aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/dvb-usb
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-06-14 15:35:56 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-13 22:26:31 -0400
commit786baecfe78f8e25547c628b48a60fc8e5636056 (patch)
treebb4101ce010f55cbbfc6d93ee13b44b496a028cc /drivers/media/usb/dvb-usb
parent616300bd51bee80d2d122c205866aa4c20adbaa8 (diff)
[media] dvb-usb: move it to drivers/media/usb/dvb-usb
As media/dvb will be removed, move it to a proper place. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/dvb-usb')
-rw-r--r--drivers/media/usb/dvb-usb/Kconfig313
-rw-r--r--drivers/media/usb/dvb-usb/Makefile82
-rw-r--r--drivers/media/usb/dvb-usb/a800.c191
-rw-r--r--drivers/media/usb/dvb-usb/af9005-fe.c1487
-rw-r--r--drivers/media/usb/dvb-usb/af9005-remote.c157
-rw-r--r--drivers/media/usb/dvb-usb/af9005-script.h203
-rw-r--r--drivers/media/usb/dvb-usb/af9005.c1117
-rw-r--r--drivers/media/usb/dvb-usb/af9005.h3496
-rw-r--r--drivers/media/usb/dvb-usb/az6027.c1182
-rw-r--r--drivers/media/usb/dvb-usb/az6027.h14
-rw-r--r--drivers/media/usb/dvb-usb/cinergyT2-core.c254
-rw-r--r--drivers/media/usb/dvb-usb/cinergyT2-fe.c356
-rw-r--r--drivers/media/usb/dvb-usb/cinergyT2.h95
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.c2043
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.h35
-rw-r--r--drivers/media/usb/dvb-usb/dib0700.h75
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_core.c845
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_devices.c4813
-rw-r--r--drivers/media/usb/dvb-usb/dib07x0.h21
-rw-r--r--drivers/media/usb/dvb-usb/dibusb-common.c479
-rw-r--r--drivers/media/usb/dvb-usb/dibusb-mb.c471
-rw-r--r--drivers/media/usb/dvb-usb/dibusb-mc.c149
-rw-r--r--drivers/media/usb/dvb-usb/dibusb.h131
-rw-r--r--drivers/media/usb/dvb-usb/digitv.c354
-rw-r--r--drivers/media/usb/dvb-usb/digitv.h66
-rw-r--r--drivers/media/usb/dvb-usb/dtt200u-fe.c210
-rw-r--r--drivers/media/usb/dvb-usb/dtt200u.c368
-rw-r--r--drivers/media/usb/dvb-usb/dtt200u.h57
-rw-r--r--drivers/media/usb/dvb-usb/dtv5100.c224
-rw-r--r--drivers/media/usb/dvb-usb/dtv5100.h51
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-common.h52
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-dvb.c288
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-firmware.c146
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-i2c.c43
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-init.c304
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-remote.c391
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-urb.c121
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb.h483
-rw-r--r--drivers/media/usb/dvb-usb/dvb_usb_dvb.c403
-rw-r--r--drivers/media/usb/dvb-usb/dvb_usb_remote.c117
-rw-r--r--drivers/media/usb/dvb-usb/dw2102.c1951
-rw-r--r--drivers/media/usb/dvb-usb/dw2102.h9
-rw-r--r--drivers/media/usb/dvb-usb/friio-fe.c473
-rw-r--r--drivers/media/usb/dvb-usb/friio.c522
-rw-r--r--drivers/media/usb/dvb-usb/friio.h99
-rw-r--r--drivers/media/usb/dvb-usb/gp8psk-fe.c369
-rw-r--r--drivers/media/usb/dvb-usb/gp8psk.c328
-rw-r--r--drivers/media/usb/dvb-usb/gp8psk.h100
-rw-r--r--drivers/media/usb/dvb-usb/m920x.c1099
-rw-r--r--drivers/media/usb/dvb-usb/m920x.h77
-rw-r--r--drivers/media/usb/dvb-usb/nova-t-usb2.c233
-rw-r--r--drivers/media/usb/dvb-usb/opera1.c583
-rw-r--r--drivers/media/usb/dvb-usb/pctv452e.c1063
-rw-r--r--drivers/media/usb/dvb-usb/technisat-usb2.c789
-rw-r--r--drivers/media/usb/dvb-usb/ttusb2.c820
-rw-r--r--drivers/media/usb/dvb-usb/ttusb2.h70
-rw-r--r--drivers/media/usb/dvb-usb/umt-010.c151
-rw-r--r--drivers/media/usb/dvb-usb/usb-urb.c254
-rw-r--r--drivers/media/usb/dvb-usb/vp702x-fe.c379
-rw-r--r--drivers/media/usb/dvb-usb/vp702x.c444
-rw-r--r--drivers/media/usb/dvb-usb/vp702x.h113
-rw-r--r--drivers/media/usb/dvb-usb/vp7045-fe.c190
-rw-r--r--drivers/media/usb/dvb-usb/vp7045.c302
-rw-r--r--drivers/media/usb/dvb-usb/vp7045.h70
64 files changed, 32175 insertions, 0 deletions
diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig
new file mode 100644
index 000000000000..00173ee15d4a
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/Kconfig
@@ -0,0 +1,313 @@
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_DIGITV
147 tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
148 depends on DVB_USB
149 select DVB_PLL if !DVB_FE_CUSTOMISE
150 select DVB_NXT6000 if !DVB_FE_CUSTOMISE
151 select DVB_MT352 if !DVB_FE_CUSTOMISE
152 help
153 Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
154
155config DVB_USB_VP7045
156 tristate "TwinhanDTV Alpha/MagicBoxII, DNTV tinyUSB2, Beetle USB2.0 support"
157 depends on DVB_USB
158 help
159 Say Y here to support the
160
161 TwinhanDTV Alpha (stick) (VP-7045),
162 TwinhanDTV MagicBox II (VP-7046),
163 DigitalNow TinyUSB 2 DVB-t,
164 DigitalRise USB 2.0 Ter (Beetle) and
165 TYPHOON DVB-T USB DRIVE
166
167 DVB-T USB2.0 receivers.
168
169config DVB_USB_VP702X
170 tristate "TwinhanDTV StarBox and clones DVB-S USB2.0 support"
171 depends on DVB_USB
172 help
173 Say Y here to support the
174
175 TwinhanDTV StarBox,
176 DigitalRise USB Starbox and
177 TYPHOON DVB-S USB 2.0 BOX
178
179 DVB-S USB2.0 receivers.
180
181config DVB_USB_GP8PSK
182 tristate "GENPIX 8PSK->USB module support"
183 depends on DVB_USB
184 help
185 Say Y here to support the
186 GENPIX 8psk module
187
188 DVB-S USB2.0 receivers.
189
190config DVB_USB_NOVA_T_USB2
191 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
192 depends on DVB_USB
193 select DVB_DIB3000MC
194 select DVB_PLL if !DVB_FE_CUSTOMISE
195 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
196 help
197 Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
198
199config DVB_USB_TTUSB2
200 tristate "Pinnacle 400e DVB-S USB2.0 support"
201 depends on DVB_USB
202 select DVB_TDA10086 if !DVB_FE_CUSTOMISE
203 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
204 select DVB_TDA826X if !DVB_FE_CUSTOMISE
205 help
206 Say Y here to support the Pinnacle 400e DVB-S USB2.0 receiver. The
207 firmware protocol used by this module is similar to the one used by the
208 old ttusb-driver - that's why the module is called dvb-usb-ttusb2.
209
210config DVB_USB_DTT200U
211 tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)"
212 depends on DVB_USB
213 help
214 Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.
215
216 The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
217
218 The WT-220U and its clones are pen-sized.
219
220config DVB_USB_OPERA1
221 tristate "Opera1 DVB-S USB2.0 receiver"
222 depends on DVB_USB
223 select DVB_STV0299 if !DVB_FE_CUSTOMISE
224 select DVB_PLL if !DVB_FE_CUSTOMISE
225 help
226 Say Y here to support the Opera DVB-S USB2.0 receiver.
227
228config DVB_USB_AF9005
229 tristate "Afatech AF9005 DVB-T USB1.1 support"
230 depends on DVB_USB && EXPERIMENTAL
231 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
232 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
233 help
234 Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
235 and the TerraTec Cinergy T USB XE (Rev.1)
236
237config DVB_USB_AF9005_REMOTE
238 tristate "Afatech AF9005 default remote control support"
239 depends on DVB_USB_AF9005
240 help
241 Say Y here to support the default remote control decoding for the
242 Afatech AF9005 based receiver.
243
244config DVB_USB_PCTV452E
245 tristate "Pinnacle PCTV HDTV Pro USB device/TT Connect S2-3600"
246 depends on DVB_USB
247 select TTPCI_EEPROM
248 select DVB_LNBP22 if !DVB_FE_CUSTOMISE
249 select DVB_STB0899 if !DVB_FE_CUSTOMISE
250 select DVB_STB6100 if !DVB_FE_CUSTOMISE
251 help
252 Support for external USB adapter designed by Pinnacle,
253 shipped under the brand name 'PCTV HDTV Pro USB'.
254 Also supports TT Connect S2-3600/3650 cards.
255 Say Y if you own such a device and want to use it.
256
257config DVB_USB_DW2102
258 tristate "DvbWorld & TeVii DVB-S/S2 USB2.0 support"
259 depends on DVB_USB
260 select DVB_PLL if !DVB_FE_CUSTOMISE
261 select DVB_STV0299 if !DVB_FE_CUSTOMISE
262 select DVB_STV0288 if !DVB_FE_CUSTOMISE
263 select DVB_STB6000 if !DVB_FE_CUSTOMISE
264 select DVB_CX24116 if !DVB_FE_CUSTOMISE
265 select DVB_SI21XX if !DVB_FE_CUSTOMISE
266 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
267 select DVB_MT312 if !DVB_FE_CUSTOMISE
268 select DVB_ZL10039 if !DVB_FE_CUSTOMISE
269 select DVB_DS3000 if !DVB_FE_CUSTOMISE
270 select DVB_STB6100 if !DVB_FE_CUSTOMISE
271 select DVB_STV6110 if !DVB_FE_CUSTOMISE
272 select DVB_STV0900 if !DVB_FE_CUSTOMISE
273 help
274 Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0
275 receivers.
276
277config DVB_USB_CINERGY_T2
278 tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
279 depends on DVB_USB
280 help
281 Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
282
283 Say Y if you own such a device and want to use it.
284
285config DVB_USB_DTV5100
286 tristate "AME DTV-5100 USB2.0 DVB-T support"
287 depends on DVB_USB
288 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
289 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
290 help
291 Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
292
293config DVB_USB_FRIIO
294 tristate "Friio ISDB-T USB2.0 Receiver support"
295 depends on DVB_USB
296 help
297 Say Y here to support the Japanese DTV receiver Friio.
298
299config DVB_USB_AZ6027
300 tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support"
301 depends on DVB_USB
302 select DVB_STB0899 if !DVB_FE_CUSTOMISE
303 select DVB_STB6100 if !DVB_FE_CUSTOMISE
304 help
305 Say Y here to support the AZ6027 device
306
307config DVB_USB_TECHNISAT_USB2
308 tristate "Technisat DVB-S/S2 USB2.0 support"
309 depends on DVB_USB
310 select DVB_STV090x if !DVB_FE_CUSTOMISE
311 select DVB_STV6110x if !DVB_FE_CUSTOMISE
312 help
313 Say Y here to support the Technisat USB2 DVB-S/S2 device
diff --git a/drivers/media/usb/dvb-usb/Makefile b/drivers/media/usb/dvb-usb/Makefile
new file mode 100644
index 000000000000..a5630e30eadc
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/Makefile
@@ -0,0 +1,82 @@
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-digitv-objs = digitv.o
37obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
38
39dvb-usb-cxusb-objs = cxusb.o
40obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o
41
42dvb-usb-ttusb2-objs = ttusb2.o
43obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o
44
45dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o
46obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
47
48dvb-usb-opera-objs = opera1.o
49obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o
50
51dvb-usb-af9005-objs = af9005.o af9005-fe.o
52obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o
53
54dvb-usb-af9005-remote-objs = af9005-remote.o
55obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
56
57dvb-usb-pctv452e-objs = pctv452e.o
58obj-$(CONFIG_DVB_USB_PCTV452E) += dvb-usb-pctv452e.o
59
60dvb-usb-dw2102-objs = dw2102.o
61obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o
62
63dvb-usb-dtv5100-objs = dtv5100.o
64obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o
65
66dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o
67obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
68
69dvb-usb-friio-objs = friio.o friio-fe.o
70obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
71
72dvb-usb-az6027-objs = az6027.o
73obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
74
75dvb-usb-technisat-usb2-objs = technisat-usb2.o
76obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
77
78ccflags-y += -I$(srctree)/drivers/media/dvb-core
79ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/
80# due to tuner-xc3028
81ccflags-y += -I$(srctree)/drivers/media/common/tuners
82ccflags-y += -I$(srctree)/drivers/media/dvb/ttpci
diff --git a/drivers/media/usb/dvb-usb/a800.c b/drivers/media/usb/dvb-usb/a800.c
new file mode 100644
index 000000000000..8d7fef84afd8
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/a800.c
@@ -0,0 +1,191 @@
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 .num_frontends = 1,
131 .fe = {{
132 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
133 .pid_filter_count = 32,
134 .streaming_ctrl = dibusb2_0_streaming_ctrl,
135 .pid_filter = dibusb_pid_filter,
136 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
137
138 .frontend_attach = dibusb_dib3000mc_frontend_attach,
139 .tuner_attach = dibusb_dib3000mc_tuner_attach,
140
141 /* parameter for the MPEG2-data transfer */
142 .stream = {
143 .type = USB_BULK,
144 .count = 7,
145 .endpoint = 0x06,
146 .u = {
147 .bulk = {
148 .buffersize = 4096,
149 }
150 }
151 },
152 }},
153 .size_of_priv = sizeof(struct dibusb_state),
154 },
155 },
156
157 .power_ctrl = a800_power_ctrl,
158 .identify_state = a800_identify_state,
159
160 .rc.legacy = {
161 .rc_interval = DEFAULT_RC_INTERVAL,
162 .rc_map_table = rc_map_a800_table,
163 .rc_map_size = ARRAY_SIZE(rc_map_a800_table),
164 .rc_query = a800_rc_query,
165 },
166
167 .i2c_algo = &dibusb_i2c_algo,
168
169 .generic_bulk_ctrl_endpoint = 0x01,
170 .num_device_descs = 1,
171 .devices = {
172 { "AVerMedia AverTV DVB-T USB 2.0 (A800)",
173 { &a800_table[0], NULL },
174 { &a800_table[1], NULL },
175 },
176 }
177};
178
179static struct usb_driver a800_driver = {
180 .name = "dvb_usb_a800",
181 .probe = a800_probe,
182 .disconnect = dvb_usb_device_exit,
183 .id_table = a800_table,
184};
185
186module_usb_driver(a800_driver);
187
188MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
189MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)");
190MODULE_VERSION("1.0");
191MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/af9005-fe.c b/drivers/media/usb/dvb-usb/af9005-fe.c
new file mode 100644
index 000000000000..740f3f496f12
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/af9005-fe.c
@@ -0,0 +1,1487 @@
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
67 if ((ret = af9005_write_ofdm_register(d, reglo, (u8) (value & 0xff))))
68 return ret;
69 return af9005_write_register_bits(d, reghi, pos, len,
70 (u8) ((value & 0x300) >> 8));
71}
72
73static int af9005_read_word_agc(struct dvb_usb_device *d, u16 reghi,
74 u16 reglo, u8 pos, u8 len, u16 * value)
75{
76 int ret;
77 u8 temp0, temp1;
78
79 if ((ret = af9005_read_ofdm_register(d, reglo, &temp0)))
80 return ret;
81 if ((ret = af9005_read_ofdm_register(d, reghi, &temp1)))
82 return ret;
83 switch (pos) {
84 case 0:
85 *value = ((u16) (temp1 & 0x03) << 8) + (u16) temp0;
86 break;
87 case 2:
88 *value = ((u16) (temp1 & 0x0C) << 6) + (u16) temp0;
89 break;
90 case 4:
91 *value = ((u16) (temp1 & 0x30) << 4) + (u16) temp0;
92 break;
93 case 6:
94 *value = ((u16) (temp1 & 0xC0) << 2) + (u16) temp0;
95 break;
96 default:
97 err("invalid pos in read word agc");
98 return -EINVAL;
99 }
100 return 0;
101
102}
103
104static int af9005_is_fecmon_available(struct dvb_frontend *fe, int *available)
105{
106 struct af9005_fe_state *state = fe->demodulator_priv;
107 int ret;
108 u8 temp;
109
110 *available = false;
111
112 ret = af9005_read_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en,
113 fec_vtb_rsd_mon_en_pos,
114 fec_vtb_rsd_mon_en_len, &temp);
115 if (ret)
116 return ret;
117 if (temp & 1) {
118 ret =
119 af9005_read_register_bits(state->d,
120 xd_p_reg_ofsm_read_rbc_en,
121 reg_ofsm_read_rbc_en_pos,
122 reg_ofsm_read_rbc_en_len, &temp);
123 if (ret)
124 return ret;
125 if ((temp & 1) == 0)
126 *available = true;
127
128 }
129 return 0;
130}
131
132static int af9005_get_post_vit_err_cw_count(struct dvb_frontend *fe,
133 u32 * post_err_count,
134 u32 * post_cw_count,
135 u16 * abort_count)
136{
137 struct af9005_fe_state *state = fe->demodulator_priv;
138 int ret;
139 u32 err_count;
140 u32 cw_count;
141 u8 temp, temp0, temp1, temp2;
142 u16 loc_abort_count;
143
144 *post_err_count = 0;
145 *post_cw_count = 0;
146
147 /* check if error bit count is ready */
148 ret =
149 af9005_read_register_bits(state->d, xd_r_fec_rsd_ber_rdy,
150 fec_rsd_ber_rdy_pos, fec_rsd_ber_rdy_len,
151 &temp);
152 if (ret)
153 return ret;
154 if (!temp) {
155 deb_info("rsd counter not ready\n");
156 return 100;
157 }
158 /* get abort count */
159 ret =
160 af9005_read_ofdm_register(state->d,
161 xd_r_fec_rsd_abort_packet_cnt_7_0,
162 &temp0);
163 if (ret)
164 return ret;
165 ret =
166 af9005_read_ofdm_register(state->d,
167 xd_r_fec_rsd_abort_packet_cnt_15_8,
168 &temp1);
169 if (ret)
170 return ret;
171 loc_abort_count = ((u16) temp1 << 8) + temp0;
172
173 /* get error count */
174 ret =
175 af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_7_0,
176 &temp0);
177 if (ret)
178 return ret;
179 ret =
180 af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_15_8,
181 &temp1);
182 if (ret)
183 return ret;
184 ret =
185 af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_23_16,
186 &temp2);
187 if (ret)
188 return ret;
189 err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0;
190 *post_err_count = err_count - (u32) loc_abort_count *8 * 8;
191
192 /* get RSD packet number */
193 ret =
194 af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0,
195 &temp0);
196 if (ret)
197 return ret;
198 ret =
199 af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8,
200 &temp1);
201 if (ret)
202 return ret;
203 cw_count = ((u32) temp1 << 8) + temp0;
204 if (cw_count == 0) {
205 err("wrong RSD packet count");
206 return -EIO;
207 }
208 deb_info("POST abort count %d err count %d rsd packets %d\n",
209 loc_abort_count, err_count, cw_count);
210 *post_cw_count = cw_count - (u32) loc_abort_count;
211 *abort_count = loc_abort_count;
212 return 0;
213
214}
215
216static int af9005_get_post_vit_ber(struct dvb_frontend *fe,
217 u32 * post_err_count, u32 * post_cw_count,
218 u16 * abort_count)
219{
220 u32 loc_cw_count = 0, loc_err_count;
221 u16 loc_abort_count = 0;
222 int ret;
223
224 ret =
225 af9005_get_post_vit_err_cw_count(fe, &loc_err_count, &loc_cw_count,
226 &loc_abort_count);
227 if (ret)
228 return ret;
229 *post_err_count = loc_err_count;
230 *post_cw_count = loc_cw_count * 204 * 8;
231 *abort_count = loc_abort_count;
232
233 return 0;
234}
235
236static int af9005_get_pre_vit_err_bit_count(struct dvb_frontend *fe,
237 u32 * pre_err_count,
238 u32 * pre_bit_count)
239{
240 struct af9005_fe_state *state = fe->demodulator_priv;
241 u8 temp, temp0, temp1, temp2;
242 u32 super_frame_count, x, bits;
243 int ret;
244
245 ret =
246 af9005_read_register_bits(state->d, xd_r_fec_vtb_ber_rdy,
247 fec_vtb_ber_rdy_pos, fec_vtb_ber_rdy_len,
248 &temp);
249 if (ret)
250 return ret;
251 if (!temp) {
252 deb_info("viterbi counter not ready\n");
253 return 101; /* ERR_APO_VTB_COUNTER_NOT_READY; */
254 }
255 ret =
256 af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_7_0,
257 &temp0);
258 if (ret)
259 return ret;
260 ret =
261 af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_15_8,
262 &temp1);
263 if (ret)
264 return ret;
265 ret =
266 af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_23_16,
267 &temp2);
268 if (ret)
269 return ret;
270 *pre_err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0;
271
272 ret =
273 af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0,
274 &temp0);
275 if (ret)
276 return ret;
277 ret =
278 af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8,
279 &temp1);
280 if (ret)
281 return ret;
282 super_frame_count = ((u32) temp1 << 8) + temp0;
283 if (super_frame_count == 0) {
284 deb_info("super frame count 0\n");
285 return 102;
286 }
287
288 /* read fft mode */
289 ret =
290 af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod,
291 reg_tpsd_txmod_pos, reg_tpsd_txmod_len,
292 &temp);
293 if (ret)
294 return ret;
295 if (temp == 0) {
296 /* 2K */
297 x = 1512;
298 } else if (temp == 1) {
299 /* 8k */
300 x = 6048;
301 } else {
302 err("Invalid fft mode");
303 return -EINVAL;
304 }
305
306 /* read modulation mode */
307 ret =
308 af9005_read_register_bits(state->d, xd_g_reg_tpsd_const,
309 reg_tpsd_const_pos, reg_tpsd_const_len,
310 &temp);
311 if (ret)
312 return ret;
313 switch (temp) {
314 case 0: /* QPSK */
315 bits = 2;
316 break;
317 case 1: /* QAM_16 */
318 bits = 4;
319 break;
320 case 2: /* QAM_64 */
321 bits = 6;
322 break;
323 default:
324 err("invalid modulation mode");
325 return -EINVAL;
326 }
327 *pre_bit_count = super_frame_count * 68 * 4 * x * bits;
328 deb_info("PRE err count %d frame count %d bit count %d\n",
329 *pre_err_count, super_frame_count, *pre_bit_count);
330 return 0;
331}
332
333static int af9005_reset_pre_viterbi(struct dvb_frontend *fe)
334{
335 struct af9005_fe_state *state = fe->demodulator_priv;
336 int ret;
337
338 /* set super frame count to 1 */
339 ret =
340 af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0,
341 1 & 0xff);
342 if (ret)
343 return ret;
344 ret = af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8,
345 1 >> 8);
346 if (ret)
347 return ret;
348 /* reset pre viterbi error count */
349 ret =
350 af9005_write_register_bits(state->d, xd_p_fec_vtb_ber_rst,
351 fec_vtb_ber_rst_pos, fec_vtb_ber_rst_len,
352 1);
353
354 return ret;
355}
356
357static int af9005_reset_post_viterbi(struct dvb_frontend *fe)
358{
359 struct af9005_fe_state *state = fe->demodulator_priv;
360 int ret;
361
362 /* set packet unit */
363 ret =
364 af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0,
365 10000 & 0xff);
366 if (ret)
367 return ret;
368 ret =
369 af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8,
370 10000 >> 8);
371 if (ret)
372 return ret;
373 /* reset post viterbi error count */
374 ret =
375 af9005_write_register_bits(state->d, xd_p_fec_rsd_ber_rst,
376 fec_rsd_ber_rst_pos, fec_rsd_ber_rst_len,
377 1);
378
379 return ret;
380}
381
382static int af9005_get_statistic(struct dvb_frontend *fe)
383{
384 struct af9005_fe_state *state = fe->demodulator_priv;
385 int ret, fecavailable;
386 u64 numerator, denominator;
387
388 deb_info("GET STATISTIC\n");
389 ret = af9005_is_fecmon_available(fe, &fecavailable);
390 if (ret)
391 return ret;
392 if (!fecavailable) {
393 deb_info("fecmon not available\n");
394 return 0;
395 }
396
397 ret = af9005_get_pre_vit_err_bit_count(fe, &state->pre_vit_error_count,
398 &state->pre_vit_bit_count);
399 if (ret == 0) {
400 af9005_reset_pre_viterbi(fe);
401 if (state->pre_vit_bit_count > 0) {
402 /* according to v 0.0.4 of the dvb api ber should be a multiple
403 of 10E-9 so we have to multiply the error count by
404 10E9=1000000000 */
405 numerator =
406 (u64) state->pre_vit_error_count * (u64) 1000000000;
407 denominator = (u64) state->pre_vit_bit_count;
408 state->ber = do_div(numerator, denominator);
409 } else {
410 state->ber = 0xffffffff;
411 }
412 }
413
414 ret = af9005_get_post_vit_ber(fe, &state->post_vit_error_count,
415 &state->post_vit_bit_count,
416 &state->abort_count);
417 if (ret == 0) {
418 ret = af9005_reset_post_viterbi(fe);
419 state->unc += state->abort_count;
420 if (ret)
421 return ret;
422 }
423 return 0;
424}
425
426static int af9005_fe_refresh_state(struct dvb_frontend *fe)
427{
428 struct af9005_fe_state *state = fe->demodulator_priv;
429 if (time_after(jiffies, state->next_status_check)) {
430 deb_info("REFRESH STATE\n");
431
432 /* statistics */
433 if (af9005_get_statistic(fe))
434 err("get_statistic_failed");
435 state->next_status_check = jiffies + 250 * HZ / 1000;
436 }
437 return 0;
438}
439
440static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat)
441{
442 struct af9005_fe_state *state = fe->demodulator_priv;
443 u8 temp;
444 int ret;
445
446 if (fe->ops.tuner_ops.release == NULL)
447 return -ENODEV;
448
449 *stat = 0;
450 ret = af9005_read_register_bits(state->d, xd_p_agc_lock,
451 agc_lock_pos, agc_lock_len, &temp);
452 if (ret)
453 return ret;
454 if (temp)
455 *stat |= FE_HAS_SIGNAL;
456
457 ret = af9005_read_register_bits(state->d, xd_p_fd_tpsd_lock,
458 fd_tpsd_lock_pos, fd_tpsd_lock_len,
459 &temp);
460 if (ret)
461 return ret;
462 if (temp)
463 *stat |= FE_HAS_CARRIER;
464
465 ret = af9005_read_register_bits(state->d,
466 xd_r_mp2if_sync_byte_locked,
467 mp2if_sync_byte_locked_pos,
468 mp2if_sync_byte_locked_pos, &temp);
469 if (ret)
470 return ret;
471 if (temp)
472 *stat |= FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_LOCK;
473 if (state->opened)
474 af9005_led_control(state->d, *stat & FE_HAS_LOCK);
475
476 ret =
477 af9005_read_register_bits(state->d, xd_p_reg_strong_sginal_detected,
478 reg_strong_sginal_detected_pos,
479 reg_strong_sginal_detected_len, &temp);
480 if (ret)
481 return ret;
482 if (temp != state->strong) {
483 deb_info("adjust for strong signal %d\n", temp);
484 state->strong = temp;
485 }
486 return 0;
487}
488
489static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber)
490{
491 struct af9005_fe_state *state = fe->demodulator_priv;
492 if (fe->ops.tuner_ops.release == NULL)
493 return -ENODEV;
494 af9005_fe_refresh_state(fe);
495 *ber = state->ber;
496 return 0;
497}
498
499static int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
500{
501 struct af9005_fe_state *state = fe->demodulator_priv;
502 if (fe->ops.tuner_ops.release == NULL)
503 return -ENODEV;
504 af9005_fe_refresh_state(fe);
505 *unc = state->unc;
506 return 0;
507}
508
509static int af9005_fe_read_signal_strength(struct dvb_frontend *fe,
510 u16 * strength)
511{
512 struct af9005_fe_state *state = fe->demodulator_priv;
513 int ret;
514 u8 if_gain, rf_gain;
515
516 if (fe->ops.tuner_ops.release == NULL)
517 return -ENODEV;
518 ret =
519 af9005_read_ofdm_register(state->d, xd_r_reg_aagc_rf_gain,
520 &rf_gain);
521 if (ret)
522 return ret;
523 ret =
524 af9005_read_ofdm_register(state->d, xd_r_reg_aagc_if_gain,
525 &if_gain);
526 if (ret)
527 return ret;
528 /* this value has no real meaning, but i don't have the tables that relate
529 the rf and if gain with the dbm, so I just scale the value */
530 *strength = (512 - rf_gain - if_gain) << 7;
531 return 0;
532}
533
534static int af9005_fe_read_snr(struct dvb_frontend *fe, u16 * snr)
535{
536 /* the snr can be derived from the ber and the modulation
537 but I don't think this kind of complex calculations belong
538 in the driver. I may be wrong.... */
539 return -ENOSYS;
540}
541
542static int af9005_fe_program_cfoe(struct dvb_usb_device *d, u32 bw)
543{
544 u8 temp0, temp1, temp2, temp3, buf[4];
545 int ret;
546 u32 NS_coeff1_2048Nu;
547 u32 NS_coeff1_8191Nu;
548 u32 NS_coeff1_8192Nu;
549 u32 NS_coeff1_8193Nu;
550 u32 NS_coeff2_2k;
551 u32 NS_coeff2_8k;
552
553 switch (bw) {
554 case 6000000:
555 NS_coeff1_2048Nu = 0x2ADB6DC;
556 NS_coeff1_8191Nu = 0xAB7313;
557 NS_coeff1_8192Nu = 0xAB6DB7;
558 NS_coeff1_8193Nu = 0xAB685C;
559 NS_coeff2_2k = 0x156DB6E;
560 NS_coeff2_8k = 0x55B6DC;
561 break;
562
563 case 7000000:
564 NS_coeff1_2048Nu = 0x3200001;
565 NS_coeff1_8191Nu = 0xC80640;
566 NS_coeff1_8192Nu = 0xC80000;
567 NS_coeff1_8193Nu = 0xC7F9C0;
568 NS_coeff2_2k = 0x1900000;
569 NS_coeff2_8k = 0x640000;
570 break;
571
572 case 8000000:
573 NS_coeff1_2048Nu = 0x3924926;
574 NS_coeff1_8191Nu = 0xE4996E;
575 NS_coeff1_8192Nu = 0xE49249;
576 NS_coeff1_8193Nu = 0xE48B25;
577 NS_coeff2_2k = 0x1C92493;
578 NS_coeff2_8k = 0x724925;
579 break;
580 default:
581 err("Invalid bandwidth %d.", bw);
582 return -EINVAL;
583 }
584
585 /*
586 * write NS_coeff1_2048Nu
587 */
588
589 temp0 = (u8) (NS_coeff1_2048Nu & 0x000000FF);
590 temp1 = (u8) ((NS_coeff1_2048Nu & 0x0000FF00) >> 8);
591 temp2 = (u8) ((NS_coeff1_2048Nu & 0x00FF0000) >> 16);
592 temp3 = (u8) ((NS_coeff1_2048Nu & 0x03000000) >> 24);
593
594 /* big endian to make 8051 happy */
595 buf[0] = temp3;
596 buf[1] = temp2;
597 buf[2] = temp1;
598 buf[3] = temp0;
599
600 /* cfoe_NS_2k_coeff1_25_24 */
601 ret = af9005_write_ofdm_register(d, 0xAE00, buf[0]);
602 if (ret)
603 return ret;
604
605 /* cfoe_NS_2k_coeff1_23_16 */
606 ret = af9005_write_ofdm_register(d, 0xAE01, buf[1]);
607 if (ret)
608 return ret;
609
610 /* cfoe_NS_2k_coeff1_15_8 */
611 ret = af9005_write_ofdm_register(d, 0xAE02, buf[2]);
612 if (ret)
613 return ret;
614
615 /* cfoe_NS_2k_coeff1_7_0 */
616 ret = af9005_write_ofdm_register(d, 0xAE03, buf[3]);
617 if (ret)
618 return ret;
619
620 /*
621 * write NS_coeff2_2k
622 */
623
624 temp0 = (u8) ((NS_coeff2_2k & 0x0000003F));
625 temp1 = (u8) ((NS_coeff2_2k & 0x00003FC0) >> 6);
626 temp2 = (u8) ((NS_coeff2_2k & 0x003FC000) >> 14);
627 temp3 = (u8) ((NS_coeff2_2k & 0x01C00000) >> 22);
628
629 /* big endian to make 8051 happy */
630 buf[0] = temp3;
631 buf[1] = temp2;
632 buf[2] = temp1;
633 buf[3] = temp0;
634
635 ret = af9005_write_ofdm_register(d, 0xAE04, buf[0]);
636 if (ret)
637 return ret;
638
639 ret = af9005_write_ofdm_register(d, 0xAE05, buf[1]);
640 if (ret)
641 return ret;
642
643 ret = af9005_write_ofdm_register(d, 0xAE06, buf[2]);
644 if (ret)
645 return ret;
646
647 ret = af9005_write_ofdm_register(d, 0xAE07, buf[3]);
648 if (ret)
649 return ret;
650
651 /*
652 * write NS_coeff1_8191Nu
653 */
654
655 temp0 = (u8) ((NS_coeff1_8191Nu & 0x000000FF));
656 temp1 = (u8) ((NS_coeff1_8191Nu & 0x0000FF00) >> 8);
657 temp2 = (u8) ((NS_coeff1_8191Nu & 0x00FFC000) >> 16);
658 temp3 = (u8) ((NS_coeff1_8191Nu & 0x03000000) >> 24);
659
660 /* big endian to make 8051 happy */
661 buf[0] = temp3;
662 buf[1] = temp2;
663 buf[2] = temp1;
664 buf[3] = temp0;
665
666 ret = af9005_write_ofdm_register(d, 0xAE08, buf[0]);
667 if (ret)
668 return ret;
669
670 ret = af9005_write_ofdm_register(d, 0xAE09, buf[1]);
671 if (ret)
672 return ret;
673
674 ret = af9005_write_ofdm_register(d, 0xAE0A, buf[2]);
675 if (ret)
676 return ret;
677
678 ret = af9005_write_ofdm_register(d, 0xAE0B, buf[3]);
679 if (ret)
680 return ret;
681
682 /*
683 * write NS_coeff1_8192Nu
684 */
685
686 temp0 = (u8) (NS_coeff1_8192Nu & 0x000000FF);
687 temp1 = (u8) ((NS_coeff1_8192Nu & 0x0000FF00) >> 8);
688 temp2 = (u8) ((NS_coeff1_8192Nu & 0x00FFC000) >> 16);
689 temp3 = (u8) ((NS_coeff1_8192Nu & 0x03000000) >> 24);
690
691 /* big endian to make 8051 happy */
692 buf[0] = temp3;
693 buf[1] = temp2;
694 buf[2] = temp1;
695 buf[3] = temp0;
696
697 ret = af9005_write_ofdm_register(d, 0xAE0C, buf[0]);
698 if (ret)
699 return ret;
700
701 ret = af9005_write_ofdm_register(d, 0xAE0D, buf[1]);
702 if (ret)
703 return ret;
704
705 ret = af9005_write_ofdm_register(d, 0xAE0E, buf[2]);
706 if (ret)
707 return ret;
708
709 ret = af9005_write_ofdm_register(d, 0xAE0F, buf[3]);
710 if (ret)
711 return ret;
712
713 /*
714 * write NS_coeff1_8193Nu
715 */
716
717 temp0 = (u8) ((NS_coeff1_8193Nu & 0x000000FF));
718 temp1 = (u8) ((NS_coeff1_8193Nu & 0x0000FF00) >> 8);
719 temp2 = (u8) ((NS_coeff1_8193Nu & 0x00FFC000) >> 16);
720 temp3 = (u8) ((NS_coeff1_8193Nu & 0x03000000) >> 24);
721
722 /* big endian to make 8051 happy */
723 buf[0] = temp3;
724 buf[1] = temp2;
725 buf[2] = temp1;
726 buf[3] = temp0;
727
728 ret = af9005_write_ofdm_register(d, 0xAE10, buf[0]);
729 if (ret)
730 return ret;
731
732 ret = af9005_write_ofdm_register(d, 0xAE11, buf[1]);
733 if (ret)
734 return ret;
735
736 ret = af9005_write_ofdm_register(d, 0xAE12, buf[2]);
737 if (ret)
738 return ret;
739
740 ret = af9005_write_ofdm_register(d, 0xAE13, buf[3]);
741 if (ret)
742 return ret;
743
744 /*
745 * write NS_coeff2_8k
746 */
747
748 temp0 = (u8) ((NS_coeff2_8k & 0x0000003F));
749 temp1 = (u8) ((NS_coeff2_8k & 0x00003FC0) >> 6);
750 temp2 = (u8) ((NS_coeff2_8k & 0x003FC000) >> 14);
751 temp3 = (u8) ((NS_coeff2_8k & 0x01C00000) >> 22);
752
753 /* big endian to make 8051 happy */
754 buf[0] = temp3;
755 buf[1] = temp2;
756 buf[2] = temp1;
757 buf[3] = temp0;
758
759 ret = af9005_write_ofdm_register(d, 0xAE14, buf[0]);
760 if (ret)
761 return ret;
762
763 ret = af9005_write_ofdm_register(d, 0xAE15, buf[1]);
764 if (ret)
765 return ret;
766
767 ret = af9005_write_ofdm_register(d, 0xAE16, buf[2]);
768 if (ret)
769 return ret;
770
771 ret = af9005_write_ofdm_register(d, 0xAE17, buf[3]);
772 return ret;
773
774}
775
776static int af9005_fe_select_bw(struct dvb_usb_device *d, u32 bw)
777{
778 u8 temp;
779 switch (bw) {
780 case 6000000:
781 temp = 0;
782 break;
783 case 7000000:
784 temp = 1;
785 break;
786 case 8000000:
787 temp = 2;
788 break;
789 default:
790 err("Invalid bandwidth %d.", bw);
791 return -EINVAL;
792 }
793 return af9005_write_register_bits(d, xd_g_reg_bw, reg_bw_pos,
794 reg_bw_len, temp);
795}
796
797static int af9005_fe_power(struct dvb_frontend *fe, int on)
798{
799 struct af9005_fe_state *state = fe->demodulator_priv;
800 u8 temp = on;
801 int ret;
802 deb_info("power %s tuner\n", on ? "on" : "off");
803 ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0);
804 return ret;
805}
806
807static struct mt2060_config af9005_mt2060_config = {
808 0xC0
809};
810
811static struct qt1010_config af9005_qt1010_config = {
812 0xC4
813};
814
815static int af9005_fe_init(struct dvb_frontend *fe)
816{
817 struct af9005_fe_state *state = fe->demodulator_priv;
818 struct dvb_usb_adapter *adap = fe->dvb->priv;
819 int ret, i, scriptlen;
820 u8 temp, temp0 = 0, temp1 = 0, temp2 = 0;
821 u8 buf[2];
822 u16 if1;
823
824 deb_info("in af9005_fe_init\n");
825
826 /* reset */
827 deb_info("reset\n");
828 if ((ret =
829 af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst_en,
830 4, 1, 0x01)))
831 return ret;
832 if ((ret = af9005_write_ofdm_register(state->d, APO_REG_RESET, 0)))
833 return ret;
834 /* clear ofdm reset */
835 deb_info("clear ofdm reset\n");
836 for (i = 0; i < 150; i++) {
837 if ((ret =
838 af9005_read_ofdm_register(state->d,
839 xd_I2C_reg_ofdm_rst, &temp)))
840 return ret;
841 if (temp & (regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos))
842 break;
843 msleep(10);
844 }
845 if (i == 150)
846 return -ETIMEDOUT;
847
848 /*FIXME in the dump
849 write B200 A9
850 write xd_g_reg_ofsm_clk 7
851 read eepr c6 (2)
852 read eepr c7 (2)
853 misc ctrl 3 -> 1
854 read eepr ca (6)
855 write xd_g_reg_ofsm_clk 0
856 write B200 a1
857 */
858 ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa9);
859 if (ret)
860 return ret;
861 ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x07);
862 if (ret)
863 return ret;
864 temp = 0x01;
865 ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0);
866 if (ret)
867 return ret;
868 ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x00);
869 if (ret)
870 return ret;
871 ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa1);
872 if (ret)
873 return ret;
874
875 temp = regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos;
876 if ((ret =
877 af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,
878 reg_ofdm_rst_pos, reg_ofdm_rst_len, 1)))
879 return ret;
880 ret = af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,
881 reg_ofdm_rst_pos, reg_ofdm_rst_len, 0);
882
883 if (ret)
884 return ret;
885 /* don't know what register aefc is, but this is what the windows driver does */
886 ret = af9005_write_ofdm_register(state->d, 0xaefc, 0);
887 if (ret)
888 return ret;
889
890 /* set stand alone chip */
891 deb_info("set stand alone chip\n");
892 if ((ret =
893 af9005_write_register_bits(state->d, xd_p_reg_dca_stand_alone,
894 reg_dca_stand_alone_pos,
895 reg_dca_stand_alone_len, 1)))
896 return ret;
897
898 /* set dca upper & lower chip */
899 deb_info("set dca upper & lower chip\n");
900 if ((ret =
901 af9005_write_register_bits(state->d, xd_p_reg_dca_upper_chip,
902 reg_dca_upper_chip_pos,
903 reg_dca_upper_chip_len, 0)))
904 return ret;
905 if ((ret =
906 af9005_write_register_bits(state->d, xd_p_reg_dca_lower_chip,
907 reg_dca_lower_chip_pos,
908 reg_dca_lower_chip_len, 0)))
909 return ret;
910
911 /* set 2wire master clock to 0x14 (for 60KHz) */
912 deb_info("set 2wire master clock to 0x14 (for 60KHz)\n");
913 if ((ret =
914 af9005_write_ofdm_register(state->d, xd_I2C_i2c_m_period, 0x14)))
915 return ret;
916
917 /* clear dca enable chip */
918 deb_info("clear dca enable chip\n");
919 if ((ret =
920 af9005_write_register_bits(state->d, xd_p_reg_dca_en,
921 reg_dca_en_pos, reg_dca_en_len, 0)))
922 return ret;
923 /* FIXME these are register bits, but I don't know which ones */
924 ret = af9005_write_ofdm_register(state->d, 0xa16c, 1);
925 if (ret)
926 return ret;
927 ret = af9005_write_ofdm_register(state->d, 0xa3c1, 0);
928 if (ret)
929 return ret;
930
931 /* init other parameters: program cfoe and select bandwidth */
932 deb_info("program cfoe\n");
933 ret = af9005_fe_program_cfoe(state->d, 6000000);
934 if (ret)
935 return ret;
936 /* set read-update bit for modulation */
937 deb_info("set read-update bit for modulation\n");
938 if ((ret =
939 af9005_write_register_bits(state->d, xd_p_reg_feq_read_update,
940 reg_feq_read_update_pos,
941 reg_feq_read_update_len, 1)))
942 return ret;
943
944 /* sample code has a set MPEG TS code here
945 but sniffing reveals that it doesn't do it */
946
947 /* set read-update bit to 1 for DCA modulation */
948 deb_info("set read-update bit 1 for DCA modulation\n");
949 if ((ret =
950 af9005_write_register_bits(state->d, xd_p_reg_dca_read_update,
951 reg_dca_read_update_pos,
952 reg_dca_read_update_len, 1)))
953 return ret;
954
955 /* enable fec monitor */
956 deb_info("enable fec monitor\n");
957 if ((ret =
958 af9005_write_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en,
959 fec_vtb_rsd_mon_en_pos,
960 fec_vtb_rsd_mon_en_len, 1)))
961 return ret;
962
963 /* FIXME should be register bits, I don't know which ones */
964 ret = af9005_write_ofdm_register(state->d, 0xa601, 0);
965
966 /* set api_retrain_never_freeze */
967 deb_info("set api_retrain_never_freeze\n");
968 if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01)))
969 return ret;
970
971 /* load init script */
972 deb_info("load init script\n");
973 scriptlen = sizeof(script) / sizeof(RegDesc);
974 for (i = 0; i < scriptlen; i++) {
975 if ((ret =
976 af9005_write_register_bits(state->d, script[i].reg,
977 script[i].pos,
978 script[i].len, script[i].val)))
979 return ret;
980 /* save 3 bytes of original fcw */
981 if (script[i].reg == 0xae18)
982 temp2 = script[i].val;
983 if (script[i].reg == 0xae19)
984 temp1 = script[i].val;
985 if (script[i].reg == 0xae1a)
986 temp0 = script[i].val;
987
988 /* save original unplug threshold */
989 if (script[i].reg == xd_p_reg_unplug_th)
990 state->original_if_unplug_th = script[i].val;
991 if (script[i].reg == xd_p_reg_unplug_rf_gain_th)
992 state->original_rf_unplug_th = script[i].val;
993 if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th)
994 state->original_dtop_if_unplug_th = script[i].val;
995 if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th)
996 state->original_dtop_rf_unplug_th = script[i].val;
997
998 }
999 state->original_fcw =
1000 ((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0;
1001
1002
1003 /* save original TOPs */
1004 deb_info("save original TOPs\n");
1005
1006 /* RF TOP */
1007 ret =
1008 af9005_read_word_agc(state->d,
1009 xd_p_reg_aagc_rf_top_numerator_9_8,
1010 xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2,
1011 &state->original_rf_top);
1012 if (ret)
1013 return ret;
1014
1015 /* IF TOP */
1016 ret =
1017 af9005_read_word_agc(state->d,
1018 xd_p_reg_aagc_if_top_numerator_9_8,
1019 xd_p_reg_aagc_if_top_numerator_7_0, 0, 2,
1020 &state->original_if_top);
1021 if (ret)
1022 return ret;
1023
1024 /* ACI 0 IF TOP */
1025 ret =
1026 af9005_read_word_agc(state->d, 0xA60E, 0xA60A, 4, 2,
1027 &state->original_aci0_if_top);
1028 if (ret)
1029 return ret;
1030
1031 /* ACI 1 IF TOP */
1032 ret =
1033 af9005_read_word_agc(state->d, 0xA60E, 0xA60B, 6, 2,
1034 &state->original_aci1_if_top);
1035 if (ret)
1036 return ret;
1037
1038 /* attach tuner and init */
1039 if (fe->ops.tuner_ops.release == NULL) {
1040 /* read tuner and board id from eeprom */
1041 ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2);
1042 if (ret) {
1043 err("Impossible to read EEPROM\n");
1044 return ret;
1045 }
1046 deb_info("Tuner id %d, board id %d\n", buf[0], buf[1]);
1047 switch (buf[0]) {
1048 case 2: /* MT2060 */
1049 /* read if1 from eeprom */
1050 ret = af9005_read_eeprom(adap->dev, 0xc8, buf, 2);
1051 if (ret) {
1052 err("Impossible to read EEPROM\n");
1053 return ret;
1054 }
1055 if1 = (u16) (buf[0] << 8) + buf[1];
1056 if (dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap,
1057 &af9005_mt2060_config, if1) == NULL) {
1058 deb_info("MT2060 attach failed\n");
1059 return -ENODEV;
1060 }
1061 break;
1062 case 3: /* QT1010 */
1063 case 9: /* QT1010B */
1064 if (dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap,
1065 &af9005_qt1010_config) ==NULL) {
1066 deb_info("QT1010 attach failed\n");
1067 return -ENODEV;
1068 }
1069 break;
1070 default:
1071 err("Unsupported tuner type %d", buf[0]);
1072 return -ENODEV;
1073 }
1074 ret = fe->ops.tuner_ops.init(fe);
1075 if (ret)
1076 return ret;
1077 }
1078
1079 deb_info("profit!\n");
1080 return 0;
1081}
1082
1083static int af9005_fe_sleep(struct dvb_frontend *fe)
1084{
1085 return af9005_fe_power(fe, 0);
1086}
1087
1088static int af9005_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
1089{
1090 struct af9005_fe_state *state = fe->demodulator_priv;
1091
1092 if (acquire) {
1093 state->opened++;
1094 } else {
1095
1096 state->opened--;
1097 if (!state->opened)
1098 af9005_led_control(state->d, 0);
1099 }
1100 return 0;
1101}
1102
1103static int af9005_fe_set_frontend(struct dvb_frontend *fe)
1104{
1105 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1106 struct af9005_fe_state *state = fe->demodulator_priv;
1107 int ret;
1108 u8 temp, temp0, temp1, temp2;
1109
1110 deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency,
1111 fep->bandwidth_hz);
1112 if (fe->ops.tuner_ops.release == NULL) {
1113 err("Tuner not attached");
1114 return -ENODEV;
1115 }
1116
1117 deb_info("turn off led\n");
1118 /* not in the log */
1119 ret = af9005_led_control(state->d, 0);
1120 if (ret)
1121 return ret;
1122 /* not sure about the bits */
1123 ret = af9005_write_register_bits(state->d, XD_MP2IF_MISC, 2, 1, 0);
1124 if (ret)
1125 return ret;
1126
1127 /* set FCW to default value */
1128 deb_info("set FCW to default value\n");
1129 temp0 = (u8) (state->original_fcw & 0x000000ff);
1130 temp1 = (u8) ((state->original_fcw & 0x0000ff00) >> 8);
1131 temp2 = (u8) ((state->original_fcw & 0x00ff0000) >> 16);
1132 ret = af9005_write_ofdm_register(state->d, 0xae1a, temp0);
1133 if (ret)
1134 return ret;
1135 ret = af9005_write_ofdm_register(state->d, 0xae19, temp1);
1136 if (ret)
1137 return ret;
1138 ret = af9005_write_ofdm_register(state->d, 0xae18, temp2);
1139 if (ret)
1140 return ret;
1141
1142 /* restore original TOPs */
1143 deb_info("restore original TOPs\n");
1144 ret =
1145 af9005_write_word_agc(state->d,
1146 xd_p_reg_aagc_rf_top_numerator_9_8,
1147 xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2,
1148 state->original_rf_top);
1149 if (ret)
1150 return ret;
1151 ret =
1152 af9005_write_word_agc(state->d,
1153 xd_p_reg_aagc_if_top_numerator_9_8,
1154 xd_p_reg_aagc_if_top_numerator_7_0, 0, 2,
1155 state->original_if_top);
1156 if (ret)
1157 return ret;
1158 ret =
1159 af9005_write_word_agc(state->d, 0xA60E, 0xA60A, 4, 2,
1160 state->original_aci0_if_top);
1161 if (ret)
1162 return ret;
1163 ret =
1164 af9005_write_word_agc(state->d, 0xA60E, 0xA60B, 6, 2,
1165 state->original_aci1_if_top);
1166 if (ret)
1167 return ret;
1168
1169 /* select bandwidth */
1170 deb_info("select bandwidth");
1171 ret = af9005_fe_select_bw(state->d, fep->bandwidth_hz);
1172 if (ret)
1173 return ret;
1174 ret = af9005_fe_program_cfoe(state->d, fep->bandwidth_hz);
1175 if (ret)
1176 return ret;
1177
1178 /* clear easy mode flag */
1179 deb_info("clear easy mode flag\n");
1180 ret = af9005_write_ofdm_register(state->d, 0xaefd, 0);
1181 if (ret)
1182 return ret;
1183
1184 /* set unplug threshold to original value */
1185 deb_info("set unplug threshold to original value\n");
1186 ret =
1187 af9005_write_ofdm_register(state->d, xd_p_reg_unplug_th,
1188 state->original_if_unplug_th);
1189 if (ret)
1190 return ret;
1191 /* set tuner */
1192 deb_info("set tuner\n");
1193 ret = fe->ops.tuner_ops.set_params(fe);
1194 if (ret)
1195 return ret;
1196
1197 /* trigger ofsm */
1198 deb_info("trigger ofsm\n");
1199 temp = 0;
1200 ret = af9005_write_tuner_registers(state->d, 0xffff, &temp, 1);
1201 if (ret)
1202 return ret;
1203
1204 /* clear retrain and freeze flag */
1205 deb_info("clear retrain and freeze flag\n");
1206 ret =
1207 af9005_write_register_bits(state->d,
1208 xd_p_reg_api_retrain_request,
1209 reg_api_retrain_request_pos, 2, 0);
1210 if (ret)
1211 return ret;
1212
1213 /* reset pre viterbi and post viterbi registers and statistics */
1214 af9005_reset_pre_viterbi(fe);
1215 af9005_reset_post_viterbi(fe);
1216 state->pre_vit_error_count = 0;
1217 state->pre_vit_bit_count = 0;
1218 state->ber = 0;
1219 state->post_vit_error_count = 0;
1220 /* state->unc = 0; commented out since it should be ever increasing */
1221 state->abort_count = 0;
1222
1223 state->next_status_check = jiffies;
1224 state->strong = -1;
1225
1226 return 0;
1227}
1228
1229static int af9005_fe_get_frontend(struct dvb_frontend *fe)
1230{
1231 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1232 struct af9005_fe_state *state = fe->demodulator_priv;
1233 int ret;
1234 u8 temp;
1235
1236 /* mode */
1237 ret =
1238 af9005_read_register_bits(state->d, xd_g_reg_tpsd_const,
1239 reg_tpsd_const_pos, reg_tpsd_const_len,
1240 &temp);
1241 if (ret)
1242 return ret;
1243 deb_info("===== fe_get_frontend_legacy = =============\n");
1244 deb_info("CONSTELLATION ");
1245 switch (temp) {
1246 case 0:
1247 fep->modulation = QPSK;
1248 deb_info("QPSK\n");
1249 break;
1250 case 1:
1251 fep->modulation = QAM_16;
1252 deb_info("QAM_16\n");
1253 break;
1254 case 2:
1255 fep->modulation = QAM_64;
1256 deb_info("QAM_64\n");
1257 break;
1258 }
1259
1260 /* tps hierarchy and alpha value */
1261 ret =
1262 af9005_read_register_bits(state->d, xd_g_reg_tpsd_hier,
1263 reg_tpsd_hier_pos, reg_tpsd_hier_len,
1264 &temp);
1265 if (ret)
1266 return ret;
1267 deb_info("HIERARCHY ");
1268 switch (temp) {
1269 case 0:
1270 fep->hierarchy = HIERARCHY_NONE;
1271 deb_info("NONE\n");
1272 break;
1273 case 1:
1274 fep->hierarchy = HIERARCHY_1;
1275 deb_info("1\n");
1276 break;
1277 case 2:
1278 fep->hierarchy = HIERARCHY_2;
1279 deb_info("2\n");
1280 break;
1281 case 3:
1282 fep->hierarchy = HIERARCHY_4;
1283 deb_info("4\n");
1284 break;
1285 }
1286
1287 /* high/low priority */
1288 ret =
1289 af9005_read_register_bits(state->d, xd_g_reg_dec_pri,
1290 reg_dec_pri_pos, reg_dec_pri_len, &temp);
1291 if (ret)
1292 return ret;
1293 /* if temp is set = high priority */
1294 deb_info("PRIORITY %s\n", temp ? "high" : "low");
1295
1296 /* high coderate */
1297 ret =
1298 af9005_read_register_bits(state->d, xd_g_reg_tpsd_hpcr,
1299 reg_tpsd_hpcr_pos, reg_tpsd_hpcr_len,
1300 &temp);
1301 if (ret)
1302 return ret;
1303 deb_info("CODERATE HP ");
1304 switch (temp) {
1305 case 0:
1306 fep->code_rate_HP = FEC_1_2;
1307 deb_info("FEC_1_2\n");
1308 break;
1309 case 1:
1310 fep->code_rate_HP = FEC_2_3;
1311 deb_info("FEC_2_3\n");
1312 break;
1313 case 2:
1314 fep->code_rate_HP = FEC_3_4;
1315 deb_info("FEC_3_4\n");
1316 break;
1317 case 3:
1318 fep->code_rate_HP = FEC_5_6;
1319 deb_info("FEC_5_6\n");
1320 break;
1321 case 4:
1322 fep->code_rate_HP = FEC_7_8;
1323 deb_info("FEC_7_8\n");
1324 break;
1325 }
1326
1327 /* low coderate */
1328 ret =
1329 af9005_read_register_bits(state->d, xd_g_reg_tpsd_lpcr,
1330 reg_tpsd_lpcr_pos, reg_tpsd_lpcr_len,
1331 &temp);
1332 if (ret)
1333 return ret;
1334 deb_info("CODERATE LP ");
1335 switch (temp) {
1336 case 0:
1337 fep->code_rate_LP = FEC_1_2;
1338 deb_info("FEC_1_2\n");
1339 break;
1340 case 1:
1341 fep->code_rate_LP = FEC_2_3;
1342 deb_info("FEC_2_3\n");
1343 break;
1344 case 2:
1345 fep->code_rate_LP = FEC_3_4;
1346 deb_info("FEC_3_4\n");
1347 break;
1348 case 3:
1349 fep->code_rate_LP = FEC_5_6;
1350 deb_info("FEC_5_6\n");
1351 break;
1352 case 4:
1353 fep->code_rate_LP = FEC_7_8;
1354 deb_info("FEC_7_8\n");
1355 break;
1356 }
1357
1358 /* guard interval */
1359 ret =
1360 af9005_read_register_bits(state->d, xd_g_reg_tpsd_gi,
1361 reg_tpsd_gi_pos, reg_tpsd_gi_len, &temp);
1362 if (ret)
1363 return ret;
1364 deb_info("GUARD INTERVAL ");
1365 switch (temp) {
1366 case 0:
1367 fep->guard_interval = GUARD_INTERVAL_1_32;
1368 deb_info("1_32\n");
1369 break;
1370 case 1:
1371 fep->guard_interval = GUARD_INTERVAL_1_16;
1372 deb_info("1_16\n");
1373 break;
1374 case 2:
1375 fep->guard_interval = GUARD_INTERVAL_1_8;
1376 deb_info("1_8\n");
1377 break;
1378 case 3:
1379 fep->guard_interval = GUARD_INTERVAL_1_4;
1380 deb_info("1_4\n");
1381 break;
1382 }
1383
1384 /* fft */
1385 ret =
1386 af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod,
1387 reg_tpsd_txmod_pos, reg_tpsd_txmod_len,
1388 &temp);
1389 if (ret)
1390 return ret;
1391 deb_info("TRANSMISSION MODE ");
1392 switch (temp) {
1393 case 0:
1394 fep->transmission_mode = TRANSMISSION_MODE_2K;
1395 deb_info("2K\n");
1396 break;
1397 case 1:
1398 fep->transmission_mode = TRANSMISSION_MODE_8K;
1399 deb_info("8K\n");
1400 break;
1401 }
1402
1403 /* bandwidth */
1404 ret =
1405 af9005_read_register_bits(state->d, xd_g_reg_bw, reg_bw_pos,
1406 reg_bw_len, &temp);
1407 deb_info("BANDWIDTH ");
1408 switch (temp) {
1409 case 0:
1410 fep->bandwidth_hz = 6000000;
1411 deb_info("6\n");
1412 break;
1413 case 1:
1414 fep->bandwidth_hz = 7000000;
1415 deb_info("7\n");
1416 break;
1417 case 2:
1418 fep->bandwidth_hz = 8000000;
1419 deb_info("8\n");
1420 break;
1421 }
1422 return 0;
1423}
1424
1425static void af9005_fe_release(struct dvb_frontend *fe)
1426{
1427 struct af9005_fe_state *state =
1428 (struct af9005_fe_state *)fe->demodulator_priv;
1429 kfree(state);
1430}
1431
1432static struct dvb_frontend_ops af9005_fe_ops;
1433
1434struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d)
1435{
1436 struct af9005_fe_state *state = NULL;
1437
1438 /* allocate memory for the internal state */
1439 state = kzalloc(sizeof(struct af9005_fe_state), GFP_KERNEL);
1440 if (state == NULL)
1441 goto error;
1442
1443 deb_info("attaching frontend af9005\n");
1444
1445 state->d = d;
1446 state->opened = 0;
1447
1448 memcpy(&state->frontend.ops, &af9005_fe_ops,
1449 sizeof(struct dvb_frontend_ops));
1450 state->frontend.demodulator_priv = state;
1451
1452 return &state->frontend;
1453 error:
1454 return NULL;
1455}
1456
1457static struct dvb_frontend_ops af9005_fe_ops = {
1458 .delsys = { SYS_DVBT },
1459 .info = {
1460 .name = "AF9005 USB DVB-T",
1461 .frequency_min = 44250000,
1462 .frequency_max = 867250000,
1463 .frequency_stepsize = 250000,
1464 .caps = FE_CAN_INVERSION_AUTO |
1465 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1466 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1467 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
1468 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
1469 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |
1470 FE_CAN_HIERARCHY_AUTO,
1471 },
1472
1473 .release = af9005_fe_release,
1474
1475 .init = af9005_fe_init,
1476 .sleep = af9005_fe_sleep,
1477 .ts_bus_ctrl = af9005_ts_bus_ctrl,
1478
1479 .set_frontend = af9005_fe_set_frontend,
1480 .get_frontend = af9005_fe_get_frontend,
1481
1482 .read_status = af9005_fe_read_status,
1483 .read_ber = af9005_fe_read_ber,
1484 .read_signal_strength = af9005_fe_read_signal_strength,
1485 .read_snr = af9005_fe_read_snr,
1486 .read_ucblocks = af9005_fe_read_unc_blocks,
1487};
diff --git a/drivers/media/usb/dvb-usb/af9005-remote.c b/drivers/media/usb/dvb-usb/af9005-remote.c
new file mode 100644
index 000000000000..7e3961d0db6b
--- /dev/null
+++ b/drivers/media/usb/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/README.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/usb/dvb-usb/af9005-script.h b/drivers/media/usb/dvb-usb/af9005-script.h
new file mode 100644
index 000000000000..4d69045426dd
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/af9005.c b/drivers/media/usb/dvb-usb/af9005.c
new file mode 100644
index 000000000000..af176b6ce738
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/af9005.c
@@ -0,0 +1,1117 @@
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/README.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 */
33bool 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_adap[0].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
980enum af9005_usb_table_entry {
981 AFATECH_AF9005,
982 TERRATEC_AF9005,
983 ANSONIC_AF9005,
984};
985
986static struct usb_device_id af9005_usb_table[] = {
987 [AFATECH_AF9005] = {USB_DEVICE(USB_VID_AFATECH,
988 USB_PID_AFATECH_AF9005)},
989 [TERRATEC_AF9005] = {USB_DEVICE(USB_VID_TERRATEC,
990 USB_PID_TERRATEC_CINERGY_T_USB_XE)},
991 [ANSONIC_AF9005] = {USB_DEVICE(USB_VID_ANSONIC,
992 USB_PID_ANSONIC_DVBT_USB)},
993 { }
994};
995
996MODULE_DEVICE_TABLE(usb, af9005_usb_table);
997
998static struct dvb_usb_device_properties af9005_properties = {
999 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1000
1001 .usb_ctrl = DEVICE_SPECIFIC,
1002 .firmware = "af9005.fw",
1003 .download_firmware = af9005_download_firmware,
1004 .no_reconnect = 1,
1005
1006 .size_of_priv = sizeof(struct af9005_device_state),
1007
1008 .num_adapters = 1,
1009 .adapter = {
1010 {
1011 .num_frontends = 1,
1012 .fe = {{
1013 .caps =
1014 DVB_USB_ADAP_HAS_PID_FILTER |
1015 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1016 .pid_filter_count = 32,
1017 .pid_filter = af9005_pid_filter,
1018 /* .pid_filter_ctrl = af9005_pid_filter_control, */
1019 .frontend_attach = af9005_frontend_attach,
1020 /* .tuner_attach = af9005_tuner_attach, */
1021 /* parameter for the MPEG2-data transfer */
1022 .stream = {
1023 .type = USB_BULK,
1024 .count = 10,
1025 .endpoint = 0x04,
1026 .u = {
1027 .bulk = {
1028 .buffersize = 4096, /* actual size seen is 3948 */
1029 }
1030 }
1031 },
1032 }},
1033 }
1034 },
1035 .power_ctrl = af9005_power_ctrl,
1036 .identify_state = af9005_identify_state,
1037
1038 .i2c_algo = &af9005_i2c_algo,
1039
1040 .rc.legacy = {
1041 .rc_interval = 200,
1042 .rc_map_table = NULL,
1043 .rc_map_size = 0,
1044 .rc_query = af9005_rc_query,
1045 },
1046
1047 .generic_bulk_ctrl_endpoint = 2,
1048 .generic_bulk_ctrl_endpoint_response = 1,
1049
1050 .num_device_descs = 3,
1051 .devices = {
1052 {.name = "Afatech DVB-T USB1.1 stick",
1053 .cold_ids = {&af9005_usb_table[AFATECH_AF9005], NULL},
1054 .warm_ids = {NULL},
1055 },
1056 {.name = "TerraTec Cinergy T USB XE",
1057 .cold_ids = {&af9005_usb_table[TERRATEC_AF9005], NULL},
1058 .warm_ids = {NULL},
1059 },
1060 {.name = "Ansonic DVB-T USB1.1 stick",
1061 .cold_ids = {&af9005_usb_table[ANSONIC_AF9005], NULL},
1062 .warm_ids = {NULL},
1063 },
1064 {NULL},
1065 }
1066};
1067
1068/* usb specific object needed to register this driver with the usb subsystem */
1069static struct usb_driver af9005_usb_driver = {
1070 .name = "dvb_usb_af9005",
1071 .probe = af9005_usb_probe,
1072 .disconnect = dvb_usb_device_exit,
1073 .id_table = af9005_usb_table,
1074};
1075
1076/* module stuff */
1077static int __init af9005_usb_module_init(void)
1078{
1079 int result;
1080 if ((result = usb_register(&af9005_usb_driver))) {
1081 err("usb_register failed. (%d)", result);
1082 return result;
1083 }
1084 rc_decode = symbol_request(af9005_rc_decode);
1085 rc_keys = symbol_request(rc_map_af9005_table);
1086 rc_keys_size = symbol_request(rc_map_af9005_table_size);
1087 if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) {
1088 err("af9005_rc_decode function not found, disabling remote");
1089 af9005_properties.rc.legacy.rc_query = NULL;
1090 } else {
1091 af9005_properties.rc.legacy.rc_map_table = rc_keys;
1092 af9005_properties.rc.legacy.rc_map_size = *rc_keys_size;
1093 }
1094
1095 return 0;
1096}
1097
1098static void __exit af9005_usb_module_exit(void)
1099{
1100 /* release rc decode symbols */
1101 if (rc_decode != NULL)
1102 symbol_put(af9005_rc_decode);
1103 if (rc_keys != NULL)
1104 symbol_put(rc_map_af9005_table);
1105 if (rc_keys_size != NULL)
1106 symbol_put(rc_map_af9005_table_size);
1107 /* deregister this driver from the USB subsystem */
1108 usb_deregister(&af9005_usb_driver);
1109}
1110
1111module_init(af9005_usb_module_init);
1112module_exit(af9005_usb_module_exit);
1113
1114MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");
1115MODULE_DESCRIPTION("Driver for Afatech 9005 DVB-T USB1.1 stick");
1116MODULE_VERSION("1.0");
1117MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/af9005.h b/drivers/media/usb/dvb-usb/af9005.h
new file mode 100644
index 000000000000..6a2bf3de8456
--- /dev/null
+++ b/drivers/media/usb/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 bool 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/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
new file mode 100644
index 000000000000..5e45ae605427
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/az6027.c
@@ -0,0 +1,1182 @@
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_DISSTATUS , 0x20 },
44 { STB0899_DISF22 , 0x99 },
45 { STB0899_DISF22RX , 0xa8 },
46 /* SYSREG ? */
47 { STB0899_ACRPRESC , 0x11 },
48 { STB0899_ACRDIV1 , 0x0a },
49 { STB0899_ACRDIV2 , 0x05 },
50 { STB0899_DACR1 , 0x00 },
51 { STB0899_DACR2 , 0x00 },
52 { STB0899_OUTCFG , 0x00 },
53 { STB0899_MODECFG , 0x00 },
54 { STB0899_IRQSTATUS_3 , 0xfe },
55 { STB0899_IRQSTATUS_2 , 0x03 },
56 { STB0899_IRQSTATUS_1 , 0x7c },
57 { STB0899_IRQSTATUS_0 , 0xf4 },
58 { STB0899_IRQMSK_3 , 0xf3 },
59 { STB0899_IRQMSK_2 , 0xfc },
60 { STB0899_IRQMSK_1 , 0xff },
61 { STB0899_IRQMSK_0 , 0xff },
62 { STB0899_IRQCFG , 0x00 },
63 { STB0899_I2CCFG , 0x88 },
64 { STB0899_I2CRPT , 0x58 },
65 { STB0899_IOPVALUE5 , 0x00 },
66 { STB0899_IOPVALUE4 , 0x33 },
67 { STB0899_IOPVALUE3 , 0x6d },
68 { STB0899_IOPVALUE2 , 0x90 },
69 { STB0899_IOPVALUE1 , 0x60 },
70 { STB0899_IOPVALUE0 , 0x00 },
71 { STB0899_GPIO00CFG , 0x82 },
72 { STB0899_GPIO01CFG , 0x82 },
73 { STB0899_GPIO02CFG , 0x82 },
74 { STB0899_GPIO03CFG , 0x82 },
75 { STB0899_GPIO04CFG , 0x82 },
76 { STB0899_GPIO05CFG , 0x82 },
77 { STB0899_GPIO06CFG , 0x82 },
78 { STB0899_GPIO07CFG , 0x82 },
79 { STB0899_GPIO08CFG , 0x82 },
80 { STB0899_GPIO09CFG , 0x82 },
81 { STB0899_GPIO10CFG , 0x82 },
82 { STB0899_GPIO11CFG , 0x82 },
83 { STB0899_GPIO12CFG , 0x82 },
84 { STB0899_GPIO13CFG , 0x82 },
85 { STB0899_GPIO14CFG , 0x82 },
86 { STB0899_GPIO15CFG , 0x82 },
87 { STB0899_GPIO16CFG , 0x82 },
88 { STB0899_GPIO17CFG , 0x82 },
89 { STB0899_GPIO18CFG , 0x82 },
90 { STB0899_GPIO19CFG , 0x82 },
91 { STB0899_GPIO20CFG , 0x82 },
92 { STB0899_SDATCFG , 0xb8 },
93 { STB0899_SCLTCFG , 0xba },
94 { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
95 { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
96 { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
97 { STB0899_DIRCLKCFG , 0x82 },
98 { STB0899_CLKOUT27CFG , 0x7e },
99 { STB0899_STDBYCFG , 0x82 },
100 { STB0899_CS0CFG , 0x82 },
101 { STB0899_CS1CFG , 0x82 },
102 { STB0899_DISEQCOCFG , 0x20 },
103 { STB0899_GPIO32CFG , 0x82 },
104 { STB0899_GPIO33CFG , 0x82 },
105 { STB0899_GPIO34CFG , 0x82 },
106 { STB0899_GPIO35CFG , 0x82 },
107 { STB0899_GPIO36CFG , 0x82 },
108 { STB0899_GPIO37CFG , 0x82 },
109 { STB0899_GPIO38CFG , 0x82 },
110 { STB0899_GPIO39CFG , 0x82 },
111 { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
112 { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
113 { STB0899_FILTCTRL , 0x00 },
114 { STB0899_SYSCTRL , 0x01 },
115 { STB0899_STOPCLK1 , 0x20 },
116 { STB0899_STOPCLK2 , 0x00 },
117 { STB0899_INTBUFSTATUS , 0x00 },
118 { STB0899_INTBUFCTRL , 0x0a },
119 { 0xffff , 0xff },
120};
121
122static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
123 { STB0899_DEMOD , 0x00 },
124 { STB0899_RCOMPC , 0xc9 },
125 { STB0899_AGC1CN , 0x01 },
126 { STB0899_AGC1REF , 0x10 },
127 { STB0899_RTC , 0x23 },
128 { STB0899_TMGCFG , 0x4e },
129 { STB0899_AGC2REF , 0x34 },
130 { STB0899_TLSR , 0x84 },
131 { STB0899_CFD , 0xf7 },
132 { STB0899_ACLC , 0x87 },
133 { STB0899_BCLC , 0x94 },
134 { STB0899_EQON , 0x41 },
135 { STB0899_LDT , 0xf1 },
136 { STB0899_LDT2 , 0xe3 },
137 { STB0899_EQUALREF , 0xb4 },
138 { STB0899_TMGRAMP , 0x10 },
139 { STB0899_TMGTHD , 0x30 },
140 { STB0899_IDCCOMP , 0xfd },
141 { STB0899_QDCCOMP , 0xff },
142 { STB0899_POWERI , 0x0c },
143 { STB0899_POWERQ , 0x0f },
144 { STB0899_RCOMP , 0x6c },
145 { STB0899_AGCIQIN , 0x80 },
146 { STB0899_AGC2I1 , 0x06 },
147 { STB0899_AGC2I2 , 0x00 },
148 { STB0899_TLIR , 0x30 },
149 { STB0899_RTF , 0x7f },
150 { STB0899_DSTATUS , 0x00 },
151 { STB0899_LDI , 0xbc },
152 { STB0899_CFRM , 0xea },
153 { STB0899_CFRL , 0x31 },
154 { STB0899_NIRM , 0x2b },
155 { STB0899_NIRL , 0x80 },
156 { STB0899_ISYMB , 0x1d },
157 { STB0899_QSYMB , 0xa6 },
158 { STB0899_SFRH , 0x2f },
159 { STB0899_SFRM , 0x68 },
160 { STB0899_SFRL , 0x40 },
161 { STB0899_SFRUPH , 0x2f },
162 { STB0899_SFRUPM , 0x68 },
163 { STB0899_SFRUPL , 0x40 },
164 { STB0899_EQUAI1 , 0x02 },
165 { STB0899_EQUAQ1 , 0xff },
166 { STB0899_EQUAI2 , 0x04 },
167 { STB0899_EQUAQ2 , 0x05 },
168 { STB0899_EQUAI3 , 0x02 },
169 { STB0899_EQUAQ3 , 0xfd },
170 { STB0899_EQUAI4 , 0x03 },
171 { STB0899_EQUAQ4 , 0x07 },
172 { STB0899_EQUAI5 , 0x08 },
173 { STB0899_EQUAQ5 , 0xf5 },
174 { STB0899_DSTATUS2 , 0x00 },
175 { STB0899_VSTATUS , 0x00 },
176 { STB0899_VERROR , 0x86 },
177 { STB0899_IQSWAP , 0x2a },
178 { STB0899_ECNT1M , 0x00 },
179 { STB0899_ECNT1L , 0x00 },
180 { STB0899_ECNT2M , 0x00 },
181 { STB0899_ECNT2L , 0x00 },
182 { STB0899_ECNT3M , 0x0a },
183 { STB0899_ECNT3L , 0xad },
184 { STB0899_FECAUTO1 , 0x06 },
185 { STB0899_FECM , 0x01 },
186 { STB0899_VTH12 , 0xb0 },
187 { STB0899_VTH23 , 0x7a },
188 { STB0899_VTH34 , 0x58 },
189 { STB0899_VTH56 , 0x38 },
190 { STB0899_VTH67 , 0x34 },
191 { STB0899_VTH78 , 0x24 },
192 { STB0899_PRVIT , 0xff },
193 { STB0899_VITSYNC , 0x19 },
194 { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
195 { STB0899_TSULC , 0x42 },
196 { STB0899_RSLLC , 0x41 },
197 { STB0899_TSLPL , 0x12 },
198 { STB0899_TSCFGH , 0x0c },
199 { STB0899_TSCFGM , 0x00 },
200 { STB0899_TSCFGL , 0x00 },
201 { STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */
202 { STB0899_RSSYNCDEL , 0x00 },
203 { STB0899_TSINHDELH , 0x02 },
204 { STB0899_TSINHDELM , 0x00 },
205 { STB0899_TSINHDELL , 0x00 },
206 { STB0899_TSLLSTKM , 0x1b },
207 { STB0899_TSLLSTKL , 0xb3 },
208 { STB0899_TSULSTKM , 0x00 },
209 { STB0899_TSULSTKL , 0x00 },
210 { STB0899_PCKLENUL , 0xbc },
211 { STB0899_PCKLENLL , 0xcc },
212 { STB0899_RSPCKLEN , 0xbd },
213 { STB0899_TSSTATUS , 0x90 },
214 { STB0899_ERRCTRL1 , 0xb6 },
215 { STB0899_ERRCTRL2 , 0x95 },
216 { STB0899_ERRCTRL3 , 0x8d },
217 { STB0899_DMONMSK1 , 0x27 },
218 { STB0899_DMONMSK0 , 0x03 },
219 { STB0899_DEMAPVIT , 0x5c },
220 { STB0899_PLPARM , 0x19 },
221 { STB0899_PDELCTRL , 0x48 },
222 { STB0899_PDELCTRL2 , 0x00 },
223 { STB0899_BBHCTRL1 , 0x00 },
224 { STB0899_BBHCTRL2 , 0x00 },
225 { STB0899_HYSTTHRESH , 0x77 },
226 { STB0899_MATCSTM , 0x00 },
227 { STB0899_MATCSTL , 0x00 },
228 { STB0899_UPLCSTM , 0x00 },
229 { STB0899_UPLCSTL , 0x00 },
230 { STB0899_DFLCSTM , 0x00 },
231 { STB0899_DFLCSTL , 0x00 },
232 { STB0899_SYNCCST , 0x00 },
233 { STB0899_SYNCDCSTM , 0x00 },
234 { STB0899_SYNCDCSTL , 0x00 },
235 { STB0899_ISI_ENTRY , 0x00 },
236 { STB0899_ISI_BIT_EN , 0x00 },
237 { STB0899_MATSTRM , 0xf0 },
238 { STB0899_MATSTRL , 0x02 },
239 { STB0899_UPLSTRM , 0x45 },
240 { STB0899_UPLSTRL , 0x60 },
241 { STB0899_DFLSTRM , 0xe3 },
242 { STB0899_DFLSTRL , 0x00 },
243 { STB0899_SYNCSTR , 0x47 },
244 { STB0899_SYNCDSTRM , 0x05 },
245 { STB0899_SYNCDSTRL , 0x18 },
246 { STB0899_CFGPDELSTATUS1 , 0x19 },
247 { STB0899_CFGPDELSTATUS2 , 0x2b },
248 { STB0899_BBFERRORM , 0x00 },
249 { STB0899_BBFERRORL , 0x01 },
250 { STB0899_UPKTERRORM , 0x00 },
251 { STB0899_UPKTERRORL , 0x00 },
252 { 0xffff , 0xff },
253};
254
255
256
257struct stb0899_config az6027_stb0899_config = {
258 .init_dev = az6027_stb0899_s1_init_1,
259 .init_s2_demod = stb0899_s2_init_2,
260 .init_s1_demod = az6027_stb0899_s1_init_3,
261 .init_s2_fec = stb0899_s2_init_4,
262 .init_tst = stb0899_s1_init_5,
263
264 .demod_address = 0xd0, /* 0x68, 0xd0 >> 1 */
265
266 .xtal_freq = 27000000,
267 .inversion = IQ_SWAP_ON, /* 1 */
268
269 .lo_clk = 76500000,
270 .hi_clk = 99000000,
271
272 .esno_ave = STB0899_DVBS2_ESNO_AVE,
273 .esno_quant = STB0899_DVBS2_ESNO_QUANT,
274 .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
275 .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
276 .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
277 .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
278 .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
279 .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
280 .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
281
282 .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
283 .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
284 .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
285 .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
286
287 .tuner_get_frequency = stb6100_get_frequency,
288 .tuner_set_frequency = stb6100_set_frequency,
289 .tuner_set_bandwidth = stb6100_set_bandwidth,
290 .tuner_get_bandwidth = stb6100_get_bandwidth,
291 .tuner_set_rfsiggain = NULL,
292};
293
294struct stb6100_config az6027_stb6100_config = {
295 .tuner_address = 0xc0,
296 .refclock = 27000000,
297};
298
299
300/* check for mutex FIXME */
301int az6027_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
302{
303 int ret = -1;
304 if (mutex_lock_interruptible(&d->usb_mutex))
305 return -EAGAIN;
306
307 ret = usb_control_msg(d->udev,
308 usb_rcvctrlpipe(d->udev, 0),
309 req,
310 USB_TYPE_VENDOR | USB_DIR_IN,
311 value,
312 index,
313 b,
314 blen,
315 2000);
316
317 if (ret < 0) {
318 warn("usb in operation failed. (%d)", ret);
319 ret = -EIO;
320 } else
321 ret = 0;
322
323 deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
324 debug_dump(b, blen, deb_xfer);
325
326 mutex_unlock(&d->usb_mutex);
327 return ret;
328}
329
330static int az6027_usb_out_op(struct dvb_usb_device *d,
331 u8 req,
332 u16 value,
333 u16 index,
334 u8 *b,
335 int blen)
336{
337 int ret;
338
339 deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
340 debug_dump(b, blen, deb_xfer);
341
342 if (mutex_lock_interruptible(&d->usb_mutex))
343 return -EAGAIN;
344
345 ret = usb_control_msg(d->udev,
346 usb_sndctrlpipe(d->udev, 0),
347 req,
348 USB_TYPE_VENDOR | USB_DIR_OUT,
349 value,
350 index,
351 b,
352 blen,
353 2000);
354
355 if (ret != blen) {
356 warn("usb out operation failed. (%d)", ret);
357 mutex_unlock(&d->usb_mutex);
358 return -EIO;
359 } else{
360 mutex_unlock(&d->usb_mutex);
361 return 0;
362 }
363}
364
365static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
366{
367 int ret;
368 u8 req;
369 u16 value;
370 u16 index;
371 int blen;
372
373 deb_info("%s %d", __func__, onoff);
374
375 req = 0xBC;
376 value = onoff;
377 index = 0;
378 blen = 0;
379
380 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
381 if (ret != 0)
382 warn("usb out operation failed. (%d)", ret);
383
384 return ret;
385}
386
387/* keys for the enclosed remote control */
388static struct rc_map_table rc_map_az6027_table[] = {
389 { 0x01, KEY_1 },
390 { 0x02, KEY_2 },
391};
392
393/* remote control stuff (does not work with my box) */
394static int az6027_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
395{
396 return 0;
397}
398
399/*
400int az6027_power_ctrl(struct dvb_usb_device *d, int onoff)
401{
402 u8 v = onoff;
403 return az6027_usb_out_op(d,0xBC,v,3,NULL,1);
404}
405*/
406
407static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
408 int slot,
409 int address)
410{
411 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
412 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
413
414 int ret;
415 u8 req;
416 u16 value;
417 u16 index;
418 int blen;
419 u8 *b;
420
421 if (slot != 0)
422 return -EINVAL;
423
424 b = kmalloc(12, GFP_KERNEL);
425 if (!b)
426 return -ENOMEM;
427
428 mutex_lock(&state->ca_mutex);
429
430 req = 0xC1;
431 value = address;
432 index = 0;
433 blen = 1;
434
435 ret = az6027_usb_in_op(d, req, value, index, b, blen);
436 if (ret < 0) {
437 warn("usb in operation failed. (%d)", ret);
438 ret = -EINVAL;
439 } else {
440 ret = b[0];
441 }
442
443 mutex_unlock(&state->ca_mutex);
444 kfree(b);
445 return ret;
446}
447
448static int az6027_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
449 int slot,
450 int address,
451 u8 value)
452{
453 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
454 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
455
456 int ret;
457 u8 req;
458 u16 value1;
459 u16 index;
460 int blen;
461
462 deb_info("%s %d", __func__, slot);
463 if (slot != 0)
464 return -EINVAL;
465
466 mutex_lock(&state->ca_mutex);
467 req = 0xC2;
468 value1 = address;
469 index = value;
470 blen = 0;
471
472 ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
473 if (ret != 0)
474 warn("usb out operation failed. (%d)", ret);
475
476 mutex_unlock(&state->ca_mutex);
477 return ret;
478}
479
480static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca,
481 int slot,
482 u8 address)
483{
484 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
485 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
486
487 int ret;
488 u8 req;
489 u16 value;
490 u16 index;
491 int blen;
492 u8 *b;
493
494 if (slot != 0)
495 return -EINVAL;
496
497 b = kmalloc(12, GFP_KERNEL);
498 if (!b)
499 return -ENOMEM;
500
501 mutex_lock(&state->ca_mutex);
502
503 req = 0xC3;
504 value = address;
505 index = 0;
506 blen = 2;
507
508 ret = az6027_usb_in_op(d, req, value, index, b, blen);
509 if (ret < 0) {
510 warn("usb in operation failed. (%d)", ret);
511 ret = -EINVAL;
512 } else {
513 if (b[0] == 0)
514 warn("Read CI IO error");
515
516 ret = b[1];
517 deb_info("read cam data = %x from 0x%x", b[1], value);
518 }
519
520 mutex_unlock(&state->ca_mutex);
521 kfree(b);
522 return ret;
523}
524
525static int az6027_ci_write_cam_control(struct dvb_ca_en50221 *ca,
526 int slot,
527 u8 address,
528 u8 value)
529{
530 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
531 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
532
533 int ret;
534 u8 req;
535 u16 value1;
536 u16 index;
537 int blen;
538
539 if (slot != 0)
540 return -EINVAL;
541
542 mutex_lock(&state->ca_mutex);
543 req = 0xC4;
544 value1 = address;
545 index = value;
546 blen = 0;
547
548 ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
549 if (ret != 0) {
550 warn("usb out operation failed. (%d)", ret);
551 goto failed;
552 }
553
554failed:
555 mutex_unlock(&state->ca_mutex);
556 return ret;
557}
558
559static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
560{
561 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
562
563 int ret;
564 u8 req;
565 u16 value;
566 u16 index;
567 int blen;
568 u8 *b;
569
570 b = kmalloc(12, GFP_KERNEL);
571 if (!b)
572 return -ENOMEM;
573
574 req = 0xC8;
575 value = 0;
576 index = 0;
577 blen = 1;
578
579 ret = az6027_usb_in_op(d, req, value, index, b, blen);
580 if (ret < 0) {
581 warn("usb in operation failed. (%d)", ret);
582 ret = -EIO;
583 } else{
584 ret = b[0];
585 }
586 kfree(b);
587 return ret;
588}
589
590static int az6027_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
591{
592 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
593 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
594
595 int ret, i;
596 u8 req;
597 u16 value;
598 u16 index;
599 int blen;
600
601 mutex_lock(&state->ca_mutex);
602
603 req = 0xC6;
604 value = 1;
605 index = 0;
606 blen = 0;
607
608 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
609 if (ret != 0) {
610 warn("usb out operation failed. (%d)", ret);
611 goto failed;
612 }
613
614 msleep(500);
615 req = 0xC6;
616 value = 0;
617 index = 0;
618 blen = 0;
619
620 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
621 if (ret != 0) {
622 warn("usb out operation failed. (%d)", ret);
623 goto failed;
624 }
625
626 for (i = 0; i < 15; i++) {
627 msleep(100);
628
629 if (CI_CamReady(ca, slot)) {
630 deb_info("CAM Ready");
631 break;
632 }
633 }
634 msleep(5000);
635
636failed:
637 mutex_unlock(&state->ca_mutex);
638 return ret;
639}
640
641static int az6027_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
642{
643 return 0;
644}
645
646static int az6027_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
647{
648 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
649 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
650
651 int ret;
652 u8 req;
653 u16 value;
654 u16 index;
655 int blen;
656
657 deb_info("%s", __func__);
658 mutex_lock(&state->ca_mutex);
659 req = 0xC7;
660 value = 1;
661 index = 0;
662 blen = 0;
663
664 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
665 if (ret != 0) {
666 warn("usb out operation failed. (%d)", ret);
667 goto failed;
668 }
669
670failed:
671 mutex_unlock(&state->ca_mutex);
672 return ret;
673}
674
675static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
676{
677 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
678 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
679 int ret;
680 u8 req;
681 u16 value;
682 u16 index;
683 int blen;
684 u8 *b;
685
686 b = kmalloc(12, GFP_KERNEL);
687 if (!b)
688 return -ENOMEM;
689 mutex_lock(&state->ca_mutex);
690
691 req = 0xC5;
692 value = 0;
693 index = 0;
694 blen = 1;
695
696 ret = az6027_usb_in_op(d, req, value, index, b, blen);
697 if (ret < 0) {
698 warn("usb in operation failed. (%d)", ret);
699 ret = -EIO;
700 } else
701 ret = 0;
702
703 if (!ret && b[0] == 1) {
704 ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
705 DVB_CA_EN50221_POLL_CAM_READY;
706 }
707
708 mutex_unlock(&state->ca_mutex);
709 kfree(b);
710 return ret;
711}
712
713
714static void az6027_ci_uninit(struct dvb_usb_device *d)
715{
716 struct az6027_device_state *state;
717
718 deb_info("%s", __func__);
719
720 if (NULL == d)
721 return;
722
723 state = (struct az6027_device_state *)d->priv;
724 if (NULL == state)
725 return;
726
727 if (NULL == state->ca.data)
728 return;
729
730 dvb_ca_en50221_release(&state->ca);
731
732 memset(&state->ca, 0, sizeof(state->ca));
733}
734
735
736static int az6027_ci_init(struct dvb_usb_adapter *a)
737{
738 struct dvb_usb_device *d = a->dev;
739 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
740 int ret;
741
742 deb_info("%s", __func__);
743
744 mutex_init(&state->ca_mutex);
745
746 state->ca.owner = THIS_MODULE;
747 state->ca.read_attribute_mem = az6027_ci_read_attribute_mem;
748 state->ca.write_attribute_mem = az6027_ci_write_attribute_mem;
749 state->ca.read_cam_control = az6027_ci_read_cam_control;
750 state->ca.write_cam_control = az6027_ci_write_cam_control;
751 state->ca.slot_reset = az6027_ci_slot_reset;
752 state->ca.slot_shutdown = az6027_ci_slot_shutdown;
753 state->ca.slot_ts_enable = az6027_ci_slot_ts_enable;
754 state->ca.poll_slot_status = az6027_ci_poll_slot_status;
755 state->ca.data = d;
756
757 ret = dvb_ca_en50221_init(&a->dvb_adap,
758 &state->ca,
759 0, /* flags */
760 1);/* n_slots */
761 if (ret != 0) {
762 err("Cannot initialize CI: Error %d.", ret);
763 memset(&state->ca, 0, sizeof(state->ca));
764 return ret;
765 }
766
767 deb_info("CI initialized.");
768
769 return 0;
770}
771
772/*
773static int az6027_read_mac_addr(struct dvb_usb_device *d, u8 mac[6])
774{
775 az6027_usb_in_op(d, 0xb7, 6, 0, &mac[0], 6);
776 return 0;
777}
778*/
779
780static int az6027_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
781{
782
783 u8 buf;
784 struct dvb_usb_adapter *adap = fe->dvb->priv;
785
786 struct i2c_msg i2c_msg = {
787 .addr = 0x99,
788 .flags = 0,
789 .buf = &buf,
790 .len = 1
791 };
792
793 /*
794 * 2 --18v
795 * 1 --13v
796 * 0 --off
797 */
798 switch (voltage) {
799 case SEC_VOLTAGE_13:
800 buf = 1;
801 i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
802 break;
803
804 case SEC_VOLTAGE_18:
805 buf = 2;
806 i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
807 break;
808
809 case SEC_VOLTAGE_OFF:
810 buf = 0;
811 i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
812 break;
813
814 default:
815 return -EINVAL;
816 }
817 return 0;
818}
819
820
821static int az6027_frontend_poweron(struct dvb_usb_adapter *adap)
822{
823 int ret;
824 u8 req;
825 u16 value;
826 u16 index;
827 int blen;
828
829 req = 0xBC;
830 value = 1; /* power on */
831 index = 3;
832 blen = 0;
833
834 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
835 if (ret != 0)
836 return -EIO;
837
838 return 0;
839}
840static int az6027_frontend_reset(struct dvb_usb_adapter *adap)
841{
842 int ret;
843 u8 req;
844 u16 value;
845 u16 index;
846 int blen;
847
848 /* reset demodulator */
849 req = 0xC0;
850 value = 1; /* high */
851 index = 3;
852 blen = 0;
853
854 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
855 if (ret != 0)
856 return -EIO;
857
858 req = 0xC0;
859 value = 0; /* low */
860 index = 3;
861 blen = 0;
862 msleep_interruptible(200);
863
864 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
865 if (ret != 0)
866 return -EIO;
867
868 msleep_interruptible(200);
869
870 req = 0xC0;
871 value = 1; /*high */
872 index = 3;
873 blen = 0;
874
875 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
876 if (ret != 0)
877 return -EIO;
878
879 msleep_interruptible(200);
880 return 0;
881}
882
883static int az6027_frontend_tsbypass(struct dvb_usb_adapter *adap, int onoff)
884{
885 int ret;
886 u8 req;
887 u16 value;
888 u16 index;
889 int blen;
890
891 /* TS passthrough */
892 req = 0xC7;
893 value = onoff;
894 index = 0;
895 blen = 0;
896
897 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
898 if (ret != 0)
899 return -EIO;
900
901 return 0;
902}
903
904static int az6027_frontend_attach(struct dvb_usb_adapter *adap)
905{
906
907 az6027_frontend_poweron(adap);
908 az6027_frontend_reset(adap);
909
910 deb_info("adap = %p, dev = %p\n", adap, adap->dev);
911 adap->fe_adap[0].fe = stb0899_attach(&az6027_stb0899_config, &adap->dev->i2c_adap);
912
913 if (adap->fe_adap[0].fe) {
914 deb_info("found STB0899 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb0899_config.demod_address);
915 if (stb6100_attach(adap->fe_adap[0].fe, &az6027_stb6100_config, &adap->dev->i2c_adap)) {
916 deb_info("found STB6100 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb6100_config.tuner_address);
917 adap->fe_adap[0].fe->ops.set_voltage = az6027_set_voltage;
918 az6027_ci_init(adap);
919 } else {
920 adap->fe_adap[0].fe = NULL;
921 }
922 } else
923 warn("no front-end attached\n");
924
925 az6027_frontend_tsbypass(adap, 0);
926
927 return 0;
928}
929
930static struct dvb_usb_device_properties az6027_properties;
931
932static void az6027_usb_disconnect(struct usb_interface *intf)
933{
934 struct dvb_usb_device *d = usb_get_intfdata(intf);
935 az6027_ci_uninit(d);
936 dvb_usb_device_exit(intf);
937}
938
939
940static int az6027_usb_probe(struct usb_interface *intf,
941 const struct usb_device_id *id)
942{
943 return dvb_usb_device_init(intf,
944 &az6027_properties,
945 THIS_MODULE,
946 NULL,
947 adapter_nr);
948}
949
950/* I2C */
951static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
952{
953 struct dvb_usb_device *d = i2c_get_adapdata(adap);
954 int i = 0, j = 0, len = 0;
955 u16 index;
956 u16 value;
957 int length;
958 u8 req;
959 u8 *data;
960
961 data = kmalloc(256, GFP_KERNEL);
962 if (!data)
963 return -ENOMEM;
964
965 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) {
966 kfree(data);
967 return -EAGAIN;
968 }
969
970 if (num > 2)
971 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
972
973 for (i = 0; i < num; i++) {
974
975 if (msg[i].addr == 0x99) {
976 req = 0xBE;
977 index = 0;
978 value = msg[i].buf[0] & 0x00ff;
979 length = 1;
980 az6027_usb_out_op(d, req, value, index, data, length);
981 }
982
983 if (msg[i].addr == 0xd0) {
984 /* write/read request */
985 if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
986 req = 0xB9;
987 index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
988 value = msg[i].addr + (msg[i].len << 8);
989 length = msg[i + 1].len + 6;
990 az6027_usb_in_op(d, req, value, index, data, length);
991 len = msg[i + 1].len;
992 for (j = 0; j < len; j++)
993 msg[i + 1].buf[j] = data[j + 5];
994
995 i++;
996 } else {
997
998 /* demod 16bit addr */
999 req = 0xBD;
1000 index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
1001 value = msg[i].addr + (2 << 8);
1002 length = msg[i].len - 2;
1003 len = msg[i].len - 2;
1004 for (j = 0; j < len; j++)
1005 data[j] = msg[i].buf[j + 2];
1006 az6027_usb_out_op(d, req, value, index, data, length);
1007 }
1008 }
1009
1010 if (msg[i].addr == 0xc0) {
1011 if (msg[i].flags & I2C_M_RD) {
1012
1013 req = 0xB9;
1014 index = 0x0;
1015 value = msg[i].addr;
1016 length = msg[i].len + 6;
1017 az6027_usb_in_op(d, req, value, index, data, length);
1018 len = msg[i].len;
1019 for (j = 0; j < len; j++)
1020 msg[i].buf[j] = data[j + 5];
1021
1022 } else {
1023
1024 req = 0xBD;
1025 index = msg[i].buf[0] & 0x00FF;
1026 value = msg[i].addr + (1 << 8);
1027 length = msg[i].len - 1;
1028 len = msg[i].len - 1;
1029
1030 for (j = 0; j < len; j++)
1031 data[j] = msg[i].buf[j + 1];
1032
1033 az6027_usb_out_op(d, req, value, index, data, length);
1034 }
1035 }
1036 }
1037 mutex_unlock(&d->i2c_mutex);
1038 kfree(data);
1039
1040 return i;
1041}
1042
1043
1044static u32 az6027_i2c_func(struct i2c_adapter *adapter)
1045{
1046 return I2C_FUNC_I2C;
1047}
1048
1049static struct i2c_algorithm az6027_i2c_algo = {
1050 .master_xfer = az6027_i2c_xfer,
1051 .functionality = az6027_i2c_func,
1052};
1053
1054int az6027_identify_state(struct usb_device *udev,
1055 struct dvb_usb_device_properties *props,
1056 struct dvb_usb_device_description **desc,
1057 int *cold)
1058{
1059 u8 *b;
1060 s16 ret;
1061
1062 b = kmalloc(16, GFP_KERNEL);
1063 if (!b)
1064 return -ENOMEM;
1065
1066 ret = usb_control_msg(udev,
1067 usb_rcvctrlpipe(udev, 0),
1068 0xb7,
1069 USB_TYPE_VENDOR | USB_DIR_IN,
1070 6,
1071 0,
1072 b,
1073 6,
1074 USB_CTRL_GET_TIMEOUT);
1075
1076 *cold = ret <= 0;
1077 kfree(b);
1078 deb_info("cold: %d\n", *cold);
1079 return 0;
1080}
1081
1082
1083static struct usb_device_id az6027_usb_table[] = {
1084 { USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_AZ6027) },
1085 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_DVBS2CI_V1) },
1086 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_DVBS2CI_V2) },
1087 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V1) },
1088 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V2) },
1089 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT) },
1090 { },
1091};
1092
1093MODULE_DEVICE_TABLE(usb, az6027_usb_table);
1094
1095static struct dvb_usb_device_properties az6027_properties = {
1096 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1097 .usb_ctrl = CYPRESS_FX2,
1098 .firmware = "dvb-usb-az6027-03.fw",
1099 .no_reconnect = 1,
1100
1101 .size_of_priv = sizeof(struct az6027_device_state),
1102 .identify_state = az6027_identify_state,
1103 .num_adapters = 1,
1104 .adapter = {
1105 {
1106 .num_frontends = 1,
1107 .fe = {{
1108 .streaming_ctrl = az6027_streaming_ctrl,
1109 .frontend_attach = az6027_frontend_attach,
1110
1111 /* parameter for the MPEG2-data transfer */
1112 .stream = {
1113 .type = USB_BULK,
1114 .count = 10,
1115 .endpoint = 0x02,
1116 .u = {
1117 .bulk = {
1118 .buffersize = 4096,
1119 }
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
1177module_usb_driver(az6027_usb_driver);
1178
1179MODULE_AUTHOR("Adams Xu <Adams.xu@azwave.com.cn>");
1180MODULE_DESCRIPTION("Driver for AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)");
1181MODULE_VERSION("1.0");
1182MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/az6027.h b/drivers/media/usb/dvb-usb/az6027.h
new file mode 100644
index 000000000000..f3afe17f3f3d
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/cinergyT2-core.c b/drivers/media/usb/dvb-usb/cinergyT2-core.c
new file mode 100644
index 000000000000..0a98548ecd17
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/cinergyT2-core.c
@@ -0,0 +1,254 @@
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_adap[0].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 .num_frontends = 1,
202 .fe = {{
203 .streaming_ctrl = cinergyt2_streaming_ctrl,
204 .frontend_attach = cinergyt2_frontend_attach,
205
206 /* parameter for the MPEG2-data transfer */
207 .stream = {
208 .type = USB_BULK,
209 .count = 5,
210 .endpoint = 0x02,
211 .u = {
212 .bulk = {
213 .buffersize = 512,
214 }
215 }
216 },
217 }},
218 }
219 },
220
221 .power_ctrl = cinergyt2_power_ctrl,
222
223 .rc.legacy = {
224 .rc_interval = 50,
225 .rc_map_table = rc_map_cinergyt2_table,
226 .rc_map_size = ARRAY_SIZE(rc_map_cinergyt2_table),
227 .rc_query = cinergyt2_rc_query,
228 },
229
230 .generic_bulk_ctrl_endpoint = 1,
231
232 .num_device_descs = 1,
233 .devices = {
234 { .name = "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver",
235 .cold_ids = {NULL},
236 .warm_ids = { &cinergyt2_usb_table[0], NULL },
237 },
238 { NULL },
239 }
240};
241
242
243static struct usb_driver cinergyt2_driver = {
244 .name = "cinergyT2",
245 .probe = cinergyt2_usb_probe,
246 .disconnect = dvb_usb_device_exit,
247 .id_table = cinergyt2_usb_table
248};
249
250module_usb_driver(cinergyt2_driver);
251
252MODULE_DESCRIPTION("Terratec Cinergy T2 DVB-T driver");
253MODULE_LICENSE("GPL");
254MODULE_AUTHOR("Tomi Orava");
diff --git a/drivers/media/usb/dvb-usb/cinergyT2-fe.c b/drivers/media/usb/dvb-usb/cinergyT2-fe.c
new file mode 100644
index 000000000000..1efc028a76c9
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/cinergyT2-fe.c
@@ -0,0 +1,356 @@
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 dtv_frontend_properties *op)
44{
45 uint16_t tps = 0;
46
47 switch (op->code_rate_HP) {
48 case FEC_2_3:
49 tps |= (1 << 7);
50 break;
51 case FEC_3_4:
52 tps |= (2 << 7);
53 break;
54 case FEC_5_6:
55 tps |= (3 << 7);
56 break;
57 case FEC_7_8:
58 tps |= (4 << 7);
59 break;
60 case FEC_1_2:
61 case FEC_AUTO:
62 default:
63 /* tps |= (0 << 7) */;
64 }
65
66 switch (op->code_rate_LP) {
67 case FEC_2_3:
68 tps |= (1 << 4);
69 break;
70 case FEC_3_4:
71 tps |= (2 << 4);
72 break;
73 case FEC_5_6:
74 tps |= (3 << 4);
75 break;
76 case FEC_7_8:
77 tps |= (4 << 4);
78 break;
79 case FEC_1_2:
80 case FEC_AUTO:
81 default:
82 /* tps |= (0 << 4) */;
83 }
84
85 switch (op->modulation) {
86 case QAM_16:
87 tps |= (1 << 13);
88 break;
89 case QAM_64:
90 tps |= (2 << 13);
91 break;
92 case QPSK:
93 default:
94 /* tps |= (0 << 13) */;
95 }
96
97 switch (op->transmission_mode) {
98 case TRANSMISSION_MODE_8K:
99 tps |= (1 << 0);
100 break;
101 case TRANSMISSION_MODE_2K:
102 default:
103 /* tps |= (0 << 0) */;
104 }
105
106 switch (op->guard_interval) {
107 case GUARD_INTERVAL_1_16:
108 tps |= (1 << 2);
109 break;
110 case GUARD_INTERVAL_1_8:
111 tps |= (2 << 2);
112 break;
113 case GUARD_INTERVAL_1_4:
114 tps |= (3 << 2);
115 break;
116 case GUARD_INTERVAL_1_32:
117 default:
118 /* tps |= (0 << 2) */;
119 }
120
121 switch (op->hierarchy) {
122 case HIERARCHY_1:
123 tps |= (1 << 10);
124 break;
125 case HIERARCHY_2:
126 tps |= (2 << 10);
127 break;
128 case HIERARCHY_4:
129 tps |= (3 << 10);
130 break;
131 case HIERARCHY_NONE:
132 default:
133 /* tps |= (0 << 10) */;
134 }
135
136 return tps;
137}
138
139struct cinergyt2_fe_state {
140 struct dvb_frontend fe;
141 struct dvb_usb_device *d;
142};
143
144static int cinergyt2_fe_read_status(struct dvb_frontend *fe,
145 fe_status_t *status)
146{
147 struct cinergyt2_fe_state *state = fe->demodulator_priv;
148 struct dvbt_get_status_msg result;
149 u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
150 int ret;
151
152 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&result,
153 sizeof(result), 0);
154 if (ret < 0)
155 return ret;
156
157 *status = 0;
158
159 if (0xffff - le16_to_cpu(result.gain) > 30)
160 *status |= FE_HAS_SIGNAL;
161 if (result.lock_bits & (1 << 6))
162 *status |= FE_HAS_LOCK;
163 if (result.lock_bits & (1 << 5))
164 *status |= FE_HAS_SYNC;
165 if (result.lock_bits & (1 << 4))
166 *status |= FE_HAS_CARRIER;
167 if (result.lock_bits & (1 << 1))
168 *status |= FE_HAS_VITERBI;
169
170 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
171 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
172 *status &= ~FE_HAS_LOCK;
173
174 return 0;
175}
176
177static int cinergyt2_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
178{
179 struct cinergyt2_fe_state *state = fe->demodulator_priv;
180 struct dvbt_get_status_msg status;
181 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
182 int ret;
183
184 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
185 sizeof(status), 0);
186 if (ret < 0)
187 return ret;
188
189 *ber = le32_to_cpu(status.viterbi_error_rate);
190 return 0;
191}
192
193static int cinergyt2_fe_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
194{
195 struct cinergyt2_fe_state *state = fe->demodulator_priv;
196 struct dvbt_get_status_msg status;
197 u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
198 int ret;
199
200 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&status,
201 sizeof(status), 0);
202 if (ret < 0) {
203 err("cinergyt2_fe_read_unc_blocks() Failed! (Error=%d)\n",
204 ret);
205 return ret;
206 }
207 *unc = le32_to_cpu(status.uncorrected_block_count);
208 return 0;
209}
210
211static int cinergyt2_fe_read_signal_strength(struct dvb_frontend *fe,
212 u16 *strength)
213{
214 struct cinergyt2_fe_state *state = fe->demodulator_priv;
215 struct dvbt_get_status_msg status;
216 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
217 int ret;
218
219 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
220 sizeof(status), 0);
221 if (ret < 0) {
222 err("cinergyt2_fe_read_signal_strength() Failed!"
223 " (Error=%d)\n", ret);
224 return ret;
225 }
226 *strength = (0xffff - le16_to_cpu(status.gain));
227 return 0;
228}
229
230static int cinergyt2_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
231{
232 struct cinergyt2_fe_state *state = fe->demodulator_priv;
233 struct dvbt_get_status_msg status;
234 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
235 int ret;
236
237 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
238 sizeof(status), 0);
239 if (ret < 0) {
240 err("cinergyt2_fe_read_snr() Failed! (Error=%d)\n", ret);
241 return ret;
242 }
243 *snr = (status.snr << 8) | status.snr;
244 return 0;
245}
246
247static int cinergyt2_fe_init(struct dvb_frontend *fe)
248{
249 return 0;
250}
251
252static int cinergyt2_fe_sleep(struct dvb_frontend *fe)
253{
254 deb_info("cinergyt2_fe_sleep() Called\n");
255 return 0;
256}
257
258static int cinergyt2_fe_get_tune_settings(struct dvb_frontend *fe,
259 struct dvb_frontend_tune_settings *tune)
260{
261 tune->min_delay_ms = 800;
262 return 0;
263}
264
265static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe)
266{
267 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
268 struct cinergyt2_fe_state *state = fe->demodulator_priv;
269 struct dvbt_set_parameters_msg param;
270 char result[2];
271 int err;
272
273 param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
274 param.tps = cpu_to_le16(compute_tps(fep));
275 param.freq = cpu_to_le32(fep->frequency / 1000);
276 param.flags = 0;
277
278 switch (fep->bandwidth_hz) {
279 default:
280 case 8000000:
281 param.bandwidth = 8;
282 break;
283 case 7000000:
284 param.bandwidth = 7;
285 break;
286 case 6000000:
287 param.bandwidth = 6;
288 break;
289 }
290
291 err = dvb_usb_generic_rw(state->d,
292 (char *)&param, sizeof(param),
293 result, sizeof(result), 0);
294 if (err < 0)
295 err("cinergyt2_fe_set_frontend() Failed! err=%d\n", err);
296
297 return (err < 0) ? err : 0;
298}
299
300static void cinergyt2_fe_release(struct dvb_frontend *fe)
301{
302 struct cinergyt2_fe_state *state = fe->demodulator_priv;
303 if (state != NULL)
304 kfree(state);
305}
306
307static struct dvb_frontend_ops cinergyt2_fe_ops;
308
309struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d)
310{
311 struct cinergyt2_fe_state *s = kzalloc(sizeof(
312 struct cinergyt2_fe_state), GFP_KERNEL);
313 if (s == NULL)
314 return NULL;
315
316 s->d = d;
317 memcpy(&s->fe.ops, &cinergyt2_fe_ops, sizeof(struct dvb_frontend_ops));
318 s->fe.demodulator_priv = s;
319 return &s->fe;
320}
321
322
323static struct dvb_frontend_ops cinergyt2_fe_ops = {
324 .delsys = { SYS_DVBT },
325 .info = {
326 .name = DRIVER_NAME,
327 .frequency_min = 174000000,
328 .frequency_max = 862000000,
329 .frequency_stepsize = 166667,
330 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2
331 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4
332 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8
333 | FE_CAN_FEC_AUTO | FE_CAN_QPSK
334 | FE_CAN_QAM_16 | FE_CAN_QAM_64
335 | FE_CAN_QAM_AUTO
336 | FE_CAN_TRANSMISSION_MODE_AUTO
337 | FE_CAN_GUARD_INTERVAL_AUTO
338 | FE_CAN_HIERARCHY_AUTO
339 | FE_CAN_RECOVER
340 | FE_CAN_MUTE_TS
341 },
342
343 .release = cinergyt2_fe_release,
344
345 .init = cinergyt2_fe_init,
346 .sleep = cinergyt2_fe_sleep,
347
348 .set_frontend = cinergyt2_fe_set_frontend,
349 .get_tune_settings = cinergyt2_fe_get_tune_settings,
350
351 .read_status = cinergyt2_fe_read_status,
352 .read_ber = cinergyt2_fe_read_ber,
353 .read_signal_strength = cinergyt2_fe_read_signal_strength,
354 .read_snr = cinergyt2_fe_read_snr,
355 .read_ucblocks = cinergyt2_fe_read_unc_blocks,
356};
diff --git a/drivers/media/usb/dvb-usb/cinergyT2.h b/drivers/media/usb/dvb-usb/cinergyT2.h
new file mode 100644
index 000000000000..84efe03771eb
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
new file mode 100644
index 000000000000..3940bb0f9ef6
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -0,0 +1,2043 @@
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].fe[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_adap[0].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_adap[0].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_adap[0].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_adap[0].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_adap[0].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_adap[0].fe->callback = dvico_bluebird_xc2028_callback;
799
800 fe = dvb_attach(xc2028_attach, adap->fe_adap[0].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_adap[0].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_adap[0].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_adap[0].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 adap->fe_adap[0].fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
841 &adap->dev->i2c_adap);
842 if ((adap->fe_adap[0].fe) != NULL)
843 return 0;
844
845 return -EIO;
846}
847
848static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
849{
850 if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
851 err("set interface failed");
852
853 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
854
855 adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach,
856 &cxusb_lgdt3303_config,
857 &adap->dev->i2c_adap);
858 if ((adap->fe_adap[0].fe) != NULL)
859 return 0;
860
861 return -EIO;
862}
863
864static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
865{
866 adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
867 &adap->dev->i2c_adap);
868 if (adap->fe_adap[0].fe != NULL)
869 return 0;
870
871 return -EIO;
872}
873
874static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
875{
876 /* used in both lgz201 and th7579 */
877 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
878 err("set interface failed");
879
880 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
881
882 adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
883 &adap->dev->i2c_adap);
884 if ((adap->fe_adap[0].fe) != NULL)
885 return 0;
886
887 return -EIO;
888}
889
890static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
891{
892 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
893 err("set interface failed");
894
895 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
896
897 adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_dee1601_config,
898 &adap->dev->i2c_adap);
899 if ((adap->fe_adap[0].fe) != NULL)
900 return 0;
901
902 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
903 &cxusb_zl10353_dee1601_config,
904 &adap->dev->i2c_adap);
905 if ((adap->fe_adap[0].fe) != NULL)
906 return 0;
907
908 return -EIO;
909}
910
911static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
912{
913 u8 ircode[4];
914 int i;
915 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
916 .buf = ircode, .len = 4 };
917
918 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
919 err("set interface failed");
920
921 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
922
923 /* reset the tuner and demodulator */
924 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
925 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
926 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
927
928 adap->fe_adap[0].fe =
929 dvb_attach(zl10353_attach,
930 &cxusb_zl10353_xc3028_config_no_i2c_gate,
931 &adap->dev->i2c_adap);
932 if ((adap->fe_adap[0].fe) == NULL)
933 return -EIO;
934
935 /* try to determine if there is no IR decoder on the I2C bus */
936 for (i = 0; adap->dev->props.rc.legacy.rc_map_table != NULL && i < 5; i++) {
937 msleep(20);
938 if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
939 goto no_IR;
940 if (ircode[0] == 0 && ircode[1] == 0)
941 continue;
942 if (ircode[2] + ircode[3] != 0xff) {
943no_IR:
944 adap->dev->props.rc.legacy.rc_map_table = NULL;
945 info("No IR receiver detected on this device.");
946 break;
947 }
948 }
949
950 return 0;
951}
952
953static struct dibx000_agc_config dib7070_agc_config = {
954 .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
955
956 /*
957 * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5,
958 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
959 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0
960 */
961 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) |
962 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
963 .inv_gain = 600,
964 .time_stabiliz = 10,
965 .alpha_level = 0,
966 .thlock = 118,
967 .wbd_inv = 0,
968 .wbd_ref = 3530,
969 .wbd_sel = 1,
970 .wbd_alpha = 5,
971 .agc1_max = 65535,
972 .agc1_min = 0,
973 .agc2_max = 65535,
974 .agc2_min = 0,
975 .agc1_pt1 = 0,
976 .agc1_pt2 = 40,
977 .agc1_pt3 = 183,
978 .agc1_slope1 = 206,
979 .agc1_slope2 = 255,
980 .agc2_pt1 = 72,
981 .agc2_pt2 = 152,
982 .agc2_slope1 = 88,
983 .agc2_slope2 = 90,
984 .alpha_mant = 17,
985 .alpha_exp = 27,
986 .beta_mant = 23,
987 .beta_exp = 51,
988 .perform_agc_softsplit = 0,
989};
990
991static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
992 .internal = 60000,
993 .sampling = 15000,
994 .pll_prediv = 1,
995 .pll_ratio = 20,
996 .pll_range = 3,
997 .pll_reset = 1,
998 .pll_bypass = 0,
999 .enable_refdiv = 0,
1000 .bypclk_div = 0,
1001 .IO_CLK_en_core = 1,
1002 .ADClkSrc = 1,
1003 .modulo = 2,
1004 /* refsel, sel, freq_15k */
1005 .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0),
1006 .ifreq = (0 << 25) | 0,
1007 .timf = 20452225,
1008 .xtal_hz = 12000000,
1009};
1010
1011static struct dib7000p_config cxusb_dualdig4_rev2_config = {
1012 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
1013 .output_mpeg2_in_188_bytes = 1,
1014
1015 .agc_config_count = 1,
1016 .agc = &dib7070_agc_config,
1017 .bw = &dib7070_bw_config_12_mhz,
1018 .tuner_is_baseband = 1,
1019 .spur_protect = 1,
1020
1021 .gpio_dir = 0xfcef,
1022 .gpio_val = 0x0110,
1023
1024 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1025
1026 .hostbus_diversity = 1,
1027};
1028
1029static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
1030{
1031 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1032 err("set interface failed");
1033
1034 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1035
1036 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1037
1038 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1039 &cxusb_dualdig4_rev2_config) < 0) {
1040 printk(KERN_WARNING "Unable to enumerate dib7000p\n");
1041 return -ENODEV;
1042 }
1043
1044 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1045 &cxusb_dualdig4_rev2_config);
1046 if (adap->fe_adap[0].fe == NULL)
1047 return -EIO;
1048
1049 return 0;
1050}
1051
1052static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1053{
1054 return dib7000p_set_gpio(fe, 8, 0, !onoff);
1055}
1056
1057static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1058{
1059 return 0;
1060}
1061
1062static struct dib0070_config dib7070p_dib0070_config = {
1063 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1064 .reset = dib7070_tuner_reset,
1065 .sleep = dib7070_tuner_sleep,
1066 .clock_khz = 12000,
1067};
1068
1069struct dib0700_adapter_state {
1070 int (*set_param_save) (struct dvb_frontend *);
1071};
1072
1073static int dib7070_set_param_override(struct dvb_frontend *fe)
1074{
1075 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1076 struct dvb_usb_adapter *adap = fe->dvb->priv;
1077 struct dib0700_adapter_state *state = adap->priv;
1078
1079 u16 offset;
1080 u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
1081 switch (band) {
1082 case BAND_VHF: offset = 950; break;
1083 default:
1084 case BAND_UHF: offset = 550; break;
1085 }
1086
1087 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1088
1089 return state->set_param_save(fe);
1090}
1091
1092static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap)
1093{
1094 struct dib0700_adapter_state *st = adap->priv;
1095 struct i2c_adapter *tun_i2c =
1096 dib7000p_get_i2c_master(adap->fe_adap[0].fe,
1097 DIBX000_I2C_INTERFACE_TUNER, 1);
1098
1099 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
1100 &dib7070p_dib0070_config) == NULL)
1101 return -ENODEV;
1102
1103 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
1104 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override;
1105 return 0;
1106}
1107
1108static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
1109{
1110 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1111 err("set interface failed");
1112
1113 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1114
1115 /* reset the tuner and demodulator */
1116 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
1117 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
1118 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1119
1120 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
1121 &cxusb_zl10353_xc3028_config,
1122 &adap->dev->i2c_adap);
1123 if ((adap->fe_adap[0].fe) != NULL)
1124 return 0;
1125
1126 adap->fe_adap[0].fe = dvb_attach(mt352_attach,
1127 &cxusb_mt352_xc3028_config,
1128 &adap->dev->i2c_adap);
1129 if ((adap->fe_adap[0].fe) != NULL)
1130 return 0;
1131
1132 return -EIO;
1133}
1134
1135static struct lgs8gxx_config d680_lgs8gl5_cfg = {
1136 .prod = LGS8GXX_PROD_LGS8GL5,
1137 .demod_address = 0x19,
1138 .serial_ts = 0,
1139 .ts_clk_pol = 0,
1140 .ts_clk_gated = 1,
1141 .if_clk_freq = 30400, /* 30.4 MHz */
1142 .if_freq = 5725, /* 5.725 MHz */
1143 .if_neg_center = 0,
1144 .ext_adc = 0,
1145 .adc_signed = 0,
1146 .if_neg_edge = 0,
1147};
1148
1149static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
1150{
1151 struct dvb_usb_device *d = adap->dev;
1152 int n;
1153
1154 /* Select required USB configuration */
1155 if (usb_set_interface(d->udev, 0, 0) < 0)
1156 err("set interface failed");
1157
1158 /* Unblock all USB pipes */
1159 usb_clear_halt(d->udev,
1160 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1161 usb_clear_halt(d->udev,
1162 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1163 usb_clear_halt(d->udev,
1164 usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
1165
1166 /* Drain USB pipes to avoid hang after reboot */
1167 for (n = 0; n < 5; n++) {
1168 cxusb_d680_dmb_drain_message(d);
1169 cxusb_d680_dmb_drain_video(d);
1170 msleep(200);
1171 }
1172
1173 /* Reset the tuner */
1174 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1175 err("clear tuner gpio failed");
1176 return -EIO;
1177 }
1178 msleep(100);
1179 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1180 err("set tuner gpio failed");
1181 return -EIO;
1182 }
1183 msleep(100);
1184
1185 /* Attach frontend */
1186 adap->fe_adap[0].fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap);
1187 if (adap->fe_adap[0].fe == NULL)
1188 return -EIO;
1189
1190 return 0;
1191}
1192
1193static struct atbm8830_config mygica_d689_atbm8830_cfg = {
1194 .prod = ATBM8830_PROD_8830,
1195 .demod_address = 0x40,
1196 .serial_ts = 0,
1197 .ts_sampling_edge = 1,
1198 .ts_clk_gated = 0,
1199 .osc_clk_freq = 30400, /* in kHz */
1200 .if_freq = 0, /* zero IF */
1201 .zif_swap_iq = 1,
1202 .agc_min = 0x2E,
1203 .agc_max = 0x90,
1204 .agc_hold_loop = 0,
1205};
1206
1207static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
1208{
1209 struct dvb_usb_device *d = adap->dev;
1210
1211 /* Select required USB configuration */
1212 if (usb_set_interface(d->udev, 0, 0) < 0)
1213 err("set interface failed");
1214
1215 /* Unblock all USB pipes */
1216 usb_clear_halt(d->udev,
1217 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1218 usb_clear_halt(d->udev,
1219 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1220 usb_clear_halt(d->udev,
1221 usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
1222
1223
1224 /* Reset the tuner */
1225 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1226 err("clear tuner gpio failed");
1227 return -EIO;
1228 }
1229 msleep(100);
1230 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1231 err("set tuner gpio failed");
1232 return -EIO;
1233 }
1234 msleep(100);
1235
1236 /* Attach frontend */
1237 adap->fe_adap[0].fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg,
1238 &d->i2c_adap);
1239 if (adap->fe_adap[0].fe == NULL)
1240 return -EIO;
1241
1242 return 0;
1243}
1244
1245/*
1246 * DViCO has shipped two devices with the same USB ID, but only one of them
1247 * needs a firmware download. Check the device class details to see if they
1248 * have non-default values to decide whether the device is actually cold or
1249 * not, and forget a match if it turns out we selected the wrong device.
1250 */
1251static int bluebird_fx2_identify_state(struct usb_device *udev,
1252 struct dvb_usb_device_properties *props,
1253 struct dvb_usb_device_description **desc,
1254 int *cold)
1255{
1256 int wascold = *cold;
1257
1258 *cold = udev->descriptor.bDeviceClass == 0xff &&
1259 udev->descriptor.bDeviceSubClass == 0xff &&
1260 udev->descriptor.bDeviceProtocol == 0xff;
1261
1262 if (*cold && !wascold)
1263 *desc = NULL;
1264
1265 return 0;
1266}
1267
1268/*
1269 * DViCO bluebird firmware needs the "warm" product ID to be patched into the
1270 * firmware file before download.
1271 */
1272
1273static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
1274static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
1275 const struct firmware *fw)
1276{
1277 int pos;
1278
1279 for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
1280 int idoff = dvico_firmware_id_offsets[pos];
1281
1282 if (fw->size < idoff + 4)
1283 continue;
1284
1285 if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
1286 fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
1287 struct firmware new_fw;
1288 u8 *new_fw_data = vmalloc(fw->size);
1289 int ret;
1290
1291 if (!new_fw_data)
1292 return -ENOMEM;
1293
1294 memcpy(new_fw_data, fw->data, fw->size);
1295 new_fw.size = fw->size;
1296 new_fw.data = new_fw_data;
1297
1298 new_fw_data[idoff + 2] =
1299 le16_to_cpu(udev->descriptor.idProduct) + 1;
1300 new_fw_data[idoff + 3] =
1301 le16_to_cpu(udev->descriptor.idProduct) >> 8;
1302
1303 ret = usb_cypress_load_firmware(udev, &new_fw,
1304 CYPRESS_FX2);
1305 vfree(new_fw_data);
1306 return ret;
1307 }
1308 }
1309
1310 return -EINVAL;
1311}
1312
1313/* DVB USB Driver stuff */
1314static struct dvb_usb_device_properties cxusb_medion_properties;
1315static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
1316static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
1317static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
1318static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
1319static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
1320static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties;
1321static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
1322static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
1323static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
1324static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
1325static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
1326
1327static int cxusb_probe(struct usb_interface *intf,
1328 const struct usb_device_id *id)
1329{
1330 if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
1331 THIS_MODULE, NULL, adapter_nr) ||
1332 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
1333 THIS_MODULE, NULL, adapter_nr) ||
1334 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
1335 THIS_MODULE, NULL, adapter_nr) ||
1336 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
1337 THIS_MODULE, NULL, adapter_nr) ||
1338 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
1339 THIS_MODULE, NULL, adapter_nr) ||
1340 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
1341 THIS_MODULE, NULL, adapter_nr) ||
1342 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
1343 THIS_MODULE, NULL, adapter_nr) ||
1344 0 == dvb_usb_device_init(intf,
1345 &cxusb_bluebird_nano2_needsfirmware_properties,
1346 THIS_MODULE, NULL, adapter_nr) ||
1347 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
1348 THIS_MODULE, NULL, adapter_nr) ||
1349 0 == dvb_usb_device_init(intf,
1350 &cxusb_bluebird_dualdig4_rev2_properties,
1351 THIS_MODULE, NULL, adapter_nr) ||
1352 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
1353 THIS_MODULE, NULL, adapter_nr) ||
1354 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
1355 THIS_MODULE, NULL, adapter_nr) ||
1356 0)
1357 return 0;
1358
1359 return -EINVAL;
1360}
1361
1362static struct usb_device_id cxusb_table [] = {
1363 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
1364 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
1365 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
1366 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
1367 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
1368 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
1369 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
1370 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
1371 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
1372 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
1373 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
1374 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
1375 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
1376 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
1377 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
1378 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
1379 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
1380 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
1381 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
1382 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
1383 {} /* Terminating entry */
1384};
1385MODULE_DEVICE_TABLE (usb, cxusb_table);
1386
1387static struct dvb_usb_device_properties cxusb_medion_properties = {
1388 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1389
1390 .usb_ctrl = CYPRESS_FX2,
1391
1392 .size_of_priv = sizeof(struct cxusb_state),
1393
1394 .num_adapters = 1,
1395 .adapter = {
1396 {
1397 .num_frontends = 1,
1398 .fe = {{
1399 .streaming_ctrl = cxusb_streaming_ctrl,
1400 .frontend_attach = cxusb_cx22702_frontend_attach,
1401 .tuner_attach = cxusb_fmd1216me_tuner_attach,
1402 /* parameter for the MPEG2-data transfer */
1403 .stream = {
1404 .type = USB_BULK,
1405 .count = 5,
1406 .endpoint = 0x02,
1407 .u = {
1408 .bulk = {
1409 .buffersize = 8192,
1410 }
1411 }
1412 },
1413 }},
1414 },
1415 },
1416 .power_ctrl = cxusb_power_ctrl,
1417
1418 .i2c_algo = &cxusb_i2c_algo,
1419
1420 .generic_bulk_ctrl_endpoint = 0x01,
1421
1422 .num_device_descs = 1,
1423 .devices = {
1424 { "Medion MD95700 (MDUSBTV-HYBRID)",
1425 { NULL },
1426 { &cxusb_table[0], NULL },
1427 },
1428 }
1429};
1430
1431static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
1432 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1433
1434 .usb_ctrl = DEVICE_SPECIFIC,
1435 .firmware = "dvb-usb-bluebird-01.fw",
1436 .download_firmware = bluebird_patch_dvico_firmware_download,
1437 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1438 use usb alt setting 7 for EP2 transfer (atsc) */
1439
1440 .size_of_priv = sizeof(struct cxusb_state),
1441
1442 .num_adapters = 1,
1443 .adapter = {
1444 {
1445 .num_frontends = 1,
1446 .fe = {{
1447 .streaming_ctrl = cxusb_streaming_ctrl,
1448 .frontend_attach = cxusb_lgdt3303_frontend_attach,
1449 .tuner_attach = cxusb_lgh064f_tuner_attach,
1450
1451 /* parameter for the MPEG2-data transfer */
1452 .stream = {
1453 .type = USB_BULK,
1454 .count = 5,
1455 .endpoint = 0x02,
1456 .u = {
1457 .bulk = {
1458 .buffersize = 8192,
1459 }
1460 }
1461 },
1462 }},
1463 },
1464 },
1465
1466 .power_ctrl = cxusb_bluebird_power_ctrl,
1467
1468 .i2c_algo = &cxusb_i2c_algo,
1469
1470 .rc.legacy = {
1471 .rc_interval = 100,
1472 .rc_map_table = rc_map_dvico_portable_table,
1473 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1474 .rc_query = cxusb_rc_query,
1475 },
1476
1477 .generic_bulk_ctrl_endpoint = 0x01,
1478
1479 .num_device_descs = 1,
1480 .devices = {
1481 { "DViCO FusionHDTV5 USB Gold",
1482 { &cxusb_table[1], NULL },
1483 { &cxusb_table[2], NULL },
1484 },
1485 }
1486};
1487
1488static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
1489 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1490
1491 .usb_ctrl = DEVICE_SPECIFIC,
1492 .firmware = "dvb-usb-bluebird-01.fw",
1493 .download_firmware = bluebird_patch_dvico_firmware_download,
1494 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1495 use usb alt setting 7 for EP2 transfer (atsc) */
1496
1497 .size_of_priv = sizeof(struct cxusb_state),
1498
1499 .num_adapters = 1,
1500 .adapter = {
1501 {
1502 .num_frontends = 1,
1503 .fe = {{
1504 .streaming_ctrl = cxusb_streaming_ctrl,
1505 .frontend_attach = cxusb_dee1601_frontend_attach,
1506 .tuner_attach = cxusb_dee1601_tuner_attach,
1507 /* parameter for the MPEG2-data transfer */
1508 .stream = {
1509 .type = USB_BULK,
1510 .count = 5,
1511 .endpoint = 0x04,
1512 .u = {
1513 .bulk = {
1514 .buffersize = 8192,
1515 }
1516 }
1517 },
1518 }},
1519 },
1520 },
1521
1522 .power_ctrl = cxusb_bluebird_power_ctrl,
1523
1524 .i2c_algo = &cxusb_i2c_algo,
1525
1526 .rc.legacy = {
1527 .rc_interval = 150,
1528 .rc_map_table = rc_map_dvico_mce_table,
1529 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
1530 .rc_query = cxusb_rc_query,
1531 },
1532
1533 .generic_bulk_ctrl_endpoint = 0x01,
1534
1535 .num_device_descs = 3,
1536 .devices = {
1537 { "DViCO FusionHDTV DVB-T Dual USB",
1538 { &cxusb_table[3], NULL },
1539 { &cxusb_table[4], NULL },
1540 },
1541 { "DigitalNow DVB-T Dual USB",
1542 { &cxusb_table[9], NULL },
1543 { &cxusb_table[10], NULL },
1544 },
1545 { "DViCO FusionHDTV DVB-T Dual Digital 2",
1546 { &cxusb_table[11], NULL },
1547 { &cxusb_table[12], NULL },
1548 },
1549 }
1550};
1551
1552static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
1553 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1554
1555 .usb_ctrl = DEVICE_SPECIFIC,
1556 .firmware = "dvb-usb-bluebird-01.fw",
1557 .download_firmware = bluebird_patch_dvico_firmware_download,
1558 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1559 use usb alt setting 7 for EP2 transfer (atsc) */
1560
1561 .size_of_priv = sizeof(struct cxusb_state),
1562
1563 .num_adapters = 2,
1564 .adapter = {
1565 {
1566 .num_frontends = 1,
1567 .fe = {{
1568 .streaming_ctrl = cxusb_streaming_ctrl,
1569 .frontend_attach = cxusb_mt352_frontend_attach,
1570 .tuner_attach = cxusb_lgz201_tuner_attach,
1571
1572 /* parameter for the MPEG2-data transfer */
1573 .stream = {
1574 .type = USB_BULK,
1575 .count = 5,
1576 .endpoint = 0x04,
1577 .u = {
1578 .bulk = {
1579 .buffersize = 8192,
1580 }
1581 }
1582 },
1583 }},
1584 },
1585 },
1586 .power_ctrl = cxusb_bluebird_power_ctrl,
1587
1588 .i2c_algo = &cxusb_i2c_algo,
1589
1590 .rc.legacy = {
1591 .rc_interval = 100,
1592 .rc_map_table = rc_map_dvico_portable_table,
1593 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1594 .rc_query = cxusb_rc_query,
1595 },
1596
1597 .generic_bulk_ctrl_endpoint = 0x01,
1598 .num_device_descs = 1,
1599 .devices = {
1600 { "DViCO FusionHDTV DVB-T USB (LGZ201)",
1601 { &cxusb_table[5], NULL },
1602 { &cxusb_table[6], NULL },
1603 },
1604 }
1605};
1606
1607static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
1608 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1609
1610 .usb_ctrl = DEVICE_SPECIFIC,
1611 .firmware = "dvb-usb-bluebird-01.fw",
1612 .download_firmware = bluebird_patch_dvico_firmware_download,
1613 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1614 use usb alt setting 7 for EP2 transfer (atsc) */
1615
1616 .size_of_priv = sizeof(struct cxusb_state),
1617
1618 .num_adapters = 1,
1619 .adapter = {
1620 {
1621 .num_frontends = 1,
1622 .fe = {{
1623 .streaming_ctrl = cxusb_streaming_ctrl,
1624 .frontend_attach = cxusb_mt352_frontend_attach,
1625 .tuner_attach = cxusb_dtt7579_tuner_attach,
1626
1627 /* parameter for the MPEG2-data transfer */
1628 .stream = {
1629 .type = USB_BULK,
1630 .count = 5,
1631 .endpoint = 0x04,
1632 .u = {
1633 .bulk = {
1634 .buffersize = 8192,
1635 }
1636 }
1637 },
1638 }},
1639 },
1640 },
1641 .power_ctrl = cxusb_bluebird_power_ctrl,
1642
1643 .i2c_algo = &cxusb_i2c_algo,
1644
1645 .rc.legacy = {
1646 .rc_interval = 100,
1647 .rc_map_table = rc_map_dvico_portable_table,
1648 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1649 .rc_query = cxusb_rc_query,
1650 },
1651
1652 .generic_bulk_ctrl_endpoint = 0x01,
1653
1654 .num_device_descs = 1,
1655 .devices = {
1656 { "DViCO FusionHDTV DVB-T USB (TH7579)",
1657 { &cxusb_table[7], NULL },
1658 { &cxusb_table[8], NULL },
1659 },
1660 }
1661};
1662
1663static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1664 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1665
1666 .usb_ctrl = CYPRESS_FX2,
1667
1668 .size_of_priv = sizeof(struct cxusb_state),
1669
1670 .num_adapters = 1,
1671 .adapter = {
1672 {
1673 .num_frontends = 1,
1674 .fe = {{
1675 .streaming_ctrl = cxusb_streaming_ctrl,
1676 .frontend_attach = cxusb_dualdig4_frontend_attach,
1677 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1678 /* parameter for the MPEG2-data transfer */
1679 .stream = {
1680 .type = USB_BULK,
1681 .count = 5,
1682 .endpoint = 0x02,
1683 .u = {
1684 .bulk = {
1685 .buffersize = 8192,
1686 }
1687 }
1688 },
1689 }},
1690 },
1691 },
1692
1693 .power_ctrl = cxusb_power_ctrl,
1694
1695 .i2c_algo = &cxusb_i2c_algo,
1696
1697 .generic_bulk_ctrl_endpoint = 0x01,
1698
1699 .rc.legacy = {
1700 .rc_interval = 100,
1701 .rc_map_table = rc_map_dvico_mce_table,
1702 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
1703 .rc_query = cxusb_bluebird2_rc_query,
1704 },
1705
1706 .num_device_descs = 1,
1707 .devices = {
1708 { "DViCO FusionHDTV DVB-T Dual Digital 4",
1709 { NULL },
1710 { &cxusb_table[13], NULL },
1711 },
1712 }
1713};
1714
1715static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1716 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1717
1718 .usb_ctrl = CYPRESS_FX2,
1719 .identify_state = bluebird_fx2_identify_state,
1720
1721 .size_of_priv = sizeof(struct cxusb_state),
1722
1723 .num_adapters = 1,
1724 .adapter = {
1725 {
1726 .num_frontends = 1,
1727 .fe = {{
1728 .streaming_ctrl = cxusb_streaming_ctrl,
1729 .frontend_attach = cxusb_nano2_frontend_attach,
1730 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1731 /* parameter for the MPEG2-data transfer */
1732 .stream = {
1733 .type = USB_BULK,
1734 .count = 5,
1735 .endpoint = 0x02,
1736 .u = {
1737 .bulk = {
1738 .buffersize = 8192,
1739 }
1740 }
1741 },
1742 }},
1743 },
1744 },
1745
1746 .power_ctrl = cxusb_nano2_power_ctrl,
1747
1748 .i2c_algo = &cxusb_i2c_algo,
1749
1750 .generic_bulk_ctrl_endpoint = 0x01,
1751
1752 .rc.legacy = {
1753 .rc_interval = 100,
1754 .rc_map_table = rc_map_dvico_portable_table,
1755 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1756 .rc_query = cxusb_bluebird2_rc_query,
1757 },
1758
1759 .num_device_descs = 1,
1760 .devices = {
1761 { "DViCO FusionHDTV DVB-T NANO2",
1762 { NULL },
1763 { &cxusb_table[14], NULL },
1764 },
1765 }
1766};
1767
1768static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
1769 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1770
1771 .usb_ctrl = DEVICE_SPECIFIC,
1772 .firmware = "dvb-usb-bluebird-02.fw",
1773 .download_firmware = bluebird_patch_dvico_firmware_download,
1774 .identify_state = bluebird_fx2_identify_state,
1775
1776 .size_of_priv = sizeof(struct cxusb_state),
1777
1778 .num_adapters = 1,
1779 .adapter = {
1780 {
1781 .num_frontends = 1,
1782 .fe = {{
1783 .streaming_ctrl = cxusb_streaming_ctrl,
1784 .frontend_attach = cxusb_nano2_frontend_attach,
1785 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1786 /* parameter for the MPEG2-data transfer */
1787 .stream = {
1788 .type = USB_BULK,
1789 .count = 5,
1790 .endpoint = 0x02,
1791 .u = {
1792 .bulk = {
1793 .buffersize = 8192,
1794 }
1795 }
1796 },
1797 }},
1798 },
1799 },
1800
1801 .power_ctrl = cxusb_nano2_power_ctrl,
1802
1803 .i2c_algo = &cxusb_i2c_algo,
1804
1805 .generic_bulk_ctrl_endpoint = 0x01,
1806
1807 .rc.legacy = {
1808 .rc_interval = 100,
1809 .rc_map_table = rc_map_dvico_portable_table,
1810 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1811 .rc_query = cxusb_rc_query,
1812 },
1813
1814 .num_device_descs = 1,
1815 .devices = {
1816 { "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
1817 { &cxusb_table[14], NULL },
1818 { &cxusb_table[15], NULL },
1819 },
1820 }
1821};
1822
1823static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
1824 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1825
1826 .usb_ctrl = CYPRESS_FX2,
1827
1828 .size_of_priv = sizeof(struct cxusb_state),
1829
1830 .num_adapters = 1,
1831 .adapter = {
1832 {
1833 .num_frontends = 1,
1834 .fe = {{
1835 .streaming_ctrl = cxusb_aver_streaming_ctrl,
1836 .frontend_attach = cxusb_aver_lgdt3303_frontend_attach,
1837 .tuner_attach = cxusb_mxl5003s_tuner_attach,
1838 /* parameter for the MPEG2-data transfer */
1839 .stream = {
1840 .type = USB_BULK,
1841 .count = 5,
1842 .endpoint = 0x04,
1843 .u = {
1844 .bulk = {
1845 .buffersize = 8192,
1846 }
1847 }
1848 },
1849 }},
1850 },
1851 },
1852 .power_ctrl = cxusb_aver_power_ctrl,
1853
1854 .i2c_algo = &cxusb_i2c_algo,
1855
1856 .generic_bulk_ctrl_endpoint = 0x01,
1857
1858 .num_device_descs = 1,
1859 .devices = {
1860 { "AVerMedia AVerTVHD Volar (A868R)",
1861 { NULL },
1862 { &cxusb_table[16], NULL },
1863 },
1864 }
1865};
1866
1867static
1868struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
1869 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1870
1871 .usb_ctrl = CYPRESS_FX2,
1872
1873 .size_of_priv = sizeof(struct cxusb_state),
1874
1875 .num_adapters = 1,
1876 .adapter = {
1877 {
1878 .size_of_priv = sizeof(struct dib0700_adapter_state),
1879 .num_frontends = 1,
1880 .fe = {{
1881 .streaming_ctrl = cxusb_streaming_ctrl,
1882 .frontend_attach = cxusb_dualdig4_rev2_frontend_attach,
1883 .tuner_attach = cxusb_dualdig4_rev2_tuner_attach,
1884 /* parameter for the MPEG2-data transfer */
1885 .stream = {
1886 .type = USB_BULK,
1887 .count = 7,
1888 .endpoint = 0x02,
1889 .u = {
1890 .bulk = {
1891 .buffersize = 4096,
1892 }
1893 }
1894 },
1895 }},
1896 },
1897 },
1898
1899 .power_ctrl = cxusb_bluebird_power_ctrl,
1900
1901 .i2c_algo = &cxusb_i2c_algo,
1902
1903 .generic_bulk_ctrl_endpoint = 0x01,
1904
1905 .rc.legacy = {
1906 .rc_interval = 100,
1907 .rc_map_table = rc_map_dvico_mce_table,
1908 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
1909 .rc_query = cxusb_rc_query,
1910 },
1911
1912 .num_device_descs = 1,
1913 .devices = {
1914 { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)",
1915 { NULL },
1916 { &cxusb_table[17], NULL },
1917 },
1918 }
1919};
1920
1921static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
1922 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1923
1924 .usb_ctrl = CYPRESS_FX2,
1925
1926 .size_of_priv = sizeof(struct cxusb_state),
1927
1928 .num_adapters = 1,
1929 .adapter = {
1930 {
1931 .num_frontends = 1,
1932 .fe = {{
1933 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
1934 .frontend_attach = cxusb_d680_dmb_frontend_attach,
1935 .tuner_attach = cxusb_d680_dmb_tuner_attach,
1936
1937 /* parameter for the MPEG2-data transfer */
1938 .stream = {
1939 .type = USB_BULK,
1940 .count = 5,
1941 .endpoint = 0x02,
1942 .u = {
1943 .bulk = {
1944 .buffersize = 8192,
1945 }
1946 }
1947 },
1948 }},
1949 },
1950 },
1951
1952 .power_ctrl = cxusb_d680_dmb_power_ctrl,
1953
1954 .i2c_algo = &cxusb_i2c_algo,
1955
1956 .generic_bulk_ctrl_endpoint = 0x01,
1957
1958 .rc.legacy = {
1959 .rc_interval = 100,
1960 .rc_map_table = rc_map_d680_dmb_table,
1961 .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
1962 .rc_query = cxusb_d680_dmb_rc_query,
1963 },
1964
1965 .num_device_descs = 1,
1966 .devices = {
1967 {
1968 "Conexant DMB-TH Stick",
1969 { NULL },
1970 { &cxusb_table[18], NULL },
1971 },
1972 }
1973};
1974
1975static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
1976 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1977
1978 .usb_ctrl = CYPRESS_FX2,
1979
1980 .size_of_priv = sizeof(struct cxusb_state),
1981
1982 .num_adapters = 1,
1983 .adapter = {
1984 {
1985 .num_frontends = 1,
1986 .fe = {{
1987 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
1988 .frontend_attach = cxusb_mygica_d689_frontend_attach,
1989 .tuner_attach = cxusb_mygica_d689_tuner_attach,
1990
1991 /* parameter for the MPEG2-data transfer */
1992 .stream = {
1993 .type = USB_BULK,
1994 .count = 5,
1995 .endpoint = 0x02,
1996 .u = {
1997 .bulk = {
1998 .buffersize = 8192,
1999 }
2000 }
2001 },
2002 }},
2003 },
2004 },
2005
2006 .power_ctrl = cxusb_d680_dmb_power_ctrl,
2007
2008 .i2c_algo = &cxusb_i2c_algo,
2009
2010 .generic_bulk_ctrl_endpoint = 0x01,
2011
2012 .rc.legacy = {
2013 .rc_interval = 100,
2014 .rc_map_table = rc_map_d680_dmb_table,
2015 .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
2016 .rc_query = cxusb_d680_dmb_rc_query,
2017 },
2018
2019 .num_device_descs = 1,
2020 .devices = {
2021 {
2022 "Mygica D689 DMB-TH",
2023 { NULL },
2024 { &cxusb_table[19], NULL },
2025 },
2026 }
2027};
2028
2029static struct usb_driver cxusb_driver = {
2030 .name = "dvb_usb_cxusb",
2031 .probe = cxusb_probe,
2032 .disconnect = dvb_usb_device_exit,
2033 .id_table = cxusb_table,
2034};
2035
2036module_usb_driver(cxusb_driver);
2037
2038MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
2039MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
2040MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
2041MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
2042MODULE_VERSION("1.0-alpha");
2043MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h
new file mode 100644
index 000000000000..1a51eafd31b9
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/dib0700.h b/drivers/media/usb/dvb-usb/dib0700.h
new file mode 100644
index 000000000000..7de125c0b36f
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dib0700.h
@@ -0,0 +1,75 @@
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 int (*read_status)(struct dvb_frontend *, fe_status_t *);
52 int (*sleep)(struct dvb_frontend* fe);
53 u8 buf[255];
54};
55
56extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
57 u32 *romversion, u32 *ramversion, u32 *fwtype);
58extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
59extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3);
60extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen);
61extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw);
62extern int dib0700_rc_setup(struct dvb_usb_device *d);
63extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
64extern struct i2c_algorithm dib0700_i2c_algo;
65extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
66 struct dvb_usb_device_description **desc, int *cold);
67extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type);
68extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz);
69
70extern int dib0700_device_count;
71extern int dvb_usb_dib0700_ir_proto;
72extern struct dvb_usb_device_properties dib0700_devices[];
73extern struct usb_device_id dib0700_usb_id_table[];
74
75#endif
diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
new file mode 100644
index 000000000000..ef87229de6af
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dib0700_core.c
@@ -0,0 +1,845 @@
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 err("could not acquire lock");
35 return -EINTR;
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 err("could not acquire lock");
121 return -EINTR;
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 err("could not acquire lock");
142 return -EINTR;
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 -EINTR;
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 err("could not acquire lock");
231 mutex_unlock(&d->i2c_mutex);
232 return -EINTR;
233 }
234 st->buf[0] = REQUEST_NEW_I2C_WRITE;
235 st->buf[1] = msg[i].addr << 1;
236 st->buf[2] = (en_start << 7) | (en_stop << 6) |
237 (msg[i].len & 0x3F);
238 /* I2C ctrl + FE bus; */
239 st->buf[3] = ((gen_mode << 6) & 0xC0) |
240 ((bus_mode << 4) & 0x30);
241 /* The Actual i2c payload */
242 memcpy(&st->buf[4], msg[i].buf, msg[i].len);
243
244 deb_data(">>> ");
245 debug_dump(st->buf, msg[i].len + 4, deb_data);
246
247 result = usb_control_msg(d->udev,
248 usb_sndctrlpipe(d->udev, 0),
249 REQUEST_NEW_I2C_WRITE,
250 USB_TYPE_VENDOR | USB_DIR_OUT,
251 0, 0, st->buf, msg[i].len + 4,
252 USB_CTRL_GET_TIMEOUT);
253 mutex_unlock(&d->usb_mutex);
254 if (result < 0) {
255 deb_info("i2c write error (status = %d)\n", result);
256 break;
257 }
258 }
259 }
260 mutex_unlock(&d->i2c_mutex);
261 return i;
262}
263
264/*
265 * I2C master xfer function (pre-1.20 firmware)
266 */
267static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
268 struct i2c_msg *msg, int num)
269{
270 struct dvb_usb_device *d = i2c_get_adapdata(adap);
271 struct dib0700_state *st = d->priv;
272 int i,len;
273
274 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
275 return -EINTR;
276 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
277 err("could not acquire lock");
278 mutex_unlock(&d->i2c_mutex);
279 return -EINTR;
280 }
281
282 for (i = 0; i < num; i++) {
283 /* fill in the address */
284 st->buf[1] = msg[i].addr << 1;
285 /* fill the buffer */
286 memcpy(&st->buf[2], msg[i].buf, msg[i].len);
287
288 /* write/read request */
289 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
290 st->buf[0] = REQUEST_I2C_READ;
291 st->buf[1] |= 1;
292
293 /* special thing in the current firmware: when length is zero the read-failed */
294 len = dib0700_ctrl_rd(d, st->buf, msg[i].len + 2,
295 msg[i+1].buf, msg[i+1].len);
296 if (len <= 0) {
297 deb_info("I2C read failed on address 0x%02x\n",
298 msg[i].addr);
299 break;
300 }
301
302 msg[i+1].len = len;
303
304 i++;
305 } else {
306 st->buf[0] = REQUEST_I2C_WRITE;
307 if (dib0700_ctrl_wr(d, st->buf, msg[i].len + 2) < 0)
308 break;
309 }
310 }
311 mutex_unlock(&d->usb_mutex);
312 mutex_unlock(&d->i2c_mutex);
313
314 return i;
315}
316
317static int dib0700_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
318 int num)
319{
320 struct dvb_usb_device *d = i2c_get_adapdata(adap);
321 struct dib0700_state *st = d->priv;
322
323 if (st->fw_use_new_i2c_api == 1) {
324 /* User running at least fw 1.20 */
325 return dib0700_i2c_xfer_new(adap, msg, num);
326 } else {
327 /* Use legacy calls */
328 return dib0700_i2c_xfer_legacy(adap, msg, num);
329 }
330}
331
332static u32 dib0700_i2c_func(struct i2c_adapter *adapter)
333{
334 return I2C_FUNC_I2C;
335}
336
337struct i2c_algorithm dib0700_i2c_algo = {
338 .master_xfer = dib0700_i2c_xfer,
339 .functionality = dib0700_i2c_func,
340};
341
342int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
343 struct dvb_usb_device_description **desc, int *cold)
344{
345 s16 ret;
346 u8 *b;
347
348 b = kmalloc(16, GFP_KERNEL);
349 if (!b)
350 return -ENOMEM;
351
352
353 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
354 REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT);
355
356 deb_info("FW GET_VERSION length: %d\n",ret);
357
358 *cold = ret <= 0;
359 deb_info("cold: %d\n", *cold);
360
361 kfree(b);
362 return 0;
363}
364
365static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
366 u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv,
367 u16 pll_loopdiv, u16 free_div, u16 dsuScaler)
368{
369 struct dib0700_state *st = d->priv;
370 int ret;
371
372 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
373 err("could not acquire lock");
374 return -EINTR;
375 }
376
377 st->buf[0] = REQUEST_SET_CLOCK;
378 st->buf[1] = (en_pll << 7) | (pll_src << 6) |
379 (pll_range << 5) | (clock_gpio3 << 4);
380 st->buf[2] = (pll_prediv >> 8) & 0xff; /* MSB */
381 st->buf[3] = pll_prediv & 0xff; /* LSB */
382 st->buf[4] = (pll_loopdiv >> 8) & 0xff; /* MSB */
383 st->buf[5] = pll_loopdiv & 0xff; /* LSB */
384 st->buf[6] = (free_div >> 8) & 0xff; /* MSB */
385 st->buf[7] = free_div & 0xff; /* LSB */
386 st->buf[8] = (dsuScaler >> 8) & 0xff; /* MSB */
387 st->buf[9] = dsuScaler & 0xff; /* LSB */
388
389 ret = dib0700_ctrl_wr(d, st->buf, 10);
390 mutex_unlock(&d->usb_mutex);
391
392 return ret;
393}
394
395int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
396{
397 struct dib0700_state *st = d->priv;
398 u16 divider;
399 int ret;
400
401 if (scl_kHz == 0)
402 return -EINVAL;
403
404 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
405 err("could not acquire lock");
406 return -EINTR;
407 }
408
409 st->buf[0] = REQUEST_SET_I2C_PARAM;
410 divider = (u16) (30000 / scl_kHz);
411 st->buf[1] = 0;
412 st->buf[2] = (u8) (divider >> 8);
413 st->buf[3] = (u8) (divider & 0xff);
414 divider = (u16) (72000 / scl_kHz);
415 st->buf[4] = (u8) (divider >> 8);
416 st->buf[5] = (u8) (divider & 0xff);
417 divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */
418 st->buf[6] = (u8) (divider >> 8);
419 st->buf[7] = (u8) (divider & 0xff);
420
421 deb_info("setting I2C speed: %04x %04x %04x (%d kHz).",
422 (st->buf[2] << 8) | (st->buf[3]), (st->buf[4] << 8) |
423 st->buf[5], (st->buf[6] << 8) | st->buf[7], scl_kHz);
424
425 ret = dib0700_ctrl_wr(d, st->buf, 8);
426 mutex_unlock(&d->usb_mutex);
427
428 return ret;
429}
430
431
432int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3)
433{
434 switch (clk_MHz) {
435 case 72: dib0700_set_clock(d, 1, 0, 1, clock_out_gp3, 2, 24, 0, 0x4c); break;
436 default: return -EINVAL;
437 }
438 return 0;
439}
440
441static int dib0700_jumpram(struct usb_device *udev, u32 address)
442{
443 int ret = 0, actlen;
444 u8 *buf;
445
446 buf = kmalloc(8, GFP_KERNEL);
447 if (!buf)
448 return -ENOMEM;
449 buf[0] = REQUEST_JUMPRAM;
450 buf[1] = 0;
451 buf[2] = 0;
452 buf[3] = 0;
453 buf[4] = (address >> 24) & 0xff;
454 buf[5] = (address >> 16) & 0xff;
455 buf[6] = (address >> 8) & 0xff;
456 buf[7] = address & 0xff;
457
458 if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) {
459 deb_fw("jumpram to 0x%x failed\n",address);
460 goto out;
461 }
462 if (actlen != 8) {
463 deb_fw("jumpram to 0x%x failed\n",address);
464 ret = -EIO;
465 goto out;
466 }
467out:
468 kfree(buf);
469 return ret;
470}
471
472int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
473{
474 struct hexline hx;
475 int pos = 0, ret, act_len, i, adap_num;
476 u8 *buf;
477 u32 fw_version;
478
479 buf = kmalloc(260, GFP_KERNEL);
480 if (!buf)
481 return -ENOMEM;
482
483 while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) {
484 deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",
485 hx.addr, hx.len, hx.chk);
486
487 buf[0] = hx.len;
488 buf[1] = (hx.addr >> 8) & 0xff;
489 buf[2] = hx.addr & 0xff;
490 buf[3] = hx.type;
491 memcpy(&buf[4],hx.data,hx.len);
492 buf[4+hx.len] = hx.chk;
493
494 ret = usb_bulk_msg(udev,
495 usb_sndbulkpipe(udev, 0x01),
496 buf,
497 hx.len + 5,
498 &act_len,
499 1000);
500
501 if (ret < 0) {
502 err("firmware download failed at %d with %d",pos,ret);
503 goto out;
504 }
505 }
506
507 if (ret == 0) {
508 /* start the firmware */
509 if ((ret = dib0700_jumpram(udev, 0x70000000)) == 0) {
510 info("firmware started successfully.");
511 msleep(500);
512 }
513 } else
514 ret = -EIO;
515
516 /* the number of ts packet has to be at least 1 */
517 if (nb_packet_buffer_size < 1)
518 nb_packet_buffer_size = 1;
519
520 /* get the fimware version */
521 usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
522 REQUEST_GET_VERSION,
523 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
524 buf, 16, USB_CTRL_GET_TIMEOUT);
525 fw_version = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11];
526
527 /* set the buffer size - DVB-USB is allocating URB buffers
528 * only after the firwmare download was successful */
529 for (i = 0; i < dib0700_device_count; i++) {
530 for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters;
531 adap_num++) {
532 if (fw_version >= 0x10201) {
533 dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = 188*nb_packet_buffer_size;
534 } else {
535 /* for fw version older than 1.20.1,
536 * the buffersize has to be n times 512 */
537 dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512;
538 if (dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize < 512)
539 dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = 512;
540 }
541 }
542 }
543out:
544 kfree(buf);
545 return ret;
546}
547
548int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
549{
550 struct dib0700_state *st = adap->dev->priv;
551 int ret;
552
553 if ((onoff != 0) && (st->fw_version >= 0x10201)) {
554 /* for firmware later than 1.20.1,
555 * the USB xfer length can be set */
556 ret = dib0700_set_usb_xfer_len(adap->dev,
557 st->nb_packet_buffer_size);
558 if (ret < 0) {
559 deb_info("can not set the USB xfer len\n");
560 return ret;
561 }
562 }
563
564 if (mutex_lock_interruptible(&adap->dev->usb_mutex) < 0) {
565 err("could not acquire lock");
566 return -EINTR;
567 }
568
569 st->buf[0] = REQUEST_ENABLE_VIDEO;
570 /* this bit gives a kind of command,
571 * rather than enabling something or not */
572 st->buf[1] = (onoff << 4) | 0x00;
573
574 if (st->disable_streaming_master_mode == 1)
575 st->buf[2] = 0x00;
576 else
577 st->buf[2] = 0x01 << 4; /* Master mode */
578
579 st->buf[3] = 0x00;
580
581 deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
582
583 st->channel_state &= ~0x3;
584 if ((adap->fe_adap[0].stream.props.endpoint != 2)
585 && (adap->fe_adap[0].stream.props.endpoint != 3)) {
586 deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->fe_adap[0].stream.props.endpoint);
587 if (onoff)
588 st->channel_state |= 1 << (adap->id);
589 else
590 st->channel_state |= 1 << ~(adap->id);
591 } else {
592 if (onoff)
593 st->channel_state |= 1 << (adap->fe_adap[0].stream.props.endpoint-2);
594 else
595 st->channel_state |= 1 << (3-adap->fe_adap[0].stream.props.endpoint);
596 }
597
598 st->buf[2] |= st->channel_state;
599
600 deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]);
601
602 ret = dib0700_ctrl_wr(adap->dev, st->buf, 4);
603 mutex_unlock(&adap->dev->usb_mutex);
604
605 return ret;
606}
607
608int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
609{
610 struct dvb_usb_device *d = rc->priv;
611 struct dib0700_state *st = d->priv;
612 int new_proto, ret;
613
614 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
615 err("could not acquire lock");
616 return -EINTR;
617 }
618
619 st->buf[0] = REQUEST_SET_RC;
620 st->buf[1] = 0;
621 st->buf[2] = 0;
622
623 /* Set the IR mode */
624 if (rc_type == RC_TYPE_RC5)
625 new_proto = 1;
626 else if (rc_type == RC_TYPE_NEC)
627 new_proto = 0;
628 else if (rc_type == RC_TYPE_RC6) {
629 if (st->fw_version < 0x10200) {
630 ret = -EINVAL;
631 goto out;
632 }
633
634 new_proto = 2;
635 } else {
636 ret = -EINVAL;
637 goto out;
638 }
639
640 st->buf[1] = new_proto;
641
642 ret = dib0700_ctrl_wr(d, st->buf, 3);
643 if (ret < 0) {
644 err("ir protocol setup failed");
645 goto out;
646 }
647
648 d->props.rc.core.protocol = rc_type;
649
650out:
651 mutex_unlock(&d->usb_mutex);
652 return ret;
653}
654
655/* Number of keypresses to ignore before start repeating */
656#define RC_REPEAT_DELAY_V1_20 10
657
658/* This is the structure of the RC response packet starting in firmware 1.20 */
659struct dib0700_rc_response {
660 u8 report_id;
661 u8 data_state;
662 union {
663 u16 system16;
664 struct {
665 u8 not_system;
666 u8 system;
667 };
668 };
669 u8 data;
670 u8 not_data;
671};
672#define RC_MSG_SIZE_V1_20 6
673
674static void dib0700_rc_urb_completion(struct urb *purb)
675{
676 struct dvb_usb_device *d = purb->context;
677 struct dib0700_rc_response *poll_reply;
678 u32 uninitialized_var(keycode);
679 u8 toggle;
680
681 deb_info("%s()\n", __func__);
682 if (d->rc_dev == NULL) {
683 /* This will occur if disable_rc_polling=1 */
684 kfree(purb->transfer_buffer);
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 kfree(purb->transfer_buffer);
694 usb_free_urb(purb);
695 return;
696 }
697
698 if (purb->actual_length != RC_MSG_SIZE_V1_20) {
699 deb_info("malformed rc msg size=%d\n", purb->actual_length);
700 goto resubmit;
701 }
702
703 deb_data("IR ID = %02X state = %02X System = %02X %02X Cmd = %02X %02X (len %d)\n",
704 poll_reply->report_id, poll_reply->data_state,
705 poll_reply->system, poll_reply->not_system,
706 poll_reply->data, poll_reply->not_data,
707 purb->actual_length);
708
709 switch (d->props.rc.core.protocol) {
710 case RC_TYPE_NEC:
711 toggle = 0;
712
713 /* NEC protocol sends repeat code as 0 0 0 FF */
714 if ((poll_reply->system == 0x00) && (poll_reply->data == 0x00)
715 && (poll_reply->not_data == 0xff)) {
716 poll_reply->data_state = 2;
717 break;
718 }
719
720 if ((poll_reply->system ^ poll_reply->not_system) != 0xff) {
721 deb_data("NEC extended protocol\n");
722 /* NEC extended code - 24 bits */
723 keycode = be16_to_cpu(poll_reply->system16) << 8 | poll_reply->data;
724 } else {
725 deb_data("NEC normal protocol\n");
726 /* normal NEC code - 16 bits */
727 keycode = poll_reply->system << 8 | poll_reply->data;
728 }
729
730 break;
731 default:
732 deb_data("RC5 protocol\n");
733 /* RC5 Protocol */
734 toggle = poll_reply->report_id;
735 keycode = poll_reply->system << 8 | poll_reply->data;
736
737 break;
738 }
739
740 if ((poll_reply->data + poll_reply->not_data) != 0xff) {
741 /* Key failed integrity check */
742 err("key failed integrity check: %04x %02x %02x",
743 poll_reply->system,
744 poll_reply->data, poll_reply->not_data);
745 goto resubmit;
746 }
747
748 rc_keydown(d->rc_dev, keycode, toggle);
749
750resubmit:
751 /* Clean the buffer before we requeue */
752 memset(purb->transfer_buffer, 0, RC_MSG_SIZE_V1_20);
753
754 /* Requeue URB */
755 usb_submit_urb(purb, GFP_ATOMIC);
756}
757
758int dib0700_rc_setup(struct dvb_usb_device *d)
759{
760 struct dib0700_state *st = d->priv;
761 struct urb *purb;
762 int ret;
763
764 /* Poll-based. Don't initialize bulk mode */
765 if (st->fw_version < 0x10200)
766 return 0;
767
768 /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
769 purb = usb_alloc_urb(0, GFP_KERNEL);
770 if (purb == NULL) {
771 err("rc usb alloc urb failed");
772 return -ENOMEM;
773 }
774
775 purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL);
776 if (purb->transfer_buffer == NULL) {
777 err("rc kzalloc failed");
778 usb_free_urb(purb);
779 return -ENOMEM;
780 }
781
782 purb->status = -EINPROGRESS;
783 usb_fill_bulk_urb(purb, d->udev, usb_rcvbulkpipe(d->udev, 1),
784 purb->transfer_buffer, RC_MSG_SIZE_V1_20,
785 dib0700_rc_urb_completion, d);
786
787 ret = usb_submit_urb(purb, GFP_ATOMIC);
788 if (ret) {
789 err("rc submit urb failed");
790 kfree(purb->transfer_buffer);
791 usb_free_urb(purb);
792 }
793
794 return ret;
795}
796
797static int dib0700_probe(struct usb_interface *intf,
798 const struct usb_device_id *id)
799{
800 int i;
801 struct dvb_usb_device *dev;
802
803 for (i = 0; i < dib0700_device_count; i++)
804 if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE,
805 &dev, adapter_nr) == 0) {
806 struct dib0700_state *st = dev->priv;
807 u32 hwversion, romversion, fw_version, fwtype;
808
809 dib0700_get_version(dev, &hwversion, &romversion,
810 &fw_version, &fwtype);
811
812 deb_info("Firmware version: %x, %d, 0x%x, %d\n",
813 hwversion, romversion, fw_version, fwtype);
814
815 st->fw_version = fw_version;
816 st->nb_packet_buffer_size = (u32)nb_packet_buffer_size;
817
818 /* Disable polling mode on newer firmwares */
819 if (st->fw_version >= 0x10200)
820 dev->props.rc.core.bulk_mode = true;
821 else
822 dev->props.rc.core.bulk_mode = false;
823
824 dib0700_rc_setup(dev);
825
826 return 0;
827 }
828
829 return -ENODEV;
830}
831
832static struct usb_driver dib0700_driver = {
833 .name = "dvb_usb_dib0700",
834 .probe = dib0700_probe,
835 .disconnect = dvb_usb_device_exit,
836 .id_table = dib0700_usb_id_table,
837};
838
839module_usb_driver(dib0700_driver);
840
841MODULE_FIRMWARE("dvb-usb-dib0700-1.20.fw");
842MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
843MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge");
844MODULE_VERSION("1.0");
845MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
new file mode 100644
index 000000000000..510001da6e83
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
@@ -0,0 +1,4813 @@
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 *);
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_adap[0].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_adap[0].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_adap[0].fe, tun_i2c,
129 &bristol_mt2060_config[adap->id], if1) == NULL ?
130 -ENODEV : 0;
131}
132
133/* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */
134
135/* MT226x */
136static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
137 {
138 BAND_UHF,
139
140 /* 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,
141 * 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 */
142 (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
143 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
144
145 1130,
146 21,
147
148 0,
149 118,
150
151 0,
152 3530,
153 1,
154 0,
155
156 65535,
157 33770,
158 65535,
159 23592,
160
161 0,
162 62,
163 255,
164 64,
165 64,
166 132,
167 192,
168 80,
169 80,
170
171 17,
172 27,
173 23,
174 51,
175
176 1,
177 }, {
178 BAND_VHF | BAND_LBAND,
179
180 /* 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,
181 * 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 */
182 (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
183 | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
184
185 2372,
186 21,
187
188 0,
189 118,
190
191 0,
192 3530,
193 1,
194 0,
195
196 65535,
197 0,
198 65535,
199 23592,
200
201 0,
202 128,
203 128,
204 128,
205 0,
206 128,
207 253,
208 81,
209 0,
210
211 17,
212 27,
213 23,
214 51,
215
216 1,
217 }
218};
219
220static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
221 60000, 30000,
222 1, 8, 3, 1, 0,
223 0, 0, 1, 1, 2,
224 (3 << 14) | (1 << 12) | (524 << 0),
225 0,
226 20452225,
227};
228
229static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
230 { .output_mpeg2_in_188_bytes = 1,
231 .hostbus_diversity = 1,
232 .tuner_is_baseband = 1,
233
234 .agc_config_count = 2,
235 .agc = stk7700d_7000p_mt2266_agc_config,
236 .bw = &stk7700d_mt2266_pll_config,
237
238 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
239 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
240 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
241 },
242 { .output_mpeg2_in_188_bytes = 1,
243 .hostbus_diversity = 1,
244 .tuner_is_baseband = 1,
245
246 .agc_config_count = 2,
247 .agc = stk7700d_7000p_mt2266_agc_config,
248 .bw = &stk7700d_mt2266_pll_config,
249
250 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
251 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
252 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
253 }
254};
255
256static struct mt2266_config stk7700d_mt2266_config[2] = {
257 { .i2c_address = 0x60
258 },
259 { .i2c_address = 0x60
260 }
261};
262
263static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
264{
265 if (adap->id == 0) {
266 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
267 msleep(10);
268 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
269 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
270 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
271 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
272 msleep(10);
273 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
274 msleep(10);
275 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
276 stk7700d_dib7000p_mt2266_config)
277 != 0) {
278 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
279 return -ENODEV;
280 }
281 }
282
283 adap->fe_adap[0].fe =
284 dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
285 0x80 + (adap->id << 1),
286 &stk7700d_dib7000p_mt2266_config[adap->id]);
287
288 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
289}
290
291static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
292{
293 if (adap->id == 0) {
294 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
295 msleep(10);
296 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
297 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
298 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
299 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
300 msleep(10);
301 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
302 msleep(10);
303 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
304 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
305 stk7700d_dib7000p_mt2266_config)
306 != 0) {
307 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
308 return -ENODEV;
309 }
310 }
311
312 adap->fe_adap[0].fe =
313 dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
314 0x80 + (adap->id << 1),
315 &stk7700d_dib7000p_mt2266_config[adap->id]);
316
317 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
318}
319
320static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
321{
322 struct i2c_adapter *tun_i2c;
323 tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
324 return dvb_attach(mt2266_attach, adap->fe_adap[0].fe, tun_i2c,
325 &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;
326}
327
328/* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
329static struct dibx000_agc_config xc3028_agc_config = {
330 BAND_VHF | BAND_UHF, /* band_caps */
331
332 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
333 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
334 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
335 (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
336 (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */
337
338 712, /* inv_gain */
339 21, /* time_stabiliz */
340
341 0, /* alpha_level */
342 118, /* thlock */
343
344 0, /* wbd_inv */
345 2867, /* wbd_ref */
346 0, /* wbd_sel */
347 2, /* wbd_alpha */
348
349 0, /* agc1_max */
350 0, /* agc1_min */
351 39718, /* agc2_max */
352 9930, /* agc2_min */
353 0, /* agc1_pt1 */
354 0, /* agc1_pt2 */
355 0, /* agc1_pt3 */
356 0, /* agc1_slope1 */
357 0, /* agc1_slope2 */
358 0, /* agc2_pt1 */
359 128, /* agc2_pt2 */
360 29, /* agc2_slope1 */
361 29, /* agc2_slope2 */
362
363 17, /* alpha_mant */
364 27, /* alpha_exp */
365 23, /* beta_mant */
366 51, /* beta_exp */
367
368 1, /* perform_agc_softsplit */
369};
370
371/* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */
372static struct dibx000_bandwidth_config xc3028_bw_config = {
373 60000, 30000, /* internal, sampling */
374 1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
375 0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc,
376 modulo */
377 (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
378 (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
379 20452225, /* timf */
380 30000000, /* xtal_hz */
381};
382
383static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
384 .output_mpeg2_in_188_bytes = 1,
385 .tuner_is_baseband = 1,
386
387 .agc_config_count = 1,
388 .agc = &xc3028_agc_config,
389 .bw = &xc3028_bw_config,
390
391 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
392 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
393 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
394};
395
396static int stk7700ph_xc3028_callback(void *ptr, int component,
397 int command, int arg)
398{
399 struct dvb_usb_adapter *adap = ptr;
400
401 switch (command) {
402 case XC2028_TUNER_RESET:
403 /* Send the tuner in then out of reset */
404 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0); msleep(10);
405 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
406 break;
407 case XC2028_RESET_CLK:
408 break;
409 default:
410 err("%s: unknown command %d, arg %d\n", __func__,
411 command, arg);
412 return -EINVAL;
413 }
414 return 0;
415}
416
417static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
418 .fname = XC2028_DEFAULT_FIRMWARE,
419 .max_len = 64,
420 .demod = XC3028_FE_DIBCOM52,
421};
422
423static struct xc2028_config stk7700ph_xc3028_config = {
424 .i2c_addr = 0x61,
425 .ctrl = &stk7700ph_xc3028_ctrl,
426};
427
428static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
429{
430 struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;
431
432 if (desc->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
433 desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX))
434 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
435 else
436 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
437 msleep(20);
438 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
439 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
440 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
441 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
442 msleep(10);
443 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
444 msleep(20);
445 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
446 msleep(10);
447
448 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
449 &stk7700ph_dib7700_xc3028_config) != 0) {
450 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
451 __func__);
452 return -ENODEV;
453 }
454
455 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
456 &stk7700ph_dib7700_xc3028_config);
457
458 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
459}
460
461static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
462{
463 struct i2c_adapter *tun_i2c;
464
465 tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
466 DIBX000_I2C_INTERFACE_TUNER, 1);
467
468 stk7700ph_xc3028_config.i2c_adap = tun_i2c;
469
470 /* FIXME: generalize & move to common area */
471 adap->fe_adap[0].fe->callback = stk7700ph_xc3028_callback;
472
473 return dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &stk7700ph_xc3028_config)
474 == NULL ? -ENODEV : 0;
475}
476
477#define DEFAULT_RC_INTERVAL 50
478
479static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
480
481/* Number of keypresses to ignore before start repeating */
482#define RC_REPEAT_DELAY 6
483
484/*
485 * This function is used only when firmware is < 1.20 version. Newer
486 * firmwares use bulk mode, with functions implemented at dib0700_core,
487 * at dib0700_rc_urb_completion()
488 */
489static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
490{
491 u8 key[4];
492 u32 keycode;
493 u8 toggle;
494 int i;
495 struct dib0700_state *st = d->priv;
496
497 if (st->fw_version >= 0x10200) {
498 /* For 1.20 firmware , We need to keep the RC polling
499 callback so we can reuse the input device setup in
500 dvb-usb-remote.c. However, the actual work is being done
501 in the bulk URB completion handler. */
502 return 0;
503 }
504
505 i = dib0700_ctrl_rd(d, rc_request, 2, key, 4);
506 if (i <= 0) {
507 err("RC Query Failed");
508 return -1;
509 }
510
511 /* losing half of KEY_0 events from Philipps rc5 remotes.. */
512 if (key[0] == 0 && key[1] == 0 && key[2] == 0 && key[3] == 0)
513 return 0;
514
515 /* 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]); */
516
517 dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */
518
519 d->last_event = 0;
520 switch (d->props.rc.core.protocol) {
521 case RC_TYPE_NEC:
522 /* NEC protocol sends repeat code as 0 0 0 FF */
523 if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
524 (key[3] == 0xff))
525 keycode = d->last_event;
526 else {
527 keycode = key[3-2] << 8 | key[3-3];
528 d->last_event = keycode;
529 }
530
531 rc_keydown(d->rc_dev, keycode, 0);
532 break;
533 default:
534 /* RC-5 protocol changes toggle bit on new keypress */
535 keycode = key[3-2] << 8 | key[3-3];
536 toggle = key[3-1];
537 rc_keydown(d->rc_dev, keycode, toggle);
538
539 break;
540 }
541 return 0;
542}
543
544/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
545static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
546 BAND_UHF | BAND_VHF,
547
548 /* 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,
549 * 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 */
550 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
551 | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
552
553 712,
554 41,
555
556 0,
557 118,
558
559 0,
560 4095,
561 0,
562 0,
563
564 42598,
565 17694,
566 45875,
567 2621,
568 0,
569 76,
570 139,
571 52,
572 59,
573 107,
574 172,
575 57,
576 70,
577
578 21,
579 25,
580 28,
581 48,
582
583 1,
584 { 0,
585 107,
586 51800,
587 24700
588 },
589};
590
591static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
592 BAND_UHF | BAND_VHF,
593
594 /* 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,
595 * 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 */
596 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
597 | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
598
599 712,
600 41,
601
602 0,
603 118,
604
605 0,
606 4095,
607 0,
608 0,
609
610 42598,
611 16384,
612 42598,
613 0,
614
615 0,
616 137,
617 255,
618
619 0,
620 255,
621
622 0,
623 0,
624
625 0,
626 41,
627
628 15,
629 25,
630
631 28,
632 48,
633
634 0,
635};
636
637static struct dibx000_bandwidth_config stk7700p_pll_config = {
638 60000, 30000,
639 1, 8, 3, 1, 0,
640 0, 0, 1, 1, 0,
641 (3 << 14) | (1 << 12) | (524 << 0),
642 60258167,
643 20452225,
644 30000000,
645};
646
647static struct dib7000m_config stk7700p_dib7000m_config = {
648 .dvbt_mode = 1,
649 .output_mpeg2_in_188_bytes = 1,
650 .quartz_direct = 1,
651
652 .agc_config_count = 1,
653 .agc = &stk7700p_7000m_mt2060_agc_config,
654 .bw = &stk7700p_pll_config,
655
656 .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
657 .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
658 .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
659};
660
661static struct dib7000p_config stk7700p_dib7000p_config = {
662 .output_mpeg2_in_188_bytes = 1,
663
664 .agc_config_count = 1,
665 .agc = &stk7700p_7000p_mt2060_agc_config,
666 .bw = &stk7700p_pll_config,
667
668 .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
669 .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
670 .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
671};
672
673static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
674{
675 struct dib0700_state *st = adap->dev->priv;
676 /* unless there is no real power management in DVB - we leave the device on GPIO6 */
677
678 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
679 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(50);
680
681 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10);
682 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
683
684 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
685 dib0700_ctrl_clock(adap->dev, 72, 1);
686 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100);
687
688 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
689
690 st->mt2060_if1[0] = 1220;
691
692 if (dib7000pc_detection(&adap->dev->i2c_adap)) {
693 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config);
694 st->is_dib7000pc = 1;
695 } else
696 adap->fe_adap[0].fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config);
697
698 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
699}
700
701static struct mt2060_config stk7700p_mt2060_config = {
702 0x60
703};
704
705static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
706{
707 struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
708 struct dib0700_state *st = adap->dev->priv;
709 struct i2c_adapter *tun_i2c;
710 s8 a;
711 int if1=1220;
712 if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) &&
713 adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) {
714 if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
715 }
716 if (st->is_dib7000pc)
717 tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
718 else
719 tun_i2c = dib7000m_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
720
721 return dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c, &stk7700p_mt2060_config,
722 if1) == NULL ? -ENODEV : 0;
723}
724
725/* DIB7070 generic */
726static struct dibx000_agc_config dib7070_agc_config = {
727 BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
728 /* 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,
729 * 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 */
730 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
731 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
732
733 600,
734 10,
735
736 0,
737 118,
738
739 0,
740 3530,
741 1,
742 5,
743
744 65535,
745 0,
746
747 65535,
748 0,
749
750 0,
751 40,
752 183,
753 206,
754 255,
755 72,
756 152,
757 88,
758 90,
759
760 17,
761 27,
762 23,
763 51,
764
765 0,
766};
767
768static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
769{
770 deb_info("reset: %d", onoff);
771 return dib7000p_set_gpio(fe, 8, 0, !onoff);
772}
773
774static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
775{
776 deb_info("sleep: %d", onoff);
777 return dib7000p_set_gpio(fe, 9, 0, onoff);
778}
779
780static struct dib0070_config dib7070p_dib0070_config[2] = {
781 {
782 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
783 .reset = dib7070_tuner_reset,
784 .sleep = dib7070_tuner_sleep,
785 .clock_khz = 12000,
786 .clock_pad_drive = 4,
787 .charge_pump = 2,
788 }, {
789 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
790 .reset = dib7070_tuner_reset,
791 .sleep = dib7070_tuner_sleep,
792 .clock_khz = 12000,
793 .charge_pump = 2,
794 }
795};
796
797static struct dib0070_config dib7770p_dib0070_config = {
798 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
799 .reset = dib7070_tuner_reset,
800 .sleep = dib7070_tuner_sleep,
801 .clock_khz = 12000,
802 .clock_pad_drive = 0,
803 .flip_chip = 1,
804 .charge_pump = 2,
805};
806
807static int dib7070_set_param_override(struct dvb_frontend *fe)
808{
809 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
810 struct dvb_usb_adapter *adap = fe->dvb->priv;
811 struct dib0700_adapter_state *state = adap->priv;
812
813 u16 offset;
814 u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
815 switch (band) {
816 case BAND_VHF: offset = 950; break;
817 case BAND_UHF:
818 default: offset = 550; break;
819 }
820 deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
821 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
822 return state->set_param_save(fe);
823}
824
825static int dib7770_set_param_override(struct dvb_frontend *fe)
826{
827 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
828 struct dvb_usb_adapter *adap = fe->dvb->priv;
829 struct dib0700_adapter_state *state = adap->priv;
830
831 u16 offset;
832 u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
833 switch (band) {
834 case BAND_VHF:
835 dib7000p_set_gpio(fe, 0, 0, 1);
836 offset = 850;
837 break;
838 case BAND_UHF:
839 default:
840 dib7000p_set_gpio(fe, 0, 0, 0);
841 offset = 250;
842 break;
843 }
844 deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
845 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
846 return state->set_param_save(fe);
847}
848
849static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap)
850{
851 struct dib0700_adapter_state *st = adap->priv;
852 struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
853 DIBX000_I2C_INTERFACE_TUNER, 1);
854
855 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
856 &dib7770p_dib0070_config) == NULL)
857 return -ENODEV;
858
859 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
860 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7770_set_param_override;
861 return 0;
862}
863
864static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
865{
866 struct dib0700_adapter_state *st = adap->priv;
867 struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
868
869 if (adap->id == 0) {
870 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
871 return -ENODEV;
872 } else {
873 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL)
874 return -ENODEV;
875 }
876
877 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
878 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override;
879 return 0;
880}
881
882static int stk7700p_pid_filter(struct dvb_usb_adapter *adapter, int index,
883 u16 pid, int onoff)
884{
885 struct dib0700_state *st = adapter->dev->priv;
886 if (st->is_dib7000pc)
887 return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
888 return dib7000m_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
889}
890
891static int stk7700p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
892{
893 struct dib0700_state *st = adapter->dev->priv;
894 if (st->is_dib7000pc)
895 return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
896 return dib7000m_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
897}
898
899static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
900{
901 return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
902}
903
904static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
905{
906 return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
907}
908
909static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
910 60000, 15000,
911 1, 20, 3, 1, 0,
912 0, 0, 1, 1, 2,
913 (3 << 14) | (1 << 12) | (524 << 0),
914 (0 << 25) | 0,
915 20452225,
916 12000000,
917};
918
919static struct dib7000p_config dib7070p_dib7000p_config = {
920 .output_mpeg2_in_188_bytes = 1,
921
922 .agc_config_count = 1,
923 .agc = &dib7070_agc_config,
924 .bw = &dib7070_bw_config_12_mhz,
925 .tuner_is_baseband = 1,
926 .spur_protect = 1,
927
928 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
929 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
930 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
931
932 .hostbus_diversity = 1,
933};
934
935/* STK7070P */
936static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
937{
938 struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
939 if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
940 p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
941 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
942 else
943 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
944 msleep(10);
945 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
946 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
947 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
948 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
949
950 dib0700_ctrl_clock(adap->dev, 72, 1);
951
952 msleep(10);
953 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
954 msleep(10);
955 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
956
957 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
958 &dib7070p_dib7000p_config) != 0) {
959 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
960 __func__);
961 return -ENODEV;
962 }
963
964 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
965 &dib7070p_dib7000p_config);
966 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
967}
968
969/* STK7770P */
970static struct dib7000p_config dib7770p_dib7000p_config = {
971 .output_mpeg2_in_188_bytes = 1,
972
973 .agc_config_count = 1,
974 .agc = &dib7070_agc_config,
975 .bw = &dib7070_bw_config_12_mhz,
976 .tuner_is_baseband = 1,
977 .spur_protect = 1,
978
979 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
980 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
981 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
982
983 .hostbus_diversity = 1,
984 .enable_current_mirror = 1,
985 .disable_sample_and_hold = 0,
986};
987
988static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap)
989{
990 struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
991 if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
992 p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
993 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
994 else
995 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
996 msleep(10);
997 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
998 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
999 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1000 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1001
1002 dib0700_ctrl_clock(adap->dev, 72, 1);
1003
1004 msleep(10);
1005 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1006 msleep(10);
1007 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1008
1009 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1010 &dib7770p_dib7000p_config) != 0) {
1011 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
1012 __func__);
1013 return -ENODEV;
1014 }
1015
1016 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1017 &dib7770p_dib7000p_config);
1018 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
1019}
1020
1021/* DIB807x generic */
1022static struct dibx000_agc_config dib807x_agc_config[2] = {
1023 {
1024 BAND_VHF,
1025 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1026 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1027 * P_agc_inv_pwm2=0,P_agc_inh_dc_rv_est=0,
1028 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1029 * P_agc_write=0 */
1030 (0 << 15) | (0 << 14) | (7 << 11) | (0 << 10) | (0 << 9) |
1031 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
1032 (0 << 0), /* setup*/
1033
1034 600, /* inv_gain*/
1035 10, /* time_stabiliz*/
1036
1037 0, /* alpha_level*/
1038 118, /* thlock*/
1039
1040 0, /* wbd_inv*/
1041 3530, /* wbd_ref*/
1042 1, /* wbd_sel*/
1043 5, /* wbd_alpha*/
1044
1045 65535, /* agc1_max*/
1046 0, /* agc1_min*/
1047
1048 65535, /* agc2_max*/
1049 0, /* agc2_min*/
1050
1051 0, /* agc1_pt1*/
1052 40, /* agc1_pt2*/
1053 183, /* agc1_pt3*/
1054 206, /* agc1_slope1*/
1055 255, /* agc1_slope2*/
1056 72, /* agc2_pt1*/
1057 152, /* agc2_pt2*/
1058 88, /* agc2_slope1*/
1059 90, /* agc2_slope2*/
1060
1061 17, /* alpha_mant*/
1062 27, /* alpha_exp*/
1063 23, /* beta_mant*/
1064 51, /* beta_exp*/
1065
1066 0, /* perform_agc_softsplit*/
1067 }, {
1068 BAND_UHF,
1069 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1070 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1071 * P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1072 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1073 * P_agc_write=0 */
1074 (0 << 15) | (0 << 14) | (1 << 11) | (0 << 10) | (0 << 9) |
1075 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
1076 (0 << 0), /* setup */
1077
1078 600, /* inv_gain*/
1079 10, /* time_stabiliz*/
1080
1081 0, /* alpha_level*/
1082 118, /* thlock*/
1083
1084 0, /* wbd_inv*/
1085 3530, /* wbd_ref*/
1086 1, /* wbd_sel*/
1087 5, /* wbd_alpha*/
1088
1089 65535, /* agc1_max*/
1090 0, /* agc1_min*/
1091
1092 65535, /* agc2_max*/
1093 0, /* agc2_min*/
1094
1095 0, /* agc1_pt1*/
1096 40, /* agc1_pt2*/
1097 183, /* agc1_pt3*/
1098 206, /* agc1_slope1*/
1099 255, /* agc1_slope2*/
1100 72, /* agc2_pt1*/
1101 152, /* agc2_pt2*/
1102 88, /* agc2_slope1*/
1103 90, /* agc2_slope2*/
1104
1105 17, /* alpha_mant*/
1106 27, /* alpha_exp*/
1107 23, /* beta_mant*/
1108 51, /* beta_exp*/
1109
1110 0, /* perform_agc_softsplit*/
1111 }
1112};
1113
1114static struct dibx000_bandwidth_config dib807x_bw_config_12_mhz = {
1115 60000, 15000, /* internal, sampling*/
1116 1, 20, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass*/
1117 0, 0, 1, 1, 2, /* misc: refdiv, bypclk_div, IO_CLK_en_core,
1118 ADClkSrc, modulo */
1119 (3 << 14) | (1 << 12) | (599 << 0), /* sad_cfg: refsel, sel, freq_15k*/
1120 (0 << 25) | 0, /* ifreq = 0.000000 MHz*/
1121 18179755, /* timf*/
1122 12000000, /* xtal_hz*/
1123};
1124
1125static struct dib8000_config dib807x_dib8000_config[2] = {
1126 {
1127 .output_mpeg2_in_188_bytes = 1,
1128
1129 .agc_config_count = 2,
1130 .agc = dib807x_agc_config,
1131 .pll = &dib807x_bw_config_12_mhz,
1132 .tuner_is_baseband = 1,
1133
1134 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1135 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1136 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1137
1138 .hostbus_diversity = 1,
1139 .div_cfg = 1,
1140 .agc_control = &dib0070_ctrl_agc_filter,
1141 .output_mode = OUTMODE_MPEG2_FIFO,
1142 .drives = 0x2d98,
1143 }, {
1144 .output_mpeg2_in_188_bytes = 1,
1145
1146 .agc_config_count = 2,
1147 .agc = dib807x_agc_config,
1148 .pll = &dib807x_bw_config_12_mhz,
1149 .tuner_is_baseband = 1,
1150
1151 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1152 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1153 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1154
1155 .hostbus_diversity = 1,
1156 .agc_control = &dib0070_ctrl_agc_filter,
1157 .output_mode = OUTMODE_MPEG2_FIFO,
1158 .drives = 0x2d98,
1159 }
1160};
1161
1162static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff)
1163{
1164 return dib8000_set_gpio(fe, 5, 0, !onoff);
1165}
1166
1167static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff)
1168{
1169 return dib8000_set_gpio(fe, 0, 0, onoff);
1170}
1171
1172static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
1173 { 240, 7},
1174 { 0xffff, 6},
1175};
1176
1177static struct dib0070_config dib807x_dib0070_config[2] = {
1178 {
1179 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1180 .reset = dib80xx_tuner_reset,
1181 .sleep = dib80xx_tuner_sleep,
1182 .clock_khz = 12000,
1183 .clock_pad_drive = 4,
1184 .vga_filter = 1,
1185 .force_crystal_mode = 1,
1186 .enable_third_order_filter = 1,
1187 .charge_pump = 0,
1188 .wbd_gain = dib8070_wbd_gain_cfg,
1189 .osc_buffer_state = 0,
1190 .freq_offset_khz_uhf = -100,
1191 .freq_offset_khz_vhf = -100,
1192 }, {
1193 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1194 .reset = dib80xx_tuner_reset,
1195 .sleep = dib80xx_tuner_sleep,
1196 .clock_khz = 12000,
1197 .clock_pad_drive = 2,
1198 .vga_filter = 1,
1199 .force_crystal_mode = 1,
1200 .enable_third_order_filter = 1,
1201 .charge_pump = 0,
1202 .wbd_gain = dib8070_wbd_gain_cfg,
1203 .osc_buffer_state = 0,
1204 .freq_offset_khz_uhf = -25,
1205 .freq_offset_khz_vhf = -25,
1206 }
1207};
1208
1209static int dib807x_set_param_override(struct dvb_frontend *fe)
1210{
1211 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1212 struct dvb_usb_adapter *adap = fe->dvb->priv;
1213 struct dib0700_adapter_state *state = adap->priv;
1214
1215 u16 offset = dib0070_wbd_offset(fe);
1216 u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
1217 switch (band) {
1218 case BAND_VHF:
1219 offset += 750;
1220 break;
1221 case BAND_UHF: /* fall-thru wanted */
1222 default:
1223 offset += 250; break;
1224 }
1225 deb_info("WBD for DiB8000: %d\n", offset);
1226 dib8000_set_wbd_ref(fe, offset);
1227
1228 return state->set_param_save(fe);
1229}
1230
1231static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
1232{
1233 struct dib0700_adapter_state *st = adap->priv;
1234 struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe,
1235 DIBX000_I2C_INTERFACE_TUNER, 1);
1236
1237 if (adap->id == 0) {
1238 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
1239 &dib807x_dib0070_config[0]) == NULL)
1240 return -ENODEV;
1241 } else {
1242 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
1243 &dib807x_dib0070_config[1]) == NULL)
1244 return -ENODEV;
1245 }
1246
1247 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
1248 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib807x_set_param_override;
1249 return 0;
1250}
1251
1252static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
1253 u16 pid, int onoff)
1254{
1255 return dib8000_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
1256}
1257
1258static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
1259 int onoff)
1260{
1261 return dib8000_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
1262}
1263
1264/* STK807x */
1265static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
1266{
1267 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1268 msleep(10);
1269 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1270 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1271 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1272
1273 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1274
1275 dib0700_ctrl_clock(adap->dev, 72, 1);
1276
1277 msleep(10);
1278 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1279 msleep(10);
1280 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1281
1282 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1283 0x80, 0);
1284
1285 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
1286 &dib807x_dib8000_config[0]);
1287
1288 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
1289}
1290
1291/* STK807xPVR */
1292static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
1293{
1294 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1295 msleep(30);
1296 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1297 msleep(500);
1298 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1299 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1300 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1301
1302 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1303
1304 dib0700_ctrl_clock(adap->dev, 72, 1);
1305
1306 msleep(10);
1307 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1308 msleep(10);
1309 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1310
1311 /* initialize IC 0 */
1312 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0);
1313
1314 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
1315 &dib807x_dib8000_config[0]);
1316
1317 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
1318}
1319
1320static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
1321{
1322 /* initialize IC 1 */
1323 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0);
1324
1325 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
1326 &dib807x_dib8000_config[1]);
1327
1328 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
1329}
1330
1331/* STK8096GP */
1332static struct dibx000_agc_config dib8090_agc_config[2] = {
1333 {
1334 BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
1335 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
1336 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1337 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
1338 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
1339 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1340
1341 787,
1342 10,
1343
1344 0,
1345 118,
1346
1347 0,
1348 3530,
1349 1,
1350 5,
1351
1352 65535,
1353 0,
1354
1355 65535,
1356 0,
1357
1358 0,
1359 32,
1360 114,
1361 143,
1362 144,
1363 114,
1364 227,
1365 116,
1366 117,
1367
1368 28,
1369 26,
1370 31,
1371 51,
1372
1373 0,
1374 },
1375 {
1376 BAND_CBAND,
1377 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
1378 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1379 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
1380 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
1381 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1382
1383 787,
1384 10,
1385
1386 0,
1387 118,
1388
1389 0,
1390 3530,
1391 1,
1392 5,
1393
1394 0,
1395 0,
1396
1397 65535,
1398 0,
1399
1400 0,
1401 32,
1402 114,
1403 143,
1404 144,
1405 114,
1406 227,
1407 116,
1408 117,
1409
1410 28,
1411 26,
1412 31,
1413 51,
1414
1415 0,
1416 }
1417};
1418
1419static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
1420 54000, 13500,
1421 1, 18, 3, 1, 0,
1422 0, 0, 1, 1, 2,
1423 (3 << 14) | (1 << 12) | (599 << 0),
1424 (0 << 25) | 0,
1425 20199727,
1426 12000000,
1427};
1428
1429static int dib8090_get_adc_power(struct dvb_frontend *fe)
1430{
1431 return dib8000_get_adc_power(fe, 1);
1432}
1433
1434static struct dib8000_config dib809x_dib8000_config[2] = {
1435 {
1436 .output_mpeg2_in_188_bytes = 1,
1437
1438 .agc_config_count = 2,
1439 .agc = dib8090_agc_config,
1440 .agc_control = dib0090_dcc_freq,
1441 .pll = &dib8090_pll_config_12mhz,
1442 .tuner_is_baseband = 1,
1443
1444 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1445 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1446 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1447
1448 .hostbus_diversity = 1,
1449 .div_cfg = 0x31,
1450 .output_mode = OUTMODE_MPEG2_FIFO,
1451 .drives = 0x2d98,
1452 .diversity_delay = 48,
1453 .refclksel = 3,
1454 }, {
1455 .output_mpeg2_in_188_bytes = 1,
1456
1457 .agc_config_count = 2,
1458 .agc = dib8090_agc_config,
1459 .agc_control = dib0090_dcc_freq,
1460 .pll = &dib8090_pll_config_12mhz,
1461 .tuner_is_baseband = 1,
1462
1463 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1464 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1465 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1466
1467 .hostbus_diversity = 1,
1468 .div_cfg = 0x31,
1469 .output_mode = OUTMODE_DIVERSITY,
1470 .drives = 0x2d08,
1471 .diversity_delay = 1,
1472 .refclksel = 3,
1473 }
1474};
1475
1476static struct dib0090_wbd_slope dib8090_wbd_table[] = {
1477 /* max freq ; cold slope ; cold offset ; warm slope ; warm offset ; wbd gain */
1478 { 120, 0, 500, 0, 500, 4 }, /* CBAND */
1479 { 170, 0, 450, 0, 450, 4 }, /* CBAND */
1480 { 380, 48, 373, 28, 259, 6 }, /* VHF */
1481 { 860, 34, 700, 36, 616, 6 }, /* high UHF */
1482 { 0xFFFF, 34, 700, 36, 616, 6 }, /* default */
1483};
1484
1485static struct dib0090_config dib809x_dib0090_config = {
1486 .io.pll_bypass = 1,
1487 .io.pll_range = 1,
1488 .io.pll_prediv = 1,
1489 .io.pll_loopdiv = 20,
1490 .io.adc_clock_ratio = 8,
1491 .io.pll_int_loop_filt = 0,
1492 .io.clock_khz = 12000,
1493 .reset = dib80xx_tuner_reset,
1494 .sleep = dib80xx_tuner_sleep,
1495 .clkouttobamse = 1,
1496 .analog_output = 1,
1497 .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
1498 .use_pwm_agc = 1,
1499 .clkoutdrive = 1,
1500 .get_adc_power = dib8090_get_adc_power,
1501 .freq_offset_khz_uhf = -63,
1502 .freq_offset_khz_vhf = -143,
1503 .wbd = dib8090_wbd_table,
1504 .fref_clock_ratio = 6,
1505};
1506
1507static int dib8096_set_param_override(struct dvb_frontend *fe)
1508{
1509 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1510 struct dvb_usb_adapter *adap = fe->dvb->priv;
1511 struct dib0700_adapter_state *state = adap->priv;
1512 u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
1513 u16 target;
1514 int ret = 0;
1515 enum frontend_tune_state tune_state = CT_SHUTDOWN;
1516 u16 ltgain, rf_gain_limit;
1517
1518 ret = state->set_param_save(fe);
1519 if (ret < 0)
1520 return ret;
1521
1522 target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2;
1523 dib8000_set_wbd_ref(fe, target);
1524
1525
1526 if (band == BAND_CBAND) {
1527 deb_info("tuning in CBAND - soft-AGC startup\n");
1528 dib0090_set_tune_state(fe, CT_AGC_START);
1529 do {
1530 ret = dib0090_gain_control(fe);
1531 msleep(ret);
1532 tune_state = dib0090_get_tune_state(fe);
1533 if (tune_state == CT_AGC_STEP_0)
1534 dib8000_set_gpio(fe, 6, 0, 1);
1535 else if (tune_state == CT_AGC_STEP_1) {
1536 dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
1537 if (rf_gain_limit == 0)
1538 dib8000_set_gpio(fe, 6, 0, 0);
1539 }
1540 } while (tune_state < CT_AGC_STOP);
1541 dib0090_pwm_gain_reset(fe);
1542 dib8000_pwm_agc_reset(fe);
1543 dib8000_set_tune_state(fe, CT_DEMOD_START);
1544 } else {
1545 deb_info("not tuning in CBAND - standard AGC startup\n");
1546 dib0090_pwm_gain_reset(fe);
1547 }
1548
1549 return 0;
1550}
1551
1552static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
1553{
1554 struct dib0700_adapter_state *st = adap->priv;
1555 struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1556
1557 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
1558 return -ENODEV;
1559
1560 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
1561 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096_set_param_override;
1562 return 0;
1563}
1564
1565static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
1566{
1567 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1568 msleep(10);
1569 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1570 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1571 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1572
1573 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1574
1575 dib0700_ctrl_clock(adap->dev, 72, 1);
1576
1577 msleep(10);
1578 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1579 msleep(10);
1580 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1581
1582 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0);
1583
1584 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
1585
1586 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
1587}
1588
1589static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap)
1590{
1591 struct dib0700_adapter_state *st = adap->priv;
1592 struct i2c_adapter *tun_i2c;
1593 struct dvb_frontend *fe_slave = dib8000_get_slave_frontend(adap->fe_adap[0].fe, 1);
1594
1595 if (fe_slave) {
1596 tun_i2c = dib8000_get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1);
1597 if (dvb_attach(dib0090_register, fe_slave, tun_i2c, &dib809x_dib0090_config) == NULL)
1598 return -ENODEV;
1599 fe_slave->dvb = adap->fe_adap[0].fe->dvb;
1600 fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override;
1601 }
1602 tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1603 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
1604 return -ENODEV;
1605
1606 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
1607 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096_set_param_override;
1608
1609 return 0;
1610}
1611
1612static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap)
1613{
1614 struct dvb_frontend *fe_slave;
1615
1616 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1617 msleep(20);
1618 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1619 msleep(1000);
1620 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1621 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1622 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1623
1624 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1625
1626 dib0700_ctrl_clock(adap->dev, 72, 1);
1627
1628 msleep(20);
1629 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1630 msleep(20);
1631 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1632
1633 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0);
1634
1635 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
1636 if (adap->fe_adap[0].fe == NULL)
1637 return -ENODEV;
1638
1639 fe_slave = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]);
1640 dib8000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave);
1641
1642 return fe_slave == NULL ? -ENODEV : 0;
1643}
1644
1645/* TFE8096P */
1646static struct dibx000_agc_config dib8096p_agc_config[2] = {
1647 {
1648 .band_caps = BAND_UHF,
1649 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1650 P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1651 P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1652 P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1653 P_agc_write=0 */
1654 .setup = (0 << 15) | (0 << 14) | (5 << 11)
1655 | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5)
1656 | (0 << 4) | (5 << 1) | (0 << 0),
1657
1658 .inv_gain = 684,
1659 .time_stabiliz = 10,
1660
1661 .alpha_level = 0,
1662 .thlock = 118,
1663
1664 .wbd_inv = 0,
1665 .wbd_ref = 1200,
1666 .wbd_sel = 3,
1667 .wbd_alpha = 5,
1668
1669 .agc1_max = 65535,
1670 .agc1_min = 0,
1671
1672 .agc2_max = 32767,
1673 .agc2_min = 0,
1674
1675 .agc1_pt1 = 0,
1676 .agc1_pt2 = 0,
1677 .agc1_pt3 = 105,
1678 .agc1_slope1 = 0,
1679 .agc1_slope2 = 156,
1680 .agc2_pt1 = 105,
1681 .agc2_pt2 = 255,
1682 .agc2_slope1 = 54,
1683 .agc2_slope2 = 0,
1684
1685 .alpha_mant = 28,
1686 .alpha_exp = 26,
1687 .beta_mant = 31,
1688 .beta_exp = 51,
1689
1690 .perform_agc_softsplit = 0,
1691 } , {
1692 .band_caps = BAND_FM | BAND_VHF | BAND_CBAND,
1693 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1694 P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1695 P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1696 P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1697 P_agc_write=0 */
1698 .setup = (0 << 15) | (0 << 14) | (5 << 11)
1699 | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5)
1700 | (0 << 4) | (5 << 1) | (0 << 0),
1701
1702 .inv_gain = 732,
1703 .time_stabiliz = 10,
1704
1705 .alpha_level = 0,
1706 .thlock = 118,
1707
1708 .wbd_inv = 0,
1709 .wbd_ref = 1200,
1710 .wbd_sel = 3,
1711 .wbd_alpha = 5,
1712
1713 .agc1_max = 65535,
1714 .agc1_min = 0,
1715
1716 .agc2_max = 32767,
1717 .agc2_min = 0,
1718
1719 .agc1_pt1 = 0,
1720 .agc1_pt2 = 0,
1721 .agc1_pt3 = 98,
1722 .agc1_slope1 = 0,
1723 .agc1_slope2 = 167,
1724 .agc2_pt1 = 98,
1725 .agc2_pt2 = 255,
1726 .agc2_slope1 = 52,
1727 .agc2_slope2 = 0,
1728
1729 .alpha_mant = 28,
1730 .alpha_exp = 26,
1731 .beta_mant = 31,
1732 .beta_exp = 51,
1733
1734 .perform_agc_softsplit = 0,
1735 }
1736};
1737
1738static struct dibx000_bandwidth_config dib8096p_clock_config_12_mhz = {
1739 108000, 13500,
1740 1, 9, 1, 0, 0,
1741 0, 0, 0, 0, 2,
1742 (3 << 14) | (1 << 12) | (524 << 0),
1743 (0 << 25) | 0,
1744 20199729,
1745 12000000,
1746};
1747
1748static struct dib8000_config tfe8096p_dib8000_config = {
1749 .output_mpeg2_in_188_bytes = 1,
1750 .hostbus_diversity = 1,
1751 .update_lna = NULL,
1752
1753 .agc_config_count = 2,
1754 .agc = dib8096p_agc_config,
1755 .pll = &dib8096p_clock_config_12_mhz,
1756
1757 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1758 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1759 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1760
1761 .agc_control = NULL,
1762 .diversity_delay = 48,
1763 .output_mode = OUTMODE_MPEG2_FIFO,
1764 .enMpegOutput = 1,
1765};
1766
1767static struct dib0090_wbd_slope dib8096p_wbd_table[] = {
1768 { 380, 81, 850, 64, 540, 4},
1769 { 860, 51, 866, 21, 375, 4},
1770 {1700, 0, 250, 0, 100, 6},
1771 {2600, 0, 250, 0, 100, 6},
1772 { 0xFFFF, 0, 0, 0, 0, 0},
1773};
1774
1775static const struct dib0090_config tfe8096p_dib0090_config = {
1776 .io.clock_khz = 12000,
1777 .io.pll_bypass = 0,
1778 .io.pll_range = 0,
1779 .io.pll_prediv = 3,
1780 .io.pll_loopdiv = 6,
1781 .io.adc_clock_ratio = 0,
1782 .io.pll_int_loop_filt = 0,
1783 .reset = dib8096p_tuner_sleep,
1784 .sleep = dib8096p_tuner_sleep,
1785
1786 .freq_offset_khz_uhf = -143,
1787 .freq_offset_khz_vhf = -143,
1788
1789 .get_adc_power = dib8090_get_adc_power,
1790
1791 .clkouttobamse = 1,
1792 .analog_output = 0,
1793
1794 .wbd_vhf_offset = 0,
1795 .wbd_cband_offset = 0,
1796 .use_pwm_agc = 1,
1797 .clkoutdrive = 0,
1798
1799 .fref_clock_ratio = 1,
1800
1801 .wbd = dib8096p_wbd_table,
1802
1803 .ls_cfg_pad_drv = 0,
1804 .data_tx_drv = 0,
1805 .low_if = NULL,
1806 .in_soc = 1,
1807 .force_cband_input = 0,
1808};
1809
1810struct dibx090p_adc {
1811 u32 freq; /* RF freq MHz */
1812 u32 timf; /* New Timf */
1813 u32 pll_loopdiv; /* New prediv */
1814 u32 pll_prediv; /* New loopdiv */
1815};
1816
1817struct dibx090p_adc dib8090p_adc_tab[] = {
1818 { 50000, 17043521, 16, 3}, /* 64 MHz */
1819 {878000, 20199729, 9, 1}, /* 60 MHz */
1820 {0xffffffff, 0, 0, 0}, /* 60 MHz */
1821};
1822
1823static int dib8096p_agc_startup(struct dvb_frontend *fe)
1824{
1825 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1826 struct dvb_usb_adapter *adap = fe->dvb->priv;
1827 struct dib0700_adapter_state *state = adap->priv;
1828 struct dibx000_bandwidth_config pll;
1829 u16 target;
1830 int better_sampling_freq = 0, ret;
1831 struct dibx090p_adc *adc_table = &dib8090p_adc_tab[0];
1832
1833 ret = state->set_param_save(fe);
1834 if (ret < 0)
1835 return ret;
1836 memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
1837
1838 dib0090_pwm_gain_reset(fe);
1839 /* dib0090_get_wbd_target is returning any possible
1840 temperature compensated wbd-target */
1841 target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2;
1842 dib8000_set_wbd_ref(fe, target);
1843
1844
1845 while (p->frequency / 1000 > adc_table->freq) {
1846 better_sampling_freq = 1;
1847 adc_table++;
1848 }
1849
1850 if ((adc_table->freq != 0xffffffff) && better_sampling_freq) {
1851 pll.pll_ratio = adc_table->pll_loopdiv;
1852 pll.pll_prediv = adc_table->pll_prediv;
1853 dib8000_update_pll(fe, &pll);
1854 dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, adc_table->timf);
1855 }
1856 return 0;
1857}
1858
1859static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap)
1860{
1861 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1862 msleep(20);
1863 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1864 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1865 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1866
1867 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1868
1869 dib0700_ctrl_clock(adap->dev, 72, 1);
1870
1871 msleep(20);
1872 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1873 msleep(20);
1874 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1875
1876 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1);
1877
1878 adap->fe_adap[0].fe = dvb_attach(dib8000_attach,
1879 &adap->dev->i2c_adap, 0x80, &tfe8096p_dib8000_config);
1880
1881 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
1882}
1883
1884static int tfe8096p_tuner_attach(struct dvb_usb_adapter *adap)
1885{
1886 struct dib0700_adapter_state *st = adap->priv;
1887 struct i2c_adapter *tun_i2c = dib8096p_get_i2c_tuner(adap->fe_adap[0].fe);
1888
1889 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
1890 &tfe8096p_dib0090_config) == NULL)
1891 return -ENODEV;
1892
1893 dib8000_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
1894
1895 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
1896 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096p_agc_startup;
1897 return 0;
1898}
1899
1900/* STK9090M */
1901static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
1902{
1903 return dib9000_fw_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
1904}
1905
1906static int dib90x0_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
1907{
1908 return dib9000_fw_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
1909}
1910
1911static int dib90x0_tuner_reset(struct dvb_frontend *fe, int onoff)
1912{
1913 return dib9000_set_gpio(fe, 5, 0, !onoff);
1914}
1915
1916static int dib90x0_tuner_sleep(struct dvb_frontend *fe, int onoff)
1917{
1918 return dib9000_set_gpio(fe, 0, 0, onoff);
1919}
1920
1921static int dib01x0_pmu_update(struct i2c_adapter *i2c, u16 *data, u8 len)
1922{
1923 u8 wb[4] = { 0xc >> 8, 0xc & 0xff, 0, 0 };
1924 u8 rb[2];
1925 struct i2c_msg msg[2] = {
1926 {.addr = 0x1e >> 1, .flags = 0, .buf = wb, .len = 2},
1927 {.addr = 0x1e >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2},
1928 };
1929 u8 index_data;
1930
1931 dibx000_i2c_set_speed(i2c, 250);
1932
1933 if (i2c_transfer(i2c, msg, 2) != 2)
1934 return -EIO;
1935
1936 switch (rb[0] << 8 | rb[1]) {
1937 case 0:
1938 deb_info("Found DiB0170 rev1: This version of DiB0170 is not supported any longer.\n");
1939 return -EIO;
1940 case 1:
1941 deb_info("Found DiB0170 rev2");
1942 break;
1943 case 2:
1944 deb_info("Found DiB0190 rev2");
1945 break;
1946 default:
1947 deb_info("DiB01x0 not found");
1948 return -EIO;
1949 }
1950
1951 for (index_data = 0; index_data < len; index_data += 2) {
1952 wb[2] = (data[index_data + 1] >> 8) & 0xff;
1953 wb[3] = (data[index_data + 1]) & 0xff;
1954
1955 if (data[index_data] == 0) {
1956 wb[0] = (data[index_data] >> 8) & 0xff;
1957 wb[1] = (data[index_data]) & 0xff;
1958 msg[0].len = 2;
1959 if (i2c_transfer(i2c, msg, 2) != 2)
1960 return -EIO;
1961 wb[2] |= rb[0];
1962 wb[3] |= rb[1] & ~(3 << 4);
1963 }
1964
1965 wb[0] = (data[index_data] >> 8)&0xff;
1966 wb[1] = (data[index_data])&0xff;
1967 msg[0].len = 4;
1968 if (i2c_transfer(i2c, &msg[0], 1) != 1)
1969 return -EIO;
1970 }
1971 return 0;
1972}
1973
1974static struct dib9000_config stk9090m_config = {
1975 .output_mpeg2_in_188_bytes = 1,
1976 .output_mode = OUTMODE_MPEG2_FIFO,
1977 .vcxo_timer = 279620,
1978 .timing_frequency = 20452225,
1979 .demod_clock_khz = 60000,
1980 .xtal_clock_khz = 30000,
1981 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
1982 .subband = {
1983 2,
1984 {
1985 { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0008 } }, /* GPIO 3 to 1 for VHF */
1986 { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0000 } }, /* GPIO 3 to 0 for UHF */
1987 { 0 },
1988 },
1989 },
1990 .gpio_function = {
1991 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
1992 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
1993 },
1994};
1995
1996static struct dib9000_config nim9090md_config[2] = {
1997 {
1998 .output_mpeg2_in_188_bytes = 1,
1999 .output_mode = OUTMODE_MPEG2_FIFO,
2000 .vcxo_timer = 279620,
2001 .timing_frequency = 20452225,
2002 .demod_clock_khz = 60000,
2003 .xtal_clock_khz = 30000,
2004 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
2005 }, {
2006 .output_mpeg2_in_188_bytes = 1,
2007 .output_mode = OUTMODE_DIVERSITY,
2008 .vcxo_timer = 279620,
2009 .timing_frequency = 20452225,
2010 .demod_clock_khz = 60000,
2011 .xtal_clock_khz = 30000,
2012 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
2013 .subband = {
2014 2,
2015 {
2016 { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0006 } }, /* GPIO 1 and 2 to 1 for VHF */
2017 { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0000 } }, /* GPIO 1 and 2 to 0 for UHF */
2018 { 0 },
2019 },
2020 },
2021 .gpio_function = {
2022 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
2023 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
2024 },
2025 }
2026};
2027
2028static struct dib0090_config dib9090_dib0090_config = {
2029 .io.pll_bypass = 0,
2030 .io.pll_range = 1,
2031 .io.pll_prediv = 1,
2032 .io.pll_loopdiv = 8,
2033 .io.adc_clock_ratio = 8,
2034 .io.pll_int_loop_filt = 0,
2035 .io.clock_khz = 30000,
2036 .reset = dib90x0_tuner_reset,
2037 .sleep = dib90x0_tuner_sleep,
2038 .clkouttobamse = 0,
2039 .analog_output = 0,
2040 .use_pwm_agc = 0,
2041 .clkoutdrive = 0,
2042 .freq_offset_khz_uhf = 0,
2043 .freq_offset_khz_vhf = 0,
2044};
2045
2046static struct dib0090_config nim9090md_dib0090_config[2] = {
2047 {
2048 .io.pll_bypass = 0,
2049 .io.pll_range = 1,
2050 .io.pll_prediv = 1,
2051 .io.pll_loopdiv = 8,
2052 .io.adc_clock_ratio = 8,
2053 .io.pll_int_loop_filt = 0,
2054 .io.clock_khz = 30000,
2055 .reset = dib90x0_tuner_reset,
2056 .sleep = dib90x0_tuner_sleep,
2057 .clkouttobamse = 1,
2058 .analog_output = 0,
2059 .use_pwm_agc = 0,
2060 .clkoutdrive = 0,
2061 .freq_offset_khz_uhf = 0,
2062 .freq_offset_khz_vhf = 0,
2063 }, {
2064 .io.pll_bypass = 0,
2065 .io.pll_range = 1,
2066 .io.pll_prediv = 1,
2067 .io.pll_loopdiv = 8,
2068 .io.adc_clock_ratio = 8,
2069 .io.pll_int_loop_filt = 0,
2070 .io.clock_khz = 30000,
2071 .reset = dib90x0_tuner_reset,
2072 .sleep = dib90x0_tuner_sleep,
2073 .clkouttobamse = 0,
2074 .analog_output = 0,
2075 .use_pwm_agc = 0,
2076 .clkoutdrive = 0,
2077 .freq_offset_khz_uhf = 0,
2078 .freq_offset_khz_vhf = 0,
2079 }
2080};
2081
2082
2083static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap)
2084{
2085 struct dib0700_adapter_state *state = adap->priv;
2086 struct dib0700_state *st = adap->dev->priv;
2087 u32 fw_version;
2088
2089 /* Make use of the new i2c functions from FW 1.20 */
2090 dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
2091 if (fw_version >= 0x10200)
2092 st->fw_use_new_i2c_api = 1;
2093 dib0700_set_i2c_speed(adap->dev, 340);
2094
2095 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2096 msleep(20);
2097 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2098 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2099 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2100 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2101
2102 dib0700_ctrl_clock(adap->dev, 72, 1);
2103
2104 msleep(20);
2105 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2106 msleep(20);
2107 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2108
2109 dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80);
2110
2111 if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
2112 deb_info("%s: Upload failed. (file not found?)\n", __func__);
2113 return -ENODEV;
2114 } else {
2115 deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
2116 }
2117 stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size;
2118 stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data;
2119
2120 adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config);
2121
2122 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
2123}
2124
2125static int dib9090_tuner_attach(struct dvb_usb_adapter *adap)
2126{
2127 struct dib0700_adapter_state *state = adap->priv;
2128 struct i2c_adapter *i2c = dib9000_get_tuner_interface(adap->fe_adap[0].fe);
2129 u16 data_dib190[10] = {
2130 1, 0x1374,
2131 2, 0x01a2,
2132 7, 0x0020,
2133 0, 0x00ef,
2134 8, 0x0486,
2135 };
2136
2137 if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &dib9090_dib0090_config) == NULL)
2138 return -ENODEV;
2139 i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
2140 if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0)
2141 return -ENODEV;
2142 dib0700_set_i2c_speed(adap->dev, 1500);
2143 if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0)
2144 return -ENODEV;
2145 release_firmware(state->frontend_firmware);
2146 return 0;
2147}
2148
2149static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap)
2150{
2151 struct dib0700_adapter_state *state = adap->priv;
2152 struct dib0700_state *st = adap->dev->priv;
2153 struct i2c_adapter *i2c;
2154 struct dvb_frontend *fe_slave;
2155 u32 fw_version;
2156
2157 /* Make use of the new i2c functions from FW 1.20 */
2158 dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
2159 if (fw_version >= 0x10200)
2160 st->fw_use_new_i2c_api = 1;
2161 dib0700_set_i2c_speed(adap->dev, 340);
2162
2163 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2164 msleep(20);
2165 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2166 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2167 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2168 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2169
2170 dib0700_ctrl_clock(adap->dev, 72, 1);
2171
2172 msleep(20);
2173 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2174 msleep(20);
2175 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2176
2177 if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
2178 deb_info("%s: Upload failed. (file not found?)\n", __func__);
2179 return -EIO;
2180 } else {
2181 deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
2182 }
2183 nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size;
2184 nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data;
2185 nim9090md_config[1].microcode_B_fe_size = state->frontend_firmware->size;
2186 nim9090md_config[1].microcode_B_fe_buffer = state->frontend_firmware->data;
2187
2188 dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80);
2189 adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]);
2190
2191 if (adap->fe_adap[0].fe == NULL)
2192 return -ENODEV;
2193
2194 i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0);
2195 dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82);
2196
2197 fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]);
2198 dib9000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave);
2199
2200 return fe_slave == NULL ? -ENODEV : 0;
2201}
2202
2203static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap)
2204{
2205 struct dib0700_adapter_state *state = adap->priv;
2206 struct i2c_adapter *i2c;
2207 struct dvb_frontend *fe_slave;
2208 u16 data_dib190[10] = {
2209 1, 0x5374,
2210 2, 0x01ae,
2211 7, 0x0020,
2212 0, 0x00ef,
2213 8, 0x0406,
2214 };
2215 i2c = dib9000_get_tuner_interface(adap->fe_adap[0].fe);
2216 if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &nim9090md_dib0090_config[0]) == NULL)
2217 return -ENODEV;
2218 i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
2219 if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0)
2220 return -ENODEV;
2221
2222 dib0700_set_i2c_speed(adap->dev, 1500);
2223 if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0)
2224 return -ENODEV;
2225
2226 fe_slave = dib9000_get_slave_frontend(adap->fe_adap[0].fe, 1);
2227 if (fe_slave != NULL) {
2228 i2c = dib9000_get_component_bus_interface(adap->fe_adap[0].fe);
2229 dib9000_set_i2c_adapter(fe_slave, i2c);
2230
2231 i2c = dib9000_get_tuner_interface(fe_slave);
2232 if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL)
2233 return -ENODEV;
2234 fe_slave->dvb = adap->fe_adap[0].fe->dvb;
2235 dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 1500);
2236 if (dib9000_firmware_post_pll_init(fe_slave) < 0)
2237 return -ENODEV;
2238 }
2239 release_firmware(state->frontend_firmware);
2240
2241 return 0;
2242}
2243
2244/* NIM7090 */
2245struct dib7090p_best_adc {
2246 u32 timf;
2247 u32 pll_loopdiv;
2248 u32 pll_prediv;
2249};
2250
2251static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_best_adc *adc)
2252{
2253 u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1;
2254
2255 u16 xtal = 12000;
2256 u32 fcp_min = 1900; /* PLL Minimum Frequency comparator KHz */
2257 u32 fcp_max = 20000; /* PLL Maximum Frequency comparator KHz */
2258 u32 fdem_max = 76000;
2259 u32 fdem_min = 69500;
2260 u32 fcp = 0, fs = 0, fdem = 0;
2261 u32 harmonic_id = 0;
2262
2263 adc->pll_loopdiv = loopdiv;
2264 adc->pll_prediv = prediv;
2265 adc->timf = 0;
2266
2267 deb_info("bandwidth = %d fdem_min =%d", fe->dtv_property_cache.bandwidth_hz, fdem_min);
2268
2269 /* Find Min and Max prediv */
2270 while ((xtal/max_prediv) >= fcp_min)
2271 max_prediv++;
2272
2273 max_prediv--;
2274 min_prediv = max_prediv;
2275 while ((xtal/min_prediv) <= fcp_max) {
2276 min_prediv--;
2277 if (min_prediv == 1)
2278 break;
2279 }
2280 deb_info("MIN prediv = %d : MAX prediv = %d", min_prediv, max_prediv);
2281
2282 min_prediv = 2;
2283
2284 for (prediv = min_prediv ; prediv < max_prediv; prediv++) {
2285 fcp = xtal / prediv;
2286 if (fcp > fcp_min && fcp < fcp_max) {
2287 for (loopdiv = 1 ; loopdiv < 64 ; loopdiv++) {
2288 fdem = ((xtal/prediv) * loopdiv);
2289 fs = fdem / 4;
2290 /* test min/max system restrictions */
2291
2292 if ((fdem >= fdem_min) && (fdem <= fdem_max) && (fs >= fe->dtv_property_cache.bandwidth_hz/1000)) {
2293 spur = 0;
2294 /* test fs harmonics positions */
2295 for (harmonic_id = (fe->dtv_property_cache.frequency / (1000*fs)) ; harmonic_id <= ((fe->dtv_property_cache.frequency / (1000*fs))+1) ; harmonic_id++) {
2296 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)))) {
2297 spur = 1;
2298 break;
2299 }
2300 }
2301
2302 if (!spur) {
2303 adc->pll_loopdiv = loopdiv;
2304 adc->pll_prediv = prediv;
2305 adc->timf = 2396745143UL/fdem*(1 << 9);
2306 adc->timf += ((2396745143UL%fdem) << 9)/fdem;
2307 deb_info("loopdiv=%i prediv=%i timf=%i", loopdiv, prediv, adc->timf);
2308 break;
2309 }
2310 }
2311 }
2312 }
2313 if (!spur)
2314 break;
2315 }
2316
2317
2318 if (adc->pll_loopdiv == 0 && adc->pll_prediv == 0)
2319 return -EINVAL;
2320 else
2321 return 0;
2322}
2323
2324static int dib7090_agc_startup(struct dvb_frontend *fe)
2325{
2326 struct dvb_usb_adapter *adap = fe->dvb->priv;
2327 struct dib0700_adapter_state *state = adap->priv;
2328 struct dibx000_bandwidth_config pll;
2329 u16 target;
2330 struct dib7090p_best_adc adc;
2331 int ret;
2332
2333 ret = state->set_param_save(fe);
2334 if (ret < 0)
2335 return ret;
2336
2337 memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
2338 dib0090_pwm_gain_reset(fe);
2339 target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2;
2340 dib7000p_set_wbd_ref(fe, target);
2341
2342 if (dib7090p_get_best_sampling(fe, &adc) == 0) {
2343 pll.pll_ratio = adc.pll_loopdiv;
2344 pll.pll_prediv = adc.pll_prediv;
2345
2346 dib7000p_update_pll(fe, &pll);
2347 dib7000p_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf);
2348 }
2349 return 0;
2350}
2351
2352static int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
2353{
2354 deb_info("AGC restart callback: %d", restart);
2355 if (restart == 0) /* before AGC startup */
2356 dib0090_set_dc_servo(fe, 1);
2357 return 0;
2358}
2359
2360static int dib7090e_update_lna(struct dvb_frontend *fe, u16 agc_global)
2361{
2362 u16 agc1 = 0, agc2, wbd = 0, wbd_target, wbd_offset, threshold_agc1;
2363 s16 wbd_delta;
2364
2365 if ((fe->dtv_property_cache.frequency) < 400000000)
2366 threshold_agc1 = 25000;
2367 else
2368 threshold_agc1 = 30000;
2369
2370 wbd_target = (dib0090_get_wbd_target(fe)*8+1)/2;
2371 wbd_offset = dib0090_get_wbd_offset(fe);
2372 dib7000p_get_agc_values(fe, NULL, &agc1, &agc2, &wbd);
2373 wbd_delta = (s16)wbd - (((s16)wbd_offset+10)*4) ;
2374
2375 deb_info("update lna, agc_global=%d agc1=%d agc2=%d",
2376 agc_global, agc1, agc2);
2377 deb_info("update lna, wbd=%d wbd target=%d wbd offset=%d wbd delta=%d",
2378 wbd, wbd_target, wbd_offset, wbd_delta);
2379
2380 if ((agc1 < threshold_agc1) && (wbd_delta > 0)) {
2381 dib0090_set_switch(fe, 1, 1, 1);
2382 dib0090_set_vga(fe, 0);
2383 dib0090_update_rframp_7090(fe, 0);
2384 dib0090_update_tuning_table_7090(fe, 0);
2385 } else {
2386 dib0090_set_vga(fe, 1);
2387 dib0090_update_rframp_7090(fe, 1);
2388 dib0090_update_tuning_table_7090(fe, 1);
2389 dib0090_set_switch(fe, 0, 0, 0);
2390 }
2391
2392 return 0;
2393}
2394
2395static struct dib0090_wbd_slope dib7090_wbd_table[] = {
2396 { 380, 81, 850, 64, 540, 4},
2397 { 860, 51, 866, 21, 375, 4},
2398 {1700, 0, 250, 0, 100, 6},
2399 {2600, 0, 250, 0, 100, 6},
2400 { 0xFFFF, 0, 0, 0, 0, 0},
2401};
2402
2403static struct dib0090_wbd_slope dib7090e_wbd_table[] = {
2404 { 380, 81, 850, 64, 540, 4},
2405 { 700, 51, 866, 21, 320, 4},
2406 { 860, 48, 666, 18, 330, 6},
2407 {1700, 0, 250, 0, 100, 6},
2408 {2600, 0, 250, 0, 100, 6},
2409 { 0xFFFF, 0, 0, 0, 0, 0},
2410};
2411
2412static struct dibx000_agc_config dib7090_agc_config[2] = {
2413 {
2414 .band_caps = BAND_UHF,
2415 /* 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,
2416 * 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 */
2417 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
2418
2419 .inv_gain = 687,
2420 .time_stabiliz = 10,
2421
2422 .alpha_level = 0,
2423 .thlock = 118,
2424
2425 .wbd_inv = 0,
2426 .wbd_ref = 1200,
2427 .wbd_sel = 3,
2428 .wbd_alpha = 5,
2429
2430 .agc1_max = 65535,
2431 .agc1_min = 0,
2432
2433 .agc2_max = 65535,
2434 .agc2_min = 0,
2435
2436 .agc1_pt1 = 0,
2437 .agc1_pt2 = 32,
2438 .agc1_pt3 = 114,
2439 .agc1_slope1 = 143,
2440 .agc1_slope2 = 144,
2441 .agc2_pt1 = 114,
2442 .agc2_pt2 = 227,
2443 .agc2_slope1 = 116,
2444 .agc2_slope2 = 117,
2445
2446 .alpha_mant = 18,
2447 .alpha_exp = 0,
2448 .beta_mant = 20,
2449 .beta_exp = 59,
2450
2451 .perform_agc_softsplit = 0,
2452 } , {
2453 .band_caps = BAND_FM | BAND_VHF | BAND_CBAND,
2454 /* 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,
2455 * 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 */
2456 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
2457
2458 .inv_gain = 732,
2459 .time_stabiliz = 10,
2460
2461 .alpha_level = 0,
2462 .thlock = 118,
2463
2464 .wbd_inv = 0,
2465 .wbd_ref = 1200,
2466 .wbd_sel = 3,
2467 .wbd_alpha = 5,
2468
2469 .agc1_max = 65535,
2470 .agc1_min = 0,
2471
2472 .agc2_max = 65535,
2473 .agc2_min = 0,
2474
2475 .agc1_pt1 = 0,
2476 .agc1_pt2 = 0,
2477 .agc1_pt3 = 98,
2478 .agc1_slope1 = 0,
2479 .agc1_slope2 = 167,
2480 .agc2_pt1 = 98,
2481 .agc2_pt2 = 255,
2482 .agc2_slope1 = 104,
2483 .agc2_slope2 = 0,
2484
2485 .alpha_mant = 18,
2486 .alpha_exp = 0,
2487 .beta_mant = 20,
2488 .beta_exp = 59,
2489
2490 .perform_agc_softsplit = 0,
2491 }
2492};
2493
2494static struct dibx000_bandwidth_config dib7090_clock_config_12_mhz = {
2495 60000, 15000,
2496 1, 5, 0, 0, 0,
2497 0, 0, 1, 1, 2,
2498 (3 << 14) | (1 << 12) | (524 << 0),
2499 (0 << 25) | 0,
2500 20452225,
2501 15000000,
2502};
2503
2504static struct dib7000p_config nim7090_dib7000p_config = {
2505 .output_mpeg2_in_188_bytes = 1,
2506 .hostbus_diversity = 1,
2507 .tuner_is_baseband = 1,
2508 .update_lna = NULL,
2509
2510 .agc_config_count = 2,
2511 .agc = dib7090_agc_config,
2512
2513 .bw = &dib7090_clock_config_12_mhz,
2514
2515 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2516 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2517 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2518
2519 .pwm_freq_div = 0,
2520
2521 .agc_control = dib7090_agc_restart,
2522
2523 .spur_protect = 0,
2524 .disable_sample_and_hold = 0,
2525 .enable_current_mirror = 0,
2526 .diversity_delay = 0,
2527
2528 .output_mode = OUTMODE_MPEG2_FIFO,
2529 .enMpegOutput = 1,
2530};
2531
2532static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = {
2533 {
2534 .output_mpeg2_in_188_bytes = 1,
2535 .hostbus_diversity = 1,
2536 .tuner_is_baseband = 1,
2537 .update_lna = NULL,
2538
2539 .agc_config_count = 2,
2540 .agc = dib7090_agc_config,
2541
2542 .bw = &dib7090_clock_config_12_mhz,
2543
2544 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2545 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2546 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2547
2548 .pwm_freq_div = 0,
2549
2550 .agc_control = dib7090_agc_restart,
2551
2552 .spur_protect = 0,
2553 .disable_sample_and_hold = 0,
2554 .enable_current_mirror = 0,
2555 .diversity_delay = 0,
2556
2557 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
2558 .default_i2c_addr = 0x90,
2559 .enMpegOutput = 1,
2560 }, {
2561 .output_mpeg2_in_188_bytes = 1,
2562 .hostbus_diversity = 1,
2563 .tuner_is_baseband = 1,
2564 .update_lna = NULL,
2565
2566 .agc_config_count = 2,
2567 .agc = dib7090_agc_config,
2568
2569 .bw = &dib7090_clock_config_12_mhz,
2570
2571 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2572 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2573 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2574
2575 .pwm_freq_div = 0,
2576
2577 .agc_control = dib7090_agc_restart,
2578
2579 .spur_protect = 0,
2580 .disable_sample_and_hold = 0,
2581 .enable_current_mirror = 0,
2582 .diversity_delay = 0,
2583
2584 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
2585 .default_i2c_addr = 0x92,
2586 .enMpegOutput = 0,
2587 }
2588};
2589
2590static struct dib7000p_config tfe7090e_dib7000p_config = {
2591 .output_mpeg2_in_188_bytes = 1,
2592 .hostbus_diversity = 1,
2593 .tuner_is_baseband = 1,
2594 .update_lna = dib7090e_update_lna,
2595
2596 .agc_config_count = 2,
2597 .agc = dib7090_agc_config,
2598
2599 .bw = &dib7090_clock_config_12_mhz,
2600
2601 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2602 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2603 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2604
2605 .pwm_freq_div = 0,
2606
2607 .agc_control = dib7090_agc_restart,
2608
2609 .spur_protect = 0,
2610 .disable_sample_and_hold = 0,
2611 .enable_current_mirror = 0,
2612 .diversity_delay = 0,
2613
2614 .output_mode = OUTMODE_MPEG2_FIFO,
2615 .enMpegOutput = 1,
2616};
2617
2618static const struct dib0090_config nim7090_dib0090_config = {
2619 .io.clock_khz = 12000,
2620 .io.pll_bypass = 0,
2621 .io.pll_range = 0,
2622 .io.pll_prediv = 3,
2623 .io.pll_loopdiv = 6,
2624 .io.adc_clock_ratio = 0,
2625 .io.pll_int_loop_filt = 0,
2626 .reset = dib7090_tuner_sleep,
2627 .sleep = dib7090_tuner_sleep,
2628
2629 .freq_offset_khz_uhf = 0,
2630 .freq_offset_khz_vhf = 0,
2631
2632 .get_adc_power = dib7090_get_adc_power,
2633
2634 .clkouttobamse = 1,
2635 .analog_output = 0,
2636
2637 .wbd_vhf_offset = 0,
2638 .wbd_cband_offset = 0,
2639 .use_pwm_agc = 1,
2640 .clkoutdrive = 0,
2641
2642 .fref_clock_ratio = 0,
2643
2644 .wbd = dib7090_wbd_table,
2645
2646 .ls_cfg_pad_drv = 0,
2647 .data_tx_drv = 0,
2648 .low_if = NULL,
2649 .in_soc = 1,
2650};
2651
2652static const struct dib0090_config tfe7090e_dib0090_config = {
2653 .io.clock_khz = 12000,
2654 .io.pll_bypass = 0,
2655 .io.pll_range = 0,
2656 .io.pll_prediv = 3,
2657 .io.pll_loopdiv = 6,
2658 .io.adc_clock_ratio = 0,
2659 .io.pll_int_loop_filt = 0,
2660 .reset = dib7090_tuner_sleep,
2661 .sleep = dib7090_tuner_sleep,
2662
2663 .freq_offset_khz_uhf = 0,
2664 .freq_offset_khz_vhf = 0,
2665
2666 .get_adc_power = dib7090_get_adc_power,
2667
2668 .clkouttobamse = 1,
2669 .analog_output = 0,
2670
2671 .wbd_vhf_offset = 0,
2672 .wbd_cband_offset = 0,
2673 .use_pwm_agc = 1,
2674 .clkoutdrive = 0,
2675
2676 .fref_clock_ratio = 0,
2677
2678 .wbd = dib7090e_wbd_table,
2679
2680 .ls_cfg_pad_drv = 0,
2681 .data_tx_drv = 0,
2682 .low_if = NULL,
2683 .in_soc = 1,
2684 .force_cband_input = 1,
2685 .is_dib7090e = 1,
2686};
2687
2688static struct dib7000p_config tfe7790e_dib7000p_config = {
2689 .output_mpeg2_in_188_bytes = 1,
2690 .hostbus_diversity = 1,
2691 .tuner_is_baseband = 1,
2692 .update_lna = dib7090e_update_lna,
2693
2694 .agc_config_count = 2,
2695 .agc = dib7090_agc_config,
2696
2697 .bw = &dib7090_clock_config_12_mhz,
2698
2699 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2700 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2701 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2702
2703 .pwm_freq_div = 0,
2704
2705 .agc_control = dib7090_agc_restart,
2706
2707 .spur_protect = 0,
2708 .disable_sample_and_hold = 0,
2709 .enable_current_mirror = 0,
2710 .diversity_delay = 0,
2711
2712 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
2713 .enMpegOutput = 1,
2714};
2715
2716static const struct dib0090_config tfe7790e_dib0090_config = {
2717 .io.clock_khz = 12000,
2718 .io.pll_bypass = 0,
2719 .io.pll_range = 0,
2720 .io.pll_prediv = 3,
2721 .io.pll_loopdiv = 6,
2722 .io.adc_clock_ratio = 0,
2723 .io.pll_int_loop_filt = 0,
2724 .reset = dib7090_tuner_sleep,
2725 .sleep = dib7090_tuner_sleep,
2726
2727 .freq_offset_khz_uhf = 0,
2728 .freq_offset_khz_vhf = 0,
2729
2730 .get_adc_power = dib7090_get_adc_power,
2731
2732 .clkouttobamse = 1,
2733 .analog_output = 0,
2734
2735 .wbd_vhf_offset = 0,
2736 .wbd_cband_offset = 0,
2737 .use_pwm_agc = 1,
2738 .clkoutdrive = 0,
2739
2740 .fref_clock_ratio = 0,
2741
2742 .wbd = dib7090e_wbd_table,
2743
2744 .ls_cfg_pad_drv = 0,
2745 .data_tx_drv = 0,
2746 .low_if = NULL,
2747 .in_soc = 1,
2748 .force_cband_input = 1,
2749 .is_dib7090e = 1,
2750 .force_crystal_mode = 1,
2751};
2752
2753static const struct dib0090_config tfe7090pvr_dib0090_config[2] = {
2754 {
2755 .io.clock_khz = 12000,
2756 .io.pll_bypass = 0,
2757 .io.pll_range = 0,
2758 .io.pll_prediv = 3,
2759 .io.pll_loopdiv = 6,
2760 .io.adc_clock_ratio = 0,
2761 .io.pll_int_loop_filt = 0,
2762 .reset = dib7090_tuner_sleep,
2763 .sleep = dib7090_tuner_sleep,
2764
2765 .freq_offset_khz_uhf = 50,
2766 .freq_offset_khz_vhf = 70,
2767
2768 .get_adc_power = dib7090_get_adc_power,
2769
2770 .clkouttobamse = 1,
2771 .analog_output = 0,
2772
2773 .wbd_vhf_offset = 0,
2774 .wbd_cband_offset = 0,
2775 .use_pwm_agc = 1,
2776 .clkoutdrive = 0,
2777
2778 .fref_clock_ratio = 0,
2779
2780 .wbd = dib7090_wbd_table,
2781
2782 .ls_cfg_pad_drv = 0,
2783 .data_tx_drv = 0,
2784 .low_if = NULL,
2785 .in_soc = 1,
2786 }, {
2787 .io.clock_khz = 12000,
2788 .io.pll_bypass = 0,
2789 .io.pll_range = 0,
2790 .io.pll_prediv = 3,
2791 .io.pll_loopdiv = 6,
2792 .io.adc_clock_ratio = 0,
2793 .io.pll_int_loop_filt = 0,
2794 .reset = dib7090_tuner_sleep,
2795 .sleep = dib7090_tuner_sleep,
2796
2797 .freq_offset_khz_uhf = -50,
2798 .freq_offset_khz_vhf = -70,
2799
2800 .get_adc_power = dib7090_get_adc_power,
2801
2802 .clkouttobamse = 1,
2803 .analog_output = 0,
2804
2805 .wbd_vhf_offset = 0,
2806 .wbd_cband_offset = 0,
2807 .use_pwm_agc = 1,
2808 .clkoutdrive = 0,
2809
2810 .fref_clock_ratio = 0,
2811
2812 .wbd = dib7090_wbd_table,
2813
2814 .ls_cfg_pad_drv = 0,
2815 .data_tx_drv = 0,
2816 .low_if = NULL,
2817 .in_soc = 1,
2818 }
2819};
2820
2821static int nim7090_frontend_attach(struct dvb_usb_adapter *adap)
2822{
2823 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2824 msleep(20);
2825 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2826 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2827 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2828 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2829
2830 msleep(20);
2831 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2832 msleep(20);
2833 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2834
2835 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) {
2836 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2837 return -ENODEV;
2838 }
2839 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config);
2840
2841 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
2842}
2843
2844static int nim7090_tuner_attach(struct dvb_usb_adapter *adap)
2845{
2846 struct dib0700_adapter_state *st = adap->priv;
2847 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
2848
2849 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &nim7090_dib0090_config) == NULL)
2850 return -ENODEV;
2851
2852 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
2853
2854 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
2855 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2856 return 0;
2857}
2858
2859static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
2860{
2861 struct dib0700_state *st = adap->dev->priv;
2862
2863 /* The TFE7090 requires the dib0700 to not be in master mode */
2864 st->disable_streaming_master_mode = 1;
2865
2866 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2867 msleep(20);
2868 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2869 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2870 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2871 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2872
2873 msleep(20);
2874 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2875 msleep(20);
2876 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2877
2878 /* initialize IC 0 */
2879 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) {
2880 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2881 return -ENODEV;
2882 }
2883
2884 dib0700_set_i2c_speed(adap->dev, 340);
2885 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
2886 if (adap->fe_adap[0].fe == NULL)
2887 return -ENODEV;
2888
2889 dib7090_slave_reset(adap->fe_adap[0].fe);
2890
2891 return 0;
2892}
2893
2894static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap)
2895{
2896 struct i2c_adapter *i2c;
2897
2898 if (adap->dev->adapter[0].fe_adap[0].fe == NULL) {
2899 err("the master dib7090 has to be initialized first");
2900 return -ENODEV; /* the master device has not been initialized */
2901 }
2902
2903 i2c = dib7000p_get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1);
2904 if (dib7000p_i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) {
2905 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2906 return -ENODEV;
2907 }
2908
2909 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]);
2910 dib0700_set_i2c_speed(adap->dev, 200);
2911
2912 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
2913}
2914
2915static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap)
2916{
2917 struct dib0700_adapter_state *st = adap->priv;
2918 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
2919
2920 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL)
2921 return -ENODEV;
2922
2923 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
2924
2925 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
2926 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2927 return 0;
2928}
2929
2930static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap)
2931{
2932 struct dib0700_adapter_state *st = adap->priv;
2933 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
2934
2935 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL)
2936 return -ENODEV;
2937
2938 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
2939
2940 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
2941 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2942 return 0;
2943}
2944
2945static int tfe7090e_frontend_attach(struct dvb_usb_adapter *adap)
2946{
2947 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2948 msleep(20);
2949 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2950 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2951 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2952 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2953
2954 msleep(20);
2955 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2956 msleep(20);
2957 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2958
2959 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap,
2960 1, 0x10, &tfe7090e_dib7000p_config) != 0) {
2961 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
2962 __func__);
2963 return -ENODEV;
2964 }
2965 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
2966 0x80, &tfe7090e_dib7000p_config);
2967
2968 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
2969}
2970
2971static int tfe7790e_frontend_attach(struct dvb_usb_adapter *adap)
2972{
2973 struct dib0700_state *st = adap->dev->priv;
2974
2975 /* The TFE7790E requires the dib0700 to not be in master mode */
2976 st->disable_streaming_master_mode = 1;
2977
2978 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2979 msleep(20);
2980 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2981 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2982 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2983 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2984 msleep(20);
2985 dib0700_ctrl_clock(adap->dev, 72, 1);
2986 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2987 msleep(20);
2988 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2989
2990 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap,
2991 1, 0x10, &tfe7790e_dib7000p_config) != 0) {
2992 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
2993 __func__);
2994 return -ENODEV;
2995 }
2996 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
2997 0x80, &tfe7790e_dib7000p_config);
2998
2999 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
3000}
3001
3002static int tfe7790e_tuner_attach(struct dvb_usb_adapter *adap)
3003{
3004 struct dib0700_adapter_state *st = adap->priv;
3005 struct i2c_adapter *tun_i2c =
3006 dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
3007
3008 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
3009 &tfe7790e_dib0090_config) == NULL)
3010 return -ENODEV;
3011
3012 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
3013
3014 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
3015 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
3016 return 0;
3017}
3018
3019static int tfe7090e_tuner_attach(struct dvb_usb_adapter *adap)
3020{
3021 struct dib0700_adapter_state *st = adap->priv;
3022 struct i2c_adapter *tun_i2c =
3023 dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
3024
3025 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
3026 &tfe7090e_dib0090_config) == NULL)
3027 return -ENODEV;
3028
3029 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
3030
3031 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
3032 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
3033 return 0;
3034}
3035
3036/* STK7070PD */
3037static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
3038 {
3039 .output_mpeg2_in_188_bytes = 1,
3040
3041 .agc_config_count = 1,
3042 .agc = &dib7070_agc_config,
3043 .bw = &dib7070_bw_config_12_mhz,
3044 .tuner_is_baseband = 1,
3045 .spur_protect = 1,
3046
3047 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
3048 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
3049 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
3050
3051 .hostbus_diversity = 1,
3052 }, {
3053 .output_mpeg2_in_188_bytes = 1,
3054
3055 .agc_config_count = 1,
3056 .agc = &dib7070_agc_config,
3057 .bw = &dib7070_bw_config_12_mhz,
3058 .tuner_is_baseband = 1,
3059 .spur_protect = 1,
3060
3061 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
3062 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
3063 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
3064
3065 .hostbus_diversity = 1,
3066 }
3067};
3068
3069static void stk7070pd_init(struct dvb_usb_device *dev)
3070{
3071 dib0700_set_gpio(dev, GPIO6, GPIO_OUT, 1);
3072 msleep(10);
3073 dib0700_set_gpio(dev, GPIO9, GPIO_OUT, 1);
3074 dib0700_set_gpio(dev, GPIO4, GPIO_OUT, 1);
3075 dib0700_set_gpio(dev, GPIO7, GPIO_OUT, 1);
3076 dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 0);
3077
3078 dib0700_ctrl_clock(dev, 72, 1);
3079
3080 msleep(10);
3081 dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 1);
3082}
3083
3084static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
3085{
3086 stk7070pd_init(adap->dev);
3087
3088 msleep(10);
3089 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
3090
3091 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
3092 stk7070pd_dib7000p_config) != 0) {
3093 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
3094 __func__);
3095 return -ENODEV;
3096 }
3097
3098 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
3099 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
3100}
3101
3102static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
3103{
3104 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]);
3105 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
3106}
3107
3108static int novatd_read_status_override(struct dvb_frontend *fe,
3109 fe_status_t *stat)
3110{
3111 struct dvb_usb_adapter *adap = fe->dvb->priv;
3112 struct dvb_usb_device *dev = adap->dev;
3113 struct dib0700_state *state = dev->priv;
3114 int ret;
3115
3116 ret = state->read_status(fe, stat);
3117
3118 if (!ret)
3119 dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT,
3120 !!(*stat & FE_HAS_LOCK));
3121
3122 return ret;
3123}
3124
3125static int novatd_sleep_override(struct dvb_frontend* fe)
3126{
3127 struct dvb_usb_adapter *adap = fe->dvb->priv;
3128 struct dvb_usb_device *dev = adap->dev;
3129 struct dib0700_state *state = dev->priv;
3130
3131 /* turn off LED */
3132 dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT, 0);
3133
3134 return state->sleep(fe);
3135}
3136
3137/**
3138 * novatd_frontend_attach - Nova-TD specific attach
3139 *
3140 * Nova-TD has GPIO0, 1 and 2 for LEDs. So do not fiddle with them except for
3141 * information purposes.
3142 */
3143static int novatd_frontend_attach(struct dvb_usb_adapter *adap)
3144{
3145 struct dvb_usb_device *dev = adap->dev;
3146 struct dib0700_state *st = dev->priv;
3147
3148 if (adap->id == 0) {
3149 stk7070pd_init(dev);
3150
3151 /* turn the power LED on, the other two off (just in case) */
3152 dib0700_set_gpio(dev, GPIO0, GPIO_OUT, 0);
3153 dib0700_set_gpio(dev, GPIO1, GPIO_OUT, 0);
3154 dib0700_set_gpio(dev, GPIO2, GPIO_OUT, 1);
3155
3156 if (dib7000p_i2c_enumeration(&dev->i2c_adap, 2, 18,
3157 stk7070pd_dib7000p_config) != 0) {
3158 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
3159 __func__);
3160 return -ENODEV;
3161 }
3162 }
3163
3164 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &dev->i2c_adap,
3165 adap->id == 0 ? 0x80 : 0x82,
3166 &stk7070pd_dib7000p_config[adap->id]);
3167
3168 if (adap->fe_adap[0].fe == NULL)
3169 return -ENODEV;
3170
3171 st->read_status = adap->fe_adap[0].fe->ops.read_status;
3172 adap->fe_adap[0].fe->ops.read_status = novatd_read_status_override;
3173 st->sleep = adap->fe_adap[0].fe->ops.sleep;
3174 adap->fe_adap[0].fe->ops.sleep = novatd_sleep_override;
3175
3176 return 0;
3177}
3178
3179/* S5H1411 */
3180static struct s5h1411_config pinnacle_801e_config = {
3181 .output_mode = S5H1411_PARALLEL_OUTPUT,
3182 .gpio = S5H1411_GPIO_OFF,
3183 .mpeg_timing = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
3184 .qam_if = S5H1411_IF_44000,
3185 .vsb_if = S5H1411_IF_44000,
3186 .inversion = S5H1411_INVERSION_OFF,
3187 .status_mode = S5H1411_DEMODLOCKING
3188};
3189
3190/* Pinnacle PCTV HD Pro 801e GPIOs map:
3191 GPIO0 - currently unknown
3192 GPIO1 - xc5000 tuner reset
3193 GPIO2 - CX25843 sleep
3194 GPIO3 - currently unknown
3195 GPIO4 - currently unknown
3196 GPIO6 - currently unknown
3197 GPIO7 - currently unknown
3198 GPIO9 - currently unknown
3199 GPIO10 - CX25843 reset
3200 */
3201static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap)
3202{
3203 struct dib0700_state *st = adap->dev->priv;
3204
3205 /* Make use of the new i2c functions from FW 1.20 */
3206 st->fw_use_new_i2c_api = 1;
3207
3208 /* The s5h1411 requires the dib0700 to not be in master mode */
3209 st->disable_streaming_master_mode = 1;
3210
3211 /* All msleep values taken from Windows USB trace */
3212 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
3213 dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0);
3214 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
3215 msleep(400);
3216 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
3217 msleep(60);
3218 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
3219 msleep(30);
3220 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
3221 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
3222 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
3223 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
3224 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 0);
3225 msleep(30);
3226
3227 /* Put the CX25843 to sleep for now since we're in digital mode */
3228 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
3229
3230 /* GPIOs are initialized, do the attach */
3231 adap->fe_adap[0].fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config,
3232 &adap->dev->i2c_adap);
3233 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
3234}
3235
3236static int dib0700_xc5000_tuner_callback(void *priv, int component,
3237 int command, int arg)
3238{
3239 struct dvb_usb_adapter *adap = priv;
3240
3241 if (command == XC5000_TUNER_RESET) {
3242 /* Reset the tuner */
3243 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
3244 msleep(10);
3245 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
3246 msleep(10);
3247 } else {
3248 err("xc5000: unknown tuner callback command: %d\n", command);
3249 return -EINVAL;
3250 }
3251
3252 return 0;
3253}
3254
3255static struct xc5000_config s5h1411_xc5000_tunerconfig = {
3256 .i2c_address = 0x64,
3257 .if_khz = 5380,
3258};
3259
3260static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
3261{
3262 /* FIXME: generalize & move to common area */
3263 adap->fe_adap[0].fe->callback = dib0700_xc5000_tuner_callback;
3264
3265 return dvb_attach(xc5000_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap,
3266 &s5h1411_xc5000_tunerconfig)
3267 == NULL ? -ENODEV : 0;
3268}
3269
3270static int dib0700_xc4000_tuner_callback(void *priv, int component,
3271 int command, int arg)
3272{
3273 struct dvb_usb_adapter *adap = priv;
3274
3275 if (command == XC4000_TUNER_RESET) {
3276 /* Reset the tuner */
3277 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0);
3278 msleep(10);
3279 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
3280 } else {
3281 err("xc4000: unknown tuner callback command: %d\n", command);
3282 return -EINVAL;
3283 }
3284
3285 return 0;
3286}
3287
3288static struct dibx000_agc_config stk7700p_7000p_xc4000_agc_config = {
3289 .band_caps = BAND_UHF | BAND_VHF,
3290 .setup = 0x64,
3291 .inv_gain = 0x02c8,
3292 .time_stabiliz = 0x15,
3293 .alpha_level = 0x00,
3294 .thlock = 0x76,
3295 .wbd_inv = 0x01,
3296 .wbd_ref = 0x0b33,
3297 .wbd_sel = 0x00,
3298 .wbd_alpha = 0x02,
3299 .agc1_max = 0x00,
3300 .agc1_min = 0x00,
3301 .agc2_max = 0x9b26,
3302 .agc2_min = 0x26ca,
3303 .agc1_pt1 = 0x00,
3304 .agc1_pt2 = 0x00,
3305 .agc1_pt3 = 0x00,
3306 .agc1_slope1 = 0x00,
3307 .agc1_slope2 = 0x00,
3308 .agc2_pt1 = 0x00,
3309 .agc2_pt2 = 0x80,
3310 .agc2_slope1 = 0x1d,
3311 .agc2_slope2 = 0x1d,
3312 .alpha_mant = 0x11,
3313 .alpha_exp = 0x1b,
3314 .beta_mant = 0x17,
3315 .beta_exp = 0x33,
3316 .perform_agc_softsplit = 0x00,
3317};
3318
3319static struct dibx000_bandwidth_config stk7700p_xc4000_pll_config = {
3320 60000, 30000, /* internal, sampling */
3321 1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
3322 0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, */
3323 /* ADClkSrc, modulo */
3324 (3 << 14) | (1 << 12) | 524, /* sad_cfg: refsel, sel, freq_15k */
3325 39370534, /* ifreq */
3326 20452225, /* timf */
3327 30000000 /* xtal */
3328};
3329
3330/* FIXME: none of these inputs are validated yet */
3331static struct dib7000p_config pctv_340e_config = {
3332 .output_mpeg2_in_188_bytes = 1,
3333
3334 .agc_config_count = 1,
3335 .agc = &stk7700p_7000p_xc4000_agc_config,
3336 .bw = &stk7700p_xc4000_pll_config,
3337
3338 .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
3339 .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
3340 .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
3341};
3342
3343/* PCTV 340e GPIOs map:
3344 dib0700:
3345 GPIO2 - CX25843 sleep
3346 GPIO3 - CS5340 reset
3347 GPIO5 - IRD
3348 GPIO6 - Power Supply
3349 GPIO8 - LNA (1=off 0=on)
3350 GPIO10 - CX25843 reset
3351 dib7000:
3352 GPIO8 - xc4000 reset
3353 */
3354static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap)
3355{
3356 struct dib0700_state *st = adap->dev->priv;
3357
3358 /* Power Supply on */
3359 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
3360 msleep(50);
3361 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
3362 msleep(100); /* Allow power supply to settle before probing */
3363
3364 /* cx25843 reset */
3365 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
3366 msleep(1); /* cx25843 datasheet say 350us required */
3367 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
3368
3369 /* LNA off for now */
3370 dib0700_set_gpio(adap->dev, GPIO8, GPIO_OUT, 1);
3371
3372 /* Put the CX25843 to sleep for now since we're in digital mode */
3373 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
3374
3375 /* FIXME: not verified yet */
3376 dib0700_ctrl_clock(adap->dev, 72, 1);
3377
3378 msleep(500);
3379
3380 if (dib7000pc_detection(&adap->dev->i2c_adap) == 0) {
3381 /* Demodulator not found for some reason? */
3382 return -ENODEV;
3383 }
3384
3385 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x12,
3386 &pctv_340e_config);
3387 st->is_dib7000pc = 1;
3388
3389 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
3390}
3391
3392static struct xc4000_config dib7000p_xc4000_tunerconfig = {
3393 .i2c_address = 0x61,
3394 .default_pm = 1,
3395 .dvb_amplitude = 0,
3396 .set_smoothedcvbs = 0,
3397 .if_khz = 5400
3398};
3399
3400static int xc4000_tuner_attach(struct dvb_usb_adapter *adap)
3401{
3402 struct i2c_adapter *tun_i2c;
3403
3404 /* The xc4000 is not on the main i2c bus */
3405 tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
3406 DIBX000_I2C_INTERFACE_TUNER, 1);
3407 if (tun_i2c == NULL) {
3408 printk(KERN_ERR "Could not reach tuner i2c bus\n");
3409 return 0;
3410 }
3411
3412 /* Setup the reset callback */
3413 adap->fe_adap[0].fe->callback = dib0700_xc4000_tuner_callback;
3414
3415 return dvb_attach(xc4000_attach, adap->fe_adap[0].fe, tun_i2c,
3416 &dib7000p_xc4000_tunerconfig)
3417 == NULL ? -ENODEV : 0;
3418}
3419
3420static struct lgdt3305_config hcw_lgdt3305_config = {
3421 .i2c_addr = 0x0e,
3422 .mpeg_mode = LGDT3305_MPEG_PARALLEL,
3423 .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
3424 .tpvalid_polarity = LGDT3305_TP_VALID_LOW,
3425 .deny_i2c_rptr = 0,
3426 .spectral_inversion = 1,
3427 .qam_if_khz = 6000,
3428 .vsb_if_khz = 6000,
3429 .usref_8vsb = 0x0500,
3430};
3431
3432static struct mxl5007t_config hcw_mxl5007t_config = {
3433 .xtal_freq_hz = MxL_XTAL_25_MHZ,
3434 .if_freq_hz = MxL_IF_6_MHZ,
3435 .invert_if = 1,
3436};
3437
3438/* TIGER-ATSC map:
3439 GPIO0 - LNA_CTR (H: LNA power enabled, L: LNA power disabled)
3440 GPIO1 - ANT_SEL (H: VPA, L: MCX)
3441 GPIO4 - SCL2
3442 GPIO6 - EN_TUNER
3443 GPIO7 - SDA2
3444 GPIO10 - DEM_RST
3445
3446 MXL is behind LG's i2c repeater. LG is on SCL2/SDA2 gpios on the DIB
3447 */
3448static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
3449{
3450 struct dib0700_state *st = adap->dev->priv;
3451
3452 /* Make use of the new i2c functions from FW 1.20 */
3453 st->fw_use_new_i2c_api = 1;
3454
3455 st->disable_streaming_master_mode = 1;
3456
3457 /* fe power enable */
3458 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
3459 msleep(30);
3460 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
3461 msleep(30);
3462
3463 /* demod reset */
3464 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
3465 msleep(30);
3466 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
3467 msleep(30);
3468 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
3469 msleep(30);
3470
3471 adap->fe_adap[0].fe = dvb_attach(lgdt3305_attach,
3472 &hcw_lgdt3305_config,
3473 &adap->dev->i2c_adap);
3474
3475 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
3476}
3477
3478static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
3479{
3480 return dvb_attach(mxl5007t_attach, adap->fe_adap[0].fe,
3481 &adap->dev->i2c_adap, 0x60,
3482 &hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
3483}
3484
3485
3486/* DVB-USB and USB stuff follows */
3487struct usb_device_id dib0700_usb_id_table[] = {
3488/* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) },
3489 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P_PC) },
3490 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
3491 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
3492 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
3493/* 5 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
3494 { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500) },
3495 { USB_DEVICE(USB_VID_UNIWILL, USB_PID_UNIWILL_STK7700P) },
3496 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
3497 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
3498/* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
3499 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV2000E) },
3500 { USB_DEVICE(USB_VID_TERRATEC,
3501 USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
3502 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
3503 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700D) },
3504/* 15 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070P) },
3505 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
3506 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070PD) },
3507 { USB_DEVICE(USB_VID_PINNACLE,
3508 USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
3509 { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500_PC) },
3510/* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
3511 { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) },
3512 { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
3513 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) },
3514 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) },
3515/* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
3516 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
3517 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_USB_XE) },
3518 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_EXPRESSCARD_320CX) },
3519 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV72E) },
3520/* 30 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73E) },
3521 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_EC372S) },
3522 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
3523 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) },
3524 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
3525/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
3526 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
3527 { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U8000) },
3528 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700PH) },
3529 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) },
3530/* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) },
3531 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) },
3532 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
3533 { USB_DEVICE(USB_VID_TERRATEC,
3534 USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
3535 { USB_DEVICE(USB_VID_SONY, USB_PID_SONY_PLAYTV) },
3536/* 45 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_PD378S) },
3537 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) },
3538 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
3539 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) },
3540 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) },
3541/* 50 */{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_Dlx) },
3542 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_H) },
3543 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T3) },
3544 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T5) },
3545 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) },
3546/* 55 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) },
3547 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73A) },
3548 { USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV73ESE) },
3549 { USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV282E) },
3550 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7770P) },
3551/* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
3552 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) },
3553 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) },
3554 { USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x000, 0x3f00) },
3555 { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
3556/* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
3557 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
3558 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) },
3559 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DIVERSITY) },
3560 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090M) },
3561/* 70 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM8096MD) },
3562 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090MD) },
3563 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM7090) },
3564 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) },
3565 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) },
3566/* 75 */{ USB_DEVICE(USB_VID_MEDION, USB_PID_CREATIX_CTX1921) },
3567 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E) },
3568 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E_SE) },
3569 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090E) },
3570 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7790E) },
3571/* 80 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE8096P) },
3572 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_2) },
3573 { 0 } /* Terminating entry */
3574};
3575MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
3576
3577#define DIB0700_DEFAULT_DEVICE_PROPERTIES \
3578 .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
3579 .usb_ctrl = DEVICE_SPECIFIC, \
3580 .firmware = "dvb-usb-dib0700-1.20.fw", \
3581 .download_firmware = dib0700_download_firmware, \
3582 .no_reconnect = 1, \
3583 .size_of_priv = sizeof(struct dib0700_state), \
3584 .i2c_algo = &dib0700_i2c_algo, \
3585 .identify_state = dib0700_identify_state
3586
3587#define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
3588 .streaming_ctrl = dib0700_streaming_ctrl, \
3589 .stream = { \
3590 .type = USB_BULK, \
3591 .count = 4, \
3592 .endpoint = ep, \
3593 .u = { \
3594 .bulk = { \
3595 .buffersize = 39480, \
3596 } \
3597 } \
3598 }
3599
3600struct dvb_usb_device_properties dib0700_devices[] = {
3601 {
3602 DIB0700_DEFAULT_DEVICE_PROPERTIES,
3603
3604 .num_adapters = 1,
3605 .adapter = {
3606 {
3607 .num_frontends = 1,
3608 .fe = {{
3609 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3610 .pid_filter_count = 32,
3611 .pid_filter = stk7700p_pid_filter,
3612 .pid_filter_ctrl = stk7700p_pid_filter_ctrl,
3613 .frontend_attach = stk7700p_frontend_attach,
3614 .tuner_attach = stk7700p_tuner_attach,
3615
3616 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3617 }},
3618 },
3619 },
3620
3621 .num_device_descs = 8,
3622 .devices = {
3623 { "DiBcom STK7700P reference design",
3624 { &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
3625 { NULL },
3626 },
3627 { "Hauppauge Nova-T Stick",
3628 { &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL },
3629 { NULL },
3630 },
3631 { "AVerMedia AVerTV DVB-T Volar",
3632 { &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] },
3633 { NULL },
3634 },
3635 { "Compro Videomate U500",
3636 { &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] },
3637 { NULL },
3638 },
3639 { "Uniwill STK7700P based (Hama and others)",
3640 { &dib0700_usb_id_table[7], NULL },
3641 { NULL },
3642 },
3643 { "Leadtek Winfast DTV Dongle (STK7700P based)",
3644 { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
3645 { NULL },
3646 },
3647 { "AVerMedia AVerTV DVB-T Express",
3648 { &dib0700_usb_id_table[20] },
3649 { NULL },
3650 },
3651 { "Gigabyte U7000",
3652 { &dib0700_usb_id_table[21], NULL },
3653 { NULL },
3654 }
3655 },
3656
3657 .rc.core = {
3658 .rc_interval = DEFAULT_RC_INTERVAL,
3659 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3660 .rc_query = dib0700_rc_query_old_firmware,
3661 .allowed_protos = RC_TYPE_RC5 |
3662 RC_TYPE_RC6 |
3663 RC_TYPE_NEC,
3664 .change_protocol = dib0700_change_protocol,
3665 },
3666 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3667
3668 .num_adapters = 2,
3669 .adapter = {
3670 {
3671 .num_frontends = 1,
3672 .fe = {{
3673 .frontend_attach = bristol_frontend_attach,
3674 .tuner_attach = bristol_tuner_attach,
3675
3676 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3677 }},
3678 }, {
3679 .num_frontends = 1,
3680 .fe = {{
3681 .frontend_attach = bristol_frontend_attach,
3682 .tuner_attach = bristol_tuner_attach,
3683
3684 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
3685 }},
3686 }
3687 },
3688
3689 .num_device_descs = 1,
3690 .devices = {
3691 { "Hauppauge Nova-T 500 Dual DVB-T",
3692 { &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL },
3693 { NULL },
3694 },
3695 },
3696
3697 .rc.core = {
3698 .rc_interval = DEFAULT_RC_INTERVAL,
3699 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3700 .rc_query = dib0700_rc_query_old_firmware,
3701 .allowed_protos = RC_TYPE_RC5 |
3702 RC_TYPE_RC6 |
3703 RC_TYPE_NEC,
3704 .change_protocol = dib0700_change_protocol,
3705 },
3706 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3707
3708 .num_adapters = 2,
3709 .adapter = {
3710 {
3711 .num_frontends = 1,
3712 .fe = {{
3713 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3714 .pid_filter_count = 32,
3715 .pid_filter = stk70x0p_pid_filter,
3716 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3717 .frontend_attach = stk7700d_frontend_attach,
3718 .tuner_attach = stk7700d_tuner_attach,
3719
3720 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3721 }},
3722 }, {
3723 .num_frontends = 1,
3724 .fe = {{
3725 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3726 .pid_filter_count = 32,
3727 .pid_filter = stk70x0p_pid_filter,
3728 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3729 .frontend_attach = stk7700d_frontend_attach,
3730 .tuner_attach = stk7700d_tuner_attach,
3731
3732 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
3733 }},
3734 }
3735 },
3736
3737 .num_device_descs = 5,
3738 .devices = {
3739 { "Pinnacle PCTV 2000e",
3740 { &dib0700_usb_id_table[11], NULL },
3741 { NULL },
3742 },
3743 { "Terratec Cinergy DT XS Diversity",
3744 { &dib0700_usb_id_table[12], NULL },
3745 { NULL },
3746 },
3747 { "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity",
3748 { &dib0700_usb_id_table[13], NULL },
3749 { NULL },
3750 },
3751 { "DiBcom STK7700D reference design",
3752 { &dib0700_usb_id_table[14], NULL },
3753 { NULL },
3754 },
3755 { "YUAN High-Tech DiBcom STK7700D",
3756 { &dib0700_usb_id_table[55], NULL },
3757 { NULL },
3758 },
3759
3760 },
3761
3762 .rc.core = {
3763 .rc_interval = DEFAULT_RC_INTERVAL,
3764 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3765 .rc_query = dib0700_rc_query_old_firmware,
3766 .allowed_protos = RC_TYPE_RC5 |
3767 RC_TYPE_RC6 |
3768 RC_TYPE_NEC,
3769 .change_protocol = dib0700_change_protocol,
3770 },
3771 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3772
3773 .num_adapters = 1,
3774 .adapter = {
3775 {
3776 .num_frontends = 1,
3777 .fe = {{
3778 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3779 .pid_filter_count = 32,
3780 .pid_filter = stk70x0p_pid_filter,
3781 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3782 .frontend_attach = stk7700P2_frontend_attach,
3783 .tuner_attach = stk7700d_tuner_attach,
3784
3785 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3786 }},
3787 },
3788 },
3789
3790 .num_device_descs = 3,
3791 .devices = {
3792 { "ASUS My Cinema U3000 Mini DVBT Tuner",
3793 { &dib0700_usb_id_table[23], NULL },
3794 { NULL },
3795 },
3796 { "Yuan EC372S",
3797 { &dib0700_usb_id_table[31], NULL },
3798 { NULL },
3799 },
3800 { "Terratec Cinergy T Express",
3801 { &dib0700_usb_id_table[42], NULL },
3802 { NULL },
3803 }
3804 },
3805
3806 .rc.core = {
3807 .rc_interval = DEFAULT_RC_INTERVAL,
3808 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3809 .module_name = "dib0700",
3810 .rc_query = dib0700_rc_query_old_firmware,
3811 .allowed_protos = RC_TYPE_RC5 |
3812 RC_TYPE_RC6 |
3813 RC_TYPE_NEC,
3814 .change_protocol = dib0700_change_protocol,
3815 },
3816 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3817
3818 .num_adapters = 1,
3819 .adapter = {
3820 {
3821 .num_frontends = 1,
3822 .fe = {{
3823 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3824 .pid_filter_count = 32,
3825 .pid_filter = stk70x0p_pid_filter,
3826 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3827 .frontend_attach = stk7070p_frontend_attach,
3828 .tuner_attach = dib7070p_tuner_attach,
3829
3830 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3831 }},
3832 .size_of_priv = sizeof(struct dib0700_adapter_state),
3833 },
3834 },
3835
3836 .num_device_descs = 12,
3837 .devices = {
3838 { "DiBcom STK7070P reference design",
3839 { &dib0700_usb_id_table[15], NULL },
3840 { NULL },
3841 },
3842 { "Pinnacle PCTV DVB-T Flash Stick",
3843 { &dib0700_usb_id_table[16], NULL },
3844 { NULL },
3845 },
3846 { "Artec T14BR DVB-T",
3847 { &dib0700_usb_id_table[22], NULL },
3848 { NULL },
3849 },
3850 { "ASUS My Cinema U3100 Mini DVBT Tuner",
3851 { &dib0700_usb_id_table[24], NULL },
3852 { NULL },
3853 },
3854 { "Hauppauge Nova-T Stick",
3855 { &dib0700_usb_id_table[25], NULL },
3856 { NULL },
3857 },
3858 { "Hauppauge Nova-T MyTV.t",
3859 { &dib0700_usb_id_table[26], NULL },
3860 { NULL },
3861 },
3862 { "Pinnacle PCTV 72e",
3863 { &dib0700_usb_id_table[29], NULL },
3864 { NULL },
3865 },
3866 { "Pinnacle PCTV 73e",
3867 { &dib0700_usb_id_table[30], NULL },
3868 { NULL },
3869 },
3870 { "Elgato EyeTV DTT",
3871 { &dib0700_usb_id_table[49], NULL },
3872 { NULL },
3873 },
3874 { "Yuan PD378S",
3875 { &dib0700_usb_id_table[45], NULL },
3876 { NULL },
3877 },
3878 { "Elgato EyeTV Dtt Dlx PD378S",
3879 { &dib0700_usb_id_table[50], NULL },
3880 { NULL },
3881 },
3882 { "Elgato EyeTV DTT rev. 2",
3883 { &dib0700_usb_id_table[81], NULL },
3884 { NULL },
3885 },
3886 },
3887
3888 .rc.core = {
3889 .rc_interval = DEFAULT_RC_INTERVAL,
3890 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3891 .module_name = "dib0700",
3892 .rc_query = dib0700_rc_query_old_firmware,
3893 .allowed_protos = RC_TYPE_RC5 |
3894 RC_TYPE_RC6 |
3895 RC_TYPE_NEC,
3896 .change_protocol = dib0700_change_protocol,
3897 },
3898 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3899
3900 .num_adapters = 1,
3901 .adapter = {
3902 {
3903 .num_frontends = 1,
3904 .fe = {{
3905 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3906 .pid_filter_count = 32,
3907 .pid_filter = stk70x0p_pid_filter,
3908 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3909 .frontend_attach = stk7070p_frontend_attach,
3910 .tuner_attach = dib7070p_tuner_attach,
3911
3912 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3913 }},
3914 .size_of_priv = sizeof(struct dib0700_adapter_state),
3915 },
3916 },
3917
3918 .num_device_descs = 3,
3919 .devices = {
3920 { "Pinnacle PCTV 73A",
3921 { &dib0700_usb_id_table[56], NULL },
3922 { NULL },
3923 },
3924 { "Pinnacle PCTV 73e SE",
3925 { &dib0700_usb_id_table[57], &dib0700_usb_id_table[65], NULL },
3926 { NULL },
3927 },
3928 { "Pinnacle PCTV 282e",
3929 { &dib0700_usb_id_table[58], &dib0700_usb_id_table[66], NULL },
3930 { NULL },
3931 },
3932 },
3933
3934 .rc.core = {
3935 .rc_interval = DEFAULT_RC_INTERVAL,
3936 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3937 .module_name = "dib0700",
3938 .rc_query = dib0700_rc_query_old_firmware,
3939 .allowed_protos = RC_TYPE_RC5 |
3940 RC_TYPE_RC6 |
3941 RC_TYPE_NEC,
3942 .change_protocol = dib0700_change_protocol,
3943 },
3944 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3945
3946 .num_adapters = 2,
3947 .adapter = {
3948 {
3949 .num_frontends = 1,
3950 .fe = {{
3951 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3952 .pid_filter_count = 32,
3953 .pid_filter = stk70x0p_pid_filter,
3954 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3955 .frontend_attach = novatd_frontend_attach,
3956 .tuner_attach = dib7070p_tuner_attach,
3957
3958 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3959 }},
3960 .size_of_priv = sizeof(struct dib0700_adapter_state),
3961 }, {
3962 .num_frontends = 1,
3963 .fe = {{
3964 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3965 .pid_filter_count = 32,
3966 .pid_filter = stk70x0p_pid_filter,
3967 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3968 .frontend_attach = novatd_frontend_attach,
3969 .tuner_attach = dib7070p_tuner_attach,
3970
3971 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
3972 }},
3973 .size_of_priv = sizeof(struct dib0700_adapter_state),
3974 }
3975 },
3976
3977 .num_device_descs = 1,
3978 .devices = {
3979 { "Hauppauge Nova-TD Stick (52009)",
3980 { &dib0700_usb_id_table[35], NULL },
3981 { NULL },
3982 },
3983 },
3984
3985 .rc.core = {
3986 .rc_interval = DEFAULT_RC_INTERVAL,
3987 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3988 .module_name = "dib0700",
3989 .rc_query = dib0700_rc_query_old_firmware,
3990 .allowed_protos = RC_TYPE_RC5 |
3991 RC_TYPE_RC6 |
3992 RC_TYPE_NEC,
3993 .change_protocol = dib0700_change_protocol,
3994 },
3995 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3996
3997 .num_adapters = 2,
3998 .adapter = {
3999 {
4000 .num_frontends = 1,
4001 .fe = {{
4002 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4003 .pid_filter_count = 32,
4004 .pid_filter = stk70x0p_pid_filter,
4005 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4006 .frontend_attach = stk7070pd_frontend_attach0,
4007 .tuner_attach = dib7070p_tuner_attach,
4008
4009 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4010 }},
4011 .size_of_priv = sizeof(struct dib0700_adapter_state),
4012 }, {
4013 .num_frontends = 1,
4014 .fe = {{
4015 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4016 .pid_filter_count = 32,
4017 .pid_filter = stk70x0p_pid_filter,
4018 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4019 .frontend_attach = stk7070pd_frontend_attach1,
4020 .tuner_attach = dib7070p_tuner_attach,
4021
4022 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
4023 }},
4024 .size_of_priv = sizeof(struct dib0700_adapter_state),
4025 }
4026 },
4027
4028 .num_device_descs = 5,
4029 .devices = {
4030 { "DiBcom STK7070PD reference design",
4031 { &dib0700_usb_id_table[17], NULL },
4032 { NULL },
4033 },
4034 { "Pinnacle PCTV Dual DVB-T Diversity Stick",
4035 { &dib0700_usb_id_table[18], NULL },
4036 { NULL },
4037 },
4038 { "Hauppauge Nova-TD-500 (84xxx)",
4039 { &dib0700_usb_id_table[36], NULL },
4040 { NULL },
4041 },
4042 { "Terratec Cinergy DT USB XS Diversity/ T5",
4043 { &dib0700_usb_id_table[43],
4044 &dib0700_usb_id_table[53], NULL},
4045 { NULL },
4046 },
4047 { "Sony PlayTV",
4048 { &dib0700_usb_id_table[44], NULL },
4049 { NULL },
4050 },
4051 },
4052
4053 .rc.core = {
4054 .rc_interval = DEFAULT_RC_INTERVAL,
4055 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4056 .module_name = "dib0700",
4057 .rc_query = dib0700_rc_query_old_firmware,
4058 .allowed_protos = RC_TYPE_RC5 |
4059 RC_TYPE_RC6 |
4060 RC_TYPE_NEC,
4061 .change_protocol = dib0700_change_protocol,
4062 },
4063 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4064
4065 .num_adapters = 2,
4066 .adapter = {
4067 {
4068 .num_frontends = 1,
4069 .fe = {{
4070 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4071 .pid_filter_count = 32,
4072 .pid_filter = stk70x0p_pid_filter,
4073 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4074 .frontend_attach = stk7070pd_frontend_attach0,
4075 .tuner_attach = dib7070p_tuner_attach,
4076
4077 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4078 }},
4079 .size_of_priv = sizeof(struct dib0700_adapter_state),
4080 }, {
4081 .num_frontends = 1,
4082 .fe = {{
4083 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4084 .pid_filter_count = 32,
4085 .pid_filter = stk70x0p_pid_filter,
4086 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4087 .frontend_attach = stk7070pd_frontend_attach1,
4088 .tuner_attach = dib7070p_tuner_attach,
4089
4090 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
4091 }},
4092 .size_of_priv = sizeof(struct dib0700_adapter_state),
4093 }
4094 },
4095
4096 .num_device_descs = 1,
4097 .devices = {
4098 { "Elgato EyeTV Diversity",
4099 { &dib0700_usb_id_table[68], NULL },
4100 { NULL },
4101 },
4102 },
4103
4104 .rc.core = {
4105 .rc_interval = DEFAULT_RC_INTERVAL,
4106 .rc_codes = RC_MAP_DIB0700_NEC_TABLE,
4107 .module_name = "dib0700",
4108 .rc_query = dib0700_rc_query_old_firmware,
4109 .allowed_protos = RC_TYPE_RC5 |
4110 RC_TYPE_RC6 |
4111 RC_TYPE_NEC,
4112 .change_protocol = dib0700_change_protocol,
4113 },
4114 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4115
4116 .num_adapters = 1,
4117 .adapter = {
4118 {
4119 .num_frontends = 1,
4120 .fe = {{
4121 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4122 .pid_filter_count = 32,
4123 .pid_filter = stk70x0p_pid_filter,
4124 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4125 .frontend_attach = stk7700ph_frontend_attach,
4126 .tuner_attach = stk7700ph_tuner_attach,
4127
4128 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4129 }},
4130 .size_of_priv = sizeof(struct
4131 dib0700_adapter_state),
4132 },
4133 },
4134
4135 .num_device_descs = 9,
4136 .devices = {
4137 { "Terratec Cinergy HT USB XE",
4138 { &dib0700_usb_id_table[27], NULL },
4139 { NULL },
4140 },
4141 { "Pinnacle Expresscard 320cx",
4142 { &dib0700_usb_id_table[28], NULL },
4143 { NULL },
4144 },
4145 { "Terratec Cinergy HT Express",
4146 { &dib0700_usb_id_table[32], NULL },
4147 { NULL },
4148 },
4149 { "Gigabyte U8000-RH",
4150 { &dib0700_usb_id_table[37], NULL },
4151 { NULL },
4152 },
4153 { "YUAN High-Tech STK7700PH",
4154 { &dib0700_usb_id_table[38], NULL },
4155 { NULL },
4156 },
4157 { "Asus My Cinema-U3000Hybrid",
4158 { &dib0700_usb_id_table[39], NULL },
4159 { NULL },
4160 },
4161 { "YUAN High-Tech MC770",
4162 { &dib0700_usb_id_table[48], NULL },
4163 { NULL },
4164 },
4165 { "Leadtek WinFast DTV Dongle H",
4166 { &dib0700_usb_id_table[51], NULL },
4167 { NULL },
4168 },
4169 { "YUAN High-Tech STK7700D",
4170 { &dib0700_usb_id_table[54], NULL },
4171 { NULL },
4172 },
4173 },
4174
4175 .rc.core = {
4176 .rc_interval = DEFAULT_RC_INTERVAL,
4177 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4178 .module_name = "dib0700",
4179 .rc_query = dib0700_rc_query_old_firmware,
4180 .allowed_protos = RC_TYPE_RC5 |
4181 RC_TYPE_RC6 |
4182 RC_TYPE_NEC,
4183 .change_protocol = dib0700_change_protocol,
4184 },
4185 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4186 .num_adapters = 1,
4187 .adapter = {
4188 {
4189 .num_frontends = 1,
4190 .fe = {{
4191 .frontend_attach = s5h1411_frontend_attach,
4192 .tuner_attach = xc5000_tuner_attach,
4193
4194 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4195 }},
4196 .size_of_priv = sizeof(struct
4197 dib0700_adapter_state),
4198 },
4199 },
4200
4201 .num_device_descs = 2,
4202 .devices = {
4203 { "Pinnacle PCTV HD Pro USB Stick",
4204 { &dib0700_usb_id_table[40], NULL },
4205 { NULL },
4206 },
4207 { "Pinnacle PCTV HD USB Stick",
4208 { &dib0700_usb_id_table[41], NULL },
4209 { NULL },
4210 },
4211 },
4212
4213 .rc.core = {
4214 .rc_interval = DEFAULT_RC_INTERVAL,
4215 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4216 .module_name = "dib0700",
4217 .rc_query = dib0700_rc_query_old_firmware,
4218 .allowed_protos = RC_TYPE_RC5 |
4219 RC_TYPE_RC6 |
4220 RC_TYPE_NEC,
4221 .change_protocol = dib0700_change_protocol,
4222 },
4223 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4224 .num_adapters = 1,
4225 .adapter = {
4226 {
4227 .num_frontends = 1,
4228 .fe = {{
4229 .frontend_attach = lgdt3305_frontend_attach,
4230 .tuner_attach = mxl5007t_tuner_attach,
4231
4232 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4233 }},
4234 .size_of_priv = sizeof(struct
4235 dib0700_adapter_state),
4236 },
4237 },
4238
4239 .num_device_descs = 2,
4240 .devices = {
4241 { "Hauppauge ATSC MiniCard (B200)",
4242 { &dib0700_usb_id_table[46], NULL },
4243 { NULL },
4244 },
4245 { "Hauppauge ATSC MiniCard (B210)",
4246 { &dib0700_usb_id_table[47], NULL },
4247 { NULL },
4248 },
4249 },
4250 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4251
4252 .num_adapters = 1,
4253 .adapter = {
4254 {
4255 .num_frontends = 1,
4256 .fe = {{
4257 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4258 .pid_filter_count = 32,
4259 .pid_filter = stk70x0p_pid_filter,
4260 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4261 .frontend_attach = stk7770p_frontend_attach,
4262 .tuner_attach = dib7770p_tuner_attach,
4263
4264 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4265 }},
4266 .size_of_priv =
4267 sizeof(struct dib0700_adapter_state),
4268 },
4269 },
4270
4271 .num_device_descs = 4,
4272 .devices = {
4273 { "DiBcom STK7770P reference design",
4274 { &dib0700_usb_id_table[59], NULL },
4275 { NULL },
4276 },
4277 { "Terratec Cinergy T USB XXS (HD)/ T3",
4278 { &dib0700_usb_id_table[33],
4279 &dib0700_usb_id_table[52],
4280 &dib0700_usb_id_table[60], NULL},
4281 { NULL },
4282 },
4283 { "TechniSat AirStar TeleStick 2",
4284 { &dib0700_usb_id_table[74], NULL },
4285 { NULL },
4286 },
4287 { "Medion CTX1921 DVB-T USB",
4288 { &dib0700_usb_id_table[75], NULL },
4289 { NULL },
4290 },
4291 },
4292
4293 .rc.core = {
4294 .rc_interval = DEFAULT_RC_INTERVAL,
4295 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4296 .module_name = "dib0700",
4297 .rc_query = dib0700_rc_query_old_firmware,
4298 .allowed_protos = RC_TYPE_RC5 |
4299 RC_TYPE_RC6 |
4300 RC_TYPE_NEC,
4301 .change_protocol = dib0700_change_protocol,
4302 },
4303 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4304 .num_adapters = 1,
4305 .adapter = {
4306 {
4307 .num_frontends = 1,
4308 .fe = {{
4309 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4310 .pid_filter_count = 32,
4311 .pid_filter = stk80xx_pid_filter,
4312 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
4313 .frontend_attach = stk807x_frontend_attach,
4314 .tuner_attach = dib807x_tuner_attach,
4315
4316 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4317 }},
4318 .size_of_priv =
4319 sizeof(struct dib0700_adapter_state),
4320 },
4321 },
4322
4323 .num_device_descs = 3,
4324 .devices = {
4325 { "DiBcom STK807xP reference design",
4326 { &dib0700_usb_id_table[62], NULL },
4327 { NULL },
4328 },
4329 { "Prolink Pixelview SBTVD",
4330 { &dib0700_usb_id_table[63], NULL },
4331 { NULL },
4332 },
4333 { "EvolutePC TVWay+",
4334 { &dib0700_usb_id_table[64], NULL },
4335 { NULL },
4336 },
4337 },
4338
4339 .rc.core = {
4340 .rc_interval = DEFAULT_RC_INTERVAL,
4341 .rc_codes = RC_MAP_DIB0700_NEC_TABLE,
4342 .module_name = "dib0700",
4343 .rc_query = dib0700_rc_query_old_firmware,
4344 .allowed_protos = RC_TYPE_RC5 |
4345 RC_TYPE_RC6 |
4346 RC_TYPE_NEC,
4347 .change_protocol = dib0700_change_protocol,
4348 },
4349 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4350 .num_adapters = 2,
4351 .adapter = {
4352 {
4353 .num_frontends = 1,
4354 .fe = {{
4355 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4356 .pid_filter_count = 32,
4357 .pid_filter = stk80xx_pid_filter,
4358 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
4359 .frontend_attach = stk807xpvr_frontend_attach0,
4360 .tuner_attach = dib807x_tuner_attach,
4361
4362 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4363 }},
4364 .size_of_priv =
4365 sizeof(struct dib0700_adapter_state),
4366 },
4367 {
4368 .num_frontends = 1,
4369 .fe = {{
4370 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4371 .pid_filter_count = 32,
4372 .pid_filter = stk80xx_pid_filter,
4373 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
4374 .frontend_attach = stk807xpvr_frontend_attach1,
4375 .tuner_attach = dib807x_tuner_attach,
4376
4377 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
4378 }},
4379 .size_of_priv =
4380 sizeof(struct dib0700_adapter_state),
4381 },
4382 },
4383
4384 .num_device_descs = 1,
4385 .devices = {
4386 { "DiBcom STK807xPVR reference design",
4387 { &dib0700_usb_id_table[61], NULL },
4388 { NULL },
4389 },
4390 },
4391
4392 .rc.core = {
4393 .rc_interval = DEFAULT_RC_INTERVAL,
4394 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4395 .module_name = "dib0700",
4396 .rc_query = dib0700_rc_query_old_firmware,
4397 .allowed_protos = RC_TYPE_RC5 |
4398 RC_TYPE_RC6 |
4399 RC_TYPE_NEC,
4400 .change_protocol = dib0700_change_protocol,
4401 },
4402 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4403 .num_adapters = 1,
4404 .adapter = {
4405 {
4406 .num_frontends = 1,
4407 .fe = {{
4408 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4409 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4410 .pid_filter_count = 32,
4411 .pid_filter = stk80xx_pid_filter,
4412 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
4413 .frontend_attach = stk809x_frontend_attach,
4414 .tuner_attach = dib809x_tuner_attach,
4415
4416 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4417 }},
4418 .size_of_priv =
4419 sizeof(struct dib0700_adapter_state),
4420 },
4421 },
4422
4423 .num_device_descs = 1,
4424 .devices = {
4425 { "DiBcom STK8096GP reference design",
4426 { &dib0700_usb_id_table[67], NULL },
4427 { NULL },
4428 },
4429 },
4430
4431 .rc.core = {
4432 .rc_interval = DEFAULT_RC_INTERVAL,
4433 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4434 .module_name = "dib0700",
4435 .rc_query = dib0700_rc_query_old_firmware,
4436 .allowed_protos = RC_TYPE_RC5 |
4437 RC_TYPE_RC6 |
4438 RC_TYPE_NEC,
4439 .change_protocol = dib0700_change_protocol,
4440 },
4441 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4442 .num_adapters = 1,
4443 .adapter = {
4444 {
4445 .num_frontends = 1,
4446 .fe = {{
4447 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4448 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4449 .pid_filter_count = 32,
4450 .pid_filter = dib90x0_pid_filter,
4451 .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
4452 .frontend_attach = stk9090m_frontend_attach,
4453 .tuner_attach = dib9090_tuner_attach,
4454
4455 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4456 }},
4457 .size_of_priv =
4458 sizeof(struct dib0700_adapter_state),
4459 },
4460 },
4461
4462 .num_device_descs = 1,
4463 .devices = {
4464 { "DiBcom STK9090M reference design",
4465 { &dib0700_usb_id_table[69], NULL },
4466 { NULL },
4467 },
4468 },
4469
4470 .rc.core = {
4471 .rc_interval = DEFAULT_RC_INTERVAL,
4472 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4473 .module_name = "dib0700",
4474 .rc_query = dib0700_rc_query_old_firmware,
4475 .allowed_protos = RC_TYPE_RC5 |
4476 RC_TYPE_RC6 |
4477 RC_TYPE_NEC,
4478 .change_protocol = dib0700_change_protocol,
4479 },
4480 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4481 .num_adapters = 1,
4482 .adapter = {
4483 {
4484 .num_frontends = 1,
4485 .fe = {{
4486 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4487 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4488 .pid_filter_count = 32,
4489 .pid_filter = stk80xx_pid_filter,
4490 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
4491 .frontend_attach = nim8096md_frontend_attach,
4492 .tuner_attach = nim8096md_tuner_attach,
4493
4494 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4495 }},
4496 .size_of_priv =
4497 sizeof(struct dib0700_adapter_state),
4498 },
4499 },
4500
4501 .num_device_descs = 1,
4502 .devices = {
4503 { "DiBcom NIM8096MD reference design",
4504 { &dib0700_usb_id_table[70], NULL },
4505 { NULL },
4506 },
4507 },
4508
4509 .rc.core = {
4510 .rc_interval = DEFAULT_RC_INTERVAL,
4511 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4512 .module_name = "dib0700",
4513 .rc_query = dib0700_rc_query_old_firmware,
4514 .allowed_protos = RC_TYPE_RC5 |
4515 RC_TYPE_RC6 |
4516 RC_TYPE_NEC,
4517 .change_protocol = dib0700_change_protocol,
4518 },
4519 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4520 .num_adapters = 1,
4521 .adapter = {
4522 {
4523 .num_frontends = 1,
4524 .fe = {{
4525 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4526 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4527 .pid_filter_count = 32,
4528 .pid_filter = dib90x0_pid_filter,
4529 .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
4530 .frontend_attach = nim9090md_frontend_attach,
4531 .tuner_attach = nim9090md_tuner_attach,
4532
4533 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4534 }},
4535 .size_of_priv =
4536 sizeof(struct dib0700_adapter_state),
4537 },
4538 },
4539
4540 .num_device_descs = 1,
4541 .devices = {
4542 { "DiBcom NIM9090MD reference design",
4543 { &dib0700_usb_id_table[71], NULL },
4544 { NULL },
4545 },
4546 },
4547
4548 .rc.core = {
4549 .rc_interval = DEFAULT_RC_INTERVAL,
4550 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4551 .module_name = "dib0700",
4552 .rc_query = dib0700_rc_query_old_firmware,
4553 .allowed_protos = RC_TYPE_RC5 |
4554 RC_TYPE_RC6 |
4555 RC_TYPE_NEC,
4556 .change_protocol = dib0700_change_protocol,
4557 },
4558 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4559 .num_adapters = 1,
4560 .adapter = {
4561 {
4562 .num_frontends = 1,
4563 .fe = {{
4564 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4565 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4566 .pid_filter_count = 32,
4567 .pid_filter = stk70x0p_pid_filter,
4568 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4569 .frontend_attach = nim7090_frontend_attach,
4570 .tuner_attach = nim7090_tuner_attach,
4571
4572 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4573 }},
4574 .size_of_priv =
4575 sizeof(struct dib0700_adapter_state),
4576 },
4577 },
4578
4579 .num_device_descs = 1,
4580 .devices = {
4581 { "DiBcom NIM7090 reference design",
4582 { &dib0700_usb_id_table[72], NULL },
4583 { NULL },
4584 },
4585 },
4586
4587 .rc.core = {
4588 .rc_interval = DEFAULT_RC_INTERVAL,
4589 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4590 .module_name = "dib0700",
4591 .rc_query = dib0700_rc_query_old_firmware,
4592 .allowed_protos = RC_TYPE_RC5 |
4593 RC_TYPE_RC6 |
4594 RC_TYPE_NEC,
4595 .change_protocol = dib0700_change_protocol,
4596 },
4597 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4598 .num_adapters = 2,
4599 .adapter = {
4600 {
4601 .num_frontends = 1,
4602 .fe = {{
4603 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4604 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4605 .pid_filter_count = 32,
4606 .pid_filter = stk70x0p_pid_filter,
4607 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4608 .frontend_attach = tfe7090pvr_frontend0_attach,
4609 .tuner_attach = tfe7090pvr_tuner0_attach,
4610
4611 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
4612 }},
4613 .size_of_priv =
4614 sizeof(struct dib0700_adapter_state),
4615 },
4616 {
4617 .num_frontends = 1,
4618 .fe = {{
4619 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4620 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4621 .pid_filter_count = 32,
4622 .pid_filter = stk70x0p_pid_filter,
4623 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4624 .frontend_attach = tfe7090pvr_frontend1_attach,
4625 .tuner_attach = tfe7090pvr_tuner1_attach,
4626
4627 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4628 }},
4629 .size_of_priv =
4630 sizeof(struct dib0700_adapter_state),
4631 },
4632 },
4633
4634 .num_device_descs = 1,
4635 .devices = {
4636 { "DiBcom TFE7090PVR reference design",
4637 { &dib0700_usb_id_table[73], NULL },
4638 { NULL },
4639 },
4640 },
4641
4642 .rc.core = {
4643 .rc_interval = DEFAULT_RC_INTERVAL,
4644 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4645 .module_name = "dib0700",
4646 .rc_query = dib0700_rc_query_old_firmware,
4647 .allowed_protos = RC_TYPE_RC5 |
4648 RC_TYPE_RC6 |
4649 RC_TYPE_NEC,
4650 .change_protocol = dib0700_change_protocol,
4651 },
4652 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4653 .num_adapters = 1,
4654 .adapter = {
4655 {
4656 .num_frontends = 1,
4657 .fe = {{
4658 .frontend_attach = pctv340e_frontend_attach,
4659 .tuner_attach = xc4000_tuner_attach,
4660
4661 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4662 }},
4663 .size_of_priv = sizeof(struct
4664 dib0700_adapter_state),
4665 },
4666 },
4667
4668 .num_device_descs = 2,
4669 .devices = {
4670 { "Pinnacle PCTV 340e HD Pro USB Stick",
4671 { &dib0700_usb_id_table[76], NULL },
4672 { NULL },
4673 },
4674 { "Pinnacle PCTV Hybrid Stick Solo",
4675 { &dib0700_usb_id_table[77], NULL },
4676 { NULL },
4677 },
4678 },
4679 .rc.core = {
4680 .rc_interval = DEFAULT_RC_INTERVAL,
4681 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4682 .module_name = "dib0700",
4683 .rc_query = dib0700_rc_query_old_firmware,
4684 .allowed_protos = RC_TYPE_RC5 |
4685 RC_TYPE_RC6 |
4686 RC_TYPE_NEC,
4687 .change_protocol = dib0700_change_protocol,
4688 },
4689 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4690 .num_adapters = 1,
4691 .adapter = {
4692 {
4693 .num_frontends = 1,
4694 .fe = {{
4695 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4696 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4697 .pid_filter_count = 32,
4698 .pid_filter = stk70x0p_pid_filter,
4699 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4700 .frontend_attach = tfe7090e_frontend_attach,
4701 .tuner_attach = tfe7090e_tuner_attach,
4702
4703 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4704 } },
4705
4706 .size_of_priv =
4707 sizeof(struct dib0700_adapter_state),
4708 },
4709 },
4710
4711 .num_device_descs = 1,
4712 .devices = {
4713 { "DiBcom TFE7090E reference design",
4714 { &dib0700_usb_id_table[78], NULL },
4715 { NULL },
4716 },
4717 },
4718
4719 .rc.core = {
4720 .rc_interval = DEFAULT_RC_INTERVAL,
4721 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4722 .module_name = "dib0700",
4723 .rc_query = dib0700_rc_query_old_firmware,
4724 .allowed_protos = RC_TYPE_RC5 |
4725 RC_TYPE_RC6 |
4726 RC_TYPE_NEC,
4727 .change_protocol = dib0700_change_protocol,
4728 },
4729 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4730 .num_adapters = 1,
4731 .adapter = {
4732 {
4733 .num_frontends = 1,
4734 .fe = {{
4735 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4736 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4737 .pid_filter_count = 32,
4738 .pid_filter = stk70x0p_pid_filter,
4739 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4740 .frontend_attach = tfe7790e_frontend_attach,
4741 .tuner_attach = tfe7790e_tuner_attach,
4742
4743 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
4744 } },
4745
4746 .size_of_priv =
4747 sizeof(struct dib0700_adapter_state),
4748 },
4749 },
4750
4751 .num_device_descs = 1,
4752 .devices = {
4753 { "DiBcom TFE7790E reference design",
4754 { &dib0700_usb_id_table[79], NULL },
4755 { NULL },
4756 },
4757 },
4758
4759 .rc.core = {
4760 .rc_interval = DEFAULT_RC_INTERVAL,
4761 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4762 .module_name = "dib0700",
4763 .rc_query = dib0700_rc_query_old_firmware,
4764 .allowed_protos = RC_TYPE_RC5 |
4765 RC_TYPE_RC6 |
4766 RC_TYPE_NEC,
4767 .change_protocol = dib0700_change_protocol,
4768 },
4769 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4770 .num_adapters = 1,
4771 .adapter = {
4772 {
4773 .num_frontends = 1,
4774 .fe = {{
4775 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4776 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4777 .pid_filter_count = 32,
4778 .pid_filter = stk80xx_pid_filter,
4779 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
4780 .frontend_attach = tfe8096p_frontend_attach,
4781 .tuner_attach = tfe8096p_tuner_attach,
4782
4783 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4784
4785 } },
4786
4787 .size_of_priv =
4788 sizeof(struct dib0700_adapter_state),
4789 },
4790 },
4791
4792 .num_device_descs = 1,
4793 .devices = {
4794 { "DiBcom TFE8096P reference design",
4795 { &dib0700_usb_id_table[80], NULL },
4796 { NULL },
4797 },
4798 },
4799
4800 .rc.core = {
4801 .rc_interval = DEFAULT_RC_INTERVAL,
4802 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4803 .module_name = "dib0700",
4804 .rc_query = dib0700_rc_query_old_firmware,
4805 .allowed_protos = RC_TYPE_RC5 |
4806 RC_TYPE_RC6 |
4807 RC_TYPE_NEC,
4808 .change_protocol = dib0700_change_protocol,
4809 },
4810 },
4811};
4812
4813int dib0700_device_count = ARRAY_SIZE(dib0700_devices);
diff --git a/drivers/media/usb/dvb-usb/dib07x0.h b/drivers/media/usb/dvb-usb/dib07x0.h
new file mode 100644
index 000000000000..7e62c1018520
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/dibusb-common.c b/drivers/media/usb/dvb-usb/dibusb-common.c
new file mode 100644
index 000000000000..a76bbb29ca36
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dibusb-common.c
@@ -0,0 +1,479 @@
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_adap[0].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_adap[0].fe,
41 index, pid, onoff);
42 }
43 return 0;
44}
45EXPORT_SYMBOL(dibusb_pid_filter);
46
47int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
48{
49 if (adap->priv != NULL) {
50 struct dibusb_state *st = adap->priv;
51 if (st->ops.pid_parse != NULL)
52 if (st->ops.pid_parse(adap->fe_adap[0].fe, onoff) < 0)
53 err("could not handle pid_parser");
54 }
55 return 0;
56}
57EXPORT_SYMBOL(dibusb_pid_filter_ctrl);
58
59int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff)
60{
61 u8 b[3];
62 int ret;
63 b[0] = DIBUSB_REQ_SET_IOCTL;
64 b[1] = DIBUSB_IOCTL_CMD_POWER_MODE;
65 b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP;
66 ret = dvb_usb_generic_write(d,b,3);
67 msleep(10);
68 return ret;
69}
70EXPORT_SYMBOL(dibusb_power_ctrl);
71
72int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
73{
74 u8 b[3] = { 0 };
75 int ret;
76
77 if ((ret = dibusb_streaming_ctrl(adap,onoff)) < 0)
78 return ret;
79
80 if (onoff) {
81 b[0] = DIBUSB_REQ_SET_STREAMING_MODE;
82 b[1] = 0x00;
83 if ((ret = dvb_usb_generic_write(adap->dev,b,2)) < 0)
84 return ret;
85 }
86
87 b[0] = DIBUSB_REQ_SET_IOCTL;
88 b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
89 return dvb_usb_generic_write(adap->dev,b,3);
90}
91EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
92
93int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff)
94{
95 if (onoff) {
96 u8 b[3] = { DIBUSB_REQ_SET_IOCTL, DIBUSB_IOCTL_CMD_POWER_MODE, DIBUSB_IOCTL_POWER_WAKEUP };
97 return dvb_usb_generic_write(d,b,3);
98 } else
99 return 0;
100}
101EXPORT_SYMBOL(dibusb2_0_power_ctrl);
102
103static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr,
104 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
105{
106 u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
107 /* write only ? */
108 int wo = (rbuf == NULL || rlen == 0),
109 len = 2 + wlen + (wo ? 0 : 2);
110
111 sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
112 sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
113
114 memcpy(&sndbuf[2],wbuf,wlen);
115
116 if (!wo) {
117 sndbuf[wlen+2] = (rlen >> 8) & 0xff;
118 sndbuf[wlen+3] = rlen & 0xff;
119 }
120
121 return dvb_usb_generic_rw(d,sndbuf,len,rbuf,rlen,0);
122}
123
124/*
125 * I2C master xfer function
126 */
127static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
128{
129 struct dvb_usb_device *d = i2c_get_adapdata(adap);
130 int i;
131
132 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
133 return -EAGAIN;
134
135 for (i = 0; i < num; i++) {
136 /* write/read request */
137 if (i+1 < num && (msg[i].flags & I2C_M_RD) == 0
138 && (msg[i+1].flags & I2C_M_RD)) {
139 if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,
140 msg[i+1].buf,msg[i+1].len) < 0)
141 break;
142 i++;
143 } else if ((msg[i].flags & I2C_M_RD) == 0) {
144 if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
145 break;
146 } else if (msg[i].addr != 0x50) {
147 /* 0x50 is the address of the eeprom - we need to protect it
148 * from dibusb's bad i2c implementation: reads without
149 * writing the offset before are forbidden */
150 if (dibusb_i2c_msg(d, msg[i].addr, NULL, 0, msg[i].buf, msg[i].len) < 0)
151 break;
152 }
153 }
154
155 mutex_unlock(&d->i2c_mutex);
156 return i;
157}
158
159static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
160{
161 return I2C_FUNC_I2C;
162}
163
164struct i2c_algorithm dibusb_i2c_algo = {
165 .master_xfer = dibusb_i2c_xfer,
166 .functionality = dibusb_i2c_func,
167};
168EXPORT_SYMBOL(dibusb_i2c_algo);
169
170int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
171{
172 u8 wbuf[1] = { offs };
173 return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1);
174}
175EXPORT_SYMBOL(dibusb_read_eeprom_byte);
176
177/* 3000MC/P stuff */
178// Config Adjacent channels Perf -cal22
179static struct dibx000_agc_config dib3000p_mt2060_agc_config = {
180 .band_caps = BAND_VHF | BAND_UHF,
181 .setup = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0),
182
183 .agc1_max = 48497,
184 .agc1_min = 23593,
185 .agc2_max = 46531,
186 .agc2_min = 24904,
187
188 .agc1_pt1 = 0x65,
189 .agc1_pt2 = 0x69,
190
191 .agc1_slope1 = 0x51,
192 .agc1_slope2 = 0x27,
193
194 .agc2_pt1 = 0,
195 .agc2_pt2 = 0x33,
196
197 .agc2_slope1 = 0x35,
198 .agc2_slope2 = 0x37,
199};
200
201static struct dib3000mc_config stk3000p_dib3000p_config = {
202 &dib3000p_mt2060_agc_config,
203
204 .max_time = 0x196,
205 .ln_adc_level = 0x1cc7,
206
207 .output_mpeg2_in_188_bytes = 1,
208
209 .agc_command1 = 1,
210 .agc_command2 = 1,
211};
212
213static struct dibx000_agc_config dib3000p_panasonic_agc_config = {
214 .band_caps = BAND_VHF | BAND_UHF,
215 .setup = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0),
216
217 .agc1_max = 56361,
218 .agc1_min = 22282,
219 .agc2_max = 47841,
220 .agc2_min = 36045,
221
222 .agc1_pt1 = 0x3b,
223 .agc1_pt2 = 0x6b,
224
225 .agc1_slope1 = 0x55,
226 .agc1_slope2 = 0x1d,
227
228 .agc2_pt1 = 0,
229 .agc2_pt2 = 0x0a,
230
231 .agc2_slope1 = 0x95,
232 .agc2_slope2 = 0x1e,
233};
234
235#if defined(CONFIG_DVB_DIB3000MC) || \
236 (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE))
237
238static struct dib3000mc_config mod3000p_dib3000p_config = {
239 &dib3000p_panasonic_agc_config,
240
241 .max_time = 0x51,
242 .ln_adc_level = 0x1cc7,
243
244 .output_mpeg2_in_188_bytes = 1,
245
246 .agc_command1 = 1,
247 .agc_command2 = 1,
248};
249
250int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap)
251{
252 if (adap->dev->udev->descriptor.idVendor == USB_VID_LITEON &&
253 adap->dev->udev->descriptor.idProduct ==
254 USB_PID_LITEON_DVB_T_WARM) {
255 msleep(1000);
256 }
257
258 adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach,
259 &adap->dev->i2c_adap,
260 DEFAULT_DIB3000P_I2C_ADDRESS,
261 &mod3000p_dib3000p_config);
262 if ((adap->fe_adap[0].fe) == NULL)
263 adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach,
264 &adap->dev->i2c_adap,
265 DEFAULT_DIB3000MC_I2C_ADDRESS,
266 &mod3000p_dib3000p_config);
267 if ((adap->fe_adap[0].fe) != NULL) {
268 if (adap->priv != NULL) {
269 struct dibusb_state *st = adap->priv;
270 st->ops.pid_parse = dib3000mc_pid_parse;
271 st->ops.pid_ctrl = dib3000mc_pid_control;
272 }
273 return 0;
274 }
275 return -ENODEV;
276}
277EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);
278
279static struct mt2060_config stk3000p_mt2060_config = {
280 0x60
281};
282
283int dibusb_dib3000mc_tuner_attach(struct dvb_usb_adapter *adap)
284{
285 struct dibusb_state *st = adap->priv;
286 u8 a,b;
287 u16 if1 = 1220;
288 struct i2c_adapter *tun_i2c;
289
290 // First IF calibration for Liteon Sticks
291 if (adap->dev->udev->descriptor.idVendor == USB_VID_LITEON &&
292 adap->dev->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) {
293
294 dibusb_read_eeprom_byte(adap->dev,0x7E,&a);
295 dibusb_read_eeprom_byte(adap->dev,0x7F,&b);
296
297 if (a == 0x00)
298 if1 += b;
299 else if (a == 0x80)
300 if1 -= b;
301 else
302 warn("LITE-ON DVB-T: Strange IF1 calibration :%2X %2X\n", a, b);
303
304 } else if (adap->dev->udev->descriptor.idVendor == USB_VID_DIBCOM &&
305 adap->dev->udev->descriptor.idProduct == USB_PID_DIBCOM_MOD3001_WARM) {
306 u8 desc;
307 dibusb_read_eeprom_byte(adap->dev, 7, &desc);
308 if (desc == 2) {
309 a = 127;
310 do {
311 dibusb_read_eeprom_byte(adap->dev, a, &desc);
312 a--;
313 } while (a > 7 && (desc == 0xff || desc == 0x00));
314 if (desc & 0x80)
315 if1 -= (0xff - desc);
316 else
317 if1 += desc;
318 }
319 }
320
321 tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe_adap[0].fe, 1);
322 if (dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c, &stk3000p_mt2060_config, if1) == NULL) {
323 /* not found - use panasonic pll parameters */
324 if (dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, tun_i2c, DVB_PLL_ENV57H1XD5) == NULL)
325 return -ENOMEM;
326 } else {
327 st->mt2060_present = 1;
328 /* set the correct parameters for the dib3000p */
329 dib3000mc_set_config(adap->fe_adap[0].fe, &stk3000p_dib3000p_config);
330 }
331 return 0;
332}
333EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
334#endif
335
336/*
337 * common remote control stuff
338 */
339struct rc_map_table rc_map_dibusb_table[] = {
340 /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
341 { 0x0016, KEY_POWER },
342 { 0x0010, KEY_MUTE },
343 { 0x0003, KEY_1 },
344 { 0x0001, KEY_2 },
345 { 0x0006, KEY_3 },
346 { 0x0009, KEY_4 },
347 { 0x001d, KEY_5 },
348 { 0x001f, KEY_6 },
349 { 0x000d, KEY_7 },
350 { 0x0019, KEY_8 },
351 { 0x001b, KEY_9 },
352 { 0x0015, KEY_0 },
353 { 0x0005, KEY_CHANNELUP },
354 { 0x0002, KEY_CHANNELDOWN },
355 { 0x001e, KEY_VOLUMEUP },
356 { 0x000a, KEY_VOLUMEDOWN },
357 { 0x0011, KEY_RECORD },
358 { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
359 { 0x0014, KEY_PLAY },
360 { 0x001a, KEY_STOP },
361 { 0x0040, KEY_REWIND },
362 { 0x0012, KEY_FASTFORWARD },
363 { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
364 { 0x004c, KEY_PAUSE },
365 { 0x004d, KEY_SCREEN }, /* Full screen mode. */
366 { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
367 /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
368 { 0x000c, KEY_CANCEL }, /* Cancel */
369 { 0x001c, KEY_EPG }, /* EPG */
370 { 0x0000, KEY_TAB }, /* Tab */
371 { 0x0048, KEY_INFO }, /* Preview */
372 { 0x0004, KEY_LIST }, /* RecordList */
373 { 0x000f, KEY_TEXT }, /* Teletext */
374 /* Key codes for the KWorld/ADSTech/JetWay remote. */
375 { 0x8612, KEY_POWER },
376 { 0x860f, KEY_SELECT }, /* source */
377 { 0x860c, KEY_UNKNOWN }, /* scan */
378 { 0x860b, KEY_EPG },
379 { 0x8610, KEY_MUTE },
380 { 0x8601, KEY_1 },
381 { 0x8602, KEY_2 },
382 { 0x8603, KEY_3 },
383 { 0x8604, KEY_4 },
384 { 0x8605, KEY_5 },
385 { 0x8606, KEY_6 },
386 { 0x8607, KEY_7 },
387 { 0x8608, KEY_8 },
388 { 0x8609, KEY_9 },
389 { 0x860a, KEY_0 },
390 { 0x8618, KEY_ZOOM },
391 { 0x861c, KEY_UNKNOWN }, /* preview */
392 { 0x8613, KEY_UNKNOWN }, /* snap */
393 { 0x8600, KEY_UNDO },
394 { 0x861d, KEY_RECORD },
395 { 0x860d, KEY_STOP },
396 { 0x860e, KEY_PAUSE },
397 { 0x8616, KEY_PLAY },
398 { 0x8611, KEY_BACK },
399 { 0x8619, KEY_FORWARD },
400 { 0x8614, KEY_UNKNOWN }, /* pip */
401 { 0x8615, KEY_ESC },
402 { 0x861a, KEY_UP },
403 { 0x861e, KEY_DOWN },
404 { 0x861f, KEY_LEFT },
405 { 0x861b, KEY_RIGHT },
406
407 /* Key codes for the DiBcom MOD3000 remote. */
408 { 0x8000, KEY_MUTE },
409 { 0x8001, KEY_TEXT },
410 { 0x8002, KEY_HOME },
411 { 0x8003, KEY_POWER },
412
413 { 0x8004, KEY_RED },
414 { 0x8005, KEY_GREEN },
415 { 0x8006, KEY_YELLOW },
416 { 0x8007, KEY_BLUE },
417
418 { 0x8008, KEY_DVD },
419 { 0x8009, KEY_AUDIO },
420 { 0x800a, KEY_IMAGES }, /* Pictures */
421 { 0x800b, KEY_VIDEO },
422
423 { 0x800c, KEY_BACK },
424 { 0x800d, KEY_UP },
425 { 0x800e, KEY_RADIO },
426 { 0x800f, KEY_EPG },
427
428 { 0x8010, KEY_LEFT },
429 { 0x8011, KEY_OK },
430 { 0x8012, KEY_RIGHT },
431 { 0x8013, KEY_UNKNOWN }, /* SAP */
432
433 { 0x8014, KEY_TV },
434 { 0x8015, KEY_DOWN },
435 { 0x8016, KEY_MENU }, /* DVD Menu */
436 { 0x8017, KEY_LAST },
437
438 { 0x8018, KEY_RECORD },
439 { 0x8019, KEY_STOP },
440 { 0x801a, KEY_PAUSE },
441 { 0x801b, KEY_PLAY },
442
443 { 0x801c, KEY_PREVIOUS },
444 { 0x801d, KEY_REWIND },
445 { 0x801e, KEY_FASTFORWARD },
446 { 0x801f, KEY_NEXT},
447
448 { 0x8040, KEY_1 },
449 { 0x8041, KEY_2 },
450 { 0x8042, KEY_3 },
451 { 0x8043, KEY_CHANNELUP },
452
453 { 0x8044, KEY_4 },
454 { 0x8045, KEY_5 },
455 { 0x8046, KEY_6 },
456 { 0x8047, KEY_CHANNELDOWN },
457
458 { 0x8048, KEY_7 },
459 { 0x8049, KEY_8 },
460 { 0x804a, KEY_9 },
461 { 0x804b, KEY_VOLUMEUP },
462
463 { 0x804c, KEY_CLEAR },
464 { 0x804d, KEY_0 },
465 { 0x804e, KEY_ENTER },
466 { 0x804f, KEY_VOLUMEDOWN },
467};
468EXPORT_SYMBOL(rc_map_dibusb_table);
469
470int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
471{
472 u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE;
473 dvb_usb_generic_rw(d,&cmd,1,key,5,0);
474 dvb_usb_nec_rc_key_to_event(d,key,event,state);
475 if (key[0] != 0)
476 deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
477 return 0;
478}
479EXPORT_SYMBOL(dibusb_rc_query);
diff --git a/drivers/media/usb/dvb-usb/dibusb-mb.c b/drivers/media/usb/dvb-usb/dibusb-mb.c
new file mode 100644
index 000000000000..a4ac37e0e98b
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dibusb-mb.c
@@ -0,0 +1,471 @@
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 adap->fe_adap[0].fe = dvb_attach(dib3000mb_attach, &demod_cfg,
35 &adap->dev->i2c_adap, &st->ops);
36 if ((adap->fe_adap[0].fe) == NULL)
37 return -ENODEV;
38
39 adap->fe_adap[0].fe->ops.i2c_gate_ctrl = dib3000mb_i2c_gate_ctrl;
40
41 return 0;
42}
43
44static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap)
45{
46 struct dibusb_state *st = adap->priv;
47
48 st->tuner_addr = 0x61;
49
50 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, &adap->dev->i2c_adap,
51 DVB_PLL_TUA6010XS);
52 return 0;
53}
54
55static int dibusb_panasonic_tuner_attach(struct dvb_usb_adapter *adap)
56{
57 struct dibusb_state *st = adap->priv;
58
59 st->tuner_addr = 0x60;
60
61 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap,
62 DVB_PLL_TDA665X);
63 return 0;
64}
65
66/* Some of the Artec 1.1 device aren't equipped with the default tuner
67 * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures
68 * this out. */
69static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap)
70{
71 u8 b[2] = { 0,0 }, b2[1];
72 int ret = 0;
73 struct i2c_msg msg[2] = {
74 { .flags = 0, .buf = b, .len = 2 },
75 { .flags = I2C_M_RD, .buf = b2, .len = 1 },
76 };
77 struct dibusb_state *st = adap->priv;
78
79 /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */
80 msg[0].addr = msg[1].addr = st->tuner_addr = 0x60;
81
82 if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
83 adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1);
84
85 if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) {
86 err("tuner i2c write failed.");
87 ret = -EREMOTEIO;
88 }
89
90 if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
91 adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0);
92
93 if (b2[0] == 0xfe) {
94 info("This device has the Thomson Cable onboard. Which is default.");
95 ret = dibusb_thomson_tuner_attach(adap);
96 } else {
97 info("This device has the Panasonic ENV77H11D5 onboard.");
98 ret = dibusb_panasonic_tuner_attach(adap);
99 }
100
101 return ret;
102}
103
104/* USB Driver stuff */
105static struct dvb_usb_device_properties dibusb1_1_properties;
106static struct dvb_usb_device_properties dibusb1_1_an2235_properties;
107static struct dvb_usb_device_properties dibusb2_0b_properties;
108static struct dvb_usb_device_properties artec_t1_usb2_properties;
109
110static int dibusb_probe(struct usb_interface *intf,
111 const struct usb_device_id *id)
112{
113 if (0 == dvb_usb_device_init(intf, &dibusb1_1_properties,
114 THIS_MODULE, NULL, adapter_nr) ||
115 0 == dvb_usb_device_init(intf, &dibusb1_1_an2235_properties,
116 THIS_MODULE, NULL, adapter_nr) ||
117 0 == dvb_usb_device_init(intf, &dibusb2_0b_properties,
118 THIS_MODULE, NULL, adapter_nr) ||
119 0 == dvb_usb_device_init(intf, &artec_t1_usb2_properties,
120 THIS_MODULE, NULL, adapter_nr))
121 return 0;
122
123 return -EINVAL;
124}
125
126/* do not change the order of the ID table */
127static struct usb_device_id dibusb_dib3000mb_table [] = {
128/* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD) },
129/* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM) },
130/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
131/* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) },
132/* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) },
133/* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) },
134/* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) },
135/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) },
136/* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) },
137/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) },
138/* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) },
139/* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) },
140/* 12 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) },
141/* 13 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) },
142/* 14 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) },
143/* 15 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_COLD) },
144/* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) },
145/* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) },
146/* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) },
147/* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
148/* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
149/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
150/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
151/* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) },
152
153/* device ID with default DIBUSB2_0-firmware and with the hacked firmware */
154/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) },
155/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) },
156/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) },
157
158/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) },
159
160/* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
161/* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) },
162
163/*
164 * XXX: As Artec just 'forgot' to program the EEPROM on some Artec T1 devices
165 * we don't catch these faulty IDs (namely 'Cypress FX1 USB controller') that
166 * have been left on the device. If you don't have such a device but an Artec
167 * device that's supposed to work with this driver but is not detected by it,
168 * free to enable CONFIG_DVB_USB_DIBUSB_MB_FAULTY via your kernel config.
169 */
170
171#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
172/* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
173#endif
174
175 { } /* Terminating entry */
176};
177MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
178
179static struct dvb_usb_device_properties dibusb1_1_properties = {
180 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
181
182 .usb_ctrl = CYPRESS_AN2135,
183
184 .firmware = "dvb-usb-dibusb-5.0.0.11.fw",
185
186 .num_adapters = 1,
187 .adapter = {
188 {
189 .num_frontends = 1,
190 .fe = {{
191 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
192 .pid_filter_count = 16,
193
194 .streaming_ctrl = dibusb_streaming_ctrl,
195 .pid_filter = dibusb_pid_filter,
196 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
197 .frontend_attach = dibusb_dib3000mb_frontend_attach,
198 .tuner_attach = dibusb_tuner_probe_and_attach,
199
200 /* parameter for the MPEG2-data transfer */
201 .stream = {
202 .type = USB_BULK,
203 .count = 7,
204 .endpoint = 0x02,
205 .u = {
206 .bulk = {
207 .buffersize = 4096,
208 }
209 }
210 },
211 }},
212 .size_of_priv = sizeof(struct dibusb_state),
213 }
214 },
215
216 .power_ctrl = dibusb_power_ctrl,
217
218 .rc.legacy = {
219 .rc_interval = DEFAULT_RC_INTERVAL,
220 .rc_map_table = rc_map_dibusb_table,
221 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
222 .rc_query = dibusb_rc_query,
223 },
224
225 .i2c_algo = &dibusb_i2c_algo,
226
227 .generic_bulk_ctrl_endpoint = 0x01,
228
229 .num_device_descs = 9,
230 .devices = {
231 { "AVerMedia AverTV DVBT USB1.1",
232 { &dibusb_dib3000mb_table[0], NULL },
233 { &dibusb_dib3000mb_table[1], NULL },
234 },
235 { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
236 { &dibusb_dib3000mb_table[2], &dibusb_dib3000mb_table[4], NULL},
237 { &dibusb_dib3000mb_table[3], NULL },
238 },
239 { "DiBcom USB1.1 DVB-T reference design (MOD3000)",
240 { &dibusb_dib3000mb_table[5], NULL },
241 { &dibusb_dib3000mb_table[6], NULL },
242 },
243 { "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
244 { &dibusb_dib3000mb_table[7], NULL },
245 { &dibusb_dib3000mb_table[8], NULL },
246 },
247 { "Grandtec USB1.1 DVB-T",
248 { &dibusb_dib3000mb_table[9], &dibusb_dib3000mb_table[11], NULL },
249 { &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL },
250 },
251 { "Unknown USB1.1 DVB-T device ???? please report the name to the author",
252 { &dibusb_dib3000mb_table[13], NULL },
253 { &dibusb_dib3000mb_table[14], NULL },
254 },
255 { "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device",
256 { &dibusb_dib3000mb_table[15], &dibusb_dib3000mb_table[17], NULL},
257 { &dibusb_dib3000mb_table[16], &dibusb_dib3000mb_table[18], NULL},
258 },
259 { "Artec T1 USB1.1 TVBOX with AN2135",
260 { &dibusb_dib3000mb_table[19], NULL },
261 { &dibusb_dib3000mb_table[20], NULL },
262 },
263 { "VideoWalker DVB-T USB",
264 { &dibusb_dib3000mb_table[25], NULL },
265 { &dibusb_dib3000mb_table[26], NULL },
266 },
267 }
268};
269
270static struct dvb_usb_device_properties dibusb1_1_an2235_properties = {
271 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
272 .usb_ctrl = CYPRESS_AN2235,
273
274 .firmware = "dvb-usb-dibusb-an2235-01.fw",
275
276 .num_adapters = 1,
277 .adapter = {
278 {
279 .num_frontends = 1,
280 .fe = {{
281 .caps = DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_ADAP_HAS_PID_FILTER,
282 .pid_filter_count = 16,
283
284 .streaming_ctrl = dibusb_streaming_ctrl,
285 .pid_filter = dibusb_pid_filter,
286 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
287 .frontend_attach = dibusb_dib3000mb_frontend_attach,
288 .tuner_attach = dibusb_tuner_probe_and_attach,
289
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 .size_of_priv = sizeof(struct dibusb_state),
303 },
304 },
305 .power_ctrl = dibusb_power_ctrl,
306
307 .rc.legacy = {
308 .rc_interval = DEFAULT_RC_INTERVAL,
309 .rc_map_table = rc_map_dibusb_table,
310 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
311 .rc_query = dibusb_rc_query,
312 },
313
314 .i2c_algo = &dibusb_i2c_algo,
315
316 .generic_bulk_ctrl_endpoint = 0x01,
317
318#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
319 .num_device_descs = 2,
320#else
321 .num_device_descs = 1,
322#endif
323 .devices = {
324 { "Artec T1 USB1.1 TVBOX with AN2235",
325 { &dibusb_dib3000mb_table[21], NULL },
326 { &dibusb_dib3000mb_table[22], NULL },
327 },
328#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
329 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
330 { &dibusb_dib3000mb_table[30], NULL },
331 { NULL },
332 },
333 { NULL },
334#endif
335 }
336};
337
338static struct dvb_usb_device_properties dibusb2_0b_properties = {
339 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
340
341 .usb_ctrl = CYPRESS_FX2,
342
343 .firmware = "dvb-usb-adstech-usb2-02.fw",
344
345 .num_adapters = 1,
346 .adapter = {
347 {
348 .num_frontends = 1,
349 .fe = {{
350 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
351 .pid_filter_count = 16,
352
353 .streaming_ctrl = dibusb2_0_streaming_ctrl,
354 .pid_filter = dibusb_pid_filter,
355 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
356 .frontend_attach = dibusb_dib3000mb_frontend_attach,
357 .tuner_attach = dibusb_thomson_tuner_attach,
358
359 /* parameter for the MPEG2-data transfer */
360 .stream = {
361 .type = USB_BULK,
362 .count = 7,
363 .endpoint = 0x06,
364 .u = {
365 .bulk = {
366 .buffersize = 4096,
367 }
368 }
369 },
370 }},
371 .size_of_priv = sizeof(struct dibusb_state),
372 }
373 },
374 .power_ctrl = dibusb2_0_power_ctrl,
375
376 .rc.legacy = {
377 .rc_interval = DEFAULT_RC_INTERVAL,
378 .rc_map_table = rc_map_dibusb_table,
379 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
380 .rc_query = dibusb_rc_query,
381 },
382
383 .i2c_algo = &dibusb_i2c_algo,
384
385 .generic_bulk_ctrl_endpoint = 0x01,
386
387 .num_device_descs = 2,
388 .devices = {
389 { "KWorld/ADSTech Instant DVB-T USB2.0",
390 { &dibusb_dib3000mb_table[23], NULL },
391 { &dibusb_dib3000mb_table[24], NULL },
392 },
393 { "KWorld Xpert DVB-T USB2.0",
394 { &dibusb_dib3000mb_table[27], NULL },
395 { NULL }
396 },
397 { NULL },
398 }
399};
400
401static struct dvb_usb_device_properties artec_t1_usb2_properties = {
402 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
403
404 .usb_ctrl = CYPRESS_FX2,
405
406 .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
407
408 .num_adapters = 1,
409 .adapter = {
410 {
411 .num_frontends = 1,
412 .fe = {{
413 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
414 .pid_filter_count = 16,
415
416 .streaming_ctrl = dibusb2_0_streaming_ctrl,
417 .pid_filter = dibusb_pid_filter,
418 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
419 .frontend_attach = dibusb_dib3000mb_frontend_attach,
420 .tuner_attach = dibusb_tuner_probe_and_attach,
421 /* parameter for the MPEG2-data transfer */
422 .stream = {
423 .type = USB_BULK,
424 .count = 7,
425 .endpoint = 0x06,
426 .u = {
427 .bulk = {
428 .buffersize = 4096,
429 }
430 }
431 },
432 }},
433 .size_of_priv = sizeof(struct dibusb_state),
434 }
435 },
436 .power_ctrl = dibusb2_0_power_ctrl,
437
438 .rc.legacy = {
439 .rc_interval = DEFAULT_RC_INTERVAL,
440 .rc_map_table = rc_map_dibusb_table,
441 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
442 .rc_query = dibusb_rc_query,
443 },
444
445 .i2c_algo = &dibusb_i2c_algo,
446
447 .generic_bulk_ctrl_endpoint = 0x01,
448
449 .num_device_descs = 1,
450 .devices = {
451 { "Artec T1 USB2.0",
452 { &dibusb_dib3000mb_table[28], NULL },
453 { &dibusb_dib3000mb_table[29], NULL },
454 },
455 { NULL },
456 }
457};
458
459static struct usb_driver dibusb_driver = {
460 .name = "dvb_usb_dibusb_mb",
461 .probe = dibusb_probe,
462 .disconnect = dvb_usb_device_exit,
463 .id_table = dibusb_dib3000mb_table,
464};
465
466module_usb_driver(dibusb_driver);
467
468MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
469MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)");
470MODULE_VERSION("1.0");
471MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dibusb-mc.c b/drivers/media/usb/dvb-usb/dibusb-mc.c
new file mode 100644
index 000000000000..9d1a59d09c52
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dibusb-mc.c
@@ -0,0 +1,149 @@
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 .num_frontends = 1,
61 .fe = {{
62 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
63 .pid_filter_count = 32,
64 .streaming_ctrl = dibusb2_0_streaming_ctrl,
65 .pid_filter = dibusb_pid_filter,
66 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
67 .frontend_attach = dibusb_dib3000mc_frontend_attach,
68 .tuner_attach = dibusb_dib3000mc_tuner_attach,
69
70 /* parameter for the MPEG2-data transfer */
71 .stream = {
72 .type = USB_BULK,
73 .count = 8,
74 .endpoint = 0x06,
75 .u = {
76 .bulk = {
77 .buffersize = 4096,
78 }
79 }
80 },
81 }},
82 .size_of_priv = sizeof(struct dibusb_state),
83 }
84 },
85 .power_ctrl = dibusb2_0_power_ctrl,
86
87 .rc.legacy = {
88 .rc_interval = DEFAULT_RC_INTERVAL,
89 .rc_map_table = rc_map_dibusb_table,
90 .rc_map_size = 111, /* FIXME */
91 .rc_query = dibusb_rc_query,
92 },
93
94 .i2c_algo = &dibusb_i2c_algo,
95
96 .generic_bulk_ctrl_endpoint = 0x01,
97
98 .num_device_descs = 8,
99 .devices = {
100 { "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
101 { &dibusb_dib3000mc_table[0], NULL },
102 { &dibusb_dib3000mc_table[1], NULL },
103 },
104 { "Artec T1 USB2.0 TVBOX (please check the warm ID)",
105 { &dibusb_dib3000mc_table[2], NULL },
106 { &dibusb_dib3000mc_table[3], NULL },
107 },
108 { "LITE-ON USB2.0 DVB-T Tuner",
109 /* Also rebranded as Intuix S800, Toshiba */
110 { &dibusb_dib3000mc_table[4], NULL },
111 { &dibusb_dib3000mc_table[5], NULL },
112 },
113 { "MSI Digivox Mini SL",
114 { &dibusb_dib3000mc_table[6], NULL },
115 { &dibusb_dib3000mc_table[7], NULL },
116 },
117 { "GRAND - USB2.0 DVB-T adapter",
118 { &dibusb_dib3000mc_table[8], NULL },
119 { &dibusb_dib3000mc_table[9], NULL },
120 },
121 { "Artec T14 - USB2.0 DVB-T",
122 { &dibusb_dib3000mc_table[10], NULL },
123 { &dibusb_dib3000mc_table[11], NULL },
124 },
125 { "Leadtek - USB2.0 Winfast DTV dongle",
126 { &dibusb_dib3000mc_table[12], NULL },
127 { &dibusb_dib3000mc_table[13], NULL },
128 },
129 { "Humax/Coex DVB-T USB Stick 2.0 High Speed",
130 { &dibusb_dib3000mc_table[14], NULL },
131 { &dibusb_dib3000mc_table[15], NULL },
132 },
133 { NULL },
134 }
135};
136
137static struct usb_driver dibusb_mc_driver = {
138 .name = "dvb_usb_dibusb_mc",
139 .probe = dibusb_mc_probe,
140 .disconnect = dvb_usb_device_exit,
141 .id_table = dibusb_dib3000mc_table,
142};
143
144module_usb_driver(dibusb_mc_driver);
145
146MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
147MODULE_DESCRIPTION("Driver for DiBcom USB2.0 DVB-T (DiB3000M-C/P based) devices");
148MODULE_VERSION("1.0");
149MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dibusb.h b/drivers/media/usb/dvb-usb/dibusb.h
new file mode 100644
index 000000000000..e47c321b3ffc
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/digitv.c b/drivers/media/usb/dvb-usb/digitv.c
new file mode 100644
index 000000000000..ff34419a4c88
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/digitv.c
@@ -0,0 +1,354 @@
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)
122{
123 struct dvb_usb_adapter *adap = fe->dvb->priv;
124 u8 b[5];
125
126 fe->ops.tuner_ops.calc_regs(fe, 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 adap->fe_adap[0].fe = dvb_attach(mt352_attach, &digitv_mt352_config,
141 &adap->dev->i2c_adap);
142 if ((adap->fe_adap[0].fe) != NULL) {
143 st->is_nxt6000 = 0;
144 return 0;
145 }
146 adap->fe_adap[0].fe = dvb_attach(nxt6000_attach,
147 &digitv_nxt6000_config,
148 &adap->dev->i2c_adap);
149 if ((adap->fe_adap[0].fe) != NULL) {
150 st->is_nxt6000 = 1;
151 return 0;
152 }
153 return -EIO;
154}
155
156static int digitv_tuner_attach(struct dvb_usb_adapter *adap)
157{
158 struct digitv_state *st = adap->dev->priv;
159
160 if (!dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, NULL, DVB_PLL_TDED4))
161 return -ENODEV;
162
163 if (st->is_nxt6000)
164 adap->fe_adap[0].fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params;
165
166 return 0;
167}
168
169static struct rc_map_table rc_map_digitv_table[] = {
170 { 0x5f55, KEY_0 },
171 { 0x6f55, KEY_1 },
172 { 0x9f55, KEY_2 },
173 { 0xaf55, KEY_3 },
174 { 0x5f56, KEY_4 },
175 { 0x6f56, KEY_5 },
176 { 0x9f56, KEY_6 },
177 { 0xaf56, KEY_7 },
178 { 0x5f59, KEY_8 },
179 { 0x6f59, KEY_9 },
180 { 0x9f59, KEY_TV },
181 { 0xaf59, KEY_AUX },
182 { 0x5f5a, KEY_DVD },
183 { 0x6f5a, KEY_POWER },
184 { 0x9f5a, KEY_CAMERA }, /* labelled 'Picture' */
185 { 0xaf5a, KEY_AUDIO },
186 { 0x5f65, KEY_INFO },
187 { 0x6f65, KEY_F13 }, /* 16:9 */
188 { 0x9f65, KEY_F14 }, /* 14:9 */
189 { 0xaf65, KEY_EPG },
190 { 0x5f66, KEY_EXIT },
191 { 0x6f66, KEY_MENU },
192 { 0x9f66, KEY_UP },
193 { 0xaf66, KEY_DOWN },
194 { 0x5f69, KEY_LEFT },
195 { 0x6f69, KEY_RIGHT },
196 { 0x9f69, KEY_ENTER },
197 { 0xaf69, KEY_CHANNELUP },
198 { 0x5f6a, KEY_CHANNELDOWN },
199 { 0x6f6a, KEY_VOLUMEUP },
200 { 0x9f6a, KEY_VOLUMEDOWN },
201 { 0xaf6a, KEY_RED },
202 { 0x5f95, KEY_GREEN },
203 { 0x6f95, KEY_YELLOW },
204 { 0x9f95, KEY_BLUE },
205 { 0xaf95, KEY_SUBTITLE },
206 { 0x5f96, KEY_F15 }, /* AD */
207 { 0x6f96, KEY_TEXT },
208 { 0x9f96, KEY_MUTE },
209 { 0xaf96, KEY_REWIND },
210 { 0x5f99, KEY_STOP },
211 { 0x6f99, KEY_PLAY },
212 { 0x9f99, KEY_FASTFORWARD },
213 { 0xaf99, KEY_F16 }, /* chapter */
214 { 0x5f9a, KEY_PAUSE },
215 { 0x6f9a, KEY_PLAY },
216 { 0x9f9a, KEY_RECORD },
217 { 0xaf9a, KEY_F17 }, /* picture in picture */
218 { 0x5fa5, KEY_KPPLUS }, /* zoom in */
219 { 0x6fa5, KEY_KPMINUS }, /* zoom out */
220 { 0x9fa5, KEY_F18 }, /* capture */
221 { 0xafa5, KEY_F19 }, /* web */
222 { 0x5fa6, KEY_EMAIL },
223 { 0x6fa6, KEY_PHONE },
224 { 0x9fa6, KEY_PC },
225};
226
227static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
228{
229 int i;
230 u8 key[5];
231 u8 b[4] = { 0 };
232
233 *event = 0;
234 *state = REMOTE_NO_KEY_PRESSED;
235
236 digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4);
237
238 /* Tell the device we've read the remote. Not sure how necessary
239 this is, but the Nebula SDK does it. */
240 digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
241
242 /* if something is inside the buffer, simulate key press */
243 if (key[1] != 0)
244 {
245 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
246 if (rc5_custom(&d->props.rc.legacy.rc_map_table[i]) == key[1] &&
247 rc5_data(&d->props.rc.legacy.rc_map_table[i]) == key[2]) {
248 *event = d->props.rc.legacy.rc_map_table[i].keycode;
249 *state = REMOTE_KEY_PRESSED;
250 return 0;
251 }
252 }
253 }
254
255 if (key[0] != 0)
256 deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
257 return 0;
258}
259
260/* DVB USB Driver stuff */
261static struct dvb_usb_device_properties digitv_properties;
262
263static int digitv_probe(struct usb_interface *intf,
264 const struct usb_device_id *id)
265{
266 struct dvb_usb_device *d;
267 int ret = dvb_usb_device_init(intf, &digitv_properties, THIS_MODULE, &d,
268 adapter_nr);
269 if (ret == 0) {
270 u8 b[4] = { 0 };
271
272 if (d != NULL) { /* do that only when the firmware is loaded */
273 b[0] = 1;
274 digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
275
276 b[0] = 0;
277 digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
278 }
279 }
280 return ret;
281}
282
283static struct usb_device_id digitv_table [] = {
284 { USB_DEVICE(USB_VID_ANCHOR, USB_PID_NEBULA_DIGITV) },
285 { } /* Terminating entry */
286};
287MODULE_DEVICE_TABLE (usb, digitv_table);
288
289static struct dvb_usb_device_properties digitv_properties = {
290 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
291
292 .usb_ctrl = CYPRESS_FX2,
293 .firmware = "dvb-usb-digitv-02.fw",
294
295 .size_of_priv = sizeof(struct digitv_state),
296
297 .num_adapters = 1,
298 .adapter = {
299 {
300 .num_frontends = 1,
301 .fe = {{
302 .frontend_attach = digitv_frontend_attach,
303 .tuner_attach = digitv_tuner_attach,
304
305 /* parameter for the MPEG2-data transfer */
306 .stream = {
307 .type = USB_BULK,
308 .count = 7,
309 .endpoint = 0x02,
310 .u = {
311 .bulk = {
312 .buffersize = 4096,
313 }
314 }
315 },
316 }},
317 }
318 },
319 .identify_state = digitv_identify_state,
320
321 .rc.legacy = {
322 .rc_interval = 1000,
323 .rc_map_table = rc_map_digitv_table,
324 .rc_map_size = ARRAY_SIZE(rc_map_digitv_table),
325 .rc_query = digitv_rc_query,
326 },
327
328 .i2c_algo = &digitv_i2c_algo,
329
330 .generic_bulk_ctrl_endpoint = 0x01,
331
332 .num_device_descs = 1,
333 .devices = {
334 { "Nebula Electronics uDigiTV DVB-T USB2.0)",
335 { &digitv_table[0], NULL },
336 { NULL },
337 },
338 { NULL },
339 }
340};
341
342static struct usb_driver digitv_driver = {
343 .name = "dvb_usb_digitv",
344 .probe = digitv_probe,
345 .disconnect = dvb_usb_device_exit,
346 .id_table = digitv_table,
347};
348
349module_usb_driver(digitv_driver);
350
351MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
352MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0");
353MODULE_VERSION("1.0-alpha");
354MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/digitv.h b/drivers/media/usb/dvb-usb/digitv.h
new file mode 100644
index 000000000000..908c09f4966b
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/dtt200u-fe.c b/drivers/media/usb/dvb-usb/dtt200u-fe.c
new file mode 100644
index 000000000000..3d81daa49172
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dtt200u-fe.c
@@ -0,0 +1,210 @@
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 dtv_frontend_properties 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{
105 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
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->bandwidth_hz) {
113 case 8000000:
114 bwbuf[1] = 8;
115 break;
116 case 7000000:
117 bwbuf[1] = 7;
118 break;
119 case 6000000:
120 bwbuf[1] = 6;
121 break;
122 default:
123 return -EINVAL;
124 }
125
126 dvb_usb_generic_write(state->d,bwbuf,2);
127
128 freqbuf[1] = freq & 0xff;
129 freqbuf[2] = (freq >> 8) & 0xff;
130 dvb_usb_generic_write(state->d,freqbuf,3);
131
132 for (i = 0; i < 30; i++) {
133 msleep(20);
134 dtt200u_fe_read_status(fe, &st);
135 if (st & FE_TIMEDOUT)
136 continue;
137 }
138
139 return 0;
140}
141
142static int dtt200u_fe_get_frontend(struct dvb_frontend* fe)
143{
144 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
145 struct dtt200u_fe_state *state = fe->demodulator_priv;
146 memcpy(fep, &state->fep, sizeof(struct dtv_frontend_properties));
147 return 0;
148}
149
150static void dtt200u_fe_release(struct dvb_frontend* fe)
151{
152 struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
153 kfree(state);
154}
155
156static struct dvb_frontend_ops dtt200u_fe_ops;
157
158struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
159{
160 struct dtt200u_fe_state* state = NULL;
161
162 /* allocate memory for the internal state */
163 state = kzalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL);
164 if (state == NULL)
165 goto error;
166
167 deb_info("attaching frontend dtt200u\n");
168
169 state->d = d;
170
171 memcpy(&state->frontend.ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops));
172 state->frontend.demodulator_priv = state;
173
174 return &state->frontend;
175error:
176 return NULL;
177}
178
179static struct dvb_frontend_ops dtt200u_fe_ops = {
180 .delsys = { SYS_DVBT },
181 .info = {
182 .name = "WideView USB DVB-T",
183 .frequency_min = 44250000,
184 .frequency_max = 867250000,
185 .frequency_stepsize = 250000,
186 .caps = FE_CAN_INVERSION_AUTO |
187 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
188 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
189 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
190 FE_CAN_TRANSMISSION_MODE_AUTO |
191 FE_CAN_GUARD_INTERVAL_AUTO |
192 FE_CAN_RECOVER |
193 FE_CAN_HIERARCHY_AUTO,
194 },
195
196 .release = dtt200u_fe_release,
197
198 .init = dtt200u_fe_init,
199 .sleep = dtt200u_fe_sleep,
200
201 .set_frontend = dtt200u_fe_set_frontend,
202 .get_frontend = dtt200u_fe_get_frontend,
203 .get_tune_settings = dtt200u_fe_get_tune_settings,
204
205 .read_status = dtt200u_fe_read_status,
206 .read_ber = dtt200u_fe_read_ber,
207 .read_signal_strength = dtt200u_fe_read_signal_strength,
208 .read_snr = dtt200u_fe_read_snr,
209 .read_ucblocks = dtt200u_fe_read_unc_blocks,
210};
diff --git a/drivers/media/usb/dvb-usb/dtt200u.c b/drivers/media/usb/dvb-usb/dtt200u.c
new file mode 100644
index 000000000000..66f205c112b2
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dtt200u.c
@@ -0,0 +1,368 @@
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_adap[0].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 .num_frontends = 1,
144 .fe = {{
145 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
146 .pid_filter_count = 15,
147
148 .streaming_ctrl = dtt200u_streaming_ctrl,
149 .pid_filter = dtt200u_pid_filter,
150 .frontend_attach = dtt200u_frontend_attach,
151 /* parameter for the MPEG2-data transfer */
152 .stream = {
153 .type = USB_BULK,
154 .count = 7,
155 .endpoint = 0x02,
156 .u = {
157 .bulk = {
158 .buffersize = 4096,
159 }
160 }
161 },
162 }},
163 }
164 },
165 .power_ctrl = dtt200u_power_ctrl,
166
167 .rc.legacy = {
168 .rc_interval = 300,
169 .rc_map_table = rc_map_dtt200u_table,
170 .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
171 .rc_query = dtt200u_rc_query,
172 },
173
174 .generic_bulk_ctrl_endpoint = 0x01,
175
176 .num_device_descs = 1,
177 .devices = {
178 { .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)",
179 .cold_ids = { &dtt200u_usb_table[0], NULL },
180 .warm_ids = { &dtt200u_usb_table[1], NULL },
181 },
182 { NULL },
183 }
184};
185
186static struct dvb_usb_device_properties wt220u_properties = {
187 .usb_ctrl = CYPRESS_FX2,
188 .firmware = "dvb-usb-wt220u-02.fw",
189
190 .num_adapters = 1,
191 .adapter = {
192 {
193 .num_frontends = 1,
194 .fe = {{
195 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
196 .pid_filter_count = 15,
197
198 .streaming_ctrl = dtt200u_streaming_ctrl,
199 .pid_filter = dtt200u_pid_filter,
200 .frontend_attach = dtt200u_frontend_attach,
201 /* parameter for the MPEG2-data transfer */
202 .stream = {
203 .type = USB_BULK,
204 .count = 7,
205 .endpoint = 0x02,
206 .u = {
207 .bulk = {
208 .buffersize = 4096,
209 }
210 }
211 },
212 }},
213 }
214 },
215 .power_ctrl = dtt200u_power_ctrl,
216
217 .rc.legacy = {
218 .rc_interval = 300,
219 .rc_map_table = rc_map_dtt200u_table,
220 .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
221 .rc_query = dtt200u_rc_query,
222 },
223
224 .generic_bulk_ctrl_endpoint = 0x01,
225
226 .num_device_descs = 1,
227 .devices = {
228 { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
229 .cold_ids = { &dtt200u_usb_table[2], &dtt200u_usb_table[8], NULL },
230 .warm_ids = { &dtt200u_usb_table[3], NULL },
231 },
232 { NULL },
233 }
234};
235
236static struct dvb_usb_device_properties wt220u_fc_properties = {
237 .usb_ctrl = CYPRESS_FX2,
238 .firmware = "dvb-usb-wt220u-fc03.fw",
239
240 .num_adapters = 1,
241 .adapter = {
242 {
243 .num_frontends = 1,
244 .fe = {{
245 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
246 .pid_filter_count = 15,
247
248 .streaming_ctrl = dtt200u_streaming_ctrl,
249 .pid_filter = dtt200u_pid_filter,
250 .frontend_attach = dtt200u_frontend_attach,
251 /* parameter for the MPEG2-data transfer */
252 .stream = {
253 .type = USB_BULK,
254 .count = 7,
255 .endpoint = 0x06,
256 .u = {
257 .bulk = {
258 .buffersize = 4096,
259 }
260 }
261 },
262 }},
263 }
264 },
265 .power_ctrl = dtt200u_power_ctrl,
266
267 .rc.legacy = {
268 .rc_interval = 300,
269 .rc_map_table = rc_map_dtt200u_table,
270 .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
271 .rc_query = dtt200u_rc_query,
272 },
273
274 .generic_bulk_ctrl_endpoint = 0x01,
275
276 .num_device_descs = 1,
277 .devices = {
278 { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
279 .cold_ids = { &dtt200u_usb_table[6], NULL },
280 .warm_ids = { &dtt200u_usb_table[7], NULL },
281 },
282 { NULL },
283 }
284};
285
286static struct dvb_usb_device_properties wt220u_zl0353_properties = {
287 .usb_ctrl = CYPRESS_FX2,
288 .firmware = "dvb-usb-wt220u-zl0353-01.fw",
289
290 .num_adapters = 1,
291 .adapter = {
292 {
293 .num_frontends = 1,
294 .fe = {{
295 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
296 .pid_filter_count = 15,
297
298 .streaming_ctrl = dtt200u_streaming_ctrl,
299 .pid_filter = dtt200u_pid_filter,
300 .frontend_attach = dtt200u_frontend_attach,
301 /* parameter for the MPEG2-data transfer */
302 .stream = {
303 .type = USB_BULK,
304 .count = 7,
305 .endpoint = 0x02,
306 .u = {
307 .bulk = {
308 .buffersize = 4096,
309 }
310 }
311 },
312 }},
313 }
314 },
315 .power_ctrl = dtt200u_power_ctrl,
316
317 .rc.legacy = {
318 .rc_interval = 300,
319 .rc_map_table = rc_map_dtt200u_table,
320 .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
321 .rc_query = dtt200u_rc_query,
322 },
323
324 .generic_bulk_ctrl_endpoint = 0x01,
325
326 .num_device_descs = 1,
327 .devices = {
328 { .name = "WideView WT-220U PenType Receiver (based on ZL353)",
329 .cold_ids = { &dtt200u_usb_table[4], NULL },
330 .warm_ids = { &dtt200u_usb_table[5], NULL },
331 },
332 { NULL },
333 }
334};
335
336static struct dvb_usb_device_properties wt220u_miglia_properties = {
337 .usb_ctrl = CYPRESS_FX2,
338 .firmware = "dvb-usb-wt220u-miglia-01.fw",
339
340 .num_adapters = 1,
341 .generic_bulk_ctrl_endpoint = 0x01,
342
343 .num_device_descs = 1,
344 .devices = {
345 { .name = "WideView WT-220U PenType Receiver (Miglia)",
346 .cold_ids = { &dtt200u_usb_table[9], NULL },
347 /* This device turns into WT220U_ZL0353_WARM when fw
348 has been uploaded */
349 .warm_ids = { NULL },
350 },
351 { NULL },
352 }
353};
354
355/* usb specific object needed to register this driver with the usb subsystem */
356static struct usb_driver dtt200u_usb_driver = {
357 .name = "dvb_usb_dtt200u",
358 .probe = dtt200u_usb_probe,
359 .disconnect = dvb_usb_device_exit,
360 .id_table = dtt200u_usb_table,
361};
362
363module_usb_driver(dtt200u_usb_driver);
364
365MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
366MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D/Miglia DVB-T USB2.0 devices");
367MODULE_VERSION("1.0");
368MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dtt200u.h b/drivers/media/usb/dvb-usb/dtt200u.h
new file mode 100644
index 000000000000..005b0a7df358
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/dtv5100.c b/drivers/media/usb/dvb-usb/dtv5100.c
new file mode 100644
index 000000000000..3d11df41cac0
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dtv5100.c
@@ -0,0 +1,224 @@
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_adap[0].fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config,
119 &adap->dev->i2c_adap);
120 if (adap->fe_adap[0].fe == NULL)
121 return -EIO;
122
123 /* disable i2c gate, or it won't work... is this safe? */
124 adap->fe_adap[0].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[0].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 .num_frontends = 1,
184 .fe = {{
185 .frontend_attach = dtv5100_frontend_attach,
186 .tuner_attach = dtv5100_tuner_attach,
187
188 .stream = {
189 .type = USB_BULK,
190 .count = 8,
191 .endpoint = 0x82,
192 .u = {
193 .bulk = {
194 .buffersize = 4096,
195 }
196 }
197 },
198 }},
199 } },
200
201 .i2c_algo = &dtv5100_i2c_algo,
202
203 .num_device_descs = 1,
204 .devices = {
205 {
206 .name = "AME DTV-5100 USB2.0 DVB-T",
207 .cold_ids = { NULL },
208 .warm_ids = { &dtv5100_table[0], NULL },
209 },
210 }
211};
212
213static struct usb_driver dtv5100_driver = {
214 .name = "dvb_usb_dtv5100",
215 .probe = dtv5100_probe,
216 .disconnect = dvb_usb_device_exit,
217 .id_table = dtv5100_table,
218};
219
220module_usb_driver(dtv5100_driver);
221
222MODULE_AUTHOR(DRIVER_AUTHOR);
223MODULE_DESCRIPTION(DRIVER_DESC);
224MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dtv5100.h b/drivers/media/usb/dvb-usb/dtv5100.h
new file mode 100644
index 000000000000..93e96e04a82a
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/dvb-usb-common.h b/drivers/media/usb/dvb-usb/dvb-usb-common.h
new file mode 100644
index 000000000000..6b7b2a89242e
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c
new file mode 100644
index 000000000000..719413b15f20
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c
@@ -0,0 +1,288 @@
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 if ((adap->active_fe < 0) ||
21 (adap->active_fe >= adap->num_frontends_initialized)) {
22 return -EINVAL;
23 }
24
25 newfeedcount = adap->feedcount + (onoff ? 1 : -1);
26
27 /* stop feed before setting a new pid if there will be no pid anymore */
28 if (newfeedcount == 0) {
29 deb_ts("stop feeding\n");
30 usb_urb_kill(&adap->fe_adap[adap->active_fe].stream);
31
32 if (adap->props.fe[adap->active_fe].streaming_ctrl != NULL) {
33 ret = adap->props.fe[adap->active_fe].streaming_ctrl(adap, 0);
34 if (ret < 0) {
35 err("error while stopping stream.");
36 return ret;
37 }
38 }
39 }
40
41 adap->feedcount = newfeedcount;
42
43 /* activate the pid on the device specific pid_filter */
44 deb_ts("setting pid (%s): %5d %04x at index %d '%s'\n",
45 adap->fe_adap[adap->active_fe].pid_filtering ?
46 "yes" : "no", dvbdmxfeed->pid, dvbdmxfeed->pid,
47 dvbdmxfeed->index, onoff ? "on" : "off");
48 if (adap->props.fe[adap->active_fe].caps & DVB_USB_ADAP_HAS_PID_FILTER &&
49 adap->fe_adap[adap->active_fe].pid_filtering &&
50 adap->props.fe[adap->active_fe].pid_filter != NULL)
51 adap->props.fe[adap->active_fe].pid_filter(adap, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
52
53 /* start the feed if this was the first feed and there is still a feed
54 * for reception.
55 */
56 if (adap->feedcount == onoff && adap->feedcount > 0) {
57 deb_ts("submitting all URBs\n");
58 usb_urb_submit(&adap->fe_adap[adap->active_fe].stream);
59
60 deb_ts("controlling pid parser\n");
61 if (adap->props.fe[adap->active_fe].caps & DVB_USB_ADAP_HAS_PID_FILTER &&
62 adap->props.fe[adap->active_fe].caps &
63 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
64 adap->props.fe[adap->active_fe].pid_filter_ctrl != NULL) {
65 ret = adap->props.fe[adap->active_fe].pid_filter_ctrl(adap,
66 adap->fe_adap[adap->active_fe].pid_filtering);
67 if (ret < 0) {
68 err("could not handle pid_parser");
69 return ret;
70 }
71 }
72 deb_ts("start feeding\n");
73 if (adap->props.fe[adap->active_fe].streaming_ctrl != NULL) {
74 ret = adap->props.fe[adap->active_fe].streaming_ctrl(adap, 1);
75 if (ret < 0) {
76 err("error while enabling fifo.");
77 return ret;
78 }
79 }
80
81 }
82 return 0;
83}
84
85static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
86{
87 deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
88 return dvb_usb_ctrl_feed(dvbdmxfeed,1);
89}
90
91static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
92{
93 deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
94 return dvb_usb_ctrl_feed(dvbdmxfeed,0);
95}
96
97int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums)
98{
99 int i;
100 int ret = dvb_register_adapter(&adap->dvb_adap, adap->dev->desc->name,
101 adap->dev->owner, &adap->dev->udev->dev,
102 adapter_nums);
103
104 if (ret < 0) {
105 deb_info("dvb_register_adapter failed: error %d", ret);
106 goto err;
107 }
108 adap->dvb_adap.priv = adap;
109
110 if (adap->dev->props.read_mac_address) {
111 if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0)
112 info("MAC address: %pM",adap->dvb_adap.proposed_mac);
113 else
114 err("MAC address reading failed.");
115 }
116
117
118 adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
119 adap->demux.priv = adap;
120
121 adap->demux.filternum = 0;
122 for (i = 0; i < adap->props.num_frontends; i++) {
123 if (adap->demux.filternum < adap->fe_adap[i].max_feed_count)
124 adap->demux.filternum = adap->fe_adap[i].max_feed_count;
125 }
126 adap->demux.feednum = adap->demux.filternum;
127 adap->demux.start_feed = dvb_usb_start_feed;
128 adap->demux.stop_feed = dvb_usb_stop_feed;
129 adap->demux.write_to_decoder = NULL;
130 if ((ret = dvb_dmx_init(&adap->demux)) < 0) {
131 err("dvb_dmx_init failed: error %d",ret);
132 goto err_dmx;
133 }
134
135 adap->dmxdev.filternum = adap->demux.filternum;
136 adap->dmxdev.demux = &adap->demux.dmx;
137 adap->dmxdev.capabilities = 0;
138 if ((ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap)) < 0) {
139 err("dvb_dmxdev_init failed: error %d",ret);
140 goto err_dmx_dev;
141 }
142
143 if ((ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net,
144 &adap->demux.dmx)) < 0) {
145 err("dvb_net_init failed: error %d",ret);
146 goto err_net_init;
147 }
148
149 adap->state |= DVB_USB_ADAP_STATE_DVB;
150 return 0;
151
152err_net_init:
153 dvb_dmxdev_release(&adap->dmxdev);
154err_dmx_dev:
155 dvb_dmx_release(&adap->demux);
156err_dmx:
157 dvb_unregister_adapter(&adap->dvb_adap);
158err:
159 return ret;
160}
161
162int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap)
163{
164 if (adap->state & DVB_USB_ADAP_STATE_DVB) {
165 deb_info("unregistering DVB part\n");
166 dvb_net_release(&adap->dvb_net);
167 adap->demux.dmx.close(&adap->demux.dmx);
168 dvb_dmxdev_release(&adap->dmxdev);
169 dvb_dmx_release(&adap->demux);
170 dvb_unregister_adapter(&adap->dvb_adap);
171 adap->state &= ~DVB_USB_ADAP_STATE_DVB;
172 }
173 return 0;
174}
175
176static int dvb_usb_set_active_fe(struct dvb_frontend *fe, int onoff)
177{
178 struct dvb_usb_adapter *adap = fe->dvb->priv;
179
180 int ret = (adap->props.frontend_ctrl) ?
181 adap->props.frontend_ctrl(fe, onoff) : 0;
182
183 if (ret < 0) {
184 err("frontend_ctrl request failed");
185 return ret;
186 }
187 if (onoff)
188 adap->active_fe = fe->id;
189
190 return 0;
191}
192
193static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
194{
195 struct dvb_usb_adapter *adap = fe->dvb->priv;
196
197 dvb_usb_device_power_ctrl(adap->dev, 1);
198
199 dvb_usb_set_active_fe(fe, 1);
200
201 if (adap->fe_adap[fe->id].fe_init)
202 adap->fe_adap[fe->id].fe_init(fe);
203
204 return 0;
205}
206
207static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
208{
209 struct dvb_usb_adapter *adap = fe->dvb->priv;
210
211 if (adap->fe_adap[fe->id].fe_sleep)
212 adap->fe_adap[fe->id].fe_sleep(fe);
213
214 dvb_usb_set_active_fe(fe, 0);
215
216 return dvb_usb_device_power_ctrl(adap->dev, 0);
217}
218
219int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
220{
221 int ret, i;
222
223 /* register all given adapter frontends */
224 for (i = 0; i < adap->props.num_frontends; i++) {
225
226 if (adap->props.fe[i].frontend_attach == NULL) {
227 err("strange: '%s' #%d,%d "
228 "doesn't want to attach a frontend.",
229 adap->dev->desc->name, adap->id, i);
230
231 return 0;
232 }
233
234 ret = adap->props.fe[i].frontend_attach(adap);
235 if (ret || adap->fe_adap[i].fe == NULL) {
236 /* only print error when there is no FE at all */
237 if (i == 0)
238 err("no frontend was attached by '%s'",
239 adap->dev->desc->name);
240
241 return 0;
242 }
243
244 adap->fe_adap[i].fe->id = i;
245
246 /* re-assign sleep and wakeup functions */
247 adap->fe_adap[i].fe_init = adap->fe_adap[i].fe->ops.init;
248 adap->fe_adap[i].fe->ops.init = dvb_usb_fe_wakeup;
249 adap->fe_adap[i].fe_sleep = adap->fe_adap[i].fe->ops.sleep;
250 adap->fe_adap[i].fe->ops.sleep = dvb_usb_fe_sleep;
251
252 if (dvb_register_frontend(&adap->dvb_adap, adap->fe_adap[i].fe)) {
253 err("Frontend %d registration failed.", i);
254 dvb_frontend_detach(adap->fe_adap[i].fe);
255 adap->fe_adap[i].fe = NULL;
256 /* In error case, do not try register more FEs,
257 * still leaving already registered FEs alive. */
258 if (i == 0)
259 return -ENODEV;
260 else
261 return 0;
262 }
263
264 /* only attach the tuner if the demod is there */
265 if (adap->props.fe[i].tuner_attach != NULL)
266 adap->props.fe[i].tuner_attach(adap);
267
268 adap->num_frontends_initialized++;
269 }
270
271 return 0;
272}
273
274int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap)
275{
276 int i = adap->num_frontends_initialized - 1;
277
278 /* unregister all given adapter frontends */
279 for (; i >= 0; i--) {
280 if (adap->fe_adap[i].fe != NULL) {
281 dvb_unregister_frontend(adap->fe_adap[i].fe);
282 dvb_frontend_detach(adap->fe_adap[i].fe);
283 }
284 }
285 adap->num_frontends_initialized = 0;
286
287 return 0;
288}
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
new file mode 100644
index 000000000000..733a7ff7b207
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/dvb-usb-i2c.c b/drivers/media/usb/dvb-usb/dvb-usb-i2c.c
new file mode 100644
index 000000000000..88e4a62abc44
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c
new file mode 100644
index 000000000000..169196ec2d4e
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c
@@ -0,0 +1,304 @@
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, o;
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 for (o = 0; o < adap->props.num_frontends; o++) {
42 struct dvb_usb_adapter_fe_properties *props = &adap->props.fe[o];
43 /* speed - when running at FULL speed we need a HW PID filter */
44 if (d->udev->speed == USB_SPEED_FULL && !(props->caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
45 err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)");
46 return -ENODEV;
47 }
48
49 if ((d->udev->speed == USB_SPEED_FULL && props->caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
50 (props->caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
51 info("will use the device's hardware PID filter (table count: %d).", props->pid_filter_count);
52 adap->fe_adap[o].pid_filtering = 1;
53 adap->fe_adap[o].max_feed_count = props->pid_filter_count;
54 } else {
55 info("will pass the complete MPEG2 transport stream to the software demuxer.");
56 adap->fe_adap[o].pid_filtering = 0;
57 adap->fe_adap[o].max_feed_count = 255;
58 }
59
60 if (!adap->fe_adap[o].pid_filtering &&
61 dvb_usb_force_pid_filter_usage &&
62 props->caps & DVB_USB_ADAP_HAS_PID_FILTER) {
63 info("pid filter enabled by module option.");
64 adap->fe_adap[o].pid_filtering = 1;
65 adap->fe_adap[o].max_feed_count = props->pid_filter_count;
66 }
67
68 if (props->size_of_priv > 0) {
69 adap->fe_adap[o].priv = kzalloc(props->size_of_priv, GFP_KERNEL);
70 if (adap->fe_adap[o].priv == NULL) {
71 err("no memory for priv for adapter %d fe %d.", n, o);
72 return -ENOMEM;
73 }
74 }
75 }
76
77 if (adap->props.size_of_priv > 0) {
78 adap->priv = kzalloc(adap->props.size_of_priv, GFP_KERNEL);
79 if (adap->priv == NULL) {
80 err("no memory for priv for adapter %d.", n);
81 return -ENOMEM;
82 }
83 }
84
85 if ((ret = dvb_usb_adapter_stream_init(adap)) ||
86 (ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) ||
87 (ret = dvb_usb_adapter_frontend_init(adap))) {
88 return ret;
89 }
90
91 /* use exclusive FE lock if there is multiple shared FEs */
92 if (adap->fe_adap[1].fe)
93 adap->dvb_adap.mfe_shared = 1;
94
95 d->num_adapters_initialized++;
96 d->state |= DVB_USB_STATE_DVB;
97 }
98
99 /*
100 * when reloading the driver w/o replugging the device
101 * sometimes a timeout occures, this helps
102 */
103 if (d->props.generic_bulk_ctrl_endpoint != 0) {
104 usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
105 usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
106 }
107
108 return 0;
109}
110
111static int dvb_usb_adapter_exit(struct dvb_usb_device *d)
112{
113 int n;
114
115 for (n = 0; n < d->num_adapters_initialized; n++) {
116 dvb_usb_adapter_frontend_exit(&d->adapter[n]);
117 dvb_usb_adapter_dvb_exit(&d->adapter[n]);
118 dvb_usb_adapter_stream_exit(&d->adapter[n]);
119 kfree(d->adapter[n].priv);
120 }
121 d->num_adapters_initialized = 0;
122 d->state &= ~DVB_USB_STATE_DVB;
123 return 0;
124}
125
126
127/* general initialization functions */
128static int dvb_usb_exit(struct dvb_usb_device *d)
129{
130 deb_info("state before exiting everything: %x\n", d->state);
131 dvb_usb_remote_exit(d);
132 dvb_usb_adapter_exit(d);
133 dvb_usb_i2c_exit(d);
134 deb_info("state should be zero now: %x\n", d->state);
135 d->state = DVB_USB_STATE_INIT;
136 kfree(d->priv);
137 kfree(d);
138 return 0;
139}
140
141static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums)
142{
143 int ret = 0;
144
145 mutex_init(&d->usb_mutex);
146 mutex_init(&d->i2c_mutex);
147
148 d->state = DVB_USB_STATE_INIT;
149
150 if (d->props.size_of_priv > 0) {
151 d->priv = kzalloc(d->props.size_of_priv, GFP_KERNEL);
152 if (d->priv == NULL) {
153 err("no memory for priv in 'struct dvb_usb_device'");
154 return -ENOMEM;
155 }
156 }
157
158 /* check the capabilities and set appropriate variables */
159 dvb_usb_device_power_ctrl(d, 1);
160
161 if ((ret = dvb_usb_i2c_init(d)) ||
162 (ret = dvb_usb_adapter_init(d, adapter_nums))) {
163 dvb_usb_exit(d);
164 return ret;
165 }
166
167 if ((ret = dvb_usb_remote_init(d)))
168 err("could not initialize remote control.");
169
170 dvb_usb_device_power_ctrl(d, 0);
171
172 return 0;
173}
174
175/* determine the name and the state of the just found USB device */
176static struct dvb_usb_device_description *dvb_usb_find_device(struct usb_device *udev, struct dvb_usb_device_properties *props, int *cold)
177{
178 int i, j;
179 struct dvb_usb_device_description *desc = NULL;
180
181 *cold = -1;
182
183 for (i = 0; i < props->num_device_descs; i++) {
184
185 for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].cold_ids[j] != NULL; j++) {
186 deb_info("check for cold %x %x\n", props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct);
187 if (props->devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
188 props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
189 *cold = 1;
190 desc = &props->devices[i];
191 break;
192 }
193 }
194
195 if (desc != NULL)
196 break;
197
198 for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].warm_ids[j] != NULL; j++) {
199 deb_info("check for warm %x %x\n", props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct);
200 if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
201 props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
202 *cold = 0;
203 desc = &props->devices[i];
204 break;
205 }
206 }
207 }
208
209 if (desc != NULL && props->identify_state != NULL)
210 props->identify_state(udev, props, &desc, cold);
211
212 return desc;
213}
214
215int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff)
216{
217 if (onoff)
218 d->powered++;
219 else
220 d->powered--;
221
222 if (d->powered == 0 || (onoff && d->powered == 1)) { /* when switching from 1 to 0 or from 0 to 1 */
223 deb_info("power control: %d\n", onoff);
224 if (d->props.power_ctrl)
225 return d->props.power_ctrl(d, onoff);
226 }
227 return 0;
228}
229
230/*
231 * USB
232 */
233int dvb_usb_device_init(struct usb_interface *intf,
234 struct dvb_usb_device_properties *props,
235 struct module *owner, struct dvb_usb_device **du,
236 short *adapter_nums)
237{
238 struct usb_device *udev = interface_to_usbdev(intf);
239 struct dvb_usb_device *d = NULL;
240 struct dvb_usb_device_description *desc = NULL;
241
242 int ret = -ENOMEM, cold = 0;
243
244 if (du != NULL)
245 *du = NULL;
246
247 if ((desc = dvb_usb_find_device(udev, props, &cold)) == NULL) {
248 deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n");
249 return -ENODEV;
250 }
251
252 if (cold) {
253 info("found a '%s' in cold state, will try to load a firmware", desc->name);
254 ret = dvb_usb_download_firmware(udev, props);
255 if (!props->no_reconnect || ret != 0)
256 return ret;
257 }
258
259 info("found a '%s' in warm state.", desc->name);
260 d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
261 if (d == NULL) {
262 err("no memory for 'struct dvb_usb_device'");
263 return -ENOMEM;
264 }
265
266 d->udev = udev;
267 memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties));
268 d->desc = desc;
269 d->owner = owner;
270
271 usb_set_intfdata(intf, d);
272
273 if (du != NULL)
274 *du = d;
275
276 ret = dvb_usb_init(d, adapter_nums);
277
278 if (ret == 0)
279 info("%s successfully initialized and connected.", desc->name);
280 else
281 info("%s error while loading driver (%d)", desc->name, ret);
282 return ret;
283}
284EXPORT_SYMBOL(dvb_usb_device_init);
285
286void dvb_usb_device_exit(struct usb_interface *intf)
287{
288 struct dvb_usb_device *d = usb_get_intfdata(intf);
289 const char *name = "generic DVB-USB module";
290
291 usb_set_intfdata(intf, NULL);
292 if (d != NULL && d->desc != NULL) {
293 name = d->desc->name;
294 dvb_usb_exit(d);
295 }
296 info("%s successfully deinitialized and disconnected.", name);
297
298}
299EXPORT_SYMBOL(dvb_usb_device_exit);
300
301MODULE_VERSION("1.0");
302MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
303MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
304MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-remote.c b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
new file mode 100644
index 000000000000..41bacff24960
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/dvb-usb-urb.c b/drivers/media/usb/dvb-usb/dvb-usb-urb.c
new file mode 100644
index 000000000000..5c8f651344fc
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb-usb-urb.c
@@ -0,0 +1,121 @@
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
83static void dvb_usb_data_complete_raw(struct usb_data_stream *stream,
84 u8 *buffer, size_t length)
85{
86 struct dvb_usb_adapter *adap = stream->user_priv;
87 if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
88 dvb_dmx_swfilter_raw(&adap->demux, buffer, length);
89}
90
91int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap)
92{
93 int i, ret = 0;
94 for (i = 0; i < adap->props.num_frontends; i++) {
95
96 adap->fe_adap[i].stream.udev = adap->dev->udev;
97 if (adap->props.fe[i].caps & DVB_USB_ADAP_RECEIVES_204_BYTE_TS)
98 adap->fe_adap[i].stream.complete =
99 dvb_usb_data_complete_204;
100 else
101 if (adap->props.fe[i].caps & DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD)
102 adap->fe_adap[i].stream.complete =
103 dvb_usb_data_complete_raw;
104 else
105 adap->fe_adap[i].stream.complete = dvb_usb_data_complete;
106 adap->fe_adap[i].stream.user_priv = adap;
107 ret = usb_urb_init(&adap->fe_adap[i].stream,
108 &adap->props.fe[i].stream);
109 if (ret < 0)
110 break;
111 }
112 return ret;
113}
114
115int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap)
116{
117 int i;
118 for (i = 0; i < adap->props.num_frontends; i++)
119 usb_urb_exit(&adap->fe_adap[i].stream);
120 return 0;
121}
diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h
new file mode 100644
index 000000000000..aab0f99bc892
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb-usb.h
@@ -0,0 +1,483 @@
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 * @num_frontends: number of frontends of the DVB USB adapter.
128 * @frontend_ctrl: called to power on/off active frontend.
129 * @streaming_ctrl: called to start and stop the MPEG2-TS streaming of the
130 * device (not URB submitting/killing).
131 * @pid_filter_ctrl: called to en/disable the PID filter, if any.
132 * @pid_filter: called to set/unset a PID for filtering.
133 * @frontend_attach: called to attach the possible frontends (fill fe-field
134 * of struct dvb_usb_device).
135 * @tuner_attach: called to attach the correct tuner and to fill pll_addr,
136 * pll_desc and pll_init_buf of struct dvb_usb_device).
137 * @stream: configuration of the USB streaming
138 */
139struct dvb_usb_adapter_fe_properties {
140#define DVB_USB_ADAP_HAS_PID_FILTER 0x01
141#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
142#define DVB_USB_ADAP_NEED_PID_FILTERING 0x04
143#define DVB_USB_ADAP_RECEIVES_204_BYTE_TS 0x08
144#define DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD 0x10
145 int caps;
146 int pid_filter_count;
147
148 int (*streaming_ctrl) (struct dvb_usb_adapter *, int);
149 int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int);
150 int (*pid_filter) (struct dvb_usb_adapter *, int, u16, int);
151
152 int (*frontend_attach) (struct dvb_usb_adapter *);
153 int (*tuner_attach) (struct dvb_usb_adapter *);
154
155 struct usb_data_stream_properties stream;
156
157 int size_of_priv;
158};
159
160#define MAX_NO_OF_FE_PER_ADAP 3
161struct dvb_usb_adapter_properties {
162 int size_of_priv;
163
164 int (*frontend_ctrl) (struct dvb_frontend *, int);
165
166 int num_frontends;
167 struct dvb_usb_adapter_fe_properties fe[MAX_NO_OF_FE_PER_ADAP];
168};
169
170/**
171 * struct dvb_rc_legacy - old properties of remote controller
172 * @rc_map_table: a hard-wired array of struct rc_map_table (NULL to disable
173 * remote control handling).
174 * @rc_map_size: number of items in @rc_map_table.
175 * @rc_query: called to query an event event.
176 * @rc_interval: time in ms between two queries.
177 */
178struct dvb_rc_legacy {
179/* remote control properties */
180#define REMOTE_NO_KEY_PRESSED 0x00
181#define REMOTE_KEY_PRESSED 0x01
182#define REMOTE_KEY_REPEAT 0x02
183 struct rc_map_table *rc_map_table;
184 int rc_map_size;
185 int (*rc_query) (struct dvb_usb_device *, u32 *, int *);
186 int rc_interval;
187};
188
189/**
190 * struct dvb_rc properties of remote controller, using rc-core
191 * @rc_codes: name of rc codes table
192 * @protocol: type of protocol(s) currently used by the driver
193 * @allowed_protos: protocol(s) supported by the driver
194 * @driver_type: Used to point if a device supports raw mode
195 * @change_protocol: callback to change protocol
196 * @rc_query: called to query an event event.
197 * @rc_interval: time in ms between two queries.
198 * @bulk_mode: device supports bulk mode for RC (disable polling mode)
199 */
200struct dvb_rc {
201 char *rc_codes;
202 u64 protocol;
203 u64 allowed_protos;
204 enum rc_driver_type driver_type;
205 int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
206 char *module_name;
207 int (*rc_query) (struct dvb_usb_device *d);
208 int rc_interval;
209 bool bulk_mode; /* uses bulk mode */
210};
211
212/**
213 * enum dvb_usb_mode - Specifies if it is using a legacy driver or a new one
214 * based on rc-core
215 * This is initialized/used only inside dvb-usb-remote.c.
216 * It shouldn't be set by the drivers.
217 */
218enum dvb_usb_mode {
219 DVB_RC_LEGACY,
220 DVB_RC_CORE,
221};
222
223/**
224 * struct dvb_usb_device_properties - properties of a dvb-usb-device
225 * @usb_ctrl: which USB device-side controller is in use. Needed for firmware
226 * download.
227 * @firmware: name of the firmware file.
228 * @download_firmware: called to download the firmware when the usb_ctrl is
229 * DEVICE_SPECIFIC.
230 * @no_reconnect: device doesn't do a reconnect after downloading the firmware,
231 * so do the warm initialization right after it
232 *
233 * @size_of_priv: how many bytes shall be allocated for the private field
234 * of struct dvb_usb_device.
235 *
236 * @power_ctrl: called to enable/disable power of the device.
237 * @read_mac_address: called to read the MAC address of the device.
238 * @identify_state: called to determine the state (cold or warm), when it
239 * is not distinguishable by the USB IDs.
240 *
241 * @rc: remote controller properties
242 *
243 * @i2c_algo: i2c_algorithm if the device has I2CoverUSB.
244 *
245 * @generic_bulk_ctrl_endpoint: most of the DVB USB devices have a generic
246 * endpoint which received control messages with bulk transfers. When this
247 * is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write-
248 * helper functions.
249 *
250 * @generic_bulk_ctrl_endpoint_response: some DVB USB devices use a separate
251 * endpoint for responses to control messages sent with bulk transfers via
252 * the generic_bulk_ctrl_endpoint. When this is non-zero, this will be used
253 * instead of the generic_bulk_ctrl_endpoint when reading usb responses in
254 * the dvb_usb_generic_rw helper function.
255 *
256 * @num_device_descs: number of struct dvb_usb_device_description in @devices
257 * @devices: array of struct dvb_usb_device_description compatibles with these
258 * properties.
259 */
260#define MAX_NO_OF_ADAPTER_PER_DEVICE 2
261struct dvb_usb_device_properties {
262
263#define DVB_USB_IS_AN_I2C_ADAPTER 0x01
264 int caps;
265
266#define DEVICE_SPECIFIC 0
267#define CYPRESS_AN2135 1
268#define CYPRESS_AN2235 2
269#define CYPRESS_FX2 3
270 int usb_ctrl;
271 int (*download_firmware) (struct usb_device *, const struct firmware *);
272 const char *firmware;
273 int no_reconnect;
274
275 int size_of_priv;
276
277 int num_adapters;
278 struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
279
280 int (*power_ctrl) (struct dvb_usb_device *, int);
281 int (*read_mac_address) (struct dvb_usb_device *, u8 []);
282 int (*identify_state) (struct usb_device *, struct dvb_usb_device_properties *,
283 struct dvb_usb_device_description **, int *);
284
285 struct {
286 enum dvb_usb_mode mode; /* Drivers shouldn't touch on it */
287 struct dvb_rc_legacy legacy;
288 struct dvb_rc core;
289 } rc;
290
291 struct i2c_algorithm *i2c_algo;
292
293 int generic_bulk_ctrl_endpoint;
294 int generic_bulk_ctrl_endpoint_response;
295
296 int num_device_descs;
297 struct dvb_usb_device_description devices[12];
298};
299
300/**
301 * struct usb_data_stream - generic object of an USB stream
302 * @buf_num: number of buffer allocated.
303 * @buf_size: size of each buffer in buf_list.
304 * @buf_list: array containing all allocate buffers for streaming.
305 * @dma_addr: list of dma_addr_t for each buffer in buf_list.
306 *
307 * @urbs_initialized: number of URBs initialized.
308 * @urbs_submitted: number of URBs submitted.
309 */
310#define MAX_NO_URBS_FOR_DATA_STREAM 10
311struct usb_data_stream {
312 struct usb_device *udev;
313 struct usb_data_stream_properties props;
314
315#define USB_STATE_INIT 0x00
316#define USB_STATE_URB_BUF 0x01
317 int state;
318
319 void (*complete) (struct usb_data_stream *, u8 *, size_t);
320
321 struct urb *urb_list[MAX_NO_URBS_FOR_DATA_STREAM];
322 int buf_num;
323 unsigned long buf_size;
324 u8 *buf_list[MAX_NO_URBS_FOR_DATA_STREAM];
325 dma_addr_t dma_addr[MAX_NO_URBS_FOR_DATA_STREAM];
326
327 int urbs_initialized;
328 int urbs_submitted;
329
330 void *user_priv;
331};
332
333/**
334 * struct dvb_usb_adapter - a DVB adapter on a USB device
335 * @id: index of this adapter (starting with 0).
336 *
337 * @feedcount: number of reqested feeds (used for streaming-activation)
338 * @pid_filtering: is hardware pid_filtering used or not.
339 *
340 * @pll_addr: I2C address of the tuner for programming
341 * @pll_init: array containing the initialization buffer
342 * @pll_desc: pointer to the appropriate struct dvb_pll_desc
343 * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod or the board
344 *
345 * @dvb_adap: device's dvb_adapter.
346 * @dmxdev: device's dmxdev.
347 * @demux: device's software demuxer.
348 * @dvb_net: device's dvb_net interfaces.
349 * @dvb_frontend: device's frontend.
350 * @max_feed_count: how many feeds can be handled simultaneously by this
351 * device
352 *
353 * @fe_init: rerouted frontend-init (wakeup) function.
354 * @fe_sleep: rerouted frontend-sleep function.
355 *
356 * @stream: the usb data stream.
357 */
358struct dvb_usb_fe_adapter {
359 struct dvb_frontend *fe;
360
361 int (*fe_init) (struct dvb_frontend *);
362 int (*fe_sleep) (struct dvb_frontend *);
363
364 struct usb_data_stream stream;
365
366 int pid_filtering;
367 int max_feed_count;
368
369 void *priv;
370};
371
372struct dvb_usb_adapter {
373 struct dvb_usb_device *dev;
374 struct dvb_usb_adapter_properties props;
375
376#define DVB_USB_ADAP_STATE_INIT 0x000
377#define DVB_USB_ADAP_STATE_DVB 0x001
378 int state;
379
380 u8 id;
381
382 int feedcount;
383
384 /* dvb */
385 struct dvb_adapter dvb_adap;
386 struct dmxdev dmxdev;
387 struct dvb_demux demux;
388 struct dvb_net dvb_net;
389
390 struct dvb_usb_fe_adapter fe_adap[MAX_NO_OF_FE_PER_ADAP];
391 int active_fe;
392 int num_frontends_initialized;
393
394 void *priv;
395};
396
397/**
398 * struct dvb_usb_device - object of a DVB USB device
399 * @props: copy of the struct dvb_usb_properties this device belongs to.
400 * @desc: pointer to the device's struct dvb_usb_device_description.
401 * @state: initialization and runtime state of the device.
402 *
403 * @powered: indicated whether the device is power or not.
404 * Powered is in/decremented for each call to modify the state.
405 * @udev: pointer to the device's struct usb_device.
406 *
407 * @usb_mutex: semaphore of USB control messages (reading needs two messages)
408 * @i2c_mutex: semaphore for i2c-transfers
409 *
410 * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
411 *
412 * @rc_dev: rc device for the remote control (rc-core mode)
413 * @input_dev: input device for the remote control (legacy mode)
414 * @rc_query_work: struct work_struct frequent rc queries
415 * @last_event: last triggered event
416 * @last_state: last state (no, pressed, repeat)
417 * @owner: owner of the dvb_adapter
418 * @priv: private data of the actual driver (allocate by dvb-usb, size defined
419 * in size_of_priv of dvb_usb_properties).
420 */
421struct dvb_usb_device {
422 struct dvb_usb_device_properties props;
423 struct dvb_usb_device_description *desc;
424
425 struct usb_device *udev;
426
427#define DVB_USB_STATE_INIT 0x000
428#define DVB_USB_STATE_I2C 0x001
429#define DVB_USB_STATE_DVB 0x002
430#define DVB_USB_STATE_REMOTE 0x004
431 int state;
432
433 int powered;
434
435 /* locking */
436 struct mutex usb_mutex;
437
438 /* i2c */
439 struct mutex i2c_mutex;
440 struct i2c_adapter i2c_adap;
441
442 int num_adapters_initialized;
443 struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
444
445 /* remote control */
446 struct rc_dev *rc_dev;
447 struct input_dev *input_dev;
448 char rc_phys[64];
449 struct delayed_work rc_query_work;
450 u32 last_event;
451 int last_state;
452
453 struct module *owner;
454
455 void *priv;
456};
457
458extern int dvb_usb_device_init(struct usb_interface *,
459 struct dvb_usb_device_properties *,
460 struct module *, struct dvb_usb_device **,
461 short *adapter_nums);
462extern void dvb_usb_device_exit(struct usb_interface *);
463
464/* the generic read/write method for device control */
465extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int);
466extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
467
468/* commonly used remote control parsing */
469extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *);
470
471/* commonly used firmware download types and function */
472struct hexline {
473 u8 len;
474 u32 addr;
475 u8 type;
476 u8 data[255];
477 u8 chk;
478};
479extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type);
480extern int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos);
481
482
483#endif
diff --git a/drivers/media/usb/dvb-usb/dvb_usb_dvb.c b/drivers/media/usb/dvb-usb/dvb_usb_dvb.c
new file mode 100644
index 000000000000..384fe8eec21f
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb_usb_dvb.c
@@ -0,0 +1,403 @@
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
11static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buf,
12 size_t len)
13{
14 struct dvb_usb_adapter *adap = stream->user_priv;
15 dvb_dmx_swfilter(&adap->demux, buf, len);
16}
17
18static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buf,
19 size_t len)
20{
21 struct dvb_usb_adapter *adap = stream->user_priv;
22 dvb_dmx_swfilter_204(&adap->demux, buf, len);
23}
24
25static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, u8 *buf,
26 size_t len)
27{
28 struct dvb_usb_adapter *adap = stream->user_priv;
29 dvb_dmx_swfilter_raw(&adap->demux, buf, len);
30}
31
32int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap)
33{
34 pr_debug("%s: adap=%d\n", __func__, adap->id);
35
36 adap->stream.udev = adap_to_d(adap)->udev;
37 adap->stream.user_priv = adap;
38 adap->stream.complete = dvb_usb_data_complete;
39
40 return usb_urb_initv2(&adap->stream, &adap->props->stream);
41}
42
43int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap)
44{
45 pr_debug("%s: adap=%d\n", __func__, adap->id);
46 usb_urb_exitv2(&adap->stream);
47
48 return 0;
49}
50
51/* does the complete input transfer handling */
52static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int count)
53{
54 struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
55 struct dvb_usb_device *d = adap_to_d(adap);
56 int ret;
57 pr_debug("%s: adap=%d active_fe=%d feed_type=%d setting pid [%s]: " \
58 "%04x (%04d) at index %d '%s'\n", __func__, adap->id,
59 adap->active_fe, dvbdmxfeed->type,
60 adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid,
61 dvbdmxfeed->pid, dvbdmxfeed->index,
62 (count == 1) ? "on" : "off");
63
64 if (adap->active_fe == -1)
65 return -EINVAL;
66
67 adap->feed_count += count;
68
69 /* stop feeding if it is last pid */
70 if (adap->feed_count == 0) {
71 pr_debug("%s: stop feeding\n", __func__);
72 usb_urb_killv2(&adap->stream);
73
74 if (d->props->streaming_ctrl) {
75 ret = d->props->streaming_ctrl(adap, 0);
76 if (ret < 0) {
77 pr_err("%s: streaming_ctrl() failed=%d\n",
78 KBUILD_MODNAME, ret);
79 goto err_mutex_unlock;
80 }
81 }
82 mutex_unlock(&adap->sync_mutex);
83 }
84
85 /* activate the pid on the device pid filter */
86 if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
87 adap->pid_filtering &&
88 adap->props->pid_filter)
89 ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
90 dvbdmxfeed->pid, (count == 1) ? 1 : 0);
91 if (ret < 0)
92 pr_err("%s: pid_filter() failed=%d\n",
93 KBUILD_MODNAME, ret);
94
95 /* start feeding if it is first pid */
96 if (adap->feed_count == 1 && count == 1) {
97 struct usb_data_stream_properties stream_props;
98 mutex_lock(&adap->sync_mutex);
99 pr_debug("%s: start feeding\n", __func__);
100
101 /* resolve input and output streaming paramters */
102 if (d->props->get_stream_config) {
103 memcpy(&stream_props, &adap->props->stream,
104 sizeof(struct usb_data_stream_properties));
105 ret = d->props->get_stream_config(
106 adap->fe[adap->active_fe],
107 &adap->ts_type, &stream_props);
108 if (ret < 0)
109 goto err_mutex_unlock;
110 } else {
111 stream_props = adap->props->stream;
112 }
113
114 switch (adap->ts_type) {
115 case DVB_USB_FE_TS_TYPE_204:
116 adap->stream.complete = dvb_usb_data_complete_204;
117 break;
118 case DVB_USB_FE_TS_TYPE_RAW:
119 adap->stream.complete = dvb_usb_data_complete_raw;
120 break;
121 case DVB_USB_FE_TS_TYPE_188:
122 default:
123 adap->stream.complete = dvb_usb_data_complete;
124 break;
125 }
126
127 usb_urb_submitv2(&adap->stream, &stream_props);
128
129 if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
130 adap->props->caps &
131 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
132 adap->props->pid_filter_ctrl) {
133 ret = adap->props->pid_filter_ctrl(adap,
134 adap->pid_filtering);
135 if (ret < 0) {
136 pr_err("%s: pid_filter_ctrl() failed=%d\n",
137 KBUILD_MODNAME, ret);
138 goto err_mutex_unlock;
139 }
140 }
141
142 if (d->props->streaming_ctrl) {
143 ret = d->props->streaming_ctrl(adap, 1);
144 if (ret < 0) {
145 pr_err("%s: streaming_ctrl() failed=%d\n",
146 KBUILD_MODNAME, ret);
147 goto err_mutex_unlock;
148 }
149 }
150 }
151
152 return 0;
153err_mutex_unlock:
154 mutex_unlock(&adap->sync_mutex);
155 pr_debug("%s: failed=%d\n", __func__, ret);
156 return ret;
157}
158
159static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
160{
161 return dvb_usb_ctrl_feed(dvbdmxfeed, 1);
162}
163
164static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
165{
166 return dvb_usb_ctrl_feed(dvbdmxfeed, -1);
167}
168
169int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
170{
171 int ret;
172 struct dvb_usb_device *d = adap_to_d(adap);
173 pr_debug("%s: adap=%d\n", __func__, adap->id);
174
175 ret = dvb_register_adapter(&adap->dvb_adap, d->name, d->props->owner,
176 &d->udev->dev, d->props->adapter_nr);
177 if (ret < 0) {
178 pr_debug("%s: dvb_register_adapter() failed=%d\n", __func__,
179 ret);
180 goto err;
181 }
182
183 adap->dvb_adap.priv = adap;
184
185 if (d->props->read_mac_address) {
186 ret = d->props->read_mac_address(adap,
187 adap->dvb_adap.proposed_mac);
188 if (ret < 0)
189 goto err_dmx;
190
191 pr_info("%s: MAC address: %pM\n", KBUILD_MODNAME,
192 adap->dvb_adap.proposed_mac);
193 }
194
195 adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
196 adap->demux.priv = adap;
197 adap->demux.filternum = 0;
198 if (adap->demux.filternum < adap->max_feed_count)
199 adap->demux.filternum = adap->max_feed_count;
200 adap->demux.feednum = adap->demux.filternum;
201 adap->demux.start_feed = dvb_usb_start_feed;
202 adap->demux.stop_feed = dvb_usb_stop_feed;
203 adap->demux.write_to_decoder = NULL;
204 ret = dvb_dmx_init(&adap->demux);
205 if (ret < 0) {
206 pr_err("%s: dvb_dmx_init() failed=%d\n", KBUILD_MODNAME, ret);
207 goto err_dmx;
208 }
209
210 adap->dmxdev.filternum = adap->demux.filternum;
211 adap->dmxdev.demux = &adap->demux.dmx;
212 adap->dmxdev.capabilities = 0;
213 ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
214 if (ret < 0) {
215 pr_err("%s: dvb_dmxdev_init() failed=%d\n", KBUILD_MODNAME,
216 ret);
217 goto err_dmx_dev;
218 }
219
220 ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
221 if (ret < 0) {
222 pr_err("%s: dvb_net_init() failed=%d\n", KBUILD_MODNAME, ret);
223 goto err_net_init;
224 }
225
226 mutex_init(&adap->sync_mutex);
227
228 return 0;
229err_net_init:
230 dvb_dmxdev_release(&adap->dmxdev);
231err_dmx_dev:
232 dvb_dmx_release(&adap->demux);
233err_dmx:
234 dvb_unregister_adapter(&adap->dvb_adap);
235err:
236 adap->dvb_adap.priv = NULL;
237 return ret;
238}
239
240int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap)
241{
242 pr_debug("%s: adap=%d\n", __func__, adap->id);
243
244 if (adap->dvb_adap.priv) {
245 dvb_net_release(&adap->dvb_net);
246 adap->demux.dmx.close(&adap->demux.dmx);
247 dvb_dmxdev_release(&adap->dmxdev);
248 dvb_dmx_release(&adap->demux);
249 dvb_unregister_adapter(&adap->dvb_adap);
250 }
251
252 return 0;
253}
254
255static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
256{
257 int ret;
258 struct dvb_usb_adapter *adap = fe->dvb->priv;
259 struct dvb_usb_device *d = adap_to_d(adap);
260 mutex_lock(&adap->sync_mutex);
261 pr_debug("%s: adap=%d fe=%d\n", __func__, adap->id, fe->id);
262
263 ret = dvb_usbv2_device_power_ctrl(d, 1);
264 if (ret < 0)
265 goto err;
266
267 if (d->props->frontend_ctrl) {
268 ret = d->props->frontend_ctrl(fe, 1);
269 if (ret < 0)
270 goto err;
271 }
272
273 if (adap->fe_init[fe->id]) {
274 ret = adap->fe_init[fe->id](fe);
275 if (ret < 0)
276 goto err;
277 }
278
279 adap->active_fe = fe->id;
280 mutex_unlock(&adap->sync_mutex);
281
282 return 0;
283err:
284 mutex_unlock(&adap->sync_mutex);
285 pr_debug("%s: failed=%d\n", __func__, ret);
286 return ret;
287}
288
289static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
290{
291 int ret;
292 struct dvb_usb_adapter *adap = fe->dvb->priv;
293 struct dvb_usb_device *d = adap_to_d(adap);
294 mutex_lock(&adap->sync_mutex);
295 pr_debug("%s: adap=%d fe=%d\n", __func__, adap->id, fe->id);
296
297 if (adap->fe_sleep[fe->id]) {
298 ret = adap->fe_sleep[fe->id](fe);
299 if (ret < 0)
300 goto err;
301 }
302
303 if (d->props->frontend_ctrl) {
304 ret = d->props->frontend_ctrl(fe, 0);
305 if (ret < 0)
306 goto err;
307 }
308
309 ret = dvb_usbv2_device_power_ctrl(d, 0);
310 if (ret < 0)
311 goto err;
312
313 adap->active_fe = -1;
314 mutex_unlock(&adap->sync_mutex);
315
316 return 0;
317err:
318 mutex_unlock(&adap->sync_mutex);
319 pr_debug("%s: failed=%d\n", __func__, ret);
320 return ret;
321}
322
323int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
324{
325 int ret, i, count_registered = 0;
326 struct dvb_usb_device *d = adap_to_d(adap);
327 pr_debug("%s: adap=%d\n", __func__, adap->id);
328
329 memset(adap->fe, 0, sizeof(adap->fe));
330 adap->active_fe = -1;
331
332 if (d->props->frontend_attach) {
333 ret = d->props->frontend_attach(adap);
334 if (ret < 0) {
335 pr_debug("%s: frontend_attach() failed=%d\n", __func__,
336 ret);
337 goto err_dvb_frontend_detach;
338 }
339 } else {
340 pr_debug("%s: frontend_attach() do not exists\n", __func__);
341 ret = 0;
342 goto err;
343 }
344
345 for (i = 0; i < MAX_NO_OF_FE_PER_ADAP && adap->fe[i]; i++) {
346 adap->fe[i]->id = i;
347
348 /* re-assign sleep and wakeup functions */
349 adap->fe_init[i] = adap->fe[i]->ops.init;
350 adap->fe[i]->ops.init = dvb_usb_fe_wakeup;
351 adap->fe_sleep[i] = adap->fe[i]->ops.sleep;
352 adap->fe[i]->ops.sleep = dvb_usb_fe_sleep;
353
354 ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]);
355 if (ret < 0) {
356 pr_err("%s: frontend%d registration failed\n",
357 KBUILD_MODNAME, i);
358 goto err_dvb_unregister_frontend;
359 }
360
361 count_registered++;
362 }
363
364 if (d->props->tuner_attach) {
365 ret = d->props->tuner_attach(adap);
366 if (ret < 0) {
367 pr_debug("%s: tuner_attach() failed=%d\n", __func__,
368 ret);
369 goto err_dvb_unregister_frontend;
370 }
371 }
372
373 return 0;
374
375err_dvb_unregister_frontend:
376 for (i = count_registered - 1; i >= 0; i--)
377 dvb_unregister_frontend(adap->fe[i]);
378
379err_dvb_frontend_detach:
380 for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
381 if (adap->fe[i])
382 dvb_frontend_detach(adap->fe[i]);
383 }
384
385err:
386 pr_debug("%s: failed=%d\n", __func__, ret);
387 return ret;
388}
389
390int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap)
391{
392 int i;
393 pr_debug("%s: adap=%d\n", __func__, adap->id);
394
395 for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
396 if (adap->fe[i]) {
397 dvb_unregister_frontend(adap->fe[i]);
398 dvb_frontend_detach(adap->fe[i]);
399 }
400 }
401
402 return 0;
403}
diff --git a/drivers/media/usb/dvb-usb/dvb_usb_remote.c b/drivers/media/usb/dvb-usb/dvb_usb_remote.c
new file mode 100644
index 000000000000..f856ab6648c7
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb_usb_remote.c
@@ -0,0 +1,117 @@
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
7 * handling remote-control-queries.
8 */
9#include "dvb_usb_common.h"
10#include <linux/usb/input.h>
11
12/* Remote-control poll function - called every dib->rc_query_interval ms to see
13 * whether the remote control has received anything.
14 *
15 * TODO: Fix the repeat rate of the input device.
16 */
17static void dvb_usb_read_remote_control(struct work_struct *work)
18{
19 struct dvb_usb_device *d = container_of(work,
20 struct dvb_usb_device, rc_query_work.work);
21 int ret;
22
23 /* TODO: need a lock here. We can simply skip checking for the remote
24 control if we're busy. */
25
26 /* when the parameter has been set to 1 via sysfs while the
27 * driver was running, or when bulk mode is enabled after IR init
28 */
29 if (dvb_usbv2_disable_rc_polling || d->rc.bulk_mode)
30 return;
31
32 ret = d->rc.query(d);
33 if (ret < 0)
34 pr_err("%s: error %d while querying for an remote control " \
35 "event\n", KBUILD_MODNAME, ret);
36
37 schedule_delayed_work(&d->rc_query_work,
38 msecs_to_jiffies(d->rc.interval));
39}
40
41int dvb_usbv2_remote_init(struct dvb_usb_device *d)
42{
43 int ret;
44 struct rc_dev *dev;
45
46 if (dvb_usbv2_disable_rc_polling || !d->props->get_rc_config)
47 return 0;
48
49 ret = d->props->get_rc_config(d, &d->rc);
50 if (ret < 0)
51 goto err;
52
53 dev = rc_allocate_device();
54 if (!dev) {
55 ret = -ENOMEM;
56 goto err;
57 }
58
59 dev->dev.parent = &d->udev->dev;
60 dev->input_name = "IR-receiver inside an USB DVB receiver";
61 usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
62 strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
63 dev->input_phys = d->rc_phys;
64 usb_to_input_id(d->udev, &dev->input_id);
65 /* TODO: likely RC-core should took const char * */
66 dev->driver_name = (char *) d->props->driver_name;
67 dev->driver_type = d->rc.driver_type;
68 dev->allowed_protos = d->rc.allowed_protos;
69 dev->change_protocol = d->rc.change_protocol;
70 dev->priv = d;
71 /* select used keymap */
72 if (d->rc.map_name)
73 dev->map_name = d->rc.map_name;
74 else if (d->rc_map)
75 dev->map_name = d->rc_map;
76 else
77 dev->map_name = RC_MAP_EMPTY; /* keep rc enabled */
78
79 ret = rc_register_device(dev);
80 if (ret < 0) {
81 rc_free_device(dev);
82 goto err;
83 }
84
85 d->input_dev = NULL;
86 d->rc_dev = dev;
87
88 /* start polling if needed */
89 if (d->rc.query && !d->rc.bulk_mode) {
90 /* initialize a work queue for handling polling */
91 INIT_DELAYED_WORK(&d->rc_query_work,
92 dvb_usb_read_remote_control);
93 pr_info("%s: schedule remote query interval to %d msecs\n",
94 KBUILD_MODNAME, d->rc.interval);
95 schedule_delayed_work(&d->rc_query_work,
96 msecs_to_jiffies(d->rc.interval));
97 }
98
99 d->state |= DVB_USB_STATE_REMOTE;
100
101 return 0;
102err:
103 pr_debug("%s: failed=%d\n", __func__, ret);
104 return ret;
105}
106
107int dvb_usbv2_remote_exit(struct dvb_usb_device *d)
108{
109 if (d->state & DVB_USB_STATE_REMOTE) {
110 cancel_delayed_work_sync(&d->rc_query_work);
111 rc_unregister_device(d->rc_dev);
112 }
113
114 d->state &= ~DVB_USB_STATE_REMOTE;
115
116 return 0;
117}
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
new file mode 100644
index 000000000000..9382895b1b88
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -0,0 +1,1951 @@
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;
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 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 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 dw210x_op_rw(d->udev, 0xb2, 0, 0,
191 buf6, 7, DW210X_WRITE_MSG);
192 } else {
193 /* read from tuner */
194 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 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 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 u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
225
226 if (!d)
227 return -ENODEV;
228 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
229 return -EAGAIN;
230
231 switch (num) {
232 case 2:
233 /* read si2109 register by number */
234 buf6[0] = msg[0].addr << 1;
235 buf6[1] = msg[0].len;
236 buf6[2] = msg[0].buf[0];
237 dw210x_op_rw(d->udev, 0xc2, 0, 0,
238 buf6, msg[0].len + 2, DW210X_WRITE_MSG);
239 /* read si2109 register */
240 dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
241 buf6, msg[1].len + 2, DW210X_READ_MSG);
242 memcpy(msg[1].buf, buf6 + 2, msg[1].len);
243
244 break;
245 case 1:
246 switch (msg[0].addr) {
247 case 0x68:
248 /* write to si2109 register */
249 buf6[0] = msg[0].addr << 1;
250 buf6[1] = msg[0].len;
251 memcpy(buf6 + 2, msg[0].buf, msg[0].len);
252 dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
253 msg[0].len + 2, DW210X_WRITE_MSG);
254 break;
255 case(DW2102_RC_QUERY):
256 dw210x_op_rw(d->udev, 0xb8, 0, 0,
257 buf6, 2, DW210X_READ_MSG);
258 msg[0].buf[0] = buf6[0];
259 msg[0].buf[1] = buf6[1];
260 break;
261 case(DW2102_VOLTAGE_CTRL):
262 buf6[0] = 0x30;
263 buf6[1] = msg[0].buf[0];
264 dw210x_op_rw(d->udev, 0xb2, 0, 0,
265 buf6, 2, DW210X_WRITE_MSG);
266 break;
267 }
268 break;
269 }
270
271 mutex_unlock(&d->i2c_mutex);
272 return num;
273}
274
275static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
276{
277 struct dvb_usb_device *d = i2c_get_adapdata(adap);
278
279 if (!d)
280 return -ENODEV;
281 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
282 return -EAGAIN;
283
284 switch (num) {
285 case 2: {
286 /* read */
287 /* first write first register number */
288 u8 ibuf[msg[1].len + 2], obuf[3];
289 obuf[0] = msg[0].addr << 1;
290 obuf[1] = msg[0].len;
291 obuf[2] = msg[0].buf[0];
292 dw210x_op_rw(d->udev, 0xc2, 0, 0,
293 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
294 /* second read registers */
295 dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
296 ibuf, msg[1].len + 2, DW210X_READ_MSG);
297 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
298
299 break;
300 }
301 case 1:
302 switch (msg[0].addr) {
303 case 0x68: {
304 /* write to register */
305 u8 obuf[msg[0].len + 2];
306 obuf[0] = msg[0].addr << 1;
307 obuf[1] = msg[0].len;
308 memcpy(obuf + 2, msg[0].buf, msg[0].len);
309 dw210x_op_rw(d->udev, 0xc2, 0, 0,
310 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
311 break;
312 }
313 case 0x61: {
314 /* write to tuner */
315 u8 obuf[msg[0].len + 2];
316 obuf[0] = msg[0].addr << 1;
317 obuf[1] = msg[0].len;
318 memcpy(obuf + 2, msg[0].buf, msg[0].len);
319 dw210x_op_rw(d->udev, 0xc2, 0, 0,
320 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
321 break;
322 }
323 case(DW2102_RC_QUERY): {
324 u8 ibuf[2];
325 dw210x_op_rw(d->udev, 0xb8, 0, 0,
326 ibuf, 2, DW210X_READ_MSG);
327 memcpy(msg[0].buf, ibuf , 2);
328 break;
329 }
330 case(DW2102_VOLTAGE_CTRL): {
331 u8 obuf[2];
332 obuf[0] = 0x30;
333 obuf[1] = msg[0].buf[0];
334 dw210x_op_rw(d->udev, 0xb2, 0, 0,
335 obuf, 2, DW210X_WRITE_MSG);
336 break;
337 }
338 }
339
340 break;
341 }
342
343 mutex_unlock(&d->i2c_mutex);
344 return num;
345}
346
347static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
348{
349 struct dvb_usb_device *d = i2c_get_adapdata(adap);
350 int len, i, j;
351
352 if (!d)
353 return -ENODEV;
354 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
355 return -EAGAIN;
356
357 for (j = 0; j < num; j++) {
358 switch (msg[j].addr) {
359 case(DW2102_RC_QUERY): {
360 u8 ibuf[2];
361 dw210x_op_rw(d->udev, 0xb8, 0, 0,
362 ibuf, 2, DW210X_READ_MSG);
363 memcpy(msg[j].buf, ibuf , 2);
364 break;
365 }
366 case(DW2102_VOLTAGE_CTRL): {
367 u8 obuf[2];
368 obuf[0] = 0x30;
369 obuf[1] = msg[j].buf[0];
370 dw210x_op_rw(d->udev, 0xb2, 0, 0,
371 obuf, 2, DW210X_WRITE_MSG);
372 break;
373 }
374 /*case 0x55: cx24116
375 case 0x6a: stv0903
376 case 0x68: ds3000, stv0903
377 case 0x60: ts2020, stv6110, stb6100 */
378 default: {
379 if (msg[j].flags == I2C_M_RD) {
380 /* read registers */
381 u8 ibuf[msg[j].len + 2];
382 dw210x_op_rw(d->udev, 0xc3,
383 (msg[j].addr << 1) + 1, 0,
384 ibuf, msg[j].len + 2,
385 DW210X_READ_MSG);
386 memcpy(msg[j].buf, ibuf + 2, msg[j].len);
387 mdelay(10);
388 } else if (((msg[j].buf[0] == 0xb0) &&
389 (msg[j].addr == 0x68)) ||
390 ((msg[j].buf[0] == 0xf7) &&
391 (msg[j].addr == 0x55))) {
392 /* write firmware */
393 u8 obuf[19];
394 obuf[0] = msg[j].addr << 1;
395 obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
396 obuf[2] = msg[j].buf[0];
397 len = msg[j].len - 1;
398 i = 1;
399 do {
400 memcpy(obuf + 3, msg[j].buf + i,
401 (len > 16 ? 16 : len));
402 dw210x_op_rw(d->udev, 0xc2, 0, 0,
403 obuf, (len > 16 ? 16 : len) + 3,
404 DW210X_WRITE_MSG);
405 i += 16;
406 len -= 16;
407 } while (len > 0);
408 } else {
409 /* write registers */
410 u8 obuf[msg[j].len + 2];
411 obuf[0] = msg[j].addr << 1;
412 obuf[1] = msg[j].len;
413 memcpy(obuf + 2, msg[j].buf, msg[j].len);
414 dw210x_op_rw(d->udev, 0xc2, 0, 0,
415 obuf, msg[j].len + 2,
416 DW210X_WRITE_MSG);
417 }
418 break;
419 }
420 }
421
422 }
423
424 mutex_unlock(&d->i2c_mutex);
425 return num;
426}
427
428static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
429 int num)
430{
431 struct dvb_usb_device *d = i2c_get_adapdata(adap);
432 int i;
433
434 if (!d)
435 return -ENODEV;
436 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
437 return -EAGAIN;
438
439 switch (num) {
440 case 2: {
441 /* read */
442 /* first write first register number */
443 u8 ibuf[msg[1].len + 2], obuf[3];
444 obuf[0] = msg[0].addr << 1;
445 obuf[1] = msg[0].len;
446 obuf[2] = msg[0].buf[0];
447 dw210x_op_rw(d->udev, 0xc2, 0, 0,
448 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
449 /* second read registers */
450 dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
451 ibuf, msg[1].len + 2, DW210X_READ_MSG);
452 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
453
454 break;
455 }
456 case 1:
457 switch (msg[0].addr) {
458 case 0x60:
459 case 0x0c: {
460 /* write to register */
461 u8 obuf[msg[0].len + 2];
462 obuf[0] = msg[0].addr << 1;
463 obuf[1] = msg[0].len;
464 memcpy(obuf + 2, msg[0].buf, msg[0].len);
465 dw210x_op_rw(d->udev, 0xc2, 0, 0,
466 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
467 break;
468 }
469 case(DW2102_RC_QUERY): {
470 u8 ibuf[2];
471 dw210x_op_rw(d->udev, 0xb8, 0, 0,
472 ibuf, 2, DW210X_READ_MSG);
473 memcpy(msg[0].buf, ibuf , 2);
474 break;
475 }
476 }
477
478 break;
479 }
480
481 for (i = 0; i < num; i++) {
482 deb_xfer("%02x:%02x: %s ", i, msg[i].addr,
483 msg[i].flags == 0 ? ">>>" : "<<<");
484 debug_dump(msg[i].buf, msg[i].len, deb_xfer);
485 }
486
487 mutex_unlock(&d->i2c_mutex);
488 return num;
489}
490
491static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
492 int num)
493{
494 struct dvb_usb_device *d = i2c_get_adapdata(adap);
495 struct usb_device *udev;
496 int len, i, j;
497
498 if (!d)
499 return -ENODEV;
500 udev = d->udev;
501 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
502 return -EAGAIN;
503
504 for (j = 0; j < num; j++) {
505 switch (msg[j].addr) {
506 case (DW2102_RC_QUERY): {
507 u8 ibuf[5];
508 dw210x_op_rw(d->udev, 0xb8, 0, 0,
509 ibuf, 5, DW210X_READ_MSG);
510 memcpy(msg[j].buf, ibuf + 3, 2);
511 break;
512 }
513 case (DW2102_VOLTAGE_CTRL): {
514 u8 obuf[2];
515
516 obuf[0] = 1;
517 obuf[1] = msg[j].buf[1];/* off-on */
518 dw210x_op_rw(d->udev, 0x8a, 0, 0,
519 obuf, 2, DW210X_WRITE_MSG);
520 obuf[0] = 3;
521 obuf[1] = msg[j].buf[0];/* 13v-18v */
522 dw210x_op_rw(d->udev, 0x8a, 0, 0,
523 obuf, 2, DW210X_WRITE_MSG);
524 break;
525 }
526 case (DW2102_LED_CTRL): {
527 u8 obuf[2];
528
529 obuf[0] = 5;
530 obuf[1] = msg[j].buf[0];
531 dw210x_op_rw(d->udev, 0x8a, 0, 0,
532 obuf, 2, DW210X_WRITE_MSG);
533 break;
534 }
535 /*case 0x55: cx24116
536 case 0x6a: stv0903
537 case 0x68: ds3000, stv0903
538 case 0x60: ts2020, stv6110, stb6100
539 case 0xa0: eeprom */
540 default: {
541 if (msg[j].flags == I2C_M_RD) {
542 /* read registers */
543 u8 ibuf[msg[j].len];
544 dw210x_op_rw(d->udev, 0x91, 0, 0,
545 ibuf, msg[j].len,
546 DW210X_READ_MSG);
547 memcpy(msg[j].buf, ibuf, msg[j].len);
548 break;
549 } else if ((msg[j].buf[0] == 0xb0) &&
550 (msg[j].addr == 0x68)) {
551 /* write firmware */
552 u8 obuf[19];
553 obuf[0] = (msg[j].len > 16 ?
554 18 : msg[j].len + 1);
555 obuf[1] = msg[j].addr << 1;
556 obuf[2] = msg[j].buf[0];
557 len = msg[j].len - 1;
558 i = 1;
559 do {
560 memcpy(obuf + 3, msg[j].buf + i,
561 (len > 16 ? 16 : len));
562 dw210x_op_rw(d->udev, 0x80, 0, 0,
563 obuf, (len > 16 ? 16 : len) + 3,
564 DW210X_WRITE_MSG);
565 i += 16;
566 len -= 16;
567 } while (len > 0);
568 } else if (j < (num - 1)) {
569 /* write register addr before read */
570 u8 obuf[msg[j].len + 2];
571 obuf[0] = msg[j + 1].len;
572 obuf[1] = (msg[j].addr << 1);
573 memcpy(obuf + 2, msg[j].buf, msg[j].len);
574 dw210x_op_rw(d->udev,
575 udev->descriptor.idProduct ==
576 0x7500 ? 0x92 : 0x90, 0, 0,
577 obuf, msg[j].len + 2,
578 DW210X_WRITE_MSG);
579 break;
580 } else {
581 /* write registers */
582 u8 obuf[msg[j].len + 2];
583 obuf[0] = msg[j].len + 1;
584 obuf[1] = (msg[j].addr << 1);
585 memcpy(obuf + 2, msg[j].buf, msg[j].len);
586 dw210x_op_rw(d->udev, 0x80, 0, 0,
587 obuf, msg[j].len + 2,
588 DW210X_WRITE_MSG);
589 break;
590 }
591 break;
592 }
593 }
594 }
595
596 mutex_unlock(&d->i2c_mutex);
597 return num;
598}
599
600static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
601 int num)
602{
603 struct dvb_usb_device *d = i2c_get_adapdata(adap);
604 u8 obuf[0x40], ibuf[0x40];
605
606 if (!d)
607 return -ENODEV;
608 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
609 return -EAGAIN;
610
611 switch (num) {
612 case 1:
613 switch (msg[0].addr) {
614 case SU3000_STREAM_CTRL:
615 obuf[0] = msg[0].buf[0] + 0x36;
616 obuf[1] = 3;
617 obuf[2] = 0;
618 if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
619 err("i2c transfer failed.");
620 break;
621 case DW2102_RC_QUERY:
622 obuf[0] = 0x10;
623 if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
624 err("i2c transfer failed.");
625 msg[0].buf[1] = ibuf[0];
626 msg[0].buf[0] = ibuf[1];
627 break;
628 default:
629 /* always i2c write*/
630 obuf[0] = 0x08;
631 obuf[1] = msg[0].addr;
632 obuf[2] = msg[0].len;
633
634 memcpy(&obuf[3], msg[0].buf, msg[0].len);
635
636 if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
637 ibuf, 1, 0) < 0)
638 err("i2c transfer failed.");
639
640 }
641 break;
642 case 2:
643 /* always i2c read */
644 obuf[0] = 0x09;
645 obuf[1] = msg[0].len;
646 obuf[2] = msg[1].len;
647 obuf[3] = msg[0].addr;
648 memcpy(&obuf[4], msg[0].buf, msg[0].len);
649
650 if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
651 ibuf, msg[1].len + 1, 0) < 0)
652 err("i2c transfer failed.");
653
654 memcpy(msg[1].buf, &ibuf[1], msg[1].len);
655 break;
656 default:
657 warn("more than 2 i2c messages at a time is not handled yet.");
658 break;
659 }
660 mutex_unlock(&d->i2c_mutex);
661 return num;
662}
663
664static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
665{
666 return I2C_FUNC_I2C;
667}
668
669static struct i2c_algorithm dw2102_i2c_algo = {
670 .master_xfer = dw2102_i2c_transfer,
671 .functionality = dw210x_i2c_func,
672};
673
674static struct i2c_algorithm dw2102_serit_i2c_algo = {
675 .master_xfer = dw2102_serit_i2c_transfer,
676 .functionality = dw210x_i2c_func,
677};
678
679static struct i2c_algorithm dw2102_earda_i2c_algo = {
680 .master_xfer = dw2102_earda_i2c_transfer,
681 .functionality = dw210x_i2c_func,
682};
683
684static struct i2c_algorithm dw2104_i2c_algo = {
685 .master_xfer = dw2104_i2c_transfer,
686 .functionality = dw210x_i2c_func,
687};
688
689static struct i2c_algorithm dw3101_i2c_algo = {
690 .master_xfer = dw3101_i2c_transfer,
691 .functionality = dw210x_i2c_func,
692};
693
694static struct i2c_algorithm s6x0_i2c_algo = {
695 .master_xfer = s6x0_i2c_transfer,
696 .functionality = dw210x_i2c_func,
697};
698
699static struct i2c_algorithm su3000_i2c_algo = {
700 .master_xfer = su3000_i2c_transfer,
701 .functionality = dw210x_i2c_func,
702};
703
704static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
705{
706 int i;
707 u8 ibuf[] = {0, 0};
708 u8 eeprom[256], eepromline[16];
709
710 for (i = 0; i < 256; i++) {
711 if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
712 err("read eeprom failed.");
713 return -1;
714 } else {
715 eepromline[i%16] = ibuf[0];
716 eeprom[i] = ibuf[0];
717 }
718 if ((i % 16) == 15) {
719 deb_xfer("%02x: ", i - 15);
720 debug_dump(eepromline, 16, deb_xfer);
721 }
722 }
723
724 memcpy(mac, eeprom + 8, 6);
725 return 0;
726};
727
728static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
729{
730 int i, ret;
731 u8 ibuf[] = { 0 }, obuf[] = { 0 };
732 u8 eeprom[256], eepromline[16];
733 struct i2c_msg msg[] = {
734 {
735 .addr = 0xa0 >> 1,
736 .flags = 0,
737 .buf = obuf,
738 .len = 1,
739 }, {
740 .addr = 0xa0 >> 1,
741 .flags = I2C_M_RD,
742 .buf = ibuf,
743 .len = 1,
744 }
745 };
746
747 for (i = 0; i < 256; i++) {
748 obuf[0] = i;
749 ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
750 if (ret != 2) {
751 err("read eeprom failed.");
752 return -1;
753 } else {
754 eepromline[i % 16] = ibuf[0];
755 eeprom[i] = ibuf[0];
756 }
757
758 if ((i % 16) == 15) {
759 deb_xfer("%02x: ", i - 15);
760 debug_dump(eepromline, 16, deb_xfer);
761 }
762 }
763
764 memcpy(mac, eeprom + 16, 6);
765 return 0;
766};
767
768static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
769{
770 static u8 command_start[] = {0x00};
771 static u8 command_stop[] = {0x01};
772 struct i2c_msg msg = {
773 .addr = SU3000_STREAM_CTRL,
774 .flags = 0,
775 .buf = onoff ? command_start : command_stop,
776 .len = 1
777 };
778
779 i2c_transfer(&adap->dev->i2c_adap, &msg, 1);
780
781 return 0;
782}
783
784static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
785{
786 struct su3000_state *state = (struct su3000_state *)d->priv;
787 u8 obuf[] = {0xde, 0};
788
789 info("%s: %d, initialized %d\n", __func__, i, state->initialized);
790
791 if (i && !state->initialized) {
792 state->initialized = 1;
793 /* reset board */
794 dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0);
795 }
796
797 return 0;
798}
799
800static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
801{
802 int i;
803 u8 obuf[] = { 0x1f, 0xf0 };
804 u8 ibuf[] = { 0 };
805 struct i2c_msg msg[] = {
806 {
807 .addr = 0x51,
808 .flags = 0,
809 .buf = obuf,
810 .len = 2,
811 }, {
812 .addr = 0x51,
813 .flags = I2C_M_RD,
814 .buf = ibuf,
815 .len = 1,
816
817 }
818 };
819
820 for (i = 0; i < 6; i++) {
821 obuf[1] = 0xf0 + i;
822 if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
823 break;
824 else
825 mac[i] = ibuf[0];
826
827 debug_dump(mac, 6, printk);
828 }
829
830 return 0;
831}
832
833static int su3000_identify_state(struct usb_device *udev,
834 struct dvb_usb_device_properties *props,
835 struct dvb_usb_device_description **desc,
836 int *cold)
837{
838 info("%s\n", __func__);
839
840 *cold = 0;
841 return 0;
842}
843
844static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
845{
846 static u8 command_13v[] = {0x00, 0x01};
847 static u8 command_18v[] = {0x01, 0x01};
848 static u8 command_off[] = {0x00, 0x00};
849 struct i2c_msg msg = {
850 .addr = DW2102_VOLTAGE_CTRL,
851 .flags = 0,
852 .buf = command_off,
853 .len = 2,
854 };
855
856 struct dvb_usb_adapter *udev_adap =
857 (struct dvb_usb_adapter *)(fe->dvb->priv);
858 if (voltage == SEC_VOLTAGE_18)
859 msg.buf = command_18v;
860 else if (voltage == SEC_VOLTAGE_13)
861 msg.buf = command_13v;
862
863 i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
864
865 return 0;
866}
867
868static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
869{
870 struct dvb_usb_adapter *d =
871 (struct dvb_usb_adapter *)(fe->dvb->priv);
872 struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
873
874 dw210x_set_voltage(fe, voltage);
875 if (st->old_set_voltage)
876 st->old_set_voltage(fe, voltage);
877
878 return 0;
879}
880
881static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon)
882{
883 static u8 led_off[] = { 0 };
884 static u8 led_on[] = { 1 };
885 struct i2c_msg msg = {
886 .addr = DW2102_LED_CTRL,
887 .flags = 0,
888 .buf = led_off,
889 .len = 1
890 };
891 struct dvb_usb_adapter *udev_adap =
892 (struct dvb_usb_adapter *)(fe->dvb->priv);
893
894 if (offon)
895 msg.buf = led_on;
896 i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
897}
898
899static struct stv0299_config sharp_z0194a_config = {
900 .demod_address = 0x68,
901 .inittab = sharp_z0194a_inittab,
902 .mclk = 88000000UL,
903 .invert = 1,
904 .skip_reinit = 0,
905 .lock_output = STV0299_LOCKOUTPUT_1,
906 .volt13_op0_op1 = STV0299_VOLT13_OP1,
907 .min_delay_ms = 100,
908 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
909};
910
911static struct cx24116_config dw2104_config = {
912 .demod_address = 0x55,
913 .mpg_clk_pos_pol = 0x01,
914};
915
916static struct si21xx_config serit_sp1511lhb_config = {
917 .demod_address = 0x68,
918 .min_delay_ms = 100,
919
920};
921
922static struct tda10023_config dw3101_tda10023_config = {
923 .demod_address = 0x0c,
924 .invert = 1,
925};
926
927static struct mt312_config zl313_config = {
928 .demod_address = 0x0e,
929};
930
931static struct ds3000_config dw2104_ds3000_config = {
932 .demod_address = 0x68,
933};
934
935static struct stv0900_config dw2104a_stv0900_config = {
936 .demod_address = 0x6a,
937 .demod_mode = 0,
938 .xtal = 27000000,
939 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
940 .diseqc_mode = 2,/* 2/3 PWM */
941 .tun1_maddress = 0,/* 0x60 */
942 .tun1_adc = 0,/* 2 Vpp */
943 .path1_mode = 3,
944};
945
946static struct stb6100_config dw2104a_stb6100_config = {
947 .tuner_address = 0x60,
948 .refclock = 27000000,
949};
950
951static struct stv0900_config dw2104_stv0900_config = {
952 .demod_address = 0x68,
953 .demod_mode = 0,
954 .xtal = 8000000,
955 .clkmode = 3,
956 .diseqc_mode = 2,
957 .tun1_maddress = 0,
958 .tun1_adc = 1,/* 1 Vpp */
959 .path1_mode = 3,
960};
961
962static struct stv6110_config dw2104_stv6110_config = {
963 .i2c_address = 0x60,
964 .mclk = 16000000,
965 .clk_div = 1,
966};
967
968static struct stv0900_config prof_7500_stv0900_config = {
969 .demod_address = 0x6a,
970 .demod_mode = 0,
971 .xtal = 27000000,
972 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
973 .diseqc_mode = 2,/* 2/3 PWM */
974 .tun1_maddress = 0,/* 0x60 */
975 .tun1_adc = 0,/* 2 Vpp */
976 .path1_mode = 3,
977 .tun1_type = 3,
978 .set_lock_led = dw210x_led_ctrl,
979};
980
981static struct ds3000_config su3000_ds3000_config = {
982 .demod_address = 0x68,
983 .ci_mode = 1,
984};
985
986static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
987{
988 struct dvb_tuner_ops *tuner_ops = NULL;
989
990 if (demod_probe & 4) {
991 d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
992 &d->dev->i2c_adap, 0);
993 if (d->fe_adap[0].fe != NULL) {
994 if (dvb_attach(stb6100_attach, d->fe_adap[0].fe,
995 &dw2104a_stb6100_config,
996 &d->dev->i2c_adap)) {
997 tuner_ops = &d->fe_adap[0].fe->ops.tuner_ops;
998 tuner_ops->set_frequency = stb6100_set_freq;
999 tuner_ops->get_frequency = stb6100_get_freq;
1000 tuner_ops->set_bandwidth = stb6100_set_bandw;
1001 tuner_ops->get_bandwidth = stb6100_get_bandw;
1002 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1003 info("Attached STV0900+STB6100!\n");
1004 return 0;
1005 }
1006 }
1007 }
1008
1009 if (demod_probe & 2) {
1010 d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
1011 &d->dev->i2c_adap, 0);
1012 if (d->fe_adap[0].fe != NULL) {
1013 if (dvb_attach(stv6110_attach, d->fe_adap[0].fe,
1014 &dw2104_stv6110_config,
1015 &d->dev->i2c_adap)) {
1016 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1017 info("Attached STV0900+STV6110A!\n");
1018 return 0;
1019 }
1020 }
1021 }
1022
1023 if (demod_probe & 1) {
1024 d->fe_adap[0].fe = dvb_attach(cx24116_attach, &dw2104_config,
1025 &d->dev->i2c_adap);
1026 if (d->fe_adap[0].fe != NULL) {
1027 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1028 info("Attached cx24116!\n");
1029 return 0;
1030 }
1031 }
1032
1033 d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
1034 &d->dev->i2c_adap);
1035 if (d->fe_adap[0].fe != NULL) {
1036 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1037 info("Attached DS3000!\n");
1038 return 0;
1039 }
1040
1041 return -EIO;
1042}
1043
1044static struct dvb_usb_device_properties dw2102_properties;
1045static struct dvb_usb_device_properties dw2104_properties;
1046static struct dvb_usb_device_properties s6x0_properties;
1047
1048static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
1049{
1050 if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
1051 /*dw2102_properties.adapter->tuner_attach = NULL;*/
1052 d->fe_adap[0].fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
1053 &d->dev->i2c_adap);
1054 if (d->fe_adap[0].fe != NULL) {
1055 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1056 info("Attached si21xx!\n");
1057 return 0;
1058 }
1059 }
1060
1061 if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
1062 d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
1063 &d->dev->i2c_adap);
1064 if (d->fe_adap[0].fe != NULL) {
1065 if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61,
1066 &d->dev->i2c_adap)) {
1067 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1068 info("Attached stv0288!\n");
1069 return 0;
1070 }
1071 }
1072 }
1073
1074 if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
1075 /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
1076 d->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
1077 &d->dev->i2c_adap);
1078 if (d->fe_adap[0].fe != NULL) {
1079 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1080 info("Attached stv0299!\n");
1081 return 0;
1082 }
1083 }
1084 return -EIO;
1085}
1086
1087static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
1088{
1089 d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
1090 &d->dev->i2c_adap, 0x48);
1091 if (d->fe_adap[0].fe != NULL) {
1092 info("Attached tda10023!\n");
1093 return 0;
1094 }
1095 return -EIO;
1096}
1097
1098static int zl100313_frontend_attach(struct dvb_usb_adapter *d)
1099{
1100 d->fe_adap[0].fe = dvb_attach(mt312_attach, &zl313_config,
1101 &d->dev->i2c_adap);
1102 if (d->fe_adap[0].fe != NULL) {
1103 if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60,
1104 &d->dev->i2c_adap)) {
1105 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1106 info("Attached zl100313+zl10039!\n");
1107 return 0;
1108 }
1109 }
1110
1111 return -EIO;
1112}
1113
1114static int stv0288_frontend_attach(struct dvb_usb_adapter *d)
1115{
1116 u8 obuf[] = {7, 1};
1117
1118 d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
1119 &d->dev->i2c_adap);
1120
1121 if (d->fe_adap[0].fe == NULL)
1122 return -EIO;
1123
1124 if (NULL == dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, &d->dev->i2c_adap))
1125 return -EIO;
1126
1127 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1128
1129 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1130
1131 info("Attached stv0288+stb6000!\n");
1132
1133 return 0;
1134
1135}
1136
1137static int ds3000_frontend_attach(struct dvb_usb_adapter *d)
1138{
1139 struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
1140 u8 obuf[] = {7, 1};
1141
1142 d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
1143 &d->dev->i2c_adap);
1144
1145 if (d->fe_adap[0].fe == NULL)
1146 return -EIO;
1147
1148 st->old_set_voltage = d->fe_adap[0].fe->ops.set_voltage;
1149 d->fe_adap[0].fe->ops.set_voltage = s660_set_voltage;
1150
1151 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1152
1153 info("Attached ds3000+ds2020!\n");
1154
1155 return 0;
1156}
1157
1158static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
1159{
1160 u8 obuf[] = {7, 1};
1161
1162 d->fe_adap[0].fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
1163 &d->dev->i2c_adap, 0);
1164 if (d->fe_adap[0].fe == NULL)
1165 return -EIO;
1166
1167 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1168
1169 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1170
1171 info("Attached STV0900+STB6100A!\n");
1172
1173 return 0;
1174}
1175
1176static int su3000_frontend_attach(struct dvb_usb_adapter *d)
1177{
1178 u8 obuf[3] = { 0xe, 0x80, 0 };
1179 u8 ibuf[] = { 0 };
1180
1181 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1182 err("command 0x0e transfer failed.");
1183
1184 obuf[0] = 0xe;
1185 obuf[1] = 0x83;
1186 obuf[2] = 0;
1187
1188 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1189 err("command 0x0e transfer failed.");
1190
1191 obuf[0] = 0xe;
1192 obuf[1] = 0x83;
1193 obuf[2] = 1;
1194
1195 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1196 err("command 0x0e transfer failed.");
1197
1198 obuf[0] = 0x51;
1199
1200 if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
1201 err("command 0x51 transfer failed.");
1202
1203 d->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
1204 &d->dev->i2c_adap);
1205 if (d->fe_adap[0].fe == NULL)
1206 return -EIO;
1207
1208 info("Attached DS3000!\n");
1209
1210 return 0;
1211}
1212
1213static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
1214{
1215 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
1216 &adap->dev->i2c_adap, DVB_PLL_OPERA1);
1217 return 0;
1218}
1219
1220static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
1221{
1222 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
1223 &adap->dev->i2c_adap, DVB_PLL_TUA6034);
1224
1225 return 0;
1226}
1227
1228static struct rc_map_table rc_map_dw210x_table[] = {
1229 { 0xf80a, KEY_POWER2 }, /*power*/
1230 { 0xf80c, KEY_MUTE }, /*mute*/
1231 { 0xf811, KEY_1 },
1232 { 0xf812, KEY_2 },
1233 { 0xf813, KEY_3 },
1234 { 0xf814, KEY_4 },
1235 { 0xf815, KEY_5 },
1236 { 0xf816, KEY_6 },
1237 { 0xf817, KEY_7 },
1238 { 0xf818, KEY_8 },
1239 { 0xf819, KEY_9 },
1240 { 0xf810, KEY_0 },
1241 { 0xf81c, KEY_CHANNELUP }, /*ch+*/
1242 { 0xf80f, KEY_CHANNELDOWN }, /*ch-*/
1243 { 0xf81a, KEY_VOLUMEUP }, /*vol+*/
1244 { 0xf80e, KEY_VOLUMEDOWN }, /*vol-*/
1245 { 0xf804, KEY_RECORD }, /*rec*/
1246 { 0xf809, KEY_FAVORITES }, /*fav*/
1247 { 0xf808, KEY_REWIND }, /*rewind*/
1248 { 0xf807, KEY_FASTFORWARD }, /*fast*/
1249 { 0xf80b, KEY_PAUSE }, /*pause*/
1250 { 0xf802, KEY_ESC }, /*cancel*/
1251 { 0xf803, KEY_TAB }, /*tab*/
1252 { 0xf800, KEY_UP }, /*up*/
1253 { 0xf81f, KEY_OK }, /*ok*/
1254 { 0xf801, KEY_DOWN }, /*down*/
1255 { 0xf805, KEY_CAMERA }, /*cap*/
1256 { 0xf806, KEY_STOP }, /*stop*/
1257 { 0xf840, KEY_ZOOM }, /*full*/
1258 { 0xf81e, KEY_TV }, /*tvmode*/
1259 { 0xf81b, KEY_LAST }, /*recall*/
1260};
1261
1262static struct rc_map_table rc_map_tevii_table[] = {
1263 { 0xf80a, KEY_POWER },
1264 { 0xf80c, KEY_MUTE },
1265 { 0xf811, KEY_1 },
1266 { 0xf812, KEY_2 },
1267 { 0xf813, KEY_3 },
1268 { 0xf814, KEY_4 },
1269 { 0xf815, KEY_5 },
1270 { 0xf816, KEY_6 },
1271 { 0xf817, KEY_7 },
1272 { 0xf818, KEY_8 },
1273 { 0xf819, KEY_9 },
1274 { 0xf810, KEY_0 },
1275 { 0xf81c, KEY_MENU },
1276 { 0xf80f, KEY_VOLUMEDOWN },
1277 { 0xf81a, KEY_LAST },
1278 { 0xf80e, KEY_OPEN },
1279 { 0xf804, KEY_RECORD },
1280 { 0xf809, KEY_VOLUMEUP },
1281 { 0xf808, KEY_CHANNELUP },
1282 { 0xf807, KEY_PVR },
1283 { 0xf80b, KEY_TIME },
1284 { 0xf802, KEY_RIGHT },
1285 { 0xf803, KEY_LEFT },
1286 { 0xf800, KEY_UP },
1287 { 0xf81f, KEY_OK },
1288 { 0xf801, KEY_DOWN },
1289 { 0xf805, KEY_TUNER },
1290 { 0xf806, KEY_CHANNELDOWN },
1291 { 0xf840, KEY_PLAYPAUSE },
1292 { 0xf81e, KEY_REWIND },
1293 { 0xf81b, KEY_FAVORITES },
1294 { 0xf81d, KEY_BACK },
1295 { 0xf84d, KEY_FASTFORWARD },
1296 { 0xf844, KEY_EPG },
1297 { 0xf84c, KEY_INFO },
1298 { 0xf841, KEY_AB },
1299 { 0xf843, KEY_AUDIO },
1300 { 0xf845, KEY_SUBTITLE },
1301 { 0xf84a, KEY_LIST },
1302 { 0xf846, KEY_F1 },
1303 { 0xf847, KEY_F2 },
1304 { 0xf85e, KEY_F3 },
1305 { 0xf85c, KEY_F4 },
1306 { 0xf852, KEY_F5 },
1307 { 0xf85a, KEY_F6 },
1308 { 0xf856, KEY_MODE },
1309 { 0xf858, KEY_SWITCHVIDEOMODE },
1310};
1311
1312static struct rc_map_table rc_map_tbs_table[] = {
1313 { 0xf884, KEY_POWER },
1314 { 0xf894, KEY_MUTE },
1315 { 0xf887, KEY_1 },
1316 { 0xf886, KEY_2 },
1317 { 0xf885, KEY_3 },
1318 { 0xf88b, KEY_4 },
1319 { 0xf88a, KEY_5 },
1320 { 0xf889, KEY_6 },
1321 { 0xf88f, KEY_7 },
1322 { 0xf88e, KEY_8 },
1323 { 0xf88d, KEY_9 },
1324 { 0xf892, KEY_0 },
1325 { 0xf896, KEY_CHANNELUP },
1326 { 0xf891, KEY_CHANNELDOWN },
1327 { 0xf893, KEY_VOLUMEUP },
1328 { 0xf88c, KEY_VOLUMEDOWN },
1329 { 0xf883, KEY_RECORD },
1330 { 0xf898, KEY_PAUSE },
1331 { 0xf899, KEY_OK },
1332 { 0xf89a, KEY_SHUFFLE },
1333 { 0xf881, KEY_UP },
1334 { 0xf890, KEY_LEFT },
1335 { 0xf882, KEY_RIGHT },
1336 { 0xf888, KEY_DOWN },
1337 { 0xf895, KEY_FAVORITES },
1338 { 0xf897, KEY_SUBTITLE },
1339 { 0xf89d, KEY_ZOOM },
1340 { 0xf89f, KEY_EXIT },
1341 { 0xf89e, KEY_MENU },
1342 { 0xf89c, KEY_EPG },
1343 { 0xf880, KEY_PREVIOUS },
1344 { 0xf89b, KEY_MODE }
1345};
1346
1347static struct rc_map_table rc_map_su3000_table[] = {
1348 { 0x25, KEY_POWER }, /* right-bottom Red */
1349 { 0x0a, KEY_MUTE }, /* -/-- */
1350 { 0x01, KEY_1 },
1351 { 0x02, KEY_2 },
1352 { 0x03, KEY_3 },
1353 { 0x04, KEY_4 },
1354 { 0x05, KEY_5 },
1355 { 0x06, KEY_6 },
1356 { 0x07, KEY_7 },
1357 { 0x08, KEY_8 },
1358 { 0x09, KEY_9 },
1359 { 0x00, KEY_0 },
1360 { 0x20, KEY_UP }, /* CH+ */
1361 { 0x21, KEY_DOWN }, /* CH+ */
1362 { 0x12, KEY_VOLUMEUP }, /* Brightness Up */
1363 { 0x13, KEY_VOLUMEDOWN },/* Brightness Down */
1364 { 0x1f, KEY_RECORD },
1365 { 0x17, KEY_PLAY },
1366 { 0x16, KEY_PAUSE },
1367 { 0x0b, KEY_STOP },
1368 { 0x27, KEY_FASTFORWARD },/* >> */
1369 { 0x26, KEY_REWIND }, /* << */
1370 { 0x0d, KEY_OK }, /* Mute */
1371 { 0x11, KEY_LEFT }, /* VOL- */
1372 { 0x10, KEY_RIGHT }, /* VOL+ */
1373 { 0x29, KEY_BACK }, /* button under 9 */
1374 { 0x2c, KEY_MENU }, /* TTX */
1375 { 0x2b, KEY_EPG }, /* EPG */
1376 { 0x1e, KEY_RED }, /* OSD */
1377 { 0x0e, KEY_GREEN }, /* Window */
1378 { 0x2d, KEY_YELLOW }, /* button under << */
1379 { 0x0f, KEY_BLUE }, /* bottom yellow button */
1380 { 0x14, KEY_AUDIO }, /* Snapshot */
1381 { 0x38, KEY_TV }, /* TV/Radio */
1382 { 0x0c, KEY_ESC } /* upper Red button */
1383};
1384
1385static struct rc_map_dvb_usb_table_table keys_tables[] = {
1386 { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) },
1387 { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) },
1388 { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) },
1389 { rc_map_su3000_table, ARRAY_SIZE(rc_map_su3000_table) },
1390};
1391
1392static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
1393{
1394 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
1395 int keymap_size = d->props.rc.legacy.rc_map_size;
1396 u8 key[2];
1397 struct i2c_msg msg = {
1398 .addr = DW2102_RC_QUERY,
1399 .flags = I2C_M_RD,
1400 .buf = key,
1401 .len = 2
1402 };
1403 int i;
1404 /* override keymap */
1405 if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) {
1406 keymap = keys_tables[ir_keymap - 1].rc_keys ;
1407 keymap_size = keys_tables[ir_keymap - 1].rc_keys_size;
1408 } else if (ir_keymap > ARRAY_SIZE(keys_tables))
1409 return 0; /* none */
1410
1411 *state = REMOTE_NO_KEY_PRESSED;
1412 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
1413 for (i = 0; i < keymap_size ; i++) {
1414 if (rc5_data(&keymap[i]) == msg.buf[0]) {
1415 *state = REMOTE_KEY_PRESSED;
1416 *event = keymap[i].keycode;
1417 break;
1418 }
1419
1420 }
1421
1422 if ((*state) == REMOTE_KEY_PRESSED)
1423 deb_rc("%s: found rc key: %x, %x, event: %x\n",
1424 __func__, key[0], key[1], (*event));
1425 else if (key[0] != 0xff)
1426 deb_rc("%s: unknown rc key: %x, %x\n",
1427 __func__, key[0], key[1]);
1428
1429 }
1430
1431 return 0;
1432}
1433
1434enum dw2102_table_entry {
1435 CYPRESS_DW2102,
1436 CYPRESS_DW2101,
1437 CYPRESS_DW2104,
1438 TEVII_S650,
1439 TERRATEC_CINERGY_S,
1440 CYPRESS_DW3101,
1441 TEVII_S630,
1442 PROF_1100,
1443 TEVII_S660,
1444 PROF_7500,
1445 GENIATECH_SU3000,
1446 TERRATEC_CINERGY_S2,
1447 TEVII_S480_1,
1448 TEVII_S480_2,
1449 X3M_SPC1400HD,
1450};
1451
1452static struct usb_device_id dw2102_table[] = {
1453 [CYPRESS_DW2102] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
1454 [CYPRESS_DW2101] = {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
1455 [CYPRESS_DW2104] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)},
1456 [TEVII_S650] = {USB_DEVICE(0x9022, USB_PID_TEVII_S650)},
1457 [TERRATEC_CINERGY_S] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
1458 [CYPRESS_DW3101] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
1459 [TEVII_S630] = {USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
1460 [PROF_1100] = {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
1461 [TEVII_S660] = {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
1462 [PROF_7500] = {USB_DEVICE(0x3034, 0x7500)},
1463 [GENIATECH_SU3000] = {USB_DEVICE(0x1f4d, 0x3000)},
1464 [TERRATEC_CINERGY_S2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)},
1465 [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)},
1466 [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
1467 [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)},
1468 { }
1469};
1470
1471MODULE_DEVICE_TABLE(usb, dw2102_table);
1472
1473static int dw2102_load_firmware(struct usb_device *dev,
1474 const struct firmware *frmwr)
1475{
1476 u8 *b, *p;
1477 int ret = 0, i;
1478 u8 reset;
1479 u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
1480 const struct firmware *fw;
1481 const char *fw_2101 = "dvb-usb-dw2101.fw";
1482
1483 switch (dev->descriptor.idProduct) {
1484 case 0x2101:
1485 ret = request_firmware(&fw, fw_2101, &dev->dev);
1486 if (ret != 0) {
1487 err(err_str, fw_2101);
1488 return ret;
1489 }
1490 break;
1491 default:
1492 fw = frmwr;
1493 break;
1494 }
1495 info("start downloading DW210X firmware");
1496 p = kmalloc(fw->size, GFP_KERNEL);
1497 reset = 1;
1498 /*stop the CPU*/
1499 dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
1500 dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
1501
1502 if (p != NULL) {
1503 memcpy(p, fw->data, fw->size);
1504 for (i = 0; i < fw->size; i += 0x40) {
1505 b = (u8 *) p + i;
1506 if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
1507 DW210X_WRITE_MSG) != 0x40) {
1508 err("error while transferring firmware");
1509 ret = -EINVAL;
1510 break;
1511 }
1512 }
1513 /* restart the CPU */
1514 reset = 0;
1515 if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
1516 DW210X_WRITE_MSG) != 1) {
1517 err("could not restart the USB controller CPU.");
1518 ret = -EINVAL;
1519 }
1520 if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
1521 DW210X_WRITE_MSG) != 1) {
1522 err("could not restart the USB controller CPU.");
1523 ret = -EINVAL;
1524 }
1525 /* init registers */
1526 switch (dev->descriptor.idProduct) {
1527 case USB_PID_TEVII_S650:
1528 dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table;
1529 dw2104_properties.rc.legacy.rc_map_size =
1530 ARRAY_SIZE(rc_map_tevii_table);
1531 case USB_PID_DW2104:
1532 reset = 1;
1533 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
1534 DW210X_WRITE_MSG);
1535 /* break omitted intentionally */
1536 case USB_PID_DW3101:
1537 reset = 0;
1538 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
1539 DW210X_WRITE_MSG);
1540 break;
1541 case USB_PID_CINERGY_S:
1542 case USB_PID_DW2102:
1543 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
1544 DW210X_WRITE_MSG);
1545 dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
1546 DW210X_READ_MSG);
1547 /* check STV0299 frontend */
1548 dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
1549 DW210X_READ_MSG);
1550 if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) {
1551 dw2102_properties.i2c_algo = &dw2102_i2c_algo;
1552 dw2102_properties.adapter->fe[0].tuner_attach = &dw2102_tuner_attach;
1553 break;
1554 } else {
1555 /* check STV0288 frontend */
1556 reset16[0] = 0xd0;
1557 reset16[1] = 1;
1558 reset16[2] = 0;
1559 dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
1560 DW210X_WRITE_MSG);
1561 dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
1562 DW210X_READ_MSG);
1563 if (reset16[2] == 0x11) {
1564 dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
1565 break;
1566 }
1567 }
1568 case 0x2101:
1569 dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
1570 DW210X_READ_MSG);
1571 dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
1572 DW210X_READ_MSG);
1573 dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
1574 DW210X_READ_MSG);
1575 dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
1576 DW210X_READ_MSG);
1577 break;
1578 }
1579
1580 msleep(100);
1581 kfree(p);
1582 }
1583 return ret;
1584}
1585
1586static struct dvb_usb_device_properties dw2102_properties = {
1587 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1588 .usb_ctrl = DEVICE_SPECIFIC,
1589 .firmware = "dvb-usb-dw2102.fw",
1590 .no_reconnect = 1,
1591
1592 .i2c_algo = &dw2102_serit_i2c_algo,
1593
1594 .rc.legacy = {
1595 .rc_map_table = rc_map_dw210x_table,
1596 .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
1597 .rc_interval = 150,
1598 .rc_query = dw2102_rc_query,
1599 },
1600
1601 .generic_bulk_ctrl_endpoint = 0x81,
1602 /* parameter for the MPEG2-data transfer */
1603 .num_adapters = 1,
1604 .download_firmware = dw2102_load_firmware,
1605 .read_mac_address = dw210x_read_mac_address,
1606 .adapter = {
1607 {
1608 .num_frontends = 1,
1609 .fe = {{
1610 .frontend_attach = dw2102_frontend_attach,
1611 .stream = {
1612 .type = USB_BULK,
1613 .count = 8,
1614 .endpoint = 0x82,
1615 .u = {
1616 .bulk = {
1617 .buffersize = 4096,
1618 }
1619 }
1620 },
1621 }},
1622 }
1623 },
1624 .num_device_descs = 3,
1625 .devices = {
1626 {"DVBWorld DVB-S 2102 USB2.0",
1627 {&dw2102_table[CYPRESS_DW2102], NULL},
1628 {NULL},
1629 },
1630 {"DVBWorld DVB-S 2101 USB2.0",
1631 {&dw2102_table[CYPRESS_DW2101], NULL},
1632 {NULL},
1633 },
1634 {"TerraTec Cinergy S USB",
1635 {&dw2102_table[TERRATEC_CINERGY_S], NULL},
1636 {NULL},
1637 },
1638 }
1639};
1640
1641static struct dvb_usb_device_properties dw2104_properties = {
1642 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1643 .usb_ctrl = DEVICE_SPECIFIC,
1644 .firmware = "dvb-usb-dw2104.fw",
1645 .no_reconnect = 1,
1646
1647 .i2c_algo = &dw2104_i2c_algo,
1648 .rc.legacy = {
1649 .rc_map_table = rc_map_dw210x_table,
1650 .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
1651 .rc_interval = 150,
1652 .rc_query = dw2102_rc_query,
1653 },
1654
1655 .generic_bulk_ctrl_endpoint = 0x81,
1656 /* parameter for the MPEG2-data transfer */
1657 .num_adapters = 1,
1658 .download_firmware = dw2102_load_firmware,
1659 .read_mac_address = dw210x_read_mac_address,
1660 .adapter = {
1661 {
1662 .num_frontends = 1,
1663 .fe = {{
1664 .frontend_attach = dw2104_frontend_attach,
1665 .stream = {
1666 .type = USB_BULK,
1667 .count = 8,
1668 .endpoint = 0x82,
1669 .u = {
1670 .bulk = {
1671 .buffersize = 4096,
1672 }
1673 }
1674 },
1675 }},
1676 }
1677 },
1678 .num_device_descs = 2,
1679 .devices = {
1680 { "DVBWorld DW2104 USB2.0",
1681 {&dw2102_table[CYPRESS_DW2104], NULL},
1682 {NULL},
1683 },
1684 { "TeVii S650 USB2.0",
1685 {&dw2102_table[TEVII_S650], NULL},
1686 {NULL},
1687 },
1688 }
1689};
1690
1691static struct dvb_usb_device_properties dw3101_properties = {
1692 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1693 .usb_ctrl = DEVICE_SPECIFIC,
1694 .firmware = "dvb-usb-dw3101.fw",
1695 .no_reconnect = 1,
1696
1697 .i2c_algo = &dw3101_i2c_algo,
1698 .rc.legacy = {
1699 .rc_map_table = rc_map_dw210x_table,
1700 .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
1701 .rc_interval = 150,
1702 .rc_query = dw2102_rc_query,
1703 },
1704
1705 .generic_bulk_ctrl_endpoint = 0x81,
1706 /* parameter for the MPEG2-data transfer */
1707 .num_adapters = 1,
1708 .download_firmware = dw2102_load_firmware,
1709 .read_mac_address = dw210x_read_mac_address,
1710 .adapter = {
1711 {
1712 .num_frontends = 1,
1713 .fe = {{
1714 .frontend_attach = dw3101_frontend_attach,
1715 .tuner_attach = dw3101_tuner_attach,
1716 .stream = {
1717 .type = USB_BULK,
1718 .count = 8,
1719 .endpoint = 0x82,
1720 .u = {
1721 .bulk = {
1722 .buffersize = 4096,
1723 }
1724 }
1725 },
1726 }},
1727 }
1728 },
1729 .num_device_descs = 1,
1730 .devices = {
1731 { "DVBWorld DVB-C 3101 USB2.0",
1732 {&dw2102_table[CYPRESS_DW3101], NULL},
1733 {NULL},
1734 },
1735 }
1736};
1737
1738static struct dvb_usb_device_properties s6x0_properties = {
1739 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1740 .usb_ctrl = DEVICE_SPECIFIC,
1741 .size_of_priv = sizeof(struct s6x0_state),
1742 .firmware = "dvb-usb-s630.fw",
1743 .no_reconnect = 1,
1744
1745 .i2c_algo = &s6x0_i2c_algo,
1746 .rc.legacy = {
1747 .rc_map_table = rc_map_tevii_table,
1748 .rc_map_size = ARRAY_SIZE(rc_map_tevii_table),
1749 .rc_interval = 150,
1750 .rc_query = dw2102_rc_query,
1751 },
1752
1753 .generic_bulk_ctrl_endpoint = 0x81,
1754 .num_adapters = 1,
1755 .download_firmware = dw2102_load_firmware,
1756 .read_mac_address = s6x0_read_mac_address,
1757 .adapter = {
1758 {
1759 .num_frontends = 1,
1760 .fe = {{
1761 .frontend_attach = zl100313_frontend_attach,
1762 .stream = {
1763 .type = USB_BULK,
1764 .count = 8,
1765 .endpoint = 0x82,
1766 .u = {
1767 .bulk = {
1768 .buffersize = 4096,
1769 }
1770 }
1771 },
1772 }},
1773 }
1774 },
1775 .num_device_descs = 1,
1776 .devices = {
1777 {"TeVii S630 USB",
1778 {&dw2102_table[TEVII_S630], NULL},
1779 {NULL},
1780 },
1781 }
1782};
1783
1784struct dvb_usb_device_properties *p1100;
1785static struct dvb_usb_device_description d1100 = {
1786 "Prof 1100 USB ",
1787 {&dw2102_table[PROF_1100], NULL},
1788 {NULL},
1789};
1790
1791struct dvb_usb_device_properties *s660;
1792static struct dvb_usb_device_description d660 = {
1793 "TeVii S660 USB",
1794 {&dw2102_table[TEVII_S660], NULL},
1795 {NULL},
1796};
1797
1798static struct dvb_usb_device_description d480_1 = {
1799 "TeVii S480.1 USB",
1800 {&dw2102_table[TEVII_S480_1], NULL},
1801 {NULL},
1802};
1803
1804static struct dvb_usb_device_description d480_2 = {
1805 "TeVii S480.2 USB",
1806 {&dw2102_table[TEVII_S480_2], NULL},
1807 {NULL},
1808};
1809
1810struct dvb_usb_device_properties *p7500;
1811static struct dvb_usb_device_description d7500 = {
1812 "Prof 7500 USB DVB-S2",
1813 {&dw2102_table[PROF_7500], NULL},
1814 {NULL},
1815};
1816
1817static struct dvb_usb_device_properties su3000_properties = {
1818 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1819 .usb_ctrl = DEVICE_SPECIFIC,
1820 .size_of_priv = sizeof(struct su3000_state),
1821 .power_ctrl = su3000_power_ctrl,
1822 .num_adapters = 1,
1823 .identify_state = su3000_identify_state,
1824 .i2c_algo = &su3000_i2c_algo,
1825
1826 .rc.legacy = {
1827 .rc_map_table = rc_map_su3000_table,
1828 .rc_map_size = ARRAY_SIZE(rc_map_su3000_table),
1829 .rc_interval = 150,
1830 .rc_query = dw2102_rc_query,
1831 },
1832
1833 .read_mac_address = su3000_read_mac_address,
1834
1835 .generic_bulk_ctrl_endpoint = 0x01,
1836
1837 .adapter = {
1838 {
1839 .num_frontends = 1,
1840 .fe = {{
1841 .streaming_ctrl = su3000_streaming_ctrl,
1842 .frontend_attach = su3000_frontend_attach,
1843 .stream = {
1844 .type = USB_BULK,
1845 .count = 8,
1846 .endpoint = 0x82,
1847 .u = {
1848 .bulk = {
1849 .buffersize = 4096,
1850 }
1851 }
1852 }
1853 }},
1854 }
1855 },
1856 .num_device_descs = 3,
1857 .devices = {
1858 { "SU3000HD DVB-S USB2.0",
1859 { &dw2102_table[GENIATECH_SU3000], NULL },
1860 { NULL },
1861 },
1862 { "Terratec Cinergy S2 USB HD",
1863 { &dw2102_table[TERRATEC_CINERGY_S2], NULL },
1864 { NULL },
1865 },
1866 { "X3M TV SPC1400HD PCI",
1867 { &dw2102_table[X3M_SPC1400HD], NULL },
1868 { NULL },
1869 },
1870 }
1871};
1872
1873static int dw2102_probe(struct usb_interface *intf,
1874 const struct usb_device_id *id)
1875{
1876 p1100 = kmemdup(&s6x0_properties,
1877 sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1878 if (!p1100)
1879 return -ENOMEM;
1880 /* copy default structure */
1881 /* fill only different fields */
1882 p1100->firmware = "dvb-usb-p1100.fw";
1883 p1100->devices[0] = d1100;
1884 p1100->rc.legacy.rc_map_table = rc_map_tbs_table;
1885 p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
1886 p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach;
1887
1888 s660 = kmemdup(&s6x0_properties,
1889 sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1890 if (!s660) {
1891 kfree(p1100);
1892 return -ENOMEM;
1893 }
1894 s660->firmware = "dvb-usb-s660.fw";
1895 s660->num_device_descs = 3;
1896 s660->devices[0] = d660;
1897 s660->devices[1] = d480_1;
1898 s660->devices[2] = d480_2;
1899 s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach;
1900
1901 p7500 = kmemdup(&s6x0_properties,
1902 sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1903 if (!p7500) {
1904 kfree(p1100);
1905 kfree(s660);
1906 return -ENOMEM;
1907 }
1908 p7500->firmware = "dvb-usb-p7500.fw";
1909 p7500->devices[0] = d7500;
1910 p7500->rc.legacy.rc_map_table = rc_map_tbs_table;
1911 p7500->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
1912 p7500->adapter->fe[0].frontend_attach = prof_7500_frontend_attach;
1913
1914 if (0 == dvb_usb_device_init(intf, &dw2102_properties,
1915 THIS_MODULE, NULL, adapter_nr) ||
1916 0 == dvb_usb_device_init(intf, &dw2104_properties,
1917 THIS_MODULE, NULL, adapter_nr) ||
1918 0 == dvb_usb_device_init(intf, &dw3101_properties,
1919 THIS_MODULE, NULL, adapter_nr) ||
1920 0 == dvb_usb_device_init(intf, &s6x0_properties,
1921 THIS_MODULE, NULL, adapter_nr) ||
1922 0 == dvb_usb_device_init(intf, p1100,
1923 THIS_MODULE, NULL, adapter_nr) ||
1924 0 == dvb_usb_device_init(intf, s660,
1925 THIS_MODULE, NULL, adapter_nr) ||
1926 0 == dvb_usb_device_init(intf, p7500,
1927 THIS_MODULE, NULL, adapter_nr) ||
1928 0 == dvb_usb_device_init(intf, &su3000_properties,
1929 THIS_MODULE, NULL, adapter_nr))
1930 return 0;
1931
1932 return -ENODEV;
1933}
1934
1935static struct usb_driver dw2102_driver = {
1936 .name = "dw2102",
1937 .probe = dw2102_probe,
1938 .disconnect = dvb_usb_device_exit,
1939 .id_table = dw2102_table,
1940};
1941
1942module_usb_driver(dw2102_driver);
1943
1944MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
1945MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
1946 " DVB-C 3101 USB2.0,"
1947 " TeVii S600, S630, S650, S660, S480,"
1948 " Prof 1100, 7500 USB2.0,"
1949 " Geniatech SU3000 devices");
1950MODULE_VERSION("0.1");
1951MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dw2102.h b/drivers/media/usb/dvb-usb/dw2102.h
new file mode 100644
index 000000000000..5cd0b0eb6ce1
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/friio-fe.c b/drivers/media/usb/dvb-usb/friio-fe.c
new file mode 100644
index 000000000000..90a70c66a96e
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/friio-fe.c
@@ -0,0 +1,473 @@
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{
287 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
288 p->inversion = INVERSION_AUTO;
289 p->bandwidth_hz = 6000000;
290 p->code_rate_HP = FEC_AUTO;
291 p->code_rate_LP = FEC_AUTO;
292 p->modulation = QAM_64;
293 p->transmission_mode = TRANSMISSION_MODE_AUTO;
294 p->guard_interval = GUARD_INTERVAL_AUTO;
295 p->hierarchy = HIERARCHY_AUTO;
296 return 0;
297}
298
299static int jdvbt90502_set_frontend(struct dvb_frontend *fe)
300{
301 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
302
303 /**
304 * NOTE: ignore all the parameters except frequency.
305 * others should be fixed to the proper value for ISDB-T,
306 * but don't check here.
307 */
308
309 struct jdvbt90502_state *state = fe->demodulator_priv;
310 int ret;
311
312 deb_fe("%s: Freq:%d\n", __func__, p->frequency);
313
314 /* for recovery from DTV_CLEAN */
315 fe->dtv_property_cache.delivery_system = SYS_ISDBT;
316
317 ret = jdvbt90502_pll_set_freq(state, p->frequency);
318 if (ret) {
319 deb_fe("%s:ret == %d\n", __func__, ret);
320 return -EREMOTEIO;
321 }
322
323 return 0;
324}
325
326
327/**
328 * (reg, val) commad list to initialize this module.
329 * captured on a Windows box.
330 */
331static u8 init_code[][2] = {
332 {0x01, 0x40},
333 {0x04, 0x38},
334 {0x05, 0x40},
335 {0x07, 0x40},
336 {0x0F, 0x4F},
337 {0x11, 0x21},
338 {0x12, 0x0B},
339 {0x13, 0x2F},
340 {0x14, 0x31},
341 {0x16, 0x02},
342 {0x21, 0xC4},
343 {0x22, 0x20},
344 {0x2C, 0x79},
345 {0x2D, 0x34},
346 {0x2F, 0x00},
347 {0x30, 0x28},
348 {0x31, 0x31},
349 {0x32, 0xDF},
350 {0x38, 0x01},
351 {0x39, 0x78},
352 {0x3B, 0x33},
353 {0x3C, 0x33},
354 {0x48, 0x90},
355 {0x51, 0x68},
356 {0x5E, 0x38},
357 {0x71, 0x00},
358 {0x72, 0x08},
359 {0x77, 0x00},
360 {0xC0, 0x21},
361 {0xC1, 0x10},
362 {0xE4, 0x1A},
363 {0xEA, 0x1F},
364 {0x77, 0x00},
365 {0x71, 0x00},
366 {0x71, 0x00},
367 {0x76, 0x0C},
368};
369
370static const int init_code_len = sizeof(init_code) / sizeof(u8[2]);
371
372static int jdvbt90502_init(struct dvb_frontend *fe)
373{
374 int i = -1;
375 int ret;
376 struct i2c_msg msg;
377
378 struct jdvbt90502_state *state = fe->demodulator_priv;
379
380 deb_fe("%s called.\n", __func__);
381
382 msg.addr = state->config.demod_address;
383 msg.flags = 0;
384 msg.len = 2;
385 for (i = 0; i < init_code_len; i++) {
386 msg.buf = init_code[i];
387 ret = i2c_transfer(state->i2c, &msg, 1);
388 if (ret != 1)
389 goto error;
390 }
391 fe->dtv_property_cache.delivery_system = SYS_ISDBT;
392 msleep(100);
393
394 return 0;
395
396error:
397 deb_fe("%s: init_code[%d] failed. ret==%d\n", __func__, i, ret);
398 return -EREMOTEIO;
399}
400
401
402static void jdvbt90502_release(struct dvb_frontend *fe)
403{
404 struct jdvbt90502_state *state = fe->demodulator_priv;
405 kfree(state);
406}
407
408
409static struct dvb_frontend_ops jdvbt90502_ops;
410
411struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d)
412{
413 struct jdvbt90502_state *state = NULL;
414
415 deb_info("%s called.\n", __func__);
416
417 /* allocate memory for the internal state */
418 state = kzalloc(sizeof(struct jdvbt90502_state), GFP_KERNEL);
419 if (state == NULL)
420 goto error;
421
422 /* setup the state */
423 state->i2c = &d->i2c_adap;
424 memcpy(&state->config, &friio_fe_config, sizeof(friio_fe_config));
425
426 /* create dvb_frontend */
427 memcpy(&state->frontend.ops, &jdvbt90502_ops,
428 sizeof(jdvbt90502_ops));
429 state->frontend.demodulator_priv = state;
430
431 if (jdvbt90502_init(&state->frontend) < 0)
432 goto error;
433
434 return &state->frontend;
435
436error:
437 kfree(state);
438 return NULL;
439}
440
441static struct dvb_frontend_ops jdvbt90502_ops = {
442 .delsys = { SYS_ISDBT },
443 .info = {
444 .name = "Comtech JDVBT90502 ISDB-T",
445 .frequency_min = 473000000, /* UHF 13ch, center */
446 .frequency_max = 767142857, /* UHF 62ch, center */
447 .frequency_stepsize = JDVBT90502_PLL_CLK / JDVBT90502_PLL_DIVIDER,
448 .frequency_tolerance = 0,
449
450 /* NOTE: this driver ignores all parameters but frequency. */
451 .caps = FE_CAN_INVERSION_AUTO |
452 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
453 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
454 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
455 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
456 FE_CAN_TRANSMISSION_MODE_AUTO |
457 FE_CAN_GUARD_INTERVAL_AUTO |
458 FE_CAN_HIERARCHY_AUTO,
459 },
460
461 .release = jdvbt90502_release,
462
463 .init = jdvbt90502_init,
464 .write = _jdvbt90502_write,
465
466 .set_property = jdvbt90502_set_property,
467
468 .set_frontend = jdvbt90502_set_frontend,
469 .get_frontend = jdvbt90502_get_frontend,
470
471 .read_status = jdvbt90502_read_status,
472 .read_signal_strength = jdvbt90502_read_signal_strength,
473};
diff --git a/drivers/media/usb/dvb-usb/friio.c b/drivers/media/usb/dvb-usb/friio.c
new file mode 100644
index 000000000000..474a17e4db0c
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/friio.c
@@ -0,0 +1,522 @@
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_adap[0].fe = jdvbt90502_attach(adap->dev);
407 if (adap->fe_adap[0].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 .num_frontends = 1,
477 .fe = {{
478 .caps = 0,
479
480 .frontend_attach = friio_frontend_attach,
481 .streaming_ctrl = friio_streaming_ctrl,
482
483 .stream = {
484 .type = USB_BULK,
485 /* count <= MAX_NO_URBS_FOR_DATA_STREAM(10) */
486 .count = 8,
487 .endpoint = 0x01,
488 .u = {
489 /* GL861 has 6KB buf inside */
490 .bulk = {
491 .buffersize = 16384,
492 }
493 }
494 },
495 }},
496 }
497 },
498 .i2c_algo = &gl861_i2c_algo,
499
500 .num_device_descs = 1,
501 .devices = {
502 {
503 .name = "774 Friio ISDB-T USB2.0",
504 .cold_ids = { NULL },
505 .warm_ids = { &friio_table[0], NULL },
506 },
507 }
508};
509
510static struct usb_driver friio_driver = {
511 .name = "dvb_usb_friio",
512 .probe = friio_probe,
513 .disconnect = dvb_usb_device_exit,
514 .id_table = friio_table,
515};
516
517module_usb_driver(friio_driver);
518
519MODULE_AUTHOR("Akihiro Tsukada <tskd2@yahoo.co.jp>");
520MODULE_DESCRIPTION("Driver for Friio ISDB-T USB2.0 Receiver");
521MODULE_VERSION("0.2");
522MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/friio.h b/drivers/media/usb/dvb-usb/friio.h
new file mode 100644
index 000000000000..0f461ca10cb9
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/gp8psk-fe.c b/drivers/media/usb/dvb-usb/gp8psk-fe.c
new file mode 100644
index 000000000000..67957dd99ede
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/gp8psk-fe.c
@@ -0,0 +1,369 @@
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_frontend(struct dvb_frontend *fe)
117{
118 struct gp8psk_fe_state *state = fe->demodulator_priv;
119 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
120 u8 cmd[10];
121 u32 freq = c->frequency * 1000;
122 int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct);
123
124 deb_fe("%s()\n", __func__);
125
126 cmd[4] = freq & 0xff;
127 cmd[5] = (freq >> 8) & 0xff;
128 cmd[6] = (freq >> 16) & 0xff;
129 cmd[7] = (freq >> 24) & 0xff;
130
131 /* backwards compatibility: DVB-S + 8-PSK were used for Turbo-FEC */
132 if (c->delivery_system == SYS_DVBS && c->modulation == PSK_8)
133 c->delivery_system = SYS_TURBO;
134
135 switch (c->delivery_system) {
136 case SYS_DVBS:
137 if (c->modulation != QPSK) {
138 deb_fe("%s: unsupported modulation selected (%d)\n",
139 __func__, c->modulation);
140 return -EOPNOTSUPP;
141 }
142 c->fec_inner = FEC_AUTO;
143 break;
144 case SYS_DVBS2: /* kept for backwards compatibility */
145 deb_fe("%s: DVB-S2 delivery system selected\n", __func__);
146 break;
147 case SYS_TURBO:
148 deb_fe("%s: Turbo-FEC delivery system selected\n", __func__);
149 break;
150
151 default:
152 deb_fe("%s: unsupported delivery system selected (%d)\n",
153 __func__, c->delivery_system);
154 return -EOPNOTSUPP;
155 }
156
157 cmd[0] = c->symbol_rate & 0xff;
158 cmd[1] = (c->symbol_rate >> 8) & 0xff;
159 cmd[2] = (c->symbol_rate >> 16) & 0xff;
160 cmd[3] = (c->symbol_rate >> 24) & 0xff;
161 switch (c->modulation) {
162 case QPSK:
163 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
164 if (gp8psk_tuned_to_DCII(fe))
165 gp8psk_bcm4500_reload(state->d);
166 switch (c->fec_inner) {
167 case FEC_1_2:
168 cmd[9] = 0; break;
169 case FEC_2_3:
170 cmd[9] = 1; break;
171 case FEC_3_4:
172 cmd[9] = 2; break;
173 case FEC_5_6:
174 cmd[9] = 3; break;
175 case FEC_7_8:
176 cmd[9] = 4; break;
177 case FEC_AUTO:
178 cmd[9] = 5; break;
179 default:
180 cmd[9] = 5; break;
181 }
182 if (c->delivery_system == SYS_TURBO)
183 cmd[8] = ADV_MOD_TURBO_QPSK;
184 else
185 cmd[8] = ADV_MOD_DVB_QPSK;
186 break;
187 case PSK_8: /* PSK_8 is for compatibility with DN */
188 cmd[8] = ADV_MOD_TURBO_8PSK;
189 switch (c->fec_inner) {
190 case FEC_2_3:
191 cmd[9] = 0; break;
192 case FEC_3_4:
193 cmd[9] = 1; break;
194 case FEC_3_5:
195 cmd[9] = 2; break;
196 case FEC_5_6:
197 cmd[9] = 3; break;
198 case FEC_8_9:
199 cmd[9] = 4; break;
200 default:
201 cmd[9] = 0; break;
202 }
203 break;
204 case QAM_16: /* QAM_16 is for compatibility with DN */
205 cmd[8] = ADV_MOD_TURBO_16QAM;
206 cmd[9] = 0;
207 break;
208 default: /* Unknown modulation */
209 deb_fe("%s: unsupported modulation selected (%d)\n",
210 __func__, c->modulation);
211 return -EOPNOTSUPP;
212 }
213
214 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
215 gp8psk_set_tuner_mode(fe, 0);
216 gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10);
217
218 state->lock = 0;
219 state->next_status_check = jiffies;
220 state->status_check_interval = 200;
221
222 return 0;
223}
224
225static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
226 struct dvb_diseqc_master_cmd *m)
227{
228 struct gp8psk_fe_state *st = fe->demodulator_priv;
229
230 deb_fe("%s\n",__func__);
231
232 if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0,
233 m->msg, m->msg_len)) {
234 return -EINVAL;
235 }
236 return 0;
237}
238
239static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe,
240 fe_sec_mini_cmd_t burst)
241{
242 struct gp8psk_fe_state *st = fe->demodulator_priv;
243 u8 cmd;
244
245 deb_fe("%s\n",__func__);
246
247 /* These commands are certainly wrong */
248 cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01;
249
250 if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0,
251 &cmd, 0)) {
252 return -EINVAL;
253 }
254 return 0;
255}
256
257static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
258{
259 struct gp8psk_fe_state* state = fe->demodulator_priv;
260
261 if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE,
262 (tone == SEC_TONE_ON), 0, NULL, 0)) {
263 return -EINVAL;
264 }
265 return 0;
266}
267
268static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
269{
270 struct gp8psk_fe_state* state = fe->demodulator_priv;
271
272 if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE,
273 voltage == SEC_VOLTAGE_18, 0, NULL, 0)) {
274 return -EINVAL;
275 }
276 return 0;
277}
278
279static int gp8psk_fe_enable_high_lnb_voltage(struct dvb_frontend* fe, long onoff)
280{
281 struct gp8psk_fe_state* state = fe->demodulator_priv;
282 return gp8psk_usb_out_op(state->d, USE_EXTRA_VOLT, onoff, 0,NULL,0);
283}
284
285static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
286{
287 struct gp8psk_fe_state* state = fe->demodulator_priv;
288 u8 cmd = sw_cmd & 0x7f;
289
290 if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0,
291 NULL, 0)) {
292 return -EINVAL;
293 }
294 if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
295 0, NULL, 0)) {
296 return -EINVAL;
297 }
298
299 return 0;
300}
301
302static void gp8psk_fe_release(struct dvb_frontend* fe)
303{
304 struct gp8psk_fe_state *state = fe->demodulator_priv;
305 kfree(state);
306}
307
308static struct dvb_frontend_ops gp8psk_fe_ops;
309
310struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
311{
312 struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
313 if (s == NULL)
314 goto error;
315
316 s->d = d;
317 memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
318 s->fe.demodulator_priv = s;
319
320 goto success;
321error:
322 return NULL;
323success:
324 return &s->fe;
325}
326
327
328static struct dvb_frontend_ops gp8psk_fe_ops = {
329 .delsys = { SYS_DVBS },
330 .info = {
331 .name = "Genpix DVB-S",
332 .frequency_min = 800000,
333 .frequency_max = 2250000,
334 .frequency_stepsize = 100,
335 .symbol_rate_min = 1000000,
336 .symbol_rate_max = 45000000,
337 .symbol_rate_tolerance = 500, /* ppm */
338 .caps = FE_CAN_INVERSION_AUTO |
339 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
340 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
341 /*
342 * FE_CAN_QAM_16 is for compatibility
343 * (Myth incorrectly detects Turbo-QPSK as plain QAM-16)
344 */
345 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_TURBO_FEC
346 },
347
348 .release = gp8psk_fe_release,
349
350 .init = NULL,
351 .sleep = NULL,
352
353 .set_frontend = gp8psk_fe_set_frontend,
354
355 .get_tune_settings = gp8psk_fe_get_tune_settings,
356
357 .read_status = gp8psk_fe_read_status,
358 .read_ber = gp8psk_fe_read_ber,
359 .read_signal_strength = gp8psk_fe_read_signal_strength,
360 .read_snr = gp8psk_fe_read_snr,
361 .read_ucblocks = gp8psk_fe_read_unc_blocks,
362
363 .diseqc_send_master_cmd = gp8psk_fe_send_diseqc_msg,
364 .diseqc_send_burst = gp8psk_fe_send_diseqc_burst,
365 .set_tone = gp8psk_fe_set_tone,
366 .set_voltage = gp8psk_fe_set_voltage,
367 .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd,
368 .enable_high_lnb_voltage = gp8psk_fe_enable_high_lnb_voltage
369};
diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
new file mode 100644
index 000000000000..5d0384dd45b5
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/gp8psk.c
@@ -0,0 +1,328 @@
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_adap[0].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 .num_frontends = 1,
272 .fe = {{
273 .streaming_ctrl = gp8psk_streaming_ctrl,
274 .frontend_attach = gp8psk_frontend_attach,
275 /* parameter for the MPEG2-data transfer */
276 .stream = {
277 .type = USB_BULK,
278 .count = 7,
279 .endpoint = 0x82,
280 .u = {
281 .bulk = {
282 .buffersize = 8192,
283 }
284 }
285 },
286 }},
287 }
288 },
289 .power_ctrl = gp8psk_power_ctrl,
290
291 .generic_bulk_ctrl_endpoint = 0x01,
292
293 .num_device_descs = 4,
294 .devices = {
295 { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver",
296 .cold_ids = { &gp8psk_usb_table[0], NULL },
297 .warm_ids = { &gp8psk_usb_table[1], NULL },
298 },
299 { .name = "Genpix 8PSK-to-USB2 Rev.2 DVB-S receiver",
300 .cold_ids = { NULL },
301 .warm_ids = { &gp8psk_usb_table[2], NULL },
302 },
303 { .name = "Genpix SkyWalker-1 DVB-S receiver",
304 .cold_ids = { NULL },
305 .warm_ids = { &gp8psk_usb_table[3], NULL },
306 },
307 { .name = "Genpix SkyWalker-2 DVB-S receiver",
308 .cold_ids = { NULL },
309 .warm_ids = { &gp8psk_usb_table[4], NULL },
310 },
311 { NULL },
312 }
313};
314
315/* usb specific object needed to register this driver with the usb subsystem */
316static struct usb_driver gp8psk_usb_driver = {
317 .name = "dvb_usb_gp8psk",
318 .probe = gp8psk_usb_probe,
319 .disconnect = dvb_usb_device_exit,
320 .id_table = gp8psk_usb_table,
321};
322
323module_usb_driver(gp8psk_usb_driver);
324
325MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>");
326MODULE_DESCRIPTION("Driver for Genpix DVB-S");
327MODULE_VERSION("1.1");
328MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/gp8psk.h b/drivers/media/usb/dvb-usb/gp8psk.h
new file mode 100644
index 000000000000..ed32b9da4843
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c
new file mode 100644
index 000000000000..288af29a8bb7
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/m920x.c
@@ -0,0 +1,1099 @@
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.fe[0].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.fe[0].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.fe[0].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 adap->fe_adap[0].fe = dvb_attach(mt352_attach,
505 &m920x_mt352_config,
506 &adap->dev->i2c_adap);
507 if ((adap->fe_adap[0].fe) == NULL)
508 return -EIO;
509
510 return 0;
511}
512
513static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap)
514{
515 deb("%s\n",__func__);
516
517 adap->fe_adap[0].fe = dvb_attach(tda10046_attach,
518 &m920x_tda10046_08_config,
519 &adap->dev->i2c_adap);
520 if ((adap->fe_adap[0].fe) == NULL)
521 return -EIO;
522
523 return 0;
524}
525
526static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap)
527{
528 deb("%s\n",__func__);
529
530 adap->fe_adap[0].fe = dvb_attach(tda10046_attach,
531 &m920x_tda10046_0b_config,
532 &adap->dev->i2c_adap);
533 if ((adap->fe_adap[0].fe) == NULL)
534 return -EIO;
535
536 return 0;
537}
538
539static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
540{
541 deb("%s\n",__func__);
542
543 if (dvb_attach(qt1010_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL)
544 return -ENODEV;
545
546 return 0;
547}
548
549static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap)
550{
551 deb("%s\n",__func__);
552
553 if (dvb_attach(tda827x_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL)
554 return -ENODEV;
555
556 return 0;
557}
558
559static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap)
560{
561 deb("%s\n",__func__);
562
563 if (dvb_attach(tda827x_attach, adap->fe_adap[0].fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL)
564 return -ENODEV;
565
566 return 0;
567}
568
569static int m920x_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
570{
571 dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
572 &adap->dev->i2c_adap, 0x61,
573 TUNER_PHILIPS_FMD1216ME_MK3);
574 return 0;
575}
576
577/* device-specific initialization */
578static struct m920x_inits megasky_rc_init [] = {
579 { M9206_RC_INIT2, 0xa8 },
580 { M9206_RC_INIT1, 0x51 },
581 { } /* terminating entry */
582};
583
584static struct m920x_inits tvwalkertwin_rc_init [] = {
585 { M9206_RC_INIT2, 0x00 },
586 { M9206_RC_INIT1, 0xef },
587 { 0xff28, 0x00 },
588 { 0xff23, 0x00 },
589 { 0xff21, 0x30 },
590 { } /* terminating entry */
591};
592
593static struct m920x_inits pinnacle310e_init[] = {
594 /* without these the tuner don't work */
595 { 0xff20, 0x9b },
596 { 0xff22, 0x70 },
597
598 /* rc settings */
599 { 0xff50, 0x80 },
600 { M9206_RC_INIT1, 0x00 },
601 { M9206_RC_INIT2, 0xff },
602 { } /* terminating entry */
603};
604
605/* ir keymaps */
606static struct rc_map_table rc_map_megasky_table[] = {
607 { 0x0012, KEY_POWER },
608 { 0x001e, KEY_CYCLEWINDOWS }, /* min/max */
609 { 0x0002, KEY_CHANNELUP },
610 { 0x0005, KEY_CHANNELDOWN },
611 { 0x0003, KEY_VOLUMEUP },
612 { 0x0006, KEY_VOLUMEDOWN },
613 { 0x0004, KEY_MUTE },
614 { 0x0007, KEY_OK }, /* TS */
615 { 0x0008, KEY_STOP },
616 { 0x0009, KEY_MENU }, /* swap */
617 { 0x000a, KEY_REWIND },
618 { 0x001b, KEY_PAUSE },
619 { 0x001f, KEY_FASTFORWARD },
620 { 0x000c, KEY_RECORD },
621 { 0x000d, KEY_CAMERA }, /* screenshot */
622 { 0x000e, KEY_COFFEE }, /* "MTS" */
623};
624
625static struct rc_map_table rc_map_tvwalkertwin_table[] = {
626 { 0x0001, KEY_ZOOM }, /* Full Screen */
627 { 0x0002, KEY_CAMERA }, /* snapshot */
628 { 0x0003, KEY_MUTE },
629 { 0x0004, KEY_REWIND },
630 { 0x0005, KEY_PLAYPAUSE }, /* Play/Pause */
631 { 0x0006, KEY_FASTFORWARD },
632 { 0x0007, KEY_RECORD },
633 { 0x0008, KEY_STOP },
634 { 0x0009, KEY_TIME }, /* Timeshift */
635 { 0x000c, KEY_COFFEE }, /* Recall */
636 { 0x000e, KEY_CHANNELUP },
637 { 0x0012, KEY_POWER },
638 { 0x0015, KEY_MENU }, /* source */
639 { 0x0018, KEY_CYCLEWINDOWS }, /* TWIN PIP */
640 { 0x001a, KEY_CHANNELDOWN },
641 { 0x001b, KEY_VOLUMEDOWN },
642 { 0x001e, KEY_VOLUMEUP },
643};
644
645static struct rc_map_table rc_map_pinnacle310e_table[] = {
646 { 0x16, KEY_POWER },
647 { 0x17, KEY_FAVORITES },
648 { 0x0f, KEY_TEXT },
649 { 0x48, KEY_PROGRAM }, /* preview */
650 { 0x1c, KEY_EPG },
651 { 0x04, KEY_LIST }, /* record list */
652 { 0x03, KEY_1 },
653 { 0x01, KEY_2 },
654 { 0x06, KEY_3 },
655 { 0x09, KEY_4 },
656 { 0x1d, KEY_5 },
657 { 0x1f, KEY_6 },
658 { 0x0d, KEY_7 },
659 { 0x19, KEY_8 },
660 { 0x1b, KEY_9 },
661 { 0x15, KEY_0 },
662 { 0x0c, KEY_CANCEL },
663 { 0x4a, KEY_CLEAR },
664 { 0x13, KEY_BACK },
665 { 0x00, KEY_TAB },
666 { 0x4b, KEY_UP },
667 { 0x4e, KEY_LEFT },
668 { 0x52, KEY_RIGHT },
669 { 0x51, KEY_DOWN },
670 { 0x4f, KEY_ENTER }, /* could also be KEY_OK */
671 { 0x1e, KEY_VOLUMEUP },
672 { 0x0a, KEY_VOLUMEDOWN },
673 { 0x05, KEY_CHANNELUP },
674 { 0x02, KEY_CHANNELDOWN },
675 { 0x11, KEY_RECORD },
676 { 0x14, KEY_PLAY },
677 { 0x4c, KEY_PAUSE },
678 { 0x1a, KEY_STOP },
679 { 0x40, KEY_REWIND },
680 { 0x12, KEY_FASTFORWARD },
681 { 0x41, KEY_PREVIOUSSONG }, /* Replay */
682 { 0x42, KEY_NEXTSONG }, /* Skip */
683 { 0x54, KEY_CAMERA }, /* Capture */
684/* { 0x50, KEY_SAP }, */ /* Sap */
685 { 0x47, KEY_CYCLEWINDOWS }, /* Pip */
686 { 0x4d, KEY_SCREEN }, /* FullScreen */
687 { 0x08, KEY_SUBTITLE },
688 { 0x0e, KEY_MUTE },
689/* { 0x49, KEY_LR }, */ /* L/R */
690 { 0x07, KEY_SLEEP }, /* Hibernate */
691 { 0x08, KEY_VIDEO }, /* A/V */
692 { 0x0e, KEY_MENU }, /* Recall */
693 { 0x45, KEY_ZOOMIN },
694 { 0x46, KEY_ZOOMOUT },
695 { 0x18, KEY_RED }, /* Red */
696 { 0x53, KEY_GREEN }, /* Green */
697 { 0x5e, KEY_YELLOW }, /* Yellow */
698 { 0x5f, KEY_BLUE }, /* Blue */
699};
700
701/* DVB USB Driver stuff */
702static struct dvb_usb_device_properties megasky_properties;
703static struct dvb_usb_device_properties digivox_mini_ii_properties;
704static struct dvb_usb_device_properties tvwalkertwin_properties;
705static struct dvb_usb_device_properties dposh_properties;
706static struct dvb_usb_device_properties pinnacle_pctv310e_properties;
707
708static int m920x_probe(struct usb_interface *intf,
709 const struct usb_device_id *id)
710{
711 struct dvb_usb_device *d = NULL;
712 int ret;
713 struct m920x_inits *rc_init_seq = NULL;
714 int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber;
715
716 deb("Probing for m920x device at interface %d\n", bInterfaceNumber);
717
718 if (bInterfaceNumber == 0) {
719 /* Single-tuner device, or first interface on
720 * multi-tuner device
721 */
722
723 ret = dvb_usb_device_init(intf, &megasky_properties,
724 THIS_MODULE, &d, adapter_nr);
725 if (ret == 0) {
726 rc_init_seq = megasky_rc_init;
727 goto found;
728 }
729
730 ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties,
731 THIS_MODULE, &d, adapter_nr);
732 if (ret == 0) {
733 /* No remote control, so no rc_init_seq */
734 goto found;
735 }
736
737 /* This configures both tuners on the TV Walker Twin */
738 ret = dvb_usb_device_init(intf, &tvwalkertwin_properties,
739 THIS_MODULE, &d, adapter_nr);
740 if (ret == 0) {
741 rc_init_seq = tvwalkertwin_rc_init;
742 goto found;
743 }
744
745 ret = dvb_usb_device_init(intf, &dposh_properties,
746 THIS_MODULE, &d, adapter_nr);
747 if (ret == 0) {
748 /* Remote controller not supported yet. */
749 goto found;
750 }
751
752 ret = dvb_usb_device_init(intf, &pinnacle_pctv310e_properties,
753 THIS_MODULE, &d, adapter_nr);
754 if (ret == 0) {
755 rc_init_seq = pinnacle310e_init;
756 goto found;
757 }
758
759 return ret;
760 } else {
761 /* Another interface on a multi-tuner device */
762
763 /* The LifeView TV Walker Twin gets here, but struct
764 * tvwalkertwin_properties already configured both
765 * tuners, so there is nothing for us to do here
766 */
767 }
768
769 found:
770 if ((ret = m920x_init_ep(intf)) < 0)
771 return ret;
772
773 if (d && (ret = m920x_init(d, rc_init_seq)) != 0)
774 return ret;
775
776 return ret;
777}
778
779static struct usb_device_id m920x_table [] = {
780 { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) },
781 { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
782 USB_PID_MSI_DIGI_VOX_MINI_II) },
783 { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
784 USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD) },
785 { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
786 USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) },
787 { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) },
788 { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) },
789 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_PINNACLE_PCTV310E) },
790 { } /* Terminating entry */
791};
792MODULE_DEVICE_TABLE (usb, m920x_table);
793
794static struct dvb_usb_device_properties megasky_properties = {
795 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
796
797 .usb_ctrl = DEVICE_SPECIFIC,
798 .firmware = "dvb-usb-megasky-02.fw",
799 .download_firmware = m920x_firmware_download,
800
801 .rc.legacy = {
802 .rc_interval = 100,
803 .rc_map_table = rc_map_megasky_table,
804 .rc_map_size = ARRAY_SIZE(rc_map_megasky_table),
805 .rc_query = m920x_rc_query,
806 },
807
808 .size_of_priv = sizeof(struct m920x_state),
809
810 .identify_state = m920x_identify_state,
811 .num_adapters = 1,
812 .adapter = {{
813 .num_frontends = 1,
814 .fe = {{
815
816 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
817 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
818
819 .pid_filter_count = 8,
820 .pid_filter = m920x_pid_filter,
821 .pid_filter_ctrl = m920x_pid_filter_ctrl,
822
823 .frontend_attach = m920x_mt352_frontend_attach,
824 .tuner_attach = m920x_qt1010_tuner_attach,
825
826 .stream = {
827 .type = USB_BULK,
828 .count = 8,
829 .endpoint = 0x81,
830 .u = {
831 .bulk = {
832 .buffersize = 512,
833 }
834 }
835 },
836 }},
837 }},
838 .i2c_algo = &m920x_i2c_algo,
839
840 .num_device_descs = 1,
841 .devices = {
842 { "MSI Mega Sky 580 DVB-T USB2.0",
843 { &m920x_table[0], NULL },
844 { NULL },
845 }
846 }
847};
848
849static struct dvb_usb_device_properties digivox_mini_ii_properties = {
850 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
851
852 .usb_ctrl = DEVICE_SPECIFIC,
853 .firmware = "dvb-usb-digivox-02.fw",
854 .download_firmware = m920x_firmware_download,
855
856 .size_of_priv = sizeof(struct m920x_state),
857
858 .identify_state = m920x_identify_state,
859 .num_adapters = 1,
860 .adapter = {{
861 .num_frontends = 1,
862 .fe = {{
863
864 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
865 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
866
867 .pid_filter_count = 8,
868 .pid_filter = m920x_pid_filter,
869 .pid_filter_ctrl = m920x_pid_filter_ctrl,
870
871 .frontend_attach = m920x_tda10046_08_frontend_attach,
872 .tuner_attach = m920x_tda8275_60_tuner_attach,
873
874 .stream = {
875 .type = USB_BULK,
876 .count = 8,
877 .endpoint = 0x81,
878 .u = {
879 .bulk = {
880 .buffersize = 0x4000,
881 }
882 }
883 },
884 }},
885 }},
886 .i2c_algo = &m920x_i2c_algo,
887
888 .num_device_descs = 1,
889 .devices = {
890 { "MSI DIGI VOX mini II DVB-T USB2.0",
891 { &m920x_table[1], NULL },
892 { NULL },
893 },
894 }
895};
896
897/* LifeView TV Walker Twin support by Nick Andrew <nick@nick-andrew.net>
898 *
899 * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A
900 * TDA10046 #0 is located at i2c address 0x08
901 * TDA10046 #1 is located at i2c address 0x0b
902 * TDA8275A #0 is located at i2c address 0x60
903 * TDA8275A #1 is located at i2c address 0x61
904 */
905static struct dvb_usb_device_properties tvwalkertwin_properties = {
906 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
907
908 .usb_ctrl = DEVICE_SPECIFIC,
909 .firmware = "dvb-usb-tvwalkert.fw",
910 .download_firmware = m920x_firmware_download,
911
912 .rc.legacy = {
913 .rc_interval = 100,
914 .rc_map_table = rc_map_tvwalkertwin_table,
915 .rc_map_size = ARRAY_SIZE(rc_map_tvwalkertwin_table),
916 .rc_query = m920x_rc_query,
917 },
918
919 .size_of_priv = sizeof(struct m920x_state),
920
921 .identify_state = m920x_identify_state,
922 .num_adapters = 2,
923 .adapter = {{
924 .num_frontends = 1,
925 .fe = {{
926
927 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
928 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
929
930 .pid_filter_count = 8,
931 .pid_filter = m920x_pid_filter,
932 .pid_filter_ctrl = m920x_pid_filter_ctrl,
933
934 .frontend_attach = m920x_tda10046_08_frontend_attach,
935 .tuner_attach = m920x_tda8275_60_tuner_attach,
936
937 .stream = {
938 .type = USB_BULK,
939 .count = 8,
940 .endpoint = 0x81,
941 .u = {
942 .bulk = {
943 .buffersize = 512,
944 }
945 }
946 }},
947 }},{
948 .num_frontends = 1,
949 .fe = {{
950
951 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
952 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
953
954 .pid_filter_count = 8,
955 .pid_filter = m920x_pid_filter,
956 .pid_filter_ctrl = m920x_pid_filter_ctrl,
957
958 .frontend_attach = m920x_tda10046_0b_frontend_attach,
959 .tuner_attach = m920x_tda8275_61_tuner_attach,
960
961 .stream = {
962 .type = USB_BULK,
963 .count = 8,
964 .endpoint = 0x82,
965 .u = {
966 .bulk = {
967 .buffersize = 512,
968 }
969 }
970 }},
971 },
972 }},
973 .i2c_algo = &m920x_i2c_algo,
974
975 .num_device_descs = 1,
976 .devices = {
977 { .name = "LifeView TV Walker Twin DVB-T USB2.0",
978 .cold_ids = { &m920x_table[2], NULL },
979 .warm_ids = { &m920x_table[3], NULL },
980 },
981 }
982};
983
984static struct dvb_usb_device_properties dposh_properties = {
985 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
986
987 .usb_ctrl = DEVICE_SPECIFIC,
988 .firmware = "dvb-usb-dposh-01.fw",
989 .download_firmware = m920x_firmware_download,
990
991 .size_of_priv = sizeof(struct m920x_state),
992
993 .identify_state = m920x_identify_state,
994 .num_adapters = 1,
995 .adapter = {{
996 .num_frontends = 1,
997 .fe = {{
998 /* Hardware pid filters don't work with this device/firmware */
999
1000 .frontend_attach = m920x_mt352_frontend_attach,
1001 .tuner_attach = m920x_qt1010_tuner_attach,
1002
1003 .stream = {
1004 .type = USB_BULK,
1005 .count = 8,
1006 .endpoint = 0x81,
1007 .u = {
1008 .bulk = {
1009 .buffersize = 512,
1010 }
1011 }
1012 },
1013 }},
1014 }},
1015 .i2c_algo = &m920x_i2c_algo,
1016
1017 .num_device_descs = 1,
1018 .devices = {
1019 { .name = "Dposh DVB-T USB2.0",
1020 .cold_ids = { &m920x_table[4], NULL },
1021 .warm_ids = { &m920x_table[5], NULL },
1022 },
1023 }
1024};
1025
1026static struct dvb_usb_device_properties pinnacle_pctv310e_properties = {
1027 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1028
1029 .usb_ctrl = DEVICE_SPECIFIC,
1030 .download_firmware = NULL,
1031
1032 .rc.legacy = {
1033 .rc_interval = 100,
1034 .rc_map_table = rc_map_pinnacle310e_table,
1035 .rc_map_size = ARRAY_SIZE(rc_map_pinnacle310e_table),
1036 .rc_query = m920x_rc_query,
1037 },
1038
1039 .size_of_priv = sizeof(struct m920x_state),
1040
1041 .identify_state = m920x_identify_state,
1042 .num_adapters = 1,
1043 .adapter = {{
1044 .num_frontends = 1,
1045 .fe = {{
1046
1047 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1048 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1049
1050 .pid_filter_count = 8,
1051 .pid_filter = m920x_pid_filter,
1052 .pid_filter_ctrl = m920x_pid_filter_ctrl,
1053
1054 .frontend_attach = m920x_mt352_frontend_attach,
1055 .tuner_attach = m920x_fmd1216me_tuner_attach,
1056
1057 .stream = {
1058 .type = USB_ISOC,
1059 .count = 5,
1060 .endpoint = 0x84,
1061 .u = {
1062 .isoc = {
1063 .framesperurb = 128,
1064 .framesize = 564,
1065 .interval = 1,
1066 }
1067 }
1068 },
1069 }},
1070 } },
1071 .i2c_algo = &m920x_i2c_algo,
1072
1073 .num_device_descs = 1,
1074 .devices = {
1075 { "Pinnacle PCTV 310e",
1076 { &m920x_table[6], NULL },
1077 { NULL },
1078 }
1079 }
1080};
1081
1082static struct usb_driver m920x_driver = {
1083 .name = "dvb_usb_m920x",
1084 .probe = m920x_probe,
1085 .disconnect = dvb_usb_device_exit,
1086 .id_table = m920x_table,
1087};
1088
1089module_usb_driver(m920x_driver);
1090
1091MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
1092MODULE_DESCRIPTION("DVB Driver for ULI M920x");
1093MODULE_VERSION("0.1");
1094MODULE_LICENSE("GPL");
1095
1096/*
1097 * Local variables:
1098 * c-basic-offset: 8
1099 */
diff --git a/drivers/media/usb/dvb-usb/m920x.h b/drivers/media/usb/dvb-usb/m920x.h
new file mode 100644
index 000000000000..3c061518ffc1
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/nova-t-usb2.c b/drivers/media/usb/dvb-usb/nova-t-usb2.c
new file mode 100644
index 000000000000..6c55384e2fca
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/nova-t-usb2.c
@@ -0,0 +1,233 @@
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 .num_frontends = 1,
170 .fe = {{
171 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
172 .pid_filter_count = 32,
173
174 .streaming_ctrl = dibusb2_0_streaming_ctrl,
175 .pid_filter = dibusb_pid_filter,
176 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
177 .frontend_attach = dibusb_dib3000mc_frontend_attach,
178 .tuner_attach = dibusb_dib3000mc_tuner_attach,
179
180 /* parameter for the MPEG2-data transfer */
181 .stream = {
182 .type = USB_BULK,
183 .count = 7,
184 .endpoint = 0x06,
185 .u = {
186 .bulk = {
187 .buffersize = 4096,
188 }
189 }
190 },
191 }},
192 .size_of_priv = sizeof(struct dibusb_state),
193 }
194 },
195 .size_of_priv = sizeof(struct dibusb_device_state),
196
197 .power_ctrl = dibusb2_0_power_ctrl,
198 .read_mac_address = nova_t_read_mac_address,
199
200 .rc.legacy = {
201 .rc_interval = 100,
202 .rc_map_table = rc_map_haupp_table,
203 .rc_map_size = ARRAY_SIZE(rc_map_haupp_table),
204 .rc_query = nova_t_rc_query,
205 },
206
207 .i2c_algo = &dibusb_i2c_algo,
208
209 .generic_bulk_ctrl_endpoint = 0x01,
210
211 .num_device_descs = 1,
212 .devices = {
213 { "Hauppauge WinTV-NOVA-T usb2",
214 { &nova_t_table[0], NULL },
215 { &nova_t_table[1], NULL },
216 },
217 { NULL },
218 }
219};
220
221static struct usb_driver nova_t_driver = {
222 .name = "dvb_usb_nova_t_usb2",
223 .probe = nova_t_probe,
224 .disconnect = dvb_usb_device_exit,
225 .id_table = nova_t_table,
226};
227
228module_usb_driver(nova_t_driver);
229
230MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
231MODULE_DESCRIPTION("Hauppauge WinTV-NOVA-T usb2");
232MODULE_VERSION("1.0");
233MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/opera1.c b/drivers/media/usb/dvb-usb/opera1.c
new file mode 100644
index 000000000000..c8a95042dfbc
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/opera1.c
@@ -0,0 +1,583 @@
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 d->fe_adap[0].fe = dvb_attach(stv0299_attach, &opera1_stv0299_config,
267 &d->dev->i2c_adap);
268 if ((d->fe_adap[0].fe) != NULL) {
269 d->fe_adap[0].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_adap[0].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 .num_frontends = 1,
520 .fe = {{
521 .frontend_attach = opera1_frontend_attach,
522 .streaming_ctrl = opera1_streaming_ctrl,
523 .tuner_attach = opera1_tuner_attach,
524 .caps =
525 DVB_USB_ADAP_HAS_PID_FILTER |
526 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
527 .pid_filter = opera1_pid_filter,
528 .pid_filter_ctrl = opera1_pid_filter_control,
529 .pid_filter_count = 252,
530 .stream = {
531 .type = USB_BULK,
532 .count = 10,
533 .endpoint = 0x82,
534 .u = {
535 .bulk = {
536 .buffersize = 4096,
537 }
538 }
539 },
540 }},
541 }
542 },
543 .num_device_descs = 1,
544 .devices = {
545 {"Opera1 DVB-S USB2.0",
546 {&opera1_table[0], NULL},
547 {&opera1_table[1], NULL},
548 },
549 }
550};
551
552static int opera1_probe(struct usb_interface *intf,
553 const struct usb_device_id *id)
554{
555 struct usb_device *udev = interface_to_usbdev(intf);
556
557 if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM &&
558 udev->descriptor.idVendor == USB_VID_OPERA1 &&
559 opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga-01.fw") != 0
560 ) {
561 return -EINVAL;
562 }
563
564 if (0 != dvb_usb_device_init(intf, &opera1_properties,
565 THIS_MODULE, NULL, adapter_nr))
566 return -EINVAL;
567 return 0;
568}
569
570static struct usb_driver opera1_driver = {
571 .name = "opera1",
572 .probe = opera1_probe,
573 .disconnect = dvb_usb_device_exit,
574 .id_table = opera1_table,
575};
576
577module_usb_driver(opera1_driver);
578
579MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org");
580MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de");
581MODULE_DESCRIPTION("Driver for Opera1 DVB-S device");
582MODULE_VERSION("0.1");
583MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
new file mode 100644
index 000000000000..02e878577c3d
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/pctv452e.c
@@ -0,0 +1,1063 @@
1/*
2 * PCTV 452e DVB driver
3 *
4 * Copyright (c) 2006-2008 Dominik Kuhlen <dkuhlen@gmx.net>
5 *
6 * TT connect S2-3650-CI Common Interface support, MAC readout
7 * Copyright (C) 2008 Michael H. Schimek <mschimek@gmx.at>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 */
14
15/* dvb usb framework */
16#define DVB_USB_LOG_PREFIX "pctv452e"
17#include "dvb-usb.h"
18
19/* Demodulator */
20#include "stb0899_drv.h"
21#include "stb0899_reg.h"
22#include "stb0899_cfg.h"
23/* Tuner */
24#include "stb6100.h"
25#include "stb6100_cfg.h"
26/* FE Power */
27#include "lnbp22.h"
28
29#include "dvb_ca_en50221.h"
30#include "ttpci-eeprom.h"
31
32static int debug;
33module_param(debug, int, 0644);
34MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
35
36DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
37
38#define ISOC_INTERFACE_ALTERNATIVE 3
39
40#define SYNC_BYTE_OUT 0xaa
41#define SYNC_BYTE_IN 0x55
42
43/* guessed: (copied from ttusb-budget) */
44#define PCTV_CMD_RESET 0x15
45/* command to poll IR receiver */
46#define PCTV_CMD_IR 0x1b
47/* command to send I2C */
48#define PCTV_CMD_I2C 0x31
49
50#define I2C_ADDR_STB0899 (0xd0 >> 1)
51#define I2C_ADDR_STB6100 (0xc0 >> 1)
52#define I2C_ADDR_LNBP22 (0x10 >> 1)
53#define I2C_ADDR_24C16 (0xa0 >> 1)
54#define I2C_ADDR_24C64 (0xa2 >> 1)
55
56
57/* pctv452e sends us this amount of data for each issued usb-command */
58#define PCTV_ANSWER_LEN 64
59/* Wait up to 1000ms for device */
60#define PCTV_TIMEOUT 1000
61
62
63#define PCTV_LED_GPIO STB0899_GPIO01
64#define PCTV_LED_GREEN 0x82
65#define PCTV_LED_ORANGE 0x02
66
67#define ci_dbg(format, arg...) \
68do { \
69 if (0) \
70 printk(KERN_DEBUG DVB_USB_LOG_PREFIX \
71 ": " format "\n" , ## arg); \
72} while (0)
73
74enum {
75 TT3650_CMD_CI_TEST = 0x40,
76 TT3650_CMD_CI_RD_CTRL,
77 TT3650_CMD_CI_WR_CTRL,
78 TT3650_CMD_CI_RD_ATTR,
79 TT3650_CMD_CI_WR_ATTR,
80 TT3650_CMD_CI_RESET,
81 TT3650_CMD_CI_SET_VIDEO_PORT
82};
83
84
85static struct stb0899_postproc pctv45e_postproc[] = {
86 { PCTV_LED_GPIO, STB0899_GPIOPULLUP },
87 { 0, 0 }
88};
89
90/*
91 * stores all private variables for communication with the PCTV452e DVB-S2
92 */
93struct pctv452e_state {
94 struct dvb_ca_en50221 ca;
95 struct mutex ca_mutex;
96
97 u8 c; /* transaction counter, wraps around... */
98 u8 initialized; /* set to 1 if 0x15 has been sent */
99 u16 last_rc_key;
100};
101
102static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data,
103 unsigned int write_len, unsigned int read_len)
104{
105 struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
106 u8 buf[64];
107 u8 id;
108 unsigned int rlen;
109 int ret;
110
111 BUG_ON(NULL == data && 0 != (write_len | read_len));
112 BUG_ON(write_len > 64 - 4);
113 BUG_ON(read_len > 64 - 4);
114
115 id = state->c++;
116
117 buf[0] = SYNC_BYTE_OUT;
118 buf[1] = id;
119 buf[2] = cmd;
120 buf[3] = write_len;
121
122 memcpy(buf + 4, data, write_len);
123
124 rlen = (read_len > 0) ? 64 : 0;
125 ret = dvb_usb_generic_rw(d, buf, 4 + write_len,
126 buf, rlen, /* delay_ms */ 0);
127 if (0 != ret)
128 goto failed;
129
130 ret = -EIO;
131 if (SYNC_BYTE_IN != buf[0] || id != buf[1])
132 goto failed;
133
134 memcpy(data, buf + 4, read_len);
135
136 return 0;
137
138failed:
139 err("CI error %d; %02X %02X %02X -> %*ph.",
140 ret, SYNC_BYTE_OUT, id, cmd, 3, buf);
141
142 return ret;
143}
144
145static int tt3650_ci_msg_locked(struct dvb_ca_en50221 *ca,
146 u8 cmd, u8 *data, unsigned int write_len,
147 unsigned int read_len)
148{
149 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
150 struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
151 int ret;
152
153 mutex_lock(&state->ca_mutex);
154 ret = tt3650_ci_msg(d, cmd, data, write_len, read_len);
155 mutex_unlock(&state->ca_mutex);
156
157 return ret;
158}
159
160static int tt3650_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
161 int slot, int address)
162{
163 u8 buf[3];
164 int ret;
165
166 if (0 != slot)
167 return -EINVAL;
168
169 buf[0] = (address >> 8) & 0x0F;
170 buf[1] = address;
171
172 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_ATTR, buf, 2, 3);
173
174 ci_dbg("%s %04x -> %d 0x%02x",
175 __func__, address, ret, buf[2]);
176
177 if (ret < 0)
178 return ret;
179
180 return buf[2];
181}
182
183static int tt3650_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
184 int slot, int address, u8 value)
185{
186 u8 buf[3];
187
188 ci_dbg("%s %d 0x%04x 0x%02x",
189 __func__, slot, address, value);
190
191 if (0 != slot)
192 return -EINVAL;
193
194 buf[0] = (address >> 8) & 0x0F;
195 buf[1] = address;
196 buf[2] = value;
197
198 return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_ATTR, buf, 3, 3);
199}
200
201static int tt3650_ci_read_cam_control(struct dvb_ca_en50221 *ca,
202 int slot,
203 u8 address)
204{
205 u8 buf[2];
206 int ret;
207
208 if (0 != slot)
209 return -EINVAL;
210
211 buf[0] = address & 3;
212
213 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_CTRL, buf, 1, 2);
214
215 ci_dbg("%s 0x%02x -> %d 0x%02x",
216 __func__, address, ret, buf[1]);
217
218 if (ret < 0)
219 return ret;
220
221 return buf[1];
222}
223
224static int tt3650_ci_write_cam_control(struct dvb_ca_en50221 *ca,
225 int slot,
226 u8 address,
227 u8 value)
228{
229 u8 buf[2];
230
231 ci_dbg("%s %d 0x%02x 0x%02x",
232 __func__, slot, address, value);
233
234 if (0 != slot)
235 return -EINVAL;
236
237 buf[0] = address;
238 buf[1] = value;
239
240 return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_CTRL, buf, 2, 2);
241}
242
243static int tt3650_ci_set_video_port(struct dvb_ca_en50221 *ca,
244 int slot,
245 int enable)
246{
247 u8 buf[1];
248 int ret;
249
250 ci_dbg("%s %d %d", __func__, slot, enable);
251
252 if (0 != slot)
253 return -EINVAL;
254
255 enable = !!enable;
256 buf[0] = enable;
257
258 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
259 if (ret < 0)
260 return ret;
261
262 if (enable != buf[0]) {
263 err("CI not %sabled.", enable ? "en" : "dis");
264 return -EIO;
265 }
266
267 return 0;
268}
269
270static int tt3650_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
271{
272 return tt3650_ci_set_video_port(ca, slot, /* enable */ 0);
273}
274
275static int tt3650_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
276{
277 return tt3650_ci_set_video_port(ca, slot, /* enable */ 1);
278}
279
280static int tt3650_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
281{
282 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
283 struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
284 u8 buf[1];
285 int ret;
286
287 ci_dbg("%s %d", __func__, slot);
288
289 if (0 != slot)
290 return -EINVAL;
291
292 buf[0] = 0;
293
294 mutex_lock(&state->ca_mutex);
295
296 ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
297 if (0 != ret)
298 goto failed;
299
300 msleep(500);
301
302 buf[0] = 1;
303
304 ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
305 if (0 != ret)
306 goto failed;
307
308 msleep(500);
309
310 buf[0] = 0; /* FTA */
311
312 ret = tt3650_ci_msg(d, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
313
314 failed:
315 mutex_unlock(&state->ca_mutex);
316
317 return ret;
318}
319
320static int tt3650_ci_poll_slot_status(struct dvb_ca_en50221 *ca,
321 int slot,
322 int open)
323{
324 u8 buf[1];
325 int ret;
326
327 if (0 != slot)
328 return -EINVAL;
329
330 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_TEST, buf, 0, 1);
331 if (0 != ret)
332 return ret;
333
334 if (1 == buf[0])
335 return DVB_CA_EN50221_POLL_CAM_PRESENT |
336 DVB_CA_EN50221_POLL_CAM_READY;
337
338 return 0;
339
340}
341
342static void tt3650_ci_uninit(struct dvb_usb_device *d)
343{
344 struct pctv452e_state *state;
345
346 ci_dbg("%s", __func__);
347
348 if (NULL == d)
349 return;
350
351 state = (struct pctv452e_state *)d->priv;
352 if (NULL == state)
353 return;
354
355 if (NULL == state->ca.data)
356 return;
357
358 /* Error ignored. */
359 tt3650_ci_set_video_port(&state->ca, /* slot */ 0, /* enable */ 0);
360
361 dvb_ca_en50221_release(&state->ca);
362
363 memset(&state->ca, 0, sizeof(state->ca));
364}
365
366static int tt3650_ci_init(struct dvb_usb_adapter *a)
367{
368 struct dvb_usb_device *d = a->dev;
369 struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
370 int ret;
371
372 ci_dbg("%s", __func__);
373
374 mutex_init(&state->ca_mutex);
375
376 state->ca.owner = THIS_MODULE;
377 state->ca.read_attribute_mem = tt3650_ci_read_attribute_mem;
378 state->ca.write_attribute_mem = tt3650_ci_write_attribute_mem;
379 state->ca.read_cam_control = tt3650_ci_read_cam_control;
380 state->ca.write_cam_control = tt3650_ci_write_cam_control;
381 state->ca.slot_reset = tt3650_ci_slot_reset;
382 state->ca.slot_shutdown = tt3650_ci_slot_shutdown;
383 state->ca.slot_ts_enable = tt3650_ci_slot_ts_enable;
384 state->ca.poll_slot_status = tt3650_ci_poll_slot_status;
385 state->ca.data = d;
386
387 ret = dvb_ca_en50221_init(&a->dvb_adap,
388 &state->ca,
389 /* flags */ 0,
390 /* n_slots */ 1);
391 if (0 != ret) {
392 err("Cannot initialize CI: Error %d.", ret);
393 memset(&state->ca, 0, sizeof(state->ca));
394 return ret;
395 }
396
397 info("CI initialized.");
398
399 return 0;
400}
401
402#define CMD_BUFFER_SIZE 0x28
403static int pctv452e_i2c_msg(struct dvb_usb_device *d, u8 addr,
404 const u8 *snd_buf, u8 snd_len,
405 u8 *rcv_buf, u8 rcv_len)
406{
407 struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
408 u8 buf[64];
409 u8 id;
410 int ret;
411
412 id = state->c++;
413
414 ret = -EINVAL;
415 if (snd_len > 64 - 7 || rcv_len > 64 - 7)
416 goto failed;
417
418 buf[0] = SYNC_BYTE_OUT;
419 buf[1] = id;
420 buf[2] = PCTV_CMD_I2C;
421 buf[3] = snd_len + 3;
422 buf[4] = addr << 1;
423 buf[5] = snd_len;
424 buf[6] = rcv_len;
425
426 memcpy(buf + 7, snd_buf, snd_len);
427
428 ret = dvb_usb_generic_rw(d, buf, 7 + snd_len,
429 buf, /* rcv_len */ 64,
430 /* delay_ms */ 0);
431 if (ret < 0)
432 goto failed;
433
434 /* TT USB protocol error. */
435 ret = -EIO;
436 if (SYNC_BYTE_IN != buf[0] || id != buf[1])
437 goto failed;
438
439 /* I2C device didn't respond as expected. */
440 ret = -EREMOTEIO;
441 if (buf[5] < snd_len || buf[6] < rcv_len)
442 goto failed;
443
444 memcpy(rcv_buf, buf + 7, rcv_len);
445
446 return rcv_len;
447
448failed:
449 err("I2C error %d; %02X %02X %02X %02X %02X -> "
450 "%02X %02X %02X %02X %02X.",
451 ret, SYNC_BYTE_OUT, id, addr << 1, snd_len, rcv_len,
452 buf[0], buf[1], buf[4], buf[5], buf[6]);
453
454 return ret;
455}
456
457static int pctv452e_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msg,
458 int num)
459{
460 struct dvb_usb_device *d = i2c_get_adapdata(adapter);
461 int i;
462
463 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
464 return -EAGAIN;
465
466 for (i = 0; i < num; i++) {
467 u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
468 int ret;
469
470 if (msg[i].flags & I2C_M_RD) {
471 addr = msg[i].addr;
472 snd_buf = NULL;
473 snd_len = 0;
474 rcv_buf = msg[i].buf;
475 rcv_len = msg[i].len;
476 } else {
477 addr = msg[i].addr;
478 snd_buf = msg[i].buf;
479 snd_len = msg[i].len;
480 rcv_buf = NULL;
481 rcv_len = 0;
482 }
483
484 ret = pctv452e_i2c_msg(d, addr, snd_buf, snd_len, rcv_buf,
485 rcv_len);
486 if (ret < rcv_len)
487 break;
488 }
489
490 mutex_unlock(&d->i2c_mutex);
491 return i;
492}
493
494static u32 pctv452e_i2c_func(struct i2c_adapter *adapter)
495{
496 return I2C_FUNC_I2C;
497}
498
499static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i)
500{
501 struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
502 u8 b0[] = { 0xaa, 0, PCTV_CMD_RESET, 1, 0 };
503 u8 rx[PCTV_ANSWER_LEN];
504 int ret;
505
506 info("%s: %d\n", __func__, i);
507
508 if (!i)
509 return 0;
510
511 if (state->initialized)
512 return 0;
513
514 /* hmm where shoud this should go? */
515 ret = usb_set_interface(d->udev, 0, ISOC_INTERFACE_ALTERNATIVE);
516 if (ret != 0)
517 info("%s: Warning set interface returned: %d\n",
518 __func__, ret);
519
520 /* this is a one-time initialization, dont know where to put */
521 b0[1] = state->c++;
522 /* reset board */
523 ret = dvb_usb_generic_rw(d, b0, sizeof(b0), rx, PCTV_ANSWER_LEN, 0);
524 if (ret)
525 return ret;
526
527 b0[1] = state->c++;
528 b0[4] = 1;
529 /* reset board (again?) */
530 ret = dvb_usb_generic_rw(d, b0, sizeof(b0), rx, PCTV_ANSWER_LEN, 0);
531 if (ret)
532 return ret;
533
534 state->initialized = 1;
535
536 return 0;
537}
538
539static int pctv452e_rc_query(struct dvb_usb_device *d)
540{
541 struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
542 u8 b[CMD_BUFFER_SIZE];
543 u8 rx[PCTV_ANSWER_LEN];
544 int ret, i;
545 u8 id = state->c++;
546
547 /* prepare command header */
548 b[0] = SYNC_BYTE_OUT;
549 b[1] = id;
550 b[2] = PCTV_CMD_IR;
551 b[3] = 0;
552
553 /* send ir request */
554 ret = dvb_usb_generic_rw(d, b, 4, rx, PCTV_ANSWER_LEN, 0);
555 if (ret != 0)
556 return ret;
557
558 if (debug > 3) {
559 info("%s: read: %2d: %*ph: ", __func__, ret, 3, rx);
560 for (i = 0; (i < rx[3]) && ((i+3) < PCTV_ANSWER_LEN); i++)
561 info(" %02x", rx[i+3]);
562
563 info("\n");
564 }
565
566 if ((rx[3] == 9) && (rx[12] & 0x01)) {
567 /* got a "press" event */
568 state->last_rc_key = (rx[7] << 8) | rx[6];
569 if (debug > 2)
570 info("%s: cmd=0x%02x sys=0x%02x\n",
571 __func__, rx[6], rx[7]);
572
573 rc_keydown(d->rc_dev, state->last_rc_key, 0);
574 } else if (state->last_rc_key) {
575 rc_keyup(d->rc_dev);
576 state->last_rc_key = 0;
577 }
578
579 return 0;
580}
581
582static int pctv452e_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
583{
584 const u8 mem_addr[] = { 0x1f, 0xcc };
585 u8 encoded_mac[20];
586 int ret;
587
588 ret = -EAGAIN;
589 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
590 goto failed;
591
592 ret = pctv452e_i2c_msg(d, I2C_ADDR_24C16,
593 mem_addr + 1, /* snd_len */ 1,
594 encoded_mac, /* rcv_len */ 20);
595 if (-EREMOTEIO == ret)
596 /* Caution! A 24C16 interprets 0xA2 0x1F 0xCC as a
597 byte write if /WC is low. */
598 ret = pctv452e_i2c_msg(d, I2C_ADDR_24C64,
599 mem_addr, 2,
600 encoded_mac, 20);
601
602 mutex_unlock(&d->i2c_mutex);
603
604 if (20 != ret)
605 goto failed;
606
607 ret = ttpci_eeprom_decode_mac(mac, encoded_mac);
608 if (0 != ret)
609 goto failed;
610
611 return 0;
612
613failed:
614 memset(mac, 0, 6);
615
616 return ret;
617}
618
619static const struct stb0899_s1_reg pctv452e_init_dev[] = {
620 { STB0899_DISCNTRL1, 0x26 },
621 { STB0899_DISCNTRL2, 0x80 },
622 { STB0899_DISRX_ST0, 0x04 },
623 { STB0899_DISRX_ST1, 0x20 },
624 { STB0899_DISPARITY, 0x00 },
625 { STB0899_DISFIFO, 0x00 },
626 { STB0899_DISF22, 0x99 },
627 { STB0899_DISF22RX, 0x85 }, /* 0xa8 */
628 { STB0899_ACRPRESC, 0x11 },
629 { STB0899_ACRDIV1, 0x0a },
630 { STB0899_ACRDIV2, 0x05 },
631 { STB0899_DACR1 , 0x00 },
632 { STB0899_DACR2 , 0x00 },
633 { STB0899_OUTCFG, 0x00 },
634 { STB0899_MODECFG, 0x00 }, /* Inversion */
635 { STB0899_IRQMSK_3, 0xf3 },
636 { STB0899_IRQMSK_2, 0xfc },
637 { STB0899_IRQMSK_1, 0xff },
638 { STB0899_IRQMSK_0, 0xff },
639 { STB0899_I2CCFG, 0x88 },
640 { STB0899_I2CRPT, 0x58 },
641 { STB0899_GPIO00CFG, 0x82 },
642 { STB0899_GPIO01CFG, 0x82 }, /* LED: 0x02 green, 0x82 orange */
643 { STB0899_GPIO02CFG, 0x82 },
644 { STB0899_GPIO03CFG, 0x82 },
645 { STB0899_GPIO04CFG, 0x82 },
646 { STB0899_GPIO05CFG, 0x82 },
647 { STB0899_GPIO06CFG, 0x82 },
648 { STB0899_GPIO07CFG, 0x82 },
649 { STB0899_GPIO08CFG, 0x82 },
650 { STB0899_GPIO09CFG, 0x82 },
651 { STB0899_GPIO10CFG, 0x82 },
652 { STB0899_GPIO11CFG, 0x82 },
653 { STB0899_GPIO12CFG, 0x82 },
654 { STB0899_GPIO13CFG, 0x82 },
655 { STB0899_GPIO14CFG, 0x82 },
656 { STB0899_GPIO15CFG, 0x82 },
657 { STB0899_GPIO16CFG, 0x82 },
658 { STB0899_GPIO17CFG, 0x82 },
659 { STB0899_GPIO18CFG, 0x82 },
660 { STB0899_GPIO19CFG, 0x82 },
661 { STB0899_GPIO20CFG, 0x82 },
662 { STB0899_SDATCFG, 0xb8 },
663 { STB0899_SCLTCFG, 0xba },
664 { STB0899_AGCRFCFG, 0x1c }, /* 0x11 DVB-S; 0x1c DVB-S2 (1c, rjkm) */
665 { STB0899_GPIO22, 0x82 },
666 { STB0899_GPIO21, 0x91 },
667 { STB0899_DIRCLKCFG, 0x82 },
668 { STB0899_CLKOUT27CFG, 0x7e },
669 { STB0899_STDBYCFG, 0x82 },
670 { STB0899_CS0CFG, 0x82 },
671 { STB0899_CS1CFG, 0x82 },
672 { STB0899_DISEQCOCFG, 0x20 },
673 { STB0899_NCOARSE, 0x15 }, /* 0x15 27Mhz, F/3 198MHz, F/6 108MHz */
674 { STB0899_SYNTCTRL, 0x00 }, /* 0x00 CLKI, 0x02 XTALI */
675 { STB0899_FILTCTRL, 0x00 },
676 { STB0899_SYSCTRL, 0x00 },
677 { STB0899_STOPCLK1, 0x20 }, /* orig: 0x00 budget-ci: 0x20 */
678 { STB0899_STOPCLK2, 0x00 },
679 { STB0899_INTBUFCTRL, 0x0a },
680 { STB0899_AGC2I1, 0x00 },
681 { STB0899_AGC2I2, 0x00 },
682 { STB0899_AGCIQIN, 0x00 },
683 { STB0899_TSTRES, 0x40 }, /* rjkm */
684 { 0xffff, 0xff },
685};
686
687static const struct stb0899_s1_reg pctv452e_init_s1_demod[] = {
688 { STB0899_DEMOD, 0x00 },
689 { STB0899_RCOMPC, 0xc9 },
690 { STB0899_AGC1CN, 0x01 },
691 { STB0899_AGC1REF, 0x10 },
692 { STB0899_RTC, 0x23 },
693 { STB0899_TMGCFG, 0x4e },
694 { STB0899_AGC2REF, 0x34 },
695 { STB0899_TLSR, 0x84 },
696 { STB0899_CFD, 0xf7 },
697 { STB0899_ACLC, 0x87 },
698 { STB0899_BCLC, 0x94 },
699 { STB0899_EQON, 0x41 },
700 { STB0899_LDT, 0xf1 },
701 { STB0899_LDT2, 0xe3 },
702 { STB0899_EQUALREF, 0xb4 },
703 { STB0899_TMGRAMP, 0x10 },
704 { STB0899_TMGTHD, 0x30 },
705 { STB0899_IDCCOMP, 0xfd },
706 { STB0899_QDCCOMP, 0xff },
707 { STB0899_POWERI, 0x0c },
708 { STB0899_POWERQ, 0x0f },
709 { STB0899_RCOMP, 0x6c },
710 { STB0899_AGCIQIN, 0x80 },
711 { STB0899_AGC2I1, 0x06 },
712 { STB0899_AGC2I2, 0x00 },
713 { STB0899_TLIR, 0x30 },
714 { STB0899_RTF, 0x7f },
715 { STB0899_DSTATUS, 0x00 },
716 { STB0899_LDI, 0xbc },
717 { STB0899_CFRM, 0xea },
718 { STB0899_CFRL, 0x31 },
719 { STB0899_NIRM, 0x2b },
720 { STB0899_NIRL, 0x80 },
721 { STB0899_ISYMB, 0x1d },
722 { STB0899_QSYMB, 0xa6 },
723 { STB0899_SFRH, 0x2f },
724 { STB0899_SFRM, 0x68 },
725 { STB0899_SFRL, 0x40 },
726 { STB0899_SFRUPH, 0x2f },
727 { STB0899_SFRUPM, 0x68 },
728 { STB0899_SFRUPL, 0x40 },
729 { STB0899_EQUAI1, 0x02 },
730 { STB0899_EQUAQ1, 0xff },
731 { STB0899_EQUAI2, 0x04 },
732 { STB0899_EQUAQ2, 0x05 },
733 { STB0899_EQUAI3, 0x02 },
734 { STB0899_EQUAQ3, 0xfd },
735 { STB0899_EQUAI4, 0x03 },
736 { STB0899_EQUAQ4, 0x07 },
737 { STB0899_EQUAI5, 0x08 },
738 { STB0899_EQUAQ5, 0xf5 },
739 { STB0899_DSTATUS2, 0x00 },
740 { STB0899_VSTATUS, 0x00 },
741 { STB0899_VERROR, 0x86 },
742 { STB0899_IQSWAP, 0x2a },
743 { STB0899_ECNT1M, 0x00 },
744 { STB0899_ECNT1L, 0x00 },
745 { STB0899_ECNT2M, 0x00 },
746 { STB0899_ECNT2L, 0x00 },
747 { STB0899_ECNT3M, 0x0a },
748 { STB0899_ECNT3L, 0xad },
749 { STB0899_FECAUTO1, 0x06 },
750 { STB0899_FECM, 0x01 },
751 { STB0899_VTH12, 0xb0 },
752 { STB0899_VTH23, 0x7a },
753 { STB0899_VTH34, 0x58 },
754 { STB0899_VTH56, 0x38 },
755 { STB0899_VTH67, 0x34 },
756 { STB0899_VTH78, 0x24 },
757 { STB0899_PRVIT, 0xff },
758 { STB0899_VITSYNC, 0x19 },
759 { STB0899_RSULC, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
760 { STB0899_TSULC, 0x42 },
761 { STB0899_RSLLC, 0x41 },
762 { STB0899_TSLPL, 0x12 },
763 { STB0899_TSCFGH, 0x0c },
764 { STB0899_TSCFGM, 0x00 },
765 { STB0899_TSCFGL, 0x00 },
766 { STB0899_TSOUT, 0x69 }, /* 0x0d for CAM */
767 { STB0899_RSSYNCDEL, 0x00 },
768 { STB0899_TSINHDELH, 0x02 },
769 { STB0899_TSINHDELM, 0x00 },
770 { STB0899_TSINHDELL, 0x00 },
771 { STB0899_TSLLSTKM, 0x1b },
772 { STB0899_TSLLSTKL, 0xb3 },
773 { STB0899_TSULSTKM, 0x00 },
774 { STB0899_TSULSTKL, 0x00 },
775 { STB0899_PCKLENUL, 0xbc },
776 { STB0899_PCKLENLL, 0xcc },
777 { STB0899_RSPCKLEN, 0xbd },
778 { STB0899_TSSTATUS, 0x90 },
779 { STB0899_ERRCTRL1, 0xb6 },
780 { STB0899_ERRCTRL2, 0x95 },
781 { STB0899_ERRCTRL3, 0x8d },
782 { STB0899_DMONMSK1, 0x27 },
783 { STB0899_DMONMSK0, 0x03 },
784 { STB0899_DEMAPVIT, 0x5c },
785 { STB0899_PLPARM, 0x19 },
786 { STB0899_PDELCTRL, 0x48 },
787 { STB0899_PDELCTRL2, 0x00 },
788 { STB0899_BBHCTRL1, 0x00 },
789 { STB0899_BBHCTRL2, 0x00 },
790 { STB0899_HYSTTHRESH, 0x77 },
791 { STB0899_MATCSTM, 0x00 },
792 { STB0899_MATCSTL, 0x00 },
793 { STB0899_UPLCSTM, 0x00 },
794 { STB0899_UPLCSTL, 0x00 },
795 { STB0899_DFLCSTM, 0x00 },
796 { STB0899_DFLCSTL, 0x00 },
797 { STB0899_SYNCCST, 0x00 },
798 { STB0899_SYNCDCSTM, 0x00 },
799 { STB0899_SYNCDCSTL, 0x00 },
800 { STB0899_ISI_ENTRY, 0x00 },
801 { STB0899_ISI_BIT_EN, 0x00 },
802 { STB0899_MATSTRM, 0xf0 },
803 { STB0899_MATSTRL, 0x02 },
804 { STB0899_UPLSTRM, 0x45 },
805 { STB0899_UPLSTRL, 0x60 },
806 { STB0899_DFLSTRM, 0xe3 },
807 { STB0899_DFLSTRL, 0x00 },
808 { STB0899_SYNCSTR, 0x47 },
809 { STB0899_SYNCDSTRM, 0x05 },
810 { STB0899_SYNCDSTRL, 0x18 },
811 { STB0899_CFGPDELSTATUS1, 0x19 },
812 { STB0899_CFGPDELSTATUS2, 0x2b },
813 { STB0899_BBFERRORM, 0x00 },
814 { STB0899_BBFERRORL, 0x01 },
815 { STB0899_UPKTERRORM, 0x00 },
816 { STB0899_UPKTERRORL, 0x00 },
817 { 0xffff, 0xff },
818};
819
820static struct stb0899_config stb0899_config = {
821 .init_dev = pctv452e_init_dev,
822 .init_s2_demod = stb0899_s2_init_2,
823 .init_s1_demod = pctv452e_init_s1_demod,
824 .init_s2_fec = stb0899_s2_init_4,
825 .init_tst = stb0899_s1_init_5,
826
827 .demod_address = I2C_ADDR_STB0899, /* I2C Address */
828 .block_sync_mode = STB0899_SYNC_FORCED, /* ? */
829
830 .xtal_freq = 27000000, /* Assume Hz ? */
831 .inversion = IQ_SWAP_ON, /* ? */
832
833 .lo_clk = 76500000,
834 .hi_clk = 99000000,
835
836 .ts_output_mode = 0, /* Use parallel mode */
837 .clock_polarity = 0,
838 .data_clk_parity = 0,
839 .fec_mode = 0,
840
841 .esno_ave = STB0899_DVBS2_ESNO_AVE,
842 .esno_quant = STB0899_DVBS2_ESNO_QUANT,
843 .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
844 .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
845 .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
846 .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
847 .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
848 .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
849 .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
850
851 .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
852 .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
853 .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
854 .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
855
856 .tuner_get_frequency = stb6100_get_frequency,
857 .tuner_set_frequency = stb6100_set_frequency,
858 .tuner_set_bandwidth = stb6100_set_bandwidth,
859 .tuner_get_bandwidth = stb6100_get_bandwidth,
860 .tuner_set_rfsiggain = NULL,
861
862 /* helper for switching LED green/orange */
863 .postproc = pctv45e_postproc
864};
865
866static struct stb6100_config stb6100_config = {
867 .tuner_address = I2C_ADDR_STB6100,
868 .refclock = 27000000
869};
870
871
872static struct i2c_algorithm pctv452e_i2c_algo = {
873 .master_xfer = pctv452e_i2c_xfer,
874 .functionality = pctv452e_i2c_func
875};
876
877static int pctv452e_frontend_attach(struct dvb_usb_adapter *a)
878{
879 struct usb_device_id *id;
880
881 a->fe_adap[0].fe = dvb_attach(stb0899_attach, &stb0899_config,
882 &a->dev->i2c_adap);
883 if (!a->fe_adap[0].fe)
884 return -ENODEV;
885 if ((dvb_attach(lnbp22_attach, a->fe_adap[0].fe,
886 &a->dev->i2c_adap)) == 0)
887 err("Cannot attach lnbp22\n");
888
889 id = a->dev->desc->warm_ids[0];
890 if (USB_VID_TECHNOTREND == id->idVendor
891 && USB_PID_TECHNOTREND_CONNECT_S2_3650_CI == id->idProduct)
892 /* Error ignored. */
893 tt3650_ci_init(a);
894
895 return 0;
896}
897
898static int pctv452e_tuner_attach(struct dvb_usb_adapter *a)
899{
900 if (!a->fe_adap[0].fe)
901 return -ENODEV;
902 if (dvb_attach(stb6100_attach, a->fe_adap[0].fe, &stb6100_config,
903 &a->dev->i2c_adap) == 0) {
904 err("%s failed\n", __func__);
905 return -ENODEV;
906 }
907
908 return 0;
909}
910
911static struct usb_device_id pctv452e_usb_table[] = {
912 {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_452E)},
913 {USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_CONNECT_S2_3600)},
914 {USB_DEVICE(USB_VID_TECHNOTREND,
915 USB_PID_TECHNOTREND_CONNECT_S2_3650_CI)},
916 {}
917};
918MODULE_DEVICE_TABLE(usb, pctv452e_usb_table);
919
920static struct dvb_usb_device_properties pctv452e_properties = {
921 .caps = DVB_USB_IS_AN_I2C_ADAPTER, /* more ? */
922 .usb_ctrl = DEVICE_SPECIFIC,
923
924 .size_of_priv = sizeof(struct pctv452e_state),
925
926 .power_ctrl = pctv452e_power_ctrl,
927
928 .rc.core = {
929 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
930 .allowed_protos = RC_TYPE_UNKNOWN,
931 .rc_query = pctv452e_rc_query,
932 .rc_interval = 100,
933 },
934
935 .num_adapters = 1,
936 .adapter = {{
937 .num_frontends = 1,
938 .fe = {{
939 .frontend_attach = pctv452e_frontend_attach,
940 .tuner_attach = pctv452e_tuner_attach,
941
942 /* parameter for the MPEG2-data transfer */
943 .stream = {
944 .type = USB_ISOC,
945 .count = 4,
946 .endpoint = 0x02,
947 .u = {
948 .isoc = {
949 .framesperurb = 4,
950 .framesize = 940,
951 .interval = 1
952 }
953 }
954 },
955 } },
956 } },
957
958 .i2c_algo = &pctv452e_i2c_algo,
959
960 .generic_bulk_ctrl_endpoint = 1, /* allow generice rw function */
961
962 .num_device_descs = 1,
963 .devices = {
964 { .name = "PCTV HDTV USB",
965 .cold_ids = { NULL, NULL }, /* this is a warm only device */
966 .warm_ids = { &pctv452e_usb_table[0], NULL }
967 },
968 { 0 },
969 }
970};
971
972static struct dvb_usb_device_properties tt_connect_s2_3600_properties = {
973 .caps = DVB_USB_IS_AN_I2C_ADAPTER, /* more ? */
974 .usb_ctrl = DEVICE_SPECIFIC,
975
976 .size_of_priv = sizeof(struct pctv452e_state),
977
978 .power_ctrl = pctv452e_power_ctrl,
979 .read_mac_address = pctv452e_read_mac_address,
980
981 .rc.core = {
982 .rc_codes = RC_MAP_TT_1500,
983 .allowed_protos = RC_TYPE_UNKNOWN,
984 .rc_query = pctv452e_rc_query,
985 .rc_interval = 100,
986 },
987
988 .num_adapters = 1,
989 .adapter = {{
990 .num_frontends = 1,
991 .fe = {{
992 .frontend_attach = pctv452e_frontend_attach,
993 .tuner_attach = pctv452e_tuner_attach,
994
995 /* parameter for the MPEG2-data transfer */
996 .stream = {
997 .type = USB_ISOC,
998 .count = 7,
999 .endpoint = 0x02,
1000 .u = {
1001 .isoc = {
1002 .framesperurb = 4,
1003 .framesize = 940,
1004 .interval = 1
1005 }
1006 }
1007 },
1008
1009 } },
1010 } },
1011
1012 .i2c_algo = &pctv452e_i2c_algo,
1013
1014 .generic_bulk_ctrl_endpoint = 1, /* allow generic rw function*/
1015
1016 .num_device_descs = 2,
1017 .devices = {
1018 { .name = "Technotrend TT Connect S2-3600",
1019 .cold_ids = { NULL, NULL }, /* this is a warm only device */
1020 .warm_ids = { &pctv452e_usb_table[1], NULL }
1021 },
1022 { .name = "Technotrend TT Connect S2-3650-CI",
1023 .cold_ids = { NULL, NULL },
1024 .warm_ids = { &pctv452e_usb_table[2], NULL }
1025 },
1026 { 0 },
1027 }
1028};
1029
1030static void pctv452e_usb_disconnect(struct usb_interface *intf)
1031{
1032 struct dvb_usb_device *d = usb_get_intfdata(intf);
1033
1034 tt3650_ci_uninit(d);
1035 dvb_usb_device_exit(intf);
1036}
1037
1038static int pctv452e_usb_probe(struct usb_interface *intf,
1039 const struct usb_device_id *id)
1040{
1041 if (0 == dvb_usb_device_init(intf, &pctv452e_properties,
1042 THIS_MODULE, NULL, adapter_nr) ||
1043 0 == dvb_usb_device_init(intf, &tt_connect_s2_3600_properties,
1044 THIS_MODULE, NULL, adapter_nr))
1045 return 0;
1046
1047 return -ENODEV;
1048}
1049
1050static struct usb_driver pctv452e_usb_driver = {
1051 .name = "pctv452e",
1052 .probe = pctv452e_usb_probe,
1053 .disconnect = pctv452e_usb_disconnect,
1054 .id_table = pctv452e_usb_table,
1055};
1056
1057module_usb_driver(pctv452e_usb_driver);
1058
1059MODULE_AUTHOR("Dominik Kuhlen <dkuhlen@gmx.net>");
1060MODULE_AUTHOR("Andre Weidemann <Andre.Weidemann@web.de>");
1061MODULE_AUTHOR("Michael H. Schimek <mschimek@gmx.at>");
1062MODULE_DESCRIPTION("Pinnacle PCTV HDTV USB DVB / TT connect S2-3600 Driver");
1063MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c
new file mode 100644
index 000000000000..acefaa89cc53
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/technisat-usb2.c
@@ -0,0 +1,789 @@
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_adap[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_adap[0].fe = dvb_attach(stv090x_attach, &technisat_usb2_stv090x_config,
509 &a->dev->i2c_adap, STV090x_DEMODULATOR_0);
510
511 if (a->fe_adap[0].fe) {
512 struct stv6110x_devctl *ctl;
513
514 ctl = dvb_attach(stv6110x_attach,
515 a->fe_adap[0].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_adap[0].fe->ops.init)
536 a->fe_adap[0].fe->ops.init(a->fe_adap[0].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_adap[0].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_adap[0].fe->ops.info.name, a->dev->desc->name,
555 sizeof(a->fe_adap[0].fe->ops.info.name));
556 } else {
557 dvb_frontend_detach(a->fe_adap[0].fe);
558 a->fe_adap[0].fe = NULL;
559 }
560 }
561
562 technisat_usb2_set_led_timer(a->dev, 1, 1);
563
564 return a->fe_adap[0].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 .num_frontends = 1,
701 .fe = {{
702 .frontend_attach = technisat_usb2_frontend_attach,
703
704 .stream = {
705 .type = USB_ISOC,
706 .count = 8,
707 .endpoint = 0x2,
708 .u = {
709 .isoc = {
710 .framesperurb = 32,
711 .framesize = 2048,
712 .interval = 3,
713 }
714 }
715 },
716 }},
717 .size_of_priv = 0,
718 },
719 },
720
721 .num_device_descs = 1,
722 .devices = {
723 { "Technisat SkyStar USB HD (DVB-S/S2)",
724 { &technisat_usb2_id_table[0], NULL },
725 { NULL },
726 },
727 },
728
729 .rc.core = {
730 .rc_interval = 100,
731 .rc_codes = RC_MAP_TECHNISAT_USB2,
732 .module_name = "technisat-usb2",
733 .rc_query = technisat_usb2_rc_query,
734 .allowed_protos = RC_TYPE_ALL,
735 .driver_type = RC_DRIVER_IR_RAW,
736 }
737};
738
739static int technisat_usb2_probe(struct usb_interface *intf,
740 const struct usb_device_id *id)
741{
742 struct dvb_usb_device *dev;
743
744 if (dvb_usb_device_init(intf, &technisat_usb2_devices, THIS_MODULE,
745 &dev, adapter_nr) != 0)
746 return -ENODEV;
747
748 if (dev) {
749 struct technisat_usb2_state *state = dev->priv;
750 state->dev = dev;
751
752 if (!disable_led_control) {
753 INIT_DELAYED_WORK(&state->green_led_work,
754 technisat_usb2_green_led_control);
755 schedule_delayed_work(&state->green_led_work,
756 msecs_to_jiffies(500));
757 }
758 }
759
760 return 0;
761}
762
763static void technisat_usb2_disconnect(struct usb_interface *intf)
764{
765 struct dvb_usb_device *dev = usb_get_intfdata(intf);
766
767 /* work and stuff was only created when the device is is hot-state */
768 if (dev != NULL) {
769 struct technisat_usb2_state *state = dev->priv;
770 if (state != NULL)
771 cancel_delayed_work_sync(&state->green_led_work);
772 }
773
774 dvb_usb_device_exit(intf);
775}
776
777static struct usb_driver technisat_usb2_driver = {
778 .name = "dvb_usb_technisat_usb2",
779 .probe = technisat_usb2_probe,
780 .disconnect = technisat_usb2_disconnect,
781 .id_table = technisat_usb2_id_table,
782};
783
784module_usb_driver(technisat_usb2_driver);
785
786MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>");
787MODULE_DESCRIPTION("Driver for Technisat DVB-S/S2 USB 2.0 device");
788MODULE_VERSION("1.0");
789MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/ttusb2.c b/drivers/media/usb/dvb-usb/ttusb2.c
new file mode 100644
index 000000000000..e53a1061cb8e
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/ttusb2.c
@@ -0,0 +1,820 @@
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 "tda10048.h"
34#include "tda827x.h"
35#include "lnbp21.h"
36/* CA */
37#include "dvb_ca_en50221.h"
38
39/* debug */
40static int dvb_usb_ttusb2_debug;
41#define deb_info(args...) dprintk(dvb_usb_ttusb2_debug,0x01,args)
42module_param_named(debug,dvb_usb_ttusb2_debug, int, 0644);
43MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS);
44static int dvb_usb_ttusb2_debug_ci;
45module_param_named(debug_ci,dvb_usb_ttusb2_debug_ci, int, 0644);
46MODULE_PARM_DESC(debug_ci, "set debugging ci." DVB_USB_DEBUG_STATUS);
47
48DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
49
50#define ci_dbg(format, arg...) \
51do { \
52 if (dvb_usb_ttusb2_debug_ci) \
53 printk(KERN_DEBUG DVB_USB_LOG_PREFIX \
54 ": %s " format "\n" , __func__, ## arg); \
55} while (0)
56
57enum {
58 TT3650_CMD_CI_TEST = 0x40,
59 TT3650_CMD_CI_RD_CTRL,
60 TT3650_CMD_CI_WR_CTRL,
61 TT3650_CMD_CI_RD_ATTR,
62 TT3650_CMD_CI_WR_ATTR,
63 TT3650_CMD_CI_RESET,
64 TT3650_CMD_CI_SET_VIDEO_PORT
65};
66
67struct ttusb2_state {
68 struct dvb_ca_en50221 ca;
69 struct mutex ca_mutex;
70 u8 id;
71 u16 last_rc_key;
72};
73
74static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd,
75 u8 *wbuf, int wlen, u8 *rbuf, int rlen)
76{
77 struct ttusb2_state *st = d->priv;
78 u8 *s, *r = NULL;
79 int ret = 0;
80
81 s = kzalloc(wlen+4, GFP_KERNEL);
82 if (!s)
83 return -ENOMEM;
84
85 r = kzalloc(64, GFP_KERNEL);
86 if (!r) {
87 kfree(s);
88 return -ENOMEM;
89 }
90
91 s[0] = 0xaa;
92 s[1] = ++st->id;
93 s[2] = cmd;
94 s[3] = wlen;
95 memcpy(&s[4],wbuf,wlen);
96
97 ret = dvb_usb_generic_rw(d, s, wlen+4, r, 64, 0);
98
99 if (ret != 0 ||
100 r[0] != 0x55 ||
101 r[1] != s[1] ||
102 r[2] != cmd ||
103 (rlen > 0 && r[3] != rlen)) {
104 warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]);
105 kfree(s);
106 kfree(r);
107 return -EIO;
108 }
109
110 if (rlen > 0)
111 memcpy(rbuf, &r[4], rlen);
112
113 kfree(s);
114 kfree(r);
115
116 return 0;
117}
118
119/* ci */
120static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len)
121{
122 int ret;
123 u8 rx[60];/* (64 -4) */
124 ret = ttusb2_msg(d, cmd, data, write_len, rx, read_len);
125 if (!ret)
126 memcpy(data, rx, read_len);
127 return ret;
128}
129
130static int tt3650_ci_msg_locked(struct dvb_ca_en50221 *ca, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len)
131{
132 struct dvb_usb_device *d = ca->data;
133 struct ttusb2_state *state = d->priv;
134 int ret;
135
136 mutex_lock(&state->ca_mutex);
137 ret = tt3650_ci_msg(d, cmd, data, write_len, read_len);
138 mutex_unlock(&state->ca_mutex);
139
140 return ret;
141}
142
143static int tt3650_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
144{
145 u8 buf[3];
146 int ret = 0;
147
148 if (slot)
149 return -EINVAL;
150
151 buf[0] = (address >> 8) & 0x0F;
152 buf[1] = address;
153
154
155 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_ATTR, buf, 2, 3);
156
157 ci_dbg("%04x -> %d 0x%02x", address, ret, buf[2]);
158
159 if (ret < 0)
160 return ret;
161
162 return buf[2];
163}
164
165static int tt3650_ci_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
166{
167 u8 buf[3];
168
169 ci_dbg("%d 0x%04x 0x%02x", slot, address, value);
170
171 if (slot)
172 return -EINVAL;
173
174 buf[0] = (address >> 8) & 0x0F;
175 buf[1] = address;
176 buf[2] = value;
177
178 return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_ATTR, buf, 3, 3);
179}
180
181static int tt3650_ci_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
182{
183 u8 buf[2];
184 int ret;
185
186 if (slot)
187 return -EINVAL;
188
189 buf[0] = address & 3;
190
191 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_CTRL, buf, 1, 2);
192
193 ci_dbg("0x%02x -> %d 0x%02x", address, ret, buf[1]);
194
195 if (ret < 0)
196 return ret;
197
198 return buf[1];
199}
200
201static int tt3650_ci_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
202{
203 u8 buf[2];
204
205 ci_dbg("%d 0x%02x 0x%02x", slot, address, value);
206
207 if (slot)
208 return -EINVAL;
209
210 buf[0] = address;
211 buf[1] = value;
212
213 return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_CTRL, buf, 2, 2);
214}
215
216static int tt3650_ci_set_video_port(struct dvb_ca_en50221 *ca, int slot, int enable)
217{
218 u8 buf[1];
219 int ret;
220
221 ci_dbg("%d %d", slot, enable);
222
223 if (slot)
224 return -EINVAL;
225
226 buf[0] = enable;
227
228 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
229 if (ret < 0)
230 return ret;
231
232 if (enable != buf[0]) {
233 err("CI not %sabled.", enable ? "en" : "dis");
234 return -EIO;
235 }
236
237 return 0;
238}
239
240static int tt3650_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
241{
242 return tt3650_ci_set_video_port(ca, slot, 0);
243}
244
245static int tt3650_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
246{
247 return tt3650_ci_set_video_port(ca, slot, 1);
248}
249
250static int tt3650_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
251{
252 struct dvb_usb_device *d = ca->data;
253 struct ttusb2_state *state = d->priv;
254 u8 buf[1];
255 int ret;
256
257 ci_dbg("%d", slot);
258
259 if (slot)
260 return -EINVAL;
261
262 buf[0] = 0;
263
264 mutex_lock(&state->ca_mutex);
265
266 ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
267 if (ret)
268 goto failed;
269
270 msleep(500);
271
272 buf[0] = 1;
273
274 ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
275 if (ret)
276 goto failed;
277
278 msleep(500);
279
280 buf[0] = 0; /* FTA */
281
282 ret = tt3650_ci_msg(d, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
283
284 msleep(1100);
285
286 failed:
287 mutex_unlock(&state->ca_mutex);
288
289 return ret;
290}
291
292static int tt3650_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
293{
294 u8 buf[1];
295 int ret;
296
297 if (slot)
298 return -EINVAL;
299
300 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_TEST, buf, 0, 1);
301 if (ret)
302 return ret;
303
304 if (1 == buf[0]) {
305 return DVB_CA_EN50221_POLL_CAM_PRESENT |
306 DVB_CA_EN50221_POLL_CAM_READY;
307 }
308 return 0;
309}
310
311static void tt3650_ci_uninit(struct dvb_usb_device *d)
312{
313 struct ttusb2_state *state;
314
315 ci_dbg("");
316
317 if (NULL == d)
318 return;
319
320 state = d->priv;
321 if (NULL == state)
322 return;
323
324 if (NULL == state->ca.data)
325 return;
326
327 dvb_ca_en50221_release(&state->ca);
328
329 memset(&state->ca, 0, sizeof(state->ca));
330}
331
332static int tt3650_ci_init(struct dvb_usb_adapter *a)
333{
334 struct dvb_usb_device *d = a->dev;
335 struct ttusb2_state *state = d->priv;
336 int ret;
337
338 ci_dbg("");
339
340 mutex_init(&state->ca_mutex);
341
342 state->ca.owner = THIS_MODULE;
343 state->ca.read_attribute_mem = tt3650_ci_read_attribute_mem;
344 state->ca.write_attribute_mem = tt3650_ci_write_attribute_mem;
345 state->ca.read_cam_control = tt3650_ci_read_cam_control;
346 state->ca.write_cam_control = tt3650_ci_write_cam_control;
347 state->ca.slot_reset = tt3650_ci_slot_reset;
348 state->ca.slot_shutdown = tt3650_ci_slot_shutdown;
349 state->ca.slot_ts_enable = tt3650_ci_slot_ts_enable;
350 state->ca.poll_slot_status = tt3650_ci_poll_slot_status;
351 state->ca.data = d;
352
353 ret = dvb_ca_en50221_init(&a->dvb_adap,
354 &state->ca,
355 /* flags */ 0,
356 /* n_slots */ 1);
357 if (ret) {
358 err("Cannot initialize CI: Error %d.", ret);
359 memset(&state->ca, 0, sizeof(state->ca));
360 return ret;
361 }
362
363 info("CI initialized.");
364
365 return 0;
366}
367
368static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
369{
370 struct dvb_usb_device *d = i2c_get_adapdata(adap);
371 static u8 obuf[60], ibuf[60];
372 int i, write_read, read;
373
374 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
375 return -EAGAIN;
376
377 if (num > 2)
378 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
379
380 for (i = 0; i < num; i++) {
381 write_read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
382 read = msg[i].flags & I2C_M_RD;
383
384 obuf[0] = (msg[i].addr << 1) | (write_read | read);
385 if (read)
386 obuf[1] = 0;
387 else
388 obuf[1] = msg[i].len;
389
390 /* read request */
391 if (write_read)
392 obuf[2] = msg[i+1].len;
393 else if (read)
394 obuf[2] = msg[i].len;
395 else
396 obuf[2] = 0;
397
398 memcpy(&obuf[3], msg[i].buf, msg[i].len);
399
400 if (ttusb2_msg(d, CMD_I2C_XFER, obuf, obuf[1]+3, ibuf, obuf[2] + 3) < 0) {
401 err("i2c transfer failed.");
402 break;
403 }
404
405 if (write_read) {
406 memcpy(msg[i+1].buf, &ibuf[3], msg[i+1].len);
407 i++;
408 } else if (read)
409 memcpy(msg[i].buf, &ibuf[3], msg[i].len);
410 }
411
412 mutex_unlock(&d->i2c_mutex);
413 return i;
414}
415
416static u32 ttusb2_i2c_func(struct i2c_adapter *adapter)
417{
418 return I2C_FUNC_I2C;
419}
420
421static struct i2c_algorithm ttusb2_i2c_algo = {
422 .master_xfer = ttusb2_i2c_xfer,
423 .functionality = ttusb2_i2c_func,
424};
425
426/* command to poll IR receiver (copied from pctv452e.c) */
427#define CMD_GET_IR_CODE 0x1b
428
429/* IR */
430static int tt3650_rc_query(struct dvb_usb_device *d)
431{
432 int ret;
433 u8 rx[9]; /* A CMD_GET_IR_CODE reply is 9 bytes long */
434 struct ttusb2_state *st = d->priv;
435 ret = ttusb2_msg(d, CMD_GET_IR_CODE, NULL, 0, rx, sizeof(rx));
436 if (ret != 0)
437 return ret;
438
439 if (rx[8] & 0x01) {
440 /* got a "press" event */
441 st->last_rc_key = (rx[3] << 8) | rx[2];
442 deb_info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[2], rx[3]);
443 rc_keydown(d->rc_dev, st->last_rc_key, 0);
444 } else if (st->last_rc_key) {
445 rc_keyup(d->rc_dev);
446 st->last_rc_key = 0;
447 }
448
449 return 0;
450}
451
452
453/* Callbacks for DVB USB */
454static int ttusb2_identify_state (struct usb_device *udev, struct
455 dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
456 int *cold)
457{
458 *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
459 return 0;
460}
461
462static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff)
463{
464 u8 b = onoff;
465 ttusb2_msg(d, CMD_POWER, &b, 0, NULL, 0);
466 return ttusb2_msg(d, CMD_POWER, &b, 1, NULL, 0);
467}
468
469
470static struct tda10086_config tda10086_config = {
471 .demod_address = 0x0e,
472 .invert = 0,
473 .diseqc_tone = 1,
474 .xtal_freq = TDA10086_XTAL_16M,
475};
476
477static struct tda10023_config tda10023_config = {
478 .demod_address = 0x0c,
479 .invert = 0,
480 .xtal = 16000000,
481 .pll_m = 11,
482 .pll_p = 3,
483 .pll_n = 1,
484 .deltaf = 0xa511,
485};
486
487static struct tda10048_config tda10048_config = {
488 .demod_address = 0x10 >> 1,
489 .output_mode = TDA10048_PARALLEL_OUTPUT,
490 .inversion = TDA10048_INVERSION_ON,
491 .dtv6_if_freq_khz = TDA10048_IF_4000,
492 .dtv7_if_freq_khz = TDA10048_IF_4500,
493 .dtv8_if_freq_khz = TDA10048_IF_5000,
494 .clk_freq_khz = TDA10048_CLK_16000,
495 .no_firmware = 1,
496 .set_pll = true ,
497 .pll_m = 5,
498 .pll_n = 3,
499 .pll_p = 0,
500};
501
502static struct tda827x_config tda827x_config = {
503 .config = 0,
504};
505
506static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap)
507{
508 if (usb_set_interface(adap->dev->udev,0,3) < 0)
509 err("set interface to alts=3 failed");
510
511 if ((adap->fe_adap[0].fe = dvb_attach(tda10086_attach, &tda10086_config, &adap->dev->i2c_adap)) == NULL) {
512 deb_info("TDA10086 attach failed\n");
513 return -ENODEV;
514 }
515
516 return 0;
517}
518
519static int ttusb2_ct3650_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
520{
521 struct dvb_usb_adapter *adap = fe->dvb->priv;
522
523 return adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, enable);
524}
525
526static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap)
527{
528 if (usb_set_interface(adap->dev->udev, 0, 3) < 0)
529 err("set interface to alts=3 failed");
530
531 if (adap->fe_adap[0].fe == NULL) {
532 /* FE 0 DVB-C */
533 adap->fe_adap[0].fe = dvb_attach(tda10023_attach,
534 &tda10023_config, &adap->dev->i2c_adap, 0x48);
535
536 if (adap->fe_adap[0].fe == NULL) {
537 deb_info("TDA10023 attach failed\n");
538 return -ENODEV;
539 }
540 tt3650_ci_init(adap);
541 } else {
542 adap->fe_adap[1].fe = dvb_attach(tda10048_attach,
543 &tda10048_config, &adap->dev->i2c_adap);
544
545 if (adap->fe_adap[1].fe == NULL) {
546 deb_info("TDA10048 attach failed\n");
547 return -ENODEV;
548 }
549
550 /* tuner is behind TDA10023 I2C-gate */
551 adap->fe_adap[1].fe->ops.i2c_gate_ctrl = ttusb2_ct3650_i2c_gate_ctrl;
552
553 }
554
555 return 0;
556}
557
558static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap)
559{
560 struct dvb_frontend *fe;
561
562 /* MFE: select correct FE to attach tuner since that's called twice */
563 if (adap->fe_adap[1].fe == NULL)
564 fe = adap->fe_adap[0].fe;
565 else
566 fe = adap->fe_adap[1].fe;
567
568 /* attach tuner */
569 if (dvb_attach(tda827x_attach, fe, 0x61, &adap->dev->i2c_adap, &tda827x_config) == NULL) {
570 printk(KERN_ERR "%s: No tda827x found!\n", __func__);
571 return -ENODEV;
572 }
573 return 0;
574}
575
576static int ttusb2_tuner_tda826x_attach(struct dvb_usb_adapter *adap)
577{
578 if (dvb_attach(tda826x_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) {
579 deb_info("TDA8263 attach failed\n");
580 return -ENODEV;
581 }
582
583 if (dvb_attach(lnbp21_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, 0, 0) == NULL) {
584 deb_info("LNBP21 attach failed\n");
585 return -ENODEV;
586 }
587 return 0;
588}
589
590/* DVB USB Driver stuff */
591static struct dvb_usb_device_properties ttusb2_properties;
592static struct dvb_usb_device_properties ttusb2_properties_s2400;
593static struct dvb_usb_device_properties ttusb2_properties_ct3650;
594
595static void ttusb2_usb_disconnect(struct usb_interface *intf)
596{
597 struct dvb_usb_device *d = usb_get_intfdata(intf);
598
599 tt3650_ci_uninit(d);
600 dvb_usb_device_exit(intf);
601}
602
603static int ttusb2_probe(struct usb_interface *intf,
604 const struct usb_device_id *id)
605{
606 if (0 == dvb_usb_device_init(intf, &ttusb2_properties,
607 THIS_MODULE, NULL, adapter_nr) ||
608 0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400,
609 THIS_MODULE, NULL, adapter_nr) ||
610 0 == dvb_usb_device_init(intf, &ttusb2_properties_ct3650,
611 THIS_MODULE, NULL, adapter_nr))
612 return 0;
613 return -ENODEV;
614}
615
616static struct usb_device_id ttusb2_table [] = {
617 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) },
618 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) },
619 { USB_DEVICE(USB_VID_TECHNOTREND,
620 USB_PID_TECHNOTREND_CONNECT_S2400) },
621 { USB_DEVICE(USB_VID_TECHNOTREND,
622 USB_PID_TECHNOTREND_CONNECT_CT3650) },
623 {} /* Terminating entry */
624};
625MODULE_DEVICE_TABLE (usb, ttusb2_table);
626
627static struct dvb_usb_device_properties ttusb2_properties = {
628 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
629
630 .usb_ctrl = CYPRESS_FX2,
631 .firmware = "dvb-usb-pctv-400e-01.fw",
632
633 .size_of_priv = sizeof(struct ttusb2_state),
634
635 .num_adapters = 1,
636 .adapter = {
637 {
638 .num_frontends = 1,
639 .fe = {{
640 .streaming_ctrl = NULL, // ttusb2_streaming_ctrl,
641
642 .frontend_attach = ttusb2_frontend_tda10086_attach,
643 .tuner_attach = ttusb2_tuner_tda826x_attach,
644
645 /* parameter for the MPEG2-data transfer */
646 .stream = {
647 .type = USB_ISOC,
648 .count = 5,
649 .endpoint = 0x02,
650 .u = {
651 .isoc = {
652 .framesperurb = 4,
653 .framesize = 940,
654 .interval = 1,
655 }
656 }
657 }
658 }},
659 }
660 },
661
662 .power_ctrl = ttusb2_power_ctrl,
663 .identify_state = ttusb2_identify_state,
664
665 .i2c_algo = &ttusb2_i2c_algo,
666
667 .generic_bulk_ctrl_endpoint = 0x01,
668
669 .num_device_descs = 2,
670 .devices = {
671 { "Pinnacle 400e DVB-S USB2.0",
672 { &ttusb2_table[0], NULL },
673 { NULL },
674 },
675 { "Pinnacle 450e DVB-S USB2.0",
676 { &ttusb2_table[1], NULL },
677 { NULL },
678 },
679 }
680};
681
682static struct dvb_usb_device_properties ttusb2_properties_s2400 = {
683 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
684
685 .usb_ctrl = CYPRESS_FX2,
686 .firmware = "dvb-usb-tt-s2400-01.fw",
687
688 .size_of_priv = sizeof(struct ttusb2_state),
689
690 .num_adapters = 1,
691 .adapter = {
692 {
693 .num_frontends = 1,
694 .fe = {{
695 .streaming_ctrl = NULL,
696
697 .frontend_attach = ttusb2_frontend_tda10086_attach,
698 .tuner_attach = ttusb2_tuner_tda826x_attach,
699
700 /* parameter for the MPEG2-data transfer */
701 .stream = {
702 .type = USB_ISOC,
703 .count = 5,
704 .endpoint = 0x02,
705 .u = {
706 .isoc = {
707 .framesperurb = 4,
708 .framesize = 940,
709 .interval = 1,
710 }
711 }
712 }
713 }},
714 }
715 },
716
717 .power_ctrl = ttusb2_power_ctrl,
718 .identify_state = ttusb2_identify_state,
719
720 .i2c_algo = &ttusb2_i2c_algo,
721
722 .generic_bulk_ctrl_endpoint = 0x01,
723
724 .num_device_descs = 1,
725 .devices = {
726 { "Technotrend TT-connect S-2400",
727 { &ttusb2_table[2], NULL },
728 { NULL },
729 },
730 }
731};
732
733static struct dvb_usb_device_properties ttusb2_properties_ct3650 = {
734 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
735
736 .usb_ctrl = CYPRESS_FX2,
737
738 .size_of_priv = sizeof(struct ttusb2_state),
739
740 .rc.core = {
741 .rc_interval = 150, /* Less than IR_KEYPRESS_TIMEOUT */
742 .rc_codes = RC_MAP_TT_1500,
743 .rc_query = tt3650_rc_query,
744 .allowed_protos = RC_TYPE_UNKNOWN,
745 },
746
747 .num_adapters = 1,
748 .adapter = {
749 {
750 .num_frontends = 2,
751 .fe = {{
752 .streaming_ctrl = NULL,
753
754 .frontend_attach = ttusb2_frontend_tda10023_attach,
755 .tuner_attach = ttusb2_tuner_tda827x_attach,
756
757 /* parameter for the MPEG2-data transfer */
758 .stream = {
759 .type = USB_ISOC,
760 .count = 5,
761 .endpoint = 0x02,
762 .u = {
763 .isoc = {
764 .framesperurb = 4,
765 .framesize = 940,
766 .interval = 1,
767 }
768 }
769 }
770 }, {
771 .streaming_ctrl = NULL,
772
773 .frontend_attach = ttusb2_frontend_tda10023_attach,
774 .tuner_attach = ttusb2_tuner_tda827x_attach,
775
776 /* parameter for the MPEG2-data transfer */
777 .stream = {
778 .type = USB_ISOC,
779 .count = 5,
780 .endpoint = 0x02,
781 .u = {
782 .isoc = {
783 .framesperurb = 4,
784 .framesize = 940,
785 .interval = 1,
786 }
787 }
788 }
789 }},
790 },
791 },
792
793 .power_ctrl = ttusb2_power_ctrl,
794 .identify_state = ttusb2_identify_state,
795
796 .i2c_algo = &ttusb2_i2c_algo,
797
798 .generic_bulk_ctrl_endpoint = 0x01,
799
800 .num_device_descs = 1,
801 .devices = {
802 { "Technotrend TT-connect CT-3650",
803 .warm_ids = { &ttusb2_table[3], NULL },
804 },
805 }
806};
807
808static struct usb_driver ttusb2_driver = {
809 .name = "dvb_usb_ttusb2",
810 .probe = ttusb2_probe,
811 .disconnect = ttusb2_usb_disconnect,
812 .id_table = ttusb2_table,
813};
814
815module_usb_driver(ttusb2_driver);
816
817MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
818MODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0");
819MODULE_VERSION("1.0");
820MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/ttusb2.h b/drivers/media/usb/dvb-usb/ttusb2.h
new file mode 100644
index 000000000000..52a63af40896
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/umt-010.c b/drivers/media/usb/dvb-usb/umt-010.c
new file mode 100644
index 000000000000..9b042292e788
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/umt-010.c
@@ -0,0 +1,151 @@
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_adap[0].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_adap[0].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 .num_frontends = 1,
104 .fe = {{
105 .streaming_ctrl = dibusb2_0_streaming_ctrl,
106 .frontend_attach = umt_mt352_frontend_attach,
107 .tuner_attach = umt_tuner_attach,
108
109 /* parameter for the MPEG2-data transfer */
110 .stream = {
111 .type = USB_BULK,
112 .count = MAX_NO_URBS_FOR_DATA_STREAM,
113 .endpoint = 0x06,
114 .u = {
115 .bulk = {
116 .buffersize = 512,
117 }
118 }
119 },
120 }},
121 .size_of_priv = sizeof(struct dibusb_state),
122 }
123 },
124 .power_ctrl = dibusb_power_ctrl,
125
126 .i2c_algo = &dibusb_i2c_algo,
127
128 .generic_bulk_ctrl_endpoint = 0x01,
129
130 .num_device_descs = 1,
131 .devices = {
132 { "Hanftek UMT-010 DVB-T USB2.0",
133 { &umt_table[0], NULL },
134 { &umt_table[1], NULL },
135 },
136 }
137};
138
139static struct usb_driver umt_driver = {
140 .name = "dvb_usb_umt_010",
141 .probe = umt_probe,
142 .disconnect = dvb_usb_device_exit,
143 .id_table = umt_table,
144};
145
146module_usb_driver(umt_driver);
147
148MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
149MODULE_DESCRIPTION("Driver for HanfTek UMT 010 USB2.0 DVB-T device");
150MODULE_VERSION("1.0");
151MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/usb-urb.c b/drivers/media/usb/dvb-usb/usb-urb.c
new file mode 100644
index 000000000000..d62ee0f5a165
--- /dev/null
+++ b/drivers/media/usb/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[j]);
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[j]);
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/usb/dvb-usb/vp702x-fe.c b/drivers/media/usb/dvb-usb/vp702x-fe.c
new file mode 100644
index 000000000000..5eab468dd904
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/vp702x-fe.c
@@ -0,0 +1,379 @@
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{
140 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
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->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->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->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_send_diseqc_msg (struct dvb_frontend* fe,
215 struct dvb_diseqc_master_cmd *m)
216{
217 u8 *cmd;
218 struct vp702x_fe_state *st = fe->demodulator_priv;
219 struct vp702x_device_state *dst = st->d->priv;
220
221 deb_fe("%s\n",__func__);
222
223 if (m->msg_len > 4)
224 return -EINVAL;
225
226 mutex_lock(&dst->buf_mutex);
227
228 cmd = dst->buf;
229 cmd[1] = SET_DISEQC_CMD;
230 cmd[2] = m->msg_len;
231 memcpy(&cmd[3], m->msg, m->msg_len);
232 cmd[7] = vp702x_chksum(cmd, 0, 7);
233
234 vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
235
236 if (cmd[2] == 0 && cmd[3] == 0)
237 deb_fe("diseqc cmd failed.\n");
238 else
239 deb_fe("diseqc cmd succeeded.\n");
240
241 mutex_unlock(&dst->buf_mutex);
242
243 return 0;
244}
245
246static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
247{
248 deb_fe("%s\n",__func__);
249 return 0;
250}
251
252static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
253{
254 struct vp702x_fe_state *st = fe->demodulator_priv;
255 struct vp702x_device_state *dst = st->d->priv;
256 u8 *buf;
257
258 deb_fe("%s\n",__func__);
259
260 st->tone_mode = tone;
261
262 if (tone == SEC_TONE_ON)
263 st->lnb_buf[2] = 0x02;
264 else
265 st->lnb_buf[2] = 0x00;
266
267 st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
268
269 mutex_lock(&dst->buf_mutex);
270
271 buf = dst->buf;
272 memcpy(buf, st->lnb_buf, 8);
273
274 vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
275 if (buf[2] == 0 && buf[3] == 0)
276 deb_fe("set_tone cmd failed.\n");
277 else
278 deb_fe("set_tone cmd succeeded.\n");
279
280 mutex_unlock(&dst->buf_mutex);
281
282 return 0;
283}
284
285static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t
286 voltage)
287{
288 struct vp702x_fe_state *st = fe->demodulator_priv;
289 struct vp702x_device_state *dst = st->d->priv;
290 u8 *buf;
291 deb_fe("%s\n",__func__);
292
293 st->voltage = voltage;
294
295 if (voltage != SEC_VOLTAGE_OFF)
296 st->lnb_buf[4] = 0x01;
297 else
298 st->lnb_buf[4] = 0x00;
299
300 st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
301
302 mutex_lock(&dst->buf_mutex);
303
304 buf = dst->buf;
305 memcpy(buf, st->lnb_buf, 8);
306
307 vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
308 if (buf[2] == 0 && buf[3] == 0)
309 deb_fe("set_voltage cmd failed.\n");
310 else
311 deb_fe("set_voltage cmd succeeded.\n");
312
313 mutex_unlock(&dst->buf_mutex);
314 return 0;
315}
316
317static void vp702x_fe_release(struct dvb_frontend* fe)
318{
319 struct vp702x_fe_state *st = fe->demodulator_priv;
320 kfree(st);
321}
322
323static struct dvb_frontend_ops vp702x_fe_ops;
324
325struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d)
326{
327 struct vp702x_fe_state *s = kzalloc(sizeof(struct vp702x_fe_state), GFP_KERNEL);
328 if (s == NULL)
329 goto error;
330
331 s->d = d;
332
333 memcpy(&s->fe.ops,&vp702x_fe_ops,sizeof(struct dvb_frontend_ops));
334 s->fe.demodulator_priv = s;
335
336 s->lnb_buf[1] = SET_LNB_POWER;
337 s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */
338
339 return &s->fe;
340error:
341 return NULL;
342}
343
344
345static struct dvb_frontend_ops vp702x_fe_ops = {
346 .delsys = { SYS_DVBS },
347 .info = {
348 .name = "Twinhan DST-like frontend (VP7021/VP7020) DVB-S",
349 .frequency_min = 950000,
350 .frequency_max = 2150000,
351 .frequency_stepsize = 1000, /* kHz for QPSK frontends */
352 .frequency_tolerance = 0,
353 .symbol_rate_min = 1000000,
354 .symbol_rate_max = 45000000,
355 .symbol_rate_tolerance = 500, /* ppm */
356 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
357 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
358 FE_CAN_QPSK |
359 FE_CAN_FEC_AUTO
360 },
361 .release = vp702x_fe_release,
362
363 .init = vp702x_fe_init,
364 .sleep = vp702x_fe_sleep,
365
366 .set_frontend = vp702x_fe_set_frontend,
367 .get_tune_settings = vp702x_fe_get_tune_settings,
368
369 .read_status = vp702x_fe_read_status,
370 .read_ber = vp702x_fe_read_ber,
371 .read_signal_strength = vp702x_fe_read_signal_strength,
372 .read_snr = vp702x_fe_read_snr,
373 .read_ucblocks = vp702x_fe_read_unc_blocks,
374
375 .diseqc_send_master_cmd = vp702x_fe_send_diseqc_msg,
376 .diseqc_send_burst = vp702x_fe_send_diseqc_burst,
377 .set_tone = vp702x_fe_set_tone,
378 .set_voltage = vp702x_fe_set_voltage,
379};
diff --git a/drivers/media/usb/dvb-usb/vp702x.c b/drivers/media/usb/dvb-usb/vp702x.c
new file mode 100644
index 000000000000..07c673a6e764
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/vp702x.c
@@ -0,0 +1,444 @@
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_adap[0].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 .num_frontends = 1,
387 .fe = {{
388 .caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS,
389
390 .streaming_ctrl = vp702x_streaming_ctrl,
391 .frontend_attach = vp702x_frontend_attach,
392
393 /* parameter for the MPEG2-data transfer */
394 .stream = {
395 .type = USB_BULK,
396 .count = 10,
397 .endpoint = 0x02,
398 .u = {
399 .bulk = {
400 .buffersize = 4096,
401 }
402 }
403 },
404 }},
405 .size_of_priv = sizeof(struct vp702x_adapter_state),
406 }
407 },
408 .read_mac_address = vp702x_read_mac_addr,
409
410 .rc.legacy = {
411 .rc_map_table = rc_map_vp702x_table,
412 .rc_map_size = ARRAY_SIZE(rc_map_vp702x_table),
413 .rc_interval = 400,
414 .rc_query = vp702x_rc_query,
415 },
416
417 .num_device_descs = 1,
418 .devices = {
419 { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7021)",
420 .cold_ids = { &vp702x_usb_table[0], NULL },
421 .warm_ids = { NULL },
422 },
423/* { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7020)",
424 .cold_ids = { &vp702x_usb_table[2], NULL },
425 .warm_ids = { &vp702x_usb_table[3], NULL },
426 },
427*/ { NULL },
428 }
429};
430
431/* usb specific object needed to register this driver with the usb subsystem */
432static struct usb_driver vp702x_usb_driver = {
433 .name = "dvb_usb_vp702x",
434 .probe = vp702x_usb_probe,
435 .disconnect = vp702x_usb_disconnect,
436 .id_table = vp702x_usb_table,
437};
438
439module_usb_driver(vp702x_usb_driver);
440
441MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
442MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones");
443MODULE_VERSION("1.0");
444MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/vp702x.h b/drivers/media/usb/dvb-usb/vp702x.h
new file mode 100644
index 000000000000..20b90055e7ac
--- /dev/null
+++ b/drivers/media/usb/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/usb/dvb-usb/vp7045-fe.c b/drivers/media/usb/dvb-usb/vp7045-fe.c
new file mode 100644
index 000000000000..b8825b18c003
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/vp7045-fe.c
@@ -0,0 +1,190 @@
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{
108 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
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->bandwidth_hz) {
119 case 8000000:
120 buf[4] = 8;
121 break;
122 case 7000000:
123 buf[4] = 7;
124 break;
125 case 6000000:
126 buf[4] = 6;
127 break;
128 default:
129 return -EINVAL;
130 }
131
132 vp7045_usb_op(state->d,LOCK_TUNER_COMMAND,buf,5,NULL,0,200);
133 return 0;
134}
135
136static void vp7045_fe_release(struct dvb_frontend* fe)
137{
138 struct vp7045_fe_state *state = fe->demodulator_priv;
139 kfree(state);
140}
141
142static struct dvb_frontend_ops vp7045_fe_ops;
143
144struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
145{
146 struct vp7045_fe_state *s = kzalloc(sizeof(struct vp7045_fe_state), GFP_KERNEL);
147 if (s == NULL)
148 goto error;
149
150 s->d = d;
151 memcpy(&s->fe.ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops));
152 s->fe.demodulator_priv = s;
153
154 return &s->fe;
155error:
156 return NULL;
157}
158
159
160static struct dvb_frontend_ops vp7045_fe_ops = {
161 .delsys = { SYS_DVBT },
162 .info = {
163 .name = "Twinhan VP7045/46 USB DVB-T",
164 .frequency_min = 44250000,
165 .frequency_max = 867250000,
166 .frequency_stepsize = 1000,
167 .caps = FE_CAN_INVERSION_AUTO |
168 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
169 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
170 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
171 FE_CAN_TRANSMISSION_MODE_AUTO |
172 FE_CAN_GUARD_INTERVAL_AUTO |
173 FE_CAN_RECOVER |
174 FE_CAN_HIERARCHY_AUTO,
175 },
176
177 .release = vp7045_fe_release,
178
179 .init = vp7045_fe_init,
180 .sleep = vp7045_fe_sleep,
181
182 .set_frontend = vp7045_fe_set_frontend,
183 .get_tune_settings = vp7045_fe_get_tune_settings,
184
185 .read_status = vp7045_fe_read_status,
186 .read_ber = vp7045_fe_read_ber,
187 .read_signal_strength = vp7045_fe_read_signal_strength,
188 .read_snr = vp7045_fe_read_snr,
189 .read_ucblocks = vp7045_fe_read_unc_blocks,
190};
diff --git a/drivers/media/usb/dvb-usb/vp7045.c b/drivers/media/usb/dvb-usb/vp7045.c
new file mode 100644
index 000000000000..d750724132ee
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/vp7045.c
@@ -0,0 +1,302 @@
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_adap[0].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 .num_frontends = 1,
249 .fe = {{
250 .frontend_attach = vp7045_frontend_attach,
251 /* parameter for the MPEG2-data transfer */
252 .stream = {
253 .type = USB_BULK,
254 .count = 7,
255 .endpoint = 0x02,
256 .u = {
257 .bulk = {
258 .buffersize = 4096,
259 }
260 }
261 },
262 }},
263 }
264 },
265 .power_ctrl = vp7045_power_ctrl,
266 .read_mac_address = vp7045_read_mac_addr,
267
268 .rc.legacy = {
269 .rc_interval = 400,
270 .rc_map_table = rc_map_vp7045_table,
271 .rc_map_size = ARRAY_SIZE(rc_map_vp7045_table),
272 .rc_query = vp7045_rc_query,
273 },
274
275 .num_device_descs = 2,
276 .devices = {
277 { .name = "Twinhan USB2.0 DVB-T receiver (TwinhanDTV Alpha/MagicBox II)",
278 .cold_ids = { &vp7045_usb_table[0], NULL },
279 .warm_ids = { &vp7045_usb_table[1], NULL },
280 },
281 { .name = "DigitalNow TinyUSB 2 DVB-t Receiver",
282 .cold_ids = { &vp7045_usb_table[2], NULL },
283 .warm_ids = { &vp7045_usb_table[3], NULL },
284 },
285 { NULL },
286 }
287};
288
289/* usb specific object needed to register this driver with the usb subsystem */
290static struct usb_driver vp7045_usb_driver = {
291 .name = "dvb_usb_vp7045",
292 .probe = vp7045_usb_probe,
293 .disconnect = dvb_usb_device_exit,
294 .id_table = vp7045_usb_table,
295};
296
297module_usb_driver(vp7045_usb_driver);
298
299MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
300MODULE_DESCRIPTION("Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0");
301MODULE_VERSION("1.0");
302MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/vp7045.h b/drivers/media/usb/dvb-usb/vp7045.h
new file mode 100644
index 000000000000..cf5ec46f8bb1
--- /dev/null
+++ b/drivers/media/usb/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