aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/media/dvb/dvb-usb
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig376
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile100
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c208
-rw-r--r--drivers/media/dvb/dvb-usb/af9005-fe.c1488
-rw-r--r--drivers/media/dvb/dvb-usb/af9005-remote.c157
-rw-r--r--drivers/media/dvb/dvb-usb/af9005-script.h203
-rw-r--r--drivers/media/dvb/dvb-usb/af9005.c1105
-rw-r--r--drivers/media/dvb/dvb-usb/af9005.h3496
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c1718
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h124
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c990
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.h325
-rw-r--r--drivers/media/dvb/dvb-usb/au6610.c268
-rw-r--r--drivers/media/dvb/dvb-usb/au6610.h39
-rw-r--r--drivers/media/dvb/dvb-usb/az6027.c1203
-rw-r--r--drivers/media/dvb/dvb-usb/az6027.h14
-rw-r--r--drivers/media/dvb/dvb-usb/ce6230.c341
-rw-r--r--drivers/media/dvb/dvb-usb/ce6230.h69
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2-core.c269
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2-fe.c352
-rw-r--r--drivers/media/dvb/dvb-usb/cinergyT2.h95
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c2017
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.h35
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700.h73
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c860
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c3966
-rw-r--r--drivers/media/dvb/dvb-usb/dib07x0.h21
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c470
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c477
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mc.c165
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb.h131
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c365
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.h66
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u-fe.c205
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.c375
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u.h57
-rw-r--r--drivers/media/dvb/dvb-usb/dtv5100.c240
-rw-r--r--drivers/media/dvb/dvb-usb/dtv5100.h51
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-common.h52
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-dvb.c216
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-firmware.c146
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-i2c.c43
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h326
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-init.c289
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c391
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-urb.c97
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h463
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c1940
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.h9
-rw-r--r--drivers/media/dvb/dvb-usb/ec168.c452
-rw-r--r--drivers/media/dvb/dvb-usb/ec168.h73
-rw-r--r--drivers/media/dvb/dvb-usb/friio-fe.c474
-rw-r--r--drivers/media/dvb/dvb-usb/friio.c540
-rw-r--r--drivers/media/dvb/dvb-usb/friio.h99
-rw-r--r--drivers/media/dvb/dvb-usb/gl861.c233
-rw-r--r--drivers/media/dvb/dvb-usb/gl861.h15
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk-fe.c378
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.c344
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.h100
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.c1310
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.h174
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.c1093
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.h77
-rw-r--r--drivers/media/dvb/dvb-usb/nova-t-usb2.c250
-rw-r--r--drivers/media/dvb/dvb-usb/opera1.c595
-rw-r--r--drivers/media/dvb/dvb-usb/technisat-usb2.c805
-rw-r--r--drivers/media/dvb/dvb-usb/ttusb2.c453
-rw-r--r--drivers/media/dvb/dvb-usb/ttusb2.h70
-rw-r--r--drivers/media/dvb/dvb-usb/umt-010.c168
-rw-r--r--drivers/media/dvb/dvb-usb/usb-urb.c254
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x-fe.c387
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x.c460
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x.h113
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045-fe.c192
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.c318
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045.h70
76 files changed, 35983 insertions, 0 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
new file mode 100644
index 00000000000..5d73dec8ac0
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -0,0 +1,376 @@
1config DVB_USB
2 tristate "Support for various USB DVB devices"
3 depends on DVB_CORE && USB && I2C && RC_CORE
4 help
5 By enabling this you will be able to choose the various supported
6 USB1.1 and USB2.0 DVB devices.
7
8 Almost every USB device needs a firmware, please look into
9 <file:Documentation/dvb/README.dvb-usb>.
10
11 For a complete list of supported USB devices see the LinuxTV DVB Wiki:
12 <http://www.linuxtv.org/wiki/index.php/DVB_USB>
13
14 Say Y if you own a USB DVB device.
15
16config DVB_USB_DEBUG
17 bool "Enable extended debug support for all DVB-USB devices"
18 depends on DVB_USB
19 help
20 Say Y if you want to enable debugging. See modinfo dvb-usb (and the
21 appropriate drivers) for debug levels.
22
23config DVB_USB_A800
24 tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
25 depends on DVB_USB
26 select DVB_DIB3000MC
27 select DVB_PLL if !DVB_FE_CUSTOMISE
28 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
29 help
30 Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
31
32config DVB_USB_DIBUSB_MB
33 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
34 depends on DVB_USB
35 select DVB_PLL if !DVB_FE_CUSTOMISE
36 select DVB_DIB3000MB
37 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
38 help
39 Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
40 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
41
42 For an up-to-date list of devices supported by this driver, have a look
43 on the Linux-DVB Wiki at www.linuxtv.org.
44
45 Say Y if you own such a device and want to use it. You should build it as
46 a module.
47
48config DVB_USB_DIBUSB_MB_FAULTY
49 bool "Support faulty USB IDs"
50 depends on DVB_USB_DIBUSB_MB
51 help
52 Support for faulty USB IDs due to an invalid EEPROM on some Artec devices.
53
54config DVB_USB_DIBUSB_MC
55 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
56 depends on DVB_USB
57 select DVB_DIB3000MC
58 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
59 help
60 Support for USB2.0 DVB-T receivers based on reference designs made by
61 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
62
63 For an up-to-date list of devices supported by this driver, have a look
64 on the Linux-DVB Wiki at www.linuxtv.org.
65
66 Say Y if you own such a device and want to use it. You should build it as
67 a module.
68
69config DVB_USB_DIB0700
70 tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)"
71 depends on DVB_USB
72 select DVB_DIB7000P if !DVB_FE_CUSTOMISE
73 select DVB_DIB7000M if !DVB_FE_CUSTOMISE
74 select DVB_DIB8000 if !DVB_FE_CUSTOMISE
75 select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
76 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
77 select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
78 select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
79 select DVB_TUNER_DIB0090 if !DVB_FE_CUSTOMISE
80 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
81 select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE
82 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
83 select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
84 select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
85 select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
86 help
87 Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
88 USB bridge is also present in devices having the DiB7700 DVB-T-USB
89 silicon. This chip can be found in devices offered by Hauppauge,
90 Avermedia and other big and small companies.
91
92 For an up-to-date list of devices supported by this driver, have a look
93 on the LinuxTV Wiki at www.linuxtv.org.
94
95 Say Y if you own such a device and want to use it. You should build it as
96 a module.
97
98config DVB_USB_UMT_010
99 tristate "HanfTek UMT-010 DVB-T USB2.0 support"
100 depends on DVB_USB
101 select DVB_PLL if !DVB_FE_CUSTOMISE
102 select DVB_DIB3000MC
103 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
104 select DVB_MT352 if !DVB_FE_CUSTOMISE
105 help
106 Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
107
108config DVB_USB_CXUSB
109 tristate "Conexant USB2.0 hybrid reference design support"
110 depends on DVB_USB
111 select DVB_PLL if !DVB_FE_CUSTOMISE
112 select DVB_CX22702 if !DVB_FE_CUSTOMISE
113 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
114 select DVB_MT352 if !DVB_FE_CUSTOMISE
115 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
116 select DVB_DIB7000P if !DVB_FE_CUSTOMISE
117 select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
118 select DVB_ATBM8830 if !DVB_FE_CUSTOMISE
119 select DVB_LGS8GXX if !DVB_FE_CUSTOMISE
120 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
121 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
122 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
123 select MEDIA_TUNER_MAX2165 if !MEDIA_TUNER_CUSTOMISE
124 help
125 Say Y here to support the Conexant USB2.0 hybrid reference design.
126 Currently, only DVB and ATSC modes are supported, analog mode
127 shall be added in the future. Devices that require this module:
128
129 Medion MD95700 hybrid USB2.0 device.
130 DViCO FusionHDTV (Bluebird) USB2.0 devices
131
132config DVB_USB_M920X
133 tristate "Uli m920x DVB-T USB2.0 support"
134 depends on DVB_USB
135 select DVB_MT352 if !DVB_FE_CUSTOMISE
136 select DVB_TDA1004X if !DVB_FE_CUSTOMISE
137 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
138 select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
139 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
140 help
141 Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
142 Currently, only devices with a product id of
143 "DTV USB MINI" (in cold state) are supported.
144 Firmware required.
145
146config DVB_USB_GL861
147 tristate "Genesys Logic GL861 USB2.0 support"
148 depends on DVB_USB
149 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
150 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
151 help
152 Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
153 receiver with USB ID 0db0:5581.
154
155config DVB_USB_AU6610
156 tristate "Alcor Micro AU6610 USB2.0 support"
157 depends on DVB_USB
158 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
159 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
160 help
161 Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
162
163config DVB_USB_DIGITV
164 tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
165 depends on DVB_USB
166 select DVB_PLL if !DVB_FE_CUSTOMISE
167 select DVB_NXT6000 if !DVB_FE_CUSTOMISE
168 select DVB_MT352 if !DVB_FE_CUSTOMISE
169 help
170 Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
171
172config DVB_USB_VP7045
173 tristate "TwinhanDTV Alpha/MagicBoxII, DNTV tinyUSB2, Beetle USB2.0 support"
174 depends on DVB_USB
175 help
176 Say Y here to support the
177
178 TwinhanDTV Alpha (stick) (VP-7045),
179 TwinhanDTV MagicBox II (VP-7046),
180 DigitalNow TinyUSB 2 DVB-t,
181 DigitalRise USB 2.0 Ter (Beetle) and
182 TYPHOON DVB-T USB DRIVE
183
184 DVB-T USB2.0 receivers.
185
186config DVB_USB_VP702X
187 tristate "TwinhanDTV StarBox and clones DVB-S USB2.0 support"
188 depends on DVB_USB
189 help
190 Say Y here to support the
191
192 TwinhanDTV StarBox,
193 DigitalRise USB Starbox and
194 TYPHOON DVB-S USB 2.0 BOX
195
196 DVB-S USB2.0 receivers.
197
198config DVB_USB_GP8PSK
199 tristate "GENPIX 8PSK->USB module support"
200 depends on DVB_USB
201 help
202 Say Y here to support the
203 GENPIX 8psk module
204
205 DVB-S USB2.0 receivers.
206
207config DVB_USB_NOVA_T_USB2
208 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
209 depends on DVB_USB
210 select DVB_DIB3000MC
211 select DVB_PLL if !DVB_FE_CUSTOMISE
212 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
213 help
214 Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
215
216config DVB_USB_TTUSB2
217 tristate "Pinnacle 400e DVB-S USB2.0 support"
218 depends on DVB_USB
219 select DVB_TDA10086 if !DVB_FE_CUSTOMISE
220 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
221 select DVB_TDA826X if !DVB_FE_CUSTOMISE
222 help
223 Say Y here to support the Pinnacle 400e DVB-S USB2.0 receiver. The
224 firmware protocol used by this module is similar to the one used by the
225 old ttusb-driver - that's why the module is called dvb-usb-ttusb2.
226
227config DVB_USB_DTT200U
228 tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)"
229 depends on DVB_USB
230 help
231 Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.
232
233 The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
234
235 The WT-220U and its clones are pen-sized.
236
237config DVB_USB_OPERA1
238 tristate "Opera1 DVB-S USB2.0 receiver"
239 depends on DVB_USB
240 select DVB_STV0299 if !DVB_FE_CUSTOMISE
241 select DVB_PLL if !DVB_FE_CUSTOMISE
242 help
243 Say Y here to support the Opera DVB-S USB2.0 receiver.
244
245config DVB_USB_AF9005
246 tristate "Afatech AF9005 DVB-T USB1.1 support"
247 depends on DVB_USB && EXPERIMENTAL
248 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
249 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
250 help
251 Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
252 and the TerraTec Cinergy T USB XE (Rev.1)
253
254config DVB_USB_AF9005_REMOTE
255 tristate "Afatech AF9005 default remote control support"
256 depends on DVB_USB_AF9005
257 help
258 Say Y here to support the default remote control decoding for the
259 Afatech AF9005 based receiver.
260
261config DVB_USB_DW2102
262 tristate "DvbWorld & TeVii DVB-S/S2 USB2.0 support"
263 depends on DVB_USB
264 select DVB_PLL if !DVB_FE_CUSTOMISE
265 select DVB_STV0299 if !DVB_FE_CUSTOMISE
266 select DVB_STV0288 if !DVB_FE_CUSTOMISE
267 select DVB_STB6000 if !DVB_FE_CUSTOMISE
268 select DVB_CX24116 if !DVB_FE_CUSTOMISE
269 select DVB_SI21XX if !DVB_FE_CUSTOMISE
270 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
271 select DVB_MT312 if !DVB_FE_CUSTOMISE
272 select DVB_ZL10039 if !DVB_FE_CUSTOMISE
273 select DVB_DS3000 if !DVB_FE_CUSTOMISE
274 select DVB_STB6100 if !DVB_FE_CUSTOMISE
275 select DVB_STV6110 if !DVB_FE_CUSTOMISE
276 select DVB_STV0900 if !DVB_FE_CUSTOMISE
277 help
278 Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0
279 receivers.
280
281config DVB_USB_CINERGY_T2
282 tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
283 depends on DVB_USB
284 help
285 Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
286
287 Say Y if you own such a device and want to use it.
288
289config DVB_USB_ANYSEE
290 tristate "Anysee DVB-T/C USB2.0 support"
291 depends on DVB_USB
292 select DVB_PLL if !DVB_FE_CUSTOMISE
293 select DVB_MT352 if !DVB_FE_CUSTOMISE
294 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
295 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
296 select MEDIA_TUNER_TDA18212 if !MEDIA_TUNER_CUSTOMISE
297 select DVB_CX24116 if !DVB_FE_CUSTOMISE
298 select DVB_STV0900 if !DVB_FE_CUSTOMISE
299 select DVB_STV6110 if !DVB_FE_CUSTOMISE
300 select DVB_ISL6423 if !DVB_FE_CUSTOMISE
301 help
302 Say Y here to support the Anysee E30, Anysee E30 Plus or
303 Anysee E30 C Plus DVB USB2.0 receiver.
304
305config DVB_USB_DTV5100
306 tristate "AME DTV-5100 USB2.0 DVB-T support"
307 depends on DVB_USB
308 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
309 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
310 help
311 Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
312
313config DVB_USB_AF9015
314 tristate "Afatech AF9015 DVB-T USB2.0 support"
315 depends on DVB_USB
316 select DVB_AF9013
317 select DVB_PLL if !DVB_FE_CUSTOMISE
318 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
319 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
320 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
321 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
322 select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
323 select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
324 select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
325 help
326 Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
327
328config DVB_USB_CE6230
329 tristate "Intel CE6230 DVB-T USB2.0 support"
330 depends on DVB_USB && EXPERIMENTAL
331 select DVB_ZL10353
332 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
333 help
334 Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
335
336config DVB_USB_FRIIO
337 tristate "Friio ISDB-T USB2.0 Receiver support"
338 depends on DVB_USB
339 help
340 Say Y here to support the Japanese DTV receiver Friio.
341
342config DVB_USB_EC168
343 tristate "E3C EC168 DVB-T USB2.0 support"
344 depends on DVB_USB && EXPERIMENTAL
345 select DVB_EC100
346 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
347 help
348 Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
349
350config DVB_USB_AZ6027
351 tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support"
352 depends on DVB_USB
353 select DVB_STB0899 if !DVB_FE_CUSTOMISE
354 select DVB_STB6100 if !DVB_FE_CUSTOMISE
355 help
356 Say Y here to support the AZ6027 device
357
358config DVB_USB_LME2510
359 tristate "LME DM04/QQBOX DVB-S USB2.0 support"
360 depends on DVB_USB
361 select DVB_TDA10086 if !DVB_FE_CUSTOMISE
362 select DVB_TDA826X if !DVB_FE_CUSTOMISE
363 select DVB_STV0288 if !DVB_FE_CUSTOMISE
364 select DVB_IX2505V if !DVB_FE_CUSTOMISE
365 select DVB_STV0299 if !DVB_FE_CUSTOMISE
366 select DVB_PLL if !DVB_FE_CUSTOMISE
367 help
368 Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 .
369
370config DVB_USB_TECHNISAT_USB2
371 tristate "Technisat DVB-S/S2 USB2.0 support"
372 depends on DVB_USB
373 select DVB_STV090x if !DVB_FE_CUSTOMISE
374 select DVB_STV6110x if !DVB_FE_CUSTOMISE
375 help
376 Say Y here to support the Technisat USB2 DVB-S/S2 device
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
new file mode 100644
index 00000000000..4bac13da0c3
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -0,0 +1,100 @@
1dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o usb-urb.o
2obj-$(CONFIG_DVB_USB) += dvb-usb.o
3
4dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
5obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
6
7dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o
8obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
9
10dvb-usb-gp8psk-objs = gp8psk.o gp8psk-fe.o
11obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o
12
13dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
14obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
15
16dvb-usb-dibusb-common-objs = dibusb-common.o
17
18dvb-usb-a800-objs = a800.o
19obj-$(CONFIG_DVB_USB_A800) += dvb-usb-dibusb-common.o dvb-usb-a800.o
20
21dvb-usb-dibusb-mb-objs = dibusb-mb.o
22obj-$(CONFIG_DVB_USB_DIBUSB_MB) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mb.o
23
24dvb-usb-dibusb-mc-objs = dibusb-mc.o
25obj-$(CONFIG_DVB_USB_DIBUSB_MC) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mc.o
26
27dvb-usb-nova-t-usb2-objs = nova-t-usb2.o
28obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2.o
29
30dvb-usb-umt-010-objs = umt-010.o
31obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o
32
33dvb-usb-m920x-objs = m920x.o
34obj-$(CONFIG_DVB_USB_M920X) += dvb-usb-m920x.o
35
36dvb-usb-gl861-objs = gl861.o
37obj-$(CONFIG_DVB_USB_GL861) += dvb-usb-gl861.o
38
39dvb-usb-au6610-objs = au6610.o
40obj-$(CONFIG_DVB_USB_AU6610) += dvb-usb-au6610.o
41
42dvb-usb-digitv-objs = digitv.o
43obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
44
45dvb-usb-cxusb-objs = cxusb.o
46obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o
47
48dvb-usb-ttusb2-objs = ttusb2.o
49obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o
50
51dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o
52obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
53
54dvb-usb-opera-objs = opera1.o
55obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o
56
57
58dvb-usb-af9005-objs = af9005.o af9005-fe.o
59obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o
60
61dvb-usb-af9005-remote-objs = af9005-remote.o
62obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
63
64dvb-usb-anysee-objs = anysee.o
65obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
66
67dvb-usb-dw2102-objs = dw2102.o
68obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o
69
70dvb-usb-dtv5100-objs = dtv5100.o
71obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o
72
73dvb-usb-af9015-objs = af9015.o
74obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o
75
76dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o
77obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
78
79dvb-usb-ce6230-objs = ce6230.o
80obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
81
82dvb-usb-friio-objs = friio.o friio-fe.o
83obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
84
85dvb-usb-ec168-objs = ec168.o
86obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
87
88dvb-usb-az6027-objs = az6027.o
89obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
90
91dvb-usb-lmedm04-objs = lmedm04.o
92obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
93
94dvb-usb-technisat-usb2-objs = technisat-usb2.o
95obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
96
97EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
98# due to tuner-xc3028
99EXTRA_CFLAGS += -Idrivers/media/common/tuners
100
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
new file mode 100644
index 00000000000..b95a95e1784
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -0,0 +1,208 @@
1/* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T
2 * USB2.0 (A800) DVB-T receiver.
3 *
4 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to
7 * - AVerMedia who kindly provided information and
8 * - Glen Harris who suffered from my mistakes during development.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation, version 2.
13 *
14 * see Documentation/dvb/README.dvb-usb for more information
15 */
16#include "dibusb.h"
17
18static int debug;
19module_param(debug, int, 0644);
20MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS);
21
22DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
23
24#define deb_rc(args...) dprintk(debug,0x01,args)
25
26static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)
27{
28 /* do nothing for the AVerMedia */
29 return 0;
30}
31
32/* assure to put cold to 0 for iManufacturer == 1 */
33static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
34 struct dvb_usb_device_description **desc, int *cold)
35{
36 *cold = udev->descriptor.iManufacturer != 1;
37 return 0;
38}
39
40static struct rc_map_table rc_map_a800_table[] = {
41 { 0x0201, KEY_MODE }, /* SOURCE */
42 { 0x0200, KEY_POWER2 }, /* POWER */
43 { 0x0205, KEY_1 }, /* 1 */
44 { 0x0206, KEY_2 }, /* 2 */
45 { 0x0207, KEY_3 }, /* 3 */
46 { 0x0209, KEY_4 }, /* 4 */
47 { 0x020a, KEY_5 }, /* 5 */
48 { 0x020b, KEY_6 }, /* 6 */
49 { 0x020d, KEY_7 }, /* 7 */
50 { 0x020e, KEY_8 }, /* 8 */
51 { 0x020f, KEY_9 }, /* 9 */
52 { 0x0212, KEY_LEFT }, /* L / DISPLAY */
53 { 0x0211, KEY_0 }, /* 0 */
54 { 0x0213, KEY_RIGHT }, /* R / CH RTN */
55 { 0x0217, KEY_CAMERA }, /* SNAP SHOT */
56 { 0x0210, KEY_LAST }, /* 16-CH PREV */
57 { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */
58 { 0x020c, KEY_ZOOM }, /* FULL SCREEN */
59 { 0x021f, KEY_VOLUMEUP }, /* VOL UP */
60 { 0x0214, KEY_MUTE }, /* MUTE */
61 { 0x0208, KEY_AUDIO }, /* AUDIO */
62 { 0x0219, KEY_RECORD }, /* RECORD */
63 { 0x0218, KEY_PLAY }, /* PLAY */
64 { 0x021b, KEY_STOP }, /* STOP */
65 { 0x021a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
66 { 0x021d, KEY_BACK }, /* << / RED */
67 { 0x021c, KEY_FORWARD }, /* >> / YELLOW */
68 { 0x0203, KEY_TEXT }, /* TELETEXT */
69 { 0x0204, KEY_EPG }, /* EPG */
70 { 0x0215, KEY_MENU }, /* MENU */
71
72 { 0x0303, KEY_CHANNELUP }, /* CH UP */
73 { 0x0302, KEY_CHANNELDOWN }, /* CH DOWN */
74 { 0x0301, KEY_FIRST }, /* |<< / GREEN */
75 { 0x0300, KEY_LAST }, /* >>| / BLUE */
76
77};
78
79static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
80{
81 int ret;
82 u8 *key = kmalloc(5, GFP_KERNEL);
83 if (!key)
84 return -ENOMEM;
85
86 if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
87 0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
88 2000) != 5) {
89 ret = -ENODEV;
90 goto out;
91 }
92
93 /* call the universal NEC remote processor, to find out the key's state and event */
94 dvb_usb_nec_rc_key_to_event(d,key,event,state);
95 if (key[0] != 0)
96 deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
97 ret = 0;
98out:
99 kfree(key);
100 return ret;
101}
102
103/* USB Driver stuff */
104static struct dvb_usb_device_properties a800_properties;
105
106static int a800_probe(struct usb_interface *intf,
107 const struct usb_device_id *id)
108{
109 return dvb_usb_device_init(intf, &a800_properties,
110 THIS_MODULE, NULL, adapter_nr);
111}
112
113/* do not change the order of the ID table */
114static struct usb_device_id a800_table [] = {
115/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_COLD) },
116/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_WARM) },
117 { } /* Terminating entry */
118};
119MODULE_DEVICE_TABLE (usb, a800_table);
120
121static struct dvb_usb_device_properties a800_properties = {
122 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
123
124 .usb_ctrl = CYPRESS_FX2,
125 .firmware = "dvb-usb-avertv-a800-02.fw",
126
127 .num_adapters = 1,
128 .adapter = {
129 {
130 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
131 .pid_filter_count = 32,
132 .streaming_ctrl = dibusb2_0_streaming_ctrl,
133 .pid_filter = dibusb_pid_filter,
134 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
135
136 .frontend_attach = dibusb_dib3000mc_frontend_attach,
137 .tuner_attach = dibusb_dib3000mc_tuner_attach,
138
139 /* parameter for the MPEG2-data transfer */
140 .stream = {
141 .type = USB_BULK,
142 .count = 7,
143 .endpoint = 0x06,
144 .u = {
145 .bulk = {
146 .buffersize = 4096,
147 }
148 }
149 },
150
151 .size_of_priv = sizeof(struct dibusb_state),
152 },
153 },
154
155 .power_ctrl = a800_power_ctrl,
156 .identify_state = a800_identify_state,
157
158 .rc.legacy = {
159 .rc_interval = DEFAULT_RC_INTERVAL,
160 .rc_map_table = rc_map_a800_table,
161 .rc_map_size = ARRAY_SIZE(rc_map_a800_table),
162 .rc_query = a800_rc_query,
163 },
164
165 .i2c_algo = &dibusb_i2c_algo,
166
167 .generic_bulk_ctrl_endpoint = 0x01,
168 .num_device_descs = 1,
169 .devices = {
170 { "AVerMedia AverTV DVB-T USB 2.0 (A800)",
171 { &a800_table[0], NULL },
172 { &a800_table[1], NULL },
173 },
174 }
175};
176
177static struct usb_driver a800_driver = {
178 .name = "dvb_usb_a800",
179 .probe = a800_probe,
180 .disconnect = dvb_usb_device_exit,
181 .id_table = a800_table,
182};
183
184/* module stuff */
185static int __init a800_module_init(void)
186{
187 int result;
188 if ((result = usb_register(&a800_driver))) {
189 err("usb_register failed. Error number %d",result);
190 return result;
191 }
192
193 return 0;
194}
195
196static void __exit a800_module_exit(void)
197{
198 /* deregister this driver from the USB subsystem */
199 usb_deregister(&a800_driver);
200}
201
202module_init (a800_module_init);
203module_exit (a800_module_exit);
204
205MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
206MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)");
207MODULE_VERSION("1.0");
208MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c
new file mode 100644
index 00000000000..6ad94745bbd
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/af9005-fe.c
@@ -0,0 +1,1488 @@
1/* Frontend part of the Linux driver for the Afatech 9005
2 * USB1.1 DVB-T receiver.
3 *
4 * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
5 *
6 * Thanks to Afatech who kindly provided information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * see Documentation/dvb/README.dvb-usb for more information
23 */
24#include "af9005.h"
25#include "af9005-script.h"
26#include "mt2060.h"
27#include "qt1010.h"
28#include <asm/div64.h>
29
30struct af9005_fe_state {
31 struct dvb_usb_device *d;
32 fe_status_t stat;
33
34 /* retraining parameters */
35 u32 original_fcw;
36 u16 original_rf_top;
37 u16 original_if_top;
38 u16 original_if_min;
39 u16 original_aci0_if_top;
40 u16 original_aci1_if_top;
41 u16 original_aci0_if_min;
42 u8 original_if_unplug_th;
43 u8 original_rf_unplug_th;
44 u8 original_dtop_if_unplug_th;
45 u8 original_dtop_rf_unplug_th;
46
47 /* statistics */
48 u32 pre_vit_error_count;
49 u32 pre_vit_bit_count;
50 u32 ber;
51 u32 post_vit_error_count;
52 u32 post_vit_bit_count;
53 u32 unc;
54 u16 abort_count;
55
56 int opened;
57 int strong;
58 unsigned long next_status_check;
59 struct dvb_frontend frontend;
60};
61
62static int af9005_write_word_agc(struct dvb_usb_device *d, u16 reghi,
63 u16 reglo, u8 pos, u8 len, u16 value)
64{
65 int ret;
66 u8 temp;
67
68 if ((ret = af9005_write_ofdm_register(d, reglo, (u8) (value & 0xff))))
69 return ret;
70 temp = (u8) ((value & 0x0300) >> 8);
71 return af9005_write_register_bits(d, reghi, pos, len,
72 (u8) ((value & 0x300) >> 8));
73}
74
75static int af9005_read_word_agc(struct dvb_usb_device *d, u16 reghi,
76 u16 reglo, u8 pos, u8 len, u16 * value)
77{
78 int ret;
79 u8 temp0, temp1;
80
81 if ((ret = af9005_read_ofdm_register(d, reglo, &temp0)))
82 return ret;
83 if ((ret = af9005_read_ofdm_register(d, reghi, &temp1)))
84 return ret;
85 switch (pos) {
86 case 0:
87 *value = ((u16) (temp1 & 0x03) << 8) + (u16) temp0;
88 break;
89 case 2:
90 *value = ((u16) (temp1 & 0x0C) << 6) + (u16) temp0;
91 break;
92 case 4:
93 *value = ((u16) (temp1 & 0x30) << 4) + (u16) temp0;
94 break;
95 case 6:
96 *value = ((u16) (temp1 & 0xC0) << 2) + (u16) temp0;
97 break;
98 default:
99 err("invalid pos in read word agc");
100 return -EINVAL;
101 }
102 return 0;
103
104}
105
106static int af9005_is_fecmon_available(struct dvb_frontend *fe, int *available)
107{
108 struct af9005_fe_state *state = fe->demodulator_priv;
109 int ret;
110 u8 temp;
111
112 *available = false;
113
114 ret = af9005_read_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en,
115 fec_vtb_rsd_mon_en_pos,
116 fec_vtb_rsd_mon_en_len, &temp);
117 if (ret)
118 return ret;
119 if (temp & 1) {
120 ret =
121 af9005_read_register_bits(state->d,
122 xd_p_reg_ofsm_read_rbc_en,
123 reg_ofsm_read_rbc_en_pos,
124 reg_ofsm_read_rbc_en_len, &temp);
125 if (ret)
126 return ret;
127 if ((temp & 1) == 0)
128 *available = true;
129
130 }
131 return 0;
132}
133
134static int af9005_get_post_vit_err_cw_count(struct dvb_frontend *fe,
135 u32 * post_err_count,
136 u32 * post_cw_count,
137 u16 * abort_count)
138{
139 struct af9005_fe_state *state = fe->demodulator_priv;
140 int ret;
141 u32 err_count;
142 u32 cw_count;
143 u8 temp, temp0, temp1, temp2;
144 u16 loc_abort_count;
145
146 *post_err_count = 0;
147 *post_cw_count = 0;
148
149 /* check if error bit count is ready */
150 ret =
151 af9005_read_register_bits(state->d, xd_r_fec_rsd_ber_rdy,
152 fec_rsd_ber_rdy_pos, fec_rsd_ber_rdy_len,
153 &temp);
154 if (ret)
155 return ret;
156 if (!temp) {
157 deb_info("rsd counter not ready\n");
158 return 100;
159 }
160 /* get abort count */
161 ret =
162 af9005_read_ofdm_register(state->d,
163 xd_r_fec_rsd_abort_packet_cnt_7_0,
164 &temp0);
165 if (ret)
166 return ret;
167 ret =
168 af9005_read_ofdm_register(state->d,
169 xd_r_fec_rsd_abort_packet_cnt_15_8,
170 &temp1);
171 if (ret)
172 return ret;
173 loc_abort_count = ((u16) temp1 << 8) + temp0;
174
175 /* get error count */
176 ret =
177 af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_7_0,
178 &temp0);
179 if (ret)
180 return ret;
181 ret =
182 af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_15_8,
183 &temp1);
184 if (ret)
185 return ret;
186 ret =
187 af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_23_16,
188 &temp2);
189 if (ret)
190 return ret;
191 err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0;
192 *post_err_count = err_count - (u32) loc_abort_count *8 * 8;
193
194 /* get RSD packet number */
195 ret =
196 af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0,
197 &temp0);
198 if (ret)
199 return ret;
200 ret =
201 af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8,
202 &temp1);
203 if (ret)
204 return ret;
205 cw_count = ((u32) temp1 << 8) + temp0;
206 if (cw_count == 0) {
207 err("wrong RSD packet count");
208 return -EIO;
209 }
210 deb_info("POST abort count %d err count %d rsd packets %d\n",
211 loc_abort_count, err_count, cw_count);
212 *post_cw_count = cw_count - (u32) loc_abort_count;
213 *abort_count = loc_abort_count;
214 return 0;
215
216}
217
218static int af9005_get_post_vit_ber(struct dvb_frontend *fe,
219 u32 * post_err_count, u32 * post_cw_count,
220 u16 * abort_count)
221{
222 u32 loc_cw_count = 0, loc_err_count;
223 u16 loc_abort_count = 0;
224 int ret;
225
226 ret =
227 af9005_get_post_vit_err_cw_count(fe, &loc_err_count, &loc_cw_count,
228 &loc_abort_count);
229 if (ret)
230 return ret;
231 *post_err_count = loc_err_count;
232 *post_cw_count = loc_cw_count * 204 * 8;
233 *abort_count = loc_abort_count;
234
235 return 0;
236}
237
238static int af9005_get_pre_vit_err_bit_count(struct dvb_frontend *fe,
239 u32 * pre_err_count,
240 u32 * pre_bit_count)
241{
242 struct af9005_fe_state *state = fe->demodulator_priv;
243 u8 temp, temp0, temp1, temp2;
244 u32 super_frame_count, x, bits;
245 int ret;
246
247 ret =
248 af9005_read_register_bits(state->d, xd_r_fec_vtb_ber_rdy,
249 fec_vtb_ber_rdy_pos, fec_vtb_ber_rdy_len,
250 &temp);
251 if (ret)
252 return ret;
253 if (!temp) {
254 deb_info("viterbi counter not ready\n");
255 return 101; /* ERR_APO_VTB_COUNTER_NOT_READY; */
256 }
257 ret =
258 af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_7_0,
259 &temp0);
260 if (ret)
261 return ret;
262 ret =
263 af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_15_8,
264 &temp1);
265 if (ret)
266 return ret;
267 ret =
268 af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_23_16,
269 &temp2);
270 if (ret)
271 return ret;
272 *pre_err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0;
273
274 ret =
275 af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0,
276 &temp0);
277 if (ret)
278 return ret;
279 ret =
280 af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8,
281 &temp1);
282 if (ret)
283 return ret;
284 super_frame_count = ((u32) temp1 << 8) + temp0;
285 if (super_frame_count == 0) {
286 deb_info("super frame count 0\n");
287 return 102;
288 }
289
290 /* read fft mode */
291 ret =
292 af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod,
293 reg_tpsd_txmod_pos, reg_tpsd_txmod_len,
294 &temp);
295 if (ret)
296 return ret;
297 if (temp == 0) {
298 /* 2K */
299 x = 1512;
300 } else if (temp == 1) {
301 /* 8k */
302 x = 6048;
303 } else {
304 err("Invalid fft mode");
305 return -EINVAL;
306 }
307
308 /* read constellation mode */
309 ret =
310 af9005_read_register_bits(state->d, xd_g_reg_tpsd_const,
311 reg_tpsd_const_pos, reg_tpsd_const_len,
312 &temp);
313 if (ret)
314 return ret;
315 switch (temp) {
316 case 0: /* QPSK */
317 bits = 2;
318 break;
319 case 1: /* QAM_16 */
320 bits = 4;
321 break;
322 case 2: /* QAM_64 */
323 bits = 6;
324 break;
325 default:
326 err("invalid constellation mode");
327 return -EINVAL;
328 }
329 *pre_bit_count = super_frame_count * 68 * 4 * x * bits;
330 deb_info("PRE err count %d frame count %d bit count %d\n",
331 *pre_err_count, super_frame_count, *pre_bit_count);
332 return 0;
333}
334
335static int af9005_reset_pre_viterbi(struct dvb_frontend *fe)
336{
337 struct af9005_fe_state *state = fe->demodulator_priv;
338 int ret;
339
340 /* set super frame count to 1 */
341 ret =
342 af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0,
343 1 & 0xff);
344 if (ret)
345 return ret;
346 ret = af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8,
347 1 >> 8);
348 if (ret)
349 return ret;
350 /* reset pre viterbi error count */
351 ret =
352 af9005_write_register_bits(state->d, xd_p_fec_vtb_ber_rst,
353 fec_vtb_ber_rst_pos, fec_vtb_ber_rst_len,
354 1);
355
356 return ret;
357}
358
359static int af9005_reset_post_viterbi(struct dvb_frontend *fe)
360{
361 struct af9005_fe_state *state = fe->demodulator_priv;
362 int ret;
363
364 /* set packet unit */
365 ret =
366 af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0,
367 10000 & 0xff);
368 if (ret)
369 return ret;
370 ret =
371 af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8,
372 10000 >> 8);
373 if (ret)
374 return ret;
375 /* reset post viterbi error count */
376 ret =
377 af9005_write_register_bits(state->d, xd_p_fec_rsd_ber_rst,
378 fec_rsd_ber_rst_pos, fec_rsd_ber_rst_len,
379 1);
380
381 return ret;
382}
383
384static int af9005_get_statistic(struct dvb_frontend *fe)
385{
386 struct af9005_fe_state *state = fe->demodulator_priv;
387 int ret, fecavailable;
388 u64 numerator, denominator;
389
390 deb_info("GET STATISTIC\n");
391 ret = af9005_is_fecmon_available(fe, &fecavailable);
392 if (ret)
393 return ret;
394 if (!fecavailable) {
395 deb_info("fecmon not available\n");
396 return 0;
397 }
398
399 ret = af9005_get_pre_vit_err_bit_count(fe, &state->pre_vit_error_count,
400 &state->pre_vit_bit_count);
401 if (ret == 0) {
402 af9005_reset_pre_viterbi(fe);
403 if (state->pre_vit_bit_count > 0) {
404 /* according to v 0.0.4 of the dvb api ber should be a multiple
405 of 10E-9 so we have to multiply the error count by
406 10E9=1000000000 */
407 numerator =
408 (u64) state->pre_vit_error_count * (u64) 1000000000;
409 denominator = (u64) state->pre_vit_bit_count;
410 state->ber = do_div(numerator, denominator);
411 } else {
412 state->ber = 0xffffffff;
413 }
414 }
415
416 ret = af9005_get_post_vit_ber(fe, &state->post_vit_error_count,
417 &state->post_vit_bit_count,
418 &state->abort_count);
419 if (ret == 0) {
420 ret = af9005_reset_post_viterbi(fe);
421 state->unc += state->abort_count;
422 if (ret)
423 return ret;
424 }
425 return 0;
426}
427
428static int af9005_fe_refresh_state(struct dvb_frontend *fe)
429{
430 struct af9005_fe_state *state = fe->demodulator_priv;
431 if (time_after(jiffies, state->next_status_check)) {
432 deb_info("REFRESH STATE\n");
433
434 /* statistics */
435 if (af9005_get_statistic(fe))
436 err("get_statistic_failed");
437 state->next_status_check = jiffies + 250 * HZ / 1000;
438 }
439 return 0;
440}
441
442static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat)
443{
444 struct af9005_fe_state *state = fe->demodulator_priv;
445 u8 temp;
446 int ret;
447
448 if (fe->ops.tuner_ops.release == NULL)
449 return -ENODEV;
450
451 *stat = 0;
452 ret = af9005_read_register_bits(state->d, xd_p_agc_lock,
453 agc_lock_pos, agc_lock_len, &temp);
454 if (ret)
455 return ret;
456 if (temp)
457 *stat |= FE_HAS_SIGNAL;
458
459 ret = af9005_read_register_bits(state->d, xd_p_fd_tpsd_lock,
460 fd_tpsd_lock_pos, fd_tpsd_lock_len,
461 &temp);
462 if (ret)
463 return ret;
464 if (temp)
465 *stat |= FE_HAS_CARRIER;
466
467 ret = af9005_read_register_bits(state->d,
468 xd_r_mp2if_sync_byte_locked,
469 mp2if_sync_byte_locked_pos,
470 mp2if_sync_byte_locked_pos, &temp);
471 if (ret)
472 return ret;
473 if (temp)
474 *stat |= FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_LOCK;
475 if (state->opened)
476 af9005_led_control(state->d, *stat & FE_HAS_LOCK);
477
478 ret =
479 af9005_read_register_bits(state->d, xd_p_reg_strong_sginal_detected,
480 reg_strong_sginal_detected_pos,
481 reg_strong_sginal_detected_len, &temp);
482 if (ret)
483 return ret;
484 if (temp != state->strong) {
485 deb_info("adjust for strong signal %d\n", temp);
486 state->strong = temp;
487 }
488 return 0;
489}
490
491static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber)
492{
493 struct af9005_fe_state *state = fe->demodulator_priv;
494 if (fe->ops.tuner_ops.release == NULL)
495 return -ENODEV;
496 af9005_fe_refresh_state(fe);
497 *ber = state->ber;
498 return 0;
499}
500
501static int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
502{
503 struct af9005_fe_state *state = fe->demodulator_priv;
504 if (fe->ops.tuner_ops.release == NULL)
505 return -ENODEV;
506 af9005_fe_refresh_state(fe);
507 *unc = state->unc;
508 return 0;
509}
510
511static int af9005_fe_read_signal_strength(struct dvb_frontend *fe,
512 u16 * strength)
513{
514 struct af9005_fe_state *state = fe->demodulator_priv;
515 int ret;
516 u8 if_gain, rf_gain;
517
518 if (fe->ops.tuner_ops.release == NULL)
519 return -ENODEV;
520 ret =
521 af9005_read_ofdm_register(state->d, xd_r_reg_aagc_rf_gain,
522 &rf_gain);
523 if (ret)
524 return ret;
525 ret =
526 af9005_read_ofdm_register(state->d, xd_r_reg_aagc_if_gain,
527 &if_gain);
528 if (ret)
529 return ret;
530 /* this value has no real meaning, but i don't have the tables that relate
531 the rf and if gain with the dbm, so I just scale the value */
532 *strength = (512 - rf_gain - if_gain) << 7;
533 return 0;
534}
535
536static int af9005_fe_read_snr(struct dvb_frontend *fe, u16 * snr)
537{
538 /* the snr can be derived from the ber and the constellation
539 but I don't think this kind of complex calculations belong
540 in the driver. I may be wrong.... */
541 return -ENOSYS;
542}
543
544static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw)
545{
546 u8 temp0, temp1, temp2, temp3, buf[4];
547 int ret;
548 u32 NS_coeff1_2048Nu;
549 u32 NS_coeff1_8191Nu;
550 u32 NS_coeff1_8192Nu;
551 u32 NS_coeff1_8193Nu;
552 u32 NS_coeff2_2k;
553 u32 NS_coeff2_8k;
554
555 switch (bw) {
556 case BANDWIDTH_6_MHZ:
557 NS_coeff1_2048Nu = 0x2ADB6DC;
558 NS_coeff1_8191Nu = 0xAB7313;
559 NS_coeff1_8192Nu = 0xAB6DB7;
560 NS_coeff1_8193Nu = 0xAB685C;
561 NS_coeff2_2k = 0x156DB6E;
562 NS_coeff2_8k = 0x55B6DC;
563 break;
564
565 case BANDWIDTH_7_MHZ:
566 NS_coeff1_2048Nu = 0x3200001;
567 NS_coeff1_8191Nu = 0xC80640;
568 NS_coeff1_8192Nu = 0xC80000;
569 NS_coeff1_8193Nu = 0xC7F9C0;
570 NS_coeff2_2k = 0x1900000;
571 NS_coeff2_8k = 0x640000;
572 break;
573
574 case BANDWIDTH_8_MHZ:
575 NS_coeff1_2048Nu = 0x3924926;
576 NS_coeff1_8191Nu = 0xE4996E;
577 NS_coeff1_8192Nu = 0xE49249;
578 NS_coeff1_8193Nu = 0xE48B25;
579 NS_coeff2_2k = 0x1C92493;
580 NS_coeff2_8k = 0x724925;
581 break;
582 default:
583 err("Invalid bandwidth %d.", bw);
584 return -EINVAL;
585 }
586
587 /*
588 * write NS_coeff1_2048Nu
589 */
590
591 temp0 = (u8) (NS_coeff1_2048Nu & 0x000000FF);
592 temp1 = (u8) ((NS_coeff1_2048Nu & 0x0000FF00) >> 8);
593 temp2 = (u8) ((NS_coeff1_2048Nu & 0x00FF0000) >> 16);
594 temp3 = (u8) ((NS_coeff1_2048Nu & 0x03000000) >> 24);
595
596 /* big endian to make 8051 happy */
597 buf[0] = temp3;
598 buf[1] = temp2;
599 buf[2] = temp1;
600 buf[3] = temp0;
601
602 /* cfoe_NS_2k_coeff1_25_24 */
603 ret = af9005_write_ofdm_register(d, 0xAE00, buf[0]);
604 if (ret)
605 return ret;
606
607 /* cfoe_NS_2k_coeff1_23_16 */
608 ret = af9005_write_ofdm_register(d, 0xAE01, buf[1]);
609 if (ret)
610 return ret;
611
612 /* cfoe_NS_2k_coeff1_15_8 */
613 ret = af9005_write_ofdm_register(d, 0xAE02, buf[2]);
614 if (ret)
615 return ret;
616
617 /* cfoe_NS_2k_coeff1_7_0 */
618 ret = af9005_write_ofdm_register(d, 0xAE03, buf[3]);
619 if (ret)
620 return ret;
621
622 /*
623 * write NS_coeff2_2k
624 */
625
626 temp0 = (u8) ((NS_coeff2_2k & 0x0000003F));
627 temp1 = (u8) ((NS_coeff2_2k & 0x00003FC0) >> 6);
628 temp2 = (u8) ((NS_coeff2_2k & 0x003FC000) >> 14);
629 temp3 = (u8) ((NS_coeff2_2k & 0x01C00000) >> 22);
630
631 /* big endian to make 8051 happy */
632 buf[0] = temp3;
633 buf[1] = temp2;
634 buf[2] = temp1;
635 buf[3] = temp0;
636
637 ret = af9005_write_ofdm_register(d, 0xAE04, buf[0]);
638 if (ret)
639 return ret;
640
641 ret = af9005_write_ofdm_register(d, 0xAE05, buf[1]);
642 if (ret)
643 return ret;
644
645 ret = af9005_write_ofdm_register(d, 0xAE06, buf[2]);
646 if (ret)
647 return ret;
648
649 ret = af9005_write_ofdm_register(d, 0xAE07, buf[3]);
650 if (ret)
651 return ret;
652
653 /*
654 * write NS_coeff1_8191Nu
655 */
656
657 temp0 = (u8) ((NS_coeff1_8191Nu & 0x000000FF));
658 temp1 = (u8) ((NS_coeff1_8191Nu & 0x0000FF00) >> 8);
659 temp2 = (u8) ((NS_coeff1_8191Nu & 0x00FFC000) >> 16);
660 temp3 = (u8) ((NS_coeff1_8191Nu & 0x03000000) >> 24);
661
662 /* big endian to make 8051 happy */
663 buf[0] = temp3;
664 buf[1] = temp2;
665 buf[2] = temp1;
666 buf[3] = temp0;
667
668 ret = af9005_write_ofdm_register(d, 0xAE08, buf[0]);
669 if (ret)
670 return ret;
671
672 ret = af9005_write_ofdm_register(d, 0xAE09, buf[1]);
673 if (ret)
674 return ret;
675
676 ret = af9005_write_ofdm_register(d, 0xAE0A, buf[2]);
677 if (ret)
678 return ret;
679
680 ret = af9005_write_ofdm_register(d, 0xAE0B, buf[3]);
681 if (ret)
682 return ret;
683
684 /*
685 * write NS_coeff1_8192Nu
686 */
687
688 temp0 = (u8) (NS_coeff1_8192Nu & 0x000000FF);
689 temp1 = (u8) ((NS_coeff1_8192Nu & 0x0000FF00) >> 8);
690 temp2 = (u8) ((NS_coeff1_8192Nu & 0x00FFC000) >> 16);
691 temp3 = (u8) ((NS_coeff1_8192Nu & 0x03000000) >> 24);
692
693 /* big endian to make 8051 happy */
694 buf[0] = temp3;
695 buf[1] = temp2;
696 buf[2] = temp1;
697 buf[3] = temp0;
698
699 ret = af9005_write_ofdm_register(d, 0xAE0C, buf[0]);
700 if (ret)
701 return ret;
702
703 ret = af9005_write_ofdm_register(d, 0xAE0D, buf[1]);
704 if (ret)
705 return ret;
706
707 ret = af9005_write_ofdm_register(d, 0xAE0E, buf[2]);
708 if (ret)
709 return ret;
710
711 ret = af9005_write_ofdm_register(d, 0xAE0F, buf[3]);
712 if (ret)
713 return ret;
714
715 /*
716 * write NS_coeff1_8193Nu
717 */
718
719 temp0 = (u8) ((NS_coeff1_8193Nu & 0x000000FF));
720 temp1 = (u8) ((NS_coeff1_8193Nu & 0x0000FF00) >> 8);
721 temp2 = (u8) ((NS_coeff1_8193Nu & 0x00FFC000) >> 16);
722 temp3 = (u8) ((NS_coeff1_8193Nu & 0x03000000) >> 24);
723
724 /* big endian to make 8051 happy */
725 buf[0] = temp3;
726 buf[1] = temp2;
727 buf[2] = temp1;
728 buf[3] = temp0;
729
730 ret = af9005_write_ofdm_register(d, 0xAE10, buf[0]);
731 if (ret)
732 return ret;
733
734 ret = af9005_write_ofdm_register(d, 0xAE11, buf[1]);
735 if (ret)
736 return ret;
737
738 ret = af9005_write_ofdm_register(d, 0xAE12, buf[2]);
739 if (ret)
740 return ret;
741
742 ret = af9005_write_ofdm_register(d, 0xAE13, buf[3]);
743 if (ret)
744 return ret;
745
746 /*
747 * write NS_coeff2_8k
748 */
749
750 temp0 = (u8) ((NS_coeff2_8k & 0x0000003F));
751 temp1 = (u8) ((NS_coeff2_8k & 0x00003FC0) >> 6);
752 temp2 = (u8) ((NS_coeff2_8k & 0x003FC000) >> 14);
753 temp3 = (u8) ((NS_coeff2_8k & 0x01C00000) >> 22);
754
755 /* big endian to make 8051 happy */
756 buf[0] = temp3;
757 buf[1] = temp2;
758 buf[2] = temp1;
759 buf[3] = temp0;
760
761 ret = af9005_write_ofdm_register(d, 0xAE14, buf[0]);
762 if (ret)
763 return ret;
764
765 ret = af9005_write_ofdm_register(d, 0xAE15, buf[1]);
766 if (ret)
767 return ret;
768
769 ret = af9005_write_ofdm_register(d, 0xAE16, buf[2]);
770 if (ret)
771 return ret;
772
773 ret = af9005_write_ofdm_register(d, 0xAE17, buf[3]);
774 return ret;
775
776}
777
778static int af9005_fe_select_bw(struct dvb_usb_device *d, fe_bandwidth_t bw)
779{
780 u8 temp;
781 switch (bw) {
782 case BANDWIDTH_6_MHZ:
783 temp = 0;
784 break;
785 case BANDWIDTH_7_MHZ:
786 temp = 1;
787 break;
788 case BANDWIDTH_8_MHZ:
789 temp = 2;
790 break;
791 default:
792 err("Invalid bandwidth %d.", bw);
793 return -EINVAL;
794 }
795 return af9005_write_register_bits(d, xd_g_reg_bw, reg_bw_pos,
796 reg_bw_len, temp);
797}
798
799static int af9005_fe_power(struct dvb_frontend *fe, int on)
800{
801 struct af9005_fe_state *state = fe->demodulator_priv;
802 u8 temp = on;
803 int ret;
804 deb_info("power %s tuner\n", on ? "on" : "off");
805 ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0);
806 return ret;
807}
808
809static struct mt2060_config af9005_mt2060_config = {
810 0xC0
811};
812
813static struct qt1010_config af9005_qt1010_config = {
814 0xC4
815};
816
817static int af9005_fe_init(struct dvb_frontend *fe)
818{
819 struct af9005_fe_state *state = fe->demodulator_priv;
820 struct dvb_usb_adapter *adap = fe->dvb->priv;
821 int ret, i, scriptlen;
822 u8 temp, temp0 = 0, temp1 = 0, temp2 = 0;
823 u8 buf[2];
824 u16 if1;
825
826 deb_info("in af9005_fe_init\n");
827
828 /* reset */
829 deb_info("reset\n");
830 if ((ret =
831 af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst_en,
832 4, 1, 0x01)))
833 return ret;
834 if ((ret = af9005_write_ofdm_register(state->d, APO_REG_RESET, 0)))
835 return ret;
836 /* clear ofdm reset */
837 deb_info("clear ofdm reset\n");
838 for (i = 0; i < 150; i++) {
839 if ((ret =
840 af9005_read_ofdm_register(state->d,
841 xd_I2C_reg_ofdm_rst, &temp)))
842 return ret;
843 if (temp & (regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos))
844 break;
845 msleep(10);
846 }
847 if (i == 150)
848 return -ETIMEDOUT;
849
850 /*FIXME in the dump
851 write B200 A9
852 write xd_g_reg_ofsm_clk 7
853 read eepr c6 (2)
854 read eepr c7 (2)
855 misc ctrl 3 -> 1
856 read eepr ca (6)
857 write xd_g_reg_ofsm_clk 0
858 write B200 a1
859 */
860 ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa9);
861 if (ret)
862 return ret;
863 ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x07);
864 if (ret)
865 return ret;
866 temp = 0x01;
867 ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0);
868 if (ret)
869 return ret;
870 ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x00);
871 if (ret)
872 return ret;
873 ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa1);
874 if (ret)
875 return ret;
876
877 temp = regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos;
878 if ((ret =
879 af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,
880 reg_ofdm_rst_pos, reg_ofdm_rst_len, 1)))
881 return ret;
882 ret = af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,
883 reg_ofdm_rst_pos, reg_ofdm_rst_len, 0);
884
885 if (ret)
886 return ret;
887 /* don't know what register aefc is, but this is what the windows driver does */
888 ret = af9005_write_ofdm_register(state->d, 0xaefc, 0);
889 if (ret)
890 return ret;
891
892 /* set stand alone chip */
893 deb_info("set stand alone chip\n");
894 if ((ret =
895 af9005_write_register_bits(state->d, xd_p_reg_dca_stand_alone,
896 reg_dca_stand_alone_pos,
897 reg_dca_stand_alone_len, 1)))
898 return ret;
899
900 /* set dca upper & lower chip */
901 deb_info("set dca upper & lower chip\n");
902 if ((ret =
903 af9005_write_register_bits(state->d, xd_p_reg_dca_upper_chip,
904 reg_dca_upper_chip_pos,
905 reg_dca_upper_chip_len, 0)))
906 return ret;
907 if ((ret =
908 af9005_write_register_bits(state->d, xd_p_reg_dca_lower_chip,
909 reg_dca_lower_chip_pos,
910 reg_dca_lower_chip_len, 0)))
911 return ret;
912
913 /* set 2wire master clock to 0x14 (for 60KHz) */
914 deb_info("set 2wire master clock to 0x14 (for 60KHz)\n");
915 if ((ret =
916 af9005_write_ofdm_register(state->d, xd_I2C_i2c_m_period, 0x14)))
917 return ret;
918
919 /* clear dca enable chip */
920 deb_info("clear dca enable chip\n");
921 if ((ret =
922 af9005_write_register_bits(state->d, xd_p_reg_dca_en,
923 reg_dca_en_pos, reg_dca_en_len, 0)))
924 return ret;
925 /* FIXME these are register bits, but I don't know which ones */
926 ret = af9005_write_ofdm_register(state->d, 0xa16c, 1);
927 if (ret)
928 return ret;
929 ret = af9005_write_ofdm_register(state->d, 0xa3c1, 0);
930 if (ret)
931 return ret;
932
933 /* init other parameters: program cfoe and select bandwidth */
934 deb_info("program cfoe\n");
935 if ((ret = af9005_fe_program_cfoe(state->d, BANDWIDTH_6_MHZ)))
936 return ret;
937 /* set read-update bit for constellation */
938 deb_info("set read-update bit for constellation\n");
939 if ((ret =
940 af9005_write_register_bits(state->d, xd_p_reg_feq_read_update,
941 reg_feq_read_update_pos,
942 reg_feq_read_update_len, 1)))
943 return ret;
944
945 /* sample code has a set MPEG TS code here
946 but sniffing reveals that it doesn't do it */
947
948 /* set read-update bit to 1 for DCA constellation */
949 deb_info("set read-update bit 1 for DCA constellation\n");
950 if ((ret =
951 af9005_write_register_bits(state->d, xd_p_reg_dca_read_update,
952 reg_dca_read_update_pos,
953 reg_dca_read_update_len, 1)))
954 return ret;
955
956 /* enable fec monitor */
957 deb_info("enable fec monitor\n");
958 if ((ret =
959 af9005_write_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en,
960 fec_vtb_rsd_mon_en_pos,
961 fec_vtb_rsd_mon_en_len, 1)))
962 return ret;
963
964 /* FIXME should be register bits, I don't know which ones */
965 ret = af9005_write_ofdm_register(state->d, 0xa601, 0);
966
967 /* set api_retrain_never_freeze */
968 deb_info("set api_retrain_never_freeze\n");
969 if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01)))
970 return ret;
971
972 /* load init script */
973 deb_info("load init script\n");
974 scriptlen = sizeof(script) / sizeof(RegDesc);
975 for (i = 0; i < scriptlen; i++) {
976 if ((ret =
977 af9005_write_register_bits(state->d, script[i].reg,
978 script[i].pos,
979 script[i].len, script[i].val)))
980 return ret;
981 /* save 3 bytes of original fcw */
982 if (script[i].reg == 0xae18)
983 temp2 = script[i].val;
984 if (script[i].reg == 0xae19)
985 temp1 = script[i].val;
986 if (script[i].reg == 0xae1a)
987 temp0 = script[i].val;
988
989 /* save original unplug threshold */
990 if (script[i].reg == xd_p_reg_unplug_th)
991 state->original_if_unplug_th = script[i].val;
992 if (script[i].reg == xd_p_reg_unplug_rf_gain_th)
993 state->original_rf_unplug_th = script[i].val;
994 if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th)
995 state->original_dtop_if_unplug_th = script[i].val;
996 if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th)
997 state->original_dtop_rf_unplug_th = script[i].val;
998
999 }
1000 state->original_fcw =
1001 ((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0;
1002
1003
1004 /* save original TOPs */
1005 deb_info("save original TOPs\n");
1006
1007 /* RF TOP */
1008 ret =
1009 af9005_read_word_agc(state->d,
1010 xd_p_reg_aagc_rf_top_numerator_9_8,
1011 xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2,
1012 &state->original_rf_top);
1013 if (ret)
1014 return ret;
1015
1016 /* IF TOP */
1017 ret =
1018 af9005_read_word_agc(state->d,
1019 xd_p_reg_aagc_if_top_numerator_9_8,
1020 xd_p_reg_aagc_if_top_numerator_7_0, 0, 2,
1021 &state->original_if_top);
1022 if (ret)
1023 return ret;
1024
1025 /* ACI 0 IF TOP */
1026 ret =
1027 af9005_read_word_agc(state->d, 0xA60E, 0xA60A, 4, 2,
1028 &state->original_aci0_if_top);
1029 if (ret)
1030 return ret;
1031
1032 /* ACI 1 IF TOP */
1033 ret =
1034 af9005_read_word_agc(state->d, 0xA60E, 0xA60B, 6, 2,
1035 &state->original_aci1_if_top);
1036 if (ret)
1037 return ret;
1038
1039 /* attach tuner and init */
1040 if (fe->ops.tuner_ops.release == NULL) {
1041 /* read tuner and board id from eeprom */
1042 ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2);
1043 if (ret) {
1044 err("Impossible to read EEPROM\n");
1045 return ret;
1046 }
1047 deb_info("Tuner id %d, board id %d\n", buf[0], buf[1]);
1048 switch (buf[0]) {
1049 case 2: /* MT2060 */
1050 /* read if1 from eeprom */
1051 ret = af9005_read_eeprom(adap->dev, 0xc8, buf, 2);
1052 if (ret) {
1053 err("Impossible to read EEPROM\n");
1054 return ret;
1055 }
1056 if1 = (u16) (buf[0] << 8) + buf[1];
1057 if (dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap,
1058 &af9005_mt2060_config, if1) == NULL) {
1059 deb_info("MT2060 attach failed\n");
1060 return -ENODEV;
1061 }
1062 break;
1063 case 3: /* QT1010 */
1064 case 9: /* QT1010B */
1065 if (dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap,
1066 &af9005_qt1010_config) ==NULL) {
1067 deb_info("QT1010 attach failed\n");
1068 return -ENODEV;
1069 }
1070 break;
1071 default:
1072 err("Unsupported tuner type %d", buf[0]);
1073 return -ENODEV;
1074 }
1075 ret = fe->ops.tuner_ops.init(fe);
1076 if (ret)
1077 return ret;
1078 }
1079
1080 deb_info("profit!\n");
1081 return 0;
1082}
1083
1084static int af9005_fe_sleep(struct dvb_frontend *fe)
1085{
1086 return af9005_fe_power(fe, 0);
1087}
1088
1089static int af9005_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
1090{
1091 struct af9005_fe_state *state = fe->demodulator_priv;
1092
1093 if (acquire) {
1094 state->opened++;
1095 } else {
1096
1097 state->opened--;
1098 if (!state->opened)
1099 af9005_led_control(state->d, 0);
1100 }
1101 return 0;
1102}
1103
1104static int af9005_fe_set_frontend(struct dvb_frontend *fe,
1105 struct dvb_frontend_parameters *fep)
1106{
1107 struct af9005_fe_state *state = fe->demodulator_priv;
1108 int ret;
1109 u8 temp, temp0, temp1, temp2;
1110
1111 deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency,
1112 fep->u.ofdm.bandwidth);
1113 if (fe->ops.tuner_ops.release == NULL) {
1114 err("Tuner not attached");
1115 return -ENODEV;
1116 }
1117
1118 deb_info("turn off led\n");
1119 /* not in the log */
1120 ret = af9005_led_control(state->d, 0);
1121 if (ret)
1122 return ret;
1123 /* not sure about the bits */
1124 ret = af9005_write_register_bits(state->d, XD_MP2IF_MISC, 2, 1, 0);
1125 if (ret)
1126 return ret;
1127
1128 /* set FCW to default value */
1129 deb_info("set FCW to default value\n");
1130 temp0 = (u8) (state->original_fcw & 0x000000ff);
1131 temp1 = (u8) ((state->original_fcw & 0x0000ff00) >> 8);
1132 temp2 = (u8) ((state->original_fcw & 0x00ff0000) >> 16);
1133 ret = af9005_write_ofdm_register(state->d, 0xae1a, temp0);
1134 if (ret)
1135 return ret;
1136 ret = af9005_write_ofdm_register(state->d, 0xae19, temp1);
1137 if (ret)
1138 return ret;
1139 ret = af9005_write_ofdm_register(state->d, 0xae18, temp2);
1140 if (ret)
1141 return ret;
1142
1143 /* restore original TOPs */
1144 deb_info("restore original TOPs\n");
1145 ret =
1146 af9005_write_word_agc(state->d,
1147 xd_p_reg_aagc_rf_top_numerator_9_8,
1148 xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2,
1149 state->original_rf_top);
1150 if (ret)
1151 return ret;
1152 ret =
1153 af9005_write_word_agc(state->d,
1154 xd_p_reg_aagc_if_top_numerator_9_8,
1155 xd_p_reg_aagc_if_top_numerator_7_0, 0, 2,
1156 state->original_if_top);
1157 if (ret)
1158 return ret;
1159 ret =
1160 af9005_write_word_agc(state->d, 0xA60E, 0xA60A, 4, 2,
1161 state->original_aci0_if_top);
1162 if (ret)
1163 return ret;
1164 ret =
1165 af9005_write_word_agc(state->d, 0xA60E, 0xA60B, 6, 2,
1166 state->original_aci1_if_top);
1167 if (ret)
1168 return ret;
1169
1170 /* select bandwidth */
1171 deb_info("select bandwidth");
1172 ret = af9005_fe_select_bw(state->d, fep->u.ofdm.bandwidth);
1173 if (ret)
1174 return ret;
1175 ret = af9005_fe_program_cfoe(state->d, fep->u.ofdm.bandwidth);
1176 if (ret)
1177 return ret;
1178
1179 /* clear easy mode flag */
1180 deb_info("clear easy mode flag\n");
1181 ret = af9005_write_ofdm_register(state->d, 0xaefd, 0);
1182 if (ret)
1183 return ret;
1184
1185 /* set unplug threshold to original value */
1186 deb_info("set unplug threshold to original value\n");
1187 ret =
1188 af9005_write_ofdm_register(state->d, xd_p_reg_unplug_th,
1189 state->original_if_unplug_th);
1190 if (ret)
1191 return ret;
1192 /* set tuner */
1193 deb_info("set tuner\n");
1194 ret = fe->ops.tuner_ops.set_params(fe, fep);
1195 if (ret)
1196 return ret;
1197
1198 /* trigger ofsm */
1199 deb_info("trigger ofsm\n");
1200 temp = 0;
1201 ret = af9005_write_tuner_registers(state->d, 0xffff, &temp, 1);
1202 if (ret)
1203 return ret;
1204
1205 /* clear retrain and freeze flag */
1206 deb_info("clear retrain and freeze flag\n");
1207 ret =
1208 af9005_write_register_bits(state->d,
1209 xd_p_reg_api_retrain_request,
1210 reg_api_retrain_request_pos, 2, 0);
1211 if (ret)
1212 return ret;
1213
1214 /* reset pre viterbi and post viterbi registers and statistics */
1215 af9005_reset_pre_viterbi(fe);
1216 af9005_reset_post_viterbi(fe);
1217 state->pre_vit_error_count = 0;
1218 state->pre_vit_bit_count = 0;
1219 state->ber = 0;
1220 state->post_vit_error_count = 0;
1221 /* state->unc = 0; commented out since it should be ever increasing */
1222 state->abort_count = 0;
1223
1224 state->next_status_check = jiffies;
1225 state->strong = -1;
1226
1227 return 0;
1228}
1229
1230static int af9005_fe_get_frontend(struct dvb_frontend *fe,
1231 struct dvb_frontend_parameters *fep)
1232{
1233 struct af9005_fe_state *state = fe->demodulator_priv;
1234 int ret;
1235 u8 temp;
1236
1237 /* mode */
1238 ret =
1239 af9005_read_register_bits(state->d, xd_g_reg_tpsd_const,
1240 reg_tpsd_const_pos, reg_tpsd_const_len,
1241 &temp);
1242 if (ret)
1243 return ret;
1244 deb_info("===== fe_get_frontend ==============\n");
1245 deb_info("CONSTELLATION ");
1246 switch (temp) {
1247 case 0:
1248 fep->u.ofdm.constellation = QPSK;
1249 deb_info("QPSK\n");
1250 break;
1251 case 1:
1252 fep->u.ofdm.constellation = QAM_16;
1253 deb_info("QAM_16\n");
1254 break;
1255 case 2:
1256 fep->u.ofdm.constellation = QAM_64;
1257 deb_info("QAM_64\n");
1258 break;
1259 }
1260
1261 /* tps hierarchy and alpha value */
1262 ret =
1263 af9005_read_register_bits(state->d, xd_g_reg_tpsd_hier,
1264 reg_tpsd_hier_pos, reg_tpsd_hier_len,
1265 &temp);
1266 if (ret)
1267 return ret;
1268 deb_info("HIERARCHY ");
1269 switch (temp) {
1270 case 0:
1271 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1272 deb_info("NONE\n");
1273 break;
1274 case 1:
1275 fep->u.ofdm.hierarchy_information = HIERARCHY_1;
1276 deb_info("1\n");
1277 break;
1278 case 2:
1279 fep->u.ofdm.hierarchy_information = HIERARCHY_2;
1280 deb_info("2\n");
1281 break;
1282 case 3:
1283 fep->u.ofdm.hierarchy_information = HIERARCHY_4;
1284 deb_info("4\n");
1285 break;
1286 }
1287
1288 /* high/low priority */
1289 ret =
1290 af9005_read_register_bits(state->d, xd_g_reg_dec_pri,
1291 reg_dec_pri_pos, reg_dec_pri_len, &temp);
1292 if (ret)
1293 return ret;
1294 /* if temp is set = high priority */
1295 deb_info("PRIORITY %s\n", temp ? "high" : "low");
1296
1297 /* high coderate */
1298 ret =
1299 af9005_read_register_bits(state->d, xd_g_reg_tpsd_hpcr,
1300 reg_tpsd_hpcr_pos, reg_tpsd_hpcr_len,
1301 &temp);
1302 if (ret)
1303 return ret;
1304 deb_info("CODERATE HP ");
1305 switch (temp) {
1306 case 0:
1307 fep->u.ofdm.code_rate_HP = FEC_1_2;
1308 deb_info("FEC_1_2\n");
1309 break;
1310 case 1:
1311 fep->u.ofdm.code_rate_HP = FEC_2_3;
1312 deb_info("FEC_2_3\n");
1313 break;
1314 case 2:
1315 fep->u.ofdm.code_rate_HP = FEC_3_4;
1316 deb_info("FEC_3_4\n");
1317 break;
1318 case 3:
1319 fep->u.ofdm.code_rate_HP = FEC_5_6;
1320 deb_info("FEC_5_6\n");
1321 break;
1322 case 4:
1323 fep->u.ofdm.code_rate_HP = FEC_7_8;
1324 deb_info("FEC_7_8\n");
1325 break;
1326 }
1327
1328 /* low coderate */
1329 ret =
1330 af9005_read_register_bits(state->d, xd_g_reg_tpsd_lpcr,
1331 reg_tpsd_lpcr_pos, reg_tpsd_lpcr_len,
1332 &temp);
1333 if (ret)
1334 return ret;
1335 deb_info("CODERATE LP ");
1336 switch (temp) {
1337 case 0:
1338 fep->u.ofdm.code_rate_LP = FEC_1_2;
1339 deb_info("FEC_1_2\n");
1340 break;
1341 case 1:
1342 fep->u.ofdm.code_rate_LP = FEC_2_3;
1343 deb_info("FEC_2_3\n");
1344 break;
1345 case 2:
1346 fep->u.ofdm.code_rate_LP = FEC_3_4;
1347 deb_info("FEC_3_4\n");
1348 break;
1349 case 3:
1350 fep->u.ofdm.code_rate_LP = FEC_5_6;
1351 deb_info("FEC_5_6\n");
1352 break;
1353 case 4:
1354 fep->u.ofdm.code_rate_LP = FEC_7_8;
1355 deb_info("FEC_7_8\n");
1356 break;
1357 }
1358
1359 /* guard interval */
1360 ret =
1361 af9005_read_register_bits(state->d, xd_g_reg_tpsd_gi,
1362 reg_tpsd_gi_pos, reg_tpsd_gi_len, &temp);
1363 if (ret)
1364 return ret;
1365 deb_info("GUARD INTERVAL ");
1366 switch (temp) {
1367 case 0:
1368 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1369 deb_info("1_32\n");
1370 break;
1371 case 1:
1372 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
1373 deb_info("1_16\n");
1374 break;
1375 case 2:
1376 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
1377 deb_info("1_8\n");
1378 break;
1379 case 3:
1380 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
1381 deb_info("1_4\n");
1382 break;
1383 }
1384
1385 /* fft */
1386 ret =
1387 af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod,
1388 reg_tpsd_txmod_pos, reg_tpsd_txmod_len,
1389 &temp);
1390 if (ret)
1391 return ret;
1392 deb_info("TRANSMISSION MODE ");
1393 switch (temp) {
1394 case 0:
1395 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
1396 deb_info("2K\n");
1397 break;
1398 case 1:
1399 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1400 deb_info("8K\n");
1401 break;
1402 }
1403
1404 /* bandwidth */
1405 ret =
1406 af9005_read_register_bits(state->d, xd_g_reg_bw, reg_bw_pos,
1407 reg_bw_len, &temp);
1408 deb_info("BANDWIDTH ");
1409 switch (temp) {
1410 case 0:
1411 fep->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
1412 deb_info("6\n");
1413 break;
1414 case 1:
1415 fep->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
1416 deb_info("7\n");
1417 break;
1418 case 2:
1419 fep->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
1420 deb_info("8\n");
1421 break;
1422 }
1423 return 0;
1424}
1425
1426static void af9005_fe_release(struct dvb_frontend *fe)
1427{
1428 struct af9005_fe_state *state =
1429 (struct af9005_fe_state *)fe->demodulator_priv;
1430 kfree(state);
1431}
1432
1433static struct dvb_frontend_ops af9005_fe_ops;
1434
1435struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d)
1436{
1437 struct af9005_fe_state *state = NULL;
1438
1439 /* allocate memory for the internal state */
1440 state = kzalloc(sizeof(struct af9005_fe_state), GFP_KERNEL);
1441 if (state == NULL)
1442 goto error;
1443
1444 deb_info("attaching frontend af9005\n");
1445
1446 state->d = d;
1447 state->opened = 0;
1448
1449 memcpy(&state->frontend.ops, &af9005_fe_ops,
1450 sizeof(struct dvb_frontend_ops));
1451 state->frontend.demodulator_priv = state;
1452
1453 return &state->frontend;
1454 error:
1455 return NULL;
1456}
1457
1458static struct dvb_frontend_ops af9005_fe_ops = {
1459 .info = {
1460 .name = "AF9005 USB DVB-T",
1461 .type = FE_OFDM,
1462 .frequency_min = 44250000,
1463 .frequency_max = 867250000,
1464 .frequency_stepsize = 250000,
1465 .caps = FE_CAN_INVERSION_AUTO |
1466 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1467 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1468 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
1469 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
1470 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |
1471 FE_CAN_HIERARCHY_AUTO,
1472 },
1473
1474 .release = af9005_fe_release,
1475
1476 .init = af9005_fe_init,
1477 .sleep = af9005_fe_sleep,
1478 .ts_bus_ctrl = af9005_ts_bus_ctrl,
1479
1480 .set_frontend = af9005_fe_set_frontend,
1481 .get_frontend = af9005_fe_get_frontend,
1482
1483 .read_status = af9005_fe_read_status,
1484 .read_ber = af9005_fe_read_ber,
1485 .read_signal_strength = af9005_fe_read_signal_strength,
1486 .read_snr = af9005_fe_read_snr,
1487 .read_ucblocks = af9005_fe_read_unc_blocks,
1488};
diff --git a/drivers/media/dvb/dvb-usb/af9005-remote.c b/drivers/media/dvb/dvb-usb/af9005-remote.c
new file mode 100644
index 00000000000..c3bc64ed405
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/af9005-remote.c
@@ -0,0 +1,157 @@
1/* DVB USB compliant Linux driver for the Afatech 9005
2 * USB1.1 DVB-T receiver.
3 *
4 * Standard remote decode function
5 *
6 * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
7 *
8 * Thanks to Afatech who kindly provided information.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * see Documentation/dvb/REDME.dvb-usb for more information
25 */
26#include "af9005.h"
27/* debug */
28static int dvb_usb_af9005_remote_debug;
29module_param_named(debug, dvb_usb_af9005_remote_debug, int, 0644);
30MODULE_PARM_DESC(debug,
31 "enable (1) or disable (0) debug messages."
32 DVB_USB_DEBUG_STATUS);
33
34#define deb_decode(args...) dprintk(dvb_usb_af9005_remote_debug,0x01,args)
35
36struct rc_map_table rc_map_af9005_table[] = {
37
38 {0x01b7, KEY_POWER},
39 {0x01a7, KEY_VOLUMEUP},
40 {0x0187, KEY_CHANNELUP},
41 {0x017f, KEY_MUTE},
42 {0x01bf, KEY_VOLUMEDOWN},
43 {0x013f, KEY_CHANNELDOWN},
44 {0x01df, KEY_1},
45 {0x015f, KEY_2},
46 {0x019f, KEY_3},
47 {0x011f, KEY_4},
48 {0x01ef, KEY_5},
49 {0x016f, KEY_6},
50 {0x01af, KEY_7},
51 {0x0127, KEY_8},
52 {0x0107, KEY_9},
53 {0x01cf, KEY_ZOOM},
54 {0x014f, KEY_0},
55 {0x018f, KEY_GOTO}, /* marked jump on the remote */
56
57 {0x00bd, KEY_POWER},
58 {0x007d, KEY_VOLUMEUP},
59 {0x00fd, KEY_CHANNELUP},
60 {0x009d, KEY_MUTE},
61 {0x005d, KEY_VOLUMEDOWN},
62 {0x00dd, KEY_CHANNELDOWN},
63 {0x00ad, KEY_1},
64 {0x006d, KEY_2},
65 {0x00ed, KEY_3},
66 {0x008d, KEY_4},
67 {0x004d, KEY_5},
68 {0x00cd, KEY_6},
69 {0x00b5, KEY_7},
70 {0x0075, KEY_8},
71 {0x00f5, KEY_9},
72 {0x0095, KEY_ZOOM},
73 {0x0055, KEY_0},
74 {0x00d5, KEY_GOTO}, /* marked jump on the remote */
75};
76
77int rc_map_af9005_table_size = ARRAY_SIZE(rc_map_af9005_table);
78
79static int repeatable_keys[] = {
80 KEY_VOLUMEUP,
81 KEY_VOLUMEDOWN,
82 KEY_CHANNELUP,
83 KEY_CHANNELDOWN
84};
85
86int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
87 int *state)
88{
89 u16 mark, space;
90 u32 result;
91 u8 cust, dat, invdat;
92 int i;
93
94 if (len >= 6) {
95 mark = (u16) (data[0] << 8) + data[1];
96 space = (u16) (data[2] << 8) + data[3];
97 if (space * 3 < mark) {
98 for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) {
99 if (d->last_event == repeatable_keys[i]) {
100 *state = REMOTE_KEY_REPEAT;
101 *event = d->last_event;
102 deb_decode("repeat key, event %x\n",
103 *event);
104 return 0;
105 }
106 }
107 deb_decode("repeated key ignored (non repeatable)\n");
108 return 0;
109 } else if (len >= 33 * 4) { /*32 bits + start code */
110 result = 0;
111 for (i = 4; i < 4 + 32 * 4; i += 4) {
112 result <<= 1;
113 mark = (u16) (data[i] << 8) + data[i + 1];
114 mark >>= 1;
115 space = (u16) (data[i + 2] << 8) + data[i + 3];
116 space >>= 1;
117 if (mark * 2 > space)
118 result += 1;
119 }
120 deb_decode("key pressed, raw value %x\n", result);
121 if ((result & 0xff000000) != 0xfe000000) {
122 deb_decode
123 ("doesn't start with 0xfe, ignored\n");
124 return 0;
125 }
126 cust = (result >> 16) & 0xff;
127 dat = (result >> 8) & 0xff;
128 invdat = (~result) & 0xff;
129 if (dat != invdat) {
130 deb_decode("code != inverted code\n");
131 return 0;
132 }
133 for (i = 0; i < rc_map_af9005_table_size; i++) {
134 if (rc5_custom(&rc_map_af9005_table[i]) == cust
135 && rc5_data(&rc_map_af9005_table[i]) == dat) {
136 *event = rc_map_af9005_table[i].keycode;
137 *state = REMOTE_KEY_PRESSED;
138 deb_decode
139 ("key pressed, event %x\n", *event);
140 return 0;
141 }
142 }
143 deb_decode("not found in table\n");
144 }
145 }
146 return 0;
147}
148
149EXPORT_SYMBOL(rc_map_af9005_table);
150EXPORT_SYMBOL(rc_map_af9005_table_size);
151EXPORT_SYMBOL(af9005_rc_decode);
152
153MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");
154MODULE_DESCRIPTION
155 ("Standard remote control decoder for Afatech 9005 DVB-T USB1.1 stick");
156MODULE_VERSION("1.0");
157MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/af9005-script.h b/drivers/media/dvb/dvb-usb/af9005-script.h
new file mode 100644
index 00000000000..4d69045426d
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/af9005-script.h
@@ -0,0 +1,203 @@
1/*
2File automatically generated by createinit.py using data
3extracted from AF05BDA.sys (windows driver):
4
5dd if=AF05BDA.sys of=initsequence bs=1 skip=88316 count=1110
6python createinit.py > af9005-script.h
7
8*/
9
10typedef struct {
11 u16 reg;
12 u8 pos;
13 u8 len;
14 u8 val;
15} RegDesc;
16
17static RegDesc script[] = {
18 {0xa180, 0x0, 0x8, 0xa},
19 {0xa181, 0x0, 0x8, 0xd7},
20 {0xa182, 0x0, 0x8, 0xa3},
21 {0xa0a0, 0x0, 0x8, 0x0},
22 {0xa0a1, 0x0, 0x5, 0x0},
23 {0xa0a1, 0x5, 0x1, 0x1},
24 {0xa0c0, 0x0, 0x4, 0x1},
25 {0xa20e, 0x4, 0x4, 0xa},
26 {0xa20f, 0x0, 0x8, 0x40},
27 {0xa210, 0x0, 0x8, 0x8},
28 {0xa32a, 0x0, 0x4, 0xa},
29 {0xa32c, 0x0, 0x8, 0x20},
30 {0xa32b, 0x0, 0x8, 0x15},
31 {0xa1a0, 0x1, 0x1, 0x1},
32 {0xa000, 0x0, 0x1, 0x1},
33 {0xa000, 0x1, 0x1, 0x0},
34 {0xa001, 0x1, 0x1, 0x1},
35 {0xa001, 0x0, 0x1, 0x0},
36 {0xa001, 0x5, 0x1, 0x0},
37 {0xa00e, 0x0, 0x5, 0x10},
38 {0xa00f, 0x0, 0x3, 0x4},
39 {0xa00f, 0x3, 0x3, 0x5},
40 {0xa010, 0x0, 0x3, 0x4},
41 {0xa010, 0x3, 0x3, 0x5},
42 {0xa016, 0x4, 0x4, 0x3},
43 {0xa01f, 0x0, 0x6, 0xa},
44 {0xa020, 0x0, 0x6, 0xa},
45 {0xa2bc, 0x0, 0x1, 0x1},
46 {0xa2bc, 0x5, 0x1, 0x1},
47 {0xa015, 0x0, 0x8, 0x50},
48 {0xa016, 0x0, 0x1, 0x0},
49 {0xa02a, 0x0, 0x8, 0x50},
50 {0xa029, 0x0, 0x8, 0x4b},
51 {0xa614, 0x0, 0x8, 0x46},
52 {0xa002, 0x0, 0x5, 0x19},
53 {0xa003, 0x0, 0x5, 0x1a},
54 {0xa004, 0x0, 0x5, 0x19},
55 {0xa005, 0x0, 0x5, 0x1a},
56 {0xa008, 0x0, 0x8, 0x69},
57 {0xa009, 0x0, 0x2, 0x2},
58 {0xae1b, 0x0, 0x8, 0x69},
59 {0xae1c, 0x0, 0x8, 0x2},
60 {0xae1d, 0x0, 0x8, 0x2a},
61 {0xa022, 0x0, 0x8, 0xaa},
62 {0xa006, 0x0, 0x8, 0xc8},
63 {0xa007, 0x0, 0x2, 0x0},
64 {0xa00c, 0x0, 0x8, 0xba},
65 {0xa00d, 0x0, 0x2, 0x2},
66 {0xa608, 0x0, 0x8, 0xba},
67 {0xa60e, 0x0, 0x2, 0x2},
68 {0xa609, 0x0, 0x8, 0x80},
69 {0xa60e, 0x2, 0x2, 0x3},
70 {0xa00a, 0x0, 0x8, 0xb6},
71 {0xa00b, 0x0, 0x2, 0x0},
72 {0xa011, 0x0, 0x8, 0xb9},
73 {0xa012, 0x0, 0x2, 0x0},
74 {0xa013, 0x0, 0x8, 0xbd},
75 {0xa014, 0x0, 0x2, 0x2},
76 {0xa366, 0x0, 0x1, 0x1},
77 {0xa2bc, 0x3, 0x1, 0x0},
78 {0xa2bd, 0x0, 0x8, 0xa},
79 {0xa2be, 0x0, 0x8, 0x14},
80 {0xa2bf, 0x0, 0x8, 0x8},
81 {0xa60a, 0x0, 0x8, 0xbd},
82 {0xa60e, 0x4, 0x2, 0x2},
83 {0xa60b, 0x0, 0x8, 0x86},
84 {0xa60e, 0x6, 0x2, 0x3},
85 {0xa001, 0x2, 0x2, 0x1},
86 {0xa1c7, 0x0, 0x8, 0xf5},
87 {0xa03d, 0x0, 0x8, 0xb1},
88 {0xa616, 0x0, 0x8, 0xff},
89 {0xa617, 0x0, 0x8, 0xad},
90 {0xa618, 0x0, 0x8, 0xad},
91 {0xa61e, 0x3, 0x1, 0x1},
92 {0xae1a, 0x0, 0x8, 0x0},
93 {0xae19, 0x0, 0x8, 0xc8},
94 {0xae18, 0x0, 0x8, 0x61},
95 {0xa140, 0x0, 0x8, 0x0},
96 {0xa141, 0x0, 0x8, 0xc8},
97 {0xa142, 0x0, 0x7, 0x61},
98 {0xa023, 0x0, 0x8, 0xff},
99 {0xa021, 0x0, 0x8, 0xad},
100 {0xa026, 0x0, 0x1, 0x0},
101 {0xa024, 0x0, 0x8, 0xff},
102 {0xa025, 0x0, 0x8, 0xff},
103 {0xa1c8, 0x0, 0x8, 0xf},
104 {0xa2bc, 0x1, 0x1, 0x0},
105 {0xa60c, 0x0, 0x4, 0x5},
106 {0xa60c, 0x4, 0x4, 0x6},
107 {0xa60d, 0x0, 0x8, 0xa},
108 {0xa371, 0x0, 0x1, 0x1},
109 {0xa366, 0x1, 0x3, 0x7},
110 {0xa338, 0x0, 0x8, 0x10},
111 {0xa339, 0x0, 0x6, 0x7},
112 {0xa33a, 0x0, 0x6, 0x1f},
113 {0xa33b, 0x0, 0x8, 0xf6},
114 {0xa33c, 0x3, 0x5, 0x4},
115 {0xa33d, 0x4, 0x4, 0x0},
116 {0xa33d, 0x1, 0x1, 0x1},
117 {0xa33d, 0x2, 0x1, 0x1},
118 {0xa33d, 0x3, 0x1, 0x1},
119 {0xa16d, 0x0, 0x4, 0xf},
120 {0xa161, 0x0, 0x5, 0x5},
121 {0xa162, 0x0, 0x4, 0x5},
122 {0xa165, 0x0, 0x8, 0xff},
123 {0xa166, 0x0, 0x8, 0x9c},
124 {0xa2c3, 0x0, 0x4, 0x5},
125 {0xa61a, 0x0, 0x6, 0xf},
126 {0xb200, 0x0, 0x8, 0xa1},
127 {0xb201, 0x0, 0x8, 0x7},
128 {0xa093, 0x0, 0x1, 0x0},
129 {0xa093, 0x1, 0x5, 0xf},
130 {0xa094, 0x0, 0x8, 0xff},
131 {0xa095, 0x0, 0x8, 0xf},
132 {0xa080, 0x2, 0x5, 0x3},
133 {0xa081, 0x0, 0x4, 0x0},
134 {0xa081, 0x4, 0x4, 0x9},
135 {0xa082, 0x0, 0x5, 0x1f},
136 {0xa08d, 0x0, 0x8, 0x1},
137 {0xa083, 0x0, 0x8, 0x32},
138 {0xa084, 0x0, 0x1, 0x0},
139 {0xa08e, 0x0, 0x8, 0x3},
140 {0xa085, 0x0, 0x8, 0x32},
141 {0xa086, 0x0, 0x3, 0x0},
142 {0xa087, 0x0, 0x8, 0x6e},
143 {0xa088, 0x0, 0x5, 0x15},
144 {0xa089, 0x0, 0x8, 0x0},
145 {0xa08a, 0x0, 0x5, 0x19},
146 {0xa08b, 0x0, 0x8, 0x92},
147 {0xa08c, 0x0, 0x5, 0x1c},
148 {0xa120, 0x0, 0x8, 0x0},
149 {0xa121, 0x0, 0x5, 0x10},
150 {0xa122, 0x0, 0x8, 0x0},
151 {0xa123, 0x0, 0x7, 0x40},
152 {0xa123, 0x7, 0x1, 0x0},
153 {0xa124, 0x0, 0x8, 0x13},
154 {0xa125, 0x0, 0x7, 0x10},
155 {0xa1c0, 0x0, 0x8, 0x0},
156 {0xa1c1, 0x0, 0x5, 0x4},
157 {0xa1c2, 0x0, 0x8, 0x0},
158 {0xa1c3, 0x0, 0x5, 0x10},
159 {0xa1c3, 0x5, 0x3, 0x0},
160 {0xa1c4, 0x0, 0x6, 0x0},
161 {0xa1c5, 0x0, 0x7, 0x10},
162 {0xa100, 0x0, 0x8, 0x0},
163 {0xa101, 0x0, 0x5, 0x10},
164 {0xa102, 0x0, 0x8, 0x0},
165 {0xa103, 0x0, 0x7, 0x40},
166 {0xa103, 0x7, 0x1, 0x0},
167 {0xa104, 0x0, 0x8, 0x18},
168 {0xa105, 0x0, 0x7, 0xa},
169 {0xa106, 0x0, 0x8, 0x20},
170 {0xa107, 0x0, 0x8, 0x40},
171 {0xa108, 0x0, 0x4, 0x0},
172 {0xa38c, 0x0, 0x8, 0xfc},
173 {0xa38d, 0x0, 0x8, 0x0},
174 {0xa38e, 0x0, 0x8, 0x7e},
175 {0xa38f, 0x0, 0x8, 0x0},
176 {0xa390, 0x0, 0x8, 0x2f},
177 {0xa60f, 0x5, 0x1, 0x1},
178 {0xa170, 0x0, 0x8, 0xdc},
179 {0xa171, 0x0, 0x2, 0x0},
180 {0xa2ae, 0x0, 0x1, 0x1},
181 {0xa2ae, 0x1, 0x1, 0x1},
182 {0xa392, 0x0, 0x1, 0x1},
183 {0xa391, 0x2, 0x1, 0x0},
184 {0xabc1, 0x0, 0x8, 0xff},
185 {0xabc2, 0x0, 0x8, 0x0},
186 {0xabc8, 0x0, 0x8, 0x8},
187 {0xabca, 0x0, 0x8, 0x10},
188 {0xabcb, 0x0, 0x1, 0x0},
189 {0xabc3, 0x5, 0x3, 0x7},
190 {0xabc0, 0x6, 0x1, 0x0},
191 {0xabc0, 0x4, 0x2, 0x0},
192 {0xa344, 0x4, 0x4, 0x1},
193 {0xabc0, 0x7, 0x1, 0x1},
194 {0xabc0, 0x2, 0x1, 0x1},
195 {0xa345, 0x0, 0x8, 0x66},
196 {0xa346, 0x0, 0x8, 0x66},
197 {0xa347, 0x0, 0x4, 0x0},
198 {0xa343, 0x0, 0x4, 0xa},
199 {0xa347, 0x4, 0x4, 0x2},
200 {0xa348, 0x0, 0x4, 0xc},
201 {0xa348, 0x4, 0x4, 0x7},
202 {0xa349, 0x0, 0x6, 0x2},
203};
diff --git a/drivers/media/dvb/dvb-usb/af9005.c b/drivers/media/dvb/dvb-usb/af9005.c
new file mode 100644
index 00000000000..51f6439dcfd
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/af9005.c
@@ -0,0 +1,1105 @@
1/* DVB USB compliant Linux driver for the Afatech 9005
2 * USB1.1 DVB-T receiver.
3 *
4 * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
5 *
6 * Thanks to Afatech who kindly provided information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * see Documentation/dvb/REDME.dvb-usb for more information
23 */
24#include "af9005.h"
25
26/* debug */
27int dvb_usb_af9005_debug;
28module_param_named(debug, dvb_usb_af9005_debug, int, 0644);
29MODULE_PARM_DESC(debug,
30 "set debugging level (1=info,xfer=2,rc=4,reg=8,i2c=16,fw=32 (or-able))."
31 DVB_USB_DEBUG_STATUS);
32/* enable obnoxious led */
33int dvb_usb_af9005_led = 1;
34module_param_named(led, dvb_usb_af9005_led, bool, 0644);
35MODULE_PARM_DESC(led, "enable led (default: 1).");
36
37/* eeprom dump */
38static int dvb_usb_af9005_dump_eeprom;
39module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0);
40MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom.");
41
42DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
43
44/* remote control decoder */
45static int (*rc_decode) (struct dvb_usb_device *d, u8 *data, int len,
46 u32 *event, int *state);
47static void *rc_keys;
48static int *rc_keys_size;
49
50u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
51
52struct af9005_device_state {
53 u8 sequence;
54 int led_state;
55};
56
57static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,
58 int readwrite, int type, u8 * values, int len)
59{
60 struct af9005_device_state *st = d->priv;
61 u8 obuf[16] = { 0 };
62 u8 ibuf[17] = { 0 };
63 u8 command;
64 int i;
65 int ret;
66
67 if (len < 1) {
68 err("generic read/write, less than 1 byte. Makes no sense.");
69 return -EINVAL;
70 }
71 if (len > 8) {
72 err("generic read/write, more than 8 bytes. Not supported.");
73 return -EINVAL;
74 }
75
76 obuf[0] = 14; /* rest of buffer length low */
77 obuf[1] = 0; /* rest of buffer length high */
78
79 obuf[2] = AF9005_REGISTER_RW; /* register operation */
80 obuf[3] = 12; /* rest of buffer length */
81
82 obuf[4] = st->sequence++; /* sequence number */
83
84 obuf[5] = (u8) (reg >> 8); /* register address */
85 obuf[6] = (u8) (reg & 0xff);
86
87 if (type == AF9005_OFDM_REG) {
88 command = AF9005_CMD_OFDM_REG;
89 } else {
90 command = AF9005_CMD_TUNER;
91 }
92
93 if (len > 1)
94 command |=
95 AF9005_CMD_BURST | AF9005_CMD_AUTOINC | (len - 1) << 3;
96 command |= readwrite;
97 if (readwrite == AF9005_CMD_WRITE)
98 for (i = 0; i < len; i++)
99 obuf[8 + i] = values[i];
100 else if (type == AF9005_TUNER_REG)
101 /* read command for tuner, the first byte contains the i2c address */
102 obuf[8] = values[0];
103 obuf[7] = command;
104
105 ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 17, 0);
106 if (ret)
107 return ret;
108
109 /* sanity check */
110 if (ibuf[2] != AF9005_REGISTER_RW_ACK) {
111 err("generic read/write, wrong reply code.");
112 return -EIO;
113 }
114 if (ibuf[3] != 0x0d) {
115 err("generic read/write, wrong length in reply.");
116 return -EIO;
117 }
118 if (ibuf[4] != obuf[4]) {
119 err("generic read/write, wrong sequence in reply.");
120 return -EIO;
121 }
122 /*
123 Windows driver doesn't check these fields, in fact sometimes
124 the register in the reply is different that what has been sent
125
126 if (ibuf[5] != obuf[5] || ibuf[6] != obuf[6]) {
127 err("generic read/write, wrong register in reply.");
128 return -EIO;
129 }
130 if (ibuf[7] != command) {
131 err("generic read/write wrong command in reply.");
132 return -EIO;
133 }
134 */
135 if (ibuf[16] != 0x01) {
136 err("generic read/write wrong status code in reply.");
137 return -EIO;
138 }
139 if (readwrite == AF9005_CMD_READ)
140 for (i = 0; i < len; i++)
141 values[i] = ibuf[8 + i];
142
143 return 0;
144
145}
146
147int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 * value)
148{
149 int ret;
150 deb_reg("read register %x ", reg);
151 ret = af9005_generic_read_write(d, reg,
152 AF9005_CMD_READ, AF9005_OFDM_REG,
153 value, 1);
154 if (ret)
155 deb_reg("failed\n");
156 else
157 deb_reg("value %x\n", *value);
158 return ret;
159}
160
161int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg,
162 u8 * values, int len)
163{
164 int ret;
165 deb_reg("read %d registers %x ", len, reg);
166 ret = af9005_generic_read_write(d, reg,
167 AF9005_CMD_READ, AF9005_OFDM_REG,
168 values, len);
169 if (ret)
170 deb_reg("failed\n");
171 else
172 debug_dump(values, len, deb_reg);
173 return ret;
174}
175
176int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 value)
177{
178 int ret;
179 u8 temp = value;
180 deb_reg("write register %x value %x ", reg, value);
181 ret = af9005_generic_read_write(d, reg,
182 AF9005_CMD_WRITE, AF9005_OFDM_REG,
183 &temp, 1);
184 if (ret)
185 deb_reg("failed\n");
186 else
187 deb_reg("ok\n");
188 return ret;
189}
190
191int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg,
192 u8 * values, int len)
193{
194 int ret;
195 deb_reg("write %d registers %x values ", len, reg);
196 debug_dump(values, len, deb_reg);
197
198 ret = af9005_generic_read_write(d, reg,
199 AF9005_CMD_WRITE, AF9005_OFDM_REG,
200 values, len);
201 if (ret)
202 deb_reg("failed\n");
203 else
204 deb_reg("ok\n");
205 return ret;
206}
207
208int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos,
209 u8 len, u8 * value)
210{
211 u8 temp;
212 int ret;
213 deb_reg("read bits %x %x %x", reg, pos, len);
214 ret = af9005_read_ofdm_register(d, reg, &temp);
215 if (ret) {
216 deb_reg(" failed\n");
217 return ret;
218 }
219 *value = (temp >> pos) & regmask[len - 1];
220 deb_reg(" value %x\n", *value);
221 return 0;
222
223}
224
225int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos,
226 u8 len, u8 value)
227{
228 u8 temp, mask;
229 int ret;
230 deb_reg("write bits %x %x %x value %x\n", reg, pos, len, value);
231 if (pos == 0 && len == 8)
232 return af9005_write_ofdm_register(d, reg, value);
233 ret = af9005_read_ofdm_register(d, reg, &temp);
234 if (ret)
235 return ret;
236 mask = regmask[len - 1] << pos;
237 temp = (temp & ~mask) | ((value << pos) & mask);
238 return af9005_write_ofdm_register(d, reg, temp);
239
240}
241
242static int af9005_usb_read_tuner_registers(struct dvb_usb_device *d,
243 u16 reg, u8 * values, int len)
244{
245 return af9005_generic_read_write(d, reg,
246 AF9005_CMD_READ, AF9005_TUNER_REG,
247 values, len);
248}
249
250static int af9005_usb_write_tuner_registers(struct dvb_usb_device *d,
251 u16 reg, u8 * values, int len)
252{
253 return af9005_generic_read_write(d, reg,
254 AF9005_CMD_WRITE,
255 AF9005_TUNER_REG, values, len);
256}
257
258int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg,
259 u8 * values, int len)
260{
261 /* don't let the name of this function mislead you: it's just used
262 as an interface from the firmware to the i2c bus. The actual
263 i2c addresses are contained in the data */
264 int ret, i, done = 0, fail = 0;
265 u8 temp;
266 ret = af9005_usb_write_tuner_registers(d, reg, values, len);
267 if (ret)
268 return ret;
269 if (reg != 0xffff) {
270 /* check if write done (0xa40d bit 1) or fail (0xa40d bit 2) */
271 for (i = 0; i < 200; i++) {
272 ret =
273 af9005_read_ofdm_register(d,
274 xd_I2C_i2c_m_status_wdat_done,
275 &temp);
276 if (ret)
277 return ret;
278 done = temp & (regmask[i2c_m_status_wdat_done_len - 1]
279 << i2c_m_status_wdat_done_pos);
280 if (done)
281 break;
282 fail = temp & (regmask[i2c_m_status_wdat_fail_len - 1]
283 << i2c_m_status_wdat_fail_pos);
284 if (fail)
285 break;
286 msleep(50);
287 }
288 if (i == 200)
289 return -ETIMEDOUT;
290 if (fail) {
291 /* clear write fail bit */
292 af9005_write_register_bits(d,
293 xd_I2C_i2c_m_status_wdat_fail,
294 i2c_m_status_wdat_fail_pos,
295 i2c_m_status_wdat_fail_len,
296 1);
297 return -EIO;
298 }
299 /* clear write done bit */
300 ret =
301 af9005_write_register_bits(d,
302 xd_I2C_i2c_m_status_wdat_fail,
303 i2c_m_status_wdat_done_pos,
304 i2c_m_status_wdat_done_len, 1);
305 if (ret)
306 return ret;
307 }
308 return 0;
309}
310
311int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg, u8 addr,
312 u8 * values, int len)
313{
314 /* don't let the name of this function mislead you: it's just used
315 as an interface from the firmware to the i2c bus. The actual
316 i2c addresses are contained in the data */
317 int ret, i;
318 u8 temp, buf[2];
319
320 buf[0] = addr; /* tuner i2c address */
321 buf[1] = values[0]; /* tuner register */
322
323 values[0] = addr + 0x01; /* i2c read address */
324
325 if (reg == APO_REG_I2C_RW_SILICON_TUNER) {
326 /* write tuner i2c address to tuner, 0c00c0 undocumented, found by sniffing */
327 ret = af9005_write_tuner_registers(d, 0x00c0, buf, 2);
328 if (ret)
329 return ret;
330 }
331
332 /* send read command to ofsm */
333 ret = af9005_usb_read_tuner_registers(d, reg, values, 1);
334 if (ret)
335 return ret;
336
337 /* check if read done */
338 for (i = 0; i < 200; i++) {
339 ret = af9005_read_ofdm_register(d, 0xa408, &temp);
340 if (ret)
341 return ret;
342 if (temp & 0x01)
343 break;
344 msleep(50);
345 }
346 if (i == 200)
347 return -ETIMEDOUT;
348
349 /* clear read done bit (by writing 1) */
350 ret = af9005_write_ofdm_register(d, xd_I2C_i2c_m_data8, 1);
351 if (ret)
352 return ret;
353
354 /* get read data (available from 0xa400) */
355 for (i = 0; i < len; i++) {
356 ret = af9005_read_ofdm_register(d, 0xa400 + i, &temp);
357 if (ret)
358 return ret;
359 values[i] = temp;
360 }
361 return 0;
362}
363
364static int af9005_i2c_write(struct dvb_usb_device *d, u8 i2caddr, u8 reg,
365 u8 * data, int len)
366{
367 int ret, i;
368 u8 buf[3];
369 deb_i2c("i2c_write i2caddr %x, reg %x, len %d data ", i2caddr,
370 reg, len);
371 debug_dump(data, len, deb_i2c);
372
373 for (i = 0; i < len; i++) {
374 buf[0] = i2caddr;
375 buf[1] = reg + (u8) i;
376 buf[2] = data[i];
377 ret =
378 af9005_write_tuner_registers(d,
379 APO_REG_I2C_RW_SILICON_TUNER,
380 buf, 3);
381 if (ret) {
382 deb_i2c("i2c_write failed\n");
383 return ret;
384 }
385 }
386 deb_i2c("i2c_write ok\n");
387 return 0;
388}
389
390static int af9005_i2c_read(struct dvb_usb_device *d, u8 i2caddr, u8 reg,
391 u8 * data, int len)
392{
393 int ret, i;
394 u8 temp;
395 deb_i2c("i2c_read i2caddr %x, reg %x, len %d\n ", i2caddr, reg, len);
396 for (i = 0; i < len; i++) {
397 temp = reg + i;
398 ret =
399 af9005_read_tuner_registers(d,
400 APO_REG_I2C_RW_SILICON_TUNER,
401 i2caddr, &temp, 1);
402 if (ret) {
403 deb_i2c("i2c_read failed\n");
404 return ret;
405 }
406 data[i] = temp;
407 }
408 deb_i2c("i2c data read: ");
409 debug_dump(data, len, deb_i2c);
410 return 0;
411}
412
413static int af9005_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
414 int num)
415{
416 /* only implements what the mt2060 module does, don't know how
417 to make it really generic */
418 struct dvb_usb_device *d = i2c_get_adapdata(adap);
419 int ret;
420 u8 reg, addr;
421 u8 *value;
422
423 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
424 return -EAGAIN;
425
426 if (num > 2)
427 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
428
429 if (num == 2) {
430 /* reads a single register */
431 reg = *msg[0].buf;
432 addr = msg[0].addr;
433 value = msg[1].buf;
434 ret = af9005_i2c_read(d, addr, reg, value, 1);
435 if (ret == 0)
436 ret = 2;
437 } else {
438 /* write one or more registers */
439 reg = msg[0].buf[0];
440 addr = msg[0].addr;
441 value = &msg[0].buf[1];
442 ret = af9005_i2c_write(d, addr, reg, value, msg[0].len - 1);
443 if (ret == 0)
444 ret = 1;
445 }
446
447 mutex_unlock(&d->i2c_mutex);
448 return ret;
449}
450
451static u32 af9005_i2c_func(struct i2c_adapter *adapter)
452{
453 return I2C_FUNC_I2C;
454}
455
456static struct i2c_algorithm af9005_i2c_algo = {
457 .master_xfer = af9005_i2c_xfer,
458 .functionality = af9005_i2c_func,
459};
460
461int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf,
462 int wlen, u8 * rbuf, int rlen)
463{
464 struct af9005_device_state *st = d->priv;
465
466 int ret, i, packet_len;
467 u8 buf[64];
468 u8 ibuf[64];
469
470 if (wlen < 0) {
471 err("send command, wlen less than 0 bytes. Makes no sense.");
472 return -EINVAL;
473 }
474 if (wlen > 54) {
475 err("send command, wlen more than 54 bytes. Not supported.");
476 return -EINVAL;
477 }
478 if (rlen > 54) {
479 err("send command, rlen more than 54 bytes. Not supported.");
480 return -EINVAL;
481 }
482 packet_len = wlen + 5;
483 buf[0] = (u8) (packet_len & 0xff);
484 buf[1] = (u8) ((packet_len & 0xff00) >> 8);
485
486 buf[2] = 0x26; /* packet type */
487 buf[3] = wlen + 3;
488 buf[4] = st->sequence++;
489 buf[5] = command;
490 buf[6] = wlen;
491 for (i = 0; i < wlen; i++)
492 buf[7 + i] = wbuf[i];
493 ret = dvb_usb_generic_rw(d, buf, wlen + 7, ibuf, rlen + 7, 0);
494 if (ret)
495 return ret;
496 if (ibuf[2] != 0x27) {
497 err("send command, wrong reply code.");
498 return -EIO;
499 }
500 if (ibuf[4] != buf[4]) {
501 err("send command, wrong sequence in reply.");
502 return -EIO;
503 }
504 if (ibuf[5] != 0x01) {
505 err("send command, wrong status code in reply.");
506 return -EIO;
507 }
508 if (ibuf[6] != rlen) {
509 err("send command, invalid data length in reply.");
510 return -EIO;
511 }
512 for (i = 0; i < rlen; i++)
513 rbuf[i] = ibuf[i + 7];
514 return 0;
515}
516
517int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, u8 * values,
518 int len)
519{
520 struct af9005_device_state *st = d->priv;
521 u8 obuf[16], ibuf[14];
522 int ret, i;
523
524 memset(obuf, 0, sizeof(obuf));
525 memset(ibuf, 0, sizeof(ibuf));
526
527 obuf[0] = 14; /* length of rest of packet low */
528 obuf[1] = 0; /* length of rest of packer high */
529
530 obuf[2] = 0x2a; /* read/write eeprom */
531
532 obuf[3] = 12; /* size */
533
534 obuf[4] = st->sequence++;
535
536 obuf[5] = 0; /* read */
537
538 obuf[6] = len;
539 obuf[7] = address;
540 ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 14, 0);
541 if (ret)
542 return ret;
543 if (ibuf[2] != 0x2b) {
544 err("Read eeprom, invalid reply code");
545 return -EIO;
546 }
547 if (ibuf[3] != 10) {
548 err("Read eeprom, invalid reply length");
549 return -EIO;
550 }
551 if (ibuf[4] != obuf[4]) {
552 err("Read eeprom, wrong sequence in reply ");
553 return -EIO;
554 }
555 if (ibuf[5] != 1) {
556 err("Read eeprom, wrong status in reply ");
557 return -EIO;
558 }
559 for (i = 0; i < len; i++) {
560 values[i] = ibuf[6 + i];
561 }
562 return 0;
563}
564
565static int af9005_boot_packet(struct usb_device *udev, int type, u8 * reply)
566{
567 u8 buf[FW_BULKOUT_SIZE + 2];
568 u16 checksum;
569 int act_len, i, ret;
570 memset(buf, 0, sizeof(buf));
571 buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);
572 buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);
573 switch (type) {
574 case FW_CONFIG:
575 buf[2] = 0x11;
576 buf[3] = 0x04;
577 buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */
578 buf[5] = 0x03;
579 checksum = buf[4] + buf[5];
580 buf[6] = (u8) ((checksum >> 8) & 0xff);
581 buf[7] = (u8) (checksum & 0xff);
582 break;
583 case FW_CONFIRM:
584 buf[2] = 0x11;
585 buf[3] = 0x04;
586 buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */
587 buf[5] = 0x01;
588 checksum = buf[4] + buf[5];
589 buf[6] = (u8) ((checksum >> 8) & 0xff);
590 buf[7] = (u8) (checksum & 0xff);
591 break;
592 case FW_BOOT:
593 buf[2] = 0x10;
594 buf[3] = 0x08;
595 buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */
596 buf[5] = 0x97;
597 buf[6] = 0xaa;
598 buf[7] = 0x55;
599 buf[8] = 0xa5;
600 buf[9] = 0x5a;
601 checksum = 0;
602 for (i = 4; i <= 9; i++)
603 checksum += buf[i];
604 buf[10] = (u8) ((checksum >> 8) & 0xff);
605 buf[11] = (u8) (checksum & 0xff);
606 break;
607 default:
608 err("boot packet invalid boot packet type");
609 return -EINVAL;
610 }
611 deb_fw(">>> ");
612 debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw);
613
614 ret = usb_bulk_msg(udev,
615 usb_sndbulkpipe(udev, 0x02),
616 buf, FW_BULKOUT_SIZE + 2, &act_len, 2000);
617 if (ret)
618 err("boot packet bulk message failed: %d (%d/%d)", ret,
619 FW_BULKOUT_SIZE + 2, act_len);
620 else
621 ret = act_len != FW_BULKOUT_SIZE + 2 ? -1 : 0;
622 if (ret)
623 return ret;
624 memset(buf, 0, 9);
625 ret = usb_bulk_msg(udev,
626 usb_rcvbulkpipe(udev, 0x01), buf, 9, &act_len, 2000);
627 if (ret) {
628 err("boot packet recv bulk message failed: %d", ret);
629 return ret;
630 }
631 deb_fw("<<< ");
632 debug_dump(buf, act_len, deb_fw);
633 checksum = 0;
634 switch (type) {
635 case FW_CONFIG:
636 if (buf[2] != 0x11) {
637 err("boot bad config header.");
638 return -EIO;
639 }
640 if (buf[3] != 0x05) {
641 err("boot bad config size.");
642 return -EIO;
643 }
644 if (buf[4] != 0x00) {
645 err("boot bad config sequence.");
646 return -EIO;
647 }
648 if (buf[5] != 0x04) {
649 err("boot bad config subtype.");
650 return -EIO;
651 }
652 for (i = 4; i <= 6; i++)
653 checksum += buf[i];
654 if (buf[7] * 256 + buf[8] != checksum) {
655 err("boot bad config checksum.");
656 return -EIO;
657 }
658 *reply = buf[6];
659 break;
660 case FW_CONFIRM:
661 if (buf[2] != 0x11) {
662 err("boot bad confirm header.");
663 return -EIO;
664 }
665 if (buf[3] != 0x05) {
666 err("boot bad confirm size.");
667 return -EIO;
668 }
669 if (buf[4] != 0x00) {
670 err("boot bad confirm sequence.");
671 return -EIO;
672 }
673 if (buf[5] != 0x02) {
674 err("boot bad confirm subtype.");
675 return -EIO;
676 }
677 for (i = 4; i <= 6; i++)
678 checksum += buf[i];
679 if (buf[7] * 256 + buf[8] != checksum) {
680 err("boot bad confirm checksum.");
681 return -EIO;
682 }
683 *reply = buf[6];
684 break;
685 case FW_BOOT:
686 if (buf[2] != 0x10) {
687 err("boot bad boot header.");
688 return -EIO;
689 }
690 if (buf[3] != 0x05) {
691 err("boot bad boot size.");
692 return -EIO;
693 }
694 if (buf[4] != 0x00) {
695 err("boot bad boot sequence.");
696 return -EIO;
697 }
698 if (buf[5] != 0x01) {
699 err("boot bad boot pattern 01.");
700 return -EIO;
701 }
702 if (buf[6] != 0x10) {
703 err("boot bad boot pattern 10.");
704 return -EIO;
705 }
706 for (i = 4; i <= 6; i++)
707 checksum += buf[i];
708 if (buf[7] * 256 + buf[8] != checksum) {
709 err("boot bad boot checksum.");
710 return -EIO;
711 }
712 break;
713
714 }
715
716 return 0;
717}
718
719static int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw)
720{
721 int i, packets, ret, act_len;
722
723 u8 buf[FW_BULKOUT_SIZE + 2];
724 u8 reply;
725
726 ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
727 if (ret)
728 return ret;
729 if (reply != 0x01) {
730 err("before downloading firmware, FW_CONFIG expected 0x01, received 0x%x", reply);
731 return -EIO;
732 }
733 packets = fw->size / FW_BULKOUT_SIZE;
734 buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);
735 buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);
736 for (i = 0; i < packets; i++) {
737 memcpy(&buf[2], fw->data + i * FW_BULKOUT_SIZE,
738 FW_BULKOUT_SIZE);
739 deb_fw(">>> ");
740 debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw);
741 ret = usb_bulk_msg(udev,
742 usb_sndbulkpipe(udev, 0x02),
743 buf, FW_BULKOUT_SIZE + 2, &act_len, 1000);
744 if (ret) {
745 err("firmware download failed at packet %d with code %d", i, ret);
746 return ret;
747 }
748 }
749 ret = af9005_boot_packet(udev, FW_CONFIRM, &reply);
750 if (ret)
751 return ret;
752 if (reply != (u8) (packets & 0xff)) {
753 err("after downloading firmware, FW_CONFIRM expected 0x%x, received 0x%x", packets & 0xff, reply);
754 return -EIO;
755 }
756 ret = af9005_boot_packet(udev, FW_BOOT, &reply);
757 if (ret)
758 return ret;
759 ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
760 if (ret)
761 return ret;
762 if (reply != 0x02) {
763 err("after downloading firmware, FW_CONFIG expected 0x02, received 0x%x", reply);
764 return -EIO;
765 }
766
767 return 0;
768
769}
770
771int af9005_led_control(struct dvb_usb_device *d, int onoff)
772{
773 struct af9005_device_state *st = d->priv;
774 int temp, ret;
775
776 if (onoff && dvb_usb_af9005_led)
777 temp = 1;
778 else
779 temp = 0;
780 if (st->led_state != temp) {
781 ret =
782 af9005_write_register_bits(d, xd_p_reg_top_locken1,
783 reg_top_locken1_pos,
784 reg_top_locken1_len, temp);
785 if (ret)
786 return ret;
787 ret =
788 af9005_write_register_bits(d, xd_p_reg_top_lock1,
789 reg_top_lock1_pos,
790 reg_top_lock1_len, temp);
791 if (ret)
792 return ret;
793 st->led_state = temp;
794 }
795 return 0;
796}
797
798static int af9005_frontend_attach(struct dvb_usb_adapter *adap)
799{
800 u8 buf[8];
801 int i;
802
803 /* without these calls the first commands after downloading
804 the firmware fail. I put these calls here to simulate
805 what it is done in dvb-usb-init.c.
806 */
807 struct usb_device *udev = adap->dev->udev;
808 usb_clear_halt(udev, usb_sndbulkpipe(udev, 2));
809 usb_clear_halt(udev, usb_rcvbulkpipe(udev, 1));
810 if (dvb_usb_af9005_dump_eeprom) {
811 printk("EEPROM DUMP\n");
812 for (i = 0; i < 255; i += 8) {
813 af9005_read_eeprom(adap->dev, i, buf, 8);
814 printk("ADDR %x ", i);
815 debug_dump(buf, 8, printk);
816 }
817 }
818 adap->fe = af9005_fe_attach(adap->dev);
819 return 0;
820}
821
822static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state)
823{
824 struct af9005_device_state *st = d->priv;
825 int ret, len;
826
827 u8 obuf[5];
828 u8 ibuf[256];
829
830 *state = REMOTE_NO_KEY_PRESSED;
831 if (rc_decode == NULL) {
832 /* it shouldn't never come here */
833 return 0;
834 }
835 /* deb_info("rc_query\n"); */
836 obuf[0] = 3; /* rest of packet length low */
837 obuf[1] = 0; /* rest of packet lentgh high */
838 obuf[2] = 0x40; /* read remote */
839 obuf[3] = 1; /* rest of packet length */
840 obuf[4] = st->sequence++; /* sequence number */
841 ret = dvb_usb_generic_rw(d, obuf, 5, ibuf, 256, 0);
842 if (ret) {
843 err("rc query failed");
844 return ret;
845 }
846 if (ibuf[2] != 0x41) {
847 err("rc query bad header.");
848 return -EIO;
849 }
850 if (ibuf[4] != obuf[4]) {
851 err("rc query bad sequence.");
852 return -EIO;
853 }
854 len = ibuf[5];
855 if (len > 246) {
856 err("rc query invalid length");
857 return -EIO;
858 }
859 if (len > 0) {
860 deb_rc("rc data (%d) ", len);
861 debug_dump((ibuf + 6), len, deb_rc);
862 ret = rc_decode(d, &ibuf[6], len, event, state);
863 if (ret) {
864 err("rc_decode failed");
865 return ret;
866 } else {
867 deb_rc("rc_decode state %x event %x\n", *state, *event);
868 if (*state == REMOTE_KEY_REPEAT)
869 *event = d->last_event;
870 }
871 }
872 return 0;
873}
874
875static int af9005_power_ctrl(struct dvb_usb_device *d, int onoff)
876{
877
878 return 0;
879}
880
881static int af9005_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
882{
883 int ret;
884 deb_info("pid filter control onoff %d\n", onoff);
885 if (onoff) {
886 ret =
887 af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1);
888 if (ret)
889 return ret;
890 ret =
891 af9005_write_register_bits(adap->dev,
892 XD_MP2IF_DMX_CTRL, 1, 1, 1);
893 if (ret)
894 return ret;
895 ret =
896 af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1);
897 } else
898 ret =
899 af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 0);
900 if (ret)
901 return ret;
902 deb_info("pid filter control ok\n");
903 return 0;
904}
905
906static int af9005_pid_filter(struct dvb_usb_adapter *adap, int index,
907 u16 pid, int onoff)
908{
909 u8 cmd = index & 0x1f;
910 int ret;
911 deb_info("set pid filter, index %d, pid %x, onoff %d\n", index,
912 pid, onoff);
913 if (onoff) {
914 /* cannot use it as pid_filter_ctrl since it has to be done
915 before setting the first pid */
916 if (adap->feedcount == 1) {
917 deb_info("first pid set, enable pid table\n");
918 ret = af9005_pid_filter_control(adap, onoff);
919 if (ret)
920 return ret;
921 }
922 ret =
923 af9005_write_ofdm_register(adap->dev,
924 XD_MP2IF_PID_DATA_L,
925 (u8) (pid & 0xff));
926 if (ret)
927 return ret;
928 ret =
929 af9005_write_ofdm_register(adap->dev,
930 XD_MP2IF_PID_DATA_H,
931 (u8) (pid >> 8));
932 if (ret)
933 return ret;
934 cmd |= 0x20 | 0x40;
935 } else {
936 if (adap->feedcount == 0) {
937 deb_info("last pid unset, disable pid table\n");
938 ret = af9005_pid_filter_control(adap, onoff);
939 if (ret)
940 return ret;
941 }
942 }
943 ret = af9005_write_ofdm_register(adap->dev, XD_MP2IF_PID_IDX, cmd);
944 if (ret)
945 return ret;
946 deb_info("set pid ok\n");
947 return 0;
948}
949
950static int af9005_identify_state(struct usb_device *udev,
951 struct dvb_usb_device_properties *props,
952 struct dvb_usb_device_description **desc,
953 int *cold)
954{
955 int ret;
956 u8 reply;
957 ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
958 if (ret)
959 return ret;
960 deb_info("result of FW_CONFIG in identify state %d\n", reply);
961 if (reply == 0x01)
962 *cold = 1;
963 else if (reply == 0x02)
964 *cold = 0;
965 else
966 return -EIO;
967 deb_info("Identify state cold = %d\n", *cold);
968 return 0;
969}
970
971static struct dvb_usb_device_properties af9005_properties;
972
973static int af9005_usb_probe(struct usb_interface *intf,
974 const struct usb_device_id *id)
975{
976 return dvb_usb_device_init(intf, &af9005_properties,
977 THIS_MODULE, NULL, adapter_nr);
978}
979
980static struct usb_device_id af9005_usb_table[] = {
981 {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9005)},
982 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE)},
983 {USB_DEVICE(USB_VID_ANSONIC, USB_PID_ANSONIC_DVBT_USB)},
984 {0},
985};
986
987MODULE_DEVICE_TABLE(usb, af9005_usb_table);
988
989static struct dvb_usb_device_properties af9005_properties = {
990 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
991
992 .usb_ctrl = DEVICE_SPECIFIC,
993 .firmware = "af9005.fw",
994 .download_firmware = af9005_download_firmware,
995 .no_reconnect = 1,
996
997 .size_of_priv = sizeof(struct af9005_device_state),
998
999 .num_adapters = 1,
1000 .adapter = {
1001 {
1002 .caps =
1003 DVB_USB_ADAP_HAS_PID_FILTER |
1004 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1005 .pid_filter_count = 32,
1006 .pid_filter = af9005_pid_filter,
1007 /* .pid_filter_ctrl = af9005_pid_filter_control, */
1008 .frontend_attach = af9005_frontend_attach,
1009 /* .tuner_attach = af9005_tuner_attach, */
1010 /* parameter for the MPEG2-data transfer */
1011 .stream = {
1012 .type = USB_BULK,
1013 .count = 10,
1014 .endpoint = 0x04,
1015 .u = {
1016 .bulk = {
1017 .buffersize = 4096, /* actual size seen is 3948 */
1018 }
1019 }
1020 },
1021 }
1022 },
1023 .power_ctrl = af9005_power_ctrl,
1024 .identify_state = af9005_identify_state,
1025
1026 .i2c_algo = &af9005_i2c_algo,
1027
1028 .rc.legacy = {
1029 .rc_interval = 200,
1030 .rc_map_table = NULL,
1031 .rc_map_size = 0,
1032 .rc_query = af9005_rc_query,
1033 },
1034
1035 .generic_bulk_ctrl_endpoint = 2,
1036 .generic_bulk_ctrl_endpoint_response = 1,
1037
1038 .num_device_descs = 3,
1039 .devices = {
1040 {.name = "Afatech DVB-T USB1.1 stick",
1041 .cold_ids = {&af9005_usb_table[0], NULL},
1042 .warm_ids = {NULL},
1043 },
1044 {.name = "TerraTec Cinergy T USB XE",
1045 .cold_ids = {&af9005_usb_table[1], NULL},
1046 .warm_ids = {NULL},
1047 },
1048 {.name = "Ansonic DVB-T USB1.1 stick",
1049 .cold_ids = {&af9005_usb_table[2], NULL},
1050 .warm_ids = {NULL},
1051 },
1052 {NULL},
1053 }
1054};
1055
1056/* usb specific object needed to register this driver with the usb subsystem */
1057static struct usb_driver af9005_usb_driver = {
1058 .name = "dvb_usb_af9005",
1059 .probe = af9005_usb_probe,
1060 .disconnect = dvb_usb_device_exit,
1061 .id_table = af9005_usb_table,
1062};
1063
1064/* module stuff */
1065static int __init af9005_usb_module_init(void)
1066{
1067 int result;
1068 if ((result = usb_register(&af9005_usb_driver))) {
1069 err("usb_register failed. (%d)", result);
1070 return result;
1071 }
1072 rc_decode = symbol_request(af9005_rc_decode);
1073 rc_keys = symbol_request(rc_map_af9005_table);
1074 rc_keys_size = symbol_request(rc_map_af9005_table_size);
1075 if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) {
1076 err("af9005_rc_decode function not found, disabling remote");
1077 af9005_properties.rc.legacy.rc_query = NULL;
1078 } else {
1079 af9005_properties.rc.legacy.rc_map_table = rc_keys;
1080 af9005_properties.rc.legacy.rc_map_size = *rc_keys_size;
1081 }
1082
1083 return 0;
1084}
1085
1086static void __exit af9005_usb_module_exit(void)
1087{
1088 /* release rc decode symbols */
1089 if (rc_decode != NULL)
1090 symbol_put(af9005_rc_decode);
1091 if (rc_keys != NULL)
1092 symbol_put(rc_map_af9005_table);
1093 if (rc_keys_size != NULL)
1094 symbol_put(rc_map_af9005_table_size);
1095 /* deregister this driver from the USB subsystem */
1096 usb_deregister(&af9005_usb_driver);
1097}
1098
1099module_init(af9005_usb_module_init);
1100module_exit(af9005_usb_module_exit);
1101
1102MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");
1103MODULE_DESCRIPTION("Driver for Afatech 9005 DVB-T USB1.1 stick");
1104MODULE_VERSION("1.0");
1105MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/af9005.h b/drivers/media/dvb/dvb-usb/af9005.h
new file mode 100644
index 00000000000..c71c77bd7f4
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/af9005.h
@@ -0,0 +1,3496 @@
1/* Common header-file of the Linux driver for the Afatech 9005
2 * USB1.1 DVB-T receiver.
3 *
4 * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
5 *
6 * Thanks to Afatech who kindly provided information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * see Documentation/dvb/README.dvb-usb for more information
23 */
24#ifndef _DVB_USB_AF9005_H_
25#define _DVB_USB_AF9005_H_
26
27#define DVB_USB_LOG_PREFIX "af9005"
28#include "dvb-usb.h"
29
30extern int dvb_usb_af9005_debug;
31#define deb_info(args...) dprintk(dvb_usb_af9005_debug,0x01,args)
32#define deb_xfer(args...) dprintk(dvb_usb_af9005_debug,0x02,args)
33#define deb_rc(args...) dprintk(dvb_usb_af9005_debug,0x04,args)
34#define deb_reg(args...) dprintk(dvb_usb_af9005_debug,0x08,args)
35#define deb_i2c(args...) dprintk(dvb_usb_af9005_debug,0x10,args)
36#define deb_fw(args...) dprintk(dvb_usb_af9005_debug,0x20,args)
37
38extern int dvb_usb_af9005_led;
39
40/* firmware */
41#define FW_BULKOUT_SIZE 250
42enum {
43 FW_CONFIG,
44 FW_CONFIRM,
45 FW_BOOT
46};
47
48/* af9005 commands */
49#define AF9005_OFDM_REG 0
50#define AF9005_TUNER_REG 1
51
52#define AF9005_REGISTER_RW 0x20
53#define AF9005_REGISTER_RW_ACK 0x21
54
55#define AF9005_CMD_OFDM_REG 0x00
56#define AF9005_CMD_TUNER 0x80
57#define AF9005_CMD_BURST 0x02
58#define AF9005_CMD_AUTOINC 0x04
59#define AF9005_CMD_READ 0x00
60#define AF9005_CMD_WRITE 0x01
61
62/* af9005 registers */
63#define APO_REG_RESET 0xAEFF
64
65#define APO_REG_I2C_RW_CAN_TUNER 0xF000
66#define APO_REG_I2C_RW_SILICON_TUNER 0xF001
67#define APO_REG_GPIO_RW_SILICON_TUNER 0xFFFE /* also for OFSM */
68#define APO_REG_TRIGGER_OFSM 0xFFFF /* also for OFSM */
69
70/***********************************************************************
71 * Apollo Registers from VLSI *
72 ***********************************************************************/
73#define xd_p_reg_aagc_inverted_agc 0xA000
74#define reg_aagc_inverted_agc_pos 0
75#define reg_aagc_inverted_agc_len 1
76#define reg_aagc_inverted_agc_lsb 0
77#define xd_p_reg_aagc_sign_only 0xA000
78#define reg_aagc_sign_only_pos 1
79#define reg_aagc_sign_only_len 1
80#define reg_aagc_sign_only_lsb 0
81#define xd_p_reg_aagc_slow_adc_en 0xA000
82#define reg_aagc_slow_adc_en_pos 2
83#define reg_aagc_slow_adc_en_len 1
84#define reg_aagc_slow_adc_en_lsb 0
85#define xd_p_reg_aagc_slow_adc_scale 0xA000
86#define reg_aagc_slow_adc_scale_pos 3
87#define reg_aagc_slow_adc_scale_len 5
88#define reg_aagc_slow_adc_scale_lsb 0
89#define xd_p_reg_aagc_check_slow_adc_lock 0xA001
90#define reg_aagc_check_slow_adc_lock_pos 0
91#define reg_aagc_check_slow_adc_lock_len 1
92#define reg_aagc_check_slow_adc_lock_lsb 0
93#define xd_p_reg_aagc_init_control 0xA001
94#define reg_aagc_init_control_pos 1
95#define reg_aagc_init_control_len 1
96#define reg_aagc_init_control_lsb 0
97#define xd_p_reg_aagc_total_gain_sel 0xA001
98#define reg_aagc_total_gain_sel_pos 2
99#define reg_aagc_total_gain_sel_len 2
100#define reg_aagc_total_gain_sel_lsb 0
101#define xd_p_reg_aagc_out_inv 0xA001
102#define reg_aagc_out_inv_pos 5
103#define reg_aagc_out_inv_len 1
104#define reg_aagc_out_inv_lsb 0
105#define xd_p_reg_aagc_int_en 0xA001
106#define reg_aagc_int_en_pos 6
107#define reg_aagc_int_en_len 1
108#define reg_aagc_int_en_lsb 0
109#define xd_p_reg_aagc_lock_change_flag 0xA001
110#define reg_aagc_lock_change_flag_pos 7
111#define reg_aagc_lock_change_flag_len 1
112#define reg_aagc_lock_change_flag_lsb 0
113#define xd_p_reg_aagc_rf_loop_bw_scale_acquire 0xA002
114#define reg_aagc_rf_loop_bw_scale_acquire_pos 0
115#define reg_aagc_rf_loop_bw_scale_acquire_len 5
116#define reg_aagc_rf_loop_bw_scale_acquire_lsb 0
117#define xd_p_reg_aagc_rf_loop_bw_scale_track 0xA003
118#define reg_aagc_rf_loop_bw_scale_track_pos 0
119#define reg_aagc_rf_loop_bw_scale_track_len 5
120#define reg_aagc_rf_loop_bw_scale_track_lsb 0
121#define xd_p_reg_aagc_if_loop_bw_scale_acquire 0xA004
122#define reg_aagc_if_loop_bw_scale_acquire_pos 0
123#define reg_aagc_if_loop_bw_scale_acquire_len 5
124#define reg_aagc_if_loop_bw_scale_acquire_lsb 0
125#define xd_p_reg_aagc_if_loop_bw_scale_track 0xA005
126#define reg_aagc_if_loop_bw_scale_track_pos 0
127#define reg_aagc_if_loop_bw_scale_track_len 5
128#define reg_aagc_if_loop_bw_scale_track_lsb 0
129#define xd_p_reg_aagc_max_rf_agc_7_0 0xA006
130#define reg_aagc_max_rf_agc_7_0_pos 0
131#define reg_aagc_max_rf_agc_7_0_len 8
132#define reg_aagc_max_rf_agc_7_0_lsb 0
133#define xd_p_reg_aagc_max_rf_agc_9_8 0xA007
134#define reg_aagc_max_rf_agc_9_8_pos 0
135#define reg_aagc_max_rf_agc_9_8_len 2
136#define reg_aagc_max_rf_agc_9_8_lsb 8
137#define xd_p_reg_aagc_min_rf_agc_7_0 0xA008
138#define reg_aagc_min_rf_agc_7_0_pos 0
139#define reg_aagc_min_rf_agc_7_0_len 8
140#define reg_aagc_min_rf_agc_7_0_lsb 0
141#define xd_p_reg_aagc_min_rf_agc_9_8 0xA009
142#define reg_aagc_min_rf_agc_9_8_pos 0
143#define reg_aagc_min_rf_agc_9_8_len 2
144#define reg_aagc_min_rf_agc_9_8_lsb 8
145#define xd_p_reg_aagc_max_if_agc_7_0 0xA00A
146#define reg_aagc_max_if_agc_7_0_pos 0
147#define reg_aagc_max_if_agc_7_0_len 8
148#define reg_aagc_max_if_agc_7_0_lsb 0
149#define xd_p_reg_aagc_max_if_agc_9_8 0xA00B
150#define reg_aagc_max_if_agc_9_8_pos 0
151#define reg_aagc_max_if_agc_9_8_len 2
152#define reg_aagc_max_if_agc_9_8_lsb 8
153#define xd_p_reg_aagc_min_if_agc_7_0 0xA00C
154#define reg_aagc_min_if_agc_7_0_pos 0
155#define reg_aagc_min_if_agc_7_0_len 8
156#define reg_aagc_min_if_agc_7_0_lsb 0
157#define xd_p_reg_aagc_min_if_agc_9_8 0xA00D
158#define reg_aagc_min_if_agc_9_8_pos 0
159#define reg_aagc_min_if_agc_9_8_len 2
160#define reg_aagc_min_if_agc_9_8_lsb 8
161#define xd_p_reg_aagc_lock_sample_scale 0xA00E
162#define reg_aagc_lock_sample_scale_pos 0
163#define reg_aagc_lock_sample_scale_len 5
164#define reg_aagc_lock_sample_scale_lsb 0
165#define xd_p_reg_aagc_rf_agc_lock_scale_acquire 0xA00F
166#define reg_aagc_rf_agc_lock_scale_acquire_pos 0
167#define reg_aagc_rf_agc_lock_scale_acquire_len 3
168#define reg_aagc_rf_agc_lock_scale_acquire_lsb 0
169#define xd_p_reg_aagc_rf_agc_lock_scale_track 0xA00F
170#define reg_aagc_rf_agc_lock_scale_track_pos 3
171#define reg_aagc_rf_agc_lock_scale_track_len 3
172#define reg_aagc_rf_agc_lock_scale_track_lsb 0
173#define xd_p_reg_aagc_if_agc_lock_scale_acquire 0xA010
174#define reg_aagc_if_agc_lock_scale_acquire_pos 0
175#define reg_aagc_if_agc_lock_scale_acquire_len 3
176#define reg_aagc_if_agc_lock_scale_acquire_lsb 0
177#define xd_p_reg_aagc_if_agc_lock_scale_track 0xA010
178#define reg_aagc_if_agc_lock_scale_track_pos 3
179#define reg_aagc_if_agc_lock_scale_track_len 3
180#define reg_aagc_if_agc_lock_scale_track_lsb 0
181#define xd_p_reg_aagc_rf_top_numerator_7_0 0xA011
182#define reg_aagc_rf_top_numerator_7_0_pos 0
183#define reg_aagc_rf_top_numerator_7_0_len 8
184#define reg_aagc_rf_top_numerator_7_0_lsb 0
185#define xd_p_reg_aagc_rf_top_numerator_9_8 0xA012
186#define reg_aagc_rf_top_numerator_9_8_pos 0
187#define reg_aagc_rf_top_numerator_9_8_len 2
188#define reg_aagc_rf_top_numerator_9_8_lsb 8
189#define xd_p_reg_aagc_if_top_numerator_7_0 0xA013
190#define reg_aagc_if_top_numerator_7_0_pos 0
191#define reg_aagc_if_top_numerator_7_0_len 8
192#define reg_aagc_if_top_numerator_7_0_lsb 0
193#define xd_p_reg_aagc_if_top_numerator_9_8 0xA014
194#define reg_aagc_if_top_numerator_9_8_pos 0
195#define reg_aagc_if_top_numerator_9_8_len 2
196#define reg_aagc_if_top_numerator_9_8_lsb 8
197#define xd_p_reg_aagc_adc_out_desired_7_0 0xA015
198#define reg_aagc_adc_out_desired_7_0_pos 0
199#define reg_aagc_adc_out_desired_7_0_len 8
200#define reg_aagc_adc_out_desired_7_0_lsb 0
201#define xd_p_reg_aagc_adc_out_desired_8 0xA016
202#define reg_aagc_adc_out_desired_8_pos 0
203#define reg_aagc_adc_out_desired_8_len 1
204#define reg_aagc_adc_out_desired_8_lsb 0
205#define xd_p_reg_aagc_fixed_gain 0xA016
206#define reg_aagc_fixed_gain_pos 3
207#define reg_aagc_fixed_gain_len 1
208#define reg_aagc_fixed_gain_lsb 0
209#define xd_p_reg_aagc_lock_count_th 0xA016
210#define reg_aagc_lock_count_th_pos 4
211#define reg_aagc_lock_count_th_len 4
212#define reg_aagc_lock_count_th_lsb 0
213#define xd_p_reg_aagc_fixed_rf_agc_control_7_0 0xA017
214#define reg_aagc_fixed_rf_agc_control_7_0_pos 0
215#define reg_aagc_fixed_rf_agc_control_7_0_len 8
216#define reg_aagc_fixed_rf_agc_control_7_0_lsb 0
217#define xd_p_reg_aagc_fixed_rf_agc_control_15_8 0xA018
218#define reg_aagc_fixed_rf_agc_control_15_8_pos 0
219#define reg_aagc_fixed_rf_agc_control_15_8_len 8
220#define reg_aagc_fixed_rf_agc_control_15_8_lsb 8
221#define xd_p_reg_aagc_fixed_rf_agc_control_23_16 0xA019
222#define reg_aagc_fixed_rf_agc_control_23_16_pos 0
223#define reg_aagc_fixed_rf_agc_control_23_16_len 8
224#define reg_aagc_fixed_rf_agc_control_23_16_lsb 16
225#define xd_p_reg_aagc_fixed_rf_agc_control_30_24 0xA01A
226#define reg_aagc_fixed_rf_agc_control_30_24_pos 0
227#define reg_aagc_fixed_rf_agc_control_30_24_len 7
228#define reg_aagc_fixed_rf_agc_control_30_24_lsb 24
229#define xd_p_reg_aagc_fixed_if_agc_control_7_0 0xA01B
230#define reg_aagc_fixed_if_agc_control_7_0_pos 0
231#define reg_aagc_fixed_if_agc_control_7_0_len 8
232#define reg_aagc_fixed_if_agc_control_7_0_lsb 0
233#define xd_p_reg_aagc_fixed_if_agc_control_15_8 0xA01C
234#define reg_aagc_fixed_if_agc_control_15_8_pos 0
235#define reg_aagc_fixed_if_agc_control_15_8_len 8
236#define reg_aagc_fixed_if_agc_control_15_8_lsb 8
237#define xd_p_reg_aagc_fixed_if_agc_control_23_16 0xA01D
238#define reg_aagc_fixed_if_agc_control_23_16_pos 0
239#define reg_aagc_fixed_if_agc_control_23_16_len 8
240#define reg_aagc_fixed_if_agc_control_23_16_lsb 16
241#define xd_p_reg_aagc_fixed_if_agc_control_30_24 0xA01E
242#define reg_aagc_fixed_if_agc_control_30_24_pos 0
243#define reg_aagc_fixed_if_agc_control_30_24_len 7
244#define reg_aagc_fixed_if_agc_control_30_24_lsb 24
245#define xd_p_reg_aagc_rf_agc_unlock_numerator 0xA01F
246#define reg_aagc_rf_agc_unlock_numerator_pos 0
247#define reg_aagc_rf_agc_unlock_numerator_len 6
248#define reg_aagc_rf_agc_unlock_numerator_lsb 0
249#define xd_p_reg_aagc_if_agc_unlock_numerator 0xA020
250#define reg_aagc_if_agc_unlock_numerator_pos 0
251#define reg_aagc_if_agc_unlock_numerator_len 6
252#define reg_aagc_if_agc_unlock_numerator_lsb 0
253#define xd_p_reg_unplug_th 0xA021
254#define reg_unplug_th_pos 0
255#define reg_unplug_th_len 8
256#define reg_aagc_rf_x0_lsb 0
257#define xd_p_reg_weak_signal_rfagc_thr 0xA022
258#define reg_weak_signal_rfagc_thr_pos 0
259#define reg_weak_signal_rfagc_thr_len 8
260#define reg_weak_signal_rfagc_thr_lsb 0
261#define xd_p_reg_unplug_rf_gain_th 0xA023
262#define reg_unplug_rf_gain_th_pos 0
263#define reg_unplug_rf_gain_th_len 8
264#define reg_unplug_rf_gain_th_lsb 0
265#define xd_p_reg_unplug_dtop_rf_gain_th 0xA024
266#define reg_unplug_dtop_rf_gain_th_pos 0
267#define reg_unplug_dtop_rf_gain_th_len 8
268#define reg_unplug_dtop_rf_gain_th_lsb 0
269#define xd_p_reg_unplug_dtop_if_gain_th 0xA025
270#define reg_unplug_dtop_if_gain_th_pos 0
271#define reg_unplug_dtop_if_gain_th_len 8
272#define reg_unplug_dtop_if_gain_th_lsb 0
273#define xd_p_reg_top_recover_at_unplug_en 0xA026
274#define reg_top_recover_at_unplug_en_pos 0
275#define reg_top_recover_at_unplug_en_len 1
276#define reg_top_recover_at_unplug_en_lsb 0
277#define xd_p_reg_aagc_rf_x6 0xA027
278#define reg_aagc_rf_x6_pos 0
279#define reg_aagc_rf_x6_len 8
280#define reg_aagc_rf_x6_lsb 0
281#define xd_p_reg_aagc_rf_x7 0xA028
282#define reg_aagc_rf_x7_pos 0
283#define reg_aagc_rf_x7_len 8
284#define reg_aagc_rf_x7_lsb 0
285#define xd_p_reg_aagc_rf_x8 0xA029
286#define reg_aagc_rf_x8_pos 0
287#define reg_aagc_rf_x8_len 8
288#define reg_aagc_rf_x8_lsb 0
289#define xd_p_reg_aagc_rf_x9 0xA02A
290#define reg_aagc_rf_x9_pos 0
291#define reg_aagc_rf_x9_len 8
292#define reg_aagc_rf_x9_lsb 0
293#define xd_p_reg_aagc_rf_x10 0xA02B
294#define reg_aagc_rf_x10_pos 0
295#define reg_aagc_rf_x10_len 8
296#define reg_aagc_rf_x10_lsb 0
297#define xd_p_reg_aagc_rf_x11 0xA02C
298#define reg_aagc_rf_x11_pos 0
299#define reg_aagc_rf_x11_len 8
300#define reg_aagc_rf_x11_lsb 0
301#define xd_p_reg_aagc_rf_x12 0xA02D
302#define reg_aagc_rf_x12_pos 0
303#define reg_aagc_rf_x12_len 8
304#define reg_aagc_rf_x12_lsb 0
305#define xd_p_reg_aagc_rf_x13 0xA02E
306#define reg_aagc_rf_x13_pos 0
307#define reg_aagc_rf_x13_len 8
308#define reg_aagc_rf_x13_lsb 0
309#define xd_p_reg_aagc_if_x0 0xA02F
310#define reg_aagc_if_x0_pos 0
311#define reg_aagc_if_x0_len 8
312#define reg_aagc_if_x0_lsb 0
313#define xd_p_reg_aagc_if_x1 0xA030
314#define reg_aagc_if_x1_pos 0
315#define reg_aagc_if_x1_len 8
316#define reg_aagc_if_x1_lsb 0
317#define xd_p_reg_aagc_if_x2 0xA031
318#define reg_aagc_if_x2_pos 0
319#define reg_aagc_if_x2_len 8
320#define reg_aagc_if_x2_lsb 0
321#define xd_p_reg_aagc_if_x3 0xA032
322#define reg_aagc_if_x3_pos 0
323#define reg_aagc_if_x3_len 8
324#define reg_aagc_if_x3_lsb 0
325#define xd_p_reg_aagc_if_x4 0xA033
326#define reg_aagc_if_x4_pos 0
327#define reg_aagc_if_x4_len 8
328#define reg_aagc_if_x4_lsb 0
329#define xd_p_reg_aagc_if_x5 0xA034
330#define reg_aagc_if_x5_pos 0
331#define reg_aagc_if_x5_len 8
332#define reg_aagc_if_x5_lsb 0
333#define xd_p_reg_aagc_if_x6 0xA035
334#define reg_aagc_if_x6_pos 0
335#define reg_aagc_if_x6_len 8
336#define reg_aagc_if_x6_lsb 0
337#define xd_p_reg_aagc_if_x7 0xA036
338#define reg_aagc_if_x7_pos 0
339#define reg_aagc_if_x7_len 8
340#define reg_aagc_if_x7_lsb 0
341#define xd_p_reg_aagc_if_x8 0xA037
342#define reg_aagc_if_x8_pos 0
343#define reg_aagc_if_x8_len 8
344#define reg_aagc_if_x8_lsb 0
345#define xd_p_reg_aagc_if_x9 0xA038
346#define reg_aagc_if_x9_pos 0
347#define reg_aagc_if_x9_len 8
348#define reg_aagc_if_x9_lsb 0
349#define xd_p_reg_aagc_if_x10 0xA039
350#define reg_aagc_if_x10_pos 0
351#define reg_aagc_if_x10_len 8
352#define reg_aagc_if_x10_lsb 0
353#define xd_p_reg_aagc_if_x11 0xA03A
354#define reg_aagc_if_x11_pos 0
355#define reg_aagc_if_x11_len 8
356#define reg_aagc_if_x11_lsb 0
357#define xd_p_reg_aagc_if_x12 0xA03B
358#define reg_aagc_if_x12_pos 0
359#define reg_aagc_if_x12_len 8
360#define reg_aagc_if_x12_lsb 0
361#define xd_p_reg_aagc_if_x13 0xA03C
362#define reg_aagc_if_x13_pos 0
363#define reg_aagc_if_x13_len 8
364#define reg_aagc_if_x13_lsb 0
365#define xd_p_reg_aagc_min_rf_ctl_8bit_for_dca 0xA03D
366#define reg_aagc_min_rf_ctl_8bit_for_dca_pos 0
367#define reg_aagc_min_rf_ctl_8bit_for_dca_len 8
368#define reg_aagc_min_rf_ctl_8bit_for_dca_lsb 0
369#define xd_p_reg_aagc_min_if_ctl_8bit_for_dca 0xA03E
370#define reg_aagc_min_if_ctl_8bit_for_dca_pos 0
371#define reg_aagc_min_if_ctl_8bit_for_dca_len 8
372#define reg_aagc_min_if_ctl_8bit_for_dca_lsb 0
373#define xd_r_reg_aagc_total_gain_7_0 0xA070
374#define reg_aagc_total_gain_7_0_pos 0
375#define reg_aagc_total_gain_7_0_len 8
376#define reg_aagc_total_gain_7_0_lsb 0
377#define xd_r_reg_aagc_total_gain_15_8 0xA071
378#define reg_aagc_total_gain_15_8_pos 0
379#define reg_aagc_total_gain_15_8_len 8
380#define reg_aagc_total_gain_15_8_lsb 8
381#define xd_p_reg_aagc_in_sat_cnt_7_0 0xA074
382#define reg_aagc_in_sat_cnt_7_0_pos 0
383#define reg_aagc_in_sat_cnt_7_0_len 8
384#define reg_aagc_in_sat_cnt_7_0_lsb 0
385#define xd_p_reg_aagc_in_sat_cnt_15_8 0xA075
386#define reg_aagc_in_sat_cnt_15_8_pos 0
387#define reg_aagc_in_sat_cnt_15_8_len 8
388#define reg_aagc_in_sat_cnt_15_8_lsb 8
389#define xd_p_reg_aagc_in_sat_cnt_23_16 0xA076
390#define reg_aagc_in_sat_cnt_23_16_pos 0
391#define reg_aagc_in_sat_cnt_23_16_len 8
392#define reg_aagc_in_sat_cnt_23_16_lsb 16
393#define xd_p_reg_aagc_in_sat_cnt_31_24 0xA077
394#define reg_aagc_in_sat_cnt_31_24_pos 0
395#define reg_aagc_in_sat_cnt_31_24_len 8
396#define reg_aagc_in_sat_cnt_31_24_lsb 24
397#define xd_r_reg_aagc_digital_rf_volt_7_0 0xA078
398#define reg_aagc_digital_rf_volt_7_0_pos 0
399#define reg_aagc_digital_rf_volt_7_0_len 8
400#define reg_aagc_digital_rf_volt_7_0_lsb 0
401#define xd_r_reg_aagc_digital_rf_volt_9_8 0xA079
402#define reg_aagc_digital_rf_volt_9_8_pos 0
403#define reg_aagc_digital_rf_volt_9_8_len 2
404#define reg_aagc_digital_rf_volt_9_8_lsb 8
405#define xd_r_reg_aagc_digital_if_volt_7_0 0xA07A
406#define reg_aagc_digital_if_volt_7_0_pos 0
407#define reg_aagc_digital_if_volt_7_0_len 8
408#define reg_aagc_digital_if_volt_7_0_lsb 0
409#define xd_r_reg_aagc_digital_if_volt_9_8 0xA07B
410#define reg_aagc_digital_if_volt_9_8_pos 0
411#define reg_aagc_digital_if_volt_9_8_len 2
412#define reg_aagc_digital_if_volt_9_8_lsb 8
413#define xd_r_reg_aagc_rf_gain 0xA07C
414#define reg_aagc_rf_gain_pos 0
415#define reg_aagc_rf_gain_len 8
416#define reg_aagc_rf_gain_lsb 0
417#define xd_r_reg_aagc_if_gain 0xA07D
418#define reg_aagc_if_gain_pos 0
419#define reg_aagc_if_gain_len 8
420#define reg_aagc_if_gain_lsb 0
421#define xd_p_tinr_imp_indicator 0xA080
422#define tinr_imp_indicator_pos 0
423#define tinr_imp_indicator_len 2
424#define tinr_imp_indicator_lsb 0
425#define xd_p_reg_tinr_fifo_size 0xA080
426#define reg_tinr_fifo_size_pos 2
427#define reg_tinr_fifo_size_len 5
428#define reg_tinr_fifo_size_lsb 0
429#define xd_p_reg_tinr_saturation_cnt_th 0xA081
430#define reg_tinr_saturation_cnt_th_pos 0
431#define reg_tinr_saturation_cnt_th_len 4
432#define reg_tinr_saturation_cnt_th_lsb 0
433#define xd_p_reg_tinr_saturation_th_3_0 0xA081
434#define reg_tinr_saturation_th_3_0_pos 4
435#define reg_tinr_saturation_th_3_0_len 4
436#define reg_tinr_saturation_th_3_0_lsb 0
437#define xd_p_reg_tinr_saturation_th_8_4 0xA082
438#define reg_tinr_saturation_th_8_4_pos 0
439#define reg_tinr_saturation_th_8_4_len 5
440#define reg_tinr_saturation_th_8_4_lsb 4
441#define xd_p_reg_tinr_imp_duration_th_2k_7_0 0xA083
442#define reg_tinr_imp_duration_th_2k_7_0_pos 0
443#define reg_tinr_imp_duration_th_2k_7_0_len 8
444#define reg_tinr_imp_duration_th_2k_7_0_lsb 0
445#define xd_p_reg_tinr_imp_duration_th_2k_8 0xA084
446#define reg_tinr_imp_duration_th_2k_8_pos 0
447#define reg_tinr_imp_duration_th_2k_8_len 1
448#define reg_tinr_imp_duration_th_2k_8_lsb 0
449#define xd_p_reg_tinr_imp_duration_th_8k_7_0 0xA085
450#define reg_tinr_imp_duration_th_8k_7_0_pos 0
451#define reg_tinr_imp_duration_th_8k_7_0_len 8
452#define reg_tinr_imp_duration_th_8k_7_0_lsb 0
453#define xd_p_reg_tinr_imp_duration_th_8k_10_8 0xA086
454#define reg_tinr_imp_duration_th_8k_10_8_pos 0
455#define reg_tinr_imp_duration_th_8k_10_8_len 3
456#define reg_tinr_imp_duration_th_8k_10_8_lsb 8
457#define xd_p_reg_tinr_freq_ratio_6m_7_0 0xA087
458#define reg_tinr_freq_ratio_6m_7_0_pos 0
459#define reg_tinr_freq_ratio_6m_7_0_len 8
460#define reg_tinr_freq_ratio_6m_7_0_lsb 0
461#define xd_p_reg_tinr_freq_ratio_6m_12_8 0xA088
462#define reg_tinr_freq_ratio_6m_12_8_pos 0
463#define reg_tinr_freq_ratio_6m_12_8_len 5
464#define reg_tinr_freq_ratio_6m_12_8_lsb 8
465#define xd_p_reg_tinr_freq_ratio_7m_7_0 0xA089
466#define reg_tinr_freq_ratio_7m_7_0_pos 0
467#define reg_tinr_freq_ratio_7m_7_0_len 8
468#define reg_tinr_freq_ratio_7m_7_0_lsb 0
469#define xd_p_reg_tinr_freq_ratio_7m_12_8 0xA08A
470#define reg_tinr_freq_ratio_7m_12_8_pos 0
471#define reg_tinr_freq_ratio_7m_12_8_len 5
472#define reg_tinr_freq_ratio_7m_12_8_lsb 8
473#define xd_p_reg_tinr_freq_ratio_8m_7_0 0xA08B
474#define reg_tinr_freq_ratio_8m_7_0_pos 0
475#define reg_tinr_freq_ratio_8m_7_0_len 8
476#define reg_tinr_freq_ratio_8m_7_0_lsb 0
477#define xd_p_reg_tinr_freq_ratio_8m_12_8 0xA08C
478#define reg_tinr_freq_ratio_8m_12_8_pos 0
479#define reg_tinr_freq_ratio_8m_12_8_len 5
480#define reg_tinr_freq_ratio_8m_12_8_lsb 8
481#define xd_p_reg_tinr_imp_duration_th_low_2k 0xA08D
482#define reg_tinr_imp_duration_th_low_2k_pos 0
483#define reg_tinr_imp_duration_th_low_2k_len 8
484#define reg_tinr_imp_duration_th_low_2k_lsb 0
485#define xd_p_reg_tinr_imp_duration_th_low_8k 0xA08E
486#define reg_tinr_imp_duration_th_low_8k_pos 0
487#define reg_tinr_imp_duration_th_low_8k_len 8
488#define reg_tinr_imp_duration_th_low_8k_lsb 0
489#define xd_r_reg_tinr_counter_7_0 0xA090
490#define reg_tinr_counter_7_0_pos 0
491#define reg_tinr_counter_7_0_len 8
492#define reg_tinr_counter_7_0_lsb 0
493#define xd_r_reg_tinr_counter_15_8 0xA091
494#define reg_tinr_counter_15_8_pos 0
495#define reg_tinr_counter_15_8_len 8
496#define reg_tinr_counter_15_8_lsb 8
497#define xd_p_reg_tinr_adative_tinr_en 0xA093
498#define reg_tinr_adative_tinr_en_pos 0
499#define reg_tinr_adative_tinr_en_len 1
500#define reg_tinr_adative_tinr_en_lsb 0
501#define xd_p_reg_tinr_peak_fifo_size 0xA093
502#define reg_tinr_peak_fifo_size_pos 1
503#define reg_tinr_peak_fifo_size_len 5
504#define reg_tinr_peak_fifo_size_lsb 0
505#define xd_p_reg_tinr_counter_rst 0xA093
506#define reg_tinr_counter_rst_pos 6
507#define reg_tinr_counter_rst_len 1
508#define reg_tinr_counter_rst_lsb 0
509#define xd_p_reg_tinr_search_period_7_0 0xA094
510#define reg_tinr_search_period_7_0_pos 0
511#define reg_tinr_search_period_7_0_len 8
512#define reg_tinr_search_period_7_0_lsb 0
513#define xd_p_reg_tinr_search_period_15_8 0xA095
514#define reg_tinr_search_period_15_8_pos 0
515#define reg_tinr_search_period_15_8_len 8
516#define reg_tinr_search_period_15_8_lsb 8
517#define xd_p_reg_ccifs_fcw_7_0 0xA0A0
518#define reg_ccifs_fcw_7_0_pos 0
519#define reg_ccifs_fcw_7_0_len 8
520#define reg_ccifs_fcw_7_0_lsb 0
521#define xd_p_reg_ccifs_fcw_12_8 0xA0A1
522#define reg_ccifs_fcw_12_8_pos 0
523#define reg_ccifs_fcw_12_8_len 5
524#define reg_ccifs_fcw_12_8_lsb 8
525#define xd_p_reg_ccifs_spec_inv 0xA0A1
526#define reg_ccifs_spec_inv_pos 5
527#define reg_ccifs_spec_inv_len 1
528#define reg_ccifs_spec_inv_lsb 0
529#define xd_p_reg_gp_trigger 0xA0A2
530#define reg_gp_trigger_pos 0
531#define reg_gp_trigger_len 1
532#define reg_gp_trigger_lsb 0
533#define xd_p_reg_trigger_sel 0xA0A2
534#define reg_trigger_sel_pos 1
535#define reg_trigger_sel_len 2
536#define reg_trigger_sel_lsb 0
537#define xd_p_reg_debug_ofdm 0xA0A2
538#define reg_debug_ofdm_pos 3
539#define reg_debug_ofdm_len 2
540#define reg_debug_ofdm_lsb 0
541#define xd_p_reg_trigger_module_sel 0xA0A3
542#define reg_trigger_module_sel_pos 0
543#define reg_trigger_module_sel_len 6
544#define reg_trigger_module_sel_lsb 0
545#define xd_p_reg_trigger_set_sel 0xA0A4
546#define reg_trigger_set_sel_pos 0
547#define reg_trigger_set_sel_len 6
548#define reg_trigger_set_sel_lsb 0
549#define xd_p_reg_fw_int_mask_n 0xA0A4
550#define reg_fw_int_mask_n_pos 6
551#define reg_fw_int_mask_n_len 1
552#define reg_fw_int_mask_n_lsb 0
553#define xd_p_reg_debug_group 0xA0A5
554#define reg_debug_group_pos 0
555#define reg_debug_group_len 4
556#define reg_debug_group_lsb 0
557#define xd_p_reg_odbg_clk_sel 0xA0A5
558#define reg_odbg_clk_sel_pos 4
559#define reg_odbg_clk_sel_len 2
560#define reg_odbg_clk_sel_lsb 0
561#define xd_p_reg_ccif_sc 0xA0C0
562#define reg_ccif_sc_pos 0
563#define reg_ccif_sc_len 4
564#define reg_ccif_sc_lsb 0
565#define xd_r_reg_ccif_saturate 0xA0C1
566#define reg_ccif_saturate_pos 0
567#define reg_ccif_saturate_len 2
568#define reg_ccif_saturate_lsb 0
569#define xd_r_reg_antif_saturate 0xA0C1
570#define reg_antif_saturate_pos 2
571#define reg_antif_saturate_len 4
572#define reg_antif_saturate_lsb 0
573#define xd_r_reg_acif_saturate 0xA0C2
574#define reg_acif_saturate_pos 0
575#define reg_acif_saturate_len 8
576#define reg_acif_saturate_lsb 0
577#define xd_p_reg_tmr_timer0_threshold_7_0 0xA0C8
578#define reg_tmr_timer0_threshold_7_0_pos 0
579#define reg_tmr_timer0_threshold_7_0_len 8
580#define reg_tmr_timer0_threshold_7_0_lsb 0
581#define xd_p_reg_tmr_timer0_threshold_15_8 0xA0C9
582#define reg_tmr_timer0_threshold_15_8_pos 0
583#define reg_tmr_timer0_threshold_15_8_len 8
584#define reg_tmr_timer0_threshold_15_8_lsb 8
585#define xd_p_reg_tmr_timer0_enable 0xA0CA
586#define reg_tmr_timer0_enable_pos 0
587#define reg_tmr_timer0_enable_len 1
588#define reg_tmr_timer0_enable_lsb 0
589#define xd_p_reg_tmr_timer0_clk_sel 0xA0CA
590#define reg_tmr_timer0_clk_sel_pos 1
591#define reg_tmr_timer0_clk_sel_len 1
592#define reg_tmr_timer0_clk_sel_lsb 0
593#define xd_p_reg_tmr_timer0_int 0xA0CA
594#define reg_tmr_timer0_int_pos 2
595#define reg_tmr_timer0_int_len 1
596#define reg_tmr_timer0_int_lsb 0
597#define xd_p_reg_tmr_timer0_rst 0xA0CA
598#define reg_tmr_timer0_rst_pos 3
599#define reg_tmr_timer0_rst_len 1
600#define reg_tmr_timer0_rst_lsb 0
601#define xd_r_reg_tmr_timer0_count_7_0 0xA0CB
602#define reg_tmr_timer0_count_7_0_pos 0
603#define reg_tmr_timer0_count_7_0_len 8
604#define reg_tmr_timer0_count_7_0_lsb 0
605#define xd_r_reg_tmr_timer0_count_15_8 0xA0CC
606#define reg_tmr_timer0_count_15_8_pos 0
607#define reg_tmr_timer0_count_15_8_len 8
608#define reg_tmr_timer0_count_15_8_lsb 8
609#define xd_p_reg_suspend 0xA0CD
610#define reg_suspend_pos 0
611#define reg_suspend_len 1
612#define reg_suspend_lsb 0
613#define xd_p_reg_suspend_rdy 0xA0CD
614#define reg_suspend_rdy_pos 1
615#define reg_suspend_rdy_len 1
616#define reg_suspend_rdy_lsb 0
617#define xd_p_reg_resume 0xA0CD
618#define reg_resume_pos 2
619#define reg_resume_len 1
620#define reg_resume_lsb 0
621#define xd_p_reg_resume_rdy 0xA0CD
622#define reg_resume_rdy_pos 3
623#define reg_resume_rdy_len 1
624#define reg_resume_rdy_lsb 0
625#define xd_p_reg_fmf 0xA0CE
626#define reg_fmf_pos 0
627#define reg_fmf_len 8
628#define reg_fmf_lsb 0
629#define xd_p_ccid_accumulate_num_2k_7_0 0xA100
630#define ccid_accumulate_num_2k_7_0_pos 0
631#define ccid_accumulate_num_2k_7_0_len 8
632#define ccid_accumulate_num_2k_7_0_lsb 0
633#define xd_p_ccid_accumulate_num_2k_12_8 0xA101
634#define ccid_accumulate_num_2k_12_8_pos 0
635#define ccid_accumulate_num_2k_12_8_len 5
636#define ccid_accumulate_num_2k_12_8_lsb 8
637#define xd_p_ccid_accumulate_num_8k_7_0 0xA102
638#define ccid_accumulate_num_8k_7_0_pos 0
639#define ccid_accumulate_num_8k_7_0_len 8
640#define ccid_accumulate_num_8k_7_0_lsb 0
641#define xd_p_ccid_accumulate_num_8k_14_8 0xA103
642#define ccid_accumulate_num_8k_14_8_pos 0
643#define ccid_accumulate_num_8k_14_8_len 7
644#define ccid_accumulate_num_8k_14_8_lsb 8
645#define xd_p_ccid_desired_level_0 0xA103
646#define ccid_desired_level_0_pos 7
647#define ccid_desired_level_0_len 1
648#define ccid_desired_level_0_lsb 0
649#define xd_p_ccid_desired_level_8_1 0xA104
650#define ccid_desired_level_8_1_pos 0
651#define ccid_desired_level_8_1_len 8
652#define ccid_desired_level_8_1_lsb 1
653#define xd_p_ccid_apply_delay 0xA105
654#define ccid_apply_delay_pos 0
655#define ccid_apply_delay_len 7
656#define ccid_apply_delay_lsb 0
657#define xd_p_ccid_CCID_Threshold1 0xA106
658#define ccid_CCID_Threshold1_pos 0
659#define ccid_CCID_Threshold1_len 8
660#define ccid_CCID_Threshold1_lsb 0
661#define xd_p_ccid_CCID_Threshold2 0xA107
662#define ccid_CCID_Threshold2_pos 0
663#define ccid_CCID_Threshold2_len 8
664#define ccid_CCID_Threshold2_lsb 0
665#define xd_p_reg_ccid_gain_scale 0xA108
666#define reg_ccid_gain_scale_pos 0
667#define reg_ccid_gain_scale_len 4
668#define reg_ccid_gain_scale_lsb 0
669#define xd_p_reg_ccid2_passband_gain_set 0xA108
670#define reg_ccid2_passband_gain_set_pos 4
671#define reg_ccid2_passband_gain_set_len 4
672#define reg_ccid2_passband_gain_set_lsb 0
673#define xd_r_ccid_multiplier_7_0 0xA109
674#define ccid_multiplier_7_0_pos 0
675#define ccid_multiplier_7_0_len 8
676#define ccid_multiplier_7_0_lsb 0
677#define xd_r_ccid_multiplier_15_8 0xA10A
678#define ccid_multiplier_15_8_pos 0
679#define ccid_multiplier_15_8_len 8
680#define ccid_multiplier_15_8_lsb 8
681#define xd_r_ccid_right_shift_bits 0xA10B
682#define ccid_right_shift_bits_pos 0
683#define ccid_right_shift_bits_len 4
684#define ccid_right_shift_bits_lsb 0
685#define xd_r_reg_ccid_sx_7_0 0xA10C
686#define reg_ccid_sx_7_0_pos 0
687#define reg_ccid_sx_7_0_len 8
688#define reg_ccid_sx_7_0_lsb 0
689#define xd_r_reg_ccid_sx_15_8 0xA10D
690#define reg_ccid_sx_15_8_pos 0
691#define reg_ccid_sx_15_8_len 8
692#define reg_ccid_sx_15_8_lsb 8
693#define xd_r_reg_ccid_sx_21_16 0xA10E
694#define reg_ccid_sx_21_16_pos 0
695#define reg_ccid_sx_21_16_len 6
696#define reg_ccid_sx_21_16_lsb 16
697#define xd_r_reg_ccid_sy_7_0 0xA110
698#define reg_ccid_sy_7_0_pos 0
699#define reg_ccid_sy_7_0_len 8
700#define reg_ccid_sy_7_0_lsb 0
701#define xd_r_reg_ccid_sy_15_8 0xA111
702#define reg_ccid_sy_15_8_pos 0
703#define reg_ccid_sy_15_8_len 8
704#define reg_ccid_sy_15_8_lsb 8
705#define xd_r_reg_ccid_sy_23_16 0xA112
706#define reg_ccid_sy_23_16_pos 0
707#define reg_ccid_sy_23_16_len 8
708#define reg_ccid_sy_23_16_lsb 16
709#define xd_r_reg_ccid2_sz_7_0 0xA114
710#define reg_ccid2_sz_7_0_pos 0
711#define reg_ccid2_sz_7_0_len 8
712#define reg_ccid2_sz_7_0_lsb 0
713#define xd_r_reg_ccid2_sz_15_8 0xA115
714#define reg_ccid2_sz_15_8_pos 0
715#define reg_ccid2_sz_15_8_len 8
716#define reg_ccid2_sz_15_8_lsb 8
717#define xd_r_reg_ccid2_sz_23_16 0xA116
718#define reg_ccid2_sz_23_16_pos 0
719#define reg_ccid2_sz_23_16_len 8
720#define reg_ccid2_sz_23_16_lsb 16
721#define xd_r_reg_ccid2_sz_25_24 0xA117
722#define reg_ccid2_sz_25_24_pos 0
723#define reg_ccid2_sz_25_24_len 2
724#define reg_ccid2_sz_25_24_lsb 24
725#define xd_r_reg_ccid2_sy_7_0 0xA118
726#define reg_ccid2_sy_7_0_pos 0
727#define reg_ccid2_sy_7_0_len 8
728#define reg_ccid2_sy_7_0_lsb 0
729#define xd_r_reg_ccid2_sy_15_8 0xA119
730#define reg_ccid2_sy_15_8_pos 0
731#define reg_ccid2_sy_15_8_len 8
732#define reg_ccid2_sy_15_8_lsb 8
733#define xd_r_reg_ccid2_sy_23_16 0xA11A
734#define reg_ccid2_sy_23_16_pos 0
735#define reg_ccid2_sy_23_16_len 8
736#define reg_ccid2_sy_23_16_lsb 16
737#define xd_r_reg_ccid2_sy_25_24 0xA11B
738#define reg_ccid2_sy_25_24_pos 0
739#define reg_ccid2_sy_25_24_len 2
740#define reg_ccid2_sy_25_24_lsb 24
741#define xd_p_dagc1_accumulate_num_2k_7_0 0xA120
742#define dagc1_accumulate_num_2k_7_0_pos 0
743#define dagc1_accumulate_num_2k_7_0_len 8
744#define dagc1_accumulate_num_2k_7_0_lsb 0
745#define xd_p_dagc1_accumulate_num_2k_12_8 0xA121
746#define dagc1_accumulate_num_2k_12_8_pos 0
747#define dagc1_accumulate_num_2k_12_8_len 5
748#define dagc1_accumulate_num_2k_12_8_lsb 8
749#define xd_p_dagc1_accumulate_num_8k_7_0 0xA122
750#define dagc1_accumulate_num_8k_7_0_pos 0
751#define dagc1_accumulate_num_8k_7_0_len 8
752#define dagc1_accumulate_num_8k_7_0_lsb 0
753#define xd_p_dagc1_accumulate_num_8k_14_8 0xA123
754#define dagc1_accumulate_num_8k_14_8_pos 0
755#define dagc1_accumulate_num_8k_14_8_len 7
756#define dagc1_accumulate_num_8k_14_8_lsb 8
757#define xd_p_dagc1_desired_level_0 0xA123
758#define dagc1_desired_level_0_pos 7
759#define dagc1_desired_level_0_len 1
760#define dagc1_desired_level_0_lsb 0
761#define xd_p_dagc1_desired_level_8_1 0xA124
762#define dagc1_desired_level_8_1_pos 0
763#define dagc1_desired_level_8_1_len 8
764#define dagc1_desired_level_8_1_lsb 1
765#define xd_p_dagc1_apply_delay 0xA125
766#define dagc1_apply_delay_pos 0
767#define dagc1_apply_delay_len 7
768#define dagc1_apply_delay_lsb 0
769#define xd_p_dagc1_bypass_scale_ctl 0xA126
770#define dagc1_bypass_scale_ctl_pos 0
771#define dagc1_bypass_scale_ctl_len 2
772#define dagc1_bypass_scale_ctl_lsb 0
773#define xd_p_reg_dagc1_in_sat_cnt_7_0 0xA127
774#define reg_dagc1_in_sat_cnt_7_0_pos 0
775#define reg_dagc1_in_sat_cnt_7_0_len 8
776#define reg_dagc1_in_sat_cnt_7_0_lsb 0
777#define xd_p_reg_dagc1_in_sat_cnt_15_8 0xA128
778#define reg_dagc1_in_sat_cnt_15_8_pos 0
779#define reg_dagc1_in_sat_cnt_15_8_len 8
780#define reg_dagc1_in_sat_cnt_15_8_lsb 8
781#define xd_p_reg_dagc1_in_sat_cnt_23_16 0xA129
782#define reg_dagc1_in_sat_cnt_23_16_pos 0
783#define reg_dagc1_in_sat_cnt_23_16_len 8
784#define reg_dagc1_in_sat_cnt_23_16_lsb 16
785#define xd_p_reg_dagc1_in_sat_cnt_31_24 0xA12A
786#define reg_dagc1_in_sat_cnt_31_24_pos 0
787#define reg_dagc1_in_sat_cnt_31_24_len 8
788#define reg_dagc1_in_sat_cnt_31_24_lsb 24
789#define xd_p_reg_dagc1_out_sat_cnt_7_0 0xA12B
790#define reg_dagc1_out_sat_cnt_7_0_pos 0
791#define reg_dagc1_out_sat_cnt_7_0_len 8
792#define reg_dagc1_out_sat_cnt_7_0_lsb 0
793#define xd_p_reg_dagc1_out_sat_cnt_15_8 0xA12C
794#define reg_dagc1_out_sat_cnt_15_8_pos 0
795#define reg_dagc1_out_sat_cnt_15_8_len 8
796#define reg_dagc1_out_sat_cnt_15_8_lsb 8
797#define xd_p_reg_dagc1_out_sat_cnt_23_16 0xA12D
798#define reg_dagc1_out_sat_cnt_23_16_pos 0
799#define reg_dagc1_out_sat_cnt_23_16_len 8
800#define reg_dagc1_out_sat_cnt_23_16_lsb 16
801#define xd_p_reg_dagc1_out_sat_cnt_31_24 0xA12E
802#define reg_dagc1_out_sat_cnt_31_24_pos 0
803#define reg_dagc1_out_sat_cnt_31_24_len 8
804#define reg_dagc1_out_sat_cnt_31_24_lsb 24
805#define xd_r_dagc1_multiplier_7_0 0xA136
806#define dagc1_multiplier_7_0_pos 0
807#define dagc1_multiplier_7_0_len 8
808#define dagc1_multiplier_7_0_lsb 0
809#define xd_r_dagc1_multiplier_15_8 0xA137
810#define dagc1_multiplier_15_8_pos 0
811#define dagc1_multiplier_15_8_len 8
812#define dagc1_multiplier_15_8_lsb 8
813#define xd_r_dagc1_right_shift_bits 0xA138
814#define dagc1_right_shift_bits_pos 0
815#define dagc1_right_shift_bits_len 4
816#define dagc1_right_shift_bits_lsb 0
817#define xd_p_reg_bfs_fcw_7_0 0xA140
818#define reg_bfs_fcw_7_0_pos 0
819#define reg_bfs_fcw_7_0_len 8
820#define reg_bfs_fcw_7_0_lsb 0
821#define xd_p_reg_bfs_fcw_15_8 0xA141
822#define reg_bfs_fcw_15_8_pos 0
823#define reg_bfs_fcw_15_8_len 8
824#define reg_bfs_fcw_15_8_lsb 8
825#define xd_p_reg_bfs_fcw_22_16 0xA142
826#define reg_bfs_fcw_22_16_pos 0
827#define reg_bfs_fcw_22_16_len 7
828#define reg_bfs_fcw_22_16_lsb 16
829#define xd_p_reg_antif_sf_7_0 0xA144
830#define reg_antif_sf_7_0_pos 0
831#define reg_antif_sf_7_0_len 8
832#define reg_antif_sf_7_0_lsb 0
833#define xd_p_reg_antif_sf_11_8 0xA145
834#define reg_antif_sf_11_8_pos 0
835#define reg_antif_sf_11_8_len 4
836#define reg_antif_sf_11_8_lsb 8
837#define xd_r_bfs_fcw_q_7_0 0xA150
838#define bfs_fcw_q_7_0_pos 0
839#define bfs_fcw_q_7_0_len 8
840#define bfs_fcw_q_7_0_lsb 0
841#define xd_r_bfs_fcw_q_15_8 0xA151
842#define bfs_fcw_q_15_8_pos 0
843#define bfs_fcw_q_15_8_len 8
844#define bfs_fcw_q_15_8_lsb 8
845#define xd_r_bfs_fcw_q_22_16 0xA152
846#define bfs_fcw_q_22_16_pos 0
847#define bfs_fcw_q_22_16_len 7
848#define bfs_fcw_q_22_16_lsb 16
849#define xd_p_reg_dca_enu 0xA160
850#define reg_dca_enu_pos 0
851#define reg_dca_enu_len 1
852#define reg_dca_enu_lsb 0
853#define xd_p_reg_dca_enl 0xA160
854#define reg_dca_enl_pos 1
855#define reg_dca_enl_len 1
856#define reg_dca_enl_lsb 0
857#define xd_p_reg_dca_lower_chip 0xA160
858#define reg_dca_lower_chip_pos 2
859#define reg_dca_lower_chip_len 1
860#define reg_dca_lower_chip_lsb 0
861#define xd_p_reg_dca_upper_chip 0xA160
862#define reg_dca_upper_chip_pos 3
863#define reg_dca_upper_chip_len 1
864#define reg_dca_upper_chip_lsb 0
865#define xd_p_reg_dca_platch 0xA160
866#define reg_dca_platch_pos 4
867#define reg_dca_platch_len 1
868#define reg_dca_platch_lsb 0
869#define xd_p_reg_dca_th 0xA161
870#define reg_dca_th_pos 0
871#define reg_dca_th_len 5
872#define reg_dca_th_lsb 0
873#define xd_p_reg_dca_scale 0xA162
874#define reg_dca_scale_pos 0
875#define reg_dca_scale_len 4
876#define reg_dca_scale_lsb 0
877#define xd_p_reg_dca_tone_7_0 0xA163
878#define reg_dca_tone_7_0_pos 0
879#define reg_dca_tone_7_0_len 8
880#define reg_dca_tone_7_0_lsb 0
881#define xd_p_reg_dca_tone_12_8 0xA164
882#define reg_dca_tone_12_8_pos 0
883#define reg_dca_tone_12_8_len 5
884#define reg_dca_tone_12_8_lsb 8
885#define xd_p_reg_dca_time_7_0 0xA165
886#define reg_dca_time_7_0_pos 0
887#define reg_dca_time_7_0_len 8
888#define reg_dca_time_7_0_lsb 0
889#define xd_p_reg_dca_time_15_8 0xA166
890#define reg_dca_time_15_8_pos 0
891#define reg_dca_time_15_8_len 8
892#define reg_dca_time_15_8_lsb 8
893#define xd_r_dcasm 0xA167
894#define dcasm_pos 0
895#define dcasm_len 3
896#define dcasm_lsb 0
897#define xd_p_reg_qnt_valuew_7_0 0xA168
898#define reg_qnt_valuew_7_0_pos 0
899#define reg_qnt_valuew_7_0_len 8
900#define reg_qnt_valuew_7_0_lsb 0
901#define xd_p_reg_qnt_valuew_10_8 0xA169
902#define reg_qnt_valuew_10_8_pos 0
903#define reg_qnt_valuew_10_8_len 3
904#define reg_qnt_valuew_10_8_lsb 8
905#define xd_p_dca_sbx_gain_diff_7_0 0xA16A
906#define dca_sbx_gain_diff_7_0_pos 0
907#define dca_sbx_gain_diff_7_0_len 8
908#define dca_sbx_gain_diff_7_0_lsb 0
909#define xd_p_dca_sbx_gain_diff_9_8 0xA16B
910#define dca_sbx_gain_diff_9_8_pos 0
911#define dca_sbx_gain_diff_9_8_len 2
912#define dca_sbx_gain_diff_9_8_lsb 8
913#define xd_p_reg_dca_stand_alone 0xA16C
914#define reg_dca_stand_alone_pos 0
915#define reg_dca_stand_alone_len 1
916#define reg_dca_stand_alone_lsb 0
917#define xd_p_reg_dca_upper_out_en 0xA16C
918#define reg_dca_upper_out_en_pos 1
919#define reg_dca_upper_out_en_len 1
920#define reg_dca_upper_out_en_lsb 0
921#define xd_p_reg_dca_rc_en 0xA16C
922#define reg_dca_rc_en_pos 2
923#define reg_dca_rc_en_len 1
924#define reg_dca_rc_en_lsb 0
925#define xd_p_reg_dca_retrain_send 0xA16C
926#define reg_dca_retrain_send_pos 3
927#define reg_dca_retrain_send_len 1
928#define reg_dca_retrain_send_lsb 0
929#define xd_p_reg_dca_retrain_rec 0xA16C
930#define reg_dca_retrain_rec_pos 4
931#define reg_dca_retrain_rec_len 1
932#define reg_dca_retrain_rec_lsb 0
933#define xd_p_reg_dca_api_tpsrdy 0xA16C
934#define reg_dca_api_tpsrdy_pos 5
935#define reg_dca_api_tpsrdy_len 1
936#define reg_dca_api_tpsrdy_lsb 0
937#define xd_p_reg_dca_symbol_gap 0xA16D
938#define reg_dca_symbol_gap_pos 0
939#define reg_dca_symbol_gap_len 4
940#define reg_dca_symbol_gap_lsb 0
941#define xd_p_reg_qnt_nfvaluew_7_0 0xA16E
942#define reg_qnt_nfvaluew_7_0_pos 0
943#define reg_qnt_nfvaluew_7_0_len 8
944#define reg_qnt_nfvaluew_7_0_lsb 0
945#define xd_p_reg_qnt_nfvaluew_10_8 0xA16F
946#define reg_qnt_nfvaluew_10_8_pos 0
947#define reg_qnt_nfvaluew_10_8_len 3
948#define reg_qnt_nfvaluew_10_8_lsb 8
949#define xd_p_reg_qnt_flatness_thr_7_0 0xA170
950#define reg_qnt_flatness_thr_7_0_pos 0
951#define reg_qnt_flatness_thr_7_0_len 8
952#define reg_qnt_flatness_thr_7_0_lsb 0
953#define xd_p_reg_qnt_flatness_thr_9_8 0xA171
954#define reg_qnt_flatness_thr_9_8_pos 0
955#define reg_qnt_flatness_thr_9_8_len 2
956#define reg_qnt_flatness_thr_9_8_lsb 8
957#define xd_p_reg_dca_tone_idx_5_0 0xA171
958#define reg_dca_tone_idx_5_0_pos 2
959#define reg_dca_tone_idx_5_0_len 6
960#define reg_dca_tone_idx_5_0_lsb 0
961#define xd_p_reg_dca_tone_idx_12_6 0xA172
962#define reg_dca_tone_idx_12_6_pos 0
963#define reg_dca_tone_idx_12_6_len 7
964#define reg_dca_tone_idx_12_6_lsb 6
965#define xd_p_reg_dca_data_vld 0xA173
966#define reg_dca_data_vld_pos 0
967#define reg_dca_data_vld_len 1
968#define reg_dca_data_vld_lsb 0
969#define xd_p_reg_dca_read_update 0xA173
970#define reg_dca_read_update_pos 1
971#define reg_dca_read_update_len 1
972#define reg_dca_read_update_lsb 0
973#define xd_r_reg_dca_data_re_5_0 0xA173
974#define reg_dca_data_re_5_0_pos 2
975#define reg_dca_data_re_5_0_len 6
976#define reg_dca_data_re_5_0_lsb 0
977#define xd_r_reg_dca_data_re_10_6 0xA174
978#define reg_dca_data_re_10_6_pos 0
979#define reg_dca_data_re_10_6_len 5
980#define reg_dca_data_re_10_6_lsb 6
981#define xd_r_reg_dca_data_im_7_0 0xA175
982#define reg_dca_data_im_7_0_pos 0
983#define reg_dca_data_im_7_0_len 8
984#define reg_dca_data_im_7_0_lsb 0
985#define xd_r_reg_dca_data_im_10_8 0xA176
986#define reg_dca_data_im_10_8_pos 0
987#define reg_dca_data_im_10_8_len 3
988#define reg_dca_data_im_10_8_lsb 8
989#define xd_r_reg_dca_data_h2_7_0 0xA178
990#define reg_dca_data_h2_7_0_pos 0
991#define reg_dca_data_h2_7_0_len 8
992#define reg_dca_data_h2_7_0_lsb 0
993#define xd_r_reg_dca_data_h2_9_8 0xA179
994#define reg_dca_data_h2_9_8_pos 0
995#define reg_dca_data_h2_9_8_len 2
996#define reg_dca_data_h2_9_8_lsb 8
997#define xd_p_reg_f_adc_7_0 0xA180
998#define reg_f_adc_7_0_pos 0
999#define reg_f_adc_7_0_len 8
1000#define reg_f_adc_7_0_lsb 0
1001#define xd_p_reg_f_adc_15_8 0xA181
1002#define reg_f_adc_15_8_pos 0
1003#define reg_f_adc_15_8_len 8
1004#define reg_f_adc_15_8_lsb 8
1005#define xd_p_reg_f_adc_23_16 0xA182
1006#define reg_f_adc_23_16_pos 0
1007#define reg_f_adc_23_16_len 8
1008#define reg_f_adc_23_16_lsb 16
1009#define xd_r_intp_mu_7_0 0xA190
1010#define intp_mu_7_0_pos 0
1011#define intp_mu_7_0_len 8
1012#define intp_mu_7_0_lsb 0
1013#define xd_r_intp_mu_15_8 0xA191
1014#define intp_mu_15_8_pos 0
1015#define intp_mu_15_8_len 8
1016#define intp_mu_15_8_lsb 8
1017#define xd_r_intp_mu_19_16 0xA192
1018#define intp_mu_19_16_pos 0
1019#define intp_mu_19_16_len 4
1020#define intp_mu_19_16_lsb 16
1021#define xd_p_reg_agc_rst 0xA1A0
1022#define reg_agc_rst_pos 0
1023#define reg_agc_rst_len 1
1024#define reg_agc_rst_lsb 0
1025#define xd_p_rf_agc_en 0xA1A0
1026#define rf_agc_en_pos 1
1027#define rf_agc_en_len 1
1028#define rf_agc_en_lsb 0
1029#define xd_p_rf_agc_dis 0xA1A0
1030#define rf_agc_dis_pos 2
1031#define rf_agc_dis_len 1
1032#define rf_agc_dis_lsb 0
1033#define xd_p_if_agc_rst 0xA1A0
1034#define if_agc_rst_pos 3
1035#define if_agc_rst_len 1
1036#define if_agc_rst_lsb 0
1037#define xd_p_if_agc_en 0xA1A0
1038#define if_agc_en_pos 4
1039#define if_agc_en_len 1
1040#define if_agc_en_lsb 0
1041#define xd_p_if_agc_dis 0xA1A0
1042#define if_agc_dis_pos 5
1043#define if_agc_dis_len 1
1044#define if_agc_dis_lsb 0
1045#define xd_p_agc_lock 0xA1A0
1046#define agc_lock_pos 6
1047#define agc_lock_len 1
1048#define agc_lock_lsb 0
1049#define xd_p_reg_tinr_rst 0xA1A1
1050#define reg_tinr_rst_pos 0
1051#define reg_tinr_rst_len 1
1052#define reg_tinr_rst_lsb 0
1053#define xd_p_reg_tinr_en 0xA1A1
1054#define reg_tinr_en_pos 1
1055#define reg_tinr_en_len 1
1056#define reg_tinr_en_lsb 0
1057#define xd_p_reg_ccifs_en 0xA1A2
1058#define reg_ccifs_en_pos 0
1059#define reg_ccifs_en_len 1
1060#define reg_ccifs_en_lsb 0
1061#define xd_p_reg_ccifs_dis 0xA1A2
1062#define reg_ccifs_dis_pos 1
1063#define reg_ccifs_dis_len 1
1064#define reg_ccifs_dis_lsb 0
1065#define xd_p_reg_ccifs_rst 0xA1A2
1066#define reg_ccifs_rst_pos 2
1067#define reg_ccifs_rst_len 1
1068#define reg_ccifs_rst_lsb 0
1069#define xd_p_reg_ccifs_byp 0xA1A2
1070#define reg_ccifs_byp_pos 3
1071#define reg_ccifs_byp_len 1
1072#define reg_ccifs_byp_lsb 0
1073#define xd_p_reg_ccif_en 0xA1A3
1074#define reg_ccif_en_pos 0
1075#define reg_ccif_en_len 1
1076#define reg_ccif_en_lsb 0
1077#define xd_p_reg_ccif_dis 0xA1A3
1078#define reg_ccif_dis_pos 1
1079#define reg_ccif_dis_len 1
1080#define reg_ccif_dis_lsb 0
1081#define xd_p_reg_ccif_rst 0xA1A3
1082#define reg_ccif_rst_pos 2
1083#define reg_ccif_rst_len 1
1084#define reg_ccif_rst_lsb 0
1085#define xd_p_reg_ccif_byp 0xA1A3
1086#define reg_ccif_byp_pos 3
1087#define reg_ccif_byp_len 1
1088#define reg_ccif_byp_lsb 0
1089#define xd_p_dagc1_rst 0xA1A4
1090#define dagc1_rst_pos 0
1091#define dagc1_rst_len 1
1092#define dagc1_rst_lsb 0
1093#define xd_p_dagc1_en 0xA1A4
1094#define dagc1_en_pos 1
1095#define dagc1_en_len 1
1096#define dagc1_en_lsb 0
1097#define xd_p_dagc1_mode 0xA1A4
1098#define dagc1_mode_pos 2
1099#define dagc1_mode_len 2
1100#define dagc1_mode_lsb 0
1101#define xd_p_dagc1_done 0xA1A4
1102#define dagc1_done_pos 4
1103#define dagc1_done_len 1
1104#define dagc1_done_lsb 0
1105#define xd_p_ccid_rst 0xA1A5
1106#define ccid_rst_pos 0
1107#define ccid_rst_len 1
1108#define ccid_rst_lsb 0
1109#define xd_p_ccid_en 0xA1A5
1110#define ccid_en_pos 1
1111#define ccid_en_len 1
1112#define ccid_en_lsb 0
1113#define xd_p_ccid_mode 0xA1A5
1114#define ccid_mode_pos 2
1115#define ccid_mode_len 2
1116#define ccid_mode_lsb 0
1117#define xd_p_ccid_done 0xA1A5
1118#define ccid_done_pos 4
1119#define ccid_done_len 1
1120#define ccid_done_lsb 0
1121#define xd_r_ccid_deted 0xA1A5
1122#define ccid_deted_pos 5
1123#define ccid_deted_len 1
1124#define ccid_deted_lsb 0
1125#define xd_p_ccid2_en 0xA1A5
1126#define ccid2_en_pos 6
1127#define ccid2_en_len 1
1128#define ccid2_en_lsb 0
1129#define xd_p_ccid2_done 0xA1A5
1130#define ccid2_done_pos 7
1131#define ccid2_done_len 1
1132#define ccid2_done_lsb 0
1133#define xd_p_reg_bfs_en 0xA1A6
1134#define reg_bfs_en_pos 0
1135#define reg_bfs_en_len 1
1136#define reg_bfs_en_lsb 0
1137#define xd_p_reg_bfs_dis 0xA1A6
1138#define reg_bfs_dis_pos 1
1139#define reg_bfs_dis_len 1
1140#define reg_bfs_dis_lsb 0
1141#define xd_p_reg_bfs_rst 0xA1A6
1142#define reg_bfs_rst_pos 2
1143#define reg_bfs_rst_len 1
1144#define reg_bfs_rst_lsb 0
1145#define xd_p_reg_bfs_byp 0xA1A6
1146#define reg_bfs_byp_pos 3
1147#define reg_bfs_byp_len 1
1148#define reg_bfs_byp_lsb 0
1149#define xd_p_reg_antif_en 0xA1A7
1150#define reg_antif_en_pos 0
1151#define reg_antif_en_len 1
1152#define reg_antif_en_lsb 0
1153#define xd_p_reg_antif_dis 0xA1A7
1154#define reg_antif_dis_pos 1
1155#define reg_antif_dis_len 1
1156#define reg_antif_dis_lsb 0
1157#define xd_p_reg_antif_rst 0xA1A7
1158#define reg_antif_rst_pos 2
1159#define reg_antif_rst_len 1
1160#define reg_antif_rst_lsb 0
1161#define xd_p_reg_antif_byp 0xA1A7
1162#define reg_antif_byp_pos 3
1163#define reg_antif_byp_len 1
1164#define reg_antif_byp_lsb 0
1165#define xd_p_intp_en 0xA1A8
1166#define intp_en_pos 0
1167#define intp_en_len 1
1168#define intp_en_lsb 0
1169#define xd_p_intp_dis 0xA1A8
1170#define intp_dis_pos 1
1171#define intp_dis_len 1
1172#define intp_dis_lsb 0
1173#define xd_p_intp_rst 0xA1A8
1174#define intp_rst_pos 2
1175#define intp_rst_len 1
1176#define intp_rst_lsb 0
1177#define xd_p_intp_byp 0xA1A8
1178#define intp_byp_pos 3
1179#define intp_byp_len 1
1180#define intp_byp_lsb 0
1181#define xd_p_reg_acif_en 0xA1A9
1182#define reg_acif_en_pos 0
1183#define reg_acif_en_len 1
1184#define reg_acif_en_lsb 0
1185#define xd_p_reg_acif_dis 0xA1A9
1186#define reg_acif_dis_pos 1
1187#define reg_acif_dis_len 1
1188#define reg_acif_dis_lsb 0
1189#define xd_p_reg_acif_rst 0xA1A9
1190#define reg_acif_rst_pos 2
1191#define reg_acif_rst_len 1
1192#define reg_acif_rst_lsb 0
1193#define xd_p_reg_acif_byp 0xA1A9
1194#define reg_acif_byp_pos 3
1195#define reg_acif_byp_len 1
1196#define reg_acif_byp_lsb 0
1197#define xd_p_reg_acif_sync_mode 0xA1A9
1198#define reg_acif_sync_mode_pos 4
1199#define reg_acif_sync_mode_len 1
1200#define reg_acif_sync_mode_lsb 0
1201#define xd_p_dagc2_rst 0xA1AA
1202#define dagc2_rst_pos 0
1203#define dagc2_rst_len 1
1204#define dagc2_rst_lsb 0
1205#define xd_p_dagc2_en 0xA1AA
1206#define dagc2_en_pos 1
1207#define dagc2_en_len 1
1208#define dagc2_en_lsb 0
1209#define xd_p_dagc2_mode 0xA1AA
1210#define dagc2_mode_pos 2
1211#define dagc2_mode_len 2
1212#define dagc2_mode_lsb 0
1213#define xd_p_dagc2_done 0xA1AA
1214#define dagc2_done_pos 4
1215#define dagc2_done_len 1
1216#define dagc2_done_lsb 0
1217#define xd_p_reg_dca_en 0xA1AB
1218#define reg_dca_en_pos 0
1219#define reg_dca_en_len 1
1220#define reg_dca_en_lsb 0
1221#define xd_p_dagc2_accumulate_num_2k_7_0 0xA1C0
1222#define dagc2_accumulate_num_2k_7_0_pos 0
1223#define dagc2_accumulate_num_2k_7_0_len 8
1224#define dagc2_accumulate_num_2k_7_0_lsb 0
1225#define xd_p_dagc2_accumulate_num_2k_12_8 0xA1C1
1226#define dagc2_accumulate_num_2k_12_8_pos 0
1227#define dagc2_accumulate_num_2k_12_8_len 5
1228#define dagc2_accumulate_num_2k_12_8_lsb 8
1229#define xd_p_dagc2_accumulate_num_8k_7_0 0xA1C2
1230#define dagc2_accumulate_num_8k_7_0_pos 0
1231#define dagc2_accumulate_num_8k_7_0_len 8
1232#define dagc2_accumulate_num_8k_7_0_lsb 0
1233#define xd_p_dagc2_accumulate_num_8k_12_8 0xA1C3
1234#define dagc2_accumulate_num_8k_12_8_pos 0
1235#define dagc2_accumulate_num_8k_12_8_len 5
1236#define dagc2_accumulate_num_8k_12_8_lsb 8
1237#define xd_p_dagc2_desired_level_2_0 0xA1C3
1238#define dagc2_desired_level_2_0_pos 5
1239#define dagc2_desired_level_2_0_len 3
1240#define dagc2_desired_level_2_0_lsb 0
1241#define xd_p_dagc2_desired_level_8_3 0xA1C4
1242#define dagc2_desired_level_8_3_pos 0
1243#define dagc2_desired_level_8_3_len 6
1244#define dagc2_desired_level_8_3_lsb 3
1245#define xd_p_dagc2_apply_delay 0xA1C5
1246#define dagc2_apply_delay_pos 0
1247#define dagc2_apply_delay_len 7
1248#define dagc2_apply_delay_lsb 0
1249#define xd_p_dagc2_bypass_scale_ctl 0xA1C6
1250#define dagc2_bypass_scale_ctl_pos 0
1251#define dagc2_bypass_scale_ctl_len 3
1252#define dagc2_bypass_scale_ctl_lsb 0
1253#define xd_p_dagc2_programmable_shift1 0xA1C7
1254#define dagc2_programmable_shift1_pos 0
1255#define dagc2_programmable_shift1_len 8
1256#define dagc2_programmable_shift1_lsb 0
1257#define xd_p_dagc2_programmable_shift2 0xA1C8
1258#define dagc2_programmable_shift2_pos 0
1259#define dagc2_programmable_shift2_len 8
1260#define dagc2_programmable_shift2_lsb 0
1261#define xd_p_reg_dagc2_in_sat_cnt_7_0 0xA1C9
1262#define reg_dagc2_in_sat_cnt_7_0_pos 0
1263#define reg_dagc2_in_sat_cnt_7_0_len 8
1264#define reg_dagc2_in_sat_cnt_7_0_lsb 0
1265#define xd_p_reg_dagc2_in_sat_cnt_15_8 0xA1CA
1266#define reg_dagc2_in_sat_cnt_15_8_pos 0
1267#define reg_dagc2_in_sat_cnt_15_8_len 8
1268#define reg_dagc2_in_sat_cnt_15_8_lsb 8
1269#define xd_p_reg_dagc2_in_sat_cnt_23_16 0xA1CB
1270#define reg_dagc2_in_sat_cnt_23_16_pos 0
1271#define reg_dagc2_in_sat_cnt_23_16_len 8
1272#define reg_dagc2_in_sat_cnt_23_16_lsb 16
1273#define xd_p_reg_dagc2_in_sat_cnt_31_24 0xA1CC
1274#define reg_dagc2_in_sat_cnt_31_24_pos 0
1275#define reg_dagc2_in_sat_cnt_31_24_len 8
1276#define reg_dagc2_in_sat_cnt_31_24_lsb 24
1277#define xd_p_reg_dagc2_out_sat_cnt_7_0 0xA1CD
1278#define reg_dagc2_out_sat_cnt_7_0_pos 0
1279#define reg_dagc2_out_sat_cnt_7_0_len 8
1280#define reg_dagc2_out_sat_cnt_7_0_lsb 0
1281#define xd_p_reg_dagc2_out_sat_cnt_15_8 0xA1CE
1282#define reg_dagc2_out_sat_cnt_15_8_pos 0
1283#define reg_dagc2_out_sat_cnt_15_8_len 8
1284#define reg_dagc2_out_sat_cnt_15_8_lsb 8
1285#define xd_p_reg_dagc2_out_sat_cnt_23_16 0xA1CF
1286#define reg_dagc2_out_sat_cnt_23_16_pos 0
1287#define reg_dagc2_out_sat_cnt_23_16_len 8
1288#define reg_dagc2_out_sat_cnt_23_16_lsb 16
1289#define xd_p_reg_dagc2_out_sat_cnt_31_24 0xA1D0
1290#define reg_dagc2_out_sat_cnt_31_24_pos 0
1291#define reg_dagc2_out_sat_cnt_31_24_len 8
1292#define reg_dagc2_out_sat_cnt_31_24_lsb 24
1293#define xd_r_dagc2_multiplier_7_0 0xA1D6
1294#define dagc2_multiplier_7_0_pos 0
1295#define dagc2_multiplier_7_0_len 8
1296#define dagc2_multiplier_7_0_lsb 0
1297#define xd_r_dagc2_multiplier_15_8 0xA1D7
1298#define dagc2_multiplier_15_8_pos 0
1299#define dagc2_multiplier_15_8_len 8
1300#define dagc2_multiplier_15_8_lsb 8
1301#define xd_r_dagc2_right_shift_bits 0xA1D8
1302#define dagc2_right_shift_bits_pos 0
1303#define dagc2_right_shift_bits_len 4
1304#define dagc2_right_shift_bits_lsb 0
1305#define xd_p_cfoe_NS_coeff1_7_0 0xA200
1306#define cfoe_NS_coeff1_7_0_pos 0
1307#define cfoe_NS_coeff1_7_0_len 8
1308#define cfoe_NS_coeff1_7_0_lsb 0
1309#define xd_p_cfoe_NS_coeff1_15_8 0xA201
1310#define cfoe_NS_coeff1_15_8_pos 0
1311#define cfoe_NS_coeff1_15_8_len 8
1312#define cfoe_NS_coeff1_15_8_lsb 8
1313#define xd_p_cfoe_NS_coeff1_23_16 0xA202
1314#define cfoe_NS_coeff1_23_16_pos 0
1315#define cfoe_NS_coeff1_23_16_len 8
1316#define cfoe_NS_coeff1_23_16_lsb 16
1317#define xd_p_cfoe_NS_coeff1_25_24 0xA203
1318#define cfoe_NS_coeff1_25_24_pos 0
1319#define cfoe_NS_coeff1_25_24_len 2
1320#define cfoe_NS_coeff1_25_24_lsb 24
1321#define xd_p_cfoe_NS_coeff2_5_0 0xA203
1322#define cfoe_NS_coeff2_5_0_pos 2
1323#define cfoe_NS_coeff2_5_0_len 6
1324#define cfoe_NS_coeff2_5_0_lsb 0
1325#define xd_p_cfoe_NS_coeff2_13_6 0xA204
1326#define cfoe_NS_coeff2_13_6_pos 0
1327#define cfoe_NS_coeff2_13_6_len 8
1328#define cfoe_NS_coeff2_13_6_lsb 6
1329#define xd_p_cfoe_NS_coeff2_21_14 0xA205
1330#define cfoe_NS_coeff2_21_14_pos 0
1331#define cfoe_NS_coeff2_21_14_len 8
1332#define cfoe_NS_coeff2_21_14_lsb 14
1333#define xd_p_cfoe_NS_coeff2_24_22 0xA206
1334#define cfoe_NS_coeff2_24_22_pos 0
1335#define cfoe_NS_coeff2_24_22_len 3
1336#define cfoe_NS_coeff2_24_22_lsb 22
1337#define xd_p_cfoe_lf_c1_4_0 0xA206
1338#define cfoe_lf_c1_4_0_pos 3
1339#define cfoe_lf_c1_4_0_len 5
1340#define cfoe_lf_c1_4_0_lsb 0
1341#define xd_p_cfoe_lf_c1_12_5 0xA207
1342#define cfoe_lf_c1_12_5_pos 0
1343#define cfoe_lf_c1_12_5_len 8
1344#define cfoe_lf_c1_12_5_lsb 5
1345#define xd_p_cfoe_lf_c1_20_13 0xA208
1346#define cfoe_lf_c1_20_13_pos 0
1347#define cfoe_lf_c1_20_13_len 8
1348#define cfoe_lf_c1_20_13_lsb 13
1349#define xd_p_cfoe_lf_c1_25_21 0xA209
1350#define cfoe_lf_c1_25_21_pos 0
1351#define cfoe_lf_c1_25_21_len 5
1352#define cfoe_lf_c1_25_21_lsb 21
1353#define xd_p_cfoe_lf_c2_2_0 0xA209
1354#define cfoe_lf_c2_2_0_pos 5
1355#define cfoe_lf_c2_2_0_len 3
1356#define cfoe_lf_c2_2_0_lsb 0
1357#define xd_p_cfoe_lf_c2_10_3 0xA20A
1358#define cfoe_lf_c2_10_3_pos 0
1359#define cfoe_lf_c2_10_3_len 8
1360#define cfoe_lf_c2_10_3_lsb 3
1361#define xd_p_cfoe_lf_c2_18_11 0xA20B
1362#define cfoe_lf_c2_18_11_pos 0
1363#define cfoe_lf_c2_18_11_len 8
1364#define cfoe_lf_c2_18_11_lsb 11
1365#define xd_p_cfoe_lf_c2_25_19 0xA20C
1366#define cfoe_lf_c2_25_19_pos 0
1367#define cfoe_lf_c2_25_19_len 7
1368#define cfoe_lf_c2_25_19_lsb 19
1369#define xd_p_cfoe_ifod_7_0 0xA20D
1370#define cfoe_ifod_7_0_pos 0
1371#define cfoe_ifod_7_0_len 8
1372#define cfoe_ifod_7_0_lsb 0
1373#define xd_p_cfoe_ifod_10_8 0xA20E
1374#define cfoe_ifod_10_8_pos 0
1375#define cfoe_ifod_10_8_len 3
1376#define cfoe_ifod_10_8_lsb 8
1377#define xd_p_cfoe_Divg_ctr_th 0xA20E
1378#define cfoe_Divg_ctr_th_pos 4
1379#define cfoe_Divg_ctr_th_len 4
1380#define cfoe_Divg_ctr_th_lsb 0
1381#define xd_p_cfoe_FOT_divg_th 0xA20F
1382#define cfoe_FOT_divg_th_pos 0
1383#define cfoe_FOT_divg_th_len 8
1384#define cfoe_FOT_divg_th_lsb 0
1385#define xd_p_cfoe_FOT_cnvg_th 0xA210
1386#define cfoe_FOT_cnvg_th_pos 0
1387#define cfoe_FOT_cnvg_th_len 8
1388#define cfoe_FOT_cnvg_th_lsb 0
1389#define xd_p_reg_cfoe_offset_7_0 0xA211
1390#define reg_cfoe_offset_7_0_pos 0
1391#define reg_cfoe_offset_7_0_len 8
1392#define reg_cfoe_offset_7_0_lsb 0
1393#define xd_p_reg_cfoe_offset_9_8 0xA212
1394#define reg_cfoe_offset_9_8_pos 0
1395#define reg_cfoe_offset_9_8_len 2
1396#define reg_cfoe_offset_9_8_lsb 8
1397#define xd_p_reg_cfoe_ifoe_sign_corr 0xA212
1398#define reg_cfoe_ifoe_sign_corr_pos 2
1399#define reg_cfoe_ifoe_sign_corr_len 1
1400#define reg_cfoe_ifoe_sign_corr_lsb 0
1401#define xd_r_cfoe_fot_LF_output_7_0 0xA218
1402#define cfoe_fot_LF_output_7_0_pos 0
1403#define cfoe_fot_LF_output_7_0_len 8
1404#define cfoe_fot_LF_output_7_0_lsb 0
1405#define xd_r_cfoe_fot_LF_output_15_8 0xA219
1406#define cfoe_fot_LF_output_15_8_pos 0
1407#define cfoe_fot_LF_output_15_8_len 8
1408#define cfoe_fot_LF_output_15_8_lsb 8
1409#define xd_r_cfoe_ifo_metric_7_0 0xA21A
1410#define cfoe_ifo_metric_7_0_pos 0
1411#define cfoe_ifo_metric_7_0_len 8
1412#define cfoe_ifo_metric_7_0_lsb 0
1413#define xd_r_cfoe_ifo_metric_15_8 0xA21B
1414#define cfoe_ifo_metric_15_8_pos 0
1415#define cfoe_ifo_metric_15_8_len 8
1416#define cfoe_ifo_metric_15_8_lsb 8
1417#define xd_r_cfoe_ifo_metric_23_16 0xA21C
1418#define cfoe_ifo_metric_23_16_pos 0
1419#define cfoe_ifo_metric_23_16_len 8
1420#define cfoe_ifo_metric_23_16_lsb 16
1421#define xd_p_ste_Nu 0xA220
1422#define ste_Nu_pos 0
1423#define ste_Nu_len 2
1424#define ste_Nu_lsb 0
1425#define xd_p_ste_GI 0xA220
1426#define ste_GI_pos 2
1427#define ste_GI_len 3
1428#define ste_GI_lsb 0
1429#define xd_p_ste_symbol_num 0xA221
1430#define ste_symbol_num_pos 0
1431#define ste_symbol_num_len 2
1432#define ste_symbol_num_lsb 0
1433#define xd_p_ste_sample_num 0xA221
1434#define ste_sample_num_pos 2
1435#define ste_sample_num_len 2
1436#define ste_sample_num_lsb 0
1437#define xd_p_reg_ste_buf_en 0xA221
1438#define reg_ste_buf_en_pos 7
1439#define reg_ste_buf_en_len 1
1440#define reg_ste_buf_en_lsb 0
1441#define xd_p_ste_FFT_offset_7_0 0xA222
1442#define ste_FFT_offset_7_0_pos 0
1443#define ste_FFT_offset_7_0_len 8
1444#define ste_FFT_offset_7_0_lsb 0
1445#define xd_p_ste_FFT_offset_11_8 0xA223
1446#define ste_FFT_offset_11_8_pos 0
1447#define ste_FFT_offset_11_8_len 4
1448#define ste_FFT_offset_11_8_lsb 8
1449#define xd_p_reg_ste_tstmod 0xA223
1450#define reg_ste_tstmod_pos 5
1451#define reg_ste_tstmod_len 1
1452#define reg_ste_tstmod_lsb 0
1453#define xd_p_ste_adv_start_7_0 0xA224
1454#define ste_adv_start_7_0_pos 0
1455#define ste_adv_start_7_0_len 8
1456#define ste_adv_start_7_0_lsb 0
1457#define xd_p_ste_adv_start_10_8 0xA225
1458#define ste_adv_start_10_8_pos 0
1459#define ste_adv_start_10_8_len 3
1460#define ste_adv_start_10_8_lsb 8
1461#define xd_p_ste_adv_stop 0xA226
1462#define ste_adv_stop_pos 0
1463#define ste_adv_stop_len 8
1464#define ste_adv_stop_lsb 0
1465#define xd_r_ste_P_value_7_0 0xA228
1466#define ste_P_value_7_0_pos 0
1467#define ste_P_value_7_0_len 8
1468#define ste_P_value_7_0_lsb 0
1469#define xd_r_ste_P_value_10_8 0xA229
1470#define ste_P_value_10_8_pos 0
1471#define ste_P_value_10_8_len 3
1472#define ste_P_value_10_8_lsb 8
1473#define xd_r_ste_M_value_7_0 0xA22A
1474#define ste_M_value_7_0_pos 0
1475#define ste_M_value_7_0_len 8
1476#define ste_M_value_7_0_lsb 0
1477#define xd_r_ste_M_value_10_8 0xA22B
1478#define ste_M_value_10_8_pos 0
1479#define ste_M_value_10_8_len 3
1480#define ste_M_value_10_8_lsb 8
1481#define xd_r_ste_H1 0xA22C
1482#define ste_H1_pos 0
1483#define ste_H1_len 7
1484#define ste_H1_lsb 0
1485#define xd_r_ste_H2 0xA22D
1486#define ste_H2_pos 0
1487#define ste_H2_len 7
1488#define ste_H2_lsb 0
1489#define xd_r_ste_H3 0xA22E
1490#define ste_H3_pos 0
1491#define ste_H3_len 7
1492#define ste_H3_lsb 0
1493#define xd_r_ste_H4 0xA22F
1494#define ste_H4_pos 0
1495#define ste_H4_len 7
1496#define ste_H4_lsb 0
1497#define xd_r_ste_Corr_value_I_7_0 0xA230
1498#define ste_Corr_value_I_7_0_pos 0
1499#define ste_Corr_value_I_7_0_len 8
1500#define ste_Corr_value_I_7_0_lsb 0
1501#define xd_r_ste_Corr_value_I_15_8 0xA231
1502#define ste_Corr_value_I_15_8_pos 0
1503#define ste_Corr_value_I_15_8_len 8
1504#define ste_Corr_value_I_15_8_lsb 8
1505#define xd_r_ste_Corr_value_I_23_16 0xA232
1506#define ste_Corr_value_I_23_16_pos 0
1507#define ste_Corr_value_I_23_16_len 8
1508#define ste_Corr_value_I_23_16_lsb 16
1509#define xd_r_ste_Corr_value_I_27_24 0xA233
1510#define ste_Corr_value_I_27_24_pos 0
1511#define ste_Corr_value_I_27_24_len 4
1512#define ste_Corr_value_I_27_24_lsb 24
1513#define xd_r_ste_Corr_value_Q_7_0 0xA234
1514#define ste_Corr_value_Q_7_0_pos 0
1515#define ste_Corr_value_Q_7_0_len 8
1516#define ste_Corr_value_Q_7_0_lsb 0
1517#define xd_r_ste_Corr_value_Q_15_8 0xA235
1518#define ste_Corr_value_Q_15_8_pos 0
1519#define ste_Corr_value_Q_15_8_len 8
1520#define ste_Corr_value_Q_15_8_lsb 8
1521#define xd_r_ste_Corr_value_Q_23_16 0xA236
1522#define ste_Corr_value_Q_23_16_pos 0
1523#define ste_Corr_value_Q_23_16_len 8
1524#define ste_Corr_value_Q_23_16_lsb 16
1525#define xd_r_ste_Corr_value_Q_27_24 0xA237
1526#define ste_Corr_value_Q_27_24_pos 0
1527#define ste_Corr_value_Q_27_24_len 4
1528#define ste_Corr_value_Q_27_24_lsb 24
1529#define xd_r_ste_J_num_7_0 0xA238
1530#define ste_J_num_7_0_pos 0
1531#define ste_J_num_7_0_len 8
1532#define ste_J_num_7_0_lsb 0
1533#define xd_r_ste_J_num_15_8 0xA239
1534#define ste_J_num_15_8_pos 0
1535#define ste_J_num_15_8_len 8
1536#define ste_J_num_15_8_lsb 8
1537#define xd_r_ste_J_num_23_16 0xA23A
1538#define ste_J_num_23_16_pos 0
1539#define ste_J_num_23_16_len 8
1540#define ste_J_num_23_16_lsb 16
1541#define xd_r_ste_J_num_31_24 0xA23B
1542#define ste_J_num_31_24_pos 0
1543#define ste_J_num_31_24_len 8
1544#define ste_J_num_31_24_lsb 24
1545#define xd_r_ste_J_den_7_0 0xA23C
1546#define ste_J_den_7_0_pos 0
1547#define ste_J_den_7_0_len 8
1548#define ste_J_den_7_0_lsb 0
1549#define xd_r_ste_J_den_15_8 0xA23D
1550#define ste_J_den_15_8_pos 0
1551#define ste_J_den_15_8_len 8
1552#define ste_J_den_15_8_lsb 8
1553#define xd_r_ste_J_den_18_16 0xA23E
1554#define ste_J_den_18_16_pos 0
1555#define ste_J_den_18_16_len 3
1556#define ste_J_den_18_16_lsb 16
1557#define xd_r_ste_Beacon_Indicator 0xA23E
1558#define ste_Beacon_Indicator_pos 4
1559#define ste_Beacon_Indicator_len 1
1560#define ste_Beacon_Indicator_lsb 0
1561#define xd_r_tpsd_Frame_Num 0xA250
1562#define tpsd_Frame_Num_pos 0
1563#define tpsd_Frame_Num_len 2
1564#define tpsd_Frame_Num_lsb 0
1565#define xd_r_tpsd_Constel 0xA250
1566#define tpsd_Constel_pos 2
1567#define tpsd_Constel_len 2
1568#define tpsd_Constel_lsb 0
1569#define xd_r_tpsd_GI 0xA250
1570#define tpsd_GI_pos 4
1571#define tpsd_GI_len 2
1572#define tpsd_GI_lsb 0
1573#define xd_r_tpsd_Mode 0xA250
1574#define tpsd_Mode_pos 6
1575#define tpsd_Mode_len 2
1576#define tpsd_Mode_lsb 0
1577#define xd_r_tpsd_CR_HP 0xA251
1578#define tpsd_CR_HP_pos 0
1579#define tpsd_CR_HP_len 3
1580#define tpsd_CR_HP_lsb 0
1581#define xd_r_tpsd_CR_LP 0xA251
1582#define tpsd_CR_LP_pos 3
1583#define tpsd_CR_LP_len 3
1584#define tpsd_CR_LP_lsb 0
1585#define xd_r_tpsd_Hie 0xA252
1586#define tpsd_Hie_pos 0
1587#define tpsd_Hie_len 3
1588#define tpsd_Hie_lsb 0
1589#define xd_r_tpsd_Res_Bits 0xA252
1590#define tpsd_Res_Bits_pos 3
1591#define tpsd_Res_Bits_len 5
1592#define tpsd_Res_Bits_lsb 0
1593#define xd_r_tpsd_Res_Bits_0 0xA253
1594#define tpsd_Res_Bits_0_pos 0
1595#define tpsd_Res_Bits_0_len 1
1596#define tpsd_Res_Bits_0_lsb 0
1597#define xd_r_tpsd_LengthInd 0xA253
1598#define tpsd_LengthInd_pos 1
1599#define tpsd_LengthInd_len 6
1600#define tpsd_LengthInd_lsb 0
1601#define xd_r_tpsd_Cell_Id_7_0 0xA254
1602#define tpsd_Cell_Id_7_0_pos 0
1603#define tpsd_Cell_Id_7_0_len 8
1604#define tpsd_Cell_Id_7_0_lsb 0
1605#define xd_r_tpsd_Cell_Id_15_8 0xA255
1606#define tpsd_Cell_Id_15_8_pos 0
1607#define tpsd_Cell_Id_15_8_len 8
1608#define tpsd_Cell_Id_15_8_lsb 0
1609#define xd_p_reg_fft_mask_tone0_7_0 0xA260
1610#define reg_fft_mask_tone0_7_0_pos 0
1611#define reg_fft_mask_tone0_7_0_len 8
1612#define reg_fft_mask_tone0_7_0_lsb 0
1613#define xd_p_reg_fft_mask_tone0_12_8 0xA261
1614#define reg_fft_mask_tone0_12_8_pos 0
1615#define reg_fft_mask_tone0_12_8_len 5
1616#define reg_fft_mask_tone0_12_8_lsb 8
1617#define xd_p_reg_fft_mask_tone1_7_0 0xA262
1618#define reg_fft_mask_tone1_7_0_pos 0
1619#define reg_fft_mask_tone1_7_0_len 8
1620#define reg_fft_mask_tone1_7_0_lsb 0
1621#define xd_p_reg_fft_mask_tone1_12_8 0xA263
1622#define reg_fft_mask_tone1_12_8_pos 0
1623#define reg_fft_mask_tone1_12_8_len 5
1624#define reg_fft_mask_tone1_12_8_lsb 8
1625#define xd_p_reg_fft_mask_tone2_7_0 0xA264
1626#define reg_fft_mask_tone2_7_0_pos 0
1627#define reg_fft_mask_tone2_7_0_len 8
1628#define reg_fft_mask_tone2_7_0_lsb 0
1629#define xd_p_reg_fft_mask_tone2_12_8 0xA265
1630#define reg_fft_mask_tone2_12_8_pos 0
1631#define reg_fft_mask_tone2_12_8_len 5
1632#define reg_fft_mask_tone2_12_8_lsb 8
1633#define xd_p_reg_fft_mask_tone3_7_0 0xA266
1634#define reg_fft_mask_tone3_7_0_pos 0
1635#define reg_fft_mask_tone3_7_0_len 8
1636#define reg_fft_mask_tone3_7_0_lsb 0
1637#define xd_p_reg_fft_mask_tone3_12_8 0xA267
1638#define reg_fft_mask_tone3_12_8_pos 0
1639#define reg_fft_mask_tone3_12_8_len 5
1640#define reg_fft_mask_tone3_12_8_lsb 8
1641#define xd_p_reg_fft_mask_from0_7_0 0xA268
1642#define reg_fft_mask_from0_7_0_pos 0
1643#define reg_fft_mask_from0_7_0_len 8
1644#define reg_fft_mask_from0_7_0_lsb 0
1645#define xd_p_reg_fft_mask_from0_12_8 0xA269
1646#define reg_fft_mask_from0_12_8_pos 0
1647#define reg_fft_mask_from0_12_8_len 5
1648#define reg_fft_mask_from0_12_8_lsb 8
1649#define xd_p_reg_fft_mask_to0_7_0 0xA26A
1650#define reg_fft_mask_to0_7_0_pos 0
1651#define reg_fft_mask_to0_7_0_len 8
1652#define reg_fft_mask_to0_7_0_lsb 0
1653#define xd_p_reg_fft_mask_to0_12_8 0xA26B
1654#define reg_fft_mask_to0_12_8_pos 0
1655#define reg_fft_mask_to0_12_8_len 5
1656#define reg_fft_mask_to0_12_8_lsb 8
1657#define xd_p_reg_fft_mask_from1_7_0 0xA26C
1658#define reg_fft_mask_from1_7_0_pos 0
1659#define reg_fft_mask_from1_7_0_len 8
1660#define reg_fft_mask_from1_7_0_lsb 0
1661#define xd_p_reg_fft_mask_from1_12_8 0xA26D
1662#define reg_fft_mask_from1_12_8_pos 0
1663#define reg_fft_mask_from1_12_8_len 5
1664#define reg_fft_mask_from1_12_8_lsb 8
1665#define xd_p_reg_fft_mask_to1_7_0 0xA26E
1666#define reg_fft_mask_to1_7_0_pos 0
1667#define reg_fft_mask_to1_7_0_len 8
1668#define reg_fft_mask_to1_7_0_lsb 0
1669#define xd_p_reg_fft_mask_to1_12_8 0xA26F
1670#define reg_fft_mask_to1_12_8_pos 0
1671#define reg_fft_mask_to1_12_8_len 5
1672#define reg_fft_mask_to1_12_8_lsb 8
1673#define xd_p_reg_cge_idx0_7_0 0xA280
1674#define reg_cge_idx0_7_0_pos 0
1675#define reg_cge_idx0_7_0_len 8
1676#define reg_cge_idx0_7_0_lsb 0
1677#define xd_p_reg_cge_idx0_12_8 0xA281
1678#define reg_cge_idx0_12_8_pos 0
1679#define reg_cge_idx0_12_8_len 5
1680#define reg_cge_idx0_12_8_lsb 8
1681#define xd_p_reg_cge_idx1_7_0 0xA282
1682#define reg_cge_idx1_7_0_pos 0
1683#define reg_cge_idx1_7_0_len 8
1684#define reg_cge_idx1_7_0_lsb 0
1685#define xd_p_reg_cge_idx1_12_8 0xA283
1686#define reg_cge_idx1_12_8_pos 0
1687#define reg_cge_idx1_12_8_len 5
1688#define reg_cge_idx1_12_8_lsb 8
1689#define xd_p_reg_cge_idx2_7_0 0xA284
1690#define reg_cge_idx2_7_0_pos 0
1691#define reg_cge_idx2_7_0_len 8
1692#define reg_cge_idx2_7_0_lsb 0
1693#define xd_p_reg_cge_idx2_12_8 0xA285
1694#define reg_cge_idx2_12_8_pos 0
1695#define reg_cge_idx2_12_8_len 5
1696#define reg_cge_idx2_12_8_lsb 8
1697#define xd_p_reg_cge_idx3_7_0 0xA286
1698#define reg_cge_idx3_7_0_pos 0
1699#define reg_cge_idx3_7_0_len 8
1700#define reg_cge_idx3_7_0_lsb 0
1701#define xd_p_reg_cge_idx3_12_8 0xA287
1702#define reg_cge_idx3_12_8_pos 0
1703#define reg_cge_idx3_12_8_len 5
1704#define reg_cge_idx3_12_8_lsb 8
1705#define xd_p_reg_cge_idx4_7_0 0xA288
1706#define reg_cge_idx4_7_0_pos 0
1707#define reg_cge_idx4_7_0_len 8
1708#define reg_cge_idx4_7_0_lsb 0
1709#define xd_p_reg_cge_idx4_12_8 0xA289
1710#define reg_cge_idx4_12_8_pos 0
1711#define reg_cge_idx4_12_8_len 5
1712#define reg_cge_idx4_12_8_lsb 8
1713#define xd_p_reg_cge_idx5_7_0 0xA28A
1714#define reg_cge_idx5_7_0_pos 0
1715#define reg_cge_idx5_7_0_len 8
1716#define reg_cge_idx5_7_0_lsb 0
1717#define xd_p_reg_cge_idx5_12_8 0xA28B
1718#define reg_cge_idx5_12_8_pos 0
1719#define reg_cge_idx5_12_8_len 5
1720#define reg_cge_idx5_12_8_lsb 8
1721#define xd_p_reg_cge_idx6_7_0 0xA28C
1722#define reg_cge_idx6_7_0_pos 0
1723#define reg_cge_idx6_7_0_len 8
1724#define reg_cge_idx6_7_0_lsb 0
1725#define xd_p_reg_cge_idx6_12_8 0xA28D
1726#define reg_cge_idx6_12_8_pos 0
1727#define reg_cge_idx6_12_8_len 5
1728#define reg_cge_idx6_12_8_lsb 8
1729#define xd_p_reg_cge_idx7_7_0 0xA28E
1730#define reg_cge_idx7_7_0_pos 0
1731#define reg_cge_idx7_7_0_len 8
1732#define reg_cge_idx7_7_0_lsb 0
1733#define xd_p_reg_cge_idx7_12_8 0xA28F
1734#define reg_cge_idx7_12_8_pos 0
1735#define reg_cge_idx7_12_8_len 5
1736#define reg_cge_idx7_12_8_lsb 8
1737#define xd_p_reg_cge_idx8_7_0 0xA290
1738#define reg_cge_idx8_7_0_pos 0
1739#define reg_cge_idx8_7_0_len 8
1740#define reg_cge_idx8_7_0_lsb 0
1741#define xd_p_reg_cge_idx8_12_8 0xA291
1742#define reg_cge_idx8_12_8_pos 0
1743#define reg_cge_idx8_12_8_len 5
1744#define reg_cge_idx8_12_8_lsb 8
1745#define xd_p_reg_cge_idx9_7_0 0xA292
1746#define reg_cge_idx9_7_0_pos 0
1747#define reg_cge_idx9_7_0_len 8
1748#define reg_cge_idx9_7_0_lsb 0
1749#define xd_p_reg_cge_idx9_12_8 0xA293
1750#define reg_cge_idx9_12_8_pos 0
1751#define reg_cge_idx9_12_8_len 5
1752#define reg_cge_idx9_12_8_lsb 8
1753#define xd_p_reg_cge_idx10_7_0 0xA294
1754#define reg_cge_idx10_7_0_pos 0
1755#define reg_cge_idx10_7_0_len 8
1756#define reg_cge_idx10_7_0_lsb 0
1757#define xd_p_reg_cge_idx10_12_8 0xA295
1758#define reg_cge_idx10_12_8_pos 0
1759#define reg_cge_idx10_12_8_len 5
1760#define reg_cge_idx10_12_8_lsb 8
1761#define xd_p_reg_cge_idx11_7_0 0xA296
1762#define reg_cge_idx11_7_0_pos 0
1763#define reg_cge_idx11_7_0_len 8
1764#define reg_cge_idx11_7_0_lsb 0
1765#define xd_p_reg_cge_idx11_12_8 0xA297
1766#define reg_cge_idx11_12_8_pos 0
1767#define reg_cge_idx11_12_8_len 5
1768#define reg_cge_idx11_12_8_lsb 8
1769#define xd_p_reg_cge_idx12_7_0 0xA298
1770#define reg_cge_idx12_7_0_pos 0
1771#define reg_cge_idx12_7_0_len 8
1772#define reg_cge_idx12_7_0_lsb 0
1773#define xd_p_reg_cge_idx12_12_8 0xA299
1774#define reg_cge_idx12_12_8_pos 0
1775#define reg_cge_idx12_12_8_len 5
1776#define reg_cge_idx12_12_8_lsb 8
1777#define xd_p_reg_cge_idx13_7_0 0xA29A
1778#define reg_cge_idx13_7_0_pos 0
1779#define reg_cge_idx13_7_0_len 8
1780#define reg_cge_idx13_7_0_lsb 0
1781#define xd_p_reg_cge_idx13_12_8 0xA29B
1782#define reg_cge_idx13_12_8_pos 0
1783#define reg_cge_idx13_12_8_len 5
1784#define reg_cge_idx13_12_8_lsb 8
1785#define xd_p_reg_cge_idx14_7_0 0xA29C
1786#define reg_cge_idx14_7_0_pos 0
1787#define reg_cge_idx14_7_0_len 8
1788#define reg_cge_idx14_7_0_lsb 0
1789#define xd_p_reg_cge_idx14_12_8 0xA29D
1790#define reg_cge_idx14_12_8_pos 0
1791#define reg_cge_idx14_12_8_len 5
1792#define reg_cge_idx14_12_8_lsb 8
1793#define xd_p_reg_cge_idx15_7_0 0xA29E
1794#define reg_cge_idx15_7_0_pos 0
1795#define reg_cge_idx15_7_0_len 8
1796#define reg_cge_idx15_7_0_lsb 0
1797#define xd_p_reg_cge_idx15_12_8 0xA29F
1798#define reg_cge_idx15_12_8_pos 0
1799#define reg_cge_idx15_12_8_len 5
1800#define reg_cge_idx15_12_8_lsb 8
1801#define xd_r_reg_fft_crc 0xA2A8
1802#define reg_fft_crc_pos 0
1803#define reg_fft_crc_len 8
1804#define reg_fft_crc_lsb 0
1805#define xd_p_fd_fft_shift_max 0xA2A9
1806#define fd_fft_shift_max_pos 0
1807#define fd_fft_shift_max_len 4
1808#define fd_fft_shift_max_lsb 0
1809#define xd_r_fd_fft_shift 0xA2A9
1810#define fd_fft_shift_pos 4
1811#define fd_fft_shift_len 4
1812#define fd_fft_shift_lsb 0
1813#define xd_r_fd_fft_frame_num 0xA2AA
1814#define fd_fft_frame_num_pos 0
1815#define fd_fft_frame_num_len 2
1816#define fd_fft_frame_num_lsb 0
1817#define xd_r_fd_fft_symbol_count 0xA2AB
1818#define fd_fft_symbol_count_pos 0
1819#define fd_fft_symbol_count_len 7
1820#define fd_fft_symbol_count_lsb 0
1821#define xd_r_reg_fft_idx_max_7_0 0xA2AC
1822#define reg_fft_idx_max_7_0_pos 0
1823#define reg_fft_idx_max_7_0_len 8
1824#define reg_fft_idx_max_7_0_lsb 0
1825#define xd_r_reg_fft_idx_max_12_8 0xA2AD
1826#define reg_fft_idx_max_12_8_pos 0
1827#define reg_fft_idx_max_12_8_len 5
1828#define reg_fft_idx_max_12_8_lsb 8
1829#define xd_p_reg_cge_program 0xA2AE
1830#define reg_cge_program_pos 0
1831#define reg_cge_program_len 1
1832#define reg_cge_program_lsb 0
1833#define xd_p_reg_cge_fixed 0xA2AE
1834#define reg_cge_fixed_pos 1
1835#define reg_cge_fixed_len 1
1836#define reg_cge_fixed_lsb 0
1837#define xd_p_reg_fft_rotate_en 0xA2AE
1838#define reg_fft_rotate_en_pos 2
1839#define reg_fft_rotate_en_len 1
1840#define reg_fft_rotate_en_lsb 0
1841#define xd_p_reg_fft_rotate_base_4_0 0xA2AE
1842#define reg_fft_rotate_base_4_0_pos 3
1843#define reg_fft_rotate_base_4_0_len 5
1844#define reg_fft_rotate_base_4_0_lsb 0
1845#define xd_p_reg_fft_rotate_base_12_5 0xA2AF
1846#define reg_fft_rotate_base_12_5_pos 0
1847#define reg_fft_rotate_base_12_5_len 8
1848#define reg_fft_rotate_base_12_5_lsb 5
1849#define xd_p_reg_gp_trigger_fd 0xA2B8
1850#define reg_gp_trigger_fd_pos 0
1851#define reg_gp_trigger_fd_len 1
1852#define reg_gp_trigger_fd_lsb 0
1853#define xd_p_reg_trigger_sel_fd 0xA2B8
1854#define reg_trigger_sel_fd_pos 1
1855#define reg_trigger_sel_fd_len 2
1856#define reg_trigger_sel_fd_lsb 0
1857#define xd_p_reg_trigger_module_sel_fd 0xA2B9
1858#define reg_trigger_module_sel_fd_pos 0
1859#define reg_trigger_module_sel_fd_len 6
1860#define reg_trigger_module_sel_fd_lsb 0
1861#define xd_p_reg_trigger_set_sel_fd 0xA2BA
1862#define reg_trigger_set_sel_fd_pos 0
1863#define reg_trigger_set_sel_fd_len 6
1864#define reg_trigger_set_sel_fd_lsb 0
1865#define xd_p_reg_fd_noname_7_0 0xA2BC
1866#define reg_fd_noname_7_0_pos 0
1867#define reg_fd_noname_7_0_len 8
1868#define reg_fd_noname_7_0_lsb 0
1869#define xd_p_reg_fd_noname_15_8 0xA2BD
1870#define reg_fd_noname_15_8_pos 0
1871#define reg_fd_noname_15_8_len 8
1872#define reg_fd_noname_15_8_lsb 8
1873#define xd_p_reg_fd_noname_23_16 0xA2BE
1874#define reg_fd_noname_23_16_pos 0
1875#define reg_fd_noname_23_16_len 8
1876#define reg_fd_noname_23_16_lsb 16
1877#define xd_p_reg_fd_noname_31_24 0xA2BF
1878#define reg_fd_noname_31_24_pos 0
1879#define reg_fd_noname_31_24_len 8
1880#define reg_fd_noname_31_24_lsb 24
1881#define xd_r_fd_fpcc_cp_corr_signn 0xA2C0
1882#define fd_fpcc_cp_corr_signn_pos 0
1883#define fd_fpcc_cp_corr_signn_len 8
1884#define fd_fpcc_cp_corr_signn_lsb 0
1885#define xd_p_reg_feq_s1 0xA2C1
1886#define reg_feq_s1_pos 0
1887#define reg_feq_s1_len 5
1888#define reg_feq_s1_lsb 0
1889#define xd_p_fd_fpcc_cp_corr_tone_th 0xA2C2
1890#define fd_fpcc_cp_corr_tone_th_pos 0
1891#define fd_fpcc_cp_corr_tone_th_len 6
1892#define fd_fpcc_cp_corr_tone_th_lsb 0
1893#define xd_p_fd_fpcc_cp_corr_symbol_log_th 0xA2C3
1894#define fd_fpcc_cp_corr_symbol_log_th_pos 0
1895#define fd_fpcc_cp_corr_symbol_log_th_len 4
1896#define fd_fpcc_cp_corr_symbol_log_th_lsb 0
1897#define xd_p_fd_fpcc_cp_corr_int 0xA2C4
1898#define fd_fpcc_cp_corr_int_pos 0
1899#define fd_fpcc_cp_corr_int_len 1
1900#define fd_fpcc_cp_corr_int_lsb 0
1901#define xd_p_reg_sfoe_ns_7_0 0xA320
1902#define reg_sfoe_ns_7_0_pos 0
1903#define reg_sfoe_ns_7_0_len 8
1904#define reg_sfoe_ns_7_0_lsb 0
1905#define xd_p_reg_sfoe_ns_14_8 0xA321
1906#define reg_sfoe_ns_14_8_pos 0
1907#define reg_sfoe_ns_14_8_len 7
1908#define reg_sfoe_ns_14_8_lsb 8
1909#define xd_p_reg_sfoe_c1_7_0 0xA322
1910#define reg_sfoe_c1_7_0_pos 0
1911#define reg_sfoe_c1_7_0_len 8
1912#define reg_sfoe_c1_7_0_lsb 0
1913#define xd_p_reg_sfoe_c1_15_8 0xA323
1914#define reg_sfoe_c1_15_8_pos 0
1915#define reg_sfoe_c1_15_8_len 8
1916#define reg_sfoe_c1_15_8_lsb 8
1917#define xd_p_reg_sfoe_c1_17_16 0xA324
1918#define reg_sfoe_c1_17_16_pos 0
1919#define reg_sfoe_c1_17_16_len 2
1920#define reg_sfoe_c1_17_16_lsb 16
1921#define xd_p_reg_sfoe_c2_7_0 0xA325
1922#define reg_sfoe_c2_7_0_pos 0
1923#define reg_sfoe_c2_7_0_len 8
1924#define reg_sfoe_c2_7_0_lsb 0
1925#define xd_p_reg_sfoe_c2_15_8 0xA326
1926#define reg_sfoe_c2_15_8_pos 0
1927#define reg_sfoe_c2_15_8_len 8
1928#define reg_sfoe_c2_15_8_lsb 8
1929#define xd_p_reg_sfoe_c2_17_16 0xA327
1930#define reg_sfoe_c2_17_16_pos 0
1931#define reg_sfoe_c2_17_16_len 2
1932#define reg_sfoe_c2_17_16_lsb 16
1933#define xd_r_reg_sfoe_out_9_2 0xA328
1934#define reg_sfoe_out_9_2_pos 0
1935#define reg_sfoe_out_9_2_len 8
1936#define reg_sfoe_out_9_2_lsb 0
1937#define xd_r_reg_sfoe_out_1_0 0xA329
1938#define reg_sfoe_out_1_0_pos 0
1939#define reg_sfoe_out_1_0_len 2
1940#define reg_sfoe_out_1_0_lsb 0
1941#define xd_p_reg_sfoe_lm_counter_th 0xA32A
1942#define reg_sfoe_lm_counter_th_pos 0
1943#define reg_sfoe_lm_counter_th_len 4
1944#define reg_sfoe_lm_counter_th_lsb 0
1945#define xd_p_reg_sfoe_convg_th 0xA32B
1946#define reg_sfoe_convg_th_pos 0
1947#define reg_sfoe_convg_th_len 8
1948#define reg_sfoe_convg_th_lsb 0
1949#define xd_p_reg_sfoe_divg_th 0xA32C
1950#define reg_sfoe_divg_th_pos 0
1951#define reg_sfoe_divg_th_len 8
1952#define reg_sfoe_divg_th_lsb 0
1953#define xd_p_fd_tpsd_en 0xA330
1954#define fd_tpsd_en_pos 0
1955#define fd_tpsd_en_len 1
1956#define fd_tpsd_en_lsb 0
1957#define xd_p_fd_tpsd_dis 0xA330
1958#define fd_tpsd_dis_pos 1
1959#define fd_tpsd_dis_len 1
1960#define fd_tpsd_dis_lsb 0
1961#define xd_p_fd_tpsd_rst 0xA330
1962#define fd_tpsd_rst_pos 2
1963#define fd_tpsd_rst_len 1
1964#define fd_tpsd_rst_lsb 0
1965#define xd_p_fd_tpsd_lock 0xA330
1966#define fd_tpsd_lock_pos 3
1967#define fd_tpsd_lock_len 1
1968#define fd_tpsd_lock_lsb 0
1969#define xd_r_fd_tpsd_s19 0xA330
1970#define fd_tpsd_s19_pos 4
1971#define fd_tpsd_s19_len 1
1972#define fd_tpsd_s19_lsb 0
1973#define xd_r_fd_tpsd_s17 0xA330
1974#define fd_tpsd_s17_pos 5
1975#define fd_tpsd_s17_len 1
1976#define fd_tpsd_s17_lsb 0
1977#define xd_p_fd_sfr_ste_en 0xA331
1978#define fd_sfr_ste_en_pos 0
1979#define fd_sfr_ste_en_len 1
1980#define fd_sfr_ste_en_lsb 0
1981#define xd_p_fd_sfr_ste_dis 0xA331
1982#define fd_sfr_ste_dis_pos 1
1983#define fd_sfr_ste_dis_len 1
1984#define fd_sfr_ste_dis_lsb 0
1985#define xd_p_fd_sfr_ste_rst 0xA331
1986#define fd_sfr_ste_rst_pos 2
1987#define fd_sfr_ste_rst_len 1
1988#define fd_sfr_ste_rst_lsb 0
1989#define xd_p_fd_sfr_ste_mode 0xA331
1990#define fd_sfr_ste_mode_pos 3
1991#define fd_sfr_ste_mode_len 1
1992#define fd_sfr_ste_mode_lsb 0
1993#define xd_p_fd_sfr_ste_done 0xA331
1994#define fd_sfr_ste_done_pos 4
1995#define fd_sfr_ste_done_len 1
1996#define fd_sfr_ste_done_lsb 0
1997#define xd_p_reg_cfoe_ffoe_en 0xA332
1998#define reg_cfoe_ffoe_en_pos 0
1999#define reg_cfoe_ffoe_en_len 1
2000#define reg_cfoe_ffoe_en_lsb 0
2001#define xd_p_reg_cfoe_ffoe_dis 0xA332
2002#define reg_cfoe_ffoe_dis_pos 1
2003#define reg_cfoe_ffoe_dis_len 1
2004#define reg_cfoe_ffoe_dis_lsb 0
2005#define xd_p_reg_cfoe_ffoe_rst 0xA332
2006#define reg_cfoe_ffoe_rst_pos 2
2007#define reg_cfoe_ffoe_rst_len 1
2008#define reg_cfoe_ffoe_rst_lsb 0
2009#define xd_p_reg_cfoe_ifoe_en 0xA332
2010#define reg_cfoe_ifoe_en_pos 3
2011#define reg_cfoe_ifoe_en_len 1
2012#define reg_cfoe_ifoe_en_lsb 0
2013#define xd_p_reg_cfoe_ifoe_dis 0xA332
2014#define reg_cfoe_ifoe_dis_pos 4
2015#define reg_cfoe_ifoe_dis_len 1
2016#define reg_cfoe_ifoe_dis_lsb 0
2017#define xd_p_reg_cfoe_ifoe_rst 0xA332
2018#define reg_cfoe_ifoe_rst_pos 5
2019#define reg_cfoe_ifoe_rst_len 1
2020#define reg_cfoe_ifoe_rst_lsb 0
2021#define xd_p_reg_cfoe_fot_en 0xA332
2022#define reg_cfoe_fot_en_pos 6
2023#define reg_cfoe_fot_en_len 1
2024#define reg_cfoe_fot_en_lsb 0
2025#define xd_p_reg_cfoe_fot_lm_en 0xA332
2026#define reg_cfoe_fot_lm_en_pos 7
2027#define reg_cfoe_fot_lm_en_len 1
2028#define reg_cfoe_fot_lm_en_lsb 0
2029#define xd_p_reg_cfoe_fot_rst 0xA333
2030#define reg_cfoe_fot_rst_pos 0
2031#define reg_cfoe_fot_rst_len 1
2032#define reg_cfoe_fot_rst_lsb 0
2033#define xd_r_fd_cfoe_ffoe_done 0xA333
2034#define fd_cfoe_ffoe_done_pos 1
2035#define fd_cfoe_ffoe_done_len 1
2036#define fd_cfoe_ffoe_done_lsb 0
2037#define xd_p_fd_cfoe_metric_vld 0xA333
2038#define fd_cfoe_metric_vld_pos 2
2039#define fd_cfoe_metric_vld_len 1
2040#define fd_cfoe_metric_vld_lsb 0
2041#define xd_p_reg_cfoe_ifod_vld 0xA333
2042#define reg_cfoe_ifod_vld_pos 3
2043#define reg_cfoe_ifod_vld_len 1
2044#define reg_cfoe_ifod_vld_lsb 0
2045#define xd_r_fd_cfoe_ifoe_done 0xA333
2046#define fd_cfoe_ifoe_done_pos 4
2047#define fd_cfoe_ifoe_done_len 1
2048#define fd_cfoe_ifoe_done_lsb 0
2049#define xd_r_fd_cfoe_fot_valid 0xA333
2050#define fd_cfoe_fot_valid_pos 5
2051#define fd_cfoe_fot_valid_len 1
2052#define fd_cfoe_fot_valid_lsb 0
2053#define xd_p_reg_cfoe_divg_int 0xA333
2054#define reg_cfoe_divg_int_pos 6
2055#define reg_cfoe_divg_int_len 1
2056#define reg_cfoe_divg_int_lsb 0
2057#define xd_r_reg_cfoe_divg_flag 0xA333
2058#define reg_cfoe_divg_flag_pos 7
2059#define reg_cfoe_divg_flag_len 1
2060#define reg_cfoe_divg_flag_lsb 0
2061#define xd_p_reg_sfoe_en 0xA334
2062#define reg_sfoe_en_pos 0
2063#define reg_sfoe_en_len 1
2064#define reg_sfoe_en_lsb 0
2065#define xd_p_reg_sfoe_dis 0xA334
2066#define reg_sfoe_dis_pos 1
2067#define reg_sfoe_dis_len 1
2068#define reg_sfoe_dis_lsb 0
2069#define xd_p_reg_sfoe_rst 0xA334
2070#define reg_sfoe_rst_pos 2
2071#define reg_sfoe_rst_len 1
2072#define reg_sfoe_rst_lsb 0
2073#define xd_p_reg_sfoe_vld_int 0xA334
2074#define reg_sfoe_vld_int_pos 3
2075#define reg_sfoe_vld_int_len 1
2076#define reg_sfoe_vld_int_lsb 0
2077#define xd_p_reg_sfoe_lm_en 0xA334
2078#define reg_sfoe_lm_en_pos 4
2079#define reg_sfoe_lm_en_len 1
2080#define reg_sfoe_lm_en_lsb 0
2081#define xd_p_reg_sfoe_divg_int 0xA334
2082#define reg_sfoe_divg_int_pos 5
2083#define reg_sfoe_divg_int_len 1
2084#define reg_sfoe_divg_int_lsb 0
2085#define xd_r_reg_sfoe_divg_flag 0xA334
2086#define reg_sfoe_divg_flag_pos 6
2087#define reg_sfoe_divg_flag_len 1
2088#define reg_sfoe_divg_flag_lsb 0
2089#define xd_p_reg_fft_rst 0xA335
2090#define reg_fft_rst_pos 0
2091#define reg_fft_rst_len 1
2092#define reg_fft_rst_lsb 0
2093#define xd_p_reg_fft_fast_beacon 0xA335
2094#define reg_fft_fast_beacon_pos 1
2095#define reg_fft_fast_beacon_len 1
2096#define reg_fft_fast_beacon_lsb 0
2097#define xd_p_reg_fft_fast_valid 0xA335
2098#define reg_fft_fast_valid_pos 2
2099#define reg_fft_fast_valid_len 1
2100#define reg_fft_fast_valid_lsb 0
2101#define xd_p_reg_fft_mask_en 0xA335
2102#define reg_fft_mask_en_pos 3
2103#define reg_fft_mask_en_len 1
2104#define reg_fft_mask_en_lsb 0
2105#define xd_p_reg_fft_crc_en 0xA335
2106#define reg_fft_crc_en_pos 4
2107#define reg_fft_crc_en_len 1
2108#define reg_fft_crc_en_lsb 0
2109#define xd_p_reg_finr_en 0xA336
2110#define reg_finr_en_pos 0
2111#define reg_finr_en_len 1
2112#define reg_finr_en_lsb 0
2113#define xd_p_fd_fste_en 0xA337
2114#define fd_fste_en_pos 1
2115#define fd_fste_en_len 1
2116#define fd_fste_en_lsb 0
2117#define xd_p_fd_sqi_tps_level_shift 0xA338
2118#define fd_sqi_tps_level_shift_pos 0
2119#define fd_sqi_tps_level_shift_len 8
2120#define fd_sqi_tps_level_shift_lsb 0
2121#define xd_p_fd_pilot_ma_len 0xA339
2122#define fd_pilot_ma_len_pos 0
2123#define fd_pilot_ma_len_len 6
2124#define fd_pilot_ma_len_lsb 0
2125#define xd_p_fd_tps_ma_len 0xA33A
2126#define fd_tps_ma_len_pos 0
2127#define fd_tps_ma_len_len 6
2128#define fd_tps_ma_len_lsb 0
2129#define xd_p_fd_sqi_s3 0xA33B
2130#define fd_sqi_s3_pos 0
2131#define fd_sqi_s3_len 8
2132#define fd_sqi_s3_lsb 0
2133#define xd_p_fd_sqi_dummy_reg_0 0xA33C
2134#define fd_sqi_dummy_reg_0_pos 0
2135#define fd_sqi_dummy_reg_0_len 1
2136#define fd_sqi_dummy_reg_0_lsb 0
2137#define xd_p_fd_sqi_debug_sel 0xA33C
2138#define fd_sqi_debug_sel_pos 1
2139#define fd_sqi_debug_sel_len 2
2140#define fd_sqi_debug_sel_lsb 0
2141#define xd_p_fd_sqi_s2 0xA33C
2142#define fd_sqi_s2_pos 3
2143#define fd_sqi_s2_len 5
2144#define fd_sqi_s2_lsb 0
2145#define xd_p_fd_sqi_dummy_reg_1 0xA33D
2146#define fd_sqi_dummy_reg_1_pos 0
2147#define fd_sqi_dummy_reg_1_len 1
2148#define fd_sqi_dummy_reg_1_lsb 0
2149#define xd_p_fd_inr_ignore 0xA33D
2150#define fd_inr_ignore_pos 1
2151#define fd_inr_ignore_len 1
2152#define fd_inr_ignore_lsb 0
2153#define xd_p_fd_pilot_ignore 0xA33D
2154#define fd_pilot_ignore_pos 2
2155#define fd_pilot_ignore_len 1
2156#define fd_pilot_ignore_lsb 0
2157#define xd_p_fd_etps_ignore 0xA33D
2158#define fd_etps_ignore_pos 3
2159#define fd_etps_ignore_len 1
2160#define fd_etps_ignore_lsb 0
2161#define xd_p_fd_sqi_s1 0xA33D
2162#define fd_sqi_s1_pos 4
2163#define fd_sqi_s1_len 4
2164#define fd_sqi_s1_lsb 0
2165#define xd_p_reg_fste_ehw_7_0 0xA33E
2166#define reg_fste_ehw_7_0_pos 0
2167#define reg_fste_ehw_7_0_len 8
2168#define reg_fste_ehw_7_0_lsb 0
2169#define xd_p_reg_fste_ehw_9_8 0xA33F
2170#define reg_fste_ehw_9_8_pos 0
2171#define reg_fste_ehw_9_8_len 2
2172#define reg_fste_ehw_9_8_lsb 8
2173#define xd_p_reg_fste_i_adj_vld 0xA33F
2174#define reg_fste_i_adj_vld_pos 2
2175#define reg_fste_i_adj_vld_len 1
2176#define reg_fste_i_adj_vld_lsb 0
2177#define xd_p_reg_fste_phase_ini_7_0 0xA340
2178#define reg_fste_phase_ini_7_0_pos 0
2179#define reg_fste_phase_ini_7_0_len 8
2180#define reg_fste_phase_ini_7_0_lsb 0
2181#define xd_p_reg_fste_phase_ini_11_8 0xA341
2182#define reg_fste_phase_ini_11_8_pos 0
2183#define reg_fste_phase_ini_11_8_len 4
2184#define reg_fste_phase_ini_11_8_lsb 8
2185#define xd_p_reg_fste_phase_inc_3_0 0xA341
2186#define reg_fste_phase_inc_3_0_pos 4
2187#define reg_fste_phase_inc_3_0_len 4
2188#define reg_fste_phase_inc_3_0_lsb 0
2189#define xd_p_reg_fste_phase_inc_11_4 0xA342
2190#define reg_fste_phase_inc_11_4_pos 0
2191#define reg_fste_phase_inc_11_4_len 8
2192#define reg_fste_phase_inc_11_4_lsb 4
2193#define xd_p_reg_fste_acum_cost_cnt_max 0xA343
2194#define reg_fste_acum_cost_cnt_max_pos 0
2195#define reg_fste_acum_cost_cnt_max_len 4
2196#define reg_fste_acum_cost_cnt_max_lsb 0
2197#define xd_p_reg_fste_step_size_std 0xA343
2198#define reg_fste_step_size_std_pos 4
2199#define reg_fste_step_size_std_len 4
2200#define reg_fste_step_size_std_lsb 0
2201#define xd_p_reg_fste_step_size_max 0xA344
2202#define reg_fste_step_size_max_pos 0
2203#define reg_fste_step_size_max_len 4
2204#define reg_fste_step_size_max_lsb 0
2205#define xd_p_reg_fste_step_size_min 0xA344
2206#define reg_fste_step_size_min_pos 4
2207#define reg_fste_step_size_min_len 4
2208#define reg_fste_step_size_min_lsb 0
2209#define xd_p_reg_fste_frac_step_size_7_0 0xA345
2210#define reg_fste_frac_step_size_7_0_pos 0
2211#define reg_fste_frac_step_size_7_0_len 8
2212#define reg_fste_frac_step_size_7_0_lsb 0
2213#define xd_p_reg_fste_frac_step_size_15_8 0xA346
2214#define reg_fste_frac_step_size_15_8_pos 0
2215#define reg_fste_frac_step_size_15_8_len 8
2216#define reg_fste_frac_step_size_15_8_lsb 8
2217#define xd_p_reg_fste_frac_step_size_19_16 0xA347
2218#define reg_fste_frac_step_size_19_16_pos 0
2219#define reg_fste_frac_step_size_19_16_len 4
2220#define reg_fste_frac_step_size_19_16_lsb 16
2221#define xd_p_reg_fste_rpd_dir_cnt_max 0xA347
2222#define reg_fste_rpd_dir_cnt_max_pos 4
2223#define reg_fste_rpd_dir_cnt_max_len 4
2224#define reg_fste_rpd_dir_cnt_max_lsb 0
2225#define xd_p_reg_fste_ehs 0xA348
2226#define reg_fste_ehs_pos 0
2227#define reg_fste_ehs_len 4
2228#define reg_fste_ehs_lsb 0
2229#define xd_p_reg_fste_frac_cost_cnt_max_3_0 0xA348
2230#define reg_fste_frac_cost_cnt_max_3_0_pos 4
2231#define reg_fste_frac_cost_cnt_max_3_0_len 4
2232#define reg_fste_frac_cost_cnt_max_3_0_lsb 0
2233#define xd_p_reg_fste_frac_cost_cnt_max_9_4 0xA349
2234#define reg_fste_frac_cost_cnt_max_9_4_pos 0
2235#define reg_fste_frac_cost_cnt_max_9_4_len 6
2236#define reg_fste_frac_cost_cnt_max_9_4_lsb 4
2237#define xd_p_reg_fste_w0_7_0 0xA34A
2238#define reg_fste_w0_7_0_pos 0
2239#define reg_fste_w0_7_0_len 8
2240#define reg_fste_w0_7_0_lsb 0
2241#define xd_p_reg_fste_w0_11_8 0xA34B
2242#define reg_fste_w0_11_8_pos 0
2243#define reg_fste_w0_11_8_len 4
2244#define reg_fste_w0_11_8_lsb 8
2245#define xd_p_reg_fste_w1_3_0 0xA34B
2246#define reg_fste_w1_3_0_pos 4
2247#define reg_fste_w1_3_0_len 4
2248#define reg_fste_w1_3_0_lsb 0
2249#define xd_p_reg_fste_w1_11_4 0xA34C
2250#define reg_fste_w1_11_4_pos 0
2251#define reg_fste_w1_11_4_len 8
2252#define reg_fste_w1_11_4_lsb 4
2253#define xd_p_reg_fste_w2_7_0 0xA34D
2254#define reg_fste_w2_7_0_pos 0
2255#define reg_fste_w2_7_0_len 8
2256#define reg_fste_w2_7_0_lsb 0
2257#define xd_p_reg_fste_w2_11_8 0xA34E
2258#define reg_fste_w2_11_8_pos 0
2259#define reg_fste_w2_11_8_len 4
2260#define reg_fste_w2_11_8_lsb 8
2261#define xd_p_reg_fste_w3_3_0 0xA34E
2262#define reg_fste_w3_3_0_pos 4
2263#define reg_fste_w3_3_0_len 4
2264#define reg_fste_w3_3_0_lsb 0
2265#define xd_p_reg_fste_w3_11_4 0xA34F
2266#define reg_fste_w3_11_4_pos 0
2267#define reg_fste_w3_11_4_len 8
2268#define reg_fste_w3_11_4_lsb 4
2269#define xd_p_reg_fste_w4_7_0 0xA350
2270#define reg_fste_w4_7_0_pos 0
2271#define reg_fste_w4_7_0_len 8
2272#define reg_fste_w4_7_0_lsb 0
2273#define xd_p_reg_fste_w4_11_8 0xA351
2274#define reg_fste_w4_11_8_pos 0
2275#define reg_fste_w4_11_8_len 4
2276#define reg_fste_w4_11_8_lsb 8
2277#define xd_p_reg_fste_w5_3_0 0xA351
2278#define reg_fste_w5_3_0_pos 4
2279#define reg_fste_w5_3_0_len 4
2280#define reg_fste_w5_3_0_lsb 0
2281#define xd_p_reg_fste_w5_11_4 0xA352
2282#define reg_fste_w5_11_4_pos 0
2283#define reg_fste_w5_11_4_len 8
2284#define reg_fste_w5_11_4_lsb 4
2285#define xd_p_reg_fste_w6_7_0 0xA353
2286#define reg_fste_w6_7_0_pos 0
2287#define reg_fste_w6_7_0_len 8
2288#define reg_fste_w6_7_0_lsb 0
2289#define xd_p_reg_fste_w6_11_8 0xA354
2290#define reg_fste_w6_11_8_pos 0
2291#define reg_fste_w6_11_8_len 4
2292#define reg_fste_w6_11_8_lsb 8
2293#define xd_p_reg_fste_w7_3_0 0xA354
2294#define reg_fste_w7_3_0_pos 4
2295#define reg_fste_w7_3_0_len 4
2296#define reg_fste_w7_3_0_lsb 0
2297#define xd_p_reg_fste_w7_11_4 0xA355
2298#define reg_fste_w7_11_4_pos 0
2299#define reg_fste_w7_11_4_len 8
2300#define reg_fste_w7_11_4_lsb 4
2301#define xd_p_reg_fste_w8_7_0 0xA356
2302#define reg_fste_w8_7_0_pos 0
2303#define reg_fste_w8_7_0_len 8
2304#define reg_fste_w8_7_0_lsb 0
2305#define xd_p_reg_fste_w8_11_8 0xA357
2306#define reg_fste_w8_11_8_pos 0
2307#define reg_fste_w8_11_8_len 4
2308#define reg_fste_w8_11_8_lsb 8
2309#define xd_p_reg_fste_w9_3_0 0xA357
2310#define reg_fste_w9_3_0_pos 4
2311#define reg_fste_w9_3_0_len 4
2312#define reg_fste_w9_3_0_lsb 0
2313#define xd_p_reg_fste_w9_11_4 0xA358
2314#define reg_fste_w9_11_4_pos 0
2315#define reg_fste_w9_11_4_len 8
2316#define reg_fste_w9_11_4_lsb 4
2317#define xd_p_reg_fste_wa_7_0 0xA359
2318#define reg_fste_wa_7_0_pos 0
2319#define reg_fste_wa_7_0_len 8
2320#define reg_fste_wa_7_0_lsb 0
2321#define xd_p_reg_fste_wa_11_8 0xA35A
2322#define reg_fste_wa_11_8_pos 0
2323#define reg_fste_wa_11_8_len 4
2324#define reg_fste_wa_11_8_lsb 8
2325#define xd_p_reg_fste_wb_3_0 0xA35A
2326#define reg_fste_wb_3_0_pos 4
2327#define reg_fste_wb_3_0_len 4
2328#define reg_fste_wb_3_0_lsb 0
2329#define xd_p_reg_fste_wb_11_4 0xA35B
2330#define reg_fste_wb_11_4_pos 0
2331#define reg_fste_wb_11_4_len 8
2332#define reg_fste_wb_11_4_lsb 4
2333#define xd_r_fd_fste_i_adj 0xA35C
2334#define fd_fste_i_adj_pos 0
2335#define fd_fste_i_adj_len 5
2336#define fd_fste_i_adj_lsb 0
2337#define xd_r_fd_fste_f_adj_7_0 0xA35D
2338#define fd_fste_f_adj_7_0_pos 0
2339#define fd_fste_f_adj_7_0_len 8
2340#define fd_fste_f_adj_7_0_lsb 0
2341#define xd_r_fd_fste_f_adj_15_8 0xA35E
2342#define fd_fste_f_adj_15_8_pos 0
2343#define fd_fste_f_adj_15_8_len 8
2344#define fd_fste_f_adj_15_8_lsb 8
2345#define xd_r_fd_fste_f_adj_19_16 0xA35F
2346#define fd_fste_f_adj_19_16_pos 0
2347#define fd_fste_f_adj_19_16_len 4
2348#define fd_fste_f_adj_19_16_lsb 16
2349#define xd_p_reg_feq_Leak_Bypass 0xA366
2350#define reg_feq_Leak_Bypass_pos 0
2351#define reg_feq_Leak_Bypass_len 1
2352#define reg_feq_Leak_Bypass_lsb 0
2353#define xd_p_reg_feq_Leak_Mneg1 0xA366
2354#define reg_feq_Leak_Mneg1_pos 1
2355#define reg_feq_Leak_Mneg1_len 3
2356#define reg_feq_Leak_Mneg1_lsb 0
2357#define xd_p_reg_feq_Leak_B_ShiftQ 0xA366
2358#define reg_feq_Leak_B_ShiftQ_pos 4
2359#define reg_feq_Leak_B_ShiftQ_len 4
2360#define reg_feq_Leak_B_ShiftQ_lsb 0
2361#define xd_p_reg_feq_Leak_B_Float0 0xA367
2362#define reg_feq_Leak_B_Float0_pos 0
2363#define reg_feq_Leak_B_Float0_len 8
2364#define reg_feq_Leak_B_Float0_lsb 0
2365#define xd_p_reg_feq_Leak_B_Float1 0xA368
2366#define reg_feq_Leak_B_Float1_pos 0
2367#define reg_feq_Leak_B_Float1_len 8
2368#define reg_feq_Leak_B_Float1_lsb 0
2369#define xd_p_reg_feq_Leak_B_Float2 0xA369
2370#define reg_feq_Leak_B_Float2_pos 0
2371#define reg_feq_Leak_B_Float2_len 8
2372#define reg_feq_Leak_B_Float2_lsb 0
2373#define xd_p_reg_feq_Leak_B_Float3 0xA36A
2374#define reg_feq_Leak_B_Float3_pos 0
2375#define reg_feq_Leak_B_Float3_len 8
2376#define reg_feq_Leak_B_Float3_lsb 0
2377#define xd_p_reg_feq_Leak_B_Float4 0xA36B
2378#define reg_feq_Leak_B_Float4_pos 0
2379#define reg_feq_Leak_B_Float4_len 8
2380#define reg_feq_Leak_B_Float4_lsb 0
2381#define xd_p_reg_feq_Leak_B_Float5 0xA36C
2382#define reg_feq_Leak_B_Float5_pos 0
2383#define reg_feq_Leak_B_Float5_len 8
2384#define reg_feq_Leak_B_Float5_lsb 0
2385#define xd_p_reg_feq_Leak_B_Float6 0xA36D
2386#define reg_feq_Leak_B_Float6_pos 0
2387#define reg_feq_Leak_B_Float6_len 8
2388#define reg_feq_Leak_B_Float6_lsb 0
2389#define xd_p_reg_feq_Leak_B_Float7 0xA36E
2390#define reg_feq_Leak_B_Float7_pos 0
2391#define reg_feq_Leak_B_Float7_len 8
2392#define reg_feq_Leak_B_Float7_lsb 0
2393#define xd_r_reg_feq_data_h2_7_0 0xA36F
2394#define reg_feq_data_h2_7_0_pos 0
2395#define reg_feq_data_h2_7_0_len 8
2396#define reg_feq_data_h2_7_0_lsb 0
2397#define xd_r_reg_feq_data_h2_9_8 0xA370
2398#define reg_feq_data_h2_9_8_pos 0
2399#define reg_feq_data_h2_9_8_len 2
2400#define reg_feq_data_h2_9_8_lsb 8
2401#define xd_p_reg_feq_leak_use_slice_tps 0xA371
2402#define reg_feq_leak_use_slice_tps_pos 0
2403#define reg_feq_leak_use_slice_tps_len 1
2404#define reg_feq_leak_use_slice_tps_lsb 0
2405#define xd_p_reg_feq_read_update 0xA371
2406#define reg_feq_read_update_pos 1
2407#define reg_feq_read_update_len 1
2408#define reg_feq_read_update_lsb 0
2409#define xd_p_reg_feq_data_vld 0xA371
2410#define reg_feq_data_vld_pos 2
2411#define reg_feq_data_vld_len 1
2412#define reg_feq_data_vld_lsb 0
2413#define xd_p_reg_feq_tone_idx_4_0 0xA371
2414#define reg_feq_tone_idx_4_0_pos 3
2415#define reg_feq_tone_idx_4_0_len 5
2416#define reg_feq_tone_idx_4_0_lsb 0
2417#define xd_p_reg_feq_tone_idx_12_5 0xA372
2418#define reg_feq_tone_idx_12_5_pos 0
2419#define reg_feq_tone_idx_12_5_len 8
2420#define reg_feq_tone_idx_12_5_lsb 5
2421#define xd_r_reg_feq_data_re_7_0 0xA373
2422#define reg_feq_data_re_7_0_pos 0
2423#define reg_feq_data_re_7_0_len 8
2424#define reg_feq_data_re_7_0_lsb 0
2425#define xd_r_reg_feq_data_re_10_8 0xA374
2426#define reg_feq_data_re_10_8_pos 0
2427#define reg_feq_data_re_10_8_len 3
2428#define reg_feq_data_re_10_8_lsb 8
2429#define xd_r_reg_feq_data_im_7_0 0xA375
2430#define reg_feq_data_im_7_0_pos 0
2431#define reg_feq_data_im_7_0_len 8
2432#define reg_feq_data_im_7_0_lsb 0
2433#define xd_r_reg_feq_data_im_10_8 0xA376
2434#define reg_feq_data_im_10_8_pos 0
2435#define reg_feq_data_im_10_8_len 3
2436#define reg_feq_data_im_10_8_lsb 8
2437#define xd_r_reg_feq_y_re 0xA377
2438#define reg_feq_y_re_pos 0
2439#define reg_feq_y_re_len 8
2440#define reg_feq_y_re_lsb 0
2441#define xd_r_reg_feq_y_im 0xA378
2442#define reg_feq_y_im_pos 0
2443#define reg_feq_y_im_len 8
2444#define reg_feq_y_im_lsb 0
2445#define xd_r_reg_feq_h_re_7_0 0xA379
2446#define reg_feq_h_re_7_0_pos 0
2447#define reg_feq_h_re_7_0_len 8
2448#define reg_feq_h_re_7_0_lsb 0
2449#define xd_r_reg_feq_h_re_8 0xA37A
2450#define reg_feq_h_re_8_pos 0
2451#define reg_feq_h_re_8_len 1
2452#define reg_feq_h_re_8_lsb 0
2453#define xd_r_reg_feq_h_im_7_0 0xA37B
2454#define reg_feq_h_im_7_0_pos 0
2455#define reg_feq_h_im_7_0_len 8
2456#define reg_feq_h_im_7_0_lsb 0
2457#define xd_r_reg_feq_h_im_8 0xA37C
2458#define reg_feq_h_im_8_pos 0
2459#define reg_feq_h_im_8_len 1
2460#define reg_feq_h_im_8_lsb 0
2461#define xd_p_fec_super_frm_unit_7_0 0xA380
2462#define fec_super_frm_unit_7_0_pos 0
2463#define fec_super_frm_unit_7_0_len 8
2464#define fec_super_frm_unit_7_0_lsb 0
2465#define xd_p_fec_super_frm_unit_15_8 0xA381
2466#define fec_super_frm_unit_15_8_pos 0
2467#define fec_super_frm_unit_15_8_len 8
2468#define fec_super_frm_unit_15_8_lsb 8
2469#define xd_r_fec_vtb_err_bit_cnt_7_0 0xA382
2470#define fec_vtb_err_bit_cnt_7_0_pos 0
2471#define fec_vtb_err_bit_cnt_7_0_len 8
2472#define fec_vtb_err_bit_cnt_7_0_lsb 0
2473#define xd_r_fec_vtb_err_bit_cnt_15_8 0xA383
2474#define fec_vtb_err_bit_cnt_15_8_pos 0
2475#define fec_vtb_err_bit_cnt_15_8_len 8
2476#define fec_vtb_err_bit_cnt_15_8_lsb 8
2477#define xd_r_fec_vtb_err_bit_cnt_23_16 0xA384
2478#define fec_vtb_err_bit_cnt_23_16_pos 0
2479#define fec_vtb_err_bit_cnt_23_16_len 8
2480#define fec_vtb_err_bit_cnt_23_16_lsb 16
2481#define xd_p_fec_rsd_packet_unit_7_0 0xA385
2482#define fec_rsd_packet_unit_7_0_pos 0
2483#define fec_rsd_packet_unit_7_0_len 8
2484#define fec_rsd_packet_unit_7_0_lsb 0
2485#define xd_p_fec_rsd_packet_unit_15_8 0xA386
2486#define fec_rsd_packet_unit_15_8_pos 0
2487#define fec_rsd_packet_unit_15_8_len 8
2488#define fec_rsd_packet_unit_15_8_lsb 8
2489#define xd_r_fec_rsd_bit_err_cnt_7_0 0xA387
2490#define fec_rsd_bit_err_cnt_7_0_pos 0
2491#define fec_rsd_bit_err_cnt_7_0_len 8
2492#define fec_rsd_bit_err_cnt_7_0_lsb 0
2493#define xd_r_fec_rsd_bit_err_cnt_15_8 0xA388
2494#define fec_rsd_bit_err_cnt_15_8_pos 0
2495#define fec_rsd_bit_err_cnt_15_8_len 8
2496#define fec_rsd_bit_err_cnt_15_8_lsb 8
2497#define xd_r_fec_rsd_bit_err_cnt_23_16 0xA389
2498#define fec_rsd_bit_err_cnt_23_16_pos 0
2499#define fec_rsd_bit_err_cnt_23_16_len 8
2500#define fec_rsd_bit_err_cnt_23_16_lsb 16
2501#define xd_r_fec_rsd_abort_packet_cnt_7_0 0xA38A
2502#define fec_rsd_abort_packet_cnt_7_0_pos 0
2503#define fec_rsd_abort_packet_cnt_7_0_len 8
2504#define fec_rsd_abort_packet_cnt_7_0_lsb 0
2505#define xd_r_fec_rsd_abort_packet_cnt_15_8 0xA38B
2506#define fec_rsd_abort_packet_cnt_15_8_pos 0
2507#define fec_rsd_abort_packet_cnt_15_8_len 8
2508#define fec_rsd_abort_packet_cnt_15_8_lsb 8
2509#define xd_p_fec_RSD_PKT_NUM_PER_UNIT_7_0 0xA38C
2510#define fec_RSD_PKT_NUM_PER_UNIT_7_0_pos 0
2511#define fec_RSD_PKT_NUM_PER_UNIT_7_0_len 8
2512#define fec_RSD_PKT_NUM_PER_UNIT_7_0_lsb 0
2513#define xd_p_fec_RSD_PKT_NUM_PER_UNIT_15_8 0xA38D
2514#define fec_RSD_PKT_NUM_PER_UNIT_15_8_pos 0
2515#define fec_RSD_PKT_NUM_PER_UNIT_15_8_len 8
2516#define fec_RSD_PKT_NUM_PER_UNIT_15_8_lsb 8
2517#define xd_p_fec_RS_TH_1_7_0 0xA38E
2518#define fec_RS_TH_1_7_0_pos 0
2519#define fec_RS_TH_1_7_0_len 8
2520#define fec_RS_TH_1_7_0_lsb 0
2521#define xd_p_fec_RS_TH_1_15_8 0xA38F
2522#define fec_RS_TH_1_15_8_pos 0
2523#define fec_RS_TH_1_15_8_len 8
2524#define fec_RS_TH_1_15_8_lsb 8
2525#define xd_p_fec_RS_TH_2 0xA390
2526#define fec_RS_TH_2_pos 0
2527#define fec_RS_TH_2_len 8
2528#define fec_RS_TH_2_lsb 0
2529#define xd_p_fec_mon_en 0xA391
2530#define fec_mon_en_pos 0
2531#define fec_mon_en_len 1
2532#define fec_mon_en_lsb 0
2533#define xd_p_reg_b8to47 0xA391
2534#define reg_b8to47_pos 1
2535#define reg_b8to47_len 1
2536#define reg_b8to47_lsb 0
2537#define xd_p_reg_rsd_sync_rep 0xA391
2538#define reg_rsd_sync_rep_pos 2
2539#define reg_rsd_sync_rep_len 1
2540#define reg_rsd_sync_rep_lsb 0
2541#define xd_p_fec_rsd_retrain_rst 0xA391
2542#define fec_rsd_retrain_rst_pos 3
2543#define fec_rsd_retrain_rst_len 1
2544#define fec_rsd_retrain_rst_lsb 0
2545#define xd_r_fec_rsd_ber_rdy 0xA391
2546#define fec_rsd_ber_rdy_pos 4
2547#define fec_rsd_ber_rdy_len 1
2548#define fec_rsd_ber_rdy_lsb 0
2549#define xd_p_fec_rsd_ber_rst 0xA391
2550#define fec_rsd_ber_rst_pos 5
2551#define fec_rsd_ber_rst_len 1
2552#define fec_rsd_ber_rst_lsb 0
2553#define xd_r_fec_vtb_ber_rdy 0xA391
2554#define fec_vtb_ber_rdy_pos 6
2555#define fec_vtb_ber_rdy_len 1
2556#define fec_vtb_ber_rdy_lsb 0
2557#define xd_p_fec_vtb_ber_rst 0xA391
2558#define fec_vtb_ber_rst_pos 7
2559#define fec_vtb_ber_rst_len 1
2560#define fec_vtb_ber_rst_lsb 0
2561#define xd_p_reg_vtb_clk40en 0xA392
2562#define reg_vtb_clk40en_pos 0
2563#define reg_vtb_clk40en_len 1
2564#define reg_vtb_clk40en_lsb 0
2565#define xd_p_fec_vtb_rsd_mon_en 0xA392
2566#define fec_vtb_rsd_mon_en_pos 1
2567#define fec_vtb_rsd_mon_en_len 1
2568#define fec_vtb_rsd_mon_en_lsb 0
2569#define xd_p_reg_fec_data_en 0xA392
2570#define reg_fec_data_en_pos 2
2571#define reg_fec_data_en_len 1
2572#define reg_fec_data_en_lsb 0
2573#define xd_p_fec_dummy_reg_2 0xA392
2574#define fec_dummy_reg_2_pos 3
2575#define fec_dummy_reg_2_len 3
2576#define fec_dummy_reg_2_lsb 0
2577#define xd_p_reg_sync_chk 0xA392
2578#define reg_sync_chk_pos 6
2579#define reg_sync_chk_len 1
2580#define reg_sync_chk_lsb 0
2581#define xd_p_fec_rsd_bypass 0xA392
2582#define fec_rsd_bypass_pos 7
2583#define fec_rsd_bypass_len 1
2584#define fec_rsd_bypass_lsb 0
2585#define xd_p_fec_sw_rst 0xA393
2586#define fec_sw_rst_pos 0
2587#define fec_sw_rst_len 1
2588#define fec_sw_rst_lsb 0
2589#define xd_r_fec_vtb_pm_crc 0xA394
2590#define fec_vtb_pm_crc_pos 0
2591#define fec_vtb_pm_crc_len 8
2592#define fec_vtb_pm_crc_lsb 0
2593#define xd_r_fec_vtb_tb_7_crc 0xA395
2594#define fec_vtb_tb_7_crc_pos 0
2595#define fec_vtb_tb_7_crc_len 8
2596#define fec_vtb_tb_7_crc_lsb 0
2597#define xd_r_fec_vtb_tb_6_crc 0xA396
2598#define fec_vtb_tb_6_crc_pos 0
2599#define fec_vtb_tb_6_crc_len 8
2600#define fec_vtb_tb_6_crc_lsb 0
2601#define xd_r_fec_vtb_tb_5_crc 0xA397
2602#define fec_vtb_tb_5_crc_pos 0
2603#define fec_vtb_tb_5_crc_len 8
2604#define fec_vtb_tb_5_crc_lsb 0
2605#define xd_r_fec_vtb_tb_4_crc 0xA398
2606#define fec_vtb_tb_4_crc_pos 0
2607#define fec_vtb_tb_4_crc_len 8
2608#define fec_vtb_tb_4_crc_lsb 0
2609#define xd_r_fec_vtb_tb_3_crc 0xA399
2610#define fec_vtb_tb_3_crc_pos 0
2611#define fec_vtb_tb_3_crc_len 8
2612#define fec_vtb_tb_3_crc_lsb 0
2613#define xd_r_fec_vtb_tb_2_crc 0xA39A
2614#define fec_vtb_tb_2_crc_pos 0
2615#define fec_vtb_tb_2_crc_len 8
2616#define fec_vtb_tb_2_crc_lsb 0
2617#define xd_r_fec_vtb_tb_1_crc 0xA39B
2618#define fec_vtb_tb_1_crc_pos 0
2619#define fec_vtb_tb_1_crc_len 8
2620#define fec_vtb_tb_1_crc_lsb 0
2621#define xd_r_fec_vtb_tb_0_crc 0xA39C
2622#define fec_vtb_tb_0_crc_pos 0
2623#define fec_vtb_tb_0_crc_len 8
2624#define fec_vtb_tb_0_crc_lsb 0
2625#define xd_r_fec_rsd_bank0_crc 0xA39D
2626#define fec_rsd_bank0_crc_pos 0
2627#define fec_rsd_bank0_crc_len 8
2628#define fec_rsd_bank0_crc_lsb 0
2629#define xd_r_fec_rsd_bank1_crc 0xA39E
2630#define fec_rsd_bank1_crc_pos 0
2631#define fec_rsd_bank1_crc_len 8
2632#define fec_rsd_bank1_crc_lsb 0
2633#define xd_r_fec_idi_vtb_crc 0xA39F
2634#define fec_idi_vtb_crc_pos 0
2635#define fec_idi_vtb_crc_len 8
2636#define fec_idi_vtb_crc_lsb 0
2637#define xd_g_reg_tpsd_txmod 0xA3C0
2638#define reg_tpsd_txmod_pos 0
2639#define reg_tpsd_txmod_len 2
2640#define reg_tpsd_txmod_lsb 0
2641#define xd_g_reg_tpsd_gi 0xA3C0
2642#define reg_tpsd_gi_pos 2
2643#define reg_tpsd_gi_len 2
2644#define reg_tpsd_gi_lsb 0
2645#define xd_g_reg_tpsd_hier 0xA3C0
2646#define reg_tpsd_hier_pos 4
2647#define reg_tpsd_hier_len 3
2648#define reg_tpsd_hier_lsb 0
2649#define xd_g_reg_bw 0xA3C1
2650#define reg_bw_pos 2
2651#define reg_bw_len 2
2652#define reg_bw_lsb 0
2653#define xd_g_reg_dec_pri 0xA3C1
2654#define reg_dec_pri_pos 4
2655#define reg_dec_pri_len 1
2656#define reg_dec_pri_lsb 0
2657#define xd_g_reg_tpsd_const 0xA3C1
2658#define reg_tpsd_const_pos 6
2659#define reg_tpsd_const_len 2
2660#define reg_tpsd_const_lsb 0
2661#define xd_g_reg_tpsd_hpcr 0xA3C2
2662#define reg_tpsd_hpcr_pos 0
2663#define reg_tpsd_hpcr_len 3
2664#define reg_tpsd_hpcr_lsb 0
2665#define xd_g_reg_tpsd_lpcr 0xA3C2
2666#define reg_tpsd_lpcr_pos 3
2667#define reg_tpsd_lpcr_len 3
2668#define reg_tpsd_lpcr_lsb 0
2669#define xd_g_reg_ofsm_clk 0xA3D0
2670#define reg_ofsm_clk_pos 0
2671#define reg_ofsm_clk_len 3
2672#define reg_ofsm_clk_lsb 0
2673#define xd_g_reg_fclk_cfg 0xA3D1
2674#define reg_fclk_cfg_pos 0
2675#define reg_fclk_cfg_len 1
2676#define reg_fclk_cfg_lsb 0
2677#define xd_g_reg_fclk_idi 0xA3D1
2678#define reg_fclk_idi_pos 1
2679#define reg_fclk_idi_len 1
2680#define reg_fclk_idi_lsb 0
2681#define xd_g_reg_fclk_odi 0xA3D1
2682#define reg_fclk_odi_pos 2
2683#define reg_fclk_odi_len 1
2684#define reg_fclk_odi_lsb 0
2685#define xd_g_reg_fclk_rsd 0xA3D1
2686#define reg_fclk_rsd_pos 3
2687#define reg_fclk_rsd_len 1
2688#define reg_fclk_rsd_lsb 0
2689#define xd_g_reg_fclk_vtb 0xA3D1
2690#define reg_fclk_vtb_pos 4
2691#define reg_fclk_vtb_len 1
2692#define reg_fclk_vtb_lsb 0
2693#define xd_g_reg_fclk_cste 0xA3D1
2694#define reg_fclk_cste_pos 5
2695#define reg_fclk_cste_len 1
2696#define reg_fclk_cste_lsb 0
2697#define xd_g_reg_fclk_mp2if 0xA3D1
2698#define reg_fclk_mp2if_pos 6
2699#define reg_fclk_mp2if_len 1
2700#define reg_fclk_mp2if_lsb 0
2701#define xd_I2C_i2c_m_slave_addr 0xA400
2702#define i2c_m_slave_addr_pos 0
2703#define i2c_m_slave_addr_len 8
2704#define i2c_m_slave_addr_lsb 0
2705#define xd_I2C_i2c_m_data1 0xA401
2706#define i2c_m_data1_pos 0
2707#define i2c_m_data1_len 8
2708#define i2c_m_data1_lsb 0
2709#define xd_I2C_i2c_m_data2 0xA402
2710#define i2c_m_data2_pos 0
2711#define i2c_m_data2_len 8
2712#define i2c_m_data2_lsb 0
2713#define xd_I2C_i2c_m_data3 0xA403
2714#define i2c_m_data3_pos 0
2715#define i2c_m_data3_len 8
2716#define i2c_m_data3_lsb 0
2717#define xd_I2C_i2c_m_data4 0xA404
2718#define i2c_m_data4_pos 0
2719#define i2c_m_data4_len 8
2720#define i2c_m_data4_lsb 0
2721#define xd_I2C_i2c_m_data5 0xA405
2722#define i2c_m_data5_pos 0
2723#define i2c_m_data5_len 8
2724#define i2c_m_data5_lsb 0
2725#define xd_I2C_i2c_m_data6 0xA406
2726#define i2c_m_data6_pos 0
2727#define i2c_m_data6_len 8
2728#define i2c_m_data6_lsb 0
2729#define xd_I2C_i2c_m_data7 0xA407
2730#define i2c_m_data7_pos 0
2731#define i2c_m_data7_len 8
2732#define i2c_m_data7_lsb 0
2733#define xd_I2C_i2c_m_data8 0xA408
2734#define i2c_m_data8_pos 0
2735#define i2c_m_data8_len 8
2736#define i2c_m_data8_lsb 0
2737#define xd_I2C_i2c_m_data9 0xA409
2738#define i2c_m_data9_pos 0
2739#define i2c_m_data9_len 8
2740#define i2c_m_data9_lsb 0
2741#define xd_I2C_i2c_m_data10 0xA40A
2742#define i2c_m_data10_pos 0
2743#define i2c_m_data10_len 8
2744#define i2c_m_data10_lsb 0
2745#define xd_I2C_i2c_m_data11 0xA40B
2746#define i2c_m_data11_pos 0
2747#define i2c_m_data11_len 8
2748#define i2c_m_data11_lsb 0
2749#define xd_I2C_i2c_m_cmd_rw 0xA40C
2750#define i2c_m_cmd_rw_pos 0
2751#define i2c_m_cmd_rw_len 1
2752#define i2c_m_cmd_rw_lsb 0
2753#define xd_I2C_i2c_m_cmd_rwlen 0xA40C
2754#define i2c_m_cmd_rwlen_pos 3
2755#define i2c_m_cmd_rwlen_len 4
2756#define i2c_m_cmd_rwlen_lsb 0
2757#define xd_I2C_i2c_m_status_cmd_exe 0xA40D
2758#define i2c_m_status_cmd_exe_pos 0
2759#define i2c_m_status_cmd_exe_len 1
2760#define i2c_m_status_cmd_exe_lsb 0
2761#define xd_I2C_i2c_m_status_wdat_done 0xA40D
2762#define i2c_m_status_wdat_done_pos 1
2763#define i2c_m_status_wdat_done_len 1
2764#define i2c_m_status_wdat_done_lsb 0
2765#define xd_I2C_i2c_m_status_wdat_fail 0xA40D
2766#define i2c_m_status_wdat_fail_pos 2
2767#define i2c_m_status_wdat_fail_len 1
2768#define i2c_m_status_wdat_fail_lsb 0
2769#define xd_I2C_i2c_m_period 0xA40E
2770#define i2c_m_period_pos 0
2771#define i2c_m_period_len 8
2772#define i2c_m_period_lsb 0
2773#define xd_I2C_i2c_m_reg_msb_lsb 0xA40F
2774#define i2c_m_reg_msb_lsb_pos 0
2775#define i2c_m_reg_msb_lsb_len 1
2776#define i2c_m_reg_msb_lsb_lsb 0
2777#define xd_I2C_reg_ofdm_rst 0xA40F
2778#define reg_ofdm_rst_pos 1
2779#define reg_ofdm_rst_len 1
2780#define reg_ofdm_rst_lsb 0
2781#define xd_I2C_reg_sample_period_on_tuner 0xA40F
2782#define reg_sample_period_on_tuner_pos 2
2783#define reg_sample_period_on_tuner_len 1
2784#define reg_sample_period_on_tuner_lsb 0
2785#define xd_I2C_reg_rst_i2c 0xA40F
2786#define reg_rst_i2c_pos 3
2787#define reg_rst_i2c_len 1
2788#define reg_rst_i2c_lsb 0
2789#define xd_I2C_reg_ofdm_rst_en 0xA40F
2790#define reg_ofdm_rst_en_pos 4
2791#define reg_ofdm_rst_en_len 1
2792#define reg_ofdm_rst_en_lsb 0
2793#define xd_I2C_reg_tuner_sda_sync_on 0xA40F
2794#define reg_tuner_sda_sync_on_pos 5
2795#define reg_tuner_sda_sync_on_len 1
2796#define reg_tuner_sda_sync_on_lsb 0
2797#define xd_p_mp2if_data_access_disable_ofsm 0xA500
2798#define mp2if_data_access_disable_ofsm_pos 0
2799#define mp2if_data_access_disable_ofsm_len 1
2800#define mp2if_data_access_disable_ofsm_lsb 0
2801#define xd_p_reg_mp2_sw_rst_ofsm 0xA500
2802#define reg_mp2_sw_rst_ofsm_pos 1
2803#define reg_mp2_sw_rst_ofsm_len 1
2804#define reg_mp2_sw_rst_ofsm_lsb 0
2805#define xd_p_reg_mp2if_clk_en_ofsm 0xA500
2806#define reg_mp2if_clk_en_ofsm_pos 2
2807#define reg_mp2if_clk_en_ofsm_len 1
2808#define reg_mp2if_clk_en_ofsm_lsb 0
2809#define xd_r_mp2if_sync_byte_locked 0xA500
2810#define mp2if_sync_byte_locked_pos 3
2811#define mp2if_sync_byte_locked_len 1
2812#define mp2if_sync_byte_locked_lsb 0
2813#define xd_r_mp2if_ts_not_188 0xA500
2814#define mp2if_ts_not_188_pos 4
2815#define mp2if_ts_not_188_len 1
2816#define mp2if_ts_not_188_lsb 0
2817#define xd_r_mp2if_psb_empty 0xA500
2818#define mp2if_psb_empty_pos 5
2819#define mp2if_psb_empty_len 1
2820#define mp2if_psb_empty_lsb 0
2821#define xd_r_mp2if_psb_overflow 0xA500
2822#define mp2if_psb_overflow_pos 6
2823#define mp2if_psb_overflow_len 1
2824#define mp2if_psb_overflow_lsb 0
2825#define xd_p_mp2if_keep_sf_sync_byte_ofsm 0xA500
2826#define mp2if_keep_sf_sync_byte_ofsm_pos 7
2827#define mp2if_keep_sf_sync_byte_ofsm_len 1
2828#define mp2if_keep_sf_sync_byte_ofsm_lsb 0
2829#define xd_r_mp2if_psb_mp2if_num_pkt 0xA501
2830#define mp2if_psb_mp2if_num_pkt_pos 0
2831#define mp2if_psb_mp2if_num_pkt_len 6
2832#define mp2if_psb_mp2if_num_pkt_lsb 0
2833#define xd_p_reg_mpeg_full_speed_ofsm 0xA501
2834#define reg_mpeg_full_speed_ofsm_pos 6
2835#define reg_mpeg_full_speed_ofsm_len 1
2836#define reg_mpeg_full_speed_ofsm_lsb 0
2837#define xd_p_mp2if_mpeg_ser_mode_ofsm 0xA501
2838#define mp2if_mpeg_ser_mode_ofsm_pos 7
2839#define mp2if_mpeg_ser_mode_ofsm_len 1
2840#define mp2if_mpeg_ser_mode_ofsm_lsb 0
2841#define xd_p_reg_sw_mon51 0xA600
2842#define reg_sw_mon51_pos 0
2843#define reg_sw_mon51_len 8
2844#define reg_sw_mon51_lsb 0
2845#define xd_p_reg_top_pcsel 0xA601
2846#define reg_top_pcsel_pos 0
2847#define reg_top_pcsel_len 1
2848#define reg_top_pcsel_lsb 0
2849#define xd_p_reg_top_rs232 0xA601
2850#define reg_top_rs232_pos 1
2851#define reg_top_rs232_len 1
2852#define reg_top_rs232_lsb 0
2853#define xd_p_reg_top_pcout 0xA601
2854#define reg_top_pcout_pos 2
2855#define reg_top_pcout_len 1
2856#define reg_top_pcout_lsb 0
2857#define xd_p_reg_top_debug 0xA601
2858#define reg_top_debug_pos 3
2859#define reg_top_debug_len 1
2860#define reg_top_debug_lsb 0
2861#define xd_p_reg_top_adcdly 0xA601
2862#define reg_top_adcdly_pos 4
2863#define reg_top_adcdly_len 2
2864#define reg_top_adcdly_lsb 0
2865#define xd_p_reg_top_pwrdw 0xA601
2866#define reg_top_pwrdw_pos 6
2867#define reg_top_pwrdw_len 1
2868#define reg_top_pwrdw_lsb 0
2869#define xd_p_reg_top_pwrdw_inv 0xA601
2870#define reg_top_pwrdw_inv_pos 7
2871#define reg_top_pwrdw_inv_len 1
2872#define reg_top_pwrdw_inv_lsb 0
2873#define xd_p_reg_top_int_inv 0xA602
2874#define reg_top_int_inv_pos 0
2875#define reg_top_int_inv_len 1
2876#define reg_top_int_inv_lsb 0
2877#define xd_p_reg_top_dio_sel 0xA602
2878#define reg_top_dio_sel_pos 1
2879#define reg_top_dio_sel_len 1
2880#define reg_top_dio_sel_lsb 0
2881#define xd_p_reg_top_gpioon0 0xA603
2882#define reg_top_gpioon0_pos 0
2883#define reg_top_gpioon0_len 1
2884#define reg_top_gpioon0_lsb 0
2885#define xd_p_reg_top_gpioon1 0xA603
2886#define reg_top_gpioon1_pos 1
2887#define reg_top_gpioon1_len 1
2888#define reg_top_gpioon1_lsb 0
2889#define xd_p_reg_top_gpioon2 0xA603
2890#define reg_top_gpioon2_pos 2
2891#define reg_top_gpioon2_len 1
2892#define reg_top_gpioon2_lsb 0
2893#define xd_p_reg_top_gpioon3 0xA603
2894#define reg_top_gpioon3_pos 3
2895#define reg_top_gpioon3_len 1
2896#define reg_top_gpioon3_lsb 0
2897#define xd_p_reg_top_lockon1 0xA603
2898#define reg_top_lockon1_pos 4
2899#define reg_top_lockon1_len 1
2900#define reg_top_lockon1_lsb 0
2901#define xd_p_reg_top_lockon2 0xA603
2902#define reg_top_lockon2_pos 5
2903#define reg_top_lockon2_len 1
2904#define reg_top_lockon2_lsb 0
2905#define xd_p_reg_top_gpioo0 0xA604
2906#define reg_top_gpioo0_pos 0
2907#define reg_top_gpioo0_len 1
2908#define reg_top_gpioo0_lsb 0
2909#define xd_p_reg_top_gpioo1 0xA604
2910#define reg_top_gpioo1_pos 1
2911#define reg_top_gpioo1_len 1
2912#define reg_top_gpioo1_lsb 0
2913#define xd_p_reg_top_gpioo2 0xA604
2914#define reg_top_gpioo2_pos 2
2915#define reg_top_gpioo2_len 1
2916#define reg_top_gpioo2_lsb 0
2917#define xd_p_reg_top_gpioo3 0xA604
2918#define reg_top_gpioo3_pos 3
2919#define reg_top_gpioo3_len 1
2920#define reg_top_gpioo3_lsb 0
2921#define xd_p_reg_top_lock1 0xA604
2922#define reg_top_lock1_pos 4
2923#define reg_top_lock1_len 1
2924#define reg_top_lock1_lsb 0
2925#define xd_p_reg_top_lock2 0xA604
2926#define reg_top_lock2_pos 5
2927#define reg_top_lock2_len 1
2928#define reg_top_lock2_lsb 0
2929#define xd_p_reg_top_gpioen0 0xA605
2930#define reg_top_gpioen0_pos 0
2931#define reg_top_gpioen0_len 1
2932#define reg_top_gpioen0_lsb 0
2933#define xd_p_reg_top_gpioen1 0xA605
2934#define reg_top_gpioen1_pos 1
2935#define reg_top_gpioen1_len 1
2936#define reg_top_gpioen1_lsb 0
2937#define xd_p_reg_top_gpioen2 0xA605
2938#define reg_top_gpioen2_pos 2
2939#define reg_top_gpioen2_len 1
2940#define reg_top_gpioen2_lsb 0
2941#define xd_p_reg_top_gpioen3 0xA605
2942#define reg_top_gpioen3_pos 3
2943#define reg_top_gpioen3_len 1
2944#define reg_top_gpioen3_lsb 0
2945#define xd_p_reg_top_locken1 0xA605
2946#define reg_top_locken1_pos 4
2947#define reg_top_locken1_len 1
2948#define reg_top_locken1_lsb 0
2949#define xd_p_reg_top_locken2 0xA605
2950#define reg_top_locken2_pos 5
2951#define reg_top_locken2_len 1
2952#define reg_top_locken2_lsb 0
2953#define xd_r_reg_top_gpioi0 0xA606
2954#define reg_top_gpioi0_pos 0
2955#define reg_top_gpioi0_len 1
2956#define reg_top_gpioi0_lsb 0
2957#define xd_r_reg_top_gpioi1 0xA606
2958#define reg_top_gpioi1_pos 1
2959#define reg_top_gpioi1_len 1
2960#define reg_top_gpioi1_lsb 0
2961#define xd_r_reg_top_gpioi2 0xA606
2962#define reg_top_gpioi2_pos 2
2963#define reg_top_gpioi2_len 1
2964#define reg_top_gpioi2_lsb 0
2965#define xd_r_reg_top_gpioi3 0xA606
2966#define reg_top_gpioi3_pos 3
2967#define reg_top_gpioi3_len 1
2968#define reg_top_gpioi3_lsb 0
2969#define xd_r_reg_top_locki1 0xA606
2970#define reg_top_locki1_pos 4
2971#define reg_top_locki1_len 1
2972#define reg_top_locki1_lsb 0
2973#define xd_r_reg_top_locki2 0xA606
2974#define reg_top_locki2_pos 5
2975#define reg_top_locki2_len 1
2976#define reg_top_locki2_lsb 0
2977#define xd_p_reg_dummy_7_0 0xA608
2978#define reg_dummy_7_0_pos 0
2979#define reg_dummy_7_0_len 8
2980#define reg_dummy_7_0_lsb 0
2981#define xd_p_reg_dummy_15_8 0xA609
2982#define reg_dummy_15_8_pos 0
2983#define reg_dummy_15_8_len 8
2984#define reg_dummy_15_8_lsb 8
2985#define xd_p_reg_dummy_23_16 0xA60A
2986#define reg_dummy_23_16_pos 0
2987#define reg_dummy_23_16_len 8
2988#define reg_dummy_23_16_lsb 16
2989#define xd_p_reg_dummy_31_24 0xA60B
2990#define reg_dummy_31_24_pos 0
2991#define reg_dummy_31_24_len 8
2992#define reg_dummy_31_24_lsb 24
2993#define xd_p_reg_dummy_39_32 0xA60C
2994#define reg_dummy_39_32_pos 0
2995#define reg_dummy_39_32_len 8
2996#define reg_dummy_39_32_lsb 32
2997#define xd_p_reg_dummy_47_40 0xA60D
2998#define reg_dummy_47_40_pos 0
2999#define reg_dummy_47_40_len 8
3000#define reg_dummy_47_40_lsb 40
3001#define xd_p_reg_dummy_55_48 0xA60E
3002#define reg_dummy_55_48_pos 0
3003#define reg_dummy_55_48_len 8
3004#define reg_dummy_55_48_lsb 48
3005#define xd_p_reg_dummy_63_56 0xA60F
3006#define reg_dummy_63_56_pos 0
3007#define reg_dummy_63_56_len 8
3008#define reg_dummy_63_56_lsb 56
3009#define xd_p_reg_dummy_71_64 0xA610
3010#define reg_dummy_71_64_pos 0
3011#define reg_dummy_71_64_len 8
3012#define reg_dummy_71_64_lsb 64
3013#define xd_p_reg_dummy_79_72 0xA611
3014#define reg_dummy_79_72_pos 0
3015#define reg_dummy_79_72_len 8
3016#define reg_dummy_79_72_lsb 72
3017#define xd_p_reg_dummy_87_80 0xA612
3018#define reg_dummy_87_80_pos 0
3019#define reg_dummy_87_80_len 8
3020#define reg_dummy_87_80_lsb 80
3021#define xd_p_reg_dummy_95_88 0xA613
3022#define reg_dummy_95_88_pos 0
3023#define reg_dummy_95_88_len 8
3024#define reg_dummy_95_88_lsb 88
3025#define xd_p_reg_dummy_103_96 0xA614
3026#define reg_dummy_103_96_pos 0
3027#define reg_dummy_103_96_len 8
3028#define reg_dummy_103_96_lsb 96
3029
3030#define xd_p_reg_unplug_flag 0xA615
3031#define reg_unplug_flag_pos 0
3032#define reg_unplug_flag_len 1
3033#define reg_unplug_flag_lsb 104
3034
3035#define xd_p_reg_api_dca_stes_request 0xA615
3036#define reg_api_dca_stes_request_pos 1
3037#define reg_api_dca_stes_request_len 1
3038#define reg_api_dca_stes_request_lsb 0
3039
3040#define xd_p_reg_back_to_dca_flag 0xA615
3041#define reg_back_to_dca_flag_pos 2
3042#define reg_back_to_dca_flag_len 1
3043#define reg_back_to_dca_flag_lsb 106
3044
3045#define xd_p_reg_api_retrain_request 0xA615
3046#define reg_api_retrain_request_pos 3
3047#define reg_api_retrain_request_len 1
3048#define reg_api_retrain_request_lsb 0
3049
3050#define xd_p_reg_Dyn_Top_Try_flag 0xA615
3051#define reg_Dyn_Top_Try_flag_pos 3
3052#define reg_Dyn_Top_Try_flag_len 1
3053#define reg_Dyn_Top_Try_flag_lsb 107
3054
3055#define xd_p_reg_API_retrain_freeze_flag 0xA615
3056#define reg_API_retrain_freeze_flag_pos 4
3057#define reg_API_retrain_freeze_flag_len 1
3058#define reg_API_retrain_freeze_flag_lsb 108
3059
3060#define xd_p_reg_dummy_111_104 0xA615
3061#define reg_dummy_111_104_pos 0
3062#define reg_dummy_111_104_len 8
3063#define reg_dummy_111_104_lsb 104
3064#define xd_p_reg_dummy_119_112 0xA616
3065#define reg_dummy_119_112_pos 0
3066#define reg_dummy_119_112_len 8
3067#define reg_dummy_119_112_lsb 112
3068#define xd_p_reg_dummy_127_120 0xA617
3069#define reg_dummy_127_120_pos 0
3070#define reg_dummy_127_120_len 8
3071#define reg_dummy_127_120_lsb 120
3072#define xd_p_reg_dummy_135_128 0xA618
3073#define reg_dummy_135_128_pos 0
3074#define reg_dummy_135_128_len 8
3075#define reg_dummy_135_128_lsb 128
3076
3077#define xd_p_reg_dummy_143_136 0xA619
3078#define reg_dummy_143_136_pos 0
3079#define reg_dummy_143_136_len 8
3080#define reg_dummy_143_136_lsb 136
3081
3082#define xd_p_reg_CCIR_dis 0xA619
3083#define reg_CCIR_dis_pos 0
3084#define reg_CCIR_dis_len 1
3085#define reg_CCIR_dis_lsb 0
3086
3087#define xd_p_reg_dummy_151_144 0xA61A
3088#define reg_dummy_151_144_pos 0
3089#define reg_dummy_151_144_len 8
3090#define reg_dummy_151_144_lsb 144
3091
3092#define xd_p_reg_dummy_159_152 0xA61B
3093#define reg_dummy_159_152_pos 0
3094#define reg_dummy_159_152_len 8
3095#define reg_dummy_159_152_lsb 152
3096
3097#define xd_p_reg_dummy_167_160 0xA61C
3098#define reg_dummy_167_160_pos 0
3099#define reg_dummy_167_160_len 8
3100#define reg_dummy_167_160_lsb 160
3101
3102#define xd_p_reg_dummy_175_168 0xA61D
3103#define reg_dummy_175_168_pos 0
3104#define reg_dummy_175_168_len 8
3105#define reg_dummy_175_168_lsb 168
3106
3107#define xd_p_reg_dummy_183_176 0xA61E
3108#define reg_dummy_183_176_pos 0
3109#define reg_dummy_183_176_len 8
3110#define reg_dummy_183_176_lsb 176
3111
3112#define xd_p_reg_ofsm_read_rbc_en 0xA61E
3113#define reg_ofsm_read_rbc_en_pos 2
3114#define reg_ofsm_read_rbc_en_len 1
3115#define reg_ofsm_read_rbc_en_lsb 0
3116
3117#define xd_p_reg_ce_filter_selection_dis 0xA61E
3118#define reg_ce_filter_selection_dis_pos 1
3119#define reg_ce_filter_selection_dis_len 1
3120#define reg_ce_filter_selection_dis_lsb 0
3121
3122#define xd_p_reg_OFSM_version_control_7_0 0xA611
3123#define reg_OFSM_version_control_7_0_pos 0
3124#define reg_OFSM_version_control_7_0_len 8
3125#define reg_OFSM_version_control_7_0_lsb 0
3126
3127#define xd_p_reg_OFSM_version_control_15_8 0xA61F
3128#define reg_OFSM_version_control_15_8_pos 0
3129#define reg_OFSM_version_control_15_8_len 8
3130#define reg_OFSM_version_control_15_8_lsb 0
3131
3132#define xd_p_reg_OFSM_version_control_23_16 0xA620
3133#define reg_OFSM_version_control_23_16_pos 0
3134#define reg_OFSM_version_control_23_16_len 8
3135#define reg_OFSM_version_control_23_16_lsb 0
3136
3137#define xd_p_reg_dummy_191_184 0xA61F
3138#define reg_dummy_191_184_pos 0
3139#define reg_dummy_191_184_len 8
3140#define reg_dummy_191_184_lsb 184
3141
3142#define xd_p_reg_dummy_199_192 0xA620
3143#define reg_dummy_199_192_pos 0
3144#define reg_dummy_199_192_len 8
3145#define reg_dummy_199_192_lsb 192
3146
3147#define xd_p_reg_ce_en 0xABC0
3148#define reg_ce_en_pos 0
3149#define reg_ce_en_len 1
3150#define reg_ce_en_lsb 0
3151#define xd_p_reg_ce_fctrl_en 0xABC0
3152#define reg_ce_fctrl_en_pos 1
3153#define reg_ce_fctrl_en_len 1
3154#define reg_ce_fctrl_en_lsb 0
3155#define xd_p_reg_ce_fste_tdi 0xABC0
3156#define reg_ce_fste_tdi_pos 2
3157#define reg_ce_fste_tdi_len 1
3158#define reg_ce_fste_tdi_lsb 0
3159#define xd_p_reg_ce_dynamic 0xABC0
3160#define reg_ce_dynamic_pos 3
3161#define reg_ce_dynamic_len 1
3162#define reg_ce_dynamic_lsb 0
3163#define xd_p_reg_ce_conf 0xABC0
3164#define reg_ce_conf_pos 4
3165#define reg_ce_conf_len 2
3166#define reg_ce_conf_lsb 0
3167#define xd_p_reg_ce_dyn12 0xABC0
3168#define reg_ce_dyn12_pos 6
3169#define reg_ce_dyn12_len 1
3170#define reg_ce_dyn12_lsb 0
3171#define xd_p_reg_ce_derot_en 0xABC0
3172#define reg_ce_derot_en_pos 7
3173#define reg_ce_derot_en_len 1
3174#define reg_ce_derot_en_lsb 0
3175#define xd_p_reg_ce_dynamic_th_7_0 0xABC1
3176#define reg_ce_dynamic_th_7_0_pos 0
3177#define reg_ce_dynamic_th_7_0_len 8
3178#define reg_ce_dynamic_th_7_0_lsb 0
3179#define xd_p_reg_ce_dynamic_th_15_8 0xABC2
3180#define reg_ce_dynamic_th_15_8_pos 0
3181#define reg_ce_dynamic_th_15_8_len 8
3182#define reg_ce_dynamic_th_15_8_lsb 8
3183#define xd_p_reg_ce_s1 0xABC3
3184#define reg_ce_s1_pos 0
3185#define reg_ce_s1_len 5
3186#define reg_ce_s1_lsb 0
3187#define xd_p_reg_ce_var_forced_value 0xABC3
3188#define reg_ce_var_forced_value_pos 5
3189#define reg_ce_var_forced_value_len 3
3190#define reg_ce_var_forced_value_lsb 0
3191#define xd_p_reg_ce_data_im_7_0 0xABC4
3192#define reg_ce_data_im_7_0_pos 0
3193#define reg_ce_data_im_7_0_len 8
3194#define reg_ce_data_im_7_0_lsb 0
3195#define xd_p_reg_ce_data_im_8 0xABC5
3196#define reg_ce_data_im_8_pos 0
3197#define reg_ce_data_im_8_len 1
3198#define reg_ce_data_im_8_lsb 0
3199#define xd_p_reg_ce_data_re_6_0 0xABC5
3200#define reg_ce_data_re_6_0_pos 1
3201#define reg_ce_data_re_6_0_len 7
3202#define reg_ce_data_re_6_0_lsb 0
3203#define xd_p_reg_ce_data_re_8_7 0xABC6
3204#define reg_ce_data_re_8_7_pos 0
3205#define reg_ce_data_re_8_7_len 2
3206#define reg_ce_data_re_8_7_lsb 7
3207#define xd_p_reg_ce_tone_5_0 0xABC6
3208#define reg_ce_tone_5_0_pos 2
3209#define reg_ce_tone_5_0_len 6
3210#define reg_ce_tone_5_0_lsb 0
3211#define xd_p_reg_ce_tone_12_6 0xABC7
3212#define reg_ce_tone_12_6_pos 0
3213#define reg_ce_tone_12_6_len 7
3214#define reg_ce_tone_12_6_lsb 6
3215#define xd_p_reg_ce_centroid_drift_th 0xABC8
3216#define reg_ce_centroid_drift_th_pos 0
3217#define reg_ce_centroid_drift_th_len 8
3218#define reg_ce_centroid_drift_th_lsb 0
3219#define xd_p_reg_ce_centroid_count_max 0xABC9
3220#define reg_ce_centroid_count_max_pos 0
3221#define reg_ce_centroid_count_max_len 4
3222#define reg_ce_centroid_count_max_lsb 0
3223#define xd_p_reg_ce_centroid_bias_inc_7_0 0xABCA
3224#define reg_ce_centroid_bias_inc_7_0_pos 0
3225#define reg_ce_centroid_bias_inc_7_0_len 8
3226#define reg_ce_centroid_bias_inc_7_0_lsb 0
3227#define xd_p_reg_ce_centroid_bias_inc_8 0xABCB
3228#define reg_ce_centroid_bias_inc_8_pos 0
3229#define reg_ce_centroid_bias_inc_8_len 1
3230#define reg_ce_centroid_bias_inc_8_lsb 0
3231#define xd_p_reg_ce_var_th0_7_0 0xABCC
3232#define reg_ce_var_th0_7_0_pos 0
3233#define reg_ce_var_th0_7_0_len 8
3234#define reg_ce_var_th0_7_0_lsb 0
3235#define xd_p_reg_ce_var_th0_15_8 0xABCD
3236#define reg_ce_var_th0_15_8_pos 0
3237#define reg_ce_var_th0_15_8_len 8
3238#define reg_ce_var_th0_15_8_lsb 8
3239#define xd_p_reg_ce_var_th1_7_0 0xABCE
3240#define reg_ce_var_th1_7_0_pos 0
3241#define reg_ce_var_th1_7_0_len 8
3242#define reg_ce_var_th1_7_0_lsb 0
3243#define xd_p_reg_ce_var_th1_15_8 0xABCF
3244#define reg_ce_var_th1_15_8_pos 0
3245#define reg_ce_var_th1_15_8_len 8
3246#define reg_ce_var_th1_15_8_lsb 8
3247#define xd_p_reg_ce_var_th2_7_0 0xABD0
3248#define reg_ce_var_th2_7_0_pos 0
3249#define reg_ce_var_th2_7_0_len 8
3250#define reg_ce_var_th2_7_0_lsb 0
3251#define xd_p_reg_ce_var_th2_15_8 0xABD1
3252#define reg_ce_var_th2_15_8_pos 0
3253#define reg_ce_var_th2_15_8_len 8
3254#define reg_ce_var_th2_15_8_lsb 8
3255#define xd_p_reg_ce_var_th3_7_0 0xABD2
3256#define reg_ce_var_th3_7_0_pos 0
3257#define reg_ce_var_th3_7_0_len 8
3258#define reg_ce_var_th3_7_0_lsb 0
3259#define xd_p_reg_ce_var_th3_15_8 0xABD3
3260#define reg_ce_var_th3_15_8_pos 0
3261#define reg_ce_var_th3_15_8_len 8
3262#define reg_ce_var_th3_15_8_lsb 8
3263#define xd_p_reg_ce_var_th4_7_0 0xABD4
3264#define reg_ce_var_th4_7_0_pos 0
3265#define reg_ce_var_th4_7_0_len 8
3266#define reg_ce_var_th4_7_0_lsb 0
3267#define xd_p_reg_ce_var_th4_15_8 0xABD5
3268#define reg_ce_var_th4_15_8_pos 0
3269#define reg_ce_var_th4_15_8_len 8
3270#define reg_ce_var_th4_15_8_lsb 8
3271#define xd_p_reg_ce_var_th5_7_0 0xABD6
3272#define reg_ce_var_th5_7_0_pos 0
3273#define reg_ce_var_th5_7_0_len 8
3274#define reg_ce_var_th5_7_0_lsb 0
3275#define xd_p_reg_ce_var_th5_15_8 0xABD7
3276#define reg_ce_var_th5_15_8_pos 0
3277#define reg_ce_var_th5_15_8_len 8
3278#define reg_ce_var_th5_15_8_lsb 8
3279#define xd_p_reg_ce_var_th6_7_0 0xABD8
3280#define reg_ce_var_th6_7_0_pos 0
3281#define reg_ce_var_th6_7_0_len 8
3282#define reg_ce_var_th6_7_0_lsb 0
3283#define xd_p_reg_ce_var_th6_15_8 0xABD9
3284#define reg_ce_var_th6_15_8_pos 0
3285#define reg_ce_var_th6_15_8_len 8
3286#define reg_ce_var_th6_15_8_lsb 8
3287#define xd_p_reg_ce_fctrl_reset 0xABDA
3288#define reg_ce_fctrl_reset_pos 0
3289#define reg_ce_fctrl_reset_len 1
3290#define reg_ce_fctrl_reset_lsb 0
3291#define xd_p_reg_ce_cent_auto_clr_en 0xABDA
3292#define reg_ce_cent_auto_clr_en_pos 1
3293#define reg_ce_cent_auto_clr_en_len 1
3294#define reg_ce_cent_auto_clr_en_lsb 0
3295#define xd_p_reg_ce_fctrl_auto_reset_en 0xABDA
3296#define reg_ce_fctrl_auto_reset_en_pos 2
3297#define reg_ce_fctrl_auto_reset_en_len 1
3298#define reg_ce_fctrl_auto_reset_en_lsb 0
3299#define xd_p_reg_ce_var_forced_en 0xABDA
3300#define reg_ce_var_forced_en_pos 3
3301#define reg_ce_var_forced_en_len 1
3302#define reg_ce_var_forced_en_lsb 0
3303#define xd_p_reg_ce_cent_forced_en 0xABDA
3304#define reg_ce_cent_forced_en_pos 4
3305#define reg_ce_cent_forced_en_len 1
3306#define reg_ce_cent_forced_en_lsb 0
3307#define xd_p_reg_ce_var_max 0xABDA
3308#define reg_ce_var_max_pos 5
3309#define reg_ce_var_max_len 3
3310#define reg_ce_var_max_lsb 0
3311#define xd_p_reg_ce_cent_forced_value_7_0 0xABDB
3312#define reg_ce_cent_forced_value_7_0_pos 0
3313#define reg_ce_cent_forced_value_7_0_len 8
3314#define reg_ce_cent_forced_value_7_0_lsb 0
3315#define xd_p_reg_ce_cent_forced_value_11_8 0xABDC
3316#define reg_ce_cent_forced_value_11_8_pos 0
3317#define reg_ce_cent_forced_value_11_8_len 4
3318#define reg_ce_cent_forced_value_11_8_lsb 8
3319#define xd_p_reg_ce_fctrl_rd 0xABDD
3320#define reg_ce_fctrl_rd_pos 0
3321#define reg_ce_fctrl_rd_len 1
3322#define reg_ce_fctrl_rd_lsb 0
3323#define xd_p_reg_ce_centroid_max_6_0 0xABDD
3324#define reg_ce_centroid_max_6_0_pos 1
3325#define reg_ce_centroid_max_6_0_len 7
3326#define reg_ce_centroid_max_6_0_lsb 0
3327#define xd_p_reg_ce_centroid_max_11_7 0xABDE
3328#define reg_ce_centroid_max_11_7_pos 0
3329#define reg_ce_centroid_max_11_7_len 5
3330#define reg_ce_centroid_max_11_7_lsb 7
3331#define xd_p_reg_ce_var 0xABDF
3332#define reg_ce_var_pos 0
3333#define reg_ce_var_len 3
3334#define reg_ce_var_lsb 0
3335#define xd_p_reg_ce_fctrl_rdy 0xABDF
3336#define reg_ce_fctrl_rdy_pos 3
3337#define reg_ce_fctrl_rdy_len 1
3338#define reg_ce_fctrl_rdy_lsb 0
3339#define xd_p_reg_ce_centroid_out_3_0 0xABDF
3340#define reg_ce_centroid_out_3_0_pos 4
3341#define reg_ce_centroid_out_3_0_len 4
3342#define reg_ce_centroid_out_3_0_lsb 0
3343#define xd_p_reg_ce_centroid_out_11_4 0xABE0
3344#define reg_ce_centroid_out_11_4_pos 0
3345#define reg_ce_centroid_out_11_4_len 8
3346#define reg_ce_centroid_out_11_4_lsb 4
3347#define xd_p_reg_ce_bias_7_0 0xABE1
3348#define reg_ce_bias_7_0_pos 0
3349#define reg_ce_bias_7_0_len 8
3350#define reg_ce_bias_7_0_lsb 0
3351#define xd_p_reg_ce_bias_11_8 0xABE2
3352#define reg_ce_bias_11_8_pos 0
3353#define reg_ce_bias_11_8_len 4
3354#define reg_ce_bias_11_8_lsb 8
3355#define xd_p_reg_ce_m1_3_0 0xABE2
3356#define reg_ce_m1_3_0_pos 4
3357#define reg_ce_m1_3_0_len 4
3358#define reg_ce_m1_3_0_lsb 0
3359#define xd_p_reg_ce_m1_11_4 0xABE3
3360#define reg_ce_m1_11_4_pos 0
3361#define reg_ce_m1_11_4_len 8
3362#define reg_ce_m1_11_4_lsb 4
3363#define xd_p_reg_ce_rh0_7_0 0xABE4
3364#define reg_ce_rh0_7_0_pos 0
3365#define reg_ce_rh0_7_0_len 8
3366#define reg_ce_rh0_7_0_lsb 0
3367#define xd_p_reg_ce_rh0_15_8 0xABE5
3368#define reg_ce_rh0_15_8_pos 0
3369#define reg_ce_rh0_15_8_len 8
3370#define reg_ce_rh0_15_8_lsb 8
3371#define xd_p_reg_ce_rh0_23_16 0xABE6
3372#define reg_ce_rh0_23_16_pos 0
3373#define reg_ce_rh0_23_16_len 8
3374#define reg_ce_rh0_23_16_lsb 16
3375#define xd_p_reg_ce_rh0_31_24 0xABE7
3376#define reg_ce_rh0_31_24_pos 0
3377#define reg_ce_rh0_31_24_len 8
3378#define reg_ce_rh0_31_24_lsb 24
3379#define xd_p_reg_ce_rh3_real_7_0 0xABE8
3380#define reg_ce_rh3_real_7_0_pos 0
3381#define reg_ce_rh3_real_7_0_len 8
3382#define reg_ce_rh3_real_7_0_lsb 0
3383#define xd_p_reg_ce_rh3_real_15_8 0xABE9
3384#define reg_ce_rh3_real_15_8_pos 0
3385#define reg_ce_rh3_real_15_8_len 8
3386#define reg_ce_rh3_real_15_8_lsb 8
3387#define xd_p_reg_ce_rh3_real_23_16 0xABEA
3388#define reg_ce_rh3_real_23_16_pos 0
3389#define reg_ce_rh3_real_23_16_len 8
3390#define reg_ce_rh3_real_23_16_lsb 16
3391#define xd_p_reg_ce_rh3_real_31_24 0xABEB
3392#define reg_ce_rh3_real_31_24_pos 0
3393#define reg_ce_rh3_real_31_24_len 8
3394#define reg_ce_rh3_real_31_24_lsb 24
3395#define xd_p_reg_ce_rh3_imag_7_0 0xABEC
3396#define reg_ce_rh3_imag_7_0_pos 0
3397#define reg_ce_rh3_imag_7_0_len 8
3398#define reg_ce_rh3_imag_7_0_lsb 0
3399#define xd_p_reg_ce_rh3_imag_15_8 0xABED
3400#define reg_ce_rh3_imag_15_8_pos 0
3401#define reg_ce_rh3_imag_15_8_len 8
3402#define reg_ce_rh3_imag_15_8_lsb 8
3403#define xd_p_reg_ce_rh3_imag_23_16 0xABEE
3404#define reg_ce_rh3_imag_23_16_pos 0
3405#define reg_ce_rh3_imag_23_16_len 8
3406#define reg_ce_rh3_imag_23_16_lsb 16
3407#define xd_p_reg_ce_rh3_imag_31_24 0xABEF
3408#define reg_ce_rh3_imag_31_24_pos 0
3409#define reg_ce_rh3_imag_31_24_len 8
3410#define reg_ce_rh3_imag_31_24_lsb 24
3411#define xd_p_reg_feq_fix_eh2_7_0 0xABF0
3412#define reg_feq_fix_eh2_7_0_pos 0
3413#define reg_feq_fix_eh2_7_0_len 8
3414#define reg_feq_fix_eh2_7_0_lsb 0
3415#define xd_p_reg_feq_fix_eh2_15_8 0xABF1
3416#define reg_feq_fix_eh2_15_8_pos 0
3417#define reg_feq_fix_eh2_15_8_len 8
3418#define reg_feq_fix_eh2_15_8_lsb 8
3419#define xd_p_reg_feq_fix_eh2_23_16 0xABF2
3420#define reg_feq_fix_eh2_23_16_pos 0
3421#define reg_feq_fix_eh2_23_16_len 8
3422#define reg_feq_fix_eh2_23_16_lsb 16
3423#define xd_p_reg_feq_fix_eh2_31_24 0xABF3
3424#define reg_feq_fix_eh2_31_24_pos 0
3425#define reg_feq_fix_eh2_31_24_len 8
3426#define reg_feq_fix_eh2_31_24_lsb 24
3427#define xd_p_reg_ce_m2_central_7_0 0xABF4
3428#define reg_ce_m2_central_7_0_pos 0
3429#define reg_ce_m2_central_7_0_len 8
3430#define reg_ce_m2_central_7_0_lsb 0
3431#define xd_p_reg_ce_m2_central_15_8 0xABF5
3432#define reg_ce_m2_central_15_8_pos 0
3433#define reg_ce_m2_central_15_8_len 8
3434#define reg_ce_m2_central_15_8_lsb 8
3435#define xd_p_reg_ce_fftshift 0xABF6
3436#define reg_ce_fftshift_pos 0
3437#define reg_ce_fftshift_len 4
3438#define reg_ce_fftshift_lsb 0
3439#define xd_p_reg_ce_fftshift1 0xABF6
3440#define reg_ce_fftshift1_pos 4
3441#define reg_ce_fftshift1_len 4
3442#define reg_ce_fftshift1_lsb 0
3443#define xd_p_reg_ce_fftshift2 0xABF7
3444#define reg_ce_fftshift2_pos 0
3445#define reg_ce_fftshift2_len 4
3446#define reg_ce_fftshift2_lsb 0
3447#define xd_p_reg_ce_top_mobile 0xABF7
3448#define reg_ce_top_mobile_pos 4
3449#define reg_ce_top_mobile_len 1
3450#define reg_ce_top_mobile_lsb 0
3451#define xd_p_reg_strong_sginal_detected 0xA2BC
3452#define reg_strong_sginal_detected_pos 2
3453#define reg_strong_sginal_detected_len 1
3454#define reg_strong_sginal_detected_lsb 0
3455
3456#define XD_MP2IF_BASE 0xB000
3457#define XD_MP2IF_CSR (0x00 + XD_MP2IF_BASE)
3458#define XD_MP2IF_DMX_CTRL (0x03 + XD_MP2IF_BASE)
3459#define XD_MP2IF_PID_IDX (0x04 + XD_MP2IF_BASE)
3460#define XD_MP2IF_PID_DATA_L (0x05 + XD_MP2IF_BASE)
3461#define XD_MP2IF_PID_DATA_H (0x06 + XD_MP2IF_BASE)
3462#define XD_MP2IF_MISC (0x07 + XD_MP2IF_BASE)
3463
3464extern struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d);
3465extern int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg,
3466 u8 * value);
3467extern int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg,
3468 u8 * values, int len);
3469extern int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg,
3470 u8 value);
3471extern int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg,
3472 u8 * values, int len);
3473extern int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg,
3474 u8 addr, u8 * values, int len);
3475extern int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg,
3476 u8 * values, int len);
3477extern int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg,
3478 u8 pos, u8 len, u8 * value);
3479extern int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg,
3480 u8 pos, u8 len, u8 value);
3481extern int af9005_send_command(struct dvb_usb_device *d, u8 command,
3482 u8 * wbuf, int wlen, u8 * rbuf, int rlen);
3483extern int af9005_read_eeprom(struct dvb_usb_device *d, u8 address,
3484 u8 * values, int len);
3485extern int af9005_tuner_attach(struct dvb_usb_adapter *adap);
3486extern int af9005_led_control(struct dvb_usb_device *d, int onoff);
3487
3488extern u8 regmask[8];
3489
3490/* remote control decoder */
3491extern int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len,
3492 u32 * event, int *state);
3493extern struct rc_map_table rc_map_af9005_table[];
3494extern int rc_map_af9005_table_size;
3495
3496#endif
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
new file mode 100644
index 00000000000..d7ad05fc383
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -0,0 +1,1718 @@
1/*
2 * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * Thanks to Afatech who kindly provided information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#include <linux/hash.h>
25#include <linux/slab.h>
26
27#include "af9015.h"
28#include "af9013.h"
29#include "mt2060.h"
30#include "qt1010.h"
31#include "tda18271.h"
32#include "mxl5005s.h"
33#include "mc44s803.h"
34#include "tda18218.h"
35#include "mxl5007t.h"
36
37static int dvb_usb_af9015_debug;
38module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
39MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
40static int dvb_usb_af9015_remote;
41module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
42MODULE_PARM_DESC(remote, "select remote");
43DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
44
45static DEFINE_MUTEX(af9015_usb_mutex);
46
47static struct af9015_config af9015_config;
48static struct dvb_usb_device_properties af9015_properties[3];
49static int af9015_properties_count = ARRAY_SIZE(af9015_properties);
50
51static struct af9013_config af9015_af9013_config[] = {
52 {
53 .demod_address = AF9015_I2C_DEMOD,
54 .output_mode = AF9013_OUTPUT_MODE_USB,
55 .api_version = { 0, 1, 9, 0 },
56 .gpio[0] = AF9013_GPIO_HI,
57 .gpio[3] = AF9013_GPIO_TUNER_ON,
58
59 }, {
60 .output_mode = AF9013_OUTPUT_MODE_SERIAL,
61 .api_version = { 0, 1, 9, 0 },
62 .gpio[0] = AF9013_GPIO_TUNER_ON,
63 .gpio[1] = AF9013_GPIO_LO,
64 }
65};
66
67static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
68{
69#define BUF_LEN 63
70#define REQ_HDR_LEN 8 /* send header size */
71#define ACK_HDR_LEN 2 /* rece header size */
72 int act_len, ret;
73 u8 buf[BUF_LEN];
74 u8 write = 1;
75 u8 msg_len = REQ_HDR_LEN;
76 static u8 seq; /* packet sequence number */
77
78 if (mutex_lock_interruptible(&af9015_usb_mutex) < 0)
79 return -EAGAIN;
80
81 buf[0] = req->cmd;
82 buf[1] = seq++;
83 buf[2] = req->i2c_addr;
84 buf[3] = req->addr >> 8;
85 buf[4] = req->addr & 0xff;
86 buf[5] = req->mbox;
87 buf[6] = req->addr_len;
88 buf[7] = req->data_len;
89
90 switch (req->cmd) {
91 case GET_CONFIG:
92 case READ_MEMORY:
93 case RECONNECT_USB:
94 write = 0;
95 break;
96 case READ_I2C:
97 write = 0;
98 buf[2] |= 0x01; /* set I2C direction */
99 case WRITE_I2C:
100 buf[0] = READ_WRITE_I2C;
101 break;
102 case WRITE_MEMORY:
103 if (((req->addr & 0xff00) == 0xff00) ||
104 ((req->addr & 0xff00) == 0xae00))
105 buf[0] = WRITE_VIRTUAL_MEMORY;
106 case WRITE_VIRTUAL_MEMORY:
107 case COPY_FIRMWARE:
108 case DOWNLOAD_FIRMWARE:
109 case BOOT:
110 break;
111 default:
112 err("unknown command:%d", req->cmd);
113 ret = -1;
114 goto error_unlock;
115 }
116
117 /* buffer overflow check */
118 if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
119 (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
120 err("too much data; cmd:%d len:%d", req->cmd, req->data_len);
121 ret = -EINVAL;
122 goto error_unlock;
123 }
124
125 /* write requested */
126 if (write) {
127 memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
128 msg_len += req->data_len;
129 }
130
131 deb_xfer(">>> ");
132 debug_dump(buf, msg_len, deb_xfer);
133
134 /* send req */
135 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len,
136 &act_len, AF9015_USB_TIMEOUT);
137 if (ret)
138 err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len);
139 else
140 if (act_len != msg_len)
141 ret = -1; /* all data is not send */
142 if (ret)
143 goto error_unlock;
144
145 /* no ack for those packets */
146 if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
147 goto exit_unlock;
148
149 /* write receives seq + status = 2 bytes
150 read receives seq + status + data = 2 + N bytes */
151 msg_len = ACK_HDR_LEN;
152 if (!write)
153 msg_len += req->data_len;
154
155 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len,
156 &act_len, AF9015_USB_TIMEOUT);
157 if (ret) {
158 err("recv bulk message failed:%d", ret);
159 ret = -1;
160 goto error_unlock;
161 }
162
163 deb_xfer("<<< ");
164 debug_dump(buf, act_len, deb_xfer);
165
166 /* check status */
167 if (buf[1]) {
168 err("command failed:%d", buf[1]);
169 ret = -1;
170 goto error_unlock;
171 }
172
173 /* read request, copy returned data to return buf */
174 if (!write)
175 memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);
176
177error_unlock:
178exit_unlock:
179 mutex_unlock(&af9015_usb_mutex);
180
181 return ret;
182}
183
184static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
185{
186 return af9015_rw_udev(d->udev, req);
187}
188
189static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val,
190 u8 len)
191{
192 struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
193 val};
194 return af9015_ctrl_msg(d, &req);
195}
196
197static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
198{
199 return af9015_write_regs(d, addr, &val, 1);
200}
201
202static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len)
203{
204 struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
205 val};
206 return af9015_ctrl_msg(d, &req);
207}
208
209static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
210{
211 return af9015_read_regs(d, addr, val, 1);
212}
213
214static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
215 u8 val)
216{
217 struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val};
218
219 if (addr == af9015_af9013_config[0].demod_address ||
220 addr == af9015_af9013_config[1].demod_address)
221 req.addr_len = 3;
222
223 return af9015_ctrl_msg(d, &req);
224}
225
226static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
227 u8 *val)
228{
229 struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val};
230
231 if (addr == af9015_af9013_config[0].demod_address ||
232 addr == af9015_af9013_config[1].demod_address)
233 req.addr_len = 3;
234
235 return af9015_ctrl_msg(d, &req);
236}
237
238static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
239 int num)
240{
241 struct dvb_usb_device *d = i2c_get_adapdata(adap);
242 int ret = 0, i = 0;
243 u16 addr;
244 u8 uninitialized_var(mbox), addr_len;
245 struct req_t req;
246
247/* TODO: implement bus lock
248
249The bus lock is needed because there is two tuners both using same I2C-address.
250Due to that the only way to select correct tuner is use demodulator I2C-gate.
251
252................................................
253. AF9015 includes integrated AF9013 demodulator.
254. ____________ ____________ . ____________
255.| uC | | demod | . | tuner |
256.|------------| |------------| . |------------|
257.| AF9015 | | AF9013/5 | . | MXL5003 |
258.| |--+----I2C-------|-----/ -----|-.-----I2C-------| |
259.| | | | addr 0x38 | . | addr 0xc6 |
260.|____________| | |____________| . |____________|
261.................|..............................
262 | ____________ ____________
263 | | demod | | tuner |
264 | |------------| |------------|
265 | | AF9013 | | MXL5003 |
266 +----I2C-------|-----/ -----|-------I2C-------| |
267 | addr 0x3a | | addr 0xc6 |
268 |____________| |____________|
269*/
270 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
271 return -EAGAIN;
272
273 while (i < num) {
274 if (msg[i].addr == af9015_af9013_config[0].demod_address ||
275 msg[i].addr == af9015_af9013_config[1].demod_address) {
276 addr = msg[i].buf[0] << 8;
277 addr += msg[i].buf[1];
278 mbox = msg[i].buf[2];
279 addr_len = 3;
280 } else {
281 addr = msg[i].buf[0];
282 addr_len = 1;
283 /* mbox is don't care in that case */
284 }
285
286 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
287 if (msg[i].len > 3 || msg[i+1].len > 61) {
288 ret = -EOPNOTSUPP;
289 goto error;
290 }
291 if (msg[i].addr ==
292 af9015_af9013_config[0].demod_address)
293 req.cmd = READ_MEMORY;
294 else
295 req.cmd = READ_I2C;
296 req.i2c_addr = msg[i].addr;
297 req.addr = addr;
298 req.mbox = mbox;
299 req.addr_len = addr_len;
300 req.data_len = msg[i+1].len;
301 req.data = &msg[i+1].buf[0];
302 ret = af9015_ctrl_msg(d, &req);
303 i += 2;
304 } else if (msg[i].flags & I2C_M_RD) {
305 if (msg[i].len > 61) {
306 ret = -EOPNOTSUPP;
307 goto error;
308 }
309 if (msg[i].addr ==
310 af9015_af9013_config[0].demod_address) {
311 ret = -EINVAL;
312 goto error;
313 }
314 req.cmd = READ_I2C;
315 req.i2c_addr = msg[i].addr;
316 req.addr = addr;
317 req.mbox = mbox;
318 req.addr_len = addr_len;
319 req.data_len = msg[i].len;
320 req.data = &msg[i].buf[0];
321 ret = af9015_ctrl_msg(d, &req);
322 i += 1;
323 } else {
324 if (msg[i].len > 21) {
325 ret = -EOPNOTSUPP;
326 goto error;
327 }
328 if (msg[i].addr ==
329 af9015_af9013_config[0].demod_address)
330 req.cmd = WRITE_MEMORY;
331 else
332 req.cmd = WRITE_I2C;
333 req.i2c_addr = msg[i].addr;
334 req.addr = addr;
335 req.mbox = mbox;
336 req.addr_len = addr_len;
337 req.data_len = msg[i].len-addr_len;
338 req.data = &msg[i].buf[addr_len];
339 ret = af9015_ctrl_msg(d, &req);
340 i += 1;
341 }
342 if (ret)
343 goto error;
344
345 }
346 ret = i;
347
348error:
349 mutex_unlock(&d->i2c_mutex);
350
351 return ret;
352}
353
354static u32 af9015_i2c_func(struct i2c_adapter *adapter)
355{
356 return I2C_FUNC_I2C;
357}
358
359static struct i2c_algorithm af9015_i2c_algo = {
360 .master_xfer = af9015_i2c_xfer,
361 .functionality = af9015_i2c_func,
362};
363
364static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op)
365{
366 int ret;
367 u8 val, mask = 0x01;
368
369 ret = af9015_read_reg(d, addr, &val);
370 if (ret)
371 return ret;
372
373 mask <<= bit;
374 if (op) {
375 /* set bit */
376 val |= mask;
377 } else {
378 /* clear bit */
379 mask ^= 0xff;
380 val &= mask;
381 }
382
383 return af9015_write_reg(d, addr, val);
384}
385
386static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
387{
388 return af9015_do_reg_bit(d, addr, bit, 1);
389}
390
391static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
392{
393 return af9015_do_reg_bit(d, addr, bit, 0);
394}
395
396static int af9015_init_endpoint(struct dvb_usb_device *d)
397{
398 int ret;
399 u16 frame_size;
400 u8 packet_size;
401 deb_info("%s: USB speed:%d\n", __func__, d->udev->speed);
402
403 /* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0.
404 We use smaller - about 1/4 from the original, 5 and 87. */
405#define TS_PACKET_SIZE 188
406
407#define TS_USB20_PACKET_COUNT 87
408#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
409
410#define TS_USB11_PACKET_COUNT 5
411#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
412
413#define TS_USB20_MAX_PACKET_SIZE 512
414#define TS_USB11_MAX_PACKET_SIZE 64
415
416 if (d->udev->speed == USB_SPEED_FULL) {
417 frame_size = TS_USB11_FRAME_SIZE/4;
418 packet_size = TS_USB11_MAX_PACKET_SIZE/4;
419 } else {
420 frame_size = TS_USB20_FRAME_SIZE/4;
421 packet_size = TS_USB20_MAX_PACKET_SIZE/4;
422 }
423
424 ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */
425 if (ret)
426 goto error;
427 ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */
428 if (ret)
429 goto error;
430 ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */
431 if (ret)
432 goto error;
433 ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */
434 if (ret)
435 goto error;
436 ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */
437 if (ret)
438 goto error;
439 if (af9015_config.dual_mode) {
440 ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */
441 if (ret)
442 goto error;
443 }
444 ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */
445 if (ret)
446 goto error;
447 if (af9015_config.dual_mode) {
448 ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */
449 if (ret)
450 goto error;
451 }
452 /* EP4 xfer length */
453 ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff);
454 if (ret)
455 goto error;
456 ret = af9015_write_reg(d, 0xdd89, frame_size >> 8);
457 if (ret)
458 goto error;
459 /* EP5 xfer length */
460 ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff);
461 if (ret)
462 goto error;
463 ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8);
464 if (ret)
465 goto error;
466 ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */
467 if (ret)
468 goto error;
469 ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */
470 if (ret)
471 goto error;
472 ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */
473 if (ret)
474 goto error;
475 if (af9015_config.dual_mode) {
476 ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */
477 if (ret)
478 goto error;
479 }
480
481 /* enable / disable mp2if2 */
482 if (af9015_config.dual_mode)
483 ret = af9015_set_reg_bit(d, 0xd50b, 0);
484 else
485 ret = af9015_clear_reg_bit(d, 0xd50b, 0);
486
487error:
488 if (ret)
489 err("endpoint init failed:%d", ret);
490 return ret;
491}
492
493static int af9015_copy_firmware(struct dvb_usb_device *d)
494{
495 int ret;
496 u8 fw_params[4];
497 u8 val, i;
498 struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params),
499 fw_params };
500 deb_info("%s:\n", __func__);
501
502 fw_params[0] = af9015_config.firmware_size >> 8;
503 fw_params[1] = af9015_config.firmware_size & 0xff;
504 fw_params[2] = af9015_config.firmware_checksum >> 8;
505 fw_params[3] = af9015_config.firmware_checksum & 0xff;
506
507 /* wait 2nd demodulator ready */
508 msleep(100);
509
510 ret = af9015_read_reg_i2c(d,
511 af9015_af9013_config[1].demod_address, 0x98be, &val);
512 if (ret)
513 goto error;
514 else
515 deb_info("%s: firmware status:%02x\n", __func__, val);
516
517 if (val == 0x0c) /* fw is running, no need for download */
518 goto exit;
519
520 /* set I2C master clock to fast (to speed up firmware copy) */
521 ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */
522 if (ret)
523 goto error;
524
525 msleep(50);
526
527 /* copy firmware */
528 ret = af9015_ctrl_msg(d, &req);
529 if (ret)
530 err("firmware copy cmd failed:%d", ret);
531 deb_info("%s: firmware copy done\n", __func__);
532
533 /* set I2C master clock back to normal */
534 ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */
535 if (ret)
536 goto error;
537
538 /* request boot firmware */
539 ret = af9015_write_reg_i2c(d, af9015_af9013_config[1].demod_address,
540 0xe205, 1);
541 deb_info("%s: firmware boot cmd status:%d\n", __func__, ret);
542 if (ret)
543 goto error;
544
545 for (i = 0; i < 15; i++) {
546 msleep(100);
547
548 /* check firmware status */
549 ret = af9015_read_reg_i2c(d,
550 af9015_af9013_config[1].demod_address, 0x98be, &val);
551 deb_info("%s: firmware status cmd status:%d fw status:%02x\n",
552 __func__, ret, val);
553 if (ret)
554 goto error;
555
556 if (val == 0x0c || val == 0x04) /* success or fail */
557 break;
558 }
559
560 if (val == 0x04) {
561 err("firmware did not run");
562 ret = -1;
563 } else if (val != 0x0c) {
564 err("firmware boot timeout");
565 ret = -1;
566 }
567
568error:
569exit:
570 return ret;
571}
572
573/* hash (and dump) eeprom */
574static int af9015_eeprom_hash(struct usb_device *udev)
575{
576 static const unsigned int eeprom_size = 256;
577 unsigned int reg;
578 int ret;
579 u8 val, *eeprom;
580 struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
581
582 eeprom = kmalloc(eeprom_size, GFP_KERNEL);
583 if (eeprom == NULL)
584 return -ENOMEM;
585
586 for (reg = 0; reg < eeprom_size; reg++) {
587 req.addr = reg;
588 ret = af9015_rw_udev(udev, &req);
589 if (ret)
590 goto free;
591 eeprom[reg] = val;
592 }
593
594 if (dvb_usb_af9015_debug & 0x01)
595 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, eeprom,
596 eeprom_size);
597
598 BUG_ON(eeprom_size % 4);
599
600 af9015_config.eeprom_sum = 0;
601 for (reg = 0; reg < eeprom_size / sizeof(u32); reg++) {
602 af9015_config.eeprom_sum *= GOLDEN_RATIO_PRIME_32;
603 af9015_config.eeprom_sum += le32_to_cpu(((u32 *)eeprom)[reg]);
604 }
605
606 deb_info("%s: eeprom sum=%.8x\n", __func__, af9015_config.eeprom_sum);
607
608 ret = 0;
609free:
610 kfree(eeprom);
611 return ret;
612}
613
614static int af9015_init(struct dvb_usb_device *d)
615{
616 int ret;
617 deb_info("%s:\n", __func__);
618
619 /* init RC canary */
620 ret = af9015_write_reg(d, 0x98e9, 0xff);
621 if (ret)
622 goto error;
623
624 ret = af9015_init_endpoint(d);
625 if (ret)
626 goto error;
627
628error:
629 return ret;
630}
631
632static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
633{
634 int ret;
635 deb_info("%s: onoff:%d\n", __func__, onoff);
636
637 if (onoff)
638 ret = af9015_set_reg_bit(adap->dev, 0xd503, 0);
639 else
640 ret = af9015_clear_reg_bit(adap->dev, 0xd503, 0);
641
642 return ret;
643}
644
645static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
646 int onoff)
647{
648 int ret;
649 u8 idx;
650
651 deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n",
652 __func__, index, pid, onoff);
653
654 ret = af9015_write_reg(adap->dev, 0xd505, (pid & 0xff));
655 if (ret)
656 goto error;
657
658 ret = af9015_write_reg(adap->dev, 0xd506, (pid >> 8));
659 if (ret)
660 goto error;
661
662 idx = ((index & 0x1f) | (1 << 5));
663 ret = af9015_write_reg(adap->dev, 0xd504, idx);
664
665error:
666 return ret;
667}
668
669static int af9015_download_firmware(struct usb_device *udev,
670 const struct firmware *fw)
671{
672 int i, len, remaining, ret;
673 struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
674 u16 checksum = 0;
675
676 deb_info("%s:\n", __func__);
677
678 /* calc checksum */
679 for (i = 0; i < fw->size; i++)
680 checksum += fw->data[i];
681
682 af9015_config.firmware_size = fw->size;
683 af9015_config.firmware_checksum = checksum;
684
685 #define FW_ADDR 0x5100 /* firmware start address */
686 #define LEN_MAX 55 /* max packet size */
687 for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
688 len = remaining;
689 if (len > LEN_MAX)
690 len = LEN_MAX;
691
692 req.data_len = len;
693 req.data = (u8 *) &fw->data[fw->size - remaining];
694 req.addr = FW_ADDR + fw->size - remaining;
695
696 ret = af9015_rw_udev(udev, &req);
697 if (ret) {
698 err("firmware download failed:%d", ret);
699 goto error;
700 }
701 }
702
703 /* firmware loaded, request boot */
704 req.cmd = BOOT;
705 ret = af9015_rw_udev(udev, &req);
706 if (ret) {
707 err("firmware boot failed:%d", ret);
708 goto error;
709 }
710
711error:
712 return ret;
713}
714
715struct af9015_rc_setup {
716 unsigned int id;
717 char *rc_codes;
718};
719
720static char *af9015_rc_setup_match(unsigned int id,
721 const struct af9015_rc_setup *table)
722{
723 for (; table->rc_codes; table++)
724 if (table->id == id)
725 return table->rc_codes;
726 return NULL;
727}
728
729static const struct af9015_rc_setup af9015_rc_setup_modparam[] = {
730 { AF9015_REMOTE_A_LINK_DTU_M, RC_MAP_ALINK_DTU_M },
731 { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, RC_MAP_MSI_DIGIVOX_II },
732 { AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND },
733 { AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE },
734 { AF9015_REMOTE_AVERMEDIA_KS, RC_MAP_AVERMEDIA_RM_KS },
735 { }
736};
737
738static const struct af9015_rc_setup af9015_rc_setup_hashes[] = {
739 { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II },
740 { 0xa3703d00, RC_MAP_ALINK_DTU_M },
741 { 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */
742 { 0x5d49e3db, RC_MAP_DIGITTRADE }, /* LC-Power LC-USB-DVBT */
743 { }
744};
745
746static const struct af9015_rc_setup af9015_rc_setup_usbids[] = {
747 { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_RC,
748 RC_MAP_TERRATEC_SLIM_2 },
749 { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
750 RC_MAP_TERRATEC_SLIM },
751 { (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700,
752 RC_MAP_AZUREWAVE_AD_TU700 },
753 { (USB_VID_VISIONPLUS << 16) + USB_PID_TINYTWIN,
754 RC_MAP_AZUREWAVE_AD_TU700 },
755 { (USB_VID_MSI_2 << 16) + USB_PID_MSI_DIGI_VOX_MINI_III,
756 RC_MAP_MSI_DIGIVOX_III },
757 { (USB_VID_MSI_2 << 16) + USB_PID_MSI_DIGIVOX_DUO,
758 RC_MAP_MSI_DIGIVOX_III },
759 { (USB_VID_LEADTEK << 16) + USB_PID_WINFAST_DTV_DONGLE_GOLD,
760 RC_MAP_LEADTEK_Y04G0051 },
761 { (USB_VID_AVERMEDIA << 16) + USB_PID_AVERMEDIA_VOLAR_X,
762 RC_MAP_AVERMEDIA_M135A },
763 { (USB_VID_AFATECH << 16) + USB_PID_TREKSTOR_DVBT,
764 RC_MAP_TREKSTOR },
765 { (USB_VID_KWORLD_2 << 16) + USB_PID_TINYTWIN_2,
766 RC_MAP_DIGITALNOW_TINYTWIN },
767 { (USB_VID_GTEK << 16) + USB_PID_TINYTWIN_3,
768 RC_MAP_DIGITALNOW_TINYTWIN },
769 { (USB_VID_KWORLD_2 << 16) + USB_PID_SVEON_STV22,
770 RC_MAP_MSI_DIGIVOX_III },
771 { }
772};
773
774static void af9015_set_remote_config(struct usb_device *udev,
775 struct dvb_usb_device_properties *props)
776{
777 u16 vid = le16_to_cpu(udev->descriptor.idVendor);
778 u16 pid = le16_to_cpu(udev->descriptor.idProduct);
779
780 /* try to load remote based module param */
781 props->rc.core.rc_codes = af9015_rc_setup_match(
782 dvb_usb_af9015_remote, af9015_rc_setup_modparam);
783
784 /* try to load remote based eeprom hash */
785 if (!props->rc.core.rc_codes)
786 props->rc.core.rc_codes = af9015_rc_setup_match(
787 af9015_config.eeprom_sum, af9015_rc_setup_hashes);
788
789 /* try to load remote based USB ID */
790 if (!props->rc.core.rc_codes)
791 props->rc.core.rc_codes = af9015_rc_setup_match(
792 (vid << 16) + pid, af9015_rc_setup_usbids);
793
794 /* try to load remote based USB iManufacturer string */
795 if (!props->rc.core.rc_codes && vid == USB_VID_AFATECH) {
796 /* Check USB manufacturer and product strings and try
797 to determine correct remote in case of chip vendor
798 reference IDs are used.
799 DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */
800 char manufacturer[10];
801 memset(manufacturer, 0, sizeof(manufacturer));
802 usb_string(udev, udev->descriptor.iManufacturer,
803 manufacturer, sizeof(manufacturer));
804 if (!strcmp("MSI", manufacturer)) {
805 /* iManufacturer 1 MSI
806 iProduct 2 MSI K-VOX */
807 props->rc.core.rc_codes = af9015_rc_setup_match(
808 AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
809 af9015_rc_setup_modparam);
810 }
811 }
812
813 /* finally load "empty" just for leaving IR receiver enabled */
814 if (!props->rc.core.rc_codes)
815 props->rc.core.rc_codes = RC_MAP_EMPTY;
816
817 return;
818}
819
820static int af9015_read_config(struct usb_device *udev)
821{
822 int ret;
823 u8 val, i, offset = 0;
824 struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
825
826 /* IR remote controller */
827 req.addr = AF9015_EEPROM_IR_MODE;
828 /* first message will timeout often due to possible hw bug */
829 for (i = 0; i < 4; i++) {
830 ret = af9015_rw_udev(udev, &req);
831 if (!ret)
832 break;
833 }
834 if (ret)
835 goto error;
836
837 ret = af9015_eeprom_hash(udev);
838 if (ret)
839 goto error;
840
841 deb_info("%s: IR mode:%d\n", __func__, val);
842 for (i = 0; i < af9015_properties_count; i++) {
843 if (val == AF9015_IR_MODE_DISABLED)
844 af9015_properties[i].rc.core.rc_codes = NULL;
845 else
846 af9015_set_remote_config(udev, &af9015_properties[i]);
847 }
848
849 /* TS mode - one or two receivers */
850 req.addr = AF9015_EEPROM_TS_MODE;
851 ret = af9015_rw_udev(udev, &req);
852 if (ret)
853 goto error;
854 af9015_config.dual_mode = val;
855 deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode);
856
857 /* Set adapter0 buffer size according to USB port speed, adapter1 buffer
858 size can be static because it is enabled only USB2.0 */
859 for (i = 0; i < af9015_properties_count; i++) {
860 /* USB1.1 set smaller buffersize and disable 2nd adapter */
861 if (udev->speed == USB_SPEED_FULL) {
862 af9015_properties[i].adapter[0].stream.u.bulk.buffersize
863 = TS_USB11_FRAME_SIZE;
864 /* disable 2nd adapter because we don't have
865 PID-filters */
866 af9015_config.dual_mode = 0;
867 } else {
868 af9015_properties[i].adapter[0].stream.u.bulk.buffersize
869 = TS_USB20_FRAME_SIZE;
870 }
871 }
872
873 if (af9015_config.dual_mode) {
874 /* read 2nd demodulator I2C address */
875 req.addr = AF9015_EEPROM_DEMOD2_I2C;
876 ret = af9015_rw_udev(udev, &req);
877 if (ret)
878 goto error;
879 af9015_af9013_config[1].demod_address = val;
880
881 /* enable 2nd adapter */
882 for (i = 0; i < af9015_properties_count; i++)
883 af9015_properties[i].num_adapters = 2;
884
885 } else {
886 /* disable 2nd adapter */
887 for (i = 0; i < af9015_properties_count; i++)
888 af9015_properties[i].num_adapters = 1;
889 }
890
891 for (i = 0; i < af9015_properties[0].num_adapters; i++) {
892 if (i == 1)
893 offset = AF9015_EEPROM_OFFSET;
894 /* xtal */
895 req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset;
896 ret = af9015_rw_udev(udev, &req);
897 if (ret)
898 goto error;
899 switch (val) {
900 case 0:
901 af9015_af9013_config[i].adc_clock = 28800;
902 break;
903 case 1:
904 af9015_af9013_config[i].adc_clock = 20480;
905 break;
906 case 2:
907 af9015_af9013_config[i].adc_clock = 28000;
908 break;
909 case 3:
910 af9015_af9013_config[i].adc_clock = 25000;
911 break;
912 };
913 deb_info("%s: [%d] xtal:%d set adc_clock:%d\n", __func__, i,
914 val, af9015_af9013_config[i].adc_clock);
915
916 /* tuner IF */
917 req.addr = AF9015_EEPROM_IF1H + offset;
918 ret = af9015_rw_udev(udev, &req);
919 if (ret)
920 goto error;
921 af9015_af9013_config[i].tuner_if = val << 8;
922 req.addr = AF9015_EEPROM_IF1L + offset;
923 ret = af9015_rw_udev(udev, &req);
924 if (ret)
925 goto error;
926 af9015_af9013_config[i].tuner_if += val;
927 deb_info("%s: [%d] IF1:%d\n", __func__, i,
928 af9015_af9013_config[0].tuner_if);
929
930 /* MT2060 IF1 */
931 req.addr = AF9015_EEPROM_MT2060_IF1H + offset;
932 ret = af9015_rw_udev(udev, &req);
933 if (ret)
934 goto error;
935 af9015_config.mt2060_if1[i] = val << 8;
936 req.addr = AF9015_EEPROM_MT2060_IF1L + offset;
937 ret = af9015_rw_udev(udev, &req);
938 if (ret)
939 goto error;
940 af9015_config.mt2060_if1[i] += val;
941 deb_info("%s: [%d] MT2060 IF1:%d\n", __func__, i,
942 af9015_config.mt2060_if1[i]);
943
944 /* tuner */
945 req.addr = AF9015_EEPROM_TUNER_ID1 + offset;
946 ret = af9015_rw_udev(udev, &req);
947 if (ret)
948 goto error;
949 switch (val) {
950 case AF9013_TUNER_ENV77H11D5:
951 case AF9013_TUNER_MT2060:
952 case AF9013_TUNER_QT1010:
953 case AF9013_TUNER_UNKNOWN:
954 case AF9013_TUNER_MT2060_2:
955 case AF9013_TUNER_TDA18271:
956 case AF9013_TUNER_QT1010A:
957 case AF9013_TUNER_TDA18218:
958 af9015_af9013_config[i].rf_spec_inv = 1;
959 break;
960 case AF9013_TUNER_MXL5003D:
961 case AF9013_TUNER_MXL5005D:
962 case AF9013_TUNER_MXL5005R:
963 case AF9013_TUNER_MXL5007T:
964 af9015_af9013_config[i].rf_spec_inv = 0;
965 break;
966 case AF9013_TUNER_MC44S803:
967 af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
968 af9015_af9013_config[i].rf_spec_inv = 1;
969 break;
970 default:
971 warn("tuner id:%d not supported, please report!", val);
972 return -ENODEV;
973 };
974
975 af9015_af9013_config[i].tuner = val;
976 deb_info("%s: [%d] tuner id:%d\n", __func__, i, val);
977 }
978
979error:
980 if (ret)
981 err("eeprom read failed:%d", ret);
982
983 /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
984 content :-( Override some wrong values here. Ditto for the
985 AVerTV Red HD+ (A850T) device. */
986 if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
987 ((le16_to_cpu(udev->descriptor.idProduct) ==
988 USB_PID_AVERMEDIA_A850) ||
989 (le16_to_cpu(udev->descriptor.idProduct) ==
990 USB_PID_AVERMEDIA_A850T))) {
991 deb_info("%s: AverMedia A850: overriding config\n", __func__);
992 /* disable dual mode */
993 af9015_config.dual_mode = 0;
994 /* disable 2nd adapter */
995 for (i = 0; i < af9015_properties_count; i++)
996 af9015_properties[i].num_adapters = 1;
997
998 /* set correct IF */
999 af9015_af9013_config[0].tuner_if = 4570;
1000 }
1001
1002 return ret;
1003}
1004
1005static int af9015_identify_state(struct usb_device *udev,
1006 struct dvb_usb_device_properties *props,
1007 struct dvb_usb_device_description **desc,
1008 int *cold)
1009{
1010 int ret;
1011 u8 reply;
1012 struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply};
1013
1014 ret = af9015_rw_udev(udev, &req);
1015 if (ret)
1016 return ret;
1017
1018 deb_info("%s: reply:%02x\n", __func__, reply);
1019 if (reply == 0x02)
1020 *cold = 0;
1021 else
1022 *cold = 1;
1023
1024 return ret;
1025}
1026
1027static int af9015_rc_query(struct dvb_usb_device *d)
1028{
1029 struct af9015_state *priv = d->priv;
1030 int ret;
1031 u8 buf[17];
1032
1033 /* read registers needed to detect remote controller code */
1034 ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
1035 if (ret)
1036 goto error;
1037
1038 /* If any of these are non-zero, assume invalid data */
1039 if (buf[1] || buf[2] || buf[3])
1040 return ret;
1041
1042 /* Check for repeat of previous code */
1043 if ((priv->rc_repeat != buf[6] || buf[0]) &&
1044 !memcmp(&buf[12], priv->rc_last, 4)) {
1045 deb_rc("%s: key repeated\n", __func__);
1046 rc_keydown(d->rc_dev, priv->rc_keycode, 0);
1047 priv->rc_repeat = buf[6];
1048 return ret;
1049 }
1050
1051 /* Only process key if canary killed */
1052 if (buf[16] != 0xff && buf[0] != 0x01) {
1053 deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__,
1054 buf[12], buf[13], buf[14], buf[15]);
1055
1056 /* Reset the canary */
1057 ret = af9015_write_reg(d, 0x98e9, 0xff);
1058 if (ret)
1059 goto error;
1060
1061 /* Remember this key */
1062 memcpy(priv->rc_last, &buf[12], 4);
1063 if (buf[14] == (u8) ~buf[15]) {
1064 if (buf[12] == (u8) ~buf[13]) {
1065 /* NEC */
1066 priv->rc_keycode = buf[12] << 8 | buf[14];
1067 } else {
1068 /* NEC extended*/
1069 priv->rc_keycode = buf[12] << 16 |
1070 buf[13] << 8 | buf[14];
1071 }
1072 } else {
1073 /* 32 bit NEC */
1074 priv->rc_keycode = buf[12] << 24 | buf[13] << 16 |
1075 buf[14] << 8 | buf[15];
1076 }
1077 rc_keydown(d->rc_dev, priv->rc_keycode, 0);
1078 } else {
1079 deb_rc("%s: no key press\n", __func__);
1080 /* Invalidate last keypress */
1081 /* Not really needed, but helps with debug */
1082 priv->rc_last[2] = priv->rc_last[3];
1083 }
1084
1085 priv->rc_repeat = buf[6];
1086
1087error:
1088 if (ret)
1089 err("%s: failed:%d", __func__, ret);
1090
1091 return ret;
1092}
1093
1094static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
1095{
1096 int ret;
1097
1098 if (adap->id == 1) {
1099 /* copy firmware to 2nd demodulator */
1100 if (af9015_config.dual_mode) {
1101 ret = af9015_copy_firmware(adap->dev);
1102 if (ret) {
1103 err("firmware copy to 2nd frontend " \
1104 "failed, will disable it");
1105 af9015_config.dual_mode = 0;
1106 return -ENODEV;
1107 }
1108 } else {
1109 return -ENODEV;
1110 }
1111 }
1112
1113 /* attach demodulator */
1114 adap->fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id],
1115 &adap->dev->i2c_adap);
1116
1117 return adap->fe == NULL ? -ENODEV : 0;
1118}
1119
1120static struct mt2060_config af9015_mt2060_config = {
1121 .i2c_address = 0xc0,
1122 .clock_out = 0,
1123};
1124
1125static struct qt1010_config af9015_qt1010_config = {
1126 .i2c_address = 0xc4,
1127};
1128
1129static struct tda18271_config af9015_tda18271_config = {
1130 .gate = TDA18271_GATE_DIGITAL,
1131 .small_i2c = TDA18271_16_BYTE_CHUNK_INIT,
1132};
1133
1134static struct mxl5005s_config af9015_mxl5003_config = {
1135 .i2c_address = 0xc6,
1136 .if_freq = IF_FREQ_4570000HZ,
1137 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
1138 .agc_mode = MXL_SINGLE_AGC,
1139 .tracking_filter = MXL_TF_DEFAULT,
1140 .rssi_enable = MXL_RSSI_ENABLE,
1141 .cap_select = MXL_CAP_SEL_ENABLE,
1142 .div_out = MXL_DIV_OUT_4,
1143 .clock_out = MXL_CLOCK_OUT_DISABLE,
1144 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
1145 .top = MXL5005S_TOP_25P2,
1146 .mod_mode = MXL_DIGITAL_MODE,
1147 .if_mode = MXL_ZERO_IF,
1148 .AgcMasterByte = 0x00,
1149};
1150
1151static struct mxl5005s_config af9015_mxl5005_config = {
1152 .i2c_address = 0xc6,
1153 .if_freq = IF_FREQ_4570000HZ,
1154 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
1155 .agc_mode = MXL_SINGLE_AGC,
1156 .tracking_filter = MXL_TF_OFF,
1157 .rssi_enable = MXL_RSSI_ENABLE,
1158 .cap_select = MXL_CAP_SEL_ENABLE,
1159 .div_out = MXL_DIV_OUT_4,
1160 .clock_out = MXL_CLOCK_OUT_DISABLE,
1161 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
1162 .top = MXL5005S_TOP_25P2,
1163 .mod_mode = MXL_DIGITAL_MODE,
1164 .if_mode = MXL_ZERO_IF,
1165 .AgcMasterByte = 0x00,
1166};
1167
1168static struct mc44s803_config af9015_mc44s803_config = {
1169 .i2c_address = 0xc0,
1170 .dig_out = 1,
1171};
1172
1173static struct tda18218_config af9015_tda18218_config = {
1174 .i2c_address = 0xc0,
1175 .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */
1176};
1177
1178static struct mxl5007t_config af9015_mxl5007t_config = {
1179 .xtal_freq_hz = MxL_XTAL_24_MHZ,
1180 .if_freq_hz = MxL_IF_4_57_MHZ,
1181};
1182
1183static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
1184{
1185 int ret;
1186 deb_info("%s:\n", __func__);
1187
1188 switch (af9015_af9013_config[adap->id].tuner) {
1189 case AF9013_TUNER_MT2060:
1190 case AF9013_TUNER_MT2060_2:
1191 ret = dvb_attach(mt2060_attach, adap->fe, &adap->dev->i2c_adap,
1192 &af9015_mt2060_config,
1193 af9015_config.mt2060_if1[adap->id])
1194 == NULL ? -ENODEV : 0;
1195 break;
1196 case AF9013_TUNER_QT1010:
1197 case AF9013_TUNER_QT1010A:
1198 ret = dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap,
1199 &af9015_qt1010_config) == NULL ? -ENODEV : 0;
1200 break;
1201 case AF9013_TUNER_TDA18271:
1202 ret = dvb_attach(tda18271_attach, adap->fe, 0xc0,
1203 &adap->dev->i2c_adap,
1204 &af9015_tda18271_config) == NULL ? -ENODEV : 0;
1205 break;
1206 case AF9013_TUNER_TDA18218:
1207 ret = dvb_attach(tda18218_attach, adap->fe,
1208 &adap->dev->i2c_adap,
1209 &af9015_tda18218_config) == NULL ? -ENODEV : 0;
1210 break;
1211 case AF9013_TUNER_MXL5003D:
1212 ret = dvb_attach(mxl5005s_attach, adap->fe,
1213 &adap->dev->i2c_adap,
1214 &af9015_mxl5003_config) == NULL ? -ENODEV : 0;
1215 break;
1216 case AF9013_TUNER_MXL5005D:
1217 case AF9013_TUNER_MXL5005R:
1218 ret = dvb_attach(mxl5005s_attach, adap->fe,
1219 &adap->dev->i2c_adap,
1220 &af9015_mxl5005_config) == NULL ? -ENODEV : 0;
1221 break;
1222 case AF9013_TUNER_ENV77H11D5:
1223 ret = dvb_attach(dvb_pll_attach, adap->fe, 0xc0,
1224 &adap->dev->i2c_adap,
1225 DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
1226 break;
1227 case AF9013_TUNER_MC44S803:
1228 ret = dvb_attach(mc44s803_attach, adap->fe,
1229 &adap->dev->i2c_adap,
1230 &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
1231 break;
1232 case AF9013_TUNER_MXL5007T:
1233 ret = dvb_attach(mxl5007t_attach, adap->fe,
1234 &adap->dev->i2c_adap,
1235 0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0;
1236 break;
1237 case AF9013_TUNER_UNKNOWN:
1238 default:
1239 ret = -ENODEV;
1240 err("Unknown tuner id:%d",
1241 af9015_af9013_config[adap->id].tuner);
1242 }
1243 return ret;
1244}
1245
1246static struct usb_device_id af9015_usb_table[] = {
1247/* 0 */{USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)},
1248 {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)},
1249 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)},
1250 {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)},
1251 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)},
1252/* 5 */{USB_DEVICE(USB_VID_VISIONPLUS,
1253 USB_PID_TINYTWIN)},
1254 {USB_DEVICE(USB_VID_VISIONPLUS,
1255 USB_PID_AZUREWAVE_AD_TU700)},
1256 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)},
1257 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)},
1258 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)},
1259/* 10 */{USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)},
1260 {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)},
1261 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)},
1262 {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)},
1263 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
1264/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
1265 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)},
1266 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
1267 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3)},
1268 {USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT)},
1269/* 20 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850)},
1270 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805)},
1271 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU)},
1272 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810)},
1273 {USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03)},
1274/* 25 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2)},
1275 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T)},
1276 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20)},
1277 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2)},
1278 {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS)},
1279/* 30 */{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T)},
1280 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4)},
1281 {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M)},
1282 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC)},
1283 {USB_DEVICE(USB_VID_TERRATEC,
1284 USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)},
1285/* 35 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)},
1286 {USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)},
1287 {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22)},
1288 {0},
1289};
1290MODULE_DEVICE_TABLE(usb, af9015_usb_table);
1291
1292#define AF9015_RC_INTERVAL 500
1293static struct dvb_usb_device_properties af9015_properties[] = {
1294 {
1295 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1296
1297 .usb_ctrl = DEVICE_SPECIFIC,
1298 .download_firmware = af9015_download_firmware,
1299 .firmware = "dvb-usb-af9015.fw",
1300 .no_reconnect = 1,
1301
1302 .size_of_priv = sizeof(struct af9015_state),
1303
1304 .num_adapters = 2,
1305 .adapter = {
1306 {
1307 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1308 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1309
1310 .pid_filter_count = 32,
1311 .pid_filter = af9015_pid_filter,
1312 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1313
1314 .frontend_attach =
1315 af9015_af9013_frontend_attach,
1316 .tuner_attach = af9015_tuner_attach,
1317 .stream = {
1318 .type = USB_BULK,
1319 .count = 6,
1320 .endpoint = 0x84,
1321 },
1322 },
1323 {
1324 .frontend_attach =
1325 af9015_af9013_frontend_attach,
1326 .tuner_attach = af9015_tuner_attach,
1327 .stream = {
1328 .type = USB_BULK,
1329 .count = 6,
1330 .endpoint = 0x85,
1331 .u = {
1332 .bulk = {
1333 .buffersize =
1334 TS_USB20_FRAME_SIZE,
1335 }
1336 }
1337 },
1338 }
1339 },
1340
1341 .identify_state = af9015_identify_state,
1342
1343 .rc.core = {
1344 .protocol = RC_TYPE_NEC,
1345 .module_name = "af9015",
1346 .rc_query = af9015_rc_query,
1347 .rc_interval = AF9015_RC_INTERVAL,
1348 .allowed_protos = RC_TYPE_NEC,
1349 },
1350
1351 .i2c_algo = &af9015_i2c_algo,
1352
1353 .num_device_descs = 12, /* check max from dvb-usb.h */
1354 .devices = {
1355 {
1356 .name = "Afatech AF9015 DVB-T USB2.0 stick",
1357 .cold_ids = {&af9015_usb_table[0],
1358 &af9015_usb_table[1], NULL},
1359 .warm_ids = {NULL},
1360 },
1361 {
1362 .name = "Leadtek WinFast DTV Dongle Gold",
1363 .cold_ids = {&af9015_usb_table[2], NULL},
1364 .warm_ids = {NULL},
1365 },
1366 {
1367 .name = "Pinnacle PCTV 71e",
1368 .cold_ids = {&af9015_usb_table[3], NULL},
1369 .warm_ids = {NULL},
1370 },
1371 {
1372 .name = "KWorld PlusTV Dual DVB-T Stick " \
1373 "(DVB-T 399U)",
1374 .cold_ids = {&af9015_usb_table[4],
1375 &af9015_usb_table[25], NULL},
1376 .warm_ids = {NULL},
1377 },
1378 {
1379 .name = "DigitalNow TinyTwin DVB-T Receiver",
1380 .cold_ids = {&af9015_usb_table[5],
1381 &af9015_usb_table[28],
1382 &af9015_usb_table[36], NULL},
1383 .warm_ids = {NULL},
1384 },
1385 {
1386 .name = "TwinHan AzureWave AD-TU700(704J)",
1387 .cold_ids = {&af9015_usb_table[6], NULL},
1388 .warm_ids = {NULL},
1389 },
1390 {
1391 .name = "TerraTec Cinergy T USB XE",
1392 .cold_ids = {&af9015_usb_table[7], NULL},
1393 .warm_ids = {NULL},
1394 },
1395 {
1396 .name = "KWorld PlusTV Dual DVB-T PCI " \
1397 "(DVB-T PC160-2T)",
1398 .cold_ids = {&af9015_usb_table[8], NULL},
1399 .warm_ids = {NULL},
1400 },
1401 {
1402 .name = "AVerMedia AVerTV DVB-T Volar X",
1403 .cold_ids = {&af9015_usb_table[9], NULL},
1404 .warm_ids = {NULL},
1405 },
1406 {
1407 .name = "TerraTec Cinergy T Stick RC",
1408 .cold_ids = {&af9015_usb_table[33], NULL},
1409 .warm_ids = {NULL},
1410 },
1411 {
1412 .name = "TerraTec Cinergy T Stick Dual RC",
1413 .cold_ids = {&af9015_usb_table[34], NULL},
1414 .warm_ids = {NULL},
1415 },
1416 {
1417 .name = "AverMedia AVerTV Red HD+ (A850T)",
1418 .cold_ids = {&af9015_usb_table[35], NULL},
1419 .warm_ids = {NULL},
1420 },
1421 }
1422 }, {
1423 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1424
1425 .usb_ctrl = DEVICE_SPECIFIC,
1426 .download_firmware = af9015_download_firmware,
1427 .firmware = "dvb-usb-af9015.fw",
1428 .no_reconnect = 1,
1429
1430 .size_of_priv = sizeof(struct af9015_state),
1431
1432 .num_adapters = 2,
1433 .adapter = {
1434 {
1435 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1436 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1437
1438 .pid_filter_count = 32,
1439 .pid_filter = af9015_pid_filter,
1440 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1441
1442 .frontend_attach =
1443 af9015_af9013_frontend_attach,
1444 .tuner_attach = af9015_tuner_attach,
1445 .stream = {
1446 .type = USB_BULK,
1447 .count = 6,
1448 .endpoint = 0x84,
1449 },
1450 },
1451 {
1452 .frontend_attach =
1453 af9015_af9013_frontend_attach,
1454 .tuner_attach = af9015_tuner_attach,
1455 .stream = {
1456 .type = USB_BULK,
1457 .count = 6,
1458 .endpoint = 0x85,
1459 .u = {
1460 .bulk = {
1461 .buffersize =
1462 TS_USB20_FRAME_SIZE,
1463 }
1464 }
1465 },
1466 }
1467 },
1468
1469 .identify_state = af9015_identify_state,
1470
1471 .rc.core = {
1472 .protocol = RC_TYPE_NEC,
1473 .module_name = "af9015",
1474 .rc_query = af9015_rc_query,
1475 .rc_interval = AF9015_RC_INTERVAL,
1476 .allowed_protos = RC_TYPE_NEC,
1477 },
1478
1479 .i2c_algo = &af9015_i2c_algo,
1480
1481 .num_device_descs = 10, /* check max from dvb-usb.h */
1482 .devices = {
1483 {
1484 .name = "Xtensions XD-380",
1485 .cold_ids = {&af9015_usb_table[10], NULL},
1486 .warm_ids = {NULL},
1487 },
1488 {
1489 .name = "MSI DIGIVOX Duo",
1490 .cold_ids = {&af9015_usb_table[11], NULL},
1491 .warm_ids = {NULL},
1492 },
1493 {
1494 .name = "Fujitsu-Siemens Slim Mobile USB DVB-T",
1495 .cold_ids = {&af9015_usb_table[12], NULL},
1496 .warm_ids = {NULL},
1497 },
1498 {
1499 .name = "Telestar Starstick 2",
1500 .cold_ids = {&af9015_usb_table[13], NULL},
1501 .warm_ids = {NULL},
1502 },
1503 {
1504 .name = "AVerMedia A309",
1505 .cold_ids = {&af9015_usb_table[14], NULL},
1506 .warm_ids = {NULL},
1507 },
1508 {
1509 .name = "MSI Digi VOX mini III",
1510 .cold_ids = {&af9015_usb_table[15], NULL},
1511 .warm_ids = {NULL},
1512 },
1513 {
1514 .name = "KWorld USB DVB-T TV Stick II " \
1515 "(VS-DVB-T 395U)",
1516 .cold_ids = {&af9015_usb_table[16],
1517 &af9015_usb_table[17],
1518 &af9015_usb_table[18],
1519 &af9015_usb_table[31], NULL},
1520 .warm_ids = {NULL},
1521 },
1522 {
1523 .name = "TrekStor DVB-T USB Stick",
1524 .cold_ids = {&af9015_usb_table[19], NULL},
1525 .warm_ids = {NULL},
1526 },
1527 {
1528 .name = "AverMedia AVerTV Volar Black HD " \
1529 "(A850)",
1530 .cold_ids = {&af9015_usb_table[20], NULL},
1531 .warm_ids = {NULL},
1532 },
1533 {
1534 .name = "Sveon STV22 Dual USB DVB-T Tuner HDTV",
1535 .cold_ids = {&af9015_usb_table[37], NULL},
1536 .warm_ids = {NULL},
1537 },
1538 }
1539 }, {
1540 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1541
1542 .usb_ctrl = DEVICE_SPECIFIC,
1543 .download_firmware = af9015_download_firmware,
1544 .firmware = "dvb-usb-af9015.fw",
1545 .no_reconnect = 1,
1546
1547 .size_of_priv = sizeof(struct af9015_state),
1548
1549 .num_adapters = 2,
1550 .adapter = {
1551 {
1552 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1553 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1554
1555 .pid_filter_count = 32,
1556 .pid_filter = af9015_pid_filter,
1557 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1558
1559 .frontend_attach =
1560 af9015_af9013_frontend_attach,
1561 .tuner_attach = af9015_tuner_attach,
1562 .stream = {
1563 .type = USB_BULK,
1564 .count = 6,
1565 .endpoint = 0x84,
1566 },
1567 },
1568 {
1569 .frontend_attach =
1570 af9015_af9013_frontend_attach,
1571 .tuner_attach = af9015_tuner_attach,
1572 .stream = {
1573 .type = USB_BULK,
1574 .count = 6,
1575 .endpoint = 0x85,
1576 .u = {
1577 .bulk = {
1578 .buffersize =
1579 TS_USB20_FRAME_SIZE,
1580 }
1581 }
1582 },
1583 }
1584 },
1585
1586 .identify_state = af9015_identify_state,
1587
1588 .rc.core = {
1589 .protocol = RC_TYPE_NEC,
1590 .module_name = "af9015",
1591 .rc_query = af9015_rc_query,
1592 .rc_interval = AF9015_RC_INTERVAL,
1593 .allowed_protos = RC_TYPE_NEC,
1594 },
1595
1596 .i2c_algo = &af9015_i2c_algo,
1597
1598 .num_device_descs = 9, /* check max from dvb-usb.h */
1599 .devices = {
1600 {
1601 .name = "AverMedia AVerTV Volar GPS 805 (A805)",
1602 .cold_ids = {&af9015_usb_table[21], NULL},
1603 .warm_ids = {NULL},
1604 },
1605 {
1606 .name = "Conceptronic USB2.0 DVB-T CTVDIGRCU " \
1607 "V3.0",
1608 .cold_ids = {&af9015_usb_table[22], NULL},
1609 .warm_ids = {NULL},
1610 },
1611 {
1612 .name = "KWorld Digial MC-810",
1613 .cold_ids = {&af9015_usb_table[23], NULL},
1614 .warm_ids = {NULL},
1615 },
1616 {
1617 .name = "Genius TVGo DVB-T03",
1618 .cold_ids = {&af9015_usb_table[24], NULL},
1619 .warm_ids = {NULL},
1620 },
1621 {
1622 .name = "KWorld PlusTV DVB-T PCI Pro Card " \
1623 "(DVB-T PC160-T)",
1624 .cold_ids = {&af9015_usb_table[26], NULL},
1625 .warm_ids = {NULL},
1626 },
1627 {
1628 .name = "Sveon STV20 Tuner USB DVB-T HDTV",
1629 .cold_ids = {&af9015_usb_table[27], NULL},
1630 .warm_ids = {NULL},
1631 },
1632 {
1633 .name = "Leadtek WinFast DTV2000DS",
1634 .cold_ids = {&af9015_usb_table[29], NULL},
1635 .warm_ids = {NULL},
1636 },
1637 {
1638 .name = "KWorld USB DVB-T Stick Mobile " \
1639 "(UB383-T)",
1640 .cold_ids = {&af9015_usb_table[30], NULL},
1641 .warm_ids = {NULL},
1642 },
1643 {
1644 .name = "AverMedia AVerTV Volar M (A815Mac)",
1645 .cold_ids = {&af9015_usb_table[32], NULL},
1646 .warm_ids = {NULL},
1647 },
1648 }
1649 },
1650};
1651
1652static int af9015_usb_probe(struct usb_interface *intf,
1653 const struct usb_device_id *id)
1654{
1655 int ret = 0;
1656 struct dvb_usb_device *d = NULL;
1657 struct usb_device *udev = interface_to_usbdev(intf);
1658 u8 i;
1659
1660 deb_info("%s: interface:%d\n", __func__,
1661 intf->cur_altsetting->desc.bInterfaceNumber);
1662
1663 /* interface 0 is used by DVB-T receiver and
1664 interface 1 is for remote controller (HID) */
1665 if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
1666 ret = af9015_read_config(udev);
1667 if (ret)
1668 return ret;
1669
1670 for (i = 0; i < af9015_properties_count; i++) {
1671 ret = dvb_usb_device_init(intf, &af9015_properties[i],
1672 THIS_MODULE, &d, adapter_nr);
1673 if (!ret)
1674 break;
1675 if (ret != -ENODEV)
1676 return ret;
1677 }
1678 if (ret)
1679 return ret;
1680
1681 if (d)
1682 ret = af9015_init(d);
1683 }
1684
1685 return ret;
1686}
1687
1688/* usb specific object needed to register this driver with the usb subsystem */
1689static struct usb_driver af9015_usb_driver = {
1690 .name = "dvb_usb_af9015",
1691 .probe = af9015_usb_probe,
1692 .disconnect = dvb_usb_device_exit,
1693 .id_table = af9015_usb_table,
1694};
1695
1696/* module stuff */
1697static int __init af9015_usb_module_init(void)
1698{
1699 int ret;
1700 ret = usb_register(&af9015_usb_driver);
1701 if (ret)
1702 err("module init failed:%d", ret);
1703
1704 return ret;
1705}
1706
1707static void __exit af9015_usb_module_exit(void)
1708{
1709 /* deregister this driver from the USB subsystem */
1710 usb_deregister(&af9015_usb_driver);
1711}
1712
1713module_init(af9015_usb_module_init);
1714module_exit(af9015_usb_module_exit);
1715
1716MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1717MODULE_DESCRIPTION("Driver for Afatech AF9015 DVB-T");
1718MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
new file mode 100644
index 00000000000..6252ea6c190
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -0,0 +1,124 @@
1/*
2 * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * Thanks to Afatech who kindly provided information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#ifndef _DVB_USB_AF9015_H_
25#define _DVB_USB_AF9015_H_
26
27#define DVB_USB_LOG_PREFIX "af9015"
28#include "dvb-usb.h"
29
30#define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args)
31#define deb_rc(args...) dprintk(dvb_usb_af9015_debug, 0x02, args)
32#define deb_xfer(args...) dprintk(dvb_usb_af9015_debug, 0x04, args)
33#define deb_reg(args...) dprintk(dvb_usb_af9015_debug, 0x08, args)
34#define deb_i2c(args...) dprintk(dvb_usb_af9015_debug, 0x10, args)
35#define deb_fw(args...) dprintk(dvb_usb_af9015_debug, 0x20, args)
36
37#define AF9015_I2C_EEPROM 0xa0
38#define AF9015_I2C_DEMOD 0x38
39#define AF9015_USB_TIMEOUT 2000
40
41/* EEPROM locations */
42#define AF9015_EEPROM_IR_MODE 0x18
43#define AF9015_EEPROM_IR_REMOTE_TYPE 0x34
44#define AF9015_EEPROM_TS_MODE 0x31
45#define AF9015_EEPROM_DEMOD2_I2C 0x32
46
47#define AF9015_EEPROM_SAW_BW1 0x35
48#define AF9015_EEPROM_XTAL_TYPE1 0x36
49#define AF9015_EEPROM_SPEC_INV1 0x37
50#define AF9015_EEPROM_IF1L 0x38
51#define AF9015_EEPROM_IF1H 0x39
52#define AF9015_EEPROM_MT2060_IF1L 0x3a
53#define AF9015_EEPROM_MT2060_IF1H 0x3b
54#define AF9015_EEPROM_TUNER_ID1 0x3c
55
56#define AF9015_EEPROM_SAW_BW2 0x45
57#define AF9015_EEPROM_XTAL_TYPE2 0x46
58#define AF9015_EEPROM_SPEC_INV2 0x47
59#define AF9015_EEPROM_IF2L 0x48
60#define AF9015_EEPROM_IF2H 0x49
61#define AF9015_EEPROM_MT2060_IF2L 0x4a
62#define AF9015_EEPROM_MT2060_IF2H 0x4b
63#define AF9015_EEPROM_TUNER_ID2 0x4c
64
65#define AF9015_EEPROM_OFFSET (AF9015_EEPROM_SAW_BW2 - AF9015_EEPROM_SAW_BW1)
66
67struct req_t {
68 u8 cmd; /* [0] */
69 /* seq */ /* [1] */
70 u8 i2c_addr; /* [2] */
71 u16 addr; /* [3|4] */
72 u8 mbox; /* [5] */
73 u8 addr_len; /* [6] */
74 u8 data_len; /* [7] */
75 u8 *data;
76};
77
78enum af9015_cmd {
79 GET_CONFIG = 0x10,
80 DOWNLOAD_FIRMWARE = 0x11,
81 BOOT = 0x13,
82 READ_MEMORY = 0x20,
83 WRITE_MEMORY = 0x21,
84 READ_WRITE_I2C = 0x22,
85 COPY_FIRMWARE = 0x23,
86 RECONNECT_USB = 0x5a,
87 WRITE_VIRTUAL_MEMORY = 0x26,
88 GET_IR_CODE = 0x27,
89 READ_I2C,
90 WRITE_I2C,
91};
92
93enum af9015_ir_mode {
94 AF9015_IR_MODE_DISABLED = 0,
95 AF9015_IR_MODE_HID,
96 AF9015_IR_MODE_RLC,
97 AF9015_IR_MODE_RC6,
98 AF9015_IR_MODE_POLLING, /* just guess */
99};
100
101struct af9015_state {
102 u8 rc_repeat;
103 u32 rc_keycode;
104 u8 rc_last[4];
105};
106
107struct af9015_config {
108 u8 dual_mode:1;
109 u16 mt2060_if1[2];
110 u16 firmware_size;
111 u16 firmware_checksum;
112 u32 eeprom_sum;
113};
114
115enum af9015_remote {
116 AF9015_REMOTE_NONE = 0,
117/* 1 */ AF9015_REMOTE_A_LINK_DTU_M,
118 AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
119 AF9015_REMOTE_MYGICTV_U718,
120 AF9015_REMOTE_DIGITTRADE_DVB_T,
121/* 5 */ AF9015_REMOTE_AVERMEDIA_KS,
122};
123
124#endif
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
new file mode 100644
index 00000000000..2cbf19a52e3
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -0,0 +1,990 @@
1/*
2 * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * TODO:
21 * - add smart card reader support for Conditional Access (CA)
22 *
23 * Card reader in Anysee is nothing more than ISO 7816 card reader.
24 * There is no hardware CAM in any Anysee device sold.
25 * In my understanding it should be implemented by making own module
26 * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
27 * module registers serial interface that can be used to communicate
28 * with any ISO 7816 smart card.
29 *
30 * Any help according to implement serial smart card reader support
31 * is highly welcome!
32 */
33
34#include "anysee.h"
35#include "tda1002x.h"
36#include "mt352.h"
37#include "mt352_priv.h"
38#include "zl10353.h"
39#include "tda18212.h"
40#include "cx24116.h"
41#include "stv0900.h"
42#include "stv6110.h"
43#include "isl6423.h"
44
45/* debug */
46static int dvb_usb_anysee_debug;
47module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
48MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
49static int dvb_usb_anysee_delsys;
50module_param_named(delsys, dvb_usb_anysee_delsys, int, 0644);
51MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)");
52DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
53
54static DEFINE_MUTEX(anysee_usb_mutex);
55
56static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
57 u8 *rbuf, u8 rlen)
58{
59 struct anysee_state *state = d->priv;
60 int act_len, ret;
61 u8 buf[64];
62
63 memcpy(&buf[0], sbuf, slen);
64 buf[60] = state->seq++;
65
66 if (mutex_lock_interruptible(&anysee_usb_mutex) < 0)
67 return -EAGAIN;
68
69 /* We need receive one message more after dvb_usb_generic_rw due
70 to weird transaction flow, which is 1 x send + 2 x receive. */
71 ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);
72
73 if (!ret) {
74 /* receive 2nd answer */
75 ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
76 d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf),
77 &act_len, 2000);
78 if (ret)
79 err("%s: recv bulk message failed: %d", __func__, ret);
80 else {
81 deb_xfer("<<< ");
82 debug_dump(buf, act_len, deb_xfer);
83 }
84 }
85
86 /* read request, copy returned data to return buf */
87 if (!ret && rbuf && rlen)
88 memcpy(rbuf, buf, rlen);
89
90 mutex_unlock(&anysee_usb_mutex);
91
92 return ret;
93}
94
95static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
96{
97 u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
98 int ret;
99 ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
100 deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);
101 return ret;
102}
103
104static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
105{
106 u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
107 deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);
108 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
109}
110
111/* write single register with mask */
112static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val,
113 u8 mask)
114{
115 int ret;
116 u8 tmp;
117
118 /* no need for read if whole reg is written */
119 if (mask != 0xff) {
120 ret = anysee_read_reg(d, reg, &tmp);
121 if (ret)
122 return ret;
123
124 val &= mask;
125 tmp &= ~mask;
126 val |= tmp;
127 }
128
129 return anysee_write_reg(d, reg, val);
130}
131
132static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
133{
134 u8 buf[] = {CMD_GET_HW_INFO};
135 return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
136}
137
138static int anysee_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
139{
140 u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
141 deb_info("%s: onoff:%02x\n", __func__, onoff);
142 return anysee_ctrl_msg(adap->dev, buf, sizeof(buf), NULL, 0);
143}
144
145static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
146{
147 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
148 deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);
149 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
150}
151
152static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
153{
154 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
155 deb_info("%s: onoff:%02x\n", __func__, onoff);
156 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
157}
158
159static int anysee_init(struct dvb_usb_device *d)
160{
161 int ret;
162 /* LED light */
163 ret = anysee_led_ctrl(d, 0x01, 0x03);
164 if (ret)
165 return ret;
166
167 /* enable IR */
168 ret = anysee_ir_ctrl(d, 1);
169 if (ret)
170 return ret;
171
172 return 0;
173}
174
175/* I2C */
176static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
177 int num)
178{
179 struct dvb_usb_device *d = i2c_get_adapdata(adap);
180 int ret = 0, inc, i = 0;
181 u8 buf[52]; /* 4 + 48 (I2C WR USB command header + I2C WR max) */
182
183 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
184 return -EAGAIN;
185
186 while (i < num) {
187 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
188 if (msg[i].len > 2 || msg[i+1].len > 60) {
189 ret = -EOPNOTSUPP;
190 break;
191 }
192 buf[0] = CMD_I2C_READ;
193 buf[1] = (msg[i].addr << 1) | 0x01;
194 buf[2] = msg[i].buf[0];
195 buf[3] = msg[i].buf[1];
196 buf[4] = msg[i].len-1;
197 buf[5] = msg[i+1].len;
198 ret = anysee_ctrl_msg(d, buf, 6, msg[i+1].buf,
199 msg[i+1].len);
200 inc = 2;
201 } else {
202 if (msg[i].len > 48) {
203 ret = -EOPNOTSUPP;
204 break;
205 }
206 buf[0] = CMD_I2C_WRITE;
207 buf[1] = (msg[i].addr << 1);
208 buf[2] = msg[i].len;
209 buf[3] = 0x01;
210 memcpy(&buf[4], msg[i].buf, msg[i].len);
211 ret = anysee_ctrl_msg(d, buf, 4 + msg[i].len, NULL, 0);
212 inc = 1;
213 }
214 if (ret)
215 break;
216
217 i += inc;
218 }
219
220 mutex_unlock(&d->i2c_mutex);
221
222 return ret ? ret : i;
223}
224
225static u32 anysee_i2c_func(struct i2c_adapter *adapter)
226{
227 return I2C_FUNC_I2C;
228}
229
230static struct i2c_algorithm anysee_i2c_algo = {
231 .master_xfer = anysee_master_xfer,
232 .functionality = anysee_i2c_func,
233};
234
235static int anysee_mt352_demod_init(struct dvb_frontend *fe)
236{
237 static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x28 };
238 static u8 reset[] = { RESET, 0x80 };
239 static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 };
240 static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0x20 };
241 static u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 };
242 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
243
244 mt352_write(fe, clock_config, sizeof(clock_config));
245 udelay(200);
246 mt352_write(fe, reset, sizeof(reset));
247 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
248
249 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
250 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
251 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
252
253 return 0;
254}
255
256/* Callbacks for DVB USB */
257static struct tda10023_config anysee_tda10023_config = {
258 .demod_address = (0x1a >> 1),
259 .invert = 0,
260 .xtal = 16000000,
261 .pll_m = 11,
262 .pll_p = 3,
263 .pll_n = 1,
264 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
265 .deltaf = 0xfeeb,
266};
267
268static struct mt352_config anysee_mt352_config = {
269 .demod_address = (0x1e >> 1),
270 .demod_init = anysee_mt352_demod_init,
271};
272
273static struct zl10353_config anysee_zl10353_config = {
274 .demod_address = (0x1e >> 1),
275 .parallel_ts = 1,
276};
277
278static struct zl10353_config anysee_zl10353_tda18212_config2 = {
279 .demod_address = (0x1e >> 1),
280 .parallel_ts = 1,
281 .disable_i2c_gate_ctrl = 1,
282 .no_tuner = 1,
283 .if2 = 41500,
284};
285
286static struct zl10353_config anysee_zl10353_tda18212_config = {
287 .demod_address = (0x18 >> 1),
288 .parallel_ts = 1,
289 .disable_i2c_gate_ctrl = 1,
290 .no_tuner = 1,
291 .if2 = 41500,
292};
293
294static struct tda10023_config anysee_tda10023_tda18212_config = {
295 .demod_address = (0x1a >> 1),
296 .xtal = 16000000,
297 .pll_m = 12,
298 .pll_p = 3,
299 .pll_n = 1,
300 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
301 .deltaf = 0xba02,
302};
303
304static struct tda18212_config anysee_tda18212_config = {
305 .i2c_address = (0xc0 >> 1),
306 .if_dvbt_6 = 4150,
307 .if_dvbt_7 = 4150,
308 .if_dvbt_8 = 4150,
309 .if_dvbc = 5000,
310};
311
312static struct cx24116_config anysee_cx24116_config = {
313 .demod_address = (0xaa >> 1),
314 .mpg_clk_pos_pol = 0x00,
315 .i2c_wr_max = 48,
316};
317
318static struct stv0900_config anysee_stv0900_config = {
319 .demod_address = (0xd0 >> 1),
320 .demod_mode = 0,
321 .xtal = 8000000,
322 .clkmode = 3,
323 .diseqc_mode = 2,
324 .tun1_maddress = 0,
325 .tun1_adc = 1, /* 1 Vpp */
326 .path1_mode = 3,
327};
328
329static struct stv6110_config anysee_stv6110_config = {
330 .i2c_address = (0xc0 >> 1),
331 .mclk = 16000000,
332 .clk_div = 1,
333};
334
335static struct isl6423_config anysee_isl6423_config = {
336 .current_max = SEC_CURRENT_800m,
337 .curlim = SEC_CURRENT_LIM_OFF,
338 .mod_extern = 1,
339 .addr = (0x10 >> 1),
340};
341
342/*
343 * New USB device strings: Mfr=1, Product=2, SerialNumber=0
344 * Manufacturer: AMT.CO.KR
345 *
346 * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
347 * PCB: ?
348 * parts: DNOS404ZH102A(MT352, DTT7579(?))
349 *
350 * E30 VID=04b4 PID=861f HW=2 FW=2.1 "anysee-T(LP)"
351 * PCB: PCB 507T (rev1.61)
352 * parts: DNOS404ZH103A(ZL10353, DTT7579(?))
353 * OEA=0a OEB=00 OEC=00 OED=ff OEE=00
354 * IOA=45 IOB=ff IOC=00 IOD=ff IOE=00
355 *
356 * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
357 * PCB: 507CD (rev1.1)
358 * parts: DNOS404ZH103A(ZL10353, DTT7579(?)), CST56I01
359 * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
360 * IOA=4f IOB=ff IOC=00 IOD=06 IOE=01
361 * IOD[0] ZL10353 1=enabled
362 * IOA[7] TS 0=enabled
363 * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
364 *
365 * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
366 * PCB: 507DC (rev0.2)
367 * parts: TDA10023, DTOS403IH102B TM, CST56I01
368 * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
369 * IOA=4f IOB=ff IOC=00 IOD=26 IOE=01
370 * IOD[0] TDA10023 1=enabled
371 *
372 * E30 S2 Plus VID=04b4 PID=861f HW=11 FW=0.1 "anysee-S2(LP)"
373 * PCB: 507SI (rev2.1)
374 * parts: BS2N10WCC01(CX24116, CX24118), ISL6423, TDA8024
375 * OEA=80 OEB=00 OEC=ff OED=ff OEE=fe
376 * IOA=4d IOB=ff IOC=00 IOD=26 IOE=01
377 * IOD[0] CX24116 1=enabled
378 *
379 * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
380 * PCB: 507FA (rev0.4)
381 * parts: TDA10023, DTOS403IH102B TM, TDA8024
382 * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
383 * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
384 * IOD[5] TDA10023 1=enabled
385 * IOE[0] tuner 1=enabled
386 *
387 * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
388 * PCB: 507FA (rev1.1)
389 * parts: ZL10353, TDA10023, DTOS403IH102B TM, TDA8024
390 * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
391 * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
392 * DVB-C:
393 * IOD[5] TDA10023 1=enabled
394 * IOE[0] tuner 1=enabled
395 * DVB-T:
396 * IOD[0] ZL10353 1=enabled
397 * IOE[0] tuner 0=enabled
398 * tuner is behind ZL10353 I2C-gate
399 *
400 * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)"
401 * PCB: 508TC (rev0.6)
402 * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
403 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
404 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
405 * IOA[7] TS 1=enabled
406 * IOE[4] TDA18212 1=enabled
407 * DVB-C:
408 * IOD[6] ZL10353 0=disabled
409 * IOD[5] TDA10023 1=enabled
410 * IOE[0] IF 1=enabled
411 * DVB-T:
412 * IOD[5] TDA10023 0=disabled
413 * IOD[6] ZL10353 1=enabled
414 * IOE[0] IF 0=enabled
415 *
416 * E7 S2 VID=1c73 PID=861f HW=19 FW=0.4 AMTCI=0.5 "anysee-E7S2(LP)"
417 * PCB: 508S2 (rev0.7)
418 * parts: DNBU10512IST(STV0903, STV6110), ISL6423
419 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
420 * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
421 * IOA[7] TS 1=enabled
422 * IOE[5] STV0903 1=enabled
423 *
424 * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)"
425 * PCB: 508PTC (rev0.5)
426 * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
427 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
428 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
429 * IOA[7] TS 1=enabled
430 * IOE[4] TDA18212 1=enabled
431 * DVB-C:
432 * IOD[6] ZL10353 0=disabled
433 * IOD[5] TDA10023 1=enabled
434 * IOE[0] IF 1=enabled
435 * DVB-T:
436 * IOD[5] TDA10023 0=disabled
437 * IOD[6] ZL10353 1=enabled
438 * IOE[0] IF 0=enabled
439 *
440 * E7 S2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)"
441 * PCB: 508PS2 (rev0.4)
442 * parts: DNBU10512IST(STV0903, STV6110), ISL6423
443 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
444 * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
445 * IOA[7] TS 1=enabled
446 * IOE[5] STV0903 1=enabled
447 */
448
449static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
450{
451 int ret;
452 struct anysee_state *state = adap->dev->priv;
453 u8 hw_info[3];
454 u8 tmp;
455 struct i2c_msg msg[2] = {
456 {
457 .addr = anysee_tda18212_config.i2c_address,
458 .flags = 0,
459 .len = 1,
460 .buf = "\x00",
461 }, {
462 .addr = anysee_tda18212_config.i2c_address,
463 .flags = I2C_M_RD,
464 .len = 1,
465 .buf = &tmp,
466 }
467 };
468
469 /* Check which hardware we have.
470 * We must do this call two times to get reliable values (hw bug).
471 */
472 ret = anysee_get_hw_info(adap->dev, hw_info);
473 if (ret)
474 goto error;
475
476 ret = anysee_get_hw_info(adap->dev, hw_info);
477 if (ret)
478 goto error;
479
480 /* Meaning of these info bytes are guessed. */
481 info("firmware version:%d.%d hardware id:%d",
482 hw_info[1], hw_info[2], hw_info[0]);
483
484 state->hw = hw_info[0];
485
486 switch (state->hw) {
487 case ANYSEE_HW_507T: /* 2 */
488 /* E30 */
489
490 /* attach demod */
491 adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config,
492 &adap->dev->i2c_adap);
493 if (adap->fe)
494 break;
495
496 /* attach demod */
497 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
498 &adap->dev->i2c_adap);
499
500 break;
501 case ANYSEE_HW_507CD: /* 6 */
502 /* E30 Plus */
503
504 /* enable DVB-T demod on IOD[0] */
505 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
506 if (ret)
507 goto error;
508
509 /* enable transport stream on IOA[7] */
510 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (0 << 7), 0x80);
511 if (ret)
512 goto error;
513
514 /* attach demod */
515 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
516 &adap->dev->i2c_adap);
517
518 break;
519 case ANYSEE_HW_507DC: /* 10 */
520 /* E30 C Plus */
521
522 /* enable DVB-C demod on IOD[0] */
523 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
524 if (ret)
525 goto error;
526
527 /* attach demod */
528 adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config,
529 &adap->dev->i2c_adap, 0x48);
530
531 break;
532 case ANYSEE_HW_507SI: /* 11 */
533 /* E30 S2 Plus */
534
535 /* enable DVB-S/S2 demod on IOD[0] */
536 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
537 if (ret)
538 goto error;
539
540 /* attach demod */
541 adap->fe = dvb_attach(cx24116_attach, &anysee_cx24116_config,
542 &adap->dev->i2c_adap);
543
544 break;
545 case ANYSEE_HW_507FA: /* 15 */
546 /* E30 Combo Plus */
547 /* E30 C Plus */
548
549 /* enable tuner on IOE[4] */
550 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
551 if (ret)
552 goto error;
553
554 /* probe TDA18212 */
555 tmp = 0;
556 ret = i2c_transfer(&adap->dev->i2c_adap, msg, 2);
557 if (ret == 2 && tmp == 0xc7)
558 deb_info("%s: TDA18212 found\n", __func__);
559 else
560 tmp = 0;
561
562 /* disable tuner on IOE[4] */
563 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
564 if (ret)
565 goto error;
566
567 if (dvb_usb_anysee_delsys) {
568 /* disable DVB-C demod on IOD[5] */
569 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
570 0x20);
571 if (ret)
572 goto error;
573
574 /* enable DVB-T demod on IOD[0] */
575 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0),
576 0x01);
577 if (ret)
578 goto error;
579
580 /* attach demod */
581 if (tmp == 0xc7) {
582 /* TDA18212 config */
583 adap->fe = dvb_attach(zl10353_attach,
584 &anysee_zl10353_tda18212_config2,
585 &adap->dev->i2c_adap);
586 } else {
587 /* PLL config */
588 adap->fe = dvb_attach(zl10353_attach,
589 &anysee_zl10353_config,
590 &adap->dev->i2c_adap);
591 }
592 } else {
593 /* disable DVB-T demod on IOD[0] */
594 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0),
595 0x01);
596 if (ret)
597 goto error;
598
599 /* enable DVB-C demod on IOD[5] */
600 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
601 0x20);
602 if (ret)
603 goto error;
604
605 /* attach demod */
606 if (tmp == 0xc7) {
607 /* TDA18212 config */
608 adap->fe = dvb_attach(tda10023_attach,
609 &anysee_tda10023_tda18212_config,
610 &adap->dev->i2c_adap, 0x48);
611 } else {
612 /* PLL config */
613 adap->fe = dvb_attach(tda10023_attach,
614 &anysee_tda10023_config,
615 &adap->dev->i2c_adap, 0x48);
616 }
617 }
618
619 break;
620 case ANYSEE_HW_508TC: /* 18 */
621 case ANYSEE_HW_508PTC: /* 21 */
622 /* E7 TC */
623 /* E7 PTC */
624
625 /* enable transport stream on IOA[7] */
626 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
627 if (ret)
628 goto error;
629
630 if (dvb_usb_anysee_delsys) {
631 /* disable DVB-C demod on IOD[5] */
632 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
633 0x20);
634 if (ret)
635 goto error;
636
637 /* enable DVB-T demod on IOD[6] */
638 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6),
639 0x40);
640 if (ret)
641 goto error;
642
643 /* enable IF route on IOE[0] */
644 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
645 0x01);
646 if (ret)
647 goto error;
648
649 /* attach demod */
650 adap->fe = dvb_attach(zl10353_attach,
651 &anysee_zl10353_tda18212_config,
652 &adap->dev->i2c_adap);
653 } else {
654 /* disable DVB-T demod on IOD[6] */
655 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
656 0x40);
657 if (ret)
658 goto error;
659
660 /* enable DVB-C demod on IOD[5] */
661 ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
662 0x20);
663 if (ret)
664 goto error;
665
666 /* enable IF route on IOE[0] */
667 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
668 0x01);
669 if (ret)
670 goto error;
671
672 /* attach demod */
673 adap->fe = dvb_attach(tda10023_attach,
674 &anysee_tda10023_tda18212_config,
675 &adap->dev->i2c_adap, 0x48);
676 }
677
678 break;
679 case ANYSEE_HW_508S2: /* 19 */
680 case ANYSEE_HW_508PS2: /* 22 */
681 /* E7 S2 */
682 /* E7 PS2 */
683
684 /* enable transport stream on IOA[7] */
685 ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
686 if (ret)
687 goto error;
688
689 /* enable DVB-S/S2 demod on IOE[5] */
690 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
691 if (ret)
692 goto error;
693
694 /* attach demod */
695 adap->fe = dvb_attach(stv0900_attach, &anysee_stv0900_config,
696 &adap->dev->i2c_adap, 0);
697
698 break;
699 }
700
701 if (!adap->fe) {
702 /* we have no frontend :-( */
703 ret = -ENODEV;
704 err("Unsupported Anysee version. " \
705 "Please report the <linux-media@vger.kernel.org>.");
706 }
707error:
708 return ret;
709}
710
711static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
712{
713 struct anysee_state *state = adap->dev->priv;
714 struct dvb_frontend *fe;
715 int ret;
716 deb_info("%s:\n", __func__);
717
718 switch (state->hw) {
719 case ANYSEE_HW_507T: /* 2 */
720 /* E30 */
721
722 /* attach tuner */
723 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1),
724 NULL, DVB_PLL_THOMSON_DTT7579);
725
726 break;
727 case ANYSEE_HW_507CD: /* 6 */
728 /* E30 Plus */
729
730 /* attach tuner */
731 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1),
732 &adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579);
733
734 break;
735 case ANYSEE_HW_507DC: /* 10 */
736 /* E30 C Plus */
737
738 /* attach tuner */
739 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1),
740 &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
741
742 break;
743 case ANYSEE_HW_507SI: /* 11 */
744 /* E30 S2 Plus */
745
746 /* attach LNB controller */
747 fe = dvb_attach(isl6423_attach, adap->fe, &adap->dev->i2c_adap,
748 &anysee_isl6423_config);
749
750 break;
751 case ANYSEE_HW_507FA: /* 15 */
752 /* E30 Combo Plus */
753 /* E30 C Plus */
754
755 if (dvb_usb_anysee_delsys) {
756 /* enable DVB-T tuner on IOE[0] */
757 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
758 0x01);
759 if (ret)
760 goto error;
761 } else {
762 /* enable DVB-C tuner on IOE[0] */
763 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
764 0x01);
765 if (ret)
766 goto error;
767 }
768
769 /* Try first attach TDA18212 silicon tuner on IOE[4], if that
770 * fails attach old simple PLL. */
771
772 /* enable tuner on IOE[4] */
773 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
774 if (ret)
775 goto error;
776
777 /* attach tuner */
778 fe = dvb_attach(tda18212_attach, adap->fe, &adap->dev->i2c_adap,
779 &anysee_tda18212_config);
780 if (fe)
781 break;
782
783 /* disable tuner on IOE[4] */
784 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
785 if (ret)
786 goto error;
787
788 /* attach tuner */
789 fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1),
790 &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
791
792 break;
793 case ANYSEE_HW_508TC: /* 18 */
794 case ANYSEE_HW_508PTC: /* 21 */
795 /* E7 TC */
796 /* E7 PTC */
797
798 /* enable tuner on IOE[4] */
799 ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
800 if (ret)
801 goto error;
802
803 /* attach tuner */
804 fe = dvb_attach(tda18212_attach, adap->fe, &adap->dev->i2c_adap,
805 &anysee_tda18212_config);
806
807 break;
808 case ANYSEE_HW_508S2: /* 19 */
809 case ANYSEE_HW_508PS2: /* 22 */
810 /* E7 S2 */
811 /* E7 PS2 */
812
813 /* attach tuner */
814 fe = dvb_attach(stv6110_attach, adap->fe,
815 &anysee_stv6110_config, &adap->dev->i2c_adap);
816
817 if (fe) {
818 /* attach LNB controller */
819 fe = dvb_attach(isl6423_attach, adap->fe,
820 &adap->dev->i2c_adap, &anysee_isl6423_config);
821 }
822
823 break;
824 default:
825 fe = NULL;
826 }
827
828 if (fe)
829 ret = 0;
830 else
831 ret = -ENODEV;
832
833error:
834 return ret;
835}
836
837static int anysee_rc_query(struct dvb_usb_device *d)
838{
839 u8 buf[] = {CMD_GET_IR_CODE};
840 u8 ircode[2];
841 int ret;
842
843 /* Remote controller is basic NEC using address byte 0x08.
844 Anysee device RC query returns only two bytes, status and code,
845 address byte is dropped. Also it does not return any value for
846 NEC RCs having address byte other than 0x08. Due to that, we
847 cannot use that device as standard NEC receiver.
848 It could be possible make hack which reads whole code directly
849 from device memory... */
850
851 ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
852 if (ret)
853 return ret;
854
855 if (ircode[0]) {
856 deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
857 rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
858 }
859
860 return 0;
861}
862
863/* DVB USB Driver stuff */
864static struct dvb_usb_device_properties anysee_properties;
865
866static int anysee_probe(struct usb_interface *intf,
867 const struct usb_device_id *id)
868{
869 struct dvb_usb_device *d;
870 struct usb_host_interface *alt;
871 int ret;
872
873 /* There is one interface with two alternate settings.
874 Alternate setting 0 is for bulk transfer.
875 Alternate setting 1 is for isochronous transfer.
876 We use bulk transfer (alternate setting 0). */
877 if (intf->num_altsetting < 1)
878 return -ENODEV;
879
880 /*
881 * Anysee is always warm (its USB-bridge, Cypress FX2, uploads
882 * firmware from eeprom). If dvb_usb_device_init() succeeds that
883 * means d is a valid pointer.
884 */
885 ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d,
886 adapter_nr);
887 if (ret)
888 return ret;
889
890 alt = usb_altnum_to_altsetting(intf, 0);
891 if (alt == NULL) {
892 deb_info("%s: no alt found!\n", __func__);
893 return -ENODEV;
894 }
895
896 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
897 alt->desc.bAlternateSetting);
898 if (ret)
899 return ret;
900
901 return anysee_init(d);
902}
903
904static struct usb_device_id anysee_table[] = {
905 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
906 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
907 { } /* Terminating entry */
908};
909MODULE_DEVICE_TABLE(usb, anysee_table);
910
911static struct dvb_usb_device_properties anysee_properties = {
912 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
913
914 .usb_ctrl = DEVICE_SPECIFIC,
915
916 .size_of_priv = sizeof(struct anysee_state),
917
918 .num_adapters = 1,
919 .adapter = {
920 {
921 .streaming_ctrl = anysee_streaming_ctrl,
922 .frontend_attach = anysee_frontend_attach,
923 .tuner_attach = anysee_tuner_attach,
924 .stream = {
925 .type = USB_BULK,
926 .count = 8,
927 .endpoint = 0x82,
928 .u = {
929 .bulk = {
930 .buffersize = (16*512),
931 }
932 }
933 },
934 }
935 },
936
937 .rc.core = {
938 .rc_codes = RC_MAP_ANYSEE,
939 .protocol = RC_TYPE_OTHER,
940 .module_name = "anysee",
941 .rc_query = anysee_rc_query,
942 .rc_interval = 250, /* windows driver uses 500ms */
943 },
944
945 .i2c_algo = &anysee_i2c_algo,
946
947 .generic_bulk_ctrl_endpoint = 1,
948
949 .num_device_descs = 1,
950 .devices = {
951 {
952 .name = "Anysee DVB USB2.0",
953 .cold_ids = {NULL},
954 .warm_ids = {&anysee_table[0],
955 &anysee_table[1], NULL},
956 },
957 }
958};
959
960static struct usb_driver anysee_driver = {
961 .name = "dvb_usb_anysee",
962 .probe = anysee_probe,
963 .disconnect = dvb_usb_device_exit,
964 .id_table = anysee_table,
965};
966
967/* module stuff */
968static int __init anysee_module_init(void)
969{
970 int ret;
971
972 ret = usb_register(&anysee_driver);
973 if (ret)
974 err("%s: usb_register failed. Error number %d", __func__, ret);
975
976 return ret;
977}
978
979static void __exit anysee_module_exit(void)
980{
981 /* deregister this driver from the USB subsystem */
982 usb_deregister(&anysee_driver);
983}
984
985module_init(anysee_module_init);
986module_exit(anysee_module_exit);
987
988MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
989MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
990MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h
new file mode 100644
index 00000000000..ad6ccd1ea2d
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/anysee.h
@@ -0,0 +1,325 @@
1/*
2 * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * TODO:
21 * - add smart card reader support for Conditional Access (CA)
22 *
23 * Card reader in Anysee is nothing more than ISO 7816 card reader.
24 * There is no hardware CAM in any Anysee device sold.
25 * In my understanding it should be implemented by making own module
26 * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
27 * module registers serial interface that can be used to communicate
28 * with any ISO 7816 smart card.
29 *
30 * Any help according to implement serial smart card reader support
31 * is highly welcome!
32 */
33
34#ifndef _DVB_USB_ANYSEE_H_
35#define _DVB_USB_ANYSEE_H_
36
37#define DVB_USB_LOG_PREFIX "anysee"
38#include "dvb-usb.h"
39
40#define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args)
41#define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args)
42#define deb_rc(args...) dprintk(dvb_usb_anysee_debug, 0x04, args)
43#define deb_reg(args...) dprintk(dvb_usb_anysee_debug, 0x08, args)
44#define deb_i2c(args...) dprintk(dvb_usb_anysee_debug, 0x10, args)
45#define deb_fw(args...) dprintk(dvb_usb_anysee_debug, 0x20, args)
46
47enum cmd {
48 CMD_I2C_READ = 0x33,
49 CMD_I2C_WRITE = 0x31,
50 CMD_REG_READ = 0xb0,
51 CMD_REG_WRITE = 0xb1,
52 CMD_STREAMING_CTRL = 0x12,
53 CMD_LED_AND_IR_CTRL = 0x16,
54 CMD_GET_IR_CODE = 0x41,
55 CMD_GET_HW_INFO = 0x19,
56 CMD_SMARTCARD = 0x34,
57};
58
59struct anysee_state {
60 u8 hw; /* PCB ID */
61 u8 seq;
62};
63
64#define ANYSEE_HW_507T 2 /* E30 */
65#define ANYSEE_HW_507CD 6 /* E30 Plus */
66#define ANYSEE_HW_507DC 10 /* E30 C Plus */
67#define ANYSEE_HW_507SI 11 /* E30 S2 Plus */
68#define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */
69#define ANYSEE_HW_508TC 18 /* E7 TC */
70#define ANYSEE_HW_508S2 19 /* E7 S2 */
71#define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */
72#define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */
73
74#define REG_IOA 0x80 /* Port A (bit addressable) */
75#define REG_IOB 0x90 /* Port B (bit addressable) */
76#define REG_IOC 0xa0 /* Port C (bit addressable) */
77#define REG_IOD 0xb0 /* Port D (bit addressable) */
78#define REG_IOE 0xb1 /* Port E (NOT bit addressable) */
79#define REG_OEA 0xb2 /* Port A Output Enable */
80#define REG_OEB 0xb3 /* Port B Output Enable */
81#define REG_OEC 0xb4 /* Port C Output Enable */
82#define REG_OED 0xb5 /* Port D Output Enable */
83#define REG_OEE 0xb6 /* Port E Output Enable */
84
85#endif
86
87/***************************************************************************
88 * USB API description (reverse engineered)
89 ***************************************************************************
90
91Transaction flow:
92=================
93BULK[00001] >>> REQUEST PACKET 64 bytes
94BULK[00081] <<< REPLY PACKET #1 64 bytes (PREVIOUS TRANSACTION REPLY)
95BULK[00081] <<< REPLY PACKET #2 64 bytes (CURRENT TRANSACTION REPLY)
96
97General reply packet(s) are always used if not own reply defined.
98
99============================================================================
100| 00-63 | GENERAL REPLY PACKET #1 (PREVIOUS REPLY)
101============================================================================
102| 00 | reply data (if any) from previous transaction
103| | Just same reply packet as returned during previous transaction.
104| | Needed only if reply is missed in previous transaction.
105| | Just skip normally.
106----------------------------------------------------------------------------
107| 01-59 | don't care
108----------------------------------------------------------------------------
109| 60 | packet sequence number
110----------------------------------------------------------------------------
111| 61-63 | don't care
112----------------------------------------------------------------------------
113
114============================================================================
115| 00-63 | GENERAL REPLY PACKET #2 (CURRENT REPLY)
116============================================================================
117| 00 | reply data (if any)
118----------------------------------------------------------------------------
119| 01-59 | don't care
120----------------------------------------------------------------------------
121| 60 | packet sequence number
122----------------------------------------------------------------------------
123| 61-63 | don't care
124----------------------------------------------------------------------------
125
126============================================================================
127| 00-63 | I2C WRITE REQUEST PACKET
128============================================================================
129| 00 | 0x31 I2C write command
130----------------------------------------------------------------------------
131| 01 | i2c address
132----------------------------------------------------------------------------
133| 02 | data length
134| | 0x02 (for typical I2C reg / val pair)
135----------------------------------------------------------------------------
136| 03 | 0x01
137----------------------------------------------------------------------------
138| 04- | data
139----------------------------------------------------------------------------
140| -59 | don't care
141----------------------------------------------------------------------------
142| 60 | packet sequence number
143----------------------------------------------------------------------------
144| 61-63 | don't care
145----------------------------------------------------------------------------
146
147============================================================================
148| 00-63 | I2C READ REQUEST PACKET
149============================================================================
150| 00 | 0x33 I2C read command
151----------------------------------------------------------------------------
152| 01 | i2c address + 1
153----------------------------------------------------------------------------
154| 02 | register
155----------------------------------------------------------------------------
156| 03 | 0x00
157----------------------------------------------------------------------------
158| 04 | 0x00
159----------------------------------------------------------------------------
160| 05 | data length
161----------------------------------------------------------------------------
162| 06-59 | don't care
163----------------------------------------------------------------------------
164| 60 | packet sequence number
165----------------------------------------------------------------------------
166| 61-63 | don't care
167----------------------------------------------------------------------------
168
169============================================================================
170| 00-63 | USB CONTROLLER REGISTER WRITE REQUEST PACKET
171============================================================================
172| 00 | 0xb1 register write command
173----------------------------------------------------------------------------
174| 01-02 | register
175----------------------------------------------------------------------------
176| 03 | 0x01
177----------------------------------------------------------------------------
178| 04 | value
179----------------------------------------------------------------------------
180| 05-59 | don't care
181----------------------------------------------------------------------------
182| 60 | packet sequence number
183----------------------------------------------------------------------------
184| 61-63 | don't care
185----------------------------------------------------------------------------
186
187============================================================================
188| 00-63 | USB CONTROLLER REGISTER READ REQUEST PACKET
189============================================================================
190| 00 | 0xb0 register read command
191----------------------------------------------------------------------------
192| 01-02 | register
193----------------------------------------------------------------------------
194| 03 | 0x01
195----------------------------------------------------------------------------
196| 04-59 | don't care
197----------------------------------------------------------------------------
198| 60 | packet sequence number
199----------------------------------------------------------------------------
200| 61-63 | don't care
201----------------------------------------------------------------------------
202
203============================================================================
204| 00-63 | LED CONTROL REQUEST PACKET
205============================================================================
206| 00 | 0x16 LED and IR control command
207----------------------------------------------------------------------------
208| 01 | 0x01 (LED)
209----------------------------------------------------------------------------
210| 03 | 0x00 blink
211| | 0x01 lights continuously
212----------------------------------------------------------------------------
213| 04 | blink interval
214| | 0x00 fastest (looks like LED lights continuously)
215| | 0xff slowest
216----------------------------------------------------------------------------
217| 05-59 | don't care
218----------------------------------------------------------------------------
219| 60 | packet sequence number
220----------------------------------------------------------------------------
221| 61-63 | don't care
222----------------------------------------------------------------------------
223
224============================================================================
225| 00-63 | IR CONTROL REQUEST PACKET
226============================================================================
227| 00 | 0x16 LED and IR control command
228----------------------------------------------------------------------------
229| 01 | 0x02 (IR)
230----------------------------------------------------------------------------
231| 03 | 0x00 IR disabled
232| | 0x01 IR enabled
233----------------------------------------------------------------------------
234| 04-59 | don't care
235----------------------------------------------------------------------------
236| 60 | packet sequence number
237----------------------------------------------------------------------------
238| 61-63 | don't care
239----------------------------------------------------------------------------
240
241============================================================================
242| 00-63 | STREAMING CONTROL REQUEST PACKET
243============================================================================
244| 00 | 0x12 streaming control command
245----------------------------------------------------------------------------
246| 01 | 0x00 streaming disabled
247| | 0x01 streaming enabled
248----------------------------------------------------------------------------
249| 02 | 0x00
250----------------------------------------------------------------------------
251| 03-59 | don't care
252----------------------------------------------------------------------------
253| 60 | packet sequence number
254----------------------------------------------------------------------------
255| 61-63 | don't care
256----------------------------------------------------------------------------
257
258============================================================================
259| 00-63 | REMOTE CONTROL REQUEST PACKET
260============================================================================
261| 00 | 0x41 remote control command
262----------------------------------------------------------------------------
263| 01-59 | don't care
264----------------------------------------------------------------------------
265| 60 | packet sequence number
266----------------------------------------------------------------------------
267| 61-63 | don't care
268----------------------------------------------------------------------------
269
270============================================================================
271| 00-63 | REMOTE CONTROL REPLY PACKET
272============================================================================
273| 00 | 0x00 code not received
274| | 0x01 code received
275----------------------------------------------------------------------------
276| 01 | remote control code
277----------------------------------------------------------------------------
278| 02-59 | don't care
279----------------------------------------------------------------------------
280| 60 | packet sequence number
281----------------------------------------------------------------------------
282| 61-63 | don't care
283----------------------------------------------------------------------------
284
285============================================================================
286| 00-63 | GET HARDWARE INFO REQUEST PACKET
287============================================================================
288| 00 | 0x19 get hardware info command
289----------------------------------------------------------------------------
290| 01-59 | don't care
291----------------------------------------------------------------------------
292| 60 | packet sequence number
293----------------------------------------------------------------------------
294| 61-63 | don't care
295----------------------------------------------------------------------------
296
297============================================================================
298| 00-63 | GET HARDWARE INFO REPLY PACKET
299============================================================================
300| 00 | hardware id
301----------------------------------------------------------------------------
302| 01-02 | firmware version
303----------------------------------------------------------------------------
304| 03-59 | don't care
305----------------------------------------------------------------------------
306| 60 | packet sequence number
307----------------------------------------------------------------------------
308| 61-63 | don't care
309----------------------------------------------------------------------------
310
311============================================================================
312| 00-63 | SMART CARD READER PACKET
313============================================================================
314| 00 | 0x34 smart card reader command
315----------------------------------------------------------------------------
316| xx |
317----------------------------------------------------------------------------
318| xx-59 | don't care
319----------------------------------------------------------------------------
320| 60 | packet sequence number
321----------------------------------------------------------------------------
322| 61-63 | don't care
323----------------------------------------------------------------------------
324
325*/
diff --git a/drivers/media/dvb/dvb-usb/au6610.c b/drivers/media/dvb/dvb-usb/au6610.c
new file mode 100644
index 00000000000..2351077ff2b
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/au6610.c
@@ -0,0 +1,268 @@
1/*
2 * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
3 *
4 * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "au6610.h"
22#include "zl10353.h"
23#include "qt1010.h"
24
25/* debug */
26static int dvb_usb_au6610_debug;
27module_param_named(debug, dvb_usb_au6610_debug, int, 0644);
28MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
29DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
30
31static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
32 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
33{
34 int ret;
35 u16 index;
36 u8 *usb_buf;
37
38 /*
39 * allocate enough for all known requests,
40 * read returns 5 and write 6 bytes
41 */
42 usb_buf = kmalloc(6, GFP_KERNEL);
43 if (!usb_buf)
44 return -ENOMEM;
45
46 switch (wlen) {
47 case 1:
48 index = wbuf[0] << 8;
49 break;
50 case 2:
51 index = wbuf[0] << 8;
52 index += wbuf[1];
53 break;
54 default:
55 warn("wlen = %x, aborting.", wlen);
56 ret = -EINVAL;
57 goto error;
58 }
59
60 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
61 USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index,
62 usb_buf, 6, AU6610_USB_TIMEOUT);
63 if (ret < 0)
64 goto error;
65
66 switch (operation) {
67 case AU6610_REQ_I2C_READ:
68 case AU6610_REQ_USB_READ:
69 /* requested value is always 5th byte in buffer */
70 rbuf[0] = usb_buf[4];
71 }
72error:
73 kfree(usb_buf);
74 return ret;
75}
76
77static int au6610_i2c_msg(struct dvb_usb_device *d, u8 addr,
78 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
79{
80 u8 request;
81 u8 wo = (rbuf == NULL || rlen == 0); /* write-only */
82
83 if (wo) {
84 request = AU6610_REQ_I2C_WRITE;
85 } else { /* rw */
86 request = AU6610_REQ_I2C_READ;
87 }
88
89 return au6610_usb_msg(d, request, addr, wbuf, wlen, rbuf, rlen);
90}
91
92
93/* I2C */
94static int au6610_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
95 int num)
96{
97 struct dvb_usb_device *d = i2c_get_adapdata(adap);
98 int i;
99
100 if (num > 2)
101 return -EINVAL;
102
103 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
104 return -EAGAIN;
105
106 for (i = 0; i < num; i++) {
107 /* write/read request */
108 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
109 if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf,
110 msg[i].len, msg[i+1].buf,
111 msg[i+1].len) < 0)
112 break;
113 i++;
114 } else if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf,
115 msg[i].len, NULL, 0) < 0)
116 break;
117 }
118
119 mutex_unlock(&d->i2c_mutex);
120 return i;
121}
122
123
124static u32 au6610_i2c_func(struct i2c_adapter *adapter)
125{
126 return I2C_FUNC_I2C;
127}
128
129static struct i2c_algorithm au6610_i2c_algo = {
130 .master_xfer = au6610_i2c_xfer,
131 .functionality = au6610_i2c_func,
132};
133
134/* Callbacks for DVB USB */
135static struct zl10353_config au6610_zl10353_config = {
136 .demod_address = 0x0f,
137 .no_tuner = 1,
138 .parallel_ts = 1,
139};
140
141static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
142{
143 adap->fe = dvb_attach(zl10353_attach, &au6610_zl10353_config,
144 &adap->dev->i2c_adap);
145 if (adap->fe == NULL)
146 return -ENODEV;
147
148 return 0;
149}
150
151static struct qt1010_config au6610_qt1010_config = {
152 .i2c_address = 0x62
153};
154
155static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
156{
157 return dvb_attach(qt1010_attach,
158 adap->fe, &adap->dev->i2c_adap,
159 &au6610_qt1010_config) == NULL ? -ENODEV : 0;
160}
161
162/* DVB USB Driver stuff */
163static struct dvb_usb_device_properties au6610_properties;
164
165static int au6610_probe(struct usb_interface *intf,
166 const struct usb_device_id *id)
167{
168 struct dvb_usb_device *d;
169 struct usb_host_interface *alt;
170 int ret;
171
172 if (intf->num_altsetting < AU6610_ALTSETTING_COUNT)
173 return -ENODEV;
174
175 ret = dvb_usb_device_init(intf, &au6610_properties, THIS_MODULE, &d,
176 adapter_nr);
177 if (ret == 0) {
178 alt = usb_altnum_to_altsetting(intf, AU6610_ALTSETTING);
179
180 if (alt == NULL) {
181 deb_info("%s: no alt found!\n", __func__);
182 return -ENODEV;
183 }
184 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
185 alt->desc.bAlternateSetting);
186 }
187
188 return ret;
189}
190
191static struct usb_device_id au6610_table [] = {
192 { USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110) },
193 { } /* Terminating entry */
194};
195MODULE_DEVICE_TABLE(usb, au6610_table);
196
197static struct dvb_usb_device_properties au6610_properties = {
198 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
199
200 .usb_ctrl = DEVICE_SPECIFIC,
201
202 .size_of_priv = 0,
203
204 .num_adapters = 1,
205 .adapter = {
206 {
207 .frontend_attach = au6610_zl10353_frontend_attach,
208 .tuner_attach = au6610_qt1010_tuner_attach,
209
210 .stream = {
211 .type = USB_ISOC,
212 .count = 5,
213 .endpoint = 0x82,
214 .u = {
215 .isoc = {
216 .framesperurb = 40,
217 .framesize = 942,
218 .interval = 1,
219 }
220 }
221 },
222 }
223 },
224
225 .i2c_algo = &au6610_i2c_algo,
226
227 .num_device_descs = 1,
228 .devices = {
229 {
230 .name = "Sigmatek DVB-110 DVB-T USB2.0",
231 .cold_ids = {NULL},
232 .warm_ids = {&au6610_table[0], NULL},
233 },
234 }
235};
236
237static struct usb_driver au6610_driver = {
238 .name = "dvb_usb_au6610",
239 .probe = au6610_probe,
240 .disconnect = dvb_usb_device_exit,
241 .id_table = au6610_table,
242};
243
244/* module stuff */
245static int __init au6610_module_init(void)
246{
247 int ret;
248
249 ret = usb_register(&au6610_driver);
250 if (ret)
251 err("usb_register failed. Error number %d", ret);
252
253 return ret;
254}
255
256static void __exit au6610_module_exit(void)
257{
258 /* deregister this driver from the USB subsystem */
259 usb_deregister(&au6610_driver);
260}
261
262module_init(au6610_module_init);
263module_exit(au6610_module_exit);
264
265MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
266MODULE_DESCRIPTION("Driver for Alcor Micro AU6610 DVB-T USB2.0");
267MODULE_VERSION("0.1");
268MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/au6610.h b/drivers/media/dvb/dvb-usb/au6610.h
new file mode 100644
index 00000000000..7849abe2c61
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/au6610.h
@@ -0,0 +1,39 @@
1/*
2 * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
3 *
4 * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef _DVB_USB_AU6610_H_
22#define _DVB_USB_AU6610_H_
23
24#define DVB_USB_LOG_PREFIX "au6610"
25#include "dvb-usb.h"
26
27#define deb_info(args...) dprintk(dvb_usb_au6610_debug, 0x01, args)
28
29#define AU6610_REQ_I2C_WRITE 0x14
30#define AU6610_REQ_I2C_READ 0x13
31#define AU6610_REQ_USB_WRITE 0x16
32#define AU6610_REQ_USB_READ 0x15
33
34#define AU6610_USB_TIMEOUT 1000
35
36#define AU6610_ALTSETTING_COUNT 6
37#define AU6610_ALTSETTING 5
38
39#endif
diff --git a/drivers/media/dvb/dvb-usb/az6027.c b/drivers/media/dvb/dvb-usb/az6027.c
new file mode 100644
index 00000000000..57e2444d51a
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/az6027.c
@@ -0,0 +1,1203 @@
1/* DVB USB compliant Linux driver for the AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)
2 * receiver.
3 *
4 * Copyright (C) 2009 Adams.Xu <adams.xu@azwave.com.cn>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "az6027.h"
13
14#include "stb0899_drv.h"
15#include "stb0899_reg.h"
16#include "stb0899_cfg.h"
17
18#include "stb6100.h"
19#include "stb6100_cfg.h"
20#include "dvb_ca_en50221.h"
21
22int dvb_usb_az6027_debug;
23module_param_named(debug, dvb_usb_az6027_debug, int, 0644);
24MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
25
26DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
27
28struct az6027_device_state {
29 struct dvb_ca_en50221 ca;
30 struct mutex ca_mutex;
31 u8 power_state;
32};
33
34static const struct stb0899_s1_reg az6027_stb0899_s1_init_1[] = {
35
36 /* 0x0000000b, SYSREG */
37 { STB0899_DEV_ID , 0x30 },
38 { STB0899_DISCNTRL1 , 0x32 },
39 { STB0899_DISCNTRL2 , 0x80 },
40 { STB0899_DISRX_ST0 , 0x04 },
41 { STB0899_DISRX_ST1 , 0x00 },
42 { STB0899_DISPARITY , 0x00 },
43 { STB0899_DISFIFO , 0x00 },
44 { STB0899_DISSTATUS , 0x20 },
45 { STB0899_DISF22 , 0x99 },
46 { STB0899_DISF22RX , 0xa8 },
47 /* SYSREG ? */
48 { STB0899_ACRPRESC , 0x11 },
49 { STB0899_ACRDIV1 , 0x0a },
50 { STB0899_ACRDIV2 , 0x05 },
51 { STB0899_DACR1 , 0x00 },
52 { STB0899_DACR2 , 0x00 },
53 { STB0899_OUTCFG , 0x00 },
54 { STB0899_MODECFG , 0x00 },
55 { STB0899_IRQSTATUS_3 , 0xfe },
56 { STB0899_IRQSTATUS_2 , 0x03 },
57 { STB0899_IRQSTATUS_1 , 0x7c },
58 { STB0899_IRQSTATUS_0 , 0xf4 },
59 { STB0899_IRQMSK_3 , 0xf3 },
60 { STB0899_IRQMSK_2 , 0xfc },
61 { STB0899_IRQMSK_1 , 0xff },
62 { STB0899_IRQMSK_0 , 0xff },
63 { STB0899_IRQCFG , 0x00 },
64 { STB0899_I2CCFG , 0x88 },
65 { STB0899_I2CRPT , 0x58 },
66 { STB0899_IOPVALUE5 , 0x00 },
67 { STB0899_IOPVALUE4 , 0x33 },
68 { STB0899_IOPVALUE3 , 0x6d },
69 { STB0899_IOPVALUE2 , 0x90 },
70 { STB0899_IOPVALUE1 , 0x60 },
71 { STB0899_IOPVALUE0 , 0x00 },
72 { STB0899_GPIO00CFG , 0x82 },
73 { STB0899_GPIO01CFG , 0x82 },
74 { STB0899_GPIO02CFG , 0x82 },
75 { STB0899_GPIO03CFG , 0x82 },
76 { STB0899_GPIO04CFG , 0x82 },
77 { STB0899_GPIO05CFG , 0x82 },
78 { STB0899_GPIO06CFG , 0x82 },
79 { STB0899_GPIO07CFG , 0x82 },
80 { STB0899_GPIO08CFG , 0x82 },
81 { STB0899_GPIO09CFG , 0x82 },
82 { STB0899_GPIO10CFG , 0x82 },
83 { STB0899_GPIO11CFG , 0x82 },
84 { STB0899_GPIO12CFG , 0x82 },
85 { STB0899_GPIO13CFG , 0x82 },
86 { STB0899_GPIO14CFG , 0x82 },
87 { STB0899_GPIO15CFG , 0x82 },
88 { STB0899_GPIO16CFG , 0x82 },
89 { STB0899_GPIO17CFG , 0x82 },
90 { STB0899_GPIO18CFG , 0x82 },
91 { STB0899_GPIO19CFG , 0x82 },
92 { STB0899_GPIO20CFG , 0x82 },
93 { STB0899_SDATCFG , 0xb8 },
94 { STB0899_SCLTCFG , 0xba },
95 { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
96 { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
97 { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
98 { STB0899_DIRCLKCFG , 0x82 },
99 { STB0899_CLKOUT27CFG , 0x7e },
100 { STB0899_STDBYCFG , 0x82 },
101 { STB0899_CS0CFG , 0x82 },
102 { STB0899_CS1CFG , 0x82 },
103 { STB0899_DISEQCOCFG , 0x20 },
104 { STB0899_GPIO32CFG , 0x82 },
105 { STB0899_GPIO33CFG , 0x82 },
106 { STB0899_GPIO34CFG , 0x82 },
107 { STB0899_GPIO35CFG , 0x82 },
108 { STB0899_GPIO36CFG , 0x82 },
109 { STB0899_GPIO37CFG , 0x82 },
110 { STB0899_GPIO38CFG , 0x82 },
111 { STB0899_GPIO39CFG , 0x82 },
112 { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
113 { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
114 { STB0899_FILTCTRL , 0x00 },
115 { STB0899_SYSCTRL , 0x01 },
116 { STB0899_STOPCLK1 , 0x20 },
117 { STB0899_STOPCLK2 , 0x00 },
118 { STB0899_INTBUFSTATUS , 0x00 },
119 { STB0899_INTBUFCTRL , 0x0a },
120 { 0xffff , 0xff },
121};
122
123static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
124 { STB0899_DEMOD , 0x00 },
125 { STB0899_RCOMPC , 0xc9 },
126 { STB0899_AGC1CN , 0x01 },
127 { STB0899_AGC1REF , 0x10 },
128 { STB0899_RTC , 0x23 },
129 { STB0899_TMGCFG , 0x4e },
130 { STB0899_AGC2REF , 0x34 },
131 { STB0899_TLSR , 0x84 },
132 { STB0899_CFD , 0xf7 },
133 { STB0899_ACLC , 0x87 },
134 { STB0899_BCLC , 0x94 },
135 { STB0899_EQON , 0x41 },
136 { STB0899_LDT , 0xf1 },
137 { STB0899_LDT2 , 0xe3 },
138 { STB0899_EQUALREF , 0xb4 },
139 { STB0899_TMGRAMP , 0x10 },
140 { STB0899_TMGTHD , 0x30 },
141 { STB0899_IDCCOMP , 0xfd },
142 { STB0899_QDCCOMP , 0xff },
143 { STB0899_POWERI , 0x0c },
144 { STB0899_POWERQ , 0x0f },
145 { STB0899_RCOMP , 0x6c },
146 { STB0899_AGCIQIN , 0x80 },
147 { STB0899_AGC2I1 , 0x06 },
148 { STB0899_AGC2I2 , 0x00 },
149 { STB0899_TLIR , 0x30 },
150 { STB0899_RTF , 0x7f },
151 { STB0899_DSTATUS , 0x00 },
152 { STB0899_LDI , 0xbc },
153 { STB0899_CFRM , 0xea },
154 { STB0899_CFRL , 0x31 },
155 { STB0899_NIRM , 0x2b },
156 { STB0899_NIRL , 0x80 },
157 { STB0899_ISYMB , 0x1d },
158 { STB0899_QSYMB , 0xa6 },
159 { STB0899_SFRH , 0x2f },
160 { STB0899_SFRM , 0x68 },
161 { STB0899_SFRL , 0x40 },
162 { STB0899_SFRUPH , 0x2f },
163 { STB0899_SFRUPM , 0x68 },
164 { STB0899_SFRUPL , 0x40 },
165 { STB0899_EQUAI1 , 0x02 },
166 { STB0899_EQUAQ1 , 0xff },
167 { STB0899_EQUAI2 , 0x04 },
168 { STB0899_EQUAQ2 , 0x05 },
169 { STB0899_EQUAI3 , 0x02 },
170 { STB0899_EQUAQ3 , 0xfd },
171 { STB0899_EQUAI4 , 0x03 },
172 { STB0899_EQUAQ4 , 0x07 },
173 { STB0899_EQUAI5 , 0x08 },
174 { STB0899_EQUAQ5 , 0xf5 },
175 { STB0899_DSTATUS2 , 0x00 },
176 { STB0899_VSTATUS , 0x00 },
177 { STB0899_VERROR , 0x86 },
178 { STB0899_IQSWAP , 0x2a },
179 { STB0899_ECNT1M , 0x00 },
180 { STB0899_ECNT1L , 0x00 },
181 { STB0899_ECNT2M , 0x00 },
182 { STB0899_ECNT2L , 0x00 },
183 { STB0899_ECNT3M , 0x0a },
184 { STB0899_ECNT3L , 0xad },
185 { STB0899_FECAUTO1 , 0x06 },
186 { STB0899_FECM , 0x01 },
187 { STB0899_VTH12 , 0xb0 },
188 { STB0899_VTH23 , 0x7a },
189 { STB0899_VTH34 , 0x58 },
190 { STB0899_VTH56 , 0x38 },
191 { STB0899_VTH67 , 0x34 },
192 { STB0899_VTH78 , 0x24 },
193 { STB0899_PRVIT , 0xff },
194 { STB0899_VITSYNC , 0x19 },
195 { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
196 { STB0899_TSULC , 0x42 },
197 { STB0899_RSLLC , 0x41 },
198 { STB0899_TSLPL , 0x12 },
199 { STB0899_TSCFGH , 0x0c },
200 { STB0899_TSCFGM , 0x00 },
201 { STB0899_TSCFGL , 0x00 },
202 { STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */
203 { STB0899_RSSYNCDEL , 0x00 },
204 { STB0899_TSINHDELH , 0x02 },
205 { STB0899_TSINHDELM , 0x00 },
206 { STB0899_TSINHDELL , 0x00 },
207 { STB0899_TSLLSTKM , 0x1b },
208 { STB0899_TSLLSTKL , 0xb3 },
209 { STB0899_TSULSTKM , 0x00 },
210 { STB0899_TSULSTKL , 0x00 },
211 { STB0899_PCKLENUL , 0xbc },
212 { STB0899_PCKLENLL , 0xcc },
213 { STB0899_RSPCKLEN , 0xbd },
214 { STB0899_TSSTATUS , 0x90 },
215 { STB0899_ERRCTRL1 , 0xb6 },
216 { STB0899_ERRCTRL2 , 0x95 },
217 { STB0899_ERRCTRL3 , 0x8d },
218 { STB0899_DMONMSK1 , 0x27 },
219 { STB0899_DMONMSK0 , 0x03 },
220 { STB0899_DEMAPVIT , 0x5c },
221 { STB0899_PLPARM , 0x19 },
222 { STB0899_PDELCTRL , 0x48 },
223 { STB0899_PDELCTRL2 , 0x00 },
224 { STB0899_BBHCTRL1 , 0x00 },
225 { STB0899_BBHCTRL2 , 0x00 },
226 { STB0899_HYSTTHRESH , 0x77 },
227 { STB0899_MATCSTM , 0x00 },
228 { STB0899_MATCSTL , 0x00 },
229 { STB0899_UPLCSTM , 0x00 },
230 { STB0899_UPLCSTL , 0x00 },
231 { STB0899_DFLCSTM , 0x00 },
232 { STB0899_DFLCSTL , 0x00 },
233 { STB0899_SYNCCST , 0x00 },
234 { STB0899_SYNCDCSTM , 0x00 },
235 { STB0899_SYNCDCSTL , 0x00 },
236 { STB0899_ISI_ENTRY , 0x00 },
237 { STB0899_ISI_BIT_EN , 0x00 },
238 { STB0899_MATSTRM , 0xf0 },
239 { STB0899_MATSTRL , 0x02 },
240 { STB0899_UPLSTRM , 0x45 },
241 { STB0899_UPLSTRL , 0x60 },
242 { STB0899_DFLSTRM , 0xe3 },
243 { STB0899_DFLSTRL , 0x00 },
244 { STB0899_SYNCSTR , 0x47 },
245 { STB0899_SYNCDSTRM , 0x05 },
246 { STB0899_SYNCDSTRL , 0x18 },
247 { STB0899_CFGPDELSTATUS1 , 0x19 },
248 { STB0899_CFGPDELSTATUS2 , 0x2b },
249 { STB0899_BBFERRORM , 0x00 },
250 { STB0899_BBFERRORL , 0x01 },
251 { STB0899_UPKTERRORM , 0x00 },
252 { STB0899_UPKTERRORL , 0x00 },
253 { 0xffff , 0xff },
254};
255
256
257
258struct stb0899_config az6027_stb0899_config = {
259 .init_dev = az6027_stb0899_s1_init_1,
260 .init_s2_demod = stb0899_s2_init_2,
261 .init_s1_demod = az6027_stb0899_s1_init_3,
262 .init_s2_fec = stb0899_s2_init_4,
263 .init_tst = stb0899_s1_init_5,
264
265 .demod_address = 0xd0, /* 0x68, 0xd0 >> 1 */
266
267 .xtal_freq = 27000000,
268 .inversion = IQ_SWAP_ON, /* 1 */
269
270 .lo_clk = 76500000,
271 .hi_clk = 99000000,
272
273 .esno_ave = STB0899_DVBS2_ESNO_AVE,
274 .esno_quant = STB0899_DVBS2_ESNO_QUANT,
275 .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
276 .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
277 .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
278 .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
279 .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
280 .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
281 .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
282
283 .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
284 .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
285 .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
286 .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
287
288 .tuner_get_frequency = stb6100_get_frequency,
289 .tuner_set_frequency = stb6100_set_frequency,
290 .tuner_set_bandwidth = stb6100_set_bandwidth,
291 .tuner_get_bandwidth = stb6100_get_bandwidth,
292 .tuner_set_rfsiggain = NULL,
293};
294
295struct stb6100_config az6027_stb6100_config = {
296 .tuner_address = 0xc0,
297 .refclock = 27000000,
298};
299
300
301/* check for mutex FIXME */
302int az6027_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
303{
304 int ret = -1;
305 if (mutex_lock_interruptible(&d->usb_mutex))
306 return -EAGAIN;
307
308 ret = usb_control_msg(d->udev,
309 usb_rcvctrlpipe(d->udev, 0),
310 req,
311 USB_TYPE_VENDOR | USB_DIR_IN,
312 value,
313 index,
314 b,
315 blen,
316 2000);
317
318 if (ret < 0) {
319 warn("usb in operation failed. (%d)", ret);
320 ret = -EIO;
321 } else
322 ret = 0;
323
324 deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
325 debug_dump(b, blen, deb_xfer);
326
327 mutex_unlock(&d->usb_mutex);
328 return ret;
329}
330
331static int az6027_usb_out_op(struct dvb_usb_device *d,
332 u8 req,
333 u16 value,
334 u16 index,
335 u8 *b,
336 int blen)
337{
338 int ret;
339
340 deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
341 debug_dump(b, blen, deb_xfer);
342
343 if (mutex_lock_interruptible(&d->usb_mutex))
344 return -EAGAIN;
345
346 ret = usb_control_msg(d->udev,
347 usb_sndctrlpipe(d->udev, 0),
348 req,
349 USB_TYPE_VENDOR | USB_DIR_OUT,
350 value,
351 index,
352 b,
353 blen,
354 2000);
355
356 if (ret != blen) {
357 warn("usb out operation failed. (%d)", ret);
358 mutex_unlock(&d->usb_mutex);
359 return -EIO;
360 } else{
361 mutex_unlock(&d->usb_mutex);
362 return 0;
363 }
364}
365
366static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
367{
368 int ret;
369 u8 req;
370 u16 value;
371 u16 index;
372 int blen;
373
374 deb_info("%s %d", __func__, onoff);
375
376 req = 0xBC;
377 value = onoff;
378 index = 0;
379 blen = 0;
380
381 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
382 if (ret != 0)
383 warn("usb out operation failed. (%d)", ret);
384
385 return ret;
386}
387
388/* keys for the enclosed remote control */
389static struct rc_map_table rc_map_az6027_table[] = {
390 { 0x01, KEY_1 },
391 { 0x02, KEY_2 },
392};
393
394/* remote control stuff (does not work with my box) */
395static int az6027_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
396{
397 return 0;
398}
399
400/*
401int az6027_power_ctrl(struct dvb_usb_device *d, int onoff)
402{
403 u8 v = onoff;
404 return az6027_usb_out_op(d,0xBC,v,3,NULL,1);
405}
406*/
407
408static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
409 int slot,
410 int address)
411{
412 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
413 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
414
415 int ret;
416 u8 req;
417 u16 value;
418 u16 index;
419 int blen;
420 u8 *b;
421
422 if (slot != 0)
423 return -EINVAL;
424
425 b = kmalloc(12, GFP_KERNEL);
426 if (!b)
427 return -ENOMEM;
428
429 mutex_lock(&state->ca_mutex);
430
431 req = 0xC1;
432 value = address;
433 index = 0;
434 blen = 1;
435
436 ret = az6027_usb_in_op(d, req, value, index, b, blen);
437 if (ret < 0) {
438 warn("usb in operation failed. (%d)", ret);
439 ret = -EINVAL;
440 } else {
441 ret = b[0];
442 }
443
444 mutex_unlock(&state->ca_mutex);
445 kfree(b);
446 return ret;
447}
448
449static int az6027_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
450 int slot,
451 int address,
452 u8 value)
453{
454 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
455 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
456
457 int ret;
458 u8 req;
459 u16 value1;
460 u16 index;
461 int blen;
462
463 deb_info("%s %d", __func__, slot);
464 if (slot != 0)
465 return -EINVAL;
466
467 mutex_lock(&state->ca_mutex);
468 req = 0xC2;
469 value1 = address;
470 index = value;
471 blen = 0;
472
473 ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
474 if (ret != 0)
475 warn("usb out operation failed. (%d)", ret);
476
477 mutex_unlock(&state->ca_mutex);
478 return ret;
479}
480
481static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca,
482 int slot,
483 u8 address)
484{
485 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
486 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
487
488 int ret;
489 u8 req;
490 u16 value;
491 u16 index;
492 int blen;
493 u8 *b;
494
495 if (slot != 0)
496 return -EINVAL;
497
498 b = kmalloc(12, GFP_KERNEL);
499 if (!b)
500 return -ENOMEM;
501
502 mutex_lock(&state->ca_mutex);
503
504 req = 0xC3;
505 value = address;
506 index = 0;
507 blen = 2;
508
509 ret = az6027_usb_in_op(d, req, value, index, b, blen);
510 if (ret < 0) {
511 warn("usb in operation failed. (%d)", ret);
512 ret = -EINVAL;
513 } else {
514 if (b[0] == 0)
515 warn("Read CI IO error");
516
517 ret = b[1];
518 deb_info("read cam data = %x from 0x%x", b[1], value);
519 }
520
521 mutex_unlock(&state->ca_mutex);
522 kfree(b);
523 return ret;
524}
525
526static int az6027_ci_write_cam_control(struct dvb_ca_en50221 *ca,
527 int slot,
528 u8 address,
529 u8 value)
530{
531 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
532 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
533
534 int ret;
535 u8 req;
536 u16 value1;
537 u16 index;
538 int blen;
539
540 if (slot != 0)
541 return -EINVAL;
542
543 mutex_lock(&state->ca_mutex);
544 req = 0xC4;
545 value1 = address;
546 index = value;
547 blen = 0;
548
549 ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
550 if (ret != 0) {
551 warn("usb out operation failed. (%d)", ret);
552 goto failed;
553 }
554
555failed:
556 mutex_unlock(&state->ca_mutex);
557 return ret;
558}
559
560static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
561{
562 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
563
564 int ret;
565 u8 req;
566 u16 value;
567 u16 index;
568 int blen;
569 u8 *b;
570
571 b = kmalloc(12, GFP_KERNEL);
572 if (!b)
573 return -ENOMEM;
574
575 req = 0xC8;
576 value = 0;
577 index = 0;
578 blen = 1;
579
580 ret = az6027_usb_in_op(d, req, value, index, b, blen);
581 if (ret < 0) {
582 warn("usb in operation failed. (%d)", ret);
583 ret = -EIO;
584 } else{
585 ret = b[0];
586 }
587 kfree(b);
588 return ret;
589}
590
591static int az6027_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
592{
593 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
594 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
595
596 int ret, i;
597 u8 req;
598 u16 value;
599 u16 index;
600 int blen;
601
602 mutex_lock(&state->ca_mutex);
603
604 req = 0xC6;
605 value = 1;
606 index = 0;
607 blen = 0;
608
609 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
610 if (ret != 0) {
611 warn("usb out operation failed. (%d)", ret);
612 goto failed;
613 }
614
615 msleep(500);
616 req = 0xC6;
617 value = 0;
618 index = 0;
619 blen = 0;
620
621 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
622 if (ret != 0) {
623 warn("usb out operation failed. (%d)", ret);
624 goto failed;
625 }
626
627 for (i = 0; i < 15; i++) {
628 msleep(100);
629
630 if (CI_CamReady(ca, slot)) {
631 deb_info("CAM Ready");
632 break;
633 }
634 }
635 msleep(5000);
636
637failed:
638 mutex_unlock(&state->ca_mutex);
639 return ret;
640}
641
642static int az6027_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
643{
644 return 0;
645}
646
647static int az6027_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
648{
649 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
650 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
651
652 int ret;
653 u8 req;
654 u16 value;
655 u16 index;
656 int blen;
657
658 deb_info("%s", __func__);
659 mutex_lock(&state->ca_mutex);
660 req = 0xC7;
661 value = 1;
662 index = 0;
663 blen = 0;
664
665 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
666 if (ret != 0) {
667 warn("usb out operation failed. (%d)", ret);
668 goto failed;
669 }
670
671failed:
672 mutex_unlock(&state->ca_mutex);
673 return ret;
674}
675
676static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
677{
678 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
679 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
680 int ret;
681 u8 req;
682 u16 value;
683 u16 index;
684 int blen;
685 u8 *b;
686
687 b = kmalloc(12, GFP_KERNEL);
688 if (!b)
689 return -ENOMEM;
690 mutex_lock(&state->ca_mutex);
691
692 req = 0xC5;
693 value = 0;
694 index = 0;
695 blen = 1;
696
697 ret = az6027_usb_in_op(d, req, value, index, b, blen);
698 if (ret < 0) {
699 warn("usb in operation failed. (%d)", ret);
700 ret = -EIO;
701 } else
702 ret = 0;
703
704 if (!ret && b[0] == 1) {
705 ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
706 DVB_CA_EN50221_POLL_CAM_READY;
707 }
708
709 mutex_unlock(&state->ca_mutex);
710 kfree(b);
711 return ret;
712}
713
714
715static void az6027_ci_uninit(struct dvb_usb_device *d)
716{
717 struct az6027_device_state *state;
718
719 deb_info("%s", __func__);
720
721 if (NULL == d)
722 return;
723
724 state = (struct az6027_device_state *)d->priv;
725 if (NULL == state)
726 return;
727
728 if (NULL == state->ca.data)
729 return;
730
731 dvb_ca_en50221_release(&state->ca);
732
733 memset(&state->ca, 0, sizeof(state->ca));
734}
735
736
737static int az6027_ci_init(struct dvb_usb_adapter *a)
738{
739 struct dvb_usb_device *d = a->dev;
740 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
741 int ret;
742
743 deb_info("%s", __func__);
744
745 mutex_init(&state->ca_mutex);
746
747 state->ca.owner = THIS_MODULE;
748 state->ca.read_attribute_mem = az6027_ci_read_attribute_mem;
749 state->ca.write_attribute_mem = az6027_ci_write_attribute_mem;
750 state->ca.read_cam_control = az6027_ci_read_cam_control;
751 state->ca.write_cam_control = az6027_ci_write_cam_control;
752 state->ca.slot_reset = az6027_ci_slot_reset;
753 state->ca.slot_shutdown = az6027_ci_slot_shutdown;
754 state->ca.slot_ts_enable = az6027_ci_slot_ts_enable;
755 state->ca.poll_slot_status = az6027_ci_poll_slot_status;
756 state->ca.data = d;
757
758 ret = dvb_ca_en50221_init(&a->dvb_adap,
759 &state->ca,
760 0, /* flags */
761 1);/* n_slots */
762 if (ret != 0) {
763 err("Cannot initialize CI: Error %d.", ret);
764 memset(&state->ca, 0, sizeof(state->ca));
765 return ret;
766 }
767
768 deb_info("CI initialized.");
769
770 return 0;
771}
772
773/*
774static int az6027_read_mac_addr(struct dvb_usb_device *d, u8 mac[6])
775{
776 az6027_usb_in_op(d, 0xb7, 6, 0, &mac[0], 6);
777 return 0;
778}
779*/
780
781static int az6027_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
782{
783
784 u8 buf;
785 int ret;
786 struct dvb_usb_adapter *adap = fe->dvb->priv;
787
788 struct i2c_msg i2c_msg = {
789 .addr = 0x99,
790 .flags = 0,
791 .buf = &buf,
792 .len = 1
793 };
794
795 /*
796 * 2 --18v
797 * 1 --13v
798 * 0 --off
799 */
800 switch (voltage) {
801 case SEC_VOLTAGE_13:
802 buf = 1;
803 ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
804 break;
805
806 case SEC_VOLTAGE_18:
807 buf = 2;
808 ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
809 break;
810
811 case SEC_VOLTAGE_OFF:
812 buf = 0;
813 ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
814 break;
815
816 default:
817 return -EINVAL;
818 }
819 return 0;
820}
821
822
823static int az6027_frontend_poweron(struct dvb_usb_adapter *adap)
824{
825 int ret;
826 u8 req;
827 u16 value;
828 u16 index;
829 int blen;
830
831 req = 0xBC;
832 value = 1; /* power on */
833 index = 3;
834 blen = 0;
835
836 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
837 if (ret != 0)
838 return -EIO;
839
840 return 0;
841}
842static int az6027_frontend_reset(struct dvb_usb_adapter *adap)
843{
844 int ret;
845 u8 req;
846 u16 value;
847 u16 index;
848 int blen;
849
850 /* reset demodulator */
851 req = 0xC0;
852 value = 1; /* high */
853 index = 3;
854 blen = 0;
855
856 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
857 if (ret != 0)
858 return -EIO;
859
860 req = 0xC0;
861 value = 0; /* low */
862 index = 3;
863 blen = 0;
864 msleep_interruptible(200);
865
866 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
867 if (ret != 0)
868 return -EIO;
869
870 msleep_interruptible(200);
871
872 req = 0xC0;
873 value = 1; /*high */
874 index = 3;
875 blen = 0;
876
877 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
878 if (ret != 0)
879 return -EIO;
880
881 msleep_interruptible(200);
882 return 0;
883}
884
885static int az6027_frontend_tsbypass(struct dvb_usb_adapter *adap, int onoff)
886{
887 int ret;
888 u8 req;
889 u16 value;
890 u16 index;
891 int blen;
892
893 /* TS passthrough */
894 req = 0xC7;
895 value = onoff;
896 index = 0;
897 blen = 0;
898
899 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
900 if (ret != 0)
901 return -EIO;
902
903 return 0;
904}
905
906static int az6027_frontend_attach(struct dvb_usb_adapter *adap)
907{
908
909 az6027_frontend_poweron(adap);
910 az6027_frontend_reset(adap);
911
912 deb_info("adap = %p, dev = %p\n", adap, adap->dev);
913 adap->fe = stb0899_attach(&az6027_stb0899_config, &adap->dev->i2c_adap);
914
915 if (adap->fe) {
916 deb_info("found STB0899 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb0899_config.demod_address);
917 if (stb6100_attach(adap->fe, &az6027_stb6100_config, &adap->dev->i2c_adap)) {
918 deb_info("found STB6100 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb6100_config.tuner_address);
919 adap->fe->ops.set_voltage = az6027_set_voltage;
920 az6027_ci_init(adap);
921 } else {
922 adap->fe = NULL;
923 }
924 } else
925 warn("no front-end attached\n");
926
927 az6027_frontend_tsbypass(adap, 0);
928
929 return 0;
930}
931
932static struct dvb_usb_device_properties az6027_properties;
933
934static void az6027_usb_disconnect(struct usb_interface *intf)
935{
936 struct dvb_usb_device *d = usb_get_intfdata(intf);
937 az6027_ci_uninit(d);
938 dvb_usb_device_exit(intf);
939}
940
941
942static int az6027_usb_probe(struct usb_interface *intf,
943 const struct usb_device_id *id)
944{
945 return dvb_usb_device_init(intf,
946 &az6027_properties,
947 THIS_MODULE,
948 NULL,
949 adapter_nr);
950}
951
952/* I2C */
953static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
954{
955 struct dvb_usb_device *d = i2c_get_adapdata(adap);
956 int i = 0, j = 0, len = 0;
957 int ret;
958 u16 index;
959 u16 value;
960 int length;
961 u8 req;
962 u8 *data;
963
964 data = kmalloc(256, GFP_KERNEL);
965 if (!data)
966 return -ENOMEM;
967
968 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) {
969 kfree(data);
970 return -EAGAIN;
971 }
972
973 if (num > 2)
974 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
975
976 for (i = 0; i < num; i++) {
977
978 if (msg[i].addr == 0x99) {
979 req = 0xBE;
980 index = 0;
981 value = msg[i].buf[0] & 0x00ff;
982 length = 1;
983 az6027_usb_out_op(d, req, value, index, data, length);
984 }
985
986 if (msg[i].addr == 0xd0) {
987 /* write/read request */
988 if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
989 req = 0xB9;
990 index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
991 value = msg[i].addr + (msg[i].len << 8);
992 length = msg[i + 1].len + 6;
993 ret = az6027_usb_in_op(d, req, value, index, data, length);
994 len = msg[i + 1].len;
995 for (j = 0; j < len; j++)
996 msg[i + 1].buf[j] = data[j + 5];
997
998 i++;
999 } else {
1000
1001 /* demod 16bit addr */
1002 req = 0xBD;
1003 index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
1004 value = msg[i].addr + (2 << 8);
1005 length = msg[i].len - 2;
1006 len = msg[i].len - 2;
1007 for (j = 0; j < len; j++)
1008 data[j] = msg[i].buf[j + 2];
1009 az6027_usb_out_op(d, req, value, index, data, length);
1010 }
1011 }
1012
1013 if (msg[i].addr == 0xc0) {
1014 if (msg[i].flags & I2C_M_RD) {
1015
1016 req = 0xB9;
1017 index = 0x0;
1018 value = msg[i].addr;
1019 length = msg[i].len + 6;
1020 ret = az6027_usb_in_op(d, req, value, index, data, length);
1021 len = msg[i].len;
1022 for (j = 0; j < len; j++)
1023 msg[i].buf[j] = data[j + 5];
1024
1025 } else {
1026
1027 req = 0xBD;
1028 index = msg[i].buf[0] & 0x00FF;
1029 value = msg[i].addr + (1 << 8);
1030 length = msg[i].len - 1;
1031 len = msg[i].len - 1;
1032
1033 for (j = 0; j < len; j++)
1034 data[j] = msg[i].buf[j + 1];
1035
1036 az6027_usb_out_op(d, req, value, index, data, length);
1037 }
1038 }
1039 }
1040 mutex_unlock(&d->i2c_mutex);
1041 kfree(data);
1042
1043 return i;
1044}
1045
1046
1047static u32 az6027_i2c_func(struct i2c_adapter *adapter)
1048{
1049 return I2C_FUNC_I2C;
1050}
1051
1052static struct i2c_algorithm az6027_i2c_algo = {
1053 .master_xfer = az6027_i2c_xfer,
1054 .functionality = az6027_i2c_func,
1055};
1056
1057int az6027_identify_state(struct usb_device *udev,
1058 struct dvb_usb_device_properties *props,
1059 struct dvb_usb_device_description **desc,
1060 int *cold)
1061{
1062 u8 *b;
1063 s16 ret;
1064
1065 b = kmalloc(16, GFP_KERNEL);
1066 if (!b)
1067 return -ENOMEM;
1068
1069 ret = usb_control_msg(udev,
1070 usb_rcvctrlpipe(udev, 0),
1071 0xb7,
1072 USB_TYPE_VENDOR | USB_DIR_IN,
1073 6,
1074 0,
1075 b,
1076 6,
1077 USB_CTRL_GET_TIMEOUT);
1078
1079 *cold = ret <= 0;
1080 kfree(b);
1081 deb_info("cold: %d\n", *cold);
1082 return 0;
1083}
1084
1085
1086static struct usb_device_id az6027_usb_table[] = {
1087 { USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_AZ6027) },
1088 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_DVBS2CI_V1) },
1089 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_DVBS2CI_V2) },
1090 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V1) },
1091 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V2) },
1092 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT) },
1093 { },
1094};
1095
1096MODULE_DEVICE_TABLE(usb, az6027_usb_table);
1097
1098static struct dvb_usb_device_properties az6027_properties = {
1099 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1100 .usb_ctrl = CYPRESS_FX2,
1101 .firmware = "dvb-usb-az6027-03.fw",
1102 .no_reconnect = 1,
1103
1104 .size_of_priv = sizeof(struct az6027_device_state),
1105 .identify_state = az6027_identify_state,
1106 .num_adapters = 1,
1107 .adapter = {
1108 {
1109 .streaming_ctrl = az6027_streaming_ctrl,
1110 .frontend_attach = az6027_frontend_attach,
1111
1112 /* parameter for the MPEG2-data transfer */
1113 .stream = {
1114 .type = USB_BULK,
1115 .count = 10,
1116 .endpoint = 0x02,
1117 .u = {
1118 .bulk = {
1119 .buffersize = 4096,
1120 }
1121 }
1122 },
1123 }
1124 },
1125/*
1126 .power_ctrl = az6027_power_ctrl,
1127 .read_mac_address = az6027_read_mac_addr,
1128 */
1129 .rc.legacy = {
1130 .rc_map_table = rc_map_az6027_table,
1131 .rc_map_size = ARRAY_SIZE(rc_map_az6027_table),
1132 .rc_interval = 400,
1133 .rc_query = az6027_rc_query,
1134 },
1135
1136 .i2c_algo = &az6027_i2c_algo,
1137
1138 .num_device_descs = 6,
1139 .devices = {
1140 {
1141 .name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)",
1142 .cold_ids = { &az6027_usb_table[0], NULL },
1143 .warm_ids = { NULL },
1144 }, {
1145 .name = "TERRATEC S7",
1146 .cold_ids = { &az6027_usb_table[1], NULL },
1147 .warm_ids = { NULL },
1148 }, {
1149 .name = "TERRATEC S7 MKII",
1150 .cold_ids = { &az6027_usb_table[2], NULL },
1151 .warm_ids = { NULL },
1152 }, {
1153 .name = "Technisat SkyStar USB 2 HD CI",
1154 .cold_ids = { &az6027_usb_table[3], NULL },
1155 .warm_ids = { NULL },
1156 }, {
1157 .name = "Technisat SkyStar USB 2 HD CI",
1158 .cold_ids = { &az6027_usb_table[4], NULL },
1159 .warm_ids = { NULL },
1160 }, {
1161 .name = "Elgato EyeTV Sat",
1162 .cold_ids = { &az6027_usb_table[5], NULL },
1163 .warm_ids = { NULL },
1164 },
1165 { NULL },
1166 }
1167};
1168
1169/* usb specific object needed to register this driver with the usb subsystem */
1170static struct usb_driver az6027_usb_driver = {
1171 .name = "dvb_usb_az6027",
1172 .probe = az6027_usb_probe,
1173 .disconnect = az6027_usb_disconnect,
1174 .id_table = az6027_usb_table,
1175};
1176
1177/* module stuff */
1178static int __init az6027_usb_module_init(void)
1179{
1180 int result;
1181
1182 result = usb_register(&az6027_usb_driver);
1183 if (result) {
1184 err("usb_register failed. (%d)", result);
1185 return result;
1186 }
1187
1188 return 0;
1189}
1190
1191static void __exit az6027_usb_module_exit(void)
1192{
1193 /* deregister this driver from the USB subsystem */
1194 usb_deregister(&az6027_usb_driver);
1195}
1196
1197module_init(az6027_usb_module_init);
1198module_exit(az6027_usb_module_exit);
1199
1200MODULE_AUTHOR("Adams Xu <Adams.xu@azwave.com.cn>");
1201MODULE_DESCRIPTION("Driver for AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)");
1202MODULE_VERSION("1.0");
1203MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/az6027.h b/drivers/media/dvb/dvb-usb/az6027.h
new file mode 100644
index 00000000000..f3afe17f3f3
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/az6027.h
@@ -0,0 +1,14 @@
1#ifndef _DVB_USB_VP6027_H_
2#define _DVB_USB_VP6027_H_
3
4#define DVB_USB_LOG_PREFIX "az6027"
5#include "dvb-usb.h"
6
7
8extern int dvb_usb_az6027_debug;
9#define deb_info(args...) dprintk(dvb_usb_az6027_debug, 0x01, args)
10#define deb_xfer(args...) dprintk(dvb_usb_az6027_debug, 0x02, args)
11#define deb_rc(args...) dprintk(dvb_usb_az6027_debug, 0x04, args)
12#define deb_fe(args...) dprintk(dvb_usb_az6027_debug, 0x08, args)
13
14#endif
diff --git a/drivers/media/dvb/dvb-usb/ce6230.c b/drivers/media/dvb/dvb-usb/ce6230.c
new file mode 100644
index 00000000000..6d1a3041540
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ce6230.c
@@ -0,0 +1,341 @@
1/*
2 * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#include "ce6230.h"
23#include "zl10353.h"
24#include "mxl5005s.h"
25
26/* debug */
27static int dvb_usb_ce6230_debug;
28module_param_named(debug, dvb_usb_ce6230_debug, int, 0644);
29MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
30DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
31
32static struct zl10353_config ce6230_zl10353_config;
33
34static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
35{
36 int ret;
37 unsigned int pipe;
38 u8 request;
39 u8 requesttype;
40 u16 value;
41 u16 index;
42 u8 *buf;
43
44 request = req->cmd;
45 value = req->value;
46 index = req->index;
47
48 switch (req->cmd) {
49 case I2C_READ:
50 case DEMOD_READ:
51 case REG_READ:
52 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
53 break;
54 case I2C_WRITE:
55 case DEMOD_WRITE:
56 case REG_WRITE:
57 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
58 break;
59 default:
60 err("unknown command:%02x", req->cmd);
61 ret = -EPERM;
62 goto error;
63 }
64
65 buf = kmalloc(req->data_len, GFP_KERNEL);
66 if (!buf) {
67 ret = -ENOMEM;
68 goto error;
69 }
70
71 if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
72 /* write */
73 memcpy(buf, req->data, req->data_len);
74 pipe = usb_sndctrlpipe(udev, 0);
75 } else {
76 /* read */
77 pipe = usb_rcvctrlpipe(udev, 0);
78 }
79
80 msleep(1); /* avoid I2C errors */
81
82 ret = usb_control_msg(udev, pipe, request, requesttype, value, index,
83 buf, req->data_len, CE6230_USB_TIMEOUT);
84
85 ce6230_debug_dump(request, requesttype, value, index, buf,
86 req->data_len, deb_xfer);
87
88 if (ret < 0)
89 deb_info("%s: usb_control_msg failed:%d\n", __func__, ret);
90 else
91 ret = 0;
92
93 /* read request, copy returned data to return buf */
94 if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
95 memcpy(req->data, buf, req->data_len);
96
97 kfree(buf);
98error:
99 return ret;
100}
101
102static int ce6230_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
103{
104 return ce6230_rw_udev(d->udev, req);
105}
106
107/* I2C */
108static int ce6230_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
109 int num)
110{
111 struct dvb_usb_device *d = i2c_get_adapdata(adap);
112 int i = 0;
113 struct req_t req;
114 int ret = 0;
115 memset(&req, 0, sizeof(req));
116
117 if (num > 2)
118 return -EINVAL;
119
120 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
121 return -EAGAIN;
122
123 while (i < num) {
124 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
125 if (msg[i].addr ==
126 ce6230_zl10353_config.demod_address) {
127 req.cmd = DEMOD_READ;
128 req.value = msg[i].addr >> 1;
129 req.index = msg[i].buf[0];
130 req.data_len = msg[i+1].len;
131 req.data = &msg[i+1].buf[0];
132 ret = ce6230_ctrl_msg(d, &req);
133 } else {
134 err("i2c read not implemented");
135 ret = -EPERM;
136 }
137 i += 2;
138 } else {
139 if (msg[i].addr ==
140 ce6230_zl10353_config.demod_address) {
141 req.cmd = DEMOD_WRITE;
142 req.value = msg[i].addr >> 1;
143 req.index = msg[i].buf[0];
144 req.data_len = msg[i].len-1;
145 req.data = &msg[i].buf[1];
146 ret = ce6230_ctrl_msg(d, &req);
147 } else {
148 req.cmd = I2C_WRITE;
149 req.value = 0x2000 + (msg[i].addr >> 1);
150 req.index = 0x0000;
151 req.data_len = msg[i].len;
152 req.data = &msg[i].buf[0];
153 ret = ce6230_ctrl_msg(d, &req);
154 }
155 i += 1;
156 }
157 if (ret)
158 break;
159 }
160
161 mutex_unlock(&d->i2c_mutex);
162 return ret ? ret : i;
163}
164
165static u32 ce6230_i2c_func(struct i2c_adapter *adapter)
166{
167 return I2C_FUNC_I2C;
168}
169
170static struct i2c_algorithm ce6230_i2c_algo = {
171 .master_xfer = ce6230_i2c_xfer,
172 .functionality = ce6230_i2c_func,
173};
174
175/* Callbacks for DVB USB */
176static struct zl10353_config ce6230_zl10353_config = {
177 .demod_address = 0x1e,
178 .adc_clock = 450000,
179 .if2 = 45700,
180 .no_tuner = 1,
181 .parallel_ts = 1,
182 .clock_ctl_1 = 0x34,
183 .pll_0 = 0x0e,
184};
185
186static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
187{
188 deb_info("%s:\n", __func__);
189 adap->fe = dvb_attach(zl10353_attach, &ce6230_zl10353_config,
190 &adap->dev->i2c_adap);
191 if (adap->fe == NULL)
192 return -ENODEV;
193 return 0;
194}
195
196static struct mxl5005s_config ce6230_mxl5003s_config = {
197 .i2c_address = 0xc6,
198 .if_freq = IF_FREQ_4570000HZ,
199 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
200 .agc_mode = MXL_SINGLE_AGC,
201 .tracking_filter = MXL_TF_DEFAULT,
202 .rssi_enable = MXL_RSSI_ENABLE,
203 .cap_select = MXL_CAP_SEL_ENABLE,
204 .div_out = MXL_DIV_OUT_4,
205 .clock_out = MXL_CLOCK_OUT_DISABLE,
206 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
207 .top = MXL5005S_TOP_25P2,
208 .mod_mode = MXL_DIGITAL_MODE,
209 .if_mode = MXL_ZERO_IF,
210 .AgcMasterByte = 0x00,
211};
212
213static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
214{
215 int ret;
216 deb_info("%s:\n", __func__);
217 ret = dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap,
218 &ce6230_mxl5003s_config) == NULL ? -ENODEV : 0;
219 return ret;
220}
221
222static int ce6230_power_ctrl(struct dvb_usb_device *d, int onoff)
223{
224 int ret;
225 deb_info("%s: onoff:%d\n", __func__, onoff);
226
227 /* InterfaceNumber 1 / AlternateSetting 0 idle
228 InterfaceNumber 1 / AlternateSetting 1 streaming */
229 ret = usb_set_interface(d->udev, 1, onoff);
230 if (ret)
231 err("usb_set_interface failed with error:%d", ret);
232
233 return ret;
234}
235
236/* DVB USB Driver stuff */
237static struct dvb_usb_device_properties ce6230_properties;
238
239static int ce6230_probe(struct usb_interface *intf,
240 const struct usb_device_id *id)
241{
242 int ret = 0;
243 struct dvb_usb_device *d = NULL;
244
245 deb_info("%s: interface:%d\n", __func__,
246 intf->cur_altsetting->desc.bInterfaceNumber);
247
248 if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
249 ret = dvb_usb_device_init(intf, &ce6230_properties, THIS_MODULE,
250 &d, adapter_nr);
251 if (ret)
252 err("init failed with error:%d\n", ret);
253 }
254
255 return ret;
256}
257
258static struct usb_device_id ce6230_table[] = {
259 { USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500) },
260 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A310) },
261 { } /* Terminating entry */
262};
263MODULE_DEVICE_TABLE(usb, ce6230_table);
264
265static struct dvb_usb_device_properties ce6230_properties = {
266 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
267
268 .usb_ctrl = DEVICE_SPECIFIC,
269 .no_reconnect = 1,
270
271 .size_of_priv = 0,
272
273 .num_adapters = 1,
274 .adapter = {
275 {
276 .frontend_attach = ce6230_zl10353_frontend_attach,
277 .tuner_attach = ce6230_mxl5003s_tuner_attach,
278 .stream = {
279 .type = USB_BULK,
280 .count = 6,
281 .endpoint = 0x82,
282 .u = {
283 .bulk = {
284 .buffersize = (16*512),
285 }
286 }
287 },
288 }
289 },
290
291 .power_ctrl = ce6230_power_ctrl,
292
293 .i2c_algo = &ce6230_i2c_algo,
294
295 .num_device_descs = 2,
296 .devices = {
297 {
298 .name = "Intel CE9500 reference design",
299 .cold_ids = {NULL},
300 .warm_ids = {&ce6230_table[0], NULL},
301 },
302 {
303 .name = "AVerMedia A310 USB 2.0 DVB-T tuner",
304 .cold_ids = {NULL},
305 .warm_ids = {&ce6230_table[1], NULL},
306 },
307 }
308};
309
310static struct usb_driver ce6230_driver = {
311 .name = "dvb_usb_ce6230",
312 .probe = ce6230_probe,
313 .disconnect = dvb_usb_device_exit,
314 .id_table = ce6230_table,
315};
316
317/* module stuff */
318static int __init ce6230_module_init(void)
319{
320 int ret;
321 deb_info("%s:\n", __func__);
322 ret = usb_register(&ce6230_driver);
323 if (ret)
324 err("usb_register failed with error:%d", ret);
325
326 return ret;
327}
328
329static void __exit ce6230_module_exit(void)
330{
331 deb_info("%s:\n", __func__);
332 /* deregister this driver from the USB subsystem */
333 usb_deregister(&ce6230_driver);
334}
335
336module_init(ce6230_module_init);
337module_exit(ce6230_module_exit);
338
339MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
340MODULE_DESCRIPTION("Driver for Intel CE6230 DVB-T USB2.0");
341MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/ce6230.h b/drivers/media/dvb/dvb-usb/ce6230.h
new file mode 100644
index 00000000000..97c42482ccb
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ce6230.h
@@ -0,0 +1,69 @@
1/*
2 * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#ifndef _DVB_USB_CE6230_H_
23#define _DVB_USB_CE6230_H_
24
25#define DVB_USB_LOG_PREFIX "ce6230"
26#include "dvb-usb.h"
27
28#define deb_info(args...) dprintk(dvb_usb_ce6230_debug, 0x01, args)
29#define deb_rc(args...) dprintk(dvb_usb_ce6230_debug, 0x02, args)
30#define deb_xfer(args...) dprintk(dvb_usb_ce6230_debug, 0x04, args)
31#define deb_reg(args...) dprintk(dvb_usb_ce6230_debug, 0x08, args)
32#define deb_i2c(args...) dprintk(dvb_usb_ce6230_debug, 0x10, args)
33#define deb_fw(args...) dprintk(dvb_usb_ce6230_debug, 0x20, args)
34
35#define ce6230_debug_dump(r, t, v, i, b, l, func) { \
36 int loop_; \
37 func("%02x %02x %02x %02x %02x %02x %02x %02x", \
38 t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \
39 if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
40 func(" >>> "); \
41 else \
42 func(" <<< "); \
43 for (loop_ = 0; loop_ < l; loop_++) \
44 func("%02x ", b[loop_]); \
45 func("\n");\
46}
47
48#define CE6230_USB_TIMEOUT 1000
49
50struct req_t {
51 u8 cmd; /* [1] */
52 u16 value; /* [2|3] */
53 u16 index; /* [4|5] */
54 u16 data_len; /* [6|7] */
55 u8 *data;
56};
57
58enum ce6230_cmd {
59 CONFIG_READ = 0xd0, /* rd 0 (unclear) */
60 UNKNOWN_WRITE = 0xc7, /* wr 7 (unclear) */
61 I2C_READ = 0xd9, /* rd 9 (unclear) */
62 I2C_WRITE = 0xca, /* wr a */
63 DEMOD_READ = 0xdb, /* rd b */
64 DEMOD_WRITE = 0xcc, /* wr c */
65 REG_READ = 0xde, /* rd e */
66 REG_WRITE = 0xcf, /* wr f */
67};
68
69#endif
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
new file mode 100644
index 00000000000..16f2ce2bc15
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cinergyT2-core.c
@@ -0,0 +1,269 @@
1/*
2 * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
3 *
4 * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
5 *
6 * Based on the dvb-usb-framework code and the
7 * original Terratec Cinergy T2 driver by:
8 *
9 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
10 * Holger Waechtler <holger@qanu.de>
11 *
12 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30#include "cinergyT2.h"
31
32
33/* debug */
34int dvb_usb_cinergyt2_debug;
35
36module_param_named(debug, dvb_usb_cinergyt2_debug, int, 0644);
37MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 "
38 "(or-able)).");
39
40DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
41
42struct cinergyt2_state {
43 u8 rc_counter;
44};
45
46/* We are missing a release hook with usb_device data */
47static struct dvb_usb_device *cinergyt2_usb_device;
48
49static struct dvb_usb_device_properties cinergyt2_properties;
50
51static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable)
52{
53 char buf[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 };
54 char result[64];
55 return dvb_usb_generic_rw(adap->dev, buf, sizeof(buf), result,
56 sizeof(result), 0);
57}
58
59static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable)
60{
61 char buf[] = { CINERGYT2_EP1_SLEEP_MODE, enable ? 0 : 1 };
62 char state[3];
63 return dvb_usb_generic_rw(d, buf, sizeof(buf), state, sizeof(state), 0);
64}
65
66static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
67{
68 char query[] = { CINERGYT2_EP1_GET_FIRMWARE_VERSION };
69 char state[3];
70 int ret;
71
72 adap->fe = cinergyt2_fe_attach(adap->dev);
73
74 ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query), state,
75 sizeof(state), 0);
76 if (ret < 0) {
77 deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep "
78 "state info\n");
79 }
80
81 /* Copy this pointer as we are gonna need it in the release phase */
82 cinergyt2_usb_device = adap->dev;
83
84 return 0;
85}
86
87static struct rc_map_table rc_map_cinergyt2_table[] = {
88 { 0x0401, KEY_POWER },
89 { 0x0402, KEY_1 },
90 { 0x0403, KEY_2 },
91 { 0x0404, KEY_3 },
92 { 0x0405, KEY_4 },
93 { 0x0406, KEY_5 },
94 { 0x0407, KEY_6 },
95 { 0x0408, KEY_7 },
96 { 0x0409, KEY_8 },
97 { 0x040a, KEY_9 },
98 { 0x040c, KEY_0 },
99 { 0x040b, KEY_VIDEO },
100 { 0x040d, KEY_REFRESH },
101 { 0x040e, KEY_SELECT },
102 { 0x040f, KEY_EPG },
103 { 0x0410, KEY_UP },
104 { 0x0414, KEY_DOWN },
105 { 0x0411, KEY_LEFT },
106 { 0x0413, KEY_RIGHT },
107 { 0x0412, KEY_OK },
108 { 0x0415, KEY_TEXT },
109 { 0x0416, KEY_INFO },
110 { 0x0417, KEY_RED },
111 { 0x0418, KEY_GREEN },
112 { 0x0419, KEY_YELLOW },
113 { 0x041a, KEY_BLUE },
114 { 0x041c, KEY_VOLUMEUP },
115 { 0x041e, KEY_VOLUMEDOWN },
116 { 0x041d, KEY_MUTE },
117 { 0x041b, KEY_CHANNELUP },
118 { 0x041f, KEY_CHANNELDOWN },
119 { 0x0440, KEY_PAUSE },
120 { 0x044c, KEY_PLAY },
121 { 0x0458, KEY_RECORD },
122 { 0x0454, KEY_PREVIOUS },
123 { 0x0448, KEY_STOP },
124 { 0x045c, KEY_NEXT }
125};
126
127/* Number of keypresses to ignore before detect repeating */
128#define RC_REPEAT_DELAY 3
129
130static int repeatable_keys[] = {
131 KEY_UP,
132 KEY_DOWN,
133 KEY_LEFT,
134 KEY_RIGHT,
135 KEY_VOLUMEUP,
136 KEY_VOLUMEDOWN,
137 KEY_CHANNELUP,
138 KEY_CHANNELDOWN
139};
140
141static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
142{
143 struct cinergyt2_state *st = d->priv;
144 u8 key[5] = {0, 0, 0, 0, 0}, cmd = CINERGYT2_EP1_GET_RC_EVENTS;
145 int i;
146
147 *state = REMOTE_NO_KEY_PRESSED;
148
149 dvb_usb_generic_rw(d, &cmd, 1, key, sizeof(key), 0);
150 if (key[4] == 0xff) {
151 /* key repeat */
152 st->rc_counter++;
153 if (st->rc_counter > RC_REPEAT_DELAY) {
154 for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) {
155 if (d->last_event == repeatable_keys[i]) {
156 *state = REMOTE_KEY_REPEAT;
157 *event = d->last_event;
158 deb_rc("repeat key, event %x\n",
159 *event);
160 return 0;
161 }
162 }
163 deb_rc("repeated key (non repeatable)\n");
164 }
165 return 0;
166 }
167
168 /* hack to pass checksum on the custom field */
169 key[2] = ~key[1];
170 dvb_usb_nec_rc_key_to_event(d, key, event, state);
171 if (key[0] != 0) {
172 if (*event != d->last_event)
173 st->rc_counter = 0;
174
175 deb_rc("key: %x %x %x %x %x\n",
176 key[0], key[1], key[2], key[3], key[4]);
177 }
178 return 0;
179}
180
181static int cinergyt2_usb_probe(struct usb_interface *intf,
182 const struct usb_device_id *id)
183{
184 return dvb_usb_device_init(intf, &cinergyt2_properties,
185 THIS_MODULE, NULL, adapter_nr);
186}
187
188
189static struct usb_device_id cinergyt2_usb_table[] = {
190 { USB_DEVICE(USB_VID_TERRATEC, 0x0038) },
191 { 0 }
192};
193
194MODULE_DEVICE_TABLE(usb, cinergyt2_usb_table);
195
196static struct dvb_usb_device_properties cinergyt2_properties = {
197 .size_of_priv = sizeof(struct cinergyt2_state),
198 .num_adapters = 1,
199 .adapter = {
200 {
201 .streaming_ctrl = cinergyt2_streaming_ctrl,
202 .frontend_attach = cinergyt2_frontend_attach,
203
204 /* parameter for the MPEG2-data transfer */
205 .stream = {
206 .type = USB_BULK,
207 .count = 5,
208 .endpoint = 0x02,
209 .u = {
210 .bulk = {
211 .buffersize = 512,
212 }
213 }
214 },
215 }
216 },
217
218 .power_ctrl = cinergyt2_power_ctrl,
219
220 .rc.legacy = {
221 .rc_interval = 50,
222 .rc_map_table = rc_map_cinergyt2_table,
223 .rc_map_size = ARRAY_SIZE(rc_map_cinergyt2_table),
224 .rc_query = cinergyt2_rc_query,
225 },
226
227 .generic_bulk_ctrl_endpoint = 1,
228
229 .num_device_descs = 1,
230 .devices = {
231 { .name = "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver",
232 .cold_ids = {NULL},
233 .warm_ids = { &cinergyt2_usb_table[0], NULL },
234 },
235 { NULL },
236 }
237};
238
239
240static struct usb_driver cinergyt2_driver = {
241 .name = "cinergyT2",
242 .probe = cinergyt2_usb_probe,
243 .disconnect = dvb_usb_device_exit,
244 .id_table = cinergyt2_usb_table
245};
246
247static int __init cinergyt2_usb_init(void)
248{
249 int err;
250
251 err = usb_register(&cinergyt2_driver);
252 if (err) {
253 err("usb_register() failed! (err %i)\n", err);
254 return err;
255 }
256 return 0;
257}
258
259static void __exit cinergyt2_usb_exit(void)
260{
261 usb_deregister(&cinergyt2_driver);
262}
263
264module_init(cinergyt2_usb_init);
265module_exit(cinergyt2_usb_exit);
266
267MODULE_DESCRIPTION("Terratec Cinergy T2 DVB-T driver");
268MODULE_LICENSE("GPL");
269MODULE_AUTHOR("Tomi Orava");
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
new file mode 100644
index 00000000000..9cd51ac1207
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c
@@ -0,0 +1,352 @@
1/*
2 * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
3 *
4 * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
5 *
6 * Based on the dvb-usb-framework code and the
7 * original Terratec Cinergy T2 driver by:
8 *
9 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
10 * Holger Waechtler <holger@qanu.de>
11 *
12 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30#include "cinergyT2.h"
31
32
33/**
34 * convert linux-dvb frontend parameter set into TPS.
35 * See ETSI ETS-300744, section 4.6.2, table 9 for details.
36 *
37 * This function is probably reusable and may better get placed in a support
38 * library.
39 *
40 * We replace errornous fields by default TPS fields (the ones with value 0).
41 */
42
43static uint16_t compute_tps(struct dvb_frontend_parameters *p)
44{
45 struct dvb_ofdm_parameters *op = &p->u.ofdm;
46 uint16_t tps = 0;
47
48 switch (op->code_rate_HP) {
49 case FEC_2_3:
50 tps |= (1 << 7);
51 break;
52 case FEC_3_4:
53 tps |= (2 << 7);
54 break;
55 case FEC_5_6:
56 tps |= (3 << 7);
57 break;
58 case FEC_7_8:
59 tps |= (4 << 7);
60 break;
61 case FEC_1_2:
62 case FEC_AUTO:
63 default:
64 /* tps |= (0 << 7) */;
65 }
66
67 switch (op->code_rate_LP) {
68 case FEC_2_3:
69 tps |= (1 << 4);
70 break;
71 case FEC_3_4:
72 tps |= (2 << 4);
73 break;
74 case FEC_5_6:
75 tps |= (3 << 4);
76 break;
77 case FEC_7_8:
78 tps |= (4 << 4);
79 break;
80 case FEC_1_2:
81 case FEC_AUTO:
82 default:
83 /* tps |= (0 << 4) */;
84 }
85
86 switch (op->constellation) {
87 case QAM_16:
88 tps |= (1 << 13);
89 break;
90 case QAM_64:
91 tps |= (2 << 13);
92 break;
93 case QPSK:
94 default:
95 /* tps |= (0 << 13) */;
96 }
97
98 switch (op->transmission_mode) {
99 case TRANSMISSION_MODE_8K:
100 tps |= (1 << 0);
101 break;
102 case TRANSMISSION_MODE_2K:
103 default:
104 /* tps |= (0 << 0) */;
105 }
106
107 switch (op->guard_interval) {
108 case GUARD_INTERVAL_1_16:
109 tps |= (1 << 2);
110 break;
111 case GUARD_INTERVAL_1_8:
112 tps |= (2 << 2);
113 break;
114 case GUARD_INTERVAL_1_4:
115 tps |= (3 << 2);
116 break;
117 case GUARD_INTERVAL_1_32:
118 default:
119 /* tps |= (0 << 2) */;
120 }
121
122 switch (op->hierarchy_information) {
123 case HIERARCHY_1:
124 tps |= (1 << 10);
125 break;
126 case HIERARCHY_2:
127 tps |= (2 << 10);
128 break;
129 case HIERARCHY_4:
130 tps |= (3 << 10);
131 break;
132 case HIERARCHY_NONE:
133 default:
134 /* tps |= (0 << 10) */;
135 }
136
137 return tps;
138}
139
140struct cinergyt2_fe_state {
141 struct dvb_frontend fe;
142 struct dvb_usb_device *d;
143};
144
145static int cinergyt2_fe_read_status(struct dvb_frontend *fe,
146 fe_status_t *status)
147{
148 struct cinergyt2_fe_state *state = fe->demodulator_priv;
149 struct dvbt_get_status_msg result;
150 u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
151 int ret;
152
153 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&result,
154 sizeof(result), 0);
155 if (ret < 0)
156 return ret;
157
158 *status = 0;
159
160 if (0xffff - le16_to_cpu(result.gain) > 30)
161 *status |= FE_HAS_SIGNAL;
162 if (result.lock_bits & (1 << 6))
163 *status |= FE_HAS_LOCK;
164 if (result.lock_bits & (1 << 5))
165 *status |= FE_HAS_SYNC;
166 if (result.lock_bits & (1 << 4))
167 *status |= FE_HAS_CARRIER;
168 if (result.lock_bits & (1 << 1))
169 *status |= FE_HAS_VITERBI;
170
171 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
172 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
173 *status &= ~FE_HAS_LOCK;
174
175 return 0;
176}
177
178static int cinergyt2_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
179{
180 struct cinergyt2_fe_state *state = fe->demodulator_priv;
181 struct dvbt_get_status_msg status;
182 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
183 int ret;
184
185 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
186 sizeof(status), 0);
187 if (ret < 0)
188 return ret;
189
190 *ber = le32_to_cpu(status.viterbi_error_rate);
191 return 0;
192}
193
194static int cinergyt2_fe_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
195{
196 struct cinergyt2_fe_state *state = fe->demodulator_priv;
197 struct dvbt_get_status_msg status;
198 u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
199 int ret;
200
201 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&status,
202 sizeof(status), 0);
203 if (ret < 0) {
204 err("cinergyt2_fe_read_unc_blocks() Failed! (Error=%d)\n",
205 ret);
206 return ret;
207 }
208 *unc = le32_to_cpu(status.uncorrected_block_count);
209 return 0;
210}
211
212static int cinergyt2_fe_read_signal_strength(struct dvb_frontend *fe,
213 u16 *strength)
214{
215 struct cinergyt2_fe_state *state = fe->demodulator_priv;
216 struct dvbt_get_status_msg status;
217 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
218 int ret;
219
220 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
221 sizeof(status), 0);
222 if (ret < 0) {
223 err("cinergyt2_fe_read_signal_strength() Failed!"
224 " (Error=%d)\n", ret);
225 return ret;
226 }
227 *strength = (0xffff - le16_to_cpu(status.gain));
228 return 0;
229}
230
231static int cinergyt2_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
232{
233 struct cinergyt2_fe_state *state = fe->demodulator_priv;
234 struct dvbt_get_status_msg status;
235 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
236 int ret;
237
238 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
239 sizeof(status), 0);
240 if (ret < 0) {
241 err("cinergyt2_fe_read_snr() Failed! (Error=%d)\n", ret);
242 return ret;
243 }
244 *snr = (status.snr << 8) | status.snr;
245 return 0;
246}
247
248static int cinergyt2_fe_init(struct dvb_frontend *fe)
249{
250 return 0;
251}
252
253static int cinergyt2_fe_sleep(struct dvb_frontend *fe)
254{
255 deb_info("cinergyt2_fe_sleep() Called\n");
256 return 0;
257}
258
259static int cinergyt2_fe_get_tune_settings(struct dvb_frontend *fe,
260 struct dvb_frontend_tune_settings *tune)
261{
262 tune->min_delay_ms = 800;
263 return 0;
264}
265
266static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe,
267 struct dvb_frontend_parameters *fep)
268{
269 struct cinergyt2_fe_state *state = fe->demodulator_priv;
270 struct dvbt_set_parameters_msg param;
271 char result[2];
272 int err;
273
274 param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
275 param.tps = cpu_to_le16(compute_tps(fep));
276 param.freq = cpu_to_le32(fep->frequency / 1000);
277 param.bandwidth = 8 - fep->u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
278 param.flags = 0;
279
280 err = dvb_usb_generic_rw(state->d,
281 (char *)&param, sizeof(param),
282 result, sizeof(result), 0);
283 if (err < 0)
284 err("cinergyt2_fe_set_frontend() Failed! err=%d\n", err);
285
286 return (err < 0) ? err : 0;
287}
288
289static int cinergyt2_fe_get_frontend(struct dvb_frontend *fe,
290 struct dvb_frontend_parameters *fep)
291{
292 return 0;
293}
294
295static void cinergyt2_fe_release(struct dvb_frontend *fe)
296{
297 struct cinergyt2_fe_state *state = fe->demodulator_priv;
298 if (state != NULL)
299 kfree(state);
300}
301
302static struct dvb_frontend_ops cinergyt2_fe_ops;
303
304struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d)
305{
306 struct cinergyt2_fe_state *s = kzalloc(sizeof(
307 struct cinergyt2_fe_state), GFP_KERNEL);
308 if (s == NULL)
309 return NULL;
310
311 s->d = d;
312 memcpy(&s->fe.ops, &cinergyt2_fe_ops, sizeof(struct dvb_frontend_ops));
313 s->fe.demodulator_priv = s;
314 return &s->fe;
315}
316
317
318static struct dvb_frontend_ops cinergyt2_fe_ops = {
319 .info = {
320 .name = DRIVER_NAME,
321 .type = FE_OFDM,
322 .frequency_min = 174000000,
323 .frequency_max = 862000000,
324 .frequency_stepsize = 166667,
325 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2
326 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4
327 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8
328 | FE_CAN_FEC_AUTO | FE_CAN_QPSK
329 | FE_CAN_QAM_16 | FE_CAN_QAM_64
330 | FE_CAN_QAM_AUTO
331 | FE_CAN_TRANSMISSION_MODE_AUTO
332 | FE_CAN_GUARD_INTERVAL_AUTO
333 | FE_CAN_HIERARCHY_AUTO
334 | FE_CAN_RECOVER
335 | FE_CAN_MUTE_TS
336 },
337
338 .release = cinergyt2_fe_release,
339
340 .init = cinergyt2_fe_init,
341 .sleep = cinergyt2_fe_sleep,
342
343 .set_frontend = cinergyt2_fe_set_frontend,
344 .get_frontend = cinergyt2_fe_get_frontend,
345 .get_tune_settings = cinergyt2_fe_get_tune_settings,
346
347 .read_status = cinergyt2_fe_read_status,
348 .read_ber = cinergyt2_fe_read_ber,
349 .read_signal_strength = cinergyt2_fe_read_signal_strength,
350 .read_snr = cinergyt2_fe_read_snr,
351 .read_ucblocks = cinergyt2_fe_read_unc_blocks,
352};
diff --git a/drivers/media/dvb/dvb-usb/cinergyT2.h b/drivers/media/dvb/dvb-usb/cinergyT2.h
new file mode 100644
index 00000000000..84efe03771e
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cinergyT2.h
@@ -0,0 +1,95 @@
1/*
2 * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
3 *
4 * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
5 *
6 * Based on the dvb-usb-framework code and the
7 * original Terratec Cinergy T2 driver by:
8 *
9 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
10 * Holger Waechtler <holger@qanu.de>
11 *
12 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30#ifndef _DVB_USB_CINERGYT2_H_
31#define _DVB_USB_CINERGYT2_H_
32
33#include <linux/usb/input.h>
34
35#define DVB_USB_LOG_PREFIX "cinergyT2"
36#include "dvb-usb.h"
37
38#define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"
39
40extern int dvb_usb_cinergyt2_debug;
41
42#define deb_info(args...) dprintk(dvb_usb_cinergyt2_debug, 0x001, args)
43#define deb_xfer(args...) dprintk(dvb_usb_cinergyt2_debug, 0x002, args)
44#define deb_pll(args...) dprintk(dvb_usb_cinergyt2_debug, 0x004, args)
45#define deb_ts(args...) dprintk(dvb_usb_cinergyt2_debug, 0x008, args)
46#define deb_err(args...) dprintk(dvb_usb_cinergyt2_debug, 0x010, args)
47#define deb_rc(args...) dprintk(dvb_usb_cinergyt2_debug, 0x020, args)
48#define deb_fw(args...) dprintk(dvb_usb_cinergyt2_debug, 0x040, args)
49#define deb_mem(args...) dprintk(dvb_usb_cinergyt2_debug, 0x080, args)
50#define deb_uxfer(args...) dprintk(dvb_usb_cinergyt2_debug, 0x100, args)
51
52
53
54enum cinergyt2_ep1_cmd {
55 CINERGYT2_EP1_PID_TABLE_RESET = 0x01,
56 CINERGYT2_EP1_PID_SETUP = 0x02,
57 CINERGYT2_EP1_CONTROL_STREAM_TRANSFER = 0x03,
58 CINERGYT2_EP1_SET_TUNER_PARAMETERS = 0x04,
59 CINERGYT2_EP1_GET_TUNER_STATUS = 0x05,
60 CINERGYT2_EP1_START_SCAN = 0x06,
61 CINERGYT2_EP1_CONTINUE_SCAN = 0x07,
62 CINERGYT2_EP1_GET_RC_EVENTS = 0x08,
63 CINERGYT2_EP1_SLEEP_MODE = 0x09,
64 CINERGYT2_EP1_GET_FIRMWARE_VERSION = 0x0A
65};
66
67
68struct dvbt_get_status_msg {
69 uint32_t freq;
70 uint8_t bandwidth;
71 uint16_t tps;
72 uint8_t flags;
73 __le16 gain;
74 uint8_t snr;
75 __le32 viterbi_error_rate;
76 uint32_t rs_error_rate;
77 __le32 uncorrected_block_count;
78 uint8_t lock_bits;
79 uint8_t prev_lock_bits;
80} __attribute__((packed));
81
82
83struct dvbt_set_parameters_msg {
84 uint8_t cmd;
85 __le32 freq;
86 uint8_t bandwidth;
87 __le16 tps;
88 uint8_t flags;
89} __attribute__((packed));
90
91
92extern struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d);
93
94#endif /* _DVB_USB_CINERGYT2_H_ */
95
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
new file mode 100644
index 00000000000..acb5fb2d2e7
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -0,0 +1,2017 @@
1/* DVB USB compliant linux driver for Conexant USB reference design.
2 *
3 * The Conexant reference design I saw on their website was only for analogue
4 * capturing (using the cx25842). The box I took to write this driver (reverse
5 * engineered) is the one labeled Medion MD95700. In addition to the cx25842
6 * for analogue capturing it also has a cx22702 DVB-T demodulator on the main
7 * board. Besides it has a atiremote (X10) and a USB2.0 hub onboard.
8 *
9 * Maybe it is a little bit premature to call this driver cxusb, but I assume
10 * the USB protocol is identical or at least inherited from the reference
11 * design, so it can be reused for the "analogue-only" device (if it will
12 * appear at all).
13 *
14 * TODO: Use the cx25840-driver for the analogue part
15 *
16 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
17 * Copyright (C) 2006 Michael Krufky (mkrufky@linuxtv.org)
18 * Copyright (C) 2006, 2007 Chris Pascoe (c.pascoe@itee.uq.edu.au)
19 *
20 * This program is free software; you can redistribute it and/or modify it
21 * under the terms of the GNU General Public License as published by the Free
22 * Software Foundation, version 2.
23 *
24 * see Documentation/dvb/README.dvb-usb for more information
25 */
26#include <media/tuner.h>
27#include <linux/vmalloc.h>
28#include <linux/slab.h>
29
30#include "cxusb.h"
31
32#include "cx22702.h"
33#include "lgdt330x.h"
34#include "mt352.h"
35#include "mt352_priv.h"
36#include "zl10353.h"
37#include "tuner-xc2028.h"
38#include "tuner-simple.h"
39#include "mxl5005s.h"
40#include "max2165.h"
41#include "dib7000p.h"
42#include "dib0070.h"
43#include "lgs8gxx.h"
44#include "atbm8830.h"
45
46/* debug */
47static int dvb_usb_cxusb_debug;
48module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
49MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
50
51DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
52
53#define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args)
54#define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args)
55
56static int cxusb_ctrl_msg(struct dvb_usb_device *d,
57 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
58{
59 int wo = (rbuf == NULL || rlen == 0); /* write-only */
60 u8 sndbuf[1+wlen];
61 memset(sndbuf, 0, 1+wlen);
62
63 sndbuf[0] = cmd;
64 memcpy(&sndbuf[1], wbuf, wlen);
65 if (wo)
66 return dvb_usb_generic_write(d, sndbuf, 1+wlen);
67 else
68 return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
69}
70
71/* GPIO */
72static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
73{
74 struct cxusb_state *st = d->priv;
75 u8 o[2], i;
76
77 if (st->gpio_write_state[GPIO_TUNER] == onoff)
78 return;
79
80 o[0] = GPIO_TUNER;
81 o[1] = onoff;
82 cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
83
84 if (i != 0x01)
85 deb_info("gpio_write failed.\n");
86
87 st->gpio_write_state[GPIO_TUNER] = onoff;
88}
89
90static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask,
91 u8 newval)
92{
93 u8 o[2], gpio_state;
94 int rc;
95
96 o[0] = 0xff & ~changemask; /* mask of bits to keep */
97 o[1] = newval & changemask; /* new values for bits */
98
99 rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1);
100 if (rc < 0 || (gpio_state & changemask) != (newval & changemask))
101 deb_info("bluebird_gpio_write failed.\n");
102
103 return rc < 0 ? rc : gpio_state;
104}
105
106static void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low)
107{
108 cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin);
109 msleep(5);
110 cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0);
111}
112
113static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
114{
115 cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
116}
117
118static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
119 u8 addr, int onoff)
120{
121 u8 o[2] = {addr, onoff};
122 u8 i;
123 int rc;
124
125 rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
126
127 if (rc < 0)
128 return rc;
129 if (i == 0x01)
130 return 0;
131 else {
132 deb_info("gpio_write failed.\n");
133 return -EIO;
134 }
135}
136
137/* I2C */
138static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
139 int num)
140{
141 struct dvb_usb_device *d = i2c_get_adapdata(adap);
142 int i;
143
144 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
145 return -EAGAIN;
146
147 for (i = 0; i < num; i++) {
148
149 if (d->udev->descriptor.idVendor == USB_VID_MEDION)
150 switch (msg[i].addr) {
151 case 0x63:
152 cxusb_gpio_tuner(d, 0);
153 break;
154 default:
155 cxusb_gpio_tuner(d, 1);
156 break;
157 }
158
159 if (msg[i].flags & I2C_M_RD) {
160 /* read only */
161 u8 obuf[3], ibuf[1+msg[i].len];
162 obuf[0] = 0;
163 obuf[1] = msg[i].len;
164 obuf[2] = msg[i].addr;
165 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
166 obuf, 3,
167 ibuf, 1+msg[i].len) < 0) {
168 warn("i2c read failed");
169 break;
170 }
171 memcpy(msg[i].buf, &ibuf[1], msg[i].len);
172 } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) &&
173 msg[i].addr == msg[i+1].addr) {
174 /* write to then read from same address */
175 u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len];
176 obuf[0] = msg[i].len;
177 obuf[1] = msg[i+1].len;
178 obuf[2] = msg[i].addr;
179 memcpy(&obuf[3], msg[i].buf, msg[i].len);
180
181 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
182 obuf, 3+msg[i].len,
183 ibuf, 1+msg[i+1].len) < 0)
184 break;
185
186 if (ibuf[0] != 0x08)
187 deb_i2c("i2c read may have failed\n");
188
189 memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
190
191 i++;
192 } else {
193 /* write only */
194 u8 obuf[2+msg[i].len], ibuf;
195 obuf[0] = msg[i].addr;
196 obuf[1] = msg[i].len;
197 memcpy(&obuf[2], msg[i].buf, msg[i].len);
198
199 if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf,
200 2+msg[i].len, &ibuf,1) < 0)
201 break;
202 if (ibuf != 0x08)
203 deb_i2c("i2c write may have failed\n");
204 }
205 }
206
207 mutex_unlock(&d->i2c_mutex);
208 return i == num ? num : -EREMOTEIO;
209}
210
211static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
212{
213 return I2C_FUNC_I2C;
214}
215
216static struct i2c_algorithm cxusb_i2c_algo = {
217 .master_xfer = cxusb_i2c_xfer,
218 .functionality = cxusb_i2c_func,
219};
220
221static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
222{
223 u8 b = 0;
224 if (onoff)
225 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
226 else
227 return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
228}
229
230static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
231{
232 int ret;
233 if (!onoff)
234 return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0);
235 if (d->state == DVB_USB_STATE_INIT &&
236 usb_set_interface(d->udev, 0, 0) < 0)
237 err("set interface failed");
238 do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
239 !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
240 !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
241 if (!ret) {
242 /* FIXME: We don't know why, but we need to configure the
243 * lgdt3303 with the register settings below on resume */
244 int i;
245 u8 buf, bufs[] = {
246 0x0e, 0x2, 0x00, 0x7f,
247 0x0e, 0x2, 0x02, 0xfe,
248 0x0e, 0x2, 0x02, 0x01,
249 0x0e, 0x2, 0x00, 0x03,
250 0x0e, 0x2, 0x0d, 0x40,
251 0x0e, 0x2, 0x0e, 0x87,
252 0x0e, 0x2, 0x0f, 0x8e,
253 0x0e, 0x2, 0x10, 0x01,
254 0x0e, 0x2, 0x14, 0xd7,
255 0x0e, 0x2, 0x47, 0x88,
256 };
257 msleep(20);
258 for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) {
259 ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE,
260 bufs+i, 4, &buf, 1);
261 if (ret)
262 break;
263 if (buf != 0x8)
264 return -EREMOTEIO;
265 }
266 }
267 return ret;
268}
269
270static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
271{
272 u8 b = 0;
273 if (onoff)
274 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
275 else
276 return 0;
277}
278
279static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff)
280{
281 int rc = 0;
282
283 rc = cxusb_power_ctrl(d, onoff);
284 if (!onoff)
285 cxusb_nano2_led(d, 0);
286
287 return rc;
288}
289
290static int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff)
291{
292 int ret;
293 u8 b;
294 ret = cxusb_power_ctrl(d, onoff);
295 if (!onoff)
296 return ret;
297
298 msleep(128);
299 cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1);
300 msleep(100);
301 return ret;
302}
303
304static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
305{
306 u8 buf[2] = { 0x03, 0x00 };
307 if (onoff)
308 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0);
309 else
310 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0);
311
312 return 0;
313}
314
315static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
316{
317 if (onoff)
318 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0);
319 else
320 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF,
321 NULL, 0, NULL, 0);
322 return 0;
323}
324
325static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d)
326{
327 int ep = d->props.generic_bulk_ctrl_endpoint;
328 const int timeout = 100;
329 const int junk_len = 32;
330 u8 *junk;
331 int rd_count;
332
333 /* Discard remaining data in video pipe */
334 junk = kmalloc(junk_len, GFP_KERNEL);
335 if (!junk)
336 return;
337 while (1) {
338 if (usb_bulk_msg(d->udev,
339 usb_rcvbulkpipe(d->udev, ep),
340 junk, junk_len, &rd_count, timeout) < 0)
341 break;
342 if (!rd_count)
343 break;
344 }
345 kfree(junk);
346}
347
348static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d)
349{
350 struct usb_data_stream_properties *p = &d->props.adapter[0].stream;
351 const int timeout = 100;
352 const int junk_len = p->u.bulk.buffersize;
353 u8 *junk;
354 int rd_count;
355
356 /* Discard remaining data in video pipe */
357 junk = kmalloc(junk_len, GFP_KERNEL);
358 if (!junk)
359 return;
360 while (1) {
361 if (usb_bulk_msg(d->udev,
362 usb_rcvbulkpipe(d->udev, p->endpoint),
363 junk, junk_len, &rd_count, timeout) < 0)
364 break;
365 if (!rd_count)
366 break;
367 }
368 kfree(junk);
369}
370
371static int cxusb_d680_dmb_streaming_ctrl(
372 struct dvb_usb_adapter *adap, int onoff)
373{
374 if (onoff) {
375 u8 buf[2] = { 0x03, 0x00 };
376 cxusb_d680_dmb_drain_video(adap->dev);
377 return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON,
378 buf, sizeof(buf), NULL, 0);
379 } else {
380 int ret = cxusb_ctrl_msg(adap->dev,
381 CMD_STREAMING_OFF, NULL, 0, NULL, 0);
382 return ret;
383 }
384}
385
386static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
387{
388 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
389 u8 ircode[4];
390 int i;
391
392 cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
393
394 *event = 0;
395 *state = REMOTE_NO_KEY_PRESSED;
396
397 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
398 if (rc5_custom(&keymap[i]) == ircode[2] &&
399 rc5_data(&keymap[i]) == ircode[3]) {
400 *event = keymap[i].keycode;
401 *state = REMOTE_KEY_PRESSED;
402
403 return 0;
404 }
405 }
406
407 return 0;
408}
409
410static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
411 int *state)
412{
413 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
414 u8 ircode[4];
415 int i;
416 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
417 .buf = ircode, .len = 4 };
418
419 *event = 0;
420 *state = REMOTE_NO_KEY_PRESSED;
421
422 if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
423 return 0;
424
425 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
426 if (rc5_custom(&keymap[i]) == ircode[1] &&
427 rc5_data(&keymap[i]) == ircode[2]) {
428 *event = keymap[i].keycode;
429 *state = REMOTE_KEY_PRESSED;
430
431 return 0;
432 }
433 }
434
435 return 0;
436}
437
438static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
439 int *state)
440{
441 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
442 u8 ircode[2];
443 int i;
444
445 *event = 0;
446 *state = REMOTE_NO_KEY_PRESSED;
447
448 if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0)
449 return 0;
450
451 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
452 if (rc5_custom(&keymap[i]) == ircode[0] &&
453 rc5_data(&keymap[i]) == ircode[1]) {
454 *event = keymap[i].keycode;
455 *state = REMOTE_KEY_PRESSED;
456
457 return 0;
458 }
459 }
460
461 return 0;
462}
463
464static struct rc_map_table rc_map_dvico_mce_table[] = {
465 { 0xfe02, KEY_TV },
466 { 0xfe0e, KEY_MP3 },
467 { 0xfe1a, KEY_DVD },
468 { 0xfe1e, KEY_FAVORITES },
469 { 0xfe16, KEY_SETUP },
470 { 0xfe46, KEY_POWER2 },
471 { 0xfe0a, KEY_EPG },
472 { 0xfe49, KEY_BACK },
473 { 0xfe4d, KEY_MENU },
474 { 0xfe51, KEY_UP },
475 { 0xfe5b, KEY_LEFT },
476 { 0xfe5f, KEY_RIGHT },
477 { 0xfe53, KEY_DOWN },
478 { 0xfe5e, KEY_OK },
479 { 0xfe59, KEY_INFO },
480 { 0xfe55, KEY_TAB },
481 { 0xfe0f, KEY_PREVIOUSSONG },/* Replay */
482 { 0xfe12, KEY_NEXTSONG }, /* Skip */
483 { 0xfe42, KEY_ENTER }, /* Windows/Start */
484 { 0xfe15, KEY_VOLUMEUP },
485 { 0xfe05, KEY_VOLUMEDOWN },
486 { 0xfe11, KEY_CHANNELUP },
487 { 0xfe09, KEY_CHANNELDOWN },
488 { 0xfe52, KEY_CAMERA },
489 { 0xfe5a, KEY_TUNER }, /* Live */
490 { 0xfe19, KEY_OPEN },
491 { 0xfe0b, KEY_1 },
492 { 0xfe17, KEY_2 },
493 { 0xfe1b, KEY_3 },
494 { 0xfe07, KEY_4 },
495 { 0xfe50, KEY_5 },
496 { 0xfe54, KEY_6 },
497 { 0xfe48, KEY_7 },
498 { 0xfe4c, KEY_8 },
499 { 0xfe58, KEY_9 },
500 { 0xfe13, KEY_ANGLE }, /* Aspect */
501 { 0xfe03, KEY_0 },
502 { 0xfe1f, KEY_ZOOM },
503 { 0xfe43, KEY_REWIND },
504 { 0xfe47, KEY_PLAYPAUSE },
505 { 0xfe4f, KEY_FASTFORWARD },
506 { 0xfe57, KEY_MUTE },
507 { 0xfe0d, KEY_STOP },
508 { 0xfe01, KEY_RECORD },
509 { 0xfe4e, KEY_POWER },
510};
511
512static struct rc_map_table rc_map_dvico_portable_table[] = {
513 { 0xfc02, KEY_SETUP }, /* Profile */
514 { 0xfc43, KEY_POWER2 },
515 { 0xfc06, KEY_EPG },
516 { 0xfc5a, KEY_BACK },
517 { 0xfc05, KEY_MENU },
518 { 0xfc47, KEY_INFO },
519 { 0xfc01, KEY_TAB },
520 { 0xfc42, KEY_PREVIOUSSONG },/* Replay */
521 { 0xfc49, KEY_VOLUMEUP },
522 { 0xfc09, KEY_VOLUMEDOWN },
523 { 0xfc54, KEY_CHANNELUP },
524 { 0xfc0b, KEY_CHANNELDOWN },
525 { 0xfc16, KEY_CAMERA },
526 { 0xfc40, KEY_TUNER }, /* ATV/DTV */
527 { 0xfc45, KEY_OPEN },
528 { 0xfc19, KEY_1 },
529 { 0xfc18, KEY_2 },
530 { 0xfc1b, KEY_3 },
531 { 0xfc1a, KEY_4 },
532 { 0xfc58, KEY_5 },
533 { 0xfc59, KEY_6 },
534 { 0xfc15, KEY_7 },
535 { 0xfc14, KEY_8 },
536 { 0xfc17, KEY_9 },
537 { 0xfc44, KEY_ANGLE }, /* Aspect */
538 { 0xfc55, KEY_0 },
539 { 0xfc07, KEY_ZOOM },
540 { 0xfc0a, KEY_REWIND },
541 { 0xfc08, KEY_PLAYPAUSE },
542 { 0xfc4b, KEY_FASTFORWARD },
543 { 0xfc5b, KEY_MUTE },
544 { 0xfc04, KEY_STOP },
545 { 0xfc56, KEY_RECORD },
546 { 0xfc57, KEY_POWER },
547 { 0xfc41, KEY_UNKNOWN }, /* INPUT */
548 { 0xfc00, KEY_UNKNOWN }, /* HD */
549};
550
551static struct rc_map_table rc_map_d680_dmb_table[] = {
552 { 0x0038, KEY_UNKNOWN }, /* TV/AV */
553 { 0x080c, KEY_ZOOM },
554 { 0x0800, KEY_0 },
555 { 0x0001, KEY_1 },
556 { 0x0802, KEY_2 },
557 { 0x0003, KEY_3 },
558 { 0x0804, KEY_4 },
559 { 0x0005, KEY_5 },
560 { 0x0806, KEY_6 },
561 { 0x0007, KEY_7 },
562 { 0x0808, KEY_8 },
563 { 0x0009, KEY_9 },
564 { 0x000a, KEY_MUTE },
565 { 0x0829, KEY_BACK },
566 { 0x0012, KEY_CHANNELUP },
567 { 0x0813, KEY_CHANNELDOWN },
568 { 0x002b, KEY_VOLUMEUP },
569 { 0x082c, KEY_VOLUMEDOWN },
570 { 0x0020, KEY_UP },
571 { 0x0821, KEY_DOWN },
572 { 0x0011, KEY_LEFT },
573 { 0x0810, KEY_RIGHT },
574 { 0x000d, KEY_OK },
575 { 0x081f, KEY_RECORD },
576 { 0x0017, KEY_PLAYPAUSE },
577 { 0x0816, KEY_PLAYPAUSE },
578 { 0x000b, KEY_STOP },
579 { 0x0827, KEY_FASTFORWARD },
580 { 0x0026, KEY_REWIND },
581 { 0x081e, KEY_UNKNOWN }, /* Time Shift */
582 { 0x000e, KEY_UNKNOWN }, /* Snapshot */
583 { 0x082d, KEY_UNKNOWN }, /* Mouse Cursor */
584 { 0x000f, KEY_UNKNOWN }, /* Minimize/Maximize */
585 { 0x0814, KEY_UNKNOWN }, /* Shuffle */
586 { 0x0025, KEY_POWER },
587};
588
589static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
590{
591 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 };
592 static u8 reset [] = { RESET, 0x80 };
593 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
594 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
595 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
596 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
597
598 mt352_write(fe, clock_config, sizeof(clock_config));
599 udelay(200);
600 mt352_write(fe, reset, sizeof(reset));
601 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
602
603 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
604 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
605 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
606
607 return 0;
608}
609
610static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
611{ /* used in both lgz201 and th7579 */
612 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x29 };
613 static u8 reset [] = { RESET, 0x80 };
614 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
615 static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
616 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
617 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
618
619 mt352_write(fe, clock_config, sizeof(clock_config));
620 udelay(200);
621 mt352_write(fe, reset, sizeof(reset));
622 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
623
624 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
625 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
626 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
627 return 0;
628}
629
630static struct cx22702_config cxusb_cx22702_config = {
631 .demod_address = 0x63,
632 .output_mode = CX22702_PARALLEL_OUTPUT,
633};
634
635static struct lgdt330x_config cxusb_lgdt3303_config = {
636 .demod_address = 0x0e,
637 .demod_chip = LGDT3303,
638};
639
640static struct lgdt330x_config cxusb_aver_lgdt3303_config = {
641 .demod_address = 0x0e,
642 .demod_chip = LGDT3303,
643 .clock_polarity_flip = 2,
644};
645
646static struct mt352_config cxusb_dee1601_config = {
647 .demod_address = 0x0f,
648 .demod_init = cxusb_dee1601_demod_init,
649};
650
651static struct zl10353_config cxusb_zl10353_dee1601_config = {
652 .demod_address = 0x0f,
653 .parallel_ts = 1,
654};
655
656static struct mt352_config cxusb_mt352_config = {
657 /* used in both lgz201 and th7579 */
658 .demod_address = 0x0f,
659 .demod_init = cxusb_mt352_demod_init,
660};
661
662static struct zl10353_config cxusb_zl10353_xc3028_config = {
663 .demod_address = 0x0f,
664 .if2 = 45600,
665 .no_tuner = 1,
666 .parallel_ts = 1,
667};
668
669static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = {
670 .demod_address = 0x0f,
671 .if2 = 45600,
672 .no_tuner = 1,
673 .parallel_ts = 1,
674 .disable_i2c_gate_ctrl = 1,
675};
676
677static struct mt352_config cxusb_mt352_xc3028_config = {
678 .demod_address = 0x0f,
679 .if2 = 4560,
680 .no_tuner = 1,
681 .demod_init = cxusb_mt352_demod_init,
682};
683
684/* FIXME: needs tweaking */
685static struct mxl5005s_config aver_a868r_tuner = {
686 .i2c_address = 0x63,
687 .if_freq = 6000000UL,
688 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
689 .agc_mode = MXL_SINGLE_AGC,
690 .tracking_filter = MXL_TF_C,
691 .rssi_enable = MXL_RSSI_ENABLE,
692 .cap_select = MXL_CAP_SEL_ENABLE,
693 .div_out = MXL_DIV_OUT_4,
694 .clock_out = MXL_CLOCK_OUT_DISABLE,
695 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
696 .top = MXL5005S_TOP_25P2,
697 .mod_mode = MXL_DIGITAL_MODE,
698 .if_mode = MXL_ZERO_IF,
699 .AgcMasterByte = 0x00,
700};
701
702/* FIXME: needs tweaking */
703static struct mxl5005s_config d680_dmb_tuner = {
704 .i2c_address = 0x63,
705 .if_freq = 36125000UL,
706 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
707 .agc_mode = MXL_SINGLE_AGC,
708 .tracking_filter = MXL_TF_C,
709 .rssi_enable = MXL_RSSI_ENABLE,
710 .cap_select = MXL_CAP_SEL_ENABLE,
711 .div_out = MXL_DIV_OUT_4,
712 .clock_out = MXL_CLOCK_OUT_DISABLE,
713 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
714 .top = MXL5005S_TOP_25P2,
715 .mod_mode = MXL_DIGITAL_MODE,
716 .if_mode = MXL_ZERO_IF,
717 .AgcMasterByte = 0x00,
718};
719
720static struct max2165_config mygica_d689_max2165_cfg = {
721 .i2c_address = 0x60,
722 .osc_clk = 20
723};
724
725/* Callbacks for DVB USB */
726static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
727{
728 dvb_attach(simple_tuner_attach, adap->fe,
729 &adap->dev->i2c_adap, 0x61,
730 TUNER_PHILIPS_FMD1216ME_MK3);
731 return 0;
732}
733
734static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap)
735{
736 dvb_attach(dvb_pll_attach, adap->fe, 0x61,
737 NULL, DVB_PLL_THOMSON_DTT7579);
738 return 0;
739}
740
741static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap)
742{
743 dvb_attach(dvb_pll_attach, adap->fe, 0x61, NULL, DVB_PLL_LG_Z201);
744 return 0;
745}
746
747static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
748{
749 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
750 NULL, DVB_PLL_THOMSON_DTT7579);
751 return 0;
752}
753
754static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
755{
756 dvb_attach(simple_tuner_attach, adap->fe,
757 &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF);
758 return 0;
759}
760
761static int dvico_bluebird_xc2028_callback(void *ptr, int component,
762 int command, int arg)
763{
764 struct dvb_usb_adapter *adap = ptr;
765 struct dvb_usb_device *d = adap->dev;
766
767 switch (command) {
768 case XC2028_TUNER_RESET:
769 deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
770 cxusb_bluebird_gpio_pulse(d, 0x01, 1);
771 break;
772 case XC2028_RESET_CLK:
773 deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
774 break;
775 default:
776 deb_info("%s: unknown command %d, arg %d\n", __func__,
777 command, arg);
778 return -EINVAL;
779 }
780
781 return 0;
782}
783
784static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
785{
786 struct dvb_frontend *fe;
787 struct xc2028_config cfg = {
788 .i2c_adap = &adap->dev->i2c_adap,
789 .i2c_addr = 0x61,
790 };
791 static struct xc2028_ctrl ctl = {
792 .fname = XC2028_DEFAULT_FIRMWARE,
793 .max_len = 64,
794 .demod = XC3028_FE_ZARLINK456,
795 };
796
797 /* FIXME: generalize & move to common area */
798 adap->fe->callback = dvico_bluebird_xc2028_callback;
799
800 fe = dvb_attach(xc2028_attach, adap->fe, &cfg);
801 if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
802 return -EIO;
803
804 fe->ops.tuner_ops.set_config(fe, &ctl);
805
806 return 0;
807}
808
809static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
810{
811 dvb_attach(mxl5005s_attach, adap->fe,
812 &adap->dev->i2c_adap, &aver_a868r_tuner);
813 return 0;
814}
815
816static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap)
817{
818 struct dvb_frontend *fe;
819 fe = dvb_attach(mxl5005s_attach, adap->fe,
820 &adap->dev->i2c_adap, &d680_dmb_tuner);
821 return (fe == NULL) ? -EIO : 0;
822}
823
824static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap)
825{
826 struct dvb_frontend *fe;
827 fe = dvb_attach(max2165_attach, adap->fe,
828 &adap->dev->i2c_adap, &mygica_d689_max2165_cfg);
829 return (fe == NULL) ? -EIO : 0;
830}
831
832static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
833{
834 u8 b;
835 if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
836 err("set interface failed");
837
838 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
839
840 if ((adap->fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
841 &adap->dev->i2c_adap)) != NULL)
842 return 0;
843
844 return -EIO;
845}
846
847static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
848{
849 if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
850 err("set interface failed");
851
852 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
853
854 if ((adap->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config,
855 &adap->dev->i2c_adap)) != NULL)
856 return 0;
857
858 return -EIO;
859}
860
861static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
862{
863 adap->fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
864 &adap->dev->i2c_adap);
865 if (adap->fe != NULL)
866 return 0;
867
868 return -EIO;
869}
870
871static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
872{
873 /* used in both lgz201 and th7579 */
874 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
875 err("set interface failed");
876
877 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
878
879 if ((adap->fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
880 &adap->dev->i2c_adap)) != NULL)
881 return 0;
882
883 return -EIO;
884}
885
886static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
887{
888 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
889 err("set interface failed");
890
891 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
892
893 if (((adap->fe = dvb_attach(mt352_attach, &cxusb_dee1601_config,
894 &adap->dev->i2c_adap)) != NULL) ||
895 ((adap->fe = dvb_attach(zl10353_attach,
896 &cxusb_zl10353_dee1601_config,
897 &adap->dev->i2c_adap)) != NULL))
898 return 0;
899
900 return -EIO;
901}
902
903static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
904{
905 u8 ircode[4];
906 int i;
907 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
908 .buf = ircode, .len = 4 };
909
910 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
911 err("set interface failed");
912
913 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
914
915 /* reset the tuner and demodulator */
916 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
917 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
918 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
919
920 if ((adap->fe = dvb_attach(zl10353_attach,
921 &cxusb_zl10353_xc3028_config_no_i2c_gate,
922 &adap->dev->i2c_adap)) == NULL)
923 return -EIO;
924
925 /* try to determine if there is no IR decoder on the I2C bus */
926 for (i = 0; adap->dev->props.rc.legacy.rc_map_table != NULL && i < 5; i++) {
927 msleep(20);
928 if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
929 goto no_IR;
930 if (ircode[0] == 0 && ircode[1] == 0)
931 continue;
932 if (ircode[2] + ircode[3] != 0xff) {
933no_IR:
934 adap->dev->props.rc.legacy.rc_map_table = NULL;
935 info("No IR receiver detected on this device.");
936 break;
937 }
938 }
939
940 return 0;
941}
942
943static struct dibx000_agc_config dib7070_agc_config = {
944 .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
945
946 /*
947 * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5,
948 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
949 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0
950 */
951 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) |
952 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
953 .inv_gain = 600,
954 .time_stabiliz = 10,
955 .alpha_level = 0,
956 .thlock = 118,
957 .wbd_inv = 0,
958 .wbd_ref = 3530,
959 .wbd_sel = 1,
960 .wbd_alpha = 5,
961 .agc1_max = 65535,
962 .agc1_min = 0,
963 .agc2_max = 65535,
964 .agc2_min = 0,
965 .agc1_pt1 = 0,
966 .agc1_pt2 = 40,
967 .agc1_pt3 = 183,
968 .agc1_slope1 = 206,
969 .agc1_slope2 = 255,
970 .agc2_pt1 = 72,
971 .agc2_pt2 = 152,
972 .agc2_slope1 = 88,
973 .agc2_slope2 = 90,
974 .alpha_mant = 17,
975 .alpha_exp = 27,
976 .beta_mant = 23,
977 .beta_exp = 51,
978 .perform_agc_softsplit = 0,
979};
980
981static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
982 .internal = 60000,
983 .sampling = 15000,
984 .pll_prediv = 1,
985 .pll_ratio = 20,
986 .pll_range = 3,
987 .pll_reset = 1,
988 .pll_bypass = 0,
989 .enable_refdiv = 0,
990 .bypclk_div = 0,
991 .IO_CLK_en_core = 1,
992 .ADClkSrc = 1,
993 .modulo = 2,
994 /* refsel, sel, freq_15k */
995 .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0),
996 .ifreq = (0 << 25) | 0,
997 .timf = 20452225,
998 .xtal_hz = 12000000,
999};
1000
1001static struct dib7000p_config cxusb_dualdig4_rev2_config = {
1002 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
1003 .output_mpeg2_in_188_bytes = 1,
1004
1005 .agc_config_count = 1,
1006 .agc = &dib7070_agc_config,
1007 .bw = &dib7070_bw_config_12_mhz,
1008 .tuner_is_baseband = 1,
1009 .spur_protect = 1,
1010
1011 .gpio_dir = 0xfcef,
1012 .gpio_val = 0x0110,
1013
1014 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1015
1016 .hostbus_diversity = 1,
1017};
1018
1019static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
1020{
1021 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1022 err("set interface failed");
1023
1024 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1025
1026 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1027
1028 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1029 &cxusb_dualdig4_rev2_config) < 0) {
1030 printk(KERN_WARNING "Unable to enumerate dib7000p\n");
1031 return -ENODEV;
1032 }
1033
1034 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1035 &cxusb_dualdig4_rev2_config);
1036 if (adap->fe == NULL)
1037 return -EIO;
1038
1039 return 0;
1040}
1041
1042static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1043{
1044 return dib7000p_set_gpio(fe, 8, 0, !onoff);
1045}
1046
1047static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1048{
1049 return 0;
1050}
1051
1052static struct dib0070_config dib7070p_dib0070_config = {
1053 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1054 .reset = dib7070_tuner_reset,
1055 .sleep = dib7070_tuner_sleep,
1056 .clock_khz = 12000,
1057};
1058
1059struct dib0700_adapter_state {
1060 int (*set_param_save) (struct dvb_frontend *,
1061 struct dvb_frontend_parameters *);
1062};
1063
1064static int dib7070_set_param_override(struct dvb_frontend *fe,
1065 struct dvb_frontend_parameters *fep)
1066{
1067 struct dvb_usb_adapter *adap = fe->dvb->priv;
1068 struct dib0700_adapter_state *state = adap->priv;
1069
1070 u16 offset;
1071 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1072 switch (band) {
1073 case BAND_VHF: offset = 950; break;
1074 default:
1075 case BAND_UHF: offset = 550; break;
1076 }
1077
1078 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1079
1080 return state->set_param_save(fe, fep);
1081}
1082
1083static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap)
1084{
1085 struct dib0700_adapter_state *st = adap->priv;
1086 struct i2c_adapter *tun_i2c =
1087 dib7000p_get_i2c_master(adap->fe,
1088 DIBX000_I2C_INTERFACE_TUNER, 1);
1089
1090 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1091 &dib7070p_dib0070_config) == NULL)
1092 return -ENODEV;
1093
1094 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1095 adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override;
1096 return 0;
1097}
1098
1099static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
1100{
1101 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1102 err("set interface failed");
1103
1104 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1105
1106 /* reset the tuner and demodulator */
1107 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
1108 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
1109 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1110
1111 if ((adap->fe = dvb_attach(zl10353_attach,
1112 &cxusb_zl10353_xc3028_config,
1113 &adap->dev->i2c_adap)) != NULL)
1114 return 0;
1115
1116 if ((adap->fe = dvb_attach(mt352_attach,
1117 &cxusb_mt352_xc3028_config,
1118 &adap->dev->i2c_adap)) != NULL)
1119 return 0;
1120
1121 return -EIO;
1122}
1123
1124static struct lgs8gxx_config d680_lgs8gl5_cfg = {
1125 .prod = LGS8GXX_PROD_LGS8GL5,
1126 .demod_address = 0x19,
1127 .serial_ts = 0,
1128 .ts_clk_pol = 0,
1129 .ts_clk_gated = 1,
1130 .if_clk_freq = 30400, /* 30.4 MHz */
1131 .if_freq = 5725, /* 5.725 MHz */
1132 .if_neg_center = 0,
1133 .ext_adc = 0,
1134 .adc_signed = 0,
1135 .if_neg_edge = 0,
1136};
1137
1138static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
1139{
1140 struct dvb_usb_device *d = adap->dev;
1141 int n;
1142
1143 /* Select required USB configuration */
1144 if (usb_set_interface(d->udev, 0, 0) < 0)
1145 err("set interface failed");
1146
1147 /* Unblock all USB pipes */
1148 usb_clear_halt(d->udev,
1149 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1150 usb_clear_halt(d->udev,
1151 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1152 usb_clear_halt(d->udev,
1153 usb_rcvbulkpipe(d->udev, d->props.adapter[0].stream.endpoint));
1154
1155 /* Drain USB pipes to avoid hang after reboot */
1156 for (n = 0; n < 5; n++) {
1157 cxusb_d680_dmb_drain_message(d);
1158 cxusb_d680_dmb_drain_video(d);
1159 msleep(200);
1160 }
1161
1162 /* Reset the tuner */
1163 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1164 err("clear tuner gpio failed");
1165 return -EIO;
1166 }
1167 msleep(100);
1168 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1169 err("set tuner gpio failed");
1170 return -EIO;
1171 }
1172 msleep(100);
1173
1174 /* Attach frontend */
1175 adap->fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap);
1176 if (adap->fe == NULL)
1177 return -EIO;
1178
1179 return 0;
1180}
1181
1182static struct atbm8830_config mygica_d689_atbm8830_cfg = {
1183 .prod = ATBM8830_PROD_8830,
1184 .demod_address = 0x40,
1185 .serial_ts = 0,
1186 .ts_sampling_edge = 1,
1187 .ts_clk_gated = 0,
1188 .osc_clk_freq = 30400, /* in kHz */
1189 .if_freq = 0, /* zero IF */
1190 .zif_swap_iq = 1,
1191 .agc_min = 0x2E,
1192 .agc_max = 0x90,
1193 .agc_hold_loop = 0,
1194};
1195
1196static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
1197{
1198 struct dvb_usb_device *d = adap->dev;
1199
1200 /* Select required USB configuration */
1201 if (usb_set_interface(d->udev, 0, 0) < 0)
1202 err("set interface failed");
1203
1204 /* Unblock all USB pipes */
1205 usb_clear_halt(d->udev,
1206 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1207 usb_clear_halt(d->udev,
1208 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1209 usb_clear_halt(d->udev,
1210 usb_rcvbulkpipe(d->udev, d->props.adapter[0].stream.endpoint));
1211
1212
1213 /* Reset the tuner */
1214 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1215 err("clear tuner gpio failed");
1216 return -EIO;
1217 }
1218 msleep(100);
1219 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1220 err("set tuner gpio failed");
1221 return -EIO;
1222 }
1223 msleep(100);
1224
1225 /* Attach frontend */
1226 adap->fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg,
1227 &d->i2c_adap);
1228 if (adap->fe == NULL)
1229 return -EIO;
1230
1231 return 0;
1232}
1233
1234/*
1235 * DViCO has shipped two devices with the same USB ID, but only one of them
1236 * needs a firmware download. Check the device class details to see if they
1237 * have non-default values to decide whether the device is actually cold or
1238 * not, and forget a match if it turns out we selected the wrong device.
1239 */
1240static int bluebird_fx2_identify_state(struct usb_device *udev,
1241 struct dvb_usb_device_properties *props,
1242 struct dvb_usb_device_description **desc,
1243 int *cold)
1244{
1245 int wascold = *cold;
1246
1247 *cold = udev->descriptor.bDeviceClass == 0xff &&
1248 udev->descriptor.bDeviceSubClass == 0xff &&
1249 udev->descriptor.bDeviceProtocol == 0xff;
1250
1251 if (*cold && !wascold)
1252 *desc = NULL;
1253
1254 return 0;
1255}
1256
1257/*
1258 * DViCO bluebird firmware needs the "warm" product ID to be patched into the
1259 * firmware file before download.
1260 */
1261
1262static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
1263static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
1264 const struct firmware *fw)
1265{
1266 int pos;
1267
1268 for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
1269 int idoff = dvico_firmware_id_offsets[pos];
1270
1271 if (fw->size < idoff + 4)
1272 continue;
1273
1274 if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
1275 fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
1276 struct firmware new_fw;
1277 u8 *new_fw_data = vmalloc(fw->size);
1278 int ret;
1279
1280 if (!new_fw_data)
1281 return -ENOMEM;
1282
1283 memcpy(new_fw_data, fw->data, fw->size);
1284 new_fw.size = fw->size;
1285 new_fw.data = new_fw_data;
1286
1287 new_fw_data[idoff + 2] =
1288 le16_to_cpu(udev->descriptor.idProduct) + 1;
1289 new_fw_data[idoff + 3] =
1290 le16_to_cpu(udev->descriptor.idProduct) >> 8;
1291
1292 ret = usb_cypress_load_firmware(udev, &new_fw,
1293 CYPRESS_FX2);
1294 vfree(new_fw_data);
1295 return ret;
1296 }
1297 }
1298
1299 return -EINVAL;
1300}
1301
1302/* DVB USB Driver stuff */
1303static struct dvb_usb_device_properties cxusb_medion_properties;
1304static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
1305static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
1306static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
1307static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
1308static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
1309static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties;
1310static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
1311static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
1312static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
1313static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
1314static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
1315
1316static int cxusb_probe(struct usb_interface *intf,
1317 const struct usb_device_id *id)
1318{
1319 if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
1320 THIS_MODULE, NULL, adapter_nr) ||
1321 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
1322 THIS_MODULE, NULL, adapter_nr) ||
1323 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
1324 THIS_MODULE, NULL, adapter_nr) ||
1325 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
1326 THIS_MODULE, NULL, adapter_nr) ||
1327 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
1328 THIS_MODULE, NULL, adapter_nr) ||
1329 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
1330 THIS_MODULE, NULL, adapter_nr) ||
1331 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
1332 THIS_MODULE, NULL, adapter_nr) ||
1333 0 == dvb_usb_device_init(intf,
1334 &cxusb_bluebird_nano2_needsfirmware_properties,
1335 THIS_MODULE, NULL, adapter_nr) ||
1336 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
1337 THIS_MODULE, NULL, adapter_nr) ||
1338 0 == dvb_usb_device_init(intf,
1339 &cxusb_bluebird_dualdig4_rev2_properties,
1340 THIS_MODULE, NULL, adapter_nr) ||
1341 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
1342 THIS_MODULE, NULL, adapter_nr) ||
1343 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
1344 THIS_MODULE, NULL, adapter_nr) ||
1345 0)
1346 return 0;
1347
1348 return -EINVAL;
1349}
1350
1351static struct usb_device_id cxusb_table [] = {
1352 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
1353 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
1354 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
1355 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
1356 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
1357 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
1358 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
1359 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
1360 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
1361 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
1362 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
1363 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
1364 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
1365 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
1366 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
1367 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
1368 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
1369 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
1370 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
1371 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
1372 {} /* Terminating entry */
1373};
1374MODULE_DEVICE_TABLE (usb, cxusb_table);
1375
1376static struct dvb_usb_device_properties cxusb_medion_properties = {
1377 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1378
1379 .usb_ctrl = CYPRESS_FX2,
1380
1381 .size_of_priv = sizeof(struct cxusb_state),
1382
1383 .num_adapters = 1,
1384 .adapter = {
1385 {
1386 .streaming_ctrl = cxusb_streaming_ctrl,
1387 .frontend_attach = cxusb_cx22702_frontend_attach,
1388 .tuner_attach = cxusb_fmd1216me_tuner_attach,
1389 /* parameter for the MPEG2-data transfer */
1390 .stream = {
1391 .type = USB_BULK,
1392 .count = 5,
1393 .endpoint = 0x02,
1394 .u = {
1395 .bulk = {
1396 .buffersize = 8192,
1397 }
1398 }
1399 },
1400
1401 },
1402 },
1403 .power_ctrl = cxusb_power_ctrl,
1404
1405 .i2c_algo = &cxusb_i2c_algo,
1406
1407 .generic_bulk_ctrl_endpoint = 0x01,
1408
1409 .num_device_descs = 1,
1410 .devices = {
1411 { "Medion MD95700 (MDUSBTV-HYBRID)",
1412 { NULL },
1413 { &cxusb_table[0], NULL },
1414 },
1415 }
1416};
1417
1418static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
1419 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1420
1421 .usb_ctrl = DEVICE_SPECIFIC,
1422 .firmware = "dvb-usb-bluebird-01.fw",
1423 .download_firmware = bluebird_patch_dvico_firmware_download,
1424 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1425 use usb alt setting 7 for EP2 transfer (atsc) */
1426
1427 .size_of_priv = sizeof(struct cxusb_state),
1428
1429 .num_adapters = 1,
1430 .adapter = {
1431 {
1432 .streaming_ctrl = cxusb_streaming_ctrl,
1433 .frontend_attach = cxusb_lgdt3303_frontend_attach,
1434 .tuner_attach = cxusb_lgh064f_tuner_attach,
1435
1436 /* parameter for the MPEG2-data transfer */
1437 .stream = {
1438 .type = USB_BULK,
1439 .count = 5,
1440 .endpoint = 0x02,
1441 .u = {
1442 .bulk = {
1443 .buffersize = 8192,
1444 }
1445 }
1446 },
1447 },
1448 },
1449
1450 .power_ctrl = cxusb_bluebird_power_ctrl,
1451
1452 .i2c_algo = &cxusb_i2c_algo,
1453
1454 .rc.legacy = {
1455 .rc_interval = 100,
1456 .rc_map_table = rc_map_dvico_portable_table,
1457 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1458 .rc_query = cxusb_rc_query,
1459 },
1460
1461 .generic_bulk_ctrl_endpoint = 0x01,
1462
1463 .num_device_descs = 1,
1464 .devices = {
1465 { "DViCO FusionHDTV5 USB Gold",
1466 { &cxusb_table[1], NULL },
1467 { &cxusb_table[2], NULL },
1468 },
1469 }
1470};
1471
1472static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
1473 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1474
1475 .usb_ctrl = DEVICE_SPECIFIC,
1476 .firmware = "dvb-usb-bluebird-01.fw",
1477 .download_firmware = bluebird_patch_dvico_firmware_download,
1478 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1479 use usb alt setting 7 for EP2 transfer (atsc) */
1480
1481 .size_of_priv = sizeof(struct cxusb_state),
1482
1483 .num_adapters = 1,
1484 .adapter = {
1485 {
1486 .streaming_ctrl = cxusb_streaming_ctrl,
1487 .frontend_attach = cxusb_dee1601_frontend_attach,
1488 .tuner_attach = cxusb_dee1601_tuner_attach,
1489 /* parameter for the MPEG2-data transfer */
1490 .stream = {
1491 .type = USB_BULK,
1492 .count = 5,
1493 .endpoint = 0x04,
1494 .u = {
1495 .bulk = {
1496 .buffersize = 8192,
1497 }
1498 }
1499 },
1500 },
1501 },
1502
1503 .power_ctrl = cxusb_bluebird_power_ctrl,
1504
1505 .i2c_algo = &cxusb_i2c_algo,
1506
1507 .rc.legacy = {
1508 .rc_interval = 150,
1509 .rc_map_table = rc_map_dvico_mce_table,
1510 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
1511 .rc_query = cxusb_rc_query,
1512 },
1513
1514 .generic_bulk_ctrl_endpoint = 0x01,
1515
1516 .num_device_descs = 3,
1517 .devices = {
1518 { "DViCO FusionHDTV DVB-T Dual USB",
1519 { &cxusb_table[3], NULL },
1520 { &cxusb_table[4], NULL },
1521 },
1522 { "DigitalNow DVB-T Dual USB",
1523 { &cxusb_table[9], NULL },
1524 { &cxusb_table[10], NULL },
1525 },
1526 { "DViCO FusionHDTV DVB-T Dual Digital 2",
1527 { &cxusb_table[11], NULL },
1528 { &cxusb_table[12], NULL },
1529 },
1530 }
1531};
1532
1533static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
1534 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1535
1536 .usb_ctrl = DEVICE_SPECIFIC,
1537 .firmware = "dvb-usb-bluebird-01.fw",
1538 .download_firmware = bluebird_patch_dvico_firmware_download,
1539 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1540 use usb alt setting 7 for EP2 transfer (atsc) */
1541
1542 .size_of_priv = sizeof(struct cxusb_state),
1543
1544 .num_adapters = 2,
1545 .adapter = {
1546 {
1547 .streaming_ctrl = cxusb_streaming_ctrl,
1548 .frontend_attach = cxusb_mt352_frontend_attach,
1549 .tuner_attach = cxusb_lgz201_tuner_attach,
1550
1551 /* parameter for the MPEG2-data transfer */
1552 .stream = {
1553 .type = USB_BULK,
1554 .count = 5,
1555 .endpoint = 0x04,
1556 .u = {
1557 .bulk = {
1558 .buffersize = 8192,
1559 }
1560 }
1561 },
1562 },
1563 },
1564 .power_ctrl = cxusb_bluebird_power_ctrl,
1565
1566 .i2c_algo = &cxusb_i2c_algo,
1567
1568 .rc.legacy = {
1569 .rc_interval = 100,
1570 .rc_map_table = rc_map_dvico_portable_table,
1571 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1572 .rc_query = cxusb_rc_query,
1573 },
1574
1575 .generic_bulk_ctrl_endpoint = 0x01,
1576 .num_device_descs = 1,
1577 .devices = {
1578 { "DViCO FusionHDTV DVB-T USB (LGZ201)",
1579 { &cxusb_table[5], NULL },
1580 { &cxusb_table[6], NULL },
1581 },
1582 }
1583};
1584
1585static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
1586 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1587
1588 .usb_ctrl = DEVICE_SPECIFIC,
1589 .firmware = "dvb-usb-bluebird-01.fw",
1590 .download_firmware = bluebird_patch_dvico_firmware_download,
1591 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1592 use usb alt setting 7 for EP2 transfer (atsc) */
1593
1594 .size_of_priv = sizeof(struct cxusb_state),
1595
1596 .num_adapters = 1,
1597 .adapter = {
1598 {
1599 .streaming_ctrl = cxusb_streaming_ctrl,
1600 .frontend_attach = cxusb_mt352_frontend_attach,
1601 .tuner_attach = cxusb_dtt7579_tuner_attach,
1602
1603 /* parameter for the MPEG2-data transfer */
1604 .stream = {
1605 .type = USB_BULK,
1606 .count = 5,
1607 .endpoint = 0x04,
1608 .u = {
1609 .bulk = {
1610 .buffersize = 8192,
1611 }
1612 }
1613 },
1614 },
1615 },
1616 .power_ctrl = cxusb_bluebird_power_ctrl,
1617
1618 .i2c_algo = &cxusb_i2c_algo,
1619
1620 .rc.legacy = {
1621 .rc_interval = 100,
1622 .rc_map_table = rc_map_dvico_portable_table,
1623 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1624 .rc_query = cxusb_rc_query,
1625 },
1626
1627 .generic_bulk_ctrl_endpoint = 0x01,
1628
1629 .num_device_descs = 1,
1630 .devices = {
1631 { "DViCO FusionHDTV DVB-T USB (TH7579)",
1632 { &cxusb_table[7], NULL },
1633 { &cxusb_table[8], NULL },
1634 },
1635 }
1636};
1637
1638static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1639 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1640
1641 .usb_ctrl = CYPRESS_FX2,
1642
1643 .size_of_priv = sizeof(struct cxusb_state),
1644
1645 .num_adapters = 1,
1646 .adapter = {
1647 {
1648 .streaming_ctrl = cxusb_streaming_ctrl,
1649 .frontend_attach = cxusb_dualdig4_frontend_attach,
1650 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1651 /* parameter for the MPEG2-data transfer */
1652 .stream = {
1653 .type = USB_BULK,
1654 .count = 5,
1655 .endpoint = 0x02,
1656 .u = {
1657 .bulk = {
1658 .buffersize = 8192,
1659 }
1660 }
1661 },
1662 },
1663 },
1664
1665 .power_ctrl = cxusb_power_ctrl,
1666
1667 .i2c_algo = &cxusb_i2c_algo,
1668
1669 .generic_bulk_ctrl_endpoint = 0x01,
1670
1671 .rc.legacy = {
1672 .rc_interval = 100,
1673 .rc_map_table = rc_map_dvico_mce_table,
1674 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
1675 .rc_query = cxusb_bluebird2_rc_query,
1676 },
1677
1678 .num_device_descs = 1,
1679 .devices = {
1680 { "DViCO FusionHDTV DVB-T Dual Digital 4",
1681 { NULL },
1682 { &cxusb_table[13], NULL },
1683 },
1684 }
1685};
1686
1687static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1688 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1689
1690 .usb_ctrl = CYPRESS_FX2,
1691 .identify_state = bluebird_fx2_identify_state,
1692
1693 .size_of_priv = sizeof(struct cxusb_state),
1694
1695 .num_adapters = 1,
1696 .adapter = {
1697 {
1698 .streaming_ctrl = cxusb_streaming_ctrl,
1699 .frontend_attach = cxusb_nano2_frontend_attach,
1700 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1701 /* parameter for the MPEG2-data transfer */
1702 .stream = {
1703 .type = USB_BULK,
1704 .count = 5,
1705 .endpoint = 0x02,
1706 .u = {
1707 .bulk = {
1708 .buffersize = 8192,
1709 }
1710 }
1711 },
1712 },
1713 },
1714
1715 .power_ctrl = cxusb_nano2_power_ctrl,
1716
1717 .i2c_algo = &cxusb_i2c_algo,
1718
1719 .generic_bulk_ctrl_endpoint = 0x01,
1720
1721 .rc.legacy = {
1722 .rc_interval = 100,
1723 .rc_map_table = rc_map_dvico_portable_table,
1724 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1725 .rc_query = cxusb_bluebird2_rc_query,
1726 },
1727
1728 .num_device_descs = 1,
1729 .devices = {
1730 { "DViCO FusionHDTV DVB-T NANO2",
1731 { NULL },
1732 { &cxusb_table[14], NULL },
1733 },
1734 }
1735};
1736
1737static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
1738 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1739
1740 .usb_ctrl = DEVICE_SPECIFIC,
1741 .firmware = "dvb-usb-bluebird-02.fw",
1742 .download_firmware = bluebird_patch_dvico_firmware_download,
1743 .identify_state = bluebird_fx2_identify_state,
1744
1745 .size_of_priv = sizeof(struct cxusb_state),
1746
1747 .num_adapters = 1,
1748 .adapter = {
1749 {
1750 .streaming_ctrl = cxusb_streaming_ctrl,
1751 .frontend_attach = cxusb_nano2_frontend_attach,
1752 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1753 /* parameter for the MPEG2-data transfer */
1754 .stream = {
1755 .type = USB_BULK,
1756 .count = 5,
1757 .endpoint = 0x02,
1758 .u = {
1759 .bulk = {
1760 .buffersize = 8192,
1761 }
1762 }
1763 },
1764 },
1765 },
1766
1767 .power_ctrl = cxusb_nano2_power_ctrl,
1768
1769 .i2c_algo = &cxusb_i2c_algo,
1770
1771 .generic_bulk_ctrl_endpoint = 0x01,
1772
1773 .rc.legacy = {
1774 .rc_interval = 100,
1775 .rc_map_table = rc_map_dvico_portable_table,
1776 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1777 .rc_query = cxusb_rc_query,
1778 },
1779
1780 .num_device_descs = 1,
1781 .devices = {
1782 { "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
1783 { &cxusb_table[14], NULL },
1784 { &cxusb_table[15], NULL },
1785 },
1786 }
1787};
1788
1789static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
1790 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1791
1792 .usb_ctrl = CYPRESS_FX2,
1793
1794 .size_of_priv = sizeof(struct cxusb_state),
1795
1796 .num_adapters = 1,
1797 .adapter = {
1798 {
1799 .streaming_ctrl = cxusb_aver_streaming_ctrl,
1800 .frontend_attach = cxusb_aver_lgdt3303_frontend_attach,
1801 .tuner_attach = cxusb_mxl5003s_tuner_attach,
1802 /* parameter for the MPEG2-data transfer */
1803 .stream = {
1804 .type = USB_BULK,
1805 .count = 5,
1806 .endpoint = 0x04,
1807 .u = {
1808 .bulk = {
1809 .buffersize = 8192,
1810 }
1811 }
1812 },
1813
1814 },
1815 },
1816 .power_ctrl = cxusb_aver_power_ctrl,
1817
1818 .i2c_algo = &cxusb_i2c_algo,
1819
1820 .generic_bulk_ctrl_endpoint = 0x01,
1821
1822 .num_device_descs = 1,
1823 .devices = {
1824 { "AVerMedia AVerTVHD Volar (A868R)",
1825 { NULL },
1826 { &cxusb_table[16], NULL },
1827 },
1828 }
1829};
1830
1831static
1832struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
1833 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1834
1835 .usb_ctrl = CYPRESS_FX2,
1836
1837 .size_of_priv = sizeof(struct cxusb_state),
1838
1839 .num_adapters = 1,
1840 .adapter = {
1841 {
1842 .streaming_ctrl = cxusb_streaming_ctrl,
1843 .frontend_attach = cxusb_dualdig4_rev2_frontend_attach,
1844 .tuner_attach = cxusb_dualdig4_rev2_tuner_attach,
1845 .size_of_priv = sizeof(struct dib0700_adapter_state),
1846 /* parameter for the MPEG2-data transfer */
1847 .stream = {
1848 .type = USB_BULK,
1849 .count = 7,
1850 .endpoint = 0x02,
1851 .u = {
1852 .bulk = {
1853 .buffersize = 4096,
1854 }
1855 }
1856 },
1857 },
1858 },
1859
1860 .power_ctrl = cxusb_bluebird_power_ctrl,
1861
1862 .i2c_algo = &cxusb_i2c_algo,
1863
1864 .generic_bulk_ctrl_endpoint = 0x01,
1865
1866 .rc.legacy = {
1867 .rc_interval = 100,
1868 .rc_map_table = rc_map_dvico_mce_table,
1869 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
1870 .rc_query = cxusb_rc_query,
1871 },
1872
1873 .num_device_descs = 1,
1874 .devices = {
1875 { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)",
1876 { NULL },
1877 { &cxusb_table[17], NULL },
1878 },
1879 }
1880};
1881
1882static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
1883 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1884
1885 .usb_ctrl = CYPRESS_FX2,
1886
1887 .size_of_priv = sizeof(struct cxusb_state),
1888
1889 .num_adapters = 1,
1890 .adapter = {
1891 {
1892 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
1893 .frontend_attach = cxusb_d680_dmb_frontend_attach,
1894 .tuner_attach = cxusb_d680_dmb_tuner_attach,
1895
1896 /* parameter for the MPEG2-data transfer */
1897 .stream = {
1898 .type = USB_BULK,
1899 .count = 5,
1900 .endpoint = 0x02,
1901 .u = {
1902 .bulk = {
1903 .buffersize = 8192,
1904 }
1905 }
1906 },
1907 },
1908 },
1909
1910 .power_ctrl = cxusb_d680_dmb_power_ctrl,
1911
1912 .i2c_algo = &cxusb_i2c_algo,
1913
1914 .generic_bulk_ctrl_endpoint = 0x01,
1915
1916 .rc.legacy = {
1917 .rc_interval = 100,
1918 .rc_map_table = rc_map_d680_dmb_table,
1919 .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
1920 .rc_query = cxusb_d680_dmb_rc_query,
1921 },
1922
1923 .num_device_descs = 1,
1924 .devices = {
1925 {
1926 "Conexant DMB-TH Stick",
1927 { NULL },
1928 { &cxusb_table[18], NULL },
1929 },
1930 }
1931};
1932
1933static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
1934 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1935
1936 .usb_ctrl = CYPRESS_FX2,
1937
1938 .size_of_priv = sizeof(struct cxusb_state),
1939
1940 .num_adapters = 1,
1941 .adapter = {
1942 {
1943 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
1944 .frontend_attach = cxusb_mygica_d689_frontend_attach,
1945 .tuner_attach = cxusb_mygica_d689_tuner_attach,
1946
1947 /* parameter for the MPEG2-data transfer */
1948 .stream = {
1949 .type = USB_BULK,
1950 .count = 5,
1951 .endpoint = 0x02,
1952 .u = {
1953 .bulk = {
1954 .buffersize = 8192,
1955 }
1956 }
1957 },
1958 },
1959 },
1960
1961 .power_ctrl = cxusb_d680_dmb_power_ctrl,
1962
1963 .i2c_algo = &cxusb_i2c_algo,
1964
1965 .generic_bulk_ctrl_endpoint = 0x01,
1966
1967 .rc.legacy = {
1968 .rc_interval = 100,
1969 .rc_map_table = rc_map_d680_dmb_table,
1970 .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
1971 .rc_query = cxusb_d680_dmb_rc_query,
1972 },
1973
1974 .num_device_descs = 1,
1975 .devices = {
1976 {
1977 "Mygica D689 DMB-TH",
1978 { NULL },
1979 { &cxusb_table[19], NULL },
1980 },
1981 }
1982};
1983
1984static struct usb_driver cxusb_driver = {
1985 .name = "dvb_usb_cxusb",
1986 .probe = cxusb_probe,
1987 .disconnect = dvb_usb_device_exit,
1988 .id_table = cxusb_table,
1989};
1990
1991/* module stuff */
1992static int __init cxusb_module_init(void)
1993{
1994 int result;
1995 if ((result = usb_register(&cxusb_driver))) {
1996 err("usb_register failed. Error number %d",result);
1997 return result;
1998 }
1999
2000 return 0;
2001}
2002
2003static void __exit cxusb_module_exit(void)
2004{
2005 /* deregister this driver from the USB subsystem */
2006 usb_deregister(&cxusb_driver);
2007}
2008
2009module_init (cxusb_module_init);
2010module_exit (cxusb_module_exit);
2011
2012MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
2013MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
2014MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
2015MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
2016MODULE_VERSION("1.0-alpha");
2017MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h
new file mode 100644
index 00000000000..1a51eafd31b
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/cxusb.h
@@ -0,0 +1,35 @@
1#ifndef _DVB_USB_CXUSB_H_
2#define _DVB_USB_CXUSB_H_
3
4#define DVB_USB_LOG_PREFIX "cxusb"
5#include "dvb-usb.h"
6
7/* usb commands - some of it are guesses, don't have a reference yet */
8#define CMD_BLUEBIRD_GPIO_RW 0x05
9
10#define CMD_I2C_WRITE 0x08
11#define CMD_I2C_READ 0x09
12
13#define CMD_GPIO_READ 0x0d
14#define CMD_GPIO_WRITE 0x0e
15#define GPIO_TUNER 0x02
16
17#define CMD_POWER_OFF 0xdc
18#define CMD_POWER_ON 0xde
19
20#define CMD_STREAMING_ON 0x36
21#define CMD_STREAMING_OFF 0x37
22
23#define CMD_AVER_STREAM_ON 0x18
24#define CMD_AVER_STREAM_OFF 0x19
25
26#define CMD_GET_IR_CODE 0x47
27
28#define CMD_ANALOG 0x50
29#define CMD_DIGITAL 0x51
30
31struct cxusb_state {
32 u8 gpio_write_state[3];
33};
34
35#endif
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
new file mode 100644
index 00000000000..9bd6d51b3b9
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dib0700.h
@@ -0,0 +1,73 @@
1/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the Free
5 * Software Foundation, version 2.
6 *
7 * Copyright (C) 2005-6 DiBcom, SA
8 */
9#ifndef _DIB0700_H_
10#define _DIB0700_H_
11
12#define DVB_USB_LOG_PREFIX "dib0700"
13#include "dvb-usb.h"
14
15#include "dib07x0.h"
16
17extern int dvb_usb_dib0700_debug;
18#define deb_info(args...) dprintk(dvb_usb_dib0700_debug,0x01,args)
19#define deb_fw(args...) dprintk(dvb_usb_dib0700_debug,0x02,args)
20#define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args)
21#define deb_data(args...) dprintk(dvb_usb_dib0700_debug,0x08,args)
22
23#define REQUEST_SET_USB_XFER_LEN 0x0 /* valid only for firmware version */
24 /* higher than 1.21 */
25#define REQUEST_I2C_READ 0x2
26#define REQUEST_I2C_WRITE 0x3
27#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */
28#define REQUEST_JUMPRAM 0x8
29#define REQUEST_SET_CLOCK 0xB
30#define REQUEST_SET_GPIO 0xC
31#define REQUEST_ENABLE_VIDEO 0xF
32 // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
33 // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
34 // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " )
35#define REQUEST_SET_I2C_PARAM 0x10
36#define REQUEST_SET_RC 0x11
37#define REQUEST_NEW_I2C_READ 0x12
38#define REQUEST_NEW_I2C_WRITE 0x13
39#define REQUEST_GET_VERSION 0x15
40
41struct dib0700_state {
42 u8 channel_state;
43 u16 mt2060_if1[2];
44 u8 rc_toggle;
45 u8 rc_counter;
46 u8 is_dib7000pc;
47 u8 fw_use_new_i2c_api;
48 u8 disable_streaming_master_mode;
49 u32 fw_version;
50 u32 nb_packet_buffer_size;
51 u8 buf[255];
52};
53
54extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
55 u32 *romversion, u32 *ramversion, u32 *fwtype);
56extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
57extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3);
58extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen);
59extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw);
60extern int dib0700_rc_setup(struct dvb_usb_device *d);
61extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
62extern struct i2c_algorithm dib0700_i2c_algo;
63extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
64 struct dvb_usb_device_description **desc, int *cold);
65extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type);
66extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz);
67
68extern int dib0700_device_count;
69extern int dvb_usb_dib0700_ir_proto;
70extern struct dvb_usb_device_properties dib0700_devices[];
71extern struct usb_device_id dib0700_usb_id_table[];
72
73#endif
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
new file mode 100644
index 00000000000..a224e94325b
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -0,0 +1,860 @@
1/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the Free
5 * Software Foundation, version 2.
6 *
7 * Copyright (C) 2005-6 DiBcom, SA
8 */
9#include "dib0700.h"
10
11/* debug */
12int dvb_usb_dib0700_debug;
13module_param_named(debug,dvb_usb_dib0700_debug, int, 0644);
14MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS);
15
16static int nb_packet_buffer_size = 21;
17module_param(nb_packet_buffer_size, int, 0644);
18MODULE_PARM_DESC(nb_packet_buffer_size,
19 "Set the dib0700 driver data buffer size. This parameter "
20 "corresponds to the number of TS packets. The actual size of "
21 "the data buffer corresponds to this parameter "
22 "multiplied by 188 (default: 21)");
23
24DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
25
26
27int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
28 u32 *romversion, u32 *ramversion, u32 *fwtype)
29{
30 struct dib0700_state *st = d->priv;
31 int ret;
32
33 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
34 deb_info("could not acquire lock");
35 return 0;
36 }
37
38 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
39 REQUEST_GET_VERSION,
40 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
41 st->buf, 16, USB_CTRL_GET_TIMEOUT);
42 if (hwversion != NULL)
43 *hwversion = (st->buf[0] << 24) | (st->buf[1] << 16) |
44 (st->buf[2] << 8) | st->buf[3];
45 if (romversion != NULL)
46 *romversion = (st->buf[4] << 24) | (st->buf[5] << 16) |
47 (st->buf[6] << 8) | st->buf[7];
48 if (ramversion != NULL)
49 *ramversion = (st->buf[8] << 24) | (st->buf[9] << 16) |
50 (st->buf[10] << 8) | st->buf[11];
51 if (fwtype != NULL)
52 *fwtype = (st->buf[12] << 24) | (st->buf[13] << 16) |
53 (st->buf[14] << 8) | st->buf[15];
54 mutex_unlock(&d->usb_mutex);
55 return ret;
56}
57
58/* expecting rx buffer: request data[0] data[1] ... data[2] */
59static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
60{
61 int status;
62
63 deb_data(">>> ");
64 debug_dump(tx, txlen, deb_data);
65
66 status = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0),
67 tx[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, tx, txlen,
68 USB_CTRL_GET_TIMEOUT);
69
70 if (status != txlen)
71 deb_data("ep 0 write error (status = %d, len: %d)\n",status,txlen);
72
73 return status < 0 ? status : 0;
74}
75
76/* expecting tx buffer: request data[0] ... data[n] (n <= 4) */
77int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
78{
79 u16 index, value;
80 int status;
81
82 if (txlen < 2) {
83 err("tx buffer length is smaller than 2. Makes no sense.");
84 return -EINVAL;
85 }
86 if (txlen > 4) {
87 err("tx buffer length is larger than 4. Not supported.");
88 return -EINVAL;
89 }
90
91 deb_data(">>> ");
92 debug_dump(tx,txlen,deb_data);
93
94 value = ((txlen - 2) << 8) | tx[1];
95 index = 0;
96 if (txlen > 2)
97 index |= (tx[2] << 8);
98 if (txlen > 3)
99 index |= tx[3];
100
101 status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0],
102 USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen,
103 USB_CTRL_GET_TIMEOUT);
104
105 if (status < 0)
106 deb_info("ep 0 read error (status = %d)\n",status);
107
108 deb_data("<<< ");
109 debug_dump(rx, rxlen, deb_data);
110
111 return status; /* length in case of success */
112}
113
114int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val)
115{
116 struct dib0700_state *st = d->priv;
117 int ret;
118
119 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
120 deb_info("could not acquire lock");
121 return 0;
122 }
123
124 st->buf[0] = REQUEST_SET_GPIO;
125 st->buf[1] = gpio;
126 st->buf[2] = ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6);
127
128 ret = dib0700_ctrl_wr(d, st->buf, 3);
129
130 mutex_unlock(&d->usb_mutex);
131 return ret;
132}
133
134static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
135{
136 struct dib0700_state *st = d->priv;
137 int ret;
138
139 if (st->fw_version >= 0x10201) {
140 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
141 deb_info("could not acquire lock");
142 return 0;
143 }
144
145 st->buf[0] = REQUEST_SET_USB_XFER_LEN;
146 st->buf[1] = (nb_ts_packets >> 8) & 0xff;
147 st->buf[2] = nb_ts_packets & 0xff;
148
149 deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
150
151 ret = dib0700_ctrl_wr(d, st->buf, 3);
152 mutex_unlock(&d->usb_mutex);
153 } else {
154 deb_info("this firmware does not allow to change the USB xfer len\n");
155 ret = -EIO;
156 }
157
158 return ret;
159}
160
161/*
162 * I2C master xfer function (supported in 1.20 firmware)
163 */
164static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
165 int num)
166{
167 /* The new i2c firmware messages are more reliable and in particular
168 properly support i2c read calls not preceded by a write */
169
170 struct dvb_usb_device *d = i2c_get_adapdata(adap);
171 struct dib0700_state *st = d->priv;
172 uint8_t bus_mode = 1; /* 0=eeprom bus, 1=frontend bus */
173 uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */
174 uint8_t en_start = 0;
175 uint8_t en_stop = 0;
176 int result, i;
177
178 /* Ensure nobody else hits the i2c bus while we're sending our
179 sequence of messages, (such as the remote control thread) */
180 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
181 return -EAGAIN;
182
183 for (i = 0; i < num; i++) {
184 if (i == 0) {
185 /* First message in the transaction */
186 en_start = 1;
187 } else if (!(msg[i].flags & I2C_M_NOSTART)) {
188 /* Device supports repeated-start */
189 en_start = 1;
190 } else {
191 /* Not the first packet and device doesn't support
192 repeated start */
193 en_start = 0;
194 }
195 if (i == (num - 1)) {
196 /* Last message in the transaction */
197 en_stop = 1;
198 }
199
200 if (msg[i].flags & I2C_M_RD) {
201 /* Read request */
202 u16 index, value;
203 uint8_t i2c_dest;
204
205 i2c_dest = (msg[i].addr << 1);
206 value = ((en_start << 7) | (en_stop << 6) |
207 (msg[i].len & 0x3F)) << 8 | i2c_dest;
208 /* I2C ctrl + FE bus; */
209 index = ((gen_mode << 6) & 0xC0) |
210 ((bus_mode << 4) & 0x30);
211
212 result = usb_control_msg(d->udev,
213 usb_rcvctrlpipe(d->udev, 0),
214 REQUEST_NEW_I2C_READ,
215 USB_TYPE_VENDOR | USB_DIR_IN,
216 value, index, msg[i].buf,
217 msg[i].len,
218 USB_CTRL_GET_TIMEOUT);
219 if (result < 0) {
220 deb_info("i2c read error (status = %d)\n", result);
221 break;
222 }
223
224 deb_data("<<< ");
225 debug_dump(msg[i].buf, msg[i].len, deb_data);
226
227 } else {
228 /* Write request */
229 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
230 deb_info("could not acquire lock");
231 return 0;
232 }
233 st->buf[0] = REQUEST_NEW_I2C_WRITE;
234 st->buf[1] = msg[i].addr << 1;
235 st->buf[2] = (en_start << 7) | (en_stop << 6) |
236 (msg[i].len & 0x3F);
237 /* I2C ctrl + FE bus; */
238 st->buf[3] = ((gen_mode << 6) & 0xC0) |
239 ((bus_mode << 4) & 0x30);
240 /* The Actual i2c payload */
241 memcpy(&st->buf[4], msg[i].buf, msg[i].len);
242
243 deb_data(">>> ");
244 debug_dump(st->buf, msg[i].len + 4, deb_data);
245
246 result = usb_control_msg(d->udev,
247 usb_sndctrlpipe(d->udev, 0),
248 REQUEST_NEW_I2C_WRITE,
249 USB_TYPE_VENDOR | USB_DIR_OUT,
250 0, 0, st->buf, msg[i].len + 4,
251 USB_CTRL_GET_TIMEOUT);
252 mutex_unlock(&d->usb_mutex);
253 if (result < 0) {
254 deb_info("i2c write error (status = %d)\n", result);
255 break;
256 }
257 }
258 }
259 mutex_unlock(&d->i2c_mutex);
260 return i;
261}
262
263/*
264 * I2C master xfer function (pre-1.20 firmware)
265 */
266static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
267 struct i2c_msg *msg, int num)
268{
269 struct dvb_usb_device *d = i2c_get_adapdata(adap);
270 struct dib0700_state *st = d->priv;
271 int i,len;
272
273 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
274 return -EAGAIN;
275 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
276 deb_info("could not acquire lock");
277 return 0;
278 }
279
280 for (i = 0; i < num; i++) {
281 /* fill in the address */
282 st->buf[1] = msg[i].addr << 1;
283 /* fill the buffer */
284 memcpy(&st->buf[2], msg[i].buf, msg[i].len);
285
286 /* write/read request */
287 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
288 st->buf[0] = REQUEST_I2C_READ;
289 st->buf[1] |= 1;
290
291 /* special thing in the current firmware: when length is zero the read-failed */
292 len = dib0700_ctrl_rd(d, st->buf, msg[i].len + 2,
293 msg[i+1].buf, msg[i+1].len);
294 if (len <= 0) {
295 deb_info("I2C read failed on address 0x%02x\n",
296 msg[i].addr);
297 break;
298 }
299
300 msg[i+1].len = len;
301
302 i++;
303 } else {
304 st->buf[0] = REQUEST_I2C_WRITE;
305 if (dib0700_ctrl_wr(d, st->buf, msg[i].len + 2) < 0)
306 break;
307 }
308 }
309 mutex_unlock(&d->usb_mutex);
310 mutex_unlock(&d->i2c_mutex);
311
312 return i;
313}
314
315static int dib0700_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
316 int num)
317{
318 struct dvb_usb_device *d = i2c_get_adapdata(adap);
319 struct dib0700_state *st = d->priv;
320
321 if (st->fw_use_new_i2c_api == 1) {
322 /* User running at least fw 1.20 */
323 return dib0700_i2c_xfer_new(adap, msg, num);
324 } else {
325 /* Use legacy calls */
326 return dib0700_i2c_xfer_legacy(adap, msg, num);
327 }
328}
329
330static u32 dib0700_i2c_func(struct i2c_adapter *adapter)
331{
332 return I2C_FUNC_I2C;
333}
334
335struct i2c_algorithm dib0700_i2c_algo = {
336 .master_xfer = dib0700_i2c_xfer,
337 .functionality = dib0700_i2c_func,
338};
339
340int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
341 struct dvb_usb_device_description **desc, int *cold)
342{
343 s16 ret;
344 u8 *b;
345
346 b = kmalloc(16, GFP_KERNEL);
347 if (!b)
348 return -ENOMEM;
349
350
351 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
352 REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT);
353
354 deb_info("FW GET_VERSION length: %d\n",ret);
355
356 *cold = ret <= 0;
357 deb_info("cold: %d\n", *cold);
358
359 kfree(b);
360 return 0;
361}
362
363static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
364 u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv,
365 u16 pll_loopdiv, u16 free_div, u16 dsuScaler)
366{
367 struct dib0700_state *st = d->priv;
368 int ret;
369
370 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
371 deb_info("could not acquire lock");
372 return 0;
373 }
374
375 st->buf[0] = REQUEST_SET_CLOCK;
376 st->buf[1] = (en_pll << 7) | (pll_src << 6) |
377 (pll_range << 5) | (clock_gpio3 << 4);
378 st->buf[2] = (pll_prediv >> 8) & 0xff; /* MSB */
379 st->buf[3] = pll_prediv & 0xff; /* LSB */
380 st->buf[4] = (pll_loopdiv >> 8) & 0xff; /* MSB */
381 st->buf[5] = pll_loopdiv & 0xff; /* LSB */
382 st->buf[6] = (free_div >> 8) & 0xff; /* MSB */
383 st->buf[7] = free_div & 0xff; /* LSB */
384 st->buf[8] = (dsuScaler >> 8) & 0xff; /* MSB */
385 st->buf[9] = dsuScaler & 0xff; /* LSB */
386
387 ret = dib0700_ctrl_wr(d, st->buf, 10);
388 mutex_unlock(&d->usb_mutex);
389
390 return ret;
391}
392
393int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
394{
395 struct dib0700_state *st = d->priv;
396 u16 divider;
397 int ret;
398
399 if (scl_kHz == 0)
400 return -EINVAL;
401
402 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
403 deb_info("could not acquire lock");
404 return 0;
405 }
406
407 st->buf[0] = REQUEST_SET_I2C_PARAM;
408 divider = (u16) (30000 / scl_kHz);
409 st->buf[1] = 0;
410 st->buf[2] = (u8) (divider >> 8);
411 st->buf[3] = (u8) (divider & 0xff);
412 divider = (u16) (72000 / scl_kHz);
413 st->buf[4] = (u8) (divider >> 8);
414 st->buf[5] = (u8) (divider & 0xff);
415 divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */
416 st->buf[6] = (u8) (divider >> 8);
417 st->buf[7] = (u8) (divider & 0xff);
418
419 deb_info("setting I2C speed: %04x %04x %04x (%d kHz).",
420 (st->buf[2] << 8) | (st->buf[3]), (st->buf[4] << 8) |
421 st->buf[5], (st->buf[6] << 8) | st->buf[7], scl_kHz);
422
423 ret = dib0700_ctrl_wr(d, st->buf, 8);
424 mutex_unlock(&d->usb_mutex);
425
426 return ret;
427}
428
429
430int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3)
431{
432 switch (clk_MHz) {
433 case 72: dib0700_set_clock(d, 1, 0, 1, clock_out_gp3, 2, 24, 0, 0x4c); break;
434 default: return -EINVAL;
435 }
436 return 0;
437}
438
439static int dib0700_jumpram(struct usb_device *udev, u32 address)
440{
441 int ret = 0, actlen;
442 u8 *buf;
443
444 buf = kmalloc(8, GFP_KERNEL);
445 if (!buf)
446 return -ENOMEM;
447 buf[0] = REQUEST_JUMPRAM;
448 buf[1] = 0;
449 buf[2] = 0;
450 buf[3] = 0;
451 buf[4] = (address >> 24) & 0xff;
452 buf[5] = (address >> 16) & 0xff;
453 buf[6] = (address >> 8) & 0xff;
454 buf[7] = address & 0xff;
455
456 if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) {
457 deb_fw("jumpram to 0x%x failed\n",address);
458 goto out;
459 }
460 if (actlen != 8) {
461 deb_fw("jumpram to 0x%x failed\n",address);
462 ret = -EIO;
463 goto out;
464 }
465out:
466 kfree(buf);
467 return ret;
468}
469
470int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
471{
472 struct hexline hx;
473 int pos = 0, ret, act_len, i, adap_num;
474 u8 *buf;
475 u32 fw_version;
476
477 buf = kmalloc(260, GFP_KERNEL);
478 if (!buf)
479 return -ENOMEM;
480
481 while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) {
482 deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",
483 hx.addr, hx.len, hx.chk);
484
485 buf[0] = hx.len;
486 buf[1] = (hx.addr >> 8) & 0xff;
487 buf[2] = hx.addr & 0xff;
488 buf[3] = hx.type;
489 memcpy(&buf[4],hx.data,hx.len);
490 buf[4+hx.len] = hx.chk;
491
492 ret = usb_bulk_msg(udev,
493 usb_sndbulkpipe(udev, 0x01),
494 buf,
495 hx.len + 5,
496 &act_len,
497 1000);
498
499 if (ret < 0) {
500 err("firmware download failed at %d with %d",pos,ret);
501 goto out;
502 }
503 }
504
505 if (ret == 0) {
506 /* start the firmware */
507 if ((ret = dib0700_jumpram(udev, 0x70000000)) == 0) {
508 info("firmware started successfully.");
509 msleep(500);
510 }
511 } else
512 ret = -EIO;
513
514 /* the number of ts packet has to be at least 1 */
515 if (nb_packet_buffer_size < 1)
516 nb_packet_buffer_size = 1;
517
518 /* get the fimware version */
519 usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
520 REQUEST_GET_VERSION,
521 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
522 buf, 16, USB_CTRL_GET_TIMEOUT);
523 fw_version = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11];
524
525 /* set the buffer size - DVB-USB is allocating URB buffers
526 * only after the firwmare download was successful */
527 for (i = 0; i < dib0700_device_count; i++) {
528 for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters;
529 adap_num++) {
530 if (fw_version >= 0x10201) {
531 dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 188*nb_packet_buffer_size;
532 } else {
533 /* for fw version older than 1.20.1,
534 * the buffersize has to be n times 512 */
535 dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512;
536 if (dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize < 512)
537 dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 512;
538 }
539 }
540 }
541out:
542 kfree(buf);
543 return ret;
544}
545
546int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
547{
548 struct dib0700_state *st = adap->dev->priv;
549 int ret;
550
551 if ((onoff != 0) && (st->fw_version >= 0x10201)) {
552 /* for firmware later than 1.20.1,
553 * the USB xfer length can be set */
554 ret = dib0700_set_usb_xfer_len(adap->dev,
555 st->nb_packet_buffer_size);
556 if (ret < 0) {
557 deb_info("can not set the USB xfer len\n");
558 return ret;
559 }
560 }
561
562 if (mutex_lock_interruptible(&adap->dev->usb_mutex) < 0) {
563 deb_info("could not acquire lock");
564 return 0;
565 }
566
567 st->buf[0] = REQUEST_ENABLE_VIDEO;
568 /* this bit gives a kind of command,
569 * rather than enabling something or not */
570 st->buf[1] = (onoff << 4) | 0x00;
571
572 if (st->disable_streaming_master_mode == 1)
573 st->buf[2] = 0x00;
574 else
575 st->buf[2] = 0x01 << 4; /* Master mode */
576
577 st->buf[3] = 0x00;
578
579 deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
580
581 st->channel_state &= ~0x3;
582 if ((adap->stream.props.endpoint != 2)
583 && (adap->stream.props.endpoint != 3)) {
584 deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->stream.props.endpoint);
585 if (onoff)
586 st->channel_state |= 1 << (adap->id);
587 else
588 st->channel_state |= 1 << ~(adap->id);
589 } else {
590 if (onoff)
591 st->channel_state |= 1 << (adap->stream.props.endpoint-2);
592 else
593 st->channel_state |= 1 << (3-adap->stream.props.endpoint);
594 }
595
596 st->buf[2] |= st->channel_state;
597
598 deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]);
599
600 ret = dib0700_ctrl_wr(adap->dev, st->buf, 4);
601 mutex_unlock(&adap->dev->usb_mutex);
602
603 return ret;
604}
605
606int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
607{
608 struct dvb_usb_device *d = rc->priv;
609 struct dib0700_state *st = d->priv;
610 int new_proto, ret;
611
612 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
613 deb_info("could not acquire lock");
614 return 0;
615 }
616
617 st->buf[0] = REQUEST_SET_RC;
618 st->buf[1] = 0;
619 st->buf[2] = 0;
620
621 /* Set the IR mode */
622 if (rc_type == RC_TYPE_RC5)
623 new_proto = 1;
624 else if (rc_type == RC_TYPE_NEC)
625 new_proto = 0;
626 else if (rc_type == RC_TYPE_RC6) {
627 if (st->fw_version < 0x10200) {
628 ret = -EINVAL;
629 goto out;
630 }
631
632 new_proto = 2;
633 } else {
634 ret = -EINVAL;
635 goto out;
636 }
637
638 st->buf[1] = new_proto;
639
640 ret = dib0700_ctrl_wr(d, st->buf, 3);
641 if (ret < 0) {
642 err("ir protocol setup failed");
643 goto out;
644 }
645
646 d->props.rc.core.protocol = rc_type;
647
648out:
649 mutex_unlock(&d->usb_mutex);
650 return ret;
651}
652
653/* Number of keypresses to ignore before start repeating */
654#define RC_REPEAT_DELAY_V1_20 10
655
656/* This is the structure of the RC response packet starting in firmware 1.20 */
657struct dib0700_rc_response {
658 u8 report_id;
659 u8 data_state;
660 union {
661 u16 system16;
662 struct {
663 u8 not_system;
664 u8 system;
665 };
666 };
667 u8 data;
668 u8 not_data;
669};
670#define RC_MSG_SIZE_V1_20 6
671
672static void dib0700_rc_urb_completion(struct urb *purb)
673{
674 struct dvb_usb_device *d = purb->context;
675 struct dib0700_rc_response *poll_reply;
676 u32 uninitialized_var(keycode);
677 u8 toggle;
678
679 deb_info("%s()\n", __func__);
680 if (d == NULL)
681 return;
682
683 if (d->rc_dev == NULL) {
684 /* This will occur if disable_rc_polling=1 */
685 usb_free_urb(purb);
686 return;
687 }
688
689 poll_reply = purb->transfer_buffer;
690
691 if (purb->status < 0) {
692 deb_info("discontinuing polling\n");
693 usb_free_urb(purb);
694 return;
695 }
696
697 if (purb->actual_length != RC_MSG_SIZE_V1_20) {
698 deb_info("malformed rc msg size=%d\n", purb->actual_length);
699 goto resubmit;
700 }
701
702 deb_data("IR ID = %02X state = %02X System = %02X %02X Cmd = %02X %02X (len %d)\n",
703 poll_reply->report_id, poll_reply->data_state,
704 poll_reply->system, poll_reply->not_system,
705 poll_reply->data, poll_reply->not_data,
706 purb->actual_length);
707
708 switch (d->props.rc.core.protocol) {
709 case RC_TYPE_NEC:
710 toggle = 0;
711
712 /* NEC protocol sends repeat code as 0 0 0 FF */
713 if ((poll_reply->system == 0x00) && (poll_reply->data == 0x00)
714 && (poll_reply->not_data == 0xff)) {
715 poll_reply->data_state = 2;
716 break;
717 }
718
719 if ((poll_reply->system ^ poll_reply->not_system) != 0xff) {
720 deb_data("NEC extended protocol\n");
721 /* NEC extended code - 24 bits */
722 keycode = be16_to_cpu(poll_reply->system16) << 8 | poll_reply->data;
723 } else {
724 deb_data("NEC normal protocol\n");
725 /* normal NEC code - 16 bits */
726 keycode = poll_reply->system << 8 | poll_reply->data;
727 }
728
729 break;
730 default:
731 deb_data("RC5 protocol\n");
732 /* RC5 Protocol */
733 toggle = poll_reply->report_id;
734 keycode = poll_reply->system << 8 | poll_reply->data;
735
736 break;
737 }
738
739 if ((poll_reply->data + poll_reply->not_data) != 0xff) {
740 /* Key failed integrity check */
741 err("key failed integrity check: %04x %02x %02x",
742 poll_reply->system,
743 poll_reply->data, poll_reply->not_data);
744 goto resubmit;
745 }
746
747 rc_keydown(d->rc_dev, keycode, toggle);
748
749resubmit:
750 /* Clean the buffer before we requeue */
751 memset(purb->transfer_buffer, 0, RC_MSG_SIZE_V1_20);
752
753 /* Requeue URB */
754 usb_submit_urb(purb, GFP_ATOMIC);
755}
756
757int dib0700_rc_setup(struct dvb_usb_device *d)
758{
759 struct dib0700_state *st = d->priv;
760 struct urb *purb;
761 int ret;
762
763 /* Poll-based. Don't initialize bulk mode */
764 if (st->fw_version < 0x10200)
765 return 0;
766
767 /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
768 purb = usb_alloc_urb(0, GFP_KERNEL);
769 if (purb == NULL) {
770 err("rc usb alloc urb failed\n");
771 return -ENOMEM;
772 }
773
774 purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL);
775 if (purb->transfer_buffer == NULL) {
776 err("rc kzalloc failed\n");
777 usb_free_urb(purb);
778 return -ENOMEM;
779 }
780
781 purb->status = -EINPROGRESS;
782 usb_fill_bulk_urb(purb, d->udev, usb_rcvbulkpipe(d->udev, 1),
783 purb->transfer_buffer, RC_MSG_SIZE_V1_20,
784 dib0700_rc_urb_completion, d);
785
786 ret = usb_submit_urb(purb, GFP_ATOMIC);
787 if (ret)
788 err("rc submit urb failed\n");
789
790 return ret;
791}
792
793static int dib0700_probe(struct usb_interface *intf,
794 const struct usb_device_id *id)
795{
796 int i;
797 struct dvb_usb_device *dev;
798
799 for (i = 0; i < dib0700_device_count; i++)
800 if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE,
801 &dev, adapter_nr) == 0) {
802 struct dib0700_state *st = dev->priv;
803 u32 hwversion, romversion, fw_version, fwtype;
804
805 dib0700_get_version(dev, &hwversion, &romversion,
806 &fw_version, &fwtype);
807
808 deb_info("Firmware version: %x, %d, 0x%x, %d\n",
809 hwversion, romversion, fw_version, fwtype);
810
811 st->fw_version = fw_version;
812 st->nb_packet_buffer_size = (u32)nb_packet_buffer_size;
813
814 /* Disable polling mode on newer firmwares */
815 if (st->fw_version >= 0x10200)
816 dev->props.rc.core.bulk_mode = true;
817 else
818 dev->props.rc.core.bulk_mode = false;
819
820 dib0700_rc_setup(dev);
821
822 return 0;
823 }
824
825 return -ENODEV;
826}
827
828static struct usb_driver dib0700_driver = {
829 .name = "dvb_usb_dib0700",
830 .probe = dib0700_probe,
831 .disconnect = dvb_usb_device_exit,
832 .id_table = dib0700_usb_id_table,
833};
834
835/* module stuff */
836static int __init dib0700_module_init(void)
837{
838 int result;
839 info("loaded with support for %d different device-types", dib0700_device_count);
840 if ((result = usb_register(&dib0700_driver))) {
841 err("usb_register failed. Error number %d",result);
842 return result;
843 }
844
845 return 0;
846}
847
848static void __exit dib0700_module_exit(void)
849{
850 /* deregister this driver from the USB subsystem */
851 usb_deregister(&dib0700_driver);
852}
853
854module_init (dib0700_module_init);
855module_exit (dib0700_module_exit);
856
857MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
858MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge");
859MODULE_VERSION("1.0");
860MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
new file mode 100644
index 00000000000..d0ea5b64f6b
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -0,0 +1,3966 @@
1/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the Free
5 * Software Foundation, version 2.
6 *
7 * Copyright (C) 2005-9 DiBcom, SA et al
8 */
9#include "dib0700.h"
10
11#include "dib3000mc.h"
12#include "dib7000m.h"
13#include "dib7000p.h"
14#include "dib8000.h"
15#include "dib9000.h"
16#include "mt2060.h"
17#include "mt2266.h"
18#include "tuner-xc2028.h"
19#include "xc5000.h"
20#include "xc4000.h"
21#include "s5h1411.h"
22#include "dib0070.h"
23#include "dib0090.h"
24#include "lgdt3305.h"
25#include "mxl5007t.h"
26
27static int force_lna_activation;
28module_param(force_lna_activation, int, 0644);
29MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), "
30 "if applicable for the device (default: 0=automatic/off).");
31
32struct dib0700_adapter_state {
33 int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *);
34 const struct firmware *frontend_firmware;
35};
36
37/* Hauppauge Nova-T 500 (aka Bristol)
38 * has a LNA on GPIO0 which is enabled by setting 1 */
39static struct mt2060_config bristol_mt2060_config[2] = {
40 {
41 .i2c_address = 0x60,
42 .clock_out = 3,
43 }, {
44 .i2c_address = 0x61,
45 }
46};
47
48
49static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
50 .band_caps = BAND_VHF | BAND_UHF,
51 .setup = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),
52
53 .agc1_max = 42598,
54 .agc1_min = 17694,
55 .agc2_max = 45875,
56 .agc2_min = 0,
57
58 .agc1_pt1 = 0,
59 .agc1_pt2 = 59,
60
61 .agc1_slope1 = 0,
62 .agc1_slope2 = 69,
63
64 .agc2_pt1 = 0,
65 .agc2_pt2 = 59,
66
67 .agc2_slope1 = 111,
68 .agc2_slope2 = 28,
69};
70
71static struct dib3000mc_config bristol_dib3000mc_config[2] = {
72 { .agc = &bristol_dib3000p_mt2060_agc_config,
73 .max_time = 0x196,
74 .ln_adc_level = 0x1cc7,
75 .output_mpeg2_in_188_bytes = 1,
76 },
77 { .agc = &bristol_dib3000p_mt2060_agc_config,
78 .max_time = 0x196,
79 .ln_adc_level = 0x1cc7,
80 .output_mpeg2_in_188_bytes = 1,
81 }
82};
83
84static int bristol_frontend_attach(struct dvb_usb_adapter *adap)
85{
86 struct dib0700_state *st = adap->dev->priv;
87 if (adap->id == 0) {
88 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
89 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10);
90 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
91 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10);
92
93 if (force_lna_activation)
94 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
95 else
96 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
97
98 if (dib3000mc_i2c_enumeration(&adap->dev->i2c_adap, 2, DEFAULT_DIB3000P_I2C_ADDRESS, bristol_dib3000mc_config) != 0) {
99 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
100 return -ENODEV;
101 }
102 }
103 st->mt2060_if1[adap->id] = 1220;
104 return (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap,
105 (10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0;
106}
107
108static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval)
109{
110 struct i2c_msg msg[2] = {
111 { .addr = 0x50, .flags = 0, .buf = &adrs, .len = 1 },
112 { .addr = 0x50, .flags = I2C_M_RD, .buf = pval, .len = 1 },
113 };
114 if (i2c_transfer(adap, msg, 2) != 2) return -EREMOTEIO;
115 return 0;
116}
117
118static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
119{
120 struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
121 struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1);
122 s8 a;
123 int if1=1220;
124 if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) &&
125 adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_500_2)) {
126 if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a;
127 }
128 return dvb_attach(mt2060_attach,adap->fe, tun_i2c,&bristol_mt2060_config[adap->id],
129 if1) == NULL ? -ENODEV : 0;
130}
131
132/* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */
133
134/* MT226x */
135static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
136 {
137 BAND_UHF,
138
139 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
140 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
141 (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
142 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
143
144 1130,
145 21,
146
147 0,
148 118,
149
150 0,
151 3530,
152 1,
153 0,
154
155 65535,
156 33770,
157 65535,
158 23592,
159
160 0,
161 62,
162 255,
163 64,
164 64,
165 132,
166 192,
167 80,
168 80,
169
170 17,
171 27,
172 23,
173 51,
174
175 1,
176 }, {
177 BAND_VHF | BAND_LBAND,
178
179 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
180 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
181 (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
182 | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
183
184 2372,
185 21,
186
187 0,
188 118,
189
190 0,
191 3530,
192 1,
193 0,
194
195 65535,
196 0,
197 65535,
198 23592,
199
200 0,
201 128,
202 128,
203 128,
204 0,
205 128,
206 253,
207 81,
208 0,
209
210 17,
211 27,
212 23,
213 51,
214
215 1,
216 }
217};
218
219static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
220 60000, 30000,
221 1, 8, 3, 1, 0,
222 0, 0, 1, 1, 2,
223 (3 << 14) | (1 << 12) | (524 << 0),
224 0,
225 20452225,
226};
227
228static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
229 { .output_mpeg2_in_188_bytes = 1,
230 .hostbus_diversity = 1,
231 .tuner_is_baseband = 1,
232
233 .agc_config_count = 2,
234 .agc = stk7700d_7000p_mt2266_agc_config,
235 .bw = &stk7700d_mt2266_pll_config,
236
237 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
238 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
239 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
240 },
241 { .output_mpeg2_in_188_bytes = 1,
242 .hostbus_diversity = 1,
243 .tuner_is_baseband = 1,
244
245 .agc_config_count = 2,
246 .agc = stk7700d_7000p_mt2266_agc_config,
247 .bw = &stk7700d_mt2266_pll_config,
248
249 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
250 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
251 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
252 }
253};
254
255static struct mt2266_config stk7700d_mt2266_config[2] = {
256 { .i2c_address = 0x60
257 },
258 { .i2c_address = 0x60
259 }
260};
261
262static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
263{
264 if (adap->id == 0) {
265 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
266 msleep(10);
267 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
268 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
269 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
270 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
271 msleep(10);
272 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
273 msleep(10);
274 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
275 stk7700d_dib7000p_mt2266_config)
276 != 0) {
277 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
278 return -ENODEV;
279 }
280 }
281
282 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
283 &stk7700d_dib7000p_mt2266_config[adap->id]);
284
285 return adap->fe == NULL ? -ENODEV : 0;
286}
287
288static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
289{
290 if (adap->id == 0) {
291 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
292 msleep(10);
293 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
294 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
295 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
296 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
297 msleep(10);
298 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
299 msleep(10);
300 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
301 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
302 stk7700d_dib7000p_mt2266_config)
303 != 0) {
304 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
305 return -ENODEV;
306 }
307 }
308
309 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
310 &stk7700d_dib7000p_mt2266_config[adap->id]);
311
312 return adap->fe == NULL ? -ENODEV : 0;
313}
314
315static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
316{
317 struct i2c_adapter *tun_i2c;
318 tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
319 return dvb_attach(mt2266_attach, adap->fe, tun_i2c,
320 &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;
321}
322
323/* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
324static struct dibx000_agc_config xc3028_agc_config = {
325 BAND_VHF | BAND_UHF, /* band_caps */
326
327 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
328 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
329 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
330 (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
331 (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */
332
333 712, /* inv_gain */
334 21, /* time_stabiliz */
335
336 0, /* alpha_level */
337 118, /* thlock */
338
339 0, /* wbd_inv */
340 2867, /* wbd_ref */
341 0, /* wbd_sel */
342 2, /* wbd_alpha */
343
344 0, /* agc1_max */
345 0, /* agc1_min */
346 39718, /* agc2_max */
347 9930, /* agc2_min */
348 0, /* agc1_pt1 */
349 0, /* agc1_pt2 */
350 0, /* agc1_pt3 */
351 0, /* agc1_slope1 */
352 0, /* agc1_slope2 */
353 0, /* agc2_pt1 */
354 128, /* agc2_pt2 */
355 29, /* agc2_slope1 */
356 29, /* agc2_slope2 */
357
358 17, /* alpha_mant */
359 27, /* alpha_exp */
360 23, /* beta_mant */
361 51, /* beta_exp */
362
363 1, /* perform_agc_softsplit */
364};
365
366/* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */
367static struct dibx000_bandwidth_config xc3028_bw_config = {
368 60000, 30000, /* internal, sampling */
369 1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
370 0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc,
371 modulo */
372 (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
373 (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
374 20452225, /* timf */
375 30000000, /* xtal_hz */
376};
377
378static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
379 .output_mpeg2_in_188_bytes = 1,
380 .tuner_is_baseband = 1,
381
382 .agc_config_count = 1,
383 .agc = &xc3028_agc_config,
384 .bw = &xc3028_bw_config,
385
386 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
387 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
388 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
389};
390
391static int stk7700ph_xc3028_callback(void *ptr, int component,
392 int command, int arg)
393{
394 struct dvb_usb_adapter *adap = ptr;
395
396 switch (command) {
397 case XC2028_TUNER_RESET:
398 /* Send the tuner in then out of reset */
399 dib7000p_set_gpio(adap->fe, 8, 0, 0); msleep(10);
400 dib7000p_set_gpio(adap->fe, 8, 0, 1);
401 break;
402 case XC2028_RESET_CLK:
403 break;
404 default:
405 err("%s: unknown command %d, arg %d\n", __func__,
406 command, arg);
407 return -EINVAL;
408 }
409 return 0;
410}
411
412static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
413 .fname = XC2028_DEFAULT_FIRMWARE,
414 .max_len = 64,
415 .demod = XC3028_FE_DIBCOM52,
416};
417
418static struct xc2028_config stk7700ph_xc3028_config = {
419 .i2c_addr = 0x61,
420 .ctrl = &stk7700ph_xc3028_ctrl,
421};
422
423static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
424{
425 struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;
426
427 if (desc->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
428 desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX))
429 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
430 else
431 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
432 msleep(20);
433 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
434 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
435 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
436 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
437 msleep(10);
438 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
439 msleep(20);
440 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
441 msleep(10);
442
443 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
444 &stk7700ph_dib7700_xc3028_config) != 0) {
445 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
446 __func__);
447 return -ENODEV;
448 }
449
450 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
451 &stk7700ph_dib7700_xc3028_config);
452
453 return adap->fe == NULL ? -ENODEV : 0;
454}
455
456static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
457{
458 struct i2c_adapter *tun_i2c;
459
460 tun_i2c = dib7000p_get_i2c_master(adap->fe,
461 DIBX000_I2C_INTERFACE_TUNER, 1);
462
463 stk7700ph_xc3028_config.i2c_adap = tun_i2c;
464
465 /* FIXME: generalize & move to common area */
466 adap->fe->callback = stk7700ph_xc3028_callback;
467
468 return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config)
469 == NULL ? -ENODEV : 0;
470}
471
472#define DEFAULT_RC_INTERVAL 50
473
474static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
475
476/* Number of keypresses to ignore before start repeating */
477#define RC_REPEAT_DELAY 6
478
479/*
480 * This function is used only when firmware is < 1.20 version. Newer
481 * firmwares use bulk mode, with functions implemented at dib0700_core,
482 * at dib0700_rc_urb_completion()
483 */
484static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
485{
486 u8 key[4];
487 u32 keycode;
488 u8 toggle;
489 int i;
490 struct dib0700_state *st = d->priv;
491
492 if (st->fw_version >= 0x10200) {
493 /* For 1.20 firmware , We need to keep the RC polling
494 callback so we can reuse the input device setup in
495 dvb-usb-remote.c. However, the actual work is being done
496 in the bulk URB completion handler. */
497 return 0;
498 }
499
500 i = dib0700_ctrl_rd(d, rc_request, 2, key, 4);
501 if (i <= 0) {
502 err("RC Query Failed");
503 return -1;
504 }
505
506 /* losing half of KEY_0 events from Philipps rc5 remotes.. */
507 if (key[0] == 0 && key[1] == 0 && key[2] == 0 && key[3] == 0)
508 return 0;
509
510 /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]); */
511
512 dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */
513
514 d->last_event = 0;
515 switch (d->props.rc.core.protocol) {
516 case RC_TYPE_NEC:
517 /* NEC protocol sends repeat code as 0 0 0 FF */
518 if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
519 (key[3] == 0xff))
520 keycode = d->last_event;
521 else {
522 keycode = key[3-2] << 8 | key[3-3];
523 d->last_event = keycode;
524 }
525
526 rc_keydown(d->rc_dev, keycode, 0);
527 break;
528 default:
529 /* RC-5 protocol changes toggle bit on new keypress */
530 keycode = key[3-2] << 8 | key[3-3];
531 toggle = key[3-1];
532 rc_keydown(d->rc_dev, keycode, toggle);
533
534 break;
535 }
536 return 0;
537}
538
539/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
540static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
541 BAND_UHF | BAND_VHF,
542
543 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
544 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
545 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
546 | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
547
548 712,
549 41,
550
551 0,
552 118,
553
554 0,
555 4095,
556 0,
557 0,
558
559 42598,
560 17694,
561 45875,
562 2621,
563 0,
564 76,
565 139,
566 52,
567 59,
568 107,
569 172,
570 57,
571 70,
572
573 21,
574 25,
575 28,
576 48,
577
578 1,
579 { 0,
580 107,
581 51800,
582 24700
583 },
584};
585
586static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
587 BAND_UHF | BAND_VHF,
588
589 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
590 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
591 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
592 | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
593
594 712,
595 41,
596
597 0,
598 118,
599
600 0,
601 4095,
602 0,
603 0,
604
605 42598,
606 16384,
607 42598,
608 0,
609
610 0,
611 137,
612 255,
613
614 0,
615 255,
616
617 0,
618 0,
619
620 0,
621 41,
622
623 15,
624 25,
625
626 28,
627 48,
628
629 0,
630};
631
632static struct dibx000_bandwidth_config stk7700p_pll_config = {
633 60000, 30000,
634 1, 8, 3, 1, 0,
635 0, 0, 1, 1, 0,
636 (3 << 14) | (1 << 12) | (524 << 0),
637 60258167,
638 20452225,
639 30000000,
640};
641
642static struct dib7000m_config stk7700p_dib7000m_config = {
643 .dvbt_mode = 1,
644 .output_mpeg2_in_188_bytes = 1,
645 .quartz_direct = 1,
646
647 .agc_config_count = 1,
648 .agc = &stk7700p_7000m_mt2060_agc_config,
649 .bw = &stk7700p_pll_config,
650
651 .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
652 .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
653 .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
654};
655
656static struct dib7000p_config stk7700p_dib7000p_config = {
657 .output_mpeg2_in_188_bytes = 1,
658
659 .agc_config_count = 1,
660 .agc = &stk7700p_7000p_mt2060_agc_config,
661 .bw = &stk7700p_pll_config,
662
663 .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
664 .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
665 .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
666};
667
668static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
669{
670 struct dib0700_state *st = adap->dev->priv;
671 /* unless there is no real power management in DVB - we leave the device on GPIO6 */
672
673 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
674 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(50);
675
676 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10);
677 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
678
679 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
680 dib0700_ctrl_clock(adap->dev, 72, 1);
681 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100);
682
683 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
684
685 st->mt2060_if1[0] = 1220;
686
687 if (dib7000pc_detection(&adap->dev->i2c_adap)) {
688 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config);
689 st->is_dib7000pc = 1;
690 } else
691 adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config);
692
693 return adap->fe == NULL ? -ENODEV : 0;
694}
695
696static struct mt2060_config stk7700p_mt2060_config = {
697 0x60
698};
699
700static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
701{
702 struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
703 struct dib0700_state *st = adap->dev->priv;
704 struct i2c_adapter *tun_i2c;
705 s8 a;
706 int if1=1220;
707 if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) &&
708 adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) {
709 if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
710 }
711 if (st->is_dib7000pc)
712 tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
713 else
714 tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
715
716 return dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk7700p_mt2060_config,
717 if1) == NULL ? -ENODEV : 0;
718}
719
720/* DIB7070 generic */
721static struct dibx000_agc_config dib7070_agc_config = {
722 BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
723 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
724 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
725 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
726 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
727
728 600,
729 10,
730
731 0,
732 118,
733
734 0,
735 3530,
736 1,
737 5,
738
739 65535,
740 0,
741
742 65535,
743 0,
744
745 0,
746 40,
747 183,
748 206,
749 255,
750 72,
751 152,
752 88,
753 90,
754
755 17,
756 27,
757 23,
758 51,
759
760 0,
761};
762
763static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
764{
765 deb_info("reset: %d", onoff);
766 return dib7000p_set_gpio(fe, 8, 0, !onoff);
767}
768
769static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
770{
771 deb_info("sleep: %d", onoff);
772 return dib7000p_set_gpio(fe, 9, 0, onoff);
773}
774
775static struct dib0070_config dib7070p_dib0070_config[2] = {
776 {
777 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
778 .reset = dib7070_tuner_reset,
779 .sleep = dib7070_tuner_sleep,
780 .clock_khz = 12000,
781 .clock_pad_drive = 4,
782 .charge_pump = 2,
783 }, {
784 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
785 .reset = dib7070_tuner_reset,
786 .sleep = dib7070_tuner_sleep,
787 .clock_khz = 12000,
788 .charge_pump = 2,
789 }
790};
791
792static struct dib0070_config dib7770p_dib0070_config = {
793 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
794 .reset = dib7070_tuner_reset,
795 .sleep = dib7070_tuner_sleep,
796 .clock_khz = 12000,
797 .clock_pad_drive = 0,
798 .flip_chip = 1,
799 .charge_pump = 2,
800};
801
802static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
803{
804 struct dvb_usb_adapter *adap = fe->dvb->priv;
805 struct dib0700_adapter_state *state = adap->priv;
806
807 u16 offset;
808 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
809 switch (band) {
810 case BAND_VHF: offset = 950; break;
811 case BAND_UHF:
812 default: offset = 550; break;
813 }
814 deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
815 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
816 return state->set_param_save(fe, fep);
817}
818
819static int dib7770_set_param_override(struct dvb_frontend *fe,
820 struct dvb_frontend_parameters *fep)
821{
822 struct dvb_usb_adapter *adap = fe->dvb->priv;
823 struct dib0700_adapter_state *state = adap->priv;
824
825 u16 offset;
826 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
827 switch (band) {
828 case BAND_VHF:
829 dib7000p_set_gpio(fe, 0, 0, 1);
830 offset = 850;
831 break;
832 case BAND_UHF:
833 default:
834 dib7000p_set_gpio(fe, 0, 0, 0);
835 offset = 250;
836 break;
837 }
838 deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
839 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
840 return state->set_param_save(fe, fep);
841}
842
843static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap)
844{
845 struct dib0700_adapter_state *st = adap->priv;
846 struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe,
847 DIBX000_I2C_INTERFACE_TUNER, 1);
848
849 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
850 &dib7770p_dib0070_config) == NULL)
851 return -ENODEV;
852
853 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
854 adap->fe->ops.tuner_ops.set_params = dib7770_set_param_override;
855 return 0;
856}
857
858static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
859{
860 struct dib0700_adapter_state *st = adap->priv;
861 struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
862
863 if (adap->id == 0) {
864 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
865 return -ENODEV;
866 } else {
867 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL)
868 return -ENODEV;
869 }
870
871 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
872 adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override;
873 return 0;
874}
875
876static int stk7700p_pid_filter(struct dvb_usb_adapter *adapter, int index,
877 u16 pid, int onoff)
878{
879 struct dib0700_state *st = adapter->dev->priv;
880 if (st->is_dib7000pc)
881 return dib7000p_pid_filter(adapter->fe, index, pid, onoff);
882 return dib7000m_pid_filter(adapter->fe, index, pid, onoff);
883}
884
885static int stk7700p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
886{
887 struct dib0700_state *st = adapter->dev->priv;
888 if (st->is_dib7000pc)
889 return dib7000p_pid_filter_ctrl(adapter->fe, onoff);
890 return dib7000m_pid_filter_ctrl(adapter->fe, onoff);
891}
892
893static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
894{
895 return dib7000p_pid_filter(adapter->fe, index, pid, onoff);
896}
897
898static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
899{
900 return dib7000p_pid_filter_ctrl(adapter->fe, onoff);
901}
902
903static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
904 60000, 15000,
905 1, 20, 3, 1, 0,
906 0, 0, 1, 1, 2,
907 (3 << 14) | (1 << 12) | (524 << 0),
908 (0 << 25) | 0,
909 20452225,
910 12000000,
911};
912
913static struct dib7000p_config dib7070p_dib7000p_config = {
914 .output_mpeg2_in_188_bytes = 1,
915
916 .agc_config_count = 1,
917 .agc = &dib7070_agc_config,
918 .bw = &dib7070_bw_config_12_mhz,
919 .tuner_is_baseband = 1,
920 .spur_protect = 1,
921
922 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
923 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
924 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
925
926 .hostbus_diversity = 1,
927};
928
929/* STK7070P */
930static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
931{
932 struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
933 if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
934 p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
935 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
936 else
937 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
938 msleep(10);
939 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
940 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
941 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
942 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
943
944 dib0700_ctrl_clock(adap->dev, 72, 1);
945
946 msleep(10);
947 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
948 msleep(10);
949 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
950
951 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
952 &dib7070p_dib7000p_config) != 0) {
953 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
954 __func__);
955 return -ENODEV;
956 }
957
958 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
959 &dib7070p_dib7000p_config);
960 return adap->fe == NULL ? -ENODEV : 0;
961}
962
963/* STK7770P */
964static struct dib7000p_config dib7770p_dib7000p_config = {
965 .output_mpeg2_in_188_bytes = 1,
966
967 .agc_config_count = 1,
968 .agc = &dib7070_agc_config,
969 .bw = &dib7070_bw_config_12_mhz,
970 .tuner_is_baseband = 1,
971 .spur_protect = 1,
972
973 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
974 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
975 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
976
977 .hostbus_diversity = 1,
978 .enable_current_mirror = 1,
979 .disable_sample_and_hold = 0,
980};
981
982static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap)
983{
984 struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
985 if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
986 p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
987 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
988 else
989 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
990 msleep(10);
991 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
992 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
993 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
994 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
995
996 dib0700_ctrl_clock(adap->dev, 72, 1);
997
998 msleep(10);
999 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1000 msleep(10);
1001 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1002
1003 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1004 &dib7770p_dib7000p_config) != 0) {
1005 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
1006 __func__);
1007 return -ENODEV;
1008 }
1009
1010 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1011 &dib7770p_dib7000p_config);
1012 return adap->fe == NULL ? -ENODEV : 0;
1013}
1014
1015/* DIB807x generic */
1016static struct dibx000_agc_config dib807x_agc_config[2] = {
1017 {
1018 BAND_VHF,
1019 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1020 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1021 * P_agc_inv_pwm2=0,P_agc_inh_dc_rv_est=0,
1022 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1023 * P_agc_write=0 */
1024 (0 << 15) | (0 << 14) | (7 << 11) | (0 << 10) | (0 << 9) |
1025 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
1026 (0 << 0), /* setup*/
1027
1028 600, /* inv_gain*/
1029 10, /* time_stabiliz*/
1030
1031 0, /* alpha_level*/
1032 118, /* thlock*/
1033
1034 0, /* wbd_inv*/
1035 3530, /* wbd_ref*/
1036 1, /* wbd_sel*/
1037 5, /* wbd_alpha*/
1038
1039 65535, /* agc1_max*/
1040 0, /* agc1_min*/
1041
1042 65535, /* agc2_max*/
1043 0, /* agc2_min*/
1044
1045 0, /* agc1_pt1*/
1046 40, /* agc1_pt2*/
1047 183, /* agc1_pt3*/
1048 206, /* agc1_slope1*/
1049 255, /* agc1_slope2*/
1050 72, /* agc2_pt1*/
1051 152, /* agc2_pt2*/
1052 88, /* agc2_slope1*/
1053 90, /* agc2_slope2*/
1054
1055 17, /* alpha_mant*/
1056 27, /* alpha_exp*/
1057 23, /* beta_mant*/
1058 51, /* beta_exp*/
1059
1060 0, /* perform_agc_softsplit*/
1061 }, {
1062 BAND_UHF,
1063 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1064 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1065 * P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1066 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1067 * P_agc_write=0 */
1068 (0 << 15) | (0 << 14) | (1 << 11) | (0 << 10) | (0 << 9) |
1069 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
1070 (0 << 0), /* setup */
1071
1072 600, /* inv_gain*/
1073 10, /* time_stabiliz*/
1074
1075 0, /* alpha_level*/
1076 118, /* thlock*/
1077
1078 0, /* wbd_inv*/
1079 3530, /* wbd_ref*/
1080 1, /* wbd_sel*/
1081 5, /* wbd_alpha*/
1082
1083 65535, /* agc1_max*/
1084 0, /* agc1_min*/
1085
1086 65535, /* agc2_max*/
1087 0, /* agc2_min*/
1088
1089 0, /* agc1_pt1*/
1090 40, /* agc1_pt2*/
1091 183, /* agc1_pt3*/
1092 206, /* agc1_slope1*/
1093 255, /* agc1_slope2*/
1094 72, /* agc2_pt1*/
1095 152, /* agc2_pt2*/
1096 88, /* agc2_slope1*/
1097 90, /* agc2_slope2*/
1098
1099 17, /* alpha_mant*/
1100 27, /* alpha_exp*/
1101 23, /* beta_mant*/
1102 51, /* beta_exp*/
1103
1104 0, /* perform_agc_softsplit*/
1105 }
1106};
1107
1108static struct dibx000_bandwidth_config dib807x_bw_config_12_mhz = {
1109 60000, 15000, /* internal, sampling*/
1110 1, 20, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass*/
1111 0, 0, 1, 1, 2, /* misc: refdiv, bypclk_div, IO_CLK_en_core,
1112 ADClkSrc, modulo */
1113 (3 << 14) | (1 << 12) | (599 << 0), /* sad_cfg: refsel, sel, freq_15k*/
1114 (0 << 25) | 0, /* ifreq = 0.000000 MHz*/
1115 18179755, /* timf*/
1116 12000000, /* xtal_hz*/
1117};
1118
1119static struct dib8000_config dib807x_dib8000_config[2] = {
1120 {
1121 .output_mpeg2_in_188_bytes = 1,
1122
1123 .agc_config_count = 2,
1124 .agc = dib807x_agc_config,
1125 .pll = &dib807x_bw_config_12_mhz,
1126 .tuner_is_baseband = 1,
1127
1128 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1129 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1130 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1131
1132 .hostbus_diversity = 1,
1133 .div_cfg = 1,
1134 .agc_control = &dib0070_ctrl_agc_filter,
1135 .output_mode = OUTMODE_MPEG2_FIFO,
1136 .drives = 0x2d98,
1137 }, {
1138 .output_mpeg2_in_188_bytes = 1,
1139
1140 .agc_config_count = 2,
1141 .agc = dib807x_agc_config,
1142 .pll = &dib807x_bw_config_12_mhz,
1143 .tuner_is_baseband = 1,
1144
1145 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1146 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1147 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1148
1149 .hostbus_diversity = 1,
1150 .agc_control = &dib0070_ctrl_agc_filter,
1151 .output_mode = OUTMODE_MPEG2_FIFO,
1152 .drives = 0x2d98,
1153 }
1154};
1155
1156static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff)
1157{
1158 return dib8000_set_gpio(fe, 5, 0, !onoff);
1159}
1160
1161static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff)
1162{
1163 return dib8000_set_gpio(fe, 0, 0, onoff);
1164}
1165
1166static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
1167 { 240, 7},
1168 { 0xffff, 6},
1169};
1170
1171static struct dib0070_config dib807x_dib0070_config[2] = {
1172 {
1173 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1174 .reset = dib80xx_tuner_reset,
1175 .sleep = dib80xx_tuner_sleep,
1176 .clock_khz = 12000,
1177 .clock_pad_drive = 4,
1178 .vga_filter = 1,
1179 .force_crystal_mode = 1,
1180 .enable_third_order_filter = 1,
1181 .charge_pump = 0,
1182 .wbd_gain = dib8070_wbd_gain_cfg,
1183 .osc_buffer_state = 0,
1184 .freq_offset_khz_uhf = -100,
1185 .freq_offset_khz_vhf = -100,
1186 }, {
1187 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1188 .reset = dib80xx_tuner_reset,
1189 .sleep = dib80xx_tuner_sleep,
1190 .clock_khz = 12000,
1191 .clock_pad_drive = 2,
1192 .vga_filter = 1,
1193 .force_crystal_mode = 1,
1194 .enable_third_order_filter = 1,
1195 .charge_pump = 0,
1196 .wbd_gain = dib8070_wbd_gain_cfg,
1197 .osc_buffer_state = 0,
1198 .freq_offset_khz_uhf = -25,
1199 .freq_offset_khz_vhf = -25,
1200 }
1201};
1202
1203static int dib807x_set_param_override(struct dvb_frontend *fe,
1204 struct dvb_frontend_parameters *fep)
1205{
1206 struct dvb_usb_adapter *adap = fe->dvb->priv;
1207 struct dib0700_adapter_state *state = adap->priv;
1208
1209 u16 offset = dib0070_wbd_offset(fe);
1210 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1211 switch (band) {
1212 case BAND_VHF:
1213 offset += 750;
1214 break;
1215 case BAND_UHF: /* fall-thru wanted */
1216 default:
1217 offset += 250; break;
1218 }
1219 deb_info("WBD for DiB8000: %d\n", offset);
1220 dib8000_set_wbd_ref(fe, offset);
1221
1222 return state->set_param_save(fe, fep);
1223}
1224
1225static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
1226{
1227 struct dib0700_adapter_state *st = adap->priv;
1228 struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe,
1229 DIBX000_I2C_INTERFACE_TUNER, 1);
1230
1231 if (adap->id == 0) {
1232 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1233 &dib807x_dib0070_config[0]) == NULL)
1234 return -ENODEV;
1235 } else {
1236 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1237 &dib807x_dib0070_config[1]) == NULL)
1238 return -ENODEV;
1239 }
1240
1241 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1242 adap->fe->ops.tuner_ops.set_params = dib807x_set_param_override;
1243 return 0;
1244}
1245
1246static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
1247 u16 pid, int onoff)
1248{
1249 return dib8000_pid_filter(adapter->fe, index, pid, onoff);
1250}
1251
1252static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
1253 int onoff)
1254{
1255 return dib8000_pid_filter_ctrl(adapter->fe, onoff);
1256}
1257
1258/* STK807x */
1259static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
1260{
1261 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1262 msleep(10);
1263 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1264 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1265 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1266
1267 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1268
1269 dib0700_ctrl_clock(adap->dev, 72, 1);
1270
1271 msleep(10);
1272 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1273 msleep(10);
1274 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1275
1276 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1277 0x80);
1278
1279 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
1280 &dib807x_dib8000_config[0]);
1281
1282 return adap->fe == NULL ? -ENODEV : 0;
1283}
1284
1285/* STK807xPVR */
1286static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
1287{
1288 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1289 msleep(30);
1290 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1291 msleep(500);
1292 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1293 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1294 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1295
1296 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1297
1298 dib0700_ctrl_clock(adap->dev, 72, 1);
1299
1300 msleep(10);
1301 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1302 msleep(10);
1303 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1304
1305 /* initialize IC 0 */
1306 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80);
1307
1308 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
1309 &dib807x_dib8000_config[0]);
1310
1311 return adap->fe == NULL ? -ENODEV : 0;
1312}
1313
1314static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
1315{
1316 /* initialize IC 1 */
1317 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82);
1318
1319 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
1320 &dib807x_dib8000_config[1]);
1321
1322 return adap->fe == NULL ? -ENODEV : 0;
1323}
1324
1325/* STK8096GP */
1326struct dibx000_agc_config dib8090_agc_config[2] = {
1327 {
1328 BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
1329 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
1330 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1331 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
1332 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
1333 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1334
1335 787,
1336 10,
1337
1338 0,
1339 118,
1340
1341 0,
1342 3530,
1343 1,
1344 5,
1345
1346 65535,
1347 0,
1348
1349 65535,
1350 0,
1351
1352 0,
1353 32,
1354 114,
1355 143,
1356 144,
1357 114,
1358 227,
1359 116,
1360 117,
1361
1362 28,
1363 26,
1364 31,
1365 51,
1366
1367 0,
1368 },
1369 {
1370 BAND_CBAND,
1371 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
1372 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1373 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
1374 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
1375 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1376
1377 787,
1378 10,
1379
1380 0,
1381 118,
1382
1383 0,
1384 3530,
1385 1,
1386 5,
1387
1388 0,
1389 0,
1390
1391 65535,
1392 0,
1393
1394 0,
1395 32,
1396 114,
1397 143,
1398 144,
1399 114,
1400 227,
1401 116,
1402 117,
1403
1404 28,
1405 26,
1406 31,
1407 51,
1408
1409 0,
1410 }
1411};
1412
1413static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
1414 54000, 13500,
1415 1, 18, 3, 1, 0,
1416 0, 0, 1, 1, 2,
1417 (3 << 14) | (1 << 12) | (599 << 0),
1418 (0 << 25) | 0,
1419 20199727,
1420 12000000,
1421};
1422
1423static int dib8090_get_adc_power(struct dvb_frontend *fe)
1424{
1425 return dib8000_get_adc_power(fe, 1);
1426}
1427
1428static struct dib8000_config dib809x_dib8000_config[2] = {
1429 {
1430 .output_mpeg2_in_188_bytes = 1,
1431
1432 .agc_config_count = 2,
1433 .agc = dib8090_agc_config,
1434 .agc_control = dib0090_dcc_freq,
1435 .pll = &dib8090_pll_config_12mhz,
1436 .tuner_is_baseband = 1,
1437
1438 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1439 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1440 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1441
1442 .hostbus_diversity = 1,
1443 .div_cfg = 0x31,
1444 .output_mode = OUTMODE_MPEG2_FIFO,
1445 .drives = 0x2d98,
1446 .diversity_delay = 48,
1447 .refclksel = 3,
1448 }, {
1449 .output_mpeg2_in_188_bytes = 1,
1450
1451 .agc_config_count = 2,
1452 .agc = dib8090_agc_config,
1453 .agc_control = dib0090_dcc_freq,
1454 .pll = &dib8090_pll_config_12mhz,
1455 .tuner_is_baseband = 1,
1456
1457 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1458 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1459 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1460
1461 .hostbus_diversity = 1,
1462 .div_cfg = 0x31,
1463 .output_mode = OUTMODE_DIVERSITY,
1464 .drives = 0x2d08,
1465 .diversity_delay = 1,
1466 .refclksel = 3,
1467 }
1468};
1469
1470static struct dib0090_wbd_slope dib8090_wbd_table[] = {
1471 /* max freq ; cold slope ; cold offset ; warm slope ; warm offset ; wbd gain */
1472 { 120, 0, 500, 0, 500, 4 }, /* CBAND */
1473 { 170, 0, 450, 0, 450, 4 }, /* CBAND */
1474 { 380, 48, 373, 28, 259, 6 }, /* VHF */
1475 { 860, 34, 700, 36, 616, 6 }, /* high UHF */
1476 { 0xFFFF, 34, 700, 36, 616, 6 }, /* default */
1477};
1478
1479static struct dib0090_config dib809x_dib0090_config = {
1480 .io.pll_bypass = 1,
1481 .io.pll_range = 1,
1482 .io.pll_prediv = 1,
1483 .io.pll_loopdiv = 20,
1484 .io.adc_clock_ratio = 8,
1485 .io.pll_int_loop_filt = 0,
1486 .io.clock_khz = 12000,
1487 .reset = dib80xx_tuner_reset,
1488 .sleep = dib80xx_tuner_sleep,
1489 .clkouttobamse = 1,
1490 .analog_output = 1,
1491 .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
1492 .use_pwm_agc = 1,
1493 .clkoutdrive = 1,
1494 .get_adc_power = dib8090_get_adc_power,
1495 .freq_offset_khz_uhf = -63,
1496 .freq_offset_khz_vhf = -143,
1497 .wbd = dib8090_wbd_table,
1498 .fref_clock_ratio = 6,
1499};
1500
1501static int dib8096_set_param_override(struct dvb_frontend *fe,
1502 struct dvb_frontend_parameters *fep)
1503{
1504 struct dvb_usb_adapter *adap = fe->dvb->priv;
1505 struct dib0700_adapter_state *state = adap->priv;
1506 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1507 u16 target;
1508 int ret = 0;
1509 enum frontend_tune_state tune_state = CT_SHUTDOWN;
1510 u16 ltgain, rf_gain_limit;
1511
1512 ret = state->set_param_save(fe, fep);
1513 if (ret < 0)
1514 return ret;
1515
1516 target = (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2;
1517 dib8000_set_wbd_ref(fe, target);
1518
1519
1520 if (band == BAND_CBAND) {
1521 deb_info("tuning in CBAND - soft-AGC startup\n");
1522 dib0090_set_tune_state(fe, CT_AGC_START);
1523 do {
1524 ret = dib0090_gain_control(fe);
1525 msleep(ret);
1526 tune_state = dib0090_get_tune_state(fe);
1527 if (tune_state == CT_AGC_STEP_0)
1528 dib8000_set_gpio(fe, 6, 0, 1);
1529 else if (tune_state == CT_AGC_STEP_1) {
1530 dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
1531 if (rf_gain_limit == 0)
1532 dib8000_set_gpio(fe, 6, 0, 0);
1533 }
1534 } while (tune_state < CT_AGC_STOP);
1535 dib0090_pwm_gain_reset(fe);
1536 dib8000_pwm_agc_reset(fe);
1537 dib8000_set_tune_state(fe, CT_DEMOD_START);
1538 } else {
1539 deb_info("not tuning in CBAND - standard AGC startup\n");
1540 dib0090_pwm_gain_reset(fe);
1541 }
1542
1543 return 0;
1544}
1545
1546static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
1547{
1548 struct dib0700_adapter_state *st = adap->priv;
1549 struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1550
1551 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL)
1552 return -ENODEV;
1553
1554 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1555 adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override;
1556 return 0;
1557}
1558
1559static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
1560{
1561 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1562 msleep(10);
1563 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1564 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1565 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1566
1567 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1568
1569 dib0700_ctrl_clock(adap->dev, 72, 1);
1570
1571 msleep(10);
1572 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1573 msleep(10);
1574 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1575
1576 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80);
1577
1578 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
1579
1580 return adap->fe == NULL ? -ENODEV : 0;
1581}
1582
1583static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap)
1584{
1585 struct dib0700_adapter_state *st = adap->priv;
1586 struct i2c_adapter *tun_i2c;
1587 struct dvb_frontend *fe_slave = dib8000_get_slave_frontend(adap->fe, 1);
1588
1589 if (fe_slave) {
1590 tun_i2c = dib8000_get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1);
1591 if (dvb_attach(dib0090_register, fe_slave, tun_i2c, &dib809x_dib0090_config) == NULL)
1592 return -ENODEV;
1593 fe_slave->dvb = adap->fe->dvb;
1594 fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override;
1595 }
1596 tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1597 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL)
1598 return -ENODEV;
1599
1600 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1601 adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override;
1602
1603 return 0;
1604}
1605
1606static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap)
1607{
1608 struct dvb_frontend *fe_slave;
1609
1610 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1611 msleep(20);
1612 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1613 msleep(1000);
1614 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1615 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1616 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1617
1618 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1619
1620 dib0700_ctrl_clock(adap->dev, 72, 1);
1621
1622 msleep(20);
1623 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1624 msleep(20);
1625 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1626
1627 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80);
1628
1629 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
1630 if (adap->fe == NULL)
1631 return -ENODEV;
1632
1633 fe_slave = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]);
1634 dib8000_set_slave_frontend(adap->fe, fe_slave);
1635
1636 return fe_slave == NULL ? -ENODEV : 0;
1637}
1638
1639/* STK9090M */
1640static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
1641{
1642 return dib9000_fw_pid_filter(adapter->fe, index, pid, onoff);
1643}
1644
1645static int dib90x0_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
1646{
1647 return dib9000_fw_pid_filter_ctrl(adapter->fe, onoff);
1648}
1649
1650static int dib90x0_tuner_reset(struct dvb_frontend *fe, int onoff)
1651{
1652 return dib9000_set_gpio(fe, 5, 0, !onoff);
1653}
1654
1655static int dib90x0_tuner_sleep(struct dvb_frontend *fe, int onoff)
1656{
1657 return dib9000_set_gpio(fe, 0, 0, onoff);
1658}
1659
1660static int dib01x0_pmu_update(struct i2c_adapter *i2c, u16 *data, u8 len)
1661{
1662 u8 wb[4] = { 0xc >> 8, 0xc & 0xff, 0, 0 };
1663 u8 rb[2];
1664 struct i2c_msg msg[2] = {
1665 {.addr = 0x1e >> 1, .flags = 0, .buf = wb, .len = 2},
1666 {.addr = 0x1e >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2},
1667 };
1668 u8 index_data;
1669
1670 dibx000_i2c_set_speed(i2c, 250);
1671
1672 if (i2c_transfer(i2c, msg, 2) != 2)
1673 return -EIO;
1674
1675 switch (rb[0] << 8 | rb[1]) {
1676 case 0:
1677 deb_info("Found DiB0170 rev1: This version of DiB0170 is not supported any longer.\n");
1678 return -EIO;
1679 case 1:
1680 deb_info("Found DiB0170 rev2");
1681 break;
1682 case 2:
1683 deb_info("Found DiB0190 rev2");
1684 break;
1685 default:
1686 deb_info("DiB01x0 not found");
1687 return -EIO;
1688 }
1689
1690 for (index_data = 0; index_data < len; index_data += 2) {
1691 wb[2] = (data[index_data + 1] >> 8) & 0xff;
1692 wb[3] = (data[index_data + 1]) & 0xff;
1693
1694 if (data[index_data] == 0) {
1695 wb[0] = (data[index_data] >> 8) & 0xff;
1696 wb[1] = (data[index_data]) & 0xff;
1697 msg[0].len = 2;
1698 if (i2c_transfer(i2c, msg, 2) != 2)
1699 return -EIO;
1700 wb[2] |= rb[0];
1701 wb[3] |= rb[1] & ~(3 << 4);
1702 }
1703
1704 wb[0] = (data[index_data] >> 8)&0xff;
1705 wb[1] = (data[index_data])&0xff;
1706 msg[0].len = 4;
1707 if (i2c_transfer(i2c, &msg[0], 1) != 1)
1708 return -EIO;
1709 }
1710 return 0;
1711}
1712
1713static struct dib9000_config stk9090m_config = {
1714 .output_mpeg2_in_188_bytes = 1,
1715 .output_mode = OUTMODE_MPEG2_FIFO,
1716 .vcxo_timer = 279620,
1717 .timing_frequency = 20452225,
1718 .demod_clock_khz = 60000,
1719 .xtal_clock_khz = 30000,
1720 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
1721 .subband = {
1722 2,
1723 {
1724 { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0008 } }, /* GPIO 3 to 1 for VHF */
1725 { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0000 } }, /* GPIO 3 to 0 for UHF */
1726 { 0 },
1727 },
1728 },
1729 .gpio_function = {
1730 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
1731 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
1732 },
1733};
1734
1735static struct dib9000_config nim9090md_config[2] = {
1736 {
1737 .output_mpeg2_in_188_bytes = 1,
1738 .output_mode = OUTMODE_MPEG2_FIFO,
1739 .vcxo_timer = 279620,
1740 .timing_frequency = 20452225,
1741 .demod_clock_khz = 60000,
1742 .xtal_clock_khz = 30000,
1743 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
1744 }, {
1745 .output_mpeg2_in_188_bytes = 1,
1746 .output_mode = OUTMODE_DIVERSITY,
1747 .vcxo_timer = 279620,
1748 .timing_frequency = 20452225,
1749 .demod_clock_khz = 60000,
1750 .xtal_clock_khz = 30000,
1751 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
1752 .subband = {
1753 2,
1754 {
1755 { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0006 } }, /* GPIO 1 and 2 to 1 for VHF */
1756 { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0000 } }, /* GPIO 1 and 2 to 0 for UHF */
1757 { 0 },
1758 },
1759 },
1760 .gpio_function = {
1761 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
1762 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
1763 },
1764 }
1765};
1766
1767static struct dib0090_config dib9090_dib0090_config = {
1768 .io.pll_bypass = 0,
1769 .io.pll_range = 1,
1770 .io.pll_prediv = 1,
1771 .io.pll_loopdiv = 8,
1772 .io.adc_clock_ratio = 8,
1773 .io.pll_int_loop_filt = 0,
1774 .io.clock_khz = 30000,
1775 .reset = dib90x0_tuner_reset,
1776 .sleep = dib90x0_tuner_sleep,
1777 .clkouttobamse = 0,
1778 .analog_output = 0,
1779 .use_pwm_agc = 0,
1780 .clkoutdrive = 0,
1781 .freq_offset_khz_uhf = 0,
1782 .freq_offset_khz_vhf = 0,
1783};
1784
1785static struct dib0090_config nim9090md_dib0090_config[2] = {
1786 {
1787 .io.pll_bypass = 0,
1788 .io.pll_range = 1,
1789 .io.pll_prediv = 1,
1790 .io.pll_loopdiv = 8,
1791 .io.adc_clock_ratio = 8,
1792 .io.pll_int_loop_filt = 0,
1793 .io.clock_khz = 30000,
1794 .reset = dib90x0_tuner_reset,
1795 .sleep = dib90x0_tuner_sleep,
1796 .clkouttobamse = 1,
1797 .analog_output = 0,
1798 .use_pwm_agc = 0,
1799 .clkoutdrive = 0,
1800 .freq_offset_khz_uhf = 0,
1801 .freq_offset_khz_vhf = 0,
1802 }, {
1803 .io.pll_bypass = 0,
1804 .io.pll_range = 1,
1805 .io.pll_prediv = 1,
1806 .io.pll_loopdiv = 8,
1807 .io.adc_clock_ratio = 8,
1808 .io.pll_int_loop_filt = 0,
1809 .io.clock_khz = 30000,
1810 .reset = dib90x0_tuner_reset,
1811 .sleep = dib90x0_tuner_sleep,
1812 .clkouttobamse = 0,
1813 .analog_output = 0,
1814 .use_pwm_agc = 0,
1815 .clkoutdrive = 0,
1816 .freq_offset_khz_uhf = 0,
1817 .freq_offset_khz_vhf = 0,
1818 }
1819};
1820
1821
1822static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap)
1823{
1824 struct dib0700_adapter_state *state = adap->priv;
1825 struct dib0700_state *st = adap->dev->priv;
1826 u32 fw_version;
1827
1828 /* Make use of the new i2c functions from FW 1.20 */
1829 dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
1830 if (fw_version >= 0x10200)
1831 st->fw_use_new_i2c_api = 1;
1832 dib0700_set_i2c_speed(adap->dev, 340);
1833
1834 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1835 msleep(20);
1836 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1837 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1838 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1839 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1840
1841 dib0700_ctrl_clock(adap->dev, 72, 1);
1842
1843 msleep(20);
1844 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1845 msleep(20);
1846 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1847
1848 dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80);
1849
1850 if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
1851 deb_info("%s: Upload failed. (file not found?)\n", __func__);
1852 return -ENODEV;
1853 } else {
1854 deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
1855 }
1856 stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size;
1857 stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data;
1858
1859 adap->fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config);
1860
1861 return adap->fe == NULL ? -ENODEV : 0;
1862}
1863
1864static int dib9090_tuner_attach(struct dvb_usb_adapter *adap)
1865{
1866 struct dib0700_adapter_state *state = adap->priv;
1867 struct i2c_adapter *i2c = dib9000_get_tuner_interface(adap->fe);
1868 u16 data_dib190[10] = {
1869 1, 0x1374,
1870 2, 0x01a2,
1871 7, 0x0020,
1872 0, 0x00ef,
1873 8, 0x0486,
1874 };
1875
1876 if (dvb_attach(dib0090_fw_register, adap->fe, i2c, &dib9090_dib0090_config) == NULL)
1877 return -ENODEV;
1878 i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
1879 if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0)
1880 return -ENODEV;
1881 dib0700_set_i2c_speed(adap->dev, 2000);
1882 if (dib9000_firmware_post_pll_init(adap->fe) < 0)
1883 return -ENODEV;
1884 release_firmware(state->frontend_firmware);
1885 return 0;
1886}
1887
1888static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap)
1889{
1890 struct dib0700_adapter_state *state = adap->priv;
1891 struct dib0700_state *st = adap->dev->priv;
1892 struct i2c_adapter *i2c;
1893 struct dvb_frontend *fe_slave;
1894 u32 fw_version;
1895
1896 /* Make use of the new i2c functions from FW 1.20 */
1897 dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
1898 if (fw_version >= 0x10200)
1899 st->fw_use_new_i2c_api = 1;
1900 dib0700_set_i2c_speed(adap->dev, 340);
1901
1902 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1903 msleep(20);
1904 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1905 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1906 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1907 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1908
1909 dib0700_ctrl_clock(adap->dev, 72, 1);
1910
1911 msleep(20);
1912 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1913 msleep(20);
1914 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1915
1916 if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
1917 deb_info("%s: Upload failed. (file not found?)\n", __func__);
1918 return -EIO;
1919 } else {
1920 deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
1921 }
1922 nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size;
1923 nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data;
1924 nim9090md_config[1].microcode_B_fe_size = state->frontend_firmware->size;
1925 nim9090md_config[1].microcode_B_fe_buffer = state->frontend_firmware->data;
1926
1927 dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80);
1928 adap->fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]);
1929
1930 if (adap->fe == NULL)
1931 return -ENODEV;
1932
1933 i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0);
1934 dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82);
1935
1936 fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]);
1937 dib9000_set_slave_frontend(adap->fe, fe_slave);
1938
1939 return fe_slave == NULL ? -ENODEV : 0;
1940}
1941
1942static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap)
1943{
1944 struct dib0700_adapter_state *state = adap->priv;
1945 struct i2c_adapter *i2c;
1946 struct dvb_frontend *fe_slave;
1947 u16 data_dib190[10] = {
1948 1, 0x5374,
1949 2, 0x01ae,
1950 7, 0x0020,
1951 0, 0x00ef,
1952 8, 0x0406,
1953 };
1954 i2c = dib9000_get_tuner_interface(adap->fe);
1955 if (dvb_attach(dib0090_fw_register, adap->fe, i2c, &nim9090md_dib0090_config[0]) == NULL)
1956 return -ENODEV;
1957 i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
1958 if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0)
1959 return -ENODEV;
1960 dib0700_set_i2c_speed(adap->dev, 2000);
1961 if (dib9000_firmware_post_pll_init(adap->fe) < 0)
1962 return -ENODEV;
1963
1964 fe_slave = dib9000_get_slave_frontend(adap->fe, 1);
1965 if (fe_slave != NULL) {
1966 i2c = dib9000_get_component_bus_interface(adap->fe);
1967 dib9000_set_i2c_adapter(fe_slave, i2c);
1968
1969 i2c = dib9000_get_tuner_interface(fe_slave);
1970 if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL)
1971 return -ENODEV;
1972 fe_slave->dvb = adap->fe->dvb;
1973 dib9000_fw_set_component_bus_speed(adap->fe, 2000);
1974 if (dib9000_firmware_post_pll_init(fe_slave) < 0)
1975 return -ENODEV;
1976 }
1977 release_firmware(state->frontend_firmware);
1978
1979 return 0;
1980}
1981
1982/* NIM7090 */
1983struct dib7090p_best_adc {
1984 u32 timf;
1985 u32 pll_loopdiv;
1986 u32 pll_prediv;
1987};
1988
1989static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_best_adc *adc)
1990{
1991 u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1;
1992
1993 u16 xtal = 12000;
1994 u32 fcp_min = 1900; /* PLL Minimum Frequency comparator KHz */
1995 u32 fcp_max = 20000; /* PLL Maximum Frequency comparator KHz */
1996 u32 fdem_max = 76000;
1997 u32 fdem_min = 69500;
1998 u32 fcp = 0, fs = 0, fdem = 0;
1999 u32 harmonic_id = 0;
2000
2001 adc->pll_loopdiv = loopdiv;
2002 adc->pll_prediv = prediv;
2003 adc->timf = 0;
2004
2005 deb_info("bandwidth = %d fdem_min =%d", fe->dtv_property_cache.bandwidth_hz, fdem_min);
2006
2007 /* Find Min and Max prediv */
2008 while ((xtal/max_prediv) >= fcp_min)
2009 max_prediv++;
2010
2011 max_prediv--;
2012 min_prediv = max_prediv;
2013 while ((xtal/min_prediv) <= fcp_max) {
2014 min_prediv--;
2015 if (min_prediv == 1)
2016 break;
2017 }
2018 deb_info("MIN prediv = %d : MAX prediv = %d", min_prediv, max_prediv);
2019
2020 min_prediv = 2;
2021
2022 for (prediv = min_prediv ; prediv < max_prediv; prediv++) {
2023 fcp = xtal / prediv;
2024 if (fcp > fcp_min && fcp < fcp_max) {
2025 for (loopdiv = 1 ; loopdiv < 64 ; loopdiv++) {
2026 fdem = ((xtal/prediv) * loopdiv);
2027 fs = fdem / 4;
2028 /* test min/max system restrictions */
2029
2030 if ((fdem >= fdem_min) && (fdem <= fdem_max) && (fs >= fe->dtv_property_cache.bandwidth_hz/1000)) {
2031 spur = 0;
2032 /* test fs harmonics positions */
2033 for (harmonic_id = (fe->dtv_property_cache.frequency / (1000*fs)) ; harmonic_id <= ((fe->dtv_property_cache.frequency / (1000*fs))+1) ; harmonic_id++) {
2034 if (((fs*harmonic_id) >= ((fe->dtv_property_cache.frequency/1000) - (fe->dtv_property_cache.bandwidth_hz/2000))) && ((fs*harmonic_id) <= ((fe->dtv_property_cache.frequency/1000) + (fe->dtv_property_cache.bandwidth_hz/2000)))) {
2035 spur = 1;
2036 break;
2037 }
2038 }
2039
2040 if (!spur) {
2041 adc->pll_loopdiv = loopdiv;
2042 adc->pll_prediv = prediv;
2043 adc->timf = 2396745143UL/fdem*(1 << 9);
2044 adc->timf += ((2396745143UL%fdem) << 9)/fdem;
2045 deb_info("loopdiv=%i prediv=%i timf=%i", loopdiv, prediv, adc->timf);
2046 break;
2047 }
2048 }
2049 }
2050 }
2051 if (!spur)
2052 break;
2053 }
2054
2055
2056 if (adc->pll_loopdiv == 0 && adc->pll_prediv == 0)
2057 return -EINVAL;
2058 else
2059 return 0;
2060}
2061
2062static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
2063{
2064 struct dvb_usb_adapter *adap = fe->dvb->priv;
2065 struct dib0700_adapter_state *state = adap->priv;
2066 struct dibx000_bandwidth_config pll;
2067 u16 target;
2068 struct dib7090p_best_adc adc;
2069 int ret;
2070
2071 ret = state->set_param_save(fe, fep);
2072 if (ret < 0)
2073 return ret;
2074
2075 memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
2076 dib0090_pwm_gain_reset(fe);
2077 target = (dib0090_get_wbd_offset(fe) * 8 + 1) / 2;
2078 dib7000p_set_wbd_ref(fe, target);
2079
2080 if (dib7090p_get_best_sampling(fe, &adc) == 0) {
2081 pll.pll_ratio = adc.pll_loopdiv;
2082 pll.pll_prediv = adc.pll_prediv;
2083
2084 dib7000p_update_pll(fe, &pll);
2085 dib7000p_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf);
2086 }
2087 return 0;
2088}
2089
2090static struct dib0090_wbd_slope dib7090_wbd_table[] = {
2091 { 380, 81, 850, 64, 540, 4},
2092 { 860, 51, 866, 21, 375, 4},
2093 {1700, 0, 250, 0, 100, 6},
2094 {2600, 0, 250, 0, 100, 6},
2095 { 0xFFFF, 0, 0, 0, 0, 0},
2096};
2097
2098struct dibx000_agc_config dib7090_agc_config[2] = {
2099 {
2100 .band_caps = BAND_UHF,
2101 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
2102 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
2103 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
2104
2105 .inv_gain = 687,
2106 .time_stabiliz = 10,
2107
2108 .alpha_level = 0,
2109 .thlock = 118,
2110
2111 .wbd_inv = 0,
2112 .wbd_ref = 1200,
2113 .wbd_sel = 3,
2114 .wbd_alpha = 5,
2115
2116 .agc1_max = 65535,
2117 .agc1_min = 0,
2118
2119 .agc2_max = 65535,
2120 .agc2_min = 0,
2121
2122 .agc1_pt1 = 0,
2123 .agc1_pt2 = 32,
2124 .agc1_pt3 = 114,
2125 .agc1_slope1 = 143,
2126 .agc1_slope2 = 144,
2127 .agc2_pt1 = 114,
2128 .agc2_pt2 = 227,
2129 .agc2_slope1 = 116,
2130 .agc2_slope2 = 117,
2131
2132 .alpha_mant = 18,
2133 .alpha_exp = 0,
2134 .beta_mant = 20,
2135 .beta_exp = 59,
2136
2137 .perform_agc_softsplit = 0,
2138 } , {
2139 .band_caps = BAND_FM | BAND_VHF | BAND_CBAND,
2140 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
2141 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
2142 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
2143
2144 .inv_gain = 732,
2145 .time_stabiliz = 10,
2146
2147 .alpha_level = 0,
2148 .thlock = 118,
2149
2150 .wbd_inv = 0,
2151 .wbd_ref = 1200,
2152 .wbd_sel = 3,
2153 .wbd_alpha = 5,
2154
2155 .agc1_max = 65535,
2156 .agc1_min = 0,
2157
2158 .agc2_max = 65535,
2159 .agc2_min = 0,
2160
2161 .agc1_pt1 = 0,
2162 .agc1_pt2 = 0,
2163 .agc1_pt3 = 98,
2164 .agc1_slope1 = 0,
2165 .agc1_slope2 = 167,
2166 .agc2_pt1 = 98,
2167 .agc2_pt2 = 255,
2168 .agc2_slope1 = 104,
2169 .agc2_slope2 = 0,
2170
2171 .alpha_mant = 18,
2172 .alpha_exp = 0,
2173 .beta_mant = 20,
2174 .beta_exp = 59,
2175
2176 .perform_agc_softsplit = 0,
2177 }
2178};
2179
2180static struct dibx000_bandwidth_config dib7090_clock_config_12_mhz = {
2181 60000, 15000,
2182 1, 5, 0, 0, 0,
2183 0, 0, 1, 1, 2,
2184 (3 << 14) | (1 << 12) | (524 << 0),
2185 (0 << 25) | 0,
2186 20452225,
2187 15000000,
2188};
2189
2190static struct dib7000p_config nim7090_dib7000p_config = {
2191 .output_mpeg2_in_188_bytes = 1,
2192 .hostbus_diversity = 1,
2193 .tuner_is_baseband = 1,
2194 .update_lna = NULL,
2195
2196 .agc_config_count = 2,
2197 .agc = dib7090_agc_config,
2198
2199 .bw = &dib7090_clock_config_12_mhz,
2200
2201 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2202 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2203 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2204
2205 .pwm_freq_div = 0,
2206
2207 .agc_control = dib7090_agc_restart,
2208
2209 .spur_protect = 0,
2210 .disable_sample_and_hold = 0,
2211 .enable_current_mirror = 0,
2212 .diversity_delay = 0,
2213
2214 .output_mode = OUTMODE_MPEG2_FIFO,
2215 .enMpegOutput = 1,
2216};
2217
2218static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = {
2219 {
2220 .output_mpeg2_in_188_bytes = 1,
2221 .hostbus_diversity = 1,
2222 .tuner_is_baseband = 1,
2223 .update_lna = NULL,
2224
2225 .agc_config_count = 2,
2226 .agc = dib7090_agc_config,
2227
2228 .bw = &dib7090_clock_config_12_mhz,
2229
2230 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2231 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2232 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2233
2234 .pwm_freq_div = 0,
2235
2236 .agc_control = dib7090_agc_restart,
2237
2238 .spur_protect = 0,
2239 .disable_sample_and_hold = 0,
2240 .enable_current_mirror = 0,
2241 .diversity_delay = 0,
2242
2243 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
2244 .default_i2c_addr = 0x90,
2245 .enMpegOutput = 1,
2246 }, {
2247 .output_mpeg2_in_188_bytes = 1,
2248 .hostbus_diversity = 1,
2249 .tuner_is_baseband = 1,
2250 .update_lna = NULL,
2251
2252 .agc_config_count = 2,
2253 .agc = dib7090_agc_config,
2254
2255 .bw = &dib7090_clock_config_12_mhz,
2256
2257 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2258 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2259 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2260
2261 .pwm_freq_div = 0,
2262
2263 .agc_control = dib7090_agc_restart,
2264
2265 .spur_protect = 0,
2266 .disable_sample_and_hold = 0,
2267 .enable_current_mirror = 0,
2268 .diversity_delay = 0,
2269
2270 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
2271 .default_i2c_addr = 0x92,
2272 .enMpegOutput = 0,
2273 }
2274};
2275
2276static const struct dib0090_config nim7090_dib0090_config = {
2277 .io.clock_khz = 12000,
2278 .io.pll_bypass = 0,
2279 .io.pll_range = 0,
2280 .io.pll_prediv = 3,
2281 .io.pll_loopdiv = 6,
2282 .io.adc_clock_ratio = 0,
2283 .io.pll_int_loop_filt = 0,
2284 .reset = dib7090_tuner_sleep,
2285 .sleep = dib7090_tuner_sleep,
2286
2287 .freq_offset_khz_uhf = 0,
2288 .freq_offset_khz_vhf = 0,
2289
2290 .get_adc_power = dib7090_get_adc_power,
2291
2292 .clkouttobamse = 1,
2293 .analog_output = 0,
2294
2295 .wbd_vhf_offset = 0,
2296 .wbd_cband_offset = 0,
2297 .use_pwm_agc = 1,
2298 .clkoutdrive = 0,
2299
2300 .fref_clock_ratio = 0,
2301
2302 .wbd = dib7090_wbd_table,
2303
2304 .ls_cfg_pad_drv = 0,
2305 .data_tx_drv = 0,
2306 .low_if = NULL,
2307 .in_soc = 1,
2308};
2309
2310static const struct dib0090_config tfe7090pvr_dib0090_config[2] = {
2311 {
2312 .io.clock_khz = 12000,
2313 .io.pll_bypass = 0,
2314 .io.pll_range = 0,
2315 .io.pll_prediv = 3,
2316 .io.pll_loopdiv = 6,
2317 .io.adc_clock_ratio = 0,
2318 .io.pll_int_loop_filt = 0,
2319 .reset = dib7090_tuner_sleep,
2320 .sleep = dib7090_tuner_sleep,
2321
2322 .freq_offset_khz_uhf = 50,
2323 .freq_offset_khz_vhf = 70,
2324
2325 .get_adc_power = dib7090_get_adc_power,
2326
2327 .clkouttobamse = 1,
2328 .analog_output = 0,
2329
2330 .wbd_vhf_offset = 0,
2331 .wbd_cband_offset = 0,
2332 .use_pwm_agc = 1,
2333 .clkoutdrive = 0,
2334
2335 .fref_clock_ratio = 0,
2336
2337 .wbd = dib7090_wbd_table,
2338
2339 .ls_cfg_pad_drv = 0,
2340 .data_tx_drv = 0,
2341 .low_if = NULL,
2342 .in_soc = 1,
2343 }, {
2344 .io.clock_khz = 12000,
2345 .io.pll_bypass = 0,
2346 .io.pll_range = 0,
2347 .io.pll_prediv = 3,
2348 .io.pll_loopdiv = 6,
2349 .io.adc_clock_ratio = 0,
2350 .io.pll_int_loop_filt = 0,
2351 .reset = dib7090_tuner_sleep,
2352 .sleep = dib7090_tuner_sleep,
2353
2354 .freq_offset_khz_uhf = -50,
2355 .freq_offset_khz_vhf = -70,
2356
2357 .get_adc_power = dib7090_get_adc_power,
2358
2359 .clkouttobamse = 1,
2360 .analog_output = 0,
2361
2362 .wbd_vhf_offset = 0,
2363 .wbd_cband_offset = 0,
2364 .use_pwm_agc = 1,
2365 .clkoutdrive = 0,
2366
2367 .fref_clock_ratio = 0,
2368
2369 .wbd = dib7090_wbd_table,
2370
2371 .ls_cfg_pad_drv = 0,
2372 .data_tx_drv = 0,
2373 .low_if = NULL,
2374 .in_soc = 1,
2375 }
2376};
2377
2378static int nim7090_frontend_attach(struct dvb_usb_adapter *adap)
2379{
2380 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2381 msleep(20);
2382 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2383 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2384 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2385 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2386
2387 msleep(20);
2388 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2389 msleep(20);
2390 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2391
2392 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) {
2393 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2394 return -ENODEV;
2395 }
2396 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config);
2397
2398 return adap->fe == NULL ? -ENODEV : 0;
2399}
2400
2401static int nim7090_tuner_attach(struct dvb_usb_adapter *adap)
2402{
2403 struct dib0700_adapter_state *st = adap->priv;
2404 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe);
2405
2406 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &nim7090_dib0090_config) == NULL)
2407 return -ENODEV;
2408
2409 dib7000p_set_gpio(adap->fe, 8, 0, 1);
2410
2411 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
2412 adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2413 return 0;
2414}
2415
2416static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
2417{
2418 struct dib0700_state *st = adap->dev->priv;
2419
2420 /* The TFE7090 requires the dib0700 to not be in master mode */
2421 st->disable_streaming_master_mode = 1;
2422
2423 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2424 msleep(20);
2425 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2426 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2427 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2428 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2429
2430 msleep(20);
2431 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2432 msleep(20);
2433 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2434
2435 /* initialize IC 0 */
2436 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) {
2437 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2438 return -ENODEV;
2439 }
2440
2441 dib0700_set_i2c_speed(adap->dev, 340);
2442 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
2443 if (adap->fe == NULL)
2444 return -ENODEV;
2445
2446 dib7090_slave_reset(adap->fe);
2447
2448 return 0;
2449}
2450
2451static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap)
2452{
2453 struct i2c_adapter *i2c;
2454
2455 if (adap->dev->adapter[0].fe == NULL) {
2456 err("the master dib7090 has to be initialized first");
2457 return -ENODEV; /* the master device has not been initialized */
2458 }
2459
2460 i2c = dib7000p_get_i2c_master(adap->dev->adapter[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1);
2461 if (dib7000p_i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) {
2462 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2463 return -ENODEV;
2464 }
2465
2466 adap->fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]);
2467 dib0700_set_i2c_speed(adap->dev, 200);
2468
2469 return adap->fe == NULL ? -ENODEV : 0;
2470}
2471
2472static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap)
2473{
2474 struct dib0700_adapter_state *st = adap->priv;
2475 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe);
2476
2477 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL)
2478 return -ENODEV;
2479
2480 dib7000p_set_gpio(adap->fe, 8, 0, 1);
2481
2482 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
2483 adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2484 return 0;
2485}
2486
2487static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap)
2488{
2489 struct dib0700_adapter_state *st = adap->priv;
2490 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe);
2491
2492 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL)
2493 return -ENODEV;
2494
2495 dib7000p_set_gpio(adap->fe, 8, 0, 1);
2496
2497 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
2498 adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2499 return 0;
2500}
2501
2502/* STK7070PD */
2503static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
2504 {
2505 .output_mpeg2_in_188_bytes = 1,
2506
2507 .agc_config_count = 1,
2508 .agc = &dib7070_agc_config,
2509 .bw = &dib7070_bw_config_12_mhz,
2510 .tuner_is_baseband = 1,
2511 .spur_protect = 1,
2512
2513 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2514 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2515 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2516
2517 .hostbus_diversity = 1,
2518 }, {
2519 .output_mpeg2_in_188_bytes = 1,
2520
2521 .agc_config_count = 1,
2522 .agc = &dib7070_agc_config,
2523 .bw = &dib7070_bw_config_12_mhz,
2524 .tuner_is_baseband = 1,
2525 .spur_protect = 1,
2526
2527 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2528 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2529 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2530
2531 .hostbus_diversity = 1,
2532 }
2533};
2534
2535static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
2536{
2537 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2538 msleep(10);
2539 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2540 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2541 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2542 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2543
2544 dib0700_ctrl_clock(adap->dev, 72, 1);
2545
2546 msleep(10);
2547 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2548 msleep(10);
2549 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2550
2551 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
2552 stk7070pd_dib7000p_config) != 0) {
2553 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
2554 __func__);
2555 return -ENODEV;
2556 }
2557
2558 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
2559 return adap->fe == NULL ? -ENODEV : 0;
2560}
2561
2562static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
2563{
2564 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]);
2565 return adap->fe == NULL ? -ENODEV : 0;
2566}
2567
2568/* S5H1411 */
2569static struct s5h1411_config pinnacle_801e_config = {
2570 .output_mode = S5H1411_PARALLEL_OUTPUT,
2571 .gpio = S5H1411_GPIO_OFF,
2572 .mpeg_timing = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
2573 .qam_if = S5H1411_IF_44000,
2574 .vsb_if = S5H1411_IF_44000,
2575 .inversion = S5H1411_INVERSION_OFF,
2576 .status_mode = S5H1411_DEMODLOCKING
2577};
2578
2579/* Pinnacle PCTV HD Pro 801e GPIOs map:
2580 GPIO0 - currently unknown
2581 GPIO1 - xc5000 tuner reset
2582 GPIO2 - CX25843 sleep
2583 GPIO3 - currently unknown
2584 GPIO4 - currently unknown
2585 GPIO6 - currently unknown
2586 GPIO7 - currently unknown
2587 GPIO9 - currently unknown
2588 GPIO10 - CX25843 reset
2589 */
2590static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap)
2591{
2592 struct dib0700_state *st = adap->dev->priv;
2593
2594 /* Make use of the new i2c functions from FW 1.20 */
2595 st->fw_use_new_i2c_api = 1;
2596
2597 /* The s5h1411 requires the dib0700 to not be in master mode */
2598 st->disable_streaming_master_mode = 1;
2599
2600 /* All msleep values taken from Windows USB trace */
2601 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
2602 dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0);
2603 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2604 msleep(400);
2605 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2606 msleep(60);
2607 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2608 msleep(30);
2609 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2610 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2611 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2612 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2613 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 0);
2614 msleep(30);
2615
2616 /* Put the CX25843 to sleep for now since we're in digital mode */
2617 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
2618
2619 /* GPIOs are initialized, do the attach */
2620 adap->fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config,
2621 &adap->dev->i2c_adap);
2622 return adap->fe == NULL ? -ENODEV : 0;
2623}
2624
2625static int dib0700_xc5000_tuner_callback(void *priv, int component,
2626 int command, int arg)
2627{
2628 struct dvb_usb_adapter *adap = priv;
2629
2630 if (command == XC5000_TUNER_RESET) {
2631 /* Reset the tuner */
2632 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
2633 msleep(10);
2634 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
2635 msleep(10);
2636 } else {
2637 err("xc5000: unknown tuner callback command: %d\n", command);
2638 return -EINVAL;
2639 }
2640
2641 return 0;
2642}
2643
2644static struct xc5000_config s5h1411_xc5000_tunerconfig = {
2645 .i2c_address = 0x64,
2646 .if_khz = 5380,
2647};
2648
2649static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
2650{
2651 /* FIXME: generalize & move to common area */
2652 adap->fe->callback = dib0700_xc5000_tuner_callback;
2653
2654 return dvb_attach(xc5000_attach, adap->fe, &adap->dev->i2c_adap,
2655 &s5h1411_xc5000_tunerconfig)
2656 == NULL ? -ENODEV : 0;
2657}
2658
2659static int dib0700_xc4000_tuner_callback(void *priv, int component,
2660 int command, int arg)
2661{
2662 struct dvb_usb_adapter *adap = priv;
2663
2664 if (command == XC4000_TUNER_RESET) {
2665 /* Reset the tuner */
2666 dib7000p_set_gpio(adap->fe, 8, 0, 0);
2667 msleep(10);
2668 dib7000p_set_gpio(adap->fe, 8, 0, 1);
2669 } else {
2670 err("xc4000: unknown tuner callback command: %d\n", command);
2671 return -EINVAL;
2672 }
2673
2674 return 0;
2675}
2676
2677static struct dibx000_agc_config stk7700p_7000p_xc4000_agc_config = {
2678 .band_caps = BAND_UHF | BAND_VHF,
2679 .setup = 0x64,
2680 .inv_gain = 0x02c8,
2681 .time_stabiliz = 0x15,
2682 .alpha_level = 0x00,
2683 .thlock = 0x76,
2684 .wbd_inv = 0x01,
2685 .wbd_ref = 0x0b33,
2686 .wbd_sel = 0x00,
2687 .wbd_alpha = 0x02,
2688 .agc1_max = 0x00,
2689 .agc1_min = 0x00,
2690 .agc2_max = 0x9b26,
2691 .agc2_min = 0x26ca,
2692 .agc1_pt1 = 0x00,
2693 .agc1_pt2 = 0x00,
2694 .agc1_pt3 = 0x00,
2695 .agc1_slope1 = 0x00,
2696 .agc1_slope2 = 0x00,
2697 .agc2_pt1 = 0x00,
2698 .agc2_pt2 = 0x80,
2699 .agc2_slope1 = 0x1d,
2700 .agc2_slope2 = 0x1d,
2701 .alpha_mant = 0x11,
2702 .alpha_exp = 0x1b,
2703 .beta_mant = 0x17,
2704 .beta_exp = 0x33,
2705 .perform_agc_softsplit = 0x00,
2706};
2707
2708static struct dibx000_bandwidth_config stk7700p_xc4000_pll_config = {
2709 60000, 30000, /* internal, sampling */
2710 1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
2711 0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, */
2712 /* ADClkSrc, modulo */
2713 (3 << 14) | (1 << 12) | 524, /* sad_cfg: refsel, sel, freq_15k */
2714 39370534, /* ifreq */
2715 20452225, /* timf */
2716 30000000 /* xtal */
2717};
2718
2719/* FIXME: none of these inputs are validated yet */
2720static struct dib7000p_config pctv_340e_config = {
2721 .output_mpeg2_in_188_bytes = 1,
2722
2723 .agc_config_count = 1,
2724 .agc = &stk7700p_7000p_xc4000_agc_config,
2725 .bw = &stk7700p_xc4000_pll_config,
2726
2727 .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
2728 .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
2729 .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
2730};
2731
2732/* PCTV 340e GPIOs map:
2733 dib0700:
2734 GPIO2 - CX25843 sleep
2735 GPIO3 - CS5340 reset
2736 GPIO5 - IRD
2737 GPIO6 - Power Supply
2738 GPIO8 - LNA (1=off 0=on)
2739 GPIO10 - CX25843 reset
2740 dib7000:
2741 GPIO8 - xc4000 reset
2742 */
2743static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap)
2744{
2745 struct dib0700_state *st = adap->dev->priv;
2746
2747 /* Power Supply on */
2748 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
2749 msleep(50);
2750 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2751 msleep(100); /* Allow power supply to settle before probing */
2752
2753 /* cx25843 reset */
2754 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2755 msleep(1); /* cx25843 datasheet say 350us required */
2756 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2757
2758 /* LNA off for now */
2759 dib0700_set_gpio(adap->dev, GPIO8, GPIO_OUT, 1);
2760
2761 /* Put the CX25843 to sleep for now since we're in digital mode */
2762 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
2763
2764 /* FIXME: not verified yet */
2765 dib0700_ctrl_clock(adap->dev, 72, 1);
2766
2767 msleep(500);
2768
2769 if (dib7000pc_detection(&adap->dev->i2c_adap) == 0) {
2770 /* Demodulator not found for some reason? */
2771 return -ENODEV;
2772 }
2773
2774 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x12,
2775 &pctv_340e_config);
2776 st->is_dib7000pc = 1;
2777
2778 return adap->fe == NULL ? -ENODEV : 0;
2779}
2780
2781static struct xc4000_config dib7000p_xc4000_tunerconfig = {
2782 .i2c_address = 0x61,
2783 .default_pm = 1,
2784 .dvb_amplitude = 0,
2785 .set_smoothedcvbs = 0,
2786 .if_khz = 5400
2787};
2788
2789static int xc4000_tuner_attach(struct dvb_usb_adapter *adap)
2790{
2791 struct i2c_adapter *tun_i2c;
2792
2793 /* The xc4000 is not on the main i2c bus */
2794 tun_i2c = dib7000p_get_i2c_master(adap->fe,
2795 DIBX000_I2C_INTERFACE_TUNER, 1);
2796 if (tun_i2c == NULL) {
2797 printk(KERN_ERR "Could not reach tuner i2c bus\n");
2798 return 0;
2799 }
2800
2801 /* Setup the reset callback */
2802 adap->fe->callback = dib0700_xc4000_tuner_callback;
2803
2804 return dvb_attach(xc4000_attach, adap->fe, tun_i2c,
2805 &dib7000p_xc4000_tunerconfig)
2806 == NULL ? -ENODEV : 0;
2807}
2808
2809static struct lgdt3305_config hcw_lgdt3305_config = {
2810 .i2c_addr = 0x0e,
2811 .mpeg_mode = LGDT3305_MPEG_PARALLEL,
2812 .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
2813 .tpvalid_polarity = LGDT3305_TP_VALID_LOW,
2814 .deny_i2c_rptr = 0,
2815 .spectral_inversion = 1,
2816 .qam_if_khz = 6000,
2817 .vsb_if_khz = 6000,
2818 .usref_8vsb = 0x0500,
2819};
2820
2821static struct mxl5007t_config hcw_mxl5007t_config = {
2822 .xtal_freq_hz = MxL_XTAL_25_MHZ,
2823 .if_freq_hz = MxL_IF_6_MHZ,
2824 .invert_if = 1,
2825};
2826
2827/* TIGER-ATSC map:
2828 GPIO0 - LNA_CTR (H: LNA power enabled, L: LNA power disabled)
2829 GPIO1 - ANT_SEL (H: VPA, L: MCX)
2830 GPIO4 - SCL2
2831 GPIO6 - EN_TUNER
2832 GPIO7 - SDA2
2833 GPIO10 - DEM_RST
2834
2835 MXL is behind LG's i2c repeater. LG is on SCL2/SDA2 gpios on the DIB
2836 */
2837static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
2838{
2839 struct dib0700_state *st = adap->dev->priv;
2840
2841 /* Make use of the new i2c functions from FW 1.20 */
2842 st->fw_use_new_i2c_api = 1;
2843
2844 st->disable_streaming_master_mode = 1;
2845
2846 /* fe power enable */
2847 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
2848 msleep(30);
2849 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2850 msleep(30);
2851
2852 /* demod reset */
2853 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2854 msleep(30);
2855 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2856 msleep(30);
2857 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2858 msleep(30);
2859
2860 adap->fe = dvb_attach(lgdt3305_attach,
2861 &hcw_lgdt3305_config,
2862 &adap->dev->i2c_adap);
2863
2864 return adap->fe == NULL ? -ENODEV : 0;
2865}
2866
2867static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
2868{
2869 return dvb_attach(mxl5007t_attach, adap->fe,
2870 &adap->dev->i2c_adap, 0x60,
2871 &hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
2872}
2873
2874
2875/* DVB-USB and USB stuff follows */
2876struct usb_device_id dib0700_usb_id_table[] = {
2877/* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) },
2878 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P_PC) },
2879 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
2880 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
2881 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
2882/* 5 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
2883 { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500) },
2884 { USB_DEVICE(USB_VID_UNIWILL, USB_PID_UNIWILL_STK7700P) },
2885 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
2886 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
2887/* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
2888 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV2000E) },
2889 { USB_DEVICE(USB_VID_TERRATEC,
2890 USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
2891 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
2892 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700D) },
2893/* 15 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070P) },
2894 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
2895 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070PD) },
2896 { USB_DEVICE(USB_VID_PINNACLE,
2897 USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
2898 { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500_PC) },
2899/* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
2900 { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) },
2901 { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
2902 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) },
2903 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) },
2904/* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
2905 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
2906 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_USB_XE) },
2907 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_EXPRESSCARD_320CX) },
2908 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV72E) },
2909/* 30 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73E) },
2910 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_EC372S) },
2911 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
2912 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) },
2913 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
2914/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
2915 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
2916 { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U8000) },
2917 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700PH) },
2918 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) },
2919/* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) },
2920 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) },
2921 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
2922 { USB_DEVICE(USB_VID_TERRATEC,
2923 USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
2924 { USB_DEVICE(USB_VID_SONY, USB_PID_SONY_PLAYTV) },
2925/* 45 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_PD378S) },
2926 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) },
2927 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
2928 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) },
2929 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) },
2930/* 50 */{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_Dlx) },
2931 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_H) },
2932 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T3) },
2933 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T5) },
2934 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) },
2935/* 55 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) },
2936 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73A) },
2937 { USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV73ESE) },
2938 { USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV282E) },
2939 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7770P) },
2940/* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
2941 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) },
2942 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) },
2943 { USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x000, 0x3f00) },
2944 { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
2945/* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
2946 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
2947 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) },
2948 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DIVERSITY) },
2949 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090M) },
2950/* 70 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM8096MD) },
2951 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090MD) },
2952 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM7090) },
2953 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) },
2954 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) },
2955/* 75 */{ USB_DEVICE(USB_VID_MEDION, USB_PID_CREATIX_CTX1921) },
2956 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E) },
2957 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E_SE) },
2958 { 0 } /* Terminating entry */
2959};
2960MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
2961
2962#define DIB0700_DEFAULT_DEVICE_PROPERTIES \
2963 .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
2964 .usb_ctrl = DEVICE_SPECIFIC, \
2965 .firmware = "dvb-usb-dib0700-1.20.fw", \
2966 .download_firmware = dib0700_download_firmware, \
2967 .no_reconnect = 1, \
2968 .size_of_priv = sizeof(struct dib0700_state), \
2969 .i2c_algo = &dib0700_i2c_algo, \
2970 .identify_state = dib0700_identify_state
2971
2972#define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
2973 .streaming_ctrl = dib0700_streaming_ctrl, \
2974 .stream = { \
2975 .type = USB_BULK, \
2976 .count = 4, \
2977 .endpoint = ep, \
2978 .u = { \
2979 .bulk = { \
2980 .buffersize = 39480, \
2981 } \
2982 } \
2983 }
2984
2985struct dvb_usb_device_properties dib0700_devices[] = {
2986 {
2987 DIB0700_DEFAULT_DEVICE_PROPERTIES,
2988
2989 .num_adapters = 1,
2990 .adapter = {
2991 {
2992 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
2993 .pid_filter_count = 32,
2994 .pid_filter = stk7700p_pid_filter,
2995 .pid_filter_ctrl = stk7700p_pid_filter_ctrl,
2996 .frontend_attach = stk7700p_frontend_attach,
2997 .tuner_attach = stk7700p_tuner_attach,
2998
2999 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3000 },
3001 },
3002
3003 .num_device_descs = 8,
3004 .devices = {
3005 { "DiBcom STK7700P reference design",
3006 { &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
3007 { NULL },
3008 },
3009 { "Hauppauge Nova-T Stick",
3010 { &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL },
3011 { NULL },
3012 },
3013 { "AVerMedia AVerTV DVB-T Volar",
3014 { &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] },
3015 { NULL },
3016 },
3017 { "Compro Videomate U500",
3018 { &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] },
3019 { NULL },
3020 },
3021 { "Uniwill STK7700P based (Hama and others)",
3022 { &dib0700_usb_id_table[7], NULL },
3023 { NULL },
3024 },
3025 { "Leadtek Winfast DTV Dongle (STK7700P based)",
3026 { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
3027 { NULL },
3028 },
3029 { "AVerMedia AVerTV DVB-T Express",
3030 { &dib0700_usb_id_table[20] },
3031 { NULL },
3032 },
3033 { "Gigabyte U7000",
3034 { &dib0700_usb_id_table[21], NULL },
3035 { NULL },
3036 }
3037 },
3038
3039 .rc.core = {
3040 .rc_interval = DEFAULT_RC_INTERVAL,
3041 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3042 .rc_query = dib0700_rc_query_old_firmware,
3043 .allowed_protos = RC_TYPE_RC5 |
3044 RC_TYPE_RC6 |
3045 RC_TYPE_NEC,
3046 .change_protocol = dib0700_change_protocol,
3047 },
3048 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3049
3050 .num_adapters = 2,
3051 .adapter = {
3052 {
3053 .frontend_attach = bristol_frontend_attach,
3054 .tuner_attach = bristol_tuner_attach,
3055
3056 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3057 }, {
3058 .frontend_attach = bristol_frontend_attach,
3059 .tuner_attach = bristol_tuner_attach,
3060
3061 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
3062 }
3063 },
3064
3065 .num_device_descs = 1,
3066 .devices = {
3067 { "Hauppauge Nova-T 500 Dual DVB-T",
3068 { &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL },
3069 { NULL },
3070 },
3071 },
3072
3073 .rc.core = {
3074 .rc_interval = DEFAULT_RC_INTERVAL,
3075 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3076 .rc_query = dib0700_rc_query_old_firmware,
3077 .allowed_protos = RC_TYPE_RC5 |
3078 RC_TYPE_RC6 |
3079 RC_TYPE_NEC,
3080 .change_protocol = dib0700_change_protocol,
3081 },
3082 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3083
3084 .num_adapters = 2,
3085 .adapter = {
3086 {
3087 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3088 .pid_filter_count = 32,
3089 .pid_filter = stk70x0p_pid_filter,
3090 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3091 .frontend_attach = stk7700d_frontend_attach,
3092 .tuner_attach = stk7700d_tuner_attach,
3093
3094 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3095 }, {
3096 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3097 .pid_filter_count = 32,
3098 .pid_filter = stk70x0p_pid_filter,
3099 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3100 .frontend_attach = stk7700d_frontend_attach,
3101 .tuner_attach = stk7700d_tuner_attach,
3102
3103 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
3104 }
3105 },
3106
3107 .num_device_descs = 5,
3108 .devices = {
3109 { "Pinnacle PCTV 2000e",
3110 { &dib0700_usb_id_table[11], NULL },
3111 { NULL },
3112 },
3113 { "Terratec Cinergy DT XS Diversity",
3114 { &dib0700_usb_id_table[12], NULL },
3115 { NULL },
3116 },
3117 { "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity",
3118 { &dib0700_usb_id_table[13], NULL },
3119 { NULL },
3120 },
3121 { "DiBcom STK7700D reference design",
3122 { &dib0700_usb_id_table[14], NULL },
3123 { NULL },
3124 },
3125 { "YUAN High-Tech DiBcom STK7700D",
3126 { &dib0700_usb_id_table[55], NULL },
3127 { NULL },
3128 },
3129
3130 },
3131
3132 .rc.core = {
3133 .rc_interval = DEFAULT_RC_INTERVAL,
3134 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3135 .rc_query = dib0700_rc_query_old_firmware,
3136 .allowed_protos = RC_TYPE_RC5 |
3137 RC_TYPE_RC6 |
3138 RC_TYPE_NEC,
3139 .change_protocol = dib0700_change_protocol,
3140 },
3141 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3142
3143 .num_adapters = 1,
3144 .adapter = {
3145 {
3146 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3147 .pid_filter_count = 32,
3148 .pid_filter = stk70x0p_pid_filter,
3149 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3150 .frontend_attach = stk7700P2_frontend_attach,
3151 .tuner_attach = stk7700d_tuner_attach,
3152
3153 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3154 },
3155 },
3156
3157 .num_device_descs = 3,
3158 .devices = {
3159 { "ASUS My Cinema U3000 Mini DVBT Tuner",
3160 { &dib0700_usb_id_table[23], NULL },
3161 { NULL },
3162 },
3163 { "Yuan EC372S",
3164 { &dib0700_usb_id_table[31], NULL },
3165 { NULL },
3166 },
3167 { "Terratec Cinergy T Express",
3168 { &dib0700_usb_id_table[42], NULL },
3169 { NULL },
3170 }
3171 },
3172
3173 .rc.core = {
3174 .rc_interval = DEFAULT_RC_INTERVAL,
3175 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3176 .module_name = "dib0700",
3177 .rc_query = dib0700_rc_query_old_firmware,
3178 .allowed_protos = RC_TYPE_RC5 |
3179 RC_TYPE_RC6 |
3180 RC_TYPE_NEC,
3181 .change_protocol = dib0700_change_protocol,
3182 },
3183 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3184
3185 .num_adapters = 1,
3186 .adapter = {
3187 {
3188 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3189 .pid_filter_count = 32,
3190 .pid_filter = stk70x0p_pid_filter,
3191 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3192 .frontend_attach = stk7070p_frontend_attach,
3193 .tuner_attach = dib7070p_tuner_attach,
3194
3195 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3196
3197 .size_of_priv = sizeof(struct dib0700_adapter_state),
3198 },
3199 },
3200
3201 .num_device_descs = 11,
3202 .devices = {
3203 { "DiBcom STK7070P reference design",
3204 { &dib0700_usb_id_table[15], NULL },
3205 { NULL },
3206 },
3207 { "Pinnacle PCTV DVB-T Flash Stick",
3208 { &dib0700_usb_id_table[16], NULL },
3209 { NULL },
3210 },
3211 { "Artec T14BR DVB-T",
3212 { &dib0700_usb_id_table[22], NULL },
3213 { NULL },
3214 },
3215 { "ASUS My Cinema U3100 Mini DVBT Tuner",
3216 { &dib0700_usb_id_table[24], NULL },
3217 { NULL },
3218 },
3219 { "Hauppauge Nova-T Stick",
3220 { &dib0700_usb_id_table[25], NULL },
3221 { NULL },
3222 },
3223 { "Hauppauge Nova-T MyTV.t",
3224 { &dib0700_usb_id_table[26], NULL },
3225 { NULL },
3226 },
3227 { "Pinnacle PCTV 72e",
3228 { &dib0700_usb_id_table[29], NULL },
3229 { NULL },
3230 },
3231 { "Pinnacle PCTV 73e",
3232 { &dib0700_usb_id_table[30], NULL },
3233 { NULL },
3234 },
3235 { "Elgato EyeTV DTT",
3236 { &dib0700_usb_id_table[49], NULL },
3237 { NULL },
3238 },
3239 { "Yuan PD378S",
3240 { &dib0700_usb_id_table[45], NULL },
3241 { NULL },
3242 },
3243 { "Elgato EyeTV Dtt Dlx PD378S",
3244 { &dib0700_usb_id_table[50], NULL },
3245 { NULL },
3246 },
3247 },
3248
3249 .rc.core = {
3250 .rc_interval = DEFAULT_RC_INTERVAL,
3251 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3252 .module_name = "dib0700",
3253 .rc_query = dib0700_rc_query_old_firmware,
3254 .allowed_protos = RC_TYPE_RC5 |
3255 RC_TYPE_RC6 |
3256 RC_TYPE_NEC,
3257 .change_protocol = dib0700_change_protocol,
3258 },
3259 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3260
3261 .num_adapters = 1,
3262 .adapter = {
3263 {
3264 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3265 .pid_filter_count = 32,
3266 .pid_filter = stk70x0p_pid_filter,
3267 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3268 .frontend_attach = stk7070p_frontend_attach,
3269 .tuner_attach = dib7070p_tuner_attach,
3270
3271 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3272
3273 .size_of_priv = sizeof(struct dib0700_adapter_state),
3274 },
3275 },
3276
3277 .num_device_descs = 3,
3278 .devices = {
3279 { "Pinnacle PCTV 73A",
3280 { &dib0700_usb_id_table[56], NULL },
3281 { NULL },
3282 },
3283 { "Pinnacle PCTV 73e SE",
3284 { &dib0700_usb_id_table[57], &dib0700_usb_id_table[65], NULL },
3285 { NULL },
3286 },
3287 { "Pinnacle PCTV 282e",
3288 { &dib0700_usb_id_table[58], &dib0700_usb_id_table[66], NULL },
3289 { NULL },
3290 },
3291 },
3292
3293 .rc.core = {
3294 .rc_interval = DEFAULT_RC_INTERVAL,
3295 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3296 .module_name = "dib0700",
3297 .rc_query = dib0700_rc_query_old_firmware,
3298 .allowed_protos = RC_TYPE_RC5 |
3299 RC_TYPE_RC6 |
3300 RC_TYPE_NEC,
3301 .change_protocol = dib0700_change_protocol,
3302 },
3303 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3304
3305 .num_adapters = 2,
3306 .adapter = {
3307 {
3308 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3309 .pid_filter_count = 32,
3310 .pid_filter = stk70x0p_pid_filter,
3311 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3312 .frontend_attach = stk7070pd_frontend_attach0,
3313 .tuner_attach = dib7070p_tuner_attach,
3314
3315 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3316
3317 .size_of_priv = sizeof(struct dib0700_adapter_state),
3318 }, {
3319 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3320 .pid_filter_count = 32,
3321 .pid_filter = stk70x0p_pid_filter,
3322 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3323 .frontend_attach = stk7070pd_frontend_attach1,
3324 .tuner_attach = dib7070p_tuner_attach,
3325
3326 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
3327
3328 .size_of_priv = sizeof(struct dib0700_adapter_state),
3329 }
3330 },
3331
3332 .num_device_descs = 6,
3333 .devices = {
3334 { "DiBcom STK7070PD reference design",
3335 { &dib0700_usb_id_table[17], NULL },
3336 { NULL },
3337 },
3338 { "Pinnacle PCTV Dual DVB-T Diversity Stick",
3339 { &dib0700_usb_id_table[18], NULL },
3340 { NULL },
3341 },
3342 { "Hauppauge Nova-TD Stick (52009)",
3343 { &dib0700_usb_id_table[35], NULL },
3344 { NULL },
3345 },
3346 { "Hauppauge Nova-TD-500 (84xxx)",
3347 { &dib0700_usb_id_table[36], NULL },
3348 { NULL },
3349 },
3350 { "Terratec Cinergy DT USB XS Diversity/ T5",
3351 { &dib0700_usb_id_table[43],
3352 &dib0700_usb_id_table[53], NULL},
3353 { NULL },
3354 },
3355 { "Sony PlayTV",
3356 { &dib0700_usb_id_table[44], NULL },
3357 { NULL },
3358 },
3359 },
3360
3361 .rc.core = {
3362 .rc_interval = DEFAULT_RC_INTERVAL,
3363 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3364 .module_name = "dib0700",
3365 .rc_query = dib0700_rc_query_old_firmware,
3366 .allowed_protos = RC_TYPE_RC5 |
3367 RC_TYPE_RC6 |
3368 RC_TYPE_NEC,
3369 .change_protocol = dib0700_change_protocol,
3370 },
3371 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3372
3373 .num_adapters = 2,
3374 .adapter = {
3375 {
3376 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3377 .pid_filter_count = 32,
3378 .pid_filter = stk70x0p_pid_filter,
3379 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3380 .frontend_attach = stk7070pd_frontend_attach0,
3381 .tuner_attach = dib7070p_tuner_attach,
3382
3383 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3384
3385 .size_of_priv = sizeof(struct dib0700_adapter_state),
3386 }, {
3387 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3388 .pid_filter_count = 32,
3389 .pid_filter = stk70x0p_pid_filter,
3390 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3391 .frontend_attach = stk7070pd_frontend_attach1,
3392 .tuner_attach = dib7070p_tuner_attach,
3393
3394 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
3395
3396 .size_of_priv = sizeof(struct dib0700_adapter_state),
3397 }
3398 },
3399
3400 .num_device_descs = 1,
3401 .devices = {
3402 { "Elgato EyeTV Diversity",
3403 { &dib0700_usb_id_table[68], NULL },
3404 { NULL },
3405 },
3406 },
3407
3408 .rc.core = {
3409 .rc_interval = DEFAULT_RC_INTERVAL,
3410 .rc_codes = RC_MAP_DIB0700_NEC_TABLE,
3411 .module_name = "dib0700",
3412 .rc_query = dib0700_rc_query_old_firmware,
3413 .allowed_protos = RC_TYPE_RC5 |
3414 RC_TYPE_RC6 |
3415 RC_TYPE_NEC,
3416 .change_protocol = dib0700_change_protocol,
3417 },
3418 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3419
3420 .num_adapters = 1,
3421 .adapter = {
3422 {
3423 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3424 .pid_filter_count = 32,
3425 .pid_filter = stk70x0p_pid_filter,
3426 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3427 .frontend_attach = stk7700ph_frontend_attach,
3428 .tuner_attach = stk7700ph_tuner_attach,
3429
3430 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3431
3432 .size_of_priv = sizeof(struct
3433 dib0700_adapter_state),
3434 },
3435 },
3436
3437 .num_device_descs = 9,
3438 .devices = {
3439 { "Terratec Cinergy HT USB XE",
3440 { &dib0700_usb_id_table[27], NULL },
3441 { NULL },
3442 },
3443 { "Pinnacle Expresscard 320cx",
3444 { &dib0700_usb_id_table[28], NULL },
3445 { NULL },
3446 },
3447 { "Terratec Cinergy HT Express",
3448 { &dib0700_usb_id_table[32], NULL },
3449 { NULL },
3450 },
3451 { "Gigabyte U8000-RH",
3452 { &dib0700_usb_id_table[37], NULL },
3453 { NULL },
3454 },
3455 { "YUAN High-Tech STK7700PH",
3456 { &dib0700_usb_id_table[38], NULL },
3457 { NULL },
3458 },
3459 { "Asus My Cinema-U3000Hybrid",
3460 { &dib0700_usb_id_table[39], NULL },
3461 { NULL },
3462 },
3463 { "YUAN High-Tech MC770",
3464 { &dib0700_usb_id_table[48], NULL },
3465 { NULL },
3466 },
3467 { "Leadtek WinFast DTV Dongle H",
3468 { &dib0700_usb_id_table[51], NULL },
3469 { NULL },
3470 },
3471 { "YUAN High-Tech STK7700D",
3472 { &dib0700_usb_id_table[54], NULL },
3473 { NULL },
3474 },
3475 },
3476
3477 .rc.core = {
3478 .rc_interval = DEFAULT_RC_INTERVAL,
3479 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3480 .module_name = "dib0700",
3481 .rc_query = dib0700_rc_query_old_firmware,
3482 .allowed_protos = RC_TYPE_RC5 |
3483 RC_TYPE_RC6 |
3484 RC_TYPE_NEC,
3485 .change_protocol = dib0700_change_protocol,
3486 },
3487 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3488 .num_adapters = 1,
3489 .adapter = {
3490 {
3491 .frontend_attach = s5h1411_frontend_attach,
3492 .tuner_attach = xc5000_tuner_attach,
3493
3494 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3495
3496 .size_of_priv = sizeof(struct
3497 dib0700_adapter_state),
3498 },
3499 },
3500
3501 .num_device_descs = 2,
3502 .devices = {
3503 { "Pinnacle PCTV HD Pro USB Stick",
3504 { &dib0700_usb_id_table[40], NULL },
3505 { NULL },
3506 },
3507 { "Pinnacle PCTV HD USB Stick",
3508 { &dib0700_usb_id_table[41], NULL },
3509 { NULL },
3510 },
3511 },
3512
3513 .rc.core = {
3514 .rc_interval = DEFAULT_RC_INTERVAL,
3515 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3516 .module_name = "dib0700",
3517 .rc_query = dib0700_rc_query_old_firmware,
3518 .allowed_protos = RC_TYPE_RC5 |
3519 RC_TYPE_RC6 |
3520 RC_TYPE_NEC,
3521 .change_protocol = dib0700_change_protocol,
3522 },
3523 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3524 .num_adapters = 1,
3525 .adapter = {
3526 {
3527 .frontend_attach = lgdt3305_frontend_attach,
3528 .tuner_attach = mxl5007t_tuner_attach,
3529
3530 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3531
3532 .size_of_priv = sizeof(struct
3533 dib0700_adapter_state),
3534 },
3535 },
3536
3537 .num_device_descs = 2,
3538 .devices = {
3539 { "Hauppauge ATSC MiniCard (B200)",
3540 { &dib0700_usb_id_table[46], NULL },
3541 { NULL },
3542 },
3543 { "Hauppauge ATSC MiniCard (B210)",
3544 { &dib0700_usb_id_table[47], NULL },
3545 { NULL },
3546 },
3547 },
3548 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3549
3550 .num_adapters = 1,
3551 .adapter = {
3552 {
3553 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3554 .pid_filter_count = 32,
3555 .pid_filter = stk70x0p_pid_filter,
3556 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3557 .frontend_attach = stk7770p_frontend_attach,
3558 .tuner_attach = dib7770p_tuner_attach,
3559
3560 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3561
3562 .size_of_priv =
3563 sizeof(struct dib0700_adapter_state),
3564 },
3565 },
3566
3567 .num_device_descs = 4,
3568 .devices = {
3569 { "DiBcom STK7770P reference design",
3570 { &dib0700_usb_id_table[59], NULL },
3571 { NULL },
3572 },
3573 { "Terratec Cinergy T USB XXS (HD)/ T3",
3574 { &dib0700_usb_id_table[33],
3575 &dib0700_usb_id_table[52],
3576 &dib0700_usb_id_table[60], NULL},
3577 { NULL },
3578 },
3579 { "TechniSat AirStar TeleStick 2",
3580 { &dib0700_usb_id_table[74], NULL },
3581 { NULL },
3582 },
3583 { "Medion CTX1921 DVB-T USB",
3584 { &dib0700_usb_id_table[75], NULL },
3585 { NULL },
3586 },
3587 },
3588
3589 .rc.core = {
3590 .rc_interval = DEFAULT_RC_INTERVAL,
3591 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3592 .module_name = "dib0700",
3593 .rc_query = dib0700_rc_query_old_firmware,
3594 .allowed_protos = RC_TYPE_RC5 |
3595 RC_TYPE_RC6 |
3596 RC_TYPE_NEC,
3597 .change_protocol = dib0700_change_protocol,
3598 },
3599 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3600 .num_adapters = 1,
3601 .adapter = {
3602 {
3603 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3604 .pid_filter_count = 32,
3605 .pid_filter = stk80xx_pid_filter,
3606 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
3607 .frontend_attach = stk807x_frontend_attach,
3608 .tuner_attach = dib807x_tuner_attach,
3609
3610 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3611
3612 .size_of_priv =
3613 sizeof(struct dib0700_adapter_state),
3614 },
3615 },
3616
3617 .num_device_descs = 3,
3618 .devices = {
3619 { "DiBcom STK807xP reference design",
3620 { &dib0700_usb_id_table[62], NULL },
3621 { NULL },
3622 },
3623 { "Prolink Pixelview SBTVD",
3624 { &dib0700_usb_id_table[63], NULL },
3625 { NULL },
3626 },
3627 { "EvolutePC TVWay+",
3628 { &dib0700_usb_id_table[64], NULL },
3629 { NULL },
3630 },
3631 },
3632
3633 .rc.core = {
3634 .rc_interval = DEFAULT_RC_INTERVAL,
3635 .rc_codes = RC_MAP_DIB0700_NEC_TABLE,
3636 .module_name = "dib0700",
3637 .rc_query = dib0700_rc_query_old_firmware,
3638 .allowed_protos = RC_TYPE_RC5 |
3639 RC_TYPE_RC6 |
3640 RC_TYPE_NEC,
3641 .change_protocol = dib0700_change_protocol,
3642 },
3643 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3644 .num_adapters = 2,
3645 .adapter = {
3646 {
3647 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3648 .pid_filter_count = 32,
3649 .pid_filter = stk80xx_pid_filter,
3650 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
3651 .frontend_attach = stk807xpvr_frontend_attach0,
3652 .tuner_attach = dib807x_tuner_attach,
3653
3654 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3655
3656 .size_of_priv =
3657 sizeof(struct dib0700_adapter_state),
3658 },
3659 {
3660 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3661 .pid_filter_count = 32,
3662 .pid_filter = stk80xx_pid_filter,
3663 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
3664 .frontend_attach = stk807xpvr_frontend_attach1,
3665 .tuner_attach = dib807x_tuner_attach,
3666
3667 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
3668
3669 .size_of_priv =
3670 sizeof(struct dib0700_adapter_state),
3671 },
3672 },
3673
3674 .num_device_descs = 1,
3675 .devices = {
3676 { "DiBcom STK807xPVR reference design",
3677 { &dib0700_usb_id_table[61], NULL },
3678 { NULL },
3679 },
3680 },
3681
3682 .rc.core = {
3683 .rc_interval = DEFAULT_RC_INTERVAL,
3684 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3685 .module_name = "dib0700",
3686 .rc_query = dib0700_rc_query_old_firmware,
3687 .allowed_protos = RC_TYPE_RC5 |
3688 RC_TYPE_RC6 |
3689 RC_TYPE_NEC,
3690 .change_protocol = dib0700_change_protocol,
3691 },
3692 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3693 .num_adapters = 1,
3694 .adapter = {
3695 {
3696 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3697 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3698 .pid_filter_count = 32,
3699 .pid_filter = stk80xx_pid_filter,
3700 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
3701 .frontend_attach = stk809x_frontend_attach,
3702 .tuner_attach = dib809x_tuner_attach,
3703
3704 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3705
3706 .size_of_priv =
3707 sizeof(struct dib0700_adapter_state),
3708 },
3709 },
3710
3711 .num_device_descs = 1,
3712 .devices = {
3713 { "DiBcom STK8096GP reference design",
3714 { &dib0700_usb_id_table[67], NULL },
3715 { NULL },
3716 },
3717 },
3718
3719 .rc.core = {
3720 .rc_interval = DEFAULT_RC_INTERVAL,
3721 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3722 .module_name = "dib0700",
3723 .rc_query = dib0700_rc_query_old_firmware,
3724 .allowed_protos = RC_TYPE_RC5 |
3725 RC_TYPE_RC6 |
3726 RC_TYPE_NEC,
3727 .change_protocol = dib0700_change_protocol,
3728 },
3729 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3730 .num_adapters = 1,
3731 .adapter = {
3732 {
3733 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3734 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3735 .pid_filter_count = 32,
3736 .pid_filter = dib90x0_pid_filter,
3737 .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
3738 .frontend_attach = stk9090m_frontend_attach,
3739 .tuner_attach = dib9090_tuner_attach,
3740
3741 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3742
3743 .size_of_priv =
3744 sizeof(struct dib0700_adapter_state),
3745 },
3746 },
3747
3748 .num_device_descs = 1,
3749 .devices = {
3750 { "DiBcom STK9090M reference design",
3751 { &dib0700_usb_id_table[69], NULL },
3752 { NULL },
3753 },
3754 },
3755
3756 .rc.core = {
3757 .rc_interval = DEFAULT_RC_INTERVAL,
3758 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3759 .module_name = "dib0700",
3760 .rc_query = dib0700_rc_query_old_firmware,
3761 .allowed_protos = RC_TYPE_RC5 |
3762 RC_TYPE_RC6 |
3763 RC_TYPE_NEC,
3764 .change_protocol = dib0700_change_protocol,
3765 },
3766 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3767 .num_adapters = 1,
3768 .adapter = {
3769 {
3770 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3771 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3772 .pid_filter_count = 32,
3773 .pid_filter = stk80xx_pid_filter,
3774 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
3775 .frontend_attach = nim8096md_frontend_attach,
3776 .tuner_attach = nim8096md_tuner_attach,
3777
3778 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3779
3780 .size_of_priv =
3781 sizeof(struct dib0700_adapter_state),
3782 },
3783 },
3784
3785 .num_device_descs = 1,
3786 .devices = {
3787 { "DiBcom NIM8096MD reference design",
3788 { &dib0700_usb_id_table[70], NULL },
3789 { NULL },
3790 },
3791 },
3792
3793 .rc.core = {
3794 .rc_interval = DEFAULT_RC_INTERVAL,
3795 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3796 .module_name = "dib0700",
3797 .rc_query = dib0700_rc_query_old_firmware,
3798 .allowed_protos = RC_TYPE_RC5 |
3799 RC_TYPE_RC6 |
3800 RC_TYPE_NEC,
3801 .change_protocol = dib0700_change_protocol,
3802 },
3803 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3804 .num_adapters = 1,
3805 .adapter = {
3806 {
3807 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3808 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3809 .pid_filter_count = 32,
3810 .pid_filter = dib90x0_pid_filter,
3811 .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
3812 .frontend_attach = nim9090md_frontend_attach,
3813 .tuner_attach = nim9090md_tuner_attach,
3814
3815 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3816
3817 .size_of_priv =
3818 sizeof(struct dib0700_adapter_state),
3819 },
3820 },
3821
3822 .num_device_descs = 1,
3823 .devices = {
3824 { "DiBcom NIM9090MD reference design",
3825 { &dib0700_usb_id_table[71], NULL },
3826 { NULL },
3827 },
3828 },
3829
3830 .rc.core = {
3831 .rc_interval = DEFAULT_RC_INTERVAL,
3832 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3833 .module_name = "dib0700",
3834 .rc_query = dib0700_rc_query_old_firmware,
3835 .allowed_protos = RC_TYPE_RC5 |
3836 RC_TYPE_RC6 |
3837 RC_TYPE_NEC,
3838 .change_protocol = dib0700_change_protocol,
3839 },
3840 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3841 .num_adapters = 1,
3842 .adapter = {
3843 {
3844 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3845 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3846 .pid_filter_count = 32,
3847 .pid_filter = stk70x0p_pid_filter,
3848 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3849 .frontend_attach = nim7090_frontend_attach,
3850 .tuner_attach = nim7090_tuner_attach,
3851
3852 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3853
3854 .size_of_priv =
3855 sizeof(struct dib0700_adapter_state),
3856 },
3857 },
3858
3859 .num_device_descs = 1,
3860 .devices = {
3861 { "DiBcom NIM7090 reference design",
3862 { &dib0700_usb_id_table[72], NULL },
3863 { NULL },
3864 },
3865 },
3866
3867 .rc.core = {
3868 .rc_interval = DEFAULT_RC_INTERVAL,
3869 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3870 .module_name = "dib0700",
3871 .rc_query = dib0700_rc_query_old_firmware,
3872 .allowed_protos = RC_TYPE_RC5 |
3873 RC_TYPE_RC6 |
3874 RC_TYPE_NEC,
3875 .change_protocol = dib0700_change_protocol,
3876 },
3877 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3878 .num_adapters = 2,
3879 .adapter = {
3880 {
3881 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3882 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3883 .pid_filter_count = 32,
3884 .pid_filter = stk70x0p_pid_filter,
3885 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3886 .frontend_attach = tfe7090pvr_frontend0_attach,
3887 .tuner_attach = tfe7090pvr_tuner0_attach,
3888
3889 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
3890
3891 .size_of_priv =
3892 sizeof(struct dib0700_adapter_state),
3893 },
3894 {
3895 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3896 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3897 .pid_filter_count = 32,
3898 .pid_filter = stk70x0p_pid_filter,
3899 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3900 .frontend_attach = tfe7090pvr_frontend1_attach,
3901 .tuner_attach = tfe7090pvr_tuner1_attach,
3902
3903 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3904
3905 .size_of_priv =
3906 sizeof(struct dib0700_adapter_state),
3907 },
3908 },
3909
3910 .num_device_descs = 1,
3911 .devices = {
3912 { "DiBcom TFE7090PVR reference design",
3913 { &dib0700_usb_id_table[73], NULL },
3914 { NULL },
3915 },
3916 },
3917
3918 .rc.core = {
3919 .rc_interval = DEFAULT_RC_INTERVAL,
3920 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3921 .module_name = "dib0700",
3922 .rc_query = dib0700_rc_query_old_firmware,
3923 .allowed_protos = RC_TYPE_RC5 |
3924 RC_TYPE_RC6 |
3925 RC_TYPE_NEC,
3926 .change_protocol = dib0700_change_protocol,
3927 },
3928 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3929 .num_adapters = 1,
3930 .adapter = {
3931 {
3932 .frontend_attach = pctv340e_frontend_attach,
3933 .tuner_attach = xc4000_tuner_attach,
3934
3935 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3936
3937 .size_of_priv = sizeof(struct
3938 dib0700_adapter_state),
3939 },
3940 },
3941
3942 .num_device_descs = 2,
3943 .devices = {
3944 { "Pinnacle PCTV 340e HD Pro USB Stick",
3945 { &dib0700_usb_id_table[76], NULL },
3946 { NULL },
3947 },
3948 { "Pinnacle PCTV Hybrid Stick Solo",
3949 { &dib0700_usb_id_table[77], NULL },
3950 { NULL },
3951 },
3952 },
3953 .rc.core = {
3954 .rc_interval = DEFAULT_RC_INTERVAL,
3955 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3956 .module_name = "dib0700",
3957 .rc_query = dib0700_rc_query_old_firmware,
3958 .allowed_protos = RC_TYPE_RC5 |
3959 RC_TYPE_RC6 |
3960 RC_TYPE_NEC,
3961 .change_protocol = dib0700_change_protocol,
3962 },
3963 },
3964};
3965
3966int dib0700_device_count = ARRAY_SIZE(dib0700_devices);
diff --git a/drivers/media/dvb/dvb-usb/dib07x0.h b/drivers/media/dvb/dvb-usb/dib07x0.h
new file mode 100644
index 00000000000..7e62c101852
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dib07x0.h
@@ -0,0 +1,21 @@
1#ifndef _DIB07X0_H_
2#define _DIB07X0_H_
3
4enum dib07x0_gpios {
5 GPIO0 = 0,
6 GPIO1 = 2,
7 GPIO2 = 3,
8 GPIO3 = 4,
9 GPIO4 = 5,
10 GPIO5 = 6,
11 GPIO6 = 8,
12 GPIO7 = 10,
13 GPIO8 = 11,
14 GPIO9 = 14,
15 GPIO10 = 15,
16};
17
18#define GPIO_IN 0
19#define GPIO_OUT 1
20
21#endif
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
new file mode 100644
index 00000000000..4c2a689c820
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -0,0 +1,470 @@
1/* Common methods for dibusb-based-receivers.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation, version 2.
8 *
9 * see Documentation/dvb/README.dvb-usb for more information
10 */
11#include "dibusb.h"
12
13static int debug;
14module_param(debug, int, 0644);
15MODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS);
16MODULE_LICENSE("GPL");
17
18#define deb_info(args...) dprintk(debug,0x01,args)
19
20/* common stuff used by the different dibusb modules */
21int dibusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
22{
23 if (adap->priv != NULL) {
24 struct dibusb_state *st = adap->priv;
25 if (st->ops.fifo_ctrl != NULL)
26 if (st->ops.fifo_ctrl(adap->fe,onoff)) {
27 err("error while controlling the fifo of the demod.");
28 return -ENODEV;
29 }
30 }
31 return 0;
32}
33EXPORT_SYMBOL(dibusb_streaming_ctrl);
34
35int dibusb_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
36{
37 if (adap->priv != NULL) {
38 struct dibusb_state *st = adap->priv;
39 if (st->ops.pid_ctrl != NULL)
40 st->ops.pid_ctrl(adap->fe,index,pid,onoff);
41 }
42 return 0;
43}
44EXPORT_SYMBOL(dibusb_pid_filter);
45
46int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
47{
48 if (adap->priv != NULL) {
49 struct dibusb_state *st = adap->priv;
50 if (st->ops.pid_parse != NULL)
51 if (st->ops.pid_parse(adap->fe,onoff) < 0)
52 err("could not handle pid_parser");
53 }
54 return 0;
55}
56EXPORT_SYMBOL(dibusb_pid_filter_ctrl);
57
58int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff)
59{
60 u8 b[3];
61 int ret;
62 b[0] = DIBUSB_REQ_SET_IOCTL;
63 b[1] = DIBUSB_IOCTL_CMD_POWER_MODE;
64 b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP;
65 ret = dvb_usb_generic_write(d,b,3);
66 msleep(10);
67 return ret;
68}
69EXPORT_SYMBOL(dibusb_power_ctrl);
70
71int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
72{
73 u8 b[3] = { 0 };
74 int ret;
75
76 if ((ret = dibusb_streaming_ctrl(adap,onoff)) < 0)
77 return ret;
78
79 if (onoff) {
80 b[0] = DIBUSB_REQ_SET_STREAMING_MODE;
81 b[1] = 0x00;
82 if ((ret = dvb_usb_generic_write(adap->dev,b,2)) < 0)
83 return ret;
84 }
85
86 b[0] = DIBUSB_REQ_SET_IOCTL;
87 b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
88 return dvb_usb_generic_write(adap->dev,b,3);
89}
90EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
91
92int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff)
93{
94 if (onoff) {
95 u8 b[3] = { DIBUSB_REQ_SET_IOCTL, DIBUSB_IOCTL_CMD_POWER_MODE, DIBUSB_IOCTL_POWER_WAKEUP };
96 return dvb_usb_generic_write(d,b,3);
97 } else
98 return 0;
99}
100EXPORT_SYMBOL(dibusb2_0_power_ctrl);
101
102static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr,
103 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
104{
105 u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
106 /* write only ? */
107 int wo = (rbuf == NULL || rlen == 0),
108 len = 2 + wlen + (wo ? 0 : 2);
109
110 sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
111 sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
112
113 memcpy(&sndbuf[2],wbuf,wlen);
114
115 if (!wo) {
116 sndbuf[wlen+2] = (rlen >> 8) & 0xff;
117 sndbuf[wlen+3] = rlen & 0xff;
118 }
119
120 return dvb_usb_generic_rw(d,sndbuf,len,rbuf,rlen,0);
121}
122
123/*
124 * I2C master xfer function
125 */
126static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
127{
128 struct dvb_usb_device *d = i2c_get_adapdata(adap);
129 int i;
130
131 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
132 return -EAGAIN;
133
134 for (i = 0; i < num; i++) {
135 /* write/read request */
136 if (i+1 < num && (msg[i].flags & I2C_M_RD) == 0
137 && (msg[i+1].flags & I2C_M_RD)) {
138 if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,
139 msg[i+1].buf,msg[i+1].len) < 0)
140 break;
141 i++;
142 } else if ((msg[i].flags & I2C_M_RD) == 0) {
143 if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
144 break;
145 } else if (msg[i].addr != 0x50) {
146 /* 0x50 is the address of the eeprom - we need to protect it
147 * from dibusb's bad i2c implementation: reads without
148 * writing the offset before are forbidden */
149 if (dibusb_i2c_msg(d, msg[i].addr, NULL, 0, msg[i].buf, msg[i].len) < 0)
150 break;
151 }
152 }
153
154 mutex_unlock(&d->i2c_mutex);
155 return i;
156}
157
158static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
159{
160 return I2C_FUNC_I2C;
161}
162
163struct i2c_algorithm dibusb_i2c_algo = {
164 .master_xfer = dibusb_i2c_xfer,
165 .functionality = dibusb_i2c_func,
166};
167EXPORT_SYMBOL(dibusb_i2c_algo);
168
169int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
170{
171 u8 wbuf[1] = { offs };
172 return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1);
173}
174EXPORT_SYMBOL(dibusb_read_eeprom_byte);
175
176/* 3000MC/P stuff */
177// Config Adjacent channels Perf -cal22
178static struct dibx000_agc_config dib3000p_mt2060_agc_config = {
179 .band_caps = BAND_VHF | BAND_UHF,
180 .setup = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0),
181
182 .agc1_max = 48497,
183 .agc1_min = 23593,
184 .agc2_max = 46531,
185 .agc2_min = 24904,
186
187 .agc1_pt1 = 0x65,
188 .agc1_pt2 = 0x69,
189
190 .agc1_slope1 = 0x51,
191 .agc1_slope2 = 0x27,
192
193 .agc2_pt1 = 0,
194 .agc2_pt2 = 0x33,
195
196 .agc2_slope1 = 0x35,
197 .agc2_slope2 = 0x37,
198};
199
200static struct dib3000mc_config stk3000p_dib3000p_config = {
201 &dib3000p_mt2060_agc_config,
202
203 .max_time = 0x196,
204 .ln_adc_level = 0x1cc7,
205
206 .output_mpeg2_in_188_bytes = 1,
207
208 .agc_command1 = 1,
209 .agc_command2 = 1,
210};
211
212static struct dibx000_agc_config dib3000p_panasonic_agc_config = {
213 .band_caps = BAND_VHF | BAND_UHF,
214 .setup = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0),
215
216 .agc1_max = 56361,
217 .agc1_min = 22282,
218 .agc2_max = 47841,
219 .agc2_min = 36045,
220
221 .agc1_pt1 = 0x3b,
222 .agc1_pt2 = 0x6b,
223
224 .agc1_slope1 = 0x55,
225 .agc1_slope2 = 0x1d,
226
227 .agc2_pt1 = 0,
228 .agc2_pt2 = 0x0a,
229
230 .agc2_slope1 = 0x95,
231 .agc2_slope2 = 0x1e,
232};
233
234#if defined(CONFIG_DVB_DIB3000MC) || \
235 (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE))
236
237static struct dib3000mc_config mod3000p_dib3000p_config = {
238 &dib3000p_panasonic_agc_config,
239
240 .max_time = 0x51,
241 .ln_adc_level = 0x1cc7,
242
243 .output_mpeg2_in_188_bytes = 1,
244
245 .agc_command1 = 1,
246 .agc_command2 = 1,
247};
248
249int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap)
250{
251 if (adap->dev->udev->descriptor.idVendor == USB_VID_LITEON &&
252 adap->dev->udev->descriptor.idProduct ==
253 USB_PID_LITEON_DVB_T_WARM) {
254 msleep(1000);
255 }
256
257 if ((adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000P_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL ||
258 (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000MC_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL) {
259 if (adap->priv != NULL) {
260 struct dibusb_state *st = adap->priv;
261 st->ops.pid_parse = dib3000mc_pid_parse;
262 st->ops.pid_ctrl = dib3000mc_pid_control;
263 }
264 return 0;
265 }
266 return -ENODEV;
267}
268EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);
269
270static struct mt2060_config stk3000p_mt2060_config = {
271 0x60
272};
273
274int dibusb_dib3000mc_tuner_attach(struct dvb_usb_adapter *adap)
275{
276 struct dibusb_state *st = adap->priv;
277 u8 a,b;
278 u16 if1 = 1220;
279 struct i2c_adapter *tun_i2c;
280
281 // First IF calibration for Liteon Sticks
282 if (adap->dev->udev->descriptor.idVendor == USB_VID_LITEON &&
283 adap->dev->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) {
284
285 dibusb_read_eeprom_byte(adap->dev,0x7E,&a);
286 dibusb_read_eeprom_byte(adap->dev,0x7F,&b);
287
288 if (a == 0x00)
289 if1 += b;
290 else if (a == 0x80)
291 if1 -= b;
292 else
293 warn("LITE-ON DVB-T: Strange IF1 calibration :%2X %2X\n", a, b);
294
295 } else if (adap->dev->udev->descriptor.idVendor == USB_VID_DIBCOM &&
296 adap->dev->udev->descriptor.idProduct == USB_PID_DIBCOM_MOD3001_WARM) {
297 u8 desc;
298 dibusb_read_eeprom_byte(adap->dev, 7, &desc);
299 if (desc == 2) {
300 a = 127;
301 do {
302 dibusb_read_eeprom_byte(adap->dev, a, &desc);
303 a--;
304 } while (a > 7 && (desc == 0xff || desc == 0x00));
305 if (desc & 0x80)
306 if1 -= (0xff - desc);
307 else
308 if1 += desc;
309 }
310 }
311
312 tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1);
313 if (dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk3000p_mt2060_config, if1) == NULL) {
314 /* not found - use panasonic pll parameters */
315 if (dvb_attach(dvb_pll_attach, adap->fe, 0x60, tun_i2c, DVB_PLL_ENV57H1XD5) == NULL)
316 return -ENOMEM;
317 } else {
318 st->mt2060_present = 1;
319 /* set the correct parameters for the dib3000p */
320 dib3000mc_set_config(adap->fe, &stk3000p_dib3000p_config);
321 }
322 return 0;
323}
324EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
325#endif
326
327/*
328 * common remote control stuff
329 */
330struct rc_map_table rc_map_dibusb_table[] = {
331 /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
332 { 0x0016, KEY_POWER },
333 { 0x0010, KEY_MUTE },
334 { 0x0003, KEY_1 },
335 { 0x0001, KEY_2 },
336 { 0x0006, KEY_3 },
337 { 0x0009, KEY_4 },
338 { 0x001d, KEY_5 },
339 { 0x001f, KEY_6 },
340 { 0x000d, KEY_7 },
341 { 0x0019, KEY_8 },
342 { 0x001b, KEY_9 },
343 { 0x0015, KEY_0 },
344 { 0x0005, KEY_CHANNELUP },
345 { 0x0002, KEY_CHANNELDOWN },
346 { 0x001e, KEY_VOLUMEUP },
347 { 0x000a, KEY_VOLUMEDOWN },
348 { 0x0011, KEY_RECORD },
349 { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
350 { 0x0014, KEY_PLAY },
351 { 0x001a, KEY_STOP },
352 { 0x0040, KEY_REWIND },
353 { 0x0012, KEY_FASTFORWARD },
354 { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
355 { 0x004c, KEY_PAUSE },
356 { 0x004d, KEY_SCREEN }, /* Full screen mode. */
357 { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
358 /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
359 { 0x000c, KEY_CANCEL }, /* Cancel */
360 { 0x001c, KEY_EPG }, /* EPG */
361 { 0x0000, KEY_TAB }, /* Tab */
362 { 0x0048, KEY_INFO }, /* Preview */
363 { 0x0004, KEY_LIST }, /* RecordList */
364 { 0x000f, KEY_TEXT }, /* Teletext */
365 /* Key codes for the KWorld/ADSTech/JetWay remote. */
366 { 0x8612, KEY_POWER },
367 { 0x860f, KEY_SELECT }, /* source */
368 { 0x860c, KEY_UNKNOWN }, /* scan */
369 { 0x860b, KEY_EPG },
370 { 0x8610, KEY_MUTE },
371 { 0x8601, KEY_1 },
372 { 0x8602, KEY_2 },
373 { 0x8603, KEY_3 },
374 { 0x8604, KEY_4 },
375 { 0x8605, KEY_5 },
376 { 0x8606, KEY_6 },
377 { 0x8607, KEY_7 },
378 { 0x8608, KEY_8 },
379 { 0x8609, KEY_9 },
380 { 0x860a, KEY_0 },
381 { 0x8618, KEY_ZOOM },
382 { 0x861c, KEY_UNKNOWN }, /* preview */
383 { 0x8613, KEY_UNKNOWN }, /* snap */
384 { 0x8600, KEY_UNDO },
385 { 0x861d, KEY_RECORD },
386 { 0x860d, KEY_STOP },
387 { 0x860e, KEY_PAUSE },
388 { 0x8616, KEY_PLAY },
389 { 0x8611, KEY_BACK },
390 { 0x8619, KEY_FORWARD },
391 { 0x8614, KEY_UNKNOWN }, /* pip */
392 { 0x8615, KEY_ESC },
393 { 0x861a, KEY_UP },
394 { 0x861e, KEY_DOWN },
395 { 0x861f, KEY_LEFT },
396 { 0x861b, KEY_RIGHT },
397
398 /* Key codes for the DiBcom MOD3000 remote. */
399 { 0x8000, KEY_MUTE },
400 { 0x8001, KEY_TEXT },
401 { 0x8002, KEY_HOME },
402 { 0x8003, KEY_POWER },
403
404 { 0x8004, KEY_RED },
405 { 0x8005, KEY_GREEN },
406 { 0x8006, KEY_YELLOW },
407 { 0x8007, KEY_BLUE },
408
409 { 0x8008, KEY_DVD },
410 { 0x8009, KEY_AUDIO },
411 { 0x800a, KEY_IMAGES }, /* Pictures */
412 { 0x800b, KEY_VIDEO },
413
414 { 0x800c, KEY_BACK },
415 { 0x800d, KEY_UP },
416 { 0x800e, KEY_RADIO },
417 { 0x800f, KEY_EPG },
418
419 { 0x8010, KEY_LEFT },
420 { 0x8011, KEY_OK },
421 { 0x8012, KEY_RIGHT },
422 { 0x8013, KEY_UNKNOWN }, /* SAP */
423
424 { 0x8014, KEY_TV },
425 { 0x8015, KEY_DOWN },
426 { 0x8016, KEY_MENU }, /* DVD Menu */
427 { 0x8017, KEY_LAST },
428
429 { 0x8018, KEY_RECORD },
430 { 0x8019, KEY_STOP },
431 { 0x801a, KEY_PAUSE },
432 { 0x801b, KEY_PLAY },
433
434 { 0x801c, KEY_PREVIOUS },
435 { 0x801d, KEY_REWIND },
436 { 0x801e, KEY_FASTFORWARD },
437 { 0x801f, KEY_NEXT},
438
439 { 0x8040, KEY_1 },
440 { 0x8041, KEY_2 },
441 { 0x8042, KEY_3 },
442 { 0x8043, KEY_CHANNELUP },
443
444 { 0x8044, KEY_4 },
445 { 0x8045, KEY_5 },
446 { 0x8046, KEY_6 },
447 { 0x8047, KEY_CHANNELDOWN },
448
449 { 0x8048, KEY_7 },
450 { 0x8049, KEY_8 },
451 { 0x804a, KEY_9 },
452 { 0x804b, KEY_VOLUMEUP },
453
454 { 0x804c, KEY_CLEAR },
455 { 0x804d, KEY_0 },
456 { 0x804e, KEY_ENTER },
457 { 0x804f, KEY_VOLUMEDOWN },
458};
459EXPORT_SYMBOL(rc_map_dibusb_table);
460
461int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
462{
463 u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE;
464 dvb_usb_generic_rw(d,&cmd,1,key,5,0);
465 dvb_usb_nec_rc_key_to_event(d,key,event,state);
466 if (key[0] != 0)
467 deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
468 return 0;
469}
470EXPORT_SYMBOL(dibusb_rc_query);
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
new file mode 100644
index 00000000000..04d91bdd356
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -0,0 +1,477 @@
1/* DVB USB compliant linux driver for mobile DVB-T USB devices based on
2 * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B)
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * based on GPL code from DiBcom, which has
7 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation, version 2.
12 *
13 * see Documentation/dvb/README.dvb-usb for more information
14 */
15#include "dibusb.h"
16
17DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
18
19static int dib3000mb_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
20{
21 struct dvb_usb_adapter *adap = fe->dvb->priv;
22 struct dibusb_state *st = adap->priv;
23
24 return st->ops.tuner_pass_ctrl(fe, enable, st->tuner_addr);
25}
26
27static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap)
28{
29 struct dib3000_config demod_cfg;
30 struct dibusb_state *st = adap->priv;
31
32 demod_cfg.demod_address = 0x8;
33
34 if ((adap->fe = dvb_attach(dib3000mb_attach, &demod_cfg,
35 &adap->dev->i2c_adap, &st->ops)) == NULL)
36 return -ENODEV;
37
38 adap->fe->ops.i2c_gate_ctrl = dib3000mb_i2c_gate_ctrl;
39
40 return 0;
41}
42
43static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap)
44{
45 struct dibusb_state *st = adap->priv;
46
47 st->tuner_addr = 0x61;
48
49 dvb_attach(dvb_pll_attach, adap->fe, 0x61, &adap->dev->i2c_adap,
50 DVB_PLL_TUA6010XS);
51 return 0;
52}
53
54static int dibusb_panasonic_tuner_attach(struct dvb_usb_adapter *adap)
55{
56 struct dibusb_state *st = adap->priv;
57
58 st->tuner_addr = 0x60;
59
60 dvb_attach(dvb_pll_attach, adap->fe, 0x60, &adap->dev->i2c_adap,
61 DVB_PLL_TDA665X);
62 return 0;
63}
64
65/* Some of the Artec 1.1 device aren't equipped with the default tuner
66 * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures
67 * this out. */
68static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap)
69{
70 u8 b[2] = { 0,0 }, b2[1];
71 int ret = 0;
72 struct i2c_msg msg[2] = {
73 { .flags = 0, .buf = b, .len = 2 },
74 { .flags = I2C_M_RD, .buf = b2, .len = 1 },
75 };
76 struct dibusb_state *st = adap->priv;
77
78 /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */
79 msg[0].addr = msg[1].addr = st->tuner_addr = 0x60;
80
81 if (adap->fe->ops.i2c_gate_ctrl)
82 adap->fe->ops.i2c_gate_ctrl(adap->fe,1);
83
84 if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) {
85 err("tuner i2c write failed.");
86 ret = -EREMOTEIO;
87 }
88
89 if (adap->fe->ops.i2c_gate_ctrl)
90 adap->fe->ops.i2c_gate_ctrl(adap->fe,0);
91
92 if (b2[0] == 0xfe) {
93 info("This device has the Thomson Cable onboard. Which is default.");
94 ret = dibusb_thomson_tuner_attach(adap);
95 } else {
96 info("This device has the Panasonic ENV77H11D5 onboard.");
97 ret = dibusb_panasonic_tuner_attach(adap);
98 }
99
100 return ret;
101}
102
103/* USB Driver stuff */
104static struct dvb_usb_device_properties dibusb1_1_properties;
105static struct dvb_usb_device_properties dibusb1_1_an2235_properties;
106static struct dvb_usb_device_properties dibusb2_0b_properties;
107static struct dvb_usb_device_properties artec_t1_usb2_properties;
108
109static int dibusb_probe(struct usb_interface *intf,
110 const struct usb_device_id *id)
111{
112 if (0 == dvb_usb_device_init(intf, &dibusb1_1_properties,
113 THIS_MODULE, NULL, adapter_nr) ||
114 0 == dvb_usb_device_init(intf, &dibusb1_1_an2235_properties,
115 THIS_MODULE, NULL, adapter_nr) ||
116 0 == dvb_usb_device_init(intf, &dibusb2_0b_properties,
117 THIS_MODULE, NULL, adapter_nr) ||
118 0 == dvb_usb_device_init(intf, &artec_t1_usb2_properties,
119 THIS_MODULE, NULL, adapter_nr))
120 return 0;
121
122 return -EINVAL;
123}
124
125/* do not change the order of the ID table */
126static struct usb_device_id dibusb_dib3000mb_table [] = {
127/* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD) },
128/* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM) },
129/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
130/* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) },
131/* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) },
132/* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) },
133/* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) },
134/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) },
135/* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) },
136/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) },
137/* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) },
138/* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) },
139/* 12 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) },
140/* 13 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) },
141/* 14 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) },
142/* 15 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_COLD) },
143/* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) },
144/* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) },
145/* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) },
146/* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
147/* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
148/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
149/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
150/* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) },
151
152/* device ID with default DIBUSB2_0-firmware and with the hacked firmware */
153/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) },
154/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) },
155/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) },
156
157/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) },
158
159/* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
160/* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) },
161
162/*
163 * XXX: As Artec just 'forgot' to program the EEPROM on some Artec T1 devices
164 * we don't catch these faulty IDs (namely 'Cypress FX1 USB controller') that
165 * have been left on the device. If you don't have such a device but an Artec
166 * device that's supposed to work with this driver but is not detected by it,
167 * free to enable CONFIG_DVB_USB_DIBUSB_MB_FAULTY via your kernel config.
168 */
169
170#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
171/* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
172#endif
173
174 { } /* Terminating entry */
175};
176MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
177
178static struct dvb_usb_device_properties dibusb1_1_properties = {
179 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
180
181 .usb_ctrl = CYPRESS_AN2135,
182
183 .firmware = "dvb-usb-dibusb-5.0.0.11.fw",
184
185 .num_adapters = 1,
186 .adapter = {
187 {
188 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
189 .pid_filter_count = 16,
190
191 .streaming_ctrl = dibusb_streaming_ctrl,
192 .pid_filter = dibusb_pid_filter,
193 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
194 .frontend_attach = dibusb_dib3000mb_frontend_attach,
195 .tuner_attach = dibusb_tuner_probe_and_attach,
196
197 /* parameter for the MPEG2-data transfer */
198 .stream = {
199 .type = USB_BULK,
200 .count = 7,
201 .endpoint = 0x02,
202 .u = {
203 .bulk = {
204 .buffersize = 4096,
205 }
206 }
207 },
208 .size_of_priv = sizeof(struct dibusb_state),
209 }
210 },
211
212 .power_ctrl = dibusb_power_ctrl,
213
214 .rc.legacy = {
215 .rc_interval = DEFAULT_RC_INTERVAL,
216 .rc_map_table = rc_map_dibusb_table,
217 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
218 .rc_query = dibusb_rc_query,
219 },
220
221 .i2c_algo = &dibusb_i2c_algo,
222
223 .generic_bulk_ctrl_endpoint = 0x01,
224
225 .num_device_descs = 9,
226 .devices = {
227 { "AVerMedia AverTV DVBT USB1.1",
228 { &dibusb_dib3000mb_table[0], NULL },
229 { &dibusb_dib3000mb_table[1], NULL },
230 },
231 { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
232 { &dibusb_dib3000mb_table[2], &dibusb_dib3000mb_table[4], NULL},
233 { &dibusb_dib3000mb_table[3], NULL },
234 },
235 { "DiBcom USB1.1 DVB-T reference design (MOD3000)",
236 { &dibusb_dib3000mb_table[5], NULL },
237 { &dibusb_dib3000mb_table[6], NULL },
238 },
239 { "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
240 { &dibusb_dib3000mb_table[7], NULL },
241 { &dibusb_dib3000mb_table[8], NULL },
242 },
243 { "Grandtec USB1.1 DVB-T",
244 { &dibusb_dib3000mb_table[9], &dibusb_dib3000mb_table[11], NULL },
245 { &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL },
246 },
247 { "Unknown USB1.1 DVB-T device ???? please report the name to the author",
248 { &dibusb_dib3000mb_table[13], NULL },
249 { &dibusb_dib3000mb_table[14], NULL },
250 },
251 { "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device",
252 { &dibusb_dib3000mb_table[15], &dibusb_dib3000mb_table[17], NULL},
253 { &dibusb_dib3000mb_table[16], &dibusb_dib3000mb_table[18], NULL},
254 },
255 { "Artec T1 USB1.1 TVBOX with AN2135",
256 { &dibusb_dib3000mb_table[19], NULL },
257 { &dibusb_dib3000mb_table[20], NULL },
258 },
259 { "VideoWalker DVB-T USB",
260 { &dibusb_dib3000mb_table[25], NULL },
261 { &dibusb_dib3000mb_table[26], NULL },
262 },
263 }
264};
265
266static struct dvb_usb_device_properties dibusb1_1_an2235_properties = {
267 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
268 .usb_ctrl = CYPRESS_AN2235,
269
270 .firmware = "dvb-usb-dibusb-an2235-01.fw",
271
272 .num_adapters = 1,
273 .adapter = {
274 {
275 .caps = DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_ADAP_HAS_PID_FILTER,
276 .pid_filter_count = 16,
277
278 .streaming_ctrl = dibusb_streaming_ctrl,
279 .pid_filter = dibusb_pid_filter,
280 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
281 .frontend_attach = dibusb_dib3000mb_frontend_attach,
282 .tuner_attach = dibusb_tuner_probe_and_attach,
283
284 /* parameter for the MPEG2-data transfer */
285 .stream = {
286 .type = USB_BULK,
287 .count = 7,
288 .endpoint = 0x02,
289 .u = {
290 .bulk = {
291 .buffersize = 4096,
292 }
293 }
294 },
295 .size_of_priv = sizeof(struct dibusb_state),
296 },
297 },
298 .power_ctrl = dibusb_power_ctrl,
299
300 .rc.legacy = {
301 .rc_interval = DEFAULT_RC_INTERVAL,
302 .rc_map_table = rc_map_dibusb_table,
303 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
304 .rc_query = dibusb_rc_query,
305 },
306
307 .i2c_algo = &dibusb_i2c_algo,
308
309 .generic_bulk_ctrl_endpoint = 0x01,
310
311#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
312 .num_device_descs = 2,
313#else
314 .num_device_descs = 1,
315#endif
316 .devices = {
317 { "Artec T1 USB1.1 TVBOX with AN2235",
318 { &dibusb_dib3000mb_table[21], NULL },
319 { &dibusb_dib3000mb_table[22], NULL },
320 },
321#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
322 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
323 { &dibusb_dib3000mb_table[30], NULL },
324 { NULL },
325 },
326 { NULL },
327#endif
328 }
329};
330
331static struct dvb_usb_device_properties dibusb2_0b_properties = {
332 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
333
334 .usb_ctrl = CYPRESS_FX2,
335
336 .firmware = "dvb-usb-adstech-usb2-02.fw",
337
338 .num_adapters = 1,
339 .adapter = {
340 {
341 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
342 .pid_filter_count = 16,
343
344 .streaming_ctrl = dibusb2_0_streaming_ctrl,
345 .pid_filter = dibusb_pid_filter,
346 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
347 .frontend_attach = dibusb_dib3000mb_frontend_attach,
348 .tuner_attach = dibusb_thomson_tuner_attach,
349
350 /* parameter for the MPEG2-data transfer */
351 .stream = {
352 .type = USB_BULK,
353 .count = 7,
354 .endpoint = 0x06,
355 .u = {
356 .bulk = {
357 .buffersize = 4096,
358 }
359 }
360 },
361 .size_of_priv = sizeof(struct dibusb_state),
362 }
363 },
364 .power_ctrl = dibusb2_0_power_ctrl,
365
366 .rc.legacy = {
367 .rc_interval = DEFAULT_RC_INTERVAL,
368 .rc_map_table = rc_map_dibusb_table,
369 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
370 .rc_query = dibusb_rc_query,
371 },
372
373 .i2c_algo = &dibusb_i2c_algo,
374
375 .generic_bulk_ctrl_endpoint = 0x01,
376
377 .num_device_descs = 2,
378 .devices = {
379 { "KWorld/ADSTech Instant DVB-T USB2.0",
380 { &dibusb_dib3000mb_table[23], NULL },
381 { &dibusb_dib3000mb_table[24], NULL },
382 },
383 { "KWorld Xpert DVB-T USB2.0",
384 { &dibusb_dib3000mb_table[27], NULL },
385 { NULL }
386 },
387 { NULL },
388 }
389};
390
391static struct dvb_usb_device_properties artec_t1_usb2_properties = {
392 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
393
394 .usb_ctrl = CYPRESS_FX2,
395
396 .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
397
398 .num_adapters = 1,
399 .adapter = {
400 {
401 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
402 .pid_filter_count = 16,
403
404 .streaming_ctrl = dibusb2_0_streaming_ctrl,
405 .pid_filter = dibusb_pid_filter,
406 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
407 .frontend_attach = dibusb_dib3000mb_frontend_attach,
408 .tuner_attach = dibusb_tuner_probe_and_attach,
409 /* parameter for the MPEG2-data transfer */
410 .stream = {
411 .type = USB_BULK,
412 .count = 7,
413 .endpoint = 0x06,
414 .u = {
415 .bulk = {
416 .buffersize = 4096,
417 }
418 }
419 },
420 .size_of_priv = sizeof(struct dibusb_state),
421 }
422 },
423 .power_ctrl = dibusb2_0_power_ctrl,
424
425 .rc.legacy = {
426 .rc_interval = DEFAULT_RC_INTERVAL,
427 .rc_map_table = rc_map_dibusb_table,
428 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
429 .rc_query = dibusb_rc_query,
430 },
431
432 .i2c_algo = &dibusb_i2c_algo,
433
434 .generic_bulk_ctrl_endpoint = 0x01,
435
436 .num_device_descs = 1,
437 .devices = {
438 { "Artec T1 USB2.0",
439 { &dibusb_dib3000mb_table[28], NULL },
440 { &dibusb_dib3000mb_table[29], NULL },
441 },
442 { NULL },
443 }
444};
445
446static struct usb_driver dibusb_driver = {
447 .name = "dvb_usb_dibusb_mb",
448 .probe = dibusb_probe,
449 .disconnect = dvb_usb_device_exit,
450 .id_table = dibusb_dib3000mb_table,
451};
452
453/* module stuff */
454static int __init dibusb_module_init(void)
455{
456 int result;
457 if ((result = usb_register(&dibusb_driver))) {
458 err("usb_register failed. Error number %d",result);
459 return result;
460 }
461
462 return 0;
463}
464
465static void __exit dibusb_module_exit(void)
466{
467 /* deregister this driver from the USB subsystem */
468 usb_deregister(&dibusb_driver);
469}
470
471module_init (dibusb_module_init);
472module_exit (dibusb_module_exit);
473
474MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
475MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)");
476MODULE_VERSION("1.0");
477MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c
new file mode 100644
index 00000000000..c1d9094b61e
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c
@@ -0,0 +1,165 @@
1/* DVB USB compliant linux driver for mobile DVB-T USB devices based on
2 * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-C/P)
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * based on GPL code from DiBcom, which has
7 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation, version 2.
12 *
13 * see Documentation/dvb/README.dvb-usb for more information
14 */
15#include "dibusb.h"
16
17DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
18
19/* USB Driver stuff */
20static struct dvb_usb_device_properties dibusb_mc_properties;
21
22static int dibusb_mc_probe(struct usb_interface *intf,
23 const struct usb_device_id *id)
24{
25 return dvb_usb_device_init(intf, &dibusb_mc_properties, THIS_MODULE,
26 NULL, adapter_nr);
27}
28
29/* do not change the order of the ID table */
30static struct usb_device_id dibusb_dib3000mc_table [] = {
31/* 00 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) },
32/* 01 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) },
33/* 02 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
34/* 03 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, // ( ? )
35/* 04 */ { USB_DEVICE(USB_VID_LITEON, USB_PID_LITEON_DVB_T_COLD) },
36/* 05 */ { USB_DEVICE(USB_VID_LITEON, USB_PID_LITEON_DVB_T_WARM) },
37/* 06 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_DIGIVOX_MINI_SL_COLD) },
38/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_DIGIVOX_MINI_SL_WARM) },
39/* 08 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB2_COLD) },
40/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB2_WARM) },
41/* 10 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_COLD) },
42/* 11 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_WARM) },
43/* 12 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_COLD) },
44/* 13 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_WARM) },
45/* 14 */ { USB_DEVICE(USB_VID_HUMAX_COEX, USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD) },
46/* 15 */ { USB_DEVICE(USB_VID_HUMAX_COEX, USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM) },
47 { } /* Terminating entry */
48};
49MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
50
51static struct dvb_usb_device_properties dibusb_mc_properties = {
52 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
53
54 .usb_ctrl = CYPRESS_FX2,
55 .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
56
57 .num_adapters = 1,
58 .adapter = {
59 {
60 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
61 .pid_filter_count = 32,
62 .streaming_ctrl = dibusb2_0_streaming_ctrl,
63 .pid_filter = dibusb_pid_filter,
64 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
65 .frontend_attach = dibusb_dib3000mc_frontend_attach,
66 .tuner_attach = dibusb_dib3000mc_tuner_attach,
67
68 /* parameter for the MPEG2-data transfer */
69 .stream = {
70 .type = USB_BULK,
71 .count = 8,
72 .endpoint = 0x06,
73 .u = {
74 .bulk = {
75 .buffersize = 4096,
76 }
77 }
78 },
79 .size_of_priv = sizeof(struct dibusb_state),
80 }
81 },
82 .power_ctrl = dibusb2_0_power_ctrl,
83
84 .rc.legacy = {
85 .rc_interval = DEFAULT_RC_INTERVAL,
86 .rc_map_table = rc_map_dibusb_table,
87 .rc_map_size = 111, /* FIXME */
88 .rc_query = dibusb_rc_query,
89 },
90
91 .i2c_algo = &dibusb_i2c_algo,
92
93 .generic_bulk_ctrl_endpoint = 0x01,
94
95 .num_device_descs = 8,
96 .devices = {
97 { "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
98 { &dibusb_dib3000mc_table[0], NULL },
99 { &dibusb_dib3000mc_table[1], NULL },
100 },
101 { "Artec T1 USB2.0 TVBOX (please check the warm ID)",
102 { &dibusb_dib3000mc_table[2], NULL },
103 { &dibusb_dib3000mc_table[3], NULL },
104 },
105 { "LITE-ON USB2.0 DVB-T Tuner",
106 /* Also rebranded as Intuix S800, Toshiba */
107 { &dibusb_dib3000mc_table[4], NULL },
108 { &dibusb_dib3000mc_table[5], NULL },
109 },
110 { "MSI Digivox Mini SL",
111 { &dibusb_dib3000mc_table[6], NULL },
112 { &dibusb_dib3000mc_table[7], NULL },
113 },
114 { "GRAND - USB2.0 DVB-T adapter",
115 { &dibusb_dib3000mc_table[8], NULL },
116 { &dibusb_dib3000mc_table[9], NULL },
117 },
118 { "Artec T14 - USB2.0 DVB-T",
119 { &dibusb_dib3000mc_table[10], NULL },
120 { &dibusb_dib3000mc_table[11], NULL },
121 },
122 { "Leadtek - USB2.0 Winfast DTV dongle",
123 { &dibusb_dib3000mc_table[12], NULL },
124 { &dibusb_dib3000mc_table[13], NULL },
125 },
126 { "Humax/Coex DVB-T USB Stick 2.0 High Speed",
127 { &dibusb_dib3000mc_table[14], NULL },
128 { &dibusb_dib3000mc_table[15], NULL },
129 },
130 { NULL },
131 }
132};
133
134static struct usb_driver dibusb_mc_driver = {
135 .name = "dvb_usb_dibusb_mc",
136 .probe = dibusb_mc_probe,
137 .disconnect = dvb_usb_device_exit,
138 .id_table = dibusb_dib3000mc_table,
139};
140
141/* module stuff */
142static int __init dibusb_mc_module_init(void)
143{
144 int result;
145 if ((result = usb_register(&dibusb_mc_driver))) {
146 err("usb_register failed. Error number %d",result);
147 return result;
148 }
149
150 return 0;
151}
152
153static void __exit dibusb_mc_module_exit(void)
154{
155 /* deregister this driver from the USB subsystem */
156 usb_deregister(&dibusb_mc_driver);
157}
158
159module_init (dibusb_mc_module_init);
160module_exit (dibusb_mc_module_exit);
161
162MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
163MODULE_DESCRIPTION("Driver for DiBcom USB2.0 DVB-T (DiB3000M-C/P based) devices");
164MODULE_VERSION("1.0");
165MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h
new file mode 100644
index 00000000000..e47c321b3ff
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dibusb.h
@@ -0,0 +1,131 @@
1/* Header file for all dibusb-based-receivers.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation, version 2.
8 *
9 * see Documentation/dvb/README.dvb-usb for more information
10 */
11#ifndef _DVB_USB_DIBUSB_H_
12#define _DVB_USB_DIBUSB_H_
13
14#ifndef DVB_USB_LOG_PREFIX
15 #define DVB_USB_LOG_PREFIX "dibusb"
16#endif
17#include "dvb-usb.h"
18
19#include "dib3000.h"
20#include "dib3000mc.h"
21#include "mt2060.h"
22
23/*
24 * protocol of all dibusb related devices
25 */
26
27/*
28 * bulk msg to/from endpoint 0x01
29 *
30 * general structure:
31 * request_byte parameter_bytes
32 */
33
34#define DIBUSB_REQ_START_READ 0x00
35#define DIBUSB_REQ_START_DEMOD 0x01
36
37/*
38 * i2c read
39 * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
40 * bulk read: byte_buffer (length_word bytes)
41 */
42#define DIBUSB_REQ_I2C_READ 0x02
43
44/*
45 * i2c write
46 * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes
47 */
48#define DIBUSB_REQ_I2C_WRITE 0x03
49
50/*
51 * polling the value of the remote control
52 * bulk write: 0x04
53 * bulk read: byte_buffer (5 bytes)
54 */
55#define DIBUSB_REQ_POLL_REMOTE 0x04
56
57/* additional status values for Hauppauge Remote Control Protocol */
58#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED 0x01
59#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY 0x03
60
61/* streaming mode:
62 * bulk write: 0x05 mode_byte
63 *
64 * mode_byte is mostly 0x00
65 */
66#define DIBUSB_REQ_SET_STREAMING_MODE 0x05
67
68/* interrupt the internal read loop, when blocking */
69#define DIBUSB_REQ_INTR_READ 0x06
70
71/* io control
72 * 0x07 cmd_byte param_bytes
73 *
74 * param_bytes can be up to 32 bytes
75 *
76 * cmd_byte function parameter name
77 * 0x00 power mode
78 * 0x00 sleep
79 * 0x01 wakeup
80 *
81 * 0x01 enable streaming
82 * 0x02 disable streaming
83 *
84 *
85 */
86#define DIBUSB_REQ_SET_IOCTL 0x07
87
88/* IOCTL commands */
89
90/* change the power mode in firmware */
91#define DIBUSB_IOCTL_CMD_POWER_MODE 0x00
92#define DIBUSB_IOCTL_POWER_SLEEP 0x00
93#define DIBUSB_IOCTL_POWER_WAKEUP 0x01
94
95/* modify streaming of the FX2 */
96#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01
97#define DIBUSB_IOCTL_CMD_DISABLE_STREAM 0x02
98
99struct dibusb_state {
100 struct dib_fe_xfer_ops ops;
101 int mt2060_present;
102 u8 tuner_addr;
103};
104
105struct dibusb_device_state {
106 /* for RC5 remote control */
107 int old_toggle;
108 int last_repeat_count;
109};
110
111extern struct i2c_algorithm dibusb_i2c_algo;
112
113extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *);
114extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_adapter *);
115
116extern int dibusb_streaming_ctrl(struct dvb_usb_adapter *, int);
117extern int dibusb_pid_filter(struct dvb_usb_adapter *, int, u16, int);
118extern int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *, int);
119extern int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *, int);
120
121extern int dibusb_power_ctrl(struct dvb_usb_device *, int);
122extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int);
123
124#define DEFAULT_RC_INTERVAL 150
125//#define DEFAULT_RC_INTERVAL 100000
126
127extern struct rc_map_table rc_map_dibusb_table[];
128extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *);
129extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *);
130
131#endif
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
new file mode 100644
index 00000000000..f6344cdd360
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -0,0 +1,365 @@
1/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0
2 * receiver
3 *
4 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * partly based on the SDK published by Nebula Electronics
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#include "digitv.h"
15
16#include "mt352.h"
17#include "nxt6000.h"
18
19/* debug */
20static int dvb_usb_digitv_debug;
21module_param_named(debug,dvb_usb_digitv_debug, int, 0644);
22MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
23
24DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
25
26#define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args)
27
28static int digitv_ctrl_msg(struct dvb_usb_device *d,
29 u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
30{
31 int wo = (rbuf == NULL || rlen == 0); /* write-only */
32 u8 sndbuf[7],rcvbuf[7];
33 memset(sndbuf,0,7); memset(rcvbuf,0,7);
34
35 sndbuf[0] = cmd;
36 sndbuf[1] = vv;
37 sndbuf[2] = wo ? wlen : rlen;
38
39 if (wo) {
40 memcpy(&sndbuf[3],wbuf,wlen);
41 dvb_usb_generic_write(d,sndbuf,7);
42 } else {
43 dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10);
44 memcpy(rbuf,&rcvbuf[3],rlen);
45 }
46 return 0;
47}
48
49/* I2C */
50static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
51{
52 struct dvb_usb_device *d = i2c_get_adapdata(adap);
53 int i;
54
55 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
56 return -EAGAIN;
57
58 if (num > 2)
59 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
60
61 for (i = 0; i < num; i++) {
62 /* write/read request */
63 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
64 if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0,
65 msg[i+1].buf,msg[i+1].len) < 0)
66 break;
67 i++;
68 } else
69 if (digitv_ctrl_msg(d,USB_WRITE_COFDM, msg[i].buf[0],
70 &msg[i].buf[1],msg[i].len-1,NULL,0) < 0)
71 break;
72 }
73
74 mutex_unlock(&d->i2c_mutex);
75 return i;
76}
77
78static u32 digitv_i2c_func(struct i2c_adapter *adapter)
79{
80 return I2C_FUNC_I2C;
81}
82
83static struct i2c_algorithm digitv_i2c_algo = {
84 .master_xfer = digitv_i2c_xfer,
85 .functionality = digitv_i2c_func,
86};
87
88/* Callbacks for DVB USB */
89static int digitv_identify_state (struct usb_device *udev, struct
90 dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
91 int *cold)
92{
93 *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
94 return 0;
95}
96
97static int digitv_mt352_demod_init(struct dvb_frontend *fe)
98{
99 static u8 reset_buf[] = { 0x89, 0x38, 0x8a, 0x2d, 0x50, 0x80 };
100 static u8 init_buf[] = { 0x68, 0xa0, 0x8e, 0x40, 0x53, 0x50,
101 0x67, 0x20, 0x7d, 0x01, 0x7c, 0x00, 0x7a, 0x00,
102 0x79, 0x20, 0x57, 0x05, 0x56, 0x31, 0x88, 0x0f,
103 0x75, 0x32 };
104 int i;
105
106 for (i = 0; i < ARRAY_SIZE(reset_buf); i += 2)
107 mt352_write(fe, &reset_buf[i], 2);
108
109 msleep(1);
110
111 for (i = 0; i < ARRAY_SIZE(init_buf); i += 2)
112 mt352_write(fe, &init_buf[i], 2);
113
114 return 0;
115}
116
117static struct mt352_config digitv_mt352_config = {
118 .demod_init = digitv_mt352_demod_init,
119};
120
121static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
122{
123 struct dvb_usb_adapter *adap = fe->dvb->priv;
124 u8 b[5];
125
126 fe->ops.tuner_ops.calc_regs(fe, fep, b, sizeof(b));
127 if (fe->ops.i2c_gate_ctrl)
128 fe->ops.i2c_gate_ctrl(fe, 1);
129 return digitv_ctrl_msg(adap->dev, USB_WRITE_TUNER, 0, &b[1], 4, NULL, 0);
130}
131
132static struct nxt6000_config digitv_nxt6000_config = {
133 .clock_inversion = 1,
134};
135
136static int digitv_frontend_attach(struct dvb_usb_adapter *adap)
137{
138 struct digitv_state *st = adap->dev->priv;
139
140 if ((adap->fe = dvb_attach(mt352_attach, &digitv_mt352_config, &adap->dev->i2c_adap)) != NULL) {
141 st->is_nxt6000 = 0;
142 return 0;
143 }
144 if ((adap->fe = dvb_attach(nxt6000_attach, &digitv_nxt6000_config, &adap->dev->i2c_adap)) != NULL) {
145 st->is_nxt6000 = 1;
146 return 0;
147 }
148 return -EIO;
149}
150
151static int digitv_tuner_attach(struct dvb_usb_adapter *adap)
152{
153 struct digitv_state *st = adap->dev->priv;
154
155 if (!dvb_attach(dvb_pll_attach, adap->fe, 0x60, NULL, DVB_PLL_TDED4))
156 return -ENODEV;
157
158 if (st->is_nxt6000)
159 adap->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params;
160
161 return 0;
162}
163
164static struct rc_map_table rc_map_digitv_table[] = {
165 { 0x5f55, KEY_0 },
166 { 0x6f55, KEY_1 },
167 { 0x9f55, KEY_2 },
168 { 0xaf55, KEY_3 },
169 { 0x5f56, KEY_4 },
170 { 0x6f56, KEY_5 },
171 { 0x9f56, KEY_6 },
172 { 0xaf56, KEY_7 },
173 { 0x5f59, KEY_8 },
174 { 0x6f59, KEY_9 },
175 { 0x9f59, KEY_TV },
176 { 0xaf59, KEY_AUX },
177 { 0x5f5a, KEY_DVD },
178 { 0x6f5a, KEY_POWER },
179 { 0x9f5a, KEY_CAMERA }, /* labelled 'Picture' */
180 { 0xaf5a, KEY_AUDIO },
181 { 0x5f65, KEY_INFO },
182 { 0x6f65, KEY_F13 }, /* 16:9 */
183 { 0x9f65, KEY_F14 }, /* 14:9 */
184 { 0xaf65, KEY_EPG },
185 { 0x5f66, KEY_EXIT },
186 { 0x6f66, KEY_MENU },
187 { 0x9f66, KEY_UP },
188 { 0xaf66, KEY_DOWN },
189 { 0x5f69, KEY_LEFT },
190 { 0x6f69, KEY_RIGHT },
191 { 0x9f69, KEY_ENTER },
192 { 0xaf69, KEY_CHANNELUP },
193 { 0x5f6a, KEY_CHANNELDOWN },
194 { 0x6f6a, KEY_VOLUMEUP },
195 { 0x9f6a, KEY_VOLUMEDOWN },
196 { 0xaf6a, KEY_RED },
197 { 0x5f95, KEY_GREEN },
198 { 0x6f95, KEY_YELLOW },
199 { 0x9f95, KEY_BLUE },
200 { 0xaf95, KEY_SUBTITLE },
201 { 0x5f96, KEY_F15 }, /* AD */
202 { 0x6f96, KEY_TEXT },
203 { 0x9f96, KEY_MUTE },
204 { 0xaf96, KEY_REWIND },
205 { 0x5f99, KEY_STOP },
206 { 0x6f99, KEY_PLAY },
207 { 0x9f99, KEY_FASTFORWARD },
208 { 0xaf99, KEY_F16 }, /* chapter */
209 { 0x5f9a, KEY_PAUSE },
210 { 0x6f9a, KEY_PLAY },
211 { 0x9f9a, KEY_RECORD },
212 { 0xaf9a, KEY_F17 }, /* picture in picture */
213 { 0x5fa5, KEY_KPPLUS }, /* zoom in */
214 { 0x6fa5, KEY_KPMINUS }, /* zoom out */
215 { 0x9fa5, KEY_F18 }, /* capture */
216 { 0xafa5, KEY_F19 }, /* web */
217 { 0x5fa6, KEY_EMAIL },
218 { 0x6fa6, KEY_PHONE },
219 { 0x9fa6, KEY_PC },
220};
221
222static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
223{
224 int i;
225 u8 key[5];
226 u8 b[4] = { 0 };
227
228 *event = 0;
229 *state = REMOTE_NO_KEY_PRESSED;
230
231 digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4);
232
233 /* Tell the device we've read the remote. Not sure how necessary
234 this is, but the Nebula SDK does it. */
235 digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
236
237 /* if something is inside the buffer, simulate key press */
238 if (key[1] != 0)
239 {
240 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
241 if (rc5_custom(&d->props.rc.legacy.rc_map_table[i]) == key[1] &&
242 rc5_data(&d->props.rc.legacy.rc_map_table[i]) == key[2]) {
243 *event = d->props.rc.legacy.rc_map_table[i].keycode;
244 *state = REMOTE_KEY_PRESSED;
245 return 0;
246 }
247 }
248 }
249
250 if (key[0] != 0)
251 deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
252 return 0;
253}
254
255/* DVB USB Driver stuff */
256static struct dvb_usb_device_properties digitv_properties;
257
258static int digitv_probe(struct usb_interface *intf,
259 const struct usb_device_id *id)
260{
261 struct dvb_usb_device *d;
262 int ret = dvb_usb_device_init(intf, &digitv_properties, THIS_MODULE, &d,
263 adapter_nr);
264 if (ret == 0) {
265 u8 b[4] = { 0 };
266
267 if (d != NULL) { /* do that only when the firmware is loaded */
268 b[0] = 1;
269 digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
270
271 b[0] = 0;
272 digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
273 }
274 }
275 return ret;
276}
277
278static struct usb_device_id digitv_table [] = {
279 { USB_DEVICE(USB_VID_ANCHOR, USB_PID_NEBULA_DIGITV) },
280 { } /* Terminating entry */
281};
282MODULE_DEVICE_TABLE (usb, digitv_table);
283
284static struct dvb_usb_device_properties digitv_properties = {
285 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
286
287 .usb_ctrl = CYPRESS_FX2,
288 .firmware = "dvb-usb-digitv-02.fw",
289
290 .size_of_priv = sizeof(struct digitv_state),
291
292 .num_adapters = 1,
293 .adapter = {
294 {
295 .frontend_attach = digitv_frontend_attach,
296 .tuner_attach = digitv_tuner_attach,
297
298 /* parameter for the MPEG2-data transfer */
299 .stream = {
300 .type = USB_BULK,
301 .count = 7,
302 .endpoint = 0x02,
303 .u = {
304 .bulk = {
305 .buffersize = 4096,
306 }
307 }
308 },
309 }
310 },
311 .identify_state = digitv_identify_state,
312
313 .rc.legacy = {
314 .rc_interval = 1000,
315 .rc_map_table = rc_map_digitv_table,
316 .rc_map_size = ARRAY_SIZE(rc_map_digitv_table),
317 .rc_query = digitv_rc_query,
318 },
319
320 .i2c_algo = &digitv_i2c_algo,
321
322 .generic_bulk_ctrl_endpoint = 0x01,
323
324 .num_device_descs = 1,
325 .devices = {
326 { "Nebula Electronics uDigiTV DVB-T USB2.0)",
327 { &digitv_table[0], NULL },
328 { NULL },
329 },
330 { NULL },
331 }
332};
333
334static struct usb_driver digitv_driver = {
335 .name = "dvb_usb_digitv",
336 .probe = digitv_probe,
337 .disconnect = dvb_usb_device_exit,
338 .id_table = digitv_table,
339};
340
341/* module stuff */
342static int __init digitv_module_init(void)
343{
344 int result;
345 if ((result = usb_register(&digitv_driver))) {
346 err("usb_register failed. Error number %d",result);
347 return result;
348 }
349
350 return 0;
351}
352
353static void __exit digitv_module_exit(void)
354{
355 /* deregister this driver from the USB subsystem */
356 usb_deregister(&digitv_driver);
357}
358
359module_init (digitv_module_init);
360module_exit (digitv_module_exit);
361
362MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
363MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0");
364MODULE_VERSION("1.0-alpha");
365MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/digitv.h b/drivers/media/dvb/dvb-usb/digitv.h
new file mode 100644
index 00000000000..908c09f4966
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/digitv.h
@@ -0,0 +1,66 @@
1#ifndef _DVB_USB_DIGITV_H_
2#define _DVB_USB_DIGITV_H_
3
4#define DVB_USB_LOG_PREFIX "digitv"
5#include "dvb-usb.h"
6
7struct digitv_state {
8 int is_nxt6000;
9};
10
11/* protocol (from usblogging and the SDK:
12 *
13 * Always 7 bytes bulk message(s) for controlling
14 *
15 * First byte describes the command. Reads are 2 consecutive transfer (as always).
16 *
17 * General structure:
18 *
19 * write or first message of a read:
20 * <cmdbyte> VV <len> B0 B1 B2 B3
21 *
22 * second message of a read
23 * <cmdbyte> VV <len> R0 R1 R2 R3
24 *
25 * whereas 0 < len <= 4
26 *
27 * I2C address is stored somewhere inside the device.
28 *
29 * 0x01 read from EEPROM
30 * VV = offset; B* = 0; R* = value(s)
31 *
32 * 0x02 read register of the COFDM
33 * VV = register; B* = 0; R* = value(s)
34 *
35 * 0x05 write register of the COFDM
36 * VV = register; B* = value(s);
37 *
38 * 0x06 write to the tuner (only for NXT6000)
39 * VV = 0; B* = PLL data; len = 4;
40 *
41 * 0x03 read remote control
42 * VV = 0; B* = 0; len = 4; R* = key
43 *
44 * 0x07 write to the remote (don't know why one should this, resetting ?)
45 * VV = 0; B* = key; len = 4;
46 *
47 * 0x08 write remote type
48 * VV = 0; B[0] = 0x01, len = 4
49 *
50 * 0x09 write device init
51 * TODO
52 */
53#define USB_READ_EEPROM 1
54
55#define USB_READ_COFDM 2
56#define USB_WRITE_COFDM 5
57
58#define USB_WRITE_TUNER 6
59
60#define USB_READ_REMOTE 3
61#define USB_WRITE_REMOTE 7
62#define USB_WRITE_REMOTE_TYPE 8
63
64#define USB_DEV_INIT 9
65
66#endif
diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
new file mode 100644
index 00000000000..17413adec7a
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
@@ -0,0 +1,205 @@
1/* Frontend part of the Linux driver for the WideView/ Yakumo/ Hama/
2 * Typhoon/ Yuan DVB-T USB2.0 receiver.
3 *
4 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "dtt200u.h"
13
14struct dtt200u_fe_state {
15 struct dvb_usb_device *d;
16
17 fe_status_t stat;
18
19 struct dvb_frontend_parameters fep;
20 struct dvb_frontend frontend;
21};
22
23static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
24{
25 struct dtt200u_fe_state *state = fe->demodulator_priv;
26 u8 st = GET_TUNE_STATUS, b[3];
27
28 dvb_usb_generic_rw(state->d,&st,1,b,3,0);
29
30 switch (b[0]) {
31 case 0x01:
32 *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER |
33 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
34 break;
35 case 0x00: /* pending */
36 *stat = FE_TIMEDOUT; /* during set_frontend */
37 break;
38 default:
39 case 0x02: /* failed */
40 *stat = 0;
41 break;
42 }
43 return 0;
44}
45
46static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
47{
48 struct dtt200u_fe_state *state = fe->demodulator_priv;
49 u8 bw = GET_VIT_ERR_CNT,b[3];
50 dvb_usb_generic_rw(state->d,&bw,1,b,3,0);
51 *ber = (b[0] << 16) | (b[1] << 8) | b[2];
52 return 0;
53}
54
55static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
56{
57 struct dtt200u_fe_state *state = fe->demodulator_priv;
58 u8 bw = GET_RS_UNCOR_BLK_CNT,b[2];
59
60 dvb_usb_generic_rw(state->d,&bw,1,b,2,0);
61 *unc = (b[0] << 8) | b[1];
62 return 0;
63}
64
65static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
66{
67 struct dtt200u_fe_state *state = fe->demodulator_priv;
68 u8 bw = GET_AGC, b;
69 dvb_usb_generic_rw(state->d,&bw,1,&b,1,0);
70 *strength = (b << 8) | b;
71 return 0;
72}
73
74static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
75{
76 struct dtt200u_fe_state *state = fe->demodulator_priv;
77 u8 bw = GET_SNR,br;
78 dvb_usb_generic_rw(state->d,&bw,1,&br,1,0);
79 *snr = ~((br << 8) | br);
80 return 0;
81}
82
83static int dtt200u_fe_init(struct dvb_frontend* fe)
84{
85 struct dtt200u_fe_state *state = fe->demodulator_priv;
86 u8 b = SET_INIT;
87 return dvb_usb_generic_write(state->d,&b,1);
88}
89
90static int dtt200u_fe_sleep(struct dvb_frontend* fe)
91{
92 return dtt200u_fe_init(fe);
93}
94
95static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
96{
97 tune->min_delay_ms = 1500;
98 tune->step_size = 0;
99 tune->max_drift = 0;
100 return 0;
101}
102
103static int dtt200u_fe_set_frontend(struct dvb_frontend* fe,
104 struct dvb_frontend_parameters *fep)
105{
106 struct dtt200u_fe_state *state = fe->demodulator_priv;
107 int i;
108 fe_status_t st;
109 u16 freq = fep->frequency / 250000;
110 u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 };
111
112 switch (fep->u.ofdm.bandwidth) {
113 case BANDWIDTH_8_MHZ: bwbuf[1] = 8; break;
114 case BANDWIDTH_7_MHZ: bwbuf[1] = 7; break;
115 case BANDWIDTH_6_MHZ: bwbuf[1] = 6; break;
116 case BANDWIDTH_AUTO: return -EOPNOTSUPP;
117 default:
118 return -EINVAL;
119 }
120
121 dvb_usb_generic_write(state->d,bwbuf,2);
122
123 freqbuf[1] = freq & 0xff;
124 freqbuf[2] = (freq >> 8) & 0xff;
125 dvb_usb_generic_write(state->d,freqbuf,3);
126
127 for (i = 0; i < 30; i++) {
128 msleep(20);
129 dtt200u_fe_read_status(fe, &st);
130 if (st & FE_TIMEDOUT)
131 continue;
132 }
133
134 return 0;
135}
136
137static int dtt200u_fe_get_frontend(struct dvb_frontend* fe,
138 struct dvb_frontend_parameters *fep)
139{
140 struct dtt200u_fe_state *state = fe->demodulator_priv;
141 memcpy(fep,&state->fep,sizeof(struct dvb_frontend_parameters));
142 return 0;
143}
144
145static void dtt200u_fe_release(struct dvb_frontend* fe)
146{
147 struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
148 kfree(state);
149}
150
151static struct dvb_frontend_ops dtt200u_fe_ops;
152
153struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
154{
155 struct dtt200u_fe_state* state = NULL;
156
157 /* allocate memory for the internal state */
158 state = kzalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL);
159 if (state == NULL)
160 goto error;
161
162 deb_info("attaching frontend dtt200u\n");
163
164 state->d = d;
165
166 memcpy(&state->frontend.ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops));
167 state->frontend.demodulator_priv = state;
168
169 return &state->frontend;
170error:
171 return NULL;
172}
173
174static struct dvb_frontend_ops dtt200u_fe_ops = {
175 .info = {
176 .name = "WideView USB DVB-T",
177 .type = FE_OFDM,
178 .frequency_min = 44250000,
179 .frequency_max = 867250000,
180 .frequency_stepsize = 250000,
181 .caps = FE_CAN_INVERSION_AUTO |
182 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
183 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
184 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
185 FE_CAN_TRANSMISSION_MODE_AUTO |
186 FE_CAN_GUARD_INTERVAL_AUTO |
187 FE_CAN_RECOVER |
188 FE_CAN_HIERARCHY_AUTO,
189 },
190
191 .release = dtt200u_fe_release,
192
193 .init = dtt200u_fe_init,
194 .sleep = dtt200u_fe_sleep,
195
196 .set_frontend = dtt200u_fe_set_frontend,
197 .get_frontend = dtt200u_fe_get_frontend,
198 .get_tune_settings = dtt200u_fe_get_tune_settings,
199
200 .read_status = dtt200u_fe_read_status,
201 .read_ber = dtt200u_fe_read_ber,
202 .read_signal_strength = dtt200u_fe_read_signal_strength,
203 .read_snr = dtt200u_fe_read_snr,
204 .read_ucblocks = dtt200u_fe_read_unc_blocks,
205};
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
new file mode 100644
index 00000000000..ecd86eca254
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -0,0 +1,375 @@
1/* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/
2 * Typhoon/ Yuan/ Miglia DVB-T USB2.0 receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to Steve Chang from WideView for providing support for the WT-220U.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#include "dtt200u.h"
15
16/* debug */
17int dvb_usb_dtt200u_debug;
18module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644);
19MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
20
21DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
22
23static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
24{
25 u8 b = SET_INIT;
26
27 if (onoff)
28 dvb_usb_generic_write(d,&b,2);
29
30 return 0;
31}
32
33static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
34{
35 u8 b_streaming[2] = { SET_STREAMING, onoff };
36 u8 b_rst_pid = RESET_PID_FILTER;
37
38 dvb_usb_generic_write(adap->dev, b_streaming, 2);
39
40 if (onoff == 0)
41 dvb_usb_generic_write(adap->dev, &b_rst_pid, 1);
42 return 0;
43}
44
45static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
46{
47 u8 b_pid[4];
48 pid = onoff ? pid : 0;
49
50 b_pid[0] = SET_PID_FILTER;
51 b_pid[1] = index;
52 b_pid[2] = pid & 0xff;
53 b_pid[3] = (pid >> 8) & 0x1f;
54
55 return dvb_usb_generic_write(adap->dev, b_pid, 4);
56}
57
58/* remote control */
59/* key list for the tiny remote control (Yakumo, don't know about the others) */
60static struct rc_map_table rc_map_dtt200u_table[] = {
61 { 0x8001, KEY_MUTE },
62 { 0x8002, KEY_CHANNELDOWN },
63 { 0x8003, KEY_VOLUMEDOWN },
64 { 0x8004, KEY_1 },
65 { 0x8005, KEY_2 },
66 { 0x8006, KEY_3 },
67 { 0x8007, KEY_4 },
68 { 0x8008, KEY_5 },
69 { 0x8009, KEY_6 },
70 { 0x800a, KEY_7 },
71 { 0x800c, KEY_ZOOM },
72 { 0x800d, KEY_0 },
73 { 0x800e, KEY_SELECT },
74 { 0x8012, KEY_POWER },
75 { 0x801a, KEY_CHANNELUP },
76 { 0x801b, KEY_8 },
77 { 0x801e, KEY_VOLUMEUP },
78 { 0x801f, KEY_9 },
79};
80
81static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
82{
83 u8 key[5],cmd = GET_RC_CODE;
84 dvb_usb_generic_rw(d,&cmd,1,key,5,0);
85 dvb_usb_nec_rc_key_to_event(d,key,event,state);
86 if (key[0] != 0)
87 deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
88 return 0;
89}
90
91static int dtt200u_frontend_attach(struct dvb_usb_adapter *adap)
92{
93 adap->fe = dtt200u_fe_attach(adap->dev);
94 return 0;
95}
96
97static struct dvb_usb_device_properties dtt200u_properties;
98static struct dvb_usb_device_properties wt220u_fc_properties;
99static struct dvb_usb_device_properties wt220u_properties;
100static struct dvb_usb_device_properties wt220u_zl0353_properties;
101static struct dvb_usb_device_properties wt220u_miglia_properties;
102
103static int dtt200u_usb_probe(struct usb_interface *intf,
104 const struct usb_device_id *id)
105{
106 if (0 == dvb_usb_device_init(intf, &dtt200u_properties,
107 THIS_MODULE, NULL, adapter_nr) ||
108 0 == dvb_usb_device_init(intf, &wt220u_properties,
109 THIS_MODULE, NULL, adapter_nr) ||
110 0 == dvb_usb_device_init(intf, &wt220u_fc_properties,
111 THIS_MODULE, NULL, adapter_nr) ||
112 0 == dvb_usb_device_init(intf, &wt220u_zl0353_properties,
113 THIS_MODULE, NULL, adapter_nr) ||
114 0 == dvb_usb_device_init(intf, &wt220u_miglia_properties,
115 THIS_MODULE, NULL, adapter_nr))
116 return 0;
117
118 return -ENODEV;
119}
120
121static struct usb_device_id dtt200u_usb_table [] = {
122 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
123 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
124 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) },
125 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
126 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_COLD) },
127 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_WARM) },
128 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_COLD) },
129 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_WARM) },
130 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZAP250_COLD) },
131 { USB_DEVICE(USB_VID_MIGLIA, USB_PID_WT220U_ZAP250_COLD) },
132 { 0 },
133};
134MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
135
136static struct dvb_usb_device_properties dtt200u_properties = {
137 .usb_ctrl = CYPRESS_FX2,
138 .firmware = "dvb-usb-dtt200u-01.fw",
139
140 .num_adapters = 1,
141 .adapter = {
142 {
143 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
144 .pid_filter_count = 15,
145
146 .streaming_ctrl = dtt200u_streaming_ctrl,
147 .pid_filter = dtt200u_pid_filter,
148 .frontend_attach = dtt200u_frontend_attach,
149 /* parameter for the MPEG2-data transfer */
150 .stream = {
151 .type = USB_BULK,
152 .count = 7,
153 .endpoint = 0x02,
154 .u = {
155 .bulk = {
156 .buffersize = 4096,
157 }
158 }
159 },
160 }
161 },
162 .power_ctrl = dtt200u_power_ctrl,
163
164 .rc.legacy = {
165 .rc_interval = 300,
166 .rc_map_table = rc_map_dtt200u_table,
167 .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
168 .rc_query = dtt200u_rc_query,
169 },
170
171 .generic_bulk_ctrl_endpoint = 0x01,
172
173 .num_device_descs = 1,
174 .devices = {
175 { .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)",
176 .cold_ids = { &dtt200u_usb_table[0], NULL },
177 .warm_ids = { &dtt200u_usb_table[1], NULL },
178 },
179 { NULL },
180 }
181};
182
183static struct dvb_usb_device_properties wt220u_properties = {
184 .usb_ctrl = CYPRESS_FX2,
185 .firmware = "dvb-usb-wt220u-02.fw",
186
187 .num_adapters = 1,
188 .adapter = {
189 {
190 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
191 .pid_filter_count = 15,
192
193 .streaming_ctrl = dtt200u_streaming_ctrl,
194 .pid_filter = dtt200u_pid_filter,
195 .frontend_attach = dtt200u_frontend_attach,
196 /* parameter for the MPEG2-data transfer */
197 .stream = {
198 .type = USB_BULK,
199 .count = 7,
200 .endpoint = 0x02,
201 .u = {
202 .bulk = {
203 .buffersize = 4096,
204 }
205 }
206 },
207 }
208 },
209 .power_ctrl = dtt200u_power_ctrl,
210
211 .rc.legacy = {
212 .rc_interval = 300,
213 .rc_map_table = rc_map_dtt200u_table,
214 .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
215 .rc_query = dtt200u_rc_query,
216 },
217
218 .generic_bulk_ctrl_endpoint = 0x01,
219
220 .num_device_descs = 1,
221 .devices = {
222 { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
223 .cold_ids = { &dtt200u_usb_table[2], &dtt200u_usb_table[8], NULL },
224 .warm_ids = { &dtt200u_usb_table[3], NULL },
225 },
226 { NULL },
227 }
228};
229
230static struct dvb_usb_device_properties wt220u_fc_properties = {
231 .usb_ctrl = CYPRESS_FX2,
232 .firmware = "dvb-usb-wt220u-fc03.fw",
233
234 .num_adapters = 1,
235 .adapter = {
236 {
237 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
238 .pid_filter_count = 15,
239
240 .streaming_ctrl = dtt200u_streaming_ctrl,
241 .pid_filter = dtt200u_pid_filter,
242 .frontend_attach = dtt200u_frontend_attach,
243 /* parameter for the MPEG2-data transfer */
244 .stream = {
245 .type = USB_BULK,
246 .count = 7,
247 .endpoint = 0x06,
248 .u = {
249 .bulk = {
250 .buffersize = 4096,
251 }
252 }
253 },
254 }
255 },
256 .power_ctrl = dtt200u_power_ctrl,
257
258 .rc.legacy = {
259 .rc_interval = 300,
260 .rc_map_table = rc_map_dtt200u_table,
261 .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
262 .rc_query = dtt200u_rc_query,
263 },
264
265 .generic_bulk_ctrl_endpoint = 0x01,
266
267 .num_device_descs = 1,
268 .devices = {
269 { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
270 .cold_ids = { &dtt200u_usb_table[6], NULL },
271 .warm_ids = { &dtt200u_usb_table[7], NULL },
272 },
273 { NULL },
274 }
275};
276
277static struct dvb_usb_device_properties wt220u_zl0353_properties = {
278 .usb_ctrl = CYPRESS_FX2,
279 .firmware = "dvb-usb-wt220u-zl0353-01.fw",
280
281 .num_adapters = 1,
282 .adapter = {
283 {
284 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
285 .pid_filter_count = 15,
286
287 .streaming_ctrl = dtt200u_streaming_ctrl,
288 .pid_filter = dtt200u_pid_filter,
289 .frontend_attach = dtt200u_frontend_attach,
290 /* parameter for the MPEG2-data transfer */
291 .stream = {
292 .type = USB_BULK,
293 .count = 7,
294 .endpoint = 0x02,
295 .u = {
296 .bulk = {
297 .buffersize = 4096,
298 }
299 }
300 },
301 }
302 },
303 .power_ctrl = dtt200u_power_ctrl,
304
305 .rc.legacy = {
306 .rc_interval = 300,
307 .rc_map_table = rc_map_dtt200u_table,
308 .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
309 .rc_query = dtt200u_rc_query,
310 },
311
312 .generic_bulk_ctrl_endpoint = 0x01,
313
314 .num_device_descs = 1,
315 .devices = {
316 { .name = "WideView WT-220U PenType Receiver (based on ZL353)",
317 .cold_ids = { &dtt200u_usb_table[4], NULL },
318 .warm_ids = { &dtt200u_usb_table[5], NULL },
319 },
320 { NULL },
321 }
322};
323
324static struct dvb_usb_device_properties wt220u_miglia_properties = {
325 .usb_ctrl = CYPRESS_FX2,
326 .firmware = "dvb-usb-wt220u-miglia-01.fw",
327
328 .num_adapters = 1,
329 .generic_bulk_ctrl_endpoint = 0x01,
330
331 .num_device_descs = 1,
332 .devices = {
333 { .name = "WideView WT-220U PenType Receiver (Miglia)",
334 .cold_ids = { &dtt200u_usb_table[9], NULL },
335 /* This device turns into WT220U_ZL0353_WARM when fw
336 has been uploaded */
337 .warm_ids = { NULL },
338 },
339 { NULL },
340 }
341};
342
343/* usb specific object needed to register this driver with the usb subsystem */
344static struct usb_driver dtt200u_usb_driver = {
345 .name = "dvb_usb_dtt200u",
346 .probe = dtt200u_usb_probe,
347 .disconnect = dvb_usb_device_exit,
348 .id_table = dtt200u_usb_table,
349};
350
351/* module stuff */
352static int __init dtt200u_usb_module_init(void)
353{
354 int result;
355 if ((result = usb_register(&dtt200u_usb_driver))) {
356 err("usb_register failed. (%d)",result);
357 return result;
358 }
359
360 return 0;
361}
362
363static void __exit dtt200u_usb_module_exit(void)
364{
365 /* deregister this driver from the USB subsystem */
366 usb_deregister(&dtt200u_usb_driver);
367}
368
369module_init(dtt200u_usb_module_init);
370module_exit(dtt200u_usb_module_exit);
371
372MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
373MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D/Miglia DVB-T USB2.0 devices");
374MODULE_VERSION("1.0");
375MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h
new file mode 100644
index 00000000000..005b0a7df35
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtt200u.h
@@ -0,0 +1,57 @@
1/* Common header file of Linux driver for the WideView/ Yakumo/ Hama/
2 * Typhoon/ Yuan DVB-T USB2.0 receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#ifndef _DVB_USB_DTT200U_H_
13#define _DVB_USB_DTT200U_H_
14
15#define DVB_USB_LOG_PREFIX "dtt200u"
16
17#include "dvb-usb.h"
18
19extern int dvb_usb_dtt200u_debug;
20#define deb_info(args...) dprintk(dvb_usb_dtt200u_debug,0x01,args)
21#define deb_xfer(args...) dprintk(dvb_usb_dtt200u_debug,0x02,args)
22
23/* guessed protocol description (reverse engineered):
24 * read
25 * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
26 * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
27 */
28
29#define GET_SPEED 0x00
30#define GET_TUNE_STATUS 0x81
31#define GET_RC_CODE 0x84
32#define GET_CONFIGURATION 0x88
33#define GET_AGC 0x89
34#define GET_SNR 0x8a
35#define GET_VIT_ERR_CNT 0x8c
36#define GET_RS_ERR_CNT 0x8d
37#define GET_RS_UNCOR_BLK_CNT 0x8e
38
39/* write
40 * 01 - init
41 * 02 - frequency (divided by 250000)
42 * 03 - bandwidth
43 * 04 - pid table (index pid(7:0) pid(12:8))
44 * 05 - reset the pid table
45 * 08 - transfer switch
46 */
47
48#define SET_INIT 0x01
49#define SET_RF_FREQ 0x02
50#define SET_BANDWIDTH 0x03
51#define SET_PID_FILTER 0x04
52#define RESET_PID_FILTER 0x05
53#define SET_STREAMING 0x08
54
55extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d);
56
57#endif
diff --git a/drivers/media/dvb/dvb-usb/dtv5100.c b/drivers/media/dvb/dvb-usb/dtv5100.c
new file mode 100644
index 00000000000..078ce92ca43
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtv5100.c
@@ -0,0 +1,240 @@
1/*
2 * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
3 *
4 * Copyright (C) 2008 Antoine Jacquet <royale@zerezo.com>
5 * http://royale.zerezo.com/dtv5100/
6 *
7 * Inspired by gl861.c and au6610.c drivers
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include "dtv5100.h"
25#include "zl10353.h"
26#include "qt1010.h"
27
28/* debug */
29static int dvb_usb_dtv5100_debug;
30module_param_named(debug, dvb_usb_dtv5100_debug, int, 0644);
31MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
32DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
33
34static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr,
35 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
36{
37 u8 request;
38 u8 type;
39 u16 value;
40 u16 index;
41
42 switch (wlen) {
43 case 1:
44 /* write { reg }, read { value } */
45 request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ :
46 DTV5100_TUNER_READ);
47 type = USB_TYPE_VENDOR | USB_DIR_IN;
48 value = 0;
49 break;
50 case 2:
51 /* write { reg, value } */
52 request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE :
53 DTV5100_TUNER_WRITE);
54 type = USB_TYPE_VENDOR | USB_DIR_OUT;
55 value = wbuf[1];
56 break;
57 default:
58 warn("wlen = %x, aborting.", wlen);
59 return -EINVAL;
60 }
61 index = (addr << 8) + wbuf[0];
62
63 msleep(1); /* avoid I2C errors */
64 return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request,
65 type, value, index, rbuf, rlen,
66 DTV5100_USB_TIMEOUT);
67}
68
69/* I2C */
70static int dtv5100_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
71 int num)
72{
73 struct dvb_usb_device *d = i2c_get_adapdata(adap);
74 int i;
75
76 if (num > 2)
77 return -EINVAL;
78
79 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
80 return -EAGAIN;
81
82 for (i = 0; i < num; i++) {
83 /* write/read request */
84 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
85 if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
86 msg[i].len, msg[i+1].buf,
87 msg[i+1].len) < 0)
88 break;
89 i++;
90 } else if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
91 msg[i].len, NULL, 0) < 0)
92 break;
93 }
94
95 mutex_unlock(&d->i2c_mutex);
96 return i;
97}
98
99static u32 dtv5100_i2c_func(struct i2c_adapter *adapter)
100{
101 return I2C_FUNC_I2C;
102}
103
104static struct i2c_algorithm dtv5100_i2c_algo = {
105 .master_xfer = dtv5100_i2c_xfer,
106 .functionality = dtv5100_i2c_func,
107};
108
109/* Callbacks for DVB USB */
110static struct zl10353_config dtv5100_zl10353_config = {
111 .demod_address = DTV5100_DEMOD_ADDR,
112 .no_tuner = 1,
113 .parallel_ts = 1,
114};
115
116static int dtv5100_frontend_attach(struct dvb_usb_adapter *adap)
117{
118 adap->fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config,
119 &adap->dev->i2c_adap);
120 if (adap->fe == NULL)
121 return -EIO;
122
123 /* disable i2c gate, or it won't work... is this safe? */
124 adap->fe->ops.i2c_gate_ctrl = NULL;
125
126 return 0;
127}
128
129static struct qt1010_config dtv5100_qt1010_config = {
130 .i2c_address = DTV5100_TUNER_ADDR
131};
132
133static int dtv5100_tuner_attach(struct dvb_usb_adapter *adap)
134{
135 return dvb_attach(qt1010_attach,
136 adap->fe, &adap->dev->i2c_adap,
137 &dtv5100_qt1010_config) == NULL ? -ENODEV : 0;
138}
139
140/* DVB USB Driver stuff */
141static struct dvb_usb_device_properties dtv5100_properties;
142
143static int dtv5100_probe(struct usb_interface *intf,
144 const struct usb_device_id *id)
145{
146 int i, ret;
147 struct usb_device *udev = interface_to_usbdev(intf);
148
149 /* initialize non qt1010/zl10353 part? */
150 for (i = 0; dtv5100_init[i].request; i++) {
151 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
152 dtv5100_init[i].request,
153 USB_TYPE_VENDOR | USB_DIR_OUT,
154 dtv5100_init[i].value,
155 dtv5100_init[i].index, NULL, 0,
156 DTV5100_USB_TIMEOUT);
157 if (ret)
158 return ret;
159 }
160
161 ret = dvb_usb_device_init(intf, &dtv5100_properties,
162 THIS_MODULE, NULL, adapter_nr);
163 if (ret)
164 return ret;
165
166 return 0;
167}
168
169static struct usb_device_id dtv5100_table[] = {
170 { USB_DEVICE(0x06be, 0xa232) },
171 { } /* Terminating entry */
172};
173MODULE_DEVICE_TABLE(usb, dtv5100_table);
174
175static struct dvb_usb_device_properties dtv5100_properties = {
176 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
177 .usb_ctrl = DEVICE_SPECIFIC,
178
179 .size_of_priv = 0,
180
181 .num_adapters = 1,
182 .adapter = {{
183 .frontend_attach = dtv5100_frontend_attach,
184 .tuner_attach = dtv5100_tuner_attach,
185
186 .stream = {
187 .type = USB_BULK,
188 .count = 8,
189 .endpoint = 0x82,
190 .u = {
191 .bulk = {
192 .buffersize = 4096,
193 }
194 }
195 },
196 } },
197
198 .i2c_algo = &dtv5100_i2c_algo,
199
200 .num_device_descs = 1,
201 .devices = {
202 {
203 .name = "AME DTV-5100 USB2.0 DVB-T",
204 .cold_ids = { NULL },
205 .warm_ids = { &dtv5100_table[0], NULL },
206 },
207 }
208};
209
210static struct usb_driver dtv5100_driver = {
211 .name = "dvb_usb_dtv5100",
212 .probe = dtv5100_probe,
213 .disconnect = dvb_usb_device_exit,
214 .id_table = dtv5100_table,
215};
216
217/* module stuff */
218static int __init dtv5100_module_init(void)
219{
220 int ret;
221
222 ret = usb_register(&dtv5100_driver);
223 if (ret)
224 err("usb_register failed. Error number %d", ret);
225
226 return ret;
227}
228
229static void __exit dtv5100_module_exit(void)
230{
231 /* deregister this driver from the USB subsystem */
232 usb_deregister(&dtv5100_driver);
233}
234
235module_init(dtv5100_module_init);
236module_exit(dtv5100_module_exit);
237
238MODULE_AUTHOR(DRIVER_AUTHOR);
239MODULE_DESCRIPTION(DRIVER_DESC);
240MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dtv5100.h b/drivers/media/dvb/dvb-usb/dtv5100.h
new file mode 100644
index 00000000000..93e96e04a82
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dtv5100.h
@@ -0,0 +1,51 @@
1/*
2 * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
3 *
4 * Copyright (C) 2008 Antoine Jacquet <royale@zerezo.com>
5 * http://royale.zerezo.com/dtv5100/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef _DVB_USB_DTV5100_H_
23#define _DVB_USB_DTV5100_H_
24
25#define DVB_USB_LOG_PREFIX "dtv5100"
26#include "dvb-usb.h"
27
28#define DTV5100_USB_TIMEOUT 500
29
30#define DTV5100_DEMOD_ADDR 0x00
31#define DTV5100_DEMOD_WRITE 0xc0
32#define DTV5100_DEMOD_READ 0xc1
33
34#define DTV5100_TUNER_ADDR 0xc4
35#define DTV5100_TUNER_WRITE 0xc7
36#define DTV5100_TUNER_READ 0xc8
37
38#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
39#define DRIVER_DESC "AME DTV-5100 USB2.0 DVB-T"
40
41static struct {
42 u8 request;
43 u8 value;
44 u16 index;
45} dtv5100_init[] = {
46 { 0x000000c5, 0x00000000, 0x00000001 },
47 { 0x000000c5, 0x00000001, 0x00000001 },
48 { } /* Terminating entry */
49};
50
51#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
new file mode 100644
index 00000000000..6b7b2a89242
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-common.h
@@ -0,0 +1,52 @@
1/* dvb-usb-common.h is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * a header file containing prototypes and types for internal use of the dvb-usb-lib
7 */
8#ifndef _DVB_USB_COMMON_H_
9#define _DVB_USB_COMMON_H_
10
11#define DVB_USB_LOG_PREFIX "dvb-usb"
12#include "dvb-usb.h"
13
14extern int dvb_usb_debug;
15extern int dvb_usb_disable_rc_polling;
16
17#define deb_info(args...) dprintk(dvb_usb_debug,0x001,args)
18#define deb_xfer(args...) dprintk(dvb_usb_debug,0x002,args)
19#define deb_pll(args...) dprintk(dvb_usb_debug,0x004,args)
20#define deb_ts(args...) dprintk(dvb_usb_debug,0x008,args)
21#define deb_err(args...) dprintk(dvb_usb_debug,0x010,args)
22#define deb_rc(args...) dprintk(dvb_usb_debug,0x020,args)
23#define deb_fw(args...) dprintk(dvb_usb_debug,0x040,args)
24#define deb_mem(args...) dprintk(dvb_usb_debug,0x080,args)
25#define deb_uxfer(args...) dprintk(dvb_usb_debug,0x100,args)
26
27/* commonly used methods */
28extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_device_properties *);
29
30extern int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff);
31
32extern int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props);
33extern int usb_urb_exit(struct usb_data_stream *stream);
34extern int usb_urb_submit(struct usb_data_stream *stream);
35extern int usb_urb_kill(struct usb_data_stream *stream);
36
37extern int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap);
38extern int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap);
39
40extern int dvb_usb_i2c_init(struct dvb_usb_device *);
41extern int dvb_usb_i2c_exit(struct dvb_usb_device *);
42
43extern int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap,
44 short *adapter_nums);
45extern int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap);
46extern int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap);
47extern int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap);
48
49extern int dvb_usb_remote_init(struct dvb_usb_device *);
50extern int dvb_usb_remote_exit(struct dvb_usb_device *);
51
52#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
new file mode 100644
index 00000000000..b3cb626ed56
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
@@ -0,0 +1,216 @@
1/* dvb-usb-dvb.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for initializing and handling the
7 * linux-dvb API.
8 */
9#include "dvb-usb-common.h"
10
11/* does the complete input transfer handling */
12static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
13{
14 struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
15 int newfeedcount, ret;
16
17 if (adap == NULL)
18 return -ENODEV;
19
20 newfeedcount = adap->feedcount + (onoff ? 1 : -1);
21
22 /* stop feed before setting a new pid if there will be no pid anymore */
23 if (newfeedcount == 0) {
24 deb_ts("stop feeding\n");
25 usb_urb_kill(&adap->stream);
26
27 if (adap->props.streaming_ctrl != NULL) {
28 ret = adap->props.streaming_ctrl(adap, 0);
29 if (ret < 0) {
30 err("error while stopping stream.");
31 return ret;
32 }
33 }
34 }
35
36 adap->feedcount = newfeedcount;
37
38 /* activate the pid on the device specific pid_filter */
39 deb_ts("setting pid (%s): %5d %04x at index %d '%s'\n",adap->pid_filtering ?
40 "yes" : "no", dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ?
41 "on" : "off");
42 if (adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER &&
43 adap->pid_filtering &&
44 adap->props.pid_filter != NULL)
45 adap->props.pid_filter(adap, dvbdmxfeed->index, dvbdmxfeed->pid,onoff);
46
47 /* start the feed if this was the first feed and there is still a feed
48 * for reception.
49 */
50 if (adap->feedcount == onoff && adap->feedcount > 0) {
51 deb_ts("submitting all URBs\n");
52 usb_urb_submit(&adap->stream);
53
54 deb_ts("controlling pid parser\n");
55 if (adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER &&
56 adap->props.caps &
57 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
58 adap->props.pid_filter_ctrl != NULL) {
59 ret = adap->props.pid_filter_ctrl(adap,
60 adap->pid_filtering);
61 if (ret < 0) {
62 err("could not handle pid_parser");
63 return ret;
64 }
65 }
66 deb_ts("start feeding\n");
67 if (adap->props.streaming_ctrl != NULL) {
68 ret = adap->props.streaming_ctrl(adap, 1);
69 if (ret < 0) {
70 err("error while enabling fifo.");
71 return ret;
72 }
73 }
74
75 }
76 return 0;
77}
78
79static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
80{
81 deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
82 return dvb_usb_ctrl_feed(dvbdmxfeed,1);
83}
84
85static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
86{
87 deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
88 return dvb_usb_ctrl_feed(dvbdmxfeed,0);
89}
90
91int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums)
92{
93 int ret = dvb_register_adapter(&adap->dvb_adap, adap->dev->desc->name,
94 adap->dev->owner, &adap->dev->udev->dev,
95 adapter_nums);
96
97 if (ret < 0) {
98 deb_info("dvb_register_adapter failed: error %d", ret);
99 goto err;
100 }
101 adap->dvb_adap.priv = adap;
102 adap->dvb_adap.fe_ioctl_override = adap->props.fe_ioctl_override;
103
104 if (adap->dev->props.read_mac_address) {
105 if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0)
106 info("MAC address: %pM",adap->dvb_adap.proposed_mac);
107 else
108 err("MAC address reading failed.");
109 }
110
111
112 adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
113 adap->demux.priv = adap;
114
115 adap->demux.feednum = adap->demux.filternum = adap->max_feed_count;
116 adap->demux.start_feed = dvb_usb_start_feed;
117 adap->demux.stop_feed = dvb_usb_stop_feed;
118 adap->demux.write_to_decoder = NULL;
119 if ((ret = dvb_dmx_init(&adap->demux)) < 0) {
120 err("dvb_dmx_init failed: error %d",ret);
121 goto err_dmx;
122 }
123
124 adap->dmxdev.filternum = adap->demux.filternum;
125 adap->dmxdev.demux = &adap->demux.dmx;
126 adap->dmxdev.capabilities = 0;
127 if ((ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap)) < 0) {
128 err("dvb_dmxdev_init failed: error %d",ret);
129 goto err_dmx_dev;
130 }
131
132 dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
133
134 adap->state |= DVB_USB_ADAP_STATE_DVB;
135 return 0;
136
137err_dmx_dev:
138 dvb_dmx_release(&adap->demux);
139err_dmx:
140 dvb_unregister_adapter(&adap->dvb_adap);
141err:
142 return ret;
143}
144
145int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap)
146{
147 if (adap->state & DVB_USB_ADAP_STATE_DVB) {
148 deb_info("unregistering DVB part\n");
149 dvb_net_release(&adap->dvb_net);
150 adap->demux.dmx.close(&adap->demux.dmx);
151 dvb_dmxdev_release(&adap->dmxdev);
152 dvb_dmx_release(&adap->demux);
153 dvb_unregister_adapter(&adap->dvb_adap);
154 adap->state &= ~DVB_USB_ADAP_STATE_DVB;
155 }
156 return 0;
157}
158
159static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
160{
161 struct dvb_usb_adapter *adap = fe->dvb->priv;
162
163 dvb_usb_device_power_ctrl(adap->dev, 1);
164
165 if (adap->fe_init)
166 adap->fe_init(fe);
167
168 return 0;
169}
170
171static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
172{
173 struct dvb_usb_adapter *adap = fe->dvb->priv;
174
175 if (adap->fe_sleep)
176 adap->fe_sleep(fe);
177
178 return dvb_usb_device_power_ctrl(adap->dev, 0);
179}
180
181int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
182{
183 if (adap->props.frontend_attach == NULL) {
184 err("strange: '%s' #%d doesn't want to attach a frontend.",adap->dev->desc->name, adap->id);
185 return 0;
186 }
187
188 /* re-assign sleep and wakeup functions */
189 if (adap->props.frontend_attach(adap) == 0 && adap->fe != NULL) {
190 adap->fe_init = adap->fe->ops.init; adap->fe->ops.init = dvb_usb_fe_wakeup;
191 adap->fe_sleep = adap->fe->ops.sleep; adap->fe->ops.sleep = dvb_usb_fe_sleep;
192
193 if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) {
194 err("Frontend registration failed.");
195 dvb_frontend_detach(adap->fe);
196 adap->fe = NULL;
197 return -ENODEV;
198 }
199
200 /* only attach the tuner if the demod is there */
201 if (adap->props.tuner_attach != NULL)
202 adap->props.tuner_attach(adap);
203 } else
204 err("no frontend was attached by '%s'",adap->dev->desc->name);
205
206 return 0;
207}
208
209int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap)
210{
211 if (adap->fe != NULL) {
212 dvb_unregister_frontend(adap->fe);
213 dvb_frontend_detach(adap->fe);
214 }
215 return 0;
216}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
new file mode 100644
index 00000000000..733a7ff7b20
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c
@@ -0,0 +1,146 @@
1/* dvb-usb-firmware.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for downloading the firmware to Cypress FX 1 and 2 based devices.
7 *
8 * FIXME: This part does actually not belong to dvb-usb, but to the usb-subsystem.
9 */
10#include "dvb-usb-common.h"
11
12#include <linux/usb.h>
13
14struct usb_cypress_controller {
15 int id;
16 const char *name; /* name of the usb controller */
17 u16 cpu_cs_register; /* needs to be restarted, when the firmware has been downloaded. */
18};
19
20static struct usb_cypress_controller cypress[] = {
21 { .id = DEVICE_SPECIFIC, .name = "Device specific", .cpu_cs_register = 0 },
22 { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
23 { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
24 { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 },
25};
26
27/*
28 * load a firmware packet to the device
29 */
30static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
31{
32 return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
33 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
34}
35
36int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type)
37{
38 struct hexline hx;
39 u8 reset;
40 int ret,pos=0;
41
42 /* stop the CPU */
43 reset = 1;
44 if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
45 err("could not stop the USB controller CPU.");
46
47 while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) {
48 deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk);
49 ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len);
50
51 if (ret != hx.len) {
52 err("error while transferring firmware "
53 "(transferred size: %d, block size: %d)",
54 ret,hx.len);
55 ret = -EINVAL;
56 break;
57 }
58 }
59 if (ret < 0) {
60 err("firmware download failed at %d with %d",pos,ret);
61 return ret;
62 }
63
64 if (ret == 0) {
65 /* restart the CPU */
66 reset = 0;
67 if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
68 err("could not restart the USB controller CPU.");
69 ret = -EINVAL;
70 }
71 } else
72 ret = -EIO;
73
74 return ret;
75}
76EXPORT_SYMBOL(usb_cypress_load_firmware);
77
78int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_device_properties *props)
79{
80 int ret;
81 const struct firmware *fw = NULL;
82
83 if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) {
84 err("did not find the firmware file. (%s) "
85 "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
86 props->firmware,ret);
87 return ret;
88 }
89
90 info("downloading firmware from file '%s'",props->firmware);
91
92 switch (props->usb_ctrl) {
93 case CYPRESS_AN2135:
94 case CYPRESS_AN2235:
95 case CYPRESS_FX2:
96 ret = usb_cypress_load_firmware(udev, fw, props->usb_ctrl);
97 break;
98 case DEVICE_SPECIFIC:
99 if (props->download_firmware)
100 ret = props->download_firmware(udev,fw);
101 else {
102 err("BUG: driver didn't specified a download_firmware-callback, although it claims to have a DEVICE_SPECIFIC one.");
103 ret = -EINVAL;
104 }
105 break;
106 default:
107 ret = -EINVAL;
108 break;
109 }
110
111 release_firmware(fw);
112 return ret;
113}
114
115int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
116 int *pos)
117{
118 u8 *b = (u8 *) &fw->data[*pos];
119 int data_offs = 4;
120 if (*pos >= fw->size)
121 return 0;
122
123 memset(hx,0,sizeof(struct hexline));
124
125 hx->len = b[0];
126
127 if ((*pos + hx->len + 4) >= fw->size)
128 return -EINVAL;
129
130 hx->addr = b[1] | (b[2] << 8);
131 hx->type = b[3];
132
133 if (hx->type == 0x04) {
134 /* b[4] and b[5] are the Extended linear address record data field */
135 hx->addr |= (b[4] << 24) | (b[5] << 16);
136/* hx->len -= 2;
137 data_offs += 2; */
138 }
139 memcpy(hx->data,&b[data_offs],hx->len);
140 hx->chk = b[hx->len + data_offs];
141
142 *pos += hx->len + 5;
143
144 return *pos;
145}
146EXPORT_SYMBOL(dvb_usb_get_hexline);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
new file mode 100644
index 00000000000..88e4a62abc4
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -0,0 +1,43 @@
1/* dvb-usb-i2c.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for (de-)initializing an I2C adapter.
7 */
8#include "dvb-usb-common.h"
9
10int dvb_usb_i2c_init(struct dvb_usb_device *d)
11{
12 int ret = 0;
13
14 if (!(d->props.caps & DVB_USB_IS_AN_I2C_ADAPTER))
15 return 0;
16
17 if (d->props.i2c_algo == NULL) {
18 err("no i2c algorithm specified");
19 return -EINVAL;
20 }
21
22 strlcpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
23 d->i2c_adap.algo = d->props.i2c_algo;
24 d->i2c_adap.algo_data = NULL;
25 d->i2c_adap.dev.parent = &d->udev->dev;
26
27 i2c_set_adapdata(&d->i2c_adap, d);
28
29 if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0)
30 err("could not add i2c adapter");
31
32 d->state |= DVB_USB_STATE_I2C;
33
34 return ret;
35}
36
37int dvb_usb_i2c_exit(struct dvb_usb_device *d)
38{
39 if (d->state & DVB_USB_STATE_I2C)
40 i2c_del_adapter(&d->i2c_adap);
41 d->state &= ~DVB_USB_STATE_I2C;
42 return 0;
43}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
new file mode 100644
index 00000000000..2a79b8fb3e8
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -0,0 +1,326 @@
1/* dvb-usb-ids.h is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) see
4 * dvb-usb-init.c for copyright information.
5 *
6 * a header file containing define's for the USB device supported by the
7 * various drivers.
8 */
9#ifndef _DVB_USB_IDS_H_
10#define _DVB_USB_IDS_H_
11
12/* Vendor IDs */
13#define USB_VID_ADSTECH 0x06e1
14#define USB_VID_AFATECH 0x15a4
15#define USB_VID_ALCOR_MICRO 0x058f
16#define USB_VID_ALINK 0x05e3
17#define USB_VID_AMT 0x1c73
18#define USB_VID_ANCHOR 0x0547
19#define USB_VID_ANSONIC 0x10b9
20#define USB_VID_ANUBIS_ELECTRONIC 0x10fd
21#define USB_VID_ASUS 0x0b05
22#define USB_VID_AVERMEDIA 0x07ca
23#define USB_VID_COMPRO 0x185b
24#define USB_VID_COMPRO_UNK 0x145f
25#define USB_VID_CONEXANT 0x0572
26#define USB_VID_CYPRESS 0x04b4
27#define USB_VID_DIBCOM 0x10b8
28#define USB_VID_DPOSH 0x1498
29#define USB_VID_DVICO 0x0fe9
30#define USB_VID_E3C 0x18b4
31#define USB_VID_ELGATO 0x0fd9
32#define USB_VID_EMPIA 0xeb1a
33#define USB_VID_GENPIX 0x09c0
34#define USB_VID_GRANDTEC 0x5032
35#define USB_VID_GTEK 0x1f4d
36#define USB_VID_HANFTEK 0x15f4
37#define USB_VID_HAUPPAUGE 0x2040
38#define USB_VID_HYPER_PALTEK 0x1025
39#define USB_VID_INTEL 0x8086
40#define USB_VID_KWORLD 0xeb2a
41#define USB_VID_KWORLD_2 0x1b80
42#define USB_VID_KYE 0x0458
43#define USB_VID_LEADTEK 0x0413
44#define USB_VID_LITEON 0x04ca
45#define USB_VID_MEDION 0x1660
46#define USB_VID_MIGLIA 0x18f3
47#define USB_VID_MSI 0x0db0
48#define USB_VID_MSI_2 0x1462
49#define USB_VID_OPERA1 0x695c
50#define USB_VID_PINNACLE 0x2304
51#define USB_VID_PCTV 0x2013
52#define USB_VID_PIXELVIEW 0x1554
53#define USB_VID_TECHNOTREND 0x0b48
54#define USB_VID_TERRATEC 0x0ccd
55#define USB_VID_TELESTAR 0x10b9
56#define USB_VID_VISIONPLUS 0x13d3
57#define USB_VID_SONY 0x1415
58#define USB_VID_TWINHAN 0x1822
59#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
60#define USB_VID_UNIWILL 0x1584
61#define USB_VID_WIDEVIEW 0x14aa
62#define USB_VID_GIGABYTE 0x1044
63#define USB_VID_YUAN 0x1164
64#define USB_VID_XTENSIONS 0x1ae7
65#define USB_VID_HUMAX_COEX 0x10b9
66#define USB_VID_774 0x7a69
67#define USB_VID_EVOLUTEPC 0x1e59
68#define USB_VID_AZUREWAVE 0x13d3
69#define USB_VID_TECHNISAT 0x14f7
70
71/* Product IDs */
72#define USB_PID_ADSTECH_USB2_COLD 0xa333
73#define USB_PID_ADSTECH_USB2_WARM 0xa334
74#define USB_PID_AFATECH_AF9005 0x9020
75#define USB_PID_AFATECH_AF9015_9015 0x9015
76#define USB_PID_AFATECH_AF9015_9016 0x9016
77#define USB_PID_TREKSTOR_DVBT 0x901b
78#define USB_VID_ALINK_DTU 0xf170
79#define USB_PID_ANSONIC_DVBT_USB 0x6000
80#define USB_PID_ANYSEE 0x861f
81#define USB_PID_AZUREWAVE_AD_TU700 0x3237
82#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
83#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
84#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800
85#define USB_PID_AVERMEDIA_DVBT_USB2_WARM 0xa801
86#define USB_PID_COMPRO_DVBU2000_COLD 0xd000
87#define USB_PID_COMPRO_DVBU2000_WARM 0xd001
88#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c
89#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d
90#define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78
91#define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80
92#define USB_PID_CONCEPTRONIC_CTVDIGRCU 0xe397
93#define USB_PID_CONEXANT_D680_DMB 0x86d6
94#define USB_PID_CREATIX_CTX1921 0x1921
95#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
96#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
97#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
98#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9
99#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6
100#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7
101#define USB_PID_DIBCOM_STK7700P 0x1e14
102#define USB_PID_DIBCOM_STK7700P_PC 0x1e78
103#define USB_PID_DIBCOM_STK7700D 0x1ef0
104#define USB_PID_DIBCOM_STK7700_U7000 0x7001
105#define USB_PID_DIBCOM_STK7070P 0x1ebc
106#define USB_PID_DIBCOM_STK7070PD 0x1ebe
107#define USB_PID_DIBCOM_STK807XP 0x1f90
108#define USB_PID_DIBCOM_STK807XPVR 0x1f98
109#define USB_PID_DIBCOM_STK8096GP 0x1fa0
110#define USB_PID_DIBCOM_NIM8096MD 0x1fa8
111#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
112#define USB_PID_DIBCOM_STK7770P 0x1e80
113#define USB_PID_DIBCOM_NIM7090 0x1bb2
114#define USB_PID_DIBCOM_TFE7090PVR 0x1bb4
115#define USB_PID_DIBCOM_NIM9090M 0x2383
116#define USB_PID_DIBCOM_NIM9090MD 0x2384
117#define USB_PID_DPOSH_M9206_COLD 0x9206
118#define USB_PID_DPOSH_M9206_WARM 0xa090
119#define USB_PID_E3C_EC168 0x1689
120#define USB_PID_E3C_EC168_2 0xfffa
121#define USB_PID_E3C_EC168_3 0xfffb
122#define USB_PID_E3C_EC168_4 0x1001
123#define USB_PID_E3C_EC168_5 0x1002
124#define USB_PID_UNIWILL_STK7700P 0x6003
125#define USB_PID_GENIUS_TVGO_DVB_T03 0x4012
126#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
127#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
128#define USB_PID_INTEL_CE9500 0x9500
129#define USB_PID_KWORLD_399U 0xe399
130#define USB_PID_KWORLD_399U_2 0xe400
131#define USB_PID_KWORLD_395U 0xe396
132#define USB_PID_KWORLD_395U_2 0xe39b
133#define USB_PID_KWORLD_395U_3 0xe395
134#define USB_PID_KWORLD_395U_4 0xe39a
135#define USB_PID_KWORLD_MC810 0xc810
136#define USB_PID_KWORLD_PC160_2T 0xc160
137#define USB_PID_KWORLD_PC160_T 0xc161
138#define USB_PID_KWORLD_UB383_T 0xe383
139#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
140#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
141#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055
142#define USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2 0x0069
143#define USB_PID_TERRATEC_CINERGY_T_STICK_RC 0x0097
144#define USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC 0x0099
145#define USB_PID_TWINHAN_VP7041_COLD 0x3201
146#define USB_PID_TWINHAN_VP7041_WARM 0x3202
147#define USB_PID_TWINHAN_VP7020_COLD 0x3203
148#define USB_PID_TWINHAN_VP7020_WARM 0x3204
149#define USB_PID_TWINHAN_VP7045_COLD 0x3205
150#define USB_PID_TWINHAN_VP7045_WARM 0x3206
151#define USB_PID_TWINHAN_VP7021_COLD 0x3207
152#define USB_PID_TWINHAN_VP7021_WARM 0x3208
153#define USB_PID_TINYTWIN 0x3226
154#define USB_PID_TINYTWIN_2 0xe402
155#define USB_PID_TINYTWIN_3 0x9016
156#define USB_PID_DNTV_TINYUSB2_COLD 0x3223
157#define USB_PID_DNTV_TINYUSB2_WARM 0x3224
158#define USB_PID_ULTIMA_TVBOX_COLD 0x8105
159#define USB_PID_ULTIMA_TVBOX_WARM 0x8106
160#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107
161#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108
162#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235
163#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109
164#define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a
165#define USB_PID_ARTEC_T14_COLD 0x810b
166#define USB_PID_ARTEC_T14_WARM 0x810c
167#define USB_PID_ARTEC_T14BR 0x810f
168#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613
169#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002
170#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e
171#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f
172#define USB_PID_HANFTEK_UMT_010_COLD 0x0001
173#define USB_PID_HANFTEK_UMT_010_WARM 0x0015
174#define USB_PID_DTT200U_COLD 0x0201
175#define USB_PID_DTT200U_WARM 0x0301
176#define USB_PID_WT220U_ZAP250_COLD 0x0220
177#define USB_PID_WT220U_COLD 0x0222
178#define USB_PID_WT220U_WARM 0x0221
179#define USB_PID_WT220U_FC_COLD 0x0225
180#define USB_PID_WT220U_FC_WARM 0x0226
181#define USB_PID_WT220U_ZL0353_COLD 0x022a
182#define USB_PID_WT220U_ZL0353_WARM 0x022b
183#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300
184#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301
185#define USB_PID_HAUPPAUGE_NOVA_T_500 0x9941
186#define USB_PID_HAUPPAUGE_NOVA_T_500_2 0x9950
187#define USB_PID_HAUPPAUGE_NOVA_T_500_3 0x8400
188#define USB_PID_HAUPPAUGE_NOVA_T_STICK 0x7050
189#define USB_PID_HAUPPAUGE_NOVA_T_STICK_2 0x7060
190#define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070
191#define USB_PID_HAUPPAUGE_MYTV_T 0x7080
192#define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580
193#define USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009 0x5200
194#define USB_PID_HAUPPAUGE_TIGER_ATSC 0xb200
195#define USB_PID_HAUPPAUGE_TIGER_ATSC_B210 0xb210
196#define USB_PID_AVERMEDIA_EXPRESS 0xb568
197#define USB_PID_AVERMEDIA_VOLAR 0xa807
198#define USB_PID_AVERMEDIA_VOLAR_2 0xb808
199#define USB_PID_AVERMEDIA_VOLAR_A868R 0xa868
200#define USB_PID_AVERMEDIA_MCE_USB_M038 0x1228
201#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R 0x0039
202#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_ATSC 0x1039
203#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_DVBT 0x2039
204#define USB_PID_AVERMEDIA_VOLAR_X 0xa815
205#define USB_PID_AVERMEDIA_VOLAR_X_2 0x8150
206#define USB_PID_AVERMEDIA_A309 0xa309
207#define USB_PID_AVERMEDIA_A310 0xa310
208#define USB_PID_AVERMEDIA_A850 0x850a
209#define USB_PID_AVERMEDIA_A850T 0x850b
210#define USB_PID_AVERMEDIA_A805 0xa805
211#define USB_PID_AVERMEDIA_A815M 0x815a
212#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
213#define USB_PID_TECHNOTREND_CONNECT_CT3650 0x300d
214#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
215#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2 0x0081
216#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058
217#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060
218#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062
219#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078
220#define USB_PID_TERRATEC_CINERGY_T_XXS_2 0x00ab
221#define USB_PID_TERRATEC_T3 0x10a0
222#define USB_PID_TERRATEC_T5 0x10a1
223#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e
224#define USB_PID_PINNACLE_PCTV2000E 0x022c
225#define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228
226#define USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T 0x0229
227#define USB_PID_PINNACLE_PCTV71E 0x022b
228#define USB_PID_PINNACLE_PCTV72E 0x0236
229#define USB_PID_PINNACLE_PCTV73E 0x0237
230#define USB_PID_PINNACLE_PCTV310E 0x3211
231#define USB_PID_PINNACLE_PCTV801E 0x023a
232#define USB_PID_PINNACLE_PCTV801E_SE 0x023b
233#define USB_PID_PINNACLE_PCTV340E 0x023d
234#define USB_PID_PINNACLE_PCTV340E_SE 0x023e
235#define USB_PID_PINNACLE_PCTV73A 0x0243
236#define USB_PID_PINNACLE_PCTV73ESE 0x0245
237#define USB_PID_PINNACLE_PCTV74E 0x0246
238#define USB_PID_PINNACLE_PCTV282E 0x0248
239#define USB_PID_PIXELVIEW_SBTVD 0x5010
240#define USB_PID_PCTV_200E 0x020e
241#define USB_PID_PCTV_400E 0x020f
242#define USB_PID_PCTV_450E 0x0222
243#define USB_PID_NEBULA_DIGITV 0x0201
244#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820
245#define USB_PID_DVICO_BLUEBIRD_LG064F_COLD 0xd500
246#define USB_PID_DVICO_BLUEBIRD_LG064F_WARM 0xd501
247#define USB_PID_DVICO_BLUEBIRD_LGZ201_COLD 0xdb00
248#define USB_PID_DVICO_BLUEBIRD_LGZ201_WARM 0xdb01
249#define USB_PID_DVICO_BLUEBIRD_TH7579_COLD 0xdb10
250#define USB_PID_DVICO_BLUEBIRD_TH7579_WARM 0xdb11
251#define USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD 0xdb50
252#define USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM 0xdb51
253#define USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD 0xdb58
254#define USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM 0xdb59
255#define USB_PID_DVICO_BLUEBIRD_DUAL_4 0xdb78
256#define USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2 0xdb98
257#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2 0xdb70
258#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM 0xdb71
259#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD 0xdb54
260#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM 0xdb55
261#define USB_PID_MEDION_MD95700 0x0932
262#define USB_PID_MSI_MEGASKY580 0x5580
263#define USB_PID_MSI_MEGASKY580_55801 0x5581
264#define USB_PID_KYE_DVB_T_COLD 0x701e
265#define USB_PID_KYE_DVB_T_WARM 0x701f
266#define USB_PID_LITEON_DVB_T_COLD 0xf000
267#define USB_PID_LITEON_DVB_T_WARM 0xf001
268#define USB_PID_DIGIVOX_MINI_SL_COLD 0xe360
269#define USB_PID_DIGIVOX_MINI_SL_WARM 0xe361
270#define USB_PID_GRANDTEC_DVBT_USB2_COLD 0x0bc6
271#define USB_PID_GRANDTEC_DVBT_USB2_WARM 0x0bc7
272#define USB_PID_WINFAST_DTV2000DS 0x6a04
273#define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025
274#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026
275#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00
276#define USB_PID_WINFAST_DTV_DONGLE_H 0x60f6
277#define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01
278#define USB_PID_WINFAST_DTV_DONGLE_GOLD 0x6029
279#define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200
280#define USB_PID_GENPIX_8PSK_REV_1_WARM 0x0201
281#define USB_PID_GENPIX_8PSK_REV_2 0x0202
282#define USB_PID_GENPIX_SKYWALKER_1 0x0203
283#define USB_PID_GENPIX_SKYWALKER_CW3K 0x0204
284#define USB_PID_GENPIX_SKYWALKER_2 0x0206
285#define USB_PID_SIGMATEK_DVB_110 0x6610
286#define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513
287#define USB_PID_MSI_DIGIVOX_DUO 0x8801
288#define USB_PID_OPERA1_COLD 0x2830
289#define USB_PID_OPERA1_WARM 0x3829
290#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD 0x0514
291#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513
292#define USB_PID_GIGABYTE_U7000 0x7001
293#define USB_PID_GIGABYTE_U8000 0x7002
294#define USB_PID_ASUS_U3000 0x171f
295#define USB_PID_ASUS_U3000H 0x1736
296#define USB_PID_ASUS_U3100 0x173f
297#define USB_PID_YUAN_EC372S 0x1edc
298#define USB_PID_YUAN_STK7700PH 0x1f08
299#define USB_PID_YUAN_PD378S 0x2edc
300#define USB_PID_YUAN_MC770 0x0871
301#define USB_PID_YUAN_STK7700D 0x1efc
302#define USB_PID_YUAN_STK7700D_2 0x1e8c
303#define USB_PID_DW2102 0x2102
304#define USB_PID_XTENSIONS_XD_380 0x0381
305#define USB_PID_TELESTAR_STARSTICK_2 0x8000
306#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807
307#define USB_PID_SONY_PLAYTV 0x0003
308#define USB_PID_MYGICA_D689 0xd811
309#define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011
310#define USB_PID_ELGATO_EYETV_DTT 0x0021
311#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
312#define USB_PID_ELGATO_EYETV_SAT 0x002a
313#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000
314#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001
315#define USB_PID_FRIIO_WHITE 0x0001
316#define USB_PID_TVWAY_PLUS 0x0002
317#define USB_PID_SVEON_STV20 0xe39d
318#define USB_PID_SVEON_STV22 0xe401
319#define USB_PID_AZUREWAVE_AZ6027 0x3275
320#define USB_PID_TERRATEC_DVBS2CI_V1 0x10a4
321#define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac
322#define USB_PID_TECHNISAT_USB2_HDCI_V1 0x0001
323#define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002
324#define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2 0x0004
325#define USB_PID_TECHNISAT_USB2_DVB_S2 0x0500
326#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
new file mode 100644
index 00000000000..2e3ea0fa28e
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -0,0 +1,289 @@
1/*
2 * DVB USB library - provides a generic interface for a DVB USB device driver.
3 *
4 * dvb-usb-init.c
5 *
6 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#include "dvb-usb-common.h"
15
16/* debug */
17int dvb_usb_debug;
18module_param_named(debug, dvb_usb_debug, int, 0644);
19MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64,mem=128,uxfer=256 (or-able))." DVB_USB_DEBUG_STATUS);
20
21int dvb_usb_disable_rc_polling;
22module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644);
23MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0).");
24
25static int dvb_usb_force_pid_filter_usage;
26module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444);
27MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID filter, if any (default: 0).");
28
29static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
30{
31 struct dvb_usb_adapter *adap;
32 int ret, n;
33
34 for (n = 0; n < d->props.num_adapters; n++) {
35 adap = &d->adapter[n];
36 adap->dev = d;
37 adap->id = n;
38
39 memcpy(&adap->props, &d->props.adapter[n], sizeof(struct dvb_usb_adapter_properties));
40
41 /* speed - when running at FULL speed we need a HW PID filter */
42 if (d->udev->speed == USB_SPEED_FULL && !(adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
43 err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)");
44 return -ENODEV;
45 }
46
47 if ((d->udev->speed == USB_SPEED_FULL && adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
48 (adap->props.caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
49 info("will use the device's hardware PID filter (table count: %d).", adap->props.pid_filter_count);
50 adap->pid_filtering = 1;
51 adap->max_feed_count = adap->props.pid_filter_count;
52 } else {
53 info("will pass the complete MPEG2 transport stream to the software demuxer.");
54 adap->pid_filtering = 0;
55 adap->max_feed_count = 255;
56 }
57
58 if (!adap->pid_filtering &&
59 dvb_usb_force_pid_filter_usage &&
60 adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER) {
61 info("pid filter enabled by module option.");
62 adap->pid_filtering = 1;
63 adap->max_feed_count = adap->props.pid_filter_count;
64 }
65
66 if (adap->props.size_of_priv > 0) {
67 adap->priv = kzalloc(adap->props.size_of_priv, GFP_KERNEL);
68 if (adap->priv == NULL) {
69 err("no memory for priv for adapter %d.", n);
70 return -ENOMEM;
71 }
72 }
73
74 if ((ret = dvb_usb_adapter_stream_init(adap)) ||
75 (ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) ||
76 (ret = dvb_usb_adapter_frontend_init(adap))) {
77 return ret;
78 }
79
80 d->num_adapters_initialized++;
81 d->state |= DVB_USB_STATE_DVB;
82 }
83
84 /*
85 * when reloading the driver w/o replugging the device
86 * sometimes a timeout occures, this helps
87 */
88 if (d->props.generic_bulk_ctrl_endpoint != 0) {
89 usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
90 usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
91 }
92
93 return 0;
94}
95
96static int dvb_usb_adapter_exit(struct dvb_usb_device *d)
97{
98 int n;
99
100 for (n = 0; n < d->num_adapters_initialized; n++) {
101 dvb_usb_adapter_frontend_exit(&d->adapter[n]);
102 dvb_usb_adapter_dvb_exit(&d->adapter[n]);
103 dvb_usb_adapter_stream_exit(&d->adapter[n]);
104 kfree(d->adapter[n].priv);
105 }
106 d->num_adapters_initialized = 0;
107 d->state &= ~DVB_USB_STATE_DVB;
108 return 0;
109}
110
111
112/* general initialization functions */
113static int dvb_usb_exit(struct dvb_usb_device *d)
114{
115 deb_info("state before exiting everything: %x\n", d->state);
116 dvb_usb_remote_exit(d);
117 dvb_usb_adapter_exit(d);
118 dvb_usb_i2c_exit(d);
119 deb_info("state should be zero now: %x\n", d->state);
120 d->state = DVB_USB_STATE_INIT;
121 kfree(d->priv);
122 kfree(d);
123 return 0;
124}
125
126static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums)
127{
128 int ret = 0;
129
130 mutex_init(&d->usb_mutex);
131 mutex_init(&d->i2c_mutex);
132
133 d->state = DVB_USB_STATE_INIT;
134
135 if (d->props.size_of_priv > 0) {
136 d->priv = kzalloc(d->props.size_of_priv, GFP_KERNEL);
137 if (d->priv == NULL) {
138 err("no memory for priv in 'struct dvb_usb_device'");
139 return -ENOMEM;
140 }
141 }
142
143 /* check the capabilities and set appropriate variables */
144 dvb_usb_device_power_ctrl(d, 1);
145
146 if ((ret = dvb_usb_i2c_init(d)) ||
147 (ret = dvb_usb_adapter_init(d, adapter_nums))) {
148 dvb_usb_exit(d);
149 return ret;
150 }
151
152 if ((ret = dvb_usb_remote_init(d)))
153 err("could not initialize remote control.");
154
155 dvb_usb_device_power_ctrl(d, 0);
156
157 return 0;
158}
159
160/* determine the name and the state of the just found USB device */
161static struct dvb_usb_device_description *dvb_usb_find_device(struct usb_device *udev, struct dvb_usb_device_properties *props, int *cold)
162{
163 int i, j;
164 struct dvb_usb_device_description *desc = NULL;
165
166 *cold = -1;
167
168 for (i = 0; i < props->num_device_descs; i++) {
169
170 for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].cold_ids[j] != NULL; j++) {
171 deb_info("check for cold %x %x\n", props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct);
172 if (props->devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
173 props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
174 *cold = 1;
175 desc = &props->devices[i];
176 break;
177 }
178 }
179
180 if (desc != NULL)
181 break;
182
183 for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].warm_ids[j] != NULL; j++) {
184 deb_info("check for warm %x %x\n", props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct);
185 if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
186 props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
187 *cold = 0;
188 desc = &props->devices[i];
189 break;
190 }
191 }
192 }
193
194 if (desc != NULL && props->identify_state != NULL)
195 props->identify_state(udev, props, &desc, cold);
196
197 return desc;
198}
199
200int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff)
201{
202 if (onoff)
203 d->powered++;
204 else
205 d->powered--;
206
207 if (d->powered == 0 || (onoff && d->powered == 1)) { /* when switching from 1 to 0 or from 0 to 1 */
208 deb_info("power control: %d\n", onoff);
209 if (d->props.power_ctrl)
210 return d->props.power_ctrl(d, onoff);
211 }
212 return 0;
213}
214
215/*
216 * USB
217 */
218int dvb_usb_device_init(struct usb_interface *intf,
219 struct dvb_usb_device_properties *props,
220 struct module *owner, struct dvb_usb_device **du,
221 short *adapter_nums)
222{
223 struct usb_device *udev = interface_to_usbdev(intf);
224 struct dvb_usb_device *d = NULL;
225 struct dvb_usb_device_description *desc = NULL;
226
227 int ret = -ENOMEM, cold = 0;
228
229 if (du != NULL)
230 *du = NULL;
231
232 if ((desc = dvb_usb_find_device(udev, props, &cold)) == NULL) {
233 deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n");
234 return -ENODEV;
235 }
236
237 if (cold) {
238 info("found a '%s' in cold state, will try to load a firmware", desc->name);
239 ret = dvb_usb_download_firmware(udev, props);
240 if (!props->no_reconnect || ret != 0)
241 return ret;
242 }
243
244 info("found a '%s' in warm state.", desc->name);
245 d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
246 if (d == NULL) {
247 err("no memory for 'struct dvb_usb_device'");
248 return -ENOMEM;
249 }
250
251 d->udev = udev;
252 memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties));
253 d->desc = desc;
254 d->owner = owner;
255
256 usb_set_intfdata(intf, d);
257
258 if (du != NULL)
259 *du = d;
260
261 ret = dvb_usb_init(d, adapter_nums);
262
263 if (ret == 0)
264 info("%s successfully initialized and connected.", desc->name);
265 else
266 info("%s error while loading driver (%d)", desc->name, ret);
267 return ret;
268}
269EXPORT_SYMBOL(dvb_usb_device_init);
270
271void dvb_usb_device_exit(struct usb_interface *intf)
272{
273 struct dvb_usb_device *d = usb_get_intfdata(intf);
274 const char *name = "generic DVB-USB module";
275
276 usb_set_intfdata(intf, NULL);
277 if (d != NULL && d->desc != NULL) {
278 name = d->desc->name;
279 dvb_usb_exit(d);
280 }
281 info("%s successfully deinitialized and disconnected.", name);
282
283}
284EXPORT_SYMBOL(dvb_usb_device_exit);
285
286MODULE_VERSION("1.0");
287MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
288MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
289MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
new file mode 100644
index 00000000000..41bacff2496
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -0,0 +1,391 @@
1/* dvb-usb-remote.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for initializing the input-device and for handling remote-control-queries.
7 */
8#include "dvb-usb-common.h"
9#include <linux/usb/input.h>
10
11static unsigned int
12legacy_dvb_usb_get_keymap_index(const struct input_keymap_entry *ke,
13 struct rc_map_table *keymap,
14 unsigned int keymap_size)
15{
16 unsigned int index;
17 unsigned int scancode;
18
19 if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
20 index = ke->index;
21 } else {
22 if (input_scancode_to_scalar(ke, &scancode))
23 return keymap_size;
24
25 /* See if we can match the raw key code. */
26 for (index = 0; index < keymap_size; index++)
27 if (keymap[index].scancode == scancode)
28 break;
29
30 /* See if there is an unused hole in the map */
31 if (index >= keymap_size) {
32 for (index = 0; index < keymap_size; index++) {
33 if (keymap[index].keycode == KEY_RESERVED ||
34 keymap[index].keycode == KEY_UNKNOWN) {
35 break;
36 }
37 }
38 }
39 }
40
41 return index;
42}
43
44static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
45 struct input_keymap_entry *ke)
46{
47 struct dvb_usb_device *d = input_get_drvdata(dev);
48 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
49 unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
50 unsigned int index;
51
52 index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
53 if (index >= keymap_size)
54 return -EINVAL;
55
56 ke->keycode = keymap[index].keycode;
57 if (ke->keycode == KEY_UNKNOWN)
58 ke->keycode = KEY_RESERVED;
59 ke->len = sizeof(keymap[index].scancode);
60 memcpy(&ke->scancode, &keymap[index].scancode, ke->len);
61 ke->index = index;
62
63 return 0;
64}
65
66static int legacy_dvb_usb_setkeycode(struct input_dev *dev,
67 const struct input_keymap_entry *ke,
68 unsigned int *old_keycode)
69{
70 struct dvb_usb_device *d = input_get_drvdata(dev);
71 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
72 unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
73 unsigned int index;
74
75 index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
76 /*
77 * FIXME: Currently, it is not possible to increase the size of
78 * scancode table. For it to happen, one possibility
79 * would be to allocate a table with key_map_size + 1,
80 * copying data, appending the new key on it, and freeing
81 * the old one - or maybe just allocating some spare space
82 */
83 if (index >= keymap_size)
84 return -EINVAL;
85
86 *old_keycode = keymap[index].keycode;
87 keymap->keycode = ke->keycode;
88 __set_bit(ke->keycode, dev->keybit);
89
90 if (*old_keycode != KEY_RESERVED) {
91 __clear_bit(*old_keycode, dev->keybit);
92 for (index = 0; index < keymap_size; index++) {
93 if (keymap[index].keycode == *old_keycode) {
94 __set_bit(*old_keycode, dev->keybit);
95 break;
96 }
97 }
98 }
99
100 return 0;
101}
102
103/* Remote-control poll function - called every dib->rc_query_interval ms to see
104 * whether the remote control has received anything.
105 *
106 * TODO: Fix the repeat rate of the input device.
107 */
108static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
109{
110 struct dvb_usb_device *d =
111 container_of(work, struct dvb_usb_device, rc_query_work.work);
112 u32 event;
113 int state;
114
115 /* TODO: need a lock here. We can simply skip checking for the remote control
116 if we're busy. */
117
118 /* when the parameter has been set to 1 via sysfs while the driver was running */
119 if (dvb_usb_disable_rc_polling)
120 return;
121
122 if (d->props.rc.legacy.rc_query(d,&event,&state)) {
123 err("error while querying for an remote control event.");
124 goto schedule;
125 }
126
127
128 switch (state) {
129 case REMOTE_NO_KEY_PRESSED:
130 break;
131 case REMOTE_KEY_PRESSED:
132 deb_rc("key pressed\n");
133 d->last_event = event;
134 case REMOTE_KEY_REPEAT:
135 deb_rc("key repeated\n");
136 input_event(d->input_dev, EV_KEY, event, 1);
137 input_sync(d->input_dev);
138 input_event(d->input_dev, EV_KEY, d->last_event, 0);
139 input_sync(d->input_dev);
140 break;
141 default:
142 break;
143 }
144
145/* improved repeat handling ???
146 switch (state) {
147 case REMOTE_NO_KEY_PRESSED:
148 deb_rc("NO KEY PRESSED\n");
149 if (d->last_state != REMOTE_NO_KEY_PRESSED) {
150 deb_rc("releasing event %d\n",d->last_event);
151 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
152 input_sync(d->rc_input_dev);
153 }
154 d->last_state = REMOTE_NO_KEY_PRESSED;
155 d->last_event = 0;
156 break;
157 case REMOTE_KEY_PRESSED:
158 deb_rc("KEY PRESSED\n");
159 deb_rc("pressing event %d\n",event);
160
161 input_event(d->rc_input_dev, EV_KEY, event, 1);
162 input_sync(d->rc_input_dev);
163
164 d->last_event = event;
165 d->last_state = REMOTE_KEY_PRESSED;
166 break;
167 case REMOTE_KEY_REPEAT:
168 deb_rc("KEY_REPEAT\n");
169 if (d->last_state != REMOTE_NO_KEY_PRESSED) {
170 deb_rc("repeating event %d\n",d->last_event);
171 input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
172 input_sync(d->rc_input_dev);
173 d->last_state = REMOTE_KEY_REPEAT;
174 }
175 default:
176 break;
177 }
178*/
179
180schedule:
181 schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
182}
183
184static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
185{
186 int i, err, rc_interval;
187 struct input_dev *input_dev;
188
189 input_dev = input_allocate_device();
190 if (!input_dev)
191 return -ENOMEM;
192
193 input_dev->evbit[0] = BIT_MASK(EV_KEY);
194 input_dev->name = "IR-receiver inside an USB DVB receiver";
195 input_dev->phys = d->rc_phys;
196 usb_to_input_id(d->udev, &input_dev->id);
197 input_dev->dev.parent = &d->udev->dev;
198 d->input_dev = input_dev;
199 d->rc_dev = NULL;
200
201 input_dev->getkeycode = legacy_dvb_usb_getkeycode;
202 input_dev->setkeycode = legacy_dvb_usb_setkeycode;
203
204 /* set the bits for the keys */
205 deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size);
206 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
207 deb_rc("setting bit for event %d item %d\n",
208 d->props.rc.legacy.rc_map_table[i].keycode, i);
209 set_bit(d->props.rc.legacy.rc_map_table[i].keycode, input_dev->keybit);
210 }
211
212 /* setting these two values to non-zero, we have to manage key repeats */
213 input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval;
214 input_dev->rep[REP_DELAY] = d->props.rc.legacy.rc_interval + 150;
215
216 input_set_drvdata(input_dev, d);
217
218 err = input_register_device(input_dev);
219 if (err)
220 input_free_device(input_dev);
221
222 rc_interval = d->props.rc.legacy.rc_interval;
223
224 INIT_DELAYED_WORK(&d->rc_query_work, legacy_dvb_usb_read_remote_control);
225
226 info("schedule remote query interval to %d msecs.", rc_interval);
227 schedule_delayed_work(&d->rc_query_work,
228 msecs_to_jiffies(rc_interval));
229
230 d->state |= DVB_USB_STATE_REMOTE;
231
232 return err;
233}
234
235/* Remote-control poll function - called every dib->rc_query_interval ms to see
236 * whether the remote control has received anything.
237 *
238 * TODO: Fix the repeat rate of the input device.
239 */
240static void dvb_usb_read_remote_control(struct work_struct *work)
241{
242 struct dvb_usb_device *d =
243 container_of(work, struct dvb_usb_device, rc_query_work.work);
244 int err;
245
246 /* TODO: need a lock here. We can simply skip checking for the remote control
247 if we're busy. */
248
249 /* when the parameter has been set to 1 via sysfs while the
250 * driver was running, or when bulk mode is enabled after IR init
251 */
252 if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode)
253 return;
254
255 err = d->props.rc.core.rc_query(d);
256 if (err)
257 err("error %d while querying for an remote control event.", err);
258
259 schedule_delayed_work(&d->rc_query_work,
260 msecs_to_jiffies(d->props.rc.core.rc_interval));
261}
262
263static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
264{
265 int err, rc_interval;
266 struct rc_dev *dev;
267
268 dev = rc_allocate_device();
269 if (!dev)
270 return -ENOMEM;
271
272 dev->driver_name = d->props.rc.core.module_name;
273 dev->map_name = d->props.rc.core.rc_codes;
274 dev->change_protocol = d->props.rc.core.change_protocol;
275 dev->allowed_protos = d->props.rc.core.allowed_protos;
276 dev->driver_type = d->props.rc.core.driver_type;
277 usb_to_input_id(d->udev, &dev->input_id);
278 dev->input_name = "IR-receiver inside an USB DVB receiver";
279 dev->input_phys = d->rc_phys;
280 dev->dev.parent = &d->udev->dev;
281 dev->priv = d;
282
283 err = rc_register_device(dev);
284 if (err < 0) {
285 rc_free_device(dev);
286 return err;
287 }
288
289 d->input_dev = NULL;
290 d->rc_dev = dev;
291
292 if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
293 return 0;
294
295 /* Polling mode - initialize a work queue for handling it */
296 INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
297
298 rc_interval = d->props.rc.core.rc_interval;
299
300 info("schedule remote query interval to %d msecs.", rc_interval);
301 schedule_delayed_work(&d->rc_query_work,
302 msecs_to_jiffies(rc_interval));
303
304 return 0;
305}
306
307int dvb_usb_remote_init(struct dvb_usb_device *d)
308{
309 int err;
310
311 if (dvb_usb_disable_rc_polling)
312 return 0;
313
314 if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query)
315 d->props.rc.mode = DVB_RC_LEGACY;
316 else if (d->props.rc.core.rc_codes)
317 d->props.rc.mode = DVB_RC_CORE;
318 else
319 return 0;
320
321 usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
322 strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
323
324 /* Start the remote-control polling. */
325 if (d->props.rc.legacy.rc_interval < 40)
326 d->props.rc.legacy.rc_interval = 100; /* default */
327
328 if (d->props.rc.mode == DVB_RC_LEGACY)
329 err = legacy_dvb_usb_remote_init(d);
330 else
331 err = rc_core_dvb_usb_remote_init(d);
332 if (err)
333 return err;
334
335 d->state |= DVB_USB_STATE_REMOTE;
336
337 return 0;
338}
339
340int dvb_usb_remote_exit(struct dvb_usb_device *d)
341{
342 if (d->state & DVB_USB_STATE_REMOTE) {
343 cancel_delayed_work_sync(&d->rc_query_work);
344 if (d->props.rc.mode == DVB_RC_LEGACY)
345 input_unregister_device(d->input_dev);
346 else
347 rc_unregister_device(d->rc_dev);
348 }
349 d->state &= ~DVB_USB_STATE_REMOTE;
350 return 0;
351}
352
353#define DVB_USB_RC_NEC_EMPTY 0x00
354#define DVB_USB_RC_NEC_KEY_PRESSED 0x01
355#define DVB_USB_RC_NEC_KEY_REPEATED 0x02
356int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
357 u8 keybuf[5], u32 *event, int *state)
358{
359 int i;
360 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
361 *event = 0;
362 *state = REMOTE_NO_KEY_PRESSED;
363 switch (keybuf[0]) {
364 case DVB_USB_RC_NEC_EMPTY:
365 break;
366 case DVB_USB_RC_NEC_KEY_PRESSED:
367 if ((u8) ~keybuf[1] != keybuf[2] ||
368 (u8) ~keybuf[3] != keybuf[4]) {
369 deb_err("remote control checksum failed.\n");
370 break;
371 }
372 /* See if we can match the raw key code. */
373 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
374 if (rc5_custom(&keymap[i]) == keybuf[1] &&
375 rc5_data(&keymap[i]) == keybuf[3]) {
376 *event = keymap[i].keycode;
377 *state = REMOTE_KEY_PRESSED;
378 return 0;
379 }
380 deb_err("key mapping failed - no appropriate key found in keymapping\n");
381 break;
382 case DVB_USB_RC_NEC_KEY_REPEATED:
383 *state = REMOTE_KEY_REPEAT;
384 break;
385 default:
386 deb_err("unknown type of remote status: %d\n",keybuf[0]);
387 break;
388 }
389 return 0;
390}
391EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
new file mode 100644
index 00000000000..bb46ba6a357
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
@@ -0,0 +1,97 @@
1/* dvb-usb-urb.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file keeps functions for initializing and handling the
7 * USB and URB stuff.
8 */
9#include "dvb-usb-common.h"
10
11int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
12 u16 rlen, int delay_ms)
13{
14 int actlen,ret = -ENOMEM;
15
16 if (!d || wbuf == NULL || wlen == 0)
17 return -EINVAL;
18
19 if (d->props.generic_bulk_ctrl_endpoint == 0) {
20 err("endpoint for generic control not specified.");
21 return -EINVAL;
22 }
23
24 if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
25 return ret;
26
27 deb_xfer(">>> ");
28 debug_dump(wbuf,wlen,deb_xfer);
29
30 ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev,
31 d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen,
32 2000);
33
34 if (ret)
35 err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
36 else
37 ret = actlen != wlen ? -1 : 0;
38
39 /* an answer is expected, and no error before */
40 if (!ret && rbuf && rlen) {
41 if (delay_ms)
42 msleep(delay_ms);
43
44 ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev,
45 d->props.generic_bulk_ctrl_endpoint_response ?
46 d->props.generic_bulk_ctrl_endpoint_response :
47 d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen,
48 2000);
49
50 if (ret)
51 err("recv bulk message failed: %d",ret);
52 else {
53 deb_xfer("<<< ");
54 debug_dump(rbuf,actlen,deb_xfer);
55 }
56 }
57
58 mutex_unlock(&d->usb_mutex);
59 return ret;
60}
61EXPORT_SYMBOL(dvb_usb_generic_rw);
62
63int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
64{
65 return dvb_usb_generic_rw(d,buf,len,NULL,0,0);
66}
67EXPORT_SYMBOL(dvb_usb_generic_write);
68
69static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buffer, size_t length)
70{
71 struct dvb_usb_adapter *adap = stream->user_priv;
72 if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
73 dvb_dmx_swfilter(&adap->demux, buffer, length);
74}
75
76static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buffer, size_t length)
77{
78 struct dvb_usb_adapter *adap = stream->user_priv;
79 if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
80 dvb_dmx_swfilter_204(&adap->demux, buffer, length);
81}
82
83int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap)
84{
85 adap->stream.udev = adap->dev->udev;
86 if (adap->props.caps & DVB_USB_ADAP_RECEIVES_204_BYTE_TS)
87 adap->stream.complete = dvb_usb_data_complete_204;
88 else
89 adap->stream.complete = dvb_usb_data_complete;
90 adap->stream.user_priv = adap;
91 return usb_urb_init(&adap->stream, &adap->props.stream);
92}
93
94int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap)
95{
96 return usb_urb_exit(&adap->stream);
97}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
new file mode 100644
index 00000000000..7d35d078342
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -0,0 +1,463 @@
1/* dvb-usb.h is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * the headerfile, all dvb-usb-drivers have to include.
7 *
8 * TODO: clean-up the structures for unused fields and update the comments
9 */
10#ifndef __DVB_USB_H__
11#define __DVB_USB_H__
12
13#include <linux/input.h>
14#include <linux/usb.h>
15#include <linux/firmware.h>
16#include <linux/mutex.h>
17#include <media/rc-core.h>
18
19#include "dvb_frontend.h"
20#include "dvb_demux.h"
21#include "dvb_net.h"
22#include "dmxdev.h"
23
24#include "dvb-pll.h"
25
26#include "dvb-usb-ids.h"
27
28/* debug */
29#ifdef CONFIG_DVB_USB_DEBUG
30#define dprintk(var,level,args...) \
31 do { if ((var & level)) { printk(args); } } while (0)
32
33#define debug_dump(b,l,func) {\
34 int loop_; \
35 for (loop_ = 0; loop_ < l; loop_++) func("%02x ", b[loop_]); \
36 func("\n");\
37}
38#define DVB_USB_DEBUG_STATUS
39#else
40#define dprintk(args...)
41#define debug_dump(b,l,func)
42
43#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
44
45#endif
46
47/* generic log methods - taken from usb.h */
48#ifndef DVB_USB_LOG_PREFIX
49 #define DVB_USB_LOG_PREFIX "dvb-usb (please define a log prefix)"
50#endif
51
52#undef err
53#define err(format, arg...) printk(KERN_ERR DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
54#undef info
55#define info(format, arg...) printk(KERN_INFO DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
56#undef warn
57#define warn(format, arg...) printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
58
59/**
60 * struct dvb_usb_device_description - name and its according USB IDs
61 * @name: real name of the box, regardless which DVB USB device class is in use
62 * @cold_ids: array of struct usb_device_id which describe the device in
63 * pre-firmware state
64 * @warm_ids: array of struct usb_device_id which describe the device in
65 * post-firmware state
66 *
67 * Each DVB USB device class can have one or more actual devices, this struct
68 * assigns a name to it.
69 */
70struct dvb_usb_device_description {
71 const char *name;
72
73#define DVB_USB_ID_MAX_NUM 15
74 struct usb_device_id *cold_ids[DVB_USB_ID_MAX_NUM];
75 struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM];
76};
77
78static inline u8 rc5_custom(struct rc_map_table *key)
79{
80 return (key->scancode >> 8) & 0xff;
81}
82
83static inline u8 rc5_data(struct rc_map_table *key)
84{
85 return key->scancode & 0xff;
86}
87
88static inline u16 rc5_scan(struct rc_map_table *key)
89{
90 return key->scancode & 0xffff;
91}
92
93struct dvb_usb_device;
94struct dvb_usb_adapter;
95struct usb_data_stream;
96
97/**
98 * Properties of USB streaming - TODO this structure should be somewhere else
99 * describes the kind of USB transfer used for data-streaming.
100 * (BULK or ISOC)
101 */
102struct usb_data_stream_properties {
103#define USB_BULK 1
104#define USB_ISOC 2
105 int type;
106 int count;
107 int endpoint;
108
109 union {
110 struct {
111 int buffersize; /* per URB */
112 } bulk;
113 struct {
114 int framesperurb;
115 int framesize;
116 int interval;
117 } isoc;
118 } u;
119};
120
121/**
122 * struct dvb_usb_adapter_properties - properties of a dvb-usb-adapter.
123 * A DVB-USB-Adapter is basically a dvb_adapter which is present on a USB-device.
124 * @caps: capabilities of the DVB USB device.
125 * @pid_filter_count: number of PID filter position in the optional hardware
126 * PID-filter.
127 * @streaming_ctrl: called to start and stop the MPEG2-TS streaming of the
128 * device (not URB submitting/killing).
129 * @pid_filter_ctrl: called to en/disable the PID filter, if any.
130 * @pid_filter: called to set/unset a PID for filtering.
131 * @frontend_attach: called to attach the possible frontends (fill fe-field
132 * of struct dvb_usb_device).
133 * @tuner_attach: called to attach the correct tuner and to fill pll_addr,
134 * pll_desc and pll_init_buf of struct dvb_usb_device).
135 * @stream: configuration of the USB streaming
136 */
137struct dvb_usb_adapter_properties {
138#define DVB_USB_ADAP_HAS_PID_FILTER 0x01
139#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
140#define DVB_USB_ADAP_NEED_PID_FILTERING 0x04
141#define DVB_USB_ADAP_RECEIVES_204_BYTE_TS 0x08
142 int caps;
143 int pid_filter_count;
144
145 int (*streaming_ctrl) (struct dvb_usb_adapter *, int);
146 int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int);
147 int (*pid_filter) (struct dvb_usb_adapter *, int, u16, int);
148
149 int (*frontend_attach) (struct dvb_usb_adapter *);
150 int (*tuner_attach) (struct dvb_usb_adapter *);
151
152 struct usb_data_stream_properties stream;
153
154 int size_of_priv;
155
156 int (*fe_ioctl_override) (struct dvb_frontend *,
157 unsigned int, void *, unsigned int);
158};
159
160/**
161 * struct dvb_rc_legacy - old properties of remote controller
162 * @rc_map_table: a hard-wired array of struct rc_map_table (NULL to disable
163 * remote control handling).
164 * @rc_map_size: number of items in @rc_map_table.
165 * @rc_query: called to query an event event.
166 * @rc_interval: time in ms between two queries.
167 */
168struct dvb_rc_legacy {
169/* remote control properties */
170#define REMOTE_NO_KEY_PRESSED 0x00
171#define REMOTE_KEY_PRESSED 0x01
172#define REMOTE_KEY_REPEAT 0x02
173 struct rc_map_table *rc_map_table;
174 int rc_map_size;
175 int (*rc_query) (struct dvb_usb_device *, u32 *, int *);
176 int rc_interval;
177};
178
179/**
180 * struct dvb_rc properties of remote controller, using rc-core
181 * @rc_codes: name of rc codes table
182 * @protocol: type of protocol(s) currently used by the driver
183 * @allowed_protos: protocol(s) supported by the driver
184 * @driver_type: Used to point if a device supports raw mode
185 * @change_protocol: callback to change protocol
186 * @rc_query: called to query an event event.
187 * @rc_interval: time in ms between two queries.
188 * @bulk_mode: device supports bulk mode for RC (disable polling mode)
189 */
190struct dvb_rc {
191 char *rc_codes;
192 u64 protocol;
193 u64 allowed_protos;
194 enum rc_driver_type driver_type;
195 int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
196 char *module_name;
197 int (*rc_query) (struct dvb_usb_device *d);
198 int rc_interval;
199 bool bulk_mode; /* uses bulk mode */
200};
201
202/**
203 * enum dvb_usb_mode - Specifies if it is using a legacy driver or a new one
204 * based on rc-core
205 * This is initialized/used only inside dvb-usb-remote.c.
206 * It shouldn't be set by the drivers.
207 */
208enum dvb_usb_mode {
209 DVB_RC_LEGACY,
210 DVB_RC_CORE,
211};
212
213/**
214 * struct dvb_usb_device_properties - properties of a dvb-usb-device
215 * @usb_ctrl: which USB device-side controller is in use. Needed for firmware
216 * download.
217 * @firmware: name of the firmware file.
218 * @download_firmware: called to download the firmware when the usb_ctrl is
219 * DEVICE_SPECIFIC.
220 * @no_reconnect: device doesn't do a reconnect after downloading the firmware,
221 * so do the warm initialization right after it
222 *
223 * @size_of_priv: how many bytes shall be allocated for the private field
224 * of struct dvb_usb_device.
225 *
226 * @power_ctrl: called to enable/disable power of the device.
227 * @read_mac_address: called to read the MAC address of the device.
228 * @identify_state: called to determine the state (cold or warm), when it
229 * is not distinguishable by the USB IDs.
230 *
231 * @rc: remote controller properties
232 *
233 * @i2c_algo: i2c_algorithm if the device has I2CoverUSB.
234 *
235 * @generic_bulk_ctrl_endpoint: most of the DVB USB devices have a generic
236 * endpoint which received control messages with bulk transfers. When this
237 * is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write-
238 * helper functions.
239 *
240 * @generic_bulk_ctrl_endpoint_response: some DVB USB devices use a separate
241 * endpoint for responses to control messages sent with bulk transfers via
242 * the generic_bulk_ctrl_endpoint. When this is non-zero, this will be used
243 * instead of the generic_bulk_ctrl_endpoint when reading usb responses in
244 * the dvb_usb_generic_rw helper function.
245 *
246 * @num_device_descs: number of struct dvb_usb_device_description in @devices
247 * @devices: array of struct dvb_usb_device_description compatibles with these
248 * properties.
249 */
250#define MAX_NO_OF_ADAPTER_PER_DEVICE 2
251struct dvb_usb_device_properties {
252
253#define DVB_USB_IS_AN_I2C_ADAPTER 0x01
254 int caps;
255
256#define DEVICE_SPECIFIC 0
257#define CYPRESS_AN2135 1
258#define CYPRESS_AN2235 2
259#define CYPRESS_FX2 3
260 int usb_ctrl;
261 int (*download_firmware) (struct usb_device *, const struct firmware *);
262 const char *firmware;
263 int no_reconnect;
264
265 int size_of_priv;
266
267 int num_adapters;
268 struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
269
270 int (*power_ctrl) (struct dvb_usb_device *, int);
271 int (*read_mac_address) (struct dvb_usb_device *, u8 []);
272 int (*identify_state) (struct usb_device *, struct dvb_usb_device_properties *,
273 struct dvb_usb_device_description **, int *);
274
275 struct {
276 enum dvb_usb_mode mode; /* Drivers shouldn't touch on it */
277 struct dvb_rc_legacy legacy;
278 struct dvb_rc core;
279 } rc;
280
281 struct i2c_algorithm *i2c_algo;
282
283 int generic_bulk_ctrl_endpoint;
284 int generic_bulk_ctrl_endpoint_response;
285
286 int num_device_descs;
287 struct dvb_usb_device_description devices[12];
288};
289
290/**
291 * struct usb_data_stream - generic object of an USB stream
292 * @buf_num: number of buffer allocated.
293 * @buf_size: size of each buffer in buf_list.
294 * @buf_list: array containing all allocate buffers for streaming.
295 * @dma_addr: list of dma_addr_t for each buffer in buf_list.
296 *
297 * @urbs_initialized: number of URBs initialized.
298 * @urbs_submitted: number of URBs submitted.
299 */
300#define MAX_NO_URBS_FOR_DATA_STREAM 10
301struct usb_data_stream {
302 struct usb_device *udev;
303 struct usb_data_stream_properties props;
304
305#define USB_STATE_INIT 0x00
306#define USB_STATE_URB_BUF 0x01
307 int state;
308
309 void (*complete) (struct usb_data_stream *, u8 *, size_t);
310
311 struct urb *urb_list[MAX_NO_URBS_FOR_DATA_STREAM];
312 int buf_num;
313 unsigned long buf_size;
314 u8 *buf_list[MAX_NO_URBS_FOR_DATA_STREAM];
315 dma_addr_t dma_addr[MAX_NO_URBS_FOR_DATA_STREAM];
316
317 int urbs_initialized;
318 int urbs_submitted;
319
320 void *user_priv;
321};
322
323/**
324 * struct dvb_usb_adapter - a DVB adapter on a USB device
325 * @id: index of this adapter (starting with 0).
326 *
327 * @feedcount: number of reqested feeds (used for streaming-activation)
328 * @pid_filtering: is hardware pid_filtering used or not.
329 *
330 * @pll_addr: I2C address of the tuner for programming
331 * @pll_init: array containing the initialization buffer
332 * @pll_desc: pointer to the appropriate struct dvb_pll_desc
333 * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod or the board
334 *
335 * @dvb_adap: device's dvb_adapter.
336 * @dmxdev: device's dmxdev.
337 * @demux: device's software demuxer.
338 * @dvb_net: device's dvb_net interfaces.
339 * @dvb_frontend: device's frontend.
340 * @max_feed_count: how many feeds can be handled simultaneously by this
341 * device
342 *
343 * @fe_init: rerouted frontend-init (wakeup) function.
344 * @fe_sleep: rerouted frontend-sleep function.
345 *
346 * @stream: the usb data stream.
347 */
348struct dvb_usb_adapter {
349 struct dvb_usb_device *dev;
350 struct dvb_usb_adapter_properties props;
351
352#define DVB_USB_ADAP_STATE_INIT 0x000
353#define DVB_USB_ADAP_STATE_DVB 0x001
354 int state;
355
356 u8 id;
357
358 int feedcount;
359 int pid_filtering;
360
361 /* dvb */
362 struct dvb_adapter dvb_adap;
363 struct dmxdev dmxdev;
364 struct dvb_demux demux;
365 struct dvb_net dvb_net;
366 struct dvb_frontend *fe;
367 int max_feed_count;
368
369 int (*fe_init) (struct dvb_frontend *);
370 int (*fe_sleep) (struct dvb_frontend *);
371
372 struct usb_data_stream stream;
373
374 void *priv;
375};
376
377/**
378 * struct dvb_usb_device - object of a DVB USB device
379 * @props: copy of the struct dvb_usb_properties this device belongs to.
380 * @desc: pointer to the device's struct dvb_usb_device_description.
381 * @state: initialization and runtime state of the device.
382 *
383 * @powered: indicated whether the device is power or not.
384 * Powered is in/decremented for each call to modify the state.
385 * @udev: pointer to the device's struct usb_device.
386 *
387 * @usb_mutex: semaphore of USB control messages (reading needs two messages)
388 * @i2c_mutex: semaphore for i2c-transfers
389 *
390 * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
391 *
392 * @rc_dev: rc device for the remote control (rc-core mode)
393 * @input_dev: input device for the remote control (legacy mode)
394 * @rc_query_work: struct work_struct frequent rc queries
395 * @last_event: last triggered event
396 * @last_state: last state (no, pressed, repeat)
397 * @owner: owner of the dvb_adapter
398 * @priv: private data of the actual driver (allocate by dvb-usb, size defined
399 * in size_of_priv of dvb_usb_properties).
400 */
401struct dvb_usb_device {
402 struct dvb_usb_device_properties props;
403 struct dvb_usb_device_description *desc;
404
405 struct usb_device *udev;
406
407#define DVB_USB_STATE_INIT 0x000
408#define DVB_USB_STATE_I2C 0x001
409#define DVB_USB_STATE_DVB 0x002
410#define DVB_USB_STATE_REMOTE 0x004
411 int state;
412
413 int powered;
414
415 /* locking */
416 struct mutex usb_mutex;
417
418 /* i2c */
419 struct mutex i2c_mutex;
420 struct i2c_adapter i2c_adap;
421
422 int num_adapters_initialized;
423 struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
424
425 /* remote control */
426 struct rc_dev *rc_dev;
427 struct input_dev *input_dev;
428 char rc_phys[64];
429 struct delayed_work rc_query_work;
430 u32 last_event;
431 int last_state;
432
433 struct module *owner;
434
435 void *priv;
436};
437
438extern int dvb_usb_device_init(struct usb_interface *,
439 struct dvb_usb_device_properties *,
440 struct module *, struct dvb_usb_device **,
441 short *adapter_nums);
442extern void dvb_usb_device_exit(struct usb_interface *);
443
444/* the generic read/write method for device control */
445extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int);
446extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
447
448/* commonly used remote control parsing */
449extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *);
450
451/* commonly used firmware download types and function */
452struct hexline {
453 u8 len;
454 u32 addr;
455 u8 type;
456 u8 data[255];
457 u8 chk;
458};
459extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type);
460extern int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos);
461
462
463#endif
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
new file mode 100644
index 00000000000..058b2318abe
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -0,0 +1,1940 @@
1/* DVB USB framework compliant Linux driver for the
2 * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
3 * TeVii S600, S630, S650, S660, S480,
4 * Prof 1100, 7500,
5 * Geniatech SU3000 Cards
6 * Copyright (C) 2008-2011 Igor M. Liplianin (liplianin@me.by)
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#include "dw2102.h"
15#include "si21xx.h"
16#include "stv0299.h"
17#include "z0194a.h"
18#include "stv0288.h"
19#include "stb6000.h"
20#include "eds1547.h"
21#include "cx24116.h"
22#include "tda1002x.h"
23#include "mt312.h"
24#include "zl10039.h"
25#include "ds3000.h"
26#include "stv0900.h"
27#include "stv6110.h"
28#include "stb6100.h"
29#include "stb6100_proc.h"
30
31#ifndef USB_PID_DW2102
32#define USB_PID_DW2102 0x2102
33#endif
34
35#ifndef USB_PID_DW2104
36#define USB_PID_DW2104 0x2104
37#endif
38
39#ifndef USB_PID_DW3101
40#define USB_PID_DW3101 0x3101
41#endif
42
43#ifndef USB_PID_CINERGY_S
44#define USB_PID_CINERGY_S 0x0064
45#endif
46
47#ifndef USB_PID_TEVII_S630
48#define USB_PID_TEVII_S630 0xd630
49#endif
50
51#ifndef USB_PID_TEVII_S650
52#define USB_PID_TEVII_S650 0xd650
53#endif
54
55#ifndef USB_PID_TEVII_S660
56#define USB_PID_TEVII_S660 0xd660
57#endif
58
59#ifndef USB_PID_TEVII_S480_1
60#define USB_PID_TEVII_S480_1 0xd481
61#endif
62
63#ifndef USB_PID_TEVII_S480_2
64#define USB_PID_TEVII_S480_2 0xd482
65#endif
66
67#ifndef USB_PID_PROF_1100
68#define USB_PID_PROF_1100 0xb012
69#endif
70
71#define DW210X_READ_MSG 0
72#define DW210X_WRITE_MSG 1
73
74#define REG_1F_SYMBOLRATE_BYTE0 0x1f
75#define REG_20_SYMBOLRATE_BYTE1 0x20
76#define REG_21_SYMBOLRATE_BYTE2 0x21
77/* on my own*/
78#define DW2102_VOLTAGE_CTRL (0x1800)
79#define SU3000_STREAM_CTRL (0x1900)
80#define DW2102_RC_QUERY (0x1a00)
81#define DW2102_LED_CTRL (0x1b00)
82
83#define err_str "did not find the firmware file. (%s) " \
84 "Please see linux/Documentation/dvb/ for more details " \
85 "on firmware-problems."
86
87struct rc_map_dvb_usb_table_table {
88 struct rc_map_table *rc_keys;
89 int rc_keys_size;
90};
91
92struct su3000_state {
93 u8 initialized;
94};
95
96struct s6x0_state {
97 int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v);
98};
99
100/* debug */
101static int dvb_usb_dw2102_debug;
102module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
103MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
104 DVB_USB_DEBUG_STATUS);
105
106/* keymaps */
107static int ir_keymap;
108module_param_named(keymap, ir_keymap, int, 0644);
109MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."
110 " 256=none");
111
112/* demod probe */
113static int demod_probe = 1;
114module_param_named(demod, demod_probe, int, 0644);
115MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 "
116 "4=stv0903+stb6100(or-able)).");
117
118DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
119
120static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
121 u16 index, u8 * data, u16 len, int flags)
122{
123 int ret;
124 u8 *u8buf;
125 unsigned int pipe = (flags == DW210X_READ_MSG) ?
126 usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
127 u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
128
129 u8buf = kmalloc(len, GFP_KERNEL);
130 if (!u8buf)
131 return -ENOMEM;
132
133
134 if (flags == DW210X_WRITE_MSG)
135 memcpy(u8buf, data, len);
136 ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
137 value, index , u8buf, len, 2000);
138
139 if (flags == DW210X_READ_MSG)
140 memcpy(data, u8buf, len);
141
142 kfree(u8buf);
143 return ret;
144}
145
146/* I2C */
147static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
148 int num)
149{
150 struct dvb_usb_device *d = i2c_get_adapdata(adap);
151 int i = 0, ret = 0;
152 u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
153 u16 value;
154
155 if (!d)
156 return -ENODEV;
157 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
158 return -EAGAIN;
159
160 switch (num) {
161 case 2:
162 /* read stv0299 register */
163 value = msg[0].buf[0];/* register */
164 for (i = 0; i < msg[1].len; i++) {
165 ret = dw210x_op_rw(d->udev, 0xb5, value + i, 0,
166 buf6, 2, DW210X_READ_MSG);
167 msg[1].buf[i] = buf6[0];
168 }
169 break;
170 case 1:
171 switch (msg[0].addr) {
172 case 0x68:
173 /* write to stv0299 register */
174 buf6[0] = 0x2a;
175 buf6[1] = msg[0].buf[0];
176 buf6[2] = msg[0].buf[1];
177 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
178 buf6, 3, DW210X_WRITE_MSG);
179 break;
180 case 0x60:
181 if (msg[0].flags == 0) {
182 /* write to tuner pll */
183 buf6[0] = 0x2c;
184 buf6[1] = 5;
185 buf6[2] = 0xc0;
186 buf6[3] = msg[0].buf[0];
187 buf6[4] = msg[0].buf[1];
188 buf6[5] = msg[0].buf[2];
189 buf6[6] = msg[0].buf[3];
190 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
191 buf6, 7, DW210X_WRITE_MSG);
192 } else {
193 /* read from tuner */
194 ret = dw210x_op_rw(d->udev, 0xb5, 0, 0,
195 buf6, 1, DW210X_READ_MSG);
196 msg[0].buf[0] = buf6[0];
197 }
198 break;
199 case (DW2102_RC_QUERY):
200 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
201 buf6, 2, DW210X_READ_MSG);
202 msg[0].buf[0] = buf6[0];
203 msg[0].buf[1] = buf6[1];
204 break;
205 case (DW2102_VOLTAGE_CTRL):
206 buf6[0] = 0x30;
207 buf6[1] = msg[0].buf[0];
208 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
209 buf6, 2, DW210X_WRITE_MSG);
210 break;
211 }
212
213 break;
214 }
215
216 mutex_unlock(&d->i2c_mutex);
217 return num;
218}
219
220static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
221 struct i2c_msg msg[], int num)
222{
223 struct dvb_usb_device *d = i2c_get_adapdata(adap);
224 int ret = 0;
225 u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
226
227 if (!d)
228 return -ENODEV;
229 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
230 return -EAGAIN;
231
232 switch (num) {
233 case 2:
234 /* read si2109 register by number */
235 buf6[0] = msg[0].addr << 1;
236 buf6[1] = msg[0].len;
237 buf6[2] = msg[0].buf[0];
238 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
239 buf6, msg[0].len + 2, DW210X_WRITE_MSG);
240 /* read si2109 register */
241 ret = dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
242 buf6, msg[1].len + 2, DW210X_READ_MSG);
243 memcpy(msg[1].buf, buf6 + 2, msg[1].len);
244
245 break;
246 case 1:
247 switch (msg[0].addr) {
248 case 0x68:
249 /* write to si2109 register */
250 buf6[0] = msg[0].addr << 1;
251 buf6[1] = msg[0].len;
252 memcpy(buf6 + 2, msg[0].buf, msg[0].len);
253 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
254 msg[0].len + 2, DW210X_WRITE_MSG);
255 break;
256 case(DW2102_RC_QUERY):
257 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
258 buf6, 2, DW210X_READ_MSG);
259 msg[0].buf[0] = buf6[0];
260 msg[0].buf[1] = buf6[1];
261 break;
262 case(DW2102_VOLTAGE_CTRL):
263 buf6[0] = 0x30;
264 buf6[1] = msg[0].buf[0];
265 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
266 buf6, 2, DW210X_WRITE_MSG);
267 break;
268 }
269 break;
270 }
271
272 mutex_unlock(&d->i2c_mutex);
273 return num;
274}
275
276static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
277{
278 struct dvb_usb_device *d = i2c_get_adapdata(adap);
279 int ret = 0;
280
281 if (!d)
282 return -ENODEV;
283 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
284 return -EAGAIN;
285
286 switch (num) {
287 case 2: {
288 /* read */
289 /* first write first register number */
290 u8 ibuf[msg[1].len + 2], obuf[3];
291 obuf[0] = msg[0].addr << 1;
292 obuf[1] = msg[0].len;
293 obuf[2] = msg[0].buf[0];
294 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
295 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
296 /* second read registers */
297 ret = dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
298 ibuf, msg[1].len + 2, DW210X_READ_MSG);
299 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
300
301 break;
302 }
303 case 1:
304 switch (msg[0].addr) {
305 case 0x68: {
306 /* write to register */
307 u8 obuf[msg[0].len + 2];
308 obuf[0] = msg[0].addr << 1;
309 obuf[1] = msg[0].len;
310 memcpy(obuf + 2, msg[0].buf, msg[0].len);
311 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
312 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
313 break;
314 }
315 case 0x61: {
316 /* write to tuner */
317 u8 obuf[msg[0].len + 2];
318 obuf[0] = msg[0].addr << 1;
319 obuf[1] = msg[0].len;
320 memcpy(obuf + 2, msg[0].buf, msg[0].len);
321 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
322 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
323 break;
324 }
325 case(DW2102_RC_QUERY): {
326 u8 ibuf[2];
327 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
328 ibuf, 2, DW210X_READ_MSG);
329 memcpy(msg[0].buf, ibuf , 2);
330 break;
331 }
332 case(DW2102_VOLTAGE_CTRL): {
333 u8 obuf[2];
334 obuf[0] = 0x30;
335 obuf[1] = msg[0].buf[0];
336 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
337 obuf, 2, DW210X_WRITE_MSG);
338 break;
339 }
340 }
341
342 break;
343 }
344
345 mutex_unlock(&d->i2c_mutex);
346 return num;
347}
348
349static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
350{
351 struct dvb_usb_device *d = i2c_get_adapdata(adap);
352 int ret = 0;
353 int len, i, j;
354
355 if (!d)
356 return -ENODEV;
357 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
358 return -EAGAIN;
359
360 for (j = 0; j < num; j++) {
361 switch (msg[j].addr) {
362 case(DW2102_RC_QUERY): {
363 u8 ibuf[2];
364 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
365 ibuf, 2, DW210X_READ_MSG);
366 memcpy(msg[j].buf, ibuf , 2);
367 break;
368 }
369 case(DW2102_VOLTAGE_CTRL): {
370 u8 obuf[2];
371 obuf[0] = 0x30;
372 obuf[1] = msg[j].buf[0];
373 ret = dw210x_op_rw(d->udev, 0xb2, 0, 0,
374 obuf, 2, DW210X_WRITE_MSG);
375 break;
376 }
377 /*case 0x55: cx24116
378 case 0x6a: stv0903
379 case 0x68: ds3000, stv0903
380 case 0x60: ts2020, stv6110, stb6100 */
381 default: {
382 if (msg[j].flags == I2C_M_RD) {
383 /* read registers */
384 u8 ibuf[msg[j].len + 2];
385 ret = dw210x_op_rw(d->udev, 0xc3,
386 (msg[j].addr << 1) + 1, 0,
387 ibuf, msg[j].len + 2,
388 DW210X_READ_MSG);
389 memcpy(msg[j].buf, ibuf + 2, msg[j].len);
390 mdelay(10);
391 } else if (((msg[j].buf[0] == 0xb0) &&
392 (msg[j].addr == 0x68)) ||
393 ((msg[j].buf[0] == 0xf7) &&
394 (msg[j].addr == 0x55))) {
395 /* write firmware */
396 u8 obuf[19];
397 obuf[0] = msg[j].addr << 1;
398 obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
399 obuf[2] = msg[j].buf[0];
400 len = msg[j].len - 1;
401 i = 1;
402 do {
403 memcpy(obuf + 3, msg[j].buf + i,
404 (len > 16 ? 16 : len));
405 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
406 obuf, (len > 16 ? 16 : len) + 3,
407 DW210X_WRITE_MSG);
408 i += 16;
409 len -= 16;
410 } while (len > 0);
411 } else {
412 /* write registers */
413 u8 obuf[msg[j].len + 2];
414 obuf[0] = msg[j].addr << 1;
415 obuf[1] = msg[j].len;
416 memcpy(obuf + 2, msg[j].buf, msg[j].len);
417 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
418 obuf, msg[j].len + 2,
419 DW210X_WRITE_MSG);
420 }
421 break;
422 }
423 }
424
425 }
426
427 mutex_unlock(&d->i2c_mutex);
428 return num;
429}
430
431static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
432 int num)
433{
434 struct dvb_usb_device *d = i2c_get_adapdata(adap);
435 int ret = 0, i;
436
437 if (!d)
438 return -ENODEV;
439 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
440 return -EAGAIN;
441
442 switch (num) {
443 case 2: {
444 /* read */
445 /* first write first register number */
446 u8 ibuf[msg[1].len + 2], obuf[3];
447 obuf[0] = msg[0].addr << 1;
448 obuf[1] = msg[0].len;
449 obuf[2] = msg[0].buf[0];
450 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
451 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
452 /* second read registers */
453 ret = dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
454 ibuf, msg[1].len + 2, DW210X_READ_MSG);
455 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
456
457 break;
458 }
459 case 1:
460 switch (msg[0].addr) {
461 case 0x60:
462 case 0x0c: {
463 /* write to register */
464 u8 obuf[msg[0].len + 2];
465 obuf[0] = msg[0].addr << 1;
466 obuf[1] = msg[0].len;
467 memcpy(obuf + 2, msg[0].buf, msg[0].len);
468 ret = dw210x_op_rw(d->udev, 0xc2, 0, 0,
469 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
470 break;
471 }
472 case(DW2102_RC_QUERY): {
473 u8 ibuf[2];
474 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
475 ibuf, 2, DW210X_READ_MSG);
476 memcpy(msg[0].buf, ibuf , 2);
477 break;
478 }
479 }
480
481 break;
482 }
483
484 for (i = 0; i < num; i++) {
485 deb_xfer("%02x:%02x: %s ", i, msg[i].addr,
486 msg[i].flags == 0 ? ">>>" : "<<<");
487 debug_dump(msg[i].buf, msg[i].len, deb_xfer);
488 }
489
490 mutex_unlock(&d->i2c_mutex);
491 return num;
492}
493
494static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
495 int num)
496{
497 struct dvb_usb_device *d = i2c_get_adapdata(adap);
498 struct usb_device *udev;
499 int ret = 0;
500 int len, i, j;
501
502 if (!d)
503 return -ENODEV;
504 udev = d->udev;
505 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
506 return -EAGAIN;
507
508 for (j = 0; j < num; j++) {
509 switch (msg[j].addr) {
510 case (DW2102_RC_QUERY): {
511 u8 ibuf[5];
512 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
513 ibuf, 5, DW210X_READ_MSG);
514 memcpy(msg[j].buf, ibuf + 3, 2);
515 break;
516 }
517 case (DW2102_VOLTAGE_CTRL): {
518 u8 obuf[2];
519
520 obuf[0] = 1;
521 obuf[1] = msg[j].buf[1];/* off-on */
522 ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
523 obuf, 2, DW210X_WRITE_MSG);
524 obuf[0] = 3;
525 obuf[1] = msg[j].buf[0];/* 13v-18v */
526 ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
527 obuf, 2, DW210X_WRITE_MSG);
528 break;
529 }
530 case (DW2102_LED_CTRL): {
531 u8 obuf[2];
532
533 obuf[0] = 5;
534 obuf[1] = msg[j].buf[0];
535 ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
536 obuf, 2, DW210X_WRITE_MSG);
537 break;
538 }
539 /*case 0x55: cx24116
540 case 0x6a: stv0903
541 case 0x68: ds3000, stv0903
542 case 0x60: ts2020, stv6110, stb6100
543 case 0xa0: eeprom */
544 default: {
545 if (msg[j].flags == I2C_M_RD) {
546 /* read registers */
547 u8 ibuf[msg[j].len];
548 ret = dw210x_op_rw(d->udev, 0x91, 0, 0,
549 ibuf, msg[j].len,
550 DW210X_READ_MSG);
551 memcpy(msg[j].buf, ibuf, msg[j].len);
552 break;
553 } else if ((msg[j].buf[0] == 0xb0) &&
554 (msg[j].addr == 0x68)) {
555 /* write firmware */
556 u8 obuf[19];
557 obuf[0] = (msg[j].len > 16 ?
558 18 : msg[j].len + 1);
559 obuf[1] = msg[j].addr << 1;
560 obuf[2] = msg[j].buf[0];
561 len = msg[j].len - 1;
562 i = 1;
563 do {
564 memcpy(obuf + 3, msg[j].buf + i,
565 (len > 16 ? 16 : len));
566 ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
567 obuf, (len > 16 ? 16 : len) + 3,
568 DW210X_WRITE_MSG);
569 i += 16;
570 len -= 16;
571 } while (len > 0);
572 } else if (j < (num - 1)) {
573 /* write register addr before read */
574 u8 obuf[msg[j].len + 2];
575 obuf[0] = msg[j + 1].len;
576 obuf[1] = (msg[j].addr << 1);
577 memcpy(obuf + 2, msg[j].buf, msg[j].len);
578 ret = dw210x_op_rw(d->udev,
579 udev->descriptor.idProduct ==
580 0x7500 ? 0x92 : 0x90, 0, 0,
581 obuf, msg[j].len + 2,
582 DW210X_WRITE_MSG);
583 break;
584 } else {
585 /* write registers */
586 u8 obuf[msg[j].len + 2];
587 obuf[0] = msg[j].len + 1;
588 obuf[1] = (msg[j].addr << 1);
589 memcpy(obuf + 2, msg[j].buf, msg[j].len);
590 ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
591 obuf, msg[j].len + 2,
592 DW210X_WRITE_MSG);
593 break;
594 }
595 break;
596 }
597 }
598 }
599
600 mutex_unlock(&d->i2c_mutex);
601 return num;
602}
603
604static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
605 int num)
606{
607 struct dvb_usb_device *d = i2c_get_adapdata(adap);
608 u8 obuf[0x40], ibuf[0x40];
609
610 if (!d)
611 return -ENODEV;
612 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
613 return -EAGAIN;
614
615 switch (num) {
616 case 1:
617 switch (msg[0].addr) {
618 case SU3000_STREAM_CTRL:
619 obuf[0] = msg[0].buf[0] + 0x36;
620 obuf[1] = 3;
621 obuf[2] = 0;
622 if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
623 err("i2c transfer failed.");
624 break;
625 case DW2102_RC_QUERY:
626 obuf[0] = 0x10;
627 if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
628 err("i2c transfer failed.");
629 msg[0].buf[1] = ibuf[0];
630 msg[0].buf[0] = ibuf[1];
631 break;
632 default:
633 /* always i2c write*/
634 obuf[0] = 0x08;
635 obuf[1] = msg[0].addr;
636 obuf[2] = msg[0].len;
637
638 memcpy(&obuf[3], msg[0].buf, msg[0].len);
639
640 if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
641 ibuf, 1, 0) < 0)
642 err("i2c transfer failed.");
643
644 }
645 break;
646 case 2:
647 /* always i2c read */
648 obuf[0] = 0x09;
649 obuf[1] = msg[0].len;
650 obuf[2] = msg[1].len;
651 obuf[3] = msg[0].addr;
652 memcpy(&obuf[4], msg[0].buf, msg[0].len);
653
654 if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
655 ibuf, msg[1].len + 1, 0) < 0)
656 err("i2c transfer failed.");
657
658 memcpy(msg[1].buf, &ibuf[1], msg[1].len);
659 break;
660 default:
661 warn("more than 2 i2c messages at a time is not handled yet.");
662 break;
663 }
664 mutex_unlock(&d->i2c_mutex);
665 return num;
666}
667
668static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
669{
670 return I2C_FUNC_I2C;
671}
672
673static struct i2c_algorithm dw2102_i2c_algo = {
674 .master_xfer = dw2102_i2c_transfer,
675 .functionality = dw210x_i2c_func,
676};
677
678static struct i2c_algorithm dw2102_serit_i2c_algo = {
679 .master_xfer = dw2102_serit_i2c_transfer,
680 .functionality = dw210x_i2c_func,
681};
682
683static struct i2c_algorithm dw2102_earda_i2c_algo = {
684 .master_xfer = dw2102_earda_i2c_transfer,
685 .functionality = dw210x_i2c_func,
686};
687
688static struct i2c_algorithm dw2104_i2c_algo = {
689 .master_xfer = dw2104_i2c_transfer,
690 .functionality = dw210x_i2c_func,
691};
692
693static struct i2c_algorithm dw3101_i2c_algo = {
694 .master_xfer = dw3101_i2c_transfer,
695 .functionality = dw210x_i2c_func,
696};
697
698static struct i2c_algorithm s6x0_i2c_algo = {
699 .master_xfer = s6x0_i2c_transfer,
700 .functionality = dw210x_i2c_func,
701};
702
703static struct i2c_algorithm su3000_i2c_algo = {
704 .master_xfer = su3000_i2c_transfer,
705 .functionality = dw210x_i2c_func,
706};
707
708static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
709{
710 int i;
711 u8 ibuf[] = {0, 0};
712 u8 eeprom[256], eepromline[16];
713
714 for (i = 0; i < 256; i++) {
715 if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
716 err("read eeprom failed.");
717 return -1;
718 } else {
719 eepromline[i%16] = ibuf[0];
720 eeprom[i] = ibuf[0];
721 }
722 if ((i % 16) == 15) {
723 deb_xfer("%02x: ", i - 15);
724 debug_dump(eepromline, 16, deb_xfer);
725 }
726 }
727
728 memcpy(mac, eeprom + 8, 6);
729 return 0;
730};
731
732static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
733{
734 int i, ret;
735 u8 ibuf[] = { 0 }, obuf[] = { 0 };
736 u8 eeprom[256], eepromline[16];
737 struct i2c_msg msg[] = {
738 {
739 .addr = 0xa0 >> 1,
740 .flags = 0,
741 .buf = obuf,
742 .len = 1,
743 }, {
744 .addr = 0xa0 >> 1,
745 .flags = I2C_M_RD,
746 .buf = ibuf,
747 .len = 1,
748 }
749 };
750
751 for (i = 0; i < 256; i++) {
752 obuf[0] = i;
753 ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
754 if (ret != 2) {
755 err("read eeprom failed.");
756 return -1;
757 } else {
758 eepromline[i % 16] = ibuf[0];
759 eeprom[i] = ibuf[0];
760 }
761
762 if ((i % 16) == 15) {
763 deb_xfer("%02x: ", i - 15);
764 debug_dump(eepromline, 16, deb_xfer);
765 }
766 }
767
768 memcpy(mac, eeprom + 16, 6);
769 return 0;
770};
771
772static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
773{
774 static u8 command_start[] = {0x00};
775 static u8 command_stop[] = {0x01};
776 struct i2c_msg msg = {
777 .addr = SU3000_STREAM_CTRL,
778 .flags = 0,
779 .buf = onoff ? command_start : command_stop,
780 .len = 1
781 };
782
783 i2c_transfer(&adap->dev->i2c_adap, &msg, 1);
784
785 return 0;
786}
787
788static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
789{
790 struct su3000_state *state = (struct su3000_state *)d->priv;
791 u8 obuf[] = {0xde, 0};
792
793 info("%s: %d, initialized %d\n", __func__, i, state->initialized);
794
795 if (i && !state->initialized) {
796 state->initialized = 1;
797 /* reset board */
798 dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0);
799 }
800
801 return 0;
802}
803
804static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
805{
806 int i;
807 u8 obuf[] = { 0x1f, 0xf0 };
808 u8 ibuf[] = { 0 };
809 struct i2c_msg msg[] = {
810 {
811 .addr = 0x51,
812 .flags = 0,
813 .buf = obuf,
814 .len = 2,
815 }, {
816 .addr = 0x51,
817 .flags = I2C_M_RD,
818 .buf = ibuf,
819 .len = 1,
820
821 }
822 };
823
824 for (i = 0; i < 6; i++) {
825 obuf[1] = 0xf0 + i;
826 if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
827 break;
828 else
829 mac[i] = ibuf[0];
830
831 debug_dump(mac, 6, printk);
832 }
833
834 return 0;
835}
836
837static int su3000_identify_state(struct usb_device *udev,
838 struct dvb_usb_device_properties *props,
839 struct dvb_usb_device_description **desc,
840 int *cold)
841{
842 info("%s\n", __func__);
843
844 *cold = 0;
845 return 0;
846}
847
848static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
849{
850 static u8 command_13v[] = {0x00, 0x01};
851 static u8 command_18v[] = {0x01, 0x01};
852 static u8 command_off[] = {0x00, 0x00};
853 struct i2c_msg msg = {
854 .addr = DW2102_VOLTAGE_CTRL,
855 .flags = 0,
856 .buf = command_off,
857 .len = 2,
858 };
859
860 struct dvb_usb_adapter *udev_adap =
861 (struct dvb_usb_adapter *)(fe->dvb->priv);
862 if (voltage == SEC_VOLTAGE_18)
863 msg.buf = command_18v;
864 else if (voltage == SEC_VOLTAGE_13)
865 msg.buf = command_13v;
866
867 i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
868
869 return 0;
870}
871
872static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
873{
874 struct dvb_usb_adapter *d =
875 (struct dvb_usb_adapter *)(fe->dvb->priv);
876 struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
877
878 dw210x_set_voltage(fe, voltage);
879 if (st->old_set_voltage)
880 st->old_set_voltage(fe, voltage);
881
882 return 0;
883}
884
885static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon)
886{
887 static u8 led_off[] = { 0 };
888 static u8 led_on[] = { 1 };
889 struct i2c_msg msg = {
890 .addr = DW2102_LED_CTRL,
891 .flags = 0,
892 .buf = led_off,
893 .len = 1
894 };
895 struct dvb_usb_adapter *udev_adap =
896 (struct dvb_usb_adapter *)(fe->dvb->priv);
897
898 if (offon)
899 msg.buf = led_on;
900 i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
901}
902
903static struct stv0299_config sharp_z0194a_config = {
904 .demod_address = 0x68,
905 .inittab = sharp_z0194a_inittab,
906 .mclk = 88000000UL,
907 .invert = 1,
908 .skip_reinit = 0,
909 .lock_output = STV0299_LOCKOUTPUT_1,
910 .volt13_op0_op1 = STV0299_VOLT13_OP1,
911 .min_delay_ms = 100,
912 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
913};
914
915static struct cx24116_config dw2104_config = {
916 .demod_address = 0x55,
917 .mpg_clk_pos_pol = 0x01,
918};
919
920static struct si21xx_config serit_sp1511lhb_config = {
921 .demod_address = 0x68,
922 .min_delay_ms = 100,
923
924};
925
926static struct tda10023_config dw3101_tda10023_config = {
927 .demod_address = 0x0c,
928 .invert = 1,
929};
930
931static struct mt312_config zl313_config = {
932 .demod_address = 0x0e,
933};
934
935static struct ds3000_config dw2104_ds3000_config = {
936 .demod_address = 0x68,
937};
938
939static struct stv0900_config dw2104a_stv0900_config = {
940 .demod_address = 0x6a,
941 .demod_mode = 0,
942 .xtal = 27000000,
943 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
944 .diseqc_mode = 2,/* 2/3 PWM */
945 .tun1_maddress = 0,/* 0x60 */
946 .tun1_adc = 0,/* 2 Vpp */
947 .path1_mode = 3,
948};
949
950static struct stb6100_config dw2104a_stb6100_config = {
951 .tuner_address = 0x60,
952 .refclock = 27000000,
953};
954
955static struct stv0900_config dw2104_stv0900_config = {
956 .demod_address = 0x68,
957 .demod_mode = 0,
958 .xtal = 8000000,
959 .clkmode = 3,
960 .diseqc_mode = 2,
961 .tun1_maddress = 0,
962 .tun1_adc = 1,/* 1 Vpp */
963 .path1_mode = 3,
964};
965
966static struct stv6110_config dw2104_stv6110_config = {
967 .i2c_address = 0x60,
968 .mclk = 16000000,
969 .clk_div = 1,
970};
971
972static struct stv0900_config prof_7500_stv0900_config = {
973 .demod_address = 0x6a,
974 .demod_mode = 0,
975 .xtal = 27000000,
976 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
977 .diseqc_mode = 2,/* 2/3 PWM */
978 .tun1_maddress = 0,/* 0x60 */
979 .tun1_adc = 0,/* 2 Vpp */
980 .path1_mode = 3,
981 .tun1_type = 3,
982 .set_lock_led = dw210x_led_ctrl,
983};
984
985static struct ds3000_config su3000_ds3000_config = {
986 .demod_address = 0x68,
987 .ci_mode = 1,
988};
989
990static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
991{
992 struct dvb_tuner_ops *tuner_ops = NULL;
993
994 if (demod_probe & 4) {
995 d->fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
996 &d->dev->i2c_adap, 0);
997 if (d->fe != NULL) {
998 if (dvb_attach(stb6100_attach, d->fe,
999 &dw2104a_stb6100_config,
1000 &d->dev->i2c_adap)) {
1001 tuner_ops = &d->fe->ops.tuner_ops;
1002 tuner_ops->set_frequency = stb6100_set_freq;
1003 tuner_ops->get_frequency = stb6100_get_freq;
1004 tuner_ops->set_bandwidth = stb6100_set_bandw;
1005 tuner_ops->get_bandwidth = stb6100_get_bandw;
1006 d->fe->ops.set_voltage = dw210x_set_voltage;
1007 info("Attached STV0900+STB6100!\n");
1008 return 0;
1009 }
1010 }
1011 }
1012
1013 if (demod_probe & 2) {
1014 d->fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
1015 &d->dev->i2c_adap, 0);
1016 if (d->fe != NULL) {
1017 if (dvb_attach(stv6110_attach, d->fe,
1018 &dw2104_stv6110_config,
1019 &d->dev->i2c_adap)) {
1020 d->fe->ops.set_voltage = dw210x_set_voltage;
1021 info("Attached STV0900+STV6110A!\n");
1022 return 0;
1023 }
1024 }
1025 }
1026
1027 if (demod_probe & 1) {
1028 d->fe = dvb_attach(cx24116_attach, &dw2104_config,
1029 &d->dev->i2c_adap);
1030 if (d->fe != NULL) {
1031 d->fe->ops.set_voltage = dw210x_set_voltage;
1032 info("Attached cx24116!\n");
1033 return 0;
1034 }
1035 }
1036
1037 d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
1038 &d->dev->i2c_adap);
1039 if (d->fe != NULL) {
1040 d->fe->ops.set_voltage = dw210x_set_voltage;
1041 info("Attached DS3000!\n");
1042 return 0;
1043 }
1044
1045 return -EIO;
1046}
1047
1048static struct dvb_usb_device_properties dw2102_properties;
1049static struct dvb_usb_device_properties dw2104_properties;
1050static struct dvb_usb_device_properties s6x0_properties;
1051
1052static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
1053{
1054 if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
1055 /*dw2102_properties.adapter->tuner_attach = NULL;*/
1056 d->fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
1057 &d->dev->i2c_adap);
1058 if (d->fe != NULL) {
1059 d->fe->ops.set_voltage = dw210x_set_voltage;
1060 info("Attached si21xx!\n");
1061 return 0;
1062 }
1063 }
1064
1065 if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
1066 d->fe = dvb_attach(stv0288_attach, &earda_config,
1067 &d->dev->i2c_adap);
1068 if (d->fe != NULL) {
1069 if (dvb_attach(stb6000_attach, d->fe, 0x61,
1070 &d->dev->i2c_adap)) {
1071 d->fe->ops.set_voltage = dw210x_set_voltage;
1072 info("Attached stv0288!\n");
1073 return 0;
1074 }
1075 }
1076 }
1077
1078 if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
1079 /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
1080 d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
1081 &d->dev->i2c_adap);
1082 if (d->fe != NULL) {
1083 d->fe->ops.set_voltage = dw210x_set_voltage;
1084 info("Attached stv0299!\n");
1085 return 0;
1086 }
1087 }
1088 return -EIO;
1089}
1090
1091static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
1092{
1093 d->fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
1094 &d->dev->i2c_adap, 0x48);
1095 if (d->fe != NULL) {
1096 info("Attached tda10023!\n");
1097 return 0;
1098 }
1099 return -EIO;
1100}
1101
1102static int zl100313_frontend_attach(struct dvb_usb_adapter *d)
1103{
1104 d->fe = dvb_attach(mt312_attach, &zl313_config,
1105 &d->dev->i2c_adap);
1106 if (d->fe != NULL) {
1107 if (dvb_attach(zl10039_attach, d->fe, 0x60,
1108 &d->dev->i2c_adap)) {
1109 d->fe->ops.set_voltage = dw210x_set_voltage;
1110 info("Attached zl100313+zl10039!\n");
1111 return 0;
1112 }
1113 }
1114
1115 return -EIO;
1116}
1117
1118static int stv0288_frontend_attach(struct dvb_usb_adapter *d)
1119{
1120 u8 obuf[] = {7, 1};
1121
1122 d->fe = dvb_attach(stv0288_attach, &earda_config,
1123 &d->dev->i2c_adap);
1124
1125 if (d->fe == NULL)
1126 return -EIO;
1127
1128 if (NULL == dvb_attach(stb6000_attach, d->fe, 0x61, &d->dev->i2c_adap))
1129 return -EIO;
1130
1131 d->fe->ops.set_voltage = dw210x_set_voltage;
1132
1133 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1134
1135 info("Attached stv0288+stb6000!\n");
1136
1137 return 0;
1138
1139}
1140
1141static int ds3000_frontend_attach(struct dvb_usb_adapter *d)
1142{
1143 struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
1144 u8 obuf[] = {7, 1};
1145
1146 d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
1147 &d->dev->i2c_adap);
1148
1149 if (d->fe == NULL)
1150 return -EIO;
1151
1152 st->old_set_voltage = d->fe->ops.set_voltage;
1153 d->fe->ops.set_voltage = s660_set_voltage;
1154
1155 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1156
1157 info("Attached ds3000+ds2020!\n");
1158
1159 return 0;
1160}
1161
1162static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
1163{
1164 u8 obuf[] = {7, 1};
1165
1166 d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
1167 &d->dev->i2c_adap, 0);
1168 if (d->fe == NULL)
1169 return -EIO;
1170
1171 d->fe->ops.set_voltage = dw210x_set_voltage;
1172
1173 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1174
1175 info("Attached STV0900+STB6100A!\n");
1176
1177 return 0;
1178}
1179
1180static int su3000_frontend_attach(struct dvb_usb_adapter *d)
1181{
1182 u8 obuf[3] = { 0xe, 0x80, 0 };
1183 u8 ibuf[] = { 0 };
1184
1185 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1186 err("command 0x0e transfer failed.");
1187
1188 obuf[0] = 0xe;
1189 obuf[1] = 0x83;
1190 obuf[2] = 0;
1191
1192 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1193 err("command 0x0e transfer failed.");
1194
1195 obuf[0] = 0xe;
1196 obuf[1] = 0x83;
1197 obuf[2] = 1;
1198
1199 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1200 err("command 0x0e transfer failed.");
1201
1202 obuf[0] = 0x51;
1203
1204 if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
1205 err("command 0x51 transfer failed.");
1206
1207 d->fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
1208 &d->dev->i2c_adap);
1209 if (d->fe == NULL)
1210 return -EIO;
1211
1212 info("Attached DS3000!\n");
1213
1214 return 0;
1215}
1216
1217static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
1218{
1219 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
1220 &adap->dev->i2c_adap, DVB_PLL_OPERA1);
1221 return 0;
1222}
1223
1224static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
1225{
1226 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
1227 &adap->dev->i2c_adap, DVB_PLL_TUA6034);
1228
1229 return 0;
1230}
1231
1232static struct rc_map_table rc_map_dw210x_table[] = {
1233 { 0xf80a, KEY_POWER2 }, /*power*/
1234 { 0xf80c, KEY_MUTE }, /*mute*/
1235 { 0xf811, KEY_1 },
1236 { 0xf812, KEY_2 },
1237 { 0xf813, KEY_3 },
1238 { 0xf814, KEY_4 },
1239 { 0xf815, KEY_5 },
1240 { 0xf816, KEY_6 },
1241 { 0xf817, KEY_7 },
1242 { 0xf818, KEY_8 },
1243 { 0xf819, KEY_9 },
1244 { 0xf810, KEY_0 },
1245 { 0xf81c, KEY_CHANNELUP }, /*ch+*/
1246 { 0xf80f, KEY_CHANNELDOWN }, /*ch-*/
1247 { 0xf81a, KEY_VOLUMEUP }, /*vol+*/
1248 { 0xf80e, KEY_VOLUMEDOWN }, /*vol-*/
1249 { 0xf804, KEY_RECORD }, /*rec*/
1250 { 0xf809, KEY_FAVORITES }, /*fav*/
1251 { 0xf808, KEY_REWIND }, /*rewind*/
1252 { 0xf807, KEY_FASTFORWARD }, /*fast*/
1253 { 0xf80b, KEY_PAUSE }, /*pause*/
1254 { 0xf802, KEY_ESC }, /*cancel*/
1255 { 0xf803, KEY_TAB }, /*tab*/
1256 { 0xf800, KEY_UP }, /*up*/
1257 { 0xf81f, KEY_OK }, /*ok*/
1258 { 0xf801, KEY_DOWN }, /*down*/
1259 { 0xf805, KEY_CAMERA }, /*cap*/
1260 { 0xf806, KEY_STOP }, /*stop*/
1261 { 0xf840, KEY_ZOOM }, /*full*/
1262 { 0xf81e, KEY_TV }, /*tvmode*/
1263 { 0xf81b, KEY_LAST }, /*recall*/
1264};
1265
1266static struct rc_map_table rc_map_tevii_table[] = {
1267 { 0xf80a, KEY_POWER },
1268 { 0xf80c, KEY_MUTE },
1269 { 0xf811, KEY_1 },
1270 { 0xf812, KEY_2 },
1271 { 0xf813, KEY_3 },
1272 { 0xf814, KEY_4 },
1273 { 0xf815, KEY_5 },
1274 { 0xf816, KEY_6 },
1275 { 0xf817, KEY_7 },
1276 { 0xf818, KEY_8 },
1277 { 0xf819, KEY_9 },
1278 { 0xf810, KEY_0 },
1279 { 0xf81c, KEY_MENU },
1280 { 0xf80f, KEY_VOLUMEDOWN },
1281 { 0xf81a, KEY_LAST },
1282 { 0xf80e, KEY_OPEN },
1283 { 0xf804, KEY_RECORD },
1284 { 0xf809, KEY_VOLUMEUP },
1285 { 0xf808, KEY_CHANNELUP },
1286 { 0xf807, KEY_PVR },
1287 { 0xf80b, KEY_TIME },
1288 { 0xf802, KEY_RIGHT },
1289 { 0xf803, KEY_LEFT },
1290 { 0xf800, KEY_UP },
1291 { 0xf81f, KEY_OK },
1292 { 0xf801, KEY_DOWN },
1293 { 0xf805, KEY_TUNER },
1294 { 0xf806, KEY_CHANNELDOWN },
1295 { 0xf840, KEY_PLAYPAUSE },
1296 { 0xf81e, KEY_REWIND },
1297 { 0xf81b, KEY_FAVORITES },
1298 { 0xf81d, KEY_BACK },
1299 { 0xf84d, KEY_FASTFORWARD },
1300 { 0xf844, KEY_EPG },
1301 { 0xf84c, KEY_INFO },
1302 { 0xf841, KEY_AB },
1303 { 0xf843, KEY_AUDIO },
1304 { 0xf845, KEY_SUBTITLE },
1305 { 0xf84a, KEY_LIST },
1306 { 0xf846, KEY_F1 },
1307 { 0xf847, KEY_F2 },
1308 { 0xf85e, KEY_F3 },
1309 { 0xf85c, KEY_F4 },
1310 { 0xf852, KEY_F5 },
1311 { 0xf85a, KEY_F6 },
1312 { 0xf856, KEY_MODE },
1313 { 0xf858, KEY_SWITCHVIDEOMODE },
1314};
1315
1316static struct rc_map_table rc_map_tbs_table[] = {
1317 { 0xf884, KEY_POWER },
1318 { 0xf894, KEY_MUTE },
1319 { 0xf887, KEY_1 },
1320 { 0xf886, KEY_2 },
1321 { 0xf885, KEY_3 },
1322 { 0xf88b, KEY_4 },
1323 { 0xf88a, KEY_5 },
1324 { 0xf889, KEY_6 },
1325 { 0xf88f, KEY_7 },
1326 { 0xf88e, KEY_8 },
1327 { 0xf88d, KEY_9 },
1328 { 0xf892, KEY_0 },
1329 { 0xf896, KEY_CHANNELUP },
1330 { 0xf891, KEY_CHANNELDOWN },
1331 { 0xf893, KEY_VOLUMEUP },
1332 { 0xf88c, KEY_VOLUMEDOWN },
1333 { 0xf883, KEY_RECORD },
1334 { 0xf898, KEY_PAUSE },
1335 { 0xf899, KEY_OK },
1336 { 0xf89a, KEY_SHUFFLE },
1337 { 0xf881, KEY_UP },
1338 { 0xf890, KEY_LEFT },
1339 { 0xf882, KEY_RIGHT },
1340 { 0xf888, KEY_DOWN },
1341 { 0xf895, KEY_FAVORITES },
1342 { 0xf897, KEY_SUBTITLE },
1343 { 0xf89d, KEY_ZOOM },
1344 { 0xf89f, KEY_EXIT },
1345 { 0xf89e, KEY_MENU },
1346 { 0xf89c, KEY_EPG },
1347 { 0xf880, KEY_PREVIOUS },
1348 { 0xf89b, KEY_MODE }
1349};
1350
1351static struct rc_map_table rc_map_su3000_table[] = {
1352 { 0x25, KEY_POWER }, /* right-bottom Red */
1353 { 0x0a, KEY_MUTE }, /* -/-- */
1354 { 0x01, KEY_1 },
1355 { 0x02, KEY_2 },
1356 { 0x03, KEY_3 },
1357 { 0x04, KEY_4 },
1358 { 0x05, KEY_5 },
1359 { 0x06, KEY_6 },
1360 { 0x07, KEY_7 },
1361 { 0x08, KEY_8 },
1362 { 0x09, KEY_9 },
1363 { 0x00, KEY_0 },
1364 { 0x20, KEY_UP }, /* CH+ */
1365 { 0x21, KEY_DOWN }, /* CH+ */
1366 { 0x12, KEY_VOLUMEUP }, /* Brightness Up */
1367 { 0x13, KEY_VOLUMEDOWN },/* Brightness Down */
1368 { 0x1f, KEY_RECORD },
1369 { 0x17, KEY_PLAY },
1370 { 0x16, KEY_PAUSE },
1371 { 0x0b, KEY_STOP },
1372 { 0x27, KEY_FASTFORWARD },/* >> */
1373 { 0x26, KEY_REWIND }, /* << */
1374 { 0x0d, KEY_OK }, /* Mute */
1375 { 0x11, KEY_LEFT }, /* VOL- */
1376 { 0x10, KEY_RIGHT }, /* VOL+ */
1377 { 0x29, KEY_BACK }, /* button under 9 */
1378 { 0x2c, KEY_MENU }, /* TTX */
1379 { 0x2b, KEY_EPG }, /* EPG */
1380 { 0x1e, KEY_RED }, /* OSD */
1381 { 0x0e, KEY_GREEN }, /* Window */
1382 { 0x2d, KEY_YELLOW }, /* button under << */
1383 { 0x0f, KEY_BLUE }, /* bottom yellow button */
1384 { 0x14, KEY_AUDIO }, /* Snapshot */
1385 { 0x38, KEY_TV }, /* TV/Radio */
1386 { 0x0c, KEY_ESC } /* upper Red button */
1387};
1388
1389static struct rc_map_dvb_usb_table_table keys_tables[] = {
1390 { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) },
1391 { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) },
1392 { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) },
1393 { rc_map_su3000_table, ARRAY_SIZE(rc_map_su3000_table) },
1394};
1395
1396static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
1397{
1398 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
1399 int keymap_size = d->props.rc.legacy.rc_map_size;
1400 u8 key[2];
1401 struct i2c_msg msg = {
1402 .addr = DW2102_RC_QUERY,
1403 .flags = I2C_M_RD,
1404 .buf = key,
1405 .len = 2
1406 };
1407 int i;
1408 /* override keymap */
1409 if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) {
1410 keymap = keys_tables[ir_keymap - 1].rc_keys ;
1411 keymap_size = keys_tables[ir_keymap - 1].rc_keys_size;
1412 } else if (ir_keymap > ARRAY_SIZE(keys_tables))
1413 return 0; /* none */
1414
1415 *state = REMOTE_NO_KEY_PRESSED;
1416 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
1417 for (i = 0; i < keymap_size ; i++) {
1418 if (rc5_data(&keymap[i]) == msg.buf[0]) {
1419 *state = REMOTE_KEY_PRESSED;
1420 *event = keymap[i].keycode;
1421 break;
1422 }
1423
1424 }
1425
1426 if ((*state) == REMOTE_KEY_PRESSED)
1427 deb_rc("%s: found rc key: %x, %x, event: %x\n",
1428 __func__, key[0], key[1], (*event));
1429 else if (key[0] != 0xff)
1430 deb_rc("%s: unknown rc key: %x, %x\n",
1431 __func__, key[0], key[1]);
1432
1433 }
1434
1435 return 0;
1436}
1437
1438static struct usb_device_id dw2102_table[] = {
1439 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
1440 {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
1441 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)},
1442 {USB_DEVICE(0x9022, USB_PID_TEVII_S650)},
1443 {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
1444 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
1445 {USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
1446 {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
1447 {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
1448 {USB_DEVICE(0x3034, 0x7500)},
1449 {USB_DEVICE(0x1f4d, 0x3000)},
1450 {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)},
1451 {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)},
1452 {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
1453 {USB_DEVICE(0x1f4d, 0x3100)},
1454 { }
1455};
1456
1457MODULE_DEVICE_TABLE(usb, dw2102_table);
1458
1459static int dw2102_load_firmware(struct usb_device *dev,
1460 const struct firmware *frmwr)
1461{
1462 u8 *b, *p;
1463 int ret = 0, i;
1464 u8 reset;
1465 u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
1466 const struct firmware *fw;
1467 const char *fw_2101 = "dvb-usb-dw2101.fw";
1468
1469 switch (dev->descriptor.idProduct) {
1470 case 0x2101:
1471 ret = request_firmware(&fw, fw_2101, &dev->dev);
1472 if (ret != 0) {
1473 err(err_str, fw_2101);
1474 return ret;
1475 }
1476 break;
1477 default:
1478 fw = frmwr;
1479 break;
1480 }
1481 info("start downloading DW210X firmware");
1482 p = kmalloc(fw->size, GFP_KERNEL);
1483 reset = 1;
1484 /*stop the CPU*/
1485 dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
1486 dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
1487
1488 if (p != NULL) {
1489 memcpy(p, fw->data, fw->size);
1490 for (i = 0; i < fw->size; i += 0x40) {
1491 b = (u8 *) p + i;
1492 if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
1493 DW210X_WRITE_MSG) != 0x40) {
1494 err("error while transferring firmware");
1495 ret = -EINVAL;
1496 break;
1497 }
1498 }
1499 /* restart the CPU */
1500 reset = 0;
1501 if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
1502 DW210X_WRITE_MSG) != 1) {
1503 err("could not restart the USB controller CPU.");
1504 ret = -EINVAL;
1505 }
1506 if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
1507 DW210X_WRITE_MSG) != 1) {
1508 err("could not restart the USB controller CPU.");
1509 ret = -EINVAL;
1510 }
1511 /* init registers */
1512 switch (dev->descriptor.idProduct) {
1513 case USB_PID_TEVII_S650:
1514 dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table;
1515 dw2104_properties.rc.legacy.rc_map_size =
1516 ARRAY_SIZE(rc_map_tevii_table);
1517 case USB_PID_DW2104:
1518 reset = 1;
1519 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
1520 DW210X_WRITE_MSG);
1521 /* break omitted intentionally */
1522 case USB_PID_DW3101:
1523 reset = 0;
1524 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
1525 DW210X_WRITE_MSG);
1526 break;
1527 case USB_PID_CINERGY_S:
1528 case USB_PID_DW2102:
1529 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
1530 DW210X_WRITE_MSG);
1531 dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
1532 DW210X_READ_MSG);
1533 /* check STV0299 frontend */
1534 dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
1535 DW210X_READ_MSG);
1536 if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) {
1537 dw2102_properties.i2c_algo = &dw2102_i2c_algo;
1538 dw2102_properties.adapter->tuner_attach = &dw2102_tuner_attach;
1539 break;
1540 } else {
1541 /* check STV0288 frontend */
1542 reset16[0] = 0xd0;
1543 reset16[1] = 1;
1544 reset16[2] = 0;
1545 dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
1546 DW210X_WRITE_MSG);
1547 dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
1548 DW210X_READ_MSG);
1549 if (reset16[2] == 0x11) {
1550 dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
1551 break;
1552 }
1553 }
1554 case 0x2101:
1555 dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
1556 DW210X_READ_MSG);
1557 dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
1558 DW210X_READ_MSG);
1559 dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
1560 DW210X_READ_MSG);
1561 dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
1562 DW210X_READ_MSG);
1563 break;
1564 }
1565
1566 msleep(100);
1567 kfree(p);
1568 }
1569 return ret;
1570}
1571
1572static struct dvb_usb_device_properties dw2102_properties = {
1573 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1574 .usb_ctrl = DEVICE_SPECIFIC,
1575 .firmware = "dvb-usb-dw2102.fw",
1576 .no_reconnect = 1,
1577
1578 .i2c_algo = &dw2102_serit_i2c_algo,
1579
1580 .rc.legacy = {
1581 .rc_map_table = rc_map_dw210x_table,
1582 .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
1583 .rc_interval = 150,
1584 .rc_query = dw2102_rc_query,
1585 },
1586
1587 .generic_bulk_ctrl_endpoint = 0x81,
1588 /* parameter for the MPEG2-data transfer */
1589 .num_adapters = 1,
1590 .download_firmware = dw2102_load_firmware,
1591 .read_mac_address = dw210x_read_mac_address,
1592 .adapter = {
1593 {
1594 .frontend_attach = dw2102_frontend_attach,
1595 .stream = {
1596 .type = USB_BULK,
1597 .count = 8,
1598 .endpoint = 0x82,
1599 .u = {
1600 .bulk = {
1601 .buffersize = 4096,
1602 }
1603 }
1604 },
1605 }
1606 },
1607 .num_device_descs = 3,
1608 .devices = {
1609 {"DVBWorld DVB-S 2102 USB2.0",
1610 {&dw2102_table[0], NULL},
1611 {NULL},
1612 },
1613 {"DVBWorld DVB-S 2101 USB2.0",
1614 {&dw2102_table[1], NULL},
1615 {NULL},
1616 },
1617 {"TerraTec Cinergy S USB",
1618 {&dw2102_table[4], NULL},
1619 {NULL},
1620 },
1621 }
1622};
1623
1624static struct dvb_usb_device_properties dw2104_properties = {
1625 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1626 .usb_ctrl = DEVICE_SPECIFIC,
1627 .firmware = "dvb-usb-dw2104.fw",
1628 .no_reconnect = 1,
1629
1630 .i2c_algo = &dw2104_i2c_algo,
1631 .rc.legacy = {
1632 .rc_map_table = rc_map_dw210x_table,
1633 .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
1634 .rc_interval = 150,
1635 .rc_query = dw2102_rc_query,
1636 },
1637
1638 .generic_bulk_ctrl_endpoint = 0x81,
1639 /* parameter for the MPEG2-data transfer */
1640 .num_adapters = 1,
1641 .download_firmware = dw2102_load_firmware,
1642 .read_mac_address = dw210x_read_mac_address,
1643 .adapter = {
1644 {
1645 .frontend_attach = dw2104_frontend_attach,
1646 .stream = {
1647 .type = USB_BULK,
1648 .count = 8,
1649 .endpoint = 0x82,
1650 .u = {
1651 .bulk = {
1652 .buffersize = 4096,
1653 }
1654 }
1655 },
1656 }
1657 },
1658 .num_device_descs = 2,
1659 .devices = {
1660 { "DVBWorld DW2104 USB2.0",
1661 {&dw2102_table[2], NULL},
1662 {NULL},
1663 },
1664 { "TeVii S650 USB2.0",
1665 {&dw2102_table[3], NULL},
1666 {NULL},
1667 },
1668 }
1669};
1670
1671static struct dvb_usb_device_properties dw3101_properties = {
1672 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1673 .usb_ctrl = DEVICE_SPECIFIC,
1674 .firmware = "dvb-usb-dw3101.fw",
1675 .no_reconnect = 1,
1676
1677 .i2c_algo = &dw3101_i2c_algo,
1678 .rc.legacy = {
1679 .rc_map_table = rc_map_dw210x_table,
1680 .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
1681 .rc_interval = 150,
1682 .rc_query = dw2102_rc_query,
1683 },
1684
1685 .generic_bulk_ctrl_endpoint = 0x81,
1686 /* parameter for the MPEG2-data transfer */
1687 .num_adapters = 1,
1688 .download_firmware = dw2102_load_firmware,
1689 .read_mac_address = dw210x_read_mac_address,
1690 .adapter = {
1691 {
1692 .frontend_attach = dw3101_frontend_attach,
1693 .tuner_attach = dw3101_tuner_attach,
1694 .stream = {
1695 .type = USB_BULK,
1696 .count = 8,
1697 .endpoint = 0x82,
1698 .u = {
1699 .bulk = {
1700 .buffersize = 4096,
1701 }
1702 }
1703 },
1704 }
1705 },
1706 .num_device_descs = 1,
1707 .devices = {
1708 { "DVBWorld DVB-C 3101 USB2.0",
1709 {&dw2102_table[5], NULL},
1710 {NULL},
1711 },
1712 }
1713};
1714
1715static struct dvb_usb_device_properties s6x0_properties = {
1716 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1717 .usb_ctrl = DEVICE_SPECIFIC,
1718 .size_of_priv = sizeof(struct s6x0_state),
1719 .firmware = "dvb-usb-s630.fw",
1720 .no_reconnect = 1,
1721
1722 .i2c_algo = &s6x0_i2c_algo,
1723 .rc.legacy = {
1724 .rc_map_table = rc_map_tevii_table,
1725 .rc_map_size = ARRAY_SIZE(rc_map_tevii_table),
1726 .rc_interval = 150,
1727 .rc_query = dw2102_rc_query,
1728 },
1729
1730 .generic_bulk_ctrl_endpoint = 0x81,
1731 .num_adapters = 1,
1732 .download_firmware = dw2102_load_firmware,
1733 .read_mac_address = s6x0_read_mac_address,
1734 .adapter = {
1735 {
1736 .frontend_attach = zl100313_frontend_attach,
1737 .stream = {
1738 .type = USB_BULK,
1739 .count = 8,
1740 .endpoint = 0x82,
1741 .u = {
1742 .bulk = {
1743 .buffersize = 4096,
1744 }
1745 }
1746 },
1747 }
1748 },
1749 .num_device_descs = 1,
1750 .devices = {
1751 {"TeVii S630 USB",
1752 {&dw2102_table[6], NULL},
1753 {NULL},
1754 },
1755 }
1756};
1757
1758struct dvb_usb_device_properties *p1100;
1759static struct dvb_usb_device_description d1100 = {
1760 "Prof 1100 USB ",
1761 {&dw2102_table[7], NULL},
1762 {NULL},
1763};
1764
1765struct dvb_usb_device_properties *s660;
1766static struct dvb_usb_device_description d660 = {
1767 "TeVii S660 USB",
1768 {&dw2102_table[8], NULL},
1769 {NULL},
1770};
1771
1772static struct dvb_usb_device_description d480_1 = {
1773 "TeVii S480.1 USB",
1774 {&dw2102_table[12], NULL},
1775 {NULL},
1776};
1777
1778static struct dvb_usb_device_description d480_2 = {
1779 "TeVii S480.2 USB",
1780 {&dw2102_table[13], NULL},
1781 {NULL},
1782};
1783
1784struct dvb_usb_device_properties *p7500;
1785static struct dvb_usb_device_description d7500 = {
1786 "Prof 7500 USB DVB-S2",
1787 {&dw2102_table[9], NULL},
1788 {NULL},
1789};
1790
1791static struct dvb_usb_device_properties su3000_properties = {
1792 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1793 .usb_ctrl = DEVICE_SPECIFIC,
1794 .size_of_priv = sizeof(struct su3000_state),
1795 .power_ctrl = su3000_power_ctrl,
1796 .num_adapters = 1,
1797 .identify_state = su3000_identify_state,
1798 .i2c_algo = &su3000_i2c_algo,
1799
1800 .rc.legacy = {
1801 .rc_map_table = rc_map_su3000_table,
1802 .rc_map_size = ARRAY_SIZE(rc_map_su3000_table),
1803 .rc_interval = 150,
1804 .rc_query = dw2102_rc_query,
1805 },
1806
1807 .read_mac_address = su3000_read_mac_address,
1808
1809 .generic_bulk_ctrl_endpoint = 0x01,
1810
1811 .adapter = {
1812 {
1813 .streaming_ctrl = su3000_streaming_ctrl,
1814 .frontend_attach = su3000_frontend_attach,
1815 .stream = {
1816 .type = USB_BULK,
1817 .count = 8,
1818 .endpoint = 0x82,
1819 .u = {
1820 .bulk = {
1821 .buffersize = 4096,
1822 }
1823 }
1824 }
1825 }
1826 },
1827 .num_device_descs = 3,
1828 .devices = {
1829 { "SU3000HD DVB-S USB2.0",
1830 { &dw2102_table[10], NULL },
1831 { NULL },
1832 },
1833 { "Terratec Cinergy S2 USB HD",
1834 { &dw2102_table[11], NULL },
1835 { NULL },
1836 },
1837 { "X3M TV SPC1400HD PCI",
1838 { &dw2102_table[14], NULL },
1839 { NULL },
1840 },
1841 }
1842};
1843
1844static int dw2102_probe(struct usb_interface *intf,
1845 const struct usb_device_id *id)
1846{
1847 p1100 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1848 if (!p1100)
1849 return -ENOMEM;
1850 /* copy default structure */
1851 memcpy(p1100, &s6x0_properties,
1852 sizeof(struct dvb_usb_device_properties));
1853 /* fill only different fields */
1854 p1100->firmware = "dvb-usb-p1100.fw";
1855 p1100->devices[0] = d1100;
1856 p1100->rc.legacy.rc_map_table = rc_map_tbs_table;
1857 p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
1858 p1100->adapter->frontend_attach = stv0288_frontend_attach;
1859
1860 s660 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1861 if (!s660) {
1862 kfree(p1100);
1863 return -ENOMEM;
1864 }
1865 memcpy(s660, &s6x0_properties,
1866 sizeof(struct dvb_usb_device_properties));
1867 s660->firmware = "dvb-usb-s660.fw";
1868 s660->num_device_descs = 3;
1869 s660->devices[0] = d660;
1870 s660->devices[1] = d480_1;
1871 s660->devices[2] = d480_2;
1872 s660->adapter->frontend_attach = ds3000_frontend_attach;
1873
1874 p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1875 if (!p7500) {
1876 kfree(p1100);
1877 kfree(s660);
1878 return -ENOMEM;
1879 }
1880 memcpy(p7500, &s6x0_properties,
1881 sizeof(struct dvb_usb_device_properties));
1882 p7500->firmware = "dvb-usb-p7500.fw";
1883 p7500->devices[0] = d7500;
1884 p7500->rc.legacy.rc_map_table = rc_map_tbs_table;
1885 p7500->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
1886 p7500->adapter->frontend_attach = prof_7500_frontend_attach;
1887
1888 if (0 == dvb_usb_device_init(intf, &dw2102_properties,
1889 THIS_MODULE, NULL, adapter_nr) ||
1890 0 == dvb_usb_device_init(intf, &dw2104_properties,
1891 THIS_MODULE, NULL, adapter_nr) ||
1892 0 == dvb_usb_device_init(intf, &dw3101_properties,
1893 THIS_MODULE, NULL, adapter_nr) ||
1894 0 == dvb_usb_device_init(intf, &s6x0_properties,
1895 THIS_MODULE, NULL, adapter_nr) ||
1896 0 == dvb_usb_device_init(intf, p1100,
1897 THIS_MODULE, NULL, adapter_nr) ||
1898 0 == dvb_usb_device_init(intf, s660,
1899 THIS_MODULE, NULL, adapter_nr) ||
1900 0 == dvb_usb_device_init(intf, p7500,
1901 THIS_MODULE, NULL, adapter_nr) ||
1902 0 == dvb_usb_device_init(intf, &su3000_properties,
1903 THIS_MODULE, NULL, adapter_nr))
1904 return 0;
1905
1906 return -ENODEV;
1907}
1908
1909static struct usb_driver dw2102_driver = {
1910 .name = "dw2102",
1911 .probe = dw2102_probe,
1912 .disconnect = dvb_usb_device_exit,
1913 .id_table = dw2102_table,
1914};
1915
1916static int __init dw2102_module_init(void)
1917{
1918 int ret = usb_register(&dw2102_driver);
1919 if (ret)
1920 err("usb_register failed. Error number %d", ret);
1921
1922 return ret;
1923}
1924
1925static void __exit dw2102_module_exit(void)
1926{
1927 usb_deregister(&dw2102_driver);
1928}
1929
1930module_init(dw2102_module_init);
1931module_exit(dw2102_module_exit);
1932
1933MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
1934MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
1935 " DVB-C 3101 USB2.0,"
1936 " TeVii S600, S630, S650, S660, S480,"
1937 " Prof 1100, 7500 USB2.0,"
1938 " Geniatech SU3000 devices");
1939MODULE_VERSION("0.1");
1940MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/dw2102.h b/drivers/media/dvb/dvb-usb/dw2102.h
new file mode 100644
index 00000000000..5cd0b0eb6ce
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/dw2102.h
@@ -0,0 +1,9 @@
1#ifndef _DW2102_H_
2#define _DW2102_H_
3
4#define DVB_USB_LOG_PREFIX "dw2102"
5#include "dvb-usb.h"
6
7#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args)
8#define deb_rc(args...) dprintk(dvb_usb_dw2102_debug, 0x04, args)
9#endif
diff --git a/drivers/media/dvb/dvb-usb/ec168.c b/drivers/media/dvb/dvb-usb/ec168.c
new file mode 100644
index 00000000000..1ba3e5dbee1
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ec168.c
@@ -0,0 +1,452 @@
1/*
2 * E3C EC168 DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#include "ec168.h"
23#include "ec100.h"
24#include "mxl5005s.h"
25
26/* debug */
27static int dvb_usb_ec168_debug;
28module_param_named(debug, dvb_usb_ec168_debug, int, 0644);
29MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
30DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
31
32static struct ec100_config ec168_ec100_config;
33
34static int ec168_rw_udev(struct usb_device *udev, struct ec168_req *req)
35{
36 int ret;
37 unsigned int pipe;
38 u8 request, requesttype;
39 u8 *buf;
40
41
42
43 switch (req->cmd) {
44 case DOWNLOAD_FIRMWARE:
45 case GPIO:
46 case WRITE_I2C:
47 case STREAMING_CTRL:
48 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
49 request = req->cmd;
50 break;
51 case READ_I2C:
52 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
53 request = req->cmd;
54 break;
55 case GET_CONFIG:
56 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
57 request = CONFIG;
58 break;
59 case SET_CONFIG:
60 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
61 request = CONFIG;
62 break;
63 case WRITE_DEMOD:
64 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
65 request = DEMOD_RW;
66 break;
67 case READ_DEMOD:
68 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
69 request = DEMOD_RW;
70 break;
71 default:
72 err("unknown command:%02x", req->cmd);
73 ret = -EPERM;
74 goto error;
75 }
76
77 buf = kmalloc(req->size, GFP_KERNEL);
78 if (!buf) {
79 ret = -ENOMEM;
80 goto error;
81 }
82
83 if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
84 /* write */
85 memcpy(buf, req->data, req->size);
86 pipe = usb_sndctrlpipe(udev, 0);
87 } else {
88 /* read */
89 pipe = usb_rcvctrlpipe(udev, 0);
90 }
91
92 msleep(1); /* avoid I2C errors */
93
94 ret = usb_control_msg(udev, pipe, request, requesttype, req->value,
95 req->index, buf, req->size, EC168_USB_TIMEOUT);
96
97 ec168_debug_dump(request, requesttype, req->value, req->index, buf,
98 req->size, deb_xfer);
99
100 if (ret < 0)
101 goto err_dealloc;
102 else
103 ret = 0;
104
105 /* read request, copy returned data to return buf */
106 if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
107 memcpy(req->data, buf, req->size);
108
109 kfree(buf);
110 return ret;
111
112err_dealloc:
113 kfree(buf);
114error:
115 deb_info("%s: failed:%d\n", __func__, ret);
116 return ret;
117}
118
119static int ec168_ctrl_msg(struct dvb_usb_device *d, struct ec168_req *req)
120{
121 return ec168_rw_udev(d->udev, req);
122}
123
124/* I2C */
125static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
126 int num)
127{
128 struct dvb_usb_device *d = i2c_get_adapdata(adap);
129 struct ec168_req req;
130 int i = 0;
131 int ret;
132
133 if (num > 2)
134 return -EINVAL;
135
136 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
137 return -EAGAIN;
138
139 while (i < num) {
140 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
141 if (msg[i].addr == ec168_ec100_config.demod_address) {
142 req.cmd = READ_DEMOD;
143 req.value = 0;
144 req.index = 0xff00 + msg[i].buf[0]; /* reg */
145 req.size = msg[i+1].len; /* bytes to read */
146 req.data = &msg[i+1].buf[0];
147 ret = ec168_ctrl_msg(d, &req);
148 i += 2;
149 } else {
150 err("I2C read not implemented");
151 ret = -ENOSYS;
152 i += 2;
153 }
154 } else {
155 if (msg[i].addr == ec168_ec100_config.demod_address) {
156 req.cmd = WRITE_DEMOD;
157 req.value = msg[i].buf[1]; /* val */
158 req.index = 0xff00 + msg[i].buf[0]; /* reg */
159 req.size = 0;
160 req.data = NULL;
161 ret = ec168_ctrl_msg(d, &req);
162 i += 1;
163 } else {
164 req.cmd = WRITE_I2C;
165 req.value = msg[i].buf[0]; /* val */
166 req.index = 0x0100 + msg[i].addr; /* I2C addr */
167 req.size = msg[i].len-1;
168 req.data = &msg[i].buf[1];
169 ret = ec168_ctrl_msg(d, &req);
170 i += 1;
171 }
172 }
173 if (ret)
174 goto error;
175
176 }
177 ret = i;
178
179error:
180 mutex_unlock(&d->i2c_mutex);
181 return i;
182}
183
184
185static u32 ec168_i2c_func(struct i2c_adapter *adapter)
186{
187 return I2C_FUNC_I2C;
188}
189
190static struct i2c_algorithm ec168_i2c_algo = {
191 .master_xfer = ec168_i2c_xfer,
192 .functionality = ec168_i2c_func,
193};
194
195/* Callbacks for DVB USB */
196static struct ec100_config ec168_ec100_config = {
197 .demod_address = 0xff, /* not real address, demod is integrated */
198};
199
200static int ec168_ec100_frontend_attach(struct dvb_usb_adapter *adap)
201{
202 deb_info("%s:\n", __func__);
203 adap->fe = dvb_attach(ec100_attach, &ec168_ec100_config,
204 &adap->dev->i2c_adap);
205 if (adap->fe == NULL)
206 return -ENODEV;
207
208 return 0;
209}
210
211static struct mxl5005s_config ec168_mxl5003s_config = {
212 .i2c_address = 0xc6,
213 .if_freq = IF_FREQ_4570000HZ,
214 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
215 .agc_mode = MXL_SINGLE_AGC,
216 .tracking_filter = MXL_TF_OFF,
217 .rssi_enable = MXL_RSSI_ENABLE,
218 .cap_select = MXL_CAP_SEL_ENABLE,
219 .div_out = MXL_DIV_OUT_4,
220 .clock_out = MXL_CLOCK_OUT_DISABLE,
221 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
222 .top = MXL5005S_TOP_25P2,
223 .mod_mode = MXL_DIGITAL_MODE,
224 .if_mode = MXL_ZERO_IF,
225 .AgcMasterByte = 0x00,
226};
227
228static int ec168_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
229{
230 deb_info("%s:\n", __func__);
231 return dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap,
232 &ec168_mxl5003s_config) == NULL ? -ENODEV : 0;
233}
234
235static int ec168_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
236{
237 struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL};
238 deb_info("%s: onoff:%d\n", __func__, onoff);
239 if (onoff)
240 req.index = 0x0102;
241 return ec168_ctrl_msg(adap->dev, &req);
242}
243
244static int ec168_download_firmware(struct usb_device *udev,
245 const struct firmware *fw)
246{
247 int i, len, packets, remainder, ret;
248 u16 addr = 0x0000; /* firmware start address */
249 struct ec168_req req = {DOWNLOAD_FIRMWARE, 0, 0, 0, NULL};
250 deb_info("%s:\n", __func__);
251
252 #define FW_PACKET_MAX_DATA 2048
253 packets = fw->size / FW_PACKET_MAX_DATA;
254 remainder = fw->size % FW_PACKET_MAX_DATA;
255 len = FW_PACKET_MAX_DATA;
256 for (i = 0; i <= packets; i++) {
257 if (i == packets) /* set size of the last packet */
258 len = remainder;
259
260 req.size = len;
261 req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);
262 req.index = addr;
263 addr += FW_PACKET_MAX_DATA;
264
265 ret = ec168_rw_udev(udev, &req);
266 if (ret) {
267 err("firmware download failed:%d packet:%d", ret, i);
268 goto error;
269 }
270 }
271 req.size = 0;
272
273 /* set "warm"? */
274 req.cmd = SET_CONFIG;
275 req.value = 0;
276 req.index = 0x0001;
277 ret = ec168_rw_udev(udev, &req);
278 if (ret)
279 goto error;
280
281 /* really needed - no idea what does */
282 req.cmd = GPIO;
283 req.value = 0;
284 req.index = 0x0206;
285 ret = ec168_rw_udev(udev, &req);
286 if (ret)
287 goto error;
288
289 /* activate tuner I2C? */
290 req.cmd = WRITE_I2C;
291 req.value = 0;
292 req.index = 0x00c6;
293 ret = ec168_rw_udev(udev, &req);
294 if (ret)
295 goto error;
296
297 return ret;
298error:
299 deb_info("%s: failed:%d\n", __func__, ret);
300 return ret;
301}
302
303static int ec168_identify_state(struct usb_device *udev,
304 struct dvb_usb_device_properties *props,
305 struct dvb_usb_device_description **desc, int *cold)
306{
307 int ret;
308 u8 reply;
309 struct ec168_req req = {GET_CONFIG, 0, 1, sizeof(reply), &reply};
310 deb_info("%s:\n", __func__);
311
312 ret = ec168_rw_udev(udev, &req);
313 if (ret)
314 goto error;
315
316 deb_info("%s: reply:%02x\n", __func__, reply);
317
318 if (reply == 0x01)
319 *cold = 0;
320 else
321 *cold = 1;
322
323 return ret;
324error:
325 deb_info("%s: failed:%d\n", __func__, ret);
326 return ret;
327}
328
329/* DVB USB Driver stuff */
330static struct dvb_usb_device_properties ec168_properties;
331
332static int ec168_probe(struct usb_interface *intf,
333 const struct usb_device_id *id)
334{
335 int ret;
336 deb_info("%s: interface:%d\n", __func__,
337 intf->cur_altsetting->desc.bInterfaceNumber);
338
339 ret = dvb_usb_device_init(intf, &ec168_properties, THIS_MODULE, NULL,
340 adapter_nr);
341 if (ret)
342 goto error;
343
344 return ret;
345error:
346 deb_info("%s: failed:%d\n", __func__, ret);
347 return ret;
348}
349
350#define E3C_EC168_1689 0
351#define E3C_EC168_FFFA 1
352#define E3C_EC168_FFFB 2
353#define E3C_EC168_1001 3
354#define E3C_EC168_1002 4
355
356static struct usb_device_id ec168_id[] = {
357 [E3C_EC168_1689] =
358 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168)},
359 [E3C_EC168_FFFA] =
360 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_2)},
361 [E3C_EC168_FFFB] =
362 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_3)},
363 [E3C_EC168_1001] =
364 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_4)},
365 [E3C_EC168_1002] =
366 {USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_5)},
367 {} /* terminating entry */
368};
369
370MODULE_DEVICE_TABLE(usb, ec168_id);
371
372static struct dvb_usb_device_properties ec168_properties = {
373 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
374
375 .usb_ctrl = DEVICE_SPECIFIC,
376 .download_firmware = ec168_download_firmware,
377 .firmware = "dvb-usb-ec168.fw",
378 .no_reconnect = 1,
379
380 .size_of_priv = 0,
381
382 .num_adapters = 1,
383 .adapter = {
384 {
385 .streaming_ctrl = ec168_streaming_ctrl,
386 .frontend_attach = ec168_ec100_frontend_attach,
387 .tuner_attach = ec168_mxl5003s_tuner_attach,
388 .stream = {
389 .type = USB_BULK,
390 .count = 6,
391 .endpoint = 0x82,
392 .u = {
393 .bulk = {
394 .buffersize = (32*512),
395 }
396 }
397 },
398 }
399 },
400
401 .identify_state = ec168_identify_state,
402
403 .i2c_algo = &ec168_i2c_algo,
404
405 .num_device_descs = 1,
406 .devices = {
407 {
408 .name = "E3C EC168 DVB-T USB2.0 reference design",
409 .cold_ids = {
410 &ec168_id[E3C_EC168_1689],
411 &ec168_id[E3C_EC168_FFFA],
412 &ec168_id[E3C_EC168_FFFB],
413 &ec168_id[E3C_EC168_1001],
414 &ec168_id[E3C_EC168_1002],
415 NULL},
416 .warm_ids = {NULL},
417 },
418 }
419};
420
421static struct usb_driver ec168_driver = {
422 .name = "dvb_usb_ec168",
423 .probe = ec168_probe,
424 .disconnect = dvb_usb_device_exit,
425 .id_table = ec168_id,
426};
427
428/* module stuff */
429static int __init ec168_module_init(void)
430{
431 int ret;
432 deb_info("%s:\n", __func__);
433 ret = usb_register(&ec168_driver);
434 if (ret)
435 err("module init failed:%d", ret);
436
437 return ret;
438}
439
440static void __exit ec168_module_exit(void)
441{
442 deb_info("%s:\n", __func__);
443 /* deregister this driver from the USB subsystem */
444 usb_deregister(&ec168_driver);
445}
446
447module_init(ec168_module_init);
448module_exit(ec168_module_exit);
449
450MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
451MODULE_DESCRIPTION("E3C EC168 DVB-T USB2.0 driver");
452MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/ec168.h b/drivers/media/dvb/dvb-usb/ec168.h
new file mode 100644
index 00000000000..e7e0b831314
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ec168.h
@@ -0,0 +1,73 @@
1/*
2 * E3C EC168 DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#ifndef EC168_H
23#define EC168_H
24
25#define DVB_USB_LOG_PREFIX "ec168"
26#include "dvb-usb.h"
27
28#define deb_info(args...) dprintk(dvb_usb_ec168_debug, 0x01, args)
29#define deb_rc(args...) dprintk(dvb_usb_ec168_debug, 0x02, args)
30#define deb_xfer(args...) dprintk(dvb_usb_ec168_debug, 0x04, args)
31#define deb_reg(args...) dprintk(dvb_usb_ec168_debug, 0x08, args)
32#define deb_i2c(args...) dprintk(dvb_usb_ec168_debug, 0x10, args)
33#define deb_fw(args...) dprintk(dvb_usb_ec168_debug, 0x20, args)
34
35#define ec168_debug_dump(r, t, v, i, b, l, func) { \
36 int loop_; \
37 func("%02x %02x %02x %02x %02x %02x %02x %02x", \
38 t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \
39 if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
40 func(" >>> "); \
41 else \
42 func(" <<< "); \
43 for (loop_ = 0; loop_ < l; loop_++) \
44 func("%02x ", b[loop_]); \
45 func("\n");\
46}
47
48#define EC168_USB_TIMEOUT 1000
49
50struct ec168_req {
51 u8 cmd; /* [1] */
52 u16 value; /* [2|3] */
53 u16 index; /* [4|5] */
54 u16 size; /* [6|7] */
55 u8 *data;
56};
57
58enum ec168_cmd {
59 DOWNLOAD_FIRMWARE = 0x00,
60 CONFIG = 0x01,
61 DEMOD_RW = 0x03,
62 GPIO = 0x04,
63 STREAMING_CTRL = 0x10,
64 READ_I2C = 0x20,
65 WRITE_I2C = 0x21,
66 HID_DOWNLOAD = 0x30,
67 GET_CONFIG,
68 SET_CONFIG,
69 READ_DEMOD,
70 WRITE_DEMOD,
71};
72
73#endif
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c
new file mode 100644
index 00000000000..015b4e8af1a
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/friio-fe.c
@@ -0,0 +1,474 @@
1/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
2 *
3 * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
4 *
5 * This module is based off the the gl861 and vp702x modules.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation, version 2.
10 *
11 * see Documentation/dvb/README.dvb-usb for more information
12 */
13#include <linux/init.h>
14#include <linux/string.h>
15#include <linux/slab.h>
16
17#include "friio.h"
18
19struct jdvbt90502_state {
20 struct i2c_adapter *i2c;
21 struct dvb_frontend frontend;
22 struct jdvbt90502_config config;
23};
24
25/* NOTE: TC90502 has 16bit register-address? */
26/* register 0x0100 is used for reading PLL status, so reg is u16 here */
27static int jdvbt90502_reg_read(struct jdvbt90502_state *state,
28 const u16 reg, u8 *buf, const size_t count)
29{
30 int ret;
31 u8 wbuf[3];
32 struct i2c_msg msg[2];
33
34 wbuf[0] = reg & 0xFF;
35 wbuf[1] = 0;
36 wbuf[2] = reg >> 8;
37
38 msg[0].addr = state->config.demod_address;
39 msg[0].flags = 0;
40 msg[0].buf = wbuf;
41 msg[0].len = sizeof(wbuf);
42
43 msg[1].addr = msg[0].addr;
44 msg[1].flags = I2C_M_RD;
45 msg[1].buf = buf;
46 msg[1].len = count;
47
48 ret = i2c_transfer(state->i2c, msg, 2);
49 if (ret != 2) {
50 deb_fe(" reg read failed.\n");
51 return -EREMOTEIO;
52 }
53 return 0;
54}
55
56/* currently 16bit register-address is not used, so reg is u8 here */
57static int jdvbt90502_single_reg_write(struct jdvbt90502_state *state,
58 const u8 reg, const u8 val)
59{
60 struct i2c_msg msg;
61 u8 wbuf[2];
62
63 wbuf[0] = reg;
64 wbuf[1] = val;
65
66 msg.addr = state->config.demod_address;
67 msg.flags = 0;
68 msg.buf = wbuf;
69 msg.len = sizeof(wbuf);
70
71 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
72 deb_fe(" reg write failed.");
73 return -EREMOTEIO;
74 }
75 return 0;
76}
77
78static int _jdvbt90502_write(struct dvb_frontend *fe, const u8 buf[], int len)
79{
80 struct jdvbt90502_state *state = fe->demodulator_priv;
81 int err, i;
82 for (i = 0; i < len - 1; i++) {
83 err = jdvbt90502_single_reg_write(state,
84 buf[0] + i, buf[i + 1]);
85 if (err)
86 return err;
87 }
88
89 return 0;
90}
91
92/* read pll status byte via the demodulator's I2C register */
93/* note: Win box reads it by 8B block at the I2C addr 0x30 from reg:0x80 */
94static int jdvbt90502_pll_read(struct jdvbt90502_state *state, u8 *result)
95{
96 int ret;
97
98 /* +1 for reading */
99 u8 pll_addr_byte = (state->config.pll_address << 1) + 1;
100
101 *result = 0;
102
103 ret = jdvbt90502_single_reg_write(state, JDVBT90502_2ND_I2C_REG,
104 pll_addr_byte);
105 if (ret)
106 goto error;
107
108 ret = jdvbt90502_reg_read(state, 0x0100, result, 1);
109 if (ret)
110 goto error;
111
112 deb_fe("PLL read val:%02x\n", *result);
113 return 0;
114
115error:
116 deb_fe("%s:ret == %d\n", __func__, ret);
117 return -EREMOTEIO;
118}
119
120
121/* set pll frequency via the demodulator's I2C register */
122static int jdvbt90502_pll_set_freq(struct jdvbt90502_state *state, u32 freq)
123{
124 int ret;
125 int retry;
126 u8 res1;
127 u8 res2[9];
128
129 u8 pll_freq_cmd[PLL_CMD_LEN];
130 u8 pll_agc_cmd[PLL_CMD_LEN];
131 struct i2c_msg msg[2];
132 u32 f;
133
134 deb_fe("%s: freq=%d, step=%d\n", __func__, freq,
135 state->frontend.ops.info.frequency_stepsize);
136 /* freq -> oscilator frequency conversion. */
137 /* freq: 473,000,000 + n*6,000,000 [+ 142857 (center freq. shift)] */
138 f = freq / state->frontend.ops.info.frequency_stepsize;
139 /* add 399[1/7 MHZ] = 57MHz for the IF */
140 f += 399;
141 /* add center frequency shift if necessary */
142 if (f % 7 == 0)
143 f++;
144 pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */
145 pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1;
146 pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F;
147 pll_freq_cmd[DIVIDER_BYTE2] = f & 0xFF;
148 pll_freq_cmd[CONTROL_BYTE] = 0xB2; /* ref.divider:28, 4MHz/28=1/7MHz */
149 pll_freq_cmd[BANDSWITCH_BYTE] = 0x08; /* UHF band */
150
151 msg[0].addr = state->config.demod_address;
152 msg[0].flags = 0;
153 msg[0].buf = pll_freq_cmd;
154 msg[0].len = sizeof(pll_freq_cmd);
155
156 ret = i2c_transfer(state->i2c, &msg[0], 1);
157 if (ret != 1)
158 goto error;
159
160 udelay(50);
161
162 pll_agc_cmd[DEMOD_REDIRECT_REG] = pll_freq_cmd[DEMOD_REDIRECT_REG];
163 pll_agc_cmd[ADDRESS_BYTE] = pll_freq_cmd[ADDRESS_BYTE];
164 pll_agc_cmd[DIVIDER_BYTE1] = pll_freq_cmd[DIVIDER_BYTE1];
165 pll_agc_cmd[DIVIDER_BYTE2] = pll_freq_cmd[DIVIDER_BYTE2];
166 pll_agc_cmd[CONTROL_BYTE] = 0x9A; /* AGC_CTRL instead of BANDSWITCH */
167 pll_agc_cmd[AGC_CTRL_BYTE] = 0x50;
168 /* AGC Time Constant 2s, AGC take-over point:103dBuV(lowest) */
169
170 msg[1].addr = msg[0].addr;
171 msg[1].flags = 0;
172 msg[1].buf = pll_agc_cmd;
173 msg[1].len = sizeof(pll_agc_cmd);
174
175 ret = i2c_transfer(state->i2c, &msg[1], 1);
176 if (ret != 1)
177 goto error;
178
179 /* I don't know what these cmds are for, */
180 /* but the USB log on a windows box contains them */
181 ret = jdvbt90502_single_reg_write(state, 0x01, 0x40);
182 ret |= jdvbt90502_single_reg_write(state, 0x01, 0x00);
183 if (ret)
184 goto error;
185 udelay(100);
186
187 /* wait for the demod to be ready? */
188#define RETRY_COUNT 5
189 for (retry = 0; retry < RETRY_COUNT; retry++) {
190 ret = jdvbt90502_reg_read(state, 0x0096, &res1, 1);
191 if (ret)
192 goto error;
193 /* if (res1 != 0x00) goto error; */
194 ret = jdvbt90502_reg_read(state, 0x00B0, res2, sizeof(res2));
195 if (ret)
196 goto error;
197 if (res2[0] >= 0xA7)
198 break;
199 msleep(100);
200 }
201 if (retry >= RETRY_COUNT) {
202 deb_fe("%s: FE does not get ready after freq setting.\n",
203 __func__);
204 return -EREMOTEIO;
205 }
206
207 return 0;
208error:
209 deb_fe("%s:ret == %d\n", __func__, ret);
210 return -EREMOTEIO;
211}
212
213static int jdvbt90502_read_status(struct dvb_frontend *fe, fe_status_t *state)
214{
215 u8 result;
216 int ret;
217
218 *state = FE_HAS_SIGNAL;
219
220 ret = jdvbt90502_pll_read(fe->demodulator_priv, &result);
221 if (ret) {
222 deb_fe("%s:ret == %d\n", __func__, ret);
223 return -EREMOTEIO;
224 }
225
226 *state = FE_HAS_SIGNAL
227 | FE_HAS_CARRIER
228 | FE_HAS_VITERBI
229 | FE_HAS_SYNC;
230
231 if (result & PLL_STATUS_LOCKED)
232 *state |= FE_HAS_LOCK;
233
234 return 0;
235}
236
237static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe,
238 u16 *strength)
239{
240 int ret;
241 u8 rbuf[37];
242
243 *strength = 0;
244
245 /* status register (incl. signal strength) : 0x89 */
246 /* TODO: read just the necessary registers [0x8B..0x8D]? */
247 ret = jdvbt90502_reg_read(fe->demodulator_priv, 0x0089,
248 rbuf, sizeof(rbuf));
249
250 if (ret) {
251 deb_fe("%s:ret == %d\n", __func__, ret);
252 return -EREMOTEIO;
253 }
254
255 /* signal_strength: rbuf[2-4] (24bit BE), use lower 16bit for now. */
256 *strength = (rbuf[3] << 8) + rbuf[4];
257 if (rbuf[2])
258 *strength = 0xffff;
259
260 return 0;
261}
262
263
264/* filter out un-supported properties to notify users */
265static int jdvbt90502_set_property(struct dvb_frontend *fe,
266 struct dtv_property *tvp)
267{
268 int r = 0;
269
270 switch (tvp->cmd) {
271 case DTV_DELIVERY_SYSTEM:
272 if (tvp->u.data != SYS_ISDBT)
273 r = -EINVAL;
274 break;
275 case DTV_CLEAR:
276 case DTV_TUNE:
277 case DTV_FREQUENCY:
278 break;
279 default:
280 r = -EINVAL;
281 }
282 return r;
283}
284
285static int jdvbt90502_get_frontend(struct dvb_frontend *fe,
286 struct dvb_frontend_parameters *p)
287{
288 p->inversion = INVERSION_AUTO;
289 p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
290 p->u.ofdm.code_rate_HP = FEC_AUTO;
291 p->u.ofdm.code_rate_LP = FEC_AUTO;
292 p->u.ofdm.constellation = QAM_64;
293 p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
294 p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
295 p->u.ofdm.hierarchy_information = HIERARCHY_AUTO;
296 return 0;
297}
298
299static int jdvbt90502_set_frontend(struct dvb_frontend *fe,
300 struct dvb_frontend_parameters *p)
301{
302 /**
303 * NOTE: ignore all the parameters except frequency.
304 * others should be fixed to the proper value for ISDB-T,
305 * but don't check here.
306 */
307
308 struct jdvbt90502_state *state = fe->demodulator_priv;
309 int ret;
310
311 deb_fe("%s: Freq:%d\n", __func__, p->frequency);
312
313 /* for recovery from DTV_CLEAN */
314 fe->dtv_property_cache.delivery_system = SYS_ISDBT;
315
316 ret = jdvbt90502_pll_set_freq(state, p->frequency);
317 if (ret) {
318 deb_fe("%s:ret == %d\n", __func__, ret);
319 return -EREMOTEIO;
320 }
321
322 return 0;
323}
324
325
326/**
327 * (reg, val) commad list to initialize this module.
328 * captured on a Windows box.
329 */
330static u8 init_code[][2] = {
331 {0x01, 0x40},
332 {0x04, 0x38},
333 {0x05, 0x40},
334 {0x07, 0x40},
335 {0x0F, 0x4F},
336 {0x11, 0x21},
337 {0x12, 0x0B},
338 {0x13, 0x2F},
339 {0x14, 0x31},
340 {0x16, 0x02},
341 {0x21, 0xC4},
342 {0x22, 0x20},
343 {0x2C, 0x79},
344 {0x2D, 0x34},
345 {0x2F, 0x00},
346 {0x30, 0x28},
347 {0x31, 0x31},
348 {0x32, 0xDF},
349 {0x38, 0x01},
350 {0x39, 0x78},
351 {0x3B, 0x33},
352 {0x3C, 0x33},
353 {0x48, 0x90},
354 {0x51, 0x68},
355 {0x5E, 0x38},
356 {0x71, 0x00},
357 {0x72, 0x08},
358 {0x77, 0x00},
359 {0xC0, 0x21},
360 {0xC1, 0x10},
361 {0xE4, 0x1A},
362 {0xEA, 0x1F},
363 {0x77, 0x00},
364 {0x71, 0x00},
365 {0x71, 0x00},
366 {0x76, 0x0C},
367};
368
369static const int init_code_len = sizeof(init_code) / sizeof(u8[2]);
370
371static int jdvbt90502_init(struct dvb_frontend *fe)
372{
373 int i = -1;
374 int ret;
375 struct i2c_msg msg;
376
377 struct jdvbt90502_state *state = fe->demodulator_priv;
378
379 deb_fe("%s called.\n", __func__);
380
381 msg.addr = state->config.demod_address;
382 msg.flags = 0;
383 msg.len = 2;
384 for (i = 0; i < init_code_len; i++) {
385 msg.buf = init_code[i];
386 ret = i2c_transfer(state->i2c, &msg, 1);
387 if (ret != 1)
388 goto error;
389 }
390 fe->dtv_property_cache.delivery_system = SYS_ISDBT;
391 msleep(100);
392
393 return 0;
394
395error:
396 deb_fe("%s: init_code[%d] failed. ret==%d\n", __func__, i, ret);
397 return -EREMOTEIO;
398}
399
400
401static void jdvbt90502_release(struct dvb_frontend *fe)
402{
403 struct jdvbt90502_state *state = fe->demodulator_priv;
404 kfree(state);
405}
406
407
408static struct dvb_frontend_ops jdvbt90502_ops;
409
410struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d)
411{
412 struct jdvbt90502_state *state = NULL;
413
414 deb_info("%s called.\n", __func__);
415
416 /* allocate memory for the internal state */
417 state = kzalloc(sizeof(struct jdvbt90502_state), GFP_KERNEL);
418 if (state == NULL)
419 goto error;
420
421 /* setup the state */
422 state->i2c = &d->i2c_adap;
423 memcpy(&state->config, &friio_fe_config, sizeof(friio_fe_config));
424
425 /* create dvb_frontend */
426 memcpy(&state->frontend.ops, &jdvbt90502_ops,
427 sizeof(jdvbt90502_ops));
428 state->frontend.demodulator_priv = state;
429
430 if (jdvbt90502_init(&state->frontend) < 0)
431 goto error;
432
433 return &state->frontend;
434
435error:
436 kfree(state);
437 return NULL;
438}
439
440static struct dvb_frontend_ops jdvbt90502_ops = {
441
442 .info = {
443 .name = "Comtech JDVBT90502 ISDB-T",
444 .type = FE_OFDM,
445 .frequency_min = 473000000, /* UHF 13ch, center */
446 .frequency_max = 767142857, /* UHF 62ch, center */
447 .frequency_stepsize = JDVBT90502_PLL_CLK /
448 JDVBT90502_PLL_DIVIDER,
449 .frequency_tolerance = 0,
450
451 /* NOTE: this driver ignores all parameters but frequency. */
452 .caps = FE_CAN_INVERSION_AUTO |
453 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
454 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
455 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
456 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
457 FE_CAN_TRANSMISSION_MODE_AUTO |
458 FE_CAN_GUARD_INTERVAL_AUTO |
459 FE_CAN_HIERARCHY_AUTO,
460 },
461
462 .release = jdvbt90502_release,
463
464 .init = jdvbt90502_init,
465 .write = _jdvbt90502_write,
466
467 .set_property = jdvbt90502_set_property,
468
469 .set_frontend = jdvbt90502_set_frontend,
470 .get_frontend = jdvbt90502_get_frontend,
471
472 .read_status = jdvbt90502_read_status,
473 .read_signal_strength = jdvbt90502_read_signal_strength,
474};
diff --git a/drivers/media/dvb/dvb-usb/friio.c b/drivers/media/dvb/dvb-usb/friio.c
new file mode 100644
index 00000000000..76159aed9bb
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/friio.c
@@ -0,0 +1,540 @@
1/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
2 *
3 * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
4 *
5 * This module is based off the the gl861 and vp702x modules.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation, version 2.
10 *
11 * see Documentation/dvb/README.dvb-usb for more information
12 */
13#include "friio.h"
14
15/* debug */
16int dvb_usb_friio_debug;
17module_param_named(debug, dvb_usb_friio_debug, int, 0644);
18MODULE_PARM_DESC(debug,
19 "set debugging level (1=info,2=xfer,4=rc,8=fe (or-able))."
20 DVB_USB_DEBUG_STATUS);
21
22DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
23
24/**
25 * Indirect I2C access to the PLL via FE.
26 * whole I2C protocol data to the PLL is sent via the FE's I2C register.
27 * This is done by a control msg to the FE with the I2C data accompanied, and
28 * a specific USB request number is assigned for that purpose.
29 *
30 * this func sends wbuf[1..] to the I2C register wbuf[0] at addr (= at FE).
31 * TODO: refoctored, smarter i2c functions.
32 */
33static int gl861_i2c_ctrlmsg_data(struct dvb_usb_device *d, u8 addr,
34 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
35{
36 u16 index = wbuf[0]; /* must be JDVBT90502_2ND_I2C_REG(=0xFE) */
37 u16 value = addr << (8 + 1);
38 int wo = (rbuf == NULL || rlen == 0); /* write only */
39 u8 req, type;
40
41 deb_xfer("write to PLL:0x%02x via FE reg:0x%02x, len:%d\n",
42 wbuf[1], wbuf[0], wlen - 1);
43
44 if (wo && wlen >= 2) {
45 req = GL861_REQ_I2C_DATA_CTRL_WRITE;
46 type = GL861_WRITE;
47 udelay(20);
48 return usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
49 req, type, value, index,
50 &wbuf[1], wlen - 1, 2000);
51 }
52
53 deb_xfer("not supported ctrl-msg, aborting.");
54 return -EINVAL;
55}
56
57/* normal I2C access (without extra data arguments).
58 * write to the register wbuf[0] at I2C address addr with the value wbuf[1],
59 * or read from the register wbuf[0].
60 * register address can be 16bit (wbuf[2]<<8 | wbuf[0]) if wlen==3
61 */
62static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
63 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
64{
65 u16 index;
66 u16 value = addr << (8 + 1);
67 int wo = (rbuf == NULL || rlen == 0); /* write-only */
68 u8 req, type;
69 unsigned int pipe;
70
71 /* special case for the indirect I2C access to the PLL via FE, */
72 if (addr == friio_fe_config.demod_address &&
73 wbuf[0] == JDVBT90502_2ND_I2C_REG)
74 return gl861_i2c_ctrlmsg_data(d, addr, wbuf, wlen, rbuf, rlen);
75
76 if (wo) {
77 req = GL861_REQ_I2C_WRITE;
78 type = GL861_WRITE;
79 pipe = usb_sndctrlpipe(d->udev, 0);
80 } else { /* rw */
81 req = GL861_REQ_I2C_READ;
82 type = GL861_READ;
83 pipe = usb_rcvctrlpipe(d->udev, 0);
84 }
85
86 switch (wlen) {
87 case 1:
88 index = wbuf[0];
89 break;
90 case 2:
91 index = wbuf[0];
92 value = value + wbuf[1];
93 break;
94 case 3:
95 /* special case for 16bit register-address */
96 index = (wbuf[2] << 8) | wbuf[0];
97 value = value + wbuf[1];
98 break;
99 default:
100 deb_xfer("wlen = %x, aborting.", wlen);
101 return -EINVAL;
102 }
103 msleep(1);
104 return usb_control_msg(d->udev, pipe, req, type,
105 value, index, rbuf, rlen, 2000);
106}
107
108/* I2C */
109static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
110 int num)
111{
112 struct dvb_usb_device *d = i2c_get_adapdata(adap);
113 int i;
114
115
116 if (num > 2)
117 return -EINVAL;
118
119 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
120 return -EAGAIN;
121
122 for (i = 0; i < num; i++) {
123 /* write/read request */
124 if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
125 if (gl861_i2c_msg(d, msg[i].addr,
126 msg[i].buf, msg[i].len,
127 msg[i + 1].buf, msg[i + 1].len) < 0)
128 break;
129 i++;
130 } else
131 if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
132 msg[i].len, NULL, 0) < 0)
133 break;
134 }
135
136 mutex_unlock(&d->i2c_mutex);
137 return i;
138}
139
140static u32 gl861_i2c_func(struct i2c_adapter *adapter)
141{
142 return I2C_FUNC_I2C;
143}
144
145static int friio_ext_ctl(struct dvb_usb_adapter *adap,
146 u32 sat_color, int lnb_on)
147{
148 int i;
149 int ret;
150 struct i2c_msg msg;
151 u8 *buf;
152 u32 mask;
153 u8 lnb = (lnb_on) ? FRIIO_CTL_LNB : 0;
154
155 buf = kmalloc(2, GFP_KERNEL);
156 if (!buf)
157 return -ENOMEM;
158
159 msg.addr = 0x00;
160 msg.flags = 0;
161 msg.len = 2;
162 msg.buf = buf;
163
164 buf[0] = 0x00;
165
166 /* send 2bit header (&B10) */
167 buf[1] = lnb | FRIIO_CTL_LED | FRIIO_CTL_STROBE;
168 ret = gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
169 buf[1] |= FRIIO_CTL_CLK;
170 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
171
172 buf[1] = lnb | FRIIO_CTL_STROBE;
173 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
174 buf[1] |= FRIIO_CTL_CLK;
175 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
176
177 /* send 32bit(satur, R, G, B) data in serial */
178 mask = 1 << 31;
179 for (i = 0; i < 32; i++) {
180 buf[1] = lnb | FRIIO_CTL_STROBE;
181 if (sat_color & mask)
182 buf[1] |= FRIIO_CTL_LED;
183 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
184 buf[1] |= FRIIO_CTL_CLK;
185 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
186 mask >>= 1;
187 }
188
189 /* set the strobe off */
190 buf[1] = lnb;
191 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
192 buf[1] |= FRIIO_CTL_CLK;
193 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
194
195 kfree(buf);
196 return (ret == 70);
197}
198
199
200static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
201
202/* TODO: move these init cmds to the FE's init routine? */
203static u8 streaming_init_cmds[][2] = {
204 {0x33, 0x08},
205 {0x37, 0x40},
206 {0x3A, 0x1F},
207 {0x3B, 0xFF},
208 {0x3C, 0x1F},
209 {0x3D, 0xFF},
210 {0x38, 0x00},
211 {0x35, 0x00},
212 {0x39, 0x00},
213 {0x36, 0x00},
214};
215static int cmdlen = sizeof(streaming_init_cmds) / 2;
216
217/*
218 * Command sequence in this init function is a replay
219 * of the captured USB commands from the Windows proprietary driver.
220 */
221static int friio_initialize(struct dvb_usb_device *d)
222{
223 int ret;
224 int i;
225 int retry = 0;
226 u8 *rbuf, *wbuf;
227
228 deb_info("%s called.\n", __func__);
229
230 wbuf = kmalloc(3, GFP_KERNEL);
231 if (!wbuf)
232 return -ENOMEM;
233
234 rbuf = kmalloc(2, GFP_KERNEL);
235 if (!rbuf) {
236 kfree(wbuf);
237 return -ENOMEM;
238 }
239
240 /* use gl861_i2c_msg instead of gl861_i2c_xfer(), */
241 /* because the i2c device is not set up yet. */
242 wbuf[0] = 0x11;
243 wbuf[1] = 0x02;
244 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
245 if (ret < 0)
246 goto error;
247 msleep(2);
248
249 wbuf[0] = 0x11;
250 wbuf[1] = 0x00;
251 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
252 if (ret < 0)
253 goto error;
254 msleep(1);
255
256 /* following msgs should be in the FE's init code? */
257 /* cmd sequence to identify the device type? (friio black/white) */
258 wbuf[0] = 0x03;
259 wbuf[1] = 0x80;
260 /* can't use gl861_i2c_cmd, as the register-addr is 16bit(0x0100) */
261 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
262 GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
263 0x1200, 0x0100, wbuf, 2, 2000);
264 if (ret < 0)
265 goto error;
266
267 msleep(2);
268 wbuf[0] = 0x00;
269 wbuf[2] = 0x01; /* reg.0x0100 */
270 wbuf[1] = 0x00;
271 ret = gl861_i2c_msg(d, 0x12 >> 1, wbuf, 3, rbuf, 2);
272 /* my Friio White returns 0xffff. */
273 if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
274 goto error;
275
276 msleep(2);
277 wbuf[0] = 0x03;
278 wbuf[1] = 0x80;
279 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
280 GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
281 0x9000, 0x0100, wbuf, 2, 2000);
282 if (ret < 0)
283 goto error;
284
285 msleep(2);
286 wbuf[0] = 0x00;
287 wbuf[2] = 0x01; /* reg.0x0100 */
288 wbuf[1] = 0x00;
289 ret = gl861_i2c_msg(d, 0x90 >> 1, wbuf, 3, rbuf, 2);
290 /* my Friio White returns 0xffff again. */
291 if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
292 goto error;
293
294 msleep(1);
295
296restart:
297 /* ============ start DEMOD init cmds ================== */
298 /* read PLL status to clear the POR bit */
299 wbuf[0] = JDVBT90502_2ND_I2C_REG;
300 wbuf[1] = (FRIIO_PLL_ADDR << 1) + 1; /* +1 for reading */
301 ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, NULL, 0);
302 if (ret < 0)
303 goto error;
304
305 msleep(5);
306 /* note: DEMODULATOR has 16bit register-address. */
307 wbuf[0] = 0x00;
308 wbuf[2] = 0x01; /* reg addr: 0x0100 */
309 wbuf[1] = 0x00; /* val: not used */
310 ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 3, rbuf, 1);
311 if (ret < 0)
312 goto error;
313/*
314 msleep(1);
315 wbuf[0] = 0x80;
316 wbuf[1] = 0x00;
317 ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, rbuf, 1);
318 if (ret < 0)
319 goto error;
320 */
321 if (rbuf[0] & 0x80) { /* still in PowerOnReset state? */
322 if (++retry > 3) {
323 deb_info("failed to get the correct"
324 " FE demod status:0x%02x\n", rbuf[0]);
325 goto error;
326 }
327 msleep(100);
328 goto restart;
329 }
330
331 /* TODO: check return value in rbuf */
332 /* =========== end DEMOD init cmds ===================== */
333 msleep(1);
334
335 wbuf[0] = 0x30;
336 wbuf[1] = 0x04;
337 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
338 if (ret < 0)
339 goto error;
340
341 msleep(2);
342 /* following 2 cmds unnecessary? */
343 wbuf[0] = 0x00;
344 wbuf[1] = 0x01;
345 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
346 if (ret < 0)
347 goto error;
348
349 wbuf[0] = 0x06;
350 wbuf[1] = 0x0F;
351 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
352 if (ret < 0)
353 goto error;
354
355 /* some streaming ctl cmds (maybe) */
356 msleep(10);
357 for (i = 0; i < cmdlen; i++) {
358 ret = gl861_i2c_msg(d, 0x00, streaming_init_cmds[i], 2,
359 NULL, 0);
360 if (ret < 0)
361 goto error;
362 msleep(1);
363 }
364 msleep(20);
365
366 /* change the LED color etc. */
367 ret = friio_streaming_ctrl(&d->adapter[0], 0);
368 if (ret < 0)
369 goto error;
370
371 return 0;
372
373error:
374 kfree(wbuf);
375 kfree(rbuf);
376 deb_info("%s:ret == %d\n", __func__, ret);
377 return -EIO;
378}
379
380/* Callbacks for DVB USB */
381
382static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
383{
384 int ret;
385
386 deb_info("%s called.(%d)\n", __func__, onoff);
387
388 /* set the LED color and saturation (and LNB on) */
389 if (onoff)
390 ret = friio_ext_ctl(adap, 0x6400ff64, 1);
391 else
392 ret = friio_ext_ctl(adap, 0x96ff00ff, 1);
393
394 if (ret != 1) {
395 deb_info("%s failed to send cmdx. ret==%d\n", __func__, ret);
396 return -EREMOTEIO;
397 }
398 return 0;
399}
400
401static int friio_frontend_attach(struct dvb_usb_adapter *adap)
402{
403 if (friio_initialize(adap->dev) < 0)
404 return -EIO;
405
406 adap->fe = jdvbt90502_attach(adap->dev);
407 if (adap->fe == NULL)
408 return -EIO;
409
410 return 0;
411}
412
413/* DVB USB Driver stuff */
414static struct dvb_usb_device_properties friio_properties;
415
416static int friio_probe(struct usb_interface *intf,
417 const struct usb_device_id *id)
418{
419 struct dvb_usb_device *d;
420 struct usb_host_interface *alt;
421 int ret;
422
423 if (intf->num_altsetting < GL861_ALTSETTING_COUNT)
424 return -ENODEV;
425
426 alt = usb_altnum_to_altsetting(intf, FRIIO_BULK_ALTSETTING);
427 if (alt == NULL) {
428 deb_rc("not alt found!\n");
429 return -ENODEV;
430 }
431 ret = usb_set_interface(interface_to_usbdev(intf),
432 alt->desc.bInterfaceNumber,
433 alt->desc.bAlternateSetting);
434 if (ret != 0) {
435 deb_rc("failed to set alt-setting!\n");
436 return ret;
437 }
438
439 ret = dvb_usb_device_init(intf, &friio_properties,
440 THIS_MODULE, &d, adapter_nr);
441 if (ret == 0)
442 friio_streaming_ctrl(&d->adapter[0], 1);
443
444 return ret;
445}
446
447
448struct jdvbt90502_config friio_fe_config = {
449 .demod_address = FRIIO_DEMOD_ADDR,
450 .pll_address = FRIIO_PLL_ADDR,
451};
452
453static struct i2c_algorithm gl861_i2c_algo = {
454 .master_xfer = gl861_i2c_xfer,
455 .functionality = gl861_i2c_func,
456};
457
458static struct usb_device_id friio_table[] = {
459 { USB_DEVICE(USB_VID_774, USB_PID_FRIIO_WHITE) },
460 { } /* Terminating entry */
461};
462MODULE_DEVICE_TABLE(usb, friio_table);
463
464
465static struct dvb_usb_device_properties friio_properties = {
466 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
467 .usb_ctrl = DEVICE_SPECIFIC,
468
469 .size_of_priv = 0,
470
471 .num_adapters = 1,
472 .adapter = {
473 /* caps:0 => no pid filter, 188B TS packet */
474 /* GL861 has a HW pid filter, but no info available. */
475 {
476 .caps = 0,
477
478 .frontend_attach = friio_frontend_attach,
479 .streaming_ctrl = friio_streaming_ctrl,
480
481 .stream = {
482 .type = USB_BULK,
483 /* count <= MAX_NO_URBS_FOR_DATA_STREAM(10) */
484 .count = 8,
485 .endpoint = 0x01,
486 .u = {
487 /* GL861 has 6KB buf inside */
488 .bulk = {
489 .buffersize = 16384,
490 }
491 }
492 },
493 }
494 },
495 .i2c_algo = &gl861_i2c_algo,
496
497 .num_device_descs = 1,
498 .devices = {
499 {
500 .name = "774 Friio ISDB-T USB2.0",
501 .cold_ids = { NULL },
502 .warm_ids = { &friio_table[0], NULL },
503 },
504 }
505};
506
507static struct usb_driver friio_driver = {
508 .name = "dvb_usb_friio",
509 .probe = friio_probe,
510 .disconnect = dvb_usb_device_exit,
511 .id_table = friio_table,
512};
513
514
515/* module stuff */
516static int __init friio_module_init(void)
517{
518 int ret;
519
520 ret = usb_register(&friio_driver);
521 if (ret)
522 err("usb_register failed. Error number %d", ret);
523
524 return ret;
525}
526
527
528static void __exit friio_module_exit(void)
529{
530 /* deregister this driver from the USB subsystem */
531 usb_deregister(&friio_driver);
532}
533
534module_init(friio_module_init);
535module_exit(friio_module_exit);
536
537MODULE_AUTHOR("Akihiro Tsukada <tskd2@yahoo.co.jp>");
538MODULE_DESCRIPTION("Driver for Friio ISDB-T USB2.0 Receiver");
539MODULE_VERSION("0.2");
540MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/friio.h b/drivers/media/dvb/dvb-usb/friio.h
new file mode 100644
index 00000000000..0f461ca10cb
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/friio.h
@@ -0,0 +1,99 @@
1/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
2 *
3 * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
4 *
5 * This module is based off the the gl861 and vp702x modules.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation, version 2.
10 *
11 * see Documentation/dvb/README.dvb-usb for more information
12 */
13#ifndef _DVB_USB_FRIIO_H_
14#define _DVB_USB_FRIIO_H_
15
16/**
17 * Friio Components
18 * USB hub: AU4254
19 * USB controller(+ TS dmx & streaming): GL861
20 * Frontend: comtech JDVBT-90502
21 * (tuner PLL: tua6034, I2C addr:(0xC0 >> 1))
22 * (OFDM demodulator: TC90502, I2C addr:(0x30 >> 1))
23 * LED x3 (+LNB) control: PIC 16F676
24 * EEPROM: 24C08
25 *
26 * (USB smart card reader: AU9522)
27 *
28 */
29
30#define DVB_USB_LOG_PREFIX "friio"
31#include "dvb-usb.h"
32
33extern int dvb_usb_friio_debug;
34#define deb_info(args...) dprintk(dvb_usb_friio_debug, 0x01, args)
35#define deb_xfer(args...) dprintk(dvb_usb_friio_debug, 0x02, args)
36#define deb_rc(args...) dprintk(dvb_usb_friio_debug, 0x04, args)
37#define deb_fe(args...) dprintk(dvb_usb_friio_debug, 0x08, args)
38
39/* Vendor requests */
40#define GL861_WRITE 0x40
41#define GL861_READ 0xc0
42
43/* command bytes */
44#define GL861_REQ_I2C_WRITE 0x01
45#define GL861_REQ_I2C_READ 0x02
46/* For control msg with data argument */
47/* Used for accessing the PLL on the secondary I2C bus of FE via GL861 */
48#define GL861_REQ_I2C_DATA_CTRL_WRITE 0x03
49
50#define GL861_ALTSETTING_COUNT 2
51#define FRIIO_BULK_ALTSETTING 0
52#define FRIIO_ISOC_ALTSETTING 1
53
54/* LED & LNB control via PIC. */
55/* basically, it's serial control with clock and strobe. */
56/* write the below 4bit control data to the reg 0x00 at the I2C addr 0x00 */
57/* when controlling the LEDs, 32bit(saturation, R, G, B) is sent on the bit3*/
58#define FRIIO_CTL_LNB (1 << 0)
59#define FRIIO_CTL_STROBE (1 << 1)
60#define FRIIO_CTL_CLK (1 << 2)
61#define FRIIO_CTL_LED (1 << 3)
62
63/* Front End related */
64
65#define FRIIO_DEMOD_ADDR (0x30 >> 1)
66#define FRIIO_PLL_ADDR (0xC0 >> 1)
67
68#define JDVBT90502_PLL_CLK 4000000
69#define JDVBT90502_PLL_DIVIDER 28
70
71#define JDVBT90502_2ND_I2C_REG 0xFE
72
73/* byte index for pll i2c command data structure*/
74/* see datasheet for tua6034 */
75#define DEMOD_REDIRECT_REG 0
76#define ADDRESS_BYTE 1
77#define DIVIDER_BYTE1 2
78#define DIVIDER_BYTE2 3
79#define CONTROL_BYTE 4
80#define BANDSWITCH_BYTE 5
81#define AGC_CTRL_BYTE 5
82#define PLL_CMD_LEN 6
83
84/* bit masks for PLL STATUS response */
85#define PLL_STATUS_POR_MODE 0x80 /* 1: Power on Reset (test) Mode */
86#define PLL_STATUS_LOCKED 0x40 /* 1: locked */
87#define PLL_STATUS_AGC_ACTIVE 0x08 /* 1:active */
88#define PLL_STATUS_TESTMODE 0x07 /* digital output level (5 level) */
89 /* 0.15Vcc step 0x00: < 0.15Vcc, ..., 0x04: >= 0.6Vcc (<= 1Vcc) */
90
91
92struct jdvbt90502_config {
93 u8 demod_address; /* i2c addr for demodulator IC */
94 u8 pll_address; /* PLL addr on the secondary i2c*/
95};
96extern struct jdvbt90502_config friio_fe_config;
97
98extern struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d);
99#endif
diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/dvb/dvb-usb/gl861.c
new file mode 100644
index 00000000000..6f596ed4176
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/gl861.c
@@ -0,0 +1,233 @@
1/* DVB USB compliant linux driver for GL861 USB2.0 devices.
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the
5 * Free Software Foundation, version 2.
6 *
7 * see Documentation/dvb/README.dvb-usb for more information
8 */
9#include "gl861.h"
10
11#include "zl10353.h"
12#include "qt1010.h"
13
14/* debug */
15static int dvb_usb_gl861_debug;
16module_param_named(debug, dvb_usb_gl861_debug, int, 0644);
17MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))."
18 DVB_USB_DEBUG_STATUS);
19DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
20
21static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
22 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
23{
24 u16 index;
25 u16 value = addr << (8 + 1);
26 int wo = (rbuf == NULL || rlen == 0); /* write-only */
27 u8 req, type;
28
29 if (wo) {
30 req = GL861_REQ_I2C_WRITE;
31 type = GL861_WRITE;
32 } else { /* rw */
33 req = GL861_REQ_I2C_READ;
34 type = GL861_READ;
35 }
36
37 switch (wlen) {
38 case 1:
39 index = wbuf[0];
40 break;
41 case 2:
42 index = wbuf[0];
43 value = value + wbuf[1];
44 break;
45 default:
46 warn("wlen = %x, aborting.", wlen);
47 return -EINVAL;
48 }
49
50 msleep(1); /* avoid I2C errors */
51
52 return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
53 value, index, rbuf, rlen, 2000);
54}
55
56/* I2C */
57static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
58 int num)
59{
60 struct dvb_usb_device *d = i2c_get_adapdata(adap);
61 int i;
62
63 if (num > 2)
64 return -EINVAL;
65
66 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
67 return -EAGAIN;
68
69 for (i = 0; i < num; i++) {
70 /* write/read request */
71 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
72 if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
73 msg[i].len, msg[i+1].buf, msg[i+1].len) < 0)
74 break;
75 i++;
76 } else
77 if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
78 msg[i].len, NULL, 0) < 0)
79 break;
80 }
81
82 mutex_unlock(&d->i2c_mutex);
83 return i;
84}
85
86static u32 gl861_i2c_func(struct i2c_adapter *adapter)
87{
88 return I2C_FUNC_I2C;
89}
90
91static struct i2c_algorithm gl861_i2c_algo = {
92 .master_xfer = gl861_i2c_xfer,
93 .functionality = gl861_i2c_func,
94};
95
96/* Callbacks for DVB USB */
97static struct zl10353_config gl861_zl10353_config = {
98 .demod_address = 0x0f,
99 .no_tuner = 1,
100 .parallel_ts = 1,
101};
102
103static int gl861_frontend_attach(struct dvb_usb_adapter *adap)
104{
105
106 adap->fe = dvb_attach(zl10353_attach, &gl861_zl10353_config,
107 &adap->dev->i2c_adap);
108 if (adap->fe == NULL)
109 return -EIO;
110
111 return 0;
112}
113
114static struct qt1010_config gl861_qt1010_config = {
115 .i2c_address = 0x62
116};
117
118static int gl861_tuner_attach(struct dvb_usb_adapter *adap)
119{
120 return dvb_attach(qt1010_attach,
121 adap->fe, &adap->dev->i2c_adap,
122 &gl861_qt1010_config) == NULL ? -ENODEV : 0;
123}
124
125/* DVB USB Driver stuff */
126static struct dvb_usb_device_properties gl861_properties;
127
128static int gl861_probe(struct usb_interface *intf,
129 const struct usb_device_id *id)
130{
131 struct dvb_usb_device *d;
132 struct usb_host_interface *alt;
133 int ret;
134
135 if (intf->num_altsetting < 2)
136 return -ENODEV;
137
138 ret = dvb_usb_device_init(intf, &gl861_properties, THIS_MODULE, &d,
139 adapter_nr);
140 if (ret == 0) {
141 alt = usb_altnum_to_altsetting(intf, 0);
142
143 if (alt == NULL) {
144 deb_rc("not alt found!\n");
145 return -ENODEV;
146 }
147
148 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
149 alt->desc.bAlternateSetting);
150 }
151
152 return ret;
153}
154
155static struct usb_device_id gl861_table [] = {
156 { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801) },
157 { USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU) },
158 { } /* Terminating entry */
159};
160MODULE_DEVICE_TABLE(usb, gl861_table);
161
162static struct dvb_usb_device_properties gl861_properties = {
163 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
164 .usb_ctrl = DEVICE_SPECIFIC,
165
166 .size_of_priv = 0,
167
168 .num_adapters = 1,
169 .adapter = {{
170
171 .frontend_attach = gl861_frontend_attach,
172 .tuner_attach = gl861_tuner_attach,
173
174 .stream = {
175 .type = USB_BULK,
176 .count = 7,
177 .endpoint = 0x81,
178 .u = {
179 .bulk = {
180 .buffersize = 512,
181 }
182 }
183 },
184 } },
185 .i2c_algo = &gl861_i2c_algo,
186
187 .num_device_descs = 2,
188 .devices = {
189 {
190 .name = "MSI Mega Sky 55801 DVB-T USB2.0",
191 .cold_ids = { NULL },
192 .warm_ids = { &gl861_table[0], NULL },
193 },
194 {
195 .name = "A-LINK DTU DVB-T USB2.0",
196 .cold_ids = { NULL },
197 .warm_ids = { &gl861_table[1], NULL },
198 },
199 }
200};
201
202static struct usb_driver gl861_driver = {
203 .name = "dvb_usb_gl861",
204 .probe = gl861_probe,
205 .disconnect = dvb_usb_device_exit,
206 .id_table = gl861_table,
207};
208
209/* module stuff */
210static int __init gl861_module_init(void)
211{
212 int ret;
213
214 ret = usb_register(&gl861_driver);
215 if (ret)
216 err("usb_register failed. Error number %d", ret);
217
218 return ret;
219}
220
221static void __exit gl861_module_exit(void)
222{
223 /* deregister this driver from the USB subsystem */
224 usb_deregister(&gl861_driver);
225}
226
227module_init(gl861_module_init);
228module_exit(gl861_module_exit);
229
230MODULE_AUTHOR("Carl Lundqvist <comabug@gmail.com>");
231MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861");
232MODULE_VERSION("0.1");
233MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/gl861.h b/drivers/media/dvb/dvb-usb/gl861.h
new file mode 100644
index 00000000000..c54855e2c23
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/gl861.h
@@ -0,0 +1,15 @@
1#ifndef _DVB_USB_GL861_H_
2#define _DVB_USB_GL861_H_
3
4#define DVB_USB_LOG_PREFIX "gl861"
5#include "dvb-usb.h"
6
7#define deb_rc(args...) dprintk(dvb_usb_gl861_debug, 0x01, args)
8
9#define GL861_WRITE 0x40
10#define GL861_READ 0xc0
11
12#define GL861_REQ_I2C_WRITE 0x01
13#define GL861_REQ_I2C_READ 0x02
14
15#endif
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
new file mode 100644
index 00000000000..60d11e57e7d
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
@@ -0,0 +1,378 @@
1/* DVB USB compliant Linux driver for the
2 * - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
3 *
4 * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
5 * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com)
6 *
7 * Thanks to GENPIX for the sample code used to implement this module.
8 *
9 * This module is based off the vp7045 and vp702x modules
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation, version 2.
14 *
15 * see Documentation/dvb/README.dvb-usb for more information
16 */
17#include "gp8psk.h"
18
19struct gp8psk_fe_state {
20 struct dvb_frontend fe;
21 struct dvb_usb_device *d;
22 u8 lock;
23 u16 snr;
24 unsigned long next_status_check;
25 unsigned long status_check_interval;
26};
27
28static int gp8psk_tuned_to_DCII(struct dvb_frontend *fe)
29{
30 struct gp8psk_fe_state *st = fe->demodulator_priv;
31 u8 status;
32 gp8psk_usb_in_op(st->d, GET_8PSK_CONFIG, 0, 0, &status, 1);
33 return status & bmDCtuned;
34}
35
36static int gp8psk_set_tuner_mode(struct dvb_frontend *fe, int mode)
37{
38 struct gp8psk_fe_state *state = fe->demodulator_priv;
39 return gp8psk_usb_out_op(state->d, SET_8PSK_CONFIG, mode, 0, NULL, 0);
40}
41
42static int gp8psk_fe_update_status(struct gp8psk_fe_state *st)
43{
44 u8 buf[6];
45 if (time_after(jiffies,st->next_status_check)) {
46 gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0,0,&st->lock,1);
47 gp8psk_usb_in_op(st->d, GET_SIGNAL_STRENGTH, 0,0,buf,6);
48 st->snr = (buf[1]) << 8 | buf[0];
49 st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
50 }
51 return 0;
52}
53
54static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
55{
56 struct gp8psk_fe_state *st = fe->demodulator_priv;
57 gp8psk_fe_update_status(st);
58
59 if (st->lock)
60 *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
61 else
62 *status = 0;
63
64 if (*status & FE_HAS_LOCK)
65 st->status_check_interval = 1000;
66 else
67 st->status_check_interval = 100;
68 return 0;
69}
70
71/* not supported by this Frontend */
72static int gp8psk_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
73{
74 (void) fe;
75 *ber = 0;
76 return 0;
77}
78
79/* not supported by this Frontend */
80static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
81{
82 (void) fe;
83 *unc = 0;
84 return 0;
85}
86
87static int gp8psk_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
88{
89 struct gp8psk_fe_state *st = fe->demodulator_priv;
90 gp8psk_fe_update_status(st);
91 /* snr is reported in dBu*256 */
92 *snr = st->snr;
93 return 0;
94}
95
96static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
97{
98 struct gp8psk_fe_state *st = fe->demodulator_priv;
99 gp8psk_fe_update_status(st);
100 /* snr is reported in dBu*256 */
101 /* snr / 38.4 ~= 100% strength */
102 /* snr * 17 returns 100% strength as 65535 */
103 if (st->snr > 0xf00)
104 *strength = 0xffff;
105 else
106 *strength = (st->snr << 4) + st->snr; /* snr*17 */
107 return 0;
108}
109
110static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
111{
112 tune->min_delay_ms = 800;
113 return 0;
114}
115
116static int gp8psk_fe_set_property(struct dvb_frontend *fe,
117 struct dtv_property *tvp)
118{
119 deb_fe("%s(..)\n", __func__);
120 return 0;
121}
122
123static int gp8psk_fe_get_property(struct dvb_frontend *fe,
124 struct dtv_property *tvp)
125{
126 deb_fe("%s(..)\n", __func__);
127 return 0;
128}
129
130
131static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
132 struct dvb_frontend_parameters *fep)
133{
134 struct gp8psk_fe_state *state = fe->demodulator_priv;
135 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
136 u8 cmd[10];
137 u32 freq = fep->frequency * 1000;
138 int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct);
139
140 deb_fe("%s()\n", __func__);
141
142 cmd[4] = freq & 0xff;
143 cmd[5] = (freq >> 8) & 0xff;
144 cmd[6] = (freq >> 16) & 0xff;
145 cmd[7] = (freq >> 24) & 0xff;
146
147 switch (c->delivery_system) {
148 case SYS_DVBS:
149 /* Allow QPSK and 8PSK (even for DVB-S) */
150 if (c->modulation != QPSK && c->modulation != PSK_8) {
151 deb_fe("%s: unsupported modulation selected (%d)\n",
152 __func__, c->modulation);
153 return -EOPNOTSUPP;
154 }
155 c->fec_inner = FEC_AUTO;
156 break;
157 case SYS_DVBS2:
158 deb_fe("%s: DVB-S2 delivery system selected\n", __func__);
159 break;
160
161 default:
162 deb_fe("%s: unsupported delivery system selected (%d)\n",
163 __func__, c->delivery_system);
164 return -EOPNOTSUPP;
165 }
166
167 cmd[0] = c->symbol_rate & 0xff;
168 cmd[1] = (c->symbol_rate >> 8) & 0xff;
169 cmd[2] = (c->symbol_rate >> 16) & 0xff;
170 cmd[3] = (c->symbol_rate >> 24) & 0xff;
171 switch (c->modulation) {
172 case QPSK:
173 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
174 if (gp8psk_tuned_to_DCII(fe))
175 gp8psk_bcm4500_reload(state->d);
176 switch (c->fec_inner) {
177 case FEC_1_2:
178 cmd[9] = 0; break;
179 case FEC_2_3:
180 cmd[9] = 1; break;
181 case FEC_3_4:
182 cmd[9] = 2; break;
183 case FEC_5_6:
184 cmd[9] = 3; break;
185 case FEC_7_8:
186 cmd[9] = 4; break;
187 case FEC_AUTO:
188 cmd[9] = 5; break;
189 default:
190 cmd[9] = 5; break;
191 }
192 cmd[8] = ADV_MOD_DVB_QPSK;
193 break;
194 case PSK_8: /* PSK_8 is for compatibility with DN */
195 cmd[8] = ADV_MOD_TURBO_8PSK;
196 switch (c->fec_inner) {
197 case FEC_2_3:
198 cmd[9] = 0; break;
199 case FEC_3_4:
200 cmd[9] = 1; break;
201 case FEC_3_5:
202 cmd[9] = 2; break;
203 case FEC_5_6:
204 cmd[9] = 3; break;
205 case FEC_8_9:
206 cmd[9] = 4; break;
207 default:
208 cmd[9] = 0; break;
209 }
210 break;
211 case QAM_16: /* QAM_16 is for compatibility with DN */
212 cmd[8] = ADV_MOD_TURBO_16QAM;
213 cmd[9] = 0;
214 break;
215 default: /* Unknown modulation */
216 deb_fe("%s: unsupported modulation selected (%d)\n",
217 __func__, c->modulation);
218 return -EOPNOTSUPP;
219 }
220
221 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
222 gp8psk_set_tuner_mode(fe, 0);
223 gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10);
224
225 state->lock = 0;
226 state->next_status_check = jiffies;
227 state->status_check_interval = 200;
228
229 return 0;
230}
231
232static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
233 struct dvb_diseqc_master_cmd *m)
234{
235 struct gp8psk_fe_state *st = fe->demodulator_priv;
236
237 deb_fe("%s\n",__func__);
238
239 if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0,
240 m->msg, m->msg_len)) {
241 return -EINVAL;
242 }
243 return 0;
244}
245
246static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe,
247 fe_sec_mini_cmd_t burst)
248{
249 struct gp8psk_fe_state *st = fe->demodulator_priv;
250 u8 cmd;
251
252 deb_fe("%s\n",__func__);
253
254 /* These commands are certainly wrong */
255 cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01;
256
257 if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0,
258 &cmd, 0)) {
259 return -EINVAL;
260 }
261 return 0;
262}
263
264static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
265{
266 struct gp8psk_fe_state* state = fe->demodulator_priv;
267
268 if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE,
269 (tone == SEC_TONE_ON), 0, NULL, 0)) {
270 return -EINVAL;
271 }
272 return 0;
273}
274
275static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
276{
277 struct gp8psk_fe_state* state = fe->demodulator_priv;
278
279 if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE,
280 voltage == SEC_VOLTAGE_18, 0, NULL, 0)) {
281 return -EINVAL;
282 }
283 return 0;
284}
285
286static int gp8psk_fe_enable_high_lnb_voltage(struct dvb_frontend* fe, long onoff)
287{
288 struct gp8psk_fe_state* state = fe->demodulator_priv;
289 return gp8psk_usb_out_op(state->d, USE_EXTRA_VOLT, onoff, 0,NULL,0);
290}
291
292static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
293{
294 struct gp8psk_fe_state* state = fe->demodulator_priv;
295 u8 cmd = sw_cmd & 0x7f;
296
297 if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0,
298 NULL, 0)) {
299 return -EINVAL;
300 }
301 if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
302 0, NULL, 0)) {
303 return -EINVAL;
304 }
305
306 return 0;
307}
308
309static void gp8psk_fe_release(struct dvb_frontend* fe)
310{
311 struct gp8psk_fe_state *state = fe->demodulator_priv;
312 kfree(state);
313}
314
315static struct dvb_frontend_ops gp8psk_fe_ops;
316
317struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
318{
319 struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
320 if (s == NULL)
321 goto error;
322
323 s->d = d;
324 memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
325 s->fe.demodulator_priv = s;
326
327 goto success;
328error:
329 return NULL;
330success:
331 return &s->fe;
332}
333
334
335static struct dvb_frontend_ops gp8psk_fe_ops = {
336 .info = {
337 .name = "Genpix DVB-S",
338 .type = FE_QPSK,
339 .frequency_min = 800000,
340 .frequency_max = 2250000,
341 .frequency_stepsize = 100,
342 .symbol_rate_min = 1000000,
343 .symbol_rate_max = 45000000,
344 .symbol_rate_tolerance = 500, /* ppm */
345 .caps = FE_CAN_INVERSION_AUTO |
346 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
347 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
348 /*
349 * FE_CAN_QAM_16 is for compatibility
350 * (Myth incorrectly detects Turbo-QPSK as plain QAM-16)
351 */
352 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_TURBO_FEC
353 },
354
355 .release = gp8psk_fe_release,
356
357 .init = NULL,
358 .sleep = NULL,
359
360 .set_property = gp8psk_fe_set_property,
361 .get_property = gp8psk_fe_get_property,
362 .set_frontend = gp8psk_fe_set_frontend,
363
364 .get_tune_settings = gp8psk_fe_get_tune_settings,
365
366 .read_status = gp8psk_fe_read_status,
367 .read_ber = gp8psk_fe_read_ber,
368 .read_signal_strength = gp8psk_fe_read_signal_strength,
369 .read_snr = gp8psk_fe_read_snr,
370 .read_ucblocks = gp8psk_fe_read_unc_blocks,
371
372 .diseqc_send_master_cmd = gp8psk_fe_send_diseqc_msg,
373 .diseqc_send_burst = gp8psk_fe_send_diseqc_burst,
374 .set_tone = gp8psk_fe_set_tone,
375 .set_voltage = gp8psk_fe_set_voltage,
376 .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd,
377 .enable_high_lnb_voltage = gp8psk_fe_enable_high_lnb_voltage
378};
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c
new file mode 100644
index 00000000000..1cb3d9a66e0
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/gp8psk.c
@@ -0,0 +1,344 @@
1/* DVB USB compliant Linux driver for the
2 * - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
3 *
4 * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
5 * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com)
6 *
7 * Thanks to GENPIX for the sample code used to implement this module.
8 *
9 * This module is based off the vp7045 and vp702x modules
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation, version 2.
14 *
15 * see Documentation/dvb/README.dvb-usb for more information
16 */
17#include "gp8psk.h"
18
19/* debug */
20static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw";
21int dvb_usb_gp8psk_debug;
22module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644);
23MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
24
25DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
26
27static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
28{
29 return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
30}
31
32static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
33{
34 return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1));
35}
36
37static void gp8psk_info(struct dvb_usb_device *d)
38{
39 u8 fpga_vers, fw_vers[6];
40
41 if (!gp8psk_get_fw_version(d, fw_vers))
42 info("FW Version = %i.%02i.%i (0x%x) Build %4i/%02i/%02i",
43 fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
44 2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
45 else
46 info("failed to get FW version");
47
48 if (!gp8psk_get_fpga_version(d, &fpga_vers))
49 info("FPGA Version = %i", fpga_vers);
50 else
51 info("failed to get FPGA version");
52}
53
54int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
55{
56 int ret = 0,try = 0;
57
58 if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
59 return ret;
60
61 while (ret >= 0 && ret != blen && try < 3) {
62 ret = usb_control_msg(d->udev,
63 usb_rcvctrlpipe(d->udev,0),
64 req,
65 USB_TYPE_VENDOR | USB_DIR_IN,
66 value,index,b,blen,
67 2000);
68 deb_info("reading number %d (ret: %d)\n",try,ret);
69 try++;
70 }
71
72 if (ret < 0 || ret != blen) {
73 warn("usb in %d operation failed.", req);
74 ret = -EIO;
75 } else
76 ret = 0;
77
78 deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
79 debug_dump(b,blen,deb_xfer);
80
81 mutex_unlock(&d->usb_mutex);
82
83 return ret;
84}
85
86int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
87 u16 index, u8 *b, int blen)
88{
89 int ret;
90
91 deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
92 debug_dump(b,blen,deb_xfer);
93
94 if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
95 return ret;
96
97 if (usb_control_msg(d->udev,
98 usb_sndctrlpipe(d->udev,0),
99 req,
100 USB_TYPE_VENDOR | USB_DIR_OUT,
101 value,index,b,blen,
102 2000) != blen) {
103 warn("usb out operation failed.");
104 ret = -EIO;
105 } else
106 ret = 0;
107 mutex_unlock(&d->usb_mutex);
108
109 return ret;
110}
111
112static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
113{
114 int ret;
115 const struct firmware *fw = NULL;
116 const u8 *ptr;
117 u8 *buf;
118 if ((ret = request_firmware(&fw, bcm4500_firmware,
119 &d->udev->dev)) != 0) {
120 err("did not find the bcm4500 firmware file. (%s) "
121 "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
122 bcm4500_firmware,ret);
123 return ret;
124 }
125
126 ret = -EINVAL;
127
128 if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0))
129 goto out_rel_fw;
130
131 info("downloading bcm4500 firmware from file '%s'",bcm4500_firmware);
132
133 ptr = fw->data;
134 buf = kmalloc(64, GFP_KERNEL | GFP_DMA);
135 if (!buf) {
136 ret = -ENOMEM;
137 goto out_rel_fw;
138 }
139
140 while (ptr[0] != 0xff) {
141 u16 buflen = ptr[0] + 4;
142 if (ptr + buflen >= fw->data + fw->size) {
143 err("failed to load bcm4500 firmware.");
144 goto out_free;
145 }
146 memcpy(buf, ptr, buflen);
147 if (dvb_usb_generic_write(d, buf, buflen)) {
148 err("failed to load bcm4500 firmware.");
149 goto out_free;
150 }
151 ptr += buflen;
152 }
153
154 ret = 0;
155
156out_free:
157 kfree(buf);
158out_rel_fw:
159 release_firmware(fw);
160
161 return ret;
162}
163
164static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
165{
166 u8 status, buf;
167 int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
168
169 if (onoff) {
170 gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
171 if (! (status & bm8pskStarted)) { /* started */
172 if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K)
173 gp8psk_usb_out_op(d, CW3K_INIT, 1, 0, NULL, 0);
174 if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
175 return -EINVAL;
176 gp8psk_info(d);
177 }
178
179 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
180 if (! (status & bm8pskFW_Loaded)) /* BCM4500 firmware loaded */
181 if(gp8psk_load_bcm4500fw(d))
182 return -EINVAL;
183
184 if (! (status & bmIntersilOn)) /* LNB Power */
185 if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0,
186 &buf, 1))
187 return -EINVAL;
188
189 /* Set DVB mode to 1 */
190 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
191 if (gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0))
192 return -EINVAL;
193 /* Abort possible TS (if previous tune crashed) */
194 if (gp8psk_usb_out_op(d, ARM_TRANSFER, 0, 0, NULL, 0))
195 return -EINVAL;
196 } else {
197 /* Turn off LNB power */
198 if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1))
199 return -EINVAL;
200 /* Turn off 8psk power */
201 if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
202 return -EINVAL;
203 if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K)
204 gp8psk_usb_out_op(d, CW3K_INIT, 0, 0, NULL, 0);
205 }
206 return 0;
207}
208
209int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
210{
211 u8 buf;
212 int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
213 /* Turn off 8psk power */
214 if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
215 return -EINVAL;
216 /* Turn On 8psk power */
217 if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
218 return -EINVAL;
219 /* load BCM4500 firmware */
220 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
221 if (gp8psk_load_bcm4500fw(d))
222 return -EINVAL;
223 return 0;
224}
225
226static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
227{
228 return gp8psk_usb_out_op(adap->dev, ARM_TRANSFER, onoff, 0 , NULL, 0);
229}
230
231static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
232{
233 adap->fe = gp8psk_fe_attach(adap->dev);
234 return 0;
235}
236
237static struct dvb_usb_device_properties gp8psk_properties;
238
239static int gp8psk_usb_probe(struct usb_interface *intf,
240 const struct usb_device_id *id)
241{
242 int ret;
243 struct usb_device *udev = interface_to_usbdev(intf);
244 ret = dvb_usb_device_init(intf, &gp8psk_properties,
245 THIS_MODULE, NULL, adapter_nr);
246 if (ret == 0) {
247 info("found Genpix USB device pID = %x (hex)",
248 le16_to_cpu(udev->descriptor.idProduct));
249 }
250 return ret;
251}
252
253static struct usb_device_id gp8psk_usb_table [] = {
254 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_COLD) },
255 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) },
256 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) },
257 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) },
258 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_2) },
259/* { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, */
260 { 0 },
261};
262MODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
263
264static struct dvb_usb_device_properties gp8psk_properties = {
265 .usb_ctrl = CYPRESS_FX2,
266 .firmware = "dvb-usb-gp8psk-01.fw",
267
268 .num_adapters = 1,
269 .adapter = {
270 {
271 .streaming_ctrl = gp8psk_streaming_ctrl,
272 .frontend_attach = gp8psk_frontend_attach,
273 /* parameter for the MPEG2-data transfer */
274 .stream = {
275 .type = USB_BULK,
276 .count = 7,
277 .endpoint = 0x82,
278 .u = {
279 .bulk = {
280 .buffersize = 8192,
281 }
282 }
283 },
284 }
285 },
286 .power_ctrl = gp8psk_power_ctrl,
287
288 .generic_bulk_ctrl_endpoint = 0x01,
289
290 .num_device_descs = 4,
291 .devices = {
292 { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver",
293 .cold_ids = { &gp8psk_usb_table[0], NULL },
294 .warm_ids = { &gp8psk_usb_table[1], NULL },
295 },
296 { .name = "Genpix 8PSK-to-USB2 Rev.2 DVB-S receiver",
297 .cold_ids = { NULL },
298 .warm_ids = { &gp8psk_usb_table[2], NULL },
299 },
300 { .name = "Genpix SkyWalker-1 DVB-S receiver",
301 .cold_ids = { NULL },
302 .warm_ids = { &gp8psk_usb_table[3], NULL },
303 },
304 { .name = "Genpix SkyWalker-2 DVB-S receiver",
305 .cold_ids = { NULL },
306 .warm_ids = { &gp8psk_usb_table[4], NULL },
307 },
308 { NULL },
309 }
310};
311
312/* usb specific object needed to register this driver with the usb subsystem */
313static struct usb_driver gp8psk_usb_driver = {
314 .name = "dvb_usb_gp8psk",
315 .probe = gp8psk_usb_probe,
316 .disconnect = dvb_usb_device_exit,
317 .id_table = gp8psk_usb_table,
318};
319
320/* module stuff */
321static int __init gp8psk_usb_module_init(void)
322{
323 int result;
324 if ((result = usb_register(&gp8psk_usb_driver))) {
325 err("usb_register failed. (%d)",result);
326 return result;
327 }
328
329 return 0;
330}
331
332static void __exit gp8psk_usb_module_exit(void)
333{
334 /* deregister this driver from the USB subsystem */
335 usb_deregister(&gp8psk_usb_driver);
336}
337
338module_init(gp8psk_usb_module_init);
339module_exit(gp8psk_usb_module_exit);
340
341MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>");
342MODULE_DESCRIPTION("Driver for Genpix DVB-S");
343MODULE_VERSION("1.1");
344MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.h b/drivers/media/dvb/dvb-usb/gp8psk.h
new file mode 100644
index 00000000000..ed32b9da484
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/gp8psk.h
@@ -0,0 +1,100 @@
1/* DVB USB compliant Linux driver for the
2 * - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
3 *
4 * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
5 * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
6 *
7 * Thanks to GENPIX for the sample code used to implement this module.
8 *
9 * This module is based off the vp7045 and vp702x modules
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation, version 2.
14 *
15 * see Documentation/dvb/README.dvb-usb for more information
16 */
17#ifndef _DVB_USB_GP8PSK_H_
18#define _DVB_USB_GP8PSK_H_
19
20#define DVB_USB_LOG_PREFIX "gp8psk"
21#include "dvb-usb.h"
22
23extern int dvb_usb_gp8psk_debug;
24#define deb_info(args...) dprintk(dvb_usb_gp8psk_debug,0x01,args)
25#define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args)
26#define deb_rc(args...) dprintk(dvb_usb_gp8psk_debug,0x04,args)
27#define deb_fe(args...) dprintk(dvb_usb_gp8psk_debug,0x08,args)
28
29/* Twinhan Vendor requests */
30#define TH_COMMAND_IN 0xC0
31#define TH_COMMAND_OUT 0xC1
32
33/* gp8psk commands */
34
35#define GET_8PSK_CONFIG 0x80 /* in */
36#define SET_8PSK_CONFIG 0x81
37#define I2C_WRITE 0x83
38#define I2C_READ 0x84
39#define ARM_TRANSFER 0x85
40#define TUNE_8PSK 0x86
41#define GET_SIGNAL_STRENGTH 0x87 /* in */
42#define LOAD_BCM4500 0x88
43#define BOOT_8PSK 0x89 /* in */
44#define START_INTERSIL 0x8A /* in */
45#define SET_LNB_VOLTAGE 0x8B
46#define SET_22KHZ_TONE 0x8C
47#define SEND_DISEQC_COMMAND 0x8D
48#define SET_DVB_MODE 0x8E
49#define SET_DN_SWITCH 0x8F
50#define GET_SIGNAL_LOCK 0x90 /* in */
51#define GET_FW_VERS 0x92
52#define GET_SERIAL_NUMBER 0x93 /* in */
53#define USE_EXTRA_VOLT 0x94
54#define GET_FPGA_VERS 0x95
55#define CW3K_INIT 0x9d
56
57/* PSK_configuration bits */
58#define bm8pskStarted 0x01
59#define bm8pskFW_Loaded 0x02
60#define bmIntersilOn 0x04
61#define bmDVBmode 0x08
62#define bm22kHz 0x10
63#define bmSEL18V 0x20
64#define bmDCtuned 0x40
65#define bmArmed 0x80
66
67/* Satellite modulation modes */
68#define ADV_MOD_DVB_QPSK 0 /* DVB-S QPSK */
69#define ADV_MOD_TURBO_QPSK 1 /* Turbo QPSK */
70#define ADV_MOD_TURBO_8PSK 2 /* Turbo 8PSK (also used for Trellis 8PSK) */
71#define ADV_MOD_TURBO_16QAM 3 /* Turbo 16QAM (also used for Trellis 8PSK) */
72
73#define ADV_MOD_DCII_C_QPSK 4 /* Digicipher II Combo */
74#define ADV_MOD_DCII_I_QPSK 5 /* Digicipher II I-stream */
75#define ADV_MOD_DCII_Q_QPSK 6 /* Digicipher II Q-stream */
76#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
77#define ADV_MOD_DSS_QPSK 8 /* DSS (DIRECTV) QPSK */
78#define ADV_MOD_DVB_BPSK 9 /* DVB-S BPSK */
79
80#define GET_USB_SPEED 0x07
81
82#define RESET_FX2 0x13
83
84#define FW_VERSION_READ 0x0B
85#define VENDOR_STRING_READ 0x0C
86#define PRODUCT_STRING_READ 0x0D
87#define FW_BCD_VERSION_READ 0x14
88
89/* firmware revision id's */
90#define GP8PSK_FW_REV1 0x020604
91#define GP8PSK_FW_REV2 0x020704
92#define GP8PSK_FW_VERS(_fw_vers) ((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0])
93
94extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
95extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
96extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
97 u16 index, u8 *b, int blen);
98extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d);
99
100#endif
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c
new file mode 100644
index 00000000000..37b146961ae
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/lmedm04.c
@@ -0,0 +1,1310 @@
1/* DVB USB compliant linux driver for
2 *
3 * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395
4 * LME2510C + LG TDQY-P001F
5 * LME2510C + BS2F7HZ0194
6 * LME2510 + LG TDQY-P001F
7 * LME2510 + BS2F7HZ0194
8 *
9 * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
10 * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
11 *
12 * MV001F (LME2510+LGTDQY-P001F)
13 * LG TDQY - P001F =(TDA8263 + TDA10086H)
14 *
15 * MVB0001F (LME2510C+LGTDQT-P001F)
16 *
17 * MV0194 (LME2510+SHARP:BS2F7HZ0194)
18 * SHARP:BS2F7HZ0194 = (STV0299+IX2410)
19 *
20 * MVB0194 (LME2510C+SHARP0194)
21 *
22 * For firmware see Documentation/dvb/lmedm04.txt
23 *
24 * I2C addresses:
25 * 0xd0 - STV0288 - Demodulator
26 * 0xc0 - Sharp IX2505V - Tuner
27 * --
28 * 0x1c - TDA10086 - Demodulator
29 * 0xc0 - TDA8263 - Tuner
30 * --
31 * 0xd0 - STV0299 - Demodulator
32 * 0xc0 - IX2410 - Tuner
33 *
34 *
35 * VID = 3344 PID LME2510=1122 LME2510C=1120
36 *
37 * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
38 * LME2510(C)(C) Leaguerme (Shenzhen) MicroElectronics Co., Ltd.
39 *
40 * This program is free software; you can redistribute it and/or modify
41 * it under the terms of the GNU General Public License Version 2, as
42 * published by the Free Software Foundation.
43 *
44 * This program is distributed in the hope that it will be useful,
45 * but WITHOUT ANY WARRANTY; without even the implied warranty of
46 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47 * GNU General Public License for more details.
48 *
49 * You should have received a copy of the GNU General Public License
50 * along with this program; if not, write to the Free Software
51 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
52 *
53 *
54 * see Documentation/dvb/README.dvb-usb for more information
55 *
56 * Known Issues :
57 * LME2510: Non Intel USB chipsets fail to maintain High Speed on
58 * Boot or Hot Plug.
59 *
60 * QQbox suffers from noise on LNB voltage.
61 *
62 * LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system
63 * with other tuners. After a cold reset streaming will not start.
64 *
65 */
66#define DVB_USB_LOG_PREFIX "LME2510(C)"
67#include <linux/usb.h>
68#include <linux/usb/input.h>
69#include <media/rc-core.h>
70
71#include "dvb-usb.h"
72#include "lmedm04.h"
73#include "tda826x.h"
74#include "tda10086.h"
75#include "stv0288.h"
76#include "ix2505v.h"
77#include "stv0299.h"
78#include "dvb-pll.h"
79#include "z0194a.h"
80
81
82
83/* debug */
84static int dvb_usb_lme2510_debug;
85#define l_dprintk(var, level, args...) do { \
86 if ((var >= level)) \
87 printk(KERN_DEBUG DVB_USB_LOG_PREFIX ": " args); \
88} while (0)
89
90#define deb_info(level, args...) l_dprintk(dvb_usb_lme2510_debug, level, args)
91#define debug_data_snipet(level, name, p) \
92 deb_info(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
93 *p, *(p+1), *(p+2), *(p+3), *(p+4), \
94 *(p+5), *(p+6), *(p+7));
95
96
97module_param_named(debug, dvb_usb_lme2510_debug, int, 0644);
98MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))."
99 DVB_USB_DEBUG_STATUS);
100
101static int dvb_usb_lme2510_firmware;
102module_param_named(firmware, dvb_usb_lme2510_firmware, int, 0644);
103MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
104
105static int pid_filter;
106module_param_named(pid, pid_filter, int, 0644);
107MODULE_PARM_DESC(pid, "set default 0=on 1=off");
108
109
110DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
111
112#define TUNER_DEFAULT 0x0
113#define TUNER_LG 0x1
114#define TUNER_S7395 0x2
115#define TUNER_S0194 0x3
116
117struct lme2510_state {
118 u8 id;
119 u8 tuner_config;
120 u8 signal_lock;
121 u8 signal_level;
122 u8 signal_sn;
123 u8 time_key;
124 u8 i2c_talk_onoff;
125 u8 i2c_gate;
126 u8 i2c_tuner_gate_w;
127 u8 i2c_tuner_gate_r;
128 u8 i2c_tuner_addr;
129 u8 stream_on;
130 u8 pid_size;
131 void *buffer;
132 struct urb *lme_urb;
133 void *usb_buffer;
134
135};
136
137static int lme2510_bulk_write(struct usb_device *dev,
138 u8 *snd, int len, u8 pipe)
139{
140 int ret, actual_l;
141
142 ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
143 snd, len , &actual_l, 100);
144 return ret;
145}
146
147static int lme2510_bulk_read(struct usb_device *dev,
148 u8 *rev, int len, u8 pipe)
149{
150 int ret, actual_l;
151
152 ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
153 rev, len , &actual_l, 200);
154 return ret;
155}
156
157static int lme2510_usb_talk(struct dvb_usb_device *d,
158 u8 *wbuf, int wlen, u8 *rbuf, int rlen)
159{
160 struct lme2510_state *st = d->priv;
161 u8 *buff;
162 int ret = 0;
163
164 if (st->usb_buffer == NULL) {
165 st->usb_buffer = kmalloc(512, GFP_KERNEL);
166 if (st->usb_buffer == NULL) {
167 info("MEM Error no memory");
168 return -ENOMEM;
169 }
170 }
171 buff = st->usb_buffer;
172
173 ret = mutex_lock_interruptible(&d->usb_mutex);
174
175 if (ret < 0)
176 return -EAGAIN;
177
178 /* the read/write capped at 512 */
179 memcpy(buff, wbuf, (wlen > 512) ? 512 : wlen);
180
181 ret |= usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01));
182
183 ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
184
185 msleep(10);
186
187 ret |= usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x01));
188
189 ret |= lme2510_bulk_read(d->udev, buff, (rlen > 512) ?
190 512 : rlen , 0x01);
191
192 if (rlen > 0)
193 memcpy(rbuf, buff, rlen);
194
195 mutex_unlock(&d->usb_mutex);
196
197 return (ret < 0) ? -ENODEV : 0;
198}
199
200static int lme2510_stream_restart(struct dvb_usb_device *d)
201{
202 static u8 stream_on[] = LME_ST_ON_W;
203 int ret;
204 u8 rbuff[10];
205 /*Restart Stream Command*/
206 ret = lme2510_usb_talk(d, stream_on, sizeof(stream_on),
207 rbuff, sizeof(rbuff));
208 return ret;
209}
210
211static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out)
212{
213 struct lme2510_state *st = d->priv;
214 static u8 pid_buff[] = LME_ZERO_PID;
215 static u8 rbuf[1];
216 u8 pid_no = index * 2;
217 u8 pid_len = pid_no + 2;
218 int ret = 0;
219 deb_info(1, "PID Setting Pid %04x", pid_out);
220
221 if (st->pid_size == 0)
222 ret |= lme2510_stream_restart(d);
223
224 pid_buff[2] = pid_no;
225 pid_buff[3] = (u8)pid_out & 0xff;
226 pid_buff[4] = pid_no + 1;
227 pid_buff[5] = (u8)(pid_out >> 8);
228
229 if (pid_len > st->pid_size)
230 st->pid_size = pid_len;
231 pid_buff[7] = 0x80 + st->pid_size;
232
233 ret |= lme2510_usb_talk(d, pid_buff ,
234 sizeof(pid_buff) , rbuf, sizeof(rbuf));
235
236 if (st->stream_on)
237 ret |= lme2510_stream_restart(d);
238
239 return ret;
240}
241
242static void lme2510_int_response(struct urb *lme_urb)
243{
244 struct dvb_usb_adapter *adap = lme_urb->context;
245 struct lme2510_state *st = adap->dev->priv;
246 static u8 *ibuf, *rbuf;
247 int i = 0, offset;
248 u32 key;
249
250 switch (lme_urb->status) {
251 case 0:
252 case -ETIMEDOUT:
253 break;
254 case -ECONNRESET:
255 case -ENOENT:
256 case -ESHUTDOWN:
257 return;
258 default:
259 info("Error %x", lme_urb->status);
260 break;
261 }
262
263 rbuf = (u8 *) lme_urb->transfer_buffer;
264
265 offset = ((lme_urb->actual_length/8) > 4)
266 ? 4 : (lme_urb->actual_length/8) ;
267
268 for (i = 0; i < offset; ++i) {
269 ibuf = (u8 *)&rbuf[i*8];
270 deb_info(5, "INT O/S C =%02x C/O=%02x Type =%02x%02x",
271 offset, i, ibuf[0], ibuf[1]);
272
273 switch (ibuf[0]) {
274 case 0xaa:
275 debug_data_snipet(1, "INT Remote data snipet", ibuf);
276 if ((ibuf[4] + ibuf[5]) == 0xff) {
277 key = ibuf[5];
278 key += (ibuf[3] > 0)
279 ? (ibuf[3] ^ 0xff) << 8 : 0;
280 key += (ibuf[2] ^ 0xff) << 16;
281 deb_info(1, "INT Key =%08x", key);
282 if (adap->dev->rc_dev != NULL)
283 rc_keydown(adap->dev->rc_dev, key, 0);
284 }
285 break;
286 case 0xbb:
287 switch (st->tuner_config) {
288 case TUNER_LG:
289 if (ibuf[2] > 0)
290 st->signal_lock = ibuf[2];
291 st->signal_level = ibuf[4];
292 st->signal_sn = ibuf[3];
293 st->time_key = ibuf[7];
294 break;
295 case TUNER_S7395:
296 case TUNER_S0194:
297 /* Tweak for earlier firmware*/
298 if (ibuf[1] == 0x03) {
299 if (ibuf[2] > 1)
300 st->signal_lock = ibuf[2];
301 st->signal_level = ibuf[3];
302 st->signal_sn = ibuf[4];
303 } else {
304 st->signal_level = ibuf[4];
305 st->signal_sn = ibuf[5];
306 st->signal_lock =
307 (st->signal_lock & 0xf7) +
308 ((ibuf[2] & 0x01) << 0x03);
309 }
310 break;
311 default:
312 break;
313 }
314 debug_data_snipet(5, "INT Remote data snipet in", ibuf);
315 break;
316 case 0xcc:
317 debug_data_snipet(1, "INT Control data snipet", ibuf);
318 break;
319 default:
320 debug_data_snipet(1, "INT Unknown data snipet", ibuf);
321 break;
322 }
323 }
324 usb_submit_urb(lme_urb, GFP_ATOMIC);
325}
326
327static int lme2510_int_read(struct dvb_usb_adapter *adap)
328{
329 struct lme2510_state *lme_int = adap->dev->priv;
330
331 lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC);
332
333 if (lme_int->lme_urb == NULL)
334 return -ENOMEM;
335
336 lme_int->buffer = usb_alloc_coherent(adap->dev->udev, 5000, GFP_ATOMIC,
337 &lme_int->lme_urb->transfer_dma);
338
339 if (lme_int->buffer == NULL)
340 return -ENOMEM;
341
342 usb_fill_int_urb(lme_int->lme_urb,
343 adap->dev->udev,
344 usb_rcvintpipe(adap->dev->udev, 0xa),
345 lme_int->buffer,
346 4096,
347 lme2510_int_response,
348 adap,
349 11);
350
351 lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
352
353 usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC);
354 info("INT Interrupt Service Started");
355
356 return 0;
357}
358
359static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
360{
361 struct lme2510_state *st = adap->dev->priv;
362 static u8 clear_pid_reg[] = LME_CLEAR_PID;
363 static u8 rbuf[1];
364 int ret;
365
366 deb_info(1, "PID Clearing Filter");
367
368 ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
369 if (ret < 0)
370 return -EAGAIN;
371
372 if (!onoff)
373 ret |= lme2510_usb_talk(adap->dev, clear_pid_reg,
374 sizeof(clear_pid_reg), rbuf, sizeof(rbuf));
375
376 st->pid_size = 0;
377
378 mutex_unlock(&adap->dev->i2c_mutex);
379
380 return 0;
381}
382
383static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
384 int onoff)
385{
386 int ret = 0;
387
388 deb_info(3, "%s PID=%04x Index=%04x onoff=%02x", __func__,
389 pid, index, onoff);
390
391 if (onoff)
392 if (!pid_filter) {
393 ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
394 if (ret < 0)
395 return -EAGAIN;
396 ret |= lme2510_enable_pid(adap->dev, index, pid);
397 mutex_unlock(&adap->dev->i2c_mutex);
398 }
399
400
401 return ret;
402}
403
404
405static int lme2510_return_status(struct usb_device *dev)
406{
407 int ret = 0;
408 u8 *data;
409
410 data = kzalloc(10, GFP_KERNEL);
411 if (!data)
412 return -ENOMEM;
413
414 ret |= usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
415 0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
416 info("Firmware Status: %x (%x)", ret , data[2]);
417
418 ret = (ret < 0) ? -ENODEV : data[2];
419 kfree(data);
420 return ret;
421}
422
423static int lme2510_msg(struct dvb_usb_device *d,
424 u8 *wbuf, int wlen, u8 *rbuf, int rlen)
425{
426 int ret = 0;
427 struct lme2510_state *st = d->priv;
428
429 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
430 return -EAGAIN;
431
432 if (st->i2c_talk_onoff == 1) {
433
434 ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
435
436 switch (st->tuner_config) {
437 case TUNER_LG:
438 if (wbuf[2] == 0x1c) {
439 if (wbuf[3] == 0x0e) {
440 st->signal_lock = rbuf[1];
441 if ((st->stream_on & 1) &&
442 (st->signal_lock & 0x10)) {
443 lme2510_stream_restart(d);
444 st->i2c_talk_onoff = 0;
445 }
446 msleep(80);
447 }
448 }
449 break;
450 case TUNER_S7395:
451 if (wbuf[2] == 0xd0) {
452 if (wbuf[3] == 0x24) {
453 st->signal_lock = rbuf[1];
454 if ((st->stream_on & 1) &&
455 (st->signal_lock & 0x8)) {
456 lme2510_stream_restart(d);
457 st->i2c_talk_onoff = 0;
458 }
459 }
460 if ((wbuf[3] != 0x6) & (wbuf[3] != 0x5))
461 msleep(5);
462 }
463 break;
464 case TUNER_S0194:
465 if (wbuf[2] == 0xd0) {
466 if (wbuf[3] == 0x1b) {
467 st->signal_lock = rbuf[1];
468 if ((st->stream_on & 1) &&
469 (st->signal_lock & 0x8)) {
470 lme2510_stream_restart(d);
471 st->i2c_talk_onoff = 0;
472 }
473 }
474 }
475 break;
476 default:
477 break;
478 }
479 } else {
480 switch (st->tuner_config) {
481 case TUNER_LG:
482 switch (wbuf[3]) {
483 case 0x0e:
484 rbuf[0] = 0x55;
485 rbuf[1] = st->signal_lock;
486 break;
487 case 0x43:
488 rbuf[0] = 0x55;
489 rbuf[1] = st->signal_level;
490 break;
491 case 0x1c:
492 rbuf[0] = 0x55;
493 rbuf[1] = st->signal_sn;
494 break;
495 case 0x15:
496 case 0x16:
497 case 0x17:
498 case 0x18:
499 rbuf[0] = 0x55;
500 rbuf[1] = 0x00;
501 break;
502 default:
503 lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
504 st->i2c_talk_onoff = 1;
505 break;
506 }
507 break;
508 case TUNER_S7395:
509 switch (wbuf[3]) {
510 case 0x10:
511 rbuf[0] = 0x55;
512 rbuf[1] = (st->signal_level & 0x80)
513 ? 0 : (st->signal_level * 2);
514 break;
515 case 0x2d:
516 rbuf[0] = 0x55;
517 rbuf[1] = st->signal_sn;
518 break;
519 case 0x24:
520 rbuf[0] = 0x55;
521 rbuf[1] = st->signal_lock;
522 break;
523 case 0x2e:
524 case 0x26:
525 case 0x27:
526 rbuf[0] = 0x55;
527 rbuf[1] = 0x00;
528 break;
529 default:
530 lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
531 st->i2c_talk_onoff = 1;
532 break;
533 }
534 break;
535 case TUNER_S0194:
536 switch (wbuf[3]) {
537 case 0x18:
538 rbuf[0] = 0x55;
539 rbuf[1] = (st->signal_level & 0x80)
540 ? 0 : (st->signal_level * 2);
541 break;
542 case 0x24:
543 rbuf[0] = 0x55;
544 rbuf[1] = st->signal_sn;
545 break;
546 case 0x1b:
547 rbuf[0] = 0x55;
548 rbuf[1] = st->signal_lock;
549 break;
550 case 0x19:
551 case 0x25:
552 case 0x1e:
553 case 0x1d:
554 rbuf[0] = 0x55;
555 rbuf[1] = 0x00;
556 break;
557 default:
558 lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
559 st->i2c_talk_onoff = 1;
560 break;
561 }
562 break;
563 default:
564 break;
565 }
566
567 deb_info(4, "I2C From Interrupt Message out(%02x) in(%02x)",
568 wbuf[3], rbuf[1]);
569
570 }
571
572 mutex_unlock(&d->i2c_mutex);
573
574 return ret;
575}
576
577
578static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
579 int num)
580{
581 struct dvb_usb_device *d = i2c_get_adapdata(adap);
582 struct lme2510_state *st = d->priv;
583 static u8 obuf[64], ibuf[512];
584 int i, read, read_o;
585 u16 len;
586 u8 gate = st->i2c_gate;
587
588 if (gate == 0)
589 gate = 5;
590
591 if (num > 2)
592 warn("more than 2 i2c messages"
593 "at a time is not handled yet. TODO.");
594
595 for (i = 0; i < num; i++) {
596 read_o = 1 & (msg[i].flags & I2C_M_RD);
597 read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
598 read |= read_o;
599 gate = (msg[i].addr == st->i2c_tuner_addr)
600 ? (read) ? st->i2c_tuner_gate_r
601 : st->i2c_tuner_gate_w
602 : st->i2c_gate;
603 obuf[0] = gate | (read << 7);
604
605 if (gate == 5)
606 obuf[1] = (read) ? 2 : msg[i].len + 1;
607 else
608 obuf[1] = msg[i].len + read + 1;
609
610 obuf[2] = msg[i].addr;
611 if (read) {
612 if (read_o)
613 len = 3;
614 else {
615 memcpy(&obuf[3], msg[i].buf, msg[i].len);
616 obuf[msg[i].len+3] = msg[i+1].len;
617 len = msg[i].len+4;
618 }
619 } else {
620 memcpy(&obuf[3], msg[i].buf, msg[i].len);
621 len = msg[i].len+3;
622 }
623
624 if (lme2510_msg(d, obuf, len, ibuf, 512) < 0) {
625 deb_info(1, "i2c transfer failed.");
626 return -EAGAIN;
627 }
628
629 if (read) {
630 if (read_o)
631 memcpy(msg[i].buf, &ibuf[1], msg[i].len);
632 else {
633 memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
634 i++;
635 }
636 }
637 }
638 return i;
639}
640
641static u32 lme2510_i2c_func(struct i2c_adapter *adapter)
642{
643 return I2C_FUNC_I2C;
644}
645
646static struct i2c_algorithm lme2510_i2c_algo = {
647 .master_xfer = lme2510_i2c_xfer,
648 .functionality = lme2510_i2c_func,
649};
650
651/* Callbacks for DVB USB */
652static int lme2510_identify_state(struct usb_device *udev,
653 struct dvb_usb_device_properties *props,
654 struct dvb_usb_device_description **desc,
655 int *cold)
656{
657 *cold = 0;
658 return 0;
659}
660
661static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
662{
663 struct lme2510_state *st = adap->dev->priv;
664 static u8 clear_reg_3[] = LME_CLEAR_PID;
665 static u8 rbuf[1];
666 int ret = 0, rlen = sizeof(rbuf);
667
668 deb_info(1, "STM (%02x)", onoff);
669
670 /* Streaming is started by FE_HAS_LOCK */
671 if (onoff == 1)
672 st->stream_on = 1;
673 else {
674 deb_info(1, "STM Steam Off");
675 /* mutex is here only to avoid collision with I2C */
676 if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
677 return -EAGAIN;
678
679 ret = lme2510_usb_talk(adap->dev, clear_reg_3,
680 sizeof(clear_reg_3), rbuf, rlen);
681 st->stream_on = 0;
682 st->i2c_talk_onoff = 1;
683
684 mutex_unlock(&adap->dev->i2c_mutex);
685 }
686
687 return (ret < 0) ? -ENODEV : 0;
688}
689
690static u8 check_sum(u8 *p, u8 len)
691{
692 u8 sum = 0;
693 while (len--)
694 sum += *p++;
695 return sum;
696}
697
698static int lme2510_download_firmware(struct usb_device *dev,
699 const struct firmware *fw)
700{
701 int ret = 0;
702 u8 *data;
703 u16 j, wlen, len_in, start, end;
704 u8 packet_size, dlen, i;
705 u8 *fw_data;
706
707 packet_size = 0x31;
708 len_in = 1;
709
710 data = kzalloc(512, GFP_KERNEL);
711 if (!data) {
712 info("FRM Could not start Firmware Download (Buffer allocation failed)");
713 return -ENOMEM;
714 }
715
716 info("FRM Starting Firmware Download");
717
718 for (i = 1; i < 3; i++) {
719 start = (i == 1) ? 0 : 512;
720 end = (i == 1) ? 512 : fw->size;
721 for (j = start; j < end; j += (packet_size+1)) {
722 fw_data = (u8 *)(fw->data + j);
723 if ((end - j) > packet_size) {
724 data[0] = i;
725 dlen = packet_size;
726 } else {
727 data[0] = i | 0x80;
728 dlen = (u8)(end - j)-1;
729 }
730 data[1] = dlen;
731 memcpy(&data[2], fw_data, dlen+1);
732 wlen = (u8) dlen + 4;
733 data[wlen-1] = check_sum(fw_data, dlen+1);
734 deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3],
735 data[dlen+2], data[dlen+3]);
736 ret |= lme2510_bulk_write(dev, data, wlen, 1);
737 ret |= lme2510_bulk_read(dev, data, len_in , 1);
738 ret |= (data[0] == 0x88) ? 0 : -1;
739 }
740 }
741
742 usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
743 0x06, 0x80, 0x0200, 0x00, data, 0x0109, 1000);
744
745
746 data[0] = 0x8a;
747 len_in = 1;
748 msleep(2000);
749 ret |= lme2510_bulk_write(dev, data , len_in, 1); /*Resetting*/
750 ret |= lme2510_bulk_read(dev, data, len_in, 1);
751 msleep(400);
752
753 if (ret < 0)
754 info("FRM Firmware Download Failed (%04x)" , ret);
755 else
756 info("FRM Firmware Download Completed - Resetting Device");
757
758 kfree(data);
759 return (ret < 0) ? -ENODEV : 0;
760}
761
762static void lme_coldreset(struct usb_device *dev)
763{
764 int ret = 0, len_in;
765 u8 data[512] = {0};
766
767 data[0] = 0x0a;
768 len_in = 1;
769 info("FRM Firmware Cold Reset");
770 ret |= lme2510_bulk_write(dev, data , len_in, 1); /*Cold Resetting*/
771 ret |= lme2510_bulk_read(dev, data, len_in, 1);
772
773 return;
774}
775
776static int lme_firmware_switch(struct usb_device *udev, int cold)
777{
778 const struct firmware *fw = NULL;
779 const char fw_c_s7395[] = "dvb-usb-lme2510c-s7395.fw";
780 const char fw_c_lg[] = "dvb-usb-lme2510c-lg.fw";
781 const char fw_c_s0194[] = "dvb-usb-lme2510c-s0194.fw";
782 const char fw_lg[] = "dvb-usb-lme2510-lg.fw";
783 const char fw_s0194[] = "dvb-usb-lme2510-s0194.fw";
784 const char *fw_lme;
785 int ret, cold_fw;
786
787 cold = (cold > 0) ? (cold & 1) : 0;
788
789 cold_fw = !cold;
790
791 if (le16_to_cpu(udev->descriptor.idProduct) == 0x1122) {
792 switch (dvb_usb_lme2510_firmware) {
793 default:
794 dvb_usb_lme2510_firmware = TUNER_S0194;
795 case TUNER_S0194:
796 fw_lme = fw_s0194;
797 ret = request_firmware(&fw, fw_lme, &udev->dev);
798 if (ret == 0) {
799 cold = 0;
800 break;
801 }
802 dvb_usb_lme2510_firmware = TUNER_LG;
803 case TUNER_LG:
804 fw_lme = fw_lg;
805 ret = request_firmware(&fw, fw_lme, &udev->dev);
806 if (ret == 0)
807 break;
808 info("FRM No Firmware Found - please install");
809 dvb_usb_lme2510_firmware = TUNER_DEFAULT;
810 cold = 0;
811 cold_fw = 0;
812 break;
813 }
814 } else {
815 switch (dvb_usb_lme2510_firmware) {
816 default:
817 dvb_usb_lme2510_firmware = TUNER_S7395;
818 case TUNER_S7395:
819 fw_lme = fw_c_s7395;
820 ret = request_firmware(&fw, fw_lme, &udev->dev);
821 if (ret == 0) {
822 cold = 0;
823 break;
824 }
825 dvb_usb_lme2510_firmware = TUNER_LG;
826 case TUNER_LG:
827 fw_lme = fw_c_lg;
828 ret = request_firmware(&fw, fw_lme, &udev->dev);
829 if (ret == 0)
830 break;
831 dvb_usb_lme2510_firmware = TUNER_S0194;
832 case TUNER_S0194:
833 fw_lme = fw_c_s0194;
834 ret = request_firmware(&fw, fw_lme, &udev->dev);
835 if (ret == 0)
836 break;
837 info("FRM No Firmware Found - please install");
838 dvb_usb_lme2510_firmware = TUNER_DEFAULT;
839 cold = 0;
840 cold_fw = 0;
841 break;
842 }
843 }
844
845 if (cold_fw) {
846 info("FRM Loading %s file", fw_lme);
847 ret = lme2510_download_firmware(udev, fw);
848 }
849
850 release_firmware(fw);
851
852 if (cold) {
853 info("FRM Changing to %s firmware", fw_lme);
854 lme_coldreset(udev);
855 return -ENODEV;
856 }
857
858 return ret;
859}
860
861static int lme2510_kill_urb(struct usb_data_stream *stream)
862{
863 int i;
864
865 for (i = 0; i < stream->urbs_submitted; i++) {
866 deb_info(3, "killing URB no. %d.", i);
867 /* stop the URB */
868 usb_kill_urb(stream->urb_list[i]);
869 }
870 stream->urbs_submitted = 0;
871
872 return 0;
873}
874
875static struct tda10086_config tda10086_config = {
876 .demod_address = 0x1c,
877 .invert = 0,
878 .diseqc_tone = 1,
879 .xtal_freq = TDA10086_XTAL_16M,
880};
881
882static struct stv0288_config lme_config = {
883 .demod_address = 0xd0,
884 .min_delay_ms = 15,
885 .inittab = s7395_inittab,
886};
887
888static struct ix2505v_config lme_tuner = {
889 .tuner_address = 0xc0,
890 .min_delay_ms = 100,
891 .tuner_gain = 0x0,
892 .tuner_chargepump = 0x3,
893};
894
895static struct stv0299_config sharp_z0194_config = {
896 .demod_address = 0xd0,
897 .inittab = sharp_z0194a_inittab,
898 .mclk = 88000000UL,
899 .invert = 0,
900 .skip_reinit = 0,
901 .lock_output = STV0299_LOCKOUTPUT_1,
902 .volt13_op0_op1 = STV0299_VOLT13_OP1,
903 .min_delay_ms = 100,
904 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
905};
906
907static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
908 fe_sec_voltage_t voltage)
909{
910 struct dvb_usb_adapter *adap = fe->dvb->priv;
911 static u8 voltage_low[] = LME_VOLTAGE_L;
912 static u8 voltage_high[] = LME_VOLTAGE_H;
913 static u8 rbuf[1];
914 int ret = 0, len = 3, rlen = 1;
915
916 if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
917 return -EAGAIN;
918
919 switch (voltage) {
920 case SEC_VOLTAGE_18:
921 ret |= lme2510_usb_talk(adap->dev,
922 voltage_high, len, rbuf, rlen);
923 break;
924
925 case SEC_VOLTAGE_OFF:
926 case SEC_VOLTAGE_13:
927 default:
928 ret |= lme2510_usb_talk(adap->dev,
929 voltage_low, len, rbuf, rlen);
930 break;
931 }
932
933 mutex_unlock(&adap->dev->i2c_mutex);
934
935 return (ret < 0) ? -ENODEV : 0;
936}
937
938static int lme_name(struct dvb_usb_adapter *adap)
939{
940 struct lme2510_state *st = adap->dev->priv;
941 const char *desc = adap->dev->desc->name;
942 char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
943 " SHARP:BS2F7HZ0194"};
944 char *name = adap->fe->ops.info.name;
945
946 strlcpy(name, desc, 128);
947 strlcat(name, fe_name[st->tuner_config], 128);
948
949 return 0;
950}
951
952static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
953{
954 struct lme2510_state *st = adap->dev->priv;
955
956 int ret = 0;
957
958 st->i2c_talk_onoff = 1;
959
960 st->i2c_gate = 4;
961 adap->fe = dvb_attach(tda10086_attach, &tda10086_config,
962 &adap->dev->i2c_adap);
963
964 if (adap->fe) {
965 info("TUN Found Frontend TDA10086");
966 st->i2c_tuner_gate_w = 4;
967 st->i2c_tuner_gate_r = 4;
968 st->i2c_tuner_addr = 0xc0;
969 st->tuner_config = TUNER_LG;
970 if (dvb_usb_lme2510_firmware != TUNER_LG) {
971 dvb_usb_lme2510_firmware = TUNER_LG;
972 ret = lme_firmware_switch(adap->dev->udev, 1);
973 }
974 goto end;
975 }
976
977 st->i2c_gate = 4;
978 adap->fe = dvb_attach(stv0299_attach, &sharp_z0194_config,
979 &adap->dev->i2c_adap);
980 if (adap->fe) {
981 info("FE Found Stv0299");
982 st->i2c_tuner_gate_w = 4;
983 st->i2c_tuner_gate_r = 5;
984 st->i2c_tuner_addr = 0xc0;
985 st->tuner_config = TUNER_S0194;
986 if (dvb_usb_lme2510_firmware != TUNER_S0194) {
987 dvb_usb_lme2510_firmware = TUNER_S0194;
988 ret = lme_firmware_switch(adap->dev->udev, 1);
989 }
990 goto end;
991 }
992
993 st->i2c_gate = 5;
994 adap->fe = dvb_attach(stv0288_attach, &lme_config,
995 &adap->dev->i2c_adap);
996 if (adap->fe) {
997 info("FE Found Stv0288");
998 st->i2c_tuner_gate_w = 4;
999 st->i2c_tuner_gate_r = 5;
1000 st->i2c_tuner_addr = 0xc0;
1001 st->tuner_config = TUNER_S7395;
1002 if (dvb_usb_lme2510_firmware != TUNER_S7395) {
1003 dvb_usb_lme2510_firmware = TUNER_S7395;
1004 ret = lme_firmware_switch(adap->dev->udev, 1);
1005 }
1006 } else {
1007 info("DM04 Not Supported");
1008 return -ENODEV;
1009 }
1010
1011
1012end: if (ret) {
1013 if (adap->fe) {
1014 dvb_frontend_detach(adap->fe);
1015 adap->fe = NULL;
1016 }
1017 adap->dev->props.rc.core.rc_codes = NULL;
1018 return -ENODEV;
1019 }
1020
1021 adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
1022 ret = lme_name(adap);
1023 return ret;
1024}
1025
1026static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
1027{
1028 struct lme2510_state *st = adap->dev->priv;
1029 char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA"};
1030 int ret = 0;
1031
1032 switch (st->tuner_config) {
1033 case TUNER_LG:
1034 if (dvb_attach(tda826x_attach, adap->fe, 0xc0,
1035 &adap->dev->i2c_adap, 1))
1036 ret = st->tuner_config;
1037 break;
1038 case TUNER_S7395:
1039 if (dvb_attach(ix2505v_attach , adap->fe, &lme_tuner,
1040 &adap->dev->i2c_adap))
1041 ret = st->tuner_config;
1042 break;
1043 case TUNER_S0194:
1044 if (dvb_attach(dvb_pll_attach , adap->fe, 0xc0,
1045 &adap->dev->i2c_adap, DVB_PLL_OPERA1))
1046 ret = st->tuner_config;
1047 break;
1048 default:
1049 break;
1050 }
1051
1052 if (ret)
1053 info("TUN Found %s tuner", tun_msg[ret]);
1054 else {
1055 info("TUN No tuner found --- reseting device");
1056 lme_coldreset(adap->dev->udev);
1057 return -ENODEV;
1058 }
1059
1060 /* Start the Interrupt*/
1061 ret = lme2510_int_read(adap);
1062 if (ret < 0) {
1063 info("INT Unable to start Interrupt Service");
1064 return -ENODEV;
1065 }
1066
1067 return ret;
1068}
1069
1070static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
1071{
1072 struct lme2510_state *st = d->priv;
1073 static u8 lnb_on[] = LNB_ON;
1074 static u8 lnb_off[] = LNB_OFF;
1075 static u8 rbuf[1];
1076 int ret, len = 3, rlen = 1;
1077
1078 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
1079 return -EAGAIN;
1080
1081 if (onoff)
1082 ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
1083 else
1084 ret = lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
1085
1086 st->i2c_talk_onoff = 1;
1087
1088 mutex_unlock(&d->i2c_mutex);
1089
1090 return ret;
1091}
1092
1093/* DVB USB Driver stuff */
1094static struct dvb_usb_device_properties lme2510_properties;
1095static struct dvb_usb_device_properties lme2510c_properties;
1096
1097static int lme2510_probe(struct usb_interface *intf,
1098 const struct usb_device_id *id)
1099{
1100 struct usb_device *udev = interface_to_usbdev(intf);
1101 int ret = 0;
1102
1103 usb_reset_configuration(udev);
1104
1105 usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 1);
1106
1107 if (udev->speed != USB_SPEED_HIGH) {
1108 ret = usb_reset_device(udev);
1109 info("DEV Failed to connect in HIGH SPEED mode");
1110 return -ENODEV;
1111 }
1112
1113 if (lme2510_return_status(udev) == 0x44) {
1114 lme_firmware_switch(udev, 0);
1115 return -ENODEV;
1116 }
1117
1118 if (0 == dvb_usb_device_init(intf, &lme2510_properties,
1119 THIS_MODULE, NULL, adapter_nr)) {
1120 info("DEV registering device driver");
1121 return 0;
1122 }
1123 if (0 == dvb_usb_device_init(intf, &lme2510c_properties,
1124 THIS_MODULE, NULL, adapter_nr)) {
1125 info("DEV registering device driver");
1126 return 0;
1127 }
1128
1129 info("DEV lme2510 Error");
1130 return -ENODEV;
1131
1132}
1133
1134static struct usb_device_id lme2510_table[] = {
1135 { USB_DEVICE(0x3344, 0x1122) }, /* LME2510 */
1136 { USB_DEVICE(0x3344, 0x1120) }, /* LME2510C */
1137 {} /* Terminating entry */
1138};
1139
1140MODULE_DEVICE_TABLE(usb, lme2510_table);
1141
1142static struct dvb_usb_device_properties lme2510_properties = {
1143 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1144 .size_of_priv = sizeof(struct lme2510_state),
1145 .num_adapters = 1,
1146 .adapter = {
1147 {
1148 .caps = DVB_USB_ADAP_HAS_PID_FILTER|
1149 DVB_USB_ADAP_NEED_PID_FILTERING|
1150 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1151 .streaming_ctrl = lme2510_streaming_ctrl,
1152 .pid_filter_count = 15,
1153 .pid_filter = lme2510_pid_filter,
1154 .pid_filter_ctrl = lme2510_pid_filter_ctrl,
1155 .frontend_attach = dm04_lme2510_frontend_attach,
1156 .tuner_attach = dm04_lme2510_tuner,
1157 /* parameter for the MPEG2-data transfer */
1158 .stream = {
1159 .type = USB_BULK,
1160 .count = 10,
1161 .endpoint = 0x06,
1162 .u = {
1163 .bulk = {
1164 .buffersize = 4096,
1165
1166 }
1167 }
1168 }
1169 }
1170 },
1171 .rc.core = {
1172 .protocol = RC_TYPE_NEC,
1173 .module_name = "LME2510 Remote Control",
1174 .allowed_protos = RC_TYPE_NEC,
1175 .rc_codes = RC_MAP_LME2510,
1176 },
1177 .power_ctrl = lme2510_powerup,
1178 .identify_state = lme2510_identify_state,
1179 .i2c_algo = &lme2510_i2c_algo,
1180 .generic_bulk_ctrl_endpoint = 0,
1181 .num_device_descs = 1,
1182 .devices = {
1183 { "DM04_LME2510_DVB-S",
1184 { &lme2510_table[0], NULL },
1185 },
1186
1187 }
1188};
1189
1190static struct dvb_usb_device_properties lme2510c_properties = {
1191 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1192 .size_of_priv = sizeof(struct lme2510_state),
1193 .num_adapters = 1,
1194 .adapter = {
1195 {
1196 .caps = DVB_USB_ADAP_HAS_PID_FILTER|
1197 DVB_USB_ADAP_NEED_PID_FILTERING|
1198 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1199 .streaming_ctrl = lme2510_streaming_ctrl,
1200 .pid_filter_count = 15,
1201 .pid_filter = lme2510_pid_filter,
1202 .pid_filter_ctrl = lme2510_pid_filter_ctrl,
1203 .frontend_attach = dm04_lme2510_frontend_attach,
1204 .tuner_attach = dm04_lme2510_tuner,
1205 /* parameter for the MPEG2-data transfer */
1206 .stream = {
1207 .type = USB_BULK,
1208 .count = 10,
1209 .endpoint = 0x8,
1210 .u = {
1211 .bulk = {
1212 .buffersize = 4096,
1213
1214 }
1215 }
1216 }
1217 }
1218 },
1219 .rc.core = {
1220 .protocol = RC_TYPE_NEC,
1221 .module_name = "LME2510 Remote Control",
1222 .allowed_protos = RC_TYPE_NEC,
1223 .rc_codes = RC_MAP_LME2510,
1224 },
1225 .power_ctrl = lme2510_powerup,
1226 .identify_state = lme2510_identify_state,
1227 .i2c_algo = &lme2510_i2c_algo,
1228 .generic_bulk_ctrl_endpoint = 0,
1229 .num_device_descs = 1,
1230 .devices = {
1231 { "DM04_LME2510C_DVB-S",
1232 { &lme2510_table[1], NULL },
1233 },
1234 }
1235};
1236
1237static void *lme2510_exit_int(struct dvb_usb_device *d)
1238{
1239 struct lme2510_state *st = d->priv;
1240 struct dvb_usb_adapter *adap = &d->adapter[0];
1241 void *buffer = NULL;
1242
1243 if (adap != NULL) {
1244 lme2510_kill_urb(&adap->stream);
1245 adap->feedcount = 0;
1246 }
1247
1248 if (st->usb_buffer != NULL) {
1249 st->i2c_talk_onoff = 1;
1250 st->signal_lock = 0;
1251 st->signal_level = 0;
1252 st->signal_sn = 0;
1253 buffer = st->usb_buffer;
1254 }
1255
1256 if (st->lme_urb != NULL) {
1257 usb_kill_urb(st->lme_urb);
1258 usb_free_coherent(d->udev, 5000, st->buffer,
1259 st->lme_urb->transfer_dma);
1260 info("Interrupt Service Stopped");
1261 }
1262
1263 return buffer;
1264}
1265
1266static void lme2510_exit(struct usb_interface *intf)
1267{
1268 struct dvb_usb_device *d = usb_get_intfdata(intf);
1269 void *usb_buffer;
1270
1271 if (d != NULL) {
1272 usb_buffer = lme2510_exit_int(d);
1273 dvb_usb_device_exit(intf);
1274 if (usb_buffer != NULL)
1275 kfree(usb_buffer);
1276 }
1277}
1278
1279static struct usb_driver lme2510_driver = {
1280 .name = "LME2510C_DVB-S",
1281 .probe = lme2510_probe,
1282 .disconnect = lme2510_exit,
1283 .id_table = lme2510_table,
1284};
1285
1286/* module stuff */
1287static int __init lme2510_module_init(void)
1288{
1289 int result = usb_register(&lme2510_driver);
1290 if (result) {
1291 err("usb_register failed. Error number %d", result);
1292 return result;
1293 }
1294
1295 return 0;
1296}
1297
1298static void __exit lme2510_module_exit(void)
1299{
1300 /* deregister this driver from the USB subsystem */
1301 usb_deregister(&lme2510_driver);
1302}
1303
1304module_init(lme2510_module_init);
1305module_exit(lme2510_module_exit);
1306
1307MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
1308MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
1309MODULE_VERSION("1.88");
1310MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.h b/drivers/media/dvb/dvb-usb/lmedm04.h
new file mode 100644
index 00000000000..ab21e2ef53f
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/lmedm04.h
@@ -0,0 +1,174 @@
1/* DVB USB compliant linux driver for
2 *
3 * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395
4 * LME2510C + LG TDQY-P001F
5 * LME2510 + LG TDQY-P001F
6 *
7 * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
8 * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
9 *
10 * MVB001F (LME2510+LGTDQT-P001F)
11 * LG TDQY - P001F =(TDA8263 + TDA10086H)
12 *
13 * MVB0001F (LME2510C+LGTDQT-P001F)
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the Free
17 * Software Foundation, version 2.
18 * *
19 * see Documentation/dvb/README.dvb-usb for more information
20 */
21#ifndef _DVB_USB_LME2510_H_
22#define _DVB_USB_LME2510_H_
23
24/* Streamer & PID
25 *
26 * Note: These commands do not actually stop the streaming
27 * but form some kind of packet filtering/stream count
28 * or tuning related functions.
29 * 06 XX
30 * offset 1 = 00 Enable Streaming
31 *
32 *
33 * PID
34 * 03 XX XX ----> reg number ---> setting....20 XX
35 * offset 1 = length
36 * offset 2 = start of data
37 * end byte -1 = 20
38 * end byte = clear pid always a0, other wise 9c, 9a ??
39 *
40*/
41#define LME_ST_ON_W {0x06, 0x00}
42#define LME_CLEAR_PID {0x03, 0x02, 0x20, 0xa0}
43#define LME_ZERO_PID {0x03, 0x06, 0x00, 0x00, 0x01, 0x00, 0x20, 0x9c}
44
45/* LNB Voltage
46 * 07 XX XX
47 * offset 1 = 01
48 * offset 2 = 00=Voltage low 01=Voltage high
49 *
50 * LNB Power
51 * 03 01 XX
52 * offset 2 = 00=ON 01=OFF
53 */
54
55#define LME_VOLTAGE_L {0x07, 0x01, 0x00}
56#define LME_VOLTAGE_H {0x07, 0x01, 0x01}
57#define LNB_ON {0x3a, 0x01, 0x00}
58#define LNB_OFF {0x3a, 0x01, 0x01}
59
60/* Initial stv0288 settings for 7395 Frontend */
61static u8 s7395_inittab[] = {
62 0x01, 0x15,
63 0x02, 0x20,
64 0x03, 0xa0,
65 0x04, 0xa0,
66 0x05, 0x12,
67 0x06, 0x00,
68 0x09, 0x00,
69 0x0a, 0x04,
70 0x0b, 0x00,
71 0x0c, 0x00,
72 0x0d, 0x00,
73 0x0e, 0xc1,
74 0x0f, 0x54,
75 0x11, 0x7a,
76 0x12, 0x03,
77 0x13, 0x48,
78 0x14, 0x84,
79 0x15, 0xc5,
80 0x16, 0xb8,
81 0x17, 0x9c,
82 0x18, 0x00,
83 0x19, 0xa6,
84 0x1a, 0x88,
85 0x1b, 0x8f,
86 0x1c, 0xf0,
87 0x20, 0x0b,
88 0x21, 0x54,
89 0x22, 0xff,
90 0x23, 0x01,
91 0x28, 0x46,
92 0x29, 0x66,
93 0x2a, 0x90,
94 0x2b, 0xfa,
95 0x2c, 0xd9,
96 0x30, 0x0,
97 0x31, 0x1e,
98 0x32, 0x14,
99 0x33, 0x0f,
100 0x34, 0x09,
101 0x35, 0x0c,
102 0x36, 0x05,
103 0x37, 0x2f,
104 0x38, 0x16,
105 0x39, 0xbd,
106 0x3a, 0x0,
107 0x3b, 0x13,
108 0x3c, 0x11,
109 0x3d, 0x30,
110 0x40, 0x63,
111 0x41, 0x04,
112 0x42, 0x20,
113 0x43, 0x00,
114 0x44, 0x00,
115 0x45, 0x00,
116 0x46, 0x00,
117 0x47, 0x00,
118 0x4a, 0x00,
119 0x50, 0x10,
120 0x51, 0x36,
121 0x52, 0x21,
122 0x53, 0x94,
123 0x54, 0xb2,
124 0x55, 0x29,
125 0x56, 0x64,
126 0x57, 0x2b,
127 0x58, 0x54,
128 0x59, 0x86,
129 0x5a, 0x00,
130 0x5b, 0x9b,
131 0x5c, 0x08,
132 0x5d, 0x7f,
133 0x5e, 0xff,
134 0x5f, 0x8d,
135 0x70, 0x0,
136 0x71, 0x0,
137 0x72, 0x0,
138 0x74, 0x0,
139 0x75, 0x0,
140 0x76, 0x0,
141 0x81, 0x0,
142 0x82, 0x3f,
143 0x83, 0x3f,
144 0x84, 0x0,
145 0x85, 0x0,
146 0x88, 0x0,
147 0x89, 0x0,
148 0x8a, 0x0,
149 0x8b, 0x0,
150 0x8c, 0x0,
151 0x90, 0x0,
152 0x91, 0x0,
153 0x92, 0x0,
154 0x93, 0x0,
155 0x94, 0x1c,
156 0x97, 0x0,
157 0xa0, 0x48,
158 0xa1, 0x0,
159 0xb0, 0xb8,
160 0xb1, 0x3a,
161 0xb2, 0x10,
162 0xb3, 0x82,
163 0xb4, 0x80,
164 0xb5, 0x82,
165 0xb6, 0x82,
166 0xb7, 0x82,
167 0xb8, 0x20,
168 0xb9, 0x0,
169 0xf0, 0x0,
170 0xf1, 0x0,
171 0xf2, 0xc0,
172 0xff, 0xff,
173};
174#endif
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
new file mode 100644
index 00000000000..9456792f219
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/m920x.c
@@ -0,0 +1,1093 @@
1/* DVB USB compliant linux driver for MSI Mega Sky 580 DVB-T USB2.0 receiver
2 *
3 * Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.org)
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation, version 2.
8 *
9 * see Documentation/dvb/README.dvb-usb for more information
10 */
11
12#include "m920x.h"
13
14#include "mt352.h"
15#include "mt352_priv.h"
16#include "qt1010.h"
17#include "tda1004x.h"
18#include "tda827x.h"
19
20#include <media/tuner.h>
21#include "tuner-simple.h"
22#include <asm/unaligned.h>
23
24/* debug */
25static int dvb_usb_m920x_debug;
26module_param_named(debug,dvb_usb_m920x_debug, int, 0644);
27MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
28
29DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
30
31static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid);
32
33static inline int m920x_read(struct usb_device *udev, u8 request, u16 value,
34 u16 index, void *data, int size)
35{
36 int ret;
37
38 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
39 request, USB_TYPE_VENDOR | USB_DIR_IN,
40 value, index, data, size, 2000);
41 if (ret < 0) {
42 printk(KERN_INFO "m920x_read = error: %d\n", ret);
43 return ret;
44 }
45
46 if (ret != size) {
47 deb("m920x_read = no data\n");
48 return -EIO;
49 }
50
51 return 0;
52}
53
54static inline int m920x_write(struct usb_device *udev, u8 request,
55 u16 value, u16 index)
56{
57 int ret;
58
59 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
60 request, USB_TYPE_VENDOR | USB_DIR_OUT,
61 value, index, NULL, 0, 2000);
62
63 return ret;
64}
65
66static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq)
67{
68 int ret = 0, i, epi, flags = 0;
69 int adap_enabled[M9206_MAX_ADAPTERS] = { 0 };
70
71 /* Remote controller init. */
72 if (d->props.rc.legacy.rc_query) {
73 deb("Initialising remote control\n");
74 while (rc_seq->address) {
75 if ((ret = m920x_write(d->udev, M9206_CORE,
76 rc_seq->data,
77 rc_seq->address)) != 0) {
78 deb("Initialising remote control failed\n");
79 return ret;
80 }
81
82 rc_seq++;
83 }
84
85 deb("Initialising remote control success\n");
86 }
87
88 for (i = 0; i < d->props.num_adapters; i++)
89 flags |= d->adapter[i].props.caps;
90
91 /* Some devices(Dposh) might crash if we attempt touch at all. */
92 if (flags & DVB_USB_ADAP_HAS_PID_FILTER) {
93 for (i = 0; i < d->props.num_adapters; i++) {
94 epi = d->adapter[i].props.stream.endpoint - 0x81;
95
96 if (epi < 0 || epi >= M9206_MAX_ADAPTERS) {
97 printk(KERN_INFO "m920x: Unexpected adapter endpoint!\n");
98 return -EINVAL;
99 }
100
101 adap_enabled[epi] = 1;
102 }
103
104 for (i = 0; i < M9206_MAX_ADAPTERS; i++) {
105 if (adap_enabled[i])
106 continue;
107
108 if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x0)) != 0)
109 return ret;
110
111 if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x02f5)) != 0)
112 return ret;
113 }
114 }
115
116 return ret;
117}
118
119static int m920x_init_ep(struct usb_interface *intf)
120{
121 struct usb_device *udev = interface_to_usbdev(intf);
122 struct usb_host_interface *alt;
123
124 if ((alt = usb_altnum_to_altsetting(intf, 1)) == NULL) {
125 deb("No alt found!\n");
126 return -ENODEV;
127 }
128
129 return usb_set_interface(udev, alt->desc.bInterfaceNumber,
130 alt->desc.bAlternateSetting);
131}
132
133static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
134{
135 struct m920x_state *m = d->priv;
136 int i, ret = 0;
137 u8 *rc_state;
138
139 rc_state = kmalloc(2, GFP_KERNEL);
140 if (!rc_state)
141 return -ENOMEM;
142
143 if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
144 goto out;
145
146 if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
147 goto out;
148
149 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
150 if (rc5_data(&d->props.rc.legacy.rc_map_table[i]) == rc_state[1]) {
151 *event = d->props.rc.legacy.rc_map_table[i].keycode;
152
153 switch(rc_state[0]) {
154 case 0x80:
155 *state = REMOTE_NO_KEY_PRESSED;
156 goto out;
157
158 case 0x88: /* framing error or "invalid code" */
159 case 0x99:
160 case 0xc0:
161 case 0xd8:
162 *state = REMOTE_NO_KEY_PRESSED;
163 m->rep_count = 0;
164 goto out;
165
166 case 0x93:
167 case 0x92:
168 case 0x83: /* pinnacle PCTV310e */
169 case 0x82:
170 m->rep_count = 0;
171 *state = REMOTE_KEY_PRESSED;
172 goto out;
173
174 case 0x91:
175 case 0x81: /* pinnacle PCTV310e */
176 /* prevent immediate auto-repeat */
177 if (++m->rep_count > 2)
178 *state = REMOTE_KEY_REPEAT;
179 else
180 *state = REMOTE_NO_KEY_PRESSED;
181 goto out;
182
183 default:
184 deb("Unexpected rc state %02x\n", rc_state[0]);
185 *state = REMOTE_NO_KEY_PRESSED;
186 goto out;
187 }
188 }
189
190 if (rc_state[1] != 0)
191 deb("Unknown rc key %02x\n", rc_state[1]);
192
193 *state = REMOTE_NO_KEY_PRESSED;
194
195 out:
196 kfree(rc_state);
197 return ret;
198}
199
200/* I2C */
201static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
202{
203 struct dvb_usb_device *d = i2c_get_adapdata(adap);
204 int i, j;
205 int ret = 0;
206
207 if (!num)
208 return -EINVAL;
209
210 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
211 return -EAGAIN;
212
213 for (i = 0; i < num; i++) {
214 if (msg[i].flags & (I2C_M_NO_RD_ACK | I2C_M_IGNORE_NAK | I2C_M_TEN) || msg[i].len == 0) {
215 /* For a 0 byte message, I think sending the address
216 * to index 0x80|0x40 would be the correct thing to
217 * do. However, zero byte messages are only used for
218 * probing, and since we don't know how to get the
219 * slave's ack, we can't probe. */
220 ret = -ENOTSUPP;
221 goto unlock;
222 }
223 /* Send START & address/RW bit */
224 if (!(msg[i].flags & I2C_M_NOSTART)) {
225 if ((ret = m920x_write(d->udev, M9206_I2C,
226 (msg[i].addr << 1) |
227 (msg[i].flags & I2C_M_RD ? 0x01 : 0), 0x80)) != 0)
228 goto unlock;
229 /* Should check for ack here, if we knew how. */
230 }
231 if (msg[i].flags & I2C_M_RD) {
232 for (j = 0; j < msg[i].len; j++) {
233 /* Last byte of transaction?
234 * Send STOP, otherwise send ACK. */
235 int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x01;
236
237 if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
238 0x20 | stop,
239 &msg[i].buf[j], 1)) != 0)
240 goto unlock;
241 }
242 } else {
243 for (j = 0; j < msg[i].len; j++) {
244 /* Last byte of transaction? Then send STOP. */
245 int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x00;
246
247 if ((ret = m920x_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0)
248 goto unlock;
249 /* Should check for ack here too. */
250 }
251 }
252 }
253 ret = num;
254
255 unlock:
256 mutex_unlock(&d->i2c_mutex);
257
258 return ret;
259}
260
261static u32 m920x_i2c_func(struct i2c_adapter *adapter)
262{
263 return I2C_FUNC_I2C;
264}
265
266static struct i2c_algorithm m920x_i2c_algo = {
267 .master_xfer = m920x_i2c_xfer,
268 .functionality = m920x_i2c_func,
269};
270
271/* pid filter */
272static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid)
273{
274 int ret = 0;
275
276 if (pid >= 0x8000)
277 return -EINVAL;
278
279 pid |= 0x8000;
280
281 if ((ret = m920x_write(d->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
282 return ret;
283
284 if ((ret = m920x_write(d->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
285 return ret;
286
287 return ret;
288}
289
290static int m920x_update_filters(struct dvb_usb_adapter *adap)
291{
292 struct m920x_state *m = adap->dev->priv;
293 int enabled = m->filtering_enabled[adap->id];
294 int i, ret = 0, filter = 0;
295 int ep = adap->props.stream.endpoint;
296
297 for (i = 0; i < M9206_MAX_FILTERS; i++)
298 if (m->filters[adap->id][i] == 8192)
299 enabled = 0;
300
301 /* Disable all filters */
302 if ((ret = m920x_set_filter(adap->dev, ep, 1, enabled)) != 0)
303 return ret;
304
305 for (i = 0; i < M9206_MAX_FILTERS; i++)
306 if ((ret = m920x_set_filter(adap->dev, ep, i + 2, 0)) != 0)
307 return ret;
308
309 /* Set */
310 if (enabled) {
311 for (i = 0; i < M9206_MAX_FILTERS; i++) {
312 if (m->filters[adap->id][i] == 0)
313 continue;
314
315 if ((ret = m920x_set_filter(adap->dev, ep, filter + 2, m->filters[adap->id][i])) != 0)
316 return ret;
317
318 filter++;
319 }
320 }
321
322 return ret;
323}
324
325static int m920x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
326{
327 struct m920x_state *m = adap->dev->priv;
328
329 m->filtering_enabled[adap->id] = onoff ? 1 : 0;
330
331 return m920x_update_filters(adap);
332}
333
334static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
335{
336 struct m920x_state *m = adap->dev->priv;
337
338 m->filters[adap->id][index] = onoff ? pid : 0;
339
340 return m920x_update_filters(adap);
341}
342
343static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw)
344{
345 u16 value, index, size;
346 u8 *read, *buff;
347 int i, pass, ret = 0;
348
349 buff = kmalloc(65536, GFP_KERNEL);
350 if (buff == NULL)
351 return -ENOMEM;
352
353 read = kmalloc(4, GFP_KERNEL);
354 if (!read) {
355 kfree(buff);
356 return -ENOMEM;
357 }
358
359 if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
360 goto done;
361 deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
362
363 if ((ret = m920x_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0)
364 goto done;
365 deb("%x\n", read[0]);
366
367 for (pass = 0; pass < 2; pass++) {
368 for (i = 0; i + (sizeof(u16) * 3) < fw->size;) {
369 value = get_unaligned_le16(fw->data + i);
370 i += sizeof(u16);
371
372 index = get_unaligned_le16(fw->data + i);
373 i += sizeof(u16);
374
375 size = get_unaligned_le16(fw->data + i);
376 i += sizeof(u16);
377
378 if (pass == 1) {
379 /* Will stall if using fw->data ... */
380 memcpy(buff, fw->data + i, size);
381
382 ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
383 M9206_FW,
384 USB_TYPE_VENDOR | USB_DIR_OUT,
385 value, index, buff, size, 20);
386 if (ret != size) {
387 deb("error while uploading fw!\n");
388 ret = -EIO;
389 goto done;
390 }
391 msleep(3);
392 }
393 i += size;
394 }
395 if (i != fw->size) {
396 deb("bad firmware file!\n");
397 ret = -EINVAL;
398 goto done;
399 }
400 }
401
402 msleep(36);
403
404 /* m920x will disconnect itself from the bus after this. */
405 (void) m920x_write(udev, M9206_CORE, 0x01, M9206_FW_GO);
406 deb("firmware uploaded!\n");
407
408 done:
409 kfree(read);
410 kfree(buff);
411
412 return ret;
413}
414
415/* Callbacks for DVB USB */
416static int m920x_identify_state(struct usb_device *udev,
417 struct dvb_usb_device_properties *props,
418 struct dvb_usb_device_description **desc,
419 int *cold)
420{
421 struct usb_host_interface *alt;
422
423 alt = usb_altnum_to_altsetting(usb_ifnum_to_if(udev, 0), 1);
424 *cold = (alt == NULL) ? 1 : 0;
425
426 return 0;
427}
428
429/* demod configurations */
430static int m920x_mt352_demod_init(struct dvb_frontend *fe)
431{
432 int ret;
433 u8 config[] = { CONFIG, 0x3d };
434 u8 clock[] = { CLOCK_CTL, 0x30 };
435 u8 reset[] = { RESET, 0x80 };
436 u8 adc_ctl[] = { ADC_CTL_1, 0x40 };
437 u8 agc[] = { AGC_TARGET, 0x1c, 0x20 };
438 u8 sec_agc[] = { 0x69, 0x00, 0xff, 0xff, 0x40, 0xff, 0x00, 0x40, 0x40 };
439 u8 unk1[] = { 0x93, 0x1a };
440 u8 unk2[] = { 0xb5, 0x7a };
441
442 deb("Demod init!\n");
443
444 if ((ret = mt352_write(fe, config, ARRAY_SIZE(config))) != 0)
445 return ret;
446 if ((ret = mt352_write(fe, clock, ARRAY_SIZE(clock))) != 0)
447 return ret;
448 if ((ret = mt352_write(fe, reset, ARRAY_SIZE(reset))) != 0)
449 return ret;
450 if ((ret = mt352_write(fe, adc_ctl, ARRAY_SIZE(adc_ctl))) != 0)
451 return ret;
452 if ((ret = mt352_write(fe, agc, ARRAY_SIZE(agc))) != 0)
453 return ret;
454 if ((ret = mt352_write(fe, sec_agc, ARRAY_SIZE(sec_agc))) != 0)
455 return ret;
456 if ((ret = mt352_write(fe, unk1, ARRAY_SIZE(unk1))) != 0)
457 return ret;
458 if ((ret = mt352_write(fe, unk2, ARRAY_SIZE(unk2))) != 0)
459 return ret;
460
461 return 0;
462}
463
464static struct mt352_config m920x_mt352_config = {
465 .demod_address = 0x0f,
466 .no_tuner = 1,
467 .demod_init = m920x_mt352_demod_init,
468};
469
470static struct tda1004x_config m920x_tda10046_08_config = {
471 .demod_address = 0x08,
472 .invert = 0,
473 .invert_oclk = 0,
474 .ts_mode = TDA10046_TS_SERIAL,
475 .xtal_freq = TDA10046_XTAL_16M,
476 .if_freq = TDA10046_FREQ_045,
477 .agc_config = TDA10046_AGC_TDA827X,
478 .gpio_config = TDA10046_GPTRI,
479 .request_firmware = NULL,
480};
481
482static struct tda1004x_config m920x_tda10046_0b_config = {
483 .demod_address = 0x0b,
484 .invert = 0,
485 .invert_oclk = 0,
486 .ts_mode = TDA10046_TS_SERIAL,
487 .xtal_freq = TDA10046_XTAL_16M,
488 .if_freq = TDA10046_FREQ_045,
489 .agc_config = TDA10046_AGC_TDA827X,
490 .gpio_config = TDA10046_GPTRI,
491 .request_firmware = NULL, /* uses firmware EEPROM */
492};
493
494/* tuner configurations */
495static struct qt1010_config m920x_qt1010_config = {
496 .i2c_address = 0x62
497};
498
499/* Callbacks for DVB USB */
500static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap)
501{
502 deb("%s\n",__func__);
503
504 if ((adap->fe = dvb_attach(mt352_attach,
505 &m920x_mt352_config,
506 &adap->dev->i2c_adap)) == NULL)
507 return -EIO;
508
509 return 0;
510}
511
512static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap)
513{
514 deb("%s\n",__func__);
515
516 if ((adap->fe = dvb_attach(tda10046_attach,
517 &m920x_tda10046_08_config,
518 &adap->dev->i2c_adap)) == NULL)
519 return -EIO;
520
521 return 0;
522}
523
524static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap)
525{
526 deb("%s\n",__func__);
527
528 if ((adap->fe = dvb_attach(tda10046_attach,
529 &m920x_tda10046_0b_config,
530 &adap->dev->i2c_adap)) == NULL)
531 return -EIO;
532
533 return 0;
534}
535
536static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
537{
538 deb("%s\n",__func__);
539
540 if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL)
541 return -ENODEV;
542
543 return 0;
544}
545
546static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap)
547{
548 deb("%s\n",__func__);
549
550 if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL)
551 return -ENODEV;
552
553 return 0;
554}
555
556static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap)
557{
558 deb("%s\n",__func__);
559
560 if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL)
561 return -ENODEV;
562
563 return 0;
564}
565
566static int m920x_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
567{
568 dvb_attach(simple_tuner_attach, adap->fe,
569 &adap->dev->i2c_adap, 0x61,
570 TUNER_PHILIPS_FMD1216ME_MK3);
571 return 0;
572}
573
574/* device-specific initialization */
575static struct m920x_inits megasky_rc_init [] = {
576 { M9206_RC_INIT2, 0xa8 },
577 { M9206_RC_INIT1, 0x51 },
578 { } /* terminating entry */
579};
580
581static struct m920x_inits tvwalkertwin_rc_init [] = {
582 { M9206_RC_INIT2, 0x00 },
583 { M9206_RC_INIT1, 0xef },
584 { 0xff28, 0x00 },
585 { 0xff23, 0x00 },
586 { 0xff21, 0x30 },
587 { } /* terminating entry */
588};
589
590static struct m920x_inits pinnacle310e_init[] = {
591 /* without these the tuner don't work */
592 { 0xff20, 0x9b },
593 { 0xff22, 0x70 },
594
595 /* rc settings */
596 { 0xff50, 0x80 },
597 { M9206_RC_INIT1, 0x00 },
598 { M9206_RC_INIT2, 0xff },
599 { } /* terminating entry */
600};
601
602/* ir keymaps */
603static struct rc_map_table rc_map_megasky_table[] = {
604 { 0x0012, KEY_POWER },
605 { 0x001e, KEY_CYCLEWINDOWS }, /* min/max */
606 { 0x0002, KEY_CHANNELUP },
607 { 0x0005, KEY_CHANNELDOWN },
608 { 0x0003, KEY_VOLUMEUP },
609 { 0x0006, KEY_VOLUMEDOWN },
610 { 0x0004, KEY_MUTE },
611 { 0x0007, KEY_OK }, /* TS */
612 { 0x0008, KEY_STOP },
613 { 0x0009, KEY_MENU }, /* swap */
614 { 0x000a, KEY_REWIND },
615 { 0x001b, KEY_PAUSE },
616 { 0x001f, KEY_FASTFORWARD },
617 { 0x000c, KEY_RECORD },
618 { 0x000d, KEY_CAMERA }, /* screenshot */
619 { 0x000e, KEY_COFFEE }, /* "MTS" */
620};
621
622static struct rc_map_table rc_map_tvwalkertwin_table[] = {
623 { 0x0001, KEY_ZOOM }, /* Full Screen */
624 { 0x0002, KEY_CAMERA }, /* snapshot */
625 { 0x0003, KEY_MUTE },
626 { 0x0004, KEY_REWIND },
627 { 0x0005, KEY_PLAYPAUSE }, /* Play/Pause */
628 { 0x0006, KEY_FASTFORWARD },
629 { 0x0007, KEY_RECORD },
630 { 0x0008, KEY_STOP },
631 { 0x0009, KEY_TIME }, /* Timeshift */
632 { 0x000c, KEY_COFFEE }, /* Recall */
633 { 0x000e, KEY_CHANNELUP },
634 { 0x0012, KEY_POWER },
635 { 0x0015, KEY_MENU }, /* source */
636 { 0x0018, KEY_CYCLEWINDOWS }, /* TWIN PIP */
637 { 0x001a, KEY_CHANNELDOWN },
638 { 0x001b, KEY_VOLUMEDOWN },
639 { 0x001e, KEY_VOLUMEUP },
640};
641
642static struct rc_map_table rc_map_pinnacle310e_table[] = {
643 { 0x16, KEY_POWER },
644 { 0x17, KEY_FAVORITES },
645 { 0x0f, KEY_TEXT },
646 { 0x48, KEY_PROGRAM }, /* preview */
647 { 0x1c, KEY_EPG },
648 { 0x04, KEY_LIST }, /* record list */
649 { 0x03, KEY_1 },
650 { 0x01, KEY_2 },
651 { 0x06, KEY_3 },
652 { 0x09, KEY_4 },
653 { 0x1d, KEY_5 },
654 { 0x1f, KEY_6 },
655 { 0x0d, KEY_7 },
656 { 0x19, KEY_8 },
657 { 0x1b, KEY_9 },
658 { 0x15, KEY_0 },
659 { 0x0c, KEY_CANCEL },
660 { 0x4a, KEY_CLEAR },
661 { 0x13, KEY_BACK },
662 { 0x00, KEY_TAB },
663 { 0x4b, KEY_UP },
664 { 0x4e, KEY_LEFT },
665 { 0x52, KEY_RIGHT },
666 { 0x51, KEY_DOWN },
667 { 0x4f, KEY_ENTER }, /* could also be KEY_OK */
668 { 0x1e, KEY_VOLUMEUP },
669 { 0x0a, KEY_VOLUMEDOWN },
670 { 0x05, KEY_CHANNELUP },
671 { 0x02, KEY_CHANNELDOWN },
672 { 0x11, KEY_RECORD },
673 { 0x14, KEY_PLAY },
674 { 0x4c, KEY_PAUSE },
675 { 0x1a, KEY_STOP },
676 { 0x40, KEY_REWIND },
677 { 0x12, KEY_FASTFORWARD },
678 { 0x41, KEY_PREVIOUSSONG }, /* Replay */
679 { 0x42, KEY_NEXTSONG }, /* Skip */
680 { 0x54, KEY_CAMERA }, /* Capture */
681/* { 0x50, KEY_SAP }, */ /* Sap */
682 { 0x47, KEY_CYCLEWINDOWS }, /* Pip */
683 { 0x4d, KEY_SCREEN }, /* FullScreen */
684 { 0x08, KEY_SUBTITLE },
685 { 0x0e, KEY_MUTE },
686/* { 0x49, KEY_LR }, */ /* L/R */
687 { 0x07, KEY_SLEEP }, /* Hibernate */
688 { 0x08, KEY_VIDEO }, /* A/V */
689 { 0x0e, KEY_MENU }, /* Recall */
690 { 0x45, KEY_ZOOMIN },
691 { 0x46, KEY_ZOOMOUT },
692 { 0x18, KEY_RED }, /* Red */
693 { 0x53, KEY_GREEN }, /* Green */
694 { 0x5e, KEY_YELLOW }, /* Yellow */
695 { 0x5f, KEY_BLUE }, /* Blue */
696};
697
698/* DVB USB Driver stuff */
699static struct dvb_usb_device_properties megasky_properties;
700static struct dvb_usb_device_properties digivox_mini_ii_properties;
701static struct dvb_usb_device_properties tvwalkertwin_properties;
702static struct dvb_usb_device_properties dposh_properties;
703static struct dvb_usb_device_properties pinnacle_pctv310e_properties;
704
705static int m920x_probe(struct usb_interface *intf,
706 const struct usb_device_id *id)
707{
708 struct dvb_usb_device *d = NULL;
709 int ret;
710 struct m920x_inits *rc_init_seq = NULL;
711 int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber;
712
713 deb("Probing for m920x device at interface %d\n", bInterfaceNumber);
714
715 if (bInterfaceNumber == 0) {
716 /* Single-tuner device, or first interface on
717 * multi-tuner device
718 */
719
720 ret = dvb_usb_device_init(intf, &megasky_properties,
721 THIS_MODULE, &d, adapter_nr);
722 if (ret == 0) {
723 rc_init_seq = megasky_rc_init;
724 goto found;
725 }
726
727 ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties,
728 THIS_MODULE, &d, adapter_nr);
729 if (ret == 0) {
730 /* No remote control, so no rc_init_seq */
731 goto found;
732 }
733
734 /* This configures both tuners on the TV Walker Twin */
735 ret = dvb_usb_device_init(intf, &tvwalkertwin_properties,
736 THIS_MODULE, &d, adapter_nr);
737 if (ret == 0) {
738 rc_init_seq = tvwalkertwin_rc_init;
739 goto found;
740 }
741
742 ret = dvb_usb_device_init(intf, &dposh_properties,
743 THIS_MODULE, &d, adapter_nr);
744 if (ret == 0) {
745 /* Remote controller not supported yet. */
746 goto found;
747 }
748
749 ret = dvb_usb_device_init(intf, &pinnacle_pctv310e_properties,
750 THIS_MODULE, &d, adapter_nr);
751 if (ret == 0) {
752 rc_init_seq = pinnacle310e_init;
753 goto found;
754 }
755
756 return ret;
757 } else {
758 /* Another interface on a multi-tuner device */
759
760 /* The LifeView TV Walker Twin gets here, but struct
761 * tvwalkertwin_properties already configured both
762 * tuners, so there is nothing for us to do here
763 */
764 }
765
766 found:
767 if ((ret = m920x_init_ep(intf)) < 0)
768 return ret;
769
770 if (d && (ret = m920x_init(d, rc_init_seq)) != 0)
771 return ret;
772
773 return ret;
774}
775
776static struct usb_device_id m920x_table [] = {
777 { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) },
778 { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
779 USB_PID_MSI_DIGI_VOX_MINI_II) },
780 { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
781 USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD) },
782 { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
783 USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) },
784 { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) },
785 { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) },
786 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_PINNACLE_PCTV310E) },
787 { } /* Terminating entry */
788};
789MODULE_DEVICE_TABLE (usb, m920x_table);
790
791static struct dvb_usb_device_properties megasky_properties = {
792 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
793
794 .usb_ctrl = DEVICE_SPECIFIC,
795 .firmware = "dvb-usb-megasky-02.fw",
796 .download_firmware = m920x_firmware_download,
797
798 .rc.legacy = {
799 .rc_interval = 100,
800 .rc_map_table = rc_map_megasky_table,
801 .rc_map_size = ARRAY_SIZE(rc_map_megasky_table),
802 .rc_query = m920x_rc_query,
803 },
804
805 .size_of_priv = sizeof(struct m920x_state),
806
807 .identify_state = m920x_identify_state,
808 .num_adapters = 1,
809 .adapter = {{
810 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
811 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
812
813 .pid_filter_count = 8,
814 .pid_filter = m920x_pid_filter,
815 .pid_filter_ctrl = m920x_pid_filter_ctrl,
816
817 .frontend_attach = m920x_mt352_frontend_attach,
818 .tuner_attach = m920x_qt1010_tuner_attach,
819
820 .stream = {
821 .type = USB_BULK,
822 .count = 8,
823 .endpoint = 0x81,
824 .u = {
825 .bulk = {
826 .buffersize = 512,
827 }
828 }
829 },
830 }},
831 .i2c_algo = &m920x_i2c_algo,
832
833 .num_device_descs = 1,
834 .devices = {
835 { "MSI Mega Sky 580 DVB-T USB2.0",
836 { &m920x_table[0], NULL },
837 { NULL },
838 }
839 }
840};
841
842static struct dvb_usb_device_properties digivox_mini_ii_properties = {
843 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
844
845 .usb_ctrl = DEVICE_SPECIFIC,
846 .firmware = "dvb-usb-digivox-02.fw",
847 .download_firmware = m920x_firmware_download,
848
849 .size_of_priv = sizeof(struct m920x_state),
850
851 .identify_state = m920x_identify_state,
852 .num_adapters = 1,
853 .adapter = {{
854 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
855 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
856
857 .pid_filter_count = 8,
858 .pid_filter = m920x_pid_filter,
859 .pid_filter_ctrl = m920x_pid_filter_ctrl,
860
861 .frontend_attach = m920x_tda10046_08_frontend_attach,
862 .tuner_attach = m920x_tda8275_60_tuner_attach,
863
864 .stream = {
865 .type = USB_BULK,
866 .count = 8,
867 .endpoint = 0x81,
868 .u = {
869 .bulk = {
870 .buffersize = 0x4000,
871 }
872 }
873 },
874 }},
875 .i2c_algo = &m920x_i2c_algo,
876
877 .num_device_descs = 1,
878 .devices = {
879 { "MSI DIGI VOX mini II DVB-T USB2.0",
880 { &m920x_table[1], NULL },
881 { NULL },
882 },
883 }
884};
885
886/* LifeView TV Walker Twin support by Nick Andrew <nick@nick-andrew.net>
887 *
888 * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A
889 * TDA10046 #0 is located at i2c address 0x08
890 * TDA10046 #1 is located at i2c address 0x0b
891 * TDA8275A #0 is located at i2c address 0x60
892 * TDA8275A #1 is located at i2c address 0x61
893 */
894static struct dvb_usb_device_properties tvwalkertwin_properties = {
895 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
896
897 .usb_ctrl = DEVICE_SPECIFIC,
898 .firmware = "dvb-usb-tvwalkert.fw",
899 .download_firmware = m920x_firmware_download,
900
901 .rc.legacy = {
902 .rc_interval = 100,
903 .rc_map_table = rc_map_tvwalkertwin_table,
904 .rc_map_size = ARRAY_SIZE(rc_map_tvwalkertwin_table),
905 .rc_query = m920x_rc_query,
906 },
907
908 .size_of_priv = sizeof(struct m920x_state),
909
910 .identify_state = m920x_identify_state,
911 .num_adapters = 2,
912 .adapter = {{
913 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
914 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
915
916 .pid_filter_count = 8,
917 .pid_filter = m920x_pid_filter,
918 .pid_filter_ctrl = m920x_pid_filter_ctrl,
919
920 .frontend_attach = m920x_tda10046_08_frontend_attach,
921 .tuner_attach = m920x_tda8275_60_tuner_attach,
922
923 .stream = {
924 .type = USB_BULK,
925 .count = 8,
926 .endpoint = 0x81,
927 .u = {
928 .bulk = {
929 .buffersize = 512,
930 }
931 }
932 }},{
933 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
934 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
935
936 .pid_filter_count = 8,
937 .pid_filter = m920x_pid_filter,
938 .pid_filter_ctrl = m920x_pid_filter_ctrl,
939
940 .frontend_attach = m920x_tda10046_0b_frontend_attach,
941 .tuner_attach = m920x_tda8275_61_tuner_attach,
942
943 .stream = {
944 .type = USB_BULK,
945 .count = 8,
946 .endpoint = 0x82,
947 .u = {
948 .bulk = {
949 .buffersize = 512,
950 }
951 }
952 },
953 }},
954 .i2c_algo = &m920x_i2c_algo,
955
956 .num_device_descs = 1,
957 .devices = {
958 { .name = "LifeView TV Walker Twin DVB-T USB2.0",
959 .cold_ids = { &m920x_table[2], NULL },
960 .warm_ids = { &m920x_table[3], NULL },
961 },
962 }
963};
964
965static struct dvb_usb_device_properties dposh_properties = {
966 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
967
968 .usb_ctrl = DEVICE_SPECIFIC,
969 .firmware = "dvb-usb-dposh-01.fw",
970 .download_firmware = m920x_firmware_download,
971
972 .size_of_priv = sizeof(struct m920x_state),
973
974 .identify_state = m920x_identify_state,
975 .num_adapters = 1,
976 .adapter = {{
977 /* Hardware pid filters don't work with this device/firmware */
978
979 .frontend_attach = m920x_mt352_frontend_attach,
980 .tuner_attach = m920x_qt1010_tuner_attach,
981
982 .stream = {
983 .type = USB_BULK,
984 .count = 8,
985 .endpoint = 0x81,
986 .u = {
987 .bulk = {
988 .buffersize = 512,
989 }
990 }
991 },
992 }},
993 .i2c_algo = &m920x_i2c_algo,
994
995 .num_device_descs = 1,
996 .devices = {
997 { .name = "Dposh DVB-T USB2.0",
998 .cold_ids = { &m920x_table[4], NULL },
999 .warm_ids = { &m920x_table[5], NULL },
1000 },
1001 }
1002};
1003
1004static struct dvb_usb_device_properties pinnacle_pctv310e_properties = {
1005 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1006
1007 .usb_ctrl = DEVICE_SPECIFIC,
1008 .download_firmware = NULL,
1009
1010 .rc.legacy = {
1011 .rc_interval = 100,
1012 .rc_map_table = rc_map_pinnacle310e_table,
1013 .rc_map_size = ARRAY_SIZE(rc_map_pinnacle310e_table),
1014 .rc_query = m920x_rc_query,
1015 },
1016
1017 .size_of_priv = sizeof(struct m920x_state),
1018
1019 .identify_state = m920x_identify_state,
1020 .num_adapters = 1,
1021 .adapter = {{
1022 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1023 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1024
1025 .pid_filter_count = 8,
1026 .pid_filter = m920x_pid_filter,
1027 .pid_filter_ctrl = m920x_pid_filter_ctrl,
1028
1029 .frontend_attach = m920x_mt352_frontend_attach,
1030 .tuner_attach = m920x_fmd1216me_tuner_attach,
1031
1032 .stream = {
1033 .type = USB_ISOC,
1034 .count = 5,
1035 .endpoint = 0x84,
1036 .u = {
1037 .isoc = {
1038 .framesperurb = 128,
1039 .framesize = 564,
1040 .interval = 1,
1041 }
1042 }
1043 },
1044 } },
1045 .i2c_algo = &m920x_i2c_algo,
1046
1047 .num_device_descs = 1,
1048 .devices = {
1049 { "Pinnacle PCTV 310e",
1050 { &m920x_table[6], NULL },
1051 { NULL },
1052 }
1053 }
1054};
1055
1056static struct usb_driver m920x_driver = {
1057 .name = "dvb_usb_m920x",
1058 .probe = m920x_probe,
1059 .disconnect = dvb_usb_device_exit,
1060 .id_table = m920x_table,
1061};
1062
1063/* module stuff */
1064static int __init m920x_module_init(void)
1065{
1066 int ret;
1067
1068 if ((ret = usb_register(&m920x_driver))) {
1069 err("usb_register failed. Error number %d", ret);
1070 return ret;
1071 }
1072
1073 return 0;
1074}
1075
1076static void __exit m920x_module_exit(void)
1077{
1078 /* deregister this driver from the USB subsystem */
1079 usb_deregister(&m920x_driver);
1080}
1081
1082module_init (m920x_module_init);
1083module_exit (m920x_module_exit);
1084
1085MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
1086MODULE_DESCRIPTION("DVB Driver for ULI M920x");
1087MODULE_VERSION("0.1");
1088MODULE_LICENSE("GPL");
1089
1090/*
1091 * Local variables:
1092 * c-basic-offset: 8
1093 */
diff --git a/drivers/media/dvb/dvb-usb/m920x.h b/drivers/media/dvb/dvb-usb/m920x.h
new file mode 100644
index 00000000000..3c061518ffc
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/m920x.h
@@ -0,0 +1,77 @@
1#ifndef _DVB_USB_M920X_H_
2#define _DVB_USB_M920X_H_
3
4#define DVB_USB_LOG_PREFIX "m920x"
5#include "dvb-usb.h"
6
7#define deb(args...) dprintk(dvb_usb_m920x_debug,0x01,args)
8
9#define M9206_CORE 0x22
10#define M9206_RC_STATE 0xff51
11#define M9206_RC_KEY 0xff52
12#define M9206_RC_INIT1 0xff54
13#define M9206_RC_INIT2 0xff55
14#define M9206_FW_GO 0xff69
15
16#define M9206_I2C 0x23
17#define M9206_FILTER 0x25
18#define M9206_FW 0x30
19
20#define M9206_MAX_FILTERS 8
21#define M9206_MAX_ADAPTERS 4
22
23/*
24sequences found in logs:
25[index value]
260x80 write addr
27(0x00 out byte)*
280x40 out byte
29
300x80 write addr
31(0x00 out byte)*
320x80 read addr
33(0x21 in byte)*
340x60 in byte
35
36this sequence works:
370x80 read addr
38(0x21 in byte)*
390x60 in byte
40
41Guess at API of the I2C function:
42I2C operation is done one byte at a time with USB control messages. The
43index the messages is sent to is made up of a set of flags that control
44the I2C bus state:
450x80: Send START condition. After a START condition, one would normally
46 always send the 7-bit slave I2C address as the 7 MSB, followed by
47 the read/write bit as the LSB.
480x40: Send STOP condition. This should be set on the last byte of an
49 I2C transaction.
500x20: Read a byte from the slave. As opposed to writing a byte to the
51 slave. The slave will normally not produce any data unless you
52 set the R/W bit to 1 when sending the slave's address after the
53 START condition.
540x01: Respond with ACK, as opposed to a NACK. For a multi-byte read,
55 the master should send an ACK, that is pull SDA low during the 9th
56 clock cycle, after every byte but the last. This flags only makes
57 sense when bit 0x20 is set, indicating a read.
58
59What any other bits might mean, or how to get the slave's ACK/NACK
60response to a write, is unknown.
61*/
62
63struct m920x_state {
64 u16 filters[M9206_MAX_ADAPTERS][M9206_MAX_FILTERS];
65 int filtering_enabled[M9206_MAX_ADAPTERS];
66 int rep_count;
67};
68
69/* Initialisation data for the m920x
70 */
71
72struct m920x_inits {
73 u16 address;
74 u8 data;
75};
76
77#endif
diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
new file mode 100644
index 00000000000..bc350e982b7
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c
@@ -0,0 +1,250 @@
1/* DVB USB framework compliant Linux driver for the Hauppauge WinTV-NOVA-T usb2
2 * DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "dibusb.h"
13
14static int debug;
15module_param(debug, int, 0644);
16MODULE_PARM_DESC(debug, "set debugging level (1=rc,2=eeprom (|-able))." DVB_USB_DEBUG_STATUS);
17
18DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
19
20#define deb_rc(args...) dprintk(debug,0x01,args)
21#define deb_ee(args...) dprintk(debug,0x02,args)
22
23/* Hauppauge NOVA-T USB2 keys */
24static struct rc_map_table rc_map_haupp_table[] = {
25 { 0x1e00, KEY_0 },
26 { 0x1e01, KEY_1 },
27 { 0x1e02, KEY_2 },
28 { 0x1e03, KEY_3 },
29 { 0x1e04, KEY_4 },
30 { 0x1e05, KEY_5 },
31 { 0x1e06, KEY_6 },
32 { 0x1e07, KEY_7 },
33 { 0x1e08, KEY_8 },
34 { 0x1e09, KEY_9 },
35 { 0x1e0a, KEY_KPASTERISK },
36 { 0x1e0b, KEY_RED },
37 { 0x1e0c, KEY_RADIO },
38 { 0x1e0d, KEY_MENU },
39 { 0x1e0e, KEY_GRAVE }, /* # */
40 { 0x1e0f, KEY_MUTE },
41 { 0x1e10, KEY_VOLUMEUP },
42 { 0x1e11, KEY_VOLUMEDOWN },
43 { 0x1e12, KEY_CHANNEL },
44 { 0x1e14, KEY_UP },
45 { 0x1e15, KEY_DOWN },
46 { 0x1e16, KEY_LEFT },
47 { 0x1e17, KEY_RIGHT },
48 { 0x1e18, KEY_VIDEO },
49 { 0x1e19, KEY_AUDIO },
50 { 0x1e1a, KEY_IMAGES },
51 { 0x1e1b, KEY_EPG },
52 { 0x1e1c, KEY_TV },
53 { 0x1e1e, KEY_NEXT },
54 { 0x1e1f, KEY_BACK },
55 { 0x1e20, KEY_CHANNELUP },
56 { 0x1e21, KEY_CHANNELDOWN },
57 { 0x1e24, KEY_LAST }, /* Skip backwards */
58 { 0x1e25, KEY_OK },
59 { 0x1e29, KEY_BLUE},
60 { 0x1e2e, KEY_GREEN },
61 { 0x1e30, KEY_PAUSE },
62 { 0x1e32, KEY_REWIND },
63 { 0x1e34, KEY_FASTFORWARD },
64 { 0x1e35, KEY_PLAY },
65 { 0x1e36, KEY_STOP },
66 { 0x1e37, KEY_RECORD },
67 { 0x1e38, KEY_YELLOW },
68 { 0x1e3b, KEY_GOTO },
69 { 0x1e3d, KEY_POWER },
70};
71
72/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key
73 * is delivered. No workaround yet, maybe a new firmware.
74 */
75static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
76{
77 u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom;
78 u16 raw;
79 int i;
80 struct dibusb_device_state *st = d->priv;
81
82 dvb_usb_generic_rw(d,cmd,2,key,5,0);
83
84 *state = REMOTE_NO_KEY_PRESSED;
85 switch (key[0]) {
86 case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
87 raw = ((key[1] << 8) | key[2]) >> 3;
88 toggle = !!(raw & 0x800);
89 data = raw & 0x3f;
90 custom = (raw >> 6) & 0x1f;
91
92 deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
93
94 for (i = 0; i < ARRAY_SIZE(rc_map_haupp_table); i++) {
95 if (rc5_data(&rc_map_haupp_table[i]) == data &&
96 rc5_custom(&rc_map_haupp_table[i]) == custom) {
97
98 deb_rc("c: %x, d: %x\n", rc5_data(&rc_map_haupp_table[i]),
99 rc5_custom(&rc_map_haupp_table[i]));
100
101 *event = rc_map_haupp_table[i].keycode;
102 *state = REMOTE_KEY_PRESSED;
103 if (st->old_toggle == toggle) {
104 if (st->last_repeat_count++ < 2)
105 *state = REMOTE_NO_KEY_PRESSED;
106 } else {
107 st->last_repeat_count = 0;
108 st->old_toggle = toggle;
109 }
110 break;
111 }
112 }
113
114 break;
115 case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
116 default:
117 break;
118 }
119
120 return 0;
121}
122
123static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6])
124{
125 int i;
126 u8 b;
127
128 mac[0] = 0x00;
129 mac[1] = 0x0d;
130 mac[2] = 0xfe;
131
132 /* this is a complete guess, but works for my box */
133 for (i = 136; i < 139; i++) {
134 dibusb_read_eeprom_byte(d,i, &b);
135
136 mac[5 - (i - 136)] = b;
137 }
138
139 return 0;
140}
141
142/* USB Driver stuff */
143static struct dvb_usb_device_properties nova_t_properties;
144
145static int nova_t_probe(struct usb_interface *intf,
146 const struct usb_device_id *id)
147{
148 return dvb_usb_device_init(intf, &nova_t_properties,
149 THIS_MODULE, NULL, adapter_nr);
150}
151
152/* do not change the order of the ID table */
153static struct usb_device_id nova_t_table [] = {
154/* 00 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_COLD) },
155/* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) },
156 { } /* Terminating entry */
157};
158MODULE_DEVICE_TABLE(usb, nova_t_table);
159
160static struct dvb_usb_device_properties nova_t_properties = {
161 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
162
163 .usb_ctrl = CYPRESS_FX2,
164 .firmware = "dvb-usb-nova-t-usb2-02.fw",
165
166 .num_adapters = 1,
167 .adapter = {
168 {
169 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
170 .pid_filter_count = 32,
171
172 .streaming_ctrl = dibusb2_0_streaming_ctrl,
173 .pid_filter = dibusb_pid_filter,
174 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
175 .frontend_attach = dibusb_dib3000mc_frontend_attach,
176 .tuner_attach = dibusb_dib3000mc_tuner_attach,
177
178 /* parameter for the MPEG2-data transfer */
179 .stream = {
180 .type = USB_BULK,
181 .count = 7,
182 .endpoint = 0x06,
183 .u = {
184 .bulk = {
185 .buffersize = 4096,
186 }
187 }
188 },
189
190 .size_of_priv = sizeof(struct dibusb_state),
191 }
192 },
193 .size_of_priv = sizeof(struct dibusb_device_state),
194
195 .power_ctrl = dibusb2_0_power_ctrl,
196 .read_mac_address = nova_t_read_mac_address,
197
198 .rc.legacy = {
199 .rc_interval = 100,
200 .rc_map_table = rc_map_haupp_table,
201 .rc_map_size = ARRAY_SIZE(rc_map_haupp_table),
202 .rc_query = nova_t_rc_query,
203 },
204
205 .i2c_algo = &dibusb_i2c_algo,
206
207 .generic_bulk_ctrl_endpoint = 0x01,
208
209 .num_device_descs = 1,
210 .devices = {
211 { "Hauppauge WinTV-NOVA-T usb2",
212 { &nova_t_table[0], NULL },
213 { &nova_t_table[1], NULL },
214 },
215 { NULL },
216 }
217};
218
219static struct usb_driver nova_t_driver = {
220 .name = "dvb_usb_nova_t_usb2",
221 .probe = nova_t_probe,
222 .disconnect = dvb_usb_device_exit,
223 .id_table = nova_t_table,
224};
225
226/* module stuff */
227static int __init nova_t_module_init(void)
228{
229 int result;
230 if ((result = usb_register(&nova_t_driver))) {
231 err("usb_register failed. Error number %d",result);
232 return result;
233 }
234
235 return 0;
236}
237
238static void __exit nova_t_module_exit(void)
239{
240 /* deregister this driver from the USB subsystem */
241 usb_deregister(&nova_t_driver);
242}
243
244module_init (nova_t_module_init);
245module_exit (nova_t_module_exit);
246
247MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
248MODULE_DESCRIPTION("Hauppauge WinTV-NOVA-T usb2");
249MODULE_VERSION("1.0");
250MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
new file mode 100644
index 00000000000..2e4fab7215f
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/opera1.c
@@ -0,0 +1,595 @@
1/* DVB USB framework compliant Linux driver for the Opera1 DVB-S Card
2*
3* Copyright (C) 2006 Mario Hlawitschka (dh1pa@amsat.org)
4* Copyright (C) 2006 Marco Gittler (g.marco@freenet.de)
5*
6* This program is free software; you can redistribute it and/or modify it
7* under the terms of the GNU General Public License as published by the Free
8* Software Foundation, version 2.
9*
10* see Documentation/dvb/README.dvb-usb for more information
11*/
12
13#define DVB_USB_LOG_PREFIX "opera"
14
15#include "dvb-usb.h"
16#include "stv0299.h"
17
18#define OPERA_READ_MSG 0
19#define OPERA_WRITE_MSG 1
20#define OPERA_I2C_TUNER 0xd1
21
22#define READ_FX2_REG_REQ 0xba
23#define READ_MAC_ADDR 0x08
24#define OPERA_WRITE_FX2 0xbb
25#define OPERA_TUNER_REQ 0xb1
26#define REG_1F_SYMBOLRATE_BYTE0 0x1f
27#define REG_20_SYMBOLRATE_BYTE1 0x20
28#define REG_21_SYMBOLRATE_BYTE2 0x21
29
30#define ADDR_B600_VOLTAGE_13V (0x02)
31#define ADDR_B601_VOLTAGE_18V (0x03)
32#define ADDR_B1A6_STREAM_CTRL (0x04)
33#define ADDR_B880_READ_REMOTE (0x05)
34
35struct opera1_state {
36 u32 last_key_pressed;
37};
38struct rc_map_opera_table {
39 u32 keycode;
40 u32 event;
41};
42
43static int dvb_usb_opera1_debug;
44module_param_named(debug, dvb_usb_opera1_debug, int, 0644);
45MODULE_PARM_DESC(debug,
46 "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))."
47 DVB_USB_DEBUG_STATUS);
48
49DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
50
51
52static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value,
53 u8 * data, u16 len, int flags)
54{
55 int ret;
56 u8 tmp;
57 u8 *buf;
58 unsigned int pipe = (flags == OPERA_READ_MSG) ?
59 usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0);
60 u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
61
62 buf = kmalloc(len, GFP_KERNEL);
63 if (!buf)
64 return -ENOMEM;
65
66 if (flags == OPERA_WRITE_MSG)
67 memcpy(buf, data, len);
68 ret = usb_control_msg(dev, pipe, request,
69 request_type | USB_TYPE_VENDOR, value, 0x0,
70 buf, len, 2000);
71
72 if (request == OPERA_TUNER_REQ) {
73 tmp = buf[0];
74 if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
75 OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
76 0x01, 0x0, buf, 1, 2000) < 1 || buf[0] != 0x08) {
77 ret = 0;
78 goto out;
79 }
80 buf[0] = tmp;
81 }
82 if (flags == OPERA_READ_MSG)
83 memcpy(data, buf, len);
84out:
85 kfree(buf);
86 return ret;
87}
88
89/* I2C */
90
91static int opera1_usb_i2c_msgxfer(struct dvb_usb_device *dev, u16 addr,
92 u8 * buf, u16 len)
93{
94 int ret = 0;
95 u8 request;
96 u16 value;
97
98 if (!dev) {
99 info("no usb_device");
100 return -EINVAL;
101 }
102 if (mutex_lock_interruptible(&dev->usb_mutex) < 0)
103 return -EAGAIN;
104
105 switch (addr>>1){
106 case ADDR_B600_VOLTAGE_13V:
107 request=0xb6;
108 value=0x00;
109 break;
110 case ADDR_B601_VOLTAGE_18V:
111 request=0xb6;
112 value=0x01;
113 break;
114 case ADDR_B1A6_STREAM_CTRL:
115 request=0xb1;
116 value=0xa6;
117 break;
118 case ADDR_B880_READ_REMOTE:
119 request=0xb8;
120 value=0x80;
121 break;
122 default:
123 request=0xb1;
124 value=addr;
125 }
126 ret = opera1_xilinx_rw(dev->udev, request,
127 value, buf, len,
128 addr&0x01?OPERA_READ_MSG:OPERA_WRITE_MSG);
129
130 mutex_unlock(&dev->usb_mutex);
131 return ret;
132}
133
134static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
135 int num)
136{
137 struct dvb_usb_device *d = i2c_get_adapdata(adap);
138 int i = 0, tmp = 0;
139
140 if (!d)
141 return -ENODEV;
142 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
143 return -EAGAIN;
144
145 for (i = 0; i < num; i++) {
146 if ((tmp = opera1_usb_i2c_msgxfer(d,
147 (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
148 msg[i].buf,
149 msg[i].len
150 )) != msg[i].len) {
151 break;
152 }
153 if (dvb_usb_opera1_debug & 0x10)
154 info("sending i2c mesage %d %d", tmp, msg[i].len);
155 }
156 mutex_unlock(&d->i2c_mutex);
157 return num;
158}
159
160static u32 opera1_i2c_func(struct i2c_adapter *adapter)
161{
162 return I2C_FUNC_I2C;
163}
164
165static struct i2c_algorithm opera1_i2c_algo = {
166 .master_xfer = opera1_i2c_xfer,
167 .functionality = opera1_i2c_func,
168};
169
170static int opera1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
171{
172 static u8 command_13v[1]={0x00};
173 static u8 command_18v[1]={0x01};
174 struct i2c_msg msg[] = {
175 {.addr = ADDR_B600_VOLTAGE_13V,.flags = 0,.buf = command_13v,.len = 1},
176 };
177 struct dvb_usb_adapter *udev_adap =
178 (struct dvb_usb_adapter *)(fe->dvb->priv);
179 if (voltage == SEC_VOLTAGE_18) {
180 msg[0].addr = ADDR_B601_VOLTAGE_18V;
181 msg[0].buf = command_18v;
182 }
183 i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
184 return 0;
185}
186
187static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
188 u32 ratio)
189{
190 stv0299_writereg(fe, 0x13, 0x98);
191 stv0299_writereg(fe, 0x14, 0x95);
192 stv0299_writereg(fe, REG_1F_SYMBOLRATE_BYTE0, (ratio >> 16) & 0xff);
193 stv0299_writereg(fe, REG_20_SYMBOLRATE_BYTE1, (ratio >> 8) & 0xff);
194 stv0299_writereg(fe, REG_21_SYMBOLRATE_BYTE2, (ratio) & 0xf0);
195 return 0;
196
197}
198static u8 opera1_inittab[] = {
199 0x00, 0xa1,
200 0x01, 0x15,
201 0x02, 0x30,
202 0x03, 0x00,
203 0x04, 0x7d,
204 0x05, 0x05,
205 0x06, 0x02,
206 0x07, 0x00,
207 0x0b, 0x00,
208 0x0c, 0x01,
209 0x0d, 0x81,
210 0x0e, 0x44,
211 0x0f, 0x19,
212 0x10, 0x3f,
213 0x11, 0x84,
214 0x12, 0xda,
215 0x13, 0x98,
216 0x14, 0x95,
217 0x15, 0xc9,
218 0x16, 0xeb,
219 0x17, 0x00,
220 0x18, 0x19,
221 0x19, 0x8b,
222 0x1a, 0x00,
223 0x1b, 0x82,
224 0x1c, 0x7f,
225 0x1d, 0x00,
226 0x1e, 0x00,
227 REG_1F_SYMBOLRATE_BYTE0, 0x06,
228 REG_20_SYMBOLRATE_BYTE1, 0x50,
229 REG_21_SYMBOLRATE_BYTE2, 0x10,
230 0x22, 0x00,
231 0x23, 0x00,
232 0x24, 0x37,
233 0x25, 0xbc,
234 0x26, 0x00,
235 0x27, 0x00,
236 0x28, 0x00,
237 0x29, 0x1e,
238 0x2a, 0x14,
239 0x2b, 0x1f,
240 0x2c, 0x09,
241 0x2d, 0x0a,
242 0x2e, 0x00,
243 0x2f, 0x00,
244 0x30, 0x00,
245 0x31, 0x1f,
246 0x32, 0x19,
247 0x33, 0xfc,
248 0x34, 0x13,
249 0xff, 0xff,
250};
251
252static struct stv0299_config opera1_stv0299_config = {
253 .demod_address = 0xd0>>1,
254 .min_delay_ms = 100,
255 .mclk = 88000000UL,
256 .invert = 1,
257 .skip_reinit = 0,
258 .lock_output = STV0299_LOCKOUTPUT_0,
259 .volt13_op0_op1 = STV0299_VOLT13_OP0,
260 .inittab = opera1_inittab,
261 .set_symbol_rate = opera1_stv0299_set_symbol_rate,
262};
263
264static int opera1_frontend_attach(struct dvb_usb_adapter *d)
265{
266 if ((d->fe =
267 dvb_attach(stv0299_attach, &opera1_stv0299_config,
268 &d->dev->i2c_adap)) != NULL) {
269 d->fe->ops.set_voltage = opera1_set_voltage;
270 return 0;
271 }
272 info("not attached stv0299");
273 return -EIO;
274}
275
276static int opera1_tuner_attach(struct dvb_usb_adapter *adap)
277{
278 dvb_attach(
279 dvb_pll_attach, adap->fe, 0xc0>>1,
280 &adap->dev->i2c_adap, DVB_PLL_OPERA1
281 );
282 return 0;
283}
284
285static int opera1_power_ctrl(struct dvb_usb_device *d, int onoff)
286{
287 u8 val = onoff ? 0x01 : 0x00;
288
289 if (dvb_usb_opera1_debug)
290 info("power %s", onoff ? "on" : "off");
291 return opera1_xilinx_rw(d->udev, 0xb7, val,
292 &val, 1, OPERA_WRITE_MSG);
293}
294
295static int opera1_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
296{
297 static u8 buf_start[2] = { 0xff, 0x03 };
298 static u8 buf_stop[2] = { 0xff, 0x00 };
299 struct i2c_msg start_tuner[] = {
300 {.addr = ADDR_B1A6_STREAM_CTRL,.buf = onoff ? buf_start : buf_stop,.len = 2},
301 };
302 if (dvb_usb_opera1_debug)
303 info("streaming %s", onoff ? "on" : "off");
304 i2c_transfer(&adap->dev->i2c_adap, start_tuner, 1);
305 return 0;
306}
307
308static int opera1_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
309 int onoff)
310{
311 u8 b_pid[3];
312 struct i2c_msg msg[] = {
313 {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
314 };
315 if (dvb_usb_opera1_debug)
316 info("pidfilter index: %d pid: %d %s", index, pid,
317 onoff ? "on" : "off");
318 b_pid[0] = (2 * index) + 4;
319 b_pid[1] = onoff ? (pid & 0xff) : (0x00);
320 b_pid[2] = onoff ? ((pid >> 8) & 0xff) : (0x00);
321 i2c_transfer(&adap->dev->i2c_adap, msg, 1);
322 return 0;
323}
324
325static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
326{
327 int u = 0x04;
328 u8 b_pid[3];
329 struct i2c_msg msg[] = {
330 {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
331 };
332 if (dvb_usb_opera1_debug)
333 info("%s hw-pidfilter", onoff ? "enable" : "disable");
334 for (; u < 0x7e; u += 2) {
335 b_pid[0] = u;
336 b_pid[1] = 0;
337 b_pid[2] = 0x80;
338 i2c_transfer(&adap->dev->i2c_adap, msg, 1);
339 }
340 return 0;
341}
342
343static struct rc_map_table rc_map_opera1_table[] = {
344 {0x5fa0, KEY_1},
345 {0x51af, KEY_2},
346 {0x5da2, KEY_3},
347 {0x41be, KEY_4},
348 {0x0bf5, KEY_5},
349 {0x43bd, KEY_6},
350 {0x47b8, KEY_7},
351 {0x49b6, KEY_8},
352 {0x05fa, KEY_9},
353 {0x45ba, KEY_0},
354 {0x09f6, KEY_CHANNELUP}, /*chanup */
355 {0x1be5, KEY_CHANNELDOWN}, /*chandown */
356 {0x5da3, KEY_VOLUMEDOWN}, /*voldown */
357 {0x5fa1, KEY_VOLUMEUP}, /*volup */
358 {0x07f8, KEY_SPACE}, /*tab */
359 {0x1fe1, KEY_OK}, /*play ok */
360 {0x1be4, KEY_ZOOM}, /*zoom */
361 {0x59a6, KEY_MUTE}, /*mute */
362 {0x5ba5, KEY_RADIO}, /*tv/f */
363 {0x19e7, KEY_RECORD}, /*rec */
364 {0x01fe, KEY_STOP}, /*Stop */
365 {0x03fd, KEY_PAUSE}, /*pause */
366 {0x03fc, KEY_SCREEN}, /*<- -> */
367 {0x07f9, KEY_CAMERA}, /*capture */
368 {0x47b9, KEY_ESC}, /*exit */
369 {0x43bc, KEY_POWER2}, /*power */
370};
371
372static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
373{
374 struct opera1_state *opst = dev->priv;
375 u8 rcbuffer[32];
376 const u16 startmarker1 = 0x10ed;
377 const u16 startmarker2 = 0x11ec;
378 struct i2c_msg read_remote[] = {
379 {.addr = ADDR_B880_READ_REMOTE,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32},
380 };
381 int i = 0;
382 u32 send_key = 0;
383
384 if (i2c_transfer(&dev->i2c_adap, read_remote, 1) == 1) {
385 for (i = 0; i < 32; i++) {
386 if (rcbuffer[i])
387 send_key |= 1;
388 if (i < 31)
389 send_key = send_key << 1;
390 }
391 if (send_key & 0x8000)
392 send_key = (send_key << 1) | (send_key >> 15 & 0x01);
393
394 if (send_key == 0xffff && opst->last_key_pressed != 0) {
395 *state = REMOTE_KEY_REPEAT;
396 *event = opst->last_key_pressed;
397 return 0;
398 }
399 for (; send_key != 0;) {
400 if (send_key >> 16 == startmarker2) {
401 break;
402 } else if (send_key >> 16 == startmarker1) {
403 send_key =
404 (send_key & 0xfffeffff) | (startmarker1 << 16);
405 break;
406 } else
407 send_key >>= 1;
408 }
409
410 if (send_key == 0)
411 return 0;
412
413 send_key = (send_key & 0xffff) | 0x0100;
414
415 for (i = 0; i < ARRAY_SIZE(rc_map_opera1_table); i++) {
416 if (rc5_scan(&rc_map_opera1_table[i]) == (send_key & 0xffff)) {
417 *state = REMOTE_KEY_PRESSED;
418 *event = rc_map_opera1_table[i].keycode;
419 opst->last_key_pressed =
420 rc_map_opera1_table[i].keycode;
421 break;
422 }
423 opst->last_key_pressed = 0;
424 }
425 } else
426 *state = REMOTE_NO_KEY_PRESSED;
427 return 0;
428}
429
430static struct usb_device_id opera1_table[] = {
431 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_OPERA1_COLD)},
432 {USB_DEVICE(USB_VID_OPERA1, USB_PID_OPERA1_WARM)},
433 {}
434};
435
436MODULE_DEVICE_TABLE(usb, opera1_table);
437
438static int opera1_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
439{
440 u8 command[] = { READ_MAC_ADDR };
441 opera1_xilinx_rw(d->udev, 0xb1, 0xa0, command, 1, OPERA_WRITE_MSG);
442 opera1_xilinx_rw(d->udev, 0xb1, 0xa1, mac, 6, OPERA_READ_MSG);
443 return 0;
444}
445static int opera1_xilinx_load_firmware(struct usb_device *dev,
446 const char *filename)
447{
448 const struct firmware *fw = NULL;
449 u8 *b, *p;
450 int ret = 0, i,fpgasize=40;
451 u8 testval;
452 info("start downloading fpga firmware %s",filename);
453
454 if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) {
455 err("did not find the firmware file. (%s) "
456 "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
457 filename);
458 return ret;
459 } else {
460 p = kmalloc(fw->size, GFP_KERNEL);
461 opera1_xilinx_rw(dev, 0xbc, 0x00, &testval, 1, OPERA_READ_MSG);
462 if (p != NULL && testval != 0x67) {
463
464 u8 reset = 0, fpga_command = 0;
465 memcpy(p, fw->data, fw->size);
466 /* clear fpga ? */
467 opera1_xilinx_rw(dev, 0xbc, 0xaa, &fpga_command, 1,
468 OPERA_WRITE_MSG);
469 for (i = 0; i < fw->size;) {
470 if ( (fw->size - i) <fpgasize){
471 fpgasize=fw->size-i;
472 }
473 b = (u8 *) p + i;
474 if (opera1_xilinx_rw
475 (dev, OPERA_WRITE_FX2, 0x0, b , fpgasize,
476 OPERA_WRITE_MSG) != fpgasize
477 ) {
478 err("error while transferring firmware");
479 ret = -EINVAL;
480 break;
481 }
482 i = i + fpgasize;
483 }
484 /* restart the CPU */
485 if (ret || opera1_xilinx_rw
486 (dev, 0xa0, 0xe600, &reset, 1,
487 OPERA_WRITE_MSG) != 1) {
488 err("could not restart the USB controller CPU.");
489 ret = -EINVAL;
490 }
491 }
492 }
493 kfree(p);
494 release_firmware(fw);
495 return ret;
496}
497
498static struct dvb_usb_device_properties opera1_properties = {
499 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
500 .usb_ctrl = CYPRESS_FX2,
501 .firmware = "dvb-usb-opera-01.fw",
502 .size_of_priv = sizeof(struct opera1_state),
503
504 .power_ctrl = opera1_power_ctrl,
505 .i2c_algo = &opera1_i2c_algo,
506
507 .rc.legacy = {
508 .rc_map_table = rc_map_opera1_table,
509 .rc_map_size = ARRAY_SIZE(rc_map_opera1_table),
510 .rc_interval = 200,
511 .rc_query = opera1_rc_query,
512 },
513 .read_mac_address = opera1_read_mac_address,
514 .generic_bulk_ctrl_endpoint = 0x00,
515 /* parameter for the MPEG2-data transfer */
516 .num_adapters = 1,
517 .adapter = {
518 {
519 .frontend_attach = opera1_frontend_attach,
520 .streaming_ctrl = opera1_streaming_ctrl,
521 .tuner_attach = opera1_tuner_attach,
522 .caps =
523 DVB_USB_ADAP_HAS_PID_FILTER |
524 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
525 .pid_filter = opera1_pid_filter,
526 .pid_filter_ctrl = opera1_pid_filter_control,
527 .pid_filter_count = 252,
528 .stream = {
529 .type = USB_BULK,
530 .count = 10,
531 .endpoint = 0x82,
532 .u = {
533 .bulk = {
534 .buffersize = 4096,
535 }
536 }
537 },
538 }
539 },
540 .num_device_descs = 1,
541 .devices = {
542 {"Opera1 DVB-S USB2.0",
543 {&opera1_table[0], NULL},
544 {&opera1_table[1], NULL},
545 },
546 }
547};
548
549static int opera1_probe(struct usb_interface *intf,
550 const struct usb_device_id *id)
551{
552 struct usb_device *udev = interface_to_usbdev(intf);
553
554 if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM &&
555 udev->descriptor.idVendor == USB_VID_OPERA1 &&
556 opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga-01.fw") != 0
557 ) {
558 return -EINVAL;
559 }
560
561 if (0 != dvb_usb_device_init(intf, &opera1_properties,
562 THIS_MODULE, NULL, adapter_nr))
563 return -EINVAL;
564 return 0;
565}
566
567static struct usb_driver opera1_driver = {
568 .name = "opera1",
569 .probe = opera1_probe,
570 .disconnect = dvb_usb_device_exit,
571 .id_table = opera1_table,
572};
573
574static int __init opera1_module_init(void)
575{
576 int result = 0;
577 if ((result = usb_register(&opera1_driver))) {
578 err("usb_register failed. Error number %d", result);
579 }
580 return result;
581}
582
583static void __exit opera1_module_exit(void)
584{
585 usb_deregister(&opera1_driver);
586}
587
588module_init(opera1_module_init);
589module_exit(opera1_module_exit);
590
591MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org");
592MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de");
593MODULE_DESCRIPTION("Driver for Opera1 DVB-S device");
594MODULE_VERSION("0.1");
595MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/technisat-usb2.c b/drivers/media/dvb/dvb-usb/technisat-usb2.c
new file mode 100644
index 00000000000..473b95ed4d5
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/technisat-usb2.c
@@ -0,0 +1,805 @@
1/*
2 * Linux driver for Technisat DVB-S/S2 USB 2.0 device
3 *
4 * Copyright (C) 2010 Patrick Boettcher,
5 * Kernel Labs Inc. PO Box 745, St James, NY 11780
6 *
7 * Development was sponsored by Technisat Digital UK Limited, whose
8 * registered office is Witan Gate House 500 - 600 Witan Gate West,
9 * Milton Keynes, MK9 1SH
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
13 * published by the Free Software Foundation; either version 2 of the
14 * License, or (at your option) any later version.
15 *
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 * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND
22 * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO
23 * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR
24 * FITNESS FOR A PARTICULAR PURPOSE. NEITHER THE COPYRIGHT HOLDER
25 * NOR TECHNISAT DIGITAL UK LIMITED SHALL BE LIABLE FOR ANY SPECIAL,
26 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
27 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
28 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
29 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PROGRAM. See the
30 * GNU General Public License for more details.
31 */
32
33#define DVB_USB_LOG_PREFIX "technisat-usb2"
34#include "dvb-usb.h"
35
36#include "stv6110x.h"
37#include "stv090x.h"
38
39/* module parameters */
40DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
41
42static int debug;
43module_param(debug, int, 0644);
44MODULE_PARM_DESC(debug,
45 "set debugging level (bit-mask: 1=info,2=eeprom,4=i2c,8=rc)." \
46 DVB_USB_DEBUG_STATUS);
47
48/* disables all LED control command and
49 * also does not start the signal polling thread */
50static int disable_led_control;
51module_param(disable_led_control, int, 0444);
52MODULE_PARM_DESC(disable_led_control,
53 "disable LED control of the device "
54 "(default: 0 - LED control is active).");
55
56/* device private data */
57struct technisat_usb2_state {
58 struct dvb_usb_device *dev;
59 struct delayed_work green_led_work;
60 u8 power_state;
61
62 u16 last_scan_code;
63};
64
65/* debug print helpers */
66#define deb_info(args...) dprintk(debug, 0x01, args)
67#define deb_eeprom(args...) dprintk(debug, 0x02, args)
68#define deb_i2c(args...) dprintk(debug, 0x04, args)
69#define deb_rc(args...) dprintk(debug, 0x08, args)
70
71/* vendor requests */
72#define SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST 0xB3
73#define SET_FRONT_END_RESET_VENDOR_REQUEST 0xB4
74#define GET_VERSION_INFO_VENDOR_REQUEST 0xB5
75#define SET_GREEN_LED_VENDOR_REQUEST 0xB6
76#define SET_RED_LED_VENDOR_REQUEST 0xB7
77#define GET_IR_DATA_VENDOR_REQUEST 0xB8
78#define SET_LED_TIMER_DIVIDER_VENDOR_REQUEST 0xB9
79#define SET_USB_REENUMERATION 0xBA
80
81/* i2c-access methods */
82#define I2C_SPEED_100KHZ_BIT 0x40
83
84#define I2C_STATUS_NAK 7
85#define I2C_STATUS_OK 8
86
87static int technisat_usb2_i2c_access(struct usb_device *udev,
88 u8 device_addr, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
89{
90 u8 b[64];
91 int ret, actual_length;
92
93 deb_i2c("i2c-access: %02x, tx: ", device_addr);
94 debug_dump(tx, txlen, deb_i2c);
95 deb_i2c(" ");
96
97 if (txlen > 62) {
98 err("i2c TX buffer can't exceed 62 bytes (dev 0x%02x)",
99 device_addr);
100 txlen = 62;
101 }
102 if (rxlen > 62) {
103 err("i2c RX buffer can't exceed 62 bytes (dev 0x%02x)",
104 device_addr);
105 txlen = 62;
106 }
107
108 b[0] = I2C_SPEED_100KHZ_BIT;
109 b[1] = device_addr << 1;
110
111 if (rx != NULL) {
112 b[0] |= rxlen;
113 b[1] |= 1;
114 }
115
116 memcpy(&b[2], tx, txlen);
117 ret = usb_bulk_msg(udev,
118 usb_sndbulkpipe(udev, 0x01),
119 b, 2 + txlen,
120 NULL, 1000);
121
122 if (ret < 0) {
123 err("i2c-error: out failed %02x = %d", device_addr, ret);
124 return -ENODEV;
125 }
126
127 ret = usb_bulk_msg(udev,
128 usb_rcvbulkpipe(udev, 0x01),
129 b, 64, &actual_length, 1000);
130 if (ret < 0) {
131 err("i2c-error: in failed %02x = %d", device_addr, ret);
132 return -ENODEV;
133 }
134
135 if (b[0] != I2C_STATUS_OK) {
136 err("i2c-error: %02x = %d", device_addr, b[0]);
137 /* handle tuner-i2c-nak */
138 if (!(b[0] == I2C_STATUS_NAK &&
139 device_addr == 0x60
140 /* && device_is_technisat_usb2 */))
141 return -ENODEV;
142 }
143
144 deb_i2c("status: %d, ", b[0]);
145
146 if (rx != NULL) {
147 memcpy(rx, &b[2], rxlen);
148
149 deb_i2c("rx (%d): ", rxlen);
150 debug_dump(rx, rxlen, deb_i2c);
151 }
152
153 deb_i2c("\n");
154
155 return 0;
156}
157
158static int technisat_usb2_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
159 int num)
160{
161 int ret = 0, i;
162 struct dvb_usb_device *d = i2c_get_adapdata(adap);
163
164 /* Ensure nobody else hits the i2c bus while we're sending our
165 sequence of messages, (such as the remote control thread) */
166 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
167 return -EAGAIN;
168
169 for (i = 0; i < num; i++) {
170 if (i+1 < num && msg[i+1].flags & I2C_M_RD) {
171 ret = technisat_usb2_i2c_access(d->udev, msg[i+1].addr,
172 msg[i].buf, msg[i].len,
173 msg[i+1].buf, msg[i+1].len);
174 if (ret != 0)
175 break;
176 i++;
177 } else {
178 ret = technisat_usb2_i2c_access(d->udev, msg[i].addr,
179 msg[i].buf, msg[i].len,
180 NULL, 0);
181 if (ret != 0)
182 break;
183 }
184 }
185
186 if (ret == 0)
187 ret = i;
188
189 mutex_unlock(&d->i2c_mutex);
190
191 return ret;
192}
193
194static u32 technisat_usb2_i2c_func(struct i2c_adapter *adapter)
195{
196 return I2C_FUNC_I2C;
197}
198
199static struct i2c_algorithm technisat_usb2_i2c_algo = {
200 .master_xfer = technisat_usb2_i2c_xfer,
201 .functionality = technisat_usb2_i2c_func,
202};
203
204#if 0
205static void technisat_usb2_frontend_reset(struct usb_device *udev)
206{
207 usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
208 SET_FRONT_END_RESET_VENDOR_REQUEST,
209 USB_TYPE_VENDOR | USB_DIR_OUT,
210 10, 0,
211 NULL, 0, 500);
212}
213#endif
214
215/* LED control */
216enum technisat_usb2_led_state {
217 LED_OFF,
218 LED_BLINK,
219 LED_ON,
220 LED_UNDEFINED
221};
222
223static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum technisat_usb2_led_state state)
224{
225 int ret;
226
227 u8 led[8] = {
228 red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
229 0
230 };
231
232 if (disable_led_control && state != LED_OFF)
233 return 0;
234
235 switch (state) {
236 case LED_ON:
237 led[1] = 0x82;
238 break;
239 case LED_BLINK:
240 led[1] = 0x82;
241 if (red) {
242 led[2] = 0x02;
243 led[3] = 10;
244 led[4] = 10;
245 } else {
246 led[2] = 0xff;
247 led[3] = 50;
248 led[4] = 50;
249 }
250 led[5] = 1;
251 break;
252
253 default:
254 case LED_OFF:
255 led[1] = 0x80;
256 break;
257 }
258
259 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
260 return -EAGAIN;
261
262 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
263 red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
264 USB_TYPE_VENDOR | USB_DIR_OUT,
265 0, 0,
266 led, sizeof(led), 500);
267
268 mutex_unlock(&d->i2c_mutex);
269 return ret;
270}
271
272static int technisat_usb2_set_led_timer(struct dvb_usb_device *d, u8 red, u8 green)
273{
274 int ret;
275 u8 b = 0;
276
277 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
278 return -EAGAIN;
279
280 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
281 SET_LED_TIMER_DIVIDER_VENDOR_REQUEST,
282 USB_TYPE_VENDOR | USB_DIR_OUT,
283 (red << 8) | green, 0,
284 &b, 1, 500);
285
286 mutex_unlock(&d->i2c_mutex);
287
288 return ret;
289}
290
291static void technisat_usb2_green_led_control(struct work_struct *work)
292{
293 struct technisat_usb2_state *state =
294 container_of(work, struct technisat_usb2_state, green_led_work.work);
295 struct dvb_frontend *fe = state->dev->adapter[0].fe;
296
297 if (state->power_state == 0)
298 goto schedule;
299
300 if (fe != NULL) {
301 enum fe_status status;
302
303 if (fe->ops.read_status(fe, &status) != 0)
304 goto schedule;
305
306 if (status & FE_HAS_LOCK) {
307 u32 ber;
308
309 if (fe->ops.read_ber(fe, &ber) != 0)
310 goto schedule;
311
312 if (ber > 1000)
313 technisat_usb2_set_led(state->dev, 0, LED_BLINK);
314 else
315 technisat_usb2_set_led(state->dev, 0, LED_ON);
316 } else
317 technisat_usb2_set_led(state->dev, 0, LED_OFF);
318 }
319
320schedule:
321 schedule_delayed_work(&state->green_led_work,
322 msecs_to_jiffies(500));
323}
324
325/* method to find out whether the firmware has to be downloaded or not */
326static int technisat_usb2_identify_state(struct usb_device *udev,
327 struct dvb_usb_device_properties *props,
328 struct dvb_usb_device_description **desc, int *cold)
329{
330 int ret;
331 u8 version[3];
332
333 /* first select the interface */
334 if (usb_set_interface(udev, 0, 1) != 0)
335 err("could not set alternate setting to 0");
336 else
337 info("set alternate setting");
338
339 *cold = 0; /* by default do not download a firmware - just in case something is wrong */
340
341 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
342 GET_VERSION_INFO_VENDOR_REQUEST,
343 USB_TYPE_VENDOR | USB_DIR_IN,
344 0, 0,
345 version, sizeof(version), 500);
346
347 if (ret < 0)
348 *cold = 1;
349 else {
350 info("firmware version: %d.%d", version[1], version[2]);
351 *cold = 0;
352 }
353
354 return 0;
355}
356
357/* power control */
358static int technisat_usb2_power_ctrl(struct dvb_usb_device *d, int level)
359{
360 struct technisat_usb2_state *state = d->priv;
361
362 state->power_state = level;
363
364 if (disable_led_control)
365 return 0;
366
367 /* green led is turned off in any case - will be turned on when tuning */
368 technisat_usb2_set_led(d, 0, LED_OFF);
369 /* red led is turned on all the time */
370 technisat_usb2_set_led(d, 1, LED_ON);
371 return 0;
372}
373
374/* mac address reading - from the eeprom */
375#if 0
376static void technisat_usb2_eeprom_dump(struct dvb_usb_device *d)
377{
378 u8 reg;
379 u8 b[16];
380 int i, j;
381
382 /* full EEPROM dump */
383 for (j = 0; j < 256 * 4; j += 16) {
384 reg = j;
385 if (technisat_usb2_i2c_access(d->udev, 0x50 + j / 256, &reg, 1, b, 16) != 0)
386 break;
387
388 deb_eeprom("EEPROM: %01x%02x: ", j / 256, reg);
389 for (i = 0; i < 16; i++)
390 deb_eeprom("%02x ", b[i]);
391 deb_eeprom("\n");
392 }
393}
394#endif
395
396static u8 technisat_usb2_calc_lrc(const u8 *b, u16 length)
397{
398 u8 lrc = 0;
399 while (--length)
400 lrc ^= *b++;
401 return lrc;
402}
403
404static int technisat_usb2_eeprom_lrc_read(struct dvb_usb_device *d,
405 u16 offset, u8 *b, u16 length, u8 tries)
406{
407 u8 bo = offset & 0xff;
408 struct i2c_msg msg[] = {
409 {
410 .addr = 0x50 | ((offset >> 8) & 0x3),
411 .buf = &bo,
412 .len = 1
413 }, {
414 .addr = 0x50 | ((offset >> 8) & 0x3),
415 .flags = I2C_M_RD,
416 .buf = b,
417 .len = length
418 }
419 };
420
421 while (tries--) {
422 int status;
423
424 if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
425 break;
426
427 status =
428 technisat_usb2_calc_lrc(b, length - 1) == b[length - 1];
429
430 if (status)
431 return 0;
432 }
433
434 return -EREMOTEIO;
435}
436
437#define EEPROM_MAC_START 0x3f8
438#define EEPROM_MAC_TOTAL 8
439static int technisat_usb2_read_mac_address(struct dvb_usb_device *d,
440 u8 mac[])
441{
442 u8 buf[EEPROM_MAC_TOTAL];
443
444 if (technisat_usb2_eeprom_lrc_read(d, EEPROM_MAC_START,
445 buf, EEPROM_MAC_TOTAL, 4) != 0)
446 return -ENODEV;
447
448 memcpy(mac, buf, 6);
449 return 0;
450}
451
452/* frontend attach */
453static int technisat_usb2_set_voltage(struct dvb_frontend *fe,
454 fe_sec_voltage_t voltage)
455{
456 int i;
457 u8 gpio[3] = { 0 }; /* 0 = 2, 1 = 3, 2 = 4 */
458
459 gpio[2] = 1; /* high - voltage ? */
460
461 switch (voltage) {
462 case SEC_VOLTAGE_13:
463 gpio[0] = 1;
464 break;
465 case SEC_VOLTAGE_18:
466 gpio[0] = 1;
467 gpio[1] = 1;
468 break;
469 default:
470 case SEC_VOLTAGE_OFF:
471 break;
472 }
473
474 for (i = 0; i < 3; i++)
475 if (stv090x_set_gpio(fe, i+2, 0, gpio[i], 0) != 0)
476 return -EREMOTEIO;
477 return 0;
478}
479
480static struct stv090x_config technisat_usb2_stv090x_config = {
481 .device = STV0903,
482 .demod_mode = STV090x_SINGLE,
483 .clk_mode = STV090x_CLK_EXT,
484
485 .xtal = 8000000,
486 .address = 0x68,
487
488 .ts1_mode = STV090x_TSMODE_DVBCI,
489 .ts1_clk = 13400000,
490 .ts1_tei = 1,
491
492 .repeater_level = STV090x_RPTLEVEL_64,
493
494 .tuner_bbgain = 6,
495};
496
497static struct stv6110x_config technisat_usb2_stv6110x_config = {
498 .addr = 0x60,
499 .refclk = 16000000,
500 .clk_div = 2,
501};
502
503static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a)
504{
505 struct usb_device *udev = a->dev->udev;
506 int ret;
507
508 a->fe = dvb_attach(stv090x_attach, &technisat_usb2_stv090x_config,
509 &a->dev->i2c_adap, STV090x_DEMODULATOR_0);
510
511 if (a->fe) {
512 struct stv6110x_devctl *ctl;
513
514 ctl = dvb_attach(stv6110x_attach,
515 a->fe,
516 &technisat_usb2_stv6110x_config,
517 &a->dev->i2c_adap);
518
519 if (ctl) {
520 technisat_usb2_stv090x_config.tuner_init = ctl->tuner_init;
521 technisat_usb2_stv090x_config.tuner_sleep = ctl->tuner_sleep;
522 technisat_usb2_stv090x_config.tuner_set_mode = ctl->tuner_set_mode;
523 technisat_usb2_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
524 technisat_usb2_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
525 technisat_usb2_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
526 technisat_usb2_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
527 technisat_usb2_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain;
528 technisat_usb2_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain;
529 technisat_usb2_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk;
530 technisat_usb2_stv090x_config.tuner_get_status = ctl->tuner_get_status;
531
532 /* call the init function once to initialize
533 tuner's clock output divider and demod's
534 master clock */
535 if (a->fe->ops.init)
536 a->fe->ops.init(a->fe);
537
538 if (mutex_lock_interruptible(&a->dev->i2c_mutex) < 0)
539 return -EAGAIN;
540
541 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
542 SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST,
543 USB_TYPE_VENDOR | USB_DIR_OUT,
544 0, 0,
545 NULL, 0, 500);
546 mutex_unlock(&a->dev->i2c_mutex);
547
548 if (ret != 0)
549 err("could not set IF_CLK to external");
550
551 a->fe->ops.set_voltage = technisat_usb2_set_voltage;
552
553 /* if everything was successful assign a nice name to the frontend */
554 strlcpy(a->fe->ops.info.name, a->dev->desc->name,
555 sizeof(a->fe->ops.info.name));
556 } else {
557 dvb_frontend_detach(a->fe);
558 a->fe = NULL;
559 }
560 }
561
562 technisat_usb2_set_led_timer(a->dev, 1, 1);
563
564 return a->fe == NULL ? -ENODEV : 0;
565}
566
567/* Remote control */
568
569/* the device is giving providing raw IR-signals to the host mapping
570 * it only to one remote control is just the default implementation
571 */
572#define NOMINAL_IR_BIT_TRANSITION_TIME_US 889
573#define NOMINAL_IR_BIT_TIME_US (2 * NOMINAL_IR_BIT_TRANSITION_TIME_US)
574
575#define FIRMWARE_CLOCK_TICK 83333
576#define FIRMWARE_CLOCK_DIVISOR 256
577
578#define IR_PERCENT_TOLERANCE 15
579
580#define NOMINAL_IR_BIT_TRANSITION_TICKS ((NOMINAL_IR_BIT_TRANSITION_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
581#define NOMINAL_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICKS / FIRMWARE_CLOCK_DIVISOR)
582
583#define NOMINAL_IR_BIT_TIME_TICKS ((NOMINAL_IR_BIT_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
584#define NOMINAL_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICKS / FIRMWARE_CLOCK_DIVISOR)
585
586#define MINIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT - ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
587#define MAXIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT + ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
588
589#define MINIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT - ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
590#define MAXIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT + ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
591
592static int technisat_usb2_get_ir(struct dvb_usb_device *d)
593{
594 u8 buf[62], *b;
595 int ret;
596 struct ir_raw_event ev;
597
598 buf[0] = GET_IR_DATA_VENDOR_REQUEST;
599 buf[1] = 0x08;
600 buf[2] = 0x8f;
601 buf[3] = MINIMUM_IR_BIT_TRANSITION_TICK_COUNT;
602 buf[4] = MAXIMUM_IR_BIT_TIME_TICK_COUNT;
603
604 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
605 return -EAGAIN;
606 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
607 GET_IR_DATA_VENDOR_REQUEST,
608 USB_TYPE_VENDOR | USB_DIR_OUT,
609 0, 0,
610 buf, 5, 500);
611 if (ret < 0)
612 goto unlock;
613
614 buf[1] = 0;
615 buf[2] = 0;
616 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
617 GET_IR_DATA_VENDOR_REQUEST,
618 USB_TYPE_VENDOR | USB_DIR_IN,
619 0x8080, 0,
620 buf, sizeof(buf), 500);
621
622unlock:
623 mutex_unlock(&d->i2c_mutex);
624
625 if (ret < 0)
626 return ret;
627
628 if (ret == 1)
629 return 0; /* no key pressed */
630
631 /* decoding */
632 b = buf+1;
633
634#if 0
635 deb_rc("RC: %d ", ret);
636 debug_dump(b, ret, deb_rc);
637#endif
638
639 ev.pulse = 0;
640 while (1) {
641 ev.pulse = !ev.pulse;
642 ev.duration = (*b * FIRMWARE_CLOCK_DIVISOR * FIRMWARE_CLOCK_TICK) / 1000;
643 ir_raw_event_store(d->rc_dev, &ev);
644
645 b++;
646 if (*b == 0xff) {
647 ev.pulse = 0;
648 ev.duration = 888888*2;
649 ir_raw_event_store(d->rc_dev, &ev);
650 break;
651 }
652 }
653
654 ir_raw_event_handle(d->rc_dev);
655
656 return 1;
657}
658
659static int technisat_usb2_rc_query(struct dvb_usb_device *d)
660{
661 int ret = technisat_usb2_get_ir(d);
662
663 if (ret < 0)
664 return ret;
665
666 if (ret == 0)
667 return 0;
668
669 if (!disable_led_control)
670 technisat_usb2_set_led(d, 1, LED_BLINK);
671
672 return 0;
673}
674
675/* DVB-USB and USB stuff follows */
676static struct usb_device_id technisat_usb2_id_table[] = {
677 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_DVB_S2) },
678 { 0 } /* Terminating entry */
679};
680
681/* device description */
682static struct dvb_usb_device_properties technisat_usb2_devices = {
683 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
684
685 .usb_ctrl = CYPRESS_FX2,
686
687 .identify_state = technisat_usb2_identify_state,
688 .firmware = "dvb-usb-SkyStar_USB_HD_FW_v17_63.HEX.fw",
689
690 .size_of_priv = sizeof(struct technisat_usb2_state),
691
692 .i2c_algo = &technisat_usb2_i2c_algo,
693
694 .power_ctrl = technisat_usb2_power_ctrl,
695 .read_mac_address = technisat_usb2_read_mac_address,
696
697 .num_adapters = 1,
698 .adapter = {
699 {
700 .frontend_attach = technisat_usb2_frontend_attach,
701
702 .stream = {
703 .type = USB_ISOC,
704 .count = 8,
705 .endpoint = 0x2,
706 .u = {
707 .isoc = {
708 .framesperurb = 32,
709 .framesize = 2048,
710 .interval = 3,
711 }
712 }
713 },
714
715 .size_of_priv = 0,
716 },
717 },
718
719 .num_device_descs = 1,
720 .devices = {
721 { "Technisat SkyStar USB HD (DVB-S/S2)",
722 { &technisat_usb2_id_table[0], NULL },
723 { NULL },
724 },
725 },
726
727 .rc.core = {
728 .rc_interval = 100,
729 .rc_codes = RC_MAP_TECHNISAT_USB2,
730 .module_name = "technisat-usb2",
731 .rc_query = technisat_usb2_rc_query,
732 .allowed_protos = RC_TYPE_ALL,
733 .driver_type = RC_DRIVER_IR_RAW,
734 }
735};
736
737static int technisat_usb2_probe(struct usb_interface *intf,
738 const struct usb_device_id *id)
739{
740 struct dvb_usb_device *dev;
741
742 if (dvb_usb_device_init(intf, &technisat_usb2_devices, THIS_MODULE,
743 &dev, adapter_nr) != 0)
744 return -ENODEV;
745
746 if (dev) {
747 struct technisat_usb2_state *state = dev->priv;
748 state->dev = dev;
749
750 if (!disable_led_control) {
751 INIT_DELAYED_WORK(&state->green_led_work,
752 technisat_usb2_green_led_control);
753 schedule_delayed_work(&state->green_led_work,
754 msecs_to_jiffies(500));
755 }
756 }
757
758 return 0;
759}
760
761static void technisat_usb2_disconnect(struct usb_interface *intf)
762{
763 struct dvb_usb_device *dev = usb_get_intfdata(intf);
764
765 /* work and stuff was only created when the device is is hot-state */
766 if (dev != NULL) {
767 struct technisat_usb2_state *state = dev->priv;
768 if (state != NULL)
769 cancel_delayed_work_sync(&state->green_led_work);
770 }
771
772 dvb_usb_device_exit(intf);
773}
774
775static struct usb_driver technisat_usb2_driver = {
776 .name = "dvb_usb_technisat_usb2",
777 .probe = technisat_usb2_probe,
778 .disconnect = technisat_usb2_disconnect,
779 .id_table = technisat_usb2_id_table,
780};
781
782/* module stuff */
783static int __init technisat_usb2_module_init(void)
784{
785 int result = usb_register(&technisat_usb2_driver);
786 if (result) {
787 err("usb_register failed. Code %d", result);
788 return result;
789 }
790
791 return 0;
792}
793
794static void __exit technisat_usb2_module_exit(void)
795{
796 usb_deregister(&technisat_usb2_driver);
797}
798
799module_init(technisat_usb2_module_init);
800module_exit(technisat_usb2_module_exit);
801
802MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>");
803MODULE_DESCRIPTION("Driver for Technisat DVB-S/S2 USB 2.0 device");
804MODULE_VERSION("1.0");
805MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c
new file mode 100644
index 00000000000..0d4709ff9cb
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ttusb2.c
@@ -0,0 +1,453 @@
1/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones
2 * (e.g. Pinnacle 400e DVB-S USB2.0).
3 *
4 * The Pinnacle 400e uses the same protocol as the Technotrend USB1.1 boxes.
5 *
6 * TDA8263 + TDA10086
7 *
8 * I2C addresses:
9 * 0x08 - LNBP21PD - LNB power supply
10 * 0x0e - TDA10086 - Demodulator
11 * 0x50 - FX2 eeprom
12 * 0x60 - TDA8263 - Tuner
13 * 0x78 ???
14 *
15 * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
16 * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
17 * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.org>
18 *
19 * This program is free software; you can redistribute it and/or modify it
20 * under the terms of the GNU General Public License as published by the Free
21 * Software Foundation, version 2.
22 *
23 * see Documentation/dvb/README.dvb-usb for more information
24 */
25#define DVB_USB_LOG_PREFIX "ttusb2"
26#include "dvb-usb.h"
27
28#include "ttusb2.h"
29
30#include "tda826x.h"
31#include "tda10086.h"
32#include "tda1002x.h"
33#include "tda827x.h"
34#include "lnbp21.h"
35
36/* debug */
37static int dvb_usb_ttusb2_debug;
38#define deb_info(args...) dprintk(dvb_usb_ttusb2_debug,0x01,args)
39module_param_named(debug,dvb_usb_ttusb2_debug, int, 0644);
40MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS);
41
42DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
43
44struct ttusb2_state {
45 u8 id;
46 u16 last_rc_key;
47};
48
49static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd,
50 u8 *wbuf, int wlen, u8 *rbuf, int rlen)
51{
52 struct ttusb2_state *st = d->priv;
53 u8 s[wlen+4],r[64] = { 0 };
54 int ret = 0;
55
56 memset(s,0,wlen+4);
57
58 s[0] = 0xaa;
59 s[1] = ++st->id;
60 s[2] = cmd;
61 s[3] = wlen;
62 memcpy(&s[4],wbuf,wlen);
63
64 ret = dvb_usb_generic_rw(d, s, wlen+4, r, 64, 0);
65
66 if (ret != 0 ||
67 r[0] != 0x55 ||
68 r[1] != s[1] ||
69 r[2] != cmd ||
70 (rlen > 0 && r[3] != rlen)) {
71 warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]);
72 return -EIO;
73 }
74
75 if (rlen > 0)
76 memcpy(rbuf, &r[4], rlen);
77
78 return 0;
79}
80
81static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
82{
83 struct dvb_usb_device *d = i2c_get_adapdata(adap);
84 static u8 obuf[60], ibuf[60];
85 int i,read;
86
87 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
88 return -EAGAIN;
89
90 if (num > 2)
91 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
92
93 for (i = 0; i < num; i++) {
94 read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
95
96 obuf[0] = (msg[i].addr << 1) | read;
97 obuf[1] = msg[i].len;
98
99 /* read request */
100 if (read)
101 obuf[2] = msg[i+1].len;
102 else
103 obuf[2] = 0;
104
105 memcpy(&obuf[3],msg[i].buf,msg[i].len);
106
107 if (ttusb2_msg(d, CMD_I2C_XFER, obuf, msg[i].len+3, ibuf, obuf[2] + 3) < 0) {
108 err("i2c transfer failed.");
109 break;
110 }
111
112 if (read) {
113 memcpy(msg[i+1].buf,&ibuf[3],msg[i+1].len);
114 i++;
115 }
116 }
117
118 mutex_unlock(&d->i2c_mutex);
119 return i;
120}
121
122static u32 ttusb2_i2c_func(struct i2c_adapter *adapter)
123{
124 return I2C_FUNC_I2C;
125}
126
127static struct i2c_algorithm ttusb2_i2c_algo = {
128 .master_xfer = ttusb2_i2c_xfer,
129 .functionality = ttusb2_i2c_func,
130};
131
132/* command to poll IR receiver (copied from pctv452e.c) */
133#define CMD_GET_IR_CODE 0x1b
134
135/* IR */
136static int tt3650_rc_query(struct dvb_usb_device *d)
137{
138 int ret;
139 u8 rx[9]; /* A CMD_GET_IR_CODE reply is 9 bytes long */
140 struct ttusb2_state *st = d->priv;
141 ret = ttusb2_msg(d, CMD_GET_IR_CODE, NULL, 0, rx, sizeof(rx));
142 if (ret != 0)
143 return ret;
144
145 if (rx[8] & 0x01) {
146 /* got a "press" event */
147 st->last_rc_key = (rx[3] << 8) | rx[2];
148 deb_info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[2], rx[3]);
149 rc_keydown(d->rc_dev, st->last_rc_key, 0);
150 } else if (st->last_rc_key) {
151 rc_keyup(d->rc_dev);
152 st->last_rc_key = 0;
153 }
154
155 return 0;
156}
157
158
159/* Callbacks for DVB USB */
160static int ttusb2_identify_state (struct usb_device *udev, struct
161 dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
162 int *cold)
163{
164 *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
165 return 0;
166}
167
168static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff)
169{
170 u8 b = onoff;
171 ttusb2_msg(d, CMD_POWER, &b, 0, NULL, 0);
172 return ttusb2_msg(d, CMD_POWER, &b, 1, NULL, 0);
173}
174
175
176static struct tda10086_config tda10086_config = {
177 .demod_address = 0x0e,
178 .invert = 0,
179 .diseqc_tone = 1,
180 .xtal_freq = TDA10086_XTAL_16M,
181};
182
183static struct tda10023_config tda10023_config = {
184 .demod_address = 0x0c,
185 .invert = 0,
186 .xtal = 16000000,
187 .pll_m = 11,
188 .pll_p = 3,
189 .pll_n = 1,
190 .deltaf = 0xa511,
191};
192
193static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap)
194{
195 if (usb_set_interface(adap->dev->udev,0,3) < 0)
196 err("set interface to alts=3 failed");
197
198 if ((adap->fe = dvb_attach(tda10086_attach, &tda10086_config, &adap->dev->i2c_adap)) == NULL) {
199 deb_info("TDA10086 attach failed\n");
200 return -ENODEV;
201 }
202
203 return 0;
204}
205
206static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap)
207{
208 if (usb_set_interface(adap->dev->udev, 0, 3) < 0)
209 err("set interface to alts=3 failed");
210 if ((adap->fe = dvb_attach(tda10023_attach, &tda10023_config, &adap->dev->i2c_adap, 0x48)) == NULL) {
211 deb_info("TDA10023 attach failed\n");
212 return -ENODEV;
213 }
214 return 0;
215}
216
217static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap)
218{
219 if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL) {
220 printk(KERN_ERR "%s: No tda827x found!\n", __func__);
221 return -ENODEV;
222 }
223 return 0;
224}
225
226static int ttusb2_tuner_tda826x_attach(struct dvb_usb_adapter *adap)
227{
228 if (dvb_attach(tda826x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) {
229 deb_info("TDA8263 attach failed\n");
230 return -ENODEV;
231 }
232
233 if (dvb_attach(lnbp21_attach, adap->fe, &adap->dev->i2c_adap, 0, 0) == NULL) {
234 deb_info("LNBP21 attach failed\n");
235 return -ENODEV;
236 }
237 return 0;
238}
239
240/* DVB USB Driver stuff */
241static struct dvb_usb_device_properties ttusb2_properties;
242static struct dvb_usb_device_properties ttusb2_properties_s2400;
243static struct dvb_usb_device_properties ttusb2_properties_ct3650;
244
245static int ttusb2_probe(struct usb_interface *intf,
246 const struct usb_device_id *id)
247{
248 if (0 == dvb_usb_device_init(intf, &ttusb2_properties,
249 THIS_MODULE, NULL, adapter_nr) ||
250 0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400,
251 THIS_MODULE, NULL, adapter_nr) ||
252 0 == dvb_usb_device_init(intf, &ttusb2_properties_ct3650,
253 THIS_MODULE, NULL, adapter_nr))
254 return 0;
255 return -ENODEV;
256}
257
258static struct usb_device_id ttusb2_table [] = {
259 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) },
260 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) },
261 { USB_DEVICE(USB_VID_TECHNOTREND,
262 USB_PID_TECHNOTREND_CONNECT_S2400) },
263 { USB_DEVICE(USB_VID_TECHNOTREND,
264 USB_PID_TECHNOTREND_CONNECT_CT3650) },
265 {} /* Terminating entry */
266};
267MODULE_DEVICE_TABLE (usb, ttusb2_table);
268
269static struct dvb_usb_device_properties ttusb2_properties = {
270 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
271
272 .usb_ctrl = CYPRESS_FX2,
273 .firmware = "dvb-usb-pctv-400e-01.fw",
274
275 .size_of_priv = sizeof(struct ttusb2_state),
276
277 .num_adapters = 1,
278 .adapter = {
279 {
280 .streaming_ctrl = NULL, // ttusb2_streaming_ctrl,
281
282 .frontend_attach = ttusb2_frontend_tda10086_attach,
283 .tuner_attach = ttusb2_tuner_tda826x_attach,
284
285 /* parameter for the MPEG2-data transfer */
286 .stream = {
287 .type = USB_ISOC,
288 .count = 5,
289 .endpoint = 0x02,
290 .u = {
291 .isoc = {
292 .framesperurb = 4,
293 .framesize = 940,
294 .interval = 1,
295 }
296 }
297 }
298 }
299 },
300
301 .power_ctrl = ttusb2_power_ctrl,
302 .identify_state = ttusb2_identify_state,
303
304 .i2c_algo = &ttusb2_i2c_algo,
305
306 .generic_bulk_ctrl_endpoint = 0x01,
307
308 .num_device_descs = 2,
309 .devices = {
310 { "Pinnacle 400e DVB-S USB2.0",
311 { &ttusb2_table[0], NULL },
312 { NULL },
313 },
314 { "Pinnacle 450e DVB-S USB2.0",
315 { &ttusb2_table[1], NULL },
316 { NULL },
317 },
318 }
319};
320
321static struct dvb_usb_device_properties ttusb2_properties_s2400 = {
322 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
323
324 .usb_ctrl = CYPRESS_FX2,
325 .firmware = "dvb-usb-tt-s2400-01.fw",
326
327 .size_of_priv = sizeof(struct ttusb2_state),
328
329 .num_adapters = 1,
330 .adapter = {
331 {
332 .streaming_ctrl = NULL,
333
334 .frontend_attach = ttusb2_frontend_tda10086_attach,
335 .tuner_attach = ttusb2_tuner_tda826x_attach,
336
337 /* parameter for the MPEG2-data transfer */
338 .stream = {
339 .type = USB_ISOC,
340 .count = 5,
341 .endpoint = 0x02,
342 .u = {
343 .isoc = {
344 .framesperurb = 4,
345 .framesize = 940,
346 .interval = 1,
347 }
348 }
349 }
350 }
351 },
352
353 .power_ctrl = ttusb2_power_ctrl,
354 .identify_state = ttusb2_identify_state,
355
356 .i2c_algo = &ttusb2_i2c_algo,
357
358 .generic_bulk_ctrl_endpoint = 0x01,
359
360 .num_device_descs = 1,
361 .devices = {
362 { "Technotrend TT-connect S-2400",
363 { &ttusb2_table[2], NULL },
364 { NULL },
365 },
366 }
367};
368
369static struct dvb_usb_device_properties ttusb2_properties_ct3650 = {
370 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
371
372 .usb_ctrl = CYPRESS_FX2,
373
374 .size_of_priv = sizeof(struct ttusb2_state),
375
376 .rc.core = {
377 .rc_interval = 150, /* Less than IR_KEYPRESS_TIMEOUT */
378 .rc_codes = RC_MAP_TT_1500,
379 .rc_query = tt3650_rc_query,
380 .allowed_protos = RC_TYPE_UNKNOWN,
381 },
382
383 .num_adapters = 1,
384 .adapter = {
385 {
386 .streaming_ctrl = NULL,
387
388 .frontend_attach = ttusb2_frontend_tda10023_attach,
389 .tuner_attach = ttusb2_tuner_tda827x_attach,
390
391 /* parameter for the MPEG2-data transfer */
392 .stream = {
393 .type = USB_ISOC,
394 .count = 5,
395 .endpoint = 0x02,
396 .u = {
397 .isoc = {
398 .framesperurb = 4,
399 .framesize = 940,
400 .interval = 1,
401 }
402 }
403 }
404 },
405 },
406
407 .power_ctrl = ttusb2_power_ctrl,
408 .identify_state = ttusb2_identify_state,
409
410 .i2c_algo = &ttusb2_i2c_algo,
411
412 .generic_bulk_ctrl_endpoint = 0x01,
413
414 .num_device_descs = 1,
415 .devices = {
416 { "Technotrend TT-connect CT-3650",
417 .warm_ids = { &ttusb2_table[3], NULL },
418 },
419 }
420};
421
422static struct usb_driver ttusb2_driver = {
423 .name = "dvb_usb_ttusb2",
424 .probe = ttusb2_probe,
425 .disconnect = dvb_usb_device_exit,
426 .id_table = ttusb2_table,
427};
428
429/* module stuff */
430static int __init ttusb2_module_init(void)
431{
432 int result;
433 if ((result = usb_register(&ttusb2_driver))) {
434 err("usb_register failed. Error number %d",result);
435 return result;
436 }
437
438 return 0;
439}
440
441static void __exit ttusb2_module_exit(void)
442{
443 /* deregister this driver from the USB subsystem */
444 usb_deregister(&ttusb2_driver);
445}
446
447module_init (ttusb2_module_init);
448module_exit (ttusb2_module_exit);
449
450MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
451MODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0");
452MODULE_VERSION("1.0");
453MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/ttusb2.h b/drivers/media/dvb/dvb-usb/ttusb2.h
new file mode 100644
index 00000000000..52a63af4089
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ttusb2.h
@@ -0,0 +1,70 @@
1/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones
2 * (e.g. Pinnacle 400e DVB-S USB2.0).
3 *
4 * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
5 * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
6 * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.de>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#ifndef _DVB_USB_TTUSB2_H_
15#define _DVB_USB_TTUSB2_H_
16
17/* TTUSB protocol
18 *
19 * always to messages (out/in)
20 * out message:
21 * 0xaa <id> <cmdbyte> <datalen> <data...>
22 *
23 * in message (complete block is always 0x40 bytes long)
24 * 0x55 <id> <cmdbyte> <datalen> <data...>
25 *
26 * id is incremented for each transaction
27 */
28
29#define CMD_DSP_DOWNLOAD 0x13
30/* out data: <byte>[28]
31 * last block must be empty */
32
33#define CMD_DSP_BOOT 0x14
34/* out data: nothing */
35
36#define CMD_POWER 0x15
37/* out data: <on=1/off=0> */
38
39#define CMD_LNB 0x16
40/* out data: <power=1> <18V=0,13V=1> <tone> <??=1> <??=1> */
41
42#define CMD_GET_VERSION 0x17
43/* in data: <version_byte>[5] */
44
45#define CMD_DISEQC 0x18
46/* out data: <master=0xff/burst=??> <cmdlen> <cmdbytes>[cmdlen] */
47
48#define CMD_PID_ENABLE 0x22
49/* out data: <index> <type: ts=1/sec=2> <pid msb> <pid lsb> */
50
51#define CMD_PID_DISABLE 0x23
52/* out data: <index> */
53
54#define CMD_FILTER_ENABLE 0x24
55/* out data: <index> <pid_idx> <filter>[12] <mask>[12] */
56
57#define CMD_FILTER_DISABLE 0x25
58/* out data: <index> */
59
60#define CMD_GET_DSP_VERSION 0x26
61/* in data: <version_byte>[28] */
62
63#define CMD_I2C_XFER 0x31
64/* out data: <addr << 1> <sndlen> <rcvlen> <data>[sndlen]
65 * in data: <addr << 1> <sndlen> <rcvlen> <data>[rcvlen] */
66
67#define CMD_I2C_BITRATE 0x32
68/* out data: <default=0> */
69
70#endif
diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
new file mode 100644
index 00000000000..118aab1a3e5
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -0,0 +1,168 @@
1/* DVB USB framework compliant Linux driver for the HanfTek UMT-010 USB2.0
2 * DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "dibusb.h"
13
14#include "mt352.h"
15
16DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
17
18static int umt_mt352_demod_init(struct dvb_frontend *fe)
19{
20 static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d };
21 static u8 mt352_reset[] = { 0x50, 0x80 };
22 static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
23 static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
24 static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 };
25
26 static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff };
27 static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff };
28 static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 };
29 static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 };
30 static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f };
31
32 static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
33 static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 };
34
35 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
36 udelay(2000);
37 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
38 mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
39
40 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
41 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
42
43 mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1));
44 mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2));
45 mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3));
46 mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4));
47 mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5));
48
49 mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
50 mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
51
52 return 0;
53}
54
55static int umt_mt352_frontend_attach(struct dvb_usb_adapter *adap)
56{
57 struct mt352_config umt_config;
58
59 memset(&umt_config,0,sizeof(struct mt352_config));
60 umt_config.demod_init = umt_mt352_demod_init;
61 umt_config.demod_address = 0xf;
62
63 adap->fe = dvb_attach(mt352_attach, &umt_config, &adap->dev->i2c_adap);
64
65 return 0;
66}
67
68static int umt_tuner_attach (struct dvb_usb_adapter *adap)
69{
70 dvb_attach(dvb_pll_attach, adap->fe, 0x61, NULL, DVB_PLL_TUA6034);
71 return 0;
72}
73
74/* USB Driver stuff */
75static struct dvb_usb_device_properties umt_properties;
76
77static int umt_probe(struct usb_interface *intf,
78 const struct usb_device_id *id)
79{
80 if (0 == dvb_usb_device_init(intf, &umt_properties,
81 THIS_MODULE, NULL, adapter_nr))
82 return 0;
83 return -EINVAL;
84}
85
86/* do not change the order of the ID table */
87static struct usb_device_id umt_table [] = {
88/* 00 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) },
89/* 01 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) },
90 { } /* Terminating entry */
91};
92MODULE_DEVICE_TABLE (usb, umt_table);
93
94static struct dvb_usb_device_properties umt_properties = {
95 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
96
97 .usb_ctrl = CYPRESS_FX2,
98 .firmware = "dvb-usb-umt-010-02.fw",
99
100 .num_adapters = 1,
101 .adapter = {
102 {
103 .streaming_ctrl = dibusb2_0_streaming_ctrl,
104 .frontend_attach = umt_mt352_frontend_attach,
105 .tuner_attach = umt_tuner_attach,
106
107 /* parameter for the MPEG2-data transfer */
108 .stream = {
109 .type = USB_BULK,
110 .count = MAX_NO_URBS_FOR_DATA_STREAM,
111 .endpoint = 0x06,
112 .u = {
113 .bulk = {
114 .buffersize = 512,
115 }
116 }
117 },
118
119 .size_of_priv = sizeof(struct dibusb_state),
120 }
121 },
122 .power_ctrl = dibusb_power_ctrl,
123
124 .i2c_algo = &dibusb_i2c_algo,
125
126 .generic_bulk_ctrl_endpoint = 0x01,
127
128 .num_device_descs = 1,
129 .devices = {
130 { "Hanftek UMT-010 DVB-T USB2.0",
131 { &umt_table[0], NULL },
132 { &umt_table[1], NULL },
133 },
134 }
135};
136
137static struct usb_driver umt_driver = {
138 .name = "dvb_usb_umt_010",
139 .probe = umt_probe,
140 .disconnect = dvb_usb_device_exit,
141 .id_table = umt_table,
142};
143
144/* module stuff */
145static int __init umt_module_init(void)
146{
147 int result;
148 if ((result = usb_register(&umt_driver))) {
149 err("usb_register failed. Error number %d",result);
150 return result;
151 }
152
153 return 0;
154}
155
156static void __exit umt_module_exit(void)
157{
158 /* deregister this driver from the USB subsystem */
159 usb_deregister(&umt_driver);
160}
161
162module_init (umt_module_init);
163module_exit (umt_module_exit);
164
165MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
166MODULE_DESCRIPTION("Driver for HanfTek UMT 010 USB2.0 DVB-T device");
167MODULE_VERSION("1.0");
168MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/usb-urb.c b/drivers/media/dvb/dvb-usb/usb-urb.c
new file mode 100644
index 00000000000..86d68933b6b
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/usb-urb.c
@@ -0,0 +1,254 @@
1/* usb-urb.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file keeps functions for initializing and handling the
7 * BULK and ISOC USB data transfers in a generic way.
8 * Can be used for DVB-only and also, that's the plan, for
9 * Hybrid USB devices (analog and DVB).
10 */
11#include "dvb-usb-common.h"
12
13/* URB stuff for streaming */
14static void usb_urb_complete(struct urb *urb)
15{
16 struct usb_data_stream *stream = urb->context;
17 int ptype = usb_pipetype(urb->pipe);
18 int i;
19 u8 *b;
20
21 deb_uxfer("'%s' urb completed. status: %d, length: %d/%d, pack_num: %d, errors: %d\n",
22 ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk",
23 urb->status,urb->actual_length,urb->transfer_buffer_length,
24 urb->number_of_packets,urb->error_count);
25
26 switch (urb->status) {
27 case 0: /* success */
28 case -ETIMEDOUT: /* NAK */
29 break;
30 case -ECONNRESET: /* kill */
31 case -ENOENT:
32 case -ESHUTDOWN:
33 return;
34 default: /* error */
35 deb_ts("urb completition error %d.\n", urb->status);
36 break;
37 }
38
39 b = (u8 *) urb->transfer_buffer;
40 switch (ptype) {
41 case PIPE_ISOCHRONOUS:
42 for (i = 0; i < urb->number_of_packets; i++) {
43
44 if (urb->iso_frame_desc[i].status != 0)
45 deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
46 else if (urb->iso_frame_desc[i].actual_length > 0)
47 stream->complete(stream, b + urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].actual_length);
48
49 urb->iso_frame_desc[i].status = 0;
50 urb->iso_frame_desc[i].actual_length = 0;
51 }
52 debug_dump(b,20,deb_uxfer);
53 break;
54 case PIPE_BULK:
55 if (urb->actual_length > 0)
56 stream->complete(stream, b, urb->actual_length);
57 break;
58 default:
59 err("unknown endpoint type in completition handler.");
60 return;
61 }
62 usb_submit_urb(urb,GFP_ATOMIC);
63}
64
65int usb_urb_kill(struct usb_data_stream *stream)
66{
67 int i;
68 for (i = 0; i < stream->urbs_submitted; i++) {
69 deb_ts("killing URB no. %d.\n",i);
70
71 /* stop the URB */
72 usb_kill_urb(stream->urb_list[i]);
73 }
74 stream->urbs_submitted = 0;
75 return 0;
76}
77
78int usb_urb_submit(struct usb_data_stream *stream)
79{
80 int i,ret;
81 for (i = 0; i < stream->urbs_initialized; i++) {
82 deb_ts("submitting URB no. %d\n",i);
83 if ((ret = usb_submit_urb(stream->urb_list[i],GFP_ATOMIC))) {
84 err("could not submit URB no. %d - get them all back",i);
85 usb_urb_kill(stream);
86 return ret;
87 }
88 stream->urbs_submitted++;
89 }
90 return 0;
91}
92
93static int usb_free_stream_buffers(struct usb_data_stream *stream)
94{
95 if (stream->state & USB_STATE_URB_BUF) {
96 while (stream->buf_num) {
97 stream->buf_num--;
98 deb_mem("freeing buffer %d\n",stream->buf_num);
99 usb_free_coherent(stream->udev, stream->buf_size,
100 stream->buf_list[stream->buf_num],
101 stream->dma_addr[stream->buf_num]);
102 }
103 }
104
105 stream->state &= ~USB_STATE_URB_BUF;
106
107 return 0;
108}
109
110static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num, unsigned long size)
111{
112 stream->buf_num = 0;
113 stream->buf_size = size;
114
115 deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
116
117 for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
118 deb_mem("allocating buffer %d\n",stream->buf_num);
119 if (( stream->buf_list[stream->buf_num] =
120 usb_alloc_coherent(stream->udev, size, GFP_ATOMIC,
121 &stream->dma_addr[stream->buf_num]) ) == NULL) {
122 deb_mem("not enough memory for urb-buffer allocation.\n");
123 usb_free_stream_buffers(stream);
124 return -ENOMEM;
125 }
126 deb_mem("buffer %d: %p (dma: %Lu)\n",
127 stream->buf_num,
128stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num]);
129 memset(stream->buf_list[stream->buf_num],0,size);
130 stream->state |= USB_STATE_URB_BUF;
131 }
132 deb_mem("allocation successful\n");
133
134 return 0;
135}
136
137static int usb_bulk_urb_init(struct usb_data_stream *stream)
138{
139 int i, j;
140
141 if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
142 stream->props.u.bulk.buffersize)) < 0)
143 return i;
144
145 /* allocate the URBs */
146 for (i = 0; i < stream->props.count; i++) {
147 stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
148 if (!stream->urb_list[i]) {
149 deb_mem("not enough memory for urb_alloc_urb!.\n");
150 for (j = 0; j < i; j++)
151 usb_free_urb(stream->urb_list[i]);
152 return -ENOMEM;
153 }
154 usb_fill_bulk_urb( stream->urb_list[i], stream->udev,
155 usb_rcvbulkpipe(stream->udev,stream->props.endpoint),
156 stream->buf_list[i],
157 stream->props.u.bulk.buffersize,
158 usb_urb_complete, stream);
159
160 stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
161 stream->urb_list[i]->transfer_dma = stream->dma_addr[i];
162 stream->urbs_initialized++;
163 }
164 return 0;
165}
166
167static int usb_isoc_urb_init(struct usb_data_stream *stream)
168{
169 int i,j;
170
171 if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
172 stream->props.u.isoc.framesize*stream->props.u.isoc.framesperurb)) < 0)
173 return i;
174
175 /* allocate the URBs */
176 for (i = 0; i < stream->props.count; i++) {
177 struct urb *urb;
178 int frame_offset = 0;
179
180 stream->urb_list[i] = usb_alloc_urb(stream->props.u.isoc.framesperurb, GFP_ATOMIC);
181 if (!stream->urb_list[i]) {
182 deb_mem("not enough memory for urb_alloc_urb!\n");
183 for (j = 0; j < i; j++)
184 usb_free_urb(stream->urb_list[i]);
185 return -ENOMEM;
186 }
187
188 urb = stream->urb_list[i];
189
190 urb->dev = stream->udev;
191 urb->context = stream;
192 urb->complete = usb_urb_complete;
193 urb->pipe = usb_rcvisocpipe(stream->udev,stream->props.endpoint);
194 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
195 urb->interval = stream->props.u.isoc.interval;
196 urb->number_of_packets = stream->props.u.isoc.framesperurb;
197 urb->transfer_buffer_length = stream->buf_size;
198 urb->transfer_buffer = stream->buf_list[i];
199 urb->transfer_dma = stream->dma_addr[i];
200
201 for (j = 0; j < stream->props.u.isoc.framesperurb; j++) {
202 urb->iso_frame_desc[j].offset = frame_offset;
203 urb->iso_frame_desc[j].length = stream->props.u.isoc.framesize;
204 frame_offset += stream->props.u.isoc.framesize;
205 }
206
207 stream->urbs_initialized++;
208 }
209 return 0;
210}
211
212int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props)
213{
214 if (stream == NULL || props == NULL)
215 return -EINVAL;
216
217 memcpy(&stream->props, props, sizeof(*props));
218
219 usb_clear_halt(stream->udev,usb_rcvbulkpipe(stream->udev,stream->props.endpoint));
220
221 if (stream->complete == NULL) {
222 err("there is no data callback - this doesn't make sense.");
223 return -EINVAL;
224 }
225
226 switch (stream->props.type) {
227 case USB_BULK:
228 return usb_bulk_urb_init(stream);
229 case USB_ISOC:
230 return usb_isoc_urb_init(stream);
231 default:
232 err("unknown URB-type for data transfer.");
233 return -EINVAL;
234 }
235}
236
237int usb_urb_exit(struct usb_data_stream *stream)
238{
239 int i;
240
241 usb_urb_kill(stream);
242
243 for (i = 0; i < stream->urbs_initialized; i++) {
244 if (stream->urb_list[i] != NULL) {
245 deb_mem("freeing URB no. %d.\n",i);
246 /* free the URBs */
247 usb_free_urb(stream->urb_list[i]);
248 }
249 }
250 stream->urbs_initialized = 0;
251
252 usb_free_stream_buffers(stream);
253 return 0;
254}
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c
new file mode 100644
index 00000000000..2bb8d4cc8d8
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c
@@ -0,0 +1,387 @@
1/* DVB frontend part of the Linux driver for the TwinhanDTV StarBox USB2.0
2 * DVB-S receiver.
3 *
4 * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
5 * Metzler Brothers Systementwicklung GbR
6 *
7 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
8 *
9 * Thanks to Twinhan who kindly provided hardware and information.
10 *
11 * This file can be removed soon, after the DST-driver is rewritten to provice
12 * the frontend-controlling separately.
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the Free
16 * Software Foundation, version 2.
17 *
18 * see Documentation/dvb/README.dvb-usb for more information
19 *
20 */
21#include "vp702x.h"
22
23struct vp702x_fe_state {
24 struct dvb_frontend fe;
25 struct dvb_usb_device *d;
26
27 struct dvb_frontend_ops ops;
28
29 fe_sec_voltage_t voltage;
30 fe_sec_tone_mode_t tone_mode;
31
32 u8 lnb_buf[8];
33
34 u8 lock;
35 u8 sig;
36 u8 snr;
37
38 unsigned long next_status_check;
39 unsigned long status_check_interval;
40};
41
42static int vp702x_fe_refresh_state(struct vp702x_fe_state *st)
43{
44 struct vp702x_device_state *dst = st->d->priv;
45 u8 *buf;
46
47 if (time_after(jiffies, st->next_status_check)) {
48 mutex_lock(&dst->buf_mutex);
49 buf = dst->buf;
50
51 vp702x_usb_in_op(st->d, READ_STATUS, 0, 0, buf, 10);
52 st->lock = buf[4];
53
54 vp702x_usb_in_op(st->d, READ_TUNER_REG_REQ, 0x11, 0, buf, 1);
55 st->snr = buf[0];
56
57 vp702x_usb_in_op(st->d, READ_TUNER_REG_REQ, 0x15, 0, buf, 1);
58 st->sig = buf[0];
59
60 mutex_unlock(&dst->buf_mutex);
61 st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
62 }
63 return 0;
64}
65
66static u8 vp702x_chksum(u8 *buf,int f, int count)
67{
68 u8 s = 0;
69 int i;
70 for (i = f; i < f+count; i++)
71 s += buf[i];
72 return ~s+1;
73}
74
75static int vp702x_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
76{
77 struct vp702x_fe_state *st = fe->demodulator_priv;
78 vp702x_fe_refresh_state(st);
79 deb_fe("%s\n",__func__);
80
81 if (st->lock == 0)
82 *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
83 else
84 *status = 0;
85
86 if (*status & FE_HAS_LOCK)
87 st->status_check_interval = 1000;
88 else
89 st->status_check_interval = 250;
90 return 0;
91}
92
93/* not supported by this Frontend */
94static int vp702x_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
95{
96 struct vp702x_fe_state *st = fe->demodulator_priv;
97 vp702x_fe_refresh_state(st);
98 *ber = 0;
99 return 0;
100}
101
102/* not supported by this Frontend */
103static int vp702x_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
104{
105 struct vp702x_fe_state *st = fe->demodulator_priv;
106 vp702x_fe_refresh_state(st);
107 *unc = 0;
108 return 0;
109}
110
111static int vp702x_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
112{
113 struct vp702x_fe_state *st = fe->demodulator_priv;
114 vp702x_fe_refresh_state(st);
115
116 *strength = (st->sig << 8) | st->sig;
117 return 0;
118}
119
120static int vp702x_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
121{
122 u8 _snr;
123 struct vp702x_fe_state *st = fe->demodulator_priv;
124 vp702x_fe_refresh_state(st);
125
126 _snr = (st->snr & 0x1f) * 0xff / 0x1f;
127 *snr = (_snr << 8) | _snr;
128 return 0;
129}
130
131static int vp702x_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
132{
133 deb_fe("%s\n",__func__);
134 tune->min_delay_ms = 2000;
135 return 0;
136}
137
138static int vp702x_fe_set_frontend(struct dvb_frontend* fe,
139 struct dvb_frontend_parameters *fep)
140{
141 struct vp702x_fe_state *st = fe->demodulator_priv;
142 struct vp702x_device_state *dst = st->d->priv;
143 u32 freq = fep->frequency/1000;
144 /*CalFrequency*/
145/* u16 frequencyRef[16] = { 2, 4, 8, 16, 32, 64, 128, 256, 24, 5, 10, 20, 40, 80, 160, 320 }; */
146 u64 sr;
147 u8 *cmd;
148
149 mutex_lock(&dst->buf_mutex);
150
151 cmd = dst->buf;
152 memset(cmd, 0, 10);
153
154 cmd[0] = (freq >> 8) & 0x7f;
155 cmd[1] = freq & 0xff;
156 cmd[2] = 1; /* divrate == 4 -> frequencyRef[1] -> 1 here */
157
158 sr = (u64) (fep->u.qpsk.symbol_rate/1000) << 20;
159 do_div(sr,88000);
160 cmd[3] = (sr >> 12) & 0xff;
161 cmd[4] = (sr >> 4) & 0xff;
162 cmd[5] = (sr << 4) & 0xf0;
163
164 deb_fe("setting frontend to: %u -> %u (%x) LNB-based GHz, symbolrate: %d -> %lu (%lx)\n",
165 fep->frequency,freq,freq, fep->u.qpsk.symbol_rate,
166 (unsigned long) sr, (unsigned long) sr);
167
168/* if (fep->inversion == INVERSION_ON)
169 cmd[6] |= 0x80; */
170
171 if (st->voltage == SEC_VOLTAGE_18)
172 cmd[6] |= 0x40;
173
174/* if (fep->u.qpsk.symbol_rate > 8000000)
175 cmd[6] |= 0x20;
176
177 if (fep->frequency < 1531000)
178 cmd[6] |= 0x04;
179
180 if (st->tone_mode == SEC_TONE_ON)
181 cmd[6] |= 0x01;*/
182
183 cmd[7] = vp702x_chksum(cmd,0,7);
184
185 st->status_check_interval = 250;
186 st->next_status_check = jiffies;
187
188 vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
189
190 if (cmd[2] == 0 && cmd[3] == 0)
191 deb_fe("tuning failed.\n");
192 else
193 deb_fe("tuning succeeded.\n");
194
195 mutex_unlock(&dst->buf_mutex);
196
197 return 0;
198}
199
200static int vp702x_fe_init(struct dvb_frontend *fe)
201{
202 struct vp702x_fe_state *st = fe->demodulator_priv;
203 deb_fe("%s\n",__func__);
204 vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0);
205 return 0;
206}
207
208static int vp702x_fe_sleep(struct dvb_frontend *fe)
209{
210 deb_fe("%s\n",__func__);
211 return 0;
212}
213
214static int vp702x_fe_get_frontend(struct dvb_frontend* fe,
215 struct dvb_frontend_parameters *fep)
216{
217 deb_fe("%s\n",__func__);
218 return 0;
219}
220
221static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
222 struct dvb_diseqc_master_cmd *m)
223{
224 u8 *cmd;
225 struct vp702x_fe_state *st = fe->demodulator_priv;
226 struct vp702x_device_state *dst = st->d->priv;
227
228 deb_fe("%s\n",__func__);
229
230 if (m->msg_len > 4)
231 return -EINVAL;
232
233 mutex_lock(&dst->buf_mutex);
234
235 cmd = dst->buf;
236 cmd[1] = SET_DISEQC_CMD;
237 cmd[2] = m->msg_len;
238 memcpy(&cmd[3], m->msg, m->msg_len);
239 cmd[7] = vp702x_chksum(cmd, 0, 7);
240
241 vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
242
243 if (cmd[2] == 0 && cmd[3] == 0)
244 deb_fe("diseqc cmd failed.\n");
245 else
246 deb_fe("diseqc cmd succeeded.\n");
247
248 mutex_unlock(&dst->buf_mutex);
249
250 return 0;
251}
252
253static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
254{
255 deb_fe("%s\n",__func__);
256 return 0;
257}
258
259static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
260{
261 struct vp702x_fe_state *st = fe->demodulator_priv;
262 struct vp702x_device_state *dst = st->d->priv;
263 u8 *buf;
264
265 deb_fe("%s\n",__func__);
266
267 st->tone_mode = tone;
268
269 if (tone == SEC_TONE_ON)
270 st->lnb_buf[2] = 0x02;
271 else
272 st->lnb_buf[2] = 0x00;
273
274 st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
275
276 mutex_lock(&dst->buf_mutex);
277
278 buf = dst->buf;
279 memcpy(buf, st->lnb_buf, 8);
280
281 vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
282 if (buf[2] == 0 && buf[3] == 0)
283 deb_fe("set_tone cmd failed.\n");
284 else
285 deb_fe("set_tone cmd succeeded.\n");
286
287 mutex_unlock(&dst->buf_mutex);
288
289 return 0;
290}
291
292static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t
293 voltage)
294{
295 struct vp702x_fe_state *st = fe->demodulator_priv;
296 struct vp702x_device_state *dst = st->d->priv;
297 u8 *buf;
298 deb_fe("%s\n",__func__);
299
300 st->voltage = voltage;
301
302 if (voltage != SEC_VOLTAGE_OFF)
303 st->lnb_buf[4] = 0x01;
304 else
305 st->lnb_buf[4] = 0x00;
306
307 st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
308
309 mutex_lock(&dst->buf_mutex);
310
311 buf = dst->buf;
312 memcpy(buf, st->lnb_buf, 8);
313
314 vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
315 if (buf[2] == 0 && buf[3] == 0)
316 deb_fe("set_voltage cmd failed.\n");
317 else
318 deb_fe("set_voltage cmd succeeded.\n");
319
320 mutex_unlock(&dst->buf_mutex);
321 return 0;
322}
323
324static void vp702x_fe_release(struct dvb_frontend* fe)
325{
326 struct vp702x_fe_state *st = fe->demodulator_priv;
327 kfree(st);
328}
329
330static struct dvb_frontend_ops vp702x_fe_ops;
331
332struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d)
333{
334 struct vp702x_fe_state *s = kzalloc(sizeof(struct vp702x_fe_state), GFP_KERNEL);
335 if (s == NULL)
336 goto error;
337
338 s->d = d;
339
340 memcpy(&s->fe.ops,&vp702x_fe_ops,sizeof(struct dvb_frontend_ops));
341 s->fe.demodulator_priv = s;
342
343 s->lnb_buf[1] = SET_LNB_POWER;
344 s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */
345
346 return &s->fe;
347error:
348 return NULL;
349}
350
351
352static struct dvb_frontend_ops vp702x_fe_ops = {
353 .info = {
354 .name = "Twinhan DST-like frontend (VP7021/VP7020) DVB-S",
355 .type = FE_QPSK,
356 .frequency_min = 950000,
357 .frequency_max = 2150000,
358 .frequency_stepsize = 1000, /* kHz for QPSK frontends */
359 .frequency_tolerance = 0,
360 .symbol_rate_min = 1000000,
361 .symbol_rate_max = 45000000,
362 .symbol_rate_tolerance = 500, /* ppm */
363 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
364 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
365 FE_CAN_QPSK |
366 FE_CAN_FEC_AUTO
367 },
368 .release = vp702x_fe_release,
369
370 .init = vp702x_fe_init,
371 .sleep = vp702x_fe_sleep,
372
373 .set_frontend = vp702x_fe_set_frontend,
374 .get_frontend = vp702x_fe_get_frontend,
375 .get_tune_settings = vp702x_fe_get_tune_settings,
376
377 .read_status = vp702x_fe_read_status,
378 .read_ber = vp702x_fe_read_ber,
379 .read_signal_strength = vp702x_fe_read_signal_strength,
380 .read_snr = vp702x_fe_read_snr,
381 .read_ucblocks = vp702x_fe_read_unc_blocks,
382
383 .diseqc_send_master_cmd = vp702x_fe_send_diseqc_msg,
384 .diseqc_send_burst = vp702x_fe_send_diseqc_burst,
385 .set_tone = vp702x_fe_set_tone,
386 .set_voltage = vp702x_fe_set_voltage,
387};
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c
new file mode 100644
index 00000000000..54355f84a98
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp702x.c
@@ -0,0 +1,460 @@
1/* DVB USB compliant Linux driver for the TwinhanDTV StarBox USB2.0 DVB-S
2 * receiver.
3 *
4 * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
5 * Metzler Brothers Systementwicklung GbR
6 *
7 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
8 *
9 * Thanks to Twinhan who kindly provided hardware and information.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation, version 2.
14 *
15 * see Documentation/dvb/README.dvb-usb for more information
16 */
17#include "vp702x.h"
18#include <linux/mutex.h>
19
20/* debug */
21int dvb_usb_vp702x_debug;
22module_param_named(debug,dvb_usb_vp702x_debug, int, 0644);
23MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
24
25DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
26
27struct vp702x_adapter_state {
28 int pid_filter_count;
29 int pid_filter_can_bypass;
30 u8 pid_filter_state;
31};
32
33static int vp702x_usb_in_op_unlocked(struct dvb_usb_device *d, u8 req,
34 u16 value, u16 index, u8 *b, int blen)
35{
36 int ret;
37
38 ret = usb_control_msg(d->udev,
39 usb_rcvctrlpipe(d->udev, 0),
40 req,
41 USB_TYPE_VENDOR | USB_DIR_IN,
42 value, index, b, blen,
43 2000);
44
45 if (ret < 0) {
46 warn("usb in operation failed. (%d)", ret);
47 ret = -EIO;
48 } else
49 ret = 0;
50
51
52 deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
53 debug_dump(b,blen,deb_xfer);
54
55 return ret;
56}
57
58int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
59 u16 index, u8 *b, int blen)
60{
61 int ret;
62
63 mutex_lock(&d->usb_mutex);
64 ret = vp702x_usb_in_op_unlocked(d, req, value, index, b, blen);
65 mutex_unlock(&d->usb_mutex);
66
67 return ret;
68}
69
70int vp702x_usb_out_op_unlocked(struct dvb_usb_device *d, u8 req, u16 value,
71 u16 index, u8 *b, int blen)
72{
73 int ret;
74 deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
75 debug_dump(b,blen,deb_xfer);
76
77 if ((ret = usb_control_msg(d->udev,
78 usb_sndctrlpipe(d->udev,0),
79 req,
80 USB_TYPE_VENDOR | USB_DIR_OUT,
81 value,index,b,blen,
82 2000)) != blen) {
83 warn("usb out operation failed. (%d)",ret);
84 return -EIO;
85 } else
86 return 0;
87}
88
89int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
90 u16 index, u8 *b, int blen)
91{
92 int ret;
93
94 mutex_lock(&d->usb_mutex);
95 ret = vp702x_usb_out_op_unlocked(d, req, value, index, b, blen);
96 mutex_unlock(&d->usb_mutex);
97
98 return ret;
99}
100
101int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec)
102{
103 int ret;
104
105 if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
106 return ret;
107
108 ret = vp702x_usb_out_op_unlocked(d, REQUEST_OUT, 0, 0, o, olen);
109 msleep(msec);
110 ret = vp702x_usb_in_op_unlocked(d, REQUEST_IN, 0, 0, i, ilen);
111
112 mutex_unlock(&d->usb_mutex);
113 return ret;
114}
115
116static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o,
117 int olen, u8 *i, int ilen, int msec)
118{
119 struct vp702x_device_state *st = d->priv;
120 int ret = 0;
121 u8 *buf;
122 int buflen = max(olen + 2, ilen + 1);
123
124 ret = mutex_lock_interruptible(&st->buf_mutex);
125 if (ret < 0)
126 return ret;
127
128 if (buflen > st->buf_len) {
129 buf = kmalloc(buflen, GFP_KERNEL);
130 if (!buf) {
131 mutex_unlock(&st->buf_mutex);
132 return -ENOMEM;
133 }
134 info("successfully reallocated a bigger buffer");
135 kfree(st->buf);
136 st->buf = buf;
137 st->buf_len = buflen;
138 } else {
139 buf = st->buf;
140 }
141
142 buf[0] = 0x00;
143 buf[1] = cmd;
144 memcpy(&buf[2], o, olen);
145
146 ret = vp702x_usb_inout_op(d, buf, olen+2, buf, ilen+1, msec);
147
148 if (ret == 0)
149 memcpy(i, &buf[1], ilen);
150 mutex_unlock(&st->buf_mutex);
151
152 return ret;
153}
154
155static int vp702x_set_pld_mode(struct dvb_usb_adapter *adap, u8 bypass)
156{
157 int ret;
158 struct vp702x_device_state *st = adap->dev->priv;
159 u8 *buf;
160
161 mutex_lock(&st->buf_mutex);
162
163 buf = st->buf;
164 memset(buf, 0, 16);
165
166 ret = vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e,
167 0, buf, 16);
168 mutex_unlock(&st->buf_mutex);
169 return ret;
170}
171
172static int vp702x_set_pld_state(struct dvb_usb_adapter *adap, u8 state)
173{
174 int ret;
175 struct vp702x_device_state *st = adap->dev->priv;
176 u8 *buf;
177
178 mutex_lock(&st->buf_mutex);
179
180 buf = st->buf;
181 memset(buf, 0, 16);
182 ret = vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f,
183 0, buf, 16);
184
185 mutex_unlock(&st->buf_mutex);
186
187 return ret;
188}
189
190static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onoff)
191{
192 struct vp702x_adapter_state *st = adap->priv;
193 struct vp702x_device_state *dst = adap->dev->priv;
194 u8 *buf;
195
196 if (onoff)
197 st->pid_filter_state |= (1 << id);
198 else {
199 st->pid_filter_state &= ~(1 << id);
200 pid = 0xffff;
201 }
202
203 id = 0x10 + id*2;
204
205 vp702x_set_pld_state(adap, st->pid_filter_state);
206
207 mutex_lock(&dst->buf_mutex);
208
209 buf = dst->buf;
210 memset(buf, 0, 16);
211 vp702x_usb_in_op(adap->dev, 0xe0, (((pid >> 8) & 0xff) << 8) | (id), 0, buf, 16);
212 vp702x_usb_in_op(adap->dev, 0xe0, (((pid ) & 0xff) << 8) | (id+1), 0, buf, 16);
213
214 mutex_unlock(&dst->buf_mutex);
215
216 return 0;
217}
218
219
220static int vp702x_init_pid_filter(struct dvb_usb_adapter *adap)
221{
222 struct vp702x_adapter_state *st = adap->priv;
223 struct vp702x_device_state *dst = adap->dev->priv;
224 int i;
225 u8 *b;
226
227 st->pid_filter_count = 8;
228 st->pid_filter_can_bypass = 1;
229 st->pid_filter_state = 0x00;
230
231 vp702x_set_pld_mode(adap, 1); /* bypass */
232
233 for (i = 0; i < st->pid_filter_count; i++)
234 vp702x_set_pid(adap, 0xffff, i, 1);
235
236 mutex_lock(&dst->buf_mutex);
237 b = dst->buf;
238 memset(b, 0, 10);
239 vp702x_usb_in_op(adap->dev, 0xb5, 3, 0, b, 10);
240 vp702x_usb_in_op(adap->dev, 0xb5, 0, 0, b, 10);
241 vp702x_usb_in_op(adap->dev, 0xb5, 1, 0, b, 10);
242 mutex_unlock(&dst->buf_mutex);
243 /*vp702x_set_pld_mode(d, 0); // filter */
244
245 return 0;
246}
247
248static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
249{
250 return 0;
251}
252
253/* keys for the enclosed remote control */
254static struct rc_map_table rc_map_vp702x_table[] = {
255 { 0x0001, KEY_1 },
256 { 0x0002, KEY_2 },
257};
258
259/* remote control stuff (does not work with my box) */
260static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
261{
262 u8 *key;
263 int i;
264
265/* remove the following return to enabled remote querying */
266 return 0;
267
268 key = kmalloc(10, GFP_KERNEL);
269 if (!key)
270 return -ENOMEM;
271
272 vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10);
273
274 deb_rc("remote query key: %x %d\n",key[1],key[1]);
275
276 if (key[1] == 0x44) {
277 *state = REMOTE_NO_KEY_PRESSED;
278 kfree(key);
279 return 0;
280 }
281
282 for (i = 0; i < ARRAY_SIZE(rc_map_vp702x_table); i++)
283 if (rc5_custom(&rc_map_vp702x_table[i]) == key[1]) {
284 *state = REMOTE_KEY_PRESSED;
285 *event = rc_map_vp702x_table[i].keycode;
286 break;
287 }
288 kfree(key);
289 return 0;
290}
291
292
293static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
294{
295 u8 i, *buf;
296 struct vp702x_device_state *st = d->priv;
297
298 mutex_lock(&st->buf_mutex);
299 buf = st->buf;
300 for (i = 6; i < 12; i++)
301 vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &buf[i - 6], 1);
302
303 memcpy(mac, buf, 6);
304 mutex_unlock(&st->buf_mutex);
305 return 0;
306}
307
308static int vp702x_frontend_attach(struct dvb_usb_adapter *adap)
309{
310 u8 buf[10] = { 0 };
311
312 vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 0, 7, NULL, 0);
313
314 if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0,
315 buf, 10, 10))
316 return -EIO;
317
318 buf[9] = '\0';
319 info("system string: %s",&buf[1]);
320
321 vp702x_init_pid_filter(adap);
322
323 adap->fe = vp702x_fe_attach(adap->dev);
324 vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 1, 7, NULL, 0);
325
326 return 0;
327}
328
329static struct dvb_usb_device_properties vp702x_properties;
330
331static int vp702x_usb_probe(struct usb_interface *intf,
332 const struct usb_device_id *id)
333{
334 struct dvb_usb_device *d;
335 struct vp702x_device_state *st;
336 int ret;
337
338 ret = dvb_usb_device_init(intf, &vp702x_properties,
339 THIS_MODULE, &d, adapter_nr);
340 if (ret)
341 goto out;
342
343 st = d->priv;
344 st->buf_len = 16;
345 st->buf = kmalloc(st->buf_len, GFP_KERNEL);
346 if (!st->buf) {
347 ret = -ENOMEM;
348 dvb_usb_device_exit(intf);
349 goto out;
350 }
351 mutex_init(&st->buf_mutex);
352
353out:
354 return ret;
355
356}
357
358static void vp702x_usb_disconnect(struct usb_interface *intf)
359{
360 struct dvb_usb_device *d = usb_get_intfdata(intf);
361 struct vp702x_device_state *st = d->priv;
362 mutex_lock(&st->buf_mutex);
363 kfree(st->buf);
364 mutex_unlock(&st->buf_mutex);
365 dvb_usb_device_exit(intf);
366}
367
368static struct usb_device_id vp702x_usb_table [] = {
369 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_COLD) },
370// { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_COLD) },
371// { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_WARM) },
372 { 0 },
373};
374MODULE_DEVICE_TABLE(usb, vp702x_usb_table);
375
376static struct dvb_usb_device_properties vp702x_properties = {
377 .usb_ctrl = CYPRESS_FX2,
378 .firmware = "dvb-usb-vp702x-02.fw",
379 .no_reconnect = 1,
380
381 .size_of_priv = sizeof(struct vp702x_device_state),
382
383 .num_adapters = 1,
384 .adapter = {
385 {
386 .caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS,
387
388 .streaming_ctrl = vp702x_streaming_ctrl,
389 .frontend_attach = vp702x_frontend_attach,
390
391 /* parameter for the MPEG2-data transfer */
392 .stream = {
393 .type = USB_BULK,
394 .count = 10,
395 .endpoint = 0x02,
396 .u = {
397 .bulk = {
398 .buffersize = 4096,
399 }
400 }
401 },
402 .size_of_priv = sizeof(struct vp702x_adapter_state),
403 }
404 },
405 .read_mac_address = vp702x_read_mac_addr,
406
407 .rc.legacy = {
408 .rc_map_table = rc_map_vp702x_table,
409 .rc_map_size = ARRAY_SIZE(rc_map_vp702x_table),
410 .rc_interval = 400,
411 .rc_query = vp702x_rc_query,
412 },
413
414 .num_device_descs = 1,
415 .devices = {
416 { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7021)",
417 .cold_ids = { &vp702x_usb_table[0], NULL },
418 .warm_ids = { NULL },
419 },
420/* { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7020)",
421 .cold_ids = { &vp702x_usb_table[2], NULL },
422 .warm_ids = { &vp702x_usb_table[3], NULL },
423 },
424*/ { NULL },
425 }
426};
427
428/* usb specific object needed to register this driver with the usb subsystem */
429static struct usb_driver vp702x_usb_driver = {
430 .name = "dvb_usb_vp702x",
431 .probe = vp702x_usb_probe,
432 .disconnect = vp702x_usb_disconnect,
433 .id_table = vp702x_usb_table,
434};
435
436/* module stuff */
437static int __init vp702x_usb_module_init(void)
438{
439 int result;
440 if ((result = usb_register(&vp702x_usb_driver))) {
441 err("usb_register failed. (%d)",result);
442 return result;
443 }
444
445 return 0;
446}
447
448static void __exit vp702x_usb_module_exit(void)
449{
450 /* deregister this driver from the USB subsystem */
451 usb_deregister(&vp702x_usb_driver);
452}
453
454module_init(vp702x_usb_module_init);
455module_exit(vp702x_usb_module_exit);
456
457MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
458MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones");
459MODULE_VERSION("1.0");
460MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h
new file mode 100644
index 00000000000..20b90055e7a
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp702x.h
@@ -0,0 +1,113 @@
1#ifndef _DVB_USB_VP7021_H_
2#define _DVB_USB_VP7021_H_
3
4#define DVB_USB_LOG_PREFIX "vp702x"
5#include "dvb-usb.h"
6
7extern int dvb_usb_vp702x_debug;
8#define deb_info(args...) dprintk(dvb_usb_vp702x_debug,0x01,args)
9#define deb_xfer(args...) dprintk(dvb_usb_vp702x_debug,0x02,args)
10#define deb_rc(args...) dprintk(dvb_usb_vp702x_debug,0x04,args)
11#define deb_fe(args...) dprintk(dvb_usb_vp702x_debug,0x08,args)
12
13/* commands are read and written with USB control messages */
14
15/* consecutive read/write operation */
16#define REQUEST_OUT 0xB2
17#define REQUEST_IN 0xB3
18
19/* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0
20 * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer
21 * the returning buffer looks as follows
22 * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */
23
24#define GET_TUNER_STATUS 0x05
25/* additional in buffer:
26 * 0 1 2 3 4 5 6 7 8
27 * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */
28
29#define GET_SYSTEM_STRING 0x06
30/* additional in buffer:
31 * 0 1 2 3 4 5 6 7 8
32 * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */
33
34#define SET_DISEQC_CMD 0x08
35/* additional out buffer:
36 * 0 1 2 3 4
37 * len X1 X2 X3 X4
38 * additional in buffer:
39 * 0 1 2
40 * N/A 0 0 b[1] == b[2] == 0 -> success, failure otherwise */
41
42#define SET_LNB_POWER 0x09
43/* additional out buffer:
44 * 0 1 2
45 * 0x00 0xff 1 = on, 0 = off
46 * additional in buffer:
47 * 0 1 2
48 * N/A 0 0 b[1] == b[2] == 0 -> success failure otherwise */
49
50#define GET_MAC_ADDRESS 0x0A
51/* #define GET_MAC_ADDRESS 0x0B */
52/* additional in buffer:
53 * 0 1 2 3 4 5 6 7 8
54 * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */
55
56#define SET_PID_FILTER 0x11
57/* additional in buffer:
58 * 0 1 ... 14 15 16
59 * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */
60
61/* request: 0xB2; i: 0; v: 0;
62 * b[0] != 0 -> tune and lock a channel
63 * 0 1 2 3 4 5 6 7
64 * freq0 freq1 divstep srate0 srate1 srate2 flag chksum
65 */
66
67/* one direction requests */
68#define READ_REMOTE_REQ 0xB4
69/* IN i: 0; v: 0; b[0] == request, b[1] == key */
70
71#define READ_PID_NUMBER_REQ 0xB5
72/* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */
73
74#define WRITE_EEPROM_REQ 0xB6
75/* OUT i: offset; v: value to write; no extra buffer */
76
77#define READ_EEPROM_REQ 0xB7
78/* IN i: bufferlen; v: offset; buffer with bufferlen bytes */
79
80#define READ_STATUS 0xB8
81/* IN i: 0; v: 0; bufferlen 10 */
82
83#define READ_TUNER_REG_REQ 0xB9
84/* IN i: 0; v: register; b[0] = value */
85
86#define READ_FX2_REG_REQ 0xBA
87/* IN i: offset; v: 0; b[0] = value */
88
89#define WRITE_FX2_REG_REQ 0xBB
90/* OUT i: offset; v: value to write; 1 byte extra buffer */
91
92#define SET_TUNER_POWER_REQ 0xBC
93/* IN i: 0 = power off, 1 = power on */
94
95#define WRITE_TUNER_REG_REQ 0xBD
96/* IN i: register, v: value to write, no extra buffer */
97
98#define RESET_TUNER 0xBE
99/* IN i: 0, v: 0, no extra buffer */
100
101struct vp702x_device_state {
102 struct mutex buf_mutex;
103 int buf_len;
104 u8 *buf;
105};
106
107
108extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
109
110extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
111extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
112
113#endif
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c
new file mode 100644
index 00000000000..8452eef9032
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c
@@ -0,0 +1,192 @@
1/* DVB frontend part of the Linux driver for TwinhanDTV Alpha/MagicBoxII USB2.0
2 * DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to Twinhan who kindly provided hardware and information.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 *
14 */
15#include "vp7045.h"
16
17/* It is a Zarlink MT352 within a Samsung Tuner (DNOS404ZH102A) - 040929 - AAT
18 *
19 * Programming is hidden inside the firmware, so set_frontend is very easy.
20 * Even though there is a Firmware command that one can use to access the demod
21 * via its registers. This is used for status information.
22 */
23
24struct vp7045_fe_state {
25 struct dvb_frontend fe;
26 struct dvb_usb_device *d;
27};
28
29static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
30{
31 struct vp7045_fe_state *state = fe->demodulator_priv;
32 u8 s0 = vp7045_read_reg(state->d,0x00),
33 s1 = vp7045_read_reg(state->d,0x01),
34 s3 = vp7045_read_reg(state->d,0x03);
35
36 *status = 0;
37 if (s0 & (1 << 4))
38 *status |= FE_HAS_CARRIER;
39 if (s0 & (1 << 1))
40 *status |= FE_HAS_VITERBI;
41 if (s0 & (1 << 5))
42 *status |= FE_HAS_LOCK;
43 if (s1 & (1 << 1))
44 *status |= FE_HAS_SYNC;
45 if (s3 & (1 << 6))
46 *status |= FE_HAS_SIGNAL;
47
48 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
49 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
50 *status &= ~FE_HAS_LOCK;
51
52 return 0;
53}
54
55static int vp7045_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
56{
57 struct vp7045_fe_state *state = fe->demodulator_priv;
58 *ber = (vp7045_read_reg(state->d, 0x0D) << 16) |
59 (vp7045_read_reg(state->d, 0x0E) << 8) |
60 vp7045_read_reg(state->d, 0x0F);
61 return 0;
62}
63
64static int vp7045_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
65{
66 struct vp7045_fe_state *state = fe->demodulator_priv;
67 *unc = (vp7045_read_reg(state->d, 0x10) << 8) |
68 vp7045_read_reg(state->d, 0x11);
69 return 0;
70}
71
72static int vp7045_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
73{
74 struct vp7045_fe_state *state = fe->demodulator_priv;
75 u16 signal = (vp7045_read_reg(state->d, 0x14) << 8) |
76 vp7045_read_reg(state->d, 0x15);
77
78 *strength = ~signal;
79 return 0;
80}
81
82static int vp7045_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
83{
84 struct vp7045_fe_state *state = fe->demodulator_priv;
85 u8 _snr = vp7045_read_reg(state->d, 0x09);
86 *snr = (_snr << 8) | _snr;
87 return 0;
88}
89
90static int vp7045_fe_init(struct dvb_frontend* fe)
91{
92 return 0;
93}
94
95static int vp7045_fe_sleep(struct dvb_frontend* fe)
96{
97 return 0;
98}
99
100static int vp7045_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
101{
102 tune->min_delay_ms = 800;
103 return 0;
104}
105
106static int vp7045_fe_set_frontend(struct dvb_frontend* fe,
107 struct dvb_frontend_parameters *fep)
108{
109 struct vp7045_fe_state *state = fe->demodulator_priv;
110 u8 buf[5];
111 u32 freq = fep->frequency / 1000;
112
113 buf[0] = (freq >> 16) & 0xff;
114 buf[1] = (freq >> 8) & 0xff;
115 buf[2] = freq & 0xff;
116 buf[3] = 0;
117
118 switch (fep->u.ofdm.bandwidth) {
119 case BANDWIDTH_8_MHZ: buf[4] = 8; break;
120 case BANDWIDTH_7_MHZ: buf[4] = 7; break;
121 case BANDWIDTH_6_MHZ: buf[4] = 6; break;
122 case BANDWIDTH_AUTO: return -EOPNOTSUPP;
123 default:
124 return -EINVAL;
125 }
126
127 vp7045_usb_op(state->d,LOCK_TUNER_COMMAND,buf,5,NULL,0,200);
128 return 0;
129}
130
131static int vp7045_fe_get_frontend(struct dvb_frontend* fe,
132 struct dvb_frontend_parameters *fep)
133{
134 return 0;
135}
136
137static void vp7045_fe_release(struct dvb_frontend* fe)
138{
139 struct vp7045_fe_state *state = fe->demodulator_priv;
140 kfree(state);
141}
142
143static struct dvb_frontend_ops vp7045_fe_ops;
144
145struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
146{
147 struct vp7045_fe_state *s = kzalloc(sizeof(struct vp7045_fe_state), GFP_KERNEL);
148 if (s == NULL)
149 goto error;
150
151 s->d = d;
152 memcpy(&s->fe.ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops));
153 s->fe.demodulator_priv = s;
154
155 return &s->fe;
156error:
157 return NULL;
158}
159
160
161static struct dvb_frontend_ops vp7045_fe_ops = {
162 .info = {
163 .name = "Twinhan VP7045/46 USB DVB-T",
164 .type = FE_OFDM,
165 .frequency_min = 44250000,
166 .frequency_max = 867250000,
167 .frequency_stepsize = 1000,
168 .caps = FE_CAN_INVERSION_AUTO |
169 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
170 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
171 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
172 FE_CAN_TRANSMISSION_MODE_AUTO |
173 FE_CAN_GUARD_INTERVAL_AUTO |
174 FE_CAN_RECOVER |
175 FE_CAN_HIERARCHY_AUTO,
176 },
177
178 .release = vp7045_fe_release,
179
180 .init = vp7045_fe_init,
181 .sleep = vp7045_fe_sleep,
182
183 .set_frontend = vp7045_fe_set_frontend,
184 .get_frontend = vp7045_fe_get_frontend,
185 .get_tune_settings = vp7045_fe_get_tune_settings,
186
187 .read_status = vp7045_fe_read_status,
188 .read_ber = vp7045_fe_read_ber,
189 .read_signal_strength = vp7045_fe_read_signal_strength,
190 .read_snr = vp7045_fe_read_snr,
191 .read_ucblocks = vp7045_fe_read_unc_blocks,
192};
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
new file mode 100644
index 00000000000..536c16c943b
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -0,0 +1,318 @@
1/* DVB USB compliant Linux driver for the
2 * - TwinhanDTV Alpha/MagicBoxII USB2.0 DVB-T receiver
3 * - DigitalNow TinyUSB2 DVB-t receiver
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * Thanks to Twinhan who kindly provided hardware and information.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation, version 2.
12 *
13 * see Documentation/dvb/README.dvb-usb for more information
14 */
15#include "vp7045.h"
16
17/* debug */
18static int dvb_usb_vp7045_debug;
19module_param_named(debug,dvb_usb_vp7045_debug, int, 0644);
20MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
21
22DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
23
24#define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args)
25#define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args)
26#define deb_rc(args...) dprintk(dvb_usb_vp7045_debug,0x04,args)
27
28int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec)
29{
30 int ret = 0;
31 u8 *buf = d->priv;
32
33 buf[0] = cmd;
34
35 if (outlen > 19)
36 outlen = 19;
37
38 if (inlen > 11)
39 inlen = 11;
40
41 ret = mutex_lock_interruptible(&d->usb_mutex);
42 if (ret)
43 return ret;
44
45 if (out != NULL && outlen > 0)
46 memcpy(&buf[1], out, outlen);
47
48 deb_xfer("out buffer: ");
49 debug_dump(buf, outlen+1, deb_xfer);
50
51
52 if (usb_control_msg(d->udev,
53 usb_sndctrlpipe(d->udev,0),
54 TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0,
55 buf, 20, 2000) != 20) {
56 err("USB control message 'out' went wrong.");
57 ret = -EIO;
58 goto unlock;
59 }
60
61 msleep(msec);
62
63 if (usb_control_msg(d->udev,
64 usb_rcvctrlpipe(d->udev,0),
65 TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
66 buf, 12, 2000) != 12) {
67 err("USB control message 'in' went wrong.");
68 ret = -EIO;
69 goto unlock;
70 }
71
72 deb_xfer("in buffer: ");
73 debug_dump(buf, 12, deb_xfer);
74
75 if (in != NULL && inlen > 0)
76 memcpy(in, &buf[1], inlen);
77
78unlock:
79 mutex_unlock(&d->usb_mutex);
80
81 return ret;
82}
83
84u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg)
85{
86 u8 obuf[2] = { 0 },v;
87 obuf[1] = reg;
88
89 vp7045_usb_op(d,TUNER_REG_READ,obuf,2,&v,1,30);
90
91 return v;
92}
93
94static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
95{
96 u8 v = onoff;
97 return vp7045_usb_op(d,SET_TUNER_POWER,&v,1,NULL,0,150);
98}
99
100/* remote control stuff */
101
102/* The keymapping struct. Somehow this should be loaded to the driver, but
103 * currently it is hardcoded. */
104static struct rc_map_table rc_map_vp7045_table[] = {
105 { 0x0016, KEY_POWER },
106 { 0x0010, KEY_MUTE },
107 { 0x0003, KEY_1 },
108 { 0x0001, KEY_2 },
109 { 0x0006, KEY_3 },
110 { 0x0009, KEY_4 },
111 { 0x001d, KEY_5 },
112 { 0x001f, KEY_6 },
113 { 0x000d, KEY_7 },
114 { 0x0019, KEY_8 },
115 { 0x001b, KEY_9 },
116 { 0x0015, KEY_0 },
117 { 0x0005, KEY_CHANNELUP },
118 { 0x0002, KEY_CHANNELDOWN },
119 { 0x001e, KEY_VOLUMEUP },
120 { 0x000a, KEY_VOLUMEDOWN },
121 { 0x0011, KEY_RECORD },
122 { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
123 { 0x0014, KEY_PLAY },
124 { 0x001a, KEY_STOP },
125 { 0x0040, KEY_REWIND },
126 { 0x0012, KEY_FASTFORWARD },
127 { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
128 { 0x004c, KEY_PAUSE },
129 { 0x004d, KEY_SCREEN }, /* Full screen mode. */
130 { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
131 { 0x000c, KEY_CANCEL }, /* Cancel */
132 { 0x001c, KEY_EPG }, /* EPG */
133 { 0x0000, KEY_TAB }, /* Tab */
134 { 0x0048, KEY_INFO }, /* Preview */
135 { 0x0004, KEY_LIST }, /* RecordList */
136 { 0x000f, KEY_TEXT }, /* Teletext */
137 { 0x0041, KEY_PREVIOUSSONG },
138 { 0x0042, KEY_NEXTSONG },
139 { 0x004b, KEY_UP },
140 { 0x0051, KEY_DOWN },
141 { 0x004e, KEY_LEFT },
142 { 0x0052, KEY_RIGHT },
143 { 0x004f, KEY_ENTER },
144 { 0x0013, KEY_CANCEL },
145 { 0x004a, KEY_CLEAR },
146 { 0x0054, KEY_PRINT }, /* Capture */
147 { 0x0043, KEY_SUBTITLE }, /* Subtitle/CC */
148 { 0x0008, KEY_VIDEO }, /* A/V */
149 { 0x0007, KEY_SLEEP }, /* Hibernate */
150 { 0x0045, KEY_ZOOM }, /* Zoom+ */
151 { 0x0018, KEY_RED},
152 { 0x0053, KEY_GREEN},
153 { 0x005e, KEY_YELLOW},
154 { 0x005f, KEY_BLUE}
155};
156
157static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
158{
159 u8 key;
160 int i;
161 vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20);
162
163 deb_rc("remote query key: %x %d\n",key,key);
164
165 if (key == 0x44) {
166 *state = REMOTE_NO_KEY_PRESSED;
167 return 0;
168 }
169
170 for (i = 0; i < ARRAY_SIZE(rc_map_vp7045_table); i++)
171 if (rc5_data(&rc_map_vp7045_table[i]) == key) {
172 *state = REMOTE_KEY_PRESSED;
173 *event = rc_map_vp7045_table[i].keycode;
174 break;
175 }
176 return 0;
177}
178
179static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int offset)
180{
181 int i = 0;
182 u8 v,br[2];
183 for (i=0; i < len; i++) {
184 v = offset + i;
185 vp7045_usb_op(d,GET_EE_VALUE,&v,1,br,2,5);
186 buf[i] = br[1];
187 }
188 deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ",offset, i);
189 debug_dump(buf,i,deb_info);
190 return 0;
191}
192
193static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
194{
195 return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR);
196}
197
198static int vp7045_frontend_attach(struct dvb_usb_adapter *adap)
199{
200 u8 buf[255] = { 0 };
201
202 vp7045_usb_op(adap->dev,VENDOR_STRING_READ,NULL,0,buf,20,0);
203 buf[10] = '\0';
204 deb_info("firmware says: %s ",buf);
205
206 vp7045_usb_op(adap->dev,PRODUCT_STRING_READ,NULL,0,buf,20,0);
207 buf[10] = '\0';
208 deb_info("%s ",buf);
209
210 vp7045_usb_op(adap->dev,FW_VERSION_READ,NULL,0,buf,20,0);
211 buf[10] = '\0';
212 deb_info("v%s\n",buf);
213
214/* Dump the EEPROM */
215/* vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */
216
217 adap->fe = vp7045_fe_attach(adap->dev);
218
219 return 0;
220}
221
222static struct dvb_usb_device_properties vp7045_properties;
223
224static int vp7045_usb_probe(struct usb_interface *intf,
225 const struct usb_device_id *id)
226{
227 return dvb_usb_device_init(intf, &vp7045_properties,
228 THIS_MODULE, NULL, adapter_nr);
229}
230
231static struct usb_device_id vp7045_usb_table [] = {
232 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_COLD) },
233 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_WARM) },
234 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_COLD) },
235 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_WARM) },
236 { 0 },
237};
238MODULE_DEVICE_TABLE(usb, vp7045_usb_table);
239
240static struct dvb_usb_device_properties vp7045_properties = {
241 .usb_ctrl = CYPRESS_FX2,
242 .firmware = "dvb-usb-vp7045-01.fw",
243 .size_of_priv = 20,
244
245 .num_adapters = 1,
246 .adapter = {
247 {
248 .frontend_attach = vp7045_frontend_attach,
249 /* parameter for the MPEG2-data transfer */
250 .stream = {
251 .type = USB_BULK,
252 .count = 7,
253 .endpoint = 0x02,
254 .u = {
255 .bulk = {
256 .buffersize = 4096,
257 }
258 }
259 },
260 }
261 },
262 .power_ctrl = vp7045_power_ctrl,
263 .read_mac_address = vp7045_read_mac_addr,
264
265 .rc.legacy = {
266 .rc_interval = 400,
267 .rc_map_table = rc_map_vp7045_table,
268 .rc_map_size = ARRAY_SIZE(rc_map_vp7045_table),
269 .rc_query = vp7045_rc_query,
270 },
271
272 .num_device_descs = 2,
273 .devices = {
274 { .name = "Twinhan USB2.0 DVB-T receiver (TwinhanDTV Alpha/MagicBox II)",
275 .cold_ids = { &vp7045_usb_table[0], NULL },
276 .warm_ids = { &vp7045_usb_table[1], NULL },
277 },
278 { .name = "DigitalNow TinyUSB 2 DVB-t Receiver",
279 .cold_ids = { &vp7045_usb_table[2], NULL },
280 .warm_ids = { &vp7045_usb_table[3], NULL },
281 },
282 { NULL },
283 }
284};
285
286/* usb specific object needed to register this driver with the usb subsystem */
287static struct usb_driver vp7045_usb_driver = {
288 .name = "dvb_usb_vp7045",
289 .probe = vp7045_usb_probe,
290 .disconnect = dvb_usb_device_exit,
291 .id_table = vp7045_usb_table,
292};
293
294/* module stuff */
295static int __init vp7045_usb_module_init(void)
296{
297 int result;
298 if ((result = usb_register(&vp7045_usb_driver))) {
299 err("usb_register failed. (%d)",result);
300 return result;
301 }
302
303 return 0;
304}
305
306static void __exit vp7045_usb_module_exit(void)
307{
308 /* deregister this driver from the USB subsystem */
309 usb_deregister(&vp7045_usb_driver);
310}
311
312module_init(vp7045_usb_module_init);
313module_exit(vp7045_usb_module_exit);
314
315MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
316MODULE_DESCRIPTION("Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0");
317MODULE_VERSION("1.0");
318MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/vp7045.h b/drivers/media/dvb/dvb-usb/vp7045.h
new file mode 100644
index 00000000000..cf5ec46f8bb
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/vp7045.h
@@ -0,0 +1,70 @@
1/* Common header-file of the Linux driver for the TwinhanDTV Alpha/MagicBoxII
2 * USB2.0 DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to Twinhan who kindly provided hardware and information.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#ifndef _DVB_USB_VP7045_H_
15#define _DVB_USB_VP7045_H_
16
17#define DVB_USB_LOG_PREFIX "vp7045"
18#include "dvb-usb.h"
19
20/* vp7045 commands */
21
22/* Twinhan Vendor requests */
23#define TH_COMMAND_IN 0xC0
24#define TH_COMMAND_OUT 0xC1
25
26/* command bytes */
27#define TUNER_REG_READ 0x03
28#define TUNER_REG_WRITE 0x04
29
30#define RC_VAL_READ 0x05
31 #define RC_NO_KEY 0x44
32
33#define SET_TUNER_POWER 0x06
34#define CHECK_TUNER_POWER 0x12
35 #define Tuner_Power_ON 1
36 #define Tuner_Power_OFF 0
37
38#define GET_USB_SPEED 0x07
39
40#define LOCK_TUNER_COMMAND 0x09
41
42#define TUNER_SIGNAL_READ 0x0A
43
44/* FX2 eeprom */
45#define SET_EE_VALUE 0x10
46#define GET_EE_VALUE 0x11
47 #define FX2_ID_ADDR 0x00
48 #define VID_MSB_ADDR 0x02
49 #define VID_LSB_ADDR 0x01
50 #define PID_MSB_ADDR 0x04
51 #define PID_LSB_ADDR 0x03
52 #define MAC_0_ADDR 0x07
53 #define MAC_1_ADDR 0x08
54 #define MAC_2_ADDR 0x09
55 #define MAC_3_ADDR 0x0a
56 #define MAC_4_ADDR 0x0b
57 #define MAC_5_ADDR 0x0c
58
59#define RESET_FX2 0x13
60
61#define FW_VERSION_READ 0x0B
62#define VENDOR_STRING_READ 0x0C
63#define PRODUCT_STRING_READ 0x0D
64#define FW_BCD_VERSION_READ 0x14
65
66extern struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d);
67extern int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen,int msec);
68extern u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg);
69
70#endif