aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-06-14 15:35:56 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-13 22:26:31 -0400
commit786baecfe78f8e25547c628b48a60fc8e5636056 (patch)
treebb4101ce010f55cbbfc6d93ee13b44b496a028cc /drivers/media/usb
parent616300bd51bee80d2d122c205866aa4c20adbaa8 (diff)
[media] dvb-usb: move it to drivers/media/usb/dvb-usb
As media/dvb will be removed, move it to a proper place. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb')
-rw-r--r--drivers/media/usb/Kconfig18
-rw-r--r--drivers/media/usb/Makefile6
-rw-r--r--drivers/media/usb/dvb-usb-v2/Kconfig146
-rw-r--r--drivers/media/usb/dvb-usb-v2/Makefile48
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9015.c1434
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9015.h170
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.c1086
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.h111
-rw-r--r--drivers/media/usb/dvb-usb-v2/anysee.c1324
-rw-r--r--drivers/media/usb/dvb-usb-v2/anysee.h356
-rw-r--r--drivers/media/usb/dvb-usb-v2/au6610.c206
-rw-r--r--drivers/media/usb/dvb-usb-v2/au6610.h32
-rw-r--r--drivers/media/usb/dvb-usb-v2/az6007.c919
-rw-r--r--drivers/media/usb/dvb-usb-v2/ce6230.c287
-rw-r--r--drivers/media/usb/dvb-usb-v2/ce6230.h61
-rw-r--r--drivers/media/usb/dvb-usb-v2/cypress_firmware.c125
-rw-r--r--drivers/media/usb/dvb-usb-v2/cypress_firmware.h31
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb.h389
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_common.h35
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_core.c997
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c77
-rw-r--r--drivers/media/usb/dvb-usb-v2/ec168.c376
-rw-r--r--drivers/media/usb/dvb-usb-v2/ec168.h63
-rw-r--r--drivers/media/usb/dvb-usb-v2/gl861.c175
-rw-r--r--drivers/media/usb/dvb-usb-v2/gl861.h12
-rw-r--r--drivers/media/usb/dvb-usb-v2/it913x.c799
-rw-r--r--drivers/media/usb/dvb-usb-v2/lmedm04.c1369
-rw-r--r--drivers/media/usb/dvb-usb-v2/lmedm04.h175
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c612
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h55
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c763
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h56
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c850
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h35
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c343
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h53
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h179
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c527
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h89
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf.c1431
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf.h160
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.c1259
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.h254
-rw-r--r--drivers/media/usb/dvb-usb-v2/usb_urb.c357
-rw-r--r--drivers/media/usb/dvb-usb/Kconfig313
-rw-r--r--drivers/media/usb/dvb-usb/Makefile82
-rw-r--r--drivers/media/usb/dvb-usb/a800.c191
-rw-r--r--drivers/media/usb/dvb-usb/af9005-fe.c1487
-rw-r--r--drivers/media/usb/dvb-usb/af9005-remote.c157
-rw-r--r--drivers/media/usb/dvb-usb/af9005-script.h203
-rw-r--r--drivers/media/usb/dvb-usb/af9005.c1117
-rw-r--r--drivers/media/usb/dvb-usb/af9005.h3496
-rw-r--r--drivers/media/usb/dvb-usb/az6027.c1182
-rw-r--r--drivers/media/usb/dvb-usb/az6027.h14
-rw-r--r--drivers/media/usb/dvb-usb/cinergyT2-core.c254
-rw-r--r--drivers/media/usb/dvb-usb/cinergyT2-fe.c356
-rw-r--r--drivers/media/usb/dvb-usb/cinergyT2.h95
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.c2043
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.h35
-rw-r--r--drivers/media/usb/dvb-usb/dib0700.h75
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_core.c845
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_devices.c4813
-rw-r--r--drivers/media/usb/dvb-usb/dib07x0.h21
-rw-r--r--drivers/media/usb/dvb-usb/dibusb-common.c479
-rw-r--r--drivers/media/usb/dvb-usb/dibusb-mb.c471
-rw-r--r--drivers/media/usb/dvb-usb/dibusb-mc.c149
-rw-r--r--drivers/media/usb/dvb-usb/dibusb.h131
-rw-r--r--drivers/media/usb/dvb-usb/digitv.c354
-rw-r--r--drivers/media/usb/dvb-usb/digitv.h66
-rw-r--r--drivers/media/usb/dvb-usb/dtt200u-fe.c210
-rw-r--r--drivers/media/usb/dvb-usb/dtt200u.c368
-rw-r--r--drivers/media/usb/dvb-usb/dtt200u.h57
-rw-r--r--drivers/media/usb/dvb-usb/dtv5100.c224
-rw-r--r--drivers/media/usb/dvb-usb/dtv5100.h51
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-common.h52
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-dvb.c288
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-firmware.c146
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-i2c.c43
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-init.c304
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-remote.c391
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb-urb.c121
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb.h483
-rw-r--r--drivers/media/usb/dvb-usb/dvb_usb_dvb.c403
-rw-r--r--drivers/media/usb/dvb-usb/dvb_usb_remote.c117
-rw-r--r--drivers/media/usb/dvb-usb/dw2102.c1951
-rw-r--r--drivers/media/usb/dvb-usb/dw2102.h9
-rw-r--r--drivers/media/usb/dvb-usb/friio-fe.c473
-rw-r--r--drivers/media/usb/dvb-usb/friio.c522
-rw-r--r--drivers/media/usb/dvb-usb/friio.h99
-rw-r--r--drivers/media/usb/dvb-usb/gp8psk-fe.c369
-rw-r--r--drivers/media/usb/dvb-usb/gp8psk.c328
-rw-r--r--drivers/media/usb/dvb-usb/gp8psk.h100
-rw-r--r--drivers/media/usb/dvb-usb/m920x.c1099
-rw-r--r--drivers/media/usb/dvb-usb/m920x.h77
-rw-r--r--drivers/media/usb/dvb-usb/nova-t-usb2.c233
-rw-r--r--drivers/media/usb/dvb-usb/opera1.c583
-rw-r--r--drivers/media/usb/dvb-usb/pctv452e.c1063
-rw-r--r--drivers/media/usb/dvb-usb/technisat-usb2.c789
-rw-r--r--drivers/media/usb/dvb-usb/ttusb2.c820
-rw-r--r--drivers/media/usb/dvb-usb/ttusb2.h70
-rw-r--r--drivers/media/usb/dvb-usb/umt-010.c151
-rw-r--r--drivers/media/usb/dvb-usb/usb-urb.c254
-rw-r--r--drivers/media/usb/dvb-usb/vp702x-fe.c379
-rw-r--r--drivers/media/usb/dvb-usb/vp702x.c444
-rw-r--r--drivers/media/usb/dvb-usb/vp702x.h113
-rw-r--r--drivers/media/usb/dvb-usb/vp7045-fe.c190
-rw-r--r--drivers/media/usb/dvb-usb/vp7045.c302
-rw-r--r--drivers/media/usb/dvb-usb/vp7045.h70
-rw-r--r--drivers/media/usb/siano/Kconfig34
-rw-r--r--drivers/media/usb/siano/Makefile11
-rw-r--r--drivers/media/usb/siano/sms-cards.c311
-rw-r--r--drivers/media/usb/siano/sms-cards.h123
-rw-r--r--drivers/media/usb/siano/smscoreapi.c1637
-rw-r--r--drivers/media/usb/siano/smscoreapi.h775
-rw-r--r--drivers/media/usb/siano/smsdvb.c1078
-rw-r--r--drivers/media/usb/siano/smsendian.c103
-rw-r--r--drivers/media/usb/siano/smsendian.h32
-rw-r--r--drivers/media/usb/siano/smsir.c114
-rw-r--r--drivers/media/usb/siano/smsir.h55
-rw-r--r--drivers/media/usb/siano/smssdio.c365
-rw-r--r--drivers/media/usb/siano/smsusb.c568
-rw-r--r--drivers/media/usb/ttusb-budget/Kconfig18
-rw-r--r--drivers/media/usb/ttusb-budget/Makefile3
-rw-r--r--drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c1816
-rw-r--r--drivers/media/usb/ttusb-dec/Kconfig21
-rw-r--r--drivers/media/usb/ttusb-dec/Makefile3
-rw-r--r--drivers/media/usb/ttusb-dec/ttusb_dec.c1764
-rw-r--r--drivers/media/usb/ttusb-dec/ttusbdecfe.c298
-rw-r--r--drivers/media/usb/ttusb-dec/ttusbdecfe.h38
129 files changed, 59192 insertions, 0 deletions
diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig
new file mode 100644
index 000000000000..70b1708db05a
--- /dev/null
+++ b/drivers/media/usb/Kconfig
@@ -0,0 +1,18 @@
1#
2# USB media device configuration
3#
4
5menuconfig MEDIA_USB_DRIVERS
6 bool "Supported DVB USB Adapters"
7 depends on USB
8 default y
9
10if MEDIA_USB_DRIVERS && DVB_CORE && I2C
11
12source "drivers/media/usb/dvb-usb/Kconfig"
13source "drivers/media/usb/dvb-usb-v2/Kconfig"
14source "drivers/media/usb/ttusb-budget/Kconfig"
15source "drivers/media/usb/ttusb-dec/Kconfig"
16source "drivers/media/usb/siano/Kconfig"
17
18endif
diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile
new file mode 100644
index 000000000000..44e29f340ebd
--- /dev/null
+++ b/drivers/media/usb/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for the USB media device drivers
3#
4
5# DVB USB-only drivers
6obj-y := ttusb-dec/ ttusb-budget/ dvb-usb/ dvb-usb-v2/ siano/
diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
new file mode 100644
index 000000000000..276374fbaf4f
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/Kconfig
@@ -0,0 +1,146 @@
1config DVB_USB_V2
2 tristate "Support for various USB DVB devices v2"
3 depends on DVB_CORE && USB && I2C && RC_CORE
4 help
5 By enabling this you will be able to choose the various supported
6 USB1.1 and USB2.0 DVB devices.
7
8 Almost every USB device needs a firmware, please look into
9 <file:Documentation/dvb/README.dvb-usb>.
10
11 For a complete list of supported USB devices see the LinuxTV DVB Wiki:
12 <http://www.linuxtv.org/wiki/index.php/DVB_USB>
13
14 Say Y if you own a USB DVB device.
15
16config DVB_USB_CYPRESS_FIRMWARE
17 tristate "Cypress firmware helper routines"
18 depends on DVB_USB_V2
19
20config DVB_USB_AF9015
21 tristate "Afatech AF9015 DVB-T USB2.0 support"
22 depends on DVB_USB_V2
23 select DVB_AF9013
24 select DVB_PLL if !DVB_FE_CUSTOMISE
25 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
26 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
27 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
28 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
29 select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
30 select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
31 select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
32 help
33 Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
34
35config DVB_USB_AF9035
36 tristate "Afatech AF9035 DVB-T USB2.0 support"
37 depends on DVB_USB_V2
38 select DVB_AF9033
39 select MEDIA_TUNER_TUA9001 if !MEDIA_TUNER_CUSTOMISE
40 select MEDIA_TUNER_FC0011 if !MEDIA_TUNER_CUSTOMISE
41 select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
42 select MEDIA_TUNER_TDA18218 if !MEDIA_TUNER_CUSTOMISE
43 help
44 Say Y here to support the Afatech AF9035 based DVB USB receiver.
45
46config DVB_USB_ANYSEE
47 tristate "Anysee DVB-T/C USB2.0 support"
48 depends on DVB_USB_V2
49 select DVB_PLL if !DVB_FE_CUSTOMISE
50 select DVB_MT352 if !DVB_FE_CUSTOMISE
51 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
52 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
53 select MEDIA_TUNER_TDA18212 if !MEDIA_TUNER_CUSTOMISE
54 select DVB_CX24116 if !DVB_FE_CUSTOMISE
55 select DVB_STV0900 if !DVB_FE_CUSTOMISE
56 select DVB_STV6110 if !DVB_FE_CUSTOMISE
57 select DVB_ISL6423 if !DVB_FE_CUSTOMISE
58 select DVB_CXD2820R if !DVB_FE_CUSTOMISE
59 help
60 Say Y here to support the Anysee E30, Anysee E30 Plus or
61 Anysee E30 C Plus DVB USB2.0 receiver.
62
63config DVB_USB_AU6610
64 tristate "Alcor Micro AU6610 USB2.0 support"
65 depends on DVB_USB_V2
66 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
67 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
68 help
69 Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
70
71config DVB_USB_AZ6007
72 tristate "AzureWave 6007 and clones DVB-T/C USB2.0 support"
73 depends on DVB_USB_V2
74 select DVB_USB_CYPRESS_FIRMWARE
75 select DVB_DRXK if !DVB_FE_CUSTOMISE
76 select MEDIA_TUNER_MT2063 if !DVB_FE_CUSTOMISE
77 help
78 Say Y here to support the AZ6007 receivers like Terratec H7.
79
80config DVB_USB_CE6230
81 tristate "Intel CE6230 DVB-T USB2.0 support"
82 depends on DVB_USB_V2
83 select DVB_ZL10353
84 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
85 help
86 Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
87
88config DVB_USB_EC168
89 tristate "E3C EC168 DVB-T USB2.0 support"
90 depends on DVB_USB_V2
91 select DVB_EC100
92 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
93 help
94 Say Y here to support the E3C EC168 DVB-T USB2.0 receiver.
95
96config DVB_USB_GL861
97 tristate "Genesys Logic GL861 USB2.0 support"
98 depends on DVB_USB_V2
99 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
100 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
101 help
102 Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
103 receiver with USB ID 0db0:5581.
104
105config DVB_USB_IT913X
106 tristate "ITE IT913X DVB-T USB2.0 support"
107 depends on DVB_USB_V2
108 select DVB_IT913X_FE
109 help
110 Say Y here to support the ITE IT913X DVB-T USB2.0
111
112config DVB_USB_LME2510
113 tristate "LME DM04/QQBOX DVB-S USB2.0 support"
114 depends on DVB_USB_V2
115 select DVB_TDA10086 if !DVB_FE_CUSTOMISE
116 select DVB_TDA826X if !DVB_FE_CUSTOMISE
117 select DVB_STV0288 if !DVB_FE_CUSTOMISE
118 select DVB_IX2505V if !DVB_FE_CUSTOMISE
119 select DVB_STV0299 if !DVB_FE_CUSTOMISE
120 select DVB_PLL if !DVB_FE_CUSTOMISE
121 select DVB_M88RS2000 if !DVB_FE_CUSTOMISE
122 help
123 Say Y here to support the LME DM04/QQBOX DVB-S USB2.0
124
125config DVB_USB_MXL111SF
126 tristate "MxL111SF DTV USB2.0 support"
127 depends on DVB_USB_V2
128 select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
129 select DVB_LG2160 if !DVB_FE_CUSTOMISE
130 select VIDEO_TVEEPROM
131 help
132 Say Y here to support the MxL111SF USB2.0 DTV receiver.
133
134config DVB_USB_RTL28XXU
135 tristate "Realtek RTL28xxU DVB USB support"
136 depends on DVB_USB_V2 && EXPERIMENTAL
137 select DVB_RTL2830
138 select DVB_RTL2832
139 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
140 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
141 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
142 select MEDIA_TUNER_FC0012 if !MEDIA_TUNER_CUSTOMISE
143 select MEDIA_TUNER_FC0013 if !MEDIA_TUNER_CUSTOMISE
144 help
145 Say Y here to support the Realtek RTL28xxU DVB USB receiver.
146
diff --git a/drivers/media/usb/dvb-usb-v2/Makefile b/drivers/media/usb/dvb-usb-v2/Makefile
new file mode 100644
index 000000000000..24248b3acd4f
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/Makefile
@@ -0,0 +1,48 @@
1dvb_usbv2-objs = dvb_usb_core.o dvb_usb_urb.o usb_urb.o
2obj-$(CONFIG_DVB_USB_V2) += dvb_usbv2.o
3
4dvb_usb_cypress_firmware-objs = cypress_firmware.o
5obj-$(CONFIG_DVB_USB_CYPRESS_FIRMWARE) += dvb_usb_cypress_firmware.o
6
7dvb-usb-af9015-objs = af9015.o
8obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o
9
10dvb-usb-af9035-objs = af9035.o
11obj-$(CONFIG_DVB_USB_AF9035) += dvb-usb-af9035.o
12
13dvb-usb-anysee-objs = anysee.o
14obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
15
16dvb-usb-au6610-objs = au6610.o
17obj-$(CONFIG_DVB_USB_AU6610) += dvb-usb-au6610.o
18
19dvb-usb-az6007-objs = az6007.o
20obj-$(CONFIG_DVB_USB_AZ6007) += dvb-usb-az6007.o
21
22dvb-usb-ce6230-objs = ce6230.o
23obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
24
25dvb-usb-ec168-objs = ec168.o
26obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o
27
28dvb-usb-it913x-objs = it913x.o
29obj-$(CONFIG_DVB_USB_IT913X) += dvb-usb-it913x.o
30
31dvb-usb-lmedm04-objs = lmedm04.o
32obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
33
34dvb-usb-gl861-objs = gl861.o
35obj-$(CONFIG_DVB_USB_GL861) += dvb-usb-gl861.o
36
37dvb-usb-mxl111sf-objs = mxl111sf.o mxl111sf-phy.o mxl111sf-i2c.o mxl111sf-gpio.o
38obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o
39obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o
40obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
41
42dvb-usb-rtl28xxu-objs = rtl28xxu.o
43obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
44
45ccflags-y += -I$(srctree)/drivers/media/dvb-core
46ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
47ccflags-y += -I$(srctree)/drivers/media/common/tuners
48
diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c
new file mode 100644
index 000000000000..e77429b37a7d
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/af9015.c
@@ -0,0 +1,1434 @@
1/*
2 * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * Thanks to Afatech who kindly provided information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#include "af9015.h"
25
26static int dvb_usb_af9015_debug;
27module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
28MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
29static int dvb_usb_af9015_remote;
30module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
31MODULE_PARM_DESC(remote, "select remote");
32DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
33
34static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
35{
36#define BUF_LEN 63
37#define REQ_HDR_LEN 8 /* send header size */
38#define ACK_HDR_LEN 2 /* rece header size */
39 struct af9015_state *state = d_to_priv(d);
40 int ret, wlen, rlen;
41 u8 buf[BUF_LEN];
42 u8 write = 1;
43
44 buf[0] = req->cmd;
45 buf[1] = state->seq++;
46 buf[2] = req->i2c_addr;
47 buf[3] = req->addr >> 8;
48 buf[4] = req->addr & 0xff;
49 buf[5] = req->mbox;
50 buf[6] = req->addr_len;
51 buf[7] = req->data_len;
52
53 switch (req->cmd) {
54 case GET_CONFIG:
55 case READ_MEMORY:
56 case RECONNECT_USB:
57 write = 0;
58 break;
59 case READ_I2C:
60 write = 0;
61 buf[2] |= 0x01; /* set I2C direction */
62 case WRITE_I2C:
63 buf[0] = READ_WRITE_I2C;
64 break;
65 case WRITE_MEMORY:
66 if (((req->addr & 0xff00) == 0xff00) ||
67 ((req->addr & 0xff00) == 0xae00))
68 buf[0] = WRITE_VIRTUAL_MEMORY;
69 case WRITE_VIRTUAL_MEMORY:
70 case COPY_FIRMWARE:
71 case DOWNLOAD_FIRMWARE:
72 case BOOT:
73 break;
74 default:
75 err("unknown command:%d", req->cmd);
76 ret = -1;
77 goto error;
78 }
79
80 /* buffer overflow check */
81 if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
82 (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
83 err("too much data; cmd:%d len:%d", req->cmd, req->data_len);
84 ret = -EINVAL;
85 goto error;
86 }
87
88 /* write receives seq + status = 2 bytes
89 read receives seq + status + data = 2 + N bytes */
90 wlen = REQ_HDR_LEN;
91 rlen = ACK_HDR_LEN;
92 if (write) {
93 wlen += req->data_len;
94 memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
95 } else {
96 rlen += req->data_len;
97 }
98
99 /* no ack for these packets */
100 if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
101 rlen = 0;
102
103 ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen);
104 if (ret)
105 goto error;
106
107 /* check status */
108 if (rlen && buf[1]) {
109 err("command failed:%d", buf[1]);
110 ret = -1;
111 goto error;
112 }
113
114 /* read request, copy returned data to return buf */
115 if (!write)
116 memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);
117error:
118 return ret;
119}
120
121static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val,
122 u8 len)
123{
124 struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
125 val};
126 return af9015_ctrl_msg(d, &req);
127}
128
129static int af9015_read_regs(struct dvb_usb_device *d, u16 addr, u8 *val, u8 len)
130{
131 struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len,
132 val};
133 return af9015_ctrl_msg(d, &req);
134}
135
136static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val)
137{
138 return af9015_write_regs(d, addr, &val, 1);
139}
140
141static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val)
142{
143 return af9015_read_regs(d, addr, val, 1);
144}
145
146static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
147 u8 val)
148{
149 struct af9015_state *state = d_to_priv(d);
150 struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val};
151
152 if (addr == state->af9013_config[0].i2c_addr ||
153 addr == state->af9013_config[1].i2c_addr)
154 req.addr_len = 3;
155
156 return af9015_ctrl_msg(d, &req);
157}
158
159static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg,
160 u8 *val)
161{
162 struct af9015_state *state = d_to_priv(d);
163 struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val};
164
165 if (addr == state->af9013_config[0].i2c_addr ||
166 addr == state->af9013_config[1].i2c_addr)
167 req.addr_len = 3;
168
169 return af9015_ctrl_msg(d, &req);
170}
171
172static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op)
173{
174 int ret;
175 u8 val, mask = 0x01;
176
177 ret = af9015_read_reg(d, addr, &val);
178 if (ret)
179 return ret;
180
181 mask <<= bit;
182 if (op) {
183 /* set bit */
184 val |= mask;
185 } else {
186 /* clear bit */
187 mask ^= 0xff;
188 val &= mask;
189 }
190
191 return af9015_write_reg(d, addr, val);
192}
193
194static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
195{
196 return af9015_do_reg_bit(d, addr, bit, 1);
197}
198
199static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit)
200{
201 return af9015_do_reg_bit(d, addr, bit, 0);
202}
203
204static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
205 int num)
206{
207 struct dvb_usb_device *d = i2c_get_adapdata(adap);
208 struct af9015_state *state = d_to_priv(d);
209 int ret = 0, i = 0;
210 u16 addr;
211 u8 uninitialized_var(mbox), addr_len;
212 struct req_t req;
213
214/*
215The bus lock is needed because there is two tuners both using same I2C-address.
216Due to that the only way to select correct tuner is use demodulator I2C-gate.
217
218................................................
219. AF9015 includes integrated AF9013 demodulator.
220. ____________ ____________ . ____________
221.| uC | | demod | . | tuner |
222.|------------| |------------| . |------------|
223.| AF9015 | | AF9013/5 | . | MXL5003 |
224.| |--+----I2C-------|-----/ -----|-.-----I2C-------| |
225.| | | | addr 0x38 | . | addr 0xc6 |
226.|____________| | |____________| . |____________|
227.................|..............................
228 | ____________ ____________
229 | | demod | | tuner |
230 | |------------| |------------|
231 | | AF9013 | | MXL5003 |
232 +----I2C-------|-----/ -----|-------I2C-------| |
233 | addr 0x3a | | addr 0xc6 |
234 |____________| |____________|
235*/
236 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
237 return -EAGAIN;
238
239 while (i < num) {
240 if (msg[i].addr == state->af9013_config[0].i2c_addr ||
241 msg[i].addr == state->af9013_config[1].i2c_addr) {
242 addr = msg[i].buf[0] << 8;
243 addr += msg[i].buf[1];
244 mbox = msg[i].buf[2];
245 addr_len = 3;
246 } else {
247 addr = msg[i].buf[0];
248 addr_len = 1;
249 /* mbox is don't care in that case */
250 }
251
252 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
253 if (msg[i].len > 3 || msg[i+1].len > 61) {
254 ret = -EOPNOTSUPP;
255 goto error;
256 }
257 if (msg[i].addr == state->af9013_config[0].i2c_addr)
258 req.cmd = READ_MEMORY;
259 else
260 req.cmd = READ_I2C;
261 req.i2c_addr = msg[i].addr;
262 req.addr = addr;
263 req.mbox = mbox;
264 req.addr_len = addr_len;
265 req.data_len = msg[i+1].len;
266 req.data = &msg[i+1].buf[0];
267 ret = af9015_ctrl_msg(d, &req);
268 i += 2;
269 } else if (msg[i].flags & I2C_M_RD) {
270 if (msg[i].len > 61) {
271 ret = -EOPNOTSUPP;
272 goto error;
273 }
274 if (msg[i].addr == state->af9013_config[0].i2c_addr) {
275 ret = -EINVAL;
276 goto error;
277 }
278 req.cmd = READ_I2C;
279 req.i2c_addr = msg[i].addr;
280 req.addr = addr;
281 req.mbox = mbox;
282 req.addr_len = addr_len;
283 req.data_len = msg[i].len;
284 req.data = &msg[i].buf[0];
285 ret = af9015_ctrl_msg(d, &req);
286 i += 1;
287 } else {
288 if (msg[i].len > 21) {
289 ret = -EOPNOTSUPP;
290 goto error;
291 }
292 if (msg[i].addr == state->af9013_config[0].i2c_addr)
293 req.cmd = WRITE_MEMORY;
294 else
295 req.cmd = WRITE_I2C;
296 req.i2c_addr = msg[i].addr;
297 req.addr = addr;
298 req.mbox = mbox;
299 req.addr_len = addr_len;
300 req.data_len = msg[i].len-addr_len;
301 req.data = &msg[i].buf[addr_len];
302 ret = af9015_ctrl_msg(d, &req);
303 i += 1;
304 }
305 if (ret)
306 goto error;
307
308 }
309 ret = i;
310
311error:
312 mutex_unlock(&d->i2c_mutex);
313
314 return ret;
315}
316
317static u32 af9015_i2c_func(struct i2c_adapter *adapter)
318{
319 return I2C_FUNC_I2C;
320}
321
322static struct i2c_algorithm af9015_i2c_algo = {
323 .master_xfer = af9015_i2c_xfer,
324 .functionality = af9015_i2c_func,
325};
326
327static int af9015_identify_state(struct dvb_usb_device *d, const char **name)
328{
329 int ret;
330 u8 reply;
331 struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply};
332
333 ret = af9015_ctrl_msg(d, &req);
334 if (ret)
335 return ret;
336
337 deb_info("%s: reply:%02x\n", __func__, reply);
338 if (reply == 0x02)
339 ret = WARM;
340 else
341 ret = COLD;
342
343 return ret;
344}
345
346static int af9015_download_firmware(struct dvb_usb_device *d,
347 const struct firmware *fw)
348{
349 struct af9015_state *state = d_to_priv(d);
350 int i, len, remaining, ret;
351 struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
352 u16 checksum = 0;
353
354 deb_info("%s:\n", __func__);
355
356 /* calc checksum */
357 for (i = 0; i < fw->size; i++)
358 checksum += fw->data[i];
359
360 state->firmware_size = fw->size;
361 state->firmware_checksum = checksum;
362
363 #define FW_ADDR 0x5100 /* firmware start address */
364 #define LEN_MAX 55 /* max packet size */
365 for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
366 len = remaining;
367 if (len > LEN_MAX)
368 len = LEN_MAX;
369
370 req.data_len = len;
371 req.data = (u8 *) &fw->data[fw->size - remaining];
372 req.addr = FW_ADDR + fw->size - remaining;
373
374 ret = af9015_ctrl_msg(d, &req);
375 if (ret) {
376 err("firmware download failed:%d", ret);
377 goto error;
378 }
379 }
380
381 /* firmware loaded, request boot */
382 req.cmd = BOOT;
383 req.data_len = 0;
384 ret = af9015_ctrl_msg(d, &req);
385 if (ret) {
386 err("firmware boot failed:%d", ret);
387 goto error;
388 }
389
390error:
391 return ret;
392}
393
394/* hash (and dump) eeprom */
395static int af9015_eeprom_hash(struct dvb_usb_device *d)
396{
397 struct af9015_state *state = d_to_priv(d);
398 int ret;
399 static const unsigned int eeprom_size = 256;
400 unsigned int reg;
401 u8 val, *eeprom;
402 struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
403
404 eeprom = kmalloc(eeprom_size, GFP_KERNEL);
405 if (eeprom == NULL)
406 return -ENOMEM;
407
408 for (reg = 0; reg < eeprom_size; reg++) {
409 req.addr = reg;
410 ret = af9015_ctrl_msg(d, &req);
411 if (ret)
412 goto free;
413
414 eeprom[reg] = val;
415 }
416
417 if (dvb_usb_af9015_debug & 0x01)
418 print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, eeprom,
419 eeprom_size);
420
421 BUG_ON(eeprom_size % 4);
422
423 state->eeprom_sum = 0;
424 for (reg = 0; reg < eeprom_size / sizeof(u32); reg++) {
425 state->eeprom_sum *= GOLDEN_RATIO_PRIME_32;
426 state->eeprom_sum += le32_to_cpu(((u32 *)eeprom)[reg]);
427 }
428
429 deb_info("%s: eeprom sum=%.8x\n", __func__, state->eeprom_sum);
430
431 ret = 0;
432free:
433 kfree(eeprom);
434 return ret;
435}
436
437static int af9015_read_config(struct dvb_usb_device *d)
438{
439 struct af9015_state *state = d_to_priv(d);
440 int ret;
441 u8 val, i, offset = 0;
442 struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val};
443
444 deb_info("%s:\n", __func__);
445
446 /* IR remote controller */
447 req.addr = AF9015_EEPROM_IR_MODE;
448 /* first message will timeout often due to possible hw bug */
449 for (i = 0; i < 4; i++) {
450 ret = af9015_ctrl_msg(d, &req);
451 if (!ret)
452 break;
453 }
454 if (ret)
455 goto error;
456
457 ret = af9015_eeprom_hash(d);
458 if (ret)
459 goto error;
460
461 deb_info("%s: IR mode=%d\n", __func__, val);
462 state->ir_mode = val;
463
464 /* TS mode - one or two receivers */
465 req.addr = AF9015_EEPROM_TS_MODE;
466 ret = af9015_ctrl_msg(d, &req);
467 if (ret)
468 goto error;
469
470 state->dual_mode = val;
471 deb_info("%s: TS mode=%d\n", __func__, state->dual_mode);
472
473 /* disable 2nd adapter because we don't have PID-filters */
474 if (d->udev->speed == USB_SPEED_FULL)
475 state->dual_mode = 0;
476
477 if (state->dual_mode) {
478 /* read 2nd demodulator I2C address */
479 req.addr = AF9015_EEPROM_DEMOD2_I2C;
480 ret = af9015_ctrl_msg(d, &req);
481 if (ret)
482 goto error;
483
484 state->af9013_config[1].i2c_addr = val;
485 }
486
487 for (i = 0; i < state->dual_mode + 1; i++) {
488 if (i == 1)
489 offset = AF9015_EEPROM_OFFSET;
490 /* xtal */
491 req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset;
492 ret = af9015_ctrl_msg(d, &req);
493 if (ret)
494 goto error;
495 switch (val) {
496 case 0:
497 state->af9013_config[i].clock = 28800000;
498 break;
499 case 1:
500 state->af9013_config[i].clock = 20480000;
501 break;
502 case 2:
503 state->af9013_config[i].clock = 28000000;
504 break;
505 case 3:
506 state->af9013_config[i].clock = 25000000;
507 break;
508 };
509 deb_info("%s: [%d] xtal=%d set clock=%d\n", __func__, i,
510 val, state->af9013_config[i].clock);
511
512 /* IF frequency */
513 req.addr = AF9015_EEPROM_IF1H + offset;
514 ret = af9015_ctrl_msg(d, &req);
515 if (ret)
516 goto error;
517
518 state->af9013_config[i].if_frequency = val << 8;
519
520 req.addr = AF9015_EEPROM_IF1L + offset;
521 ret = af9015_ctrl_msg(d, &req);
522 if (ret)
523 goto error;
524
525 state->af9013_config[i].if_frequency += val;
526 state->af9013_config[i].if_frequency *= 1000;
527 deb_info("%s: [%d] IF frequency=%d\n", __func__, i,
528 state->af9013_config[i].if_frequency);
529
530 /* MT2060 IF1 */
531 req.addr = AF9015_EEPROM_MT2060_IF1H + offset;
532 ret = af9015_ctrl_msg(d, &req);
533 if (ret)
534 goto error;
535 state->mt2060_if1[i] = val << 8;
536 req.addr = AF9015_EEPROM_MT2060_IF1L + offset;
537 ret = af9015_ctrl_msg(d, &req);
538 if (ret)
539 goto error;
540 state->mt2060_if1[i] += val;
541 deb_info("%s: [%d] MT2060 IF1=%d\n", __func__, i,
542 state->mt2060_if1[i]);
543
544 /* tuner */
545 req.addr = AF9015_EEPROM_TUNER_ID1 + offset;
546 ret = af9015_ctrl_msg(d, &req);
547 if (ret)
548 goto error;
549 switch (val) {
550 case AF9013_TUNER_ENV77H11D5:
551 case AF9013_TUNER_MT2060:
552 case AF9013_TUNER_QT1010:
553 case AF9013_TUNER_UNKNOWN:
554 case AF9013_TUNER_MT2060_2:
555 case AF9013_TUNER_TDA18271:
556 case AF9013_TUNER_QT1010A:
557 case AF9013_TUNER_TDA18218:
558 state->af9013_config[i].spec_inv = 1;
559 break;
560 case AF9013_TUNER_MXL5003D:
561 case AF9013_TUNER_MXL5005D:
562 case AF9013_TUNER_MXL5005R:
563 case AF9013_TUNER_MXL5007T:
564 state->af9013_config[i].spec_inv = 0;
565 break;
566 case AF9013_TUNER_MC44S803:
567 state->af9013_config[i].gpio[1] = AF9013_GPIO_LO;
568 state->af9013_config[i].spec_inv = 1;
569 break;
570 default:
571 warn("tuner id=%d not supported, please report!", val);
572 return -ENODEV;
573 };
574
575 state->af9013_config[i].tuner = val;
576 deb_info("%s: [%d] tuner id=%d\n", __func__, i, val);
577 }
578
579error:
580 if (ret)
581 err("eeprom read failed=%d", ret);
582
583 /* AverMedia AVerTV Volar Black HD (A850) device have bad EEPROM
584 content :-( Override some wrong values here. Ditto for the
585 AVerTV Red HD+ (A850T) device. */
586 if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA &&
587 ((le16_to_cpu(d->udev->descriptor.idProduct) ==
588 USB_PID_AVERMEDIA_A850) ||
589 (le16_to_cpu(d->udev->descriptor.idProduct) ==
590 USB_PID_AVERMEDIA_A850T))) {
591 deb_info("%s: AverMedia A850: overriding config\n", __func__);
592 /* disable dual mode */
593 state->dual_mode = 0;
594
595 /* set correct IF */
596 state->af9013_config[0].if_frequency = 4570000;
597 }
598
599 return ret;
600}
601
602static int af9015_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
603 struct usb_data_stream_properties *stream)
604{
605 deb_info("%s: adap=%d\n", __func__, fe_to_adap(fe)->id);
606
607 if (fe_to_d(fe)->udev->speed == USB_SPEED_FULL)
608 stream->u.bulk.buffersize = TS_USB11_FRAME_SIZE;
609
610 return 0;
611}
612
613static int af9015_get_adapter_count(struct dvb_usb_device *d)
614{
615 struct af9015_state *state = d_to_priv(d);
616 return state->dual_mode + 1;
617}
618
619/* override demod callbacks for resource locking */
620static int af9015_af9013_set_frontend(struct dvb_frontend *fe)
621{
622 int ret;
623 struct af9015_state *state = fe_to_priv(fe);
624
625 if (mutex_lock_interruptible(&state->fe_mutex))
626 return -EAGAIN;
627
628 ret = state->set_frontend[fe_to_adap(fe)->id](fe);
629
630 mutex_unlock(&state->fe_mutex);
631
632 return ret;
633}
634
635/* override demod callbacks for resource locking */
636static int af9015_af9013_read_status(struct dvb_frontend *fe,
637 fe_status_t *status)
638{
639 int ret;
640 struct af9015_state *state = fe_to_priv(fe);
641
642 if (mutex_lock_interruptible(&state->fe_mutex))
643 return -EAGAIN;
644
645 ret = state->read_status[fe_to_adap(fe)->id](fe, status);
646
647 mutex_unlock(&state->fe_mutex);
648
649 return ret;
650}
651
652/* override demod callbacks for resource locking */
653static int af9015_af9013_init(struct dvb_frontend *fe)
654{
655 int ret;
656 struct af9015_state *state = fe_to_priv(fe);
657
658 if (mutex_lock_interruptible(&state->fe_mutex))
659 return -EAGAIN;
660
661 ret = state->init[fe_to_adap(fe)->id](fe);
662
663 mutex_unlock(&state->fe_mutex);
664
665 return ret;
666}
667
668/* override demod callbacks for resource locking */
669static int af9015_af9013_sleep(struct dvb_frontend *fe)
670{
671 int ret;
672 struct af9015_state *state = fe_to_priv(fe);
673
674 if (mutex_lock_interruptible(&state->fe_mutex))
675 return -EAGAIN;
676
677 ret = state->sleep[fe_to_adap(fe)->id](fe);
678
679 mutex_unlock(&state->fe_mutex);
680
681 return ret;
682}
683
684/* override tuner callbacks for resource locking */
685static int af9015_tuner_init(struct dvb_frontend *fe)
686{
687 int ret;
688 struct af9015_state *state = fe_to_priv(fe);
689
690 if (mutex_lock_interruptible(&state->fe_mutex))
691 return -EAGAIN;
692
693 ret = state->tuner_init[fe_to_adap(fe)->id](fe);
694
695 mutex_unlock(&state->fe_mutex);
696
697 return ret;
698}
699
700/* override tuner callbacks for resource locking */
701static int af9015_tuner_sleep(struct dvb_frontend *fe)
702{
703 int ret;
704 struct af9015_state *state = fe_to_priv(fe);
705
706 if (mutex_lock_interruptible(&state->fe_mutex))
707 return -EAGAIN;
708
709 ret = state->tuner_sleep[fe_to_adap(fe)->id](fe);
710
711 mutex_unlock(&state->fe_mutex);
712
713 return ret;
714}
715
716static int af9015_copy_firmware(struct dvb_usb_device *d)
717{
718 struct af9015_state *state = d_to_priv(d);
719 int ret;
720 u8 fw_params[4];
721 u8 val, i;
722 struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params),
723 fw_params };
724 deb_info("%s:\n", __func__);
725
726 fw_params[0] = state->firmware_size >> 8;
727 fw_params[1] = state->firmware_size & 0xff;
728 fw_params[2] = state->firmware_checksum >> 8;
729 fw_params[3] = state->firmware_checksum & 0xff;
730
731 /* wait 2nd demodulator ready */
732 msleep(100);
733
734 ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr,
735 0x98be, &val);
736 if (ret)
737 goto error;
738 else
739 deb_info("%s: firmware status:%02x\n", __func__, val);
740
741 if (val == 0x0c) /* fw is running, no need for download */
742 goto exit;
743
744 /* set I2C master clock to fast (to speed up firmware copy) */
745 ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */
746 if (ret)
747 goto error;
748
749 msleep(50);
750
751 /* copy firmware */
752 ret = af9015_ctrl_msg(d, &req);
753 if (ret)
754 err("firmware copy cmd failed:%d", ret);
755 deb_info("%s: firmware copy done\n", __func__);
756
757 /* set I2C master clock back to normal */
758 ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */
759 if (ret)
760 goto error;
761
762 /* request boot firmware */
763 ret = af9015_write_reg_i2c(d, state->af9013_config[1].i2c_addr,
764 0xe205, 1);
765 deb_info("%s: firmware boot cmd status:%d\n", __func__, ret);
766 if (ret)
767 goto error;
768
769 for (i = 0; i < 15; i++) {
770 msleep(100);
771
772 /* check firmware status */
773 ret = af9015_read_reg_i2c(d, state->af9013_config[1].i2c_addr,
774 0x98be, &val);
775 deb_info("%s: firmware status cmd status:%d fw status:%02x\n",
776 __func__, ret, val);
777 if (ret)
778 goto error;
779
780 if (val == 0x0c || val == 0x04) /* success or fail */
781 break;
782 }
783
784 if (val == 0x04) {
785 err("firmware did not run");
786 ret = -1;
787 } else if (val != 0x0c) {
788 err("firmware boot timeout");
789 ret = -1;
790 }
791
792error:
793exit:
794 return ret;
795}
796
797static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
798{
799 int ret;
800 struct af9015_state *state = adap_to_priv(adap);
801
802 if (adap->id == 0) {
803 state->af9013_config[0].ts_mode = AF9013_TS_USB;
804 memcpy(state->af9013_config[0].api_version, "\x0\x1\x9\x0", 4);
805 state->af9013_config[0].gpio[0] = AF9013_GPIO_HI;
806 state->af9013_config[0].gpio[3] = AF9013_GPIO_TUNER_ON;
807 } else if (adap->id == 1) {
808 state->af9013_config[1].ts_mode = AF9013_TS_SERIAL;
809 memcpy(state->af9013_config[1].api_version, "\x0\x1\x9\x0", 4);
810 state->af9013_config[1].gpio[0] = AF9013_GPIO_TUNER_ON;
811 state->af9013_config[1].gpio[1] = AF9013_GPIO_LO;
812
813 /* copy firmware to 2nd demodulator */
814 if (state->dual_mode) {
815 ret = af9015_copy_firmware(adap_to_d(adap));
816 if (ret) {
817 err("firmware copy to 2nd frontend " \
818 "failed, will disable it");
819 state->dual_mode = 0;
820 return -ENODEV;
821 }
822 } else {
823 return -ENODEV;
824 }
825 }
826
827 /* attach demodulator */
828 adap->fe[0] = dvb_attach(af9013_attach,
829 &state->af9013_config[adap->id], &adap_to_d(adap)->i2c_adap);
830
831 /*
832 * AF9015 firmware does not like if it gets interrupted by I2C adapter
833 * request on some critical phases. During normal operation I2C adapter
834 * is used only 2nd demodulator and tuner on dual tuner devices.
835 * Override demodulator callbacks and use mutex for limit access to
836 * those "critical" paths to keep AF9015 happy.
837 */
838 if (adap->fe[0]) {
839 state->set_frontend[adap->id] =
840 adap->fe[0]->ops.set_frontend;
841 adap->fe[0]->ops.set_frontend =
842 af9015_af9013_set_frontend;
843
844 state->read_status[adap->id] =
845 adap->fe[0]->ops.read_status;
846 adap->fe[0]->ops.read_status =
847 af9015_af9013_read_status;
848
849 state->init[adap->id] = adap->fe[0]->ops.init;
850 adap->fe[0]->ops.init = af9015_af9013_init;
851
852 state->sleep[adap->id] = adap->fe[0]->ops.sleep;
853 adap->fe[0]->ops.sleep = af9015_af9013_sleep;
854 }
855
856 return adap->fe[0] == NULL ? -ENODEV : 0;
857}
858
859static struct mt2060_config af9015_mt2060_config = {
860 .i2c_address = 0xc0,
861 .clock_out = 0,
862};
863
864static struct qt1010_config af9015_qt1010_config = {
865 .i2c_address = 0xc4,
866};
867
868static struct tda18271_config af9015_tda18271_config = {
869 .gate = TDA18271_GATE_DIGITAL,
870 .small_i2c = TDA18271_16_BYTE_CHUNK_INIT,
871};
872
873static struct mxl5005s_config af9015_mxl5003_config = {
874 .i2c_address = 0xc6,
875 .if_freq = IF_FREQ_4570000HZ,
876 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
877 .agc_mode = MXL_SINGLE_AGC,
878 .tracking_filter = MXL_TF_DEFAULT,
879 .rssi_enable = MXL_RSSI_ENABLE,
880 .cap_select = MXL_CAP_SEL_ENABLE,
881 .div_out = MXL_DIV_OUT_4,
882 .clock_out = MXL_CLOCK_OUT_DISABLE,
883 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
884 .top = MXL5005S_TOP_25P2,
885 .mod_mode = MXL_DIGITAL_MODE,
886 .if_mode = MXL_ZERO_IF,
887 .AgcMasterByte = 0x00,
888};
889
890static struct mxl5005s_config af9015_mxl5005_config = {
891 .i2c_address = 0xc6,
892 .if_freq = IF_FREQ_4570000HZ,
893 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
894 .agc_mode = MXL_SINGLE_AGC,
895 .tracking_filter = MXL_TF_OFF,
896 .rssi_enable = MXL_RSSI_ENABLE,
897 .cap_select = MXL_CAP_SEL_ENABLE,
898 .div_out = MXL_DIV_OUT_4,
899 .clock_out = MXL_CLOCK_OUT_DISABLE,
900 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
901 .top = MXL5005S_TOP_25P2,
902 .mod_mode = MXL_DIGITAL_MODE,
903 .if_mode = MXL_ZERO_IF,
904 .AgcMasterByte = 0x00,
905};
906
907static struct mc44s803_config af9015_mc44s803_config = {
908 .i2c_address = 0xc0,
909 .dig_out = 1,
910};
911
912static struct tda18218_config af9015_tda18218_config = {
913 .i2c_address = 0xc0,
914 .i2c_wr_max = 21, /* max wr bytes AF9015 I2C adap can handle at once */
915};
916
917static struct mxl5007t_config af9015_mxl5007t_config = {
918 .xtal_freq_hz = MxL_XTAL_24_MHZ,
919 .if_freq_hz = MxL_IF_4_57_MHZ,
920};
921
922static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
923{
924 struct af9015_state *state = adap_to_priv(adap);
925 int ret;
926 deb_info("%s:\n", __func__);
927
928 switch (state->af9013_config[adap->id].tuner) {
929 case AF9013_TUNER_MT2060:
930 case AF9013_TUNER_MT2060_2:
931 ret = dvb_attach(mt2060_attach, adap->fe[0],
932 &adap_to_d(adap)->i2c_adap, &af9015_mt2060_config,
933 state->mt2060_if1[adap->id])
934 == NULL ? -ENODEV : 0;
935 break;
936 case AF9013_TUNER_QT1010:
937 case AF9013_TUNER_QT1010A:
938 ret = dvb_attach(qt1010_attach, adap->fe[0],
939 &adap_to_d(adap)->i2c_adap,
940 &af9015_qt1010_config) == NULL ? -ENODEV : 0;
941 break;
942 case AF9013_TUNER_TDA18271:
943 ret = dvb_attach(tda18271_attach, adap->fe[0], 0xc0,
944 &adap_to_d(adap)->i2c_adap,
945 &af9015_tda18271_config) == NULL ? -ENODEV : 0;
946 break;
947 case AF9013_TUNER_TDA18218:
948 ret = dvb_attach(tda18218_attach, adap->fe[0],
949 &adap_to_d(adap)->i2c_adap,
950 &af9015_tda18218_config) == NULL ? -ENODEV : 0;
951 break;
952 case AF9013_TUNER_MXL5003D:
953 ret = dvb_attach(mxl5005s_attach, adap->fe[0],
954 &adap_to_d(adap)->i2c_adap,
955 &af9015_mxl5003_config) == NULL ? -ENODEV : 0;
956 break;
957 case AF9013_TUNER_MXL5005D:
958 case AF9013_TUNER_MXL5005R:
959 ret = dvb_attach(mxl5005s_attach, adap->fe[0],
960 &adap_to_d(adap)->i2c_adap,
961 &af9015_mxl5005_config) == NULL ? -ENODEV : 0;
962 break;
963 case AF9013_TUNER_ENV77H11D5:
964 ret = dvb_attach(dvb_pll_attach, adap->fe[0], 0xc0,
965 &adap_to_d(adap)->i2c_adap,
966 DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
967 break;
968 case AF9013_TUNER_MC44S803:
969 ret = dvb_attach(mc44s803_attach, adap->fe[0],
970 &adap_to_d(adap)->i2c_adap,
971 &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
972 break;
973 case AF9013_TUNER_MXL5007T:
974 ret = dvb_attach(mxl5007t_attach, adap->fe[0],
975 &adap_to_d(adap)->i2c_adap,
976 0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0;
977 break;
978 case AF9013_TUNER_UNKNOWN:
979 default:
980 ret = -ENODEV;
981 err("Unknown tuner id:%d",
982 state->af9013_config[adap->id].tuner);
983 }
984
985 if (adap->fe[0]->ops.tuner_ops.init) {
986 state->tuner_init[adap->id] =
987 adap->fe[0]->ops.tuner_ops.init;
988 adap->fe[0]->ops.tuner_ops.init = af9015_tuner_init;
989 }
990
991 if (adap->fe[0]->ops.tuner_ops.sleep) {
992 state->tuner_sleep[adap->id] =
993 adap->fe[0]->ops.tuner_ops.sleep;
994 adap->fe[0]->ops.tuner_ops.sleep = af9015_tuner_sleep;
995 }
996
997 return ret;
998}
999
1000static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
1001{
1002 int ret;
1003 deb_info("%s: onoff:%d\n", __func__, onoff);
1004
1005 if (onoff)
1006 ret = af9015_set_reg_bit(adap_to_d(adap), 0xd503, 0);
1007 else
1008 ret = af9015_clear_reg_bit(adap_to_d(adap), 0xd503, 0);
1009
1010 return ret;
1011}
1012
1013static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
1014 int onoff)
1015{
1016 int ret;
1017 u8 idx;
1018
1019 deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n",
1020 __func__, index, pid, onoff);
1021
1022 ret = af9015_write_reg(adap_to_d(adap), 0xd505, (pid & 0xff));
1023 if (ret)
1024 goto error;
1025
1026 ret = af9015_write_reg(adap_to_d(adap), 0xd506, (pid >> 8));
1027 if (ret)
1028 goto error;
1029
1030 idx = ((index & 0x1f) | (1 << 5));
1031 ret = af9015_write_reg(adap_to_d(adap), 0xd504, idx);
1032
1033error:
1034 return ret;
1035}
1036
1037static int af9015_init_endpoint(struct dvb_usb_device *d)
1038{
1039 struct af9015_state *state = d_to_priv(d);
1040 int ret;
1041 u16 frame_size;
1042 u8 packet_size;
1043 deb_info("%s: USB speed:%d\n", __func__, d->udev->speed);
1044
1045 if (d->udev->speed == USB_SPEED_FULL) {
1046 frame_size = TS_USB11_FRAME_SIZE/4;
1047 packet_size = TS_USB11_MAX_PACKET_SIZE/4;
1048 } else {
1049 frame_size = TS_USB20_FRAME_SIZE/4;
1050 packet_size = TS_USB20_MAX_PACKET_SIZE/4;
1051 }
1052
1053 ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */
1054 if (ret)
1055 goto error;
1056 ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */
1057 if (ret)
1058 goto error;
1059 ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */
1060 if (ret)
1061 goto error;
1062 ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */
1063 if (ret)
1064 goto error;
1065 ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */
1066 if (ret)
1067 goto error;
1068 if (state->dual_mode) {
1069 ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */
1070 if (ret)
1071 goto error;
1072 }
1073 ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */
1074 if (ret)
1075 goto error;
1076 if (state->dual_mode) {
1077 ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */
1078 if (ret)
1079 goto error;
1080 }
1081 /* EP4 xfer length */
1082 ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff);
1083 if (ret)
1084 goto error;
1085 ret = af9015_write_reg(d, 0xdd89, frame_size >> 8);
1086 if (ret)
1087 goto error;
1088 /* EP5 xfer length */
1089 ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff);
1090 if (ret)
1091 goto error;
1092 ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8);
1093 if (ret)
1094 goto error;
1095 ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */
1096 if (ret)
1097 goto error;
1098 ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */
1099 if (ret)
1100 goto error;
1101 ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */
1102 if (ret)
1103 goto error;
1104 if (state->dual_mode) {
1105 ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */
1106 if (ret)
1107 goto error;
1108 }
1109
1110 /* enable / disable mp2if2 */
1111 if (state->dual_mode)
1112 ret = af9015_set_reg_bit(d, 0xd50b, 0);
1113 else
1114 ret = af9015_clear_reg_bit(d, 0xd50b, 0);
1115
1116error:
1117 if (ret)
1118 err("endpoint init failed:%d", ret);
1119 return ret;
1120}
1121
1122static int af9015_init(struct dvb_usb_device *d)
1123{
1124 struct af9015_state *state = d_to_priv(d);
1125 int ret;
1126 deb_info("%s:\n", __func__);
1127
1128 mutex_init(&state->fe_mutex);
1129
1130 /* init RC canary */
1131 ret = af9015_write_reg(d, 0x98e9, 0xff);
1132 if (ret)
1133 goto error;
1134
1135 ret = af9015_init_endpoint(d);
1136 if (ret)
1137 goto error;
1138
1139error:
1140 return ret;
1141}
1142
1143struct af9015_rc_setup {
1144 unsigned int id;
1145 char *rc_codes;
1146};
1147
1148static char *af9015_rc_setup_match(unsigned int id,
1149 const struct af9015_rc_setup *table)
1150{
1151 for (; table->rc_codes; table++)
1152 if (table->id == id)
1153 return table->rc_codes;
1154 return NULL;
1155}
1156
1157static const struct af9015_rc_setup af9015_rc_setup_modparam[] = {
1158 { AF9015_REMOTE_A_LINK_DTU_M, RC_MAP_ALINK_DTU_M },
1159 { AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, RC_MAP_MSI_DIGIVOX_II },
1160 { AF9015_REMOTE_MYGICTV_U718, RC_MAP_TOTAL_MEDIA_IN_HAND },
1161 { AF9015_REMOTE_DIGITTRADE_DVB_T, RC_MAP_DIGITTRADE },
1162 { AF9015_REMOTE_AVERMEDIA_KS, RC_MAP_AVERMEDIA_RM_KS },
1163 { }
1164};
1165
1166static const struct af9015_rc_setup af9015_rc_setup_hashes[] = {
1167 { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II },
1168 { 0xa3703d00, RC_MAP_ALINK_DTU_M },
1169 { 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */
1170 { 0x5d49e3db, RC_MAP_DIGITTRADE }, /* LC-Power LC-USB-DVBT */
1171 { }
1172};
1173
1174static int af9015_rc_query(struct dvb_usb_device *d)
1175{
1176 struct af9015_state *state = d_to_priv(d);
1177 int ret;
1178 u8 buf[17];
1179
1180 deb_info("%s:\n", __func__);
1181
1182 /* read registers needed to detect remote controller code */
1183 ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
1184 if (ret)
1185 goto error;
1186
1187 /* If any of these are non-zero, assume invalid data */
1188 if (buf[1] || buf[2] || buf[3])
1189 return ret;
1190
1191 /* Check for repeat of previous code */
1192 if ((state->rc_repeat != buf[6] || buf[0]) &&
1193 !memcmp(&buf[12], state->rc_last, 4)) {
1194 deb_rc("%s: key repeated\n", __func__);
1195 rc_keydown(d->rc_dev, state->rc_keycode, 0);
1196 state->rc_repeat = buf[6];
1197 return ret;
1198 }
1199
1200 /* Only process key if canary killed */
1201 if (buf[16] != 0xff && buf[0] != 0x01) {
1202 deb_rc("%s: key pressed %*ph\n", __func__, 4, buf + 12);
1203
1204 /* Reset the canary */
1205 ret = af9015_write_reg(d, 0x98e9, 0xff);
1206 if (ret)
1207 goto error;
1208
1209 /* Remember this key */
1210 memcpy(state->rc_last, &buf[12], 4);
1211 if (buf[14] == (u8) ~buf[15]) {
1212 if (buf[12] == (u8) ~buf[13]) {
1213 /* NEC */
1214 state->rc_keycode = buf[12] << 8 | buf[14];
1215 } else {
1216 /* NEC extended*/
1217 state->rc_keycode = buf[12] << 16 |
1218 buf[13] << 8 | buf[14];
1219 }
1220 } else {
1221 /* 32 bit NEC */
1222 state->rc_keycode = buf[12] << 24 | buf[13] << 16 |
1223 buf[14] << 8 | buf[15];
1224 }
1225 rc_keydown(d->rc_dev, state->rc_keycode, 0);
1226 } else {
1227 deb_rc("%s: no key press\n", __func__);
1228 /* Invalidate last keypress */
1229 /* Not really needed, but helps with debug */
1230 state->rc_last[2] = state->rc_last[3];
1231 }
1232
1233 state->rc_repeat = buf[6];
1234 state->rc_failed = false;
1235
1236error:
1237 if (ret) {
1238 err("%s: failed:%d", __func__, ret);
1239
1240 /* allow random errors as dvb-usb will stop polling on error */
1241 if (!state->rc_failed)
1242 ret = 0;
1243
1244 state->rc_failed = true;
1245 }
1246
1247 return ret;
1248}
1249
1250static int af9015_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
1251{
1252 struct af9015_state *state = d_to_priv(d);
1253 u16 vid = le16_to_cpu(d->udev->descriptor.idVendor);
1254
1255 if (state->ir_mode == AF9015_IR_MODE_DISABLED)
1256 return 0;
1257
1258 /* try to load remote based module param */
1259 if (!rc->map_name)
1260 rc->map_name = af9015_rc_setup_match(dvb_usb_af9015_remote,
1261 af9015_rc_setup_modparam);
1262
1263 /* try to load remote based eeprom hash */
1264 if (!rc->map_name)
1265 rc->map_name = af9015_rc_setup_match(state->eeprom_sum,
1266 af9015_rc_setup_hashes);
1267
1268 /* try to load remote based USB iManufacturer string */
1269 if (!rc->map_name && vid == USB_VID_AFATECH) {
1270 /* Check USB manufacturer and product strings and try
1271 to determine correct remote in case of chip vendor
1272 reference IDs are used.
1273 DO NOT ADD ANYTHING NEW HERE. Use hashes instead. */
1274 char manufacturer[10];
1275 memset(manufacturer, 0, sizeof(manufacturer));
1276 usb_string(d->udev, d->udev->descriptor.iManufacturer,
1277 manufacturer, sizeof(manufacturer));
1278 if (!strcmp("MSI", manufacturer)) {
1279 /* iManufacturer 1 MSI
1280 iProduct 2 MSI K-VOX */
1281 rc->map_name = af9015_rc_setup_match(
1282 AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
1283 af9015_rc_setup_modparam);
1284 }
1285 }
1286
1287 /* load empty to enable rc */
1288 if (!rc->map_name)
1289 rc->map_name = RC_MAP_EMPTY;
1290
1291 rc->allowed_protos = RC_TYPE_NEC;
1292 rc->query = af9015_rc_query;
1293 rc->interval = 500;
1294
1295 return 0;
1296}
1297
1298/* interface 0 is used by DVB-T receiver and
1299 interface 1 is for remote controller (HID) */
1300static struct dvb_usb_device_properties af9015_props = {
1301 .driver_name = KBUILD_MODNAME,
1302 .owner = THIS_MODULE,
1303 .adapter_nr = adapter_nr,
1304 .size_of_priv = sizeof(struct af9015_state),
1305
1306 .generic_bulk_ctrl_endpoint = 0x02,
1307 .generic_bulk_ctrl_endpoint_response = 0x81,
1308
1309 .identify_state = af9015_identify_state,
1310 .firmware = "dvb-usb-af9015.fw",
1311 .download_firmware = af9015_download_firmware,
1312
1313 .i2c_algo = &af9015_i2c_algo,
1314 .read_config = af9015_read_config,
1315 .frontend_attach = af9015_af9013_frontend_attach,
1316 .tuner_attach = af9015_tuner_attach,
1317 .init = af9015_init,
1318 .get_rc_config = af9015_get_rc_config,
1319 .get_stream_config = af9015_get_stream_config,
1320
1321 .get_adapter_count = af9015_get_adapter_count,
1322 .adapter = {
1323 {
1324 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1325 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1326 .pid_filter_count = 32,
1327 .pid_filter = af9015_pid_filter,
1328 .pid_filter_ctrl = af9015_pid_filter_ctrl,
1329
1330 .stream = DVB_USB_STREAM_BULK(0x84, 8, TS_USB20_FRAME_SIZE),
1331 }, {
1332 .stream = DVB_USB_STREAM_BULK(0x85, 8, TS_USB20_FRAME_SIZE),
1333 },
1334 },
1335};
1336
1337static const struct usb_device_id af9015_id_table[] = {
1338 { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015,
1339 &af9015_props, "Afatech AF9015 reference design", NULL) },
1340 { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016,
1341 &af9015_props, "Afatech AF9015 reference design", NULL) },
1342 { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD,
1343 &af9015_props, "Leadtek WinFast DTV Dongle Gold", RC_MAP_LEADTEK_Y04G0051) },
1344 { DVB_USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E,
1345 &af9015_props, "Pinnacle PCTV 71e", NULL) },
1346 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U,
1347 &af9015_props, "KWorld PlusTV Dual DVB-T Stick (DVB-T 399U)", NULL) },
1348 { DVB_USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TINYTWIN,
1349 &af9015_props, "DigitalNow TinyTwin", RC_MAP_AZUREWAVE_AD_TU700) },
1350 { DVB_USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_AZUREWAVE_AD_TU700,
1351 &af9015_props, "TwinHan AzureWave AD-TU700(704J)", RC_MAP_AZUREWAVE_AD_TU700) },
1352 { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2,
1353 &af9015_props, "TerraTec Cinergy T USB XE", NULL) },
1354 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T,
1355 &af9015_props, "KWorld PlusTV Dual DVB-T PCI (DVB-T PC160-2T)", NULL) },
1356 { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X,
1357 &af9015_props, "AVerMedia AVerTV DVB-T Volar X", RC_MAP_AVERMEDIA_M135A) },
1358 { DVB_USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380,
1359 &af9015_props, "Xtensions XD-380", NULL) },
1360 { DVB_USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO,
1361 &af9015_props, "MSI DIGIVOX Duo", RC_MAP_MSI_DIGIVOX_III) },
1362 { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2,
1363 &af9015_props, "Fujitsu-Siemens Slim Mobile USB DVB-T", NULL) },
1364 { DVB_USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2,
1365 &af9015_props, "Telestar Starstick 2", NULL) },
1366 { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309,
1367 &af9015_props, "AVerMedia A309", NULL) },
1368 { DVB_USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III,
1369 &af9015_props, "MSI Digi VOX mini III", RC_MAP_MSI_DIGIVOX_III) },
1370 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U,
1371 &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
1372 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2,
1373 &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
1374 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_3,
1375 &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
1376 { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_TREKSTOR_DVBT,
1377 &af9015_props, "TrekStor DVB-T USB Stick", RC_MAP_TREKSTOR) },
1378 { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850,
1379 &af9015_props, "AverMedia AVerTV Volar Black HD (A850)", NULL) },
1380 { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A805,
1381 &af9015_props, "AverMedia AVerTV Volar GPS 805 (A805)", NULL) },
1382 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_CONCEPTRONIC_CTVDIGRCU,
1383 &af9015_props, "Conceptronic USB2.0 DVB-T CTVDIGRCU V3.0", NULL) },
1384 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_MC810,
1385 &af9015_props, "KWorld Digial MC-810", NULL) },
1386 { DVB_USB_DEVICE(USB_VID_KYE, USB_PID_GENIUS_TVGO_DVB_T03,
1387 &af9015_props, "Genius TVGo DVB-T03", NULL) },
1388 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U_2,
1389 &af9015_props, "KWorld PlusTV Dual DVB-T Stick (DVB-T 399U)", NULL) },
1390 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_T,
1391 &af9015_props, "KWorld PlusTV DVB-T PCI Pro Card (DVB-T PC160-T)", NULL) },
1392 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV20,
1393 &af9015_props, "Sveon STV20 Tuner USB DVB-T HDTV", NULL) },
1394 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_TINYTWIN_2,
1395 &af9015_props, "DigitalNow TinyTwin v2", RC_MAP_DIGITALNOW_TINYTWIN) },
1396 { DVB_USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV2000DS,
1397 &af9015_props, "Leadtek WinFast DTV2000DS", RC_MAP_LEADTEK_Y04G0051) },
1398 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB383_T,
1399 &af9015_props, "KWorld USB DVB-T Stick Mobile (UB383-T)", NULL) },
1400 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_4,
1401 &af9015_props, "KWorld USB DVB-T TV Stick II (VS-DVB-T 395U)", NULL) },
1402 { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A815M,
1403 &af9015_props, "AverMedia AVerTV Volar M (A815Mac)", NULL) },
1404 { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_RC,
1405 &af9015_props, "TerraTec Cinergy T Stick RC", RC_MAP_TERRATEC_SLIM_2) },
1406 { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
1407 &af9015_props, "TerraTec Cinergy T Stick Dual RC", RC_MAP_TERRATEC_SLIM) },
1408 { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T,
1409 &af9015_props, "AverMedia AVerTV Red HD+ (A850T)", NULL) },
1410 { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3,
1411 &af9015_props, "DigitalNow TinyTwin v3", RC_MAP_DIGITALNOW_TINYTWIN) },
1412 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22,
1413 &af9015_props, "Sveon STV22 Dual USB DVB-T Tuner HDTV", RC_MAP_MSI_DIGIVOX_III) },
1414 { }
1415};
1416MODULE_DEVICE_TABLE(usb, af9015_id_table);
1417
1418/* usb specific object needed to register this driver with the usb subsystem */
1419static struct usb_driver af9015_usb_driver = {
1420 .name = KBUILD_MODNAME,
1421 .id_table = af9015_id_table,
1422 .probe = dvb_usbv2_probe,
1423 .disconnect = dvb_usbv2_disconnect,
1424 .suspend = dvb_usbv2_suspend,
1425 .resume = dvb_usbv2_resume,
1426 .no_dynamic_id = 1,
1427 .soft_unbind = 1,
1428};
1429
1430module_usb_driver(af9015_usb_driver);
1431
1432MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1433MODULE_DESCRIPTION("Afatech AF9015 driver");
1434MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/af9015.h b/drivers/media/usb/dvb-usb-v2/af9015.h
new file mode 100644
index 000000000000..c6b304d962ad
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/af9015.h
@@ -0,0 +1,170 @@
1/*
2 * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * Thanks to Afatech who kindly provided information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#ifndef AF9015_H
25#define AF9015_H
26
27#include <linux/hash.h>
28#include "dvb_usb.h"
29#include "af9013.h"
30#include "dvb-pll.h"
31#include "mt2060.h"
32#include "qt1010.h"
33#include "tda18271.h"
34#include "mxl5005s.h"
35#include "mc44s803.h"
36#include "tda18218.h"
37#include "mxl5007t.h"
38
39#define DVB_USB_LOG_PREFIX "af9015"
40
41#ifdef CONFIG_DVB_USB_DEBUG
42#define dprintk(var, level, args...) \
43 do { if ((var & level)) printk(args); } while (0)
44#define DVB_USB_DEBUG_STATUS
45#else
46#define dprintk(args...)
47#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
48#endif
49
50#define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args)
51#define deb_rc(args...) dprintk(dvb_usb_af9015_debug, 0x02, args)
52
53#undef err
54#define err(format, arg...) \
55 printk(KERN_ERR DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
56#undef warn
57#define warn(format, arg...) \
58 printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
59
60/* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0.
61 We use smaller - about 1/4 from the original, 5 and 87. */
62#define TS_PACKET_SIZE 188
63
64#define TS_USB20_PACKET_COUNT 87
65#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
66
67#define TS_USB11_PACKET_COUNT 5
68#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
69
70#define TS_USB20_MAX_PACKET_SIZE 512
71#define TS_USB11_MAX_PACKET_SIZE 64
72
73#define AF9015_I2C_EEPROM 0xa0
74#define AF9015_I2C_DEMOD 0x38
75#define AF9015_USB_TIMEOUT 2000
76
77/* EEPROM locations */
78#define AF9015_EEPROM_IR_MODE 0x18
79#define AF9015_EEPROM_IR_REMOTE_TYPE 0x34
80#define AF9015_EEPROM_TS_MODE 0x31
81#define AF9015_EEPROM_DEMOD2_I2C 0x32
82
83#define AF9015_EEPROM_SAW_BW1 0x35
84#define AF9015_EEPROM_XTAL_TYPE1 0x36
85#define AF9015_EEPROM_SPEC_INV1 0x37
86#define AF9015_EEPROM_IF1L 0x38
87#define AF9015_EEPROM_IF1H 0x39
88#define AF9015_EEPROM_MT2060_IF1L 0x3a
89#define AF9015_EEPROM_MT2060_IF1H 0x3b
90#define AF9015_EEPROM_TUNER_ID1 0x3c
91
92#define AF9015_EEPROM_SAW_BW2 0x45
93#define AF9015_EEPROM_XTAL_TYPE2 0x46
94#define AF9015_EEPROM_SPEC_INV2 0x47
95#define AF9015_EEPROM_IF2L 0x48
96#define AF9015_EEPROM_IF2H 0x49
97#define AF9015_EEPROM_MT2060_IF2L 0x4a
98#define AF9015_EEPROM_MT2060_IF2H 0x4b
99#define AF9015_EEPROM_TUNER_ID2 0x4c
100
101#define AF9015_EEPROM_OFFSET (AF9015_EEPROM_SAW_BW2 - AF9015_EEPROM_SAW_BW1)
102
103struct req_t {
104 u8 cmd; /* [0] */
105 /* seq */ /* [1] */
106 u8 i2c_addr; /* [2] */
107 u16 addr; /* [3|4] */
108 u8 mbox; /* [5] */
109 u8 addr_len; /* [6] */
110 u8 data_len; /* [7] */
111 u8 *data;
112};
113
114enum af9015_cmd {
115 GET_CONFIG = 0x10,
116 DOWNLOAD_FIRMWARE = 0x11,
117 BOOT = 0x13,
118 READ_MEMORY = 0x20,
119 WRITE_MEMORY = 0x21,
120 READ_WRITE_I2C = 0x22,
121 COPY_FIRMWARE = 0x23,
122 RECONNECT_USB = 0x5a,
123 WRITE_VIRTUAL_MEMORY = 0x26,
124 GET_IR_CODE = 0x27,
125 READ_I2C,
126 WRITE_I2C,
127};
128
129enum af9015_ir_mode {
130 AF9015_IR_MODE_DISABLED = 0,
131 AF9015_IR_MODE_HID,
132 AF9015_IR_MODE_RLC,
133 AF9015_IR_MODE_RC6,
134 AF9015_IR_MODE_POLLING, /* just guess */
135};
136
137struct af9015_state {
138 u8 ir_mode;
139 u8 rc_repeat;
140 u32 rc_keycode;
141 u8 rc_last[4];
142 bool rc_failed;
143 u8 dual_mode;
144 u8 seq; /* packet sequence number */
145 u16 mt2060_if1[2];
146 u16 firmware_size;
147 u16 firmware_checksum;
148 u32 eeprom_sum;
149 struct af9013_config af9013_config[2];
150
151 /* for demod callback override */
152 int (*set_frontend[2]) (struct dvb_frontend *fe);
153 int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status);
154 int (*init[2]) (struct dvb_frontend *fe);
155 int (*sleep[2]) (struct dvb_frontend *fe);
156 int (*tuner_init[2]) (struct dvb_frontend *fe);
157 int (*tuner_sleep[2]) (struct dvb_frontend *fe);
158 struct mutex fe_mutex;
159};
160
161enum af9015_remote {
162 AF9015_REMOTE_NONE = 0,
163/* 1 */ AF9015_REMOTE_A_LINK_DTU_M,
164 AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
165 AF9015_REMOTE_MYGICTV_U718,
166 AF9015_REMOTE_DIGITTRADE_DVB_T,
167/* 5 */ AF9015_REMOTE_AVERMEDIA_KS,
168};
169
170#endif
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
new file mode 100644
index 000000000000..bb90b877d07b
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -0,0 +1,1086 @@
1/*
2 * Afatech AF9035 DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
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 along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#include "af9035.h"
23
24DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
25
26static u16 af9035_checksum(const u8 *buf, size_t len)
27{
28 size_t i;
29 u16 checksum = 0;
30
31 for (i = 1; i < len; i++) {
32 if (i % 2)
33 checksum += buf[i] << 8;
34 else
35 checksum += buf[i];
36 }
37 checksum = ~checksum;
38
39 return checksum;
40}
41
42static int af9035_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
43{
44#define BUF_LEN 64
45#define REQ_HDR_LEN 4 /* send header size */
46#define ACK_HDR_LEN 3 /* rece header size */
47#define CHECKSUM_LEN 2
48#define USB_TIMEOUT 2000
49 struct state *state = d_to_priv(d);
50 int ret, wlen, rlen;
51 u8 buf[BUF_LEN];
52 u16 checksum, tmp_checksum;
53
54 /* buffer overflow check */
55 if (req->wlen > (BUF_LEN - REQ_HDR_LEN - CHECKSUM_LEN) ||
56 req->rlen > (BUF_LEN - ACK_HDR_LEN - CHECKSUM_LEN)) {
57 pr_debug("%s: too much data wlen=%d rlen=%d\n", __func__,
58 req->wlen, req->rlen);
59 return -EINVAL;
60 }
61
62 buf[0] = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN - 1;
63 buf[1] = req->mbox;
64 buf[2] = req->cmd;
65 buf[3] = state->seq++;
66 memcpy(&buf[REQ_HDR_LEN], req->wbuf, req->wlen);
67
68 wlen = REQ_HDR_LEN + req->wlen + CHECKSUM_LEN;
69 rlen = ACK_HDR_LEN + req->rlen + CHECKSUM_LEN;
70
71 /* calc and add checksum */
72 checksum = af9035_checksum(buf, buf[0] - 1);
73 buf[buf[0] - 1] = (checksum >> 8);
74 buf[buf[0] - 0] = (checksum & 0xff);
75
76 /* no ack for these packets */
77 if (req->cmd == CMD_FW_DL)
78 rlen = 0;
79
80 ret = dvb_usbv2_generic_rw(d, buf, wlen, buf, rlen);
81 if (ret)
82 goto err;
83
84 /* no ack for those packets */
85 if (req->cmd == CMD_FW_DL)
86 goto exit;
87
88 /* verify checksum */
89 checksum = af9035_checksum(buf, rlen - 2);
90 tmp_checksum = (buf[rlen - 2] << 8) | buf[rlen - 1];
91 if (tmp_checksum != checksum) {
92 pr_err("%s: command=%02x checksum mismatch (%04x != %04x)\n",
93 KBUILD_MODNAME, req->cmd, tmp_checksum,
94 checksum);
95 ret = -EIO;
96 goto err;
97 }
98
99 /* check status */
100 if (buf[2]) {
101 pr_debug("%s: command=%02x failed fw error=%d\n", __func__,
102 req->cmd, buf[2]);
103 ret = -EIO;
104 goto err;
105 }
106
107 /* read request, copy returned data to return buf */
108 if (req->rlen)
109 memcpy(req->rbuf, &buf[ACK_HDR_LEN], req->rlen);
110
111exit:
112 return 0;
113
114err:
115 pr_debug("%s: failed=%d\n", __func__, ret);
116
117 return ret;
118}
119
120/* write multiple registers */
121static int af9035_wr_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
122{
123 u8 wbuf[6 + len];
124 u8 mbox = (reg >> 16) & 0xff;
125 struct usb_req req = { CMD_MEM_WR, mbox, sizeof(wbuf), wbuf, 0, NULL };
126
127 wbuf[0] = len;
128 wbuf[1] = 2;
129 wbuf[2] = 0;
130 wbuf[3] = 0;
131 wbuf[4] = (reg >> 8) & 0xff;
132 wbuf[5] = (reg >> 0) & 0xff;
133 memcpy(&wbuf[6], val, len);
134
135 return af9035_ctrl_msg(d, &req);
136}
137
138/* read multiple registers */
139static int af9035_rd_regs(struct dvb_usb_device *d, u32 reg, u8 *val, int len)
140{
141 u8 wbuf[] = { len, 2, 0, 0, (reg >> 8) & 0xff, reg & 0xff };
142 u8 mbox = (reg >> 16) & 0xff;
143 struct usb_req req = { CMD_MEM_RD, mbox, sizeof(wbuf), wbuf, len, val };
144
145 return af9035_ctrl_msg(d, &req);
146}
147
148/* write single register */
149static int af9035_wr_reg(struct dvb_usb_device *d, u32 reg, u8 val)
150{
151 return af9035_wr_regs(d, reg, &val, 1);
152}
153
154/* read single register */
155static int af9035_rd_reg(struct dvb_usb_device *d, u32 reg, u8 *val)
156{
157 return af9035_rd_regs(d, reg, val, 1);
158}
159
160/* write single register with mask */
161static int af9035_wr_reg_mask(struct dvb_usb_device *d, u32 reg, u8 val,
162 u8 mask)
163{
164 int ret;
165 u8 tmp;
166
167 /* no need for read if whole reg is written */
168 if (mask != 0xff) {
169 ret = af9035_rd_regs(d, reg, &tmp, 1);
170 if (ret)
171 return ret;
172
173 val &= mask;
174 tmp &= ~mask;
175 val |= tmp;
176 }
177
178 return af9035_wr_regs(d, reg, &val, 1);
179}
180
181static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
182 struct i2c_msg msg[], int num)
183{
184 struct dvb_usb_device *d = i2c_get_adapdata(adap);
185 struct state *state = d_to_priv(d);
186 int ret;
187
188 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
189 return -EAGAIN;
190
191 /*
192 * I2C sub header is 5 bytes long. Meaning of those bytes are:
193 * 0: data len
194 * 1: I2C addr << 1
195 * 2: reg addr len
196 * byte 3 and 4 can be used as reg addr
197 * 3: reg addr MSB
198 * used when reg addr len is set to 2
199 * 4: reg addr LSB
200 * used when reg addr len is set to 1 or 2
201 *
202 * For the simplify we do not use register addr at all.
203 * NOTE: As a firmware knows tuner type there is very small possibility
204 * there could be some tuner I2C hacks done by firmware and this may
205 * lead problems if firmware expects those bytes are used.
206 */
207 if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
208 (msg[1].flags & I2C_M_RD)) {
209 if (msg[0].len > 40 || msg[1].len > 40) {
210 /* TODO: correct limits > 40 */
211 ret = -EOPNOTSUPP;
212 } else if (msg[0].addr == state->af9033_config[0].i2c_addr) {
213 /* integrated demod */
214 u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
215 msg[0].buf[2];
216 ret = af9035_rd_regs(d, reg, &msg[1].buf[0],
217 msg[1].len);
218 } else {
219 /* I2C */
220 u8 buf[5 + msg[0].len];
221 struct usb_req req = { CMD_I2C_RD, 0, sizeof(buf),
222 buf, msg[1].len, msg[1].buf };
223 buf[0] = msg[1].len;
224 buf[1] = msg[0].addr << 1;
225 buf[2] = 0x00; /* reg addr len */
226 buf[3] = 0x00; /* reg addr MSB */
227 buf[4] = 0x00; /* reg addr LSB */
228 memcpy(&buf[5], msg[0].buf, msg[0].len);
229 ret = af9035_ctrl_msg(d, &req);
230 }
231 } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
232 if (msg[0].len > 40) {
233 /* TODO: correct limits > 40 */
234 ret = -EOPNOTSUPP;
235 } else if (msg[0].addr == state->af9033_config[0].i2c_addr) {
236 /* integrated demod */
237 u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
238 msg[0].buf[2];
239 ret = af9035_wr_regs(d, reg, &msg[0].buf[3],
240 msg[0].len - 3);
241 } else {
242 /* I2C */
243 u8 buf[5 + msg[0].len];
244 struct usb_req req = { CMD_I2C_WR, 0, sizeof(buf), buf,
245 0, NULL };
246 buf[0] = msg[0].len;
247 buf[1] = msg[0].addr << 1;
248 buf[2] = 0x00; /* reg addr len */
249 buf[3] = 0x00; /* reg addr MSB */
250 buf[4] = 0x00; /* reg addr LSB */
251 memcpy(&buf[5], msg[0].buf, msg[0].len);
252 ret = af9035_ctrl_msg(d, &req);
253 }
254 } else {
255 /*
256 * We support only two kind of I2C transactions:
257 * 1) 1 x read + 1 x write
258 * 2) 1 x write
259 */
260 ret = -EOPNOTSUPP;
261 }
262
263 mutex_unlock(&d->i2c_mutex);
264
265 if (ret < 0)
266 return ret;
267 else
268 return num;
269}
270
271static u32 af9035_i2c_functionality(struct i2c_adapter *adapter)
272{
273 return I2C_FUNC_I2C;
274}
275
276static struct i2c_algorithm af9035_i2c_algo = {
277 .master_xfer = af9035_i2c_master_xfer,
278 .functionality = af9035_i2c_functionality,
279};
280
281static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
282{
283 int ret;
284 u8 wbuf[1] = { 1 };
285 u8 rbuf[4];
286 struct usb_req req = { CMD_FW_QUERYINFO, 0, sizeof(wbuf), wbuf,
287 sizeof(rbuf), rbuf };
288
289 ret = af9035_ctrl_msg(d, &req);
290 if (ret < 0)
291 goto err;
292
293 pr_debug("%s: reply=%*ph\n", __func__, 4, rbuf);
294 if (rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])
295 ret = WARM;
296 else
297 ret = COLD;
298
299 return ret;
300
301err:
302 pr_debug("%s: failed=%d\n", __func__, ret);
303
304 return ret;
305}
306
307static int af9035_download_firmware(struct dvb_usb_device *d,
308 const struct firmware *fw)
309{
310 int ret, i, j, len;
311 u8 wbuf[1];
312 u8 rbuf[4];
313 struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
314 struct usb_req req_fw_dl = { CMD_FW_DL, 0, 0, wbuf, 0, NULL };
315 struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
316 u8 hdr_core;
317 u16 hdr_addr, hdr_data_len, hdr_checksum;
318 #define MAX_DATA 58
319 #define HDR_SIZE 7
320
321 /*
322 * Thanks to Daniel Glöckner <daniel-gl@gmx.net> about that info!
323 *
324 * byte 0: MCS 51 core
325 * There are two inside the AF9035 (1=Link and 2=OFDM) with separate
326 * address spaces
327 * byte 1-2: Big endian destination address
328 * byte 3-4: Big endian number of data bytes following the header
329 * byte 5-6: Big endian header checksum, apparently ignored by the chip
330 * Calculated as ~(h[0]*256+h[1]+h[2]*256+h[3]+h[4]*256)
331 */
332
333 for (i = fw->size; i > HDR_SIZE;) {
334 hdr_core = fw->data[fw->size - i + 0];
335 hdr_addr = fw->data[fw->size - i + 1] << 8;
336 hdr_addr |= fw->data[fw->size - i + 2] << 0;
337 hdr_data_len = fw->data[fw->size - i + 3] << 8;
338 hdr_data_len |= fw->data[fw->size - i + 4] << 0;
339 hdr_checksum = fw->data[fw->size - i + 5] << 8;
340 hdr_checksum |= fw->data[fw->size - i + 6] << 0;
341
342 pr_debug("%s: core=%d addr=%04x data_len=%d checksum=%04x\n",
343 __func__, hdr_core, hdr_addr, hdr_data_len,
344 hdr_checksum);
345
346 if (((hdr_core != 1) && (hdr_core != 2)) ||
347 (hdr_data_len > i)) {
348 pr_debug("%s: bad firmware\n", __func__);
349 break;
350 }
351
352 /* download begin packet */
353 req.cmd = CMD_FW_DL_BEGIN;
354 ret = af9035_ctrl_msg(d, &req);
355 if (ret < 0)
356 goto err;
357
358 /* download firmware packet(s) */
359 for (j = HDR_SIZE + hdr_data_len; j > 0; j -= MAX_DATA) {
360 len = j;
361 if (len > MAX_DATA)
362 len = MAX_DATA;
363 req_fw_dl.wlen = len;
364 req_fw_dl.wbuf = (u8 *) &fw->data[fw->size - i +
365 HDR_SIZE + hdr_data_len - j];
366 ret = af9035_ctrl_msg(d, &req_fw_dl);
367 if (ret < 0)
368 goto err;
369 }
370
371 /* download end packet */
372 req.cmd = CMD_FW_DL_END;
373 ret = af9035_ctrl_msg(d, &req);
374 if (ret < 0)
375 goto err;
376
377 i -= hdr_data_len + HDR_SIZE;
378
379 pr_debug("%s: data uploaded=%zu\n", __func__, fw->size - i);
380 }
381
382 /* firmware loaded, request boot */
383 req.cmd = CMD_FW_BOOT;
384 ret = af9035_ctrl_msg(d, &req);
385 if (ret < 0)
386 goto err;
387
388 /* ensure firmware starts */
389 wbuf[0] = 1;
390 ret = af9035_ctrl_msg(d, &req_fw_ver);
391 if (ret < 0)
392 goto err;
393
394 if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
395 pr_err("%s: firmware did not run\n", KBUILD_MODNAME);
396 ret = -ENODEV;
397 goto err;
398 }
399
400 pr_info("%s: firmware version=%d.%d.%d.%d", KBUILD_MODNAME,
401 rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
402
403 return 0;
404
405err:
406 pr_debug("%s: failed=%d\n", __func__, ret);
407
408 return ret;
409}
410
411static int af9035_download_firmware_it9135(struct dvb_usb_device *d,
412 const struct firmware *fw)
413{
414 int ret, i, i_prev;
415 u8 wbuf[1];
416 u8 rbuf[4];
417 struct usb_req req = { 0, 0, 0, NULL, 0, NULL };
418 struct usb_req req_fw_dl = { CMD_FW_SCATTER_WR, 0, 0, NULL, 0, NULL };
419 struct usb_req req_fw_ver = { CMD_FW_QUERYINFO, 0, 1, wbuf, 4, rbuf } ;
420 #define HDR_SIZE 7
421
422 /*
423 * There seems to be following firmware header. Meaning of bytes 0-3
424 * is unknown.
425 *
426 * 0: 3
427 * 1: 0, 1
428 * 2: 0
429 * 3: 1, 2, 3
430 * 4: addr MSB
431 * 5: addr LSB
432 * 6: count of data bytes ?
433 */
434
435 for (i = HDR_SIZE, i_prev = 0; i <= fw->size; i++) {
436 if (i == fw->size ||
437 (fw->data[i + 0] == 0x03 &&
438 (fw->data[i + 1] == 0x00 ||
439 fw->data[i + 1] == 0x01) &&
440 fw->data[i + 2] == 0x00)) {
441 req_fw_dl.wlen = i - i_prev;
442 req_fw_dl.wbuf = (u8 *) &fw->data[i_prev];
443 i_prev = i;
444 ret = af9035_ctrl_msg(d, &req_fw_dl);
445 if (ret < 0)
446 goto err;
447
448 pr_debug("%s: data uploaded=%d\n", __func__, i);
449 }
450 }
451
452 /* firmware loaded, request boot */
453 req.cmd = CMD_FW_BOOT;
454 ret = af9035_ctrl_msg(d, &req);
455 if (ret < 0)
456 goto err;
457
458 /* ensure firmware starts */
459 wbuf[0] = 1;
460 ret = af9035_ctrl_msg(d, &req_fw_ver);
461 if (ret < 0)
462 goto err;
463
464 if (!(rbuf[0] || rbuf[1] || rbuf[2] || rbuf[3])) {
465 pr_err("%s: firmware did not run\n", KBUILD_MODNAME);
466 ret = -ENODEV;
467 goto err;
468 }
469
470 pr_info("%s: firmware version=%d.%d.%d.%d", KBUILD_MODNAME,
471 rbuf[0], rbuf[1], rbuf[2], rbuf[3]);
472
473 return 0;
474
475err:
476 pr_debug("%s: failed=%d\n", __func__, ret);
477
478 return ret;
479}
480
481static int af9035_read_config(struct dvb_usb_device *d)
482{
483 struct state *state = d_to_priv(d);
484 int ret, i, eeprom_shift = 0;
485 u8 tmp;
486 u16 tmp16;
487
488 /* check if there is dual tuners */
489 ret = af9035_rd_reg(d, EEPROM_DUAL_MODE, &tmp);
490 if (ret < 0)
491 goto err;
492
493 state->dual_mode = tmp;
494 pr_debug("%s: dual mode=%d\n", __func__, state->dual_mode);
495
496 for (i = 0; i < state->dual_mode + 1; i++) {
497 /* tuner */
498 ret = af9035_rd_reg(d, EEPROM_1_TUNER_ID + eeprom_shift, &tmp);
499 if (ret < 0)
500 goto err;
501
502 state->af9033_config[i].tuner = tmp;
503 pr_debug("%s: [%d]tuner=%02x\n", __func__, i, tmp);
504
505 switch (tmp) {
506 case AF9033_TUNER_TUA9001:
507 case AF9033_TUNER_FC0011:
508 case AF9033_TUNER_MXL5007T:
509 case AF9033_TUNER_TDA18218:
510 state->af9033_config[i].spec_inv = 1;
511 break;
512 default:
513 pr_info("%s: tuner ID=%02x not supported, please " \
514 "report!", KBUILD_MODNAME, tmp);
515 };
516
517 /* tuner IF frequency */
518 ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_L + eeprom_shift, &tmp);
519 if (ret < 0)
520 goto err;
521
522 tmp16 = tmp;
523
524 ret = af9035_rd_reg(d, EEPROM_1_IFFREQ_H + eeprom_shift, &tmp);
525 if (ret < 0)
526 goto err;
527
528 tmp16 |= tmp << 8;
529
530 pr_debug("%s: [%d]IF=%d\n", __func__, i, tmp16);
531
532 eeprom_shift = 0x10; /* shift for the 2nd tuner params */
533 }
534
535 /* get demod clock */
536 ret = af9035_rd_reg(d, 0x00d800, &tmp);
537 if (ret < 0)
538 goto err;
539
540 tmp = (tmp >> 0) & 0x0f;
541
542 for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++)
543 state->af9033_config[i].clock = clock_lut[tmp];
544
545 return 0;
546
547err:
548 pr_debug("%s: failed=%d\n", __func__, ret);
549
550 return ret;
551}
552
553static int af9035_read_config_it9135(struct dvb_usb_device *d)
554{
555 struct state *state = d_to_priv(d);
556 int ret, i;
557 u8 tmp;
558
559 state->dual_mode = false;
560
561 /* get demod clock */
562 ret = af9035_rd_reg(d, 0x00d800, &tmp);
563 if (ret < 0)
564 goto err;
565
566 tmp = (tmp >> 0) & 0x0f;
567
568 for (i = 0; i < ARRAY_SIZE(state->af9033_config); i++)
569 state->af9033_config[i].clock = clock_lut_it9135[tmp];
570
571 return 0;
572
573err:
574 pr_debug("%s: failed=%d\n", __func__, ret);
575
576 return ret;
577}
578
579static int af9035_fc0011_tuner_callback(struct dvb_usb_device *d,
580 int cmd, int arg)
581{
582 int ret;
583
584 switch (cmd) {
585 case FC0011_FE_CALLBACK_POWER:
586 /* Tuner enable */
587 ret = af9035_wr_reg_mask(d, 0xd8eb, 1, 1);
588 if (ret < 0)
589 goto err;
590
591 ret = af9035_wr_reg_mask(d, 0xd8ec, 1, 1);
592 if (ret < 0)
593 goto err;
594
595 ret = af9035_wr_reg_mask(d, 0xd8ed, 1, 1);
596 if (ret < 0)
597 goto err;
598
599 /* LED */
600 ret = af9035_wr_reg_mask(d, 0xd8d0, 1, 1);
601 if (ret < 0)
602 goto err;
603
604 ret = af9035_wr_reg_mask(d, 0xd8d1, 1, 1);
605 if (ret < 0)
606 goto err;
607
608 usleep_range(10000, 50000);
609 break;
610 case FC0011_FE_CALLBACK_RESET:
611 ret = af9035_wr_reg(d, 0xd8e9, 1);
612 if (ret < 0)
613 goto err;
614
615 ret = af9035_wr_reg(d, 0xd8e8, 1);
616 if (ret < 0)
617 goto err;
618
619 ret = af9035_wr_reg(d, 0xd8e7, 1);
620 if (ret < 0)
621 goto err;
622
623 usleep_range(10000, 20000);
624
625 ret = af9035_wr_reg(d, 0xd8e7, 0);
626 if (ret < 0)
627 goto err;
628
629 usleep_range(10000, 20000);
630 break;
631 default:
632 ret = -EINVAL;
633 goto err;
634 }
635
636 return 0;
637
638err:
639 pr_debug("%s: failed=%d\n", __func__, ret);
640
641 return ret;
642}
643
644static int af9035_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
645{
646 struct state *state = d_to_priv(d);
647
648 switch (state->af9033_config[0].tuner) {
649 case AF9033_TUNER_FC0011:
650 return af9035_fc0011_tuner_callback(d, cmd, arg);
651 default:
652 break;
653 }
654
655 return -ENODEV;
656}
657
658static int af9035_frontend_callback(void *adapter_priv, int component,
659 int cmd, int arg)
660{
661 struct i2c_adapter *adap = adapter_priv;
662 struct dvb_usb_device *d = i2c_get_adapdata(adap);
663
664 switch (component) {
665 case DVB_FRONTEND_COMPONENT_TUNER:
666 return af9035_tuner_callback(d, cmd, arg);
667 default:
668 break;
669 }
670
671 return -EINVAL;
672}
673
674static int af9035_frontend_attach(struct dvb_usb_adapter *adap)
675{
676 struct state *state = adap_to_priv(adap);
677 struct dvb_usb_device *d = adap_to_d(adap);
678 int ret;
679
680 if (!state->af9033_config[adap->id].tuner) {
681 /* unsupported tuner */
682 ret = -ENODEV;
683 goto err;
684 }
685
686 if (adap->id == 0) {
687 state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB;
688 state->af9033_config[1].ts_mode = AF9033_TS_MODE_SERIAL;
689
690 ret = af9035_wr_reg(d, 0x00417f,
691 state->af9033_config[1].i2c_addr);
692 if (ret < 0)
693 goto err;
694
695 ret = af9035_wr_reg(d, 0x00d81a,
696 state->dual_mode);
697 if (ret < 0)
698 goto err;
699 }
700
701 /* attach demodulator */
702 adap->fe[0] = dvb_attach(af9033_attach,
703 &state->af9033_config[adap->id], &d->i2c_adap);
704 if (adap->fe[0] == NULL) {
705 ret = -ENODEV;
706 goto err;
707 }
708
709 /* disable I2C-gate */
710 adap->fe[0]->ops.i2c_gate_ctrl = NULL;
711 adap->fe[0]->callback = af9035_frontend_callback;
712
713 return 0;
714
715err:
716 pr_debug("%s: failed=%d\n", __func__, ret);
717
718 return ret;
719}
720
721static struct tua9001_config af9035_tua9001_config = {
722 .i2c_addr = 0x60,
723};
724
725static const struct fc0011_config af9035_fc0011_config = {
726 .i2c_address = 0x60,
727};
728
729static struct mxl5007t_config af9035_mxl5007t_config = {
730 .xtal_freq_hz = MxL_XTAL_24_MHZ,
731 .if_freq_hz = MxL_IF_4_57_MHZ,
732 .invert_if = 0,
733 .loop_thru_enable = 0,
734 .clk_out_enable = 0,
735 .clk_out_amp = MxL_CLKOUT_AMP_0_94V,
736};
737
738static struct tda18218_config af9035_tda18218_config = {
739 .i2c_address = 0x60,
740 .i2c_wr_max = 21,
741};
742
743static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
744{
745 struct state *state = adap_to_priv(adap);
746 struct dvb_usb_device *d = adap_to_d(adap);
747 int ret;
748 struct dvb_frontend *fe;
749
750 switch (state->af9033_config[adap->id].tuner) {
751 case AF9033_TUNER_TUA9001:
752 /* AF9035 gpiot3 = TUA9001 RESETN
753 AF9035 gpiot2 = TUA9001 RXEN */
754
755 /* configure gpiot2 and gpiot2 as output */
756 ret = af9035_wr_reg_mask(d, 0x00d8ec, 0x01, 0x01);
757 if (ret < 0)
758 goto err;
759
760 ret = af9035_wr_reg_mask(d, 0x00d8ed, 0x01, 0x01);
761 if (ret < 0)
762 goto err;
763
764 ret = af9035_wr_reg_mask(d, 0x00d8e8, 0x01, 0x01);
765 if (ret < 0)
766 goto err;
767
768 ret = af9035_wr_reg_mask(d, 0x00d8e9, 0x01, 0x01);
769 if (ret < 0)
770 goto err;
771
772 /* reset tuner */
773 ret = af9035_wr_reg_mask(d, 0x00d8e7, 0x00, 0x01);
774 if (ret < 0)
775 goto err;
776
777 usleep_range(2000, 20000);
778
779 ret = af9035_wr_reg_mask(d, 0x00d8e7, 0x01, 0x01);
780 if (ret < 0)
781 goto err;
782
783 /* activate tuner RX */
784 /* TODO: use callback for TUA9001 RXEN */
785 ret = af9035_wr_reg_mask(d, 0x00d8eb, 0x01, 0x01);
786 if (ret < 0)
787 goto err;
788
789 /* attach tuner */
790 fe = dvb_attach(tua9001_attach, adap->fe[0],
791 &d->i2c_adap, &af9035_tua9001_config);
792 break;
793 case AF9033_TUNER_FC0011:
794 fe = dvb_attach(fc0011_attach, adap->fe[0],
795 &d->i2c_adap, &af9035_fc0011_config);
796 break;
797 case AF9033_TUNER_MXL5007T:
798 ret = af9035_wr_reg(d, 0x00d8e0, 1);
799 if (ret < 0)
800 goto err;
801 ret = af9035_wr_reg(d, 0x00d8e1, 1);
802 if (ret < 0)
803 goto err;
804 ret = af9035_wr_reg(d, 0x00d8df, 0);
805 if (ret < 0)
806 goto err;
807
808 msleep(30);
809
810 ret = af9035_wr_reg(d, 0x00d8df, 1);
811 if (ret < 0)
812 goto err;
813
814 msleep(300);
815
816 ret = af9035_wr_reg(d, 0x00d8c0, 1);
817 if (ret < 0)
818 goto err;
819 ret = af9035_wr_reg(d, 0x00d8c1, 1);
820 if (ret < 0)
821 goto err;
822 ret = af9035_wr_reg(d, 0x00d8bf, 0);
823 if (ret < 0)
824 goto err;
825 ret = af9035_wr_reg(d, 0x00d8b4, 1);
826 if (ret < 0)
827 goto err;
828 ret = af9035_wr_reg(d, 0x00d8b5, 1);
829 if (ret < 0)
830 goto err;
831 ret = af9035_wr_reg(d, 0x00d8b3, 1);
832 if (ret < 0)
833 goto err;
834
835 /* attach tuner */
836 fe = dvb_attach(mxl5007t_attach, adap->fe[0],
837 &d->i2c_adap, 0x60, &af9035_mxl5007t_config);
838 break;
839 case AF9033_TUNER_TDA18218:
840 /* attach tuner */
841 fe = dvb_attach(tda18218_attach, adap->fe[0],
842 &d->i2c_adap, &af9035_tda18218_config);
843 break;
844 default:
845 fe = NULL;
846 }
847
848 if (fe == NULL) {
849 ret = -ENODEV;
850 goto err;
851 }
852
853 return 0;
854
855err:
856 pr_debug("%s: failed=%d\n", __func__, ret);
857
858 return ret;
859}
860
861static int af9035_init(struct dvb_usb_device *d)
862{
863 struct state *state = d_to_priv(d);
864 int ret, i;
865 u16 frame_size = 87 * 188 / 4;
866 u8 packet_size = 512 / 4;
867 struct reg_val_mask tab[] = {
868 { 0x80f99d, 0x01, 0x01 },
869 { 0x80f9a4, 0x01, 0x01 },
870 { 0x00dd11, 0x00, 0x20 },
871 { 0x00dd11, 0x00, 0x40 },
872 { 0x00dd13, 0x00, 0x20 },
873 { 0x00dd13, 0x00, 0x40 },
874 { 0x00dd11, 0x20, 0x20 },
875 { 0x00dd88, (frame_size >> 0) & 0xff, 0xff},
876 { 0x00dd89, (frame_size >> 8) & 0xff, 0xff},
877 { 0x00dd0c, packet_size, 0xff},
878 { 0x00dd11, state->dual_mode << 6, 0x40 },
879 { 0x00dd8a, (frame_size >> 0) & 0xff, 0xff},
880 { 0x00dd8b, (frame_size >> 8) & 0xff, 0xff},
881 { 0x00dd0d, packet_size, 0xff },
882 { 0x80f9a3, 0x00, 0x01 },
883 { 0x80f9cd, 0x00, 0x01 },
884 { 0x80f99d, 0x00, 0x01 },
885 { 0x80f9a4, 0x00, 0x01 },
886 };
887
888 pr_debug("%s: USB speed=%d frame_size=%04x packet_size=%02x\n",
889 __func__, d->udev->speed, frame_size, packet_size);
890
891 /* init endpoints */
892 for (i = 0; i < ARRAY_SIZE(tab); i++) {
893 ret = af9035_wr_reg_mask(d, tab[i].reg, tab[i].val,
894 tab[i].mask);
895 if (ret < 0)
896 goto err;
897 }
898
899 return 0;
900
901err:
902 pr_debug("%s: failed=%d\n", __func__, ret);
903
904 return ret;
905}
906
907static int af9035_rc_query(struct dvb_usb_device *d)
908{
909 unsigned int key;
910 unsigned char b[4];
911 int ret;
912 struct usb_req req = { CMD_IR_GET, 0, 0, NULL, 4, b };
913
914 ret = af9035_ctrl_msg(d, &req);
915 if (ret < 0)
916 goto err;
917
918 if ((b[2] + b[3]) == 0xff) {
919 if ((b[0] + b[1]) == 0xff) {
920 /* NEC */
921 key = b[0] << 8 | b[2];
922 } else {
923 /* ext. NEC */
924 key = b[0] << 16 | b[1] << 8 | b[2];
925 }
926 } else {
927 key = b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3];
928 }
929
930 rc_keydown(d->rc_dev, key, 0);
931
932err:
933 /* ignore errors */
934 return 0;
935}
936
937static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
938{
939 int ret;
940 u8 tmp;
941
942 ret = af9035_rd_reg(d, EEPROM_IR_MODE, &tmp);
943 if (ret < 0)
944 goto err;
945
946 pr_debug("%s: ir_mode=%02x\n", __func__, tmp);
947
948 /* don't activate rc if in HID mode or if not available */
949 if (tmp == 5) {
950 ret = af9035_rd_reg(d, EEPROM_IR_TYPE, &tmp);
951 if (ret < 0)
952 goto err;
953
954 pr_debug("%s: ir_type=%02x\n", __func__, tmp);
955
956 switch (tmp) {
957 case 0: /* NEC */
958 default:
959 rc->allowed_protos = RC_TYPE_NEC;
960 break;
961 case 1: /* RC6 */
962 rc->allowed_protos = RC_TYPE_RC6;
963 break;
964 }
965
966 rc->query = af9035_rc_query;
967 rc->interval = 500;
968
969 /* load empty to enable rc */
970 if (!rc->map_name)
971 rc->map_name = RC_MAP_EMPTY;
972 }
973
974 return 0;
975
976err:
977 pr_debug("%s: failed=%d\n", __func__, ret);
978
979 return ret;
980}
981
982/* interface 0 is used by DVB-T receiver and
983 interface 1 is for remote controller (HID) */
984static const struct dvb_usb_device_properties af9035_props = {
985 .driver_name = KBUILD_MODNAME,
986 .owner = THIS_MODULE,
987 .adapter_nr = adapter_nr,
988 .size_of_priv = sizeof(struct state),
989
990 .generic_bulk_ctrl_endpoint = 0x02,
991 .generic_bulk_ctrl_endpoint_response = 0x81,
992
993 .identify_state = af9035_identify_state,
994 .firmware = "dvb-usb-af9035-02.fw",
995 .download_firmware = af9035_download_firmware,
996
997 .i2c_algo = &af9035_i2c_algo,
998 .read_config = af9035_read_config,
999 .frontend_attach = af9035_frontend_attach,
1000 .tuner_attach = af9035_tuner_attach,
1001 .init = af9035_init,
1002 .get_rc_config = af9035_get_rc_config,
1003
1004 .num_adapters = 1,
1005 .adapter = {
1006 {
1007 .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
1008 }, {
1009 .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
1010 },
1011 },
1012};
1013
1014static const struct dvb_usb_device_properties it9135_props = {
1015 .driver_name = KBUILD_MODNAME,
1016 .owner = THIS_MODULE,
1017 .adapter_nr = adapter_nr,
1018 .size_of_priv = sizeof(struct state),
1019
1020 .generic_bulk_ctrl_endpoint = 0x02,
1021 .generic_bulk_ctrl_endpoint_response = 0x81,
1022
1023 .identify_state = af9035_identify_state,
1024 .firmware = "dvb-usb-it9135-01.fw",
1025 .download_firmware = af9035_download_firmware_it9135,
1026
1027 .i2c_algo = &af9035_i2c_algo,
1028 .read_config = af9035_read_config_it9135,
1029 .frontend_attach = af9035_frontend_attach,
1030 .tuner_attach = af9035_tuner_attach,
1031 .init = af9035_init,
1032 .get_rc_config = af9035_get_rc_config,
1033
1034 .num_adapters = 1,
1035 .adapter = {
1036 {
1037 .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
1038 }, {
1039 .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
1040 },
1041 },
1042};
1043
1044static const struct usb_device_id af9035_id_table[] = {
1045 { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_9035,
1046 &af9035_props, "Afatech AF9035 reference design", NULL) },
1047 { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1000,
1048 &af9035_props, "Afatech AF9035 reference design", NULL) },
1049 { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1001,
1050 &af9035_props, "Afatech AF9035 reference design", NULL) },
1051 { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1002,
1052 &af9035_props, "Afatech AF9035 reference design", NULL) },
1053 { DVB_USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9035_1003,
1054 &af9035_props, "Afatech AF9035 reference design", NULL) },
1055 { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK,
1056 &af9035_props, "TerraTec Cinergy T Stick", NULL) },
1057 { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A835,
1058 &af9035_props, "AVerMedia AVerTV Volar HD/PRO (A835)", NULL) },
1059 { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_B835,
1060 &af9035_props, "AVerMedia AVerTV Volar HD/PRO (A835)", NULL) },
1061 { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_1867,
1062 &af9035_props, "AVerMedia HD Volar (A867)", NULL) },
1063 { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A867,
1064 &af9035_props, "AVerMedia HD Volar (A867)", NULL) },
1065 { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_TWINSTAR,
1066 &af9035_props, "AVerMedia Twinstar (A825)", NULL) },
1067 { }
1068};
1069MODULE_DEVICE_TABLE(usb, af9035_id_table);
1070
1071static struct usb_driver af9035_usb_driver = {
1072 .name = KBUILD_MODNAME,
1073 .id_table = af9035_id_table,
1074 .probe = dvb_usbv2_probe,
1075 .disconnect = dvb_usbv2_disconnect,
1076 .suspend = dvb_usbv2_suspend,
1077 .resume = dvb_usbv2_resume,
1078 .no_dynamic_id = 1,
1079 .soft_unbind = 1,
1080};
1081
1082module_usb_driver(af9035_usb_driver);
1083
1084MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1085MODULE_DESCRIPTION("Afatech AF9035 driver");
1086MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h
new file mode 100644
index 000000000000..59ff69ede0f0
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/af9035.h
@@ -0,0 +1,111 @@
1/*
2 * Afatech AF9035 DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
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 along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#ifndef AF9035_H
23#define AF9035_H
24
25#include "dvb_usb.h"
26#include "af9033.h"
27#include "tua9001.h"
28#include "fc0011.h"
29#include "mxl5007t.h"
30#include "tda18218.h"
31
32struct reg_val {
33 u32 reg;
34 u8 val;
35};
36
37struct reg_val_mask {
38 u32 reg;
39 u8 val;
40 u8 mask;
41};
42
43struct usb_req {
44 u8 cmd;
45 u8 mbox;
46 u8 wlen;
47 u8 *wbuf;
48 u8 rlen;
49 u8 *rbuf;
50};
51
52struct state {
53 u8 seq; /* packet sequence number */
54 bool dual_mode;
55
56 struct af9033_config af9033_config[2];
57};
58
59u32 clock_lut[] = {
60 20480000, /* FPGA */
61 16384000, /* 16.38 MHz */
62 20480000, /* 20.48 MHz */
63 36000000, /* 36.00 MHz */
64 30000000, /* 30.00 MHz */
65 26000000, /* 26.00 MHz */
66 28000000, /* 28.00 MHz */
67 32000000, /* 32.00 MHz */
68 34000000, /* 34.00 MHz */
69 24000000, /* 24.00 MHz */
70 22000000, /* 22.00 MHz */
71 12000000, /* 12.00 MHz */
72};
73
74u32 clock_lut_it9135[] = {
75 12000000, /* 12.00 MHz */
76 20480000, /* 20.48 MHz */
77 36000000, /* 36.00 MHz */
78 30000000, /* 30.00 MHz */
79 26000000, /* 26.00 MHz */
80 28000000, /* 28.00 MHz */
81 32000000, /* 32.00 MHz */
82 34000000, /* 34.00 MHz */
83 24000000, /* 24.00 MHz */
84 22000000, /* 22.00 MHz */
85};
86
87/* EEPROM locations */
88#define EEPROM_IR_MODE 0x430d
89#define EEPROM_DUAL_MODE 0x4326
90#define EEPROM_IR_TYPE 0x4329
91#define EEPROM_1_IFFREQ_L 0x432d
92#define EEPROM_1_IFFREQ_H 0x432e
93#define EEPROM_1_TUNER_ID 0x4331
94#define EEPROM_2_IFFREQ_L 0x433d
95#define EEPROM_2_IFFREQ_H 0x433e
96#define EEPROM_2_TUNER_ID 0x4341
97
98/* USB commands */
99#define CMD_MEM_RD 0x00
100#define CMD_MEM_WR 0x01
101#define CMD_I2C_RD 0x02
102#define CMD_I2C_WR 0x03
103#define CMD_IR_GET 0x18
104#define CMD_FW_DL 0x21
105#define CMD_FW_QUERYINFO 0x22
106#define CMD_FW_BOOT 0x23
107#define CMD_FW_DL_BEGIN 0x24
108#define CMD_FW_DL_END 0x25
109#define CMD_FW_SCATTER_WR 0x29
110
111#endif
diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c
new file mode 100644
index 000000000000..fb3829a73d2d
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/anysee.c
@@ -0,0 +1,1324 @@
1/*
2 * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * TODO:
21 * - add smart card reader support for Conditional Access (CA)
22 *
23 * Card reader in Anysee is nothing more than ISO 7816 card reader.
24 * There is no hardware CAM in any Anysee device sold.
25 * In my understanding it should be implemented by making own module
26 * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
27 * module registers serial interface that can be used to communicate
28 * with any ISO 7816 smart card.
29 *
30 * Any help according to implement serial smart card reader support
31 * is highly welcome!
32 */
33
34#include "anysee.h"
35#include "dvb-pll.h"
36#include "tda1002x.h"
37#include "mt352.h"
38#include "mt352_priv.h"
39#include "zl10353.h"
40#include "tda18212.h"
41#include "cx24116.h"
42#include "stv0900.h"
43#include "stv6110.h"
44#include "isl6423.h"
45#include "cxd2820r.h"
46
47/* debug */
48static int dvb_usb_anysee_debug;
49module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
50MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
51DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
52
53static DEFINE_MUTEX(anysee_usb_mutex);
54
55static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
56 u8 *rbuf, u8 rlen)
57{
58 struct anysee_state *state = d_to_priv(d);
59 int act_len, ret, i;
60 u8 buf[64];
61
62 memcpy(&buf[0], sbuf, slen);
63 buf[60] = state->seq++;
64
65 mutex_lock(&anysee_usb_mutex);
66
67 deb_xfer(">>> ");
68 debug_dump(buf, slen, deb_xfer);
69
70 /* We need receive one message more after dvb_usb_generic_rw due
71 to weird transaction flow, which is 1 x send + 2 x receive. */
72 ret = dvb_usbv2_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf));
73 if (ret)
74 goto error_unlock;
75
76 /* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32
77 * (EPIPE, Broken pipe). Function supports currently msleep() as a
78 * parameter but I would not like to use it, since according to
79 * Documentation/timers/timers-howto.txt it should not be used such
80 * short, under < 20ms, sleeps. Repeating failed message would be
81 * better choice as not to add unwanted delays...
82 * Fixing that correctly is one of those or both;
83 * 1) use repeat if possible
84 * 2) add suitable delay
85 */
86
87 /* get answer, retry few times if error returned */
88 for (i = 0; i < 3; i++) {
89 /* receive 2nd answer */
90 ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
91 d->props->generic_bulk_ctrl_endpoint), buf, sizeof(buf),
92 &act_len, 2000);
93
94 if (ret) {
95 deb_info("%s: recv bulk message failed: %d",
96 __func__, ret);
97 } else {
98 deb_xfer("<<< ");
99 debug_dump(buf, rlen, deb_xfer);
100
101 if (buf[63] != 0x4f)
102 deb_info("%s: cmd failed\n", __func__);
103
104 break;
105 }
106 }
107
108 if (ret) {
109 /* all retries failed, it is fatal */
110 err("%s: recv bulk message failed: %d", __func__, ret);
111 goto error_unlock;
112 }
113
114 /* read request, copy returned data to return buf */
115 if (rbuf && rlen)
116 memcpy(rbuf, buf, rlen);
117
118error_unlock:
119 mutex_unlock(&anysee_usb_mutex);
120
121 return ret;
122}
123
124static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
125{
126 u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
127 int ret;
128 ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
129 deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);
130 return ret;
131}
132
133static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
134{
135 u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
136 deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);
137 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
138}
139
140/* write single register with mask */
141static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val,
142 u8 mask)
143{
144 int ret;
145 u8 tmp;
146
147 /* no need for read if whole reg is written */
148 if (mask != 0xff) {
149 ret = anysee_read_reg(d, reg, &tmp);
150 if (ret)
151 return ret;
152
153 val &= mask;
154 tmp &= ~mask;
155 val |= tmp;
156 }
157
158 return anysee_write_reg(d, reg, val);
159}
160
161/* read single register with mask */
162static int anysee_rd_reg_mask(struct dvb_usb_device *d, u16 reg, u8 *val,
163 u8 mask)
164{
165 int ret, i;
166 u8 tmp;
167
168 ret = anysee_read_reg(d, reg, &tmp);
169 if (ret)
170 return ret;
171
172 tmp &= mask;
173
174 /* find position of the first bit */
175 for (i = 0; i < 8; i++) {
176 if ((mask >> i) & 0x01)
177 break;
178 }
179 *val = tmp >> i;
180
181 return 0;
182}
183
184static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
185{
186 u8 buf[] = {CMD_GET_HW_INFO};
187 return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
188}
189
190static int anysee_streaming_ctrl(struct dvb_frontend *fe, int onoff)
191{
192 u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
193 deb_info("%s: onoff:%02x\n", __func__, onoff);
194 return anysee_ctrl_msg(fe_to_d(fe), buf, sizeof(buf), NULL, 0);
195}
196
197static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
198{
199 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
200 deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);
201 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
202}
203
204static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
205{
206 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
207 deb_info("%s: onoff:%02x\n", __func__, onoff);
208 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
209}
210
211/* I2C */
212static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
213 int num)
214{
215 struct dvb_usb_device *d = i2c_get_adapdata(adap);
216 int ret = 0, inc, i = 0;
217 u8 buf[52]; /* 4 + 48 (I2C WR USB command header + I2C WR max) */
218
219 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
220 return -EAGAIN;
221
222 while (i < num) {
223 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
224 if (msg[i].len > 2 || msg[i+1].len > 60) {
225 ret = -EOPNOTSUPP;
226 break;
227 }
228 buf[0] = CMD_I2C_READ;
229 buf[1] = (msg[i].addr << 1) | 0x01;
230 buf[2] = msg[i].buf[0];
231 buf[3] = msg[i].buf[1];
232 buf[4] = msg[i].len-1;
233 buf[5] = msg[i+1].len;
234 ret = anysee_ctrl_msg(d, buf, 6, msg[i+1].buf,
235 msg[i+1].len);
236 inc = 2;
237 } else {
238 if (msg[i].len > 48) {
239 ret = -EOPNOTSUPP;
240 break;
241 }
242 buf[0] = CMD_I2C_WRITE;
243 buf[1] = (msg[i].addr << 1);
244 buf[2] = msg[i].len;
245 buf[3] = 0x01;
246 memcpy(&buf[4], msg[i].buf, msg[i].len);
247 ret = anysee_ctrl_msg(d, buf, 4 + msg[i].len, NULL, 0);
248 inc = 1;
249 }
250 if (ret)
251 break;
252
253 i += inc;
254 }
255
256 mutex_unlock(&d->i2c_mutex);
257
258 return ret ? ret : i;
259}
260
261static u32 anysee_i2c_func(struct i2c_adapter *adapter)
262{
263 return I2C_FUNC_I2C;
264}
265
266static struct i2c_algorithm anysee_i2c_algo = {
267 .master_xfer = anysee_master_xfer,
268 .functionality = anysee_i2c_func,
269};
270
271static int anysee_mt352_demod_init(struct dvb_frontend *fe)
272{
273 static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x28 };
274 static u8 reset[] = { RESET, 0x80 };
275 static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 };
276 static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0x20 };
277 static u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 };
278 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
279
280 mt352_write(fe, clock_config, sizeof(clock_config));
281 udelay(200);
282 mt352_write(fe, reset, sizeof(reset));
283 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
284
285 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
286 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
287 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
288
289 return 0;
290}
291
292/* Callbacks for DVB USB */
293static struct tda10023_config anysee_tda10023_config = {
294 .demod_address = (0x1a >> 1),
295 .invert = 0,
296 .xtal = 16000000,
297 .pll_m = 11,
298 .pll_p = 3,
299 .pll_n = 1,
300 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
301 .deltaf = 0xfeeb,
302};
303
304static struct mt352_config anysee_mt352_config = {
305 .demod_address = (0x1e >> 1),
306 .demod_init = anysee_mt352_demod_init,
307};
308
309static struct zl10353_config anysee_zl10353_config = {
310 .demod_address = (0x1e >> 1),
311 .parallel_ts = 1,
312};
313
314static struct zl10353_config anysee_zl10353_tda18212_config2 = {
315 .demod_address = (0x1e >> 1),
316 .parallel_ts = 1,
317 .disable_i2c_gate_ctrl = 1,
318 .no_tuner = 1,
319 .if2 = 41500,
320};
321
322static struct zl10353_config anysee_zl10353_tda18212_config = {
323 .demod_address = (0x18 >> 1),
324 .parallel_ts = 1,
325 .disable_i2c_gate_ctrl = 1,
326 .no_tuner = 1,
327 .if2 = 41500,
328};
329
330static struct tda10023_config anysee_tda10023_tda18212_config = {
331 .demod_address = (0x1a >> 1),
332 .xtal = 16000000,
333 .pll_m = 12,
334 .pll_p = 3,
335 .pll_n = 1,
336 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_B,
337 .deltaf = 0xba02,
338};
339
340static struct tda18212_config anysee_tda18212_config = {
341 .i2c_address = (0xc0 >> 1),
342 .if_dvbt_6 = 4150,
343 .if_dvbt_7 = 4150,
344 .if_dvbt_8 = 4150,
345 .if_dvbc = 5000,
346};
347
348static struct tda18212_config anysee_tda18212_config2 = {
349 .i2c_address = 0x60 /* (0xc0 >> 1) */,
350 .if_dvbt_6 = 3550,
351 .if_dvbt_7 = 3700,
352 .if_dvbt_8 = 4150,
353 .if_dvbt2_6 = 3250,
354 .if_dvbt2_7 = 4000,
355 .if_dvbt2_8 = 4000,
356 .if_dvbc = 5000,
357};
358
359static struct cx24116_config anysee_cx24116_config = {
360 .demod_address = (0xaa >> 1),
361 .mpg_clk_pos_pol = 0x00,
362 .i2c_wr_max = 48,
363};
364
365static struct stv0900_config anysee_stv0900_config = {
366 .demod_address = (0xd0 >> 1),
367 .demod_mode = 0,
368 .xtal = 8000000,
369 .clkmode = 3,
370 .diseqc_mode = 2,
371 .tun1_maddress = 0,
372 .tun1_adc = 1, /* 1 Vpp */
373 .path1_mode = 3,
374};
375
376static struct stv6110_config anysee_stv6110_config = {
377 .i2c_address = (0xc0 >> 1),
378 .mclk = 16000000,
379 .clk_div = 1,
380};
381
382static struct isl6423_config anysee_isl6423_config = {
383 .current_max = SEC_CURRENT_800m,
384 .curlim = SEC_CURRENT_LIM_OFF,
385 .mod_extern = 1,
386 .addr = (0x10 >> 1),
387};
388
389static struct cxd2820r_config anysee_cxd2820r_config = {
390 .i2c_address = 0x6d, /* (0xda >> 1) */
391 .ts_mode = 0x38,
392};
393
394/*
395 * New USB device strings: Mfr=1, Product=2, SerialNumber=0
396 * Manufacturer: AMT.CO.KR
397 *
398 * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
399 * PCB: ?
400 * parts: DNOS404ZH102A(MT352, DTT7579(?))
401 *
402 * E30 VID=04b4 PID=861f HW=2 FW=2.1 "anysee-T(LP)"
403 * PCB: PCB 507T (rev1.61)
404 * parts: DNOS404ZH103A(ZL10353, DTT7579(?))
405 * OEA=0a OEB=00 OEC=00 OED=ff OEE=00
406 * IOA=45 IOB=ff IOC=00 IOD=ff IOE=00
407 *
408 * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
409 * PCB: 507CD (rev1.1)
410 * parts: DNOS404ZH103A(ZL10353, DTT7579(?)), CST56I01
411 * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
412 * IOA=4f IOB=ff IOC=00 IOD=06 IOE=01
413 * IOD[0] ZL10353 1=enabled
414 * IOA[7] TS 0=enabled
415 * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
416 *
417 * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
418 * PCB: 507DC (rev0.2)
419 * parts: TDA10023, DTOS403IH102B TM, CST56I01
420 * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe
421 * IOA=4f IOB=ff IOC=00 IOD=26 IOE=01
422 * IOD[0] TDA10023 1=enabled
423 *
424 * E30 S2 Plus VID=04b4 PID=861f HW=11 FW=0.1 "anysee-S2(LP)"
425 * PCB: 507SI (rev2.1)
426 * parts: BS2N10WCC01(CX24116, CX24118), ISL6423, TDA8024
427 * OEA=80 OEB=00 OEC=ff OED=ff OEE=fe
428 * IOA=4d IOB=ff IOC=00 IOD=26 IOE=01
429 * IOD[0] CX24116 1=enabled
430 *
431 * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
432 * PCB: 507FA (rev0.4)
433 * parts: TDA10023, DTOS403IH102B TM, TDA8024
434 * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
435 * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
436 * IOD[5] TDA10023 1=enabled
437 * IOE[0] tuner 1=enabled
438 *
439 * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
440 * PCB: 507FA (rev1.1)
441 * parts: ZL10353, TDA10023, DTOS403IH102B TM, TDA8024
442 * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff
443 * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0
444 * DVB-C:
445 * IOD[5] TDA10023 1=enabled
446 * IOE[0] tuner 1=enabled
447 * DVB-T:
448 * IOD[0] ZL10353 1=enabled
449 * IOE[0] tuner 0=enabled
450 * tuner is behind ZL10353 I2C-gate
451 *
452 * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)"
453 * PCB: 508TC (rev0.6)
454 * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
455 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
456 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
457 * IOA[7] TS 1=enabled
458 * IOE[4] TDA18212 1=enabled
459 * DVB-C:
460 * IOD[6] ZL10353 0=disabled
461 * IOD[5] TDA10023 1=enabled
462 * IOE[0] IF 1=enabled
463 * DVB-T:
464 * IOD[5] TDA10023 0=disabled
465 * IOD[6] ZL10353 1=enabled
466 * IOE[0] IF 0=enabled
467 *
468 * E7 S2 VID=1c73 PID=861f HW=19 FW=0.4 AMTCI=0.5 "anysee-E7S2(LP)"
469 * PCB: 508S2 (rev0.7)
470 * parts: DNBU10512IST(STV0903, STV6110), ISL6423
471 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
472 * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
473 * IOA[7] TS 1=enabled
474 * IOE[5] STV0903 1=enabled
475 *
476 * E7 T2C VID=1c73 PID=861f HW=20 FW=0.1 AMTCI=0.5 "anysee-E7T2C(LP)"
477 * PCB: 508T2C (rev0.3)
478 * parts: DNOQ44QCH106A(CXD2820R, TDA18212), TDA8024
479 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
480 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
481 * IOA[7] TS 1=enabled
482 * IOE[5] CXD2820R 1=enabled
483 *
484 * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)"
485 * PCB: 508PTC (rev0.5)
486 * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
487 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
488 * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4
489 * IOA[7] TS 1=enabled
490 * IOE[4] TDA18212 1=enabled
491 * DVB-C:
492 * IOD[6] ZL10353 0=disabled
493 * IOD[5] TDA10023 1=enabled
494 * IOE[0] IF 1=enabled
495 * DVB-T:
496 * IOD[5] TDA10023 0=disabled
497 * IOD[6] ZL10353 1=enabled
498 * IOE[0] IF 0=enabled
499 *
500 * E7 PS2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)"
501 * PCB: 508PS2 (rev0.4)
502 * parts: DNBU10512IST(STV0903, STV6110), ISL6423
503 * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff
504 * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4
505 * IOA[7] TS 1=enabled
506 * IOE[5] STV0903 1=enabled
507 */
508
509static int anysee_read_config(struct dvb_usb_device *d)
510{
511 struct anysee_state *state = d_to_priv(d);
512 int ret;
513 u8 hw_info[3];
514
515 /*
516 * Check which hardware we have.
517 * We must do this call two times to get reliable values (hw/fw bug).
518 */
519 ret = anysee_get_hw_info(d, hw_info);
520 if (ret)
521 goto error;
522
523 ret = anysee_get_hw_info(d, hw_info);
524 if (ret)
525 goto error;
526
527 /* Meaning of these info bytes are guessed. */
528 info("firmware version:%d.%d hardware id:%d",
529 hw_info[1], hw_info[2], hw_info[0]);
530
531 state->hw = hw_info[0];
532error:
533 return ret;
534}
535
536/* external I2C gate used for DNOD44CDH086A(TDA18212) tuner module */
537static int anysee_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
538{
539 /* enable / disable tuner access on IOE[4] */
540 return anysee_wr_reg_mask(fe_to_d(fe), REG_IOE, (enable << 4), 0x10);
541}
542
543static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff)
544{
545 struct anysee_state *state = fe_to_priv(fe);
546 struct dvb_usb_device *d = fe_to_d(fe);
547 int ret;
548
549 deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
550
551 /* no frontend sleep control */
552 if (onoff == 0)
553 return 0;
554
555 switch (state->hw) {
556 case ANYSEE_HW_507FA: /* 15 */
557 /* E30 Combo Plus */
558 /* E30 C Plus */
559
560 if (fe->id == 0) {
561 /* disable DVB-T demod on IOD[0] */
562 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 0), 0x01);
563 if (ret)
564 goto error;
565
566 /* enable DVB-C demod on IOD[5] */
567 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
568 if (ret)
569 goto error;
570
571 /* enable DVB-C tuner on IOE[0] */
572 ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 0), 0x01);
573 if (ret)
574 goto error;
575 } else {
576 /* disable DVB-C demod on IOD[5] */
577 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
578 if (ret)
579 goto error;
580
581 /* enable DVB-T demod on IOD[0] */
582 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
583 if (ret)
584 goto error;
585
586 /* enable DVB-T tuner on IOE[0] */
587 ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 0), 0x01);
588 if (ret)
589 goto error;
590 }
591
592 break;
593 case ANYSEE_HW_508TC: /* 18 */
594 case ANYSEE_HW_508PTC: /* 21 */
595 /* E7 TC */
596 /* E7 PTC */
597
598 if (fe->id == 0) {
599 /* disable DVB-T demod on IOD[6] */
600 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 6), 0x40);
601 if (ret)
602 goto error;
603
604 /* enable DVB-C demod on IOD[5] */
605 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
606 if (ret)
607 goto error;
608
609 /* enable IF route on IOE[0] */
610 ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 0), 0x01);
611 if (ret)
612 goto error;
613 } else {
614 /* disable DVB-C demod on IOD[5] */
615 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
616 if (ret)
617 goto error;
618
619 /* enable DVB-T demod on IOD[6] */
620 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 6), 0x40);
621 if (ret)
622 goto error;
623
624 /* enable IF route on IOE[0] */
625 ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 0), 0x01);
626 if (ret)
627 goto error;
628 }
629
630 break;
631 default:
632 ret = 0;
633 }
634
635error:
636 return ret;
637}
638
639static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
640{
641 struct anysee_state *state = adap_to_priv(adap);
642 struct dvb_usb_device *d = adap_to_d(adap);
643 int ret;
644 u8 tmp;
645 struct i2c_msg msg[2] = {
646 {
647 .addr = anysee_tda18212_config.i2c_address,
648 .flags = 0,
649 .len = 1,
650 .buf = "\x00",
651 }, {
652 .addr = anysee_tda18212_config.i2c_address,
653 .flags = I2C_M_RD,
654 .len = 1,
655 .buf = &tmp,
656 }
657 };
658
659 switch (state->hw) {
660 case ANYSEE_HW_507T: /* 2 */
661 /* E30 */
662
663 /* attach demod */
664 adap->fe[0] = dvb_attach(mt352_attach, &anysee_mt352_config,
665 &d->i2c_adap);
666 if (adap->fe[0])
667 break;
668
669 /* attach demod */
670 adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config,
671 &d->i2c_adap);
672
673 break;
674 case ANYSEE_HW_507CD: /* 6 */
675 /* E30 Plus */
676
677 /* enable DVB-T demod on IOD[0] */
678 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
679 if (ret)
680 goto error;
681
682 /* enable transport stream on IOA[7] */
683 ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
684 if (ret)
685 goto error;
686
687 /* attach demod */
688 adap->fe[0] = dvb_attach(zl10353_attach, &anysee_zl10353_config,
689 &d->i2c_adap);
690
691 break;
692 case ANYSEE_HW_507DC: /* 10 */
693 /* E30 C Plus */
694
695 /* enable DVB-C demod on IOD[0] */
696 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
697 if (ret)
698 goto error;
699
700 /* attach demod */
701 adap->fe[0] = dvb_attach(tda10023_attach,
702 &anysee_tda10023_config, &d->i2c_adap, 0x48);
703
704 break;
705 case ANYSEE_HW_507SI: /* 11 */
706 /* E30 S2 Plus */
707
708 /* enable DVB-S/S2 demod on IOD[0] */
709 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
710 if (ret)
711 goto error;
712
713 /* attach demod */
714 adap->fe[0] = dvb_attach(cx24116_attach, &anysee_cx24116_config,
715 &d->i2c_adap);
716
717 break;
718 case ANYSEE_HW_507FA: /* 15 */
719 /* E30 Combo Plus */
720 /* E30 C Plus */
721
722 /* enable tuner on IOE[4] */
723 ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 4), 0x10);
724 if (ret)
725 goto error;
726
727 /* probe TDA18212 */
728 tmp = 0;
729 ret = i2c_transfer(&d->i2c_adap, msg, 2);
730 if (ret == 2 && tmp == 0xc7)
731 deb_info("%s: TDA18212 found\n", __func__);
732 else
733 tmp = 0;
734
735 /* disable tuner on IOE[4] */
736 ret = anysee_wr_reg_mask(d, REG_IOE, (0 << 4), 0x10);
737 if (ret)
738 goto error;
739
740 /* disable DVB-T demod on IOD[0] */
741 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 0), 0x01);
742 if (ret)
743 goto error;
744
745 /* enable DVB-C demod on IOD[5] */
746 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
747 if (ret)
748 goto error;
749
750 /* attach demod */
751 if (tmp == 0xc7) {
752 /* TDA18212 config */
753 adap->fe[0] = dvb_attach(tda10023_attach,
754 &anysee_tda10023_tda18212_config,
755 &d->i2c_adap, 0x48);
756
757 /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
758 if (adap->fe[0])
759 adap->fe[0]->ops.i2c_gate_ctrl =
760 anysee_i2c_gate_ctrl;
761 } else {
762 /* PLL config */
763 adap->fe[0] = dvb_attach(tda10023_attach,
764 &anysee_tda10023_config,
765 &d->i2c_adap, 0x48);
766 }
767
768 /* break out if first frontend attaching fails */
769 if (!adap->fe[0])
770 break;
771
772 /* disable DVB-C demod on IOD[5] */
773 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
774 if (ret)
775 goto error;
776
777 /* enable DVB-T demod on IOD[0] */
778 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 0), 0x01);
779 if (ret)
780 goto error;
781
782 /* attach demod */
783 if (tmp == 0xc7) {
784 /* TDA18212 config */
785 adap->fe[1] = dvb_attach(zl10353_attach,
786 &anysee_zl10353_tda18212_config2,
787 &d->i2c_adap);
788
789 /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
790 if (adap->fe[1])
791 adap->fe[1]->ops.i2c_gate_ctrl =
792 anysee_i2c_gate_ctrl;
793 } else {
794 /* PLL config */
795 adap->fe[1] = dvb_attach(zl10353_attach,
796 &anysee_zl10353_config,
797 &d->i2c_adap);
798 }
799
800 break;
801 case ANYSEE_HW_508TC: /* 18 */
802 case ANYSEE_HW_508PTC: /* 21 */
803 /* E7 TC */
804 /* E7 PTC */
805
806 /* disable DVB-T demod on IOD[6] */
807 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 6), 0x40);
808 if (ret)
809 goto error;
810
811 /* enable DVB-C demod on IOD[5] */
812 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 5), 0x20);
813 if (ret)
814 goto error;
815
816 /* attach demod */
817 adap->fe[0] = dvb_attach(tda10023_attach,
818 &anysee_tda10023_tda18212_config,
819 &d->i2c_adap, 0x48);
820
821 /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
822 if (adap->fe[0])
823 adap->fe[0]->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl;
824
825 /* break out if first frontend attaching fails */
826 if (!adap->fe[0])
827 break;
828
829 /* disable DVB-C demod on IOD[5] */
830 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 5), 0x20);
831 if (ret)
832 goto error;
833
834 /* enable DVB-T demod on IOD[6] */
835 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 6), 0x40);
836 if (ret)
837 goto error;
838
839 /* attach demod */
840 adap->fe[1] = dvb_attach(zl10353_attach,
841 &anysee_zl10353_tda18212_config,
842 &d->i2c_adap);
843
844 /* I2C gate for DNOD44CDH086A(TDA18212) tuner module */
845 if (adap->fe[1])
846 adap->fe[1]->ops.i2c_gate_ctrl = anysee_i2c_gate_ctrl;
847
848 state->has_ci = true;
849
850 break;
851 case ANYSEE_HW_508S2: /* 19 */
852 case ANYSEE_HW_508PS2: /* 22 */
853 /* E7 S2 */
854 /* E7 PS2 */
855
856 /* enable DVB-S/S2 demod on IOE[5] */
857 ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 5), 0x20);
858 if (ret)
859 goto error;
860
861 /* attach demod */
862 adap->fe[0] = dvb_attach(stv0900_attach,
863 &anysee_stv0900_config, &d->i2c_adap, 0);
864
865 state->has_ci = true;
866
867 break;
868 case ANYSEE_HW_508T2C: /* 20 */
869 /* E7 T2C */
870
871 /* enable DVB-T/T2/C demod on IOE[5] */
872 ret = anysee_wr_reg_mask(d, REG_IOE, (1 << 5), 0x20);
873 if (ret)
874 goto error;
875
876 /* attach demod */
877 adap->fe[0] = dvb_attach(cxd2820r_attach,
878 &anysee_cxd2820r_config, &d->i2c_adap);
879
880 state->has_ci = true;
881
882 break;
883 }
884
885 if (!adap->fe[0]) {
886 /* we have no frontend :-( */
887 ret = -ENODEV;
888 err("Unsupported Anysee version. " \
889 "Please report the <linux-media@vger.kernel.org>.");
890 }
891error:
892 return ret;
893}
894
895static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
896{
897 struct anysee_state *state = adap_to_priv(adap);
898 struct dvb_usb_device *d = adap_to_d(adap);
899 struct dvb_frontend *fe;
900 int ret;
901 deb_info("%s: adap=%d\n", __func__, adap->id);
902
903 switch (state->hw) {
904 case ANYSEE_HW_507T: /* 2 */
905 /* E30 */
906
907 /* attach tuner */
908 fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc2 >> 1), NULL,
909 DVB_PLL_THOMSON_DTT7579);
910
911 break;
912 case ANYSEE_HW_507CD: /* 6 */
913 /* E30 Plus */
914
915 /* attach tuner */
916 fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc2 >> 1),
917 &d->i2c_adap, DVB_PLL_THOMSON_DTT7579);
918
919 break;
920 case ANYSEE_HW_507DC: /* 10 */
921 /* E30 C Plus */
922
923 /* attach tuner */
924 fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc0 >> 1),
925 &d->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
926
927 break;
928 case ANYSEE_HW_507SI: /* 11 */
929 /* E30 S2 Plus */
930
931 /* attach LNB controller */
932 fe = dvb_attach(isl6423_attach, adap->fe[0], &d->i2c_adap,
933 &anysee_isl6423_config);
934
935 break;
936 case ANYSEE_HW_507FA: /* 15 */
937 /* E30 Combo Plus */
938 /* E30 C Plus */
939
940 /* Try first attach TDA18212 silicon tuner on IOE[4], if that
941 * fails attach old simple PLL. */
942
943 /* attach tuner */
944 fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
945 &anysee_tda18212_config);
946
947 if (fe && adap->fe[1]) {
948 /* attach tuner for 2nd FE */
949 fe = dvb_attach(tda18212_attach, adap->fe[1],
950 &d->i2c_adap, &anysee_tda18212_config);
951 break;
952 } else if (fe) {
953 break;
954 }
955
956 /* attach tuner */
957 fe = dvb_attach(dvb_pll_attach, adap->fe[0], (0xc0 >> 1),
958 &d->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
959
960 if (fe && adap->fe[1]) {
961 /* attach tuner for 2nd FE */
962 fe = dvb_attach(dvb_pll_attach, adap->fe[0],
963 (0xc0 >> 1), &d->i2c_adap,
964 DVB_PLL_SAMSUNG_DTOS403IH102A);
965 }
966
967 break;
968 case ANYSEE_HW_508TC: /* 18 */
969 case ANYSEE_HW_508PTC: /* 21 */
970 /* E7 TC */
971 /* E7 PTC */
972
973 /* attach tuner */
974 fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
975 &anysee_tda18212_config);
976
977 if (fe) {
978 /* attach tuner for 2nd FE */
979 fe = dvb_attach(tda18212_attach, adap->fe[1],
980 &d->i2c_adap, &anysee_tda18212_config);
981 }
982
983 break;
984 case ANYSEE_HW_508S2: /* 19 */
985 case ANYSEE_HW_508PS2: /* 22 */
986 /* E7 S2 */
987 /* E7 PS2 */
988
989 /* attach tuner */
990 fe = dvb_attach(stv6110_attach, adap->fe[0],
991 &anysee_stv6110_config, &d->i2c_adap);
992
993 if (fe) {
994 /* attach LNB controller */
995 fe = dvb_attach(isl6423_attach, adap->fe[0],
996 &d->i2c_adap, &anysee_isl6423_config);
997 }
998
999 break;
1000
1001 case ANYSEE_HW_508T2C: /* 20 */
1002 /* E7 T2C */
1003
1004 /* attach tuner */
1005 fe = dvb_attach(tda18212_attach, adap->fe[0], &d->i2c_adap,
1006 &anysee_tda18212_config2);
1007
1008 break;
1009 default:
1010 fe = NULL;
1011 }
1012
1013 if (fe)
1014 ret = 0;
1015 else
1016 ret = -ENODEV;
1017
1018 return ret;
1019}
1020
1021static int anysee_rc_query(struct dvb_usb_device *d)
1022{
1023 u8 buf[] = {CMD_GET_IR_CODE};
1024 u8 ircode[2];
1025 int ret;
1026
1027 /* Remote controller is basic NEC using address byte 0x08.
1028 Anysee device RC query returns only two bytes, status and code,
1029 address byte is dropped. Also it does not return any value for
1030 NEC RCs having address byte other than 0x08. Due to that, we
1031 cannot use that device as standard NEC receiver.
1032 It could be possible make hack which reads whole code directly
1033 from device memory... */
1034
1035 ret = anysee_ctrl_msg(d, buf, sizeof(buf), ircode, sizeof(ircode));
1036 if (ret)
1037 return ret;
1038
1039 if (ircode[0]) {
1040 deb_rc("%s: key pressed %02x\n", __func__, ircode[1]);
1041 rc_keydown(d->rc_dev, 0x08 << 8 | ircode[1], 0);
1042 }
1043
1044 return 0;
1045}
1046
1047static int anysee_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
1048{
1049 rc->allowed_protos = RC_TYPE_NEC;
1050 rc->query = anysee_rc_query;
1051 rc->interval = 250; /* windows driver uses 500ms */
1052
1053 return 0;
1054}
1055
1056static int anysee_ci_read_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
1057 int addr)
1058{
1059 struct dvb_usb_device *d = ci->data;
1060 int ret;
1061 u8 buf[] = {CMD_CI, 0x02, 0x40 | addr >> 8, addr & 0xff, 0x00, 1};
1062 u8 val;
1063
1064 ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
1065 if (ret)
1066 return ret;
1067
1068 return val;
1069}
1070
1071static int anysee_ci_write_attribute_mem(struct dvb_ca_en50221 *ci, int slot,
1072 int addr, u8 val)
1073{
1074 struct dvb_usb_device *d = ci->data;
1075 int ret;
1076 u8 buf[] = {CMD_CI, 0x03, 0x40 | addr >> 8, addr & 0xff, 0x00, 1, val};
1077
1078 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
1079 if (ret)
1080 return ret;
1081
1082 return 0;
1083}
1084
1085static int anysee_ci_read_cam_control(struct dvb_ca_en50221 *ci, int slot,
1086 u8 addr)
1087{
1088 struct dvb_usb_device *d = ci->data;
1089 int ret;
1090 u8 buf[] = {CMD_CI, 0x04, 0x40, addr, 0x00, 1};
1091 u8 val;
1092
1093 ret = anysee_ctrl_msg(d, buf, sizeof(buf), &val, 1);
1094 if (ret)
1095 return ret;
1096
1097 return val;
1098}
1099
1100static int anysee_ci_write_cam_control(struct dvb_ca_en50221 *ci, int slot,
1101 u8 addr, u8 val)
1102{
1103 struct dvb_usb_device *d = ci->data;
1104 int ret;
1105 u8 buf[] = {CMD_CI, 0x05, 0x40, addr, 0x00, 1, val};
1106
1107 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
1108 if (ret)
1109 return ret;
1110
1111 return 0;
1112}
1113
1114static int anysee_ci_slot_reset(struct dvb_ca_en50221 *ci, int slot)
1115{
1116 struct dvb_usb_device *d = ci->data;
1117 int ret;
1118 struct anysee_state *state = d_to_priv(d);
1119
1120 state->ci_cam_ready = jiffies + msecs_to_jiffies(1000);
1121
1122 ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
1123 if (ret)
1124 return ret;
1125
1126 msleep(300);
1127
1128 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1129 if (ret)
1130 return ret;
1131
1132 return 0;
1133}
1134
1135static int anysee_ci_slot_shutdown(struct dvb_ca_en50221 *ci, int slot)
1136{
1137 struct dvb_usb_device *d = ci->data;
1138 int ret;
1139
1140 ret = anysee_wr_reg_mask(d, REG_IOA, (0 << 7), 0x80);
1141 if (ret)
1142 return ret;
1143
1144 msleep(30);
1145
1146 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1147 if (ret)
1148 return ret;
1149
1150 return 0;
1151}
1152
1153static int anysee_ci_slot_ts_enable(struct dvb_ca_en50221 *ci, int slot)
1154{
1155 struct dvb_usb_device *d = ci->data;
1156 int ret;
1157
1158 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 1), 0x02);
1159 if (ret)
1160 return ret;
1161
1162 return 0;
1163}
1164
1165static int anysee_ci_poll_slot_status(struct dvb_ca_en50221 *ci, int slot,
1166 int open)
1167{
1168 struct dvb_usb_device *d = ci->data;
1169 struct anysee_state *state = d_to_priv(d);
1170 int ret;
1171 u8 tmp;
1172
1173 ret = anysee_rd_reg_mask(d, REG_IOC, &tmp, 0x40);
1174 if (ret)
1175 return ret;
1176
1177 if (tmp == 0) {
1178 ret = DVB_CA_EN50221_POLL_CAM_PRESENT;
1179 if (time_after(jiffies, state->ci_cam_ready))
1180 ret |= DVB_CA_EN50221_POLL_CAM_READY;
1181 }
1182
1183 return ret;
1184}
1185
1186static int anysee_ci_init(struct dvb_usb_device *d)
1187{
1188 struct anysee_state *state = d_to_priv(d);
1189 int ret;
1190
1191 state->ci.owner = THIS_MODULE;
1192 state->ci.read_attribute_mem = anysee_ci_read_attribute_mem;
1193 state->ci.write_attribute_mem = anysee_ci_write_attribute_mem;
1194 state->ci.read_cam_control = anysee_ci_read_cam_control;
1195 state->ci.write_cam_control = anysee_ci_write_cam_control;
1196 state->ci.slot_reset = anysee_ci_slot_reset;
1197 state->ci.slot_shutdown = anysee_ci_slot_shutdown;
1198 state->ci.slot_ts_enable = anysee_ci_slot_ts_enable;
1199 state->ci.poll_slot_status = anysee_ci_poll_slot_status;
1200 state->ci.data = d;
1201
1202 ret = anysee_wr_reg_mask(d, REG_IOA, (1 << 7), 0x80);
1203 if (ret)
1204 return ret;
1205
1206 ret = anysee_wr_reg_mask(d, REG_IOD, (0 << 2)|(0 << 1)|(0 << 0), 0x07);
1207 if (ret)
1208 return ret;
1209
1210 ret = anysee_wr_reg_mask(d, REG_IOD, (1 << 2)|(1 << 1)|(1 << 0), 0x07);
1211 if (ret)
1212 return ret;
1213
1214 ret = dvb_ca_en50221_init(&d->adapter[0].dvb_adap, &state->ci, 0, 1);
1215 if (ret)
1216 return ret;
1217
1218 return 0;
1219}
1220
1221static void anysee_ci_release(struct dvb_usb_device *d)
1222{
1223 struct anysee_state *state = d_to_priv(d);
1224
1225 /* detach CI */
1226 if (state->has_ci)
1227 dvb_ca_en50221_release(&state->ci);
1228
1229 return;
1230}
1231
1232static int anysee_init(struct dvb_usb_device *d)
1233{
1234 struct anysee_state *state = d_to_priv(d);
1235 int ret;
1236
1237 /* There is one interface with two alternate settings.
1238 Alternate setting 0 is for bulk transfer.
1239 Alternate setting 1 is for isochronous transfer.
1240 We use bulk transfer (alternate setting 0). */
1241 ret = usb_set_interface(d->udev, 0, 0);
1242 if (ret)
1243 return ret;
1244
1245 /* LED light */
1246 ret = anysee_led_ctrl(d, 0x01, 0x03);
1247 if (ret)
1248 return ret;
1249
1250 /* enable IR */
1251 ret = anysee_ir_ctrl(d, 1);
1252 if (ret)
1253 return ret;
1254
1255 /* attach CI */
1256 if (state->has_ci) {
1257 ret = anysee_ci_init(d);
1258 if (ret) {
1259 state->has_ci = false;
1260 return ret;
1261 }
1262 }
1263
1264 return 0;
1265}
1266
1267static void anysee_exit(struct dvb_usb_device *d)
1268{
1269 return anysee_ci_release(d);
1270}
1271
1272/* DVB USB Driver stuff */
1273static struct dvb_usb_device_properties anysee_props = {
1274 .driver_name = KBUILD_MODNAME,
1275 .owner = THIS_MODULE,
1276 .adapter_nr = adapter_nr,
1277 .size_of_priv = sizeof(struct anysee_state),
1278
1279 .generic_bulk_ctrl_endpoint = 0x01,
1280 .generic_bulk_ctrl_endpoint_response = 0x81,
1281
1282 .i2c_algo = &anysee_i2c_algo,
1283 .read_config = anysee_read_config,
1284 .frontend_attach = anysee_frontend_attach,
1285 .tuner_attach = anysee_tuner_attach,
1286 .init = anysee_init,
1287 .get_rc_config = anysee_get_rc_config,
1288 .frontend_ctrl = anysee_frontend_ctrl,
1289 .streaming_ctrl = anysee_streaming_ctrl,
1290 .exit = anysee_exit,
1291
1292 .num_adapters = 1,
1293 .adapter = {
1294 {
1295 .stream = DVB_USB_STREAM_BULK(0x82, 8, 16 * 512),
1296 }
1297 }
1298};
1299
1300static const struct usb_device_id anysee_id_table[] = {
1301 { DVB_USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE,
1302 &anysee_props, "Anysee", RC_MAP_ANYSEE) },
1303 { DVB_USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE,
1304 &anysee_props, "Anysee", RC_MAP_ANYSEE) },
1305 { }
1306};
1307MODULE_DEVICE_TABLE(usb, anysee_id_table);
1308
1309static struct usb_driver anysee_usb_driver = {
1310 .name = KBUILD_MODNAME,
1311 .id_table = anysee_id_table,
1312 .probe = dvb_usbv2_probe,
1313 .disconnect = dvb_usbv2_disconnect,
1314 .suspend = dvb_usbv2_suspend,
1315 .resume = dvb_usbv2_resume,
1316 .no_dynamic_id = 1,
1317 .soft_unbind = 1,
1318};
1319
1320module_usb_driver(anysee_usb_driver);
1321
1322MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1323MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
1324MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/anysee.h b/drivers/media/usb/dvb-usb-v2/anysee.h
new file mode 100644
index 000000000000..dc40dcf7c328
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/anysee.h
@@ -0,0 +1,356 @@
1/*
2 * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * TODO:
21 * - add smart card reader support for Conditional Access (CA)
22 *
23 * Card reader in Anysee is nothing more than ISO 7816 card reader.
24 * There is no hardware CAM in any Anysee device sold.
25 * In my understanding it should be implemented by making own module
26 * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
27 * module registers serial interface that can be used to communicate
28 * with any ISO 7816 smart card.
29 *
30 * Any help according to implement serial smart card reader support
31 * is highly welcome!
32 */
33
34#ifndef _DVB_USB_ANYSEE_H_
35#define _DVB_USB_ANYSEE_H_
36
37#define DVB_USB_LOG_PREFIX "anysee"
38#include "dvb_usb.h"
39#include "dvb_ca_en50221.h"
40
41#ifdef CONFIG_DVB_USB_DEBUG
42#define dprintk(var, level, args...) \
43 do { if ((var & level)) printk(args); } while (0)
44#define DVB_USB_DEBUG_STATUS
45#else
46#define dprintk(args...)
47#define debug_dump(b, l, func)
48#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
49#endif
50
51#define debug_dump(b, l, func) {\
52 int loop_; \
53 for (loop_ = 0; loop_ < l; loop_++) \
54 func("%02x ", b[loop_]); \
55 func("\n");\
56}
57
58#define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args)
59#define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args)
60#define deb_rc(args...) dprintk(dvb_usb_anysee_debug, 0x04, args)
61#define deb_reg(args...) dprintk(dvb_usb_anysee_debug, 0x08, args)
62#define deb_i2c(args...) dprintk(dvb_usb_anysee_debug, 0x10, args)
63#define deb_fw(args...) dprintk(dvb_usb_anysee_debug, 0x20, args)
64
65#undef err
66#define err(format, arg...) printk(KERN_ERR DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
67#undef info
68#define info(format, arg...) printk(KERN_INFO DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
69#undef warn
70#define warn(format, arg...) printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
71
72enum cmd {
73 CMD_I2C_READ = 0x33,
74 CMD_I2C_WRITE = 0x31,
75 CMD_REG_READ = 0xb0,
76 CMD_REG_WRITE = 0xb1,
77 CMD_STREAMING_CTRL = 0x12,
78 CMD_LED_AND_IR_CTRL = 0x16,
79 CMD_GET_IR_CODE = 0x41,
80 CMD_GET_HW_INFO = 0x19,
81 CMD_SMARTCARD = 0x34,
82 CMD_CI = 0x37,
83};
84
85struct anysee_state {
86 u8 hw; /* PCB ID */
87 u8 seq;
88 u8 fe_id:1; /* frondend ID */
89 u8 has_ci:1;
90 struct dvb_ca_en50221 ci;
91 unsigned long ci_cam_ready; /* jiffies */
92};
93
94#define ANYSEE_HW_507T 2 /* E30 */
95#define ANYSEE_HW_507CD 6 /* E30 Plus */
96#define ANYSEE_HW_507DC 10 /* E30 C Plus */
97#define ANYSEE_HW_507SI 11 /* E30 S2 Plus */
98#define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */
99#define ANYSEE_HW_508TC 18 /* E7 TC */
100#define ANYSEE_HW_508S2 19 /* E7 S2 */
101#define ANYSEE_HW_508T2C 20 /* E7 T2C */
102#define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */
103#define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */
104
105#define REG_IOA 0x80 /* Port A (bit addressable) */
106#define REG_IOB 0x90 /* Port B (bit addressable) */
107#define REG_IOC 0xa0 /* Port C (bit addressable) */
108#define REG_IOD 0xb0 /* Port D (bit addressable) */
109#define REG_IOE 0xb1 /* Port E (NOT bit addressable) */
110#define REG_OEA 0xb2 /* Port A Output Enable */
111#define REG_OEB 0xb3 /* Port B Output Enable */
112#define REG_OEC 0xb4 /* Port C Output Enable */
113#define REG_OED 0xb5 /* Port D Output Enable */
114#define REG_OEE 0xb6 /* Port E Output Enable */
115
116#endif
117
118/***************************************************************************
119 * USB API description (reverse engineered)
120 ***************************************************************************
121
122Transaction flow:
123=================
124BULK[00001] >>> REQUEST PACKET 64 bytes
125BULK[00081] <<< REPLY PACKET #1 64 bytes (PREVIOUS TRANSACTION REPLY)
126BULK[00081] <<< REPLY PACKET #2 64 bytes (CURRENT TRANSACTION REPLY)
127
128General reply packet(s) are always used if not own reply defined.
129
130============================================================================
131| 00-63 | GENERAL REPLY PACKET #1 (PREVIOUS REPLY)
132============================================================================
133| 00 | reply data (if any) from previous transaction
134| | Just same reply packet as returned during previous transaction.
135| | Needed only if reply is missed in previous transaction.
136| | Just skip normally.
137----------------------------------------------------------------------------
138| 01-59 | don't care
139----------------------------------------------------------------------------
140| 60 | packet sequence number
141----------------------------------------------------------------------------
142| 61-63 | don't care
143----------------------------------------------------------------------------
144
145============================================================================
146| 00-63 | GENERAL REPLY PACKET #2 (CURRENT REPLY)
147============================================================================
148| 00 | reply data (if any)
149----------------------------------------------------------------------------
150| 01-59 | don't care
151----------------------------------------------------------------------------
152| 60 | packet sequence number
153----------------------------------------------------------------------------
154| 61-63 | don't care
155----------------------------------------------------------------------------
156
157============================================================================
158| 00-63 | I2C WRITE REQUEST PACKET
159============================================================================
160| 00 | 0x31 I2C write command
161----------------------------------------------------------------------------
162| 01 | i2c address
163----------------------------------------------------------------------------
164| 02 | data length
165| | 0x02 (for typical I2C reg / val pair)
166----------------------------------------------------------------------------
167| 03 | 0x01
168----------------------------------------------------------------------------
169| 04- | data
170----------------------------------------------------------------------------
171| -59 | don't care
172----------------------------------------------------------------------------
173| 60 | packet sequence number
174----------------------------------------------------------------------------
175| 61-63 | don't care
176----------------------------------------------------------------------------
177
178============================================================================
179| 00-63 | I2C READ REQUEST PACKET
180============================================================================
181| 00 | 0x33 I2C read command
182----------------------------------------------------------------------------
183| 01 | i2c address + 1
184----------------------------------------------------------------------------
185| 02 | register
186----------------------------------------------------------------------------
187| 03 | 0x00
188----------------------------------------------------------------------------
189| 04 | 0x00
190----------------------------------------------------------------------------
191| 05 | data length
192----------------------------------------------------------------------------
193| 06-59 | don't care
194----------------------------------------------------------------------------
195| 60 | packet sequence number
196----------------------------------------------------------------------------
197| 61-63 | don't care
198----------------------------------------------------------------------------
199
200============================================================================
201| 00-63 | USB CONTROLLER REGISTER WRITE REQUEST PACKET
202============================================================================
203| 00 | 0xb1 register write command
204----------------------------------------------------------------------------
205| 01-02 | register
206----------------------------------------------------------------------------
207| 03 | 0x01
208----------------------------------------------------------------------------
209| 04 | value
210----------------------------------------------------------------------------
211| 05-59 | don't care
212----------------------------------------------------------------------------
213| 60 | packet sequence number
214----------------------------------------------------------------------------
215| 61-63 | don't care
216----------------------------------------------------------------------------
217
218============================================================================
219| 00-63 | USB CONTROLLER REGISTER READ REQUEST PACKET
220============================================================================
221| 00 | 0xb0 register read command
222----------------------------------------------------------------------------
223| 01-02 | register
224----------------------------------------------------------------------------
225| 03 | 0x01
226----------------------------------------------------------------------------
227| 04-59 | don't care
228----------------------------------------------------------------------------
229| 60 | packet sequence number
230----------------------------------------------------------------------------
231| 61-63 | don't care
232----------------------------------------------------------------------------
233
234============================================================================
235| 00-63 | LED CONTROL REQUEST PACKET
236============================================================================
237| 00 | 0x16 LED and IR control command
238----------------------------------------------------------------------------
239| 01 | 0x01 (LED)
240----------------------------------------------------------------------------
241| 03 | 0x00 blink
242| | 0x01 lights continuously
243----------------------------------------------------------------------------
244| 04 | blink interval
245| | 0x00 fastest (looks like LED lights continuously)
246| | 0xff slowest
247----------------------------------------------------------------------------
248| 05-59 | don't care
249----------------------------------------------------------------------------
250| 60 | packet sequence number
251----------------------------------------------------------------------------
252| 61-63 | don't care
253----------------------------------------------------------------------------
254
255============================================================================
256| 00-63 | IR CONTROL REQUEST PACKET
257============================================================================
258| 00 | 0x16 LED and IR control command
259----------------------------------------------------------------------------
260| 01 | 0x02 (IR)
261----------------------------------------------------------------------------
262| 03 | 0x00 IR disabled
263| | 0x01 IR enabled
264----------------------------------------------------------------------------
265| 04-59 | don't care
266----------------------------------------------------------------------------
267| 60 | packet sequence number
268----------------------------------------------------------------------------
269| 61-63 | don't care
270----------------------------------------------------------------------------
271
272============================================================================
273| 00-63 | STREAMING CONTROL REQUEST PACKET
274============================================================================
275| 00 | 0x12 streaming control command
276----------------------------------------------------------------------------
277| 01 | 0x00 streaming disabled
278| | 0x01 streaming enabled
279----------------------------------------------------------------------------
280| 02 | 0x00
281----------------------------------------------------------------------------
282| 03-59 | don't care
283----------------------------------------------------------------------------
284| 60 | packet sequence number
285----------------------------------------------------------------------------
286| 61-63 | don't care
287----------------------------------------------------------------------------
288
289============================================================================
290| 00-63 | REMOTE CONTROL REQUEST PACKET
291============================================================================
292| 00 | 0x41 remote control command
293----------------------------------------------------------------------------
294| 01-59 | don't care
295----------------------------------------------------------------------------
296| 60 | packet sequence number
297----------------------------------------------------------------------------
298| 61-63 | don't care
299----------------------------------------------------------------------------
300
301============================================================================
302| 00-63 | REMOTE CONTROL REPLY PACKET
303============================================================================
304| 00 | 0x00 code not received
305| | 0x01 code received
306----------------------------------------------------------------------------
307| 01 | remote control code
308----------------------------------------------------------------------------
309| 02-59 | don't care
310----------------------------------------------------------------------------
311| 60 | packet sequence number
312----------------------------------------------------------------------------
313| 61-63 | don't care
314----------------------------------------------------------------------------
315
316============================================================================
317| 00-63 | GET HARDWARE INFO REQUEST PACKET
318============================================================================
319| 00 | 0x19 get hardware info command
320----------------------------------------------------------------------------
321| 01-59 | don't care
322----------------------------------------------------------------------------
323| 60 | packet sequence number
324----------------------------------------------------------------------------
325| 61-63 | don't care
326----------------------------------------------------------------------------
327
328============================================================================
329| 00-63 | GET HARDWARE INFO REPLY PACKET
330============================================================================
331| 00 | hardware id
332----------------------------------------------------------------------------
333| 01-02 | firmware version
334----------------------------------------------------------------------------
335| 03-59 | don't care
336----------------------------------------------------------------------------
337| 60 | packet sequence number
338----------------------------------------------------------------------------
339| 61-63 | don't care
340----------------------------------------------------------------------------
341
342============================================================================
343| 00-63 | SMART CARD READER PACKET
344============================================================================
345| 00 | 0x34 smart card reader command
346----------------------------------------------------------------------------
347| xx |
348----------------------------------------------------------------------------
349| xx-59 | don't care
350----------------------------------------------------------------------------
351| 60 | packet sequence number
352----------------------------------------------------------------------------
353| 61-63 | don't care
354----------------------------------------------------------------------------
355
356*/
diff --git a/drivers/media/usb/dvb-usb-v2/au6610.c b/drivers/media/usb/dvb-usb-v2/au6610.c
new file mode 100644
index 000000000000..05f2a8628142
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/au6610.c
@@ -0,0 +1,206 @@
1/*
2 * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
3 *
4 * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "au6610.h"
22#include "zl10353.h"
23#include "qt1010.h"
24
25DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
26
27static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
28 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
29{
30 int ret;
31 u16 index;
32 u8 *usb_buf;
33
34 /*
35 * allocate enough for all known requests,
36 * read returns 5 and write 6 bytes
37 */
38 usb_buf = kmalloc(6, GFP_KERNEL);
39 if (!usb_buf)
40 return -ENOMEM;
41
42 switch (wlen) {
43 case 1:
44 index = wbuf[0] << 8;
45 break;
46 case 2:
47 index = wbuf[0] << 8;
48 index += wbuf[1];
49 break;
50 default:
51 pr_err("%s: wlen = %d, aborting\n", KBUILD_MODNAME, wlen);
52 ret = -EINVAL;
53 goto error;
54 }
55
56 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
57 USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index,
58 usb_buf, 6, AU6610_USB_TIMEOUT);
59 if (ret < 0)
60 goto error;
61
62 switch (operation) {
63 case AU6610_REQ_I2C_READ:
64 case AU6610_REQ_USB_READ:
65 /* requested value is always 5th byte in buffer */
66 rbuf[0] = usb_buf[4];
67 }
68error:
69 kfree(usb_buf);
70 return ret;
71}
72
73static int au6610_i2c_msg(struct dvb_usb_device *d, u8 addr,
74 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
75{
76 u8 request;
77 u8 wo = (rbuf == NULL || rlen == 0); /* write-only */
78
79 if (wo) {
80 request = AU6610_REQ_I2C_WRITE;
81 } else { /* rw */
82 request = AU6610_REQ_I2C_READ;
83 }
84
85 return au6610_usb_msg(d, request, addr, wbuf, wlen, rbuf, rlen);
86}
87
88
89/* I2C */
90static int au6610_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
91 int num)
92{
93 struct dvb_usb_device *d = i2c_get_adapdata(adap);
94 int i;
95
96 if (num > 2)
97 return -EINVAL;
98
99 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
100 return -EAGAIN;
101
102 for (i = 0; i < num; i++) {
103 /* write/read request */
104 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
105 if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf,
106 msg[i].len, msg[i+1].buf,
107 msg[i+1].len) < 0)
108 break;
109 i++;
110 } else if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf,
111 msg[i].len, NULL, 0) < 0)
112 break;
113 }
114
115 mutex_unlock(&d->i2c_mutex);
116 return i;
117}
118
119
120static u32 au6610_i2c_func(struct i2c_adapter *adapter)
121{
122 return I2C_FUNC_I2C;
123}
124
125static struct i2c_algorithm au6610_i2c_algo = {
126 .master_xfer = au6610_i2c_xfer,
127 .functionality = au6610_i2c_func,
128};
129
130/* Callbacks for DVB USB */
131static struct zl10353_config au6610_zl10353_config = {
132 .demod_address = 0x0f,
133 .no_tuner = 1,
134 .parallel_ts = 1,
135};
136
137static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
138{
139 adap->fe[0] = dvb_attach(zl10353_attach, &au6610_zl10353_config,
140 &adap_to_d(adap)->i2c_adap);
141 if (adap->fe[0] == NULL)
142 return -ENODEV;
143
144 return 0;
145}
146
147static struct qt1010_config au6610_qt1010_config = {
148 .i2c_address = 0x62
149};
150
151static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
152{
153 return dvb_attach(qt1010_attach, adap->fe[0],
154 &adap_to_d(adap)->i2c_adap,
155 &au6610_qt1010_config) == NULL ? -ENODEV : 0;
156}
157
158static int au6610_init(struct dvb_usb_device *d)
159{
160 /* TODO: this functionality belongs likely to the streaming control */
161 /* bInterfaceNumber 0, bAlternateSetting 5 */
162 return usb_set_interface(d->udev, 0, 5);
163}
164
165static struct dvb_usb_device_properties au6610_props = {
166 .driver_name = KBUILD_MODNAME,
167 .owner = THIS_MODULE,
168 .adapter_nr = adapter_nr,
169
170 .i2c_algo = &au6610_i2c_algo,
171 .frontend_attach = au6610_zl10353_frontend_attach,
172 .tuner_attach = au6610_qt1010_tuner_attach,
173 .init = au6610_init,
174
175 .num_adapters = 1,
176 .adapter = {
177 {
178 .stream = DVB_USB_STREAM_ISOC(0x82, 5, 40, 942, 1),
179 },
180 },
181};
182
183static const struct usb_device_id au6610_id_table[] = {
184 { DVB_USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110,
185 &au6610_props, "Sigmatek DVB-110", NULL) },
186 { }
187};
188MODULE_DEVICE_TABLE(usb, au6610_id_table);
189
190static struct usb_driver au6610_driver = {
191 .name = KBUILD_MODNAME,
192 .id_table = au6610_id_table,
193 .probe = dvb_usbv2_probe,
194 .disconnect = dvb_usbv2_disconnect,
195 .suspend = dvb_usbv2_suspend,
196 .resume = dvb_usbv2_resume,
197 .no_dynamic_id = 1,
198 .soft_unbind = 1,
199};
200
201module_usb_driver(au6610_driver);
202
203MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
204MODULE_DESCRIPTION("Driver for Alcor Micro AU6610 DVB-T USB2.0");
205MODULE_VERSION("0.1");
206MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/au6610.h b/drivers/media/usb/dvb-usb-v2/au6610.h
new file mode 100644
index 000000000000..ea337bfc00b1
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/au6610.h
@@ -0,0 +1,32 @@
1/*
2 * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
3 *
4 * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef AU6610_H
22#define AU6610_H
23#include "dvb_usb.h"
24
25#define AU6610_REQ_I2C_WRITE 0x14
26#define AU6610_REQ_I2C_READ 0x13
27#define AU6610_REQ_USB_WRITE 0x16
28#define AU6610_REQ_USB_READ 0x15
29
30#define AU6610_USB_TIMEOUT 1000
31
32#endif
diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c
new file mode 100644
index 000000000000..54f1221d930d
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/az6007.c
@@ -0,0 +1,919 @@
1/*
2 * Driver for AzureWave 6007 DVB-C/T USB2.0 and clones
3 *
4 * Copyright (c) Henry Wang <Henry.wang@AzureWave.com>
5 *
6 * This driver was made publicly available by Terratec, at:
7 * http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
8 * The original driver's license is GPL, as declared with MODULE_LICENSE()
9 *
10 * Copyright (c) 2010-2012 Mauro Carvalho Chehab <mchehab@redhat.com>
11 * Driver modified by in order to work with upstream drxk driver, and
12 * tons of bugs got fixed, and converted to use dvb-usb-v2.
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 under version 2 of the License.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 */
23
24#include "drxk.h"
25#include "mt2063.h"
26#include "dvb_ca_en50221.h"
27#include "dvb_usb.h"
28#include "cypress_firmware.h"
29
30#define AZ6007_FIRMWARE "dvb-usb-terratec-h7-az6007.fw"
31
32static int az6007_xfer_debug;
33module_param_named(xfer_debug, az6007_xfer_debug, int, 0644);
34MODULE_PARM_DESC(xfer_debug, "Enable xfer debug");
35
36DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
37
38/* Known requests (Cypress FX2 firmware + az6007 "private" ones*/
39
40#define FX2_OED 0xb5
41#define AZ6007_READ_DATA 0xb7
42#define AZ6007_I2C_RD 0xb9
43#define AZ6007_POWER 0xbc
44#define AZ6007_I2C_WR 0xbd
45#define FX2_SCON1 0xc0
46#define AZ6007_TS_THROUGH 0xc7
47#define AZ6007_READ_IR 0xb4
48
49struct az6007_device_state {
50 struct mutex mutex;
51 struct mutex ca_mutex;
52 struct dvb_ca_en50221 ca;
53 unsigned warm:1;
54 int (*gate_ctrl) (struct dvb_frontend *, int);
55 unsigned char data[4096];
56};
57
58static struct drxk_config terratec_h7_drxk = {
59 .adr = 0x29,
60 .parallel_ts = true,
61 .dynamic_clk = true,
62 .single_master = true,
63 .enable_merr_cfg = true,
64 .no_i2c_bridge = false,
65 .chunk_size = 64,
66 .mpeg_out_clk_strength = 0x02,
67 .qam_demod_parameter_count = 2,
68 .microcode_name = "dvb-usb-terratec-h7-drxk.fw",
69};
70
71static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
72{
73 struct az6007_device_state *st = fe_to_priv(fe);
74 struct dvb_usb_adapter *adap = fe->sec_priv;
75 int status = 0;
76
77 pr_debug("%s: %s\n", __func__, enable ? "enable" : "disable");
78
79 if (!adap || !st)
80 return -EINVAL;
81
82 if (enable)
83 status = st->gate_ctrl(fe, 1);
84 else
85 status = st->gate_ctrl(fe, 0);
86
87 return status;
88}
89
90static struct mt2063_config az6007_mt2063_config = {
91 .tuner_address = 0x60,
92 .refclock = 36125000,
93};
94
95static int __az6007_read(struct usb_device *udev, u8 req, u16 value,
96 u16 index, u8 *b, int blen)
97{
98 int ret;
99
100 ret = usb_control_msg(udev,
101 usb_rcvctrlpipe(udev, 0),
102 req,
103 USB_TYPE_VENDOR | USB_DIR_IN,
104 value, index, b, blen, 5000);
105 if (ret < 0) {
106 pr_warn("usb read operation failed. (%d)\n", ret);
107 return -EIO;
108 }
109
110 if (az6007_xfer_debug) {
111 printk(KERN_DEBUG "az6007: IN req: %02x, value: %04x, index: %04x\n",
112 req, value, index);
113 print_hex_dump_bytes("az6007: payload: ",
114 DUMP_PREFIX_NONE, b, blen);
115 }
116
117 return ret;
118}
119
120static int az6007_read(struct dvb_usb_device *d, u8 req, u16 value,
121 u16 index, u8 *b, int blen)
122{
123 struct az6007_device_state *st = d->priv;
124 int ret;
125
126 if (mutex_lock_interruptible(&st->mutex) < 0)
127 return -EAGAIN;
128
129 ret = __az6007_read(d->udev, req, value, index, b, blen);
130
131 mutex_unlock(&st->mutex);
132
133 return ret;
134}
135
136static int __az6007_write(struct usb_device *udev, u8 req, u16 value,
137 u16 index, u8 *b, int blen)
138{
139 int ret;
140
141 if (az6007_xfer_debug) {
142 printk(KERN_DEBUG "az6007: OUT req: %02x, value: %04x, index: %04x\n",
143 req, value, index);
144 print_hex_dump_bytes("az6007: payload: ",
145 DUMP_PREFIX_NONE, b, blen);
146 }
147
148 if (blen > 64) {
149 pr_err("az6007: tried to write %d bytes, but I2C max size is 64 bytes\n",
150 blen);
151 return -EOPNOTSUPP;
152 }
153
154 ret = usb_control_msg(udev,
155 usb_sndctrlpipe(udev, 0),
156 req,
157 USB_TYPE_VENDOR | USB_DIR_OUT,
158 value, index, b, blen, 5000);
159 if (ret != blen) {
160 pr_err("usb write operation failed. (%d)\n", ret);
161 return -EIO;
162 }
163
164 return 0;
165}
166
167static int az6007_write(struct dvb_usb_device *d, u8 req, u16 value,
168 u16 index, u8 *b, int blen)
169{
170 struct az6007_device_state *st = d->priv;
171 int ret;
172
173 if (mutex_lock_interruptible(&st->mutex) < 0)
174 return -EAGAIN;
175
176 ret = __az6007_write(d->udev, req, value, index, b, blen);
177
178 mutex_unlock(&st->mutex);
179
180 return ret;
181}
182
183static int az6007_streaming_ctrl(struct dvb_frontend *fe, int onoff)
184{
185 struct dvb_usb_device *d = fe_to_d(fe);
186
187 pr_debug("%s: %s\n", __func__, onoff ? "enable" : "disable");
188
189 return az6007_write(d, 0xbc, onoff, 0, NULL, 0);
190}
191
192/* remote control stuff (does not work with my box) */
193static int az6007_rc_query(struct dvb_usb_device *d)
194{
195 struct az6007_device_state *st = d_to_priv(d);
196 unsigned code = 0;
197
198 az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10);
199
200 if (st->data[1] == 0x44)
201 return 0;
202
203 if ((st->data[1] ^ st->data[2]) == 0xff)
204 code = st->data[1];
205 else
206 code = st->data[1] << 8 | st->data[2];
207
208 if ((st->data[3] ^ st->data[4]) == 0xff)
209 code = code << 8 | st->data[3];
210 else
211 code = code << 16 | st->data[3] << 8 | st->data[4];
212
213 rc_keydown(d->rc_dev, code, st->data[5]);
214
215 return 0;
216}
217
218static int az6007_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
219 int slot,
220 int address)
221{
222 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
223 struct az6007_device_state *state = d_to_priv(d);
224
225 int ret;
226 u8 req;
227 u16 value;
228 u16 index;
229 int blen;
230 u8 *b;
231
232 if (slot != 0)
233 return -EINVAL;
234
235 b = kmalloc(12, GFP_KERNEL);
236 if (!b)
237 return -ENOMEM;
238
239 mutex_lock(&state->ca_mutex);
240
241 req = 0xC1;
242 value = address;
243 index = 0;
244 blen = 1;
245
246 ret = az6007_read(d, req, value, index, b, blen);
247 if (ret < 0) {
248 pr_warn("usb in operation failed. (%d)\n", ret);
249 ret = -EINVAL;
250 } else {
251 ret = b[0];
252 }
253
254 mutex_unlock(&state->ca_mutex);
255 kfree(b);
256 return ret;
257}
258
259static int az6007_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
260 int slot,
261 int address,
262 u8 value)
263{
264 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
265 struct az6007_device_state *state = d_to_priv(d);
266
267 int ret;
268 u8 req;
269 u16 value1;
270 u16 index;
271 int blen;
272
273 pr_debug("%s(), slot %d\n", __func__, slot);
274 if (slot != 0)
275 return -EINVAL;
276
277 mutex_lock(&state->ca_mutex);
278 req = 0xC2;
279 value1 = address;
280 index = value;
281 blen = 0;
282
283 ret = az6007_write(d, req, value1, index, NULL, blen);
284 if (ret != 0)
285 pr_warn("usb out operation failed. (%d)\n", ret);
286
287 mutex_unlock(&state->ca_mutex);
288 return ret;
289}
290
291static int az6007_ci_read_cam_control(struct dvb_ca_en50221 *ca,
292 int slot,
293 u8 address)
294{
295 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
296 struct az6007_device_state *state = d_to_priv(d);
297
298 int ret;
299 u8 req;
300 u16 value;
301 u16 index;
302 int blen;
303 u8 *b;
304
305 if (slot != 0)
306 return -EINVAL;
307
308 b = kmalloc(12, GFP_KERNEL);
309 if (!b)
310 return -ENOMEM;
311
312 mutex_lock(&state->ca_mutex);
313
314 req = 0xC3;
315 value = address;
316 index = 0;
317 blen = 2;
318
319 ret = az6007_read(d, req, value, index, b, blen);
320 if (ret < 0) {
321 pr_warn("usb in operation failed. (%d)\n", ret);
322 ret = -EINVAL;
323 } else {
324 if (b[0] == 0)
325 pr_warn("Read CI IO error\n");
326
327 ret = b[1];
328 pr_debug("read cam data = %x from 0x%x\n", b[1], value);
329 }
330
331 mutex_unlock(&state->ca_mutex);
332 kfree(b);
333 return ret;
334}
335
336static int az6007_ci_write_cam_control(struct dvb_ca_en50221 *ca,
337 int slot,
338 u8 address,
339 u8 value)
340{
341 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
342 struct az6007_device_state *state = d_to_priv(d);
343
344 int ret;
345 u8 req;
346 u16 value1;
347 u16 index;
348 int blen;
349
350 if (slot != 0)
351 return -EINVAL;
352
353 mutex_lock(&state->ca_mutex);
354 req = 0xC4;
355 value1 = address;
356 index = value;
357 blen = 0;
358
359 ret = az6007_write(d, req, value1, index, NULL, blen);
360 if (ret != 0) {
361 pr_warn("usb out operation failed. (%d)\n", ret);
362 goto failed;
363 }
364
365failed:
366 mutex_unlock(&state->ca_mutex);
367 return ret;
368}
369
370static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
371{
372 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
373
374 int ret;
375 u8 req;
376 u16 value;
377 u16 index;
378 int blen;
379 u8 *b;
380
381 b = kmalloc(12, GFP_KERNEL);
382 if (!b)
383 return -ENOMEM;
384
385 req = 0xC8;
386 value = 0;
387 index = 0;
388 blen = 1;
389
390 ret = az6007_read(d, req, value, index, b, blen);
391 if (ret < 0) {
392 pr_warn("usb in operation failed. (%d)\n", ret);
393 ret = -EIO;
394 } else{
395 ret = b[0];
396 }
397 kfree(b);
398 return ret;
399}
400
401static int az6007_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
402{
403 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
404 struct az6007_device_state *state = d_to_priv(d);
405
406 int ret, i;
407 u8 req;
408 u16 value;
409 u16 index;
410 int blen;
411
412 mutex_lock(&state->ca_mutex);
413
414 req = 0xC6;
415 value = 1;
416 index = 0;
417 blen = 0;
418
419 ret = az6007_write(d, req, value, index, NULL, blen);
420 if (ret != 0) {
421 pr_warn("usb out operation failed. (%d)\n", ret);
422 goto failed;
423 }
424
425 msleep(500);
426 req = 0xC6;
427 value = 0;
428 index = 0;
429 blen = 0;
430
431 ret = az6007_write(d, req, value, index, NULL, blen);
432 if (ret != 0) {
433 pr_warn("usb out operation failed. (%d)\n", ret);
434 goto failed;
435 }
436
437 for (i = 0; i < 15; i++) {
438 msleep(100);
439
440 if (CI_CamReady(ca, slot)) {
441 pr_debug("CAM Ready\n");
442 break;
443 }
444 }
445 msleep(5000);
446
447failed:
448 mutex_unlock(&state->ca_mutex);
449 return ret;
450}
451
452static int az6007_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
453{
454 return 0;
455}
456
457static int az6007_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
458{
459 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
460 struct az6007_device_state *state = d_to_priv(d);
461
462 int ret;
463 u8 req;
464 u16 value;
465 u16 index;
466 int blen;
467
468 pr_debug("%s()\n", __func__);
469 mutex_lock(&state->ca_mutex);
470 req = 0xC7;
471 value = 1;
472 index = 0;
473 blen = 0;
474
475 ret = az6007_write(d, req, value, index, NULL, blen);
476 if (ret != 0) {
477 pr_warn("usb out operation failed. (%d)\n", ret);
478 goto failed;
479 }
480
481failed:
482 mutex_unlock(&state->ca_mutex);
483 return ret;
484}
485
486static int az6007_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
487{
488 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
489 struct az6007_device_state *state = d_to_priv(d);
490 int ret;
491 u8 req;
492 u16 value;
493 u16 index;
494 int blen;
495 u8 *b;
496
497 b = kmalloc(12, GFP_KERNEL);
498 if (!b)
499 return -ENOMEM;
500 mutex_lock(&state->ca_mutex);
501
502 req = 0xC5;
503 value = 0;
504 index = 0;
505 blen = 1;
506
507 ret = az6007_read(d, req, value, index, b, blen);
508 if (ret < 0) {
509 pr_warn("usb in operation failed. (%d)\n", ret);
510 ret = -EIO;
511 } else
512 ret = 0;
513
514 if (!ret && b[0] == 1) {
515 ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
516 DVB_CA_EN50221_POLL_CAM_READY;
517 }
518
519 mutex_unlock(&state->ca_mutex);
520 kfree(b);
521 return ret;
522}
523
524
525static void az6007_ci_uninit(struct dvb_usb_device *d)
526{
527 struct az6007_device_state *state;
528
529 pr_debug("%s()\n", __func__);
530
531 if (NULL == d)
532 return;
533
534 state = d_to_priv(d);
535 if (NULL == state)
536 return;
537
538 if (NULL == state->ca.data)
539 return;
540
541 dvb_ca_en50221_release(&state->ca);
542
543 memset(&state->ca, 0, sizeof(state->ca));
544}
545
546
547static int az6007_ci_init(struct dvb_usb_adapter *adap)
548{
549 struct dvb_usb_device *d = adap_to_d(adap);
550 struct az6007_device_state *state = adap_to_priv(adap);
551 int ret;
552
553 pr_debug("%s()\n", __func__);
554
555 mutex_init(&state->ca_mutex);
556 state->ca.owner = THIS_MODULE;
557 state->ca.read_attribute_mem = az6007_ci_read_attribute_mem;
558 state->ca.write_attribute_mem = az6007_ci_write_attribute_mem;
559 state->ca.read_cam_control = az6007_ci_read_cam_control;
560 state->ca.write_cam_control = az6007_ci_write_cam_control;
561 state->ca.slot_reset = az6007_ci_slot_reset;
562 state->ca.slot_shutdown = az6007_ci_slot_shutdown;
563 state->ca.slot_ts_enable = az6007_ci_slot_ts_enable;
564 state->ca.poll_slot_status = az6007_ci_poll_slot_status;
565 state->ca.data = d;
566
567 ret = dvb_ca_en50221_init(&adap->dvb_adap,
568 &state->ca,
569 0, /* flags */
570 1);/* n_slots */
571 if (ret != 0) {
572 pr_err("Cannot initialize CI: Error %d.\n", ret);
573 memset(&state->ca, 0, sizeof(state->ca));
574 return ret;
575 }
576
577 pr_debug("CI initialized.\n");
578
579 return 0;
580}
581
582static int az6007_read_mac_addr(struct dvb_usb_adapter *adap, u8 mac[6])
583{
584 struct dvb_usb_device *d = adap_to_d(adap);
585 struct az6007_device_state *st = adap_to_priv(adap);
586 int ret;
587
588 ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, st->data, 6);
589 memcpy(mac, st->data, 6);
590
591 if (ret > 0)
592 pr_debug("%s: mac is %pM\n", __func__, mac);
593
594 return ret;
595}
596
597static int az6007_frontend_attach(struct dvb_usb_adapter *adap)
598{
599 struct az6007_device_state *st = adap_to_priv(adap);
600 struct dvb_usb_device *d = adap_to_d(adap);
601
602 pr_debug("attaching demod drxk\n");
603
604 adap->fe[0] = dvb_attach(drxk_attach, &terratec_h7_drxk,
605 &d->i2c_adap);
606 if (!adap->fe[0])
607 return -EINVAL;
608
609 adap->fe[0]->sec_priv = adap;
610 st->gate_ctrl = adap->fe[0]->ops.i2c_gate_ctrl;
611 adap->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
612
613 az6007_ci_init(adap);
614
615 return 0;
616}
617
618static int az6007_tuner_attach(struct dvb_usb_adapter *adap)
619{
620 struct dvb_usb_device *d = adap_to_d(adap);
621
622 pr_debug("attaching tuner mt2063\n");
623
624 /* Attach mt2063 to DVB-C frontend */
625 if (adap->fe[0]->ops.i2c_gate_ctrl)
626 adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 1);
627 if (!dvb_attach(mt2063_attach, adap->fe[0],
628 &az6007_mt2063_config,
629 &d->i2c_adap))
630 return -EINVAL;
631
632 if (adap->fe[0]->ops.i2c_gate_ctrl)
633 adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 0);
634
635 return 0;
636}
637
638static int az6007_power_ctrl(struct dvb_usb_device *d, int onoff)
639{
640 struct az6007_device_state *state = d_to_priv(d);
641 int ret;
642
643 pr_debug("%s()\n", __func__);
644
645 if (!state->warm) {
646 mutex_init(&state->mutex);
647
648 ret = az6007_write(d, AZ6007_POWER, 0, 2, NULL, 0);
649 if (ret < 0)
650 return ret;
651 msleep(60);
652 ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0);
653 if (ret < 0)
654 return ret;
655 msleep(100);
656 ret = az6007_write(d, AZ6007_POWER, 1, 3, NULL, 0);
657 if (ret < 0)
658 return ret;
659 msleep(20);
660 ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0);
661 if (ret < 0)
662 return ret;
663
664 msleep(400);
665 ret = az6007_write(d, FX2_SCON1, 0, 3, NULL, 0);
666 if (ret < 0)
667 return ret;
668 msleep(150);
669 ret = az6007_write(d, FX2_SCON1, 1, 3, NULL, 0);
670 if (ret < 0)
671 return ret;
672 msleep(430);
673 ret = az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0);
674 if (ret < 0)
675 return ret;
676
677 state->warm = true;
678
679 return 0;
680 }
681
682 if (!onoff)
683 return 0;
684
685 az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0);
686 az6007_write(d, AZ6007_TS_THROUGH, 0, 0, NULL, 0);
687
688 return 0;
689}
690
691/* I2C */
692static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
693 int num)
694{
695 struct dvb_usb_device *d = i2c_get_adapdata(adap);
696 struct az6007_device_state *st = d_to_priv(d);
697 int i, j, len;
698 int ret = 0;
699 u16 index;
700 u16 value;
701 int length;
702 u8 req, addr;
703
704 if (mutex_lock_interruptible(&st->mutex) < 0)
705 return -EAGAIN;
706
707 for (i = 0; i < num; i++) {
708 addr = msgs[i].addr << 1;
709 if (((i + 1) < num)
710 && (msgs[i].len == 1)
711 && ((msgs[i].flags & I2C_M_RD) != I2C_M_RD)
712 && (msgs[i + 1].flags & I2C_M_RD)
713 && (msgs[i].addr == msgs[i + 1].addr)) {
714 /*
715 * A write + read xfer for the same address, where
716 * the first xfer has just 1 byte length.
717 * Need to join both into one operation
718 */
719 if (az6007_xfer_debug)
720 printk(KERN_DEBUG "az6007: I2C W/R addr=0x%x len=%d/%d\n",
721 addr, msgs[i].len, msgs[i + 1].len);
722 req = AZ6007_I2C_RD;
723 index = msgs[i].buf[0];
724 value = addr | (1 << 8);
725 length = 6 + msgs[i + 1].len;
726 len = msgs[i + 1].len;
727 ret = __az6007_read(d->udev, req, value, index,
728 st->data, length);
729 if (ret >= len) {
730 for (j = 0; j < len; j++)
731 msgs[i + 1].buf[j] = st->data[j + 5];
732 } else
733 ret = -EIO;
734 i++;
735 } else if (!(msgs[i].flags & I2C_M_RD)) {
736 /* write bytes */
737 if (az6007_xfer_debug)
738 printk(KERN_DEBUG "az6007: I2C W addr=0x%x len=%d\n",
739 addr, msgs[i].len);
740 req = AZ6007_I2C_WR;
741 index = msgs[i].buf[0];
742 value = addr | (1 << 8);
743 length = msgs[i].len - 1;
744 len = msgs[i].len - 1;
745 for (j = 0; j < len; j++)
746 st->data[j] = msgs[i].buf[j + 1];
747 ret = __az6007_write(d->udev, req, value, index,
748 st->data, length);
749 } else {
750 /* read bytes */
751 if (az6007_xfer_debug)
752 printk(KERN_DEBUG "az6007: I2C R addr=0x%x len=%d\n",
753 addr, msgs[i].len);
754 req = AZ6007_I2C_RD;
755 index = msgs[i].buf[0];
756 value = addr;
757 length = msgs[i].len + 6;
758 len = msgs[i].len;
759 ret = __az6007_read(d->udev, req, value, index,
760 st->data, length);
761 for (j = 0; j < len; j++)
762 msgs[i].buf[j] = st->data[j + 5];
763 }
764 if (ret < 0)
765 goto err;
766 }
767err:
768 mutex_unlock(&st->mutex);
769
770 if (ret < 0) {
771 pr_info("%s ERROR: %i\n", __func__, ret);
772 return ret;
773 }
774 return num;
775}
776
777static u32 az6007_i2c_func(struct i2c_adapter *adapter)
778{
779 return I2C_FUNC_I2C;
780}
781
782static struct i2c_algorithm az6007_i2c_algo = {
783 .master_xfer = az6007_i2c_xfer,
784 .functionality = az6007_i2c_func,
785};
786
787static int az6007_identify_state(struct dvb_usb_device *d, const char **name)
788{
789 int ret;
790 u8 *mac;
791
792 pr_debug("Identifying az6007 state\n");
793
794 mac = kmalloc(6, GFP_ATOMIC);
795 if (!mac)
796 return -ENOMEM;
797
798 /* Try to read the mac address */
799 ret = __az6007_read(d->udev, AZ6007_READ_DATA, 6, 0, mac, 6);
800 if (ret == 6)
801 ret = WARM;
802 else
803 ret = COLD;
804
805 kfree(mac);
806
807 if (ret == COLD) {
808 __az6007_write(d->udev, 0x09, 1, 0, NULL, 0);
809 __az6007_write(d->udev, 0x00, 0, 0, NULL, 0);
810 __az6007_write(d->udev, 0x00, 0, 0, NULL, 0);
811 }
812
813 pr_debug("Device is on %s state\n",
814 ret == WARM ? "warm" : "cold");
815 return ret;
816}
817
818static void az6007_usb_disconnect(struct usb_interface *intf)
819{
820 struct dvb_usb_device *d = usb_get_intfdata(intf);
821 az6007_ci_uninit(d);
822 dvb_usbv2_disconnect(intf);
823}
824
825static int az6007_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
826{
827 pr_debug("Getting az6007 Remote Control properties\n");
828
829 rc->allowed_protos = RC_TYPE_NEC;
830 rc->query = az6007_rc_query;
831 rc->interval = 400;
832
833 return 0;
834}
835
836static int az6007_download_firmware(struct dvb_usb_device *d,
837 const struct firmware *fw)
838{
839 pr_debug("Loading az6007 firmware\n");
840
841 return usbv2_cypress_load_firmware(d->udev, fw, CYPRESS_FX2);
842}
843
844/* DVB USB Driver stuff */
845static struct dvb_usb_device_properties az6007_props = {
846 .driver_name = KBUILD_MODNAME,
847 .owner = THIS_MODULE,
848 .firmware = AZ6007_FIRMWARE,
849
850 .adapter_nr = adapter_nr,
851 .size_of_priv = sizeof(struct az6007_device_state),
852 .i2c_algo = &az6007_i2c_algo,
853 .tuner_attach = az6007_tuner_attach,
854 .frontend_attach = az6007_frontend_attach,
855 .streaming_ctrl = az6007_streaming_ctrl,
856 .get_rc_config = az6007_get_rc_config,
857 .read_mac_address = az6007_read_mac_addr,
858 .download_firmware = az6007_download_firmware,
859 .identify_state = az6007_identify_state,
860 .power_ctrl = az6007_power_ctrl,
861 .num_adapters = 1,
862 .adapter = {
863 { .stream = DVB_USB_STREAM_BULK(0x02, 10, 4096), }
864 }
865};
866
867static struct usb_device_id az6007_usb_table[] = {
868 {DVB_USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007,
869 &az6007_props, "Azurewave 6007", RC_MAP_EMPTY)},
870 {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7,
871 &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)},
872 {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7_2,
873 &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)},
874 {0},
875};
876
877MODULE_DEVICE_TABLE(usb, az6007_usb_table);
878
879static int az6007_suspend(struct usb_interface *intf, pm_message_t msg)
880{
881 struct dvb_usb_device *d = usb_get_intfdata(intf);
882
883 az6007_ci_uninit(d);
884 return dvb_usbv2_suspend(intf, msg);
885}
886
887static int az6007_resume(struct usb_interface *intf)
888{
889 struct dvb_usb_device *d = usb_get_intfdata(intf);
890 struct dvb_usb_adapter *adap = &d->adapter[0];
891
892 az6007_ci_init(adap);
893 return dvb_usbv2_resume(intf);
894}
895
896/* usb specific object needed to register this driver with the usb subsystem */
897static struct usb_driver az6007_usb_driver = {
898 .name = KBUILD_MODNAME,
899 .id_table = az6007_usb_table,
900 .probe = dvb_usbv2_probe,
901 .disconnect = az6007_usb_disconnect,
902 .no_dynamic_id = 1,
903 .soft_unbind = 1,
904 /*
905 * FIXME: need to implement reset_resume, likely with
906 * dvb-usb-v2 core support
907 */
908 .suspend = az6007_suspend,
909 .resume = az6007_resume,
910};
911
912module_usb_driver(az6007_usb_driver);
913
914MODULE_AUTHOR("Henry Wang <Henry.wang@AzureWave.com>");
915MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
916MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones");
917MODULE_VERSION("2.0");
918MODULE_LICENSE("GPL");
919MODULE_FIRMWARE(AZ6007_FIRMWARE);
diff --git a/drivers/media/usb/dvb-usb-v2/ce6230.c b/drivers/media/usb/dvb-usb-v2/ce6230.c
new file mode 100644
index 000000000000..84ff4a96ca4e
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/ce6230.c
@@ -0,0 +1,287 @@
1/*
2 * Intel CE6230 DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#include "ce6230.h"
23
24DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
25
26static int ce6230_ctrl_msg(struct dvb_usb_device *d, struct usb_req *req)
27{
28 int ret;
29 unsigned int pipe;
30 u8 request;
31 u8 requesttype;
32 u16 value;
33 u16 index;
34 u8 *buf;
35
36 request = req->cmd;
37 value = req->value;
38 index = req->index;
39
40 switch (req->cmd) {
41 case I2C_READ:
42 case DEMOD_READ:
43 case REG_READ:
44 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
45 break;
46 case I2C_WRITE:
47 case DEMOD_WRITE:
48 case REG_WRITE:
49 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
50 break;
51 default:
52 pr_debug("%s: unknown command=%02x\n", __func__, req->cmd);
53 ret = -EINVAL;
54 goto error;
55 }
56
57 buf = kmalloc(req->data_len, GFP_KERNEL);
58 if (!buf) {
59 ret = -ENOMEM;
60 goto error;
61 }
62
63 if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
64 /* write */
65 memcpy(buf, req->data, req->data_len);
66 pipe = usb_sndctrlpipe(d->udev, 0);
67 } else {
68 /* read */
69 pipe = usb_rcvctrlpipe(d->udev, 0);
70 }
71
72 msleep(1); /* avoid I2C errors */
73
74 ret = usb_control_msg(d->udev, pipe, request, requesttype, value, index,
75 buf, req->data_len, CE6230_USB_TIMEOUT);
76
77 ce6230_debug_dump(request, requesttype, value, index, buf,
78 req->data_len);
79
80 if (ret < 0)
81 pr_err("%s: usb_control_msg() failed=%d\n", KBUILD_MODNAME,
82 ret);
83 else
84 ret = 0;
85
86 /* read request, copy returned data to return buf */
87 if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
88 memcpy(req->data, buf, req->data_len);
89
90 kfree(buf);
91error:
92 return ret;
93}
94
95/* I2C */
96static struct zl10353_config ce6230_zl10353_config;
97
98static int ce6230_i2c_master_xfer(struct i2c_adapter *adap,
99 struct i2c_msg msg[], int num)
100{
101 struct dvb_usb_device *d = i2c_get_adapdata(adap);
102 int ret = 0, i = 0;
103 struct usb_req req;
104
105 if (num > 2)
106 return -EOPNOTSUPP;
107
108 memset(&req, 0, sizeof(req));
109
110 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
111 return -EAGAIN;
112
113 while (i < num) {
114 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
115 if (msg[i].addr ==
116 ce6230_zl10353_config.demod_address) {
117 req.cmd = DEMOD_READ;
118 req.value = msg[i].addr >> 1;
119 req.index = msg[i].buf[0];
120 req.data_len = msg[i+1].len;
121 req.data = &msg[i+1].buf[0];
122 ret = ce6230_ctrl_msg(d, &req);
123 } else {
124 pr_err("%s: I2C read not implemented\n",
125 KBUILD_MODNAME);
126 ret = -EOPNOTSUPP;
127 }
128 i += 2;
129 } else {
130 if (msg[i].addr ==
131 ce6230_zl10353_config.demod_address) {
132 req.cmd = DEMOD_WRITE;
133 req.value = msg[i].addr >> 1;
134 req.index = msg[i].buf[0];
135 req.data_len = msg[i].len-1;
136 req.data = &msg[i].buf[1];
137 ret = ce6230_ctrl_msg(d, &req);
138 } else {
139 req.cmd = I2C_WRITE;
140 req.value = 0x2000 + (msg[i].addr >> 1);
141 req.index = 0x0000;
142 req.data_len = msg[i].len;
143 req.data = &msg[i].buf[0];
144 ret = ce6230_ctrl_msg(d, &req);
145 }
146 i += 1;
147 }
148 if (ret)
149 break;
150 }
151
152 mutex_unlock(&d->i2c_mutex);
153 return ret ? ret : i;
154}
155
156static u32 ce6230_i2c_functionality(struct i2c_adapter *adapter)
157{
158 return I2C_FUNC_I2C;
159}
160
161static struct i2c_algorithm ce6230_i2c_algorithm = {
162 .master_xfer = ce6230_i2c_master_xfer,
163 .functionality = ce6230_i2c_functionality,
164};
165
166/* Callbacks for DVB USB */
167static struct zl10353_config ce6230_zl10353_config = {
168 .demod_address = 0x1e,
169 .adc_clock = 450000,
170 .if2 = 45700,
171 .no_tuner = 1,
172 .parallel_ts = 1,
173 .clock_ctl_1 = 0x34,
174 .pll_0 = 0x0e,
175};
176
177static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
178{
179 pr_debug("%s:\n", __func__);
180
181 adap->fe[0] = dvb_attach(zl10353_attach, &ce6230_zl10353_config,
182 &adap_to_d(adap)->i2c_adap);
183 if (adap->fe[0] == NULL)
184 return -ENODEV;
185
186 return 0;
187}
188
189static struct mxl5005s_config ce6230_mxl5003s_config = {
190 .i2c_address = 0xc6,
191 .if_freq = IF_FREQ_4570000HZ,
192 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
193 .agc_mode = MXL_SINGLE_AGC,
194 .tracking_filter = MXL_TF_DEFAULT,
195 .rssi_enable = MXL_RSSI_ENABLE,
196 .cap_select = MXL_CAP_SEL_ENABLE,
197 .div_out = MXL_DIV_OUT_4,
198 .clock_out = MXL_CLOCK_OUT_DISABLE,
199 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
200 .top = MXL5005S_TOP_25P2,
201 .mod_mode = MXL_DIGITAL_MODE,
202 .if_mode = MXL_ZERO_IF,
203 .AgcMasterByte = 0x00,
204};
205
206static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
207{
208 int ret;
209
210 pr_debug("%s:\n", __func__);
211
212 ret = dvb_attach(mxl5005s_attach, adap->fe[0],
213 &adap_to_d(adap)->i2c_adap,
214 &ce6230_mxl5003s_config) == NULL ? -ENODEV : 0;
215 return ret;
216}
217
218static int ce6230_power_ctrl(struct dvb_usb_device *d, int onoff)
219{
220 int ret;
221
222 pr_debug("%s: onoff=%d\n", __func__, onoff);
223
224 /* InterfaceNumber 1 / AlternateSetting 0 idle
225 InterfaceNumber 1 / AlternateSetting 1 streaming */
226 ret = usb_set_interface(d->udev, 1, onoff);
227 if (ret)
228 pr_err("%s: usb_set_interface() failed=%d\n", KBUILD_MODNAME,
229 ret);
230
231 return ret;
232}
233
234/* DVB USB Driver stuff */
235static struct dvb_usb_device_properties ce6230_props = {
236 .driver_name = KBUILD_MODNAME,
237 .owner = THIS_MODULE,
238 .adapter_nr = adapter_nr,
239 .bInterfaceNumber = 1,
240
241 .i2c_algo = &ce6230_i2c_algorithm,
242 .power_ctrl = ce6230_power_ctrl,
243 .frontend_attach = ce6230_zl10353_frontend_attach,
244 .tuner_attach = ce6230_mxl5003s_tuner_attach,
245
246 .num_adapters = 1,
247 .adapter = {
248 {
249 .stream = {
250 .type = USB_BULK,
251 .count = 6,
252 .endpoint = 0x82,
253 .u = {
254 .bulk = {
255 .buffersize = (16 * 512),
256 }
257 }
258 },
259 }
260 },
261};
262
263static const struct usb_device_id ce6230_id_table[] = {
264 { DVB_USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500,
265 &ce6230_props, "Intel CE9500 reference design", NULL) },
266 { DVB_USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A310,
267 &ce6230_props, "AVerMedia A310 USB 2.0 DVB-T tuner", NULL) },
268 { }
269};
270MODULE_DEVICE_TABLE(usb, ce6230_id_table);
271
272static struct usb_driver ce6230_usb_driver = {
273 .name = KBUILD_MODNAME,
274 .id_table = ce6230_id_table,
275 .probe = dvb_usbv2_probe,
276 .disconnect = dvb_usbv2_disconnect,
277 .suspend = dvb_usbv2_suspend,
278 .resume = dvb_usbv2_resume,
279 .no_dynamic_id = 1,
280 .soft_unbind = 1,
281};
282
283module_usb_driver(ce6230_usb_driver);
284
285MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
286MODULE_DESCRIPTION("Intel CE6230 driver");
287MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/ce6230.h b/drivers/media/usb/dvb-usb-v2/ce6230.h
new file mode 100644
index 000000000000..42d754494a3a
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/ce6230.h
@@ -0,0 +1,61 @@
1/*
2 * Intel CE6230 DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#ifndef CE6230_H
23#define CE6230_H
24
25#include "dvb_usb.h"
26#include "zl10353.h"
27#include "mxl5005s.h"
28
29#define ce6230_debug_dump(r, t, v, i, b, l) { \
30 char *direction; \
31 if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
32 direction = ">>>"; \
33 else \
34 direction = "<<<"; \
35 pr_debug("%s: %02x %02x %02x %02x %02x %02x %02x %02x %s [%d bytes]\n", \
36 __func__, t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, \
37 l & 0xff, l >> 8, direction, l); \
38}
39
40#define CE6230_USB_TIMEOUT 1000
41
42struct usb_req {
43 u8 cmd; /* [1] */
44 u16 value; /* [2|3] */
45 u16 index; /* [4|5] */
46 u16 data_len; /* [6|7] */
47 u8 *data;
48};
49
50enum ce6230_cmd {
51 CONFIG_READ = 0xd0, /* rd 0 (unclear) */
52 UNKNOWN_WRITE = 0xc7, /* wr 7 (unclear) */
53 I2C_READ = 0xd9, /* rd 9 (unclear) */
54 I2C_WRITE = 0xca, /* wr a */
55 DEMOD_READ = 0xdb, /* rd b */
56 DEMOD_WRITE = 0xcc, /* wr c */
57 REG_READ = 0xde, /* rd e */
58 REG_WRITE = 0xcf, /* wr f */
59};
60
61#endif
diff --git a/drivers/media/usb/dvb-usb-v2/cypress_firmware.c b/drivers/media/usb/dvb-usb-v2/cypress_firmware.c
new file mode 100644
index 000000000000..9f7c970c6424
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/cypress_firmware.c
@@ -0,0 +1,125 @@
1/* cypress_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
7 * and 2 based devices.
8 *
9 */
10
11#include "dvb_usb.h"
12#include "cypress_firmware.h"
13
14struct usb_cypress_controller {
15 u8 id;
16 const char *name; /* name of the usb controller */
17 u16 cs_reg; /* needs to be restarted,
18 * when the firmware has been downloaded */
19};
20
21static const struct usb_cypress_controller cypress[] = {
22 { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cs_reg = 0x7f92 },
23 { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cs_reg = 0x7f92 },
24 { .id = CYPRESS_FX2, .name = "Cypress FX2", .cs_reg = 0xe600 },
25};
26
27/*
28 * load a firmware packet to the device
29 */
30static int usb_cypress_writemem(struct usb_device *udev, u16 addr, u8 *data,
31 u8 len)
32{
33 return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
34 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
35}
36
37int usbv2_cypress_load_firmware(struct usb_device *udev,
38 const struct firmware *fw, int type)
39{
40 struct hexline hx;
41 u8 reset;
42 int ret, pos = 0;
43
44 /* stop the CPU */
45 reset = 1;
46 ret = usb_cypress_writemem(udev, cypress[type].cs_reg, &reset, 1);
47 if (ret != 1)
48 pr_err("%s: could not stop the USB controller CPU",
49 KBUILD_MODNAME);
50
51 while ((ret = dvb_usbv2_get_hexline(fw, &hx, &pos)) > 0) {
52 pr_debug("%s: writing to address %04x (buffer: %02x %02x)\n",
53 __func__, hx.addr, hx.len, hx.chk);
54
55 ret = usb_cypress_writemem(udev, hx.addr, hx.data, hx.len);
56 if (ret != hx.len) {
57 pr_err("%s: error while transferring firmware " \
58 "(transferred size=%d, block size=%d)",
59 KBUILD_MODNAME, ret, hx.len);
60 ret = -EINVAL;
61 break;
62 }
63 }
64 if (ret < 0) {
65 pr_err("%s: firmware download failed at %d with %d",
66 KBUILD_MODNAME, pos, ret);
67 return ret;
68 }
69
70 if (ret == 0) {
71 /* restart the CPU */
72 reset = 0;
73 if (ret || usb_cypress_writemem(
74 udev, cypress[type].cs_reg, &reset, 1) != 1) {
75 pr_err("%s: could not restart the USB controller CPU",
76 KBUILD_MODNAME);
77 ret = -EINVAL;
78 }
79 } else
80 ret = -EIO;
81
82 return ret;
83}
84EXPORT_SYMBOL(usbv2_cypress_load_firmware);
85
86int dvb_usbv2_get_hexline(const struct firmware *fw, struct hexline *hx,
87 int *pos)
88{
89 u8 *b = (u8 *) &fw->data[*pos];
90 int data_offs = 4;
91
92 if (*pos >= fw->size)
93 return 0;
94
95 memset(hx, 0, sizeof(struct hexline));
96
97 hx->len = b[0];
98
99 if ((*pos + hx->len + 4) >= fw->size)
100 return -EINVAL;
101
102 hx->addr = b[1] | (b[2] << 8);
103 hx->type = b[3];
104
105 if (hx->type == 0x04) {
106 /* b[4] and b[5] are the Extended linear address record data
107 * field */
108 hx->addr |= (b[4] << 24) | (b[5] << 16);
109 /*
110 hx->len -= 2;
111 data_offs += 2;
112 */
113 }
114 memcpy(hx->data, &b[data_offs], hx->len);
115 hx->chk = b[hx->len + data_offs];
116
117 *pos += hx->len + 5;
118
119 return *pos;
120}
121EXPORT_SYMBOL(dvb_usbv2_get_hexline);
122
123MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
124MODULE_DESCRIPTION("Cypress firmware download");
125MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/cypress_firmware.h b/drivers/media/usb/dvb-usb-v2/cypress_firmware.h
new file mode 100644
index 000000000000..80085fd4132c
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/cypress_firmware.h
@@ -0,0 +1,31 @@
1/* cypress_firmware.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 * This file contains functions for downloading the firmware to Cypress FX 1
7 * and 2 based devices.
8 *
9 */
10
11#ifndef CYPRESS_FIRMWARE_H
12#define CYPRESS_FIRMWARE_H
13
14#define CYPRESS_AN2135 0
15#define CYPRESS_AN2235 1
16#define CYPRESS_FX2 2
17
18/* commonly used firmware download types and function */
19struct hexline {
20 u8 len;
21 u32 addr;
22 u8 type;
23 u8 data[255];
24 u8 chk;
25};
26extern int usbv2_cypress_load_firmware(struct usb_device *,
27 const struct firmware *, int);
28extern int dvb_usbv2_get_hexline(const struct firmware *,
29 struct hexline *, int *);
30
31#endif
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
new file mode 100644
index 000000000000..79b3b8b6750d
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
@@ -0,0 +1,389 @@
1/*
2 * DVB USB framework
3 *
4 * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
5 * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
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 along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#ifndef DVB_USB_H
23#define DVB_USB_H
24
25#include <linux/usb/input.h>
26#include <linux/firmware.h>
27#include <media/rc-core.h>
28
29#include "dvb_frontend.h"
30#include "dvb_demux.h"
31#include "dvb_net.h"
32#include "dmxdev.h"
33#include "dvb-usb-ids.h"
34
35/*
36 * device file: /dev/dvb/adapter[0-1]/frontend[0-2]
37 *
38 * |-- device
39 * | |-- adapter0
40 * | | |-- frontend0
41 * | | |-- frontend1
42 * | | `-- frontend2
43 * | `-- adapter1
44 * | |-- frontend0
45 * | |-- frontend1
46 * | `-- frontend2
47 *
48 *
49 * Commonly used variable names:
50 * d = pointer to device (struct dvb_usb_device *)
51 * adap = pointer to adapter (struct dvb_usb_adapter *)
52 * fe = pointer to frontend (struct dvb_frontend *)
53 *
54 * Use macros defined in that file to resolve needed pointers.
55 */
56
57/* helper macros for every DVB USB driver use */
58#define adap_to_d(adap) (container_of(adap, struct dvb_usb_device, \
59 adapter[adap->id]))
60#define adap_to_priv(adap) (adap_to_d(adap)->priv)
61#define fe_to_adap(fe) ((struct dvb_usb_adapter *) ((fe)->dvb->priv))
62#define fe_to_d(fe) (adap_to_d(fe_to_adap(fe)))
63#define fe_to_priv(fe) (fe_to_d(fe)->priv)
64#define d_to_priv(d) (d->priv)
65
66#define DVB_USB_STREAM_BULK(endpoint_, count_, size_) { \
67 .type = USB_BULK, \
68 .count = count_, \
69 .endpoint = endpoint_, \
70 .u = { \
71 .bulk = { \
72 .buffersize = size_, \
73 } \
74 } \
75}
76
77#define DVB_USB_STREAM_ISOC(endpoint_, count_, frames_, size_, interval_) { \
78 .type = USB_ISOC, \
79 .count = count_, \
80 .endpoint = endpoint_, \
81 .u = { \
82 .isoc = { \
83 .framesperurb = frames_, \
84 .framesize = size_,\
85 .interval = interval_, \
86 } \
87 } \
88}
89
90#define DVB_USB_DEVICE(vend, prod, props_, name_, rc) \
91 .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
92 .idVendor = (vend), \
93 .idProduct = (prod), \
94 .driver_info = (kernel_ulong_t) &((const struct dvb_usb_driver_info) { \
95 .props = (props_), \
96 .name = (name_), \
97 .rc_map = (rc), \
98 })
99
100struct dvb_usb_device;
101struct dvb_usb_adapter;
102
103/**
104 * structure for carrying all needed data from the device driver to the general
105 * dvb usb routines
106 * @name: device name
107 * @rc_map: name of rc codes table
108 * @props: structure containing all device properties
109 */
110struct dvb_usb_driver_info {
111 const char *name;
112 const char *rc_map;
113 const struct dvb_usb_device_properties *props;
114};
115
116/**
117 * structure for remote controller configuration
118 * @map_name: name of rc codes table
119 * @allowed_protos: protocol(s) supported by the driver
120 * @change_protocol: callback to change protocol
121 * @query: called to query an event from the device
122 * @interval: time in ms between two queries
123 * @driver_type: used to point if a device supports raw mode
124 * @bulk_mode: device supports bulk mode for rc (disable polling mode)
125 */
126struct dvb_usb_rc {
127 const char *map_name;
128 u64 allowed_protos;
129 int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
130 int (*query) (struct dvb_usb_device *d);
131 unsigned int interval;
132 const enum rc_driver_type driver_type;
133 bool bulk_mode;
134};
135
136/**
137 * usb streaming configration for adapter
138 * @type: urb type
139 * @count: count of used urbs
140 * @endpoint: stream usb endpoint number
141 */
142struct usb_data_stream_properties {
143#define USB_BULK 1
144#define USB_ISOC 2
145 u8 type;
146 u8 count;
147 u8 endpoint;
148
149 union {
150 struct {
151 unsigned int buffersize; /* per URB */
152 } bulk;
153 struct {
154 int framesperurb;
155 int framesize;
156 int interval;
157 } isoc;
158 } u;
159};
160
161/**
162 * properties of dvb usb device adapter
163 * @caps: adapter capabilities
164 * @pid_filter_count: pid count of adapter pid-filter
165 * @pid_filter_ctrl: called to enable/disable pid-filter
166 * @pid_filter: called to set/unset pid for filtering
167 * @stream: adapter usb stream configuration
168 */
169#define MAX_NO_OF_FE_PER_ADAP 3
170struct dvb_usb_adapter_properties {
171#define DVB_USB_ADAP_HAS_PID_FILTER 0x01
172#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
173#define DVB_USB_ADAP_NEED_PID_FILTERING 0x04
174 u8 caps;
175
176 u8 pid_filter_count;
177 int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int);
178 int (*pid_filter) (struct dvb_usb_adapter *, int, u16, int);
179
180 struct usb_data_stream_properties stream;
181};
182
183/**
184 * struct dvb_usb_device_properties - properties of a dvb-usb-device
185 * @driver_name: name of the owning driver module
186 * @owner: owner of the dvb_adapter
187 * @adapter_nr: values from the DVB_DEFINE_MOD_OPT_ADAPTER_NR() macro
188 * @bInterfaceNumber: usb interface number driver binds
189 * @size_of_priv: bytes allocated for the driver private data
190 * @generic_bulk_ctrl_endpoint: bulk control endpoint number for sent
191 * @generic_bulk_ctrl_endpoint_response: bulk control endpoint number for
192 * receive
193 * @generic_bulk_ctrl_delay: delay between bulk control sent and receive message
194 * @identify_state: called to determine the firmware state (cold or warm) and
195 * return possible firmware file name to be loaded
196 * @firmware: name of the firmware file to be loaded
197 * @download_firmware: called to download the firmware
198 * @i2c_algo: i2c_algorithm if the device has i2c-adapter
199 * @num_adapters: dvb usb device adapter count
200 * @get_adapter_count: called to resolve adapter count
201 * @adapter: array of all adapter properties of device
202 * @power_ctrl: called to enable/disable power of the device
203 * @read_config: called to resolve device configuration
204 * @read_mac_address: called to resolve adapter mac-address
205 * @frontend_attach: called to attach the possible frontends
206 * @tuner_attach: called to attach the possible tuners
207 * @frontend_ctrl: called to power on/off active frontend
208 * @streaming_ctrl: called to start/stop the usb streaming of adapter
209 * @init: called after adapters are created in order to finalize device
210 * configuration
211 * @exit: called when driver is unloaded
212 * @get_rc_config: called to resolve used remote controller configuration
213 * @get_stream_config: called to resolve input and output stream configuration
214 * of the adapter just before streaming is started. input stream is transport
215 * stream from the demodulator and output stream is usb stream to host.
216 */
217#define MAX_NO_OF_ADAPTER_PER_DEVICE 2
218struct dvb_usb_device_properties {
219 const char *driver_name;
220 struct module *owner;
221 short *adapter_nr;
222
223 u8 bInterfaceNumber;
224 unsigned int size_of_priv;
225 u8 generic_bulk_ctrl_endpoint;
226 u8 generic_bulk_ctrl_endpoint_response;
227 unsigned int generic_bulk_ctrl_delay;
228
229#define WARM 0
230#define COLD 1
231 int (*identify_state) (struct dvb_usb_device *, const char **);
232 const char *firmware;
233#define RECONNECTS_USB 1
234 int (*download_firmware) (struct dvb_usb_device *,
235 const struct firmware *);
236
237 struct i2c_algorithm *i2c_algo;
238
239 unsigned int num_adapters;
240 int (*get_adapter_count) (struct dvb_usb_device *);
241 struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
242 int (*power_ctrl) (struct dvb_usb_device *, int);
243 int (*read_config) (struct dvb_usb_device *d);
244 int (*read_mac_address) (struct dvb_usb_adapter *, u8 []);
245 int (*frontend_attach) (struct dvb_usb_adapter *);
246 int (*tuner_attach) (struct dvb_usb_adapter *);
247 int (*frontend_ctrl) (struct dvb_frontend *, int);
248 int (*streaming_ctrl) (struct dvb_frontend *, int);
249 int (*init) (struct dvb_usb_device *);
250 void (*exit) (struct dvb_usb_device *);
251 int (*get_rc_config) (struct dvb_usb_device *, struct dvb_usb_rc *);
252#define DVB_USB_FE_TS_TYPE_188 0
253#define DVB_USB_FE_TS_TYPE_204 1
254#define DVB_USB_FE_TS_TYPE_RAW 2
255 int (*get_stream_config) (struct dvb_frontend *, u8 *,
256 struct usb_data_stream_properties *);
257};
258
259/**
260 * generic object of an usb stream
261 * @buf_num: number of buffer allocated
262 * @buf_size: size of each buffer in buf_list
263 * @buf_list: array containing all allocate buffers for streaming
264 * @dma_addr: list of dma_addr_t for each buffer in buf_list
265 *
266 * @urbs_initialized: number of URBs initialized
267 * @urbs_submitted: number of URBs submitted
268 */
269#define MAX_NO_URBS_FOR_DATA_STREAM 10
270struct usb_data_stream {
271 struct usb_device *udev;
272 struct usb_data_stream_properties props;
273
274#define USB_STATE_INIT 0x00
275#define USB_STATE_URB_BUF 0x01
276 u8 state;
277
278 void (*complete) (struct usb_data_stream *, u8 *, size_t);
279
280 struct urb *urb_list[MAX_NO_URBS_FOR_DATA_STREAM];
281 int buf_num;
282 unsigned long buf_size;
283 u8 *buf_list[MAX_NO_URBS_FOR_DATA_STREAM];
284 dma_addr_t dma_addr[MAX_NO_URBS_FOR_DATA_STREAM];
285
286 int urbs_initialized;
287 int urbs_submitted;
288
289 void *user_priv;
290};
291
292/**
293 * dvb adapter object on dvb usb device
294 * @props: pointer to adapter properties
295 * @stream: adapter the usb data stream
296 * @id: index of this adapter (starting with 0)
297 * @ts_type: transport stream, input stream, type
298 * @pid_filtering: is hardware pid_filtering used or not
299 * @feed_count: current feed count
300 * @max_feed_count: maimum feed count device can handle
301 * @dvb_adap: adapter dvb_adapter
302 * @dmxdev: adapter dmxdev
303 * @demux: adapter software demuxer
304 * @dvb_net: adapter dvb_net interfaces
305 * @sync_mutex: mutex used to sync control and streaming of the adapter
306 * @fe: adapter frontends
307 * @fe_init: rerouted frontend-init function
308 * @fe_sleep: rerouted frontend-sleep function
309 */
310struct dvb_usb_adapter {
311 const struct dvb_usb_adapter_properties *props;
312 struct usb_data_stream stream;
313 u8 id;
314 u8 ts_type;
315 bool pid_filtering;
316 u8 feed_count;
317 u8 max_feed_count;
318 s8 active_fe;
319
320 /* dvb */
321 struct dvb_adapter dvb_adap;
322 struct dmxdev dmxdev;
323 struct dvb_demux demux;
324 struct dvb_net dvb_net;
325 struct mutex sync_mutex;
326
327 struct dvb_frontend *fe[MAX_NO_OF_FE_PER_ADAP];
328 int (*fe_init[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *);
329 int (*fe_sleep[MAX_NO_OF_FE_PER_ADAP]) (struct dvb_frontend *);
330};
331
332/**
333 * dvb usb device object
334 * @props: device properties
335 * @name: device name
336 * @rc_map: name of rc codes table
337 * @udev: pointer to the device's struct usb_device
338 * @intf: pointer to the device's usb interface
339 * @rc: remote controller configuration
340 * @probe_work: work to defer .probe()
341 * @powered: indicated whether the device is power or not
342 * @usb_mutex: mutex for usb control messages
343 * @i2c_mutex: mutex for i2c-transfers
344 * @i2c_adap: device's i2c-adapter
345 * @rc_dev: rc device for the remote control
346 * @rc_query_work: work for polling remote
347 * @priv: private data of the actual driver (allocate by dvb usb, size defined
348 * in size_of_priv of dvb_usb_properties).
349 */
350struct dvb_usb_device {
351 const struct dvb_usb_device_properties *props;
352 const char *name;
353 const char *rc_map;
354
355 struct usb_device *udev;
356 struct usb_interface *intf;
357 struct dvb_usb_rc rc;
358 struct work_struct probe_work;
359 pid_t work_pid;
360 int powered;
361
362 /* locking */
363 struct mutex usb_mutex;
364
365 /* i2c */
366 struct mutex i2c_mutex;
367 struct i2c_adapter i2c_adap;
368
369 struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
370
371 /* remote control */
372 struct rc_dev *rc_dev;
373 char rc_phys[64];
374 struct delayed_work rc_query_work;
375
376 void *priv;
377};
378
379extern int dvb_usbv2_probe(struct usb_interface *,
380 const struct usb_device_id *);
381extern void dvb_usbv2_disconnect(struct usb_interface *);
382extern int dvb_usbv2_suspend(struct usb_interface *, pm_message_t);
383extern int dvb_usbv2_resume(struct usb_interface *);
384
385/* the generic read/write method for device control */
386extern int dvb_usbv2_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16);
387extern int dvb_usbv2_generic_write(struct dvb_usb_device *, u8 *, u16);
388
389#endif
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_common.h b/drivers/media/usb/dvb-usb-v2/dvb_usb_common.h
new file mode 100644
index 000000000000..45f07090d431
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_common.h
@@ -0,0 +1,35 @@
1/*
2 * DVB USB framework
3 *
4 * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
5 * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
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 along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#ifndef DVB_USB_COMMON_H
23#define DVB_USB_COMMON_H
24
25#include "dvb_usb.h"
26
27/* commonly used methods */
28extern int usb_urb_initv2(struct usb_data_stream *stream,
29 const struct usb_data_stream_properties *props);
30extern int usb_urb_exitv2(struct usb_data_stream *stream);
31extern int usb_urb_submitv2(struct usb_data_stream *stream,
32 struct usb_data_stream_properties *props);
33extern int usb_urb_killv2(struct usb_data_stream *stream);
34
35#endif
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
new file mode 100644
index 000000000000..a72f9c7de682
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
@@ -0,0 +1,997 @@
1/*
2 * DVB USB framework
3 *
4 * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
5 * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
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 along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#include "dvb_usb_common.h"
23
24int dvb_usbv2_disable_rc_polling;
25module_param_named(disable_rc_polling, dvb_usbv2_disable_rc_polling, int, 0644);
26MODULE_PARM_DESC(disable_rc_polling,
27 "disable remote control polling (default: 0)");
28static int dvb_usb_force_pid_filter_usage;
29module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage,
30 int, 0444);
31MODULE_PARM_DESC(force_pid_filter_usage, "force all DVB USB devices to use a " \
32 "PID filter, if any (default: 0)");
33
34static int dvb_usbv2_download_firmware(struct dvb_usb_device *d, const char *name)
35{
36 int ret;
37 const struct firmware *fw;
38 dev_dbg(&d->udev->dev, "%s:\n", __func__);
39
40 if (!d->props->download_firmware) {
41 ret = -EINVAL;
42 goto err;
43 }
44
45 ret = request_firmware(&fw, name, &d->udev->dev);
46 if (ret < 0) {
47 dev_err(&d->udev->dev, "%s: Did not find the firmware file "\
48 "'%s'. Please see linux/Documentation/dvb/ " \
49 "for more details on firmware-problems. " \
50 "Status %d\n", KBUILD_MODNAME, name, ret);
51 goto err;
52 }
53
54 dev_info(&d->udev->dev, "%s: downloading firmware from file '%s'\n",
55 KBUILD_MODNAME, name);
56
57 ret = d->props->download_firmware(d, fw);
58 release_firmware(fw);
59 if (ret < 0)
60 goto err;
61
62 return ret;
63err:
64 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
65 return ret;
66}
67
68static int dvb_usbv2_i2c_init(struct dvb_usb_device *d)
69{
70 int ret;
71 dev_dbg(&d->udev->dev, "%s:\n", __func__);
72
73 if (!d->props->i2c_algo)
74 return 0;
75
76 strlcpy(d->i2c_adap.name, d->name, sizeof(d->i2c_adap.name));
77 d->i2c_adap.algo = d->props->i2c_algo;
78 d->i2c_adap.dev.parent = &d->udev->dev;
79 i2c_set_adapdata(&d->i2c_adap, d);
80
81 ret = i2c_add_adapter(&d->i2c_adap);
82 if (ret < 0) {
83 d->i2c_adap.algo = NULL;
84 dev_err(&d->udev->dev, "%s: i2c_add_adapter() failed=%d\n",
85 KBUILD_MODNAME, ret);
86 goto err;
87 }
88
89 return 0;
90err:
91 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
92 return ret;
93}
94
95static int dvb_usbv2_i2c_exit(struct dvb_usb_device *d)
96{
97 dev_dbg(&d->udev->dev, "%s:\n", __func__);
98
99 if (d->i2c_adap.algo)
100 i2c_del_adapter(&d->i2c_adap);
101
102 return 0;
103}
104
105static void dvb_usb_read_remote_control(struct work_struct *work)
106{
107 struct dvb_usb_device *d = container_of(work,
108 struct dvb_usb_device, rc_query_work.work);
109 int ret;
110
111 /*
112 * When the parameter has been set to 1 via sysfs while the
113 * driver was running, or when bulk mode is enabled after IR init.
114 */
115 if (dvb_usbv2_disable_rc_polling || d->rc.bulk_mode)
116 return;
117
118 ret = d->rc.query(d);
119 if (ret < 0) {
120 dev_err(&d->udev->dev, "%s: rc.query() failed=%d\n",
121 KBUILD_MODNAME, ret);
122 return; /* stop polling */
123 }
124
125 schedule_delayed_work(&d->rc_query_work,
126 msecs_to_jiffies(d->rc.interval));
127}
128
129static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
130{
131 int ret;
132 struct rc_dev *dev;
133 dev_dbg(&d->udev->dev, "%s:\n", __func__);
134
135 if (dvb_usbv2_disable_rc_polling || !d->props->get_rc_config)
136 return 0;
137
138 d->rc.map_name = d->rc_map;
139 ret = d->props->get_rc_config(d, &d->rc);
140 if (ret < 0)
141 goto err;
142
143 /* disable rc when there is no keymap defined */
144 if (!d->rc.map_name)
145 return 0;
146
147 dev = rc_allocate_device();
148 if (!dev) {
149 ret = -ENOMEM;
150 goto err;
151 }
152
153 dev->dev.parent = &d->udev->dev;
154 dev->input_name = d->name;
155 usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
156 strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
157 dev->input_phys = d->rc_phys;
158 usb_to_input_id(d->udev, &dev->input_id);
159 /* TODO: likely RC-core should took const char * */
160 dev->driver_name = (char *) d->props->driver_name;
161 dev->map_name = d->rc.map_name;
162 dev->driver_type = d->rc.driver_type;
163 dev->allowed_protos = d->rc.allowed_protos;
164 dev->change_protocol = d->rc.change_protocol;
165 dev->priv = d;
166
167 ret = rc_register_device(dev);
168 if (ret < 0) {
169 rc_free_device(dev);
170 goto err;
171 }
172
173 d->rc_dev = dev;
174
175 /* start polling if needed */
176 if (d->rc.query && !d->rc.bulk_mode) {
177 /* initialize a work queue for handling polling */
178 INIT_DELAYED_WORK(&d->rc_query_work,
179 dvb_usb_read_remote_control);
180 dev_info(&d->udev->dev, "%s: schedule remote query interval " \
181 "to %d msecs\n", KBUILD_MODNAME,
182 d->rc.interval);
183 schedule_delayed_work(&d->rc_query_work,
184 msecs_to_jiffies(d->rc.interval));
185 }
186
187 return 0;
188err:
189 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
190 return ret;
191}
192
193static int dvb_usbv2_remote_exit(struct dvb_usb_device *d)
194{
195 dev_dbg(&d->udev->dev, "%s:\n", __func__);
196
197 if (d->rc_dev) {
198 cancel_delayed_work_sync(&d->rc_query_work);
199 rc_unregister_device(d->rc_dev);
200 d->rc_dev = NULL;
201 }
202
203 return 0;
204}
205
206static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buf,
207 size_t len)
208{
209 struct dvb_usb_adapter *adap = stream->user_priv;
210 dvb_dmx_swfilter(&adap->demux, buf, len);
211}
212
213static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buf,
214 size_t len)
215{
216 struct dvb_usb_adapter *adap = stream->user_priv;
217 dvb_dmx_swfilter_204(&adap->demux, buf, len);
218}
219
220static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, u8 *buf,
221 size_t len)
222{
223 struct dvb_usb_adapter *adap = stream->user_priv;
224 dvb_dmx_swfilter_raw(&adap->demux, buf, len);
225}
226
227int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap)
228{
229 dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
230 adap->id);
231
232 adap->stream.udev = adap_to_d(adap)->udev;
233 adap->stream.user_priv = adap;
234 adap->stream.complete = dvb_usb_data_complete;
235
236 return usb_urb_initv2(&adap->stream, &adap->props->stream);
237}
238
239int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap)
240{
241 dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
242 adap->id);
243
244 return usb_urb_exitv2(&adap->stream);
245}
246
247static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed,
248 int count)
249{
250 struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
251 struct dvb_usb_device *d = adap_to_d(adap);
252 int ret;
253 dev_dbg(&d->udev->dev, "%s: adap=%d active_fe=%d feed_type=%d " \
254 "setting pid [%s]: %04x (%04d) at index %d '%s'\n",
255 __func__, adap->id, adap->active_fe, dvbdmxfeed->type,
256 adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid,
257 dvbdmxfeed->pid, dvbdmxfeed->index,
258 (count == 1) ? "on" : "off");
259
260 if (adap->active_fe == -1)
261 return -EINVAL;
262
263 adap->feed_count += count;
264
265 /* stop feeding if it is last pid */
266 if (adap->feed_count == 0) {
267 dev_dbg(&d->udev->dev, "%s: stop feeding\n", __func__);
268 usb_urb_killv2(&adap->stream);
269
270 if (d->props->streaming_ctrl) {
271 ret = d->props->streaming_ctrl(
272 adap->fe[adap->active_fe], 0);
273 if (ret < 0) {
274 dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
275 "failed=%d\n", KBUILD_MODNAME,
276 ret);
277 goto err_mutex_unlock;
278 }
279 }
280 mutex_unlock(&adap->sync_mutex);
281 }
282
283 /* activate the pid on the device pid filter */
284 if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
285 adap->pid_filtering &&
286 adap->props->pid_filter)
287 ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
288 dvbdmxfeed->pid, (count == 1) ? 1 : 0);
289 if (ret < 0)
290 dev_err(&d->udev->dev, "%s: pid_filter() " \
291 "failed=%d\n", KBUILD_MODNAME,
292 ret);
293
294 /* start feeding if it is first pid */
295 if (adap->feed_count == 1 && count == 1) {
296 struct usb_data_stream_properties stream_props;
297 mutex_lock(&adap->sync_mutex);
298 dev_dbg(&d->udev->dev, "%s: start feeding\n", __func__);
299
300 /* resolve input and output streaming paramters */
301 if (d->props->get_stream_config) {
302 memcpy(&stream_props, &adap->props->stream,
303 sizeof(struct usb_data_stream_properties));
304 ret = d->props->get_stream_config(
305 adap->fe[adap->active_fe],
306 &adap->ts_type, &stream_props);
307 if (ret < 0)
308 goto err_mutex_unlock;
309 } else {
310 stream_props = adap->props->stream;
311 }
312
313 switch (adap->ts_type) {
314 case DVB_USB_FE_TS_TYPE_204:
315 adap->stream.complete = dvb_usb_data_complete_204;
316 break;
317 case DVB_USB_FE_TS_TYPE_RAW:
318 adap->stream.complete = dvb_usb_data_complete_raw;
319 break;
320 case DVB_USB_FE_TS_TYPE_188:
321 default:
322 adap->stream.complete = dvb_usb_data_complete;
323 break;
324 }
325
326 usb_urb_submitv2(&adap->stream, &stream_props);
327
328 if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
329 adap->props->caps &
330 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
331 adap->props->pid_filter_ctrl) {
332 ret = adap->props->pid_filter_ctrl(adap,
333 adap->pid_filtering);
334 if (ret < 0) {
335 dev_err(&d->udev->dev, "%s: " \
336 "pid_filter_ctrl() failed=%d\n",
337 KBUILD_MODNAME, ret);
338 goto err_mutex_unlock;
339 }
340 }
341
342 if (d->props->streaming_ctrl) {
343 ret = d->props->streaming_ctrl(
344 adap->fe[adap->active_fe], 1);
345 if (ret < 0) {
346 dev_err(&d->udev->dev, "%s: streaming_ctrl() " \
347 "failed=%d\n", KBUILD_MODNAME,
348 ret);
349 goto err_mutex_unlock;
350 }
351 }
352 }
353
354 return 0;
355err_mutex_unlock:
356 mutex_unlock(&adap->sync_mutex);
357 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
358 return ret;
359}
360
361static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
362{
363 return dvb_usb_ctrl_feed(dvbdmxfeed, 1);
364}
365
366static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
367{
368 return dvb_usb_ctrl_feed(dvbdmxfeed, -1);
369}
370
371int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
372{
373 int ret;
374 struct dvb_usb_device *d = adap_to_d(adap);
375 dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);
376
377 ret = dvb_register_adapter(&adap->dvb_adap, d->name, d->props->owner,
378 &d->udev->dev, d->props->adapter_nr);
379 if (ret < 0) {
380 dev_dbg(&d->udev->dev, "%s: dvb_register_adapter() failed=%d\n",
381 __func__, ret);
382 goto err_dvb_register_adapter;
383 }
384
385 adap->dvb_adap.priv = adap;
386
387 if (d->props->read_mac_address) {
388 ret = d->props->read_mac_address(adap,
389 adap->dvb_adap.proposed_mac);
390 if (ret < 0)
391 goto err_dvb_dmx_init;
392
393 dev_info(&d->udev->dev, "%s: MAC address: %pM\n",
394 KBUILD_MODNAME, adap->dvb_adap.proposed_mac);
395 }
396
397 adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
398 adap->demux.priv = adap;
399 adap->demux.filternum = 0;
400 adap->demux.filternum = adap->max_feed_count;
401 adap->demux.feednum = adap->demux.filternum;
402 adap->demux.start_feed = dvb_usb_start_feed;
403 adap->demux.stop_feed = dvb_usb_stop_feed;
404 adap->demux.write_to_decoder = NULL;
405 ret = dvb_dmx_init(&adap->demux);
406 if (ret < 0) {
407 dev_err(&d->udev->dev, "%s: dvb_dmx_init() failed=%d\n",
408 KBUILD_MODNAME, ret);
409 goto err_dvb_dmx_init;
410 }
411
412 adap->dmxdev.filternum = adap->demux.filternum;
413 adap->dmxdev.demux = &adap->demux.dmx;
414 adap->dmxdev.capabilities = 0;
415 ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
416 if (ret < 0) {
417 dev_err(&d->udev->dev, "%s: dvb_dmxdev_init() failed=%d\n",
418 KBUILD_MODNAME, ret);
419 goto err_dvb_dmxdev_init;
420 }
421
422 ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
423 if (ret < 0) {
424 dev_err(&d->udev->dev, "%s: dvb_net_init() failed=%d\n",
425 KBUILD_MODNAME, ret);
426 goto err_dvb_net_init;
427 }
428
429 mutex_init(&adap->sync_mutex);
430
431 return 0;
432err_dvb_net_init:
433 dvb_dmxdev_release(&adap->dmxdev);
434err_dvb_dmxdev_init:
435 dvb_dmx_release(&adap->demux);
436err_dvb_dmx_init:
437 dvb_unregister_adapter(&adap->dvb_adap);
438err_dvb_register_adapter:
439 adap->dvb_adap.priv = NULL;
440 return ret;
441}
442
443int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap)
444{
445 dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
446 adap->id);
447
448 if (adap->dvb_adap.priv) {
449 dvb_net_release(&adap->dvb_net);
450 adap->demux.dmx.close(&adap->demux.dmx);
451 dvb_dmxdev_release(&adap->dmxdev);
452 dvb_dmx_release(&adap->demux);
453 dvb_unregister_adapter(&adap->dvb_adap);
454 }
455
456 return 0;
457}
458
459int dvb_usbv2_device_power_ctrl(struct dvb_usb_device *d, int onoff)
460{
461 int ret;
462
463 if (onoff)
464 d->powered++;
465 else
466 d->powered--;
467
468 if (d->powered == 0 || (onoff && d->powered == 1)) {
469 /* when switching from 1 to 0 or from 0 to 1 */
470 dev_dbg(&d->udev->dev, "%s: power=%d\n", __func__, onoff);
471 if (d->props->power_ctrl) {
472 ret = d->props->power_ctrl(d, onoff);
473 if (ret < 0)
474 goto err;
475 }
476 }
477
478 return 0;
479err:
480 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
481 return ret;
482}
483
484static int dvb_usb_fe_init(struct dvb_frontend *fe)
485{
486 int ret;
487 struct dvb_usb_adapter *adap = fe->dvb->priv;
488 struct dvb_usb_device *d = adap_to_d(adap);
489 mutex_lock(&adap->sync_mutex);
490 dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
491 fe->id);
492
493 ret = dvb_usbv2_device_power_ctrl(d, 1);
494 if (ret < 0)
495 goto err;
496
497 if (d->props->frontend_ctrl) {
498 ret = d->props->frontend_ctrl(fe, 1);
499 if (ret < 0)
500 goto err;
501 }
502
503 if (adap->fe_init[fe->id]) {
504 ret = adap->fe_init[fe->id](fe);
505 if (ret < 0)
506 goto err;
507 }
508
509 adap->active_fe = fe->id;
510 mutex_unlock(&adap->sync_mutex);
511
512 return 0;
513err:
514 mutex_unlock(&adap->sync_mutex);
515 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
516 return ret;
517}
518
519static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
520{
521 int ret;
522 struct dvb_usb_adapter *adap = fe->dvb->priv;
523 struct dvb_usb_device *d = adap_to_d(adap);
524 mutex_lock(&adap->sync_mutex);
525 dev_dbg(&d->udev->dev, "%s: adap=%d fe=%d\n", __func__, adap->id,
526 fe->id);
527
528 if (adap->fe_sleep[fe->id]) {
529 ret = adap->fe_sleep[fe->id](fe);
530 if (ret < 0)
531 goto err;
532 }
533
534 if (d->props->frontend_ctrl) {
535 ret = d->props->frontend_ctrl(fe, 0);
536 if (ret < 0)
537 goto err;
538 }
539
540 ret = dvb_usbv2_device_power_ctrl(d, 0);
541 if (ret < 0)
542 goto err;
543
544 adap->active_fe = -1;
545 mutex_unlock(&adap->sync_mutex);
546
547 return 0;
548err:
549 mutex_unlock(&adap->sync_mutex);
550 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
551 return ret;
552}
553
554int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
555{
556 int ret, i, count_registered = 0;
557 struct dvb_usb_device *d = adap_to_d(adap);
558 dev_dbg(&d->udev->dev, "%s: adap=%d\n", __func__, adap->id);
559
560 memset(adap->fe, 0, sizeof(adap->fe));
561 adap->active_fe = -1;
562
563 if (d->props->frontend_attach) {
564 ret = d->props->frontend_attach(adap);
565 if (ret < 0) {
566 dev_dbg(&d->udev->dev, "%s: frontend_attach() " \
567 "failed=%d\n", __func__, ret);
568 goto err_dvb_frontend_detach;
569 }
570 } else {
571 dev_dbg(&d->udev->dev, "%s: frontend_attach() do not exists\n",
572 __func__);
573 ret = 0;
574 goto err;
575 }
576
577 for (i = 0; i < MAX_NO_OF_FE_PER_ADAP && adap->fe[i]; i++) {
578 adap->fe[i]->id = i;
579 /* re-assign sleep and wakeup functions */
580 adap->fe_init[i] = adap->fe[i]->ops.init;
581 adap->fe[i]->ops.init = dvb_usb_fe_init;
582 adap->fe_sleep[i] = adap->fe[i]->ops.sleep;
583 adap->fe[i]->ops.sleep = dvb_usb_fe_sleep;
584
585 ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]);
586 if (ret < 0) {
587 dev_err(&d->udev->dev, "%s: frontend%d registration " \
588 "failed\n", KBUILD_MODNAME, i);
589 goto err_dvb_unregister_frontend;
590 }
591
592 count_registered++;
593 }
594
595 if (d->props->tuner_attach) {
596 ret = d->props->tuner_attach(adap);
597 if (ret < 0) {
598 dev_dbg(&d->udev->dev, "%s: tuner_attach() failed=%d\n",
599 __func__, ret);
600 goto err_dvb_unregister_frontend;
601 }
602 }
603
604 return 0;
605
606err_dvb_unregister_frontend:
607 for (i = count_registered - 1; i >= 0; i--)
608 dvb_unregister_frontend(adap->fe[i]);
609
610err_dvb_frontend_detach:
611 for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
612 if (adap->fe[i])
613 dvb_frontend_detach(adap->fe[i]);
614 }
615
616err:
617 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
618 return ret;
619}
620
621int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap)
622{
623 int i;
624 dev_dbg(&adap_to_d(adap)->udev->dev, "%s: adap=%d\n", __func__,
625 adap->id);
626
627 for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
628 if (adap->fe[i]) {
629 dvb_unregister_frontend(adap->fe[i]);
630 dvb_frontend_detach(adap->fe[i]);
631 }
632 }
633
634 return 0;
635}
636
637static int dvb_usbv2_adapter_init(struct dvb_usb_device *d)
638{
639 struct dvb_usb_adapter *adap;
640 int ret, i, adapter_count;
641
642 /* resolve adapter count */
643 adapter_count = d->props->num_adapters;
644 if (d->props->get_adapter_count) {
645 ret = d->props->get_adapter_count(d);
646 if (ret < 0)
647 goto err;
648
649 adapter_count = ret;
650 }
651
652 for (i = 0; i < adapter_count; i++) {
653 adap = &d->adapter[i];
654 adap->id = i;
655 adap->props = &d->props->adapter[i];
656
657 /* speed - when running at FULL speed we need a HW PID filter */
658 if (d->udev->speed == USB_SPEED_FULL &&
659 !(adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
660 dev_err(&d->udev->dev, "%s: this USB2.0 device " \
661 "cannot be run on a USB1.1 port (it " \
662 "lacks a hardware PID filter)\n",
663 KBUILD_MODNAME);
664 ret = -ENODEV;
665 goto err;
666 } else if ((d->udev->speed == USB_SPEED_FULL &&
667 adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
668 (adap->props->caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
669 dev_info(&d->udev->dev, "%s: will use the device's " \
670 "hardware PID filter " \
671 "(table count: %d)\n", KBUILD_MODNAME,
672 adap->props->pid_filter_count);
673 adap->pid_filtering = 1;
674 adap->max_feed_count = adap->props->pid_filter_count;
675 } else {
676 dev_info(&d->udev->dev, "%s: will pass the complete " \
677 "MPEG2 transport stream to the " \
678 "software demuxer\n", KBUILD_MODNAME);
679 adap->pid_filtering = 0;
680 adap->max_feed_count = 255;
681 }
682
683 if (!adap->pid_filtering && dvb_usb_force_pid_filter_usage &&
684 adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER) {
685 dev_info(&d->udev->dev, "%s: PID filter enabled by " \
686 "module option\n", KBUILD_MODNAME);
687 adap->pid_filtering = 1;
688 adap->max_feed_count = adap->props->pid_filter_count;
689 }
690
691 ret = dvb_usbv2_adapter_stream_init(adap);
692 if (ret)
693 goto err;
694
695 ret = dvb_usbv2_adapter_dvb_init(adap);
696 if (ret)
697 goto err;
698
699 ret = dvb_usbv2_adapter_frontend_init(adap);
700 if (ret)
701 goto err;
702
703 /* use exclusive FE lock if there is multiple shared FEs */
704 if (adap->fe[1])
705 adap->dvb_adap.mfe_shared = 1;
706 }
707
708 return 0;
709err:
710 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
711 return ret;
712}
713
714static int dvb_usbv2_adapter_exit(struct dvb_usb_device *d)
715{
716 int i;
717 dev_dbg(&d->udev->dev, "%s:\n", __func__);
718
719 for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; i--) {
720 if (d->adapter[i].props) {
721 dvb_usbv2_adapter_frontend_exit(&d->adapter[i]);
722 dvb_usbv2_adapter_dvb_exit(&d->adapter[i]);
723 dvb_usbv2_adapter_stream_exit(&d->adapter[i]);
724 }
725 }
726
727 return 0;
728}
729
730/* general initialization functions */
731static int dvb_usbv2_exit(struct dvb_usb_device *d)
732{
733 dev_dbg(&d->udev->dev, "%s:\n", __func__);
734
735 dvb_usbv2_remote_exit(d);
736 dvb_usbv2_adapter_exit(d);
737 dvb_usbv2_i2c_exit(d);
738 kfree(d->priv);
739 kfree(d);
740
741 return 0;
742}
743
744static int dvb_usbv2_init(struct dvb_usb_device *d)
745{
746 int ret;
747 dev_dbg(&d->udev->dev, "%s:\n", __func__);
748
749 dvb_usbv2_device_power_ctrl(d, 1);
750
751 if (d->props->read_config) {
752 ret = d->props->read_config(d);
753 if (ret < 0)
754 goto err;
755 }
756
757 ret = dvb_usbv2_i2c_init(d);
758 if (ret < 0)
759 goto err;
760
761 ret = dvb_usbv2_adapter_init(d);
762 if (ret < 0)
763 goto err;
764
765 if (d->props->init) {
766 ret = d->props->init(d);
767 if (ret < 0)
768 goto err;
769 }
770
771 ret = dvb_usbv2_remote_init(d);
772 if (ret < 0)
773 goto err;
774
775 dvb_usbv2_device_power_ctrl(d, 0);
776
777 return 0;
778err:
779 dvb_usbv2_device_power_ctrl(d, 0);
780 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
781 return ret;
782}
783
784/*
785 * udev, which is used for the firmware downloading, requires we cannot
786 * block during module_init(). module_init() calls USB probe() which
787 * is this routine. Due to that we delay actual operation using workqueue
788 * and return always success here.
789 */
790static void dvb_usbv2_init_work(struct work_struct *work)
791{
792 int ret;
793 struct dvb_usb_device *d =
794 container_of(work, struct dvb_usb_device, probe_work);
795
796 d->work_pid = current->pid;
797 dev_dbg(&d->udev->dev, "%s: work_pid=%d\n", __func__, d->work_pid);
798
799 if (d->props->size_of_priv) {
800 d->priv = kzalloc(d->props->size_of_priv, GFP_KERNEL);
801 if (!d->priv) {
802 dev_err(&d->udev->dev, "%s: kzalloc() failed\n",
803 KBUILD_MODNAME);
804 ret = -ENOMEM;
805 goto err_usb_driver_release_interface;
806 }
807 }
808
809 if (d->props->identify_state) {
810 const char *name = NULL;
811 ret = d->props->identify_state(d, &name);
812 if (ret == 0) {
813 ;
814 } else if (ret == COLD) {
815 dev_info(&d->udev->dev, "%s: found a '%s' in cold " \
816 "state\n", KBUILD_MODNAME, d->name);
817
818 if (!name)
819 name = d->props->firmware;
820
821 ret = dvb_usbv2_download_firmware(d, name);
822 if (ret == 0) {
823 /* device is warm, continue initialization */
824 ;
825 } else if (ret == RECONNECTS_USB) {
826 /*
827 * USB core will call disconnect() and then
828 * probe() as device reconnects itself from the
829 * USB bus. disconnect() will release all driver
830 * resources and probe() is called for 'new'
831 * device. As 'new' device is warm we should
832 * never go here again.
833 */
834 return;
835 } else {
836 /*
837 * Unexpected error. We must unregister driver
838 * manually from the device, because device is
839 * already register by returning from probe()
840 * with success. usb_driver_release_interface()
841 * finally calls disconnect() in order to free
842 * resources.
843 */
844 goto err_usb_driver_release_interface;
845 }
846 } else {
847 goto err_usb_driver_release_interface;
848 }
849 }
850
851 dev_info(&d->udev->dev, "%s: found a '%s' in warm state\n",
852 KBUILD_MODNAME, d->name);
853
854 ret = dvb_usbv2_init(d);
855 if (ret < 0)
856 goto err_usb_driver_release_interface;
857
858 dev_info(&d->udev->dev, "%s: '%s' successfully initialized and " \
859 "connected\n", KBUILD_MODNAME, d->name);
860
861 return;
862err_usb_driver_release_interface:
863 dev_info(&d->udev->dev, "%s: '%s' error while loading driver (%d)\n",
864 KBUILD_MODNAME, d->name, ret);
865 usb_driver_release_interface(to_usb_driver(d->intf->dev.driver),
866 d->intf);
867 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
868 return;
869}
870
871int dvb_usbv2_probe(struct usb_interface *intf,
872 const struct usb_device_id *id)
873{
874 int ret;
875 struct dvb_usb_device *d;
876 struct usb_device *udev = interface_to_usbdev(intf);
877 struct dvb_usb_driver_info *driver_info =
878 (struct dvb_usb_driver_info *) id->driver_info;
879
880 dev_dbg(&udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
881 intf->cur_altsetting->desc.bInterfaceNumber);
882
883 if (!id->driver_info) {
884 dev_err(&udev->dev, "%s: driver_info failed\n", KBUILD_MODNAME);
885 ret = -ENODEV;
886 goto err;
887 }
888
889 d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
890 if (!d) {
891 dev_err(&udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
892 ret = -ENOMEM;
893 goto err;
894 }
895
896 d->name = driver_info->name;
897 d->rc_map = driver_info->rc_map;
898 d->udev = udev;
899 d->intf = intf;
900 d->props = driver_info->props;
901
902 if (d->intf->cur_altsetting->desc.bInterfaceNumber !=
903 d->props->bInterfaceNumber) {
904 ret = -ENODEV;
905 goto err_kfree;
906 }
907
908 mutex_init(&d->usb_mutex);
909 mutex_init(&d->i2c_mutex);
910 INIT_WORK(&d->probe_work, dvb_usbv2_init_work);
911 usb_set_intfdata(intf, d);
912 ret = schedule_work(&d->probe_work);
913 if (ret < 0) {
914 dev_err(&d->udev->dev, "%s: schedule_work() failed\n",
915 KBUILD_MODNAME);
916 goto err_kfree;
917 }
918
919 return 0;
920err_kfree:
921 kfree(d);
922err:
923 dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret);
924 return ret;
925}
926EXPORT_SYMBOL(dvb_usbv2_probe);
927
928void dvb_usbv2_disconnect(struct usb_interface *intf)
929{
930 struct dvb_usb_device *d = usb_get_intfdata(intf);
931 const char *name = d->name;
932 struct device dev = d->udev->dev;
933 dev_dbg(&d->udev->dev, "%s: pid=%d work_pid=%d\n", __func__,
934 current->pid, d->work_pid);
935
936 /* ensure initialization work is finished until release resources */
937 if (d->work_pid != current->pid)
938 cancel_work_sync(&d->probe_work);
939
940 if (d->props->exit)
941 d->props->exit(d);
942
943 dvb_usbv2_exit(d);
944
945 dev_info(&dev, "%s: '%s' successfully deinitialized and disconnected\n",
946 KBUILD_MODNAME, name);
947}
948EXPORT_SYMBOL(dvb_usbv2_disconnect);
949
950int dvb_usbv2_suspend(struct usb_interface *intf, pm_message_t msg)
951{
952 struct dvb_usb_device *d = usb_get_intfdata(intf);
953 int i;
954 dev_dbg(&d->udev->dev, "%s:\n", __func__);
955
956 /* stop remote controller poll */
957 if (d->rc.query && !d->rc.bulk_mode)
958 cancel_delayed_work_sync(&d->rc_query_work);
959
960 /* stop streaming */
961 for (i = MAX_NO_OF_ADAPTER_PER_DEVICE - 1; i >= 0; i--) {
962 if (d->adapter[i].dvb_adap.priv &&
963 d->adapter[i].active_fe != -1)
964 usb_urb_killv2(&d->adapter[i].stream);
965 }
966
967 return 0;
968}
969EXPORT_SYMBOL(dvb_usbv2_suspend);
970
971int dvb_usbv2_resume(struct usb_interface *intf)
972{
973 struct dvb_usb_device *d = usb_get_intfdata(intf);
974 int i;
975 dev_dbg(&d->udev->dev, "%s:\n", __func__);
976
977 /* start streaming */
978 for (i = 0; i < MAX_NO_OF_ADAPTER_PER_DEVICE; i++) {
979 if (d->adapter[i].dvb_adap.priv &&
980 d->adapter[i].active_fe != -1)
981 usb_urb_submitv2(&d->adapter[i].stream, NULL);
982 }
983
984 /* start remote controller poll */
985 if (d->rc.query && !d->rc.bulk_mode)
986 schedule_delayed_work(&d->rc_query_work,
987 msecs_to_jiffies(d->rc.interval));
988
989 return 0;
990}
991EXPORT_SYMBOL(dvb_usbv2_resume);
992
993MODULE_VERSION("2.0");
994MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
995MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
996MODULE_DESCRIPTION("DVB USB common");
997MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c
new file mode 100644
index 000000000000..0431beed0ef4
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_urb.c
@@ -0,0 +1,77 @@
1/*
2 * DVB USB framework
3 *
4 * Copyright (C) 2004-6 Patrick Boettcher <patrick.boettcher@desy.de>
5 * Copyright (C) 2012 Antti Palosaari <crope@iki.fi>
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 along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#include "dvb_usb_common.h"
23
24int dvb_usbv2_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
25 u16 rlen)
26{
27 int ret, actual_length;
28
29 if (!d || !wbuf || !wlen || !d->props->generic_bulk_ctrl_endpoint ||
30 !d->props->generic_bulk_ctrl_endpoint_response) {
31 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, -EINVAL);
32 return -EINVAL;
33 }
34
35 ret = mutex_lock_interruptible(&d->usb_mutex);
36 if (ret < 0)
37 return ret;
38
39 dev_dbg(&d->udev->dev, "%s: >>> %*ph\n", __func__, wlen, wbuf);
40
41 ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev,
42 d->props->generic_bulk_ctrl_endpoint), wbuf, wlen,
43 &actual_length, 2000);
44 if (ret < 0)
45 dev_err(&d->udev->dev, "%s: usb_bulk_msg() failed=%d\n",
46 KBUILD_MODNAME, ret);
47 else
48 ret = actual_length != wlen ? -EIO : 0;
49
50 /* an answer is expected, and no error before */
51 if (!ret && rbuf && rlen) {
52 if (d->props->generic_bulk_ctrl_delay)
53 usleep_range(d->props->generic_bulk_ctrl_delay,
54 d->props->generic_bulk_ctrl_delay
55 + 20000);
56
57 ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
58 d->props->generic_bulk_ctrl_endpoint_response),
59 rbuf, rlen, &actual_length, 2000);
60 if (ret)
61 dev_err(&d->udev->dev, "%s: 2nd usb_bulk_msg() " \
62 "failed=%d\n", KBUILD_MODNAME, ret);
63
64 dev_dbg(&d->udev->dev, "%s: <<< %*ph\n", __func__,
65 actual_length, rbuf);
66 }
67
68 mutex_unlock(&d->usb_mutex);
69 return ret;
70}
71EXPORT_SYMBOL(dvb_usbv2_generic_rw);
72
73int dvb_usbv2_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
74{
75 return dvb_usbv2_generic_rw(d, buf, len, NULL, 0);
76}
77EXPORT_SYMBOL(dvb_usbv2_generic_write);
diff --git a/drivers/media/usb/dvb-usb-v2/ec168.c b/drivers/media/usb/dvb-usb-v2/ec168.c
new file mode 100644
index 000000000000..ab77622c383d
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/ec168.c
@@ -0,0 +1,376 @@
1/*
2 * E3C EC168 DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#include "ec168.h"
23#include "ec100.h"
24#include "mxl5005s.h"
25
26DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
27
28static int ec168_ctrl_msg(struct dvb_usb_device *d, struct ec168_req *req)
29{
30 int ret;
31 unsigned int pipe;
32 u8 request, requesttype;
33 u8 *buf;
34
35 switch (req->cmd) {
36 case DOWNLOAD_FIRMWARE:
37 case GPIO:
38 case WRITE_I2C:
39 case STREAMING_CTRL:
40 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
41 request = req->cmd;
42 break;
43 case READ_I2C:
44 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
45 request = req->cmd;
46 break;
47 case GET_CONFIG:
48 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
49 request = CONFIG;
50 break;
51 case SET_CONFIG:
52 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
53 request = CONFIG;
54 break;
55 case WRITE_DEMOD:
56 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
57 request = DEMOD_RW;
58 break;
59 case READ_DEMOD:
60 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
61 request = DEMOD_RW;
62 break;
63 default:
64 pr_err("%s: unknown command=%02x\n", KBUILD_MODNAME, req->cmd);
65 ret = -EINVAL;
66 goto error;
67 }
68
69 buf = kmalloc(req->size, GFP_KERNEL);
70 if (!buf) {
71 ret = -ENOMEM;
72 goto error;
73 }
74
75 if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
76 /* write */
77 memcpy(buf, req->data, req->size);
78 pipe = usb_sndctrlpipe(d->udev, 0);
79 } else {
80 /* read */
81 pipe = usb_rcvctrlpipe(d->udev, 0);
82 }
83
84 msleep(1); /* avoid I2C errors */
85
86 ret = usb_control_msg(d->udev, pipe, request, requesttype, req->value,
87 req->index, buf, req->size, EC168_USB_TIMEOUT);
88
89 ec168_debug_dump(request, requesttype, req->value, req->index, buf,
90 req->size);
91
92 if (ret < 0)
93 goto err_dealloc;
94 else
95 ret = 0;
96
97 /* read request, copy returned data to return buf */
98 if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
99 memcpy(req->data, buf, req->size);
100
101 kfree(buf);
102 return ret;
103
104err_dealloc:
105 kfree(buf);
106error:
107 pr_debug("%s: failed=%d\n", __func__, ret);
108 return ret;
109}
110
111/* I2C */
112static struct ec100_config ec168_ec100_config;
113
114static int ec168_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
115 int num)
116{
117 struct dvb_usb_device *d = i2c_get_adapdata(adap);
118 struct ec168_req req;
119 int i = 0;
120 int ret;
121
122 if (num > 2)
123 return -EINVAL;
124
125 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
126 return -EAGAIN;
127
128 while (i < num) {
129 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
130 if (msg[i].addr == ec168_ec100_config.demod_address) {
131 req.cmd = READ_DEMOD;
132 req.value = 0;
133 req.index = 0xff00 + msg[i].buf[0]; /* reg */
134 req.size = msg[i+1].len; /* bytes to read */
135 req.data = &msg[i+1].buf[0];
136 ret = ec168_ctrl_msg(d, &req);
137 i += 2;
138 } else {
139 pr_err("%s: I2C read not implemented\n",
140 KBUILD_MODNAME);
141 ret = -EOPNOTSUPP;
142 i += 2;
143 }
144 } else {
145 if (msg[i].addr == ec168_ec100_config.demod_address) {
146 req.cmd = WRITE_DEMOD;
147 req.value = msg[i].buf[1]; /* val */
148 req.index = 0xff00 + msg[i].buf[0]; /* reg */
149 req.size = 0;
150 req.data = NULL;
151 ret = ec168_ctrl_msg(d, &req);
152 i += 1;
153 } else {
154 req.cmd = WRITE_I2C;
155 req.value = msg[i].buf[0]; /* val */
156 req.index = 0x0100 + msg[i].addr; /* I2C addr */
157 req.size = msg[i].len-1;
158 req.data = &msg[i].buf[1];
159 ret = ec168_ctrl_msg(d, &req);
160 i += 1;
161 }
162 }
163 if (ret)
164 goto error;
165
166 }
167 ret = i;
168
169error:
170 mutex_unlock(&d->i2c_mutex);
171 return i;
172}
173
174static u32 ec168_i2c_func(struct i2c_adapter *adapter)
175{
176 return I2C_FUNC_I2C;
177}
178
179static struct i2c_algorithm ec168_i2c_algo = {
180 .master_xfer = ec168_i2c_xfer,
181 .functionality = ec168_i2c_func,
182};
183
184/* Callbacks for DVB USB */
185static int ec168_identify_state(struct dvb_usb_device *d, const char **name)
186{
187 int ret;
188 u8 reply;
189 struct ec168_req req = {GET_CONFIG, 0, 1, sizeof(reply), &reply};
190 pr_debug("%s:\n", __func__);
191
192 ret = ec168_ctrl_msg(d, &req);
193 if (ret)
194 goto error;
195
196 pr_debug("%s: reply=%02x\n", __func__, reply);
197
198 if (reply == 0x01)
199 ret = WARM;
200 else
201 ret = COLD;
202
203 return ret;
204error:
205 pr_debug("%s: failed=%d\n", __func__, ret);
206 return ret;
207}
208
209static int ec168_download_firmware(struct dvb_usb_device *d,
210 const struct firmware *fw)
211{
212 int ret, len, remaining;
213 struct ec168_req req = {DOWNLOAD_FIRMWARE, 0, 0, 0, NULL};
214 pr_debug("%s:\n", __func__);
215
216 #define LEN_MAX 2048 /* max packet size */
217 for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
218 len = remaining;
219 if (len > LEN_MAX)
220 len = LEN_MAX;
221
222 req.size = len;
223 req.data = (u8 *) &fw->data[fw->size - remaining];
224 req.index = fw->size - remaining;
225
226 ret = ec168_ctrl_msg(d, &req);
227 if (ret) {
228 pr_err("%s: firmware download failed=%d\n",
229 KBUILD_MODNAME, ret);
230 goto error;
231 }
232 }
233
234 req.size = 0;
235
236 /* set "warm"? */
237 req.cmd = SET_CONFIG;
238 req.value = 0;
239 req.index = 0x0001;
240 ret = ec168_ctrl_msg(d, &req);
241 if (ret)
242 goto error;
243
244 /* really needed - no idea what does */
245 req.cmd = GPIO;
246 req.value = 0;
247 req.index = 0x0206;
248 ret = ec168_ctrl_msg(d, &req);
249 if (ret)
250 goto error;
251
252 /* activate tuner I2C? */
253 req.cmd = WRITE_I2C;
254 req.value = 0;
255 req.index = 0x00c6;
256 ret = ec168_ctrl_msg(d, &req);
257 if (ret)
258 goto error;
259
260 return ret;
261error:
262 pr_debug("%s: failed=%d\n", __func__, ret);
263 return ret;
264}
265
266static struct ec100_config ec168_ec100_config = {
267 .demod_address = 0xff, /* not real address, demod is integrated */
268};
269
270static int ec168_ec100_frontend_attach(struct dvb_usb_adapter *adap)
271{
272 pr_debug("%s:\n", __func__);
273 adap->fe[0] = dvb_attach(ec100_attach, &ec168_ec100_config,
274 &adap_to_d(adap)->i2c_adap);
275 if (adap->fe[0] == NULL)
276 return -ENODEV;
277
278 return 0;
279}
280
281static struct mxl5005s_config ec168_mxl5003s_config = {
282 .i2c_address = 0xc6,
283 .if_freq = IF_FREQ_4570000HZ,
284 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
285 .agc_mode = MXL_SINGLE_AGC,
286 .tracking_filter = MXL_TF_OFF,
287 .rssi_enable = MXL_RSSI_ENABLE,
288 .cap_select = MXL_CAP_SEL_ENABLE,
289 .div_out = MXL_DIV_OUT_4,
290 .clock_out = MXL_CLOCK_OUT_DISABLE,
291 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
292 .top = MXL5005S_TOP_25P2,
293 .mod_mode = MXL_DIGITAL_MODE,
294 .if_mode = MXL_ZERO_IF,
295 .AgcMasterByte = 0x00,
296};
297
298static int ec168_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
299{
300 pr_debug("%s:\n", __func__);
301 return dvb_attach(mxl5005s_attach, adap->fe[0],
302 &adap_to_d(adap)->i2c_adap,
303 &ec168_mxl5003s_config) == NULL ? -ENODEV : 0;
304}
305
306static int ec168_streaming_ctrl(struct dvb_frontend *fe, int onoff)
307{
308 struct ec168_req req = {STREAMING_CTRL, 0x7f01, 0x0202, 0, NULL};
309 pr_debug("%s: onoff=%d\n", __func__, onoff);
310 if (onoff)
311 req.index = 0x0102;
312 return ec168_ctrl_msg(fe_to_d(fe), &req);
313}
314
315/* DVB USB Driver stuff */
316/* bInterfaceNumber 0 is HID
317 * bInterfaceNumber 1 is DVB-T */
318static struct dvb_usb_device_properties ec168_props = {
319 .driver_name = KBUILD_MODNAME,
320 .owner = THIS_MODULE,
321 .adapter_nr = adapter_nr,
322 .bInterfaceNumber = 1,
323
324 .identify_state = ec168_identify_state,
325 .firmware = "dvb-usb-ec168.fw",
326 .download_firmware = ec168_download_firmware,
327
328 .i2c_algo = &ec168_i2c_algo,
329 .frontend_attach = ec168_ec100_frontend_attach,
330 .tuner_attach = ec168_mxl5003s_tuner_attach,
331 .streaming_ctrl = ec168_streaming_ctrl,
332
333 .num_adapters = 1,
334 .adapter = {
335 {
336 .stream = DVB_USB_STREAM_BULK(0x82, 6, 32 * 512),
337 }
338 },
339};
340
341static const struct dvb_usb_driver_info ec168_driver_info = {
342 .name = "E3C EC168 reference design",
343 .props = &ec168_props,
344};
345
346static const struct usb_device_id ec168_id[] = {
347 { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168),
348 .driver_info = (kernel_ulong_t) &ec168_driver_info },
349 { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_2),
350 .driver_info = (kernel_ulong_t) &ec168_driver_info },
351 { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_3),
352 .driver_info = (kernel_ulong_t) &ec168_driver_info },
353 { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_4),
354 .driver_info = (kernel_ulong_t) &ec168_driver_info },
355 { USB_DEVICE(USB_VID_E3C, USB_PID_E3C_EC168_5),
356 .driver_info = (kernel_ulong_t) &ec168_driver_info },
357 {}
358};
359MODULE_DEVICE_TABLE(usb, ec168_id);
360
361static struct usb_driver ec168_driver = {
362 .name = KBUILD_MODNAME,
363 .id_table = ec168_id,
364 .probe = dvb_usbv2_probe,
365 .disconnect = dvb_usbv2_disconnect,
366 .suspend = dvb_usbv2_suspend,
367 .resume = dvb_usbv2_resume,
368 .no_dynamic_id = 1,
369 .soft_unbind = 1,
370};
371
372module_usb_driver(ec168_driver);
373
374MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
375MODULE_DESCRIPTION("E3C EC168 driver");
376MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/ec168.h b/drivers/media/usb/dvb-usb-v2/ec168.h
new file mode 100644
index 000000000000..9181236f6ebc
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/ec168.h
@@ -0,0 +1,63 @@
1/*
2 * E3C EC168 DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#ifndef EC168_H
23#define EC168_H
24
25#include "dvb_usb.h"
26
27#define ec168_debug_dump(r, t, v, i, b, l) { \
28 char *direction; \
29 if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
30 direction = ">>>"; \
31 else \
32 direction = "<<<"; \
33 pr_debug("%s: %02x %02x %02x %02x %02x %02x %02x %02x %s\n", \
34 __func__, t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, \
35 l & 0xff, l >> 8, direction); \
36}
37
38#define EC168_USB_TIMEOUT 1000
39
40struct ec168_req {
41 u8 cmd; /* [1] */
42 u16 value; /* [2|3] */
43 u16 index; /* [4|5] */
44 u16 size; /* [6|7] */
45 u8 *data;
46};
47
48enum ec168_cmd {
49 DOWNLOAD_FIRMWARE = 0x00,
50 CONFIG = 0x01,
51 DEMOD_RW = 0x03,
52 GPIO = 0x04,
53 STREAMING_CTRL = 0x10,
54 READ_I2C = 0x20,
55 WRITE_I2C = 0x21,
56 HID_DOWNLOAD = 0x30,
57 GET_CONFIG,
58 SET_CONFIG,
59 READ_DEMOD,
60 WRITE_DEMOD,
61};
62
63#endif
diff --git a/drivers/media/usb/dvb-usb-v2/gl861.c b/drivers/media/usb/dvb-usb-v2/gl861.c
new file mode 100644
index 000000000000..cf29f43e3598
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/gl861.c
@@ -0,0 +1,175 @@
1/* DVB USB compliant linux driver for GL861 USB2.0 devices.
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the
5 * Free Software Foundation, version 2.
6 *
7 * see Documentation/dvb/README.dvb-usb for more information
8 */
9#include "gl861.h"
10
11#include "zl10353.h"
12#include "qt1010.h"
13
14DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
15
16static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
17 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
18{
19 u16 index;
20 u16 value = addr << (8 + 1);
21 int wo = (rbuf == NULL || rlen == 0); /* write-only */
22 u8 req, type;
23
24 if (wo) {
25 req = GL861_REQ_I2C_WRITE;
26 type = GL861_WRITE;
27 } else { /* rw */
28 req = GL861_REQ_I2C_READ;
29 type = GL861_READ;
30 }
31
32 switch (wlen) {
33 case 1:
34 index = wbuf[0];
35 break;
36 case 2:
37 index = wbuf[0];
38 value = value + wbuf[1];
39 break;
40 default:
41 pr_err("%s: wlen=%d, aborting\n", KBUILD_MODNAME, wlen);
42 return -EINVAL;
43 }
44
45 msleep(1); /* avoid I2C errors */
46
47 return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
48 value, index, rbuf, rlen, 2000);
49}
50
51/* I2C */
52static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
53 int num)
54{
55 struct dvb_usb_device *d = i2c_get_adapdata(adap);
56 int i;
57
58 if (num > 2)
59 return -EINVAL;
60
61 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
62 return -EAGAIN;
63
64 for (i = 0; i < num; i++) {
65 /* write/read request */
66 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
67 if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
68 msg[i].len, msg[i+1].buf, msg[i+1].len) < 0)
69 break;
70 i++;
71 } else
72 if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
73 msg[i].len, NULL, 0) < 0)
74 break;
75 }
76
77 mutex_unlock(&d->i2c_mutex);
78 return i;
79}
80
81static u32 gl861_i2c_func(struct i2c_adapter *adapter)
82{
83 return I2C_FUNC_I2C;
84}
85
86static struct i2c_algorithm gl861_i2c_algo = {
87 .master_xfer = gl861_i2c_xfer,
88 .functionality = gl861_i2c_func,
89};
90
91/* Callbacks for DVB USB */
92static struct zl10353_config gl861_zl10353_config = {
93 .demod_address = 0x0f,
94 .no_tuner = 1,
95 .parallel_ts = 1,
96};
97
98static int gl861_frontend_attach(struct dvb_usb_adapter *adap)
99{
100
101 adap->fe[0] = dvb_attach(zl10353_attach, &gl861_zl10353_config,
102 &adap_to_d(adap)->i2c_adap);
103 if (adap->fe[0] == NULL)
104 return -EIO;
105
106 return 0;
107}
108
109static struct qt1010_config gl861_qt1010_config = {
110 .i2c_address = 0x62
111};
112
113static int gl861_tuner_attach(struct dvb_usb_adapter *adap)
114{
115 return dvb_attach(qt1010_attach,
116 adap->fe[0], &adap_to_d(adap)->i2c_adap,
117 &gl861_qt1010_config) == NULL ? -ENODEV : 0;
118}
119
120static int gl861_init(struct dvb_usb_device *d)
121{
122 /*
123 * There is 2 interfaces. Interface 0 is for TV and interface 1 is
124 * for HID remote controller. Interface 0 has 2 alternate settings.
125 * For some reason we need to set interface explicitly, defaulted
126 * as alternate setting 1?
127 */
128 return usb_set_interface(d->udev, 0, 0);
129}
130
131/* DVB USB Driver stuff */
132static struct dvb_usb_device_properties gl861_props = {
133 .driver_name = KBUILD_MODNAME,
134 .owner = THIS_MODULE,
135 .adapter_nr = adapter_nr,
136
137 .i2c_algo = &gl861_i2c_algo,
138 .frontend_attach = gl861_frontend_attach,
139 .tuner_attach = gl861_tuner_attach,
140 .init = gl861_init,
141
142 .num_adapters = 1,
143 .adapter = {
144 {
145 .stream = DVB_USB_STREAM_BULK(0x81, 7, 512),
146 }
147 }
148};
149
150static const struct usb_device_id gl861_id_table[] = {
151 { DVB_USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801,
152 &gl861_props, "MSI Mega Sky 55801 DVB-T USB2.0", NULL) },
153 { DVB_USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU,
154 &gl861_props, "A-LINK DTU DVB-T USB2.0", NULL) },
155 { }
156};
157MODULE_DEVICE_TABLE(usb, gl861_id_table);
158
159static struct usb_driver gl861_usb_driver = {
160 .name = KBUILD_MODNAME,
161 .id_table = gl861_id_table,
162 .probe = dvb_usbv2_probe,
163 .disconnect = dvb_usbv2_disconnect,
164 .suspend = dvb_usbv2_suspend,
165 .resume = dvb_usbv2_resume,
166 .no_dynamic_id = 1,
167 .soft_unbind = 1,
168};
169
170module_usb_driver(gl861_usb_driver);
171
172MODULE_AUTHOR("Carl Lundqvist <comabug@gmail.com>");
173MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861");
174MODULE_VERSION("0.1");
175MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/gl861.h b/drivers/media/usb/dvb-usb-v2/gl861.h
new file mode 100644
index 000000000000..b0b80d87bb7e
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/gl861.h
@@ -0,0 +1,12 @@
1#ifndef _DVB_USB_GL861_H_
2#define _DVB_USB_GL861_H_
3
4#include "dvb_usb.h"
5
6#define GL861_WRITE 0x40
7#define GL861_READ 0xc0
8
9#define GL861_REQ_I2C_WRITE 0x01
10#define GL861_REQ_I2C_READ 0x02
11
12#endif
diff --git a/drivers/media/usb/dvb-usb-v2/it913x.c b/drivers/media/usb/dvb-usb-v2/it913x.c
new file mode 100644
index 000000000000..695f9106bc54
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/it913x.c
@@ -0,0 +1,799 @@
1/*
2 * DVB USB compliant linux driver for ITE IT9135 and IT9137
3 *
4 * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)
5 * IT9135 (C) ITE Tech Inc.
6 * IT9137 (C) ITE Tech Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License Version 2, as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 *
22 * see Documentation/dvb/README.dvb-usb for more information
23 * see Documentation/dvb/it9137.txt for firmware information
24 *
25 */
26#define DVB_USB_LOG_PREFIX "it913x"
27
28#include <linux/usb.h>
29#include <linux/usb/input.h>
30#include <media/rc-core.h>
31
32#include "dvb_usb.h"
33#include "it913x-fe.h"
34
35/* debug */
36static int dvb_usb_it913x_debug;
37#define it_debug(var, level, args...) \
38 do { if ((var & level)) pr_debug(DVB_USB_LOG_PREFIX": " args); \
39} while (0)
40#define deb_info(level, args...) it_debug(dvb_usb_it913x_debug, level, args)
41#define info(args...) pr_info(DVB_USB_LOG_PREFIX": " args)
42
43module_param_named(debug, dvb_usb_it913x_debug, int, 0644);
44MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
45
46static int dvb_usb_it913x_firmware;
47module_param_named(firmware, dvb_usb_it913x_firmware, int, 0644);
48MODULE_PARM_DESC(firmware, "set firmware 0=auto"\
49 "1=IT9137 2=IT9135 V1 3=IT9135 V2");
50#define FW_IT9137 "dvb-usb-it9137-01.fw"
51#define FW_IT9135_V1 "dvb-usb-it9135-01.fw"
52#define FW_IT9135_V2 "dvb-usb-it9135-02.fw"
53
54DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
55
56struct it913x_state {
57 struct ite_config it913x_config;
58 u8 pid_filter_onoff;
59 bool proprietary_ir;
60 int cmd_counter;
61};
62
63static u16 check_sum(u8 *p, u8 len)
64{
65 u16 sum = 0;
66 u8 i = 1;
67 while (i < len)
68 sum += (i++ & 1) ? (*p++) << 8 : *p++;
69 return ~sum;
70}
71
72static int it913x_io(struct dvb_usb_device *d, u8 mode, u8 pro,
73 u8 cmd, u32 reg, u8 addr, u8 *data, u8 len)
74{
75 struct it913x_state *st = d->priv;
76 int ret = 0, i, buf_size = 1;
77 u8 *buff;
78 u8 rlen;
79 u16 chk_sum;
80
81 buff = kzalloc(256, GFP_KERNEL);
82 if (!buff) {
83 info("USB Buffer Failed");
84 return -ENOMEM;
85 }
86
87 buff[buf_size++] = pro;
88 buff[buf_size++] = cmd;
89 buff[buf_size++] = st->cmd_counter;
90
91 switch (mode) {
92 case READ_LONG:
93 case WRITE_LONG:
94 buff[buf_size++] = len;
95 buff[buf_size++] = 2;
96 buff[buf_size++] = (reg >> 24);
97 buff[buf_size++] = (reg >> 16) & 0xff;
98 buff[buf_size++] = (reg >> 8) & 0xff;
99 buff[buf_size++] = reg & 0xff;
100 break;
101 case READ_SHORT:
102 buff[buf_size++] = addr;
103 break;
104 case WRITE_SHORT:
105 buff[buf_size++] = len;
106 buff[buf_size++] = addr;
107 buff[buf_size++] = (reg >> 8) & 0xff;
108 buff[buf_size++] = reg & 0xff;
109 break;
110 case READ_DATA:
111 case WRITE_DATA:
112 break;
113 case WRITE_CMD:
114 mode = 7;
115 break;
116 default:
117 kfree(buff);
118 return -EINVAL;
119 }
120
121 if (mode & 1) {
122 for (i = 0; i < len ; i++)
123 buff[buf_size++] = data[i];
124 }
125 chk_sum = check_sum(&buff[1], buf_size);
126
127 buff[buf_size++] = chk_sum >> 8;
128 buff[0] = buf_size;
129 buff[buf_size++] = (chk_sum & 0xff);
130
131 ret = dvb_usbv2_generic_rw(d, buff, buf_size, buff, (mode & 1) ?
132 5 : len + 5);
133 if (ret < 0)
134 goto error;
135
136 rlen = (mode & 0x1) ? 0x1 : len;
137
138 if (mode & 1)
139 ret = buff[2];
140 else
141 memcpy(data, &buff[3], rlen);
142
143 st->cmd_counter++;
144
145error: kfree(buff);
146
147 return ret;
148}
149
150static int it913x_wr_reg(struct dvb_usb_device *d, u8 pro, u32 reg , u8 data)
151{
152 int ret;
153 u8 b[1];
154 b[0] = data;
155 ret = it913x_io(d, WRITE_LONG, pro,
156 CMD_DEMOD_WRITE, reg, 0, b, sizeof(b));
157
158 return ret;
159}
160
161static int it913x_read_reg(struct dvb_usb_device *d, u32 reg)
162{
163 int ret;
164 u8 data[1];
165
166 ret = it913x_io(d, READ_LONG, DEV_0,
167 CMD_DEMOD_READ, reg, 0, &data[0], sizeof(data));
168
169 return (ret < 0) ? ret : data[0];
170}
171
172static int it913x_query(struct dvb_usb_device *d, u8 pro)
173{
174 struct it913x_state *st = d->priv;
175 int ret, i;
176 u8 data[4];
177 u8 ver;
178
179 for (i = 0; i < 5; i++) {
180 ret = it913x_io(d, READ_LONG, pro, CMD_DEMOD_READ,
181 0x1222, 0, &data[0], 3);
182 ver = data[0];
183 if (ver > 0 && ver < 3)
184 break;
185 msleep(100);
186 }
187
188 if (ver < 1 || ver > 2) {
189 info("Failed to identify chip version applying 1");
190 st->it913x_config.chip_ver = 0x1;
191 st->it913x_config.chip_type = 0x9135;
192 return 0;
193 }
194
195 st->it913x_config.chip_ver = ver;
196 st->it913x_config.chip_type = (u16)(data[2] << 8) + data[1];
197
198 info("Chip Version=%02x Chip Type=%04x", st->it913x_config.chip_ver,
199 st->it913x_config.chip_type);
200
201 ret = it913x_io(d, READ_SHORT, pro,
202 CMD_QUERYINFO, 0, 0x1, &data[0], 4);
203
204 st->it913x_config.firmware = (data[0] << 24) | (data[1] << 16) |
205 (data[2] << 8) | data[3];
206
207 return ret;
208}
209
210static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
211{
212 struct dvb_usb_device *d = adap_to_d(adap);
213 struct it913x_state *st = adap_to_priv(adap);
214 int ret;
215 u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
216
217 mutex_lock(&d->i2c_mutex);
218
219 deb_info(1, "PID_C (%02x)", onoff);
220
221 ret = it913x_wr_reg(d, pro, PID_EN, st->pid_filter_onoff);
222
223 mutex_unlock(&d->i2c_mutex);
224 return ret;
225}
226
227static int it913x_pid_filter(struct dvb_usb_adapter *adap,
228 int index, u16 pid, int onoff)
229{
230 struct dvb_usb_device *d = adap_to_d(adap);
231 struct it913x_state *st = adap_to_priv(adap);
232 int ret;
233 u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
234
235 mutex_lock(&d->i2c_mutex);
236
237 deb_info(1, "PID_F (%02x)", onoff);
238
239 ret = it913x_wr_reg(d, pro, PID_LSB, (u8)(pid & 0xff));
240
241 ret |= it913x_wr_reg(d, pro, PID_MSB, (u8)(pid >> 8));
242
243 ret |= it913x_wr_reg(d, pro, PID_INX_EN, (u8)onoff);
244
245 ret |= it913x_wr_reg(d, pro, PID_INX, (u8)(index & 0x1f));
246
247 if (d->udev->speed == USB_SPEED_HIGH && pid == 0x2000) {
248 ret |= it913x_wr_reg(d , pro, PID_EN, !onoff);
249 st->pid_filter_onoff = !onoff;
250 } else
251 st->pid_filter_onoff =
252 adap->pid_filtering;
253
254 mutex_unlock(&d->i2c_mutex);
255 return 0;
256}
257
258
259static int it913x_return_status(struct dvb_usb_device *d)
260{
261 struct it913x_state *st = d->priv;
262 int ret = it913x_query(d, DEV_0);
263 if (st->it913x_config.firmware > 0)
264 info("Firmware Version %d", st->it913x_config.firmware);
265
266 return ret;
267}
268
269static int it913x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
270 int num)
271{
272 struct dvb_usb_device *d = i2c_get_adapdata(adap);
273 static u8 data[256];
274 int ret;
275 u32 reg;
276 u8 pro;
277
278 mutex_lock(&d->i2c_mutex);
279
280 deb_info(2, "num of messages %d address %02x", num, msg[0].addr);
281
282 pro = (msg[0].addr & 0x2) ? DEV_0_DMOD : 0x0;
283 pro |= (msg[0].addr & 0x20) ? DEV_1 : DEV_0;
284 memcpy(data, msg[0].buf, msg[0].len);
285 reg = (data[0] << 24) + (data[1] << 16) +
286 (data[2] << 8) + data[3];
287 if (num == 2) {
288 ret = it913x_io(d, READ_LONG, pro,
289 CMD_DEMOD_READ, reg, 0, data, msg[1].len);
290 memcpy(msg[1].buf, data, msg[1].len);
291 } else
292 ret = it913x_io(d, WRITE_LONG, pro, CMD_DEMOD_WRITE,
293 reg, 0, &data[4], msg[0].len - 4);
294
295 mutex_unlock(&d->i2c_mutex);
296
297 return ret;
298}
299
300static u32 it913x_i2c_func(struct i2c_adapter *adapter)
301{
302 return I2C_FUNC_I2C;
303}
304
305static struct i2c_algorithm it913x_i2c_algo = {
306 .master_xfer = it913x_i2c_xfer,
307 .functionality = it913x_i2c_func,
308};
309
310/* Callbacks for DVB USB */
311#define IT913X_POLL 250
312static int it913x_rc_query(struct dvb_usb_device *d)
313{
314 u8 ibuf[4];
315 int ret;
316 u32 key;
317 /* Avoid conflict with frontends*/
318 mutex_lock(&d->i2c_mutex);
319
320 ret = it913x_io(d, READ_LONG, PRO_LINK, CMD_IR_GET,
321 0, 0, &ibuf[0], sizeof(ibuf));
322
323 if ((ibuf[2] + ibuf[3]) == 0xff) {
324 key = ibuf[2];
325 key += ibuf[0] << 16;
326 key += ibuf[1] << 8;
327 deb_info(1, "NEC Extended Key =%08x", key);
328 if (d->rc_dev != NULL)
329 rc_keydown(d->rc_dev, key, 0);
330 }
331
332 mutex_unlock(&d->i2c_mutex);
333
334 return ret;
335}
336
337/* Firmware sets raw */
338static const char fw_it9135_v1[] = FW_IT9135_V1;
339static const char fw_it9135_v2[] = FW_IT9135_V2;
340static const char fw_it9137[] = FW_IT9137;
341
342static void ite_get_firmware_name(struct dvb_usb_device *d,
343 const char **name)
344{
345 struct it913x_state *st = d->priv;
346 int sw;
347 /* auto switch */
348 if (le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_KWORLD_2)
349 sw = IT9137_FW;
350 else if (st->it913x_config.chip_ver == 1)
351 sw = IT9135_V1_FW;
352 else
353 sw = IT9135_V2_FW;
354
355 /* force switch */
356 if (dvb_usb_it913x_firmware != IT9135_AUTO)
357 sw = dvb_usb_it913x_firmware;
358
359 switch (sw) {
360 case IT9135_V1_FW:
361 st->it913x_config.firmware_ver = 1;
362 st->it913x_config.adc_x2 = 1;
363 st->it913x_config.read_slevel = false;
364 *name = fw_it9135_v1;
365 break;
366 case IT9135_V2_FW:
367 st->it913x_config.firmware_ver = 1;
368 st->it913x_config.adc_x2 = 1;
369 st->it913x_config.read_slevel = false;
370 *name = fw_it9135_v2;
371 switch (st->it913x_config.tuner_id_0) {
372 case IT9135_61:
373 case IT9135_62:
374 break;
375 default:
376 info("Unknown tuner ID applying default 0x60");
377 case IT9135_60:
378 st->it913x_config.tuner_id_0 = IT9135_60;
379 }
380 break;
381 case IT9137_FW:
382 default:
383 st->it913x_config.firmware_ver = 0;
384 st->it913x_config.adc_x2 = 0;
385 st->it913x_config.read_slevel = true;
386 *name = fw_it9137;
387 }
388
389 return;
390}
391
392#define TS_MPEG_PKT_SIZE 188
393#define EP_LOW 21
394#define TS_BUFFER_SIZE_PID (EP_LOW*TS_MPEG_PKT_SIZE)
395#define EP_HIGH 348
396#define TS_BUFFER_SIZE_MAX (EP_HIGH*TS_MPEG_PKT_SIZE)
397
398static int it913x_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
399 struct usb_data_stream_properties *stream)
400{
401 struct dvb_usb_adapter *adap = fe_to_adap(fe);
402 if (adap->pid_filtering)
403 stream->u.bulk.buffersize = TS_BUFFER_SIZE_PID;
404 else
405 stream->u.bulk.buffersize = TS_BUFFER_SIZE_MAX;
406
407 return 0;
408}
409
410static int it913x_select_config(struct dvb_usb_device *d)
411{
412 struct it913x_state *st = d->priv;
413 int ret, reg;
414
415 ret = it913x_return_status(d);
416 if (ret < 0)
417 return ret;
418
419 if (st->it913x_config.chip_ver == 0x02
420 && st->it913x_config.chip_type == 0x9135)
421 reg = it913x_read_reg(d, 0x461d);
422 else
423 reg = it913x_read_reg(d, 0x461b);
424
425 if (reg < 0)
426 return reg;
427
428 if (reg == 0) {
429 st->it913x_config.dual_mode = 0;
430 st->it913x_config.tuner_id_0 = IT9135_38;
431 st->proprietary_ir = true;
432 } else {
433 /* TS mode */
434 reg = it913x_read_reg(d, 0x49c5);
435 if (reg < 0)
436 return reg;
437 st->it913x_config.dual_mode = reg;
438
439 /* IR mode type */
440 reg = it913x_read_reg(d, 0x49ac);
441 if (reg < 0)
442 return reg;
443 if (reg == 5) {
444 info("Remote propriety (raw) mode");
445 st->proprietary_ir = true;
446 } else if (reg == 1) {
447 info("Remote HID mode NOT SUPPORTED");
448 st->proprietary_ir = false;
449 }
450
451 /* Tuner_id */
452 reg = it913x_read_reg(d, 0x49d0);
453 if (reg < 0)
454 return reg;
455 st->it913x_config.tuner_id_0 = reg;
456 }
457
458 info("Dual mode=%x Tuner Type=%x", st->it913x_config.dual_mode,
459 st->it913x_config.tuner_id_0);
460
461 return ret;
462}
463
464static int it913x_streaming_ctrl(struct dvb_frontend *fe, int onoff)
465{
466 struct dvb_usb_adapter *adap = fe_to_adap(fe);
467 struct dvb_usb_device *d = adap_to_d(adap);
468 struct it913x_state *st = fe_to_priv(fe);
469 int ret = 0;
470 u8 pro = (adap->id == 0) ? DEV_0_DMOD : DEV_1_DMOD;
471
472 deb_info(1, "STM (%02x)", onoff);
473
474 if (!onoff) {
475 mutex_lock(&d->i2c_mutex);
476
477 ret = it913x_wr_reg(d, pro, PID_RST, 0x1);
478
479 mutex_unlock(&d->i2c_mutex);
480 st->pid_filter_onoff =
481 adap->pid_filtering;
482
483 }
484
485 return ret;
486}
487
488static int it913x_identify_state(struct dvb_usb_device *d, const char **name)
489{
490 struct it913x_state *st = d->priv;
491 int ret;
492 u8 reg;
493
494 /* Read and select config */
495 ret = it913x_select_config(d);
496 if (ret < 0)
497 return ret;
498
499 ite_get_firmware_name(d, name);
500
501 if (st->it913x_config.firmware > 0)
502 return WARM;
503
504 if (st->it913x_config.dual_mode) {
505 st->it913x_config.tuner_id_1 = it913x_read_reg(d, 0x49e0);
506 ret = it913x_wr_reg(d, DEV_0, GPIOH1_EN, 0x1);
507 ret |= it913x_wr_reg(d, DEV_0, GPIOH1_ON, 0x1);
508 ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x1);
509 msleep(50);
510 ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x0);
511 msleep(50);
512 reg = it913x_read_reg(d, GPIOH1_O);
513 if (reg == 0) {
514 ret |= it913x_wr_reg(d, DEV_0, GPIOH1_O, 0x1);
515 ret |= it913x_return_status(d);
516 if (ret != 0)
517 ret = it913x_wr_reg(d, DEV_0,
518 GPIOH1_O, 0x0);
519 }
520 }
521
522 reg = it913x_read_reg(d, IO_MUX_POWER_CLK);
523
524 if (st->it913x_config.dual_mode) {
525 ret |= it913x_wr_reg(d, DEV_0, 0x4bfb, CHIP2_I2C_ADDR);
526 if (st->it913x_config.firmware_ver == 1)
527 ret |= it913x_wr_reg(d, DEV_0, 0xcfff, 0x1);
528 else
529 ret |= it913x_wr_reg(d, DEV_0, CLK_O_EN, 0x1);
530 } else {
531 ret |= it913x_wr_reg(d, DEV_0, 0x4bfb, 0x0);
532 if (st->it913x_config.firmware_ver == 1)
533 ret |= it913x_wr_reg(d, DEV_0, 0xcfff, 0x0);
534 else
535 ret |= it913x_wr_reg(d, DEV_0, CLK_O_EN, 0x0);
536 }
537
538 ret |= it913x_wr_reg(d, DEV_0, I2C_CLK, I2C_CLK_100);
539
540 return (ret < 0) ? ret : COLD;
541}
542
543static int it913x_download_firmware(struct dvb_usb_device *d,
544 const struct firmware *fw)
545{
546 struct it913x_state *st = d->priv;
547 int ret = 0, i = 0, pos = 0;
548 u8 packet_size, min_pkt;
549 u8 *fw_data;
550
551 ret = it913x_wr_reg(d, DEV_0, I2C_CLK, I2C_CLK_100);
552
553 info("FRM Starting Firmware Download");
554
555 /* Multi firmware loader */
556 /* This uses scatter write firmware headers */
557 /* The firmware must start with 03 XX 00 */
558 /* and be the extact firmware length */
559
560 if (st->it913x_config.chip_ver == 2)
561 min_pkt = 0x11;
562 else
563 min_pkt = 0x19;
564
565 while (i <= fw->size) {
566 if (((fw->data[i] == 0x3) && (fw->data[i + 2] == 0x0))
567 || (i == fw->size)) {
568 packet_size = i - pos;
569 if ((packet_size > min_pkt) || (i == fw->size)) {
570 fw_data = (u8 *)(fw->data + pos);
571 pos += packet_size;
572 if (packet_size > 0) {
573 ret = it913x_io(d, WRITE_DATA,
574 DEV_0, CMD_SCATTER_WRITE, 0,
575 0, fw_data, packet_size);
576 if (ret < 0)
577 break;
578 }
579 udelay(1000);
580 }
581 }
582 i++;
583 }
584
585 if (ret < 0)
586 info("FRM Firmware Download Failed (%d)" , ret);
587 else
588 info("FRM Firmware Download Completed - Resetting Device");
589
590 msleep(30);
591
592 ret = it913x_io(d, WRITE_CMD, DEV_0, CMD_BOOT, 0, 0, NULL, 0);
593 if (ret < 0)
594 info("FRM Device not responding to reboot");
595
596 ret = it913x_return_status(d);
597 if (st->it913x_config.firmware == 0) {
598 info("FRM Failed to reboot device");
599 return -ENODEV;
600 }
601
602 msleep(30);
603
604 ret = it913x_wr_reg(d, DEV_0, I2C_CLK, I2C_CLK_400);
605
606 msleep(30);
607
608 /* Tuner function */
609 if (st->it913x_config.dual_mode)
610 ret |= it913x_wr_reg(d, DEV_0_DMOD , 0xec4c, 0xa0);
611 else
612 ret |= it913x_wr_reg(d, DEV_0_DMOD , 0xec4c, 0x68);
613
614 if ((st->it913x_config.chip_ver == 1) &&
615 (st->it913x_config.chip_type == 0x9135)) {
616 ret |= it913x_wr_reg(d, DEV_0, PADODPU, 0x0);
617 ret |= it913x_wr_reg(d, DEV_0, AGC_O_D, 0x0);
618 if (st->it913x_config.dual_mode) {
619 ret |= it913x_wr_reg(d, DEV_1, PADODPU, 0x0);
620 ret |= it913x_wr_reg(d, DEV_1, AGC_O_D, 0x0);
621 }
622 }
623
624 return (ret < 0) ? -ENODEV : 0;
625}
626
627static int it913x_name(struct dvb_usb_adapter *adap)
628{
629 struct dvb_usb_device *d = adap_to_d(adap);
630 const char *desc = d->name;
631 char *fe_name[] = {"_1", "_2", "_3", "_4"};
632 char *name = adap->fe[0]->ops.info.name;
633
634 strlcpy(name, desc, 128);
635 strlcat(name, fe_name[adap->id], 128);
636
637 return 0;
638}
639
640static int it913x_frontend_attach(struct dvb_usb_adapter *adap)
641{
642 struct dvb_usb_device *d = adap_to_d(adap);
643 struct it913x_state *st = d->priv;
644 int ret = 0;
645 u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5);
646 u16 ep_size = adap->stream.buf_size / 4;
647 u8 pkt_size = 0x80;
648
649 if (d->udev->speed != USB_SPEED_HIGH)
650 pkt_size = 0x10;
651
652 st->it913x_config.adf = it913x_read_reg(d, IO_MUX_POWER_CLK);
653
654 adap->fe[0] = dvb_attach(it913x_fe_attach,
655 &d->i2c_adap, adap_addr, &st->it913x_config);
656
657 if (adap->id == 0 && adap->fe[0]) {
658 it913x_wr_reg(d, DEV_0_DMOD, MP2_SW_RST, 0x1);
659 it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_SW_RST, 0x1);
660 it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x0f);
661 it913x_wr_reg(d, DEV_0, EP0_TX_NAK, 0x1b);
662 it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x2f);
663 it913x_wr_reg(d, DEV_0, EP4_TX_LEN_LSB,
664 ep_size & 0xff);
665 it913x_wr_reg(d, DEV_0, EP4_TX_LEN_MSB, ep_size >> 8);
666 ret = it913x_wr_reg(d, DEV_0, EP4_MAX_PKT, pkt_size);
667 } else if (adap->id == 1 && adap->fe[0]) {
668 it913x_wr_reg(d, DEV_0, EP0_TX_EN, 0x6f);
669 it913x_wr_reg(d, DEV_0, EP5_TX_LEN_LSB,
670 ep_size & 0xff);
671 it913x_wr_reg(d, DEV_0, EP5_TX_LEN_MSB, ep_size >> 8);
672 it913x_wr_reg(d, DEV_0, EP5_MAX_PKT, pkt_size);
673 it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_EN, 0x1);
674 it913x_wr_reg(d, DEV_1_DMOD, MP2IF_SERIAL, 0x1);
675 it913x_wr_reg(d, DEV_1, TOP_HOSTB_SER_MODE, 0x1);
676 it913x_wr_reg(d, DEV_0_DMOD, TSIS_ENABLE, 0x1);
677 it913x_wr_reg(d, DEV_0_DMOD, MP2_SW_RST, 0x0);
678 it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_SW_RST, 0x0);
679 it913x_wr_reg(d, DEV_0_DMOD, MP2IF2_HALF_PSB, 0x0);
680 it913x_wr_reg(d, DEV_0_DMOD, MP2IF_STOP_EN, 0x1);
681 it913x_wr_reg(d, DEV_1_DMOD, MPEG_FULL_SPEED, 0x0);
682 ret = it913x_wr_reg(d, DEV_1_DMOD, MP2IF_STOP_EN, 0x0);
683 } else
684 return -ENODEV;
685
686 ret |= it913x_name(adap);
687
688 return ret;
689}
690
691/* DVB USB Driver */
692static int it913x_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
693{
694 struct it913x_state *st = d->priv;
695
696 if (st->proprietary_ir == false) {
697 rc->map_name = NULL;
698 return 0;
699 }
700
701 rc->allowed_protos = RC_TYPE_NEC;
702 rc->query = it913x_rc_query;
703 rc->interval = 250;
704
705 return 0;
706}
707
708static int it913x_get_adapter_count(struct dvb_usb_device *d)
709{
710 struct it913x_state *st = d->priv;
711 if (st->it913x_config.dual_mode)
712 return 2;
713 return 1;
714}
715
716static struct dvb_usb_device_properties it913x_properties = {
717 .driver_name = KBUILD_MODNAME,
718 .owner = THIS_MODULE,
719 .bInterfaceNumber = 0,
720 .generic_bulk_ctrl_endpoint = 0x02,
721 .generic_bulk_ctrl_endpoint_response = 0x81,
722
723 .adapter_nr = adapter_nr,
724 .size_of_priv = sizeof(struct it913x_state),
725
726 .identify_state = it913x_identify_state,
727 .i2c_algo = &it913x_i2c_algo,
728
729 .download_firmware = it913x_download_firmware,
730
731 .frontend_attach = it913x_frontend_attach,
732 .get_rc_config = it913x_get_rc_config,
733 .get_stream_config = it913x_get_stream_config,
734 .get_adapter_count = it913x_get_adapter_count,
735 .streaming_ctrl = it913x_streaming_ctrl,
736
737
738 .adapter = {
739 {
740 .caps = DVB_USB_ADAP_HAS_PID_FILTER|
741 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
742 .pid_filter_count = 32,
743 .pid_filter = it913x_pid_filter,
744 .pid_filter_ctrl = it913x_pid_filter_ctrl,
745 .stream =
746 DVB_USB_STREAM_BULK(0x84, 10, TS_BUFFER_SIZE_MAX),
747 },
748 {
749 .caps = DVB_USB_ADAP_HAS_PID_FILTER|
750 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
751 .pid_filter_count = 32,
752 .pid_filter = it913x_pid_filter,
753 .pid_filter_ctrl = it913x_pid_filter_ctrl,
754 .stream =
755 DVB_USB_STREAM_BULK(0x85, 10, TS_BUFFER_SIZE_MAX),
756 }
757 }
758};
759
760static const struct usb_device_id it913x_id_table[] = {
761 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09,
762 &it913x_properties, "Kworld UB499-2T T09(IT9137)",
763 RC_MAP_IT913X_V1) },
764 { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135,
765 &it913x_properties, "ITE 9135 Generic",
766 RC_MAP_IT913X_V1) },
767 { DVB_USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22_IT9137,
768 &it913x_properties, "Sveon STV22 Dual DVB-T HDTV(IT9137)",
769 RC_MAP_IT913X_V1) },
770 { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9005,
771 &it913x_properties, "ITE 9135(9005) Generic",
772 RC_MAP_IT913X_V2) },
773 { DVB_USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135_9006,
774 &it913x_properties, "ITE 9135(9006) Generic",
775 RC_MAP_IT913X_V1) },
776 {} /* Terminating entry */
777};
778
779MODULE_DEVICE_TABLE(usb, it913x_id_table);
780
781static struct usb_driver it913x_driver = {
782 .name = KBUILD_MODNAME,
783 .probe = dvb_usbv2_probe,
784 .disconnect = dvb_usbv2_disconnect,
785 .suspend = dvb_usbv2_suspend,
786 .resume = dvb_usbv2_resume,
787 .id_table = it913x_id_table,
788};
789
790module_usb_driver(it913x_driver);
791
792MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
793MODULE_DESCRIPTION("it913x USB 2 Driver");
794MODULE_VERSION("1.32");
795MODULE_LICENSE("GPL");
796MODULE_FIRMWARE(FW_IT9135_V1);
797MODULE_FIRMWARE(FW_IT9135_V2);
798MODULE_FIRMWARE(FW_IT9137);
799
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
new file mode 100644
index 000000000000..c41d9d9ec7b5
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -0,0 +1,1369 @@
1/* DVB USB compliant linux driver for
2 *
3 * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395
4 * LME2510C + LG TDQY-P001F
5 * LME2510C + BS2F7HZ0194
6 * LME2510 + LG TDQY-P001F
7 * LME2510 + BS2F7HZ0194
8 *
9 * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
10 * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
11 *
12 * MV001F (LME2510+LGTDQY-P001F)
13 * LG TDQY - P001F =(TDA8263 + TDA10086H)
14 *
15 * MVB0001F (LME2510C+LGTDQT-P001F)
16 *
17 * MV0194 (LME2510+SHARP:BS2F7HZ0194)
18 * SHARP:BS2F7HZ0194 = (STV0299+IX2410)
19 *
20 * MVB0194 (LME2510C+SHARP0194)
21 *
22 * LME2510C + M88RS2000
23 *
24 * For firmware see Documentation/dvb/lmedm04.txt
25 *
26 * I2C addresses:
27 * 0xd0 - STV0288 - Demodulator
28 * 0xc0 - Sharp IX2505V - Tuner
29 * --
30 * 0x1c - TDA10086 - Demodulator
31 * 0xc0 - TDA8263 - Tuner
32 * --
33 * 0xd0 - STV0299 - Demodulator
34 * 0xc0 - IX2410 - Tuner
35 *
36 *
37 * VID = 3344 PID LME2510=1122 LME2510C=1120
38 *
39 * Copyright (C) 2010 Malcolm Priestley (tvboxspy@gmail.com)
40 * LME2510(C)(C) Leaguerme (Shenzhen) MicroElectronics Co., Ltd.
41 *
42 * This program is free software; you can redistribute it and/or modify
43 * it under the terms of the GNU General Public License Version 2, as
44 * published by the Free Software Foundation.
45 *
46 * This program is distributed in the hope that it will be useful,
47 * but WITHOUT ANY WARRANTY; without even the implied warranty of
48 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49 * GNU General Public License for more details.
50 *
51 * You should have received a copy of the GNU General Public License
52 * along with this program; if not, write to the Free Software
53 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
54 *
55 *
56 * see Documentation/dvb/README.dvb-usb for more information
57 *
58 * Known Issues :
59 * LME2510: Non Intel USB chipsets fail to maintain High Speed on
60 * Boot or Hot Plug.
61 *
62 * QQbox suffers from noise on LNB voltage.
63 *
64 * LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system
65 * with other tuners. After a cold reset streaming will not start.
66 *
67 * M88RS2000 suffers from loss of lock.
68 */
69#define DVB_USB_LOG_PREFIX "LME2510(C)"
70#include <linux/usb.h>
71#include <linux/usb/input.h>
72#include <media/rc-core.h>
73
74#include "dvb_usb.h"
75#include "lmedm04.h"
76#include "tda826x.h"
77#include "tda10086.h"
78#include "stv0288.h"
79#include "ix2505v.h"
80#include "stv0299.h"
81#include "dvb-pll.h"
82#include "z0194a.h"
83#include "m88rs2000.h"
84
85
86#define LME2510_C_S7395 "dvb-usb-lme2510c-s7395.fw";
87#define LME2510_C_LG "dvb-usb-lme2510c-lg.fw";
88#define LME2510_C_S0194 "dvb-usb-lme2510c-s0194.fw";
89#define LME2510_C_RS2000 "dvb-usb-lme2510c-rs2000.fw";
90#define LME2510_LG "dvb-usb-lme2510-lg.fw";
91#define LME2510_S0194 "dvb-usb-lme2510-s0194.fw";
92
93/* debug */
94static int dvb_usb_lme2510_debug;
95#define lme_debug(var, level, args...) do { \
96 if ((var >= level)) \
97 pr_debug(DVB_USB_LOG_PREFIX": " args); \
98} while (0)
99#define deb_info(level, args...) lme_debug(dvb_usb_lme2510_debug, level, args)
100#define debug_data_snipet(level, name, p) \
101 deb_info(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
102 *p, *(p+1), *(p+2), *(p+3), *(p+4), \
103 *(p+5), *(p+6), *(p+7));
104#define info(args...) pr_info(DVB_USB_LOG_PREFIX": "args)
105
106module_param_named(debug, dvb_usb_lme2510_debug, int, 0644);
107MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
108
109static int dvb_usb_lme2510_firmware;
110module_param_named(firmware, dvb_usb_lme2510_firmware, int, 0644);
111MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
112
113static int pid_filter;
114module_param_named(pid, pid_filter, int, 0644);
115MODULE_PARM_DESC(pid, "set default 0=default 1=off 2=on");
116
117
118DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
119
120#define TUNER_DEFAULT 0x0
121#define TUNER_LG 0x1
122#define TUNER_S7395 0x2
123#define TUNER_S0194 0x3
124#define TUNER_RS2000 0x4
125
126struct lme2510_state {
127 u8 id;
128 u8 tuner_config;
129 u8 signal_lock;
130 u8 signal_level;
131 u8 signal_sn;
132 u8 time_key;
133 u8 last_key;
134 u8 key_timeout;
135 u8 i2c_talk_onoff;
136 u8 i2c_gate;
137 u8 i2c_tuner_gate_w;
138 u8 i2c_tuner_gate_r;
139 u8 i2c_tuner_addr;
140 u8 stream_on;
141 u8 pid_size;
142 u8 pid_off;
143 void *buffer;
144 struct urb *lme_urb;
145 void *usb_buffer;
146 int (*fe_set_voltage)(struct dvb_frontend *, fe_sec_voltage_t);
147 u8 dvb_usb_lme2510_firmware;
148};
149
150static int lme2510_bulk_write(struct usb_device *dev,
151 u8 *snd, int len, u8 pipe)
152{
153 int ret, actual_l;
154
155 ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe),
156 snd, len , &actual_l, 100);
157 return ret;
158}
159
160static int lme2510_bulk_read(struct usb_device *dev,
161 u8 *rev, int len, u8 pipe)
162{
163 int ret, actual_l;
164
165 ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe),
166 rev, len , &actual_l, 200);
167 return ret;
168}
169
170static int lme2510_usb_talk(struct dvb_usb_device *d,
171 u8 *wbuf, int wlen, u8 *rbuf, int rlen)
172{
173 struct lme2510_state *st = d->priv;
174 u8 *buff;
175 int ret = 0;
176
177 if (st->usb_buffer == NULL) {
178 st->usb_buffer = kmalloc(64, GFP_KERNEL);
179 if (st->usb_buffer == NULL) {
180 info("MEM Error no memory");
181 return -ENOMEM;
182 }
183 }
184 buff = st->usb_buffer;
185
186 ret = mutex_lock_interruptible(&d->usb_mutex);
187
188 if (ret < 0)
189 return -EAGAIN;
190
191 /* the read/write capped at 64 */
192 memcpy(buff, wbuf, (wlen < 64) ? wlen : 64);
193
194 ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
195
196 ret |= lme2510_bulk_read(d->udev, buff, (rlen < 64) ?
197 rlen : 64 , 0x01);
198
199 if (rlen > 0)
200 memcpy(rbuf, buff, rlen);
201
202 mutex_unlock(&d->usb_mutex);
203
204 return (ret < 0) ? -ENODEV : 0;
205}
206
207static int lme2510_stream_restart(struct dvb_usb_device *d)
208{
209 struct lme2510_state *st = d->priv;
210 u8 all_pids[] = LME_ALL_PIDS;
211 u8 stream_on[] = LME_ST_ON_W;
212 int ret;
213 u8 rbuff[1];
214 if (st->pid_off)
215 ret = lme2510_usb_talk(d, all_pids, sizeof(all_pids),
216 rbuff, sizeof(rbuff));
217 /*Restart Stream Command*/
218 ret = lme2510_usb_talk(d, stream_on, sizeof(stream_on),
219 rbuff, sizeof(rbuff));
220 return ret;
221}
222
223static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out)
224{
225 struct lme2510_state *st = d->priv;
226 static u8 pid_buff[] = LME_ZERO_PID;
227 static u8 rbuf[1];
228 u8 pid_no = index * 2;
229 u8 pid_len = pid_no + 2;
230 int ret = 0;
231 deb_info(1, "PID Setting Pid %04x", pid_out);
232
233 if (st->pid_size == 0)
234 ret |= lme2510_stream_restart(d);
235
236 pid_buff[2] = pid_no;
237 pid_buff[3] = (u8)pid_out & 0xff;
238 pid_buff[4] = pid_no + 1;
239 pid_buff[5] = (u8)(pid_out >> 8);
240
241 if (pid_len > st->pid_size)
242 st->pid_size = pid_len;
243 pid_buff[7] = 0x80 + st->pid_size;
244
245 ret |= lme2510_usb_talk(d, pid_buff ,
246 sizeof(pid_buff) , rbuf, sizeof(rbuf));
247
248 if (st->stream_on)
249 ret |= lme2510_stream_restart(d);
250
251 return ret;
252}
253
254static void lme2510_int_response(struct urb *lme_urb)
255{
256 struct dvb_usb_adapter *adap = lme_urb->context;
257 struct lme2510_state *st = adap_to_priv(adap);
258 static u8 *ibuf, *rbuf;
259 int i = 0, offset;
260 u32 key;
261
262 switch (lme_urb->status) {
263 case 0:
264 case -ETIMEDOUT:
265 break;
266 case -ECONNRESET:
267 case -ENOENT:
268 case -ESHUTDOWN:
269 return;
270 default:
271 info("Error %x", lme_urb->status);
272 break;
273 }
274
275 rbuf = (u8 *) lme_urb->transfer_buffer;
276
277 offset = ((lme_urb->actual_length/8) > 4)
278 ? 4 : (lme_urb->actual_length/8) ;
279
280 for (i = 0; i < offset; ++i) {
281 ibuf = (u8 *)&rbuf[i*8];
282 deb_info(5, "INT O/S C =%02x C/O=%02x Type =%02x%02x",
283 offset, i, ibuf[0], ibuf[1]);
284
285 switch (ibuf[0]) {
286 case 0xaa:
287 debug_data_snipet(1, "INT Remote data snipet", ibuf);
288 if ((ibuf[4] + ibuf[5]) == 0xff) {
289 key = ibuf[5];
290 key += (ibuf[3] > 0)
291 ? (ibuf[3] ^ 0xff) << 8 : 0;
292 key += (ibuf[2] ^ 0xff) << 16;
293 deb_info(1, "INT Key =%08x", key);
294 if (adap_to_d(adap)->rc_dev != NULL)
295 rc_keydown(adap_to_d(adap)->rc_dev,
296 key, 0);
297 }
298 break;
299 case 0xbb:
300 switch (st->tuner_config) {
301 case TUNER_LG:
302 if (ibuf[2] > 0)
303 st->signal_lock = ibuf[2];
304 st->signal_level = ibuf[4];
305 st->signal_sn = ibuf[3];
306 st->time_key = ibuf[7];
307 break;
308 case TUNER_S7395:
309 case TUNER_S0194:
310 /* Tweak for earlier firmware*/
311 if (ibuf[1] == 0x03) {
312 if (ibuf[2] > 1)
313 st->signal_lock = ibuf[2];
314 st->signal_level = ibuf[3];
315 st->signal_sn = ibuf[4];
316 } else {
317 st->signal_level = ibuf[4];
318 st->signal_sn = ibuf[5];
319 st->signal_lock =
320 (st->signal_lock & 0xf7) +
321 ((ibuf[2] & 0x01) << 0x03);
322 }
323 break;
324 case TUNER_RS2000:
325 if (ibuf[1] == 0x3 && ibuf[6] == 0xff)
326 st->signal_lock = 0xff;
327 else
328 st->signal_lock = 0x00;
329 st->signal_level = ibuf[5];
330 st->signal_sn = ibuf[4];
331 st->time_key = ibuf[7];
332 default:
333 break;
334 }
335 debug_data_snipet(5, "INT Remote data snipet in", ibuf);
336 break;
337 case 0xcc:
338 debug_data_snipet(1, "INT Control data snipet", ibuf);
339 break;
340 default:
341 debug_data_snipet(1, "INT Unknown data snipet", ibuf);
342 break;
343 }
344 }
345 usb_submit_urb(lme_urb, GFP_ATOMIC);
346}
347
348static int lme2510_int_read(struct dvb_usb_adapter *adap)
349{
350 struct dvb_usb_device *d = adap_to_d(adap);
351 struct lme2510_state *lme_int = adap_to_priv(adap);
352
353 lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC);
354
355 if (lme_int->lme_urb == NULL)
356 return -ENOMEM;
357
358 lme_int->buffer = usb_alloc_coherent(d->udev, 128, GFP_ATOMIC,
359 &lme_int->lme_urb->transfer_dma);
360
361 if (lme_int->buffer == NULL)
362 return -ENOMEM;
363
364 usb_fill_int_urb(lme_int->lme_urb,
365 d->udev,
366 usb_rcvintpipe(d->udev, 0xa),
367 lme_int->buffer,
368 128,
369 lme2510_int_response,
370 adap,
371 8);
372
373 lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
374
375 usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC);
376 info("INT Interrupt Service Started");
377
378 return 0;
379}
380
381static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
382{
383 struct dvb_usb_device *d = adap_to_d(adap);
384 struct lme2510_state *st = adap_to_priv(adap);
385 static u8 clear_pid_reg[] = LME_ALL_PIDS;
386 static u8 rbuf[1];
387 int ret = 0;
388
389 deb_info(1, "PID Clearing Filter");
390
391 mutex_lock(&d->i2c_mutex);
392
393 if (!onoff) {
394 ret |= lme2510_usb_talk(d, clear_pid_reg,
395 sizeof(clear_pid_reg), rbuf, sizeof(rbuf));
396 st->pid_off = true;
397 } else
398 st->pid_off = false;
399
400 st->pid_size = 0;
401
402 mutex_unlock(&d->i2c_mutex);
403
404 return 0;
405}
406
407static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
408 int onoff)
409{
410 struct dvb_usb_device *d = adap_to_d(adap);
411 int ret = 0;
412
413 deb_info(3, "%s PID=%04x Index=%04x onoff=%02x", __func__,
414 pid, index, onoff);
415
416 if (onoff) {
417 mutex_lock(&d->i2c_mutex);
418 ret |= lme2510_enable_pid(d, index, pid);
419 mutex_unlock(&d->i2c_mutex);
420 }
421
422
423 return ret;
424}
425
426
427static int lme2510_return_status(struct dvb_usb_device *d)
428{
429 int ret = 0;
430 u8 *data;
431
432 data = kzalloc(10, GFP_KERNEL);
433 if (!data)
434 return -ENOMEM;
435
436 ret |= usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
437 0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
438 info("Firmware Status: %x (%x)", ret , data[2]);
439
440 ret = (ret < 0) ? -ENODEV : data[2];
441 kfree(data);
442 return ret;
443}
444
445static int lme2510_msg(struct dvb_usb_device *d,
446 u8 *wbuf, int wlen, u8 *rbuf, int rlen)
447{
448 int ret = 0;
449 struct lme2510_state *st = d->priv;
450
451 if (st->i2c_talk_onoff == 1) {
452
453 ret = lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
454
455 switch (st->tuner_config) {
456 case TUNER_LG:
457 if (wbuf[2] == 0x1c) {
458 if (wbuf[3] == 0x0e) {
459 st->signal_lock = rbuf[1];
460 if ((st->stream_on & 1) &&
461 (st->signal_lock & 0x10)) {
462 lme2510_stream_restart(d);
463 st->i2c_talk_onoff = 0;
464 }
465 msleep(80);
466 }
467 }
468 break;
469 case TUNER_S7395:
470 if (wbuf[2] == 0xd0) {
471 if (wbuf[3] == 0x24) {
472 st->signal_lock = rbuf[1];
473 if ((st->stream_on & 1) &&
474 (st->signal_lock & 0x8)) {
475 lme2510_stream_restart(d);
476 st->i2c_talk_onoff = 0;
477 }
478 }
479 }
480 break;
481 case TUNER_S0194:
482 if (wbuf[2] == 0xd0) {
483 if (wbuf[3] == 0x1b) {
484 st->signal_lock = rbuf[1];
485 if ((st->stream_on & 1) &&
486 (st->signal_lock & 0x8)) {
487 lme2510_stream_restart(d);
488 st->i2c_talk_onoff = 0;
489 }
490 }
491 }
492 break;
493 case TUNER_RS2000:
494 default:
495 break;
496 }
497 } else {
498 /* TODO rewrite this section */
499 switch (st->tuner_config) {
500 case TUNER_LG:
501 switch (wbuf[3]) {
502 case 0x0e:
503 rbuf[0] = 0x55;
504 rbuf[1] = st->signal_lock;
505 break;
506 case 0x43:
507 rbuf[0] = 0x55;
508 rbuf[1] = st->signal_level;
509 break;
510 case 0x1c:
511 rbuf[0] = 0x55;
512 rbuf[1] = st->signal_sn;
513 break;
514 case 0x15:
515 case 0x16:
516 case 0x17:
517 case 0x18:
518 rbuf[0] = 0x55;
519 rbuf[1] = 0x00;
520 break;
521 default:
522 lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
523 st->i2c_talk_onoff = 1;
524 break;
525 }
526 break;
527 case TUNER_S7395:
528 switch (wbuf[3]) {
529 case 0x10:
530 rbuf[0] = 0x55;
531 rbuf[1] = (st->signal_level & 0x80)
532 ? 0 : (st->signal_level * 2);
533 break;
534 case 0x2d:
535 rbuf[0] = 0x55;
536 rbuf[1] = st->signal_sn;
537 break;
538 case 0x24:
539 rbuf[0] = 0x55;
540 rbuf[1] = st->signal_lock;
541 break;
542 case 0x2e:
543 case 0x26:
544 case 0x27:
545 rbuf[0] = 0x55;
546 rbuf[1] = 0x00;
547 break;
548 default:
549 lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
550 st->i2c_talk_onoff = 1;
551 break;
552 }
553 break;
554 case TUNER_S0194:
555 switch (wbuf[3]) {
556 case 0x18:
557 rbuf[0] = 0x55;
558 rbuf[1] = (st->signal_level & 0x80)
559 ? 0 : (st->signal_level * 2);
560 break;
561 case 0x24:
562 rbuf[0] = 0x55;
563 rbuf[1] = st->signal_sn;
564 break;
565 case 0x1b:
566 rbuf[0] = 0x55;
567 rbuf[1] = st->signal_lock;
568 break;
569 case 0x19:
570 case 0x25:
571 case 0x1e:
572 case 0x1d:
573 rbuf[0] = 0x55;
574 rbuf[1] = 0x00;
575 break;
576 default:
577 lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
578 st->i2c_talk_onoff = 1;
579 break;
580 }
581 break;
582 case TUNER_RS2000:
583 switch (wbuf[3]) {
584 case 0x8c:
585 rbuf[0] = 0x55;
586 rbuf[1] = 0xff;
587 if (st->last_key == st->time_key) {
588 st->key_timeout++;
589 if (st->key_timeout > 5)
590 rbuf[1] = 0;
591 } else
592 st->key_timeout = 0;
593 st->last_key = st->time_key;
594 break;
595 default:
596 lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
597 st->i2c_talk_onoff = 1;
598 break;
599 }
600 default:
601 break;
602 }
603
604 deb_info(4, "I2C From Interrupt Message out(%02x) in(%02x)",
605 wbuf[3], rbuf[1]);
606
607 }
608
609 return ret;
610}
611
612
613static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
614 int num)
615{
616 struct dvb_usb_device *d = i2c_get_adapdata(adap);
617 struct lme2510_state *st = d->priv;
618 static u8 obuf[64], ibuf[64];
619 int i, read, read_o;
620 u16 len;
621 u8 gate = st->i2c_gate;
622
623 mutex_lock(&d->i2c_mutex);
624
625 if (gate == 0)
626 gate = 5;
627
628 for (i = 0; i < num; i++) {
629 read_o = 1 & (msg[i].flags & I2C_M_RD);
630 read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
631 read |= read_o;
632 gate = (msg[i].addr == st->i2c_tuner_addr)
633 ? (read) ? st->i2c_tuner_gate_r
634 : st->i2c_tuner_gate_w
635 : st->i2c_gate;
636 obuf[0] = gate | (read << 7);
637
638 if (gate == 5)
639 obuf[1] = (read) ? 2 : msg[i].len + 1;
640 else
641 obuf[1] = msg[i].len + read + 1;
642
643 obuf[2] = msg[i].addr;
644 if (read) {
645 if (read_o)
646 len = 3;
647 else {
648 memcpy(&obuf[3], msg[i].buf, msg[i].len);
649 obuf[msg[i].len+3] = msg[i+1].len;
650 len = msg[i].len+4;
651 }
652 } else {
653 memcpy(&obuf[3], msg[i].buf, msg[i].len);
654 len = msg[i].len+3;
655 }
656
657 if (lme2510_msg(d, obuf, len, ibuf, 64) < 0) {
658 deb_info(1, "i2c transfer failed.");
659 mutex_unlock(&d->i2c_mutex);
660 return -EAGAIN;
661 }
662
663 if (read) {
664 if (read_o)
665 memcpy(msg[i].buf, &ibuf[1], msg[i].len);
666 else {
667 memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
668 i++;
669 }
670 }
671 }
672
673 mutex_unlock(&d->i2c_mutex);
674 return i;
675}
676
677static u32 lme2510_i2c_func(struct i2c_adapter *adapter)
678{
679 return I2C_FUNC_I2C;
680}
681
682static struct i2c_algorithm lme2510_i2c_algo = {
683 .master_xfer = lme2510_i2c_xfer,
684 .functionality = lme2510_i2c_func,
685};
686
687static int lme2510_streaming_ctrl(struct dvb_frontend *fe, int onoff)
688{
689 struct dvb_usb_adapter *adap = fe_to_adap(fe);
690 struct dvb_usb_device *d = adap_to_d(adap);
691 struct lme2510_state *st = adap_to_priv(adap);
692 static u8 clear_reg_3[] = LME_ALL_PIDS;
693 static u8 rbuf[1];
694 int ret = 0, rlen = sizeof(rbuf);
695
696 deb_info(1, "STM (%02x)", onoff);
697
698 /* Streaming is started by FE_HAS_LOCK */
699 if (onoff == 1)
700 st->stream_on = 1;
701 else {
702 deb_info(1, "STM Steam Off");
703 /* mutex is here only to avoid collision with I2C */
704 mutex_lock(&d->i2c_mutex);
705
706 ret = lme2510_usb_talk(d, clear_reg_3,
707 sizeof(clear_reg_3), rbuf, rlen);
708 st->stream_on = 0;
709 st->i2c_talk_onoff = 1;
710
711 mutex_unlock(&d->i2c_mutex);
712 }
713
714 return (ret < 0) ? -ENODEV : 0;
715}
716
717static u8 check_sum(u8 *p, u8 len)
718{
719 u8 sum = 0;
720 while (len--)
721 sum += *p++;
722 return sum;
723}
724
725static int lme2510_download_firmware(struct dvb_usb_device *d,
726 const struct firmware *fw)
727{
728 int ret = 0;
729 u8 *data;
730 u16 j, wlen, len_in, start, end;
731 u8 packet_size, dlen, i;
732 u8 *fw_data;
733
734 packet_size = 0x31;
735 len_in = 1;
736
737 data = kzalloc(128, GFP_KERNEL);
738 if (!data) {
739 info("FRM Could not start Firmware Download"\
740 "(Buffer allocation failed)");
741 return -ENOMEM;
742 }
743
744 info("FRM Starting Firmware Download");
745
746 for (i = 1; i < 3; i++) {
747 start = (i == 1) ? 0 : 512;
748 end = (i == 1) ? 512 : fw->size;
749 for (j = start; j < end; j += (packet_size+1)) {
750 fw_data = (u8 *)(fw->data + j);
751 if ((end - j) > packet_size) {
752 data[0] = i;
753 dlen = packet_size;
754 } else {
755 data[0] = i | 0x80;
756 dlen = (u8)(end - j)-1;
757 }
758 data[1] = dlen;
759 memcpy(&data[2], fw_data, dlen+1);
760 wlen = (u8) dlen + 4;
761 data[wlen-1] = check_sum(fw_data, dlen+1);
762 deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3],
763 data[dlen+2], data[dlen+3]);
764 lme2510_usb_talk(d, data, wlen, data, len_in);
765 ret |= (data[0] == 0x88) ? 0 : -1;
766 }
767 }
768
769 data[0] = 0x8a;
770 len_in = 1;
771 msleep(2000);
772 lme2510_usb_talk(d, data, len_in, data, len_in);
773 msleep(400);
774
775 if (ret < 0)
776 info("FRM Firmware Download Failed (%04x)" , ret);
777 else
778 info("FRM Firmware Download Completed - Resetting Device");
779
780 kfree(data);
781 return RECONNECTS_USB;
782}
783
784static void lme_coldreset(struct dvb_usb_device *d)
785{
786 u8 data[1] = {0};
787 data[0] = 0x0a;
788 info("FRM Firmware Cold Reset");
789
790 lme2510_usb_talk(d, data, sizeof(data), data, sizeof(data));
791
792 return;
793}
794
795static const char fw_c_s7395[] = LME2510_C_S7395;
796static const char fw_c_lg[] = LME2510_C_LG;
797static const char fw_c_s0194[] = LME2510_C_S0194;
798static const char fw_c_rs2000[] = LME2510_C_RS2000;
799static const char fw_lg[] = LME2510_LG;
800static const char fw_s0194[] = LME2510_S0194;
801
802const char *lme_firmware_switch(struct dvb_usb_device *d, int cold)
803{
804 struct lme2510_state *st = d->priv;
805 struct usb_device *udev = d->udev;
806 const struct firmware *fw = NULL;
807 const char *fw_lme;
808 int ret = 0;
809
810 cold = (cold > 0) ? (cold & 1) : 0;
811
812 switch (le16_to_cpu(udev->descriptor.idProduct)) {
813 case 0x1122:
814 switch (st->dvb_usb_lme2510_firmware) {
815 default:
816 st->dvb_usb_lme2510_firmware = TUNER_S0194;
817 case TUNER_S0194:
818 fw_lme = fw_s0194;
819 ret = request_firmware(&fw, fw_lme, &udev->dev);
820 if (ret == 0) {
821 cold = 0;
822 break;
823 }
824 st->dvb_usb_lme2510_firmware = TUNER_LG;
825 case TUNER_LG:
826 fw_lme = fw_lg;
827 ret = request_firmware(&fw, fw_lme, &udev->dev);
828 if (ret == 0)
829 break;
830 st->dvb_usb_lme2510_firmware = TUNER_DEFAULT;
831 break;
832 }
833 break;
834 case 0x1120:
835 switch (st->dvb_usb_lme2510_firmware) {
836 default:
837 st->dvb_usb_lme2510_firmware = TUNER_S7395;
838 case TUNER_S7395:
839 fw_lme = fw_c_s7395;
840 ret = request_firmware(&fw, fw_lme, &udev->dev);
841 if (ret == 0) {
842 cold = 0;
843 break;
844 }
845 st->dvb_usb_lme2510_firmware = TUNER_LG;
846 case TUNER_LG:
847 fw_lme = fw_c_lg;
848 ret = request_firmware(&fw, fw_lme, &udev->dev);
849 if (ret == 0)
850 break;
851 st->dvb_usb_lme2510_firmware = TUNER_S0194;
852 case TUNER_S0194:
853 fw_lme = fw_c_s0194;
854 ret = request_firmware(&fw, fw_lme, &udev->dev);
855 if (ret == 0)
856 break;
857 st->dvb_usb_lme2510_firmware = TUNER_DEFAULT;
858 cold = 0;
859 break;
860 }
861 break;
862 case 0x22f0:
863 fw_lme = fw_c_rs2000;
864 st->dvb_usb_lme2510_firmware = TUNER_RS2000;
865 break;
866 default:
867 fw_lme = fw_c_s7395;
868 }
869
870 release_firmware(fw);
871
872 if (cold) {
873 dvb_usb_lme2510_firmware = st->dvb_usb_lme2510_firmware;
874 info("FRM Changing to %s firmware", fw_lme);
875 lme_coldreset(d);
876 return NULL;
877 }
878
879 return fw_lme;
880}
881
882static int lme2510_kill_urb(struct usb_data_stream *stream)
883{
884 int i;
885
886 for (i = 0; i < stream->urbs_submitted; i++) {
887 deb_info(3, "killing URB no. %d.", i);
888 /* stop the URB */
889 usb_kill_urb(stream->urb_list[i]);
890 }
891 stream->urbs_submitted = 0;
892
893 return 0;
894}
895
896static struct tda10086_config tda10086_config = {
897 .demod_address = 0x1c,
898 .invert = 0,
899 .diseqc_tone = 1,
900 .xtal_freq = TDA10086_XTAL_16M,
901};
902
903static struct stv0288_config lme_config = {
904 .demod_address = 0xd0,
905 .min_delay_ms = 15,
906 .inittab = s7395_inittab,
907};
908
909static struct ix2505v_config lme_tuner = {
910 .tuner_address = 0xc0,
911 .min_delay_ms = 100,
912 .tuner_gain = 0x0,
913 .tuner_chargepump = 0x3,
914};
915
916static struct stv0299_config sharp_z0194_config = {
917 .demod_address = 0xd0,
918 .inittab = sharp_z0194a_inittab,
919 .mclk = 88000000UL,
920 .invert = 0,
921 .skip_reinit = 0,
922 .lock_output = STV0299_LOCKOUTPUT_1,
923 .volt13_op0_op1 = STV0299_VOLT13_OP1,
924 .min_delay_ms = 100,
925 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
926};
927
928static int dm04_rs2000_set_ts_param(struct dvb_frontend *fe,
929 int caller)
930{
931 struct dvb_usb_adapter *adap = fe_to_adap(fe);
932 struct dvb_usb_device *d = adap_to_d(adap);
933 struct lme2510_state *st = d->priv;
934
935 mutex_lock(&d->i2c_mutex);
936 if ((st->i2c_talk_onoff == 1) && (st->stream_on & 1)) {
937 st->i2c_talk_onoff = 0;
938 lme2510_stream_restart(d);
939 }
940 mutex_unlock(&d->i2c_mutex);
941
942 return 0;
943}
944
945static struct m88rs2000_config m88rs2000_config = {
946 .demod_addr = 0xd0,
947 .tuner_addr = 0xc0,
948 .set_ts_params = dm04_rs2000_set_ts_param,
949};
950
951static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
952 fe_sec_voltage_t voltage)
953{
954 struct dvb_usb_device *d = fe_to_d(fe);
955 struct lme2510_state *st = fe_to_priv(fe);
956 static u8 voltage_low[] = LME_VOLTAGE_L;
957 static u8 voltage_high[] = LME_VOLTAGE_H;
958 static u8 rbuf[1];
959 int ret = 0, len = 3, rlen = 1;
960
961 mutex_lock(&d->i2c_mutex);
962
963 switch (voltage) {
964 case SEC_VOLTAGE_18:
965 ret |= lme2510_usb_talk(d,
966 voltage_high, len, rbuf, rlen);
967 break;
968
969 case SEC_VOLTAGE_OFF:
970 case SEC_VOLTAGE_13:
971 default:
972 ret |= lme2510_usb_talk(d,
973 voltage_low, len, rbuf, rlen);
974 break;
975 }
976
977 mutex_unlock(&d->i2c_mutex);
978
979 if (st->tuner_config == TUNER_RS2000)
980 if (st->fe_set_voltage)
981 st->fe_set_voltage(fe, voltage);
982
983
984 return (ret < 0) ? -ENODEV : 0;
985}
986
987static int dm04_rs2000_read_signal_strength(struct dvb_frontend *fe,
988 u16 *strength)
989{
990 struct lme2510_state *st = fe_to_priv(fe);
991
992 *strength = (u16)((u32)st->signal_level * 0xffff / 0xff);
993
994 return 0;
995}
996
997static int dm04_rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
998{
999 struct lme2510_state *st = fe_to_priv(fe);
1000
1001 *snr = (u16)((u32)st->signal_sn * 0xffff / 0x7f);
1002
1003 return 0;
1004}
1005
1006static int dm04_read_ber(struct dvb_frontend *fe, u32 *ber)
1007{
1008 *ber = 0;
1009
1010 return 0;
1011}
1012
1013static int dm04_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
1014{
1015 *ucblocks = 0;
1016
1017 return 0;
1018}
1019
1020static int lme_name(struct dvb_usb_adapter *adap)
1021{
1022 struct dvb_usb_device *d = adap_to_d(adap);
1023 struct lme2510_state *st = adap_to_priv(adap);
1024 const char *desc = d->name;
1025 char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
1026 " SHARP:BS2F7HZ0194", " RS2000"};
1027 char *name = adap->fe[0]->ops.info.name;
1028
1029 strlcpy(name, desc, 128);
1030 strlcat(name, fe_name[st->tuner_config], 128);
1031
1032 return 0;
1033}
1034
1035static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
1036{
1037 struct dvb_usb_device *d = adap_to_d(adap);
1038 struct lme2510_state *st = d->priv;
1039 int ret = 0;
1040
1041 st->i2c_talk_onoff = 1;
1042 switch (le16_to_cpu(d->udev->descriptor.idProduct)) {
1043 case 0x1122:
1044 case 0x1120:
1045 st->i2c_gate = 4;
1046 adap->fe[0] = dvb_attach(tda10086_attach,
1047 &tda10086_config, &d->i2c_adap);
1048 if (adap->fe[0]) {
1049 info("TUN Found Frontend TDA10086");
1050 st->i2c_tuner_gate_w = 4;
1051 st->i2c_tuner_gate_r = 4;
1052 st->i2c_tuner_addr = 0xc0;
1053 st->tuner_config = TUNER_LG;
1054 if (st->dvb_usb_lme2510_firmware != TUNER_LG) {
1055 st->dvb_usb_lme2510_firmware = TUNER_LG;
1056 ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
1057 }
1058 break;
1059 }
1060
1061 st->i2c_gate = 4;
1062 adap->fe[0] = dvb_attach(stv0299_attach,
1063 &sharp_z0194_config, &d->i2c_adap);
1064 if (adap->fe[0]) {
1065 info("FE Found Stv0299");
1066 st->i2c_tuner_gate_w = 4;
1067 st->i2c_tuner_gate_r = 5;
1068 st->i2c_tuner_addr = 0xc0;
1069 st->tuner_config = TUNER_S0194;
1070 if (st->dvb_usb_lme2510_firmware != TUNER_S0194) {
1071 st->dvb_usb_lme2510_firmware = TUNER_S0194;
1072 ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
1073 }
1074 break;
1075 }
1076
1077 st->i2c_gate = 5;
1078 adap->fe[0] = dvb_attach(stv0288_attach, &lme_config,
1079 &d->i2c_adap);
1080
1081 if (adap->fe[0]) {
1082 info("FE Found Stv0288");
1083 st->i2c_tuner_gate_w = 4;
1084 st->i2c_tuner_gate_r = 5;
1085 st->i2c_tuner_addr = 0xc0;
1086 st->tuner_config = TUNER_S7395;
1087 if (st->dvb_usb_lme2510_firmware != TUNER_S7395) {
1088 st->dvb_usb_lme2510_firmware = TUNER_S7395;
1089 ret = lme_firmware_switch(d, 1) ? 0 : -ENODEV;
1090 }
1091 break;
1092 }
1093 case 0x22f0:
1094 st->i2c_gate = 5;
1095 adap->fe[0] = dvb_attach(m88rs2000_attach,
1096 &m88rs2000_config, &d->i2c_adap);
1097
1098 if (adap->fe[0]) {
1099 info("FE Found M88RS2000");
1100 st->i2c_tuner_gate_w = 5;
1101 st->i2c_tuner_gate_r = 5;
1102 st->i2c_tuner_addr = 0xc0;
1103 st->tuner_config = TUNER_RS2000;
1104 st->fe_set_voltage =
1105 adap->fe[0]->ops.set_voltage;
1106
1107 adap->fe[0]->ops.read_signal_strength =
1108 dm04_rs2000_read_signal_strength;
1109 adap->fe[0]->ops.read_snr =
1110 dm04_rs2000_read_snr;
1111 adap->fe[0]->ops.read_ber =
1112 dm04_read_ber;
1113 adap->fe[0]->ops.read_ucblocks =
1114 dm04_read_ucblocks;
1115 }
1116 break;
1117 }
1118
1119 if (adap->fe[0] == NULL) {
1120 info("DM04/QQBOX Not Powered up or not Supported");
1121 return -ENODEV;
1122 }
1123
1124 if (ret) {
1125 if (adap->fe[0]) {
1126 dvb_frontend_detach(adap->fe[0]);
1127 adap->fe[0] = NULL;
1128 }
1129 d->rc_map = NULL;
1130 return -ENODEV;
1131 }
1132
1133 adap->fe[0]->ops.set_voltage = dm04_lme2510_set_voltage;
1134 ret = lme_name(adap);
1135 return ret;
1136}
1137
1138static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
1139{
1140 struct dvb_usb_device *d = adap_to_d(adap);
1141 struct lme2510_state *st = adap_to_priv(adap);
1142 char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA", "RS2000"};
1143 int ret = 0;
1144
1145 switch (st->tuner_config) {
1146 case TUNER_LG:
1147 if (dvb_attach(tda826x_attach, adap->fe[0], 0xc0,
1148 &d->i2c_adap, 1))
1149 ret = st->tuner_config;
1150 break;
1151 case TUNER_S7395:
1152 if (dvb_attach(ix2505v_attach , adap->fe[0], &lme_tuner,
1153 &d->i2c_adap))
1154 ret = st->tuner_config;
1155 break;
1156 case TUNER_S0194:
1157 if (dvb_attach(dvb_pll_attach , adap->fe[0], 0xc0,
1158 &d->i2c_adap, DVB_PLL_OPERA1))
1159 ret = st->tuner_config;
1160 break;
1161 case TUNER_RS2000:
1162 ret = st->tuner_config;
1163 break;
1164 default:
1165 break;
1166 }
1167
1168 if (ret)
1169 info("TUN Found %s tuner", tun_msg[ret]);
1170 else {
1171 info("TUN No tuner found --- resetting device");
1172 lme_coldreset(d);
1173 return -ENODEV;
1174 }
1175
1176 /* Start the Interrupt*/
1177 ret = lme2510_int_read(adap);
1178 if (ret < 0) {
1179 info("INT Unable to start Interrupt Service");
1180 return -ENODEV;
1181 }
1182
1183 return ret;
1184}
1185
1186static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
1187{
1188 struct lme2510_state *st = d->priv;
1189 static u8 lnb_on[] = LNB_ON;
1190 static u8 lnb_off[] = LNB_OFF;
1191 static u8 rbuf[1];
1192 int ret = 0, len = 3, rlen = 1;
1193
1194 mutex_lock(&d->i2c_mutex);
1195
1196 if (onoff)
1197 ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
1198 else
1199 ret = lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
1200
1201 st->i2c_talk_onoff = 1;
1202
1203 mutex_unlock(&d->i2c_mutex);
1204
1205 return ret;
1206}
1207
1208static int lme2510_get_adapter_count(struct dvb_usb_device *d)
1209{
1210 return 1;
1211}
1212
1213static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
1214{
1215 struct lme2510_state *st = d->priv;
1216
1217 usb_reset_configuration(d->udev);
1218
1219 usb_set_interface(d->udev,
1220 d->intf->cur_altsetting->desc.bInterfaceNumber, 1);
1221
1222 st->dvb_usb_lme2510_firmware = dvb_usb_lme2510_firmware;
1223
1224 if (lme2510_return_status(d) == 0x44) {
1225 *name = lme_firmware_switch(d, 0);
1226 return COLD;
1227 }
1228
1229 return 0;
1230}
1231
1232static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
1233 struct usb_data_stream_properties *stream)
1234{
1235 struct dvb_usb_adapter *adap = fe_to_adap(fe);
1236 struct dvb_usb_device *d = adap_to_d(adap);
1237
1238 if (adap == NULL)
1239 return 0;
1240 /* Turn PID filter on the fly by module option */
1241 if (pid_filter == 2) {
1242 adap->pid_filtering = 1;
1243 adap->max_feed_count = 15;
1244 }
1245
1246 if (!(le16_to_cpu(d->udev->descriptor.idProduct)
1247 == 0x1122))
1248 stream->endpoint = 0x8;
1249
1250 return 0;
1251}
1252
1253static int lme2510_get_rc_config(struct dvb_usb_device *d,
1254 struct dvb_usb_rc *rc)
1255{
1256 rc->allowed_protos = RC_TYPE_NEC;
1257 return 0;
1258}
1259
1260static void *lme2510_exit_int(struct dvb_usb_device *d)
1261{
1262 struct lme2510_state *st = d->priv;
1263 struct dvb_usb_adapter *adap = &d->adapter[0];
1264 void *buffer = NULL;
1265
1266 if (adap != NULL) {
1267 lme2510_kill_urb(&adap->stream);
1268 }
1269
1270 if (st->usb_buffer != NULL) {
1271 st->i2c_talk_onoff = 1;
1272 st->signal_lock = 0;
1273 st->signal_level = 0;
1274 st->signal_sn = 0;
1275 buffer = st->usb_buffer;
1276 }
1277
1278 if (st->lme_urb != NULL) {
1279 usb_kill_urb(st->lme_urb);
1280 usb_free_coherent(d->udev, 128, st->buffer,
1281 st->lme_urb->transfer_dma);
1282 info("Interrupt Service Stopped");
1283 }
1284
1285 return buffer;
1286}
1287
1288static void lme2510_exit(struct dvb_usb_device *d)
1289{
1290 void *usb_buffer;
1291
1292 if (d != NULL) {
1293 usb_buffer = lme2510_exit_int(d);
1294 if (usb_buffer != NULL)
1295 kfree(usb_buffer);
1296 }
1297}
1298
1299static struct dvb_usb_device_properties lme2510_props = {
1300 .driver_name = KBUILD_MODNAME,
1301 .owner = THIS_MODULE,
1302 .bInterfaceNumber = 0,
1303 .adapter_nr = adapter_nr,
1304 .size_of_priv = sizeof(struct lme2510_state),
1305
1306 .download_firmware = lme2510_download_firmware,
1307
1308 .power_ctrl = lme2510_powerup,
1309 .identify_state = lme2510_identify_state,
1310 .i2c_algo = &lme2510_i2c_algo,
1311
1312 .frontend_attach = dm04_lme2510_frontend_attach,
1313 .tuner_attach = dm04_lme2510_tuner,
1314 .get_stream_config = lme2510_get_stream_config,
1315 .get_adapter_count = lme2510_get_adapter_count,
1316 .streaming_ctrl = lme2510_streaming_ctrl,
1317
1318 .get_rc_config = lme2510_get_rc_config,
1319
1320 .exit = lme2510_exit,
1321 .adapter = {
1322 {
1323 .caps = DVB_USB_ADAP_HAS_PID_FILTER|
1324 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1325 .pid_filter_count = 15,
1326 .pid_filter = lme2510_pid_filter,
1327 .pid_filter_ctrl = lme2510_pid_filter_ctrl,
1328 .stream =
1329 DVB_USB_STREAM_BULK(0x86, 10, 4096),
1330 },
1331 {
1332 }
1333 },
1334};
1335
1336static const struct usb_device_id lme2510_id_table[] = {
1337 { DVB_USB_DEVICE(0x3344, 0x1122, &lme2510_props,
1338 "DM04_LME2510_DVB-S", RC_MAP_LME2510) },
1339 { DVB_USB_DEVICE(0x3344, 0x1120, &lme2510_props,
1340 "DM04_LME2510C_DVB-S", RC_MAP_LME2510) },
1341 { DVB_USB_DEVICE(0x3344, 0x22f0, &lme2510_props,
1342 "DM04_LME2510C_DVB-S RS2000", RC_MAP_LME2510) },
1343 {} /* Terminating entry */
1344};
1345
1346MODULE_DEVICE_TABLE(usb, lme2510_id_table);
1347
1348static struct usb_driver lme2510_driver = {
1349 .name = KBUILD_MODNAME,
1350 .probe = dvb_usbv2_probe,
1351 .disconnect = dvb_usbv2_disconnect,
1352 .id_table = lme2510_id_table,
1353 .no_dynamic_id = 1,
1354 .soft_unbind = 1,
1355};
1356
1357module_usb_driver(lme2510_driver);
1358
1359MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
1360MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
1361MODULE_VERSION("2.06");
1362MODULE_LICENSE("GPL");
1363MODULE_FIRMWARE(LME2510_C_S7395);
1364MODULE_FIRMWARE(LME2510_C_LG);
1365MODULE_FIRMWARE(LME2510_C_S0194);
1366MODULE_FIRMWARE(LME2510_C_RS2000);
1367MODULE_FIRMWARE(LME2510_LG);
1368MODULE_FIRMWARE(LME2510_S0194);
1369
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.h b/drivers/media/usb/dvb-usb-v2/lmedm04.h
new file mode 100644
index 000000000000..e9c207205c2f
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.h
@@ -0,0 +1,175 @@
1/* DVB USB compliant linux driver for
2 *
3 * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395
4 * LME2510C + LG TDQY-P001F
5 * LME2510 + LG TDQY-P001F
6 *
7 * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
8 * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
9 *
10 * MVB001F (LME2510+LGTDQT-P001F)
11 * LG TDQY - P001F =(TDA8263 + TDA10086H)
12 *
13 * MVB0001F (LME2510C+LGTDQT-P001F)
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the Free
17 * Software Foundation, version 2.
18 * *
19 * see Documentation/dvb/README.dvb-usb for more information
20 */
21#ifndef _DVB_USB_LME2510_H_
22#define _DVB_USB_LME2510_H_
23
24/* Streamer & PID
25 *
26 * Note: These commands do not actually stop the streaming
27 * but form some kind of packet filtering/stream count
28 * or tuning related functions.
29 * 06 XX
30 * offset 1 = 00 Enable Streaming
31 *
32 *
33 * PID
34 * 03 XX XX ----> reg number ---> setting....20 XX
35 * offset 1 = length
36 * offset 2 = start of data
37 * end byte -1 = 20
38 * end byte = clear pid always a0, other wise 9c, 9a ??
39 *
40*/
41#define LME_ST_ON_W {0x06, 0x00}
42#define LME_CLEAR_PID {0x03, 0x02, 0x20, 0xa0}
43#define LME_ZERO_PID {0x03, 0x06, 0x00, 0x00, 0x01, 0x00, 0x20, 0x9c}
44#define LME_ALL_PIDS {0x03, 0x06, 0x00, 0xff, 0x01, 0x1f, 0x20, 0x81}
45
46/* LNB Voltage
47 * 07 XX XX
48 * offset 1 = 01
49 * offset 2 = 00=Voltage low 01=Voltage high
50 *
51 * LNB Power
52 * 03 01 XX
53 * offset 2 = 00=ON 01=OFF
54 */
55
56#define LME_VOLTAGE_L {0x07, 0x01, 0x00}
57#define LME_VOLTAGE_H {0x07, 0x01, 0x01}
58#define LNB_ON {0x3a, 0x01, 0x00}
59#define LNB_OFF {0x3a, 0x01, 0x01}
60
61/* Initial stv0288 settings for 7395 Frontend */
62static u8 s7395_inittab[] = {
63 0x01, 0x15,
64 0x02, 0x20,
65 0x03, 0xa0,
66 0x04, 0xa0,
67 0x05, 0x12,
68 0x06, 0x00,
69 0x09, 0x00,
70 0x0a, 0x04,
71 0x0b, 0x00,
72 0x0c, 0x00,
73 0x0d, 0x00,
74 0x0e, 0xc1,
75 0x0f, 0x54,
76 0x11, 0x7a,
77 0x12, 0x03,
78 0x13, 0x48,
79 0x14, 0x84,
80 0x15, 0xc5,
81 0x16, 0xb8,
82 0x17, 0x9c,
83 0x18, 0x00,
84 0x19, 0xa6,
85 0x1a, 0x88,
86 0x1b, 0x8f,
87 0x1c, 0xf0,
88 0x20, 0x0b,
89 0x21, 0x54,
90 0x22, 0xff,
91 0x23, 0x01,
92 0x28, 0x46,
93 0x29, 0x66,
94 0x2a, 0x90,
95 0x2b, 0xfa,
96 0x2c, 0xd9,
97 0x30, 0x0,
98 0x31, 0x1e,
99 0x32, 0x14,
100 0x33, 0x0f,
101 0x34, 0x09,
102 0x35, 0x0c,
103 0x36, 0x05,
104 0x37, 0x2f,
105 0x38, 0x16,
106 0x39, 0xbd,
107 0x3a, 0x0,
108 0x3b, 0x13,
109 0x3c, 0x11,
110 0x3d, 0x30,
111 0x40, 0x63,
112 0x41, 0x04,
113 0x42, 0x20,
114 0x43, 0x00,
115 0x44, 0x00,
116 0x45, 0x00,
117 0x46, 0x00,
118 0x47, 0x00,
119 0x4a, 0x00,
120 0x50, 0x10,
121 0x51, 0x36,
122 0x52, 0x21,
123 0x53, 0x94,
124 0x54, 0xb2,
125 0x55, 0x29,
126 0x56, 0x64,
127 0x57, 0x2b,
128 0x58, 0x54,
129 0x59, 0x86,
130 0x5a, 0x00,
131 0x5b, 0x9b,
132 0x5c, 0x08,
133 0x5d, 0x7f,
134 0x5e, 0xff,
135 0x5f, 0x8d,
136 0x70, 0x0,
137 0x71, 0x0,
138 0x72, 0x0,
139 0x74, 0x0,
140 0x75, 0x0,
141 0x76, 0x0,
142 0x81, 0x0,
143 0x82, 0x3f,
144 0x83, 0x3f,
145 0x84, 0x0,
146 0x85, 0x0,
147 0x88, 0x0,
148 0x89, 0x0,
149 0x8a, 0x0,
150 0x8b, 0x0,
151 0x8c, 0x0,
152 0x90, 0x0,
153 0x91, 0x0,
154 0x92, 0x0,
155 0x93, 0x0,
156 0x94, 0x1c,
157 0x97, 0x0,
158 0xa0, 0x48,
159 0xa1, 0x0,
160 0xb0, 0xb8,
161 0xb1, 0x3a,
162 0xb2, 0x10,
163 0xb3, 0x82,
164 0xb4, 0x80,
165 0xb5, 0x82,
166 0xb6, 0x82,
167 0xb7, 0x82,
168 0xb8, 0x20,
169 0xb9, 0x0,
170 0xf0, 0x0,
171 0xf1, 0x0,
172 0xf2, 0xc0,
173 0xff, 0xff,
174};
175#endif
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
new file mode 100644
index 000000000000..d83df4bb72d3
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
@@ -0,0 +1,612 @@
1/*
2 * mxl111sf-demod.c - driver for the MaxLinear MXL111SF DVB-T demodulator
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "mxl111sf-demod.h"
22#include "mxl111sf-reg.h"
23
24/* debug */
25static int mxl111sf_demod_debug;
26module_param_named(debug, mxl111sf_demod_debug, int, 0644);
27MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
28
29#define mxl_dbg(fmt, arg...) \
30 if (mxl111sf_demod_debug) \
31 mxl_printk(KERN_DEBUG, fmt, ##arg)
32
33/* ------------------------------------------------------------------------ */
34
35struct mxl111sf_demod_state {
36 struct mxl111sf_state *mxl_state;
37
38 struct mxl111sf_demod_config *cfg;
39
40 struct dvb_frontend fe;
41};
42
43/* ------------------------------------------------------------------------ */
44
45static int mxl111sf_demod_read_reg(struct mxl111sf_demod_state *state,
46 u8 addr, u8 *data)
47{
48 return (state->cfg->read_reg) ?
49 state->cfg->read_reg(state->mxl_state, addr, data) :
50 -EINVAL;
51}
52
53static int mxl111sf_demod_write_reg(struct mxl111sf_demod_state *state,
54 u8 addr, u8 data)
55{
56 return (state->cfg->write_reg) ?
57 state->cfg->write_reg(state->mxl_state, addr, data) :
58 -EINVAL;
59}
60
61static
62int mxl111sf_demod_program_regs(struct mxl111sf_demod_state *state,
63 struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
64{
65 return (state->cfg->program_regs) ?
66 state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
67 -EINVAL;
68}
69
70/* ------------------------------------------------------------------------ */
71/* TPS */
72
73static
74int mxl1x1sf_demod_get_tps_code_rate(struct mxl111sf_demod_state *state,
75 fe_code_rate_t *code_rate)
76{
77 u8 val;
78 int ret = mxl111sf_demod_read_reg(state, V6_CODE_RATE_TPS_REG, &val);
79 /* bit<2:0> - 000:1/2, 001:2/3, 010:3/4, 011:5/6, 100:7/8 */
80 if (mxl_fail(ret))
81 goto fail;
82
83 switch (val & V6_CODE_RATE_TPS_MASK) {
84 case 0:
85 *code_rate = FEC_1_2;
86 break;
87 case 1:
88 *code_rate = FEC_2_3;
89 break;
90 case 2:
91 *code_rate = FEC_3_4;
92 break;
93 case 3:
94 *code_rate = FEC_5_6;
95 break;
96 case 4:
97 *code_rate = FEC_7_8;
98 break;
99 }
100fail:
101 return ret;
102}
103
104static
105int mxl1x1sf_demod_get_tps_modulation(struct mxl111sf_demod_state *state,
106 fe_modulation_t *modulation)
107{
108 u8 val;
109 int ret = mxl111sf_demod_read_reg(state, V6_MODORDER_TPS_REG, &val);
110 /* Constellation, 00 : QPSK, 01 : 16QAM, 10:64QAM */
111 if (mxl_fail(ret))
112 goto fail;
113
114 switch ((val & V6_PARAM_CONSTELLATION_MASK) >> 4) {
115 case 0:
116 *modulation = QPSK;
117 break;
118 case 1:
119 *modulation = QAM_16;
120 break;
121 case 2:
122 *modulation = QAM_64;
123 break;
124 }
125fail:
126 return ret;
127}
128
129static
130int mxl1x1sf_demod_get_tps_guard_fft_mode(struct mxl111sf_demod_state *state,
131 fe_transmit_mode_t *fft_mode)
132{
133 u8 val;
134 int ret = mxl111sf_demod_read_reg(state, V6_MODE_TPS_REG, &val);
135 /* FFT Mode, 00:2K, 01:8K, 10:4K */
136 if (mxl_fail(ret))
137 goto fail;
138
139 switch ((val & V6_PARAM_FFT_MODE_MASK) >> 2) {
140 case 0:
141 *fft_mode = TRANSMISSION_MODE_2K;
142 break;
143 case 1:
144 *fft_mode = TRANSMISSION_MODE_8K;
145 break;
146 case 2:
147 *fft_mode = TRANSMISSION_MODE_4K;
148 break;
149 }
150fail:
151 return ret;
152}
153
154static
155int mxl1x1sf_demod_get_tps_guard_interval(struct mxl111sf_demod_state *state,
156 fe_guard_interval_t *guard)
157{
158 u8 val;
159 int ret = mxl111sf_demod_read_reg(state, V6_CP_TPS_REG, &val);
160 /* 00:1/32, 01:1/16, 10:1/8, 11:1/4 */
161 if (mxl_fail(ret))
162 goto fail;
163
164 switch ((val & V6_PARAM_GI_MASK) >> 4) {
165 case 0:
166 *guard = GUARD_INTERVAL_1_32;
167 break;
168 case 1:
169 *guard = GUARD_INTERVAL_1_16;
170 break;
171 case 2:
172 *guard = GUARD_INTERVAL_1_8;
173 break;
174 case 3:
175 *guard = GUARD_INTERVAL_1_4;
176 break;
177 }
178fail:
179 return ret;
180}
181
182static
183int mxl1x1sf_demod_get_tps_hierarchy(struct mxl111sf_demod_state *state,
184 fe_hierarchy_t *hierarchy)
185{
186 u8 val;
187 int ret = mxl111sf_demod_read_reg(state, V6_TPS_HIERACHY_REG, &val);
188 /* bit<6:4> - 000:Non hierarchy, 001:1, 010:2, 011:4 */
189 if (mxl_fail(ret))
190 goto fail;
191
192 switch ((val & V6_TPS_HIERARCHY_INFO_MASK) >> 6) {
193 case 0:
194 *hierarchy = HIERARCHY_NONE;
195 break;
196 case 1:
197 *hierarchy = HIERARCHY_1;
198 break;
199 case 2:
200 *hierarchy = HIERARCHY_2;
201 break;
202 case 3:
203 *hierarchy = HIERARCHY_4;
204 break;
205 }
206fail:
207 return ret;
208}
209
210/* ------------------------------------------------------------------------ */
211/* LOCKS */
212
213static
214int mxl1x1sf_demod_get_sync_lock_status(struct mxl111sf_demod_state *state,
215 int *sync_lock)
216{
217 u8 val = 0;
218 int ret = mxl111sf_demod_read_reg(state, V6_SYNC_LOCK_REG, &val);
219 if (mxl_fail(ret))
220 goto fail;
221 *sync_lock = (val & SYNC_LOCK_MASK) >> 4;
222fail:
223 return ret;
224}
225
226static
227int mxl1x1sf_demod_get_rs_lock_status(struct mxl111sf_demod_state *state,
228 int *rs_lock)
229{
230 u8 val = 0;
231 int ret = mxl111sf_demod_read_reg(state, V6_RS_LOCK_DET_REG, &val);
232 if (mxl_fail(ret))
233 goto fail;
234 *rs_lock = (val & RS_LOCK_DET_MASK) >> 3;
235fail:
236 return ret;
237}
238
239static
240int mxl1x1sf_demod_get_tps_lock_status(struct mxl111sf_demod_state *state,
241 int *tps_lock)
242{
243 u8 val = 0;
244 int ret = mxl111sf_demod_read_reg(state, V6_TPS_LOCK_REG, &val);
245 if (mxl_fail(ret))
246 goto fail;
247 *tps_lock = (val & V6_PARAM_TPS_LOCK_MASK) >> 6;
248fail:
249 return ret;
250}
251
252static
253int mxl1x1sf_demod_get_fec_lock_status(struct mxl111sf_demod_state *state,
254 int *fec_lock)
255{
256 u8 val = 0;
257 int ret = mxl111sf_demod_read_reg(state, V6_IRQ_STATUS_REG, &val);
258 if (mxl_fail(ret))
259 goto fail;
260 *fec_lock = (val & IRQ_MASK_FEC_LOCK) >> 4;
261fail:
262 return ret;
263}
264
265#if 0
266static
267int mxl1x1sf_demod_get_cp_lock_status(struct mxl111sf_demod_state *state,
268 int *cp_lock)
269{
270 u8 val = 0;
271 int ret = mxl111sf_demod_read_reg(state, V6_CP_LOCK_DET_REG, &val);
272 if (mxl_fail(ret))
273 goto fail;
274 *cp_lock = (val & V6_CP_LOCK_DET_MASK) >> 2;
275fail:
276 return ret;
277}
278#endif
279
280static int mxl1x1sf_demod_reset_irq_status(struct mxl111sf_demod_state *state)
281{
282 return mxl111sf_demod_write_reg(state, 0x0e, 0xff);
283}
284
285/* ------------------------------------------------------------------------ */
286
287static int mxl111sf_demod_set_frontend(struct dvb_frontend *fe)
288{
289 struct mxl111sf_demod_state *state = fe->demodulator_priv;
290 int ret = 0;
291
292 struct mxl111sf_reg_ctrl_info phy_pll_patch[] = {
293 {0x00, 0xff, 0x01}, /* change page to 1 */
294 {0x40, 0xff, 0x05},
295 {0x40, 0xff, 0x01},
296 {0x41, 0xff, 0xca},
297 {0x41, 0xff, 0xc0},
298 {0x00, 0xff, 0x00}, /* change page to 0 */
299 {0, 0, 0}
300 };
301
302 mxl_dbg("()");
303
304 if (fe->ops.tuner_ops.set_params) {
305 ret = fe->ops.tuner_ops.set_params(fe);
306 if (mxl_fail(ret))
307 goto fail;
308 msleep(50);
309 }
310 ret = mxl111sf_demod_program_regs(state, phy_pll_patch);
311 mxl_fail(ret);
312 msleep(50);
313 ret = mxl1x1sf_demod_reset_irq_status(state);
314 mxl_fail(ret);
315 msleep(100);
316fail:
317 return ret;
318}
319
320/* ------------------------------------------------------------------------ */
321
322#if 0
323/* resets TS Packet error count */
324/* After setting 7th bit of V5_PER_COUNT_RESET_REG, it should be reset to 0. */
325static
326int mxl1x1sf_demod_reset_packet_error_count(struct mxl111sf_demod_state *state)
327{
328 struct mxl111sf_reg_ctrl_info reset_per_count[] = {
329 {0x20, 0x01, 0x01},
330 {0x20, 0x01, 0x00},
331 {0, 0, 0}
332 };
333 return mxl111sf_demod_program_regs(state, reset_per_count);
334}
335#endif
336
337/* returns TS Packet error count */
338/* PER Count = FEC_PER_COUNT * (2 ** (FEC_PER_SCALE * 4)) */
339static int mxl111sf_demod_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
340{
341 struct mxl111sf_demod_state *state = fe->demodulator_priv;
342 u32 fec_per_count, fec_per_scale;
343 u8 val;
344 int ret;
345
346 *ucblocks = 0;
347
348 /* FEC_PER_COUNT Register */
349 ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_COUNT_REG, &val);
350 if (mxl_fail(ret))
351 goto fail;
352
353 fec_per_count = val;
354
355 /* FEC_PER_SCALE Register */
356 ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_SCALE_REG, &val);
357 if (mxl_fail(ret))
358 goto fail;
359
360 val &= V6_FEC_PER_SCALE_MASK;
361 val *= 4;
362
363 fec_per_scale = 1 << val;
364
365 fec_per_count *= fec_per_scale;
366
367 *ucblocks = fec_per_count;
368fail:
369 return ret;
370}
371
372#ifdef MXL111SF_DEMOD_ENABLE_CALCULATIONS
373/* FIXME: leaving this enabled breaks the build on some architectures,
374 * and we shouldn't have any floating point math in the kernel, anyway.
375 *
376 * These macros need to be re-written, but it's harmless to simply
377 * return zero for now. */
378#define CALCULATE_BER(avg_errors, count) \
379 ((u32)(avg_errors * 4)/(count*64*188*8))
380#define CALCULATE_SNR(data) \
381 ((u32)((10 * (u32)data / 64) - 2.5))
382#else
383#define CALCULATE_BER(avg_errors, count) 0
384#define CALCULATE_SNR(data) 0
385#endif
386
387static int mxl111sf_demod_read_ber(struct dvb_frontend *fe, u32 *ber)
388{
389 struct mxl111sf_demod_state *state = fe->demodulator_priv;
390 u8 val1, val2, val3;
391 int ret;
392
393 *ber = 0;
394
395 ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_LSB_REG, &val1);
396 if (mxl_fail(ret))
397 goto fail;
398 ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_MSB_REG, &val2);
399 if (mxl_fail(ret))
400 goto fail;
401 ret = mxl111sf_demod_read_reg(state, V6_N_ACCUMULATE_REG, &val3);
402 if (mxl_fail(ret))
403 goto fail;
404
405 *ber = CALCULATE_BER((val1 | (val2 << 8)), val3);
406fail:
407 return ret;
408}
409
410static int mxl111sf_demod_calc_snr(struct mxl111sf_demod_state *state,
411 u16 *snr)
412{
413 u8 val1, val2;
414 int ret;
415
416 *snr = 0;
417
418 ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_LSB_REG, &val1);
419 if (mxl_fail(ret))
420 goto fail;
421 ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_MSB_REG, &val2);
422 if (mxl_fail(ret))
423 goto fail;
424
425 *snr = CALCULATE_SNR(val1 | ((val2 & 0x03) << 8));
426fail:
427 return ret;
428}
429
430static int mxl111sf_demod_read_snr(struct dvb_frontend *fe, u16 *snr)
431{
432 struct mxl111sf_demod_state *state = fe->demodulator_priv;
433
434 int ret = mxl111sf_demod_calc_snr(state, snr);
435 if (mxl_fail(ret))
436 goto fail;
437
438 *snr /= 10; /* 0.1 dB */
439fail:
440 return ret;
441}
442
443static int mxl111sf_demod_read_status(struct dvb_frontend *fe,
444 fe_status_t *status)
445{
446 struct mxl111sf_demod_state *state = fe->demodulator_priv;
447 int ret, locked, cr_lock, sync_lock, fec_lock;
448
449 *status = 0;
450
451 ret = mxl1x1sf_demod_get_rs_lock_status(state, &locked);
452 if (mxl_fail(ret))
453 goto fail;
454 ret = mxl1x1sf_demod_get_tps_lock_status(state, &cr_lock);
455 if (mxl_fail(ret))
456 goto fail;
457 ret = mxl1x1sf_demod_get_sync_lock_status(state, &sync_lock);
458 if (mxl_fail(ret))
459 goto fail;
460 ret = mxl1x1sf_demod_get_fec_lock_status(state, &fec_lock);
461 if (mxl_fail(ret))
462 goto fail;
463
464 if (locked)
465 *status |= FE_HAS_SIGNAL;
466 if (cr_lock)
467 *status |= FE_HAS_CARRIER;
468 if (sync_lock)
469 *status |= FE_HAS_SYNC;
470 if (fec_lock) /* false positives? */
471 *status |= FE_HAS_VITERBI;
472
473 if ((locked) && (cr_lock) && (sync_lock))
474 *status |= FE_HAS_LOCK;
475fail:
476 return ret;
477}
478
479static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe,
480 u16 *signal_strength)
481{
482 struct mxl111sf_demod_state *state = fe->demodulator_priv;
483 fe_modulation_t modulation;
484 u16 snr;
485
486 mxl111sf_demod_calc_snr(state, &snr);
487 mxl1x1sf_demod_get_tps_modulation(state, &modulation);
488
489 switch (modulation) {
490 case QPSK:
491 *signal_strength = (snr >= 1300) ?
492 min(65535, snr * 44) : snr * 38;
493 break;
494 case QAM_16:
495 *signal_strength = (snr >= 1500) ?
496 min(65535, snr * 38) : snr * 33;
497 break;
498 case QAM_64:
499 *signal_strength = (snr >= 2000) ?
500 min(65535, snr * 29) : snr * 25;
501 break;
502 default:
503 *signal_strength = 0;
504 return -EINVAL;
505 }
506
507 return 0;
508}
509
510static int mxl111sf_demod_get_frontend(struct dvb_frontend *fe)
511{
512 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
513 struct mxl111sf_demod_state *state = fe->demodulator_priv;
514
515 mxl_dbg("()");
516#if 0
517 p->inversion = /* FIXME */ ? INVERSION_ON : INVERSION_OFF;
518#endif
519 if (fe->ops.tuner_ops.get_bandwidth)
520 fe->ops.tuner_ops.get_bandwidth(fe, &p->bandwidth_hz);
521 if (fe->ops.tuner_ops.get_frequency)
522 fe->ops.tuner_ops.get_frequency(fe, &p->frequency);
523 mxl1x1sf_demod_get_tps_code_rate(state, &p->code_rate_HP);
524 mxl1x1sf_demod_get_tps_code_rate(state, &p->code_rate_LP);
525 mxl1x1sf_demod_get_tps_modulation(state, &p->modulation);
526 mxl1x1sf_demod_get_tps_guard_fft_mode(state,
527 &p->transmission_mode);
528 mxl1x1sf_demod_get_tps_guard_interval(state,
529 &p->guard_interval);
530 mxl1x1sf_demod_get_tps_hierarchy(state,
531 &p->hierarchy);
532
533 return 0;
534}
535
536static
537int mxl111sf_demod_get_tune_settings(struct dvb_frontend *fe,
538 struct dvb_frontend_tune_settings *tune)
539{
540 tune->min_delay_ms = 1000;
541 return 0;
542}
543
544static void mxl111sf_demod_release(struct dvb_frontend *fe)
545{
546 struct mxl111sf_demod_state *state = fe->demodulator_priv;
547 mxl_dbg("()");
548 kfree(state);
549 fe->demodulator_priv = NULL;
550}
551
552static struct dvb_frontend_ops mxl111sf_demod_ops = {
553 .delsys = { SYS_DVBT },
554 .info = {
555 .name = "MaxLinear MxL111SF DVB-T demodulator",
556 .frequency_min = 177000000,
557 .frequency_max = 858000000,
558 .frequency_stepsize = 166666,
559 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
560 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
561 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
562 FE_CAN_QAM_AUTO |
563 FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
564 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
565 },
566 .release = mxl111sf_demod_release,
567#if 0
568 .init = mxl111sf_init,
569 .i2c_gate_ctrl = mxl111sf_i2c_gate_ctrl,
570#endif
571 .set_frontend = mxl111sf_demod_set_frontend,
572 .get_frontend = mxl111sf_demod_get_frontend,
573 .get_tune_settings = mxl111sf_demod_get_tune_settings,
574 .read_status = mxl111sf_demod_read_status,
575 .read_signal_strength = mxl111sf_demod_read_signal_strength,
576 .read_ber = mxl111sf_demod_read_ber,
577 .read_snr = mxl111sf_demod_read_snr,
578 .read_ucblocks = mxl111sf_demod_read_ucblocks,
579};
580
581struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
582 struct mxl111sf_demod_config *cfg)
583{
584 struct mxl111sf_demod_state *state = NULL;
585
586 mxl_dbg("()");
587
588 state = kzalloc(sizeof(struct mxl111sf_demod_state), GFP_KERNEL);
589 if (state == NULL)
590 return NULL;
591
592 state->mxl_state = mxl_state;
593 state->cfg = cfg;
594
595 memcpy(&state->fe.ops, &mxl111sf_demod_ops,
596 sizeof(struct dvb_frontend_ops));
597
598 state->fe.demodulator_priv = state;
599 return &state->fe;
600}
601EXPORT_SYMBOL_GPL(mxl111sf_demod_attach);
602
603MODULE_DESCRIPTION("MaxLinear MxL111SF DVB-T demodulator driver");
604MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
605MODULE_LICENSE("GPL");
606MODULE_VERSION("0.1");
607
608/*
609 * Local variables:
610 * c-basic-offset: 8
611 * End:
612 */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
new file mode 100644
index 000000000000..432706ae5274
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
@@ -0,0 +1,55 @@
1/*
2 * mxl111sf-demod.h - driver for the MaxLinear MXL111SF DVB-T demodulator
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef __MXL111SF_DEMOD_H__
22#define __MXL111SF_DEMOD_H__
23
24#include "dvb_frontend.h"
25#include "mxl111sf.h"
26
27struct mxl111sf_demod_config {
28 int (*read_reg)(struct mxl111sf_state *state, u8 addr, u8 *data);
29 int (*write_reg)(struct mxl111sf_state *state, u8 addr, u8 data);
30 int (*program_regs)(struct mxl111sf_state *state,
31 struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
32};
33
34#if defined(CONFIG_DVB_USB_MXL111SF) || \
35 (defined(CONFIG_DVB_USB_MXL111SF_MODULE) && defined(MODULE))
36extern
37struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
38 struct mxl111sf_demod_config *cfg);
39#else
40static inline
41struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
42 struct mxl111sf_demod_config *cfg)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
45 return NULL;
46}
47#endif /* CONFIG_DVB_USB_MXL111SF */
48
49#endif /* __MXL111SF_DEMOD_H__ */
50
51/*
52 * Local variables:
53 * c-basic-offset: 8
54 * End:
55 */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c
new file mode 100644
index 000000000000..e4121cb8f5ef
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c
@@ -0,0 +1,763 @@
1/*
2 * mxl111sf-gpio.c - driver for the MaxLinear MXL111SF
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "mxl111sf-gpio.h"
22#include "mxl111sf-i2c.h"
23#include "mxl111sf.h"
24
25/* ------------------------------------------------------------------------- */
26
27#define MXL_GPIO_MUX_REG_0 0x84
28#define MXL_GPIO_MUX_REG_1 0x89
29#define MXL_GPIO_MUX_REG_2 0x82
30
31#define MXL_GPIO_DIR_INPUT 0
32#define MXL_GPIO_DIR_OUTPUT 1
33
34
35static int mxl111sf_set_gpo_state(struct mxl111sf_state *state, u8 pin, u8 val)
36{
37 int ret;
38 u8 tmp;
39
40 mxl_debug_adv("(%d, %d)", pin, val);
41
42 if ((pin > 0) && (pin < 8)) {
43 ret = mxl111sf_read_reg(state, 0x19, &tmp);
44 if (mxl_fail(ret))
45 goto fail;
46 tmp &= ~(1 << (pin - 1));
47 tmp |= (val << (pin - 1));
48 ret = mxl111sf_write_reg(state, 0x19, tmp);
49 if (mxl_fail(ret))
50 goto fail;
51 } else if (pin <= 10) {
52 if (pin == 0)
53 pin += 7;
54 ret = mxl111sf_read_reg(state, 0x30, &tmp);
55 if (mxl_fail(ret))
56 goto fail;
57 tmp &= ~(1 << (pin - 3));
58 tmp |= (val << (pin - 3));
59 ret = mxl111sf_write_reg(state, 0x30, tmp);
60 if (mxl_fail(ret))
61 goto fail;
62 } else
63 ret = -EINVAL;
64fail:
65 return ret;
66}
67
68static int mxl111sf_get_gpi_state(struct mxl111sf_state *state, u8 pin, u8 *val)
69{
70 int ret;
71 u8 tmp;
72
73 mxl_debug("(0x%02x)", pin);
74
75 *val = 0;
76
77 switch (pin) {
78 case 0:
79 case 1:
80 case 2:
81 case 3:
82 ret = mxl111sf_read_reg(state, 0x23, &tmp);
83 if (mxl_fail(ret))
84 goto fail;
85 *val = (tmp >> (pin + 4)) & 0x01;
86 break;
87 case 4:
88 case 5:
89 case 6:
90 case 7:
91 ret = mxl111sf_read_reg(state, 0x2f, &tmp);
92 if (mxl_fail(ret))
93 goto fail;
94 *val = (tmp >> pin) & 0x01;
95 break;
96 case 8:
97 case 9:
98 case 10:
99 ret = mxl111sf_read_reg(state, 0x22, &tmp);
100 if (mxl_fail(ret))
101 goto fail;
102 *val = (tmp >> (pin - 3)) & 0x01;
103 break;
104 default:
105 return -EINVAL; /* invalid pin */
106 }
107fail:
108 return ret;
109}
110
111struct mxl_gpio_cfg {
112 u8 pin;
113 u8 dir;
114 u8 val;
115};
116
117static int mxl111sf_config_gpio_pins(struct mxl111sf_state *state,
118 struct mxl_gpio_cfg *gpio_cfg)
119{
120 int ret;
121 u8 tmp;
122
123 mxl_debug_adv("(%d, %d)", gpio_cfg->pin, gpio_cfg->dir);
124
125 switch (gpio_cfg->pin) {
126 case 0:
127 case 1:
128 case 2:
129 case 3:
130 ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_0, &tmp);
131 if (mxl_fail(ret))
132 goto fail;
133 tmp &= ~(1 << (gpio_cfg->pin + 4));
134 tmp |= (gpio_cfg->dir << (gpio_cfg->pin + 4));
135 ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_0, tmp);
136 if (mxl_fail(ret))
137 goto fail;
138 break;
139 case 4:
140 case 5:
141 case 6:
142 case 7:
143 ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_1, &tmp);
144 if (mxl_fail(ret))
145 goto fail;
146 tmp &= ~(1 << gpio_cfg->pin);
147 tmp |= (gpio_cfg->dir << gpio_cfg->pin);
148 ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_1, tmp);
149 if (mxl_fail(ret))
150 goto fail;
151 break;
152 case 8:
153 case 9:
154 case 10:
155 ret = mxl111sf_read_reg(state, MXL_GPIO_MUX_REG_2, &tmp);
156 if (mxl_fail(ret))
157 goto fail;
158 tmp &= ~(1 << (gpio_cfg->pin - 3));
159 tmp |= (gpio_cfg->dir << (gpio_cfg->pin - 3));
160 ret = mxl111sf_write_reg(state, MXL_GPIO_MUX_REG_2, tmp);
161 if (mxl_fail(ret))
162 goto fail;
163 break;
164 default:
165 return -EINVAL; /* invalid pin */
166 }
167
168 ret = (MXL_GPIO_DIR_OUTPUT == gpio_cfg->dir) ?
169 mxl111sf_set_gpo_state(state,
170 gpio_cfg->pin, gpio_cfg->val) :
171 mxl111sf_get_gpi_state(state,
172 gpio_cfg->pin, &gpio_cfg->val);
173 mxl_fail(ret);
174fail:
175 return ret;
176}
177
178static int mxl111sf_hw_do_set_gpio(struct mxl111sf_state *state,
179 int gpio, int direction, int val)
180{
181 struct mxl_gpio_cfg gpio_config = {
182 .pin = gpio,
183 .dir = direction,
184 .val = val,
185 };
186
187 mxl_debug("(%d, %d, %d)", gpio, direction, val);
188
189 return mxl111sf_config_gpio_pins(state, &gpio_config);
190}
191
192/* ------------------------------------------------------------------------- */
193
194#define PIN_MUX_MPEG_MODE_MASK 0x40 /* 0x17 <6> */
195#define PIN_MUX_MPEG_PAR_EN_MASK 0x01 /* 0x18 <0> */
196#define PIN_MUX_MPEG_SER_EN_MASK 0x02 /* 0x18 <1> */
197#define PIN_MUX_MPG_IN_MUX_MASK 0x80 /* 0x3D <7> */
198#define PIN_MUX_BT656_ENABLE_MASK 0x04 /* 0x12 <2> */
199#define PIN_MUX_I2S_ENABLE_MASK 0x40 /* 0x15 <6> */
200#define PIN_MUX_SPI_MODE_MASK 0x10 /* 0x3D <4> */
201#define PIN_MUX_MCLK_EN_CTRL_MASK 0x10 /* 0x82 <4> */
202#define PIN_MUX_MPSYN_EN_CTRL_MASK 0x20 /* 0x82 <5> */
203#define PIN_MUX_MDVAL_EN_CTRL_MASK 0x40 /* 0x82 <6> */
204#define PIN_MUX_MPERR_EN_CTRL_MASK 0x80 /* 0x82 <7> */
205#define PIN_MUX_MDAT_EN_0_MASK 0x10 /* 0x84 <4> */
206#define PIN_MUX_MDAT_EN_1_MASK 0x20 /* 0x84 <5> */
207#define PIN_MUX_MDAT_EN_2_MASK 0x40 /* 0x84 <6> */
208#define PIN_MUX_MDAT_EN_3_MASK 0x80 /* 0x84 <7> */
209#define PIN_MUX_MDAT_EN_4_MASK 0x10 /* 0x89 <4> */
210#define PIN_MUX_MDAT_EN_5_MASK 0x20 /* 0x89 <5> */
211#define PIN_MUX_MDAT_EN_6_MASK 0x40 /* 0x89 <6> */
212#define PIN_MUX_MDAT_EN_7_MASK 0x80 /* 0x89 <7> */
213
214int mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state,
215 enum mxl111sf_mux_config pin_mux_config)
216{
217 u8 r12, r15, r17, r18, r3D, r82, r84, r89;
218 int ret;
219
220 mxl_debug("(%d)", pin_mux_config);
221
222 ret = mxl111sf_read_reg(state, 0x17, &r17);
223 if (mxl_fail(ret))
224 goto fail;
225 ret = mxl111sf_read_reg(state, 0x18, &r18);
226 if (mxl_fail(ret))
227 goto fail;
228 ret = mxl111sf_read_reg(state, 0x12, &r12);
229 if (mxl_fail(ret))
230 goto fail;
231 ret = mxl111sf_read_reg(state, 0x15, &r15);
232 if (mxl_fail(ret))
233 goto fail;
234 ret = mxl111sf_read_reg(state, 0x82, &r82);
235 if (mxl_fail(ret))
236 goto fail;
237 ret = mxl111sf_read_reg(state, 0x84, &r84);
238 if (mxl_fail(ret))
239 goto fail;
240 ret = mxl111sf_read_reg(state, 0x89, &r89);
241 if (mxl_fail(ret))
242 goto fail;
243 ret = mxl111sf_read_reg(state, 0x3D, &r3D);
244 if (mxl_fail(ret))
245 goto fail;
246
247 switch (pin_mux_config) {
248 case PIN_MUX_TS_OUT_PARALLEL:
249 /* mpeg_mode = 1 */
250 r17 |= PIN_MUX_MPEG_MODE_MASK;
251 /* mpeg_par_en = 1 */
252 r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
253 /* mpeg_ser_en = 0 */
254 r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
255 /* mpg_in_mux = 0 */
256 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
257 /* bt656_enable = 0 */
258 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
259 /* i2s_enable = 0 */
260 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
261 /* spi_mode = 0 */
262 r3D &= ~PIN_MUX_SPI_MODE_MASK;
263 /* mclk_en_ctrl = 1 */
264 r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
265 /* mperr_en_ctrl = 1 */
266 r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
267 /* mdval_en_ctrl = 1 */
268 r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
269 /* mpsyn_en_ctrl = 1 */
270 r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
271 /* mdat_en_ctrl[3:0] = 0xF */
272 r84 |= 0xF0;
273 /* mdat_en_ctrl[7:4] = 0xF */
274 r89 |= 0xF0;
275 break;
276 case PIN_MUX_TS_OUT_SERIAL:
277 /* mpeg_mode = 1 */
278 r17 |= PIN_MUX_MPEG_MODE_MASK;
279 /* mpeg_par_en = 0 */
280 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
281 /* mpeg_ser_en = 1 */
282 r18 |= PIN_MUX_MPEG_SER_EN_MASK;
283 /* mpg_in_mux = 0 */
284 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
285 /* bt656_enable = 0 */
286 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
287 /* i2s_enable = 0 */
288 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
289 /* spi_mode = 0 */
290 r3D &= ~PIN_MUX_SPI_MODE_MASK;
291 /* mclk_en_ctrl = 1 */
292 r82 |= PIN_MUX_MCLK_EN_CTRL_MASK;
293 /* mperr_en_ctrl = 1 */
294 r82 |= PIN_MUX_MPERR_EN_CTRL_MASK;
295 /* mdval_en_ctrl = 1 */
296 r82 |= PIN_MUX_MDVAL_EN_CTRL_MASK;
297 /* mpsyn_en_ctrl = 1 */
298 r82 |= PIN_MUX_MPSYN_EN_CTRL_MASK;
299 /* mdat_en_ctrl[3:0] = 0xF */
300 r84 |= 0xF0;
301 /* mdat_en_ctrl[7:4] = 0xF */
302 r89 |= 0xF0;
303 break;
304 case PIN_MUX_GPIO_MODE:
305 /* mpeg_mode = 0 */
306 r17 &= ~PIN_MUX_MPEG_MODE_MASK;
307 /* mpeg_par_en = 0 */
308 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
309 /* mpeg_ser_en = 0 */
310 r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
311 /* mpg_in_mux = 0 */
312 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
313 /* bt656_enable = 0 */
314 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
315 /* i2s_enable = 0 */
316 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
317 /* spi_mode = 0 */
318 r3D &= ~PIN_MUX_SPI_MODE_MASK;
319 /* mclk_en_ctrl = 0 */
320 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
321 /* mperr_en_ctrl = 0 */
322 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
323 /* mdval_en_ctrl = 0 */
324 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
325 /* mpsyn_en_ctrl = 0 */
326 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
327 /* mdat_en_ctrl[3:0] = 0x0 */
328 r84 &= 0x0F;
329 /* mdat_en_ctrl[7:4] = 0x0 */
330 r89 &= 0x0F;
331 break;
332 case PIN_MUX_TS_SERIAL_IN_MODE_0:
333 /* mpeg_mode = 0 */
334 r17 &= ~PIN_MUX_MPEG_MODE_MASK;
335 /* mpeg_par_en = 0 */
336 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
337 /* mpeg_ser_en = 1 */
338 r18 |= PIN_MUX_MPEG_SER_EN_MASK;
339 /* mpg_in_mux = 0 */
340 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
341 /* bt656_enable = 0 */
342 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
343 /* i2s_enable = 0 */
344 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
345 /* spi_mode = 0 */
346 r3D &= ~PIN_MUX_SPI_MODE_MASK;
347 /* mclk_en_ctrl = 0 */
348 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
349 /* mperr_en_ctrl = 0 */
350 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
351 /* mdval_en_ctrl = 0 */
352 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
353 /* mpsyn_en_ctrl = 0 */
354 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
355 /* mdat_en_ctrl[3:0] = 0x0 */
356 r84 &= 0x0F;
357 /* mdat_en_ctrl[7:4] = 0x0 */
358 r89 &= 0x0F;
359 break;
360 case PIN_MUX_TS_SERIAL_IN_MODE_1:
361 /* mpeg_mode = 0 */
362 r17 &= ~PIN_MUX_MPEG_MODE_MASK;
363 /* mpeg_par_en = 0 */
364 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
365 /* mpeg_ser_en = 1 */
366 r18 |= PIN_MUX_MPEG_SER_EN_MASK;
367 /* mpg_in_mux = 1 */
368 r3D |= PIN_MUX_MPG_IN_MUX_MASK;
369 /* bt656_enable = 0 */
370 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
371 /* i2s_enable = 0 */
372 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
373 /* spi_mode = 0 */
374 r3D &= ~PIN_MUX_SPI_MODE_MASK;
375 /* mclk_en_ctrl = 0 */
376 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
377 /* mperr_en_ctrl = 0 */
378 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
379 /* mdval_en_ctrl = 0 */
380 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
381 /* mpsyn_en_ctrl = 0 */
382 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
383 /* mdat_en_ctrl[3:0] = 0x0 */
384 r84 &= 0x0F;
385 /* mdat_en_ctrl[7:4] = 0x0 */
386 r89 &= 0x0F;
387 break;
388 case PIN_MUX_TS_SPI_IN_MODE_1:
389 /* mpeg_mode = 0 */
390 r17 &= ~PIN_MUX_MPEG_MODE_MASK;
391 /* mpeg_par_en = 0 */
392 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
393 /* mpeg_ser_en = 1 */
394 r18 |= PIN_MUX_MPEG_SER_EN_MASK;
395 /* mpg_in_mux = 1 */
396 r3D |= PIN_MUX_MPG_IN_MUX_MASK;
397 /* bt656_enable = 0 */
398 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
399 /* i2s_enable = 1 */
400 r15 |= PIN_MUX_I2S_ENABLE_MASK;
401 /* spi_mode = 1 */
402 r3D |= PIN_MUX_SPI_MODE_MASK;
403 /* mclk_en_ctrl = 0 */
404 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
405 /* mperr_en_ctrl = 0 */
406 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
407 /* mdval_en_ctrl = 0 */
408 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
409 /* mpsyn_en_ctrl = 0 */
410 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
411 /* mdat_en_ctrl[3:0] = 0x0 */
412 r84 &= 0x0F;
413 /* mdat_en_ctrl[7:4] = 0x0 */
414 r89 &= 0x0F;
415 break;
416 case PIN_MUX_TS_SPI_IN_MODE_0:
417 /* mpeg_mode = 0 */
418 r17 &= ~PIN_MUX_MPEG_MODE_MASK;
419 /* mpeg_par_en = 0 */
420 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
421 /* mpeg_ser_en = 1 */
422 r18 |= PIN_MUX_MPEG_SER_EN_MASK;
423 /* mpg_in_mux = 0 */
424 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
425 /* bt656_enable = 0 */
426 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
427 /* i2s_enable = 1 */
428 r15 |= PIN_MUX_I2S_ENABLE_MASK;
429 /* spi_mode = 1 */
430 r3D |= PIN_MUX_SPI_MODE_MASK;
431 /* mclk_en_ctrl = 0 */
432 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
433 /* mperr_en_ctrl = 0 */
434 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
435 /* mdval_en_ctrl = 0 */
436 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
437 /* mpsyn_en_ctrl = 0 */
438 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
439 /* mdat_en_ctrl[3:0] = 0x0 */
440 r84 &= 0x0F;
441 /* mdat_en_ctrl[7:4] = 0x0 */
442 r89 &= 0x0F;
443 break;
444 case PIN_MUX_TS_PARALLEL_IN:
445 /* mpeg_mode = 0 */
446 r17 &= ~PIN_MUX_MPEG_MODE_MASK;
447 /* mpeg_par_en = 1 */
448 r18 |= PIN_MUX_MPEG_PAR_EN_MASK;
449 /* mpeg_ser_en = 0 */
450 r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
451 /* mpg_in_mux = 0 */
452 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
453 /* bt656_enable = 0 */
454 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
455 /* i2s_enable = 0 */
456 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
457 /* spi_mode = 0 */
458 r3D &= ~PIN_MUX_SPI_MODE_MASK;
459 /* mclk_en_ctrl = 0 */
460 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
461 /* mperr_en_ctrl = 0 */
462 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
463 /* mdval_en_ctrl = 0 */
464 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
465 /* mpsyn_en_ctrl = 0 */
466 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
467 /* mdat_en_ctrl[3:0] = 0x0 */
468 r84 &= 0x0F;
469 /* mdat_en_ctrl[7:4] = 0x0 */
470 r89 &= 0x0F;
471 break;
472 case PIN_MUX_BT656_I2S_MODE:
473 /* mpeg_mode = 0 */
474 r17 &= ~PIN_MUX_MPEG_MODE_MASK;
475 /* mpeg_par_en = 0 */
476 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
477 /* mpeg_ser_en = 0 */
478 r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
479 /* mpg_in_mux = 0 */
480 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
481 /* bt656_enable = 1 */
482 r12 |= PIN_MUX_BT656_ENABLE_MASK;
483 /* i2s_enable = 1 */
484 r15 |= PIN_MUX_I2S_ENABLE_MASK;
485 /* spi_mode = 0 */
486 r3D &= ~PIN_MUX_SPI_MODE_MASK;
487 /* mclk_en_ctrl = 0 */
488 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
489 /* mperr_en_ctrl = 0 */
490 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
491 /* mdval_en_ctrl = 0 */
492 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
493 /* mpsyn_en_ctrl = 0 */
494 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
495 /* mdat_en_ctrl[3:0] = 0x0 */
496 r84 &= 0x0F;
497 /* mdat_en_ctrl[7:4] = 0x0 */
498 r89 &= 0x0F;
499 break;
500 case PIN_MUX_DEFAULT:
501 default:
502 /* mpeg_mode = 1 */
503 r17 |= PIN_MUX_MPEG_MODE_MASK;
504 /* mpeg_par_en = 0 */
505 r18 &= ~PIN_MUX_MPEG_PAR_EN_MASK;
506 /* mpeg_ser_en = 0 */
507 r18 &= ~PIN_MUX_MPEG_SER_EN_MASK;
508 /* mpg_in_mux = 0 */
509 r3D &= ~PIN_MUX_MPG_IN_MUX_MASK;
510 /* bt656_enable = 0 */
511 r12 &= ~PIN_MUX_BT656_ENABLE_MASK;
512 /* i2s_enable = 0 */
513 r15 &= ~PIN_MUX_I2S_ENABLE_MASK;
514 /* spi_mode = 0 */
515 r3D &= ~PIN_MUX_SPI_MODE_MASK;
516 /* mclk_en_ctrl = 0 */
517 r82 &= ~PIN_MUX_MCLK_EN_CTRL_MASK;
518 /* mperr_en_ctrl = 0 */
519 r82 &= ~PIN_MUX_MPERR_EN_CTRL_MASK;
520 /* mdval_en_ctrl = 0 */
521 r82 &= ~PIN_MUX_MDVAL_EN_CTRL_MASK;
522 /* mpsyn_en_ctrl = 0 */
523 r82 &= ~PIN_MUX_MPSYN_EN_CTRL_MASK;
524 /* mdat_en_ctrl[3:0] = 0x0 */
525 r84 &= 0x0F;
526 /* mdat_en_ctrl[7:4] = 0x0 */
527 r89 &= 0x0F;
528 break;
529 }
530
531 ret = mxl111sf_write_reg(state, 0x17, r17);
532 if (mxl_fail(ret))
533 goto fail;
534 ret = mxl111sf_write_reg(state, 0x18, r18);
535 if (mxl_fail(ret))
536 goto fail;
537 ret = mxl111sf_write_reg(state, 0x12, r12);
538 if (mxl_fail(ret))
539 goto fail;
540 ret = mxl111sf_write_reg(state, 0x15, r15);
541 if (mxl_fail(ret))
542 goto fail;
543 ret = mxl111sf_write_reg(state, 0x82, r82);
544 if (mxl_fail(ret))
545 goto fail;
546 ret = mxl111sf_write_reg(state, 0x84, r84);
547 if (mxl_fail(ret))
548 goto fail;
549 ret = mxl111sf_write_reg(state, 0x89, r89);
550 if (mxl_fail(ret))
551 goto fail;
552 ret = mxl111sf_write_reg(state, 0x3D, r3D);
553 if (mxl_fail(ret))
554 goto fail;
555fail:
556 return ret;
557}
558
559/* ------------------------------------------------------------------------- */
560
561static int mxl111sf_hw_set_gpio(struct mxl111sf_state *state, int gpio, int val)
562{
563 return mxl111sf_hw_do_set_gpio(state, gpio, MXL_GPIO_DIR_OUTPUT, val);
564}
565
566static int mxl111sf_hw_gpio_initialize(struct mxl111sf_state *state)
567{
568 u8 gpioval = 0x07; /* write protect enabled, signal LEDs off */
569 int i, ret;
570
571 mxl_debug("()");
572
573 for (i = 3; i < 8; i++) {
574 ret = mxl111sf_hw_set_gpio(state, i, (gpioval >> i) & 0x01);
575 if (mxl_fail(ret))
576 break;
577 }
578
579 return ret;
580}
581
582#define PCA9534_I2C_ADDR (0x40 >> 1)
583static int pca9534_set_gpio(struct mxl111sf_state *state, int gpio, int val)
584{
585 u8 w[2] = { 1, 0 };
586 u8 r = 0;
587 struct i2c_msg msg[] = {
588 { .addr = PCA9534_I2C_ADDR,
589 .flags = 0, .buf = w, .len = 1 },
590 { .addr = PCA9534_I2C_ADDR,
591 .flags = I2C_M_RD, .buf = &r, .len = 1 },
592 };
593
594 mxl_debug("(%d, %d)", gpio, val);
595
596 /* read current GPIO levels from flip-flop */
597 i2c_transfer(&state->d->i2c_adap, msg, 2);
598
599 /* prepare write buffer with current GPIO levels */
600 msg[0].len = 2;
601#if 0
602 w[0] = 1;
603#endif
604 w[1] = r;
605
606 /* clear the desired GPIO */
607 w[1] &= ~(1 << gpio);
608
609 /* set the desired GPIO value */
610 w[1] |= ((val ? 1 : 0) << gpio);
611
612 /* write new GPIO levels to flip-flop */
613 i2c_transfer(&state->d->i2c_adap, &msg[0], 1);
614
615 return 0;
616}
617
618static int pca9534_init_port_expander(struct mxl111sf_state *state)
619{
620 u8 w[2] = { 1, 0x07 }; /* write protect enabled, signal LEDs off */
621
622 struct i2c_msg msg = {
623 .addr = PCA9534_I2C_ADDR,
624 .flags = 0, .buf = w, .len = 2
625 };
626
627 mxl_debug("()");
628
629 i2c_transfer(&state->d->i2c_adap, &msg, 1);
630
631 /* configure all pins as outputs */
632 w[0] = 3;
633 w[1] = 0;
634
635 i2c_transfer(&state->d->i2c_adap, &msg, 1);
636
637 return 0;
638}
639
640int mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val)
641{
642 mxl_debug("(%d, %d)", gpio, val);
643
644 switch (state->gpio_port_expander) {
645 default:
646 mxl_printk(KERN_ERR,
647 "gpio_port_expander undefined, assuming PCA9534");
648 /* fall-thru */
649 case mxl111sf_PCA9534:
650 return pca9534_set_gpio(state, gpio, val);
651 case mxl111sf_gpio_hw:
652 return mxl111sf_hw_set_gpio(state, gpio, val);
653 }
654}
655
656static int mxl111sf_probe_port_expander(struct mxl111sf_state *state)
657{
658 int ret;
659 u8 w = 1;
660 u8 r = 0;
661 struct i2c_msg msg[] = {
662 { .flags = 0, .buf = &w, .len = 1 },
663 { .flags = I2C_M_RD, .buf = &r, .len = 1 },
664 };
665
666 mxl_debug("()");
667
668 msg[0].addr = 0x70 >> 1;
669 msg[1].addr = 0x70 >> 1;
670
671 /* read current GPIO levels from flip-flop */
672 ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
673 if (ret == 2) {
674 state->port_expander_addr = msg[0].addr;
675 state->gpio_port_expander = mxl111sf_PCA9534;
676 mxl_debug("found port expander at 0x%02x",
677 state->port_expander_addr);
678 return 0;
679 }
680
681 msg[0].addr = 0x40 >> 1;
682 msg[1].addr = 0x40 >> 1;
683
684 ret = i2c_transfer(&state->d->i2c_adap, msg, 2);
685 if (ret == 2) {
686 state->port_expander_addr = msg[0].addr;
687 state->gpio_port_expander = mxl111sf_PCA9534;
688 mxl_debug("found port expander at 0x%02x",
689 state->port_expander_addr);
690 return 0;
691 }
692 state->port_expander_addr = 0xff;
693 state->gpio_port_expander = mxl111sf_gpio_hw;
694 mxl_debug("using hardware gpio");
695 return 0;
696}
697
698int mxl111sf_init_port_expander(struct mxl111sf_state *state)
699{
700 mxl_debug("()");
701
702 if (0x00 == state->port_expander_addr)
703 mxl111sf_probe_port_expander(state);
704
705 switch (state->gpio_port_expander) {
706 default:
707 mxl_printk(KERN_ERR,
708 "gpio_port_expander undefined, assuming PCA9534");
709 /* fall-thru */
710 case mxl111sf_PCA9534:
711 return pca9534_init_port_expander(state);
712 case mxl111sf_gpio_hw:
713 return mxl111sf_hw_gpio_initialize(state);
714 }
715}
716
717/* ------------------------------------------------------------------------ */
718
719int mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode)
720{
721/* GPO:
722 * 3 - ATSC/MH# | 1 = ATSC transport, 0 = MH transport | default 0
723 * 4 - ATSC_RST## | 1 = ATSC enable, 0 = ATSC Reset | default 0
724 * 5 - ATSC_EN | 1 = ATSC power enable, 0 = ATSC power off | default 0
725 * 6 - MH_RESET# | 1 = MH enable, 0 = MH Reset | default 0
726 * 7 - MH_EN | 1 = MH power enable, 0 = MH power off | default 0
727 */
728 mxl_debug("(%d)", mode);
729
730 switch (mode) {
731 case MXL111SF_GPIO_MOD_MH:
732 mxl111sf_set_gpio(state, 4, 0);
733 mxl111sf_set_gpio(state, 5, 0);
734 msleep(50);
735 mxl111sf_set_gpio(state, 7, 1);
736 msleep(50);
737 mxl111sf_set_gpio(state, 6, 1);
738 msleep(50);
739
740 mxl111sf_set_gpio(state, 3, 0);
741 break;
742 case MXL111SF_GPIO_MOD_ATSC:
743 mxl111sf_set_gpio(state, 6, 0);
744 mxl111sf_set_gpio(state, 7, 0);
745 msleep(50);
746 mxl111sf_set_gpio(state, 5, 1);
747 msleep(50);
748 mxl111sf_set_gpio(state, 4, 1);
749 msleep(50);
750 mxl111sf_set_gpio(state, 3, 1);
751 break;
752 default: /* DVBT / STANDBY */
753 mxl111sf_init_port_expander(state);
754 break;
755 }
756 return 0;
757}
758
759/*
760 * Local variables:
761 * c-basic-offset: 8
762 * End:
763 */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h
new file mode 100644
index 000000000000..0220f54299a5
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h
@@ -0,0 +1,56 @@
1/*
2 * mxl111sf-gpio.h - driver for the MaxLinear MXL111SF
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef _DVB_USB_MXL111SF_GPIO_H_
22#define _DVB_USB_MXL111SF_GPIO_H_
23
24#include "mxl111sf.h"
25
26int mxl111sf_set_gpio(struct mxl111sf_state *state, int gpio, int val);
27int mxl111sf_init_port_expander(struct mxl111sf_state *state);
28
29#define MXL111SF_GPIO_MOD_DVBT 0
30#define MXL111SF_GPIO_MOD_MH 1
31#define MXL111SF_GPIO_MOD_ATSC 2
32int mxl111sf_gpio_mode_switch(struct mxl111sf_state *state, unsigned int mode);
33
34enum mxl111sf_mux_config {
35 PIN_MUX_DEFAULT = 0,
36 PIN_MUX_TS_OUT_PARALLEL,
37 PIN_MUX_TS_OUT_SERIAL,
38 PIN_MUX_GPIO_MODE,
39 PIN_MUX_TS_SERIAL_IN_MODE_0,
40 PIN_MUX_TS_SERIAL_IN_MODE_1,
41 PIN_MUX_TS_SPI_IN_MODE_0,
42 PIN_MUX_TS_SPI_IN_MODE_1,
43 PIN_MUX_TS_PARALLEL_IN,
44 PIN_MUX_BT656_I2S_MODE,
45};
46
47int mxl111sf_config_pin_mux_modes(struct mxl111sf_state *state,
48 enum mxl111sf_mux_config pin_mux_config);
49
50#endif /* _DVB_USB_MXL111SF_GPIO_H_ */
51
52/*
53 * Local variables:
54 * c-basic-offset: 8
55 * End:
56 */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c
new file mode 100644
index 000000000000..34434557ef65
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c
@@ -0,0 +1,850 @@
1/*
2 * mxl111sf-i2c.c - driver for the MaxLinear MXL111SF
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "mxl111sf-i2c.h"
22#include "mxl111sf.h"
23
24/* SW-I2C ----------------------------------------------------------------- */
25
26#define SW_I2C_ADDR 0x1a
27#define SW_I2C_EN 0x02
28#define SW_SCL_OUT 0x04
29#define SW_SDA_OUT 0x08
30#define SW_SDA_IN 0x04
31
32#define SW_I2C_BUSY_ADDR 0x2f
33#define SW_I2C_BUSY 0x02
34
35static int mxl111sf_i2c_bitbang_sendbyte(struct mxl111sf_state *state,
36 u8 byte)
37{
38 int i, ret;
39 u8 data = 0;
40
41 mxl_i2c("(0x%02x)", byte);
42
43 ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
44 if (mxl_fail(ret))
45 goto fail;
46
47 for (i = 0; i < 8; i++) {
48
49 data = (byte & (0x80 >> i)) ? SW_SDA_OUT : 0;
50
51 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
52 0x10 | SW_I2C_EN | data);
53 if (mxl_fail(ret))
54 goto fail;
55
56 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
57 0x10 | SW_I2C_EN | data | SW_SCL_OUT);
58 if (mxl_fail(ret))
59 goto fail;
60
61 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
62 0x10 | SW_I2C_EN | data);
63 if (mxl_fail(ret))
64 goto fail;
65 }
66
67 /* last bit was 0 so we need to release SDA */
68 if (!(byte & 1)) {
69 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
70 0x10 | SW_I2C_EN | SW_SDA_OUT);
71 if (mxl_fail(ret))
72 goto fail;
73 }
74
75 /* CLK high for ACK readback */
76 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
77 0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
78 if (mxl_fail(ret))
79 goto fail;
80
81 ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
82 if (mxl_fail(ret))
83 goto fail;
84
85 /* drop the CLK after getting ACK, SDA will go high right away */
86 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
87 0x10 | SW_I2C_EN | SW_SDA_OUT);
88 if (mxl_fail(ret))
89 goto fail;
90
91 if (data & SW_SDA_IN)
92 ret = -EIO;
93fail:
94 return ret;
95}
96
97static int mxl111sf_i2c_bitbang_recvbyte(struct mxl111sf_state *state,
98 u8 *pbyte)
99{
100 int i, ret;
101 u8 byte = 0;
102 u8 data = 0;
103
104 mxl_i2c("()");
105
106 *pbyte = 0;
107
108 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
109 0x10 | SW_I2C_EN | SW_SDA_OUT);
110 if (mxl_fail(ret))
111 goto fail;
112
113 for (i = 0; i < 8; i++) {
114 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
115 0x10 | SW_I2C_EN |
116 SW_SCL_OUT | SW_SDA_OUT);
117 if (mxl_fail(ret))
118 goto fail;
119
120 ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data);
121 if (mxl_fail(ret))
122 goto fail;
123
124 if (data & SW_SDA_IN)
125 byte |= (0x80 >> i);
126
127 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
128 0x10 | SW_I2C_EN | SW_SDA_OUT);
129 if (mxl_fail(ret))
130 goto fail;
131 }
132 *pbyte = byte;
133fail:
134 return ret;
135}
136
137static int mxl111sf_i2c_start(struct mxl111sf_state *state)
138{
139 int ret;
140
141 mxl_i2c("()");
142
143 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
144 0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
145 if (mxl_fail(ret))
146 goto fail;
147
148 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
149 0x10 | SW_I2C_EN | SW_SCL_OUT);
150 if (mxl_fail(ret))
151 goto fail;
152
153 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
154 0x10 | SW_I2C_EN); /* start */
155 mxl_fail(ret);
156fail:
157 return ret;
158}
159
160static int mxl111sf_i2c_stop(struct mxl111sf_state *state)
161{
162 int ret;
163
164 mxl_i2c("()");
165
166 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
167 0x10 | SW_I2C_EN); /* stop */
168 if (mxl_fail(ret))
169 goto fail;
170
171 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
172 0x10 | SW_I2C_EN | SW_SCL_OUT);
173 if (mxl_fail(ret))
174 goto fail;
175
176 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
177 0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
178 if (mxl_fail(ret))
179 goto fail;
180
181 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
182 0x10 | SW_SCL_OUT | SW_SDA_OUT);
183 mxl_fail(ret);
184fail:
185 return ret;
186}
187
188static int mxl111sf_i2c_ack(struct mxl111sf_state *state)
189{
190 int ret;
191 u8 b = 0;
192
193 mxl_i2c("()");
194
195 ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &b);
196 if (mxl_fail(ret))
197 goto fail;
198
199 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
200 0x10 | SW_I2C_EN);
201 if (mxl_fail(ret))
202 goto fail;
203
204 /* pull SDA low */
205 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
206 0x10 | SW_I2C_EN | SW_SCL_OUT);
207 if (mxl_fail(ret))
208 goto fail;
209
210 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
211 0x10 | SW_I2C_EN | SW_SDA_OUT);
212 mxl_fail(ret);
213fail:
214 return ret;
215}
216
217static int mxl111sf_i2c_nack(struct mxl111sf_state *state)
218{
219 int ret;
220
221 mxl_i2c("()");
222
223 /* SDA high to signal last byte read from slave */
224 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
225 0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT);
226 if (mxl_fail(ret))
227 goto fail;
228
229 ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
230 0x10 | SW_I2C_EN | SW_SDA_OUT);
231 mxl_fail(ret);
232fail:
233 return ret;
234}
235
236/* ------------------------------------------------------------------------ */
237
238static int mxl111sf_i2c_sw_xfer_msg(struct mxl111sf_state *state,
239 struct i2c_msg *msg)
240{
241 int i, ret;
242
243 mxl_i2c("()");
244
245 if (msg->flags & I2C_M_RD) {
246
247 ret = mxl111sf_i2c_start(state);
248 if (mxl_fail(ret))
249 goto fail;
250
251 ret = mxl111sf_i2c_bitbang_sendbyte(state,
252 (msg->addr << 1) | 0x01);
253 if (mxl_fail(ret)) {
254 mxl111sf_i2c_stop(state);
255 goto fail;
256 }
257
258 for (i = 0; i < msg->len; i++) {
259 ret = mxl111sf_i2c_bitbang_recvbyte(state,
260 &msg->buf[i]);
261 if (mxl_fail(ret)) {
262 mxl111sf_i2c_stop(state);
263 goto fail;
264 }
265
266 if (i < msg->len - 1)
267 mxl111sf_i2c_ack(state);
268 }
269
270 mxl111sf_i2c_nack(state);
271
272 ret = mxl111sf_i2c_stop(state);
273 if (mxl_fail(ret))
274 goto fail;
275
276 } else {
277
278 ret = mxl111sf_i2c_start(state);
279 if (mxl_fail(ret))
280 goto fail;
281
282 ret = mxl111sf_i2c_bitbang_sendbyte(state,
283 (msg->addr << 1) & 0xfe);
284 if (mxl_fail(ret)) {
285 mxl111sf_i2c_stop(state);
286 goto fail;
287 }
288
289 for (i = 0; i < msg->len; i++) {
290 ret = mxl111sf_i2c_bitbang_sendbyte(state,
291 msg->buf[i]);
292 if (mxl_fail(ret)) {
293 mxl111sf_i2c_stop(state);
294 goto fail;
295 }
296 }
297
298 /* FIXME: we only want to do this on the last transaction */
299 mxl111sf_i2c_stop(state);
300 }
301fail:
302 return ret;
303}
304
305/* HW-I2C ----------------------------------------------------------------- */
306
307#define USB_WRITE_I2C_CMD 0x99
308#define USB_READ_I2C_CMD 0xdd
309#define USB_END_I2C_CMD 0xfe
310
311#define USB_WRITE_I2C_CMD_LEN 26
312#define USB_READ_I2C_CMD_LEN 24
313
314#define I2C_MUX_REG 0x30
315#define I2C_CONTROL_REG 0x00
316#define I2C_SLAVE_ADDR_REG 0x08
317#define I2C_DATA_REG 0x0c
318#define I2C_INT_STATUS_REG 0x10
319
320static int mxl111sf_i2c_send_data(struct mxl111sf_state *state,
321 u8 index, u8 *wdata)
322{
323 int ret = mxl111sf_ctrl_msg(state->d, wdata[0],
324 &wdata[1], 25, NULL, 0);
325 mxl_fail(ret);
326
327 return ret;
328}
329
330static int mxl111sf_i2c_get_data(struct mxl111sf_state *state,
331 u8 index, u8 *wdata, u8 *rdata)
332{
333 int ret = mxl111sf_ctrl_msg(state->d, wdata[0],
334 &wdata[1], 25, rdata, 24);
335 mxl_fail(ret);
336
337 return ret;
338}
339
340static u8 mxl111sf_i2c_check_status(struct mxl111sf_state *state)
341{
342 u8 status = 0;
343 u8 buf[26];
344
345 mxl_i2c_adv("()");
346
347 buf[0] = USB_READ_I2C_CMD;
348 buf[1] = 0x00;
349
350 buf[2] = I2C_INT_STATUS_REG;
351 buf[3] = 0x00;
352 buf[4] = 0x00;
353
354 buf[5] = USB_END_I2C_CMD;
355
356 mxl111sf_i2c_get_data(state, 0, buf, buf);
357
358 if (buf[1] & 0x04)
359 status = 1;
360
361 return status;
362}
363
364static u8 mxl111sf_i2c_check_fifo(struct mxl111sf_state *state)
365{
366 u8 status = 0;
367 u8 buf[26];
368
369 mxl_i2c("()");
370
371 buf[0] = USB_READ_I2C_CMD;
372 buf[1] = 0x00;
373
374 buf[2] = I2C_MUX_REG;
375 buf[3] = 0x00;
376 buf[4] = 0x00;
377
378 buf[5] = I2C_INT_STATUS_REG;
379 buf[6] = 0x00;
380 buf[7] = 0x00;
381 buf[8] = USB_END_I2C_CMD;
382
383 mxl111sf_i2c_get_data(state, 0, buf, buf);
384
385 if (0x08 == (buf[1] & 0x08))
386 status = 1;
387
388 if ((buf[5] & 0x02) == 0x02)
389 mxl_i2c("(buf[5] & 0x02) == 0x02"); /* FIXME */
390
391 return status;
392}
393
394static int mxl111sf_i2c_readagain(struct mxl111sf_state *state,
395 u8 count, u8 *rbuf)
396{
397 u8 i2c_w_data[26];
398 u8 i2c_r_data[24];
399 u8 i = 0;
400 u8 fifo_status = 0;
401 int status = 0;
402
403 mxl_i2c("read %d bytes", count);
404
405 while ((fifo_status == 0) && (i++ < 5))
406 fifo_status = mxl111sf_i2c_check_fifo(state);
407
408 i2c_w_data[0] = 0xDD;
409 i2c_w_data[1] = 0x00;
410
411 for (i = 2; i < 26; i++)
412 i2c_w_data[i] = 0xFE;
413
414 for (i = 0; i < count; i++) {
415 i2c_w_data[2+(i*3)] = 0x0C;
416 i2c_w_data[3+(i*3)] = 0x00;
417 i2c_w_data[4+(i*3)] = 0x00;
418 }
419
420 mxl111sf_i2c_get_data(state, 0, i2c_w_data, i2c_r_data);
421
422 /* Check for I2C NACK status */
423 if (mxl111sf_i2c_check_status(state) == 1) {
424 mxl_i2c("error!");
425 } else {
426 for (i = 0; i < count; i++) {
427 rbuf[i] = i2c_r_data[(i*3)+1];
428 mxl_i2c("%02x\t %02x",
429 i2c_r_data[(i*3)+1],
430 i2c_r_data[(i*3)+2]);
431 }
432
433 status = 1;
434 }
435
436 return status;
437}
438
439#define HWI2C400 1
440static int mxl111sf_i2c_hw_xfer_msg(struct mxl111sf_state *state,
441 struct i2c_msg *msg)
442{
443 int i, k, ret = 0;
444 u16 index = 0;
445 u8 buf[26];
446 u8 i2c_r_data[24];
447 u16 block_len;
448 u16 left_over_len;
449 u8 rd_status[8];
450 u8 ret_status;
451 u8 readbuff[26];
452
453 mxl_i2c("addr: 0x%02x, read buff len: %d, write buff len: %d",
454 msg->addr, (msg->flags & I2C_M_RD) ? msg->len : 0,
455 (!(msg->flags & I2C_M_RD)) ? msg->len : 0);
456
457 for (index = 0; index < 26; index++)
458 buf[index] = USB_END_I2C_CMD;
459
460 /* command to indicate data payload is destined for I2C interface */
461 buf[0] = USB_WRITE_I2C_CMD;
462 buf[1] = 0x00;
463
464 /* enable I2C interface */
465 buf[2] = I2C_MUX_REG;
466 buf[3] = 0x80;
467 buf[4] = 0x00;
468
469 /* enable I2C interface */
470 buf[5] = I2C_MUX_REG;
471 buf[6] = 0x81;
472 buf[7] = 0x00;
473
474 /* set Timeout register on I2C interface */
475 buf[8] = 0x14;
476 buf[9] = 0xff;
477 buf[10] = 0x00;
478#if 0
479 /* enable Interrupts on I2C interface */
480 buf[8] = 0x24;
481 buf[9] = 0xF7;
482 buf[10] = 0x00;
483#endif
484 buf[11] = 0x24;
485 buf[12] = 0xF7;
486 buf[13] = 0x00;
487
488 ret = mxl111sf_i2c_send_data(state, 0, buf);
489
490 /* write data on I2C bus */
491 if (!(msg->flags & I2C_M_RD) && (msg->len > 0)) {
492 mxl_i2c("%d\t%02x", msg->len, msg->buf[0]);
493
494 /* control register on I2C interface to initialize I2C bus */
495 buf[2] = I2C_CONTROL_REG;
496 buf[3] = 0x5E;
497 buf[4] = (HWI2C400) ? 0x03 : 0x0D;
498
499 /* I2C Slave device Address */
500 buf[5] = I2C_SLAVE_ADDR_REG;
501 buf[6] = (msg->addr);
502 buf[7] = 0x00;
503 buf[8] = USB_END_I2C_CMD;
504 ret = mxl111sf_i2c_send_data(state, 0, buf);
505
506 /* check for slave device status */
507 if (mxl111sf_i2c_check_status(state) == 1) {
508 mxl_i2c("NACK writing slave address %02x",
509 msg->addr);
510 /* if NACK, stop I2C bus and exit */
511 buf[2] = I2C_CONTROL_REG;
512 buf[3] = 0x4E;
513 buf[4] = (HWI2C400) ? 0x03 : 0x0D;
514 ret = -EIO;
515 goto exit;
516 }
517
518 /* I2C interface can do I2C operations in block of 8 bytes of
519 I2C data. calculation to figure out number of blocks of i2c
520 data required to program */
521 block_len = (msg->len / 8);
522 left_over_len = (msg->len % 8);
523 index = 0;
524
525 mxl_i2c("block_len %d, left_over_len %d",
526 block_len, left_over_len);
527
528 for (index = 0; index < block_len; index++) {
529 for (i = 0; i < 8; i++) {
530 /* write data on I2C interface */
531 buf[2+(i*3)] = I2C_DATA_REG;
532 buf[3+(i*3)] = msg->buf[(index*8)+i];
533 buf[4+(i*3)] = 0x00;
534 }
535
536 ret = mxl111sf_i2c_send_data(state, 0, buf);
537
538 /* check for I2C NACK status */
539 if (mxl111sf_i2c_check_status(state) == 1) {
540 mxl_i2c("NACK writing slave address %02x",
541 msg->addr);
542
543 /* if NACK, stop I2C bus and exit */
544 buf[2] = I2C_CONTROL_REG;
545 buf[3] = 0x4E;
546 buf[4] = (HWI2C400) ? 0x03 : 0x0D;
547 ret = -EIO;
548 goto exit;
549 }
550
551 }
552
553 if (left_over_len) {
554 for (k = 0; k < 26; k++)
555 buf[k] = USB_END_I2C_CMD;
556
557 buf[0] = 0x99;
558 buf[1] = 0x00;
559
560 for (i = 0; i < left_over_len; i++) {
561 buf[2+(i*3)] = I2C_DATA_REG;
562 buf[3+(i*3)] = msg->buf[(index*8)+i];
563 mxl_i2c("index = %d %d data %d",
564 index, i, msg->buf[(index*8)+i]);
565 buf[4+(i*3)] = 0x00;
566 }
567 ret = mxl111sf_i2c_send_data(state, 0, buf);
568
569 /* check for I2C NACK status */
570 if (mxl111sf_i2c_check_status(state) == 1) {
571 mxl_i2c("NACK writing slave address %02x",
572 msg->addr);
573
574 /* if NACK, stop I2C bus and exit */
575 buf[2] = I2C_CONTROL_REG;
576 buf[3] = 0x4E;
577 buf[4] = (HWI2C400) ? 0x03 : 0x0D;
578 ret = -EIO;
579 goto exit;
580 }
581
582 }
583
584 /* issue I2C STOP after write */
585 buf[2] = I2C_CONTROL_REG;
586 buf[3] = 0x4E;
587 buf[4] = (HWI2C400) ? 0x03 : 0x0D;
588
589 }
590
591 /* read data from I2C bus */
592 if ((msg->flags & I2C_M_RD) && (msg->len > 0)) {
593 mxl_i2c("read buf len %d", msg->len);
594
595 /* command to indicate data payload is
596 destined for I2C interface */
597 buf[2] = I2C_CONTROL_REG;
598 buf[3] = 0xDF;
599 buf[4] = (HWI2C400) ? 0x03 : 0x0D;
600
601 /* I2C xfer length */
602 buf[5] = 0x14;
603 buf[6] = (msg->len & 0xFF);
604 buf[7] = 0;
605
606 /* I2C slave device Address */
607 buf[8] = I2C_SLAVE_ADDR_REG;
608 buf[9] = msg->addr;
609 buf[10] = 0x00;
610 buf[11] = USB_END_I2C_CMD;
611 ret = mxl111sf_i2c_send_data(state, 0, buf);
612
613 /* check for I2C NACK status */
614 if (mxl111sf_i2c_check_status(state) == 1) {
615 mxl_i2c("NACK reading slave address %02x",
616 msg->addr);
617
618 /* if NACK, stop I2C bus and exit */
619 buf[2] = I2C_CONTROL_REG;
620 buf[3] = 0xC7;
621 buf[4] = (HWI2C400) ? 0x03 : 0x0D;
622 ret = -EIO;
623 goto exit;
624 }
625
626 /* I2C interface can do I2C operations in block of 8 bytes of
627 I2C data. calculation to figure out number of blocks of
628 i2c data required to program */
629 block_len = ((msg->len) / 8);
630 left_over_len = ((msg->len) % 8);
631 index = 0;
632
633 mxl_i2c("block_len %d, left_over_len %d",
634 block_len, left_over_len);
635
636 /* command to read data from I2C interface */
637 buf[0] = USB_READ_I2C_CMD;
638 buf[1] = 0x00;
639
640 for (index = 0; index < block_len; index++) {
641 /* setup I2C read request packet on I2C interface */
642 for (i = 0; i < 8; i++) {
643 buf[2+(i*3)] = I2C_DATA_REG;
644 buf[3+(i*3)] = 0x00;
645 buf[4+(i*3)] = 0x00;
646 }
647
648 ret = mxl111sf_i2c_get_data(state, 0, buf, i2c_r_data);
649
650 /* check for I2C NACK status */
651 if (mxl111sf_i2c_check_status(state) == 1) {
652 mxl_i2c("NACK reading slave address %02x",
653 msg->addr);
654
655 /* if NACK, stop I2C bus and exit */
656 buf[2] = I2C_CONTROL_REG;
657 buf[3] = 0xC7;
658 buf[4] = (HWI2C400) ? 0x03 : 0x0D;
659 ret = -EIO;
660 goto exit;
661 }
662
663 /* copy data from i2c data payload to read buffer */
664 for (i = 0; i < 8; i++) {
665 rd_status[i] = i2c_r_data[(i*3)+2];
666
667 if (rd_status[i] == 0x04) {
668 if (i < 7) {
669 mxl_i2c("i2c fifo empty!"
670 " @ %d", i);
671 msg->buf[(index*8)+i] =
672 i2c_r_data[(i*3)+1];
673 /* read again */
674 ret_status =
675 mxl111sf_i2c_readagain(
676 state, 8-(i+1),
677 readbuff);
678 if (ret_status == 1) {
679 for (k = 0;
680 k < 8-(i+1);
681 k++) {
682
683 msg->buf[(index*8)+(k+i+1)] =
684 readbuff[k];
685 mxl_i2c("read data: %02x\t %02x",
686 msg->buf[(index*8)+(k+i)],
687 (index*8)+(k+i));
688 mxl_i2c("read data: %02x\t %02x",
689 msg->buf[(index*8)+(k+i+1)],
690 readbuff[k]);
691
692 }
693 goto stop_copy;
694 } else {
695 mxl_i2c("readagain "
696 "ERROR!");
697 }
698 } else {
699 msg->buf[(index*8)+i] =
700 i2c_r_data[(i*3)+1];
701 }
702 } else {
703 msg->buf[(index*8)+i] =
704 i2c_r_data[(i*3)+1];
705 }
706 }
707stop_copy:
708 ;
709
710 }
711
712 if (left_over_len) {
713 for (k = 0; k < 26; k++)
714 buf[k] = USB_END_I2C_CMD;
715
716 buf[0] = 0xDD;
717 buf[1] = 0x00;
718
719 for (i = 0; i < left_over_len; i++) {
720 buf[2+(i*3)] = I2C_DATA_REG;
721 buf[3+(i*3)] = 0x00;
722 buf[4+(i*3)] = 0x00;
723 }
724 ret = mxl111sf_i2c_get_data(state, 0, buf,
725 i2c_r_data);
726
727 /* check for I2C NACK status */
728 if (mxl111sf_i2c_check_status(state) == 1) {
729 mxl_i2c("NACK reading slave address %02x",
730 msg->addr);
731
732 /* if NACK, stop I2C bus and exit */
733 buf[2] = I2C_CONTROL_REG;
734 buf[3] = 0xC7;
735 buf[4] = (HWI2C400) ? 0x03 : 0x0D;
736 ret = -EIO;
737 goto exit;
738 }
739
740 for (i = 0; i < left_over_len; i++) {
741 msg->buf[(block_len*8)+i] =
742 i2c_r_data[(i*3)+1];
743 mxl_i2c("read data: %02x\t %02x",
744 i2c_r_data[(i*3)+1],
745 i2c_r_data[(i*3)+2]);
746 }
747 }
748
749 /* indicate I2C interface to issue NACK
750 after next I2C read op */
751 buf[0] = USB_WRITE_I2C_CMD;
752 buf[1] = 0x00;
753
754 /* control register */
755 buf[2] = I2C_CONTROL_REG;
756 buf[3] = 0x17;
757 buf[4] = (HWI2C400) ? 0x03 : 0x0D;
758
759 buf[5] = USB_END_I2C_CMD;
760 ret = mxl111sf_i2c_send_data(state, 0, buf);
761
762 /* control register */
763 buf[2] = I2C_CONTROL_REG;
764 buf[3] = 0xC7;
765 buf[4] = (HWI2C400) ? 0x03 : 0x0D;
766
767 }
768exit:
769 /* STOP and disable I2C MUX */
770 buf[0] = USB_WRITE_I2C_CMD;
771 buf[1] = 0x00;
772
773 /* de-initilize I2C BUS */
774 buf[5] = USB_END_I2C_CMD;
775 mxl111sf_i2c_send_data(state, 0, buf);
776
777 /* Control Register */
778 buf[2] = I2C_CONTROL_REG;
779 buf[3] = 0xDF;
780 buf[4] = 0x03;
781
782 /* disable I2C interface */
783 buf[5] = I2C_MUX_REG;
784 buf[6] = 0x00;
785 buf[7] = 0x00;
786
787 /* de-initilize I2C BUS */
788 buf[8] = USB_END_I2C_CMD;
789 mxl111sf_i2c_send_data(state, 0, buf);
790
791 /* disable I2C interface */
792 buf[2] = I2C_MUX_REG;
793 buf[3] = 0x81;
794 buf[4] = 0x00;
795
796 /* disable I2C interface */
797 buf[5] = I2C_MUX_REG;
798 buf[6] = 0x00;
799 buf[7] = 0x00;
800
801 /* disable I2C interface */
802 buf[8] = I2C_MUX_REG;
803 buf[9] = 0x00;
804 buf[10] = 0x00;
805
806 buf[11] = USB_END_I2C_CMD;
807 mxl111sf_i2c_send_data(state, 0, buf);
808
809 return ret;
810}
811
812/* ------------------------------------------------------------------------ */
813
814int mxl111sf_i2c_xfer(struct i2c_adapter *adap,
815 struct i2c_msg msg[], int num)
816{
817 struct dvb_usb_device *d = i2c_get_adapdata(adap);
818 struct mxl111sf_state *state = d->priv;
819 int hwi2c = (state->chip_rev > MXL111SF_V6);
820 int i, ret;
821
822 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
823 return -EAGAIN;
824
825 for (i = 0; i < num; i++) {
826 ret = (hwi2c) ?
827 mxl111sf_i2c_hw_xfer_msg(state, &msg[i]) :
828 mxl111sf_i2c_sw_xfer_msg(state, &msg[i]);
829 if (mxl_fail(ret)) {
830 mxl_debug_adv("failed with error %d on i2c "
831 "transaction %d of %d, %sing %d bytes "
832 "to/from 0x%02x", ret, i+1, num,
833 (msg[i].flags & I2C_M_RD) ?
834 "read" : "writ",
835 msg[i].len, msg[i].addr);
836
837 break;
838 }
839 }
840
841 mutex_unlock(&d->i2c_mutex);
842
843 return i == num ? num : -EREMOTEIO;
844}
845
846/*
847 * Local variables:
848 * c-basic-offset: 8
849 * End:
850 */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h
new file mode 100644
index 000000000000..a57a45ffb9e4
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h
@@ -0,0 +1,35 @@
1/*
2 * mxl111sf-i2c.h - driver for the MaxLinear MXL111SF
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef _DVB_USB_MXL111SF_I2C_H_
22#define _DVB_USB_MXL111SF_I2C_H_
23
24#include <linux/i2c.h>
25
26int mxl111sf_i2c_xfer(struct i2c_adapter *adap,
27 struct i2c_msg msg[], int num);
28
29#endif /* _DVB_USB_MXL111SF_I2C_H_ */
30
31/*
32 * Local variables:
33 * c-basic-offset: 8
34 * End:
35 */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c
new file mode 100644
index 000000000000..b741b3a7a325
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c
@@ -0,0 +1,343 @@
1/*
2 * mxl111sf-phy.c - driver for the MaxLinear MXL111SF
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "mxl111sf-phy.h"
22#include "mxl111sf-reg.h"
23
24int mxl111sf_init_tuner_demod(struct mxl111sf_state *state)
25{
26 struct mxl111sf_reg_ctrl_info mxl_111_overwrite_default[] = {
27 {0x07, 0xff, 0x0c},
28 {0x58, 0xff, 0x9d},
29 {0x09, 0xff, 0x00},
30 {0x06, 0xff, 0x06},
31 {0xc8, 0xff, 0x40}, /* ED_LE_WIN_OLD = 0 */
32 {0x8d, 0x01, 0x01}, /* NEGATE_Q */
33 {0x32, 0xff, 0xac}, /* DIG_RFREFSELECT = 12 */
34 {0x42, 0xff, 0x43}, /* DIG_REG_AMP = 4 */
35 {0x74, 0xff, 0xc4}, /* SSPUR_FS_PRIO = 4 */
36 {0x71, 0xff, 0xe6}, /* SPUR_ROT_PRIO_VAL = 1 */
37 {0x83, 0xff, 0x64}, /* INF_FILT1_THD_SC = 100 */
38 {0x85, 0xff, 0x64}, /* INF_FILT2_THD_SC = 100 */
39 {0x88, 0xff, 0xf0}, /* INF_THD = 240 */
40 {0x6f, 0xf0, 0xb0}, /* DFE_DLY = 11 */
41 {0x00, 0xff, 0x01}, /* Change to page 1 */
42 {0x81, 0xff, 0x11}, /* DSM_FERR_BYPASS = 1 */
43 {0xf4, 0xff, 0x07}, /* DIG_FREQ_CORR = 1 */
44 {0xd4, 0x1f, 0x0f}, /* SPUR_TEST_NOISE_TH = 15 */
45 {0xd6, 0xff, 0x0c}, /* SPUR_TEST_NOISE_PAPR = 12 */
46 {0x00, 0xff, 0x00}, /* Change to page 0 */
47 {0, 0, 0}
48 };
49
50 mxl_debug("()");
51
52 return mxl111sf_ctrl_program_regs(state, mxl_111_overwrite_default);
53}
54
55int mxl1x1sf_soft_reset(struct mxl111sf_state *state)
56{
57 int ret;
58 mxl_debug("()");
59
60 ret = mxl111sf_write_reg(state, 0xff, 0x00); /* AIC */
61 if (mxl_fail(ret))
62 goto fail;
63 ret = mxl111sf_write_reg(state, 0x02, 0x01); /* get out of reset */
64 mxl_fail(ret);
65fail:
66 return ret;
67}
68
69int mxl1x1sf_set_device_mode(struct mxl111sf_state *state, int mode)
70{
71 int ret;
72
73 mxl_debug("(%s)", MXL_SOC_MODE == mode ?
74 "MXL_SOC_MODE" : "MXL_TUNER_MODE");
75
76 /* set device mode */
77 ret = mxl111sf_write_reg(state, 0x03,
78 MXL_SOC_MODE == mode ? 0x01 : 0x00);
79 if (mxl_fail(ret))
80 goto fail;
81
82 ret = mxl111sf_write_reg_mask(state,
83 0x7d, 0x40, MXL_SOC_MODE == mode ?
84 0x00 : /* enable impulse noise filter,
85 INF_BYP = 0 */
86 0x40); /* disable impulse noise filter,
87 INF_BYP = 1 */
88 if (mxl_fail(ret))
89 goto fail;
90
91 state->device_mode = mode;
92fail:
93 return ret;
94}
95
96/* power up tuner */
97int mxl1x1sf_top_master_ctrl(struct mxl111sf_state *state, int onoff)
98{
99 mxl_debug("(%d)", onoff);
100
101 return mxl111sf_write_reg(state, 0x01, onoff ? 0x01 : 0x00);
102}
103
104int mxl111sf_disable_656_port(struct mxl111sf_state *state)
105{
106 mxl_debug("()");
107
108 return mxl111sf_write_reg_mask(state, 0x12, 0x04, 0x00);
109}
110
111int mxl111sf_enable_usb_output(struct mxl111sf_state *state)
112{
113 mxl_debug("()");
114
115 return mxl111sf_write_reg_mask(state, 0x17, 0x40, 0x00);
116}
117
118/* initialize TSIF as input port of MxL1X1SF for MPEG2 data transfer */
119int mxl111sf_config_mpeg_in(struct mxl111sf_state *state,
120 unsigned int parallel_serial,
121 unsigned int msb_lsb_1st,
122 unsigned int clock_phase,
123 unsigned int mpeg_valid_pol,
124 unsigned int mpeg_sync_pol)
125{
126 int ret;
127 u8 mode, tmp;
128
129 mxl_debug("(%u,%u,%u,%u,%u)", parallel_serial, msb_lsb_1st,
130 clock_phase, mpeg_valid_pol, mpeg_sync_pol);
131
132 /* Enable PIN MUX */
133 ret = mxl111sf_write_reg(state, V6_PIN_MUX_MODE_REG, V6_ENABLE_PIN_MUX);
134 mxl_fail(ret);
135
136 /* Configure MPEG Clock phase */
137 mxl111sf_read_reg(state, V6_MPEG_IN_CLK_INV_REG, &mode);
138
139 if (clock_phase == TSIF_NORMAL)
140 mode &= ~V6_INVERTED_CLK_PHASE;
141 else
142 mode |= V6_INVERTED_CLK_PHASE;
143
144 ret = mxl111sf_write_reg(state, V6_MPEG_IN_CLK_INV_REG, mode);
145 mxl_fail(ret);
146
147 /* Configure data input mode, MPEG Valid polarity, MPEG Sync polarity
148 * Get current configuration */
149 ret = mxl111sf_read_reg(state, V6_MPEG_IN_CTRL_REG, &mode);
150 mxl_fail(ret);
151
152 /* Data Input mode */
153 if (parallel_serial == TSIF_INPUT_PARALLEL) {
154 /* Disable serial mode */
155 mode &= ~V6_MPEG_IN_DATA_SERIAL;
156
157 /* Enable Parallel mode */
158 mode |= V6_MPEG_IN_DATA_PARALLEL;
159 } else {
160 /* Disable Parallel mode */
161 mode &= ~V6_MPEG_IN_DATA_PARALLEL;
162
163 /* Enable Serial Mode */
164 mode |= V6_MPEG_IN_DATA_SERIAL;
165
166 /* If serial interface is chosen, configure
167 MSB or LSB order in transmission */
168 ret = mxl111sf_read_reg(state,
169 V6_MPEG_INOUT_BIT_ORDER_CTRL_REG,
170 &tmp);
171 mxl_fail(ret);
172
173 if (msb_lsb_1st == MPEG_SER_MSB_FIRST_ENABLED)
174 tmp |= V6_MPEG_SER_MSB_FIRST;
175 else
176 tmp &= ~V6_MPEG_SER_MSB_FIRST;
177
178 ret = mxl111sf_write_reg(state,
179 V6_MPEG_INOUT_BIT_ORDER_CTRL_REG,
180 tmp);
181 mxl_fail(ret);
182 }
183
184 /* MPEG Sync polarity */
185 if (mpeg_sync_pol == TSIF_NORMAL)
186 mode &= ~V6_INVERTED_MPEG_SYNC;
187 else
188 mode |= V6_INVERTED_MPEG_SYNC;
189
190 /* MPEG Valid polarity */
191 if (mpeg_valid_pol == 0)
192 mode &= ~V6_INVERTED_MPEG_VALID;
193 else
194 mode |= V6_INVERTED_MPEG_VALID;
195
196 ret = mxl111sf_write_reg(state, V6_MPEG_IN_CTRL_REG, mode);
197 mxl_fail(ret);
198
199 return ret;
200}
201
202int mxl111sf_init_i2s_port(struct mxl111sf_state *state, u8 sample_size)
203{
204 static struct mxl111sf_reg_ctrl_info init_i2s[] = {
205 {0x1b, 0xff, 0x1e}, /* pin mux mode, Choose 656/I2S input */
206 {0x15, 0x60, 0x60}, /* Enable I2S */
207 {0x17, 0xe0, 0x20}, /* Input, MPEG MODE USB,
208 Inverted 656 Clock, I2S_SOFT_RESET,
209 0 : Normal operation, 1 : Reset State */
210#if 0
211 {0x12, 0x01, 0x00}, /* AUDIO_IRQ_CLR (Overflow Indicator) */
212#endif
213 {0x00, 0xff, 0x02}, /* Change to Control Page */
214 {0x26, 0x0d, 0x0d}, /* I2S_MODE & BT656_SRC_SEL for FPGA only */
215 {0x00, 0xff, 0x00},
216 {0, 0, 0}
217 };
218 int ret;
219
220 mxl_debug("(0x%02x)", sample_size);
221
222 ret = mxl111sf_ctrl_program_regs(state, init_i2s);
223 if (mxl_fail(ret))
224 goto fail;
225
226 ret = mxl111sf_write_reg(state, V6_I2S_NUM_SAMPLES_REG, sample_size);
227 mxl_fail(ret);
228fail:
229 return ret;
230}
231
232int mxl111sf_disable_i2s_port(struct mxl111sf_state *state)
233{
234 static struct mxl111sf_reg_ctrl_info disable_i2s[] = {
235 {0x15, 0x40, 0x00},
236 {0, 0, 0}
237 };
238
239 mxl_debug("()");
240
241 return mxl111sf_ctrl_program_regs(state, disable_i2s);
242}
243
244int mxl111sf_config_i2s(struct mxl111sf_state *state,
245 u8 msb_start_pos, u8 data_width)
246{
247 int ret;
248 u8 tmp;
249
250 mxl_debug("(0x%02x, 0x%02x)", msb_start_pos, data_width);
251
252 ret = mxl111sf_read_reg(state, V6_I2S_STREAM_START_BIT_REG, &tmp);
253 if (mxl_fail(ret))
254 goto fail;
255
256 tmp &= 0xe0;
257 tmp |= msb_start_pos;
258 ret = mxl111sf_write_reg(state, V6_I2S_STREAM_START_BIT_REG, tmp);
259 if (mxl_fail(ret))
260 goto fail;
261
262 ret = mxl111sf_read_reg(state, V6_I2S_STREAM_END_BIT_REG, &tmp);
263 if (mxl_fail(ret))
264 goto fail;
265
266 tmp &= 0xe0;
267 tmp |= data_width;
268 ret = mxl111sf_write_reg(state, V6_I2S_STREAM_END_BIT_REG, tmp);
269 mxl_fail(ret);
270fail:
271 return ret;
272}
273
274int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff)
275{
276 u8 val;
277 int ret;
278
279 mxl_debug("(%d)", onoff);
280
281 ret = mxl111sf_write_reg(state, 0x00, 0x02);
282 if (mxl_fail(ret))
283 goto fail;
284
285 ret = mxl111sf_read_reg(state, V8_SPI_MODE_REG, &val);
286 if (mxl_fail(ret))
287 goto fail;
288
289 if (onoff)
290 val |= 0x04;
291 else
292 val &= ~0x04;
293
294 ret = mxl111sf_write_reg(state, V8_SPI_MODE_REG, val);
295 if (mxl_fail(ret))
296 goto fail;
297
298 ret = mxl111sf_write_reg(state, 0x00, 0x00);
299 mxl_fail(ret);
300fail:
301 return ret;
302}
303
304int mxl111sf_idac_config(struct mxl111sf_state *state,
305 u8 control_mode, u8 current_setting,
306 u8 current_value, u8 hysteresis_value)
307{
308 int ret;
309 u8 val;
310 /* current value will be set for both automatic & manual IDAC control */
311 val = current_value;
312
313 if (control_mode == IDAC_MANUAL_CONTROL) {
314 /* enable manual control of IDAC */
315 val |= IDAC_MANUAL_CONTROL_BIT_MASK;
316
317 if (current_setting == IDAC_CURRENT_SINKING_ENABLE)
318 /* enable current sinking in manual mode */
319 val |= IDAC_CURRENT_SINKING_BIT_MASK;
320 else
321 /* disable current sinking in manual mode */
322 val &= ~IDAC_CURRENT_SINKING_BIT_MASK;
323 } else {
324 /* disable manual control of IDAC */
325 val &= ~IDAC_MANUAL_CONTROL_BIT_MASK;
326
327 /* set hysteresis value reg: 0x0B<5:0> */
328 ret = mxl111sf_write_reg(state, V6_IDAC_HYSTERESIS_REG,
329 (hysteresis_value & 0x3F));
330 mxl_fail(ret);
331 }
332
333 ret = mxl111sf_write_reg(state, V6_IDAC_SETTINGS_REG, val);
334 mxl_fail(ret);
335
336 return ret;
337}
338
339/*
340 * Local variables:
341 * c-basic-offset: 8
342 * End:
343 */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h
new file mode 100644
index 000000000000..f0756071d347
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h
@@ -0,0 +1,53 @@
1/*
2 * mxl111sf-phy.h - driver for the MaxLinear MXL111SF
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef _DVB_USB_MXL111SF_PHY_H_
22#define _DVB_USB_MXL111SF_PHY_H_
23
24#include "mxl111sf.h"
25
26int mxl1x1sf_soft_reset(struct mxl111sf_state *state);
27int mxl1x1sf_set_device_mode(struct mxl111sf_state *state, int mode);
28int mxl1x1sf_top_master_ctrl(struct mxl111sf_state *state, int onoff);
29int mxl111sf_disable_656_port(struct mxl111sf_state *state);
30int mxl111sf_init_tuner_demod(struct mxl111sf_state *state);
31int mxl111sf_enable_usb_output(struct mxl111sf_state *state);
32int mxl111sf_config_mpeg_in(struct mxl111sf_state *state,
33 unsigned int parallel_serial,
34 unsigned int msb_lsb_1st,
35 unsigned int clock_phase,
36 unsigned int mpeg_valid_pol,
37 unsigned int mpeg_sync_pol);
38int mxl111sf_config_i2s(struct mxl111sf_state *state,
39 u8 msb_start_pos, u8 data_width);
40int mxl111sf_init_i2s_port(struct mxl111sf_state *state, u8 sample_size);
41int mxl111sf_disable_i2s_port(struct mxl111sf_state *state);
42int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff);
43int mxl111sf_idac_config(struct mxl111sf_state *state,
44 u8 control_mode, u8 current_setting,
45 u8 current_value, u8 hysteresis_value);
46
47#endif /* _DVB_USB_MXL111SF_PHY_H_ */
48
49/*
50 * Local variables:
51 * c-basic-offset: 8
52 * End:
53 */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h
new file mode 100644
index 000000000000..17831b0fb9db
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h
@@ -0,0 +1,179 @@
1/*
2 * mxl111sf-reg.h - driver for the MaxLinear MXL111SF
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef _DVB_USB_MXL111SF_REG_H_
22#define _DVB_USB_MXL111SF_REG_H_
23
24#define CHIP_ID_REG 0xFC
25#define TOP_CHIP_REV_ID_REG 0xFA
26
27#define V6_SNR_RB_LSB_REG 0x27
28#define V6_SNR_RB_MSB_REG 0x28
29
30#define V6_N_ACCUMULATE_REG 0x11
31#define V6_RS_AVG_ERRORS_LSB_REG 0x2C
32#define V6_RS_AVG_ERRORS_MSB_REG 0x2D
33
34#define V6_IRQ_STATUS_REG 0x24
35#define IRQ_MASK_FEC_LOCK 0x10
36
37#define V6_SYNC_LOCK_REG 0x28
38#define SYNC_LOCK_MASK 0x10
39
40#define V6_RS_LOCK_DET_REG 0x28
41#define RS_LOCK_DET_MASK 0x08
42
43#define V6_INITACQ_NODETECT_REG 0x20
44#define V6_FORCE_NFFT_CPSIZE_REG 0x20
45
46#define V6_CODE_RATE_TPS_REG 0x29
47#define V6_CODE_RATE_TPS_MASK 0x07
48
49
50#define V6_CP_LOCK_DET_REG 0x28
51#define V6_CP_LOCK_DET_MASK 0x04
52
53#define V6_TPS_HIERACHY_REG 0x29
54#define V6_TPS_HIERARCHY_INFO_MASK 0x40
55
56#define V6_MODORDER_TPS_REG 0x2A
57#define V6_PARAM_CONSTELLATION_MASK 0x30
58
59#define V6_MODE_TPS_REG 0x2A
60#define V6_PARAM_FFT_MODE_MASK 0x0C
61
62
63#define V6_CP_TPS_REG 0x29
64#define V6_PARAM_GI_MASK 0x30
65
66#define V6_TPS_LOCK_REG 0x2A
67#define V6_PARAM_TPS_LOCK_MASK 0x40
68
69#define V6_FEC_PER_COUNT_REG 0x2E
70#define V6_FEC_PER_SCALE_REG 0x2B
71#define V6_FEC_PER_SCALE_MASK 0x03
72#define V6_FEC_PER_CLR_REG 0x20
73#define V6_FEC_PER_CLR_MASK 0x01
74
75#define V6_PIN_MUX_MODE_REG 0x1B
76#define V6_ENABLE_PIN_MUX 0x1E
77
78#define V6_I2S_NUM_SAMPLES_REG 0x16
79
80#define V6_MPEG_IN_CLK_INV_REG 0x17
81#define V6_MPEG_IN_CTRL_REG 0x18
82
83#define V6_INVERTED_CLK_PHASE 0x20
84#define V6_MPEG_IN_DATA_PARALLEL 0x01
85#define V6_MPEG_IN_DATA_SERIAL 0x02
86
87#define V6_INVERTED_MPEG_SYNC 0x04
88#define V6_INVERTED_MPEG_VALID 0x08
89
90#define TSIF_INPUT_PARALLEL 0
91#define TSIF_INPUT_SERIAL 1
92#define TSIF_NORMAL 0
93
94#define V6_MPEG_INOUT_BIT_ORDER_CTRL_REG 0x19
95#define V6_MPEG_SER_MSB_FIRST 0x80
96#define MPEG_SER_MSB_FIRST_ENABLED 0x01
97
98#define V6_656_I2S_BUFF_STATUS_REG 0x2F
99#define V6_656_OVERFLOW_MASK_BIT 0x08
100#define V6_I2S_OVERFLOW_MASK_BIT 0x01
101
102#define V6_I2S_STREAM_START_BIT_REG 0x14
103#define V6_I2S_STREAM_END_BIT_REG 0x15
104#define I2S_RIGHT_JUSTIFIED 0
105#define I2S_LEFT_JUSTIFIED 1
106#define I2S_DATA_FORMAT 2
107
108#define V6_TUNER_LOOP_THRU_CONTROL_REG 0x09
109#define V6_ENABLE_LOOP_THRU 0x01
110
111#define TOTAL_NUM_IF_OUTPUT_FREQ 16
112
113#define TUNER_NORMAL_IF_SPECTRUM 0x0
114#define TUNER_INVERT_IF_SPECTRUM 0x10
115
116#define V6_TUNER_IF_SEL_REG 0x06
117#define V6_TUNER_IF_FCW_REG 0x3C
118#define V6_TUNER_IF_FCW_BYP_REG 0x3D
119#define V6_RF_LOCK_STATUS_REG 0x23
120
121#define NUM_DIG_TV_CHANNEL 1000
122
123#define V6_DIG_CLK_FREQ_SEL_REG 0x07
124#define V6_REF_SYNTH_INT_REG 0x5C
125#define V6_REF_SYNTH_REMAIN_REG 0x58
126#define V6_DIG_RFREFSELECT_REG 0x32
127#define V6_XTAL_CLK_OUT_GAIN_REG 0x31
128#define V6_TUNER_LOOP_THRU_CTRL_REG 0x09
129#define V6_DIG_XTAL_ENABLE_REG 0x06
130#define V6_DIG_XTAL_BIAS_REG 0x66
131#define V6_XTAL_CAP_REG 0x08
132
133#define V6_GPO_CTRL_REG 0x18
134#define MXL_GPO_0 0x00
135#define MXL_GPO_1 0x01
136#define V6_GPO_0_MASK 0x10
137#define V6_GPO_1_MASK 0x20
138
139#define V6_111SF_GPO_CTRL_REG 0x19
140#define MXL_111SF_GPO_1 0x00
141#define MXL_111SF_GPO_2 0x01
142#define MXL_111SF_GPO_3 0x02
143#define MXL_111SF_GPO_4 0x03
144#define MXL_111SF_GPO_5 0x04
145#define MXL_111SF_GPO_6 0x05
146#define MXL_111SF_GPO_7 0x06
147
148#define MXL_111SF_GPO_0_MASK 0x01
149#define MXL_111SF_GPO_1_MASK 0x02
150#define MXL_111SF_GPO_2_MASK 0x04
151#define MXL_111SF_GPO_3_MASK 0x08
152#define MXL_111SF_GPO_4_MASK 0x10
153#define MXL_111SF_GPO_5_MASK 0x20
154#define MXL_111SF_GPO_6_MASK 0x40
155
156#define V6_ATSC_CONFIG_REG 0x0A
157
158#define MXL_MODE_REG 0x03
159#define START_TUNE_REG 0x1C
160
161#define V6_IDAC_HYSTERESIS_REG 0x0B
162#define V6_IDAC_SETTINGS_REG 0x0C
163#define IDAC_MANUAL_CONTROL 1
164#define IDAC_CURRENT_SINKING_ENABLE 1
165#define IDAC_MANUAL_CONTROL_BIT_MASK 0x80
166#define IDAC_CURRENT_SINKING_BIT_MASK 0x40
167
168#define V8_SPI_MODE_REG 0xE9
169
170#define V6_DIG_RF_PWR_LSB_REG 0x46
171#define V6_DIG_RF_PWR_MSB_REG 0x47
172
173#endif /* _DVB_USB_MXL111SF_REG_H_ */
174
175/*
176 * Local variables:
177 * c-basic-offset: 8
178 * End:
179 */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
new file mode 100644
index 000000000000..ef4c65fcbb73
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
@@ -0,0 +1,527 @@
1/*
2 * mxl111sf-tuner.c - driver for the MaxLinear MXL111SF CMOS tuner
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "mxl111sf-tuner.h"
22#include "mxl111sf-phy.h"
23#include "mxl111sf-reg.h"
24
25/* debug */
26static int mxl111sf_tuner_debug;
27module_param_named(debug, mxl111sf_tuner_debug, int, 0644);
28MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
29
30#define mxl_dbg(fmt, arg...) \
31 if (mxl111sf_tuner_debug) \
32 mxl_printk(KERN_DEBUG, fmt, ##arg)
33
34#define err pr_err
35
36/* ------------------------------------------------------------------------ */
37
38struct mxl111sf_tuner_state {
39 struct mxl111sf_state *mxl_state;
40
41 struct mxl111sf_tuner_config *cfg;
42
43 enum mxl_if_freq if_freq;
44
45 u32 frequency;
46 u32 bandwidth;
47};
48
49static int mxl111sf_tuner_read_reg(struct mxl111sf_tuner_state *state,
50 u8 addr, u8 *data)
51{
52 return (state->cfg->read_reg) ?
53 state->cfg->read_reg(state->mxl_state, addr, data) :
54 -EINVAL;
55}
56
57static int mxl111sf_tuner_write_reg(struct mxl111sf_tuner_state *state,
58 u8 addr, u8 data)
59{
60 return (state->cfg->write_reg) ?
61 state->cfg->write_reg(state->mxl_state, addr, data) :
62 -EINVAL;
63}
64
65static int mxl111sf_tuner_program_regs(struct mxl111sf_tuner_state *state,
66 struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
67{
68 return (state->cfg->program_regs) ?
69 state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
70 -EINVAL;
71}
72
73static int mxl1x1sf_tuner_top_master_ctrl(struct mxl111sf_tuner_state *state,
74 int onoff)
75{
76 return (state->cfg->top_master_ctrl) ?
77 state->cfg->top_master_ctrl(state->mxl_state, onoff) :
78 -EINVAL;
79}
80
81/* ------------------------------------------------------------------------ */
82
83static struct mxl111sf_reg_ctrl_info mxl_phy_tune_rf[] = {
84 {0x1d, 0x7f, 0x00}, /* channel bandwidth section 1/2/3,
85 DIG_MODEINDEX, _A, _CSF, */
86 {0x1e, 0xff, 0x00}, /* channel frequency (lo and fractional) */
87 {0x1f, 0xff, 0x00}, /* channel frequency (hi for integer portion) */
88 {0, 0, 0}
89};
90
91/* ------------------------------------------------------------------------ */
92
93static struct mxl111sf_reg_ctrl_info *mxl111sf_calc_phy_tune_regs(u32 freq,
94 u8 bw)
95{
96 u8 filt_bw;
97
98 /* set channel bandwidth */
99 switch (bw) {
100 case 0: /* ATSC */
101 filt_bw = 25;
102 break;
103 case 1: /* QAM */
104 filt_bw = 69;
105 break;
106 case 6:
107 filt_bw = 21;
108 break;
109 case 7:
110 filt_bw = 42;
111 break;
112 case 8:
113 filt_bw = 63;
114 break;
115 default:
116 err("%s: invalid bandwidth setting!", __func__);
117 return NULL;
118 }
119
120 /* calculate RF channel */
121 freq /= 1000000;
122
123 freq *= 64;
124#if 0
125 /* do round */
126 freq += 0.5;
127#endif
128 /* set bandwidth */
129 mxl_phy_tune_rf[0].data = filt_bw;
130
131 /* set RF */
132 mxl_phy_tune_rf[1].data = (freq & 0xff);
133 mxl_phy_tune_rf[2].data = (freq >> 8) & 0xff;
134
135 /* start tune */
136 return mxl_phy_tune_rf;
137}
138
139static int mxl1x1sf_tuner_set_if_output_freq(struct mxl111sf_tuner_state *state)
140{
141 int ret;
142 u8 ctrl;
143#if 0
144 u16 iffcw;
145 u32 if_freq;
146#endif
147 mxl_dbg("(IF polarity = %d, IF freq = 0x%02x)",
148 state->cfg->invert_spectrum, state->cfg->if_freq);
149
150 /* set IF polarity */
151 ctrl = state->cfg->invert_spectrum;
152
153 ctrl |= state->cfg->if_freq;
154
155 ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_SEL_REG, ctrl);
156 if (mxl_fail(ret))
157 goto fail;
158
159#if 0
160 if_freq /= 1000000;
161
162 /* do round */
163 if_freq += 0.5;
164
165 if (MXL_IF_LO == state->cfg->if_freq) {
166 ctrl = 0x08;
167 iffcw = (u16)(if_freq / (108 * 4096));
168 } else if (MXL_IF_HI == state->cfg->if_freq) {
169 ctrl = 0x08;
170 iffcw = (u16)(if_freq / (216 * 4096));
171 } else {
172 ctrl = 0;
173 iffcw = 0;
174 }
175
176 ctrl |= (iffcw >> 8);
177#endif
178 ret = mxl111sf_tuner_read_reg(state, V6_TUNER_IF_FCW_BYP_REG, &ctrl);
179 if (mxl_fail(ret))
180 goto fail;
181
182 ctrl &= 0xf0;
183 ctrl |= 0x90;
184
185 ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_BYP_REG, ctrl);
186 if (mxl_fail(ret))
187 goto fail;
188
189#if 0
190 ctrl = iffcw & 0x00ff;
191#endif
192 ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_REG, ctrl);
193 if (mxl_fail(ret))
194 goto fail;
195
196 state->if_freq = state->cfg->if_freq;
197fail:
198 return ret;
199}
200
201static int mxl1x1sf_tune_rf(struct dvb_frontend *fe, u32 freq, u8 bw)
202{
203 struct mxl111sf_tuner_state *state = fe->tuner_priv;
204 static struct mxl111sf_reg_ctrl_info *reg_ctrl_array;
205 int ret;
206 u8 mxl_mode;
207
208 mxl_dbg("(freq = %d, bw = 0x%x)", freq, bw);
209
210 /* stop tune */
211 ret = mxl111sf_tuner_write_reg(state, START_TUNE_REG, 0);
212 if (mxl_fail(ret))
213 goto fail;
214
215 /* check device mode */
216 ret = mxl111sf_tuner_read_reg(state, MXL_MODE_REG, &mxl_mode);
217 if (mxl_fail(ret))
218 goto fail;
219
220 /* Fill out registers for channel tune */
221 reg_ctrl_array = mxl111sf_calc_phy_tune_regs(freq, bw);
222 if (!reg_ctrl_array)
223 return -EINVAL;
224
225 ret = mxl111sf_tuner_program_regs(state, reg_ctrl_array);
226 if (mxl_fail(ret))
227 goto fail;
228
229 if ((mxl_mode & MXL_DEV_MODE_MASK) == MXL_TUNER_MODE) {
230 /* IF tuner mode only */
231 mxl1x1sf_tuner_top_master_ctrl(state, 0);
232 mxl1x1sf_tuner_top_master_ctrl(state, 1);
233 mxl1x1sf_tuner_set_if_output_freq(state);
234 }
235
236 ret = mxl111sf_tuner_write_reg(state, START_TUNE_REG, 1);
237 if (mxl_fail(ret))
238 goto fail;
239
240 if (state->cfg->ant_hunt)
241 state->cfg->ant_hunt(fe);
242fail:
243 return ret;
244}
245
246static int mxl1x1sf_tuner_get_lock_status(struct mxl111sf_tuner_state *state,
247 int *rf_synth_lock,
248 int *ref_synth_lock)
249{
250 int ret;
251 u8 data;
252
253 *rf_synth_lock = 0;
254 *ref_synth_lock = 0;
255
256 ret = mxl111sf_tuner_read_reg(state, V6_RF_LOCK_STATUS_REG, &data);
257 if (mxl_fail(ret))
258 goto fail;
259
260 *ref_synth_lock = ((data & 0x03) == 0x03) ? 1 : 0;
261 *rf_synth_lock = ((data & 0x0c) == 0x0c) ? 1 : 0;
262fail:
263 return ret;
264}
265
266#if 0
267static int mxl1x1sf_tuner_loop_thru_ctrl(struct mxl111sf_tuner_state *state,
268 int onoff)
269{
270 return mxl111sf_tuner_write_reg(state, V6_TUNER_LOOP_THRU_CTRL_REG,
271 onoff ? 1 : 0);
272}
273#endif
274
275/* ------------------------------------------------------------------------ */
276
277static int mxl111sf_tuner_set_params(struct dvb_frontend *fe)
278{
279 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
280 u32 delsys = c->delivery_system;
281 struct mxl111sf_tuner_state *state = fe->tuner_priv;
282 int ret;
283 u8 bw;
284
285 mxl_dbg("()");
286
287 switch (delsys) {
288 case SYS_ATSC:
289 case SYS_ATSCMH:
290 bw = 0; /* ATSC */
291 break;
292 case SYS_DVBC_ANNEX_B:
293 bw = 1; /* US CABLE */
294 break;
295 case SYS_DVBT:
296 switch (c->bandwidth_hz) {
297 case 6000000:
298 bw = 6;
299 break;
300 case 7000000:
301 bw = 7;
302 break;
303 case 8000000:
304 bw = 8;
305 break;
306 default:
307 err("%s: bandwidth not set!", __func__);
308 return -EINVAL;
309 }
310 break;
311 default:
312 err("%s: modulation type not supported!", __func__);
313 return -EINVAL;
314 }
315 ret = mxl1x1sf_tune_rf(fe, c->frequency, bw);
316 if (mxl_fail(ret))
317 goto fail;
318
319 state->frequency = c->frequency;
320 state->bandwidth = c->bandwidth_hz;
321fail:
322 return ret;
323}
324
325/* ------------------------------------------------------------------------ */
326
327#if 0
328static int mxl111sf_tuner_init(struct dvb_frontend *fe)
329{
330 struct mxl111sf_tuner_state *state = fe->tuner_priv;
331 int ret;
332
333 /* wake from standby handled by usb driver */
334
335 return ret;
336}
337
338static int mxl111sf_tuner_sleep(struct dvb_frontend *fe)
339{
340 struct mxl111sf_tuner_state *state = fe->tuner_priv;
341 int ret;
342
343 /* enter standby mode handled by usb driver */
344
345 return ret;
346}
347#endif
348
349/* ------------------------------------------------------------------------ */
350
351static int mxl111sf_tuner_get_status(struct dvb_frontend *fe, u32 *status)
352{
353 struct mxl111sf_tuner_state *state = fe->tuner_priv;
354 int rf_locked, ref_locked, ret;
355
356 *status = 0;
357
358 ret = mxl1x1sf_tuner_get_lock_status(state, &rf_locked, &ref_locked);
359 if (mxl_fail(ret))
360 goto fail;
361 mxl_info("%s%s", rf_locked ? "rf locked " : "",
362 ref_locked ? "ref locked" : "");
363
364 if ((rf_locked) || (ref_locked))
365 *status |= TUNER_STATUS_LOCKED;
366fail:
367 return ret;
368}
369
370static int mxl111sf_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
371{
372 struct mxl111sf_tuner_state *state = fe->tuner_priv;
373 u8 val1, val2;
374 int ret;
375
376 *strength = 0;
377
378 ret = mxl111sf_tuner_write_reg(state, 0x00, 0x02);
379 if (mxl_fail(ret))
380 goto fail;
381 ret = mxl111sf_tuner_read_reg(state, V6_DIG_RF_PWR_LSB_REG, &val1);
382 if (mxl_fail(ret))
383 goto fail;
384 ret = mxl111sf_tuner_read_reg(state, V6_DIG_RF_PWR_MSB_REG, &val2);
385 if (mxl_fail(ret))
386 goto fail;
387
388 *strength = val1 | ((val2 & 0x07) << 8);
389fail:
390 ret = mxl111sf_tuner_write_reg(state, 0x00, 0x00);
391 mxl_fail(ret);
392
393 return ret;
394}
395
396/* ------------------------------------------------------------------------ */
397
398static int mxl111sf_tuner_get_frequency(struct dvb_frontend *fe, u32 *frequency)
399{
400 struct mxl111sf_tuner_state *state = fe->tuner_priv;
401 *frequency = state->frequency;
402 return 0;
403}
404
405static int mxl111sf_tuner_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
406{
407 struct mxl111sf_tuner_state *state = fe->tuner_priv;
408 *bandwidth = state->bandwidth;
409 return 0;
410}
411
412static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend *fe,
413 u32 *frequency)
414{
415 struct mxl111sf_tuner_state *state = fe->tuner_priv;
416
417 *frequency = 0;
418
419 switch (state->if_freq) {
420 case MXL_IF_4_0: /* 4.0 MHz */
421 *frequency = 4000000;
422 break;
423 case MXL_IF_4_5: /* 4.5 MHz */
424 *frequency = 4500000;
425 break;
426 case MXL_IF_4_57: /* 4.57 MHz */
427 *frequency = 4570000;
428 break;
429 case MXL_IF_5_0: /* 5.0 MHz */
430 *frequency = 5000000;
431 break;
432 case MXL_IF_5_38: /* 5.38 MHz */
433 *frequency = 5380000;
434 break;
435 case MXL_IF_6_0: /* 6.0 MHz */
436 *frequency = 6000000;
437 break;
438 case MXL_IF_6_28: /* 6.28 MHz */
439 *frequency = 6280000;
440 break;
441 case MXL_IF_7_2: /* 7.2 MHz */
442 *frequency = 7200000;
443 break;
444 case MXL_IF_35_25: /* 35.25 MHz */
445 *frequency = 35250000;
446 break;
447 case MXL_IF_36: /* 36 MHz */
448 *frequency = 36000000;
449 break;
450 case MXL_IF_36_15: /* 36.15 MHz */
451 *frequency = 36150000;
452 break;
453 case MXL_IF_44: /* 44 MHz */
454 *frequency = 44000000;
455 break;
456 }
457 return 0;
458}
459
460static int mxl111sf_tuner_release(struct dvb_frontend *fe)
461{
462 struct mxl111sf_tuner_state *state = fe->tuner_priv;
463 mxl_dbg("()");
464 kfree(state);
465 fe->tuner_priv = NULL;
466 return 0;
467}
468
469/* ------------------------------------------------------------------------- */
470
471static struct dvb_tuner_ops mxl111sf_tuner_tuner_ops = {
472 .info = {
473 .name = "MaxLinear MxL111SF",
474#if 0
475 .frequency_min = ,
476 .frequency_max = ,
477 .frequency_step = ,
478#endif
479 },
480#if 0
481 .init = mxl111sf_tuner_init,
482 .sleep = mxl111sf_tuner_sleep,
483#endif
484 .set_params = mxl111sf_tuner_set_params,
485 .get_status = mxl111sf_tuner_get_status,
486 .get_rf_strength = mxl111sf_get_rf_strength,
487 .get_frequency = mxl111sf_tuner_get_frequency,
488 .get_bandwidth = mxl111sf_tuner_get_bandwidth,
489 .get_if_frequency = mxl111sf_tuner_get_if_frequency,
490 .release = mxl111sf_tuner_release,
491};
492
493struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
494 struct mxl111sf_state *mxl_state,
495 struct mxl111sf_tuner_config *cfg)
496{
497 struct mxl111sf_tuner_state *state = NULL;
498
499 mxl_dbg("()");
500
501 state = kzalloc(sizeof(struct mxl111sf_tuner_state), GFP_KERNEL);
502 if (state == NULL)
503 return NULL;
504
505 state->mxl_state = mxl_state;
506 state->cfg = cfg;
507
508 memcpy(&fe->ops.tuner_ops, &mxl111sf_tuner_tuner_ops,
509 sizeof(struct dvb_tuner_ops));
510
511 fe->tuner_priv = state;
512 return fe;
513}
514EXPORT_SYMBOL_GPL(mxl111sf_tuner_attach);
515
516MODULE_DESCRIPTION("MaxLinear MxL111SF CMOS tuner driver");
517MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
518MODULE_LICENSE("GPL");
519MODULE_VERSION("0.1");
520
521/*
522 * Overrides for Emacs so that we follow Linus's tabbing style.
523 * ---------------------------------------------------------------------------
524 * Local variables:
525 * c-basic-offset: 8
526 * End:
527 */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
new file mode 100644
index 000000000000..ff333960b184
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
@@ -0,0 +1,89 @@
1/*
2 * mxl111sf-tuner.h - driver for the MaxLinear MXL111SF CMOS tuner
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef __MXL111SF_TUNER_H__
22#define __MXL111SF_TUNER_H__
23
24#include "dvb_frontend.h"
25
26#include "mxl111sf.h"
27
28enum mxl_if_freq {
29#if 0
30 MXL_IF_LO = 0x00, /* other IF < 9MHz */
31#endif
32 MXL_IF_4_0 = 0x01, /* 4.0 MHz */
33 MXL_IF_4_5 = 0x02, /* 4.5 MHz */
34 MXL_IF_4_57 = 0x03, /* 4.57 MHz */
35 MXL_IF_5_0 = 0x04, /* 5.0 MHz */
36 MXL_IF_5_38 = 0x05, /* 5.38 MHz */
37 MXL_IF_6_0 = 0x06, /* 6.0 MHz */
38 MXL_IF_6_28 = 0x07, /* 6.28 MHz */
39 MXL_IF_7_2 = 0x08, /* 7.2 MHz */
40 MXL_IF_35_25 = 0x09, /* 35.25 MHz */
41 MXL_IF_36 = 0x0a, /* 36 MHz */
42 MXL_IF_36_15 = 0x0b, /* 36.15 MHz */
43 MXL_IF_44 = 0x0c, /* 44 MHz */
44#if 0
45 MXL_IF_HI = 0x0f, /* other IF > 35 MHz and < 45 MHz */
46#endif
47};
48
49struct mxl111sf_tuner_config {
50 enum mxl_if_freq if_freq;
51 unsigned int invert_spectrum:1;
52
53 int (*read_reg)(struct mxl111sf_state *state, u8 addr, u8 *data);
54 int (*write_reg)(struct mxl111sf_state *state, u8 addr, u8 data);
55 int (*program_regs)(struct mxl111sf_state *state,
56 struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
57 int (*top_master_ctrl)(struct mxl111sf_state *state, int onoff);
58 int (*ant_hunt)(struct dvb_frontend *fe);
59};
60
61/* ------------------------------------------------------------------------ */
62
63#if defined(CONFIG_DVB_USB_MXL111SF) || \
64 (defined(CONFIG_DVB_USB_MXL111SF_MODULE) && defined(MODULE))
65extern
66struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
67 struct mxl111sf_state *mxl_state,
68 struct mxl111sf_tuner_config *cfg);
69#else
70static inline
71struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
72 struct mxl111sf_state *mxl_state
73 struct mxl111sf_tuner_config *cfg)
74{
75 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
76 return NULL;
77}
78#endif
79
80#endif /* __MXL111SF_TUNER_H__ */
81
82/*
83 * Overrides for Emacs so that we follow Linus's tabbing style.
84 * ---------------------------------------------------------------------------
85 * Local variables:
86 * c-basic-offset: 8
87 * End:
88 */
89
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.c b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
new file mode 100644
index 000000000000..efdcb15358f1
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
@@ -0,0 +1,1431 @@
1/*
2 * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com)
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation, version 2.
7 *
8 * see Documentation/dvb/README.dvb-usb for more information
9 */
10
11#include <linux/vmalloc.h>
12#include <linux/i2c.h>
13
14#include "mxl111sf.h"
15#include "mxl111sf-reg.h"
16#include "mxl111sf-phy.h"
17#include "mxl111sf-i2c.h"
18#include "mxl111sf-gpio.h"
19
20#include "mxl111sf-demod.h"
21#include "mxl111sf-tuner.h"
22
23#include "lgdt3305.h"
24#include "lg2160.h"
25
26int dvb_usb_mxl111sf_debug;
27module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644);
28MODULE_PARM_DESC(debug, "set debugging level "
29 "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able)).");
30
31int dvb_usb_mxl111sf_isoc;
32module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644);
33MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc).");
34
35int dvb_usb_mxl111sf_spi;
36module_param_named(spi, dvb_usb_mxl111sf_spi, int, 0644);
37MODULE_PARM_DESC(spi, "use spi rather than tp for data xfer (0=tp, 1=spi).");
38
39#define ANT_PATH_AUTO 0
40#define ANT_PATH_EXTERNAL 1
41#define ANT_PATH_INTERNAL 2
42
43int dvb_usb_mxl111sf_rfswitch =
44#if 0
45 ANT_PATH_AUTO;
46#else
47 ANT_PATH_EXTERNAL;
48#endif
49
50module_param_named(rfswitch, dvb_usb_mxl111sf_rfswitch, int, 0644);
51MODULE_PARM_DESC(rfswitch, "force rf switch position (0=auto, 1=ext, 2=int).");
52
53DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
54
55#define deb_info pr_debug
56#define deb_reg pr_debug
57#define deb_adv pr_debug
58#define err pr_err
59#define info pr_info
60
61int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
62 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
63{
64 int wo = (rbuf == NULL || rlen == 0); /* write-only */
65 int ret;
66 u8 sndbuf[1+wlen];
67
68 deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
69
70 memset(sndbuf, 0, 1+wlen);
71
72 sndbuf[0] = cmd;
73 memcpy(&sndbuf[1], wbuf, wlen);
74
75 ret = (wo) ? dvb_usbv2_generic_write(d, sndbuf, 1+wlen) :
76 dvb_usbv2_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen);
77 mxl_fail(ret);
78
79 return ret;
80}
81
82/* ------------------------------------------------------------------------ */
83
84#define MXL_CMD_REG_READ 0xaa
85#define MXL_CMD_REG_WRITE 0x55
86
87int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data)
88{
89 u8 buf[2];
90 int ret;
91
92 ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_READ, &addr, 1, buf, 2);
93 if (mxl_fail(ret)) {
94 mxl_debug("error reading reg: 0x%02x", addr);
95 goto fail;
96 }
97
98 if (buf[0] == addr)
99 *data = buf[1];
100 else {
101 err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
102 addr, buf[0], buf[1]);
103 ret = -EINVAL;
104 }
105
106 deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data);
107fail:
108 return ret;
109}
110
111int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data)
112{
113 u8 buf[] = { addr, data };
114 int ret;
115
116 deb_reg("W: (0x%02x, 0x%02x)\n", addr, data);
117
118 ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
119 if (mxl_fail(ret))
120 err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
121 return ret;
122}
123
124/* ------------------------------------------------------------------------ */
125
126int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
127 u8 addr, u8 mask, u8 data)
128{
129 int ret;
130 u8 val;
131
132 if (mask != 0xff) {
133 ret = mxl111sf_read_reg(state, addr, &val);
134#if 1
135 /* dont know why this usually errors out on the first try */
136 if (mxl_fail(ret))
137 err("error writing addr: 0x%02x, mask: 0x%02x, "
138 "data: 0x%02x, retrying...", addr, mask, data);
139
140 ret = mxl111sf_read_reg(state, addr, &val);
141#endif
142 if (mxl_fail(ret))
143 goto fail;
144 }
145 val &= ~mask;
146 val |= data;
147
148 ret = mxl111sf_write_reg(state, addr, val);
149 mxl_fail(ret);
150fail:
151 return ret;
152}
153
154/* ------------------------------------------------------------------------ */
155
156int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
157 struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
158{
159 int i, ret = 0;
160
161 for (i = 0; ctrl_reg_info[i].addr |
162 ctrl_reg_info[i].mask |
163 ctrl_reg_info[i].data; i++) {
164
165 ret = mxl111sf_write_reg_mask(state,
166 ctrl_reg_info[i].addr,
167 ctrl_reg_info[i].mask,
168 ctrl_reg_info[i].data);
169 if (mxl_fail(ret)) {
170 err("failed on reg #%d (0x%02x)", i,
171 ctrl_reg_info[i].addr);
172 break;
173 }
174 }
175 return ret;
176}
177
178/* ------------------------------------------------------------------------ */
179
180static int mxl1x1sf_get_chip_info(struct mxl111sf_state *state)
181{
182 int ret;
183 u8 id, ver;
184 char *mxl_chip, *mxl_rev;
185
186 if ((state->chip_id) && (state->chip_ver))
187 return 0;
188
189 ret = mxl111sf_read_reg(state, CHIP_ID_REG, &id);
190 if (mxl_fail(ret))
191 goto fail;
192 state->chip_id = id;
193
194 ret = mxl111sf_read_reg(state, TOP_CHIP_REV_ID_REG, &ver);
195 if (mxl_fail(ret))
196 goto fail;
197 state->chip_ver = ver;
198
199 switch (id) {
200 case 0x61:
201 mxl_chip = "MxL101SF";
202 break;
203 case 0x63:
204 mxl_chip = "MxL111SF";
205 break;
206 default:
207 mxl_chip = "UNKNOWN MxL1X1";
208 break;
209 }
210 switch (ver) {
211 case 0x36:
212 state->chip_rev = MXL111SF_V6;
213 mxl_rev = "v6";
214 break;
215 case 0x08:
216 state->chip_rev = MXL111SF_V8_100;
217 mxl_rev = "v8_100";
218 break;
219 case 0x18:
220 state->chip_rev = MXL111SF_V8_200;
221 mxl_rev = "v8_200";
222 break;
223 default:
224 state->chip_rev = 0;
225 mxl_rev = "UNKNOWN REVISION";
226 break;
227 }
228 info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
229fail:
230 return ret;
231}
232
233#define get_chip_info(state) \
234({ \
235 int ___ret; \
236 ___ret = mxl1x1sf_get_chip_info(state); \
237 if (mxl_fail(___ret)) { \
238 mxl_debug("failed to get chip info" \
239 " on first probe attempt"); \
240 ___ret = mxl1x1sf_get_chip_info(state); \
241 if (mxl_fail(___ret)) \
242 err("failed to get chip info during probe"); \
243 else \
244 mxl_debug("probe needed a retry " \
245 "in order to succeed."); \
246 } \
247 ___ret; \
248})
249
250/* ------------------------------------------------------------------------ */
251#if 0
252static int mxl111sf_power_ctrl(struct dvb_usb_device *d, int onoff)
253{
254 /* power control depends on which adapter is being woken:
255 * save this for init, instead, via mxl111sf_adap_fe_init */
256 return 0;
257}
258#endif
259
260static int mxl111sf_adap_fe_init(struct dvb_frontend *fe)
261{
262 struct dvb_usb_device *d = fe_to_d(fe);
263 struct mxl111sf_state *state = fe_to_priv(fe);
264 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
265 int err;
266
267 /* exit if we didnt initialize the driver yet */
268 if (!state->chip_id) {
269 mxl_debug("driver not yet initialized, exit.");
270 goto fail;
271 }
272
273 deb_info("%s()\n", __func__);
274
275 mutex_lock(&state->fe_lock);
276
277 state->alt_mode = adap_state->alt_mode;
278
279 if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
280 err("set interface failed");
281
282 err = mxl1x1sf_soft_reset(state);
283 mxl_fail(err);
284 err = mxl111sf_init_tuner_demod(state);
285 mxl_fail(err);
286 err = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
287
288 mxl_fail(err);
289 mxl111sf_enable_usb_output(state);
290 mxl_fail(err);
291 mxl1x1sf_top_master_ctrl(state, 1);
292 mxl_fail(err);
293
294 if ((MXL111SF_GPIO_MOD_DVBT != adap_state->gpio_mode) &&
295 (state->chip_rev > MXL111SF_V6)) {
296 mxl111sf_config_pin_mux_modes(state,
297 PIN_MUX_TS_SPI_IN_MODE_1);
298 mxl_fail(err);
299 }
300 err = mxl111sf_init_port_expander(state);
301 if (!mxl_fail(err)) {
302 state->gpio_mode = adap_state->gpio_mode;
303 err = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
304 mxl_fail(err);
305#if 0
306 err = fe->ops.init(fe);
307#endif
308 msleep(100); /* add short delay after enabling
309 * the demod before touching it */
310 }
311
312 return (adap_state->fe_init) ? adap_state->fe_init(fe) : 0;
313fail:
314 return -ENODEV;
315}
316
317static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe)
318{
319 struct mxl111sf_state *state = fe_to_priv(fe);
320 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
321 int err;
322
323 /* exit if we didnt initialize the driver yet */
324 if (!state->chip_id) {
325 mxl_debug("driver not yet initialized, exit.");
326 goto fail;
327 }
328
329 deb_info("%s()\n", __func__);
330
331 err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;
332
333 mutex_unlock(&state->fe_lock);
334
335 return err;
336fail:
337 return -ENODEV;
338}
339
340
341static int mxl111sf_ep6_streaming_ctrl(struct dvb_frontend *fe, int onoff)
342{
343 struct mxl111sf_state *state = fe_to_priv(fe);
344 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe->id];
345 int ret = 0;
346
347 deb_info("%s(%d)\n", __func__, onoff);
348
349 if (onoff) {
350 ret = mxl111sf_enable_usb_output(state);
351 mxl_fail(ret);
352 ret = mxl111sf_config_mpeg_in(state, 1, 1,
353 adap_state->ep6_clockphase,
354 0, 0);
355 mxl_fail(ret);
356#if 0
357 } else {
358 ret = mxl111sf_disable_656_port(state);
359 mxl_fail(ret);
360#endif
361 }
362
363 return ret;
364}
365
366static int mxl111sf_ep5_streaming_ctrl(struct dvb_frontend *fe, int onoff)
367{
368 struct mxl111sf_state *state = fe_to_priv(fe);
369 int ret = 0;
370
371 deb_info("%s(%d)\n", __func__, onoff);
372
373 if (onoff) {
374 ret = mxl111sf_enable_usb_output(state);
375 mxl_fail(ret);
376
377 ret = mxl111sf_init_i2s_port(state, 200);
378 mxl_fail(ret);
379 ret = mxl111sf_config_i2s(state, 0, 15);
380 mxl_fail(ret);
381 } else {
382 ret = mxl111sf_disable_i2s_port(state);
383 mxl_fail(ret);
384 }
385 if (state->chip_rev > MXL111SF_V6)
386 ret = mxl111sf_config_spi(state, onoff);
387 mxl_fail(ret);
388
389 return ret;
390}
391
392static int mxl111sf_ep4_streaming_ctrl(struct dvb_frontend *fe, int onoff)
393{
394 struct mxl111sf_state *state = fe_to_priv(fe);
395 int ret = 0;
396
397 deb_info("%s(%d)\n", __func__, onoff);
398
399 if (onoff) {
400 ret = mxl111sf_enable_usb_output(state);
401 mxl_fail(ret);
402 }
403
404 return ret;
405}
406
407/* ------------------------------------------------------------------------ */
408
409static struct lgdt3305_config hauppauge_lgdt3305_config = {
410 .i2c_addr = 0xb2 >> 1,
411 .mpeg_mode = LGDT3305_MPEG_SERIAL,
412 .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE,
413 .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
414 .deny_i2c_rptr = 1,
415 .spectral_inversion = 0,
416 .qam_if_khz = 6000,
417 .vsb_if_khz = 6000,
418};
419
420static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
421{
422 struct dvb_usb_device *d = adap_to_d(adap);
423 struct mxl111sf_state *state = d_to_priv(d);
424 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
425 int ret;
426
427 deb_adv("%s()\n", __func__);
428
429 /* save a pointer to the dvb_usb_device in device state */
430 state->d = d;
431 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
432 state->alt_mode = adap_state->alt_mode;
433
434 if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
435 err("set interface failed");
436
437 state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
438 adap_state->gpio_mode = state->gpio_mode;
439 adap_state->device_mode = MXL_TUNER_MODE;
440 adap_state->ep6_clockphase = 1;
441
442 ret = mxl1x1sf_soft_reset(state);
443 if (mxl_fail(ret))
444 goto fail;
445 ret = mxl111sf_init_tuner_demod(state);
446 if (mxl_fail(ret))
447 goto fail;
448
449 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
450 if (mxl_fail(ret))
451 goto fail;
452
453 ret = mxl111sf_enable_usb_output(state);
454 if (mxl_fail(ret))
455 goto fail;
456 ret = mxl1x1sf_top_master_ctrl(state, 1);
457 if (mxl_fail(ret))
458 goto fail;
459
460 ret = mxl111sf_init_port_expander(state);
461 if (mxl_fail(ret))
462 goto fail;
463 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
464 if (mxl_fail(ret))
465 goto fail;
466
467 adap->fe[fe_id] = dvb_attach(lgdt3305_attach,
468 &hauppauge_lgdt3305_config,
469 &d->i2c_adap);
470 if (adap->fe[fe_id]) {
471 state->num_frontends++;
472 adap_state->fe_init = adap->fe[fe_id]->ops.init;
473 adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
474 adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
475 adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
476 return 0;
477 }
478 ret = -EIO;
479fail:
480 return ret;
481}
482
483static struct lg2160_config hauppauge_lg2160_config = {
484 .lg_chip = LG2160,
485 .i2c_addr = 0x1c >> 1,
486 .deny_i2c_rptr = 1,
487 .spectral_inversion = 0,
488 .if_khz = 6000,
489};
490
491static int mxl111sf_lg2160_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
492{
493 struct dvb_usb_device *d = adap_to_d(adap);
494 struct mxl111sf_state *state = d_to_priv(d);
495 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
496 int ret;
497
498 deb_adv("%s()\n", __func__);
499
500 /* save a pointer to the dvb_usb_device in device state */
501 state->d = d;
502 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
503 state->alt_mode = adap_state->alt_mode;
504
505 if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
506 err("set interface failed");
507
508 state->gpio_mode = MXL111SF_GPIO_MOD_MH;
509 adap_state->gpio_mode = state->gpio_mode;
510 adap_state->device_mode = MXL_TUNER_MODE;
511 adap_state->ep6_clockphase = 1;
512
513 ret = mxl1x1sf_soft_reset(state);
514 if (mxl_fail(ret))
515 goto fail;
516 ret = mxl111sf_init_tuner_demod(state);
517 if (mxl_fail(ret))
518 goto fail;
519
520 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
521 if (mxl_fail(ret))
522 goto fail;
523
524 ret = mxl111sf_enable_usb_output(state);
525 if (mxl_fail(ret))
526 goto fail;
527 ret = mxl1x1sf_top_master_ctrl(state, 1);
528 if (mxl_fail(ret))
529 goto fail;
530
531 ret = mxl111sf_init_port_expander(state);
532 if (mxl_fail(ret))
533 goto fail;
534 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
535 if (mxl_fail(ret))
536 goto fail;
537
538 ret = get_chip_info(state);
539 if (mxl_fail(ret))
540 goto fail;
541
542 adap->fe[fe_id] = dvb_attach(lg2160_attach,
543 &hauppauge_lg2160_config,
544 &d->i2c_adap);
545 if (adap->fe[fe_id]) {
546 state->num_frontends++;
547 adap_state->fe_init = adap->fe[fe_id]->ops.init;
548 adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
549 adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
550 adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
551 return 0;
552 }
553 ret = -EIO;
554fail:
555 return ret;
556}
557
558static struct lg2160_config hauppauge_lg2161_1019_config = {
559 .lg_chip = LG2161_1019,
560 .i2c_addr = 0x1c >> 1,
561 .deny_i2c_rptr = 1,
562 .spectral_inversion = 0,
563 .if_khz = 6000,
564 .output_if = 2, /* LG2161_OIF_SPI_MAS */
565};
566
567static struct lg2160_config hauppauge_lg2161_1040_config = {
568 .lg_chip = LG2161_1040,
569 .i2c_addr = 0x1c >> 1,
570 .deny_i2c_rptr = 1,
571 .spectral_inversion = 0,
572 .if_khz = 6000,
573 .output_if = 4, /* LG2161_OIF_SPI_MAS */
574};
575
576static int mxl111sf_lg2161_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
577{
578 struct dvb_usb_device *d = adap_to_d(adap);
579 struct mxl111sf_state *state = d_to_priv(d);
580 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
581 int ret;
582
583 deb_adv("%s()\n", __func__);
584
585 /* save a pointer to the dvb_usb_device in device state */
586 state->d = d;
587 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
588 state->alt_mode = adap_state->alt_mode;
589
590 if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
591 err("set interface failed");
592
593 state->gpio_mode = MXL111SF_GPIO_MOD_MH;
594 adap_state->gpio_mode = state->gpio_mode;
595 adap_state->device_mode = MXL_TUNER_MODE;
596 adap_state->ep6_clockphase = 1;
597
598 ret = mxl1x1sf_soft_reset(state);
599 if (mxl_fail(ret))
600 goto fail;
601 ret = mxl111sf_init_tuner_demod(state);
602 if (mxl_fail(ret))
603 goto fail;
604
605 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
606 if (mxl_fail(ret))
607 goto fail;
608
609 ret = mxl111sf_enable_usb_output(state);
610 if (mxl_fail(ret))
611 goto fail;
612 ret = mxl1x1sf_top_master_ctrl(state, 1);
613 if (mxl_fail(ret))
614 goto fail;
615
616 ret = mxl111sf_init_port_expander(state);
617 if (mxl_fail(ret))
618 goto fail;
619 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
620 if (mxl_fail(ret))
621 goto fail;
622
623 ret = get_chip_info(state);
624 if (mxl_fail(ret))
625 goto fail;
626
627 adap->fe[fe_id] = dvb_attach(lg2160_attach,
628 (MXL111SF_V8_200 == state->chip_rev) ?
629 &hauppauge_lg2161_1040_config :
630 &hauppauge_lg2161_1019_config,
631 &d->i2c_adap);
632 if (adap->fe[fe_id]) {
633 state->num_frontends++;
634 adap_state->fe_init = adap->fe[fe_id]->ops.init;
635 adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
636 adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
637 adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
638 return 0;
639 }
640 ret = -EIO;
641fail:
642 return ret;
643}
644
645static struct lg2160_config hauppauge_lg2161_1019_ep6_config = {
646 .lg_chip = LG2161_1019,
647 .i2c_addr = 0x1c >> 1,
648 .deny_i2c_rptr = 1,
649 .spectral_inversion = 0,
650 .if_khz = 6000,
651 .output_if = 1, /* LG2161_OIF_SERIAL_TS */
652};
653
654static struct lg2160_config hauppauge_lg2161_1040_ep6_config = {
655 .lg_chip = LG2161_1040,
656 .i2c_addr = 0x1c >> 1,
657 .deny_i2c_rptr = 1,
658 .spectral_inversion = 0,
659 .if_khz = 6000,
660 .output_if = 7, /* LG2161_OIF_SERIAL_TS */
661};
662
663static int mxl111sf_lg2161_ep6_frontend_attach(struct dvb_usb_adapter *adap, u8 fe_id)
664{
665 struct dvb_usb_device *d = adap_to_d(adap);
666 struct mxl111sf_state *state = d_to_priv(d);
667 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
668 int ret;
669
670 deb_adv("%s()\n", __func__);
671
672 /* save a pointer to the dvb_usb_device in device state */
673 state->d = d;
674 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
675 state->alt_mode = adap_state->alt_mode;
676
677 if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
678 err("set interface failed");
679
680 state->gpio_mode = MXL111SF_GPIO_MOD_MH;
681 adap_state->gpio_mode = state->gpio_mode;
682 adap_state->device_mode = MXL_TUNER_MODE;
683 adap_state->ep6_clockphase = 0;
684
685 ret = mxl1x1sf_soft_reset(state);
686 if (mxl_fail(ret))
687 goto fail;
688 ret = mxl111sf_init_tuner_demod(state);
689 if (mxl_fail(ret))
690 goto fail;
691
692 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
693 if (mxl_fail(ret))
694 goto fail;
695
696 ret = mxl111sf_enable_usb_output(state);
697 if (mxl_fail(ret))
698 goto fail;
699 ret = mxl1x1sf_top_master_ctrl(state, 1);
700 if (mxl_fail(ret))
701 goto fail;
702
703 ret = mxl111sf_init_port_expander(state);
704 if (mxl_fail(ret))
705 goto fail;
706 ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
707 if (mxl_fail(ret))
708 goto fail;
709
710 ret = get_chip_info(state);
711 if (mxl_fail(ret))
712 goto fail;
713
714 adap->fe[fe_id] = dvb_attach(lg2160_attach,
715 (MXL111SF_V8_200 == state->chip_rev) ?
716 &hauppauge_lg2161_1040_ep6_config :
717 &hauppauge_lg2161_1019_ep6_config,
718 &d->i2c_adap);
719 if (adap->fe[fe_id]) {
720 state->num_frontends++;
721 adap_state->fe_init = adap->fe[fe_id]->ops.init;
722 adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
723 adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
724 adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
725 return 0;
726 }
727 ret = -EIO;
728fail:
729 return ret;
730}
731
732static struct mxl111sf_demod_config mxl_demod_config = {
733 .read_reg = mxl111sf_read_reg,
734 .write_reg = mxl111sf_write_reg,
735 .program_regs = mxl111sf_ctrl_program_regs,
736};
737
738static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap, u8 fe_id)
739{
740 struct dvb_usb_device *d = adap_to_d(adap);
741 struct mxl111sf_state *state = d_to_priv(d);
742 struct mxl111sf_adap_state *adap_state = &state->adap_state[fe_id];
743 int ret;
744
745 deb_adv("%s()\n", __func__);
746
747 /* save a pointer to the dvb_usb_device in device state */
748 state->d = d;
749 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
750 state->alt_mode = adap_state->alt_mode;
751
752 if (usb_set_interface(d->udev, 0, state->alt_mode) < 0)
753 err("set interface failed");
754
755 state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
756 adap_state->gpio_mode = state->gpio_mode;
757 adap_state->device_mode = MXL_SOC_MODE;
758 adap_state->ep6_clockphase = 1;
759
760 ret = mxl1x1sf_soft_reset(state);
761 if (mxl_fail(ret))
762 goto fail;
763 ret = mxl111sf_init_tuner_demod(state);
764 if (mxl_fail(ret))
765 goto fail;
766
767 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
768 if (mxl_fail(ret))
769 goto fail;
770
771 ret = mxl111sf_enable_usb_output(state);
772 if (mxl_fail(ret))
773 goto fail;
774 ret = mxl1x1sf_top_master_ctrl(state, 1);
775 if (mxl_fail(ret))
776 goto fail;
777
778 /* dont care if this fails */
779 mxl111sf_init_port_expander(state);
780
781 adap->fe[fe_id] = dvb_attach(mxl111sf_demod_attach, state,
782 &mxl_demod_config);
783 if (adap->fe[fe_id]) {
784 state->num_frontends++;
785 adap_state->fe_init = adap->fe[fe_id]->ops.init;
786 adap->fe[fe_id]->ops.init = mxl111sf_adap_fe_init;
787 adap_state->fe_sleep = adap->fe[fe_id]->ops.sleep;
788 adap->fe[fe_id]->ops.sleep = mxl111sf_adap_fe_sleep;
789 return 0;
790 }
791 ret = -EIO;
792fail:
793 return ret;
794}
795
796static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
797 int antpath)
798{
799 return mxl111sf_idac_config(state, 1, 1,
800 (antpath == ANT_PATH_INTERNAL) ?
801 0x3f : 0x00, 0);
802}
803
804#define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
805 err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
806 __func__, __LINE__, \
807 (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
808 pwr0, pwr1, pwr2, pwr3)
809
810#define ANT_HUNT_SLEEP 90
811#define ANT_EXT_TWEAK 0
812
813static int mxl111sf_ant_hunt(struct dvb_frontend *fe)
814{
815 struct mxl111sf_state *state = fe_to_priv(fe);
816 int antctrl = dvb_usb_mxl111sf_rfswitch;
817
818 u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2;
819
820 /* FIXME: must force EXTERNAL for QAM - done elsewhere */
821 mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ?
822 ANT_PATH_EXTERNAL : antctrl);
823
824 if (antctrl == ANT_PATH_AUTO) {
825#if 0
826 msleep(ANT_HUNT_SLEEP);
827#endif
828 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA);
829
830 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
831 msleep(ANT_HUNT_SLEEP);
832 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0);
833
834 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
835 msleep(ANT_HUNT_SLEEP);
836 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1);
837
838 mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL);
839 msleep(ANT_HUNT_SLEEP);
840 fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2);
841
842 if (rxPwr1+ANT_EXT_TWEAK >= rxPwr2) {
843 /* return with EXTERNAL enabled */
844 mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
845 DbgAntHunt(ANT_PATH_EXTERNAL, rxPwrA,
846 rxPwr0, rxPwr1, rxPwr2);
847 } else {
848 /* return with INTERNAL enabled */
849 DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA,
850 rxPwr0, rxPwr1, rxPwr2);
851 }
852 }
853 return 0;
854}
855
856static struct mxl111sf_tuner_config mxl_tuner_config = {
857 .if_freq = MXL_IF_6_0, /* applies to external IF output, only */
858 .invert_spectrum = 0,
859 .read_reg = mxl111sf_read_reg,
860 .write_reg = mxl111sf_write_reg,
861 .program_regs = mxl111sf_ctrl_program_regs,
862 .top_master_ctrl = mxl1x1sf_top_master_ctrl,
863 .ant_hunt = mxl111sf_ant_hunt,
864};
865
866static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
867{
868 struct mxl111sf_state *state = adap_to_priv(adap);
869 int i;
870
871 deb_adv("%s()\n", __func__);
872
873 for (i = 0; i < state->num_frontends; i++) {
874 if (dvb_attach(mxl111sf_tuner_attach, adap->fe[i], state,
875 &mxl_tuner_config) == NULL)
876 return -EIO;
877 adap->fe[i]->ops.read_signal_strength = adap->fe[i]->ops.tuner_ops.get_rf_strength;
878 }
879
880 return 0;
881}
882
883static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)
884{
885 return I2C_FUNC_I2C;
886}
887
888struct i2c_algorithm mxl111sf_i2c_algo = {
889 .master_xfer = mxl111sf_i2c_xfer,
890 .functionality = mxl111sf_i2c_func,
891#ifdef NEED_ALGO_CONTROL
892 .algo_control = dummy_algo_control,
893#endif
894};
895
896static int mxl111sf_init(struct dvb_usb_device *d)
897{
898 struct mxl111sf_state *state = d_to_priv(d);
899 int ret;
900 static u8 eeprom[256];
901 struct i2c_client c;
902
903 ret = get_chip_info(state);
904 if (mxl_fail(ret))
905 err("failed to get chip info during probe");
906
907 mutex_init(&state->fe_lock);
908
909 if (state->chip_rev > MXL111SF_V6)
910 mxl111sf_config_pin_mux_modes(state, PIN_MUX_TS_SPI_IN_MODE_1);
911
912 c.adapter = &d->i2c_adap;
913 c.addr = 0xa0 >> 1;
914
915 ret = tveeprom_read(&c, eeprom, sizeof(eeprom));
916 if (mxl_fail(ret))
917 return 0;
918 tveeprom_hauppauge_analog(&c, &state->tv, (0x84 == eeprom[0xa0]) ?
919 eeprom + 0xa0 : eeprom + 0x80);
920#if 0
921 switch (state->tv.model) {
922 case 117001:
923 case 126001:
924 case 138001:
925 break;
926 default:
927 printk(KERN_WARNING "%s: warning: "
928 "unknown hauppauge model #%d\n",
929 __func__, state->tv.model);
930 }
931#endif
932 return 0;
933}
934
935static int mxl111sf_frontend_attach_dvbt(struct dvb_usb_adapter *adap)
936{
937 return mxl111sf_attach_demod(adap, 0);
938}
939
940static int mxl111sf_frontend_attach_atsc(struct dvb_usb_adapter *adap)
941{
942 return mxl111sf_lgdt3305_frontend_attach(adap, 0);
943}
944
945static int mxl111sf_frontend_attach_mh(struct dvb_usb_adapter *adap)
946{
947 return mxl111sf_lg2160_frontend_attach(adap, 0);
948}
949
950static int mxl111sf_frontend_attach_atsc_mh(struct dvb_usb_adapter *adap)
951{
952 int ret;
953 deb_info("%s\n", __func__);
954
955 ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
956 if (ret < 0)
957 return ret;
958
959 ret = mxl111sf_attach_demod(adap, 1);
960 if (ret < 0)
961 return ret;
962
963 ret = mxl111sf_lg2160_frontend_attach(adap, 2);
964 if (ret < 0)
965 return ret;
966
967 return ret;
968}
969
970static int mxl111sf_frontend_attach_mercury(struct dvb_usb_adapter *adap)
971{
972 int ret;
973 deb_info("%s\n", __func__);
974
975 ret = mxl111sf_lgdt3305_frontend_attach(adap, 0);
976 if (ret < 0)
977 return ret;
978
979 ret = mxl111sf_attach_demod(adap, 1);
980 if (ret < 0)
981 return ret;
982
983 ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 2);
984 if (ret < 0)
985 return ret;
986
987 return ret;
988}
989
990static int mxl111sf_frontend_attach_mercury_mh(struct dvb_usb_adapter *adap)
991{
992 int ret;
993 deb_info("%s\n", __func__);
994
995 ret = mxl111sf_attach_demod(adap, 0);
996 if (ret < 0)
997 return ret;
998
999 if (dvb_usb_mxl111sf_spi)
1000 ret = mxl111sf_lg2161_frontend_attach(adap, 1);
1001 else
1002 ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 1);
1003
1004 return ret;
1005}
1006
1007static void mxl111sf_stream_config_bulk(struct usb_data_stream_properties *stream, u8 endpoint)
1008{
1009 deb_info("%s: endpoint=%d size=8192\n", __func__, endpoint);
1010 stream->type = USB_BULK;
1011 stream->count = 5;
1012 stream->endpoint = endpoint;
1013 stream->u.bulk.buffersize = 8192;
1014}
1015
1016static void mxl111sf_stream_config_isoc(struct usb_data_stream_properties *stream,
1017 u8 endpoint, int framesperurb, int framesize)
1018{
1019 deb_info("%s: endpoint=%d size=%d\n", __func__, endpoint,
1020 framesperurb * framesize);
1021 stream->type = USB_ISOC;
1022 stream->count = 5;
1023 stream->endpoint = endpoint;
1024 stream->u.isoc.framesperurb = framesperurb;
1025 stream->u.isoc.framesize = framesize;
1026 stream->u.isoc.interval = 1;
1027}
1028
1029/* DVB USB Driver stuff */
1030
1031/* dvbt mxl111sf
1032 * bulk EP4/BULK/5/8192
1033 * isoc EP4/ISOC/5/96/564
1034 */
1035static int mxl111sf_get_stream_config_dvbt(struct dvb_frontend *fe,
1036 u8 *ts_type, struct usb_data_stream_properties *stream)
1037{
1038 deb_info("%s: fe=%d\n", __func__, fe->id);
1039
1040 *ts_type = DVB_USB_FE_TS_TYPE_188;
1041 if (dvb_usb_mxl111sf_isoc)
1042 mxl111sf_stream_config_isoc(stream, 4, 96, 564);
1043 else
1044 mxl111sf_stream_config_bulk(stream, 4);
1045 return 0;
1046}
1047
1048static struct dvb_usb_device_properties mxl111sf_props_dvbt = {
1049 .driver_name = KBUILD_MODNAME,
1050 .owner = THIS_MODULE,
1051 .adapter_nr = adapter_nr,
1052 .size_of_priv = sizeof(struct mxl111sf_state),
1053
1054 .generic_bulk_ctrl_endpoint = 0x02,
1055 .generic_bulk_ctrl_endpoint_response = 0x81,
1056
1057 .i2c_algo = &mxl111sf_i2c_algo,
1058 .frontend_attach = mxl111sf_frontend_attach_dvbt,
1059 .tuner_attach = mxl111sf_attach_tuner,
1060 .init = mxl111sf_init,
1061 .streaming_ctrl = mxl111sf_ep4_streaming_ctrl,
1062 .get_stream_config = mxl111sf_get_stream_config_dvbt,
1063
1064 .num_adapters = 1,
1065 .adapter = {
1066 {
1067 .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
1068 }
1069 }
1070};
1071
1072/* atsc lgdt3305
1073 * bulk EP6/BULK/5/8192
1074 * isoc EP6/ISOC/5/24/3072
1075 */
1076static int mxl111sf_get_stream_config_atsc(struct dvb_frontend *fe,
1077 u8 *ts_type, struct usb_data_stream_properties *stream)
1078{
1079 deb_info("%s: fe=%d\n", __func__, fe->id);
1080
1081 *ts_type = DVB_USB_FE_TS_TYPE_188;
1082 if (dvb_usb_mxl111sf_isoc)
1083 mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
1084 else
1085 mxl111sf_stream_config_bulk(stream, 6);
1086 return 0;
1087}
1088
1089static struct dvb_usb_device_properties mxl111sf_props_atsc = {
1090 .driver_name = KBUILD_MODNAME,
1091 .owner = THIS_MODULE,
1092 .adapter_nr = adapter_nr,
1093 .size_of_priv = sizeof(struct mxl111sf_state),
1094
1095 .generic_bulk_ctrl_endpoint = 0x02,
1096 .generic_bulk_ctrl_endpoint_response = 0x81,
1097
1098 .i2c_algo = &mxl111sf_i2c_algo,
1099 .frontend_attach = mxl111sf_frontend_attach_atsc,
1100 .tuner_attach = mxl111sf_attach_tuner,
1101 .init = mxl111sf_init,
1102 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl,
1103 .get_stream_config = mxl111sf_get_stream_config_atsc,
1104
1105 .num_adapters = 1,
1106 .adapter = {
1107 {
1108 .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
1109 }
1110 }
1111};
1112
1113/* mh lg2160
1114 * bulk EP5/BULK/5/8192/RAW
1115 * isoc EP5/ISOC/5/96/200/RAW
1116 */
1117static int mxl111sf_get_stream_config_mh(struct dvb_frontend *fe,
1118 u8 *ts_type, struct usb_data_stream_properties *stream)
1119{
1120 deb_info("%s: fe=%d\n", __func__, fe->id);
1121
1122 *ts_type = DVB_USB_FE_TS_TYPE_RAW;
1123 if (dvb_usb_mxl111sf_isoc)
1124 mxl111sf_stream_config_isoc(stream, 5, 96, 200);
1125 else
1126 mxl111sf_stream_config_bulk(stream, 5);
1127 return 0;
1128}
1129
1130static struct dvb_usb_device_properties mxl111sf_props_mh = {
1131 .driver_name = KBUILD_MODNAME,
1132 .owner = THIS_MODULE,
1133 .adapter_nr = adapter_nr,
1134 .size_of_priv = sizeof(struct mxl111sf_state),
1135
1136 .generic_bulk_ctrl_endpoint = 0x02,
1137 .generic_bulk_ctrl_endpoint_response = 0x81,
1138
1139 .i2c_algo = &mxl111sf_i2c_algo,
1140 .frontend_attach = mxl111sf_frontend_attach_mh,
1141 .tuner_attach = mxl111sf_attach_tuner,
1142 .init = mxl111sf_init,
1143 .streaming_ctrl = mxl111sf_ep5_streaming_ctrl,
1144 .get_stream_config = mxl111sf_get_stream_config_mh,
1145
1146 .num_adapters = 1,
1147 .adapter = {
1148 {
1149 .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
1150 }
1151 }
1152};
1153
1154/* atsc mh lgdt3305 mxl111sf lg2160
1155 * bulk EP6/BULK/5/8192 EP4/BULK/5/8192 EP5/BULK/5/8192/RAW
1156 * isoc EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
1157 */
1158static int mxl111sf_get_stream_config_atsc_mh(struct dvb_frontend *fe,
1159 u8 *ts_type, struct usb_data_stream_properties *stream)
1160{
1161 deb_info("%s: fe=%d\n", __func__, fe->id);
1162
1163 if (fe->id == 0) {
1164 *ts_type = DVB_USB_FE_TS_TYPE_188;
1165 if (dvb_usb_mxl111sf_isoc)
1166 mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
1167 else
1168 mxl111sf_stream_config_bulk(stream, 6);
1169 } else if (fe->id == 1) {
1170 *ts_type = DVB_USB_FE_TS_TYPE_188;
1171 if (dvb_usb_mxl111sf_isoc)
1172 mxl111sf_stream_config_isoc(stream, 4, 96, 564);
1173 else
1174 mxl111sf_stream_config_bulk(stream, 4);
1175 } else if (fe->id == 2) {
1176 *ts_type = DVB_USB_FE_TS_TYPE_RAW;
1177 if (dvb_usb_mxl111sf_isoc)
1178 mxl111sf_stream_config_isoc(stream, 5, 96, 200);
1179 else
1180 mxl111sf_stream_config_bulk(stream, 5);
1181 }
1182 return 0;
1183}
1184
1185static int mxl111sf_streaming_ctrl_atsc_mh(struct dvb_frontend *fe, int onoff)
1186{
1187 deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
1188
1189 if (fe->id == 0)
1190 return mxl111sf_ep6_streaming_ctrl(fe, onoff);
1191 else if (fe->id == 1)
1192 return mxl111sf_ep4_streaming_ctrl(fe, onoff);
1193 else if (fe->id == 2)
1194 return mxl111sf_ep5_streaming_ctrl(fe, onoff);
1195 return 0;
1196}
1197
1198static struct dvb_usb_device_properties mxl111sf_props_atsc_mh = {
1199 .driver_name = KBUILD_MODNAME,
1200 .owner = THIS_MODULE,
1201 .adapter_nr = adapter_nr,
1202 .size_of_priv = sizeof(struct mxl111sf_state),
1203
1204 .generic_bulk_ctrl_endpoint = 0x02,
1205 .generic_bulk_ctrl_endpoint_response = 0x81,
1206
1207 .i2c_algo = &mxl111sf_i2c_algo,
1208 .frontend_attach = mxl111sf_frontend_attach_atsc_mh,
1209 .tuner_attach = mxl111sf_attach_tuner,
1210 .init = mxl111sf_init,
1211 .streaming_ctrl = mxl111sf_streaming_ctrl_atsc_mh,
1212 .get_stream_config = mxl111sf_get_stream_config_atsc_mh,
1213
1214 .num_adapters = 1,
1215 .adapter = {
1216 {
1217 .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
1218 }
1219 }
1220};
1221
1222/* mercury lgdt3305 mxl111sf lg2161
1223 * tp bulk EP6/BULK/5/8192 EP4/BULK/5/8192 EP6/BULK/5/8192/RAW
1224 * tp isoc EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW
1225 * spi bulk EP6/BULK/5/8192 EP4/BULK/5/8192 EP5/BULK/5/8192/RAW
1226 * spi isoc EP6/ISOC/5/24/3072 EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
1227 */
1228static int mxl111sf_get_stream_config_mercury(struct dvb_frontend *fe,
1229 u8 *ts_type, struct usb_data_stream_properties *stream)
1230{
1231 deb_info("%s: fe=%d\n", __func__, fe->id);
1232
1233 if (fe->id == 0) {
1234 *ts_type = DVB_USB_FE_TS_TYPE_188;
1235 if (dvb_usb_mxl111sf_isoc)
1236 mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
1237 else
1238 mxl111sf_stream_config_bulk(stream, 6);
1239 } else if (fe->id == 1) {
1240 *ts_type = DVB_USB_FE_TS_TYPE_188;
1241 if (dvb_usb_mxl111sf_isoc)
1242 mxl111sf_stream_config_isoc(stream, 4, 96, 564);
1243 else
1244 mxl111sf_stream_config_bulk(stream, 4);
1245 } else if (fe->id == 2 && dvb_usb_mxl111sf_spi) {
1246 *ts_type = DVB_USB_FE_TS_TYPE_RAW;
1247 if (dvb_usb_mxl111sf_isoc)
1248 mxl111sf_stream_config_isoc(stream, 5, 96, 200);
1249 else
1250 mxl111sf_stream_config_bulk(stream, 5);
1251 } else if (fe->id == 2 && !dvb_usb_mxl111sf_spi) {
1252 *ts_type = DVB_USB_FE_TS_TYPE_RAW;
1253 if (dvb_usb_mxl111sf_isoc)
1254 mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
1255 else
1256 mxl111sf_stream_config_bulk(stream, 6);
1257 }
1258 return 0;
1259}
1260
1261static int mxl111sf_streaming_ctrl_mercury(struct dvb_frontend *fe, int onoff)
1262{
1263 deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
1264
1265 if (fe->id == 0)
1266 return mxl111sf_ep6_streaming_ctrl(fe, onoff);
1267 else if (fe->id == 1)
1268 return mxl111sf_ep4_streaming_ctrl(fe, onoff);
1269 else if (fe->id == 2 && dvb_usb_mxl111sf_spi)
1270 return mxl111sf_ep5_streaming_ctrl(fe, onoff);
1271 else if (fe->id == 2 && !dvb_usb_mxl111sf_spi)
1272 return mxl111sf_ep6_streaming_ctrl(fe, onoff);
1273 return 0;
1274}
1275
1276static struct dvb_usb_device_properties mxl111sf_props_mercury = {
1277 .driver_name = KBUILD_MODNAME,
1278 .owner = THIS_MODULE,
1279 .adapter_nr = adapter_nr,
1280 .size_of_priv = sizeof(struct mxl111sf_state),
1281
1282 .generic_bulk_ctrl_endpoint = 0x02,
1283 .generic_bulk_ctrl_endpoint_response = 0x81,
1284
1285 .i2c_algo = &mxl111sf_i2c_algo,
1286 .frontend_attach = mxl111sf_frontend_attach_mercury,
1287 .tuner_attach = mxl111sf_attach_tuner,
1288 .init = mxl111sf_init,
1289 .streaming_ctrl = mxl111sf_streaming_ctrl_mercury,
1290 .get_stream_config = mxl111sf_get_stream_config_mercury,
1291
1292 .num_adapters = 1,
1293 .adapter = {
1294 {
1295 .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
1296 }
1297 }
1298};
1299
1300/* mercury mh mxl111sf lg2161
1301 * tp bulk EP4/BULK/5/8192 EP6/BULK/5/8192/RAW
1302 * tp isoc EP4/ISOC/5/96/564 EP6/ISOC/5/24/3072/RAW
1303 * spi bulk EP4/BULK/5/8192 EP5/BULK/5/8192/RAW
1304 * spi isoc EP4/ISOC/5/96/564 EP5/ISOC/5/96/200/RAW
1305 */
1306static int mxl111sf_get_stream_config_mercury_mh(struct dvb_frontend *fe,
1307 u8 *ts_type, struct usb_data_stream_properties *stream)
1308{
1309 deb_info("%s: fe=%d\n", __func__, fe->id);
1310
1311 if (fe->id == 0) {
1312 *ts_type = DVB_USB_FE_TS_TYPE_188;
1313 if (dvb_usb_mxl111sf_isoc)
1314 mxl111sf_stream_config_isoc(stream, 4, 96, 564);
1315 else
1316 mxl111sf_stream_config_bulk(stream, 4);
1317 } else if (fe->id == 1 && dvb_usb_mxl111sf_spi) {
1318 *ts_type = DVB_USB_FE_TS_TYPE_RAW;
1319 if (dvb_usb_mxl111sf_isoc)
1320 mxl111sf_stream_config_isoc(stream, 5, 96, 200);
1321 else
1322 mxl111sf_stream_config_bulk(stream, 5);
1323 } else if (fe->id == 1 && !dvb_usb_mxl111sf_spi) {
1324 *ts_type = DVB_USB_FE_TS_TYPE_RAW;
1325 if (dvb_usb_mxl111sf_isoc)
1326 mxl111sf_stream_config_isoc(stream, 6, 24, 3072);
1327 else
1328 mxl111sf_stream_config_bulk(stream, 6);
1329 }
1330 return 0;
1331}
1332
1333static int mxl111sf_streaming_ctrl_mercury_mh(struct dvb_frontend *fe, int onoff)
1334{
1335 deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff);
1336
1337 if (fe->id == 0)
1338 return mxl111sf_ep4_streaming_ctrl(fe, onoff);
1339 else if (fe->id == 1 && dvb_usb_mxl111sf_spi)
1340 return mxl111sf_ep5_streaming_ctrl(fe, onoff);
1341 else if (fe->id == 1 && !dvb_usb_mxl111sf_spi)
1342 return mxl111sf_ep6_streaming_ctrl(fe, onoff);
1343 return 0;
1344}
1345
1346static struct dvb_usb_device_properties mxl111sf_props_mercury_mh = {
1347 .driver_name = KBUILD_MODNAME,
1348 .owner = THIS_MODULE,
1349 .adapter_nr = adapter_nr,
1350 .size_of_priv = sizeof(struct mxl111sf_state),
1351
1352 .generic_bulk_ctrl_endpoint = 0x02,
1353 .generic_bulk_ctrl_endpoint_response = 0x81,
1354
1355 .i2c_algo = &mxl111sf_i2c_algo,
1356 .frontend_attach = mxl111sf_frontend_attach_mercury_mh,
1357 .tuner_attach = mxl111sf_attach_tuner,
1358 .init = mxl111sf_init,
1359 .streaming_ctrl = mxl111sf_streaming_ctrl_mercury_mh,
1360 .get_stream_config = mxl111sf_get_stream_config_mercury_mh,
1361
1362 .num_adapters = 1,
1363 .adapter = {
1364 {
1365 .stream = DVB_USB_STREAM_ISOC(6, 5, 24, 3072, 1),
1366 }
1367 }
1368};
1369
1370static const struct usb_device_id mxl111sf_id_table[] = {
1371 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc600, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
1372 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc601, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
1373 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc602, &mxl111sf_props_mh, "HCW 126xxx", NULL) },
1374 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc603, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
1375 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc604, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) },
1376 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc609, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
1377 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60a, &mxl111sf_props_mh, "HCW 126xxx", NULL) },
1378 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
1379 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60c, &mxl111sf_props_dvbt, "Hauppauge 126xxx DVBT", NULL) },
1380 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc653, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
1381 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc65b, &mxl111sf_props_atsc_mh, "Hauppauge 126xxx ATSC+", NULL) },
1382 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb700, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
1383 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb701, &mxl111sf_props_atsc, "Hauppauge 126xxx ATSC", NULL) },
1384 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb702, &mxl111sf_props_mh, "HCW 117xxx", NULL) },
1385 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb703, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
1386 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb704, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) },
1387 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb753, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
1388 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb763, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
1389 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb764, &mxl111sf_props_dvbt, "Hauppauge 117xxx DVBT", NULL) },
1390 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd853, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
1391 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd854, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
1392 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd863, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
1393 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd864, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
1394 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
1395 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
1396 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e3, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
1397 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e4, &mxl111sf_props_dvbt, "Hauppauge 138xxx DVBT", NULL) },
1398 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8ff, &mxl111sf_props_mercury, "Hauppauge Mercury", NULL) },
1399 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc612, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) },
1400 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc613, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) },
1401 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61a, &mxl111sf_props_mercury_mh, "Hauppauge 126xxx", NULL) },
1402 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61b, &mxl111sf_props_mercury, "Hauppauge WinTV-Aero-M", NULL) },
1403 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb757, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
1404 { DVB_USB_DEVICE(USB_VID_HAUPPAUGE, 0xb767, &mxl111sf_props_atsc_mh, "Hauppauge 117xxx ATSC+", NULL) },
1405 { }
1406};
1407MODULE_DEVICE_TABLE(usb, mxl111sf_id_table);
1408
1409static struct usb_driver mxl111sf_usb_driver = {
1410 .name = KBUILD_MODNAME,
1411 .id_table = mxl111sf_id_table,
1412 .probe = dvb_usbv2_probe,
1413 .disconnect = dvb_usbv2_disconnect,
1414 .suspend = dvb_usbv2_suspend,
1415 .resume = dvb_usbv2_resume,
1416 .no_dynamic_id = 1,
1417 .soft_unbind = 1,
1418};
1419
1420module_usb_driver(mxl111sf_usb_driver);
1421
1422MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
1423MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
1424MODULE_VERSION("1.0");
1425MODULE_LICENSE("GPL");
1426
1427/*
1428 * Local variables:
1429 * c-basic-offset: 8
1430 * End:
1431 */
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf.h b/drivers/media/usb/dvb-usb-v2/mxl111sf.h
new file mode 100644
index 000000000000..9816de86e48c
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.h
@@ -0,0 +1,160 @@
1/*
2 * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com)
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation, version 2.
7 *
8 * see Documentation/dvb/README.dvb-usb for more information
9 */
10
11#ifndef _DVB_USB_MXL111SF_H_
12#define _DVB_USB_MXL111SF_H_
13
14#ifdef DVB_USB_LOG_PREFIX
15#undef DVB_USB_LOG_PREFIX
16#endif
17#define DVB_USB_LOG_PREFIX "mxl111sf"
18#include "dvb_usb.h"
19#include <media/tveeprom.h>
20
21#define MXL_EP1_REG_READ 1
22#define MXL_EP2_REG_WRITE 2
23#define MXL_EP3_INTERRUPT 3
24#define MXL_EP4_MPEG2 4
25#define MXL_EP5_I2S 5
26#define MXL_EP6_656 6
27#define MXL_EP6_MPEG2 6
28
29#ifdef USING_ENUM_mxl111sf_current_mode
30enum mxl111sf_current_mode {
31 mxl_mode_dvbt = MXL_EP4_MPEG2,
32 mxl_mode_mh = MXL_EP5_I2S,
33 mxl_mode_atsc = MXL_EP6_MPEG2,
34};
35#endif
36
37enum mxl111sf_gpio_port_expander {
38 mxl111sf_gpio_hw,
39 mxl111sf_PCA9534,
40};
41
42struct mxl111sf_adap_state {
43 int alt_mode;
44 int gpio_mode;
45 int device_mode;
46 int ep6_clockphase;
47 int (*fe_init)(struct dvb_frontend *);
48 int (*fe_sleep)(struct dvb_frontend *);
49};
50
51struct mxl111sf_state {
52 struct dvb_usb_device *d;
53
54 enum mxl111sf_gpio_port_expander gpio_port_expander;
55 u8 port_expander_addr;
56
57 u8 chip_id;
58 u8 chip_ver;
59#define MXL111SF_V6 1
60#define MXL111SF_V8_100 2
61#define MXL111SF_V8_200 3
62 u8 chip_rev;
63
64#ifdef USING_ENUM_mxl111sf_current_mode
65 enum mxl111sf_current_mode current_mode;
66#endif
67
68#define MXL_TUNER_MODE 0
69#define MXL_SOC_MODE 1
70#define MXL_DEV_MODE_MASK 0x01
71#if 1
72 int device_mode;
73#endif
74 /* use usb alt setting 1 for EP4 ISOC transfer (dvb-t),
75 EP5 BULK transfer (atsc-mh),
76 EP6 BULK transfer (atsc/qam),
77 use usb alt setting 2 for EP4 BULK transfer (dvb-t),
78 EP5 ISOC transfer (atsc-mh),
79 EP6 ISOC transfer (atsc/qam),
80 */
81 int alt_mode;
82 int gpio_mode;
83 struct tveeprom tv;
84
85 struct mutex fe_lock;
86 u8 num_frontends;
87 struct mxl111sf_adap_state adap_state[3];
88};
89
90int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data);
91int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data);
92
93struct mxl111sf_reg_ctrl_info {
94 u8 addr;
95 u8 mask;
96 u8 data;
97};
98
99int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
100 u8 addr, u8 mask, u8 data);
101int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
102 struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
103
104/* needed for hardware i2c functions in mxl111sf-i2c.c:
105 * mxl111sf_i2c_send_data / mxl111sf_i2c_get_data */
106int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
107 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen);
108
109#define mxl_printk(kern, fmt, arg...) \
110 printk(kern "%s: " fmt "\n", __func__, ##arg)
111
112#define mxl_info(fmt, arg...) \
113 mxl_printk(KERN_INFO, fmt, ##arg)
114
115extern int dvb_usb_mxl111sf_debug;
116#define mxl_debug(fmt, arg...) \
117 if (dvb_usb_mxl111sf_debug) \
118 mxl_printk(KERN_DEBUG, fmt, ##arg)
119
120#define MXL_I2C_DBG 0x04
121#define MXL_ADV_DBG 0x10
122#define mxl_debug_adv(fmt, arg...) \
123 if (dvb_usb_mxl111sf_debug & MXL_ADV_DBG) \
124 mxl_printk(KERN_DEBUG, fmt, ##arg)
125
126#define mxl_i2c(fmt, arg...) \
127 if (dvb_usb_mxl111sf_debug & MXL_I2C_DBG) \
128 mxl_printk(KERN_DEBUG, fmt, ##arg)
129
130#define mxl_i2c_adv(fmt, arg...) \
131 if ((dvb_usb_mxl111sf_debug & (MXL_I2C_DBG | MXL_ADV_DBG)) == \
132 (MXL_I2C_DBG | MXL_ADV_DBG)) \
133 mxl_printk(KERN_DEBUG, fmt, ##arg)
134
135/* The following allows the mxl_fail() macro defined below to work
136 * in externel modules, such as mxl111sf-tuner.ko, even though
137 * dvb_usb_mxl111sf_debug is not defined within those modules */
138#if (defined(__MXL111SF_TUNER_H__)) || (defined(__MXL111SF_DEMOD_H__))
139#define MXL_ADV_DEBUG_ENABLED MXL_ADV_DBG
140#else
141#define MXL_ADV_DEBUG_ENABLED dvb_usb_mxl111sf_debug
142#endif
143
144#define mxl_fail(ret) \
145({ \
146 int __ret; \
147 __ret = (ret < 0); \
148 if ((__ret) && (MXL_ADV_DEBUG_ENABLED & MXL_ADV_DBG)) \
149 mxl_printk(KERN_ERR, "error %d on line %d", \
150 ret, __LINE__); \
151 __ret; \
152})
153
154#endif /* _DVB_USB_MXL111SF_H_ */
155
156/*
157 * Local variables:
158 * c-basic-offset: 8
159 * End:
160 */
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
new file mode 100644
index 000000000000..a2d1e5b9d9d4
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -0,0 +1,1259 @@
1/*
2 * Realtek RTL28xxU DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
6 * Copyright (C) 2012 Thomas Mair <thomas.mair86@googlemail.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23#include "rtl28xxu.h"
24
25#include "rtl2830.h"
26#include "rtl2832.h"
27
28#include "qt1010.h"
29#include "mt2060.h"
30#include "mxl5005s.h"
31#include "fc0012.h"
32#include "fc0013.h"
33
34DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
35
36static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
37{
38 int ret;
39 unsigned int pipe;
40 u8 requesttype;
41 u8 *buf;
42
43 buf = kmalloc(req->size, GFP_KERNEL);
44 if (!buf) {
45 ret = -ENOMEM;
46 goto err;
47 }
48
49 if (req->index & CMD_WR_FLAG) {
50 /* write */
51 memcpy(buf, req->data, req->size);
52 requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
53 pipe = usb_sndctrlpipe(d->udev, 0);
54 } else {
55 /* read */
56 requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
57 pipe = usb_rcvctrlpipe(d->udev, 0);
58 }
59
60 ret = usb_control_msg(d->udev, pipe, 0, requesttype, req->value,
61 req->index, buf, req->size, 1000);
62 if (ret > 0)
63 ret = 0;
64
65 deb_dump(0, requesttype, req->value, req->index, buf, req->size);
66
67 /* read request, copy returned data to return buf */
68 if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
69 memcpy(req->data, buf, req->size);
70
71 kfree(buf);
72
73 if (ret)
74 goto err;
75
76 return ret;
77err:
78 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
79 return ret;
80}
81
82static int rtl28xx_wr_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len)
83{
84 struct rtl28xxu_req req;
85
86 if (reg < 0x3000)
87 req.index = CMD_USB_WR;
88 else if (reg < 0x4000)
89 req.index = CMD_SYS_WR;
90 else
91 req.index = CMD_IR_WR;
92
93 req.value = reg;
94 req.size = len;
95 req.data = val;
96
97 return rtl28xxu_ctrl_msg(d, &req);
98}
99
100static int rtl2831_rd_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len)
101{
102 struct rtl28xxu_req req;
103
104 if (reg < 0x3000)
105 req.index = CMD_USB_RD;
106 else if (reg < 0x4000)
107 req.index = CMD_SYS_RD;
108 else
109 req.index = CMD_IR_RD;
110
111 req.value = reg;
112 req.size = len;
113 req.data = val;
114
115 return rtl28xxu_ctrl_msg(d, &req);
116}
117
118static int rtl28xx_wr_reg(struct dvb_usb_device *d, u16 reg, u8 val)
119{
120 return rtl28xx_wr_regs(d, reg, &val, 1);
121}
122
123static int rtl28xx_rd_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
124{
125 return rtl2831_rd_regs(d, reg, val, 1);
126}
127
128/* I2C */
129static int rtl28xxu_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
130 int num)
131{
132 int ret;
133 struct dvb_usb_device *d = i2c_get_adapdata(adap);
134 struct rtl28xxu_priv *priv = d->priv;
135 struct rtl28xxu_req req;
136
137 /*
138 * It is not known which are real I2C bus xfer limits, but testing
139 * with RTL2831U + MT2060 gives max RD 24 and max WR 22 bytes.
140 * TODO: find out RTL2832U lens
141 */
142
143 /*
144 * I2C adapter logic looks rather complicated due to fact it handles
145 * three different access methods. Those methods are;
146 * 1) integrated demod access
147 * 2) old I2C access
148 * 3) new I2C access
149 *
150 * Used method is selected in order 1, 2, 3. Method 3 can handle all
151 * requests but there is two reasons why not use it always;
152 * 1) It is most expensive, usually two USB messages are needed
153 * 2) At least RTL2831U does not support it
154 *
155 * Method 3 is needed in case of I2C write+read (typical register read)
156 * where write is more than one byte.
157 */
158
159 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
160 return -EAGAIN;
161
162 if (num == 2 && !(msg[0].flags & I2C_M_RD) &&
163 (msg[1].flags & I2C_M_RD)) {
164 if (msg[0].len > 24 || msg[1].len > 24) {
165 /* TODO: check msg[0].len max */
166 ret = -EOPNOTSUPP;
167 goto err_mutex_unlock;
168 } else if (msg[0].addr == 0x10) {
169 /* method 1 - integrated demod */
170 req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
171 req.index = CMD_DEMOD_RD | priv->page;
172 req.size = msg[1].len;
173 req.data = &msg[1].buf[0];
174 ret = rtl28xxu_ctrl_msg(d, &req);
175 } else if (msg[0].len < 2) {
176 /* method 2 - old I2C */
177 req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
178 req.index = CMD_I2C_RD;
179 req.size = msg[1].len;
180 req.data = &msg[1].buf[0];
181 ret = rtl28xxu_ctrl_msg(d, &req);
182 } else {
183 /* method 3 - new I2C */
184 req.value = (msg[0].addr << 1);
185 req.index = CMD_I2C_DA_WR;
186 req.size = msg[0].len;
187 req.data = msg[0].buf;
188 ret = rtl28xxu_ctrl_msg(d, &req);
189 if (ret)
190 goto err_mutex_unlock;
191
192 req.value = (msg[0].addr << 1);
193 req.index = CMD_I2C_DA_RD;
194 req.size = msg[1].len;
195 req.data = msg[1].buf;
196 ret = rtl28xxu_ctrl_msg(d, &req);
197 }
198 } else if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
199 if (msg[0].len > 22) {
200 /* TODO: check msg[0].len max */
201 ret = -EOPNOTSUPP;
202 goto err_mutex_unlock;
203 } else if (msg[0].addr == 0x10) {
204 /* method 1 - integrated demod */
205 if (msg[0].buf[0] == 0x00) {
206 /* save demod page for later demod access */
207 priv->page = msg[0].buf[1];
208 ret = 0;
209 } else {
210 req.value = (msg[0].buf[0] << 8) |
211 (msg[0].addr << 1);
212 req.index = CMD_DEMOD_WR | priv->page;
213 req.size = msg[0].len-1;
214 req.data = &msg[0].buf[1];
215 ret = rtl28xxu_ctrl_msg(d, &req);
216 }
217 } else if (msg[0].len < 23) {
218 /* method 2 - old I2C */
219 req.value = (msg[0].buf[0] << 8) | (msg[0].addr << 1);
220 req.index = CMD_I2C_WR;
221 req.size = msg[0].len-1;
222 req.data = &msg[0].buf[1];
223 ret = rtl28xxu_ctrl_msg(d, &req);
224 } else {
225 /* method 3 - new I2C */
226 req.value = (msg[0].addr << 1);
227 req.index = CMD_I2C_DA_WR;
228 req.size = msg[0].len;
229 req.data = msg[0].buf;
230 ret = rtl28xxu_ctrl_msg(d, &req);
231 }
232 } else {
233 ret = -EINVAL;
234 }
235
236err_mutex_unlock:
237 mutex_unlock(&d->i2c_mutex);
238
239 return ret ? ret : num;
240}
241
242static u32 rtl28xxu_i2c_func(struct i2c_adapter *adapter)
243{
244 return I2C_FUNC_I2C;
245}
246
247static struct i2c_algorithm rtl28xxu_i2c_algo = {
248 .master_xfer = rtl28xxu_i2c_xfer,
249 .functionality = rtl28xxu_i2c_func,
250};
251
252static struct rtl2830_config rtl28xxu_rtl2830_mt2060_config = {
253 .i2c_addr = 0x10, /* 0x20 */
254 .xtal = 28800000,
255 .ts_mode = 0,
256 .spec_inv = 1,
257 .if_dvbt = 36150000,
258 .vtop = 0x20,
259 .krf = 0x04,
260 .agc_targ_val = 0x2d,
261
262};
263
264static struct rtl2830_config rtl28xxu_rtl2830_qt1010_config = {
265 .i2c_addr = 0x10, /* 0x20 */
266 .xtal = 28800000,
267 .ts_mode = 0,
268 .spec_inv = 1,
269 .if_dvbt = 36125000,
270 .vtop = 0x20,
271 .krf = 0x04,
272 .agc_targ_val = 0x2d,
273};
274
275static struct rtl2830_config rtl28xxu_rtl2830_mxl5005s_config = {
276 .i2c_addr = 0x10, /* 0x20 */
277 .xtal = 28800000,
278 .ts_mode = 0,
279 .spec_inv = 0,
280 .if_dvbt = 4570000,
281 .vtop = 0x3f,
282 .krf = 0x04,
283 .agc_targ_val = 0x3e,
284};
285
286static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
287{
288 int ret;
289 struct dvb_usb_device *d = adap_to_d(adap);
290 struct rtl28xxu_priv *priv = d_to_priv(d);
291 u8 buf[1];
292 struct rtl2830_config *rtl2830_config;
293 /* open RTL2831U/RTL2830 I2C gate */
294 struct rtl28xxu_req req_gate = { 0x0120, 0x0011, 0x0001, "\x08" };
295 /* for MT2060 tuner probe */
296 struct rtl28xxu_req req_mt2060 = { 0x00c0, CMD_I2C_RD, 1, buf };
297 /* for QT1010 tuner probe */
298 struct rtl28xxu_req req_qt1010 = { 0x0fc4, CMD_I2C_RD, 1, buf };
299
300 dev_dbg(&d->udev->dev, "%s:\n", __func__);
301
302 /*
303 * RTL2831U GPIOs
304 * =========================================================
305 * GPIO0 | tuner#0 | 0 off | 1 on | MXL5005S (?)
306 * GPIO2 | LED | 0 off | 1 on |
307 * GPIO4 | tuner#1 | 0 on | 1 off | MT2060
308 */
309
310 /* GPIO direction */
311 ret = rtl28xx_wr_reg(d, SYS_GPIO_DIR, 0x0a);
312 if (ret)
313 goto err;
314
315 /* enable as output GPIO0, GPIO2, GPIO4 */
316 ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_EN, 0x15);
317 if (ret)
318 goto err;
319
320 /*
321 * Probe used tuner. We need to know used tuner before demod attach
322 * since there is some demod params needed to set according to tuner.
323 */
324
325 /* demod needs some time to wake up */
326 msleep(20);
327
328 /* open demod I2C gate */
329 ret = rtl28xxu_ctrl_msg(d, &req_gate);
330 if (ret)
331 goto err;
332
333 /* check QT1010 ID(?) register; reg=0f val=2c */
334 ret = rtl28xxu_ctrl_msg(d, &req_qt1010);
335 if (ret == 0 && buf[0] == 0x2c) {
336 priv->tuner = TUNER_RTL2830_QT1010;
337 rtl2830_config = &rtl28xxu_rtl2830_qt1010_config;
338 dev_dbg(&d->udev->dev, "%s: QT1010\n", __func__);
339 goto found;
340 } else {
341 dev_dbg(&d->udev->dev, "%s: QT1010 probe failed=%d - %02x\n",
342 __func__, ret, buf[0]);
343 }
344
345 /* open demod I2C gate */
346 ret = rtl28xxu_ctrl_msg(d, &req_gate);
347 if (ret)
348 goto err;
349
350 /* check MT2060 ID register; reg=00 val=63 */
351 ret = rtl28xxu_ctrl_msg(d, &req_mt2060);
352 if (ret == 0 && buf[0] == 0x63) {
353 priv->tuner = TUNER_RTL2830_MT2060;
354 rtl2830_config = &rtl28xxu_rtl2830_mt2060_config;
355 dev_dbg(&d->udev->dev, "%s: MT2060\n", __func__);
356 goto found;
357 } else {
358 dev_dbg(&d->udev->dev, "%s: MT2060 probe failed=%d - %02x\n",
359 __func__, ret, buf[0]);
360 }
361
362 /* assume MXL5005S */
363 ret = 0;
364 priv->tuner = TUNER_RTL2830_MXL5005S;
365 rtl2830_config = &rtl28xxu_rtl2830_mxl5005s_config;
366 dev_dbg(&d->udev->dev, "%s: MXL5005S\n", __func__);
367 goto found;
368
369found:
370 /* attach demodulator */
371 adap->fe[0] = dvb_attach(rtl2830_attach, rtl2830_config,
372 &d->i2c_adap);
373 if (adap->fe[0] == NULL) {
374 ret = -ENODEV;
375 goto err;
376 }
377
378 return ret;
379err:
380 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
381 return ret;
382}
383
384static struct rtl2832_config rtl28xxu_rtl2832_fc0012_config = {
385 .i2c_addr = 0x10, /* 0x20 */
386 .xtal = 28800000,
387 .if_dvbt = 0,
388 .tuner = TUNER_RTL2832_FC0012
389};
390
391static struct rtl2832_config rtl28xxu_rtl2832_fc0013_config = {
392 .i2c_addr = 0x10, /* 0x20 */
393 .xtal = 28800000,
394 .if_dvbt = 0,
395 .tuner = TUNER_RTL2832_FC0013
396};
397
398static int rtl2832u_fc0012_tuner_callback(struct dvb_usb_device *d,
399 int cmd, int arg)
400{
401 int ret;
402 u8 val;
403
404 dev_dbg(&d->udev->dev, "%s: cmd=%d arg=%d\n", __func__, cmd, arg);
405
406 switch (cmd) {
407 case FC_FE_CALLBACK_VHF_ENABLE:
408 /* set output values */
409 ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
410 if (ret)
411 goto err;
412
413 if (arg)
414 val &= 0xbf; /* set GPIO6 low */
415 else
416 val |= 0x40; /* set GPIO6 high */
417
418
419 ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
420 if (ret)
421 goto err;
422 break;
423 default:
424 ret = -EINVAL;
425 goto err;
426 }
427 return 0;
428
429err:
430 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
431 return ret;
432}
433
434
435static int rtl2832u_fc0013_tuner_callback(struct dvb_usb_device *d,
436 int cmd, int arg)
437{
438 /* TODO implement*/
439 return 0;
440}
441
442static int rtl2832u_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
443{
444 struct rtl28xxu_priv *priv = d->priv;
445
446 switch (priv->tuner) {
447 case TUNER_RTL2832_FC0012:
448 return rtl2832u_fc0012_tuner_callback(d, cmd, arg);
449
450 case TUNER_RTL2832_FC0013:
451 return rtl2832u_fc0013_tuner_callback(d, cmd, arg);
452 default:
453 break;
454 }
455
456 return -ENODEV;
457}
458
459static int rtl2832u_frontend_callback(void *adapter_priv, int component,
460 int cmd, int arg)
461{
462 struct i2c_adapter *adap = adapter_priv;
463 struct dvb_usb_device *d = i2c_get_adapdata(adap);
464
465 switch (component) {
466 case DVB_FRONTEND_COMPONENT_TUNER:
467 return rtl2832u_tuner_callback(d, cmd, arg);
468 default:
469 break;
470 }
471
472 return -EINVAL;
473}
474
475static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
476{
477 int ret;
478 struct dvb_usb_device *d = adap_to_d(adap);
479 struct rtl28xxu_priv *priv = d_to_priv(d);
480 struct rtl2832_config *rtl2832_config;
481 u8 buf[2], val;
482 /* open RTL2832U/RTL2832 I2C gate */
483 struct rtl28xxu_req req_gate_open = {0x0120, 0x0011, 0x0001, "\x18"};
484 /* close RTL2832U/RTL2832 I2C gate */
485 struct rtl28xxu_req req_gate_close = {0x0120, 0x0011, 0x0001, "\x10"};
486 /* for FC0012 tuner probe */
487 struct rtl28xxu_req req_fc0012 = {0x00c6, CMD_I2C_RD, 1, buf};
488 /* for FC0013 tuner probe */
489 struct rtl28xxu_req req_fc0013 = {0x00c6, CMD_I2C_RD, 1, buf};
490 /* for MT2266 tuner probe */
491 struct rtl28xxu_req req_mt2266 = {0x00c0, CMD_I2C_RD, 1, buf};
492 /* for FC2580 tuner probe */
493 struct rtl28xxu_req req_fc2580 = {0x01ac, CMD_I2C_RD, 1, buf};
494 /* for MT2063 tuner probe */
495 struct rtl28xxu_req req_mt2063 = {0x00c0, CMD_I2C_RD, 1, buf};
496 /* for MAX3543 tuner probe */
497 struct rtl28xxu_req req_max3543 = {0x00c0, CMD_I2C_RD, 1, buf};
498 /* for TUA9001 tuner probe */
499 struct rtl28xxu_req req_tua9001 = {0x7ec0, CMD_I2C_RD, 2, buf};
500 /* for MXL5007T tuner probe */
501 struct rtl28xxu_req req_mxl5007t = {0xd9c0, CMD_I2C_RD, 1, buf};
502 /* for E4000 tuner probe */
503 struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf};
504 /* for TDA18272 tuner probe */
505 struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf};
506
507 dev_dbg(&d->udev->dev, "%s:\n", __func__);
508
509 ret = rtl28xx_rd_reg(d, SYS_GPIO_DIR, &val);
510 if (ret)
511 goto err;
512
513 val &= 0xbf;
514
515 ret = rtl28xx_wr_reg(d, SYS_GPIO_DIR, val);
516 if (ret)
517 goto err;
518
519 /* enable as output GPIO3 and GPIO6*/
520 ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_EN, &val);
521 if (ret)
522 goto err;
523
524 val |= 0x48;
525
526 ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_EN, val);
527 if (ret)
528 goto err;
529
530 /*
531 * Probe used tuner. We need to know used tuner before demod attach
532 * since there is some demod params needed to set according to tuner.
533 */
534
535 /* open demod I2C gate */
536 ret = rtl28xxu_ctrl_msg(d, &req_gate_open);
537 if (ret)
538 goto err;
539
540 priv->tuner = TUNER_NONE;
541
542 /* check FC0012 ID register; reg=00 val=a1 */
543 ret = rtl28xxu_ctrl_msg(d, &req_fc0012);
544 if (ret == 0 && buf[0] == 0xa1) {
545 priv->tuner = TUNER_RTL2832_FC0012;
546 rtl2832_config = &rtl28xxu_rtl2832_fc0012_config;
547 dev_info(&d->udev->dev, "%s: FC0012 tuner found",
548 KBUILD_MODNAME);
549 goto found;
550 }
551
552 /* check FC0013 ID register; reg=00 val=a3 */
553 ret = rtl28xxu_ctrl_msg(d, &req_fc0013);
554 if (ret == 0 && buf[0] == 0xa3) {
555 priv->tuner = TUNER_RTL2832_FC0013;
556 rtl2832_config = &rtl28xxu_rtl2832_fc0013_config;
557 dev_info(&d->udev->dev, "%s: FC0013 tuner found",
558 KBUILD_MODNAME);
559 goto found;
560 }
561
562 /* check MT2266 ID register; reg=00 val=85 */
563 ret = rtl28xxu_ctrl_msg(d, &req_mt2266);
564 if (ret == 0 && buf[0] == 0x85) {
565 priv->tuner = TUNER_RTL2832_MT2266;
566 /* TODO implement tuner */
567 dev_info(&d->udev->dev, "%s: MT2266 tuner found",
568 KBUILD_MODNAME);
569 goto unsupported;
570 }
571
572 /* check FC2580 ID register; reg=01 val=56 */
573 ret = rtl28xxu_ctrl_msg(d, &req_fc2580);
574 if (ret == 0 && buf[0] == 0x56) {
575 priv->tuner = TUNER_RTL2832_FC2580;
576 /* TODO implement tuner */
577 dev_info(&d->udev->dev, "%s: FC2580 tuner found",
578 KBUILD_MODNAME);
579 goto unsupported;
580 }
581
582 /* check MT2063 ID register; reg=00 val=9e || 9c */
583 ret = rtl28xxu_ctrl_msg(d, &req_mt2063);
584 if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) {
585 priv->tuner = TUNER_RTL2832_MT2063;
586 /* TODO implement tuner */
587 dev_info(&d->udev->dev, "%s: MT2063 tuner found",
588 KBUILD_MODNAME);
589 goto unsupported;
590 }
591
592 /* check MAX3543 ID register; reg=00 val=38 */
593 ret = rtl28xxu_ctrl_msg(d, &req_max3543);
594 if (ret == 0 && buf[0] == 0x38) {
595 priv->tuner = TUNER_RTL2832_MAX3543;
596 /* TODO implement tuner */
597 dev_info(&d->udev->dev, "%s: MAX3534 tuner found",
598 KBUILD_MODNAME);
599 goto unsupported;
600 }
601
602 /* check TUA9001 ID register; reg=7e val=2328 */
603 ret = rtl28xxu_ctrl_msg(d, &req_tua9001);
604 if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) {
605 priv->tuner = TUNER_RTL2832_TUA9001;
606 /* TODO implement tuner */
607 dev_info(&d->udev->dev, "%s: TUA9001 tuner found",
608 KBUILD_MODNAME);
609 goto unsupported;
610 }
611
612 /* check MXL5007R ID register; reg=d9 val=14 */
613 ret = rtl28xxu_ctrl_msg(d, &req_mxl5007t);
614 if (ret == 0 && buf[0] == 0x14) {
615 priv->tuner = TUNER_RTL2832_MXL5007T;
616 /* TODO implement tuner */
617 dev_info(&d->udev->dev, "%s: MXL5007T tuner found",
618 KBUILD_MODNAME);
619 goto unsupported;
620 }
621
622 /* check E4000 ID register; reg=02 val=40 */
623 ret = rtl28xxu_ctrl_msg(d, &req_e4000);
624 if (ret == 0 && buf[0] == 0x40) {
625 priv->tuner = TUNER_RTL2832_E4000;
626 /* TODO implement tuner */
627 dev_info(&d->udev->dev, "%s: E4000 tuner found",
628 KBUILD_MODNAME);
629 goto unsupported;
630 }
631
632 /* check TDA18272 ID register; reg=00 val=c760 */
633 ret = rtl28xxu_ctrl_msg(d, &req_tda18272);
634 if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) {
635 priv->tuner = TUNER_RTL2832_TDA18272;
636 /* TODO implement tuner */
637 dev_info(&d->udev->dev, "%s: TDA18272 tuner found",
638 KBUILD_MODNAME);
639 goto unsupported;
640 }
641
642unsupported:
643 /* close demod I2C gate */
644 ret = rtl28xxu_ctrl_msg(d, &req_gate_close);
645 if (ret)
646 goto err;
647
648 /* tuner not found */
649 dev_dbg(&d->udev->dev, "%s: No compatible tuner found\n", __func__);
650 ret = -ENODEV;
651 return ret;
652
653found:
654 /* close demod I2C gate */
655 ret = rtl28xxu_ctrl_msg(d, &req_gate_close);
656 if (ret)
657 goto err;
658
659 /* attach demodulator */
660 adap->fe[0] = dvb_attach(rtl2832_attach, rtl2832_config,
661 &d->i2c_adap);
662 if (adap->fe[0] == NULL) {
663 ret = -ENODEV;
664 goto err;
665 }
666
667 /* set fe callbacks */
668 adap->fe[0]->callback = rtl2832u_frontend_callback;
669
670 return ret;
671
672err:
673 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
674 return ret;
675}
676
677static struct qt1010_config rtl28xxu_qt1010_config = {
678 .i2c_address = 0x62, /* 0xc4 */
679};
680
681static struct mt2060_config rtl28xxu_mt2060_config = {
682 .i2c_address = 0x60, /* 0xc0 */
683 .clock_out = 0,
684};
685
686static struct mxl5005s_config rtl28xxu_mxl5005s_config = {
687 .i2c_address = 0x63, /* 0xc6 */
688 .if_freq = IF_FREQ_4570000HZ,
689 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
690 .agc_mode = MXL_SINGLE_AGC,
691 .tracking_filter = MXL_TF_C_H,
692 .rssi_enable = MXL_RSSI_ENABLE,
693 .cap_select = MXL_CAP_SEL_ENABLE,
694 .div_out = MXL_DIV_OUT_4,
695 .clock_out = MXL_CLOCK_OUT_DISABLE,
696 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
697 .top = MXL5005S_TOP_25P2,
698 .mod_mode = MXL_DIGITAL_MODE,
699 .if_mode = MXL_ZERO_IF,
700 .AgcMasterByte = 0x00,
701};
702
703static int rtl2831u_tuner_attach(struct dvb_usb_adapter *adap)
704{
705 int ret;
706 struct dvb_usb_device *d = adap_to_d(adap);
707 struct rtl28xxu_priv *priv = d_to_priv(d);
708 struct i2c_adapter *rtl2830_tuner_i2c;
709 struct dvb_frontend *fe;
710
711 dev_dbg(&d->udev->dev, "%s:\n", __func__);
712
713 /* use rtl2830 driver I2C adapter, for more info see rtl2830 driver */
714 rtl2830_tuner_i2c = rtl2830_get_tuner_i2c_adapter(adap->fe[0]);
715
716 switch (priv->tuner) {
717 case TUNER_RTL2830_QT1010:
718 fe = dvb_attach(qt1010_attach, adap->fe[0],
719 rtl2830_tuner_i2c, &rtl28xxu_qt1010_config);
720 break;
721 case TUNER_RTL2830_MT2060:
722 fe = dvb_attach(mt2060_attach, adap->fe[0],
723 rtl2830_tuner_i2c, &rtl28xxu_mt2060_config,
724 1220);
725 break;
726 case TUNER_RTL2830_MXL5005S:
727 fe = dvb_attach(mxl5005s_attach, adap->fe[0],
728 rtl2830_tuner_i2c, &rtl28xxu_mxl5005s_config);
729 break;
730 default:
731 fe = NULL;
732 dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
733 priv->tuner);
734 }
735
736 if (fe == NULL) {
737 ret = -ENODEV;
738 goto err;
739 }
740
741 return 0;
742err:
743 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
744 return ret;
745}
746
747static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
748{
749 int ret;
750 struct dvb_usb_device *d = adap_to_d(adap);
751 struct rtl28xxu_priv *priv = d_to_priv(d);
752 struct dvb_frontend *fe;
753
754 dev_dbg(&d->udev->dev, "%s:\n", __func__);
755
756 switch (priv->tuner) {
757 case TUNER_RTL2832_FC0012:
758 fe = dvb_attach(fc0012_attach, adap->fe[0],
759 &d->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ);
760
761 /* since fc0012 includs reading the signal strength delegate
762 * that to the tuner driver */
763 adap->fe[0]->ops.read_signal_strength =
764 adap->fe[0]->ops.tuner_ops.get_rf_strength;
765 return 0;
766 break;
767 case TUNER_RTL2832_FC0013:
768 fe = dvb_attach(fc0013_attach, adap->fe[0],
769 &d->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ);
770
771 /* fc0013 also supports signal strength reading */
772 adap->fe[0]->ops.read_signal_strength =
773 adap->fe[0]->ops.tuner_ops.get_rf_strength;
774 return 0;
775 default:
776 fe = NULL;
777 dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
778 priv->tuner);
779 }
780
781 if (fe == NULL) {
782 ret = -ENODEV;
783 goto err;
784 }
785
786 return 0;
787err:
788 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
789 return ret;
790}
791
792static int rtl28xxu_init(struct dvb_usb_device *d)
793{
794 int ret;
795 u8 val;
796
797 dev_dbg(&d->udev->dev, "%s:\n", __func__);
798
799 /* init USB endpoints */
800 ret = rtl28xx_rd_reg(d, USB_SYSCTL_0, &val);
801 if (ret)
802 goto err;
803
804 /* enable DMA and Full Packet Mode*/
805 val |= 0x09;
806 ret = rtl28xx_wr_reg(d, USB_SYSCTL_0, val);
807 if (ret)
808 goto err;
809
810 /* set EPA maximum packet size to 0x0200 */
811 ret = rtl28xx_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4);
812 if (ret)
813 goto err;
814
815 /* change EPA FIFO length */
816 ret = rtl28xx_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4);
817 if (ret)
818 goto err;
819
820 return ret;
821err:
822 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
823 return ret;
824}
825
826static int rtl28xxu_streaming_ctrl(struct dvb_frontend *fe , int onoff)
827{
828 int ret;
829 u8 buf[2];
830 struct dvb_usb_device *d = fe_to_d(fe);
831
832 dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
833
834 if (onoff) {
835 buf[0] = 0x00;
836 buf[1] = 0x00;
837 } else {
838 buf[0] = 0x10; /* stall EPA */
839 buf[1] = 0x02; /* reset EPA */
840 }
841
842 ret = rtl28xx_wr_regs(d, USB_EPA_CTL, buf, 2);
843 if (ret)
844 goto err;
845
846 return ret;
847err:
848 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
849 return ret;
850}
851
852static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff)
853{
854 int ret;
855 u8 gpio, sys0;
856
857 dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
858
859 /* demod adc */
860 ret = rtl28xx_rd_reg(d, SYS_SYS0, &sys0);
861 if (ret)
862 goto err;
863
864 /* tuner power, read GPIOs */
865 ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &gpio);
866 if (ret)
867 goto err;
868
869 dev_dbg(&d->udev->dev, "%s: RD SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__,
870 sys0, gpio);
871
872 if (onoff) {
873 gpio |= 0x01; /* GPIO0 = 1 */
874 gpio &= (~0x10); /* GPIO4 = 0 */
875 gpio |= 0x04; /* GPIO2 = 1, LED on */
876 sys0 = sys0 & 0x0f;
877 sys0 |= 0xe0;
878 } else {
879 gpio &= (~0x01); /* GPIO0 = 0 */
880 gpio |= 0x10; /* GPIO4 = 1 */
881 gpio &= (~0x04); /* GPIO2 = 1, LED off */
882 sys0 = sys0 & (~0xc0);
883 }
884
885 dev_dbg(&d->udev->dev, "%s: WR SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__,
886 sys0, gpio);
887
888 /* demod adc */
889 ret = rtl28xx_wr_reg(d, SYS_SYS0, sys0);
890 if (ret)
891 goto err;
892
893 /* tuner power, write GPIOs */
894 ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, gpio);
895 if (ret)
896 goto err;
897
898 return ret;
899err:
900 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
901 return ret;
902}
903
904static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff)
905{
906 int ret;
907 u8 val;
908
909 dev_dbg(&d->udev->dev, "%s: onoff=%d\n", __func__, onoff);
910
911 if (onoff) {
912 /* set output values */
913 ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
914 if (ret)
915 goto err;
916
917 val |= 0x08;
918 val &= 0xef;
919
920 ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
921 if (ret)
922 goto err;
923
924 /* demod_ctl_1 */
925 ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
926 if (ret)
927 goto err;
928
929 val &= 0xef;
930
931 ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
932 if (ret)
933 goto err;
934
935 /* demod control */
936 /* PLL enable */
937 ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
938 if (ret)
939 goto err;
940
941 /* bit 7 to 1 */
942 val |= 0x80;
943
944 ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
945 if (ret)
946 goto err;
947
948 /* demod HW reset */
949 ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
950 if (ret)
951 goto err;
952 /* bit 5 to 0 */
953 val &= 0xdf;
954
955 ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
956 if (ret)
957 goto err;
958
959 ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
960 if (ret)
961 goto err;
962
963 val |= 0x20;
964
965 ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
966 if (ret)
967 goto err;
968
969 mdelay(5);
970
971 /*enable ADC_Q and ADC_I */
972 ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
973 if (ret)
974 goto err;
975
976 val |= 0x48;
977
978 ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
979 if (ret)
980 goto err;
981
982
983 } else {
984 /* demod_ctl_1 */
985 ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
986 if (ret)
987 goto err;
988
989 val |= 0x0c;
990
991 ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
992 if (ret)
993 goto err;
994
995 /* set output values */
996 ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
997 if (ret)
998 goto err;
999
1000 val |= 0x10;
1001
1002 ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
1003 if (ret)
1004 goto err;
1005
1006 /* demod control */
1007 ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
1008 if (ret)
1009 goto err;
1010
1011 val &= 0x37;
1012
1013 ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
1014 if (ret)
1015 goto err;
1016
1017 }
1018
1019 return ret;
1020err:
1021 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
1022 return ret;
1023}
1024
1025
1026static int rtl2831u_rc_query(struct dvb_usb_device *d)
1027{
1028 int ret, i;
1029 struct rtl28xxu_priv *priv = d->priv;
1030 u8 buf[5];
1031 u32 rc_code;
1032 struct rtl28xxu_reg_val rc_nec_tab[] = {
1033 { 0x3033, 0x80 },
1034 { 0x3020, 0x43 },
1035 { 0x3021, 0x16 },
1036 { 0x3022, 0x16 },
1037 { 0x3023, 0x5a },
1038 { 0x3024, 0x2d },
1039 { 0x3025, 0x16 },
1040 { 0x3026, 0x01 },
1041 { 0x3028, 0xb0 },
1042 { 0x3029, 0x04 },
1043 { 0x302c, 0x88 },
1044 { 0x302e, 0x13 },
1045 { 0x3030, 0xdf },
1046 { 0x3031, 0x05 },
1047 };
1048
1049 /* init remote controller */
1050 if (!priv->rc_active) {
1051 for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
1052 ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg,
1053 rc_nec_tab[i].val);
1054 if (ret)
1055 goto err;
1056 }
1057 priv->rc_active = true;
1058 }
1059
1060 ret = rtl2831_rd_regs(d, SYS_IRRC_RP, buf, 5);
1061 if (ret)
1062 goto err;
1063
1064 if (buf[4] & 0x01) {
1065 if (buf[2] == (u8) ~buf[3]) {
1066 if (buf[0] == (u8) ~buf[1]) {
1067 /* NEC standard (16 bit) */
1068 rc_code = buf[0] << 8 | buf[2];
1069 } else {
1070 /* NEC extended (24 bit) */
1071 rc_code = buf[0] << 16 |
1072 buf[1] << 8 | buf[2];
1073 }
1074 } else {
1075 /* NEC full (32 bit) */
1076 rc_code = buf[0] << 24 | buf[1] << 16 |
1077 buf[2] << 8 | buf[3];
1078 }
1079
1080 rc_keydown(d->rc_dev, rc_code, 0);
1081
1082 ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1);
1083 if (ret)
1084 goto err;
1085
1086 /* repeated intentionally to avoid extra keypress */
1087 ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1);
1088 if (ret)
1089 goto err;
1090 }
1091
1092 return ret;
1093err:
1094 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
1095 return ret;
1096}
1097
1098static int rtl2831u_get_rc_config(struct dvb_usb_device *d,
1099 struct dvb_usb_rc *rc)
1100{
1101 rc->map_name = RC_MAP_EMPTY;
1102 rc->allowed_protos = RC_TYPE_NEC;
1103 rc->query = rtl2831u_rc_query;
1104 rc->interval = 400;
1105
1106 return 0;
1107}
1108
1109static int rtl2832u_rc_query(struct dvb_usb_device *d)
1110{
1111 int ret, i;
1112 struct rtl28xxu_priv *priv = d->priv;
1113 u8 buf[128];
1114 int len;
1115 struct rtl28xxu_reg_val rc_nec_tab[] = {
1116 { IR_RX_CTRL, 0x20 },
1117 { IR_RX_BUF_CTRL, 0x80 },
1118 { IR_RX_IF, 0xff },
1119 { IR_RX_IE, 0xff },
1120 { IR_MAX_DURATION0, 0xd0 },
1121 { IR_MAX_DURATION1, 0x07 },
1122 { IR_IDLE_LEN0, 0xc0 },
1123 { IR_IDLE_LEN1, 0x00 },
1124 { IR_GLITCH_LEN, 0x03 },
1125 { IR_RX_CLK, 0x09 },
1126 { IR_RX_CFG, 0x1c },
1127 { IR_MAX_H_TOL_LEN, 0x1e },
1128 { IR_MAX_L_TOL_LEN, 0x1e },
1129 { IR_RX_CTRL, 0x80 },
1130 };
1131
1132 /* init remote controller */
1133 if (!priv->rc_active) {
1134 for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
1135 ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg,
1136 rc_nec_tab[i].val);
1137 if (ret)
1138 goto err;
1139 }
1140 priv->rc_active = true;
1141 }
1142
1143 ret = rtl28xx_rd_reg(d, IR_RX_IF, &buf[0]);
1144 if (ret)
1145 goto err;
1146
1147 if (buf[0] != 0x83)
1148 goto exit;
1149
1150 ret = rtl28xx_rd_reg(d, IR_RX_BC, &buf[0]);
1151 if (ret)
1152 goto err;
1153
1154 len = buf[0];
1155 ret = rtl2831_rd_regs(d, IR_RX_BUF, buf, len);
1156
1157 /* TODO: pass raw IR to Kernel IR decoder */
1158
1159 ret = rtl28xx_wr_reg(d, IR_RX_IF, 0x03);
1160 ret = rtl28xx_wr_reg(d, IR_RX_BUF_CTRL, 0x80);
1161 ret = rtl28xx_wr_reg(d, IR_RX_CTRL, 0x80);
1162
1163exit:
1164 return ret;
1165err:
1166 dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
1167 return ret;
1168}
1169
1170static int rtl2832u_get_rc_config(struct dvb_usb_device *d,
1171 struct dvb_usb_rc *rc)
1172{
1173 rc->map_name = RC_MAP_EMPTY;
1174 rc->allowed_protos = RC_TYPE_NEC;
1175 rc->query = rtl2832u_rc_query;
1176 rc->interval = 400;
1177
1178 return 0;
1179}
1180
1181static const struct dvb_usb_device_properties rtl2831u_props = {
1182 .driver_name = KBUILD_MODNAME,
1183 .owner = THIS_MODULE,
1184 .adapter_nr = adapter_nr,
1185 .size_of_priv = sizeof(struct rtl28xxu_priv),
1186
1187 .power_ctrl = rtl2831u_power_ctrl,
1188 .i2c_algo = &rtl28xxu_i2c_algo,
1189 .frontend_attach = rtl2831u_frontend_attach,
1190 .tuner_attach = rtl2831u_tuner_attach,
1191 .init = rtl28xxu_init,
1192 .get_rc_config = rtl2831u_get_rc_config,
1193 .streaming_ctrl = rtl28xxu_streaming_ctrl,
1194
1195 .num_adapters = 1,
1196 .adapter = {
1197 {
1198 .stream = DVB_USB_STREAM_BULK(0x81, 6, 8 * 512),
1199 },
1200 },
1201};
1202
1203static const struct dvb_usb_device_properties rtl2832u_props = {
1204 .driver_name = KBUILD_MODNAME,
1205 .owner = THIS_MODULE,
1206 .adapter_nr = adapter_nr,
1207 .size_of_priv = sizeof(struct rtl28xxu_priv),
1208
1209 .power_ctrl = rtl2832u_power_ctrl,
1210 .i2c_algo = &rtl28xxu_i2c_algo,
1211 .frontend_attach = rtl2832u_frontend_attach,
1212 .tuner_attach = rtl2832u_tuner_attach,
1213 .init = rtl28xxu_init,
1214 .get_rc_config = rtl2832u_get_rc_config,
1215 .streaming_ctrl = rtl28xxu_streaming_ctrl,
1216
1217 .num_adapters = 1,
1218 .adapter = {
1219 {
1220 .stream = DVB_USB_STREAM_BULK(0x81, 6, 8 * 512),
1221 },
1222 },
1223};
1224
1225static const struct usb_device_id rtl28xxu_id_table[] = {
1226 { DVB_USB_DEVICE(USB_VID_REALTEK, USB_PID_REALTEK_RTL2831U,
1227 &rtl2831u_props, "Realtek RTL2831U reference design", NULL) },
1228 { DVB_USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT,
1229 &rtl2831u_props, "Freecom USB2.0 DVB-T", NULL) },
1230 { DVB_USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT_2,
1231 &rtl2831u_props, "Freecom USB2.0 DVB-T", NULL) },
1232
1233 { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_BLACK_REV1,
1234 &rtl2832u_props, "Terratec Cinergy T Stick Black", NULL) },
1235 { DVB_USB_DEVICE(USB_VID_GTEK, USB_PID_DELOCK_USB2_DVBT,
1236 &rtl2832u_props, "G-Tek Electronics Group Lifeview LV5TDLX DVB-T", NULL) },
1237 { DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK,
1238 &rtl2832u_props, "NOXON DAB/DAB+ USB dongle", NULL) },
1239 { }
1240};
1241MODULE_DEVICE_TABLE(usb, rtl28xxu_id_table);
1242
1243static struct usb_driver rtl28xxu_usb_driver = {
1244 .name = KBUILD_MODNAME,
1245 .id_table = rtl28xxu_id_table,
1246 .probe = dvb_usbv2_probe,
1247 .disconnect = dvb_usbv2_disconnect,
1248 .suspend = dvb_usbv2_suspend,
1249 .resume = dvb_usbv2_resume,
1250 .no_dynamic_id = 1,
1251 .soft_unbind = 1,
1252};
1253
1254module_usb_driver(rtl28xxu_usb_driver);
1255
1256MODULE_DESCRIPTION("Realtek RTL28xxU DVB USB driver");
1257MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1258MODULE_AUTHOR("Thomas Mair <thomas.mair86@googlemail.com>");
1259MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
new file mode 100644
index 000000000000..575edbf13a92
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h
@@ -0,0 +1,254 @@
1/*
2 * Realtek RTL28xxU DVB USB driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
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 along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#ifndef RTL28XXU_H
23#define RTL28XXU_H
24
25#include "dvb_usb.h"
26
27#define deb_dump(r, t, v, i, b, l) { \
28 char *direction; \
29 if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
30 direction = ">>>"; \
31 else \
32 direction = "<<<"; \
33 dev_dbg(&d->udev->dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x " \
34 "%s [%d bytes]\n", __func__, t, r, v & 0xff, v >> 8, \
35 i & 0xff, i >> 8, l & 0xff, l >> 8, direction, l); \
36}
37
38/*
39 * USB commands
40 * (usb_control_msg() index parameter)
41 */
42
43#define DEMOD 0x0000
44#define USB 0x0100
45#define SYS 0x0200
46#define I2C 0x0300
47#define I2C_DA 0x0600
48
49#define CMD_WR_FLAG 0x0010
50#define CMD_DEMOD_RD 0x0000
51#define CMD_DEMOD_WR 0x0010
52#define CMD_USB_RD 0x0100
53#define CMD_USB_WR 0x0110
54#define CMD_SYS_RD 0x0200
55#define CMD_IR_RD 0x0201
56#define CMD_IR_WR 0x0211
57#define CMD_SYS_WR 0x0210
58#define CMD_I2C_RD 0x0300
59#define CMD_I2C_WR 0x0310
60#define CMD_I2C_DA_RD 0x0600
61#define CMD_I2C_DA_WR 0x0610
62
63
64struct rtl28xxu_priv {
65 u8 chip_id;
66 u8 tuner;
67 u8 page; /* integrated demod active register page */
68 bool rc_active;
69};
70
71enum rtl28xxu_chip_id {
72 CHIP_ID_NONE,
73 CHIP_ID_RTL2831U,
74 CHIP_ID_RTL2832U,
75};
76
77enum rtl28xxu_tuner {
78 TUNER_NONE,
79
80 TUNER_RTL2830_QT1010,
81 TUNER_RTL2830_MT2060,
82 TUNER_RTL2830_MXL5005S,
83
84 TUNER_RTL2832_MT2266,
85 TUNER_RTL2832_FC2580,
86 TUNER_RTL2832_MT2063,
87 TUNER_RTL2832_MAX3543,
88 TUNER_RTL2832_TUA9001,
89 TUNER_RTL2832_MXL5007T,
90 TUNER_RTL2832_FC0012,
91 TUNER_RTL2832_E4000,
92 TUNER_RTL2832_TDA18272,
93 TUNER_RTL2832_FC0013,
94};
95
96struct rtl28xxu_req {
97 u16 value;
98 u16 index;
99 u16 size;
100 u8 *data;
101};
102
103struct rtl28xxu_reg_val {
104 u16 reg;
105 u8 val;
106};
107
108/*
109 * memory map
110 *
111 * 0x0000 DEMOD : demodulator
112 * 0x2000 USB : SIE, USB endpoint, debug, DMA
113 * 0x3000 SYS : system
114 * 0xfc00 RC : remote controller (not RTL2831U)
115 */
116
117/*
118 * USB registers
119 */
120/* SIE Control Registers */
121#define USB_SYSCTL 0x2000 /* USB system control */
122#define USB_SYSCTL_0 0x2000 /* USB system control */
123#define USB_SYSCTL_1 0x2001 /* USB system control */
124#define USB_SYSCTL_2 0x2002 /* USB system control */
125#define USB_SYSCTL_3 0x2003 /* USB system control */
126#define USB_IRQSTAT 0x2008 /* SIE interrupt status */
127#define USB_IRQEN 0x200C /* SIE interrupt enable */
128#define USB_CTRL 0x2010 /* USB control */
129#define USB_STAT 0x2014 /* USB status */
130#define USB_DEVADDR 0x2018 /* USB device address */
131#define USB_TEST 0x201C /* USB test mode */
132#define USB_FRAME_NUMBER 0x2020 /* frame number */
133#define USB_FIFO_ADDR 0x2028 /* address of SIE FIFO RAM */
134#define USB_FIFO_CMD 0x202A /* SIE FIFO RAM access command */
135#define USB_FIFO_DATA 0x2030 /* SIE FIFO RAM data */
136/* Endpoint Registers */
137#define EP0_SETUPA 0x20F8 /* EP 0 setup packet lower byte */
138#define EP0_SETUPB 0x20FC /* EP 0 setup packet higher byte */
139#define USB_EP0_CFG 0x2104 /* EP 0 configure */
140#define USB_EP0_CTL 0x2108 /* EP 0 control */
141#define USB_EP0_STAT 0x210C /* EP 0 status */
142#define USB_EP0_IRQSTAT 0x2110 /* EP 0 interrupt status */
143#define USB_EP0_IRQEN 0x2114 /* EP 0 interrupt enable */
144#define USB_EP0_MAXPKT 0x2118 /* EP 0 max packet size */
145#define USB_EP0_BC 0x2120 /* EP 0 FIFO byte counter */
146#define USB_EPA_CFG 0x2144 /* EP A configure */
147#define USB_EPA_CFG_0 0x2144 /* EP A configure */
148#define USB_EPA_CFG_1 0x2145 /* EP A configure */
149#define USB_EPA_CFG_2 0x2146 /* EP A configure */
150#define USB_EPA_CFG_3 0x2147 /* EP A configure */
151#define USB_EPA_CTL 0x2148 /* EP A control */
152#define USB_EPA_CTL_0 0x2148 /* EP A control */
153#define USB_EPA_CTL_1 0x2149 /* EP A control */
154#define USB_EPA_CTL_2 0x214A /* EP A control */
155#define USB_EPA_CTL_3 0x214B /* EP A control */
156#define USB_EPA_STAT 0x214C /* EP A status */
157#define USB_EPA_IRQSTAT 0x2150 /* EP A interrupt status */
158#define USB_EPA_IRQEN 0x2154 /* EP A interrupt enable */
159#define USB_EPA_MAXPKT 0x2158 /* EP A max packet size */
160#define USB_EPA_MAXPKT_0 0x2158 /* EP A max packet size */
161#define USB_EPA_MAXPKT_1 0x2159 /* EP A max packet size */
162#define USB_EPA_MAXPKT_2 0x215A /* EP A max packet size */
163#define USB_EPA_MAXPKT_3 0x215B /* EP A max packet size */
164#define USB_EPA_FIFO_CFG 0x2160 /* EP A FIFO configure */
165#define USB_EPA_FIFO_CFG_0 0x2160 /* EP A FIFO configure */
166#define USB_EPA_FIFO_CFG_1 0x2161 /* EP A FIFO configure */
167#define USB_EPA_FIFO_CFG_2 0x2162 /* EP A FIFO configure */
168#define USB_EPA_FIFO_CFG_3 0x2163 /* EP A FIFO configure */
169/* Debug Registers */
170#define USB_PHYTSTDIS 0x2F04 /* PHY test disable */
171#define USB_TOUT_VAL 0x2F08 /* USB time-out time */
172#define USB_VDRCTRL 0x2F10 /* UTMI vendor signal control */
173#define USB_VSTAIN 0x2F14 /* UTMI vendor signal status in */
174#define USB_VLOADM 0x2F18 /* UTMI load vendor signal status in */
175#define USB_VSTAOUT 0x2F1C /* UTMI vendor signal status out */
176#define USB_UTMI_TST 0x2F80 /* UTMI test */
177#define USB_UTMI_STATUS 0x2F84 /* UTMI status */
178#define USB_TSTCTL 0x2F88 /* test control */
179#define USB_TSTCTL2 0x2F8C /* test control 2 */
180#define USB_PID_FORCE 0x2F90 /* force PID */
181#define USB_PKTERR_CNT 0x2F94 /* packet error counter */
182#define USB_RXERR_CNT 0x2F98 /* RX error counter */
183#define USB_MEM_BIST 0x2F9C /* MEM BIST test */
184#define USB_SLBBIST 0x2FA0 /* self-loop-back BIST */
185#define USB_CNTTEST 0x2FA4 /* counter test */
186#define USB_PHYTST 0x2FC0 /* USB PHY test */
187#define USB_DBGIDX 0x2FF0 /* select individual block debug signal */
188#define USB_DBGMUX 0x2FF4 /* debug signal module mux */
189
190/*
191 * SYS registers
192 */
193/* demod control registers */
194#define SYS_SYS0 0x3000 /* include DEMOD_CTL, GPO, GPI, GPOE */
195#define SYS_DEMOD_CTL 0x3000 /* control register for DVB-T demodulator */
196/* GPIO registers */
197#define SYS_GPIO_OUT_VAL 0x3001 /* output value of GPIO */
198#define SYS_GPIO_IN_VAL 0x3002 /* input value of GPIO */
199#define SYS_GPIO_OUT_EN 0x3003 /* output enable of GPIO */
200#define SYS_SYS1 0x3004 /* include GPD, SYSINTE, SYSINTS, GP_CFG0 */
201#define SYS_GPIO_DIR 0x3004 /* direction control for GPIO */
202#define SYS_SYSINTE 0x3005 /* system interrupt enable */
203#define SYS_SYSINTS 0x3006 /* system interrupt status */
204#define SYS_GPIO_CFG0 0x3007 /* PAD configuration for GPIO0-GPIO3 */
205#define SYS_SYS2 0x3008 /* include GP_CFG1 and 3 reserved bytes */
206#define SYS_GPIO_CFG1 0x3008 /* PAD configuration for GPIO4 */
207#define SYS_DEMOD_CTL1 0x300B
208
209/* IrDA registers */
210#define SYS_IRRC_PSR 0x3020 /* IR protocol selection */
211#define SYS_IRRC_PER 0x3024 /* IR protocol extension */
212#define SYS_IRRC_SF 0x3028 /* IR sampling frequency */
213#define SYS_IRRC_DPIR 0x302C /* IR data package interval */
214#define SYS_IRRC_CR 0x3030 /* IR control */
215#define SYS_IRRC_RP 0x3034 /* IR read port */
216#define SYS_IRRC_SR 0x3038 /* IR status */
217/* I2C master registers */
218#define SYS_I2CCR 0x3040 /* I2C clock */
219#define SYS_I2CMCR 0x3044 /* I2C master control */
220#define SYS_I2CMSTR 0x3048 /* I2C master SCL timing */
221#define SYS_I2CMSR 0x304C /* I2C master status */
222#define SYS_I2CMFR 0x3050 /* I2C master FIFO */
223
224/*
225 * IR registers
226 */
227#define IR_RX_BUF 0xFC00
228#define IR_RX_IE 0xFD00
229#define IR_RX_IF 0xFD01
230#define IR_RX_CTRL 0xFD02
231#define IR_RX_CFG 0xFD03
232#define IR_MAX_DURATION0 0xFD04
233#define IR_MAX_DURATION1 0xFD05
234#define IR_IDLE_LEN0 0xFD06
235#define IR_IDLE_LEN1 0xFD07
236#define IR_GLITCH_LEN 0xFD08
237#define IR_RX_BUF_CTRL 0xFD09
238#define IR_RX_BUF_DATA 0xFD0A
239#define IR_RX_BC 0xFD0B
240#define IR_RX_CLK 0xFD0C
241#define IR_RX_C_COUNT_L 0xFD0D
242#define IR_RX_C_COUNT_H 0xFD0E
243#define IR_SUSPEND_CTRL 0xFD10
244#define IR_ERR_TOL_CTRL 0xFD11
245#define IR_UNIT_LEN 0xFD12
246#define IR_ERR_TOL_LEN 0xFD13
247#define IR_MAX_H_TOL_LEN 0xFD14
248#define IR_MAX_L_TOL_LEN 0xFD15
249#define IR_MASK_CTRL 0xFD16
250#define IR_MASK_DATA 0xFD17
251#define IR_RES_MASK_ADDR 0xFD18
252#define IR_RES_MASK_T_LEN 0xFD19
253
254#endif
diff --git a/drivers/media/usb/dvb-usb-v2/usb_urb.c b/drivers/media/usb/dvb-usb-v2/usb_urb.c
new file mode 100644
index 000000000000..eaf673a3978d
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/usb_urb.c
@@ -0,0 +1,357 @@
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
15int usb_urb_reconfig(struct usb_data_stream *stream,
16 struct usb_data_stream_properties *props);
17
18static void usb_urb_complete(struct urb *urb)
19{
20 struct usb_data_stream *stream = urb->context;
21 int ptype = usb_pipetype(urb->pipe);
22 int i;
23 u8 *b;
24
25 dev_dbg(&stream->udev->dev, "%s: %s urb completed status=%d " \
26 "length=%d/%d pack_num=%d errors=%d\n", __func__,
27 ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk",
28 urb->status, urb->actual_length,
29 urb->transfer_buffer_length,
30 urb->number_of_packets, urb->error_count);
31
32 switch (urb->status) {
33 case 0: /* success */
34 case -ETIMEDOUT: /* NAK */
35 break;
36 case -ECONNRESET: /* kill */
37 case -ENOENT:
38 case -ESHUTDOWN:
39 return;
40 default: /* error */
41 dev_dbg(&stream->udev->dev, "%s: urb completition failed=%d\n",
42 __func__, urb->status);
43 break;
44 }
45
46 b = (u8 *) urb->transfer_buffer;
47 switch (ptype) {
48 case PIPE_ISOCHRONOUS:
49 for (i = 0; i < urb->number_of_packets; i++) {
50 if (urb->iso_frame_desc[i].status != 0)
51 dev_dbg(&stream->udev->dev, "%s: iso frame " \
52 "descriptor has an error=%d\n",
53 __func__,
54 urb->iso_frame_desc[i].status);
55 else if (urb->iso_frame_desc[i].actual_length > 0)
56 stream->complete(stream,
57 b + urb->iso_frame_desc[i].offset,
58 urb->iso_frame_desc[i].actual_length);
59
60 urb->iso_frame_desc[i].status = 0;
61 urb->iso_frame_desc[i].actual_length = 0;
62 }
63 break;
64 case PIPE_BULK:
65 if (urb->actual_length > 0)
66 stream->complete(stream, b, urb->actual_length);
67 break;
68 default:
69 dev_err(&stream->udev->dev, "%s: unknown endpoint type in " \
70 "completition handler\n", KBUILD_MODNAME);
71 return;
72 }
73 usb_submit_urb(urb, GFP_ATOMIC);
74}
75
76int usb_urb_killv2(struct usb_data_stream *stream)
77{
78 int i;
79 for (i = 0; i < stream->urbs_submitted; i++) {
80 dev_dbg(&stream->udev->dev, "%s: kill urb=%d\n", __func__, i);
81 /* stop the URB */
82 usb_kill_urb(stream->urb_list[i]);
83 }
84 stream->urbs_submitted = 0;
85 return 0;
86}
87
88int usb_urb_submitv2(struct usb_data_stream *stream,
89 struct usb_data_stream_properties *props)
90{
91 int i, ret;
92
93 if (props) {
94 ret = usb_urb_reconfig(stream, props);
95 if (ret < 0)
96 return ret;
97 }
98
99 for (i = 0; i < stream->urbs_initialized; i++) {
100 dev_dbg(&stream->udev->dev, "%s: submit urb=%d\n", __func__, i);
101 ret = usb_submit_urb(stream->urb_list[i], GFP_ATOMIC);
102 if (ret) {
103 dev_err(&stream->udev->dev, "%s: could not submit " \
104 "urb no. %d - get them all back\n",
105 KBUILD_MODNAME, i);
106 usb_urb_killv2(stream);
107 return ret;
108 }
109 stream->urbs_submitted++;
110 }
111 return 0;
112}
113
114int usb_urb_free_urbs(struct usb_data_stream *stream)
115{
116 int i;
117
118 usb_urb_killv2(stream);
119
120 for (i = stream->urbs_initialized - 1; i >= 0; i--) {
121 if (stream->urb_list[i]) {
122 dev_dbg(&stream->udev->dev, "%s: free urb=%d\n",
123 __func__, i);
124 /* free the URBs */
125 usb_free_urb(stream->urb_list[i]);
126 }
127 }
128 stream->urbs_initialized = 0;
129
130 return 0;
131}
132
133static int usb_urb_alloc_bulk_urbs(struct usb_data_stream *stream)
134{
135 int i, j;
136
137 /* allocate the URBs */
138 for (i = 0; i < stream->props.count; i++) {
139 dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
140 stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
141 if (!stream->urb_list[i]) {
142 dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
143 for (j = 0; j < i; j++)
144 usb_free_urb(stream->urb_list[j]);
145 return -ENOMEM;
146 }
147 usb_fill_bulk_urb(stream->urb_list[i],
148 stream->udev,
149 usb_rcvbulkpipe(stream->udev,
150 stream->props.endpoint),
151 stream->buf_list[i],
152 stream->props.u.bulk.buffersize,
153 usb_urb_complete, stream);
154
155 stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
156 stream->urb_list[i]->transfer_dma = stream->dma_addr[i];
157 stream->urbs_initialized++;
158 }
159 return 0;
160}
161
162static int usb_urb_alloc_isoc_urbs(struct usb_data_stream *stream)
163{
164 int i, j;
165
166 /* allocate the URBs */
167 for (i = 0; i < stream->props.count; i++) {
168 struct urb *urb;
169 int frame_offset = 0;
170 dev_dbg(&stream->udev->dev, "%s: alloc urb=%d\n", __func__, i);
171 stream->urb_list[i] = usb_alloc_urb(
172 stream->props.u.isoc.framesperurb, GFP_ATOMIC);
173 if (!stream->urb_list[i]) {
174 dev_dbg(&stream->udev->dev, "%s: failed\n", __func__);
175 for (j = 0; j < i; j++)
176 usb_free_urb(stream->urb_list[j]);
177 return -ENOMEM;
178 }
179
180 urb = stream->urb_list[i];
181
182 urb->dev = stream->udev;
183 urb->context = stream;
184 urb->complete = usb_urb_complete;
185 urb->pipe = usb_rcvisocpipe(stream->udev,
186 stream->props.endpoint);
187 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
188 urb->interval = stream->props.u.isoc.interval;
189 urb->number_of_packets = stream->props.u.isoc.framesperurb;
190 urb->transfer_buffer_length = stream->props.u.isoc.framesize *
191 stream->props.u.isoc.framesperurb;
192 urb->transfer_buffer = stream->buf_list[i];
193 urb->transfer_dma = stream->dma_addr[i];
194
195 for (j = 0; j < stream->props.u.isoc.framesperurb; j++) {
196 urb->iso_frame_desc[j].offset = frame_offset;
197 urb->iso_frame_desc[j].length =
198 stream->props.u.isoc.framesize;
199 frame_offset += stream->props.u.isoc.framesize;
200 }
201
202 stream->urbs_initialized++;
203 }
204 return 0;
205}
206
207int usb_free_stream_buffers(struct usb_data_stream *stream)
208{
209 if (stream->state & USB_STATE_URB_BUF) {
210 while (stream->buf_num) {
211 stream->buf_num--;
212 dev_dbg(&stream->udev->dev, "%s: free buf=%d\n",
213 __func__, stream->buf_num);
214 usb_free_coherent(stream->udev, stream->buf_size,
215 stream->buf_list[stream->buf_num],
216 stream->dma_addr[stream->buf_num]);
217 }
218 }
219
220 stream->state &= ~USB_STATE_URB_BUF;
221
222 return 0;
223}
224
225int usb_alloc_stream_buffers(struct usb_data_stream *stream, int num,
226 unsigned long size)
227{
228 stream->buf_num = 0;
229 stream->buf_size = size;
230
231 dev_dbg(&stream->udev->dev, "%s: all in all I will use %lu bytes for " \
232 "streaming\n", __func__, num * size);
233
234 for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
235 stream->buf_list[stream->buf_num] = usb_alloc_coherent(
236 stream->udev, size, GFP_ATOMIC,
237 &stream->dma_addr[stream->buf_num]);
238 if (!stream->buf_list[stream->buf_num]) {
239 dev_dbg(&stream->udev->dev, "%s: alloc buf=%d failed\n",
240 __func__, stream->buf_num);
241 usb_free_stream_buffers(stream);
242 return -ENOMEM;
243 }
244
245 dev_dbg(&stream->udev->dev, "%s: alloc buf=%d %p (dma %llu)\n",
246 __func__, stream->buf_num,
247 stream->buf_list[stream->buf_num],
248 (long long)stream->dma_addr[stream->buf_num]);
249 memset(stream->buf_list[stream->buf_num], 0, size);
250 stream->state |= USB_STATE_URB_BUF;
251 }
252
253 return 0;
254}
255
256int usb_urb_reconfig(struct usb_data_stream *stream,
257 struct usb_data_stream_properties *props)
258{
259 int buf_size;
260
261 if (!props)
262 return 0;
263
264 /* check allocated buffers are large enough for the request */
265 if (props->type == USB_BULK) {
266 buf_size = stream->props.u.bulk.buffersize;
267 } else if (props->type == USB_ISOC) {
268 buf_size = props->u.isoc.framesize * props->u.isoc.framesperurb;
269 } else {
270 dev_err(&stream->udev->dev, "%s: invalid endpoint type=%d\n",
271 KBUILD_MODNAME, props->type);
272 return -EINVAL;
273 }
274
275 if (stream->buf_num < props->count || stream->buf_size < buf_size) {
276 dev_err(&stream->udev->dev, "%s: cannot reconfigure as " \
277 "allocated buffers are too small\n",
278 KBUILD_MODNAME);
279 return -EINVAL;
280 }
281
282 /* check if all fields are same */
283 if (stream->props.type == props->type &&
284 stream->props.count == props->count &&
285 stream->props.endpoint == props->endpoint) {
286 if (props->type == USB_BULK &&
287 props->u.bulk.buffersize ==
288 stream->props.u.bulk.buffersize)
289 return 0;
290 else if (props->type == USB_ISOC &&
291 props->u.isoc.framesperurb ==
292 stream->props.u.isoc.framesperurb &&
293 props->u.isoc.framesize ==
294 stream->props.u.isoc.framesize &&
295 props->u.isoc.interval ==
296 stream->props.u.isoc.interval)
297 return 0;
298 }
299
300 dev_dbg(&stream->udev->dev, "%s: re-alloc urbs\n", __func__);
301
302 usb_urb_free_urbs(stream);
303 memcpy(&stream->props, props, sizeof(*props));
304 if (props->type == USB_BULK)
305 return usb_urb_alloc_bulk_urbs(stream);
306 else if (props->type == USB_ISOC)
307 return usb_urb_alloc_isoc_urbs(stream);
308
309 return 0;
310}
311
312int usb_urb_initv2(struct usb_data_stream *stream,
313 const struct usb_data_stream_properties *props)
314{
315 int ret;
316
317 if (!stream || !props)
318 return -EINVAL;
319
320 memcpy(&stream->props, props, sizeof(*props));
321
322 if (!stream->complete) {
323 dev_err(&stream->udev->dev, "%s: there is no data callback - " \
324 "this doesn't make sense\n", KBUILD_MODNAME);
325 return -EINVAL;
326 }
327
328 switch (stream->props.type) {
329 case USB_BULK:
330 ret = usb_alloc_stream_buffers(stream, stream->props.count,
331 stream->props.u.bulk.buffersize);
332 if (ret < 0)
333 return ret;
334
335 return usb_urb_alloc_bulk_urbs(stream);
336 case USB_ISOC:
337 ret = usb_alloc_stream_buffers(stream, stream->props.count,
338 stream->props.u.isoc.framesize *
339 stream->props.u.isoc.framesperurb);
340 if (ret < 0)
341 return ret;
342
343 return usb_urb_alloc_isoc_urbs(stream);
344 default:
345 dev_err(&stream->udev->dev, "%s: unknown urb-type for data " \
346 "transfer\n", KBUILD_MODNAME);
347 return -EINVAL;
348 }
349}
350
351int usb_urb_exitv2(struct usb_data_stream *stream)
352{
353 usb_urb_free_urbs(stream);
354 usb_free_stream_buffers(stream);
355
356 return 0;
357}
diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig
new file mode 100644
index 000000000000..00173ee15d4a
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/Kconfig
@@ -0,0 +1,313 @@
1config DVB_USB
2 tristate "Support for various USB DVB devices"
3 depends on DVB_CORE && USB && I2C && RC_CORE
4 help
5 By enabling this you will be able to choose the various supported
6 USB1.1 and USB2.0 DVB devices.
7
8 Almost every USB device needs a firmware, please look into
9 <file:Documentation/dvb/README.dvb-usb>.
10
11 For a complete list of supported USB devices see the LinuxTV DVB Wiki:
12 <http://www.linuxtv.org/wiki/index.php/DVB_USB>
13
14 Say Y if you own a USB DVB device.
15
16config DVB_USB_DEBUG
17 bool "Enable extended debug support for all DVB-USB devices"
18 depends on DVB_USB
19 help
20 Say Y if you want to enable debugging. See modinfo dvb-usb (and the
21 appropriate drivers) for debug levels.
22
23config DVB_USB_A800
24 tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)"
25 depends on DVB_USB
26 select DVB_DIB3000MC
27 select DVB_PLL if !DVB_FE_CUSTOMISE
28 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
29 help
30 Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
31
32config DVB_USB_DIBUSB_MB
33 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)"
34 depends on DVB_USB
35 select DVB_PLL if !DVB_FE_CUSTOMISE
36 select DVB_DIB3000MB
37 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
38 help
39 Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
40 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
41
42 For an up-to-date list of devices supported by this driver, have a look
43 on the Linux-DVB Wiki at www.linuxtv.org.
44
45 Say Y if you own such a device and want to use it. You should build it as
46 a module.
47
48config DVB_USB_DIBUSB_MB_FAULTY
49 bool "Support faulty USB IDs"
50 depends on DVB_USB_DIBUSB_MB
51 help
52 Support for faulty USB IDs due to an invalid EEPROM on some Artec devices.
53
54config DVB_USB_DIBUSB_MC
55 tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
56 depends on DVB_USB
57 select DVB_DIB3000MC
58 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
59 help
60 Support for USB2.0 DVB-T receivers based on reference designs made by
61 DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
62
63 For an up-to-date list of devices supported by this driver, have a look
64 on the Linux-DVB Wiki at www.linuxtv.org.
65
66 Say Y if you own such a device and want to use it. You should build it as
67 a module.
68
69config DVB_USB_DIB0700
70 tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)"
71 depends on DVB_USB
72 select DVB_DIB7000P if !DVB_FE_CUSTOMISE
73 select DVB_DIB7000M if !DVB_FE_CUSTOMISE
74 select DVB_DIB8000 if !DVB_FE_CUSTOMISE
75 select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
76 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
77 select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
78 select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
79 select DVB_TUNER_DIB0090 if !DVB_FE_CUSTOMISE
80 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
81 select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE
82 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
83 select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
84 select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
85 select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
86 help
87 Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
88 USB bridge is also present in devices having the DiB7700 DVB-T-USB
89 silicon. This chip can be found in devices offered by Hauppauge,
90 Avermedia and other big and small companies.
91
92 For an up-to-date list of devices supported by this driver, have a look
93 on the LinuxTV Wiki at www.linuxtv.org.
94
95 Say Y if you own such a device and want to use it. You should build it as
96 a module.
97
98config DVB_USB_UMT_010
99 tristate "HanfTek UMT-010 DVB-T USB2.0 support"
100 depends on DVB_USB
101 select DVB_PLL if !DVB_FE_CUSTOMISE
102 select DVB_DIB3000MC
103 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
104 select DVB_MT352 if !DVB_FE_CUSTOMISE
105 help
106 Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
107
108config DVB_USB_CXUSB
109 tristate "Conexant USB2.0 hybrid reference design support"
110 depends on DVB_USB
111 select DVB_PLL if !DVB_FE_CUSTOMISE
112 select DVB_CX22702 if !DVB_FE_CUSTOMISE
113 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
114 select DVB_MT352 if !DVB_FE_CUSTOMISE
115 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
116 select DVB_DIB7000P if !DVB_FE_CUSTOMISE
117 select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
118 select DVB_ATBM8830 if !DVB_FE_CUSTOMISE
119 select DVB_LGS8GXX if !DVB_FE_CUSTOMISE
120 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
121 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
122 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
123 select MEDIA_TUNER_MAX2165 if !MEDIA_TUNER_CUSTOMISE
124 help
125 Say Y here to support the Conexant USB2.0 hybrid reference design.
126 Currently, only DVB and ATSC modes are supported, analog mode
127 shall be added in the future. Devices that require this module:
128
129 Medion MD95700 hybrid USB2.0 device.
130 DViCO FusionHDTV (Bluebird) USB2.0 devices
131
132config DVB_USB_M920X
133 tristate "Uli m920x DVB-T USB2.0 support"
134 depends on DVB_USB
135 select DVB_MT352 if !DVB_FE_CUSTOMISE
136 select DVB_TDA1004X if !DVB_FE_CUSTOMISE
137 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
138 select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
139 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
140 help
141 Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
142 Currently, only devices with a product id of
143 "DTV USB MINI" (in cold state) are supported.
144 Firmware required.
145
146config DVB_USB_DIGITV
147 tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
148 depends on DVB_USB
149 select DVB_PLL if !DVB_FE_CUSTOMISE
150 select DVB_NXT6000 if !DVB_FE_CUSTOMISE
151 select DVB_MT352 if !DVB_FE_CUSTOMISE
152 help
153 Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver.
154
155config DVB_USB_VP7045
156 tristate "TwinhanDTV Alpha/MagicBoxII, DNTV tinyUSB2, Beetle USB2.0 support"
157 depends on DVB_USB
158 help
159 Say Y here to support the
160
161 TwinhanDTV Alpha (stick) (VP-7045),
162 TwinhanDTV MagicBox II (VP-7046),
163 DigitalNow TinyUSB 2 DVB-t,
164 DigitalRise USB 2.0 Ter (Beetle) and
165 TYPHOON DVB-T USB DRIVE
166
167 DVB-T USB2.0 receivers.
168
169config DVB_USB_VP702X
170 tristate "TwinhanDTV StarBox and clones DVB-S USB2.0 support"
171 depends on DVB_USB
172 help
173 Say Y here to support the
174
175 TwinhanDTV StarBox,
176 DigitalRise USB Starbox and
177 TYPHOON DVB-S USB 2.0 BOX
178
179 DVB-S USB2.0 receivers.
180
181config DVB_USB_GP8PSK
182 tristate "GENPIX 8PSK->USB module support"
183 depends on DVB_USB
184 help
185 Say Y here to support the
186 GENPIX 8psk module
187
188 DVB-S USB2.0 receivers.
189
190config DVB_USB_NOVA_T_USB2
191 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
192 depends on DVB_USB
193 select DVB_DIB3000MC
194 select DVB_PLL if !DVB_FE_CUSTOMISE
195 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
196 help
197 Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
198
199config DVB_USB_TTUSB2
200 tristate "Pinnacle 400e DVB-S USB2.0 support"
201 depends on DVB_USB
202 select DVB_TDA10086 if !DVB_FE_CUSTOMISE
203 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
204 select DVB_TDA826X if !DVB_FE_CUSTOMISE
205 help
206 Say Y here to support the Pinnacle 400e DVB-S USB2.0 receiver. The
207 firmware protocol used by this module is similar to the one used by the
208 old ttusb-driver - that's why the module is called dvb-usb-ttusb2.
209
210config DVB_USB_DTT200U
211 tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)"
212 depends on DVB_USB
213 help
214 Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver.
215
216 The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan).
217
218 The WT-220U and its clones are pen-sized.
219
220config DVB_USB_OPERA1
221 tristate "Opera1 DVB-S USB2.0 receiver"
222 depends on DVB_USB
223 select DVB_STV0299 if !DVB_FE_CUSTOMISE
224 select DVB_PLL if !DVB_FE_CUSTOMISE
225 help
226 Say Y here to support the Opera DVB-S USB2.0 receiver.
227
228config DVB_USB_AF9005
229 tristate "Afatech AF9005 DVB-T USB1.1 support"
230 depends on DVB_USB && EXPERIMENTAL
231 select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
232 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
233 help
234 Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
235 and the TerraTec Cinergy T USB XE (Rev.1)
236
237config DVB_USB_AF9005_REMOTE
238 tristate "Afatech AF9005 default remote control support"
239 depends on DVB_USB_AF9005
240 help
241 Say Y here to support the default remote control decoding for the
242 Afatech AF9005 based receiver.
243
244config DVB_USB_PCTV452E
245 tristate "Pinnacle PCTV HDTV Pro USB device/TT Connect S2-3600"
246 depends on DVB_USB
247 select TTPCI_EEPROM
248 select DVB_LNBP22 if !DVB_FE_CUSTOMISE
249 select DVB_STB0899 if !DVB_FE_CUSTOMISE
250 select DVB_STB6100 if !DVB_FE_CUSTOMISE
251 help
252 Support for external USB adapter designed by Pinnacle,
253 shipped under the brand name 'PCTV HDTV Pro USB'.
254 Also supports TT Connect S2-3600/3650 cards.
255 Say Y if you own such a device and want to use it.
256
257config DVB_USB_DW2102
258 tristate "DvbWorld & TeVii DVB-S/S2 USB2.0 support"
259 depends on DVB_USB
260 select DVB_PLL if !DVB_FE_CUSTOMISE
261 select DVB_STV0299 if !DVB_FE_CUSTOMISE
262 select DVB_STV0288 if !DVB_FE_CUSTOMISE
263 select DVB_STB6000 if !DVB_FE_CUSTOMISE
264 select DVB_CX24116 if !DVB_FE_CUSTOMISE
265 select DVB_SI21XX if !DVB_FE_CUSTOMISE
266 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
267 select DVB_MT312 if !DVB_FE_CUSTOMISE
268 select DVB_ZL10039 if !DVB_FE_CUSTOMISE
269 select DVB_DS3000 if !DVB_FE_CUSTOMISE
270 select DVB_STB6100 if !DVB_FE_CUSTOMISE
271 select DVB_STV6110 if !DVB_FE_CUSTOMISE
272 select DVB_STV0900 if !DVB_FE_CUSTOMISE
273 help
274 Say Y here to support the DvbWorld, TeVii, Prof DVB-S/S2 USB2.0
275 receivers.
276
277config DVB_USB_CINERGY_T2
278 tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver"
279 depends on DVB_USB
280 help
281 Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers
282
283 Say Y if you own such a device and want to use it.
284
285config DVB_USB_DTV5100
286 tristate "AME DTV-5100 USB2.0 DVB-T support"
287 depends on DVB_USB
288 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
289 select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
290 help
291 Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
292
293config DVB_USB_FRIIO
294 tristate "Friio ISDB-T USB2.0 Receiver support"
295 depends on DVB_USB
296 help
297 Say Y here to support the Japanese DTV receiver Friio.
298
299config DVB_USB_AZ6027
300 tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support"
301 depends on DVB_USB
302 select DVB_STB0899 if !DVB_FE_CUSTOMISE
303 select DVB_STB6100 if !DVB_FE_CUSTOMISE
304 help
305 Say Y here to support the AZ6027 device
306
307config DVB_USB_TECHNISAT_USB2
308 tristate "Technisat DVB-S/S2 USB2.0 support"
309 depends on DVB_USB
310 select DVB_STV090x if !DVB_FE_CUSTOMISE
311 select DVB_STV6110x if !DVB_FE_CUSTOMISE
312 help
313 Say Y here to support the Technisat USB2 DVB-S/S2 device
diff --git a/drivers/media/usb/dvb-usb/Makefile b/drivers/media/usb/dvb-usb/Makefile
new file mode 100644
index 000000000000..a5630e30eadc
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/Makefile
@@ -0,0 +1,82 @@
1dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o usb-urb.o
2obj-$(CONFIG_DVB_USB) += dvb-usb.o
3
4dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o
5obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o
6
7dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o
8obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o
9
10dvb-usb-gp8psk-objs = gp8psk.o gp8psk-fe.o
11obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o
12
13dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
14obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
15
16dvb-usb-dibusb-common-objs = dibusb-common.o
17
18dvb-usb-a800-objs = a800.o
19obj-$(CONFIG_DVB_USB_A800) += dvb-usb-dibusb-common.o dvb-usb-a800.o
20
21dvb-usb-dibusb-mb-objs = dibusb-mb.o
22obj-$(CONFIG_DVB_USB_DIBUSB_MB) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mb.o
23
24dvb-usb-dibusb-mc-objs = dibusb-mc.o
25obj-$(CONFIG_DVB_USB_DIBUSB_MC) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mc.o
26
27dvb-usb-nova-t-usb2-objs = nova-t-usb2.o
28obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2.o
29
30dvb-usb-umt-010-objs = umt-010.o
31obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o
32
33dvb-usb-m920x-objs = m920x.o
34obj-$(CONFIG_DVB_USB_M920X) += dvb-usb-m920x.o
35
36dvb-usb-digitv-objs = digitv.o
37obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
38
39dvb-usb-cxusb-objs = cxusb.o
40obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o
41
42dvb-usb-ttusb2-objs = ttusb2.o
43obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o
44
45dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o
46obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o
47
48dvb-usb-opera-objs = opera1.o
49obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o
50
51dvb-usb-af9005-objs = af9005.o af9005-fe.o
52obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o
53
54dvb-usb-af9005-remote-objs = af9005-remote.o
55obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
56
57dvb-usb-pctv452e-objs = pctv452e.o
58obj-$(CONFIG_DVB_USB_PCTV452E) += dvb-usb-pctv452e.o
59
60dvb-usb-dw2102-objs = dw2102.o
61obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o
62
63dvb-usb-dtv5100-objs = dtv5100.o
64obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o
65
66dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o
67obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
68
69dvb-usb-friio-objs = friio.o friio-fe.o
70obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
71
72dvb-usb-az6027-objs = az6027.o
73obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
74
75dvb-usb-technisat-usb2-objs = technisat-usb2.o
76obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
77
78ccflags-y += -I$(srctree)/drivers/media/dvb-core
79ccflags-y += -I$(srctree)/drivers/media/dvb-frontends/
80# due to tuner-xc3028
81ccflags-y += -I$(srctree)/drivers/media/common/tuners
82ccflags-y += -I$(srctree)/drivers/media/dvb/ttpci
diff --git a/drivers/media/usb/dvb-usb/a800.c b/drivers/media/usb/dvb-usb/a800.c
new file mode 100644
index 000000000000..8d7fef84afd8
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/a800.c
@@ -0,0 +1,191 @@
1/* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T
2 * USB2.0 (A800) DVB-T receiver.
3 *
4 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to
7 * - AVerMedia who kindly provided information and
8 * - Glen Harris who suffered from my mistakes during development.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation, version 2.
13 *
14 * see Documentation/dvb/README.dvb-usb for more information
15 */
16#include "dibusb.h"
17
18static int debug;
19module_param(debug, int, 0644);
20MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS);
21
22DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
23
24#define deb_rc(args...) dprintk(debug,0x01,args)
25
26static int a800_power_ctrl(struct dvb_usb_device *d, int onoff)
27{
28 /* do nothing for the AVerMedia */
29 return 0;
30}
31
32/* assure to put cold to 0 for iManufacturer == 1 */
33static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
34 struct dvb_usb_device_description **desc, int *cold)
35{
36 *cold = udev->descriptor.iManufacturer != 1;
37 return 0;
38}
39
40static struct rc_map_table rc_map_a800_table[] = {
41 { 0x0201, KEY_MODE }, /* SOURCE */
42 { 0x0200, KEY_POWER2 }, /* POWER */
43 { 0x0205, KEY_1 }, /* 1 */
44 { 0x0206, KEY_2 }, /* 2 */
45 { 0x0207, KEY_3 }, /* 3 */
46 { 0x0209, KEY_4 }, /* 4 */
47 { 0x020a, KEY_5 }, /* 5 */
48 { 0x020b, KEY_6 }, /* 6 */
49 { 0x020d, KEY_7 }, /* 7 */
50 { 0x020e, KEY_8 }, /* 8 */
51 { 0x020f, KEY_9 }, /* 9 */
52 { 0x0212, KEY_LEFT }, /* L / DISPLAY */
53 { 0x0211, KEY_0 }, /* 0 */
54 { 0x0213, KEY_RIGHT }, /* R / CH RTN */
55 { 0x0217, KEY_CAMERA }, /* SNAP SHOT */
56 { 0x0210, KEY_LAST }, /* 16-CH PREV */
57 { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */
58 { 0x020c, KEY_ZOOM }, /* FULL SCREEN */
59 { 0x021f, KEY_VOLUMEUP }, /* VOL UP */
60 { 0x0214, KEY_MUTE }, /* MUTE */
61 { 0x0208, KEY_AUDIO }, /* AUDIO */
62 { 0x0219, KEY_RECORD }, /* RECORD */
63 { 0x0218, KEY_PLAY }, /* PLAY */
64 { 0x021b, KEY_STOP }, /* STOP */
65 { 0x021a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */
66 { 0x021d, KEY_BACK }, /* << / RED */
67 { 0x021c, KEY_FORWARD }, /* >> / YELLOW */
68 { 0x0203, KEY_TEXT }, /* TELETEXT */
69 { 0x0204, KEY_EPG }, /* EPG */
70 { 0x0215, KEY_MENU }, /* MENU */
71
72 { 0x0303, KEY_CHANNELUP }, /* CH UP */
73 { 0x0302, KEY_CHANNELDOWN }, /* CH DOWN */
74 { 0x0301, KEY_FIRST }, /* |<< / GREEN */
75 { 0x0300, KEY_LAST }, /* >>| / BLUE */
76
77};
78
79static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
80{
81 int ret;
82 u8 *key = kmalloc(5, GFP_KERNEL);
83 if (!key)
84 return -ENOMEM;
85
86 if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
87 0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
88 2000) != 5) {
89 ret = -ENODEV;
90 goto out;
91 }
92
93 /* call the universal NEC remote processor, to find out the key's state and event */
94 dvb_usb_nec_rc_key_to_event(d,key,event,state);
95 if (key[0] != 0)
96 deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
97 ret = 0;
98out:
99 kfree(key);
100 return ret;
101}
102
103/* USB Driver stuff */
104static struct dvb_usb_device_properties a800_properties;
105
106static int a800_probe(struct usb_interface *intf,
107 const struct usb_device_id *id)
108{
109 return dvb_usb_device_init(intf, &a800_properties,
110 THIS_MODULE, NULL, adapter_nr);
111}
112
113/* do not change the order of the ID table */
114static struct usb_device_id a800_table [] = {
115/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_COLD) },
116/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_WARM) },
117 { } /* Terminating entry */
118};
119MODULE_DEVICE_TABLE (usb, a800_table);
120
121static struct dvb_usb_device_properties a800_properties = {
122 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
123
124 .usb_ctrl = CYPRESS_FX2,
125 .firmware = "dvb-usb-avertv-a800-02.fw",
126
127 .num_adapters = 1,
128 .adapter = {
129 {
130 .num_frontends = 1,
131 .fe = {{
132 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
133 .pid_filter_count = 32,
134 .streaming_ctrl = dibusb2_0_streaming_ctrl,
135 .pid_filter = dibusb_pid_filter,
136 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
137
138 .frontend_attach = dibusb_dib3000mc_frontend_attach,
139 .tuner_attach = dibusb_dib3000mc_tuner_attach,
140
141 /* parameter for the MPEG2-data transfer */
142 .stream = {
143 .type = USB_BULK,
144 .count = 7,
145 .endpoint = 0x06,
146 .u = {
147 .bulk = {
148 .buffersize = 4096,
149 }
150 }
151 },
152 }},
153 .size_of_priv = sizeof(struct dibusb_state),
154 },
155 },
156
157 .power_ctrl = a800_power_ctrl,
158 .identify_state = a800_identify_state,
159
160 .rc.legacy = {
161 .rc_interval = DEFAULT_RC_INTERVAL,
162 .rc_map_table = rc_map_a800_table,
163 .rc_map_size = ARRAY_SIZE(rc_map_a800_table),
164 .rc_query = a800_rc_query,
165 },
166
167 .i2c_algo = &dibusb_i2c_algo,
168
169 .generic_bulk_ctrl_endpoint = 0x01,
170 .num_device_descs = 1,
171 .devices = {
172 { "AVerMedia AverTV DVB-T USB 2.0 (A800)",
173 { &a800_table[0], NULL },
174 { &a800_table[1], NULL },
175 },
176 }
177};
178
179static struct usb_driver a800_driver = {
180 .name = "dvb_usb_a800",
181 .probe = a800_probe,
182 .disconnect = dvb_usb_device_exit,
183 .id_table = a800_table,
184};
185
186module_usb_driver(a800_driver);
187
188MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
189MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)");
190MODULE_VERSION("1.0");
191MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/af9005-fe.c b/drivers/media/usb/dvb-usb/af9005-fe.c
new file mode 100644
index 000000000000..740f3f496f12
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/af9005-fe.c
@@ -0,0 +1,1487 @@
1/* Frontend part of the Linux driver for the Afatech 9005
2 * USB1.1 DVB-T receiver.
3 *
4 * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
5 *
6 * Thanks to Afatech who kindly provided information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * see Documentation/dvb/README.dvb-usb for more information
23 */
24#include "af9005.h"
25#include "af9005-script.h"
26#include "mt2060.h"
27#include "qt1010.h"
28#include <asm/div64.h>
29
30struct af9005_fe_state {
31 struct dvb_usb_device *d;
32 fe_status_t stat;
33
34 /* retraining parameters */
35 u32 original_fcw;
36 u16 original_rf_top;
37 u16 original_if_top;
38 u16 original_if_min;
39 u16 original_aci0_if_top;
40 u16 original_aci1_if_top;
41 u16 original_aci0_if_min;
42 u8 original_if_unplug_th;
43 u8 original_rf_unplug_th;
44 u8 original_dtop_if_unplug_th;
45 u8 original_dtop_rf_unplug_th;
46
47 /* statistics */
48 u32 pre_vit_error_count;
49 u32 pre_vit_bit_count;
50 u32 ber;
51 u32 post_vit_error_count;
52 u32 post_vit_bit_count;
53 u32 unc;
54 u16 abort_count;
55
56 int opened;
57 int strong;
58 unsigned long next_status_check;
59 struct dvb_frontend frontend;
60};
61
62static int af9005_write_word_agc(struct dvb_usb_device *d, u16 reghi,
63 u16 reglo, u8 pos, u8 len, u16 value)
64{
65 int ret;
66
67 if ((ret = af9005_write_ofdm_register(d, reglo, (u8) (value & 0xff))))
68 return ret;
69 return af9005_write_register_bits(d, reghi, pos, len,
70 (u8) ((value & 0x300) >> 8));
71}
72
73static int af9005_read_word_agc(struct dvb_usb_device *d, u16 reghi,
74 u16 reglo, u8 pos, u8 len, u16 * value)
75{
76 int ret;
77 u8 temp0, temp1;
78
79 if ((ret = af9005_read_ofdm_register(d, reglo, &temp0)))
80 return ret;
81 if ((ret = af9005_read_ofdm_register(d, reghi, &temp1)))
82 return ret;
83 switch (pos) {
84 case 0:
85 *value = ((u16) (temp1 & 0x03) << 8) + (u16) temp0;
86 break;
87 case 2:
88 *value = ((u16) (temp1 & 0x0C) << 6) + (u16) temp0;
89 break;
90 case 4:
91 *value = ((u16) (temp1 & 0x30) << 4) + (u16) temp0;
92 break;
93 case 6:
94 *value = ((u16) (temp1 & 0xC0) << 2) + (u16) temp0;
95 break;
96 default:
97 err("invalid pos in read word agc");
98 return -EINVAL;
99 }
100 return 0;
101
102}
103
104static int af9005_is_fecmon_available(struct dvb_frontend *fe, int *available)
105{
106 struct af9005_fe_state *state = fe->demodulator_priv;
107 int ret;
108 u8 temp;
109
110 *available = false;
111
112 ret = af9005_read_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en,
113 fec_vtb_rsd_mon_en_pos,
114 fec_vtb_rsd_mon_en_len, &temp);
115 if (ret)
116 return ret;
117 if (temp & 1) {
118 ret =
119 af9005_read_register_bits(state->d,
120 xd_p_reg_ofsm_read_rbc_en,
121 reg_ofsm_read_rbc_en_pos,
122 reg_ofsm_read_rbc_en_len, &temp);
123 if (ret)
124 return ret;
125 if ((temp & 1) == 0)
126 *available = true;
127
128 }
129 return 0;
130}
131
132static int af9005_get_post_vit_err_cw_count(struct dvb_frontend *fe,
133 u32 * post_err_count,
134 u32 * post_cw_count,
135 u16 * abort_count)
136{
137 struct af9005_fe_state *state = fe->demodulator_priv;
138 int ret;
139 u32 err_count;
140 u32 cw_count;
141 u8 temp, temp0, temp1, temp2;
142 u16 loc_abort_count;
143
144 *post_err_count = 0;
145 *post_cw_count = 0;
146
147 /* check if error bit count is ready */
148 ret =
149 af9005_read_register_bits(state->d, xd_r_fec_rsd_ber_rdy,
150 fec_rsd_ber_rdy_pos, fec_rsd_ber_rdy_len,
151 &temp);
152 if (ret)
153 return ret;
154 if (!temp) {
155 deb_info("rsd counter not ready\n");
156 return 100;
157 }
158 /* get abort count */
159 ret =
160 af9005_read_ofdm_register(state->d,
161 xd_r_fec_rsd_abort_packet_cnt_7_0,
162 &temp0);
163 if (ret)
164 return ret;
165 ret =
166 af9005_read_ofdm_register(state->d,
167 xd_r_fec_rsd_abort_packet_cnt_15_8,
168 &temp1);
169 if (ret)
170 return ret;
171 loc_abort_count = ((u16) temp1 << 8) + temp0;
172
173 /* get error count */
174 ret =
175 af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_7_0,
176 &temp0);
177 if (ret)
178 return ret;
179 ret =
180 af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_15_8,
181 &temp1);
182 if (ret)
183 return ret;
184 ret =
185 af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_23_16,
186 &temp2);
187 if (ret)
188 return ret;
189 err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0;
190 *post_err_count = err_count - (u32) loc_abort_count *8 * 8;
191
192 /* get RSD packet number */
193 ret =
194 af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0,
195 &temp0);
196 if (ret)
197 return ret;
198 ret =
199 af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8,
200 &temp1);
201 if (ret)
202 return ret;
203 cw_count = ((u32) temp1 << 8) + temp0;
204 if (cw_count == 0) {
205 err("wrong RSD packet count");
206 return -EIO;
207 }
208 deb_info("POST abort count %d err count %d rsd packets %d\n",
209 loc_abort_count, err_count, cw_count);
210 *post_cw_count = cw_count - (u32) loc_abort_count;
211 *abort_count = loc_abort_count;
212 return 0;
213
214}
215
216static int af9005_get_post_vit_ber(struct dvb_frontend *fe,
217 u32 * post_err_count, u32 * post_cw_count,
218 u16 * abort_count)
219{
220 u32 loc_cw_count = 0, loc_err_count;
221 u16 loc_abort_count = 0;
222 int ret;
223
224 ret =
225 af9005_get_post_vit_err_cw_count(fe, &loc_err_count, &loc_cw_count,
226 &loc_abort_count);
227 if (ret)
228 return ret;
229 *post_err_count = loc_err_count;
230 *post_cw_count = loc_cw_count * 204 * 8;
231 *abort_count = loc_abort_count;
232
233 return 0;
234}
235
236static int af9005_get_pre_vit_err_bit_count(struct dvb_frontend *fe,
237 u32 * pre_err_count,
238 u32 * pre_bit_count)
239{
240 struct af9005_fe_state *state = fe->demodulator_priv;
241 u8 temp, temp0, temp1, temp2;
242 u32 super_frame_count, x, bits;
243 int ret;
244
245 ret =
246 af9005_read_register_bits(state->d, xd_r_fec_vtb_ber_rdy,
247 fec_vtb_ber_rdy_pos, fec_vtb_ber_rdy_len,
248 &temp);
249 if (ret)
250 return ret;
251 if (!temp) {
252 deb_info("viterbi counter not ready\n");
253 return 101; /* ERR_APO_VTB_COUNTER_NOT_READY; */
254 }
255 ret =
256 af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_7_0,
257 &temp0);
258 if (ret)
259 return ret;
260 ret =
261 af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_15_8,
262 &temp1);
263 if (ret)
264 return ret;
265 ret =
266 af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_23_16,
267 &temp2);
268 if (ret)
269 return ret;
270 *pre_err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0;
271
272 ret =
273 af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0,
274 &temp0);
275 if (ret)
276 return ret;
277 ret =
278 af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8,
279 &temp1);
280 if (ret)
281 return ret;
282 super_frame_count = ((u32) temp1 << 8) + temp0;
283 if (super_frame_count == 0) {
284 deb_info("super frame count 0\n");
285 return 102;
286 }
287
288 /* read fft mode */
289 ret =
290 af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod,
291 reg_tpsd_txmod_pos, reg_tpsd_txmod_len,
292 &temp);
293 if (ret)
294 return ret;
295 if (temp == 0) {
296 /* 2K */
297 x = 1512;
298 } else if (temp == 1) {
299 /* 8k */
300 x = 6048;
301 } else {
302 err("Invalid fft mode");
303 return -EINVAL;
304 }
305
306 /* read modulation mode */
307 ret =
308 af9005_read_register_bits(state->d, xd_g_reg_tpsd_const,
309 reg_tpsd_const_pos, reg_tpsd_const_len,
310 &temp);
311 if (ret)
312 return ret;
313 switch (temp) {
314 case 0: /* QPSK */
315 bits = 2;
316 break;
317 case 1: /* QAM_16 */
318 bits = 4;
319 break;
320 case 2: /* QAM_64 */
321 bits = 6;
322 break;
323 default:
324 err("invalid modulation mode");
325 return -EINVAL;
326 }
327 *pre_bit_count = super_frame_count * 68 * 4 * x * bits;
328 deb_info("PRE err count %d frame count %d bit count %d\n",
329 *pre_err_count, super_frame_count, *pre_bit_count);
330 return 0;
331}
332
333static int af9005_reset_pre_viterbi(struct dvb_frontend *fe)
334{
335 struct af9005_fe_state *state = fe->demodulator_priv;
336 int ret;
337
338 /* set super frame count to 1 */
339 ret =
340 af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0,
341 1 & 0xff);
342 if (ret)
343 return ret;
344 ret = af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8,
345 1 >> 8);
346 if (ret)
347 return ret;
348 /* reset pre viterbi error count */
349 ret =
350 af9005_write_register_bits(state->d, xd_p_fec_vtb_ber_rst,
351 fec_vtb_ber_rst_pos, fec_vtb_ber_rst_len,
352 1);
353
354 return ret;
355}
356
357static int af9005_reset_post_viterbi(struct dvb_frontend *fe)
358{
359 struct af9005_fe_state *state = fe->demodulator_priv;
360 int ret;
361
362 /* set packet unit */
363 ret =
364 af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0,
365 10000 & 0xff);
366 if (ret)
367 return ret;
368 ret =
369 af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8,
370 10000 >> 8);
371 if (ret)
372 return ret;
373 /* reset post viterbi error count */
374 ret =
375 af9005_write_register_bits(state->d, xd_p_fec_rsd_ber_rst,
376 fec_rsd_ber_rst_pos, fec_rsd_ber_rst_len,
377 1);
378
379 return ret;
380}
381
382static int af9005_get_statistic(struct dvb_frontend *fe)
383{
384 struct af9005_fe_state *state = fe->demodulator_priv;
385 int ret, fecavailable;
386 u64 numerator, denominator;
387
388 deb_info("GET STATISTIC\n");
389 ret = af9005_is_fecmon_available(fe, &fecavailable);
390 if (ret)
391 return ret;
392 if (!fecavailable) {
393 deb_info("fecmon not available\n");
394 return 0;
395 }
396
397 ret = af9005_get_pre_vit_err_bit_count(fe, &state->pre_vit_error_count,
398 &state->pre_vit_bit_count);
399 if (ret == 0) {
400 af9005_reset_pre_viterbi(fe);
401 if (state->pre_vit_bit_count > 0) {
402 /* according to v 0.0.4 of the dvb api ber should be a multiple
403 of 10E-9 so we have to multiply the error count by
404 10E9=1000000000 */
405 numerator =
406 (u64) state->pre_vit_error_count * (u64) 1000000000;
407 denominator = (u64) state->pre_vit_bit_count;
408 state->ber = do_div(numerator, denominator);
409 } else {
410 state->ber = 0xffffffff;
411 }
412 }
413
414 ret = af9005_get_post_vit_ber(fe, &state->post_vit_error_count,
415 &state->post_vit_bit_count,
416 &state->abort_count);
417 if (ret == 0) {
418 ret = af9005_reset_post_viterbi(fe);
419 state->unc += state->abort_count;
420 if (ret)
421 return ret;
422 }
423 return 0;
424}
425
426static int af9005_fe_refresh_state(struct dvb_frontend *fe)
427{
428 struct af9005_fe_state *state = fe->demodulator_priv;
429 if (time_after(jiffies, state->next_status_check)) {
430 deb_info("REFRESH STATE\n");
431
432 /* statistics */
433 if (af9005_get_statistic(fe))
434 err("get_statistic_failed");
435 state->next_status_check = jiffies + 250 * HZ / 1000;
436 }
437 return 0;
438}
439
440static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat)
441{
442 struct af9005_fe_state *state = fe->demodulator_priv;
443 u8 temp;
444 int ret;
445
446 if (fe->ops.tuner_ops.release == NULL)
447 return -ENODEV;
448
449 *stat = 0;
450 ret = af9005_read_register_bits(state->d, xd_p_agc_lock,
451 agc_lock_pos, agc_lock_len, &temp);
452 if (ret)
453 return ret;
454 if (temp)
455 *stat |= FE_HAS_SIGNAL;
456
457 ret = af9005_read_register_bits(state->d, xd_p_fd_tpsd_lock,
458 fd_tpsd_lock_pos, fd_tpsd_lock_len,
459 &temp);
460 if (ret)
461 return ret;
462 if (temp)
463 *stat |= FE_HAS_CARRIER;
464
465 ret = af9005_read_register_bits(state->d,
466 xd_r_mp2if_sync_byte_locked,
467 mp2if_sync_byte_locked_pos,
468 mp2if_sync_byte_locked_pos, &temp);
469 if (ret)
470 return ret;
471 if (temp)
472 *stat |= FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_LOCK;
473 if (state->opened)
474 af9005_led_control(state->d, *stat & FE_HAS_LOCK);
475
476 ret =
477 af9005_read_register_bits(state->d, xd_p_reg_strong_sginal_detected,
478 reg_strong_sginal_detected_pos,
479 reg_strong_sginal_detected_len, &temp);
480 if (ret)
481 return ret;
482 if (temp != state->strong) {
483 deb_info("adjust for strong signal %d\n", temp);
484 state->strong = temp;
485 }
486 return 0;
487}
488
489static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber)
490{
491 struct af9005_fe_state *state = fe->demodulator_priv;
492 if (fe->ops.tuner_ops.release == NULL)
493 return -ENODEV;
494 af9005_fe_refresh_state(fe);
495 *ber = state->ber;
496 return 0;
497}
498
499static int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
500{
501 struct af9005_fe_state *state = fe->demodulator_priv;
502 if (fe->ops.tuner_ops.release == NULL)
503 return -ENODEV;
504 af9005_fe_refresh_state(fe);
505 *unc = state->unc;
506 return 0;
507}
508
509static int af9005_fe_read_signal_strength(struct dvb_frontend *fe,
510 u16 * strength)
511{
512 struct af9005_fe_state *state = fe->demodulator_priv;
513 int ret;
514 u8 if_gain, rf_gain;
515
516 if (fe->ops.tuner_ops.release == NULL)
517 return -ENODEV;
518 ret =
519 af9005_read_ofdm_register(state->d, xd_r_reg_aagc_rf_gain,
520 &rf_gain);
521 if (ret)
522 return ret;
523 ret =
524 af9005_read_ofdm_register(state->d, xd_r_reg_aagc_if_gain,
525 &if_gain);
526 if (ret)
527 return ret;
528 /* this value has no real meaning, but i don't have the tables that relate
529 the rf and if gain with the dbm, so I just scale the value */
530 *strength = (512 - rf_gain - if_gain) << 7;
531 return 0;
532}
533
534static int af9005_fe_read_snr(struct dvb_frontend *fe, u16 * snr)
535{
536 /* the snr can be derived from the ber and the modulation
537 but I don't think this kind of complex calculations belong
538 in the driver. I may be wrong.... */
539 return -ENOSYS;
540}
541
542static int af9005_fe_program_cfoe(struct dvb_usb_device *d, u32 bw)
543{
544 u8 temp0, temp1, temp2, temp3, buf[4];
545 int ret;
546 u32 NS_coeff1_2048Nu;
547 u32 NS_coeff1_8191Nu;
548 u32 NS_coeff1_8192Nu;
549 u32 NS_coeff1_8193Nu;
550 u32 NS_coeff2_2k;
551 u32 NS_coeff2_8k;
552
553 switch (bw) {
554 case 6000000:
555 NS_coeff1_2048Nu = 0x2ADB6DC;
556 NS_coeff1_8191Nu = 0xAB7313;
557 NS_coeff1_8192Nu = 0xAB6DB7;
558 NS_coeff1_8193Nu = 0xAB685C;
559 NS_coeff2_2k = 0x156DB6E;
560 NS_coeff2_8k = 0x55B6DC;
561 break;
562
563 case 7000000:
564 NS_coeff1_2048Nu = 0x3200001;
565 NS_coeff1_8191Nu = 0xC80640;
566 NS_coeff1_8192Nu = 0xC80000;
567 NS_coeff1_8193Nu = 0xC7F9C0;
568 NS_coeff2_2k = 0x1900000;
569 NS_coeff2_8k = 0x640000;
570 break;
571
572 case 8000000:
573 NS_coeff1_2048Nu = 0x3924926;
574 NS_coeff1_8191Nu = 0xE4996E;
575 NS_coeff1_8192Nu = 0xE49249;
576 NS_coeff1_8193Nu = 0xE48B25;
577 NS_coeff2_2k = 0x1C92493;
578 NS_coeff2_8k = 0x724925;
579 break;
580 default:
581 err("Invalid bandwidth %d.", bw);
582 return -EINVAL;
583 }
584
585 /*
586 * write NS_coeff1_2048Nu
587 */
588
589 temp0 = (u8) (NS_coeff1_2048Nu & 0x000000FF);
590 temp1 = (u8) ((NS_coeff1_2048Nu & 0x0000FF00) >> 8);
591 temp2 = (u8) ((NS_coeff1_2048Nu & 0x00FF0000) >> 16);
592 temp3 = (u8) ((NS_coeff1_2048Nu & 0x03000000) >> 24);
593
594 /* big endian to make 8051 happy */
595 buf[0] = temp3;
596 buf[1] = temp2;
597 buf[2] = temp1;
598 buf[3] = temp0;
599
600 /* cfoe_NS_2k_coeff1_25_24 */
601 ret = af9005_write_ofdm_register(d, 0xAE00, buf[0]);
602 if (ret)
603 return ret;
604
605 /* cfoe_NS_2k_coeff1_23_16 */
606 ret = af9005_write_ofdm_register(d, 0xAE01, buf[1]);
607 if (ret)
608 return ret;
609
610 /* cfoe_NS_2k_coeff1_15_8 */
611 ret = af9005_write_ofdm_register(d, 0xAE02, buf[2]);
612 if (ret)
613 return ret;
614
615 /* cfoe_NS_2k_coeff1_7_0 */
616 ret = af9005_write_ofdm_register(d, 0xAE03, buf[3]);
617 if (ret)
618 return ret;
619
620 /*
621 * write NS_coeff2_2k
622 */
623
624 temp0 = (u8) ((NS_coeff2_2k & 0x0000003F));
625 temp1 = (u8) ((NS_coeff2_2k & 0x00003FC0) >> 6);
626 temp2 = (u8) ((NS_coeff2_2k & 0x003FC000) >> 14);
627 temp3 = (u8) ((NS_coeff2_2k & 0x01C00000) >> 22);
628
629 /* big endian to make 8051 happy */
630 buf[0] = temp3;
631 buf[1] = temp2;
632 buf[2] = temp1;
633 buf[3] = temp0;
634
635 ret = af9005_write_ofdm_register(d, 0xAE04, buf[0]);
636 if (ret)
637 return ret;
638
639 ret = af9005_write_ofdm_register(d, 0xAE05, buf[1]);
640 if (ret)
641 return ret;
642
643 ret = af9005_write_ofdm_register(d, 0xAE06, buf[2]);
644 if (ret)
645 return ret;
646
647 ret = af9005_write_ofdm_register(d, 0xAE07, buf[3]);
648 if (ret)
649 return ret;
650
651 /*
652 * write NS_coeff1_8191Nu
653 */
654
655 temp0 = (u8) ((NS_coeff1_8191Nu & 0x000000FF));
656 temp1 = (u8) ((NS_coeff1_8191Nu & 0x0000FF00) >> 8);
657 temp2 = (u8) ((NS_coeff1_8191Nu & 0x00FFC000) >> 16);
658 temp3 = (u8) ((NS_coeff1_8191Nu & 0x03000000) >> 24);
659
660 /* big endian to make 8051 happy */
661 buf[0] = temp3;
662 buf[1] = temp2;
663 buf[2] = temp1;
664 buf[3] = temp0;
665
666 ret = af9005_write_ofdm_register(d, 0xAE08, buf[0]);
667 if (ret)
668 return ret;
669
670 ret = af9005_write_ofdm_register(d, 0xAE09, buf[1]);
671 if (ret)
672 return ret;
673
674 ret = af9005_write_ofdm_register(d, 0xAE0A, buf[2]);
675 if (ret)
676 return ret;
677
678 ret = af9005_write_ofdm_register(d, 0xAE0B, buf[3]);
679 if (ret)
680 return ret;
681
682 /*
683 * write NS_coeff1_8192Nu
684 */
685
686 temp0 = (u8) (NS_coeff1_8192Nu & 0x000000FF);
687 temp1 = (u8) ((NS_coeff1_8192Nu & 0x0000FF00) >> 8);
688 temp2 = (u8) ((NS_coeff1_8192Nu & 0x00FFC000) >> 16);
689 temp3 = (u8) ((NS_coeff1_8192Nu & 0x03000000) >> 24);
690
691 /* big endian to make 8051 happy */
692 buf[0] = temp3;
693 buf[1] = temp2;
694 buf[2] = temp1;
695 buf[3] = temp0;
696
697 ret = af9005_write_ofdm_register(d, 0xAE0C, buf[0]);
698 if (ret)
699 return ret;
700
701 ret = af9005_write_ofdm_register(d, 0xAE0D, buf[1]);
702 if (ret)
703 return ret;
704
705 ret = af9005_write_ofdm_register(d, 0xAE0E, buf[2]);
706 if (ret)
707 return ret;
708
709 ret = af9005_write_ofdm_register(d, 0xAE0F, buf[3]);
710 if (ret)
711 return ret;
712
713 /*
714 * write NS_coeff1_8193Nu
715 */
716
717 temp0 = (u8) ((NS_coeff1_8193Nu & 0x000000FF));
718 temp1 = (u8) ((NS_coeff1_8193Nu & 0x0000FF00) >> 8);
719 temp2 = (u8) ((NS_coeff1_8193Nu & 0x00FFC000) >> 16);
720 temp3 = (u8) ((NS_coeff1_8193Nu & 0x03000000) >> 24);
721
722 /* big endian to make 8051 happy */
723 buf[0] = temp3;
724 buf[1] = temp2;
725 buf[2] = temp1;
726 buf[3] = temp0;
727
728 ret = af9005_write_ofdm_register(d, 0xAE10, buf[0]);
729 if (ret)
730 return ret;
731
732 ret = af9005_write_ofdm_register(d, 0xAE11, buf[1]);
733 if (ret)
734 return ret;
735
736 ret = af9005_write_ofdm_register(d, 0xAE12, buf[2]);
737 if (ret)
738 return ret;
739
740 ret = af9005_write_ofdm_register(d, 0xAE13, buf[3]);
741 if (ret)
742 return ret;
743
744 /*
745 * write NS_coeff2_8k
746 */
747
748 temp0 = (u8) ((NS_coeff2_8k & 0x0000003F));
749 temp1 = (u8) ((NS_coeff2_8k & 0x00003FC0) >> 6);
750 temp2 = (u8) ((NS_coeff2_8k & 0x003FC000) >> 14);
751 temp3 = (u8) ((NS_coeff2_8k & 0x01C00000) >> 22);
752
753 /* big endian to make 8051 happy */
754 buf[0] = temp3;
755 buf[1] = temp2;
756 buf[2] = temp1;
757 buf[3] = temp0;
758
759 ret = af9005_write_ofdm_register(d, 0xAE14, buf[0]);
760 if (ret)
761 return ret;
762
763 ret = af9005_write_ofdm_register(d, 0xAE15, buf[1]);
764 if (ret)
765 return ret;
766
767 ret = af9005_write_ofdm_register(d, 0xAE16, buf[2]);
768 if (ret)
769 return ret;
770
771 ret = af9005_write_ofdm_register(d, 0xAE17, buf[3]);
772 return ret;
773
774}
775
776static int af9005_fe_select_bw(struct dvb_usb_device *d, u32 bw)
777{
778 u8 temp;
779 switch (bw) {
780 case 6000000:
781 temp = 0;
782 break;
783 case 7000000:
784 temp = 1;
785 break;
786 case 8000000:
787 temp = 2;
788 break;
789 default:
790 err("Invalid bandwidth %d.", bw);
791 return -EINVAL;
792 }
793 return af9005_write_register_bits(d, xd_g_reg_bw, reg_bw_pos,
794 reg_bw_len, temp);
795}
796
797static int af9005_fe_power(struct dvb_frontend *fe, int on)
798{
799 struct af9005_fe_state *state = fe->demodulator_priv;
800 u8 temp = on;
801 int ret;
802 deb_info("power %s tuner\n", on ? "on" : "off");
803 ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0);
804 return ret;
805}
806
807static struct mt2060_config af9005_mt2060_config = {
808 0xC0
809};
810
811static struct qt1010_config af9005_qt1010_config = {
812 0xC4
813};
814
815static int af9005_fe_init(struct dvb_frontend *fe)
816{
817 struct af9005_fe_state *state = fe->demodulator_priv;
818 struct dvb_usb_adapter *adap = fe->dvb->priv;
819 int ret, i, scriptlen;
820 u8 temp, temp0 = 0, temp1 = 0, temp2 = 0;
821 u8 buf[2];
822 u16 if1;
823
824 deb_info("in af9005_fe_init\n");
825
826 /* reset */
827 deb_info("reset\n");
828 if ((ret =
829 af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst_en,
830 4, 1, 0x01)))
831 return ret;
832 if ((ret = af9005_write_ofdm_register(state->d, APO_REG_RESET, 0)))
833 return ret;
834 /* clear ofdm reset */
835 deb_info("clear ofdm reset\n");
836 for (i = 0; i < 150; i++) {
837 if ((ret =
838 af9005_read_ofdm_register(state->d,
839 xd_I2C_reg_ofdm_rst, &temp)))
840 return ret;
841 if (temp & (regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos))
842 break;
843 msleep(10);
844 }
845 if (i == 150)
846 return -ETIMEDOUT;
847
848 /*FIXME in the dump
849 write B200 A9
850 write xd_g_reg_ofsm_clk 7
851 read eepr c6 (2)
852 read eepr c7 (2)
853 misc ctrl 3 -> 1
854 read eepr ca (6)
855 write xd_g_reg_ofsm_clk 0
856 write B200 a1
857 */
858 ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa9);
859 if (ret)
860 return ret;
861 ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x07);
862 if (ret)
863 return ret;
864 temp = 0x01;
865 ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0);
866 if (ret)
867 return ret;
868 ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x00);
869 if (ret)
870 return ret;
871 ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa1);
872 if (ret)
873 return ret;
874
875 temp = regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos;
876 if ((ret =
877 af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,
878 reg_ofdm_rst_pos, reg_ofdm_rst_len, 1)))
879 return ret;
880 ret = af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst,
881 reg_ofdm_rst_pos, reg_ofdm_rst_len, 0);
882
883 if (ret)
884 return ret;
885 /* don't know what register aefc is, but this is what the windows driver does */
886 ret = af9005_write_ofdm_register(state->d, 0xaefc, 0);
887 if (ret)
888 return ret;
889
890 /* set stand alone chip */
891 deb_info("set stand alone chip\n");
892 if ((ret =
893 af9005_write_register_bits(state->d, xd_p_reg_dca_stand_alone,
894 reg_dca_stand_alone_pos,
895 reg_dca_stand_alone_len, 1)))
896 return ret;
897
898 /* set dca upper & lower chip */
899 deb_info("set dca upper & lower chip\n");
900 if ((ret =
901 af9005_write_register_bits(state->d, xd_p_reg_dca_upper_chip,
902 reg_dca_upper_chip_pos,
903 reg_dca_upper_chip_len, 0)))
904 return ret;
905 if ((ret =
906 af9005_write_register_bits(state->d, xd_p_reg_dca_lower_chip,
907 reg_dca_lower_chip_pos,
908 reg_dca_lower_chip_len, 0)))
909 return ret;
910
911 /* set 2wire master clock to 0x14 (for 60KHz) */
912 deb_info("set 2wire master clock to 0x14 (for 60KHz)\n");
913 if ((ret =
914 af9005_write_ofdm_register(state->d, xd_I2C_i2c_m_period, 0x14)))
915 return ret;
916
917 /* clear dca enable chip */
918 deb_info("clear dca enable chip\n");
919 if ((ret =
920 af9005_write_register_bits(state->d, xd_p_reg_dca_en,
921 reg_dca_en_pos, reg_dca_en_len, 0)))
922 return ret;
923 /* FIXME these are register bits, but I don't know which ones */
924 ret = af9005_write_ofdm_register(state->d, 0xa16c, 1);
925 if (ret)
926 return ret;
927 ret = af9005_write_ofdm_register(state->d, 0xa3c1, 0);
928 if (ret)
929 return ret;
930
931 /* init other parameters: program cfoe and select bandwidth */
932 deb_info("program cfoe\n");
933 ret = af9005_fe_program_cfoe(state->d, 6000000);
934 if (ret)
935 return ret;
936 /* set read-update bit for modulation */
937 deb_info("set read-update bit for modulation\n");
938 if ((ret =
939 af9005_write_register_bits(state->d, xd_p_reg_feq_read_update,
940 reg_feq_read_update_pos,
941 reg_feq_read_update_len, 1)))
942 return ret;
943
944 /* sample code has a set MPEG TS code here
945 but sniffing reveals that it doesn't do it */
946
947 /* set read-update bit to 1 for DCA modulation */
948 deb_info("set read-update bit 1 for DCA modulation\n");
949 if ((ret =
950 af9005_write_register_bits(state->d, xd_p_reg_dca_read_update,
951 reg_dca_read_update_pos,
952 reg_dca_read_update_len, 1)))
953 return ret;
954
955 /* enable fec monitor */
956 deb_info("enable fec monitor\n");
957 if ((ret =
958 af9005_write_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en,
959 fec_vtb_rsd_mon_en_pos,
960 fec_vtb_rsd_mon_en_len, 1)))
961 return ret;
962
963 /* FIXME should be register bits, I don't know which ones */
964 ret = af9005_write_ofdm_register(state->d, 0xa601, 0);
965
966 /* set api_retrain_never_freeze */
967 deb_info("set api_retrain_never_freeze\n");
968 if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01)))
969 return ret;
970
971 /* load init script */
972 deb_info("load init script\n");
973 scriptlen = sizeof(script) / sizeof(RegDesc);
974 for (i = 0; i < scriptlen; i++) {
975 if ((ret =
976 af9005_write_register_bits(state->d, script[i].reg,
977 script[i].pos,
978 script[i].len, script[i].val)))
979 return ret;
980 /* save 3 bytes of original fcw */
981 if (script[i].reg == 0xae18)
982 temp2 = script[i].val;
983 if (script[i].reg == 0xae19)
984 temp1 = script[i].val;
985 if (script[i].reg == 0xae1a)
986 temp0 = script[i].val;
987
988 /* save original unplug threshold */
989 if (script[i].reg == xd_p_reg_unplug_th)
990 state->original_if_unplug_th = script[i].val;
991 if (script[i].reg == xd_p_reg_unplug_rf_gain_th)
992 state->original_rf_unplug_th = script[i].val;
993 if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th)
994 state->original_dtop_if_unplug_th = script[i].val;
995 if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th)
996 state->original_dtop_rf_unplug_th = script[i].val;
997
998 }
999 state->original_fcw =
1000 ((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0;
1001
1002
1003 /* save original TOPs */
1004 deb_info("save original TOPs\n");
1005
1006 /* RF TOP */
1007 ret =
1008 af9005_read_word_agc(state->d,
1009 xd_p_reg_aagc_rf_top_numerator_9_8,
1010 xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2,
1011 &state->original_rf_top);
1012 if (ret)
1013 return ret;
1014
1015 /* IF TOP */
1016 ret =
1017 af9005_read_word_agc(state->d,
1018 xd_p_reg_aagc_if_top_numerator_9_8,
1019 xd_p_reg_aagc_if_top_numerator_7_0, 0, 2,
1020 &state->original_if_top);
1021 if (ret)
1022 return ret;
1023
1024 /* ACI 0 IF TOP */
1025 ret =
1026 af9005_read_word_agc(state->d, 0xA60E, 0xA60A, 4, 2,
1027 &state->original_aci0_if_top);
1028 if (ret)
1029 return ret;
1030
1031 /* ACI 1 IF TOP */
1032 ret =
1033 af9005_read_word_agc(state->d, 0xA60E, 0xA60B, 6, 2,
1034 &state->original_aci1_if_top);
1035 if (ret)
1036 return ret;
1037
1038 /* attach tuner and init */
1039 if (fe->ops.tuner_ops.release == NULL) {
1040 /* read tuner and board id from eeprom */
1041 ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2);
1042 if (ret) {
1043 err("Impossible to read EEPROM\n");
1044 return ret;
1045 }
1046 deb_info("Tuner id %d, board id %d\n", buf[0], buf[1]);
1047 switch (buf[0]) {
1048 case 2: /* MT2060 */
1049 /* read if1 from eeprom */
1050 ret = af9005_read_eeprom(adap->dev, 0xc8, buf, 2);
1051 if (ret) {
1052 err("Impossible to read EEPROM\n");
1053 return ret;
1054 }
1055 if1 = (u16) (buf[0] << 8) + buf[1];
1056 if (dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap,
1057 &af9005_mt2060_config, if1) == NULL) {
1058 deb_info("MT2060 attach failed\n");
1059 return -ENODEV;
1060 }
1061 break;
1062 case 3: /* QT1010 */
1063 case 9: /* QT1010B */
1064 if (dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap,
1065 &af9005_qt1010_config) ==NULL) {
1066 deb_info("QT1010 attach failed\n");
1067 return -ENODEV;
1068 }
1069 break;
1070 default:
1071 err("Unsupported tuner type %d", buf[0]);
1072 return -ENODEV;
1073 }
1074 ret = fe->ops.tuner_ops.init(fe);
1075 if (ret)
1076 return ret;
1077 }
1078
1079 deb_info("profit!\n");
1080 return 0;
1081}
1082
1083static int af9005_fe_sleep(struct dvb_frontend *fe)
1084{
1085 return af9005_fe_power(fe, 0);
1086}
1087
1088static int af9005_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
1089{
1090 struct af9005_fe_state *state = fe->demodulator_priv;
1091
1092 if (acquire) {
1093 state->opened++;
1094 } else {
1095
1096 state->opened--;
1097 if (!state->opened)
1098 af9005_led_control(state->d, 0);
1099 }
1100 return 0;
1101}
1102
1103static int af9005_fe_set_frontend(struct dvb_frontend *fe)
1104{
1105 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1106 struct af9005_fe_state *state = fe->demodulator_priv;
1107 int ret;
1108 u8 temp, temp0, temp1, temp2;
1109
1110 deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency,
1111 fep->bandwidth_hz);
1112 if (fe->ops.tuner_ops.release == NULL) {
1113 err("Tuner not attached");
1114 return -ENODEV;
1115 }
1116
1117 deb_info("turn off led\n");
1118 /* not in the log */
1119 ret = af9005_led_control(state->d, 0);
1120 if (ret)
1121 return ret;
1122 /* not sure about the bits */
1123 ret = af9005_write_register_bits(state->d, XD_MP2IF_MISC, 2, 1, 0);
1124 if (ret)
1125 return ret;
1126
1127 /* set FCW to default value */
1128 deb_info("set FCW to default value\n");
1129 temp0 = (u8) (state->original_fcw & 0x000000ff);
1130 temp1 = (u8) ((state->original_fcw & 0x0000ff00) >> 8);
1131 temp2 = (u8) ((state->original_fcw & 0x00ff0000) >> 16);
1132 ret = af9005_write_ofdm_register(state->d, 0xae1a, temp0);
1133 if (ret)
1134 return ret;
1135 ret = af9005_write_ofdm_register(state->d, 0xae19, temp1);
1136 if (ret)
1137 return ret;
1138 ret = af9005_write_ofdm_register(state->d, 0xae18, temp2);
1139 if (ret)
1140 return ret;
1141
1142 /* restore original TOPs */
1143 deb_info("restore original TOPs\n");
1144 ret =
1145 af9005_write_word_agc(state->d,
1146 xd_p_reg_aagc_rf_top_numerator_9_8,
1147 xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2,
1148 state->original_rf_top);
1149 if (ret)
1150 return ret;
1151 ret =
1152 af9005_write_word_agc(state->d,
1153 xd_p_reg_aagc_if_top_numerator_9_8,
1154 xd_p_reg_aagc_if_top_numerator_7_0, 0, 2,
1155 state->original_if_top);
1156 if (ret)
1157 return ret;
1158 ret =
1159 af9005_write_word_agc(state->d, 0xA60E, 0xA60A, 4, 2,
1160 state->original_aci0_if_top);
1161 if (ret)
1162 return ret;
1163 ret =
1164 af9005_write_word_agc(state->d, 0xA60E, 0xA60B, 6, 2,
1165 state->original_aci1_if_top);
1166 if (ret)
1167 return ret;
1168
1169 /* select bandwidth */
1170 deb_info("select bandwidth");
1171 ret = af9005_fe_select_bw(state->d, fep->bandwidth_hz);
1172 if (ret)
1173 return ret;
1174 ret = af9005_fe_program_cfoe(state->d, fep->bandwidth_hz);
1175 if (ret)
1176 return ret;
1177
1178 /* clear easy mode flag */
1179 deb_info("clear easy mode flag\n");
1180 ret = af9005_write_ofdm_register(state->d, 0xaefd, 0);
1181 if (ret)
1182 return ret;
1183
1184 /* set unplug threshold to original value */
1185 deb_info("set unplug threshold to original value\n");
1186 ret =
1187 af9005_write_ofdm_register(state->d, xd_p_reg_unplug_th,
1188 state->original_if_unplug_th);
1189 if (ret)
1190 return ret;
1191 /* set tuner */
1192 deb_info("set tuner\n");
1193 ret = fe->ops.tuner_ops.set_params(fe);
1194 if (ret)
1195 return ret;
1196
1197 /* trigger ofsm */
1198 deb_info("trigger ofsm\n");
1199 temp = 0;
1200 ret = af9005_write_tuner_registers(state->d, 0xffff, &temp, 1);
1201 if (ret)
1202 return ret;
1203
1204 /* clear retrain and freeze flag */
1205 deb_info("clear retrain and freeze flag\n");
1206 ret =
1207 af9005_write_register_bits(state->d,
1208 xd_p_reg_api_retrain_request,
1209 reg_api_retrain_request_pos, 2, 0);
1210 if (ret)
1211 return ret;
1212
1213 /* reset pre viterbi and post viterbi registers and statistics */
1214 af9005_reset_pre_viterbi(fe);
1215 af9005_reset_post_viterbi(fe);
1216 state->pre_vit_error_count = 0;
1217 state->pre_vit_bit_count = 0;
1218 state->ber = 0;
1219 state->post_vit_error_count = 0;
1220 /* state->unc = 0; commented out since it should be ever increasing */
1221 state->abort_count = 0;
1222
1223 state->next_status_check = jiffies;
1224 state->strong = -1;
1225
1226 return 0;
1227}
1228
1229static int af9005_fe_get_frontend(struct dvb_frontend *fe)
1230{
1231 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1232 struct af9005_fe_state *state = fe->demodulator_priv;
1233 int ret;
1234 u8 temp;
1235
1236 /* mode */
1237 ret =
1238 af9005_read_register_bits(state->d, xd_g_reg_tpsd_const,
1239 reg_tpsd_const_pos, reg_tpsd_const_len,
1240 &temp);
1241 if (ret)
1242 return ret;
1243 deb_info("===== fe_get_frontend_legacy = =============\n");
1244 deb_info("CONSTELLATION ");
1245 switch (temp) {
1246 case 0:
1247 fep->modulation = QPSK;
1248 deb_info("QPSK\n");
1249 break;
1250 case 1:
1251 fep->modulation = QAM_16;
1252 deb_info("QAM_16\n");
1253 break;
1254 case 2:
1255 fep->modulation = QAM_64;
1256 deb_info("QAM_64\n");
1257 break;
1258 }
1259
1260 /* tps hierarchy and alpha value */
1261 ret =
1262 af9005_read_register_bits(state->d, xd_g_reg_tpsd_hier,
1263 reg_tpsd_hier_pos, reg_tpsd_hier_len,
1264 &temp);
1265 if (ret)
1266 return ret;
1267 deb_info("HIERARCHY ");
1268 switch (temp) {
1269 case 0:
1270 fep->hierarchy = HIERARCHY_NONE;
1271 deb_info("NONE\n");
1272 break;
1273 case 1:
1274 fep->hierarchy = HIERARCHY_1;
1275 deb_info("1\n");
1276 break;
1277 case 2:
1278 fep->hierarchy = HIERARCHY_2;
1279 deb_info("2\n");
1280 break;
1281 case 3:
1282 fep->hierarchy = HIERARCHY_4;
1283 deb_info("4\n");
1284 break;
1285 }
1286
1287 /* high/low priority */
1288 ret =
1289 af9005_read_register_bits(state->d, xd_g_reg_dec_pri,
1290 reg_dec_pri_pos, reg_dec_pri_len, &temp);
1291 if (ret)
1292 return ret;
1293 /* if temp is set = high priority */
1294 deb_info("PRIORITY %s\n", temp ? "high" : "low");
1295
1296 /* high coderate */
1297 ret =
1298 af9005_read_register_bits(state->d, xd_g_reg_tpsd_hpcr,
1299 reg_tpsd_hpcr_pos, reg_tpsd_hpcr_len,
1300 &temp);
1301 if (ret)
1302 return ret;
1303 deb_info("CODERATE HP ");
1304 switch (temp) {
1305 case 0:
1306 fep->code_rate_HP = FEC_1_2;
1307 deb_info("FEC_1_2\n");
1308 break;
1309 case 1:
1310 fep->code_rate_HP = FEC_2_3;
1311 deb_info("FEC_2_3\n");
1312 break;
1313 case 2:
1314 fep->code_rate_HP = FEC_3_4;
1315 deb_info("FEC_3_4\n");
1316 break;
1317 case 3:
1318 fep->code_rate_HP = FEC_5_6;
1319 deb_info("FEC_5_6\n");
1320 break;
1321 case 4:
1322 fep->code_rate_HP = FEC_7_8;
1323 deb_info("FEC_7_8\n");
1324 break;
1325 }
1326
1327 /* low coderate */
1328 ret =
1329 af9005_read_register_bits(state->d, xd_g_reg_tpsd_lpcr,
1330 reg_tpsd_lpcr_pos, reg_tpsd_lpcr_len,
1331 &temp);
1332 if (ret)
1333 return ret;
1334 deb_info("CODERATE LP ");
1335 switch (temp) {
1336 case 0:
1337 fep->code_rate_LP = FEC_1_2;
1338 deb_info("FEC_1_2\n");
1339 break;
1340 case 1:
1341 fep->code_rate_LP = FEC_2_3;
1342 deb_info("FEC_2_3\n");
1343 break;
1344 case 2:
1345 fep->code_rate_LP = FEC_3_4;
1346 deb_info("FEC_3_4\n");
1347 break;
1348 case 3:
1349 fep->code_rate_LP = FEC_5_6;
1350 deb_info("FEC_5_6\n");
1351 break;
1352 case 4:
1353 fep->code_rate_LP = FEC_7_8;
1354 deb_info("FEC_7_8\n");
1355 break;
1356 }
1357
1358 /* guard interval */
1359 ret =
1360 af9005_read_register_bits(state->d, xd_g_reg_tpsd_gi,
1361 reg_tpsd_gi_pos, reg_tpsd_gi_len, &temp);
1362 if (ret)
1363 return ret;
1364 deb_info("GUARD INTERVAL ");
1365 switch (temp) {
1366 case 0:
1367 fep->guard_interval = GUARD_INTERVAL_1_32;
1368 deb_info("1_32\n");
1369 break;
1370 case 1:
1371 fep->guard_interval = GUARD_INTERVAL_1_16;
1372 deb_info("1_16\n");
1373 break;
1374 case 2:
1375 fep->guard_interval = GUARD_INTERVAL_1_8;
1376 deb_info("1_8\n");
1377 break;
1378 case 3:
1379 fep->guard_interval = GUARD_INTERVAL_1_4;
1380 deb_info("1_4\n");
1381 break;
1382 }
1383
1384 /* fft */
1385 ret =
1386 af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod,
1387 reg_tpsd_txmod_pos, reg_tpsd_txmod_len,
1388 &temp);
1389 if (ret)
1390 return ret;
1391 deb_info("TRANSMISSION MODE ");
1392 switch (temp) {
1393 case 0:
1394 fep->transmission_mode = TRANSMISSION_MODE_2K;
1395 deb_info("2K\n");
1396 break;
1397 case 1:
1398 fep->transmission_mode = TRANSMISSION_MODE_8K;
1399 deb_info("8K\n");
1400 break;
1401 }
1402
1403 /* bandwidth */
1404 ret =
1405 af9005_read_register_bits(state->d, xd_g_reg_bw, reg_bw_pos,
1406 reg_bw_len, &temp);
1407 deb_info("BANDWIDTH ");
1408 switch (temp) {
1409 case 0:
1410 fep->bandwidth_hz = 6000000;
1411 deb_info("6\n");
1412 break;
1413 case 1:
1414 fep->bandwidth_hz = 7000000;
1415 deb_info("7\n");
1416 break;
1417 case 2:
1418 fep->bandwidth_hz = 8000000;
1419 deb_info("8\n");
1420 break;
1421 }
1422 return 0;
1423}
1424
1425static void af9005_fe_release(struct dvb_frontend *fe)
1426{
1427 struct af9005_fe_state *state =
1428 (struct af9005_fe_state *)fe->demodulator_priv;
1429 kfree(state);
1430}
1431
1432static struct dvb_frontend_ops af9005_fe_ops;
1433
1434struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d)
1435{
1436 struct af9005_fe_state *state = NULL;
1437
1438 /* allocate memory for the internal state */
1439 state = kzalloc(sizeof(struct af9005_fe_state), GFP_KERNEL);
1440 if (state == NULL)
1441 goto error;
1442
1443 deb_info("attaching frontend af9005\n");
1444
1445 state->d = d;
1446 state->opened = 0;
1447
1448 memcpy(&state->frontend.ops, &af9005_fe_ops,
1449 sizeof(struct dvb_frontend_ops));
1450 state->frontend.demodulator_priv = state;
1451
1452 return &state->frontend;
1453 error:
1454 return NULL;
1455}
1456
1457static struct dvb_frontend_ops af9005_fe_ops = {
1458 .delsys = { SYS_DVBT },
1459 .info = {
1460 .name = "AF9005 USB DVB-T",
1461 .frequency_min = 44250000,
1462 .frequency_max = 867250000,
1463 .frequency_stepsize = 250000,
1464 .caps = FE_CAN_INVERSION_AUTO |
1465 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1466 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1467 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
1468 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
1469 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |
1470 FE_CAN_HIERARCHY_AUTO,
1471 },
1472
1473 .release = af9005_fe_release,
1474
1475 .init = af9005_fe_init,
1476 .sleep = af9005_fe_sleep,
1477 .ts_bus_ctrl = af9005_ts_bus_ctrl,
1478
1479 .set_frontend = af9005_fe_set_frontend,
1480 .get_frontend = af9005_fe_get_frontend,
1481
1482 .read_status = af9005_fe_read_status,
1483 .read_ber = af9005_fe_read_ber,
1484 .read_signal_strength = af9005_fe_read_signal_strength,
1485 .read_snr = af9005_fe_read_snr,
1486 .read_ucblocks = af9005_fe_read_unc_blocks,
1487};
diff --git a/drivers/media/usb/dvb-usb/af9005-remote.c b/drivers/media/usb/dvb-usb/af9005-remote.c
new file mode 100644
index 000000000000..7e3961d0db6b
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/af9005-remote.c
@@ -0,0 +1,157 @@
1/* DVB USB compliant Linux driver for the Afatech 9005
2 * USB1.1 DVB-T receiver.
3 *
4 * Standard remote decode function
5 *
6 * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
7 *
8 * Thanks to Afatech who kindly provided information.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 * see Documentation/dvb/README.dvb-usb for more information
25 */
26#include "af9005.h"
27/* debug */
28static int dvb_usb_af9005_remote_debug;
29module_param_named(debug, dvb_usb_af9005_remote_debug, int, 0644);
30MODULE_PARM_DESC(debug,
31 "enable (1) or disable (0) debug messages."
32 DVB_USB_DEBUG_STATUS);
33
34#define deb_decode(args...) dprintk(dvb_usb_af9005_remote_debug,0x01,args)
35
36struct rc_map_table rc_map_af9005_table[] = {
37
38 {0x01b7, KEY_POWER},
39 {0x01a7, KEY_VOLUMEUP},
40 {0x0187, KEY_CHANNELUP},
41 {0x017f, KEY_MUTE},
42 {0x01bf, KEY_VOLUMEDOWN},
43 {0x013f, KEY_CHANNELDOWN},
44 {0x01df, KEY_1},
45 {0x015f, KEY_2},
46 {0x019f, KEY_3},
47 {0x011f, KEY_4},
48 {0x01ef, KEY_5},
49 {0x016f, KEY_6},
50 {0x01af, KEY_7},
51 {0x0127, KEY_8},
52 {0x0107, KEY_9},
53 {0x01cf, KEY_ZOOM},
54 {0x014f, KEY_0},
55 {0x018f, KEY_GOTO}, /* marked jump on the remote */
56
57 {0x00bd, KEY_POWER},
58 {0x007d, KEY_VOLUMEUP},
59 {0x00fd, KEY_CHANNELUP},
60 {0x009d, KEY_MUTE},
61 {0x005d, KEY_VOLUMEDOWN},
62 {0x00dd, KEY_CHANNELDOWN},
63 {0x00ad, KEY_1},
64 {0x006d, KEY_2},
65 {0x00ed, KEY_3},
66 {0x008d, KEY_4},
67 {0x004d, KEY_5},
68 {0x00cd, KEY_6},
69 {0x00b5, KEY_7},
70 {0x0075, KEY_8},
71 {0x00f5, KEY_9},
72 {0x0095, KEY_ZOOM},
73 {0x0055, KEY_0},
74 {0x00d5, KEY_GOTO}, /* marked jump on the remote */
75};
76
77int rc_map_af9005_table_size = ARRAY_SIZE(rc_map_af9005_table);
78
79static int repeatable_keys[] = {
80 KEY_VOLUMEUP,
81 KEY_VOLUMEDOWN,
82 KEY_CHANNELUP,
83 KEY_CHANNELDOWN
84};
85
86int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
87 int *state)
88{
89 u16 mark, space;
90 u32 result;
91 u8 cust, dat, invdat;
92 int i;
93
94 if (len >= 6) {
95 mark = (u16) (data[0] << 8) + data[1];
96 space = (u16) (data[2] << 8) + data[3];
97 if (space * 3 < mark) {
98 for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) {
99 if (d->last_event == repeatable_keys[i]) {
100 *state = REMOTE_KEY_REPEAT;
101 *event = d->last_event;
102 deb_decode("repeat key, event %x\n",
103 *event);
104 return 0;
105 }
106 }
107 deb_decode("repeated key ignored (non repeatable)\n");
108 return 0;
109 } else if (len >= 33 * 4) { /*32 bits + start code */
110 result = 0;
111 for (i = 4; i < 4 + 32 * 4; i += 4) {
112 result <<= 1;
113 mark = (u16) (data[i] << 8) + data[i + 1];
114 mark >>= 1;
115 space = (u16) (data[i + 2] << 8) + data[i + 3];
116 space >>= 1;
117 if (mark * 2 > space)
118 result += 1;
119 }
120 deb_decode("key pressed, raw value %x\n", result);
121 if ((result & 0xff000000) != 0xfe000000) {
122 deb_decode
123 ("doesn't start with 0xfe, ignored\n");
124 return 0;
125 }
126 cust = (result >> 16) & 0xff;
127 dat = (result >> 8) & 0xff;
128 invdat = (~result) & 0xff;
129 if (dat != invdat) {
130 deb_decode("code != inverted code\n");
131 return 0;
132 }
133 for (i = 0; i < rc_map_af9005_table_size; i++) {
134 if (rc5_custom(&rc_map_af9005_table[i]) == cust
135 && rc5_data(&rc_map_af9005_table[i]) == dat) {
136 *event = rc_map_af9005_table[i].keycode;
137 *state = REMOTE_KEY_PRESSED;
138 deb_decode
139 ("key pressed, event %x\n", *event);
140 return 0;
141 }
142 }
143 deb_decode("not found in table\n");
144 }
145 }
146 return 0;
147}
148
149EXPORT_SYMBOL(rc_map_af9005_table);
150EXPORT_SYMBOL(rc_map_af9005_table_size);
151EXPORT_SYMBOL(af9005_rc_decode);
152
153MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");
154MODULE_DESCRIPTION
155 ("Standard remote control decoder for Afatech 9005 DVB-T USB1.1 stick");
156MODULE_VERSION("1.0");
157MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/af9005-script.h b/drivers/media/usb/dvb-usb/af9005-script.h
new file mode 100644
index 000000000000..4d69045426dd
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/af9005-script.h
@@ -0,0 +1,203 @@
1/*
2File automatically generated by createinit.py using data
3extracted from AF05BDA.sys (windows driver):
4
5dd if=AF05BDA.sys of=initsequence bs=1 skip=88316 count=1110
6python createinit.py > af9005-script.h
7
8*/
9
10typedef struct {
11 u16 reg;
12 u8 pos;
13 u8 len;
14 u8 val;
15} RegDesc;
16
17static RegDesc script[] = {
18 {0xa180, 0x0, 0x8, 0xa},
19 {0xa181, 0x0, 0x8, 0xd7},
20 {0xa182, 0x0, 0x8, 0xa3},
21 {0xa0a0, 0x0, 0x8, 0x0},
22 {0xa0a1, 0x0, 0x5, 0x0},
23 {0xa0a1, 0x5, 0x1, 0x1},
24 {0xa0c0, 0x0, 0x4, 0x1},
25 {0xa20e, 0x4, 0x4, 0xa},
26 {0xa20f, 0x0, 0x8, 0x40},
27 {0xa210, 0x0, 0x8, 0x8},
28 {0xa32a, 0x0, 0x4, 0xa},
29 {0xa32c, 0x0, 0x8, 0x20},
30 {0xa32b, 0x0, 0x8, 0x15},
31 {0xa1a0, 0x1, 0x1, 0x1},
32 {0xa000, 0x0, 0x1, 0x1},
33 {0xa000, 0x1, 0x1, 0x0},
34 {0xa001, 0x1, 0x1, 0x1},
35 {0xa001, 0x0, 0x1, 0x0},
36 {0xa001, 0x5, 0x1, 0x0},
37 {0xa00e, 0x0, 0x5, 0x10},
38 {0xa00f, 0x0, 0x3, 0x4},
39 {0xa00f, 0x3, 0x3, 0x5},
40 {0xa010, 0x0, 0x3, 0x4},
41 {0xa010, 0x3, 0x3, 0x5},
42 {0xa016, 0x4, 0x4, 0x3},
43 {0xa01f, 0x0, 0x6, 0xa},
44 {0xa020, 0x0, 0x6, 0xa},
45 {0xa2bc, 0x0, 0x1, 0x1},
46 {0xa2bc, 0x5, 0x1, 0x1},
47 {0xa015, 0x0, 0x8, 0x50},
48 {0xa016, 0x0, 0x1, 0x0},
49 {0xa02a, 0x0, 0x8, 0x50},
50 {0xa029, 0x0, 0x8, 0x4b},
51 {0xa614, 0x0, 0x8, 0x46},
52 {0xa002, 0x0, 0x5, 0x19},
53 {0xa003, 0x0, 0x5, 0x1a},
54 {0xa004, 0x0, 0x5, 0x19},
55 {0xa005, 0x0, 0x5, 0x1a},
56 {0xa008, 0x0, 0x8, 0x69},
57 {0xa009, 0x0, 0x2, 0x2},
58 {0xae1b, 0x0, 0x8, 0x69},
59 {0xae1c, 0x0, 0x8, 0x2},
60 {0xae1d, 0x0, 0x8, 0x2a},
61 {0xa022, 0x0, 0x8, 0xaa},
62 {0xa006, 0x0, 0x8, 0xc8},
63 {0xa007, 0x0, 0x2, 0x0},
64 {0xa00c, 0x0, 0x8, 0xba},
65 {0xa00d, 0x0, 0x2, 0x2},
66 {0xa608, 0x0, 0x8, 0xba},
67 {0xa60e, 0x0, 0x2, 0x2},
68 {0xa609, 0x0, 0x8, 0x80},
69 {0xa60e, 0x2, 0x2, 0x3},
70 {0xa00a, 0x0, 0x8, 0xb6},
71 {0xa00b, 0x0, 0x2, 0x0},
72 {0xa011, 0x0, 0x8, 0xb9},
73 {0xa012, 0x0, 0x2, 0x0},
74 {0xa013, 0x0, 0x8, 0xbd},
75 {0xa014, 0x0, 0x2, 0x2},
76 {0xa366, 0x0, 0x1, 0x1},
77 {0xa2bc, 0x3, 0x1, 0x0},
78 {0xa2bd, 0x0, 0x8, 0xa},
79 {0xa2be, 0x0, 0x8, 0x14},
80 {0xa2bf, 0x0, 0x8, 0x8},
81 {0xa60a, 0x0, 0x8, 0xbd},
82 {0xa60e, 0x4, 0x2, 0x2},
83 {0xa60b, 0x0, 0x8, 0x86},
84 {0xa60e, 0x6, 0x2, 0x3},
85 {0xa001, 0x2, 0x2, 0x1},
86 {0xa1c7, 0x0, 0x8, 0xf5},
87 {0xa03d, 0x0, 0x8, 0xb1},
88 {0xa616, 0x0, 0x8, 0xff},
89 {0xa617, 0x0, 0x8, 0xad},
90 {0xa618, 0x0, 0x8, 0xad},
91 {0xa61e, 0x3, 0x1, 0x1},
92 {0xae1a, 0x0, 0x8, 0x0},
93 {0xae19, 0x0, 0x8, 0xc8},
94 {0xae18, 0x0, 0x8, 0x61},
95 {0xa140, 0x0, 0x8, 0x0},
96 {0xa141, 0x0, 0x8, 0xc8},
97 {0xa142, 0x0, 0x7, 0x61},
98 {0xa023, 0x0, 0x8, 0xff},
99 {0xa021, 0x0, 0x8, 0xad},
100 {0xa026, 0x0, 0x1, 0x0},
101 {0xa024, 0x0, 0x8, 0xff},
102 {0xa025, 0x0, 0x8, 0xff},
103 {0xa1c8, 0x0, 0x8, 0xf},
104 {0xa2bc, 0x1, 0x1, 0x0},
105 {0xa60c, 0x0, 0x4, 0x5},
106 {0xa60c, 0x4, 0x4, 0x6},
107 {0xa60d, 0x0, 0x8, 0xa},
108 {0xa371, 0x0, 0x1, 0x1},
109 {0xa366, 0x1, 0x3, 0x7},
110 {0xa338, 0x0, 0x8, 0x10},
111 {0xa339, 0x0, 0x6, 0x7},
112 {0xa33a, 0x0, 0x6, 0x1f},
113 {0xa33b, 0x0, 0x8, 0xf6},
114 {0xa33c, 0x3, 0x5, 0x4},
115 {0xa33d, 0x4, 0x4, 0x0},
116 {0xa33d, 0x1, 0x1, 0x1},
117 {0xa33d, 0x2, 0x1, 0x1},
118 {0xa33d, 0x3, 0x1, 0x1},
119 {0xa16d, 0x0, 0x4, 0xf},
120 {0xa161, 0x0, 0x5, 0x5},
121 {0xa162, 0x0, 0x4, 0x5},
122 {0xa165, 0x0, 0x8, 0xff},
123 {0xa166, 0x0, 0x8, 0x9c},
124 {0xa2c3, 0x0, 0x4, 0x5},
125 {0xa61a, 0x0, 0x6, 0xf},
126 {0xb200, 0x0, 0x8, 0xa1},
127 {0xb201, 0x0, 0x8, 0x7},
128 {0xa093, 0x0, 0x1, 0x0},
129 {0xa093, 0x1, 0x5, 0xf},
130 {0xa094, 0x0, 0x8, 0xff},
131 {0xa095, 0x0, 0x8, 0xf},
132 {0xa080, 0x2, 0x5, 0x3},
133 {0xa081, 0x0, 0x4, 0x0},
134 {0xa081, 0x4, 0x4, 0x9},
135 {0xa082, 0x0, 0x5, 0x1f},
136 {0xa08d, 0x0, 0x8, 0x1},
137 {0xa083, 0x0, 0x8, 0x32},
138 {0xa084, 0x0, 0x1, 0x0},
139 {0xa08e, 0x0, 0x8, 0x3},
140 {0xa085, 0x0, 0x8, 0x32},
141 {0xa086, 0x0, 0x3, 0x0},
142 {0xa087, 0x0, 0x8, 0x6e},
143 {0xa088, 0x0, 0x5, 0x15},
144 {0xa089, 0x0, 0x8, 0x0},
145 {0xa08a, 0x0, 0x5, 0x19},
146 {0xa08b, 0x0, 0x8, 0x92},
147 {0xa08c, 0x0, 0x5, 0x1c},
148 {0xa120, 0x0, 0x8, 0x0},
149 {0xa121, 0x0, 0x5, 0x10},
150 {0xa122, 0x0, 0x8, 0x0},
151 {0xa123, 0x0, 0x7, 0x40},
152 {0xa123, 0x7, 0x1, 0x0},
153 {0xa124, 0x0, 0x8, 0x13},
154 {0xa125, 0x0, 0x7, 0x10},
155 {0xa1c0, 0x0, 0x8, 0x0},
156 {0xa1c1, 0x0, 0x5, 0x4},
157 {0xa1c2, 0x0, 0x8, 0x0},
158 {0xa1c3, 0x0, 0x5, 0x10},
159 {0xa1c3, 0x5, 0x3, 0x0},
160 {0xa1c4, 0x0, 0x6, 0x0},
161 {0xa1c5, 0x0, 0x7, 0x10},
162 {0xa100, 0x0, 0x8, 0x0},
163 {0xa101, 0x0, 0x5, 0x10},
164 {0xa102, 0x0, 0x8, 0x0},
165 {0xa103, 0x0, 0x7, 0x40},
166 {0xa103, 0x7, 0x1, 0x0},
167 {0xa104, 0x0, 0x8, 0x18},
168 {0xa105, 0x0, 0x7, 0xa},
169 {0xa106, 0x0, 0x8, 0x20},
170 {0xa107, 0x0, 0x8, 0x40},
171 {0xa108, 0x0, 0x4, 0x0},
172 {0xa38c, 0x0, 0x8, 0xfc},
173 {0xa38d, 0x0, 0x8, 0x0},
174 {0xa38e, 0x0, 0x8, 0x7e},
175 {0xa38f, 0x0, 0x8, 0x0},
176 {0xa390, 0x0, 0x8, 0x2f},
177 {0xa60f, 0x5, 0x1, 0x1},
178 {0xa170, 0x0, 0x8, 0xdc},
179 {0xa171, 0x0, 0x2, 0x0},
180 {0xa2ae, 0x0, 0x1, 0x1},
181 {0xa2ae, 0x1, 0x1, 0x1},
182 {0xa392, 0x0, 0x1, 0x1},
183 {0xa391, 0x2, 0x1, 0x0},
184 {0xabc1, 0x0, 0x8, 0xff},
185 {0xabc2, 0x0, 0x8, 0x0},
186 {0xabc8, 0x0, 0x8, 0x8},
187 {0xabca, 0x0, 0x8, 0x10},
188 {0xabcb, 0x0, 0x1, 0x0},
189 {0xabc3, 0x5, 0x3, 0x7},
190 {0xabc0, 0x6, 0x1, 0x0},
191 {0xabc0, 0x4, 0x2, 0x0},
192 {0xa344, 0x4, 0x4, 0x1},
193 {0xabc0, 0x7, 0x1, 0x1},
194 {0xabc0, 0x2, 0x1, 0x1},
195 {0xa345, 0x0, 0x8, 0x66},
196 {0xa346, 0x0, 0x8, 0x66},
197 {0xa347, 0x0, 0x4, 0x0},
198 {0xa343, 0x0, 0x4, 0xa},
199 {0xa347, 0x4, 0x4, 0x2},
200 {0xa348, 0x0, 0x4, 0xc},
201 {0xa348, 0x4, 0x4, 0x7},
202 {0xa349, 0x0, 0x6, 0x2},
203};
diff --git a/drivers/media/usb/dvb-usb/af9005.c b/drivers/media/usb/dvb-usb/af9005.c
new file mode 100644
index 000000000000..af176b6ce738
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/af9005.c
@@ -0,0 +1,1117 @@
1/* DVB USB compliant Linux driver for the Afatech 9005
2 * USB1.1 DVB-T receiver.
3 *
4 * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
5 *
6 * Thanks to Afatech who kindly provided information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * see Documentation/dvb/README.dvb-usb for more information
23 */
24#include "af9005.h"
25
26/* debug */
27int dvb_usb_af9005_debug;
28module_param_named(debug, dvb_usb_af9005_debug, int, 0644);
29MODULE_PARM_DESC(debug,
30 "set debugging level (1=info,xfer=2,rc=4,reg=8,i2c=16,fw=32 (or-able))."
31 DVB_USB_DEBUG_STATUS);
32/* enable obnoxious led */
33bool dvb_usb_af9005_led = 1;
34module_param_named(led, dvb_usb_af9005_led, bool, 0644);
35MODULE_PARM_DESC(led, "enable led (default: 1).");
36
37/* eeprom dump */
38static int dvb_usb_af9005_dump_eeprom;
39module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0);
40MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom.");
41
42DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
43
44/* remote control decoder */
45static int (*rc_decode) (struct dvb_usb_device *d, u8 *data, int len,
46 u32 *event, int *state);
47static void *rc_keys;
48static int *rc_keys_size;
49
50u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
51
52struct af9005_device_state {
53 u8 sequence;
54 int led_state;
55};
56
57static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg,
58 int readwrite, int type, u8 * values, int len)
59{
60 struct af9005_device_state *st = d->priv;
61 u8 obuf[16] = { 0 };
62 u8 ibuf[17] = { 0 };
63 u8 command;
64 int i;
65 int ret;
66
67 if (len < 1) {
68 err("generic read/write, less than 1 byte. Makes no sense.");
69 return -EINVAL;
70 }
71 if (len > 8) {
72 err("generic read/write, more than 8 bytes. Not supported.");
73 return -EINVAL;
74 }
75
76 obuf[0] = 14; /* rest of buffer length low */
77 obuf[1] = 0; /* rest of buffer length high */
78
79 obuf[2] = AF9005_REGISTER_RW; /* register operation */
80 obuf[3] = 12; /* rest of buffer length */
81
82 obuf[4] = st->sequence++; /* sequence number */
83
84 obuf[5] = (u8) (reg >> 8); /* register address */
85 obuf[6] = (u8) (reg & 0xff);
86
87 if (type == AF9005_OFDM_REG) {
88 command = AF9005_CMD_OFDM_REG;
89 } else {
90 command = AF9005_CMD_TUNER;
91 }
92
93 if (len > 1)
94 command |=
95 AF9005_CMD_BURST | AF9005_CMD_AUTOINC | (len - 1) << 3;
96 command |= readwrite;
97 if (readwrite == AF9005_CMD_WRITE)
98 for (i = 0; i < len; i++)
99 obuf[8 + i] = values[i];
100 else if (type == AF9005_TUNER_REG)
101 /* read command for tuner, the first byte contains the i2c address */
102 obuf[8] = values[0];
103 obuf[7] = command;
104
105 ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 17, 0);
106 if (ret)
107 return ret;
108
109 /* sanity check */
110 if (ibuf[2] != AF9005_REGISTER_RW_ACK) {
111 err("generic read/write, wrong reply code.");
112 return -EIO;
113 }
114 if (ibuf[3] != 0x0d) {
115 err("generic read/write, wrong length in reply.");
116 return -EIO;
117 }
118 if (ibuf[4] != obuf[4]) {
119 err("generic read/write, wrong sequence in reply.");
120 return -EIO;
121 }
122 /*
123 Windows driver doesn't check these fields, in fact sometimes
124 the register in the reply is different that what has been sent
125
126 if (ibuf[5] != obuf[5] || ibuf[6] != obuf[6]) {
127 err("generic read/write, wrong register in reply.");
128 return -EIO;
129 }
130 if (ibuf[7] != command) {
131 err("generic read/write wrong command in reply.");
132 return -EIO;
133 }
134 */
135 if (ibuf[16] != 0x01) {
136 err("generic read/write wrong status code in reply.");
137 return -EIO;
138 }
139 if (readwrite == AF9005_CMD_READ)
140 for (i = 0; i < len; i++)
141 values[i] = ibuf[8 + i];
142
143 return 0;
144
145}
146
147int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 * value)
148{
149 int ret;
150 deb_reg("read register %x ", reg);
151 ret = af9005_generic_read_write(d, reg,
152 AF9005_CMD_READ, AF9005_OFDM_REG,
153 value, 1);
154 if (ret)
155 deb_reg("failed\n");
156 else
157 deb_reg("value %x\n", *value);
158 return ret;
159}
160
161int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg,
162 u8 * values, int len)
163{
164 int ret;
165 deb_reg("read %d registers %x ", len, reg);
166 ret = af9005_generic_read_write(d, reg,
167 AF9005_CMD_READ, AF9005_OFDM_REG,
168 values, len);
169 if (ret)
170 deb_reg("failed\n");
171 else
172 debug_dump(values, len, deb_reg);
173 return ret;
174}
175
176int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 value)
177{
178 int ret;
179 u8 temp = value;
180 deb_reg("write register %x value %x ", reg, value);
181 ret = af9005_generic_read_write(d, reg,
182 AF9005_CMD_WRITE, AF9005_OFDM_REG,
183 &temp, 1);
184 if (ret)
185 deb_reg("failed\n");
186 else
187 deb_reg("ok\n");
188 return ret;
189}
190
191int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg,
192 u8 * values, int len)
193{
194 int ret;
195 deb_reg("write %d registers %x values ", len, reg);
196 debug_dump(values, len, deb_reg);
197
198 ret = af9005_generic_read_write(d, reg,
199 AF9005_CMD_WRITE, AF9005_OFDM_REG,
200 values, len);
201 if (ret)
202 deb_reg("failed\n");
203 else
204 deb_reg("ok\n");
205 return ret;
206}
207
208int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos,
209 u8 len, u8 * value)
210{
211 u8 temp;
212 int ret;
213 deb_reg("read bits %x %x %x", reg, pos, len);
214 ret = af9005_read_ofdm_register(d, reg, &temp);
215 if (ret) {
216 deb_reg(" failed\n");
217 return ret;
218 }
219 *value = (temp >> pos) & regmask[len - 1];
220 deb_reg(" value %x\n", *value);
221 return 0;
222
223}
224
225int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos,
226 u8 len, u8 value)
227{
228 u8 temp, mask;
229 int ret;
230 deb_reg("write bits %x %x %x value %x\n", reg, pos, len, value);
231 if (pos == 0 && len == 8)
232 return af9005_write_ofdm_register(d, reg, value);
233 ret = af9005_read_ofdm_register(d, reg, &temp);
234 if (ret)
235 return ret;
236 mask = regmask[len - 1] << pos;
237 temp = (temp & ~mask) | ((value << pos) & mask);
238 return af9005_write_ofdm_register(d, reg, temp);
239
240}
241
242static int af9005_usb_read_tuner_registers(struct dvb_usb_device *d,
243 u16 reg, u8 * values, int len)
244{
245 return af9005_generic_read_write(d, reg,
246 AF9005_CMD_READ, AF9005_TUNER_REG,
247 values, len);
248}
249
250static int af9005_usb_write_tuner_registers(struct dvb_usb_device *d,
251 u16 reg, u8 * values, int len)
252{
253 return af9005_generic_read_write(d, reg,
254 AF9005_CMD_WRITE,
255 AF9005_TUNER_REG, values, len);
256}
257
258int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg,
259 u8 * values, int len)
260{
261 /* don't let the name of this function mislead you: it's just used
262 as an interface from the firmware to the i2c bus. The actual
263 i2c addresses are contained in the data */
264 int ret, i, done = 0, fail = 0;
265 u8 temp;
266 ret = af9005_usb_write_tuner_registers(d, reg, values, len);
267 if (ret)
268 return ret;
269 if (reg != 0xffff) {
270 /* check if write done (0xa40d bit 1) or fail (0xa40d bit 2) */
271 for (i = 0; i < 200; i++) {
272 ret =
273 af9005_read_ofdm_register(d,
274 xd_I2C_i2c_m_status_wdat_done,
275 &temp);
276 if (ret)
277 return ret;
278 done = temp & (regmask[i2c_m_status_wdat_done_len - 1]
279 << i2c_m_status_wdat_done_pos);
280 if (done)
281 break;
282 fail = temp & (regmask[i2c_m_status_wdat_fail_len - 1]
283 << i2c_m_status_wdat_fail_pos);
284 if (fail)
285 break;
286 msleep(50);
287 }
288 if (i == 200)
289 return -ETIMEDOUT;
290 if (fail) {
291 /* clear write fail bit */
292 af9005_write_register_bits(d,
293 xd_I2C_i2c_m_status_wdat_fail,
294 i2c_m_status_wdat_fail_pos,
295 i2c_m_status_wdat_fail_len,
296 1);
297 return -EIO;
298 }
299 /* clear write done bit */
300 ret =
301 af9005_write_register_bits(d,
302 xd_I2C_i2c_m_status_wdat_fail,
303 i2c_m_status_wdat_done_pos,
304 i2c_m_status_wdat_done_len, 1);
305 if (ret)
306 return ret;
307 }
308 return 0;
309}
310
311int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg, u8 addr,
312 u8 * values, int len)
313{
314 /* don't let the name of this function mislead you: it's just used
315 as an interface from the firmware to the i2c bus. The actual
316 i2c addresses are contained in the data */
317 int ret, i;
318 u8 temp, buf[2];
319
320 buf[0] = addr; /* tuner i2c address */
321 buf[1] = values[0]; /* tuner register */
322
323 values[0] = addr + 0x01; /* i2c read address */
324
325 if (reg == APO_REG_I2C_RW_SILICON_TUNER) {
326 /* write tuner i2c address to tuner, 0c00c0 undocumented, found by sniffing */
327 ret = af9005_write_tuner_registers(d, 0x00c0, buf, 2);
328 if (ret)
329 return ret;
330 }
331
332 /* send read command to ofsm */
333 ret = af9005_usb_read_tuner_registers(d, reg, values, 1);
334 if (ret)
335 return ret;
336
337 /* check if read done */
338 for (i = 0; i < 200; i++) {
339 ret = af9005_read_ofdm_register(d, 0xa408, &temp);
340 if (ret)
341 return ret;
342 if (temp & 0x01)
343 break;
344 msleep(50);
345 }
346 if (i == 200)
347 return -ETIMEDOUT;
348
349 /* clear read done bit (by writing 1) */
350 ret = af9005_write_ofdm_register(d, xd_I2C_i2c_m_data8, 1);
351 if (ret)
352 return ret;
353
354 /* get read data (available from 0xa400) */
355 for (i = 0; i < len; i++) {
356 ret = af9005_read_ofdm_register(d, 0xa400 + i, &temp);
357 if (ret)
358 return ret;
359 values[i] = temp;
360 }
361 return 0;
362}
363
364static int af9005_i2c_write(struct dvb_usb_device *d, u8 i2caddr, u8 reg,
365 u8 * data, int len)
366{
367 int ret, i;
368 u8 buf[3];
369 deb_i2c("i2c_write i2caddr %x, reg %x, len %d data ", i2caddr,
370 reg, len);
371 debug_dump(data, len, deb_i2c);
372
373 for (i = 0; i < len; i++) {
374 buf[0] = i2caddr;
375 buf[1] = reg + (u8) i;
376 buf[2] = data[i];
377 ret =
378 af9005_write_tuner_registers(d,
379 APO_REG_I2C_RW_SILICON_TUNER,
380 buf, 3);
381 if (ret) {
382 deb_i2c("i2c_write failed\n");
383 return ret;
384 }
385 }
386 deb_i2c("i2c_write ok\n");
387 return 0;
388}
389
390static int af9005_i2c_read(struct dvb_usb_device *d, u8 i2caddr, u8 reg,
391 u8 * data, int len)
392{
393 int ret, i;
394 u8 temp;
395 deb_i2c("i2c_read i2caddr %x, reg %x, len %d\n ", i2caddr, reg, len);
396 for (i = 0; i < len; i++) {
397 temp = reg + i;
398 ret =
399 af9005_read_tuner_registers(d,
400 APO_REG_I2C_RW_SILICON_TUNER,
401 i2caddr, &temp, 1);
402 if (ret) {
403 deb_i2c("i2c_read failed\n");
404 return ret;
405 }
406 data[i] = temp;
407 }
408 deb_i2c("i2c data read: ");
409 debug_dump(data, len, deb_i2c);
410 return 0;
411}
412
413static int af9005_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
414 int num)
415{
416 /* only implements what the mt2060 module does, don't know how
417 to make it really generic */
418 struct dvb_usb_device *d = i2c_get_adapdata(adap);
419 int ret;
420 u8 reg, addr;
421 u8 *value;
422
423 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
424 return -EAGAIN;
425
426 if (num > 2)
427 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
428
429 if (num == 2) {
430 /* reads a single register */
431 reg = *msg[0].buf;
432 addr = msg[0].addr;
433 value = msg[1].buf;
434 ret = af9005_i2c_read(d, addr, reg, value, 1);
435 if (ret == 0)
436 ret = 2;
437 } else {
438 /* write one or more registers */
439 reg = msg[0].buf[0];
440 addr = msg[0].addr;
441 value = &msg[0].buf[1];
442 ret = af9005_i2c_write(d, addr, reg, value, msg[0].len - 1);
443 if (ret == 0)
444 ret = 1;
445 }
446
447 mutex_unlock(&d->i2c_mutex);
448 return ret;
449}
450
451static u32 af9005_i2c_func(struct i2c_adapter *adapter)
452{
453 return I2C_FUNC_I2C;
454}
455
456static struct i2c_algorithm af9005_i2c_algo = {
457 .master_xfer = af9005_i2c_xfer,
458 .functionality = af9005_i2c_func,
459};
460
461int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf,
462 int wlen, u8 * rbuf, int rlen)
463{
464 struct af9005_device_state *st = d->priv;
465
466 int ret, i, packet_len;
467 u8 buf[64];
468 u8 ibuf[64];
469
470 if (wlen < 0) {
471 err("send command, wlen less than 0 bytes. Makes no sense.");
472 return -EINVAL;
473 }
474 if (wlen > 54) {
475 err("send command, wlen more than 54 bytes. Not supported.");
476 return -EINVAL;
477 }
478 if (rlen > 54) {
479 err("send command, rlen more than 54 bytes. Not supported.");
480 return -EINVAL;
481 }
482 packet_len = wlen + 5;
483 buf[0] = (u8) (packet_len & 0xff);
484 buf[1] = (u8) ((packet_len & 0xff00) >> 8);
485
486 buf[2] = 0x26; /* packet type */
487 buf[3] = wlen + 3;
488 buf[4] = st->sequence++;
489 buf[5] = command;
490 buf[6] = wlen;
491 for (i = 0; i < wlen; i++)
492 buf[7 + i] = wbuf[i];
493 ret = dvb_usb_generic_rw(d, buf, wlen + 7, ibuf, rlen + 7, 0);
494 if (ret)
495 return ret;
496 if (ibuf[2] != 0x27) {
497 err("send command, wrong reply code.");
498 return -EIO;
499 }
500 if (ibuf[4] != buf[4]) {
501 err("send command, wrong sequence in reply.");
502 return -EIO;
503 }
504 if (ibuf[5] != 0x01) {
505 err("send command, wrong status code in reply.");
506 return -EIO;
507 }
508 if (ibuf[6] != rlen) {
509 err("send command, invalid data length in reply.");
510 return -EIO;
511 }
512 for (i = 0; i < rlen; i++)
513 rbuf[i] = ibuf[i + 7];
514 return 0;
515}
516
517int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, u8 * values,
518 int len)
519{
520 struct af9005_device_state *st = d->priv;
521 u8 obuf[16], ibuf[14];
522 int ret, i;
523
524 memset(obuf, 0, sizeof(obuf));
525 memset(ibuf, 0, sizeof(ibuf));
526
527 obuf[0] = 14; /* length of rest of packet low */
528 obuf[1] = 0; /* length of rest of packer high */
529
530 obuf[2] = 0x2a; /* read/write eeprom */
531
532 obuf[3] = 12; /* size */
533
534 obuf[4] = st->sequence++;
535
536 obuf[5] = 0; /* read */
537
538 obuf[6] = len;
539 obuf[7] = address;
540 ret = dvb_usb_generic_rw(d, obuf, 16, ibuf, 14, 0);
541 if (ret)
542 return ret;
543 if (ibuf[2] != 0x2b) {
544 err("Read eeprom, invalid reply code");
545 return -EIO;
546 }
547 if (ibuf[3] != 10) {
548 err("Read eeprom, invalid reply length");
549 return -EIO;
550 }
551 if (ibuf[4] != obuf[4]) {
552 err("Read eeprom, wrong sequence in reply ");
553 return -EIO;
554 }
555 if (ibuf[5] != 1) {
556 err("Read eeprom, wrong status in reply ");
557 return -EIO;
558 }
559 for (i = 0; i < len; i++) {
560 values[i] = ibuf[6 + i];
561 }
562 return 0;
563}
564
565static int af9005_boot_packet(struct usb_device *udev, int type, u8 * reply)
566{
567 u8 buf[FW_BULKOUT_SIZE + 2];
568 u16 checksum;
569 int act_len, i, ret;
570 memset(buf, 0, sizeof(buf));
571 buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);
572 buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);
573 switch (type) {
574 case FW_CONFIG:
575 buf[2] = 0x11;
576 buf[3] = 0x04;
577 buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */
578 buf[5] = 0x03;
579 checksum = buf[4] + buf[5];
580 buf[6] = (u8) ((checksum >> 8) & 0xff);
581 buf[7] = (u8) (checksum & 0xff);
582 break;
583 case FW_CONFIRM:
584 buf[2] = 0x11;
585 buf[3] = 0x04;
586 buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */
587 buf[5] = 0x01;
588 checksum = buf[4] + buf[5];
589 buf[6] = (u8) ((checksum >> 8) & 0xff);
590 buf[7] = (u8) (checksum & 0xff);
591 break;
592 case FW_BOOT:
593 buf[2] = 0x10;
594 buf[3] = 0x08;
595 buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */
596 buf[5] = 0x97;
597 buf[6] = 0xaa;
598 buf[7] = 0x55;
599 buf[8] = 0xa5;
600 buf[9] = 0x5a;
601 checksum = 0;
602 for (i = 4; i <= 9; i++)
603 checksum += buf[i];
604 buf[10] = (u8) ((checksum >> 8) & 0xff);
605 buf[11] = (u8) (checksum & 0xff);
606 break;
607 default:
608 err("boot packet invalid boot packet type");
609 return -EINVAL;
610 }
611 deb_fw(">>> ");
612 debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw);
613
614 ret = usb_bulk_msg(udev,
615 usb_sndbulkpipe(udev, 0x02),
616 buf, FW_BULKOUT_SIZE + 2, &act_len, 2000);
617 if (ret)
618 err("boot packet bulk message failed: %d (%d/%d)", ret,
619 FW_BULKOUT_SIZE + 2, act_len);
620 else
621 ret = act_len != FW_BULKOUT_SIZE + 2 ? -1 : 0;
622 if (ret)
623 return ret;
624 memset(buf, 0, 9);
625 ret = usb_bulk_msg(udev,
626 usb_rcvbulkpipe(udev, 0x01), buf, 9, &act_len, 2000);
627 if (ret) {
628 err("boot packet recv bulk message failed: %d", ret);
629 return ret;
630 }
631 deb_fw("<<< ");
632 debug_dump(buf, act_len, deb_fw);
633 checksum = 0;
634 switch (type) {
635 case FW_CONFIG:
636 if (buf[2] != 0x11) {
637 err("boot bad config header.");
638 return -EIO;
639 }
640 if (buf[3] != 0x05) {
641 err("boot bad config size.");
642 return -EIO;
643 }
644 if (buf[4] != 0x00) {
645 err("boot bad config sequence.");
646 return -EIO;
647 }
648 if (buf[5] != 0x04) {
649 err("boot bad config subtype.");
650 return -EIO;
651 }
652 for (i = 4; i <= 6; i++)
653 checksum += buf[i];
654 if (buf[7] * 256 + buf[8] != checksum) {
655 err("boot bad config checksum.");
656 return -EIO;
657 }
658 *reply = buf[6];
659 break;
660 case FW_CONFIRM:
661 if (buf[2] != 0x11) {
662 err("boot bad confirm header.");
663 return -EIO;
664 }
665 if (buf[3] != 0x05) {
666 err("boot bad confirm size.");
667 return -EIO;
668 }
669 if (buf[4] != 0x00) {
670 err("boot bad confirm sequence.");
671 return -EIO;
672 }
673 if (buf[5] != 0x02) {
674 err("boot bad confirm subtype.");
675 return -EIO;
676 }
677 for (i = 4; i <= 6; i++)
678 checksum += buf[i];
679 if (buf[7] * 256 + buf[8] != checksum) {
680 err("boot bad confirm checksum.");
681 return -EIO;
682 }
683 *reply = buf[6];
684 break;
685 case FW_BOOT:
686 if (buf[2] != 0x10) {
687 err("boot bad boot header.");
688 return -EIO;
689 }
690 if (buf[3] != 0x05) {
691 err("boot bad boot size.");
692 return -EIO;
693 }
694 if (buf[4] != 0x00) {
695 err("boot bad boot sequence.");
696 return -EIO;
697 }
698 if (buf[5] != 0x01) {
699 err("boot bad boot pattern 01.");
700 return -EIO;
701 }
702 if (buf[6] != 0x10) {
703 err("boot bad boot pattern 10.");
704 return -EIO;
705 }
706 for (i = 4; i <= 6; i++)
707 checksum += buf[i];
708 if (buf[7] * 256 + buf[8] != checksum) {
709 err("boot bad boot checksum.");
710 return -EIO;
711 }
712 break;
713
714 }
715
716 return 0;
717}
718
719static int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw)
720{
721 int i, packets, ret, act_len;
722
723 u8 buf[FW_BULKOUT_SIZE + 2];
724 u8 reply;
725
726 ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
727 if (ret)
728 return ret;
729 if (reply != 0x01) {
730 err("before downloading firmware, FW_CONFIG expected 0x01, received 0x%x", reply);
731 return -EIO;
732 }
733 packets = fw->size / FW_BULKOUT_SIZE;
734 buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff);
735 buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff);
736 for (i = 0; i < packets; i++) {
737 memcpy(&buf[2], fw->data + i * FW_BULKOUT_SIZE,
738 FW_BULKOUT_SIZE);
739 deb_fw(">>> ");
740 debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw);
741 ret = usb_bulk_msg(udev,
742 usb_sndbulkpipe(udev, 0x02),
743 buf, FW_BULKOUT_SIZE + 2, &act_len, 1000);
744 if (ret) {
745 err("firmware download failed at packet %d with code %d", i, ret);
746 return ret;
747 }
748 }
749 ret = af9005_boot_packet(udev, FW_CONFIRM, &reply);
750 if (ret)
751 return ret;
752 if (reply != (u8) (packets & 0xff)) {
753 err("after downloading firmware, FW_CONFIRM expected 0x%x, received 0x%x", packets & 0xff, reply);
754 return -EIO;
755 }
756 ret = af9005_boot_packet(udev, FW_BOOT, &reply);
757 if (ret)
758 return ret;
759 ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
760 if (ret)
761 return ret;
762 if (reply != 0x02) {
763 err("after downloading firmware, FW_CONFIG expected 0x02, received 0x%x", reply);
764 return -EIO;
765 }
766
767 return 0;
768
769}
770
771int af9005_led_control(struct dvb_usb_device *d, int onoff)
772{
773 struct af9005_device_state *st = d->priv;
774 int temp, ret;
775
776 if (onoff && dvb_usb_af9005_led)
777 temp = 1;
778 else
779 temp = 0;
780 if (st->led_state != temp) {
781 ret =
782 af9005_write_register_bits(d, xd_p_reg_top_locken1,
783 reg_top_locken1_pos,
784 reg_top_locken1_len, temp);
785 if (ret)
786 return ret;
787 ret =
788 af9005_write_register_bits(d, xd_p_reg_top_lock1,
789 reg_top_lock1_pos,
790 reg_top_lock1_len, temp);
791 if (ret)
792 return ret;
793 st->led_state = temp;
794 }
795 return 0;
796}
797
798static int af9005_frontend_attach(struct dvb_usb_adapter *adap)
799{
800 u8 buf[8];
801 int i;
802
803 /* without these calls the first commands after downloading
804 the firmware fail. I put these calls here to simulate
805 what it is done in dvb-usb-init.c.
806 */
807 struct usb_device *udev = adap->dev->udev;
808 usb_clear_halt(udev, usb_sndbulkpipe(udev, 2));
809 usb_clear_halt(udev, usb_rcvbulkpipe(udev, 1));
810 if (dvb_usb_af9005_dump_eeprom) {
811 printk("EEPROM DUMP\n");
812 for (i = 0; i < 255; i += 8) {
813 af9005_read_eeprom(adap->dev, i, buf, 8);
814 printk("ADDR %x ", i);
815 debug_dump(buf, 8, printk);
816 }
817 }
818 adap->fe_adap[0].fe = af9005_fe_attach(adap->dev);
819 return 0;
820}
821
822static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state)
823{
824 struct af9005_device_state *st = d->priv;
825 int ret, len;
826
827 u8 obuf[5];
828 u8 ibuf[256];
829
830 *state = REMOTE_NO_KEY_PRESSED;
831 if (rc_decode == NULL) {
832 /* it shouldn't never come here */
833 return 0;
834 }
835 /* deb_info("rc_query\n"); */
836 obuf[0] = 3; /* rest of packet length low */
837 obuf[1] = 0; /* rest of packet lentgh high */
838 obuf[2] = 0x40; /* read remote */
839 obuf[3] = 1; /* rest of packet length */
840 obuf[4] = st->sequence++; /* sequence number */
841 ret = dvb_usb_generic_rw(d, obuf, 5, ibuf, 256, 0);
842 if (ret) {
843 err("rc query failed");
844 return ret;
845 }
846 if (ibuf[2] != 0x41) {
847 err("rc query bad header.");
848 return -EIO;
849 }
850 if (ibuf[4] != obuf[4]) {
851 err("rc query bad sequence.");
852 return -EIO;
853 }
854 len = ibuf[5];
855 if (len > 246) {
856 err("rc query invalid length");
857 return -EIO;
858 }
859 if (len > 0) {
860 deb_rc("rc data (%d) ", len);
861 debug_dump((ibuf + 6), len, deb_rc);
862 ret = rc_decode(d, &ibuf[6], len, event, state);
863 if (ret) {
864 err("rc_decode failed");
865 return ret;
866 } else {
867 deb_rc("rc_decode state %x event %x\n", *state, *event);
868 if (*state == REMOTE_KEY_REPEAT)
869 *event = d->last_event;
870 }
871 }
872 return 0;
873}
874
875static int af9005_power_ctrl(struct dvb_usb_device *d, int onoff)
876{
877
878 return 0;
879}
880
881static int af9005_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
882{
883 int ret;
884 deb_info("pid filter control onoff %d\n", onoff);
885 if (onoff) {
886 ret =
887 af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1);
888 if (ret)
889 return ret;
890 ret =
891 af9005_write_register_bits(adap->dev,
892 XD_MP2IF_DMX_CTRL, 1, 1, 1);
893 if (ret)
894 return ret;
895 ret =
896 af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1);
897 } else
898 ret =
899 af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 0);
900 if (ret)
901 return ret;
902 deb_info("pid filter control ok\n");
903 return 0;
904}
905
906static int af9005_pid_filter(struct dvb_usb_adapter *adap, int index,
907 u16 pid, int onoff)
908{
909 u8 cmd = index & 0x1f;
910 int ret;
911 deb_info("set pid filter, index %d, pid %x, onoff %d\n", index,
912 pid, onoff);
913 if (onoff) {
914 /* cannot use it as pid_filter_ctrl since it has to be done
915 before setting the first pid */
916 if (adap->feedcount == 1) {
917 deb_info("first pid set, enable pid table\n");
918 ret = af9005_pid_filter_control(adap, onoff);
919 if (ret)
920 return ret;
921 }
922 ret =
923 af9005_write_ofdm_register(adap->dev,
924 XD_MP2IF_PID_DATA_L,
925 (u8) (pid & 0xff));
926 if (ret)
927 return ret;
928 ret =
929 af9005_write_ofdm_register(adap->dev,
930 XD_MP2IF_PID_DATA_H,
931 (u8) (pid >> 8));
932 if (ret)
933 return ret;
934 cmd |= 0x20 | 0x40;
935 } else {
936 if (adap->feedcount == 0) {
937 deb_info("last pid unset, disable pid table\n");
938 ret = af9005_pid_filter_control(adap, onoff);
939 if (ret)
940 return ret;
941 }
942 }
943 ret = af9005_write_ofdm_register(adap->dev, XD_MP2IF_PID_IDX, cmd);
944 if (ret)
945 return ret;
946 deb_info("set pid ok\n");
947 return 0;
948}
949
950static int af9005_identify_state(struct usb_device *udev,
951 struct dvb_usb_device_properties *props,
952 struct dvb_usb_device_description **desc,
953 int *cold)
954{
955 int ret;
956 u8 reply;
957 ret = af9005_boot_packet(udev, FW_CONFIG, &reply);
958 if (ret)
959 return ret;
960 deb_info("result of FW_CONFIG in identify state %d\n", reply);
961 if (reply == 0x01)
962 *cold = 1;
963 else if (reply == 0x02)
964 *cold = 0;
965 else
966 return -EIO;
967 deb_info("Identify state cold = %d\n", *cold);
968 return 0;
969}
970
971static struct dvb_usb_device_properties af9005_properties;
972
973static int af9005_usb_probe(struct usb_interface *intf,
974 const struct usb_device_id *id)
975{
976 return dvb_usb_device_init(intf, &af9005_properties,
977 THIS_MODULE, NULL, adapter_nr);
978}
979
980enum af9005_usb_table_entry {
981 AFATECH_AF9005,
982 TERRATEC_AF9005,
983 ANSONIC_AF9005,
984};
985
986static struct usb_device_id af9005_usb_table[] = {
987 [AFATECH_AF9005] = {USB_DEVICE(USB_VID_AFATECH,
988 USB_PID_AFATECH_AF9005)},
989 [TERRATEC_AF9005] = {USB_DEVICE(USB_VID_TERRATEC,
990 USB_PID_TERRATEC_CINERGY_T_USB_XE)},
991 [ANSONIC_AF9005] = {USB_DEVICE(USB_VID_ANSONIC,
992 USB_PID_ANSONIC_DVBT_USB)},
993 { }
994};
995
996MODULE_DEVICE_TABLE(usb, af9005_usb_table);
997
998static struct dvb_usb_device_properties af9005_properties = {
999 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1000
1001 .usb_ctrl = DEVICE_SPECIFIC,
1002 .firmware = "af9005.fw",
1003 .download_firmware = af9005_download_firmware,
1004 .no_reconnect = 1,
1005
1006 .size_of_priv = sizeof(struct af9005_device_state),
1007
1008 .num_adapters = 1,
1009 .adapter = {
1010 {
1011 .num_frontends = 1,
1012 .fe = {{
1013 .caps =
1014 DVB_USB_ADAP_HAS_PID_FILTER |
1015 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1016 .pid_filter_count = 32,
1017 .pid_filter = af9005_pid_filter,
1018 /* .pid_filter_ctrl = af9005_pid_filter_control, */
1019 .frontend_attach = af9005_frontend_attach,
1020 /* .tuner_attach = af9005_tuner_attach, */
1021 /* parameter for the MPEG2-data transfer */
1022 .stream = {
1023 .type = USB_BULK,
1024 .count = 10,
1025 .endpoint = 0x04,
1026 .u = {
1027 .bulk = {
1028 .buffersize = 4096, /* actual size seen is 3948 */
1029 }
1030 }
1031 },
1032 }},
1033 }
1034 },
1035 .power_ctrl = af9005_power_ctrl,
1036 .identify_state = af9005_identify_state,
1037
1038 .i2c_algo = &af9005_i2c_algo,
1039
1040 .rc.legacy = {
1041 .rc_interval = 200,
1042 .rc_map_table = NULL,
1043 .rc_map_size = 0,
1044 .rc_query = af9005_rc_query,
1045 },
1046
1047 .generic_bulk_ctrl_endpoint = 2,
1048 .generic_bulk_ctrl_endpoint_response = 1,
1049
1050 .num_device_descs = 3,
1051 .devices = {
1052 {.name = "Afatech DVB-T USB1.1 stick",
1053 .cold_ids = {&af9005_usb_table[AFATECH_AF9005], NULL},
1054 .warm_ids = {NULL},
1055 },
1056 {.name = "TerraTec Cinergy T USB XE",
1057 .cold_ids = {&af9005_usb_table[TERRATEC_AF9005], NULL},
1058 .warm_ids = {NULL},
1059 },
1060 {.name = "Ansonic DVB-T USB1.1 stick",
1061 .cold_ids = {&af9005_usb_table[ANSONIC_AF9005], NULL},
1062 .warm_ids = {NULL},
1063 },
1064 {NULL},
1065 }
1066};
1067
1068/* usb specific object needed to register this driver with the usb subsystem */
1069static struct usb_driver af9005_usb_driver = {
1070 .name = "dvb_usb_af9005",
1071 .probe = af9005_usb_probe,
1072 .disconnect = dvb_usb_device_exit,
1073 .id_table = af9005_usb_table,
1074};
1075
1076/* module stuff */
1077static int __init af9005_usb_module_init(void)
1078{
1079 int result;
1080 if ((result = usb_register(&af9005_usb_driver))) {
1081 err("usb_register failed. (%d)", result);
1082 return result;
1083 }
1084 rc_decode = symbol_request(af9005_rc_decode);
1085 rc_keys = symbol_request(rc_map_af9005_table);
1086 rc_keys_size = symbol_request(rc_map_af9005_table_size);
1087 if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) {
1088 err("af9005_rc_decode function not found, disabling remote");
1089 af9005_properties.rc.legacy.rc_query = NULL;
1090 } else {
1091 af9005_properties.rc.legacy.rc_map_table = rc_keys;
1092 af9005_properties.rc.legacy.rc_map_size = *rc_keys_size;
1093 }
1094
1095 return 0;
1096}
1097
1098static void __exit af9005_usb_module_exit(void)
1099{
1100 /* release rc decode symbols */
1101 if (rc_decode != NULL)
1102 symbol_put(af9005_rc_decode);
1103 if (rc_keys != NULL)
1104 symbol_put(rc_map_af9005_table);
1105 if (rc_keys_size != NULL)
1106 symbol_put(rc_map_af9005_table_size);
1107 /* deregister this driver from the USB subsystem */
1108 usb_deregister(&af9005_usb_driver);
1109}
1110
1111module_init(af9005_usb_module_init);
1112module_exit(af9005_usb_module_exit);
1113
1114MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");
1115MODULE_DESCRIPTION("Driver for Afatech 9005 DVB-T USB1.1 stick");
1116MODULE_VERSION("1.0");
1117MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/af9005.h b/drivers/media/usb/dvb-usb/af9005.h
new file mode 100644
index 000000000000..6a2bf3de8456
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/af9005.h
@@ -0,0 +1,3496 @@
1/* Common header-file of the Linux driver for the Afatech 9005
2 * USB1.1 DVB-T receiver.
3 *
4 * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
5 *
6 * Thanks to Afatech who kindly provided information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 * see Documentation/dvb/README.dvb-usb for more information
23 */
24#ifndef _DVB_USB_AF9005_H_
25#define _DVB_USB_AF9005_H_
26
27#define DVB_USB_LOG_PREFIX "af9005"
28#include "dvb-usb.h"
29
30extern int dvb_usb_af9005_debug;
31#define deb_info(args...) dprintk(dvb_usb_af9005_debug,0x01,args)
32#define deb_xfer(args...) dprintk(dvb_usb_af9005_debug,0x02,args)
33#define deb_rc(args...) dprintk(dvb_usb_af9005_debug,0x04,args)
34#define deb_reg(args...) dprintk(dvb_usb_af9005_debug,0x08,args)
35#define deb_i2c(args...) dprintk(dvb_usb_af9005_debug,0x10,args)
36#define deb_fw(args...) dprintk(dvb_usb_af9005_debug,0x20,args)
37
38extern bool dvb_usb_af9005_led;
39
40/* firmware */
41#define FW_BULKOUT_SIZE 250
42enum {
43 FW_CONFIG,
44 FW_CONFIRM,
45 FW_BOOT
46};
47
48/* af9005 commands */
49#define AF9005_OFDM_REG 0
50#define AF9005_TUNER_REG 1
51
52#define AF9005_REGISTER_RW 0x20
53#define AF9005_REGISTER_RW_ACK 0x21
54
55#define AF9005_CMD_OFDM_REG 0x00
56#define AF9005_CMD_TUNER 0x80
57#define AF9005_CMD_BURST 0x02
58#define AF9005_CMD_AUTOINC 0x04
59#define AF9005_CMD_READ 0x00
60#define AF9005_CMD_WRITE 0x01
61
62/* af9005 registers */
63#define APO_REG_RESET 0xAEFF
64
65#define APO_REG_I2C_RW_CAN_TUNER 0xF000
66#define APO_REG_I2C_RW_SILICON_TUNER 0xF001
67#define APO_REG_GPIO_RW_SILICON_TUNER 0xFFFE /* also for OFSM */
68#define APO_REG_TRIGGER_OFSM 0xFFFF /* also for OFSM */
69
70/***********************************************************************
71 * Apollo Registers from VLSI *
72 ***********************************************************************/
73#define xd_p_reg_aagc_inverted_agc 0xA000
74#define reg_aagc_inverted_agc_pos 0
75#define reg_aagc_inverted_agc_len 1
76#define reg_aagc_inverted_agc_lsb 0
77#define xd_p_reg_aagc_sign_only 0xA000
78#define reg_aagc_sign_only_pos 1
79#define reg_aagc_sign_only_len 1
80#define reg_aagc_sign_only_lsb 0
81#define xd_p_reg_aagc_slow_adc_en 0xA000
82#define reg_aagc_slow_adc_en_pos 2
83#define reg_aagc_slow_adc_en_len 1
84#define reg_aagc_slow_adc_en_lsb 0
85#define xd_p_reg_aagc_slow_adc_scale 0xA000
86#define reg_aagc_slow_adc_scale_pos 3
87#define reg_aagc_slow_adc_scale_len 5
88#define reg_aagc_slow_adc_scale_lsb 0
89#define xd_p_reg_aagc_check_slow_adc_lock 0xA001
90#define reg_aagc_check_slow_adc_lock_pos 0
91#define reg_aagc_check_slow_adc_lock_len 1
92#define reg_aagc_check_slow_adc_lock_lsb 0
93#define xd_p_reg_aagc_init_control 0xA001
94#define reg_aagc_init_control_pos 1
95#define reg_aagc_init_control_len 1
96#define reg_aagc_init_control_lsb 0
97#define xd_p_reg_aagc_total_gain_sel 0xA001
98#define reg_aagc_total_gain_sel_pos 2
99#define reg_aagc_total_gain_sel_len 2
100#define reg_aagc_total_gain_sel_lsb 0
101#define xd_p_reg_aagc_out_inv 0xA001
102#define reg_aagc_out_inv_pos 5
103#define reg_aagc_out_inv_len 1
104#define reg_aagc_out_inv_lsb 0
105#define xd_p_reg_aagc_int_en 0xA001
106#define reg_aagc_int_en_pos 6
107#define reg_aagc_int_en_len 1
108#define reg_aagc_int_en_lsb 0
109#define xd_p_reg_aagc_lock_change_flag 0xA001
110#define reg_aagc_lock_change_flag_pos 7
111#define reg_aagc_lock_change_flag_len 1
112#define reg_aagc_lock_change_flag_lsb 0
113#define xd_p_reg_aagc_rf_loop_bw_scale_acquire 0xA002
114#define reg_aagc_rf_loop_bw_scale_acquire_pos 0
115#define reg_aagc_rf_loop_bw_scale_acquire_len 5
116#define reg_aagc_rf_loop_bw_scale_acquire_lsb 0
117#define xd_p_reg_aagc_rf_loop_bw_scale_track 0xA003
118#define reg_aagc_rf_loop_bw_scale_track_pos 0
119#define reg_aagc_rf_loop_bw_scale_track_len 5
120#define reg_aagc_rf_loop_bw_scale_track_lsb 0
121#define xd_p_reg_aagc_if_loop_bw_scale_acquire 0xA004
122#define reg_aagc_if_loop_bw_scale_acquire_pos 0
123#define reg_aagc_if_loop_bw_scale_acquire_len 5
124#define reg_aagc_if_loop_bw_scale_acquire_lsb 0
125#define xd_p_reg_aagc_if_loop_bw_scale_track 0xA005
126#define reg_aagc_if_loop_bw_scale_track_pos 0
127#define reg_aagc_if_loop_bw_scale_track_len 5
128#define reg_aagc_if_loop_bw_scale_track_lsb 0
129#define xd_p_reg_aagc_max_rf_agc_7_0 0xA006
130#define reg_aagc_max_rf_agc_7_0_pos 0
131#define reg_aagc_max_rf_agc_7_0_len 8
132#define reg_aagc_max_rf_agc_7_0_lsb 0
133#define xd_p_reg_aagc_max_rf_agc_9_8 0xA007
134#define reg_aagc_max_rf_agc_9_8_pos 0
135#define reg_aagc_max_rf_agc_9_8_len 2
136#define reg_aagc_max_rf_agc_9_8_lsb 8
137#define xd_p_reg_aagc_min_rf_agc_7_0 0xA008
138#define reg_aagc_min_rf_agc_7_0_pos 0
139#define reg_aagc_min_rf_agc_7_0_len 8
140#define reg_aagc_min_rf_agc_7_0_lsb 0
141#define xd_p_reg_aagc_min_rf_agc_9_8 0xA009
142#define reg_aagc_min_rf_agc_9_8_pos 0
143#define reg_aagc_min_rf_agc_9_8_len 2
144#define reg_aagc_min_rf_agc_9_8_lsb 8
145#define xd_p_reg_aagc_max_if_agc_7_0 0xA00A
146#define reg_aagc_max_if_agc_7_0_pos 0
147#define reg_aagc_max_if_agc_7_0_len 8
148#define reg_aagc_max_if_agc_7_0_lsb 0
149#define xd_p_reg_aagc_max_if_agc_9_8 0xA00B
150#define reg_aagc_max_if_agc_9_8_pos 0
151#define reg_aagc_max_if_agc_9_8_len 2
152#define reg_aagc_max_if_agc_9_8_lsb 8
153#define xd_p_reg_aagc_min_if_agc_7_0 0xA00C
154#define reg_aagc_min_if_agc_7_0_pos 0
155#define reg_aagc_min_if_agc_7_0_len 8
156#define reg_aagc_min_if_agc_7_0_lsb 0
157#define xd_p_reg_aagc_min_if_agc_9_8 0xA00D
158#define reg_aagc_min_if_agc_9_8_pos 0
159#define reg_aagc_min_if_agc_9_8_len 2
160#define reg_aagc_min_if_agc_9_8_lsb 8
161#define xd_p_reg_aagc_lock_sample_scale 0xA00E
162#define reg_aagc_lock_sample_scale_pos 0
163#define reg_aagc_lock_sample_scale_len 5
164#define reg_aagc_lock_sample_scale_lsb 0
165#define xd_p_reg_aagc_rf_agc_lock_scale_acquire 0xA00F
166#define reg_aagc_rf_agc_lock_scale_acquire_pos 0
167#define reg_aagc_rf_agc_lock_scale_acquire_len 3
168#define reg_aagc_rf_agc_lock_scale_acquire_lsb 0
169#define xd_p_reg_aagc_rf_agc_lock_scale_track 0xA00F
170#define reg_aagc_rf_agc_lock_scale_track_pos 3
171#define reg_aagc_rf_agc_lock_scale_track_len 3
172#define reg_aagc_rf_agc_lock_scale_track_lsb 0
173#define xd_p_reg_aagc_if_agc_lock_scale_acquire 0xA010
174#define reg_aagc_if_agc_lock_scale_acquire_pos 0
175#define reg_aagc_if_agc_lock_scale_acquire_len 3
176#define reg_aagc_if_agc_lock_scale_acquire_lsb 0
177#define xd_p_reg_aagc_if_agc_lock_scale_track 0xA010
178#define reg_aagc_if_agc_lock_scale_track_pos 3
179#define reg_aagc_if_agc_lock_scale_track_len 3
180#define reg_aagc_if_agc_lock_scale_track_lsb 0
181#define xd_p_reg_aagc_rf_top_numerator_7_0 0xA011
182#define reg_aagc_rf_top_numerator_7_0_pos 0
183#define reg_aagc_rf_top_numerator_7_0_len 8
184#define reg_aagc_rf_top_numerator_7_0_lsb 0
185#define xd_p_reg_aagc_rf_top_numerator_9_8 0xA012
186#define reg_aagc_rf_top_numerator_9_8_pos 0
187#define reg_aagc_rf_top_numerator_9_8_len 2
188#define reg_aagc_rf_top_numerator_9_8_lsb 8
189#define xd_p_reg_aagc_if_top_numerator_7_0 0xA013
190#define reg_aagc_if_top_numerator_7_0_pos 0
191#define reg_aagc_if_top_numerator_7_0_len 8
192#define reg_aagc_if_top_numerator_7_0_lsb 0
193#define xd_p_reg_aagc_if_top_numerator_9_8 0xA014
194#define reg_aagc_if_top_numerator_9_8_pos 0
195#define reg_aagc_if_top_numerator_9_8_len 2
196#define reg_aagc_if_top_numerator_9_8_lsb 8
197#define xd_p_reg_aagc_adc_out_desired_7_0 0xA015
198#define reg_aagc_adc_out_desired_7_0_pos 0
199#define reg_aagc_adc_out_desired_7_0_len 8
200#define reg_aagc_adc_out_desired_7_0_lsb 0
201#define xd_p_reg_aagc_adc_out_desired_8 0xA016
202#define reg_aagc_adc_out_desired_8_pos 0
203#define reg_aagc_adc_out_desired_8_len 1
204#define reg_aagc_adc_out_desired_8_lsb 0
205#define xd_p_reg_aagc_fixed_gain 0xA016
206#define reg_aagc_fixed_gain_pos 3
207#define reg_aagc_fixed_gain_len 1
208#define reg_aagc_fixed_gain_lsb 0
209#define xd_p_reg_aagc_lock_count_th 0xA016
210#define reg_aagc_lock_count_th_pos 4
211#define reg_aagc_lock_count_th_len 4
212#define reg_aagc_lock_count_th_lsb 0
213#define xd_p_reg_aagc_fixed_rf_agc_control_7_0 0xA017
214#define reg_aagc_fixed_rf_agc_control_7_0_pos 0
215#define reg_aagc_fixed_rf_agc_control_7_0_len 8
216#define reg_aagc_fixed_rf_agc_control_7_0_lsb 0
217#define xd_p_reg_aagc_fixed_rf_agc_control_15_8 0xA018
218#define reg_aagc_fixed_rf_agc_control_15_8_pos 0
219#define reg_aagc_fixed_rf_agc_control_15_8_len 8
220#define reg_aagc_fixed_rf_agc_control_15_8_lsb 8
221#define xd_p_reg_aagc_fixed_rf_agc_control_23_16 0xA019
222#define reg_aagc_fixed_rf_agc_control_23_16_pos 0
223#define reg_aagc_fixed_rf_agc_control_23_16_len 8
224#define reg_aagc_fixed_rf_agc_control_23_16_lsb 16
225#define xd_p_reg_aagc_fixed_rf_agc_control_30_24 0xA01A
226#define reg_aagc_fixed_rf_agc_control_30_24_pos 0
227#define reg_aagc_fixed_rf_agc_control_30_24_len 7
228#define reg_aagc_fixed_rf_agc_control_30_24_lsb 24
229#define xd_p_reg_aagc_fixed_if_agc_control_7_0 0xA01B
230#define reg_aagc_fixed_if_agc_control_7_0_pos 0
231#define reg_aagc_fixed_if_agc_control_7_0_len 8
232#define reg_aagc_fixed_if_agc_control_7_0_lsb 0
233#define xd_p_reg_aagc_fixed_if_agc_control_15_8 0xA01C
234#define reg_aagc_fixed_if_agc_control_15_8_pos 0
235#define reg_aagc_fixed_if_agc_control_15_8_len 8
236#define reg_aagc_fixed_if_agc_control_15_8_lsb 8
237#define xd_p_reg_aagc_fixed_if_agc_control_23_16 0xA01D
238#define reg_aagc_fixed_if_agc_control_23_16_pos 0
239#define reg_aagc_fixed_if_agc_control_23_16_len 8
240#define reg_aagc_fixed_if_agc_control_23_16_lsb 16
241#define xd_p_reg_aagc_fixed_if_agc_control_30_24 0xA01E
242#define reg_aagc_fixed_if_agc_control_30_24_pos 0
243#define reg_aagc_fixed_if_agc_control_30_24_len 7
244#define reg_aagc_fixed_if_agc_control_30_24_lsb 24
245#define xd_p_reg_aagc_rf_agc_unlock_numerator 0xA01F
246#define reg_aagc_rf_agc_unlock_numerator_pos 0
247#define reg_aagc_rf_agc_unlock_numerator_len 6
248#define reg_aagc_rf_agc_unlock_numerator_lsb 0
249#define xd_p_reg_aagc_if_agc_unlock_numerator 0xA020
250#define reg_aagc_if_agc_unlock_numerator_pos 0
251#define reg_aagc_if_agc_unlock_numerator_len 6
252#define reg_aagc_if_agc_unlock_numerator_lsb 0
253#define xd_p_reg_unplug_th 0xA021
254#define reg_unplug_th_pos 0
255#define reg_unplug_th_len 8
256#define reg_aagc_rf_x0_lsb 0
257#define xd_p_reg_weak_signal_rfagc_thr 0xA022
258#define reg_weak_signal_rfagc_thr_pos 0
259#define reg_weak_signal_rfagc_thr_len 8
260#define reg_weak_signal_rfagc_thr_lsb 0
261#define xd_p_reg_unplug_rf_gain_th 0xA023
262#define reg_unplug_rf_gain_th_pos 0
263#define reg_unplug_rf_gain_th_len 8
264#define reg_unplug_rf_gain_th_lsb 0
265#define xd_p_reg_unplug_dtop_rf_gain_th 0xA024
266#define reg_unplug_dtop_rf_gain_th_pos 0
267#define reg_unplug_dtop_rf_gain_th_len 8
268#define reg_unplug_dtop_rf_gain_th_lsb 0
269#define xd_p_reg_unplug_dtop_if_gain_th 0xA025
270#define reg_unplug_dtop_if_gain_th_pos 0
271#define reg_unplug_dtop_if_gain_th_len 8
272#define reg_unplug_dtop_if_gain_th_lsb 0
273#define xd_p_reg_top_recover_at_unplug_en 0xA026
274#define reg_top_recover_at_unplug_en_pos 0
275#define reg_top_recover_at_unplug_en_len 1
276#define reg_top_recover_at_unplug_en_lsb 0
277#define xd_p_reg_aagc_rf_x6 0xA027
278#define reg_aagc_rf_x6_pos 0
279#define reg_aagc_rf_x6_len 8
280#define reg_aagc_rf_x6_lsb 0
281#define xd_p_reg_aagc_rf_x7 0xA028
282#define reg_aagc_rf_x7_pos 0
283#define reg_aagc_rf_x7_len 8
284#define reg_aagc_rf_x7_lsb 0
285#define xd_p_reg_aagc_rf_x8 0xA029
286#define reg_aagc_rf_x8_pos 0
287#define reg_aagc_rf_x8_len 8
288#define reg_aagc_rf_x8_lsb 0
289#define xd_p_reg_aagc_rf_x9 0xA02A
290#define reg_aagc_rf_x9_pos 0
291#define reg_aagc_rf_x9_len 8
292#define reg_aagc_rf_x9_lsb 0
293#define xd_p_reg_aagc_rf_x10 0xA02B
294#define reg_aagc_rf_x10_pos 0
295#define reg_aagc_rf_x10_len 8
296#define reg_aagc_rf_x10_lsb 0
297#define xd_p_reg_aagc_rf_x11 0xA02C
298#define reg_aagc_rf_x11_pos 0
299#define reg_aagc_rf_x11_len 8
300#define reg_aagc_rf_x11_lsb 0
301#define xd_p_reg_aagc_rf_x12 0xA02D
302#define reg_aagc_rf_x12_pos 0
303#define reg_aagc_rf_x12_len 8
304#define reg_aagc_rf_x12_lsb 0
305#define xd_p_reg_aagc_rf_x13 0xA02E
306#define reg_aagc_rf_x13_pos 0
307#define reg_aagc_rf_x13_len 8
308#define reg_aagc_rf_x13_lsb 0
309#define xd_p_reg_aagc_if_x0 0xA02F
310#define reg_aagc_if_x0_pos 0
311#define reg_aagc_if_x0_len 8
312#define reg_aagc_if_x0_lsb 0
313#define xd_p_reg_aagc_if_x1 0xA030
314#define reg_aagc_if_x1_pos 0
315#define reg_aagc_if_x1_len 8
316#define reg_aagc_if_x1_lsb 0
317#define xd_p_reg_aagc_if_x2 0xA031
318#define reg_aagc_if_x2_pos 0
319#define reg_aagc_if_x2_len 8
320#define reg_aagc_if_x2_lsb 0
321#define xd_p_reg_aagc_if_x3 0xA032
322#define reg_aagc_if_x3_pos 0
323#define reg_aagc_if_x3_len 8
324#define reg_aagc_if_x3_lsb 0
325#define xd_p_reg_aagc_if_x4 0xA033
326#define reg_aagc_if_x4_pos 0
327#define reg_aagc_if_x4_len 8
328#define reg_aagc_if_x4_lsb 0
329#define xd_p_reg_aagc_if_x5 0xA034
330#define reg_aagc_if_x5_pos 0
331#define reg_aagc_if_x5_len 8
332#define reg_aagc_if_x5_lsb 0
333#define xd_p_reg_aagc_if_x6 0xA035
334#define reg_aagc_if_x6_pos 0
335#define reg_aagc_if_x6_len 8
336#define reg_aagc_if_x6_lsb 0
337#define xd_p_reg_aagc_if_x7 0xA036
338#define reg_aagc_if_x7_pos 0
339#define reg_aagc_if_x7_len 8
340#define reg_aagc_if_x7_lsb 0
341#define xd_p_reg_aagc_if_x8 0xA037
342#define reg_aagc_if_x8_pos 0
343#define reg_aagc_if_x8_len 8
344#define reg_aagc_if_x8_lsb 0
345#define xd_p_reg_aagc_if_x9 0xA038
346#define reg_aagc_if_x9_pos 0
347#define reg_aagc_if_x9_len 8
348#define reg_aagc_if_x9_lsb 0
349#define xd_p_reg_aagc_if_x10 0xA039
350#define reg_aagc_if_x10_pos 0
351#define reg_aagc_if_x10_len 8
352#define reg_aagc_if_x10_lsb 0
353#define xd_p_reg_aagc_if_x11 0xA03A
354#define reg_aagc_if_x11_pos 0
355#define reg_aagc_if_x11_len 8
356#define reg_aagc_if_x11_lsb 0
357#define xd_p_reg_aagc_if_x12 0xA03B
358#define reg_aagc_if_x12_pos 0
359#define reg_aagc_if_x12_len 8
360#define reg_aagc_if_x12_lsb 0
361#define xd_p_reg_aagc_if_x13 0xA03C
362#define reg_aagc_if_x13_pos 0
363#define reg_aagc_if_x13_len 8
364#define reg_aagc_if_x13_lsb 0
365#define xd_p_reg_aagc_min_rf_ctl_8bit_for_dca 0xA03D
366#define reg_aagc_min_rf_ctl_8bit_for_dca_pos 0
367#define reg_aagc_min_rf_ctl_8bit_for_dca_len 8
368#define reg_aagc_min_rf_ctl_8bit_for_dca_lsb 0
369#define xd_p_reg_aagc_min_if_ctl_8bit_for_dca 0xA03E
370#define reg_aagc_min_if_ctl_8bit_for_dca_pos 0
371#define reg_aagc_min_if_ctl_8bit_for_dca_len 8
372#define reg_aagc_min_if_ctl_8bit_for_dca_lsb 0
373#define xd_r_reg_aagc_total_gain_7_0 0xA070
374#define reg_aagc_total_gain_7_0_pos 0
375#define reg_aagc_total_gain_7_0_len 8
376#define reg_aagc_total_gain_7_0_lsb 0
377#define xd_r_reg_aagc_total_gain_15_8 0xA071
378#define reg_aagc_total_gain_15_8_pos 0
379#define reg_aagc_total_gain_15_8_len 8
380#define reg_aagc_total_gain_15_8_lsb 8
381#define xd_p_reg_aagc_in_sat_cnt_7_0 0xA074
382#define reg_aagc_in_sat_cnt_7_0_pos 0
383#define reg_aagc_in_sat_cnt_7_0_len 8
384#define reg_aagc_in_sat_cnt_7_0_lsb 0
385#define xd_p_reg_aagc_in_sat_cnt_15_8 0xA075
386#define reg_aagc_in_sat_cnt_15_8_pos 0
387#define reg_aagc_in_sat_cnt_15_8_len 8
388#define reg_aagc_in_sat_cnt_15_8_lsb 8
389#define xd_p_reg_aagc_in_sat_cnt_23_16 0xA076
390#define reg_aagc_in_sat_cnt_23_16_pos 0
391#define reg_aagc_in_sat_cnt_23_16_len 8
392#define reg_aagc_in_sat_cnt_23_16_lsb 16
393#define xd_p_reg_aagc_in_sat_cnt_31_24 0xA077
394#define reg_aagc_in_sat_cnt_31_24_pos 0
395#define reg_aagc_in_sat_cnt_31_24_len 8
396#define reg_aagc_in_sat_cnt_31_24_lsb 24
397#define xd_r_reg_aagc_digital_rf_volt_7_0 0xA078
398#define reg_aagc_digital_rf_volt_7_0_pos 0
399#define reg_aagc_digital_rf_volt_7_0_len 8
400#define reg_aagc_digital_rf_volt_7_0_lsb 0
401#define xd_r_reg_aagc_digital_rf_volt_9_8 0xA079
402#define reg_aagc_digital_rf_volt_9_8_pos 0
403#define reg_aagc_digital_rf_volt_9_8_len 2
404#define reg_aagc_digital_rf_volt_9_8_lsb 8
405#define xd_r_reg_aagc_digital_if_volt_7_0 0xA07A
406#define reg_aagc_digital_if_volt_7_0_pos 0
407#define reg_aagc_digital_if_volt_7_0_len 8
408#define reg_aagc_digital_if_volt_7_0_lsb 0
409#define xd_r_reg_aagc_digital_if_volt_9_8 0xA07B
410#define reg_aagc_digital_if_volt_9_8_pos 0
411#define reg_aagc_digital_if_volt_9_8_len 2
412#define reg_aagc_digital_if_volt_9_8_lsb 8
413#define xd_r_reg_aagc_rf_gain 0xA07C
414#define reg_aagc_rf_gain_pos 0
415#define reg_aagc_rf_gain_len 8
416#define reg_aagc_rf_gain_lsb 0
417#define xd_r_reg_aagc_if_gain 0xA07D
418#define reg_aagc_if_gain_pos 0
419#define reg_aagc_if_gain_len 8
420#define reg_aagc_if_gain_lsb 0
421#define xd_p_tinr_imp_indicator 0xA080
422#define tinr_imp_indicator_pos 0
423#define tinr_imp_indicator_len 2
424#define tinr_imp_indicator_lsb 0
425#define xd_p_reg_tinr_fifo_size 0xA080
426#define reg_tinr_fifo_size_pos 2
427#define reg_tinr_fifo_size_len 5
428#define reg_tinr_fifo_size_lsb 0
429#define xd_p_reg_tinr_saturation_cnt_th 0xA081
430#define reg_tinr_saturation_cnt_th_pos 0
431#define reg_tinr_saturation_cnt_th_len 4
432#define reg_tinr_saturation_cnt_th_lsb 0
433#define xd_p_reg_tinr_saturation_th_3_0 0xA081
434#define reg_tinr_saturation_th_3_0_pos 4
435#define reg_tinr_saturation_th_3_0_len 4
436#define reg_tinr_saturation_th_3_0_lsb 0
437#define xd_p_reg_tinr_saturation_th_8_4 0xA082
438#define reg_tinr_saturation_th_8_4_pos 0
439#define reg_tinr_saturation_th_8_4_len 5
440#define reg_tinr_saturation_th_8_4_lsb 4
441#define xd_p_reg_tinr_imp_duration_th_2k_7_0 0xA083
442#define reg_tinr_imp_duration_th_2k_7_0_pos 0
443#define reg_tinr_imp_duration_th_2k_7_0_len 8
444#define reg_tinr_imp_duration_th_2k_7_0_lsb 0
445#define xd_p_reg_tinr_imp_duration_th_2k_8 0xA084
446#define reg_tinr_imp_duration_th_2k_8_pos 0
447#define reg_tinr_imp_duration_th_2k_8_len 1
448#define reg_tinr_imp_duration_th_2k_8_lsb 0
449#define xd_p_reg_tinr_imp_duration_th_8k_7_0 0xA085
450#define reg_tinr_imp_duration_th_8k_7_0_pos 0
451#define reg_tinr_imp_duration_th_8k_7_0_len 8
452#define reg_tinr_imp_duration_th_8k_7_0_lsb 0
453#define xd_p_reg_tinr_imp_duration_th_8k_10_8 0xA086
454#define reg_tinr_imp_duration_th_8k_10_8_pos 0
455#define reg_tinr_imp_duration_th_8k_10_8_len 3
456#define reg_tinr_imp_duration_th_8k_10_8_lsb 8
457#define xd_p_reg_tinr_freq_ratio_6m_7_0 0xA087
458#define reg_tinr_freq_ratio_6m_7_0_pos 0
459#define reg_tinr_freq_ratio_6m_7_0_len 8
460#define reg_tinr_freq_ratio_6m_7_0_lsb 0
461#define xd_p_reg_tinr_freq_ratio_6m_12_8 0xA088
462#define reg_tinr_freq_ratio_6m_12_8_pos 0
463#define reg_tinr_freq_ratio_6m_12_8_len 5
464#define reg_tinr_freq_ratio_6m_12_8_lsb 8
465#define xd_p_reg_tinr_freq_ratio_7m_7_0 0xA089
466#define reg_tinr_freq_ratio_7m_7_0_pos 0
467#define reg_tinr_freq_ratio_7m_7_0_len 8
468#define reg_tinr_freq_ratio_7m_7_0_lsb 0
469#define xd_p_reg_tinr_freq_ratio_7m_12_8 0xA08A
470#define reg_tinr_freq_ratio_7m_12_8_pos 0
471#define reg_tinr_freq_ratio_7m_12_8_len 5
472#define reg_tinr_freq_ratio_7m_12_8_lsb 8
473#define xd_p_reg_tinr_freq_ratio_8m_7_0 0xA08B
474#define reg_tinr_freq_ratio_8m_7_0_pos 0
475#define reg_tinr_freq_ratio_8m_7_0_len 8
476#define reg_tinr_freq_ratio_8m_7_0_lsb 0
477#define xd_p_reg_tinr_freq_ratio_8m_12_8 0xA08C
478#define reg_tinr_freq_ratio_8m_12_8_pos 0
479#define reg_tinr_freq_ratio_8m_12_8_len 5
480#define reg_tinr_freq_ratio_8m_12_8_lsb 8
481#define xd_p_reg_tinr_imp_duration_th_low_2k 0xA08D
482#define reg_tinr_imp_duration_th_low_2k_pos 0
483#define reg_tinr_imp_duration_th_low_2k_len 8
484#define reg_tinr_imp_duration_th_low_2k_lsb 0
485#define xd_p_reg_tinr_imp_duration_th_low_8k 0xA08E
486#define reg_tinr_imp_duration_th_low_8k_pos 0
487#define reg_tinr_imp_duration_th_low_8k_len 8
488#define reg_tinr_imp_duration_th_low_8k_lsb 0
489#define xd_r_reg_tinr_counter_7_0 0xA090
490#define reg_tinr_counter_7_0_pos 0
491#define reg_tinr_counter_7_0_len 8
492#define reg_tinr_counter_7_0_lsb 0
493#define xd_r_reg_tinr_counter_15_8 0xA091
494#define reg_tinr_counter_15_8_pos 0
495#define reg_tinr_counter_15_8_len 8
496#define reg_tinr_counter_15_8_lsb 8
497#define xd_p_reg_tinr_adative_tinr_en 0xA093
498#define reg_tinr_adative_tinr_en_pos 0
499#define reg_tinr_adative_tinr_en_len 1
500#define reg_tinr_adative_tinr_en_lsb 0
501#define xd_p_reg_tinr_peak_fifo_size 0xA093
502#define reg_tinr_peak_fifo_size_pos 1
503#define reg_tinr_peak_fifo_size_len 5
504#define reg_tinr_peak_fifo_size_lsb 0
505#define xd_p_reg_tinr_counter_rst 0xA093
506#define reg_tinr_counter_rst_pos 6
507#define reg_tinr_counter_rst_len 1
508#define reg_tinr_counter_rst_lsb 0
509#define xd_p_reg_tinr_search_period_7_0 0xA094
510#define reg_tinr_search_period_7_0_pos 0
511#define reg_tinr_search_period_7_0_len 8
512#define reg_tinr_search_period_7_0_lsb 0
513#define xd_p_reg_tinr_search_period_15_8 0xA095
514#define reg_tinr_search_period_15_8_pos 0
515#define reg_tinr_search_period_15_8_len 8
516#define reg_tinr_search_period_15_8_lsb 8
517#define xd_p_reg_ccifs_fcw_7_0 0xA0A0
518#define reg_ccifs_fcw_7_0_pos 0
519#define reg_ccifs_fcw_7_0_len 8
520#define reg_ccifs_fcw_7_0_lsb 0
521#define xd_p_reg_ccifs_fcw_12_8 0xA0A1
522#define reg_ccifs_fcw_12_8_pos 0
523#define reg_ccifs_fcw_12_8_len 5
524#define reg_ccifs_fcw_12_8_lsb 8
525#define xd_p_reg_ccifs_spec_inv 0xA0A1
526#define reg_ccifs_spec_inv_pos 5
527#define reg_ccifs_spec_inv_len 1
528#define reg_ccifs_spec_inv_lsb 0
529#define xd_p_reg_gp_trigger 0xA0A2
530#define reg_gp_trigger_pos 0
531#define reg_gp_trigger_len 1
532#define reg_gp_trigger_lsb 0
533#define xd_p_reg_trigger_sel 0xA0A2
534#define reg_trigger_sel_pos 1
535#define reg_trigger_sel_len 2
536#define reg_trigger_sel_lsb 0
537#define xd_p_reg_debug_ofdm 0xA0A2
538#define reg_debug_ofdm_pos 3
539#define reg_debug_ofdm_len 2
540#define reg_debug_ofdm_lsb 0
541#define xd_p_reg_trigger_module_sel 0xA0A3
542#define reg_trigger_module_sel_pos 0
543#define reg_trigger_module_sel_len 6
544#define reg_trigger_module_sel_lsb 0
545#define xd_p_reg_trigger_set_sel 0xA0A4
546#define reg_trigger_set_sel_pos 0
547#define reg_trigger_set_sel_len 6
548#define reg_trigger_set_sel_lsb 0
549#define xd_p_reg_fw_int_mask_n 0xA0A4
550#define reg_fw_int_mask_n_pos 6
551#define reg_fw_int_mask_n_len 1
552#define reg_fw_int_mask_n_lsb 0
553#define xd_p_reg_debug_group 0xA0A5
554#define reg_debug_group_pos 0
555#define reg_debug_group_len 4
556#define reg_debug_group_lsb 0
557#define xd_p_reg_odbg_clk_sel 0xA0A5
558#define reg_odbg_clk_sel_pos 4
559#define reg_odbg_clk_sel_len 2
560#define reg_odbg_clk_sel_lsb 0
561#define xd_p_reg_ccif_sc 0xA0C0
562#define reg_ccif_sc_pos 0
563#define reg_ccif_sc_len 4
564#define reg_ccif_sc_lsb 0
565#define xd_r_reg_ccif_saturate 0xA0C1
566#define reg_ccif_saturate_pos 0
567#define reg_ccif_saturate_len 2
568#define reg_ccif_saturate_lsb 0
569#define xd_r_reg_antif_saturate 0xA0C1
570#define reg_antif_saturate_pos 2
571#define reg_antif_saturate_len 4
572#define reg_antif_saturate_lsb 0
573#define xd_r_reg_acif_saturate 0xA0C2
574#define reg_acif_saturate_pos 0
575#define reg_acif_saturate_len 8
576#define reg_acif_saturate_lsb 0
577#define xd_p_reg_tmr_timer0_threshold_7_0 0xA0C8
578#define reg_tmr_timer0_threshold_7_0_pos 0
579#define reg_tmr_timer0_threshold_7_0_len 8
580#define reg_tmr_timer0_threshold_7_0_lsb 0
581#define xd_p_reg_tmr_timer0_threshold_15_8 0xA0C9
582#define reg_tmr_timer0_threshold_15_8_pos 0
583#define reg_tmr_timer0_threshold_15_8_len 8
584#define reg_tmr_timer0_threshold_15_8_lsb 8
585#define xd_p_reg_tmr_timer0_enable 0xA0CA
586#define reg_tmr_timer0_enable_pos 0
587#define reg_tmr_timer0_enable_len 1
588#define reg_tmr_timer0_enable_lsb 0
589#define xd_p_reg_tmr_timer0_clk_sel 0xA0CA
590#define reg_tmr_timer0_clk_sel_pos 1
591#define reg_tmr_timer0_clk_sel_len 1
592#define reg_tmr_timer0_clk_sel_lsb 0
593#define xd_p_reg_tmr_timer0_int 0xA0CA
594#define reg_tmr_timer0_int_pos 2
595#define reg_tmr_timer0_int_len 1
596#define reg_tmr_timer0_int_lsb 0
597#define xd_p_reg_tmr_timer0_rst 0xA0CA
598#define reg_tmr_timer0_rst_pos 3
599#define reg_tmr_timer0_rst_len 1
600#define reg_tmr_timer0_rst_lsb 0
601#define xd_r_reg_tmr_timer0_count_7_0 0xA0CB
602#define reg_tmr_timer0_count_7_0_pos 0
603#define reg_tmr_timer0_count_7_0_len 8
604#define reg_tmr_timer0_count_7_0_lsb 0
605#define xd_r_reg_tmr_timer0_count_15_8 0xA0CC
606#define reg_tmr_timer0_count_15_8_pos 0
607#define reg_tmr_timer0_count_15_8_len 8
608#define reg_tmr_timer0_count_15_8_lsb 8
609#define xd_p_reg_suspend 0xA0CD
610#define reg_suspend_pos 0
611#define reg_suspend_len 1
612#define reg_suspend_lsb 0
613#define xd_p_reg_suspend_rdy 0xA0CD
614#define reg_suspend_rdy_pos 1
615#define reg_suspend_rdy_len 1
616#define reg_suspend_rdy_lsb 0
617#define xd_p_reg_resume 0xA0CD
618#define reg_resume_pos 2
619#define reg_resume_len 1
620#define reg_resume_lsb 0
621#define xd_p_reg_resume_rdy 0xA0CD
622#define reg_resume_rdy_pos 3
623#define reg_resume_rdy_len 1
624#define reg_resume_rdy_lsb 0
625#define xd_p_reg_fmf 0xA0CE
626#define reg_fmf_pos 0
627#define reg_fmf_len 8
628#define reg_fmf_lsb 0
629#define xd_p_ccid_accumulate_num_2k_7_0 0xA100
630#define ccid_accumulate_num_2k_7_0_pos 0
631#define ccid_accumulate_num_2k_7_0_len 8
632#define ccid_accumulate_num_2k_7_0_lsb 0
633#define xd_p_ccid_accumulate_num_2k_12_8 0xA101
634#define ccid_accumulate_num_2k_12_8_pos 0
635#define ccid_accumulate_num_2k_12_8_len 5
636#define ccid_accumulate_num_2k_12_8_lsb 8
637#define xd_p_ccid_accumulate_num_8k_7_0 0xA102
638#define ccid_accumulate_num_8k_7_0_pos 0
639#define ccid_accumulate_num_8k_7_0_len 8
640#define ccid_accumulate_num_8k_7_0_lsb 0
641#define xd_p_ccid_accumulate_num_8k_14_8 0xA103
642#define ccid_accumulate_num_8k_14_8_pos 0
643#define ccid_accumulate_num_8k_14_8_len 7
644#define ccid_accumulate_num_8k_14_8_lsb 8
645#define xd_p_ccid_desired_level_0 0xA103
646#define ccid_desired_level_0_pos 7
647#define ccid_desired_level_0_len 1
648#define ccid_desired_level_0_lsb 0
649#define xd_p_ccid_desired_level_8_1 0xA104
650#define ccid_desired_level_8_1_pos 0
651#define ccid_desired_level_8_1_len 8
652#define ccid_desired_level_8_1_lsb 1
653#define xd_p_ccid_apply_delay 0xA105
654#define ccid_apply_delay_pos 0
655#define ccid_apply_delay_len 7
656#define ccid_apply_delay_lsb 0
657#define xd_p_ccid_CCID_Threshold1 0xA106
658#define ccid_CCID_Threshold1_pos 0
659#define ccid_CCID_Threshold1_len 8
660#define ccid_CCID_Threshold1_lsb 0
661#define xd_p_ccid_CCID_Threshold2 0xA107
662#define ccid_CCID_Threshold2_pos 0
663#define ccid_CCID_Threshold2_len 8
664#define ccid_CCID_Threshold2_lsb 0
665#define xd_p_reg_ccid_gain_scale 0xA108
666#define reg_ccid_gain_scale_pos 0
667#define reg_ccid_gain_scale_len 4
668#define reg_ccid_gain_scale_lsb 0
669#define xd_p_reg_ccid2_passband_gain_set 0xA108
670#define reg_ccid2_passband_gain_set_pos 4
671#define reg_ccid2_passband_gain_set_len 4
672#define reg_ccid2_passband_gain_set_lsb 0
673#define xd_r_ccid_multiplier_7_0 0xA109
674#define ccid_multiplier_7_0_pos 0
675#define ccid_multiplier_7_0_len 8
676#define ccid_multiplier_7_0_lsb 0
677#define xd_r_ccid_multiplier_15_8 0xA10A
678#define ccid_multiplier_15_8_pos 0
679#define ccid_multiplier_15_8_len 8
680#define ccid_multiplier_15_8_lsb 8
681#define xd_r_ccid_right_shift_bits 0xA10B
682#define ccid_right_shift_bits_pos 0
683#define ccid_right_shift_bits_len 4
684#define ccid_right_shift_bits_lsb 0
685#define xd_r_reg_ccid_sx_7_0 0xA10C
686#define reg_ccid_sx_7_0_pos 0
687#define reg_ccid_sx_7_0_len 8
688#define reg_ccid_sx_7_0_lsb 0
689#define xd_r_reg_ccid_sx_15_8 0xA10D
690#define reg_ccid_sx_15_8_pos 0
691#define reg_ccid_sx_15_8_len 8
692#define reg_ccid_sx_15_8_lsb 8
693#define xd_r_reg_ccid_sx_21_16 0xA10E
694#define reg_ccid_sx_21_16_pos 0
695#define reg_ccid_sx_21_16_len 6
696#define reg_ccid_sx_21_16_lsb 16
697#define xd_r_reg_ccid_sy_7_0 0xA110
698#define reg_ccid_sy_7_0_pos 0
699#define reg_ccid_sy_7_0_len 8
700#define reg_ccid_sy_7_0_lsb 0
701#define xd_r_reg_ccid_sy_15_8 0xA111
702#define reg_ccid_sy_15_8_pos 0
703#define reg_ccid_sy_15_8_len 8
704#define reg_ccid_sy_15_8_lsb 8
705#define xd_r_reg_ccid_sy_23_16 0xA112
706#define reg_ccid_sy_23_16_pos 0
707#define reg_ccid_sy_23_16_len 8
708#define reg_ccid_sy_23_16_lsb 16
709#define xd_r_reg_ccid2_sz_7_0 0xA114
710#define reg_ccid2_sz_7_0_pos 0
711#define reg_ccid2_sz_7_0_len 8
712#define reg_ccid2_sz_7_0_lsb 0
713#define xd_r_reg_ccid2_sz_15_8 0xA115
714#define reg_ccid2_sz_15_8_pos 0
715#define reg_ccid2_sz_15_8_len 8
716#define reg_ccid2_sz_15_8_lsb 8
717#define xd_r_reg_ccid2_sz_23_16 0xA116
718#define reg_ccid2_sz_23_16_pos 0
719#define reg_ccid2_sz_23_16_len 8
720#define reg_ccid2_sz_23_16_lsb 16
721#define xd_r_reg_ccid2_sz_25_24 0xA117
722#define reg_ccid2_sz_25_24_pos 0
723#define reg_ccid2_sz_25_24_len 2
724#define reg_ccid2_sz_25_24_lsb 24
725#define xd_r_reg_ccid2_sy_7_0 0xA118
726#define reg_ccid2_sy_7_0_pos 0
727#define reg_ccid2_sy_7_0_len 8
728#define reg_ccid2_sy_7_0_lsb 0
729#define xd_r_reg_ccid2_sy_15_8 0xA119
730#define reg_ccid2_sy_15_8_pos 0
731#define reg_ccid2_sy_15_8_len 8
732#define reg_ccid2_sy_15_8_lsb 8
733#define xd_r_reg_ccid2_sy_23_16 0xA11A
734#define reg_ccid2_sy_23_16_pos 0
735#define reg_ccid2_sy_23_16_len 8
736#define reg_ccid2_sy_23_16_lsb 16
737#define xd_r_reg_ccid2_sy_25_24 0xA11B
738#define reg_ccid2_sy_25_24_pos 0
739#define reg_ccid2_sy_25_24_len 2
740#define reg_ccid2_sy_25_24_lsb 24
741#define xd_p_dagc1_accumulate_num_2k_7_0 0xA120
742#define dagc1_accumulate_num_2k_7_0_pos 0
743#define dagc1_accumulate_num_2k_7_0_len 8
744#define dagc1_accumulate_num_2k_7_0_lsb 0
745#define xd_p_dagc1_accumulate_num_2k_12_8 0xA121
746#define dagc1_accumulate_num_2k_12_8_pos 0
747#define dagc1_accumulate_num_2k_12_8_len 5
748#define dagc1_accumulate_num_2k_12_8_lsb 8
749#define xd_p_dagc1_accumulate_num_8k_7_0 0xA122
750#define dagc1_accumulate_num_8k_7_0_pos 0
751#define dagc1_accumulate_num_8k_7_0_len 8
752#define dagc1_accumulate_num_8k_7_0_lsb 0
753#define xd_p_dagc1_accumulate_num_8k_14_8 0xA123
754#define dagc1_accumulate_num_8k_14_8_pos 0
755#define dagc1_accumulate_num_8k_14_8_len 7
756#define dagc1_accumulate_num_8k_14_8_lsb 8
757#define xd_p_dagc1_desired_level_0 0xA123
758#define dagc1_desired_level_0_pos 7
759#define dagc1_desired_level_0_len 1
760#define dagc1_desired_level_0_lsb 0
761#define xd_p_dagc1_desired_level_8_1 0xA124
762#define dagc1_desired_level_8_1_pos 0
763#define dagc1_desired_level_8_1_len 8
764#define dagc1_desired_level_8_1_lsb 1
765#define xd_p_dagc1_apply_delay 0xA125
766#define dagc1_apply_delay_pos 0
767#define dagc1_apply_delay_len 7
768#define dagc1_apply_delay_lsb 0
769#define xd_p_dagc1_bypass_scale_ctl 0xA126
770#define dagc1_bypass_scale_ctl_pos 0
771#define dagc1_bypass_scale_ctl_len 2
772#define dagc1_bypass_scale_ctl_lsb 0
773#define xd_p_reg_dagc1_in_sat_cnt_7_0 0xA127
774#define reg_dagc1_in_sat_cnt_7_0_pos 0
775#define reg_dagc1_in_sat_cnt_7_0_len 8
776#define reg_dagc1_in_sat_cnt_7_0_lsb 0
777#define xd_p_reg_dagc1_in_sat_cnt_15_8 0xA128
778#define reg_dagc1_in_sat_cnt_15_8_pos 0
779#define reg_dagc1_in_sat_cnt_15_8_len 8
780#define reg_dagc1_in_sat_cnt_15_8_lsb 8
781#define xd_p_reg_dagc1_in_sat_cnt_23_16 0xA129
782#define reg_dagc1_in_sat_cnt_23_16_pos 0
783#define reg_dagc1_in_sat_cnt_23_16_len 8
784#define reg_dagc1_in_sat_cnt_23_16_lsb 16
785#define xd_p_reg_dagc1_in_sat_cnt_31_24 0xA12A
786#define reg_dagc1_in_sat_cnt_31_24_pos 0
787#define reg_dagc1_in_sat_cnt_31_24_len 8
788#define reg_dagc1_in_sat_cnt_31_24_lsb 24
789#define xd_p_reg_dagc1_out_sat_cnt_7_0 0xA12B
790#define reg_dagc1_out_sat_cnt_7_0_pos 0
791#define reg_dagc1_out_sat_cnt_7_0_len 8
792#define reg_dagc1_out_sat_cnt_7_0_lsb 0
793#define xd_p_reg_dagc1_out_sat_cnt_15_8 0xA12C
794#define reg_dagc1_out_sat_cnt_15_8_pos 0
795#define reg_dagc1_out_sat_cnt_15_8_len 8
796#define reg_dagc1_out_sat_cnt_15_8_lsb 8
797#define xd_p_reg_dagc1_out_sat_cnt_23_16 0xA12D
798#define reg_dagc1_out_sat_cnt_23_16_pos 0
799#define reg_dagc1_out_sat_cnt_23_16_len 8
800#define reg_dagc1_out_sat_cnt_23_16_lsb 16
801#define xd_p_reg_dagc1_out_sat_cnt_31_24 0xA12E
802#define reg_dagc1_out_sat_cnt_31_24_pos 0
803#define reg_dagc1_out_sat_cnt_31_24_len 8
804#define reg_dagc1_out_sat_cnt_31_24_lsb 24
805#define xd_r_dagc1_multiplier_7_0 0xA136
806#define dagc1_multiplier_7_0_pos 0
807#define dagc1_multiplier_7_0_len 8
808#define dagc1_multiplier_7_0_lsb 0
809#define xd_r_dagc1_multiplier_15_8 0xA137
810#define dagc1_multiplier_15_8_pos 0
811#define dagc1_multiplier_15_8_len 8
812#define dagc1_multiplier_15_8_lsb 8
813#define xd_r_dagc1_right_shift_bits 0xA138
814#define dagc1_right_shift_bits_pos 0
815#define dagc1_right_shift_bits_len 4
816#define dagc1_right_shift_bits_lsb 0
817#define xd_p_reg_bfs_fcw_7_0 0xA140
818#define reg_bfs_fcw_7_0_pos 0
819#define reg_bfs_fcw_7_0_len 8
820#define reg_bfs_fcw_7_0_lsb 0
821#define xd_p_reg_bfs_fcw_15_8 0xA141
822#define reg_bfs_fcw_15_8_pos 0
823#define reg_bfs_fcw_15_8_len 8
824#define reg_bfs_fcw_15_8_lsb 8
825#define xd_p_reg_bfs_fcw_22_16 0xA142
826#define reg_bfs_fcw_22_16_pos 0
827#define reg_bfs_fcw_22_16_len 7
828#define reg_bfs_fcw_22_16_lsb 16
829#define xd_p_reg_antif_sf_7_0 0xA144
830#define reg_antif_sf_7_0_pos 0
831#define reg_antif_sf_7_0_len 8
832#define reg_antif_sf_7_0_lsb 0
833#define xd_p_reg_antif_sf_11_8 0xA145
834#define reg_antif_sf_11_8_pos 0
835#define reg_antif_sf_11_8_len 4
836#define reg_antif_sf_11_8_lsb 8
837#define xd_r_bfs_fcw_q_7_0 0xA150
838#define bfs_fcw_q_7_0_pos 0
839#define bfs_fcw_q_7_0_len 8
840#define bfs_fcw_q_7_0_lsb 0
841#define xd_r_bfs_fcw_q_15_8 0xA151
842#define bfs_fcw_q_15_8_pos 0
843#define bfs_fcw_q_15_8_len 8
844#define bfs_fcw_q_15_8_lsb 8
845#define xd_r_bfs_fcw_q_22_16 0xA152
846#define bfs_fcw_q_22_16_pos 0
847#define bfs_fcw_q_22_16_len 7
848#define bfs_fcw_q_22_16_lsb 16
849#define xd_p_reg_dca_enu 0xA160
850#define reg_dca_enu_pos 0
851#define reg_dca_enu_len 1
852#define reg_dca_enu_lsb 0
853#define xd_p_reg_dca_enl 0xA160
854#define reg_dca_enl_pos 1
855#define reg_dca_enl_len 1
856#define reg_dca_enl_lsb 0
857#define xd_p_reg_dca_lower_chip 0xA160
858#define reg_dca_lower_chip_pos 2
859#define reg_dca_lower_chip_len 1
860#define reg_dca_lower_chip_lsb 0
861#define xd_p_reg_dca_upper_chip 0xA160
862#define reg_dca_upper_chip_pos 3
863#define reg_dca_upper_chip_len 1
864#define reg_dca_upper_chip_lsb 0
865#define xd_p_reg_dca_platch 0xA160
866#define reg_dca_platch_pos 4
867#define reg_dca_platch_len 1
868#define reg_dca_platch_lsb 0
869#define xd_p_reg_dca_th 0xA161
870#define reg_dca_th_pos 0
871#define reg_dca_th_len 5
872#define reg_dca_th_lsb 0
873#define xd_p_reg_dca_scale 0xA162
874#define reg_dca_scale_pos 0
875#define reg_dca_scale_len 4
876#define reg_dca_scale_lsb 0
877#define xd_p_reg_dca_tone_7_0 0xA163
878#define reg_dca_tone_7_0_pos 0
879#define reg_dca_tone_7_0_len 8
880#define reg_dca_tone_7_0_lsb 0
881#define xd_p_reg_dca_tone_12_8 0xA164
882#define reg_dca_tone_12_8_pos 0
883#define reg_dca_tone_12_8_len 5
884#define reg_dca_tone_12_8_lsb 8
885#define xd_p_reg_dca_time_7_0 0xA165
886#define reg_dca_time_7_0_pos 0
887#define reg_dca_time_7_0_len 8
888#define reg_dca_time_7_0_lsb 0
889#define xd_p_reg_dca_time_15_8 0xA166
890#define reg_dca_time_15_8_pos 0
891#define reg_dca_time_15_8_len 8
892#define reg_dca_time_15_8_lsb 8
893#define xd_r_dcasm 0xA167
894#define dcasm_pos 0
895#define dcasm_len 3
896#define dcasm_lsb 0
897#define xd_p_reg_qnt_valuew_7_0 0xA168
898#define reg_qnt_valuew_7_0_pos 0
899#define reg_qnt_valuew_7_0_len 8
900#define reg_qnt_valuew_7_0_lsb 0
901#define xd_p_reg_qnt_valuew_10_8 0xA169
902#define reg_qnt_valuew_10_8_pos 0
903#define reg_qnt_valuew_10_8_len 3
904#define reg_qnt_valuew_10_8_lsb 8
905#define xd_p_dca_sbx_gain_diff_7_0 0xA16A
906#define dca_sbx_gain_diff_7_0_pos 0
907#define dca_sbx_gain_diff_7_0_len 8
908#define dca_sbx_gain_diff_7_0_lsb 0
909#define xd_p_dca_sbx_gain_diff_9_8 0xA16B
910#define dca_sbx_gain_diff_9_8_pos 0
911#define dca_sbx_gain_diff_9_8_len 2
912#define dca_sbx_gain_diff_9_8_lsb 8
913#define xd_p_reg_dca_stand_alone 0xA16C
914#define reg_dca_stand_alone_pos 0
915#define reg_dca_stand_alone_len 1
916#define reg_dca_stand_alone_lsb 0
917#define xd_p_reg_dca_upper_out_en 0xA16C
918#define reg_dca_upper_out_en_pos 1
919#define reg_dca_upper_out_en_len 1
920#define reg_dca_upper_out_en_lsb 0
921#define xd_p_reg_dca_rc_en 0xA16C
922#define reg_dca_rc_en_pos 2
923#define reg_dca_rc_en_len 1
924#define reg_dca_rc_en_lsb 0
925#define xd_p_reg_dca_retrain_send 0xA16C
926#define reg_dca_retrain_send_pos 3
927#define reg_dca_retrain_send_len 1
928#define reg_dca_retrain_send_lsb 0
929#define xd_p_reg_dca_retrain_rec 0xA16C
930#define reg_dca_retrain_rec_pos 4
931#define reg_dca_retrain_rec_len 1
932#define reg_dca_retrain_rec_lsb 0
933#define xd_p_reg_dca_api_tpsrdy 0xA16C
934#define reg_dca_api_tpsrdy_pos 5
935#define reg_dca_api_tpsrdy_len 1
936#define reg_dca_api_tpsrdy_lsb 0
937#define xd_p_reg_dca_symbol_gap 0xA16D
938#define reg_dca_symbol_gap_pos 0
939#define reg_dca_symbol_gap_len 4
940#define reg_dca_symbol_gap_lsb 0
941#define xd_p_reg_qnt_nfvaluew_7_0 0xA16E
942#define reg_qnt_nfvaluew_7_0_pos 0
943#define reg_qnt_nfvaluew_7_0_len 8
944#define reg_qnt_nfvaluew_7_0_lsb 0
945#define xd_p_reg_qnt_nfvaluew_10_8 0xA16F
946#define reg_qnt_nfvaluew_10_8_pos 0
947#define reg_qnt_nfvaluew_10_8_len 3
948#define reg_qnt_nfvaluew_10_8_lsb 8
949#define xd_p_reg_qnt_flatness_thr_7_0 0xA170
950#define reg_qnt_flatness_thr_7_0_pos 0
951#define reg_qnt_flatness_thr_7_0_len 8
952#define reg_qnt_flatness_thr_7_0_lsb 0
953#define xd_p_reg_qnt_flatness_thr_9_8 0xA171
954#define reg_qnt_flatness_thr_9_8_pos 0
955#define reg_qnt_flatness_thr_9_8_len 2
956#define reg_qnt_flatness_thr_9_8_lsb 8
957#define xd_p_reg_dca_tone_idx_5_0 0xA171
958#define reg_dca_tone_idx_5_0_pos 2
959#define reg_dca_tone_idx_5_0_len 6
960#define reg_dca_tone_idx_5_0_lsb 0
961#define xd_p_reg_dca_tone_idx_12_6 0xA172
962#define reg_dca_tone_idx_12_6_pos 0
963#define reg_dca_tone_idx_12_6_len 7
964#define reg_dca_tone_idx_12_6_lsb 6
965#define xd_p_reg_dca_data_vld 0xA173
966#define reg_dca_data_vld_pos 0
967#define reg_dca_data_vld_len 1
968#define reg_dca_data_vld_lsb 0
969#define xd_p_reg_dca_read_update 0xA173
970#define reg_dca_read_update_pos 1
971#define reg_dca_read_update_len 1
972#define reg_dca_read_update_lsb 0
973#define xd_r_reg_dca_data_re_5_0 0xA173
974#define reg_dca_data_re_5_0_pos 2
975#define reg_dca_data_re_5_0_len 6
976#define reg_dca_data_re_5_0_lsb 0
977#define xd_r_reg_dca_data_re_10_6 0xA174
978#define reg_dca_data_re_10_6_pos 0
979#define reg_dca_data_re_10_6_len 5
980#define reg_dca_data_re_10_6_lsb 6
981#define xd_r_reg_dca_data_im_7_0 0xA175
982#define reg_dca_data_im_7_0_pos 0
983#define reg_dca_data_im_7_0_len 8
984#define reg_dca_data_im_7_0_lsb 0
985#define xd_r_reg_dca_data_im_10_8 0xA176
986#define reg_dca_data_im_10_8_pos 0
987#define reg_dca_data_im_10_8_len 3
988#define reg_dca_data_im_10_8_lsb 8
989#define xd_r_reg_dca_data_h2_7_0 0xA178
990#define reg_dca_data_h2_7_0_pos 0
991#define reg_dca_data_h2_7_0_len 8
992#define reg_dca_data_h2_7_0_lsb 0
993#define xd_r_reg_dca_data_h2_9_8 0xA179
994#define reg_dca_data_h2_9_8_pos 0
995#define reg_dca_data_h2_9_8_len 2
996#define reg_dca_data_h2_9_8_lsb 8
997#define xd_p_reg_f_adc_7_0 0xA180
998#define reg_f_adc_7_0_pos 0
999#define reg_f_adc_7_0_len 8
1000#define reg_f_adc_7_0_lsb 0
1001#define xd_p_reg_f_adc_15_8 0xA181
1002#define reg_f_adc_15_8_pos 0
1003#define reg_f_adc_15_8_len 8
1004#define reg_f_adc_15_8_lsb 8
1005#define xd_p_reg_f_adc_23_16 0xA182
1006#define reg_f_adc_23_16_pos 0
1007#define reg_f_adc_23_16_len 8
1008#define reg_f_adc_23_16_lsb 16
1009#define xd_r_intp_mu_7_0 0xA190
1010#define intp_mu_7_0_pos 0
1011#define intp_mu_7_0_len 8
1012#define intp_mu_7_0_lsb 0
1013#define xd_r_intp_mu_15_8 0xA191
1014#define intp_mu_15_8_pos 0
1015#define intp_mu_15_8_len 8
1016#define intp_mu_15_8_lsb 8
1017#define xd_r_intp_mu_19_16 0xA192
1018#define intp_mu_19_16_pos 0
1019#define intp_mu_19_16_len 4
1020#define intp_mu_19_16_lsb 16
1021#define xd_p_reg_agc_rst 0xA1A0
1022#define reg_agc_rst_pos 0
1023#define reg_agc_rst_len 1
1024#define reg_agc_rst_lsb 0
1025#define xd_p_rf_agc_en 0xA1A0
1026#define rf_agc_en_pos 1
1027#define rf_agc_en_len 1
1028#define rf_agc_en_lsb 0
1029#define xd_p_rf_agc_dis 0xA1A0
1030#define rf_agc_dis_pos 2
1031#define rf_agc_dis_len 1
1032#define rf_agc_dis_lsb 0
1033#define xd_p_if_agc_rst 0xA1A0
1034#define if_agc_rst_pos 3
1035#define if_agc_rst_len 1
1036#define if_agc_rst_lsb 0
1037#define xd_p_if_agc_en 0xA1A0
1038#define if_agc_en_pos 4
1039#define if_agc_en_len 1
1040#define if_agc_en_lsb 0
1041#define xd_p_if_agc_dis 0xA1A0
1042#define if_agc_dis_pos 5
1043#define if_agc_dis_len 1
1044#define if_agc_dis_lsb 0
1045#define xd_p_agc_lock 0xA1A0
1046#define agc_lock_pos 6
1047#define agc_lock_len 1
1048#define agc_lock_lsb 0
1049#define xd_p_reg_tinr_rst 0xA1A1
1050#define reg_tinr_rst_pos 0
1051#define reg_tinr_rst_len 1
1052#define reg_tinr_rst_lsb 0
1053#define xd_p_reg_tinr_en 0xA1A1
1054#define reg_tinr_en_pos 1
1055#define reg_tinr_en_len 1
1056#define reg_tinr_en_lsb 0
1057#define xd_p_reg_ccifs_en 0xA1A2
1058#define reg_ccifs_en_pos 0
1059#define reg_ccifs_en_len 1
1060#define reg_ccifs_en_lsb 0
1061#define xd_p_reg_ccifs_dis 0xA1A2
1062#define reg_ccifs_dis_pos 1
1063#define reg_ccifs_dis_len 1
1064#define reg_ccifs_dis_lsb 0
1065#define xd_p_reg_ccifs_rst 0xA1A2
1066#define reg_ccifs_rst_pos 2
1067#define reg_ccifs_rst_len 1
1068#define reg_ccifs_rst_lsb 0
1069#define xd_p_reg_ccifs_byp 0xA1A2
1070#define reg_ccifs_byp_pos 3
1071#define reg_ccifs_byp_len 1
1072#define reg_ccifs_byp_lsb 0
1073#define xd_p_reg_ccif_en 0xA1A3
1074#define reg_ccif_en_pos 0
1075#define reg_ccif_en_len 1
1076#define reg_ccif_en_lsb 0
1077#define xd_p_reg_ccif_dis 0xA1A3
1078#define reg_ccif_dis_pos 1
1079#define reg_ccif_dis_len 1
1080#define reg_ccif_dis_lsb 0
1081#define xd_p_reg_ccif_rst 0xA1A3
1082#define reg_ccif_rst_pos 2
1083#define reg_ccif_rst_len 1
1084#define reg_ccif_rst_lsb 0
1085#define xd_p_reg_ccif_byp 0xA1A3
1086#define reg_ccif_byp_pos 3
1087#define reg_ccif_byp_len 1
1088#define reg_ccif_byp_lsb 0
1089#define xd_p_dagc1_rst 0xA1A4
1090#define dagc1_rst_pos 0
1091#define dagc1_rst_len 1
1092#define dagc1_rst_lsb 0
1093#define xd_p_dagc1_en 0xA1A4
1094#define dagc1_en_pos 1
1095#define dagc1_en_len 1
1096#define dagc1_en_lsb 0
1097#define xd_p_dagc1_mode 0xA1A4
1098#define dagc1_mode_pos 2
1099#define dagc1_mode_len 2
1100#define dagc1_mode_lsb 0
1101#define xd_p_dagc1_done 0xA1A4
1102#define dagc1_done_pos 4
1103#define dagc1_done_len 1
1104#define dagc1_done_lsb 0
1105#define xd_p_ccid_rst 0xA1A5
1106#define ccid_rst_pos 0
1107#define ccid_rst_len 1
1108#define ccid_rst_lsb 0
1109#define xd_p_ccid_en 0xA1A5
1110#define ccid_en_pos 1
1111#define ccid_en_len 1
1112#define ccid_en_lsb 0
1113#define xd_p_ccid_mode 0xA1A5
1114#define ccid_mode_pos 2
1115#define ccid_mode_len 2
1116#define ccid_mode_lsb 0
1117#define xd_p_ccid_done 0xA1A5
1118#define ccid_done_pos 4
1119#define ccid_done_len 1
1120#define ccid_done_lsb 0
1121#define xd_r_ccid_deted 0xA1A5
1122#define ccid_deted_pos 5
1123#define ccid_deted_len 1
1124#define ccid_deted_lsb 0
1125#define xd_p_ccid2_en 0xA1A5
1126#define ccid2_en_pos 6
1127#define ccid2_en_len 1
1128#define ccid2_en_lsb 0
1129#define xd_p_ccid2_done 0xA1A5
1130#define ccid2_done_pos 7
1131#define ccid2_done_len 1
1132#define ccid2_done_lsb 0
1133#define xd_p_reg_bfs_en 0xA1A6
1134#define reg_bfs_en_pos 0
1135#define reg_bfs_en_len 1
1136#define reg_bfs_en_lsb 0
1137#define xd_p_reg_bfs_dis 0xA1A6
1138#define reg_bfs_dis_pos 1
1139#define reg_bfs_dis_len 1
1140#define reg_bfs_dis_lsb 0
1141#define xd_p_reg_bfs_rst 0xA1A6
1142#define reg_bfs_rst_pos 2
1143#define reg_bfs_rst_len 1
1144#define reg_bfs_rst_lsb 0
1145#define xd_p_reg_bfs_byp 0xA1A6
1146#define reg_bfs_byp_pos 3
1147#define reg_bfs_byp_len 1
1148#define reg_bfs_byp_lsb 0
1149#define xd_p_reg_antif_en 0xA1A7
1150#define reg_antif_en_pos 0
1151#define reg_antif_en_len 1
1152#define reg_antif_en_lsb 0
1153#define xd_p_reg_antif_dis 0xA1A7
1154#define reg_antif_dis_pos 1
1155#define reg_antif_dis_len 1
1156#define reg_antif_dis_lsb 0
1157#define xd_p_reg_antif_rst 0xA1A7
1158#define reg_antif_rst_pos 2
1159#define reg_antif_rst_len 1
1160#define reg_antif_rst_lsb 0
1161#define xd_p_reg_antif_byp 0xA1A7
1162#define reg_antif_byp_pos 3
1163#define reg_antif_byp_len 1
1164#define reg_antif_byp_lsb 0
1165#define xd_p_intp_en 0xA1A8
1166#define intp_en_pos 0
1167#define intp_en_len 1
1168#define intp_en_lsb 0
1169#define xd_p_intp_dis 0xA1A8
1170#define intp_dis_pos 1
1171#define intp_dis_len 1
1172#define intp_dis_lsb 0
1173#define xd_p_intp_rst 0xA1A8
1174#define intp_rst_pos 2
1175#define intp_rst_len 1
1176#define intp_rst_lsb 0
1177#define xd_p_intp_byp 0xA1A8
1178#define intp_byp_pos 3
1179#define intp_byp_len 1
1180#define intp_byp_lsb 0
1181#define xd_p_reg_acif_en 0xA1A9
1182#define reg_acif_en_pos 0
1183#define reg_acif_en_len 1
1184#define reg_acif_en_lsb 0
1185#define xd_p_reg_acif_dis 0xA1A9
1186#define reg_acif_dis_pos 1
1187#define reg_acif_dis_len 1
1188#define reg_acif_dis_lsb 0
1189#define xd_p_reg_acif_rst 0xA1A9
1190#define reg_acif_rst_pos 2
1191#define reg_acif_rst_len 1
1192#define reg_acif_rst_lsb 0
1193#define xd_p_reg_acif_byp 0xA1A9
1194#define reg_acif_byp_pos 3
1195#define reg_acif_byp_len 1
1196#define reg_acif_byp_lsb 0
1197#define xd_p_reg_acif_sync_mode 0xA1A9
1198#define reg_acif_sync_mode_pos 4
1199#define reg_acif_sync_mode_len 1
1200#define reg_acif_sync_mode_lsb 0
1201#define xd_p_dagc2_rst 0xA1AA
1202#define dagc2_rst_pos 0
1203#define dagc2_rst_len 1
1204#define dagc2_rst_lsb 0
1205#define xd_p_dagc2_en 0xA1AA
1206#define dagc2_en_pos 1
1207#define dagc2_en_len 1
1208#define dagc2_en_lsb 0
1209#define xd_p_dagc2_mode 0xA1AA
1210#define dagc2_mode_pos 2
1211#define dagc2_mode_len 2
1212#define dagc2_mode_lsb 0
1213#define xd_p_dagc2_done 0xA1AA
1214#define dagc2_done_pos 4
1215#define dagc2_done_len 1
1216#define dagc2_done_lsb 0
1217#define xd_p_reg_dca_en 0xA1AB
1218#define reg_dca_en_pos 0
1219#define reg_dca_en_len 1
1220#define reg_dca_en_lsb 0
1221#define xd_p_dagc2_accumulate_num_2k_7_0 0xA1C0
1222#define dagc2_accumulate_num_2k_7_0_pos 0
1223#define dagc2_accumulate_num_2k_7_0_len 8
1224#define dagc2_accumulate_num_2k_7_0_lsb 0
1225#define xd_p_dagc2_accumulate_num_2k_12_8 0xA1C1
1226#define dagc2_accumulate_num_2k_12_8_pos 0
1227#define dagc2_accumulate_num_2k_12_8_len 5
1228#define dagc2_accumulate_num_2k_12_8_lsb 8
1229#define xd_p_dagc2_accumulate_num_8k_7_0 0xA1C2
1230#define dagc2_accumulate_num_8k_7_0_pos 0
1231#define dagc2_accumulate_num_8k_7_0_len 8
1232#define dagc2_accumulate_num_8k_7_0_lsb 0
1233#define xd_p_dagc2_accumulate_num_8k_12_8 0xA1C3
1234#define dagc2_accumulate_num_8k_12_8_pos 0
1235#define dagc2_accumulate_num_8k_12_8_len 5
1236#define dagc2_accumulate_num_8k_12_8_lsb 8
1237#define xd_p_dagc2_desired_level_2_0 0xA1C3
1238#define dagc2_desired_level_2_0_pos 5
1239#define dagc2_desired_level_2_0_len 3
1240#define dagc2_desired_level_2_0_lsb 0
1241#define xd_p_dagc2_desired_level_8_3 0xA1C4
1242#define dagc2_desired_level_8_3_pos 0
1243#define dagc2_desired_level_8_3_len 6
1244#define dagc2_desired_level_8_3_lsb 3
1245#define xd_p_dagc2_apply_delay 0xA1C5
1246#define dagc2_apply_delay_pos 0
1247#define dagc2_apply_delay_len 7
1248#define dagc2_apply_delay_lsb 0
1249#define xd_p_dagc2_bypass_scale_ctl 0xA1C6
1250#define dagc2_bypass_scale_ctl_pos 0
1251#define dagc2_bypass_scale_ctl_len 3
1252#define dagc2_bypass_scale_ctl_lsb 0
1253#define xd_p_dagc2_programmable_shift1 0xA1C7
1254#define dagc2_programmable_shift1_pos 0
1255#define dagc2_programmable_shift1_len 8
1256#define dagc2_programmable_shift1_lsb 0
1257#define xd_p_dagc2_programmable_shift2 0xA1C8
1258#define dagc2_programmable_shift2_pos 0
1259#define dagc2_programmable_shift2_len 8
1260#define dagc2_programmable_shift2_lsb 0
1261#define xd_p_reg_dagc2_in_sat_cnt_7_0 0xA1C9
1262#define reg_dagc2_in_sat_cnt_7_0_pos 0
1263#define reg_dagc2_in_sat_cnt_7_0_len 8
1264#define reg_dagc2_in_sat_cnt_7_0_lsb 0
1265#define xd_p_reg_dagc2_in_sat_cnt_15_8 0xA1CA
1266#define reg_dagc2_in_sat_cnt_15_8_pos 0
1267#define reg_dagc2_in_sat_cnt_15_8_len 8
1268#define reg_dagc2_in_sat_cnt_15_8_lsb 8
1269#define xd_p_reg_dagc2_in_sat_cnt_23_16 0xA1CB
1270#define reg_dagc2_in_sat_cnt_23_16_pos 0
1271#define reg_dagc2_in_sat_cnt_23_16_len 8
1272#define reg_dagc2_in_sat_cnt_23_16_lsb 16
1273#define xd_p_reg_dagc2_in_sat_cnt_31_24 0xA1CC
1274#define reg_dagc2_in_sat_cnt_31_24_pos 0
1275#define reg_dagc2_in_sat_cnt_31_24_len 8
1276#define reg_dagc2_in_sat_cnt_31_24_lsb 24
1277#define xd_p_reg_dagc2_out_sat_cnt_7_0 0xA1CD
1278#define reg_dagc2_out_sat_cnt_7_0_pos 0
1279#define reg_dagc2_out_sat_cnt_7_0_len 8
1280#define reg_dagc2_out_sat_cnt_7_0_lsb 0
1281#define xd_p_reg_dagc2_out_sat_cnt_15_8 0xA1CE
1282#define reg_dagc2_out_sat_cnt_15_8_pos 0
1283#define reg_dagc2_out_sat_cnt_15_8_len 8
1284#define reg_dagc2_out_sat_cnt_15_8_lsb 8
1285#define xd_p_reg_dagc2_out_sat_cnt_23_16 0xA1CF
1286#define reg_dagc2_out_sat_cnt_23_16_pos 0
1287#define reg_dagc2_out_sat_cnt_23_16_len 8
1288#define reg_dagc2_out_sat_cnt_23_16_lsb 16
1289#define xd_p_reg_dagc2_out_sat_cnt_31_24 0xA1D0
1290#define reg_dagc2_out_sat_cnt_31_24_pos 0
1291#define reg_dagc2_out_sat_cnt_31_24_len 8
1292#define reg_dagc2_out_sat_cnt_31_24_lsb 24
1293#define xd_r_dagc2_multiplier_7_0 0xA1D6
1294#define dagc2_multiplier_7_0_pos 0
1295#define dagc2_multiplier_7_0_len 8
1296#define dagc2_multiplier_7_0_lsb 0
1297#define xd_r_dagc2_multiplier_15_8 0xA1D7
1298#define dagc2_multiplier_15_8_pos 0
1299#define dagc2_multiplier_15_8_len 8
1300#define dagc2_multiplier_15_8_lsb 8
1301#define xd_r_dagc2_right_shift_bits 0xA1D8
1302#define dagc2_right_shift_bits_pos 0
1303#define dagc2_right_shift_bits_len 4
1304#define dagc2_right_shift_bits_lsb 0
1305#define xd_p_cfoe_NS_coeff1_7_0 0xA200
1306#define cfoe_NS_coeff1_7_0_pos 0
1307#define cfoe_NS_coeff1_7_0_len 8
1308#define cfoe_NS_coeff1_7_0_lsb 0
1309#define xd_p_cfoe_NS_coeff1_15_8 0xA201
1310#define cfoe_NS_coeff1_15_8_pos 0
1311#define cfoe_NS_coeff1_15_8_len 8
1312#define cfoe_NS_coeff1_15_8_lsb 8
1313#define xd_p_cfoe_NS_coeff1_23_16 0xA202
1314#define cfoe_NS_coeff1_23_16_pos 0
1315#define cfoe_NS_coeff1_23_16_len 8
1316#define cfoe_NS_coeff1_23_16_lsb 16
1317#define xd_p_cfoe_NS_coeff1_25_24 0xA203
1318#define cfoe_NS_coeff1_25_24_pos 0
1319#define cfoe_NS_coeff1_25_24_len 2
1320#define cfoe_NS_coeff1_25_24_lsb 24
1321#define xd_p_cfoe_NS_coeff2_5_0 0xA203
1322#define cfoe_NS_coeff2_5_0_pos 2
1323#define cfoe_NS_coeff2_5_0_len 6
1324#define cfoe_NS_coeff2_5_0_lsb 0
1325#define xd_p_cfoe_NS_coeff2_13_6 0xA204
1326#define cfoe_NS_coeff2_13_6_pos 0
1327#define cfoe_NS_coeff2_13_6_len 8
1328#define cfoe_NS_coeff2_13_6_lsb 6
1329#define xd_p_cfoe_NS_coeff2_21_14 0xA205
1330#define cfoe_NS_coeff2_21_14_pos 0
1331#define cfoe_NS_coeff2_21_14_len 8
1332#define cfoe_NS_coeff2_21_14_lsb 14
1333#define xd_p_cfoe_NS_coeff2_24_22 0xA206
1334#define cfoe_NS_coeff2_24_22_pos 0
1335#define cfoe_NS_coeff2_24_22_len 3
1336#define cfoe_NS_coeff2_24_22_lsb 22
1337#define xd_p_cfoe_lf_c1_4_0 0xA206
1338#define cfoe_lf_c1_4_0_pos 3
1339#define cfoe_lf_c1_4_0_len 5
1340#define cfoe_lf_c1_4_0_lsb 0
1341#define xd_p_cfoe_lf_c1_12_5 0xA207
1342#define cfoe_lf_c1_12_5_pos 0
1343#define cfoe_lf_c1_12_5_len 8
1344#define cfoe_lf_c1_12_5_lsb 5
1345#define xd_p_cfoe_lf_c1_20_13 0xA208
1346#define cfoe_lf_c1_20_13_pos 0
1347#define cfoe_lf_c1_20_13_len 8
1348#define cfoe_lf_c1_20_13_lsb 13
1349#define xd_p_cfoe_lf_c1_25_21 0xA209
1350#define cfoe_lf_c1_25_21_pos 0
1351#define cfoe_lf_c1_25_21_len 5
1352#define cfoe_lf_c1_25_21_lsb 21
1353#define xd_p_cfoe_lf_c2_2_0 0xA209
1354#define cfoe_lf_c2_2_0_pos 5
1355#define cfoe_lf_c2_2_0_len 3
1356#define cfoe_lf_c2_2_0_lsb 0
1357#define xd_p_cfoe_lf_c2_10_3 0xA20A
1358#define cfoe_lf_c2_10_3_pos 0
1359#define cfoe_lf_c2_10_3_len 8
1360#define cfoe_lf_c2_10_3_lsb 3
1361#define xd_p_cfoe_lf_c2_18_11 0xA20B
1362#define cfoe_lf_c2_18_11_pos 0
1363#define cfoe_lf_c2_18_11_len 8
1364#define cfoe_lf_c2_18_11_lsb 11
1365#define xd_p_cfoe_lf_c2_25_19 0xA20C
1366#define cfoe_lf_c2_25_19_pos 0
1367#define cfoe_lf_c2_25_19_len 7
1368#define cfoe_lf_c2_25_19_lsb 19
1369#define xd_p_cfoe_ifod_7_0 0xA20D
1370#define cfoe_ifod_7_0_pos 0
1371#define cfoe_ifod_7_0_len 8
1372#define cfoe_ifod_7_0_lsb 0
1373#define xd_p_cfoe_ifod_10_8 0xA20E
1374#define cfoe_ifod_10_8_pos 0
1375#define cfoe_ifod_10_8_len 3
1376#define cfoe_ifod_10_8_lsb 8
1377#define xd_p_cfoe_Divg_ctr_th 0xA20E
1378#define cfoe_Divg_ctr_th_pos 4
1379#define cfoe_Divg_ctr_th_len 4
1380#define cfoe_Divg_ctr_th_lsb 0
1381#define xd_p_cfoe_FOT_divg_th 0xA20F
1382#define cfoe_FOT_divg_th_pos 0
1383#define cfoe_FOT_divg_th_len 8
1384#define cfoe_FOT_divg_th_lsb 0
1385#define xd_p_cfoe_FOT_cnvg_th 0xA210
1386#define cfoe_FOT_cnvg_th_pos 0
1387#define cfoe_FOT_cnvg_th_len 8
1388#define cfoe_FOT_cnvg_th_lsb 0
1389#define xd_p_reg_cfoe_offset_7_0 0xA211
1390#define reg_cfoe_offset_7_0_pos 0
1391#define reg_cfoe_offset_7_0_len 8
1392#define reg_cfoe_offset_7_0_lsb 0
1393#define xd_p_reg_cfoe_offset_9_8 0xA212
1394#define reg_cfoe_offset_9_8_pos 0
1395#define reg_cfoe_offset_9_8_len 2
1396#define reg_cfoe_offset_9_8_lsb 8
1397#define xd_p_reg_cfoe_ifoe_sign_corr 0xA212
1398#define reg_cfoe_ifoe_sign_corr_pos 2
1399#define reg_cfoe_ifoe_sign_corr_len 1
1400#define reg_cfoe_ifoe_sign_corr_lsb 0
1401#define xd_r_cfoe_fot_LF_output_7_0 0xA218
1402#define cfoe_fot_LF_output_7_0_pos 0
1403#define cfoe_fot_LF_output_7_0_len 8
1404#define cfoe_fot_LF_output_7_0_lsb 0
1405#define xd_r_cfoe_fot_LF_output_15_8 0xA219
1406#define cfoe_fot_LF_output_15_8_pos 0
1407#define cfoe_fot_LF_output_15_8_len 8
1408#define cfoe_fot_LF_output_15_8_lsb 8
1409#define xd_r_cfoe_ifo_metric_7_0 0xA21A
1410#define cfoe_ifo_metric_7_0_pos 0
1411#define cfoe_ifo_metric_7_0_len 8
1412#define cfoe_ifo_metric_7_0_lsb 0
1413#define xd_r_cfoe_ifo_metric_15_8 0xA21B
1414#define cfoe_ifo_metric_15_8_pos 0
1415#define cfoe_ifo_metric_15_8_len 8
1416#define cfoe_ifo_metric_15_8_lsb 8
1417#define xd_r_cfoe_ifo_metric_23_16 0xA21C
1418#define cfoe_ifo_metric_23_16_pos 0
1419#define cfoe_ifo_metric_23_16_len 8
1420#define cfoe_ifo_metric_23_16_lsb 16
1421#define xd_p_ste_Nu 0xA220
1422#define ste_Nu_pos 0
1423#define ste_Nu_len 2
1424#define ste_Nu_lsb 0
1425#define xd_p_ste_GI 0xA220
1426#define ste_GI_pos 2
1427#define ste_GI_len 3
1428#define ste_GI_lsb 0
1429#define xd_p_ste_symbol_num 0xA221
1430#define ste_symbol_num_pos 0
1431#define ste_symbol_num_len 2
1432#define ste_symbol_num_lsb 0
1433#define xd_p_ste_sample_num 0xA221
1434#define ste_sample_num_pos 2
1435#define ste_sample_num_len 2
1436#define ste_sample_num_lsb 0
1437#define xd_p_reg_ste_buf_en 0xA221
1438#define reg_ste_buf_en_pos 7
1439#define reg_ste_buf_en_len 1
1440#define reg_ste_buf_en_lsb 0
1441#define xd_p_ste_FFT_offset_7_0 0xA222
1442#define ste_FFT_offset_7_0_pos 0
1443#define ste_FFT_offset_7_0_len 8
1444#define ste_FFT_offset_7_0_lsb 0
1445#define xd_p_ste_FFT_offset_11_8 0xA223
1446#define ste_FFT_offset_11_8_pos 0
1447#define ste_FFT_offset_11_8_len 4
1448#define ste_FFT_offset_11_8_lsb 8
1449#define xd_p_reg_ste_tstmod 0xA223
1450#define reg_ste_tstmod_pos 5
1451#define reg_ste_tstmod_len 1
1452#define reg_ste_tstmod_lsb 0
1453#define xd_p_ste_adv_start_7_0 0xA224
1454#define ste_adv_start_7_0_pos 0
1455#define ste_adv_start_7_0_len 8
1456#define ste_adv_start_7_0_lsb 0
1457#define xd_p_ste_adv_start_10_8 0xA225
1458#define ste_adv_start_10_8_pos 0
1459#define ste_adv_start_10_8_len 3
1460#define ste_adv_start_10_8_lsb 8
1461#define xd_p_ste_adv_stop 0xA226
1462#define ste_adv_stop_pos 0
1463#define ste_adv_stop_len 8
1464#define ste_adv_stop_lsb 0
1465#define xd_r_ste_P_value_7_0 0xA228
1466#define ste_P_value_7_0_pos 0
1467#define ste_P_value_7_0_len 8
1468#define ste_P_value_7_0_lsb 0
1469#define xd_r_ste_P_value_10_8 0xA229
1470#define ste_P_value_10_8_pos 0
1471#define ste_P_value_10_8_len 3
1472#define ste_P_value_10_8_lsb 8
1473#define xd_r_ste_M_value_7_0 0xA22A
1474#define ste_M_value_7_0_pos 0
1475#define ste_M_value_7_0_len 8
1476#define ste_M_value_7_0_lsb 0
1477#define xd_r_ste_M_value_10_8 0xA22B
1478#define ste_M_value_10_8_pos 0
1479#define ste_M_value_10_8_len 3
1480#define ste_M_value_10_8_lsb 8
1481#define xd_r_ste_H1 0xA22C
1482#define ste_H1_pos 0
1483#define ste_H1_len 7
1484#define ste_H1_lsb 0
1485#define xd_r_ste_H2 0xA22D
1486#define ste_H2_pos 0
1487#define ste_H2_len 7
1488#define ste_H2_lsb 0
1489#define xd_r_ste_H3 0xA22E
1490#define ste_H3_pos 0
1491#define ste_H3_len 7
1492#define ste_H3_lsb 0
1493#define xd_r_ste_H4 0xA22F
1494#define ste_H4_pos 0
1495#define ste_H4_len 7
1496#define ste_H4_lsb 0
1497#define xd_r_ste_Corr_value_I_7_0 0xA230
1498#define ste_Corr_value_I_7_0_pos 0
1499#define ste_Corr_value_I_7_0_len 8
1500#define ste_Corr_value_I_7_0_lsb 0
1501#define xd_r_ste_Corr_value_I_15_8 0xA231
1502#define ste_Corr_value_I_15_8_pos 0
1503#define ste_Corr_value_I_15_8_len 8
1504#define ste_Corr_value_I_15_8_lsb 8
1505#define xd_r_ste_Corr_value_I_23_16 0xA232
1506#define ste_Corr_value_I_23_16_pos 0
1507#define ste_Corr_value_I_23_16_len 8
1508#define ste_Corr_value_I_23_16_lsb 16
1509#define xd_r_ste_Corr_value_I_27_24 0xA233
1510#define ste_Corr_value_I_27_24_pos 0
1511#define ste_Corr_value_I_27_24_len 4
1512#define ste_Corr_value_I_27_24_lsb 24
1513#define xd_r_ste_Corr_value_Q_7_0 0xA234
1514#define ste_Corr_value_Q_7_0_pos 0
1515#define ste_Corr_value_Q_7_0_len 8
1516#define ste_Corr_value_Q_7_0_lsb 0
1517#define xd_r_ste_Corr_value_Q_15_8 0xA235
1518#define ste_Corr_value_Q_15_8_pos 0
1519#define ste_Corr_value_Q_15_8_len 8
1520#define ste_Corr_value_Q_15_8_lsb 8
1521#define xd_r_ste_Corr_value_Q_23_16 0xA236
1522#define ste_Corr_value_Q_23_16_pos 0
1523#define ste_Corr_value_Q_23_16_len 8
1524#define ste_Corr_value_Q_23_16_lsb 16
1525#define xd_r_ste_Corr_value_Q_27_24 0xA237
1526#define ste_Corr_value_Q_27_24_pos 0
1527#define ste_Corr_value_Q_27_24_len 4
1528#define ste_Corr_value_Q_27_24_lsb 24
1529#define xd_r_ste_J_num_7_0 0xA238
1530#define ste_J_num_7_0_pos 0
1531#define ste_J_num_7_0_len 8
1532#define ste_J_num_7_0_lsb 0
1533#define xd_r_ste_J_num_15_8 0xA239
1534#define ste_J_num_15_8_pos 0
1535#define ste_J_num_15_8_len 8
1536#define ste_J_num_15_8_lsb 8
1537#define xd_r_ste_J_num_23_16 0xA23A
1538#define ste_J_num_23_16_pos 0
1539#define ste_J_num_23_16_len 8
1540#define ste_J_num_23_16_lsb 16
1541#define xd_r_ste_J_num_31_24 0xA23B
1542#define ste_J_num_31_24_pos 0
1543#define ste_J_num_31_24_len 8
1544#define ste_J_num_31_24_lsb 24
1545#define xd_r_ste_J_den_7_0 0xA23C
1546#define ste_J_den_7_0_pos 0
1547#define ste_J_den_7_0_len 8
1548#define ste_J_den_7_0_lsb 0
1549#define xd_r_ste_J_den_15_8 0xA23D
1550#define ste_J_den_15_8_pos 0
1551#define ste_J_den_15_8_len 8
1552#define ste_J_den_15_8_lsb 8
1553#define xd_r_ste_J_den_18_16 0xA23E
1554#define ste_J_den_18_16_pos 0
1555#define ste_J_den_18_16_len 3
1556#define ste_J_den_18_16_lsb 16
1557#define xd_r_ste_Beacon_Indicator 0xA23E
1558#define ste_Beacon_Indicator_pos 4
1559#define ste_Beacon_Indicator_len 1
1560#define ste_Beacon_Indicator_lsb 0
1561#define xd_r_tpsd_Frame_Num 0xA250
1562#define tpsd_Frame_Num_pos 0
1563#define tpsd_Frame_Num_len 2
1564#define tpsd_Frame_Num_lsb 0
1565#define xd_r_tpsd_Constel 0xA250
1566#define tpsd_Constel_pos 2
1567#define tpsd_Constel_len 2
1568#define tpsd_Constel_lsb 0
1569#define xd_r_tpsd_GI 0xA250
1570#define tpsd_GI_pos 4
1571#define tpsd_GI_len 2
1572#define tpsd_GI_lsb 0
1573#define xd_r_tpsd_Mode 0xA250
1574#define tpsd_Mode_pos 6
1575#define tpsd_Mode_len 2
1576#define tpsd_Mode_lsb 0
1577#define xd_r_tpsd_CR_HP 0xA251
1578#define tpsd_CR_HP_pos 0
1579#define tpsd_CR_HP_len 3
1580#define tpsd_CR_HP_lsb 0
1581#define xd_r_tpsd_CR_LP 0xA251
1582#define tpsd_CR_LP_pos 3
1583#define tpsd_CR_LP_len 3
1584#define tpsd_CR_LP_lsb 0
1585#define xd_r_tpsd_Hie 0xA252
1586#define tpsd_Hie_pos 0
1587#define tpsd_Hie_len 3
1588#define tpsd_Hie_lsb 0
1589#define xd_r_tpsd_Res_Bits 0xA252
1590#define tpsd_Res_Bits_pos 3
1591#define tpsd_Res_Bits_len 5
1592#define tpsd_Res_Bits_lsb 0
1593#define xd_r_tpsd_Res_Bits_0 0xA253
1594#define tpsd_Res_Bits_0_pos 0
1595#define tpsd_Res_Bits_0_len 1
1596#define tpsd_Res_Bits_0_lsb 0
1597#define xd_r_tpsd_LengthInd 0xA253
1598#define tpsd_LengthInd_pos 1
1599#define tpsd_LengthInd_len 6
1600#define tpsd_LengthInd_lsb 0
1601#define xd_r_tpsd_Cell_Id_7_0 0xA254
1602#define tpsd_Cell_Id_7_0_pos 0
1603#define tpsd_Cell_Id_7_0_len 8
1604#define tpsd_Cell_Id_7_0_lsb 0
1605#define xd_r_tpsd_Cell_Id_15_8 0xA255
1606#define tpsd_Cell_Id_15_8_pos 0
1607#define tpsd_Cell_Id_15_8_len 8
1608#define tpsd_Cell_Id_15_8_lsb 0
1609#define xd_p_reg_fft_mask_tone0_7_0 0xA260
1610#define reg_fft_mask_tone0_7_0_pos 0
1611#define reg_fft_mask_tone0_7_0_len 8
1612#define reg_fft_mask_tone0_7_0_lsb 0
1613#define xd_p_reg_fft_mask_tone0_12_8 0xA261
1614#define reg_fft_mask_tone0_12_8_pos 0
1615#define reg_fft_mask_tone0_12_8_len 5
1616#define reg_fft_mask_tone0_12_8_lsb 8
1617#define xd_p_reg_fft_mask_tone1_7_0 0xA262
1618#define reg_fft_mask_tone1_7_0_pos 0
1619#define reg_fft_mask_tone1_7_0_len 8
1620#define reg_fft_mask_tone1_7_0_lsb 0
1621#define xd_p_reg_fft_mask_tone1_12_8 0xA263
1622#define reg_fft_mask_tone1_12_8_pos 0
1623#define reg_fft_mask_tone1_12_8_len 5
1624#define reg_fft_mask_tone1_12_8_lsb 8
1625#define xd_p_reg_fft_mask_tone2_7_0 0xA264
1626#define reg_fft_mask_tone2_7_0_pos 0
1627#define reg_fft_mask_tone2_7_0_len 8
1628#define reg_fft_mask_tone2_7_0_lsb 0
1629#define xd_p_reg_fft_mask_tone2_12_8 0xA265
1630#define reg_fft_mask_tone2_12_8_pos 0
1631#define reg_fft_mask_tone2_12_8_len 5
1632#define reg_fft_mask_tone2_12_8_lsb 8
1633#define xd_p_reg_fft_mask_tone3_7_0 0xA266
1634#define reg_fft_mask_tone3_7_0_pos 0
1635#define reg_fft_mask_tone3_7_0_len 8
1636#define reg_fft_mask_tone3_7_0_lsb 0
1637#define xd_p_reg_fft_mask_tone3_12_8 0xA267
1638#define reg_fft_mask_tone3_12_8_pos 0
1639#define reg_fft_mask_tone3_12_8_len 5
1640#define reg_fft_mask_tone3_12_8_lsb 8
1641#define xd_p_reg_fft_mask_from0_7_0 0xA268
1642#define reg_fft_mask_from0_7_0_pos 0
1643#define reg_fft_mask_from0_7_0_len 8
1644#define reg_fft_mask_from0_7_0_lsb 0
1645#define xd_p_reg_fft_mask_from0_12_8 0xA269
1646#define reg_fft_mask_from0_12_8_pos 0
1647#define reg_fft_mask_from0_12_8_len 5
1648#define reg_fft_mask_from0_12_8_lsb 8
1649#define xd_p_reg_fft_mask_to0_7_0 0xA26A
1650#define reg_fft_mask_to0_7_0_pos 0
1651#define reg_fft_mask_to0_7_0_len 8
1652#define reg_fft_mask_to0_7_0_lsb 0
1653#define xd_p_reg_fft_mask_to0_12_8 0xA26B
1654#define reg_fft_mask_to0_12_8_pos 0
1655#define reg_fft_mask_to0_12_8_len 5
1656#define reg_fft_mask_to0_12_8_lsb 8
1657#define xd_p_reg_fft_mask_from1_7_0 0xA26C
1658#define reg_fft_mask_from1_7_0_pos 0
1659#define reg_fft_mask_from1_7_0_len 8
1660#define reg_fft_mask_from1_7_0_lsb 0
1661#define xd_p_reg_fft_mask_from1_12_8 0xA26D
1662#define reg_fft_mask_from1_12_8_pos 0
1663#define reg_fft_mask_from1_12_8_len 5
1664#define reg_fft_mask_from1_12_8_lsb 8
1665#define xd_p_reg_fft_mask_to1_7_0 0xA26E
1666#define reg_fft_mask_to1_7_0_pos 0
1667#define reg_fft_mask_to1_7_0_len 8
1668#define reg_fft_mask_to1_7_0_lsb 0
1669#define xd_p_reg_fft_mask_to1_12_8 0xA26F
1670#define reg_fft_mask_to1_12_8_pos 0
1671#define reg_fft_mask_to1_12_8_len 5
1672#define reg_fft_mask_to1_12_8_lsb 8
1673#define xd_p_reg_cge_idx0_7_0 0xA280
1674#define reg_cge_idx0_7_0_pos 0
1675#define reg_cge_idx0_7_0_len 8
1676#define reg_cge_idx0_7_0_lsb 0
1677#define xd_p_reg_cge_idx0_12_8 0xA281
1678#define reg_cge_idx0_12_8_pos 0
1679#define reg_cge_idx0_12_8_len 5
1680#define reg_cge_idx0_12_8_lsb 8
1681#define xd_p_reg_cge_idx1_7_0 0xA282
1682#define reg_cge_idx1_7_0_pos 0
1683#define reg_cge_idx1_7_0_len 8
1684#define reg_cge_idx1_7_0_lsb 0
1685#define xd_p_reg_cge_idx1_12_8 0xA283
1686#define reg_cge_idx1_12_8_pos 0
1687#define reg_cge_idx1_12_8_len 5
1688#define reg_cge_idx1_12_8_lsb 8
1689#define xd_p_reg_cge_idx2_7_0 0xA284
1690#define reg_cge_idx2_7_0_pos 0
1691#define reg_cge_idx2_7_0_len 8
1692#define reg_cge_idx2_7_0_lsb 0
1693#define xd_p_reg_cge_idx2_12_8 0xA285
1694#define reg_cge_idx2_12_8_pos 0
1695#define reg_cge_idx2_12_8_len 5
1696#define reg_cge_idx2_12_8_lsb 8
1697#define xd_p_reg_cge_idx3_7_0 0xA286
1698#define reg_cge_idx3_7_0_pos 0
1699#define reg_cge_idx3_7_0_len 8
1700#define reg_cge_idx3_7_0_lsb 0
1701#define xd_p_reg_cge_idx3_12_8 0xA287
1702#define reg_cge_idx3_12_8_pos 0
1703#define reg_cge_idx3_12_8_len 5
1704#define reg_cge_idx3_12_8_lsb 8
1705#define xd_p_reg_cge_idx4_7_0 0xA288
1706#define reg_cge_idx4_7_0_pos 0
1707#define reg_cge_idx4_7_0_len 8
1708#define reg_cge_idx4_7_0_lsb 0
1709#define xd_p_reg_cge_idx4_12_8 0xA289
1710#define reg_cge_idx4_12_8_pos 0
1711#define reg_cge_idx4_12_8_len 5
1712#define reg_cge_idx4_12_8_lsb 8
1713#define xd_p_reg_cge_idx5_7_0 0xA28A
1714#define reg_cge_idx5_7_0_pos 0
1715#define reg_cge_idx5_7_0_len 8
1716#define reg_cge_idx5_7_0_lsb 0
1717#define xd_p_reg_cge_idx5_12_8 0xA28B
1718#define reg_cge_idx5_12_8_pos 0
1719#define reg_cge_idx5_12_8_len 5
1720#define reg_cge_idx5_12_8_lsb 8
1721#define xd_p_reg_cge_idx6_7_0 0xA28C
1722#define reg_cge_idx6_7_0_pos 0
1723#define reg_cge_idx6_7_0_len 8
1724#define reg_cge_idx6_7_0_lsb 0
1725#define xd_p_reg_cge_idx6_12_8 0xA28D
1726#define reg_cge_idx6_12_8_pos 0
1727#define reg_cge_idx6_12_8_len 5
1728#define reg_cge_idx6_12_8_lsb 8
1729#define xd_p_reg_cge_idx7_7_0 0xA28E
1730#define reg_cge_idx7_7_0_pos 0
1731#define reg_cge_idx7_7_0_len 8
1732#define reg_cge_idx7_7_0_lsb 0
1733#define xd_p_reg_cge_idx7_12_8 0xA28F
1734#define reg_cge_idx7_12_8_pos 0
1735#define reg_cge_idx7_12_8_len 5
1736#define reg_cge_idx7_12_8_lsb 8
1737#define xd_p_reg_cge_idx8_7_0 0xA290
1738#define reg_cge_idx8_7_0_pos 0
1739#define reg_cge_idx8_7_0_len 8
1740#define reg_cge_idx8_7_0_lsb 0
1741#define xd_p_reg_cge_idx8_12_8 0xA291
1742#define reg_cge_idx8_12_8_pos 0
1743#define reg_cge_idx8_12_8_len 5
1744#define reg_cge_idx8_12_8_lsb 8
1745#define xd_p_reg_cge_idx9_7_0 0xA292
1746#define reg_cge_idx9_7_0_pos 0
1747#define reg_cge_idx9_7_0_len 8
1748#define reg_cge_idx9_7_0_lsb 0
1749#define xd_p_reg_cge_idx9_12_8 0xA293
1750#define reg_cge_idx9_12_8_pos 0
1751#define reg_cge_idx9_12_8_len 5
1752#define reg_cge_idx9_12_8_lsb 8
1753#define xd_p_reg_cge_idx10_7_0 0xA294
1754#define reg_cge_idx10_7_0_pos 0
1755#define reg_cge_idx10_7_0_len 8
1756#define reg_cge_idx10_7_0_lsb 0
1757#define xd_p_reg_cge_idx10_12_8 0xA295
1758#define reg_cge_idx10_12_8_pos 0
1759#define reg_cge_idx10_12_8_len 5
1760#define reg_cge_idx10_12_8_lsb 8
1761#define xd_p_reg_cge_idx11_7_0 0xA296
1762#define reg_cge_idx11_7_0_pos 0
1763#define reg_cge_idx11_7_0_len 8
1764#define reg_cge_idx11_7_0_lsb 0
1765#define xd_p_reg_cge_idx11_12_8 0xA297
1766#define reg_cge_idx11_12_8_pos 0
1767#define reg_cge_idx11_12_8_len 5
1768#define reg_cge_idx11_12_8_lsb 8
1769#define xd_p_reg_cge_idx12_7_0 0xA298
1770#define reg_cge_idx12_7_0_pos 0
1771#define reg_cge_idx12_7_0_len 8
1772#define reg_cge_idx12_7_0_lsb 0
1773#define xd_p_reg_cge_idx12_12_8 0xA299
1774#define reg_cge_idx12_12_8_pos 0
1775#define reg_cge_idx12_12_8_len 5
1776#define reg_cge_idx12_12_8_lsb 8
1777#define xd_p_reg_cge_idx13_7_0 0xA29A
1778#define reg_cge_idx13_7_0_pos 0
1779#define reg_cge_idx13_7_0_len 8
1780#define reg_cge_idx13_7_0_lsb 0
1781#define xd_p_reg_cge_idx13_12_8 0xA29B
1782#define reg_cge_idx13_12_8_pos 0
1783#define reg_cge_idx13_12_8_len 5
1784#define reg_cge_idx13_12_8_lsb 8
1785#define xd_p_reg_cge_idx14_7_0 0xA29C
1786#define reg_cge_idx14_7_0_pos 0
1787#define reg_cge_idx14_7_0_len 8
1788#define reg_cge_idx14_7_0_lsb 0
1789#define xd_p_reg_cge_idx14_12_8 0xA29D
1790#define reg_cge_idx14_12_8_pos 0
1791#define reg_cge_idx14_12_8_len 5
1792#define reg_cge_idx14_12_8_lsb 8
1793#define xd_p_reg_cge_idx15_7_0 0xA29E
1794#define reg_cge_idx15_7_0_pos 0
1795#define reg_cge_idx15_7_0_len 8
1796#define reg_cge_idx15_7_0_lsb 0
1797#define xd_p_reg_cge_idx15_12_8 0xA29F
1798#define reg_cge_idx15_12_8_pos 0
1799#define reg_cge_idx15_12_8_len 5
1800#define reg_cge_idx15_12_8_lsb 8
1801#define xd_r_reg_fft_crc 0xA2A8
1802#define reg_fft_crc_pos 0
1803#define reg_fft_crc_len 8
1804#define reg_fft_crc_lsb 0
1805#define xd_p_fd_fft_shift_max 0xA2A9
1806#define fd_fft_shift_max_pos 0
1807#define fd_fft_shift_max_len 4
1808#define fd_fft_shift_max_lsb 0
1809#define xd_r_fd_fft_shift 0xA2A9
1810#define fd_fft_shift_pos 4
1811#define fd_fft_shift_len 4
1812#define fd_fft_shift_lsb 0
1813#define xd_r_fd_fft_frame_num 0xA2AA
1814#define fd_fft_frame_num_pos 0
1815#define fd_fft_frame_num_len 2
1816#define fd_fft_frame_num_lsb 0
1817#define xd_r_fd_fft_symbol_count 0xA2AB
1818#define fd_fft_symbol_count_pos 0
1819#define fd_fft_symbol_count_len 7
1820#define fd_fft_symbol_count_lsb 0
1821#define xd_r_reg_fft_idx_max_7_0 0xA2AC
1822#define reg_fft_idx_max_7_0_pos 0
1823#define reg_fft_idx_max_7_0_len 8
1824#define reg_fft_idx_max_7_0_lsb 0
1825#define xd_r_reg_fft_idx_max_12_8 0xA2AD
1826#define reg_fft_idx_max_12_8_pos 0
1827#define reg_fft_idx_max_12_8_len 5
1828#define reg_fft_idx_max_12_8_lsb 8
1829#define xd_p_reg_cge_program 0xA2AE
1830#define reg_cge_program_pos 0
1831#define reg_cge_program_len 1
1832#define reg_cge_program_lsb 0
1833#define xd_p_reg_cge_fixed 0xA2AE
1834#define reg_cge_fixed_pos 1
1835#define reg_cge_fixed_len 1
1836#define reg_cge_fixed_lsb 0
1837#define xd_p_reg_fft_rotate_en 0xA2AE
1838#define reg_fft_rotate_en_pos 2
1839#define reg_fft_rotate_en_len 1
1840#define reg_fft_rotate_en_lsb 0
1841#define xd_p_reg_fft_rotate_base_4_0 0xA2AE
1842#define reg_fft_rotate_base_4_0_pos 3
1843#define reg_fft_rotate_base_4_0_len 5
1844#define reg_fft_rotate_base_4_0_lsb 0
1845#define xd_p_reg_fft_rotate_base_12_5 0xA2AF
1846#define reg_fft_rotate_base_12_5_pos 0
1847#define reg_fft_rotate_base_12_5_len 8
1848#define reg_fft_rotate_base_12_5_lsb 5
1849#define xd_p_reg_gp_trigger_fd 0xA2B8
1850#define reg_gp_trigger_fd_pos 0
1851#define reg_gp_trigger_fd_len 1
1852#define reg_gp_trigger_fd_lsb 0
1853#define xd_p_reg_trigger_sel_fd 0xA2B8
1854#define reg_trigger_sel_fd_pos 1
1855#define reg_trigger_sel_fd_len 2
1856#define reg_trigger_sel_fd_lsb 0
1857#define xd_p_reg_trigger_module_sel_fd 0xA2B9
1858#define reg_trigger_module_sel_fd_pos 0
1859#define reg_trigger_module_sel_fd_len 6
1860#define reg_trigger_module_sel_fd_lsb 0
1861#define xd_p_reg_trigger_set_sel_fd 0xA2BA
1862#define reg_trigger_set_sel_fd_pos 0
1863#define reg_trigger_set_sel_fd_len 6
1864#define reg_trigger_set_sel_fd_lsb 0
1865#define xd_p_reg_fd_noname_7_0 0xA2BC
1866#define reg_fd_noname_7_0_pos 0
1867#define reg_fd_noname_7_0_len 8
1868#define reg_fd_noname_7_0_lsb 0
1869#define xd_p_reg_fd_noname_15_8 0xA2BD
1870#define reg_fd_noname_15_8_pos 0
1871#define reg_fd_noname_15_8_len 8
1872#define reg_fd_noname_15_8_lsb 8
1873#define xd_p_reg_fd_noname_23_16 0xA2BE
1874#define reg_fd_noname_23_16_pos 0
1875#define reg_fd_noname_23_16_len 8
1876#define reg_fd_noname_23_16_lsb 16
1877#define xd_p_reg_fd_noname_31_24 0xA2BF
1878#define reg_fd_noname_31_24_pos 0
1879#define reg_fd_noname_31_24_len 8
1880#define reg_fd_noname_31_24_lsb 24
1881#define xd_r_fd_fpcc_cp_corr_signn 0xA2C0
1882#define fd_fpcc_cp_corr_signn_pos 0
1883#define fd_fpcc_cp_corr_signn_len 8
1884#define fd_fpcc_cp_corr_signn_lsb 0
1885#define xd_p_reg_feq_s1 0xA2C1
1886#define reg_feq_s1_pos 0
1887#define reg_feq_s1_len 5
1888#define reg_feq_s1_lsb 0
1889#define xd_p_fd_fpcc_cp_corr_tone_th 0xA2C2
1890#define fd_fpcc_cp_corr_tone_th_pos 0
1891#define fd_fpcc_cp_corr_tone_th_len 6
1892#define fd_fpcc_cp_corr_tone_th_lsb 0
1893#define xd_p_fd_fpcc_cp_corr_symbol_log_th 0xA2C3
1894#define fd_fpcc_cp_corr_symbol_log_th_pos 0
1895#define fd_fpcc_cp_corr_symbol_log_th_len 4
1896#define fd_fpcc_cp_corr_symbol_log_th_lsb 0
1897#define xd_p_fd_fpcc_cp_corr_int 0xA2C4
1898#define fd_fpcc_cp_corr_int_pos 0
1899#define fd_fpcc_cp_corr_int_len 1
1900#define fd_fpcc_cp_corr_int_lsb 0
1901#define xd_p_reg_sfoe_ns_7_0 0xA320
1902#define reg_sfoe_ns_7_0_pos 0
1903#define reg_sfoe_ns_7_0_len 8
1904#define reg_sfoe_ns_7_0_lsb 0
1905#define xd_p_reg_sfoe_ns_14_8 0xA321
1906#define reg_sfoe_ns_14_8_pos 0
1907#define reg_sfoe_ns_14_8_len 7
1908#define reg_sfoe_ns_14_8_lsb 8
1909#define xd_p_reg_sfoe_c1_7_0 0xA322
1910#define reg_sfoe_c1_7_0_pos 0
1911#define reg_sfoe_c1_7_0_len 8
1912#define reg_sfoe_c1_7_0_lsb 0
1913#define xd_p_reg_sfoe_c1_15_8 0xA323
1914#define reg_sfoe_c1_15_8_pos 0
1915#define reg_sfoe_c1_15_8_len 8
1916#define reg_sfoe_c1_15_8_lsb 8
1917#define xd_p_reg_sfoe_c1_17_16 0xA324
1918#define reg_sfoe_c1_17_16_pos 0
1919#define reg_sfoe_c1_17_16_len 2
1920#define reg_sfoe_c1_17_16_lsb 16
1921#define xd_p_reg_sfoe_c2_7_0 0xA325
1922#define reg_sfoe_c2_7_0_pos 0
1923#define reg_sfoe_c2_7_0_len 8
1924#define reg_sfoe_c2_7_0_lsb 0
1925#define xd_p_reg_sfoe_c2_15_8 0xA326
1926#define reg_sfoe_c2_15_8_pos 0
1927#define reg_sfoe_c2_15_8_len 8
1928#define reg_sfoe_c2_15_8_lsb 8
1929#define xd_p_reg_sfoe_c2_17_16 0xA327
1930#define reg_sfoe_c2_17_16_pos 0
1931#define reg_sfoe_c2_17_16_len 2
1932#define reg_sfoe_c2_17_16_lsb 16
1933#define xd_r_reg_sfoe_out_9_2 0xA328
1934#define reg_sfoe_out_9_2_pos 0
1935#define reg_sfoe_out_9_2_len 8
1936#define reg_sfoe_out_9_2_lsb 0
1937#define xd_r_reg_sfoe_out_1_0 0xA329
1938#define reg_sfoe_out_1_0_pos 0
1939#define reg_sfoe_out_1_0_len 2
1940#define reg_sfoe_out_1_0_lsb 0
1941#define xd_p_reg_sfoe_lm_counter_th 0xA32A
1942#define reg_sfoe_lm_counter_th_pos 0
1943#define reg_sfoe_lm_counter_th_len 4
1944#define reg_sfoe_lm_counter_th_lsb 0
1945#define xd_p_reg_sfoe_convg_th 0xA32B
1946#define reg_sfoe_convg_th_pos 0
1947#define reg_sfoe_convg_th_len 8
1948#define reg_sfoe_convg_th_lsb 0
1949#define xd_p_reg_sfoe_divg_th 0xA32C
1950#define reg_sfoe_divg_th_pos 0
1951#define reg_sfoe_divg_th_len 8
1952#define reg_sfoe_divg_th_lsb 0
1953#define xd_p_fd_tpsd_en 0xA330
1954#define fd_tpsd_en_pos 0
1955#define fd_tpsd_en_len 1
1956#define fd_tpsd_en_lsb 0
1957#define xd_p_fd_tpsd_dis 0xA330
1958#define fd_tpsd_dis_pos 1
1959#define fd_tpsd_dis_len 1
1960#define fd_tpsd_dis_lsb 0
1961#define xd_p_fd_tpsd_rst 0xA330
1962#define fd_tpsd_rst_pos 2
1963#define fd_tpsd_rst_len 1
1964#define fd_tpsd_rst_lsb 0
1965#define xd_p_fd_tpsd_lock 0xA330
1966#define fd_tpsd_lock_pos 3
1967#define fd_tpsd_lock_len 1
1968#define fd_tpsd_lock_lsb 0
1969#define xd_r_fd_tpsd_s19 0xA330
1970#define fd_tpsd_s19_pos 4
1971#define fd_tpsd_s19_len 1
1972#define fd_tpsd_s19_lsb 0
1973#define xd_r_fd_tpsd_s17 0xA330
1974#define fd_tpsd_s17_pos 5
1975#define fd_tpsd_s17_len 1
1976#define fd_tpsd_s17_lsb 0
1977#define xd_p_fd_sfr_ste_en 0xA331
1978#define fd_sfr_ste_en_pos 0
1979#define fd_sfr_ste_en_len 1
1980#define fd_sfr_ste_en_lsb 0
1981#define xd_p_fd_sfr_ste_dis 0xA331
1982#define fd_sfr_ste_dis_pos 1
1983#define fd_sfr_ste_dis_len 1
1984#define fd_sfr_ste_dis_lsb 0
1985#define xd_p_fd_sfr_ste_rst 0xA331
1986#define fd_sfr_ste_rst_pos 2
1987#define fd_sfr_ste_rst_len 1
1988#define fd_sfr_ste_rst_lsb 0
1989#define xd_p_fd_sfr_ste_mode 0xA331
1990#define fd_sfr_ste_mode_pos 3
1991#define fd_sfr_ste_mode_len 1
1992#define fd_sfr_ste_mode_lsb 0
1993#define xd_p_fd_sfr_ste_done 0xA331
1994#define fd_sfr_ste_done_pos 4
1995#define fd_sfr_ste_done_len 1
1996#define fd_sfr_ste_done_lsb 0
1997#define xd_p_reg_cfoe_ffoe_en 0xA332
1998#define reg_cfoe_ffoe_en_pos 0
1999#define reg_cfoe_ffoe_en_len 1
2000#define reg_cfoe_ffoe_en_lsb 0
2001#define xd_p_reg_cfoe_ffoe_dis 0xA332
2002#define reg_cfoe_ffoe_dis_pos 1
2003#define reg_cfoe_ffoe_dis_len 1
2004#define reg_cfoe_ffoe_dis_lsb 0
2005#define xd_p_reg_cfoe_ffoe_rst 0xA332
2006#define reg_cfoe_ffoe_rst_pos 2
2007#define reg_cfoe_ffoe_rst_len 1
2008#define reg_cfoe_ffoe_rst_lsb 0
2009#define xd_p_reg_cfoe_ifoe_en 0xA332
2010#define reg_cfoe_ifoe_en_pos 3
2011#define reg_cfoe_ifoe_en_len 1
2012#define reg_cfoe_ifoe_en_lsb 0
2013#define xd_p_reg_cfoe_ifoe_dis 0xA332
2014#define reg_cfoe_ifoe_dis_pos 4
2015#define reg_cfoe_ifoe_dis_len 1
2016#define reg_cfoe_ifoe_dis_lsb 0
2017#define xd_p_reg_cfoe_ifoe_rst 0xA332
2018#define reg_cfoe_ifoe_rst_pos 5
2019#define reg_cfoe_ifoe_rst_len 1
2020#define reg_cfoe_ifoe_rst_lsb 0
2021#define xd_p_reg_cfoe_fot_en 0xA332
2022#define reg_cfoe_fot_en_pos 6
2023#define reg_cfoe_fot_en_len 1
2024#define reg_cfoe_fot_en_lsb 0
2025#define xd_p_reg_cfoe_fot_lm_en 0xA332
2026#define reg_cfoe_fot_lm_en_pos 7
2027#define reg_cfoe_fot_lm_en_len 1
2028#define reg_cfoe_fot_lm_en_lsb 0
2029#define xd_p_reg_cfoe_fot_rst 0xA333
2030#define reg_cfoe_fot_rst_pos 0
2031#define reg_cfoe_fot_rst_len 1
2032#define reg_cfoe_fot_rst_lsb 0
2033#define xd_r_fd_cfoe_ffoe_done 0xA333
2034#define fd_cfoe_ffoe_done_pos 1
2035#define fd_cfoe_ffoe_done_len 1
2036#define fd_cfoe_ffoe_done_lsb 0
2037#define xd_p_fd_cfoe_metric_vld 0xA333
2038#define fd_cfoe_metric_vld_pos 2
2039#define fd_cfoe_metric_vld_len 1
2040#define fd_cfoe_metric_vld_lsb 0
2041#define xd_p_reg_cfoe_ifod_vld 0xA333
2042#define reg_cfoe_ifod_vld_pos 3
2043#define reg_cfoe_ifod_vld_len 1
2044#define reg_cfoe_ifod_vld_lsb 0
2045#define xd_r_fd_cfoe_ifoe_done 0xA333
2046#define fd_cfoe_ifoe_done_pos 4
2047#define fd_cfoe_ifoe_done_len 1
2048#define fd_cfoe_ifoe_done_lsb 0
2049#define xd_r_fd_cfoe_fot_valid 0xA333
2050#define fd_cfoe_fot_valid_pos 5
2051#define fd_cfoe_fot_valid_len 1
2052#define fd_cfoe_fot_valid_lsb 0
2053#define xd_p_reg_cfoe_divg_int 0xA333
2054#define reg_cfoe_divg_int_pos 6
2055#define reg_cfoe_divg_int_len 1
2056#define reg_cfoe_divg_int_lsb 0
2057#define xd_r_reg_cfoe_divg_flag 0xA333
2058#define reg_cfoe_divg_flag_pos 7
2059#define reg_cfoe_divg_flag_len 1
2060#define reg_cfoe_divg_flag_lsb 0
2061#define xd_p_reg_sfoe_en 0xA334
2062#define reg_sfoe_en_pos 0
2063#define reg_sfoe_en_len 1
2064#define reg_sfoe_en_lsb 0
2065#define xd_p_reg_sfoe_dis 0xA334
2066#define reg_sfoe_dis_pos 1
2067#define reg_sfoe_dis_len 1
2068#define reg_sfoe_dis_lsb 0
2069#define xd_p_reg_sfoe_rst 0xA334
2070#define reg_sfoe_rst_pos 2
2071#define reg_sfoe_rst_len 1
2072#define reg_sfoe_rst_lsb 0
2073#define xd_p_reg_sfoe_vld_int 0xA334
2074#define reg_sfoe_vld_int_pos 3
2075#define reg_sfoe_vld_int_len 1
2076#define reg_sfoe_vld_int_lsb 0
2077#define xd_p_reg_sfoe_lm_en 0xA334
2078#define reg_sfoe_lm_en_pos 4
2079#define reg_sfoe_lm_en_len 1
2080#define reg_sfoe_lm_en_lsb 0
2081#define xd_p_reg_sfoe_divg_int 0xA334
2082#define reg_sfoe_divg_int_pos 5
2083#define reg_sfoe_divg_int_len 1
2084#define reg_sfoe_divg_int_lsb 0
2085#define xd_r_reg_sfoe_divg_flag 0xA334
2086#define reg_sfoe_divg_flag_pos 6
2087#define reg_sfoe_divg_flag_len 1
2088#define reg_sfoe_divg_flag_lsb 0
2089#define xd_p_reg_fft_rst 0xA335
2090#define reg_fft_rst_pos 0
2091#define reg_fft_rst_len 1
2092#define reg_fft_rst_lsb 0
2093#define xd_p_reg_fft_fast_beacon 0xA335
2094#define reg_fft_fast_beacon_pos 1
2095#define reg_fft_fast_beacon_len 1
2096#define reg_fft_fast_beacon_lsb 0
2097#define xd_p_reg_fft_fast_valid 0xA335
2098#define reg_fft_fast_valid_pos 2
2099#define reg_fft_fast_valid_len 1
2100#define reg_fft_fast_valid_lsb 0
2101#define xd_p_reg_fft_mask_en 0xA335
2102#define reg_fft_mask_en_pos 3
2103#define reg_fft_mask_en_len 1
2104#define reg_fft_mask_en_lsb 0
2105#define xd_p_reg_fft_crc_en 0xA335
2106#define reg_fft_crc_en_pos 4
2107#define reg_fft_crc_en_len 1
2108#define reg_fft_crc_en_lsb 0
2109#define xd_p_reg_finr_en 0xA336
2110#define reg_finr_en_pos 0
2111#define reg_finr_en_len 1
2112#define reg_finr_en_lsb 0
2113#define xd_p_fd_fste_en 0xA337
2114#define fd_fste_en_pos 1
2115#define fd_fste_en_len 1
2116#define fd_fste_en_lsb 0
2117#define xd_p_fd_sqi_tps_level_shift 0xA338
2118#define fd_sqi_tps_level_shift_pos 0
2119#define fd_sqi_tps_level_shift_len 8
2120#define fd_sqi_tps_level_shift_lsb 0
2121#define xd_p_fd_pilot_ma_len 0xA339
2122#define fd_pilot_ma_len_pos 0
2123#define fd_pilot_ma_len_len 6
2124#define fd_pilot_ma_len_lsb 0
2125#define xd_p_fd_tps_ma_len 0xA33A
2126#define fd_tps_ma_len_pos 0
2127#define fd_tps_ma_len_len 6
2128#define fd_tps_ma_len_lsb 0
2129#define xd_p_fd_sqi_s3 0xA33B
2130#define fd_sqi_s3_pos 0
2131#define fd_sqi_s3_len 8
2132#define fd_sqi_s3_lsb 0
2133#define xd_p_fd_sqi_dummy_reg_0 0xA33C
2134#define fd_sqi_dummy_reg_0_pos 0
2135#define fd_sqi_dummy_reg_0_len 1
2136#define fd_sqi_dummy_reg_0_lsb 0
2137#define xd_p_fd_sqi_debug_sel 0xA33C
2138#define fd_sqi_debug_sel_pos 1
2139#define fd_sqi_debug_sel_len 2
2140#define fd_sqi_debug_sel_lsb 0
2141#define xd_p_fd_sqi_s2 0xA33C
2142#define fd_sqi_s2_pos 3
2143#define fd_sqi_s2_len 5
2144#define fd_sqi_s2_lsb 0
2145#define xd_p_fd_sqi_dummy_reg_1 0xA33D
2146#define fd_sqi_dummy_reg_1_pos 0
2147#define fd_sqi_dummy_reg_1_len 1
2148#define fd_sqi_dummy_reg_1_lsb 0
2149#define xd_p_fd_inr_ignore 0xA33D
2150#define fd_inr_ignore_pos 1
2151#define fd_inr_ignore_len 1
2152#define fd_inr_ignore_lsb 0
2153#define xd_p_fd_pilot_ignore 0xA33D
2154#define fd_pilot_ignore_pos 2
2155#define fd_pilot_ignore_len 1
2156#define fd_pilot_ignore_lsb 0
2157#define xd_p_fd_etps_ignore 0xA33D
2158#define fd_etps_ignore_pos 3
2159#define fd_etps_ignore_len 1
2160#define fd_etps_ignore_lsb 0
2161#define xd_p_fd_sqi_s1 0xA33D
2162#define fd_sqi_s1_pos 4
2163#define fd_sqi_s1_len 4
2164#define fd_sqi_s1_lsb 0
2165#define xd_p_reg_fste_ehw_7_0 0xA33E
2166#define reg_fste_ehw_7_0_pos 0
2167#define reg_fste_ehw_7_0_len 8
2168#define reg_fste_ehw_7_0_lsb 0
2169#define xd_p_reg_fste_ehw_9_8 0xA33F
2170#define reg_fste_ehw_9_8_pos 0
2171#define reg_fste_ehw_9_8_len 2
2172#define reg_fste_ehw_9_8_lsb 8
2173#define xd_p_reg_fste_i_adj_vld 0xA33F
2174#define reg_fste_i_adj_vld_pos 2
2175#define reg_fste_i_adj_vld_len 1
2176#define reg_fste_i_adj_vld_lsb 0
2177#define xd_p_reg_fste_phase_ini_7_0 0xA340
2178#define reg_fste_phase_ini_7_0_pos 0
2179#define reg_fste_phase_ini_7_0_len 8
2180#define reg_fste_phase_ini_7_0_lsb 0
2181#define xd_p_reg_fste_phase_ini_11_8 0xA341
2182#define reg_fste_phase_ini_11_8_pos 0
2183#define reg_fste_phase_ini_11_8_len 4
2184#define reg_fste_phase_ini_11_8_lsb 8
2185#define xd_p_reg_fste_phase_inc_3_0 0xA341
2186#define reg_fste_phase_inc_3_0_pos 4
2187#define reg_fste_phase_inc_3_0_len 4
2188#define reg_fste_phase_inc_3_0_lsb 0
2189#define xd_p_reg_fste_phase_inc_11_4 0xA342
2190#define reg_fste_phase_inc_11_4_pos 0
2191#define reg_fste_phase_inc_11_4_len 8
2192#define reg_fste_phase_inc_11_4_lsb 4
2193#define xd_p_reg_fste_acum_cost_cnt_max 0xA343
2194#define reg_fste_acum_cost_cnt_max_pos 0
2195#define reg_fste_acum_cost_cnt_max_len 4
2196#define reg_fste_acum_cost_cnt_max_lsb 0
2197#define xd_p_reg_fste_step_size_std 0xA343
2198#define reg_fste_step_size_std_pos 4
2199#define reg_fste_step_size_std_len 4
2200#define reg_fste_step_size_std_lsb 0
2201#define xd_p_reg_fste_step_size_max 0xA344
2202#define reg_fste_step_size_max_pos 0
2203#define reg_fste_step_size_max_len 4
2204#define reg_fste_step_size_max_lsb 0
2205#define xd_p_reg_fste_step_size_min 0xA344
2206#define reg_fste_step_size_min_pos 4
2207#define reg_fste_step_size_min_len 4
2208#define reg_fste_step_size_min_lsb 0
2209#define xd_p_reg_fste_frac_step_size_7_0 0xA345
2210#define reg_fste_frac_step_size_7_0_pos 0
2211#define reg_fste_frac_step_size_7_0_len 8
2212#define reg_fste_frac_step_size_7_0_lsb 0
2213#define xd_p_reg_fste_frac_step_size_15_8 0xA346
2214#define reg_fste_frac_step_size_15_8_pos 0
2215#define reg_fste_frac_step_size_15_8_len 8
2216#define reg_fste_frac_step_size_15_8_lsb 8
2217#define xd_p_reg_fste_frac_step_size_19_16 0xA347
2218#define reg_fste_frac_step_size_19_16_pos 0
2219#define reg_fste_frac_step_size_19_16_len 4
2220#define reg_fste_frac_step_size_19_16_lsb 16
2221#define xd_p_reg_fste_rpd_dir_cnt_max 0xA347
2222#define reg_fste_rpd_dir_cnt_max_pos 4
2223#define reg_fste_rpd_dir_cnt_max_len 4
2224#define reg_fste_rpd_dir_cnt_max_lsb 0
2225#define xd_p_reg_fste_ehs 0xA348
2226#define reg_fste_ehs_pos 0
2227#define reg_fste_ehs_len 4
2228#define reg_fste_ehs_lsb 0
2229#define xd_p_reg_fste_frac_cost_cnt_max_3_0 0xA348
2230#define reg_fste_frac_cost_cnt_max_3_0_pos 4
2231#define reg_fste_frac_cost_cnt_max_3_0_len 4
2232#define reg_fste_frac_cost_cnt_max_3_0_lsb 0
2233#define xd_p_reg_fste_frac_cost_cnt_max_9_4 0xA349
2234#define reg_fste_frac_cost_cnt_max_9_4_pos 0
2235#define reg_fste_frac_cost_cnt_max_9_4_len 6
2236#define reg_fste_frac_cost_cnt_max_9_4_lsb 4
2237#define xd_p_reg_fste_w0_7_0 0xA34A
2238#define reg_fste_w0_7_0_pos 0
2239#define reg_fste_w0_7_0_len 8
2240#define reg_fste_w0_7_0_lsb 0
2241#define xd_p_reg_fste_w0_11_8 0xA34B
2242#define reg_fste_w0_11_8_pos 0
2243#define reg_fste_w0_11_8_len 4
2244#define reg_fste_w0_11_8_lsb 8
2245#define xd_p_reg_fste_w1_3_0 0xA34B
2246#define reg_fste_w1_3_0_pos 4
2247#define reg_fste_w1_3_0_len 4
2248#define reg_fste_w1_3_0_lsb 0
2249#define xd_p_reg_fste_w1_11_4 0xA34C
2250#define reg_fste_w1_11_4_pos 0
2251#define reg_fste_w1_11_4_len 8
2252#define reg_fste_w1_11_4_lsb 4
2253#define xd_p_reg_fste_w2_7_0 0xA34D
2254#define reg_fste_w2_7_0_pos 0
2255#define reg_fste_w2_7_0_len 8
2256#define reg_fste_w2_7_0_lsb 0
2257#define xd_p_reg_fste_w2_11_8 0xA34E
2258#define reg_fste_w2_11_8_pos 0
2259#define reg_fste_w2_11_8_len 4
2260#define reg_fste_w2_11_8_lsb 8
2261#define xd_p_reg_fste_w3_3_0 0xA34E
2262#define reg_fste_w3_3_0_pos 4
2263#define reg_fste_w3_3_0_len 4
2264#define reg_fste_w3_3_0_lsb 0
2265#define xd_p_reg_fste_w3_11_4 0xA34F
2266#define reg_fste_w3_11_4_pos 0
2267#define reg_fste_w3_11_4_len 8
2268#define reg_fste_w3_11_4_lsb 4
2269#define xd_p_reg_fste_w4_7_0 0xA350
2270#define reg_fste_w4_7_0_pos 0
2271#define reg_fste_w4_7_0_len 8
2272#define reg_fste_w4_7_0_lsb 0
2273#define xd_p_reg_fste_w4_11_8 0xA351
2274#define reg_fste_w4_11_8_pos 0
2275#define reg_fste_w4_11_8_len 4
2276#define reg_fste_w4_11_8_lsb 8
2277#define xd_p_reg_fste_w5_3_0 0xA351
2278#define reg_fste_w5_3_0_pos 4
2279#define reg_fste_w5_3_0_len 4
2280#define reg_fste_w5_3_0_lsb 0
2281#define xd_p_reg_fste_w5_11_4 0xA352
2282#define reg_fste_w5_11_4_pos 0
2283#define reg_fste_w5_11_4_len 8
2284#define reg_fste_w5_11_4_lsb 4
2285#define xd_p_reg_fste_w6_7_0 0xA353
2286#define reg_fste_w6_7_0_pos 0
2287#define reg_fste_w6_7_0_len 8
2288#define reg_fste_w6_7_0_lsb 0
2289#define xd_p_reg_fste_w6_11_8 0xA354
2290#define reg_fste_w6_11_8_pos 0
2291#define reg_fste_w6_11_8_len 4
2292#define reg_fste_w6_11_8_lsb 8
2293#define xd_p_reg_fste_w7_3_0 0xA354
2294#define reg_fste_w7_3_0_pos 4
2295#define reg_fste_w7_3_0_len 4
2296#define reg_fste_w7_3_0_lsb 0
2297#define xd_p_reg_fste_w7_11_4 0xA355
2298#define reg_fste_w7_11_4_pos 0
2299#define reg_fste_w7_11_4_len 8
2300#define reg_fste_w7_11_4_lsb 4
2301#define xd_p_reg_fste_w8_7_0 0xA356
2302#define reg_fste_w8_7_0_pos 0
2303#define reg_fste_w8_7_0_len 8
2304#define reg_fste_w8_7_0_lsb 0
2305#define xd_p_reg_fste_w8_11_8 0xA357
2306#define reg_fste_w8_11_8_pos 0
2307#define reg_fste_w8_11_8_len 4
2308#define reg_fste_w8_11_8_lsb 8
2309#define xd_p_reg_fste_w9_3_0 0xA357
2310#define reg_fste_w9_3_0_pos 4
2311#define reg_fste_w9_3_0_len 4
2312#define reg_fste_w9_3_0_lsb 0
2313#define xd_p_reg_fste_w9_11_4 0xA358
2314#define reg_fste_w9_11_4_pos 0
2315#define reg_fste_w9_11_4_len 8
2316#define reg_fste_w9_11_4_lsb 4
2317#define xd_p_reg_fste_wa_7_0 0xA359
2318#define reg_fste_wa_7_0_pos 0
2319#define reg_fste_wa_7_0_len 8
2320#define reg_fste_wa_7_0_lsb 0
2321#define xd_p_reg_fste_wa_11_8 0xA35A
2322#define reg_fste_wa_11_8_pos 0
2323#define reg_fste_wa_11_8_len 4
2324#define reg_fste_wa_11_8_lsb 8
2325#define xd_p_reg_fste_wb_3_0 0xA35A
2326#define reg_fste_wb_3_0_pos 4
2327#define reg_fste_wb_3_0_len 4
2328#define reg_fste_wb_3_0_lsb 0
2329#define xd_p_reg_fste_wb_11_4 0xA35B
2330#define reg_fste_wb_11_4_pos 0
2331#define reg_fste_wb_11_4_len 8
2332#define reg_fste_wb_11_4_lsb 4
2333#define xd_r_fd_fste_i_adj 0xA35C
2334#define fd_fste_i_adj_pos 0
2335#define fd_fste_i_adj_len 5
2336#define fd_fste_i_adj_lsb 0
2337#define xd_r_fd_fste_f_adj_7_0 0xA35D
2338#define fd_fste_f_adj_7_0_pos 0
2339#define fd_fste_f_adj_7_0_len 8
2340#define fd_fste_f_adj_7_0_lsb 0
2341#define xd_r_fd_fste_f_adj_15_8 0xA35E
2342#define fd_fste_f_adj_15_8_pos 0
2343#define fd_fste_f_adj_15_8_len 8
2344#define fd_fste_f_adj_15_8_lsb 8
2345#define xd_r_fd_fste_f_adj_19_16 0xA35F
2346#define fd_fste_f_adj_19_16_pos 0
2347#define fd_fste_f_adj_19_16_len 4
2348#define fd_fste_f_adj_19_16_lsb 16
2349#define xd_p_reg_feq_Leak_Bypass 0xA366
2350#define reg_feq_Leak_Bypass_pos 0
2351#define reg_feq_Leak_Bypass_len 1
2352#define reg_feq_Leak_Bypass_lsb 0
2353#define xd_p_reg_feq_Leak_Mneg1 0xA366
2354#define reg_feq_Leak_Mneg1_pos 1
2355#define reg_feq_Leak_Mneg1_len 3
2356#define reg_feq_Leak_Mneg1_lsb 0
2357#define xd_p_reg_feq_Leak_B_ShiftQ 0xA366
2358#define reg_feq_Leak_B_ShiftQ_pos 4
2359#define reg_feq_Leak_B_ShiftQ_len 4
2360#define reg_feq_Leak_B_ShiftQ_lsb 0
2361#define xd_p_reg_feq_Leak_B_Float0 0xA367
2362#define reg_feq_Leak_B_Float0_pos 0
2363#define reg_feq_Leak_B_Float0_len 8
2364#define reg_feq_Leak_B_Float0_lsb 0
2365#define xd_p_reg_feq_Leak_B_Float1 0xA368
2366#define reg_feq_Leak_B_Float1_pos 0
2367#define reg_feq_Leak_B_Float1_len 8
2368#define reg_feq_Leak_B_Float1_lsb 0
2369#define xd_p_reg_feq_Leak_B_Float2 0xA369
2370#define reg_feq_Leak_B_Float2_pos 0
2371#define reg_feq_Leak_B_Float2_len 8
2372#define reg_feq_Leak_B_Float2_lsb 0
2373#define xd_p_reg_feq_Leak_B_Float3 0xA36A
2374#define reg_feq_Leak_B_Float3_pos 0
2375#define reg_feq_Leak_B_Float3_len 8
2376#define reg_feq_Leak_B_Float3_lsb 0
2377#define xd_p_reg_feq_Leak_B_Float4 0xA36B
2378#define reg_feq_Leak_B_Float4_pos 0
2379#define reg_feq_Leak_B_Float4_len 8
2380#define reg_feq_Leak_B_Float4_lsb 0
2381#define xd_p_reg_feq_Leak_B_Float5 0xA36C
2382#define reg_feq_Leak_B_Float5_pos 0
2383#define reg_feq_Leak_B_Float5_len 8
2384#define reg_feq_Leak_B_Float5_lsb 0
2385#define xd_p_reg_feq_Leak_B_Float6 0xA36D
2386#define reg_feq_Leak_B_Float6_pos 0
2387#define reg_feq_Leak_B_Float6_len 8
2388#define reg_feq_Leak_B_Float6_lsb 0
2389#define xd_p_reg_feq_Leak_B_Float7 0xA36E
2390#define reg_feq_Leak_B_Float7_pos 0
2391#define reg_feq_Leak_B_Float7_len 8
2392#define reg_feq_Leak_B_Float7_lsb 0
2393#define xd_r_reg_feq_data_h2_7_0 0xA36F
2394#define reg_feq_data_h2_7_0_pos 0
2395#define reg_feq_data_h2_7_0_len 8
2396#define reg_feq_data_h2_7_0_lsb 0
2397#define xd_r_reg_feq_data_h2_9_8 0xA370
2398#define reg_feq_data_h2_9_8_pos 0
2399#define reg_feq_data_h2_9_8_len 2
2400#define reg_feq_data_h2_9_8_lsb 8
2401#define xd_p_reg_feq_leak_use_slice_tps 0xA371
2402#define reg_feq_leak_use_slice_tps_pos 0
2403#define reg_feq_leak_use_slice_tps_len 1
2404#define reg_feq_leak_use_slice_tps_lsb 0
2405#define xd_p_reg_feq_read_update 0xA371
2406#define reg_feq_read_update_pos 1
2407#define reg_feq_read_update_len 1
2408#define reg_feq_read_update_lsb 0
2409#define xd_p_reg_feq_data_vld 0xA371
2410#define reg_feq_data_vld_pos 2
2411#define reg_feq_data_vld_len 1
2412#define reg_feq_data_vld_lsb 0
2413#define xd_p_reg_feq_tone_idx_4_0 0xA371
2414#define reg_feq_tone_idx_4_0_pos 3
2415#define reg_feq_tone_idx_4_0_len 5
2416#define reg_feq_tone_idx_4_0_lsb 0
2417#define xd_p_reg_feq_tone_idx_12_5 0xA372
2418#define reg_feq_tone_idx_12_5_pos 0
2419#define reg_feq_tone_idx_12_5_len 8
2420#define reg_feq_tone_idx_12_5_lsb 5
2421#define xd_r_reg_feq_data_re_7_0 0xA373
2422#define reg_feq_data_re_7_0_pos 0
2423#define reg_feq_data_re_7_0_len 8
2424#define reg_feq_data_re_7_0_lsb 0
2425#define xd_r_reg_feq_data_re_10_8 0xA374
2426#define reg_feq_data_re_10_8_pos 0
2427#define reg_feq_data_re_10_8_len 3
2428#define reg_feq_data_re_10_8_lsb 8
2429#define xd_r_reg_feq_data_im_7_0 0xA375
2430#define reg_feq_data_im_7_0_pos 0
2431#define reg_feq_data_im_7_0_len 8
2432#define reg_feq_data_im_7_0_lsb 0
2433#define xd_r_reg_feq_data_im_10_8 0xA376
2434#define reg_feq_data_im_10_8_pos 0
2435#define reg_feq_data_im_10_8_len 3
2436#define reg_feq_data_im_10_8_lsb 8
2437#define xd_r_reg_feq_y_re 0xA377
2438#define reg_feq_y_re_pos 0
2439#define reg_feq_y_re_len 8
2440#define reg_feq_y_re_lsb 0
2441#define xd_r_reg_feq_y_im 0xA378
2442#define reg_feq_y_im_pos 0
2443#define reg_feq_y_im_len 8
2444#define reg_feq_y_im_lsb 0
2445#define xd_r_reg_feq_h_re_7_0 0xA379
2446#define reg_feq_h_re_7_0_pos 0
2447#define reg_feq_h_re_7_0_len 8
2448#define reg_feq_h_re_7_0_lsb 0
2449#define xd_r_reg_feq_h_re_8 0xA37A
2450#define reg_feq_h_re_8_pos 0
2451#define reg_feq_h_re_8_len 1
2452#define reg_feq_h_re_8_lsb 0
2453#define xd_r_reg_feq_h_im_7_0 0xA37B
2454#define reg_feq_h_im_7_0_pos 0
2455#define reg_feq_h_im_7_0_len 8
2456#define reg_feq_h_im_7_0_lsb 0
2457#define xd_r_reg_feq_h_im_8 0xA37C
2458#define reg_feq_h_im_8_pos 0
2459#define reg_feq_h_im_8_len 1
2460#define reg_feq_h_im_8_lsb 0
2461#define xd_p_fec_super_frm_unit_7_0 0xA380
2462#define fec_super_frm_unit_7_0_pos 0
2463#define fec_super_frm_unit_7_0_len 8
2464#define fec_super_frm_unit_7_0_lsb 0
2465#define xd_p_fec_super_frm_unit_15_8 0xA381
2466#define fec_super_frm_unit_15_8_pos 0
2467#define fec_super_frm_unit_15_8_len 8
2468#define fec_super_frm_unit_15_8_lsb 8
2469#define xd_r_fec_vtb_err_bit_cnt_7_0 0xA382
2470#define fec_vtb_err_bit_cnt_7_0_pos 0
2471#define fec_vtb_err_bit_cnt_7_0_len 8
2472#define fec_vtb_err_bit_cnt_7_0_lsb 0
2473#define xd_r_fec_vtb_err_bit_cnt_15_8 0xA383
2474#define fec_vtb_err_bit_cnt_15_8_pos 0
2475#define fec_vtb_err_bit_cnt_15_8_len 8
2476#define fec_vtb_err_bit_cnt_15_8_lsb 8
2477#define xd_r_fec_vtb_err_bit_cnt_23_16 0xA384
2478#define fec_vtb_err_bit_cnt_23_16_pos 0
2479#define fec_vtb_err_bit_cnt_23_16_len 8
2480#define fec_vtb_err_bit_cnt_23_16_lsb 16
2481#define xd_p_fec_rsd_packet_unit_7_0 0xA385
2482#define fec_rsd_packet_unit_7_0_pos 0
2483#define fec_rsd_packet_unit_7_0_len 8
2484#define fec_rsd_packet_unit_7_0_lsb 0
2485#define xd_p_fec_rsd_packet_unit_15_8 0xA386
2486#define fec_rsd_packet_unit_15_8_pos 0
2487#define fec_rsd_packet_unit_15_8_len 8
2488#define fec_rsd_packet_unit_15_8_lsb 8
2489#define xd_r_fec_rsd_bit_err_cnt_7_0 0xA387
2490#define fec_rsd_bit_err_cnt_7_0_pos 0
2491#define fec_rsd_bit_err_cnt_7_0_len 8
2492#define fec_rsd_bit_err_cnt_7_0_lsb 0
2493#define xd_r_fec_rsd_bit_err_cnt_15_8 0xA388
2494#define fec_rsd_bit_err_cnt_15_8_pos 0
2495#define fec_rsd_bit_err_cnt_15_8_len 8
2496#define fec_rsd_bit_err_cnt_15_8_lsb 8
2497#define xd_r_fec_rsd_bit_err_cnt_23_16 0xA389
2498#define fec_rsd_bit_err_cnt_23_16_pos 0
2499#define fec_rsd_bit_err_cnt_23_16_len 8
2500#define fec_rsd_bit_err_cnt_23_16_lsb 16
2501#define xd_r_fec_rsd_abort_packet_cnt_7_0 0xA38A
2502#define fec_rsd_abort_packet_cnt_7_0_pos 0
2503#define fec_rsd_abort_packet_cnt_7_0_len 8
2504#define fec_rsd_abort_packet_cnt_7_0_lsb 0
2505#define xd_r_fec_rsd_abort_packet_cnt_15_8 0xA38B
2506#define fec_rsd_abort_packet_cnt_15_8_pos 0
2507#define fec_rsd_abort_packet_cnt_15_8_len 8
2508#define fec_rsd_abort_packet_cnt_15_8_lsb 8
2509#define xd_p_fec_RSD_PKT_NUM_PER_UNIT_7_0 0xA38C
2510#define fec_RSD_PKT_NUM_PER_UNIT_7_0_pos 0
2511#define fec_RSD_PKT_NUM_PER_UNIT_7_0_len 8
2512#define fec_RSD_PKT_NUM_PER_UNIT_7_0_lsb 0
2513#define xd_p_fec_RSD_PKT_NUM_PER_UNIT_15_8 0xA38D
2514#define fec_RSD_PKT_NUM_PER_UNIT_15_8_pos 0
2515#define fec_RSD_PKT_NUM_PER_UNIT_15_8_len 8
2516#define fec_RSD_PKT_NUM_PER_UNIT_15_8_lsb 8
2517#define xd_p_fec_RS_TH_1_7_0 0xA38E
2518#define fec_RS_TH_1_7_0_pos 0
2519#define fec_RS_TH_1_7_0_len 8
2520#define fec_RS_TH_1_7_0_lsb 0
2521#define xd_p_fec_RS_TH_1_15_8 0xA38F
2522#define fec_RS_TH_1_15_8_pos 0
2523#define fec_RS_TH_1_15_8_len 8
2524#define fec_RS_TH_1_15_8_lsb 8
2525#define xd_p_fec_RS_TH_2 0xA390
2526#define fec_RS_TH_2_pos 0
2527#define fec_RS_TH_2_len 8
2528#define fec_RS_TH_2_lsb 0
2529#define xd_p_fec_mon_en 0xA391
2530#define fec_mon_en_pos 0
2531#define fec_mon_en_len 1
2532#define fec_mon_en_lsb 0
2533#define xd_p_reg_b8to47 0xA391
2534#define reg_b8to47_pos 1
2535#define reg_b8to47_len 1
2536#define reg_b8to47_lsb 0
2537#define xd_p_reg_rsd_sync_rep 0xA391
2538#define reg_rsd_sync_rep_pos 2
2539#define reg_rsd_sync_rep_len 1
2540#define reg_rsd_sync_rep_lsb 0
2541#define xd_p_fec_rsd_retrain_rst 0xA391
2542#define fec_rsd_retrain_rst_pos 3
2543#define fec_rsd_retrain_rst_len 1
2544#define fec_rsd_retrain_rst_lsb 0
2545#define xd_r_fec_rsd_ber_rdy 0xA391
2546#define fec_rsd_ber_rdy_pos 4
2547#define fec_rsd_ber_rdy_len 1
2548#define fec_rsd_ber_rdy_lsb 0
2549#define xd_p_fec_rsd_ber_rst 0xA391
2550#define fec_rsd_ber_rst_pos 5
2551#define fec_rsd_ber_rst_len 1
2552#define fec_rsd_ber_rst_lsb 0
2553#define xd_r_fec_vtb_ber_rdy 0xA391
2554#define fec_vtb_ber_rdy_pos 6
2555#define fec_vtb_ber_rdy_len 1
2556#define fec_vtb_ber_rdy_lsb 0
2557#define xd_p_fec_vtb_ber_rst 0xA391
2558#define fec_vtb_ber_rst_pos 7
2559#define fec_vtb_ber_rst_len 1
2560#define fec_vtb_ber_rst_lsb 0
2561#define xd_p_reg_vtb_clk40en 0xA392
2562#define reg_vtb_clk40en_pos 0
2563#define reg_vtb_clk40en_len 1
2564#define reg_vtb_clk40en_lsb 0
2565#define xd_p_fec_vtb_rsd_mon_en 0xA392
2566#define fec_vtb_rsd_mon_en_pos 1
2567#define fec_vtb_rsd_mon_en_len 1
2568#define fec_vtb_rsd_mon_en_lsb 0
2569#define xd_p_reg_fec_data_en 0xA392
2570#define reg_fec_data_en_pos 2
2571#define reg_fec_data_en_len 1
2572#define reg_fec_data_en_lsb 0
2573#define xd_p_fec_dummy_reg_2 0xA392
2574#define fec_dummy_reg_2_pos 3
2575#define fec_dummy_reg_2_len 3
2576#define fec_dummy_reg_2_lsb 0
2577#define xd_p_reg_sync_chk 0xA392
2578#define reg_sync_chk_pos 6
2579#define reg_sync_chk_len 1
2580#define reg_sync_chk_lsb 0
2581#define xd_p_fec_rsd_bypass 0xA392
2582#define fec_rsd_bypass_pos 7
2583#define fec_rsd_bypass_len 1
2584#define fec_rsd_bypass_lsb 0
2585#define xd_p_fec_sw_rst 0xA393
2586#define fec_sw_rst_pos 0
2587#define fec_sw_rst_len 1
2588#define fec_sw_rst_lsb 0
2589#define xd_r_fec_vtb_pm_crc 0xA394
2590#define fec_vtb_pm_crc_pos 0
2591#define fec_vtb_pm_crc_len 8
2592#define fec_vtb_pm_crc_lsb 0
2593#define xd_r_fec_vtb_tb_7_crc 0xA395
2594#define fec_vtb_tb_7_crc_pos 0
2595#define fec_vtb_tb_7_crc_len 8
2596#define fec_vtb_tb_7_crc_lsb 0
2597#define xd_r_fec_vtb_tb_6_crc 0xA396
2598#define fec_vtb_tb_6_crc_pos 0
2599#define fec_vtb_tb_6_crc_len 8
2600#define fec_vtb_tb_6_crc_lsb 0
2601#define xd_r_fec_vtb_tb_5_crc 0xA397
2602#define fec_vtb_tb_5_crc_pos 0
2603#define fec_vtb_tb_5_crc_len 8
2604#define fec_vtb_tb_5_crc_lsb 0
2605#define xd_r_fec_vtb_tb_4_crc 0xA398
2606#define fec_vtb_tb_4_crc_pos 0
2607#define fec_vtb_tb_4_crc_len 8
2608#define fec_vtb_tb_4_crc_lsb 0
2609#define xd_r_fec_vtb_tb_3_crc 0xA399
2610#define fec_vtb_tb_3_crc_pos 0
2611#define fec_vtb_tb_3_crc_len 8
2612#define fec_vtb_tb_3_crc_lsb 0
2613#define xd_r_fec_vtb_tb_2_crc 0xA39A
2614#define fec_vtb_tb_2_crc_pos 0
2615#define fec_vtb_tb_2_crc_len 8
2616#define fec_vtb_tb_2_crc_lsb 0
2617#define xd_r_fec_vtb_tb_1_crc 0xA39B
2618#define fec_vtb_tb_1_crc_pos 0
2619#define fec_vtb_tb_1_crc_len 8
2620#define fec_vtb_tb_1_crc_lsb 0
2621#define xd_r_fec_vtb_tb_0_crc 0xA39C
2622#define fec_vtb_tb_0_crc_pos 0
2623#define fec_vtb_tb_0_crc_len 8
2624#define fec_vtb_tb_0_crc_lsb 0
2625#define xd_r_fec_rsd_bank0_crc 0xA39D
2626#define fec_rsd_bank0_crc_pos 0
2627#define fec_rsd_bank0_crc_len 8
2628#define fec_rsd_bank0_crc_lsb 0
2629#define xd_r_fec_rsd_bank1_crc 0xA39E
2630#define fec_rsd_bank1_crc_pos 0
2631#define fec_rsd_bank1_crc_len 8
2632#define fec_rsd_bank1_crc_lsb 0
2633#define xd_r_fec_idi_vtb_crc 0xA39F
2634#define fec_idi_vtb_crc_pos 0
2635#define fec_idi_vtb_crc_len 8
2636#define fec_idi_vtb_crc_lsb 0
2637#define xd_g_reg_tpsd_txmod 0xA3C0
2638#define reg_tpsd_txmod_pos 0
2639#define reg_tpsd_txmod_len 2
2640#define reg_tpsd_txmod_lsb 0
2641#define xd_g_reg_tpsd_gi 0xA3C0
2642#define reg_tpsd_gi_pos 2
2643#define reg_tpsd_gi_len 2
2644#define reg_tpsd_gi_lsb 0
2645#define xd_g_reg_tpsd_hier 0xA3C0
2646#define reg_tpsd_hier_pos 4
2647#define reg_tpsd_hier_len 3
2648#define reg_tpsd_hier_lsb 0
2649#define xd_g_reg_bw 0xA3C1
2650#define reg_bw_pos 2
2651#define reg_bw_len 2
2652#define reg_bw_lsb 0
2653#define xd_g_reg_dec_pri 0xA3C1
2654#define reg_dec_pri_pos 4
2655#define reg_dec_pri_len 1
2656#define reg_dec_pri_lsb 0
2657#define xd_g_reg_tpsd_const 0xA3C1
2658#define reg_tpsd_const_pos 6
2659#define reg_tpsd_const_len 2
2660#define reg_tpsd_const_lsb 0
2661#define xd_g_reg_tpsd_hpcr 0xA3C2
2662#define reg_tpsd_hpcr_pos 0
2663#define reg_tpsd_hpcr_len 3
2664#define reg_tpsd_hpcr_lsb 0
2665#define xd_g_reg_tpsd_lpcr 0xA3C2
2666#define reg_tpsd_lpcr_pos 3
2667#define reg_tpsd_lpcr_len 3
2668#define reg_tpsd_lpcr_lsb 0
2669#define xd_g_reg_ofsm_clk 0xA3D0
2670#define reg_ofsm_clk_pos 0
2671#define reg_ofsm_clk_len 3
2672#define reg_ofsm_clk_lsb 0
2673#define xd_g_reg_fclk_cfg 0xA3D1
2674#define reg_fclk_cfg_pos 0
2675#define reg_fclk_cfg_len 1
2676#define reg_fclk_cfg_lsb 0
2677#define xd_g_reg_fclk_idi 0xA3D1
2678#define reg_fclk_idi_pos 1
2679#define reg_fclk_idi_len 1
2680#define reg_fclk_idi_lsb 0
2681#define xd_g_reg_fclk_odi 0xA3D1
2682#define reg_fclk_odi_pos 2
2683#define reg_fclk_odi_len 1
2684#define reg_fclk_odi_lsb 0
2685#define xd_g_reg_fclk_rsd 0xA3D1
2686#define reg_fclk_rsd_pos 3
2687#define reg_fclk_rsd_len 1
2688#define reg_fclk_rsd_lsb 0
2689#define xd_g_reg_fclk_vtb 0xA3D1
2690#define reg_fclk_vtb_pos 4
2691#define reg_fclk_vtb_len 1
2692#define reg_fclk_vtb_lsb 0
2693#define xd_g_reg_fclk_cste 0xA3D1
2694#define reg_fclk_cste_pos 5
2695#define reg_fclk_cste_len 1
2696#define reg_fclk_cste_lsb 0
2697#define xd_g_reg_fclk_mp2if 0xA3D1
2698#define reg_fclk_mp2if_pos 6
2699#define reg_fclk_mp2if_len 1
2700#define reg_fclk_mp2if_lsb 0
2701#define xd_I2C_i2c_m_slave_addr 0xA400
2702#define i2c_m_slave_addr_pos 0
2703#define i2c_m_slave_addr_len 8
2704#define i2c_m_slave_addr_lsb 0
2705#define xd_I2C_i2c_m_data1 0xA401
2706#define i2c_m_data1_pos 0
2707#define i2c_m_data1_len 8
2708#define i2c_m_data1_lsb 0
2709#define xd_I2C_i2c_m_data2 0xA402
2710#define i2c_m_data2_pos 0
2711#define i2c_m_data2_len 8
2712#define i2c_m_data2_lsb 0
2713#define xd_I2C_i2c_m_data3 0xA403
2714#define i2c_m_data3_pos 0
2715#define i2c_m_data3_len 8
2716#define i2c_m_data3_lsb 0
2717#define xd_I2C_i2c_m_data4 0xA404
2718#define i2c_m_data4_pos 0
2719#define i2c_m_data4_len 8
2720#define i2c_m_data4_lsb 0
2721#define xd_I2C_i2c_m_data5 0xA405
2722#define i2c_m_data5_pos 0
2723#define i2c_m_data5_len 8
2724#define i2c_m_data5_lsb 0
2725#define xd_I2C_i2c_m_data6 0xA406
2726#define i2c_m_data6_pos 0
2727#define i2c_m_data6_len 8
2728#define i2c_m_data6_lsb 0
2729#define xd_I2C_i2c_m_data7 0xA407
2730#define i2c_m_data7_pos 0
2731#define i2c_m_data7_len 8
2732#define i2c_m_data7_lsb 0
2733#define xd_I2C_i2c_m_data8 0xA408
2734#define i2c_m_data8_pos 0
2735#define i2c_m_data8_len 8
2736#define i2c_m_data8_lsb 0
2737#define xd_I2C_i2c_m_data9 0xA409
2738#define i2c_m_data9_pos 0
2739#define i2c_m_data9_len 8
2740#define i2c_m_data9_lsb 0
2741#define xd_I2C_i2c_m_data10 0xA40A
2742#define i2c_m_data10_pos 0
2743#define i2c_m_data10_len 8
2744#define i2c_m_data10_lsb 0
2745#define xd_I2C_i2c_m_data11 0xA40B
2746#define i2c_m_data11_pos 0
2747#define i2c_m_data11_len 8
2748#define i2c_m_data11_lsb 0
2749#define xd_I2C_i2c_m_cmd_rw 0xA40C
2750#define i2c_m_cmd_rw_pos 0
2751#define i2c_m_cmd_rw_len 1
2752#define i2c_m_cmd_rw_lsb 0
2753#define xd_I2C_i2c_m_cmd_rwlen 0xA40C
2754#define i2c_m_cmd_rwlen_pos 3
2755#define i2c_m_cmd_rwlen_len 4
2756#define i2c_m_cmd_rwlen_lsb 0
2757#define xd_I2C_i2c_m_status_cmd_exe 0xA40D
2758#define i2c_m_status_cmd_exe_pos 0
2759#define i2c_m_status_cmd_exe_len 1
2760#define i2c_m_status_cmd_exe_lsb 0
2761#define xd_I2C_i2c_m_status_wdat_done 0xA40D
2762#define i2c_m_status_wdat_done_pos 1
2763#define i2c_m_status_wdat_done_len 1
2764#define i2c_m_status_wdat_done_lsb 0
2765#define xd_I2C_i2c_m_status_wdat_fail 0xA40D
2766#define i2c_m_status_wdat_fail_pos 2
2767#define i2c_m_status_wdat_fail_len 1
2768#define i2c_m_status_wdat_fail_lsb 0
2769#define xd_I2C_i2c_m_period 0xA40E
2770#define i2c_m_period_pos 0
2771#define i2c_m_period_len 8
2772#define i2c_m_period_lsb 0
2773#define xd_I2C_i2c_m_reg_msb_lsb 0xA40F
2774#define i2c_m_reg_msb_lsb_pos 0
2775#define i2c_m_reg_msb_lsb_len 1
2776#define i2c_m_reg_msb_lsb_lsb 0
2777#define xd_I2C_reg_ofdm_rst 0xA40F
2778#define reg_ofdm_rst_pos 1
2779#define reg_ofdm_rst_len 1
2780#define reg_ofdm_rst_lsb 0
2781#define xd_I2C_reg_sample_period_on_tuner 0xA40F
2782#define reg_sample_period_on_tuner_pos 2
2783#define reg_sample_period_on_tuner_len 1
2784#define reg_sample_period_on_tuner_lsb 0
2785#define xd_I2C_reg_rst_i2c 0xA40F
2786#define reg_rst_i2c_pos 3
2787#define reg_rst_i2c_len 1
2788#define reg_rst_i2c_lsb 0
2789#define xd_I2C_reg_ofdm_rst_en 0xA40F
2790#define reg_ofdm_rst_en_pos 4
2791#define reg_ofdm_rst_en_len 1
2792#define reg_ofdm_rst_en_lsb 0
2793#define xd_I2C_reg_tuner_sda_sync_on 0xA40F
2794#define reg_tuner_sda_sync_on_pos 5
2795#define reg_tuner_sda_sync_on_len 1
2796#define reg_tuner_sda_sync_on_lsb 0
2797#define xd_p_mp2if_data_access_disable_ofsm 0xA500
2798#define mp2if_data_access_disable_ofsm_pos 0
2799#define mp2if_data_access_disable_ofsm_len 1
2800#define mp2if_data_access_disable_ofsm_lsb 0
2801#define xd_p_reg_mp2_sw_rst_ofsm 0xA500
2802#define reg_mp2_sw_rst_ofsm_pos 1
2803#define reg_mp2_sw_rst_ofsm_len 1
2804#define reg_mp2_sw_rst_ofsm_lsb 0
2805#define xd_p_reg_mp2if_clk_en_ofsm 0xA500
2806#define reg_mp2if_clk_en_ofsm_pos 2
2807#define reg_mp2if_clk_en_ofsm_len 1
2808#define reg_mp2if_clk_en_ofsm_lsb 0
2809#define xd_r_mp2if_sync_byte_locked 0xA500
2810#define mp2if_sync_byte_locked_pos 3
2811#define mp2if_sync_byte_locked_len 1
2812#define mp2if_sync_byte_locked_lsb 0
2813#define xd_r_mp2if_ts_not_188 0xA500
2814#define mp2if_ts_not_188_pos 4
2815#define mp2if_ts_not_188_len 1
2816#define mp2if_ts_not_188_lsb 0
2817#define xd_r_mp2if_psb_empty 0xA500
2818#define mp2if_psb_empty_pos 5
2819#define mp2if_psb_empty_len 1
2820#define mp2if_psb_empty_lsb 0
2821#define xd_r_mp2if_psb_overflow 0xA500
2822#define mp2if_psb_overflow_pos 6
2823#define mp2if_psb_overflow_len 1
2824#define mp2if_psb_overflow_lsb 0
2825#define xd_p_mp2if_keep_sf_sync_byte_ofsm 0xA500
2826#define mp2if_keep_sf_sync_byte_ofsm_pos 7
2827#define mp2if_keep_sf_sync_byte_ofsm_len 1
2828#define mp2if_keep_sf_sync_byte_ofsm_lsb 0
2829#define xd_r_mp2if_psb_mp2if_num_pkt 0xA501
2830#define mp2if_psb_mp2if_num_pkt_pos 0
2831#define mp2if_psb_mp2if_num_pkt_len 6
2832#define mp2if_psb_mp2if_num_pkt_lsb 0
2833#define xd_p_reg_mpeg_full_speed_ofsm 0xA501
2834#define reg_mpeg_full_speed_ofsm_pos 6
2835#define reg_mpeg_full_speed_ofsm_len 1
2836#define reg_mpeg_full_speed_ofsm_lsb 0
2837#define xd_p_mp2if_mpeg_ser_mode_ofsm 0xA501
2838#define mp2if_mpeg_ser_mode_ofsm_pos 7
2839#define mp2if_mpeg_ser_mode_ofsm_len 1
2840#define mp2if_mpeg_ser_mode_ofsm_lsb 0
2841#define xd_p_reg_sw_mon51 0xA600
2842#define reg_sw_mon51_pos 0
2843#define reg_sw_mon51_len 8
2844#define reg_sw_mon51_lsb 0
2845#define xd_p_reg_top_pcsel 0xA601
2846#define reg_top_pcsel_pos 0
2847#define reg_top_pcsel_len 1
2848#define reg_top_pcsel_lsb 0
2849#define xd_p_reg_top_rs232 0xA601
2850#define reg_top_rs232_pos 1
2851#define reg_top_rs232_len 1
2852#define reg_top_rs232_lsb 0
2853#define xd_p_reg_top_pcout 0xA601
2854#define reg_top_pcout_pos 2
2855#define reg_top_pcout_len 1
2856#define reg_top_pcout_lsb 0
2857#define xd_p_reg_top_debug 0xA601
2858#define reg_top_debug_pos 3
2859#define reg_top_debug_len 1
2860#define reg_top_debug_lsb 0
2861#define xd_p_reg_top_adcdly 0xA601
2862#define reg_top_adcdly_pos 4
2863#define reg_top_adcdly_len 2
2864#define reg_top_adcdly_lsb 0
2865#define xd_p_reg_top_pwrdw 0xA601
2866#define reg_top_pwrdw_pos 6
2867#define reg_top_pwrdw_len 1
2868#define reg_top_pwrdw_lsb 0
2869#define xd_p_reg_top_pwrdw_inv 0xA601
2870#define reg_top_pwrdw_inv_pos 7
2871#define reg_top_pwrdw_inv_len 1
2872#define reg_top_pwrdw_inv_lsb 0
2873#define xd_p_reg_top_int_inv 0xA602
2874#define reg_top_int_inv_pos 0
2875#define reg_top_int_inv_len 1
2876#define reg_top_int_inv_lsb 0
2877#define xd_p_reg_top_dio_sel 0xA602
2878#define reg_top_dio_sel_pos 1
2879#define reg_top_dio_sel_len 1
2880#define reg_top_dio_sel_lsb 0
2881#define xd_p_reg_top_gpioon0 0xA603
2882#define reg_top_gpioon0_pos 0
2883#define reg_top_gpioon0_len 1
2884#define reg_top_gpioon0_lsb 0
2885#define xd_p_reg_top_gpioon1 0xA603
2886#define reg_top_gpioon1_pos 1
2887#define reg_top_gpioon1_len 1
2888#define reg_top_gpioon1_lsb 0
2889#define xd_p_reg_top_gpioon2 0xA603
2890#define reg_top_gpioon2_pos 2
2891#define reg_top_gpioon2_len 1
2892#define reg_top_gpioon2_lsb 0
2893#define xd_p_reg_top_gpioon3 0xA603
2894#define reg_top_gpioon3_pos 3
2895#define reg_top_gpioon3_len 1
2896#define reg_top_gpioon3_lsb 0
2897#define xd_p_reg_top_lockon1 0xA603
2898#define reg_top_lockon1_pos 4
2899#define reg_top_lockon1_len 1
2900#define reg_top_lockon1_lsb 0
2901#define xd_p_reg_top_lockon2 0xA603
2902#define reg_top_lockon2_pos 5
2903#define reg_top_lockon2_len 1
2904#define reg_top_lockon2_lsb 0
2905#define xd_p_reg_top_gpioo0 0xA604
2906#define reg_top_gpioo0_pos 0
2907#define reg_top_gpioo0_len 1
2908#define reg_top_gpioo0_lsb 0
2909#define xd_p_reg_top_gpioo1 0xA604
2910#define reg_top_gpioo1_pos 1
2911#define reg_top_gpioo1_len 1
2912#define reg_top_gpioo1_lsb 0
2913#define xd_p_reg_top_gpioo2 0xA604
2914#define reg_top_gpioo2_pos 2
2915#define reg_top_gpioo2_len 1
2916#define reg_top_gpioo2_lsb 0
2917#define xd_p_reg_top_gpioo3 0xA604
2918#define reg_top_gpioo3_pos 3
2919#define reg_top_gpioo3_len 1
2920#define reg_top_gpioo3_lsb 0
2921#define xd_p_reg_top_lock1 0xA604
2922#define reg_top_lock1_pos 4
2923#define reg_top_lock1_len 1
2924#define reg_top_lock1_lsb 0
2925#define xd_p_reg_top_lock2 0xA604
2926#define reg_top_lock2_pos 5
2927#define reg_top_lock2_len 1
2928#define reg_top_lock2_lsb 0
2929#define xd_p_reg_top_gpioen0 0xA605
2930#define reg_top_gpioen0_pos 0
2931#define reg_top_gpioen0_len 1
2932#define reg_top_gpioen0_lsb 0
2933#define xd_p_reg_top_gpioen1 0xA605
2934#define reg_top_gpioen1_pos 1
2935#define reg_top_gpioen1_len 1
2936#define reg_top_gpioen1_lsb 0
2937#define xd_p_reg_top_gpioen2 0xA605
2938#define reg_top_gpioen2_pos 2
2939#define reg_top_gpioen2_len 1
2940#define reg_top_gpioen2_lsb 0
2941#define xd_p_reg_top_gpioen3 0xA605
2942#define reg_top_gpioen3_pos 3
2943#define reg_top_gpioen3_len 1
2944#define reg_top_gpioen3_lsb 0
2945#define xd_p_reg_top_locken1 0xA605
2946#define reg_top_locken1_pos 4
2947#define reg_top_locken1_len 1
2948#define reg_top_locken1_lsb 0
2949#define xd_p_reg_top_locken2 0xA605
2950#define reg_top_locken2_pos 5
2951#define reg_top_locken2_len 1
2952#define reg_top_locken2_lsb 0
2953#define xd_r_reg_top_gpioi0 0xA606
2954#define reg_top_gpioi0_pos 0
2955#define reg_top_gpioi0_len 1
2956#define reg_top_gpioi0_lsb 0
2957#define xd_r_reg_top_gpioi1 0xA606
2958#define reg_top_gpioi1_pos 1
2959#define reg_top_gpioi1_len 1
2960#define reg_top_gpioi1_lsb 0
2961#define xd_r_reg_top_gpioi2 0xA606
2962#define reg_top_gpioi2_pos 2
2963#define reg_top_gpioi2_len 1
2964#define reg_top_gpioi2_lsb 0
2965#define xd_r_reg_top_gpioi3 0xA606
2966#define reg_top_gpioi3_pos 3
2967#define reg_top_gpioi3_len 1
2968#define reg_top_gpioi3_lsb 0
2969#define xd_r_reg_top_locki1 0xA606
2970#define reg_top_locki1_pos 4
2971#define reg_top_locki1_len 1
2972#define reg_top_locki1_lsb 0
2973#define xd_r_reg_top_locki2 0xA606
2974#define reg_top_locki2_pos 5
2975#define reg_top_locki2_len 1
2976#define reg_top_locki2_lsb 0
2977#define xd_p_reg_dummy_7_0 0xA608
2978#define reg_dummy_7_0_pos 0
2979#define reg_dummy_7_0_len 8
2980#define reg_dummy_7_0_lsb 0
2981#define xd_p_reg_dummy_15_8 0xA609
2982#define reg_dummy_15_8_pos 0
2983#define reg_dummy_15_8_len 8
2984#define reg_dummy_15_8_lsb 8
2985#define xd_p_reg_dummy_23_16 0xA60A
2986#define reg_dummy_23_16_pos 0
2987#define reg_dummy_23_16_len 8
2988#define reg_dummy_23_16_lsb 16
2989#define xd_p_reg_dummy_31_24 0xA60B
2990#define reg_dummy_31_24_pos 0
2991#define reg_dummy_31_24_len 8
2992#define reg_dummy_31_24_lsb 24
2993#define xd_p_reg_dummy_39_32 0xA60C
2994#define reg_dummy_39_32_pos 0
2995#define reg_dummy_39_32_len 8
2996#define reg_dummy_39_32_lsb 32
2997#define xd_p_reg_dummy_47_40 0xA60D
2998#define reg_dummy_47_40_pos 0
2999#define reg_dummy_47_40_len 8
3000#define reg_dummy_47_40_lsb 40
3001#define xd_p_reg_dummy_55_48 0xA60E
3002#define reg_dummy_55_48_pos 0
3003#define reg_dummy_55_48_len 8
3004#define reg_dummy_55_48_lsb 48
3005#define xd_p_reg_dummy_63_56 0xA60F
3006#define reg_dummy_63_56_pos 0
3007#define reg_dummy_63_56_len 8
3008#define reg_dummy_63_56_lsb 56
3009#define xd_p_reg_dummy_71_64 0xA610
3010#define reg_dummy_71_64_pos 0
3011#define reg_dummy_71_64_len 8
3012#define reg_dummy_71_64_lsb 64
3013#define xd_p_reg_dummy_79_72 0xA611
3014#define reg_dummy_79_72_pos 0
3015#define reg_dummy_79_72_len 8
3016#define reg_dummy_79_72_lsb 72
3017#define xd_p_reg_dummy_87_80 0xA612
3018#define reg_dummy_87_80_pos 0
3019#define reg_dummy_87_80_len 8
3020#define reg_dummy_87_80_lsb 80
3021#define xd_p_reg_dummy_95_88 0xA613
3022#define reg_dummy_95_88_pos 0
3023#define reg_dummy_95_88_len 8
3024#define reg_dummy_95_88_lsb 88
3025#define xd_p_reg_dummy_103_96 0xA614
3026#define reg_dummy_103_96_pos 0
3027#define reg_dummy_103_96_len 8
3028#define reg_dummy_103_96_lsb 96
3029
3030#define xd_p_reg_unplug_flag 0xA615
3031#define reg_unplug_flag_pos 0
3032#define reg_unplug_flag_len 1
3033#define reg_unplug_flag_lsb 104
3034
3035#define xd_p_reg_api_dca_stes_request 0xA615
3036#define reg_api_dca_stes_request_pos 1
3037#define reg_api_dca_stes_request_len 1
3038#define reg_api_dca_stes_request_lsb 0
3039
3040#define xd_p_reg_back_to_dca_flag 0xA615
3041#define reg_back_to_dca_flag_pos 2
3042#define reg_back_to_dca_flag_len 1
3043#define reg_back_to_dca_flag_lsb 106
3044
3045#define xd_p_reg_api_retrain_request 0xA615
3046#define reg_api_retrain_request_pos 3
3047#define reg_api_retrain_request_len 1
3048#define reg_api_retrain_request_lsb 0
3049
3050#define xd_p_reg_Dyn_Top_Try_flag 0xA615
3051#define reg_Dyn_Top_Try_flag_pos 3
3052#define reg_Dyn_Top_Try_flag_len 1
3053#define reg_Dyn_Top_Try_flag_lsb 107
3054
3055#define xd_p_reg_API_retrain_freeze_flag 0xA615
3056#define reg_API_retrain_freeze_flag_pos 4
3057#define reg_API_retrain_freeze_flag_len 1
3058#define reg_API_retrain_freeze_flag_lsb 108
3059
3060#define xd_p_reg_dummy_111_104 0xA615
3061#define reg_dummy_111_104_pos 0
3062#define reg_dummy_111_104_len 8
3063#define reg_dummy_111_104_lsb 104
3064#define xd_p_reg_dummy_119_112 0xA616
3065#define reg_dummy_119_112_pos 0
3066#define reg_dummy_119_112_len 8
3067#define reg_dummy_119_112_lsb 112
3068#define xd_p_reg_dummy_127_120 0xA617
3069#define reg_dummy_127_120_pos 0
3070#define reg_dummy_127_120_len 8
3071#define reg_dummy_127_120_lsb 120
3072#define xd_p_reg_dummy_135_128 0xA618
3073#define reg_dummy_135_128_pos 0
3074#define reg_dummy_135_128_len 8
3075#define reg_dummy_135_128_lsb 128
3076
3077#define xd_p_reg_dummy_143_136 0xA619
3078#define reg_dummy_143_136_pos 0
3079#define reg_dummy_143_136_len 8
3080#define reg_dummy_143_136_lsb 136
3081
3082#define xd_p_reg_CCIR_dis 0xA619
3083#define reg_CCIR_dis_pos 0
3084#define reg_CCIR_dis_len 1
3085#define reg_CCIR_dis_lsb 0
3086
3087#define xd_p_reg_dummy_151_144 0xA61A
3088#define reg_dummy_151_144_pos 0
3089#define reg_dummy_151_144_len 8
3090#define reg_dummy_151_144_lsb 144
3091
3092#define xd_p_reg_dummy_159_152 0xA61B
3093#define reg_dummy_159_152_pos 0
3094#define reg_dummy_159_152_len 8
3095#define reg_dummy_159_152_lsb 152
3096
3097#define xd_p_reg_dummy_167_160 0xA61C
3098#define reg_dummy_167_160_pos 0
3099#define reg_dummy_167_160_len 8
3100#define reg_dummy_167_160_lsb 160
3101
3102#define xd_p_reg_dummy_175_168 0xA61D
3103#define reg_dummy_175_168_pos 0
3104#define reg_dummy_175_168_len 8
3105#define reg_dummy_175_168_lsb 168
3106
3107#define xd_p_reg_dummy_183_176 0xA61E
3108#define reg_dummy_183_176_pos 0
3109#define reg_dummy_183_176_len 8
3110#define reg_dummy_183_176_lsb 176
3111
3112#define xd_p_reg_ofsm_read_rbc_en 0xA61E
3113#define reg_ofsm_read_rbc_en_pos 2
3114#define reg_ofsm_read_rbc_en_len 1
3115#define reg_ofsm_read_rbc_en_lsb 0
3116
3117#define xd_p_reg_ce_filter_selection_dis 0xA61E
3118#define reg_ce_filter_selection_dis_pos 1
3119#define reg_ce_filter_selection_dis_len 1
3120#define reg_ce_filter_selection_dis_lsb 0
3121
3122#define xd_p_reg_OFSM_version_control_7_0 0xA611
3123#define reg_OFSM_version_control_7_0_pos 0
3124#define reg_OFSM_version_control_7_0_len 8
3125#define reg_OFSM_version_control_7_0_lsb 0
3126
3127#define xd_p_reg_OFSM_version_control_15_8 0xA61F
3128#define reg_OFSM_version_control_15_8_pos 0
3129#define reg_OFSM_version_control_15_8_len 8
3130#define reg_OFSM_version_control_15_8_lsb 0
3131
3132#define xd_p_reg_OFSM_version_control_23_16 0xA620
3133#define reg_OFSM_version_control_23_16_pos 0
3134#define reg_OFSM_version_control_23_16_len 8
3135#define reg_OFSM_version_control_23_16_lsb 0
3136
3137#define xd_p_reg_dummy_191_184 0xA61F
3138#define reg_dummy_191_184_pos 0
3139#define reg_dummy_191_184_len 8
3140#define reg_dummy_191_184_lsb 184
3141
3142#define xd_p_reg_dummy_199_192 0xA620
3143#define reg_dummy_199_192_pos 0
3144#define reg_dummy_199_192_len 8
3145#define reg_dummy_199_192_lsb 192
3146
3147#define xd_p_reg_ce_en 0xABC0
3148#define reg_ce_en_pos 0
3149#define reg_ce_en_len 1
3150#define reg_ce_en_lsb 0
3151#define xd_p_reg_ce_fctrl_en 0xABC0
3152#define reg_ce_fctrl_en_pos 1
3153#define reg_ce_fctrl_en_len 1
3154#define reg_ce_fctrl_en_lsb 0
3155#define xd_p_reg_ce_fste_tdi 0xABC0
3156#define reg_ce_fste_tdi_pos 2
3157#define reg_ce_fste_tdi_len 1
3158#define reg_ce_fste_tdi_lsb 0
3159#define xd_p_reg_ce_dynamic 0xABC0
3160#define reg_ce_dynamic_pos 3
3161#define reg_ce_dynamic_len 1
3162#define reg_ce_dynamic_lsb 0
3163#define xd_p_reg_ce_conf 0xABC0
3164#define reg_ce_conf_pos 4
3165#define reg_ce_conf_len 2
3166#define reg_ce_conf_lsb 0
3167#define xd_p_reg_ce_dyn12 0xABC0
3168#define reg_ce_dyn12_pos 6
3169#define reg_ce_dyn12_len 1
3170#define reg_ce_dyn12_lsb 0
3171#define xd_p_reg_ce_derot_en 0xABC0
3172#define reg_ce_derot_en_pos 7
3173#define reg_ce_derot_en_len 1
3174#define reg_ce_derot_en_lsb 0
3175#define xd_p_reg_ce_dynamic_th_7_0 0xABC1
3176#define reg_ce_dynamic_th_7_0_pos 0
3177#define reg_ce_dynamic_th_7_0_len 8
3178#define reg_ce_dynamic_th_7_0_lsb 0
3179#define xd_p_reg_ce_dynamic_th_15_8 0xABC2
3180#define reg_ce_dynamic_th_15_8_pos 0
3181#define reg_ce_dynamic_th_15_8_len 8
3182#define reg_ce_dynamic_th_15_8_lsb 8
3183#define xd_p_reg_ce_s1 0xABC3
3184#define reg_ce_s1_pos 0
3185#define reg_ce_s1_len 5
3186#define reg_ce_s1_lsb 0
3187#define xd_p_reg_ce_var_forced_value 0xABC3
3188#define reg_ce_var_forced_value_pos 5
3189#define reg_ce_var_forced_value_len 3
3190#define reg_ce_var_forced_value_lsb 0
3191#define xd_p_reg_ce_data_im_7_0 0xABC4
3192#define reg_ce_data_im_7_0_pos 0
3193#define reg_ce_data_im_7_0_len 8
3194#define reg_ce_data_im_7_0_lsb 0
3195#define xd_p_reg_ce_data_im_8 0xABC5
3196#define reg_ce_data_im_8_pos 0
3197#define reg_ce_data_im_8_len 1
3198#define reg_ce_data_im_8_lsb 0
3199#define xd_p_reg_ce_data_re_6_0 0xABC5
3200#define reg_ce_data_re_6_0_pos 1
3201#define reg_ce_data_re_6_0_len 7
3202#define reg_ce_data_re_6_0_lsb 0
3203#define xd_p_reg_ce_data_re_8_7 0xABC6
3204#define reg_ce_data_re_8_7_pos 0
3205#define reg_ce_data_re_8_7_len 2
3206#define reg_ce_data_re_8_7_lsb 7
3207#define xd_p_reg_ce_tone_5_0 0xABC6
3208#define reg_ce_tone_5_0_pos 2
3209#define reg_ce_tone_5_0_len 6
3210#define reg_ce_tone_5_0_lsb 0
3211#define xd_p_reg_ce_tone_12_6 0xABC7
3212#define reg_ce_tone_12_6_pos 0
3213#define reg_ce_tone_12_6_len 7
3214#define reg_ce_tone_12_6_lsb 6
3215#define xd_p_reg_ce_centroid_drift_th 0xABC8
3216#define reg_ce_centroid_drift_th_pos 0
3217#define reg_ce_centroid_drift_th_len 8
3218#define reg_ce_centroid_drift_th_lsb 0
3219#define xd_p_reg_ce_centroid_count_max 0xABC9
3220#define reg_ce_centroid_count_max_pos 0
3221#define reg_ce_centroid_count_max_len 4
3222#define reg_ce_centroid_count_max_lsb 0
3223#define xd_p_reg_ce_centroid_bias_inc_7_0 0xABCA
3224#define reg_ce_centroid_bias_inc_7_0_pos 0
3225#define reg_ce_centroid_bias_inc_7_0_len 8
3226#define reg_ce_centroid_bias_inc_7_0_lsb 0
3227#define xd_p_reg_ce_centroid_bias_inc_8 0xABCB
3228#define reg_ce_centroid_bias_inc_8_pos 0
3229#define reg_ce_centroid_bias_inc_8_len 1
3230#define reg_ce_centroid_bias_inc_8_lsb 0
3231#define xd_p_reg_ce_var_th0_7_0 0xABCC
3232#define reg_ce_var_th0_7_0_pos 0
3233#define reg_ce_var_th0_7_0_len 8
3234#define reg_ce_var_th0_7_0_lsb 0
3235#define xd_p_reg_ce_var_th0_15_8 0xABCD
3236#define reg_ce_var_th0_15_8_pos 0
3237#define reg_ce_var_th0_15_8_len 8
3238#define reg_ce_var_th0_15_8_lsb 8
3239#define xd_p_reg_ce_var_th1_7_0 0xABCE
3240#define reg_ce_var_th1_7_0_pos 0
3241#define reg_ce_var_th1_7_0_len 8
3242#define reg_ce_var_th1_7_0_lsb 0
3243#define xd_p_reg_ce_var_th1_15_8 0xABCF
3244#define reg_ce_var_th1_15_8_pos 0
3245#define reg_ce_var_th1_15_8_len 8
3246#define reg_ce_var_th1_15_8_lsb 8
3247#define xd_p_reg_ce_var_th2_7_0 0xABD0
3248#define reg_ce_var_th2_7_0_pos 0
3249#define reg_ce_var_th2_7_0_len 8
3250#define reg_ce_var_th2_7_0_lsb 0
3251#define xd_p_reg_ce_var_th2_15_8 0xABD1
3252#define reg_ce_var_th2_15_8_pos 0
3253#define reg_ce_var_th2_15_8_len 8
3254#define reg_ce_var_th2_15_8_lsb 8
3255#define xd_p_reg_ce_var_th3_7_0 0xABD2
3256#define reg_ce_var_th3_7_0_pos 0
3257#define reg_ce_var_th3_7_0_len 8
3258#define reg_ce_var_th3_7_0_lsb 0
3259#define xd_p_reg_ce_var_th3_15_8 0xABD3
3260#define reg_ce_var_th3_15_8_pos 0
3261#define reg_ce_var_th3_15_8_len 8
3262#define reg_ce_var_th3_15_8_lsb 8
3263#define xd_p_reg_ce_var_th4_7_0 0xABD4
3264#define reg_ce_var_th4_7_0_pos 0
3265#define reg_ce_var_th4_7_0_len 8
3266#define reg_ce_var_th4_7_0_lsb 0
3267#define xd_p_reg_ce_var_th4_15_8 0xABD5
3268#define reg_ce_var_th4_15_8_pos 0
3269#define reg_ce_var_th4_15_8_len 8
3270#define reg_ce_var_th4_15_8_lsb 8
3271#define xd_p_reg_ce_var_th5_7_0 0xABD6
3272#define reg_ce_var_th5_7_0_pos 0
3273#define reg_ce_var_th5_7_0_len 8
3274#define reg_ce_var_th5_7_0_lsb 0
3275#define xd_p_reg_ce_var_th5_15_8 0xABD7
3276#define reg_ce_var_th5_15_8_pos 0
3277#define reg_ce_var_th5_15_8_len 8
3278#define reg_ce_var_th5_15_8_lsb 8
3279#define xd_p_reg_ce_var_th6_7_0 0xABD8
3280#define reg_ce_var_th6_7_0_pos 0
3281#define reg_ce_var_th6_7_0_len 8
3282#define reg_ce_var_th6_7_0_lsb 0
3283#define xd_p_reg_ce_var_th6_15_8 0xABD9
3284#define reg_ce_var_th6_15_8_pos 0
3285#define reg_ce_var_th6_15_8_len 8
3286#define reg_ce_var_th6_15_8_lsb 8
3287#define xd_p_reg_ce_fctrl_reset 0xABDA
3288#define reg_ce_fctrl_reset_pos 0
3289#define reg_ce_fctrl_reset_len 1
3290#define reg_ce_fctrl_reset_lsb 0
3291#define xd_p_reg_ce_cent_auto_clr_en 0xABDA
3292#define reg_ce_cent_auto_clr_en_pos 1
3293#define reg_ce_cent_auto_clr_en_len 1
3294#define reg_ce_cent_auto_clr_en_lsb 0
3295#define xd_p_reg_ce_fctrl_auto_reset_en 0xABDA
3296#define reg_ce_fctrl_auto_reset_en_pos 2
3297#define reg_ce_fctrl_auto_reset_en_len 1
3298#define reg_ce_fctrl_auto_reset_en_lsb 0
3299#define xd_p_reg_ce_var_forced_en 0xABDA
3300#define reg_ce_var_forced_en_pos 3
3301#define reg_ce_var_forced_en_len 1
3302#define reg_ce_var_forced_en_lsb 0
3303#define xd_p_reg_ce_cent_forced_en 0xABDA
3304#define reg_ce_cent_forced_en_pos 4
3305#define reg_ce_cent_forced_en_len 1
3306#define reg_ce_cent_forced_en_lsb 0
3307#define xd_p_reg_ce_var_max 0xABDA
3308#define reg_ce_var_max_pos 5
3309#define reg_ce_var_max_len 3
3310#define reg_ce_var_max_lsb 0
3311#define xd_p_reg_ce_cent_forced_value_7_0 0xABDB
3312#define reg_ce_cent_forced_value_7_0_pos 0
3313#define reg_ce_cent_forced_value_7_0_len 8
3314#define reg_ce_cent_forced_value_7_0_lsb 0
3315#define xd_p_reg_ce_cent_forced_value_11_8 0xABDC
3316#define reg_ce_cent_forced_value_11_8_pos 0
3317#define reg_ce_cent_forced_value_11_8_len 4
3318#define reg_ce_cent_forced_value_11_8_lsb 8
3319#define xd_p_reg_ce_fctrl_rd 0xABDD
3320#define reg_ce_fctrl_rd_pos 0
3321#define reg_ce_fctrl_rd_len 1
3322#define reg_ce_fctrl_rd_lsb 0
3323#define xd_p_reg_ce_centroid_max_6_0 0xABDD
3324#define reg_ce_centroid_max_6_0_pos 1
3325#define reg_ce_centroid_max_6_0_len 7
3326#define reg_ce_centroid_max_6_0_lsb 0
3327#define xd_p_reg_ce_centroid_max_11_7 0xABDE
3328#define reg_ce_centroid_max_11_7_pos 0
3329#define reg_ce_centroid_max_11_7_len 5
3330#define reg_ce_centroid_max_11_7_lsb 7
3331#define xd_p_reg_ce_var 0xABDF
3332#define reg_ce_var_pos 0
3333#define reg_ce_var_len 3
3334#define reg_ce_var_lsb 0
3335#define xd_p_reg_ce_fctrl_rdy 0xABDF
3336#define reg_ce_fctrl_rdy_pos 3
3337#define reg_ce_fctrl_rdy_len 1
3338#define reg_ce_fctrl_rdy_lsb 0
3339#define xd_p_reg_ce_centroid_out_3_0 0xABDF
3340#define reg_ce_centroid_out_3_0_pos 4
3341#define reg_ce_centroid_out_3_0_len 4
3342#define reg_ce_centroid_out_3_0_lsb 0
3343#define xd_p_reg_ce_centroid_out_11_4 0xABE0
3344#define reg_ce_centroid_out_11_4_pos 0
3345#define reg_ce_centroid_out_11_4_len 8
3346#define reg_ce_centroid_out_11_4_lsb 4
3347#define xd_p_reg_ce_bias_7_0 0xABE1
3348#define reg_ce_bias_7_0_pos 0
3349#define reg_ce_bias_7_0_len 8
3350#define reg_ce_bias_7_0_lsb 0
3351#define xd_p_reg_ce_bias_11_8 0xABE2
3352#define reg_ce_bias_11_8_pos 0
3353#define reg_ce_bias_11_8_len 4
3354#define reg_ce_bias_11_8_lsb 8
3355#define xd_p_reg_ce_m1_3_0 0xABE2
3356#define reg_ce_m1_3_0_pos 4
3357#define reg_ce_m1_3_0_len 4
3358#define reg_ce_m1_3_0_lsb 0
3359#define xd_p_reg_ce_m1_11_4 0xABE3
3360#define reg_ce_m1_11_4_pos 0
3361#define reg_ce_m1_11_4_len 8
3362#define reg_ce_m1_11_4_lsb 4
3363#define xd_p_reg_ce_rh0_7_0 0xABE4
3364#define reg_ce_rh0_7_0_pos 0
3365#define reg_ce_rh0_7_0_len 8
3366#define reg_ce_rh0_7_0_lsb 0
3367#define xd_p_reg_ce_rh0_15_8 0xABE5
3368#define reg_ce_rh0_15_8_pos 0
3369#define reg_ce_rh0_15_8_len 8
3370#define reg_ce_rh0_15_8_lsb 8
3371#define xd_p_reg_ce_rh0_23_16 0xABE6
3372#define reg_ce_rh0_23_16_pos 0
3373#define reg_ce_rh0_23_16_len 8
3374#define reg_ce_rh0_23_16_lsb 16
3375#define xd_p_reg_ce_rh0_31_24 0xABE7
3376#define reg_ce_rh0_31_24_pos 0
3377#define reg_ce_rh0_31_24_len 8
3378#define reg_ce_rh0_31_24_lsb 24
3379#define xd_p_reg_ce_rh3_real_7_0 0xABE8
3380#define reg_ce_rh3_real_7_0_pos 0
3381#define reg_ce_rh3_real_7_0_len 8
3382#define reg_ce_rh3_real_7_0_lsb 0
3383#define xd_p_reg_ce_rh3_real_15_8 0xABE9
3384#define reg_ce_rh3_real_15_8_pos 0
3385#define reg_ce_rh3_real_15_8_len 8
3386#define reg_ce_rh3_real_15_8_lsb 8
3387#define xd_p_reg_ce_rh3_real_23_16 0xABEA
3388#define reg_ce_rh3_real_23_16_pos 0
3389#define reg_ce_rh3_real_23_16_len 8
3390#define reg_ce_rh3_real_23_16_lsb 16
3391#define xd_p_reg_ce_rh3_real_31_24 0xABEB
3392#define reg_ce_rh3_real_31_24_pos 0
3393#define reg_ce_rh3_real_31_24_len 8
3394#define reg_ce_rh3_real_31_24_lsb 24
3395#define xd_p_reg_ce_rh3_imag_7_0 0xABEC
3396#define reg_ce_rh3_imag_7_0_pos 0
3397#define reg_ce_rh3_imag_7_0_len 8
3398#define reg_ce_rh3_imag_7_0_lsb 0
3399#define xd_p_reg_ce_rh3_imag_15_8 0xABED
3400#define reg_ce_rh3_imag_15_8_pos 0
3401#define reg_ce_rh3_imag_15_8_len 8
3402#define reg_ce_rh3_imag_15_8_lsb 8
3403#define xd_p_reg_ce_rh3_imag_23_16 0xABEE
3404#define reg_ce_rh3_imag_23_16_pos 0
3405#define reg_ce_rh3_imag_23_16_len 8
3406#define reg_ce_rh3_imag_23_16_lsb 16
3407#define xd_p_reg_ce_rh3_imag_31_24 0xABEF
3408#define reg_ce_rh3_imag_31_24_pos 0
3409#define reg_ce_rh3_imag_31_24_len 8
3410#define reg_ce_rh3_imag_31_24_lsb 24
3411#define xd_p_reg_feq_fix_eh2_7_0 0xABF0
3412#define reg_feq_fix_eh2_7_0_pos 0
3413#define reg_feq_fix_eh2_7_0_len 8
3414#define reg_feq_fix_eh2_7_0_lsb 0
3415#define xd_p_reg_feq_fix_eh2_15_8 0xABF1
3416#define reg_feq_fix_eh2_15_8_pos 0
3417#define reg_feq_fix_eh2_15_8_len 8
3418#define reg_feq_fix_eh2_15_8_lsb 8
3419#define xd_p_reg_feq_fix_eh2_23_16 0xABF2
3420#define reg_feq_fix_eh2_23_16_pos 0
3421#define reg_feq_fix_eh2_23_16_len 8
3422#define reg_feq_fix_eh2_23_16_lsb 16
3423#define xd_p_reg_feq_fix_eh2_31_24 0xABF3
3424#define reg_feq_fix_eh2_31_24_pos 0
3425#define reg_feq_fix_eh2_31_24_len 8
3426#define reg_feq_fix_eh2_31_24_lsb 24
3427#define xd_p_reg_ce_m2_central_7_0 0xABF4
3428#define reg_ce_m2_central_7_0_pos 0
3429#define reg_ce_m2_central_7_0_len 8
3430#define reg_ce_m2_central_7_0_lsb 0
3431#define xd_p_reg_ce_m2_central_15_8 0xABF5
3432#define reg_ce_m2_central_15_8_pos 0
3433#define reg_ce_m2_central_15_8_len 8
3434#define reg_ce_m2_central_15_8_lsb 8
3435#define xd_p_reg_ce_fftshift 0xABF6
3436#define reg_ce_fftshift_pos 0
3437#define reg_ce_fftshift_len 4
3438#define reg_ce_fftshift_lsb 0
3439#define xd_p_reg_ce_fftshift1 0xABF6
3440#define reg_ce_fftshift1_pos 4
3441#define reg_ce_fftshift1_len 4
3442#define reg_ce_fftshift1_lsb 0
3443#define xd_p_reg_ce_fftshift2 0xABF7
3444#define reg_ce_fftshift2_pos 0
3445#define reg_ce_fftshift2_len 4
3446#define reg_ce_fftshift2_lsb 0
3447#define xd_p_reg_ce_top_mobile 0xABF7
3448#define reg_ce_top_mobile_pos 4
3449#define reg_ce_top_mobile_len 1
3450#define reg_ce_top_mobile_lsb 0
3451#define xd_p_reg_strong_sginal_detected 0xA2BC
3452#define reg_strong_sginal_detected_pos 2
3453#define reg_strong_sginal_detected_len 1
3454#define reg_strong_sginal_detected_lsb 0
3455
3456#define XD_MP2IF_BASE 0xB000
3457#define XD_MP2IF_CSR (0x00 + XD_MP2IF_BASE)
3458#define XD_MP2IF_DMX_CTRL (0x03 + XD_MP2IF_BASE)
3459#define XD_MP2IF_PID_IDX (0x04 + XD_MP2IF_BASE)
3460#define XD_MP2IF_PID_DATA_L (0x05 + XD_MP2IF_BASE)
3461#define XD_MP2IF_PID_DATA_H (0x06 + XD_MP2IF_BASE)
3462#define XD_MP2IF_MISC (0x07 + XD_MP2IF_BASE)
3463
3464extern struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d);
3465extern int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg,
3466 u8 * value);
3467extern int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg,
3468 u8 * values, int len);
3469extern int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg,
3470 u8 value);
3471extern int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg,
3472 u8 * values, int len);
3473extern int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg,
3474 u8 addr, u8 * values, int len);
3475extern int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg,
3476 u8 * values, int len);
3477extern int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg,
3478 u8 pos, u8 len, u8 * value);
3479extern int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg,
3480 u8 pos, u8 len, u8 value);
3481extern int af9005_send_command(struct dvb_usb_device *d, u8 command,
3482 u8 * wbuf, int wlen, u8 * rbuf, int rlen);
3483extern int af9005_read_eeprom(struct dvb_usb_device *d, u8 address,
3484 u8 * values, int len);
3485extern int af9005_tuner_attach(struct dvb_usb_adapter *adap);
3486extern int af9005_led_control(struct dvb_usb_device *d, int onoff);
3487
3488extern u8 regmask[8];
3489
3490/* remote control decoder */
3491extern int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len,
3492 u32 * event, int *state);
3493extern struct rc_map_table rc_map_af9005_table[];
3494extern int rc_map_af9005_table_size;
3495
3496#endif
diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
new file mode 100644
index 000000000000..5e45ae605427
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/az6027.c
@@ -0,0 +1,1182 @@
1/* DVB USB compliant Linux driver for the AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)
2 * receiver.
3 *
4 * Copyright (C) 2009 Adams.Xu <adams.xu@azwave.com.cn>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "az6027.h"
13
14#include "stb0899_drv.h"
15#include "stb0899_reg.h"
16#include "stb0899_cfg.h"
17
18#include "stb6100.h"
19#include "stb6100_cfg.h"
20#include "dvb_ca_en50221.h"
21
22int dvb_usb_az6027_debug;
23module_param_named(debug, dvb_usb_az6027_debug, int, 0644);
24MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
25
26DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
27
28struct az6027_device_state {
29 struct dvb_ca_en50221 ca;
30 struct mutex ca_mutex;
31 u8 power_state;
32};
33
34static const struct stb0899_s1_reg az6027_stb0899_s1_init_1[] = {
35
36 /* 0x0000000b, SYSREG */
37 { STB0899_DEV_ID , 0x30 },
38 { STB0899_DISCNTRL1 , 0x32 },
39 { STB0899_DISCNTRL2 , 0x80 },
40 { STB0899_DISRX_ST0 , 0x04 },
41 { STB0899_DISRX_ST1 , 0x00 },
42 { STB0899_DISPARITY , 0x00 },
43 { STB0899_DISSTATUS , 0x20 },
44 { STB0899_DISF22 , 0x99 },
45 { STB0899_DISF22RX , 0xa8 },
46 /* SYSREG ? */
47 { STB0899_ACRPRESC , 0x11 },
48 { STB0899_ACRDIV1 , 0x0a },
49 { STB0899_ACRDIV2 , 0x05 },
50 { STB0899_DACR1 , 0x00 },
51 { STB0899_DACR2 , 0x00 },
52 { STB0899_OUTCFG , 0x00 },
53 { STB0899_MODECFG , 0x00 },
54 { STB0899_IRQSTATUS_3 , 0xfe },
55 { STB0899_IRQSTATUS_2 , 0x03 },
56 { STB0899_IRQSTATUS_1 , 0x7c },
57 { STB0899_IRQSTATUS_0 , 0xf4 },
58 { STB0899_IRQMSK_3 , 0xf3 },
59 { STB0899_IRQMSK_2 , 0xfc },
60 { STB0899_IRQMSK_1 , 0xff },
61 { STB0899_IRQMSK_0 , 0xff },
62 { STB0899_IRQCFG , 0x00 },
63 { STB0899_I2CCFG , 0x88 },
64 { STB0899_I2CRPT , 0x58 },
65 { STB0899_IOPVALUE5 , 0x00 },
66 { STB0899_IOPVALUE4 , 0x33 },
67 { STB0899_IOPVALUE3 , 0x6d },
68 { STB0899_IOPVALUE2 , 0x90 },
69 { STB0899_IOPVALUE1 , 0x60 },
70 { STB0899_IOPVALUE0 , 0x00 },
71 { STB0899_GPIO00CFG , 0x82 },
72 { STB0899_GPIO01CFG , 0x82 },
73 { STB0899_GPIO02CFG , 0x82 },
74 { STB0899_GPIO03CFG , 0x82 },
75 { STB0899_GPIO04CFG , 0x82 },
76 { STB0899_GPIO05CFG , 0x82 },
77 { STB0899_GPIO06CFG , 0x82 },
78 { STB0899_GPIO07CFG , 0x82 },
79 { STB0899_GPIO08CFG , 0x82 },
80 { STB0899_GPIO09CFG , 0x82 },
81 { STB0899_GPIO10CFG , 0x82 },
82 { STB0899_GPIO11CFG , 0x82 },
83 { STB0899_GPIO12CFG , 0x82 },
84 { STB0899_GPIO13CFG , 0x82 },
85 { STB0899_GPIO14CFG , 0x82 },
86 { STB0899_GPIO15CFG , 0x82 },
87 { STB0899_GPIO16CFG , 0x82 },
88 { STB0899_GPIO17CFG , 0x82 },
89 { STB0899_GPIO18CFG , 0x82 },
90 { STB0899_GPIO19CFG , 0x82 },
91 { STB0899_GPIO20CFG , 0x82 },
92 { STB0899_SDATCFG , 0xb8 },
93 { STB0899_SCLTCFG , 0xba },
94 { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
95 { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
96 { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
97 { STB0899_DIRCLKCFG , 0x82 },
98 { STB0899_CLKOUT27CFG , 0x7e },
99 { STB0899_STDBYCFG , 0x82 },
100 { STB0899_CS0CFG , 0x82 },
101 { STB0899_CS1CFG , 0x82 },
102 { STB0899_DISEQCOCFG , 0x20 },
103 { STB0899_GPIO32CFG , 0x82 },
104 { STB0899_GPIO33CFG , 0x82 },
105 { STB0899_GPIO34CFG , 0x82 },
106 { STB0899_GPIO35CFG , 0x82 },
107 { STB0899_GPIO36CFG , 0x82 },
108 { STB0899_GPIO37CFG , 0x82 },
109 { STB0899_GPIO38CFG , 0x82 },
110 { STB0899_GPIO39CFG , 0x82 },
111 { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
112 { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
113 { STB0899_FILTCTRL , 0x00 },
114 { STB0899_SYSCTRL , 0x01 },
115 { STB0899_STOPCLK1 , 0x20 },
116 { STB0899_STOPCLK2 , 0x00 },
117 { STB0899_INTBUFSTATUS , 0x00 },
118 { STB0899_INTBUFCTRL , 0x0a },
119 { 0xffff , 0xff },
120};
121
122static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
123 { STB0899_DEMOD , 0x00 },
124 { STB0899_RCOMPC , 0xc9 },
125 { STB0899_AGC1CN , 0x01 },
126 { STB0899_AGC1REF , 0x10 },
127 { STB0899_RTC , 0x23 },
128 { STB0899_TMGCFG , 0x4e },
129 { STB0899_AGC2REF , 0x34 },
130 { STB0899_TLSR , 0x84 },
131 { STB0899_CFD , 0xf7 },
132 { STB0899_ACLC , 0x87 },
133 { STB0899_BCLC , 0x94 },
134 { STB0899_EQON , 0x41 },
135 { STB0899_LDT , 0xf1 },
136 { STB0899_LDT2 , 0xe3 },
137 { STB0899_EQUALREF , 0xb4 },
138 { STB0899_TMGRAMP , 0x10 },
139 { STB0899_TMGTHD , 0x30 },
140 { STB0899_IDCCOMP , 0xfd },
141 { STB0899_QDCCOMP , 0xff },
142 { STB0899_POWERI , 0x0c },
143 { STB0899_POWERQ , 0x0f },
144 { STB0899_RCOMP , 0x6c },
145 { STB0899_AGCIQIN , 0x80 },
146 { STB0899_AGC2I1 , 0x06 },
147 { STB0899_AGC2I2 , 0x00 },
148 { STB0899_TLIR , 0x30 },
149 { STB0899_RTF , 0x7f },
150 { STB0899_DSTATUS , 0x00 },
151 { STB0899_LDI , 0xbc },
152 { STB0899_CFRM , 0xea },
153 { STB0899_CFRL , 0x31 },
154 { STB0899_NIRM , 0x2b },
155 { STB0899_NIRL , 0x80 },
156 { STB0899_ISYMB , 0x1d },
157 { STB0899_QSYMB , 0xa6 },
158 { STB0899_SFRH , 0x2f },
159 { STB0899_SFRM , 0x68 },
160 { STB0899_SFRL , 0x40 },
161 { STB0899_SFRUPH , 0x2f },
162 { STB0899_SFRUPM , 0x68 },
163 { STB0899_SFRUPL , 0x40 },
164 { STB0899_EQUAI1 , 0x02 },
165 { STB0899_EQUAQ1 , 0xff },
166 { STB0899_EQUAI2 , 0x04 },
167 { STB0899_EQUAQ2 , 0x05 },
168 { STB0899_EQUAI3 , 0x02 },
169 { STB0899_EQUAQ3 , 0xfd },
170 { STB0899_EQUAI4 , 0x03 },
171 { STB0899_EQUAQ4 , 0x07 },
172 { STB0899_EQUAI5 , 0x08 },
173 { STB0899_EQUAQ5 , 0xf5 },
174 { STB0899_DSTATUS2 , 0x00 },
175 { STB0899_VSTATUS , 0x00 },
176 { STB0899_VERROR , 0x86 },
177 { STB0899_IQSWAP , 0x2a },
178 { STB0899_ECNT1M , 0x00 },
179 { STB0899_ECNT1L , 0x00 },
180 { STB0899_ECNT2M , 0x00 },
181 { STB0899_ECNT2L , 0x00 },
182 { STB0899_ECNT3M , 0x0a },
183 { STB0899_ECNT3L , 0xad },
184 { STB0899_FECAUTO1 , 0x06 },
185 { STB0899_FECM , 0x01 },
186 { STB0899_VTH12 , 0xb0 },
187 { STB0899_VTH23 , 0x7a },
188 { STB0899_VTH34 , 0x58 },
189 { STB0899_VTH56 , 0x38 },
190 { STB0899_VTH67 , 0x34 },
191 { STB0899_VTH78 , 0x24 },
192 { STB0899_PRVIT , 0xff },
193 { STB0899_VITSYNC , 0x19 },
194 { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
195 { STB0899_TSULC , 0x42 },
196 { STB0899_RSLLC , 0x41 },
197 { STB0899_TSLPL , 0x12 },
198 { STB0899_TSCFGH , 0x0c },
199 { STB0899_TSCFGM , 0x00 },
200 { STB0899_TSCFGL , 0x00 },
201 { STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */
202 { STB0899_RSSYNCDEL , 0x00 },
203 { STB0899_TSINHDELH , 0x02 },
204 { STB0899_TSINHDELM , 0x00 },
205 { STB0899_TSINHDELL , 0x00 },
206 { STB0899_TSLLSTKM , 0x1b },
207 { STB0899_TSLLSTKL , 0xb3 },
208 { STB0899_TSULSTKM , 0x00 },
209 { STB0899_TSULSTKL , 0x00 },
210 { STB0899_PCKLENUL , 0xbc },
211 { STB0899_PCKLENLL , 0xcc },
212 { STB0899_RSPCKLEN , 0xbd },
213 { STB0899_TSSTATUS , 0x90 },
214 { STB0899_ERRCTRL1 , 0xb6 },
215 { STB0899_ERRCTRL2 , 0x95 },
216 { STB0899_ERRCTRL3 , 0x8d },
217 { STB0899_DMONMSK1 , 0x27 },
218 { STB0899_DMONMSK0 , 0x03 },
219 { STB0899_DEMAPVIT , 0x5c },
220 { STB0899_PLPARM , 0x19 },
221 { STB0899_PDELCTRL , 0x48 },
222 { STB0899_PDELCTRL2 , 0x00 },
223 { STB0899_BBHCTRL1 , 0x00 },
224 { STB0899_BBHCTRL2 , 0x00 },
225 { STB0899_HYSTTHRESH , 0x77 },
226 { STB0899_MATCSTM , 0x00 },
227 { STB0899_MATCSTL , 0x00 },
228 { STB0899_UPLCSTM , 0x00 },
229 { STB0899_UPLCSTL , 0x00 },
230 { STB0899_DFLCSTM , 0x00 },
231 { STB0899_DFLCSTL , 0x00 },
232 { STB0899_SYNCCST , 0x00 },
233 { STB0899_SYNCDCSTM , 0x00 },
234 { STB0899_SYNCDCSTL , 0x00 },
235 { STB0899_ISI_ENTRY , 0x00 },
236 { STB0899_ISI_BIT_EN , 0x00 },
237 { STB0899_MATSTRM , 0xf0 },
238 { STB0899_MATSTRL , 0x02 },
239 { STB0899_UPLSTRM , 0x45 },
240 { STB0899_UPLSTRL , 0x60 },
241 { STB0899_DFLSTRM , 0xe3 },
242 { STB0899_DFLSTRL , 0x00 },
243 { STB0899_SYNCSTR , 0x47 },
244 { STB0899_SYNCDSTRM , 0x05 },
245 { STB0899_SYNCDSTRL , 0x18 },
246 { STB0899_CFGPDELSTATUS1 , 0x19 },
247 { STB0899_CFGPDELSTATUS2 , 0x2b },
248 { STB0899_BBFERRORM , 0x00 },
249 { STB0899_BBFERRORL , 0x01 },
250 { STB0899_UPKTERRORM , 0x00 },
251 { STB0899_UPKTERRORL , 0x00 },
252 { 0xffff , 0xff },
253};
254
255
256
257struct stb0899_config az6027_stb0899_config = {
258 .init_dev = az6027_stb0899_s1_init_1,
259 .init_s2_demod = stb0899_s2_init_2,
260 .init_s1_demod = az6027_stb0899_s1_init_3,
261 .init_s2_fec = stb0899_s2_init_4,
262 .init_tst = stb0899_s1_init_5,
263
264 .demod_address = 0xd0, /* 0x68, 0xd0 >> 1 */
265
266 .xtal_freq = 27000000,
267 .inversion = IQ_SWAP_ON, /* 1 */
268
269 .lo_clk = 76500000,
270 .hi_clk = 99000000,
271
272 .esno_ave = STB0899_DVBS2_ESNO_AVE,
273 .esno_quant = STB0899_DVBS2_ESNO_QUANT,
274 .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
275 .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
276 .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
277 .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
278 .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
279 .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
280 .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
281
282 .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
283 .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
284 .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
285 .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
286
287 .tuner_get_frequency = stb6100_get_frequency,
288 .tuner_set_frequency = stb6100_set_frequency,
289 .tuner_set_bandwidth = stb6100_set_bandwidth,
290 .tuner_get_bandwidth = stb6100_get_bandwidth,
291 .tuner_set_rfsiggain = NULL,
292};
293
294struct stb6100_config az6027_stb6100_config = {
295 .tuner_address = 0xc0,
296 .refclock = 27000000,
297};
298
299
300/* check for mutex FIXME */
301int az6027_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
302{
303 int ret = -1;
304 if (mutex_lock_interruptible(&d->usb_mutex))
305 return -EAGAIN;
306
307 ret = usb_control_msg(d->udev,
308 usb_rcvctrlpipe(d->udev, 0),
309 req,
310 USB_TYPE_VENDOR | USB_DIR_IN,
311 value,
312 index,
313 b,
314 blen,
315 2000);
316
317 if (ret < 0) {
318 warn("usb in operation failed. (%d)", ret);
319 ret = -EIO;
320 } else
321 ret = 0;
322
323 deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
324 debug_dump(b, blen, deb_xfer);
325
326 mutex_unlock(&d->usb_mutex);
327 return ret;
328}
329
330static int az6027_usb_out_op(struct dvb_usb_device *d,
331 u8 req,
332 u16 value,
333 u16 index,
334 u8 *b,
335 int blen)
336{
337 int ret;
338
339 deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, index);
340 debug_dump(b, blen, deb_xfer);
341
342 if (mutex_lock_interruptible(&d->usb_mutex))
343 return -EAGAIN;
344
345 ret = usb_control_msg(d->udev,
346 usb_sndctrlpipe(d->udev, 0),
347 req,
348 USB_TYPE_VENDOR | USB_DIR_OUT,
349 value,
350 index,
351 b,
352 blen,
353 2000);
354
355 if (ret != blen) {
356 warn("usb out operation failed. (%d)", ret);
357 mutex_unlock(&d->usb_mutex);
358 return -EIO;
359 } else{
360 mutex_unlock(&d->usb_mutex);
361 return 0;
362 }
363}
364
365static int az6027_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
366{
367 int ret;
368 u8 req;
369 u16 value;
370 u16 index;
371 int blen;
372
373 deb_info("%s %d", __func__, onoff);
374
375 req = 0xBC;
376 value = onoff;
377 index = 0;
378 blen = 0;
379
380 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
381 if (ret != 0)
382 warn("usb out operation failed. (%d)", ret);
383
384 return ret;
385}
386
387/* keys for the enclosed remote control */
388static struct rc_map_table rc_map_az6027_table[] = {
389 { 0x01, KEY_1 },
390 { 0x02, KEY_2 },
391};
392
393/* remote control stuff (does not work with my box) */
394static int az6027_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
395{
396 return 0;
397}
398
399/*
400int az6027_power_ctrl(struct dvb_usb_device *d, int onoff)
401{
402 u8 v = onoff;
403 return az6027_usb_out_op(d,0xBC,v,3,NULL,1);
404}
405*/
406
407static int az6027_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
408 int slot,
409 int address)
410{
411 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
412 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
413
414 int ret;
415 u8 req;
416 u16 value;
417 u16 index;
418 int blen;
419 u8 *b;
420
421 if (slot != 0)
422 return -EINVAL;
423
424 b = kmalloc(12, GFP_KERNEL);
425 if (!b)
426 return -ENOMEM;
427
428 mutex_lock(&state->ca_mutex);
429
430 req = 0xC1;
431 value = address;
432 index = 0;
433 blen = 1;
434
435 ret = az6027_usb_in_op(d, req, value, index, b, blen);
436 if (ret < 0) {
437 warn("usb in operation failed. (%d)", ret);
438 ret = -EINVAL;
439 } else {
440 ret = b[0];
441 }
442
443 mutex_unlock(&state->ca_mutex);
444 kfree(b);
445 return ret;
446}
447
448static int az6027_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
449 int slot,
450 int address,
451 u8 value)
452{
453 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
454 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
455
456 int ret;
457 u8 req;
458 u16 value1;
459 u16 index;
460 int blen;
461
462 deb_info("%s %d", __func__, slot);
463 if (slot != 0)
464 return -EINVAL;
465
466 mutex_lock(&state->ca_mutex);
467 req = 0xC2;
468 value1 = address;
469 index = value;
470 blen = 0;
471
472 ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
473 if (ret != 0)
474 warn("usb out operation failed. (%d)", ret);
475
476 mutex_unlock(&state->ca_mutex);
477 return ret;
478}
479
480static int az6027_ci_read_cam_control(struct dvb_ca_en50221 *ca,
481 int slot,
482 u8 address)
483{
484 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
485 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
486
487 int ret;
488 u8 req;
489 u16 value;
490 u16 index;
491 int blen;
492 u8 *b;
493
494 if (slot != 0)
495 return -EINVAL;
496
497 b = kmalloc(12, GFP_KERNEL);
498 if (!b)
499 return -ENOMEM;
500
501 mutex_lock(&state->ca_mutex);
502
503 req = 0xC3;
504 value = address;
505 index = 0;
506 blen = 2;
507
508 ret = az6027_usb_in_op(d, req, value, index, b, blen);
509 if (ret < 0) {
510 warn("usb in operation failed. (%d)", ret);
511 ret = -EINVAL;
512 } else {
513 if (b[0] == 0)
514 warn("Read CI IO error");
515
516 ret = b[1];
517 deb_info("read cam data = %x from 0x%x", b[1], value);
518 }
519
520 mutex_unlock(&state->ca_mutex);
521 kfree(b);
522 return ret;
523}
524
525static int az6027_ci_write_cam_control(struct dvb_ca_en50221 *ca,
526 int slot,
527 u8 address,
528 u8 value)
529{
530 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
531 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
532
533 int ret;
534 u8 req;
535 u16 value1;
536 u16 index;
537 int blen;
538
539 if (slot != 0)
540 return -EINVAL;
541
542 mutex_lock(&state->ca_mutex);
543 req = 0xC4;
544 value1 = address;
545 index = value;
546 blen = 0;
547
548 ret = az6027_usb_out_op(d, req, value1, index, NULL, blen);
549 if (ret != 0) {
550 warn("usb out operation failed. (%d)", ret);
551 goto failed;
552 }
553
554failed:
555 mutex_unlock(&state->ca_mutex);
556 return ret;
557}
558
559static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
560{
561 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
562
563 int ret;
564 u8 req;
565 u16 value;
566 u16 index;
567 int blen;
568 u8 *b;
569
570 b = kmalloc(12, GFP_KERNEL);
571 if (!b)
572 return -ENOMEM;
573
574 req = 0xC8;
575 value = 0;
576 index = 0;
577 blen = 1;
578
579 ret = az6027_usb_in_op(d, req, value, index, b, blen);
580 if (ret < 0) {
581 warn("usb in operation failed. (%d)", ret);
582 ret = -EIO;
583 } else{
584 ret = b[0];
585 }
586 kfree(b);
587 return ret;
588}
589
590static int az6027_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
591{
592 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
593 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
594
595 int ret, i;
596 u8 req;
597 u16 value;
598 u16 index;
599 int blen;
600
601 mutex_lock(&state->ca_mutex);
602
603 req = 0xC6;
604 value = 1;
605 index = 0;
606 blen = 0;
607
608 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
609 if (ret != 0) {
610 warn("usb out operation failed. (%d)", ret);
611 goto failed;
612 }
613
614 msleep(500);
615 req = 0xC6;
616 value = 0;
617 index = 0;
618 blen = 0;
619
620 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
621 if (ret != 0) {
622 warn("usb out operation failed. (%d)", ret);
623 goto failed;
624 }
625
626 for (i = 0; i < 15; i++) {
627 msleep(100);
628
629 if (CI_CamReady(ca, slot)) {
630 deb_info("CAM Ready");
631 break;
632 }
633 }
634 msleep(5000);
635
636failed:
637 mutex_unlock(&state->ca_mutex);
638 return ret;
639}
640
641static int az6027_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
642{
643 return 0;
644}
645
646static int az6027_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
647{
648 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
649 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
650
651 int ret;
652 u8 req;
653 u16 value;
654 u16 index;
655 int blen;
656
657 deb_info("%s", __func__);
658 mutex_lock(&state->ca_mutex);
659 req = 0xC7;
660 value = 1;
661 index = 0;
662 blen = 0;
663
664 ret = az6027_usb_out_op(d, req, value, index, NULL, blen);
665 if (ret != 0) {
666 warn("usb out operation failed. (%d)", ret);
667 goto failed;
668 }
669
670failed:
671 mutex_unlock(&state->ca_mutex);
672 return ret;
673}
674
675static int az6027_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
676{
677 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
678 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
679 int ret;
680 u8 req;
681 u16 value;
682 u16 index;
683 int blen;
684 u8 *b;
685
686 b = kmalloc(12, GFP_KERNEL);
687 if (!b)
688 return -ENOMEM;
689 mutex_lock(&state->ca_mutex);
690
691 req = 0xC5;
692 value = 0;
693 index = 0;
694 blen = 1;
695
696 ret = az6027_usb_in_op(d, req, value, index, b, blen);
697 if (ret < 0) {
698 warn("usb in operation failed. (%d)", ret);
699 ret = -EIO;
700 } else
701 ret = 0;
702
703 if (!ret && b[0] == 1) {
704 ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
705 DVB_CA_EN50221_POLL_CAM_READY;
706 }
707
708 mutex_unlock(&state->ca_mutex);
709 kfree(b);
710 return ret;
711}
712
713
714static void az6027_ci_uninit(struct dvb_usb_device *d)
715{
716 struct az6027_device_state *state;
717
718 deb_info("%s", __func__);
719
720 if (NULL == d)
721 return;
722
723 state = (struct az6027_device_state *)d->priv;
724 if (NULL == state)
725 return;
726
727 if (NULL == state->ca.data)
728 return;
729
730 dvb_ca_en50221_release(&state->ca);
731
732 memset(&state->ca, 0, sizeof(state->ca));
733}
734
735
736static int az6027_ci_init(struct dvb_usb_adapter *a)
737{
738 struct dvb_usb_device *d = a->dev;
739 struct az6027_device_state *state = (struct az6027_device_state *)d->priv;
740 int ret;
741
742 deb_info("%s", __func__);
743
744 mutex_init(&state->ca_mutex);
745
746 state->ca.owner = THIS_MODULE;
747 state->ca.read_attribute_mem = az6027_ci_read_attribute_mem;
748 state->ca.write_attribute_mem = az6027_ci_write_attribute_mem;
749 state->ca.read_cam_control = az6027_ci_read_cam_control;
750 state->ca.write_cam_control = az6027_ci_write_cam_control;
751 state->ca.slot_reset = az6027_ci_slot_reset;
752 state->ca.slot_shutdown = az6027_ci_slot_shutdown;
753 state->ca.slot_ts_enable = az6027_ci_slot_ts_enable;
754 state->ca.poll_slot_status = az6027_ci_poll_slot_status;
755 state->ca.data = d;
756
757 ret = dvb_ca_en50221_init(&a->dvb_adap,
758 &state->ca,
759 0, /* flags */
760 1);/* n_slots */
761 if (ret != 0) {
762 err("Cannot initialize CI: Error %d.", ret);
763 memset(&state->ca, 0, sizeof(state->ca));
764 return ret;
765 }
766
767 deb_info("CI initialized.");
768
769 return 0;
770}
771
772/*
773static int az6027_read_mac_addr(struct dvb_usb_device *d, u8 mac[6])
774{
775 az6027_usb_in_op(d, 0xb7, 6, 0, &mac[0], 6);
776 return 0;
777}
778*/
779
780static int az6027_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
781{
782
783 u8 buf;
784 struct dvb_usb_adapter *adap = fe->dvb->priv;
785
786 struct i2c_msg i2c_msg = {
787 .addr = 0x99,
788 .flags = 0,
789 .buf = &buf,
790 .len = 1
791 };
792
793 /*
794 * 2 --18v
795 * 1 --13v
796 * 0 --off
797 */
798 switch (voltage) {
799 case SEC_VOLTAGE_13:
800 buf = 1;
801 i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
802 break;
803
804 case SEC_VOLTAGE_18:
805 buf = 2;
806 i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
807 break;
808
809 case SEC_VOLTAGE_OFF:
810 buf = 0;
811 i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1);
812 break;
813
814 default:
815 return -EINVAL;
816 }
817 return 0;
818}
819
820
821static int az6027_frontend_poweron(struct dvb_usb_adapter *adap)
822{
823 int ret;
824 u8 req;
825 u16 value;
826 u16 index;
827 int blen;
828
829 req = 0xBC;
830 value = 1; /* power on */
831 index = 3;
832 blen = 0;
833
834 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
835 if (ret != 0)
836 return -EIO;
837
838 return 0;
839}
840static int az6027_frontend_reset(struct dvb_usb_adapter *adap)
841{
842 int ret;
843 u8 req;
844 u16 value;
845 u16 index;
846 int blen;
847
848 /* reset demodulator */
849 req = 0xC0;
850 value = 1; /* high */
851 index = 3;
852 blen = 0;
853
854 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
855 if (ret != 0)
856 return -EIO;
857
858 req = 0xC0;
859 value = 0; /* low */
860 index = 3;
861 blen = 0;
862 msleep_interruptible(200);
863
864 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
865 if (ret != 0)
866 return -EIO;
867
868 msleep_interruptible(200);
869
870 req = 0xC0;
871 value = 1; /*high */
872 index = 3;
873 blen = 0;
874
875 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
876 if (ret != 0)
877 return -EIO;
878
879 msleep_interruptible(200);
880 return 0;
881}
882
883static int az6027_frontend_tsbypass(struct dvb_usb_adapter *adap, int onoff)
884{
885 int ret;
886 u8 req;
887 u16 value;
888 u16 index;
889 int blen;
890
891 /* TS passthrough */
892 req = 0xC7;
893 value = onoff;
894 index = 0;
895 blen = 0;
896
897 ret = az6027_usb_out_op(adap->dev, req, value, index, NULL, blen);
898 if (ret != 0)
899 return -EIO;
900
901 return 0;
902}
903
904static int az6027_frontend_attach(struct dvb_usb_adapter *adap)
905{
906
907 az6027_frontend_poweron(adap);
908 az6027_frontend_reset(adap);
909
910 deb_info("adap = %p, dev = %p\n", adap, adap->dev);
911 adap->fe_adap[0].fe = stb0899_attach(&az6027_stb0899_config, &adap->dev->i2c_adap);
912
913 if (adap->fe_adap[0].fe) {
914 deb_info("found STB0899 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb0899_config.demod_address);
915 if (stb6100_attach(adap->fe_adap[0].fe, &az6027_stb6100_config, &adap->dev->i2c_adap)) {
916 deb_info("found STB6100 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb6100_config.tuner_address);
917 adap->fe_adap[0].fe->ops.set_voltage = az6027_set_voltage;
918 az6027_ci_init(adap);
919 } else {
920 adap->fe_adap[0].fe = NULL;
921 }
922 } else
923 warn("no front-end attached\n");
924
925 az6027_frontend_tsbypass(adap, 0);
926
927 return 0;
928}
929
930static struct dvb_usb_device_properties az6027_properties;
931
932static void az6027_usb_disconnect(struct usb_interface *intf)
933{
934 struct dvb_usb_device *d = usb_get_intfdata(intf);
935 az6027_ci_uninit(d);
936 dvb_usb_device_exit(intf);
937}
938
939
940static int az6027_usb_probe(struct usb_interface *intf,
941 const struct usb_device_id *id)
942{
943 return dvb_usb_device_init(intf,
944 &az6027_properties,
945 THIS_MODULE,
946 NULL,
947 adapter_nr);
948}
949
950/* I2C */
951static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
952{
953 struct dvb_usb_device *d = i2c_get_adapdata(adap);
954 int i = 0, j = 0, len = 0;
955 u16 index;
956 u16 value;
957 int length;
958 u8 req;
959 u8 *data;
960
961 data = kmalloc(256, GFP_KERNEL);
962 if (!data)
963 return -ENOMEM;
964
965 if (mutex_lock_interruptible(&d->i2c_mutex) < 0) {
966 kfree(data);
967 return -EAGAIN;
968 }
969
970 if (num > 2)
971 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
972
973 for (i = 0; i < num; i++) {
974
975 if (msg[i].addr == 0x99) {
976 req = 0xBE;
977 index = 0;
978 value = msg[i].buf[0] & 0x00ff;
979 length = 1;
980 az6027_usb_out_op(d, req, value, index, data, length);
981 }
982
983 if (msg[i].addr == 0xd0) {
984 /* write/read request */
985 if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
986 req = 0xB9;
987 index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
988 value = msg[i].addr + (msg[i].len << 8);
989 length = msg[i + 1].len + 6;
990 az6027_usb_in_op(d, req, value, index, data, length);
991 len = msg[i + 1].len;
992 for (j = 0; j < len; j++)
993 msg[i + 1].buf[j] = data[j + 5];
994
995 i++;
996 } else {
997
998 /* demod 16bit addr */
999 req = 0xBD;
1000 index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
1001 value = msg[i].addr + (2 << 8);
1002 length = msg[i].len - 2;
1003 len = msg[i].len - 2;
1004 for (j = 0; j < len; j++)
1005 data[j] = msg[i].buf[j + 2];
1006 az6027_usb_out_op(d, req, value, index, data, length);
1007 }
1008 }
1009
1010 if (msg[i].addr == 0xc0) {
1011 if (msg[i].flags & I2C_M_RD) {
1012
1013 req = 0xB9;
1014 index = 0x0;
1015 value = msg[i].addr;
1016 length = msg[i].len + 6;
1017 az6027_usb_in_op(d, req, value, index, data, length);
1018 len = msg[i].len;
1019 for (j = 0; j < len; j++)
1020 msg[i].buf[j] = data[j + 5];
1021
1022 } else {
1023
1024 req = 0xBD;
1025 index = msg[i].buf[0] & 0x00FF;
1026 value = msg[i].addr + (1 << 8);
1027 length = msg[i].len - 1;
1028 len = msg[i].len - 1;
1029
1030 for (j = 0; j < len; j++)
1031 data[j] = msg[i].buf[j + 1];
1032
1033 az6027_usb_out_op(d, req, value, index, data, length);
1034 }
1035 }
1036 }
1037 mutex_unlock(&d->i2c_mutex);
1038 kfree(data);
1039
1040 return i;
1041}
1042
1043
1044static u32 az6027_i2c_func(struct i2c_adapter *adapter)
1045{
1046 return I2C_FUNC_I2C;
1047}
1048
1049static struct i2c_algorithm az6027_i2c_algo = {
1050 .master_xfer = az6027_i2c_xfer,
1051 .functionality = az6027_i2c_func,
1052};
1053
1054int az6027_identify_state(struct usb_device *udev,
1055 struct dvb_usb_device_properties *props,
1056 struct dvb_usb_device_description **desc,
1057 int *cold)
1058{
1059 u8 *b;
1060 s16 ret;
1061
1062 b = kmalloc(16, GFP_KERNEL);
1063 if (!b)
1064 return -ENOMEM;
1065
1066 ret = usb_control_msg(udev,
1067 usb_rcvctrlpipe(udev, 0),
1068 0xb7,
1069 USB_TYPE_VENDOR | USB_DIR_IN,
1070 6,
1071 0,
1072 b,
1073 6,
1074 USB_CTRL_GET_TIMEOUT);
1075
1076 *cold = ret <= 0;
1077 kfree(b);
1078 deb_info("cold: %d\n", *cold);
1079 return 0;
1080}
1081
1082
1083static struct usb_device_id az6027_usb_table[] = {
1084 { USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_AZ6027) },
1085 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_DVBS2CI_V1) },
1086 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_DVBS2CI_V2) },
1087 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V1) },
1088 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_HDCI_V2) },
1089 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_SAT) },
1090 { },
1091};
1092
1093MODULE_DEVICE_TABLE(usb, az6027_usb_table);
1094
1095static struct dvb_usb_device_properties az6027_properties = {
1096 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1097 .usb_ctrl = CYPRESS_FX2,
1098 .firmware = "dvb-usb-az6027-03.fw",
1099 .no_reconnect = 1,
1100
1101 .size_of_priv = sizeof(struct az6027_device_state),
1102 .identify_state = az6027_identify_state,
1103 .num_adapters = 1,
1104 .adapter = {
1105 {
1106 .num_frontends = 1,
1107 .fe = {{
1108 .streaming_ctrl = az6027_streaming_ctrl,
1109 .frontend_attach = az6027_frontend_attach,
1110
1111 /* parameter for the MPEG2-data transfer */
1112 .stream = {
1113 .type = USB_BULK,
1114 .count = 10,
1115 .endpoint = 0x02,
1116 .u = {
1117 .bulk = {
1118 .buffersize = 4096,
1119 }
1120 }
1121 },
1122 }},
1123 }
1124 },
1125/*
1126 .power_ctrl = az6027_power_ctrl,
1127 .read_mac_address = az6027_read_mac_addr,
1128 */
1129 .rc.legacy = {
1130 .rc_map_table = rc_map_az6027_table,
1131 .rc_map_size = ARRAY_SIZE(rc_map_az6027_table),
1132 .rc_interval = 400,
1133 .rc_query = az6027_rc_query,
1134 },
1135
1136 .i2c_algo = &az6027_i2c_algo,
1137
1138 .num_device_descs = 6,
1139 .devices = {
1140 {
1141 .name = "AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)",
1142 .cold_ids = { &az6027_usb_table[0], NULL },
1143 .warm_ids = { NULL },
1144 }, {
1145 .name = "TERRATEC S7",
1146 .cold_ids = { &az6027_usb_table[1], NULL },
1147 .warm_ids = { NULL },
1148 }, {
1149 .name = "TERRATEC S7 MKII",
1150 .cold_ids = { &az6027_usb_table[2], NULL },
1151 .warm_ids = { NULL },
1152 }, {
1153 .name = "Technisat SkyStar USB 2 HD CI",
1154 .cold_ids = { &az6027_usb_table[3], NULL },
1155 .warm_ids = { NULL },
1156 }, {
1157 .name = "Technisat SkyStar USB 2 HD CI",
1158 .cold_ids = { &az6027_usb_table[4], NULL },
1159 .warm_ids = { NULL },
1160 }, {
1161 .name = "Elgato EyeTV Sat",
1162 .cold_ids = { &az6027_usb_table[5], NULL },
1163 .warm_ids = { NULL },
1164 },
1165 { NULL },
1166 }
1167};
1168
1169/* usb specific object needed to register this driver with the usb subsystem */
1170static struct usb_driver az6027_usb_driver = {
1171 .name = "dvb_usb_az6027",
1172 .probe = az6027_usb_probe,
1173 .disconnect = az6027_usb_disconnect,
1174 .id_table = az6027_usb_table,
1175};
1176
1177module_usb_driver(az6027_usb_driver);
1178
1179MODULE_AUTHOR("Adams Xu <Adams.xu@azwave.com.cn>");
1180MODULE_DESCRIPTION("Driver for AZUREWAVE DVB-S/S2 USB2.0 (AZ6027)");
1181MODULE_VERSION("1.0");
1182MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/az6027.h b/drivers/media/usb/dvb-usb/az6027.h
new file mode 100644
index 000000000000..f3afe17f3f3d
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/az6027.h
@@ -0,0 +1,14 @@
1#ifndef _DVB_USB_VP6027_H_
2#define _DVB_USB_VP6027_H_
3
4#define DVB_USB_LOG_PREFIX "az6027"
5#include "dvb-usb.h"
6
7
8extern int dvb_usb_az6027_debug;
9#define deb_info(args...) dprintk(dvb_usb_az6027_debug, 0x01, args)
10#define deb_xfer(args...) dprintk(dvb_usb_az6027_debug, 0x02, args)
11#define deb_rc(args...) dprintk(dvb_usb_az6027_debug, 0x04, args)
12#define deb_fe(args...) dprintk(dvb_usb_az6027_debug, 0x08, args)
13
14#endif
diff --git a/drivers/media/usb/dvb-usb/cinergyT2-core.c b/drivers/media/usb/dvb-usb/cinergyT2-core.c
new file mode 100644
index 000000000000..0a98548ecd17
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/cinergyT2-core.c
@@ -0,0 +1,254 @@
1/*
2 * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
3 *
4 * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
5 *
6 * Based on the dvb-usb-framework code and the
7 * original Terratec Cinergy T2 driver by:
8 *
9 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
10 * Holger Waechtler <holger@qanu.de>
11 *
12 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30#include "cinergyT2.h"
31
32
33/* debug */
34int dvb_usb_cinergyt2_debug;
35
36module_param_named(debug, dvb_usb_cinergyt2_debug, int, 0644);
37MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 "
38 "(or-able)).");
39
40DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
41
42struct cinergyt2_state {
43 u8 rc_counter;
44};
45
46/* We are missing a release hook with usb_device data */
47static struct dvb_usb_device *cinergyt2_usb_device;
48
49static struct dvb_usb_device_properties cinergyt2_properties;
50
51static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable)
52{
53 char buf[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 };
54 char result[64];
55 return dvb_usb_generic_rw(adap->dev, buf, sizeof(buf), result,
56 sizeof(result), 0);
57}
58
59static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable)
60{
61 char buf[] = { CINERGYT2_EP1_SLEEP_MODE, enable ? 0 : 1 };
62 char state[3];
63 return dvb_usb_generic_rw(d, buf, sizeof(buf), state, sizeof(state), 0);
64}
65
66static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap)
67{
68 char query[] = { CINERGYT2_EP1_GET_FIRMWARE_VERSION };
69 char state[3];
70 int ret;
71
72 adap->fe_adap[0].fe = cinergyt2_fe_attach(adap->dev);
73
74 ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query), state,
75 sizeof(state), 0);
76 if (ret < 0) {
77 deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep "
78 "state info\n");
79 }
80
81 /* Copy this pointer as we are gonna need it in the release phase */
82 cinergyt2_usb_device = adap->dev;
83
84 return 0;
85}
86
87static struct rc_map_table rc_map_cinergyt2_table[] = {
88 { 0x0401, KEY_POWER },
89 { 0x0402, KEY_1 },
90 { 0x0403, KEY_2 },
91 { 0x0404, KEY_3 },
92 { 0x0405, KEY_4 },
93 { 0x0406, KEY_5 },
94 { 0x0407, KEY_6 },
95 { 0x0408, KEY_7 },
96 { 0x0409, KEY_8 },
97 { 0x040a, KEY_9 },
98 { 0x040c, KEY_0 },
99 { 0x040b, KEY_VIDEO },
100 { 0x040d, KEY_REFRESH },
101 { 0x040e, KEY_SELECT },
102 { 0x040f, KEY_EPG },
103 { 0x0410, KEY_UP },
104 { 0x0414, KEY_DOWN },
105 { 0x0411, KEY_LEFT },
106 { 0x0413, KEY_RIGHT },
107 { 0x0412, KEY_OK },
108 { 0x0415, KEY_TEXT },
109 { 0x0416, KEY_INFO },
110 { 0x0417, KEY_RED },
111 { 0x0418, KEY_GREEN },
112 { 0x0419, KEY_YELLOW },
113 { 0x041a, KEY_BLUE },
114 { 0x041c, KEY_VOLUMEUP },
115 { 0x041e, KEY_VOLUMEDOWN },
116 { 0x041d, KEY_MUTE },
117 { 0x041b, KEY_CHANNELUP },
118 { 0x041f, KEY_CHANNELDOWN },
119 { 0x0440, KEY_PAUSE },
120 { 0x044c, KEY_PLAY },
121 { 0x0458, KEY_RECORD },
122 { 0x0454, KEY_PREVIOUS },
123 { 0x0448, KEY_STOP },
124 { 0x045c, KEY_NEXT }
125};
126
127/* Number of keypresses to ignore before detect repeating */
128#define RC_REPEAT_DELAY 3
129
130static int repeatable_keys[] = {
131 KEY_UP,
132 KEY_DOWN,
133 KEY_LEFT,
134 KEY_RIGHT,
135 KEY_VOLUMEUP,
136 KEY_VOLUMEDOWN,
137 KEY_CHANNELUP,
138 KEY_CHANNELDOWN
139};
140
141static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
142{
143 struct cinergyt2_state *st = d->priv;
144 u8 key[5] = {0, 0, 0, 0, 0}, cmd = CINERGYT2_EP1_GET_RC_EVENTS;
145 int i;
146
147 *state = REMOTE_NO_KEY_PRESSED;
148
149 dvb_usb_generic_rw(d, &cmd, 1, key, sizeof(key), 0);
150 if (key[4] == 0xff) {
151 /* key repeat */
152 st->rc_counter++;
153 if (st->rc_counter > RC_REPEAT_DELAY) {
154 for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) {
155 if (d->last_event == repeatable_keys[i]) {
156 *state = REMOTE_KEY_REPEAT;
157 *event = d->last_event;
158 deb_rc("repeat key, event %x\n",
159 *event);
160 return 0;
161 }
162 }
163 deb_rc("repeated key (non repeatable)\n");
164 }
165 return 0;
166 }
167
168 /* hack to pass checksum on the custom field */
169 key[2] = ~key[1];
170 dvb_usb_nec_rc_key_to_event(d, key, event, state);
171 if (key[0] != 0) {
172 if (*event != d->last_event)
173 st->rc_counter = 0;
174
175 deb_rc("key: %x %x %x %x %x\n",
176 key[0], key[1], key[2], key[3], key[4]);
177 }
178 return 0;
179}
180
181static int cinergyt2_usb_probe(struct usb_interface *intf,
182 const struct usb_device_id *id)
183{
184 return dvb_usb_device_init(intf, &cinergyt2_properties,
185 THIS_MODULE, NULL, adapter_nr);
186}
187
188
189static struct usb_device_id cinergyt2_usb_table[] = {
190 { USB_DEVICE(USB_VID_TERRATEC, 0x0038) },
191 { 0 }
192};
193
194MODULE_DEVICE_TABLE(usb, cinergyt2_usb_table);
195
196static struct dvb_usb_device_properties cinergyt2_properties = {
197 .size_of_priv = sizeof(struct cinergyt2_state),
198 .num_adapters = 1,
199 .adapter = {
200 {
201 .num_frontends = 1,
202 .fe = {{
203 .streaming_ctrl = cinergyt2_streaming_ctrl,
204 .frontend_attach = cinergyt2_frontend_attach,
205
206 /* parameter for the MPEG2-data transfer */
207 .stream = {
208 .type = USB_BULK,
209 .count = 5,
210 .endpoint = 0x02,
211 .u = {
212 .bulk = {
213 .buffersize = 512,
214 }
215 }
216 },
217 }},
218 }
219 },
220
221 .power_ctrl = cinergyt2_power_ctrl,
222
223 .rc.legacy = {
224 .rc_interval = 50,
225 .rc_map_table = rc_map_cinergyt2_table,
226 .rc_map_size = ARRAY_SIZE(rc_map_cinergyt2_table),
227 .rc_query = cinergyt2_rc_query,
228 },
229
230 .generic_bulk_ctrl_endpoint = 1,
231
232 .num_device_descs = 1,
233 .devices = {
234 { .name = "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver",
235 .cold_ids = {NULL},
236 .warm_ids = { &cinergyt2_usb_table[0], NULL },
237 },
238 { NULL },
239 }
240};
241
242
243static struct usb_driver cinergyt2_driver = {
244 .name = "cinergyT2",
245 .probe = cinergyt2_usb_probe,
246 .disconnect = dvb_usb_device_exit,
247 .id_table = cinergyt2_usb_table
248};
249
250module_usb_driver(cinergyt2_driver);
251
252MODULE_DESCRIPTION("Terratec Cinergy T2 DVB-T driver");
253MODULE_LICENSE("GPL");
254MODULE_AUTHOR("Tomi Orava");
diff --git a/drivers/media/usb/dvb-usb/cinergyT2-fe.c b/drivers/media/usb/dvb-usb/cinergyT2-fe.c
new file mode 100644
index 000000000000..1efc028a76c9
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/cinergyT2-fe.c
@@ -0,0 +1,356 @@
1/*
2 * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
3 *
4 * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
5 *
6 * Based on the dvb-usb-framework code and the
7 * original Terratec Cinergy T2 driver by:
8 *
9 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
10 * Holger Waechtler <holger@qanu.de>
11 *
12 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30#include "cinergyT2.h"
31
32
33/**
34 * convert linux-dvb frontend parameter set into TPS.
35 * See ETSI ETS-300744, section 4.6.2, table 9 for details.
36 *
37 * This function is probably reusable and may better get placed in a support
38 * library.
39 *
40 * We replace errornous fields by default TPS fields (the ones with value 0).
41 */
42
43static uint16_t compute_tps(struct dtv_frontend_properties *op)
44{
45 uint16_t tps = 0;
46
47 switch (op->code_rate_HP) {
48 case FEC_2_3:
49 tps |= (1 << 7);
50 break;
51 case FEC_3_4:
52 tps |= (2 << 7);
53 break;
54 case FEC_5_6:
55 tps |= (3 << 7);
56 break;
57 case FEC_7_8:
58 tps |= (4 << 7);
59 break;
60 case FEC_1_2:
61 case FEC_AUTO:
62 default:
63 /* tps |= (0 << 7) */;
64 }
65
66 switch (op->code_rate_LP) {
67 case FEC_2_3:
68 tps |= (1 << 4);
69 break;
70 case FEC_3_4:
71 tps |= (2 << 4);
72 break;
73 case FEC_5_6:
74 tps |= (3 << 4);
75 break;
76 case FEC_7_8:
77 tps |= (4 << 4);
78 break;
79 case FEC_1_2:
80 case FEC_AUTO:
81 default:
82 /* tps |= (0 << 4) */;
83 }
84
85 switch (op->modulation) {
86 case QAM_16:
87 tps |= (1 << 13);
88 break;
89 case QAM_64:
90 tps |= (2 << 13);
91 break;
92 case QPSK:
93 default:
94 /* tps |= (0 << 13) */;
95 }
96
97 switch (op->transmission_mode) {
98 case TRANSMISSION_MODE_8K:
99 tps |= (1 << 0);
100 break;
101 case TRANSMISSION_MODE_2K:
102 default:
103 /* tps |= (0 << 0) */;
104 }
105
106 switch (op->guard_interval) {
107 case GUARD_INTERVAL_1_16:
108 tps |= (1 << 2);
109 break;
110 case GUARD_INTERVAL_1_8:
111 tps |= (2 << 2);
112 break;
113 case GUARD_INTERVAL_1_4:
114 tps |= (3 << 2);
115 break;
116 case GUARD_INTERVAL_1_32:
117 default:
118 /* tps |= (0 << 2) */;
119 }
120
121 switch (op->hierarchy) {
122 case HIERARCHY_1:
123 tps |= (1 << 10);
124 break;
125 case HIERARCHY_2:
126 tps |= (2 << 10);
127 break;
128 case HIERARCHY_4:
129 tps |= (3 << 10);
130 break;
131 case HIERARCHY_NONE:
132 default:
133 /* tps |= (0 << 10) */;
134 }
135
136 return tps;
137}
138
139struct cinergyt2_fe_state {
140 struct dvb_frontend fe;
141 struct dvb_usb_device *d;
142};
143
144static int cinergyt2_fe_read_status(struct dvb_frontend *fe,
145 fe_status_t *status)
146{
147 struct cinergyt2_fe_state *state = fe->demodulator_priv;
148 struct dvbt_get_status_msg result;
149 u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
150 int ret;
151
152 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&result,
153 sizeof(result), 0);
154 if (ret < 0)
155 return ret;
156
157 *status = 0;
158
159 if (0xffff - le16_to_cpu(result.gain) > 30)
160 *status |= FE_HAS_SIGNAL;
161 if (result.lock_bits & (1 << 6))
162 *status |= FE_HAS_LOCK;
163 if (result.lock_bits & (1 << 5))
164 *status |= FE_HAS_SYNC;
165 if (result.lock_bits & (1 << 4))
166 *status |= FE_HAS_CARRIER;
167 if (result.lock_bits & (1 << 1))
168 *status |= FE_HAS_VITERBI;
169
170 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
171 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
172 *status &= ~FE_HAS_LOCK;
173
174 return 0;
175}
176
177static int cinergyt2_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
178{
179 struct cinergyt2_fe_state *state = fe->demodulator_priv;
180 struct dvbt_get_status_msg status;
181 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
182 int ret;
183
184 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
185 sizeof(status), 0);
186 if (ret < 0)
187 return ret;
188
189 *ber = le32_to_cpu(status.viterbi_error_rate);
190 return 0;
191}
192
193static int cinergyt2_fe_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
194{
195 struct cinergyt2_fe_state *state = fe->demodulator_priv;
196 struct dvbt_get_status_msg status;
197 u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
198 int ret;
199
200 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&status,
201 sizeof(status), 0);
202 if (ret < 0) {
203 err("cinergyt2_fe_read_unc_blocks() Failed! (Error=%d)\n",
204 ret);
205 return ret;
206 }
207 *unc = le32_to_cpu(status.uncorrected_block_count);
208 return 0;
209}
210
211static int cinergyt2_fe_read_signal_strength(struct dvb_frontend *fe,
212 u16 *strength)
213{
214 struct cinergyt2_fe_state *state = fe->demodulator_priv;
215 struct dvbt_get_status_msg status;
216 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
217 int ret;
218
219 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
220 sizeof(status), 0);
221 if (ret < 0) {
222 err("cinergyt2_fe_read_signal_strength() Failed!"
223 " (Error=%d)\n", ret);
224 return ret;
225 }
226 *strength = (0xffff - le16_to_cpu(status.gain));
227 return 0;
228}
229
230static int cinergyt2_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
231{
232 struct cinergyt2_fe_state *state = fe->demodulator_priv;
233 struct dvbt_get_status_msg status;
234 char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS };
235 int ret;
236
237 ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status,
238 sizeof(status), 0);
239 if (ret < 0) {
240 err("cinergyt2_fe_read_snr() Failed! (Error=%d)\n", ret);
241 return ret;
242 }
243 *snr = (status.snr << 8) | status.snr;
244 return 0;
245}
246
247static int cinergyt2_fe_init(struct dvb_frontend *fe)
248{
249 return 0;
250}
251
252static int cinergyt2_fe_sleep(struct dvb_frontend *fe)
253{
254 deb_info("cinergyt2_fe_sleep() Called\n");
255 return 0;
256}
257
258static int cinergyt2_fe_get_tune_settings(struct dvb_frontend *fe,
259 struct dvb_frontend_tune_settings *tune)
260{
261 tune->min_delay_ms = 800;
262 return 0;
263}
264
265static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe)
266{
267 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
268 struct cinergyt2_fe_state *state = fe->demodulator_priv;
269 struct dvbt_set_parameters_msg param;
270 char result[2];
271 int err;
272
273 param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
274 param.tps = cpu_to_le16(compute_tps(fep));
275 param.freq = cpu_to_le32(fep->frequency / 1000);
276 param.flags = 0;
277
278 switch (fep->bandwidth_hz) {
279 default:
280 case 8000000:
281 param.bandwidth = 8;
282 break;
283 case 7000000:
284 param.bandwidth = 7;
285 break;
286 case 6000000:
287 param.bandwidth = 6;
288 break;
289 }
290
291 err = dvb_usb_generic_rw(state->d,
292 (char *)&param, sizeof(param),
293 result, sizeof(result), 0);
294 if (err < 0)
295 err("cinergyt2_fe_set_frontend() Failed! err=%d\n", err);
296
297 return (err < 0) ? err : 0;
298}
299
300static void cinergyt2_fe_release(struct dvb_frontend *fe)
301{
302 struct cinergyt2_fe_state *state = fe->demodulator_priv;
303 if (state != NULL)
304 kfree(state);
305}
306
307static struct dvb_frontend_ops cinergyt2_fe_ops;
308
309struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d)
310{
311 struct cinergyt2_fe_state *s = kzalloc(sizeof(
312 struct cinergyt2_fe_state), GFP_KERNEL);
313 if (s == NULL)
314 return NULL;
315
316 s->d = d;
317 memcpy(&s->fe.ops, &cinergyt2_fe_ops, sizeof(struct dvb_frontend_ops));
318 s->fe.demodulator_priv = s;
319 return &s->fe;
320}
321
322
323static struct dvb_frontend_ops cinergyt2_fe_ops = {
324 .delsys = { SYS_DVBT },
325 .info = {
326 .name = DRIVER_NAME,
327 .frequency_min = 174000000,
328 .frequency_max = 862000000,
329 .frequency_stepsize = 166667,
330 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2
331 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4
332 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8
333 | FE_CAN_FEC_AUTO | FE_CAN_QPSK
334 | FE_CAN_QAM_16 | FE_CAN_QAM_64
335 | FE_CAN_QAM_AUTO
336 | FE_CAN_TRANSMISSION_MODE_AUTO
337 | FE_CAN_GUARD_INTERVAL_AUTO
338 | FE_CAN_HIERARCHY_AUTO
339 | FE_CAN_RECOVER
340 | FE_CAN_MUTE_TS
341 },
342
343 .release = cinergyt2_fe_release,
344
345 .init = cinergyt2_fe_init,
346 .sleep = cinergyt2_fe_sleep,
347
348 .set_frontend = cinergyt2_fe_set_frontend,
349 .get_tune_settings = cinergyt2_fe_get_tune_settings,
350
351 .read_status = cinergyt2_fe_read_status,
352 .read_ber = cinergyt2_fe_read_ber,
353 .read_signal_strength = cinergyt2_fe_read_signal_strength,
354 .read_snr = cinergyt2_fe_read_snr,
355 .read_ucblocks = cinergyt2_fe_read_unc_blocks,
356};
diff --git a/drivers/media/usb/dvb-usb/cinergyT2.h b/drivers/media/usb/dvb-usb/cinergyT2.h
new file mode 100644
index 000000000000..84efe03771eb
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/cinergyT2.h
@@ -0,0 +1,95 @@
1/*
2 * TerraTec Cinergy T2/qanu USB2 DVB-T adapter.
3 *
4 * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi)
5 *
6 * Based on the dvb-usb-framework code and the
7 * original Terratec Cinergy T2 driver by:
8 *
9 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
10 * Holger Waechtler <holger@qanu.de>
11 *
12 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 *
28 */
29
30#ifndef _DVB_USB_CINERGYT2_H_
31#define _DVB_USB_CINERGYT2_H_
32
33#include <linux/usb/input.h>
34
35#define DVB_USB_LOG_PREFIX "cinergyT2"
36#include "dvb-usb.h"
37
38#define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"
39
40extern int dvb_usb_cinergyt2_debug;
41
42#define deb_info(args...) dprintk(dvb_usb_cinergyt2_debug, 0x001, args)
43#define deb_xfer(args...) dprintk(dvb_usb_cinergyt2_debug, 0x002, args)
44#define deb_pll(args...) dprintk(dvb_usb_cinergyt2_debug, 0x004, args)
45#define deb_ts(args...) dprintk(dvb_usb_cinergyt2_debug, 0x008, args)
46#define deb_err(args...) dprintk(dvb_usb_cinergyt2_debug, 0x010, args)
47#define deb_rc(args...) dprintk(dvb_usb_cinergyt2_debug, 0x020, args)
48#define deb_fw(args...) dprintk(dvb_usb_cinergyt2_debug, 0x040, args)
49#define deb_mem(args...) dprintk(dvb_usb_cinergyt2_debug, 0x080, args)
50#define deb_uxfer(args...) dprintk(dvb_usb_cinergyt2_debug, 0x100, args)
51
52
53
54enum cinergyt2_ep1_cmd {
55 CINERGYT2_EP1_PID_TABLE_RESET = 0x01,
56 CINERGYT2_EP1_PID_SETUP = 0x02,
57 CINERGYT2_EP1_CONTROL_STREAM_TRANSFER = 0x03,
58 CINERGYT2_EP1_SET_TUNER_PARAMETERS = 0x04,
59 CINERGYT2_EP1_GET_TUNER_STATUS = 0x05,
60 CINERGYT2_EP1_START_SCAN = 0x06,
61 CINERGYT2_EP1_CONTINUE_SCAN = 0x07,
62 CINERGYT2_EP1_GET_RC_EVENTS = 0x08,
63 CINERGYT2_EP1_SLEEP_MODE = 0x09,
64 CINERGYT2_EP1_GET_FIRMWARE_VERSION = 0x0A
65};
66
67
68struct dvbt_get_status_msg {
69 uint32_t freq;
70 uint8_t bandwidth;
71 uint16_t tps;
72 uint8_t flags;
73 __le16 gain;
74 uint8_t snr;
75 __le32 viterbi_error_rate;
76 uint32_t rs_error_rate;
77 __le32 uncorrected_block_count;
78 uint8_t lock_bits;
79 uint8_t prev_lock_bits;
80} __attribute__((packed));
81
82
83struct dvbt_set_parameters_msg {
84 uint8_t cmd;
85 __le32 freq;
86 uint8_t bandwidth;
87 __le16 tps;
88 uint8_t flags;
89} __attribute__((packed));
90
91
92extern struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d);
93
94#endif /* _DVB_USB_CINERGYT2_H_ */
95
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
new file mode 100644
index 000000000000..3940bb0f9ef6
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -0,0 +1,2043 @@
1/* DVB USB compliant linux driver for Conexant USB reference design.
2 *
3 * The Conexant reference design I saw on their website was only for analogue
4 * capturing (using the cx25842). The box I took to write this driver (reverse
5 * engineered) is the one labeled Medion MD95700. In addition to the cx25842
6 * for analogue capturing it also has a cx22702 DVB-T demodulator on the main
7 * board. Besides it has a atiremote (X10) and a USB2.0 hub onboard.
8 *
9 * Maybe it is a little bit premature to call this driver cxusb, but I assume
10 * the USB protocol is identical or at least inherited from the reference
11 * design, so it can be reused for the "analogue-only" device (if it will
12 * appear at all).
13 *
14 * TODO: Use the cx25840-driver for the analogue part
15 *
16 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
17 * Copyright (C) 2006 Michael Krufky (mkrufky@linuxtv.org)
18 * Copyright (C) 2006, 2007 Chris Pascoe (c.pascoe@itee.uq.edu.au)
19 *
20 * This program is free software; you can redistribute it and/or modify it
21 * under the terms of the GNU General Public License as published by the Free
22 * Software Foundation, version 2.
23 *
24 * see Documentation/dvb/README.dvb-usb for more information
25 */
26#include <media/tuner.h>
27#include <linux/vmalloc.h>
28#include <linux/slab.h>
29
30#include "cxusb.h"
31
32#include "cx22702.h"
33#include "lgdt330x.h"
34#include "mt352.h"
35#include "mt352_priv.h"
36#include "zl10353.h"
37#include "tuner-xc2028.h"
38#include "tuner-simple.h"
39#include "mxl5005s.h"
40#include "max2165.h"
41#include "dib7000p.h"
42#include "dib0070.h"
43#include "lgs8gxx.h"
44#include "atbm8830.h"
45
46/* debug */
47static int dvb_usb_cxusb_debug;
48module_param_named(debug, dvb_usb_cxusb_debug, int, 0644);
49MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
50
51DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
52
53#define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args)
54#define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args)
55
56static int cxusb_ctrl_msg(struct dvb_usb_device *d,
57 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
58{
59 int wo = (rbuf == NULL || rlen == 0); /* write-only */
60 u8 sndbuf[1+wlen];
61 memset(sndbuf, 0, 1+wlen);
62
63 sndbuf[0] = cmd;
64 memcpy(&sndbuf[1], wbuf, wlen);
65 if (wo)
66 return dvb_usb_generic_write(d, sndbuf, 1+wlen);
67 else
68 return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
69}
70
71/* GPIO */
72static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff)
73{
74 struct cxusb_state *st = d->priv;
75 u8 o[2], i;
76
77 if (st->gpio_write_state[GPIO_TUNER] == onoff)
78 return;
79
80 o[0] = GPIO_TUNER;
81 o[1] = onoff;
82 cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
83
84 if (i != 0x01)
85 deb_info("gpio_write failed.\n");
86
87 st->gpio_write_state[GPIO_TUNER] = onoff;
88}
89
90static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask,
91 u8 newval)
92{
93 u8 o[2], gpio_state;
94 int rc;
95
96 o[0] = 0xff & ~changemask; /* mask of bits to keep */
97 o[1] = newval & changemask; /* new values for bits */
98
99 rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1);
100 if (rc < 0 || (gpio_state & changemask) != (newval & changemask))
101 deb_info("bluebird_gpio_write failed.\n");
102
103 return rc < 0 ? rc : gpio_state;
104}
105
106static void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low)
107{
108 cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin);
109 msleep(5);
110 cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0);
111}
112
113static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff)
114{
115 cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40);
116}
117
118static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d,
119 u8 addr, int onoff)
120{
121 u8 o[2] = {addr, onoff};
122 u8 i;
123 int rc;
124
125 rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1);
126
127 if (rc < 0)
128 return rc;
129 if (i == 0x01)
130 return 0;
131 else {
132 deb_info("gpio_write failed.\n");
133 return -EIO;
134 }
135}
136
137/* I2C */
138static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
139 int num)
140{
141 struct dvb_usb_device *d = i2c_get_adapdata(adap);
142 int i;
143
144 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
145 return -EAGAIN;
146
147 for (i = 0; i < num; i++) {
148
149 if (d->udev->descriptor.idVendor == USB_VID_MEDION)
150 switch (msg[i].addr) {
151 case 0x63:
152 cxusb_gpio_tuner(d, 0);
153 break;
154 default:
155 cxusb_gpio_tuner(d, 1);
156 break;
157 }
158
159 if (msg[i].flags & I2C_M_RD) {
160 /* read only */
161 u8 obuf[3], ibuf[1+msg[i].len];
162 obuf[0] = 0;
163 obuf[1] = msg[i].len;
164 obuf[2] = msg[i].addr;
165 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
166 obuf, 3,
167 ibuf, 1+msg[i].len) < 0) {
168 warn("i2c read failed");
169 break;
170 }
171 memcpy(msg[i].buf, &ibuf[1], msg[i].len);
172 } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) &&
173 msg[i].addr == msg[i+1].addr) {
174 /* write to then read from same address */
175 u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len];
176 obuf[0] = msg[i].len;
177 obuf[1] = msg[i+1].len;
178 obuf[2] = msg[i].addr;
179 memcpy(&obuf[3], msg[i].buf, msg[i].len);
180
181 if (cxusb_ctrl_msg(d, CMD_I2C_READ,
182 obuf, 3+msg[i].len,
183 ibuf, 1+msg[i+1].len) < 0)
184 break;
185
186 if (ibuf[0] != 0x08)
187 deb_i2c("i2c read may have failed\n");
188
189 memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len);
190
191 i++;
192 } else {
193 /* write only */
194 u8 obuf[2+msg[i].len], ibuf;
195 obuf[0] = msg[i].addr;
196 obuf[1] = msg[i].len;
197 memcpy(&obuf[2], msg[i].buf, msg[i].len);
198
199 if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf,
200 2+msg[i].len, &ibuf,1) < 0)
201 break;
202 if (ibuf != 0x08)
203 deb_i2c("i2c write may have failed\n");
204 }
205 }
206
207 mutex_unlock(&d->i2c_mutex);
208 return i == num ? num : -EREMOTEIO;
209}
210
211static u32 cxusb_i2c_func(struct i2c_adapter *adapter)
212{
213 return I2C_FUNC_I2C;
214}
215
216static struct i2c_algorithm cxusb_i2c_algo = {
217 .master_xfer = cxusb_i2c_xfer,
218 .functionality = cxusb_i2c_func,
219};
220
221static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
222{
223 u8 b = 0;
224 if (onoff)
225 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
226 else
227 return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
228}
229
230static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
231{
232 int ret;
233 if (!onoff)
234 return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0);
235 if (d->state == DVB_USB_STATE_INIT &&
236 usb_set_interface(d->udev, 0, 0) < 0)
237 err("set interface failed");
238 do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
239 !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
240 !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
241 if (!ret) {
242 /* FIXME: We don't know why, but we need to configure the
243 * lgdt3303 with the register settings below on resume */
244 int i;
245 u8 buf, bufs[] = {
246 0x0e, 0x2, 0x00, 0x7f,
247 0x0e, 0x2, 0x02, 0xfe,
248 0x0e, 0x2, 0x02, 0x01,
249 0x0e, 0x2, 0x00, 0x03,
250 0x0e, 0x2, 0x0d, 0x40,
251 0x0e, 0x2, 0x0e, 0x87,
252 0x0e, 0x2, 0x0f, 0x8e,
253 0x0e, 0x2, 0x10, 0x01,
254 0x0e, 0x2, 0x14, 0xd7,
255 0x0e, 0x2, 0x47, 0x88,
256 };
257 msleep(20);
258 for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) {
259 ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE,
260 bufs+i, 4, &buf, 1);
261 if (ret)
262 break;
263 if (buf != 0x8)
264 return -EREMOTEIO;
265 }
266 }
267 return ret;
268}
269
270static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
271{
272 u8 b = 0;
273 if (onoff)
274 return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0);
275 else
276 return 0;
277}
278
279static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff)
280{
281 int rc = 0;
282
283 rc = cxusb_power_ctrl(d, onoff);
284 if (!onoff)
285 cxusb_nano2_led(d, 0);
286
287 return rc;
288}
289
290static int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff)
291{
292 int ret;
293 u8 b;
294 ret = cxusb_power_ctrl(d, onoff);
295 if (!onoff)
296 return ret;
297
298 msleep(128);
299 cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1);
300 msleep(100);
301 return ret;
302}
303
304static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
305{
306 u8 buf[2] = { 0x03, 0x00 };
307 if (onoff)
308 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0);
309 else
310 cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0);
311
312 return 0;
313}
314
315static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
316{
317 if (onoff)
318 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0);
319 else
320 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF,
321 NULL, 0, NULL, 0);
322 return 0;
323}
324
325static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d)
326{
327 int ep = d->props.generic_bulk_ctrl_endpoint;
328 const int timeout = 100;
329 const int junk_len = 32;
330 u8 *junk;
331 int rd_count;
332
333 /* Discard remaining data in video pipe */
334 junk = kmalloc(junk_len, GFP_KERNEL);
335 if (!junk)
336 return;
337 while (1) {
338 if (usb_bulk_msg(d->udev,
339 usb_rcvbulkpipe(d->udev, ep),
340 junk, junk_len, &rd_count, timeout) < 0)
341 break;
342 if (!rd_count)
343 break;
344 }
345 kfree(junk);
346}
347
348static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d)
349{
350 struct usb_data_stream_properties *p = &d->props.adapter[0].fe[0].stream;
351 const int timeout = 100;
352 const int junk_len = p->u.bulk.buffersize;
353 u8 *junk;
354 int rd_count;
355
356 /* Discard remaining data in video pipe */
357 junk = kmalloc(junk_len, GFP_KERNEL);
358 if (!junk)
359 return;
360 while (1) {
361 if (usb_bulk_msg(d->udev,
362 usb_rcvbulkpipe(d->udev, p->endpoint),
363 junk, junk_len, &rd_count, timeout) < 0)
364 break;
365 if (!rd_count)
366 break;
367 }
368 kfree(junk);
369}
370
371static int cxusb_d680_dmb_streaming_ctrl(
372 struct dvb_usb_adapter *adap, int onoff)
373{
374 if (onoff) {
375 u8 buf[2] = { 0x03, 0x00 };
376 cxusb_d680_dmb_drain_video(adap->dev);
377 return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON,
378 buf, sizeof(buf), NULL, 0);
379 } else {
380 int ret = cxusb_ctrl_msg(adap->dev,
381 CMD_STREAMING_OFF, NULL, 0, NULL, 0);
382 return ret;
383 }
384}
385
386static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
387{
388 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
389 u8 ircode[4];
390 int i;
391
392 cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4);
393
394 *event = 0;
395 *state = REMOTE_NO_KEY_PRESSED;
396
397 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
398 if (rc5_custom(&keymap[i]) == ircode[2] &&
399 rc5_data(&keymap[i]) == ircode[3]) {
400 *event = keymap[i].keycode;
401 *state = REMOTE_KEY_PRESSED;
402
403 return 0;
404 }
405 }
406
407 return 0;
408}
409
410static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event,
411 int *state)
412{
413 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
414 u8 ircode[4];
415 int i;
416 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
417 .buf = ircode, .len = 4 };
418
419 *event = 0;
420 *state = REMOTE_NO_KEY_PRESSED;
421
422 if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1)
423 return 0;
424
425 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
426 if (rc5_custom(&keymap[i]) == ircode[1] &&
427 rc5_data(&keymap[i]) == ircode[2]) {
428 *event = keymap[i].keycode;
429 *state = REMOTE_KEY_PRESSED;
430
431 return 0;
432 }
433 }
434
435 return 0;
436}
437
438static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event,
439 int *state)
440{
441 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
442 u8 ircode[2];
443 int i;
444
445 *event = 0;
446 *state = REMOTE_NO_KEY_PRESSED;
447
448 if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0)
449 return 0;
450
451 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
452 if (rc5_custom(&keymap[i]) == ircode[0] &&
453 rc5_data(&keymap[i]) == ircode[1]) {
454 *event = keymap[i].keycode;
455 *state = REMOTE_KEY_PRESSED;
456
457 return 0;
458 }
459 }
460
461 return 0;
462}
463
464static struct rc_map_table rc_map_dvico_mce_table[] = {
465 { 0xfe02, KEY_TV },
466 { 0xfe0e, KEY_MP3 },
467 { 0xfe1a, KEY_DVD },
468 { 0xfe1e, KEY_FAVORITES },
469 { 0xfe16, KEY_SETUP },
470 { 0xfe46, KEY_POWER2 },
471 { 0xfe0a, KEY_EPG },
472 { 0xfe49, KEY_BACK },
473 { 0xfe4d, KEY_MENU },
474 { 0xfe51, KEY_UP },
475 { 0xfe5b, KEY_LEFT },
476 { 0xfe5f, KEY_RIGHT },
477 { 0xfe53, KEY_DOWN },
478 { 0xfe5e, KEY_OK },
479 { 0xfe59, KEY_INFO },
480 { 0xfe55, KEY_TAB },
481 { 0xfe0f, KEY_PREVIOUSSONG },/* Replay */
482 { 0xfe12, KEY_NEXTSONG }, /* Skip */
483 { 0xfe42, KEY_ENTER }, /* Windows/Start */
484 { 0xfe15, KEY_VOLUMEUP },
485 { 0xfe05, KEY_VOLUMEDOWN },
486 { 0xfe11, KEY_CHANNELUP },
487 { 0xfe09, KEY_CHANNELDOWN },
488 { 0xfe52, KEY_CAMERA },
489 { 0xfe5a, KEY_TUNER }, /* Live */
490 { 0xfe19, KEY_OPEN },
491 { 0xfe0b, KEY_1 },
492 { 0xfe17, KEY_2 },
493 { 0xfe1b, KEY_3 },
494 { 0xfe07, KEY_4 },
495 { 0xfe50, KEY_5 },
496 { 0xfe54, KEY_6 },
497 { 0xfe48, KEY_7 },
498 { 0xfe4c, KEY_8 },
499 { 0xfe58, KEY_9 },
500 { 0xfe13, KEY_ANGLE }, /* Aspect */
501 { 0xfe03, KEY_0 },
502 { 0xfe1f, KEY_ZOOM },
503 { 0xfe43, KEY_REWIND },
504 { 0xfe47, KEY_PLAYPAUSE },
505 { 0xfe4f, KEY_FASTFORWARD },
506 { 0xfe57, KEY_MUTE },
507 { 0xfe0d, KEY_STOP },
508 { 0xfe01, KEY_RECORD },
509 { 0xfe4e, KEY_POWER },
510};
511
512static struct rc_map_table rc_map_dvico_portable_table[] = {
513 { 0xfc02, KEY_SETUP }, /* Profile */
514 { 0xfc43, KEY_POWER2 },
515 { 0xfc06, KEY_EPG },
516 { 0xfc5a, KEY_BACK },
517 { 0xfc05, KEY_MENU },
518 { 0xfc47, KEY_INFO },
519 { 0xfc01, KEY_TAB },
520 { 0xfc42, KEY_PREVIOUSSONG },/* Replay */
521 { 0xfc49, KEY_VOLUMEUP },
522 { 0xfc09, KEY_VOLUMEDOWN },
523 { 0xfc54, KEY_CHANNELUP },
524 { 0xfc0b, KEY_CHANNELDOWN },
525 { 0xfc16, KEY_CAMERA },
526 { 0xfc40, KEY_TUNER }, /* ATV/DTV */
527 { 0xfc45, KEY_OPEN },
528 { 0xfc19, KEY_1 },
529 { 0xfc18, KEY_2 },
530 { 0xfc1b, KEY_3 },
531 { 0xfc1a, KEY_4 },
532 { 0xfc58, KEY_5 },
533 { 0xfc59, KEY_6 },
534 { 0xfc15, KEY_7 },
535 { 0xfc14, KEY_8 },
536 { 0xfc17, KEY_9 },
537 { 0xfc44, KEY_ANGLE }, /* Aspect */
538 { 0xfc55, KEY_0 },
539 { 0xfc07, KEY_ZOOM },
540 { 0xfc0a, KEY_REWIND },
541 { 0xfc08, KEY_PLAYPAUSE },
542 { 0xfc4b, KEY_FASTFORWARD },
543 { 0xfc5b, KEY_MUTE },
544 { 0xfc04, KEY_STOP },
545 { 0xfc56, KEY_RECORD },
546 { 0xfc57, KEY_POWER },
547 { 0xfc41, KEY_UNKNOWN }, /* INPUT */
548 { 0xfc00, KEY_UNKNOWN }, /* HD */
549};
550
551static struct rc_map_table rc_map_d680_dmb_table[] = {
552 { 0x0038, KEY_UNKNOWN }, /* TV/AV */
553 { 0x080c, KEY_ZOOM },
554 { 0x0800, KEY_0 },
555 { 0x0001, KEY_1 },
556 { 0x0802, KEY_2 },
557 { 0x0003, KEY_3 },
558 { 0x0804, KEY_4 },
559 { 0x0005, KEY_5 },
560 { 0x0806, KEY_6 },
561 { 0x0007, KEY_7 },
562 { 0x0808, KEY_8 },
563 { 0x0009, KEY_9 },
564 { 0x000a, KEY_MUTE },
565 { 0x0829, KEY_BACK },
566 { 0x0012, KEY_CHANNELUP },
567 { 0x0813, KEY_CHANNELDOWN },
568 { 0x002b, KEY_VOLUMEUP },
569 { 0x082c, KEY_VOLUMEDOWN },
570 { 0x0020, KEY_UP },
571 { 0x0821, KEY_DOWN },
572 { 0x0011, KEY_LEFT },
573 { 0x0810, KEY_RIGHT },
574 { 0x000d, KEY_OK },
575 { 0x081f, KEY_RECORD },
576 { 0x0017, KEY_PLAYPAUSE },
577 { 0x0816, KEY_PLAYPAUSE },
578 { 0x000b, KEY_STOP },
579 { 0x0827, KEY_FASTFORWARD },
580 { 0x0026, KEY_REWIND },
581 { 0x081e, KEY_UNKNOWN }, /* Time Shift */
582 { 0x000e, KEY_UNKNOWN }, /* Snapshot */
583 { 0x082d, KEY_UNKNOWN }, /* Mouse Cursor */
584 { 0x000f, KEY_UNKNOWN }, /* Minimize/Maximize */
585 { 0x0814, KEY_UNKNOWN }, /* Shuffle */
586 { 0x0025, KEY_POWER },
587};
588
589static int cxusb_dee1601_demod_init(struct dvb_frontend* fe)
590{
591 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 };
592 static u8 reset [] = { RESET, 0x80 };
593 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
594 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
595 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
596 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
597
598 mt352_write(fe, clock_config, sizeof(clock_config));
599 udelay(200);
600 mt352_write(fe, reset, sizeof(reset));
601 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
602
603 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
604 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
605 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
606
607 return 0;
608}
609
610static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
611{ /* used in both lgz201 and th7579 */
612 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x29 };
613 static u8 reset [] = { RESET, 0x80 };
614 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
615 static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
616 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
617 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
618
619 mt352_write(fe, clock_config, sizeof(clock_config));
620 udelay(200);
621 mt352_write(fe, reset, sizeof(reset));
622 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
623
624 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
625 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
626 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
627 return 0;
628}
629
630static struct cx22702_config cxusb_cx22702_config = {
631 .demod_address = 0x63,
632 .output_mode = CX22702_PARALLEL_OUTPUT,
633};
634
635static struct lgdt330x_config cxusb_lgdt3303_config = {
636 .demod_address = 0x0e,
637 .demod_chip = LGDT3303,
638};
639
640static struct lgdt330x_config cxusb_aver_lgdt3303_config = {
641 .demod_address = 0x0e,
642 .demod_chip = LGDT3303,
643 .clock_polarity_flip = 2,
644};
645
646static struct mt352_config cxusb_dee1601_config = {
647 .demod_address = 0x0f,
648 .demod_init = cxusb_dee1601_demod_init,
649};
650
651static struct zl10353_config cxusb_zl10353_dee1601_config = {
652 .demod_address = 0x0f,
653 .parallel_ts = 1,
654};
655
656static struct mt352_config cxusb_mt352_config = {
657 /* used in both lgz201 and th7579 */
658 .demod_address = 0x0f,
659 .demod_init = cxusb_mt352_demod_init,
660};
661
662static struct zl10353_config cxusb_zl10353_xc3028_config = {
663 .demod_address = 0x0f,
664 .if2 = 45600,
665 .no_tuner = 1,
666 .parallel_ts = 1,
667};
668
669static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = {
670 .demod_address = 0x0f,
671 .if2 = 45600,
672 .no_tuner = 1,
673 .parallel_ts = 1,
674 .disable_i2c_gate_ctrl = 1,
675};
676
677static struct mt352_config cxusb_mt352_xc3028_config = {
678 .demod_address = 0x0f,
679 .if2 = 4560,
680 .no_tuner = 1,
681 .demod_init = cxusb_mt352_demod_init,
682};
683
684/* FIXME: needs tweaking */
685static struct mxl5005s_config aver_a868r_tuner = {
686 .i2c_address = 0x63,
687 .if_freq = 6000000UL,
688 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
689 .agc_mode = MXL_SINGLE_AGC,
690 .tracking_filter = MXL_TF_C,
691 .rssi_enable = MXL_RSSI_ENABLE,
692 .cap_select = MXL_CAP_SEL_ENABLE,
693 .div_out = MXL_DIV_OUT_4,
694 .clock_out = MXL_CLOCK_OUT_DISABLE,
695 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
696 .top = MXL5005S_TOP_25P2,
697 .mod_mode = MXL_DIGITAL_MODE,
698 .if_mode = MXL_ZERO_IF,
699 .AgcMasterByte = 0x00,
700};
701
702/* FIXME: needs tweaking */
703static struct mxl5005s_config d680_dmb_tuner = {
704 .i2c_address = 0x63,
705 .if_freq = 36125000UL,
706 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
707 .agc_mode = MXL_SINGLE_AGC,
708 .tracking_filter = MXL_TF_C,
709 .rssi_enable = MXL_RSSI_ENABLE,
710 .cap_select = MXL_CAP_SEL_ENABLE,
711 .div_out = MXL_DIV_OUT_4,
712 .clock_out = MXL_CLOCK_OUT_DISABLE,
713 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
714 .top = MXL5005S_TOP_25P2,
715 .mod_mode = MXL_DIGITAL_MODE,
716 .if_mode = MXL_ZERO_IF,
717 .AgcMasterByte = 0x00,
718};
719
720static struct max2165_config mygica_d689_max2165_cfg = {
721 .i2c_address = 0x60,
722 .osc_clk = 20
723};
724
725/* Callbacks for DVB USB */
726static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
727{
728 dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
729 &adap->dev->i2c_adap, 0x61,
730 TUNER_PHILIPS_FMD1216ME_MK3);
731 return 0;
732}
733
734static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap)
735{
736 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61,
737 NULL, DVB_PLL_THOMSON_DTT7579);
738 return 0;
739}
740
741static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap)
742{
743 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_LG_Z201);
744 return 0;
745}
746
747static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap)
748{
749 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
750 NULL, DVB_PLL_THOMSON_DTT7579);
751 return 0;
752}
753
754static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap)
755{
756 dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
757 &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF);
758 return 0;
759}
760
761static int dvico_bluebird_xc2028_callback(void *ptr, int component,
762 int command, int arg)
763{
764 struct dvb_usb_adapter *adap = ptr;
765 struct dvb_usb_device *d = adap->dev;
766
767 switch (command) {
768 case XC2028_TUNER_RESET:
769 deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg);
770 cxusb_bluebird_gpio_pulse(d, 0x01, 1);
771 break;
772 case XC2028_RESET_CLK:
773 deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
774 break;
775 default:
776 deb_info("%s: unknown command %d, arg %d\n", __func__,
777 command, arg);
778 return -EINVAL;
779 }
780
781 return 0;
782}
783
784static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
785{
786 struct dvb_frontend *fe;
787 struct xc2028_config cfg = {
788 .i2c_adap = &adap->dev->i2c_adap,
789 .i2c_addr = 0x61,
790 };
791 static struct xc2028_ctrl ctl = {
792 .fname = XC2028_DEFAULT_FIRMWARE,
793 .max_len = 64,
794 .demod = XC3028_FE_ZARLINK456,
795 };
796
797 /* FIXME: generalize & move to common area */
798 adap->fe_adap[0].fe->callback = dvico_bluebird_xc2028_callback;
799
800 fe = dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &cfg);
801 if (fe == NULL || fe->ops.tuner_ops.set_config == NULL)
802 return -EIO;
803
804 fe->ops.tuner_ops.set_config(fe, &ctl);
805
806 return 0;
807}
808
809static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
810{
811 dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
812 &adap->dev->i2c_adap, &aver_a868r_tuner);
813 return 0;
814}
815
816static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap)
817{
818 struct dvb_frontend *fe;
819 fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe,
820 &adap->dev->i2c_adap, &d680_dmb_tuner);
821 return (fe == NULL) ? -EIO : 0;
822}
823
824static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap)
825{
826 struct dvb_frontend *fe;
827 fe = dvb_attach(max2165_attach, adap->fe_adap[0].fe,
828 &adap->dev->i2c_adap, &mygica_d689_max2165_cfg);
829 return (fe == NULL) ? -EIO : 0;
830}
831
832static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
833{
834 u8 b;
835 if (usb_set_interface(adap->dev->udev, 0, 6) < 0)
836 err("set interface failed");
837
838 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1);
839
840 adap->fe_adap[0].fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config,
841 &adap->dev->i2c_adap);
842 if ((adap->fe_adap[0].fe) != NULL)
843 return 0;
844
845 return -EIO;
846}
847
848static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
849{
850 if (usb_set_interface(adap->dev->udev, 0, 7) < 0)
851 err("set interface failed");
852
853 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
854
855 adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach,
856 &cxusb_lgdt3303_config,
857 &adap->dev->i2c_adap);
858 if ((adap->fe_adap[0].fe) != NULL)
859 return 0;
860
861 return -EIO;
862}
863
864static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
865{
866 adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
867 &adap->dev->i2c_adap);
868 if (adap->fe_adap[0].fe != NULL)
869 return 0;
870
871 return -EIO;
872}
873
874static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
875{
876 /* used in both lgz201 and th7579 */
877 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
878 err("set interface failed");
879
880 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
881
882 adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_mt352_config,
883 &adap->dev->i2c_adap);
884 if ((adap->fe_adap[0].fe) != NULL)
885 return 0;
886
887 return -EIO;
888}
889
890static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap)
891{
892 if (usb_set_interface(adap->dev->udev, 0, 0) < 0)
893 err("set interface failed");
894
895 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
896
897 adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_dee1601_config,
898 &adap->dev->i2c_adap);
899 if ((adap->fe_adap[0].fe) != NULL)
900 return 0;
901
902 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
903 &cxusb_zl10353_dee1601_config,
904 &adap->dev->i2c_adap);
905 if ((adap->fe_adap[0].fe) != NULL)
906 return 0;
907
908 return -EIO;
909}
910
911static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
912{
913 u8 ircode[4];
914 int i;
915 struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD,
916 .buf = ircode, .len = 4 };
917
918 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
919 err("set interface failed");
920
921 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
922
923 /* reset the tuner and demodulator */
924 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
925 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
926 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
927
928 adap->fe_adap[0].fe =
929 dvb_attach(zl10353_attach,
930 &cxusb_zl10353_xc3028_config_no_i2c_gate,
931 &adap->dev->i2c_adap);
932 if ((adap->fe_adap[0].fe) == NULL)
933 return -EIO;
934
935 /* try to determine if there is no IR decoder on the I2C bus */
936 for (i = 0; adap->dev->props.rc.legacy.rc_map_table != NULL && i < 5; i++) {
937 msleep(20);
938 if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1)
939 goto no_IR;
940 if (ircode[0] == 0 && ircode[1] == 0)
941 continue;
942 if (ircode[2] + ircode[3] != 0xff) {
943no_IR:
944 adap->dev->props.rc.legacy.rc_map_table = NULL;
945 info("No IR receiver detected on this device.");
946 break;
947 }
948 }
949
950 return 0;
951}
952
953static struct dibx000_agc_config dib7070_agc_config = {
954 .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
955
956 /*
957 * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5,
958 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
959 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0
960 */
961 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) |
962 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
963 .inv_gain = 600,
964 .time_stabiliz = 10,
965 .alpha_level = 0,
966 .thlock = 118,
967 .wbd_inv = 0,
968 .wbd_ref = 3530,
969 .wbd_sel = 1,
970 .wbd_alpha = 5,
971 .agc1_max = 65535,
972 .agc1_min = 0,
973 .agc2_max = 65535,
974 .agc2_min = 0,
975 .agc1_pt1 = 0,
976 .agc1_pt2 = 40,
977 .agc1_pt3 = 183,
978 .agc1_slope1 = 206,
979 .agc1_slope2 = 255,
980 .agc2_pt1 = 72,
981 .agc2_pt2 = 152,
982 .agc2_slope1 = 88,
983 .agc2_slope2 = 90,
984 .alpha_mant = 17,
985 .alpha_exp = 27,
986 .beta_mant = 23,
987 .beta_exp = 51,
988 .perform_agc_softsplit = 0,
989};
990
991static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
992 .internal = 60000,
993 .sampling = 15000,
994 .pll_prediv = 1,
995 .pll_ratio = 20,
996 .pll_range = 3,
997 .pll_reset = 1,
998 .pll_bypass = 0,
999 .enable_refdiv = 0,
1000 .bypclk_div = 0,
1001 .IO_CLK_en_core = 1,
1002 .ADClkSrc = 1,
1003 .modulo = 2,
1004 /* refsel, sel, freq_15k */
1005 .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0),
1006 .ifreq = (0 << 25) | 0,
1007 .timf = 20452225,
1008 .xtal_hz = 12000000,
1009};
1010
1011static struct dib7000p_config cxusb_dualdig4_rev2_config = {
1012 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
1013 .output_mpeg2_in_188_bytes = 1,
1014
1015 .agc_config_count = 1,
1016 .agc = &dib7070_agc_config,
1017 .bw = &dib7070_bw_config_12_mhz,
1018 .tuner_is_baseband = 1,
1019 .spur_protect = 1,
1020
1021 .gpio_dir = 0xfcef,
1022 .gpio_val = 0x0110,
1023
1024 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
1025
1026 .hostbus_diversity = 1,
1027};
1028
1029static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap)
1030{
1031 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1032 err("set interface failed");
1033
1034 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1035
1036 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1037
1038 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1039 &cxusb_dualdig4_rev2_config) < 0) {
1040 printk(KERN_WARNING "Unable to enumerate dib7000p\n");
1041 return -ENODEV;
1042 }
1043
1044 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1045 &cxusb_dualdig4_rev2_config);
1046 if (adap->fe_adap[0].fe == NULL)
1047 return -EIO;
1048
1049 return 0;
1050}
1051
1052static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1053{
1054 return dib7000p_set_gpio(fe, 8, 0, !onoff);
1055}
1056
1057static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1058{
1059 return 0;
1060}
1061
1062static struct dib0070_config dib7070p_dib0070_config = {
1063 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1064 .reset = dib7070_tuner_reset,
1065 .sleep = dib7070_tuner_sleep,
1066 .clock_khz = 12000,
1067};
1068
1069struct dib0700_adapter_state {
1070 int (*set_param_save) (struct dvb_frontend *);
1071};
1072
1073static int dib7070_set_param_override(struct dvb_frontend *fe)
1074{
1075 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1076 struct dvb_usb_adapter *adap = fe->dvb->priv;
1077 struct dib0700_adapter_state *state = adap->priv;
1078
1079 u16 offset;
1080 u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
1081 switch (band) {
1082 case BAND_VHF: offset = 950; break;
1083 default:
1084 case BAND_UHF: offset = 550; break;
1085 }
1086
1087 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1088
1089 return state->set_param_save(fe);
1090}
1091
1092static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap)
1093{
1094 struct dib0700_adapter_state *st = adap->priv;
1095 struct i2c_adapter *tun_i2c =
1096 dib7000p_get_i2c_master(adap->fe_adap[0].fe,
1097 DIBX000_I2C_INTERFACE_TUNER, 1);
1098
1099 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
1100 &dib7070p_dib0070_config) == NULL)
1101 return -ENODEV;
1102
1103 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
1104 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override;
1105 return 0;
1106}
1107
1108static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap)
1109{
1110 if (usb_set_interface(adap->dev->udev, 0, 1) < 0)
1111 err("set interface failed");
1112
1113 cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0);
1114
1115 /* reset the tuner and demodulator */
1116 cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0);
1117 cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1);
1118 cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
1119
1120 adap->fe_adap[0].fe = dvb_attach(zl10353_attach,
1121 &cxusb_zl10353_xc3028_config,
1122 &adap->dev->i2c_adap);
1123 if ((adap->fe_adap[0].fe) != NULL)
1124 return 0;
1125
1126 adap->fe_adap[0].fe = dvb_attach(mt352_attach,
1127 &cxusb_mt352_xc3028_config,
1128 &adap->dev->i2c_adap);
1129 if ((adap->fe_adap[0].fe) != NULL)
1130 return 0;
1131
1132 return -EIO;
1133}
1134
1135static struct lgs8gxx_config d680_lgs8gl5_cfg = {
1136 .prod = LGS8GXX_PROD_LGS8GL5,
1137 .demod_address = 0x19,
1138 .serial_ts = 0,
1139 .ts_clk_pol = 0,
1140 .ts_clk_gated = 1,
1141 .if_clk_freq = 30400, /* 30.4 MHz */
1142 .if_freq = 5725, /* 5.725 MHz */
1143 .if_neg_center = 0,
1144 .ext_adc = 0,
1145 .adc_signed = 0,
1146 .if_neg_edge = 0,
1147};
1148
1149static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap)
1150{
1151 struct dvb_usb_device *d = adap->dev;
1152 int n;
1153
1154 /* Select required USB configuration */
1155 if (usb_set_interface(d->udev, 0, 0) < 0)
1156 err("set interface failed");
1157
1158 /* Unblock all USB pipes */
1159 usb_clear_halt(d->udev,
1160 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1161 usb_clear_halt(d->udev,
1162 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1163 usb_clear_halt(d->udev,
1164 usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
1165
1166 /* Drain USB pipes to avoid hang after reboot */
1167 for (n = 0; n < 5; n++) {
1168 cxusb_d680_dmb_drain_message(d);
1169 cxusb_d680_dmb_drain_video(d);
1170 msleep(200);
1171 }
1172
1173 /* Reset the tuner */
1174 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1175 err("clear tuner gpio failed");
1176 return -EIO;
1177 }
1178 msleep(100);
1179 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1180 err("set tuner gpio failed");
1181 return -EIO;
1182 }
1183 msleep(100);
1184
1185 /* Attach frontend */
1186 adap->fe_adap[0].fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap);
1187 if (adap->fe_adap[0].fe == NULL)
1188 return -EIO;
1189
1190 return 0;
1191}
1192
1193static struct atbm8830_config mygica_d689_atbm8830_cfg = {
1194 .prod = ATBM8830_PROD_8830,
1195 .demod_address = 0x40,
1196 .serial_ts = 0,
1197 .ts_sampling_edge = 1,
1198 .ts_clk_gated = 0,
1199 .osc_clk_freq = 30400, /* in kHz */
1200 .if_freq = 0, /* zero IF */
1201 .zif_swap_iq = 1,
1202 .agc_min = 0x2E,
1203 .agc_max = 0x90,
1204 .agc_hold_loop = 0,
1205};
1206
1207static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap)
1208{
1209 struct dvb_usb_device *d = adap->dev;
1210
1211 /* Select required USB configuration */
1212 if (usb_set_interface(d->udev, 0, 0) < 0)
1213 err("set interface failed");
1214
1215 /* Unblock all USB pipes */
1216 usb_clear_halt(d->udev,
1217 usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1218 usb_clear_halt(d->udev,
1219 usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
1220 usb_clear_halt(d->udev,
1221 usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint));
1222
1223
1224 /* Reset the tuner */
1225 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) {
1226 err("clear tuner gpio failed");
1227 return -EIO;
1228 }
1229 msleep(100);
1230 if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) {
1231 err("set tuner gpio failed");
1232 return -EIO;
1233 }
1234 msleep(100);
1235
1236 /* Attach frontend */
1237 adap->fe_adap[0].fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg,
1238 &d->i2c_adap);
1239 if (adap->fe_adap[0].fe == NULL)
1240 return -EIO;
1241
1242 return 0;
1243}
1244
1245/*
1246 * DViCO has shipped two devices with the same USB ID, but only one of them
1247 * needs a firmware download. Check the device class details to see if they
1248 * have non-default values to decide whether the device is actually cold or
1249 * not, and forget a match if it turns out we selected the wrong device.
1250 */
1251static int bluebird_fx2_identify_state(struct usb_device *udev,
1252 struct dvb_usb_device_properties *props,
1253 struct dvb_usb_device_description **desc,
1254 int *cold)
1255{
1256 int wascold = *cold;
1257
1258 *cold = udev->descriptor.bDeviceClass == 0xff &&
1259 udev->descriptor.bDeviceSubClass == 0xff &&
1260 udev->descriptor.bDeviceProtocol == 0xff;
1261
1262 if (*cold && !wascold)
1263 *desc = NULL;
1264
1265 return 0;
1266}
1267
1268/*
1269 * DViCO bluebird firmware needs the "warm" product ID to be patched into the
1270 * firmware file before download.
1271 */
1272
1273static const int dvico_firmware_id_offsets[] = { 6638, 3204 };
1274static int bluebird_patch_dvico_firmware_download(struct usb_device *udev,
1275 const struct firmware *fw)
1276{
1277 int pos;
1278
1279 for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) {
1280 int idoff = dvico_firmware_id_offsets[pos];
1281
1282 if (fw->size < idoff + 4)
1283 continue;
1284
1285 if (fw->data[idoff] == (USB_VID_DVICO & 0xff) &&
1286 fw->data[idoff + 1] == USB_VID_DVICO >> 8) {
1287 struct firmware new_fw;
1288 u8 *new_fw_data = vmalloc(fw->size);
1289 int ret;
1290
1291 if (!new_fw_data)
1292 return -ENOMEM;
1293
1294 memcpy(new_fw_data, fw->data, fw->size);
1295 new_fw.size = fw->size;
1296 new_fw.data = new_fw_data;
1297
1298 new_fw_data[idoff + 2] =
1299 le16_to_cpu(udev->descriptor.idProduct) + 1;
1300 new_fw_data[idoff + 3] =
1301 le16_to_cpu(udev->descriptor.idProduct) >> 8;
1302
1303 ret = usb_cypress_load_firmware(udev, &new_fw,
1304 CYPRESS_FX2);
1305 vfree(new_fw_data);
1306 return ret;
1307 }
1308 }
1309
1310 return -EINVAL;
1311}
1312
1313/* DVB USB Driver stuff */
1314static struct dvb_usb_device_properties cxusb_medion_properties;
1315static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties;
1316static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties;
1317static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties;
1318static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
1319static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
1320static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties;
1321static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
1322static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
1323static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
1324static struct dvb_usb_device_properties cxusb_d680_dmb_properties;
1325static struct dvb_usb_device_properties cxusb_mygica_d689_properties;
1326
1327static int cxusb_probe(struct usb_interface *intf,
1328 const struct usb_device_id *id)
1329{
1330 if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties,
1331 THIS_MODULE, NULL, adapter_nr) ||
1332 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties,
1333 THIS_MODULE, NULL, adapter_nr) ||
1334 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties,
1335 THIS_MODULE, NULL, adapter_nr) ||
1336 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties,
1337 THIS_MODULE, NULL, adapter_nr) ||
1338 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties,
1339 THIS_MODULE, NULL, adapter_nr) ||
1340 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties,
1341 THIS_MODULE, NULL, adapter_nr) ||
1342 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties,
1343 THIS_MODULE, NULL, adapter_nr) ||
1344 0 == dvb_usb_device_init(intf,
1345 &cxusb_bluebird_nano2_needsfirmware_properties,
1346 THIS_MODULE, NULL, adapter_nr) ||
1347 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
1348 THIS_MODULE, NULL, adapter_nr) ||
1349 0 == dvb_usb_device_init(intf,
1350 &cxusb_bluebird_dualdig4_rev2_properties,
1351 THIS_MODULE, NULL, adapter_nr) ||
1352 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties,
1353 THIS_MODULE, NULL, adapter_nr) ||
1354 0 == dvb_usb_device_init(intf, &cxusb_mygica_d689_properties,
1355 THIS_MODULE, NULL, adapter_nr) ||
1356 0)
1357 return 0;
1358
1359 return -EINVAL;
1360}
1361
1362static struct usb_device_id cxusb_table [] = {
1363 { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) },
1364 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) },
1365 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) },
1366 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) },
1367 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) },
1368 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) },
1369 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) },
1370 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) },
1371 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) },
1372 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) },
1373 { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) },
1374 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) },
1375 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) },
1376 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
1377 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
1378 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
1379 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
1380 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) },
1381 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) },
1382 { USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_D689) },
1383 {} /* Terminating entry */
1384};
1385MODULE_DEVICE_TABLE (usb, cxusb_table);
1386
1387static struct dvb_usb_device_properties cxusb_medion_properties = {
1388 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1389
1390 .usb_ctrl = CYPRESS_FX2,
1391
1392 .size_of_priv = sizeof(struct cxusb_state),
1393
1394 .num_adapters = 1,
1395 .adapter = {
1396 {
1397 .num_frontends = 1,
1398 .fe = {{
1399 .streaming_ctrl = cxusb_streaming_ctrl,
1400 .frontend_attach = cxusb_cx22702_frontend_attach,
1401 .tuner_attach = cxusb_fmd1216me_tuner_attach,
1402 /* parameter for the MPEG2-data transfer */
1403 .stream = {
1404 .type = USB_BULK,
1405 .count = 5,
1406 .endpoint = 0x02,
1407 .u = {
1408 .bulk = {
1409 .buffersize = 8192,
1410 }
1411 }
1412 },
1413 }},
1414 },
1415 },
1416 .power_ctrl = cxusb_power_ctrl,
1417
1418 .i2c_algo = &cxusb_i2c_algo,
1419
1420 .generic_bulk_ctrl_endpoint = 0x01,
1421
1422 .num_device_descs = 1,
1423 .devices = {
1424 { "Medion MD95700 (MDUSBTV-HYBRID)",
1425 { NULL },
1426 { &cxusb_table[0], NULL },
1427 },
1428 }
1429};
1430
1431static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = {
1432 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1433
1434 .usb_ctrl = DEVICE_SPECIFIC,
1435 .firmware = "dvb-usb-bluebird-01.fw",
1436 .download_firmware = bluebird_patch_dvico_firmware_download,
1437 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1438 use usb alt setting 7 for EP2 transfer (atsc) */
1439
1440 .size_of_priv = sizeof(struct cxusb_state),
1441
1442 .num_adapters = 1,
1443 .adapter = {
1444 {
1445 .num_frontends = 1,
1446 .fe = {{
1447 .streaming_ctrl = cxusb_streaming_ctrl,
1448 .frontend_attach = cxusb_lgdt3303_frontend_attach,
1449 .tuner_attach = cxusb_lgh064f_tuner_attach,
1450
1451 /* parameter for the MPEG2-data transfer */
1452 .stream = {
1453 .type = USB_BULK,
1454 .count = 5,
1455 .endpoint = 0x02,
1456 .u = {
1457 .bulk = {
1458 .buffersize = 8192,
1459 }
1460 }
1461 },
1462 }},
1463 },
1464 },
1465
1466 .power_ctrl = cxusb_bluebird_power_ctrl,
1467
1468 .i2c_algo = &cxusb_i2c_algo,
1469
1470 .rc.legacy = {
1471 .rc_interval = 100,
1472 .rc_map_table = rc_map_dvico_portable_table,
1473 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1474 .rc_query = cxusb_rc_query,
1475 },
1476
1477 .generic_bulk_ctrl_endpoint = 0x01,
1478
1479 .num_device_descs = 1,
1480 .devices = {
1481 { "DViCO FusionHDTV5 USB Gold",
1482 { &cxusb_table[1], NULL },
1483 { &cxusb_table[2], NULL },
1484 },
1485 }
1486};
1487
1488static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = {
1489 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1490
1491 .usb_ctrl = DEVICE_SPECIFIC,
1492 .firmware = "dvb-usb-bluebird-01.fw",
1493 .download_firmware = bluebird_patch_dvico_firmware_download,
1494 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1495 use usb alt setting 7 for EP2 transfer (atsc) */
1496
1497 .size_of_priv = sizeof(struct cxusb_state),
1498
1499 .num_adapters = 1,
1500 .adapter = {
1501 {
1502 .num_frontends = 1,
1503 .fe = {{
1504 .streaming_ctrl = cxusb_streaming_ctrl,
1505 .frontend_attach = cxusb_dee1601_frontend_attach,
1506 .tuner_attach = cxusb_dee1601_tuner_attach,
1507 /* parameter for the MPEG2-data transfer */
1508 .stream = {
1509 .type = USB_BULK,
1510 .count = 5,
1511 .endpoint = 0x04,
1512 .u = {
1513 .bulk = {
1514 .buffersize = 8192,
1515 }
1516 }
1517 },
1518 }},
1519 },
1520 },
1521
1522 .power_ctrl = cxusb_bluebird_power_ctrl,
1523
1524 .i2c_algo = &cxusb_i2c_algo,
1525
1526 .rc.legacy = {
1527 .rc_interval = 150,
1528 .rc_map_table = rc_map_dvico_mce_table,
1529 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
1530 .rc_query = cxusb_rc_query,
1531 },
1532
1533 .generic_bulk_ctrl_endpoint = 0x01,
1534
1535 .num_device_descs = 3,
1536 .devices = {
1537 { "DViCO FusionHDTV DVB-T Dual USB",
1538 { &cxusb_table[3], NULL },
1539 { &cxusb_table[4], NULL },
1540 },
1541 { "DigitalNow DVB-T Dual USB",
1542 { &cxusb_table[9], NULL },
1543 { &cxusb_table[10], NULL },
1544 },
1545 { "DViCO FusionHDTV DVB-T Dual Digital 2",
1546 { &cxusb_table[11], NULL },
1547 { &cxusb_table[12], NULL },
1548 },
1549 }
1550};
1551
1552static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = {
1553 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1554
1555 .usb_ctrl = DEVICE_SPECIFIC,
1556 .firmware = "dvb-usb-bluebird-01.fw",
1557 .download_firmware = bluebird_patch_dvico_firmware_download,
1558 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1559 use usb alt setting 7 for EP2 transfer (atsc) */
1560
1561 .size_of_priv = sizeof(struct cxusb_state),
1562
1563 .num_adapters = 2,
1564 .adapter = {
1565 {
1566 .num_frontends = 1,
1567 .fe = {{
1568 .streaming_ctrl = cxusb_streaming_ctrl,
1569 .frontend_attach = cxusb_mt352_frontend_attach,
1570 .tuner_attach = cxusb_lgz201_tuner_attach,
1571
1572 /* parameter for the MPEG2-data transfer */
1573 .stream = {
1574 .type = USB_BULK,
1575 .count = 5,
1576 .endpoint = 0x04,
1577 .u = {
1578 .bulk = {
1579 .buffersize = 8192,
1580 }
1581 }
1582 },
1583 }},
1584 },
1585 },
1586 .power_ctrl = cxusb_bluebird_power_ctrl,
1587
1588 .i2c_algo = &cxusb_i2c_algo,
1589
1590 .rc.legacy = {
1591 .rc_interval = 100,
1592 .rc_map_table = rc_map_dvico_portable_table,
1593 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1594 .rc_query = cxusb_rc_query,
1595 },
1596
1597 .generic_bulk_ctrl_endpoint = 0x01,
1598 .num_device_descs = 1,
1599 .devices = {
1600 { "DViCO FusionHDTV DVB-T USB (LGZ201)",
1601 { &cxusb_table[5], NULL },
1602 { &cxusb_table[6], NULL },
1603 },
1604 }
1605};
1606
1607static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = {
1608 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1609
1610 .usb_ctrl = DEVICE_SPECIFIC,
1611 .firmware = "dvb-usb-bluebird-01.fw",
1612 .download_firmware = bluebird_patch_dvico_firmware_download,
1613 /* use usb alt setting 0 for EP4 transfer (dvb-t),
1614 use usb alt setting 7 for EP2 transfer (atsc) */
1615
1616 .size_of_priv = sizeof(struct cxusb_state),
1617
1618 .num_adapters = 1,
1619 .adapter = {
1620 {
1621 .num_frontends = 1,
1622 .fe = {{
1623 .streaming_ctrl = cxusb_streaming_ctrl,
1624 .frontend_attach = cxusb_mt352_frontend_attach,
1625 .tuner_attach = cxusb_dtt7579_tuner_attach,
1626
1627 /* parameter for the MPEG2-data transfer */
1628 .stream = {
1629 .type = USB_BULK,
1630 .count = 5,
1631 .endpoint = 0x04,
1632 .u = {
1633 .bulk = {
1634 .buffersize = 8192,
1635 }
1636 }
1637 },
1638 }},
1639 },
1640 },
1641 .power_ctrl = cxusb_bluebird_power_ctrl,
1642
1643 .i2c_algo = &cxusb_i2c_algo,
1644
1645 .rc.legacy = {
1646 .rc_interval = 100,
1647 .rc_map_table = rc_map_dvico_portable_table,
1648 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1649 .rc_query = cxusb_rc_query,
1650 },
1651
1652 .generic_bulk_ctrl_endpoint = 0x01,
1653
1654 .num_device_descs = 1,
1655 .devices = {
1656 { "DViCO FusionHDTV DVB-T USB (TH7579)",
1657 { &cxusb_table[7], NULL },
1658 { &cxusb_table[8], NULL },
1659 },
1660 }
1661};
1662
1663static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = {
1664 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1665
1666 .usb_ctrl = CYPRESS_FX2,
1667
1668 .size_of_priv = sizeof(struct cxusb_state),
1669
1670 .num_adapters = 1,
1671 .adapter = {
1672 {
1673 .num_frontends = 1,
1674 .fe = {{
1675 .streaming_ctrl = cxusb_streaming_ctrl,
1676 .frontend_attach = cxusb_dualdig4_frontend_attach,
1677 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1678 /* parameter for the MPEG2-data transfer */
1679 .stream = {
1680 .type = USB_BULK,
1681 .count = 5,
1682 .endpoint = 0x02,
1683 .u = {
1684 .bulk = {
1685 .buffersize = 8192,
1686 }
1687 }
1688 },
1689 }},
1690 },
1691 },
1692
1693 .power_ctrl = cxusb_power_ctrl,
1694
1695 .i2c_algo = &cxusb_i2c_algo,
1696
1697 .generic_bulk_ctrl_endpoint = 0x01,
1698
1699 .rc.legacy = {
1700 .rc_interval = 100,
1701 .rc_map_table = rc_map_dvico_mce_table,
1702 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
1703 .rc_query = cxusb_bluebird2_rc_query,
1704 },
1705
1706 .num_device_descs = 1,
1707 .devices = {
1708 { "DViCO FusionHDTV DVB-T Dual Digital 4",
1709 { NULL },
1710 { &cxusb_table[13], NULL },
1711 },
1712 }
1713};
1714
1715static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = {
1716 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1717
1718 .usb_ctrl = CYPRESS_FX2,
1719 .identify_state = bluebird_fx2_identify_state,
1720
1721 .size_of_priv = sizeof(struct cxusb_state),
1722
1723 .num_adapters = 1,
1724 .adapter = {
1725 {
1726 .num_frontends = 1,
1727 .fe = {{
1728 .streaming_ctrl = cxusb_streaming_ctrl,
1729 .frontend_attach = cxusb_nano2_frontend_attach,
1730 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1731 /* parameter for the MPEG2-data transfer */
1732 .stream = {
1733 .type = USB_BULK,
1734 .count = 5,
1735 .endpoint = 0x02,
1736 .u = {
1737 .bulk = {
1738 .buffersize = 8192,
1739 }
1740 }
1741 },
1742 }},
1743 },
1744 },
1745
1746 .power_ctrl = cxusb_nano2_power_ctrl,
1747
1748 .i2c_algo = &cxusb_i2c_algo,
1749
1750 .generic_bulk_ctrl_endpoint = 0x01,
1751
1752 .rc.legacy = {
1753 .rc_interval = 100,
1754 .rc_map_table = rc_map_dvico_portable_table,
1755 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1756 .rc_query = cxusb_bluebird2_rc_query,
1757 },
1758
1759 .num_device_descs = 1,
1760 .devices = {
1761 { "DViCO FusionHDTV DVB-T NANO2",
1762 { NULL },
1763 { &cxusb_table[14], NULL },
1764 },
1765 }
1766};
1767
1768static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = {
1769 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1770
1771 .usb_ctrl = DEVICE_SPECIFIC,
1772 .firmware = "dvb-usb-bluebird-02.fw",
1773 .download_firmware = bluebird_patch_dvico_firmware_download,
1774 .identify_state = bluebird_fx2_identify_state,
1775
1776 .size_of_priv = sizeof(struct cxusb_state),
1777
1778 .num_adapters = 1,
1779 .adapter = {
1780 {
1781 .num_frontends = 1,
1782 .fe = {{
1783 .streaming_ctrl = cxusb_streaming_ctrl,
1784 .frontend_attach = cxusb_nano2_frontend_attach,
1785 .tuner_attach = cxusb_dvico_xc3028_tuner_attach,
1786 /* parameter for the MPEG2-data transfer */
1787 .stream = {
1788 .type = USB_BULK,
1789 .count = 5,
1790 .endpoint = 0x02,
1791 .u = {
1792 .bulk = {
1793 .buffersize = 8192,
1794 }
1795 }
1796 },
1797 }},
1798 },
1799 },
1800
1801 .power_ctrl = cxusb_nano2_power_ctrl,
1802
1803 .i2c_algo = &cxusb_i2c_algo,
1804
1805 .generic_bulk_ctrl_endpoint = 0x01,
1806
1807 .rc.legacy = {
1808 .rc_interval = 100,
1809 .rc_map_table = rc_map_dvico_portable_table,
1810 .rc_map_size = ARRAY_SIZE(rc_map_dvico_portable_table),
1811 .rc_query = cxusb_rc_query,
1812 },
1813
1814 .num_device_descs = 1,
1815 .devices = {
1816 { "DViCO FusionHDTV DVB-T NANO2 w/o firmware",
1817 { &cxusb_table[14], NULL },
1818 { &cxusb_table[15], NULL },
1819 },
1820 }
1821};
1822
1823static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
1824 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1825
1826 .usb_ctrl = CYPRESS_FX2,
1827
1828 .size_of_priv = sizeof(struct cxusb_state),
1829
1830 .num_adapters = 1,
1831 .adapter = {
1832 {
1833 .num_frontends = 1,
1834 .fe = {{
1835 .streaming_ctrl = cxusb_aver_streaming_ctrl,
1836 .frontend_attach = cxusb_aver_lgdt3303_frontend_attach,
1837 .tuner_attach = cxusb_mxl5003s_tuner_attach,
1838 /* parameter for the MPEG2-data transfer */
1839 .stream = {
1840 .type = USB_BULK,
1841 .count = 5,
1842 .endpoint = 0x04,
1843 .u = {
1844 .bulk = {
1845 .buffersize = 8192,
1846 }
1847 }
1848 },
1849 }},
1850 },
1851 },
1852 .power_ctrl = cxusb_aver_power_ctrl,
1853
1854 .i2c_algo = &cxusb_i2c_algo,
1855
1856 .generic_bulk_ctrl_endpoint = 0x01,
1857
1858 .num_device_descs = 1,
1859 .devices = {
1860 { "AVerMedia AVerTVHD Volar (A868R)",
1861 { NULL },
1862 { &cxusb_table[16], NULL },
1863 },
1864 }
1865};
1866
1867static
1868struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = {
1869 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1870
1871 .usb_ctrl = CYPRESS_FX2,
1872
1873 .size_of_priv = sizeof(struct cxusb_state),
1874
1875 .num_adapters = 1,
1876 .adapter = {
1877 {
1878 .size_of_priv = sizeof(struct dib0700_adapter_state),
1879 .num_frontends = 1,
1880 .fe = {{
1881 .streaming_ctrl = cxusb_streaming_ctrl,
1882 .frontend_attach = cxusb_dualdig4_rev2_frontend_attach,
1883 .tuner_attach = cxusb_dualdig4_rev2_tuner_attach,
1884 /* parameter for the MPEG2-data transfer */
1885 .stream = {
1886 .type = USB_BULK,
1887 .count = 7,
1888 .endpoint = 0x02,
1889 .u = {
1890 .bulk = {
1891 .buffersize = 4096,
1892 }
1893 }
1894 },
1895 }},
1896 },
1897 },
1898
1899 .power_ctrl = cxusb_bluebird_power_ctrl,
1900
1901 .i2c_algo = &cxusb_i2c_algo,
1902
1903 .generic_bulk_ctrl_endpoint = 0x01,
1904
1905 .rc.legacy = {
1906 .rc_interval = 100,
1907 .rc_map_table = rc_map_dvico_mce_table,
1908 .rc_map_size = ARRAY_SIZE(rc_map_dvico_mce_table),
1909 .rc_query = cxusb_rc_query,
1910 },
1911
1912 .num_device_descs = 1,
1913 .devices = {
1914 { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)",
1915 { NULL },
1916 { &cxusb_table[17], NULL },
1917 },
1918 }
1919};
1920
1921static struct dvb_usb_device_properties cxusb_d680_dmb_properties = {
1922 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1923
1924 .usb_ctrl = CYPRESS_FX2,
1925
1926 .size_of_priv = sizeof(struct cxusb_state),
1927
1928 .num_adapters = 1,
1929 .adapter = {
1930 {
1931 .num_frontends = 1,
1932 .fe = {{
1933 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
1934 .frontend_attach = cxusb_d680_dmb_frontend_attach,
1935 .tuner_attach = cxusb_d680_dmb_tuner_attach,
1936
1937 /* parameter for the MPEG2-data transfer */
1938 .stream = {
1939 .type = USB_BULK,
1940 .count = 5,
1941 .endpoint = 0x02,
1942 .u = {
1943 .bulk = {
1944 .buffersize = 8192,
1945 }
1946 }
1947 },
1948 }},
1949 },
1950 },
1951
1952 .power_ctrl = cxusb_d680_dmb_power_ctrl,
1953
1954 .i2c_algo = &cxusb_i2c_algo,
1955
1956 .generic_bulk_ctrl_endpoint = 0x01,
1957
1958 .rc.legacy = {
1959 .rc_interval = 100,
1960 .rc_map_table = rc_map_d680_dmb_table,
1961 .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
1962 .rc_query = cxusb_d680_dmb_rc_query,
1963 },
1964
1965 .num_device_descs = 1,
1966 .devices = {
1967 {
1968 "Conexant DMB-TH Stick",
1969 { NULL },
1970 { &cxusb_table[18], NULL },
1971 },
1972 }
1973};
1974
1975static struct dvb_usb_device_properties cxusb_mygica_d689_properties = {
1976 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1977
1978 .usb_ctrl = CYPRESS_FX2,
1979
1980 .size_of_priv = sizeof(struct cxusb_state),
1981
1982 .num_adapters = 1,
1983 .adapter = {
1984 {
1985 .num_frontends = 1,
1986 .fe = {{
1987 .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl,
1988 .frontend_attach = cxusb_mygica_d689_frontend_attach,
1989 .tuner_attach = cxusb_mygica_d689_tuner_attach,
1990
1991 /* parameter for the MPEG2-data transfer */
1992 .stream = {
1993 .type = USB_BULK,
1994 .count = 5,
1995 .endpoint = 0x02,
1996 .u = {
1997 .bulk = {
1998 .buffersize = 8192,
1999 }
2000 }
2001 },
2002 }},
2003 },
2004 },
2005
2006 .power_ctrl = cxusb_d680_dmb_power_ctrl,
2007
2008 .i2c_algo = &cxusb_i2c_algo,
2009
2010 .generic_bulk_ctrl_endpoint = 0x01,
2011
2012 .rc.legacy = {
2013 .rc_interval = 100,
2014 .rc_map_table = rc_map_d680_dmb_table,
2015 .rc_map_size = ARRAY_SIZE(rc_map_d680_dmb_table),
2016 .rc_query = cxusb_d680_dmb_rc_query,
2017 },
2018
2019 .num_device_descs = 1,
2020 .devices = {
2021 {
2022 "Mygica D689 DMB-TH",
2023 { NULL },
2024 { &cxusb_table[19], NULL },
2025 },
2026 }
2027};
2028
2029static struct usb_driver cxusb_driver = {
2030 .name = "dvb_usb_cxusb",
2031 .probe = cxusb_probe,
2032 .disconnect = dvb_usb_device_exit,
2033 .id_table = cxusb_table,
2034};
2035
2036module_usb_driver(cxusb_driver);
2037
2038MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
2039MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
2040MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
2041MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design");
2042MODULE_VERSION("1.0-alpha");
2043MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/cxusb.h b/drivers/media/usb/dvb-usb/cxusb.h
new file mode 100644
index 000000000000..1a51eafd31b9
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/cxusb.h
@@ -0,0 +1,35 @@
1#ifndef _DVB_USB_CXUSB_H_
2#define _DVB_USB_CXUSB_H_
3
4#define DVB_USB_LOG_PREFIX "cxusb"
5#include "dvb-usb.h"
6
7/* usb commands - some of it are guesses, don't have a reference yet */
8#define CMD_BLUEBIRD_GPIO_RW 0x05
9
10#define CMD_I2C_WRITE 0x08
11#define CMD_I2C_READ 0x09
12
13#define CMD_GPIO_READ 0x0d
14#define CMD_GPIO_WRITE 0x0e
15#define GPIO_TUNER 0x02
16
17#define CMD_POWER_OFF 0xdc
18#define CMD_POWER_ON 0xde
19
20#define CMD_STREAMING_ON 0x36
21#define CMD_STREAMING_OFF 0x37
22
23#define CMD_AVER_STREAM_ON 0x18
24#define CMD_AVER_STREAM_OFF 0x19
25
26#define CMD_GET_IR_CODE 0x47
27
28#define CMD_ANALOG 0x50
29#define CMD_DIGITAL 0x51
30
31struct cxusb_state {
32 u8 gpio_write_state[3];
33};
34
35#endif
diff --git a/drivers/media/usb/dvb-usb/dib0700.h b/drivers/media/usb/dvb-usb/dib0700.h
new file mode 100644
index 000000000000..7de125c0b36f
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dib0700.h
@@ -0,0 +1,75 @@
1/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the Free
5 * Software Foundation, version 2.
6 *
7 * Copyright (C) 2005-6 DiBcom, SA
8 */
9#ifndef _DIB0700_H_
10#define _DIB0700_H_
11
12#define DVB_USB_LOG_PREFIX "dib0700"
13#include "dvb-usb.h"
14
15#include "dib07x0.h"
16
17extern int dvb_usb_dib0700_debug;
18#define deb_info(args...) dprintk(dvb_usb_dib0700_debug,0x01,args)
19#define deb_fw(args...) dprintk(dvb_usb_dib0700_debug,0x02,args)
20#define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args)
21#define deb_data(args...) dprintk(dvb_usb_dib0700_debug,0x08,args)
22
23#define REQUEST_SET_USB_XFER_LEN 0x0 /* valid only for firmware version */
24 /* higher than 1.21 */
25#define REQUEST_I2C_READ 0x2
26#define REQUEST_I2C_WRITE 0x3
27#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */
28#define REQUEST_JUMPRAM 0x8
29#define REQUEST_SET_CLOCK 0xB
30#define REQUEST_SET_GPIO 0xC
31#define REQUEST_ENABLE_VIDEO 0xF
32 // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
33 // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
34 // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " )
35#define REQUEST_SET_I2C_PARAM 0x10
36#define REQUEST_SET_RC 0x11
37#define REQUEST_NEW_I2C_READ 0x12
38#define REQUEST_NEW_I2C_WRITE 0x13
39#define REQUEST_GET_VERSION 0x15
40
41struct dib0700_state {
42 u8 channel_state;
43 u16 mt2060_if1[2];
44 u8 rc_toggle;
45 u8 rc_counter;
46 u8 is_dib7000pc;
47 u8 fw_use_new_i2c_api;
48 u8 disable_streaming_master_mode;
49 u32 fw_version;
50 u32 nb_packet_buffer_size;
51 int (*read_status)(struct dvb_frontend *, fe_status_t *);
52 int (*sleep)(struct dvb_frontend* fe);
53 u8 buf[255];
54};
55
56extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
57 u32 *romversion, u32 *ramversion, u32 *fwtype);
58extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val);
59extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3);
60extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen);
61extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw);
62extern int dib0700_rc_setup(struct dvb_usb_device *d);
63extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
64extern struct i2c_algorithm dib0700_i2c_algo;
65extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
66 struct dvb_usb_device_description **desc, int *cold);
67extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type);
68extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz);
69
70extern int dib0700_device_count;
71extern int dvb_usb_dib0700_ir_proto;
72extern struct dvb_usb_device_properties dib0700_devices[];
73extern struct usb_device_id dib0700_usb_id_table[];
74
75#endif
diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
new file mode 100644
index 000000000000..ef87229de6af
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dib0700_core.c
@@ -0,0 +1,845 @@
1/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the Free
5 * Software Foundation, version 2.
6 *
7 * Copyright (C) 2005-6 DiBcom, SA
8 */
9#include "dib0700.h"
10
11/* debug */
12int dvb_usb_dib0700_debug;
13module_param_named(debug,dvb_usb_dib0700_debug, int, 0644);
14MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS);
15
16static int nb_packet_buffer_size = 21;
17module_param(nb_packet_buffer_size, int, 0644);
18MODULE_PARM_DESC(nb_packet_buffer_size,
19 "Set the dib0700 driver data buffer size. This parameter "
20 "corresponds to the number of TS packets. The actual size of "
21 "the data buffer corresponds to this parameter "
22 "multiplied by 188 (default: 21)");
23
24DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
25
26
27int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
28 u32 *romversion, u32 *ramversion, u32 *fwtype)
29{
30 struct dib0700_state *st = d->priv;
31 int ret;
32
33 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
34 err("could not acquire lock");
35 return -EINTR;
36 }
37
38 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
39 REQUEST_GET_VERSION,
40 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
41 st->buf, 16, USB_CTRL_GET_TIMEOUT);
42 if (hwversion != NULL)
43 *hwversion = (st->buf[0] << 24) | (st->buf[1] << 16) |
44 (st->buf[2] << 8) | st->buf[3];
45 if (romversion != NULL)
46 *romversion = (st->buf[4] << 24) | (st->buf[5] << 16) |
47 (st->buf[6] << 8) | st->buf[7];
48 if (ramversion != NULL)
49 *ramversion = (st->buf[8] << 24) | (st->buf[9] << 16) |
50 (st->buf[10] << 8) | st->buf[11];
51 if (fwtype != NULL)
52 *fwtype = (st->buf[12] << 24) | (st->buf[13] << 16) |
53 (st->buf[14] << 8) | st->buf[15];
54 mutex_unlock(&d->usb_mutex);
55 return ret;
56}
57
58/* expecting rx buffer: request data[0] data[1] ... data[2] */
59static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
60{
61 int status;
62
63 deb_data(">>> ");
64 debug_dump(tx, txlen, deb_data);
65
66 status = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0),
67 tx[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, tx, txlen,
68 USB_CTRL_GET_TIMEOUT);
69
70 if (status != txlen)
71 deb_data("ep 0 write error (status = %d, len: %d)\n",status,txlen);
72
73 return status < 0 ? status : 0;
74}
75
76/* expecting tx buffer: request data[0] ... data[n] (n <= 4) */
77int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
78{
79 u16 index, value;
80 int status;
81
82 if (txlen < 2) {
83 err("tx buffer length is smaller than 2. Makes no sense.");
84 return -EINVAL;
85 }
86 if (txlen > 4) {
87 err("tx buffer length is larger than 4. Not supported.");
88 return -EINVAL;
89 }
90
91 deb_data(">>> ");
92 debug_dump(tx,txlen,deb_data);
93
94 value = ((txlen - 2) << 8) | tx[1];
95 index = 0;
96 if (txlen > 2)
97 index |= (tx[2] << 8);
98 if (txlen > 3)
99 index |= tx[3];
100
101 status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0],
102 USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen,
103 USB_CTRL_GET_TIMEOUT);
104
105 if (status < 0)
106 deb_info("ep 0 read error (status = %d)\n",status);
107
108 deb_data("<<< ");
109 debug_dump(rx, rxlen, deb_data);
110
111 return status; /* length in case of success */
112}
113
114int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val)
115{
116 struct dib0700_state *st = d->priv;
117 int ret;
118
119 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
120 err("could not acquire lock");
121 return -EINTR;
122 }
123
124 st->buf[0] = REQUEST_SET_GPIO;
125 st->buf[1] = gpio;
126 st->buf[2] = ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6);
127
128 ret = dib0700_ctrl_wr(d, st->buf, 3);
129
130 mutex_unlock(&d->usb_mutex);
131 return ret;
132}
133
134static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
135{
136 struct dib0700_state *st = d->priv;
137 int ret;
138
139 if (st->fw_version >= 0x10201) {
140 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
141 err("could not acquire lock");
142 return -EINTR;
143 }
144
145 st->buf[0] = REQUEST_SET_USB_XFER_LEN;
146 st->buf[1] = (nb_ts_packets >> 8) & 0xff;
147 st->buf[2] = nb_ts_packets & 0xff;
148
149 deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
150
151 ret = dib0700_ctrl_wr(d, st->buf, 3);
152 mutex_unlock(&d->usb_mutex);
153 } else {
154 deb_info("this firmware does not allow to change the USB xfer len\n");
155 ret = -EIO;
156 }
157
158 return ret;
159}
160
161/*
162 * I2C master xfer function (supported in 1.20 firmware)
163 */
164static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
165 int num)
166{
167 /* The new i2c firmware messages are more reliable and in particular
168 properly support i2c read calls not preceded by a write */
169
170 struct dvb_usb_device *d = i2c_get_adapdata(adap);
171 struct dib0700_state *st = d->priv;
172 uint8_t bus_mode = 1; /* 0=eeprom bus, 1=frontend bus */
173 uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */
174 uint8_t en_start = 0;
175 uint8_t en_stop = 0;
176 int result, i;
177
178 /* Ensure nobody else hits the i2c bus while we're sending our
179 sequence of messages, (such as the remote control thread) */
180 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
181 return -EINTR;
182
183 for (i = 0; i < num; i++) {
184 if (i == 0) {
185 /* First message in the transaction */
186 en_start = 1;
187 } else if (!(msg[i].flags & I2C_M_NOSTART)) {
188 /* Device supports repeated-start */
189 en_start = 1;
190 } else {
191 /* Not the first packet and device doesn't support
192 repeated start */
193 en_start = 0;
194 }
195 if (i == (num - 1)) {
196 /* Last message in the transaction */
197 en_stop = 1;
198 }
199
200 if (msg[i].flags & I2C_M_RD) {
201 /* Read request */
202 u16 index, value;
203 uint8_t i2c_dest;
204
205 i2c_dest = (msg[i].addr << 1);
206 value = ((en_start << 7) | (en_stop << 6) |
207 (msg[i].len & 0x3F)) << 8 | i2c_dest;
208 /* I2C ctrl + FE bus; */
209 index = ((gen_mode << 6) & 0xC0) |
210 ((bus_mode << 4) & 0x30);
211
212 result = usb_control_msg(d->udev,
213 usb_rcvctrlpipe(d->udev, 0),
214 REQUEST_NEW_I2C_READ,
215 USB_TYPE_VENDOR | USB_DIR_IN,
216 value, index, msg[i].buf,
217 msg[i].len,
218 USB_CTRL_GET_TIMEOUT);
219 if (result < 0) {
220 deb_info("i2c read error (status = %d)\n", result);
221 break;
222 }
223
224 deb_data("<<< ");
225 debug_dump(msg[i].buf, msg[i].len, deb_data);
226
227 } else {
228 /* Write request */
229 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
230 err("could not acquire lock");
231 mutex_unlock(&d->i2c_mutex);
232 return -EINTR;
233 }
234 st->buf[0] = REQUEST_NEW_I2C_WRITE;
235 st->buf[1] = msg[i].addr << 1;
236 st->buf[2] = (en_start << 7) | (en_stop << 6) |
237 (msg[i].len & 0x3F);
238 /* I2C ctrl + FE bus; */
239 st->buf[3] = ((gen_mode << 6) & 0xC0) |
240 ((bus_mode << 4) & 0x30);
241 /* The Actual i2c payload */
242 memcpy(&st->buf[4], msg[i].buf, msg[i].len);
243
244 deb_data(">>> ");
245 debug_dump(st->buf, msg[i].len + 4, deb_data);
246
247 result = usb_control_msg(d->udev,
248 usb_sndctrlpipe(d->udev, 0),
249 REQUEST_NEW_I2C_WRITE,
250 USB_TYPE_VENDOR | USB_DIR_OUT,
251 0, 0, st->buf, msg[i].len + 4,
252 USB_CTRL_GET_TIMEOUT);
253 mutex_unlock(&d->usb_mutex);
254 if (result < 0) {
255 deb_info("i2c write error (status = %d)\n", result);
256 break;
257 }
258 }
259 }
260 mutex_unlock(&d->i2c_mutex);
261 return i;
262}
263
264/*
265 * I2C master xfer function (pre-1.20 firmware)
266 */
267static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
268 struct i2c_msg *msg, int num)
269{
270 struct dvb_usb_device *d = i2c_get_adapdata(adap);
271 struct dib0700_state *st = d->priv;
272 int i,len;
273
274 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
275 return -EINTR;
276 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
277 err("could not acquire lock");
278 mutex_unlock(&d->i2c_mutex);
279 return -EINTR;
280 }
281
282 for (i = 0; i < num; i++) {
283 /* fill in the address */
284 st->buf[1] = msg[i].addr << 1;
285 /* fill the buffer */
286 memcpy(&st->buf[2], msg[i].buf, msg[i].len);
287
288 /* write/read request */
289 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
290 st->buf[0] = REQUEST_I2C_READ;
291 st->buf[1] |= 1;
292
293 /* special thing in the current firmware: when length is zero the read-failed */
294 len = dib0700_ctrl_rd(d, st->buf, msg[i].len + 2,
295 msg[i+1].buf, msg[i+1].len);
296 if (len <= 0) {
297 deb_info("I2C read failed on address 0x%02x\n",
298 msg[i].addr);
299 break;
300 }
301
302 msg[i+1].len = len;
303
304 i++;
305 } else {
306 st->buf[0] = REQUEST_I2C_WRITE;
307 if (dib0700_ctrl_wr(d, st->buf, msg[i].len + 2) < 0)
308 break;
309 }
310 }
311 mutex_unlock(&d->usb_mutex);
312 mutex_unlock(&d->i2c_mutex);
313
314 return i;
315}
316
317static int dib0700_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
318 int num)
319{
320 struct dvb_usb_device *d = i2c_get_adapdata(adap);
321 struct dib0700_state *st = d->priv;
322
323 if (st->fw_use_new_i2c_api == 1) {
324 /* User running at least fw 1.20 */
325 return dib0700_i2c_xfer_new(adap, msg, num);
326 } else {
327 /* Use legacy calls */
328 return dib0700_i2c_xfer_legacy(adap, msg, num);
329 }
330}
331
332static u32 dib0700_i2c_func(struct i2c_adapter *adapter)
333{
334 return I2C_FUNC_I2C;
335}
336
337struct i2c_algorithm dib0700_i2c_algo = {
338 .master_xfer = dib0700_i2c_xfer,
339 .functionality = dib0700_i2c_func,
340};
341
342int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
343 struct dvb_usb_device_description **desc, int *cold)
344{
345 s16 ret;
346 u8 *b;
347
348 b = kmalloc(16, GFP_KERNEL);
349 if (!b)
350 return -ENOMEM;
351
352
353 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
354 REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT);
355
356 deb_info("FW GET_VERSION length: %d\n",ret);
357
358 *cold = ret <= 0;
359 deb_info("cold: %d\n", *cold);
360
361 kfree(b);
362 return 0;
363}
364
365static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
366 u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv,
367 u16 pll_loopdiv, u16 free_div, u16 dsuScaler)
368{
369 struct dib0700_state *st = d->priv;
370 int ret;
371
372 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
373 err("could not acquire lock");
374 return -EINTR;
375 }
376
377 st->buf[0] = REQUEST_SET_CLOCK;
378 st->buf[1] = (en_pll << 7) | (pll_src << 6) |
379 (pll_range << 5) | (clock_gpio3 << 4);
380 st->buf[2] = (pll_prediv >> 8) & 0xff; /* MSB */
381 st->buf[3] = pll_prediv & 0xff; /* LSB */
382 st->buf[4] = (pll_loopdiv >> 8) & 0xff; /* MSB */
383 st->buf[5] = pll_loopdiv & 0xff; /* LSB */
384 st->buf[6] = (free_div >> 8) & 0xff; /* MSB */
385 st->buf[7] = free_div & 0xff; /* LSB */
386 st->buf[8] = (dsuScaler >> 8) & 0xff; /* MSB */
387 st->buf[9] = dsuScaler & 0xff; /* LSB */
388
389 ret = dib0700_ctrl_wr(d, st->buf, 10);
390 mutex_unlock(&d->usb_mutex);
391
392 return ret;
393}
394
395int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
396{
397 struct dib0700_state *st = d->priv;
398 u16 divider;
399 int ret;
400
401 if (scl_kHz == 0)
402 return -EINVAL;
403
404 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
405 err("could not acquire lock");
406 return -EINTR;
407 }
408
409 st->buf[0] = REQUEST_SET_I2C_PARAM;
410 divider = (u16) (30000 / scl_kHz);
411 st->buf[1] = 0;
412 st->buf[2] = (u8) (divider >> 8);
413 st->buf[3] = (u8) (divider & 0xff);
414 divider = (u16) (72000 / scl_kHz);
415 st->buf[4] = (u8) (divider >> 8);
416 st->buf[5] = (u8) (divider & 0xff);
417 divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */
418 st->buf[6] = (u8) (divider >> 8);
419 st->buf[7] = (u8) (divider & 0xff);
420
421 deb_info("setting I2C speed: %04x %04x %04x (%d kHz).",
422 (st->buf[2] << 8) | (st->buf[3]), (st->buf[4] << 8) |
423 st->buf[5], (st->buf[6] << 8) | st->buf[7], scl_kHz);
424
425 ret = dib0700_ctrl_wr(d, st->buf, 8);
426 mutex_unlock(&d->usb_mutex);
427
428 return ret;
429}
430
431
432int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3)
433{
434 switch (clk_MHz) {
435 case 72: dib0700_set_clock(d, 1, 0, 1, clock_out_gp3, 2, 24, 0, 0x4c); break;
436 default: return -EINVAL;
437 }
438 return 0;
439}
440
441static int dib0700_jumpram(struct usb_device *udev, u32 address)
442{
443 int ret = 0, actlen;
444 u8 *buf;
445
446 buf = kmalloc(8, GFP_KERNEL);
447 if (!buf)
448 return -ENOMEM;
449 buf[0] = REQUEST_JUMPRAM;
450 buf[1] = 0;
451 buf[2] = 0;
452 buf[3] = 0;
453 buf[4] = (address >> 24) & 0xff;
454 buf[5] = (address >> 16) & 0xff;
455 buf[6] = (address >> 8) & 0xff;
456 buf[7] = address & 0xff;
457
458 if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) {
459 deb_fw("jumpram to 0x%x failed\n",address);
460 goto out;
461 }
462 if (actlen != 8) {
463 deb_fw("jumpram to 0x%x failed\n",address);
464 ret = -EIO;
465 goto out;
466 }
467out:
468 kfree(buf);
469 return ret;
470}
471
472int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
473{
474 struct hexline hx;
475 int pos = 0, ret, act_len, i, adap_num;
476 u8 *buf;
477 u32 fw_version;
478
479 buf = kmalloc(260, GFP_KERNEL);
480 if (!buf)
481 return -ENOMEM;
482
483 while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) {
484 deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",
485 hx.addr, hx.len, hx.chk);
486
487 buf[0] = hx.len;
488 buf[1] = (hx.addr >> 8) & 0xff;
489 buf[2] = hx.addr & 0xff;
490 buf[3] = hx.type;
491 memcpy(&buf[4],hx.data,hx.len);
492 buf[4+hx.len] = hx.chk;
493
494 ret = usb_bulk_msg(udev,
495 usb_sndbulkpipe(udev, 0x01),
496 buf,
497 hx.len + 5,
498 &act_len,
499 1000);
500
501 if (ret < 0) {
502 err("firmware download failed at %d with %d",pos,ret);
503 goto out;
504 }
505 }
506
507 if (ret == 0) {
508 /* start the firmware */
509 if ((ret = dib0700_jumpram(udev, 0x70000000)) == 0) {
510 info("firmware started successfully.");
511 msleep(500);
512 }
513 } else
514 ret = -EIO;
515
516 /* the number of ts packet has to be at least 1 */
517 if (nb_packet_buffer_size < 1)
518 nb_packet_buffer_size = 1;
519
520 /* get the fimware version */
521 usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
522 REQUEST_GET_VERSION,
523 USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
524 buf, 16, USB_CTRL_GET_TIMEOUT);
525 fw_version = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11];
526
527 /* set the buffer size - DVB-USB is allocating URB buffers
528 * only after the firwmare download was successful */
529 for (i = 0; i < dib0700_device_count; i++) {
530 for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters;
531 adap_num++) {
532 if (fw_version >= 0x10201) {
533 dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = 188*nb_packet_buffer_size;
534 } else {
535 /* for fw version older than 1.20.1,
536 * the buffersize has to be n times 512 */
537 dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512;
538 if (dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize < 512)
539 dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = 512;
540 }
541 }
542 }
543out:
544 kfree(buf);
545 return ret;
546}
547
548int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
549{
550 struct dib0700_state *st = adap->dev->priv;
551 int ret;
552
553 if ((onoff != 0) && (st->fw_version >= 0x10201)) {
554 /* for firmware later than 1.20.1,
555 * the USB xfer length can be set */
556 ret = dib0700_set_usb_xfer_len(adap->dev,
557 st->nb_packet_buffer_size);
558 if (ret < 0) {
559 deb_info("can not set the USB xfer len\n");
560 return ret;
561 }
562 }
563
564 if (mutex_lock_interruptible(&adap->dev->usb_mutex) < 0) {
565 err("could not acquire lock");
566 return -EINTR;
567 }
568
569 st->buf[0] = REQUEST_ENABLE_VIDEO;
570 /* this bit gives a kind of command,
571 * rather than enabling something or not */
572 st->buf[1] = (onoff << 4) | 0x00;
573
574 if (st->disable_streaming_master_mode == 1)
575 st->buf[2] = 0x00;
576 else
577 st->buf[2] = 0x01 << 4; /* Master mode */
578
579 st->buf[3] = 0x00;
580
581 deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
582
583 st->channel_state &= ~0x3;
584 if ((adap->fe_adap[0].stream.props.endpoint != 2)
585 && (adap->fe_adap[0].stream.props.endpoint != 3)) {
586 deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->fe_adap[0].stream.props.endpoint);
587 if (onoff)
588 st->channel_state |= 1 << (adap->id);
589 else
590 st->channel_state |= 1 << ~(adap->id);
591 } else {
592 if (onoff)
593 st->channel_state |= 1 << (adap->fe_adap[0].stream.props.endpoint-2);
594 else
595 st->channel_state |= 1 << (3-adap->fe_adap[0].stream.props.endpoint);
596 }
597
598 st->buf[2] |= st->channel_state;
599
600 deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]);
601
602 ret = dib0700_ctrl_wr(adap->dev, st->buf, 4);
603 mutex_unlock(&adap->dev->usb_mutex);
604
605 return ret;
606}
607
608int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
609{
610 struct dvb_usb_device *d = rc->priv;
611 struct dib0700_state *st = d->priv;
612 int new_proto, ret;
613
614 if (mutex_lock_interruptible(&d->usb_mutex) < 0) {
615 err("could not acquire lock");
616 return -EINTR;
617 }
618
619 st->buf[0] = REQUEST_SET_RC;
620 st->buf[1] = 0;
621 st->buf[2] = 0;
622
623 /* Set the IR mode */
624 if (rc_type == RC_TYPE_RC5)
625 new_proto = 1;
626 else if (rc_type == RC_TYPE_NEC)
627 new_proto = 0;
628 else if (rc_type == RC_TYPE_RC6) {
629 if (st->fw_version < 0x10200) {
630 ret = -EINVAL;
631 goto out;
632 }
633
634 new_proto = 2;
635 } else {
636 ret = -EINVAL;
637 goto out;
638 }
639
640 st->buf[1] = new_proto;
641
642 ret = dib0700_ctrl_wr(d, st->buf, 3);
643 if (ret < 0) {
644 err("ir protocol setup failed");
645 goto out;
646 }
647
648 d->props.rc.core.protocol = rc_type;
649
650out:
651 mutex_unlock(&d->usb_mutex);
652 return ret;
653}
654
655/* Number of keypresses to ignore before start repeating */
656#define RC_REPEAT_DELAY_V1_20 10
657
658/* This is the structure of the RC response packet starting in firmware 1.20 */
659struct dib0700_rc_response {
660 u8 report_id;
661 u8 data_state;
662 union {
663 u16 system16;
664 struct {
665 u8 not_system;
666 u8 system;
667 };
668 };
669 u8 data;
670 u8 not_data;
671};
672#define RC_MSG_SIZE_V1_20 6
673
674static void dib0700_rc_urb_completion(struct urb *purb)
675{
676 struct dvb_usb_device *d = purb->context;
677 struct dib0700_rc_response *poll_reply;
678 u32 uninitialized_var(keycode);
679 u8 toggle;
680
681 deb_info("%s()\n", __func__);
682 if (d->rc_dev == NULL) {
683 /* This will occur if disable_rc_polling=1 */
684 kfree(purb->transfer_buffer);
685 usb_free_urb(purb);
686 return;
687 }
688
689 poll_reply = purb->transfer_buffer;
690
691 if (purb->status < 0) {
692 deb_info("discontinuing polling\n");
693 kfree(purb->transfer_buffer);
694 usb_free_urb(purb);
695 return;
696 }
697
698 if (purb->actual_length != RC_MSG_SIZE_V1_20) {
699 deb_info("malformed rc msg size=%d\n", purb->actual_length);
700 goto resubmit;
701 }
702
703 deb_data("IR ID = %02X state = %02X System = %02X %02X Cmd = %02X %02X (len %d)\n",
704 poll_reply->report_id, poll_reply->data_state,
705 poll_reply->system, poll_reply->not_system,
706 poll_reply->data, poll_reply->not_data,
707 purb->actual_length);
708
709 switch (d->props.rc.core.protocol) {
710 case RC_TYPE_NEC:
711 toggle = 0;
712
713 /* NEC protocol sends repeat code as 0 0 0 FF */
714 if ((poll_reply->system == 0x00) && (poll_reply->data == 0x00)
715 && (poll_reply->not_data == 0xff)) {
716 poll_reply->data_state = 2;
717 break;
718 }
719
720 if ((poll_reply->system ^ poll_reply->not_system) != 0xff) {
721 deb_data("NEC extended protocol\n");
722 /* NEC extended code - 24 bits */
723 keycode = be16_to_cpu(poll_reply->system16) << 8 | poll_reply->data;
724 } else {
725 deb_data("NEC normal protocol\n");
726 /* normal NEC code - 16 bits */
727 keycode = poll_reply->system << 8 | poll_reply->data;
728 }
729
730 break;
731 default:
732 deb_data("RC5 protocol\n");
733 /* RC5 Protocol */
734 toggle = poll_reply->report_id;
735 keycode = poll_reply->system << 8 | poll_reply->data;
736
737 break;
738 }
739
740 if ((poll_reply->data + poll_reply->not_data) != 0xff) {
741 /* Key failed integrity check */
742 err("key failed integrity check: %04x %02x %02x",
743 poll_reply->system,
744 poll_reply->data, poll_reply->not_data);
745 goto resubmit;
746 }
747
748 rc_keydown(d->rc_dev, keycode, toggle);
749
750resubmit:
751 /* Clean the buffer before we requeue */
752 memset(purb->transfer_buffer, 0, RC_MSG_SIZE_V1_20);
753
754 /* Requeue URB */
755 usb_submit_urb(purb, GFP_ATOMIC);
756}
757
758int dib0700_rc_setup(struct dvb_usb_device *d)
759{
760 struct dib0700_state *st = d->priv;
761 struct urb *purb;
762 int ret;
763
764 /* Poll-based. Don't initialize bulk mode */
765 if (st->fw_version < 0x10200)
766 return 0;
767
768 /* Starting in firmware 1.20, the RC info is provided on a bulk pipe */
769 purb = usb_alloc_urb(0, GFP_KERNEL);
770 if (purb == NULL) {
771 err("rc usb alloc urb failed");
772 return -ENOMEM;
773 }
774
775 purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL);
776 if (purb->transfer_buffer == NULL) {
777 err("rc kzalloc failed");
778 usb_free_urb(purb);
779 return -ENOMEM;
780 }
781
782 purb->status = -EINPROGRESS;
783 usb_fill_bulk_urb(purb, d->udev, usb_rcvbulkpipe(d->udev, 1),
784 purb->transfer_buffer, RC_MSG_SIZE_V1_20,
785 dib0700_rc_urb_completion, d);
786
787 ret = usb_submit_urb(purb, GFP_ATOMIC);
788 if (ret) {
789 err("rc submit urb failed");
790 kfree(purb->transfer_buffer);
791 usb_free_urb(purb);
792 }
793
794 return ret;
795}
796
797static int dib0700_probe(struct usb_interface *intf,
798 const struct usb_device_id *id)
799{
800 int i;
801 struct dvb_usb_device *dev;
802
803 for (i = 0; i < dib0700_device_count; i++)
804 if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE,
805 &dev, adapter_nr) == 0) {
806 struct dib0700_state *st = dev->priv;
807 u32 hwversion, romversion, fw_version, fwtype;
808
809 dib0700_get_version(dev, &hwversion, &romversion,
810 &fw_version, &fwtype);
811
812 deb_info("Firmware version: %x, %d, 0x%x, %d\n",
813 hwversion, romversion, fw_version, fwtype);
814
815 st->fw_version = fw_version;
816 st->nb_packet_buffer_size = (u32)nb_packet_buffer_size;
817
818 /* Disable polling mode on newer firmwares */
819 if (st->fw_version >= 0x10200)
820 dev->props.rc.core.bulk_mode = true;
821 else
822 dev->props.rc.core.bulk_mode = false;
823
824 dib0700_rc_setup(dev);
825
826 return 0;
827 }
828
829 return -ENODEV;
830}
831
832static struct usb_driver dib0700_driver = {
833 .name = "dvb_usb_dib0700",
834 .probe = dib0700_probe,
835 .disconnect = dvb_usb_device_exit,
836 .id_table = dib0700_usb_id_table,
837};
838
839module_usb_driver(dib0700_driver);
840
841MODULE_FIRMWARE("dvb-usb-dib0700-1.20.fw");
842MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
843MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge");
844MODULE_VERSION("1.0");
845MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
new file mode 100644
index 000000000000..510001da6e83
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
@@ -0,0 +1,4813 @@
1/* Linux driver for devices based on the DiBcom DiB0700 USB bridge
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the Free
5 * Software Foundation, version 2.
6 *
7 * Copyright (C) 2005-9 DiBcom, SA et al
8 */
9#include "dib0700.h"
10
11#include "dib3000mc.h"
12#include "dib7000m.h"
13#include "dib7000p.h"
14#include "dib8000.h"
15#include "dib9000.h"
16#include "mt2060.h"
17#include "mt2266.h"
18#include "tuner-xc2028.h"
19#include "xc5000.h"
20#include "xc4000.h"
21#include "s5h1411.h"
22#include "dib0070.h"
23#include "dib0090.h"
24#include "lgdt3305.h"
25#include "mxl5007t.h"
26
27static int force_lna_activation;
28module_param(force_lna_activation, int, 0644);
29MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), "
30 "if applicable for the device (default: 0=automatic/off).");
31
32struct dib0700_adapter_state {
33 int (*set_param_save) (struct dvb_frontend *);
34 const struct firmware *frontend_firmware;
35};
36
37/* Hauppauge Nova-T 500 (aka Bristol)
38 * has a LNA on GPIO0 which is enabled by setting 1 */
39static struct mt2060_config bristol_mt2060_config[2] = {
40 {
41 .i2c_address = 0x60,
42 .clock_out = 3,
43 }, {
44 .i2c_address = 0x61,
45 }
46};
47
48
49static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = {
50 .band_caps = BAND_VHF | BAND_UHF,
51 .setup = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0),
52
53 .agc1_max = 42598,
54 .agc1_min = 17694,
55 .agc2_max = 45875,
56 .agc2_min = 0,
57
58 .agc1_pt1 = 0,
59 .agc1_pt2 = 59,
60
61 .agc1_slope1 = 0,
62 .agc1_slope2 = 69,
63
64 .agc2_pt1 = 0,
65 .agc2_pt2 = 59,
66
67 .agc2_slope1 = 111,
68 .agc2_slope2 = 28,
69};
70
71static struct dib3000mc_config bristol_dib3000mc_config[2] = {
72 { .agc = &bristol_dib3000p_mt2060_agc_config,
73 .max_time = 0x196,
74 .ln_adc_level = 0x1cc7,
75 .output_mpeg2_in_188_bytes = 1,
76 },
77 { .agc = &bristol_dib3000p_mt2060_agc_config,
78 .max_time = 0x196,
79 .ln_adc_level = 0x1cc7,
80 .output_mpeg2_in_188_bytes = 1,
81 }
82};
83
84static int bristol_frontend_attach(struct dvb_usb_adapter *adap)
85{
86 struct dib0700_state *st = adap->dev->priv;
87 if (adap->id == 0) {
88 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
89 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10);
90 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
91 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10);
92
93 if (force_lna_activation)
94 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
95 else
96 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
97
98 if (dib3000mc_i2c_enumeration(&adap->dev->i2c_adap, 2, DEFAULT_DIB3000P_I2C_ADDRESS, bristol_dib3000mc_config) != 0) {
99 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10);
100 return -ENODEV;
101 }
102 }
103 st->mt2060_if1[adap->id] = 1220;
104 return (adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap,
105 (10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0;
106}
107
108static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval)
109{
110 struct i2c_msg msg[2] = {
111 { .addr = 0x50, .flags = 0, .buf = &adrs, .len = 1 },
112 { .addr = 0x50, .flags = I2C_M_RD, .buf = pval, .len = 1 },
113 };
114 if (i2c_transfer(adap, msg, 2) != 2) return -EREMOTEIO;
115 return 0;
116}
117
118static int bristol_tuner_attach(struct dvb_usb_adapter *adap)
119{
120 struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
121 struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe_adap[0].fe, 1);
122 s8 a;
123 int if1=1220;
124 if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) &&
125 adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_500_2)) {
126 if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a;
127 }
128 return dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c,
129 &bristol_mt2060_config[adap->id], if1) == NULL ?
130 -ENODEV : 0;
131}
132
133/* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */
134
135/* MT226x */
136static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = {
137 {
138 BAND_UHF,
139
140 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
141 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
142 (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
143 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
144
145 1130,
146 21,
147
148 0,
149 118,
150
151 0,
152 3530,
153 1,
154 0,
155
156 65535,
157 33770,
158 65535,
159 23592,
160
161 0,
162 62,
163 255,
164 64,
165 64,
166 132,
167 192,
168 80,
169 80,
170
171 17,
172 27,
173 23,
174 51,
175
176 1,
177 }, {
178 BAND_VHF | BAND_LBAND,
179
180 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1,
181 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
182 (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8)
183 | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
184
185 2372,
186 21,
187
188 0,
189 118,
190
191 0,
192 3530,
193 1,
194 0,
195
196 65535,
197 0,
198 65535,
199 23592,
200
201 0,
202 128,
203 128,
204 128,
205 0,
206 128,
207 253,
208 81,
209 0,
210
211 17,
212 27,
213 23,
214 51,
215
216 1,
217 }
218};
219
220static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = {
221 60000, 30000,
222 1, 8, 3, 1, 0,
223 0, 0, 1, 1, 2,
224 (3 << 14) | (1 << 12) | (524 << 0),
225 0,
226 20452225,
227};
228
229static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = {
230 { .output_mpeg2_in_188_bytes = 1,
231 .hostbus_diversity = 1,
232 .tuner_is_baseband = 1,
233
234 .agc_config_count = 2,
235 .agc = stk7700d_7000p_mt2266_agc_config,
236 .bw = &stk7700d_mt2266_pll_config,
237
238 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
239 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
240 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
241 },
242 { .output_mpeg2_in_188_bytes = 1,
243 .hostbus_diversity = 1,
244 .tuner_is_baseband = 1,
245
246 .agc_config_count = 2,
247 .agc = stk7700d_7000p_mt2266_agc_config,
248 .bw = &stk7700d_mt2266_pll_config,
249
250 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
251 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
252 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
253 }
254};
255
256static struct mt2266_config stk7700d_mt2266_config[2] = {
257 { .i2c_address = 0x60
258 },
259 { .i2c_address = 0x60
260 }
261};
262
263static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
264{
265 if (adap->id == 0) {
266 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
267 msleep(10);
268 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
269 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
270 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
271 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
272 msleep(10);
273 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
274 msleep(10);
275 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
276 stk7700d_dib7000p_mt2266_config)
277 != 0) {
278 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
279 return -ENODEV;
280 }
281 }
282
283 adap->fe_adap[0].fe =
284 dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
285 0x80 + (adap->id << 1),
286 &stk7700d_dib7000p_mt2266_config[adap->id]);
287
288 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
289}
290
291static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
292{
293 if (adap->id == 0) {
294 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
295 msleep(10);
296 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
297 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
298 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
299 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
300 msleep(10);
301 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
302 msleep(10);
303 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
304 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
305 stk7700d_dib7000p_mt2266_config)
306 != 0) {
307 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
308 return -ENODEV;
309 }
310 }
311
312 adap->fe_adap[0].fe =
313 dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
314 0x80 + (adap->id << 1),
315 &stk7700d_dib7000p_mt2266_config[adap->id]);
316
317 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
318}
319
320static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
321{
322 struct i2c_adapter *tun_i2c;
323 tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
324 return dvb_attach(mt2266_attach, adap->fe_adap[0].fe, tun_i2c,
325 &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;
326}
327
328/* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
329static struct dibx000_agc_config xc3028_agc_config = {
330 BAND_VHF | BAND_UHF, /* band_caps */
331
332 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
333 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
334 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
335 (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
336 (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */
337
338 712, /* inv_gain */
339 21, /* time_stabiliz */
340
341 0, /* alpha_level */
342 118, /* thlock */
343
344 0, /* wbd_inv */
345 2867, /* wbd_ref */
346 0, /* wbd_sel */
347 2, /* wbd_alpha */
348
349 0, /* agc1_max */
350 0, /* agc1_min */
351 39718, /* agc2_max */
352 9930, /* agc2_min */
353 0, /* agc1_pt1 */
354 0, /* agc1_pt2 */
355 0, /* agc1_pt3 */
356 0, /* agc1_slope1 */
357 0, /* agc1_slope2 */
358 0, /* agc2_pt1 */
359 128, /* agc2_pt2 */
360 29, /* agc2_slope1 */
361 29, /* agc2_slope2 */
362
363 17, /* alpha_mant */
364 27, /* alpha_exp */
365 23, /* beta_mant */
366 51, /* beta_exp */
367
368 1, /* perform_agc_softsplit */
369};
370
371/* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */
372static struct dibx000_bandwidth_config xc3028_bw_config = {
373 60000, 30000, /* internal, sampling */
374 1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
375 0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc,
376 modulo */
377 (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
378 (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
379 20452225, /* timf */
380 30000000, /* xtal_hz */
381};
382
383static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
384 .output_mpeg2_in_188_bytes = 1,
385 .tuner_is_baseband = 1,
386
387 .agc_config_count = 1,
388 .agc = &xc3028_agc_config,
389 .bw = &xc3028_bw_config,
390
391 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
392 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
393 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
394};
395
396static int stk7700ph_xc3028_callback(void *ptr, int component,
397 int command, int arg)
398{
399 struct dvb_usb_adapter *adap = ptr;
400
401 switch (command) {
402 case XC2028_TUNER_RESET:
403 /* Send the tuner in then out of reset */
404 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0); msleep(10);
405 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
406 break;
407 case XC2028_RESET_CLK:
408 break;
409 default:
410 err("%s: unknown command %d, arg %d\n", __func__,
411 command, arg);
412 return -EINVAL;
413 }
414 return 0;
415}
416
417static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
418 .fname = XC2028_DEFAULT_FIRMWARE,
419 .max_len = 64,
420 .demod = XC3028_FE_DIBCOM52,
421};
422
423static struct xc2028_config stk7700ph_xc3028_config = {
424 .i2c_addr = 0x61,
425 .ctrl = &stk7700ph_xc3028_ctrl,
426};
427
428static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
429{
430 struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;
431
432 if (desc->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
433 desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX))
434 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
435 else
436 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
437 msleep(20);
438 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
439 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
440 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
441 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
442 msleep(10);
443 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
444 msleep(20);
445 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
446 msleep(10);
447
448 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
449 &stk7700ph_dib7700_xc3028_config) != 0) {
450 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
451 __func__);
452 return -ENODEV;
453 }
454
455 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
456 &stk7700ph_dib7700_xc3028_config);
457
458 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
459}
460
461static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
462{
463 struct i2c_adapter *tun_i2c;
464
465 tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
466 DIBX000_I2C_INTERFACE_TUNER, 1);
467
468 stk7700ph_xc3028_config.i2c_adap = tun_i2c;
469
470 /* FIXME: generalize & move to common area */
471 adap->fe_adap[0].fe->callback = stk7700ph_xc3028_callback;
472
473 return dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &stk7700ph_xc3028_config)
474 == NULL ? -ENODEV : 0;
475}
476
477#define DEFAULT_RC_INTERVAL 50
478
479static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
480
481/* Number of keypresses to ignore before start repeating */
482#define RC_REPEAT_DELAY 6
483
484/*
485 * This function is used only when firmware is < 1.20 version. Newer
486 * firmwares use bulk mode, with functions implemented at dib0700_core,
487 * at dib0700_rc_urb_completion()
488 */
489static int dib0700_rc_query_old_firmware(struct dvb_usb_device *d)
490{
491 u8 key[4];
492 u32 keycode;
493 u8 toggle;
494 int i;
495 struct dib0700_state *st = d->priv;
496
497 if (st->fw_version >= 0x10200) {
498 /* For 1.20 firmware , We need to keep the RC polling
499 callback so we can reuse the input device setup in
500 dvb-usb-remote.c. However, the actual work is being done
501 in the bulk URB completion handler. */
502 return 0;
503 }
504
505 i = dib0700_ctrl_rd(d, rc_request, 2, key, 4);
506 if (i <= 0) {
507 err("RC Query Failed");
508 return -1;
509 }
510
511 /* losing half of KEY_0 events from Philipps rc5 remotes.. */
512 if (key[0] == 0 && key[1] == 0 && key[2] == 0 && key[3] == 0)
513 return 0;
514
515 /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]); */
516
517 dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */
518
519 d->last_event = 0;
520 switch (d->props.rc.core.protocol) {
521 case RC_TYPE_NEC:
522 /* NEC protocol sends repeat code as 0 0 0 FF */
523 if ((key[3-2] == 0x00) && (key[3-3] == 0x00) &&
524 (key[3] == 0xff))
525 keycode = d->last_event;
526 else {
527 keycode = key[3-2] << 8 | key[3-3];
528 d->last_event = keycode;
529 }
530
531 rc_keydown(d->rc_dev, keycode, 0);
532 break;
533 default:
534 /* RC-5 protocol changes toggle bit on new keypress */
535 keycode = key[3-2] << 8 | key[3-3];
536 toggle = key[3-1];
537 rc_keydown(d->rc_dev, keycode, toggle);
538
539 break;
540 }
541 return 0;
542}
543
544/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */
545static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = {
546 BAND_UHF | BAND_VHF,
547
548 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
549 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
550 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
551 | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
552
553 712,
554 41,
555
556 0,
557 118,
558
559 0,
560 4095,
561 0,
562 0,
563
564 42598,
565 17694,
566 45875,
567 2621,
568 0,
569 76,
570 139,
571 52,
572 59,
573 107,
574 172,
575 57,
576 70,
577
578 21,
579 25,
580 28,
581 48,
582
583 1,
584 { 0,
585 107,
586 51800,
587 24700
588 },
589};
590
591static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = {
592 BAND_UHF | BAND_VHF,
593
594 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
595 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
596 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
597 | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0),
598
599 712,
600 41,
601
602 0,
603 118,
604
605 0,
606 4095,
607 0,
608 0,
609
610 42598,
611 16384,
612 42598,
613 0,
614
615 0,
616 137,
617 255,
618
619 0,
620 255,
621
622 0,
623 0,
624
625 0,
626 41,
627
628 15,
629 25,
630
631 28,
632 48,
633
634 0,
635};
636
637static struct dibx000_bandwidth_config stk7700p_pll_config = {
638 60000, 30000,
639 1, 8, 3, 1, 0,
640 0, 0, 1, 1, 0,
641 (3 << 14) | (1 << 12) | (524 << 0),
642 60258167,
643 20452225,
644 30000000,
645};
646
647static struct dib7000m_config stk7700p_dib7000m_config = {
648 .dvbt_mode = 1,
649 .output_mpeg2_in_188_bytes = 1,
650 .quartz_direct = 1,
651
652 .agc_config_count = 1,
653 .agc = &stk7700p_7000m_mt2060_agc_config,
654 .bw = &stk7700p_pll_config,
655
656 .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
657 .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
658 .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
659};
660
661static struct dib7000p_config stk7700p_dib7000p_config = {
662 .output_mpeg2_in_188_bytes = 1,
663
664 .agc_config_count = 1,
665 .agc = &stk7700p_7000p_mt2060_agc_config,
666 .bw = &stk7700p_pll_config,
667
668 .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
669 .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
670 .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
671};
672
673static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap)
674{
675 struct dib0700_state *st = adap->dev->priv;
676 /* unless there is no real power management in DVB - we leave the device on GPIO6 */
677
678 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
679 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(50);
680
681 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10);
682 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
683
684 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10);
685 dib0700_ctrl_clock(adap->dev, 72, 1);
686 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100);
687
688 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
689
690 st->mt2060_if1[0] = 1220;
691
692 if (dib7000pc_detection(&adap->dev->i2c_adap)) {
693 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config);
694 st->is_dib7000pc = 1;
695 } else
696 adap->fe_adap[0].fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config);
697
698 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
699}
700
701static struct mt2060_config stk7700p_mt2060_config = {
702 0x60
703};
704
705static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap)
706{
707 struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap;
708 struct dib0700_state *st = adap->dev->priv;
709 struct i2c_adapter *tun_i2c;
710 s8 a;
711 int if1=1220;
712 if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) &&
713 adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) {
714 if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a;
715 }
716 if (st->is_dib7000pc)
717 tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
718 else
719 tun_i2c = dib7000m_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
720
721 return dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c, &stk7700p_mt2060_config,
722 if1) == NULL ? -ENODEV : 0;
723}
724
725/* DIB7070 generic */
726static struct dibx000_agc_config dib7070_agc_config = {
727 BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
728 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
729 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
730 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
731 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
732
733 600,
734 10,
735
736 0,
737 118,
738
739 0,
740 3530,
741 1,
742 5,
743
744 65535,
745 0,
746
747 65535,
748 0,
749
750 0,
751 40,
752 183,
753 206,
754 255,
755 72,
756 152,
757 88,
758 90,
759
760 17,
761 27,
762 23,
763 51,
764
765 0,
766};
767
768static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
769{
770 deb_info("reset: %d", onoff);
771 return dib7000p_set_gpio(fe, 8, 0, !onoff);
772}
773
774static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
775{
776 deb_info("sleep: %d", onoff);
777 return dib7000p_set_gpio(fe, 9, 0, onoff);
778}
779
780static struct dib0070_config dib7070p_dib0070_config[2] = {
781 {
782 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
783 .reset = dib7070_tuner_reset,
784 .sleep = dib7070_tuner_sleep,
785 .clock_khz = 12000,
786 .clock_pad_drive = 4,
787 .charge_pump = 2,
788 }, {
789 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
790 .reset = dib7070_tuner_reset,
791 .sleep = dib7070_tuner_sleep,
792 .clock_khz = 12000,
793 .charge_pump = 2,
794 }
795};
796
797static struct dib0070_config dib7770p_dib0070_config = {
798 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
799 .reset = dib7070_tuner_reset,
800 .sleep = dib7070_tuner_sleep,
801 .clock_khz = 12000,
802 .clock_pad_drive = 0,
803 .flip_chip = 1,
804 .charge_pump = 2,
805};
806
807static int dib7070_set_param_override(struct dvb_frontend *fe)
808{
809 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
810 struct dvb_usb_adapter *adap = fe->dvb->priv;
811 struct dib0700_adapter_state *state = adap->priv;
812
813 u16 offset;
814 u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
815 switch (band) {
816 case BAND_VHF: offset = 950; break;
817 case BAND_UHF:
818 default: offset = 550; break;
819 }
820 deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
821 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
822 return state->set_param_save(fe);
823}
824
825static int dib7770_set_param_override(struct dvb_frontend *fe)
826{
827 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
828 struct dvb_usb_adapter *adap = fe->dvb->priv;
829 struct dib0700_adapter_state *state = adap->priv;
830
831 u16 offset;
832 u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
833 switch (band) {
834 case BAND_VHF:
835 dib7000p_set_gpio(fe, 0, 0, 1);
836 offset = 850;
837 break;
838 case BAND_UHF:
839 default:
840 dib7000p_set_gpio(fe, 0, 0, 0);
841 offset = 250;
842 break;
843 }
844 deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
845 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
846 return state->set_param_save(fe);
847}
848
849static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap)
850{
851 struct dib0700_adapter_state *st = adap->priv;
852 struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
853 DIBX000_I2C_INTERFACE_TUNER, 1);
854
855 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
856 &dib7770p_dib0070_config) == NULL)
857 return -ENODEV;
858
859 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
860 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7770_set_param_override;
861 return 0;
862}
863
864static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
865{
866 struct dib0700_adapter_state *st = adap->priv;
867 struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
868
869 if (adap->id == 0) {
870 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL)
871 return -ENODEV;
872 } else {
873 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL)
874 return -ENODEV;
875 }
876
877 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
878 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override;
879 return 0;
880}
881
882static int stk7700p_pid_filter(struct dvb_usb_adapter *adapter, int index,
883 u16 pid, int onoff)
884{
885 struct dib0700_state *st = adapter->dev->priv;
886 if (st->is_dib7000pc)
887 return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
888 return dib7000m_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
889}
890
891static int stk7700p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
892{
893 struct dib0700_state *st = adapter->dev->priv;
894 if (st->is_dib7000pc)
895 return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
896 return dib7000m_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
897}
898
899static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
900{
901 return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
902}
903
904static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
905{
906 return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
907}
908
909static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = {
910 60000, 15000,
911 1, 20, 3, 1, 0,
912 0, 0, 1, 1, 2,
913 (3 << 14) | (1 << 12) | (524 << 0),
914 (0 << 25) | 0,
915 20452225,
916 12000000,
917};
918
919static struct dib7000p_config dib7070p_dib7000p_config = {
920 .output_mpeg2_in_188_bytes = 1,
921
922 .agc_config_count = 1,
923 .agc = &dib7070_agc_config,
924 .bw = &dib7070_bw_config_12_mhz,
925 .tuner_is_baseband = 1,
926 .spur_protect = 1,
927
928 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
929 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
930 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
931
932 .hostbus_diversity = 1,
933};
934
935/* STK7070P */
936static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
937{
938 struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
939 if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
940 p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
941 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
942 else
943 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
944 msleep(10);
945 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
946 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
947 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
948 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
949
950 dib0700_ctrl_clock(adap->dev, 72, 1);
951
952 msleep(10);
953 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
954 msleep(10);
955 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
956
957 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
958 &dib7070p_dib7000p_config) != 0) {
959 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
960 __func__);
961 return -ENODEV;
962 }
963
964 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
965 &dib7070p_dib7000p_config);
966 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
967}
968
969/* STK7770P */
970static struct dib7000p_config dib7770p_dib7000p_config = {
971 .output_mpeg2_in_188_bytes = 1,
972
973 .agc_config_count = 1,
974 .agc = &dib7070_agc_config,
975 .bw = &dib7070_bw_config_12_mhz,
976 .tuner_is_baseband = 1,
977 .spur_protect = 1,
978
979 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
980 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
981 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
982
983 .hostbus_diversity = 1,
984 .enable_current_mirror = 1,
985 .disable_sample_and_hold = 0,
986};
987
988static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap)
989{
990 struct usb_device_descriptor *p = &adap->dev->udev->descriptor;
991 if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) &&
992 p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E))
993 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
994 else
995 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
996 msleep(10);
997 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
998 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
999 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1000 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1001
1002 dib0700_ctrl_clock(adap->dev, 72, 1);
1003
1004 msleep(10);
1005 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1006 msleep(10);
1007 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1008
1009 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1010 &dib7770p_dib7000p_config) != 0) {
1011 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
1012 __func__);
1013 return -ENODEV;
1014 }
1015
1016 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
1017 &dib7770p_dib7000p_config);
1018 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
1019}
1020
1021/* DIB807x generic */
1022static struct dibx000_agc_config dib807x_agc_config[2] = {
1023 {
1024 BAND_VHF,
1025 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1026 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1027 * P_agc_inv_pwm2=0,P_agc_inh_dc_rv_est=0,
1028 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1029 * P_agc_write=0 */
1030 (0 << 15) | (0 << 14) | (7 << 11) | (0 << 10) | (0 << 9) |
1031 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
1032 (0 << 0), /* setup*/
1033
1034 600, /* inv_gain*/
1035 10, /* time_stabiliz*/
1036
1037 0, /* alpha_level*/
1038 118, /* thlock*/
1039
1040 0, /* wbd_inv*/
1041 3530, /* wbd_ref*/
1042 1, /* wbd_sel*/
1043 5, /* wbd_alpha*/
1044
1045 65535, /* agc1_max*/
1046 0, /* agc1_min*/
1047
1048 65535, /* agc2_max*/
1049 0, /* agc2_min*/
1050
1051 0, /* agc1_pt1*/
1052 40, /* agc1_pt2*/
1053 183, /* agc1_pt3*/
1054 206, /* agc1_slope1*/
1055 255, /* agc1_slope2*/
1056 72, /* agc2_pt1*/
1057 152, /* agc2_pt2*/
1058 88, /* agc2_slope1*/
1059 90, /* agc2_slope2*/
1060
1061 17, /* alpha_mant*/
1062 27, /* alpha_exp*/
1063 23, /* beta_mant*/
1064 51, /* beta_exp*/
1065
1066 0, /* perform_agc_softsplit*/
1067 }, {
1068 BAND_UHF,
1069 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1070 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1071 * P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1072 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1073 * P_agc_write=0 */
1074 (0 << 15) | (0 << 14) | (1 << 11) | (0 << 10) | (0 << 9) |
1075 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
1076 (0 << 0), /* setup */
1077
1078 600, /* inv_gain*/
1079 10, /* time_stabiliz*/
1080
1081 0, /* alpha_level*/
1082 118, /* thlock*/
1083
1084 0, /* wbd_inv*/
1085 3530, /* wbd_ref*/
1086 1, /* wbd_sel*/
1087 5, /* wbd_alpha*/
1088
1089 65535, /* agc1_max*/
1090 0, /* agc1_min*/
1091
1092 65535, /* agc2_max*/
1093 0, /* agc2_min*/
1094
1095 0, /* agc1_pt1*/
1096 40, /* agc1_pt2*/
1097 183, /* agc1_pt3*/
1098 206, /* agc1_slope1*/
1099 255, /* agc1_slope2*/
1100 72, /* agc2_pt1*/
1101 152, /* agc2_pt2*/
1102 88, /* agc2_slope1*/
1103 90, /* agc2_slope2*/
1104
1105 17, /* alpha_mant*/
1106 27, /* alpha_exp*/
1107 23, /* beta_mant*/
1108 51, /* beta_exp*/
1109
1110 0, /* perform_agc_softsplit*/
1111 }
1112};
1113
1114static struct dibx000_bandwidth_config dib807x_bw_config_12_mhz = {
1115 60000, 15000, /* internal, sampling*/
1116 1, 20, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass*/
1117 0, 0, 1, 1, 2, /* misc: refdiv, bypclk_div, IO_CLK_en_core,
1118 ADClkSrc, modulo */
1119 (3 << 14) | (1 << 12) | (599 << 0), /* sad_cfg: refsel, sel, freq_15k*/
1120 (0 << 25) | 0, /* ifreq = 0.000000 MHz*/
1121 18179755, /* timf*/
1122 12000000, /* xtal_hz*/
1123};
1124
1125static struct dib8000_config dib807x_dib8000_config[2] = {
1126 {
1127 .output_mpeg2_in_188_bytes = 1,
1128
1129 .agc_config_count = 2,
1130 .agc = dib807x_agc_config,
1131 .pll = &dib807x_bw_config_12_mhz,
1132 .tuner_is_baseband = 1,
1133
1134 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1135 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1136 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1137
1138 .hostbus_diversity = 1,
1139 .div_cfg = 1,
1140 .agc_control = &dib0070_ctrl_agc_filter,
1141 .output_mode = OUTMODE_MPEG2_FIFO,
1142 .drives = 0x2d98,
1143 }, {
1144 .output_mpeg2_in_188_bytes = 1,
1145
1146 .agc_config_count = 2,
1147 .agc = dib807x_agc_config,
1148 .pll = &dib807x_bw_config_12_mhz,
1149 .tuner_is_baseband = 1,
1150
1151 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1152 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1153 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1154
1155 .hostbus_diversity = 1,
1156 .agc_control = &dib0070_ctrl_agc_filter,
1157 .output_mode = OUTMODE_MPEG2_FIFO,
1158 .drives = 0x2d98,
1159 }
1160};
1161
1162static int dib80xx_tuner_reset(struct dvb_frontend *fe, int onoff)
1163{
1164 return dib8000_set_gpio(fe, 5, 0, !onoff);
1165}
1166
1167static int dib80xx_tuner_sleep(struct dvb_frontend *fe, int onoff)
1168{
1169 return dib8000_set_gpio(fe, 0, 0, onoff);
1170}
1171
1172static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
1173 { 240, 7},
1174 { 0xffff, 6},
1175};
1176
1177static struct dib0070_config dib807x_dib0070_config[2] = {
1178 {
1179 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1180 .reset = dib80xx_tuner_reset,
1181 .sleep = dib80xx_tuner_sleep,
1182 .clock_khz = 12000,
1183 .clock_pad_drive = 4,
1184 .vga_filter = 1,
1185 .force_crystal_mode = 1,
1186 .enable_third_order_filter = 1,
1187 .charge_pump = 0,
1188 .wbd_gain = dib8070_wbd_gain_cfg,
1189 .osc_buffer_state = 0,
1190 .freq_offset_khz_uhf = -100,
1191 .freq_offset_khz_vhf = -100,
1192 }, {
1193 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1194 .reset = dib80xx_tuner_reset,
1195 .sleep = dib80xx_tuner_sleep,
1196 .clock_khz = 12000,
1197 .clock_pad_drive = 2,
1198 .vga_filter = 1,
1199 .force_crystal_mode = 1,
1200 .enable_third_order_filter = 1,
1201 .charge_pump = 0,
1202 .wbd_gain = dib8070_wbd_gain_cfg,
1203 .osc_buffer_state = 0,
1204 .freq_offset_khz_uhf = -25,
1205 .freq_offset_khz_vhf = -25,
1206 }
1207};
1208
1209static int dib807x_set_param_override(struct dvb_frontend *fe)
1210{
1211 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1212 struct dvb_usb_adapter *adap = fe->dvb->priv;
1213 struct dib0700_adapter_state *state = adap->priv;
1214
1215 u16 offset = dib0070_wbd_offset(fe);
1216 u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
1217 switch (band) {
1218 case BAND_VHF:
1219 offset += 750;
1220 break;
1221 case BAND_UHF: /* fall-thru wanted */
1222 default:
1223 offset += 250; break;
1224 }
1225 deb_info("WBD for DiB8000: %d\n", offset);
1226 dib8000_set_wbd_ref(fe, offset);
1227
1228 return state->set_param_save(fe);
1229}
1230
1231static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
1232{
1233 struct dib0700_adapter_state *st = adap->priv;
1234 struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe,
1235 DIBX000_I2C_INTERFACE_TUNER, 1);
1236
1237 if (adap->id == 0) {
1238 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
1239 &dib807x_dib0070_config[0]) == NULL)
1240 return -ENODEV;
1241 } else {
1242 if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c,
1243 &dib807x_dib0070_config[1]) == NULL)
1244 return -ENODEV;
1245 }
1246
1247 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
1248 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib807x_set_param_override;
1249 return 0;
1250}
1251
1252static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
1253 u16 pid, int onoff)
1254{
1255 return dib8000_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
1256}
1257
1258static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
1259 int onoff)
1260{
1261 return dib8000_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
1262}
1263
1264/* STK807x */
1265static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
1266{
1267 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1268 msleep(10);
1269 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1270 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1271 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1272
1273 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1274
1275 dib0700_ctrl_clock(adap->dev, 72, 1);
1276
1277 msleep(10);
1278 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1279 msleep(10);
1280 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1281
1282 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1283 0x80, 0);
1284
1285 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
1286 &dib807x_dib8000_config[0]);
1287
1288 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
1289}
1290
1291/* STK807xPVR */
1292static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
1293{
1294 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1295 msleep(30);
1296 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1297 msleep(500);
1298 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1299 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1300 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1301
1302 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1303
1304 dib0700_ctrl_clock(adap->dev, 72, 1);
1305
1306 msleep(10);
1307 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1308 msleep(10);
1309 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1310
1311 /* initialize IC 0 */
1312 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80, 0);
1313
1314 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
1315 &dib807x_dib8000_config[0]);
1316
1317 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
1318}
1319
1320static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
1321{
1322 /* initialize IC 1 */
1323 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82, 0);
1324
1325 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
1326 &dib807x_dib8000_config[1]);
1327
1328 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
1329}
1330
1331/* STK8096GP */
1332static struct dibx000_agc_config dib8090_agc_config[2] = {
1333 {
1334 BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
1335 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
1336 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1337 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
1338 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
1339 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1340
1341 787,
1342 10,
1343
1344 0,
1345 118,
1346
1347 0,
1348 3530,
1349 1,
1350 5,
1351
1352 65535,
1353 0,
1354
1355 65535,
1356 0,
1357
1358 0,
1359 32,
1360 114,
1361 143,
1362 144,
1363 114,
1364 227,
1365 116,
1366 117,
1367
1368 28,
1369 26,
1370 31,
1371 51,
1372
1373 0,
1374 },
1375 {
1376 BAND_CBAND,
1377 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
1378 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1379 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
1380 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
1381 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1382
1383 787,
1384 10,
1385
1386 0,
1387 118,
1388
1389 0,
1390 3530,
1391 1,
1392 5,
1393
1394 0,
1395 0,
1396
1397 65535,
1398 0,
1399
1400 0,
1401 32,
1402 114,
1403 143,
1404 144,
1405 114,
1406 227,
1407 116,
1408 117,
1409
1410 28,
1411 26,
1412 31,
1413 51,
1414
1415 0,
1416 }
1417};
1418
1419static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
1420 54000, 13500,
1421 1, 18, 3, 1, 0,
1422 0, 0, 1, 1, 2,
1423 (3 << 14) | (1 << 12) | (599 << 0),
1424 (0 << 25) | 0,
1425 20199727,
1426 12000000,
1427};
1428
1429static int dib8090_get_adc_power(struct dvb_frontend *fe)
1430{
1431 return dib8000_get_adc_power(fe, 1);
1432}
1433
1434static struct dib8000_config dib809x_dib8000_config[2] = {
1435 {
1436 .output_mpeg2_in_188_bytes = 1,
1437
1438 .agc_config_count = 2,
1439 .agc = dib8090_agc_config,
1440 .agc_control = dib0090_dcc_freq,
1441 .pll = &dib8090_pll_config_12mhz,
1442 .tuner_is_baseband = 1,
1443
1444 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1445 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1446 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1447
1448 .hostbus_diversity = 1,
1449 .div_cfg = 0x31,
1450 .output_mode = OUTMODE_MPEG2_FIFO,
1451 .drives = 0x2d98,
1452 .diversity_delay = 48,
1453 .refclksel = 3,
1454 }, {
1455 .output_mpeg2_in_188_bytes = 1,
1456
1457 .agc_config_count = 2,
1458 .agc = dib8090_agc_config,
1459 .agc_control = dib0090_dcc_freq,
1460 .pll = &dib8090_pll_config_12mhz,
1461 .tuner_is_baseband = 1,
1462
1463 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1464 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1465 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1466
1467 .hostbus_diversity = 1,
1468 .div_cfg = 0x31,
1469 .output_mode = OUTMODE_DIVERSITY,
1470 .drives = 0x2d08,
1471 .diversity_delay = 1,
1472 .refclksel = 3,
1473 }
1474};
1475
1476static struct dib0090_wbd_slope dib8090_wbd_table[] = {
1477 /* max freq ; cold slope ; cold offset ; warm slope ; warm offset ; wbd gain */
1478 { 120, 0, 500, 0, 500, 4 }, /* CBAND */
1479 { 170, 0, 450, 0, 450, 4 }, /* CBAND */
1480 { 380, 48, 373, 28, 259, 6 }, /* VHF */
1481 { 860, 34, 700, 36, 616, 6 }, /* high UHF */
1482 { 0xFFFF, 34, 700, 36, 616, 6 }, /* default */
1483};
1484
1485static struct dib0090_config dib809x_dib0090_config = {
1486 .io.pll_bypass = 1,
1487 .io.pll_range = 1,
1488 .io.pll_prediv = 1,
1489 .io.pll_loopdiv = 20,
1490 .io.adc_clock_ratio = 8,
1491 .io.pll_int_loop_filt = 0,
1492 .io.clock_khz = 12000,
1493 .reset = dib80xx_tuner_reset,
1494 .sleep = dib80xx_tuner_sleep,
1495 .clkouttobamse = 1,
1496 .analog_output = 1,
1497 .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
1498 .use_pwm_agc = 1,
1499 .clkoutdrive = 1,
1500 .get_adc_power = dib8090_get_adc_power,
1501 .freq_offset_khz_uhf = -63,
1502 .freq_offset_khz_vhf = -143,
1503 .wbd = dib8090_wbd_table,
1504 .fref_clock_ratio = 6,
1505};
1506
1507static int dib8096_set_param_override(struct dvb_frontend *fe)
1508{
1509 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1510 struct dvb_usb_adapter *adap = fe->dvb->priv;
1511 struct dib0700_adapter_state *state = adap->priv;
1512 u8 band = BAND_OF_FREQUENCY(p->frequency/1000);
1513 u16 target;
1514 int ret = 0;
1515 enum frontend_tune_state tune_state = CT_SHUTDOWN;
1516 u16 ltgain, rf_gain_limit;
1517
1518 ret = state->set_param_save(fe);
1519 if (ret < 0)
1520 return ret;
1521
1522 target = (dib0090_get_wbd_target(fe) * 8 * 18 / 33 + 1) / 2;
1523 dib8000_set_wbd_ref(fe, target);
1524
1525
1526 if (band == BAND_CBAND) {
1527 deb_info("tuning in CBAND - soft-AGC startup\n");
1528 dib0090_set_tune_state(fe, CT_AGC_START);
1529 do {
1530 ret = dib0090_gain_control(fe);
1531 msleep(ret);
1532 tune_state = dib0090_get_tune_state(fe);
1533 if (tune_state == CT_AGC_STEP_0)
1534 dib8000_set_gpio(fe, 6, 0, 1);
1535 else if (tune_state == CT_AGC_STEP_1) {
1536 dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
1537 if (rf_gain_limit == 0)
1538 dib8000_set_gpio(fe, 6, 0, 0);
1539 }
1540 } while (tune_state < CT_AGC_STOP);
1541 dib0090_pwm_gain_reset(fe);
1542 dib8000_pwm_agc_reset(fe);
1543 dib8000_set_tune_state(fe, CT_DEMOD_START);
1544 } else {
1545 deb_info("not tuning in CBAND - standard AGC startup\n");
1546 dib0090_pwm_gain_reset(fe);
1547 }
1548
1549 return 0;
1550}
1551
1552static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
1553{
1554 struct dib0700_adapter_state *st = adap->priv;
1555 struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1556
1557 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
1558 return -ENODEV;
1559
1560 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
1561 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096_set_param_override;
1562 return 0;
1563}
1564
1565static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
1566{
1567 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1568 msleep(10);
1569 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1570 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1571 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1572
1573 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1574
1575 dib0700_ctrl_clock(adap->dev, 72, 1);
1576
1577 msleep(10);
1578 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1579 msleep(10);
1580 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1581
1582 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80, 0);
1583
1584 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
1585
1586 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
1587}
1588
1589static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap)
1590{
1591 struct dib0700_adapter_state *st = adap->priv;
1592 struct i2c_adapter *tun_i2c;
1593 struct dvb_frontend *fe_slave = dib8000_get_slave_frontend(adap->fe_adap[0].fe, 1);
1594
1595 if (fe_slave) {
1596 tun_i2c = dib8000_get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1);
1597 if (dvb_attach(dib0090_register, fe_slave, tun_i2c, &dib809x_dib0090_config) == NULL)
1598 return -ENODEV;
1599 fe_slave->dvb = adap->fe_adap[0].fe->dvb;
1600 fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override;
1601 }
1602 tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1603 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL)
1604 return -ENODEV;
1605
1606 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
1607 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096_set_param_override;
1608
1609 return 0;
1610}
1611
1612static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap)
1613{
1614 struct dvb_frontend *fe_slave;
1615
1616 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1617 msleep(20);
1618 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1619 msleep(1000);
1620 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1621 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1622 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1623
1624 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1625
1626 dib0700_ctrl_clock(adap->dev, 72, 1);
1627
1628 msleep(20);
1629 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1630 msleep(20);
1631 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1632
1633 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80, 0);
1634
1635 adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
1636 if (adap->fe_adap[0].fe == NULL)
1637 return -ENODEV;
1638
1639 fe_slave = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]);
1640 dib8000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave);
1641
1642 return fe_slave == NULL ? -ENODEV : 0;
1643}
1644
1645/* TFE8096P */
1646static struct dibx000_agc_config dib8096p_agc_config[2] = {
1647 {
1648 .band_caps = BAND_UHF,
1649 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1650 P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1651 P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1652 P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1653 P_agc_write=0 */
1654 .setup = (0 << 15) | (0 << 14) | (5 << 11)
1655 | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5)
1656 | (0 << 4) | (5 << 1) | (0 << 0),
1657
1658 .inv_gain = 684,
1659 .time_stabiliz = 10,
1660
1661 .alpha_level = 0,
1662 .thlock = 118,
1663
1664 .wbd_inv = 0,
1665 .wbd_ref = 1200,
1666 .wbd_sel = 3,
1667 .wbd_alpha = 5,
1668
1669 .agc1_max = 65535,
1670 .agc1_min = 0,
1671
1672 .agc2_max = 32767,
1673 .agc2_min = 0,
1674
1675 .agc1_pt1 = 0,
1676 .agc1_pt2 = 0,
1677 .agc1_pt3 = 105,
1678 .agc1_slope1 = 0,
1679 .agc1_slope2 = 156,
1680 .agc2_pt1 = 105,
1681 .agc2_pt2 = 255,
1682 .agc2_slope1 = 54,
1683 .agc2_slope2 = 0,
1684
1685 .alpha_mant = 28,
1686 .alpha_exp = 26,
1687 .beta_mant = 31,
1688 .beta_exp = 51,
1689
1690 .perform_agc_softsplit = 0,
1691 } , {
1692 .band_caps = BAND_FM | BAND_VHF | BAND_CBAND,
1693 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1694 P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1695 P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1696 P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1697 P_agc_write=0 */
1698 .setup = (0 << 15) | (0 << 14) | (5 << 11)
1699 | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5)
1700 | (0 << 4) | (5 << 1) | (0 << 0),
1701
1702 .inv_gain = 732,
1703 .time_stabiliz = 10,
1704
1705 .alpha_level = 0,
1706 .thlock = 118,
1707
1708 .wbd_inv = 0,
1709 .wbd_ref = 1200,
1710 .wbd_sel = 3,
1711 .wbd_alpha = 5,
1712
1713 .agc1_max = 65535,
1714 .agc1_min = 0,
1715
1716 .agc2_max = 32767,
1717 .agc2_min = 0,
1718
1719 .agc1_pt1 = 0,
1720 .agc1_pt2 = 0,
1721 .agc1_pt3 = 98,
1722 .agc1_slope1 = 0,
1723 .agc1_slope2 = 167,
1724 .agc2_pt1 = 98,
1725 .agc2_pt2 = 255,
1726 .agc2_slope1 = 52,
1727 .agc2_slope2 = 0,
1728
1729 .alpha_mant = 28,
1730 .alpha_exp = 26,
1731 .beta_mant = 31,
1732 .beta_exp = 51,
1733
1734 .perform_agc_softsplit = 0,
1735 }
1736};
1737
1738static struct dibx000_bandwidth_config dib8096p_clock_config_12_mhz = {
1739 108000, 13500,
1740 1, 9, 1, 0, 0,
1741 0, 0, 0, 0, 2,
1742 (3 << 14) | (1 << 12) | (524 << 0),
1743 (0 << 25) | 0,
1744 20199729,
1745 12000000,
1746};
1747
1748static struct dib8000_config tfe8096p_dib8000_config = {
1749 .output_mpeg2_in_188_bytes = 1,
1750 .hostbus_diversity = 1,
1751 .update_lna = NULL,
1752
1753 .agc_config_count = 2,
1754 .agc = dib8096p_agc_config,
1755 .pll = &dib8096p_clock_config_12_mhz,
1756
1757 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1758 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1759 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1760
1761 .agc_control = NULL,
1762 .diversity_delay = 48,
1763 .output_mode = OUTMODE_MPEG2_FIFO,
1764 .enMpegOutput = 1,
1765};
1766
1767static struct dib0090_wbd_slope dib8096p_wbd_table[] = {
1768 { 380, 81, 850, 64, 540, 4},
1769 { 860, 51, 866, 21, 375, 4},
1770 {1700, 0, 250, 0, 100, 6},
1771 {2600, 0, 250, 0, 100, 6},
1772 { 0xFFFF, 0, 0, 0, 0, 0},
1773};
1774
1775static const struct dib0090_config tfe8096p_dib0090_config = {
1776 .io.clock_khz = 12000,
1777 .io.pll_bypass = 0,
1778 .io.pll_range = 0,
1779 .io.pll_prediv = 3,
1780 .io.pll_loopdiv = 6,
1781 .io.adc_clock_ratio = 0,
1782 .io.pll_int_loop_filt = 0,
1783 .reset = dib8096p_tuner_sleep,
1784 .sleep = dib8096p_tuner_sleep,
1785
1786 .freq_offset_khz_uhf = -143,
1787 .freq_offset_khz_vhf = -143,
1788
1789 .get_adc_power = dib8090_get_adc_power,
1790
1791 .clkouttobamse = 1,
1792 .analog_output = 0,
1793
1794 .wbd_vhf_offset = 0,
1795 .wbd_cband_offset = 0,
1796 .use_pwm_agc = 1,
1797 .clkoutdrive = 0,
1798
1799 .fref_clock_ratio = 1,
1800
1801 .wbd = dib8096p_wbd_table,
1802
1803 .ls_cfg_pad_drv = 0,
1804 .data_tx_drv = 0,
1805 .low_if = NULL,
1806 .in_soc = 1,
1807 .force_cband_input = 0,
1808};
1809
1810struct dibx090p_adc {
1811 u32 freq; /* RF freq MHz */
1812 u32 timf; /* New Timf */
1813 u32 pll_loopdiv; /* New prediv */
1814 u32 pll_prediv; /* New loopdiv */
1815};
1816
1817struct dibx090p_adc dib8090p_adc_tab[] = {
1818 { 50000, 17043521, 16, 3}, /* 64 MHz */
1819 {878000, 20199729, 9, 1}, /* 60 MHz */
1820 {0xffffffff, 0, 0, 0}, /* 60 MHz */
1821};
1822
1823static int dib8096p_agc_startup(struct dvb_frontend *fe)
1824{
1825 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1826 struct dvb_usb_adapter *adap = fe->dvb->priv;
1827 struct dib0700_adapter_state *state = adap->priv;
1828 struct dibx000_bandwidth_config pll;
1829 u16 target;
1830 int better_sampling_freq = 0, ret;
1831 struct dibx090p_adc *adc_table = &dib8090p_adc_tab[0];
1832
1833 ret = state->set_param_save(fe);
1834 if (ret < 0)
1835 return ret;
1836 memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
1837
1838 dib0090_pwm_gain_reset(fe);
1839 /* dib0090_get_wbd_target is returning any possible
1840 temperature compensated wbd-target */
1841 target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2;
1842 dib8000_set_wbd_ref(fe, target);
1843
1844
1845 while (p->frequency / 1000 > adc_table->freq) {
1846 better_sampling_freq = 1;
1847 adc_table++;
1848 }
1849
1850 if ((adc_table->freq != 0xffffffff) && better_sampling_freq) {
1851 pll.pll_ratio = adc_table->pll_loopdiv;
1852 pll.pll_prediv = adc_table->pll_prediv;
1853 dib8000_update_pll(fe, &pll);
1854 dib8000_ctrl_timf(fe, DEMOD_TIMF_SET, adc_table->timf);
1855 }
1856 return 0;
1857}
1858
1859static int tfe8096p_frontend_attach(struct dvb_usb_adapter *adap)
1860{
1861 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1862 msleep(20);
1863 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1864 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1865 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1866
1867 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1868
1869 dib0700_ctrl_clock(adap->dev, 72, 1);
1870
1871 msleep(20);
1872 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1873 msleep(20);
1874 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1875
1876 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80, 1);
1877
1878 adap->fe_adap[0].fe = dvb_attach(dib8000_attach,
1879 &adap->dev->i2c_adap, 0x80, &tfe8096p_dib8000_config);
1880
1881 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
1882}
1883
1884static int tfe8096p_tuner_attach(struct dvb_usb_adapter *adap)
1885{
1886 struct dib0700_adapter_state *st = adap->priv;
1887 struct i2c_adapter *tun_i2c = dib8096p_get_i2c_tuner(adap->fe_adap[0].fe);
1888
1889 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
1890 &tfe8096p_dib0090_config) == NULL)
1891 return -ENODEV;
1892
1893 dib8000_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
1894
1895 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
1896 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096p_agc_startup;
1897 return 0;
1898}
1899
1900/* STK9090M */
1901static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
1902{
1903 return dib9000_fw_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff);
1904}
1905
1906static int dib90x0_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
1907{
1908 return dib9000_fw_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff);
1909}
1910
1911static int dib90x0_tuner_reset(struct dvb_frontend *fe, int onoff)
1912{
1913 return dib9000_set_gpio(fe, 5, 0, !onoff);
1914}
1915
1916static int dib90x0_tuner_sleep(struct dvb_frontend *fe, int onoff)
1917{
1918 return dib9000_set_gpio(fe, 0, 0, onoff);
1919}
1920
1921static int dib01x0_pmu_update(struct i2c_adapter *i2c, u16 *data, u8 len)
1922{
1923 u8 wb[4] = { 0xc >> 8, 0xc & 0xff, 0, 0 };
1924 u8 rb[2];
1925 struct i2c_msg msg[2] = {
1926 {.addr = 0x1e >> 1, .flags = 0, .buf = wb, .len = 2},
1927 {.addr = 0x1e >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2},
1928 };
1929 u8 index_data;
1930
1931 dibx000_i2c_set_speed(i2c, 250);
1932
1933 if (i2c_transfer(i2c, msg, 2) != 2)
1934 return -EIO;
1935
1936 switch (rb[0] << 8 | rb[1]) {
1937 case 0:
1938 deb_info("Found DiB0170 rev1: This version of DiB0170 is not supported any longer.\n");
1939 return -EIO;
1940 case 1:
1941 deb_info("Found DiB0170 rev2");
1942 break;
1943 case 2:
1944 deb_info("Found DiB0190 rev2");
1945 break;
1946 default:
1947 deb_info("DiB01x0 not found");
1948 return -EIO;
1949 }
1950
1951 for (index_data = 0; index_data < len; index_data += 2) {
1952 wb[2] = (data[index_data + 1] >> 8) & 0xff;
1953 wb[3] = (data[index_data + 1]) & 0xff;
1954
1955 if (data[index_data] == 0) {
1956 wb[0] = (data[index_data] >> 8) & 0xff;
1957 wb[1] = (data[index_data]) & 0xff;
1958 msg[0].len = 2;
1959 if (i2c_transfer(i2c, msg, 2) != 2)
1960 return -EIO;
1961 wb[2] |= rb[0];
1962 wb[3] |= rb[1] & ~(3 << 4);
1963 }
1964
1965 wb[0] = (data[index_data] >> 8)&0xff;
1966 wb[1] = (data[index_data])&0xff;
1967 msg[0].len = 4;
1968 if (i2c_transfer(i2c, &msg[0], 1) != 1)
1969 return -EIO;
1970 }
1971 return 0;
1972}
1973
1974static struct dib9000_config stk9090m_config = {
1975 .output_mpeg2_in_188_bytes = 1,
1976 .output_mode = OUTMODE_MPEG2_FIFO,
1977 .vcxo_timer = 279620,
1978 .timing_frequency = 20452225,
1979 .demod_clock_khz = 60000,
1980 .xtal_clock_khz = 30000,
1981 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
1982 .subband = {
1983 2,
1984 {
1985 { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0008 } }, /* GPIO 3 to 1 for VHF */
1986 { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0000 } }, /* GPIO 3 to 0 for UHF */
1987 { 0 },
1988 },
1989 },
1990 .gpio_function = {
1991 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
1992 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
1993 },
1994};
1995
1996static struct dib9000_config nim9090md_config[2] = {
1997 {
1998 .output_mpeg2_in_188_bytes = 1,
1999 .output_mode = OUTMODE_MPEG2_FIFO,
2000 .vcxo_timer = 279620,
2001 .timing_frequency = 20452225,
2002 .demod_clock_khz = 60000,
2003 .xtal_clock_khz = 30000,
2004 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
2005 }, {
2006 .output_mpeg2_in_188_bytes = 1,
2007 .output_mode = OUTMODE_DIVERSITY,
2008 .vcxo_timer = 279620,
2009 .timing_frequency = 20452225,
2010 .demod_clock_khz = 60000,
2011 .xtal_clock_khz = 30000,
2012 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
2013 .subband = {
2014 2,
2015 {
2016 { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0006 } }, /* GPIO 1 and 2 to 1 for VHF */
2017 { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0000 } }, /* GPIO 1 and 2 to 0 for UHF */
2018 { 0 },
2019 },
2020 },
2021 .gpio_function = {
2022 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
2023 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
2024 },
2025 }
2026};
2027
2028static struct dib0090_config dib9090_dib0090_config = {
2029 .io.pll_bypass = 0,
2030 .io.pll_range = 1,
2031 .io.pll_prediv = 1,
2032 .io.pll_loopdiv = 8,
2033 .io.adc_clock_ratio = 8,
2034 .io.pll_int_loop_filt = 0,
2035 .io.clock_khz = 30000,
2036 .reset = dib90x0_tuner_reset,
2037 .sleep = dib90x0_tuner_sleep,
2038 .clkouttobamse = 0,
2039 .analog_output = 0,
2040 .use_pwm_agc = 0,
2041 .clkoutdrive = 0,
2042 .freq_offset_khz_uhf = 0,
2043 .freq_offset_khz_vhf = 0,
2044};
2045
2046static struct dib0090_config nim9090md_dib0090_config[2] = {
2047 {
2048 .io.pll_bypass = 0,
2049 .io.pll_range = 1,
2050 .io.pll_prediv = 1,
2051 .io.pll_loopdiv = 8,
2052 .io.adc_clock_ratio = 8,
2053 .io.pll_int_loop_filt = 0,
2054 .io.clock_khz = 30000,
2055 .reset = dib90x0_tuner_reset,
2056 .sleep = dib90x0_tuner_sleep,
2057 .clkouttobamse = 1,
2058 .analog_output = 0,
2059 .use_pwm_agc = 0,
2060 .clkoutdrive = 0,
2061 .freq_offset_khz_uhf = 0,
2062 .freq_offset_khz_vhf = 0,
2063 }, {
2064 .io.pll_bypass = 0,
2065 .io.pll_range = 1,
2066 .io.pll_prediv = 1,
2067 .io.pll_loopdiv = 8,
2068 .io.adc_clock_ratio = 8,
2069 .io.pll_int_loop_filt = 0,
2070 .io.clock_khz = 30000,
2071 .reset = dib90x0_tuner_reset,
2072 .sleep = dib90x0_tuner_sleep,
2073 .clkouttobamse = 0,
2074 .analog_output = 0,
2075 .use_pwm_agc = 0,
2076 .clkoutdrive = 0,
2077 .freq_offset_khz_uhf = 0,
2078 .freq_offset_khz_vhf = 0,
2079 }
2080};
2081
2082
2083static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap)
2084{
2085 struct dib0700_adapter_state *state = adap->priv;
2086 struct dib0700_state *st = adap->dev->priv;
2087 u32 fw_version;
2088
2089 /* Make use of the new i2c functions from FW 1.20 */
2090 dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
2091 if (fw_version >= 0x10200)
2092 st->fw_use_new_i2c_api = 1;
2093 dib0700_set_i2c_speed(adap->dev, 340);
2094
2095 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2096 msleep(20);
2097 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2098 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2099 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2100 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2101
2102 dib0700_ctrl_clock(adap->dev, 72, 1);
2103
2104 msleep(20);
2105 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2106 msleep(20);
2107 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2108
2109 dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80);
2110
2111 if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
2112 deb_info("%s: Upload failed. (file not found?)\n", __func__);
2113 return -ENODEV;
2114 } else {
2115 deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
2116 }
2117 stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size;
2118 stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data;
2119
2120 adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config);
2121
2122 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
2123}
2124
2125static int dib9090_tuner_attach(struct dvb_usb_adapter *adap)
2126{
2127 struct dib0700_adapter_state *state = adap->priv;
2128 struct i2c_adapter *i2c = dib9000_get_tuner_interface(adap->fe_adap[0].fe);
2129 u16 data_dib190[10] = {
2130 1, 0x1374,
2131 2, 0x01a2,
2132 7, 0x0020,
2133 0, 0x00ef,
2134 8, 0x0486,
2135 };
2136
2137 if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &dib9090_dib0090_config) == NULL)
2138 return -ENODEV;
2139 i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
2140 if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0)
2141 return -ENODEV;
2142 dib0700_set_i2c_speed(adap->dev, 1500);
2143 if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0)
2144 return -ENODEV;
2145 release_firmware(state->frontend_firmware);
2146 return 0;
2147}
2148
2149static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap)
2150{
2151 struct dib0700_adapter_state *state = adap->priv;
2152 struct dib0700_state *st = adap->dev->priv;
2153 struct i2c_adapter *i2c;
2154 struct dvb_frontend *fe_slave;
2155 u32 fw_version;
2156
2157 /* Make use of the new i2c functions from FW 1.20 */
2158 dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
2159 if (fw_version >= 0x10200)
2160 st->fw_use_new_i2c_api = 1;
2161 dib0700_set_i2c_speed(adap->dev, 340);
2162
2163 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2164 msleep(20);
2165 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2166 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2167 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2168 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2169
2170 dib0700_ctrl_clock(adap->dev, 72, 1);
2171
2172 msleep(20);
2173 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2174 msleep(20);
2175 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2176
2177 if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
2178 deb_info("%s: Upload failed. (file not found?)\n", __func__);
2179 return -EIO;
2180 } else {
2181 deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
2182 }
2183 nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size;
2184 nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data;
2185 nim9090md_config[1].microcode_B_fe_size = state->frontend_firmware->size;
2186 nim9090md_config[1].microcode_B_fe_buffer = state->frontend_firmware->data;
2187
2188 dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80);
2189 adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]);
2190
2191 if (adap->fe_adap[0].fe == NULL)
2192 return -ENODEV;
2193
2194 i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0);
2195 dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82);
2196
2197 fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]);
2198 dib9000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave);
2199
2200 return fe_slave == NULL ? -ENODEV : 0;
2201}
2202
2203static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap)
2204{
2205 struct dib0700_adapter_state *state = adap->priv;
2206 struct i2c_adapter *i2c;
2207 struct dvb_frontend *fe_slave;
2208 u16 data_dib190[10] = {
2209 1, 0x5374,
2210 2, 0x01ae,
2211 7, 0x0020,
2212 0, 0x00ef,
2213 8, 0x0406,
2214 };
2215 i2c = dib9000_get_tuner_interface(adap->fe_adap[0].fe);
2216 if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &nim9090md_dib0090_config[0]) == NULL)
2217 return -ENODEV;
2218 i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
2219 if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0)
2220 return -ENODEV;
2221
2222 dib0700_set_i2c_speed(adap->dev, 1500);
2223 if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0)
2224 return -ENODEV;
2225
2226 fe_slave = dib9000_get_slave_frontend(adap->fe_adap[0].fe, 1);
2227 if (fe_slave != NULL) {
2228 i2c = dib9000_get_component_bus_interface(adap->fe_adap[0].fe);
2229 dib9000_set_i2c_adapter(fe_slave, i2c);
2230
2231 i2c = dib9000_get_tuner_interface(fe_slave);
2232 if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL)
2233 return -ENODEV;
2234 fe_slave->dvb = adap->fe_adap[0].fe->dvb;
2235 dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 1500);
2236 if (dib9000_firmware_post_pll_init(fe_slave) < 0)
2237 return -ENODEV;
2238 }
2239 release_firmware(state->frontend_firmware);
2240
2241 return 0;
2242}
2243
2244/* NIM7090 */
2245struct dib7090p_best_adc {
2246 u32 timf;
2247 u32 pll_loopdiv;
2248 u32 pll_prediv;
2249};
2250
2251static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_best_adc *adc)
2252{
2253 u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1;
2254
2255 u16 xtal = 12000;
2256 u32 fcp_min = 1900; /* PLL Minimum Frequency comparator KHz */
2257 u32 fcp_max = 20000; /* PLL Maximum Frequency comparator KHz */
2258 u32 fdem_max = 76000;
2259 u32 fdem_min = 69500;
2260 u32 fcp = 0, fs = 0, fdem = 0;
2261 u32 harmonic_id = 0;
2262
2263 adc->pll_loopdiv = loopdiv;
2264 adc->pll_prediv = prediv;
2265 adc->timf = 0;
2266
2267 deb_info("bandwidth = %d fdem_min =%d", fe->dtv_property_cache.bandwidth_hz, fdem_min);
2268
2269 /* Find Min and Max prediv */
2270 while ((xtal/max_prediv) >= fcp_min)
2271 max_prediv++;
2272
2273 max_prediv--;
2274 min_prediv = max_prediv;
2275 while ((xtal/min_prediv) <= fcp_max) {
2276 min_prediv--;
2277 if (min_prediv == 1)
2278 break;
2279 }
2280 deb_info("MIN prediv = %d : MAX prediv = %d", min_prediv, max_prediv);
2281
2282 min_prediv = 2;
2283
2284 for (prediv = min_prediv ; prediv < max_prediv; prediv++) {
2285 fcp = xtal / prediv;
2286 if (fcp > fcp_min && fcp < fcp_max) {
2287 for (loopdiv = 1 ; loopdiv < 64 ; loopdiv++) {
2288 fdem = ((xtal/prediv) * loopdiv);
2289 fs = fdem / 4;
2290 /* test min/max system restrictions */
2291
2292 if ((fdem >= fdem_min) && (fdem <= fdem_max) && (fs >= fe->dtv_property_cache.bandwidth_hz/1000)) {
2293 spur = 0;
2294 /* test fs harmonics positions */
2295 for (harmonic_id = (fe->dtv_property_cache.frequency / (1000*fs)) ; harmonic_id <= ((fe->dtv_property_cache.frequency / (1000*fs))+1) ; harmonic_id++) {
2296 if (((fs*harmonic_id) >= ((fe->dtv_property_cache.frequency/1000) - (fe->dtv_property_cache.bandwidth_hz/2000))) && ((fs*harmonic_id) <= ((fe->dtv_property_cache.frequency/1000) + (fe->dtv_property_cache.bandwidth_hz/2000)))) {
2297 spur = 1;
2298 break;
2299 }
2300 }
2301
2302 if (!spur) {
2303 adc->pll_loopdiv = loopdiv;
2304 adc->pll_prediv = prediv;
2305 adc->timf = 2396745143UL/fdem*(1 << 9);
2306 adc->timf += ((2396745143UL%fdem) << 9)/fdem;
2307 deb_info("loopdiv=%i prediv=%i timf=%i", loopdiv, prediv, adc->timf);
2308 break;
2309 }
2310 }
2311 }
2312 }
2313 if (!spur)
2314 break;
2315 }
2316
2317
2318 if (adc->pll_loopdiv == 0 && adc->pll_prediv == 0)
2319 return -EINVAL;
2320 else
2321 return 0;
2322}
2323
2324static int dib7090_agc_startup(struct dvb_frontend *fe)
2325{
2326 struct dvb_usb_adapter *adap = fe->dvb->priv;
2327 struct dib0700_adapter_state *state = adap->priv;
2328 struct dibx000_bandwidth_config pll;
2329 u16 target;
2330 struct dib7090p_best_adc adc;
2331 int ret;
2332
2333 ret = state->set_param_save(fe);
2334 if (ret < 0)
2335 return ret;
2336
2337 memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
2338 dib0090_pwm_gain_reset(fe);
2339 target = (dib0090_get_wbd_target(fe) * 8 + 1) / 2;
2340 dib7000p_set_wbd_ref(fe, target);
2341
2342 if (dib7090p_get_best_sampling(fe, &adc) == 0) {
2343 pll.pll_ratio = adc.pll_loopdiv;
2344 pll.pll_prediv = adc.pll_prediv;
2345
2346 dib7000p_update_pll(fe, &pll);
2347 dib7000p_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf);
2348 }
2349 return 0;
2350}
2351
2352static int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
2353{
2354 deb_info("AGC restart callback: %d", restart);
2355 if (restart == 0) /* before AGC startup */
2356 dib0090_set_dc_servo(fe, 1);
2357 return 0;
2358}
2359
2360static int dib7090e_update_lna(struct dvb_frontend *fe, u16 agc_global)
2361{
2362 u16 agc1 = 0, agc2, wbd = 0, wbd_target, wbd_offset, threshold_agc1;
2363 s16 wbd_delta;
2364
2365 if ((fe->dtv_property_cache.frequency) < 400000000)
2366 threshold_agc1 = 25000;
2367 else
2368 threshold_agc1 = 30000;
2369
2370 wbd_target = (dib0090_get_wbd_target(fe)*8+1)/2;
2371 wbd_offset = dib0090_get_wbd_offset(fe);
2372 dib7000p_get_agc_values(fe, NULL, &agc1, &agc2, &wbd);
2373 wbd_delta = (s16)wbd - (((s16)wbd_offset+10)*4) ;
2374
2375 deb_info("update lna, agc_global=%d agc1=%d agc2=%d",
2376 agc_global, agc1, agc2);
2377 deb_info("update lna, wbd=%d wbd target=%d wbd offset=%d wbd delta=%d",
2378 wbd, wbd_target, wbd_offset, wbd_delta);
2379
2380 if ((agc1 < threshold_agc1) && (wbd_delta > 0)) {
2381 dib0090_set_switch(fe, 1, 1, 1);
2382 dib0090_set_vga(fe, 0);
2383 dib0090_update_rframp_7090(fe, 0);
2384 dib0090_update_tuning_table_7090(fe, 0);
2385 } else {
2386 dib0090_set_vga(fe, 1);
2387 dib0090_update_rframp_7090(fe, 1);
2388 dib0090_update_tuning_table_7090(fe, 1);
2389 dib0090_set_switch(fe, 0, 0, 0);
2390 }
2391
2392 return 0;
2393}
2394
2395static struct dib0090_wbd_slope dib7090_wbd_table[] = {
2396 { 380, 81, 850, 64, 540, 4},
2397 { 860, 51, 866, 21, 375, 4},
2398 {1700, 0, 250, 0, 100, 6},
2399 {2600, 0, 250, 0, 100, 6},
2400 { 0xFFFF, 0, 0, 0, 0, 0},
2401};
2402
2403static struct dib0090_wbd_slope dib7090e_wbd_table[] = {
2404 { 380, 81, 850, 64, 540, 4},
2405 { 700, 51, 866, 21, 320, 4},
2406 { 860, 48, 666, 18, 330, 6},
2407 {1700, 0, 250, 0, 100, 6},
2408 {2600, 0, 250, 0, 100, 6},
2409 { 0xFFFF, 0, 0, 0, 0, 0},
2410};
2411
2412static struct dibx000_agc_config dib7090_agc_config[2] = {
2413 {
2414 .band_caps = BAND_UHF,
2415 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
2416 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
2417 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
2418
2419 .inv_gain = 687,
2420 .time_stabiliz = 10,
2421
2422 .alpha_level = 0,
2423 .thlock = 118,
2424
2425 .wbd_inv = 0,
2426 .wbd_ref = 1200,
2427 .wbd_sel = 3,
2428 .wbd_alpha = 5,
2429
2430 .agc1_max = 65535,
2431 .agc1_min = 0,
2432
2433 .agc2_max = 65535,
2434 .agc2_min = 0,
2435
2436 .agc1_pt1 = 0,
2437 .agc1_pt2 = 32,
2438 .agc1_pt3 = 114,
2439 .agc1_slope1 = 143,
2440 .agc1_slope2 = 144,
2441 .agc2_pt1 = 114,
2442 .agc2_pt2 = 227,
2443 .agc2_slope1 = 116,
2444 .agc2_slope2 = 117,
2445
2446 .alpha_mant = 18,
2447 .alpha_exp = 0,
2448 .beta_mant = 20,
2449 .beta_exp = 59,
2450
2451 .perform_agc_softsplit = 0,
2452 } , {
2453 .band_caps = BAND_FM | BAND_VHF | BAND_CBAND,
2454 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
2455 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
2456 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
2457
2458 .inv_gain = 732,
2459 .time_stabiliz = 10,
2460
2461 .alpha_level = 0,
2462 .thlock = 118,
2463
2464 .wbd_inv = 0,
2465 .wbd_ref = 1200,
2466 .wbd_sel = 3,
2467 .wbd_alpha = 5,
2468
2469 .agc1_max = 65535,
2470 .agc1_min = 0,
2471
2472 .agc2_max = 65535,
2473 .agc2_min = 0,
2474
2475 .agc1_pt1 = 0,
2476 .agc1_pt2 = 0,
2477 .agc1_pt3 = 98,
2478 .agc1_slope1 = 0,
2479 .agc1_slope2 = 167,
2480 .agc2_pt1 = 98,
2481 .agc2_pt2 = 255,
2482 .agc2_slope1 = 104,
2483 .agc2_slope2 = 0,
2484
2485 .alpha_mant = 18,
2486 .alpha_exp = 0,
2487 .beta_mant = 20,
2488 .beta_exp = 59,
2489
2490 .perform_agc_softsplit = 0,
2491 }
2492};
2493
2494static struct dibx000_bandwidth_config dib7090_clock_config_12_mhz = {
2495 60000, 15000,
2496 1, 5, 0, 0, 0,
2497 0, 0, 1, 1, 2,
2498 (3 << 14) | (1 << 12) | (524 << 0),
2499 (0 << 25) | 0,
2500 20452225,
2501 15000000,
2502};
2503
2504static struct dib7000p_config nim7090_dib7000p_config = {
2505 .output_mpeg2_in_188_bytes = 1,
2506 .hostbus_diversity = 1,
2507 .tuner_is_baseband = 1,
2508 .update_lna = NULL,
2509
2510 .agc_config_count = 2,
2511 .agc = dib7090_agc_config,
2512
2513 .bw = &dib7090_clock_config_12_mhz,
2514
2515 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2516 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2517 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2518
2519 .pwm_freq_div = 0,
2520
2521 .agc_control = dib7090_agc_restart,
2522
2523 .spur_protect = 0,
2524 .disable_sample_and_hold = 0,
2525 .enable_current_mirror = 0,
2526 .diversity_delay = 0,
2527
2528 .output_mode = OUTMODE_MPEG2_FIFO,
2529 .enMpegOutput = 1,
2530};
2531
2532static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = {
2533 {
2534 .output_mpeg2_in_188_bytes = 1,
2535 .hostbus_diversity = 1,
2536 .tuner_is_baseband = 1,
2537 .update_lna = NULL,
2538
2539 .agc_config_count = 2,
2540 .agc = dib7090_agc_config,
2541
2542 .bw = &dib7090_clock_config_12_mhz,
2543
2544 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2545 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2546 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2547
2548 .pwm_freq_div = 0,
2549
2550 .agc_control = dib7090_agc_restart,
2551
2552 .spur_protect = 0,
2553 .disable_sample_and_hold = 0,
2554 .enable_current_mirror = 0,
2555 .diversity_delay = 0,
2556
2557 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
2558 .default_i2c_addr = 0x90,
2559 .enMpegOutput = 1,
2560 }, {
2561 .output_mpeg2_in_188_bytes = 1,
2562 .hostbus_diversity = 1,
2563 .tuner_is_baseband = 1,
2564 .update_lna = NULL,
2565
2566 .agc_config_count = 2,
2567 .agc = dib7090_agc_config,
2568
2569 .bw = &dib7090_clock_config_12_mhz,
2570
2571 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2572 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2573 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2574
2575 .pwm_freq_div = 0,
2576
2577 .agc_control = dib7090_agc_restart,
2578
2579 .spur_protect = 0,
2580 .disable_sample_and_hold = 0,
2581 .enable_current_mirror = 0,
2582 .diversity_delay = 0,
2583
2584 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
2585 .default_i2c_addr = 0x92,
2586 .enMpegOutput = 0,
2587 }
2588};
2589
2590static struct dib7000p_config tfe7090e_dib7000p_config = {
2591 .output_mpeg2_in_188_bytes = 1,
2592 .hostbus_diversity = 1,
2593 .tuner_is_baseband = 1,
2594 .update_lna = dib7090e_update_lna,
2595
2596 .agc_config_count = 2,
2597 .agc = dib7090_agc_config,
2598
2599 .bw = &dib7090_clock_config_12_mhz,
2600
2601 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2602 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2603 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2604
2605 .pwm_freq_div = 0,
2606
2607 .agc_control = dib7090_agc_restart,
2608
2609 .spur_protect = 0,
2610 .disable_sample_and_hold = 0,
2611 .enable_current_mirror = 0,
2612 .diversity_delay = 0,
2613
2614 .output_mode = OUTMODE_MPEG2_FIFO,
2615 .enMpegOutput = 1,
2616};
2617
2618static const struct dib0090_config nim7090_dib0090_config = {
2619 .io.clock_khz = 12000,
2620 .io.pll_bypass = 0,
2621 .io.pll_range = 0,
2622 .io.pll_prediv = 3,
2623 .io.pll_loopdiv = 6,
2624 .io.adc_clock_ratio = 0,
2625 .io.pll_int_loop_filt = 0,
2626 .reset = dib7090_tuner_sleep,
2627 .sleep = dib7090_tuner_sleep,
2628
2629 .freq_offset_khz_uhf = 0,
2630 .freq_offset_khz_vhf = 0,
2631
2632 .get_adc_power = dib7090_get_adc_power,
2633
2634 .clkouttobamse = 1,
2635 .analog_output = 0,
2636
2637 .wbd_vhf_offset = 0,
2638 .wbd_cband_offset = 0,
2639 .use_pwm_agc = 1,
2640 .clkoutdrive = 0,
2641
2642 .fref_clock_ratio = 0,
2643
2644 .wbd = dib7090_wbd_table,
2645
2646 .ls_cfg_pad_drv = 0,
2647 .data_tx_drv = 0,
2648 .low_if = NULL,
2649 .in_soc = 1,
2650};
2651
2652static const struct dib0090_config tfe7090e_dib0090_config = {
2653 .io.clock_khz = 12000,
2654 .io.pll_bypass = 0,
2655 .io.pll_range = 0,
2656 .io.pll_prediv = 3,
2657 .io.pll_loopdiv = 6,
2658 .io.adc_clock_ratio = 0,
2659 .io.pll_int_loop_filt = 0,
2660 .reset = dib7090_tuner_sleep,
2661 .sleep = dib7090_tuner_sleep,
2662
2663 .freq_offset_khz_uhf = 0,
2664 .freq_offset_khz_vhf = 0,
2665
2666 .get_adc_power = dib7090_get_adc_power,
2667
2668 .clkouttobamse = 1,
2669 .analog_output = 0,
2670
2671 .wbd_vhf_offset = 0,
2672 .wbd_cband_offset = 0,
2673 .use_pwm_agc = 1,
2674 .clkoutdrive = 0,
2675
2676 .fref_clock_ratio = 0,
2677
2678 .wbd = dib7090e_wbd_table,
2679
2680 .ls_cfg_pad_drv = 0,
2681 .data_tx_drv = 0,
2682 .low_if = NULL,
2683 .in_soc = 1,
2684 .force_cband_input = 1,
2685 .is_dib7090e = 1,
2686};
2687
2688static struct dib7000p_config tfe7790e_dib7000p_config = {
2689 .output_mpeg2_in_188_bytes = 1,
2690 .hostbus_diversity = 1,
2691 .tuner_is_baseband = 1,
2692 .update_lna = dib7090e_update_lna,
2693
2694 .agc_config_count = 2,
2695 .agc = dib7090_agc_config,
2696
2697 .bw = &dib7090_clock_config_12_mhz,
2698
2699 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2700 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2701 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2702
2703 .pwm_freq_div = 0,
2704
2705 .agc_control = dib7090_agc_restart,
2706
2707 .spur_protect = 0,
2708 .disable_sample_and_hold = 0,
2709 .enable_current_mirror = 0,
2710 .diversity_delay = 0,
2711
2712 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
2713 .enMpegOutput = 1,
2714};
2715
2716static const struct dib0090_config tfe7790e_dib0090_config = {
2717 .io.clock_khz = 12000,
2718 .io.pll_bypass = 0,
2719 .io.pll_range = 0,
2720 .io.pll_prediv = 3,
2721 .io.pll_loopdiv = 6,
2722 .io.adc_clock_ratio = 0,
2723 .io.pll_int_loop_filt = 0,
2724 .reset = dib7090_tuner_sleep,
2725 .sleep = dib7090_tuner_sleep,
2726
2727 .freq_offset_khz_uhf = 0,
2728 .freq_offset_khz_vhf = 0,
2729
2730 .get_adc_power = dib7090_get_adc_power,
2731
2732 .clkouttobamse = 1,
2733 .analog_output = 0,
2734
2735 .wbd_vhf_offset = 0,
2736 .wbd_cband_offset = 0,
2737 .use_pwm_agc = 1,
2738 .clkoutdrive = 0,
2739
2740 .fref_clock_ratio = 0,
2741
2742 .wbd = dib7090e_wbd_table,
2743
2744 .ls_cfg_pad_drv = 0,
2745 .data_tx_drv = 0,
2746 .low_if = NULL,
2747 .in_soc = 1,
2748 .force_cband_input = 1,
2749 .is_dib7090e = 1,
2750 .force_crystal_mode = 1,
2751};
2752
2753static const struct dib0090_config tfe7090pvr_dib0090_config[2] = {
2754 {
2755 .io.clock_khz = 12000,
2756 .io.pll_bypass = 0,
2757 .io.pll_range = 0,
2758 .io.pll_prediv = 3,
2759 .io.pll_loopdiv = 6,
2760 .io.adc_clock_ratio = 0,
2761 .io.pll_int_loop_filt = 0,
2762 .reset = dib7090_tuner_sleep,
2763 .sleep = dib7090_tuner_sleep,
2764
2765 .freq_offset_khz_uhf = 50,
2766 .freq_offset_khz_vhf = 70,
2767
2768 .get_adc_power = dib7090_get_adc_power,
2769
2770 .clkouttobamse = 1,
2771 .analog_output = 0,
2772
2773 .wbd_vhf_offset = 0,
2774 .wbd_cband_offset = 0,
2775 .use_pwm_agc = 1,
2776 .clkoutdrive = 0,
2777
2778 .fref_clock_ratio = 0,
2779
2780 .wbd = dib7090_wbd_table,
2781
2782 .ls_cfg_pad_drv = 0,
2783 .data_tx_drv = 0,
2784 .low_if = NULL,
2785 .in_soc = 1,
2786 }, {
2787 .io.clock_khz = 12000,
2788 .io.pll_bypass = 0,
2789 .io.pll_range = 0,
2790 .io.pll_prediv = 3,
2791 .io.pll_loopdiv = 6,
2792 .io.adc_clock_ratio = 0,
2793 .io.pll_int_loop_filt = 0,
2794 .reset = dib7090_tuner_sleep,
2795 .sleep = dib7090_tuner_sleep,
2796
2797 .freq_offset_khz_uhf = -50,
2798 .freq_offset_khz_vhf = -70,
2799
2800 .get_adc_power = dib7090_get_adc_power,
2801
2802 .clkouttobamse = 1,
2803 .analog_output = 0,
2804
2805 .wbd_vhf_offset = 0,
2806 .wbd_cband_offset = 0,
2807 .use_pwm_agc = 1,
2808 .clkoutdrive = 0,
2809
2810 .fref_clock_ratio = 0,
2811
2812 .wbd = dib7090_wbd_table,
2813
2814 .ls_cfg_pad_drv = 0,
2815 .data_tx_drv = 0,
2816 .low_if = NULL,
2817 .in_soc = 1,
2818 }
2819};
2820
2821static int nim7090_frontend_attach(struct dvb_usb_adapter *adap)
2822{
2823 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2824 msleep(20);
2825 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2826 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2827 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2828 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2829
2830 msleep(20);
2831 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2832 msleep(20);
2833 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2834
2835 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) {
2836 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2837 return -ENODEV;
2838 }
2839 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config);
2840
2841 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
2842}
2843
2844static int nim7090_tuner_attach(struct dvb_usb_adapter *adap)
2845{
2846 struct dib0700_adapter_state *st = adap->priv;
2847 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
2848
2849 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &nim7090_dib0090_config) == NULL)
2850 return -ENODEV;
2851
2852 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
2853
2854 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
2855 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2856 return 0;
2857}
2858
2859static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
2860{
2861 struct dib0700_state *st = adap->dev->priv;
2862
2863 /* The TFE7090 requires the dib0700 to not be in master mode */
2864 st->disable_streaming_master_mode = 1;
2865
2866 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2867 msleep(20);
2868 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2869 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2870 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2871 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2872
2873 msleep(20);
2874 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2875 msleep(20);
2876 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2877
2878 /* initialize IC 0 */
2879 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) {
2880 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2881 return -ENODEV;
2882 }
2883
2884 dib0700_set_i2c_speed(adap->dev, 340);
2885 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
2886 if (adap->fe_adap[0].fe == NULL)
2887 return -ENODEV;
2888
2889 dib7090_slave_reset(adap->fe_adap[0].fe);
2890
2891 return 0;
2892}
2893
2894static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap)
2895{
2896 struct i2c_adapter *i2c;
2897
2898 if (adap->dev->adapter[0].fe_adap[0].fe == NULL) {
2899 err("the master dib7090 has to be initialized first");
2900 return -ENODEV; /* the master device has not been initialized */
2901 }
2902
2903 i2c = dib7000p_get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1);
2904 if (dib7000p_i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) {
2905 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2906 return -ENODEV;
2907 }
2908
2909 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]);
2910 dib0700_set_i2c_speed(adap->dev, 200);
2911
2912 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
2913}
2914
2915static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap)
2916{
2917 struct dib0700_adapter_state *st = adap->priv;
2918 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
2919
2920 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL)
2921 return -ENODEV;
2922
2923 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
2924
2925 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
2926 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2927 return 0;
2928}
2929
2930static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap)
2931{
2932 struct dib0700_adapter_state *st = adap->priv;
2933 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
2934
2935 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL)
2936 return -ENODEV;
2937
2938 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
2939
2940 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
2941 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2942 return 0;
2943}
2944
2945static int tfe7090e_frontend_attach(struct dvb_usb_adapter *adap)
2946{
2947 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2948 msleep(20);
2949 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2950 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2951 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2952 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2953
2954 msleep(20);
2955 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2956 msleep(20);
2957 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2958
2959 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap,
2960 1, 0x10, &tfe7090e_dib7000p_config) != 0) {
2961 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
2962 __func__);
2963 return -ENODEV;
2964 }
2965 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
2966 0x80, &tfe7090e_dib7000p_config);
2967
2968 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
2969}
2970
2971static int tfe7790e_frontend_attach(struct dvb_usb_adapter *adap)
2972{
2973 struct dib0700_state *st = adap->dev->priv;
2974
2975 /* The TFE7790E requires the dib0700 to not be in master mode */
2976 st->disable_streaming_master_mode = 1;
2977
2978 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2979 msleep(20);
2980 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2981 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2982 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2983 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2984 msleep(20);
2985 dib0700_ctrl_clock(adap->dev, 72, 1);
2986 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2987 msleep(20);
2988 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2989
2990 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap,
2991 1, 0x10, &tfe7790e_dib7000p_config) != 0) {
2992 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
2993 __func__);
2994 return -ENODEV;
2995 }
2996 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,
2997 0x80, &tfe7790e_dib7000p_config);
2998
2999 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
3000}
3001
3002static int tfe7790e_tuner_attach(struct dvb_usb_adapter *adap)
3003{
3004 struct dib0700_adapter_state *st = adap->priv;
3005 struct i2c_adapter *tun_i2c =
3006 dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
3007
3008 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
3009 &tfe7790e_dib0090_config) == NULL)
3010 return -ENODEV;
3011
3012 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
3013
3014 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
3015 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
3016 return 0;
3017}
3018
3019static int tfe7090e_tuner_attach(struct dvb_usb_adapter *adap)
3020{
3021 struct dib0700_adapter_state *st = adap->priv;
3022 struct i2c_adapter *tun_i2c =
3023 dib7090_get_i2c_tuner(adap->fe_adap[0].fe);
3024
3025 if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c,
3026 &tfe7090e_dib0090_config) == NULL)
3027 return -ENODEV;
3028
3029 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
3030
3031 st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params;
3032 adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup;
3033 return 0;
3034}
3035
3036/* STK7070PD */
3037static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
3038 {
3039 .output_mpeg2_in_188_bytes = 1,
3040
3041 .agc_config_count = 1,
3042 .agc = &dib7070_agc_config,
3043 .bw = &dib7070_bw_config_12_mhz,
3044 .tuner_is_baseband = 1,
3045 .spur_protect = 1,
3046
3047 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
3048 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
3049 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
3050
3051 .hostbus_diversity = 1,
3052 }, {
3053 .output_mpeg2_in_188_bytes = 1,
3054
3055 .agc_config_count = 1,
3056 .agc = &dib7070_agc_config,
3057 .bw = &dib7070_bw_config_12_mhz,
3058 .tuner_is_baseband = 1,
3059 .spur_protect = 1,
3060
3061 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
3062 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
3063 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
3064
3065 .hostbus_diversity = 1,
3066 }
3067};
3068
3069static void stk7070pd_init(struct dvb_usb_device *dev)
3070{
3071 dib0700_set_gpio(dev, GPIO6, GPIO_OUT, 1);
3072 msleep(10);
3073 dib0700_set_gpio(dev, GPIO9, GPIO_OUT, 1);
3074 dib0700_set_gpio(dev, GPIO4, GPIO_OUT, 1);
3075 dib0700_set_gpio(dev, GPIO7, GPIO_OUT, 1);
3076 dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 0);
3077
3078 dib0700_ctrl_clock(dev, 72, 1);
3079
3080 msleep(10);
3081 dib0700_set_gpio(dev, GPIO10, GPIO_OUT, 1);
3082}
3083
3084static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
3085{
3086 stk7070pd_init(adap->dev);
3087
3088 msleep(10);
3089 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
3090
3091 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
3092 stk7070pd_dib7000p_config) != 0) {
3093 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
3094 __func__);
3095 return -ENODEV;
3096 }
3097
3098 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
3099 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
3100}
3101
3102static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
3103{
3104 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]);
3105 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
3106}
3107
3108static int novatd_read_status_override(struct dvb_frontend *fe,
3109 fe_status_t *stat)
3110{
3111 struct dvb_usb_adapter *adap = fe->dvb->priv;
3112 struct dvb_usb_device *dev = adap->dev;
3113 struct dib0700_state *state = dev->priv;
3114 int ret;
3115
3116 ret = state->read_status(fe, stat);
3117
3118 if (!ret)
3119 dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT,
3120 !!(*stat & FE_HAS_LOCK));
3121
3122 return ret;
3123}
3124
3125static int novatd_sleep_override(struct dvb_frontend* fe)
3126{
3127 struct dvb_usb_adapter *adap = fe->dvb->priv;
3128 struct dvb_usb_device *dev = adap->dev;
3129 struct dib0700_state *state = dev->priv;
3130
3131 /* turn off LED */
3132 dib0700_set_gpio(dev, adap->id == 0 ? GPIO1 : GPIO0, GPIO_OUT, 0);
3133
3134 return state->sleep(fe);
3135}
3136
3137/**
3138 * novatd_frontend_attach - Nova-TD specific attach
3139 *
3140 * Nova-TD has GPIO0, 1 and 2 for LEDs. So do not fiddle with them except for
3141 * information purposes.
3142 */
3143static int novatd_frontend_attach(struct dvb_usb_adapter *adap)
3144{
3145 struct dvb_usb_device *dev = adap->dev;
3146 struct dib0700_state *st = dev->priv;
3147
3148 if (adap->id == 0) {
3149 stk7070pd_init(dev);
3150
3151 /* turn the power LED on, the other two off (just in case) */
3152 dib0700_set_gpio(dev, GPIO0, GPIO_OUT, 0);
3153 dib0700_set_gpio(dev, GPIO1, GPIO_OUT, 0);
3154 dib0700_set_gpio(dev, GPIO2, GPIO_OUT, 1);
3155
3156 if (dib7000p_i2c_enumeration(&dev->i2c_adap, 2, 18,
3157 stk7070pd_dib7000p_config) != 0) {
3158 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
3159 __func__);
3160 return -ENODEV;
3161 }
3162 }
3163
3164 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &dev->i2c_adap,
3165 adap->id == 0 ? 0x80 : 0x82,
3166 &stk7070pd_dib7000p_config[adap->id]);
3167
3168 if (adap->fe_adap[0].fe == NULL)
3169 return -ENODEV;
3170
3171 st->read_status = adap->fe_adap[0].fe->ops.read_status;
3172 adap->fe_adap[0].fe->ops.read_status = novatd_read_status_override;
3173 st->sleep = adap->fe_adap[0].fe->ops.sleep;
3174 adap->fe_adap[0].fe->ops.sleep = novatd_sleep_override;
3175
3176 return 0;
3177}
3178
3179/* S5H1411 */
3180static struct s5h1411_config pinnacle_801e_config = {
3181 .output_mode = S5H1411_PARALLEL_OUTPUT,
3182 .gpio = S5H1411_GPIO_OFF,
3183 .mpeg_timing = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK,
3184 .qam_if = S5H1411_IF_44000,
3185 .vsb_if = S5H1411_IF_44000,
3186 .inversion = S5H1411_INVERSION_OFF,
3187 .status_mode = S5H1411_DEMODLOCKING
3188};
3189
3190/* Pinnacle PCTV HD Pro 801e GPIOs map:
3191 GPIO0 - currently unknown
3192 GPIO1 - xc5000 tuner reset
3193 GPIO2 - CX25843 sleep
3194 GPIO3 - currently unknown
3195 GPIO4 - currently unknown
3196 GPIO6 - currently unknown
3197 GPIO7 - currently unknown
3198 GPIO9 - currently unknown
3199 GPIO10 - CX25843 reset
3200 */
3201static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap)
3202{
3203 struct dib0700_state *st = adap->dev->priv;
3204
3205 /* Make use of the new i2c functions from FW 1.20 */
3206 st->fw_use_new_i2c_api = 1;
3207
3208 /* The s5h1411 requires the dib0700 to not be in master mode */
3209 st->disable_streaming_master_mode = 1;
3210
3211 /* All msleep values taken from Windows USB trace */
3212 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0);
3213 dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0);
3214 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
3215 msleep(400);
3216 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
3217 msleep(60);
3218 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
3219 msleep(30);
3220 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
3221 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
3222 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
3223 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
3224 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 0);
3225 msleep(30);
3226
3227 /* Put the CX25843 to sleep for now since we're in digital mode */
3228 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
3229
3230 /* GPIOs are initialized, do the attach */
3231 adap->fe_adap[0].fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config,
3232 &adap->dev->i2c_adap);
3233 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
3234}
3235
3236static int dib0700_xc5000_tuner_callback(void *priv, int component,
3237 int command, int arg)
3238{
3239 struct dvb_usb_adapter *adap = priv;
3240
3241 if (command == XC5000_TUNER_RESET) {
3242 /* Reset the tuner */
3243 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0);
3244 msleep(10);
3245 dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1);
3246 msleep(10);
3247 } else {
3248 err("xc5000: unknown tuner callback command: %d\n", command);
3249 return -EINVAL;
3250 }
3251
3252 return 0;
3253}
3254
3255static struct xc5000_config s5h1411_xc5000_tunerconfig = {
3256 .i2c_address = 0x64,
3257 .if_khz = 5380,
3258};
3259
3260static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
3261{
3262 /* FIXME: generalize & move to common area */
3263 adap->fe_adap[0].fe->callback = dib0700_xc5000_tuner_callback;
3264
3265 return dvb_attach(xc5000_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap,
3266 &s5h1411_xc5000_tunerconfig)
3267 == NULL ? -ENODEV : 0;
3268}
3269
3270static int dib0700_xc4000_tuner_callback(void *priv, int component,
3271 int command, int arg)
3272{
3273 struct dvb_usb_adapter *adap = priv;
3274
3275 if (command == XC4000_TUNER_RESET) {
3276 /* Reset the tuner */
3277 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0);
3278 msleep(10);
3279 dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
3280 } else {
3281 err("xc4000: unknown tuner callback command: %d\n", command);
3282 return -EINVAL;
3283 }
3284
3285 return 0;
3286}
3287
3288static struct dibx000_agc_config stk7700p_7000p_xc4000_agc_config = {
3289 .band_caps = BAND_UHF | BAND_VHF,
3290 .setup = 0x64,
3291 .inv_gain = 0x02c8,
3292 .time_stabiliz = 0x15,
3293 .alpha_level = 0x00,
3294 .thlock = 0x76,
3295 .wbd_inv = 0x01,
3296 .wbd_ref = 0x0b33,
3297 .wbd_sel = 0x00,
3298 .wbd_alpha = 0x02,
3299 .agc1_max = 0x00,
3300 .agc1_min = 0x00,
3301 .agc2_max = 0x9b26,
3302 .agc2_min = 0x26ca,
3303 .agc1_pt1 = 0x00,
3304 .agc1_pt2 = 0x00,
3305 .agc1_pt3 = 0x00,
3306 .agc1_slope1 = 0x00,
3307 .agc1_slope2 = 0x00,
3308 .agc2_pt1 = 0x00,
3309 .agc2_pt2 = 0x80,
3310 .agc2_slope1 = 0x1d,
3311 .agc2_slope2 = 0x1d,
3312 .alpha_mant = 0x11,
3313 .alpha_exp = 0x1b,
3314 .beta_mant = 0x17,
3315 .beta_exp = 0x33,
3316 .perform_agc_softsplit = 0x00,
3317};
3318
3319static struct dibx000_bandwidth_config stk7700p_xc4000_pll_config = {
3320 60000, 30000, /* internal, sampling */
3321 1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
3322 0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, */
3323 /* ADClkSrc, modulo */
3324 (3 << 14) | (1 << 12) | 524, /* sad_cfg: refsel, sel, freq_15k */
3325 39370534, /* ifreq */
3326 20452225, /* timf */
3327 30000000 /* xtal */
3328};
3329
3330/* FIXME: none of these inputs are validated yet */
3331static struct dib7000p_config pctv_340e_config = {
3332 .output_mpeg2_in_188_bytes = 1,
3333
3334 .agc_config_count = 1,
3335 .agc = &stk7700p_7000p_xc4000_agc_config,
3336 .bw = &stk7700p_xc4000_pll_config,
3337
3338 .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS,
3339 .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES,
3340 .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS,
3341};
3342
3343/* PCTV 340e GPIOs map:
3344 dib0700:
3345 GPIO2 - CX25843 sleep
3346 GPIO3 - CS5340 reset
3347 GPIO5 - IRD
3348 GPIO6 - Power Supply
3349 GPIO8 - LNA (1=off 0=on)
3350 GPIO10 - CX25843 reset
3351 dib7000:
3352 GPIO8 - xc4000 reset
3353 */
3354static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap)
3355{
3356 struct dib0700_state *st = adap->dev->priv;
3357
3358 /* Power Supply on */
3359 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
3360 msleep(50);
3361 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
3362 msleep(100); /* Allow power supply to settle before probing */
3363
3364 /* cx25843 reset */
3365 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
3366 msleep(1); /* cx25843 datasheet say 350us required */
3367 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
3368
3369 /* LNA off for now */
3370 dib0700_set_gpio(adap->dev, GPIO8, GPIO_OUT, 1);
3371
3372 /* Put the CX25843 to sleep for now since we're in digital mode */
3373 dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1);
3374
3375 /* FIXME: not verified yet */
3376 dib0700_ctrl_clock(adap->dev, 72, 1);
3377
3378 msleep(500);
3379
3380 if (dib7000pc_detection(&adap->dev->i2c_adap) == 0) {
3381 /* Demodulator not found for some reason? */
3382 return -ENODEV;
3383 }
3384
3385 adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x12,
3386 &pctv_340e_config);
3387 st->is_dib7000pc = 1;
3388
3389 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
3390}
3391
3392static struct xc4000_config dib7000p_xc4000_tunerconfig = {
3393 .i2c_address = 0x61,
3394 .default_pm = 1,
3395 .dvb_amplitude = 0,
3396 .set_smoothedcvbs = 0,
3397 .if_khz = 5400
3398};
3399
3400static int xc4000_tuner_attach(struct dvb_usb_adapter *adap)
3401{
3402 struct i2c_adapter *tun_i2c;
3403
3404 /* The xc4000 is not on the main i2c bus */
3405 tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe,
3406 DIBX000_I2C_INTERFACE_TUNER, 1);
3407 if (tun_i2c == NULL) {
3408 printk(KERN_ERR "Could not reach tuner i2c bus\n");
3409 return 0;
3410 }
3411
3412 /* Setup the reset callback */
3413 adap->fe_adap[0].fe->callback = dib0700_xc4000_tuner_callback;
3414
3415 return dvb_attach(xc4000_attach, adap->fe_adap[0].fe, tun_i2c,
3416 &dib7000p_xc4000_tunerconfig)
3417 == NULL ? -ENODEV : 0;
3418}
3419
3420static struct lgdt3305_config hcw_lgdt3305_config = {
3421 .i2c_addr = 0x0e,
3422 .mpeg_mode = LGDT3305_MPEG_PARALLEL,
3423 .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
3424 .tpvalid_polarity = LGDT3305_TP_VALID_LOW,
3425 .deny_i2c_rptr = 0,
3426 .spectral_inversion = 1,
3427 .qam_if_khz = 6000,
3428 .vsb_if_khz = 6000,
3429 .usref_8vsb = 0x0500,
3430};
3431
3432static struct mxl5007t_config hcw_mxl5007t_config = {
3433 .xtal_freq_hz = MxL_XTAL_25_MHZ,
3434 .if_freq_hz = MxL_IF_6_MHZ,
3435 .invert_if = 1,
3436};
3437
3438/* TIGER-ATSC map:
3439 GPIO0 - LNA_CTR (H: LNA power enabled, L: LNA power disabled)
3440 GPIO1 - ANT_SEL (H: VPA, L: MCX)
3441 GPIO4 - SCL2
3442 GPIO6 - EN_TUNER
3443 GPIO7 - SDA2
3444 GPIO10 - DEM_RST
3445
3446 MXL is behind LG's i2c repeater. LG is on SCL2/SDA2 gpios on the DIB
3447 */
3448static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
3449{
3450 struct dib0700_state *st = adap->dev->priv;
3451
3452 /* Make use of the new i2c functions from FW 1.20 */
3453 st->fw_use_new_i2c_api = 1;
3454
3455 st->disable_streaming_master_mode = 1;
3456
3457 /* fe power enable */
3458 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
3459 msleep(30);
3460 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
3461 msleep(30);
3462
3463 /* demod reset */
3464 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
3465 msleep(30);
3466 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
3467 msleep(30);
3468 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
3469 msleep(30);
3470
3471 adap->fe_adap[0].fe = dvb_attach(lgdt3305_attach,
3472 &hcw_lgdt3305_config,
3473 &adap->dev->i2c_adap);
3474
3475 return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
3476}
3477
3478static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
3479{
3480 return dvb_attach(mxl5007t_attach, adap->fe_adap[0].fe,
3481 &adap->dev->i2c_adap, 0x60,
3482 &hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
3483}
3484
3485
3486/* DVB-USB and USB stuff follows */
3487struct usb_device_id dib0700_usb_id_table[] = {
3488/* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) },
3489 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P_PC) },
3490 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
3491 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
3492 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
3493/* 5 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
3494 { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500) },
3495 { USB_DEVICE(USB_VID_UNIWILL, USB_PID_UNIWILL_STK7700P) },
3496 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
3497 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
3498/* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
3499 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV2000E) },
3500 { USB_DEVICE(USB_VID_TERRATEC,
3501 USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
3502 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
3503 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700D) },
3504/* 15 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070P) },
3505 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
3506 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070PD) },
3507 { USB_DEVICE(USB_VID_PINNACLE,
3508 USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
3509 { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500_PC) },
3510/* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
3511 { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) },
3512 { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
3513 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) },
3514 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) },
3515/* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
3516 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
3517 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_USB_XE) },
3518 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_EXPRESSCARD_320CX) },
3519 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV72E) },
3520/* 30 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73E) },
3521 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_EC372S) },
3522 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
3523 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) },
3524 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
3525/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
3526 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) },
3527 { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U8000) },
3528 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700PH) },
3529 { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) },
3530/* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) },
3531 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) },
3532 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
3533 { USB_DEVICE(USB_VID_TERRATEC,
3534 USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
3535 { USB_DEVICE(USB_VID_SONY, USB_PID_SONY_PLAYTV) },
3536/* 45 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_PD378S) },
3537 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) },
3538 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
3539 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) },
3540 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) },
3541/* 50 */{ USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_Dlx) },
3542 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_H) },
3543 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T3) },
3544 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T5) },
3545 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) },
3546/* 55 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) },
3547 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73A) },
3548 { USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV73ESE) },
3549 { USB_DEVICE(USB_VID_PCTV, USB_PID_PINNACLE_PCTV282E) },
3550 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7770P) },
3551/* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
3552 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) },
3553 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) },
3554 { USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x000, 0x3f00) },
3555 { USB_DEVICE(USB_VID_EVOLUTEPC, USB_PID_TVWAY_PLUS) },
3556/* 65 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
3557 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
3558 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) },
3559 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DIVERSITY) },
3560 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090M) },
3561/* 70 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM8096MD) },
3562 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090MD) },
3563 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM7090) },
3564 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) },
3565 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) },
3566/* 75 */{ USB_DEVICE(USB_VID_MEDION, USB_PID_CREATIX_CTX1921) },
3567 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E) },
3568 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E_SE) },
3569 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090E) },
3570 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7790E) },
3571/* 80 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE8096P) },
3572 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT_2) },
3573 { 0 } /* Terminating entry */
3574};
3575MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
3576
3577#define DIB0700_DEFAULT_DEVICE_PROPERTIES \
3578 .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
3579 .usb_ctrl = DEVICE_SPECIFIC, \
3580 .firmware = "dvb-usb-dib0700-1.20.fw", \
3581 .download_firmware = dib0700_download_firmware, \
3582 .no_reconnect = 1, \
3583 .size_of_priv = sizeof(struct dib0700_state), \
3584 .i2c_algo = &dib0700_i2c_algo, \
3585 .identify_state = dib0700_identify_state
3586
3587#define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \
3588 .streaming_ctrl = dib0700_streaming_ctrl, \
3589 .stream = { \
3590 .type = USB_BULK, \
3591 .count = 4, \
3592 .endpoint = ep, \
3593 .u = { \
3594 .bulk = { \
3595 .buffersize = 39480, \
3596 } \
3597 } \
3598 }
3599
3600struct dvb_usb_device_properties dib0700_devices[] = {
3601 {
3602 DIB0700_DEFAULT_DEVICE_PROPERTIES,
3603
3604 .num_adapters = 1,
3605 .adapter = {
3606 {
3607 .num_frontends = 1,
3608 .fe = {{
3609 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3610 .pid_filter_count = 32,
3611 .pid_filter = stk7700p_pid_filter,
3612 .pid_filter_ctrl = stk7700p_pid_filter_ctrl,
3613 .frontend_attach = stk7700p_frontend_attach,
3614 .tuner_attach = stk7700p_tuner_attach,
3615
3616 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3617 }},
3618 },
3619 },
3620
3621 .num_device_descs = 8,
3622 .devices = {
3623 { "DiBcom STK7700P reference design",
3624 { &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] },
3625 { NULL },
3626 },
3627 { "Hauppauge Nova-T Stick",
3628 { &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL },
3629 { NULL },
3630 },
3631 { "AVerMedia AVerTV DVB-T Volar",
3632 { &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] },
3633 { NULL },
3634 },
3635 { "Compro Videomate U500",
3636 { &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] },
3637 { NULL },
3638 },
3639 { "Uniwill STK7700P based (Hama and others)",
3640 { &dib0700_usb_id_table[7], NULL },
3641 { NULL },
3642 },
3643 { "Leadtek Winfast DTV Dongle (STK7700P based)",
3644 { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] },
3645 { NULL },
3646 },
3647 { "AVerMedia AVerTV DVB-T Express",
3648 { &dib0700_usb_id_table[20] },
3649 { NULL },
3650 },
3651 { "Gigabyte U7000",
3652 { &dib0700_usb_id_table[21], NULL },
3653 { NULL },
3654 }
3655 },
3656
3657 .rc.core = {
3658 .rc_interval = DEFAULT_RC_INTERVAL,
3659 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3660 .rc_query = dib0700_rc_query_old_firmware,
3661 .allowed_protos = RC_TYPE_RC5 |
3662 RC_TYPE_RC6 |
3663 RC_TYPE_NEC,
3664 .change_protocol = dib0700_change_protocol,
3665 },
3666 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3667
3668 .num_adapters = 2,
3669 .adapter = {
3670 {
3671 .num_frontends = 1,
3672 .fe = {{
3673 .frontend_attach = bristol_frontend_attach,
3674 .tuner_attach = bristol_tuner_attach,
3675
3676 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3677 }},
3678 }, {
3679 .num_frontends = 1,
3680 .fe = {{
3681 .frontend_attach = bristol_frontend_attach,
3682 .tuner_attach = bristol_tuner_attach,
3683
3684 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
3685 }},
3686 }
3687 },
3688
3689 .num_device_descs = 1,
3690 .devices = {
3691 { "Hauppauge Nova-T 500 Dual DVB-T",
3692 { &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL },
3693 { NULL },
3694 },
3695 },
3696
3697 .rc.core = {
3698 .rc_interval = DEFAULT_RC_INTERVAL,
3699 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3700 .rc_query = dib0700_rc_query_old_firmware,
3701 .allowed_protos = RC_TYPE_RC5 |
3702 RC_TYPE_RC6 |
3703 RC_TYPE_NEC,
3704 .change_protocol = dib0700_change_protocol,
3705 },
3706 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3707
3708 .num_adapters = 2,
3709 .adapter = {
3710 {
3711 .num_frontends = 1,
3712 .fe = {{
3713 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3714 .pid_filter_count = 32,
3715 .pid_filter = stk70x0p_pid_filter,
3716 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3717 .frontend_attach = stk7700d_frontend_attach,
3718 .tuner_attach = stk7700d_tuner_attach,
3719
3720 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3721 }},
3722 }, {
3723 .num_frontends = 1,
3724 .fe = {{
3725 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3726 .pid_filter_count = 32,
3727 .pid_filter = stk70x0p_pid_filter,
3728 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3729 .frontend_attach = stk7700d_frontend_attach,
3730 .tuner_attach = stk7700d_tuner_attach,
3731
3732 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
3733 }},
3734 }
3735 },
3736
3737 .num_device_descs = 5,
3738 .devices = {
3739 { "Pinnacle PCTV 2000e",
3740 { &dib0700_usb_id_table[11], NULL },
3741 { NULL },
3742 },
3743 { "Terratec Cinergy DT XS Diversity",
3744 { &dib0700_usb_id_table[12], NULL },
3745 { NULL },
3746 },
3747 { "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity",
3748 { &dib0700_usb_id_table[13], NULL },
3749 { NULL },
3750 },
3751 { "DiBcom STK7700D reference design",
3752 { &dib0700_usb_id_table[14], NULL },
3753 { NULL },
3754 },
3755 { "YUAN High-Tech DiBcom STK7700D",
3756 { &dib0700_usb_id_table[55], NULL },
3757 { NULL },
3758 },
3759
3760 },
3761
3762 .rc.core = {
3763 .rc_interval = DEFAULT_RC_INTERVAL,
3764 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3765 .rc_query = dib0700_rc_query_old_firmware,
3766 .allowed_protos = RC_TYPE_RC5 |
3767 RC_TYPE_RC6 |
3768 RC_TYPE_NEC,
3769 .change_protocol = dib0700_change_protocol,
3770 },
3771 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3772
3773 .num_adapters = 1,
3774 .adapter = {
3775 {
3776 .num_frontends = 1,
3777 .fe = {{
3778 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3779 .pid_filter_count = 32,
3780 .pid_filter = stk70x0p_pid_filter,
3781 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3782 .frontend_attach = stk7700P2_frontend_attach,
3783 .tuner_attach = stk7700d_tuner_attach,
3784
3785 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3786 }},
3787 },
3788 },
3789
3790 .num_device_descs = 3,
3791 .devices = {
3792 { "ASUS My Cinema U3000 Mini DVBT Tuner",
3793 { &dib0700_usb_id_table[23], NULL },
3794 { NULL },
3795 },
3796 { "Yuan EC372S",
3797 { &dib0700_usb_id_table[31], NULL },
3798 { NULL },
3799 },
3800 { "Terratec Cinergy T Express",
3801 { &dib0700_usb_id_table[42], NULL },
3802 { NULL },
3803 }
3804 },
3805
3806 .rc.core = {
3807 .rc_interval = DEFAULT_RC_INTERVAL,
3808 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3809 .module_name = "dib0700",
3810 .rc_query = dib0700_rc_query_old_firmware,
3811 .allowed_protos = RC_TYPE_RC5 |
3812 RC_TYPE_RC6 |
3813 RC_TYPE_NEC,
3814 .change_protocol = dib0700_change_protocol,
3815 },
3816 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3817
3818 .num_adapters = 1,
3819 .adapter = {
3820 {
3821 .num_frontends = 1,
3822 .fe = {{
3823 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3824 .pid_filter_count = 32,
3825 .pid_filter = stk70x0p_pid_filter,
3826 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3827 .frontend_attach = stk7070p_frontend_attach,
3828 .tuner_attach = dib7070p_tuner_attach,
3829
3830 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3831 }},
3832 .size_of_priv = sizeof(struct dib0700_adapter_state),
3833 },
3834 },
3835
3836 .num_device_descs = 12,
3837 .devices = {
3838 { "DiBcom STK7070P reference design",
3839 { &dib0700_usb_id_table[15], NULL },
3840 { NULL },
3841 },
3842 { "Pinnacle PCTV DVB-T Flash Stick",
3843 { &dib0700_usb_id_table[16], NULL },
3844 { NULL },
3845 },
3846 { "Artec T14BR DVB-T",
3847 { &dib0700_usb_id_table[22], NULL },
3848 { NULL },
3849 },
3850 { "ASUS My Cinema U3100 Mini DVBT Tuner",
3851 { &dib0700_usb_id_table[24], NULL },
3852 { NULL },
3853 },
3854 { "Hauppauge Nova-T Stick",
3855 { &dib0700_usb_id_table[25], NULL },
3856 { NULL },
3857 },
3858 { "Hauppauge Nova-T MyTV.t",
3859 { &dib0700_usb_id_table[26], NULL },
3860 { NULL },
3861 },
3862 { "Pinnacle PCTV 72e",
3863 { &dib0700_usb_id_table[29], NULL },
3864 { NULL },
3865 },
3866 { "Pinnacle PCTV 73e",
3867 { &dib0700_usb_id_table[30], NULL },
3868 { NULL },
3869 },
3870 { "Elgato EyeTV DTT",
3871 { &dib0700_usb_id_table[49], NULL },
3872 { NULL },
3873 },
3874 { "Yuan PD378S",
3875 { &dib0700_usb_id_table[45], NULL },
3876 { NULL },
3877 },
3878 { "Elgato EyeTV Dtt Dlx PD378S",
3879 { &dib0700_usb_id_table[50], NULL },
3880 { NULL },
3881 },
3882 { "Elgato EyeTV DTT rev. 2",
3883 { &dib0700_usb_id_table[81], NULL },
3884 { NULL },
3885 },
3886 },
3887
3888 .rc.core = {
3889 .rc_interval = DEFAULT_RC_INTERVAL,
3890 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3891 .module_name = "dib0700",
3892 .rc_query = dib0700_rc_query_old_firmware,
3893 .allowed_protos = RC_TYPE_RC5 |
3894 RC_TYPE_RC6 |
3895 RC_TYPE_NEC,
3896 .change_protocol = dib0700_change_protocol,
3897 },
3898 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3899
3900 .num_adapters = 1,
3901 .adapter = {
3902 {
3903 .num_frontends = 1,
3904 .fe = {{
3905 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3906 .pid_filter_count = 32,
3907 .pid_filter = stk70x0p_pid_filter,
3908 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3909 .frontend_attach = stk7070p_frontend_attach,
3910 .tuner_attach = dib7070p_tuner_attach,
3911
3912 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3913 }},
3914 .size_of_priv = sizeof(struct dib0700_adapter_state),
3915 },
3916 },
3917
3918 .num_device_descs = 3,
3919 .devices = {
3920 { "Pinnacle PCTV 73A",
3921 { &dib0700_usb_id_table[56], NULL },
3922 { NULL },
3923 },
3924 { "Pinnacle PCTV 73e SE",
3925 { &dib0700_usb_id_table[57], &dib0700_usb_id_table[65], NULL },
3926 { NULL },
3927 },
3928 { "Pinnacle PCTV 282e",
3929 { &dib0700_usb_id_table[58], &dib0700_usb_id_table[66], NULL },
3930 { NULL },
3931 },
3932 },
3933
3934 .rc.core = {
3935 .rc_interval = DEFAULT_RC_INTERVAL,
3936 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3937 .module_name = "dib0700",
3938 .rc_query = dib0700_rc_query_old_firmware,
3939 .allowed_protos = RC_TYPE_RC5 |
3940 RC_TYPE_RC6 |
3941 RC_TYPE_NEC,
3942 .change_protocol = dib0700_change_protocol,
3943 },
3944 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3945
3946 .num_adapters = 2,
3947 .adapter = {
3948 {
3949 .num_frontends = 1,
3950 .fe = {{
3951 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3952 .pid_filter_count = 32,
3953 .pid_filter = stk70x0p_pid_filter,
3954 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3955 .frontend_attach = novatd_frontend_attach,
3956 .tuner_attach = dib7070p_tuner_attach,
3957
3958 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3959 }},
3960 .size_of_priv = sizeof(struct dib0700_adapter_state),
3961 }, {
3962 .num_frontends = 1,
3963 .fe = {{
3964 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3965 .pid_filter_count = 32,
3966 .pid_filter = stk70x0p_pid_filter,
3967 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3968 .frontend_attach = novatd_frontend_attach,
3969 .tuner_attach = dib7070p_tuner_attach,
3970
3971 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
3972 }},
3973 .size_of_priv = sizeof(struct dib0700_adapter_state),
3974 }
3975 },
3976
3977 .num_device_descs = 1,
3978 .devices = {
3979 { "Hauppauge Nova-TD Stick (52009)",
3980 { &dib0700_usb_id_table[35], NULL },
3981 { NULL },
3982 },
3983 },
3984
3985 .rc.core = {
3986 .rc_interval = DEFAULT_RC_INTERVAL,
3987 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3988 .module_name = "dib0700",
3989 .rc_query = dib0700_rc_query_old_firmware,
3990 .allowed_protos = RC_TYPE_RC5 |
3991 RC_TYPE_RC6 |
3992 RC_TYPE_NEC,
3993 .change_protocol = dib0700_change_protocol,
3994 },
3995 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3996
3997 .num_adapters = 2,
3998 .adapter = {
3999 {
4000 .num_frontends = 1,
4001 .fe = {{
4002 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4003 .pid_filter_count = 32,
4004 .pid_filter = stk70x0p_pid_filter,
4005 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4006 .frontend_attach = stk7070pd_frontend_attach0,
4007 .tuner_attach = dib7070p_tuner_attach,
4008
4009 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4010 }},
4011 .size_of_priv = sizeof(struct dib0700_adapter_state),
4012 }, {
4013 .num_frontends = 1,
4014 .fe = {{
4015 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4016 .pid_filter_count = 32,
4017 .pid_filter = stk70x0p_pid_filter,
4018 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4019 .frontend_attach = stk7070pd_frontend_attach1,
4020 .tuner_attach = dib7070p_tuner_attach,
4021
4022 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
4023 }},
4024 .size_of_priv = sizeof(struct dib0700_adapter_state),
4025 }
4026 },
4027
4028 .num_device_descs = 5,
4029 .devices = {
4030 { "DiBcom STK7070PD reference design",
4031 { &dib0700_usb_id_table[17], NULL },
4032 { NULL },
4033 },
4034 { "Pinnacle PCTV Dual DVB-T Diversity Stick",
4035 { &dib0700_usb_id_table[18], NULL },
4036 { NULL },
4037 },
4038 { "Hauppauge Nova-TD-500 (84xxx)",
4039 { &dib0700_usb_id_table[36], NULL },
4040 { NULL },
4041 },
4042 { "Terratec Cinergy DT USB XS Diversity/ T5",
4043 { &dib0700_usb_id_table[43],
4044 &dib0700_usb_id_table[53], NULL},
4045 { NULL },
4046 },
4047 { "Sony PlayTV",
4048 { &dib0700_usb_id_table[44], NULL },
4049 { NULL },
4050 },
4051 },
4052
4053 .rc.core = {
4054 .rc_interval = DEFAULT_RC_INTERVAL,
4055 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4056 .module_name = "dib0700",
4057 .rc_query = dib0700_rc_query_old_firmware,
4058 .allowed_protos = RC_TYPE_RC5 |
4059 RC_TYPE_RC6 |
4060 RC_TYPE_NEC,
4061 .change_protocol = dib0700_change_protocol,
4062 },
4063 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4064
4065 .num_adapters = 2,
4066 .adapter = {
4067 {
4068 .num_frontends = 1,
4069 .fe = {{
4070 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4071 .pid_filter_count = 32,
4072 .pid_filter = stk70x0p_pid_filter,
4073 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4074 .frontend_attach = stk7070pd_frontend_attach0,
4075 .tuner_attach = dib7070p_tuner_attach,
4076
4077 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4078 }},
4079 .size_of_priv = sizeof(struct dib0700_adapter_state),
4080 }, {
4081 .num_frontends = 1,
4082 .fe = {{
4083 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4084 .pid_filter_count = 32,
4085 .pid_filter = stk70x0p_pid_filter,
4086 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4087 .frontend_attach = stk7070pd_frontend_attach1,
4088 .tuner_attach = dib7070p_tuner_attach,
4089
4090 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
4091 }},
4092 .size_of_priv = sizeof(struct dib0700_adapter_state),
4093 }
4094 },
4095
4096 .num_device_descs = 1,
4097 .devices = {
4098 { "Elgato EyeTV Diversity",
4099 { &dib0700_usb_id_table[68], NULL },
4100 { NULL },
4101 },
4102 },
4103
4104 .rc.core = {
4105 .rc_interval = DEFAULT_RC_INTERVAL,
4106 .rc_codes = RC_MAP_DIB0700_NEC_TABLE,
4107 .module_name = "dib0700",
4108 .rc_query = dib0700_rc_query_old_firmware,
4109 .allowed_protos = RC_TYPE_RC5 |
4110 RC_TYPE_RC6 |
4111 RC_TYPE_NEC,
4112 .change_protocol = dib0700_change_protocol,
4113 },
4114 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4115
4116 .num_adapters = 1,
4117 .adapter = {
4118 {
4119 .num_frontends = 1,
4120 .fe = {{
4121 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4122 .pid_filter_count = 32,
4123 .pid_filter = stk70x0p_pid_filter,
4124 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4125 .frontend_attach = stk7700ph_frontend_attach,
4126 .tuner_attach = stk7700ph_tuner_attach,
4127
4128 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4129 }},
4130 .size_of_priv = sizeof(struct
4131 dib0700_adapter_state),
4132 },
4133 },
4134
4135 .num_device_descs = 9,
4136 .devices = {
4137 { "Terratec Cinergy HT USB XE",
4138 { &dib0700_usb_id_table[27], NULL },
4139 { NULL },
4140 },
4141 { "Pinnacle Expresscard 320cx",
4142 { &dib0700_usb_id_table[28], NULL },
4143 { NULL },
4144 },
4145 { "Terratec Cinergy HT Express",
4146 { &dib0700_usb_id_table[32], NULL },
4147 { NULL },
4148 },
4149 { "Gigabyte U8000-RH",
4150 { &dib0700_usb_id_table[37], NULL },
4151 { NULL },
4152 },
4153 { "YUAN High-Tech STK7700PH",
4154 { &dib0700_usb_id_table[38], NULL },
4155 { NULL },
4156 },
4157 { "Asus My Cinema-U3000Hybrid",
4158 { &dib0700_usb_id_table[39], NULL },
4159 { NULL },
4160 },
4161 { "YUAN High-Tech MC770",
4162 { &dib0700_usb_id_table[48], NULL },
4163 { NULL },
4164 },
4165 { "Leadtek WinFast DTV Dongle H",
4166 { &dib0700_usb_id_table[51], NULL },
4167 { NULL },
4168 },
4169 { "YUAN High-Tech STK7700D",
4170 { &dib0700_usb_id_table[54], NULL },
4171 { NULL },
4172 },
4173 },
4174
4175 .rc.core = {
4176 .rc_interval = DEFAULT_RC_INTERVAL,
4177 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4178 .module_name = "dib0700",
4179 .rc_query = dib0700_rc_query_old_firmware,
4180 .allowed_protos = RC_TYPE_RC5 |
4181 RC_TYPE_RC6 |
4182 RC_TYPE_NEC,
4183 .change_protocol = dib0700_change_protocol,
4184 },
4185 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4186 .num_adapters = 1,
4187 .adapter = {
4188 {
4189 .num_frontends = 1,
4190 .fe = {{
4191 .frontend_attach = s5h1411_frontend_attach,
4192 .tuner_attach = xc5000_tuner_attach,
4193
4194 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4195 }},
4196 .size_of_priv = sizeof(struct
4197 dib0700_adapter_state),
4198 },
4199 },
4200
4201 .num_device_descs = 2,
4202 .devices = {
4203 { "Pinnacle PCTV HD Pro USB Stick",
4204 { &dib0700_usb_id_table[40], NULL },
4205 { NULL },
4206 },
4207 { "Pinnacle PCTV HD USB Stick",
4208 { &dib0700_usb_id_table[41], NULL },
4209 { NULL },
4210 },
4211 },
4212
4213 .rc.core = {
4214 .rc_interval = DEFAULT_RC_INTERVAL,
4215 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4216 .module_name = "dib0700",
4217 .rc_query = dib0700_rc_query_old_firmware,
4218 .allowed_protos = RC_TYPE_RC5 |
4219 RC_TYPE_RC6 |
4220 RC_TYPE_NEC,
4221 .change_protocol = dib0700_change_protocol,
4222 },
4223 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4224 .num_adapters = 1,
4225 .adapter = {
4226 {
4227 .num_frontends = 1,
4228 .fe = {{
4229 .frontend_attach = lgdt3305_frontend_attach,
4230 .tuner_attach = mxl5007t_tuner_attach,
4231
4232 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4233 }},
4234 .size_of_priv = sizeof(struct
4235 dib0700_adapter_state),
4236 },
4237 },
4238
4239 .num_device_descs = 2,
4240 .devices = {
4241 { "Hauppauge ATSC MiniCard (B200)",
4242 { &dib0700_usb_id_table[46], NULL },
4243 { NULL },
4244 },
4245 { "Hauppauge ATSC MiniCard (B210)",
4246 { &dib0700_usb_id_table[47], NULL },
4247 { NULL },
4248 },
4249 },
4250 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4251
4252 .num_adapters = 1,
4253 .adapter = {
4254 {
4255 .num_frontends = 1,
4256 .fe = {{
4257 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4258 .pid_filter_count = 32,
4259 .pid_filter = stk70x0p_pid_filter,
4260 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4261 .frontend_attach = stk7770p_frontend_attach,
4262 .tuner_attach = dib7770p_tuner_attach,
4263
4264 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4265 }},
4266 .size_of_priv =
4267 sizeof(struct dib0700_adapter_state),
4268 },
4269 },
4270
4271 .num_device_descs = 4,
4272 .devices = {
4273 { "DiBcom STK7770P reference design",
4274 { &dib0700_usb_id_table[59], NULL },
4275 { NULL },
4276 },
4277 { "Terratec Cinergy T USB XXS (HD)/ T3",
4278 { &dib0700_usb_id_table[33],
4279 &dib0700_usb_id_table[52],
4280 &dib0700_usb_id_table[60], NULL},
4281 { NULL },
4282 },
4283 { "TechniSat AirStar TeleStick 2",
4284 { &dib0700_usb_id_table[74], NULL },
4285 { NULL },
4286 },
4287 { "Medion CTX1921 DVB-T USB",
4288 { &dib0700_usb_id_table[75], NULL },
4289 { NULL },
4290 },
4291 },
4292
4293 .rc.core = {
4294 .rc_interval = DEFAULT_RC_INTERVAL,
4295 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4296 .module_name = "dib0700",
4297 .rc_query = dib0700_rc_query_old_firmware,
4298 .allowed_protos = RC_TYPE_RC5 |
4299 RC_TYPE_RC6 |
4300 RC_TYPE_NEC,
4301 .change_protocol = dib0700_change_protocol,
4302 },
4303 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4304 .num_adapters = 1,
4305 .adapter = {
4306 {
4307 .num_frontends = 1,
4308 .fe = {{
4309 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4310 .pid_filter_count = 32,
4311 .pid_filter = stk80xx_pid_filter,
4312 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
4313 .frontend_attach = stk807x_frontend_attach,
4314 .tuner_attach = dib807x_tuner_attach,
4315
4316 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4317 }},
4318 .size_of_priv =
4319 sizeof(struct dib0700_adapter_state),
4320 },
4321 },
4322
4323 .num_device_descs = 3,
4324 .devices = {
4325 { "DiBcom STK807xP reference design",
4326 { &dib0700_usb_id_table[62], NULL },
4327 { NULL },
4328 },
4329 { "Prolink Pixelview SBTVD",
4330 { &dib0700_usb_id_table[63], NULL },
4331 { NULL },
4332 },
4333 { "EvolutePC TVWay+",
4334 { &dib0700_usb_id_table[64], NULL },
4335 { NULL },
4336 },
4337 },
4338
4339 .rc.core = {
4340 .rc_interval = DEFAULT_RC_INTERVAL,
4341 .rc_codes = RC_MAP_DIB0700_NEC_TABLE,
4342 .module_name = "dib0700",
4343 .rc_query = dib0700_rc_query_old_firmware,
4344 .allowed_protos = RC_TYPE_RC5 |
4345 RC_TYPE_RC6 |
4346 RC_TYPE_NEC,
4347 .change_protocol = dib0700_change_protocol,
4348 },
4349 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4350 .num_adapters = 2,
4351 .adapter = {
4352 {
4353 .num_frontends = 1,
4354 .fe = {{
4355 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4356 .pid_filter_count = 32,
4357 .pid_filter = stk80xx_pid_filter,
4358 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
4359 .frontend_attach = stk807xpvr_frontend_attach0,
4360 .tuner_attach = dib807x_tuner_attach,
4361
4362 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4363 }},
4364 .size_of_priv =
4365 sizeof(struct dib0700_adapter_state),
4366 },
4367 {
4368 .num_frontends = 1,
4369 .fe = {{
4370 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4371 .pid_filter_count = 32,
4372 .pid_filter = stk80xx_pid_filter,
4373 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
4374 .frontend_attach = stk807xpvr_frontend_attach1,
4375 .tuner_attach = dib807x_tuner_attach,
4376
4377 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
4378 }},
4379 .size_of_priv =
4380 sizeof(struct dib0700_adapter_state),
4381 },
4382 },
4383
4384 .num_device_descs = 1,
4385 .devices = {
4386 { "DiBcom STK807xPVR reference design",
4387 { &dib0700_usb_id_table[61], NULL },
4388 { NULL },
4389 },
4390 },
4391
4392 .rc.core = {
4393 .rc_interval = DEFAULT_RC_INTERVAL,
4394 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4395 .module_name = "dib0700",
4396 .rc_query = dib0700_rc_query_old_firmware,
4397 .allowed_protos = RC_TYPE_RC5 |
4398 RC_TYPE_RC6 |
4399 RC_TYPE_NEC,
4400 .change_protocol = dib0700_change_protocol,
4401 },
4402 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4403 .num_adapters = 1,
4404 .adapter = {
4405 {
4406 .num_frontends = 1,
4407 .fe = {{
4408 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4409 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4410 .pid_filter_count = 32,
4411 .pid_filter = stk80xx_pid_filter,
4412 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
4413 .frontend_attach = stk809x_frontend_attach,
4414 .tuner_attach = dib809x_tuner_attach,
4415
4416 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4417 }},
4418 .size_of_priv =
4419 sizeof(struct dib0700_adapter_state),
4420 },
4421 },
4422
4423 .num_device_descs = 1,
4424 .devices = {
4425 { "DiBcom STK8096GP reference design",
4426 { &dib0700_usb_id_table[67], NULL },
4427 { NULL },
4428 },
4429 },
4430
4431 .rc.core = {
4432 .rc_interval = DEFAULT_RC_INTERVAL,
4433 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4434 .module_name = "dib0700",
4435 .rc_query = dib0700_rc_query_old_firmware,
4436 .allowed_protos = RC_TYPE_RC5 |
4437 RC_TYPE_RC6 |
4438 RC_TYPE_NEC,
4439 .change_protocol = dib0700_change_protocol,
4440 },
4441 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4442 .num_adapters = 1,
4443 .adapter = {
4444 {
4445 .num_frontends = 1,
4446 .fe = {{
4447 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4448 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4449 .pid_filter_count = 32,
4450 .pid_filter = dib90x0_pid_filter,
4451 .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
4452 .frontend_attach = stk9090m_frontend_attach,
4453 .tuner_attach = dib9090_tuner_attach,
4454
4455 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4456 }},
4457 .size_of_priv =
4458 sizeof(struct dib0700_adapter_state),
4459 },
4460 },
4461
4462 .num_device_descs = 1,
4463 .devices = {
4464 { "DiBcom STK9090M reference design",
4465 { &dib0700_usb_id_table[69], NULL },
4466 { NULL },
4467 },
4468 },
4469
4470 .rc.core = {
4471 .rc_interval = DEFAULT_RC_INTERVAL,
4472 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4473 .module_name = "dib0700",
4474 .rc_query = dib0700_rc_query_old_firmware,
4475 .allowed_protos = RC_TYPE_RC5 |
4476 RC_TYPE_RC6 |
4477 RC_TYPE_NEC,
4478 .change_protocol = dib0700_change_protocol,
4479 },
4480 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4481 .num_adapters = 1,
4482 .adapter = {
4483 {
4484 .num_frontends = 1,
4485 .fe = {{
4486 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4487 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4488 .pid_filter_count = 32,
4489 .pid_filter = stk80xx_pid_filter,
4490 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
4491 .frontend_attach = nim8096md_frontend_attach,
4492 .tuner_attach = nim8096md_tuner_attach,
4493
4494 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4495 }},
4496 .size_of_priv =
4497 sizeof(struct dib0700_adapter_state),
4498 },
4499 },
4500
4501 .num_device_descs = 1,
4502 .devices = {
4503 { "DiBcom NIM8096MD reference design",
4504 { &dib0700_usb_id_table[70], NULL },
4505 { NULL },
4506 },
4507 },
4508
4509 .rc.core = {
4510 .rc_interval = DEFAULT_RC_INTERVAL,
4511 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4512 .module_name = "dib0700",
4513 .rc_query = dib0700_rc_query_old_firmware,
4514 .allowed_protos = RC_TYPE_RC5 |
4515 RC_TYPE_RC6 |
4516 RC_TYPE_NEC,
4517 .change_protocol = dib0700_change_protocol,
4518 },
4519 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4520 .num_adapters = 1,
4521 .adapter = {
4522 {
4523 .num_frontends = 1,
4524 .fe = {{
4525 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4526 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4527 .pid_filter_count = 32,
4528 .pid_filter = dib90x0_pid_filter,
4529 .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
4530 .frontend_attach = nim9090md_frontend_attach,
4531 .tuner_attach = nim9090md_tuner_attach,
4532
4533 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4534 }},
4535 .size_of_priv =
4536 sizeof(struct dib0700_adapter_state),
4537 },
4538 },
4539
4540 .num_device_descs = 1,
4541 .devices = {
4542 { "DiBcom NIM9090MD reference design",
4543 { &dib0700_usb_id_table[71], NULL },
4544 { NULL },
4545 },
4546 },
4547
4548 .rc.core = {
4549 .rc_interval = DEFAULT_RC_INTERVAL,
4550 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4551 .module_name = "dib0700",
4552 .rc_query = dib0700_rc_query_old_firmware,
4553 .allowed_protos = RC_TYPE_RC5 |
4554 RC_TYPE_RC6 |
4555 RC_TYPE_NEC,
4556 .change_protocol = dib0700_change_protocol,
4557 },
4558 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4559 .num_adapters = 1,
4560 .adapter = {
4561 {
4562 .num_frontends = 1,
4563 .fe = {{
4564 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4565 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4566 .pid_filter_count = 32,
4567 .pid_filter = stk70x0p_pid_filter,
4568 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4569 .frontend_attach = nim7090_frontend_attach,
4570 .tuner_attach = nim7090_tuner_attach,
4571
4572 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4573 }},
4574 .size_of_priv =
4575 sizeof(struct dib0700_adapter_state),
4576 },
4577 },
4578
4579 .num_device_descs = 1,
4580 .devices = {
4581 { "DiBcom NIM7090 reference design",
4582 { &dib0700_usb_id_table[72], NULL },
4583 { NULL },
4584 },
4585 },
4586
4587 .rc.core = {
4588 .rc_interval = DEFAULT_RC_INTERVAL,
4589 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4590 .module_name = "dib0700",
4591 .rc_query = dib0700_rc_query_old_firmware,
4592 .allowed_protos = RC_TYPE_RC5 |
4593 RC_TYPE_RC6 |
4594 RC_TYPE_NEC,
4595 .change_protocol = dib0700_change_protocol,
4596 },
4597 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4598 .num_adapters = 2,
4599 .adapter = {
4600 {
4601 .num_frontends = 1,
4602 .fe = {{
4603 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4604 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4605 .pid_filter_count = 32,
4606 .pid_filter = stk70x0p_pid_filter,
4607 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4608 .frontend_attach = tfe7090pvr_frontend0_attach,
4609 .tuner_attach = tfe7090pvr_tuner0_attach,
4610
4611 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
4612 }},
4613 .size_of_priv =
4614 sizeof(struct dib0700_adapter_state),
4615 },
4616 {
4617 .num_frontends = 1,
4618 .fe = {{
4619 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4620 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4621 .pid_filter_count = 32,
4622 .pid_filter = stk70x0p_pid_filter,
4623 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4624 .frontend_attach = tfe7090pvr_frontend1_attach,
4625 .tuner_attach = tfe7090pvr_tuner1_attach,
4626
4627 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4628 }},
4629 .size_of_priv =
4630 sizeof(struct dib0700_adapter_state),
4631 },
4632 },
4633
4634 .num_device_descs = 1,
4635 .devices = {
4636 { "DiBcom TFE7090PVR reference design",
4637 { &dib0700_usb_id_table[73], NULL },
4638 { NULL },
4639 },
4640 },
4641
4642 .rc.core = {
4643 .rc_interval = DEFAULT_RC_INTERVAL,
4644 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4645 .module_name = "dib0700",
4646 .rc_query = dib0700_rc_query_old_firmware,
4647 .allowed_protos = RC_TYPE_RC5 |
4648 RC_TYPE_RC6 |
4649 RC_TYPE_NEC,
4650 .change_protocol = dib0700_change_protocol,
4651 },
4652 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4653 .num_adapters = 1,
4654 .adapter = {
4655 {
4656 .num_frontends = 1,
4657 .fe = {{
4658 .frontend_attach = pctv340e_frontend_attach,
4659 .tuner_attach = xc4000_tuner_attach,
4660
4661 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4662 }},
4663 .size_of_priv = sizeof(struct
4664 dib0700_adapter_state),
4665 },
4666 },
4667
4668 .num_device_descs = 2,
4669 .devices = {
4670 { "Pinnacle PCTV 340e HD Pro USB Stick",
4671 { &dib0700_usb_id_table[76], NULL },
4672 { NULL },
4673 },
4674 { "Pinnacle PCTV Hybrid Stick Solo",
4675 { &dib0700_usb_id_table[77], NULL },
4676 { NULL },
4677 },
4678 },
4679 .rc.core = {
4680 .rc_interval = DEFAULT_RC_INTERVAL,
4681 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4682 .module_name = "dib0700",
4683 .rc_query = dib0700_rc_query_old_firmware,
4684 .allowed_protos = RC_TYPE_RC5 |
4685 RC_TYPE_RC6 |
4686 RC_TYPE_NEC,
4687 .change_protocol = dib0700_change_protocol,
4688 },
4689 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4690 .num_adapters = 1,
4691 .adapter = {
4692 {
4693 .num_frontends = 1,
4694 .fe = {{
4695 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4696 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4697 .pid_filter_count = 32,
4698 .pid_filter = stk70x0p_pid_filter,
4699 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4700 .frontend_attach = tfe7090e_frontend_attach,
4701 .tuner_attach = tfe7090e_tuner_attach,
4702
4703 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4704 } },
4705
4706 .size_of_priv =
4707 sizeof(struct dib0700_adapter_state),
4708 },
4709 },
4710
4711 .num_device_descs = 1,
4712 .devices = {
4713 { "DiBcom TFE7090E reference design",
4714 { &dib0700_usb_id_table[78], NULL },
4715 { NULL },
4716 },
4717 },
4718
4719 .rc.core = {
4720 .rc_interval = DEFAULT_RC_INTERVAL,
4721 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4722 .module_name = "dib0700",
4723 .rc_query = dib0700_rc_query_old_firmware,
4724 .allowed_protos = RC_TYPE_RC5 |
4725 RC_TYPE_RC6 |
4726 RC_TYPE_NEC,
4727 .change_protocol = dib0700_change_protocol,
4728 },
4729 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4730 .num_adapters = 1,
4731 .adapter = {
4732 {
4733 .num_frontends = 1,
4734 .fe = {{
4735 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4736 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4737 .pid_filter_count = 32,
4738 .pid_filter = stk70x0p_pid_filter,
4739 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
4740 .frontend_attach = tfe7790e_frontend_attach,
4741 .tuner_attach = tfe7790e_tuner_attach,
4742
4743 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
4744 } },
4745
4746 .size_of_priv =
4747 sizeof(struct dib0700_adapter_state),
4748 },
4749 },
4750
4751 .num_device_descs = 1,
4752 .devices = {
4753 { "DiBcom TFE7790E reference design",
4754 { &dib0700_usb_id_table[79], NULL },
4755 { NULL },
4756 },
4757 },
4758
4759 .rc.core = {
4760 .rc_interval = DEFAULT_RC_INTERVAL,
4761 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4762 .module_name = "dib0700",
4763 .rc_query = dib0700_rc_query_old_firmware,
4764 .allowed_protos = RC_TYPE_RC5 |
4765 RC_TYPE_RC6 |
4766 RC_TYPE_NEC,
4767 .change_protocol = dib0700_change_protocol,
4768 },
4769 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
4770 .num_adapters = 1,
4771 .adapter = {
4772 {
4773 .num_frontends = 1,
4774 .fe = {{
4775 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
4776 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
4777 .pid_filter_count = 32,
4778 .pid_filter = stk80xx_pid_filter,
4779 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
4780 .frontend_attach = tfe8096p_frontend_attach,
4781 .tuner_attach = tfe8096p_tuner_attach,
4782
4783 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
4784
4785 } },
4786
4787 .size_of_priv =
4788 sizeof(struct dib0700_adapter_state),
4789 },
4790 },
4791
4792 .num_device_descs = 1,
4793 .devices = {
4794 { "DiBcom TFE8096P reference design",
4795 { &dib0700_usb_id_table[80], NULL },
4796 { NULL },
4797 },
4798 },
4799
4800 .rc.core = {
4801 .rc_interval = DEFAULT_RC_INTERVAL,
4802 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
4803 .module_name = "dib0700",
4804 .rc_query = dib0700_rc_query_old_firmware,
4805 .allowed_protos = RC_TYPE_RC5 |
4806 RC_TYPE_RC6 |
4807 RC_TYPE_NEC,
4808 .change_protocol = dib0700_change_protocol,
4809 },
4810 },
4811};
4812
4813int dib0700_device_count = ARRAY_SIZE(dib0700_devices);
diff --git a/drivers/media/usb/dvb-usb/dib07x0.h b/drivers/media/usb/dvb-usb/dib07x0.h
new file mode 100644
index 000000000000..7e62c1018520
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dib07x0.h
@@ -0,0 +1,21 @@
1#ifndef _DIB07X0_H_
2#define _DIB07X0_H_
3
4enum dib07x0_gpios {
5 GPIO0 = 0,
6 GPIO1 = 2,
7 GPIO2 = 3,
8 GPIO3 = 4,
9 GPIO4 = 5,
10 GPIO5 = 6,
11 GPIO6 = 8,
12 GPIO7 = 10,
13 GPIO8 = 11,
14 GPIO9 = 14,
15 GPIO10 = 15,
16};
17
18#define GPIO_IN 0
19#define GPIO_OUT 1
20
21#endif
diff --git a/drivers/media/usb/dvb-usb/dibusb-common.c b/drivers/media/usb/dvb-usb/dibusb-common.c
new file mode 100644
index 000000000000..a76bbb29ca36
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dibusb-common.c
@@ -0,0 +1,479 @@
1/* Common methods for dibusb-based-receivers.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation, version 2.
8 *
9 * see Documentation/dvb/README.dvb-usb for more information
10 */
11#include "dibusb.h"
12
13static int debug;
14module_param(debug, int, 0644);
15MODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS);
16MODULE_LICENSE("GPL");
17
18#define deb_info(args...) dprintk(debug,0x01,args)
19
20/* common stuff used by the different dibusb modules */
21int dibusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
22{
23 if (adap->priv != NULL) {
24 struct dibusb_state *st = adap->priv;
25 if (st->ops.fifo_ctrl != NULL)
26 if (st->ops.fifo_ctrl(adap->fe_adap[0].fe, onoff)) {
27 err("error while controlling the fifo of the demod.");
28 return -ENODEV;
29 }
30 }
31 return 0;
32}
33EXPORT_SYMBOL(dibusb_streaming_ctrl);
34
35int dibusb_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
36{
37 if (adap->priv != NULL) {
38 struct dibusb_state *st = adap->priv;
39 if (st->ops.pid_ctrl != NULL)
40 st->ops.pid_ctrl(adap->fe_adap[0].fe,
41 index, pid, onoff);
42 }
43 return 0;
44}
45EXPORT_SYMBOL(dibusb_pid_filter);
46
47int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
48{
49 if (adap->priv != NULL) {
50 struct dibusb_state *st = adap->priv;
51 if (st->ops.pid_parse != NULL)
52 if (st->ops.pid_parse(adap->fe_adap[0].fe, onoff) < 0)
53 err("could not handle pid_parser");
54 }
55 return 0;
56}
57EXPORT_SYMBOL(dibusb_pid_filter_ctrl);
58
59int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff)
60{
61 u8 b[3];
62 int ret;
63 b[0] = DIBUSB_REQ_SET_IOCTL;
64 b[1] = DIBUSB_IOCTL_CMD_POWER_MODE;
65 b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP;
66 ret = dvb_usb_generic_write(d,b,3);
67 msleep(10);
68 return ret;
69}
70EXPORT_SYMBOL(dibusb_power_ctrl);
71
72int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
73{
74 u8 b[3] = { 0 };
75 int ret;
76
77 if ((ret = dibusb_streaming_ctrl(adap,onoff)) < 0)
78 return ret;
79
80 if (onoff) {
81 b[0] = DIBUSB_REQ_SET_STREAMING_MODE;
82 b[1] = 0x00;
83 if ((ret = dvb_usb_generic_write(adap->dev,b,2)) < 0)
84 return ret;
85 }
86
87 b[0] = DIBUSB_REQ_SET_IOCTL;
88 b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM;
89 return dvb_usb_generic_write(adap->dev,b,3);
90}
91EXPORT_SYMBOL(dibusb2_0_streaming_ctrl);
92
93int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff)
94{
95 if (onoff) {
96 u8 b[3] = { DIBUSB_REQ_SET_IOCTL, DIBUSB_IOCTL_CMD_POWER_MODE, DIBUSB_IOCTL_POWER_WAKEUP };
97 return dvb_usb_generic_write(d,b,3);
98 } else
99 return 0;
100}
101EXPORT_SYMBOL(dibusb2_0_power_ctrl);
102
103static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr,
104 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
105{
106 u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */
107 /* write only ? */
108 int wo = (rbuf == NULL || rlen == 0),
109 len = 2 + wlen + (wo ? 0 : 2);
110
111 sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ;
112 sndbuf[1] = (addr << 1) | (wo ? 0 : 1);
113
114 memcpy(&sndbuf[2],wbuf,wlen);
115
116 if (!wo) {
117 sndbuf[wlen+2] = (rlen >> 8) & 0xff;
118 sndbuf[wlen+3] = rlen & 0xff;
119 }
120
121 return dvb_usb_generic_rw(d,sndbuf,len,rbuf,rlen,0);
122}
123
124/*
125 * I2C master xfer function
126 */
127static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
128{
129 struct dvb_usb_device *d = i2c_get_adapdata(adap);
130 int i;
131
132 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
133 return -EAGAIN;
134
135 for (i = 0; i < num; i++) {
136 /* write/read request */
137 if (i+1 < num && (msg[i].flags & I2C_M_RD) == 0
138 && (msg[i+1].flags & I2C_M_RD)) {
139 if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,
140 msg[i+1].buf,msg[i+1].len) < 0)
141 break;
142 i++;
143 } else if ((msg[i].flags & I2C_M_RD) == 0) {
144 if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0)
145 break;
146 } else if (msg[i].addr != 0x50) {
147 /* 0x50 is the address of the eeprom - we need to protect it
148 * from dibusb's bad i2c implementation: reads without
149 * writing the offset before are forbidden */
150 if (dibusb_i2c_msg(d, msg[i].addr, NULL, 0, msg[i].buf, msg[i].len) < 0)
151 break;
152 }
153 }
154
155 mutex_unlock(&d->i2c_mutex);
156 return i;
157}
158
159static u32 dibusb_i2c_func(struct i2c_adapter *adapter)
160{
161 return I2C_FUNC_I2C;
162}
163
164struct i2c_algorithm dibusb_i2c_algo = {
165 .master_xfer = dibusb_i2c_xfer,
166 .functionality = dibusb_i2c_func,
167};
168EXPORT_SYMBOL(dibusb_i2c_algo);
169
170int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
171{
172 u8 wbuf[1] = { offs };
173 return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1);
174}
175EXPORT_SYMBOL(dibusb_read_eeprom_byte);
176
177/* 3000MC/P stuff */
178// Config Adjacent channels Perf -cal22
179static struct dibx000_agc_config dib3000p_mt2060_agc_config = {
180 .band_caps = BAND_VHF | BAND_UHF,
181 .setup = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0),
182
183 .agc1_max = 48497,
184 .agc1_min = 23593,
185 .agc2_max = 46531,
186 .agc2_min = 24904,
187
188 .agc1_pt1 = 0x65,
189 .agc1_pt2 = 0x69,
190
191 .agc1_slope1 = 0x51,
192 .agc1_slope2 = 0x27,
193
194 .agc2_pt1 = 0,
195 .agc2_pt2 = 0x33,
196
197 .agc2_slope1 = 0x35,
198 .agc2_slope2 = 0x37,
199};
200
201static struct dib3000mc_config stk3000p_dib3000p_config = {
202 &dib3000p_mt2060_agc_config,
203
204 .max_time = 0x196,
205 .ln_adc_level = 0x1cc7,
206
207 .output_mpeg2_in_188_bytes = 1,
208
209 .agc_command1 = 1,
210 .agc_command2 = 1,
211};
212
213static struct dibx000_agc_config dib3000p_panasonic_agc_config = {
214 .band_caps = BAND_VHF | BAND_UHF,
215 .setup = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0),
216
217 .agc1_max = 56361,
218 .agc1_min = 22282,
219 .agc2_max = 47841,
220 .agc2_min = 36045,
221
222 .agc1_pt1 = 0x3b,
223 .agc1_pt2 = 0x6b,
224
225 .agc1_slope1 = 0x55,
226 .agc1_slope2 = 0x1d,
227
228 .agc2_pt1 = 0,
229 .agc2_pt2 = 0x0a,
230
231 .agc2_slope1 = 0x95,
232 .agc2_slope2 = 0x1e,
233};
234
235#if defined(CONFIG_DVB_DIB3000MC) || \
236 (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE))
237
238static struct dib3000mc_config mod3000p_dib3000p_config = {
239 &dib3000p_panasonic_agc_config,
240
241 .max_time = 0x51,
242 .ln_adc_level = 0x1cc7,
243
244 .output_mpeg2_in_188_bytes = 1,
245
246 .agc_command1 = 1,
247 .agc_command2 = 1,
248};
249
250int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap)
251{
252 if (adap->dev->udev->descriptor.idVendor == USB_VID_LITEON &&
253 adap->dev->udev->descriptor.idProduct ==
254 USB_PID_LITEON_DVB_T_WARM) {
255 msleep(1000);
256 }
257
258 adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach,
259 &adap->dev->i2c_adap,
260 DEFAULT_DIB3000P_I2C_ADDRESS,
261 &mod3000p_dib3000p_config);
262 if ((adap->fe_adap[0].fe) == NULL)
263 adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach,
264 &adap->dev->i2c_adap,
265 DEFAULT_DIB3000MC_I2C_ADDRESS,
266 &mod3000p_dib3000p_config);
267 if ((adap->fe_adap[0].fe) != NULL) {
268 if (adap->priv != NULL) {
269 struct dibusb_state *st = adap->priv;
270 st->ops.pid_parse = dib3000mc_pid_parse;
271 st->ops.pid_ctrl = dib3000mc_pid_control;
272 }
273 return 0;
274 }
275 return -ENODEV;
276}
277EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);
278
279static struct mt2060_config stk3000p_mt2060_config = {
280 0x60
281};
282
283int dibusb_dib3000mc_tuner_attach(struct dvb_usb_adapter *adap)
284{
285 struct dibusb_state *st = adap->priv;
286 u8 a,b;
287 u16 if1 = 1220;
288 struct i2c_adapter *tun_i2c;
289
290 // First IF calibration for Liteon Sticks
291 if (adap->dev->udev->descriptor.idVendor == USB_VID_LITEON &&
292 adap->dev->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) {
293
294 dibusb_read_eeprom_byte(adap->dev,0x7E,&a);
295 dibusb_read_eeprom_byte(adap->dev,0x7F,&b);
296
297 if (a == 0x00)
298 if1 += b;
299 else if (a == 0x80)
300 if1 -= b;
301 else
302 warn("LITE-ON DVB-T: Strange IF1 calibration :%2X %2X\n", a, b);
303
304 } else if (adap->dev->udev->descriptor.idVendor == USB_VID_DIBCOM &&
305 adap->dev->udev->descriptor.idProduct == USB_PID_DIBCOM_MOD3001_WARM) {
306 u8 desc;
307 dibusb_read_eeprom_byte(adap->dev, 7, &desc);
308 if (desc == 2) {
309 a = 127;
310 do {
311 dibusb_read_eeprom_byte(adap->dev, a, &desc);
312 a--;
313 } while (a > 7 && (desc == 0xff || desc == 0x00));
314 if (desc & 0x80)
315 if1 -= (0xff - desc);
316 else
317 if1 += desc;
318 }
319 }
320
321 tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe_adap[0].fe, 1);
322 if (dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c, &stk3000p_mt2060_config, if1) == NULL) {
323 /* not found - use panasonic pll parameters */
324 if (dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, tun_i2c, DVB_PLL_ENV57H1XD5) == NULL)
325 return -ENOMEM;
326 } else {
327 st->mt2060_present = 1;
328 /* set the correct parameters for the dib3000p */
329 dib3000mc_set_config(adap->fe_adap[0].fe, &stk3000p_dib3000p_config);
330 }
331 return 0;
332}
333EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
334#endif
335
336/*
337 * common remote control stuff
338 */
339struct rc_map_table rc_map_dibusb_table[] = {
340 /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */
341 { 0x0016, KEY_POWER },
342 { 0x0010, KEY_MUTE },
343 { 0x0003, KEY_1 },
344 { 0x0001, KEY_2 },
345 { 0x0006, KEY_3 },
346 { 0x0009, KEY_4 },
347 { 0x001d, KEY_5 },
348 { 0x001f, KEY_6 },
349 { 0x000d, KEY_7 },
350 { 0x0019, KEY_8 },
351 { 0x001b, KEY_9 },
352 { 0x0015, KEY_0 },
353 { 0x0005, KEY_CHANNELUP },
354 { 0x0002, KEY_CHANNELDOWN },
355 { 0x001e, KEY_VOLUMEUP },
356 { 0x000a, KEY_VOLUMEDOWN },
357 { 0x0011, KEY_RECORD },
358 { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
359 { 0x0014, KEY_PLAY },
360 { 0x001a, KEY_STOP },
361 { 0x0040, KEY_REWIND },
362 { 0x0012, KEY_FASTFORWARD },
363 { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
364 { 0x004c, KEY_PAUSE },
365 { 0x004d, KEY_SCREEN }, /* Full screen mode. */
366 { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
367 /* additional keys TwinHan VisionPlus, the Artec seemingly not have */
368 { 0x000c, KEY_CANCEL }, /* Cancel */
369 { 0x001c, KEY_EPG }, /* EPG */
370 { 0x0000, KEY_TAB }, /* Tab */
371 { 0x0048, KEY_INFO }, /* Preview */
372 { 0x0004, KEY_LIST }, /* RecordList */
373 { 0x000f, KEY_TEXT }, /* Teletext */
374 /* Key codes for the KWorld/ADSTech/JetWay remote. */
375 { 0x8612, KEY_POWER },
376 { 0x860f, KEY_SELECT }, /* source */
377 { 0x860c, KEY_UNKNOWN }, /* scan */
378 { 0x860b, KEY_EPG },
379 { 0x8610, KEY_MUTE },
380 { 0x8601, KEY_1 },
381 { 0x8602, KEY_2 },
382 { 0x8603, KEY_3 },
383 { 0x8604, KEY_4 },
384 { 0x8605, KEY_5 },
385 { 0x8606, KEY_6 },
386 { 0x8607, KEY_7 },
387 { 0x8608, KEY_8 },
388 { 0x8609, KEY_9 },
389 { 0x860a, KEY_0 },
390 { 0x8618, KEY_ZOOM },
391 { 0x861c, KEY_UNKNOWN }, /* preview */
392 { 0x8613, KEY_UNKNOWN }, /* snap */
393 { 0x8600, KEY_UNDO },
394 { 0x861d, KEY_RECORD },
395 { 0x860d, KEY_STOP },
396 { 0x860e, KEY_PAUSE },
397 { 0x8616, KEY_PLAY },
398 { 0x8611, KEY_BACK },
399 { 0x8619, KEY_FORWARD },
400 { 0x8614, KEY_UNKNOWN }, /* pip */
401 { 0x8615, KEY_ESC },
402 { 0x861a, KEY_UP },
403 { 0x861e, KEY_DOWN },
404 { 0x861f, KEY_LEFT },
405 { 0x861b, KEY_RIGHT },
406
407 /* Key codes for the DiBcom MOD3000 remote. */
408 { 0x8000, KEY_MUTE },
409 { 0x8001, KEY_TEXT },
410 { 0x8002, KEY_HOME },
411 { 0x8003, KEY_POWER },
412
413 { 0x8004, KEY_RED },
414 { 0x8005, KEY_GREEN },
415 { 0x8006, KEY_YELLOW },
416 { 0x8007, KEY_BLUE },
417
418 { 0x8008, KEY_DVD },
419 { 0x8009, KEY_AUDIO },
420 { 0x800a, KEY_IMAGES }, /* Pictures */
421 { 0x800b, KEY_VIDEO },
422
423 { 0x800c, KEY_BACK },
424 { 0x800d, KEY_UP },
425 { 0x800e, KEY_RADIO },
426 { 0x800f, KEY_EPG },
427
428 { 0x8010, KEY_LEFT },
429 { 0x8011, KEY_OK },
430 { 0x8012, KEY_RIGHT },
431 { 0x8013, KEY_UNKNOWN }, /* SAP */
432
433 { 0x8014, KEY_TV },
434 { 0x8015, KEY_DOWN },
435 { 0x8016, KEY_MENU }, /* DVD Menu */
436 { 0x8017, KEY_LAST },
437
438 { 0x8018, KEY_RECORD },
439 { 0x8019, KEY_STOP },
440 { 0x801a, KEY_PAUSE },
441 { 0x801b, KEY_PLAY },
442
443 { 0x801c, KEY_PREVIOUS },
444 { 0x801d, KEY_REWIND },
445 { 0x801e, KEY_FASTFORWARD },
446 { 0x801f, KEY_NEXT},
447
448 { 0x8040, KEY_1 },
449 { 0x8041, KEY_2 },
450 { 0x8042, KEY_3 },
451 { 0x8043, KEY_CHANNELUP },
452
453 { 0x8044, KEY_4 },
454 { 0x8045, KEY_5 },
455 { 0x8046, KEY_6 },
456 { 0x8047, KEY_CHANNELDOWN },
457
458 { 0x8048, KEY_7 },
459 { 0x8049, KEY_8 },
460 { 0x804a, KEY_9 },
461 { 0x804b, KEY_VOLUMEUP },
462
463 { 0x804c, KEY_CLEAR },
464 { 0x804d, KEY_0 },
465 { 0x804e, KEY_ENTER },
466 { 0x804f, KEY_VOLUMEDOWN },
467};
468EXPORT_SYMBOL(rc_map_dibusb_table);
469
470int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
471{
472 u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE;
473 dvb_usb_generic_rw(d,&cmd,1,key,5,0);
474 dvb_usb_nec_rc_key_to_event(d,key,event,state);
475 if (key[0] != 0)
476 deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
477 return 0;
478}
479EXPORT_SYMBOL(dibusb_rc_query);
diff --git a/drivers/media/usb/dvb-usb/dibusb-mb.c b/drivers/media/usb/dvb-usb/dibusb-mb.c
new file mode 100644
index 000000000000..a4ac37e0e98b
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dibusb-mb.c
@@ -0,0 +1,471 @@
1/* DVB USB compliant linux driver for mobile DVB-T USB devices based on
2 * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B)
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * based on GPL code from DiBcom, which has
7 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation, version 2.
12 *
13 * see Documentation/dvb/README.dvb-usb for more information
14 */
15#include "dibusb.h"
16
17DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
18
19static int dib3000mb_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
20{
21 struct dvb_usb_adapter *adap = fe->dvb->priv;
22 struct dibusb_state *st = adap->priv;
23
24 return st->ops.tuner_pass_ctrl(fe, enable, st->tuner_addr);
25}
26
27static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap)
28{
29 struct dib3000_config demod_cfg;
30 struct dibusb_state *st = adap->priv;
31
32 demod_cfg.demod_address = 0x8;
33
34 adap->fe_adap[0].fe = dvb_attach(dib3000mb_attach, &demod_cfg,
35 &adap->dev->i2c_adap, &st->ops);
36 if ((adap->fe_adap[0].fe) == NULL)
37 return -ENODEV;
38
39 adap->fe_adap[0].fe->ops.i2c_gate_ctrl = dib3000mb_i2c_gate_ctrl;
40
41 return 0;
42}
43
44static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap)
45{
46 struct dibusb_state *st = adap->priv;
47
48 st->tuner_addr = 0x61;
49
50 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, &adap->dev->i2c_adap,
51 DVB_PLL_TUA6010XS);
52 return 0;
53}
54
55static int dibusb_panasonic_tuner_attach(struct dvb_usb_adapter *adap)
56{
57 struct dibusb_state *st = adap->priv;
58
59 st->tuner_addr = 0x60;
60
61 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap,
62 DVB_PLL_TDA665X);
63 return 0;
64}
65
66/* Some of the Artec 1.1 device aren't equipped with the default tuner
67 * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures
68 * this out. */
69static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap)
70{
71 u8 b[2] = { 0,0 }, b2[1];
72 int ret = 0;
73 struct i2c_msg msg[2] = {
74 { .flags = 0, .buf = b, .len = 2 },
75 { .flags = I2C_M_RD, .buf = b2, .len = 1 },
76 };
77 struct dibusb_state *st = adap->priv;
78
79 /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */
80 msg[0].addr = msg[1].addr = st->tuner_addr = 0x60;
81
82 if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
83 adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1);
84
85 if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) {
86 err("tuner i2c write failed.");
87 ret = -EREMOTEIO;
88 }
89
90 if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl)
91 adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0);
92
93 if (b2[0] == 0xfe) {
94 info("This device has the Thomson Cable onboard. Which is default.");
95 ret = dibusb_thomson_tuner_attach(adap);
96 } else {
97 info("This device has the Panasonic ENV77H11D5 onboard.");
98 ret = dibusb_panasonic_tuner_attach(adap);
99 }
100
101 return ret;
102}
103
104/* USB Driver stuff */
105static struct dvb_usb_device_properties dibusb1_1_properties;
106static struct dvb_usb_device_properties dibusb1_1_an2235_properties;
107static struct dvb_usb_device_properties dibusb2_0b_properties;
108static struct dvb_usb_device_properties artec_t1_usb2_properties;
109
110static int dibusb_probe(struct usb_interface *intf,
111 const struct usb_device_id *id)
112{
113 if (0 == dvb_usb_device_init(intf, &dibusb1_1_properties,
114 THIS_MODULE, NULL, adapter_nr) ||
115 0 == dvb_usb_device_init(intf, &dibusb1_1_an2235_properties,
116 THIS_MODULE, NULL, adapter_nr) ||
117 0 == dvb_usb_device_init(intf, &dibusb2_0b_properties,
118 THIS_MODULE, NULL, adapter_nr) ||
119 0 == dvb_usb_device_init(intf, &artec_t1_usb2_properties,
120 THIS_MODULE, NULL, adapter_nr))
121 return 0;
122
123 return -EINVAL;
124}
125
126/* do not change the order of the ID table */
127static struct usb_device_id dibusb_dib3000mb_table [] = {
128/* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD) },
129/* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM) },
130/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) },
131/* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) },
132/* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) },
133/* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) },
134/* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) },
135/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) },
136/* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) },
137/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) },
138/* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) },
139/* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) },
140/* 12 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) },
141/* 13 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) },
142/* 14 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) },
143/* 15 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_COLD) },
144/* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) },
145/* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) },
146/* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) },
147/* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) },
148/* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) },
149/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) },
150/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) },
151/* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) },
152
153/* device ID with default DIBUSB2_0-firmware and with the hacked firmware */
154/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) },
155/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) },
156/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) },
157
158/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) },
159
160/* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
161/* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) },
162
163/*
164 * XXX: As Artec just 'forgot' to program the EEPROM on some Artec T1 devices
165 * we don't catch these faulty IDs (namely 'Cypress FX1 USB controller') that
166 * have been left on the device. If you don't have such a device but an Artec
167 * device that's supposed to work with this driver but is not detected by it,
168 * free to enable CONFIG_DVB_USB_DIBUSB_MB_FAULTY via your kernel config.
169 */
170
171#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
172/* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) },
173#endif
174
175 { } /* Terminating entry */
176};
177MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table);
178
179static struct dvb_usb_device_properties dibusb1_1_properties = {
180 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
181
182 .usb_ctrl = CYPRESS_AN2135,
183
184 .firmware = "dvb-usb-dibusb-5.0.0.11.fw",
185
186 .num_adapters = 1,
187 .adapter = {
188 {
189 .num_frontends = 1,
190 .fe = {{
191 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
192 .pid_filter_count = 16,
193
194 .streaming_ctrl = dibusb_streaming_ctrl,
195 .pid_filter = dibusb_pid_filter,
196 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
197 .frontend_attach = dibusb_dib3000mb_frontend_attach,
198 .tuner_attach = dibusb_tuner_probe_and_attach,
199
200 /* parameter for the MPEG2-data transfer */
201 .stream = {
202 .type = USB_BULK,
203 .count = 7,
204 .endpoint = 0x02,
205 .u = {
206 .bulk = {
207 .buffersize = 4096,
208 }
209 }
210 },
211 }},
212 .size_of_priv = sizeof(struct dibusb_state),
213 }
214 },
215
216 .power_ctrl = dibusb_power_ctrl,
217
218 .rc.legacy = {
219 .rc_interval = DEFAULT_RC_INTERVAL,
220 .rc_map_table = rc_map_dibusb_table,
221 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
222 .rc_query = dibusb_rc_query,
223 },
224
225 .i2c_algo = &dibusb_i2c_algo,
226
227 .generic_bulk_ctrl_endpoint = 0x01,
228
229 .num_device_descs = 9,
230 .devices = {
231 { "AVerMedia AverTV DVBT USB1.1",
232 { &dibusb_dib3000mb_table[0], NULL },
233 { &dibusb_dib3000mb_table[1], NULL },
234 },
235 { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)",
236 { &dibusb_dib3000mb_table[2], &dibusb_dib3000mb_table[4], NULL},
237 { &dibusb_dib3000mb_table[3], NULL },
238 },
239 { "DiBcom USB1.1 DVB-T reference design (MOD3000)",
240 { &dibusb_dib3000mb_table[5], NULL },
241 { &dibusb_dib3000mb_table[6], NULL },
242 },
243 { "KWorld V-Stream XPERT DTV - DVB-T USB1.1",
244 { &dibusb_dib3000mb_table[7], NULL },
245 { &dibusb_dib3000mb_table[8], NULL },
246 },
247 { "Grandtec USB1.1 DVB-T",
248 { &dibusb_dib3000mb_table[9], &dibusb_dib3000mb_table[11], NULL },
249 { &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL },
250 },
251 { "Unknown USB1.1 DVB-T device ???? please report the name to the author",
252 { &dibusb_dib3000mb_table[13], NULL },
253 { &dibusb_dib3000mb_table[14], NULL },
254 },
255 { "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device",
256 { &dibusb_dib3000mb_table[15], &dibusb_dib3000mb_table[17], NULL},
257 { &dibusb_dib3000mb_table[16], &dibusb_dib3000mb_table[18], NULL},
258 },
259 { "Artec T1 USB1.1 TVBOX with AN2135",
260 { &dibusb_dib3000mb_table[19], NULL },
261 { &dibusb_dib3000mb_table[20], NULL },
262 },
263 { "VideoWalker DVB-T USB",
264 { &dibusb_dib3000mb_table[25], NULL },
265 { &dibusb_dib3000mb_table[26], NULL },
266 },
267 }
268};
269
270static struct dvb_usb_device_properties dibusb1_1_an2235_properties = {
271 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
272 .usb_ctrl = CYPRESS_AN2235,
273
274 .firmware = "dvb-usb-dibusb-an2235-01.fw",
275
276 .num_adapters = 1,
277 .adapter = {
278 {
279 .num_frontends = 1,
280 .fe = {{
281 .caps = DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_ADAP_HAS_PID_FILTER,
282 .pid_filter_count = 16,
283
284 .streaming_ctrl = dibusb_streaming_ctrl,
285 .pid_filter = dibusb_pid_filter,
286 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
287 .frontend_attach = dibusb_dib3000mb_frontend_attach,
288 .tuner_attach = dibusb_tuner_probe_and_attach,
289
290 /* parameter for the MPEG2-data transfer */
291 .stream = {
292 .type = USB_BULK,
293 .count = 7,
294 .endpoint = 0x02,
295 .u = {
296 .bulk = {
297 .buffersize = 4096,
298 }
299 }
300 },
301 }},
302 .size_of_priv = sizeof(struct dibusb_state),
303 },
304 },
305 .power_ctrl = dibusb_power_ctrl,
306
307 .rc.legacy = {
308 .rc_interval = DEFAULT_RC_INTERVAL,
309 .rc_map_table = rc_map_dibusb_table,
310 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
311 .rc_query = dibusb_rc_query,
312 },
313
314 .i2c_algo = &dibusb_i2c_algo,
315
316 .generic_bulk_ctrl_endpoint = 0x01,
317
318#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
319 .num_device_descs = 2,
320#else
321 .num_device_descs = 1,
322#endif
323 .devices = {
324 { "Artec T1 USB1.1 TVBOX with AN2235",
325 { &dibusb_dib3000mb_table[21], NULL },
326 { &dibusb_dib3000mb_table[22], NULL },
327 },
328#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY
329 { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)",
330 { &dibusb_dib3000mb_table[30], NULL },
331 { NULL },
332 },
333 { NULL },
334#endif
335 }
336};
337
338static struct dvb_usb_device_properties dibusb2_0b_properties = {
339 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
340
341 .usb_ctrl = CYPRESS_FX2,
342
343 .firmware = "dvb-usb-adstech-usb2-02.fw",
344
345 .num_adapters = 1,
346 .adapter = {
347 {
348 .num_frontends = 1,
349 .fe = {{
350 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
351 .pid_filter_count = 16,
352
353 .streaming_ctrl = dibusb2_0_streaming_ctrl,
354 .pid_filter = dibusb_pid_filter,
355 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
356 .frontend_attach = dibusb_dib3000mb_frontend_attach,
357 .tuner_attach = dibusb_thomson_tuner_attach,
358
359 /* parameter for the MPEG2-data transfer */
360 .stream = {
361 .type = USB_BULK,
362 .count = 7,
363 .endpoint = 0x06,
364 .u = {
365 .bulk = {
366 .buffersize = 4096,
367 }
368 }
369 },
370 }},
371 .size_of_priv = sizeof(struct dibusb_state),
372 }
373 },
374 .power_ctrl = dibusb2_0_power_ctrl,
375
376 .rc.legacy = {
377 .rc_interval = DEFAULT_RC_INTERVAL,
378 .rc_map_table = rc_map_dibusb_table,
379 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
380 .rc_query = dibusb_rc_query,
381 },
382
383 .i2c_algo = &dibusb_i2c_algo,
384
385 .generic_bulk_ctrl_endpoint = 0x01,
386
387 .num_device_descs = 2,
388 .devices = {
389 { "KWorld/ADSTech Instant DVB-T USB2.0",
390 { &dibusb_dib3000mb_table[23], NULL },
391 { &dibusb_dib3000mb_table[24], NULL },
392 },
393 { "KWorld Xpert DVB-T USB2.0",
394 { &dibusb_dib3000mb_table[27], NULL },
395 { NULL }
396 },
397 { NULL },
398 }
399};
400
401static struct dvb_usb_device_properties artec_t1_usb2_properties = {
402 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
403
404 .usb_ctrl = CYPRESS_FX2,
405
406 .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
407
408 .num_adapters = 1,
409 .adapter = {
410 {
411 .num_frontends = 1,
412 .fe = {{
413 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
414 .pid_filter_count = 16,
415
416 .streaming_ctrl = dibusb2_0_streaming_ctrl,
417 .pid_filter = dibusb_pid_filter,
418 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
419 .frontend_attach = dibusb_dib3000mb_frontend_attach,
420 .tuner_attach = dibusb_tuner_probe_and_attach,
421 /* parameter for the MPEG2-data transfer */
422 .stream = {
423 .type = USB_BULK,
424 .count = 7,
425 .endpoint = 0x06,
426 .u = {
427 .bulk = {
428 .buffersize = 4096,
429 }
430 }
431 },
432 }},
433 .size_of_priv = sizeof(struct dibusb_state),
434 }
435 },
436 .power_ctrl = dibusb2_0_power_ctrl,
437
438 .rc.legacy = {
439 .rc_interval = DEFAULT_RC_INTERVAL,
440 .rc_map_table = rc_map_dibusb_table,
441 .rc_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */
442 .rc_query = dibusb_rc_query,
443 },
444
445 .i2c_algo = &dibusb_i2c_algo,
446
447 .generic_bulk_ctrl_endpoint = 0x01,
448
449 .num_device_descs = 1,
450 .devices = {
451 { "Artec T1 USB2.0",
452 { &dibusb_dib3000mb_table[28], NULL },
453 { &dibusb_dib3000mb_table[29], NULL },
454 },
455 { NULL },
456 }
457};
458
459static struct usb_driver dibusb_driver = {
460 .name = "dvb_usb_dibusb_mb",
461 .probe = dibusb_probe,
462 .disconnect = dvb_usb_device_exit,
463 .id_table = dibusb_dib3000mb_table,
464};
465
466module_usb_driver(dibusb_driver);
467
468MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
469MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)");
470MODULE_VERSION("1.0");
471MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dibusb-mc.c b/drivers/media/usb/dvb-usb/dibusb-mc.c
new file mode 100644
index 000000000000..9d1a59d09c52
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dibusb-mc.c
@@ -0,0 +1,149 @@
1/* DVB USB compliant linux driver for mobile DVB-T USB devices based on
2 * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-C/P)
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * based on GPL code from DiBcom, which has
7 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation, version 2.
12 *
13 * see Documentation/dvb/README.dvb-usb for more information
14 */
15#include "dibusb.h"
16
17DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
18
19/* USB Driver stuff */
20static struct dvb_usb_device_properties dibusb_mc_properties;
21
22static int dibusb_mc_probe(struct usb_interface *intf,
23 const struct usb_device_id *id)
24{
25 return dvb_usb_device_init(intf, &dibusb_mc_properties, THIS_MODULE,
26 NULL, adapter_nr);
27}
28
29/* do not change the order of the ID table */
30static struct usb_device_id dibusb_dib3000mc_table [] = {
31/* 00 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) },
32/* 01 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) },
33/* 02 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) },
34/* 03 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, // ( ? )
35/* 04 */ { USB_DEVICE(USB_VID_LITEON, USB_PID_LITEON_DVB_T_COLD) },
36/* 05 */ { USB_DEVICE(USB_VID_LITEON, USB_PID_LITEON_DVB_T_WARM) },
37/* 06 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_DIGIVOX_MINI_SL_COLD) },
38/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_DIGIVOX_MINI_SL_WARM) },
39/* 08 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB2_COLD) },
40/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB2_WARM) },
41/* 10 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_COLD) },
42/* 11 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_WARM) },
43/* 12 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_COLD) },
44/* 13 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_WARM) },
45/* 14 */ { USB_DEVICE(USB_VID_HUMAX_COEX, USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD) },
46/* 15 */ { USB_DEVICE(USB_VID_HUMAX_COEX, USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM) },
47 { } /* Terminating entry */
48};
49MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table);
50
51static struct dvb_usb_device_properties dibusb_mc_properties = {
52 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
53
54 .usb_ctrl = CYPRESS_FX2,
55 .firmware = "dvb-usb-dibusb-6.0.0.8.fw",
56
57 .num_adapters = 1,
58 .adapter = {
59 {
60 .num_frontends = 1,
61 .fe = {{
62 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
63 .pid_filter_count = 32,
64 .streaming_ctrl = dibusb2_0_streaming_ctrl,
65 .pid_filter = dibusb_pid_filter,
66 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
67 .frontend_attach = dibusb_dib3000mc_frontend_attach,
68 .tuner_attach = dibusb_dib3000mc_tuner_attach,
69
70 /* parameter for the MPEG2-data transfer */
71 .stream = {
72 .type = USB_BULK,
73 .count = 8,
74 .endpoint = 0x06,
75 .u = {
76 .bulk = {
77 .buffersize = 4096,
78 }
79 }
80 },
81 }},
82 .size_of_priv = sizeof(struct dibusb_state),
83 }
84 },
85 .power_ctrl = dibusb2_0_power_ctrl,
86
87 .rc.legacy = {
88 .rc_interval = DEFAULT_RC_INTERVAL,
89 .rc_map_table = rc_map_dibusb_table,
90 .rc_map_size = 111, /* FIXME */
91 .rc_query = dibusb_rc_query,
92 },
93
94 .i2c_algo = &dibusb_i2c_algo,
95
96 .generic_bulk_ctrl_endpoint = 0x01,
97
98 .num_device_descs = 8,
99 .devices = {
100 { "DiBcom USB2.0 DVB-T reference design (MOD3000P)",
101 { &dibusb_dib3000mc_table[0], NULL },
102 { &dibusb_dib3000mc_table[1], NULL },
103 },
104 { "Artec T1 USB2.0 TVBOX (please check the warm ID)",
105 { &dibusb_dib3000mc_table[2], NULL },
106 { &dibusb_dib3000mc_table[3], NULL },
107 },
108 { "LITE-ON USB2.0 DVB-T Tuner",
109 /* Also rebranded as Intuix S800, Toshiba */
110 { &dibusb_dib3000mc_table[4], NULL },
111 { &dibusb_dib3000mc_table[5], NULL },
112 },
113 { "MSI Digivox Mini SL",
114 { &dibusb_dib3000mc_table[6], NULL },
115 { &dibusb_dib3000mc_table[7], NULL },
116 },
117 { "GRAND - USB2.0 DVB-T adapter",
118 { &dibusb_dib3000mc_table[8], NULL },
119 { &dibusb_dib3000mc_table[9], NULL },
120 },
121 { "Artec T14 - USB2.0 DVB-T",
122 { &dibusb_dib3000mc_table[10], NULL },
123 { &dibusb_dib3000mc_table[11], NULL },
124 },
125 { "Leadtek - USB2.0 Winfast DTV dongle",
126 { &dibusb_dib3000mc_table[12], NULL },
127 { &dibusb_dib3000mc_table[13], NULL },
128 },
129 { "Humax/Coex DVB-T USB Stick 2.0 High Speed",
130 { &dibusb_dib3000mc_table[14], NULL },
131 { &dibusb_dib3000mc_table[15], NULL },
132 },
133 { NULL },
134 }
135};
136
137static struct usb_driver dibusb_mc_driver = {
138 .name = "dvb_usb_dibusb_mc",
139 .probe = dibusb_mc_probe,
140 .disconnect = dvb_usb_device_exit,
141 .id_table = dibusb_dib3000mc_table,
142};
143
144module_usb_driver(dibusb_mc_driver);
145
146MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
147MODULE_DESCRIPTION("Driver for DiBcom USB2.0 DVB-T (DiB3000M-C/P based) devices");
148MODULE_VERSION("1.0");
149MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dibusb.h b/drivers/media/usb/dvb-usb/dibusb.h
new file mode 100644
index 000000000000..e47c321b3ffc
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dibusb.h
@@ -0,0 +1,131 @@
1/* Header file for all dibusb-based-receivers.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation, version 2.
8 *
9 * see Documentation/dvb/README.dvb-usb for more information
10 */
11#ifndef _DVB_USB_DIBUSB_H_
12#define _DVB_USB_DIBUSB_H_
13
14#ifndef DVB_USB_LOG_PREFIX
15 #define DVB_USB_LOG_PREFIX "dibusb"
16#endif
17#include "dvb-usb.h"
18
19#include "dib3000.h"
20#include "dib3000mc.h"
21#include "mt2060.h"
22
23/*
24 * protocol of all dibusb related devices
25 */
26
27/*
28 * bulk msg to/from endpoint 0x01
29 *
30 * general structure:
31 * request_byte parameter_bytes
32 */
33
34#define DIBUSB_REQ_START_READ 0x00
35#define DIBUSB_REQ_START_DEMOD 0x01
36
37/*
38 * i2c read
39 * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word
40 * bulk read: byte_buffer (length_word bytes)
41 */
42#define DIBUSB_REQ_I2C_READ 0x02
43
44/*
45 * i2c write
46 * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes
47 */
48#define DIBUSB_REQ_I2C_WRITE 0x03
49
50/*
51 * polling the value of the remote control
52 * bulk write: 0x04
53 * bulk read: byte_buffer (5 bytes)
54 */
55#define DIBUSB_REQ_POLL_REMOTE 0x04
56
57/* additional status values for Hauppauge Remote Control Protocol */
58#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED 0x01
59#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY 0x03
60
61/* streaming mode:
62 * bulk write: 0x05 mode_byte
63 *
64 * mode_byte is mostly 0x00
65 */
66#define DIBUSB_REQ_SET_STREAMING_MODE 0x05
67
68/* interrupt the internal read loop, when blocking */
69#define DIBUSB_REQ_INTR_READ 0x06
70
71/* io control
72 * 0x07 cmd_byte param_bytes
73 *
74 * param_bytes can be up to 32 bytes
75 *
76 * cmd_byte function parameter name
77 * 0x00 power mode
78 * 0x00 sleep
79 * 0x01 wakeup
80 *
81 * 0x01 enable streaming
82 * 0x02 disable streaming
83 *
84 *
85 */
86#define DIBUSB_REQ_SET_IOCTL 0x07
87
88/* IOCTL commands */
89
90/* change the power mode in firmware */
91#define DIBUSB_IOCTL_CMD_POWER_MODE 0x00
92#define DIBUSB_IOCTL_POWER_SLEEP 0x00
93#define DIBUSB_IOCTL_POWER_WAKEUP 0x01
94
95/* modify streaming of the FX2 */
96#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01
97#define DIBUSB_IOCTL_CMD_DISABLE_STREAM 0x02
98
99struct dibusb_state {
100 struct dib_fe_xfer_ops ops;
101 int mt2060_present;
102 u8 tuner_addr;
103};
104
105struct dibusb_device_state {
106 /* for RC5 remote control */
107 int old_toggle;
108 int last_repeat_count;
109};
110
111extern struct i2c_algorithm dibusb_i2c_algo;
112
113extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *);
114extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_adapter *);
115
116extern int dibusb_streaming_ctrl(struct dvb_usb_adapter *, int);
117extern int dibusb_pid_filter(struct dvb_usb_adapter *, int, u16, int);
118extern int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *, int);
119extern int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *, int);
120
121extern int dibusb_power_ctrl(struct dvb_usb_device *, int);
122extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int);
123
124#define DEFAULT_RC_INTERVAL 150
125//#define DEFAULT_RC_INTERVAL 100000
126
127extern struct rc_map_table rc_map_dibusb_table[];
128extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *);
129extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *);
130
131#endif
diff --git a/drivers/media/usb/dvb-usb/digitv.c b/drivers/media/usb/dvb-usb/digitv.c
new file mode 100644
index 000000000000..ff34419a4c88
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/digitv.c
@@ -0,0 +1,354 @@
1/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0
2 * receiver
3 *
4 * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * partly based on the SDK published by Nebula Electronics
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#include "digitv.h"
15
16#include "mt352.h"
17#include "nxt6000.h"
18
19/* debug */
20static int dvb_usb_digitv_debug;
21module_param_named(debug,dvb_usb_digitv_debug, int, 0644);
22MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
23
24DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
25
26#define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args)
27
28static int digitv_ctrl_msg(struct dvb_usb_device *d,
29 u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
30{
31 int wo = (rbuf == NULL || rlen == 0); /* write-only */
32 u8 sndbuf[7],rcvbuf[7];
33 memset(sndbuf,0,7); memset(rcvbuf,0,7);
34
35 sndbuf[0] = cmd;
36 sndbuf[1] = vv;
37 sndbuf[2] = wo ? wlen : rlen;
38
39 if (wo) {
40 memcpy(&sndbuf[3],wbuf,wlen);
41 dvb_usb_generic_write(d,sndbuf,7);
42 } else {
43 dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10);
44 memcpy(rbuf,&rcvbuf[3],rlen);
45 }
46 return 0;
47}
48
49/* I2C */
50static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
51{
52 struct dvb_usb_device *d = i2c_get_adapdata(adap);
53 int i;
54
55 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
56 return -EAGAIN;
57
58 if (num > 2)
59 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
60
61 for (i = 0; i < num; i++) {
62 /* write/read request */
63 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
64 if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0,
65 msg[i+1].buf,msg[i+1].len) < 0)
66 break;
67 i++;
68 } else
69 if (digitv_ctrl_msg(d,USB_WRITE_COFDM, msg[i].buf[0],
70 &msg[i].buf[1],msg[i].len-1,NULL,0) < 0)
71 break;
72 }
73
74 mutex_unlock(&d->i2c_mutex);
75 return i;
76}
77
78static u32 digitv_i2c_func(struct i2c_adapter *adapter)
79{
80 return I2C_FUNC_I2C;
81}
82
83static struct i2c_algorithm digitv_i2c_algo = {
84 .master_xfer = digitv_i2c_xfer,
85 .functionality = digitv_i2c_func,
86};
87
88/* Callbacks for DVB USB */
89static int digitv_identify_state (struct usb_device *udev, struct
90 dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
91 int *cold)
92{
93 *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
94 return 0;
95}
96
97static int digitv_mt352_demod_init(struct dvb_frontend *fe)
98{
99 static u8 reset_buf[] = { 0x89, 0x38, 0x8a, 0x2d, 0x50, 0x80 };
100 static u8 init_buf[] = { 0x68, 0xa0, 0x8e, 0x40, 0x53, 0x50,
101 0x67, 0x20, 0x7d, 0x01, 0x7c, 0x00, 0x7a, 0x00,
102 0x79, 0x20, 0x57, 0x05, 0x56, 0x31, 0x88, 0x0f,
103 0x75, 0x32 };
104 int i;
105
106 for (i = 0; i < ARRAY_SIZE(reset_buf); i += 2)
107 mt352_write(fe, &reset_buf[i], 2);
108
109 msleep(1);
110
111 for (i = 0; i < ARRAY_SIZE(init_buf); i += 2)
112 mt352_write(fe, &init_buf[i], 2);
113
114 return 0;
115}
116
117static struct mt352_config digitv_mt352_config = {
118 .demod_init = digitv_mt352_demod_init,
119};
120
121static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe)
122{
123 struct dvb_usb_adapter *adap = fe->dvb->priv;
124 u8 b[5];
125
126 fe->ops.tuner_ops.calc_regs(fe, b, sizeof(b));
127 if (fe->ops.i2c_gate_ctrl)
128 fe->ops.i2c_gate_ctrl(fe, 1);
129 return digitv_ctrl_msg(adap->dev, USB_WRITE_TUNER, 0, &b[1], 4, NULL, 0);
130}
131
132static struct nxt6000_config digitv_nxt6000_config = {
133 .clock_inversion = 1,
134};
135
136static int digitv_frontend_attach(struct dvb_usb_adapter *adap)
137{
138 struct digitv_state *st = adap->dev->priv;
139
140 adap->fe_adap[0].fe = dvb_attach(mt352_attach, &digitv_mt352_config,
141 &adap->dev->i2c_adap);
142 if ((adap->fe_adap[0].fe) != NULL) {
143 st->is_nxt6000 = 0;
144 return 0;
145 }
146 adap->fe_adap[0].fe = dvb_attach(nxt6000_attach,
147 &digitv_nxt6000_config,
148 &adap->dev->i2c_adap);
149 if ((adap->fe_adap[0].fe) != NULL) {
150 st->is_nxt6000 = 1;
151 return 0;
152 }
153 return -EIO;
154}
155
156static int digitv_tuner_attach(struct dvb_usb_adapter *adap)
157{
158 struct digitv_state *st = adap->dev->priv;
159
160 if (!dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, NULL, DVB_PLL_TDED4))
161 return -ENODEV;
162
163 if (st->is_nxt6000)
164 adap->fe_adap[0].fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params;
165
166 return 0;
167}
168
169static struct rc_map_table rc_map_digitv_table[] = {
170 { 0x5f55, KEY_0 },
171 { 0x6f55, KEY_1 },
172 { 0x9f55, KEY_2 },
173 { 0xaf55, KEY_3 },
174 { 0x5f56, KEY_4 },
175 { 0x6f56, KEY_5 },
176 { 0x9f56, KEY_6 },
177 { 0xaf56, KEY_7 },
178 { 0x5f59, KEY_8 },
179 { 0x6f59, KEY_9 },
180 { 0x9f59, KEY_TV },
181 { 0xaf59, KEY_AUX },
182 { 0x5f5a, KEY_DVD },
183 { 0x6f5a, KEY_POWER },
184 { 0x9f5a, KEY_CAMERA }, /* labelled 'Picture' */
185 { 0xaf5a, KEY_AUDIO },
186 { 0x5f65, KEY_INFO },
187 { 0x6f65, KEY_F13 }, /* 16:9 */
188 { 0x9f65, KEY_F14 }, /* 14:9 */
189 { 0xaf65, KEY_EPG },
190 { 0x5f66, KEY_EXIT },
191 { 0x6f66, KEY_MENU },
192 { 0x9f66, KEY_UP },
193 { 0xaf66, KEY_DOWN },
194 { 0x5f69, KEY_LEFT },
195 { 0x6f69, KEY_RIGHT },
196 { 0x9f69, KEY_ENTER },
197 { 0xaf69, KEY_CHANNELUP },
198 { 0x5f6a, KEY_CHANNELDOWN },
199 { 0x6f6a, KEY_VOLUMEUP },
200 { 0x9f6a, KEY_VOLUMEDOWN },
201 { 0xaf6a, KEY_RED },
202 { 0x5f95, KEY_GREEN },
203 { 0x6f95, KEY_YELLOW },
204 { 0x9f95, KEY_BLUE },
205 { 0xaf95, KEY_SUBTITLE },
206 { 0x5f96, KEY_F15 }, /* AD */
207 { 0x6f96, KEY_TEXT },
208 { 0x9f96, KEY_MUTE },
209 { 0xaf96, KEY_REWIND },
210 { 0x5f99, KEY_STOP },
211 { 0x6f99, KEY_PLAY },
212 { 0x9f99, KEY_FASTFORWARD },
213 { 0xaf99, KEY_F16 }, /* chapter */
214 { 0x5f9a, KEY_PAUSE },
215 { 0x6f9a, KEY_PLAY },
216 { 0x9f9a, KEY_RECORD },
217 { 0xaf9a, KEY_F17 }, /* picture in picture */
218 { 0x5fa5, KEY_KPPLUS }, /* zoom in */
219 { 0x6fa5, KEY_KPMINUS }, /* zoom out */
220 { 0x9fa5, KEY_F18 }, /* capture */
221 { 0xafa5, KEY_F19 }, /* web */
222 { 0x5fa6, KEY_EMAIL },
223 { 0x6fa6, KEY_PHONE },
224 { 0x9fa6, KEY_PC },
225};
226
227static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
228{
229 int i;
230 u8 key[5];
231 u8 b[4] = { 0 };
232
233 *event = 0;
234 *state = REMOTE_NO_KEY_PRESSED;
235
236 digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4);
237
238 /* Tell the device we've read the remote. Not sure how necessary
239 this is, but the Nebula SDK does it. */
240 digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
241
242 /* if something is inside the buffer, simulate key press */
243 if (key[1] != 0)
244 {
245 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
246 if (rc5_custom(&d->props.rc.legacy.rc_map_table[i]) == key[1] &&
247 rc5_data(&d->props.rc.legacy.rc_map_table[i]) == key[2]) {
248 *event = d->props.rc.legacy.rc_map_table[i].keycode;
249 *state = REMOTE_KEY_PRESSED;
250 return 0;
251 }
252 }
253 }
254
255 if (key[0] != 0)
256 deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
257 return 0;
258}
259
260/* DVB USB Driver stuff */
261static struct dvb_usb_device_properties digitv_properties;
262
263static int digitv_probe(struct usb_interface *intf,
264 const struct usb_device_id *id)
265{
266 struct dvb_usb_device *d;
267 int ret = dvb_usb_device_init(intf, &digitv_properties, THIS_MODULE, &d,
268 adapter_nr);
269 if (ret == 0) {
270 u8 b[4] = { 0 };
271
272 if (d != NULL) { /* do that only when the firmware is loaded */
273 b[0] = 1;
274 digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0);
275
276 b[0] = 0;
277 digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0);
278 }
279 }
280 return ret;
281}
282
283static struct usb_device_id digitv_table [] = {
284 { USB_DEVICE(USB_VID_ANCHOR, USB_PID_NEBULA_DIGITV) },
285 { } /* Terminating entry */
286};
287MODULE_DEVICE_TABLE (usb, digitv_table);
288
289static struct dvb_usb_device_properties digitv_properties = {
290 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
291
292 .usb_ctrl = CYPRESS_FX2,
293 .firmware = "dvb-usb-digitv-02.fw",
294
295 .size_of_priv = sizeof(struct digitv_state),
296
297 .num_adapters = 1,
298 .adapter = {
299 {
300 .num_frontends = 1,
301 .fe = {{
302 .frontend_attach = digitv_frontend_attach,
303 .tuner_attach = digitv_tuner_attach,
304
305 /* parameter for the MPEG2-data transfer */
306 .stream = {
307 .type = USB_BULK,
308 .count = 7,
309 .endpoint = 0x02,
310 .u = {
311 .bulk = {
312 .buffersize = 4096,
313 }
314 }
315 },
316 }},
317 }
318 },
319 .identify_state = digitv_identify_state,
320
321 .rc.legacy = {
322 .rc_interval = 1000,
323 .rc_map_table = rc_map_digitv_table,
324 .rc_map_size = ARRAY_SIZE(rc_map_digitv_table),
325 .rc_query = digitv_rc_query,
326 },
327
328 .i2c_algo = &digitv_i2c_algo,
329
330 .generic_bulk_ctrl_endpoint = 0x01,
331
332 .num_device_descs = 1,
333 .devices = {
334 { "Nebula Electronics uDigiTV DVB-T USB2.0)",
335 { &digitv_table[0], NULL },
336 { NULL },
337 },
338 { NULL },
339 }
340};
341
342static struct usb_driver digitv_driver = {
343 .name = "dvb_usb_digitv",
344 .probe = digitv_probe,
345 .disconnect = dvb_usb_device_exit,
346 .id_table = digitv_table,
347};
348
349module_usb_driver(digitv_driver);
350
351MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
352MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0");
353MODULE_VERSION("1.0-alpha");
354MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/digitv.h b/drivers/media/usb/dvb-usb/digitv.h
new file mode 100644
index 000000000000..908c09f4966b
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/digitv.h
@@ -0,0 +1,66 @@
1#ifndef _DVB_USB_DIGITV_H_
2#define _DVB_USB_DIGITV_H_
3
4#define DVB_USB_LOG_PREFIX "digitv"
5#include "dvb-usb.h"
6
7struct digitv_state {
8 int is_nxt6000;
9};
10
11/* protocol (from usblogging and the SDK:
12 *
13 * Always 7 bytes bulk message(s) for controlling
14 *
15 * First byte describes the command. Reads are 2 consecutive transfer (as always).
16 *
17 * General structure:
18 *
19 * write or first message of a read:
20 * <cmdbyte> VV <len> B0 B1 B2 B3
21 *
22 * second message of a read
23 * <cmdbyte> VV <len> R0 R1 R2 R3
24 *
25 * whereas 0 < len <= 4
26 *
27 * I2C address is stored somewhere inside the device.
28 *
29 * 0x01 read from EEPROM
30 * VV = offset; B* = 0; R* = value(s)
31 *
32 * 0x02 read register of the COFDM
33 * VV = register; B* = 0; R* = value(s)
34 *
35 * 0x05 write register of the COFDM
36 * VV = register; B* = value(s);
37 *
38 * 0x06 write to the tuner (only for NXT6000)
39 * VV = 0; B* = PLL data; len = 4;
40 *
41 * 0x03 read remote control
42 * VV = 0; B* = 0; len = 4; R* = key
43 *
44 * 0x07 write to the remote (don't know why one should this, resetting ?)
45 * VV = 0; B* = key; len = 4;
46 *
47 * 0x08 write remote type
48 * VV = 0; B[0] = 0x01, len = 4
49 *
50 * 0x09 write device init
51 * TODO
52 */
53#define USB_READ_EEPROM 1
54
55#define USB_READ_COFDM 2
56#define USB_WRITE_COFDM 5
57
58#define USB_WRITE_TUNER 6
59
60#define USB_READ_REMOTE 3
61#define USB_WRITE_REMOTE 7
62#define USB_WRITE_REMOTE_TYPE 8
63
64#define USB_DEV_INIT 9
65
66#endif
diff --git a/drivers/media/usb/dvb-usb/dtt200u-fe.c b/drivers/media/usb/dvb-usb/dtt200u-fe.c
new file mode 100644
index 000000000000..3d81daa49172
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dtt200u-fe.c
@@ -0,0 +1,210 @@
1/* Frontend part of the Linux driver for the WideView/ Yakumo/ Hama/
2 * Typhoon/ Yuan DVB-T USB2.0 receiver.
3 *
4 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "dtt200u.h"
13
14struct dtt200u_fe_state {
15 struct dvb_usb_device *d;
16
17 fe_status_t stat;
18
19 struct dtv_frontend_properties fep;
20 struct dvb_frontend frontend;
21};
22
23static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat)
24{
25 struct dtt200u_fe_state *state = fe->demodulator_priv;
26 u8 st = GET_TUNE_STATUS, b[3];
27
28 dvb_usb_generic_rw(state->d,&st,1,b,3,0);
29
30 switch (b[0]) {
31 case 0x01:
32 *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER |
33 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
34 break;
35 case 0x00: /* pending */
36 *stat = FE_TIMEDOUT; /* during set_frontend */
37 break;
38 default:
39 case 0x02: /* failed */
40 *stat = 0;
41 break;
42 }
43 return 0;
44}
45
46static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
47{
48 struct dtt200u_fe_state *state = fe->demodulator_priv;
49 u8 bw = GET_VIT_ERR_CNT,b[3];
50 dvb_usb_generic_rw(state->d,&bw,1,b,3,0);
51 *ber = (b[0] << 16) | (b[1] << 8) | b[2];
52 return 0;
53}
54
55static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
56{
57 struct dtt200u_fe_state *state = fe->demodulator_priv;
58 u8 bw = GET_RS_UNCOR_BLK_CNT,b[2];
59
60 dvb_usb_generic_rw(state->d,&bw,1,b,2,0);
61 *unc = (b[0] << 8) | b[1];
62 return 0;
63}
64
65static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
66{
67 struct dtt200u_fe_state *state = fe->demodulator_priv;
68 u8 bw = GET_AGC, b;
69 dvb_usb_generic_rw(state->d,&bw,1,&b,1,0);
70 *strength = (b << 8) | b;
71 return 0;
72}
73
74static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
75{
76 struct dtt200u_fe_state *state = fe->demodulator_priv;
77 u8 bw = GET_SNR,br;
78 dvb_usb_generic_rw(state->d,&bw,1,&br,1,0);
79 *snr = ~((br << 8) | br);
80 return 0;
81}
82
83static int dtt200u_fe_init(struct dvb_frontend* fe)
84{
85 struct dtt200u_fe_state *state = fe->demodulator_priv;
86 u8 b = SET_INIT;
87 return dvb_usb_generic_write(state->d,&b,1);
88}
89
90static int dtt200u_fe_sleep(struct dvb_frontend* fe)
91{
92 return dtt200u_fe_init(fe);
93}
94
95static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
96{
97 tune->min_delay_ms = 1500;
98 tune->step_size = 0;
99 tune->max_drift = 0;
100 return 0;
101}
102
103static int dtt200u_fe_set_frontend(struct dvb_frontend *fe)
104{
105 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
106 struct dtt200u_fe_state *state = fe->demodulator_priv;
107 int i;
108 fe_status_t st;
109 u16 freq = fep->frequency / 250000;
110 u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 };
111
112 switch (fep->bandwidth_hz) {
113 case 8000000:
114 bwbuf[1] = 8;
115 break;
116 case 7000000:
117 bwbuf[1] = 7;
118 break;
119 case 6000000:
120 bwbuf[1] = 6;
121 break;
122 default:
123 return -EINVAL;
124 }
125
126 dvb_usb_generic_write(state->d,bwbuf,2);
127
128 freqbuf[1] = freq & 0xff;
129 freqbuf[2] = (freq >> 8) & 0xff;
130 dvb_usb_generic_write(state->d,freqbuf,3);
131
132 for (i = 0; i < 30; i++) {
133 msleep(20);
134 dtt200u_fe_read_status(fe, &st);
135 if (st & FE_TIMEDOUT)
136 continue;
137 }
138
139 return 0;
140}
141
142static int dtt200u_fe_get_frontend(struct dvb_frontend* fe)
143{
144 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
145 struct dtt200u_fe_state *state = fe->demodulator_priv;
146 memcpy(fep, &state->fep, sizeof(struct dtv_frontend_properties));
147 return 0;
148}
149
150static void dtt200u_fe_release(struct dvb_frontend* fe)
151{
152 struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv;
153 kfree(state);
154}
155
156static struct dvb_frontend_ops dtt200u_fe_ops;
157
158struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d)
159{
160 struct dtt200u_fe_state* state = NULL;
161
162 /* allocate memory for the internal state */
163 state = kzalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL);
164 if (state == NULL)
165 goto error;
166
167 deb_info("attaching frontend dtt200u\n");
168
169 state->d = d;
170
171 memcpy(&state->frontend.ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops));
172 state->frontend.demodulator_priv = state;
173
174 return &state->frontend;
175error:
176 return NULL;
177}
178
179static struct dvb_frontend_ops dtt200u_fe_ops = {
180 .delsys = { SYS_DVBT },
181 .info = {
182 .name = "WideView USB DVB-T",
183 .frequency_min = 44250000,
184 .frequency_max = 867250000,
185 .frequency_stepsize = 250000,
186 .caps = FE_CAN_INVERSION_AUTO |
187 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
188 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
189 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
190 FE_CAN_TRANSMISSION_MODE_AUTO |
191 FE_CAN_GUARD_INTERVAL_AUTO |
192 FE_CAN_RECOVER |
193 FE_CAN_HIERARCHY_AUTO,
194 },
195
196 .release = dtt200u_fe_release,
197
198 .init = dtt200u_fe_init,
199 .sleep = dtt200u_fe_sleep,
200
201 .set_frontend = dtt200u_fe_set_frontend,
202 .get_frontend = dtt200u_fe_get_frontend,
203 .get_tune_settings = dtt200u_fe_get_tune_settings,
204
205 .read_status = dtt200u_fe_read_status,
206 .read_ber = dtt200u_fe_read_ber,
207 .read_signal_strength = dtt200u_fe_read_signal_strength,
208 .read_snr = dtt200u_fe_read_snr,
209 .read_ucblocks = dtt200u_fe_read_unc_blocks,
210};
diff --git a/drivers/media/usb/dvb-usb/dtt200u.c b/drivers/media/usb/dvb-usb/dtt200u.c
new file mode 100644
index 000000000000..66f205c112b2
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dtt200u.c
@@ -0,0 +1,368 @@
1/* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/
2 * Typhoon/ Yuan/ Miglia DVB-T USB2.0 receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to Steve Chang from WideView for providing support for the WT-220U.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#include "dtt200u.h"
15
16/* debug */
17int dvb_usb_dtt200u_debug;
18module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644);
19MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS);
20
21DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
22
23static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff)
24{
25 u8 b = SET_INIT;
26
27 if (onoff)
28 dvb_usb_generic_write(d,&b,2);
29
30 return 0;
31}
32
33static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
34{
35 u8 b_streaming[2] = { SET_STREAMING, onoff };
36 u8 b_rst_pid = RESET_PID_FILTER;
37
38 dvb_usb_generic_write(adap->dev, b_streaming, 2);
39
40 if (onoff == 0)
41 dvb_usb_generic_write(adap->dev, &b_rst_pid, 1);
42 return 0;
43}
44
45static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
46{
47 u8 b_pid[4];
48 pid = onoff ? pid : 0;
49
50 b_pid[0] = SET_PID_FILTER;
51 b_pid[1] = index;
52 b_pid[2] = pid & 0xff;
53 b_pid[3] = (pid >> 8) & 0x1f;
54
55 return dvb_usb_generic_write(adap->dev, b_pid, 4);
56}
57
58/* remote control */
59/* key list for the tiny remote control (Yakumo, don't know about the others) */
60static struct rc_map_table rc_map_dtt200u_table[] = {
61 { 0x8001, KEY_MUTE },
62 { 0x8002, KEY_CHANNELDOWN },
63 { 0x8003, KEY_VOLUMEDOWN },
64 { 0x8004, KEY_1 },
65 { 0x8005, KEY_2 },
66 { 0x8006, KEY_3 },
67 { 0x8007, KEY_4 },
68 { 0x8008, KEY_5 },
69 { 0x8009, KEY_6 },
70 { 0x800a, KEY_7 },
71 { 0x800c, KEY_ZOOM },
72 { 0x800d, KEY_0 },
73 { 0x800e, KEY_SELECT },
74 { 0x8012, KEY_POWER },
75 { 0x801a, KEY_CHANNELUP },
76 { 0x801b, KEY_8 },
77 { 0x801e, KEY_VOLUMEUP },
78 { 0x801f, KEY_9 },
79};
80
81static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
82{
83 u8 key[5],cmd = GET_RC_CODE;
84 dvb_usb_generic_rw(d,&cmd,1,key,5,0);
85 dvb_usb_nec_rc_key_to_event(d,key,event,state);
86 if (key[0] != 0)
87 deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
88 return 0;
89}
90
91static int dtt200u_frontend_attach(struct dvb_usb_adapter *adap)
92{
93 adap->fe_adap[0].fe = dtt200u_fe_attach(adap->dev);
94 return 0;
95}
96
97static struct dvb_usb_device_properties dtt200u_properties;
98static struct dvb_usb_device_properties wt220u_fc_properties;
99static struct dvb_usb_device_properties wt220u_properties;
100static struct dvb_usb_device_properties wt220u_zl0353_properties;
101static struct dvb_usb_device_properties wt220u_miglia_properties;
102
103static int dtt200u_usb_probe(struct usb_interface *intf,
104 const struct usb_device_id *id)
105{
106 if (0 == dvb_usb_device_init(intf, &dtt200u_properties,
107 THIS_MODULE, NULL, adapter_nr) ||
108 0 == dvb_usb_device_init(intf, &wt220u_properties,
109 THIS_MODULE, NULL, adapter_nr) ||
110 0 == dvb_usb_device_init(intf, &wt220u_fc_properties,
111 THIS_MODULE, NULL, adapter_nr) ||
112 0 == dvb_usb_device_init(intf, &wt220u_zl0353_properties,
113 THIS_MODULE, NULL, adapter_nr) ||
114 0 == dvb_usb_device_init(intf, &wt220u_miglia_properties,
115 THIS_MODULE, NULL, adapter_nr))
116 return 0;
117
118 return -ENODEV;
119}
120
121static struct usb_device_id dtt200u_usb_table [] = {
122 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) },
123 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) },
124 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) },
125 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) },
126 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_COLD) },
127 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_WARM) },
128 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_COLD) },
129 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_WARM) },
130 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZAP250_COLD) },
131 { USB_DEVICE(USB_VID_MIGLIA, USB_PID_WT220U_ZAP250_COLD) },
132 { 0 },
133};
134MODULE_DEVICE_TABLE(usb, dtt200u_usb_table);
135
136static struct dvb_usb_device_properties dtt200u_properties = {
137 .usb_ctrl = CYPRESS_FX2,
138 .firmware = "dvb-usb-dtt200u-01.fw",
139
140 .num_adapters = 1,
141 .adapter = {
142 {
143 .num_frontends = 1,
144 .fe = {{
145 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
146 .pid_filter_count = 15,
147
148 .streaming_ctrl = dtt200u_streaming_ctrl,
149 .pid_filter = dtt200u_pid_filter,
150 .frontend_attach = dtt200u_frontend_attach,
151 /* parameter for the MPEG2-data transfer */
152 .stream = {
153 .type = USB_BULK,
154 .count = 7,
155 .endpoint = 0x02,
156 .u = {
157 .bulk = {
158 .buffersize = 4096,
159 }
160 }
161 },
162 }},
163 }
164 },
165 .power_ctrl = dtt200u_power_ctrl,
166
167 .rc.legacy = {
168 .rc_interval = 300,
169 .rc_map_table = rc_map_dtt200u_table,
170 .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
171 .rc_query = dtt200u_rc_query,
172 },
173
174 .generic_bulk_ctrl_endpoint = 0x01,
175
176 .num_device_descs = 1,
177 .devices = {
178 { .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)",
179 .cold_ids = { &dtt200u_usb_table[0], NULL },
180 .warm_ids = { &dtt200u_usb_table[1], NULL },
181 },
182 { NULL },
183 }
184};
185
186static struct dvb_usb_device_properties wt220u_properties = {
187 .usb_ctrl = CYPRESS_FX2,
188 .firmware = "dvb-usb-wt220u-02.fw",
189
190 .num_adapters = 1,
191 .adapter = {
192 {
193 .num_frontends = 1,
194 .fe = {{
195 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
196 .pid_filter_count = 15,
197
198 .streaming_ctrl = dtt200u_streaming_ctrl,
199 .pid_filter = dtt200u_pid_filter,
200 .frontend_attach = dtt200u_frontend_attach,
201 /* parameter for the MPEG2-data transfer */
202 .stream = {
203 .type = USB_BULK,
204 .count = 7,
205 .endpoint = 0x02,
206 .u = {
207 .bulk = {
208 .buffersize = 4096,
209 }
210 }
211 },
212 }},
213 }
214 },
215 .power_ctrl = dtt200u_power_ctrl,
216
217 .rc.legacy = {
218 .rc_interval = 300,
219 .rc_map_table = rc_map_dtt200u_table,
220 .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
221 .rc_query = dtt200u_rc_query,
222 },
223
224 .generic_bulk_ctrl_endpoint = 0x01,
225
226 .num_device_descs = 1,
227 .devices = {
228 { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
229 .cold_ids = { &dtt200u_usb_table[2], &dtt200u_usb_table[8], NULL },
230 .warm_ids = { &dtt200u_usb_table[3], NULL },
231 },
232 { NULL },
233 }
234};
235
236static struct dvb_usb_device_properties wt220u_fc_properties = {
237 .usb_ctrl = CYPRESS_FX2,
238 .firmware = "dvb-usb-wt220u-fc03.fw",
239
240 .num_adapters = 1,
241 .adapter = {
242 {
243 .num_frontends = 1,
244 .fe = {{
245 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
246 .pid_filter_count = 15,
247
248 .streaming_ctrl = dtt200u_streaming_ctrl,
249 .pid_filter = dtt200u_pid_filter,
250 .frontend_attach = dtt200u_frontend_attach,
251 /* parameter for the MPEG2-data transfer */
252 .stream = {
253 .type = USB_BULK,
254 .count = 7,
255 .endpoint = 0x06,
256 .u = {
257 .bulk = {
258 .buffersize = 4096,
259 }
260 }
261 },
262 }},
263 }
264 },
265 .power_ctrl = dtt200u_power_ctrl,
266
267 .rc.legacy = {
268 .rc_interval = 300,
269 .rc_map_table = rc_map_dtt200u_table,
270 .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
271 .rc_query = dtt200u_rc_query,
272 },
273
274 .generic_bulk_ctrl_endpoint = 0x01,
275
276 .num_device_descs = 1,
277 .devices = {
278 { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)",
279 .cold_ids = { &dtt200u_usb_table[6], NULL },
280 .warm_ids = { &dtt200u_usb_table[7], NULL },
281 },
282 { NULL },
283 }
284};
285
286static struct dvb_usb_device_properties wt220u_zl0353_properties = {
287 .usb_ctrl = CYPRESS_FX2,
288 .firmware = "dvb-usb-wt220u-zl0353-01.fw",
289
290 .num_adapters = 1,
291 .adapter = {
292 {
293 .num_frontends = 1,
294 .fe = {{
295 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING,
296 .pid_filter_count = 15,
297
298 .streaming_ctrl = dtt200u_streaming_ctrl,
299 .pid_filter = dtt200u_pid_filter,
300 .frontend_attach = dtt200u_frontend_attach,
301 /* parameter for the MPEG2-data transfer */
302 .stream = {
303 .type = USB_BULK,
304 .count = 7,
305 .endpoint = 0x02,
306 .u = {
307 .bulk = {
308 .buffersize = 4096,
309 }
310 }
311 },
312 }},
313 }
314 },
315 .power_ctrl = dtt200u_power_ctrl,
316
317 .rc.legacy = {
318 .rc_interval = 300,
319 .rc_map_table = rc_map_dtt200u_table,
320 .rc_map_size = ARRAY_SIZE(rc_map_dtt200u_table),
321 .rc_query = dtt200u_rc_query,
322 },
323
324 .generic_bulk_ctrl_endpoint = 0x01,
325
326 .num_device_descs = 1,
327 .devices = {
328 { .name = "WideView WT-220U PenType Receiver (based on ZL353)",
329 .cold_ids = { &dtt200u_usb_table[4], NULL },
330 .warm_ids = { &dtt200u_usb_table[5], NULL },
331 },
332 { NULL },
333 }
334};
335
336static struct dvb_usb_device_properties wt220u_miglia_properties = {
337 .usb_ctrl = CYPRESS_FX2,
338 .firmware = "dvb-usb-wt220u-miglia-01.fw",
339
340 .num_adapters = 1,
341 .generic_bulk_ctrl_endpoint = 0x01,
342
343 .num_device_descs = 1,
344 .devices = {
345 { .name = "WideView WT-220U PenType Receiver (Miglia)",
346 .cold_ids = { &dtt200u_usb_table[9], NULL },
347 /* This device turns into WT220U_ZL0353_WARM when fw
348 has been uploaded */
349 .warm_ids = { NULL },
350 },
351 { NULL },
352 }
353};
354
355/* usb specific object needed to register this driver with the usb subsystem */
356static struct usb_driver dtt200u_usb_driver = {
357 .name = "dvb_usb_dtt200u",
358 .probe = dtt200u_usb_probe,
359 .disconnect = dvb_usb_device_exit,
360 .id_table = dtt200u_usb_table,
361};
362
363module_usb_driver(dtt200u_usb_driver);
364
365MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
366MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D/Miglia DVB-T USB2.0 devices");
367MODULE_VERSION("1.0");
368MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dtt200u.h b/drivers/media/usb/dvb-usb/dtt200u.h
new file mode 100644
index 000000000000..005b0a7df358
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dtt200u.h
@@ -0,0 +1,57 @@
1/* Common header file of Linux driver for the WideView/ Yakumo/ Hama/
2 * Typhoon/ Yuan DVB-T USB2.0 receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#ifndef _DVB_USB_DTT200U_H_
13#define _DVB_USB_DTT200U_H_
14
15#define DVB_USB_LOG_PREFIX "dtt200u"
16
17#include "dvb-usb.h"
18
19extern int dvb_usb_dtt200u_debug;
20#define deb_info(args...) dprintk(dvb_usb_dtt200u_debug,0x01,args)
21#define deb_xfer(args...) dprintk(dvb_usb_dtt200u_debug,0x02,args)
22
23/* guessed protocol description (reverse engineered):
24 * read
25 * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1
26 * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal)
27 */
28
29#define GET_SPEED 0x00
30#define GET_TUNE_STATUS 0x81
31#define GET_RC_CODE 0x84
32#define GET_CONFIGURATION 0x88
33#define GET_AGC 0x89
34#define GET_SNR 0x8a
35#define GET_VIT_ERR_CNT 0x8c
36#define GET_RS_ERR_CNT 0x8d
37#define GET_RS_UNCOR_BLK_CNT 0x8e
38
39/* write
40 * 01 - init
41 * 02 - frequency (divided by 250000)
42 * 03 - bandwidth
43 * 04 - pid table (index pid(7:0) pid(12:8))
44 * 05 - reset the pid table
45 * 08 - transfer switch
46 */
47
48#define SET_INIT 0x01
49#define SET_RF_FREQ 0x02
50#define SET_BANDWIDTH 0x03
51#define SET_PID_FILTER 0x04
52#define RESET_PID_FILTER 0x05
53#define SET_STREAMING 0x08
54
55extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d);
56
57#endif
diff --git a/drivers/media/usb/dvb-usb/dtv5100.c b/drivers/media/usb/dvb-usb/dtv5100.c
new file mode 100644
index 000000000000..3d11df41cac0
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dtv5100.c
@@ -0,0 +1,224 @@
1/*
2 * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
3 *
4 * Copyright (C) 2008 Antoine Jacquet <royale@zerezo.com>
5 * http://royale.zerezo.com/dtv5100/
6 *
7 * Inspired by gl861.c and au6610.c drivers
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include "dtv5100.h"
25#include "zl10353.h"
26#include "qt1010.h"
27
28/* debug */
29static int dvb_usb_dtv5100_debug;
30module_param_named(debug, dvb_usb_dtv5100_debug, int, 0644);
31MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
32DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
33
34static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr,
35 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
36{
37 u8 request;
38 u8 type;
39 u16 value;
40 u16 index;
41
42 switch (wlen) {
43 case 1:
44 /* write { reg }, read { value } */
45 request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ :
46 DTV5100_TUNER_READ);
47 type = USB_TYPE_VENDOR | USB_DIR_IN;
48 value = 0;
49 break;
50 case 2:
51 /* write { reg, value } */
52 request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE :
53 DTV5100_TUNER_WRITE);
54 type = USB_TYPE_VENDOR | USB_DIR_OUT;
55 value = wbuf[1];
56 break;
57 default:
58 warn("wlen = %x, aborting.", wlen);
59 return -EINVAL;
60 }
61 index = (addr << 8) + wbuf[0];
62
63 msleep(1); /* avoid I2C errors */
64 return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request,
65 type, value, index, rbuf, rlen,
66 DTV5100_USB_TIMEOUT);
67}
68
69/* I2C */
70static int dtv5100_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
71 int num)
72{
73 struct dvb_usb_device *d = i2c_get_adapdata(adap);
74 int i;
75
76 if (num > 2)
77 return -EINVAL;
78
79 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
80 return -EAGAIN;
81
82 for (i = 0; i < num; i++) {
83 /* write/read request */
84 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
85 if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
86 msg[i].len, msg[i+1].buf,
87 msg[i+1].len) < 0)
88 break;
89 i++;
90 } else if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf,
91 msg[i].len, NULL, 0) < 0)
92 break;
93 }
94
95 mutex_unlock(&d->i2c_mutex);
96 return i;
97}
98
99static u32 dtv5100_i2c_func(struct i2c_adapter *adapter)
100{
101 return I2C_FUNC_I2C;
102}
103
104static struct i2c_algorithm dtv5100_i2c_algo = {
105 .master_xfer = dtv5100_i2c_xfer,
106 .functionality = dtv5100_i2c_func,
107};
108
109/* Callbacks for DVB USB */
110static struct zl10353_config dtv5100_zl10353_config = {
111 .demod_address = DTV5100_DEMOD_ADDR,
112 .no_tuner = 1,
113 .parallel_ts = 1,
114};
115
116static int dtv5100_frontend_attach(struct dvb_usb_adapter *adap)
117{
118 adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config,
119 &adap->dev->i2c_adap);
120 if (adap->fe_adap[0].fe == NULL)
121 return -EIO;
122
123 /* disable i2c gate, or it won't work... is this safe? */
124 adap->fe_adap[0].fe->ops.i2c_gate_ctrl = NULL;
125
126 return 0;
127}
128
129static struct qt1010_config dtv5100_qt1010_config = {
130 .i2c_address = DTV5100_TUNER_ADDR
131};
132
133static int dtv5100_tuner_attach(struct dvb_usb_adapter *adap)
134{
135 return dvb_attach(qt1010_attach,
136 adap->fe_adap[0].fe, &adap->dev->i2c_adap,
137 &dtv5100_qt1010_config) == NULL ? -ENODEV : 0;
138}
139
140/* DVB USB Driver stuff */
141static struct dvb_usb_device_properties dtv5100_properties;
142
143static int dtv5100_probe(struct usb_interface *intf,
144 const struct usb_device_id *id)
145{
146 int i, ret;
147 struct usb_device *udev = interface_to_usbdev(intf);
148
149 /* initialize non qt1010/zl10353 part? */
150 for (i = 0; dtv5100_init[i].request; i++) {
151 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
152 dtv5100_init[i].request,
153 USB_TYPE_VENDOR | USB_DIR_OUT,
154 dtv5100_init[i].value,
155 dtv5100_init[i].index, NULL, 0,
156 DTV5100_USB_TIMEOUT);
157 if (ret)
158 return ret;
159 }
160
161 ret = dvb_usb_device_init(intf, &dtv5100_properties,
162 THIS_MODULE, NULL, adapter_nr);
163 if (ret)
164 return ret;
165
166 return 0;
167}
168
169static struct usb_device_id dtv5100_table[] = {
170 { USB_DEVICE(0x06be, 0xa232) },
171 { } /* Terminating entry */
172};
173MODULE_DEVICE_TABLE(usb, dtv5100_table);
174
175static struct dvb_usb_device_properties dtv5100_properties = {
176 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
177 .usb_ctrl = DEVICE_SPECIFIC,
178
179 .size_of_priv = 0,
180
181 .num_adapters = 1,
182 .adapter = {{
183 .num_frontends = 1,
184 .fe = {{
185 .frontend_attach = dtv5100_frontend_attach,
186 .tuner_attach = dtv5100_tuner_attach,
187
188 .stream = {
189 .type = USB_BULK,
190 .count = 8,
191 .endpoint = 0x82,
192 .u = {
193 .bulk = {
194 .buffersize = 4096,
195 }
196 }
197 },
198 }},
199 } },
200
201 .i2c_algo = &dtv5100_i2c_algo,
202
203 .num_device_descs = 1,
204 .devices = {
205 {
206 .name = "AME DTV-5100 USB2.0 DVB-T",
207 .cold_ids = { NULL },
208 .warm_ids = { &dtv5100_table[0], NULL },
209 },
210 }
211};
212
213static struct usb_driver dtv5100_driver = {
214 .name = "dvb_usb_dtv5100",
215 .probe = dtv5100_probe,
216 .disconnect = dvb_usb_device_exit,
217 .id_table = dtv5100_table,
218};
219
220module_usb_driver(dtv5100_driver);
221
222MODULE_AUTHOR(DRIVER_AUTHOR);
223MODULE_DESCRIPTION(DRIVER_DESC);
224MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dtv5100.h b/drivers/media/usb/dvb-usb/dtv5100.h
new file mode 100644
index 000000000000..93e96e04a82a
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dtv5100.h
@@ -0,0 +1,51 @@
1/*
2 * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T
3 *
4 * Copyright (C) 2008 Antoine Jacquet <royale@zerezo.com>
5 * http://royale.zerezo.com/dtv5100/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#ifndef _DVB_USB_DTV5100_H_
23#define _DVB_USB_DTV5100_H_
24
25#define DVB_USB_LOG_PREFIX "dtv5100"
26#include "dvb-usb.h"
27
28#define DTV5100_USB_TIMEOUT 500
29
30#define DTV5100_DEMOD_ADDR 0x00
31#define DTV5100_DEMOD_WRITE 0xc0
32#define DTV5100_DEMOD_READ 0xc1
33
34#define DTV5100_TUNER_ADDR 0xc4
35#define DTV5100_TUNER_WRITE 0xc7
36#define DTV5100_TUNER_READ 0xc8
37
38#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/"
39#define DRIVER_DESC "AME DTV-5100 USB2.0 DVB-T"
40
41static struct {
42 u8 request;
43 u8 value;
44 u16 index;
45} dtv5100_init[] = {
46 { 0x000000c5, 0x00000000, 0x00000001 },
47 { 0x000000c5, 0x00000001, 0x00000001 },
48 { } /* Terminating entry */
49};
50
51#endif
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-common.h b/drivers/media/usb/dvb-usb/dvb-usb-common.h
new file mode 100644
index 000000000000..6b7b2a89242e
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb-usb-common.h
@@ -0,0 +1,52 @@
1/* dvb-usb-common.h is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * a header file containing prototypes and types for internal use of the dvb-usb-lib
7 */
8#ifndef _DVB_USB_COMMON_H_
9#define _DVB_USB_COMMON_H_
10
11#define DVB_USB_LOG_PREFIX "dvb-usb"
12#include "dvb-usb.h"
13
14extern int dvb_usb_debug;
15extern int dvb_usb_disable_rc_polling;
16
17#define deb_info(args...) dprintk(dvb_usb_debug,0x001,args)
18#define deb_xfer(args...) dprintk(dvb_usb_debug,0x002,args)
19#define deb_pll(args...) dprintk(dvb_usb_debug,0x004,args)
20#define deb_ts(args...) dprintk(dvb_usb_debug,0x008,args)
21#define deb_err(args...) dprintk(dvb_usb_debug,0x010,args)
22#define deb_rc(args...) dprintk(dvb_usb_debug,0x020,args)
23#define deb_fw(args...) dprintk(dvb_usb_debug,0x040,args)
24#define deb_mem(args...) dprintk(dvb_usb_debug,0x080,args)
25#define deb_uxfer(args...) dprintk(dvb_usb_debug,0x100,args)
26
27/* commonly used methods */
28extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_device_properties *);
29
30extern int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff);
31
32extern int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props);
33extern int usb_urb_exit(struct usb_data_stream *stream);
34extern int usb_urb_submit(struct usb_data_stream *stream);
35extern int usb_urb_kill(struct usb_data_stream *stream);
36
37extern int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap);
38extern int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap);
39
40extern int dvb_usb_i2c_init(struct dvb_usb_device *);
41extern int dvb_usb_i2c_exit(struct dvb_usb_device *);
42
43extern int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap,
44 short *adapter_nums);
45extern int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap);
46extern int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap);
47extern int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap);
48
49extern int dvb_usb_remote_init(struct dvb_usb_device *);
50extern int dvb_usb_remote_exit(struct dvb_usb_device *);
51
52#endif
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c
new file mode 100644
index 000000000000..719413b15f20
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c
@@ -0,0 +1,288 @@
1/* dvb-usb-dvb.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for initializing and handling the
7 * linux-dvb API.
8 */
9#include "dvb-usb-common.h"
10
11/* does the complete input transfer handling */
12static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
13{
14 struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
15 int newfeedcount, ret;
16
17 if (adap == NULL)
18 return -ENODEV;
19
20 if ((adap->active_fe < 0) ||
21 (adap->active_fe >= adap->num_frontends_initialized)) {
22 return -EINVAL;
23 }
24
25 newfeedcount = adap->feedcount + (onoff ? 1 : -1);
26
27 /* stop feed before setting a new pid if there will be no pid anymore */
28 if (newfeedcount == 0) {
29 deb_ts("stop feeding\n");
30 usb_urb_kill(&adap->fe_adap[adap->active_fe].stream);
31
32 if (adap->props.fe[adap->active_fe].streaming_ctrl != NULL) {
33 ret = adap->props.fe[adap->active_fe].streaming_ctrl(adap, 0);
34 if (ret < 0) {
35 err("error while stopping stream.");
36 return ret;
37 }
38 }
39 }
40
41 adap->feedcount = newfeedcount;
42
43 /* activate the pid on the device specific pid_filter */
44 deb_ts("setting pid (%s): %5d %04x at index %d '%s'\n",
45 adap->fe_adap[adap->active_fe].pid_filtering ?
46 "yes" : "no", dvbdmxfeed->pid, dvbdmxfeed->pid,
47 dvbdmxfeed->index, onoff ? "on" : "off");
48 if (adap->props.fe[adap->active_fe].caps & DVB_USB_ADAP_HAS_PID_FILTER &&
49 adap->fe_adap[adap->active_fe].pid_filtering &&
50 adap->props.fe[adap->active_fe].pid_filter != NULL)
51 adap->props.fe[adap->active_fe].pid_filter(adap, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
52
53 /* start the feed if this was the first feed and there is still a feed
54 * for reception.
55 */
56 if (adap->feedcount == onoff && adap->feedcount > 0) {
57 deb_ts("submitting all URBs\n");
58 usb_urb_submit(&adap->fe_adap[adap->active_fe].stream);
59
60 deb_ts("controlling pid parser\n");
61 if (adap->props.fe[adap->active_fe].caps & DVB_USB_ADAP_HAS_PID_FILTER &&
62 adap->props.fe[adap->active_fe].caps &
63 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
64 adap->props.fe[adap->active_fe].pid_filter_ctrl != NULL) {
65 ret = adap->props.fe[adap->active_fe].pid_filter_ctrl(adap,
66 adap->fe_adap[adap->active_fe].pid_filtering);
67 if (ret < 0) {
68 err("could not handle pid_parser");
69 return ret;
70 }
71 }
72 deb_ts("start feeding\n");
73 if (adap->props.fe[adap->active_fe].streaming_ctrl != NULL) {
74 ret = adap->props.fe[adap->active_fe].streaming_ctrl(adap, 1);
75 if (ret < 0) {
76 err("error while enabling fifo.");
77 return ret;
78 }
79 }
80
81 }
82 return 0;
83}
84
85static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
86{
87 deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type);
88 return dvb_usb_ctrl_feed(dvbdmxfeed,1);
89}
90
91static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
92{
93 deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type);
94 return dvb_usb_ctrl_feed(dvbdmxfeed,0);
95}
96
97int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums)
98{
99 int i;
100 int ret = dvb_register_adapter(&adap->dvb_adap, adap->dev->desc->name,
101 adap->dev->owner, &adap->dev->udev->dev,
102 adapter_nums);
103
104 if (ret < 0) {
105 deb_info("dvb_register_adapter failed: error %d", ret);
106 goto err;
107 }
108 adap->dvb_adap.priv = adap;
109
110 if (adap->dev->props.read_mac_address) {
111 if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0)
112 info("MAC address: %pM",adap->dvb_adap.proposed_mac);
113 else
114 err("MAC address reading failed.");
115 }
116
117
118 adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
119 adap->demux.priv = adap;
120
121 adap->demux.filternum = 0;
122 for (i = 0; i < adap->props.num_frontends; i++) {
123 if (adap->demux.filternum < adap->fe_adap[i].max_feed_count)
124 adap->demux.filternum = adap->fe_adap[i].max_feed_count;
125 }
126 adap->demux.feednum = adap->demux.filternum;
127 adap->demux.start_feed = dvb_usb_start_feed;
128 adap->demux.stop_feed = dvb_usb_stop_feed;
129 adap->demux.write_to_decoder = NULL;
130 if ((ret = dvb_dmx_init(&adap->demux)) < 0) {
131 err("dvb_dmx_init failed: error %d",ret);
132 goto err_dmx;
133 }
134
135 adap->dmxdev.filternum = adap->demux.filternum;
136 adap->dmxdev.demux = &adap->demux.dmx;
137 adap->dmxdev.capabilities = 0;
138 if ((ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap)) < 0) {
139 err("dvb_dmxdev_init failed: error %d",ret);
140 goto err_dmx_dev;
141 }
142
143 if ((ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net,
144 &adap->demux.dmx)) < 0) {
145 err("dvb_net_init failed: error %d",ret);
146 goto err_net_init;
147 }
148
149 adap->state |= DVB_USB_ADAP_STATE_DVB;
150 return 0;
151
152err_net_init:
153 dvb_dmxdev_release(&adap->dmxdev);
154err_dmx_dev:
155 dvb_dmx_release(&adap->demux);
156err_dmx:
157 dvb_unregister_adapter(&adap->dvb_adap);
158err:
159 return ret;
160}
161
162int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap)
163{
164 if (adap->state & DVB_USB_ADAP_STATE_DVB) {
165 deb_info("unregistering DVB part\n");
166 dvb_net_release(&adap->dvb_net);
167 adap->demux.dmx.close(&adap->demux.dmx);
168 dvb_dmxdev_release(&adap->dmxdev);
169 dvb_dmx_release(&adap->demux);
170 dvb_unregister_adapter(&adap->dvb_adap);
171 adap->state &= ~DVB_USB_ADAP_STATE_DVB;
172 }
173 return 0;
174}
175
176static int dvb_usb_set_active_fe(struct dvb_frontend *fe, int onoff)
177{
178 struct dvb_usb_adapter *adap = fe->dvb->priv;
179
180 int ret = (adap->props.frontend_ctrl) ?
181 adap->props.frontend_ctrl(fe, onoff) : 0;
182
183 if (ret < 0) {
184 err("frontend_ctrl request failed");
185 return ret;
186 }
187 if (onoff)
188 adap->active_fe = fe->id;
189
190 return 0;
191}
192
193static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
194{
195 struct dvb_usb_adapter *adap = fe->dvb->priv;
196
197 dvb_usb_device_power_ctrl(adap->dev, 1);
198
199 dvb_usb_set_active_fe(fe, 1);
200
201 if (adap->fe_adap[fe->id].fe_init)
202 adap->fe_adap[fe->id].fe_init(fe);
203
204 return 0;
205}
206
207static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
208{
209 struct dvb_usb_adapter *adap = fe->dvb->priv;
210
211 if (adap->fe_adap[fe->id].fe_sleep)
212 adap->fe_adap[fe->id].fe_sleep(fe);
213
214 dvb_usb_set_active_fe(fe, 0);
215
216 return dvb_usb_device_power_ctrl(adap->dev, 0);
217}
218
219int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap)
220{
221 int ret, i;
222
223 /* register all given adapter frontends */
224 for (i = 0; i < adap->props.num_frontends; i++) {
225
226 if (adap->props.fe[i].frontend_attach == NULL) {
227 err("strange: '%s' #%d,%d "
228 "doesn't want to attach a frontend.",
229 adap->dev->desc->name, adap->id, i);
230
231 return 0;
232 }
233
234 ret = adap->props.fe[i].frontend_attach(adap);
235 if (ret || adap->fe_adap[i].fe == NULL) {
236 /* only print error when there is no FE at all */
237 if (i == 0)
238 err("no frontend was attached by '%s'",
239 adap->dev->desc->name);
240
241 return 0;
242 }
243
244 adap->fe_adap[i].fe->id = i;
245
246 /* re-assign sleep and wakeup functions */
247 adap->fe_adap[i].fe_init = adap->fe_adap[i].fe->ops.init;
248 adap->fe_adap[i].fe->ops.init = dvb_usb_fe_wakeup;
249 adap->fe_adap[i].fe_sleep = adap->fe_adap[i].fe->ops.sleep;
250 adap->fe_adap[i].fe->ops.sleep = dvb_usb_fe_sleep;
251
252 if (dvb_register_frontend(&adap->dvb_adap, adap->fe_adap[i].fe)) {
253 err("Frontend %d registration failed.", i);
254 dvb_frontend_detach(adap->fe_adap[i].fe);
255 adap->fe_adap[i].fe = NULL;
256 /* In error case, do not try register more FEs,
257 * still leaving already registered FEs alive. */
258 if (i == 0)
259 return -ENODEV;
260 else
261 return 0;
262 }
263
264 /* only attach the tuner if the demod is there */
265 if (adap->props.fe[i].tuner_attach != NULL)
266 adap->props.fe[i].tuner_attach(adap);
267
268 adap->num_frontends_initialized++;
269 }
270
271 return 0;
272}
273
274int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap)
275{
276 int i = adap->num_frontends_initialized - 1;
277
278 /* unregister all given adapter frontends */
279 for (; i >= 0; i--) {
280 if (adap->fe_adap[i].fe != NULL) {
281 dvb_unregister_frontend(adap->fe_adap[i].fe);
282 dvb_frontend_detach(adap->fe_adap[i].fe);
283 }
284 }
285 adap->num_frontends_initialized = 0;
286
287 return 0;
288}
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
new file mode 100644
index 000000000000..733a7ff7b207
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
@@ -0,0 +1,146 @@
1/* dvb-usb-firmware.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for downloading the firmware to Cypress FX 1 and 2 based devices.
7 *
8 * FIXME: This part does actually not belong to dvb-usb, but to the usb-subsystem.
9 */
10#include "dvb-usb-common.h"
11
12#include <linux/usb.h>
13
14struct usb_cypress_controller {
15 int id;
16 const char *name; /* name of the usb controller */
17 u16 cpu_cs_register; /* needs to be restarted, when the firmware has been downloaded. */
18};
19
20static struct usb_cypress_controller cypress[] = {
21 { .id = DEVICE_SPECIFIC, .name = "Device specific", .cpu_cs_register = 0 },
22 { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 },
23 { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 },
24 { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 },
25};
26
27/*
28 * load a firmware packet to the device
29 */
30static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len)
31{
32 return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
33 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
34}
35
36int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type)
37{
38 struct hexline hx;
39 u8 reset;
40 int ret,pos=0;
41
42 /* stop the CPU */
43 reset = 1;
44 if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1)
45 err("could not stop the USB controller CPU.");
46
47 while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) {
48 deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk);
49 ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len);
50
51 if (ret != hx.len) {
52 err("error while transferring firmware "
53 "(transferred size: %d, block size: %d)",
54 ret,hx.len);
55 ret = -EINVAL;
56 break;
57 }
58 }
59 if (ret < 0) {
60 err("firmware download failed at %d with %d",pos,ret);
61 return ret;
62 }
63
64 if (ret == 0) {
65 /* restart the CPU */
66 reset = 0;
67 if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) {
68 err("could not restart the USB controller CPU.");
69 ret = -EINVAL;
70 }
71 } else
72 ret = -EIO;
73
74 return ret;
75}
76EXPORT_SYMBOL(usb_cypress_load_firmware);
77
78int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_device_properties *props)
79{
80 int ret;
81 const struct firmware *fw = NULL;
82
83 if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) {
84 err("did not find the firmware file. (%s) "
85 "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
86 props->firmware,ret);
87 return ret;
88 }
89
90 info("downloading firmware from file '%s'",props->firmware);
91
92 switch (props->usb_ctrl) {
93 case CYPRESS_AN2135:
94 case CYPRESS_AN2235:
95 case CYPRESS_FX2:
96 ret = usb_cypress_load_firmware(udev, fw, props->usb_ctrl);
97 break;
98 case DEVICE_SPECIFIC:
99 if (props->download_firmware)
100 ret = props->download_firmware(udev,fw);
101 else {
102 err("BUG: driver didn't specified a download_firmware-callback, although it claims to have a DEVICE_SPECIFIC one.");
103 ret = -EINVAL;
104 }
105 break;
106 default:
107 ret = -EINVAL;
108 break;
109 }
110
111 release_firmware(fw);
112 return ret;
113}
114
115int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
116 int *pos)
117{
118 u8 *b = (u8 *) &fw->data[*pos];
119 int data_offs = 4;
120 if (*pos >= fw->size)
121 return 0;
122
123 memset(hx,0,sizeof(struct hexline));
124
125 hx->len = b[0];
126
127 if ((*pos + hx->len + 4) >= fw->size)
128 return -EINVAL;
129
130 hx->addr = b[1] | (b[2] << 8);
131 hx->type = b[3];
132
133 if (hx->type == 0x04) {
134 /* b[4] and b[5] are the Extended linear address record data field */
135 hx->addr |= (b[4] << 24) | (b[5] << 16);
136/* hx->len -= 2;
137 data_offs += 2; */
138 }
139 memcpy(hx->data,&b[data_offs],hx->len);
140 hx->chk = b[hx->len + data_offs];
141
142 *pos += hx->len + 5;
143
144 return *pos;
145}
146EXPORT_SYMBOL(dvb_usb_get_hexline);
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-i2c.c b/drivers/media/usb/dvb-usb/dvb-usb-i2c.c
new file mode 100644
index 000000000000..88e4a62abc44
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb-usb-i2c.c
@@ -0,0 +1,43 @@
1/* dvb-usb-i2c.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for (de-)initializing an I2C adapter.
7 */
8#include "dvb-usb-common.h"
9
10int dvb_usb_i2c_init(struct dvb_usb_device *d)
11{
12 int ret = 0;
13
14 if (!(d->props.caps & DVB_USB_IS_AN_I2C_ADAPTER))
15 return 0;
16
17 if (d->props.i2c_algo == NULL) {
18 err("no i2c algorithm specified");
19 return -EINVAL;
20 }
21
22 strlcpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
23 d->i2c_adap.algo = d->props.i2c_algo;
24 d->i2c_adap.algo_data = NULL;
25 d->i2c_adap.dev.parent = &d->udev->dev;
26
27 i2c_set_adapdata(&d->i2c_adap, d);
28
29 if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0)
30 err("could not add i2c adapter");
31
32 d->state |= DVB_USB_STATE_I2C;
33
34 return ret;
35}
36
37int dvb_usb_i2c_exit(struct dvb_usb_device *d)
38{
39 if (d->state & DVB_USB_STATE_I2C)
40 i2c_del_adapter(&d->i2c_adap);
41 d->state &= ~DVB_USB_STATE_I2C;
42 return 0;
43}
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c
new file mode 100644
index 000000000000..169196ec2d4e
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c
@@ -0,0 +1,304 @@
1/*
2 * DVB USB library - provides a generic interface for a DVB USB device driver.
3 *
4 * dvb-usb-init.c
5 *
6 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#include "dvb-usb-common.h"
15
16/* debug */
17int dvb_usb_debug;
18module_param_named(debug, dvb_usb_debug, int, 0644);
19MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64,mem=128,uxfer=256 (or-able))." DVB_USB_DEBUG_STATUS);
20
21int dvb_usb_disable_rc_polling;
22module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644);
23MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0).");
24
25static int dvb_usb_force_pid_filter_usage;
26module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444);
27MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID filter, if any (default: 0).");
28
29static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
30{
31 struct dvb_usb_adapter *adap;
32 int ret, n, o;
33
34 for (n = 0; n < d->props.num_adapters; n++) {
35 adap = &d->adapter[n];
36 adap->dev = d;
37 adap->id = n;
38
39 memcpy(&adap->props, &d->props.adapter[n], sizeof(struct dvb_usb_adapter_properties));
40
41 for (o = 0; o < adap->props.num_frontends; o++) {
42 struct dvb_usb_adapter_fe_properties *props = &adap->props.fe[o];
43 /* speed - when running at FULL speed we need a HW PID filter */
44 if (d->udev->speed == USB_SPEED_FULL && !(props->caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
45 err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)");
46 return -ENODEV;
47 }
48
49 if ((d->udev->speed == USB_SPEED_FULL && props->caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
50 (props->caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
51 info("will use the device's hardware PID filter (table count: %d).", props->pid_filter_count);
52 adap->fe_adap[o].pid_filtering = 1;
53 adap->fe_adap[o].max_feed_count = props->pid_filter_count;
54 } else {
55 info("will pass the complete MPEG2 transport stream to the software demuxer.");
56 adap->fe_adap[o].pid_filtering = 0;
57 adap->fe_adap[o].max_feed_count = 255;
58 }
59
60 if (!adap->fe_adap[o].pid_filtering &&
61 dvb_usb_force_pid_filter_usage &&
62 props->caps & DVB_USB_ADAP_HAS_PID_FILTER) {
63 info("pid filter enabled by module option.");
64 adap->fe_adap[o].pid_filtering = 1;
65 adap->fe_adap[o].max_feed_count = props->pid_filter_count;
66 }
67
68 if (props->size_of_priv > 0) {
69 adap->fe_adap[o].priv = kzalloc(props->size_of_priv, GFP_KERNEL);
70 if (adap->fe_adap[o].priv == NULL) {
71 err("no memory for priv for adapter %d fe %d.", n, o);
72 return -ENOMEM;
73 }
74 }
75 }
76
77 if (adap->props.size_of_priv > 0) {
78 adap->priv = kzalloc(adap->props.size_of_priv, GFP_KERNEL);
79 if (adap->priv == NULL) {
80 err("no memory for priv for adapter %d.", n);
81 return -ENOMEM;
82 }
83 }
84
85 if ((ret = dvb_usb_adapter_stream_init(adap)) ||
86 (ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) ||
87 (ret = dvb_usb_adapter_frontend_init(adap))) {
88 return ret;
89 }
90
91 /* use exclusive FE lock if there is multiple shared FEs */
92 if (adap->fe_adap[1].fe)
93 adap->dvb_adap.mfe_shared = 1;
94
95 d->num_adapters_initialized++;
96 d->state |= DVB_USB_STATE_DVB;
97 }
98
99 /*
100 * when reloading the driver w/o replugging the device
101 * sometimes a timeout occures, this helps
102 */
103 if (d->props.generic_bulk_ctrl_endpoint != 0) {
104 usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
105 usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
106 }
107
108 return 0;
109}
110
111static int dvb_usb_adapter_exit(struct dvb_usb_device *d)
112{
113 int n;
114
115 for (n = 0; n < d->num_adapters_initialized; n++) {
116 dvb_usb_adapter_frontend_exit(&d->adapter[n]);
117 dvb_usb_adapter_dvb_exit(&d->adapter[n]);
118 dvb_usb_adapter_stream_exit(&d->adapter[n]);
119 kfree(d->adapter[n].priv);
120 }
121 d->num_adapters_initialized = 0;
122 d->state &= ~DVB_USB_STATE_DVB;
123 return 0;
124}
125
126
127/* general initialization functions */
128static int dvb_usb_exit(struct dvb_usb_device *d)
129{
130 deb_info("state before exiting everything: %x\n", d->state);
131 dvb_usb_remote_exit(d);
132 dvb_usb_adapter_exit(d);
133 dvb_usb_i2c_exit(d);
134 deb_info("state should be zero now: %x\n", d->state);
135 d->state = DVB_USB_STATE_INIT;
136 kfree(d->priv);
137 kfree(d);
138 return 0;
139}
140
141static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums)
142{
143 int ret = 0;
144
145 mutex_init(&d->usb_mutex);
146 mutex_init(&d->i2c_mutex);
147
148 d->state = DVB_USB_STATE_INIT;
149
150 if (d->props.size_of_priv > 0) {
151 d->priv = kzalloc(d->props.size_of_priv, GFP_KERNEL);
152 if (d->priv == NULL) {
153 err("no memory for priv in 'struct dvb_usb_device'");
154 return -ENOMEM;
155 }
156 }
157
158 /* check the capabilities and set appropriate variables */
159 dvb_usb_device_power_ctrl(d, 1);
160
161 if ((ret = dvb_usb_i2c_init(d)) ||
162 (ret = dvb_usb_adapter_init(d, adapter_nums))) {
163 dvb_usb_exit(d);
164 return ret;
165 }
166
167 if ((ret = dvb_usb_remote_init(d)))
168 err("could not initialize remote control.");
169
170 dvb_usb_device_power_ctrl(d, 0);
171
172 return 0;
173}
174
175/* determine the name and the state of the just found USB device */
176static struct dvb_usb_device_description *dvb_usb_find_device(struct usb_device *udev, struct dvb_usb_device_properties *props, int *cold)
177{
178 int i, j;
179 struct dvb_usb_device_description *desc = NULL;
180
181 *cold = -1;
182
183 for (i = 0; i < props->num_device_descs; i++) {
184
185 for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].cold_ids[j] != NULL; j++) {
186 deb_info("check for cold %x %x\n", props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct);
187 if (props->devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
188 props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
189 *cold = 1;
190 desc = &props->devices[i];
191 break;
192 }
193 }
194
195 if (desc != NULL)
196 break;
197
198 for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].warm_ids[j] != NULL; j++) {
199 deb_info("check for warm %x %x\n", props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct);
200 if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
201 props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
202 *cold = 0;
203 desc = &props->devices[i];
204 break;
205 }
206 }
207 }
208
209 if (desc != NULL && props->identify_state != NULL)
210 props->identify_state(udev, props, &desc, cold);
211
212 return desc;
213}
214
215int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff)
216{
217 if (onoff)
218 d->powered++;
219 else
220 d->powered--;
221
222 if (d->powered == 0 || (onoff && d->powered == 1)) { /* when switching from 1 to 0 or from 0 to 1 */
223 deb_info("power control: %d\n", onoff);
224 if (d->props.power_ctrl)
225 return d->props.power_ctrl(d, onoff);
226 }
227 return 0;
228}
229
230/*
231 * USB
232 */
233int dvb_usb_device_init(struct usb_interface *intf,
234 struct dvb_usb_device_properties *props,
235 struct module *owner, struct dvb_usb_device **du,
236 short *adapter_nums)
237{
238 struct usb_device *udev = interface_to_usbdev(intf);
239 struct dvb_usb_device *d = NULL;
240 struct dvb_usb_device_description *desc = NULL;
241
242 int ret = -ENOMEM, cold = 0;
243
244 if (du != NULL)
245 *du = NULL;
246
247 if ((desc = dvb_usb_find_device(udev, props, &cold)) == NULL) {
248 deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n");
249 return -ENODEV;
250 }
251
252 if (cold) {
253 info("found a '%s' in cold state, will try to load a firmware", desc->name);
254 ret = dvb_usb_download_firmware(udev, props);
255 if (!props->no_reconnect || ret != 0)
256 return ret;
257 }
258
259 info("found a '%s' in warm state.", desc->name);
260 d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
261 if (d == NULL) {
262 err("no memory for 'struct dvb_usb_device'");
263 return -ENOMEM;
264 }
265
266 d->udev = udev;
267 memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties));
268 d->desc = desc;
269 d->owner = owner;
270
271 usb_set_intfdata(intf, d);
272
273 if (du != NULL)
274 *du = d;
275
276 ret = dvb_usb_init(d, adapter_nums);
277
278 if (ret == 0)
279 info("%s successfully initialized and connected.", desc->name);
280 else
281 info("%s error while loading driver (%d)", desc->name, ret);
282 return ret;
283}
284EXPORT_SYMBOL(dvb_usb_device_init);
285
286void dvb_usb_device_exit(struct usb_interface *intf)
287{
288 struct dvb_usb_device *d = usb_get_intfdata(intf);
289 const char *name = "generic DVB-USB module";
290
291 usb_set_intfdata(intf, NULL);
292 if (d != NULL && d->desc != NULL) {
293 name = d->desc->name;
294 dvb_usb_exit(d);
295 }
296 info("%s successfully deinitialized and disconnected.", name);
297
298}
299EXPORT_SYMBOL(dvb_usb_device_exit);
300
301MODULE_VERSION("1.0");
302MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
303MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices");
304MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-remote.c b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
new file mode 100644
index 000000000000..41bacff24960
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb-usb-remote.c
@@ -0,0 +1,391 @@
1/* dvb-usb-remote.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for initializing the input-device and for handling remote-control-queries.
7 */
8#include "dvb-usb-common.h"
9#include <linux/usb/input.h>
10
11static unsigned int
12legacy_dvb_usb_get_keymap_index(const struct input_keymap_entry *ke,
13 struct rc_map_table *keymap,
14 unsigned int keymap_size)
15{
16 unsigned int index;
17 unsigned int scancode;
18
19 if (ke->flags & INPUT_KEYMAP_BY_INDEX) {
20 index = ke->index;
21 } else {
22 if (input_scancode_to_scalar(ke, &scancode))
23 return keymap_size;
24
25 /* See if we can match the raw key code. */
26 for (index = 0; index < keymap_size; index++)
27 if (keymap[index].scancode == scancode)
28 break;
29
30 /* See if there is an unused hole in the map */
31 if (index >= keymap_size) {
32 for (index = 0; index < keymap_size; index++) {
33 if (keymap[index].keycode == KEY_RESERVED ||
34 keymap[index].keycode == KEY_UNKNOWN) {
35 break;
36 }
37 }
38 }
39 }
40
41 return index;
42}
43
44static int legacy_dvb_usb_getkeycode(struct input_dev *dev,
45 struct input_keymap_entry *ke)
46{
47 struct dvb_usb_device *d = input_get_drvdata(dev);
48 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
49 unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
50 unsigned int index;
51
52 index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
53 if (index >= keymap_size)
54 return -EINVAL;
55
56 ke->keycode = keymap[index].keycode;
57 if (ke->keycode == KEY_UNKNOWN)
58 ke->keycode = KEY_RESERVED;
59 ke->len = sizeof(keymap[index].scancode);
60 memcpy(&ke->scancode, &keymap[index].scancode, ke->len);
61 ke->index = index;
62
63 return 0;
64}
65
66static int legacy_dvb_usb_setkeycode(struct input_dev *dev,
67 const struct input_keymap_entry *ke,
68 unsigned int *old_keycode)
69{
70 struct dvb_usb_device *d = input_get_drvdata(dev);
71 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
72 unsigned int keymap_size = d->props.rc.legacy.rc_map_size;
73 unsigned int index;
74
75 index = legacy_dvb_usb_get_keymap_index(ke, keymap, keymap_size);
76 /*
77 * FIXME: Currently, it is not possible to increase the size of
78 * scancode table. For it to happen, one possibility
79 * would be to allocate a table with key_map_size + 1,
80 * copying data, appending the new key on it, and freeing
81 * the old one - or maybe just allocating some spare space
82 */
83 if (index >= keymap_size)
84 return -EINVAL;
85
86 *old_keycode = keymap[index].keycode;
87 keymap->keycode = ke->keycode;
88 __set_bit(ke->keycode, dev->keybit);
89
90 if (*old_keycode != KEY_RESERVED) {
91 __clear_bit(*old_keycode, dev->keybit);
92 for (index = 0; index < keymap_size; index++) {
93 if (keymap[index].keycode == *old_keycode) {
94 __set_bit(*old_keycode, dev->keybit);
95 break;
96 }
97 }
98 }
99
100 return 0;
101}
102
103/* Remote-control poll function - called every dib->rc_query_interval ms to see
104 * whether the remote control has received anything.
105 *
106 * TODO: Fix the repeat rate of the input device.
107 */
108static void legacy_dvb_usb_read_remote_control(struct work_struct *work)
109{
110 struct dvb_usb_device *d =
111 container_of(work, struct dvb_usb_device, rc_query_work.work);
112 u32 event;
113 int state;
114
115 /* TODO: need a lock here. We can simply skip checking for the remote control
116 if we're busy. */
117
118 /* when the parameter has been set to 1 via sysfs while the driver was running */
119 if (dvb_usb_disable_rc_polling)
120 return;
121
122 if (d->props.rc.legacy.rc_query(d,&event,&state)) {
123 err("error while querying for an remote control event.");
124 goto schedule;
125 }
126
127
128 switch (state) {
129 case REMOTE_NO_KEY_PRESSED:
130 break;
131 case REMOTE_KEY_PRESSED:
132 deb_rc("key pressed\n");
133 d->last_event = event;
134 case REMOTE_KEY_REPEAT:
135 deb_rc("key repeated\n");
136 input_event(d->input_dev, EV_KEY, event, 1);
137 input_sync(d->input_dev);
138 input_event(d->input_dev, EV_KEY, d->last_event, 0);
139 input_sync(d->input_dev);
140 break;
141 default:
142 break;
143 }
144
145/* improved repeat handling ???
146 switch (state) {
147 case REMOTE_NO_KEY_PRESSED:
148 deb_rc("NO KEY PRESSED\n");
149 if (d->last_state != REMOTE_NO_KEY_PRESSED) {
150 deb_rc("releasing event %d\n",d->last_event);
151 input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
152 input_sync(d->rc_input_dev);
153 }
154 d->last_state = REMOTE_NO_KEY_PRESSED;
155 d->last_event = 0;
156 break;
157 case REMOTE_KEY_PRESSED:
158 deb_rc("KEY PRESSED\n");
159 deb_rc("pressing event %d\n",event);
160
161 input_event(d->rc_input_dev, EV_KEY, event, 1);
162 input_sync(d->rc_input_dev);
163
164 d->last_event = event;
165 d->last_state = REMOTE_KEY_PRESSED;
166 break;
167 case REMOTE_KEY_REPEAT:
168 deb_rc("KEY_REPEAT\n");
169 if (d->last_state != REMOTE_NO_KEY_PRESSED) {
170 deb_rc("repeating event %d\n",d->last_event);
171 input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
172 input_sync(d->rc_input_dev);
173 d->last_state = REMOTE_KEY_REPEAT;
174 }
175 default:
176 break;
177 }
178*/
179
180schedule:
181 schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc.legacy.rc_interval));
182}
183
184static int legacy_dvb_usb_remote_init(struct dvb_usb_device *d)
185{
186 int i, err, rc_interval;
187 struct input_dev *input_dev;
188
189 input_dev = input_allocate_device();
190 if (!input_dev)
191 return -ENOMEM;
192
193 input_dev->evbit[0] = BIT_MASK(EV_KEY);
194 input_dev->name = "IR-receiver inside an USB DVB receiver";
195 input_dev->phys = d->rc_phys;
196 usb_to_input_id(d->udev, &input_dev->id);
197 input_dev->dev.parent = &d->udev->dev;
198 d->input_dev = input_dev;
199 d->rc_dev = NULL;
200
201 input_dev->getkeycode = legacy_dvb_usb_getkeycode;
202 input_dev->setkeycode = legacy_dvb_usb_setkeycode;
203
204 /* set the bits for the keys */
205 deb_rc("key map size: %d\n", d->props.rc.legacy.rc_map_size);
206 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) {
207 deb_rc("setting bit for event %d item %d\n",
208 d->props.rc.legacy.rc_map_table[i].keycode, i);
209 set_bit(d->props.rc.legacy.rc_map_table[i].keycode, input_dev->keybit);
210 }
211
212 /* setting these two values to non-zero, we have to manage key repeats */
213 input_dev->rep[REP_PERIOD] = d->props.rc.legacy.rc_interval;
214 input_dev->rep[REP_DELAY] = d->props.rc.legacy.rc_interval + 150;
215
216 input_set_drvdata(input_dev, d);
217
218 err = input_register_device(input_dev);
219 if (err)
220 input_free_device(input_dev);
221
222 rc_interval = d->props.rc.legacy.rc_interval;
223
224 INIT_DELAYED_WORK(&d->rc_query_work, legacy_dvb_usb_read_remote_control);
225
226 info("schedule remote query interval to %d msecs.", rc_interval);
227 schedule_delayed_work(&d->rc_query_work,
228 msecs_to_jiffies(rc_interval));
229
230 d->state |= DVB_USB_STATE_REMOTE;
231
232 return err;
233}
234
235/* Remote-control poll function - called every dib->rc_query_interval ms to see
236 * whether the remote control has received anything.
237 *
238 * TODO: Fix the repeat rate of the input device.
239 */
240static void dvb_usb_read_remote_control(struct work_struct *work)
241{
242 struct dvb_usb_device *d =
243 container_of(work, struct dvb_usb_device, rc_query_work.work);
244 int err;
245
246 /* TODO: need a lock here. We can simply skip checking for the remote control
247 if we're busy. */
248
249 /* when the parameter has been set to 1 via sysfs while the
250 * driver was running, or when bulk mode is enabled after IR init
251 */
252 if (dvb_usb_disable_rc_polling || d->props.rc.core.bulk_mode)
253 return;
254
255 err = d->props.rc.core.rc_query(d);
256 if (err)
257 err("error %d while querying for an remote control event.", err);
258
259 schedule_delayed_work(&d->rc_query_work,
260 msecs_to_jiffies(d->props.rc.core.rc_interval));
261}
262
263static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
264{
265 int err, rc_interval;
266 struct rc_dev *dev;
267
268 dev = rc_allocate_device();
269 if (!dev)
270 return -ENOMEM;
271
272 dev->driver_name = d->props.rc.core.module_name;
273 dev->map_name = d->props.rc.core.rc_codes;
274 dev->change_protocol = d->props.rc.core.change_protocol;
275 dev->allowed_protos = d->props.rc.core.allowed_protos;
276 dev->driver_type = d->props.rc.core.driver_type;
277 usb_to_input_id(d->udev, &dev->input_id);
278 dev->input_name = "IR-receiver inside an USB DVB receiver";
279 dev->input_phys = d->rc_phys;
280 dev->dev.parent = &d->udev->dev;
281 dev->priv = d;
282
283 err = rc_register_device(dev);
284 if (err < 0) {
285 rc_free_device(dev);
286 return err;
287 }
288
289 d->input_dev = NULL;
290 d->rc_dev = dev;
291
292 if (!d->props.rc.core.rc_query || d->props.rc.core.bulk_mode)
293 return 0;
294
295 /* Polling mode - initialize a work queue for handling it */
296 INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control);
297
298 rc_interval = d->props.rc.core.rc_interval;
299
300 info("schedule remote query interval to %d msecs.", rc_interval);
301 schedule_delayed_work(&d->rc_query_work,
302 msecs_to_jiffies(rc_interval));
303
304 return 0;
305}
306
307int dvb_usb_remote_init(struct dvb_usb_device *d)
308{
309 int err;
310
311 if (dvb_usb_disable_rc_polling)
312 return 0;
313
314 if (d->props.rc.legacy.rc_map_table && d->props.rc.legacy.rc_query)
315 d->props.rc.mode = DVB_RC_LEGACY;
316 else if (d->props.rc.core.rc_codes)
317 d->props.rc.mode = DVB_RC_CORE;
318 else
319 return 0;
320
321 usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
322 strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
323
324 /* Start the remote-control polling. */
325 if (d->props.rc.legacy.rc_interval < 40)
326 d->props.rc.legacy.rc_interval = 100; /* default */
327
328 if (d->props.rc.mode == DVB_RC_LEGACY)
329 err = legacy_dvb_usb_remote_init(d);
330 else
331 err = rc_core_dvb_usb_remote_init(d);
332 if (err)
333 return err;
334
335 d->state |= DVB_USB_STATE_REMOTE;
336
337 return 0;
338}
339
340int dvb_usb_remote_exit(struct dvb_usb_device *d)
341{
342 if (d->state & DVB_USB_STATE_REMOTE) {
343 cancel_delayed_work_sync(&d->rc_query_work);
344 if (d->props.rc.mode == DVB_RC_LEGACY)
345 input_unregister_device(d->input_dev);
346 else
347 rc_unregister_device(d->rc_dev);
348 }
349 d->state &= ~DVB_USB_STATE_REMOTE;
350 return 0;
351}
352
353#define DVB_USB_RC_NEC_EMPTY 0x00
354#define DVB_USB_RC_NEC_KEY_PRESSED 0x01
355#define DVB_USB_RC_NEC_KEY_REPEATED 0x02
356int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d,
357 u8 keybuf[5], u32 *event, int *state)
358{
359 int i;
360 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
361 *event = 0;
362 *state = REMOTE_NO_KEY_PRESSED;
363 switch (keybuf[0]) {
364 case DVB_USB_RC_NEC_EMPTY:
365 break;
366 case DVB_USB_RC_NEC_KEY_PRESSED:
367 if ((u8) ~keybuf[1] != keybuf[2] ||
368 (u8) ~keybuf[3] != keybuf[4]) {
369 deb_err("remote control checksum failed.\n");
370 break;
371 }
372 /* See if we can match the raw key code. */
373 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
374 if (rc5_custom(&keymap[i]) == keybuf[1] &&
375 rc5_data(&keymap[i]) == keybuf[3]) {
376 *event = keymap[i].keycode;
377 *state = REMOTE_KEY_PRESSED;
378 return 0;
379 }
380 deb_err("key mapping failed - no appropriate key found in keymapping\n");
381 break;
382 case DVB_USB_RC_NEC_KEY_REPEATED:
383 *state = REMOTE_KEY_REPEAT;
384 break;
385 default:
386 deb_err("unknown type of remote status: %d\n",keybuf[0]);
387 break;
388 }
389 return 0;
390}
391EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event);
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-urb.c b/drivers/media/usb/dvb-usb/dvb-usb-urb.c
new file mode 100644
index 000000000000..5c8f651344fc
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb-usb-urb.c
@@ -0,0 +1,121 @@
1/* dvb-usb-urb.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file keeps functions for initializing and handling the
7 * USB and URB stuff.
8 */
9#include "dvb-usb-common.h"
10
11int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf,
12 u16 rlen, int delay_ms)
13{
14 int actlen,ret = -ENOMEM;
15
16 if (!d || wbuf == NULL || wlen == 0)
17 return -EINVAL;
18
19 if (d->props.generic_bulk_ctrl_endpoint == 0) {
20 err("endpoint for generic control not specified.");
21 return -EINVAL;
22 }
23
24 if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
25 return ret;
26
27 deb_xfer(">>> ");
28 debug_dump(wbuf,wlen,deb_xfer);
29
30 ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev,
31 d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen,
32 2000);
33
34 if (ret)
35 err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
36 else
37 ret = actlen != wlen ? -1 : 0;
38
39 /* an answer is expected, and no error before */
40 if (!ret && rbuf && rlen) {
41 if (delay_ms)
42 msleep(delay_ms);
43
44 ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev,
45 d->props.generic_bulk_ctrl_endpoint_response ?
46 d->props.generic_bulk_ctrl_endpoint_response :
47 d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen,
48 2000);
49
50 if (ret)
51 err("recv bulk message failed: %d",ret);
52 else {
53 deb_xfer("<<< ");
54 debug_dump(rbuf,actlen,deb_xfer);
55 }
56 }
57
58 mutex_unlock(&d->usb_mutex);
59 return ret;
60}
61EXPORT_SYMBOL(dvb_usb_generic_rw);
62
63int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len)
64{
65 return dvb_usb_generic_rw(d,buf,len,NULL,0,0);
66}
67EXPORT_SYMBOL(dvb_usb_generic_write);
68
69static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buffer, size_t length)
70{
71 struct dvb_usb_adapter *adap = stream->user_priv;
72 if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
73 dvb_dmx_swfilter(&adap->demux, buffer, length);
74}
75
76static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buffer, size_t length)
77{
78 struct dvb_usb_adapter *adap = stream->user_priv;
79 if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
80 dvb_dmx_swfilter_204(&adap->demux, buffer, length);
81}
82
83static void dvb_usb_data_complete_raw(struct usb_data_stream *stream,
84 u8 *buffer, size_t length)
85{
86 struct dvb_usb_adapter *adap = stream->user_priv;
87 if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB)
88 dvb_dmx_swfilter_raw(&adap->demux, buffer, length);
89}
90
91int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap)
92{
93 int i, ret = 0;
94 for (i = 0; i < adap->props.num_frontends; i++) {
95
96 adap->fe_adap[i].stream.udev = adap->dev->udev;
97 if (adap->props.fe[i].caps & DVB_USB_ADAP_RECEIVES_204_BYTE_TS)
98 adap->fe_adap[i].stream.complete =
99 dvb_usb_data_complete_204;
100 else
101 if (adap->props.fe[i].caps & DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD)
102 adap->fe_adap[i].stream.complete =
103 dvb_usb_data_complete_raw;
104 else
105 adap->fe_adap[i].stream.complete = dvb_usb_data_complete;
106 adap->fe_adap[i].stream.user_priv = adap;
107 ret = usb_urb_init(&adap->fe_adap[i].stream,
108 &adap->props.fe[i].stream);
109 if (ret < 0)
110 break;
111 }
112 return ret;
113}
114
115int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap)
116{
117 int i;
118 for (i = 0; i < adap->props.num_frontends; i++)
119 usb_urb_exit(&adap->fe_adap[i].stream);
120 return 0;
121}
diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h
new file mode 100644
index 000000000000..aab0f99bc892
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb-usb.h
@@ -0,0 +1,483 @@
1/* dvb-usb.h is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * the headerfile, all dvb-usb-drivers have to include.
7 *
8 * TODO: clean-up the structures for unused fields and update the comments
9 */
10#ifndef __DVB_USB_H__
11#define __DVB_USB_H__
12
13#include <linux/input.h>
14#include <linux/usb.h>
15#include <linux/firmware.h>
16#include <linux/mutex.h>
17#include <media/rc-core.h>
18
19#include "dvb_frontend.h"
20#include "dvb_demux.h"
21#include "dvb_net.h"
22#include "dmxdev.h"
23
24#include "dvb-pll.h"
25
26#include "dvb-usb-ids.h"
27
28/* debug */
29#ifdef CONFIG_DVB_USB_DEBUG
30#define dprintk(var,level,args...) \
31 do { if ((var & level)) { printk(args); } } while (0)
32
33#define debug_dump(b,l,func) {\
34 int loop_; \
35 for (loop_ = 0; loop_ < l; loop_++) func("%02x ", b[loop_]); \
36 func("\n");\
37}
38#define DVB_USB_DEBUG_STATUS
39#else
40#define dprintk(args...)
41#define debug_dump(b,l,func)
42
43#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)"
44
45#endif
46
47/* generic log methods - taken from usb.h */
48#ifndef DVB_USB_LOG_PREFIX
49 #define DVB_USB_LOG_PREFIX "dvb-usb (please define a log prefix)"
50#endif
51
52#undef err
53#define err(format, arg...) printk(KERN_ERR DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
54#undef info
55#define info(format, arg...) printk(KERN_INFO DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
56#undef warn
57#define warn(format, arg...) printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg)
58
59/**
60 * struct dvb_usb_device_description - name and its according USB IDs
61 * @name: real name of the box, regardless which DVB USB device class is in use
62 * @cold_ids: array of struct usb_device_id which describe the device in
63 * pre-firmware state
64 * @warm_ids: array of struct usb_device_id which describe the device in
65 * post-firmware state
66 *
67 * Each DVB USB device class can have one or more actual devices, this struct
68 * assigns a name to it.
69 */
70struct dvb_usb_device_description {
71 const char *name;
72
73#define DVB_USB_ID_MAX_NUM 15
74 struct usb_device_id *cold_ids[DVB_USB_ID_MAX_NUM];
75 struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM];
76};
77
78static inline u8 rc5_custom(struct rc_map_table *key)
79{
80 return (key->scancode >> 8) & 0xff;
81}
82
83static inline u8 rc5_data(struct rc_map_table *key)
84{
85 return key->scancode & 0xff;
86}
87
88static inline u16 rc5_scan(struct rc_map_table *key)
89{
90 return key->scancode & 0xffff;
91}
92
93struct dvb_usb_device;
94struct dvb_usb_adapter;
95struct usb_data_stream;
96
97/**
98 * Properties of USB streaming - TODO this structure should be somewhere else
99 * describes the kind of USB transfer used for data-streaming.
100 * (BULK or ISOC)
101 */
102struct usb_data_stream_properties {
103#define USB_BULK 1
104#define USB_ISOC 2
105 int type;
106 int count;
107 int endpoint;
108
109 union {
110 struct {
111 int buffersize; /* per URB */
112 } bulk;
113 struct {
114 int framesperurb;
115 int framesize;
116 int interval;
117 } isoc;
118 } u;
119};
120
121/**
122 * struct dvb_usb_adapter_properties - properties of a dvb-usb-adapter.
123 * A DVB-USB-Adapter is basically a dvb_adapter which is present on a USB-device.
124 * @caps: capabilities of the DVB USB device.
125 * @pid_filter_count: number of PID filter position in the optional hardware
126 * PID-filter.
127 * @num_frontends: number of frontends of the DVB USB adapter.
128 * @frontend_ctrl: called to power on/off active frontend.
129 * @streaming_ctrl: called to start and stop the MPEG2-TS streaming of the
130 * device (not URB submitting/killing).
131 * @pid_filter_ctrl: called to en/disable the PID filter, if any.
132 * @pid_filter: called to set/unset a PID for filtering.
133 * @frontend_attach: called to attach the possible frontends (fill fe-field
134 * of struct dvb_usb_device).
135 * @tuner_attach: called to attach the correct tuner and to fill pll_addr,
136 * pll_desc and pll_init_buf of struct dvb_usb_device).
137 * @stream: configuration of the USB streaming
138 */
139struct dvb_usb_adapter_fe_properties {
140#define DVB_USB_ADAP_HAS_PID_FILTER 0x01
141#define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02
142#define DVB_USB_ADAP_NEED_PID_FILTERING 0x04
143#define DVB_USB_ADAP_RECEIVES_204_BYTE_TS 0x08
144#define DVB_USB_ADAP_RECEIVES_RAW_PAYLOAD 0x10
145 int caps;
146 int pid_filter_count;
147
148 int (*streaming_ctrl) (struct dvb_usb_adapter *, int);
149 int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int);
150 int (*pid_filter) (struct dvb_usb_adapter *, int, u16, int);
151
152 int (*frontend_attach) (struct dvb_usb_adapter *);
153 int (*tuner_attach) (struct dvb_usb_adapter *);
154
155 struct usb_data_stream_properties stream;
156
157 int size_of_priv;
158};
159
160#define MAX_NO_OF_FE_PER_ADAP 3
161struct dvb_usb_adapter_properties {
162 int size_of_priv;
163
164 int (*frontend_ctrl) (struct dvb_frontend *, int);
165
166 int num_frontends;
167 struct dvb_usb_adapter_fe_properties fe[MAX_NO_OF_FE_PER_ADAP];
168};
169
170/**
171 * struct dvb_rc_legacy - old properties of remote controller
172 * @rc_map_table: a hard-wired array of struct rc_map_table (NULL to disable
173 * remote control handling).
174 * @rc_map_size: number of items in @rc_map_table.
175 * @rc_query: called to query an event event.
176 * @rc_interval: time in ms between two queries.
177 */
178struct dvb_rc_legacy {
179/* remote control properties */
180#define REMOTE_NO_KEY_PRESSED 0x00
181#define REMOTE_KEY_PRESSED 0x01
182#define REMOTE_KEY_REPEAT 0x02
183 struct rc_map_table *rc_map_table;
184 int rc_map_size;
185 int (*rc_query) (struct dvb_usb_device *, u32 *, int *);
186 int rc_interval;
187};
188
189/**
190 * struct dvb_rc properties of remote controller, using rc-core
191 * @rc_codes: name of rc codes table
192 * @protocol: type of protocol(s) currently used by the driver
193 * @allowed_protos: protocol(s) supported by the driver
194 * @driver_type: Used to point if a device supports raw mode
195 * @change_protocol: callback to change protocol
196 * @rc_query: called to query an event event.
197 * @rc_interval: time in ms between two queries.
198 * @bulk_mode: device supports bulk mode for RC (disable polling mode)
199 */
200struct dvb_rc {
201 char *rc_codes;
202 u64 protocol;
203 u64 allowed_protos;
204 enum rc_driver_type driver_type;
205 int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
206 char *module_name;
207 int (*rc_query) (struct dvb_usb_device *d);
208 int rc_interval;
209 bool bulk_mode; /* uses bulk mode */
210};
211
212/**
213 * enum dvb_usb_mode - Specifies if it is using a legacy driver or a new one
214 * based on rc-core
215 * This is initialized/used only inside dvb-usb-remote.c.
216 * It shouldn't be set by the drivers.
217 */
218enum dvb_usb_mode {
219 DVB_RC_LEGACY,
220 DVB_RC_CORE,
221};
222
223/**
224 * struct dvb_usb_device_properties - properties of a dvb-usb-device
225 * @usb_ctrl: which USB device-side controller is in use. Needed for firmware
226 * download.
227 * @firmware: name of the firmware file.
228 * @download_firmware: called to download the firmware when the usb_ctrl is
229 * DEVICE_SPECIFIC.
230 * @no_reconnect: device doesn't do a reconnect after downloading the firmware,
231 * so do the warm initialization right after it
232 *
233 * @size_of_priv: how many bytes shall be allocated for the private field
234 * of struct dvb_usb_device.
235 *
236 * @power_ctrl: called to enable/disable power of the device.
237 * @read_mac_address: called to read the MAC address of the device.
238 * @identify_state: called to determine the state (cold or warm), when it
239 * is not distinguishable by the USB IDs.
240 *
241 * @rc: remote controller properties
242 *
243 * @i2c_algo: i2c_algorithm if the device has I2CoverUSB.
244 *
245 * @generic_bulk_ctrl_endpoint: most of the DVB USB devices have a generic
246 * endpoint which received control messages with bulk transfers. When this
247 * is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write-
248 * helper functions.
249 *
250 * @generic_bulk_ctrl_endpoint_response: some DVB USB devices use a separate
251 * endpoint for responses to control messages sent with bulk transfers via
252 * the generic_bulk_ctrl_endpoint. When this is non-zero, this will be used
253 * instead of the generic_bulk_ctrl_endpoint when reading usb responses in
254 * the dvb_usb_generic_rw helper function.
255 *
256 * @num_device_descs: number of struct dvb_usb_device_description in @devices
257 * @devices: array of struct dvb_usb_device_description compatibles with these
258 * properties.
259 */
260#define MAX_NO_OF_ADAPTER_PER_DEVICE 2
261struct dvb_usb_device_properties {
262
263#define DVB_USB_IS_AN_I2C_ADAPTER 0x01
264 int caps;
265
266#define DEVICE_SPECIFIC 0
267#define CYPRESS_AN2135 1
268#define CYPRESS_AN2235 2
269#define CYPRESS_FX2 3
270 int usb_ctrl;
271 int (*download_firmware) (struct usb_device *, const struct firmware *);
272 const char *firmware;
273 int no_reconnect;
274
275 int size_of_priv;
276
277 int num_adapters;
278 struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
279
280 int (*power_ctrl) (struct dvb_usb_device *, int);
281 int (*read_mac_address) (struct dvb_usb_device *, u8 []);
282 int (*identify_state) (struct usb_device *, struct dvb_usb_device_properties *,
283 struct dvb_usb_device_description **, int *);
284
285 struct {
286 enum dvb_usb_mode mode; /* Drivers shouldn't touch on it */
287 struct dvb_rc_legacy legacy;
288 struct dvb_rc core;
289 } rc;
290
291 struct i2c_algorithm *i2c_algo;
292
293 int generic_bulk_ctrl_endpoint;
294 int generic_bulk_ctrl_endpoint_response;
295
296 int num_device_descs;
297 struct dvb_usb_device_description devices[12];
298};
299
300/**
301 * struct usb_data_stream - generic object of an USB stream
302 * @buf_num: number of buffer allocated.
303 * @buf_size: size of each buffer in buf_list.
304 * @buf_list: array containing all allocate buffers for streaming.
305 * @dma_addr: list of dma_addr_t for each buffer in buf_list.
306 *
307 * @urbs_initialized: number of URBs initialized.
308 * @urbs_submitted: number of URBs submitted.
309 */
310#define MAX_NO_URBS_FOR_DATA_STREAM 10
311struct usb_data_stream {
312 struct usb_device *udev;
313 struct usb_data_stream_properties props;
314
315#define USB_STATE_INIT 0x00
316#define USB_STATE_URB_BUF 0x01
317 int state;
318
319 void (*complete) (struct usb_data_stream *, u8 *, size_t);
320
321 struct urb *urb_list[MAX_NO_URBS_FOR_DATA_STREAM];
322 int buf_num;
323 unsigned long buf_size;
324 u8 *buf_list[MAX_NO_URBS_FOR_DATA_STREAM];
325 dma_addr_t dma_addr[MAX_NO_URBS_FOR_DATA_STREAM];
326
327 int urbs_initialized;
328 int urbs_submitted;
329
330 void *user_priv;
331};
332
333/**
334 * struct dvb_usb_adapter - a DVB adapter on a USB device
335 * @id: index of this adapter (starting with 0).
336 *
337 * @feedcount: number of reqested feeds (used for streaming-activation)
338 * @pid_filtering: is hardware pid_filtering used or not.
339 *
340 * @pll_addr: I2C address of the tuner for programming
341 * @pll_init: array containing the initialization buffer
342 * @pll_desc: pointer to the appropriate struct dvb_pll_desc
343 * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod or the board
344 *
345 * @dvb_adap: device's dvb_adapter.
346 * @dmxdev: device's dmxdev.
347 * @demux: device's software demuxer.
348 * @dvb_net: device's dvb_net interfaces.
349 * @dvb_frontend: device's frontend.
350 * @max_feed_count: how many feeds can be handled simultaneously by this
351 * device
352 *
353 * @fe_init: rerouted frontend-init (wakeup) function.
354 * @fe_sleep: rerouted frontend-sleep function.
355 *
356 * @stream: the usb data stream.
357 */
358struct dvb_usb_fe_adapter {
359 struct dvb_frontend *fe;
360
361 int (*fe_init) (struct dvb_frontend *);
362 int (*fe_sleep) (struct dvb_frontend *);
363
364 struct usb_data_stream stream;
365
366 int pid_filtering;
367 int max_feed_count;
368
369 void *priv;
370};
371
372struct dvb_usb_adapter {
373 struct dvb_usb_device *dev;
374 struct dvb_usb_adapter_properties props;
375
376#define DVB_USB_ADAP_STATE_INIT 0x000
377#define DVB_USB_ADAP_STATE_DVB 0x001
378 int state;
379
380 u8 id;
381
382 int feedcount;
383
384 /* dvb */
385 struct dvb_adapter dvb_adap;
386 struct dmxdev dmxdev;
387 struct dvb_demux demux;
388 struct dvb_net dvb_net;
389
390 struct dvb_usb_fe_adapter fe_adap[MAX_NO_OF_FE_PER_ADAP];
391 int active_fe;
392 int num_frontends_initialized;
393
394 void *priv;
395};
396
397/**
398 * struct dvb_usb_device - object of a DVB USB device
399 * @props: copy of the struct dvb_usb_properties this device belongs to.
400 * @desc: pointer to the device's struct dvb_usb_device_description.
401 * @state: initialization and runtime state of the device.
402 *
403 * @powered: indicated whether the device is power or not.
404 * Powered is in/decremented for each call to modify the state.
405 * @udev: pointer to the device's struct usb_device.
406 *
407 * @usb_mutex: semaphore of USB control messages (reading needs two messages)
408 * @i2c_mutex: semaphore for i2c-transfers
409 *
410 * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
411 *
412 * @rc_dev: rc device for the remote control (rc-core mode)
413 * @input_dev: input device for the remote control (legacy mode)
414 * @rc_query_work: struct work_struct frequent rc queries
415 * @last_event: last triggered event
416 * @last_state: last state (no, pressed, repeat)
417 * @owner: owner of the dvb_adapter
418 * @priv: private data of the actual driver (allocate by dvb-usb, size defined
419 * in size_of_priv of dvb_usb_properties).
420 */
421struct dvb_usb_device {
422 struct dvb_usb_device_properties props;
423 struct dvb_usb_device_description *desc;
424
425 struct usb_device *udev;
426
427#define DVB_USB_STATE_INIT 0x000
428#define DVB_USB_STATE_I2C 0x001
429#define DVB_USB_STATE_DVB 0x002
430#define DVB_USB_STATE_REMOTE 0x004
431 int state;
432
433 int powered;
434
435 /* locking */
436 struct mutex usb_mutex;
437
438 /* i2c */
439 struct mutex i2c_mutex;
440 struct i2c_adapter i2c_adap;
441
442 int num_adapters_initialized;
443 struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE];
444
445 /* remote control */
446 struct rc_dev *rc_dev;
447 struct input_dev *input_dev;
448 char rc_phys[64];
449 struct delayed_work rc_query_work;
450 u32 last_event;
451 int last_state;
452
453 struct module *owner;
454
455 void *priv;
456};
457
458extern int dvb_usb_device_init(struct usb_interface *,
459 struct dvb_usb_device_properties *,
460 struct module *, struct dvb_usb_device **,
461 short *adapter_nums);
462extern void dvb_usb_device_exit(struct usb_interface *);
463
464/* the generic read/write method for device control */
465extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int);
466extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
467
468/* commonly used remote control parsing */
469extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *);
470
471/* commonly used firmware download types and function */
472struct hexline {
473 u8 len;
474 u32 addr;
475 u8 type;
476 u8 data[255];
477 u8 chk;
478};
479extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type);
480extern int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos);
481
482
483#endif
diff --git a/drivers/media/usb/dvb-usb/dvb_usb_dvb.c b/drivers/media/usb/dvb-usb/dvb_usb_dvb.c
new file mode 100644
index 000000000000..384fe8eec21f
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb_usb_dvb.c
@@ -0,0 +1,403 @@
1/* dvb-usb-dvb.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for initializing and handling the
7 * linux-dvb API.
8 */
9#include "dvb_usb_common.h"
10
11static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buf,
12 size_t len)
13{
14 struct dvb_usb_adapter *adap = stream->user_priv;
15 dvb_dmx_swfilter(&adap->demux, buf, len);
16}
17
18static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buf,
19 size_t len)
20{
21 struct dvb_usb_adapter *adap = stream->user_priv;
22 dvb_dmx_swfilter_204(&adap->demux, buf, len);
23}
24
25static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, u8 *buf,
26 size_t len)
27{
28 struct dvb_usb_adapter *adap = stream->user_priv;
29 dvb_dmx_swfilter_raw(&adap->demux, buf, len);
30}
31
32int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap)
33{
34 pr_debug("%s: adap=%d\n", __func__, adap->id);
35
36 adap->stream.udev = adap_to_d(adap)->udev;
37 adap->stream.user_priv = adap;
38 adap->stream.complete = dvb_usb_data_complete;
39
40 return usb_urb_initv2(&adap->stream, &adap->props->stream);
41}
42
43int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap)
44{
45 pr_debug("%s: adap=%d\n", __func__, adap->id);
46 usb_urb_exitv2(&adap->stream);
47
48 return 0;
49}
50
51/* does the complete input transfer handling */
52static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int count)
53{
54 struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
55 struct dvb_usb_device *d = adap_to_d(adap);
56 int ret;
57 pr_debug("%s: adap=%d active_fe=%d feed_type=%d setting pid [%s]: " \
58 "%04x (%04d) at index %d '%s'\n", __func__, adap->id,
59 adap->active_fe, dvbdmxfeed->type,
60 adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid,
61 dvbdmxfeed->pid, dvbdmxfeed->index,
62 (count == 1) ? "on" : "off");
63
64 if (adap->active_fe == -1)
65 return -EINVAL;
66
67 adap->feed_count += count;
68
69 /* stop feeding if it is last pid */
70 if (adap->feed_count == 0) {
71 pr_debug("%s: stop feeding\n", __func__);
72 usb_urb_killv2(&adap->stream);
73
74 if (d->props->streaming_ctrl) {
75 ret = d->props->streaming_ctrl(adap, 0);
76 if (ret < 0) {
77 pr_err("%s: streaming_ctrl() failed=%d\n",
78 KBUILD_MODNAME, ret);
79 goto err_mutex_unlock;
80 }
81 }
82 mutex_unlock(&adap->sync_mutex);
83 }
84
85 /* activate the pid on the device pid filter */
86 if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
87 adap->pid_filtering &&
88 adap->props->pid_filter)
89 ret = adap->props->pid_filter(adap, dvbdmxfeed->index,
90 dvbdmxfeed->pid, (count == 1) ? 1 : 0);
91 if (ret < 0)
92 pr_err("%s: pid_filter() failed=%d\n",
93 KBUILD_MODNAME, ret);
94
95 /* start feeding if it is first pid */
96 if (adap->feed_count == 1 && count == 1) {
97 struct usb_data_stream_properties stream_props;
98 mutex_lock(&adap->sync_mutex);
99 pr_debug("%s: start feeding\n", __func__);
100
101 /* resolve input and output streaming paramters */
102 if (d->props->get_stream_config) {
103 memcpy(&stream_props, &adap->props->stream,
104 sizeof(struct usb_data_stream_properties));
105 ret = d->props->get_stream_config(
106 adap->fe[adap->active_fe],
107 &adap->ts_type, &stream_props);
108 if (ret < 0)
109 goto err_mutex_unlock;
110 } else {
111 stream_props = adap->props->stream;
112 }
113
114 switch (adap->ts_type) {
115 case DVB_USB_FE_TS_TYPE_204:
116 adap->stream.complete = dvb_usb_data_complete_204;
117 break;
118 case DVB_USB_FE_TS_TYPE_RAW:
119 adap->stream.complete = dvb_usb_data_complete_raw;
120 break;
121 case DVB_USB_FE_TS_TYPE_188:
122 default:
123 adap->stream.complete = dvb_usb_data_complete;
124 break;
125 }
126
127 usb_urb_submitv2(&adap->stream, &stream_props);
128
129 if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER &&
130 adap->props->caps &
131 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
132 adap->props->pid_filter_ctrl) {
133 ret = adap->props->pid_filter_ctrl(adap,
134 adap->pid_filtering);
135 if (ret < 0) {
136 pr_err("%s: pid_filter_ctrl() failed=%d\n",
137 KBUILD_MODNAME, ret);
138 goto err_mutex_unlock;
139 }
140 }
141
142 if (d->props->streaming_ctrl) {
143 ret = d->props->streaming_ctrl(adap, 1);
144 if (ret < 0) {
145 pr_err("%s: streaming_ctrl() failed=%d\n",
146 KBUILD_MODNAME, ret);
147 goto err_mutex_unlock;
148 }
149 }
150 }
151
152 return 0;
153err_mutex_unlock:
154 mutex_unlock(&adap->sync_mutex);
155 pr_debug("%s: failed=%d\n", __func__, ret);
156 return ret;
157}
158
159static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
160{
161 return dvb_usb_ctrl_feed(dvbdmxfeed, 1);
162}
163
164static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
165{
166 return dvb_usb_ctrl_feed(dvbdmxfeed, -1);
167}
168
169int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap)
170{
171 int ret;
172 struct dvb_usb_device *d = adap_to_d(adap);
173 pr_debug("%s: adap=%d\n", __func__, adap->id);
174
175 ret = dvb_register_adapter(&adap->dvb_adap, d->name, d->props->owner,
176 &d->udev->dev, d->props->adapter_nr);
177 if (ret < 0) {
178 pr_debug("%s: dvb_register_adapter() failed=%d\n", __func__,
179 ret);
180 goto err;
181 }
182
183 adap->dvb_adap.priv = adap;
184
185 if (d->props->read_mac_address) {
186 ret = d->props->read_mac_address(adap,
187 adap->dvb_adap.proposed_mac);
188 if (ret < 0)
189 goto err_dmx;
190
191 pr_info("%s: MAC address: %pM\n", KBUILD_MODNAME,
192 adap->dvb_adap.proposed_mac);
193 }
194
195 adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
196 adap->demux.priv = adap;
197 adap->demux.filternum = 0;
198 if (adap->demux.filternum < adap->max_feed_count)
199 adap->demux.filternum = adap->max_feed_count;
200 adap->demux.feednum = adap->demux.filternum;
201 adap->demux.start_feed = dvb_usb_start_feed;
202 adap->demux.stop_feed = dvb_usb_stop_feed;
203 adap->demux.write_to_decoder = NULL;
204 ret = dvb_dmx_init(&adap->demux);
205 if (ret < 0) {
206 pr_err("%s: dvb_dmx_init() failed=%d\n", KBUILD_MODNAME, ret);
207 goto err_dmx;
208 }
209
210 adap->dmxdev.filternum = adap->demux.filternum;
211 adap->dmxdev.demux = &adap->demux.dmx;
212 adap->dmxdev.capabilities = 0;
213 ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap);
214 if (ret < 0) {
215 pr_err("%s: dvb_dmxdev_init() failed=%d\n", KBUILD_MODNAME,
216 ret);
217 goto err_dmx_dev;
218 }
219
220 ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx);
221 if (ret < 0) {
222 pr_err("%s: dvb_net_init() failed=%d\n", KBUILD_MODNAME, ret);
223 goto err_net_init;
224 }
225
226 mutex_init(&adap->sync_mutex);
227
228 return 0;
229err_net_init:
230 dvb_dmxdev_release(&adap->dmxdev);
231err_dmx_dev:
232 dvb_dmx_release(&adap->demux);
233err_dmx:
234 dvb_unregister_adapter(&adap->dvb_adap);
235err:
236 adap->dvb_adap.priv = NULL;
237 return ret;
238}
239
240int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap)
241{
242 pr_debug("%s: adap=%d\n", __func__, adap->id);
243
244 if (adap->dvb_adap.priv) {
245 dvb_net_release(&adap->dvb_net);
246 adap->demux.dmx.close(&adap->demux.dmx);
247 dvb_dmxdev_release(&adap->dmxdev);
248 dvb_dmx_release(&adap->demux);
249 dvb_unregister_adapter(&adap->dvb_adap);
250 }
251
252 return 0;
253}
254
255static int dvb_usb_fe_wakeup(struct dvb_frontend *fe)
256{
257 int ret;
258 struct dvb_usb_adapter *adap = fe->dvb->priv;
259 struct dvb_usb_device *d = adap_to_d(adap);
260 mutex_lock(&adap->sync_mutex);
261 pr_debug("%s: adap=%d fe=%d\n", __func__, adap->id, fe->id);
262
263 ret = dvb_usbv2_device_power_ctrl(d, 1);
264 if (ret < 0)
265 goto err;
266
267 if (d->props->frontend_ctrl) {
268 ret = d->props->frontend_ctrl(fe, 1);
269 if (ret < 0)
270 goto err;
271 }
272
273 if (adap->fe_init[fe->id]) {
274 ret = adap->fe_init[fe->id](fe);
275 if (ret < 0)
276 goto err;
277 }
278
279 adap->active_fe = fe->id;
280 mutex_unlock(&adap->sync_mutex);
281
282 return 0;
283err:
284 mutex_unlock(&adap->sync_mutex);
285 pr_debug("%s: failed=%d\n", __func__, ret);
286 return ret;
287}
288
289static int dvb_usb_fe_sleep(struct dvb_frontend *fe)
290{
291 int ret;
292 struct dvb_usb_adapter *adap = fe->dvb->priv;
293 struct dvb_usb_device *d = adap_to_d(adap);
294 mutex_lock(&adap->sync_mutex);
295 pr_debug("%s: adap=%d fe=%d\n", __func__, adap->id, fe->id);
296
297 if (adap->fe_sleep[fe->id]) {
298 ret = adap->fe_sleep[fe->id](fe);
299 if (ret < 0)
300 goto err;
301 }
302
303 if (d->props->frontend_ctrl) {
304 ret = d->props->frontend_ctrl(fe, 0);
305 if (ret < 0)
306 goto err;
307 }
308
309 ret = dvb_usbv2_device_power_ctrl(d, 0);
310 if (ret < 0)
311 goto err;
312
313 adap->active_fe = -1;
314 mutex_unlock(&adap->sync_mutex);
315
316 return 0;
317err:
318 mutex_unlock(&adap->sync_mutex);
319 pr_debug("%s: failed=%d\n", __func__, ret);
320 return ret;
321}
322
323int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap)
324{
325 int ret, i, count_registered = 0;
326 struct dvb_usb_device *d = adap_to_d(adap);
327 pr_debug("%s: adap=%d\n", __func__, adap->id);
328
329 memset(adap->fe, 0, sizeof(adap->fe));
330 adap->active_fe = -1;
331
332 if (d->props->frontend_attach) {
333 ret = d->props->frontend_attach(adap);
334 if (ret < 0) {
335 pr_debug("%s: frontend_attach() failed=%d\n", __func__,
336 ret);
337 goto err_dvb_frontend_detach;
338 }
339 } else {
340 pr_debug("%s: frontend_attach() do not exists\n", __func__);
341 ret = 0;
342 goto err;
343 }
344
345 for (i = 0; i < MAX_NO_OF_FE_PER_ADAP && adap->fe[i]; i++) {
346 adap->fe[i]->id = i;
347
348 /* re-assign sleep and wakeup functions */
349 adap->fe_init[i] = adap->fe[i]->ops.init;
350 adap->fe[i]->ops.init = dvb_usb_fe_wakeup;
351 adap->fe_sleep[i] = adap->fe[i]->ops.sleep;
352 adap->fe[i]->ops.sleep = dvb_usb_fe_sleep;
353
354 ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]);
355 if (ret < 0) {
356 pr_err("%s: frontend%d registration failed\n",
357 KBUILD_MODNAME, i);
358 goto err_dvb_unregister_frontend;
359 }
360
361 count_registered++;
362 }
363
364 if (d->props->tuner_attach) {
365 ret = d->props->tuner_attach(adap);
366 if (ret < 0) {
367 pr_debug("%s: tuner_attach() failed=%d\n", __func__,
368 ret);
369 goto err_dvb_unregister_frontend;
370 }
371 }
372
373 return 0;
374
375err_dvb_unregister_frontend:
376 for (i = count_registered - 1; i >= 0; i--)
377 dvb_unregister_frontend(adap->fe[i]);
378
379err_dvb_frontend_detach:
380 for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
381 if (adap->fe[i])
382 dvb_frontend_detach(adap->fe[i]);
383 }
384
385err:
386 pr_debug("%s: failed=%d\n", __func__, ret);
387 return ret;
388}
389
390int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap)
391{
392 int i;
393 pr_debug("%s: adap=%d\n", __func__, adap->id);
394
395 for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) {
396 if (adap->fe[i]) {
397 dvb_unregister_frontend(adap->fe[i]);
398 dvb_frontend_detach(adap->fe[i]);
399 }
400 }
401
402 return 0;
403}
diff --git a/drivers/media/usb/dvb-usb/dvb_usb_remote.c b/drivers/media/usb/dvb-usb/dvb_usb_remote.c
new file mode 100644
index 000000000000..f856ab6648c7
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dvb_usb_remote.c
@@ -0,0 +1,117 @@
1/* dvb-usb-remote.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file contains functions for initializing the input-device and for
7 * handling remote-control-queries.
8 */
9#include "dvb_usb_common.h"
10#include <linux/usb/input.h>
11
12/* Remote-control poll function - called every dib->rc_query_interval ms to see
13 * whether the remote control has received anything.
14 *
15 * TODO: Fix the repeat rate of the input device.
16 */
17static void dvb_usb_read_remote_control(struct work_struct *work)
18{
19 struct dvb_usb_device *d = container_of(work,
20 struct dvb_usb_device, rc_query_work.work);
21 int ret;
22
23 /* TODO: need a lock here. We can simply skip checking for the remote
24 control if we're busy. */
25
26 /* when the parameter has been set to 1 via sysfs while the
27 * driver was running, or when bulk mode is enabled after IR init
28 */
29 if (dvb_usbv2_disable_rc_polling || d->rc.bulk_mode)
30 return;
31
32 ret = d->rc.query(d);
33 if (ret < 0)
34 pr_err("%s: error %d while querying for an remote control " \
35 "event\n", KBUILD_MODNAME, ret);
36
37 schedule_delayed_work(&d->rc_query_work,
38 msecs_to_jiffies(d->rc.interval));
39}
40
41int dvb_usbv2_remote_init(struct dvb_usb_device *d)
42{
43 int ret;
44 struct rc_dev *dev;
45
46 if (dvb_usbv2_disable_rc_polling || !d->props->get_rc_config)
47 return 0;
48
49 ret = d->props->get_rc_config(d, &d->rc);
50 if (ret < 0)
51 goto err;
52
53 dev = rc_allocate_device();
54 if (!dev) {
55 ret = -ENOMEM;
56 goto err;
57 }
58
59 dev->dev.parent = &d->udev->dev;
60 dev->input_name = "IR-receiver inside an USB DVB receiver";
61 usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
62 strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
63 dev->input_phys = d->rc_phys;
64 usb_to_input_id(d->udev, &dev->input_id);
65 /* TODO: likely RC-core should took const char * */
66 dev->driver_name = (char *) d->props->driver_name;
67 dev->driver_type = d->rc.driver_type;
68 dev->allowed_protos = d->rc.allowed_protos;
69 dev->change_protocol = d->rc.change_protocol;
70 dev->priv = d;
71 /* select used keymap */
72 if (d->rc.map_name)
73 dev->map_name = d->rc.map_name;
74 else if (d->rc_map)
75 dev->map_name = d->rc_map;
76 else
77 dev->map_name = RC_MAP_EMPTY; /* keep rc enabled */
78
79 ret = rc_register_device(dev);
80 if (ret < 0) {
81 rc_free_device(dev);
82 goto err;
83 }
84
85 d->input_dev = NULL;
86 d->rc_dev = dev;
87
88 /* start polling if needed */
89 if (d->rc.query && !d->rc.bulk_mode) {
90 /* initialize a work queue for handling polling */
91 INIT_DELAYED_WORK(&d->rc_query_work,
92 dvb_usb_read_remote_control);
93 pr_info("%s: schedule remote query interval to %d msecs\n",
94 KBUILD_MODNAME, d->rc.interval);
95 schedule_delayed_work(&d->rc_query_work,
96 msecs_to_jiffies(d->rc.interval));
97 }
98
99 d->state |= DVB_USB_STATE_REMOTE;
100
101 return 0;
102err:
103 pr_debug("%s: failed=%d\n", __func__, ret);
104 return ret;
105}
106
107int dvb_usbv2_remote_exit(struct dvb_usb_device *d)
108{
109 if (d->state & DVB_USB_STATE_REMOTE) {
110 cancel_delayed_work_sync(&d->rc_query_work);
111 rc_unregister_device(d->rc_dev);
112 }
113
114 d->state &= ~DVB_USB_STATE_REMOTE;
115
116 return 0;
117}
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
new file mode 100644
index 000000000000..9382895b1b88
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -0,0 +1,1951 @@
1/* DVB USB framework compliant Linux driver for the
2 * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
3 * TeVii S600, S630, S650, S660, S480,
4 * Prof 1100, 7500,
5 * Geniatech SU3000 Cards
6 * Copyright (C) 2008-2011 Igor M. Liplianin (liplianin@me.by)
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#include "dw2102.h"
15#include "si21xx.h"
16#include "stv0299.h"
17#include "z0194a.h"
18#include "stv0288.h"
19#include "stb6000.h"
20#include "eds1547.h"
21#include "cx24116.h"
22#include "tda1002x.h"
23#include "mt312.h"
24#include "zl10039.h"
25#include "ds3000.h"
26#include "stv0900.h"
27#include "stv6110.h"
28#include "stb6100.h"
29#include "stb6100_proc.h"
30
31#ifndef USB_PID_DW2102
32#define USB_PID_DW2102 0x2102
33#endif
34
35#ifndef USB_PID_DW2104
36#define USB_PID_DW2104 0x2104
37#endif
38
39#ifndef USB_PID_DW3101
40#define USB_PID_DW3101 0x3101
41#endif
42
43#ifndef USB_PID_CINERGY_S
44#define USB_PID_CINERGY_S 0x0064
45#endif
46
47#ifndef USB_PID_TEVII_S630
48#define USB_PID_TEVII_S630 0xd630
49#endif
50
51#ifndef USB_PID_TEVII_S650
52#define USB_PID_TEVII_S650 0xd650
53#endif
54
55#ifndef USB_PID_TEVII_S660
56#define USB_PID_TEVII_S660 0xd660
57#endif
58
59#ifndef USB_PID_TEVII_S480_1
60#define USB_PID_TEVII_S480_1 0xd481
61#endif
62
63#ifndef USB_PID_TEVII_S480_2
64#define USB_PID_TEVII_S480_2 0xd482
65#endif
66
67#ifndef USB_PID_PROF_1100
68#define USB_PID_PROF_1100 0xb012
69#endif
70
71#define DW210X_READ_MSG 0
72#define DW210X_WRITE_MSG 1
73
74#define REG_1F_SYMBOLRATE_BYTE0 0x1f
75#define REG_20_SYMBOLRATE_BYTE1 0x20
76#define REG_21_SYMBOLRATE_BYTE2 0x21
77/* on my own*/
78#define DW2102_VOLTAGE_CTRL (0x1800)
79#define SU3000_STREAM_CTRL (0x1900)
80#define DW2102_RC_QUERY (0x1a00)
81#define DW2102_LED_CTRL (0x1b00)
82
83#define err_str "did not find the firmware file. (%s) " \
84 "Please see linux/Documentation/dvb/ for more details " \
85 "on firmware-problems."
86
87struct rc_map_dvb_usb_table_table {
88 struct rc_map_table *rc_keys;
89 int rc_keys_size;
90};
91
92struct su3000_state {
93 u8 initialized;
94};
95
96struct s6x0_state {
97 int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v);
98};
99
100/* debug */
101static int dvb_usb_dw2102_debug;
102module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
103MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
104 DVB_USB_DEBUG_STATUS);
105
106/* keymaps */
107static int ir_keymap;
108module_param_named(keymap, ir_keymap, int, 0644);
109MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."
110 " 256=none");
111
112/* demod probe */
113static int demod_probe = 1;
114module_param_named(demod, demod_probe, int, 0644);
115MODULE_PARM_DESC(demod, "demod to probe (1=cx24116 2=stv0903+stv6110 "
116 "4=stv0903+stb6100(or-able)).");
117
118DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
119
120static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value,
121 u16 index, u8 * data, u16 len, int flags)
122{
123 int ret;
124 u8 *u8buf;
125 unsigned int pipe = (flags == DW210X_READ_MSG) ?
126 usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
127 u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
128
129 u8buf = kmalloc(len, GFP_KERNEL);
130 if (!u8buf)
131 return -ENOMEM;
132
133
134 if (flags == DW210X_WRITE_MSG)
135 memcpy(u8buf, data, len);
136 ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
137 value, index , u8buf, len, 2000);
138
139 if (flags == DW210X_READ_MSG)
140 memcpy(data, u8buf, len);
141
142 kfree(u8buf);
143 return ret;
144}
145
146/* I2C */
147static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
148 int num)
149{
150 struct dvb_usb_device *d = i2c_get_adapdata(adap);
151 int i = 0;
152 u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
153 u16 value;
154
155 if (!d)
156 return -ENODEV;
157 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
158 return -EAGAIN;
159
160 switch (num) {
161 case 2:
162 /* read stv0299 register */
163 value = msg[0].buf[0];/* register */
164 for (i = 0; i < msg[1].len; i++) {
165 dw210x_op_rw(d->udev, 0xb5, value + i, 0,
166 buf6, 2, DW210X_READ_MSG);
167 msg[1].buf[i] = buf6[0];
168 }
169 break;
170 case 1:
171 switch (msg[0].addr) {
172 case 0x68:
173 /* write to stv0299 register */
174 buf6[0] = 0x2a;
175 buf6[1] = msg[0].buf[0];
176 buf6[2] = msg[0].buf[1];
177 dw210x_op_rw(d->udev, 0xb2, 0, 0,
178 buf6, 3, DW210X_WRITE_MSG);
179 break;
180 case 0x60:
181 if (msg[0].flags == 0) {
182 /* write to tuner pll */
183 buf6[0] = 0x2c;
184 buf6[1] = 5;
185 buf6[2] = 0xc0;
186 buf6[3] = msg[0].buf[0];
187 buf6[4] = msg[0].buf[1];
188 buf6[5] = msg[0].buf[2];
189 buf6[6] = msg[0].buf[3];
190 dw210x_op_rw(d->udev, 0xb2, 0, 0,
191 buf6, 7, DW210X_WRITE_MSG);
192 } else {
193 /* read from tuner */
194 dw210x_op_rw(d->udev, 0xb5, 0, 0,
195 buf6, 1, DW210X_READ_MSG);
196 msg[0].buf[0] = buf6[0];
197 }
198 break;
199 case (DW2102_RC_QUERY):
200 dw210x_op_rw(d->udev, 0xb8, 0, 0,
201 buf6, 2, DW210X_READ_MSG);
202 msg[0].buf[0] = buf6[0];
203 msg[0].buf[1] = buf6[1];
204 break;
205 case (DW2102_VOLTAGE_CTRL):
206 buf6[0] = 0x30;
207 buf6[1] = msg[0].buf[0];
208 dw210x_op_rw(d->udev, 0xb2, 0, 0,
209 buf6, 2, DW210X_WRITE_MSG);
210 break;
211 }
212
213 break;
214 }
215
216 mutex_unlock(&d->i2c_mutex);
217 return num;
218}
219
220static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
221 struct i2c_msg msg[], int num)
222{
223 struct dvb_usb_device *d = i2c_get_adapdata(adap);
224 u8 buf6[] = {0, 0, 0, 0, 0, 0, 0};
225
226 if (!d)
227 return -ENODEV;
228 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
229 return -EAGAIN;
230
231 switch (num) {
232 case 2:
233 /* read si2109 register by number */
234 buf6[0] = msg[0].addr << 1;
235 buf6[1] = msg[0].len;
236 buf6[2] = msg[0].buf[0];
237 dw210x_op_rw(d->udev, 0xc2, 0, 0,
238 buf6, msg[0].len + 2, DW210X_WRITE_MSG);
239 /* read si2109 register */
240 dw210x_op_rw(d->udev, 0xc3, 0xd0, 0,
241 buf6, msg[1].len + 2, DW210X_READ_MSG);
242 memcpy(msg[1].buf, buf6 + 2, msg[1].len);
243
244 break;
245 case 1:
246 switch (msg[0].addr) {
247 case 0x68:
248 /* write to si2109 register */
249 buf6[0] = msg[0].addr << 1;
250 buf6[1] = msg[0].len;
251 memcpy(buf6 + 2, msg[0].buf, msg[0].len);
252 dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6,
253 msg[0].len + 2, DW210X_WRITE_MSG);
254 break;
255 case(DW2102_RC_QUERY):
256 dw210x_op_rw(d->udev, 0xb8, 0, 0,
257 buf6, 2, DW210X_READ_MSG);
258 msg[0].buf[0] = buf6[0];
259 msg[0].buf[1] = buf6[1];
260 break;
261 case(DW2102_VOLTAGE_CTRL):
262 buf6[0] = 0x30;
263 buf6[1] = msg[0].buf[0];
264 dw210x_op_rw(d->udev, 0xb2, 0, 0,
265 buf6, 2, DW210X_WRITE_MSG);
266 break;
267 }
268 break;
269 }
270
271 mutex_unlock(&d->i2c_mutex);
272 return num;
273}
274
275static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
276{
277 struct dvb_usb_device *d = i2c_get_adapdata(adap);
278
279 if (!d)
280 return -ENODEV;
281 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
282 return -EAGAIN;
283
284 switch (num) {
285 case 2: {
286 /* read */
287 /* first write first register number */
288 u8 ibuf[msg[1].len + 2], obuf[3];
289 obuf[0] = msg[0].addr << 1;
290 obuf[1] = msg[0].len;
291 obuf[2] = msg[0].buf[0];
292 dw210x_op_rw(d->udev, 0xc2, 0, 0,
293 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
294 /* second read registers */
295 dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0,
296 ibuf, msg[1].len + 2, DW210X_READ_MSG);
297 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
298
299 break;
300 }
301 case 1:
302 switch (msg[0].addr) {
303 case 0x68: {
304 /* write to register */
305 u8 obuf[msg[0].len + 2];
306 obuf[0] = msg[0].addr << 1;
307 obuf[1] = msg[0].len;
308 memcpy(obuf + 2, msg[0].buf, msg[0].len);
309 dw210x_op_rw(d->udev, 0xc2, 0, 0,
310 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
311 break;
312 }
313 case 0x61: {
314 /* write to tuner */
315 u8 obuf[msg[0].len + 2];
316 obuf[0] = msg[0].addr << 1;
317 obuf[1] = msg[0].len;
318 memcpy(obuf + 2, msg[0].buf, msg[0].len);
319 dw210x_op_rw(d->udev, 0xc2, 0, 0,
320 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
321 break;
322 }
323 case(DW2102_RC_QUERY): {
324 u8 ibuf[2];
325 dw210x_op_rw(d->udev, 0xb8, 0, 0,
326 ibuf, 2, DW210X_READ_MSG);
327 memcpy(msg[0].buf, ibuf , 2);
328 break;
329 }
330 case(DW2102_VOLTAGE_CTRL): {
331 u8 obuf[2];
332 obuf[0] = 0x30;
333 obuf[1] = msg[0].buf[0];
334 dw210x_op_rw(d->udev, 0xb2, 0, 0,
335 obuf, 2, DW210X_WRITE_MSG);
336 break;
337 }
338 }
339
340 break;
341 }
342
343 mutex_unlock(&d->i2c_mutex);
344 return num;
345}
346
347static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
348{
349 struct dvb_usb_device *d = i2c_get_adapdata(adap);
350 int len, i, j;
351
352 if (!d)
353 return -ENODEV;
354 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
355 return -EAGAIN;
356
357 for (j = 0; j < num; j++) {
358 switch (msg[j].addr) {
359 case(DW2102_RC_QUERY): {
360 u8 ibuf[2];
361 dw210x_op_rw(d->udev, 0xb8, 0, 0,
362 ibuf, 2, DW210X_READ_MSG);
363 memcpy(msg[j].buf, ibuf , 2);
364 break;
365 }
366 case(DW2102_VOLTAGE_CTRL): {
367 u8 obuf[2];
368 obuf[0] = 0x30;
369 obuf[1] = msg[j].buf[0];
370 dw210x_op_rw(d->udev, 0xb2, 0, 0,
371 obuf, 2, DW210X_WRITE_MSG);
372 break;
373 }
374 /*case 0x55: cx24116
375 case 0x6a: stv0903
376 case 0x68: ds3000, stv0903
377 case 0x60: ts2020, stv6110, stb6100 */
378 default: {
379 if (msg[j].flags == I2C_M_RD) {
380 /* read registers */
381 u8 ibuf[msg[j].len + 2];
382 dw210x_op_rw(d->udev, 0xc3,
383 (msg[j].addr << 1) + 1, 0,
384 ibuf, msg[j].len + 2,
385 DW210X_READ_MSG);
386 memcpy(msg[j].buf, ibuf + 2, msg[j].len);
387 mdelay(10);
388 } else if (((msg[j].buf[0] == 0xb0) &&
389 (msg[j].addr == 0x68)) ||
390 ((msg[j].buf[0] == 0xf7) &&
391 (msg[j].addr == 0x55))) {
392 /* write firmware */
393 u8 obuf[19];
394 obuf[0] = msg[j].addr << 1;
395 obuf[1] = (msg[j].len > 15 ? 17 : msg[j].len);
396 obuf[2] = msg[j].buf[0];
397 len = msg[j].len - 1;
398 i = 1;
399 do {
400 memcpy(obuf + 3, msg[j].buf + i,
401 (len > 16 ? 16 : len));
402 dw210x_op_rw(d->udev, 0xc2, 0, 0,
403 obuf, (len > 16 ? 16 : len) + 3,
404 DW210X_WRITE_MSG);
405 i += 16;
406 len -= 16;
407 } while (len > 0);
408 } else {
409 /* write registers */
410 u8 obuf[msg[j].len + 2];
411 obuf[0] = msg[j].addr << 1;
412 obuf[1] = msg[j].len;
413 memcpy(obuf + 2, msg[j].buf, msg[j].len);
414 dw210x_op_rw(d->udev, 0xc2, 0, 0,
415 obuf, msg[j].len + 2,
416 DW210X_WRITE_MSG);
417 }
418 break;
419 }
420 }
421
422 }
423
424 mutex_unlock(&d->i2c_mutex);
425 return num;
426}
427
428static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
429 int num)
430{
431 struct dvb_usb_device *d = i2c_get_adapdata(adap);
432 int i;
433
434 if (!d)
435 return -ENODEV;
436 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
437 return -EAGAIN;
438
439 switch (num) {
440 case 2: {
441 /* read */
442 /* first write first register number */
443 u8 ibuf[msg[1].len + 2], obuf[3];
444 obuf[0] = msg[0].addr << 1;
445 obuf[1] = msg[0].len;
446 obuf[2] = msg[0].buf[0];
447 dw210x_op_rw(d->udev, 0xc2, 0, 0,
448 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
449 /* second read registers */
450 dw210x_op_rw(d->udev, 0xc3, 0x19 , 0,
451 ibuf, msg[1].len + 2, DW210X_READ_MSG);
452 memcpy(msg[1].buf, ibuf + 2, msg[1].len);
453
454 break;
455 }
456 case 1:
457 switch (msg[0].addr) {
458 case 0x60:
459 case 0x0c: {
460 /* write to register */
461 u8 obuf[msg[0].len + 2];
462 obuf[0] = msg[0].addr << 1;
463 obuf[1] = msg[0].len;
464 memcpy(obuf + 2, msg[0].buf, msg[0].len);
465 dw210x_op_rw(d->udev, 0xc2, 0, 0,
466 obuf, msg[0].len + 2, DW210X_WRITE_MSG);
467 break;
468 }
469 case(DW2102_RC_QUERY): {
470 u8 ibuf[2];
471 dw210x_op_rw(d->udev, 0xb8, 0, 0,
472 ibuf, 2, DW210X_READ_MSG);
473 memcpy(msg[0].buf, ibuf , 2);
474 break;
475 }
476 }
477
478 break;
479 }
480
481 for (i = 0; i < num; i++) {
482 deb_xfer("%02x:%02x: %s ", i, msg[i].addr,
483 msg[i].flags == 0 ? ">>>" : "<<<");
484 debug_dump(msg[i].buf, msg[i].len, deb_xfer);
485 }
486
487 mutex_unlock(&d->i2c_mutex);
488 return num;
489}
490
491static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
492 int num)
493{
494 struct dvb_usb_device *d = i2c_get_adapdata(adap);
495 struct usb_device *udev;
496 int len, i, j;
497
498 if (!d)
499 return -ENODEV;
500 udev = d->udev;
501 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
502 return -EAGAIN;
503
504 for (j = 0; j < num; j++) {
505 switch (msg[j].addr) {
506 case (DW2102_RC_QUERY): {
507 u8 ibuf[5];
508 dw210x_op_rw(d->udev, 0xb8, 0, 0,
509 ibuf, 5, DW210X_READ_MSG);
510 memcpy(msg[j].buf, ibuf + 3, 2);
511 break;
512 }
513 case (DW2102_VOLTAGE_CTRL): {
514 u8 obuf[2];
515
516 obuf[0] = 1;
517 obuf[1] = msg[j].buf[1];/* off-on */
518 dw210x_op_rw(d->udev, 0x8a, 0, 0,
519 obuf, 2, DW210X_WRITE_MSG);
520 obuf[0] = 3;
521 obuf[1] = msg[j].buf[0];/* 13v-18v */
522 dw210x_op_rw(d->udev, 0x8a, 0, 0,
523 obuf, 2, DW210X_WRITE_MSG);
524 break;
525 }
526 case (DW2102_LED_CTRL): {
527 u8 obuf[2];
528
529 obuf[0] = 5;
530 obuf[1] = msg[j].buf[0];
531 dw210x_op_rw(d->udev, 0x8a, 0, 0,
532 obuf, 2, DW210X_WRITE_MSG);
533 break;
534 }
535 /*case 0x55: cx24116
536 case 0x6a: stv0903
537 case 0x68: ds3000, stv0903
538 case 0x60: ts2020, stv6110, stb6100
539 case 0xa0: eeprom */
540 default: {
541 if (msg[j].flags == I2C_M_RD) {
542 /* read registers */
543 u8 ibuf[msg[j].len];
544 dw210x_op_rw(d->udev, 0x91, 0, 0,
545 ibuf, msg[j].len,
546 DW210X_READ_MSG);
547 memcpy(msg[j].buf, ibuf, msg[j].len);
548 break;
549 } else if ((msg[j].buf[0] == 0xb0) &&
550 (msg[j].addr == 0x68)) {
551 /* write firmware */
552 u8 obuf[19];
553 obuf[0] = (msg[j].len > 16 ?
554 18 : msg[j].len + 1);
555 obuf[1] = msg[j].addr << 1;
556 obuf[2] = msg[j].buf[0];
557 len = msg[j].len - 1;
558 i = 1;
559 do {
560 memcpy(obuf + 3, msg[j].buf + i,
561 (len > 16 ? 16 : len));
562 dw210x_op_rw(d->udev, 0x80, 0, 0,
563 obuf, (len > 16 ? 16 : len) + 3,
564 DW210X_WRITE_MSG);
565 i += 16;
566 len -= 16;
567 } while (len > 0);
568 } else if (j < (num - 1)) {
569 /* write register addr before read */
570 u8 obuf[msg[j].len + 2];
571 obuf[0] = msg[j + 1].len;
572 obuf[1] = (msg[j].addr << 1);
573 memcpy(obuf + 2, msg[j].buf, msg[j].len);
574 dw210x_op_rw(d->udev,
575 udev->descriptor.idProduct ==
576 0x7500 ? 0x92 : 0x90, 0, 0,
577 obuf, msg[j].len + 2,
578 DW210X_WRITE_MSG);
579 break;
580 } else {
581 /* write registers */
582 u8 obuf[msg[j].len + 2];
583 obuf[0] = msg[j].len + 1;
584 obuf[1] = (msg[j].addr << 1);
585 memcpy(obuf + 2, msg[j].buf, msg[j].len);
586 dw210x_op_rw(d->udev, 0x80, 0, 0,
587 obuf, msg[j].len + 2,
588 DW210X_WRITE_MSG);
589 break;
590 }
591 break;
592 }
593 }
594 }
595
596 mutex_unlock(&d->i2c_mutex);
597 return num;
598}
599
600static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
601 int num)
602{
603 struct dvb_usb_device *d = i2c_get_adapdata(adap);
604 u8 obuf[0x40], ibuf[0x40];
605
606 if (!d)
607 return -ENODEV;
608 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
609 return -EAGAIN;
610
611 switch (num) {
612 case 1:
613 switch (msg[0].addr) {
614 case SU3000_STREAM_CTRL:
615 obuf[0] = msg[0].buf[0] + 0x36;
616 obuf[1] = 3;
617 obuf[2] = 0;
618 if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
619 err("i2c transfer failed.");
620 break;
621 case DW2102_RC_QUERY:
622 obuf[0] = 0x10;
623 if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
624 err("i2c transfer failed.");
625 msg[0].buf[1] = ibuf[0];
626 msg[0].buf[0] = ibuf[1];
627 break;
628 default:
629 /* always i2c write*/
630 obuf[0] = 0x08;
631 obuf[1] = msg[0].addr;
632 obuf[2] = msg[0].len;
633
634 memcpy(&obuf[3], msg[0].buf, msg[0].len);
635
636 if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
637 ibuf, 1, 0) < 0)
638 err("i2c transfer failed.");
639
640 }
641 break;
642 case 2:
643 /* always i2c read */
644 obuf[0] = 0x09;
645 obuf[1] = msg[0].len;
646 obuf[2] = msg[1].len;
647 obuf[3] = msg[0].addr;
648 memcpy(&obuf[4], msg[0].buf, msg[0].len);
649
650 if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
651 ibuf, msg[1].len + 1, 0) < 0)
652 err("i2c transfer failed.");
653
654 memcpy(msg[1].buf, &ibuf[1], msg[1].len);
655 break;
656 default:
657 warn("more than 2 i2c messages at a time is not handled yet.");
658 break;
659 }
660 mutex_unlock(&d->i2c_mutex);
661 return num;
662}
663
664static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
665{
666 return I2C_FUNC_I2C;
667}
668
669static struct i2c_algorithm dw2102_i2c_algo = {
670 .master_xfer = dw2102_i2c_transfer,
671 .functionality = dw210x_i2c_func,
672};
673
674static struct i2c_algorithm dw2102_serit_i2c_algo = {
675 .master_xfer = dw2102_serit_i2c_transfer,
676 .functionality = dw210x_i2c_func,
677};
678
679static struct i2c_algorithm dw2102_earda_i2c_algo = {
680 .master_xfer = dw2102_earda_i2c_transfer,
681 .functionality = dw210x_i2c_func,
682};
683
684static struct i2c_algorithm dw2104_i2c_algo = {
685 .master_xfer = dw2104_i2c_transfer,
686 .functionality = dw210x_i2c_func,
687};
688
689static struct i2c_algorithm dw3101_i2c_algo = {
690 .master_xfer = dw3101_i2c_transfer,
691 .functionality = dw210x_i2c_func,
692};
693
694static struct i2c_algorithm s6x0_i2c_algo = {
695 .master_xfer = s6x0_i2c_transfer,
696 .functionality = dw210x_i2c_func,
697};
698
699static struct i2c_algorithm su3000_i2c_algo = {
700 .master_xfer = su3000_i2c_transfer,
701 .functionality = dw210x_i2c_func,
702};
703
704static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
705{
706 int i;
707 u8 ibuf[] = {0, 0};
708 u8 eeprom[256], eepromline[16];
709
710 for (i = 0; i < 256; i++) {
711 if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) {
712 err("read eeprom failed.");
713 return -1;
714 } else {
715 eepromline[i%16] = ibuf[0];
716 eeprom[i] = ibuf[0];
717 }
718 if ((i % 16) == 15) {
719 deb_xfer("%02x: ", i - 15);
720 debug_dump(eepromline, 16, deb_xfer);
721 }
722 }
723
724 memcpy(mac, eeprom + 8, 6);
725 return 0;
726};
727
728static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
729{
730 int i, ret;
731 u8 ibuf[] = { 0 }, obuf[] = { 0 };
732 u8 eeprom[256], eepromline[16];
733 struct i2c_msg msg[] = {
734 {
735 .addr = 0xa0 >> 1,
736 .flags = 0,
737 .buf = obuf,
738 .len = 1,
739 }, {
740 .addr = 0xa0 >> 1,
741 .flags = I2C_M_RD,
742 .buf = ibuf,
743 .len = 1,
744 }
745 };
746
747 for (i = 0; i < 256; i++) {
748 obuf[0] = i;
749 ret = s6x0_i2c_transfer(&d->i2c_adap, msg, 2);
750 if (ret != 2) {
751 err("read eeprom failed.");
752 return -1;
753 } else {
754 eepromline[i % 16] = ibuf[0];
755 eeprom[i] = ibuf[0];
756 }
757
758 if ((i % 16) == 15) {
759 deb_xfer("%02x: ", i - 15);
760 debug_dump(eepromline, 16, deb_xfer);
761 }
762 }
763
764 memcpy(mac, eeprom + 16, 6);
765 return 0;
766};
767
768static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
769{
770 static u8 command_start[] = {0x00};
771 static u8 command_stop[] = {0x01};
772 struct i2c_msg msg = {
773 .addr = SU3000_STREAM_CTRL,
774 .flags = 0,
775 .buf = onoff ? command_start : command_stop,
776 .len = 1
777 };
778
779 i2c_transfer(&adap->dev->i2c_adap, &msg, 1);
780
781 return 0;
782}
783
784static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
785{
786 struct su3000_state *state = (struct su3000_state *)d->priv;
787 u8 obuf[] = {0xde, 0};
788
789 info("%s: %d, initialized %d\n", __func__, i, state->initialized);
790
791 if (i && !state->initialized) {
792 state->initialized = 1;
793 /* reset board */
794 dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0);
795 }
796
797 return 0;
798}
799
800static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
801{
802 int i;
803 u8 obuf[] = { 0x1f, 0xf0 };
804 u8 ibuf[] = { 0 };
805 struct i2c_msg msg[] = {
806 {
807 .addr = 0x51,
808 .flags = 0,
809 .buf = obuf,
810 .len = 2,
811 }, {
812 .addr = 0x51,
813 .flags = I2C_M_RD,
814 .buf = ibuf,
815 .len = 1,
816
817 }
818 };
819
820 for (i = 0; i < 6; i++) {
821 obuf[1] = 0xf0 + i;
822 if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
823 break;
824 else
825 mac[i] = ibuf[0];
826
827 debug_dump(mac, 6, printk);
828 }
829
830 return 0;
831}
832
833static int su3000_identify_state(struct usb_device *udev,
834 struct dvb_usb_device_properties *props,
835 struct dvb_usb_device_description **desc,
836 int *cold)
837{
838 info("%s\n", __func__);
839
840 *cold = 0;
841 return 0;
842}
843
844static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
845{
846 static u8 command_13v[] = {0x00, 0x01};
847 static u8 command_18v[] = {0x01, 0x01};
848 static u8 command_off[] = {0x00, 0x00};
849 struct i2c_msg msg = {
850 .addr = DW2102_VOLTAGE_CTRL,
851 .flags = 0,
852 .buf = command_off,
853 .len = 2,
854 };
855
856 struct dvb_usb_adapter *udev_adap =
857 (struct dvb_usb_adapter *)(fe->dvb->priv);
858 if (voltage == SEC_VOLTAGE_18)
859 msg.buf = command_18v;
860 else if (voltage == SEC_VOLTAGE_13)
861 msg.buf = command_13v;
862
863 i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
864
865 return 0;
866}
867
868static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
869{
870 struct dvb_usb_adapter *d =
871 (struct dvb_usb_adapter *)(fe->dvb->priv);
872 struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
873
874 dw210x_set_voltage(fe, voltage);
875 if (st->old_set_voltage)
876 st->old_set_voltage(fe, voltage);
877
878 return 0;
879}
880
881static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon)
882{
883 static u8 led_off[] = { 0 };
884 static u8 led_on[] = { 1 };
885 struct i2c_msg msg = {
886 .addr = DW2102_LED_CTRL,
887 .flags = 0,
888 .buf = led_off,
889 .len = 1
890 };
891 struct dvb_usb_adapter *udev_adap =
892 (struct dvb_usb_adapter *)(fe->dvb->priv);
893
894 if (offon)
895 msg.buf = led_on;
896 i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
897}
898
899static struct stv0299_config sharp_z0194a_config = {
900 .demod_address = 0x68,
901 .inittab = sharp_z0194a_inittab,
902 .mclk = 88000000UL,
903 .invert = 1,
904 .skip_reinit = 0,
905 .lock_output = STV0299_LOCKOUTPUT_1,
906 .volt13_op0_op1 = STV0299_VOLT13_OP1,
907 .min_delay_ms = 100,
908 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
909};
910
911static struct cx24116_config dw2104_config = {
912 .demod_address = 0x55,
913 .mpg_clk_pos_pol = 0x01,
914};
915
916static struct si21xx_config serit_sp1511lhb_config = {
917 .demod_address = 0x68,
918 .min_delay_ms = 100,
919
920};
921
922static struct tda10023_config dw3101_tda10023_config = {
923 .demod_address = 0x0c,
924 .invert = 1,
925};
926
927static struct mt312_config zl313_config = {
928 .demod_address = 0x0e,
929};
930
931static struct ds3000_config dw2104_ds3000_config = {
932 .demod_address = 0x68,
933};
934
935static struct stv0900_config dw2104a_stv0900_config = {
936 .demod_address = 0x6a,
937 .demod_mode = 0,
938 .xtal = 27000000,
939 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
940 .diseqc_mode = 2,/* 2/3 PWM */
941 .tun1_maddress = 0,/* 0x60 */
942 .tun1_adc = 0,/* 2 Vpp */
943 .path1_mode = 3,
944};
945
946static struct stb6100_config dw2104a_stb6100_config = {
947 .tuner_address = 0x60,
948 .refclock = 27000000,
949};
950
951static struct stv0900_config dw2104_stv0900_config = {
952 .demod_address = 0x68,
953 .demod_mode = 0,
954 .xtal = 8000000,
955 .clkmode = 3,
956 .diseqc_mode = 2,
957 .tun1_maddress = 0,
958 .tun1_adc = 1,/* 1 Vpp */
959 .path1_mode = 3,
960};
961
962static struct stv6110_config dw2104_stv6110_config = {
963 .i2c_address = 0x60,
964 .mclk = 16000000,
965 .clk_div = 1,
966};
967
968static struct stv0900_config prof_7500_stv0900_config = {
969 .demod_address = 0x6a,
970 .demod_mode = 0,
971 .xtal = 27000000,
972 .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
973 .diseqc_mode = 2,/* 2/3 PWM */
974 .tun1_maddress = 0,/* 0x60 */
975 .tun1_adc = 0,/* 2 Vpp */
976 .path1_mode = 3,
977 .tun1_type = 3,
978 .set_lock_led = dw210x_led_ctrl,
979};
980
981static struct ds3000_config su3000_ds3000_config = {
982 .demod_address = 0x68,
983 .ci_mode = 1,
984};
985
986static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
987{
988 struct dvb_tuner_ops *tuner_ops = NULL;
989
990 if (demod_probe & 4) {
991 d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config,
992 &d->dev->i2c_adap, 0);
993 if (d->fe_adap[0].fe != NULL) {
994 if (dvb_attach(stb6100_attach, d->fe_adap[0].fe,
995 &dw2104a_stb6100_config,
996 &d->dev->i2c_adap)) {
997 tuner_ops = &d->fe_adap[0].fe->ops.tuner_ops;
998 tuner_ops->set_frequency = stb6100_set_freq;
999 tuner_ops->get_frequency = stb6100_get_freq;
1000 tuner_ops->set_bandwidth = stb6100_set_bandw;
1001 tuner_ops->get_bandwidth = stb6100_get_bandw;
1002 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1003 info("Attached STV0900+STB6100!\n");
1004 return 0;
1005 }
1006 }
1007 }
1008
1009 if (demod_probe & 2) {
1010 d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config,
1011 &d->dev->i2c_adap, 0);
1012 if (d->fe_adap[0].fe != NULL) {
1013 if (dvb_attach(stv6110_attach, d->fe_adap[0].fe,
1014 &dw2104_stv6110_config,
1015 &d->dev->i2c_adap)) {
1016 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1017 info("Attached STV0900+STV6110A!\n");
1018 return 0;
1019 }
1020 }
1021 }
1022
1023 if (demod_probe & 1) {
1024 d->fe_adap[0].fe = dvb_attach(cx24116_attach, &dw2104_config,
1025 &d->dev->i2c_adap);
1026 if (d->fe_adap[0].fe != NULL) {
1027 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1028 info("Attached cx24116!\n");
1029 return 0;
1030 }
1031 }
1032
1033 d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
1034 &d->dev->i2c_adap);
1035 if (d->fe_adap[0].fe != NULL) {
1036 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1037 info("Attached DS3000!\n");
1038 return 0;
1039 }
1040
1041 return -EIO;
1042}
1043
1044static struct dvb_usb_device_properties dw2102_properties;
1045static struct dvb_usb_device_properties dw2104_properties;
1046static struct dvb_usb_device_properties s6x0_properties;
1047
1048static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
1049{
1050 if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) {
1051 /*dw2102_properties.adapter->tuner_attach = NULL;*/
1052 d->fe_adap[0].fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config,
1053 &d->dev->i2c_adap);
1054 if (d->fe_adap[0].fe != NULL) {
1055 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1056 info("Attached si21xx!\n");
1057 return 0;
1058 }
1059 }
1060
1061 if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) {
1062 d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
1063 &d->dev->i2c_adap);
1064 if (d->fe_adap[0].fe != NULL) {
1065 if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61,
1066 &d->dev->i2c_adap)) {
1067 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1068 info("Attached stv0288!\n");
1069 return 0;
1070 }
1071 }
1072 }
1073
1074 if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) {
1075 /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/
1076 d->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
1077 &d->dev->i2c_adap);
1078 if (d->fe_adap[0].fe != NULL) {
1079 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1080 info("Attached stv0299!\n");
1081 return 0;
1082 }
1083 }
1084 return -EIO;
1085}
1086
1087static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
1088{
1089 d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config,
1090 &d->dev->i2c_adap, 0x48);
1091 if (d->fe_adap[0].fe != NULL) {
1092 info("Attached tda10023!\n");
1093 return 0;
1094 }
1095 return -EIO;
1096}
1097
1098static int zl100313_frontend_attach(struct dvb_usb_adapter *d)
1099{
1100 d->fe_adap[0].fe = dvb_attach(mt312_attach, &zl313_config,
1101 &d->dev->i2c_adap);
1102 if (d->fe_adap[0].fe != NULL) {
1103 if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60,
1104 &d->dev->i2c_adap)) {
1105 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1106 info("Attached zl100313+zl10039!\n");
1107 return 0;
1108 }
1109 }
1110
1111 return -EIO;
1112}
1113
1114static int stv0288_frontend_attach(struct dvb_usb_adapter *d)
1115{
1116 u8 obuf[] = {7, 1};
1117
1118 d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config,
1119 &d->dev->i2c_adap);
1120
1121 if (d->fe_adap[0].fe == NULL)
1122 return -EIO;
1123
1124 if (NULL == dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, &d->dev->i2c_adap))
1125 return -EIO;
1126
1127 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1128
1129 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1130
1131 info("Attached stv0288+stb6000!\n");
1132
1133 return 0;
1134
1135}
1136
1137static int ds3000_frontend_attach(struct dvb_usb_adapter *d)
1138{
1139 struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
1140 u8 obuf[] = {7, 1};
1141
1142 d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
1143 &d->dev->i2c_adap);
1144
1145 if (d->fe_adap[0].fe == NULL)
1146 return -EIO;
1147
1148 st->old_set_voltage = d->fe_adap[0].fe->ops.set_voltage;
1149 d->fe_adap[0].fe->ops.set_voltage = s660_set_voltage;
1150
1151 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1152
1153 info("Attached ds3000+ds2020!\n");
1154
1155 return 0;
1156}
1157
1158static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
1159{
1160 u8 obuf[] = {7, 1};
1161
1162 d->fe_adap[0].fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
1163 &d->dev->i2c_adap, 0);
1164 if (d->fe_adap[0].fe == NULL)
1165 return -EIO;
1166
1167 d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage;
1168
1169 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1170
1171 info("Attached STV0900+STB6100A!\n");
1172
1173 return 0;
1174}
1175
1176static int su3000_frontend_attach(struct dvb_usb_adapter *d)
1177{
1178 u8 obuf[3] = { 0xe, 0x80, 0 };
1179 u8 ibuf[] = { 0 };
1180
1181 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1182 err("command 0x0e transfer failed.");
1183
1184 obuf[0] = 0xe;
1185 obuf[1] = 0x83;
1186 obuf[2] = 0;
1187
1188 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1189 err("command 0x0e transfer failed.");
1190
1191 obuf[0] = 0xe;
1192 obuf[1] = 0x83;
1193 obuf[2] = 1;
1194
1195 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1196 err("command 0x0e transfer failed.");
1197
1198 obuf[0] = 0x51;
1199
1200 if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
1201 err("command 0x51 transfer failed.");
1202
1203 d->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
1204 &d->dev->i2c_adap);
1205 if (d->fe_adap[0].fe == NULL)
1206 return -EIO;
1207
1208 info("Attached DS3000!\n");
1209
1210 return 0;
1211}
1212
1213static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
1214{
1215 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
1216 &adap->dev->i2c_adap, DVB_PLL_OPERA1);
1217 return 0;
1218}
1219
1220static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
1221{
1222 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60,
1223 &adap->dev->i2c_adap, DVB_PLL_TUA6034);
1224
1225 return 0;
1226}
1227
1228static struct rc_map_table rc_map_dw210x_table[] = {
1229 { 0xf80a, KEY_POWER2 }, /*power*/
1230 { 0xf80c, KEY_MUTE }, /*mute*/
1231 { 0xf811, KEY_1 },
1232 { 0xf812, KEY_2 },
1233 { 0xf813, KEY_3 },
1234 { 0xf814, KEY_4 },
1235 { 0xf815, KEY_5 },
1236 { 0xf816, KEY_6 },
1237 { 0xf817, KEY_7 },
1238 { 0xf818, KEY_8 },
1239 { 0xf819, KEY_9 },
1240 { 0xf810, KEY_0 },
1241 { 0xf81c, KEY_CHANNELUP }, /*ch+*/
1242 { 0xf80f, KEY_CHANNELDOWN }, /*ch-*/
1243 { 0xf81a, KEY_VOLUMEUP }, /*vol+*/
1244 { 0xf80e, KEY_VOLUMEDOWN }, /*vol-*/
1245 { 0xf804, KEY_RECORD }, /*rec*/
1246 { 0xf809, KEY_FAVORITES }, /*fav*/
1247 { 0xf808, KEY_REWIND }, /*rewind*/
1248 { 0xf807, KEY_FASTFORWARD }, /*fast*/
1249 { 0xf80b, KEY_PAUSE }, /*pause*/
1250 { 0xf802, KEY_ESC }, /*cancel*/
1251 { 0xf803, KEY_TAB }, /*tab*/
1252 { 0xf800, KEY_UP }, /*up*/
1253 { 0xf81f, KEY_OK }, /*ok*/
1254 { 0xf801, KEY_DOWN }, /*down*/
1255 { 0xf805, KEY_CAMERA }, /*cap*/
1256 { 0xf806, KEY_STOP }, /*stop*/
1257 { 0xf840, KEY_ZOOM }, /*full*/
1258 { 0xf81e, KEY_TV }, /*tvmode*/
1259 { 0xf81b, KEY_LAST }, /*recall*/
1260};
1261
1262static struct rc_map_table rc_map_tevii_table[] = {
1263 { 0xf80a, KEY_POWER },
1264 { 0xf80c, KEY_MUTE },
1265 { 0xf811, KEY_1 },
1266 { 0xf812, KEY_2 },
1267 { 0xf813, KEY_3 },
1268 { 0xf814, KEY_4 },
1269 { 0xf815, KEY_5 },
1270 { 0xf816, KEY_6 },
1271 { 0xf817, KEY_7 },
1272 { 0xf818, KEY_8 },
1273 { 0xf819, KEY_9 },
1274 { 0xf810, KEY_0 },
1275 { 0xf81c, KEY_MENU },
1276 { 0xf80f, KEY_VOLUMEDOWN },
1277 { 0xf81a, KEY_LAST },
1278 { 0xf80e, KEY_OPEN },
1279 { 0xf804, KEY_RECORD },
1280 { 0xf809, KEY_VOLUMEUP },
1281 { 0xf808, KEY_CHANNELUP },
1282 { 0xf807, KEY_PVR },
1283 { 0xf80b, KEY_TIME },
1284 { 0xf802, KEY_RIGHT },
1285 { 0xf803, KEY_LEFT },
1286 { 0xf800, KEY_UP },
1287 { 0xf81f, KEY_OK },
1288 { 0xf801, KEY_DOWN },
1289 { 0xf805, KEY_TUNER },
1290 { 0xf806, KEY_CHANNELDOWN },
1291 { 0xf840, KEY_PLAYPAUSE },
1292 { 0xf81e, KEY_REWIND },
1293 { 0xf81b, KEY_FAVORITES },
1294 { 0xf81d, KEY_BACK },
1295 { 0xf84d, KEY_FASTFORWARD },
1296 { 0xf844, KEY_EPG },
1297 { 0xf84c, KEY_INFO },
1298 { 0xf841, KEY_AB },
1299 { 0xf843, KEY_AUDIO },
1300 { 0xf845, KEY_SUBTITLE },
1301 { 0xf84a, KEY_LIST },
1302 { 0xf846, KEY_F1 },
1303 { 0xf847, KEY_F2 },
1304 { 0xf85e, KEY_F3 },
1305 { 0xf85c, KEY_F4 },
1306 { 0xf852, KEY_F5 },
1307 { 0xf85a, KEY_F6 },
1308 { 0xf856, KEY_MODE },
1309 { 0xf858, KEY_SWITCHVIDEOMODE },
1310};
1311
1312static struct rc_map_table rc_map_tbs_table[] = {
1313 { 0xf884, KEY_POWER },
1314 { 0xf894, KEY_MUTE },
1315 { 0xf887, KEY_1 },
1316 { 0xf886, KEY_2 },
1317 { 0xf885, KEY_3 },
1318 { 0xf88b, KEY_4 },
1319 { 0xf88a, KEY_5 },
1320 { 0xf889, KEY_6 },
1321 { 0xf88f, KEY_7 },
1322 { 0xf88e, KEY_8 },
1323 { 0xf88d, KEY_9 },
1324 { 0xf892, KEY_0 },
1325 { 0xf896, KEY_CHANNELUP },
1326 { 0xf891, KEY_CHANNELDOWN },
1327 { 0xf893, KEY_VOLUMEUP },
1328 { 0xf88c, KEY_VOLUMEDOWN },
1329 { 0xf883, KEY_RECORD },
1330 { 0xf898, KEY_PAUSE },
1331 { 0xf899, KEY_OK },
1332 { 0xf89a, KEY_SHUFFLE },
1333 { 0xf881, KEY_UP },
1334 { 0xf890, KEY_LEFT },
1335 { 0xf882, KEY_RIGHT },
1336 { 0xf888, KEY_DOWN },
1337 { 0xf895, KEY_FAVORITES },
1338 { 0xf897, KEY_SUBTITLE },
1339 { 0xf89d, KEY_ZOOM },
1340 { 0xf89f, KEY_EXIT },
1341 { 0xf89e, KEY_MENU },
1342 { 0xf89c, KEY_EPG },
1343 { 0xf880, KEY_PREVIOUS },
1344 { 0xf89b, KEY_MODE }
1345};
1346
1347static struct rc_map_table rc_map_su3000_table[] = {
1348 { 0x25, KEY_POWER }, /* right-bottom Red */
1349 { 0x0a, KEY_MUTE }, /* -/-- */
1350 { 0x01, KEY_1 },
1351 { 0x02, KEY_2 },
1352 { 0x03, KEY_3 },
1353 { 0x04, KEY_4 },
1354 { 0x05, KEY_5 },
1355 { 0x06, KEY_6 },
1356 { 0x07, KEY_7 },
1357 { 0x08, KEY_8 },
1358 { 0x09, KEY_9 },
1359 { 0x00, KEY_0 },
1360 { 0x20, KEY_UP }, /* CH+ */
1361 { 0x21, KEY_DOWN }, /* CH+ */
1362 { 0x12, KEY_VOLUMEUP }, /* Brightness Up */
1363 { 0x13, KEY_VOLUMEDOWN },/* Brightness Down */
1364 { 0x1f, KEY_RECORD },
1365 { 0x17, KEY_PLAY },
1366 { 0x16, KEY_PAUSE },
1367 { 0x0b, KEY_STOP },
1368 { 0x27, KEY_FASTFORWARD },/* >> */
1369 { 0x26, KEY_REWIND }, /* << */
1370 { 0x0d, KEY_OK }, /* Mute */
1371 { 0x11, KEY_LEFT }, /* VOL- */
1372 { 0x10, KEY_RIGHT }, /* VOL+ */
1373 { 0x29, KEY_BACK }, /* button under 9 */
1374 { 0x2c, KEY_MENU }, /* TTX */
1375 { 0x2b, KEY_EPG }, /* EPG */
1376 { 0x1e, KEY_RED }, /* OSD */
1377 { 0x0e, KEY_GREEN }, /* Window */
1378 { 0x2d, KEY_YELLOW }, /* button under << */
1379 { 0x0f, KEY_BLUE }, /* bottom yellow button */
1380 { 0x14, KEY_AUDIO }, /* Snapshot */
1381 { 0x38, KEY_TV }, /* TV/Radio */
1382 { 0x0c, KEY_ESC } /* upper Red button */
1383};
1384
1385static struct rc_map_dvb_usb_table_table keys_tables[] = {
1386 { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) },
1387 { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) },
1388 { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) },
1389 { rc_map_su3000_table, ARRAY_SIZE(rc_map_su3000_table) },
1390};
1391
1392static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
1393{
1394 struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table;
1395 int keymap_size = d->props.rc.legacy.rc_map_size;
1396 u8 key[2];
1397 struct i2c_msg msg = {
1398 .addr = DW2102_RC_QUERY,
1399 .flags = I2C_M_RD,
1400 .buf = key,
1401 .len = 2
1402 };
1403 int i;
1404 /* override keymap */
1405 if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) {
1406 keymap = keys_tables[ir_keymap - 1].rc_keys ;
1407 keymap_size = keys_tables[ir_keymap - 1].rc_keys_size;
1408 } else if (ir_keymap > ARRAY_SIZE(keys_tables))
1409 return 0; /* none */
1410
1411 *state = REMOTE_NO_KEY_PRESSED;
1412 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
1413 for (i = 0; i < keymap_size ; i++) {
1414 if (rc5_data(&keymap[i]) == msg.buf[0]) {
1415 *state = REMOTE_KEY_PRESSED;
1416 *event = keymap[i].keycode;
1417 break;
1418 }
1419
1420 }
1421
1422 if ((*state) == REMOTE_KEY_PRESSED)
1423 deb_rc("%s: found rc key: %x, %x, event: %x\n",
1424 __func__, key[0], key[1], (*event));
1425 else if (key[0] != 0xff)
1426 deb_rc("%s: unknown rc key: %x, %x\n",
1427 __func__, key[0], key[1]);
1428
1429 }
1430
1431 return 0;
1432}
1433
1434enum dw2102_table_entry {
1435 CYPRESS_DW2102,
1436 CYPRESS_DW2101,
1437 CYPRESS_DW2104,
1438 TEVII_S650,
1439 TERRATEC_CINERGY_S,
1440 CYPRESS_DW3101,
1441 TEVII_S630,
1442 PROF_1100,
1443 TEVII_S660,
1444 PROF_7500,
1445 GENIATECH_SU3000,
1446 TERRATEC_CINERGY_S2,
1447 TEVII_S480_1,
1448 TEVII_S480_2,
1449 X3M_SPC1400HD,
1450};
1451
1452static struct usb_device_id dw2102_table[] = {
1453 [CYPRESS_DW2102] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
1454 [CYPRESS_DW2101] = {USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
1455 [CYPRESS_DW2104] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2104)},
1456 [TEVII_S650] = {USB_DEVICE(0x9022, USB_PID_TEVII_S650)},
1457 [TERRATEC_CINERGY_S] = {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)},
1458 [CYPRESS_DW3101] = {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW3101)},
1459 [TEVII_S630] = {USB_DEVICE(0x9022, USB_PID_TEVII_S630)},
1460 [PROF_1100] = {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
1461 [TEVII_S660] = {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
1462 [PROF_7500] = {USB_DEVICE(0x3034, 0x7500)},
1463 [GENIATECH_SU3000] = {USB_DEVICE(0x1f4d, 0x3000)},
1464 [TERRATEC_CINERGY_S2] = {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)},
1465 [TEVII_S480_1] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)},
1466 [TEVII_S480_2] = {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
1467 [X3M_SPC1400HD] = {USB_DEVICE(0x1f4d, 0x3100)},
1468 { }
1469};
1470
1471MODULE_DEVICE_TABLE(usb, dw2102_table);
1472
1473static int dw2102_load_firmware(struct usb_device *dev,
1474 const struct firmware *frmwr)
1475{
1476 u8 *b, *p;
1477 int ret = 0, i;
1478 u8 reset;
1479 u8 reset16[] = {0, 0, 0, 0, 0, 0, 0};
1480 const struct firmware *fw;
1481 const char *fw_2101 = "dvb-usb-dw2101.fw";
1482
1483 switch (dev->descriptor.idProduct) {
1484 case 0x2101:
1485 ret = request_firmware(&fw, fw_2101, &dev->dev);
1486 if (ret != 0) {
1487 err(err_str, fw_2101);
1488 return ret;
1489 }
1490 break;
1491 default:
1492 fw = frmwr;
1493 break;
1494 }
1495 info("start downloading DW210X firmware");
1496 p = kmalloc(fw->size, GFP_KERNEL);
1497 reset = 1;
1498 /*stop the CPU*/
1499 dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG);
1500 dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG);
1501
1502 if (p != NULL) {
1503 memcpy(p, fw->data, fw->size);
1504 for (i = 0; i < fw->size; i += 0x40) {
1505 b = (u8 *) p + i;
1506 if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40,
1507 DW210X_WRITE_MSG) != 0x40) {
1508 err("error while transferring firmware");
1509 ret = -EINVAL;
1510 break;
1511 }
1512 }
1513 /* restart the CPU */
1514 reset = 0;
1515 if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1,
1516 DW210X_WRITE_MSG) != 1) {
1517 err("could not restart the USB controller CPU.");
1518 ret = -EINVAL;
1519 }
1520 if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1,
1521 DW210X_WRITE_MSG) != 1) {
1522 err("could not restart the USB controller CPU.");
1523 ret = -EINVAL;
1524 }
1525 /* init registers */
1526 switch (dev->descriptor.idProduct) {
1527 case USB_PID_TEVII_S650:
1528 dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table;
1529 dw2104_properties.rc.legacy.rc_map_size =
1530 ARRAY_SIZE(rc_map_tevii_table);
1531 case USB_PID_DW2104:
1532 reset = 1;
1533 dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1,
1534 DW210X_WRITE_MSG);
1535 /* break omitted intentionally */
1536 case USB_PID_DW3101:
1537 reset = 0;
1538 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
1539 DW210X_WRITE_MSG);
1540 break;
1541 case USB_PID_CINERGY_S:
1542 case USB_PID_DW2102:
1543 dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0,
1544 DW210X_WRITE_MSG);
1545 dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
1546 DW210X_READ_MSG);
1547 /* check STV0299 frontend */
1548 dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2,
1549 DW210X_READ_MSG);
1550 if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) {
1551 dw2102_properties.i2c_algo = &dw2102_i2c_algo;
1552 dw2102_properties.adapter->fe[0].tuner_attach = &dw2102_tuner_attach;
1553 break;
1554 } else {
1555 /* check STV0288 frontend */
1556 reset16[0] = 0xd0;
1557 reset16[1] = 1;
1558 reset16[2] = 0;
1559 dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3,
1560 DW210X_WRITE_MSG);
1561 dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3,
1562 DW210X_READ_MSG);
1563 if (reset16[2] == 0x11) {
1564 dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo;
1565 break;
1566 }
1567 }
1568 case 0x2101:
1569 dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2,
1570 DW210X_READ_MSG);
1571 dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
1572 DW210X_READ_MSG);
1573 dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7,
1574 DW210X_READ_MSG);
1575 dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2,
1576 DW210X_READ_MSG);
1577 break;
1578 }
1579
1580 msleep(100);
1581 kfree(p);
1582 }
1583 return ret;
1584}
1585
1586static struct dvb_usb_device_properties dw2102_properties = {
1587 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1588 .usb_ctrl = DEVICE_SPECIFIC,
1589 .firmware = "dvb-usb-dw2102.fw",
1590 .no_reconnect = 1,
1591
1592 .i2c_algo = &dw2102_serit_i2c_algo,
1593
1594 .rc.legacy = {
1595 .rc_map_table = rc_map_dw210x_table,
1596 .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
1597 .rc_interval = 150,
1598 .rc_query = dw2102_rc_query,
1599 },
1600
1601 .generic_bulk_ctrl_endpoint = 0x81,
1602 /* parameter for the MPEG2-data transfer */
1603 .num_adapters = 1,
1604 .download_firmware = dw2102_load_firmware,
1605 .read_mac_address = dw210x_read_mac_address,
1606 .adapter = {
1607 {
1608 .num_frontends = 1,
1609 .fe = {{
1610 .frontend_attach = dw2102_frontend_attach,
1611 .stream = {
1612 .type = USB_BULK,
1613 .count = 8,
1614 .endpoint = 0x82,
1615 .u = {
1616 .bulk = {
1617 .buffersize = 4096,
1618 }
1619 }
1620 },
1621 }},
1622 }
1623 },
1624 .num_device_descs = 3,
1625 .devices = {
1626 {"DVBWorld DVB-S 2102 USB2.0",
1627 {&dw2102_table[CYPRESS_DW2102], NULL},
1628 {NULL},
1629 },
1630 {"DVBWorld DVB-S 2101 USB2.0",
1631 {&dw2102_table[CYPRESS_DW2101], NULL},
1632 {NULL},
1633 },
1634 {"TerraTec Cinergy S USB",
1635 {&dw2102_table[TERRATEC_CINERGY_S], NULL},
1636 {NULL},
1637 },
1638 }
1639};
1640
1641static struct dvb_usb_device_properties dw2104_properties = {
1642 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1643 .usb_ctrl = DEVICE_SPECIFIC,
1644 .firmware = "dvb-usb-dw2104.fw",
1645 .no_reconnect = 1,
1646
1647 .i2c_algo = &dw2104_i2c_algo,
1648 .rc.legacy = {
1649 .rc_map_table = rc_map_dw210x_table,
1650 .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
1651 .rc_interval = 150,
1652 .rc_query = dw2102_rc_query,
1653 },
1654
1655 .generic_bulk_ctrl_endpoint = 0x81,
1656 /* parameter for the MPEG2-data transfer */
1657 .num_adapters = 1,
1658 .download_firmware = dw2102_load_firmware,
1659 .read_mac_address = dw210x_read_mac_address,
1660 .adapter = {
1661 {
1662 .num_frontends = 1,
1663 .fe = {{
1664 .frontend_attach = dw2104_frontend_attach,
1665 .stream = {
1666 .type = USB_BULK,
1667 .count = 8,
1668 .endpoint = 0x82,
1669 .u = {
1670 .bulk = {
1671 .buffersize = 4096,
1672 }
1673 }
1674 },
1675 }},
1676 }
1677 },
1678 .num_device_descs = 2,
1679 .devices = {
1680 { "DVBWorld DW2104 USB2.0",
1681 {&dw2102_table[CYPRESS_DW2104], NULL},
1682 {NULL},
1683 },
1684 { "TeVii S650 USB2.0",
1685 {&dw2102_table[TEVII_S650], NULL},
1686 {NULL},
1687 },
1688 }
1689};
1690
1691static struct dvb_usb_device_properties dw3101_properties = {
1692 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1693 .usb_ctrl = DEVICE_SPECIFIC,
1694 .firmware = "dvb-usb-dw3101.fw",
1695 .no_reconnect = 1,
1696
1697 .i2c_algo = &dw3101_i2c_algo,
1698 .rc.legacy = {
1699 .rc_map_table = rc_map_dw210x_table,
1700 .rc_map_size = ARRAY_SIZE(rc_map_dw210x_table),
1701 .rc_interval = 150,
1702 .rc_query = dw2102_rc_query,
1703 },
1704
1705 .generic_bulk_ctrl_endpoint = 0x81,
1706 /* parameter for the MPEG2-data transfer */
1707 .num_adapters = 1,
1708 .download_firmware = dw2102_load_firmware,
1709 .read_mac_address = dw210x_read_mac_address,
1710 .adapter = {
1711 {
1712 .num_frontends = 1,
1713 .fe = {{
1714 .frontend_attach = dw3101_frontend_attach,
1715 .tuner_attach = dw3101_tuner_attach,
1716 .stream = {
1717 .type = USB_BULK,
1718 .count = 8,
1719 .endpoint = 0x82,
1720 .u = {
1721 .bulk = {
1722 .buffersize = 4096,
1723 }
1724 }
1725 },
1726 }},
1727 }
1728 },
1729 .num_device_descs = 1,
1730 .devices = {
1731 { "DVBWorld DVB-C 3101 USB2.0",
1732 {&dw2102_table[CYPRESS_DW3101], NULL},
1733 {NULL},
1734 },
1735 }
1736};
1737
1738static struct dvb_usb_device_properties s6x0_properties = {
1739 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1740 .usb_ctrl = DEVICE_SPECIFIC,
1741 .size_of_priv = sizeof(struct s6x0_state),
1742 .firmware = "dvb-usb-s630.fw",
1743 .no_reconnect = 1,
1744
1745 .i2c_algo = &s6x0_i2c_algo,
1746 .rc.legacy = {
1747 .rc_map_table = rc_map_tevii_table,
1748 .rc_map_size = ARRAY_SIZE(rc_map_tevii_table),
1749 .rc_interval = 150,
1750 .rc_query = dw2102_rc_query,
1751 },
1752
1753 .generic_bulk_ctrl_endpoint = 0x81,
1754 .num_adapters = 1,
1755 .download_firmware = dw2102_load_firmware,
1756 .read_mac_address = s6x0_read_mac_address,
1757 .adapter = {
1758 {
1759 .num_frontends = 1,
1760 .fe = {{
1761 .frontend_attach = zl100313_frontend_attach,
1762 .stream = {
1763 .type = USB_BULK,
1764 .count = 8,
1765 .endpoint = 0x82,
1766 .u = {
1767 .bulk = {
1768 .buffersize = 4096,
1769 }
1770 }
1771 },
1772 }},
1773 }
1774 },
1775 .num_device_descs = 1,
1776 .devices = {
1777 {"TeVii S630 USB",
1778 {&dw2102_table[TEVII_S630], NULL},
1779 {NULL},
1780 },
1781 }
1782};
1783
1784struct dvb_usb_device_properties *p1100;
1785static struct dvb_usb_device_description d1100 = {
1786 "Prof 1100 USB ",
1787 {&dw2102_table[PROF_1100], NULL},
1788 {NULL},
1789};
1790
1791struct dvb_usb_device_properties *s660;
1792static struct dvb_usb_device_description d660 = {
1793 "TeVii S660 USB",
1794 {&dw2102_table[TEVII_S660], NULL},
1795 {NULL},
1796};
1797
1798static struct dvb_usb_device_description d480_1 = {
1799 "TeVii S480.1 USB",
1800 {&dw2102_table[TEVII_S480_1], NULL},
1801 {NULL},
1802};
1803
1804static struct dvb_usb_device_description d480_2 = {
1805 "TeVii S480.2 USB",
1806 {&dw2102_table[TEVII_S480_2], NULL},
1807 {NULL},
1808};
1809
1810struct dvb_usb_device_properties *p7500;
1811static struct dvb_usb_device_description d7500 = {
1812 "Prof 7500 USB DVB-S2",
1813 {&dw2102_table[PROF_7500], NULL},
1814 {NULL},
1815};
1816
1817static struct dvb_usb_device_properties su3000_properties = {
1818 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1819 .usb_ctrl = DEVICE_SPECIFIC,
1820 .size_of_priv = sizeof(struct su3000_state),
1821 .power_ctrl = su3000_power_ctrl,
1822 .num_adapters = 1,
1823 .identify_state = su3000_identify_state,
1824 .i2c_algo = &su3000_i2c_algo,
1825
1826 .rc.legacy = {
1827 .rc_map_table = rc_map_su3000_table,
1828 .rc_map_size = ARRAY_SIZE(rc_map_su3000_table),
1829 .rc_interval = 150,
1830 .rc_query = dw2102_rc_query,
1831 },
1832
1833 .read_mac_address = su3000_read_mac_address,
1834
1835 .generic_bulk_ctrl_endpoint = 0x01,
1836
1837 .adapter = {
1838 {
1839 .num_frontends = 1,
1840 .fe = {{
1841 .streaming_ctrl = su3000_streaming_ctrl,
1842 .frontend_attach = su3000_frontend_attach,
1843 .stream = {
1844 .type = USB_BULK,
1845 .count = 8,
1846 .endpoint = 0x82,
1847 .u = {
1848 .bulk = {
1849 .buffersize = 4096,
1850 }
1851 }
1852 }
1853 }},
1854 }
1855 },
1856 .num_device_descs = 3,
1857 .devices = {
1858 { "SU3000HD DVB-S USB2.0",
1859 { &dw2102_table[GENIATECH_SU3000], NULL },
1860 { NULL },
1861 },
1862 { "Terratec Cinergy S2 USB HD",
1863 { &dw2102_table[TERRATEC_CINERGY_S2], NULL },
1864 { NULL },
1865 },
1866 { "X3M TV SPC1400HD PCI",
1867 { &dw2102_table[X3M_SPC1400HD], NULL },
1868 { NULL },
1869 },
1870 }
1871};
1872
1873static int dw2102_probe(struct usb_interface *intf,
1874 const struct usb_device_id *id)
1875{
1876 p1100 = kmemdup(&s6x0_properties,
1877 sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1878 if (!p1100)
1879 return -ENOMEM;
1880 /* copy default structure */
1881 /* fill only different fields */
1882 p1100->firmware = "dvb-usb-p1100.fw";
1883 p1100->devices[0] = d1100;
1884 p1100->rc.legacy.rc_map_table = rc_map_tbs_table;
1885 p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
1886 p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach;
1887
1888 s660 = kmemdup(&s6x0_properties,
1889 sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1890 if (!s660) {
1891 kfree(p1100);
1892 return -ENOMEM;
1893 }
1894 s660->firmware = "dvb-usb-s660.fw";
1895 s660->num_device_descs = 3;
1896 s660->devices[0] = d660;
1897 s660->devices[1] = d480_1;
1898 s660->devices[2] = d480_2;
1899 s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach;
1900
1901 p7500 = kmemdup(&s6x0_properties,
1902 sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1903 if (!p7500) {
1904 kfree(p1100);
1905 kfree(s660);
1906 return -ENOMEM;
1907 }
1908 p7500->firmware = "dvb-usb-p7500.fw";
1909 p7500->devices[0] = d7500;
1910 p7500->rc.legacy.rc_map_table = rc_map_tbs_table;
1911 p7500->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
1912 p7500->adapter->fe[0].frontend_attach = prof_7500_frontend_attach;
1913
1914 if (0 == dvb_usb_device_init(intf, &dw2102_properties,
1915 THIS_MODULE, NULL, adapter_nr) ||
1916 0 == dvb_usb_device_init(intf, &dw2104_properties,
1917 THIS_MODULE, NULL, adapter_nr) ||
1918 0 == dvb_usb_device_init(intf, &dw3101_properties,
1919 THIS_MODULE, NULL, adapter_nr) ||
1920 0 == dvb_usb_device_init(intf, &s6x0_properties,
1921 THIS_MODULE, NULL, adapter_nr) ||
1922 0 == dvb_usb_device_init(intf, p1100,
1923 THIS_MODULE, NULL, adapter_nr) ||
1924 0 == dvb_usb_device_init(intf, s660,
1925 THIS_MODULE, NULL, adapter_nr) ||
1926 0 == dvb_usb_device_init(intf, p7500,
1927 THIS_MODULE, NULL, adapter_nr) ||
1928 0 == dvb_usb_device_init(intf, &su3000_properties,
1929 THIS_MODULE, NULL, adapter_nr))
1930 return 0;
1931
1932 return -ENODEV;
1933}
1934
1935static struct usb_driver dw2102_driver = {
1936 .name = "dw2102",
1937 .probe = dw2102_probe,
1938 .disconnect = dvb_usb_device_exit,
1939 .id_table = dw2102_table,
1940};
1941
1942module_usb_driver(dw2102_driver);
1943
1944MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
1945MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
1946 " DVB-C 3101 USB2.0,"
1947 " TeVii S600, S630, S650, S660, S480,"
1948 " Prof 1100, 7500 USB2.0,"
1949 " Geniatech SU3000 devices");
1950MODULE_VERSION("0.1");
1951MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/dw2102.h b/drivers/media/usb/dvb-usb/dw2102.h
new file mode 100644
index 000000000000..5cd0b0eb6ce1
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/dw2102.h
@@ -0,0 +1,9 @@
1#ifndef _DW2102_H_
2#define _DW2102_H_
3
4#define DVB_USB_LOG_PREFIX "dw2102"
5#include "dvb-usb.h"
6
7#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args)
8#define deb_rc(args...) dprintk(dvb_usb_dw2102_debug, 0x04, args)
9#endif
diff --git a/drivers/media/usb/dvb-usb/friio-fe.c b/drivers/media/usb/dvb-usb/friio-fe.c
new file mode 100644
index 000000000000..90a70c66a96e
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/friio-fe.c
@@ -0,0 +1,473 @@
1/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
2 *
3 * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
4 *
5 * This module is based off the the gl861 and vp702x modules.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation, version 2.
10 *
11 * see Documentation/dvb/README.dvb-usb for more information
12 */
13#include <linux/init.h>
14#include <linux/string.h>
15#include <linux/slab.h>
16
17#include "friio.h"
18
19struct jdvbt90502_state {
20 struct i2c_adapter *i2c;
21 struct dvb_frontend frontend;
22 struct jdvbt90502_config config;
23};
24
25/* NOTE: TC90502 has 16bit register-address? */
26/* register 0x0100 is used for reading PLL status, so reg is u16 here */
27static int jdvbt90502_reg_read(struct jdvbt90502_state *state,
28 const u16 reg, u8 *buf, const size_t count)
29{
30 int ret;
31 u8 wbuf[3];
32 struct i2c_msg msg[2];
33
34 wbuf[0] = reg & 0xFF;
35 wbuf[1] = 0;
36 wbuf[2] = reg >> 8;
37
38 msg[0].addr = state->config.demod_address;
39 msg[0].flags = 0;
40 msg[0].buf = wbuf;
41 msg[0].len = sizeof(wbuf);
42
43 msg[1].addr = msg[0].addr;
44 msg[1].flags = I2C_M_RD;
45 msg[1].buf = buf;
46 msg[1].len = count;
47
48 ret = i2c_transfer(state->i2c, msg, 2);
49 if (ret != 2) {
50 deb_fe(" reg read failed.\n");
51 return -EREMOTEIO;
52 }
53 return 0;
54}
55
56/* currently 16bit register-address is not used, so reg is u8 here */
57static int jdvbt90502_single_reg_write(struct jdvbt90502_state *state,
58 const u8 reg, const u8 val)
59{
60 struct i2c_msg msg;
61 u8 wbuf[2];
62
63 wbuf[0] = reg;
64 wbuf[1] = val;
65
66 msg.addr = state->config.demod_address;
67 msg.flags = 0;
68 msg.buf = wbuf;
69 msg.len = sizeof(wbuf);
70
71 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
72 deb_fe(" reg write failed.");
73 return -EREMOTEIO;
74 }
75 return 0;
76}
77
78static int _jdvbt90502_write(struct dvb_frontend *fe, const u8 buf[], int len)
79{
80 struct jdvbt90502_state *state = fe->demodulator_priv;
81 int err, i;
82 for (i = 0; i < len - 1; i++) {
83 err = jdvbt90502_single_reg_write(state,
84 buf[0] + i, buf[i + 1]);
85 if (err)
86 return err;
87 }
88
89 return 0;
90}
91
92/* read pll status byte via the demodulator's I2C register */
93/* note: Win box reads it by 8B block at the I2C addr 0x30 from reg:0x80 */
94static int jdvbt90502_pll_read(struct jdvbt90502_state *state, u8 *result)
95{
96 int ret;
97
98 /* +1 for reading */
99 u8 pll_addr_byte = (state->config.pll_address << 1) + 1;
100
101 *result = 0;
102
103 ret = jdvbt90502_single_reg_write(state, JDVBT90502_2ND_I2C_REG,
104 pll_addr_byte);
105 if (ret)
106 goto error;
107
108 ret = jdvbt90502_reg_read(state, 0x0100, result, 1);
109 if (ret)
110 goto error;
111
112 deb_fe("PLL read val:%02x\n", *result);
113 return 0;
114
115error:
116 deb_fe("%s:ret == %d\n", __func__, ret);
117 return -EREMOTEIO;
118}
119
120
121/* set pll frequency via the demodulator's I2C register */
122static int jdvbt90502_pll_set_freq(struct jdvbt90502_state *state, u32 freq)
123{
124 int ret;
125 int retry;
126 u8 res1;
127 u8 res2[9];
128
129 u8 pll_freq_cmd[PLL_CMD_LEN];
130 u8 pll_agc_cmd[PLL_CMD_LEN];
131 struct i2c_msg msg[2];
132 u32 f;
133
134 deb_fe("%s: freq=%d, step=%d\n", __func__, freq,
135 state->frontend.ops.info.frequency_stepsize);
136 /* freq -> oscilator frequency conversion. */
137 /* freq: 473,000,000 + n*6,000,000 [+ 142857 (center freq. shift)] */
138 f = freq / state->frontend.ops.info.frequency_stepsize;
139 /* add 399[1/7 MHZ] = 57MHz for the IF */
140 f += 399;
141 /* add center frequency shift if necessary */
142 if (f % 7 == 0)
143 f++;
144 pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */
145 pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1;
146 pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F;
147 pll_freq_cmd[DIVIDER_BYTE2] = f & 0xFF;
148 pll_freq_cmd[CONTROL_BYTE] = 0xB2; /* ref.divider:28, 4MHz/28=1/7MHz */
149 pll_freq_cmd[BANDSWITCH_BYTE] = 0x08; /* UHF band */
150
151 msg[0].addr = state->config.demod_address;
152 msg[0].flags = 0;
153 msg[0].buf = pll_freq_cmd;
154 msg[0].len = sizeof(pll_freq_cmd);
155
156 ret = i2c_transfer(state->i2c, &msg[0], 1);
157 if (ret != 1)
158 goto error;
159
160 udelay(50);
161
162 pll_agc_cmd[DEMOD_REDIRECT_REG] = pll_freq_cmd[DEMOD_REDIRECT_REG];
163 pll_agc_cmd[ADDRESS_BYTE] = pll_freq_cmd[ADDRESS_BYTE];
164 pll_agc_cmd[DIVIDER_BYTE1] = pll_freq_cmd[DIVIDER_BYTE1];
165 pll_agc_cmd[DIVIDER_BYTE2] = pll_freq_cmd[DIVIDER_BYTE2];
166 pll_agc_cmd[CONTROL_BYTE] = 0x9A; /* AGC_CTRL instead of BANDSWITCH */
167 pll_agc_cmd[AGC_CTRL_BYTE] = 0x50;
168 /* AGC Time Constant 2s, AGC take-over point:103dBuV(lowest) */
169
170 msg[1].addr = msg[0].addr;
171 msg[1].flags = 0;
172 msg[1].buf = pll_agc_cmd;
173 msg[1].len = sizeof(pll_agc_cmd);
174
175 ret = i2c_transfer(state->i2c, &msg[1], 1);
176 if (ret != 1)
177 goto error;
178
179 /* I don't know what these cmds are for, */
180 /* but the USB log on a windows box contains them */
181 ret = jdvbt90502_single_reg_write(state, 0x01, 0x40);
182 ret |= jdvbt90502_single_reg_write(state, 0x01, 0x00);
183 if (ret)
184 goto error;
185 udelay(100);
186
187 /* wait for the demod to be ready? */
188#define RETRY_COUNT 5
189 for (retry = 0; retry < RETRY_COUNT; retry++) {
190 ret = jdvbt90502_reg_read(state, 0x0096, &res1, 1);
191 if (ret)
192 goto error;
193 /* if (res1 != 0x00) goto error; */
194 ret = jdvbt90502_reg_read(state, 0x00B0, res2, sizeof(res2));
195 if (ret)
196 goto error;
197 if (res2[0] >= 0xA7)
198 break;
199 msleep(100);
200 }
201 if (retry >= RETRY_COUNT) {
202 deb_fe("%s: FE does not get ready after freq setting.\n",
203 __func__);
204 return -EREMOTEIO;
205 }
206
207 return 0;
208error:
209 deb_fe("%s:ret == %d\n", __func__, ret);
210 return -EREMOTEIO;
211}
212
213static int jdvbt90502_read_status(struct dvb_frontend *fe, fe_status_t *state)
214{
215 u8 result;
216 int ret;
217
218 *state = FE_HAS_SIGNAL;
219
220 ret = jdvbt90502_pll_read(fe->demodulator_priv, &result);
221 if (ret) {
222 deb_fe("%s:ret == %d\n", __func__, ret);
223 return -EREMOTEIO;
224 }
225
226 *state = FE_HAS_SIGNAL
227 | FE_HAS_CARRIER
228 | FE_HAS_VITERBI
229 | FE_HAS_SYNC;
230
231 if (result & PLL_STATUS_LOCKED)
232 *state |= FE_HAS_LOCK;
233
234 return 0;
235}
236
237static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe,
238 u16 *strength)
239{
240 int ret;
241 u8 rbuf[37];
242
243 *strength = 0;
244
245 /* status register (incl. signal strength) : 0x89 */
246 /* TODO: read just the necessary registers [0x8B..0x8D]? */
247 ret = jdvbt90502_reg_read(fe->demodulator_priv, 0x0089,
248 rbuf, sizeof(rbuf));
249
250 if (ret) {
251 deb_fe("%s:ret == %d\n", __func__, ret);
252 return -EREMOTEIO;
253 }
254
255 /* signal_strength: rbuf[2-4] (24bit BE), use lower 16bit for now. */
256 *strength = (rbuf[3] << 8) + rbuf[4];
257 if (rbuf[2])
258 *strength = 0xffff;
259
260 return 0;
261}
262
263
264/* filter out un-supported properties to notify users */
265static int jdvbt90502_set_property(struct dvb_frontend *fe,
266 struct dtv_property *tvp)
267{
268 int r = 0;
269
270 switch (tvp->cmd) {
271 case DTV_DELIVERY_SYSTEM:
272 if (tvp->u.data != SYS_ISDBT)
273 r = -EINVAL;
274 break;
275 case DTV_CLEAR:
276 case DTV_TUNE:
277 case DTV_FREQUENCY:
278 break;
279 default:
280 r = -EINVAL;
281 }
282 return r;
283}
284
285static int jdvbt90502_get_frontend(struct dvb_frontend *fe)
286{
287 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
288 p->inversion = INVERSION_AUTO;
289 p->bandwidth_hz = 6000000;
290 p->code_rate_HP = FEC_AUTO;
291 p->code_rate_LP = FEC_AUTO;
292 p->modulation = QAM_64;
293 p->transmission_mode = TRANSMISSION_MODE_AUTO;
294 p->guard_interval = GUARD_INTERVAL_AUTO;
295 p->hierarchy = HIERARCHY_AUTO;
296 return 0;
297}
298
299static int jdvbt90502_set_frontend(struct dvb_frontend *fe)
300{
301 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
302
303 /**
304 * NOTE: ignore all the parameters except frequency.
305 * others should be fixed to the proper value for ISDB-T,
306 * but don't check here.
307 */
308
309 struct jdvbt90502_state *state = fe->demodulator_priv;
310 int ret;
311
312 deb_fe("%s: Freq:%d\n", __func__, p->frequency);
313
314 /* for recovery from DTV_CLEAN */
315 fe->dtv_property_cache.delivery_system = SYS_ISDBT;
316
317 ret = jdvbt90502_pll_set_freq(state, p->frequency);
318 if (ret) {
319 deb_fe("%s:ret == %d\n", __func__, ret);
320 return -EREMOTEIO;
321 }
322
323 return 0;
324}
325
326
327/**
328 * (reg, val) commad list to initialize this module.
329 * captured on a Windows box.
330 */
331static u8 init_code[][2] = {
332 {0x01, 0x40},
333 {0x04, 0x38},
334 {0x05, 0x40},
335 {0x07, 0x40},
336 {0x0F, 0x4F},
337 {0x11, 0x21},
338 {0x12, 0x0B},
339 {0x13, 0x2F},
340 {0x14, 0x31},
341 {0x16, 0x02},
342 {0x21, 0xC4},
343 {0x22, 0x20},
344 {0x2C, 0x79},
345 {0x2D, 0x34},
346 {0x2F, 0x00},
347 {0x30, 0x28},
348 {0x31, 0x31},
349 {0x32, 0xDF},
350 {0x38, 0x01},
351 {0x39, 0x78},
352 {0x3B, 0x33},
353 {0x3C, 0x33},
354 {0x48, 0x90},
355 {0x51, 0x68},
356 {0x5E, 0x38},
357 {0x71, 0x00},
358 {0x72, 0x08},
359 {0x77, 0x00},
360 {0xC0, 0x21},
361 {0xC1, 0x10},
362 {0xE4, 0x1A},
363 {0xEA, 0x1F},
364 {0x77, 0x00},
365 {0x71, 0x00},
366 {0x71, 0x00},
367 {0x76, 0x0C},
368};
369
370static const int init_code_len = sizeof(init_code) / sizeof(u8[2]);
371
372static int jdvbt90502_init(struct dvb_frontend *fe)
373{
374 int i = -1;
375 int ret;
376 struct i2c_msg msg;
377
378 struct jdvbt90502_state *state = fe->demodulator_priv;
379
380 deb_fe("%s called.\n", __func__);
381
382 msg.addr = state->config.demod_address;
383 msg.flags = 0;
384 msg.len = 2;
385 for (i = 0; i < init_code_len; i++) {
386 msg.buf = init_code[i];
387 ret = i2c_transfer(state->i2c, &msg, 1);
388 if (ret != 1)
389 goto error;
390 }
391 fe->dtv_property_cache.delivery_system = SYS_ISDBT;
392 msleep(100);
393
394 return 0;
395
396error:
397 deb_fe("%s: init_code[%d] failed. ret==%d\n", __func__, i, ret);
398 return -EREMOTEIO;
399}
400
401
402static void jdvbt90502_release(struct dvb_frontend *fe)
403{
404 struct jdvbt90502_state *state = fe->demodulator_priv;
405 kfree(state);
406}
407
408
409static struct dvb_frontend_ops jdvbt90502_ops;
410
411struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d)
412{
413 struct jdvbt90502_state *state = NULL;
414
415 deb_info("%s called.\n", __func__);
416
417 /* allocate memory for the internal state */
418 state = kzalloc(sizeof(struct jdvbt90502_state), GFP_KERNEL);
419 if (state == NULL)
420 goto error;
421
422 /* setup the state */
423 state->i2c = &d->i2c_adap;
424 memcpy(&state->config, &friio_fe_config, sizeof(friio_fe_config));
425
426 /* create dvb_frontend */
427 memcpy(&state->frontend.ops, &jdvbt90502_ops,
428 sizeof(jdvbt90502_ops));
429 state->frontend.demodulator_priv = state;
430
431 if (jdvbt90502_init(&state->frontend) < 0)
432 goto error;
433
434 return &state->frontend;
435
436error:
437 kfree(state);
438 return NULL;
439}
440
441static struct dvb_frontend_ops jdvbt90502_ops = {
442 .delsys = { SYS_ISDBT },
443 .info = {
444 .name = "Comtech JDVBT90502 ISDB-T",
445 .frequency_min = 473000000, /* UHF 13ch, center */
446 .frequency_max = 767142857, /* UHF 62ch, center */
447 .frequency_stepsize = JDVBT90502_PLL_CLK / JDVBT90502_PLL_DIVIDER,
448 .frequency_tolerance = 0,
449
450 /* NOTE: this driver ignores all parameters but frequency. */
451 .caps = FE_CAN_INVERSION_AUTO |
452 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
453 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
454 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
455 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
456 FE_CAN_TRANSMISSION_MODE_AUTO |
457 FE_CAN_GUARD_INTERVAL_AUTO |
458 FE_CAN_HIERARCHY_AUTO,
459 },
460
461 .release = jdvbt90502_release,
462
463 .init = jdvbt90502_init,
464 .write = _jdvbt90502_write,
465
466 .set_property = jdvbt90502_set_property,
467
468 .set_frontend = jdvbt90502_set_frontend,
469 .get_frontend = jdvbt90502_get_frontend,
470
471 .read_status = jdvbt90502_read_status,
472 .read_signal_strength = jdvbt90502_read_signal_strength,
473};
diff --git a/drivers/media/usb/dvb-usb/friio.c b/drivers/media/usb/dvb-usb/friio.c
new file mode 100644
index 000000000000..474a17e4db0c
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/friio.c
@@ -0,0 +1,522 @@
1/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
2 *
3 * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
4 *
5 * This module is based off the the gl861 and vp702x modules.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation, version 2.
10 *
11 * see Documentation/dvb/README.dvb-usb for more information
12 */
13#include "friio.h"
14
15/* debug */
16int dvb_usb_friio_debug;
17module_param_named(debug, dvb_usb_friio_debug, int, 0644);
18MODULE_PARM_DESC(debug,
19 "set debugging level (1=info,2=xfer,4=rc,8=fe (or-able))."
20 DVB_USB_DEBUG_STATUS);
21
22DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
23
24/**
25 * Indirect I2C access to the PLL via FE.
26 * whole I2C protocol data to the PLL is sent via the FE's I2C register.
27 * This is done by a control msg to the FE with the I2C data accompanied, and
28 * a specific USB request number is assigned for that purpose.
29 *
30 * this func sends wbuf[1..] to the I2C register wbuf[0] at addr (= at FE).
31 * TODO: refoctored, smarter i2c functions.
32 */
33static int gl861_i2c_ctrlmsg_data(struct dvb_usb_device *d, u8 addr,
34 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
35{
36 u16 index = wbuf[0]; /* must be JDVBT90502_2ND_I2C_REG(=0xFE) */
37 u16 value = addr << (8 + 1);
38 int wo = (rbuf == NULL || rlen == 0); /* write only */
39 u8 req, type;
40
41 deb_xfer("write to PLL:0x%02x via FE reg:0x%02x, len:%d\n",
42 wbuf[1], wbuf[0], wlen - 1);
43
44 if (wo && wlen >= 2) {
45 req = GL861_REQ_I2C_DATA_CTRL_WRITE;
46 type = GL861_WRITE;
47 udelay(20);
48 return usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
49 req, type, value, index,
50 &wbuf[1], wlen - 1, 2000);
51 }
52
53 deb_xfer("not supported ctrl-msg, aborting.");
54 return -EINVAL;
55}
56
57/* normal I2C access (without extra data arguments).
58 * write to the register wbuf[0] at I2C address addr with the value wbuf[1],
59 * or read from the register wbuf[0].
60 * register address can be 16bit (wbuf[2]<<8 | wbuf[0]) if wlen==3
61 */
62static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
63 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
64{
65 u16 index;
66 u16 value = addr << (8 + 1);
67 int wo = (rbuf == NULL || rlen == 0); /* write-only */
68 u8 req, type;
69 unsigned int pipe;
70
71 /* special case for the indirect I2C access to the PLL via FE, */
72 if (addr == friio_fe_config.demod_address &&
73 wbuf[0] == JDVBT90502_2ND_I2C_REG)
74 return gl861_i2c_ctrlmsg_data(d, addr, wbuf, wlen, rbuf, rlen);
75
76 if (wo) {
77 req = GL861_REQ_I2C_WRITE;
78 type = GL861_WRITE;
79 pipe = usb_sndctrlpipe(d->udev, 0);
80 } else { /* rw */
81 req = GL861_REQ_I2C_READ;
82 type = GL861_READ;
83 pipe = usb_rcvctrlpipe(d->udev, 0);
84 }
85
86 switch (wlen) {
87 case 1:
88 index = wbuf[0];
89 break;
90 case 2:
91 index = wbuf[0];
92 value = value + wbuf[1];
93 break;
94 case 3:
95 /* special case for 16bit register-address */
96 index = (wbuf[2] << 8) | wbuf[0];
97 value = value + wbuf[1];
98 break;
99 default:
100 deb_xfer("wlen = %x, aborting.", wlen);
101 return -EINVAL;
102 }
103 msleep(1);
104 return usb_control_msg(d->udev, pipe, req, type,
105 value, index, rbuf, rlen, 2000);
106}
107
108/* I2C */
109static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
110 int num)
111{
112 struct dvb_usb_device *d = i2c_get_adapdata(adap);
113 int i;
114
115
116 if (num > 2)
117 return -EINVAL;
118
119 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
120 return -EAGAIN;
121
122 for (i = 0; i < num; i++) {
123 /* write/read request */
124 if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
125 if (gl861_i2c_msg(d, msg[i].addr,
126 msg[i].buf, msg[i].len,
127 msg[i + 1].buf, msg[i + 1].len) < 0)
128 break;
129 i++;
130 } else
131 if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
132 msg[i].len, NULL, 0) < 0)
133 break;
134 }
135
136 mutex_unlock(&d->i2c_mutex);
137 return i;
138}
139
140static u32 gl861_i2c_func(struct i2c_adapter *adapter)
141{
142 return I2C_FUNC_I2C;
143}
144
145static int friio_ext_ctl(struct dvb_usb_adapter *adap,
146 u32 sat_color, int lnb_on)
147{
148 int i;
149 int ret;
150 struct i2c_msg msg;
151 u8 *buf;
152 u32 mask;
153 u8 lnb = (lnb_on) ? FRIIO_CTL_LNB : 0;
154
155 buf = kmalloc(2, GFP_KERNEL);
156 if (!buf)
157 return -ENOMEM;
158
159 msg.addr = 0x00;
160 msg.flags = 0;
161 msg.len = 2;
162 msg.buf = buf;
163
164 buf[0] = 0x00;
165
166 /* send 2bit header (&B10) */
167 buf[1] = lnb | FRIIO_CTL_LED | FRIIO_CTL_STROBE;
168 ret = gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
169 buf[1] |= FRIIO_CTL_CLK;
170 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
171
172 buf[1] = lnb | FRIIO_CTL_STROBE;
173 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
174 buf[1] |= FRIIO_CTL_CLK;
175 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
176
177 /* send 32bit(satur, R, G, B) data in serial */
178 mask = 1 << 31;
179 for (i = 0; i < 32; i++) {
180 buf[1] = lnb | FRIIO_CTL_STROBE;
181 if (sat_color & mask)
182 buf[1] |= FRIIO_CTL_LED;
183 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
184 buf[1] |= FRIIO_CTL_CLK;
185 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
186 mask >>= 1;
187 }
188
189 /* set the strobe off */
190 buf[1] = lnb;
191 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
192 buf[1] |= FRIIO_CTL_CLK;
193 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
194
195 kfree(buf);
196 return (ret == 70);
197}
198
199
200static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
201
202/* TODO: move these init cmds to the FE's init routine? */
203static u8 streaming_init_cmds[][2] = {
204 {0x33, 0x08},
205 {0x37, 0x40},
206 {0x3A, 0x1F},
207 {0x3B, 0xFF},
208 {0x3C, 0x1F},
209 {0x3D, 0xFF},
210 {0x38, 0x00},
211 {0x35, 0x00},
212 {0x39, 0x00},
213 {0x36, 0x00},
214};
215static int cmdlen = sizeof(streaming_init_cmds) / 2;
216
217/*
218 * Command sequence in this init function is a replay
219 * of the captured USB commands from the Windows proprietary driver.
220 */
221static int friio_initialize(struct dvb_usb_device *d)
222{
223 int ret;
224 int i;
225 int retry = 0;
226 u8 *rbuf, *wbuf;
227
228 deb_info("%s called.\n", __func__);
229
230 wbuf = kmalloc(3, GFP_KERNEL);
231 if (!wbuf)
232 return -ENOMEM;
233
234 rbuf = kmalloc(2, GFP_KERNEL);
235 if (!rbuf) {
236 kfree(wbuf);
237 return -ENOMEM;
238 }
239
240 /* use gl861_i2c_msg instead of gl861_i2c_xfer(), */
241 /* because the i2c device is not set up yet. */
242 wbuf[0] = 0x11;
243 wbuf[1] = 0x02;
244 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
245 if (ret < 0)
246 goto error;
247 msleep(2);
248
249 wbuf[0] = 0x11;
250 wbuf[1] = 0x00;
251 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
252 if (ret < 0)
253 goto error;
254 msleep(1);
255
256 /* following msgs should be in the FE's init code? */
257 /* cmd sequence to identify the device type? (friio black/white) */
258 wbuf[0] = 0x03;
259 wbuf[1] = 0x80;
260 /* can't use gl861_i2c_cmd, as the register-addr is 16bit(0x0100) */
261 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
262 GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
263 0x1200, 0x0100, wbuf, 2, 2000);
264 if (ret < 0)
265 goto error;
266
267 msleep(2);
268 wbuf[0] = 0x00;
269 wbuf[2] = 0x01; /* reg.0x0100 */
270 wbuf[1] = 0x00;
271 ret = gl861_i2c_msg(d, 0x12 >> 1, wbuf, 3, rbuf, 2);
272 /* my Friio White returns 0xffff. */
273 if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
274 goto error;
275
276 msleep(2);
277 wbuf[0] = 0x03;
278 wbuf[1] = 0x80;
279 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
280 GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
281 0x9000, 0x0100, wbuf, 2, 2000);
282 if (ret < 0)
283 goto error;
284
285 msleep(2);
286 wbuf[0] = 0x00;
287 wbuf[2] = 0x01; /* reg.0x0100 */
288 wbuf[1] = 0x00;
289 ret = gl861_i2c_msg(d, 0x90 >> 1, wbuf, 3, rbuf, 2);
290 /* my Friio White returns 0xffff again. */
291 if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
292 goto error;
293
294 msleep(1);
295
296restart:
297 /* ============ start DEMOD init cmds ================== */
298 /* read PLL status to clear the POR bit */
299 wbuf[0] = JDVBT90502_2ND_I2C_REG;
300 wbuf[1] = (FRIIO_PLL_ADDR << 1) + 1; /* +1 for reading */
301 ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, NULL, 0);
302 if (ret < 0)
303 goto error;
304
305 msleep(5);
306 /* note: DEMODULATOR has 16bit register-address. */
307 wbuf[0] = 0x00;
308 wbuf[2] = 0x01; /* reg addr: 0x0100 */
309 wbuf[1] = 0x00; /* val: not used */
310 ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 3, rbuf, 1);
311 if (ret < 0)
312 goto error;
313/*
314 msleep(1);
315 wbuf[0] = 0x80;
316 wbuf[1] = 0x00;
317 ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, rbuf, 1);
318 if (ret < 0)
319 goto error;
320 */
321 if (rbuf[0] & 0x80) { /* still in PowerOnReset state? */
322 if (++retry > 3) {
323 deb_info("failed to get the correct"
324 " FE demod status:0x%02x\n", rbuf[0]);
325 goto error;
326 }
327 msleep(100);
328 goto restart;
329 }
330
331 /* TODO: check return value in rbuf */
332 /* =========== end DEMOD init cmds ===================== */
333 msleep(1);
334
335 wbuf[0] = 0x30;
336 wbuf[1] = 0x04;
337 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
338 if (ret < 0)
339 goto error;
340
341 msleep(2);
342 /* following 2 cmds unnecessary? */
343 wbuf[0] = 0x00;
344 wbuf[1] = 0x01;
345 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
346 if (ret < 0)
347 goto error;
348
349 wbuf[0] = 0x06;
350 wbuf[1] = 0x0F;
351 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
352 if (ret < 0)
353 goto error;
354
355 /* some streaming ctl cmds (maybe) */
356 msleep(10);
357 for (i = 0; i < cmdlen; i++) {
358 ret = gl861_i2c_msg(d, 0x00, streaming_init_cmds[i], 2,
359 NULL, 0);
360 if (ret < 0)
361 goto error;
362 msleep(1);
363 }
364 msleep(20);
365
366 /* change the LED color etc. */
367 ret = friio_streaming_ctrl(&d->adapter[0], 0);
368 if (ret < 0)
369 goto error;
370
371 return 0;
372
373error:
374 kfree(wbuf);
375 kfree(rbuf);
376 deb_info("%s:ret == %d\n", __func__, ret);
377 return -EIO;
378}
379
380/* Callbacks for DVB USB */
381
382static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
383{
384 int ret;
385
386 deb_info("%s called.(%d)\n", __func__, onoff);
387
388 /* set the LED color and saturation (and LNB on) */
389 if (onoff)
390 ret = friio_ext_ctl(adap, 0x6400ff64, 1);
391 else
392 ret = friio_ext_ctl(adap, 0x96ff00ff, 1);
393
394 if (ret != 1) {
395 deb_info("%s failed to send cmdx. ret==%d\n", __func__, ret);
396 return -EREMOTEIO;
397 }
398 return 0;
399}
400
401static int friio_frontend_attach(struct dvb_usb_adapter *adap)
402{
403 if (friio_initialize(adap->dev) < 0)
404 return -EIO;
405
406 adap->fe_adap[0].fe = jdvbt90502_attach(adap->dev);
407 if (adap->fe_adap[0].fe == NULL)
408 return -EIO;
409
410 return 0;
411}
412
413/* DVB USB Driver stuff */
414static struct dvb_usb_device_properties friio_properties;
415
416static int friio_probe(struct usb_interface *intf,
417 const struct usb_device_id *id)
418{
419 struct dvb_usb_device *d;
420 struct usb_host_interface *alt;
421 int ret;
422
423 if (intf->num_altsetting < GL861_ALTSETTING_COUNT)
424 return -ENODEV;
425
426 alt = usb_altnum_to_altsetting(intf, FRIIO_BULK_ALTSETTING);
427 if (alt == NULL) {
428 deb_rc("not alt found!\n");
429 return -ENODEV;
430 }
431 ret = usb_set_interface(interface_to_usbdev(intf),
432 alt->desc.bInterfaceNumber,
433 alt->desc.bAlternateSetting);
434 if (ret != 0) {
435 deb_rc("failed to set alt-setting!\n");
436 return ret;
437 }
438
439 ret = dvb_usb_device_init(intf, &friio_properties,
440 THIS_MODULE, &d, adapter_nr);
441 if (ret == 0)
442 friio_streaming_ctrl(&d->adapter[0], 1);
443
444 return ret;
445}
446
447
448struct jdvbt90502_config friio_fe_config = {
449 .demod_address = FRIIO_DEMOD_ADDR,
450 .pll_address = FRIIO_PLL_ADDR,
451};
452
453static struct i2c_algorithm gl861_i2c_algo = {
454 .master_xfer = gl861_i2c_xfer,
455 .functionality = gl861_i2c_func,
456};
457
458static struct usb_device_id friio_table[] = {
459 { USB_DEVICE(USB_VID_774, USB_PID_FRIIO_WHITE) },
460 { } /* Terminating entry */
461};
462MODULE_DEVICE_TABLE(usb, friio_table);
463
464
465static struct dvb_usb_device_properties friio_properties = {
466 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
467 .usb_ctrl = DEVICE_SPECIFIC,
468
469 .size_of_priv = 0,
470
471 .num_adapters = 1,
472 .adapter = {
473 /* caps:0 => no pid filter, 188B TS packet */
474 /* GL861 has a HW pid filter, but no info available. */
475 {
476 .num_frontends = 1,
477 .fe = {{
478 .caps = 0,
479
480 .frontend_attach = friio_frontend_attach,
481 .streaming_ctrl = friio_streaming_ctrl,
482
483 .stream = {
484 .type = USB_BULK,
485 /* count <= MAX_NO_URBS_FOR_DATA_STREAM(10) */
486 .count = 8,
487 .endpoint = 0x01,
488 .u = {
489 /* GL861 has 6KB buf inside */
490 .bulk = {
491 .buffersize = 16384,
492 }
493 }
494 },
495 }},
496 }
497 },
498 .i2c_algo = &gl861_i2c_algo,
499
500 .num_device_descs = 1,
501 .devices = {
502 {
503 .name = "774 Friio ISDB-T USB2.0",
504 .cold_ids = { NULL },
505 .warm_ids = { &friio_table[0], NULL },
506 },
507 }
508};
509
510static struct usb_driver friio_driver = {
511 .name = "dvb_usb_friio",
512 .probe = friio_probe,
513 .disconnect = dvb_usb_device_exit,
514 .id_table = friio_table,
515};
516
517module_usb_driver(friio_driver);
518
519MODULE_AUTHOR("Akihiro Tsukada <tskd2@yahoo.co.jp>");
520MODULE_DESCRIPTION("Driver for Friio ISDB-T USB2.0 Receiver");
521MODULE_VERSION("0.2");
522MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/friio.h b/drivers/media/usb/dvb-usb/friio.h
new file mode 100644
index 000000000000..0f461ca10cb9
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/friio.h
@@ -0,0 +1,99 @@
1/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
2 *
3 * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
4 *
5 * This module is based off the the gl861 and vp702x modules.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation, version 2.
10 *
11 * see Documentation/dvb/README.dvb-usb for more information
12 */
13#ifndef _DVB_USB_FRIIO_H_
14#define _DVB_USB_FRIIO_H_
15
16/**
17 * Friio Components
18 * USB hub: AU4254
19 * USB controller(+ TS dmx & streaming): GL861
20 * Frontend: comtech JDVBT-90502
21 * (tuner PLL: tua6034, I2C addr:(0xC0 >> 1))
22 * (OFDM demodulator: TC90502, I2C addr:(0x30 >> 1))
23 * LED x3 (+LNB) control: PIC 16F676
24 * EEPROM: 24C08
25 *
26 * (USB smart card reader: AU9522)
27 *
28 */
29
30#define DVB_USB_LOG_PREFIX "friio"
31#include "dvb-usb.h"
32
33extern int dvb_usb_friio_debug;
34#define deb_info(args...) dprintk(dvb_usb_friio_debug, 0x01, args)
35#define deb_xfer(args...) dprintk(dvb_usb_friio_debug, 0x02, args)
36#define deb_rc(args...) dprintk(dvb_usb_friio_debug, 0x04, args)
37#define deb_fe(args...) dprintk(dvb_usb_friio_debug, 0x08, args)
38
39/* Vendor requests */
40#define GL861_WRITE 0x40
41#define GL861_READ 0xc0
42
43/* command bytes */
44#define GL861_REQ_I2C_WRITE 0x01
45#define GL861_REQ_I2C_READ 0x02
46/* For control msg with data argument */
47/* Used for accessing the PLL on the secondary I2C bus of FE via GL861 */
48#define GL861_REQ_I2C_DATA_CTRL_WRITE 0x03
49
50#define GL861_ALTSETTING_COUNT 2
51#define FRIIO_BULK_ALTSETTING 0
52#define FRIIO_ISOC_ALTSETTING 1
53
54/* LED & LNB control via PIC. */
55/* basically, it's serial control with clock and strobe. */
56/* write the below 4bit control data to the reg 0x00 at the I2C addr 0x00 */
57/* when controlling the LEDs, 32bit(saturation, R, G, B) is sent on the bit3*/
58#define FRIIO_CTL_LNB (1 << 0)
59#define FRIIO_CTL_STROBE (1 << 1)
60#define FRIIO_CTL_CLK (1 << 2)
61#define FRIIO_CTL_LED (1 << 3)
62
63/* Front End related */
64
65#define FRIIO_DEMOD_ADDR (0x30 >> 1)
66#define FRIIO_PLL_ADDR (0xC0 >> 1)
67
68#define JDVBT90502_PLL_CLK 4000000
69#define JDVBT90502_PLL_DIVIDER 28
70
71#define JDVBT90502_2ND_I2C_REG 0xFE
72
73/* byte index for pll i2c command data structure*/
74/* see datasheet for tua6034 */
75#define DEMOD_REDIRECT_REG 0
76#define ADDRESS_BYTE 1
77#define DIVIDER_BYTE1 2
78#define DIVIDER_BYTE2 3
79#define CONTROL_BYTE 4
80#define BANDSWITCH_BYTE 5
81#define AGC_CTRL_BYTE 5
82#define PLL_CMD_LEN 6
83
84/* bit masks for PLL STATUS response */
85#define PLL_STATUS_POR_MODE 0x80 /* 1: Power on Reset (test) Mode */
86#define PLL_STATUS_LOCKED 0x40 /* 1: locked */
87#define PLL_STATUS_AGC_ACTIVE 0x08 /* 1:active */
88#define PLL_STATUS_TESTMODE 0x07 /* digital output level (5 level) */
89 /* 0.15Vcc step 0x00: < 0.15Vcc, ..., 0x04: >= 0.6Vcc (<= 1Vcc) */
90
91
92struct jdvbt90502_config {
93 u8 demod_address; /* i2c addr for demodulator IC */
94 u8 pll_address; /* PLL addr on the secondary i2c*/
95};
96extern struct jdvbt90502_config friio_fe_config;
97
98extern struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d);
99#endif
diff --git a/drivers/media/usb/dvb-usb/gp8psk-fe.c b/drivers/media/usb/dvb-usb/gp8psk-fe.c
new file mode 100644
index 000000000000..67957dd99ede
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/gp8psk-fe.c
@@ -0,0 +1,369 @@
1/* DVB USB compliant Linux driver for the
2 * - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
3 *
4 * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
5 * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com)
6 *
7 * Thanks to GENPIX for the sample code used to implement this module.
8 *
9 * This module is based off the vp7045 and vp702x modules
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation, version 2.
14 *
15 * see Documentation/dvb/README.dvb-usb for more information
16 */
17#include "gp8psk.h"
18
19struct gp8psk_fe_state {
20 struct dvb_frontend fe;
21 struct dvb_usb_device *d;
22 u8 lock;
23 u16 snr;
24 unsigned long next_status_check;
25 unsigned long status_check_interval;
26};
27
28static int gp8psk_tuned_to_DCII(struct dvb_frontend *fe)
29{
30 struct gp8psk_fe_state *st = fe->demodulator_priv;
31 u8 status;
32 gp8psk_usb_in_op(st->d, GET_8PSK_CONFIG, 0, 0, &status, 1);
33 return status & bmDCtuned;
34}
35
36static int gp8psk_set_tuner_mode(struct dvb_frontend *fe, int mode)
37{
38 struct gp8psk_fe_state *state = fe->demodulator_priv;
39 return gp8psk_usb_out_op(state->d, SET_8PSK_CONFIG, mode, 0, NULL, 0);
40}
41
42static int gp8psk_fe_update_status(struct gp8psk_fe_state *st)
43{
44 u8 buf[6];
45 if (time_after(jiffies,st->next_status_check)) {
46 gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0,0,&st->lock,1);
47 gp8psk_usb_in_op(st->d, GET_SIGNAL_STRENGTH, 0,0,buf,6);
48 st->snr = (buf[1]) << 8 | buf[0];
49 st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
50 }
51 return 0;
52}
53
54static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
55{
56 struct gp8psk_fe_state *st = fe->demodulator_priv;
57 gp8psk_fe_update_status(st);
58
59 if (st->lock)
60 *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
61 else
62 *status = 0;
63
64 if (*status & FE_HAS_LOCK)
65 st->status_check_interval = 1000;
66 else
67 st->status_check_interval = 100;
68 return 0;
69}
70
71/* not supported by this Frontend */
72static int gp8psk_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
73{
74 (void) fe;
75 *ber = 0;
76 return 0;
77}
78
79/* not supported by this Frontend */
80static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
81{
82 (void) fe;
83 *unc = 0;
84 return 0;
85}
86
87static int gp8psk_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
88{
89 struct gp8psk_fe_state *st = fe->demodulator_priv;
90 gp8psk_fe_update_status(st);
91 /* snr is reported in dBu*256 */
92 *snr = st->snr;
93 return 0;
94}
95
96static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
97{
98 struct gp8psk_fe_state *st = fe->demodulator_priv;
99 gp8psk_fe_update_status(st);
100 /* snr is reported in dBu*256 */
101 /* snr / 38.4 ~= 100% strength */
102 /* snr * 17 returns 100% strength as 65535 */
103 if (st->snr > 0xf00)
104 *strength = 0xffff;
105 else
106 *strength = (st->snr << 4) + st->snr; /* snr*17 */
107 return 0;
108}
109
110static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
111{
112 tune->min_delay_ms = 800;
113 return 0;
114}
115
116static int gp8psk_fe_set_frontend(struct dvb_frontend *fe)
117{
118 struct gp8psk_fe_state *state = fe->demodulator_priv;
119 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
120 u8 cmd[10];
121 u32 freq = c->frequency * 1000;
122 int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct);
123
124 deb_fe("%s()\n", __func__);
125
126 cmd[4] = freq & 0xff;
127 cmd[5] = (freq >> 8) & 0xff;
128 cmd[6] = (freq >> 16) & 0xff;
129 cmd[7] = (freq >> 24) & 0xff;
130
131 /* backwards compatibility: DVB-S + 8-PSK were used for Turbo-FEC */
132 if (c->delivery_system == SYS_DVBS && c->modulation == PSK_8)
133 c->delivery_system = SYS_TURBO;
134
135 switch (c->delivery_system) {
136 case SYS_DVBS:
137 if (c->modulation != QPSK) {
138 deb_fe("%s: unsupported modulation selected (%d)\n",
139 __func__, c->modulation);
140 return -EOPNOTSUPP;
141 }
142 c->fec_inner = FEC_AUTO;
143 break;
144 case SYS_DVBS2: /* kept for backwards compatibility */
145 deb_fe("%s: DVB-S2 delivery system selected\n", __func__);
146 break;
147 case SYS_TURBO:
148 deb_fe("%s: Turbo-FEC delivery system selected\n", __func__);
149 break;
150
151 default:
152 deb_fe("%s: unsupported delivery system selected (%d)\n",
153 __func__, c->delivery_system);
154 return -EOPNOTSUPP;
155 }
156
157 cmd[0] = c->symbol_rate & 0xff;
158 cmd[1] = (c->symbol_rate >> 8) & 0xff;
159 cmd[2] = (c->symbol_rate >> 16) & 0xff;
160 cmd[3] = (c->symbol_rate >> 24) & 0xff;
161 switch (c->modulation) {
162 case QPSK:
163 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
164 if (gp8psk_tuned_to_DCII(fe))
165 gp8psk_bcm4500_reload(state->d);
166 switch (c->fec_inner) {
167 case FEC_1_2:
168 cmd[9] = 0; break;
169 case FEC_2_3:
170 cmd[9] = 1; break;
171 case FEC_3_4:
172 cmd[9] = 2; break;
173 case FEC_5_6:
174 cmd[9] = 3; break;
175 case FEC_7_8:
176 cmd[9] = 4; break;
177 case FEC_AUTO:
178 cmd[9] = 5; break;
179 default:
180 cmd[9] = 5; break;
181 }
182 if (c->delivery_system == SYS_TURBO)
183 cmd[8] = ADV_MOD_TURBO_QPSK;
184 else
185 cmd[8] = ADV_MOD_DVB_QPSK;
186 break;
187 case PSK_8: /* PSK_8 is for compatibility with DN */
188 cmd[8] = ADV_MOD_TURBO_8PSK;
189 switch (c->fec_inner) {
190 case FEC_2_3:
191 cmd[9] = 0; break;
192 case FEC_3_4:
193 cmd[9] = 1; break;
194 case FEC_3_5:
195 cmd[9] = 2; break;
196 case FEC_5_6:
197 cmd[9] = 3; break;
198 case FEC_8_9:
199 cmd[9] = 4; break;
200 default:
201 cmd[9] = 0; break;
202 }
203 break;
204 case QAM_16: /* QAM_16 is for compatibility with DN */
205 cmd[8] = ADV_MOD_TURBO_16QAM;
206 cmd[9] = 0;
207 break;
208 default: /* Unknown modulation */
209 deb_fe("%s: unsupported modulation selected (%d)\n",
210 __func__, c->modulation);
211 return -EOPNOTSUPP;
212 }
213
214 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
215 gp8psk_set_tuner_mode(fe, 0);
216 gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10);
217
218 state->lock = 0;
219 state->next_status_check = jiffies;
220 state->status_check_interval = 200;
221
222 return 0;
223}
224
225static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
226 struct dvb_diseqc_master_cmd *m)
227{
228 struct gp8psk_fe_state *st = fe->demodulator_priv;
229
230 deb_fe("%s\n",__func__);
231
232 if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0,
233 m->msg, m->msg_len)) {
234 return -EINVAL;
235 }
236 return 0;
237}
238
239static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe,
240 fe_sec_mini_cmd_t burst)
241{
242 struct gp8psk_fe_state *st = fe->demodulator_priv;
243 u8 cmd;
244
245 deb_fe("%s\n",__func__);
246
247 /* These commands are certainly wrong */
248 cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01;
249
250 if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0,
251 &cmd, 0)) {
252 return -EINVAL;
253 }
254 return 0;
255}
256
257static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
258{
259 struct gp8psk_fe_state* state = fe->demodulator_priv;
260
261 if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE,
262 (tone == SEC_TONE_ON), 0, NULL, 0)) {
263 return -EINVAL;
264 }
265 return 0;
266}
267
268static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
269{
270 struct gp8psk_fe_state* state = fe->demodulator_priv;
271
272 if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE,
273 voltage == SEC_VOLTAGE_18, 0, NULL, 0)) {
274 return -EINVAL;
275 }
276 return 0;
277}
278
279static int gp8psk_fe_enable_high_lnb_voltage(struct dvb_frontend* fe, long onoff)
280{
281 struct gp8psk_fe_state* state = fe->demodulator_priv;
282 return gp8psk_usb_out_op(state->d, USE_EXTRA_VOLT, onoff, 0,NULL,0);
283}
284
285static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
286{
287 struct gp8psk_fe_state* state = fe->demodulator_priv;
288 u8 cmd = sw_cmd & 0x7f;
289
290 if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0,
291 NULL, 0)) {
292 return -EINVAL;
293 }
294 if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
295 0, NULL, 0)) {
296 return -EINVAL;
297 }
298
299 return 0;
300}
301
302static void gp8psk_fe_release(struct dvb_frontend* fe)
303{
304 struct gp8psk_fe_state *state = fe->demodulator_priv;
305 kfree(state);
306}
307
308static struct dvb_frontend_ops gp8psk_fe_ops;
309
310struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
311{
312 struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
313 if (s == NULL)
314 goto error;
315
316 s->d = d;
317 memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
318 s->fe.demodulator_priv = s;
319
320 goto success;
321error:
322 return NULL;
323success:
324 return &s->fe;
325}
326
327
328static struct dvb_frontend_ops gp8psk_fe_ops = {
329 .delsys = { SYS_DVBS },
330 .info = {
331 .name = "Genpix DVB-S",
332 .frequency_min = 800000,
333 .frequency_max = 2250000,
334 .frequency_stepsize = 100,
335 .symbol_rate_min = 1000000,
336 .symbol_rate_max = 45000000,
337 .symbol_rate_tolerance = 500, /* ppm */
338 .caps = FE_CAN_INVERSION_AUTO |
339 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
340 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
341 /*
342 * FE_CAN_QAM_16 is for compatibility
343 * (Myth incorrectly detects Turbo-QPSK as plain QAM-16)
344 */
345 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_TURBO_FEC
346 },
347
348 .release = gp8psk_fe_release,
349
350 .init = NULL,
351 .sleep = NULL,
352
353 .set_frontend = gp8psk_fe_set_frontend,
354
355 .get_tune_settings = gp8psk_fe_get_tune_settings,
356
357 .read_status = gp8psk_fe_read_status,
358 .read_ber = gp8psk_fe_read_ber,
359 .read_signal_strength = gp8psk_fe_read_signal_strength,
360 .read_snr = gp8psk_fe_read_snr,
361 .read_ucblocks = gp8psk_fe_read_unc_blocks,
362
363 .diseqc_send_master_cmd = gp8psk_fe_send_diseqc_msg,
364 .diseqc_send_burst = gp8psk_fe_send_diseqc_burst,
365 .set_tone = gp8psk_fe_set_tone,
366 .set_voltage = gp8psk_fe_set_voltage,
367 .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd,
368 .enable_high_lnb_voltage = gp8psk_fe_enable_high_lnb_voltage
369};
diff --git a/drivers/media/usb/dvb-usb/gp8psk.c b/drivers/media/usb/dvb-usb/gp8psk.c
new file mode 100644
index 000000000000..5d0384dd45b5
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/gp8psk.c
@@ -0,0 +1,328 @@
1/* DVB USB compliant Linux driver for the
2 * - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
3 *
4 * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
5 * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com)
6 *
7 * Thanks to GENPIX for the sample code used to implement this module.
8 *
9 * This module is based off the vp7045 and vp702x modules
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation, version 2.
14 *
15 * see Documentation/dvb/README.dvb-usb for more information
16 */
17#include "gp8psk.h"
18
19/* debug */
20static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw";
21int dvb_usb_gp8psk_debug;
22module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644);
23MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
24
25DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
26
27static int gp8psk_get_fw_version(struct dvb_usb_device *d, u8 *fw_vers)
28{
29 return (gp8psk_usb_in_op(d, GET_FW_VERS, 0, 0, fw_vers, 6));
30}
31
32static int gp8psk_get_fpga_version(struct dvb_usb_device *d, u8 *fpga_vers)
33{
34 return (gp8psk_usb_in_op(d, GET_FPGA_VERS, 0, 0, fpga_vers, 1));
35}
36
37static void gp8psk_info(struct dvb_usb_device *d)
38{
39 u8 fpga_vers, fw_vers[6];
40
41 if (!gp8psk_get_fw_version(d, fw_vers))
42 info("FW Version = %i.%02i.%i (0x%x) Build %4i/%02i/%02i",
43 fw_vers[2], fw_vers[1], fw_vers[0], GP8PSK_FW_VERS(fw_vers),
44 2000 + fw_vers[5], fw_vers[4], fw_vers[3]);
45 else
46 info("failed to get FW version");
47
48 if (!gp8psk_get_fpga_version(d, &fpga_vers))
49 info("FPGA Version = %i", fpga_vers);
50 else
51 info("failed to get FPGA version");
52}
53
54int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
55{
56 int ret = 0,try = 0;
57
58 if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
59 return ret;
60
61 while (ret >= 0 && ret != blen && try < 3) {
62 ret = usb_control_msg(d->udev,
63 usb_rcvctrlpipe(d->udev,0),
64 req,
65 USB_TYPE_VENDOR | USB_DIR_IN,
66 value,index,b,blen,
67 2000);
68 deb_info("reading number %d (ret: %d)\n",try,ret);
69 try++;
70 }
71
72 if (ret < 0 || ret != blen) {
73 warn("usb in %d operation failed.", req);
74 ret = -EIO;
75 } else
76 ret = 0;
77
78 deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
79 debug_dump(b,blen,deb_xfer);
80
81 mutex_unlock(&d->usb_mutex);
82
83 return ret;
84}
85
86int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
87 u16 index, u8 *b, int blen)
88{
89 int ret;
90
91 deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
92 debug_dump(b,blen,deb_xfer);
93
94 if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
95 return ret;
96
97 if (usb_control_msg(d->udev,
98 usb_sndctrlpipe(d->udev,0),
99 req,
100 USB_TYPE_VENDOR | USB_DIR_OUT,
101 value,index,b,blen,
102 2000) != blen) {
103 warn("usb out operation failed.");
104 ret = -EIO;
105 } else
106 ret = 0;
107 mutex_unlock(&d->usb_mutex);
108
109 return ret;
110}
111
112static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
113{
114 int ret;
115 const struct firmware *fw = NULL;
116 const u8 *ptr;
117 u8 *buf;
118 if ((ret = request_firmware(&fw, bcm4500_firmware,
119 &d->udev->dev)) != 0) {
120 err("did not find the bcm4500 firmware file. (%s) "
121 "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
122 bcm4500_firmware,ret);
123 return ret;
124 }
125
126 ret = -EINVAL;
127
128 if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0))
129 goto out_rel_fw;
130
131 info("downloading bcm4500 firmware from file '%s'",bcm4500_firmware);
132
133 ptr = fw->data;
134 buf = kmalloc(64, GFP_KERNEL | GFP_DMA);
135 if (!buf) {
136 ret = -ENOMEM;
137 goto out_rel_fw;
138 }
139
140 while (ptr[0] != 0xff) {
141 u16 buflen = ptr[0] + 4;
142 if (ptr + buflen >= fw->data + fw->size) {
143 err("failed to load bcm4500 firmware.");
144 goto out_free;
145 }
146 memcpy(buf, ptr, buflen);
147 if (dvb_usb_generic_write(d, buf, buflen)) {
148 err("failed to load bcm4500 firmware.");
149 goto out_free;
150 }
151 ptr += buflen;
152 }
153
154 ret = 0;
155
156out_free:
157 kfree(buf);
158out_rel_fw:
159 release_firmware(fw);
160
161 return ret;
162}
163
164static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
165{
166 u8 status, buf;
167 int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
168
169 if (onoff) {
170 gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
171 if (! (status & bm8pskStarted)) { /* started */
172 if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K)
173 gp8psk_usb_out_op(d, CW3K_INIT, 1, 0, NULL, 0);
174 if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
175 return -EINVAL;
176 gp8psk_info(d);
177 }
178
179 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
180 if (! (status & bm8pskFW_Loaded)) /* BCM4500 firmware loaded */
181 if(gp8psk_load_bcm4500fw(d))
182 return -EINVAL;
183
184 if (! (status & bmIntersilOn)) /* LNB Power */
185 if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0,
186 &buf, 1))
187 return -EINVAL;
188
189 /* Set DVB mode to 1 */
190 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
191 if (gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0))
192 return -EINVAL;
193 /* Abort possible TS (if previous tune crashed) */
194 if (gp8psk_usb_out_op(d, ARM_TRANSFER, 0, 0, NULL, 0))
195 return -EINVAL;
196 } else {
197 /* Turn off LNB power */
198 if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1))
199 return -EINVAL;
200 /* Turn off 8psk power */
201 if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
202 return -EINVAL;
203 if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K)
204 gp8psk_usb_out_op(d, CW3K_INIT, 0, 0, NULL, 0);
205 }
206 return 0;
207}
208
209int gp8psk_bcm4500_reload(struct dvb_usb_device *d)
210{
211 u8 buf;
212 int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct);
213 /* Turn off 8psk power */
214 if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
215 return -EINVAL;
216 /* Turn On 8psk power */
217 if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
218 return -EINVAL;
219 /* load BCM4500 firmware */
220 if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)
221 if (gp8psk_load_bcm4500fw(d))
222 return -EINVAL;
223 return 0;
224}
225
226static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
227{
228 return gp8psk_usb_out_op(adap->dev, ARM_TRANSFER, onoff, 0 , NULL, 0);
229}
230
231static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap)
232{
233 adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev);
234 return 0;
235}
236
237static struct dvb_usb_device_properties gp8psk_properties;
238
239static int gp8psk_usb_probe(struct usb_interface *intf,
240 const struct usb_device_id *id)
241{
242 int ret;
243 struct usb_device *udev = interface_to_usbdev(intf);
244 ret = dvb_usb_device_init(intf, &gp8psk_properties,
245 THIS_MODULE, NULL, adapter_nr);
246 if (ret == 0) {
247 info("found Genpix USB device pID = %x (hex)",
248 le16_to_cpu(udev->descriptor.idProduct));
249 }
250 return ret;
251}
252
253static struct usb_device_id gp8psk_usb_table [] = {
254 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_COLD) },
255 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) },
256 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) },
257 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) },
258 { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_2) },
259/* { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, */
260 { 0 },
261};
262MODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
263
264static struct dvb_usb_device_properties gp8psk_properties = {
265 .usb_ctrl = CYPRESS_FX2,
266 .firmware = "dvb-usb-gp8psk-01.fw",
267
268 .num_adapters = 1,
269 .adapter = {
270 {
271 .num_frontends = 1,
272 .fe = {{
273 .streaming_ctrl = gp8psk_streaming_ctrl,
274 .frontend_attach = gp8psk_frontend_attach,
275 /* parameter for the MPEG2-data transfer */
276 .stream = {
277 .type = USB_BULK,
278 .count = 7,
279 .endpoint = 0x82,
280 .u = {
281 .bulk = {
282 .buffersize = 8192,
283 }
284 }
285 },
286 }},
287 }
288 },
289 .power_ctrl = gp8psk_power_ctrl,
290
291 .generic_bulk_ctrl_endpoint = 0x01,
292
293 .num_device_descs = 4,
294 .devices = {
295 { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver",
296 .cold_ids = { &gp8psk_usb_table[0], NULL },
297 .warm_ids = { &gp8psk_usb_table[1], NULL },
298 },
299 { .name = "Genpix 8PSK-to-USB2 Rev.2 DVB-S receiver",
300 .cold_ids = { NULL },
301 .warm_ids = { &gp8psk_usb_table[2], NULL },
302 },
303 { .name = "Genpix SkyWalker-1 DVB-S receiver",
304 .cold_ids = { NULL },
305 .warm_ids = { &gp8psk_usb_table[3], NULL },
306 },
307 { .name = "Genpix SkyWalker-2 DVB-S receiver",
308 .cold_ids = { NULL },
309 .warm_ids = { &gp8psk_usb_table[4], NULL },
310 },
311 { NULL },
312 }
313};
314
315/* usb specific object needed to register this driver with the usb subsystem */
316static struct usb_driver gp8psk_usb_driver = {
317 .name = "dvb_usb_gp8psk",
318 .probe = gp8psk_usb_probe,
319 .disconnect = dvb_usb_device_exit,
320 .id_table = gp8psk_usb_table,
321};
322
323module_usb_driver(gp8psk_usb_driver);
324
325MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>");
326MODULE_DESCRIPTION("Driver for Genpix DVB-S");
327MODULE_VERSION("1.1");
328MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/gp8psk.h b/drivers/media/usb/dvb-usb/gp8psk.h
new file mode 100644
index 000000000000..ed32b9da4843
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/gp8psk.h
@@ -0,0 +1,100 @@
1/* DVB USB compliant Linux driver for the
2 * - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module
3 *
4 * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
5 * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com)
6 *
7 * Thanks to GENPIX for the sample code used to implement this module.
8 *
9 * This module is based off the vp7045 and vp702x modules
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation, version 2.
14 *
15 * see Documentation/dvb/README.dvb-usb for more information
16 */
17#ifndef _DVB_USB_GP8PSK_H_
18#define _DVB_USB_GP8PSK_H_
19
20#define DVB_USB_LOG_PREFIX "gp8psk"
21#include "dvb-usb.h"
22
23extern int dvb_usb_gp8psk_debug;
24#define deb_info(args...) dprintk(dvb_usb_gp8psk_debug,0x01,args)
25#define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args)
26#define deb_rc(args...) dprintk(dvb_usb_gp8psk_debug,0x04,args)
27#define deb_fe(args...) dprintk(dvb_usb_gp8psk_debug,0x08,args)
28
29/* Twinhan Vendor requests */
30#define TH_COMMAND_IN 0xC0
31#define TH_COMMAND_OUT 0xC1
32
33/* gp8psk commands */
34
35#define GET_8PSK_CONFIG 0x80 /* in */
36#define SET_8PSK_CONFIG 0x81
37#define I2C_WRITE 0x83
38#define I2C_READ 0x84
39#define ARM_TRANSFER 0x85
40#define TUNE_8PSK 0x86
41#define GET_SIGNAL_STRENGTH 0x87 /* in */
42#define LOAD_BCM4500 0x88
43#define BOOT_8PSK 0x89 /* in */
44#define START_INTERSIL 0x8A /* in */
45#define SET_LNB_VOLTAGE 0x8B
46#define SET_22KHZ_TONE 0x8C
47#define SEND_DISEQC_COMMAND 0x8D
48#define SET_DVB_MODE 0x8E
49#define SET_DN_SWITCH 0x8F
50#define GET_SIGNAL_LOCK 0x90 /* in */
51#define GET_FW_VERS 0x92
52#define GET_SERIAL_NUMBER 0x93 /* in */
53#define USE_EXTRA_VOLT 0x94
54#define GET_FPGA_VERS 0x95
55#define CW3K_INIT 0x9d
56
57/* PSK_configuration bits */
58#define bm8pskStarted 0x01
59#define bm8pskFW_Loaded 0x02
60#define bmIntersilOn 0x04
61#define bmDVBmode 0x08
62#define bm22kHz 0x10
63#define bmSEL18V 0x20
64#define bmDCtuned 0x40
65#define bmArmed 0x80
66
67/* Satellite modulation modes */
68#define ADV_MOD_DVB_QPSK 0 /* DVB-S QPSK */
69#define ADV_MOD_TURBO_QPSK 1 /* Turbo QPSK */
70#define ADV_MOD_TURBO_8PSK 2 /* Turbo 8PSK (also used for Trellis 8PSK) */
71#define ADV_MOD_TURBO_16QAM 3 /* Turbo 16QAM (also used for Trellis 8PSK) */
72
73#define ADV_MOD_DCII_C_QPSK 4 /* Digicipher II Combo */
74#define ADV_MOD_DCII_I_QPSK 5 /* Digicipher II I-stream */
75#define ADV_MOD_DCII_Q_QPSK 6 /* Digicipher II Q-stream */
76#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
77#define ADV_MOD_DSS_QPSK 8 /* DSS (DIRECTV) QPSK */
78#define ADV_MOD_DVB_BPSK 9 /* DVB-S BPSK */
79
80#define GET_USB_SPEED 0x07
81
82#define RESET_FX2 0x13
83
84#define FW_VERSION_READ 0x0B
85#define VENDOR_STRING_READ 0x0C
86#define PRODUCT_STRING_READ 0x0D
87#define FW_BCD_VERSION_READ 0x14
88
89/* firmware revision id's */
90#define GP8PSK_FW_REV1 0x020604
91#define GP8PSK_FW_REV2 0x020704
92#define GP8PSK_FW_VERS(_fw_vers) ((_fw_vers)[2]<<0x10 | (_fw_vers)[1]<<0x08 | (_fw_vers)[0])
93
94extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
95extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
96extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
97 u16 index, u8 *b, int blen);
98extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d);
99
100#endif
diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c
new file mode 100644
index 000000000000..288af29a8bb7
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/m920x.c
@@ -0,0 +1,1099 @@
1/* DVB USB compliant linux driver for MSI Mega Sky 580 DVB-T USB2.0 receiver
2 *
3 * Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.org)
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation, version 2.
8 *
9 * see Documentation/dvb/README.dvb-usb for more information
10 */
11
12#include "m920x.h"
13
14#include "mt352.h"
15#include "mt352_priv.h"
16#include "qt1010.h"
17#include "tda1004x.h"
18#include "tda827x.h"
19
20#include <media/tuner.h>
21#include "tuner-simple.h"
22#include <asm/unaligned.h>
23
24/* debug */
25static int dvb_usb_m920x_debug;
26module_param_named(debug,dvb_usb_m920x_debug, int, 0644);
27MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
28
29DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
30
31static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid);
32
33static inline int m920x_read(struct usb_device *udev, u8 request, u16 value,
34 u16 index, void *data, int size)
35{
36 int ret;
37
38 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
39 request, USB_TYPE_VENDOR | USB_DIR_IN,
40 value, index, data, size, 2000);
41 if (ret < 0) {
42 printk(KERN_INFO "m920x_read = error: %d\n", ret);
43 return ret;
44 }
45
46 if (ret != size) {
47 deb("m920x_read = no data\n");
48 return -EIO;
49 }
50
51 return 0;
52}
53
54static inline int m920x_write(struct usb_device *udev, u8 request,
55 u16 value, u16 index)
56{
57 int ret;
58
59 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
60 request, USB_TYPE_VENDOR | USB_DIR_OUT,
61 value, index, NULL, 0, 2000);
62
63 return ret;
64}
65
66static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq)
67{
68 int ret = 0, i, epi, flags = 0;
69 int adap_enabled[M9206_MAX_ADAPTERS] = { 0 };
70
71 /* Remote controller init. */
72 if (d->props.rc.legacy.rc_query) {
73 deb("Initialising remote control\n");
74 while (rc_seq->address) {
75 if ((ret = m920x_write(d->udev, M9206_CORE,
76 rc_seq->data,
77 rc_seq->address)) != 0) {
78 deb("Initialising remote control failed\n");
79 return ret;
80 }
81
82 rc_seq++;
83 }
84
85 deb("Initialising remote control success\n");
86 }
87
88 for (i = 0; i < d->props.num_adapters; i++)
89 flags |= d->adapter[i].props.fe[0].caps;
90
91 /* Some devices(Dposh) might crash if we attempt touch at all. */
92 if (flags & DVB_USB_ADAP_HAS_PID_FILTER) {
93 for (i = 0; i < d->props.num_adapters; i++) {
94 epi = d->adapter[i].props.fe[0].stream.endpoint - 0x81;
95
96 if (epi < 0 || epi >= M9206_MAX_ADAPTERS) {
97 printk(KERN_INFO "m920x: Unexpected adapter endpoint!\n");
98 return -EINVAL;
99 }
100
101 adap_enabled[epi] = 1;
102 }
103
104 for (i = 0; i < M9206_MAX_ADAPTERS; i++) {
105 if (adap_enabled[i])
106 continue;
107
108 if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x0)) != 0)
109 return ret;
110
111 if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x02f5)) != 0)
112 return ret;
113 }
114 }
115
116 return ret;
117}
118
119static int m920x_init_ep(struct usb_interface *intf)
120{
121 struct usb_device *udev = interface_to_usbdev(intf);
122 struct usb_host_interface *alt;
123
124 if ((alt = usb_altnum_to_altsetting(intf, 1)) == NULL) {
125 deb("No alt found!\n");
126 return -ENODEV;
127 }
128
129 return usb_set_interface(udev, alt->desc.bInterfaceNumber,
130 alt->desc.bAlternateSetting);
131}
132
133static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
134{
135 struct m920x_state *m = d->priv;
136 int i, ret = 0;
137 u8 *rc_state;
138
139 rc_state = kmalloc(2, GFP_KERNEL);
140 if (!rc_state)
141 return -ENOMEM;
142
143 if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
144 goto out;
145
146 if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
147 goto out;
148
149 for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
150 if (rc5_data(&d->props.rc.legacy.rc_map_table[i]) == rc_state[1]) {
151 *event = d->props.rc.legacy.rc_map_table[i].keycode;
152
153 switch(rc_state[0]) {
154 case 0x80:
155 *state = REMOTE_NO_KEY_PRESSED;
156 goto out;
157
158 case 0x88: /* framing error or "invalid code" */
159 case 0x99:
160 case 0xc0:
161 case 0xd8:
162 *state = REMOTE_NO_KEY_PRESSED;
163 m->rep_count = 0;
164 goto out;
165
166 case 0x93:
167 case 0x92:
168 case 0x83: /* pinnacle PCTV310e */
169 case 0x82:
170 m->rep_count = 0;
171 *state = REMOTE_KEY_PRESSED;
172 goto out;
173
174 case 0x91:
175 case 0x81: /* pinnacle PCTV310e */
176 /* prevent immediate auto-repeat */
177 if (++m->rep_count > 2)
178 *state = REMOTE_KEY_REPEAT;
179 else
180 *state = REMOTE_NO_KEY_PRESSED;
181 goto out;
182
183 default:
184 deb("Unexpected rc state %02x\n", rc_state[0]);
185 *state = REMOTE_NO_KEY_PRESSED;
186 goto out;
187 }
188 }
189
190 if (rc_state[1] != 0)
191 deb("Unknown rc key %02x\n", rc_state[1]);
192
193 *state = REMOTE_NO_KEY_PRESSED;
194
195 out:
196 kfree(rc_state);
197 return ret;
198}
199
200/* I2C */
201static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num)
202{
203 struct dvb_usb_device *d = i2c_get_adapdata(adap);
204 int i, j;
205 int ret = 0;
206
207 if (!num)
208 return -EINVAL;
209
210 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
211 return -EAGAIN;
212
213 for (i = 0; i < num; i++) {
214 if (msg[i].flags & (I2C_M_NO_RD_ACK | I2C_M_IGNORE_NAK | I2C_M_TEN) || msg[i].len == 0) {
215 /* For a 0 byte message, I think sending the address
216 * to index 0x80|0x40 would be the correct thing to
217 * do. However, zero byte messages are only used for
218 * probing, and since we don't know how to get the
219 * slave's ack, we can't probe. */
220 ret = -ENOTSUPP;
221 goto unlock;
222 }
223 /* Send START & address/RW bit */
224 if (!(msg[i].flags & I2C_M_NOSTART)) {
225 if ((ret = m920x_write(d->udev, M9206_I2C,
226 (msg[i].addr << 1) |
227 (msg[i].flags & I2C_M_RD ? 0x01 : 0), 0x80)) != 0)
228 goto unlock;
229 /* Should check for ack here, if we knew how. */
230 }
231 if (msg[i].flags & I2C_M_RD) {
232 for (j = 0; j < msg[i].len; j++) {
233 /* Last byte of transaction?
234 * Send STOP, otherwise send ACK. */
235 int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x01;
236
237 if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
238 0x20 | stop,
239 &msg[i].buf[j], 1)) != 0)
240 goto unlock;
241 }
242 } else {
243 for (j = 0; j < msg[i].len; j++) {
244 /* Last byte of transaction? Then send STOP. */
245 int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x00;
246
247 if ((ret = m920x_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0)
248 goto unlock;
249 /* Should check for ack here too. */
250 }
251 }
252 }
253 ret = num;
254
255 unlock:
256 mutex_unlock(&d->i2c_mutex);
257
258 return ret;
259}
260
261static u32 m920x_i2c_func(struct i2c_adapter *adapter)
262{
263 return I2C_FUNC_I2C;
264}
265
266static struct i2c_algorithm m920x_i2c_algo = {
267 .master_xfer = m920x_i2c_xfer,
268 .functionality = m920x_i2c_func,
269};
270
271/* pid filter */
272static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid)
273{
274 int ret = 0;
275
276 if (pid >= 0x8000)
277 return -EINVAL;
278
279 pid |= 0x8000;
280
281 if ((ret = m920x_write(d->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
282 return ret;
283
284 if ((ret = m920x_write(d->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
285 return ret;
286
287 return ret;
288}
289
290static int m920x_update_filters(struct dvb_usb_adapter *adap)
291{
292 struct m920x_state *m = adap->dev->priv;
293 int enabled = m->filtering_enabled[adap->id];
294 int i, ret = 0, filter = 0;
295 int ep = adap->props.fe[0].stream.endpoint;
296
297 for (i = 0; i < M9206_MAX_FILTERS; i++)
298 if (m->filters[adap->id][i] == 8192)
299 enabled = 0;
300
301 /* Disable all filters */
302 if ((ret = m920x_set_filter(adap->dev, ep, 1, enabled)) != 0)
303 return ret;
304
305 for (i = 0; i < M9206_MAX_FILTERS; i++)
306 if ((ret = m920x_set_filter(adap->dev, ep, i + 2, 0)) != 0)
307 return ret;
308
309 /* Set */
310 if (enabled) {
311 for (i = 0; i < M9206_MAX_FILTERS; i++) {
312 if (m->filters[adap->id][i] == 0)
313 continue;
314
315 if ((ret = m920x_set_filter(adap->dev, ep, filter + 2, m->filters[adap->id][i])) != 0)
316 return ret;
317
318 filter++;
319 }
320 }
321
322 return ret;
323}
324
325static int m920x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
326{
327 struct m920x_state *m = adap->dev->priv;
328
329 m->filtering_enabled[adap->id] = onoff ? 1 : 0;
330
331 return m920x_update_filters(adap);
332}
333
334static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff)
335{
336 struct m920x_state *m = adap->dev->priv;
337
338 m->filters[adap->id][index] = onoff ? pid : 0;
339
340 return m920x_update_filters(adap);
341}
342
343static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw)
344{
345 u16 value, index, size;
346 u8 *read, *buff;
347 int i, pass, ret = 0;
348
349 buff = kmalloc(65536, GFP_KERNEL);
350 if (buff == NULL)
351 return -ENOMEM;
352
353 read = kmalloc(4, GFP_KERNEL);
354 if (!read) {
355 kfree(buff);
356 return -ENOMEM;
357 }
358
359 if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
360 goto done;
361 deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
362
363 if ((ret = m920x_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0)
364 goto done;
365 deb("%x\n", read[0]);
366
367 for (pass = 0; pass < 2; pass++) {
368 for (i = 0; i + (sizeof(u16) * 3) < fw->size;) {
369 value = get_unaligned_le16(fw->data + i);
370 i += sizeof(u16);
371
372 index = get_unaligned_le16(fw->data + i);
373 i += sizeof(u16);
374
375 size = get_unaligned_le16(fw->data + i);
376 i += sizeof(u16);
377
378 if (pass == 1) {
379 /* Will stall if using fw->data ... */
380 memcpy(buff, fw->data + i, size);
381
382 ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
383 M9206_FW,
384 USB_TYPE_VENDOR | USB_DIR_OUT,
385 value, index, buff, size, 20);
386 if (ret != size) {
387 deb("error while uploading fw!\n");
388 ret = -EIO;
389 goto done;
390 }
391 msleep(3);
392 }
393 i += size;
394 }
395 if (i != fw->size) {
396 deb("bad firmware file!\n");
397 ret = -EINVAL;
398 goto done;
399 }
400 }
401
402 msleep(36);
403
404 /* m920x will disconnect itself from the bus after this. */
405 (void) m920x_write(udev, M9206_CORE, 0x01, M9206_FW_GO);
406 deb("firmware uploaded!\n");
407
408 done:
409 kfree(read);
410 kfree(buff);
411
412 return ret;
413}
414
415/* Callbacks for DVB USB */
416static int m920x_identify_state(struct usb_device *udev,
417 struct dvb_usb_device_properties *props,
418 struct dvb_usb_device_description **desc,
419 int *cold)
420{
421 struct usb_host_interface *alt;
422
423 alt = usb_altnum_to_altsetting(usb_ifnum_to_if(udev, 0), 1);
424 *cold = (alt == NULL) ? 1 : 0;
425
426 return 0;
427}
428
429/* demod configurations */
430static int m920x_mt352_demod_init(struct dvb_frontend *fe)
431{
432 int ret;
433 u8 config[] = { CONFIG, 0x3d };
434 u8 clock[] = { CLOCK_CTL, 0x30 };
435 u8 reset[] = { RESET, 0x80 };
436 u8 adc_ctl[] = { ADC_CTL_1, 0x40 };
437 u8 agc[] = { AGC_TARGET, 0x1c, 0x20 };
438 u8 sec_agc[] = { 0x69, 0x00, 0xff, 0xff, 0x40, 0xff, 0x00, 0x40, 0x40 };
439 u8 unk1[] = { 0x93, 0x1a };
440 u8 unk2[] = { 0xb5, 0x7a };
441
442 deb("Demod init!\n");
443
444 if ((ret = mt352_write(fe, config, ARRAY_SIZE(config))) != 0)
445 return ret;
446 if ((ret = mt352_write(fe, clock, ARRAY_SIZE(clock))) != 0)
447 return ret;
448 if ((ret = mt352_write(fe, reset, ARRAY_SIZE(reset))) != 0)
449 return ret;
450 if ((ret = mt352_write(fe, adc_ctl, ARRAY_SIZE(adc_ctl))) != 0)
451 return ret;
452 if ((ret = mt352_write(fe, agc, ARRAY_SIZE(agc))) != 0)
453 return ret;
454 if ((ret = mt352_write(fe, sec_agc, ARRAY_SIZE(sec_agc))) != 0)
455 return ret;
456 if ((ret = mt352_write(fe, unk1, ARRAY_SIZE(unk1))) != 0)
457 return ret;
458 if ((ret = mt352_write(fe, unk2, ARRAY_SIZE(unk2))) != 0)
459 return ret;
460
461 return 0;
462}
463
464static struct mt352_config m920x_mt352_config = {
465 .demod_address = 0x0f,
466 .no_tuner = 1,
467 .demod_init = m920x_mt352_demod_init,
468};
469
470static struct tda1004x_config m920x_tda10046_08_config = {
471 .demod_address = 0x08,
472 .invert = 0,
473 .invert_oclk = 0,
474 .ts_mode = TDA10046_TS_SERIAL,
475 .xtal_freq = TDA10046_XTAL_16M,
476 .if_freq = TDA10046_FREQ_045,
477 .agc_config = TDA10046_AGC_TDA827X,
478 .gpio_config = TDA10046_GPTRI,
479 .request_firmware = NULL,
480};
481
482static struct tda1004x_config m920x_tda10046_0b_config = {
483 .demod_address = 0x0b,
484 .invert = 0,
485 .invert_oclk = 0,
486 .ts_mode = TDA10046_TS_SERIAL,
487 .xtal_freq = TDA10046_XTAL_16M,
488 .if_freq = TDA10046_FREQ_045,
489 .agc_config = TDA10046_AGC_TDA827X,
490 .gpio_config = TDA10046_GPTRI,
491 .request_firmware = NULL, /* uses firmware EEPROM */
492};
493
494/* tuner configurations */
495static struct qt1010_config m920x_qt1010_config = {
496 .i2c_address = 0x62
497};
498
499/* Callbacks for DVB USB */
500static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap)
501{
502 deb("%s\n",__func__);
503
504 adap->fe_adap[0].fe = dvb_attach(mt352_attach,
505 &m920x_mt352_config,
506 &adap->dev->i2c_adap);
507 if ((adap->fe_adap[0].fe) == NULL)
508 return -EIO;
509
510 return 0;
511}
512
513static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap)
514{
515 deb("%s\n",__func__);
516
517 adap->fe_adap[0].fe = dvb_attach(tda10046_attach,
518 &m920x_tda10046_08_config,
519 &adap->dev->i2c_adap);
520 if ((adap->fe_adap[0].fe) == NULL)
521 return -EIO;
522
523 return 0;
524}
525
526static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap)
527{
528 deb("%s\n",__func__);
529
530 adap->fe_adap[0].fe = dvb_attach(tda10046_attach,
531 &m920x_tda10046_0b_config,
532 &adap->dev->i2c_adap);
533 if ((adap->fe_adap[0].fe) == NULL)
534 return -EIO;
535
536 return 0;
537}
538
539static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
540{
541 deb("%s\n",__func__);
542
543 if (dvb_attach(qt1010_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL)
544 return -ENODEV;
545
546 return 0;
547}
548
549static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap)
550{
551 deb("%s\n",__func__);
552
553 if (dvb_attach(tda827x_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL)
554 return -ENODEV;
555
556 return 0;
557}
558
559static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap)
560{
561 deb("%s\n",__func__);
562
563 if (dvb_attach(tda827x_attach, adap->fe_adap[0].fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL)
564 return -ENODEV;
565
566 return 0;
567}
568
569static int m920x_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
570{
571 dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe,
572 &adap->dev->i2c_adap, 0x61,
573 TUNER_PHILIPS_FMD1216ME_MK3);
574 return 0;
575}
576
577/* device-specific initialization */
578static struct m920x_inits megasky_rc_init [] = {
579 { M9206_RC_INIT2, 0xa8 },
580 { M9206_RC_INIT1, 0x51 },
581 { } /* terminating entry */
582};
583
584static struct m920x_inits tvwalkertwin_rc_init [] = {
585 { M9206_RC_INIT2, 0x00 },
586 { M9206_RC_INIT1, 0xef },
587 { 0xff28, 0x00 },
588 { 0xff23, 0x00 },
589 { 0xff21, 0x30 },
590 { } /* terminating entry */
591};
592
593static struct m920x_inits pinnacle310e_init[] = {
594 /* without these the tuner don't work */
595 { 0xff20, 0x9b },
596 { 0xff22, 0x70 },
597
598 /* rc settings */
599 { 0xff50, 0x80 },
600 { M9206_RC_INIT1, 0x00 },
601 { M9206_RC_INIT2, 0xff },
602 { } /* terminating entry */
603};
604
605/* ir keymaps */
606static struct rc_map_table rc_map_megasky_table[] = {
607 { 0x0012, KEY_POWER },
608 { 0x001e, KEY_CYCLEWINDOWS }, /* min/max */
609 { 0x0002, KEY_CHANNELUP },
610 { 0x0005, KEY_CHANNELDOWN },
611 { 0x0003, KEY_VOLUMEUP },
612 { 0x0006, KEY_VOLUMEDOWN },
613 { 0x0004, KEY_MUTE },
614 { 0x0007, KEY_OK }, /* TS */
615 { 0x0008, KEY_STOP },
616 { 0x0009, KEY_MENU }, /* swap */
617 { 0x000a, KEY_REWIND },
618 { 0x001b, KEY_PAUSE },
619 { 0x001f, KEY_FASTFORWARD },
620 { 0x000c, KEY_RECORD },
621 { 0x000d, KEY_CAMERA }, /* screenshot */
622 { 0x000e, KEY_COFFEE }, /* "MTS" */
623};
624
625static struct rc_map_table rc_map_tvwalkertwin_table[] = {
626 { 0x0001, KEY_ZOOM }, /* Full Screen */
627 { 0x0002, KEY_CAMERA }, /* snapshot */
628 { 0x0003, KEY_MUTE },
629 { 0x0004, KEY_REWIND },
630 { 0x0005, KEY_PLAYPAUSE }, /* Play/Pause */
631 { 0x0006, KEY_FASTFORWARD },
632 { 0x0007, KEY_RECORD },
633 { 0x0008, KEY_STOP },
634 { 0x0009, KEY_TIME }, /* Timeshift */
635 { 0x000c, KEY_COFFEE }, /* Recall */
636 { 0x000e, KEY_CHANNELUP },
637 { 0x0012, KEY_POWER },
638 { 0x0015, KEY_MENU }, /* source */
639 { 0x0018, KEY_CYCLEWINDOWS }, /* TWIN PIP */
640 { 0x001a, KEY_CHANNELDOWN },
641 { 0x001b, KEY_VOLUMEDOWN },
642 { 0x001e, KEY_VOLUMEUP },
643};
644
645static struct rc_map_table rc_map_pinnacle310e_table[] = {
646 { 0x16, KEY_POWER },
647 { 0x17, KEY_FAVORITES },
648 { 0x0f, KEY_TEXT },
649 { 0x48, KEY_PROGRAM }, /* preview */
650 { 0x1c, KEY_EPG },
651 { 0x04, KEY_LIST }, /* record list */
652 { 0x03, KEY_1 },
653 { 0x01, KEY_2 },
654 { 0x06, KEY_3 },
655 { 0x09, KEY_4 },
656 { 0x1d, KEY_5 },
657 { 0x1f, KEY_6 },
658 { 0x0d, KEY_7 },
659 { 0x19, KEY_8 },
660 { 0x1b, KEY_9 },
661 { 0x15, KEY_0 },
662 { 0x0c, KEY_CANCEL },
663 { 0x4a, KEY_CLEAR },
664 { 0x13, KEY_BACK },
665 { 0x00, KEY_TAB },
666 { 0x4b, KEY_UP },
667 { 0x4e, KEY_LEFT },
668 { 0x52, KEY_RIGHT },
669 { 0x51, KEY_DOWN },
670 { 0x4f, KEY_ENTER }, /* could also be KEY_OK */
671 { 0x1e, KEY_VOLUMEUP },
672 { 0x0a, KEY_VOLUMEDOWN },
673 { 0x05, KEY_CHANNELUP },
674 { 0x02, KEY_CHANNELDOWN },
675 { 0x11, KEY_RECORD },
676 { 0x14, KEY_PLAY },
677 { 0x4c, KEY_PAUSE },
678 { 0x1a, KEY_STOP },
679 { 0x40, KEY_REWIND },
680 { 0x12, KEY_FASTFORWARD },
681 { 0x41, KEY_PREVIOUSSONG }, /* Replay */
682 { 0x42, KEY_NEXTSONG }, /* Skip */
683 { 0x54, KEY_CAMERA }, /* Capture */
684/* { 0x50, KEY_SAP }, */ /* Sap */
685 { 0x47, KEY_CYCLEWINDOWS }, /* Pip */
686 { 0x4d, KEY_SCREEN }, /* FullScreen */
687 { 0x08, KEY_SUBTITLE },
688 { 0x0e, KEY_MUTE },
689/* { 0x49, KEY_LR }, */ /* L/R */
690 { 0x07, KEY_SLEEP }, /* Hibernate */
691 { 0x08, KEY_VIDEO }, /* A/V */
692 { 0x0e, KEY_MENU }, /* Recall */
693 { 0x45, KEY_ZOOMIN },
694 { 0x46, KEY_ZOOMOUT },
695 { 0x18, KEY_RED }, /* Red */
696 { 0x53, KEY_GREEN }, /* Green */
697 { 0x5e, KEY_YELLOW }, /* Yellow */
698 { 0x5f, KEY_BLUE }, /* Blue */
699};
700
701/* DVB USB Driver stuff */
702static struct dvb_usb_device_properties megasky_properties;
703static struct dvb_usb_device_properties digivox_mini_ii_properties;
704static struct dvb_usb_device_properties tvwalkertwin_properties;
705static struct dvb_usb_device_properties dposh_properties;
706static struct dvb_usb_device_properties pinnacle_pctv310e_properties;
707
708static int m920x_probe(struct usb_interface *intf,
709 const struct usb_device_id *id)
710{
711 struct dvb_usb_device *d = NULL;
712 int ret;
713 struct m920x_inits *rc_init_seq = NULL;
714 int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber;
715
716 deb("Probing for m920x device at interface %d\n", bInterfaceNumber);
717
718 if (bInterfaceNumber == 0) {
719 /* Single-tuner device, or first interface on
720 * multi-tuner device
721 */
722
723 ret = dvb_usb_device_init(intf, &megasky_properties,
724 THIS_MODULE, &d, adapter_nr);
725 if (ret == 0) {
726 rc_init_seq = megasky_rc_init;
727 goto found;
728 }
729
730 ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties,
731 THIS_MODULE, &d, adapter_nr);
732 if (ret == 0) {
733 /* No remote control, so no rc_init_seq */
734 goto found;
735 }
736
737 /* This configures both tuners on the TV Walker Twin */
738 ret = dvb_usb_device_init(intf, &tvwalkertwin_properties,
739 THIS_MODULE, &d, adapter_nr);
740 if (ret == 0) {
741 rc_init_seq = tvwalkertwin_rc_init;
742 goto found;
743 }
744
745 ret = dvb_usb_device_init(intf, &dposh_properties,
746 THIS_MODULE, &d, adapter_nr);
747 if (ret == 0) {
748 /* Remote controller not supported yet. */
749 goto found;
750 }
751
752 ret = dvb_usb_device_init(intf, &pinnacle_pctv310e_properties,
753 THIS_MODULE, &d, adapter_nr);
754 if (ret == 0) {
755 rc_init_seq = pinnacle310e_init;
756 goto found;
757 }
758
759 return ret;
760 } else {
761 /* Another interface on a multi-tuner device */
762
763 /* The LifeView TV Walker Twin gets here, but struct
764 * tvwalkertwin_properties already configured both
765 * tuners, so there is nothing for us to do here
766 */
767 }
768
769 found:
770 if ((ret = m920x_init_ep(intf)) < 0)
771 return ret;
772
773 if (d && (ret = m920x_init(d, rc_init_seq)) != 0)
774 return ret;
775
776 return ret;
777}
778
779static struct usb_device_id m920x_table [] = {
780 { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) },
781 { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
782 USB_PID_MSI_DIGI_VOX_MINI_II) },
783 { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
784 USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD) },
785 { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
786 USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) },
787 { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) },
788 { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) },
789 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_PINNACLE_PCTV310E) },
790 { } /* Terminating entry */
791};
792MODULE_DEVICE_TABLE (usb, m920x_table);
793
794static struct dvb_usb_device_properties megasky_properties = {
795 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
796
797 .usb_ctrl = DEVICE_SPECIFIC,
798 .firmware = "dvb-usb-megasky-02.fw",
799 .download_firmware = m920x_firmware_download,
800
801 .rc.legacy = {
802 .rc_interval = 100,
803 .rc_map_table = rc_map_megasky_table,
804 .rc_map_size = ARRAY_SIZE(rc_map_megasky_table),
805 .rc_query = m920x_rc_query,
806 },
807
808 .size_of_priv = sizeof(struct m920x_state),
809
810 .identify_state = m920x_identify_state,
811 .num_adapters = 1,
812 .adapter = {{
813 .num_frontends = 1,
814 .fe = {{
815
816 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
817 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
818
819 .pid_filter_count = 8,
820 .pid_filter = m920x_pid_filter,
821 .pid_filter_ctrl = m920x_pid_filter_ctrl,
822
823 .frontend_attach = m920x_mt352_frontend_attach,
824 .tuner_attach = m920x_qt1010_tuner_attach,
825
826 .stream = {
827 .type = USB_BULK,
828 .count = 8,
829 .endpoint = 0x81,
830 .u = {
831 .bulk = {
832 .buffersize = 512,
833 }
834 }
835 },
836 }},
837 }},
838 .i2c_algo = &m920x_i2c_algo,
839
840 .num_device_descs = 1,
841 .devices = {
842 { "MSI Mega Sky 580 DVB-T USB2.0",
843 { &m920x_table[0], NULL },
844 { NULL },
845 }
846 }
847};
848
849static struct dvb_usb_device_properties digivox_mini_ii_properties = {
850 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
851
852 .usb_ctrl = DEVICE_SPECIFIC,
853 .firmware = "dvb-usb-digivox-02.fw",
854 .download_firmware = m920x_firmware_download,
855
856 .size_of_priv = sizeof(struct m920x_state),
857
858 .identify_state = m920x_identify_state,
859 .num_adapters = 1,
860 .adapter = {{
861 .num_frontends = 1,
862 .fe = {{
863
864 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
865 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
866
867 .pid_filter_count = 8,
868 .pid_filter = m920x_pid_filter,
869 .pid_filter_ctrl = m920x_pid_filter_ctrl,
870
871 .frontend_attach = m920x_tda10046_08_frontend_attach,
872 .tuner_attach = m920x_tda8275_60_tuner_attach,
873
874 .stream = {
875 .type = USB_BULK,
876 .count = 8,
877 .endpoint = 0x81,
878 .u = {
879 .bulk = {
880 .buffersize = 0x4000,
881 }
882 }
883 },
884 }},
885 }},
886 .i2c_algo = &m920x_i2c_algo,
887
888 .num_device_descs = 1,
889 .devices = {
890 { "MSI DIGI VOX mini II DVB-T USB2.0",
891 { &m920x_table[1], NULL },
892 { NULL },
893 },
894 }
895};
896
897/* LifeView TV Walker Twin support by Nick Andrew <nick@nick-andrew.net>
898 *
899 * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A
900 * TDA10046 #0 is located at i2c address 0x08
901 * TDA10046 #1 is located at i2c address 0x0b
902 * TDA8275A #0 is located at i2c address 0x60
903 * TDA8275A #1 is located at i2c address 0x61
904 */
905static struct dvb_usb_device_properties tvwalkertwin_properties = {
906 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
907
908 .usb_ctrl = DEVICE_SPECIFIC,
909 .firmware = "dvb-usb-tvwalkert.fw",
910 .download_firmware = m920x_firmware_download,
911
912 .rc.legacy = {
913 .rc_interval = 100,
914 .rc_map_table = rc_map_tvwalkertwin_table,
915 .rc_map_size = ARRAY_SIZE(rc_map_tvwalkertwin_table),
916 .rc_query = m920x_rc_query,
917 },
918
919 .size_of_priv = sizeof(struct m920x_state),
920
921 .identify_state = m920x_identify_state,
922 .num_adapters = 2,
923 .adapter = {{
924 .num_frontends = 1,
925 .fe = {{
926
927 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
928 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
929
930 .pid_filter_count = 8,
931 .pid_filter = m920x_pid_filter,
932 .pid_filter_ctrl = m920x_pid_filter_ctrl,
933
934 .frontend_attach = m920x_tda10046_08_frontend_attach,
935 .tuner_attach = m920x_tda8275_60_tuner_attach,
936
937 .stream = {
938 .type = USB_BULK,
939 .count = 8,
940 .endpoint = 0x81,
941 .u = {
942 .bulk = {
943 .buffersize = 512,
944 }
945 }
946 }},
947 }},{
948 .num_frontends = 1,
949 .fe = {{
950
951 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
952 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
953
954 .pid_filter_count = 8,
955 .pid_filter = m920x_pid_filter,
956 .pid_filter_ctrl = m920x_pid_filter_ctrl,
957
958 .frontend_attach = m920x_tda10046_0b_frontend_attach,
959 .tuner_attach = m920x_tda8275_61_tuner_attach,
960
961 .stream = {
962 .type = USB_BULK,
963 .count = 8,
964 .endpoint = 0x82,
965 .u = {
966 .bulk = {
967 .buffersize = 512,
968 }
969 }
970 }},
971 },
972 }},
973 .i2c_algo = &m920x_i2c_algo,
974
975 .num_device_descs = 1,
976 .devices = {
977 { .name = "LifeView TV Walker Twin DVB-T USB2.0",
978 .cold_ids = { &m920x_table[2], NULL },
979 .warm_ids = { &m920x_table[3], NULL },
980 },
981 }
982};
983
984static struct dvb_usb_device_properties dposh_properties = {
985 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
986
987 .usb_ctrl = DEVICE_SPECIFIC,
988 .firmware = "dvb-usb-dposh-01.fw",
989 .download_firmware = m920x_firmware_download,
990
991 .size_of_priv = sizeof(struct m920x_state),
992
993 .identify_state = m920x_identify_state,
994 .num_adapters = 1,
995 .adapter = {{
996 .num_frontends = 1,
997 .fe = {{
998 /* Hardware pid filters don't work with this device/firmware */
999
1000 .frontend_attach = m920x_mt352_frontend_attach,
1001 .tuner_attach = m920x_qt1010_tuner_attach,
1002
1003 .stream = {
1004 .type = USB_BULK,
1005 .count = 8,
1006 .endpoint = 0x81,
1007 .u = {
1008 .bulk = {
1009 .buffersize = 512,
1010 }
1011 }
1012 },
1013 }},
1014 }},
1015 .i2c_algo = &m920x_i2c_algo,
1016
1017 .num_device_descs = 1,
1018 .devices = {
1019 { .name = "Dposh DVB-T USB2.0",
1020 .cold_ids = { &m920x_table[4], NULL },
1021 .warm_ids = { &m920x_table[5], NULL },
1022 },
1023 }
1024};
1025
1026static struct dvb_usb_device_properties pinnacle_pctv310e_properties = {
1027 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1028
1029 .usb_ctrl = DEVICE_SPECIFIC,
1030 .download_firmware = NULL,
1031
1032 .rc.legacy = {
1033 .rc_interval = 100,
1034 .rc_map_table = rc_map_pinnacle310e_table,
1035 .rc_map_size = ARRAY_SIZE(rc_map_pinnacle310e_table),
1036 .rc_query = m920x_rc_query,
1037 },
1038
1039 .size_of_priv = sizeof(struct m920x_state),
1040
1041 .identify_state = m920x_identify_state,
1042 .num_adapters = 1,
1043 .adapter = {{
1044 .num_frontends = 1,
1045 .fe = {{
1046
1047 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
1048 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
1049
1050 .pid_filter_count = 8,
1051 .pid_filter = m920x_pid_filter,
1052 .pid_filter_ctrl = m920x_pid_filter_ctrl,
1053
1054 .frontend_attach = m920x_mt352_frontend_attach,
1055 .tuner_attach = m920x_fmd1216me_tuner_attach,
1056
1057 .stream = {
1058 .type = USB_ISOC,
1059 .count = 5,
1060 .endpoint = 0x84,
1061 .u = {
1062 .isoc = {
1063 .framesperurb = 128,
1064 .framesize = 564,
1065 .interval = 1,
1066 }
1067 }
1068 },
1069 }},
1070 } },
1071 .i2c_algo = &m920x_i2c_algo,
1072
1073 .num_device_descs = 1,
1074 .devices = {
1075 { "Pinnacle PCTV 310e",
1076 { &m920x_table[6], NULL },
1077 { NULL },
1078 }
1079 }
1080};
1081
1082static struct usb_driver m920x_driver = {
1083 .name = "dvb_usb_m920x",
1084 .probe = m920x_probe,
1085 .disconnect = dvb_usb_device_exit,
1086 .id_table = m920x_table,
1087};
1088
1089module_usb_driver(m920x_driver);
1090
1091MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
1092MODULE_DESCRIPTION("DVB Driver for ULI M920x");
1093MODULE_VERSION("0.1");
1094MODULE_LICENSE("GPL");
1095
1096/*
1097 * Local variables:
1098 * c-basic-offset: 8
1099 */
diff --git a/drivers/media/usb/dvb-usb/m920x.h b/drivers/media/usb/dvb-usb/m920x.h
new file mode 100644
index 000000000000..3c061518ffc1
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/m920x.h
@@ -0,0 +1,77 @@
1#ifndef _DVB_USB_M920X_H_
2#define _DVB_USB_M920X_H_
3
4#define DVB_USB_LOG_PREFIX "m920x"
5#include "dvb-usb.h"
6
7#define deb(args...) dprintk(dvb_usb_m920x_debug,0x01,args)
8
9#define M9206_CORE 0x22
10#define M9206_RC_STATE 0xff51
11#define M9206_RC_KEY 0xff52
12#define M9206_RC_INIT1 0xff54
13#define M9206_RC_INIT2 0xff55
14#define M9206_FW_GO 0xff69
15
16#define M9206_I2C 0x23
17#define M9206_FILTER 0x25
18#define M9206_FW 0x30
19
20#define M9206_MAX_FILTERS 8
21#define M9206_MAX_ADAPTERS 4
22
23/*
24sequences found in logs:
25[index value]
260x80 write addr
27(0x00 out byte)*
280x40 out byte
29
300x80 write addr
31(0x00 out byte)*
320x80 read addr
33(0x21 in byte)*
340x60 in byte
35
36this sequence works:
370x80 read addr
38(0x21 in byte)*
390x60 in byte
40
41Guess at API of the I2C function:
42I2C operation is done one byte at a time with USB control messages. The
43index the messages is sent to is made up of a set of flags that control
44the I2C bus state:
450x80: Send START condition. After a START condition, one would normally
46 always send the 7-bit slave I2C address as the 7 MSB, followed by
47 the read/write bit as the LSB.
480x40: Send STOP condition. This should be set on the last byte of an
49 I2C transaction.
500x20: Read a byte from the slave. As opposed to writing a byte to the
51 slave. The slave will normally not produce any data unless you
52 set the R/W bit to 1 when sending the slave's address after the
53 START condition.
540x01: Respond with ACK, as opposed to a NACK. For a multi-byte read,
55 the master should send an ACK, that is pull SDA low during the 9th
56 clock cycle, after every byte but the last. This flags only makes
57 sense when bit 0x20 is set, indicating a read.
58
59What any other bits might mean, or how to get the slave's ACK/NACK
60response to a write, is unknown.
61*/
62
63struct m920x_state {
64 u16 filters[M9206_MAX_ADAPTERS][M9206_MAX_FILTERS];
65 int filtering_enabled[M9206_MAX_ADAPTERS];
66 int rep_count;
67};
68
69/* Initialisation data for the m920x
70 */
71
72struct m920x_inits {
73 u16 address;
74 u8 data;
75};
76
77#endif
diff --git a/drivers/media/usb/dvb-usb/nova-t-usb2.c b/drivers/media/usb/dvb-usb/nova-t-usb2.c
new file mode 100644
index 000000000000..6c55384e2fca
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/nova-t-usb2.c
@@ -0,0 +1,233 @@
1/* DVB USB framework compliant Linux driver for the Hauppauge WinTV-NOVA-T usb2
2 * DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "dibusb.h"
13
14static int debug;
15module_param(debug, int, 0644);
16MODULE_PARM_DESC(debug, "set debugging level (1=rc,2=eeprom (|-able))." DVB_USB_DEBUG_STATUS);
17
18DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
19
20#define deb_rc(args...) dprintk(debug,0x01,args)
21#define deb_ee(args...) dprintk(debug,0x02,args)
22
23/* Hauppauge NOVA-T USB2 keys */
24static struct rc_map_table rc_map_haupp_table[] = {
25 { 0x1e00, KEY_0 },
26 { 0x1e01, KEY_1 },
27 { 0x1e02, KEY_2 },
28 { 0x1e03, KEY_3 },
29 { 0x1e04, KEY_4 },
30 { 0x1e05, KEY_5 },
31 { 0x1e06, KEY_6 },
32 { 0x1e07, KEY_7 },
33 { 0x1e08, KEY_8 },
34 { 0x1e09, KEY_9 },
35 { 0x1e0a, KEY_KPASTERISK },
36 { 0x1e0b, KEY_RED },
37 { 0x1e0c, KEY_RADIO },
38 { 0x1e0d, KEY_MENU },
39 { 0x1e0e, KEY_GRAVE }, /* # */
40 { 0x1e0f, KEY_MUTE },
41 { 0x1e10, KEY_VOLUMEUP },
42 { 0x1e11, KEY_VOLUMEDOWN },
43 { 0x1e12, KEY_CHANNEL },
44 { 0x1e14, KEY_UP },
45 { 0x1e15, KEY_DOWN },
46 { 0x1e16, KEY_LEFT },
47 { 0x1e17, KEY_RIGHT },
48 { 0x1e18, KEY_VIDEO },
49 { 0x1e19, KEY_AUDIO },
50 { 0x1e1a, KEY_IMAGES },
51 { 0x1e1b, KEY_EPG },
52 { 0x1e1c, KEY_TV },
53 { 0x1e1e, KEY_NEXT },
54 { 0x1e1f, KEY_BACK },
55 { 0x1e20, KEY_CHANNELUP },
56 { 0x1e21, KEY_CHANNELDOWN },
57 { 0x1e24, KEY_LAST }, /* Skip backwards */
58 { 0x1e25, KEY_OK },
59 { 0x1e29, KEY_BLUE},
60 { 0x1e2e, KEY_GREEN },
61 { 0x1e30, KEY_PAUSE },
62 { 0x1e32, KEY_REWIND },
63 { 0x1e34, KEY_FASTFORWARD },
64 { 0x1e35, KEY_PLAY },
65 { 0x1e36, KEY_STOP },
66 { 0x1e37, KEY_RECORD },
67 { 0x1e38, KEY_YELLOW },
68 { 0x1e3b, KEY_GOTO },
69 { 0x1e3d, KEY_POWER },
70};
71
72/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key
73 * is delivered. No workaround yet, maybe a new firmware.
74 */
75static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
76{
77 u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom;
78 u16 raw;
79 int i;
80 struct dibusb_device_state *st = d->priv;
81
82 dvb_usb_generic_rw(d,cmd,2,key,5,0);
83
84 *state = REMOTE_NO_KEY_PRESSED;
85 switch (key[0]) {
86 case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
87 raw = ((key[1] << 8) | key[2]) >> 3;
88 toggle = !!(raw & 0x800);
89 data = raw & 0x3f;
90 custom = (raw >> 6) & 0x1f;
91
92 deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);
93
94 for (i = 0; i < ARRAY_SIZE(rc_map_haupp_table); i++) {
95 if (rc5_data(&rc_map_haupp_table[i]) == data &&
96 rc5_custom(&rc_map_haupp_table[i]) == custom) {
97
98 deb_rc("c: %x, d: %x\n", rc5_data(&rc_map_haupp_table[i]),
99 rc5_custom(&rc_map_haupp_table[i]));
100
101 *event = rc_map_haupp_table[i].keycode;
102 *state = REMOTE_KEY_PRESSED;
103 if (st->old_toggle == toggle) {
104 if (st->last_repeat_count++ < 2)
105 *state = REMOTE_NO_KEY_PRESSED;
106 } else {
107 st->last_repeat_count = 0;
108 st->old_toggle = toggle;
109 }
110 break;
111 }
112 }
113
114 break;
115 case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
116 default:
117 break;
118 }
119
120 return 0;
121}
122
123static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6])
124{
125 int i;
126 u8 b;
127
128 mac[0] = 0x00;
129 mac[1] = 0x0d;
130 mac[2] = 0xfe;
131
132 /* this is a complete guess, but works for my box */
133 for (i = 136; i < 139; i++) {
134 dibusb_read_eeprom_byte(d,i, &b);
135
136 mac[5 - (i - 136)] = b;
137 }
138
139 return 0;
140}
141
142/* USB Driver stuff */
143static struct dvb_usb_device_properties nova_t_properties;
144
145static int nova_t_probe(struct usb_interface *intf,
146 const struct usb_device_id *id)
147{
148 return dvb_usb_device_init(intf, &nova_t_properties,
149 THIS_MODULE, NULL, adapter_nr);
150}
151
152/* do not change the order of the ID table */
153static struct usb_device_id nova_t_table [] = {
154/* 00 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_COLD) },
155/* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) },
156 { } /* Terminating entry */
157};
158MODULE_DEVICE_TABLE(usb, nova_t_table);
159
160static struct dvb_usb_device_properties nova_t_properties = {
161 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
162
163 .usb_ctrl = CYPRESS_FX2,
164 .firmware = "dvb-usb-nova-t-usb2-02.fw",
165
166 .num_adapters = 1,
167 .adapter = {
168 {
169 .num_frontends = 1,
170 .fe = {{
171 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
172 .pid_filter_count = 32,
173
174 .streaming_ctrl = dibusb2_0_streaming_ctrl,
175 .pid_filter = dibusb_pid_filter,
176 .pid_filter_ctrl = dibusb_pid_filter_ctrl,
177 .frontend_attach = dibusb_dib3000mc_frontend_attach,
178 .tuner_attach = dibusb_dib3000mc_tuner_attach,
179
180 /* parameter for the MPEG2-data transfer */
181 .stream = {
182 .type = USB_BULK,
183 .count = 7,
184 .endpoint = 0x06,
185 .u = {
186 .bulk = {
187 .buffersize = 4096,
188 }
189 }
190 },
191 }},
192 .size_of_priv = sizeof(struct dibusb_state),
193 }
194 },
195 .size_of_priv = sizeof(struct dibusb_device_state),
196
197 .power_ctrl = dibusb2_0_power_ctrl,
198 .read_mac_address = nova_t_read_mac_address,
199
200 .rc.legacy = {
201 .rc_interval = 100,
202 .rc_map_table = rc_map_haupp_table,
203 .rc_map_size = ARRAY_SIZE(rc_map_haupp_table),
204 .rc_query = nova_t_rc_query,
205 },
206
207 .i2c_algo = &dibusb_i2c_algo,
208
209 .generic_bulk_ctrl_endpoint = 0x01,
210
211 .num_device_descs = 1,
212 .devices = {
213 { "Hauppauge WinTV-NOVA-T usb2",
214 { &nova_t_table[0], NULL },
215 { &nova_t_table[1], NULL },
216 },
217 { NULL },
218 }
219};
220
221static struct usb_driver nova_t_driver = {
222 .name = "dvb_usb_nova_t_usb2",
223 .probe = nova_t_probe,
224 .disconnect = dvb_usb_device_exit,
225 .id_table = nova_t_table,
226};
227
228module_usb_driver(nova_t_driver);
229
230MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
231MODULE_DESCRIPTION("Hauppauge WinTV-NOVA-T usb2");
232MODULE_VERSION("1.0");
233MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/opera1.c b/drivers/media/usb/dvb-usb/opera1.c
new file mode 100644
index 000000000000..c8a95042dfbc
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/opera1.c
@@ -0,0 +1,583 @@
1/* DVB USB framework compliant Linux driver for the Opera1 DVB-S Card
2*
3* Copyright (C) 2006 Mario Hlawitschka (dh1pa@amsat.org)
4* Copyright (C) 2006 Marco Gittler (g.marco@freenet.de)
5*
6* This program is free software; you can redistribute it and/or modify it
7* under the terms of the GNU General Public License as published by the Free
8* Software Foundation, version 2.
9*
10* see Documentation/dvb/README.dvb-usb for more information
11*/
12
13#define DVB_USB_LOG_PREFIX "opera"
14
15#include "dvb-usb.h"
16#include "stv0299.h"
17
18#define OPERA_READ_MSG 0
19#define OPERA_WRITE_MSG 1
20#define OPERA_I2C_TUNER 0xd1
21
22#define READ_FX2_REG_REQ 0xba
23#define READ_MAC_ADDR 0x08
24#define OPERA_WRITE_FX2 0xbb
25#define OPERA_TUNER_REQ 0xb1
26#define REG_1F_SYMBOLRATE_BYTE0 0x1f
27#define REG_20_SYMBOLRATE_BYTE1 0x20
28#define REG_21_SYMBOLRATE_BYTE2 0x21
29
30#define ADDR_B600_VOLTAGE_13V (0x02)
31#define ADDR_B601_VOLTAGE_18V (0x03)
32#define ADDR_B1A6_STREAM_CTRL (0x04)
33#define ADDR_B880_READ_REMOTE (0x05)
34
35struct opera1_state {
36 u32 last_key_pressed;
37};
38struct rc_map_opera_table {
39 u32 keycode;
40 u32 event;
41};
42
43static int dvb_usb_opera1_debug;
44module_param_named(debug, dvb_usb_opera1_debug, int, 0644);
45MODULE_PARM_DESC(debug,
46 "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))."
47 DVB_USB_DEBUG_STATUS);
48
49DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
50
51
52static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value,
53 u8 * data, u16 len, int flags)
54{
55 int ret;
56 u8 tmp;
57 u8 *buf;
58 unsigned int pipe = (flags == OPERA_READ_MSG) ?
59 usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0);
60 u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
61
62 buf = kmalloc(len, GFP_KERNEL);
63 if (!buf)
64 return -ENOMEM;
65
66 if (flags == OPERA_WRITE_MSG)
67 memcpy(buf, data, len);
68 ret = usb_control_msg(dev, pipe, request,
69 request_type | USB_TYPE_VENDOR, value, 0x0,
70 buf, len, 2000);
71
72 if (request == OPERA_TUNER_REQ) {
73 tmp = buf[0];
74 if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
75 OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
76 0x01, 0x0, buf, 1, 2000) < 1 || buf[0] != 0x08) {
77 ret = 0;
78 goto out;
79 }
80 buf[0] = tmp;
81 }
82 if (flags == OPERA_READ_MSG)
83 memcpy(data, buf, len);
84out:
85 kfree(buf);
86 return ret;
87}
88
89/* I2C */
90
91static int opera1_usb_i2c_msgxfer(struct dvb_usb_device *dev, u16 addr,
92 u8 * buf, u16 len)
93{
94 int ret = 0;
95 u8 request;
96 u16 value;
97
98 if (!dev) {
99 info("no usb_device");
100 return -EINVAL;
101 }
102 if (mutex_lock_interruptible(&dev->usb_mutex) < 0)
103 return -EAGAIN;
104
105 switch (addr>>1){
106 case ADDR_B600_VOLTAGE_13V:
107 request=0xb6;
108 value=0x00;
109 break;
110 case ADDR_B601_VOLTAGE_18V:
111 request=0xb6;
112 value=0x01;
113 break;
114 case ADDR_B1A6_STREAM_CTRL:
115 request=0xb1;
116 value=0xa6;
117 break;
118 case ADDR_B880_READ_REMOTE:
119 request=0xb8;
120 value=0x80;
121 break;
122 default:
123 request=0xb1;
124 value=addr;
125 }
126 ret = opera1_xilinx_rw(dev->udev, request,
127 value, buf, len,
128 addr&0x01?OPERA_READ_MSG:OPERA_WRITE_MSG);
129
130 mutex_unlock(&dev->usb_mutex);
131 return ret;
132}
133
134static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
135 int num)
136{
137 struct dvb_usb_device *d = i2c_get_adapdata(adap);
138 int i = 0, tmp = 0;
139
140 if (!d)
141 return -ENODEV;
142 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
143 return -EAGAIN;
144
145 for (i = 0; i < num; i++) {
146 if ((tmp = opera1_usb_i2c_msgxfer(d,
147 (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0),
148 msg[i].buf,
149 msg[i].len
150 )) != msg[i].len) {
151 break;
152 }
153 if (dvb_usb_opera1_debug & 0x10)
154 info("sending i2c mesage %d %d", tmp, msg[i].len);
155 }
156 mutex_unlock(&d->i2c_mutex);
157 return num;
158}
159
160static u32 opera1_i2c_func(struct i2c_adapter *adapter)
161{
162 return I2C_FUNC_I2C;
163}
164
165static struct i2c_algorithm opera1_i2c_algo = {
166 .master_xfer = opera1_i2c_xfer,
167 .functionality = opera1_i2c_func,
168};
169
170static int opera1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
171{
172 static u8 command_13v[1]={0x00};
173 static u8 command_18v[1]={0x01};
174 struct i2c_msg msg[] = {
175 {.addr = ADDR_B600_VOLTAGE_13V,.flags = 0,.buf = command_13v,.len = 1},
176 };
177 struct dvb_usb_adapter *udev_adap =
178 (struct dvb_usb_adapter *)(fe->dvb->priv);
179 if (voltage == SEC_VOLTAGE_18) {
180 msg[0].addr = ADDR_B601_VOLTAGE_18V;
181 msg[0].buf = command_18v;
182 }
183 i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
184 return 0;
185}
186
187static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate,
188 u32 ratio)
189{
190 stv0299_writereg(fe, 0x13, 0x98);
191 stv0299_writereg(fe, 0x14, 0x95);
192 stv0299_writereg(fe, REG_1F_SYMBOLRATE_BYTE0, (ratio >> 16) & 0xff);
193 stv0299_writereg(fe, REG_20_SYMBOLRATE_BYTE1, (ratio >> 8) & 0xff);
194 stv0299_writereg(fe, REG_21_SYMBOLRATE_BYTE2, (ratio) & 0xf0);
195 return 0;
196
197}
198static u8 opera1_inittab[] = {
199 0x00, 0xa1,
200 0x01, 0x15,
201 0x02, 0x30,
202 0x03, 0x00,
203 0x04, 0x7d,
204 0x05, 0x05,
205 0x06, 0x02,
206 0x07, 0x00,
207 0x0b, 0x00,
208 0x0c, 0x01,
209 0x0d, 0x81,
210 0x0e, 0x44,
211 0x0f, 0x19,
212 0x10, 0x3f,
213 0x11, 0x84,
214 0x12, 0xda,
215 0x13, 0x98,
216 0x14, 0x95,
217 0x15, 0xc9,
218 0x16, 0xeb,
219 0x17, 0x00,
220 0x18, 0x19,
221 0x19, 0x8b,
222 0x1a, 0x00,
223 0x1b, 0x82,
224 0x1c, 0x7f,
225 0x1d, 0x00,
226 0x1e, 0x00,
227 REG_1F_SYMBOLRATE_BYTE0, 0x06,
228 REG_20_SYMBOLRATE_BYTE1, 0x50,
229 REG_21_SYMBOLRATE_BYTE2, 0x10,
230 0x22, 0x00,
231 0x23, 0x00,
232 0x24, 0x37,
233 0x25, 0xbc,
234 0x26, 0x00,
235 0x27, 0x00,
236 0x28, 0x00,
237 0x29, 0x1e,
238 0x2a, 0x14,
239 0x2b, 0x1f,
240 0x2c, 0x09,
241 0x2d, 0x0a,
242 0x2e, 0x00,
243 0x2f, 0x00,
244 0x30, 0x00,
245 0x31, 0x1f,
246 0x32, 0x19,
247 0x33, 0xfc,
248 0x34, 0x13,
249 0xff, 0xff,
250};
251
252static struct stv0299_config opera1_stv0299_config = {
253 .demod_address = 0xd0>>1,
254 .min_delay_ms = 100,
255 .mclk = 88000000UL,
256 .invert = 1,
257 .skip_reinit = 0,
258 .lock_output = STV0299_LOCKOUTPUT_0,
259 .volt13_op0_op1 = STV0299_VOLT13_OP0,
260 .inittab = opera1_inittab,
261 .set_symbol_rate = opera1_stv0299_set_symbol_rate,
262};
263
264static int opera1_frontend_attach(struct dvb_usb_adapter *d)
265{
266 d->fe_adap[0].fe = dvb_attach(stv0299_attach, &opera1_stv0299_config,
267 &d->dev->i2c_adap);
268 if ((d->fe_adap[0].fe) != NULL) {
269 d->fe_adap[0].fe->ops.set_voltage = opera1_set_voltage;
270 return 0;
271 }
272 info("not attached stv0299");
273 return -EIO;
274}
275
276static int opera1_tuner_attach(struct dvb_usb_adapter *adap)
277{
278 dvb_attach(
279 dvb_pll_attach, adap->fe_adap[0].fe, 0xc0>>1,
280 &adap->dev->i2c_adap, DVB_PLL_OPERA1
281 );
282 return 0;
283}
284
285static int opera1_power_ctrl(struct dvb_usb_device *d, int onoff)
286{
287 u8 val = onoff ? 0x01 : 0x00;
288
289 if (dvb_usb_opera1_debug)
290 info("power %s", onoff ? "on" : "off");
291 return opera1_xilinx_rw(d->udev, 0xb7, val,
292 &val, 1, OPERA_WRITE_MSG);
293}
294
295static int opera1_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
296{
297 static u8 buf_start[2] = { 0xff, 0x03 };
298 static u8 buf_stop[2] = { 0xff, 0x00 };
299 struct i2c_msg start_tuner[] = {
300 {.addr = ADDR_B1A6_STREAM_CTRL,.buf = onoff ? buf_start : buf_stop,.len = 2},
301 };
302 if (dvb_usb_opera1_debug)
303 info("streaming %s", onoff ? "on" : "off");
304 i2c_transfer(&adap->dev->i2c_adap, start_tuner, 1);
305 return 0;
306}
307
308static int opera1_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
309 int onoff)
310{
311 u8 b_pid[3];
312 struct i2c_msg msg[] = {
313 {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
314 };
315 if (dvb_usb_opera1_debug)
316 info("pidfilter index: %d pid: %d %s", index, pid,
317 onoff ? "on" : "off");
318 b_pid[0] = (2 * index) + 4;
319 b_pid[1] = onoff ? (pid & 0xff) : (0x00);
320 b_pid[2] = onoff ? ((pid >> 8) & 0xff) : (0x00);
321 i2c_transfer(&adap->dev->i2c_adap, msg, 1);
322 return 0;
323}
324
325static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff)
326{
327 int u = 0x04;
328 u8 b_pid[3];
329 struct i2c_msg msg[] = {
330 {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3},
331 };
332 if (dvb_usb_opera1_debug)
333 info("%s hw-pidfilter", onoff ? "enable" : "disable");
334 for (; u < 0x7e; u += 2) {
335 b_pid[0] = u;
336 b_pid[1] = 0;
337 b_pid[2] = 0x80;
338 i2c_transfer(&adap->dev->i2c_adap, msg, 1);
339 }
340 return 0;
341}
342
343static struct rc_map_table rc_map_opera1_table[] = {
344 {0x5fa0, KEY_1},
345 {0x51af, KEY_2},
346 {0x5da2, KEY_3},
347 {0x41be, KEY_4},
348 {0x0bf5, KEY_5},
349 {0x43bd, KEY_6},
350 {0x47b8, KEY_7},
351 {0x49b6, KEY_8},
352 {0x05fa, KEY_9},
353 {0x45ba, KEY_0},
354 {0x09f6, KEY_CHANNELUP}, /*chanup */
355 {0x1be5, KEY_CHANNELDOWN}, /*chandown */
356 {0x5da3, KEY_VOLUMEDOWN}, /*voldown */
357 {0x5fa1, KEY_VOLUMEUP}, /*volup */
358 {0x07f8, KEY_SPACE}, /*tab */
359 {0x1fe1, KEY_OK}, /*play ok */
360 {0x1be4, KEY_ZOOM}, /*zoom */
361 {0x59a6, KEY_MUTE}, /*mute */
362 {0x5ba5, KEY_RADIO}, /*tv/f */
363 {0x19e7, KEY_RECORD}, /*rec */
364 {0x01fe, KEY_STOP}, /*Stop */
365 {0x03fd, KEY_PAUSE}, /*pause */
366 {0x03fc, KEY_SCREEN}, /*<- -> */
367 {0x07f9, KEY_CAMERA}, /*capture */
368 {0x47b9, KEY_ESC}, /*exit */
369 {0x43bc, KEY_POWER2}, /*power */
370};
371
372static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
373{
374 struct opera1_state *opst = dev->priv;
375 u8 rcbuffer[32];
376 const u16 startmarker1 = 0x10ed;
377 const u16 startmarker2 = 0x11ec;
378 struct i2c_msg read_remote[] = {
379 {.addr = ADDR_B880_READ_REMOTE,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32},
380 };
381 int i = 0;
382 u32 send_key = 0;
383
384 if (i2c_transfer(&dev->i2c_adap, read_remote, 1) == 1) {
385 for (i = 0; i < 32; i++) {
386 if (rcbuffer[i])
387 send_key |= 1;
388 if (i < 31)
389 send_key = send_key << 1;
390 }
391 if (send_key & 0x8000)
392 send_key = (send_key << 1) | (send_key >> 15 & 0x01);
393
394 if (send_key == 0xffff && opst->last_key_pressed != 0) {
395 *state = REMOTE_KEY_REPEAT;
396 *event = opst->last_key_pressed;
397 return 0;
398 }
399 for (; send_key != 0;) {
400 if (send_key >> 16 == startmarker2) {
401 break;
402 } else if (send_key >> 16 == startmarker1) {
403 send_key =
404 (send_key & 0xfffeffff) | (startmarker1 << 16);
405 break;
406 } else
407 send_key >>= 1;
408 }
409
410 if (send_key == 0)
411 return 0;
412
413 send_key = (send_key & 0xffff) | 0x0100;
414
415 for (i = 0; i < ARRAY_SIZE(rc_map_opera1_table); i++) {
416 if (rc5_scan(&rc_map_opera1_table[i]) == (send_key & 0xffff)) {
417 *state = REMOTE_KEY_PRESSED;
418 *event = rc_map_opera1_table[i].keycode;
419 opst->last_key_pressed =
420 rc_map_opera1_table[i].keycode;
421 break;
422 }
423 opst->last_key_pressed = 0;
424 }
425 } else
426 *state = REMOTE_NO_KEY_PRESSED;
427 return 0;
428}
429
430static struct usb_device_id opera1_table[] = {
431 {USB_DEVICE(USB_VID_CYPRESS, USB_PID_OPERA1_COLD)},
432 {USB_DEVICE(USB_VID_OPERA1, USB_PID_OPERA1_WARM)},
433 {}
434};
435
436MODULE_DEVICE_TABLE(usb, opera1_table);
437
438static int opera1_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
439{
440 u8 command[] = { READ_MAC_ADDR };
441 opera1_xilinx_rw(d->udev, 0xb1, 0xa0, command, 1, OPERA_WRITE_MSG);
442 opera1_xilinx_rw(d->udev, 0xb1, 0xa1, mac, 6, OPERA_READ_MSG);
443 return 0;
444}
445static int opera1_xilinx_load_firmware(struct usb_device *dev,
446 const char *filename)
447{
448 const struct firmware *fw = NULL;
449 u8 *b, *p;
450 int ret = 0, i,fpgasize=40;
451 u8 testval;
452 info("start downloading fpga firmware %s",filename);
453
454 if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) {
455 err("did not find the firmware file. (%s) "
456 "Please see linux/Documentation/dvb/ for more details on firmware-problems.",
457 filename);
458 return ret;
459 } else {
460 p = kmalloc(fw->size, GFP_KERNEL);
461 opera1_xilinx_rw(dev, 0xbc, 0x00, &testval, 1, OPERA_READ_MSG);
462 if (p != NULL && testval != 0x67) {
463
464 u8 reset = 0, fpga_command = 0;
465 memcpy(p, fw->data, fw->size);
466 /* clear fpga ? */
467 opera1_xilinx_rw(dev, 0xbc, 0xaa, &fpga_command, 1,
468 OPERA_WRITE_MSG);
469 for (i = 0; i < fw->size;) {
470 if ( (fw->size - i) <fpgasize){
471 fpgasize=fw->size-i;
472 }
473 b = (u8 *) p + i;
474 if (opera1_xilinx_rw
475 (dev, OPERA_WRITE_FX2, 0x0, b , fpgasize,
476 OPERA_WRITE_MSG) != fpgasize
477 ) {
478 err("error while transferring firmware");
479 ret = -EINVAL;
480 break;
481 }
482 i = i + fpgasize;
483 }
484 /* restart the CPU */
485 if (ret || opera1_xilinx_rw
486 (dev, 0xa0, 0xe600, &reset, 1,
487 OPERA_WRITE_MSG) != 1) {
488 err("could not restart the USB controller CPU.");
489 ret = -EINVAL;
490 }
491 }
492 }
493 kfree(p);
494 release_firmware(fw);
495 return ret;
496}
497
498static struct dvb_usb_device_properties opera1_properties = {
499 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
500 .usb_ctrl = CYPRESS_FX2,
501 .firmware = "dvb-usb-opera-01.fw",
502 .size_of_priv = sizeof(struct opera1_state),
503
504 .power_ctrl = opera1_power_ctrl,
505 .i2c_algo = &opera1_i2c_algo,
506
507 .rc.legacy = {
508 .rc_map_table = rc_map_opera1_table,
509 .rc_map_size = ARRAY_SIZE(rc_map_opera1_table),
510 .rc_interval = 200,
511 .rc_query = opera1_rc_query,
512 },
513 .read_mac_address = opera1_read_mac_address,
514 .generic_bulk_ctrl_endpoint = 0x00,
515 /* parameter for the MPEG2-data transfer */
516 .num_adapters = 1,
517 .adapter = {
518 {
519 .num_frontends = 1,
520 .fe = {{
521 .frontend_attach = opera1_frontend_attach,
522 .streaming_ctrl = opera1_streaming_ctrl,
523 .tuner_attach = opera1_tuner_attach,
524 .caps =
525 DVB_USB_ADAP_HAS_PID_FILTER |
526 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
527 .pid_filter = opera1_pid_filter,
528 .pid_filter_ctrl = opera1_pid_filter_control,
529 .pid_filter_count = 252,
530 .stream = {
531 .type = USB_BULK,
532 .count = 10,
533 .endpoint = 0x82,
534 .u = {
535 .bulk = {
536 .buffersize = 4096,
537 }
538 }
539 },
540 }},
541 }
542 },
543 .num_device_descs = 1,
544 .devices = {
545 {"Opera1 DVB-S USB2.0",
546 {&opera1_table[0], NULL},
547 {&opera1_table[1], NULL},
548 },
549 }
550};
551
552static int opera1_probe(struct usb_interface *intf,
553 const struct usb_device_id *id)
554{
555 struct usb_device *udev = interface_to_usbdev(intf);
556
557 if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM &&
558 udev->descriptor.idVendor == USB_VID_OPERA1 &&
559 opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga-01.fw") != 0
560 ) {
561 return -EINVAL;
562 }
563
564 if (0 != dvb_usb_device_init(intf, &opera1_properties,
565 THIS_MODULE, NULL, adapter_nr))
566 return -EINVAL;
567 return 0;
568}
569
570static struct usb_driver opera1_driver = {
571 .name = "opera1",
572 .probe = opera1_probe,
573 .disconnect = dvb_usb_device_exit,
574 .id_table = opera1_table,
575};
576
577module_usb_driver(opera1_driver);
578
579MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org");
580MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de");
581MODULE_DESCRIPTION("Driver for Opera1 DVB-S device");
582MODULE_VERSION("0.1");
583MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
new file mode 100644
index 000000000000..02e878577c3d
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/pctv452e.c
@@ -0,0 +1,1063 @@
1/*
2 * PCTV 452e DVB driver
3 *
4 * Copyright (c) 2006-2008 Dominik Kuhlen <dkuhlen@gmx.net>
5 *
6 * TT connect S2-3650-CI Common Interface support, MAC readout
7 * Copyright (C) 2008 Michael H. Schimek <mschimek@gmx.at>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 */
14
15/* dvb usb framework */
16#define DVB_USB_LOG_PREFIX "pctv452e"
17#include "dvb-usb.h"
18
19/* Demodulator */
20#include "stb0899_drv.h"
21#include "stb0899_reg.h"
22#include "stb0899_cfg.h"
23/* Tuner */
24#include "stb6100.h"
25#include "stb6100_cfg.h"
26/* FE Power */
27#include "lnbp22.h"
28
29#include "dvb_ca_en50221.h"
30#include "ttpci-eeprom.h"
31
32static int debug;
33module_param(debug, int, 0644);
34MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
35
36DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
37
38#define ISOC_INTERFACE_ALTERNATIVE 3
39
40#define SYNC_BYTE_OUT 0xaa
41#define SYNC_BYTE_IN 0x55
42
43/* guessed: (copied from ttusb-budget) */
44#define PCTV_CMD_RESET 0x15
45/* command to poll IR receiver */
46#define PCTV_CMD_IR 0x1b
47/* command to send I2C */
48#define PCTV_CMD_I2C 0x31
49
50#define I2C_ADDR_STB0899 (0xd0 >> 1)
51#define I2C_ADDR_STB6100 (0xc0 >> 1)
52#define I2C_ADDR_LNBP22 (0x10 >> 1)
53#define I2C_ADDR_24C16 (0xa0 >> 1)
54#define I2C_ADDR_24C64 (0xa2 >> 1)
55
56
57/* pctv452e sends us this amount of data for each issued usb-command */
58#define PCTV_ANSWER_LEN 64
59/* Wait up to 1000ms for device */
60#define PCTV_TIMEOUT 1000
61
62
63#define PCTV_LED_GPIO STB0899_GPIO01
64#define PCTV_LED_GREEN 0x82
65#define PCTV_LED_ORANGE 0x02
66
67#define ci_dbg(format, arg...) \
68do { \
69 if (0) \
70 printk(KERN_DEBUG DVB_USB_LOG_PREFIX \
71 ": " format "\n" , ## arg); \
72} while (0)
73
74enum {
75 TT3650_CMD_CI_TEST = 0x40,
76 TT3650_CMD_CI_RD_CTRL,
77 TT3650_CMD_CI_WR_CTRL,
78 TT3650_CMD_CI_RD_ATTR,
79 TT3650_CMD_CI_WR_ATTR,
80 TT3650_CMD_CI_RESET,
81 TT3650_CMD_CI_SET_VIDEO_PORT
82};
83
84
85static struct stb0899_postproc pctv45e_postproc[] = {
86 { PCTV_LED_GPIO, STB0899_GPIOPULLUP },
87 { 0, 0 }
88};
89
90/*
91 * stores all private variables for communication with the PCTV452e DVB-S2
92 */
93struct pctv452e_state {
94 struct dvb_ca_en50221 ca;
95 struct mutex ca_mutex;
96
97 u8 c; /* transaction counter, wraps around... */
98 u8 initialized; /* set to 1 if 0x15 has been sent */
99 u16 last_rc_key;
100};
101
102static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data,
103 unsigned int write_len, unsigned int read_len)
104{
105 struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
106 u8 buf[64];
107 u8 id;
108 unsigned int rlen;
109 int ret;
110
111 BUG_ON(NULL == data && 0 != (write_len | read_len));
112 BUG_ON(write_len > 64 - 4);
113 BUG_ON(read_len > 64 - 4);
114
115 id = state->c++;
116
117 buf[0] = SYNC_BYTE_OUT;
118 buf[1] = id;
119 buf[2] = cmd;
120 buf[3] = write_len;
121
122 memcpy(buf + 4, data, write_len);
123
124 rlen = (read_len > 0) ? 64 : 0;
125 ret = dvb_usb_generic_rw(d, buf, 4 + write_len,
126 buf, rlen, /* delay_ms */ 0);
127 if (0 != ret)
128 goto failed;
129
130 ret = -EIO;
131 if (SYNC_BYTE_IN != buf[0] || id != buf[1])
132 goto failed;
133
134 memcpy(data, buf + 4, read_len);
135
136 return 0;
137
138failed:
139 err("CI error %d; %02X %02X %02X -> %*ph.",
140 ret, SYNC_BYTE_OUT, id, cmd, 3, buf);
141
142 return ret;
143}
144
145static int tt3650_ci_msg_locked(struct dvb_ca_en50221 *ca,
146 u8 cmd, u8 *data, unsigned int write_len,
147 unsigned int read_len)
148{
149 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
150 struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
151 int ret;
152
153 mutex_lock(&state->ca_mutex);
154 ret = tt3650_ci_msg(d, cmd, data, write_len, read_len);
155 mutex_unlock(&state->ca_mutex);
156
157 return ret;
158}
159
160static int tt3650_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
161 int slot, int address)
162{
163 u8 buf[3];
164 int ret;
165
166 if (0 != slot)
167 return -EINVAL;
168
169 buf[0] = (address >> 8) & 0x0F;
170 buf[1] = address;
171
172 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_ATTR, buf, 2, 3);
173
174 ci_dbg("%s %04x -> %d 0x%02x",
175 __func__, address, ret, buf[2]);
176
177 if (ret < 0)
178 return ret;
179
180 return buf[2];
181}
182
183static int tt3650_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
184 int slot, int address, u8 value)
185{
186 u8 buf[3];
187
188 ci_dbg("%s %d 0x%04x 0x%02x",
189 __func__, slot, address, value);
190
191 if (0 != slot)
192 return -EINVAL;
193
194 buf[0] = (address >> 8) & 0x0F;
195 buf[1] = address;
196 buf[2] = value;
197
198 return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_ATTR, buf, 3, 3);
199}
200
201static int tt3650_ci_read_cam_control(struct dvb_ca_en50221 *ca,
202 int slot,
203 u8 address)
204{
205 u8 buf[2];
206 int ret;
207
208 if (0 != slot)
209 return -EINVAL;
210
211 buf[0] = address & 3;
212
213 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_CTRL, buf, 1, 2);
214
215 ci_dbg("%s 0x%02x -> %d 0x%02x",
216 __func__, address, ret, buf[1]);
217
218 if (ret < 0)
219 return ret;
220
221 return buf[1];
222}
223
224static int tt3650_ci_write_cam_control(struct dvb_ca_en50221 *ca,
225 int slot,
226 u8 address,
227 u8 value)
228{
229 u8 buf[2];
230
231 ci_dbg("%s %d 0x%02x 0x%02x",
232 __func__, slot, address, value);
233
234 if (0 != slot)
235 return -EINVAL;
236
237 buf[0] = address;
238 buf[1] = value;
239
240 return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_CTRL, buf, 2, 2);
241}
242
243static int tt3650_ci_set_video_port(struct dvb_ca_en50221 *ca,
244 int slot,
245 int enable)
246{
247 u8 buf[1];
248 int ret;
249
250 ci_dbg("%s %d %d", __func__, slot, enable);
251
252 if (0 != slot)
253 return -EINVAL;
254
255 enable = !!enable;
256 buf[0] = enable;
257
258 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
259 if (ret < 0)
260 return ret;
261
262 if (enable != buf[0]) {
263 err("CI not %sabled.", enable ? "en" : "dis");
264 return -EIO;
265 }
266
267 return 0;
268}
269
270static int tt3650_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
271{
272 return tt3650_ci_set_video_port(ca, slot, /* enable */ 0);
273}
274
275static int tt3650_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
276{
277 return tt3650_ci_set_video_port(ca, slot, /* enable */ 1);
278}
279
280static int tt3650_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
281{
282 struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
283 struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
284 u8 buf[1];
285 int ret;
286
287 ci_dbg("%s %d", __func__, slot);
288
289 if (0 != slot)
290 return -EINVAL;
291
292 buf[0] = 0;
293
294 mutex_lock(&state->ca_mutex);
295
296 ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
297 if (0 != ret)
298 goto failed;
299
300 msleep(500);
301
302 buf[0] = 1;
303
304 ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
305 if (0 != ret)
306 goto failed;
307
308 msleep(500);
309
310 buf[0] = 0; /* FTA */
311
312 ret = tt3650_ci_msg(d, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
313
314 failed:
315 mutex_unlock(&state->ca_mutex);
316
317 return ret;
318}
319
320static int tt3650_ci_poll_slot_status(struct dvb_ca_en50221 *ca,
321 int slot,
322 int open)
323{
324 u8 buf[1];
325 int ret;
326
327 if (0 != slot)
328 return -EINVAL;
329
330 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_TEST, buf, 0, 1);
331 if (0 != ret)
332 return ret;
333
334 if (1 == buf[0])
335 return DVB_CA_EN50221_POLL_CAM_PRESENT |
336 DVB_CA_EN50221_POLL_CAM_READY;
337
338 return 0;
339
340}
341
342static void tt3650_ci_uninit(struct dvb_usb_device *d)
343{
344 struct pctv452e_state *state;
345
346 ci_dbg("%s", __func__);
347
348 if (NULL == d)
349 return;
350
351 state = (struct pctv452e_state *)d->priv;
352 if (NULL == state)
353 return;
354
355 if (NULL == state->ca.data)
356 return;
357
358 /* Error ignored. */
359 tt3650_ci_set_video_port(&state->ca, /* slot */ 0, /* enable */ 0);
360
361 dvb_ca_en50221_release(&state->ca);
362
363 memset(&state->ca, 0, sizeof(state->ca));
364}
365
366static int tt3650_ci_init(struct dvb_usb_adapter *a)
367{
368 struct dvb_usb_device *d = a->dev;
369 struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
370 int ret;
371
372 ci_dbg("%s", __func__);
373
374 mutex_init(&state->ca_mutex);
375
376 state->ca.owner = THIS_MODULE;
377 state->ca.read_attribute_mem = tt3650_ci_read_attribute_mem;
378 state->ca.write_attribute_mem = tt3650_ci_write_attribute_mem;
379 state->ca.read_cam_control = tt3650_ci_read_cam_control;
380 state->ca.write_cam_control = tt3650_ci_write_cam_control;
381 state->ca.slot_reset = tt3650_ci_slot_reset;
382 state->ca.slot_shutdown = tt3650_ci_slot_shutdown;
383 state->ca.slot_ts_enable = tt3650_ci_slot_ts_enable;
384 state->ca.poll_slot_status = tt3650_ci_poll_slot_status;
385 state->ca.data = d;
386
387 ret = dvb_ca_en50221_init(&a->dvb_adap,
388 &state->ca,
389 /* flags */ 0,
390 /* n_slots */ 1);
391 if (0 != ret) {
392 err("Cannot initialize CI: Error %d.", ret);
393 memset(&state->ca, 0, sizeof(state->ca));
394 return ret;
395 }
396
397 info("CI initialized.");
398
399 return 0;
400}
401
402#define CMD_BUFFER_SIZE 0x28
403static int pctv452e_i2c_msg(struct dvb_usb_device *d, u8 addr,
404 const u8 *snd_buf, u8 snd_len,
405 u8 *rcv_buf, u8 rcv_len)
406{
407 struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
408 u8 buf[64];
409 u8 id;
410 int ret;
411
412 id = state->c++;
413
414 ret = -EINVAL;
415 if (snd_len > 64 - 7 || rcv_len > 64 - 7)
416 goto failed;
417
418 buf[0] = SYNC_BYTE_OUT;
419 buf[1] = id;
420 buf[2] = PCTV_CMD_I2C;
421 buf[3] = snd_len + 3;
422 buf[4] = addr << 1;
423 buf[5] = snd_len;
424 buf[6] = rcv_len;
425
426 memcpy(buf + 7, snd_buf, snd_len);
427
428 ret = dvb_usb_generic_rw(d, buf, 7 + snd_len,
429 buf, /* rcv_len */ 64,
430 /* delay_ms */ 0);
431 if (ret < 0)
432 goto failed;
433
434 /* TT USB protocol error. */
435 ret = -EIO;
436 if (SYNC_BYTE_IN != buf[0] || id != buf[1])
437 goto failed;
438
439 /* I2C device didn't respond as expected. */
440 ret = -EREMOTEIO;
441 if (buf[5] < snd_len || buf[6] < rcv_len)
442 goto failed;
443
444 memcpy(rcv_buf, buf + 7, rcv_len);
445
446 return rcv_len;
447
448failed:
449 err("I2C error %d; %02X %02X %02X %02X %02X -> "
450 "%02X %02X %02X %02X %02X.",
451 ret, SYNC_BYTE_OUT, id, addr << 1, snd_len, rcv_len,
452 buf[0], buf[1], buf[4], buf[5], buf[6]);
453
454 return ret;
455}
456
457static int pctv452e_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msg,
458 int num)
459{
460 struct dvb_usb_device *d = i2c_get_adapdata(adapter);
461 int i;
462
463 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
464 return -EAGAIN;
465
466 for (i = 0; i < num; i++) {
467 u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
468 int ret;
469
470 if (msg[i].flags & I2C_M_RD) {
471 addr = msg[i].addr;
472 snd_buf = NULL;
473 snd_len = 0;
474 rcv_buf = msg[i].buf;
475 rcv_len = msg[i].len;
476 } else {
477 addr = msg[i].addr;
478 snd_buf = msg[i].buf;
479 snd_len = msg[i].len;
480 rcv_buf = NULL;
481 rcv_len = 0;
482 }
483
484 ret = pctv452e_i2c_msg(d, addr, snd_buf, snd_len, rcv_buf,
485 rcv_len);
486 if (ret < rcv_len)
487 break;
488 }
489
490 mutex_unlock(&d->i2c_mutex);
491 return i;
492}
493
494static u32 pctv452e_i2c_func(struct i2c_adapter *adapter)
495{
496 return I2C_FUNC_I2C;
497}
498
499static int pctv452e_power_ctrl(struct dvb_usb_device *d, int i)
500{
501 struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
502 u8 b0[] = { 0xaa, 0, PCTV_CMD_RESET, 1, 0 };
503 u8 rx[PCTV_ANSWER_LEN];
504 int ret;
505
506 info("%s: %d\n", __func__, i);
507
508 if (!i)
509 return 0;
510
511 if (state->initialized)
512 return 0;
513
514 /* hmm where shoud this should go? */
515 ret = usb_set_interface(d->udev, 0, ISOC_INTERFACE_ALTERNATIVE);
516 if (ret != 0)
517 info("%s: Warning set interface returned: %d\n",
518 __func__, ret);
519
520 /* this is a one-time initialization, dont know where to put */
521 b0[1] = state->c++;
522 /* reset board */
523 ret = dvb_usb_generic_rw(d, b0, sizeof(b0), rx, PCTV_ANSWER_LEN, 0);
524 if (ret)
525 return ret;
526
527 b0[1] = state->c++;
528 b0[4] = 1;
529 /* reset board (again?) */
530 ret = dvb_usb_generic_rw(d, b0, sizeof(b0), rx, PCTV_ANSWER_LEN, 0);
531 if (ret)
532 return ret;
533
534 state->initialized = 1;
535
536 return 0;
537}
538
539static int pctv452e_rc_query(struct dvb_usb_device *d)
540{
541 struct pctv452e_state *state = (struct pctv452e_state *)d->priv;
542 u8 b[CMD_BUFFER_SIZE];
543 u8 rx[PCTV_ANSWER_LEN];
544 int ret, i;
545 u8 id = state->c++;
546
547 /* prepare command header */
548 b[0] = SYNC_BYTE_OUT;
549 b[1] = id;
550 b[2] = PCTV_CMD_IR;
551 b[3] = 0;
552
553 /* send ir request */
554 ret = dvb_usb_generic_rw(d, b, 4, rx, PCTV_ANSWER_LEN, 0);
555 if (ret != 0)
556 return ret;
557
558 if (debug > 3) {
559 info("%s: read: %2d: %*ph: ", __func__, ret, 3, rx);
560 for (i = 0; (i < rx[3]) && ((i+3) < PCTV_ANSWER_LEN); i++)
561 info(" %02x", rx[i+3]);
562
563 info("\n");
564 }
565
566 if ((rx[3] == 9) && (rx[12] & 0x01)) {
567 /* got a "press" event */
568 state->last_rc_key = (rx[7] << 8) | rx[6];
569 if (debug > 2)
570 info("%s: cmd=0x%02x sys=0x%02x\n",
571 __func__, rx[6], rx[7]);
572
573 rc_keydown(d->rc_dev, state->last_rc_key, 0);
574 } else if (state->last_rc_key) {
575 rc_keyup(d->rc_dev);
576 state->last_rc_key = 0;
577 }
578
579 return 0;
580}
581
582static int pctv452e_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
583{
584 const u8 mem_addr[] = { 0x1f, 0xcc };
585 u8 encoded_mac[20];
586 int ret;
587
588 ret = -EAGAIN;
589 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
590 goto failed;
591
592 ret = pctv452e_i2c_msg(d, I2C_ADDR_24C16,
593 mem_addr + 1, /* snd_len */ 1,
594 encoded_mac, /* rcv_len */ 20);
595 if (-EREMOTEIO == ret)
596 /* Caution! A 24C16 interprets 0xA2 0x1F 0xCC as a
597 byte write if /WC is low. */
598 ret = pctv452e_i2c_msg(d, I2C_ADDR_24C64,
599 mem_addr, 2,
600 encoded_mac, 20);
601
602 mutex_unlock(&d->i2c_mutex);
603
604 if (20 != ret)
605 goto failed;
606
607 ret = ttpci_eeprom_decode_mac(mac, encoded_mac);
608 if (0 != ret)
609 goto failed;
610
611 return 0;
612
613failed:
614 memset(mac, 0, 6);
615
616 return ret;
617}
618
619static const struct stb0899_s1_reg pctv452e_init_dev[] = {
620 { STB0899_DISCNTRL1, 0x26 },
621 { STB0899_DISCNTRL2, 0x80 },
622 { STB0899_DISRX_ST0, 0x04 },
623 { STB0899_DISRX_ST1, 0x20 },
624 { STB0899_DISPARITY, 0x00 },
625 { STB0899_DISFIFO, 0x00 },
626 { STB0899_DISF22, 0x99 },
627 { STB0899_DISF22RX, 0x85 }, /* 0xa8 */
628 { STB0899_ACRPRESC, 0x11 },
629 { STB0899_ACRDIV1, 0x0a },
630 { STB0899_ACRDIV2, 0x05 },
631 { STB0899_DACR1 , 0x00 },
632 { STB0899_DACR2 , 0x00 },
633 { STB0899_OUTCFG, 0x00 },
634 { STB0899_MODECFG, 0x00 }, /* Inversion */
635 { STB0899_IRQMSK_3, 0xf3 },
636 { STB0899_IRQMSK_2, 0xfc },
637 { STB0899_IRQMSK_1, 0xff },
638 { STB0899_IRQMSK_0, 0xff },
639 { STB0899_I2CCFG, 0x88 },
640 { STB0899_I2CRPT, 0x58 },
641 { STB0899_GPIO00CFG, 0x82 },
642 { STB0899_GPIO01CFG, 0x82 }, /* LED: 0x02 green, 0x82 orange */
643 { STB0899_GPIO02CFG, 0x82 },
644 { STB0899_GPIO03CFG, 0x82 },
645 { STB0899_GPIO04CFG, 0x82 },
646 { STB0899_GPIO05CFG, 0x82 },
647 { STB0899_GPIO06CFG, 0x82 },
648 { STB0899_GPIO07CFG, 0x82 },
649 { STB0899_GPIO08CFG, 0x82 },
650 { STB0899_GPIO09CFG, 0x82 },
651 { STB0899_GPIO10CFG, 0x82 },
652 { STB0899_GPIO11CFG, 0x82 },
653 { STB0899_GPIO12CFG, 0x82 },
654 { STB0899_GPIO13CFG, 0x82 },
655 { STB0899_GPIO14CFG, 0x82 },
656 { STB0899_GPIO15CFG, 0x82 },
657 { STB0899_GPIO16CFG, 0x82 },
658 { STB0899_GPIO17CFG, 0x82 },
659 { STB0899_GPIO18CFG, 0x82 },
660 { STB0899_GPIO19CFG, 0x82 },
661 { STB0899_GPIO20CFG, 0x82 },
662 { STB0899_SDATCFG, 0xb8 },
663 { STB0899_SCLTCFG, 0xba },
664 { STB0899_AGCRFCFG, 0x1c }, /* 0x11 DVB-S; 0x1c DVB-S2 (1c, rjkm) */
665 { STB0899_GPIO22, 0x82 },
666 { STB0899_GPIO21, 0x91 },
667 { STB0899_DIRCLKCFG, 0x82 },
668 { STB0899_CLKOUT27CFG, 0x7e },
669 { STB0899_STDBYCFG, 0x82 },
670 { STB0899_CS0CFG, 0x82 },
671 { STB0899_CS1CFG, 0x82 },
672 { STB0899_DISEQCOCFG, 0x20 },
673 { STB0899_NCOARSE, 0x15 }, /* 0x15 27Mhz, F/3 198MHz, F/6 108MHz */
674 { STB0899_SYNTCTRL, 0x00 }, /* 0x00 CLKI, 0x02 XTALI */
675 { STB0899_FILTCTRL, 0x00 },
676 { STB0899_SYSCTRL, 0x00 },
677 { STB0899_STOPCLK1, 0x20 }, /* orig: 0x00 budget-ci: 0x20 */
678 { STB0899_STOPCLK2, 0x00 },
679 { STB0899_INTBUFCTRL, 0x0a },
680 { STB0899_AGC2I1, 0x00 },
681 { STB0899_AGC2I2, 0x00 },
682 { STB0899_AGCIQIN, 0x00 },
683 { STB0899_TSTRES, 0x40 }, /* rjkm */
684 { 0xffff, 0xff },
685};
686
687static const struct stb0899_s1_reg pctv452e_init_s1_demod[] = {
688 { STB0899_DEMOD, 0x00 },
689 { STB0899_RCOMPC, 0xc9 },
690 { STB0899_AGC1CN, 0x01 },
691 { STB0899_AGC1REF, 0x10 },
692 { STB0899_RTC, 0x23 },
693 { STB0899_TMGCFG, 0x4e },
694 { STB0899_AGC2REF, 0x34 },
695 { STB0899_TLSR, 0x84 },
696 { STB0899_CFD, 0xf7 },
697 { STB0899_ACLC, 0x87 },
698 { STB0899_BCLC, 0x94 },
699 { STB0899_EQON, 0x41 },
700 { STB0899_LDT, 0xf1 },
701 { STB0899_LDT2, 0xe3 },
702 { STB0899_EQUALREF, 0xb4 },
703 { STB0899_TMGRAMP, 0x10 },
704 { STB0899_TMGTHD, 0x30 },
705 { STB0899_IDCCOMP, 0xfd },
706 { STB0899_QDCCOMP, 0xff },
707 { STB0899_POWERI, 0x0c },
708 { STB0899_POWERQ, 0x0f },
709 { STB0899_RCOMP, 0x6c },
710 { STB0899_AGCIQIN, 0x80 },
711 { STB0899_AGC2I1, 0x06 },
712 { STB0899_AGC2I2, 0x00 },
713 { STB0899_TLIR, 0x30 },
714 { STB0899_RTF, 0x7f },
715 { STB0899_DSTATUS, 0x00 },
716 { STB0899_LDI, 0xbc },
717 { STB0899_CFRM, 0xea },
718 { STB0899_CFRL, 0x31 },
719 { STB0899_NIRM, 0x2b },
720 { STB0899_NIRL, 0x80 },
721 { STB0899_ISYMB, 0x1d },
722 { STB0899_QSYMB, 0xa6 },
723 { STB0899_SFRH, 0x2f },
724 { STB0899_SFRM, 0x68 },
725 { STB0899_SFRL, 0x40 },
726 { STB0899_SFRUPH, 0x2f },
727 { STB0899_SFRUPM, 0x68 },
728 { STB0899_SFRUPL, 0x40 },
729 { STB0899_EQUAI1, 0x02 },
730 { STB0899_EQUAQ1, 0xff },
731 { STB0899_EQUAI2, 0x04 },
732 { STB0899_EQUAQ2, 0x05 },
733 { STB0899_EQUAI3, 0x02 },
734 { STB0899_EQUAQ3, 0xfd },
735 { STB0899_EQUAI4, 0x03 },
736 { STB0899_EQUAQ4, 0x07 },
737 { STB0899_EQUAI5, 0x08 },
738 { STB0899_EQUAQ5, 0xf5 },
739 { STB0899_DSTATUS2, 0x00 },
740 { STB0899_VSTATUS, 0x00 },
741 { STB0899_VERROR, 0x86 },
742 { STB0899_IQSWAP, 0x2a },
743 { STB0899_ECNT1M, 0x00 },
744 { STB0899_ECNT1L, 0x00 },
745 { STB0899_ECNT2M, 0x00 },
746 { STB0899_ECNT2L, 0x00 },
747 { STB0899_ECNT3M, 0x0a },
748 { STB0899_ECNT3L, 0xad },
749 { STB0899_FECAUTO1, 0x06 },
750 { STB0899_FECM, 0x01 },
751 { STB0899_VTH12, 0xb0 },
752 { STB0899_VTH23, 0x7a },
753 { STB0899_VTH34, 0x58 },
754 { STB0899_VTH56, 0x38 },
755 { STB0899_VTH67, 0x34 },
756 { STB0899_VTH78, 0x24 },
757 { STB0899_PRVIT, 0xff },
758 { STB0899_VITSYNC, 0x19 },
759 { STB0899_RSULC, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
760 { STB0899_TSULC, 0x42 },
761 { STB0899_RSLLC, 0x41 },
762 { STB0899_TSLPL, 0x12 },
763 { STB0899_TSCFGH, 0x0c },
764 { STB0899_TSCFGM, 0x00 },
765 { STB0899_TSCFGL, 0x00 },
766 { STB0899_TSOUT, 0x69 }, /* 0x0d for CAM */
767 { STB0899_RSSYNCDEL, 0x00 },
768 { STB0899_TSINHDELH, 0x02 },
769 { STB0899_TSINHDELM, 0x00 },
770 { STB0899_TSINHDELL, 0x00 },
771 { STB0899_TSLLSTKM, 0x1b },
772 { STB0899_TSLLSTKL, 0xb3 },
773 { STB0899_TSULSTKM, 0x00 },
774 { STB0899_TSULSTKL, 0x00 },
775 { STB0899_PCKLENUL, 0xbc },
776 { STB0899_PCKLENLL, 0xcc },
777 { STB0899_RSPCKLEN, 0xbd },
778 { STB0899_TSSTATUS, 0x90 },
779 { STB0899_ERRCTRL1, 0xb6 },
780 { STB0899_ERRCTRL2, 0x95 },
781 { STB0899_ERRCTRL3, 0x8d },
782 { STB0899_DMONMSK1, 0x27 },
783 { STB0899_DMONMSK0, 0x03 },
784 { STB0899_DEMAPVIT, 0x5c },
785 { STB0899_PLPARM, 0x19 },
786 { STB0899_PDELCTRL, 0x48 },
787 { STB0899_PDELCTRL2, 0x00 },
788 { STB0899_BBHCTRL1, 0x00 },
789 { STB0899_BBHCTRL2, 0x00 },
790 { STB0899_HYSTTHRESH, 0x77 },
791 { STB0899_MATCSTM, 0x00 },
792 { STB0899_MATCSTL, 0x00 },
793 { STB0899_UPLCSTM, 0x00 },
794 { STB0899_UPLCSTL, 0x00 },
795 { STB0899_DFLCSTM, 0x00 },
796 { STB0899_DFLCSTL, 0x00 },
797 { STB0899_SYNCCST, 0x00 },
798 { STB0899_SYNCDCSTM, 0x00 },
799 { STB0899_SYNCDCSTL, 0x00 },
800 { STB0899_ISI_ENTRY, 0x00 },
801 { STB0899_ISI_BIT_EN, 0x00 },
802 { STB0899_MATSTRM, 0xf0 },
803 { STB0899_MATSTRL, 0x02 },
804 { STB0899_UPLSTRM, 0x45 },
805 { STB0899_UPLSTRL, 0x60 },
806 { STB0899_DFLSTRM, 0xe3 },
807 { STB0899_DFLSTRL, 0x00 },
808 { STB0899_SYNCSTR, 0x47 },
809 { STB0899_SYNCDSTRM, 0x05 },
810 { STB0899_SYNCDSTRL, 0x18 },
811 { STB0899_CFGPDELSTATUS1, 0x19 },
812 { STB0899_CFGPDELSTATUS2, 0x2b },
813 { STB0899_BBFERRORM, 0x00 },
814 { STB0899_BBFERRORL, 0x01 },
815 { STB0899_UPKTERRORM, 0x00 },
816 { STB0899_UPKTERRORL, 0x00 },
817 { 0xffff, 0xff },
818};
819
820static struct stb0899_config stb0899_config = {
821 .init_dev = pctv452e_init_dev,
822 .init_s2_demod = stb0899_s2_init_2,
823 .init_s1_demod = pctv452e_init_s1_demod,
824 .init_s2_fec = stb0899_s2_init_4,
825 .init_tst = stb0899_s1_init_5,
826
827 .demod_address = I2C_ADDR_STB0899, /* I2C Address */
828 .block_sync_mode = STB0899_SYNC_FORCED, /* ? */
829
830 .xtal_freq = 27000000, /* Assume Hz ? */
831 .inversion = IQ_SWAP_ON, /* ? */
832
833 .lo_clk = 76500000,
834 .hi_clk = 99000000,
835
836 .ts_output_mode = 0, /* Use parallel mode */
837 .clock_polarity = 0,
838 .data_clk_parity = 0,
839 .fec_mode = 0,
840
841 .esno_ave = STB0899_DVBS2_ESNO_AVE,
842 .esno_quant = STB0899_DVBS2_ESNO_QUANT,
843 .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
844 .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
845 .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
846 .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
847 .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
848 .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
849 .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
850
851 .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
852 .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
853 .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
854 .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
855
856 .tuner_get_frequency = stb6100_get_frequency,
857 .tuner_set_frequency = stb6100_set_frequency,
858 .tuner_set_bandwidth = stb6100_set_bandwidth,
859 .tuner_get_bandwidth = stb6100_get_bandwidth,
860 .tuner_set_rfsiggain = NULL,
861
862 /* helper for switching LED green/orange */
863 .postproc = pctv45e_postproc
864};
865
866static struct stb6100_config stb6100_config = {
867 .tuner_address = I2C_ADDR_STB6100,
868 .refclock = 27000000
869};
870
871
872static struct i2c_algorithm pctv452e_i2c_algo = {
873 .master_xfer = pctv452e_i2c_xfer,
874 .functionality = pctv452e_i2c_func
875};
876
877static int pctv452e_frontend_attach(struct dvb_usb_adapter *a)
878{
879 struct usb_device_id *id;
880
881 a->fe_adap[0].fe = dvb_attach(stb0899_attach, &stb0899_config,
882 &a->dev->i2c_adap);
883 if (!a->fe_adap[0].fe)
884 return -ENODEV;
885 if ((dvb_attach(lnbp22_attach, a->fe_adap[0].fe,
886 &a->dev->i2c_adap)) == 0)
887 err("Cannot attach lnbp22\n");
888
889 id = a->dev->desc->warm_ids[0];
890 if (USB_VID_TECHNOTREND == id->idVendor
891 && USB_PID_TECHNOTREND_CONNECT_S2_3650_CI == id->idProduct)
892 /* Error ignored. */
893 tt3650_ci_init(a);
894
895 return 0;
896}
897
898static int pctv452e_tuner_attach(struct dvb_usb_adapter *a)
899{
900 if (!a->fe_adap[0].fe)
901 return -ENODEV;
902 if (dvb_attach(stb6100_attach, a->fe_adap[0].fe, &stb6100_config,
903 &a->dev->i2c_adap) == 0) {
904 err("%s failed\n", __func__);
905 return -ENODEV;
906 }
907
908 return 0;
909}
910
911static struct usb_device_id pctv452e_usb_table[] = {
912 {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_452E)},
913 {USB_DEVICE(USB_VID_TECHNOTREND, USB_PID_TECHNOTREND_CONNECT_S2_3600)},
914 {USB_DEVICE(USB_VID_TECHNOTREND,
915 USB_PID_TECHNOTREND_CONNECT_S2_3650_CI)},
916 {}
917};
918MODULE_DEVICE_TABLE(usb, pctv452e_usb_table);
919
920static struct dvb_usb_device_properties pctv452e_properties = {
921 .caps = DVB_USB_IS_AN_I2C_ADAPTER, /* more ? */
922 .usb_ctrl = DEVICE_SPECIFIC,
923
924 .size_of_priv = sizeof(struct pctv452e_state),
925
926 .power_ctrl = pctv452e_power_ctrl,
927
928 .rc.core = {
929 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
930 .allowed_protos = RC_TYPE_UNKNOWN,
931 .rc_query = pctv452e_rc_query,
932 .rc_interval = 100,
933 },
934
935 .num_adapters = 1,
936 .adapter = {{
937 .num_frontends = 1,
938 .fe = {{
939 .frontend_attach = pctv452e_frontend_attach,
940 .tuner_attach = pctv452e_tuner_attach,
941
942 /* parameter for the MPEG2-data transfer */
943 .stream = {
944 .type = USB_ISOC,
945 .count = 4,
946 .endpoint = 0x02,
947 .u = {
948 .isoc = {
949 .framesperurb = 4,
950 .framesize = 940,
951 .interval = 1
952 }
953 }
954 },
955 } },
956 } },
957
958 .i2c_algo = &pctv452e_i2c_algo,
959
960 .generic_bulk_ctrl_endpoint = 1, /* allow generice rw function */
961
962 .num_device_descs = 1,
963 .devices = {
964 { .name = "PCTV HDTV USB",
965 .cold_ids = { NULL, NULL }, /* this is a warm only device */
966 .warm_ids = { &pctv452e_usb_table[0], NULL }
967 },
968 { 0 },
969 }
970};
971
972static struct dvb_usb_device_properties tt_connect_s2_3600_properties = {
973 .caps = DVB_USB_IS_AN_I2C_ADAPTER, /* more ? */
974 .usb_ctrl = DEVICE_SPECIFIC,
975
976 .size_of_priv = sizeof(struct pctv452e_state),
977
978 .power_ctrl = pctv452e_power_ctrl,
979 .read_mac_address = pctv452e_read_mac_address,
980
981 .rc.core = {
982 .rc_codes = RC_MAP_TT_1500,
983 .allowed_protos = RC_TYPE_UNKNOWN,
984 .rc_query = pctv452e_rc_query,
985 .rc_interval = 100,
986 },
987
988 .num_adapters = 1,
989 .adapter = {{
990 .num_frontends = 1,
991 .fe = {{
992 .frontend_attach = pctv452e_frontend_attach,
993 .tuner_attach = pctv452e_tuner_attach,
994
995 /* parameter for the MPEG2-data transfer */
996 .stream = {
997 .type = USB_ISOC,
998 .count = 7,
999 .endpoint = 0x02,
1000 .u = {
1001 .isoc = {
1002 .framesperurb = 4,
1003 .framesize = 940,
1004 .interval = 1
1005 }
1006 }
1007 },
1008
1009 } },
1010 } },
1011
1012 .i2c_algo = &pctv452e_i2c_algo,
1013
1014 .generic_bulk_ctrl_endpoint = 1, /* allow generic rw function*/
1015
1016 .num_device_descs = 2,
1017 .devices = {
1018 { .name = "Technotrend TT Connect S2-3600",
1019 .cold_ids = { NULL, NULL }, /* this is a warm only device */
1020 .warm_ids = { &pctv452e_usb_table[1], NULL }
1021 },
1022 { .name = "Technotrend TT Connect S2-3650-CI",
1023 .cold_ids = { NULL, NULL },
1024 .warm_ids = { &pctv452e_usb_table[2], NULL }
1025 },
1026 { 0 },
1027 }
1028};
1029
1030static void pctv452e_usb_disconnect(struct usb_interface *intf)
1031{
1032 struct dvb_usb_device *d = usb_get_intfdata(intf);
1033
1034 tt3650_ci_uninit(d);
1035 dvb_usb_device_exit(intf);
1036}
1037
1038static int pctv452e_usb_probe(struct usb_interface *intf,
1039 const struct usb_device_id *id)
1040{
1041 if (0 == dvb_usb_device_init(intf, &pctv452e_properties,
1042 THIS_MODULE, NULL, adapter_nr) ||
1043 0 == dvb_usb_device_init(intf, &tt_connect_s2_3600_properties,
1044 THIS_MODULE, NULL, adapter_nr))
1045 return 0;
1046
1047 return -ENODEV;
1048}
1049
1050static struct usb_driver pctv452e_usb_driver = {
1051 .name = "pctv452e",
1052 .probe = pctv452e_usb_probe,
1053 .disconnect = pctv452e_usb_disconnect,
1054 .id_table = pctv452e_usb_table,
1055};
1056
1057module_usb_driver(pctv452e_usb_driver);
1058
1059MODULE_AUTHOR("Dominik Kuhlen <dkuhlen@gmx.net>");
1060MODULE_AUTHOR("Andre Weidemann <Andre.Weidemann@web.de>");
1061MODULE_AUTHOR("Michael H. Schimek <mschimek@gmx.at>");
1062MODULE_DESCRIPTION("Pinnacle PCTV HDTV USB DVB / TT connect S2-3600 Driver");
1063MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/technisat-usb2.c b/drivers/media/usb/dvb-usb/technisat-usb2.c
new file mode 100644
index 000000000000..acefaa89cc53
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/technisat-usb2.c
@@ -0,0 +1,789 @@
1/*
2 * Linux driver for Technisat DVB-S/S2 USB 2.0 device
3 *
4 * Copyright (C) 2010 Patrick Boettcher,
5 * Kernel Labs Inc. PO Box 745, St James, NY 11780
6 *
7 * Development was sponsored by Technisat Digital UK Limited, whose
8 * registered office is Witan Gate House 500 - 600 Witan Gate West,
9 * Milton Keynes, MK9 1SH
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of the
14 * License, or (at your option) any later version.
15 *
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND
22 * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO
23 * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR
24 * FITNESS FOR A PARTICULAR PURPOSE. NEITHER THE COPYRIGHT HOLDER
25 * NOR TECHNISAT DIGITAL UK LIMITED SHALL BE LIABLE FOR ANY SPECIAL,
26 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
27 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
28 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
29 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PROGRAM. See the
30 * GNU General Public License for more details.
31 */
32
33#define DVB_USB_LOG_PREFIX "technisat-usb2"
34#include "dvb-usb.h"
35
36#include "stv6110x.h"
37#include "stv090x.h"
38
39/* module parameters */
40DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
41
42static int debug;
43module_param(debug, int, 0644);
44MODULE_PARM_DESC(debug,
45 "set debugging level (bit-mask: 1=info,2=eeprom,4=i2c,8=rc)." \
46 DVB_USB_DEBUG_STATUS);
47
48/* disables all LED control command and
49 * also does not start the signal polling thread */
50static int disable_led_control;
51module_param(disable_led_control, int, 0444);
52MODULE_PARM_DESC(disable_led_control,
53 "disable LED control of the device "
54 "(default: 0 - LED control is active).");
55
56/* device private data */
57struct technisat_usb2_state {
58 struct dvb_usb_device *dev;
59 struct delayed_work green_led_work;
60 u8 power_state;
61
62 u16 last_scan_code;
63};
64
65/* debug print helpers */
66#define deb_info(args...) dprintk(debug, 0x01, args)
67#define deb_eeprom(args...) dprintk(debug, 0x02, args)
68#define deb_i2c(args...) dprintk(debug, 0x04, args)
69#define deb_rc(args...) dprintk(debug, 0x08, args)
70
71/* vendor requests */
72#define SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST 0xB3
73#define SET_FRONT_END_RESET_VENDOR_REQUEST 0xB4
74#define GET_VERSION_INFO_VENDOR_REQUEST 0xB5
75#define SET_GREEN_LED_VENDOR_REQUEST 0xB6
76#define SET_RED_LED_VENDOR_REQUEST 0xB7
77#define GET_IR_DATA_VENDOR_REQUEST 0xB8
78#define SET_LED_TIMER_DIVIDER_VENDOR_REQUEST 0xB9
79#define SET_USB_REENUMERATION 0xBA
80
81/* i2c-access methods */
82#define I2C_SPEED_100KHZ_BIT 0x40
83
84#define I2C_STATUS_NAK 7
85#define I2C_STATUS_OK 8
86
87static int technisat_usb2_i2c_access(struct usb_device *udev,
88 u8 device_addr, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
89{
90 u8 b[64];
91 int ret, actual_length;
92
93 deb_i2c("i2c-access: %02x, tx: ", device_addr);
94 debug_dump(tx, txlen, deb_i2c);
95 deb_i2c(" ");
96
97 if (txlen > 62) {
98 err("i2c TX buffer can't exceed 62 bytes (dev 0x%02x)",
99 device_addr);
100 txlen = 62;
101 }
102 if (rxlen > 62) {
103 err("i2c RX buffer can't exceed 62 bytes (dev 0x%02x)",
104 device_addr);
105 txlen = 62;
106 }
107
108 b[0] = I2C_SPEED_100KHZ_BIT;
109 b[1] = device_addr << 1;
110
111 if (rx != NULL) {
112 b[0] |= rxlen;
113 b[1] |= 1;
114 }
115
116 memcpy(&b[2], tx, txlen);
117 ret = usb_bulk_msg(udev,
118 usb_sndbulkpipe(udev, 0x01),
119 b, 2 + txlen,
120 NULL, 1000);
121
122 if (ret < 0) {
123 err("i2c-error: out failed %02x = %d", device_addr, ret);
124 return -ENODEV;
125 }
126
127 ret = usb_bulk_msg(udev,
128 usb_rcvbulkpipe(udev, 0x01),
129 b, 64, &actual_length, 1000);
130 if (ret < 0) {
131 err("i2c-error: in failed %02x = %d", device_addr, ret);
132 return -ENODEV;
133 }
134
135 if (b[0] != I2C_STATUS_OK) {
136 err("i2c-error: %02x = %d", device_addr, b[0]);
137 /* handle tuner-i2c-nak */
138 if (!(b[0] == I2C_STATUS_NAK &&
139 device_addr == 0x60
140 /* && device_is_technisat_usb2 */))
141 return -ENODEV;
142 }
143
144 deb_i2c("status: %d, ", b[0]);
145
146 if (rx != NULL) {
147 memcpy(rx, &b[2], rxlen);
148
149 deb_i2c("rx (%d): ", rxlen);
150 debug_dump(rx, rxlen, deb_i2c);
151 }
152
153 deb_i2c("\n");
154
155 return 0;
156}
157
158static int technisat_usb2_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
159 int num)
160{
161 int ret = 0, i;
162 struct dvb_usb_device *d = i2c_get_adapdata(adap);
163
164 /* Ensure nobody else hits the i2c bus while we're sending our
165 sequence of messages, (such as the remote control thread) */
166 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
167 return -EAGAIN;
168
169 for (i = 0; i < num; i++) {
170 if (i+1 < num && msg[i+1].flags & I2C_M_RD) {
171 ret = technisat_usb2_i2c_access(d->udev, msg[i+1].addr,
172 msg[i].buf, msg[i].len,
173 msg[i+1].buf, msg[i+1].len);
174 if (ret != 0)
175 break;
176 i++;
177 } else {
178 ret = technisat_usb2_i2c_access(d->udev, msg[i].addr,
179 msg[i].buf, msg[i].len,
180 NULL, 0);
181 if (ret != 0)
182 break;
183 }
184 }
185
186 if (ret == 0)
187 ret = i;
188
189 mutex_unlock(&d->i2c_mutex);
190
191 return ret;
192}
193
194static u32 technisat_usb2_i2c_func(struct i2c_adapter *adapter)
195{
196 return I2C_FUNC_I2C;
197}
198
199static struct i2c_algorithm technisat_usb2_i2c_algo = {
200 .master_xfer = technisat_usb2_i2c_xfer,
201 .functionality = technisat_usb2_i2c_func,
202};
203
204#if 0
205static void technisat_usb2_frontend_reset(struct usb_device *udev)
206{
207 usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
208 SET_FRONT_END_RESET_VENDOR_REQUEST,
209 USB_TYPE_VENDOR | USB_DIR_OUT,
210 10, 0,
211 NULL, 0, 500);
212}
213#endif
214
215/* LED control */
216enum technisat_usb2_led_state {
217 LED_OFF,
218 LED_BLINK,
219 LED_ON,
220 LED_UNDEFINED
221};
222
223static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum technisat_usb2_led_state state)
224{
225 int ret;
226
227 u8 led[8] = {
228 red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
229 0
230 };
231
232 if (disable_led_control && state != LED_OFF)
233 return 0;
234
235 switch (state) {
236 case LED_ON:
237 led[1] = 0x82;
238 break;
239 case LED_BLINK:
240 led[1] = 0x82;
241 if (red) {
242 led[2] = 0x02;
243 led[3] = 10;
244 led[4] = 10;
245 } else {
246 led[2] = 0xff;
247 led[3] = 50;
248 led[4] = 50;
249 }
250 led[5] = 1;
251 break;
252
253 default:
254 case LED_OFF:
255 led[1] = 0x80;
256 break;
257 }
258
259 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
260 return -EAGAIN;
261
262 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
263 red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
264 USB_TYPE_VENDOR | USB_DIR_OUT,
265 0, 0,
266 led, sizeof(led), 500);
267
268 mutex_unlock(&d->i2c_mutex);
269 return ret;
270}
271
272static int technisat_usb2_set_led_timer(struct dvb_usb_device *d, u8 red, u8 green)
273{
274 int ret;
275 u8 b = 0;
276
277 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
278 return -EAGAIN;
279
280 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
281 SET_LED_TIMER_DIVIDER_VENDOR_REQUEST,
282 USB_TYPE_VENDOR | USB_DIR_OUT,
283 (red << 8) | green, 0,
284 &b, 1, 500);
285
286 mutex_unlock(&d->i2c_mutex);
287
288 return ret;
289}
290
291static void technisat_usb2_green_led_control(struct work_struct *work)
292{
293 struct technisat_usb2_state *state =
294 container_of(work, struct technisat_usb2_state, green_led_work.work);
295 struct dvb_frontend *fe = state->dev->adapter[0].fe_adap[0].fe;
296
297 if (state->power_state == 0)
298 goto schedule;
299
300 if (fe != NULL) {
301 enum fe_status status;
302
303 if (fe->ops.read_status(fe, &status) != 0)
304 goto schedule;
305
306 if (status & FE_HAS_LOCK) {
307 u32 ber;
308
309 if (fe->ops.read_ber(fe, &ber) != 0)
310 goto schedule;
311
312 if (ber > 1000)
313 technisat_usb2_set_led(state->dev, 0, LED_BLINK);
314 else
315 technisat_usb2_set_led(state->dev, 0, LED_ON);
316 } else
317 technisat_usb2_set_led(state->dev, 0, LED_OFF);
318 }
319
320schedule:
321 schedule_delayed_work(&state->green_led_work,
322 msecs_to_jiffies(500));
323}
324
325/* method to find out whether the firmware has to be downloaded or not */
326static int technisat_usb2_identify_state(struct usb_device *udev,
327 struct dvb_usb_device_properties *props,
328 struct dvb_usb_device_description **desc, int *cold)
329{
330 int ret;
331 u8 version[3];
332
333 /* first select the interface */
334 if (usb_set_interface(udev, 0, 1) != 0)
335 err("could not set alternate setting to 0");
336 else
337 info("set alternate setting");
338
339 *cold = 0; /* by default do not download a firmware - just in case something is wrong */
340
341 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
342 GET_VERSION_INFO_VENDOR_REQUEST,
343 USB_TYPE_VENDOR | USB_DIR_IN,
344 0, 0,
345 version, sizeof(version), 500);
346
347 if (ret < 0)
348 *cold = 1;
349 else {
350 info("firmware version: %d.%d", version[1], version[2]);
351 *cold = 0;
352 }
353
354 return 0;
355}
356
357/* power control */
358static int technisat_usb2_power_ctrl(struct dvb_usb_device *d, int level)
359{
360 struct technisat_usb2_state *state = d->priv;
361
362 state->power_state = level;
363
364 if (disable_led_control)
365 return 0;
366
367 /* green led is turned off in any case - will be turned on when tuning */
368 technisat_usb2_set_led(d, 0, LED_OFF);
369 /* red led is turned on all the time */
370 technisat_usb2_set_led(d, 1, LED_ON);
371 return 0;
372}
373
374/* mac address reading - from the eeprom */
375#if 0
376static void technisat_usb2_eeprom_dump(struct dvb_usb_device *d)
377{
378 u8 reg;
379 u8 b[16];
380 int i, j;
381
382 /* full EEPROM dump */
383 for (j = 0; j < 256 * 4; j += 16) {
384 reg = j;
385 if (technisat_usb2_i2c_access(d->udev, 0x50 + j / 256, &reg, 1, b, 16) != 0)
386 break;
387
388 deb_eeprom("EEPROM: %01x%02x: ", j / 256, reg);
389 for (i = 0; i < 16; i++)
390 deb_eeprom("%02x ", b[i]);
391 deb_eeprom("\n");
392 }
393}
394#endif
395
396static u8 technisat_usb2_calc_lrc(const u8 *b, u16 length)
397{
398 u8 lrc = 0;
399 while (--length)
400 lrc ^= *b++;
401 return lrc;
402}
403
404static int technisat_usb2_eeprom_lrc_read(struct dvb_usb_device *d,
405 u16 offset, u8 *b, u16 length, u8 tries)
406{
407 u8 bo = offset & 0xff;
408 struct i2c_msg msg[] = {
409 {
410 .addr = 0x50 | ((offset >> 8) & 0x3),
411 .buf = &bo,
412 .len = 1
413 }, {
414 .addr = 0x50 | ((offset >> 8) & 0x3),
415 .flags = I2C_M_RD,
416 .buf = b,
417 .len = length
418 }
419 };
420
421 while (tries--) {
422 int status;
423
424 if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
425 break;
426
427 status =
428 technisat_usb2_calc_lrc(b, length - 1) == b[length - 1];
429
430 if (status)
431 return 0;
432 }
433
434 return -EREMOTEIO;
435}
436
437#define EEPROM_MAC_START 0x3f8
438#define EEPROM_MAC_TOTAL 8
439static int technisat_usb2_read_mac_address(struct dvb_usb_device *d,
440 u8 mac[])
441{
442 u8 buf[EEPROM_MAC_TOTAL];
443
444 if (technisat_usb2_eeprom_lrc_read(d, EEPROM_MAC_START,
445 buf, EEPROM_MAC_TOTAL, 4) != 0)
446 return -ENODEV;
447
448 memcpy(mac, buf, 6);
449 return 0;
450}
451
452/* frontend attach */
453static int technisat_usb2_set_voltage(struct dvb_frontend *fe,
454 fe_sec_voltage_t voltage)
455{
456 int i;
457 u8 gpio[3] = { 0 }; /* 0 = 2, 1 = 3, 2 = 4 */
458
459 gpio[2] = 1; /* high - voltage ? */
460
461 switch (voltage) {
462 case SEC_VOLTAGE_13:
463 gpio[0] = 1;
464 break;
465 case SEC_VOLTAGE_18:
466 gpio[0] = 1;
467 gpio[1] = 1;
468 break;
469 default:
470 case SEC_VOLTAGE_OFF:
471 break;
472 }
473
474 for (i = 0; i < 3; i++)
475 if (stv090x_set_gpio(fe, i+2, 0, gpio[i], 0) != 0)
476 return -EREMOTEIO;
477 return 0;
478}
479
480static struct stv090x_config technisat_usb2_stv090x_config = {
481 .device = STV0903,
482 .demod_mode = STV090x_SINGLE,
483 .clk_mode = STV090x_CLK_EXT,
484
485 .xtal = 8000000,
486 .address = 0x68,
487
488 .ts1_mode = STV090x_TSMODE_DVBCI,
489 .ts1_clk = 13400000,
490 .ts1_tei = 1,
491
492 .repeater_level = STV090x_RPTLEVEL_64,
493
494 .tuner_bbgain = 6,
495};
496
497static struct stv6110x_config technisat_usb2_stv6110x_config = {
498 .addr = 0x60,
499 .refclk = 16000000,
500 .clk_div = 2,
501};
502
503static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a)
504{
505 struct usb_device *udev = a->dev->udev;
506 int ret;
507
508 a->fe_adap[0].fe = dvb_attach(stv090x_attach, &technisat_usb2_stv090x_config,
509 &a->dev->i2c_adap, STV090x_DEMODULATOR_0);
510
511 if (a->fe_adap[0].fe) {
512 struct stv6110x_devctl *ctl;
513
514 ctl = dvb_attach(stv6110x_attach,
515 a->fe_adap[0].fe,
516 &technisat_usb2_stv6110x_config,
517 &a->dev->i2c_adap);
518
519 if (ctl) {
520 technisat_usb2_stv090x_config.tuner_init = ctl->tuner_init;
521 technisat_usb2_stv090x_config.tuner_sleep = ctl->tuner_sleep;
522 technisat_usb2_stv090x_config.tuner_set_mode = ctl->tuner_set_mode;
523 technisat_usb2_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
524 technisat_usb2_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
525 technisat_usb2_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
526 technisat_usb2_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
527 technisat_usb2_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain;
528 technisat_usb2_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain;
529 technisat_usb2_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk;
530 technisat_usb2_stv090x_config.tuner_get_status = ctl->tuner_get_status;
531
532 /* call the init function once to initialize
533 tuner's clock output divider and demod's
534 master clock */
535 if (a->fe_adap[0].fe->ops.init)
536 a->fe_adap[0].fe->ops.init(a->fe_adap[0].fe);
537
538 if (mutex_lock_interruptible(&a->dev->i2c_mutex) < 0)
539 return -EAGAIN;
540
541 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
542 SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST,
543 USB_TYPE_VENDOR | USB_DIR_OUT,
544 0, 0,
545 NULL, 0, 500);
546 mutex_unlock(&a->dev->i2c_mutex);
547
548 if (ret != 0)
549 err("could not set IF_CLK to external");
550
551 a->fe_adap[0].fe->ops.set_voltage = technisat_usb2_set_voltage;
552
553 /* if everything was successful assign a nice name to the frontend */
554 strlcpy(a->fe_adap[0].fe->ops.info.name, a->dev->desc->name,
555 sizeof(a->fe_adap[0].fe->ops.info.name));
556 } else {
557 dvb_frontend_detach(a->fe_adap[0].fe);
558 a->fe_adap[0].fe = NULL;
559 }
560 }
561
562 technisat_usb2_set_led_timer(a->dev, 1, 1);
563
564 return a->fe_adap[0].fe == NULL ? -ENODEV : 0;
565}
566
567/* Remote control */
568
569/* the device is giving providing raw IR-signals to the host mapping
570 * it only to one remote control is just the default implementation
571 */
572#define NOMINAL_IR_BIT_TRANSITION_TIME_US 889
573#define NOMINAL_IR_BIT_TIME_US (2 * NOMINAL_IR_BIT_TRANSITION_TIME_US)
574
575#define FIRMWARE_CLOCK_TICK 83333
576#define FIRMWARE_CLOCK_DIVISOR 256
577
578#define IR_PERCENT_TOLERANCE 15
579
580#define NOMINAL_IR_BIT_TRANSITION_TICKS ((NOMINAL_IR_BIT_TRANSITION_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
581#define NOMINAL_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICKS / FIRMWARE_CLOCK_DIVISOR)
582
583#define NOMINAL_IR_BIT_TIME_TICKS ((NOMINAL_IR_BIT_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
584#define NOMINAL_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICKS / FIRMWARE_CLOCK_DIVISOR)
585
586#define MINIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT - ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
587#define MAXIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT + ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
588
589#define MINIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT - ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
590#define MAXIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT + ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
591
592static int technisat_usb2_get_ir(struct dvb_usb_device *d)
593{
594 u8 buf[62], *b;
595 int ret;
596 struct ir_raw_event ev;
597
598 buf[0] = GET_IR_DATA_VENDOR_REQUEST;
599 buf[1] = 0x08;
600 buf[2] = 0x8f;
601 buf[3] = MINIMUM_IR_BIT_TRANSITION_TICK_COUNT;
602 buf[4] = MAXIMUM_IR_BIT_TIME_TICK_COUNT;
603
604 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
605 return -EAGAIN;
606 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
607 GET_IR_DATA_VENDOR_REQUEST,
608 USB_TYPE_VENDOR | USB_DIR_OUT,
609 0, 0,
610 buf, 5, 500);
611 if (ret < 0)
612 goto unlock;
613
614 buf[1] = 0;
615 buf[2] = 0;
616 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
617 GET_IR_DATA_VENDOR_REQUEST,
618 USB_TYPE_VENDOR | USB_DIR_IN,
619 0x8080, 0,
620 buf, sizeof(buf), 500);
621
622unlock:
623 mutex_unlock(&d->i2c_mutex);
624
625 if (ret < 0)
626 return ret;
627
628 if (ret == 1)
629 return 0; /* no key pressed */
630
631 /* decoding */
632 b = buf+1;
633
634#if 0
635 deb_rc("RC: %d ", ret);
636 debug_dump(b, ret, deb_rc);
637#endif
638
639 ev.pulse = 0;
640 while (1) {
641 ev.pulse = !ev.pulse;
642 ev.duration = (*b * FIRMWARE_CLOCK_DIVISOR * FIRMWARE_CLOCK_TICK) / 1000;
643 ir_raw_event_store(d->rc_dev, &ev);
644
645 b++;
646 if (*b == 0xff) {
647 ev.pulse = 0;
648 ev.duration = 888888*2;
649 ir_raw_event_store(d->rc_dev, &ev);
650 break;
651 }
652 }
653
654 ir_raw_event_handle(d->rc_dev);
655
656 return 1;
657}
658
659static int technisat_usb2_rc_query(struct dvb_usb_device *d)
660{
661 int ret = technisat_usb2_get_ir(d);
662
663 if (ret < 0)
664 return ret;
665
666 if (ret == 0)
667 return 0;
668
669 if (!disable_led_control)
670 technisat_usb2_set_led(d, 1, LED_BLINK);
671
672 return 0;
673}
674
675/* DVB-USB and USB stuff follows */
676static struct usb_device_id technisat_usb2_id_table[] = {
677 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_DVB_S2) },
678 { 0 } /* Terminating entry */
679};
680
681/* device description */
682static struct dvb_usb_device_properties technisat_usb2_devices = {
683 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
684
685 .usb_ctrl = CYPRESS_FX2,
686
687 .identify_state = technisat_usb2_identify_state,
688 .firmware = "dvb-usb-SkyStar_USB_HD_FW_v17_63.HEX.fw",
689
690 .size_of_priv = sizeof(struct technisat_usb2_state),
691
692 .i2c_algo = &technisat_usb2_i2c_algo,
693
694 .power_ctrl = technisat_usb2_power_ctrl,
695 .read_mac_address = technisat_usb2_read_mac_address,
696
697 .num_adapters = 1,
698 .adapter = {
699 {
700 .num_frontends = 1,
701 .fe = {{
702 .frontend_attach = technisat_usb2_frontend_attach,
703
704 .stream = {
705 .type = USB_ISOC,
706 .count = 8,
707 .endpoint = 0x2,
708 .u = {
709 .isoc = {
710 .framesperurb = 32,
711 .framesize = 2048,
712 .interval = 3,
713 }
714 }
715 },
716 }},
717 .size_of_priv = 0,
718 },
719 },
720
721 .num_device_descs = 1,
722 .devices = {
723 { "Technisat SkyStar USB HD (DVB-S/S2)",
724 { &technisat_usb2_id_table[0], NULL },
725 { NULL },
726 },
727 },
728
729 .rc.core = {
730 .rc_interval = 100,
731 .rc_codes = RC_MAP_TECHNISAT_USB2,
732 .module_name = "technisat-usb2",
733 .rc_query = technisat_usb2_rc_query,
734 .allowed_protos = RC_TYPE_ALL,
735 .driver_type = RC_DRIVER_IR_RAW,
736 }
737};
738
739static int technisat_usb2_probe(struct usb_interface *intf,
740 const struct usb_device_id *id)
741{
742 struct dvb_usb_device *dev;
743
744 if (dvb_usb_device_init(intf, &technisat_usb2_devices, THIS_MODULE,
745 &dev, adapter_nr) != 0)
746 return -ENODEV;
747
748 if (dev) {
749 struct technisat_usb2_state *state = dev->priv;
750 state->dev = dev;
751
752 if (!disable_led_control) {
753 INIT_DELAYED_WORK(&state->green_led_work,
754 technisat_usb2_green_led_control);
755 schedule_delayed_work(&state->green_led_work,
756 msecs_to_jiffies(500));
757 }
758 }
759
760 return 0;
761}
762
763static void technisat_usb2_disconnect(struct usb_interface *intf)
764{
765 struct dvb_usb_device *dev = usb_get_intfdata(intf);
766
767 /* work and stuff was only created when the device is is hot-state */
768 if (dev != NULL) {
769 struct technisat_usb2_state *state = dev->priv;
770 if (state != NULL)
771 cancel_delayed_work_sync(&state->green_led_work);
772 }
773
774 dvb_usb_device_exit(intf);
775}
776
777static struct usb_driver technisat_usb2_driver = {
778 .name = "dvb_usb_technisat_usb2",
779 .probe = technisat_usb2_probe,
780 .disconnect = technisat_usb2_disconnect,
781 .id_table = technisat_usb2_id_table,
782};
783
784module_usb_driver(technisat_usb2_driver);
785
786MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>");
787MODULE_DESCRIPTION("Driver for Technisat DVB-S/S2 USB 2.0 device");
788MODULE_VERSION("1.0");
789MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/ttusb2.c b/drivers/media/usb/dvb-usb/ttusb2.c
new file mode 100644
index 000000000000..e53a1061cb8e
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/ttusb2.c
@@ -0,0 +1,820 @@
1/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones
2 * (e.g. Pinnacle 400e DVB-S USB2.0).
3 *
4 * The Pinnacle 400e uses the same protocol as the Technotrend USB1.1 boxes.
5 *
6 * TDA8263 + TDA10086
7 *
8 * I2C addresses:
9 * 0x08 - LNBP21PD - LNB power supply
10 * 0x0e - TDA10086 - Demodulator
11 * 0x50 - FX2 eeprom
12 * 0x60 - TDA8263 - Tuner
13 * 0x78 ???
14 *
15 * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
16 * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
17 * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.org>
18 *
19 * This program is free software; you can redistribute it and/or modify it
20 * under the terms of the GNU General Public License as published by the Free
21 * Software Foundation, version 2.
22 *
23 * see Documentation/dvb/README.dvb-usb for more information
24 */
25#define DVB_USB_LOG_PREFIX "ttusb2"
26#include "dvb-usb.h"
27
28#include "ttusb2.h"
29
30#include "tda826x.h"
31#include "tda10086.h"
32#include "tda1002x.h"
33#include "tda10048.h"
34#include "tda827x.h"
35#include "lnbp21.h"
36/* CA */
37#include "dvb_ca_en50221.h"
38
39/* debug */
40static int dvb_usb_ttusb2_debug;
41#define deb_info(args...) dprintk(dvb_usb_ttusb2_debug,0x01,args)
42module_param_named(debug,dvb_usb_ttusb2_debug, int, 0644);
43MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS);
44static int dvb_usb_ttusb2_debug_ci;
45module_param_named(debug_ci,dvb_usb_ttusb2_debug_ci, int, 0644);
46MODULE_PARM_DESC(debug_ci, "set debugging ci." DVB_USB_DEBUG_STATUS);
47
48DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
49
50#define ci_dbg(format, arg...) \
51do { \
52 if (dvb_usb_ttusb2_debug_ci) \
53 printk(KERN_DEBUG DVB_USB_LOG_PREFIX \
54 ": %s " format "\n" , __func__, ## arg); \
55} while (0)
56
57enum {
58 TT3650_CMD_CI_TEST = 0x40,
59 TT3650_CMD_CI_RD_CTRL,
60 TT3650_CMD_CI_WR_CTRL,
61 TT3650_CMD_CI_RD_ATTR,
62 TT3650_CMD_CI_WR_ATTR,
63 TT3650_CMD_CI_RESET,
64 TT3650_CMD_CI_SET_VIDEO_PORT
65};
66
67struct ttusb2_state {
68 struct dvb_ca_en50221 ca;
69 struct mutex ca_mutex;
70 u8 id;
71 u16 last_rc_key;
72};
73
74static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd,
75 u8 *wbuf, int wlen, u8 *rbuf, int rlen)
76{
77 struct ttusb2_state *st = d->priv;
78 u8 *s, *r = NULL;
79 int ret = 0;
80
81 s = kzalloc(wlen+4, GFP_KERNEL);
82 if (!s)
83 return -ENOMEM;
84
85 r = kzalloc(64, GFP_KERNEL);
86 if (!r) {
87 kfree(s);
88 return -ENOMEM;
89 }
90
91 s[0] = 0xaa;
92 s[1] = ++st->id;
93 s[2] = cmd;
94 s[3] = wlen;
95 memcpy(&s[4],wbuf,wlen);
96
97 ret = dvb_usb_generic_rw(d, s, wlen+4, r, 64, 0);
98
99 if (ret != 0 ||
100 r[0] != 0x55 ||
101 r[1] != s[1] ||
102 r[2] != cmd ||
103 (rlen > 0 && r[3] != rlen)) {
104 warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]);
105 kfree(s);
106 kfree(r);
107 return -EIO;
108 }
109
110 if (rlen > 0)
111 memcpy(rbuf, &r[4], rlen);
112
113 kfree(s);
114 kfree(r);
115
116 return 0;
117}
118
119/* ci */
120static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len)
121{
122 int ret;
123 u8 rx[60];/* (64 -4) */
124 ret = ttusb2_msg(d, cmd, data, write_len, rx, read_len);
125 if (!ret)
126 memcpy(data, rx, read_len);
127 return ret;
128}
129
130static int tt3650_ci_msg_locked(struct dvb_ca_en50221 *ca, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len)
131{
132 struct dvb_usb_device *d = ca->data;
133 struct ttusb2_state *state = d->priv;
134 int ret;
135
136 mutex_lock(&state->ca_mutex);
137 ret = tt3650_ci_msg(d, cmd, data, write_len, read_len);
138 mutex_unlock(&state->ca_mutex);
139
140 return ret;
141}
142
143static int tt3650_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
144{
145 u8 buf[3];
146 int ret = 0;
147
148 if (slot)
149 return -EINVAL;
150
151 buf[0] = (address >> 8) & 0x0F;
152 buf[1] = address;
153
154
155 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_ATTR, buf, 2, 3);
156
157 ci_dbg("%04x -> %d 0x%02x", address, ret, buf[2]);
158
159 if (ret < 0)
160 return ret;
161
162 return buf[2];
163}
164
165static int tt3650_ci_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
166{
167 u8 buf[3];
168
169 ci_dbg("%d 0x%04x 0x%02x", slot, address, value);
170
171 if (slot)
172 return -EINVAL;
173
174 buf[0] = (address >> 8) & 0x0F;
175 buf[1] = address;
176 buf[2] = value;
177
178 return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_ATTR, buf, 3, 3);
179}
180
181static int tt3650_ci_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
182{
183 u8 buf[2];
184 int ret;
185
186 if (slot)
187 return -EINVAL;
188
189 buf[0] = address & 3;
190
191 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_CTRL, buf, 1, 2);
192
193 ci_dbg("0x%02x -> %d 0x%02x", address, ret, buf[1]);
194
195 if (ret < 0)
196 return ret;
197
198 return buf[1];
199}
200
201static int tt3650_ci_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
202{
203 u8 buf[2];
204
205 ci_dbg("%d 0x%02x 0x%02x", slot, address, value);
206
207 if (slot)
208 return -EINVAL;
209
210 buf[0] = address;
211 buf[1] = value;
212
213 return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_CTRL, buf, 2, 2);
214}
215
216static int tt3650_ci_set_video_port(struct dvb_ca_en50221 *ca, int slot, int enable)
217{
218 u8 buf[1];
219 int ret;
220
221 ci_dbg("%d %d", slot, enable);
222
223 if (slot)
224 return -EINVAL;
225
226 buf[0] = enable;
227
228 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
229 if (ret < 0)
230 return ret;
231
232 if (enable != buf[0]) {
233 err("CI not %sabled.", enable ? "en" : "dis");
234 return -EIO;
235 }
236
237 return 0;
238}
239
240static int tt3650_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
241{
242 return tt3650_ci_set_video_port(ca, slot, 0);
243}
244
245static int tt3650_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
246{
247 return tt3650_ci_set_video_port(ca, slot, 1);
248}
249
250static int tt3650_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
251{
252 struct dvb_usb_device *d = ca->data;
253 struct ttusb2_state *state = d->priv;
254 u8 buf[1];
255 int ret;
256
257 ci_dbg("%d", slot);
258
259 if (slot)
260 return -EINVAL;
261
262 buf[0] = 0;
263
264 mutex_lock(&state->ca_mutex);
265
266 ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
267 if (ret)
268 goto failed;
269
270 msleep(500);
271
272 buf[0] = 1;
273
274 ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1);
275 if (ret)
276 goto failed;
277
278 msleep(500);
279
280 buf[0] = 0; /* FTA */
281
282 ret = tt3650_ci_msg(d, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1);
283
284 msleep(1100);
285
286 failed:
287 mutex_unlock(&state->ca_mutex);
288
289 return ret;
290}
291
292static int tt3650_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
293{
294 u8 buf[1];
295 int ret;
296
297 if (slot)
298 return -EINVAL;
299
300 ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_TEST, buf, 0, 1);
301 if (ret)
302 return ret;
303
304 if (1 == buf[0]) {
305 return DVB_CA_EN50221_POLL_CAM_PRESENT |
306 DVB_CA_EN50221_POLL_CAM_READY;
307 }
308 return 0;
309}
310
311static void tt3650_ci_uninit(struct dvb_usb_device *d)
312{
313 struct ttusb2_state *state;
314
315 ci_dbg("");
316
317 if (NULL == d)
318 return;
319
320 state = d->priv;
321 if (NULL == state)
322 return;
323
324 if (NULL == state->ca.data)
325 return;
326
327 dvb_ca_en50221_release(&state->ca);
328
329 memset(&state->ca, 0, sizeof(state->ca));
330}
331
332static int tt3650_ci_init(struct dvb_usb_adapter *a)
333{
334 struct dvb_usb_device *d = a->dev;
335 struct ttusb2_state *state = d->priv;
336 int ret;
337
338 ci_dbg("");
339
340 mutex_init(&state->ca_mutex);
341
342 state->ca.owner = THIS_MODULE;
343 state->ca.read_attribute_mem = tt3650_ci_read_attribute_mem;
344 state->ca.write_attribute_mem = tt3650_ci_write_attribute_mem;
345 state->ca.read_cam_control = tt3650_ci_read_cam_control;
346 state->ca.write_cam_control = tt3650_ci_write_cam_control;
347 state->ca.slot_reset = tt3650_ci_slot_reset;
348 state->ca.slot_shutdown = tt3650_ci_slot_shutdown;
349 state->ca.slot_ts_enable = tt3650_ci_slot_ts_enable;
350 state->ca.poll_slot_status = tt3650_ci_poll_slot_status;
351 state->ca.data = d;
352
353 ret = dvb_ca_en50221_init(&a->dvb_adap,
354 &state->ca,
355 /* flags */ 0,
356 /* n_slots */ 1);
357 if (ret) {
358 err("Cannot initialize CI: Error %d.", ret);
359 memset(&state->ca, 0, sizeof(state->ca));
360 return ret;
361 }
362
363 info("CI initialized.");
364
365 return 0;
366}
367
368static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num)
369{
370 struct dvb_usb_device *d = i2c_get_adapdata(adap);
371 static u8 obuf[60], ibuf[60];
372 int i, write_read, read;
373
374 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
375 return -EAGAIN;
376
377 if (num > 2)
378 warn("more than 2 i2c messages at a time is not handled yet. TODO.");
379
380 for (i = 0; i < num; i++) {
381 write_read = i+1 < num && (msg[i+1].flags & I2C_M_RD);
382 read = msg[i].flags & I2C_M_RD;
383
384 obuf[0] = (msg[i].addr << 1) | (write_read | read);
385 if (read)
386 obuf[1] = 0;
387 else
388 obuf[1] = msg[i].len;
389
390 /* read request */
391 if (write_read)
392 obuf[2] = msg[i+1].len;
393 else if (read)
394 obuf[2] = msg[i].len;
395 else
396 obuf[2] = 0;
397
398 memcpy(&obuf[3], msg[i].buf, msg[i].len);
399
400 if (ttusb2_msg(d, CMD_I2C_XFER, obuf, obuf[1]+3, ibuf, obuf[2] + 3) < 0) {
401 err("i2c transfer failed.");
402 break;
403 }
404
405 if (write_read) {
406 memcpy(msg[i+1].buf, &ibuf[3], msg[i+1].len);
407 i++;
408 } else if (read)
409 memcpy(msg[i].buf, &ibuf[3], msg[i].len);
410 }
411
412 mutex_unlock(&d->i2c_mutex);
413 return i;
414}
415
416static u32 ttusb2_i2c_func(struct i2c_adapter *adapter)
417{
418 return I2C_FUNC_I2C;
419}
420
421static struct i2c_algorithm ttusb2_i2c_algo = {
422 .master_xfer = ttusb2_i2c_xfer,
423 .functionality = ttusb2_i2c_func,
424};
425
426/* command to poll IR receiver (copied from pctv452e.c) */
427#define CMD_GET_IR_CODE 0x1b
428
429/* IR */
430static int tt3650_rc_query(struct dvb_usb_device *d)
431{
432 int ret;
433 u8 rx[9]; /* A CMD_GET_IR_CODE reply is 9 bytes long */
434 struct ttusb2_state *st = d->priv;
435 ret = ttusb2_msg(d, CMD_GET_IR_CODE, NULL, 0, rx, sizeof(rx));
436 if (ret != 0)
437 return ret;
438
439 if (rx[8] & 0x01) {
440 /* got a "press" event */
441 st->last_rc_key = (rx[3] << 8) | rx[2];
442 deb_info("%s: cmd=0x%02x sys=0x%02x\n", __func__, rx[2], rx[3]);
443 rc_keydown(d->rc_dev, st->last_rc_key, 0);
444 } else if (st->last_rc_key) {
445 rc_keyup(d->rc_dev);
446 st->last_rc_key = 0;
447 }
448
449 return 0;
450}
451
452
453/* Callbacks for DVB USB */
454static int ttusb2_identify_state (struct usb_device *udev, struct
455 dvb_usb_device_properties *props, struct dvb_usb_device_description **desc,
456 int *cold)
457{
458 *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0;
459 return 0;
460}
461
462static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff)
463{
464 u8 b = onoff;
465 ttusb2_msg(d, CMD_POWER, &b, 0, NULL, 0);
466 return ttusb2_msg(d, CMD_POWER, &b, 1, NULL, 0);
467}
468
469
470static struct tda10086_config tda10086_config = {
471 .demod_address = 0x0e,
472 .invert = 0,
473 .diseqc_tone = 1,
474 .xtal_freq = TDA10086_XTAL_16M,
475};
476
477static struct tda10023_config tda10023_config = {
478 .demod_address = 0x0c,
479 .invert = 0,
480 .xtal = 16000000,
481 .pll_m = 11,
482 .pll_p = 3,
483 .pll_n = 1,
484 .deltaf = 0xa511,
485};
486
487static struct tda10048_config tda10048_config = {
488 .demod_address = 0x10 >> 1,
489 .output_mode = TDA10048_PARALLEL_OUTPUT,
490 .inversion = TDA10048_INVERSION_ON,
491 .dtv6_if_freq_khz = TDA10048_IF_4000,
492 .dtv7_if_freq_khz = TDA10048_IF_4500,
493 .dtv8_if_freq_khz = TDA10048_IF_5000,
494 .clk_freq_khz = TDA10048_CLK_16000,
495 .no_firmware = 1,
496 .set_pll = true ,
497 .pll_m = 5,
498 .pll_n = 3,
499 .pll_p = 0,
500};
501
502static struct tda827x_config tda827x_config = {
503 .config = 0,
504};
505
506static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap)
507{
508 if (usb_set_interface(adap->dev->udev,0,3) < 0)
509 err("set interface to alts=3 failed");
510
511 if ((adap->fe_adap[0].fe = dvb_attach(tda10086_attach, &tda10086_config, &adap->dev->i2c_adap)) == NULL) {
512 deb_info("TDA10086 attach failed\n");
513 return -ENODEV;
514 }
515
516 return 0;
517}
518
519static int ttusb2_ct3650_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
520{
521 struct dvb_usb_adapter *adap = fe->dvb->priv;
522
523 return adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, enable);
524}
525
526static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap)
527{
528 if (usb_set_interface(adap->dev->udev, 0, 3) < 0)
529 err("set interface to alts=3 failed");
530
531 if (adap->fe_adap[0].fe == NULL) {
532 /* FE 0 DVB-C */
533 adap->fe_adap[0].fe = dvb_attach(tda10023_attach,
534 &tda10023_config, &adap->dev->i2c_adap, 0x48);
535
536 if (adap->fe_adap[0].fe == NULL) {
537 deb_info("TDA10023 attach failed\n");
538 return -ENODEV;
539 }
540 tt3650_ci_init(adap);
541 } else {
542 adap->fe_adap[1].fe = dvb_attach(tda10048_attach,
543 &tda10048_config, &adap->dev->i2c_adap);
544
545 if (adap->fe_adap[1].fe == NULL) {
546 deb_info("TDA10048 attach failed\n");
547 return -ENODEV;
548 }
549
550 /* tuner is behind TDA10023 I2C-gate */
551 adap->fe_adap[1].fe->ops.i2c_gate_ctrl = ttusb2_ct3650_i2c_gate_ctrl;
552
553 }
554
555 return 0;
556}
557
558static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap)
559{
560 struct dvb_frontend *fe;
561
562 /* MFE: select correct FE to attach tuner since that's called twice */
563 if (adap->fe_adap[1].fe == NULL)
564 fe = adap->fe_adap[0].fe;
565 else
566 fe = adap->fe_adap[1].fe;
567
568 /* attach tuner */
569 if (dvb_attach(tda827x_attach, fe, 0x61, &adap->dev->i2c_adap, &tda827x_config) == NULL) {
570 printk(KERN_ERR "%s: No tda827x found!\n", __func__);
571 return -ENODEV;
572 }
573 return 0;
574}
575
576static int ttusb2_tuner_tda826x_attach(struct dvb_usb_adapter *adap)
577{
578 if (dvb_attach(tda826x_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) {
579 deb_info("TDA8263 attach failed\n");
580 return -ENODEV;
581 }
582
583 if (dvb_attach(lnbp21_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, 0, 0) == NULL) {
584 deb_info("LNBP21 attach failed\n");
585 return -ENODEV;
586 }
587 return 0;
588}
589
590/* DVB USB Driver stuff */
591static struct dvb_usb_device_properties ttusb2_properties;
592static struct dvb_usb_device_properties ttusb2_properties_s2400;
593static struct dvb_usb_device_properties ttusb2_properties_ct3650;
594
595static void ttusb2_usb_disconnect(struct usb_interface *intf)
596{
597 struct dvb_usb_device *d = usb_get_intfdata(intf);
598
599 tt3650_ci_uninit(d);
600 dvb_usb_device_exit(intf);
601}
602
603static int ttusb2_probe(struct usb_interface *intf,
604 const struct usb_device_id *id)
605{
606 if (0 == dvb_usb_device_init(intf, &ttusb2_properties,
607 THIS_MODULE, NULL, adapter_nr) ||
608 0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400,
609 THIS_MODULE, NULL, adapter_nr) ||
610 0 == dvb_usb_device_init(intf, &ttusb2_properties_ct3650,
611 THIS_MODULE, NULL, adapter_nr))
612 return 0;
613 return -ENODEV;
614}
615
616static struct usb_device_id ttusb2_table [] = {
617 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) },
618 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) },
619 { USB_DEVICE(USB_VID_TECHNOTREND,
620 USB_PID_TECHNOTREND_CONNECT_S2400) },
621 { USB_DEVICE(USB_VID_TECHNOTREND,
622 USB_PID_TECHNOTREND_CONNECT_CT3650) },
623 {} /* Terminating entry */
624};
625MODULE_DEVICE_TABLE (usb, ttusb2_table);
626
627static struct dvb_usb_device_properties ttusb2_properties = {
628 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
629
630 .usb_ctrl = CYPRESS_FX2,
631 .firmware = "dvb-usb-pctv-400e-01.fw",
632
633 .size_of_priv = sizeof(struct ttusb2_state),
634
635 .num_adapters = 1,
636 .adapter = {
637 {
638 .num_frontends = 1,
639 .fe = {{
640 .streaming_ctrl = NULL, // ttusb2_streaming_ctrl,
641
642 .frontend_attach = ttusb2_frontend_tda10086_attach,
643 .tuner_attach = ttusb2_tuner_tda826x_attach,
644
645 /* parameter for the MPEG2-data transfer */
646 .stream = {
647 .type = USB_ISOC,
648 .count = 5,
649 .endpoint = 0x02,
650 .u = {
651 .isoc = {
652 .framesperurb = 4,
653 .framesize = 940,
654 .interval = 1,
655 }
656 }
657 }
658 }},
659 }
660 },
661
662 .power_ctrl = ttusb2_power_ctrl,
663 .identify_state = ttusb2_identify_state,
664
665 .i2c_algo = &ttusb2_i2c_algo,
666
667 .generic_bulk_ctrl_endpoint = 0x01,
668
669 .num_device_descs = 2,
670 .devices = {
671 { "Pinnacle 400e DVB-S USB2.0",
672 { &ttusb2_table[0], NULL },
673 { NULL },
674 },
675 { "Pinnacle 450e DVB-S USB2.0",
676 { &ttusb2_table[1], NULL },
677 { NULL },
678 },
679 }
680};
681
682static struct dvb_usb_device_properties ttusb2_properties_s2400 = {
683 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
684
685 .usb_ctrl = CYPRESS_FX2,
686 .firmware = "dvb-usb-tt-s2400-01.fw",
687
688 .size_of_priv = sizeof(struct ttusb2_state),
689
690 .num_adapters = 1,
691 .adapter = {
692 {
693 .num_frontends = 1,
694 .fe = {{
695 .streaming_ctrl = NULL,
696
697 .frontend_attach = ttusb2_frontend_tda10086_attach,
698 .tuner_attach = ttusb2_tuner_tda826x_attach,
699
700 /* parameter for the MPEG2-data transfer */
701 .stream = {
702 .type = USB_ISOC,
703 .count = 5,
704 .endpoint = 0x02,
705 .u = {
706 .isoc = {
707 .framesperurb = 4,
708 .framesize = 940,
709 .interval = 1,
710 }
711 }
712 }
713 }},
714 }
715 },
716
717 .power_ctrl = ttusb2_power_ctrl,
718 .identify_state = ttusb2_identify_state,
719
720 .i2c_algo = &ttusb2_i2c_algo,
721
722 .generic_bulk_ctrl_endpoint = 0x01,
723
724 .num_device_descs = 1,
725 .devices = {
726 { "Technotrend TT-connect S-2400",
727 { &ttusb2_table[2], NULL },
728 { NULL },
729 },
730 }
731};
732
733static struct dvb_usb_device_properties ttusb2_properties_ct3650 = {
734 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
735
736 .usb_ctrl = CYPRESS_FX2,
737
738 .size_of_priv = sizeof(struct ttusb2_state),
739
740 .rc.core = {
741 .rc_interval = 150, /* Less than IR_KEYPRESS_TIMEOUT */
742 .rc_codes = RC_MAP_TT_1500,
743 .rc_query = tt3650_rc_query,
744 .allowed_protos = RC_TYPE_UNKNOWN,
745 },
746
747 .num_adapters = 1,
748 .adapter = {
749 {
750 .num_frontends = 2,
751 .fe = {{
752 .streaming_ctrl = NULL,
753
754 .frontend_attach = ttusb2_frontend_tda10023_attach,
755 .tuner_attach = ttusb2_tuner_tda827x_attach,
756
757 /* parameter for the MPEG2-data transfer */
758 .stream = {
759 .type = USB_ISOC,
760 .count = 5,
761 .endpoint = 0x02,
762 .u = {
763 .isoc = {
764 .framesperurb = 4,
765 .framesize = 940,
766 .interval = 1,
767 }
768 }
769 }
770 }, {
771 .streaming_ctrl = NULL,
772
773 .frontend_attach = ttusb2_frontend_tda10023_attach,
774 .tuner_attach = ttusb2_tuner_tda827x_attach,
775
776 /* parameter for the MPEG2-data transfer */
777 .stream = {
778 .type = USB_ISOC,
779 .count = 5,
780 .endpoint = 0x02,
781 .u = {
782 .isoc = {
783 .framesperurb = 4,
784 .framesize = 940,
785 .interval = 1,
786 }
787 }
788 }
789 }},
790 },
791 },
792
793 .power_ctrl = ttusb2_power_ctrl,
794 .identify_state = ttusb2_identify_state,
795
796 .i2c_algo = &ttusb2_i2c_algo,
797
798 .generic_bulk_ctrl_endpoint = 0x01,
799
800 .num_device_descs = 1,
801 .devices = {
802 { "Technotrend TT-connect CT-3650",
803 .warm_ids = { &ttusb2_table[3], NULL },
804 },
805 }
806};
807
808static struct usb_driver ttusb2_driver = {
809 .name = "dvb_usb_ttusb2",
810 .probe = ttusb2_probe,
811 .disconnect = ttusb2_usb_disconnect,
812 .id_table = ttusb2_table,
813};
814
815module_usb_driver(ttusb2_driver);
816
817MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
818MODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0");
819MODULE_VERSION("1.0");
820MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/ttusb2.h b/drivers/media/usb/dvb-usb/ttusb2.h
new file mode 100644
index 000000000000..52a63af40896
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/ttusb2.h
@@ -0,0 +1,70 @@
1/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones
2 * (e.g. Pinnacle 400e DVB-S USB2.0).
3 *
4 * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
5 * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
6 * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.de>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#ifndef _DVB_USB_TTUSB2_H_
15#define _DVB_USB_TTUSB2_H_
16
17/* TTUSB protocol
18 *
19 * always to messages (out/in)
20 * out message:
21 * 0xaa <id> <cmdbyte> <datalen> <data...>
22 *
23 * in message (complete block is always 0x40 bytes long)
24 * 0x55 <id> <cmdbyte> <datalen> <data...>
25 *
26 * id is incremented for each transaction
27 */
28
29#define CMD_DSP_DOWNLOAD 0x13
30/* out data: <byte>[28]
31 * last block must be empty */
32
33#define CMD_DSP_BOOT 0x14
34/* out data: nothing */
35
36#define CMD_POWER 0x15
37/* out data: <on=1/off=0> */
38
39#define CMD_LNB 0x16
40/* out data: <power=1> <18V=0,13V=1> <tone> <??=1> <??=1> */
41
42#define CMD_GET_VERSION 0x17
43/* in data: <version_byte>[5] */
44
45#define CMD_DISEQC 0x18
46/* out data: <master=0xff/burst=??> <cmdlen> <cmdbytes>[cmdlen] */
47
48#define CMD_PID_ENABLE 0x22
49/* out data: <index> <type: ts=1/sec=2> <pid msb> <pid lsb> */
50
51#define CMD_PID_DISABLE 0x23
52/* out data: <index> */
53
54#define CMD_FILTER_ENABLE 0x24
55/* out data: <index> <pid_idx> <filter>[12] <mask>[12] */
56
57#define CMD_FILTER_DISABLE 0x25
58/* out data: <index> */
59
60#define CMD_GET_DSP_VERSION 0x26
61/* in data: <version_byte>[28] */
62
63#define CMD_I2C_XFER 0x31
64/* out data: <addr << 1> <sndlen> <rcvlen> <data>[sndlen]
65 * in data: <addr << 1> <sndlen> <rcvlen> <data>[rcvlen] */
66
67#define CMD_I2C_BITRATE 0x32
68/* out data: <default=0> */
69
70#endif
diff --git a/drivers/media/usb/dvb-usb/umt-010.c b/drivers/media/usb/dvb-usb/umt-010.c
new file mode 100644
index 000000000000..9b042292e788
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/umt-010.c
@@ -0,0 +1,151 @@
1/* DVB USB framework compliant Linux driver for the HanfTek UMT-010 USB2.0
2 * DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation, version 2.
9 *
10 * see Documentation/dvb/README.dvb-usb for more information
11 */
12#include "dibusb.h"
13
14#include "mt352.h"
15
16DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
17
18static int umt_mt352_demod_init(struct dvb_frontend *fe)
19{
20 static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d };
21 static u8 mt352_reset[] = { 0x50, 0x80 };
22 static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 };
23 static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
24 static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 };
25
26 static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff };
27 static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff };
28 static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 };
29 static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 };
30 static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f };
31
32 static u8 mt352_acq_ctl[] = { 0x53, 0x50 };
33 static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 };
34
35 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
36 udelay(2000);
37 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
38 mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio));
39
40 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
41 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
42
43 mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1));
44 mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2));
45 mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3));
46 mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4));
47 mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5));
48
49 mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl));
50 mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1));
51
52 return 0;
53}
54
55static int umt_mt352_frontend_attach(struct dvb_usb_adapter *adap)
56{
57 struct mt352_config umt_config;
58
59 memset(&umt_config,0,sizeof(struct mt352_config));
60 umt_config.demod_init = umt_mt352_demod_init;
61 umt_config.demod_address = 0xf;
62
63 adap->fe_adap[0].fe = dvb_attach(mt352_attach, &umt_config, &adap->dev->i2c_adap);
64
65 return 0;
66}
67
68static int umt_tuner_attach (struct dvb_usb_adapter *adap)
69{
70 dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_TUA6034);
71 return 0;
72}
73
74/* USB Driver stuff */
75static struct dvb_usb_device_properties umt_properties;
76
77static int umt_probe(struct usb_interface *intf,
78 const struct usb_device_id *id)
79{
80 if (0 == dvb_usb_device_init(intf, &umt_properties,
81 THIS_MODULE, NULL, adapter_nr))
82 return 0;
83 return -EINVAL;
84}
85
86/* do not change the order of the ID table */
87static struct usb_device_id umt_table [] = {
88/* 00 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) },
89/* 01 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) },
90 { } /* Terminating entry */
91};
92MODULE_DEVICE_TABLE (usb, umt_table);
93
94static struct dvb_usb_device_properties umt_properties = {
95 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
96
97 .usb_ctrl = CYPRESS_FX2,
98 .firmware = "dvb-usb-umt-010-02.fw",
99
100 .num_adapters = 1,
101 .adapter = {
102 {
103 .num_frontends = 1,
104 .fe = {{
105 .streaming_ctrl = dibusb2_0_streaming_ctrl,
106 .frontend_attach = umt_mt352_frontend_attach,
107 .tuner_attach = umt_tuner_attach,
108
109 /* parameter for the MPEG2-data transfer */
110 .stream = {
111 .type = USB_BULK,
112 .count = MAX_NO_URBS_FOR_DATA_STREAM,
113 .endpoint = 0x06,
114 .u = {
115 .bulk = {
116 .buffersize = 512,
117 }
118 }
119 },
120 }},
121 .size_of_priv = sizeof(struct dibusb_state),
122 }
123 },
124 .power_ctrl = dibusb_power_ctrl,
125
126 .i2c_algo = &dibusb_i2c_algo,
127
128 .generic_bulk_ctrl_endpoint = 0x01,
129
130 .num_device_descs = 1,
131 .devices = {
132 { "Hanftek UMT-010 DVB-T USB2.0",
133 { &umt_table[0], NULL },
134 { &umt_table[1], NULL },
135 },
136 }
137};
138
139static struct usb_driver umt_driver = {
140 .name = "dvb_usb_umt_010",
141 .probe = umt_probe,
142 .disconnect = dvb_usb_device_exit,
143 .id_table = umt_table,
144};
145
146module_usb_driver(umt_driver);
147
148MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
149MODULE_DESCRIPTION("Driver for HanfTek UMT 010 USB2.0 DVB-T device");
150MODULE_VERSION("1.0");
151MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/usb-urb.c b/drivers/media/usb/dvb-usb/usb-urb.c
new file mode 100644
index 000000000000..d62ee0f5a165
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/usb-urb.c
@@ -0,0 +1,254 @@
1/* usb-urb.c is part of the DVB USB library.
2 *
3 * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
4 * see dvb-usb-init.c for copyright information.
5 *
6 * This file keeps functions for initializing and handling the
7 * BULK and ISOC USB data transfers in a generic way.
8 * Can be used for DVB-only and also, that's the plan, for
9 * Hybrid USB devices (analog and DVB).
10 */
11#include "dvb-usb-common.h"
12
13/* URB stuff for streaming */
14static void usb_urb_complete(struct urb *urb)
15{
16 struct usb_data_stream *stream = urb->context;
17 int ptype = usb_pipetype(urb->pipe);
18 int i;
19 u8 *b;
20
21 deb_uxfer("'%s' urb completed. status: %d, length: %d/%d, pack_num: %d, errors: %d\n",
22 ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk",
23 urb->status,urb->actual_length,urb->transfer_buffer_length,
24 urb->number_of_packets,urb->error_count);
25
26 switch (urb->status) {
27 case 0: /* success */
28 case -ETIMEDOUT: /* NAK */
29 break;
30 case -ECONNRESET: /* kill */
31 case -ENOENT:
32 case -ESHUTDOWN:
33 return;
34 default: /* error */
35 deb_ts("urb completition error %d.\n", urb->status);
36 break;
37 }
38
39 b = (u8 *) urb->transfer_buffer;
40 switch (ptype) {
41 case PIPE_ISOCHRONOUS:
42 for (i = 0; i < urb->number_of_packets; i++) {
43
44 if (urb->iso_frame_desc[i].status != 0)
45 deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
46 else if (urb->iso_frame_desc[i].actual_length > 0)
47 stream->complete(stream, b + urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].actual_length);
48
49 urb->iso_frame_desc[i].status = 0;
50 urb->iso_frame_desc[i].actual_length = 0;
51 }
52 debug_dump(b,20,deb_uxfer);
53 break;
54 case PIPE_BULK:
55 if (urb->actual_length > 0)
56 stream->complete(stream, b, urb->actual_length);
57 break;
58 default:
59 err("unknown endpoint type in completition handler.");
60 return;
61 }
62 usb_submit_urb(urb,GFP_ATOMIC);
63}
64
65int usb_urb_kill(struct usb_data_stream *stream)
66{
67 int i;
68 for (i = 0; i < stream->urbs_submitted; i++) {
69 deb_ts("killing URB no. %d.\n",i);
70
71 /* stop the URB */
72 usb_kill_urb(stream->urb_list[i]);
73 }
74 stream->urbs_submitted = 0;
75 return 0;
76}
77
78int usb_urb_submit(struct usb_data_stream *stream)
79{
80 int i,ret;
81 for (i = 0; i < stream->urbs_initialized; i++) {
82 deb_ts("submitting URB no. %d\n",i);
83 if ((ret = usb_submit_urb(stream->urb_list[i],GFP_ATOMIC))) {
84 err("could not submit URB no. %d - get them all back",i);
85 usb_urb_kill(stream);
86 return ret;
87 }
88 stream->urbs_submitted++;
89 }
90 return 0;
91}
92
93static int usb_free_stream_buffers(struct usb_data_stream *stream)
94{
95 if (stream->state & USB_STATE_URB_BUF) {
96 while (stream->buf_num) {
97 stream->buf_num--;
98 deb_mem("freeing buffer %d\n",stream->buf_num);
99 usb_free_coherent(stream->udev, stream->buf_size,
100 stream->buf_list[stream->buf_num],
101 stream->dma_addr[stream->buf_num]);
102 }
103 }
104
105 stream->state &= ~USB_STATE_URB_BUF;
106
107 return 0;
108}
109
110static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num, unsigned long size)
111{
112 stream->buf_num = 0;
113 stream->buf_size = size;
114
115 deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
116
117 for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) {
118 deb_mem("allocating buffer %d\n",stream->buf_num);
119 if (( stream->buf_list[stream->buf_num] =
120 usb_alloc_coherent(stream->udev, size, GFP_ATOMIC,
121 &stream->dma_addr[stream->buf_num]) ) == NULL) {
122 deb_mem("not enough memory for urb-buffer allocation.\n");
123 usb_free_stream_buffers(stream);
124 return -ENOMEM;
125 }
126 deb_mem("buffer %d: %p (dma: %Lu)\n",
127 stream->buf_num,
128stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num]);
129 memset(stream->buf_list[stream->buf_num],0,size);
130 stream->state |= USB_STATE_URB_BUF;
131 }
132 deb_mem("allocation successful\n");
133
134 return 0;
135}
136
137static int usb_bulk_urb_init(struct usb_data_stream *stream)
138{
139 int i, j;
140
141 if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
142 stream->props.u.bulk.buffersize)) < 0)
143 return i;
144
145 /* allocate the URBs */
146 for (i = 0; i < stream->props.count; i++) {
147 stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);
148 if (!stream->urb_list[i]) {
149 deb_mem("not enough memory for urb_alloc_urb!.\n");
150 for (j = 0; j < i; j++)
151 usb_free_urb(stream->urb_list[j]);
152 return -ENOMEM;
153 }
154 usb_fill_bulk_urb( stream->urb_list[i], stream->udev,
155 usb_rcvbulkpipe(stream->udev,stream->props.endpoint),
156 stream->buf_list[i],
157 stream->props.u.bulk.buffersize,
158 usb_urb_complete, stream);
159
160 stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
161 stream->urb_list[i]->transfer_dma = stream->dma_addr[i];
162 stream->urbs_initialized++;
163 }
164 return 0;
165}
166
167static int usb_isoc_urb_init(struct usb_data_stream *stream)
168{
169 int i,j;
170
171 if ((i = usb_allocate_stream_buffers(stream,stream->props.count,
172 stream->props.u.isoc.framesize*stream->props.u.isoc.framesperurb)) < 0)
173 return i;
174
175 /* allocate the URBs */
176 for (i = 0; i < stream->props.count; i++) {
177 struct urb *urb;
178 int frame_offset = 0;
179
180 stream->urb_list[i] = usb_alloc_urb(stream->props.u.isoc.framesperurb, GFP_ATOMIC);
181 if (!stream->urb_list[i]) {
182 deb_mem("not enough memory for urb_alloc_urb!\n");
183 for (j = 0; j < i; j++)
184 usb_free_urb(stream->urb_list[j]);
185 return -ENOMEM;
186 }
187
188 urb = stream->urb_list[i];
189
190 urb->dev = stream->udev;
191 urb->context = stream;
192 urb->complete = usb_urb_complete;
193 urb->pipe = usb_rcvisocpipe(stream->udev,stream->props.endpoint);
194 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
195 urb->interval = stream->props.u.isoc.interval;
196 urb->number_of_packets = stream->props.u.isoc.framesperurb;
197 urb->transfer_buffer_length = stream->buf_size;
198 urb->transfer_buffer = stream->buf_list[i];
199 urb->transfer_dma = stream->dma_addr[i];
200
201 for (j = 0; j < stream->props.u.isoc.framesperurb; j++) {
202 urb->iso_frame_desc[j].offset = frame_offset;
203 urb->iso_frame_desc[j].length = stream->props.u.isoc.framesize;
204 frame_offset += stream->props.u.isoc.framesize;
205 }
206
207 stream->urbs_initialized++;
208 }
209 return 0;
210}
211
212int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props)
213{
214 if (stream == NULL || props == NULL)
215 return -EINVAL;
216
217 memcpy(&stream->props, props, sizeof(*props));
218
219 usb_clear_halt(stream->udev,usb_rcvbulkpipe(stream->udev,stream->props.endpoint));
220
221 if (stream->complete == NULL) {
222 err("there is no data callback - this doesn't make sense.");
223 return -EINVAL;
224 }
225
226 switch (stream->props.type) {
227 case USB_BULK:
228 return usb_bulk_urb_init(stream);
229 case USB_ISOC:
230 return usb_isoc_urb_init(stream);
231 default:
232 err("unknown URB-type for data transfer.");
233 return -EINVAL;
234 }
235}
236
237int usb_urb_exit(struct usb_data_stream *stream)
238{
239 int i;
240
241 usb_urb_kill(stream);
242
243 for (i = 0; i < stream->urbs_initialized; i++) {
244 if (stream->urb_list[i] != NULL) {
245 deb_mem("freeing URB no. %d.\n",i);
246 /* free the URBs */
247 usb_free_urb(stream->urb_list[i]);
248 }
249 }
250 stream->urbs_initialized = 0;
251
252 usb_free_stream_buffers(stream);
253 return 0;
254}
diff --git a/drivers/media/usb/dvb-usb/vp702x-fe.c b/drivers/media/usb/dvb-usb/vp702x-fe.c
new file mode 100644
index 000000000000..5eab468dd904
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/vp702x-fe.c
@@ -0,0 +1,379 @@
1/* DVB frontend part of the Linux driver for the TwinhanDTV StarBox USB2.0
2 * DVB-S receiver.
3 *
4 * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
5 * Metzler Brothers Systementwicklung GbR
6 *
7 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
8 *
9 * Thanks to Twinhan who kindly provided hardware and information.
10 *
11 * This file can be removed soon, after the DST-driver is rewritten to provice
12 * the frontend-controlling separately.
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the Free
16 * Software Foundation, version 2.
17 *
18 * see Documentation/dvb/README.dvb-usb for more information
19 *
20 */
21#include "vp702x.h"
22
23struct vp702x_fe_state {
24 struct dvb_frontend fe;
25 struct dvb_usb_device *d;
26
27 struct dvb_frontend_ops ops;
28
29 fe_sec_voltage_t voltage;
30 fe_sec_tone_mode_t tone_mode;
31
32 u8 lnb_buf[8];
33
34 u8 lock;
35 u8 sig;
36 u8 snr;
37
38 unsigned long next_status_check;
39 unsigned long status_check_interval;
40};
41
42static int vp702x_fe_refresh_state(struct vp702x_fe_state *st)
43{
44 struct vp702x_device_state *dst = st->d->priv;
45 u8 *buf;
46
47 if (time_after(jiffies, st->next_status_check)) {
48 mutex_lock(&dst->buf_mutex);
49 buf = dst->buf;
50
51 vp702x_usb_in_op(st->d, READ_STATUS, 0, 0, buf, 10);
52 st->lock = buf[4];
53
54 vp702x_usb_in_op(st->d, READ_TUNER_REG_REQ, 0x11, 0, buf, 1);
55 st->snr = buf[0];
56
57 vp702x_usb_in_op(st->d, READ_TUNER_REG_REQ, 0x15, 0, buf, 1);
58 st->sig = buf[0];
59
60 mutex_unlock(&dst->buf_mutex);
61 st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
62 }
63 return 0;
64}
65
66static u8 vp702x_chksum(u8 *buf,int f, int count)
67{
68 u8 s = 0;
69 int i;
70 for (i = f; i < f+count; i++)
71 s += buf[i];
72 return ~s+1;
73}
74
75static int vp702x_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
76{
77 struct vp702x_fe_state *st = fe->demodulator_priv;
78 vp702x_fe_refresh_state(st);
79 deb_fe("%s\n",__func__);
80
81 if (st->lock == 0)
82 *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
83 else
84 *status = 0;
85
86 if (*status & FE_HAS_LOCK)
87 st->status_check_interval = 1000;
88 else
89 st->status_check_interval = 250;
90 return 0;
91}
92
93/* not supported by this Frontend */
94static int vp702x_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
95{
96 struct vp702x_fe_state *st = fe->demodulator_priv;
97 vp702x_fe_refresh_state(st);
98 *ber = 0;
99 return 0;
100}
101
102/* not supported by this Frontend */
103static int vp702x_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
104{
105 struct vp702x_fe_state *st = fe->demodulator_priv;
106 vp702x_fe_refresh_state(st);
107 *unc = 0;
108 return 0;
109}
110
111static int vp702x_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
112{
113 struct vp702x_fe_state *st = fe->demodulator_priv;
114 vp702x_fe_refresh_state(st);
115
116 *strength = (st->sig << 8) | st->sig;
117 return 0;
118}
119
120static int vp702x_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
121{
122 u8 _snr;
123 struct vp702x_fe_state *st = fe->demodulator_priv;
124 vp702x_fe_refresh_state(st);
125
126 _snr = (st->snr & 0x1f) * 0xff / 0x1f;
127 *snr = (_snr << 8) | _snr;
128 return 0;
129}
130
131static int vp702x_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
132{
133 deb_fe("%s\n",__func__);
134 tune->min_delay_ms = 2000;
135 return 0;
136}
137
138static int vp702x_fe_set_frontend(struct dvb_frontend *fe)
139{
140 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
141 struct vp702x_fe_state *st = fe->demodulator_priv;
142 struct vp702x_device_state *dst = st->d->priv;
143 u32 freq = fep->frequency/1000;
144 /*CalFrequency*/
145/* u16 frequencyRef[16] = { 2, 4, 8, 16, 32, 64, 128, 256, 24, 5, 10, 20, 40, 80, 160, 320 }; */
146 u64 sr;
147 u8 *cmd;
148
149 mutex_lock(&dst->buf_mutex);
150
151 cmd = dst->buf;
152 memset(cmd, 0, 10);
153
154 cmd[0] = (freq >> 8) & 0x7f;
155 cmd[1] = freq & 0xff;
156 cmd[2] = 1; /* divrate == 4 -> frequencyRef[1] -> 1 here */
157
158 sr = (u64) (fep->symbol_rate/1000) << 20;
159 do_div(sr,88000);
160 cmd[3] = (sr >> 12) & 0xff;
161 cmd[4] = (sr >> 4) & 0xff;
162 cmd[5] = (sr << 4) & 0xf0;
163
164 deb_fe("setting frontend to: %u -> %u (%x) LNB-based GHz, symbolrate: %d -> %lu (%lx)\n",
165 fep->frequency, freq, freq, fep->symbol_rate,
166 (unsigned long) sr, (unsigned long) sr);
167
168/* if (fep->inversion == INVERSION_ON)
169 cmd[6] |= 0x80; */
170
171 if (st->voltage == SEC_VOLTAGE_18)
172 cmd[6] |= 0x40;
173
174/* if (fep->symbol_rate > 8000000)
175 cmd[6] |= 0x20;
176
177 if (fep->frequency < 1531000)
178 cmd[6] |= 0x04;
179
180 if (st->tone_mode == SEC_TONE_ON)
181 cmd[6] |= 0x01;*/
182
183 cmd[7] = vp702x_chksum(cmd,0,7);
184
185 st->status_check_interval = 250;
186 st->next_status_check = jiffies;
187
188 vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
189
190 if (cmd[2] == 0 && cmd[3] == 0)
191 deb_fe("tuning failed.\n");
192 else
193 deb_fe("tuning succeeded.\n");
194
195 mutex_unlock(&dst->buf_mutex);
196
197 return 0;
198}
199
200static int vp702x_fe_init(struct dvb_frontend *fe)
201{
202 struct vp702x_fe_state *st = fe->demodulator_priv;
203 deb_fe("%s\n",__func__);
204 vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0);
205 return 0;
206}
207
208static int vp702x_fe_sleep(struct dvb_frontend *fe)
209{
210 deb_fe("%s\n",__func__);
211 return 0;
212}
213
214static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
215 struct dvb_diseqc_master_cmd *m)
216{
217 u8 *cmd;
218 struct vp702x_fe_state *st = fe->demodulator_priv;
219 struct vp702x_device_state *dst = st->d->priv;
220
221 deb_fe("%s\n",__func__);
222
223 if (m->msg_len > 4)
224 return -EINVAL;
225
226 mutex_lock(&dst->buf_mutex);
227
228 cmd = dst->buf;
229 cmd[1] = SET_DISEQC_CMD;
230 cmd[2] = m->msg_len;
231 memcpy(&cmd[3], m->msg, m->msg_len);
232 cmd[7] = vp702x_chksum(cmd, 0, 7);
233
234 vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
235
236 if (cmd[2] == 0 && cmd[3] == 0)
237 deb_fe("diseqc cmd failed.\n");
238 else
239 deb_fe("diseqc cmd succeeded.\n");
240
241 mutex_unlock(&dst->buf_mutex);
242
243 return 0;
244}
245
246static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
247{
248 deb_fe("%s\n",__func__);
249 return 0;
250}
251
252static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
253{
254 struct vp702x_fe_state *st = fe->demodulator_priv;
255 struct vp702x_device_state *dst = st->d->priv;
256 u8 *buf;
257
258 deb_fe("%s\n",__func__);
259
260 st->tone_mode = tone;
261
262 if (tone == SEC_TONE_ON)
263 st->lnb_buf[2] = 0x02;
264 else
265 st->lnb_buf[2] = 0x00;
266
267 st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
268
269 mutex_lock(&dst->buf_mutex);
270
271 buf = dst->buf;
272 memcpy(buf, st->lnb_buf, 8);
273
274 vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
275 if (buf[2] == 0 && buf[3] == 0)
276 deb_fe("set_tone cmd failed.\n");
277 else
278 deb_fe("set_tone cmd succeeded.\n");
279
280 mutex_unlock(&dst->buf_mutex);
281
282 return 0;
283}
284
285static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t
286 voltage)
287{
288 struct vp702x_fe_state *st = fe->demodulator_priv;
289 struct vp702x_device_state *dst = st->d->priv;
290 u8 *buf;
291 deb_fe("%s\n",__func__);
292
293 st->voltage = voltage;
294
295 if (voltage != SEC_VOLTAGE_OFF)
296 st->lnb_buf[4] = 0x01;
297 else
298 st->lnb_buf[4] = 0x00;
299
300 st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
301
302 mutex_lock(&dst->buf_mutex);
303
304 buf = dst->buf;
305 memcpy(buf, st->lnb_buf, 8);
306
307 vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
308 if (buf[2] == 0 && buf[3] == 0)
309 deb_fe("set_voltage cmd failed.\n");
310 else
311 deb_fe("set_voltage cmd succeeded.\n");
312
313 mutex_unlock(&dst->buf_mutex);
314 return 0;
315}
316
317static void vp702x_fe_release(struct dvb_frontend* fe)
318{
319 struct vp702x_fe_state *st = fe->demodulator_priv;
320 kfree(st);
321}
322
323static struct dvb_frontend_ops vp702x_fe_ops;
324
325struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d)
326{
327 struct vp702x_fe_state *s = kzalloc(sizeof(struct vp702x_fe_state), GFP_KERNEL);
328 if (s == NULL)
329 goto error;
330
331 s->d = d;
332
333 memcpy(&s->fe.ops,&vp702x_fe_ops,sizeof(struct dvb_frontend_ops));
334 s->fe.demodulator_priv = s;
335
336 s->lnb_buf[1] = SET_LNB_POWER;
337 s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */
338
339 return &s->fe;
340error:
341 return NULL;
342}
343
344
345static struct dvb_frontend_ops vp702x_fe_ops = {
346 .delsys = { SYS_DVBS },
347 .info = {
348 .name = "Twinhan DST-like frontend (VP7021/VP7020) DVB-S",
349 .frequency_min = 950000,
350 .frequency_max = 2150000,
351 .frequency_stepsize = 1000, /* kHz for QPSK frontends */
352 .frequency_tolerance = 0,
353 .symbol_rate_min = 1000000,
354 .symbol_rate_max = 45000000,
355 .symbol_rate_tolerance = 500, /* ppm */
356 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
357 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
358 FE_CAN_QPSK |
359 FE_CAN_FEC_AUTO
360 },
361 .release = vp702x_fe_release,
362
363 .init = vp702x_fe_init,
364 .sleep = vp702x_fe_sleep,
365
366 .set_frontend = vp702x_fe_set_frontend,
367 .get_tune_settings = vp702x_fe_get_tune_settings,
368
369 .read_status = vp702x_fe_read_status,
370 .read_ber = vp702x_fe_read_ber,
371 .read_signal_strength = vp702x_fe_read_signal_strength,
372 .read_snr = vp702x_fe_read_snr,
373 .read_ucblocks = vp702x_fe_read_unc_blocks,
374
375 .diseqc_send_master_cmd = vp702x_fe_send_diseqc_msg,
376 .diseqc_send_burst = vp702x_fe_send_diseqc_burst,
377 .set_tone = vp702x_fe_set_tone,
378 .set_voltage = vp702x_fe_set_voltage,
379};
diff --git a/drivers/media/usb/dvb-usb/vp702x.c b/drivers/media/usb/dvb-usb/vp702x.c
new file mode 100644
index 000000000000..07c673a6e764
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/vp702x.c
@@ -0,0 +1,444 @@
1/* DVB USB compliant Linux driver for the TwinhanDTV StarBox USB2.0 DVB-S
2 * receiver.
3 *
4 * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de>
5 * Metzler Brothers Systementwicklung GbR
6 *
7 * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de>
8 *
9 * Thanks to Twinhan who kindly provided hardware and information.
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the Free
13 * Software Foundation, version 2.
14 *
15 * see Documentation/dvb/README.dvb-usb for more information
16 */
17#include "vp702x.h"
18#include <linux/mutex.h>
19
20/* debug */
21int dvb_usb_vp702x_debug;
22module_param_named(debug,dvb_usb_vp702x_debug, int, 0644);
23MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
24
25DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
26
27struct vp702x_adapter_state {
28 int pid_filter_count;
29 int pid_filter_can_bypass;
30 u8 pid_filter_state;
31};
32
33static int vp702x_usb_in_op_unlocked(struct dvb_usb_device *d, u8 req,
34 u16 value, u16 index, u8 *b, int blen)
35{
36 int ret;
37
38 ret = usb_control_msg(d->udev,
39 usb_rcvctrlpipe(d->udev, 0),
40 req,
41 USB_TYPE_VENDOR | USB_DIR_IN,
42 value, index, b, blen,
43 2000);
44
45 if (ret < 0) {
46 warn("usb in operation failed. (%d)", ret);
47 ret = -EIO;
48 } else
49 ret = 0;
50
51
52 deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
53 debug_dump(b,blen,deb_xfer);
54
55 return ret;
56}
57
58int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
59 u16 index, u8 *b, int blen)
60{
61 int ret;
62
63 mutex_lock(&d->usb_mutex);
64 ret = vp702x_usb_in_op_unlocked(d, req, value, index, b, blen);
65 mutex_unlock(&d->usb_mutex);
66
67 return ret;
68}
69
70int vp702x_usb_out_op_unlocked(struct dvb_usb_device *d, u8 req, u16 value,
71 u16 index, u8 *b, int blen)
72{
73 int ret;
74 deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
75 debug_dump(b,blen,deb_xfer);
76
77 if ((ret = usb_control_msg(d->udev,
78 usb_sndctrlpipe(d->udev,0),
79 req,
80 USB_TYPE_VENDOR | USB_DIR_OUT,
81 value,index,b,blen,
82 2000)) != blen) {
83 warn("usb out operation failed. (%d)",ret);
84 return -EIO;
85 } else
86 return 0;
87}
88
89int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
90 u16 index, u8 *b, int blen)
91{
92 int ret;
93
94 mutex_lock(&d->usb_mutex);
95 ret = vp702x_usb_out_op_unlocked(d, req, value, index, b, blen);
96 mutex_unlock(&d->usb_mutex);
97
98 return ret;
99}
100
101int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec)
102{
103 int ret;
104
105 if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
106 return ret;
107
108 ret = vp702x_usb_out_op_unlocked(d, REQUEST_OUT, 0, 0, o, olen);
109 msleep(msec);
110 ret = vp702x_usb_in_op_unlocked(d, REQUEST_IN, 0, 0, i, ilen);
111
112 mutex_unlock(&d->usb_mutex);
113 return ret;
114}
115
116static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o,
117 int olen, u8 *i, int ilen, int msec)
118{
119 struct vp702x_device_state *st = d->priv;
120 int ret = 0;
121 u8 *buf;
122 int buflen = max(olen + 2, ilen + 1);
123
124 ret = mutex_lock_interruptible(&st->buf_mutex);
125 if (ret < 0)
126 return ret;
127
128 if (buflen > st->buf_len) {
129 buf = kmalloc(buflen, GFP_KERNEL);
130 if (!buf) {
131 mutex_unlock(&st->buf_mutex);
132 return -ENOMEM;
133 }
134 info("successfully reallocated a bigger buffer");
135 kfree(st->buf);
136 st->buf = buf;
137 st->buf_len = buflen;
138 } else {
139 buf = st->buf;
140 }
141
142 buf[0] = 0x00;
143 buf[1] = cmd;
144 memcpy(&buf[2], o, olen);
145
146 ret = vp702x_usb_inout_op(d, buf, olen+2, buf, ilen+1, msec);
147
148 if (ret == 0)
149 memcpy(i, &buf[1], ilen);
150 mutex_unlock(&st->buf_mutex);
151
152 return ret;
153}
154
155static int vp702x_set_pld_mode(struct dvb_usb_adapter *adap, u8 bypass)
156{
157 int ret;
158 struct vp702x_device_state *st = adap->dev->priv;
159 u8 *buf;
160
161 mutex_lock(&st->buf_mutex);
162
163 buf = st->buf;
164 memset(buf, 0, 16);
165
166 ret = vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e,
167 0, buf, 16);
168 mutex_unlock(&st->buf_mutex);
169 return ret;
170}
171
172static int vp702x_set_pld_state(struct dvb_usb_adapter *adap, u8 state)
173{
174 int ret;
175 struct vp702x_device_state *st = adap->dev->priv;
176 u8 *buf;
177
178 mutex_lock(&st->buf_mutex);
179
180 buf = st->buf;
181 memset(buf, 0, 16);
182 ret = vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f,
183 0, buf, 16);
184
185 mutex_unlock(&st->buf_mutex);
186
187 return ret;
188}
189
190static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onoff)
191{
192 struct vp702x_adapter_state *st = adap->priv;
193 struct vp702x_device_state *dst = adap->dev->priv;
194 u8 *buf;
195
196 if (onoff)
197 st->pid_filter_state |= (1 << id);
198 else {
199 st->pid_filter_state &= ~(1 << id);
200 pid = 0xffff;
201 }
202
203 id = 0x10 + id*2;
204
205 vp702x_set_pld_state(adap, st->pid_filter_state);
206
207 mutex_lock(&dst->buf_mutex);
208
209 buf = dst->buf;
210 memset(buf, 0, 16);
211 vp702x_usb_in_op(adap->dev, 0xe0, (((pid >> 8) & 0xff) << 8) | (id), 0, buf, 16);
212 vp702x_usb_in_op(adap->dev, 0xe0, (((pid ) & 0xff) << 8) | (id+1), 0, buf, 16);
213
214 mutex_unlock(&dst->buf_mutex);
215
216 return 0;
217}
218
219
220static int vp702x_init_pid_filter(struct dvb_usb_adapter *adap)
221{
222 struct vp702x_adapter_state *st = adap->priv;
223 struct vp702x_device_state *dst = adap->dev->priv;
224 int i;
225 u8 *b;
226
227 st->pid_filter_count = 8;
228 st->pid_filter_can_bypass = 1;
229 st->pid_filter_state = 0x00;
230
231 vp702x_set_pld_mode(adap, 1); /* bypass */
232
233 for (i = 0; i < st->pid_filter_count; i++)
234 vp702x_set_pid(adap, 0xffff, i, 1);
235
236 mutex_lock(&dst->buf_mutex);
237 b = dst->buf;
238 memset(b, 0, 10);
239 vp702x_usb_in_op(adap->dev, 0xb5, 3, 0, b, 10);
240 vp702x_usb_in_op(adap->dev, 0xb5, 0, 0, b, 10);
241 vp702x_usb_in_op(adap->dev, 0xb5, 1, 0, b, 10);
242 mutex_unlock(&dst->buf_mutex);
243 /*vp702x_set_pld_mode(d, 0); // filter */
244
245 return 0;
246}
247
248static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
249{
250 return 0;
251}
252
253/* keys for the enclosed remote control */
254static struct rc_map_table rc_map_vp702x_table[] = {
255 { 0x0001, KEY_1 },
256 { 0x0002, KEY_2 },
257};
258
259/* remote control stuff (does not work with my box) */
260static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
261{
262 u8 *key;
263 int i;
264
265/* remove the following return to enabled remote querying */
266 return 0;
267
268 key = kmalloc(10, GFP_KERNEL);
269 if (!key)
270 return -ENOMEM;
271
272 vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10);
273
274 deb_rc("remote query key: %x %d\n",key[1],key[1]);
275
276 if (key[1] == 0x44) {
277 *state = REMOTE_NO_KEY_PRESSED;
278 kfree(key);
279 return 0;
280 }
281
282 for (i = 0; i < ARRAY_SIZE(rc_map_vp702x_table); i++)
283 if (rc5_custom(&rc_map_vp702x_table[i]) == key[1]) {
284 *state = REMOTE_KEY_PRESSED;
285 *event = rc_map_vp702x_table[i].keycode;
286 break;
287 }
288 kfree(key);
289 return 0;
290}
291
292
293static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
294{
295 u8 i, *buf;
296 struct vp702x_device_state *st = d->priv;
297
298 mutex_lock(&st->buf_mutex);
299 buf = st->buf;
300 for (i = 6; i < 12; i++)
301 vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &buf[i - 6], 1);
302
303 memcpy(mac, buf, 6);
304 mutex_unlock(&st->buf_mutex);
305 return 0;
306}
307
308static int vp702x_frontend_attach(struct dvb_usb_adapter *adap)
309{
310 u8 buf[10] = { 0 };
311
312 vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 0, 7, NULL, 0);
313
314 if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0,
315 buf, 10, 10))
316 return -EIO;
317
318 buf[9] = '\0';
319 info("system string: %s",&buf[1]);
320
321 vp702x_init_pid_filter(adap);
322
323 adap->fe_adap[0].fe = vp702x_fe_attach(adap->dev);
324 vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 1, 7, NULL, 0);
325
326 return 0;
327}
328
329static struct dvb_usb_device_properties vp702x_properties;
330
331static int vp702x_usb_probe(struct usb_interface *intf,
332 const struct usb_device_id *id)
333{
334 struct dvb_usb_device *d;
335 struct vp702x_device_state *st;
336 int ret;
337
338 ret = dvb_usb_device_init(intf, &vp702x_properties,
339 THIS_MODULE, &d, adapter_nr);
340 if (ret)
341 goto out;
342
343 st = d->priv;
344 st->buf_len = 16;
345 st->buf = kmalloc(st->buf_len, GFP_KERNEL);
346 if (!st->buf) {
347 ret = -ENOMEM;
348 dvb_usb_device_exit(intf);
349 goto out;
350 }
351 mutex_init(&st->buf_mutex);
352
353out:
354 return ret;
355
356}
357
358static void vp702x_usb_disconnect(struct usb_interface *intf)
359{
360 struct dvb_usb_device *d = usb_get_intfdata(intf);
361 struct vp702x_device_state *st = d->priv;
362 mutex_lock(&st->buf_mutex);
363 kfree(st->buf);
364 mutex_unlock(&st->buf_mutex);
365 dvb_usb_device_exit(intf);
366}
367
368static struct usb_device_id vp702x_usb_table [] = {
369 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_COLD) },
370// { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_COLD) },
371// { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_WARM) },
372 { 0 },
373};
374MODULE_DEVICE_TABLE(usb, vp702x_usb_table);
375
376static struct dvb_usb_device_properties vp702x_properties = {
377 .usb_ctrl = CYPRESS_FX2,
378 .firmware = "dvb-usb-vp702x-02.fw",
379 .no_reconnect = 1,
380
381 .size_of_priv = sizeof(struct vp702x_device_state),
382
383 .num_adapters = 1,
384 .adapter = {
385 {
386 .num_frontends = 1,
387 .fe = {{
388 .caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS,
389
390 .streaming_ctrl = vp702x_streaming_ctrl,
391 .frontend_attach = vp702x_frontend_attach,
392
393 /* parameter for the MPEG2-data transfer */
394 .stream = {
395 .type = USB_BULK,
396 .count = 10,
397 .endpoint = 0x02,
398 .u = {
399 .bulk = {
400 .buffersize = 4096,
401 }
402 }
403 },
404 }},
405 .size_of_priv = sizeof(struct vp702x_adapter_state),
406 }
407 },
408 .read_mac_address = vp702x_read_mac_addr,
409
410 .rc.legacy = {
411 .rc_map_table = rc_map_vp702x_table,
412 .rc_map_size = ARRAY_SIZE(rc_map_vp702x_table),
413 .rc_interval = 400,
414 .rc_query = vp702x_rc_query,
415 },
416
417 .num_device_descs = 1,
418 .devices = {
419 { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7021)",
420 .cold_ids = { &vp702x_usb_table[0], NULL },
421 .warm_ids = { NULL },
422 },
423/* { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7020)",
424 .cold_ids = { &vp702x_usb_table[2], NULL },
425 .warm_ids = { &vp702x_usb_table[3], NULL },
426 },
427*/ { NULL },
428 }
429};
430
431/* usb specific object needed to register this driver with the usb subsystem */
432static struct usb_driver vp702x_usb_driver = {
433 .name = "dvb_usb_vp702x",
434 .probe = vp702x_usb_probe,
435 .disconnect = vp702x_usb_disconnect,
436 .id_table = vp702x_usb_table,
437};
438
439module_usb_driver(vp702x_usb_driver);
440
441MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
442MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones");
443MODULE_VERSION("1.0");
444MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/vp702x.h b/drivers/media/usb/dvb-usb/vp702x.h
new file mode 100644
index 000000000000..20b90055e7ac
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/vp702x.h
@@ -0,0 +1,113 @@
1#ifndef _DVB_USB_VP7021_H_
2#define _DVB_USB_VP7021_H_
3
4#define DVB_USB_LOG_PREFIX "vp702x"
5#include "dvb-usb.h"
6
7extern int dvb_usb_vp702x_debug;
8#define deb_info(args...) dprintk(dvb_usb_vp702x_debug,0x01,args)
9#define deb_xfer(args...) dprintk(dvb_usb_vp702x_debug,0x02,args)
10#define deb_rc(args...) dprintk(dvb_usb_vp702x_debug,0x04,args)
11#define deb_fe(args...) dprintk(dvb_usb_vp702x_debug,0x08,args)
12
13/* commands are read and written with USB control messages */
14
15/* consecutive read/write operation */
16#define REQUEST_OUT 0xB2
17#define REQUEST_IN 0xB3
18
19/* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0
20 * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer
21 * the returning buffer looks as follows
22 * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */
23
24#define GET_TUNER_STATUS 0x05
25/* additional in buffer:
26 * 0 1 2 3 4 5 6 7 8
27 * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */
28
29#define GET_SYSTEM_STRING 0x06
30/* additional in buffer:
31 * 0 1 2 3 4 5 6 7 8
32 * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */
33
34#define SET_DISEQC_CMD 0x08
35/* additional out buffer:
36 * 0 1 2 3 4
37 * len X1 X2 X3 X4
38 * additional in buffer:
39 * 0 1 2
40 * N/A 0 0 b[1] == b[2] == 0 -> success, failure otherwise */
41
42#define SET_LNB_POWER 0x09
43/* additional out buffer:
44 * 0 1 2
45 * 0x00 0xff 1 = on, 0 = off
46 * additional in buffer:
47 * 0 1 2
48 * N/A 0 0 b[1] == b[2] == 0 -> success failure otherwise */
49
50#define GET_MAC_ADDRESS 0x0A
51/* #define GET_MAC_ADDRESS 0x0B */
52/* additional in buffer:
53 * 0 1 2 3 4 5 6 7 8
54 * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */
55
56#define SET_PID_FILTER 0x11
57/* additional in buffer:
58 * 0 1 ... 14 15 16
59 * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */
60
61/* request: 0xB2; i: 0; v: 0;
62 * b[0] != 0 -> tune and lock a channel
63 * 0 1 2 3 4 5 6 7
64 * freq0 freq1 divstep srate0 srate1 srate2 flag chksum
65 */
66
67/* one direction requests */
68#define READ_REMOTE_REQ 0xB4
69/* IN i: 0; v: 0; b[0] == request, b[1] == key */
70
71#define READ_PID_NUMBER_REQ 0xB5
72/* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */
73
74#define WRITE_EEPROM_REQ 0xB6
75/* OUT i: offset; v: value to write; no extra buffer */
76
77#define READ_EEPROM_REQ 0xB7
78/* IN i: bufferlen; v: offset; buffer with bufferlen bytes */
79
80#define READ_STATUS 0xB8
81/* IN i: 0; v: 0; bufferlen 10 */
82
83#define READ_TUNER_REG_REQ 0xB9
84/* IN i: 0; v: register; b[0] = value */
85
86#define READ_FX2_REG_REQ 0xBA
87/* IN i: offset; v: 0; b[0] = value */
88
89#define WRITE_FX2_REG_REQ 0xBB
90/* OUT i: offset; v: value to write; 1 byte extra buffer */
91
92#define SET_TUNER_POWER_REQ 0xBC
93/* IN i: 0 = power off, 1 = power on */
94
95#define WRITE_TUNER_REG_REQ 0xBD
96/* IN i: register, v: value to write, no extra buffer */
97
98#define RESET_TUNER 0xBE
99/* IN i: 0, v: 0, no extra buffer */
100
101struct vp702x_device_state {
102 struct mutex buf_mutex;
103 int buf_len;
104 u8 *buf;
105};
106
107
108extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
109
110extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
111extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
112
113#endif
diff --git a/drivers/media/usb/dvb-usb/vp7045-fe.c b/drivers/media/usb/dvb-usb/vp7045-fe.c
new file mode 100644
index 000000000000..b8825b18c003
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/vp7045-fe.c
@@ -0,0 +1,190 @@
1/* DVB frontend part of the Linux driver for TwinhanDTV Alpha/MagicBoxII USB2.0
2 * DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to Twinhan who kindly provided hardware and information.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 *
14 */
15#include "vp7045.h"
16
17/* It is a Zarlink MT352 within a Samsung Tuner (DNOS404ZH102A) - 040929 - AAT
18 *
19 * Programming is hidden inside the firmware, so set_frontend is very easy.
20 * Even though there is a Firmware command that one can use to access the demod
21 * via its registers. This is used for status information.
22 */
23
24struct vp7045_fe_state {
25 struct dvb_frontend fe;
26 struct dvb_usb_device *d;
27};
28
29static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
30{
31 struct vp7045_fe_state *state = fe->demodulator_priv;
32 u8 s0 = vp7045_read_reg(state->d,0x00),
33 s1 = vp7045_read_reg(state->d,0x01),
34 s3 = vp7045_read_reg(state->d,0x03);
35
36 *status = 0;
37 if (s0 & (1 << 4))
38 *status |= FE_HAS_CARRIER;
39 if (s0 & (1 << 1))
40 *status |= FE_HAS_VITERBI;
41 if (s0 & (1 << 5))
42 *status |= FE_HAS_LOCK;
43 if (s1 & (1 << 1))
44 *status |= FE_HAS_SYNC;
45 if (s3 & (1 << 6))
46 *status |= FE_HAS_SIGNAL;
47
48 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
49 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
50 *status &= ~FE_HAS_LOCK;
51
52 return 0;
53}
54
55static int vp7045_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
56{
57 struct vp7045_fe_state *state = fe->demodulator_priv;
58 *ber = (vp7045_read_reg(state->d, 0x0D) << 16) |
59 (vp7045_read_reg(state->d, 0x0E) << 8) |
60 vp7045_read_reg(state->d, 0x0F);
61 return 0;
62}
63
64static int vp7045_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
65{
66 struct vp7045_fe_state *state = fe->demodulator_priv;
67 *unc = (vp7045_read_reg(state->d, 0x10) << 8) |
68 vp7045_read_reg(state->d, 0x11);
69 return 0;
70}
71
72static int vp7045_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
73{
74 struct vp7045_fe_state *state = fe->demodulator_priv;
75 u16 signal = (vp7045_read_reg(state->d, 0x14) << 8) |
76 vp7045_read_reg(state->d, 0x15);
77
78 *strength = ~signal;
79 return 0;
80}
81
82static int vp7045_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
83{
84 struct vp7045_fe_state *state = fe->demodulator_priv;
85 u8 _snr = vp7045_read_reg(state->d, 0x09);
86 *snr = (_snr << 8) | _snr;
87 return 0;
88}
89
90static int vp7045_fe_init(struct dvb_frontend* fe)
91{
92 return 0;
93}
94
95static int vp7045_fe_sleep(struct dvb_frontend* fe)
96{
97 return 0;
98}
99
100static int vp7045_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
101{
102 tune->min_delay_ms = 800;
103 return 0;
104}
105
106static int vp7045_fe_set_frontend(struct dvb_frontend *fe)
107{
108 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
109 struct vp7045_fe_state *state = fe->demodulator_priv;
110 u8 buf[5];
111 u32 freq = fep->frequency / 1000;
112
113 buf[0] = (freq >> 16) & 0xff;
114 buf[1] = (freq >> 8) & 0xff;
115 buf[2] = freq & 0xff;
116 buf[3] = 0;
117
118 switch (fep->bandwidth_hz) {
119 case 8000000:
120 buf[4] = 8;
121 break;
122 case 7000000:
123 buf[4] = 7;
124 break;
125 case 6000000:
126 buf[4] = 6;
127 break;
128 default:
129 return -EINVAL;
130 }
131
132 vp7045_usb_op(state->d,LOCK_TUNER_COMMAND,buf,5,NULL,0,200);
133 return 0;
134}
135
136static void vp7045_fe_release(struct dvb_frontend* fe)
137{
138 struct vp7045_fe_state *state = fe->demodulator_priv;
139 kfree(state);
140}
141
142static struct dvb_frontend_ops vp7045_fe_ops;
143
144struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
145{
146 struct vp7045_fe_state *s = kzalloc(sizeof(struct vp7045_fe_state), GFP_KERNEL);
147 if (s == NULL)
148 goto error;
149
150 s->d = d;
151 memcpy(&s->fe.ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops));
152 s->fe.demodulator_priv = s;
153
154 return &s->fe;
155error:
156 return NULL;
157}
158
159
160static struct dvb_frontend_ops vp7045_fe_ops = {
161 .delsys = { SYS_DVBT },
162 .info = {
163 .name = "Twinhan VP7045/46 USB DVB-T",
164 .frequency_min = 44250000,
165 .frequency_max = 867250000,
166 .frequency_stepsize = 1000,
167 .caps = FE_CAN_INVERSION_AUTO |
168 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
169 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
170 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
171 FE_CAN_TRANSMISSION_MODE_AUTO |
172 FE_CAN_GUARD_INTERVAL_AUTO |
173 FE_CAN_RECOVER |
174 FE_CAN_HIERARCHY_AUTO,
175 },
176
177 .release = vp7045_fe_release,
178
179 .init = vp7045_fe_init,
180 .sleep = vp7045_fe_sleep,
181
182 .set_frontend = vp7045_fe_set_frontend,
183 .get_tune_settings = vp7045_fe_get_tune_settings,
184
185 .read_status = vp7045_fe_read_status,
186 .read_ber = vp7045_fe_read_ber,
187 .read_signal_strength = vp7045_fe_read_signal_strength,
188 .read_snr = vp7045_fe_read_snr,
189 .read_ucblocks = vp7045_fe_read_unc_blocks,
190};
diff --git a/drivers/media/usb/dvb-usb/vp7045.c b/drivers/media/usb/dvb-usb/vp7045.c
new file mode 100644
index 000000000000..d750724132ee
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/vp7045.c
@@ -0,0 +1,302 @@
1/* DVB USB compliant Linux driver for the
2 * - TwinhanDTV Alpha/MagicBoxII USB2.0 DVB-T receiver
3 * - DigitalNow TinyUSB2 DVB-t receiver
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * Thanks to Twinhan who kindly provided hardware and information.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation, version 2.
12 *
13 * see Documentation/dvb/README.dvb-usb for more information
14 */
15#include "vp7045.h"
16
17/* debug */
18static int dvb_usb_vp7045_debug;
19module_param_named(debug,dvb_usb_vp7045_debug, int, 0644);
20MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
21
22DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
23
24#define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args)
25#define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args)
26#define deb_rc(args...) dprintk(dvb_usb_vp7045_debug,0x04,args)
27
28int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec)
29{
30 int ret = 0;
31 u8 *buf = d->priv;
32
33 buf[0] = cmd;
34
35 if (outlen > 19)
36 outlen = 19;
37
38 if (inlen > 11)
39 inlen = 11;
40
41 ret = mutex_lock_interruptible(&d->usb_mutex);
42 if (ret)
43 return ret;
44
45 if (out != NULL && outlen > 0)
46 memcpy(&buf[1], out, outlen);
47
48 deb_xfer("out buffer: ");
49 debug_dump(buf, outlen+1, deb_xfer);
50
51
52 if (usb_control_msg(d->udev,
53 usb_sndctrlpipe(d->udev,0),
54 TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0,
55 buf, 20, 2000) != 20) {
56 err("USB control message 'out' went wrong.");
57 ret = -EIO;
58 goto unlock;
59 }
60
61 msleep(msec);
62
63 if (usb_control_msg(d->udev,
64 usb_rcvctrlpipe(d->udev,0),
65 TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
66 buf, 12, 2000) != 12) {
67 err("USB control message 'in' went wrong.");
68 ret = -EIO;
69 goto unlock;
70 }
71
72 deb_xfer("in buffer: ");
73 debug_dump(buf, 12, deb_xfer);
74
75 if (in != NULL && inlen > 0)
76 memcpy(in, &buf[1], inlen);
77
78unlock:
79 mutex_unlock(&d->usb_mutex);
80
81 return ret;
82}
83
84u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg)
85{
86 u8 obuf[2] = { 0 },v;
87 obuf[1] = reg;
88
89 vp7045_usb_op(d,TUNER_REG_READ,obuf,2,&v,1,30);
90
91 return v;
92}
93
94static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff)
95{
96 u8 v = onoff;
97 return vp7045_usb_op(d,SET_TUNER_POWER,&v,1,NULL,0,150);
98}
99
100/* remote control stuff */
101
102/* The keymapping struct. Somehow this should be loaded to the driver, but
103 * currently it is hardcoded. */
104static struct rc_map_table rc_map_vp7045_table[] = {
105 { 0x0016, KEY_POWER },
106 { 0x0010, KEY_MUTE },
107 { 0x0003, KEY_1 },
108 { 0x0001, KEY_2 },
109 { 0x0006, KEY_3 },
110 { 0x0009, KEY_4 },
111 { 0x001d, KEY_5 },
112 { 0x001f, KEY_6 },
113 { 0x000d, KEY_7 },
114 { 0x0019, KEY_8 },
115 { 0x001b, KEY_9 },
116 { 0x0015, KEY_0 },
117 { 0x0005, KEY_CHANNELUP },
118 { 0x0002, KEY_CHANNELDOWN },
119 { 0x001e, KEY_VOLUMEUP },
120 { 0x000a, KEY_VOLUMEDOWN },
121 { 0x0011, KEY_RECORD },
122 { 0x0017, KEY_FAVORITES }, /* Heart symbol - Channel list. */
123 { 0x0014, KEY_PLAY },
124 { 0x001a, KEY_STOP },
125 { 0x0040, KEY_REWIND },
126 { 0x0012, KEY_FASTFORWARD },
127 { 0x000e, KEY_PREVIOUS }, /* Recall - Previous channel. */
128 { 0x004c, KEY_PAUSE },
129 { 0x004d, KEY_SCREEN }, /* Full screen mode. */
130 { 0x0054, KEY_AUDIO }, /* MTS - Switch to secondary audio. */
131 { 0x000c, KEY_CANCEL }, /* Cancel */
132 { 0x001c, KEY_EPG }, /* EPG */
133 { 0x0000, KEY_TAB }, /* Tab */
134 { 0x0048, KEY_INFO }, /* Preview */
135 { 0x0004, KEY_LIST }, /* RecordList */
136 { 0x000f, KEY_TEXT }, /* Teletext */
137 { 0x0041, KEY_PREVIOUSSONG },
138 { 0x0042, KEY_NEXTSONG },
139 { 0x004b, KEY_UP },
140 { 0x0051, KEY_DOWN },
141 { 0x004e, KEY_LEFT },
142 { 0x0052, KEY_RIGHT },
143 { 0x004f, KEY_ENTER },
144 { 0x0013, KEY_CANCEL },
145 { 0x004a, KEY_CLEAR },
146 { 0x0054, KEY_PRINT }, /* Capture */
147 { 0x0043, KEY_SUBTITLE }, /* Subtitle/CC */
148 { 0x0008, KEY_VIDEO }, /* A/V */
149 { 0x0007, KEY_SLEEP }, /* Hibernate */
150 { 0x0045, KEY_ZOOM }, /* Zoom+ */
151 { 0x0018, KEY_RED},
152 { 0x0053, KEY_GREEN},
153 { 0x005e, KEY_YELLOW},
154 { 0x005f, KEY_BLUE}
155};
156
157static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
158{
159 u8 key;
160 int i;
161 vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20);
162
163 deb_rc("remote query key: %x %d\n",key,key);
164
165 if (key == 0x44) {
166 *state = REMOTE_NO_KEY_PRESSED;
167 return 0;
168 }
169
170 for (i = 0; i < ARRAY_SIZE(rc_map_vp7045_table); i++)
171 if (rc5_data(&rc_map_vp7045_table[i]) == key) {
172 *state = REMOTE_KEY_PRESSED;
173 *event = rc_map_vp7045_table[i].keycode;
174 break;
175 }
176 return 0;
177}
178
179static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int offset)
180{
181 int i = 0;
182 u8 v,br[2];
183 for (i=0; i < len; i++) {
184 v = offset + i;
185 vp7045_usb_op(d,GET_EE_VALUE,&v,1,br,2,5);
186 buf[i] = br[1];
187 }
188 deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ",offset, i);
189 debug_dump(buf,i,deb_info);
190 return 0;
191}
192
193static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
194{
195 return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR);
196}
197
198static int vp7045_frontend_attach(struct dvb_usb_adapter *adap)
199{
200 u8 buf[255] = { 0 };
201
202 vp7045_usb_op(adap->dev,VENDOR_STRING_READ,NULL,0,buf,20,0);
203 buf[10] = '\0';
204 deb_info("firmware says: %s ",buf);
205
206 vp7045_usb_op(adap->dev,PRODUCT_STRING_READ,NULL,0,buf,20,0);
207 buf[10] = '\0';
208 deb_info("%s ",buf);
209
210 vp7045_usb_op(adap->dev,FW_VERSION_READ,NULL,0,buf,20,0);
211 buf[10] = '\0';
212 deb_info("v%s\n",buf);
213
214/* Dump the EEPROM */
215/* vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */
216
217 adap->fe_adap[0].fe = vp7045_fe_attach(adap->dev);
218
219 return 0;
220}
221
222static struct dvb_usb_device_properties vp7045_properties;
223
224static int vp7045_usb_probe(struct usb_interface *intf,
225 const struct usb_device_id *id)
226{
227 return dvb_usb_device_init(intf, &vp7045_properties,
228 THIS_MODULE, NULL, adapter_nr);
229}
230
231static struct usb_device_id vp7045_usb_table [] = {
232 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_COLD) },
233 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_WARM) },
234 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_COLD) },
235 { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_WARM) },
236 { 0 },
237};
238MODULE_DEVICE_TABLE(usb, vp7045_usb_table);
239
240static struct dvb_usb_device_properties vp7045_properties = {
241 .usb_ctrl = CYPRESS_FX2,
242 .firmware = "dvb-usb-vp7045-01.fw",
243 .size_of_priv = 20,
244
245 .num_adapters = 1,
246 .adapter = {
247 {
248 .num_frontends = 1,
249 .fe = {{
250 .frontend_attach = vp7045_frontend_attach,
251 /* parameter for the MPEG2-data transfer */
252 .stream = {
253 .type = USB_BULK,
254 .count = 7,
255 .endpoint = 0x02,
256 .u = {
257 .bulk = {
258 .buffersize = 4096,
259 }
260 }
261 },
262 }},
263 }
264 },
265 .power_ctrl = vp7045_power_ctrl,
266 .read_mac_address = vp7045_read_mac_addr,
267
268 .rc.legacy = {
269 .rc_interval = 400,
270 .rc_map_table = rc_map_vp7045_table,
271 .rc_map_size = ARRAY_SIZE(rc_map_vp7045_table),
272 .rc_query = vp7045_rc_query,
273 },
274
275 .num_device_descs = 2,
276 .devices = {
277 { .name = "Twinhan USB2.0 DVB-T receiver (TwinhanDTV Alpha/MagicBox II)",
278 .cold_ids = { &vp7045_usb_table[0], NULL },
279 .warm_ids = { &vp7045_usb_table[1], NULL },
280 },
281 { .name = "DigitalNow TinyUSB 2 DVB-t Receiver",
282 .cold_ids = { &vp7045_usb_table[2], NULL },
283 .warm_ids = { &vp7045_usb_table[3], NULL },
284 },
285 { NULL },
286 }
287};
288
289/* usb specific object needed to register this driver with the usb subsystem */
290static struct usb_driver vp7045_usb_driver = {
291 .name = "dvb_usb_vp7045",
292 .probe = vp7045_usb_probe,
293 .disconnect = dvb_usb_device_exit,
294 .id_table = vp7045_usb_table,
295};
296
297module_usb_driver(vp7045_usb_driver);
298
299MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
300MODULE_DESCRIPTION("Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0");
301MODULE_VERSION("1.0");
302MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/dvb-usb/vp7045.h b/drivers/media/usb/dvb-usb/vp7045.h
new file mode 100644
index 000000000000..cf5ec46f8bb1
--- /dev/null
+++ b/drivers/media/usb/dvb-usb/vp7045.h
@@ -0,0 +1,70 @@
1/* Common header-file of the Linux driver for the TwinhanDTV Alpha/MagicBoxII
2 * USB2.0 DVB-T receiver.
3 *
4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * Thanks to Twinhan who kindly provided hardware and information.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation, version 2.
11 *
12 * see Documentation/dvb/README.dvb-usb for more information
13 */
14#ifndef _DVB_USB_VP7045_H_
15#define _DVB_USB_VP7045_H_
16
17#define DVB_USB_LOG_PREFIX "vp7045"
18#include "dvb-usb.h"
19
20/* vp7045 commands */
21
22/* Twinhan Vendor requests */
23#define TH_COMMAND_IN 0xC0
24#define TH_COMMAND_OUT 0xC1
25
26/* command bytes */
27#define TUNER_REG_READ 0x03
28#define TUNER_REG_WRITE 0x04
29
30#define RC_VAL_READ 0x05
31 #define RC_NO_KEY 0x44
32
33#define SET_TUNER_POWER 0x06
34#define CHECK_TUNER_POWER 0x12
35 #define Tuner_Power_ON 1
36 #define Tuner_Power_OFF 0
37
38#define GET_USB_SPEED 0x07
39
40#define LOCK_TUNER_COMMAND 0x09
41
42#define TUNER_SIGNAL_READ 0x0A
43
44/* FX2 eeprom */
45#define SET_EE_VALUE 0x10
46#define GET_EE_VALUE 0x11
47 #define FX2_ID_ADDR 0x00
48 #define VID_MSB_ADDR 0x02
49 #define VID_LSB_ADDR 0x01
50 #define PID_MSB_ADDR 0x04
51 #define PID_LSB_ADDR 0x03
52 #define MAC_0_ADDR 0x07
53 #define MAC_1_ADDR 0x08
54 #define MAC_2_ADDR 0x09
55 #define MAC_3_ADDR 0x0a
56 #define MAC_4_ADDR 0x0b
57 #define MAC_5_ADDR 0x0c
58
59#define RESET_FX2 0x13
60
61#define FW_VERSION_READ 0x0B
62#define VENDOR_STRING_READ 0x0C
63#define PRODUCT_STRING_READ 0x0D
64#define FW_BCD_VERSION_READ 0x14
65
66extern struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d);
67extern int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen,int msec);
68extern u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg);
69
70#endif
diff --git a/drivers/media/usb/siano/Kconfig b/drivers/media/usb/siano/Kconfig
new file mode 100644
index 000000000000..bc6456eb2c4f
--- /dev/null
+++ b/drivers/media/usb/siano/Kconfig
@@ -0,0 +1,34 @@
1#
2# Siano Mobile Silicon Digital TV device configuration
3#
4
5config SMS_SIANO_MDTV
6 tristate "Siano SMS1xxx based MDTV receiver"
7 depends on DVB_CORE && RC_CORE && HAS_DMA
8 ---help---
9 Choose Y or M here if you have MDTV receiver with a Siano chipset.
10
11 To compile this driver as a module, choose M here
12 (The module will be called smsmdtv).
13
14 Further documentation on this driver can be found on the WWW
15 at http://www.siano-ms.com/
16
17if SMS_SIANO_MDTV
18menu "Siano module components"
19
20# Hardware interfaces support
21
22config SMS_USB_DRV
23 tristate "USB interface support"
24 depends on DVB_CORE && USB
25 ---help---
26 Choose if you would like to have Siano's support for USB interface
27
28config SMS_SDIO_DRV
29 tristate "SDIO interface support"
30 depends on DVB_CORE && MMC
31 ---help---
32 Choose if you would like to have Siano's support for SDIO interface
33endmenu
34endif # SMS_SIANO_MDTV
diff --git a/drivers/media/usb/siano/Makefile b/drivers/media/usb/siano/Makefile
new file mode 100644
index 000000000000..14756bdb6eaa
--- /dev/null
+++ b/drivers/media/usb/siano/Makefile
@@ -0,0 +1,11 @@
1
2smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
3
4obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
5obj-$(CONFIG_SMS_USB_DRV) += smsusb.o
6obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o
7
8ccflags-y += -Idrivers/media/dvb-core
9
10ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
11
diff --git a/drivers/media/usb/siano/sms-cards.c b/drivers/media/usb/siano/sms-cards.c
new file mode 100644
index 000000000000..680c781c8dd6
--- /dev/null
+++ b/drivers/media/usb/siano/sms-cards.c
@@ -0,0 +1,311 @@
1/*
2 * Card-specific functions for the Siano SMS1xxx USB dongle
3 *
4 * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * Software distributed under the License is distributed on an "AS IS"
11 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
12 *
13 * See the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include "sms-cards.h"
21#include "smsir.h"
22#include <linux/module.h>
23
24static int sms_dbg;
25module_param_named(cards_dbg, sms_dbg, int, 0644);
26MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
27
28static struct sms_board sms_boards[] = {
29 [SMS_BOARD_UNKNOWN] = {
30 .name = "Unknown board",
31 },
32 [SMS1XXX_BOARD_SIANO_STELLAR] = {
33 .name = "Siano Stellar Digital Receiver",
34 .type = SMS_STELLAR,
35 },
36 [SMS1XXX_BOARD_SIANO_NOVA_A] = {
37 .name = "Siano Nova A Digital Receiver",
38 .type = SMS_NOVA_A0,
39 },
40 [SMS1XXX_BOARD_SIANO_NOVA_B] = {
41 .name = "Siano Nova B Digital Receiver",
42 .type = SMS_NOVA_B0,
43 },
44 [SMS1XXX_BOARD_SIANO_VEGA] = {
45 .name = "Siano Vega Digital Receiver",
46 .type = SMS_VEGA,
47 },
48 [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = {
49 .name = "Hauppauge Catamount",
50 .type = SMS_STELLAR,
51 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
52 },
53 [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = {
54 .name = "Hauppauge Okemo-A",
55 .type = SMS_NOVA_A0,
56 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
57 },
58 [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = {
59 .name = "Hauppauge Okemo-B",
60 .type = SMS_NOVA_B0,
61 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
62 },
63 [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
64 .name = "Hauppauge WinTV MiniStick",
65 .type = SMS_NOVA_B0,
66 .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
67 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
68 .rc_codes = RC_MAP_HAUPPAUGE,
69 .board_cfg.leds_power = 26,
70 .board_cfg.led0 = 27,
71 .board_cfg.led1 = 28,
72 .board_cfg.ir = 9,
73 .led_power = 26,
74 .led_lo = 27,
75 .led_hi = 28,
76 },
77 [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = {
78 .name = "Hauppauge WinTV MiniCard",
79 .type = SMS_NOVA_B0,
80 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
81 .lna_ctrl = 29,
82 .board_cfg.foreign_lna0_ctrl = 29,
83 .rf_switch = 17,
84 .board_cfg.rf_switch_uhf = 17,
85 },
86 [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
87 .name = "Hauppauge WinTV MiniCard",
88 .type = SMS_NOVA_B0,
89 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
90 .lna_ctrl = -1,
91 },
92 [SMS1XXX_BOARD_SIANO_NICE] = {
93 /* 11 */
94 .name = "Siano Nice Digital Receiver",
95 .type = SMS_NOVA_B0,
96 },
97 [SMS1XXX_BOARD_SIANO_VENICE] = {
98 /* 12 */
99 .name = "Siano Venice Digital Receiver",
100 .type = SMS_VEGA,
101 },
102};
103
104struct sms_board *sms_get_board(unsigned id)
105{
106 BUG_ON(id >= ARRAY_SIZE(sms_boards));
107
108 return &sms_boards[id];
109}
110EXPORT_SYMBOL_GPL(sms_get_board);
111static inline void sms_gpio_assign_11xx_default_led_config(
112 struct smscore_gpio_config *pGpioConfig) {
113 pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT;
114 pGpioConfig->InputCharacteristics =
115 SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL;
116 pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA;
117 pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;
118 pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE;
119}
120
121int sms_board_event(struct smscore_device_t *coredev,
122 enum SMS_BOARD_EVENTS gevent) {
123 struct smscore_gpio_config MyGpioConfig;
124
125 sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);
126
127 switch (gevent) {
128 case BOARD_EVENT_POWER_INIT: /* including hotplug */
129 break; /* BOARD_EVENT_BIND */
130
131 case BOARD_EVENT_POWER_SUSPEND:
132 break; /* BOARD_EVENT_POWER_SUSPEND */
133
134 case BOARD_EVENT_POWER_RESUME:
135 break; /* BOARD_EVENT_POWER_RESUME */
136
137 case BOARD_EVENT_BIND:
138 break; /* BOARD_EVENT_BIND */
139
140 case BOARD_EVENT_SCAN_PROG:
141 break; /* BOARD_EVENT_SCAN_PROG */
142 case BOARD_EVENT_SCAN_COMP:
143 break; /* BOARD_EVENT_SCAN_COMP */
144 case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL:
145 break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */
146 case BOARD_EVENT_FE_LOCK:
147 break; /* BOARD_EVENT_FE_LOCK */
148 case BOARD_EVENT_FE_UNLOCK:
149 break; /* BOARD_EVENT_FE_UNLOCK */
150 case BOARD_EVENT_DEMOD_LOCK:
151 break; /* BOARD_EVENT_DEMOD_LOCK */
152 case BOARD_EVENT_DEMOD_UNLOCK:
153 break; /* BOARD_EVENT_DEMOD_UNLOCK */
154 case BOARD_EVENT_RECEPTION_MAX_4:
155 break; /* BOARD_EVENT_RECEPTION_MAX_4 */
156 case BOARD_EVENT_RECEPTION_3:
157 break; /* BOARD_EVENT_RECEPTION_3 */
158 case BOARD_EVENT_RECEPTION_2:
159 break; /* BOARD_EVENT_RECEPTION_2 */
160 case BOARD_EVENT_RECEPTION_1:
161 break; /* BOARD_EVENT_RECEPTION_1 */
162 case BOARD_EVENT_RECEPTION_LOST_0:
163 break; /* BOARD_EVENT_RECEPTION_LOST_0 */
164 case BOARD_EVENT_MULTIPLEX_OK:
165 break; /* BOARD_EVENT_MULTIPLEX_OK */
166 case BOARD_EVENT_MULTIPLEX_ERRORS:
167 break; /* BOARD_EVENT_MULTIPLEX_ERRORS */
168
169 default:
170 sms_err("Unknown SMS board event");
171 break;
172 }
173 return 0;
174}
175EXPORT_SYMBOL_GPL(sms_board_event);
176
177static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
178{
179 int lvl, ret;
180 u32 gpio;
181 struct smscore_config_gpio gpioconfig = {
182 .direction = SMS_GPIO_DIRECTION_OUTPUT,
183 .pullupdown = SMS_GPIO_PULLUPDOWN_NONE,
184 .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,
185 .outputslewrate = SMS_GPIO_OUTPUTSLEWRATE_FAST,
186 .outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA,
187 };
188
189 if (pin == 0)
190 return -EINVAL;
191
192 if (pin < 0) {
193 /* inverted gpio */
194 gpio = pin * -1;
195 lvl = enable ? 0 : 1;
196 } else {
197 gpio = pin;
198 lvl = enable ? 1 : 0;
199 }
200
201 ret = smscore_configure_gpio(coredev, gpio, &gpioconfig);
202 if (ret < 0)
203 return ret;
204
205 return smscore_set_gpio(coredev, gpio, lvl);
206}
207
208int sms_board_setup(struct smscore_device_t *coredev)
209{
210 int board_id = smscore_get_board_id(coredev);
211 struct sms_board *board = sms_get_board(board_id);
212
213 switch (board_id) {
214 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
215 /* turn off all LEDs */
216 sms_set_gpio(coredev, board->led_power, 0);
217 sms_set_gpio(coredev, board->led_hi, 0);
218 sms_set_gpio(coredev, board->led_lo, 0);
219 break;
220 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
221 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
222 /* turn off LNA */
223 sms_set_gpio(coredev, board->lna_ctrl, 0);
224 break;
225 }
226 return 0;
227}
228EXPORT_SYMBOL_GPL(sms_board_setup);
229
230int sms_board_power(struct smscore_device_t *coredev, int onoff)
231{
232 int board_id = smscore_get_board_id(coredev);
233 struct sms_board *board = sms_get_board(board_id);
234
235 switch (board_id) {
236 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
237 /* power LED */
238 sms_set_gpio(coredev,
239 board->led_power, onoff ? 1 : 0);
240 break;
241 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
242 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
243 /* LNA */
244 if (!onoff)
245 sms_set_gpio(coredev, board->lna_ctrl, 0);
246 break;
247 }
248 return 0;
249}
250EXPORT_SYMBOL_GPL(sms_board_power);
251
252int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
253{
254 int board_id = smscore_get_board_id(coredev);
255 struct sms_board *board = sms_get_board(board_id);
256
257 /* dont touch GPIO if LEDs are already set */
258 if (smscore_led_state(coredev, -1) == led)
259 return 0;
260
261 switch (board_id) {
262 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
263 sms_set_gpio(coredev,
264 board->led_lo, (led & SMS_LED_LO) ? 1 : 0);
265 sms_set_gpio(coredev,
266 board->led_hi, (led & SMS_LED_HI) ? 1 : 0);
267
268 smscore_led_state(coredev, led);
269 break;
270 }
271 return 0;
272}
273EXPORT_SYMBOL_GPL(sms_board_led_feedback);
274
275int sms_board_lna_control(struct smscore_device_t *coredev, int onoff)
276{
277 int board_id = smscore_get_board_id(coredev);
278 struct sms_board *board = sms_get_board(board_id);
279
280 sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled");
281
282 switch (board_id) {
283 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
284 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
285 sms_set_gpio(coredev,
286 board->rf_switch, onoff ? 1 : 0);
287 return sms_set_gpio(coredev,
288 board->lna_ctrl, onoff ? 1 : 0);
289 }
290 return -EINVAL;
291}
292EXPORT_SYMBOL_GPL(sms_board_lna_control);
293
294int sms_board_load_modules(int id)
295{
296 switch (id) {
297 case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT:
298 case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
299 case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
300 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
301 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
302 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
303 request_module("smsdvb");
304 break;
305 default:
306 /* do nothing */
307 break;
308 }
309 return 0;
310}
311EXPORT_SYMBOL_GPL(sms_board_load_modules);
diff --git a/drivers/media/usb/siano/sms-cards.h b/drivers/media/usb/siano/sms-cards.h
new file mode 100644
index 000000000000..d8cdf756f7cf
--- /dev/null
+++ b/drivers/media/usb/siano/sms-cards.h
@@ -0,0 +1,123 @@
1/*
2 * Card-specific functions for the Siano SMS1xxx USB dongle
3 *
4 * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * Software distributed under the License is distributed on an "AS IS"
11 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
12 *
13 * See the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#ifndef __SMS_CARDS_H__
21#define __SMS_CARDS_H__
22
23#include <linux/usb.h>
24#include "smscoreapi.h"
25#include "smsir.h"
26
27#define SMS_BOARD_UNKNOWN 0
28#define SMS1XXX_BOARD_SIANO_STELLAR 1
29#define SMS1XXX_BOARD_SIANO_NOVA_A 2
30#define SMS1XXX_BOARD_SIANO_NOVA_B 3
31#define SMS1XXX_BOARD_SIANO_VEGA 4
32#define SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT 5
33#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A 6
34#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B 7
35#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8
36#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9
37#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10
38#define SMS1XXX_BOARD_SIANO_NICE 11
39#define SMS1XXX_BOARD_SIANO_VENICE 12
40
41struct sms_board_gpio_cfg {
42 int lna_vhf_exist;
43 int lna_vhf_ctrl;
44 int lna_uhf_exist;
45 int lna_uhf_ctrl;
46 int lna_uhf_d_ctrl;
47 int lna_sband_exist;
48 int lna_sband_ctrl;
49 int lna_sband_d_ctrl;
50 int foreign_lna0_ctrl;
51 int foreign_lna1_ctrl;
52 int foreign_lna2_ctrl;
53 int rf_switch_vhf;
54 int rf_switch_uhf;
55 int rf_switch_sband;
56 int leds_power;
57 int led0;
58 int led1;
59 int led2;
60 int led3;
61 int led4;
62 int ir;
63 int eeprom_wp;
64 int mrc_sense;
65 int mrc_pdn_resetn;
66 int mrc_gp0; /* mrcs spi int */
67 int mrc_gp1;
68 int mrc_gp2;
69 int mrc_gp3;
70 int mrc_gp4;
71 int host_spi_gsp_ts_int;
72};
73
74struct sms_board {
75 enum sms_device_type_st type;
76 char *name, *fw[DEVICE_MODE_MAX];
77 struct sms_board_gpio_cfg board_cfg;
78 char *rc_codes; /* Name of IR codes table */
79
80 /* gpios */
81 int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
82};
83
84struct sms_board *sms_get_board(unsigned id);
85
86extern struct smscore_device_t *coredev;
87
88enum SMS_BOARD_EVENTS {
89 BOARD_EVENT_POWER_INIT,
90 BOARD_EVENT_POWER_SUSPEND,
91 BOARD_EVENT_POWER_RESUME,
92 BOARD_EVENT_BIND,
93 BOARD_EVENT_SCAN_PROG,
94 BOARD_EVENT_SCAN_COMP,
95 BOARD_EVENT_EMERGENCY_WARNING_SIGNAL,
96 BOARD_EVENT_FE_LOCK,
97 BOARD_EVENT_FE_UNLOCK,
98 BOARD_EVENT_DEMOD_LOCK,
99 BOARD_EVENT_DEMOD_UNLOCK,
100 BOARD_EVENT_RECEPTION_MAX_4,
101 BOARD_EVENT_RECEPTION_3,
102 BOARD_EVENT_RECEPTION_2,
103 BOARD_EVENT_RECEPTION_1,
104 BOARD_EVENT_RECEPTION_LOST_0,
105 BOARD_EVENT_MULTIPLEX_OK,
106 BOARD_EVENT_MULTIPLEX_ERRORS
107};
108
109int sms_board_event(struct smscore_device_t *coredev,
110 enum SMS_BOARD_EVENTS gevent);
111
112int sms_board_setup(struct smscore_device_t *coredev);
113
114#define SMS_LED_OFF 0
115#define SMS_LED_LO 1
116#define SMS_LED_HI 2
117int sms_board_led_feedback(struct smscore_device_t *coredev, int led);
118int sms_board_power(struct smscore_device_t *coredev, int onoff);
119int sms_board_lna_control(struct smscore_device_t *coredev, int onoff);
120
121extern int sms_board_load_modules(int id);
122
123#endif /* __SMS_CARDS_H__ */
diff --git a/drivers/media/usb/siano/smscoreapi.c b/drivers/media/usb/siano/smscoreapi.c
new file mode 100644
index 000000000000..9cc55546cc30
--- /dev/null
+++ b/drivers/media/usb/siano/smscoreapi.c
@@ -0,0 +1,1637 @@
1/*
2 * Siano core API module
3 *
4 * This file contains implementation for the interface to sms core component
5 *
6 * author: Uri Shkolnik
7 *
8 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
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 version 2 as
12 * published by the Free Software Foundation;
13 *
14 * Software distributed under the License is distributed on an "AS IS"
15 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
16 *
17 * See the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/kernel.h>
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/dma-mapping.h>
29#include <linux/delay.h>
30#include <linux/io.h>
31#include <linux/slab.h>
32
33#include <linux/firmware.h>
34#include <linux/wait.h>
35#include <asm/byteorder.h>
36
37#include "smscoreapi.h"
38#include "sms-cards.h"
39#include "smsir.h"
40#include "smsendian.h"
41
42static int sms_dbg;
43module_param_named(debug, sms_dbg, int, 0644);
44MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
45
46struct smscore_device_notifyee_t {
47 struct list_head entry;
48 hotplug_t hotplug;
49};
50
51struct smscore_idlist_t {
52 struct list_head entry;
53 int id;
54 int data_type;
55};
56
57struct smscore_client_t {
58 struct list_head entry;
59 struct smscore_device_t *coredev;
60 void *context;
61 struct list_head idlist;
62 onresponse_t onresponse_handler;
63 onremove_t onremove_handler;
64};
65
66void smscore_set_board_id(struct smscore_device_t *core, int id)
67{
68 core->board_id = id;
69}
70
71int smscore_led_state(struct smscore_device_t *core, int led)
72{
73 if (led >= 0)
74 core->led_state = led;
75 return core->led_state;
76}
77EXPORT_SYMBOL_GPL(smscore_set_board_id);
78
79int smscore_get_board_id(struct smscore_device_t *core)
80{
81 return core->board_id;
82}
83EXPORT_SYMBOL_GPL(smscore_get_board_id);
84
85struct smscore_registry_entry_t {
86 struct list_head entry;
87 char devpath[32];
88 int mode;
89 enum sms_device_type_st type;
90};
91
92static struct list_head g_smscore_notifyees;
93static struct list_head g_smscore_devices;
94static struct mutex g_smscore_deviceslock;
95
96static struct list_head g_smscore_registry;
97static struct mutex g_smscore_registrylock;
98
99static int default_mode = 4;
100
101module_param(default_mode, int, 0644);
102MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
103
104static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
105{
106 struct smscore_registry_entry_t *entry;
107 struct list_head *next;
108
109 kmutex_lock(&g_smscore_registrylock);
110 for (next = g_smscore_registry.next;
111 next != &g_smscore_registry;
112 next = next->next) {
113 entry = (struct smscore_registry_entry_t *) next;
114 if (!strcmp(entry->devpath, devpath)) {
115 kmutex_unlock(&g_smscore_registrylock);
116 return entry;
117 }
118 }
119 entry = kmalloc(sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
120 if (entry) {
121 entry->mode = default_mode;
122 strcpy(entry->devpath, devpath);
123 list_add(&entry->entry, &g_smscore_registry);
124 } else
125 sms_err("failed to create smscore_registry.");
126 kmutex_unlock(&g_smscore_registrylock);
127 return entry;
128}
129
130int smscore_registry_getmode(char *devpath)
131{
132 struct smscore_registry_entry_t *entry;
133
134 entry = smscore_find_registry(devpath);
135 if (entry)
136 return entry->mode;
137 else
138 sms_err("No registry found.");
139
140 return default_mode;
141}
142EXPORT_SYMBOL_GPL(smscore_registry_getmode);
143
144static enum sms_device_type_st smscore_registry_gettype(char *devpath)
145{
146 struct smscore_registry_entry_t *entry;
147
148 entry = smscore_find_registry(devpath);
149 if (entry)
150 return entry->type;
151 else
152 sms_err("No registry found.");
153
154 return -1;
155}
156
157void smscore_registry_setmode(char *devpath, int mode)
158{
159 struct smscore_registry_entry_t *entry;
160
161 entry = smscore_find_registry(devpath);
162 if (entry)
163 entry->mode = mode;
164 else
165 sms_err("No registry found.");
166}
167
168static void smscore_registry_settype(char *devpath,
169 enum sms_device_type_st type)
170{
171 struct smscore_registry_entry_t *entry;
172
173 entry = smscore_find_registry(devpath);
174 if (entry)
175 entry->type = type;
176 else
177 sms_err("No registry found.");
178}
179
180
181static void list_add_locked(struct list_head *new, struct list_head *head,
182 spinlock_t *lock)
183{
184 unsigned long flags;
185
186 spin_lock_irqsave(lock, flags);
187
188 list_add(new, head);
189
190 spin_unlock_irqrestore(lock, flags);
191}
192
193/**
194 * register a client callback that called when device plugged in/unplugged
195 * NOTE: if devices exist callback is called immediately for each device
196 *
197 * @param hotplug callback
198 *
199 * @return 0 on success, <0 on error.
200 */
201int smscore_register_hotplug(hotplug_t hotplug)
202{
203 struct smscore_device_notifyee_t *notifyee;
204 struct list_head *next, *first;
205 int rc = 0;
206
207 kmutex_lock(&g_smscore_deviceslock);
208
209 notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
210 GFP_KERNEL);
211 if (notifyee) {
212 /* now notify callback about existing devices */
213 first = &g_smscore_devices;
214 for (next = first->next;
215 next != first && !rc;
216 next = next->next) {
217 struct smscore_device_t *coredev =
218 (struct smscore_device_t *) next;
219 rc = hotplug(coredev, coredev->device, 1);
220 }
221
222 if (rc >= 0) {
223 notifyee->hotplug = hotplug;
224 list_add(&notifyee->entry, &g_smscore_notifyees);
225 } else
226 kfree(notifyee);
227 } else
228 rc = -ENOMEM;
229
230 kmutex_unlock(&g_smscore_deviceslock);
231
232 return rc;
233}
234EXPORT_SYMBOL_GPL(smscore_register_hotplug);
235
236/**
237 * unregister a client callback that called when device plugged in/unplugged
238 *
239 * @param hotplug callback
240 *
241 */
242void smscore_unregister_hotplug(hotplug_t hotplug)
243{
244 struct list_head *next, *first;
245
246 kmutex_lock(&g_smscore_deviceslock);
247
248 first = &g_smscore_notifyees;
249
250 for (next = first->next; next != first;) {
251 struct smscore_device_notifyee_t *notifyee =
252 (struct smscore_device_notifyee_t *) next;
253 next = next->next;
254
255 if (notifyee->hotplug == hotplug) {
256 list_del(&notifyee->entry);
257 kfree(notifyee);
258 }
259 }
260
261 kmutex_unlock(&g_smscore_deviceslock);
262}
263EXPORT_SYMBOL_GPL(smscore_unregister_hotplug);
264
265static void smscore_notify_clients(struct smscore_device_t *coredev)
266{
267 struct smscore_client_t *client;
268
269 /* the client must call smscore_unregister_client from remove handler */
270 while (!list_empty(&coredev->clients)) {
271 client = (struct smscore_client_t *) coredev->clients.next;
272 client->onremove_handler(client->context);
273 }
274}
275
276static int smscore_notify_callbacks(struct smscore_device_t *coredev,
277 struct device *device, int arrival)
278{
279 struct smscore_device_notifyee_t *elem;
280 int rc = 0;
281
282 /* note: must be called under g_deviceslock */
283
284 list_for_each_entry(elem, &g_smscore_notifyees, entry) {
285 rc = elem->hotplug(coredev, device, arrival);
286 if (rc < 0)
287 break;
288 }
289
290 return rc;
291}
292
293static struct
294smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
295 dma_addr_t common_buffer_phys)
296{
297 struct smscore_buffer_t *cb =
298 kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
299 if (!cb) {
300 sms_info("kmalloc(...) failed");
301 return NULL;
302 }
303
304 cb->p = buffer;
305 cb->offset_in_common = buffer - (u8 *) common_buffer;
306 cb->phys = common_buffer_phys + cb->offset_in_common;
307
308 return cb;
309}
310
311/**
312 * creates coredev object for a device, prepares buffers,
313 * creates buffer mappings, notifies registered hotplugs about new device.
314 *
315 * @param params device pointer to struct with device specific parameters
316 * and handlers
317 * @param coredev pointer to a value that receives created coredev object
318 *
319 * @return 0 on success, <0 on error.
320 */
321int smscore_register_device(struct smsdevice_params_t *params,
322 struct smscore_device_t **coredev)
323{
324 struct smscore_device_t *dev;
325 u8 *buffer;
326
327 dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
328 if (!dev) {
329 sms_info("kzalloc(...) failed");
330 return -ENOMEM;
331 }
332
333 /* init list entry so it could be safe in smscore_unregister_device */
334 INIT_LIST_HEAD(&dev->entry);
335
336 /* init queues */
337 INIT_LIST_HEAD(&dev->clients);
338 INIT_LIST_HEAD(&dev->buffers);
339
340 /* init locks */
341 spin_lock_init(&dev->clientslock);
342 spin_lock_init(&dev->bufferslock);
343
344 /* init completion events */
345 init_completion(&dev->version_ex_done);
346 init_completion(&dev->data_download_done);
347 init_completion(&dev->trigger_done);
348 init_completion(&dev->init_device_done);
349 init_completion(&dev->reload_start_done);
350 init_completion(&dev->resume_done);
351 init_completion(&dev->gpio_configuration_done);
352 init_completion(&dev->gpio_set_level_done);
353 init_completion(&dev->gpio_get_level_done);
354 init_completion(&dev->ir_init_done);
355
356 /* Buffer management */
357 init_waitqueue_head(&dev->buffer_mng_waitq);
358
359 /* alloc common buffer */
360 dev->common_buffer_size = params->buffer_size * params->num_buffers;
361 dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size,
362 &dev->common_buffer_phys,
363 GFP_KERNEL | GFP_DMA);
364 if (!dev->common_buffer) {
365 smscore_unregister_device(dev);
366 return -ENOMEM;
367 }
368
369 /* prepare dma buffers */
370 for (buffer = dev->common_buffer;
371 dev->num_buffers < params->num_buffers;
372 dev->num_buffers++, buffer += params->buffer_size) {
373 struct smscore_buffer_t *cb =
374 smscore_createbuffer(buffer, dev->common_buffer,
375 dev->common_buffer_phys);
376 if (!cb) {
377 smscore_unregister_device(dev);
378 return -ENOMEM;
379 }
380
381 smscore_putbuffer(dev, cb);
382 }
383
384 sms_info("allocated %d buffers", dev->num_buffers);
385
386 dev->mode = DEVICE_MODE_NONE;
387 dev->context = params->context;
388 dev->device = params->device;
389 dev->setmode_handler = params->setmode_handler;
390 dev->detectmode_handler = params->detectmode_handler;
391 dev->sendrequest_handler = params->sendrequest_handler;
392 dev->preload_handler = params->preload_handler;
393 dev->postload_handler = params->postload_handler;
394
395 dev->device_flags = params->flags;
396 strcpy(dev->devpath, params->devpath);
397
398 smscore_registry_settype(dev->devpath, params->device_type);
399
400 /* add device to devices list */
401 kmutex_lock(&g_smscore_deviceslock);
402 list_add(&dev->entry, &g_smscore_devices);
403 kmutex_unlock(&g_smscore_deviceslock);
404
405 *coredev = dev;
406
407 sms_info("device %p created", dev);
408
409 return 0;
410}
411EXPORT_SYMBOL_GPL(smscore_register_device);
412
413
414static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
415 void *buffer, size_t size, struct completion *completion) {
416 int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
417 if (rc < 0) {
418 sms_info("sendrequest returned error %d", rc);
419 return rc;
420 }
421
422 return wait_for_completion_timeout(completion,
423 msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ?
424 0 : -ETIME;
425}
426
427/**
428 * Starts & enables IR operations
429 *
430 * @return 0 on success, < 0 on error.
431 */
432static int smscore_init_ir(struct smscore_device_t *coredev)
433{
434 int ir_io;
435 int rc;
436 void *buffer;
437
438 coredev->ir.dev = NULL;
439 ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
440 if (ir_io) {/* only if IR port exist we use IR sub-module */
441 sms_info("IR loading");
442 rc = sms_ir_init(coredev);
443
444 if (rc != 0)
445 sms_err("Error initialization DTV IR sub-module");
446 else {
447 buffer = kmalloc(sizeof(struct SmsMsgData_ST2) +
448 SMS_DMA_ALIGNMENT,
449 GFP_KERNEL | GFP_DMA);
450 if (buffer) {
451 struct SmsMsgData_ST2 *msg =
452 (struct SmsMsgData_ST2 *)
453 SMS_ALIGN_ADDRESS(buffer);
454
455 SMS_INIT_MSG(&msg->xMsgHeader,
456 MSG_SMS_START_IR_REQ,
457 sizeof(struct SmsMsgData_ST2));
458 msg->msgData[0] = coredev->ir.controller;
459 msg->msgData[1] = coredev->ir.timeout;
460
461 smsendian_handle_tx_message(
462 (struct SmsMsgHdr_ST2 *)msg);
463 rc = smscore_sendrequest_and_wait(coredev, msg,
464 msg->xMsgHeader. msgLength,
465 &coredev->ir_init_done);
466
467 kfree(buffer);
468 } else
469 sms_err
470 ("Sending IR initialization message failed");
471 }
472 } else
473 sms_info("IR port has not been detected");
474
475 return 0;
476}
477
478/**
479 * sets initial device mode and notifies client hotplugs that device is ready
480 *
481 * @param coredev pointer to a coredev object returned by
482 * smscore_register_device
483 *
484 * @return 0 on success, <0 on error.
485 */
486int smscore_start_device(struct smscore_device_t *coredev)
487{
488 int rc = smscore_set_device_mode(
489 coredev, smscore_registry_getmode(coredev->devpath));
490 if (rc < 0) {
491 sms_info("set device mode faile , rc %d", rc);
492 return rc;
493 }
494
495 kmutex_lock(&g_smscore_deviceslock);
496
497 rc = smscore_notify_callbacks(coredev, coredev->device, 1);
498 smscore_init_ir(coredev);
499
500 sms_info("device %p started, rc %d", coredev, rc);
501
502 kmutex_unlock(&g_smscore_deviceslock);
503
504 return rc;
505}
506EXPORT_SYMBOL_GPL(smscore_start_device);
507
508
509static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
510 void *buffer, size_t size)
511{
512 struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
513 struct SmsMsgHdr_ST *msg;
514 u32 mem_address;
515 u8 *payload = firmware->Payload;
516 int rc = 0;
517 firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
518 firmware->Length = le32_to_cpu(firmware->Length);
519
520 mem_address = firmware->StartAddress;
521
522 sms_info("loading FW to addr 0x%x size %d",
523 mem_address, firmware->Length);
524 if (coredev->preload_handler) {
525 rc = coredev->preload_handler(coredev->context);
526 if (rc < 0)
527 return rc;
528 }
529
530 /* PAGE_SIZE buffer shall be enough and dma aligned */
531 msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
532 if (!msg)
533 return -ENOMEM;
534
535 if (coredev->mode != DEVICE_MODE_NONE) {
536 sms_debug("sending reload command.");
537 SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ,
538 sizeof(struct SmsMsgHdr_ST));
539 rc = smscore_sendrequest_and_wait(coredev, msg,
540 msg->msgLength,
541 &coredev->reload_start_done);
542 mem_address = *(u32 *) &payload[20];
543 }
544
545 while (size && rc >= 0) {
546 struct SmsDataDownload_ST *DataMsg =
547 (struct SmsDataDownload_ST *) msg;
548 int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
549
550 SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
551 (u16)(sizeof(struct SmsMsgHdr_ST) +
552 sizeof(u32) + payload_size));
553
554 DataMsg->MemAddr = mem_address;
555 memcpy(DataMsg->Payload, payload, payload_size);
556
557 if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
558 (coredev->mode == DEVICE_MODE_NONE))
559 rc = coredev->sendrequest_handler(
560 coredev->context, DataMsg,
561 DataMsg->xMsgHeader.msgLength);
562 else
563 rc = smscore_sendrequest_and_wait(
564 coredev, DataMsg,
565 DataMsg->xMsgHeader.msgLength,
566 &coredev->data_download_done);
567
568 payload += payload_size;
569 size -= payload_size;
570 mem_address += payload_size;
571 }
572
573 if (rc >= 0) {
574 if (coredev->mode == DEVICE_MODE_NONE) {
575 struct SmsMsgData_ST *TriggerMsg =
576 (struct SmsMsgData_ST *) msg;
577
578 SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
579 sizeof(struct SmsMsgHdr_ST) +
580 sizeof(u32) * 5);
581
582 TriggerMsg->msgData[0] = firmware->StartAddress;
583 /* Entry point */
584 TriggerMsg->msgData[1] = 5; /* Priority */
585 TriggerMsg->msgData[2] = 0x200; /* Stack size */
586 TriggerMsg->msgData[3] = 0; /* Parameter */
587 TriggerMsg->msgData[4] = 4; /* Task ID */
588
589 if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
590 rc = coredev->sendrequest_handler(
591 coredev->context, TriggerMsg,
592 TriggerMsg->xMsgHeader.msgLength);
593 msleep(100);
594 } else
595 rc = smscore_sendrequest_and_wait(
596 coredev, TriggerMsg,
597 TriggerMsg->xMsgHeader.msgLength,
598 &coredev->trigger_done);
599 } else {
600 SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
601 sizeof(struct SmsMsgHdr_ST));
602
603 rc = coredev->sendrequest_handler(coredev->context,
604 msg, msg->msgLength);
605 }
606 msleep(500);
607 }
608
609 sms_debug("rc=%d, postload=%p ", rc,
610 coredev->postload_handler);
611
612 kfree(msg);
613
614 return ((rc >= 0) && coredev->postload_handler) ?
615 coredev->postload_handler(coredev->context) :
616 rc;
617}
618
619/**
620 * loads specified firmware into a buffer and calls device loadfirmware_handler
621 *
622 * @param coredev pointer to a coredev object returned by
623 * smscore_register_device
624 * @param filename null-terminated string specifies firmware file name
625 * @param loadfirmware_handler device handler that loads firmware
626 *
627 * @return 0 on success, <0 on error.
628 */
629static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
630 char *filename,
631 loadfirmware_t loadfirmware_handler)
632{
633 int rc = -ENOENT;
634 const struct firmware *fw;
635 u8 *fw_buffer;
636
637 if (loadfirmware_handler == NULL && !(coredev->device_flags &
638 SMS_DEVICE_FAMILY2))
639 return -EINVAL;
640
641 rc = request_firmware(&fw, filename, coredev->device);
642 if (rc < 0) {
643 sms_info("failed to open \"%s\"", filename);
644 return rc;
645 }
646 sms_info("read FW %s, size=%zd", filename, fw->size);
647 fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
648 GFP_KERNEL | GFP_DMA);
649 if (fw_buffer) {
650 memcpy(fw_buffer, fw->data, fw->size);
651
652 rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
653 smscore_load_firmware_family2(coredev,
654 fw_buffer,
655 fw->size) :
656 loadfirmware_handler(coredev->context,
657 fw_buffer, fw->size);
658
659 kfree(fw_buffer);
660 } else {
661 sms_info("failed to allocate firmware buffer");
662 rc = -ENOMEM;
663 }
664
665 release_firmware(fw);
666
667 return rc;
668}
669
670/**
671 * notifies all clients registered with the device, notifies hotplugs,
672 * frees all buffers and coredev object
673 *
674 * @param coredev pointer to a coredev object returned by
675 * smscore_register_device
676 *
677 * @return 0 on success, <0 on error.
678 */
679void smscore_unregister_device(struct smscore_device_t *coredev)
680{
681 struct smscore_buffer_t *cb;
682 int num_buffers = 0;
683 int retry = 0;
684
685 kmutex_lock(&g_smscore_deviceslock);
686
687 /* Release input device (IR) resources */
688 sms_ir_exit(coredev);
689
690 smscore_notify_clients(coredev);
691 smscore_notify_callbacks(coredev, NULL, 0);
692
693 /* at this point all buffers should be back
694 * onresponse must no longer be called */
695
696 while (1) {
697 while (!list_empty(&coredev->buffers)) {
698 cb = (struct smscore_buffer_t *) coredev->buffers.next;
699 list_del(&cb->entry);
700 kfree(cb);
701 num_buffers++;
702 }
703 if (num_buffers == coredev->num_buffers)
704 break;
705 if (++retry > 10) {
706 sms_info("exiting although "
707 "not all buffers released.");
708 break;
709 }
710
711 sms_info("waiting for %d buffer(s)",
712 coredev->num_buffers - num_buffers);
713 msleep(100);
714 }
715
716 sms_info("freed %d buffers", num_buffers);
717
718 if (coredev->common_buffer)
719 dma_free_coherent(NULL, coredev->common_buffer_size,
720 coredev->common_buffer, coredev->common_buffer_phys);
721
722 if (coredev->fw_buf != NULL)
723 kfree(coredev->fw_buf);
724
725 list_del(&coredev->entry);
726 kfree(coredev);
727
728 kmutex_unlock(&g_smscore_deviceslock);
729
730 sms_info("device %p destroyed", coredev);
731}
732EXPORT_SYMBOL_GPL(smscore_unregister_device);
733
734static int smscore_detect_mode(struct smscore_device_t *coredev)
735{
736 void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
737 GFP_KERNEL | GFP_DMA);
738 struct SmsMsgHdr_ST *msg =
739 (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
740 int rc;
741
742 if (!buffer)
743 return -ENOMEM;
744
745 SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
746 sizeof(struct SmsMsgHdr_ST));
747
748 rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
749 &coredev->version_ex_done);
750 if (rc == -ETIME) {
751 sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
752
753 if (wait_for_completion_timeout(&coredev->resume_done,
754 msecs_to_jiffies(5000))) {
755 rc = smscore_sendrequest_and_wait(
756 coredev, msg, msg->msgLength,
757 &coredev->version_ex_done);
758 if (rc < 0)
759 sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
760 "second try, rc %d", rc);
761 } else
762 rc = -ETIME;
763 }
764
765 kfree(buffer);
766
767 return rc;
768}
769
770static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
771 /*Stellar NOVA A0 Nova B0 VEGA*/
772 /*DVBT*/
773 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
774 /*DVBH*/
775 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
776 /*TDMB*/
777 {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"},
778 /*DABIP*/
779 {"none", "none", "none", "none"},
780 /*BDA*/
781 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
782 /*ISDBT*/
783 {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
784 /*ISDBTBDA*/
785 {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
786 /*CMMB*/
787 {"none", "none", "none", "cmmb_vega_12mhz.inp"}
788};
789
790static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
791 int mode, enum sms_device_type_st type)
792{
793 char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
794 return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
795}
796
797/**
798 * calls device handler to change mode of operation
799 * NOTE: stellar/usb may disconnect when changing mode
800 *
801 * @param coredev pointer to a coredev object returned by
802 * smscore_register_device
803 * @param mode requested mode of operation
804 *
805 * @return 0 on success, <0 on error.
806 */
807int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
808{
809 void *buffer;
810 int rc = 0;
811 enum sms_device_type_st type;
812
813 sms_debug("set device mode to %d", mode);
814 if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
815 if (mode < DEVICE_MODE_DVBT || mode >= DEVICE_MODE_RAW_TUNER) {
816 sms_err("invalid mode specified %d", mode);
817 return -EINVAL;
818 }
819
820 smscore_registry_setmode(coredev->devpath, mode);
821
822 if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
823 rc = smscore_detect_mode(coredev);
824 if (rc < 0) {
825 sms_err("mode detect failed %d", rc);
826 return rc;
827 }
828 }
829
830 if (coredev->mode == mode) {
831 sms_info("device mode %d already set", mode);
832 return 0;
833 }
834
835 if (!(coredev->modes_supported & (1 << mode))) {
836 char *fw_filename;
837
838 type = smscore_registry_gettype(coredev->devpath);
839 fw_filename = sms_get_fw_name(coredev, mode, type);
840
841 rc = smscore_load_firmware_from_file(coredev,
842 fw_filename, NULL);
843 if (rc < 0) {
844 sms_warn("error %d loading firmware: %s, "
845 "trying again with default firmware",
846 rc, fw_filename);
847
848 /* try again with the default firmware */
849 fw_filename = smscore_fw_lkup[mode][type];
850 rc = smscore_load_firmware_from_file(coredev,
851 fw_filename, NULL);
852
853 if (rc < 0) {
854 sms_warn("error %d loading "
855 "firmware: %s", rc,
856 fw_filename);
857 return rc;
858 }
859 }
860 sms_log("firmware download success: %s", fw_filename);
861 } else
862 sms_info("mode %d supported by running "
863 "firmware", mode);
864
865 buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
866 SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
867 if (buffer) {
868 struct SmsMsgData_ST *msg =
869 (struct SmsMsgData_ST *)
870 SMS_ALIGN_ADDRESS(buffer);
871
872 SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
873 sizeof(struct SmsMsgData_ST));
874 msg->msgData[0] = mode;
875
876 rc = smscore_sendrequest_and_wait(
877 coredev, msg, msg->xMsgHeader.msgLength,
878 &coredev->init_device_done);
879
880 kfree(buffer);
881 } else {
882 sms_err("Could not allocate buffer for "
883 "init device message.");
884 rc = -ENOMEM;
885 }
886 } else {
887 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
888 sms_err("invalid mode specified %d", mode);
889 return -EINVAL;
890 }
891
892 smscore_registry_setmode(coredev->devpath, mode);
893
894 if (coredev->detectmode_handler)
895 coredev->detectmode_handler(coredev->context,
896 &coredev->mode);
897
898 if (coredev->mode != mode && coredev->setmode_handler)
899 rc = coredev->setmode_handler(coredev->context, mode);
900 }
901
902 if (rc >= 0) {
903 coredev->mode = mode;
904 coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
905 }
906
907 if (rc < 0)
908 sms_err("return error code %d.", rc);
909 return rc;
910}
911
912/**
913 * calls device handler to get current mode of operation
914 *
915 * @param coredev pointer to a coredev object returned by
916 * smscore_register_device
917 *
918 * @return current mode
919 */
920int smscore_get_device_mode(struct smscore_device_t *coredev)
921{
922 return coredev->mode;
923}
924EXPORT_SYMBOL_GPL(smscore_get_device_mode);
925
926/**
927 * find client by response id & type within the clients list.
928 * return client handle or NULL.
929 *
930 * @param coredev pointer to a coredev object returned by
931 * smscore_register_device
932 * @param data_type client data type (SMS_DONT_CARE for all types)
933 * @param id client id (SMS_DONT_CARE for all id)
934 *
935 */
936static struct
937smscore_client_t *smscore_find_client(struct smscore_device_t *coredev,
938 int data_type, int id)
939{
940 struct list_head *first;
941 struct smscore_client_t *client;
942 unsigned long flags;
943 struct list_head *firstid;
944 struct smscore_idlist_t *client_id;
945
946 spin_lock_irqsave(&coredev->clientslock, flags);
947 first = &coredev->clients;
948 list_for_each_entry(client, first, entry) {
949 firstid = &client->idlist;
950 list_for_each_entry(client_id, firstid, entry) {
951 if ((client_id->id == id) &&
952 (client_id->data_type == data_type ||
953 (client_id->data_type == 0)))
954 goto found;
955 }
956 }
957 client = NULL;
958found:
959 spin_unlock_irqrestore(&coredev->clientslock, flags);
960 return client;
961}
962
963/**
964 * find client by response id/type, call clients onresponse handler
965 * return buffer to pool on error
966 *
967 * @param coredev pointer to a coredev object returned by
968 * smscore_register_device
969 * @param cb pointer to response buffer descriptor
970 *
971 */
972void smscore_onresponse(struct smscore_device_t *coredev,
973 struct smscore_buffer_t *cb) {
974 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p
975 + cb->offset);
976 struct smscore_client_t *client;
977 int rc = -EBUSY;
978 static unsigned long last_sample_time; /* = 0; */
979 static int data_total; /* = 0; */
980 unsigned long time_now = jiffies_to_msecs(jiffies);
981
982 if (!last_sample_time)
983 last_sample_time = time_now;
984
985 if (time_now - last_sample_time > 10000) {
986 sms_debug("\ndata rate %d bytes/secs",
987 (int)((data_total * 1000) /
988 (time_now - last_sample_time)));
989
990 last_sample_time = time_now;
991 data_total = 0;
992 }
993
994 data_total += cb->size;
995 /* Do we need to re-route? */
996 if ((phdr->msgType == MSG_SMS_HO_PER_SLICES_IND) ||
997 (phdr->msgType == MSG_SMS_TRANSMISSION_IND)) {
998 if (coredev->mode == DEVICE_MODE_DVBT_BDA)
999 phdr->msgDstId = DVBT_BDA_CONTROL_MSG_ID;
1000 }
1001
1002
1003 client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
1004
1005 /* If no client registered for type & id,
1006 * check for control client where type is not registered */
1007 if (client)
1008 rc = client->onresponse_handler(client->context, cb);
1009
1010 if (rc < 0) {
1011 switch (phdr->msgType) {
1012 case MSG_SMS_GET_VERSION_EX_RES:
1013 {
1014 struct SmsVersionRes_ST *ver =
1015 (struct SmsVersionRes_ST *) phdr;
1016 sms_debug("MSG_SMS_GET_VERSION_EX_RES "
1017 "id %d prots 0x%x ver %d.%d",
1018 ver->FirmwareId, ver->SupportedProtocols,
1019 ver->RomVersionMajor, ver->RomVersionMinor);
1020
1021 coredev->mode = ver->FirmwareId == 255 ?
1022 DEVICE_MODE_NONE : ver->FirmwareId;
1023 coredev->modes_supported = ver->SupportedProtocols;
1024
1025 complete(&coredev->version_ex_done);
1026 break;
1027 }
1028 case MSG_SMS_INIT_DEVICE_RES:
1029 sms_debug("MSG_SMS_INIT_DEVICE_RES");
1030 complete(&coredev->init_device_done);
1031 break;
1032 case MSG_SW_RELOAD_START_RES:
1033 sms_debug("MSG_SW_RELOAD_START_RES");
1034 complete(&coredev->reload_start_done);
1035 break;
1036 case MSG_SMS_DATA_DOWNLOAD_RES:
1037 complete(&coredev->data_download_done);
1038 break;
1039 case MSG_SW_RELOAD_EXEC_RES:
1040 sms_debug("MSG_SW_RELOAD_EXEC_RES");
1041 break;
1042 case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
1043 sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES");
1044 complete(&coredev->trigger_done);
1045 break;
1046 case MSG_SMS_SLEEP_RESUME_COMP_IND:
1047 complete(&coredev->resume_done);
1048 break;
1049 case MSG_SMS_GPIO_CONFIG_EX_RES:
1050 sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES");
1051 complete(&coredev->gpio_configuration_done);
1052 break;
1053 case MSG_SMS_GPIO_SET_LEVEL_RES:
1054 sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES");
1055 complete(&coredev->gpio_set_level_done);
1056 break;
1057 case MSG_SMS_GPIO_GET_LEVEL_RES:
1058 {
1059 u32 *msgdata = (u32 *) phdr;
1060 coredev->gpio_get_res = msgdata[1];
1061 sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d",
1062 coredev->gpio_get_res);
1063 complete(&coredev->gpio_get_level_done);
1064 break;
1065 }
1066 case MSG_SMS_START_IR_RES:
1067 complete(&coredev->ir_init_done);
1068 break;
1069 case MSG_SMS_IR_SAMPLES_IND:
1070 sms_ir_event(coredev,
1071 (const char *)
1072 ((char *)phdr
1073 + sizeof(struct SmsMsgHdr_ST)),
1074 (int)phdr->msgLength
1075 - sizeof(struct SmsMsgHdr_ST));
1076 break;
1077
1078 default:
1079 break;
1080 }
1081 smscore_putbuffer(coredev, cb);
1082 }
1083}
1084EXPORT_SYMBOL_GPL(smscore_onresponse);
1085
1086/**
1087 * return pointer to next free buffer descriptor from core pool
1088 *
1089 * @param coredev pointer to a coredev object returned by
1090 * smscore_register_device
1091 *
1092 * @return pointer to descriptor on success, NULL on error.
1093 */
1094
1095struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
1096{
1097 struct smscore_buffer_t *cb = NULL;
1098 unsigned long flags;
1099
1100 spin_lock_irqsave(&coredev->bufferslock, flags);
1101 if (!list_empty(&coredev->buffers)) {
1102 cb = (struct smscore_buffer_t *) coredev->buffers.next;
1103 list_del(&cb->entry);
1104 }
1105 spin_unlock_irqrestore(&coredev->bufferslock, flags);
1106 return cb;
1107}
1108
1109struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
1110{
1111 struct smscore_buffer_t *cb = NULL;
1112
1113 wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev)));
1114
1115 return cb;
1116}
1117EXPORT_SYMBOL_GPL(smscore_getbuffer);
1118
1119/**
1120 * return buffer descriptor to a pool
1121 *
1122 * @param coredev pointer to a coredev object returned by
1123 * smscore_register_device
1124 * @param cb pointer buffer descriptor
1125 *
1126 */
1127void smscore_putbuffer(struct smscore_device_t *coredev,
1128 struct smscore_buffer_t *cb) {
1129 wake_up_interruptible(&coredev->buffer_mng_waitq);
1130 list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
1131}
1132EXPORT_SYMBOL_GPL(smscore_putbuffer);
1133
1134static int smscore_validate_client(struct smscore_device_t *coredev,
1135 struct smscore_client_t *client,
1136 int data_type, int id)
1137{
1138 struct smscore_idlist_t *listentry;
1139 struct smscore_client_t *registered_client;
1140
1141 if (!client) {
1142 sms_err("bad parameter.");
1143 return -EINVAL;
1144 }
1145 registered_client = smscore_find_client(coredev, data_type, id);
1146 if (registered_client == client)
1147 return 0;
1148
1149 if (registered_client) {
1150 sms_err("The msg ID already registered to another client.");
1151 return -EEXIST;
1152 }
1153 listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
1154 if (!listentry) {
1155 sms_err("Can't allocate memory for client id.");
1156 return -ENOMEM;
1157 }
1158 listentry->id = id;
1159 listentry->data_type = data_type;
1160 list_add_locked(&listentry->entry, &client->idlist,
1161 &coredev->clientslock);
1162 return 0;
1163}
1164
1165/**
1166 * creates smsclient object, check that id is taken by another client
1167 *
1168 * @param coredev pointer to a coredev object from clients hotplug
1169 * @param initial_id all messages with this id would be sent to this client
1170 * @param data_type all messages of this type would be sent to this client
1171 * @param onresponse_handler client handler that is called to
1172 * process incoming messages
1173 * @param onremove_handler client handler that is called when device is removed
1174 * @param context client-specific context
1175 * @param client pointer to a value that receives created smsclient object
1176 *
1177 * @return 0 on success, <0 on error.
1178 */
1179int smscore_register_client(struct smscore_device_t *coredev,
1180 struct smsclient_params_t *params,
1181 struct smscore_client_t **client)
1182{
1183 struct smscore_client_t *newclient;
1184 /* check that no other channel with same parameters exists */
1185 if (smscore_find_client(coredev, params->data_type,
1186 params->initial_id)) {
1187 sms_err("Client already exist.");
1188 return -EEXIST;
1189 }
1190
1191 newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
1192 if (!newclient) {
1193 sms_err("Failed to allocate memory for client.");
1194 return -ENOMEM;
1195 }
1196
1197 INIT_LIST_HEAD(&newclient->idlist);
1198 newclient->coredev = coredev;
1199 newclient->onresponse_handler = params->onresponse_handler;
1200 newclient->onremove_handler = params->onremove_handler;
1201 newclient->context = params->context;
1202 list_add_locked(&newclient->entry, &coredev->clients,
1203 &coredev->clientslock);
1204 smscore_validate_client(coredev, newclient, params->data_type,
1205 params->initial_id);
1206 *client = newclient;
1207 sms_debug("%p %d %d", params->context, params->data_type,
1208 params->initial_id);
1209
1210 return 0;
1211}
1212EXPORT_SYMBOL_GPL(smscore_register_client);
1213
1214/**
1215 * frees smsclient object and all subclients associated with it
1216 *
1217 * @param client pointer to smsclient object returned by
1218 * smscore_register_client
1219 *
1220 */
1221void smscore_unregister_client(struct smscore_client_t *client)
1222{
1223 struct smscore_device_t *coredev = client->coredev;
1224 unsigned long flags;
1225
1226 spin_lock_irqsave(&coredev->clientslock, flags);
1227
1228
1229 while (!list_empty(&client->idlist)) {
1230 struct smscore_idlist_t *identry =
1231 (struct smscore_idlist_t *) client->idlist.next;
1232 list_del(&identry->entry);
1233 kfree(identry);
1234 }
1235
1236 sms_info("%p", client->context);
1237
1238 list_del(&client->entry);
1239 kfree(client);
1240
1241 spin_unlock_irqrestore(&coredev->clientslock, flags);
1242}
1243EXPORT_SYMBOL_GPL(smscore_unregister_client);
1244
1245/**
1246 * verifies that source id is not taken by another client,
1247 * calls device handler to send requests to the device
1248 *
1249 * @param client pointer to smsclient object returned by
1250 * smscore_register_client
1251 * @param buffer pointer to a request buffer
1252 * @param size size (in bytes) of request buffer
1253 *
1254 * @return 0 on success, <0 on error.
1255 */
1256int smsclient_sendrequest(struct smscore_client_t *client,
1257 void *buffer, size_t size)
1258{
1259 struct smscore_device_t *coredev;
1260 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
1261 int rc;
1262
1263 if (client == NULL) {
1264 sms_err("Got NULL client");
1265 return -EINVAL;
1266 }
1267
1268 coredev = client->coredev;
1269
1270 /* check that no other channel with same id exists */
1271 if (coredev == NULL) {
1272 sms_err("Got NULL coredev");
1273 return -EINVAL;
1274 }
1275
1276 rc = smscore_validate_client(client->coredev, client, 0,
1277 phdr->msgSrcId);
1278 if (rc < 0)
1279 return rc;
1280
1281 return coredev->sendrequest_handler(coredev->context, buffer, size);
1282}
1283EXPORT_SYMBOL_GPL(smsclient_sendrequest);
1284
1285
1286/* old GPIO managements implementation */
1287int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
1288 struct smscore_config_gpio *pinconfig)
1289{
1290 struct {
1291 struct SmsMsgHdr_ST hdr;
1292 u32 data[6];
1293 } msg;
1294
1295 if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
1296 msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1297 msg.hdr.msgDstId = HIF_TASK;
1298 msg.hdr.msgFlags = 0;
1299 msg.hdr.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
1300 msg.hdr.msgLength = sizeof(msg);
1301
1302 msg.data[0] = pin;
1303 msg.data[1] = pinconfig->pullupdown;
1304
1305 /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */
1306 msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0;
1307
1308 switch (pinconfig->outputdriving) {
1309 case SMS_GPIO_OUTPUTDRIVING_16mA:
1310 msg.data[3] = 7; /* Nova - 16mA */
1311 break;
1312 case SMS_GPIO_OUTPUTDRIVING_12mA:
1313 msg.data[3] = 5; /* Nova - 11mA */
1314 break;
1315 case SMS_GPIO_OUTPUTDRIVING_8mA:
1316 msg.data[3] = 3; /* Nova - 7mA */
1317 break;
1318 case SMS_GPIO_OUTPUTDRIVING_4mA:
1319 default:
1320 msg.data[3] = 2; /* Nova - 4mA */
1321 break;
1322 }
1323
1324 msg.data[4] = pinconfig->direction;
1325 msg.data[5] = 0;
1326 } else /* TODO: SMS_DEVICE_FAMILY1 */
1327 return -EINVAL;
1328
1329 return coredev->sendrequest_handler(coredev->context,
1330 &msg, sizeof(msg));
1331}
1332
1333int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
1334{
1335 struct {
1336 struct SmsMsgHdr_ST hdr;
1337 u32 data[3];
1338 } msg;
1339
1340 if (pin > MAX_GPIO_PIN_NUMBER)
1341 return -EINVAL;
1342
1343 msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1344 msg.hdr.msgDstId = HIF_TASK;
1345 msg.hdr.msgFlags = 0;
1346 msg.hdr.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
1347 msg.hdr.msgLength = sizeof(msg);
1348
1349 msg.data[0] = pin;
1350 msg.data[1] = level ? 1 : 0;
1351 msg.data[2] = 0;
1352
1353 return coredev->sendrequest_handler(coredev->context,
1354 &msg, sizeof(msg));
1355}
1356
1357/* new GPIO management implementation */
1358static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
1359 u32 *pGroupNum, u32 *pGroupCfg) {
1360
1361 *pGroupCfg = 1;
1362
1363 if (PinNum <= 1) {
1364 *pTranslatedPinNum = 0;
1365 *pGroupNum = 9;
1366 *pGroupCfg = 2;
1367 } else if (PinNum >= 2 && PinNum <= 6) {
1368 *pTranslatedPinNum = 2;
1369 *pGroupNum = 0;
1370 *pGroupCfg = 2;
1371 } else if (PinNum >= 7 && PinNum <= 11) {
1372 *pTranslatedPinNum = 7;
1373 *pGroupNum = 1;
1374 } else if (PinNum >= 12 && PinNum <= 15) {
1375 *pTranslatedPinNum = 12;
1376 *pGroupNum = 2;
1377 *pGroupCfg = 3;
1378 } else if (PinNum == 16) {
1379 *pTranslatedPinNum = 16;
1380 *pGroupNum = 23;
1381 } else if (PinNum >= 17 && PinNum <= 24) {
1382 *pTranslatedPinNum = 17;
1383 *pGroupNum = 3;
1384 } else if (PinNum == 25) {
1385 *pTranslatedPinNum = 25;
1386 *pGroupNum = 6;
1387 } else if (PinNum >= 26 && PinNum <= 28) {
1388 *pTranslatedPinNum = 26;
1389 *pGroupNum = 4;
1390 } else if (PinNum == 29) {
1391 *pTranslatedPinNum = 29;
1392 *pGroupNum = 5;
1393 *pGroupCfg = 2;
1394 } else if (PinNum == 30) {
1395 *pTranslatedPinNum = 30;
1396 *pGroupNum = 8;
1397 } else if (PinNum == 31) {
1398 *pTranslatedPinNum = 31;
1399 *pGroupNum = 17;
1400 } else
1401 return -1;
1402
1403 *pGroupCfg <<= 24;
1404
1405 return 0;
1406}
1407
1408int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
1409 struct smscore_gpio_config *pGpioConfig) {
1410
1411 u32 totalLen;
1412 u32 TranslatedPinNum = 0;
1413 u32 GroupNum = 0;
1414 u32 ElectricChar;
1415 u32 groupCfg;
1416 void *buffer;
1417 int rc;
1418
1419 struct SetGpioMsg {
1420 struct SmsMsgHdr_ST xMsgHeader;
1421 u32 msgData[6];
1422 } *pMsg;
1423
1424
1425 if (PinNum > MAX_GPIO_PIN_NUMBER)
1426 return -EINVAL;
1427
1428 if (pGpioConfig == NULL)
1429 return -EINVAL;
1430
1431 totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6);
1432
1433 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1434 GFP_KERNEL | GFP_DMA);
1435 if (!buffer)
1436 return -ENOMEM;
1437
1438 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1439
1440 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1441 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1442 pMsg->xMsgHeader.msgFlags = 0;
1443 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1444 pMsg->msgData[0] = PinNum;
1445
1446 if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
1447 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
1448 if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
1449 &groupCfg) != 0) {
1450 rc = -EINVAL;
1451 goto free;
1452 }
1453
1454 pMsg->msgData[1] = TranslatedPinNum;
1455 pMsg->msgData[2] = GroupNum;
1456 ElectricChar = (pGpioConfig->PullUpDown)
1457 | (pGpioConfig->InputCharacteristics << 2)
1458 | (pGpioConfig->OutputSlewRate << 3)
1459 | (pGpioConfig->OutputDriving << 4);
1460 pMsg->msgData[3] = ElectricChar;
1461 pMsg->msgData[4] = pGpioConfig->Direction;
1462 pMsg->msgData[5] = groupCfg;
1463 } else {
1464 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
1465 pMsg->msgData[1] = pGpioConfig->PullUpDown;
1466 pMsg->msgData[2] = pGpioConfig->OutputSlewRate;
1467 pMsg->msgData[3] = pGpioConfig->OutputDriving;
1468 pMsg->msgData[4] = pGpioConfig->Direction;
1469 pMsg->msgData[5] = 0;
1470 }
1471
1472 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1473 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1474 &coredev->gpio_configuration_done);
1475
1476 if (rc != 0) {
1477 if (rc == -ETIME)
1478 sms_err("smscore_gpio_configure timeout");
1479 else
1480 sms_err("smscore_gpio_configure error");
1481 }
1482free:
1483 kfree(buffer);
1484
1485 return rc;
1486}
1487
1488int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
1489 u8 NewLevel) {
1490
1491 u32 totalLen;
1492 int rc;
1493 void *buffer;
1494
1495 struct SetGpioMsg {
1496 struct SmsMsgHdr_ST xMsgHeader;
1497 u32 msgData[3]; /* keep it 3 ! */
1498 } *pMsg;
1499
1500 if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER))
1501 return -EINVAL;
1502
1503 totalLen = sizeof(struct SmsMsgHdr_ST) +
1504 (3 * sizeof(u32)); /* keep it 3 ! */
1505
1506 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1507 GFP_KERNEL | GFP_DMA);
1508 if (!buffer)
1509 return -ENOMEM;
1510
1511 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1512
1513 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1514 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1515 pMsg->xMsgHeader.msgFlags = 0;
1516 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
1517 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1518 pMsg->msgData[0] = PinNum;
1519 pMsg->msgData[1] = NewLevel;
1520
1521 /* Send message to SMS */
1522 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1523 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1524 &coredev->gpio_set_level_done);
1525
1526 if (rc != 0) {
1527 if (rc == -ETIME)
1528 sms_err("smscore_gpio_set_level timeout");
1529 else
1530 sms_err("smscore_gpio_set_level error");
1531 }
1532 kfree(buffer);
1533
1534 return rc;
1535}
1536
1537int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
1538 u8 *level) {
1539
1540 u32 totalLen;
1541 int rc;
1542 void *buffer;
1543
1544 struct SetGpioMsg {
1545 struct SmsMsgHdr_ST xMsgHeader;
1546 u32 msgData[2];
1547 } *pMsg;
1548
1549
1550 if (PinNum > MAX_GPIO_PIN_NUMBER)
1551 return -EINVAL;
1552
1553 totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32));
1554
1555 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1556 GFP_KERNEL | GFP_DMA);
1557 if (!buffer)
1558 return -ENOMEM;
1559
1560 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1561
1562 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1563 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1564 pMsg->xMsgHeader.msgFlags = 0;
1565 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
1566 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1567 pMsg->msgData[0] = PinNum;
1568 pMsg->msgData[1] = 0;
1569
1570 /* Send message to SMS */
1571 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1572 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1573 &coredev->gpio_get_level_done);
1574
1575 if (rc != 0) {
1576 if (rc == -ETIME)
1577 sms_err("smscore_gpio_get_level timeout");
1578 else
1579 sms_err("smscore_gpio_get_level error");
1580 }
1581 kfree(buffer);
1582
1583 /* Its a race between other gpio_get_level() and the copy of the single
1584 * global 'coredev->gpio_get_res' to the function's variable 'level'
1585 */
1586 *level = coredev->gpio_get_res;
1587
1588 return rc;
1589}
1590
1591static int __init smscore_module_init(void)
1592{
1593 int rc = 0;
1594
1595 INIT_LIST_HEAD(&g_smscore_notifyees);
1596 INIT_LIST_HEAD(&g_smscore_devices);
1597 kmutex_init(&g_smscore_deviceslock);
1598
1599 INIT_LIST_HEAD(&g_smscore_registry);
1600 kmutex_init(&g_smscore_registrylock);
1601
1602 return rc;
1603}
1604
1605static void __exit smscore_module_exit(void)
1606{
1607 kmutex_lock(&g_smscore_deviceslock);
1608 while (!list_empty(&g_smscore_notifyees)) {
1609 struct smscore_device_notifyee_t *notifyee =
1610 (struct smscore_device_notifyee_t *)
1611 g_smscore_notifyees.next;
1612
1613 list_del(&notifyee->entry);
1614 kfree(notifyee);
1615 }
1616 kmutex_unlock(&g_smscore_deviceslock);
1617
1618 kmutex_lock(&g_smscore_registrylock);
1619 while (!list_empty(&g_smscore_registry)) {
1620 struct smscore_registry_entry_t *entry =
1621 (struct smscore_registry_entry_t *)
1622 g_smscore_registry.next;
1623
1624 list_del(&entry->entry);
1625 kfree(entry);
1626 }
1627 kmutex_unlock(&g_smscore_registrylock);
1628
1629 sms_debug("");
1630}
1631
1632module_init(smscore_module_init);
1633module_exit(smscore_module_exit);
1634
1635MODULE_DESCRIPTION("Siano MDTV Core module");
1636MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
1637MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/siano/smscoreapi.h b/drivers/media/usb/siano/smscoreapi.h
new file mode 100644
index 000000000000..c592ae090397
--- /dev/null
+++ b/drivers/media/usb/siano/smscoreapi.h
@@ -0,0 +1,775 @@
1/****************************************************************
2
3Siano Mobile Silicon, Inc.
4MDTV receiver kernel modules.
5Copyright (C) 2006-2008, Uri Shkolnik, Anatoly Greenblat
6
7This program is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the 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,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20****************************************************************/
21
22#ifndef __SMS_CORE_API_H__
23#define __SMS_CORE_API_H__
24
25#include <linux/device.h>
26#include <linux/list.h>
27#include <linux/mm.h>
28#include <linux/scatterlist.h>
29#include <linux/types.h>
30#include <linux/mutex.h>
31#include <linux/wait.h>
32#include <linux/timer.h>
33
34#include <asm/page.h>
35
36#include "smsir.h"
37
38#define kmutex_init(_p_) mutex_init(_p_)
39#define kmutex_lock(_p_) mutex_lock(_p_)
40#define kmutex_trylock(_p_) mutex_trylock(_p_)
41#define kmutex_unlock(_p_) mutex_unlock(_p_)
42
43#ifndef min
44#define min(a, b) (((a) < (b)) ? (a) : (b))
45#endif
46
47#define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS (10000)
48#define SMS_ALLOC_ALIGNMENT 128
49#define SMS_DMA_ALIGNMENT 16
50#define SMS_ALIGN_ADDRESS(addr) \
51 ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1))
52
53#define SMS_DEVICE_FAMILY2 1
54#define SMS_ROM_NO_RESPONSE 2
55#define SMS_DEVICE_NOT_READY 0x8000000
56
57enum sms_device_type_st {
58 SMS_STELLAR = 0,
59 SMS_NOVA_A0,
60 SMS_NOVA_B0,
61 SMS_VEGA,
62 SMS_NUM_OF_DEVICE_TYPES
63};
64
65struct smscore_device_t;
66struct smscore_client_t;
67struct smscore_buffer_t;
68
69typedef int (*hotplug_t)(struct smscore_device_t *coredev,
70 struct device *device, int arrival);
71
72typedef int (*setmode_t)(void *context, int mode);
73typedef void (*detectmode_t)(void *context, int *mode);
74typedef int (*sendrequest_t)(void *context, void *buffer, size_t size);
75typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size);
76typedef int (*preload_t)(void *context);
77typedef int (*postload_t)(void *context);
78
79typedef int (*onresponse_t)(void *context, struct smscore_buffer_t *cb);
80typedef void (*onremove_t)(void *context);
81
82struct smscore_buffer_t {
83 /* public members, once passed to clients can be changed freely */
84 struct list_head entry;
85 int size;
86 int offset;
87
88 /* private members, read-only for clients */
89 void *p;
90 dma_addr_t phys;
91 unsigned long offset_in_common;
92};
93
94struct smsdevice_params_t {
95 struct device *device;
96
97 int buffer_size;
98 int num_buffers;
99
100 char devpath[32];
101 unsigned long flags;
102
103 setmode_t setmode_handler;
104 detectmode_t detectmode_handler;
105 sendrequest_t sendrequest_handler;
106 preload_t preload_handler;
107 postload_t postload_handler;
108
109 void *context;
110 enum sms_device_type_st device_type;
111};
112
113struct smsclient_params_t {
114 int initial_id;
115 int data_type;
116 onresponse_t onresponse_handler;
117 onremove_t onremove_handler;
118 void *context;
119};
120
121struct smscore_device_t {
122 struct list_head entry;
123
124 struct list_head clients;
125 struct list_head subclients;
126 spinlock_t clientslock;
127
128 struct list_head buffers;
129 spinlock_t bufferslock;
130 int num_buffers;
131
132 void *common_buffer;
133 int common_buffer_size;
134 dma_addr_t common_buffer_phys;
135
136 void *context;
137 struct device *device;
138
139 char devpath[32];
140 unsigned long device_flags;
141
142 setmode_t setmode_handler;
143 detectmode_t detectmode_handler;
144 sendrequest_t sendrequest_handler;
145 preload_t preload_handler;
146 postload_t postload_handler;
147
148 int mode, modes_supported;
149
150 /* host <--> device messages */
151 struct completion version_ex_done, data_download_done, trigger_done;
152 struct completion init_device_done, reload_start_done, resume_done;
153 struct completion gpio_configuration_done, gpio_set_level_done;
154 struct completion gpio_get_level_done, ir_init_done;
155
156 /* Buffer management */
157 wait_queue_head_t buffer_mng_waitq;
158
159 /* GPIO */
160 int gpio_get_res;
161
162 /* Target hardware board */
163 int board_id;
164
165 /* Firmware */
166 u8 *fw_buf;
167 u32 fw_buf_size;
168
169 /* Infrared (IR) */
170 struct ir_t ir;
171
172 int led_state;
173};
174
175/* GPIO definitions for antenna frequency domain control (SMS8021) */
176#define SMS_ANTENNA_GPIO_0 1
177#define SMS_ANTENNA_GPIO_1 0
178
179#define BW_8_MHZ 0
180#define BW_7_MHZ 1
181#define BW_6_MHZ 2
182#define BW_5_MHZ 3
183#define BW_ISDBT_1SEG 4
184#define BW_ISDBT_3SEG 5
185
186#define MSG_HDR_FLAG_SPLIT_MSG 4
187
188#define MAX_GPIO_PIN_NUMBER 31
189
190#define HIF_TASK 11
191#define SMS_HOST_LIB 150
192#define DVBT_BDA_CONTROL_MSG_ID 201
193
194#define SMS_MAX_PAYLOAD_SIZE 240
195#define SMS_TUNE_TIMEOUT 500
196
197#define MSG_SMS_GPIO_CONFIG_REQ 507
198#define MSG_SMS_GPIO_CONFIG_RES 508
199#define MSG_SMS_GPIO_SET_LEVEL_REQ 509
200#define MSG_SMS_GPIO_SET_LEVEL_RES 510
201#define MSG_SMS_GPIO_GET_LEVEL_REQ 511
202#define MSG_SMS_GPIO_GET_LEVEL_RES 512
203#define MSG_SMS_RF_TUNE_REQ 561
204#define MSG_SMS_RF_TUNE_RES 562
205#define MSG_SMS_INIT_DEVICE_REQ 578
206#define MSG_SMS_INIT_DEVICE_RES 579
207#define MSG_SMS_ADD_PID_FILTER_REQ 601
208#define MSG_SMS_ADD_PID_FILTER_RES 602
209#define MSG_SMS_REMOVE_PID_FILTER_REQ 603
210#define MSG_SMS_REMOVE_PID_FILTER_RES 604
211#define MSG_SMS_DAB_CHANNEL 607
212#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608
213#define MSG_SMS_GET_PID_FILTER_LIST_RES 609
214#define MSG_SMS_GET_STATISTICS_RES 616
215#define MSG_SMS_GET_STATISTICS_REQ 615
216#define MSG_SMS_HO_PER_SLICES_IND 630
217#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651
218#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652
219#define MSG_SMS_SLEEP_RESUME_COMP_IND 655
220#define MSG_SMS_DATA_DOWNLOAD_REQ 660
221#define MSG_SMS_DATA_DOWNLOAD_RES 661
222#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664
223#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665
224#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666
225#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667
226#define MSG_SMS_GET_VERSION_EX_REQ 668
227#define MSG_SMS_GET_VERSION_EX_RES 669
228#define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670
229#define MSG_SMS_I2C_SET_FREQ_REQ 685
230#define MSG_SMS_GENERIC_I2C_REQ 687
231#define MSG_SMS_GENERIC_I2C_RES 688
232#define MSG_SMS_DVBT_BDA_DATA 693
233#define MSG_SW_RELOAD_REQ 697
234#define MSG_SMS_DATA_MSG 699
235#define MSG_SW_RELOAD_START_REQ 702
236#define MSG_SW_RELOAD_START_RES 703
237#define MSG_SW_RELOAD_EXEC_REQ 704
238#define MSG_SW_RELOAD_EXEC_RES 705
239#define MSG_SMS_SPI_INT_LINE_SET_REQ 710
240#define MSG_SMS_GPIO_CONFIG_EX_REQ 712
241#define MSG_SMS_GPIO_CONFIG_EX_RES 713
242#define MSG_SMS_ISDBT_TUNE_REQ 776
243#define MSG_SMS_ISDBT_TUNE_RES 777
244#define MSG_SMS_TRANSMISSION_IND 782
245#define MSG_SMS_START_IR_REQ 800
246#define MSG_SMS_START_IR_RES 801
247#define MSG_SMS_IR_SAMPLES_IND 802
248#define MSG_SMS_SIGNAL_DETECTED_IND 827
249#define MSG_SMS_NO_SIGNAL_IND 828
250
251#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \
252 (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \
253 (ptr)->msgLength = len; (ptr)->msgFlags = 0; \
254} while (0)
255
256#define SMS_INIT_MSG(ptr, type, len) \
257 SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len)
258
259enum SMS_DVB3_EVENTS {
260 DVB3_EVENT_INIT = 0,
261 DVB3_EVENT_SLEEP,
262 DVB3_EVENT_HOTPLUG,
263 DVB3_EVENT_FE_LOCK,
264 DVB3_EVENT_FE_UNLOCK,
265 DVB3_EVENT_UNC_OK,
266 DVB3_EVENT_UNC_ERR
267};
268
269enum SMS_DEVICE_MODE {
270 DEVICE_MODE_NONE = -1,
271 DEVICE_MODE_DVBT = 0,
272 DEVICE_MODE_DVBH,
273 DEVICE_MODE_DAB_TDMB,
274 DEVICE_MODE_DAB_TDMB_DABIP,
275 DEVICE_MODE_DVBT_BDA,
276 DEVICE_MODE_ISDBT,
277 DEVICE_MODE_ISDBT_BDA,
278 DEVICE_MODE_CMMB,
279 DEVICE_MODE_RAW_TUNER,
280 DEVICE_MODE_MAX,
281};
282
283struct SmsMsgHdr_ST {
284 u16 msgType;
285 u8 msgSrcId;
286 u8 msgDstId;
287 u16 msgLength; /* Length of entire message, including header */
288 u16 msgFlags;
289};
290
291struct SmsMsgData_ST {
292 struct SmsMsgHdr_ST xMsgHeader;
293 u32 msgData[1];
294};
295
296struct SmsMsgData_ST2 {
297 struct SmsMsgHdr_ST xMsgHeader;
298 u32 msgData[2];
299};
300
301struct SmsDataDownload_ST {
302 struct SmsMsgHdr_ST xMsgHeader;
303 u32 MemAddr;
304 u8 Payload[SMS_MAX_PAYLOAD_SIZE];
305};
306
307struct SmsVersionRes_ST {
308 struct SmsMsgHdr_ST xMsgHeader;
309
310 u16 ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */
311 u8 Step; /* 0 - Step A */
312 u8 MetalFix; /* 0 - Metal 0 */
313
314 /* FirmwareId 0xFF if ROM, otherwise the
315 * value indicated by SMSHOSTLIB_DEVICE_MODES_E */
316 u8 FirmwareId;
317 /* SupportedProtocols Bitwise OR combination of
318 * supported protocols */
319 u8 SupportedProtocols;
320
321 u8 VersionMajor;
322 u8 VersionMinor;
323 u8 VersionPatch;
324 u8 VersionFieldPatch;
325
326 u8 RomVersionMajor;
327 u8 RomVersionMinor;
328 u8 RomVersionPatch;
329 u8 RomVersionFieldPatch;
330
331 u8 TextLabel[34];
332};
333
334struct SmsFirmware_ST {
335 u32 CheckSum;
336 u32 Length;
337 u32 StartAddress;
338 u8 Payload[1];
339};
340
341/* Statistics information returned as response for
342 * SmsHostApiGetStatistics_Req */
343struct SMSHOSTLIB_STATISTICS_ST {
344 u32 Reserved; /* Reserved */
345
346 /* Common parameters */
347 u32 IsRfLocked; /* 0 - not locked, 1 - locked */
348 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
349 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
350
351 /* Reception quality */
352 s32 SNR; /* dB */
353 u32 BER; /* Post Viterbi BER [1E-5] */
354 u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */
355 u32 TS_PER; /* Transport stream PER,
356 0xFFFFFFFF indicate N/A, valid only for DVB-T/H */
357 u32 MFER; /* DVB-H frame error rate in percentage,
358 0xFFFFFFFF indicate N/A, valid only for DVB-H */
359 s32 RSSI; /* dBm */
360 s32 InBandPwr; /* In band power in dBM */
361 s32 CarrierOffset; /* Carrier Offset in bin/1024 */
362
363 /* Transmission parameters */
364 u32 Frequency; /* Frequency in Hz */
365 u32 Bandwidth; /* Bandwidth in MHz, valid only for DVB-T/H */
366 u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4,
367 for DVB-T/H FFT mode carriers in Kilos */
368 u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET,
369 valid only for DVB-T/H */
370 u32 GuardInterval; /* Guard Interval from
371 SMSHOSTLIB_GUARD_INTERVALS_ET, valid only for DVB-T/H */
372 u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
373 valid only for DVB-T/H */
374 u32 LPCodeRate; /* Low Priority Code Rate from
375 SMSHOSTLIB_CODE_RATE_ET, valid only for DVB-T/H */
376 u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET,
377 valid only for DVB-T/H */
378 u32 Constellation; /* Constellation from
379 SMSHOSTLIB_CONSTELLATION_ET, valid only for DVB-T/H */
380
381 /* Burst parameters, valid only for DVB-H */
382 u32 BurstSize; /* Current burst size in bytes,
383 valid only for DVB-H */
384 u32 BurstDuration; /* Current burst duration in mSec,
385 valid only for DVB-H */
386 u32 BurstCycleTime; /* Current burst cycle time in mSec,
387 valid only for DVB-H */
388 u32 CalculatedBurstCycleTime;/* Current burst cycle time in mSec,
389 as calculated by demodulator, valid only for DVB-H */
390 u32 NumOfRows; /* Number of rows in MPE table,
391 valid only for DVB-H */
392 u32 NumOfPaddCols; /* Number of padding columns in MPE table,
393 valid only for DVB-H */
394 u32 NumOfPunctCols; /* Number of puncturing columns in MPE table,
395 valid only for DVB-H */
396 u32 ErrorTSPackets; /* Number of erroneous
397 transport-stream packets */
398 u32 TotalTSPackets; /* Total number of transport-stream packets */
399 u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include
400 errors after MPE RS decoding */
401 u32 NumOfInvalidMpeTlbs;/* Number of MPE tables which include errors
402 after MPE RS decoding */
403 u32 NumOfCorrectedMpeTlbs;/* Number of MPE tables which were
404 corrected by MPE RS decoding */
405 /* Common params */
406 u32 BERErrorCount; /* Number of errornous SYNC bits. */
407 u32 BERBitCount; /* Total number of SYNC bits. */
408
409 /* Interface information */
410 u32 SmsToHostTxErrors; /* Total number of transmission errors. */
411
412 /* DAB/T-DMB */
413 u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */
414
415 /* DVB-H TPS parameters */
416 u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
417 if set to 0xFFFFFFFF cell_id not yet recovered */
418 u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 -
419 Time Slicing indicator, bit 0 - MPE-FEC indicator */
420 u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 -
421 Time Slicing indicator, bit 0 - MPE-FEC indicator */
422
423 u32 NumMPEReceived; /* DVB-H, Num MPE section received */
424
425 u32 ReservedFields[10]; /* Reserved */
426};
427
428struct SmsMsgStatisticsInfo_ST {
429 u32 RequestResult;
430
431 struct SMSHOSTLIB_STATISTICS_ST Stat;
432
433 /* Split the calc of the SNR in DAB */
434 u32 Signal; /* dB */
435 u32 Noise; /* dB */
436
437};
438
439struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST {
440 /* Per-layer information */
441 u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
442 * 255 means layer does not exist */
443 u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET,
444 * 255 means layer does not exist */
445 u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
446 u32 BERErrorCount; /* Post Viterbi Error Bits Count */
447 u32 BERBitCount; /* Post Viterbi Total Bits Count */
448 u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
449 u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */
450 u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
451 u32 TotalTSPackets; /* Total number of transport-stream packets */
452 u32 TILdepthI; /* Time interleaver depth I parameter,
453 * 255 means layer does not exist */
454 u32 NumberOfSegments; /* Number of segments in layer A,
455 * 255 means layer does not exist */
456 u32 TMCCErrors; /* TMCC errors */
457};
458
459struct SMSHOSTLIB_STATISTICS_ISDBT_ST {
460 u32 StatisticsType; /* Enumerator identifying the type of the
461 * structure. Values are the same as
462 * SMSHOSTLIB_DEVICE_MODES_E
463 *
464 * This field MUST always be first in any
465 * statistics structure */
466
467 u32 FullSize; /* Total size of the structure returned by the modem.
468 * If the size requested by the host is smaller than
469 * FullSize, the struct will be truncated */
470
471 /* Common parameters */
472 u32 IsRfLocked; /* 0 - not locked, 1 - locked */
473 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
474 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
475
476 /* Reception quality */
477 s32 SNR; /* dB */
478 s32 RSSI; /* dBm */
479 s32 InBandPwr; /* In band power in dBM */
480 s32 CarrierOffset; /* Carrier Offset in Hz */
481
482 /* Transmission parameters */
483 u32 Frequency; /* Frequency in Hz */
484 u32 Bandwidth; /* Bandwidth in MHz */
485 u32 TransmissionMode; /* ISDB-T transmission mode */
486 u32 ModemState; /* 0 - Acquisition, 1 - Locked */
487 u32 GuardInterval; /* Guard Interval, 1 divided by value */
488 u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */
489 u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */
490 u32 NumOfLayers; /* Number of ISDB-T layers in the network */
491
492 /* Per-layer information */
493 /* Layers A, B and C */
494 struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3];
495 /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */
496
497 /* Interface information */
498 u32 SmsToHostTxErrors; /* Total number of transmission errors. */
499};
500
501struct PID_STATISTICS_DATA_S {
502 struct PID_BURST_S {
503 u32 size;
504 u32 padding_cols;
505 u32 punct_cols;
506 u32 duration;
507 u32 cycle;
508 u32 calc_cycle;
509 } burst;
510
511 u32 tot_tbl_cnt;
512 u32 invalid_tbl_cnt;
513 u32 tot_cor_tbl;
514};
515
516struct PID_DATA_S {
517 u32 pid;
518 u32 num_rows;
519 struct PID_STATISTICS_DATA_S pid_statistics;
520};
521
522#define CORRECT_STAT_RSSI(_stat) ((_stat).RSSI *= -1)
523#define CORRECT_STAT_BANDWIDTH(_stat) (_stat.Bandwidth = 8 - _stat.Bandwidth)
524#define CORRECT_STAT_TRANSMISSON_MODE(_stat) \
525 if (_stat.TransmissionMode == 0) \
526 _stat.TransmissionMode = 2; \
527 else if (_stat.TransmissionMode == 1) \
528 _stat.TransmissionMode = 8; \
529 else \
530 _stat.TransmissionMode = 4;
531
532struct TRANSMISSION_STATISTICS_S {
533 u32 Frequency; /* Frequency in Hz */
534 u32 Bandwidth; /* Bandwidth in MHz */
535 u32 TransmissionMode; /* FFT mode carriers in Kilos */
536 u32 GuardInterval; /* Guard Interval from
537 SMSHOSTLIB_GUARD_INTERVALS_ET */
538 u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */
539 u32 LPCodeRate; /* Low Priority Code Rate from
540 SMSHOSTLIB_CODE_RATE_ET */
541 u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */
542 u32 Constellation; /* Constellation from
543 SMSHOSTLIB_CONSTELLATION_ET */
544
545 /* DVB-H TPS parameters */
546 u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
547 if set to 0xFFFFFFFF cell_id not yet recovered */
548 u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 -
549 Time Slicing indicator, bit 0 - MPE-FEC indicator */
550 u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 -
551 Time Slicing indicator, bit 0 - MPE-FEC indicator */
552 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
553};
554
555struct RECEPTION_STATISTICS_S {
556 u32 IsRfLocked; /* 0 - not locked, 1 - locked */
557 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
558 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
559
560 u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
561 s32 SNR; /* dB */
562 u32 BER; /* Post Viterbi BER [1E-5] */
563 u32 BERErrorCount; /* Number of erronous SYNC bits. */
564 u32 BERBitCount; /* Total number of SYNC bits. */
565 u32 TS_PER; /* Transport stream PER,
566 0xFFFFFFFF indicate N/A */
567 u32 MFER; /* DVB-H frame error rate in percentage,
568 0xFFFFFFFF indicate N/A, valid only for DVB-H */
569 s32 RSSI; /* dBm */
570 s32 InBandPwr; /* In band power in dBM */
571 s32 CarrierOffset; /* Carrier Offset in bin/1024 */
572 u32 ErrorTSPackets; /* Number of erroneous
573 transport-stream packets */
574 u32 TotalTSPackets; /* Total number of transport-stream packets */
575
576 s32 MRC_SNR; /* dB */
577 s32 MRC_RSSI; /* dBm */
578 s32 MRC_InBandPwr; /* In band power in dBM */
579};
580
581
582/* Statistics information returned as response for
583 * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */
584struct SMSHOSTLIB_STATISTICS_DVB_S {
585 /* Reception */
586 struct RECEPTION_STATISTICS_S ReceptionData;
587
588 /* Transmission parameters */
589 struct TRANSMISSION_STATISTICS_S TransmissionData;
590
591 /* Burst parameters, valid only for DVB-H */
592#define SRVM_MAX_PID_FILTERS 8
593 struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS];
594};
595
596struct SRVM_SIGNAL_STATUS_S {
597 u32 result;
598 u32 snr;
599 u32 tsPackets;
600 u32 etsPackets;
601 u32 constellation;
602 u32 hpCode;
603 u32 tpsSrvIndLP;
604 u32 tpsSrvIndHP;
605 u32 cellId;
606 u32 reason;
607
608 s32 inBandPower;
609 u32 requestId;
610};
611
612struct SMSHOSTLIB_I2C_REQ_ST {
613 u32 DeviceAddress; /* I2c device address */
614 u32 WriteCount; /* number of bytes to write */
615 u32 ReadCount; /* number of bytes to read */
616 u8 Data[1];
617};
618
619struct SMSHOSTLIB_I2C_RES_ST {
620 u32 Status; /* non-zero value in case of failure */
621 u32 ReadCount; /* number of bytes read */
622 u8 Data[1];
623};
624
625
626struct smscore_config_gpio {
627#define SMS_GPIO_DIRECTION_INPUT 0
628#define SMS_GPIO_DIRECTION_OUTPUT 1
629 u8 direction;
630
631#define SMS_GPIO_PULLUPDOWN_NONE 0
632#define SMS_GPIO_PULLUPDOWN_PULLDOWN 1
633#define SMS_GPIO_PULLUPDOWN_PULLUP 2
634#define SMS_GPIO_PULLUPDOWN_KEEPER 3
635 u8 pullupdown;
636
637#define SMS_GPIO_INPUTCHARACTERISTICS_NORMAL 0
638#define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1
639 u8 inputcharacteristics;
640
641#define SMS_GPIO_OUTPUTSLEWRATE_FAST 0
642#define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1
643 u8 outputslewrate;
644
645#define SMS_GPIO_OUTPUTDRIVING_4mA 0
646#define SMS_GPIO_OUTPUTDRIVING_8mA 1
647#define SMS_GPIO_OUTPUTDRIVING_12mA 2
648#define SMS_GPIO_OUTPUTDRIVING_16mA 3
649 u8 outputdriving;
650};
651
652struct smscore_gpio_config {
653#define SMS_GPIO_DIRECTION_INPUT 0
654#define SMS_GPIO_DIRECTION_OUTPUT 1
655 u8 Direction;
656
657#define SMS_GPIO_PULL_UP_DOWN_NONE 0
658#define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1
659#define SMS_GPIO_PULL_UP_DOWN_PULLUP 2
660#define SMS_GPIO_PULL_UP_DOWN_KEEPER 3
661 u8 PullUpDown;
662
663#define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL 0
664#define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1
665 u8 InputCharacteristics;
666
667#define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW 1 /* 10xx */
668#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0 /* 10xx */
669
670
671#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0 /* 11xx */
672#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1 /* 11xx */
673#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2 /* 11xx */
674#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3 /* 11xx */
675 u8 OutputSlewRate;
676
677#define SMS_GPIO_OUTPUT_DRIVING_S_4mA 0 /* 10xx */
678#define SMS_GPIO_OUTPUT_DRIVING_S_8mA 1 /* 10xx */
679#define SMS_GPIO_OUTPUT_DRIVING_S_12mA 2 /* 10xx */
680#define SMS_GPIO_OUTPUT_DRIVING_S_16mA 3 /* 10xx */
681
682#define SMS_GPIO_OUTPUT_DRIVING_1_5mA 0 /* 11xx */
683#define SMS_GPIO_OUTPUT_DRIVING_2_8mA 1 /* 11xx */
684#define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */
685#define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */
686#define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */
687#define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */
688#define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */
689#define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */
690 u8 OutputDriving;
691};
692
693extern void smscore_registry_setmode(char *devpath, int mode);
694extern int smscore_registry_getmode(char *devpath);
695
696extern int smscore_register_hotplug(hotplug_t hotplug);
697extern void smscore_unregister_hotplug(hotplug_t hotplug);
698
699extern int smscore_register_device(struct smsdevice_params_t *params,
700 struct smscore_device_t **coredev);
701extern void smscore_unregister_device(struct smscore_device_t *coredev);
702
703extern int smscore_start_device(struct smscore_device_t *coredev);
704extern int smscore_load_firmware(struct smscore_device_t *coredev,
705 char *filename,
706 loadfirmware_t loadfirmware_handler);
707
708extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode);
709extern int smscore_get_device_mode(struct smscore_device_t *coredev);
710
711extern int smscore_register_client(struct smscore_device_t *coredev,
712 struct smsclient_params_t *params,
713 struct smscore_client_t **client);
714extern void smscore_unregister_client(struct smscore_client_t *client);
715
716extern int smsclient_sendrequest(struct smscore_client_t *client,
717 void *buffer, size_t size);
718extern void smscore_onresponse(struct smscore_device_t *coredev,
719 struct smscore_buffer_t *cb);
720
721extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
722extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
723 struct vm_area_struct *vma);
724extern int smscore_get_fw_filename(struct smscore_device_t *coredev,
725 int mode, char *filename);
726extern int smscore_send_fw_file(struct smscore_device_t *coredev,
727 u8 *ufwbuf, int size);
728
729extern
730struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
731extern void smscore_putbuffer(struct smscore_device_t *coredev,
732 struct smscore_buffer_t *cb);
733
734/* old GPIO management */
735int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
736 struct smscore_config_gpio *pinconfig);
737int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level);
738
739/* new GPIO management */
740extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
741 struct smscore_gpio_config *pGpioConfig);
742extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
743 u8 NewLevel);
744extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
745 u8 *level);
746
747void smscore_set_board_id(struct smscore_device_t *core, int id);
748int smscore_get_board_id(struct smscore_device_t *core);
749
750int smscore_led_state(struct smscore_device_t *core, int led);
751
752
753/* ------------------------------------------------------------------------ */
754
755#define DBG_INFO 1
756#define DBG_ADV 2
757
758#define sms_printk(kern, fmt, arg...) \
759 printk(kern "%s: " fmt "\n", __func__, ##arg)
760
761#define dprintk(kern, lvl, fmt, arg...) do {\
762 if (sms_dbg & lvl) \
763 sms_printk(kern, fmt, ##arg); } while (0)
764
765#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
766#define sms_err(fmt, arg...) \
767 sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg)
768#define sms_warn(fmt, arg...) sms_printk(KERN_WARNING, fmt, ##arg)
769#define sms_info(fmt, arg...) \
770 dprintk(KERN_INFO, DBG_INFO, fmt, ##arg)
771#define sms_debug(fmt, arg...) \
772 dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg)
773
774
775#endif /* __SMS_CORE_API_H__ */
diff --git a/drivers/media/usb/siano/smsdvb.c b/drivers/media/usb/siano/smsdvb.c
new file mode 100644
index 000000000000..aa77e54a8fae
--- /dev/null
+++ b/drivers/media/usb/siano/smsdvb.c
@@ -0,0 +1,1078 @@
1/****************************************************************
2
3Siano Mobile Silicon, Inc.
4MDTV receiver kernel modules.
5Copyright (C) 2006-2008, Uri Shkolnik
6
7This program is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the 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,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20****************************************************************/
21
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <linux/init.h>
25
26#include "dmxdev.h"
27#include "dvbdev.h"
28#include "dvb_demux.h"
29#include "dvb_frontend.h"
30
31#include "smscoreapi.h"
32#include "smsendian.h"
33#include "sms-cards.h"
34
35DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
36
37struct smsdvb_client_t {
38 struct list_head entry;
39
40 struct smscore_device_t *coredev;
41 struct smscore_client_t *smsclient;
42
43 struct dvb_adapter adapter;
44 struct dvb_demux demux;
45 struct dmxdev dmxdev;
46 struct dvb_frontend frontend;
47
48 fe_status_t fe_status;
49
50 struct completion tune_done;
51
52 struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb;
53 int event_fe_state;
54 int event_unc_state;
55};
56
57static struct list_head g_smsdvb_clients;
58static struct mutex g_smsdvb_clientslock;
59
60static int sms_dbg;
61module_param_named(debug, sms_dbg, int, 0644);
62MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
63
64/* Events that may come from DVB v3 adapter */
65static void sms_board_dvb3_event(struct smsdvb_client_t *client,
66 enum SMS_DVB3_EVENTS event) {
67
68 struct smscore_device_t *coredev = client->coredev;
69 switch (event) {
70 case DVB3_EVENT_INIT:
71 sms_debug("DVB3_EVENT_INIT");
72 sms_board_event(coredev, BOARD_EVENT_BIND);
73 break;
74 case DVB3_EVENT_SLEEP:
75 sms_debug("DVB3_EVENT_SLEEP");
76 sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND);
77 break;
78 case DVB3_EVENT_HOTPLUG:
79 sms_debug("DVB3_EVENT_HOTPLUG");
80 sms_board_event(coredev, BOARD_EVENT_POWER_INIT);
81 break;
82 case DVB3_EVENT_FE_LOCK:
83 if (client->event_fe_state != DVB3_EVENT_FE_LOCK) {
84 client->event_fe_state = DVB3_EVENT_FE_LOCK;
85 sms_debug("DVB3_EVENT_FE_LOCK");
86 sms_board_event(coredev, BOARD_EVENT_FE_LOCK);
87 }
88 break;
89 case DVB3_EVENT_FE_UNLOCK:
90 if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) {
91 client->event_fe_state = DVB3_EVENT_FE_UNLOCK;
92 sms_debug("DVB3_EVENT_FE_UNLOCK");
93 sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK);
94 }
95 break;
96 case DVB3_EVENT_UNC_OK:
97 if (client->event_unc_state != DVB3_EVENT_UNC_OK) {
98 client->event_unc_state = DVB3_EVENT_UNC_OK;
99 sms_debug("DVB3_EVENT_UNC_OK");
100 sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK);
101 }
102 break;
103 case DVB3_EVENT_UNC_ERR:
104 if (client->event_unc_state != DVB3_EVENT_UNC_ERR) {
105 client->event_unc_state = DVB3_EVENT_UNC_ERR;
106 sms_debug("DVB3_EVENT_UNC_ERR");
107 sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS);
108 }
109 break;
110
111 default:
112 sms_err("Unknown dvb3 api event");
113 break;
114 }
115}
116
117
118static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
119 struct SMSHOSTLIB_STATISTICS_ST *p)
120{
121 if (sms_dbg & 2) {
122 printk(KERN_DEBUG "Reserved = %d", p->Reserved);
123 printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
124 printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
125 printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
126 printk(KERN_DEBUG "SNR = %d", p->SNR);
127 printk(KERN_DEBUG "BER = %d", p->BER);
128 printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC);
129 printk(KERN_DEBUG "TS_PER = %d", p->TS_PER);
130 printk(KERN_DEBUG "MFER = %d", p->MFER);
131 printk(KERN_DEBUG "RSSI = %d", p->RSSI);
132 printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
133 printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
134 printk(KERN_DEBUG "Frequency = %d", p->Frequency);
135 printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
136 printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
137 printk(KERN_DEBUG "ModemState = %d", p->ModemState);
138 printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
139 printk(KERN_DEBUG "CodeRate = %d", p->CodeRate);
140 printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate);
141 printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy);
142 printk(KERN_DEBUG "Constellation = %d", p->Constellation);
143 printk(KERN_DEBUG "BurstSize = %d", p->BurstSize);
144 printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration);
145 printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime);
146 printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime);
147 printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows);
148 printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols);
149 printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols);
150 printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets);
151 printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets);
152 printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs);
153 printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs);
154 printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs);
155 printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount);
156 printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount);
157 printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
158 printk(KERN_DEBUG "PreBER = %d", p->PreBER);
159 printk(KERN_DEBUG "CellId = %d", p->CellId);
160 printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP);
161 printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP);
162 printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived);
163 }
164
165 pReceptionData->IsDemodLocked = p->IsDemodLocked;
166
167 pReceptionData->SNR = p->SNR;
168 pReceptionData->BER = p->BER;
169 pReceptionData->BERErrorCount = p->BERErrorCount;
170 pReceptionData->InBandPwr = p->InBandPwr;
171 pReceptionData->ErrorTSPackets = p->ErrorTSPackets;
172};
173
174
175static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
176 struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p)
177{
178 int i;
179
180 if (sms_dbg & 2) {
181 printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
182 printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
183 printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
184 printk(KERN_DEBUG "SNR = %d", p->SNR);
185 printk(KERN_DEBUG "RSSI = %d", p->RSSI);
186 printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
187 printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
188 printk(KERN_DEBUG "Frequency = %d", p->Frequency);
189 printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
190 printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
191 printk(KERN_DEBUG "ModemState = %d", p->ModemState);
192 printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
193 printk(KERN_DEBUG "SystemType = %d", p->SystemType);
194 printk(KERN_DEBUG "PartialReception = %d", p->PartialReception);
195 printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers);
196 printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
197
198 for (i = 0; i < 3; i++) {
199 printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate);
200 printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation);
201 printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER);
202 printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount);
203 printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount);
204 printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER);
205 printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER);
206 printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets);
207 printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets);
208 printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI);
209 printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments);
210 printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors);
211 }
212 }
213
214 pReceptionData->IsDemodLocked = p->IsDemodLocked;
215
216 pReceptionData->SNR = p->SNR;
217 pReceptionData->InBandPwr = p->InBandPwr;
218
219 pReceptionData->ErrorTSPackets = 0;
220 pReceptionData->BER = 0;
221 pReceptionData->BERErrorCount = 0;
222 for (i = 0; i < 3; i++) {
223 pReceptionData->BER += p->LayerInfo[i].BER;
224 pReceptionData->BERErrorCount += p->LayerInfo[i].BERErrorCount;
225 pReceptionData->ErrorTSPackets += p->LayerInfo[i].ErrorTSPackets;
226 }
227}
228
229static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
230{
231 struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
232 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p)
233 + cb->offset);
234 u32 *pMsgData = (u32 *) phdr + 1;
235 /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/
236 bool is_status_update = false;
237
238 smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr);
239
240 switch (phdr->msgType) {
241 case MSG_SMS_DVBT_BDA_DATA:
242 dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1),
243 cb->size - sizeof(struct SmsMsgHdr_ST));
244 break;
245
246 case MSG_SMS_RF_TUNE_RES:
247 case MSG_SMS_ISDBT_TUNE_RES:
248 complete(&client->tune_done);
249 break;
250
251 case MSG_SMS_SIGNAL_DETECTED_IND:
252 sms_info("MSG_SMS_SIGNAL_DETECTED_IND");
253 client->sms_stat_dvb.TransmissionData.IsDemodLocked = true;
254 is_status_update = true;
255 break;
256
257 case MSG_SMS_NO_SIGNAL_IND:
258 sms_info("MSG_SMS_NO_SIGNAL_IND");
259 client->sms_stat_dvb.TransmissionData.IsDemodLocked = false;
260 is_status_update = true;
261 break;
262
263 case MSG_SMS_TRANSMISSION_IND: {
264 sms_info("MSG_SMS_TRANSMISSION_IND");
265
266 pMsgData++;
267 memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData,
268 sizeof(struct TRANSMISSION_STATISTICS_S));
269
270 /* Mo need to correct guard interval
271 * (as opposed to old statistics message).
272 */
273 CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData);
274 CORRECT_STAT_TRANSMISSON_MODE(
275 client->sms_stat_dvb.TransmissionData);
276 is_status_update = true;
277 break;
278 }
279 case MSG_SMS_HO_PER_SLICES_IND: {
280 struct RECEPTION_STATISTICS_S *pReceptionData =
281 &client->sms_stat_dvb.ReceptionData;
282 struct SRVM_SIGNAL_STATUS_S SignalStatusData;
283
284 /*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/
285 pMsgData++;
286 SignalStatusData.result = pMsgData[0];
287 SignalStatusData.snr = pMsgData[1];
288 SignalStatusData.inBandPower = (s32) pMsgData[2];
289 SignalStatusData.tsPackets = pMsgData[3];
290 SignalStatusData.etsPackets = pMsgData[4];
291 SignalStatusData.constellation = pMsgData[5];
292 SignalStatusData.hpCode = pMsgData[6];
293 SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03;
294 SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03;
295 SignalStatusData.cellId = pMsgData[9] & 0xFFFF;
296 SignalStatusData.reason = pMsgData[10];
297 SignalStatusData.requestId = pMsgData[11];
298 pReceptionData->IsRfLocked = pMsgData[16];
299 pReceptionData->IsDemodLocked = pMsgData[17];
300 pReceptionData->ModemState = pMsgData[12];
301 pReceptionData->SNR = pMsgData[1];
302 pReceptionData->BER = pMsgData[13];
303 pReceptionData->RSSI = pMsgData[14];
304 CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData);
305
306 pReceptionData->InBandPwr = (s32) pMsgData[2];
307 pReceptionData->CarrierOffset = (s32) pMsgData[15];
308 pReceptionData->TotalTSPackets = pMsgData[3];
309 pReceptionData->ErrorTSPackets = pMsgData[4];
310
311 /* TS PER */
312 if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets)
313 > 0) {
314 pReceptionData->TS_PER = (SignalStatusData.etsPackets
315 * 100) / (SignalStatusData.tsPackets
316 + SignalStatusData.etsPackets);
317 } else {
318 pReceptionData->TS_PER = 0;
319 }
320
321 pReceptionData->BERBitCount = pMsgData[18];
322 pReceptionData->BERErrorCount = pMsgData[19];
323
324 pReceptionData->MRC_SNR = pMsgData[20];
325 pReceptionData->MRC_InBandPwr = pMsgData[21];
326 pReceptionData->MRC_RSSI = pMsgData[22];
327
328 is_status_update = true;
329 break;
330 }
331 case MSG_SMS_GET_STATISTICS_RES: {
332 union {
333 struct SMSHOSTLIB_STATISTICS_ISDBT_ST isdbt;
334 struct SmsMsgStatisticsInfo_ST dvb;
335 } *p = (void *) (phdr + 1);
336 struct RECEPTION_STATISTICS_S *pReceptionData =
337 &client->sms_stat_dvb.ReceptionData;
338
339 sms_info("MSG_SMS_GET_STATISTICS_RES");
340
341 is_status_update = true;
342
343 switch (smscore_get_device_mode(client->coredev)) {
344 case DEVICE_MODE_ISDBT:
345 case DEVICE_MODE_ISDBT_BDA:
346 smsdvb_update_isdbt_stats(pReceptionData, &p->isdbt);
347 break;
348 default:
349 smsdvb_update_dvb_stats(pReceptionData, &p->dvb.Stat);
350 }
351 if (!pReceptionData->IsDemodLocked) {
352 pReceptionData->SNR = 0;
353 pReceptionData->BER = 0;
354 pReceptionData->BERErrorCount = 0;
355 pReceptionData->InBandPwr = 0;
356 pReceptionData->ErrorTSPackets = 0;
357 }
358
359 complete(&client->tune_done);
360 break;
361 }
362 default:
363 sms_info("Unhandled message %d", phdr->msgType);
364
365 }
366 smscore_putbuffer(client->coredev, cb);
367
368 if (is_status_update) {
369 if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) {
370 client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER
371 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
372 sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK);
373 if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets
374 == 0)
375 sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK);
376 else
377 sms_board_dvb3_event(client,
378 DVB3_EVENT_UNC_ERR);
379
380 } else {
381 if (client->sms_stat_dvb.ReceptionData.IsRfLocked)
382 client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
383 else
384 client->fe_status = 0;
385 sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK);
386 }
387 }
388
389 return 0;
390}
391
392static void smsdvb_unregister_client(struct smsdvb_client_t *client)
393{
394 /* must be called under clientslock */
395
396 list_del(&client->entry);
397
398 smscore_unregister_client(client->smsclient);
399 dvb_unregister_frontend(&client->frontend);
400 dvb_dmxdev_release(&client->dmxdev);
401 dvb_dmx_release(&client->demux);
402 dvb_unregister_adapter(&client->adapter);
403 kfree(client);
404}
405
406static void smsdvb_onremove(void *context)
407{
408 kmutex_lock(&g_smsdvb_clientslock);
409
410 smsdvb_unregister_client((struct smsdvb_client_t *) context);
411
412 kmutex_unlock(&g_smsdvb_clientslock);
413}
414
415static int smsdvb_start_feed(struct dvb_demux_feed *feed)
416{
417 struct smsdvb_client_t *client =
418 container_of(feed->demux, struct smsdvb_client_t, demux);
419 struct SmsMsgData_ST PidMsg;
420
421 sms_debug("add pid %d(%x)",
422 feed->pid, feed->pid);
423
424 PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
425 PidMsg.xMsgHeader.msgDstId = HIF_TASK;
426 PidMsg.xMsgHeader.msgFlags = 0;
427 PidMsg.xMsgHeader.msgType = MSG_SMS_ADD_PID_FILTER_REQ;
428 PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
429 PidMsg.msgData[0] = feed->pid;
430
431 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
432 return smsclient_sendrequest(client->smsclient,
433 &PidMsg, sizeof(PidMsg));
434}
435
436static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
437{
438 struct smsdvb_client_t *client =
439 container_of(feed->demux, struct smsdvb_client_t, demux);
440 struct SmsMsgData_ST PidMsg;
441
442 sms_debug("remove pid %d(%x)",
443 feed->pid, feed->pid);
444
445 PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
446 PidMsg.xMsgHeader.msgDstId = HIF_TASK;
447 PidMsg.xMsgHeader.msgFlags = 0;
448 PidMsg.xMsgHeader.msgType = MSG_SMS_REMOVE_PID_FILTER_REQ;
449 PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
450 PidMsg.msgData[0] = feed->pid;
451
452 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
453 return smsclient_sendrequest(client->smsclient,
454 &PidMsg, sizeof(PidMsg));
455}
456
457static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
458 void *buffer, size_t size,
459 struct completion *completion)
460{
461 int rc;
462
463 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)buffer);
464 rc = smsclient_sendrequest(client->smsclient, buffer, size);
465 if (rc < 0)
466 return rc;
467
468 return wait_for_completion_timeout(completion,
469 msecs_to_jiffies(2000)) ?
470 0 : -ETIME;
471}
472
473static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
474{
475 int rc;
476 struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
477 DVBT_BDA_CONTROL_MSG_ID,
478 HIF_TASK,
479 sizeof(struct SmsMsgHdr_ST), 0 };
480
481 rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
482 &client->tune_done);
483
484 return rc;
485}
486
487static inline int led_feedback(struct smsdvb_client_t *client)
488{
489 if (client->fe_status & FE_HAS_LOCK)
490 return sms_board_led_feedback(client->coredev,
491 (client->sms_stat_dvb.ReceptionData.BER
492 == 0) ? SMS_LED_HI : SMS_LED_LO);
493 else
494 return sms_board_led_feedback(client->coredev, SMS_LED_OFF);
495}
496
497static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
498{
499 int rc;
500 struct smsdvb_client_t *client;
501 client = container_of(fe, struct smsdvb_client_t, frontend);
502
503 rc = smsdvb_send_statistics_request(client);
504
505 *stat = client->fe_status;
506
507 led_feedback(client);
508
509 return rc;
510}
511
512static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
513{
514 int rc;
515 struct smsdvb_client_t *client;
516 client = container_of(fe, struct smsdvb_client_t, frontend);
517
518 rc = smsdvb_send_statistics_request(client);
519
520 *ber = client->sms_stat_dvb.ReceptionData.BER;
521
522 led_feedback(client);
523
524 return rc;
525}
526
527static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
528{
529 int rc;
530
531 struct smsdvb_client_t *client;
532 client = container_of(fe, struct smsdvb_client_t, frontend);
533
534 rc = smsdvb_send_statistics_request(client);
535
536 if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95)
537 *strength = 0;
538 else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29)
539 *strength = 100;
540 else
541 *strength =
542 (client->sms_stat_dvb.ReceptionData.InBandPwr
543 + 95) * 3 / 2;
544
545 led_feedback(client);
546
547 return rc;
548}
549
550static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
551{
552 int rc;
553 struct smsdvb_client_t *client;
554 client = container_of(fe, struct smsdvb_client_t, frontend);
555
556 rc = smsdvb_send_statistics_request(client);
557
558 *snr = client->sms_stat_dvb.ReceptionData.SNR;
559
560 led_feedback(client);
561
562 return rc;
563}
564
565static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
566{
567 int rc;
568 struct smsdvb_client_t *client;
569 client = container_of(fe, struct smsdvb_client_t, frontend);
570
571 rc = smsdvb_send_statistics_request(client);
572
573 *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
574
575 led_feedback(client);
576
577 return rc;
578}
579
580static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
581 struct dvb_frontend_tune_settings *tune)
582{
583 sms_debug("");
584
585 tune->min_delay_ms = 400;
586 tune->step_size = 250000;
587 tune->max_drift = 0;
588 return 0;
589}
590
591static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe)
592{
593 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
594 struct smsdvb_client_t *client =
595 container_of(fe, struct smsdvb_client_t, frontend);
596
597 struct {
598 struct SmsMsgHdr_ST Msg;
599 u32 Data[3];
600 } Msg;
601
602 int ret;
603
604 client->fe_status = FE_HAS_SIGNAL;
605 client->event_fe_state = -1;
606 client->event_unc_state = -1;
607 fe->dtv_property_cache.delivery_system = SYS_DVBT;
608
609 Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
610 Msg.Msg.msgDstId = HIF_TASK;
611 Msg.Msg.msgFlags = 0;
612 Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ;
613 Msg.Msg.msgLength = sizeof(Msg);
614 Msg.Data[0] = c->frequency;
615 Msg.Data[2] = 12000000;
616
617 sms_info("%s: freq %d band %d", __func__, c->frequency,
618 c->bandwidth_hz);
619
620 switch (c->bandwidth_hz / 1000000) {
621 case 8:
622 Msg.Data[1] = BW_8_MHZ;
623 break;
624 case 7:
625 Msg.Data[1] = BW_7_MHZ;
626 break;
627 case 6:
628 Msg.Data[1] = BW_6_MHZ;
629 break;
630 case 0:
631 return -EOPNOTSUPP;
632 default:
633 return -EINVAL;
634 }
635 /* Disable LNA, if any. An error is returned if no LNA is present */
636 ret = sms_board_lna_control(client->coredev, 0);
637 if (ret == 0) {
638 fe_status_t status;
639
640 /* tune with LNA off at first */
641 ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
642 &client->tune_done);
643
644 smsdvb_read_status(fe, &status);
645
646 if (status & FE_HAS_LOCK)
647 return ret;
648
649 /* previous tune didn't lock - enable LNA and tune again */
650 sms_board_lna_control(client->coredev, 1);
651 }
652
653 return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
654 &client->tune_done);
655}
656
657static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe)
658{
659 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
660 struct smsdvb_client_t *client =
661 container_of(fe, struct smsdvb_client_t, frontend);
662
663 struct {
664 struct SmsMsgHdr_ST Msg;
665 u32 Data[4];
666 } Msg;
667
668 fe->dtv_property_cache.delivery_system = SYS_ISDBT;
669
670 Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
671 Msg.Msg.msgDstId = HIF_TASK;
672 Msg.Msg.msgFlags = 0;
673 Msg.Msg.msgType = MSG_SMS_ISDBT_TUNE_REQ;
674 Msg.Msg.msgLength = sizeof(Msg);
675
676 if (c->isdbt_sb_segment_idx == -1)
677 c->isdbt_sb_segment_idx = 0;
678
679 switch (c->isdbt_sb_segment_count) {
680 case 3:
681 Msg.Data[1] = BW_ISDBT_3SEG;
682 break;
683 case 1:
684 Msg.Data[1] = BW_ISDBT_1SEG;
685 break;
686 case 0: /* AUTO */
687 switch (c->bandwidth_hz / 1000000) {
688 case 8:
689 case 7:
690 c->isdbt_sb_segment_count = 3;
691 Msg.Data[1] = BW_ISDBT_3SEG;
692 break;
693 case 6:
694 c->isdbt_sb_segment_count = 1;
695 Msg.Data[1] = BW_ISDBT_1SEG;
696 break;
697 default: /* Assumes 6 MHZ bw */
698 c->isdbt_sb_segment_count = 1;
699 c->bandwidth_hz = 6000;
700 Msg.Data[1] = BW_ISDBT_1SEG;
701 break;
702 }
703 break;
704 default:
705 sms_info("Segment count %d not supported", c->isdbt_sb_segment_count);
706 return -EINVAL;
707 }
708
709 Msg.Data[0] = c->frequency;
710 Msg.Data[2] = 12000000;
711 Msg.Data[3] = c->isdbt_sb_segment_idx;
712
713 sms_info("%s: freq %d segwidth %d segindex %d\n", __func__,
714 c->frequency, c->isdbt_sb_segment_count,
715 c->isdbt_sb_segment_idx);
716
717 return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
718 &client->tune_done);
719}
720
721static int smsdvb_set_frontend(struct dvb_frontend *fe)
722{
723 struct smsdvb_client_t *client =
724 container_of(fe, struct smsdvb_client_t, frontend);
725 struct smscore_device_t *coredev = client->coredev;
726
727 switch (smscore_get_device_mode(coredev)) {
728 case DEVICE_MODE_DVBT:
729 case DEVICE_MODE_DVBT_BDA:
730 return smsdvb_dvbt_set_frontend(fe);
731 case DEVICE_MODE_ISDBT:
732 case DEVICE_MODE_ISDBT_BDA:
733 return smsdvb_isdbt_set_frontend(fe);
734 default:
735 return -EINVAL;
736 }
737}
738
739static int smsdvb_get_frontend(struct dvb_frontend *fe)
740{
741 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
742 struct smsdvb_client_t *client =
743 container_of(fe, struct smsdvb_client_t, frontend);
744 struct smscore_device_t *coredev = client->coredev;
745 struct TRANSMISSION_STATISTICS_S *td =
746 &client->sms_stat_dvb.TransmissionData;
747
748 switch (smscore_get_device_mode(coredev)) {
749 case DEVICE_MODE_DVBT:
750 case DEVICE_MODE_DVBT_BDA:
751 fep->frequency = td->Frequency;
752
753 switch (td->Bandwidth) {
754 case 6:
755 fep->bandwidth_hz = 6000000;
756 break;
757 case 7:
758 fep->bandwidth_hz = 7000000;
759 break;
760 case 8:
761 fep->bandwidth_hz = 8000000;
762 break;
763 }
764
765 switch (td->TransmissionMode) {
766 case 2:
767 fep->transmission_mode = TRANSMISSION_MODE_2K;
768 break;
769 case 8:
770 fep->transmission_mode = TRANSMISSION_MODE_8K;
771 }
772
773 switch (td->GuardInterval) {
774 case 0:
775 fep->guard_interval = GUARD_INTERVAL_1_32;
776 break;
777 case 1:
778 fep->guard_interval = GUARD_INTERVAL_1_16;
779 break;
780 case 2:
781 fep->guard_interval = GUARD_INTERVAL_1_8;
782 break;
783 case 3:
784 fep->guard_interval = GUARD_INTERVAL_1_4;
785 break;
786 }
787
788 switch (td->CodeRate) {
789 case 0:
790 fep->code_rate_HP = FEC_1_2;
791 break;
792 case 1:
793 fep->code_rate_HP = FEC_2_3;
794 break;
795 case 2:
796 fep->code_rate_HP = FEC_3_4;
797 break;
798 case 3:
799 fep->code_rate_HP = FEC_5_6;
800 break;
801 case 4:
802 fep->code_rate_HP = FEC_7_8;
803 break;
804 }
805
806 switch (td->LPCodeRate) {
807 case 0:
808 fep->code_rate_LP = FEC_1_2;
809 break;
810 case 1:
811 fep->code_rate_LP = FEC_2_3;
812 break;
813 case 2:
814 fep->code_rate_LP = FEC_3_4;
815 break;
816 case 3:
817 fep->code_rate_LP = FEC_5_6;
818 break;
819 case 4:
820 fep->code_rate_LP = FEC_7_8;
821 break;
822 }
823
824 switch (td->Constellation) {
825 case 0:
826 fep->modulation = QPSK;
827 break;
828 case 1:
829 fep->modulation = QAM_16;
830 break;
831 case 2:
832 fep->modulation = QAM_64;
833 break;
834 }
835
836 switch (td->Hierarchy) {
837 case 0:
838 fep->hierarchy = HIERARCHY_NONE;
839 break;
840 case 1:
841 fep->hierarchy = HIERARCHY_1;
842 break;
843 case 2:
844 fep->hierarchy = HIERARCHY_2;
845 break;
846 case 3:
847 fep->hierarchy = HIERARCHY_4;
848 break;
849 }
850
851 fep->inversion = INVERSION_AUTO;
852 break;
853 case DEVICE_MODE_ISDBT:
854 case DEVICE_MODE_ISDBT_BDA:
855 fep->frequency = td->Frequency;
856 fep->bandwidth_hz = 6000000;
857 /* todo: retrive the other parameters */
858 break;
859 default:
860 return -EINVAL;
861 }
862
863 return 0;
864}
865
866static int smsdvb_init(struct dvb_frontend *fe)
867{
868 struct smsdvb_client_t *client =
869 container_of(fe, struct smsdvb_client_t, frontend);
870
871 sms_board_power(client->coredev, 1);
872
873 sms_board_dvb3_event(client, DVB3_EVENT_INIT);
874 return 0;
875}
876
877static int smsdvb_sleep(struct dvb_frontend *fe)
878{
879 struct smsdvb_client_t *client =
880 container_of(fe, struct smsdvb_client_t, frontend);
881
882 sms_board_led_feedback(client->coredev, SMS_LED_OFF);
883 sms_board_power(client->coredev, 0);
884
885 sms_board_dvb3_event(client, DVB3_EVENT_SLEEP);
886
887 return 0;
888}
889
890static void smsdvb_release(struct dvb_frontend *fe)
891{
892 /* do nothing */
893}
894
895static struct dvb_frontend_ops smsdvb_fe_ops = {
896 .info = {
897 .name = "Siano Mobile Digital MDTV Receiver",
898 .frequency_min = 44250000,
899 .frequency_max = 867250000,
900 .frequency_stepsize = 250000,
901 .caps = FE_CAN_INVERSION_AUTO |
902 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
903 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
904 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
905 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
906 FE_CAN_GUARD_INTERVAL_AUTO |
907 FE_CAN_RECOVER |
908 FE_CAN_HIERARCHY_AUTO,
909 },
910
911 .release = smsdvb_release,
912
913 .set_frontend = smsdvb_set_frontend,
914 .get_frontend = smsdvb_get_frontend,
915 .get_tune_settings = smsdvb_get_tune_settings,
916
917 .read_status = smsdvb_read_status,
918 .read_ber = smsdvb_read_ber,
919 .read_signal_strength = smsdvb_read_signal_strength,
920 .read_snr = smsdvb_read_snr,
921 .read_ucblocks = smsdvb_read_ucblocks,
922
923 .init = smsdvb_init,
924 .sleep = smsdvb_sleep,
925};
926
927static int smsdvb_hotplug(struct smscore_device_t *coredev,
928 struct device *device, int arrival)
929{
930 struct smsclient_params_t params;
931 struct smsdvb_client_t *client;
932 int rc;
933
934 /* device removal handled by onremove callback */
935 if (!arrival)
936 return 0;
937 client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
938 if (!client) {
939 sms_err("kmalloc() failed");
940 return -ENOMEM;
941 }
942
943 /* register dvb adapter */
944 rc = dvb_register_adapter(&client->adapter,
945 sms_get_board(
946 smscore_get_board_id(coredev))->name,
947 THIS_MODULE, device, adapter_nr);
948 if (rc < 0) {
949 sms_err("dvb_register_adapter() failed %d", rc);
950 goto adapter_error;
951 }
952
953 /* init dvb demux */
954 client->demux.dmx.capabilities = DMX_TS_FILTERING;
955 client->demux.filternum = 32; /* todo: nova ??? */
956 client->demux.feednum = 32;
957 client->demux.start_feed = smsdvb_start_feed;
958 client->demux.stop_feed = smsdvb_stop_feed;
959
960 rc = dvb_dmx_init(&client->demux);
961 if (rc < 0) {
962 sms_err("dvb_dmx_init failed %d", rc);
963 goto dvbdmx_error;
964 }
965
966 /* init dmxdev */
967 client->dmxdev.filternum = 32;
968 client->dmxdev.demux = &client->demux.dmx;
969 client->dmxdev.capabilities = 0;
970
971 rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
972 if (rc < 0) {
973 sms_err("dvb_dmxdev_init failed %d", rc);
974 goto dmxdev_error;
975 }
976
977 /* init and register frontend */
978 memcpy(&client->frontend.ops, &smsdvb_fe_ops,
979 sizeof(struct dvb_frontend_ops));
980
981 switch (smscore_get_device_mode(coredev)) {
982 case DEVICE_MODE_DVBT:
983 case DEVICE_MODE_DVBT_BDA:
984 client->frontend.ops.delsys[0] = SYS_DVBT;
985 break;
986 case DEVICE_MODE_ISDBT:
987 case DEVICE_MODE_ISDBT_BDA:
988 client->frontend.ops.delsys[0] = SYS_ISDBT;
989 break;
990 }
991
992 rc = dvb_register_frontend(&client->adapter, &client->frontend);
993 if (rc < 0) {
994 sms_err("frontend registration failed %d", rc);
995 goto frontend_error;
996 }
997
998 params.initial_id = 1;
999 params.data_type = MSG_SMS_DVBT_BDA_DATA;
1000 params.onresponse_handler = smsdvb_onresponse;
1001 params.onremove_handler = smsdvb_onremove;
1002 params.context = client;
1003
1004 rc = smscore_register_client(coredev, &params, &client->smsclient);
1005 if (rc < 0) {
1006 sms_err("smscore_register_client() failed %d", rc);
1007 goto client_error;
1008 }
1009
1010 client->coredev = coredev;
1011
1012 init_completion(&client->tune_done);
1013
1014 kmutex_lock(&g_smsdvb_clientslock);
1015
1016 list_add(&client->entry, &g_smsdvb_clients);
1017
1018 kmutex_unlock(&g_smsdvb_clientslock);
1019
1020 client->event_fe_state = -1;
1021 client->event_unc_state = -1;
1022 sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
1023
1024 sms_info("success");
1025 sms_board_setup(coredev);
1026
1027 return 0;
1028
1029client_error:
1030 dvb_unregister_frontend(&client->frontend);
1031
1032frontend_error:
1033 dvb_dmxdev_release(&client->dmxdev);
1034
1035dmxdev_error:
1036 dvb_dmx_release(&client->demux);
1037
1038dvbdmx_error:
1039 dvb_unregister_adapter(&client->adapter);
1040
1041adapter_error:
1042 kfree(client);
1043 return rc;
1044}
1045
1046static int __init smsdvb_module_init(void)
1047{
1048 int rc;
1049
1050 INIT_LIST_HEAD(&g_smsdvb_clients);
1051 kmutex_init(&g_smsdvb_clientslock);
1052
1053 rc = smscore_register_hotplug(smsdvb_hotplug);
1054
1055 sms_debug("");
1056
1057 return rc;
1058}
1059
1060static void __exit smsdvb_module_exit(void)
1061{
1062 smscore_unregister_hotplug(smsdvb_hotplug);
1063
1064 kmutex_lock(&g_smsdvb_clientslock);
1065
1066 while (!list_empty(&g_smsdvb_clients))
1067 smsdvb_unregister_client(
1068 (struct smsdvb_client_t *) g_smsdvb_clients.next);
1069
1070 kmutex_unlock(&g_smsdvb_clientslock);
1071}
1072
1073module_init(smsdvb_module_init);
1074module_exit(smsdvb_module_exit);
1075
1076MODULE_DESCRIPTION("SMS DVB subsystem adaptation module");
1077MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
1078MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/siano/smsendian.c b/drivers/media/usb/siano/smsendian.c
new file mode 100644
index 000000000000..e2657c2f0109
--- /dev/null
+++ b/drivers/media/usb/siano/smsendian.c
@@ -0,0 +1,103 @@
1/****************************************************************
2
3 Siano Mobile Silicon, Inc.
4 MDTV receiver kernel modules.
5 Copyright (C) 2006-2009, Uri Shkolnik
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, see <http://www.gnu.org/licenses/>.
19
20 ****************************************************************/
21
22#include <linux/export.h>
23#include <asm/byteorder.h>
24
25#include "smsendian.h"
26#include "smscoreapi.h"
27
28void smsendian_handle_tx_message(void *buffer)
29{
30#ifdef __BIG_ENDIAN
31 struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
32 int i;
33 int msgWords;
34
35 switch (msg->xMsgHeader.msgType) {
36 case MSG_SMS_DATA_DOWNLOAD_REQ:
37 {
38 msg->msgData[0] = le32_to_cpu(msg->msgData[0]);
39 break;
40 }
41
42 default:
43 msgWords = (msg->xMsgHeader.msgLength -
44 sizeof(struct SmsMsgHdr_ST))/4;
45
46 for (i = 0; i < msgWords; i++)
47 msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
48
49 break;
50 }
51#endif /* __BIG_ENDIAN */
52}
53EXPORT_SYMBOL_GPL(smsendian_handle_tx_message);
54
55void smsendian_handle_rx_message(void *buffer)
56{
57#ifdef __BIG_ENDIAN
58 struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
59 int i;
60 int msgWords;
61
62 switch (msg->xMsgHeader.msgType) {
63 case MSG_SMS_GET_VERSION_EX_RES:
64 {
65 struct SmsVersionRes_ST *ver =
66 (struct SmsVersionRes_ST *) msg;
67 ver->ChipModel = le16_to_cpu(ver->ChipModel);
68 break;
69 }
70
71 case MSG_SMS_DVBT_BDA_DATA:
72 case MSG_SMS_DAB_CHANNEL:
73 case MSG_SMS_DATA_MSG:
74 {
75 break;
76 }
77
78 default:
79 {
80 msgWords = (msg->xMsgHeader.msgLength -
81 sizeof(struct SmsMsgHdr_ST))/4;
82
83 for (i = 0; i < msgWords; i++)
84 msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
85
86 break;
87 }
88 }
89#endif /* __BIG_ENDIAN */
90}
91EXPORT_SYMBOL_GPL(smsendian_handle_rx_message);
92
93void smsendian_handle_message_header(void *msg)
94{
95#ifdef __BIG_ENDIAN
96 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)msg;
97
98 phdr->msgType = le16_to_cpu(phdr->msgType);
99 phdr->msgLength = le16_to_cpu(phdr->msgLength);
100 phdr->msgFlags = le16_to_cpu(phdr->msgFlags);
101#endif /* __BIG_ENDIAN */
102}
103EXPORT_SYMBOL_GPL(smsendian_handle_message_header);
diff --git a/drivers/media/usb/siano/smsendian.h b/drivers/media/usb/siano/smsendian.h
new file mode 100644
index 000000000000..1624d6fd367b
--- /dev/null
+++ b/drivers/media/usb/siano/smsendian.h
@@ -0,0 +1,32 @@
1/****************************************************************
2
3Siano Mobile Silicon, Inc.
4MDTV receiver kernel modules.
5Copyright (C) 2006-2009, Uri Shkolnik
6
7This program is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the 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,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20****************************************************************/
21
22#ifndef __SMS_ENDIAN_H__
23#define __SMS_ENDIAN_H__
24
25#include <asm/byteorder.h>
26
27extern void smsendian_handle_tx_message(void *buffer);
28extern void smsendian_handle_rx_message(void *buffer);
29extern void smsendian_handle_message_header(void *msg);
30
31#endif /* __SMS_ENDIAN_H__ */
32
diff --git a/drivers/media/usb/siano/smsir.c b/drivers/media/usb/siano/smsir.c
new file mode 100644
index 000000000000..37bc5c4b8ad8
--- /dev/null
+++ b/drivers/media/usb/siano/smsir.c
@@ -0,0 +1,114 @@
1/****************************************************************
2
3 Siano Mobile Silicon, Inc.
4 MDTV receiver kernel modules.
5 Copyright (C) 2006-2009, Uri Shkolnik
6
7 Copyright (c) 2010 - Mauro Carvalho Chehab
8 - Ported the driver to use rc-core
9 - IR raw event decoding is now done at rc-core
10 - Code almost re-written
11
12 This program is free software: you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation, either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
24
25 ****************************************************************/
26
27
28#include <linux/types.h>
29#include <linux/input.h>
30
31#include "smscoreapi.h"
32#include "smsir.h"
33#include "sms-cards.h"
34
35#define MODULE_NAME "smsmdtv"
36
37void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
38{
39 int i;
40 const s32 *samples = (const void *)buf;
41
42 for (i = 0; i < len >> 2; i++) {
43 DEFINE_IR_RAW_EVENT(ev);
44
45 ev.duration = abs(samples[i]) * 1000; /* Convert to ns */
46 ev.pulse = (samples[i] > 0) ? false : true;
47
48 ir_raw_event_store(coredev->ir.dev, &ev);
49 }
50 ir_raw_event_handle(coredev->ir.dev);
51}
52
53int sms_ir_init(struct smscore_device_t *coredev)
54{
55 int err;
56 int board_id = smscore_get_board_id(coredev);
57 struct rc_dev *dev;
58
59 sms_log("Allocating rc device");
60 dev = rc_allocate_device();
61 if (!dev) {
62 sms_err("Not enough memory");
63 return -ENOMEM;
64 }
65
66 coredev->ir.controller = 0; /* Todo: vega/nova SPI number */
67 coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
68 sms_log("IR port %d, timeout %d ms",
69 coredev->ir.controller, coredev->ir.timeout);
70
71 snprintf(coredev->ir.name, sizeof(coredev->ir.name),
72 "SMS IR (%s)", sms_get_board(board_id)->name);
73
74 strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
75 strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));
76
77 dev->input_name = coredev->ir.name;
78 dev->input_phys = coredev->ir.phys;
79 dev->dev.parent = coredev->device;
80
81#if 0
82 /* TODO: properly initialize the parameters bellow */
83 dev->input_id.bustype = BUS_USB;
84 dev->input_id.version = 1;
85 dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
86 dev->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
87#endif
88
89 dev->priv = coredev;
90 dev->driver_type = RC_DRIVER_IR_RAW;
91 dev->allowed_protos = RC_TYPE_ALL;
92 dev->map_name = sms_get_board(board_id)->rc_codes;
93 dev->driver_name = MODULE_NAME;
94
95 sms_log("Input device (IR) %s is set for key events", dev->input_name);
96
97 err = rc_register_device(dev);
98 if (err < 0) {
99 sms_err("Failed to register device");
100 rc_free_device(dev);
101 return err;
102 }
103
104 coredev->ir.dev = dev;
105 return 0;
106}
107
108void sms_ir_exit(struct smscore_device_t *coredev)
109{
110 if (coredev->ir.dev)
111 rc_unregister_device(coredev->ir.dev);
112
113 sms_log("");
114}
diff --git a/drivers/media/usb/siano/smsir.h b/drivers/media/usb/siano/smsir.h
new file mode 100644
index 000000000000..ae92b3a8587e
--- /dev/null
+++ b/drivers/media/usb/siano/smsir.h
@@ -0,0 +1,55 @@
1/****************************************************************
2
3Siano Mobile Silicon, Inc.
4MDTV receiver kernel modules.
5Copyright (C) 2006-2009, Uri Shkolnik
6
7 Copyright (c) 2010 - Mauro Carvalho Chehab
8 - Ported the driver to use rc-core
9 - IR raw event decoding is now done at rc-core
10 - Code almost re-written
11
12This program is free software: you can redistribute it and/or modify
13it under the terms of the GNU General Public License as published by
14the Free Software Foundation, either version 2 of the License, or
15(at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with this program. If not, see <http://www.gnu.org/licenses/>.
24
25****************************************************************/
26
27#ifndef __SMS_IR_H__
28#define __SMS_IR_H__
29
30#include <linux/input.h>
31#include <media/rc-core.h>
32
33#define IR_DEFAULT_TIMEOUT 100
34
35struct smscore_device_t;
36
37struct ir_t {
38 struct rc_dev *dev;
39 char name[40];
40 char phys[32];
41
42 char *rc_codes;
43 u64 protocol;
44
45 u32 timeout;
46 u32 controller;
47};
48
49int sms_ir_init(struct smscore_device_t *coredev);
50void sms_ir_exit(struct smscore_device_t *coredev);
51void sms_ir_event(struct smscore_device_t *coredev,
52 const char *buf, int len);
53
54#endif /* __SMS_IR_H__ */
55
diff --git a/drivers/media/usb/siano/smssdio.c b/drivers/media/usb/siano/smssdio.c
new file mode 100644
index 000000000000..d6f3f100699a
--- /dev/null
+++ b/drivers/media/usb/siano/smssdio.c
@@ -0,0 +1,365 @@
1/*
2 * smssdio.c - Siano 1xxx SDIO interface driver
3 *
4 * Copyright 2008 Pierre Ossman
5 *
6 * Based on code by Siano Mobile Silicon, Inc.,
7 * Copyright (C) 2006-2008, Uri Shkolnik
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 (at
12 * your option) any later version.
13 *
14 *
15 * This hardware is a bit odd in that all transfers should be done
16 * to/from the SMSSDIO_DATA register, yet the "increase address" bit
17 * always needs to be set.
18 *
19 * Also, buffers from the card are always aligned to 128 byte
20 * boundaries.
21 */
22
23/*
24 * General cleanup notes:
25 *
26 * - only typedefs should be name *_t
27 *
28 * - use ERR_PTR and friends for smscore_register_device()
29 *
30 * - smscore_getbuffer should zero fields
31 *
32 * Fix stop command
33 */
34
35#include <linux/moduleparam.h>
36#include <linux/slab.h>
37#include <linux/firmware.h>
38#include <linux/delay.h>
39#include <linux/mmc/card.h>
40#include <linux/mmc/sdio_func.h>
41#include <linux/mmc/sdio_ids.h>
42#include <linux/module.h>
43
44#include "smscoreapi.h"
45#include "sms-cards.h"
46
47/* Registers */
48
49#define SMSSDIO_DATA 0x00
50#define SMSSDIO_INT 0x04
51#define SMSSDIO_BLOCK_SIZE 128
52
53static const struct sdio_device_id smssdio_ids[] __devinitconst = {
54 {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR),
55 .driver_data = SMS1XXX_BOARD_SIANO_STELLAR},
56 {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0),
57 .driver_data = SMS1XXX_BOARD_SIANO_NOVA_A},
58 {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_B0),
59 .driver_data = SMS1XXX_BOARD_SIANO_NOVA_B},
60 {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VEGA_A0),
61 .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
62 {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VENICE),
63 .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
64 { /* end: all zeroes */ },
65};
66
67MODULE_DEVICE_TABLE(sdio, smssdio_ids);
68
69struct smssdio_device {
70 struct sdio_func *func;
71
72 struct smscore_device_t *coredev;
73
74 struct smscore_buffer_t *split_cb;
75};
76
77/*******************************************************************/
78/* Siano core callbacks */
79/*******************************************************************/
80
81static int smssdio_sendrequest(void *context, void *buffer, size_t size)
82{
83 int ret = 0;
84 struct smssdio_device *smsdev;
85
86 smsdev = context;
87
88 sdio_claim_host(smsdev->func);
89
90 while (size >= smsdev->func->cur_blksize) {
91 ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
92 buffer, smsdev->func->cur_blksize);
93 if (ret)
94 goto out;
95
96 buffer += smsdev->func->cur_blksize;
97 size -= smsdev->func->cur_blksize;
98 }
99
100 if (size) {
101 ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
102 buffer, size);
103 }
104
105out:
106 sdio_release_host(smsdev->func);
107
108 return ret;
109}
110
111/*******************************************************************/
112/* SDIO callbacks */
113/*******************************************************************/
114
115static void smssdio_interrupt(struct sdio_func *func)
116{
117 int ret;
118
119 struct smssdio_device *smsdev;
120 struct smscore_buffer_t *cb;
121 struct SmsMsgHdr_ST *hdr;
122 size_t size;
123
124 smsdev = sdio_get_drvdata(func);
125
126 /*
127 * The interrupt register has no defined meaning. It is just
128 * a way of turning of the level triggered interrupt.
129 */
130 (void)sdio_readb(func, SMSSDIO_INT, &ret);
131 if (ret) {
132 sms_err("Unable to read interrupt register!\n");
133 return;
134 }
135
136 if (smsdev->split_cb == NULL) {
137 cb = smscore_getbuffer(smsdev->coredev);
138 if (!cb) {
139 sms_err("Unable to allocate data buffer!\n");
140 return;
141 }
142
143 ret = sdio_memcpy_fromio(smsdev->func,
144 cb->p,
145 SMSSDIO_DATA,
146 SMSSDIO_BLOCK_SIZE);
147 if (ret) {
148 sms_err("Error %d reading initial block!\n", ret);
149 return;
150 }
151
152 hdr = cb->p;
153
154 if (hdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG) {
155 smsdev->split_cb = cb;
156 return;
157 }
158
159 if (hdr->msgLength > smsdev->func->cur_blksize)
160 size = hdr->msgLength - smsdev->func->cur_blksize;
161 else
162 size = 0;
163 } else {
164 cb = smsdev->split_cb;
165 hdr = cb->p;
166
167 size = hdr->msgLength - sizeof(struct SmsMsgHdr_ST);
168
169 smsdev->split_cb = NULL;
170 }
171
172 if (size) {
173 void *buffer;
174
175 buffer = cb->p + (hdr->msgLength - size);
176 size = ALIGN(size, SMSSDIO_BLOCK_SIZE);
177
178 BUG_ON(smsdev->func->cur_blksize != SMSSDIO_BLOCK_SIZE);
179
180 /*
181 * First attempt to transfer all of it in one go...
182 */
183 ret = sdio_memcpy_fromio(smsdev->func,
184 buffer,
185 SMSSDIO_DATA,
186 size);
187 if (ret && ret != -EINVAL) {
188 smscore_putbuffer(smsdev->coredev, cb);
189 sms_err("Error %d reading data from card!\n", ret);
190 return;
191 }
192
193 /*
194 * ..then fall back to one block at a time if that is
195 * not possible...
196 *
197 * (we have to do this manually because of the
198 * problem with the "increase address" bit)
199 */
200 if (ret == -EINVAL) {
201 while (size) {
202 ret = sdio_memcpy_fromio(smsdev->func,
203 buffer, SMSSDIO_DATA,
204 smsdev->func->cur_blksize);
205 if (ret) {
206 smscore_putbuffer(smsdev->coredev, cb);
207 sms_err("Error %d reading "
208 "data from card!\n", ret);
209 return;
210 }
211
212 buffer += smsdev->func->cur_blksize;
213 if (size > smsdev->func->cur_blksize)
214 size -= smsdev->func->cur_blksize;
215 else
216 size = 0;
217 }
218 }
219 }
220
221 cb->size = hdr->msgLength;
222 cb->offset = 0;
223
224 smscore_onresponse(smsdev->coredev, cb);
225}
226
227static int __devinit smssdio_probe(struct sdio_func *func,
228 const struct sdio_device_id *id)
229{
230 int ret;
231
232 int board_id;
233 struct smssdio_device *smsdev;
234 struct smsdevice_params_t params;
235
236 board_id = id->driver_data;
237
238 smsdev = kzalloc(sizeof(struct smssdio_device), GFP_KERNEL);
239 if (!smsdev)
240 return -ENOMEM;
241
242 smsdev->func = func;
243
244 memset(&params, 0, sizeof(struct smsdevice_params_t));
245
246 params.device = &func->dev;
247 params.buffer_size = 0x5000; /* ?? */
248 params.num_buffers = 22; /* ?? */
249 params.context = smsdev;
250
251 snprintf(params.devpath, sizeof(params.devpath),
252 "sdio\\%s", sdio_func_id(func));
253
254 params.sendrequest_handler = smssdio_sendrequest;
255
256 params.device_type = sms_get_board(board_id)->type;
257
258 if (params.device_type != SMS_STELLAR)
259 params.flags |= SMS_DEVICE_FAMILY2;
260 else {
261 /*
262 * FIXME: Stellar needs special handling...
263 */
264 ret = -ENODEV;
265 goto free;
266 }
267
268 ret = smscore_register_device(&params, &smsdev->coredev);
269 if (ret < 0)
270 goto free;
271
272 smscore_set_board_id(smsdev->coredev, board_id);
273
274 sdio_claim_host(func);
275
276 ret = sdio_enable_func(func);
277 if (ret)
278 goto release;
279
280 ret = sdio_set_block_size(func, SMSSDIO_BLOCK_SIZE);
281 if (ret)
282 goto disable;
283
284 ret = sdio_claim_irq(func, smssdio_interrupt);
285 if (ret)
286 goto disable;
287
288 sdio_set_drvdata(func, smsdev);
289
290 sdio_release_host(func);
291
292 ret = smscore_start_device(smsdev->coredev);
293 if (ret < 0)
294 goto reclaim;
295
296 return 0;
297
298reclaim:
299 sdio_claim_host(func);
300 sdio_release_irq(func);
301disable:
302 sdio_disable_func(func);
303release:
304 sdio_release_host(func);
305 smscore_unregister_device(smsdev->coredev);
306free:
307 kfree(smsdev);
308
309 return ret;
310}
311
312static void smssdio_remove(struct sdio_func *func)
313{
314 struct smssdio_device *smsdev;
315
316 smsdev = sdio_get_drvdata(func);
317
318 /* FIXME: racy! */
319 if (smsdev->split_cb)
320 smscore_putbuffer(smsdev->coredev, smsdev->split_cb);
321
322 smscore_unregister_device(smsdev->coredev);
323
324 sdio_claim_host(func);
325 sdio_release_irq(func);
326 sdio_disable_func(func);
327 sdio_release_host(func);
328
329 kfree(smsdev);
330}
331
332static struct sdio_driver smssdio_driver = {
333 .name = "smssdio",
334 .id_table = smssdio_ids,
335 .probe = smssdio_probe,
336 .remove = smssdio_remove,
337};
338
339/*******************************************************************/
340/* Module functions */
341/*******************************************************************/
342
343static int __init smssdio_module_init(void)
344{
345 int ret = 0;
346
347 printk(KERN_INFO "smssdio: Siano SMS1xxx SDIO driver\n");
348 printk(KERN_INFO "smssdio: Copyright Pierre Ossman\n");
349
350 ret = sdio_register_driver(&smssdio_driver);
351
352 return ret;
353}
354
355static void __exit smssdio_module_exit(void)
356{
357 sdio_unregister_driver(&smssdio_driver);
358}
359
360module_init(smssdio_module_init);
361module_exit(smssdio_module_exit);
362
363MODULE_DESCRIPTION("Siano SMS1xxx SDIO driver");
364MODULE_AUTHOR("Pierre Ossman");
365MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c
new file mode 100644
index 000000000000..664e460f247b
--- /dev/null
+++ b/drivers/media/usb/siano/smsusb.c
@@ -0,0 +1,568 @@
1/****************************************************************
2
3Siano Mobile Silicon, Inc.
4MDTV receiver kernel modules.
5Copyright (C) 2005-2009, Uri Shkolnik, Anatoly Greenblat
6
7This program is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the 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,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20****************************************************************/
21
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/usb.h>
25#include <linux/firmware.h>
26#include <linux/slab.h>
27#include <linux/module.h>
28
29#include "smscoreapi.h"
30#include "sms-cards.h"
31#include "smsendian.h"
32
33static int sms_dbg;
34module_param_named(debug, sms_dbg, int, 0644);
35MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
36
37#define USB1_BUFFER_SIZE 0x1000
38#define USB2_BUFFER_SIZE 0x4000
39
40#define MAX_BUFFERS 50
41#define MAX_URBS 10
42
43struct smsusb_device_t;
44
45struct smsusb_urb_t {
46 struct smscore_buffer_t *cb;
47 struct smsusb_device_t *dev;
48
49 struct urb urb;
50};
51
52struct smsusb_device_t {
53 struct usb_device *udev;
54 struct smscore_device_t *coredev;
55
56 struct smsusb_urb_t surbs[MAX_URBS];
57
58 int response_alignment;
59 int buffer_size;
60};
61
62static int smsusb_submit_urb(struct smsusb_device_t *dev,
63 struct smsusb_urb_t *surb);
64
65static void smsusb_onresponse(struct urb *urb)
66{
67 struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context;
68 struct smsusb_device_t *dev = surb->dev;
69
70 if (urb->status == -ESHUTDOWN) {
71 sms_err("error, urb status %d (-ESHUTDOWN), %d bytes",
72 urb->status, urb->actual_length);
73 return;
74 }
75
76 if ((urb->actual_length > 0) && (urb->status == 0)) {
77 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)surb->cb->p;
78
79 smsendian_handle_message_header(phdr);
80 if (urb->actual_length >= phdr->msgLength) {
81 surb->cb->size = phdr->msgLength;
82
83 if (dev->response_alignment &&
84 (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG)) {
85
86 surb->cb->offset =
87 dev->response_alignment +
88 ((phdr->msgFlags >> 8) & 3);
89
90 /* sanity check */
91 if (((int) phdr->msgLength +
92 surb->cb->offset) > urb->actual_length) {
93 sms_err("invalid response "
94 "msglen %d offset %d "
95 "size %d",
96 phdr->msgLength,
97 surb->cb->offset,
98 urb->actual_length);
99 goto exit_and_resubmit;
100 }
101
102 /* move buffer pointer and
103 * copy header to its new location */
104 memcpy((char *) phdr + surb->cb->offset,
105 phdr, sizeof(struct SmsMsgHdr_ST));
106 } else
107 surb->cb->offset = 0;
108
109 smscore_onresponse(dev->coredev, surb->cb);
110 surb->cb = NULL;
111 } else {
112 sms_err("invalid response "
113 "msglen %d actual %d",
114 phdr->msgLength, urb->actual_length);
115 }
116 } else
117 sms_err("error, urb status %d, %d bytes",
118 urb->status, urb->actual_length);
119
120
121exit_and_resubmit:
122 smsusb_submit_urb(dev, surb);
123}
124
125static int smsusb_submit_urb(struct smsusb_device_t *dev,
126 struct smsusb_urb_t *surb)
127{
128 if (!surb->cb) {
129 surb->cb = smscore_getbuffer(dev->coredev);
130 if (!surb->cb) {
131 sms_err("smscore_getbuffer(...) returned NULL");
132 return -ENOMEM;
133 }
134 }
135
136 usb_fill_bulk_urb(
137 &surb->urb,
138 dev->udev,
139 usb_rcvbulkpipe(dev->udev, 0x81),
140 surb->cb->p,
141 dev->buffer_size,
142 smsusb_onresponse,
143 surb
144 );
145 surb->urb.transfer_dma = surb->cb->phys;
146 surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
147
148 return usb_submit_urb(&surb->urb, GFP_ATOMIC);
149}
150
151static void smsusb_stop_streaming(struct smsusb_device_t *dev)
152{
153 int i;
154
155 for (i = 0; i < MAX_URBS; i++) {
156 usb_kill_urb(&dev->surbs[i].urb);
157
158 if (dev->surbs[i].cb) {
159 smscore_putbuffer(dev->coredev, dev->surbs[i].cb);
160 dev->surbs[i].cb = NULL;
161 }
162 }
163}
164
165static int smsusb_start_streaming(struct smsusb_device_t *dev)
166{
167 int i, rc;
168
169 for (i = 0; i < MAX_URBS; i++) {
170 rc = smsusb_submit_urb(dev, &dev->surbs[i]);
171 if (rc < 0) {
172 sms_err("smsusb_submit_urb(...) failed");
173 smsusb_stop_streaming(dev);
174 break;
175 }
176 }
177
178 return rc;
179}
180
181static int smsusb_sendrequest(void *context, void *buffer, size_t size)
182{
183 struct smsusb_device_t *dev = (struct smsusb_device_t *) context;
184 int dummy;
185
186 smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer);
187 return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2),
188 buffer, size, &dummy, 1000);
189}
190
191static char *smsusb1_fw_lkup[] = {
192 "dvbt_stellar_usb.inp",
193 "dvbh_stellar_usb.inp",
194 "tdmb_stellar_usb.inp",
195 "none",
196 "dvbt_bda_stellar_usb.inp",
197};
198
199static inline char *sms_get_fw_name(int mode, int board_id)
200{
201 char **fw = sms_get_board(board_id)->fw;
202 return (fw && fw[mode]) ? fw[mode] : smsusb1_fw_lkup[mode];
203}
204
205static int smsusb1_load_firmware(struct usb_device *udev, int id, int board_id)
206{
207 const struct firmware *fw;
208 u8 *fw_buffer;
209 int rc, dummy;
210 char *fw_filename;
211
212 if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) {
213 sms_err("invalid firmware id specified %d", id);
214 return -EINVAL;
215 }
216
217 fw_filename = sms_get_fw_name(id, board_id);
218
219 rc = request_firmware(&fw, fw_filename, &udev->dev);
220 if (rc < 0) {
221 sms_warn("failed to open \"%s\" mode %d, "
222 "trying again with default firmware", fw_filename, id);
223
224 fw_filename = smsusb1_fw_lkup[id];
225 rc = request_firmware(&fw, fw_filename, &udev->dev);
226 if (rc < 0) {
227 sms_warn("failed to open \"%s\" mode %d",
228 fw_filename, id);
229
230 return rc;
231 }
232 }
233
234 fw_buffer = kmalloc(fw->size, GFP_KERNEL);
235 if (fw_buffer) {
236 memcpy(fw_buffer, fw->data, fw->size);
237
238 rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2),
239 fw_buffer, fw->size, &dummy, 1000);
240
241 sms_info("sent %zd(%d) bytes, rc %d", fw->size, dummy, rc);
242
243 kfree(fw_buffer);
244 } else {
245 sms_err("failed to allocate firmware buffer");
246 rc = -ENOMEM;
247 }
248 sms_info("read FW %s, size=%zd", fw_filename, fw->size);
249
250 release_firmware(fw);
251
252 return rc;
253}
254
255static void smsusb1_detectmode(void *context, int *mode)
256{
257 char *product_string =
258 ((struct smsusb_device_t *) context)->udev->product;
259
260 *mode = DEVICE_MODE_NONE;
261
262 if (!product_string) {
263 product_string = "none";
264 sms_err("product string not found");
265 } else if (strstr(product_string, "DVBH"))
266 *mode = 1;
267 else if (strstr(product_string, "BDA"))
268 *mode = 4;
269 else if (strstr(product_string, "DVBT"))
270 *mode = 0;
271 else if (strstr(product_string, "TDMB"))
272 *mode = 2;
273
274 sms_info("%d \"%s\"", *mode, product_string);
275}
276
277static int smsusb1_setmode(void *context, int mode)
278{
279 struct SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK,
280 sizeof(struct SmsMsgHdr_ST), 0 };
281
282 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
283 sms_err("invalid firmware id specified %d", mode);
284 return -EINVAL;
285 }
286
287 return smsusb_sendrequest(context, &Msg, sizeof(Msg));
288}
289
290static void smsusb_term_device(struct usb_interface *intf)
291{
292 struct smsusb_device_t *dev = usb_get_intfdata(intf);
293
294 if (dev) {
295 smsusb_stop_streaming(dev);
296
297 /* unregister from smscore */
298 if (dev->coredev)
299 smscore_unregister_device(dev->coredev);
300
301 sms_info("device %p destroyed", dev);
302 kfree(dev);
303 }
304
305 usb_set_intfdata(intf, NULL);
306}
307
308static int smsusb_init_device(struct usb_interface *intf, int board_id)
309{
310 struct smsdevice_params_t params;
311 struct smsusb_device_t *dev;
312 int i, rc;
313
314 /* create device object */
315 dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL);
316 if (!dev) {
317 sms_err("kzalloc(sizeof(struct smsusb_device_t) failed");
318 return -ENOMEM;
319 }
320
321 memset(&params, 0, sizeof(params));
322 usb_set_intfdata(intf, dev);
323 dev->udev = interface_to_usbdev(intf);
324
325 params.device_type = sms_get_board(board_id)->type;
326
327 switch (params.device_type) {
328 case SMS_STELLAR:
329 dev->buffer_size = USB1_BUFFER_SIZE;
330
331 params.setmode_handler = smsusb1_setmode;
332 params.detectmode_handler = smsusb1_detectmode;
333 break;
334 default:
335 sms_err("Unspecified sms device type!");
336 /* fall-thru */
337 case SMS_NOVA_A0:
338 case SMS_NOVA_B0:
339 case SMS_VEGA:
340 dev->buffer_size = USB2_BUFFER_SIZE;
341 dev->response_alignment =
342 le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) -
343 sizeof(struct SmsMsgHdr_ST);
344
345 params.flags |= SMS_DEVICE_FAMILY2;
346 break;
347 }
348
349 params.device = &dev->udev->dev;
350 params.buffer_size = dev->buffer_size;
351 params.num_buffers = MAX_BUFFERS;
352 params.sendrequest_handler = smsusb_sendrequest;
353 params.context = dev;
354 usb_make_path(dev->udev, params.devpath, sizeof(params.devpath));
355
356 /* register in smscore */
357 rc = smscore_register_device(&params, &dev->coredev);
358 if (rc < 0) {
359 sms_err("smscore_register_device(...) failed, rc %d", rc);
360 smsusb_term_device(intf);
361 return rc;
362 }
363
364 smscore_set_board_id(dev->coredev, board_id);
365
366 /* initialize urbs */
367 for (i = 0; i < MAX_URBS; i++) {
368 dev->surbs[i].dev = dev;
369 usb_init_urb(&dev->surbs[i].urb);
370 }
371
372 sms_info("smsusb_start_streaming(...).");
373 rc = smsusb_start_streaming(dev);
374 if (rc < 0) {
375 sms_err("smsusb_start_streaming(...) failed");
376 smsusb_term_device(intf);
377 return rc;
378 }
379
380 rc = smscore_start_device(dev->coredev);
381 if (rc < 0) {
382 sms_err("smscore_start_device(...) failed");
383 smsusb_term_device(intf);
384 return rc;
385 }
386
387 sms_info("device %p created", dev);
388
389 return rc;
390}
391
392static int __devinit smsusb_probe(struct usb_interface *intf,
393 const struct usb_device_id *id)
394{
395 struct usb_device *udev = interface_to_usbdev(intf);
396 char devpath[32];
397 int i, rc;
398
399 rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81));
400 rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02));
401
402 if (intf->num_altsetting > 0) {
403 rc = usb_set_interface(
404 udev, intf->cur_altsetting->desc.bInterfaceNumber, 0);
405 if (rc < 0) {
406 sms_err("usb_set_interface failed, rc %d", rc);
407 return rc;
408 }
409 }
410
411 sms_info("smsusb_probe %d",
412 intf->cur_altsetting->desc.bInterfaceNumber);
413 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++)
414 sms_info("endpoint %d %02x %02x %d", i,
415 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress,
416 intf->cur_altsetting->endpoint[i].desc.bmAttributes,
417 intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
418
419 if ((udev->actconfig->desc.bNumInterfaces == 2) &&
420 (intf->cur_altsetting->desc.bInterfaceNumber == 0)) {
421 sms_err("rom interface 0 is not used");
422 return -ENODEV;
423 }
424
425 if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
426 snprintf(devpath, sizeof(devpath), "usb\\%d-%s",
427 udev->bus->busnum, udev->devpath);
428 sms_info("stellar device was found.");
429 return smsusb1_load_firmware(
430 udev, smscore_registry_getmode(devpath),
431 id->driver_info);
432 }
433
434 rc = smsusb_init_device(intf, id->driver_info);
435 sms_info("rc %d", rc);
436 sms_board_load_modules(id->driver_info);
437 return rc;
438}
439
440static void smsusb_disconnect(struct usb_interface *intf)
441{
442 smsusb_term_device(intf);
443}
444
445static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg)
446{
447 struct smsusb_device_t *dev = usb_get_intfdata(intf);
448 printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event);
449 smsusb_stop_streaming(dev);
450 return 0;
451}
452
453static int smsusb_resume(struct usb_interface *intf)
454{
455 int rc, i;
456 struct smsusb_device_t *dev = usb_get_intfdata(intf);
457 struct usb_device *udev = interface_to_usbdev(intf);
458
459 printk(KERN_INFO "%s: Entering.\n", __func__);
460 usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81));
461 usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02));
462
463 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++)
464 printk(KERN_INFO "endpoint %d %02x %02x %d\n", i,
465 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress,
466 intf->cur_altsetting->endpoint[i].desc.bmAttributes,
467 intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
468
469 if (intf->num_altsetting > 0) {
470 rc = usb_set_interface(udev,
471 intf->cur_altsetting->desc.
472 bInterfaceNumber, 0);
473 if (rc < 0) {
474 printk(KERN_INFO "%s usb_set_interface failed, "
475 "rc %d\n", __func__, rc);
476 return rc;
477 }
478 }
479
480 smsusb_start_streaming(dev);
481 return 0;
482}
483
484static const struct usb_device_id smsusb_id_table[] __devinitconst = {
485 { USB_DEVICE(0x187f, 0x0010),
486 .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
487 { USB_DEVICE(0x187f, 0x0100),
488 .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
489 { USB_DEVICE(0x187f, 0x0200),
490 .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A },
491 { USB_DEVICE(0x187f, 0x0201),
492 .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
493 { USB_DEVICE(0x187f, 0x0300),
494 .driver_info = SMS1XXX_BOARD_SIANO_VEGA },
495 { USB_DEVICE(0x2040, 0x1700),
496 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT },
497 { USB_DEVICE(0x2040, 0x1800),
498 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A },
499 { USB_DEVICE(0x2040, 0x1801),
500 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B },
501 { USB_DEVICE(0x2040, 0x2000),
502 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
503 { USB_DEVICE(0x2040, 0x2009),
504 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 },
505 { USB_DEVICE(0x2040, 0x200a),
506 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
507 { USB_DEVICE(0x2040, 0x2010),
508 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
509 { USB_DEVICE(0x2040, 0x2011),
510 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
511 { USB_DEVICE(0x2040, 0x2019),
512 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
513 { USB_DEVICE(0x2040, 0x5500),
514 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
515 { USB_DEVICE(0x2040, 0x5510),
516 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
517 { USB_DEVICE(0x2040, 0x5520),
518 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
519 { USB_DEVICE(0x2040, 0x5530),
520 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
521 { USB_DEVICE(0x2040, 0x5580),
522 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
523 { USB_DEVICE(0x2040, 0x5590),
524 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
525 { USB_DEVICE(0x187f, 0x0202),
526 .driver_info = SMS1XXX_BOARD_SIANO_NICE },
527 { USB_DEVICE(0x187f, 0x0301),
528 .driver_info = SMS1XXX_BOARD_SIANO_VENICE },
529 { USB_DEVICE(0x2040, 0xb900),
530 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
531 { USB_DEVICE(0x2040, 0xb910),
532 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
533 { USB_DEVICE(0x2040, 0xb980),
534 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
535 { USB_DEVICE(0x2040, 0xb990),
536 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
537 { USB_DEVICE(0x2040, 0xc000),
538 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
539 { USB_DEVICE(0x2040, 0xc010),
540 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
541 { USB_DEVICE(0x2040, 0xc080),
542 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
543 { USB_DEVICE(0x2040, 0xc090),
544 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
545 { USB_DEVICE(0x2040, 0xc0a0),
546 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
547 { USB_DEVICE(0x2040, 0xf5a0),
548 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
549 { } /* Terminating entry */
550 };
551
552MODULE_DEVICE_TABLE(usb, smsusb_id_table);
553
554static struct usb_driver smsusb_driver = {
555 .name = "smsusb",
556 .probe = smsusb_probe,
557 .disconnect = smsusb_disconnect,
558 .id_table = smsusb_id_table,
559
560 .suspend = smsusb_suspend,
561 .resume = smsusb_resume,
562};
563
564module_usb_driver(smsusb_driver);
565
566MODULE_DESCRIPTION("Driver for the Siano SMS1xxx USB dongle");
567MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)");
568MODULE_LICENSE("GPL");
diff --git a/drivers/media/usb/ttusb-budget/Kconfig b/drivers/media/usb/ttusb-budget/Kconfig
new file mode 100644
index 000000000000..2663ae39b886
--- /dev/null
+++ b/drivers/media/usb/ttusb-budget/Kconfig
@@ -0,0 +1,18 @@
1config DVB_TTUSB_BUDGET
2 tristate "Technotrend/Hauppauge Nova-USB devices"
3 depends on DVB_CORE && USB && I2C && PCI
4 select DVB_CX22700 if !DVB_FE_CUSTOMISE
5 select DVB_TDA1004X if !DVB_FE_CUSTOMISE
6 select DVB_VES1820 if !DVB_FE_CUSTOMISE
7 select DVB_TDA8083 if !DVB_FE_CUSTOMISE
8 select DVB_STV0299 if !DVB_FE_CUSTOMISE
9 select DVB_STV0297 if !DVB_FE_CUSTOMISE
10 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
11 help
12 Support for external USB adapters designed by Technotrend and
13 produced by Hauppauge, shipped under the brand name 'Nova-USB'.
14
15 These devices don't have a MPEG decoder built in, so you need
16 an external software decoder to watch TV.
17
18 Say Y if you own such a device and want to use it.
diff --git a/drivers/media/usb/ttusb-budget/Makefile b/drivers/media/usb/ttusb-budget/Makefile
new file mode 100644
index 000000000000..f47bbf62dcde
--- /dev/null
+++ b/drivers/media/usb/ttusb-budget/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o
2
3ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends
diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
new file mode 100644
index 000000000000..5b682cc4c814
--- /dev/null
+++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
@@ -0,0 +1,1816 @@
1/*
2 * TTUSB DVB driver
3 *
4 * Copyright (c) 2002 Holger Waechtler <holger@convergence.de>
5 * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 */
12#include <linux/init.h>
13#include <linux/slab.h>
14#include <linux/wait.h>
15#include <linux/fs.h>
16#include <linux/module.h>
17#include <linux/usb.h>
18#include <linux/delay.h>
19#include <linux/time.h>
20#include <linux/errno.h>
21#include <linux/jiffies.h>
22#include <linux/mutex.h>
23#include <linux/firmware.h>
24
25#include "dvb_frontend.h"
26#include "dmxdev.h"
27#include "dvb_demux.h"
28#include "dvb_net.h"
29#include "ves1820.h"
30#include "cx22700.h"
31#include "tda1004x.h"
32#include "stv0299.h"
33#include "tda8083.h"
34#include "stv0297.h"
35#include "lnbp21.h"
36
37#include <linux/dvb/frontend.h>
38#include <linux/dvb/dmx.h>
39#include <linux/pci.h>
40
41/*
42 TTUSB_HWSECTIONS:
43 the DSP supports filtering in hardware, however, since the "muxstream"
44 is a bit braindead (no matching channel masks or no matching filter mask),
45 we won't support this - yet. it doesn't event support negative filters,
46 so the best way is maybe to keep TTUSB_HWSECTIONS undef'd and just
47 parse TS data. USB bandwidth will be a problem when having large
48 datastreams, especially for dvb-net, but hey, that's not my problem.
49
50 TTUSB_DISEQC, TTUSB_TONE:
51 let the STC do the diseqc/tone stuff. this isn't supported at least with
52 my TTUSB, so let it undef'd unless you want to implement another
53 frontend. never tested.
54
55 debug:
56 define it to > 3 for really hardcore debugging. you probably don't want
57 this unless the device doesn't load at all. > 2 for bandwidth statistics.
58*/
59
60static int debug;
61module_param(debug, int, 0644);
62MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
63
64DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
65
66#define dprintk(x...) do { if (debug) printk(KERN_DEBUG x); } while (0)
67
68#define ISO_BUF_COUNT 4
69#define FRAMES_PER_ISO_BUF 4
70#define ISO_FRAME_SIZE 912
71#define TTUSB_MAXCHANNEL 32
72#ifdef TTUSB_HWSECTIONS
73#define TTUSB_MAXFILTER 16 /* ??? */
74#endif
75
76#define TTUSB_REV_2_2 0x22
77#define TTUSB_BUDGET_NAME "ttusb_stc_fw"
78
79/**
80 * since we're casting (struct ttusb*) <-> (struct dvb_demux*) around
81 * the dvb_demux field must be the first in struct!!
82 */
83struct ttusb {
84 struct dvb_demux dvb_demux;
85 struct dmxdev dmxdev;
86 struct dvb_net dvbnet;
87
88 /* and one for USB access. */
89 struct mutex semi2c;
90 struct mutex semusb;
91
92 struct dvb_adapter adapter;
93 struct usb_device *dev;
94
95 struct i2c_adapter i2c_adap;
96
97 int disconnecting;
98 int iso_streaming;
99
100 unsigned int bulk_out_pipe;
101 unsigned int bulk_in_pipe;
102 unsigned int isoc_in_pipe;
103
104 void *iso_buffer;
105 dma_addr_t iso_dma_handle;
106
107 struct urb *iso_urb[ISO_BUF_COUNT];
108
109 int running_feed_count;
110 int last_channel;
111 int last_filter;
112
113 u8 c; /* transaction counter, wraps around... */
114 fe_sec_tone_mode_t tone;
115 fe_sec_voltage_t voltage;
116
117 int mux_state; // 0..2 - MuxSyncWord, 3 - nMuxPacks, 4 - muxpack
118 u8 mux_npacks;
119 u8 muxpack[256 + 8];
120 int muxpack_ptr, muxpack_len;
121
122 int insync;
123
124 int cc; /* MuxCounter - will increment on EVERY MUX PACKET */
125 /* (including stuffing. yes. really.) */
126
127 u8 last_result[32];
128
129 int revision;
130
131 struct dvb_frontend* fe;
132};
133
134/* ugly workaround ... don't know why it's necessary to read */
135/* all result codes. */
136
137static int ttusb_cmd(struct ttusb *ttusb,
138 const u8 * data, int len, int needresult)
139{
140 int actual_len;
141 int err;
142 int i;
143
144 if (debug >= 3) {
145 printk(KERN_DEBUG ">");
146 for (i = 0; i < len; ++i)
147 printk(KERN_CONT " %02x", data[i]);
148 printk(KERN_CONT "\n");
149 }
150
151 if (mutex_lock_interruptible(&ttusb->semusb) < 0)
152 return -EAGAIN;
153
154 err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe,
155 (u8 *) data, len, &actual_len, 1000);
156 if (err != 0) {
157 dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n",
158 __func__, err);
159 mutex_unlock(&ttusb->semusb);
160 return err;
161 }
162 if (actual_len != len) {
163 dprintk("%s: only wrote %d of %d bytes\n", __func__,
164 actual_len, len);
165 mutex_unlock(&ttusb->semusb);
166 return -1;
167 }
168
169 err = usb_bulk_msg(ttusb->dev, ttusb->bulk_in_pipe,
170 ttusb->last_result, 32, &actual_len, 1000);
171
172 if (err != 0) {
173 printk("%s: failed, receive error %d\n", __func__,
174 err);
175 mutex_unlock(&ttusb->semusb);
176 return err;
177 }
178
179 if (debug >= 3) {
180 actual_len = ttusb->last_result[3] + 4;
181 printk(KERN_DEBUG "<");
182 for (i = 0; i < actual_len; ++i)
183 printk(KERN_CONT " %02x", ttusb->last_result[i]);
184 printk(KERN_CONT "\n");
185 }
186
187 if (!needresult)
188 mutex_unlock(&ttusb->semusb);
189 return 0;
190}
191
192static int ttusb_result(struct ttusb *ttusb, u8 * data, int len)
193{
194 memcpy(data, ttusb->last_result, len);
195 mutex_unlock(&ttusb->semusb);
196 return 0;
197}
198
199static int ttusb_i2c_msg(struct ttusb *ttusb,
200 u8 addr, u8 * snd_buf, u8 snd_len, u8 * rcv_buf,
201 u8 rcv_len)
202{
203 u8 b[0x28];
204 u8 id = ++ttusb->c;
205 int i, err;
206
207 if (snd_len > 0x28 - 7 || rcv_len > 0x20 - 7)
208 return -EINVAL;
209
210 b[0] = 0xaa;
211 b[1] = id;
212 b[2] = 0x31;
213 b[3] = snd_len + 3;
214 b[4] = addr << 1;
215 b[5] = snd_len;
216 b[6] = rcv_len;
217
218 for (i = 0; i < snd_len; i++)
219 b[7 + i] = snd_buf[i];
220
221 err = ttusb_cmd(ttusb, b, snd_len + 7, 1);
222
223 if (err)
224 return -EREMOTEIO;
225
226 err = ttusb_result(ttusb, b, 0x20);
227
228 /* check if the i2c transaction was successful */
229 if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO;
230
231 if (rcv_len > 0) {
232
233 if (err || b[0] != 0x55 || b[1] != id) {
234 dprintk
235 ("%s: usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ",
236 __func__, err, id);
237 return -EREMOTEIO;
238 }
239
240 for (i = 0; i < rcv_len; i++)
241 rcv_buf[i] = b[7 + i];
242 }
243
244 return rcv_len;
245}
246
247static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
248{
249 struct ttusb *ttusb = i2c_get_adapdata(adapter);
250 int i = 0;
251 int inc;
252
253 if (mutex_lock_interruptible(&ttusb->semi2c) < 0)
254 return -EAGAIN;
255
256 while (i < num) {
257 u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
258 int err;
259
260 if (num > i + 1 && (msg[i + 1].flags & I2C_M_RD)) {
261 addr = msg[i].addr;
262 snd_buf = msg[i].buf;
263 snd_len = msg[i].len;
264 rcv_buf = msg[i + 1].buf;
265 rcv_len = msg[i + 1].len;
266 inc = 2;
267 } else {
268 addr = msg[i].addr;
269 snd_buf = msg[i].buf;
270 snd_len = msg[i].len;
271 rcv_buf = NULL;
272 rcv_len = 0;
273 inc = 1;
274 }
275
276 err = ttusb_i2c_msg(ttusb, addr,
277 snd_buf, snd_len, rcv_buf, rcv_len);
278
279 if (err < rcv_len) {
280 dprintk("%s: i == %i\n", __func__, i);
281 break;
282 }
283
284 i += inc;
285 }
286
287 mutex_unlock(&ttusb->semi2c);
288 return i;
289}
290
291static int ttusb_boot_dsp(struct ttusb *ttusb)
292{
293 const struct firmware *fw;
294 int i, err;
295 u8 b[40];
296
297 err = request_firmware(&fw, "ttusb-budget/dspbootcode.bin",
298 &ttusb->dev->dev);
299 if (err) {
300 printk(KERN_ERR "ttusb-budget: failed to request firmware\n");
301 return err;
302 }
303
304 /* BootBlock */
305 b[0] = 0xaa;
306 b[2] = 0x13;
307 b[3] = 28;
308
309 /* upload dsp code in 32 byte steps (36 didn't work for me ...) */
310 /* 32 is max packet size, no messages should be splitted. */
311 for (i = 0; i < fw->size; i += 28) {
312 memcpy(&b[4], &fw->data[i], 28);
313
314 b[1] = ++ttusb->c;
315
316 err = ttusb_cmd(ttusb, b, 32, 0);
317 if (err)
318 goto done;
319 }
320
321 /* last block ... */
322 b[1] = ++ttusb->c;
323 b[2] = 0x13;
324 b[3] = 0;
325
326 err = ttusb_cmd(ttusb, b, 4, 0);
327 if (err)
328 goto done;
329
330 /* BootEnd */
331 b[1] = ++ttusb->c;
332 b[2] = 0x14;
333 b[3] = 0;
334
335 err = ttusb_cmd(ttusb, b, 4, 0);
336
337 done:
338 release_firmware(fw);
339 if (err) {
340 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
341 __func__, err);
342 }
343
344 return err;
345}
346
347static int ttusb_set_channel(struct ttusb *ttusb, int chan_id, int filter_type,
348 int pid)
349{
350 int err;
351 /* SetChannel */
352 u8 b[] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type,
353 (pid >> 8) & 0xff, pid & 0xff
354 };
355
356 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
357 return err;
358}
359
360static int ttusb_del_channel(struct ttusb *ttusb, int channel_id)
361{
362 int err;
363 /* DelChannel */
364 u8 b[] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id };
365
366 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
367 return err;
368}
369
370#ifdef TTUSB_HWSECTIONS
371static int ttusb_set_filter(struct ttusb *ttusb, int filter_id,
372 int associated_chan, u8 filter[8], u8 mask[8])
373{
374 int err;
375 /* SetFilter */
376 u8 b[] = { 0xaa, 0, 0x24, 0x1a, filter_id, associated_chan,
377 filter[0], filter[1], filter[2], filter[3],
378 filter[4], filter[5], filter[6], filter[7],
379 filter[8], filter[9], filter[10], filter[11],
380 mask[0], mask[1], mask[2], mask[3],
381 mask[4], mask[5], mask[6], mask[7],
382 mask[8], mask[9], mask[10], mask[11]
383 };
384
385 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
386 return err;
387}
388
389static int ttusb_del_filter(struct ttusb *ttusb, int filter_id)
390{
391 int err;
392 /* DelFilter */
393 u8 b[] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id };
394
395 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
396 return err;
397}
398#endif
399
400static int ttusb_init_controller(struct ttusb *ttusb)
401{
402 u8 b0[] = { 0xaa, ++ttusb->c, 0x15, 1, 0 };
403 u8 b1[] = { 0xaa, ++ttusb->c, 0x15, 1, 1 };
404 u8 b2[] = { 0xaa, ++ttusb->c, 0x32, 1, 0 };
405 /* i2c write read: 5 bytes, addr 0x10, 0x02 bytes write, 1 bytes read. */
406 u8 b3[] =
407 { 0xaa, ++ttusb->c, 0x31, 5, 0x10, 0x02, 0x01, 0x00, 0x1e };
408 u8 b4[] =
409 { 0x55, ttusb->c, 0x31, 4, 0x10, 0x02, 0x01, 0x00, 0x1e };
410
411 u8 get_version[] = { 0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0 };
412 u8 get_dsp_version[0x20] =
413 { 0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0 };
414 int err;
415
416 /* reset board */
417 if ((err = ttusb_cmd(ttusb, b0, sizeof(b0), 0)))
418 return err;
419
420 /* reset board (again?) */
421 if ((err = ttusb_cmd(ttusb, b1, sizeof(b1), 0)))
422 return err;
423
424 ttusb_boot_dsp(ttusb);
425
426 /* set i2c bit rate */
427 if ((err = ttusb_cmd(ttusb, b2, sizeof(b2), 0)))
428 return err;
429
430 if ((err = ttusb_cmd(ttusb, b3, sizeof(b3), 1)))
431 return err;
432
433 err = ttusb_result(ttusb, b4, sizeof(b4));
434
435 if ((err = ttusb_cmd(ttusb, get_version, sizeof(get_version), 1)))
436 return err;
437
438 if ((err = ttusb_result(ttusb, get_version, sizeof(get_version))))
439 return err;
440
441 dprintk("%s: stc-version: %c%c%c%c%c\n", __func__,
442 get_version[4], get_version[5], get_version[6],
443 get_version[7], get_version[8]);
444
445 if (memcmp(get_version + 4, "V 0.0", 5) &&
446 memcmp(get_version + 4, "V 1.1", 5) &&
447 memcmp(get_version + 4, "V 2.1", 5) &&
448 memcmp(get_version + 4, "V 2.2", 5)) {
449 printk
450 ("%s: unknown STC version %c%c%c%c%c, please report!\n",
451 __func__, get_version[4], get_version[5],
452 get_version[6], get_version[7], get_version[8]);
453 }
454
455 ttusb->revision = ((get_version[6] - '0') << 4) |
456 (get_version[8] - '0');
457
458 err =
459 ttusb_cmd(ttusb, get_dsp_version, sizeof(get_dsp_version), 1);
460 if (err)
461 return err;
462
463 err =
464 ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version));
465 if (err)
466 return err;
467 printk("%s: dsp-version: %c%c%c\n", __func__,
468 get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]);
469 return 0;
470}
471
472#ifdef TTUSB_DISEQC
473static int ttusb_send_diseqc(struct dvb_frontend* fe,
474 const struct dvb_diseqc_master_cmd *cmd)
475{
476 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
477 u8 b[12] = { 0xaa, ++ttusb->c, 0x18 };
478
479 int err;
480
481 b[3] = 4 + 2 + cmd->msg_len;
482 b[4] = 0xFF; /* send diseqc master, not burst */
483 b[5] = cmd->msg_len;
484
485 memcpy(b + 5, cmd->msg, cmd->msg_len);
486
487 /* Diseqc */
488 if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) {
489 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
490 __func__, err);
491 }
492
493 return err;
494}
495#endif
496
497static int ttusb_update_lnb(struct ttusb *ttusb)
498{
499 u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
500 ttusb->voltage == SEC_VOLTAGE_18 ? 0 : 1,
501 ttusb->tone == SEC_TONE_ON ? 1 : 0, 1, 1
502 };
503 int err;
504
505 /* SetLNB */
506 if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) {
507 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
508 __func__, err);
509 }
510
511 return err;
512}
513
514static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
515{
516 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
517
518 ttusb->voltage = voltage;
519 return ttusb_update_lnb(ttusb);
520}
521
522#ifdef TTUSB_TONE
523static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
524{
525 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
526
527 ttusb->tone = tone;
528 return ttusb_update_lnb(ttusb);
529}
530#endif
531
532
533#if 0
534static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq)
535{
536 u8 b[] = { 0xaa, ++ttusb->c, 0x19, 1, freq };
537 int err, actual_len;
538
539 err = ttusb_cmd(ttusb, b, sizeof(b), 0);
540 if (err) {
541 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
542 __func__, err);
543 }
544}
545#endif
546
547/*****************************************************************************/
548
549#ifdef TTUSB_HWSECTIONS
550static void ttusb_handle_ts_data(struct ttusb_channel *channel,
551 const u8 * data, int len);
552static void ttusb_handle_sec_data(struct ttusb_channel *channel,
553 const u8 * data, int len);
554#endif
555
556static int numpkt, numts, numstuff, numsec, numinvalid;
557static unsigned long lastj;
558
559static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack,
560 int len)
561{
562 u16 csum = 0, cc;
563 int i;
564 for (i = 0; i < len; i += 2)
565 csum ^= le16_to_cpup((__le16 *) (muxpack + i));
566 if (csum) {
567 printk("%s: muxpack with incorrect checksum, ignoring\n",
568 __func__);
569 numinvalid++;
570 return;
571 }
572
573 cc = (muxpack[len - 4] << 8) | muxpack[len - 3];
574 cc &= 0x7FFF;
575 if ((cc != ttusb->cc) && (ttusb->cc != -1))
576 printk("%s: cc discontinuity (%d frames missing)\n",
577 __func__, (cc - ttusb->cc) & 0x7FFF);
578 ttusb->cc = (cc + 1) & 0x7FFF;
579 if (muxpack[0] & 0x80) {
580#ifdef TTUSB_HWSECTIONS
581 /* section data */
582 int pusi = muxpack[0] & 0x40;
583 int channel = muxpack[0] & 0x1F;
584 int payload = muxpack[1];
585 const u8 *data = muxpack + 2;
586 /* check offset flag */
587 if (muxpack[0] & 0x20)
588 data++;
589
590 ttusb_handle_sec_data(ttusb->channel + channel, data,
591 payload);
592 data += payload;
593
594 if ((!!(ttusb->muxpack[0] & 0x20)) ^
595 !!(ttusb->muxpack[1] & 1))
596 data++;
597#warning TODO: pusi
598 printk("cc: %04x\n", (data[0] << 8) | data[1]);
599#endif
600 numsec++;
601 } else if (muxpack[0] == 0x47) {
602#ifdef TTUSB_HWSECTIONS
603 /* we have TS data here! */
604 int pid = ((muxpack[1] & 0x0F) << 8) | muxpack[2];
605 int channel;
606 for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel)
607 if (ttusb->channel[channel].active
608 && (pid == ttusb->channel[channel].pid))
609 ttusb_handle_ts_data(ttusb->channel +
610 channel, muxpack,
611 188);
612#endif
613 numts++;
614 dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1);
615 } else if (muxpack[0] != 0) {
616 numinvalid++;
617 printk("illegal muxpack type %02x\n", muxpack[0]);
618 } else
619 numstuff++;
620}
621
622static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len)
623{
624 int maxwork = 1024;
625 while (len) {
626 if (!(maxwork--)) {
627 printk("%s: too much work\n", __func__);
628 break;
629 }
630
631 switch (ttusb->mux_state) {
632 case 0:
633 case 1:
634 case 2:
635 len--;
636 if (*data++ == 0xAA)
637 ++ttusb->mux_state;
638 else {
639 ttusb->mux_state = 0;
640 if (ttusb->insync) {
641 dprintk("%s: %02x\n",
642 __func__, data[-1]);
643 printk(KERN_INFO "%s: lost sync.\n",
644 __func__);
645 ttusb->insync = 0;
646 }
647 }
648 break;
649 case 3:
650 ttusb->insync = 1;
651 len--;
652 ttusb->mux_npacks = *data++;
653 ++ttusb->mux_state;
654 ttusb->muxpack_ptr = 0;
655 /* maximum bytes, until we know the length */
656 ttusb->muxpack_len = 2;
657 break;
658 case 4:
659 {
660 int avail;
661 avail = len;
662 if (avail >
663 (ttusb->muxpack_len -
664 ttusb->muxpack_ptr))
665 avail =
666 ttusb->muxpack_len -
667 ttusb->muxpack_ptr;
668 memcpy(ttusb->muxpack + ttusb->muxpack_ptr,
669 data, avail);
670 ttusb->muxpack_ptr += avail;
671 BUG_ON(ttusb->muxpack_ptr > 264);
672 data += avail;
673 len -= avail;
674 /* determine length */
675 if (ttusb->muxpack_ptr == 2) {
676 if (ttusb->muxpack[0] & 0x80) {
677 ttusb->muxpack_len =
678 ttusb->muxpack[1] + 2;
679 if (ttusb->
680 muxpack[0] & 0x20)
681 ttusb->
682 muxpack_len++;
683 if ((!!
684 (ttusb->
685 muxpack[0] & 0x20)) ^
686 !!(ttusb->
687 muxpack[1] & 1))
688 ttusb->
689 muxpack_len++;
690 ttusb->muxpack_len += 4;
691 } else if (ttusb->muxpack[0] ==
692 0x47)
693 ttusb->muxpack_len =
694 188 + 4;
695 else if (ttusb->muxpack[0] == 0x00)
696 ttusb->muxpack_len =
697 ttusb->muxpack[1] + 2 +
698 4;
699 else {
700 dprintk
701 ("%s: invalid state: first byte is %x\n",
702 __func__,
703 ttusb->muxpack[0]);
704 ttusb->mux_state = 0;
705 }
706 }
707
708 /**
709 * if length is valid and we reached the end:
710 * goto next muxpack
711 */
712 if ((ttusb->muxpack_ptr >= 2) &&
713 (ttusb->muxpack_ptr ==
714 ttusb->muxpack_len)) {
715 ttusb_process_muxpack(ttusb,
716 ttusb->
717 muxpack,
718 ttusb->
719 muxpack_ptr);
720 ttusb->muxpack_ptr = 0;
721 /* maximum bytes, until we know the length */
722 ttusb->muxpack_len = 2;
723
724 /**
725 * no muxpacks left?
726 * return to search-sync state
727 */
728 if (!ttusb->mux_npacks--) {
729 ttusb->mux_state = 0;
730 break;
731 }
732 }
733 break;
734 }
735 default:
736 BUG();
737 break;
738 }
739 }
740}
741
742static void ttusb_iso_irq(struct urb *urb)
743{
744 struct ttusb *ttusb = urb->context;
745 struct usb_iso_packet_descriptor *d;
746 u8 *data;
747 int len, i;
748
749 if (!ttusb->iso_streaming)
750 return;
751
752#if 0
753 printk("%s: status %d, errcount == %d, length == %i\n",
754 __func__,
755 urb->status, urb->error_count, urb->actual_length);
756#endif
757
758 if (!urb->status) {
759 for (i = 0; i < urb->number_of_packets; ++i) {
760 numpkt++;
761 if (time_after_eq(jiffies, lastj + HZ)) {
762 dprintk("frames/s: %lu (ts: %d, stuff %d, "
763 "sec: %d, invalid: %d, all: %d)\n",
764 numpkt * HZ / (jiffies - lastj),
765 numts, numstuff, numsec, numinvalid,
766 numts + numstuff + numsec + numinvalid);
767 numts = numstuff = numsec = numinvalid = 0;
768 lastj = jiffies;
769 numpkt = 0;
770 }
771 d = &urb->iso_frame_desc[i];
772 data = urb->transfer_buffer + d->offset;
773 len = d->actual_length;
774 d->actual_length = 0;
775 d->status = 0;
776 ttusb_process_frame(ttusb, data, len);
777 }
778 }
779 usb_submit_urb(urb, GFP_ATOMIC);
780}
781
782static void ttusb_free_iso_urbs(struct ttusb *ttusb)
783{
784 int i;
785
786 for (i = 0; i < ISO_BUF_COUNT; i++)
787 if (ttusb->iso_urb[i])
788 usb_free_urb(ttusb->iso_urb[i]);
789
790 pci_free_consistent(NULL,
791 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
792 ISO_BUF_COUNT, ttusb->iso_buffer,
793 ttusb->iso_dma_handle);
794}
795
796static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
797{
798 int i;
799
800 ttusb->iso_buffer = pci_alloc_consistent(NULL,
801 ISO_FRAME_SIZE *
802 FRAMES_PER_ISO_BUF *
803 ISO_BUF_COUNT,
804 &ttusb->iso_dma_handle);
805
806 if (!ttusb->iso_buffer) {
807 dprintk("%s: pci_alloc_consistent - not enough memory\n",
808 __func__);
809 return -ENOMEM;
810 }
811
812 memset(ttusb->iso_buffer, 0,
813 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT);
814
815 for (i = 0; i < ISO_BUF_COUNT; i++) {
816 struct urb *urb;
817
818 if (!
819 (urb =
820 usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
821 ttusb_free_iso_urbs(ttusb);
822 return -ENOMEM;
823 }
824
825 ttusb->iso_urb[i] = urb;
826 }
827
828 return 0;
829}
830
831static void ttusb_stop_iso_xfer(struct ttusb *ttusb)
832{
833 int i;
834
835 for (i = 0; i < ISO_BUF_COUNT; i++)
836 usb_kill_urb(ttusb->iso_urb[i]);
837
838 ttusb->iso_streaming = 0;
839}
840
841static int ttusb_start_iso_xfer(struct ttusb *ttusb)
842{
843 int i, j, err, buffer_offset = 0;
844
845 if (ttusb->iso_streaming) {
846 printk("%s: iso xfer already running!\n", __func__);
847 return 0;
848 }
849
850 ttusb->cc = -1;
851 ttusb->insync = 0;
852 ttusb->mux_state = 0;
853
854 for (i = 0; i < ISO_BUF_COUNT; i++) {
855 int frame_offset = 0;
856 struct urb *urb = ttusb->iso_urb[i];
857
858 urb->dev = ttusb->dev;
859 urb->context = ttusb;
860 urb->complete = ttusb_iso_irq;
861 urb->pipe = ttusb->isoc_in_pipe;
862 urb->transfer_flags = URB_ISO_ASAP;
863 urb->interval = 1;
864 urb->number_of_packets = FRAMES_PER_ISO_BUF;
865 urb->transfer_buffer_length =
866 ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
867 urb->transfer_buffer = ttusb->iso_buffer + buffer_offset;
868 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
869
870 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
871 urb->iso_frame_desc[j].offset = frame_offset;
872 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
873 frame_offset += ISO_FRAME_SIZE;
874 }
875 }
876
877 for (i = 0; i < ISO_BUF_COUNT; i++) {
878 if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) {
879 ttusb_stop_iso_xfer(ttusb);
880 printk
881 ("%s: failed urb submission (%i: err = %i)!\n",
882 __func__, i, err);
883 return err;
884 }
885 }
886
887 ttusb->iso_streaming = 1;
888
889 return 0;
890}
891
892#ifdef TTUSB_HWSECTIONS
893static void ttusb_handle_ts_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
894 int len)
895{
896 dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0);
897}
898
899static void ttusb_handle_sec_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data,
900 int len)
901{
902// struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed;
903#error TODO: handle ugly stuff
904// dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0);
905}
906#endif
907
908static int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
909{
910 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
911 int feed_type = 1;
912
913 dprintk("ttusb_start_feed\n");
914
915 switch (dvbdmxfeed->type) {
916 case DMX_TYPE_TS:
917 break;
918 case DMX_TYPE_SEC:
919 break;
920 default:
921 return -EINVAL;
922 }
923
924 if (dvbdmxfeed->type == DMX_TYPE_TS) {
925 switch (dvbdmxfeed->pes_type) {
926 case DMX_TS_PES_VIDEO:
927 case DMX_TS_PES_AUDIO:
928 case DMX_TS_PES_TELETEXT:
929 case DMX_TS_PES_PCR:
930 case DMX_TS_PES_OTHER:
931 break;
932 default:
933 return -EINVAL;
934 }
935 }
936
937#ifdef TTUSB_HWSECTIONS
938#error TODO: allocate filters
939 if (dvbdmxfeed->type == DMX_TYPE_TS) {
940 feed_type = 1;
941 } else if (dvbdmxfeed->type == DMX_TYPE_SEC) {
942 feed_type = 2;
943 }
944#endif
945
946 ttusb_set_channel(ttusb, dvbdmxfeed->index, feed_type, dvbdmxfeed->pid);
947
948 if (0 == ttusb->running_feed_count++)
949 ttusb_start_iso_xfer(ttusb);
950
951 return 0;
952}
953
954static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
955{
956 struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux;
957
958 ttusb_del_channel(ttusb, dvbdmxfeed->index);
959
960 if (--ttusb->running_feed_count == 0)
961 ttusb_stop_iso_xfer(ttusb);
962
963 return 0;
964}
965
966static int ttusb_setup_interfaces(struct ttusb *ttusb)
967{
968 usb_set_interface(ttusb->dev, 1, 1);
969
970 ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1);
971 ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1);
972 ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2);
973
974 return 0;
975}
976
977#if 0
978static u8 stc_firmware[8192];
979
980static int stc_open(struct inode *inode, struct file *file)
981{
982 struct ttusb *ttusb = file->private_data;
983 int addr;
984
985 for (addr = 0; addr < 8192; addr += 16) {
986 u8 snd_buf[2] = { addr >> 8, addr & 0xFF };
987 ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr,
988 16);
989 }
990
991 return 0;
992}
993
994static ssize_t stc_read(struct file *file, char *buf, size_t count,
995 loff_t *offset)
996{
997 return simple_read_from_buffer(buf, count, offset, stc_firmware, 8192);
998}
999
1000static int stc_release(struct inode *inode, struct file *file)
1001{
1002 return 0;
1003}
1004
1005static const struct file_operations stc_fops = {
1006 .owner = THIS_MODULE,
1007 .read = stc_read,
1008 .open = stc_open,
1009 .release = stc_release,
1010};
1011#endif
1012
1013static u32 functionality(struct i2c_adapter *adapter)
1014{
1015 return I2C_FUNC_I2C;
1016}
1017
1018
1019
1020static int alps_tdmb7_tuner_set_params(struct dvb_frontend *fe)
1021{
1022 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1023 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1024 u8 data[4];
1025 struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) };
1026 u32 div;
1027
1028 div = (p->frequency + 36166667) / 166667;
1029
1030 data[0] = (div >> 8) & 0x7f;
1031 data[1] = div & 0xff;
1032 data[2] = ((div >> 10) & 0x60) | 0x85;
1033 data[3] = p->frequency < 592000000 ? 0x40 : 0x80;
1034
1035 if (fe->ops.i2c_gate_ctrl)
1036 fe->ops.i2c_gate_ctrl(fe, 1);
1037 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO;
1038 return 0;
1039}
1040
1041static struct cx22700_config alps_tdmb7_config = {
1042 .demod_address = 0x43,
1043};
1044
1045
1046
1047
1048
1049static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe)
1050{
1051 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1052 static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
1053 static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
1054 struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) };
1055
1056 // setup PLL configuration
1057 if (fe->ops.i2c_gate_ctrl)
1058 fe->ops.i2c_gate_ctrl(fe, 1);
1059 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO;
1060 msleep(1);
1061
1062 // disable the mc44BC374c (do not check for errors)
1063 tuner_msg.addr = 0x65;
1064 tuner_msg.buf = disable_mc44BC374c;
1065 tuner_msg.len = sizeof(disable_mc44BC374c);
1066 if (fe->ops.i2c_gate_ctrl)
1067 fe->ops.i2c_gate_ctrl(fe, 1);
1068 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1069 i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1);
1070 }
1071
1072 return 0;
1073}
1074
1075static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
1076{
1077 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1078 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1079 u8 tuner_buf[4];
1080 struct i2c_msg tuner_msg = {.addr=0x60, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) };
1081 int tuner_frequency = 0;
1082 u8 band, cp, filter;
1083
1084 // determine charge pump
1085 tuner_frequency = p->frequency + 36130000;
1086 if (tuner_frequency < 87000000) return -EINVAL;
1087 else if (tuner_frequency < 130000000) cp = 3;
1088 else if (tuner_frequency < 160000000) cp = 5;
1089 else if (tuner_frequency < 200000000) cp = 6;
1090 else if (tuner_frequency < 290000000) cp = 3;
1091 else if (tuner_frequency < 420000000) cp = 5;
1092 else if (tuner_frequency < 480000000) cp = 6;
1093 else if (tuner_frequency < 620000000) cp = 3;
1094 else if (tuner_frequency < 830000000) cp = 5;
1095 else if (tuner_frequency < 895000000) cp = 7;
1096 else return -EINVAL;
1097
1098 // determine band
1099 if (p->frequency < 49000000)
1100 return -EINVAL;
1101 else if (p->frequency < 159000000)
1102 band = 1;
1103 else if (p->frequency < 444000000)
1104 band = 2;
1105 else if (p->frequency < 861000000)
1106 band = 4;
1107 else return -EINVAL;
1108
1109 // setup PLL filter
1110 switch (p->bandwidth_hz) {
1111 case 6000000:
1112 tda1004x_writereg(fe, 0x0C, 0);
1113 filter = 0;
1114 break;
1115
1116 case 7000000:
1117 tda1004x_writereg(fe, 0x0C, 0);
1118 filter = 0;
1119 break;
1120
1121 case 8000000:
1122 tda1004x_writereg(fe, 0x0C, 0xFF);
1123 filter = 1;
1124 break;
1125
1126 default:
1127 return -EINVAL;
1128 }
1129
1130 // calculate divisor
1131 // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
1132 tuner_frequency = (((p->frequency / 1000) * 6) + 217280) / 1000;
1133
1134 // setup tuner buffer
1135 tuner_buf[0] = tuner_frequency >> 8;
1136 tuner_buf[1] = tuner_frequency & 0xff;
1137 tuner_buf[2] = 0xca;
1138 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1139
1140 if (fe->ops.i2c_gate_ctrl)
1141 fe->ops.i2c_gate_ctrl(fe, 1);
1142 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1)
1143 return -EIO;
1144
1145 msleep(1);
1146 return 0;
1147}
1148
1149static int philips_tdm1316l_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
1150{
1151 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1152
1153 return request_firmware(fw, name, &ttusb->dev->dev);
1154}
1155
1156static struct tda1004x_config philips_tdm1316l_config = {
1157
1158 .demod_address = 0x8,
1159 .invert = 1,
1160 .invert_oclk = 0,
1161 .request_firmware = philips_tdm1316l_request_firmware,
1162};
1163
1164static u8 alps_bsbe1_inittab[] = {
1165 0x01, 0x15,
1166 0x02, 0x30,
1167 0x03, 0x00,
1168 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1169 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1170 0x06, 0x40, /* DAC not used, set to high impendance mode */
1171 0x07, 0x00, /* DAC LSB */
1172 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1173 0x09, 0x00, /* FIFO */
1174 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1175 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1176 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1177 0x10, 0x3f, // AGC2 0x3d
1178 0x11, 0x84,
1179 0x12, 0xb9,
1180 0x15, 0xc9, // lock detector threshold
1181 0x16, 0x00,
1182 0x17, 0x00,
1183 0x18, 0x00,
1184 0x19, 0x00,
1185 0x1a, 0x00,
1186 0x1f, 0x50,
1187 0x20, 0x00,
1188 0x21, 0x00,
1189 0x22, 0x00,
1190 0x23, 0x00,
1191 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1192 0x29, 0x1e, // 1/2 threshold
1193 0x2a, 0x14, // 2/3 threshold
1194 0x2b, 0x0f, // 3/4 threshold
1195 0x2c, 0x09, // 5/6 threshold
1196 0x2d, 0x05, // 7/8 threshold
1197 0x2e, 0x01,
1198 0x31, 0x1f, // test all FECs
1199 0x32, 0x19, // viterbi and synchro search
1200 0x33, 0xfc, // rs control
1201 0x34, 0x93, // error control
1202 0x0f, 0x92,
1203 0xff, 0xff
1204};
1205
1206static u8 alps_bsru6_inittab[] = {
1207 0x01, 0x15,
1208 0x02, 0x30,
1209 0x03, 0x00,
1210 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
1211 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
1212 0x06, 0x40, /* DAC not used, set to high impendance mode */
1213 0x07, 0x00, /* DAC LSB */
1214 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
1215 0x09, 0x00, /* FIFO */
1216 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
1217 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
1218 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
1219 0x10, 0x3f, // AGC2 0x3d
1220 0x11, 0x84,
1221 0x12, 0xb9,
1222 0x15, 0xc9, // lock detector threshold
1223 0x16, 0x00,
1224 0x17, 0x00,
1225 0x18, 0x00,
1226 0x19, 0x00,
1227 0x1a, 0x00,
1228 0x1f, 0x50,
1229 0x20, 0x00,
1230 0x21, 0x00,
1231 0x22, 0x00,
1232 0x23, 0x00,
1233 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
1234 0x29, 0x1e, // 1/2 threshold
1235 0x2a, 0x14, // 2/3 threshold
1236 0x2b, 0x0f, // 3/4 threshold
1237 0x2c, 0x09, // 5/6 threshold
1238 0x2d, 0x05, // 7/8 threshold
1239 0x2e, 0x01,
1240 0x31, 0x1f, // test all FECs
1241 0x32, 0x19, // viterbi and synchro search
1242 0x33, 0xfc, // rs control
1243 0x34, 0x93, // error control
1244 0x0f, 0x52,
1245 0xff, 0xff
1246};
1247
1248static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
1249{
1250 u8 aclk = 0;
1251 u8 bclk = 0;
1252
1253 if (srate < 1500000) {
1254 aclk = 0xb7;
1255 bclk = 0x47;
1256 } else if (srate < 3000000) {
1257 aclk = 0xb7;
1258 bclk = 0x4b;
1259 } else if (srate < 7000000) {
1260 aclk = 0xb7;
1261 bclk = 0x4f;
1262 } else if (srate < 14000000) {
1263 aclk = 0xb7;
1264 bclk = 0x53;
1265 } else if (srate < 30000000) {
1266 aclk = 0xb6;
1267 bclk = 0x53;
1268 } else if (srate < 45000000) {
1269 aclk = 0xb4;
1270 bclk = 0x51;
1271 }
1272
1273 stv0299_writereg(fe, 0x13, aclk);
1274 stv0299_writereg(fe, 0x14, bclk);
1275 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
1276 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
1277 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
1278
1279 return 0;
1280}
1281
1282static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe)
1283{
1284 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1285 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1286 u8 buf[4];
1287 u32 div;
1288 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1289
1290 if ((p->frequency < 950000) || (p->frequency > 2150000))
1291 return -EINVAL;
1292
1293 div = (p->frequency + (125 - 1)) / 125; /* round correctly */
1294 buf[0] = (div >> 8) & 0x7f;
1295 buf[1] = div & 0xff;
1296 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
1297 buf[3] = 0xC4;
1298
1299 if (p->frequency > 1530000)
1300 buf[3] = 0xC0;
1301
1302 /* BSBE1 wants XCE bit set */
1303 if (ttusb->revision == TTUSB_REV_2_2)
1304 buf[3] |= 0x20;
1305
1306 if (fe->ops.i2c_gate_ctrl)
1307 fe->ops.i2c_gate_ctrl(fe, 1);
1308 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1309 return -EIO;
1310
1311 return 0;
1312}
1313
1314static struct stv0299_config alps_stv0299_config = {
1315 .demod_address = 0x68,
1316 .inittab = alps_bsru6_inittab,
1317 .mclk = 88000000UL,
1318 .invert = 1,
1319 .skip_reinit = 0,
1320 .lock_output = STV0299_LOCKOUTPUT_1,
1321 .volt13_op0_op1 = STV0299_VOLT13_OP1,
1322 .min_delay_ms = 100,
1323 .set_symbol_rate = alps_stv0299_set_symbol_rate,
1324};
1325
1326static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *fe)
1327{
1328 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1329 struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
1330 u8 buf[4];
1331 u32 div;
1332 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
1333
1334 div = p->frequency / 125;
1335
1336 buf[0] = (div >> 8) & 0x7f;
1337 buf[1] = div & 0xff;
1338 buf[2] = 0x8e;
1339 buf[3] = 0x00;
1340
1341 if (fe->ops.i2c_gate_ctrl)
1342 fe->ops.i2c_gate_ctrl(fe, 1);
1343 if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
1344 return -EIO;
1345
1346 return 0;
1347}
1348
1349static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
1350
1351 .demod_address = 0x68,
1352};
1353
1354static int alps_tdbe2_tuner_set_params(struct dvb_frontend *fe)
1355{
1356 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1357 struct ttusb* ttusb = fe->dvb->priv;
1358 u32 div;
1359 u8 data[4];
1360 struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
1361
1362 div = (p->frequency + 35937500 + 31250) / 62500;
1363
1364 data[0] = (div >> 8) & 0x7f;
1365 data[1] = div & 0xff;
1366 data[2] = 0x85 | ((div >> 10) & 0x60);
1367 data[3] = (p->frequency < 174000000 ? 0x88 : p->frequency < 470000000 ? 0x84 : 0x81);
1368
1369 if (fe->ops.i2c_gate_ctrl)
1370 fe->ops.i2c_gate_ctrl(fe, 1);
1371 if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1)
1372 return -EIO;
1373
1374 return 0;
1375}
1376
1377
1378static struct ves1820_config alps_tdbe2_config = {
1379 .demod_address = 0x09,
1380 .xin = 57840000UL,
1381 .invert = 1,
1382 .selagc = VES1820_SELAGC_SIGNAMPERR,
1383};
1384
1385static u8 read_pwm(struct ttusb* ttusb)
1386{
1387 u8 b = 0xff;
1388 u8 pwm;
1389 struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
1390 { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
1391
1392 if ((i2c_transfer(&ttusb->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
1393 pwm = 0x48;
1394
1395 return pwm;
1396}
1397
1398
1399static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe)
1400{
1401 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1402 struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv;
1403 u8 tuner_buf[5];
1404 struct i2c_msg tuner_msg = {.addr = 0x60,
1405 .flags = 0,
1406 .buf = tuner_buf,
1407 .len = sizeof(tuner_buf) };
1408 int tuner_frequency = 0;
1409 u8 band, cp, filter;
1410
1411 // determine charge pump
1412 tuner_frequency = p->frequency;
1413 if (tuner_frequency < 87000000) {return -EINVAL;}
1414 else if (tuner_frequency < 130000000) {cp = 3; band = 1;}
1415 else if (tuner_frequency < 160000000) {cp = 5; band = 1;}
1416 else if (tuner_frequency < 200000000) {cp = 6; band = 1;}
1417 else if (tuner_frequency < 290000000) {cp = 3; band = 2;}
1418 else if (tuner_frequency < 420000000) {cp = 5; band = 2;}
1419 else if (tuner_frequency < 480000000) {cp = 6; band = 2;}
1420 else if (tuner_frequency < 620000000) {cp = 3; band = 4;}
1421 else if (tuner_frequency < 830000000) {cp = 5; band = 4;}
1422 else if (tuner_frequency < 895000000) {cp = 7; band = 4;}
1423 else {return -EINVAL;}
1424
1425 // assume PLL filter should always be 8MHz for the moment.
1426 filter = 1;
1427
1428 // calculate divisor
1429 // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz
1430 tuner_frequency = ((p->frequency + 36125000) / 62500);
1431
1432 // setup tuner buffer
1433 tuner_buf[0] = tuner_frequency >> 8;
1434 tuner_buf[1] = tuner_frequency & 0xff;
1435 tuner_buf[2] = 0xc8;
1436 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
1437 tuner_buf[4] = 0x80;
1438
1439 if (fe->ops.i2c_gate_ctrl)
1440 fe->ops.i2c_gate_ctrl(fe, 1);
1441 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1442 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n");
1443 return -EIO;
1444 }
1445
1446 msleep(50);
1447
1448 if (fe->ops.i2c_gate_ctrl)
1449 fe->ops.i2c_gate_ctrl(fe, 1);
1450 if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) {
1451 printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n");
1452 return -EIO;
1453 }
1454
1455 msleep(1);
1456
1457 return 0;
1458}
1459
1460static u8 dvbc_philips_tdm1316l_inittab[] = {
1461 0x80, 0x21,
1462 0x80, 0x20,
1463 0x81, 0x01,
1464 0x81, 0x00,
1465 0x00, 0x09,
1466 0x01, 0x69,
1467 0x03, 0x00,
1468 0x04, 0x00,
1469 0x07, 0x00,
1470 0x08, 0x00,
1471 0x20, 0x00,
1472 0x21, 0x40,
1473 0x22, 0x00,
1474 0x23, 0x00,
1475 0x24, 0x40,
1476 0x25, 0x88,
1477 0x30, 0xff,
1478 0x31, 0x00,
1479 0x32, 0xff,
1480 0x33, 0x00,
1481 0x34, 0x50,
1482 0x35, 0x7f,
1483 0x36, 0x00,
1484 0x37, 0x20,
1485 0x38, 0x00,
1486 0x40, 0x1c,
1487 0x41, 0xff,
1488 0x42, 0x29,
1489 0x43, 0x20,
1490 0x44, 0xff,
1491 0x45, 0x00,
1492 0x46, 0x00,
1493 0x49, 0x04,
1494 0x4a, 0xff,
1495 0x4b, 0x7f,
1496 0x52, 0x30,
1497 0x55, 0xae,
1498 0x56, 0x47,
1499 0x57, 0xe1,
1500 0x58, 0x3a,
1501 0x5a, 0x1e,
1502 0x5b, 0x34,
1503 0x60, 0x00,
1504 0x63, 0x00,
1505 0x64, 0x00,
1506 0x65, 0x00,
1507 0x66, 0x00,
1508 0x67, 0x00,
1509 0x68, 0x00,
1510 0x69, 0x00,
1511 0x6a, 0x02,
1512 0x6b, 0x00,
1513 0x70, 0xff,
1514 0x71, 0x00,
1515 0x72, 0x00,
1516 0x73, 0x00,
1517 0x74, 0x0c,
1518 0x80, 0x00,
1519 0x81, 0x00,
1520 0x82, 0x00,
1521 0x83, 0x00,
1522 0x84, 0x04,
1523 0x85, 0x80,
1524 0x86, 0x24,
1525 0x87, 0x78,
1526 0x88, 0x00,
1527 0x89, 0x00,
1528 0x90, 0x01,
1529 0x91, 0x01,
1530 0xa0, 0x00,
1531 0xa1, 0x00,
1532 0xa2, 0x00,
1533 0xb0, 0x91,
1534 0xb1, 0x0b,
1535 0xc0, 0x4b,
1536 0xc1, 0x00,
1537 0xc2, 0x00,
1538 0xd0, 0x00,
1539 0xd1, 0x00,
1540 0xd2, 0x00,
1541 0xd3, 0x00,
1542 0xd4, 0x00,
1543 0xd5, 0x00,
1544 0xde, 0x00,
1545 0xdf, 0x00,
1546 0x61, 0x38,
1547 0x62, 0x0a,
1548 0x53, 0x13,
1549 0x59, 0x08,
1550 0x55, 0x00,
1551 0x56, 0x40,
1552 0x57, 0x08,
1553 0x58, 0x3d,
1554 0x88, 0x10,
1555 0xa0, 0x00,
1556 0xa0, 0x00,
1557 0xa0, 0x00,
1558 0xa0, 0x04,
1559 0xff, 0xff,
1560};
1561
1562static struct stv0297_config dvbc_philips_tdm1316l_config = {
1563 .demod_address = 0x1c,
1564 .inittab = dvbc_philips_tdm1316l_inittab,
1565 .invert = 0,
1566};
1567
1568static void frontend_init(struct ttusb* ttusb)
1569{
1570 switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) {
1571 case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6|BSBE1(tsa5059))
1572 // try the stv0299 based first
1573 ttusb->fe = dvb_attach(stv0299_attach, &alps_stv0299_config, &ttusb->i2c_adap);
1574 if (ttusb->fe != NULL) {
1575 ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params;
1576
1577 if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1
1578 alps_stv0299_config.inittab = alps_bsbe1_inittab;
1579 dvb_attach(lnbp21_attach, ttusb->fe, &ttusb->i2c_adap, 0, 0);
1580 } else { // ALPS BSRU6
1581 ttusb->fe->ops.set_voltage = ttusb_set_voltage;
1582 }
1583 break;
1584 }
1585
1586 // Grundig 29504-491
1587 ttusb->fe = dvb_attach(tda8083_attach, &ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
1588 if (ttusb->fe != NULL) {
1589 ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params;
1590 ttusb->fe->ops.set_voltage = ttusb_set_voltage;
1591 break;
1592 }
1593 break;
1594
1595 case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659))
1596 ttusb->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb));
1597 if (ttusb->fe != NULL) {
1598 ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params;
1599 break;
1600 }
1601
1602 ttusb->fe = dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &ttusb->i2c_adap);
1603 if (ttusb->fe != NULL) {
1604 ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params;
1605 break;
1606 }
1607 break;
1608
1609 case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
1610 // try the ALPS TDMB7 first
1611 ttusb->fe = dvb_attach(cx22700_attach, &alps_tdmb7_config, &ttusb->i2c_adap);
1612 if (ttusb->fe != NULL) {
1613 ttusb->fe->ops.tuner_ops.set_params = alps_tdmb7_tuner_set_params;
1614 break;
1615 }
1616
1617 // Philips td1316
1618 ttusb->fe = dvb_attach(tda10046_attach, &philips_tdm1316l_config, &ttusb->i2c_adap);
1619 if (ttusb->fe != NULL) {
1620 ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init;
1621 ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params;
1622 break;
1623 }
1624 break;
1625 }
1626
1627 if (ttusb->fe == NULL) {
1628 printk("dvb-ttusb-budget: A frontend driver was not found for device [%04x:%04x]\n",
1629 le16_to_cpu(ttusb->dev->descriptor.idVendor),
1630 le16_to_cpu(ttusb->dev->descriptor.idProduct));
1631 } else {
1632 if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) {
1633 printk("dvb-ttusb-budget: Frontend registration failed!\n");
1634 dvb_frontend_detach(ttusb->fe);
1635 ttusb->fe = NULL;
1636 }
1637 }
1638}
1639
1640
1641
1642static struct i2c_algorithm ttusb_dec_algo = {
1643 .master_xfer = master_xfer,
1644 .functionality = functionality,
1645};
1646
1647static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1648{
1649 struct usb_device *udev;
1650 struct ttusb *ttusb;
1651 int result;
1652
1653 dprintk("%s: TTUSB DVB connected\n", __func__);
1654
1655 udev = interface_to_usbdev(intf);
1656
1657 if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
1658
1659 if (!(ttusb = kzalloc(sizeof(struct ttusb), GFP_KERNEL)))
1660 return -ENOMEM;
1661
1662 ttusb->dev = udev;
1663 ttusb->c = 0;
1664 ttusb->mux_state = 0;
1665 mutex_init(&ttusb->semi2c);
1666
1667 mutex_lock(&ttusb->semi2c);
1668
1669 mutex_init(&ttusb->semusb);
1670
1671 ttusb_setup_interfaces(ttusb);
1672
1673 result = ttusb_alloc_iso_urbs(ttusb);
1674 if (result < 0) {
1675 dprintk("%s: ttusb_alloc_iso_urbs - failed\n", __func__);
1676 mutex_unlock(&ttusb->semi2c);
1677 kfree(ttusb);
1678 return result;
1679 }
1680
1681 if (ttusb_init_controller(ttusb))
1682 printk("ttusb_init_controller: error\n");
1683
1684 mutex_unlock(&ttusb->semi2c);
1685
1686 result = dvb_register_adapter(&ttusb->adapter,
1687 "Technotrend/Hauppauge Nova-USB",
1688 THIS_MODULE, &udev->dev, adapter_nr);
1689 if (result < 0) {
1690 ttusb_free_iso_urbs(ttusb);
1691 kfree(ttusb);
1692 return result;
1693 }
1694 ttusb->adapter.priv = ttusb;
1695
1696 /* i2c */
1697 memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
1698 strcpy(ttusb->i2c_adap.name, "TTUSB DEC");
1699
1700 i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
1701
1702 ttusb->i2c_adap.algo = &ttusb_dec_algo;
1703 ttusb->i2c_adap.algo_data = NULL;
1704 ttusb->i2c_adap.dev.parent = &udev->dev;
1705
1706 result = i2c_add_adapter(&ttusb->i2c_adap);
1707 if (result)
1708 goto err_unregister_adapter;
1709
1710 memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux));
1711
1712 ttusb->dvb_demux.dmx.capabilities =
1713 DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1714 ttusb->dvb_demux.priv = NULL;
1715#ifdef TTUSB_HWSECTIONS
1716 ttusb->dvb_demux.filternum = TTUSB_MAXFILTER;
1717#else
1718 ttusb->dvb_demux.filternum = 32;
1719#endif
1720 ttusb->dvb_demux.feednum = TTUSB_MAXCHANNEL;
1721 ttusb->dvb_demux.start_feed = ttusb_start_feed;
1722 ttusb->dvb_demux.stop_feed = ttusb_stop_feed;
1723 ttusb->dvb_demux.write_to_decoder = NULL;
1724
1725 result = dvb_dmx_init(&ttusb->dvb_demux);
1726 if (result < 0) {
1727 printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result);
1728 result = -ENODEV;
1729 goto err_i2c_del_adapter;
1730 }
1731//FIXME dmxdev (nur WAS?)
1732 ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum;
1733 ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx;
1734 ttusb->dmxdev.capabilities = 0;
1735
1736 result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter);
1737 if (result < 0) {
1738 printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n",
1739 result);
1740 result = -ENODEV;
1741 goto err_release_dmx;
1742 }
1743
1744 if (dvb_net_init(&ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
1745 printk("ttusb_dvb: dvb_net_init failed!\n");
1746 result = -ENODEV;
1747 goto err_release_dmxdev;
1748 }
1749
1750 usb_set_intfdata(intf, (void *) ttusb);
1751
1752 frontend_init(ttusb);
1753
1754 return 0;
1755
1756err_release_dmxdev:
1757 dvb_dmxdev_release(&ttusb->dmxdev);
1758err_release_dmx:
1759 dvb_dmx_release(&ttusb->dvb_demux);
1760err_i2c_del_adapter:
1761 i2c_del_adapter(&ttusb->i2c_adap);
1762err_unregister_adapter:
1763 dvb_unregister_adapter (&ttusb->adapter);
1764 return result;
1765}
1766
1767static void ttusb_disconnect(struct usb_interface *intf)
1768{
1769 struct ttusb *ttusb = usb_get_intfdata(intf);
1770
1771 usb_set_intfdata(intf, NULL);
1772
1773 ttusb->disconnecting = 1;
1774
1775 ttusb_stop_iso_xfer(ttusb);
1776
1777 ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx);
1778 dvb_net_release(&ttusb->dvbnet);
1779 dvb_dmxdev_release(&ttusb->dmxdev);
1780 dvb_dmx_release(&ttusb->dvb_demux);
1781 if (ttusb->fe != NULL) {
1782 dvb_unregister_frontend(ttusb->fe);
1783 dvb_frontend_detach(ttusb->fe);
1784 }
1785 i2c_del_adapter(&ttusb->i2c_adap);
1786 dvb_unregister_adapter(&ttusb->adapter);
1787
1788 ttusb_free_iso_urbs(ttusb);
1789
1790 kfree(ttusb);
1791
1792 dprintk("%s: TTUSB DVB disconnected\n", __func__);
1793}
1794
1795static struct usb_device_id ttusb_table[] = {
1796 {USB_DEVICE(0xb48, 0x1003)},
1797 {USB_DEVICE(0xb48, 0x1004)},
1798 {USB_DEVICE(0xb48, 0x1005)},
1799 {}
1800};
1801
1802MODULE_DEVICE_TABLE(usb, ttusb_table);
1803
1804static struct usb_driver ttusb_driver = {
1805 .name = "ttusb",
1806 .probe = ttusb_probe,
1807 .disconnect = ttusb_disconnect,
1808 .id_table = ttusb_table,
1809};
1810
1811module_usb_driver(ttusb_driver);
1812
1813MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
1814MODULE_DESCRIPTION("TTUSB DVB Driver");
1815MODULE_LICENSE("GPL");
1816MODULE_FIRMWARE("ttusb-budget/dspbootcode.bin");
diff --git a/drivers/media/usb/ttusb-dec/Kconfig b/drivers/media/usb/ttusb-dec/Kconfig
new file mode 100644
index 000000000000..290254ab06db
--- /dev/null
+++ b/drivers/media/usb/ttusb-dec/Kconfig
@@ -0,0 +1,21 @@
1config DVB_TTUSB_DEC
2 tristate "Technotrend/Hauppauge USB DEC devices"
3 depends on DVB_CORE && USB && INPUT && PCI
4 select CRC32
5 help
6 Support for external USB adapters designed by Technotrend and
7 produced by Hauppauge, shipped under the brand name 'DEC2000-t'
8 and 'DEC3000-s'.
9
10 Even if these devices have a MPEG decoder built in, they transmit
11 only compressed MPEG data over the USB bus, so you need
12 an external software decoder to watch TV on your computer.
13
14 This driver needs external firmware. Please use the commands
15 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t",
16 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t",
17 "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s",
18 download/extract them, and then copy them to /usr/lib/hotplug/firmware
19 or /lib/firmware (depending on configuration of firmware hotplug).
20
21 Say Y if you own such a device and want to use it.
diff --git a/drivers/media/usb/ttusb-dec/Makefile b/drivers/media/usb/ttusb-dec/Makefile
new file mode 100644
index 000000000000..5352740d2353
--- /dev/null
+++ b/drivers/media/usb/ttusb-dec/Makefile
@@ -0,0 +1,3 @@
1obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o ttusbdecfe.o
2
3ccflags-y += -Idrivers/media/dvb-core/
diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c
new file mode 100644
index 000000000000..504c81230339
--- /dev/null
+++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c
@@ -0,0 +1,1764 @@
1/*
2 * TTUSB DEC Driver
3 *
4 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
5 * IR support by Peter Beutner <p.beutner@gmx.net>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23#include <linux/list.h>
24#include <linux/module.h>
25#include <linux/pci.h>
26#include <linux/slab.h>
27#include <linux/spinlock.h>
28#include <linux/usb.h>
29#include <linux/interrupt.h>
30#include <linux/firmware.h>
31#include <linux/crc32.h>
32#include <linux/init.h>
33#include <linux/input.h>
34
35#include <linux/mutex.h>
36
37#include "dmxdev.h"
38#include "dvb_demux.h"
39#include "dvb_filter.h"
40#include "dvb_frontend.h"
41#include "dvb_net.h"
42#include "ttusbdecfe.h"
43
44static int debug;
45static int output_pva;
46static int enable_rc;
47
48module_param(debug, int, 0644);
49MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
50module_param(output_pva, int, 0444);
51MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)");
52module_param(enable_rc, int, 0644);
53MODULE_PARM_DESC(enable_rc, "Turn on/off IR remote control(default: off)");
54
55DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
56
57#define dprintk if (debug) printk
58
59#define DRIVER_NAME "TechnoTrend/Hauppauge DEC USB"
60
61#define COMMAND_PIPE 0x03
62#define RESULT_PIPE 0x04
63#define IN_PIPE 0x08
64#define OUT_PIPE 0x07
65#define IRQ_PIPE 0x0A
66
67#define COMMAND_PACKET_SIZE 0x3c
68#define ARM_PACKET_SIZE 0x1000
69#define IRQ_PACKET_SIZE 0x8
70
71#define ISO_BUF_COUNT 0x04
72#define FRAMES_PER_ISO_BUF 0x04
73#define ISO_FRAME_SIZE 0x0380
74
75#define MAX_PVA_LENGTH 6144
76
77enum ttusb_dec_model {
78 TTUSB_DEC2000T,
79 TTUSB_DEC2540T,
80 TTUSB_DEC3000S
81};
82
83enum ttusb_dec_packet_type {
84 TTUSB_DEC_PACKET_PVA,
85 TTUSB_DEC_PACKET_SECTION,
86 TTUSB_DEC_PACKET_EMPTY
87};
88
89enum ttusb_dec_interface {
90 TTUSB_DEC_INTERFACE_INITIAL,
91 TTUSB_DEC_INTERFACE_IN,
92 TTUSB_DEC_INTERFACE_OUT
93};
94
95struct ttusb_dec {
96 enum ttusb_dec_model model;
97 char *model_name;
98 char *firmware_name;
99 int can_playback;
100
101 /* DVB bits */
102 struct dvb_adapter adapter;
103 struct dmxdev dmxdev;
104 struct dvb_demux demux;
105 struct dmx_frontend frontend;
106 struct dvb_net dvb_net;
107 struct dvb_frontend* fe;
108
109 u16 pid[DMX_PES_OTHER];
110
111 /* USB bits */
112 struct usb_device *udev;
113 u8 trans_count;
114 unsigned int command_pipe;
115 unsigned int result_pipe;
116 unsigned int in_pipe;
117 unsigned int out_pipe;
118 unsigned int irq_pipe;
119 enum ttusb_dec_interface interface;
120 struct mutex usb_mutex;
121
122 void *irq_buffer;
123 struct urb *irq_urb;
124 dma_addr_t irq_dma_handle;
125 void *iso_buffer;
126 dma_addr_t iso_dma_handle;
127 struct urb *iso_urb[ISO_BUF_COUNT];
128 int iso_stream_count;
129 struct mutex iso_mutex;
130
131 u8 packet[MAX_PVA_LENGTH + 4];
132 enum ttusb_dec_packet_type packet_type;
133 int packet_state;
134 int packet_length;
135 int packet_payload_length;
136 u16 next_packet_id;
137
138 int pva_stream_count;
139 int filter_stream_count;
140
141 struct dvb_filter_pes2ts a_pes2ts;
142 struct dvb_filter_pes2ts v_pes2ts;
143
144 u8 v_pes[16 + MAX_PVA_LENGTH];
145 int v_pes_length;
146 int v_pes_postbytes;
147
148 struct list_head urb_frame_list;
149 struct tasklet_struct urb_tasklet;
150 spinlock_t urb_frame_list_lock;
151
152 struct dvb_demux_filter *audio_filter;
153 struct dvb_demux_filter *video_filter;
154 struct list_head filter_info_list;
155 spinlock_t filter_info_list_lock;
156
157 struct input_dev *rc_input_dev;
158 char rc_phys[64];
159
160 int active; /* Loaded successfully */
161};
162
163struct urb_frame {
164 u8 data[ISO_FRAME_SIZE];
165 int length;
166 struct list_head urb_frame_list;
167};
168
169struct filter_info {
170 u8 stream_id;
171 struct dvb_demux_filter *filter;
172 struct list_head filter_info_list;
173};
174
175static u16 rc_keys[] = {
176 KEY_POWER,
177 KEY_MUTE,
178 KEY_1,
179 KEY_2,
180 KEY_3,
181 KEY_4,
182 KEY_5,
183 KEY_6,
184 KEY_7,
185 KEY_8,
186 KEY_9,
187 KEY_0,
188 KEY_CHANNELUP,
189 KEY_VOLUMEDOWN,
190 KEY_OK,
191 KEY_VOLUMEUP,
192 KEY_CHANNELDOWN,
193 KEY_PREVIOUS,
194 KEY_ESC,
195 KEY_RED,
196 KEY_GREEN,
197 KEY_YELLOW,
198 KEY_BLUE,
199 KEY_OPTION,
200 KEY_M,
201 KEY_RADIO
202};
203
204static void ttusb_dec_set_model(struct ttusb_dec *dec,
205 enum ttusb_dec_model model);
206
207static void ttusb_dec_handle_irq( struct urb *urb)
208{
209 struct ttusb_dec * dec = urb->context;
210 char *buffer = dec->irq_buffer;
211 int retval;
212
213 switch(urb->status) {
214 case 0: /*success*/
215 break;
216 case -ECONNRESET:
217 case -ENOENT:
218 case -ESHUTDOWN:
219 case -ETIME:
220 /* this urb is dead, cleanup */
221 dprintk("%s:urb shutting down with status: %d\n",
222 __func__, urb->status);
223 return;
224 default:
225 dprintk("%s:nonzero status received: %d\n",
226 __func__,urb->status);
227 goto exit;
228 }
229
230 if( (buffer[0] == 0x1) && (buffer[2] == 0x15) ) {
231 /* IR - Event */
232 /* this is an fact a bit too simple implementation;
233 * the box also reports a keyrepeat signal
234 * (with buffer[3] == 0x40) in an intervall of ~100ms.
235 * But to handle this correctly we had to imlemenent some
236 * kind of timer which signals a 'key up' event if no
237 * keyrepeat signal is received for lets say 200ms.
238 * this should/could be added later ...
239 * for now lets report each signal as a key down and up*/
240 dprintk("%s:rc signal:%d\n", __func__, buffer[4]);
241 input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1);
242 input_sync(dec->rc_input_dev);
243 input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0);
244 input_sync(dec->rc_input_dev);
245 }
246
247exit: retval = usb_submit_urb(urb, GFP_ATOMIC);
248 if(retval)
249 printk("%s - usb_commit_urb failed with result: %d\n",
250 __func__, retval);
251}
252
253static u16 crc16(u16 crc, const u8 *buf, size_t len)
254{
255 u16 tmp;
256
257 while (len--) {
258 crc ^= *buf++;
259 crc ^= (u8)crc >> 4;
260 tmp = (u8)crc;
261 crc ^= (tmp ^ (tmp << 1)) << 4;
262 }
263 return crc;
264}
265
266static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command,
267 int param_length, const u8 params[],
268 int *result_length, u8 cmd_result[])
269{
270 int result, actual_len, i;
271 u8 *b;
272
273 dprintk("%s\n", __func__);
274
275 b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL);
276 if (!b)
277 return -ENOMEM;
278
279 if ((result = mutex_lock_interruptible(&dec->usb_mutex))) {
280 kfree(b);
281 printk("%s: Failed to lock usb mutex.\n", __func__);
282 return result;
283 }
284
285 b[0] = 0xaa;
286 b[1] = ++dec->trans_count;
287 b[2] = command;
288 b[3] = param_length;
289
290 if (params)
291 memcpy(&b[4], params, param_length);
292
293 if (debug) {
294 printk("%s: command: ", __func__);
295 for (i = 0; i < param_length + 4; i++)
296 printk("0x%02X ", b[i]);
297 printk("\n");
298 }
299
300 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
301 COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
302
303 if (result) {
304 printk("%s: command bulk message failed: error %d\n",
305 __func__, result);
306 mutex_unlock(&dec->usb_mutex);
307 kfree(b);
308 return result;
309 }
310
311 result = usb_bulk_msg(dec->udev, dec->result_pipe, b,
312 COMMAND_PACKET_SIZE + 4, &actual_len, 1000);
313
314 if (result) {
315 printk("%s: result bulk message failed: error %d\n",
316 __func__, result);
317 mutex_unlock(&dec->usb_mutex);
318 kfree(b);
319 return result;
320 } else {
321 if (debug) {
322 printk("%s: result: ", __func__);
323 for (i = 0; i < actual_len; i++)
324 printk("0x%02X ", b[i]);
325 printk("\n");
326 }
327
328 if (result_length)
329 *result_length = b[3];
330 if (cmd_result && b[3] > 0)
331 memcpy(cmd_result, &b[4], b[3]);
332
333 mutex_unlock(&dec->usb_mutex);
334
335 kfree(b);
336 return 0;
337 }
338}
339
340static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode,
341 unsigned int *model, unsigned int *version)
342{
343 u8 c[COMMAND_PACKET_SIZE];
344 int c_length;
345 int result;
346 __be32 tmp;
347
348 dprintk("%s\n", __func__);
349
350 result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c);
351 if (result)
352 return result;
353
354 if (c_length >= 0x0c) {
355 if (mode != NULL) {
356 memcpy(&tmp, c, 4);
357 *mode = ntohl(tmp);
358 }
359 if (model != NULL) {
360 memcpy(&tmp, &c[4], 4);
361 *model = ntohl(tmp);
362 }
363 if (version != NULL) {
364 memcpy(&tmp, &c[8], 4);
365 *version = ntohl(tmp);
366 }
367 return 0;
368 } else {
369 return -1;
370 }
371}
372
373static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data)
374{
375 struct ttusb_dec *dec = priv;
376
377 dec->audio_filter->feed->cb.ts(data, 188, NULL, 0,
378 &dec->audio_filter->feed->feed.ts,
379 DMX_OK);
380
381 return 0;
382}
383
384static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data)
385{
386 struct ttusb_dec *dec = priv;
387
388 dec->video_filter->feed->cb.ts(data, 188, NULL, 0,
389 &dec->video_filter->feed->feed.ts,
390 DMX_OK);
391
392 return 0;
393}
394
395static void ttusb_dec_set_pids(struct ttusb_dec *dec)
396{
397 u8 b[] = { 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0xff, 0xff,
399 0xff, 0xff, 0xff, 0xff };
400
401 __be16 pcr = htons(dec->pid[DMX_PES_PCR]);
402 __be16 audio = htons(dec->pid[DMX_PES_AUDIO]);
403 __be16 video = htons(dec->pid[DMX_PES_VIDEO]);
404
405 dprintk("%s\n", __func__);
406
407 memcpy(&b[0], &pcr, 2);
408 memcpy(&b[2], &audio, 2);
409 memcpy(&b[4], &video, 2);
410
411 ttusb_dec_send_command(dec, 0x50, sizeof(b), b, NULL, NULL);
412
413 dvb_filter_pes2ts_init(&dec->a_pes2ts, dec->pid[DMX_PES_AUDIO],
414 ttusb_dec_audio_pes2ts_cb, dec);
415 dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO],
416 ttusb_dec_video_pes2ts_cb, dec);
417 dec->v_pes_length = 0;
418 dec->v_pes_postbytes = 0;
419}
420
421static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length)
422{
423 if (length < 8) {
424 printk("%s: packet too short - discarding\n", __func__);
425 return;
426 }
427
428 if (length > 8 + MAX_PVA_LENGTH) {
429 printk("%s: packet too long - discarding\n", __func__);
430 return;
431 }
432
433 switch (pva[2]) {
434
435 case 0x01: { /* VideoStream */
436 int prebytes = pva[5] & 0x03;
437 int postbytes = (pva[5] & 0x0c) >> 2;
438 __be16 v_pes_payload_length;
439
440 if (output_pva) {
441 dec->video_filter->feed->cb.ts(pva, length, NULL, 0,
442 &dec->video_filter->feed->feed.ts, DMX_OK);
443 return;
444 }
445
446 if (dec->v_pes_postbytes > 0 &&
447 dec->v_pes_postbytes == prebytes) {
448 memcpy(&dec->v_pes[dec->v_pes_length],
449 &pva[12], prebytes);
450
451 dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
452 dec->v_pes_length + prebytes, 1);
453 }
454
455 if (pva[5] & 0x10) {
456 dec->v_pes[7] = 0x80;
457 dec->v_pes[8] = 0x05;
458
459 dec->v_pes[9] = 0x21 | ((pva[8] & 0xc0) >> 5);
460 dec->v_pes[10] = ((pva[8] & 0x3f) << 2) |
461 ((pva[9] & 0xc0) >> 6);
462 dec->v_pes[11] = 0x01 |
463 ((pva[9] & 0x3f) << 2) |
464 ((pva[10] & 0x80) >> 6);
465 dec->v_pes[12] = ((pva[10] & 0x7f) << 1) |
466 ((pva[11] & 0xc0) >> 7);
467 dec->v_pes[13] = 0x01 | ((pva[11] & 0x7f) << 1);
468
469 memcpy(&dec->v_pes[14], &pva[12 + prebytes],
470 length - 12 - prebytes);
471 dec->v_pes_length = 14 + length - 12 - prebytes;
472 } else {
473 dec->v_pes[7] = 0x00;
474 dec->v_pes[8] = 0x00;
475
476 memcpy(&dec->v_pes[9], &pva[8], length - 8);
477 dec->v_pes_length = 9 + length - 8;
478 }
479
480 dec->v_pes_postbytes = postbytes;
481
482 if (dec->v_pes[9 + dec->v_pes[8]] == 0x00 &&
483 dec->v_pes[10 + dec->v_pes[8]] == 0x00 &&
484 dec->v_pes[11 + dec->v_pes[8]] == 0x01)
485 dec->v_pes[6] = 0x84;
486 else
487 dec->v_pes[6] = 0x80;
488
489 v_pes_payload_length = htons(dec->v_pes_length - 6 +
490 postbytes);
491 memcpy(&dec->v_pes[4], &v_pes_payload_length, 2);
492
493 if (postbytes == 0)
494 dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
495 dec->v_pes_length, 1);
496
497 break;
498 }
499
500 case 0x02: /* MainAudioStream */
501 if (output_pva) {
502 dec->audio_filter->feed->cb.ts(pva, length, NULL, 0,
503 &dec->audio_filter->feed->feed.ts, DMX_OK);
504 return;
505 }
506
507 dvb_filter_pes2ts(&dec->a_pes2ts, &pva[8], length - 8,
508 pva[5] & 0x10);
509 break;
510
511 default:
512 printk("%s: unknown PVA type: %02x.\n", __func__,
513 pva[2]);
514 break;
515 }
516}
517
518static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet,
519 int length)
520{
521 struct list_head *item;
522 struct filter_info *finfo;
523 struct dvb_demux_filter *filter = NULL;
524 unsigned long flags;
525 u8 sid;
526
527 sid = packet[1];
528 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
529 for (item = dec->filter_info_list.next; item != &dec->filter_info_list;
530 item = item->next) {
531 finfo = list_entry(item, struct filter_info, filter_info_list);
532 if (finfo->stream_id == sid) {
533 filter = finfo->filter;
534 break;
535 }
536 }
537 spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
538
539 if (filter)
540 filter->feed->cb.sec(&packet[2], length - 2, NULL, 0,
541 &filter->filter, DMX_OK);
542}
543
544static void ttusb_dec_process_packet(struct ttusb_dec *dec)
545{
546 int i;
547 u16 csum = 0;
548 u16 packet_id;
549
550 if (dec->packet_length % 2) {
551 printk("%s: odd sized packet - discarding\n", __func__);
552 return;
553 }
554
555 for (i = 0; i < dec->packet_length; i += 2)
556 csum ^= ((dec->packet[i] << 8) + dec->packet[i + 1]);
557
558 if (csum) {
559 printk("%s: checksum failed - discarding\n", __func__);
560 return;
561 }
562
563 packet_id = dec->packet[dec->packet_length - 4] << 8;
564 packet_id += dec->packet[dec->packet_length - 3];
565
566 if ((packet_id != dec->next_packet_id) && dec->next_packet_id) {
567 printk("%s: warning: lost packets between %u and %u\n",
568 __func__, dec->next_packet_id - 1, packet_id);
569 }
570
571 if (packet_id == 0xffff)
572 dec->next_packet_id = 0x8000;
573 else
574 dec->next_packet_id = packet_id + 1;
575
576 switch (dec->packet_type) {
577 case TTUSB_DEC_PACKET_PVA:
578 if (dec->pva_stream_count)
579 ttusb_dec_process_pva(dec, dec->packet,
580 dec->packet_payload_length);
581 break;
582
583 case TTUSB_DEC_PACKET_SECTION:
584 if (dec->filter_stream_count)
585 ttusb_dec_process_filter(dec, dec->packet,
586 dec->packet_payload_length);
587 break;
588
589 case TTUSB_DEC_PACKET_EMPTY:
590 break;
591 }
592}
593
594static void swap_bytes(u8 *b, int length)
595{
596 u8 c;
597
598 length -= length % 2;
599 for (; length; b += 2, length -= 2) {
600 c = *b;
601 *b = *(b + 1);
602 *(b + 1) = c;
603 }
604}
605
606static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b,
607 int length)
608{
609 swap_bytes(b, length);
610
611 while (length) {
612 switch (dec->packet_state) {
613
614 case 0:
615 case 1:
616 case 2:
617 if (*b++ == 0xaa)
618 dec->packet_state++;
619 else
620 dec->packet_state = 0;
621
622 length--;
623 break;
624
625 case 3:
626 if (*b == 0x00) {
627 dec->packet_state++;
628 dec->packet_length = 0;
629 } else if (*b != 0xaa) {
630 dec->packet_state = 0;
631 }
632
633 b++;
634 length--;
635 break;
636
637 case 4:
638 dec->packet[dec->packet_length++] = *b++;
639
640 if (dec->packet_length == 2) {
641 if (dec->packet[0] == 'A' &&
642 dec->packet[1] == 'V') {
643 dec->packet_type =
644 TTUSB_DEC_PACKET_PVA;
645 dec->packet_state++;
646 } else if (dec->packet[0] == 'S') {
647 dec->packet_type =
648 TTUSB_DEC_PACKET_SECTION;
649 dec->packet_state++;
650 } else if (dec->packet[0] == 0x00) {
651 dec->packet_type =
652 TTUSB_DEC_PACKET_EMPTY;
653 dec->packet_payload_length = 2;
654 dec->packet_state = 7;
655 } else {
656 printk("%s: unknown packet type: "
657 "%02x%02x\n", __func__,
658 dec->packet[0], dec->packet[1]);
659 dec->packet_state = 0;
660 }
661 }
662
663 length--;
664 break;
665
666 case 5:
667 dec->packet[dec->packet_length++] = *b++;
668
669 if (dec->packet_type == TTUSB_DEC_PACKET_PVA &&
670 dec->packet_length == 8) {
671 dec->packet_state++;
672 dec->packet_payload_length = 8 +
673 (dec->packet[6] << 8) +
674 dec->packet[7];
675 } else if (dec->packet_type ==
676 TTUSB_DEC_PACKET_SECTION &&
677 dec->packet_length == 5) {
678 dec->packet_state++;
679 dec->packet_payload_length = 5 +
680 ((dec->packet[3] & 0x0f) << 8) +
681 dec->packet[4];
682 }
683
684 length--;
685 break;
686
687 case 6: {
688 int remainder = dec->packet_payload_length -
689 dec->packet_length;
690
691 if (length >= remainder) {
692 memcpy(dec->packet + dec->packet_length,
693 b, remainder);
694 dec->packet_length += remainder;
695 b += remainder;
696 length -= remainder;
697 dec->packet_state++;
698 } else {
699 memcpy(&dec->packet[dec->packet_length],
700 b, length);
701 dec->packet_length += length;
702 length = 0;
703 }
704
705 break;
706 }
707
708 case 7: {
709 int tail = 4;
710
711 dec->packet[dec->packet_length++] = *b++;
712
713 if (dec->packet_type == TTUSB_DEC_PACKET_SECTION &&
714 dec->packet_payload_length % 2)
715 tail++;
716
717 if (dec->packet_length ==
718 dec->packet_payload_length + tail) {
719 ttusb_dec_process_packet(dec);
720 dec->packet_state = 0;
721 }
722
723 length--;
724 break;
725 }
726
727 default:
728 printk("%s: illegal packet state encountered.\n",
729 __func__);
730 dec->packet_state = 0;
731 }
732 }
733}
734
735static void ttusb_dec_process_urb_frame_list(unsigned long data)
736{
737 struct ttusb_dec *dec = (struct ttusb_dec *)data;
738 struct list_head *item;
739 struct urb_frame *frame;
740 unsigned long flags;
741
742 while (1) {
743 spin_lock_irqsave(&dec->urb_frame_list_lock, flags);
744 if ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
745 frame = list_entry(item, struct urb_frame,
746 urb_frame_list);
747 list_del(&frame->urb_frame_list);
748 } else {
749 spin_unlock_irqrestore(&dec->urb_frame_list_lock,
750 flags);
751 return;
752 }
753 spin_unlock_irqrestore(&dec->urb_frame_list_lock, flags);
754
755 ttusb_dec_process_urb_frame(dec, frame->data, frame->length);
756 kfree(frame);
757 }
758}
759
760static void ttusb_dec_process_urb(struct urb *urb)
761{
762 struct ttusb_dec *dec = urb->context;
763
764 if (!urb->status) {
765 int i;
766
767 for (i = 0; i < FRAMES_PER_ISO_BUF; i++) {
768 struct usb_iso_packet_descriptor *d;
769 u8 *b;
770 int length;
771 struct urb_frame *frame;
772
773 d = &urb->iso_frame_desc[i];
774 b = urb->transfer_buffer + d->offset;
775 length = d->actual_length;
776
777 if ((frame = kmalloc(sizeof(struct urb_frame),
778 GFP_ATOMIC))) {
779 unsigned long flags;
780
781 memcpy(frame->data, b, length);
782 frame->length = length;
783
784 spin_lock_irqsave(&dec->urb_frame_list_lock,
785 flags);
786 list_add_tail(&frame->urb_frame_list,
787 &dec->urb_frame_list);
788 spin_unlock_irqrestore(&dec->urb_frame_list_lock,
789 flags);
790
791 tasklet_schedule(&dec->urb_tasklet);
792 }
793 }
794 } else {
795 /* -ENOENT is expected when unlinking urbs */
796 if (urb->status != -ENOENT)
797 dprintk("%s: urb error: %d\n", __func__,
798 urb->status);
799 }
800
801 if (dec->iso_stream_count)
802 usb_submit_urb(urb, GFP_ATOMIC);
803}
804
805static void ttusb_dec_setup_urbs(struct ttusb_dec *dec)
806{
807 int i, j, buffer_offset = 0;
808
809 dprintk("%s\n", __func__);
810
811 for (i = 0; i < ISO_BUF_COUNT; i++) {
812 int frame_offset = 0;
813 struct urb *urb = dec->iso_urb[i];
814
815 urb->dev = dec->udev;
816 urb->context = dec;
817 urb->complete = ttusb_dec_process_urb;
818 urb->pipe = dec->in_pipe;
819 urb->transfer_flags = URB_ISO_ASAP;
820 urb->interval = 1;
821 urb->number_of_packets = FRAMES_PER_ISO_BUF;
822 urb->transfer_buffer_length = ISO_FRAME_SIZE *
823 FRAMES_PER_ISO_BUF;
824 urb->transfer_buffer = dec->iso_buffer + buffer_offset;
825 buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF;
826
827 for (j = 0; j < FRAMES_PER_ISO_BUF; j++) {
828 urb->iso_frame_desc[j].offset = frame_offset;
829 urb->iso_frame_desc[j].length = ISO_FRAME_SIZE;
830 frame_offset += ISO_FRAME_SIZE;
831 }
832 }
833}
834
835static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec)
836{
837 int i;
838
839 dprintk("%s\n", __func__);
840
841 if (mutex_lock_interruptible(&dec->iso_mutex))
842 return;
843
844 dec->iso_stream_count--;
845
846 if (!dec->iso_stream_count) {
847 for (i = 0; i < ISO_BUF_COUNT; i++)
848 usb_kill_urb(dec->iso_urb[i]);
849 }
850
851 mutex_unlock(&dec->iso_mutex);
852}
853
854/* Setting the interface of the DEC tends to take down the USB communications
855 * for a short period, so it's important not to call this function just before
856 * trying to talk to it.
857 */
858static int ttusb_dec_set_interface(struct ttusb_dec *dec,
859 enum ttusb_dec_interface interface)
860{
861 int result = 0;
862 u8 b[] = { 0x05 };
863
864 if (interface != dec->interface) {
865 switch (interface) {
866 case TTUSB_DEC_INTERFACE_INITIAL:
867 result = usb_set_interface(dec->udev, 0, 0);
868 break;
869 case TTUSB_DEC_INTERFACE_IN:
870 result = ttusb_dec_send_command(dec, 0x80, sizeof(b),
871 b, NULL, NULL);
872 if (result)
873 return result;
874 result = usb_set_interface(dec->udev, 0, 8);
875 break;
876 case TTUSB_DEC_INTERFACE_OUT:
877 result = usb_set_interface(dec->udev, 0, 1);
878 break;
879 }
880
881 if (result)
882 return result;
883
884 dec->interface = interface;
885 }
886
887 return 0;
888}
889
890static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec)
891{
892 int i, result;
893
894 dprintk("%s\n", __func__);
895
896 if (mutex_lock_interruptible(&dec->iso_mutex))
897 return -EAGAIN;
898
899 if (!dec->iso_stream_count) {
900 ttusb_dec_setup_urbs(dec);
901
902 dec->packet_state = 0;
903 dec->v_pes_postbytes = 0;
904 dec->next_packet_id = 0;
905
906 for (i = 0; i < ISO_BUF_COUNT; i++) {
907 if ((result = usb_submit_urb(dec->iso_urb[i],
908 GFP_ATOMIC))) {
909 printk("%s: failed urb submission %d: "
910 "error %d\n", __func__, i, result);
911
912 while (i) {
913 usb_kill_urb(dec->iso_urb[i - 1]);
914 i--;
915 }
916
917 mutex_unlock(&dec->iso_mutex);
918 return result;
919 }
920 }
921 }
922
923 dec->iso_stream_count++;
924
925 mutex_unlock(&dec->iso_mutex);
926
927 return 0;
928}
929
930static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
931{
932 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
933 struct ttusb_dec *dec = dvbdmx->priv;
934 u8 b0[] = { 0x05 };
935 int result = 0;
936
937 dprintk("%s\n", __func__);
938
939 dprintk(" ts_type:");
940
941 if (dvbdmxfeed->ts_type & TS_DECODER)
942 dprintk(" TS_DECODER");
943
944 if (dvbdmxfeed->ts_type & TS_PACKET)
945 dprintk(" TS_PACKET");
946
947 if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
948 dprintk(" TS_PAYLOAD_ONLY");
949
950 dprintk("\n");
951
952 switch (dvbdmxfeed->pes_type) {
953
954 case DMX_TS_PES_VIDEO:
955 dprintk(" pes_type: DMX_TS_PES_VIDEO\n");
956 dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
957 dec->pid[DMX_PES_VIDEO] = dvbdmxfeed->pid;
958 dec->video_filter = dvbdmxfeed->filter;
959 ttusb_dec_set_pids(dec);
960 break;
961
962 case DMX_TS_PES_AUDIO:
963 dprintk(" pes_type: DMX_TS_PES_AUDIO\n");
964 dec->pid[DMX_PES_AUDIO] = dvbdmxfeed->pid;
965 dec->audio_filter = dvbdmxfeed->filter;
966 ttusb_dec_set_pids(dec);
967 break;
968
969 case DMX_TS_PES_TELETEXT:
970 dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid;
971 dprintk(" pes_type: DMX_TS_PES_TELETEXT(not supported)\n");
972 return -ENOSYS;
973
974 case DMX_TS_PES_PCR:
975 dprintk(" pes_type: DMX_TS_PES_PCR\n");
976 dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid;
977 ttusb_dec_set_pids(dec);
978 break;
979
980 case DMX_TS_PES_OTHER:
981 dprintk(" pes_type: DMX_TS_PES_OTHER(not supported)\n");
982 return -ENOSYS;
983
984 default:
985 dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type);
986 return -EINVAL;
987
988 }
989
990 result = ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL);
991 if (result)
992 return result;
993
994 dec->pva_stream_count++;
995 return ttusb_dec_start_iso_xfer(dec);
996}
997
998static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
999{
1000 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1001 u8 b0[] = { 0x00, 0x00, 0x00, 0x01,
1002 0x00, 0x00, 0x00, 0x00,
1003 0x00, 0x00, 0x00, 0x00,
1004 0x00, 0x00, 0x00, 0x00,
1005 0x00, 0xff, 0x00, 0x00,
1006 0x00, 0x00, 0x00, 0x00,
1007 0x00, 0x00, 0x00, 0x00,
1008 0x00 };
1009 __be16 pid;
1010 u8 c[COMMAND_PACKET_SIZE];
1011 int c_length;
1012 int result;
1013 struct filter_info *finfo;
1014 unsigned long flags;
1015 u8 x = 1;
1016
1017 dprintk("%s\n", __func__);
1018
1019 pid = htons(dvbdmxfeed->pid);
1020 memcpy(&b0[0], &pid, 2);
1021 memcpy(&b0[4], &x, 1);
1022 memcpy(&b0[5], &dvbdmxfeed->filter->filter.filter_value[0], 1);
1023
1024 result = ttusb_dec_send_command(dec, 0x60, sizeof(b0), b0,
1025 &c_length, c);
1026
1027 if (!result) {
1028 if (c_length == 2) {
1029 if (!(finfo = kmalloc(sizeof(struct filter_info),
1030 GFP_ATOMIC)))
1031 return -ENOMEM;
1032
1033 finfo->stream_id = c[1];
1034 finfo->filter = dvbdmxfeed->filter;
1035
1036 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
1037 list_add_tail(&finfo->filter_info_list,
1038 &dec->filter_info_list);
1039 spin_unlock_irqrestore(&dec->filter_info_list_lock,
1040 flags);
1041
1042 dvbdmxfeed->priv = finfo;
1043
1044 dec->filter_stream_count++;
1045 return ttusb_dec_start_iso_xfer(dec);
1046 }
1047
1048 return -EAGAIN;
1049 } else
1050 return result;
1051}
1052
1053static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed)
1054{
1055 struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
1056
1057 dprintk("%s\n", __func__);
1058
1059 if (!dvbdmx->dmx.frontend)
1060 return -EINVAL;
1061
1062 dprintk(" pid: 0x%04X\n", dvbdmxfeed->pid);
1063
1064 switch (dvbdmxfeed->type) {
1065
1066 case DMX_TYPE_TS:
1067 return ttusb_dec_start_ts_feed(dvbdmxfeed);
1068 break;
1069
1070 case DMX_TYPE_SEC:
1071 return ttusb_dec_start_sec_feed(dvbdmxfeed);
1072 break;
1073
1074 default:
1075 dprintk(" type: unknown (%d)\n", dvbdmxfeed->type);
1076 return -EINVAL;
1077
1078 }
1079}
1080
1081static int ttusb_dec_stop_ts_feed(struct dvb_demux_feed *dvbdmxfeed)
1082{
1083 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1084 u8 b0[] = { 0x00 };
1085
1086 ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL);
1087
1088 dec->pva_stream_count--;
1089
1090 ttusb_dec_stop_iso_xfer(dec);
1091
1092 return 0;
1093}
1094
1095static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed)
1096{
1097 struct ttusb_dec *dec = dvbdmxfeed->demux->priv;
1098 u8 b0[] = { 0x00, 0x00 };
1099 struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv;
1100 unsigned long flags;
1101
1102 b0[1] = finfo->stream_id;
1103 spin_lock_irqsave(&dec->filter_info_list_lock, flags);
1104 list_del(&finfo->filter_info_list);
1105 spin_unlock_irqrestore(&dec->filter_info_list_lock, flags);
1106 kfree(finfo);
1107 ttusb_dec_send_command(dec, 0x62, sizeof(b0), b0, NULL, NULL);
1108
1109 dec->filter_stream_count--;
1110
1111 ttusb_dec_stop_iso_xfer(dec);
1112
1113 return 0;
1114}
1115
1116static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
1117{
1118 dprintk("%s\n", __func__);
1119
1120 switch (dvbdmxfeed->type) {
1121 case DMX_TYPE_TS:
1122 return ttusb_dec_stop_ts_feed(dvbdmxfeed);
1123 break;
1124
1125 case DMX_TYPE_SEC:
1126 return ttusb_dec_stop_sec_feed(dvbdmxfeed);
1127 break;
1128 }
1129
1130 return 0;
1131}
1132
1133static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec)
1134{
1135 int i;
1136
1137 dprintk("%s\n", __func__);
1138
1139 for (i = 0; i < ISO_BUF_COUNT; i++)
1140 usb_free_urb(dec->iso_urb[i]);
1141
1142 pci_free_consistent(NULL,
1143 ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *
1144 ISO_BUF_COUNT),
1145 dec->iso_buffer, dec->iso_dma_handle);
1146}
1147
1148static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
1149{
1150 int i;
1151
1152 dprintk("%s\n", __func__);
1153
1154 dec->iso_buffer = pci_alloc_consistent(NULL,
1155 ISO_FRAME_SIZE *
1156 (FRAMES_PER_ISO_BUF *
1157 ISO_BUF_COUNT),
1158 &dec->iso_dma_handle);
1159
1160 if (!dec->iso_buffer) {
1161 dprintk("%s: pci_alloc_consistent - not enough memory\n",
1162 __func__);
1163 return -ENOMEM;
1164 }
1165
1166 memset(dec->iso_buffer, 0,
1167 ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT));
1168
1169 for (i = 0; i < ISO_BUF_COUNT; i++) {
1170 struct urb *urb;
1171
1172 if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
1173 ttusb_dec_free_iso_urbs(dec);
1174 return -ENOMEM;
1175 }
1176
1177 dec->iso_urb[i] = urb;
1178 }
1179
1180 ttusb_dec_setup_urbs(dec);
1181
1182 return 0;
1183}
1184
1185static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
1186{
1187 spin_lock_init(&dec->urb_frame_list_lock);
1188 INIT_LIST_HEAD(&dec->urb_frame_list);
1189 tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list,
1190 (unsigned long)dec);
1191}
1192
1193static int ttusb_init_rc( struct ttusb_dec *dec)
1194{
1195 struct input_dev *input_dev;
1196 u8 b[] = { 0x00, 0x01 };
1197 int i;
1198 int err;
1199
1200 usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
1201 strlcat(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
1202
1203 input_dev = input_allocate_device();
1204 if (!input_dev)
1205 return -ENOMEM;
1206
1207 input_dev->name = "ttusb_dec remote control";
1208 input_dev->phys = dec->rc_phys;
1209 input_dev->evbit[0] = BIT_MASK(EV_KEY);
1210 input_dev->keycodesize = sizeof(u16);
1211 input_dev->keycodemax = 0x1a;
1212 input_dev->keycode = rc_keys;
1213
1214 for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
1215 set_bit(rc_keys[i], input_dev->keybit);
1216
1217 err = input_register_device(input_dev);
1218 if (err) {
1219 input_free_device(input_dev);
1220 return err;
1221 }
1222
1223 dec->rc_input_dev = input_dev;
1224 if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
1225 printk("%s: usb_submit_urb failed\n",__func__);
1226 /* enable irq pipe */
1227 ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
1228
1229 return 0;
1230}
1231
1232static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
1233{
1234 dprintk("%s\n", __func__);
1235
1236 dec->v_pes[0] = 0x00;
1237 dec->v_pes[1] = 0x00;
1238 dec->v_pes[2] = 0x01;
1239 dec->v_pes[3] = 0xe0;
1240}
1241
1242static int ttusb_dec_init_usb(struct ttusb_dec *dec)
1243{
1244 dprintk("%s\n", __func__);
1245
1246 mutex_init(&dec->usb_mutex);
1247 mutex_init(&dec->iso_mutex);
1248
1249 dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE);
1250 dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE);
1251 dec->in_pipe = usb_rcvisocpipe(dec->udev, IN_PIPE);
1252 dec->out_pipe = usb_sndisocpipe(dec->udev, OUT_PIPE);
1253 dec->irq_pipe = usb_rcvintpipe(dec->udev, IRQ_PIPE);
1254
1255 if(enable_rc) {
1256 dec->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
1257 if(!dec->irq_urb) {
1258 return -ENOMEM;
1259 }
1260 dec->irq_buffer = usb_alloc_coherent(dec->udev,IRQ_PACKET_SIZE,
1261 GFP_ATOMIC, &dec->irq_dma_handle);
1262 if(!dec->irq_buffer) {
1263 usb_free_urb(dec->irq_urb);
1264 return -ENOMEM;
1265 }
1266 usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe,
1267 dec->irq_buffer, IRQ_PACKET_SIZE,
1268 ttusb_dec_handle_irq, dec, 1);
1269 dec->irq_urb->transfer_dma = dec->irq_dma_handle;
1270 dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
1271 }
1272
1273 return ttusb_dec_alloc_iso_urbs(dec);
1274}
1275
1276static int ttusb_dec_boot_dsp(struct ttusb_dec *dec)
1277{
1278 int i, j, actual_len, result, size, trans_count;
1279 u8 b0[] = { 0x00, 0x00, 0x00, 0x00,
1280 0x00, 0x00, 0x00, 0x00,
1281 0x61, 0x00 };
1282 u8 b1[] = { 0x61 };
1283 u8 *b;
1284 char idstring[21];
1285 const u8 *firmware = NULL;
1286 size_t firmware_size = 0;
1287 u16 firmware_csum = 0;
1288 __be16 firmware_csum_ns;
1289 __be32 firmware_size_nl;
1290 u32 crc32_csum, crc32_check;
1291 __be32 tmp;
1292 const struct firmware *fw_entry = NULL;
1293
1294 dprintk("%s\n", __func__);
1295
1296 if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) {
1297 printk(KERN_ERR "%s: Firmware (%s) unavailable.\n",
1298 __func__, dec->firmware_name);
1299 return 1;
1300 }
1301
1302 firmware = fw_entry->data;
1303 firmware_size = fw_entry->size;
1304
1305 if (firmware_size < 60) {
1306 printk("%s: firmware size too small for DSP code (%zu < 60).\n",
1307 __func__, firmware_size);
1308 release_firmware(fw_entry);
1309 return -1;
1310 }
1311
1312 /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored
1313 at offset 56 of file, so use it to check if the firmware file is
1314 valid. */
1315 crc32_csum = crc32(~0L, firmware, 56) ^ ~0L;
1316 memcpy(&tmp, &firmware[56], 4);
1317 crc32_check = ntohl(tmp);
1318 if (crc32_csum != crc32_check) {
1319 printk("%s: crc32 check of DSP code failed (calculated "
1320 "0x%08x != 0x%08x in file), file invalid.\n",
1321 __func__, crc32_csum, crc32_check);
1322 release_firmware(fw_entry);
1323 return -1;
1324 }
1325 memcpy(idstring, &firmware[36], 20);
1326 idstring[20] = '\0';
1327 printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring);
1328
1329 firmware_size_nl = htonl(firmware_size);
1330 memcpy(b0, &firmware_size_nl, 4);
1331 firmware_csum = crc16(~0, firmware, firmware_size) ^ ~0;
1332 firmware_csum_ns = htons(firmware_csum);
1333 memcpy(&b0[6], &firmware_csum_ns, 2);
1334
1335 result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL);
1336
1337 if (result) {
1338 release_firmware(fw_entry);
1339 return result;
1340 }
1341
1342 trans_count = 0;
1343 j = 0;
1344
1345 b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL);
1346 if (b == NULL) {
1347 release_firmware(fw_entry);
1348 return -ENOMEM;
1349 }
1350
1351 for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) {
1352 size = firmware_size - i;
1353 if (size > COMMAND_PACKET_SIZE)
1354 size = COMMAND_PACKET_SIZE;
1355
1356 b[j + 0] = 0xaa;
1357 b[j + 1] = trans_count++;
1358 b[j + 2] = 0xf0;
1359 b[j + 3] = size;
1360 memcpy(&b[j + 4], &firmware[i], size);
1361
1362 j += COMMAND_PACKET_SIZE + 4;
1363
1364 if (j >= ARM_PACKET_SIZE) {
1365 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
1366 ARM_PACKET_SIZE, &actual_len,
1367 100);
1368 j = 0;
1369 } else if (size < COMMAND_PACKET_SIZE) {
1370 result = usb_bulk_msg(dec->udev, dec->command_pipe, b,
1371 j - COMMAND_PACKET_SIZE + size,
1372 &actual_len, 100);
1373 }
1374 }
1375
1376 result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL);
1377
1378 release_firmware(fw_entry);
1379 kfree(b);
1380
1381 return result;
1382}
1383
1384static int ttusb_dec_init_stb(struct ttusb_dec *dec)
1385{
1386 int result;
1387 unsigned int mode = 0, model = 0, version = 0;
1388
1389 dprintk("%s\n", __func__);
1390
1391 result = ttusb_dec_get_stb_state(dec, &mode, &model, &version);
1392
1393 if (!result) {
1394 if (!mode) {
1395 if (version == 0xABCDEFAB)
1396 printk(KERN_INFO "ttusb_dec: no version "
1397 "info in Firmware\n");
1398 else
1399 printk(KERN_INFO "ttusb_dec: Firmware "
1400 "%x.%02x%c%c\n",
1401 version >> 24, (version >> 16) & 0xff,
1402 (version >> 8) & 0xff, version & 0xff);
1403
1404 result = ttusb_dec_boot_dsp(dec);
1405 if (result)
1406 return result;
1407 else
1408 return 1;
1409 } else {
1410 /* We can't trust the USB IDs that some firmwares
1411 give the box */
1412 switch (model) {
1413 case 0x00070001:
1414 case 0x00070008:
1415 case 0x0007000c:
1416 ttusb_dec_set_model(dec, TTUSB_DEC3000S);
1417 break;
1418 case 0x00070009:
1419 case 0x00070013:
1420 ttusb_dec_set_model(dec, TTUSB_DEC2000T);
1421 break;
1422 case 0x00070011:
1423 ttusb_dec_set_model(dec, TTUSB_DEC2540T);
1424 break;
1425 default:
1426 printk(KERN_ERR "%s: unknown model returned "
1427 "by firmware (%08x) - please report\n",
1428 __func__, model);
1429 return -1;
1430 break;
1431 }
1432
1433 if (version >= 0x01770000)
1434 dec->can_playback = 1;
1435
1436 return 0;
1437 }
1438 }
1439 else
1440 return result;
1441}
1442
1443static int ttusb_dec_init_dvb(struct ttusb_dec *dec)
1444{
1445 int result;
1446
1447 dprintk("%s\n", __func__);
1448
1449 if ((result = dvb_register_adapter(&dec->adapter,
1450 dec->model_name, THIS_MODULE,
1451 &dec->udev->dev,
1452 adapter_nr)) < 0) {
1453 printk("%s: dvb_register_adapter failed: error %d\n",
1454 __func__, result);
1455
1456 return result;
1457 }
1458
1459 dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
1460
1461 dec->demux.priv = (void *)dec;
1462 dec->demux.filternum = 31;
1463 dec->demux.feednum = 31;
1464 dec->demux.start_feed = ttusb_dec_start_feed;
1465 dec->demux.stop_feed = ttusb_dec_stop_feed;
1466 dec->demux.write_to_decoder = NULL;
1467
1468 if ((result = dvb_dmx_init(&dec->demux)) < 0) {
1469 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
1470 result);
1471
1472 dvb_unregister_adapter(&dec->adapter);
1473
1474 return result;
1475 }
1476
1477 dec->dmxdev.filternum = 32;
1478 dec->dmxdev.demux = &dec->demux.dmx;
1479 dec->dmxdev.capabilities = 0;
1480
1481 if ((result = dvb_dmxdev_init(&dec->dmxdev, &dec->adapter)) < 0) {
1482 printk("%s: dvb_dmxdev_init failed: error %d\n",
1483 __func__, result);
1484
1485 dvb_dmx_release(&dec->demux);
1486 dvb_unregister_adapter(&dec->adapter);
1487
1488 return result;
1489 }
1490
1491 dec->frontend.source = DMX_FRONTEND_0;
1492
1493 if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx,
1494 &dec->frontend)) < 0) {
1495 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
1496 result);
1497
1498 dvb_dmxdev_release(&dec->dmxdev);
1499 dvb_dmx_release(&dec->demux);
1500 dvb_unregister_adapter(&dec->adapter);
1501
1502 return result;
1503 }
1504
1505 if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx,
1506 &dec->frontend)) < 0) {
1507 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
1508 result);
1509
1510 dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
1511 dvb_dmxdev_release(&dec->dmxdev);
1512 dvb_dmx_release(&dec->demux);
1513 dvb_unregister_adapter(&dec->adapter);
1514
1515 return result;
1516 }
1517
1518 dvb_net_init(&dec->adapter, &dec->dvb_net, &dec->demux.dmx);
1519
1520 return 0;
1521}
1522
1523static void ttusb_dec_exit_dvb(struct ttusb_dec *dec)
1524{
1525 dprintk("%s\n", __func__);
1526
1527 dvb_net_release(&dec->dvb_net);
1528 dec->demux.dmx.close(&dec->demux.dmx);
1529 dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend);
1530 dvb_dmxdev_release(&dec->dmxdev);
1531 dvb_dmx_release(&dec->demux);
1532 if (dec->fe) {
1533 dvb_unregister_frontend(dec->fe);
1534 if (dec->fe->ops.release)
1535 dec->fe->ops.release(dec->fe);
1536 }
1537 dvb_unregister_adapter(&dec->adapter);
1538}
1539
1540static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
1541{
1542
1543 dprintk("%s\n", __func__);
1544 /* we have to check whether the irq URB is already submitted.
1545 * As the irq is submitted after the interface is changed,
1546 * this is the best method i figured out.
1547 * Any others?*/
1548 if (dec->interface == TTUSB_DEC_INTERFACE_IN)
1549 usb_kill_urb(dec->irq_urb);
1550
1551 usb_free_urb(dec->irq_urb);
1552
1553 usb_free_coherent(dec->udev,IRQ_PACKET_SIZE,
1554 dec->irq_buffer, dec->irq_dma_handle);
1555
1556 if (dec->rc_input_dev) {
1557 input_unregister_device(dec->rc_input_dev);
1558 dec->rc_input_dev = NULL;
1559 }
1560}
1561
1562
1563static void ttusb_dec_exit_usb(struct ttusb_dec *dec)
1564{
1565 int i;
1566
1567 dprintk("%s\n", __func__);
1568
1569 dec->iso_stream_count = 0;
1570
1571 for (i = 0; i < ISO_BUF_COUNT; i++)
1572 usb_kill_urb(dec->iso_urb[i]);
1573
1574 ttusb_dec_free_iso_urbs(dec);
1575}
1576
1577static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec)
1578{
1579 struct list_head *item;
1580 struct urb_frame *frame;
1581
1582 tasklet_kill(&dec->urb_tasklet);
1583
1584 while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
1585 frame = list_entry(item, struct urb_frame, urb_frame_list);
1586 list_del(&frame->urb_frame_list);
1587 kfree(frame);
1588 }
1589}
1590
1591static void ttusb_dec_init_filters(struct ttusb_dec *dec)
1592{
1593 INIT_LIST_HEAD(&dec->filter_info_list);
1594 spin_lock_init(&dec->filter_info_list_lock);
1595}
1596
1597static void ttusb_dec_exit_filters(struct ttusb_dec *dec)
1598{
1599 struct list_head *item;
1600 struct filter_info *finfo;
1601
1602 while ((item = dec->filter_info_list.next) != &dec->filter_info_list) {
1603 finfo = list_entry(item, struct filter_info, filter_info_list);
1604 list_del(&finfo->filter_info_list);
1605 kfree(finfo);
1606 }
1607}
1608
1609static int fe_send_command(struct dvb_frontend* fe, const u8 command,
1610 int param_length, const u8 params[],
1611 int *result_length, u8 cmd_result[])
1612{
1613 struct ttusb_dec* dec = fe->dvb->priv;
1614 return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result);
1615}
1616
1617static struct ttusbdecfe_config fe_config = {
1618 .send_command = fe_send_command
1619};
1620
1621static int ttusb_dec_probe(struct usb_interface *intf,
1622 const struct usb_device_id *id)
1623{
1624 struct usb_device *udev;
1625 struct ttusb_dec *dec;
1626
1627 dprintk("%s\n", __func__);
1628
1629 udev = interface_to_usbdev(intf);
1630
1631 if (!(dec = kzalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) {
1632 printk("%s: couldn't allocate memory.\n", __func__);
1633 return -ENOMEM;
1634 }
1635
1636 usb_set_intfdata(intf, (void *)dec);
1637
1638 switch (id->idProduct) {
1639 case 0x1006:
1640 ttusb_dec_set_model(dec, TTUSB_DEC3000S);
1641 break;
1642
1643 case 0x1008:
1644 ttusb_dec_set_model(dec, TTUSB_DEC2000T);
1645 break;
1646
1647 case 0x1009:
1648 ttusb_dec_set_model(dec, TTUSB_DEC2540T);
1649 break;
1650 }
1651
1652 dec->udev = udev;
1653
1654 if (ttusb_dec_init_usb(dec))
1655 return 0;
1656 if (ttusb_dec_init_stb(dec)) {
1657 ttusb_dec_exit_usb(dec);
1658 return 0;
1659 }
1660 ttusb_dec_init_dvb(dec);
1661
1662 dec->adapter.priv = dec;
1663 switch (id->idProduct) {
1664 case 0x1006:
1665 dec->fe = ttusbdecfe_dvbs_attach(&fe_config);
1666 break;
1667
1668 case 0x1008:
1669 case 0x1009:
1670 dec->fe = ttusbdecfe_dvbt_attach(&fe_config);
1671 break;
1672 }
1673
1674 if (dec->fe == NULL) {
1675 printk("dvb-ttusb-dec: A frontend driver was not found for device [%04x:%04x]\n",
1676 le16_to_cpu(dec->udev->descriptor.idVendor),
1677 le16_to_cpu(dec->udev->descriptor.idProduct));
1678 } else {
1679 if (dvb_register_frontend(&dec->adapter, dec->fe)) {
1680 printk("budget-ci: Frontend registration failed!\n");
1681 if (dec->fe->ops.release)
1682 dec->fe->ops.release(dec->fe);
1683 dec->fe = NULL;
1684 }
1685 }
1686
1687 ttusb_dec_init_v_pes(dec);
1688 ttusb_dec_init_filters(dec);
1689 ttusb_dec_init_tasklet(dec);
1690
1691 dec->active = 1;
1692
1693 ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
1694
1695 if (enable_rc)
1696 ttusb_init_rc(dec);
1697
1698 return 0;
1699}
1700
1701static void ttusb_dec_disconnect(struct usb_interface *intf)
1702{
1703 struct ttusb_dec *dec = usb_get_intfdata(intf);
1704
1705 usb_set_intfdata(intf, NULL);
1706
1707 dprintk("%s\n", __func__);
1708
1709 if (dec->active) {
1710 ttusb_dec_exit_tasklet(dec);
1711 ttusb_dec_exit_filters(dec);
1712 if(enable_rc)
1713 ttusb_dec_exit_rc(dec);
1714 ttusb_dec_exit_usb(dec);
1715 ttusb_dec_exit_dvb(dec);
1716 }
1717
1718 kfree(dec);
1719}
1720
1721static void ttusb_dec_set_model(struct ttusb_dec *dec,
1722 enum ttusb_dec_model model)
1723{
1724 dec->model = model;
1725
1726 switch (model) {
1727 case TTUSB_DEC2000T:
1728 dec->model_name = "DEC2000-t";
1729 dec->firmware_name = "dvb-ttusb-dec-2000t.fw";
1730 break;
1731
1732 case TTUSB_DEC2540T:
1733 dec->model_name = "DEC2540-t";
1734 dec->firmware_name = "dvb-ttusb-dec-2540t.fw";
1735 break;
1736
1737 case TTUSB_DEC3000S:
1738 dec->model_name = "DEC3000-s";
1739 dec->firmware_name = "dvb-ttusb-dec-3000s.fw";
1740 break;
1741 }
1742}
1743
1744static struct usb_device_id ttusb_dec_table[] = {
1745 {USB_DEVICE(0x0b48, 0x1006)}, /* DEC3000-s */
1746 /*{USB_DEVICE(0x0b48, 0x1007)}, Unconfirmed */
1747 {USB_DEVICE(0x0b48, 0x1008)}, /* DEC2000-t */
1748 {USB_DEVICE(0x0b48, 0x1009)}, /* DEC2540-t */
1749 {}
1750};
1751
1752static struct usb_driver ttusb_dec_driver = {
1753 .name = "ttusb-dec",
1754 .probe = ttusb_dec_probe,
1755 .disconnect = ttusb_dec_disconnect,
1756 .id_table = ttusb_dec_table,
1757};
1758
1759module_usb_driver(ttusb_dec_driver);
1760
1761MODULE_AUTHOR("Alex Woods <linux-dvb@giblets.org>");
1762MODULE_DESCRIPTION(DRIVER_NAME);
1763MODULE_LICENSE("GPL");
1764MODULE_DEVICE_TABLE(usb, ttusb_dec_table);
diff --git a/drivers/media/usb/ttusb-dec/ttusbdecfe.c b/drivers/media/usb/ttusb-dec/ttusbdecfe.c
new file mode 100644
index 000000000000..5c45c9d0712d
--- /dev/null
+++ b/drivers/media/usb/ttusb-dec/ttusbdecfe.c
@@ -0,0 +1,298 @@
1/*
2 * TTUSB DEC Frontend Driver
3 *
4 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#include "dvb_frontend.h"
23#include "ttusbdecfe.h"
24
25
26#define LOF_HI 10600000
27#define LOF_LO 9750000
28
29struct ttusbdecfe_state {
30
31 /* configuration settings */
32 const struct ttusbdecfe_config* config;
33
34 struct dvb_frontend frontend;
35
36 u8 hi_band;
37 u8 voltage;
38};
39
40
41static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe,
42 fe_status_t *status)
43{
44 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
45 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
46 return 0;
47}
48
49
50static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe,
51 fe_status_t *status)
52{
53 struct ttusbdecfe_state* state = fe->demodulator_priv;
54 u8 b[] = { 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00 };
56 u8 result[4];
57 int len, ret;
58
59 *status=0;
60
61 ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result);
62 if(ret)
63 return ret;
64
65 if(len != 4) {
66 printk(KERN_ERR "%s: unexpected reply\n", __func__);
67 return -EIO;
68 }
69
70 switch(result[3]) {
71 case 1: /* not tuned yet */
72 case 2: /* no signal/no lock*/
73 break;
74 case 3: /* signal found and locked*/
75 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
76 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
77 break;
78 case 4:
79 *status = FE_TIMEDOUT;
80 break;
81 default:
82 pr_info("%s: returned unknown value: %d\n",
83 __func__, result[3]);
84 return -EIO;
85 }
86
87 return 0;
88}
89
90static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend *fe)
91{
92 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
93 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
94 u8 b[] = { 0x00, 0x00, 0x00, 0x03,
95 0x00, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x01,
97 0x00, 0x00, 0x00, 0xff,
98 0x00, 0x00, 0x00, 0xff };
99
100 __be32 freq = htonl(p->frequency / 1000);
101 memcpy(&b[4], &freq, sizeof (u32));
102 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
103
104 return 0;
105}
106
107static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
108 struct dvb_frontend_tune_settings* fesettings)
109{
110 fesettings->min_delay_ms = 1500;
111 /* Drift compensation makes no sense for DVB-T */
112 fesettings->step_size = 0;
113 fesettings->max_drift = 0;
114 return 0;
115}
116
117static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend *fe)
118{
119 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
120 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
121
122 u8 b[] = { 0x00, 0x00, 0x00, 0x01,
123 0x00, 0x00, 0x00, 0x00,
124 0x00, 0x00, 0x00, 0x01,
125 0x00, 0x00, 0x00, 0x00,
126 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00 };
132 __be32 freq;
133 __be32 sym_rate;
134 __be32 band;
135 __be32 lnb_voltage;
136
137 freq = htonl(p->frequency +
138 (state->hi_band ? LOF_HI : LOF_LO));
139 memcpy(&b[4], &freq, sizeof(u32));
140 sym_rate = htonl(p->symbol_rate);
141 memcpy(&b[12], &sym_rate, sizeof(u32));
142 band = htonl(state->hi_band ? LOF_HI : LOF_LO);
143 memcpy(&b[24], &band, sizeof(u32));
144 lnb_voltage = htonl(state->voltage);
145 memcpy(&b[28], &lnb_voltage, sizeof(u32));
146
147 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
148
149 return 0;
150}
151
152static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
153{
154 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
155 u8 b[] = { 0x00, 0xff, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x00 };
158
159 memcpy(&b[4], cmd->msg, cmd->msg_len);
160
161 state->config->send_command(fe, 0x72,
162 sizeof(b) - (6 - cmd->msg_len), b,
163 NULL, NULL);
164
165 return 0;
166}
167
168
169static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
170{
171 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
172
173 state->hi_band = (SEC_TONE_ON == tone);
174
175 return 0;
176}
177
178
179static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
180{
181 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
182
183 switch (voltage) {
184 case SEC_VOLTAGE_13:
185 state->voltage = 13;
186 break;
187 case SEC_VOLTAGE_18:
188 state->voltage = 18;
189 break;
190 default:
191 return -EINVAL;
192 }
193
194 return 0;
195}
196
197static void ttusbdecfe_release(struct dvb_frontend* fe)
198{
199 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
200 kfree(state);
201}
202
203static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
204
205struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
206{
207 struct ttusbdecfe_state* state = NULL;
208
209 /* allocate memory for the internal state */
210 state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
211 if (state == NULL)
212 return NULL;
213
214 /* setup the state */
215 state->config = config;
216
217 /* create dvb_frontend */
218 memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
219 state->frontend.demodulator_priv = state;
220 return &state->frontend;
221}
222
223static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
224
225struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
226{
227 struct ttusbdecfe_state* state = NULL;
228
229 /* allocate memory for the internal state */
230 state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
231 if (state == NULL)
232 return NULL;
233
234 /* setup the state */
235 state->config = config;
236 state->voltage = 0;
237 state->hi_band = 0;
238
239 /* create dvb_frontend */
240 memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
241 state->frontend.demodulator_priv = state;
242 return &state->frontend;
243}
244
245static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
246 .delsys = { SYS_DVBT },
247 .info = {
248 .name = "TechnoTrend/Hauppauge DEC2000-t Frontend",
249 .frequency_min = 51000000,
250 .frequency_max = 858000000,
251 .frequency_stepsize = 62500,
252 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
253 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
254 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
255 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
256 FE_CAN_HIERARCHY_AUTO,
257 },
258
259 .release = ttusbdecfe_release,
260
261 .set_frontend = ttusbdecfe_dvbt_set_frontend,
262
263 .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
264
265 .read_status = ttusbdecfe_dvbt_read_status,
266};
267
268static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
269 .delsys = { SYS_DVBS },
270 .info = {
271 .name = "TechnoTrend/Hauppauge DEC3000-s Frontend",
272 .frequency_min = 950000,
273 .frequency_max = 2150000,
274 .frequency_stepsize = 125,
275 .symbol_rate_min = 1000000, /* guessed */
276 .symbol_rate_max = 45000000, /* guessed */
277 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
278 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
279 FE_CAN_QPSK
280 },
281
282 .release = ttusbdecfe_release,
283
284 .set_frontend = ttusbdecfe_dvbs_set_frontend,
285
286 .read_status = ttusbdecfe_dvbs_read_status,
287
288 .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
289 .set_voltage = ttusbdecfe_dvbs_set_voltage,
290 .set_tone = ttusbdecfe_dvbs_set_tone,
291};
292
293MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
294MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
295MODULE_LICENSE("GPL");
296
297EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
298EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);
diff --git a/drivers/media/usb/ttusb-dec/ttusbdecfe.h b/drivers/media/usb/ttusb-dec/ttusbdecfe.h
new file mode 100644
index 000000000000..15ccc3d1a20e
--- /dev/null
+++ b/drivers/media/usb/ttusb-dec/ttusbdecfe.h
@@ -0,0 +1,38 @@
1/*
2 * TTUSB DEC Driver
3 *
4 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#ifndef TTUSBDECFE_H
23#define TTUSBDECFE_H
24
25#include <linux/dvb/frontend.h>
26
27struct ttusbdecfe_config
28{
29 int (*send_command)(struct dvb_frontend* fe, const u8 command,
30 int param_length, const u8 params[],
31 int *result_length, u8 cmd_result[]);
32};
33
34extern struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config);
35
36extern struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config);
37
38#endif // TTUSBDECFE_H