diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-06-14 15:35:56 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-13 22:26:31 -0400 |
commit | 786baecfe78f8e25547c628b48a60fc8e5636056 (patch) | |
tree | bb4101ce010f55cbbfc6d93ee13b44b496a028cc /drivers/media/usb/dvb-usb | |
parent | 616300bd51bee80d2d122c205866aa4c20adbaa8 (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')
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 @@ | |||
1 | config 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 | |||
16 | config 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 | |||
23 | config 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 | |||
32 | config 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 | |||
48 | config 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 | |||
54 | config 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 | |||
69 | config 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 | |||
98 | config 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 | |||
108 | config 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 | |||
132 | config 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 | |||
146 | config 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 | |||
155 | config 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 | |||
169 | config 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 | |||
181 | config 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 | |||
190 | config 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 | |||
199 | config 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 | |||
210 | config 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 | |||
220 | config 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 | |||
228 | config 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 | |||
237 | config 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 | |||
244 | config 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 | |||
257 | config 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 | |||
277 | config 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 | |||
285 | config 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 | |||
293 | config 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 | |||
299 | config 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 | |||
307 | config 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 @@ | |||
1 | dvb-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 | ||
2 | obj-$(CONFIG_DVB_USB) += dvb-usb.o | ||
3 | |||
4 | dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o | ||
5 | obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o | ||
6 | |||
7 | dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o | ||
8 | obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o | ||
9 | |||
10 | dvb-usb-gp8psk-objs = gp8psk.o gp8psk-fe.o | ||
11 | obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o | ||
12 | |||
13 | dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o | ||
14 | obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o | ||
15 | |||
16 | dvb-usb-dibusb-common-objs = dibusb-common.o | ||
17 | |||
18 | dvb-usb-a800-objs = a800.o | ||
19 | obj-$(CONFIG_DVB_USB_A800) += dvb-usb-dibusb-common.o dvb-usb-a800.o | ||
20 | |||
21 | dvb-usb-dibusb-mb-objs = dibusb-mb.o | ||
22 | obj-$(CONFIG_DVB_USB_DIBUSB_MB) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mb.o | ||
23 | |||
24 | dvb-usb-dibusb-mc-objs = dibusb-mc.o | ||
25 | obj-$(CONFIG_DVB_USB_DIBUSB_MC) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mc.o | ||
26 | |||
27 | dvb-usb-nova-t-usb2-objs = nova-t-usb2.o | ||
28 | obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2.o | ||
29 | |||
30 | dvb-usb-umt-010-objs = umt-010.o | ||
31 | obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o | ||
32 | |||
33 | dvb-usb-m920x-objs = m920x.o | ||
34 | obj-$(CONFIG_DVB_USB_M920X) += dvb-usb-m920x.o | ||
35 | |||
36 | dvb-usb-digitv-objs = digitv.o | ||
37 | obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o | ||
38 | |||
39 | dvb-usb-cxusb-objs = cxusb.o | ||
40 | obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o | ||
41 | |||
42 | dvb-usb-ttusb2-objs = ttusb2.o | ||
43 | obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o | ||
44 | |||
45 | dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o | ||
46 | obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o | ||
47 | |||
48 | dvb-usb-opera-objs = opera1.o | ||
49 | obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o | ||
50 | |||
51 | dvb-usb-af9005-objs = af9005.o af9005-fe.o | ||
52 | obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o | ||
53 | |||
54 | dvb-usb-af9005-remote-objs = af9005-remote.o | ||
55 | obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o | ||
56 | |||
57 | dvb-usb-pctv452e-objs = pctv452e.o | ||
58 | obj-$(CONFIG_DVB_USB_PCTV452E) += dvb-usb-pctv452e.o | ||
59 | |||
60 | dvb-usb-dw2102-objs = dw2102.o | ||
61 | obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o | ||
62 | |||
63 | dvb-usb-dtv5100-objs = dtv5100.o | ||
64 | obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o | ||
65 | |||
66 | dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o | ||
67 | obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o | ||
68 | |||
69 | dvb-usb-friio-objs = friio.o friio-fe.o | ||
70 | obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o | ||
71 | |||
72 | dvb-usb-az6027-objs = az6027.o | ||
73 | obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o | ||
74 | |||
75 | dvb-usb-technisat-usb2-objs = technisat-usb2.o | ||
76 | obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o | ||
77 | |||
78 | ccflags-y += -I$(srctree)/drivers/media/dvb-core | ||
79 | ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/ | ||
80 | # due to tuner-xc3028 | ||
81 | ccflags-y += -I$(srctree)/drivers/media/common/tuners | ||
82 | ccflags-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 | |||
18 | static int debug; | ||
19 | module_param(debug, int, 0644); | ||
20 | MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS); | ||
21 | |||
22 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
23 | |||
24 | #define deb_rc(args...) dprintk(debug,0x01,args) | ||
25 | |||
26 | static 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 */ | ||
33 | static 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 | |||
40 | static 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 | |||
79 | static 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; | ||
98 | out: | ||
99 | kfree(key); | ||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | /* USB Driver stuff */ | ||
104 | static struct dvb_usb_device_properties a800_properties; | ||
105 | |||
106 | static 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 */ | ||
114 | static 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 | }; | ||
119 | MODULE_DEVICE_TABLE (usb, a800_table); | ||
120 | |||
121 | static 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 | |||
179 | static 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 | |||
186 | module_usb_driver(a800_driver); | ||
187 | |||
188 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); | ||
189 | MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)"); | ||
190 | MODULE_VERSION("1.0"); | ||
191 | MODULE_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 | |||
30 | struct 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 | |||
62 | static 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 | |||
73 | static 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 | |||
104 | static 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 | |||
132 | static 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 | |||
216 | static 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 | |||
236 | static 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 | |||
333 | static 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 | |||
357 | static 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 | |||
382 | static 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 | |||
426 | static 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 | |||
440 | static 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 | |||
489 | static 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 | |||
499 | static 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 | |||
509 | static 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 | |||
534 | static 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 | |||
542 | static 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 | |||
776 | static 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 | |||
797 | static 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 | |||
807 | static struct mt2060_config af9005_mt2060_config = { | ||
808 | 0xC0 | ||
809 | }; | ||
810 | |||
811 | static struct qt1010_config af9005_qt1010_config = { | ||
812 | 0xC4 | ||
813 | }; | ||
814 | |||
815 | static 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 | |||
1083 | static int af9005_fe_sleep(struct dvb_frontend *fe) | ||
1084 | { | ||
1085 | return af9005_fe_power(fe, 0); | ||
1086 | } | ||
1087 | |||
1088 | static 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 | |||
1103 | static 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 | |||
1229 | static 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 | |||
1425 | static 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 | |||
1432 | static struct dvb_frontend_ops af9005_fe_ops; | ||
1433 | |||
1434 | struct 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 | |||
1457 | static 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 */ | ||
28 | static int dvb_usb_af9005_remote_debug; | ||
29 | module_param_named(debug, dvb_usb_af9005_remote_debug, int, 0644); | ||
30 | MODULE_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 | |||
36 | struct 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 | |||
77 | int rc_map_af9005_table_size = ARRAY_SIZE(rc_map_af9005_table); | ||
78 | |||
79 | static int repeatable_keys[] = { | ||
80 | KEY_VOLUMEUP, | ||
81 | KEY_VOLUMEDOWN, | ||
82 | KEY_CHANNELUP, | ||
83 | KEY_CHANNELDOWN | ||
84 | }; | ||
85 | |||
86 | int 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 | |||
149 | EXPORT_SYMBOL(rc_map_af9005_table); | ||
150 | EXPORT_SYMBOL(rc_map_af9005_table_size); | ||
151 | EXPORT_SYMBOL(af9005_rc_decode); | ||
152 | |||
153 | MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>"); | ||
154 | MODULE_DESCRIPTION | ||
155 | ("Standard remote control decoder for Afatech 9005 DVB-T USB1.1 stick"); | ||
156 | MODULE_VERSION("1.0"); | ||
157 | MODULE_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 | /* | ||
2 | File automatically generated by createinit.py using data | ||
3 | extracted from AF05BDA.sys (windows driver): | ||
4 | |||
5 | dd if=AF05BDA.sys of=initsequence bs=1 skip=88316 count=1110 | ||
6 | python createinit.py > af9005-script.h | ||
7 | |||
8 | */ | ||
9 | |||
10 | typedef struct { | ||
11 | u16 reg; | ||
12 | u8 pos; | ||
13 | u8 len; | ||
14 | u8 val; | ||
15 | } RegDesc; | ||
16 | |||
17 | static 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 */ | ||
27 | int dvb_usb_af9005_debug; | ||
28 | module_param_named(debug, dvb_usb_af9005_debug, int, 0644); | ||
29 | MODULE_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 */ | ||
33 | bool dvb_usb_af9005_led = 1; | ||
34 | module_param_named(led, dvb_usb_af9005_led, bool, 0644); | ||
35 | MODULE_PARM_DESC(led, "enable led (default: 1)."); | ||
36 | |||
37 | /* eeprom dump */ | ||
38 | static int dvb_usb_af9005_dump_eeprom; | ||
39 | module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0); | ||
40 | MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom."); | ||
41 | |||
42 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
43 | |||
44 | /* remote control decoder */ | ||
45 | static int (*rc_decode) (struct dvb_usb_device *d, u8 *data, int len, | ||
46 | u32 *event, int *state); | ||
47 | static void *rc_keys; | ||
48 | static int *rc_keys_size; | ||
49 | |||
50 | u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; | ||
51 | |||
52 | struct af9005_device_state { | ||
53 | u8 sequence; | ||
54 | int led_state; | ||
55 | }; | ||
56 | |||
57 | static 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 | |||
147 | int 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 | |||
161 | int 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 | |||
176 | int 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 | |||
191 | int 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 | |||
208 | int 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 | |||
225 | int 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 | |||
242 | static 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 | |||
250 | static 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 | |||
258 | int 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 | |||
311 | int 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 | |||
364 | static 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 | |||
390 | static 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 | |||
413 | static 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 | |||
451 | static u32 af9005_i2c_func(struct i2c_adapter *adapter) | ||
452 | { | ||
453 | return I2C_FUNC_I2C; | ||
454 | } | ||
455 | |||
456 | static struct i2c_algorithm af9005_i2c_algo = { | ||
457 | .master_xfer = af9005_i2c_xfer, | ||
458 | .functionality = af9005_i2c_func, | ||
459 | }; | ||
460 | |||
461 | int 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 | |||
517 | int 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 | |||
565 | static 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 | |||
719 | static 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 | |||
771 | int 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 | |||
798 | static 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 | |||
822 | static 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 | |||
875 | static int af9005_power_ctrl(struct dvb_usb_device *d, int onoff) | ||
876 | { | ||
877 | |||
878 | return 0; | ||
879 | } | ||
880 | |||
881 | static 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 | |||
906 | static 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 | |||
950 | static 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 | |||
971 | static struct dvb_usb_device_properties af9005_properties; | ||
972 | |||
973 | static 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 | |||
980 | enum af9005_usb_table_entry { | ||
981 | AFATECH_AF9005, | ||
982 | TERRATEC_AF9005, | ||
983 | ANSONIC_AF9005, | ||
984 | }; | ||
985 | |||
986 | static 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 | |||
996 | MODULE_DEVICE_TABLE(usb, af9005_usb_table); | ||
997 | |||
998 | static 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 */ | ||
1069 | static 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 */ | ||
1077 | static 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 | |||
1098 | static 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 | |||
1111 | module_init(af9005_usb_module_init); | ||
1112 | module_exit(af9005_usb_module_exit); | ||
1113 | |||
1114 | MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>"); | ||
1115 | MODULE_DESCRIPTION("Driver for Afatech 9005 DVB-T USB1.1 stick"); | ||
1116 | MODULE_VERSION("1.0"); | ||
1117 | MODULE_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 | |||
30 | extern 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 | |||
38 | extern bool dvb_usb_af9005_led; | ||
39 | |||
40 | /* firmware */ | ||
41 | #define FW_BULKOUT_SIZE 250 | ||
42 | enum { | ||
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 | |||
3464 | extern struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d); | ||
3465 | extern int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg, | ||
3466 | u8 * value); | ||
3467 | extern int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg, | ||
3468 | u8 * values, int len); | ||
3469 | extern int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg, | ||
3470 | u8 value); | ||
3471 | extern int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg, | ||
3472 | u8 * values, int len); | ||
3473 | extern int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg, | ||
3474 | u8 addr, u8 * values, int len); | ||
3475 | extern int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg, | ||
3476 | u8 * values, int len); | ||
3477 | extern int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg, | ||
3478 | u8 pos, u8 len, u8 * value); | ||
3479 | extern int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg, | ||
3480 | u8 pos, u8 len, u8 value); | ||
3481 | extern int af9005_send_command(struct dvb_usb_device *d, u8 command, | ||
3482 | u8 * wbuf, int wlen, u8 * rbuf, int rlen); | ||
3483 | extern int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, | ||
3484 | u8 * values, int len); | ||
3485 | extern int af9005_tuner_attach(struct dvb_usb_adapter *adap); | ||
3486 | extern int af9005_led_control(struct dvb_usb_device *d, int onoff); | ||
3487 | |||
3488 | extern u8 regmask[8]; | ||
3489 | |||
3490 | /* remote control decoder */ | ||
3491 | extern int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, | ||
3492 | u32 * event, int *state); | ||
3493 | extern struct rc_map_table rc_map_af9005_table[]; | ||
3494 | extern 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 | |||
22 | int dvb_usb_az6027_debug; | ||
23 | module_param_named(debug, dvb_usb_az6027_debug, int, 0644); | ||
24 | MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); | ||
25 | |||
26 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
27 | |||
28 | struct az6027_device_state { | ||
29 | struct dvb_ca_en50221 ca; | ||
30 | struct mutex ca_mutex; | ||
31 | u8 power_state; | ||
32 | }; | ||
33 | |||
34 | static 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 | |||
122 | static 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 | |||
257 | struct 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 | |||
294 | struct stb6100_config az6027_stb6100_config = { | ||
295 | .tuner_address = 0xc0, | ||
296 | .refclock = 27000000, | ||
297 | }; | ||
298 | |||
299 | |||
300 | /* check for mutex FIXME */ | ||
301 | int 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 | |||
330 | static 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 | |||
365 | static 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 */ | ||
388 | static 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) */ | ||
394 | static int az6027_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | ||
395 | { | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | /* | ||
400 | int 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 | |||
407 | static 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 | |||
448 | static 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 | |||
480 | static 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 | |||
525 | static 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 | |||
554 | failed: | ||
555 | mutex_unlock(&state->ca_mutex); | ||
556 | return ret; | ||
557 | } | ||
558 | |||
559 | static 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 | |||
590 | static 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 | |||
636 | failed: | ||
637 | mutex_unlock(&state->ca_mutex); | ||
638 | return ret; | ||
639 | } | ||
640 | |||
641 | static int az6027_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) | ||
642 | { | ||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | static 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 | |||
670 | failed: | ||
671 | mutex_unlock(&state->ca_mutex); | ||
672 | return ret; | ||
673 | } | ||
674 | |||
675 | static 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 | |||
714 | static 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 | |||
736 | static 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 | /* | ||
773 | static 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 | |||
780 | static 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 | |||
821 | static 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 | } | ||
840 | static 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 | |||
883 | static 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 | |||
904 | static 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 | |||
930 | static struct dvb_usb_device_properties az6027_properties; | ||
931 | |||
932 | static 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 | |||
940 | static 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 */ | ||
951 | static 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 | |||
1044 | static u32 az6027_i2c_func(struct i2c_adapter *adapter) | ||
1045 | { | ||
1046 | return I2C_FUNC_I2C; | ||
1047 | } | ||
1048 | |||
1049 | static struct i2c_algorithm az6027_i2c_algo = { | ||
1050 | .master_xfer = az6027_i2c_xfer, | ||
1051 | .functionality = az6027_i2c_func, | ||
1052 | }; | ||
1053 | |||
1054 | int 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 | |||
1083 | static 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 | |||
1093 | MODULE_DEVICE_TABLE(usb, az6027_usb_table); | ||
1094 | |||
1095 | static 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 */ | ||
1170 | static struct usb_driver az6027_usb_driver = { | ||
1171 | .name = "dvb_usb_az6027", | ||
1172 | .probe = az6027_usb_probe, | ||
1173 | .disconnect = az6027_usb_disconnect, | ||
1174 | .id_table = az6027_usb_table, | ||
1175 | }; | ||
1176 | |||
1177 | module_usb_driver(az6027_usb_driver); | ||
1178 | |||
1179 | MODULE_AUTHOR("Adams Xu <Adams.xu@azwave.com.cn>"); | ||
1180 | MODULE_DESCRIPTION("Driver for AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)"); | ||
1181 | MODULE_VERSION("1.0"); | ||
1182 | MODULE_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 | |||
8 | extern 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 */ | ||
34 | int dvb_usb_cinergyt2_debug; | ||
35 | |||
36 | module_param_named(debug, dvb_usb_cinergyt2_debug, int, 0644); | ||
37 | MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 " | ||
38 | "(or-able))."); | ||
39 | |||
40 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
41 | |||
42 | struct cinergyt2_state { | ||
43 | u8 rc_counter; | ||
44 | }; | ||
45 | |||
46 | /* We are missing a release hook with usb_device data */ | ||
47 | static struct dvb_usb_device *cinergyt2_usb_device; | ||
48 | |||
49 | static struct dvb_usb_device_properties cinergyt2_properties; | ||
50 | |||
51 | static 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 | |||
59 | static 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 | |||
66 | static 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 | |||
87 | static 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 | |||
130 | static 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 | |||
141 | static 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 | |||
181 | static 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 | |||
189 | static struct usb_device_id cinergyt2_usb_table[] = { | ||
190 | { USB_DEVICE(USB_VID_TERRATEC, 0x0038) }, | ||
191 | { 0 } | ||
192 | }; | ||
193 | |||
194 | MODULE_DEVICE_TABLE(usb, cinergyt2_usb_table); | ||
195 | |||
196 | static 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 | |||
243 | static 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 | |||
250 | module_usb_driver(cinergyt2_driver); | ||
251 | |||
252 | MODULE_DESCRIPTION("Terratec Cinergy T2 DVB-T driver"); | ||
253 | MODULE_LICENSE("GPL"); | ||
254 | MODULE_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 | |||
43 | static 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 | |||
139 | struct cinergyt2_fe_state { | ||
140 | struct dvb_frontend fe; | ||
141 | struct dvb_usb_device *d; | ||
142 | }; | ||
143 | |||
144 | static 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 | |||
177 | static 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 | |||
193 | static 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 | |||
211 | static 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 | |||
230 | static 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 | |||
247 | static int cinergyt2_fe_init(struct dvb_frontend *fe) | ||
248 | { | ||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static int cinergyt2_fe_sleep(struct dvb_frontend *fe) | ||
253 | { | ||
254 | deb_info("cinergyt2_fe_sleep() Called\n"); | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static 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 | |||
265 | static 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 *)¶m, 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 | |||
300 | static 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 | |||
307 | static struct dvb_frontend_ops cinergyt2_fe_ops; | ||
308 | |||
309 | struct 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 | |||
323 | static 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 | |||
40 | extern 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 | |||
54 | enum 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 | |||
68 | struct 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 | |||
83 | struct 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 | |||
92 | extern 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 */ | ||
47 | static int dvb_usb_cxusb_debug; | ||
48 | module_param_named(debug, dvb_usb_cxusb_debug, int, 0644); | ||
49 | MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); | ||
50 | |||
51 | DVB_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 | |||
56 | static 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 */ | ||
72 | static 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 | |||
90 | static 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 | |||
106 | static 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 | |||
113 | static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff) | ||
114 | { | ||
115 | cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40); | ||
116 | } | ||
117 | |||
118 | static 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 */ | ||
138 | static 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 | |||
211 | static u32 cxusb_i2c_func(struct i2c_adapter *adapter) | ||
212 | { | ||
213 | return I2C_FUNC_I2C; | ||
214 | } | ||
215 | |||
216 | static struct i2c_algorithm cxusb_i2c_algo = { | ||
217 | .master_xfer = cxusb_i2c_xfer, | ||
218 | .functionality = cxusb_i2c_func, | ||
219 | }; | ||
220 | |||
221 | static 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 | |||
230 | static 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 | |||
270 | static 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 | |||
279 | static 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 | |||
290 | static 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 | |||
304 | static 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 | |||
315 | static 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 | |||
325 | static 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 | |||
348 | static 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 | |||
371 | static 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 | |||
386 | static 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 | |||
410 | static 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 | |||
438 | static 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 | |||
464 | static 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 | |||
512 | static 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 | |||
551 | static 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 | |||
589 | static 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 | |||
610 | static 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 | |||
630 | static struct cx22702_config cxusb_cx22702_config = { | ||
631 | .demod_address = 0x63, | ||
632 | .output_mode = CX22702_PARALLEL_OUTPUT, | ||
633 | }; | ||
634 | |||
635 | static struct lgdt330x_config cxusb_lgdt3303_config = { | ||
636 | .demod_address = 0x0e, | ||
637 | .demod_chip = LGDT3303, | ||
638 | }; | ||
639 | |||
640 | static struct lgdt330x_config cxusb_aver_lgdt3303_config = { | ||
641 | .demod_address = 0x0e, | ||
642 | .demod_chip = LGDT3303, | ||
643 | .clock_polarity_flip = 2, | ||
644 | }; | ||
645 | |||
646 | static struct mt352_config cxusb_dee1601_config = { | ||
647 | .demod_address = 0x0f, | ||
648 | .demod_init = cxusb_dee1601_demod_init, | ||
649 | }; | ||
650 | |||
651 | static struct zl10353_config cxusb_zl10353_dee1601_config = { | ||
652 | .demod_address = 0x0f, | ||
653 | .parallel_ts = 1, | ||
654 | }; | ||
655 | |||
656 | static 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 | |||
662 | static struct zl10353_config cxusb_zl10353_xc3028_config = { | ||
663 | .demod_address = 0x0f, | ||
664 | .if2 = 45600, | ||
665 | .no_tuner = 1, | ||
666 | .parallel_ts = 1, | ||
667 | }; | ||
668 | |||
669 | static 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 | |||
677 | static 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 */ | ||
685 | static 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 */ | ||
703 | static 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 | |||
720 | static struct max2165_config mygica_d689_max2165_cfg = { | ||
721 | .i2c_address = 0x60, | ||
722 | .osc_clk = 20 | ||
723 | }; | ||
724 | |||
725 | /* Callbacks for DVB USB */ | ||
726 | static 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 | |||
734 | static 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 | |||
741 | static 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 | |||
747 | static 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 | |||
754 | static 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 | |||
761 | static 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 | |||
784 | static 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 | |||
809 | static 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 | |||
816 | static 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 | |||
824 | static 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 | |||
832 | static 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 | |||
848 | static 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 | |||
864 | static 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 | |||
874 | static 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 | |||
890 | static 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 | |||
911 | static 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) { | ||
943 | no_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 | |||
953 | static 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 | |||
991 | static 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 | |||
1011 | static 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 | |||
1029 | static 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 | |||
1052 | static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) | ||
1053 | { | ||
1054 | return dib7000p_set_gpio(fe, 8, 0, !onoff); | ||
1055 | } | ||
1056 | |||
1057 | static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff) | ||
1058 | { | ||
1059 | return 0; | ||
1060 | } | ||
1061 | |||
1062 | static 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 | |||
1069 | struct dib0700_adapter_state { | ||
1070 | int (*set_param_save) (struct dvb_frontend *); | ||
1071 | }; | ||
1072 | |||
1073 | static 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 | |||
1092 | static 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 | |||
1108 | static 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 | |||
1135 | static 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 | |||
1149 | static 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 | |||
1193 | static 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 | |||
1207 | static 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 | */ | ||
1251 | static 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 | |||
1273 | static const int dvico_firmware_id_offsets[] = { 6638, 3204 }; | ||
1274 | static 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 */ | ||
1314 | static struct dvb_usb_device_properties cxusb_medion_properties; | ||
1315 | static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties; | ||
1316 | static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties; | ||
1317 | static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties; | ||
1318 | static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties; | ||
1319 | static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties; | ||
1320 | static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties; | ||
1321 | static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; | ||
1322 | static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; | ||
1323 | static struct dvb_usb_device_properties cxusb_aver_a868r_properties; | ||
1324 | static struct dvb_usb_device_properties cxusb_d680_dmb_properties; | ||
1325 | static struct dvb_usb_device_properties cxusb_mygica_d689_properties; | ||
1326 | |||
1327 | static 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 | |||
1362 | static 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 | }; | ||
1385 | MODULE_DEVICE_TABLE (usb, cxusb_table); | ||
1386 | |||
1387 | static 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 | |||
1431 | static 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 | |||
1488 | static 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 | |||
1552 | static 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 | |||
1607 | static 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 | |||
1663 | static 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 | |||
1715 | static 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 | |||
1768 | static 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 | |||
1823 | static 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 | |||
1867 | static | ||
1868 | struct 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 | |||
1921 | static 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 | |||
1975 | static 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 | |||
2029 | static 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 | |||
2036 | module_usb_driver(cxusb_driver); | ||
2037 | |||
2038 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); | ||
2039 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); | ||
2040 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); | ||
2041 | MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design"); | ||
2042 | MODULE_VERSION("1.0-alpha"); | ||
2043 | MODULE_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 | |||
31 | struct 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 | |||
17 | extern 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 | |||
41 | struct 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 | |||
56 | extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, | ||
57 | u32 *romversion, u32 *ramversion, u32 *fwtype); | ||
58 | extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val); | ||
59 | extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3); | ||
60 | extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen); | ||
61 | extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw); | ||
62 | extern int dib0700_rc_setup(struct dvb_usb_device *d); | ||
63 | extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); | ||
64 | extern struct i2c_algorithm dib0700_i2c_algo; | ||
65 | extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, | ||
66 | struct dvb_usb_device_description **desc, int *cold); | ||
67 | extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type); | ||
68 | extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz); | ||
69 | |||
70 | extern int dib0700_device_count; | ||
71 | extern int dvb_usb_dib0700_ir_proto; | ||
72 | extern struct dvb_usb_device_properties dib0700_devices[]; | ||
73 | extern 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 */ | ||
12 | int dvb_usb_dib0700_debug; | ||
13 | module_param_named(debug,dvb_usb_dib0700_debug, int, 0644); | ||
14 | MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS); | ||
15 | |||
16 | static int nb_packet_buffer_size = 21; | ||
17 | module_param(nb_packet_buffer_size, int, 0644); | ||
18 | MODULE_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 | |||
24 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
25 | |||
26 | |||
27 | int 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] */ | ||
59 | static 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) */ | ||
77 | int 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 | |||
114 | int 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 | |||
134 | static 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 | */ | ||
164 | static 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 | */ | ||
267 | static 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 | |||
317 | static 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 | |||
332 | static u32 dib0700_i2c_func(struct i2c_adapter *adapter) | ||
333 | { | ||
334 | return I2C_FUNC_I2C; | ||
335 | } | ||
336 | |||
337 | struct i2c_algorithm dib0700_i2c_algo = { | ||
338 | .master_xfer = dib0700_i2c_xfer, | ||
339 | .functionality = dib0700_i2c_func, | ||
340 | }; | ||
341 | |||
342 | int 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 | |||
365 | static 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 | |||
395 | int 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 | |||
432 | int 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 | |||
441 | static 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 | } | ||
467 | out: | ||
468 | kfree(buf); | ||
469 | return ret; | ||
470 | } | ||
471 | |||
472 | int 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 | } | ||
543 | out: | ||
544 | kfree(buf); | ||
545 | return ret; | ||
546 | } | ||
547 | |||
548 | int 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 | |||
608 | int 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 | |||
650 | out: | ||
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 */ | ||
659 | struct 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 | |||
674 | static 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 | |||
750 | resubmit: | ||
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 | |||
758 | int 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 | |||
797 | static 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 | |||
832 | static 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 | |||
839 | module_usb_driver(dib0700_driver); | ||
840 | |||
841 | MODULE_FIRMWARE("dvb-usb-dib0700-1.20.fw"); | ||
842 | MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); | ||
843 | MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge"); | ||
844 | MODULE_VERSION("1.0"); | ||
845 | MODULE_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 | |||
27 | static int force_lna_activation; | ||
28 | module_param(force_lna_activation, int, 0644); | ||
29 | MODULE_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 | |||
32 | struct 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 */ | ||
39 | static 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 | |||
49 | static 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 | |||
71 | static 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 | |||
84 | static 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 | |||
108 | static 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 | |||
118 | static 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 */ | ||
136 | static 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 | |||
220 | static 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 | |||
229 | static 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 | |||
256 | static struct mt2266_config stk7700d_mt2266_config[2] = { | ||
257 | { .i2c_address = 0x60 | ||
258 | }, | ||
259 | { .i2c_address = 0x60 | ||
260 | } | ||
261 | }; | ||
262 | |||
263 | static 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 | |||
291 | static 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 | |||
320 | static 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 */ | ||
329 | static 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 */ | ||
372 | static 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 | |||
383 | static 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 | |||
396 | static 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 | |||
417 | static struct xc2028_ctrl stk7700ph_xc3028_ctrl = { | ||
418 | .fname = XC2028_DEFAULT_FIRMWARE, | ||
419 | .max_len = 64, | ||
420 | .demod = XC3028_FE_DIBCOM52, | ||
421 | }; | ||
422 | |||
423 | static struct xc2028_config stk7700ph_xc3028_config = { | ||
424 | .i2c_addr = 0x61, | ||
425 | .ctrl = &stk7700ph_xc3028_ctrl, | ||
426 | }; | ||
427 | |||
428 | static 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 | |||
461 | static 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 | |||
479 | static 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 | */ | ||
489 | static 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 */ | ||
545 | static 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 | |||
591 | static 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 | |||
637 | static 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 | |||
647 | static 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 | |||
661 | static 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 | |||
673 | static 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 | |||
701 | static struct mt2060_config stk7700p_mt2060_config = { | ||
702 | 0x60 | ||
703 | }; | ||
704 | |||
705 | static 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 */ | ||
726 | static 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 | |||
768 | static 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 | |||
774 | static 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 | |||
780 | static 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 | |||
797 | static 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 | |||
807 | static 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 | |||
825 | static 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 | |||
849 | static 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 | |||
864 | static 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 | |||
882 | static 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 | |||
891 | static 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 | |||
899 | static 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 | |||
904 | static 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 | |||
909 | static 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 | |||
919 | static 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 */ | ||
936 | static 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 */ | ||
970 | static 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 | |||
988 | static 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 */ | ||
1022 | static 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 | |||
1114 | static 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 | |||
1125 | static 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 | |||
1162 | static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff) | ||
1163 | { | ||
1164 | return dib8000_set_gpio(fe, 5, 0, !onoff); | ||
1165 | } | ||
1166 | |||
1167 | static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff) | ||
1168 | { | ||
1169 | return dib8000_set_gpio(fe, 0, 0, onoff); | ||
1170 | } | ||
1171 | |||
1172 | static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = { | ||
1173 | { 240, 7}, | ||
1174 | { 0xffff, 6}, | ||
1175 | }; | ||
1176 | |||
1177 | static 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 | |||
1209 | static 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 | |||
1231 | static 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 | |||
1252 | static 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 | |||
1258 | static 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 */ | ||
1265 | static 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 */ | ||
1292 | static 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 | |||
1320 | static 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 */ | ||
1332 | static 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 | |||
1419 | static 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 | |||
1429 | static int dib8090_get_adc_power(struct dvb_frontend *fe) | ||
1430 | { | ||
1431 | return dib8000_get_adc_power(fe, 1); | ||
1432 | } | ||
1433 | |||
1434 | static 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 | |||
1476 | static 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 | |||
1485 | static 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 | |||
1507 | static 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, <gain); | ||
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 | |||
1552 | static 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 | |||
1565 | static 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 | |||
1589 | static 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 | |||
1612 | static 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 */ | ||
1646 | static 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 | |||
1738 | static 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 | |||
1748 | static 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 | |||
1767 | static 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 | |||
1775 | static 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 | |||
1810 | struct 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 | |||
1817 | struct 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 | |||
1823 | static 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 | |||
1859 | static 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 | |||
1884 | static 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 */ | ||
1901 | static 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 | |||
1906 | static 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 | |||
1911 | static int dib90x0_tuner_reset(struct dvb_frontend *fe, int onoff) | ||
1912 | { | ||
1913 | return dib9000_set_gpio(fe, 5, 0, !onoff); | ||
1914 | } | ||
1915 | |||
1916 | static int dib90x0_tuner_sleep(struct dvb_frontend *fe, int onoff) | ||
1917 | { | ||
1918 | return dib9000_set_gpio(fe, 0, 0, onoff); | ||
1919 | } | ||
1920 | |||
1921 | static 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 | |||
1974 | static 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 | |||
1996 | static 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 | |||
2028 | static 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 | |||
2046 | static 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 | |||
2083 | static 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 | |||
2125 | static 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 | |||
2149 | static 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 | |||
2203 | static 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 */ | ||
2245 | struct dib7090p_best_adc { | ||
2246 | u32 timf; | ||
2247 | u32 pll_loopdiv; | ||
2248 | u32 pll_prediv; | ||
2249 | }; | ||
2250 | |||
2251 | static 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 | |||
2324 | static 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 | |||
2352 | static 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 | |||
2360 | static 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 | |||
2395 | static 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 | |||
2403 | static 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 | |||
2412 | static 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 | |||
2494 | static 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 | |||
2504 | static 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 | |||
2532 | static 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 | |||
2590 | static 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 | |||
2618 | static 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 | |||
2652 | static 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 | |||
2688 | static 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 | |||
2716 | static 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 | |||
2753 | static 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 | |||
2821 | static 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 | |||
2844 | static 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 | |||
2859 | static 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 | |||
2894 | static 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 | |||
2915 | static 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 | |||
2930 | static 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 | |||
2945 | static 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 | |||
2971 | static 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 | |||
3002 | static 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 | |||
3019 | static 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 */ | ||
3037 | static 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 | |||
3069 | static 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 | |||
3084 | static 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 | |||
3102 | static 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 | |||
3108 | static 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 | |||
3125 | static 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 | */ | ||
3143 | static 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 */ | ||
3180 | static 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 | */ | ||
3201 | static 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 | |||
3236 | static 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 | |||
3255 | static struct xc5000_config s5h1411_xc5000_tunerconfig = { | ||
3256 | .i2c_address = 0x64, | ||
3257 | .if_khz = 5380, | ||
3258 | }; | ||
3259 | |||
3260 | static 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 | |||
3270 | static 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 | |||
3288 | static 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 | |||
3319 | static 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 */ | ||
3331 | static 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 | */ | ||
3354 | static 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 | |||
3392 | static 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 | |||
3400 | static 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 | |||
3420 | static 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 | |||
3432 | static 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 | */ | ||
3448 | static 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 | |||
3478 | static 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 */ | ||
3487 | struct 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 | }; | ||
3575 | MODULE_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 | |||
3600 | struct 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 | |||
4813 | int 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 | |||
4 | enum 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 | |||
13 | static int debug; | ||
14 | module_param(debug, int, 0644); | ||
15 | MODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS); | ||
16 | MODULE_LICENSE("GPL"); | ||
17 | |||
18 | #define deb_info(args...) dprintk(debug,0x01,args) | ||
19 | |||
20 | /* common stuff used by the different dibusb modules */ | ||
21 | int 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 | } | ||
33 | EXPORT_SYMBOL(dibusb_streaming_ctrl); | ||
34 | |||
35 | int 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 | } | ||
45 | EXPORT_SYMBOL(dibusb_pid_filter); | ||
46 | |||
47 | int 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 | } | ||
57 | EXPORT_SYMBOL(dibusb_pid_filter_ctrl); | ||
58 | |||
59 | int 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 | } | ||
70 | EXPORT_SYMBOL(dibusb_power_ctrl); | ||
71 | |||
72 | int 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 | } | ||
91 | EXPORT_SYMBOL(dibusb2_0_streaming_ctrl); | ||
92 | |||
93 | int 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 | } | ||
101 | EXPORT_SYMBOL(dibusb2_0_power_ctrl); | ||
102 | |||
103 | static 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 | */ | ||
127 | static 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 | |||
159 | static u32 dibusb_i2c_func(struct i2c_adapter *adapter) | ||
160 | { | ||
161 | return I2C_FUNC_I2C; | ||
162 | } | ||
163 | |||
164 | struct i2c_algorithm dibusb_i2c_algo = { | ||
165 | .master_xfer = dibusb_i2c_xfer, | ||
166 | .functionality = dibusb_i2c_func, | ||
167 | }; | ||
168 | EXPORT_SYMBOL(dibusb_i2c_algo); | ||
169 | |||
170 | int 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 | } | ||
175 | EXPORT_SYMBOL(dibusb_read_eeprom_byte); | ||
176 | |||
177 | /* 3000MC/P stuff */ | ||
178 | // Config Adjacent channels Perf -cal22 | ||
179 | static 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 | |||
201 | static 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 | |||
213 | static 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 | |||
238 | static 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 | |||
250 | int 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 | } | ||
277 | EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach); | ||
278 | |||
279 | static struct mt2060_config stk3000p_mt2060_config = { | ||
280 | 0x60 | ||
281 | }; | ||
282 | |||
283 | int 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 | } | ||
333 | EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); | ||
334 | #endif | ||
335 | |||
336 | /* | ||
337 | * common remote control stuff | ||
338 | */ | ||
339 | struct 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 | }; | ||
468 | EXPORT_SYMBOL(rc_map_dibusb_table); | ||
469 | |||
470 | int 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 | } | ||
479 | EXPORT_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 | |||
17 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
18 | |||
19 | static 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 | |||
27 | static 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 | |||
44 | static 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 | |||
55 | static 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. */ | ||
69 | static 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 */ | ||
105 | static struct dvb_usb_device_properties dibusb1_1_properties; | ||
106 | static struct dvb_usb_device_properties dibusb1_1_an2235_properties; | ||
107 | static struct dvb_usb_device_properties dibusb2_0b_properties; | ||
108 | static struct dvb_usb_device_properties artec_t1_usb2_properties; | ||
109 | |||
110 | static 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 */ | ||
127 | static 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 | }; | ||
177 | MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table); | ||
178 | |||
179 | static 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 | |||
270 | static 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 | |||
338 | static 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 | |||
401 | static 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 | |||
459 | static 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 | |||
466 | module_usb_driver(dibusb_driver); | ||
467 | |||
468 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); | ||
469 | MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)"); | ||
470 | MODULE_VERSION("1.0"); | ||
471 | MODULE_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 | |||
17 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
18 | |||
19 | /* USB Driver stuff */ | ||
20 | static struct dvb_usb_device_properties dibusb_mc_properties; | ||
21 | |||
22 | static 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 */ | ||
30 | static 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 | }; | ||
49 | MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table); | ||
50 | |||
51 | static 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 | |||
137 | static 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 | |||
144 | module_usb_driver(dibusb_mc_driver); | ||
145 | |||
146 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); | ||
147 | MODULE_DESCRIPTION("Driver for DiBcom USB2.0 DVB-T (DiB3000M-C/P based) devices"); | ||
148 | MODULE_VERSION("1.0"); | ||
149 | MODULE_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 | |||
99 | struct dibusb_state { | ||
100 | struct dib_fe_xfer_ops ops; | ||
101 | int mt2060_present; | ||
102 | u8 tuner_addr; | ||
103 | }; | ||
104 | |||
105 | struct dibusb_device_state { | ||
106 | /* for RC5 remote control */ | ||
107 | int old_toggle; | ||
108 | int last_repeat_count; | ||
109 | }; | ||
110 | |||
111 | extern struct i2c_algorithm dibusb_i2c_algo; | ||
112 | |||
113 | extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *); | ||
114 | extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_adapter *); | ||
115 | |||
116 | extern int dibusb_streaming_ctrl(struct dvb_usb_adapter *, int); | ||
117 | extern int dibusb_pid_filter(struct dvb_usb_adapter *, int, u16, int); | ||
118 | extern int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *, int); | ||
119 | extern int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *, int); | ||
120 | |||
121 | extern int dibusb_power_ctrl(struct dvb_usb_device *, int); | ||
122 | extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int); | ||
123 | |||
124 | #define DEFAULT_RC_INTERVAL 150 | ||
125 | //#define DEFAULT_RC_INTERVAL 100000 | ||
126 | |||
127 | extern struct rc_map_table rc_map_dibusb_table[]; | ||
128 | extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *); | ||
129 | extern 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 */ | ||
20 | static int dvb_usb_digitv_debug; | ||
21 | module_param_named(debug,dvb_usb_digitv_debug, int, 0644); | ||
22 | MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); | ||
23 | |||
24 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
25 | |||
26 | #define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args) | ||
27 | |||
28 | static 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 */ | ||
50 | static 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 | |||
78 | static u32 digitv_i2c_func(struct i2c_adapter *adapter) | ||
79 | { | ||
80 | return I2C_FUNC_I2C; | ||
81 | } | ||
82 | |||
83 | static struct i2c_algorithm digitv_i2c_algo = { | ||
84 | .master_xfer = digitv_i2c_xfer, | ||
85 | .functionality = digitv_i2c_func, | ||
86 | }; | ||
87 | |||
88 | /* Callbacks for DVB USB */ | ||
89 | static 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 | |||
97 | static 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 | |||
117 | static struct mt352_config digitv_mt352_config = { | ||
118 | .demod_init = digitv_mt352_demod_init, | ||
119 | }; | ||
120 | |||
121 | static 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 | |||
132 | static struct nxt6000_config digitv_nxt6000_config = { | ||
133 | .clock_inversion = 1, | ||
134 | }; | ||
135 | |||
136 | static 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 | |||
156 | static 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 | |||
169 | static 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 | |||
227 | static 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 */ | ||
261 | static struct dvb_usb_device_properties digitv_properties; | ||
262 | |||
263 | static 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 | |||
283 | static struct usb_device_id digitv_table [] = { | ||
284 | { USB_DEVICE(USB_VID_ANCHOR, USB_PID_NEBULA_DIGITV) }, | ||
285 | { } /* Terminating entry */ | ||
286 | }; | ||
287 | MODULE_DEVICE_TABLE (usb, digitv_table); | ||
288 | |||
289 | static 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 | |||
342 | static 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 | |||
349 | module_usb_driver(digitv_driver); | ||
350 | |||
351 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); | ||
352 | MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0"); | ||
353 | MODULE_VERSION("1.0-alpha"); | ||
354 | MODULE_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 | |||
7 | struct 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 | |||
14 | struct 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 | |||
23 | static 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 | |||
46 | static 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 | |||
55 | static 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 | |||
65 | static 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 | |||
74 | static 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 | |||
83 | static 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 | |||
90 | static int dtt200u_fe_sleep(struct dvb_frontend* fe) | ||
91 | { | ||
92 | return dtt200u_fe_init(fe); | ||
93 | } | ||
94 | |||
95 | static 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 | |||
103 | static 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 | |||
142 | static 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 | |||
150 | static 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 | |||
156 | static struct dvb_frontend_ops dtt200u_fe_ops; | ||
157 | |||
158 | struct 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; | ||
175 | error: | ||
176 | return NULL; | ||
177 | } | ||
178 | |||
179 | static 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 */ | ||
17 | int dvb_usb_dtt200u_debug; | ||
18 | module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644); | ||
19 | MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS); | ||
20 | |||
21 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
22 | |||
23 | static 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 | |||
33 | static 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 | |||
45 | static 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) */ | ||
60 | static 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 | |||
81 | static 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 | |||
91 | static 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 | |||
97 | static struct dvb_usb_device_properties dtt200u_properties; | ||
98 | static struct dvb_usb_device_properties wt220u_fc_properties; | ||
99 | static struct dvb_usb_device_properties wt220u_properties; | ||
100 | static struct dvb_usb_device_properties wt220u_zl0353_properties; | ||
101 | static struct dvb_usb_device_properties wt220u_miglia_properties; | ||
102 | |||
103 | static 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 | |||
121 | static 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 | }; | ||
134 | MODULE_DEVICE_TABLE(usb, dtt200u_usb_table); | ||
135 | |||
136 | static 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 | |||
186 | static 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 | |||
236 | static 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 | |||
286 | static 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 | |||
336 | static 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 */ | ||
356 | static 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 | |||
363 | module_usb_driver(dtt200u_usb_driver); | ||
364 | |||
365 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); | ||
366 | MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D/Miglia DVB-T USB2.0 devices"); | ||
367 | MODULE_VERSION("1.0"); | ||
368 | MODULE_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 | |||
19 | extern 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 | |||
55 | extern 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 */ | ||
29 | static int dvb_usb_dtv5100_debug; | ||
30 | module_param_named(debug, dvb_usb_dtv5100_debug, int, 0644); | ||
31 | MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); | ||
32 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
33 | |||
34 | static 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 */ | ||
70 | static 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 | |||
99 | static u32 dtv5100_i2c_func(struct i2c_adapter *adapter) | ||
100 | { | ||
101 | return I2C_FUNC_I2C; | ||
102 | } | ||
103 | |||
104 | static struct i2c_algorithm dtv5100_i2c_algo = { | ||
105 | .master_xfer = dtv5100_i2c_xfer, | ||
106 | .functionality = dtv5100_i2c_func, | ||
107 | }; | ||
108 | |||
109 | /* Callbacks for DVB USB */ | ||
110 | static struct zl10353_config dtv5100_zl10353_config = { | ||
111 | .demod_address = DTV5100_DEMOD_ADDR, | ||
112 | .no_tuner = 1, | ||
113 | .parallel_ts = 1, | ||
114 | }; | ||
115 | |||
116 | static 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 | |||
129 | static struct qt1010_config dtv5100_qt1010_config = { | ||
130 | .i2c_address = DTV5100_TUNER_ADDR | ||
131 | }; | ||
132 | |||
133 | static 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 */ | ||
141 | static struct dvb_usb_device_properties dtv5100_properties; | ||
142 | |||
143 | static 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 | |||
169 | static struct usb_device_id dtv5100_table[] = { | ||
170 | { USB_DEVICE(0x06be, 0xa232) }, | ||
171 | { } /* Terminating entry */ | ||
172 | }; | ||
173 | MODULE_DEVICE_TABLE(usb, dtv5100_table); | ||
174 | |||
175 | static 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 | |||
213 | static 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 | |||
220 | module_usb_driver(dtv5100_driver); | ||
221 | |||
222 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
223 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
224 | MODULE_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 | |||
41 | static 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 | |||
14 | extern int dvb_usb_debug; | ||
15 | extern 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 */ | ||
28 | extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_device_properties *); | ||
29 | |||
30 | extern int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff); | ||
31 | |||
32 | extern int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props); | ||
33 | extern int usb_urb_exit(struct usb_data_stream *stream); | ||
34 | extern int usb_urb_submit(struct usb_data_stream *stream); | ||
35 | extern int usb_urb_kill(struct usb_data_stream *stream); | ||
36 | |||
37 | extern int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap); | ||
38 | extern int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap); | ||
39 | |||
40 | extern int dvb_usb_i2c_init(struct dvb_usb_device *); | ||
41 | extern int dvb_usb_i2c_exit(struct dvb_usb_device *); | ||
42 | |||
43 | extern int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, | ||
44 | short *adapter_nums); | ||
45 | extern int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap); | ||
46 | extern int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap); | ||
47 | extern int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap); | ||
48 | |||
49 | extern int dvb_usb_remote_init(struct dvb_usb_device *); | ||
50 | extern 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 */ | ||
12 | static 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 | |||
85 | static 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 | |||
91 | static 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 | |||
97 | int 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 | |||
152 | err_net_init: | ||
153 | dvb_dmxdev_release(&adap->dmxdev); | ||
154 | err_dmx_dev: | ||
155 | dvb_dmx_release(&adap->demux); | ||
156 | err_dmx: | ||
157 | dvb_unregister_adapter(&adap->dvb_adap); | ||
158 | err: | ||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | int 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 | |||
176 | static 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 | |||
193 | static 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 | |||
207 | static 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 | |||
219 | int 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 | |||
274 | int 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 | |||
14 | struct 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 | |||
20 | static 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 | */ | ||
30 | static 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 | |||
36 | int 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 | } | ||
76 | EXPORT_SYMBOL(usb_cypress_load_firmware); | ||
77 | |||
78 | int 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 | |||
115 | int 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 | } | ||
146 | EXPORT_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 | |||
10 | int 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 | |||
37 | int 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 */ | ||
17 | int dvb_usb_debug; | ||
18 | module_param_named(debug, dvb_usb_debug, int, 0644); | ||
19 | MODULE_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 | |||
21 | int dvb_usb_disable_rc_polling; | ||
22 | module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644); | ||
23 | MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0)."); | ||
24 | |||
25 | static int dvb_usb_force_pid_filter_usage; | ||
26 | module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444); | ||
27 | MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID filter, if any (default: 0)."); | ||
28 | |||
29 | static 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 | |||
111 | static 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 */ | ||
128 | static 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 | |||
141 | static 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 */ | ||
176 | static 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 | |||
215 | int 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 | */ | ||
233 | int 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 | } | ||
284 | EXPORT_SYMBOL(dvb_usb_device_init); | ||
285 | |||
286 | void 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 | } | ||
299 | EXPORT_SYMBOL(dvb_usb_device_exit); | ||
300 | |||
301 | MODULE_VERSION("1.0"); | ||
302 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); | ||
303 | MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices"); | ||
304 | MODULE_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 | |||
11 | static unsigned int | ||
12 | legacy_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 | |||
44 | static 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 | |||
66 | static 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 | */ | ||
108 | static 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 | |||
180 | schedule: | ||
181 | schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval)); | ||
182 | } | ||
183 | |||
184 | static 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 | */ | ||
240 | static 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 | |||
263 | static 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 | |||
307 | int 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 | |||
340 | int 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 | ||
356 | int 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 | } | ||
391 | EXPORT_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 | |||
11 | int 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 | } | ||
61 | EXPORT_SYMBOL(dvb_usb_generic_rw); | ||
62 | |||
63 | int 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 | } | ||
67 | EXPORT_SYMBOL(dvb_usb_generic_write); | ||
68 | |||
69 | static 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 | |||
76 | static 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 | |||
83 | static 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 | |||
91 | int 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 | |||
115 | int 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 | */ | ||
70 | struct 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 | |||
78 | static inline u8 rc5_custom(struct rc_map_table *key) | ||
79 | { | ||
80 | return (key->scancode >> 8) & 0xff; | ||
81 | } | ||
82 | |||
83 | static inline u8 rc5_data(struct rc_map_table *key) | ||
84 | { | ||
85 | return key->scancode & 0xff; | ||
86 | } | ||
87 | |||
88 | static inline u16 rc5_scan(struct rc_map_table *key) | ||
89 | { | ||
90 | return key->scancode & 0xffff; | ||
91 | } | ||
92 | |||
93 | struct dvb_usb_device; | ||
94 | struct dvb_usb_adapter; | ||
95 | struct 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 | */ | ||
102 | struct 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 | */ | ||
139 | struct 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 | ||
161 | struct 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 | */ | ||
178 | struct 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 | */ | ||
200 | struct 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 | */ | ||
218 | enum 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 | ||
261 | struct 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 | ||
311 | struct 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 | */ | ||
358 | struct 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 | |||
372 | struct 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 | */ | ||
421 | struct 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 | |||
458 | extern 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); | ||
462 | extern void dvb_usb_device_exit(struct usb_interface *); | ||
463 | |||
464 | /* the generic read/write method for device control */ | ||
465 | extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int); | ||
466 | extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16); | ||
467 | |||
468 | /* commonly used remote control parsing */ | ||
469 | extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); | ||
470 | |||
471 | /* commonly used firmware download types and function */ | ||
472 | struct hexline { | ||
473 | u8 len; | ||
474 | u32 addr; | ||
475 | u8 type; | ||
476 | u8 data[255]; | ||
477 | u8 chk; | ||
478 | }; | ||
479 | extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type); | ||
480 | extern 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 | |||
11 | static 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 | |||
18 | static 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 | |||
25 | static 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 | |||
32 | int 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 | |||
43 | int 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 */ | ||
52 | static 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; | ||
153 | err_mutex_unlock: | ||
154 | mutex_unlock(&adap->sync_mutex); | ||
155 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
156 | return ret; | ||
157 | } | ||
158 | |||
159 | static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
160 | { | ||
161 | return dvb_usb_ctrl_feed(dvbdmxfeed, 1); | ||
162 | } | ||
163 | |||
164 | static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
165 | { | ||
166 | return dvb_usb_ctrl_feed(dvbdmxfeed, -1); | ||
167 | } | ||
168 | |||
169 | int 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; | ||
229 | err_net_init: | ||
230 | dvb_dmxdev_release(&adap->dmxdev); | ||
231 | err_dmx_dev: | ||
232 | dvb_dmx_release(&adap->demux); | ||
233 | err_dmx: | ||
234 | dvb_unregister_adapter(&adap->dvb_adap); | ||
235 | err: | ||
236 | adap->dvb_adap.priv = NULL; | ||
237 | return ret; | ||
238 | } | ||
239 | |||
240 | int 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 | |||
255 | static 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; | ||
283 | err: | ||
284 | mutex_unlock(&adap->sync_mutex); | ||
285 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
286 | return ret; | ||
287 | } | ||
288 | |||
289 | static 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; | ||
317 | err: | ||
318 | mutex_unlock(&adap->sync_mutex); | ||
319 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
320 | return ret; | ||
321 | } | ||
322 | |||
323 | int 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 | |||
375 | err_dvb_unregister_frontend: | ||
376 | for (i = count_registered - 1; i >= 0; i--) | ||
377 | dvb_unregister_frontend(adap->fe[i]); | ||
378 | |||
379 | err_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 | |||
385 | err: | ||
386 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
387 | return ret; | ||
388 | } | ||
389 | |||
390 | int 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 | */ | ||
17 | static 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 | |||
41 | int 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; | ||
102 | err: | ||
103 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
104 | return ret; | ||
105 | } | ||
106 | |||
107 | int 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 | |||
87 | struct rc_map_dvb_usb_table_table { | ||
88 | struct rc_map_table *rc_keys; | ||
89 | int rc_keys_size; | ||
90 | }; | ||
91 | |||
92 | struct su3000_state { | ||
93 | u8 initialized; | ||
94 | }; | ||
95 | |||
96 | struct s6x0_state { | ||
97 | int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v); | ||
98 | }; | ||
99 | |||
100 | /* debug */ | ||
101 | static int dvb_usb_dw2102_debug; | ||
102 | module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); | ||
103 | MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))." | ||
104 | DVB_USB_DEBUG_STATUS); | ||
105 | |||
106 | /* keymaps */ | ||
107 | static int ir_keymap; | ||
108 | module_param_named(keymap, ir_keymap, int, 0644); | ||
109 | MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..." | ||
110 | " 256=none"); | ||
111 | |||
112 | /* demod probe */ | ||
113 | static int demod_probe = 1; | ||
114 | module_param_named(demod, demod_probe, int, 0644); | ||
115 | MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 " | ||
116 | "4=stv0903+stb6100(or-able))."); | ||
117 | |||
118 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
119 | |||
120 | static 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 */ | ||
147 | static 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 | |||
220 | static 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 | |||
275 | static 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 | |||
347 | static 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 | |||
428 | static 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 | |||
491 | static 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 | |||
600 | static 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 | |||
664 | static u32 dw210x_i2c_func(struct i2c_adapter *adapter) | ||
665 | { | ||
666 | return I2C_FUNC_I2C; | ||
667 | } | ||
668 | |||
669 | static struct i2c_algorithm dw2102_i2c_algo = { | ||
670 | .master_xfer = dw2102_i2c_transfer, | ||
671 | .functionality = dw210x_i2c_func, | ||
672 | }; | ||
673 | |||
674 | static struct i2c_algorithm dw2102_serit_i2c_algo = { | ||
675 | .master_xfer = dw2102_serit_i2c_transfer, | ||
676 | .functionality = dw210x_i2c_func, | ||
677 | }; | ||
678 | |||
679 | static struct i2c_algorithm dw2102_earda_i2c_algo = { | ||
680 | .master_xfer = dw2102_earda_i2c_transfer, | ||
681 | .functionality = dw210x_i2c_func, | ||
682 | }; | ||
683 | |||
684 | static struct i2c_algorithm dw2104_i2c_algo = { | ||
685 | .master_xfer = dw2104_i2c_transfer, | ||
686 | .functionality = dw210x_i2c_func, | ||
687 | }; | ||
688 | |||
689 | static struct i2c_algorithm dw3101_i2c_algo = { | ||
690 | .master_xfer = dw3101_i2c_transfer, | ||
691 | .functionality = dw210x_i2c_func, | ||
692 | }; | ||
693 | |||
694 | static struct i2c_algorithm s6x0_i2c_algo = { | ||
695 | .master_xfer = s6x0_i2c_transfer, | ||
696 | .functionality = dw210x_i2c_func, | ||
697 | }; | ||
698 | |||
699 | static struct i2c_algorithm su3000_i2c_algo = { | ||
700 | .master_xfer = su3000_i2c_transfer, | ||
701 | .functionality = dw210x_i2c_func, | ||
702 | }; | ||
703 | |||
704 | static 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 | |||
728 | static 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 | |||
768 | static 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 | |||
784 | static 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 | |||
800 | static 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 | |||
833 | static 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 | |||
844 | static 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 | |||
868 | static 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 | |||
881 | static 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 | |||
899 | static 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 | |||
911 | static struct cx24116_config dw2104_config = { | ||
912 | .demod_address = 0x55, | ||
913 | .mpg_clk_pos_pol = 0x01, | ||
914 | }; | ||
915 | |||
916 | static struct si21xx_config serit_sp1511lhb_config = { | ||
917 | .demod_address = 0x68, | ||
918 | .min_delay_ms = 100, | ||
919 | |||
920 | }; | ||
921 | |||
922 | static struct tda10023_config dw3101_tda10023_config = { | ||
923 | .demod_address = 0x0c, | ||
924 | .invert = 1, | ||
925 | }; | ||
926 | |||
927 | static struct mt312_config zl313_config = { | ||
928 | .demod_address = 0x0e, | ||
929 | }; | ||
930 | |||
931 | static struct ds3000_config dw2104_ds3000_config = { | ||
932 | .demod_address = 0x68, | ||
933 | }; | ||
934 | |||
935 | static 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 | |||
946 | static struct stb6100_config dw2104a_stb6100_config = { | ||
947 | .tuner_address = 0x60, | ||
948 | .refclock = 27000000, | ||
949 | }; | ||
950 | |||
951 | static 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 | |||
962 | static struct stv6110_config dw2104_stv6110_config = { | ||
963 | .i2c_address = 0x60, | ||
964 | .mclk = 16000000, | ||
965 | .clk_div = 1, | ||
966 | }; | ||
967 | |||
968 | static 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 | |||
981 | static struct ds3000_config su3000_ds3000_config = { | ||
982 | .demod_address = 0x68, | ||
983 | .ci_mode = 1, | ||
984 | }; | ||
985 | |||
986 | static 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 | |||
1044 | static struct dvb_usb_device_properties dw2102_properties; | ||
1045 | static struct dvb_usb_device_properties dw2104_properties; | ||
1046 | static struct dvb_usb_device_properties s6x0_properties; | ||
1047 | |||
1048 | static 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 | |||
1087 | static 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 | |||
1098 | static 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 | |||
1114 | static 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 | |||
1137 | static 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 | |||
1158 | static 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 | |||
1176 | static 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 | |||
1213 | static 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 | |||
1220 | static 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 | |||
1228 | static 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 | |||
1262 | static 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 | |||
1312 | static 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 | |||
1347 | static 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 | |||
1385 | static 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 | |||
1392 | static 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 | |||
1434 | enum 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 | |||
1452 | static 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 | |||
1471 | MODULE_DEVICE_TABLE(usb, dw2102_table); | ||
1472 | |||
1473 | static 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 | |||
1586 | static 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 | |||
1641 | static 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 | |||
1691 | static 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 | |||
1738 | static 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 | |||
1784 | struct dvb_usb_device_properties *p1100; | ||
1785 | static struct dvb_usb_device_description d1100 = { | ||
1786 | "Prof 1100 USB ", | ||
1787 | {&dw2102_table[PROF_1100], NULL}, | ||
1788 | {NULL}, | ||
1789 | }; | ||
1790 | |||
1791 | struct dvb_usb_device_properties *s660; | ||
1792 | static struct dvb_usb_device_description d660 = { | ||
1793 | "TeVii S660 USB", | ||
1794 | {&dw2102_table[TEVII_S660], NULL}, | ||
1795 | {NULL}, | ||
1796 | }; | ||
1797 | |||
1798 | static struct dvb_usb_device_description d480_1 = { | ||
1799 | "TeVii S480.1 USB", | ||
1800 | {&dw2102_table[TEVII_S480_1], NULL}, | ||
1801 | {NULL}, | ||
1802 | }; | ||
1803 | |||
1804 | static struct dvb_usb_device_description d480_2 = { | ||
1805 | "TeVii S480.2 USB", | ||
1806 | {&dw2102_table[TEVII_S480_2], NULL}, | ||
1807 | {NULL}, | ||
1808 | }; | ||
1809 | |||
1810 | struct dvb_usb_device_properties *p7500; | ||
1811 | static struct dvb_usb_device_description d7500 = { | ||
1812 | "Prof 7500 USB DVB-S2", | ||
1813 | {&dw2102_table[PROF_7500], NULL}, | ||
1814 | {NULL}, | ||
1815 | }; | ||
1816 | |||
1817 | static 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 | |||
1873 | static 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 | |||
1935 | static 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 | |||
1942 | module_usb_driver(dw2102_driver); | ||
1943 | |||
1944 | MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); | ||
1945 | MODULE_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"); | ||
1950 | MODULE_VERSION("0.1"); | ||
1951 | MODULE_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 | |||
19 | struct 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 */ | ||
27 | static 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 */ | ||
57 | static 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 | |||
78 | static 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 */ | ||
94 | static 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 | |||
115 | error: | ||
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 */ | ||
122 | static 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; | ||
208 | error: | ||
209 | deb_fe("%s:ret == %d\n", __func__, ret); | ||
210 | return -EREMOTEIO; | ||
211 | } | ||
212 | |||
213 | static 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 | |||
237 | static 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 */ | ||
265 | static 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 | |||
285 | static 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 | |||
299 | static 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 | */ | ||
331 | static 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 | |||
370 | static const int init_code_len = sizeof(init_code) / sizeof(u8[2]); | ||
371 | |||
372 | static 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 | |||
396 | error: | ||
397 | deb_fe("%s: init_code[%d] failed. ret==%d\n", __func__, i, ret); | ||
398 | return -EREMOTEIO; | ||
399 | } | ||
400 | |||
401 | |||
402 | static void jdvbt90502_release(struct dvb_frontend *fe) | ||
403 | { | ||
404 | struct jdvbt90502_state *state = fe->demodulator_priv; | ||
405 | kfree(state); | ||
406 | } | ||
407 | |||
408 | |||
409 | static struct dvb_frontend_ops jdvbt90502_ops; | ||
410 | |||
411 | struct 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 | |||
436 | error: | ||
437 | kfree(state); | ||
438 | return NULL; | ||
439 | } | ||
440 | |||
441 | static 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 */ | ||
16 | int dvb_usb_friio_debug; | ||
17 | module_param_named(debug, dvb_usb_friio_debug, int, 0644); | ||
18 | MODULE_PARM_DESC(debug, | ||
19 | "set debugging level (1=info,2=xfer,4=rc,8=fe (or-able))." | ||
20 | DVB_USB_DEBUG_STATUS); | ||
21 | |||
22 | DVB_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 | */ | ||
33 | static 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 | */ | ||
62 | static 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 */ | ||
109 | static 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 | |||
140 | static u32 gl861_i2c_func(struct i2c_adapter *adapter) | ||
141 | { | ||
142 | return I2C_FUNC_I2C; | ||
143 | } | ||
144 | |||
145 | static 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 | |||
200 | static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); | ||
201 | |||
202 | /* TODO: move these init cmds to the FE's init routine? */ | ||
203 | static 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 | }; | ||
215 | static 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 | */ | ||
221 | static 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 | |||
296 | restart: | ||
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 | |||
373 | error: | ||
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 | |||
382 | static 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 | |||
401 | static 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 */ | ||
414 | static struct dvb_usb_device_properties friio_properties; | ||
415 | |||
416 | static 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 | |||
448 | struct jdvbt90502_config friio_fe_config = { | ||
449 | .demod_address = FRIIO_DEMOD_ADDR, | ||
450 | .pll_address = FRIIO_PLL_ADDR, | ||
451 | }; | ||
452 | |||
453 | static struct i2c_algorithm gl861_i2c_algo = { | ||
454 | .master_xfer = gl861_i2c_xfer, | ||
455 | .functionality = gl861_i2c_func, | ||
456 | }; | ||
457 | |||
458 | static struct usb_device_id friio_table[] = { | ||
459 | { USB_DEVICE(USB_VID_774, USB_PID_FRIIO_WHITE) }, | ||
460 | { } /* Terminating entry */ | ||
461 | }; | ||
462 | MODULE_DEVICE_TABLE(usb, friio_table); | ||
463 | |||
464 | |||
465 | static 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 | |||
510 | static 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 | |||
517 | module_usb_driver(friio_driver); | ||
518 | |||
519 | MODULE_AUTHOR("Akihiro Tsukada <tskd2@yahoo.co.jp>"); | ||
520 | MODULE_DESCRIPTION("Driver for Friio ISDB-T USB2.0 Receiver"); | ||
521 | MODULE_VERSION("0.2"); | ||
522 | MODULE_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 | |||
33 | extern 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 | |||
92 | struct jdvbt90502_config { | ||
93 | u8 demod_address; /* i2c addr for demodulator IC */ | ||
94 | u8 pll_address; /* PLL addr on the secondary i2c*/ | ||
95 | }; | ||
96 | extern struct jdvbt90502_config friio_fe_config; | ||
97 | |||
98 | extern 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 | |||
19 | struct 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 | |||
28 | static 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 | |||
36 | static 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 | |||
42 | static 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 | |||
54 | static 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 */ | ||
72 | static 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 */ | ||
80 | static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) | ||
81 | { | ||
82 | (void) fe; | ||
83 | *unc = 0; | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static 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 | |||
96 | static 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 | |||
110 | static 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 | |||
116 | static 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 | |||
225 | static 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 | |||
239 | static 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 | |||
257 | static 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 | |||
268 | static 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 | |||
279 | static 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 | |||
285 | static 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 | |||
302 | static void gp8psk_fe_release(struct dvb_frontend* fe) | ||
303 | { | ||
304 | struct gp8psk_fe_state *state = fe->demodulator_priv; | ||
305 | kfree(state); | ||
306 | } | ||
307 | |||
308 | static struct dvb_frontend_ops gp8psk_fe_ops; | ||
309 | |||
310 | struct 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; | ||
321 | error: | ||
322 | return NULL; | ||
323 | success: | ||
324 | return &s->fe; | ||
325 | } | ||
326 | |||
327 | |||
328 | static 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 */ | ||
20 | static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw"; | ||
21 | int dvb_usb_gp8psk_debug; | ||
22 | module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644); | ||
23 | MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); | ||
24 | |||
25 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
26 | |||
27 | static 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 | |||
32 | static 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 | |||
37 | static 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 | |||
54 | int 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 | |||
86 | int 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 | |||
112 | static 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 | |||
156 | out_free: | ||
157 | kfree(buf); | ||
158 | out_rel_fw: | ||
159 | release_firmware(fw); | ||
160 | |||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | static 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 | |||
209 | int 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 | |||
226 | static 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 | |||
231 | static 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 | |||
237 | static struct dvb_usb_device_properties gp8psk_properties; | ||
238 | |||
239 | static 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 | |||
253 | static 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 | }; | ||
262 | MODULE_DEVICE_TABLE(usb, gp8psk_usb_table); | ||
263 | |||
264 | static 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 */ | ||
316 | static 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 | |||
323 | module_usb_driver(gp8psk_usb_driver); | ||
324 | |||
325 | MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>"); | ||
326 | MODULE_DESCRIPTION("Driver for Genpix DVB-S"); | ||
327 | MODULE_VERSION("1.1"); | ||
328 | MODULE_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 | |||
23 | extern 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 | |||
94 | extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d); | ||
95 | extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); | ||
96 | extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, | ||
97 | u16 index, u8 *b, int blen); | ||
98 | extern 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 */ | ||
25 | static int dvb_usb_m920x_debug; | ||
26 | module_param_named(debug,dvb_usb_m920x_debug, int, 0644); | ||
27 | MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); | ||
28 | |||
29 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
30 | |||
31 | static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid); | ||
32 | |||
33 | static 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 | |||
54 | static 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 | |||
66 | static 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 | |||
119 | static 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 | |||
133 | static 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 */ | ||
201 | static 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 | |||
261 | static u32 m920x_i2c_func(struct i2c_adapter *adapter) | ||
262 | { | ||
263 | return I2C_FUNC_I2C; | ||
264 | } | ||
265 | |||
266 | static struct i2c_algorithm m920x_i2c_algo = { | ||
267 | .master_xfer = m920x_i2c_xfer, | ||
268 | .functionality = m920x_i2c_func, | ||
269 | }; | ||
270 | |||
271 | /* pid filter */ | ||
272 | static 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 | |||
290 | static 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 | |||
325 | static 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 | |||
334 | static 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 | |||
343 | static 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 */ | ||
416 | static 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 */ | ||
430 | static 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 | |||
464 | static struct mt352_config m920x_mt352_config = { | ||
465 | .demod_address = 0x0f, | ||
466 | .no_tuner = 1, | ||
467 | .demod_init = m920x_mt352_demod_init, | ||
468 | }; | ||
469 | |||
470 | static 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 | |||
482 | static 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 */ | ||
495 | static struct qt1010_config m920x_qt1010_config = { | ||
496 | .i2c_address = 0x62 | ||
497 | }; | ||
498 | |||
499 | /* Callbacks for DVB USB */ | ||
500 | static 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 | |||
513 | static 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 | |||
526 | static 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 | |||
539 | static 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 | |||
549 | static 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 | |||
559 | static 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 | |||
569 | static 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 */ | ||
578 | static struct m920x_inits megasky_rc_init [] = { | ||
579 | { M9206_RC_INIT2, 0xa8 }, | ||
580 | { M9206_RC_INIT1, 0x51 }, | ||
581 | { } /* terminating entry */ | ||
582 | }; | ||
583 | |||
584 | static 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 | |||
593 | static 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 */ | ||
606 | static 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 | |||
625 | static 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 | |||
645 | static 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 */ | ||
702 | static struct dvb_usb_device_properties megasky_properties; | ||
703 | static struct dvb_usb_device_properties digivox_mini_ii_properties; | ||
704 | static struct dvb_usb_device_properties tvwalkertwin_properties; | ||
705 | static struct dvb_usb_device_properties dposh_properties; | ||
706 | static struct dvb_usb_device_properties pinnacle_pctv310e_properties; | ||
707 | |||
708 | static 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 | |||
779 | static 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 | }; | ||
792 | MODULE_DEVICE_TABLE (usb, m920x_table); | ||
793 | |||
794 | static 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 | |||
849 | static 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 | */ | ||
905 | static 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 | |||
984 | static 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 | |||
1026 | static 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 | |||
1082 | static 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 | |||
1089 | module_usb_driver(m920x_driver); | ||
1090 | |||
1091 | MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>"); | ||
1092 | MODULE_DESCRIPTION("DVB Driver for ULI M920x"); | ||
1093 | MODULE_VERSION("0.1"); | ||
1094 | MODULE_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 | /* | ||
24 | sequences found in logs: | ||
25 | [index value] | ||
26 | 0x80 write addr | ||
27 | (0x00 out byte)* | ||
28 | 0x40 out byte | ||
29 | |||
30 | 0x80 write addr | ||
31 | (0x00 out byte)* | ||
32 | 0x80 read addr | ||
33 | (0x21 in byte)* | ||
34 | 0x60 in byte | ||
35 | |||
36 | this sequence works: | ||
37 | 0x80 read addr | ||
38 | (0x21 in byte)* | ||
39 | 0x60 in byte | ||
40 | |||
41 | Guess at API of the I2C function: | ||
42 | I2C operation is done one byte at a time with USB control messages. The | ||
43 | index the messages is sent to is made up of a set of flags that control | ||
44 | the I2C bus state: | ||
45 | 0x80: 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. | ||
48 | 0x40: Send STOP condition. This should be set on the last byte of an | ||
49 | I2C transaction. | ||
50 | 0x20: 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. | ||
54 | 0x01: 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 | |||
59 | What any other bits might mean, or how to get the slave's ACK/NACK | ||
60 | response to a write, is unknown. | ||
61 | */ | ||
62 | |||
63 | struct 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 | |||
72 | struct 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 | |||
14 | static int debug; | ||
15 | module_param(debug, int, 0644); | ||
16 | MODULE_PARM_DESC(debug, "set debugging level (1=rc,2=eeprom (|-able))." DVB_USB_DEBUG_STATUS); | ||
17 | |||
18 | DVB_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 */ | ||
24 | static 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 | */ | ||
75 | static 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 | |||
123 | static 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 */ | ||
143 | static struct dvb_usb_device_properties nova_t_properties; | ||
144 | |||
145 | static 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 */ | ||
153 | static 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 | }; | ||
158 | MODULE_DEVICE_TABLE(usb, nova_t_table); | ||
159 | |||
160 | static 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 | |||
221 | static 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 | |||
228 | module_usb_driver(nova_t_driver); | ||
229 | |||
230 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); | ||
231 | MODULE_DESCRIPTION("Hauppauge WinTV-NOVA-T usb2"); | ||
232 | MODULE_VERSION("1.0"); | ||
233 | MODULE_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 | |||
35 | struct opera1_state { | ||
36 | u32 last_key_pressed; | ||
37 | }; | ||
38 | struct rc_map_opera_table { | ||
39 | u32 keycode; | ||
40 | u32 event; | ||
41 | }; | ||
42 | |||
43 | static int dvb_usb_opera1_debug; | ||
44 | module_param_named(debug, dvb_usb_opera1_debug, int, 0644); | ||
45 | MODULE_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 | |||
49 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
50 | |||
51 | |||
52 | static 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); | ||
84 | out: | ||
85 | kfree(buf); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | /* I2C */ | ||
90 | |||
91 | static 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 | |||
134 | static 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 | |||
160 | static u32 opera1_i2c_func(struct i2c_adapter *adapter) | ||
161 | { | ||
162 | return I2C_FUNC_I2C; | ||
163 | } | ||
164 | |||
165 | static struct i2c_algorithm opera1_i2c_algo = { | ||
166 | .master_xfer = opera1_i2c_xfer, | ||
167 | .functionality = opera1_i2c_func, | ||
168 | }; | ||
169 | |||
170 | static 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 | |||
187 | static 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 | } | ||
198 | static 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 | |||
252 | static 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 | |||
264 | static 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 | |||
276 | static 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 | |||
285 | static 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 | |||
295 | static 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 | |||
308 | static 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 | |||
325 | static 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 | |||
343 | static 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 | |||
372 | static 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 | |||
430 | static 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 | |||
436 | MODULE_DEVICE_TABLE(usb, opera1_table); | ||
437 | |||
438 | static 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 | } | ||
445 | static 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 | |||
498 | static 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 | |||
552 | static 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 | |||
570 | static 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 | |||
577 | module_usb_driver(opera1_driver); | ||
578 | |||
579 | MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org"); | ||
580 | MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de"); | ||
581 | MODULE_DESCRIPTION("Driver for Opera1 DVB-S device"); | ||
582 | MODULE_VERSION("0.1"); | ||
583 | MODULE_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 | |||
32 | static int debug; | ||
33 | module_param(debug, int, 0644); | ||
34 | MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); | ||
35 | |||
36 | DVB_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...) \ | ||
68 | do { \ | ||
69 | if (0) \ | ||
70 | printk(KERN_DEBUG DVB_USB_LOG_PREFIX \ | ||
71 | ": " format "\n" , ## arg); \ | ||
72 | } while (0) | ||
73 | |||
74 | enum { | ||
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 | |||
85 | static 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 | */ | ||
93 | struct 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 | |||
102 | static 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 | |||
138 | failed: | ||
139 | err("CI error %d; %02X %02X %02X -> %*ph.", | ||
140 | ret, SYNC_BYTE_OUT, id, cmd, 3, buf); | ||
141 | |||
142 | return ret; | ||
143 | } | ||
144 | |||
145 | static 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 | |||
160 | static 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 | |||
183 | static 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 | |||
201 | static 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 | |||
224 | static 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 | |||
243 | static 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 | |||
270 | static 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 | |||
275 | static 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 | |||
280 | static 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 | |||
320 | static 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 | |||
342 | static 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 | |||
366 | static 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 | ||
403 | static 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 | |||
448 | failed: | ||
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 | |||
457 | static 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 | |||
494 | static u32 pctv452e_i2c_func(struct i2c_adapter *adapter) | ||
495 | { | ||
496 | return I2C_FUNC_I2C; | ||
497 | } | ||
498 | |||
499 | static 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 | |||
539 | static 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 | |||
582 | static 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 | |||
613 | failed: | ||
614 | memset(mac, 0, 6); | ||
615 | |||
616 | return ret; | ||
617 | } | ||
618 | |||
619 | static 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 | |||
687 | static 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 | |||
820 | static 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 | |||
866 | static struct stb6100_config stb6100_config = { | ||
867 | .tuner_address = I2C_ADDR_STB6100, | ||
868 | .refclock = 27000000 | ||
869 | }; | ||
870 | |||
871 | |||
872 | static struct i2c_algorithm pctv452e_i2c_algo = { | ||
873 | .master_xfer = pctv452e_i2c_xfer, | ||
874 | .functionality = pctv452e_i2c_func | ||
875 | }; | ||
876 | |||
877 | static 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 | |||
898 | static 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 | |||
911 | static 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 | }; | ||
918 | MODULE_DEVICE_TABLE(usb, pctv452e_usb_table); | ||
919 | |||
920 | static 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 | |||
972 | static 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 | |||
1030 | static 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 | |||
1038 | static 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 | |||
1050 | static 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 | |||
1057 | module_usb_driver(pctv452e_usb_driver); | ||
1058 | |||
1059 | MODULE_AUTHOR("Dominik Kuhlen <dkuhlen@gmx.net>"); | ||
1060 | MODULE_AUTHOR("Andre Weidemann <Andre.Weidemann@web.de>"); | ||
1061 | MODULE_AUTHOR("Michael H. Schimek <mschimek@gmx.at>"); | ||
1062 | MODULE_DESCRIPTION("Pinnacle PCTV HDTV USB DVB / TT connect S2-3600 Driver"); | ||
1063 | MODULE_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 */ | ||
40 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
41 | |||
42 | static int debug; | ||
43 | module_param(debug, int, 0644); | ||
44 | MODULE_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 */ | ||
50 | static int disable_led_control; | ||
51 | module_param(disable_led_control, int, 0444); | ||
52 | MODULE_PARM_DESC(disable_led_control, | ||
53 | "disable LED control of the device " | ||
54 | "(default: 0 - LED control is active)."); | ||
55 | |||
56 | /* device private data */ | ||
57 | struct 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 | |||
87 | static 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 | |||
158 | static 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 | |||
194 | static u32 technisat_usb2_i2c_func(struct i2c_adapter *adapter) | ||
195 | { | ||
196 | return I2C_FUNC_I2C; | ||
197 | } | ||
198 | |||
199 | static 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 | ||
205 | static 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 */ | ||
216 | enum technisat_usb2_led_state { | ||
217 | LED_OFF, | ||
218 | LED_BLINK, | ||
219 | LED_ON, | ||
220 | LED_UNDEFINED | ||
221 | }; | ||
222 | |||
223 | static 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 | |||
272 | static 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 | |||
291 | static 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 | |||
320 | schedule: | ||
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 */ | ||
326 | static 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 */ | ||
358 | static 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 | ||
376 | static 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, ®, 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 | |||
396 | static 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 | |||
404 | static 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 | ||
439 | static 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 */ | ||
453 | static 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 | |||
480 | static 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 | |||
497 | static struct stv6110x_config technisat_usb2_stv6110x_config = { | ||
498 | .addr = 0x60, | ||
499 | .refclk = 16000000, | ||
500 | .clk_div = 2, | ||
501 | }; | ||
502 | |||
503 | static 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 | |||
592 | static 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 | |||
622 | unlock: | ||
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 | |||
659 | static 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 */ | ||
676 | static 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 */ | ||
682 | static 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 | |||
739 | static 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 | |||
763 | static 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 | |||
777 | static 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 | |||
784 | module_usb_driver(technisat_usb2_driver); | ||
785 | |||
786 | MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>"); | ||
787 | MODULE_DESCRIPTION("Driver for Technisat DVB-S/S2 USB 2.0 device"); | ||
788 | MODULE_VERSION("1.0"); | ||
789 | MODULE_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 */ | ||
40 | static int dvb_usb_ttusb2_debug; | ||
41 | #define deb_info(args...) dprintk(dvb_usb_ttusb2_debug,0x01,args) | ||
42 | module_param_named(debug,dvb_usb_ttusb2_debug, int, 0644); | ||
43 | MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS); | ||
44 | static int dvb_usb_ttusb2_debug_ci; | ||
45 | module_param_named(debug_ci,dvb_usb_ttusb2_debug_ci, int, 0644); | ||
46 | MODULE_PARM_DESC(debug_ci, "set debugging ci." DVB_USB_DEBUG_STATUS); | ||
47 | |||
48 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
49 | |||
50 | #define ci_dbg(format, arg...) \ | ||
51 | do { \ | ||
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 | |||
57 | enum { | ||
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 | |||
67 | struct ttusb2_state { | ||
68 | struct dvb_ca_en50221 ca; | ||
69 | struct mutex ca_mutex; | ||
70 | u8 id; | ||
71 | u16 last_rc_key; | ||
72 | }; | ||
73 | |||
74 | static 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 */ | ||
120 | static 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 | |||
130 | static 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 | |||
143 | static 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 | |||
165 | static 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 | |||
181 | static 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 | |||
201 | static 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 | |||
216 | static 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 | |||
240 | static 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 | |||
245 | static 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 | |||
250 | static 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 | |||
292 | static 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 | |||
311 | static 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 | |||
332 | static 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 | |||
368 | static 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 | |||
416 | static u32 ttusb2_i2c_func(struct i2c_adapter *adapter) | ||
417 | { | ||
418 | return I2C_FUNC_I2C; | ||
419 | } | ||
420 | |||
421 | static 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 */ | ||
430 | static 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 */ | ||
454 | static 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 | |||
462 | static 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 | |||
470 | static struct tda10086_config tda10086_config = { | ||
471 | .demod_address = 0x0e, | ||
472 | .invert = 0, | ||
473 | .diseqc_tone = 1, | ||
474 | .xtal_freq = TDA10086_XTAL_16M, | ||
475 | }; | ||
476 | |||
477 | static 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 | |||
487 | static 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 | |||
502 | static struct tda827x_config tda827x_config = { | ||
503 | .config = 0, | ||
504 | }; | ||
505 | |||
506 | static 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 | |||
519 | static 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 | |||
526 | static 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 | |||
558 | static 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 | |||
576 | static 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 */ | ||
591 | static struct dvb_usb_device_properties ttusb2_properties; | ||
592 | static struct dvb_usb_device_properties ttusb2_properties_s2400; | ||
593 | static struct dvb_usb_device_properties ttusb2_properties_ct3650; | ||
594 | |||
595 | static 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 | |||
603 | static 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 | |||
616 | static 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 | }; | ||
625 | MODULE_DEVICE_TABLE (usb, ttusb2_table); | ||
626 | |||
627 | static 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 | |||
682 | static 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 | |||
733 | static 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 | |||
808 | static 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 | |||
815 | module_usb_driver(ttusb2_driver); | ||
816 | |||
817 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); | ||
818 | MODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0"); | ||
819 | MODULE_VERSION("1.0"); | ||
820 | MODULE_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 | |||
16 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
17 | |||
18 | static 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 | |||
55 | static 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 | |||
68 | static 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 */ | ||
75 | static struct dvb_usb_device_properties umt_properties; | ||
76 | |||
77 | static 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 */ | ||
87 | static 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 | }; | ||
92 | MODULE_DEVICE_TABLE (usb, umt_table); | ||
93 | |||
94 | static 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 | |||
139 | static 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 | |||
146 | module_usb_driver(umt_driver); | ||
147 | |||
148 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); | ||
149 | MODULE_DESCRIPTION("Driver for HanfTek UMT 010 USB2.0 DVB-T device"); | ||
150 | MODULE_VERSION("1.0"); | ||
151 | MODULE_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 */ | ||
14 | static 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 | |||
65 | int 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 | |||
78 | int 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 | |||
93 | static 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 | |||
110 | static 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, | ||
128 | stream->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 | |||
137 | static 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 | |||
167 | static 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 | |||
212 | int 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 | |||
237 | int 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 | |||
23 | struct 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 | |||
42 | static 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 | |||
66 | static 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 | |||
75 | static 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 */ | ||
94 | static 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 */ | ||
103 | static 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 | |||
111 | static 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 | |||
120 | static 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 | |||
131 | static 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 | |||
138 | static 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 | |||
200 | static 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 | |||
208 | static int vp702x_fe_sleep(struct dvb_frontend *fe) | ||
209 | { | ||
210 | deb_fe("%s\n",__func__); | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static 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 | |||
246 | static 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 | |||
252 | static 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 | |||
285 | static 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 | |||
317 | static void vp702x_fe_release(struct dvb_frontend* fe) | ||
318 | { | ||
319 | struct vp702x_fe_state *st = fe->demodulator_priv; | ||
320 | kfree(st); | ||
321 | } | ||
322 | |||
323 | static struct dvb_frontend_ops vp702x_fe_ops; | ||
324 | |||
325 | struct 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; | ||
340 | error: | ||
341 | return NULL; | ||
342 | } | ||
343 | |||
344 | |||
345 | static 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 */ | ||
21 | int dvb_usb_vp702x_debug; | ||
22 | module_param_named(debug,dvb_usb_vp702x_debug, int, 0644); | ||
23 | MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); | ||
24 | |||
25 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
26 | |||
27 | struct vp702x_adapter_state { | ||
28 | int pid_filter_count; | ||
29 | int pid_filter_can_bypass; | ||
30 | u8 pid_filter_state; | ||
31 | }; | ||
32 | |||
33 | static 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 | |||
58 | int 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 | |||
70 | int 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 | |||
89 | int 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 | |||
101 | int 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 | |||
116 | static 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 | |||
155 | static 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 | |||
172 | static 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 | |||
190 | static 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 | |||
220 | static 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 | |||
248 | static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | ||
249 | { | ||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | /* keys for the enclosed remote control */ | ||
254 | static 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) */ | ||
260 | static 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 | |||
293 | static 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 | |||
308 | static 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 | |||
329 | static struct dvb_usb_device_properties vp702x_properties; | ||
330 | |||
331 | static 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 | |||
353 | out: | ||
354 | return ret; | ||
355 | |||
356 | } | ||
357 | |||
358 | static 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 | |||
368 | static 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 | }; | ||
374 | MODULE_DEVICE_TABLE(usb, vp702x_usb_table); | ||
375 | |||
376 | static 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 */ | ||
432 | static 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 | |||
439 | module_usb_driver(vp702x_usb_driver); | ||
440 | |||
441 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); | ||
442 | MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones"); | ||
443 | MODULE_VERSION("1.0"); | ||
444 | MODULE_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 | |||
7 | extern 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 | |||
101 | struct vp702x_device_state { | ||
102 | struct mutex buf_mutex; | ||
103 | int buf_len; | ||
104 | u8 *buf; | ||
105 | }; | ||
106 | |||
107 | |||
108 | extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d); | ||
109 | |||
110 | extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec); | ||
111 | extern 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 | |||
24 | struct vp7045_fe_state { | ||
25 | struct dvb_frontend fe; | ||
26 | struct dvb_usb_device *d; | ||
27 | }; | ||
28 | |||
29 | static 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 | |||
55 | static 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 | |||
64 | static 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 | |||
72 | static 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 | |||
82 | static 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 | |||
90 | static int vp7045_fe_init(struct dvb_frontend* fe) | ||
91 | { | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static int vp7045_fe_sleep(struct dvb_frontend* fe) | ||
96 | { | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static 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 | |||
106 | static 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 | |||
136 | static void vp7045_fe_release(struct dvb_frontend* fe) | ||
137 | { | ||
138 | struct vp7045_fe_state *state = fe->demodulator_priv; | ||
139 | kfree(state); | ||
140 | } | ||
141 | |||
142 | static struct dvb_frontend_ops vp7045_fe_ops; | ||
143 | |||
144 | struct 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; | ||
155 | error: | ||
156 | return NULL; | ||
157 | } | ||
158 | |||
159 | |||
160 | static 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 */ | ||
18 | static int dvb_usb_vp7045_debug; | ||
19 | module_param_named(debug,dvb_usb_vp7045_debug, int, 0644); | ||
20 | MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); | ||
21 | |||
22 | DVB_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 | |||
28 | int 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 | |||
78 | unlock: | ||
79 | mutex_unlock(&d->usb_mutex); | ||
80 | |||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | u8 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 | |||
94 | static 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. */ | ||
104 | static 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 | |||
157 | static 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 | |||
179 | static 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 | |||
193 | static 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 | |||
198 | static 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 | |||
222 | static struct dvb_usb_device_properties vp7045_properties; | ||
223 | |||
224 | static 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 | |||
231 | static 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 | }; | ||
238 | MODULE_DEVICE_TABLE(usb, vp7045_usb_table); | ||
239 | |||
240 | static 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 */ | ||
290 | static 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 | |||
297 | module_usb_driver(vp7045_usb_driver); | ||
298 | |||
299 | MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); | ||
300 | MODULE_DESCRIPTION("Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0"); | ||
301 | MODULE_VERSION("1.0"); | ||
302 | MODULE_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 | |||
66 | extern struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d); | ||
67 | extern int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen,int msec); | ||
68 | extern u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg); | ||
69 | |||
70 | #endif | ||