aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/media/dvb/frontends
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r--drivers/media/dvb/frontends/Kconfig669
-rw-r--r--drivers/media/dvb/frontends/Makefile94
-rw-r--r--drivers/media/dvb/frontends/af9013.c1572
-rw-r--r--drivers/media/dvb/frontends/af9013.h109
-rw-r--r--drivers/media/dvb/frontends/af9013_priv.h923
-rw-r--r--drivers/media/dvb/frontends/atbm8830.c509
-rw-r--r--drivers/media/dvb/frontends/atbm8830.h76
-rw-r--r--drivers/media/dvb/frontends/atbm8830_priv.h75
-rw-r--r--drivers/media/dvb/frontends/au8522.h98
-rw-r--r--drivers/media/dvb/frontends/au8522_decoder.c853
-rw-r--r--drivers/media/dvb/frontends/au8522_dig.c1013
-rw-r--r--drivers/media/dvb/frontends/au8522_priv.h421
-rw-r--r--drivers/media/dvb/frontends/bcm3510.c854
-rw-r--r--drivers/media/dvb/frontends/bcm3510.h49
-rw-r--r--drivers/media/dvb/frontends/bcm3510_priv.h460
-rw-r--r--drivers/media/dvb/frontends/bsbe1-d01a.h146
-rw-r--r--drivers/media/dvb/frontends/bsbe1.h105
-rw-r--r--drivers/media/dvb/frontends/bsru6.h142
-rw-r--r--drivers/media/dvb/frontends/cx22700.c440
-rw-r--r--drivers/media/dvb/frontends/cx22700.h46
-rw-r--r--drivers/media/dvb/frontends/cx22702.c638
-rw-r--r--drivers/media/dvb/frontends/cx22702.h58
-rw-r--r--drivers/media/dvb/frontends/cx24110.c667
-rw-r--r--drivers/media/dvb/frontends/cx24110.h61
-rw-r--r--drivers/media/dvb/frontends/cx24113.c620
-rw-r--r--drivers/media/dvb/frontends/cx24113.h53
-rw-r--r--drivers/media/dvb/frontends/cx24116.c1518
-rw-r--r--drivers/media/dvb/frontends/cx24116.h58
-rw-r--r--drivers/media/dvb/frontends/cx24123.c1167
-rw-r--r--drivers/media/dvb/frontends/cx24123.h61
-rw-r--r--drivers/media/dvb/frontends/cxd2820r.h118
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_c.c338
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_core.c929
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_priv.h166
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_t.c449
-rw-r--r--drivers/media/dvb/frontends/cxd2820r_t2.c423
-rw-r--r--drivers/media/dvb/frontends/dib0070.c780
-rw-r--r--drivers/media/dvb/frontends/dib0070.h76
-rw-r--r--drivers/media/dvb/frontends/dib0090.c2539
-rw-r--r--drivers/media/dvb/frontends/dib0090.h139
-rw-r--r--drivers/media/dvb/frontends/dib3000.h56
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c834
-rw-r--r--drivers/media/dvb/frontends/dib3000mb_priv.h556
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c934
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.h85
-rw-r--r--drivers/media/dvb/frontends/dib7000m.c1467
-rw-r--r--drivers/media/dvb/frontends/dib7000m.h90
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c2426
-rw-r--r--drivers/media/dvb/frontends/dib7000p.h156
-rw-r--r--drivers/media/dvb/frontends/dib8000.c2669
-rw-r--r--drivers/media/dvb/frontends/dib8000.h136
-rw-r--r--drivers/media/dvb/frontends/dib9000.c2529
-rw-r--r--drivers/media/dvb/frontends/dib9000.h131
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.c514
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.h279
-rw-r--r--drivers/media/dvb/frontends/drxd.h61
-rw-r--r--drivers/media/dvb/frontends/drxd_firm.c929
-rw-r--r--drivers/media/dvb/frontends/drxd_firm.h115
-rw-r--r--drivers/media/dvb/frontends/drxd_hard.c3002
-rw-r--r--drivers/media/dvb/frontends/drxd_map_firm.h1013
-rw-r--r--drivers/media/dvb/frontends/drxk.h47
-rw-r--r--drivers/media/dvb/frontends/drxk_hard.c6454
-rw-r--r--drivers/media/dvb/frontends/drxk_hard.h348
-rw-r--r--drivers/media/dvb/frontends/drxk_map.h449
-rw-r--r--drivers/media/dvb/frontends/ds3000.c1327
-rw-r--r--drivers/media/dvb/frontends/ds3000.h48
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c795
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h56
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.c276
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.h51
-rw-r--r--drivers/media/dvb/frontends/ec100.c335
-rw-r--r--drivers/media/dvb/frontends/ec100.h46
-rw-r--r--drivers/media/dvb/frontends/ec100_priv.h39
-rw-r--r--drivers/media/dvb/frontends/eds1547.h133
-rw-r--r--drivers/media/dvb/frontends/isl6405.c164
-rw-r--r--drivers/media/dvb/frontends/isl6405.h74
-rw-r--r--drivers/media/dvb/frontends/isl6421.c141
-rw-r--r--drivers/media/dvb/frontends/isl6421.h55
-rw-r--r--drivers/media/dvb/frontends/isl6423.c308
-rw-r--r--drivers/media/dvb/frontends/isl6423.h63
-rw-r--r--drivers/media/dvb/frontends/itd1000.c398
-rw-r--r--drivers/media/dvb/frontends/itd1000.h42
-rw-r--r--drivers/media/dvb/frontends/itd1000_priv.h88
-rw-r--r--drivers/media/dvb/frontends/ix2505v.c325
-rw-r--r--drivers/media/dvb/frontends/ix2505v.h64
-rw-r--r--drivers/media/dvb/frontends/l64781.c602
-rw-r--r--drivers/media/dvb/frontends/l64781.h46
-rw-r--r--drivers/media/dvb/frontends/lgdt3305.c1222
-rw-r--r--drivers/media/dvb/frontends/lgdt3305.h91
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c820
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.h73
-rw-r--r--drivers/media/dvb/frontends/lgdt330x_priv.h77
-rw-r--r--drivers/media/dvb/frontends/lgs8gl5.c454
-rw-r--r--drivers/media/dvb/frontends/lgs8gl5.h45
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx.c1073
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx.h95
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx_priv.h70
-rw-r--r--drivers/media/dvb/frontends/lnbh24.h55
-rw-r--r--drivers/media/dvb/frontends/lnbp21.c188
-rw-r--r--drivers/media/dvb/frontends/lnbp21.h75
-rw-r--r--drivers/media/dvb/frontends/mb86a16.c1878
-rw-r--r--drivers/media/dvb/frontends/mb86a16.h52
-rw-r--r--drivers/media/dvb/frontends/mb86a16_priv.h151
-rw-r--r--drivers/media/dvb/frontends/mb86a20s.c639
-rw-r--r--drivers/media/dvb/frontends/mb86a20s.h52
-rw-r--r--drivers/media/dvb/frontends/mt312.c840
-rw-r--r--drivers/media/dvb/frontends/mt312.h51
-rw-r--r--drivers/media/dvb/frontends/mt312_priv.h165
-rw-r--r--drivers/media/dvb/frontends/mt352.c613
-rw-r--r--drivers/media/dvb/frontends/mt352.h73
-rw-r--r--drivers/media/dvb/frontends/mt352_priv.h127
-rw-r--r--drivers/media/dvb/frontends/nxt200x.c1241
-rw-r--r--drivers/media/dvb/frontends/nxt200x.h63
-rw-r--r--drivers/media/dvb/frontends/nxt6000.c610
-rw-r--r--drivers/media/dvb/frontends/nxt6000.h48
-rw-r--r--drivers/media/dvb/frontends/nxt6000_priv.h286
-rw-r--r--drivers/media/dvb/frontends/or51132.c625
-rw-r--r--drivers/media/dvb/frontends/or51132.h55
-rw-r--r--drivers/media/dvb/frontends/or51211.c582
-rw-r--r--drivers/media/dvb/frontends/or51211.h53
-rw-r--r--drivers/media/dvb/frontends/s5h1409.c1001
-rw-r--r--drivers/media/dvb/frontends/s5h1409.h88
-rw-r--r--drivers/media/dvb/frontends/s5h1411.c923
-rw-r--r--drivers/media/dvb/frontends/s5h1411.h90
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c981
-rw-r--r--drivers/media/dvb/frontends/s5h1420.h61
-rw-r--r--drivers/media/dvb/frontends/s5h1420_priv.h102
-rw-r--r--drivers/media/dvb/frontends/s5h1432.c415
-rw-r--r--drivers/media/dvb/frontends/s5h1432.h91
-rw-r--r--drivers/media/dvb/frontends/s921.c548
-rw-r--r--drivers/media/dvb/frontends/s921.h47
-rw-r--r--drivers/media/dvb/frontends/si21xx.c967
-rw-r--r--drivers/media/dvb/frontends/si21xx.h37
-rw-r--r--drivers/media/dvb/frontends/sp8870.c619
-rw-r--r--drivers/media/dvb/frontends/sp8870.h50
-rw-r--r--drivers/media/dvb/frontends/sp887x.c617
-rw-r--r--drivers/media/dvb/frontends/sp887x.h32
-rw-r--r--drivers/media/dvb/frontends/stb0899_algo.c1522
-rw-r--r--drivers/media/dvb/frontends/stb0899_cfg.h287
-rw-r--r--drivers/media/dvb/frontends/stb0899_drv.c1686
-rw-r--r--drivers/media/dvb/frontends/stb0899_drv.h162
-rw-r--r--drivers/media/dvb/frontends/stb0899_priv.h263
-rw-r--r--drivers/media/dvb/frontends/stb0899_reg.h2027
-rw-r--r--drivers/media/dvb/frontends/stb6000.c256
-rw-r--r--drivers/media/dvb/frontends/stb6000.h51
-rw-r--r--drivers/media/dvb/frontends/stb6100.c612
-rw-r--r--drivers/media/dvb/frontends/stb6100.h115
-rw-r--r--drivers/media/dvb/frontends/stb6100_cfg.h104
-rw-r--r--drivers/media/dvb/frontends/stb6100_proc.h138
-rw-r--r--drivers/media/dvb/frontends/stv0288.c624
-rw-r--r--drivers/media/dvb/frontends/stv0288.h67
-rw-r--r--drivers/media/dvb/frontends/stv0297.c723
-rw-r--r--drivers/media/dvb/frontends/stv0297.h57
-rw-r--r--drivers/media/dvb/frontends/stv0299.c760
-rw-r--r--drivers/media/dvb/frontends/stv0299.h118
-rw-r--r--drivers/media/dvb/frontends/stv0367.c3459
-rw-r--r--drivers/media/dvb/frontends/stv0367.h66
-rw-r--r--drivers/media/dvb/frontends/stv0367_priv.h212
-rw-r--r--drivers/media/dvb/frontends/stv0367_regs.h3614
-rw-r--r--drivers/media/dvb/frontends/stv0900.h74
-rw-r--r--drivers/media/dvb/frontends/stv0900_core.c1986
-rw-r--r--drivers/media/dvb/frontends/stv0900_init.h584
-rw-r--r--drivers/media/dvb/frontends/stv0900_priv.h408
-rw-r--r--drivers/media/dvb/frontends/stv0900_reg.h3981
-rw-r--r--drivers/media/dvb/frontends/stv0900_sw.c2034
-rw-r--r--drivers/media/dvb/frontends/stv090x.c4831
-rw-r--r--drivers/media/dvb/frontends/stv090x.h134
-rw-r--r--drivers/media/dvb/frontends/stv090x_priv.h279
-rw-r--r--drivers/media/dvb/frontends/stv090x_reg.h2371
-rw-r--r--drivers/media/dvb/frontends/stv6110.c452
-rw-r--r--drivers/media/dvb/frontends/stv6110.h63
-rw-r--r--drivers/media/dvb/frontends/stv6110x.c405
-rw-r--r--drivers/media/dvb/frontends/stv6110x.h73
-rw-r--r--drivers/media/dvb/frontends/stv6110x_priv.h76
-rw-r--r--drivers/media/dvb/frontends/stv6110x_reg.h82
-rw-r--r--drivers/media/dvb/frontends/tda10021.c489
-rw-r--r--drivers/media/dvb/frontends/tda10023.c573
-rw-r--r--drivers/media/dvb/frontends/tda1002x.h87
-rw-r--r--drivers/media/dvb/frontends/tda10048.c1193
-rw-r--r--drivers/media/dvb/frontends/tda10048.h82
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c1380
-rw-r--r--drivers/media/dvb/frontends/tda1004x.h149
-rw-r--r--drivers/media/dvb/frontends/tda10086.c775
-rw-r--r--drivers/media/dvb/frontends/tda10086.h61
-rw-r--r--drivers/media/dvb/frontends/tda18271c2dd.c1251
-rw-r--r--drivers/media/dvb/frontends/tda18271c2dd.h16
-rw-r--r--drivers/media/dvb/frontends/tda18271c2dd_maps.h814
-rw-r--r--drivers/media/dvb/frontends/tda665x.c258
-rw-r--r--drivers/media/dvb/frontends/tda665x.h52
-rw-r--r--drivers/media/dvb/frontends/tda8083.c486
-rw-r--r--drivers/media/dvb/frontends/tda8083.h50
-rw-r--r--drivers/media/dvb/frontends/tda8261.c230
-rw-r--r--drivers/media/dvb/frontends/tda8261.h55
-rw-r--r--drivers/media/dvb/frontends/tda8261_cfg.h84
-rw-r--r--drivers/media/dvb/frontends/tda826x.c187
-rw-r--r--drivers/media/dvb/frontends/tda826x.h53
-rw-r--r--drivers/media/dvb/frontends/tdhd1.h73
-rw-r--r--drivers/media/dvb/frontends/tua6100.c205
-rw-r--r--drivers/media/dvb/frontends/tua6100.h47
-rw-r--r--drivers/media/dvb/frontends/ves1820.c446
-rw-r--r--drivers/media/dvb/frontends/ves1820.h56
-rw-r--r--drivers/media/dvb/frontends/ves1x93.c550
-rw-r--r--drivers/media/dvb/frontends/ves1x93.h55
-rw-r--r--drivers/media/dvb/frontends/z0194a.h85
-rw-r--r--drivers/media/dvb/frontends/zl10036.c520
-rw-r--r--drivers/media/dvb/frontends/zl10036.h53
-rw-r--r--drivers/media/dvb/frontends/zl10039.c307
-rw-r--r--drivers/media/dvb/frontends/zl10039.h40
-rw-r--r--drivers/media/dvb/frontends/zl10353.c699
-rw-r--r--drivers/media/dvb/frontends/zl10353.h62
-rw-r--r--drivers/media/dvb/frontends/zl10353_priv.h79
211 files changed, 115837 insertions, 0 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
new file mode 100644
index 00000000000..32e08e35152
--- /dev/null
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -0,0 +1,669 @@
1config DVB_FE_CUSTOMISE
2 bool "Customise the frontend modules to build"
3 depends on DVB_CORE
4 default y if EXPERT
5 help
6 This allows the user to select/deselect frontend drivers for their
7 hardware from the build.
8
9 Use this option with care as deselecting frontends which are in fact
10 necessary will result in DVB devices which cannot be tuned due to lack
11 of driver support.
12
13 If unsure say N.
14
15menu "Customise DVB Frontends"
16 visible if DVB_FE_CUSTOMISE
17
18comment "Multistandard (satellite) frontends"
19 depends on DVB_CORE
20
21config DVB_STB0899
22 tristate "STB0899 based"
23 depends on DVB_CORE && I2C
24 default m if DVB_FE_CUSTOMISE
25 help
26 A DVB-S/S2/DSS Multistandard demodulator. Say Y when you want
27 to support this demodulator based frontends
28
29config DVB_STB6100
30 tristate "STB6100 based tuners"
31 depends on DVB_CORE && I2C
32 default m if DVB_FE_CUSTOMISE
33 help
34 A Silicon tuner from ST used in conjunction with the STB0899
35 demodulator. Say Y when you want to support this tuner.
36
37config DVB_STV090x
38 tristate "STV0900/STV0903(A/B) based"
39 depends on DVB_CORE && I2C
40 default m if DVB_FE_CUSTOMISE
41 help
42 DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators.
43 Say Y when you want to support these frontends.
44
45config DVB_STV6110x
46 tristate "STV6110/(A) based tuners"
47 depends on DVB_CORE && I2C
48 default m if DVB_FE_CUSTOMISE
49 help
50 A Silicon tuner that supports DVB-S and DVB-S2 modes
51
52comment "Multistandard (cable + terrestrial) frontends"
53 depends on DVB_CORE
54
55config DVB_DRXK
56 tristate "Micronas DRXK based"
57 depends on DVB_CORE && I2C
58 default m if DVB_FE_CUSTOMISE
59 help
60 Micronas DRX-K DVB-C/T demodulator.
61
62 Say Y when you want to support this frontend.
63
64config DVB_TDA18271C2DD
65 tristate "NXP TDA18271C2 silicon tuner"
66 depends on DVB_CORE && I2C
67 default m if DVB_FE_CUSTOMISE
68 help
69 NXP TDA18271 silicon tuner.
70
71 Say Y when you want to support this tuner.
72
73comment "DVB-S (satellite) frontends"
74 depends on DVB_CORE
75
76config DVB_CX24110
77 tristate "Conexant CX24110 based"
78 depends on DVB_CORE && I2C
79 default m if DVB_FE_CUSTOMISE
80 help
81 A DVB-S tuner module. Say Y when you want to support this frontend.
82
83config DVB_CX24123
84 tristate "Conexant CX24123 based"
85 depends on DVB_CORE && I2C
86 default m if DVB_FE_CUSTOMISE
87 help
88 A DVB-S tuner module. Say Y when you want to support this frontend.
89
90config DVB_MT312
91 tristate "Zarlink VP310/MT312/ZL10313 based"
92 depends on DVB_CORE && I2C
93 default m if DVB_FE_CUSTOMISE
94 help
95 A DVB-S tuner module. Say Y when you want to support this frontend.
96
97config DVB_ZL10036
98 tristate "Zarlink ZL10036 silicon tuner"
99 depends on DVB_CORE && I2C
100 default m if DVB_FE_CUSTOMISE
101 help
102 A DVB-S tuner module. Say Y when you want to support this frontend.
103
104config DVB_ZL10039
105 tristate "Zarlink ZL10039 silicon tuner"
106 depends on DVB_CORE && I2C
107 default m if DVB_FE_CUSTOMISE
108 help
109 A DVB-S tuner module. Say Y when you want to support this frontend.
110
111config DVB_S5H1420
112 tristate "Samsung S5H1420 based"
113 depends on DVB_CORE && I2C
114 default m if DVB_FE_CUSTOMISE
115 help
116 A DVB-S tuner module. Say Y when you want to support this frontend.
117
118config DVB_STV0288
119 tristate "ST STV0288 based"
120 depends on DVB_CORE && I2C
121 default m if DVB_FE_CUSTOMISE
122 help
123 A DVB-S tuner module. Say Y when you want to support this frontend.
124
125config DVB_STB6000
126 tristate "ST STB6000 silicon tuner"
127 depends on DVB_CORE && I2C
128 default m if DVB_FE_CUSTOMISE
129 help
130 A DVB-S silicon tuner module. Say Y when you want to support this tuner.
131
132config DVB_STV0299
133 tristate "ST STV0299 based"
134 depends on DVB_CORE && I2C
135 default m if DVB_FE_CUSTOMISE
136 help
137 A DVB-S tuner module. Say Y when you want to support this frontend.
138
139config DVB_STV6110
140 tristate "ST STV6110 silicon tuner"
141 depends on DVB_CORE && I2C
142 default m if DVB_FE_CUSTOMISE
143 help
144 A DVB-S silicon tuner module. Say Y when you want to support this tuner.
145
146config DVB_STV0900
147 tristate "ST STV0900 based"
148 depends on DVB_CORE && I2C
149 default m if DVB_FE_CUSTOMISE
150 help
151 A DVB-S/S2 demodulator. Say Y when you want to support this frontend.
152
153config DVB_TDA8083
154 tristate "Philips TDA8083 based"
155 depends on DVB_CORE && I2C
156 default m if DVB_FE_CUSTOMISE
157 help
158 A DVB-S tuner module. Say Y when you want to support this frontend.
159
160config DVB_TDA10086
161 tristate "Philips TDA10086 based"
162 depends on DVB_CORE && I2C
163 default m if DVB_FE_CUSTOMISE
164 help
165 A DVB-S tuner module. Say Y when you want to support this frontend.
166
167config DVB_TDA8261
168 tristate "Philips TDA8261 based"
169 depends on DVB_CORE && I2C
170 default m if DVB_FE_CUSTOMISE
171 help
172 A DVB-S tuner module. Say Y when you want to support this frontend.
173
174config DVB_VES1X93
175 tristate "VLSI VES1893 or VES1993 based"
176 depends on DVB_CORE && I2C
177 default m if DVB_FE_CUSTOMISE
178 help
179 A DVB-S tuner module. Say Y when you want to support this frontend.
180
181config DVB_TUNER_ITD1000
182 tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
183 depends on DVB_CORE && I2C
184 default m if DVB_FE_CUSTOMISE
185 help
186 A DVB-S tuner module. Say Y when you want to support this frontend.
187
188config DVB_TUNER_CX24113
189 tristate "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
190 depends on DVB_CORE && I2C
191 default m if DVB_FE_CUSTOMISE
192 help
193 A DVB-S tuner module. Say Y when you want to support this frontend.
194
195
196config DVB_TDA826X
197 tristate "Philips TDA826X silicon tuner"
198 depends on DVB_CORE && I2C
199 default m if DVB_FE_CUSTOMISE
200 help
201 A DVB-S silicon tuner module. Say Y when you want to support this tuner.
202
203config DVB_TUA6100
204 tristate "Infineon TUA6100 PLL"
205 depends on DVB_CORE && I2C
206 default m if DVB_FE_CUSTOMISE
207 help
208 A DVB-S PLL chip.
209
210config DVB_CX24116
211 tristate "Conexant CX24116 based"
212 depends on DVB_CORE && I2C
213 default m if DVB_FE_CUSTOMISE
214 help
215 A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
216
217config DVB_SI21XX
218 tristate "Silicon Labs SI21XX based"
219 depends on DVB_CORE && I2C
220 default m if DVB_FE_CUSTOMISE
221 help
222 A DVB-S tuner module. Say Y when you want to support this frontend.
223
224config DVB_DS3000
225 tristate "Montage Tehnology DS3000 based"
226 depends on DVB_CORE && I2C
227 default m if DVB_FE_CUSTOMISE
228 help
229 A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
230
231config DVB_MB86A16
232 tristate "Fujitsu MB86A16 based"
233 depends on DVB_CORE && I2C
234 default m if DVB_FE_CUSTOMISE
235 help
236 A DVB-S/DSS Direct Conversion reveiver.
237 Say Y when you want to support this frontend.
238
239comment "DVB-T (terrestrial) frontends"
240 depends on DVB_CORE
241
242config DVB_SP8870
243 tristate "Spase sp8870 based"
244 depends on DVB_CORE && I2C
245 default m if DVB_FE_CUSTOMISE
246 help
247 A DVB-T tuner module. Say Y when you want to support this frontend.
248
249 This driver needs external firmware. Please use the command
250 "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to
251 download/extract it, and then copy it to /usr/lib/hotplug/firmware
252 or /lib/firmware (depending on configuration of firmware hotplug).
253
254config DVB_SP887X
255 tristate "Spase sp887x based"
256 depends on DVB_CORE && I2C
257 default m if DVB_FE_CUSTOMISE
258 help
259 A DVB-T tuner module. Say Y when you want to support this frontend.
260
261 This driver needs external firmware. Please use the command
262 "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
263 download/extract it, and then copy it to /usr/lib/hotplug/firmware
264 or /lib/firmware (depending on configuration of firmware hotplug).
265
266config DVB_CX22700
267 tristate "Conexant CX22700 based"
268 depends on DVB_CORE && I2C
269 default m if DVB_FE_CUSTOMISE
270 help
271 A DVB-T tuner module. Say Y when you want to support this frontend.
272
273config DVB_CX22702
274 tristate "Conexant cx22702 demodulator (OFDM)"
275 depends on DVB_CORE && I2C
276 default m if DVB_FE_CUSTOMISE
277 help
278 A DVB-T tuner module. Say Y when you want to support this frontend.
279
280config DVB_S5H1432
281 tristate "Samsung s5h1432 demodulator (OFDM)"
282 depends on DVB_CORE && I2C
283 default m if DVB_FE_CUSTOMISE
284 help
285 A DVB-T tuner module. Say Y when you want to support this frontend.
286
287config DVB_DRXD
288 tristate "Micronas DRXD driver"
289 depends on DVB_CORE && I2C
290 default m if DVB_FE_CUSTOMISE
291 help
292 A DVB-T tuner module. Say Y when you want to support this frontend.
293
294 Note: this driver was based on vendor driver reference code (released
295 under the GPL) as opposed to the existing drx397xd driver, which
296 was written via reverse engineering.
297
298config DVB_L64781
299 tristate "LSI L64781"
300 depends on DVB_CORE && I2C
301 default m if DVB_FE_CUSTOMISE
302 help
303 A DVB-T tuner module. Say Y when you want to support this frontend.
304
305config DVB_TDA1004X
306 tristate "Philips TDA10045H/TDA10046H based"
307 depends on DVB_CORE && I2C
308 default m if DVB_FE_CUSTOMISE
309 help
310 A DVB-T tuner module. Say Y when you want to support this frontend.
311
312 This driver needs external firmware. Please use the commands
313 "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
314 "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
315 download/extract them, and then copy them to /usr/lib/hotplug/firmware
316 or /lib/firmware (depending on configuration of firmware hotplug).
317
318config DVB_NXT6000
319 tristate "NxtWave Communications NXT6000 based"
320 depends on DVB_CORE && I2C
321 default m if DVB_FE_CUSTOMISE
322 help
323 A DVB-T tuner module. Say Y when you want to support this frontend.
324
325config DVB_MT352
326 tristate "Zarlink MT352 based"
327 depends on DVB_CORE && I2C
328 default m if DVB_FE_CUSTOMISE
329 help
330 A DVB-T tuner module. Say Y when you want to support this frontend.
331
332config DVB_ZL10353
333 tristate "Zarlink ZL10353 based"
334 depends on DVB_CORE && I2C
335 default m if DVB_FE_CUSTOMISE
336 help
337 A DVB-T tuner module. Say Y when you want to support this frontend.
338
339config DVB_DIB3000MB
340 tristate "DiBcom 3000M-B"
341 depends on DVB_CORE && I2C
342 default m if DVB_FE_CUSTOMISE
343 help
344 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
345 to support this frontend.
346
347config DVB_DIB3000MC
348 tristate "DiBcom 3000P/M-C"
349 depends on DVB_CORE && I2C
350 default m if DVB_FE_CUSTOMISE
351 help
352 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
353 to support this frontend.
354
355config DVB_DIB7000M
356 tristate "DiBcom 7000MA/MB/PA/PB/MC"
357 depends on DVB_CORE && I2C
358 default m if DVB_FE_CUSTOMISE
359 help
360 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
361 to support this frontend.
362
363config DVB_DIB7000P
364 tristate "DiBcom 7000PC"
365 depends on DVB_CORE && I2C
366 default m if DVB_FE_CUSTOMISE
367 help
368 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
369 to support this frontend.
370
371config DVB_DIB9000
372 tristate "DiBcom 9000"
373 depends on DVB_CORE && I2C
374 default m if DVB_FE_CUSTOMISE
375 help
376 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
377 to support this frontend.
378
379config DVB_TDA10048
380 tristate "Philips TDA10048HN based"
381 depends on DVB_CORE && I2C
382 default m if DVB_FE_CUSTOMISE
383 help
384 A DVB-T tuner module. Say Y when you want to support this frontend.
385
386config DVB_AF9013
387 tristate "Afatech AF9013 demodulator"
388 depends on DVB_CORE && I2C
389 default m if DVB_FE_CUSTOMISE
390 help
391 Say Y when you want to support this frontend.
392
393config DVB_EC100
394 tristate "E3C EC100"
395 depends on DVB_CORE && I2C
396 default m if DVB_FE_CUSTOMISE
397 help
398 Say Y when you want to support this frontend.
399
400config DVB_STV0367
401 tristate "ST STV0367 based"
402 depends on DVB_CORE && I2C
403 default m if DVB_FE_CUSTOMISE
404 help
405 A DVB-T/C tuner module. Say Y when you want to support this frontend.
406
407config DVB_CXD2820R
408 tristate "Sony CXD2820R"
409 depends on DVB_CORE && I2C
410 default m if DVB_FE_CUSTOMISE
411 help
412 Say Y when you want to support this frontend.
413
414comment "DVB-C (cable) frontends"
415 depends on DVB_CORE
416
417config DVB_VES1820
418 tristate "VLSI VES1820 based"
419 depends on DVB_CORE && I2C
420 default m if DVB_FE_CUSTOMISE
421 help
422 A DVB-C tuner module. Say Y when you want to support this frontend.
423
424config DVB_TDA10021
425 tristate "Philips TDA10021 based"
426 depends on DVB_CORE && I2C
427 default m if DVB_FE_CUSTOMISE
428 help
429 A DVB-C tuner module. Say Y when you want to support this frontend.
430
431config DVB_TDA10023
432 tristate "Philips TDA10023 based"
433 depends on DVB_CORE && I2C
434 default m if DVB_FE_CUSTOMISE
435 help
436 A DVB-C tuner module. Say Y when you want to support this frontend.
437
438config DVB_STV0297
439 tristate "ST STV0297 based"
440 depends on DVB_CORE && I2C
441 default m if DVB_FE_CUSTOMISE
442 help
443 A DVB-C tuner module. Say Y when you want to support this frontend.
444
445comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
446 depends on DVB_CORE
447
448config DVB_NXT200X
449 tristate "NxtWave Communications NXT2002/NXT2004 based"
450 depends on DVB_CORE && I2C
451 default m if DVB_FE_CUSTOMISE
452 help
453 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
454 to support this frontend.
455
456 This driver needs external firmware. Please use the commands
457 "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" and
458 "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
459 download/extract them, and then copy them to /usr/lib/hotplug/firmware
460 or /lib/firmware (depending on configuration of firmware hotplug).
461
462config DVB_OR51211
463 tristate "Oren OR51211 based"
464 depends on DVB_CORE && I2C
465 default m if DVB_FE_CUSTOMISE
466 help
467 An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
468
469 This driver needs external firmware. Please use the command
470 "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
471 download it, and then copy it to /usr/lib/hotplug/firmware
472 or /lib/firmware (depending on configuration of firmware hotplug).
473
474config DVB_OR51132
475 tristate "Oren OR51132 based"
476 depends on DVB_CORE && I2C
477 default m if DVB_FE_CUSTOMISE
478 help
479 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
480 to support this frontend.
481
482 This driver needs external firmware. Please use the commands
483 "<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_vsb" and/or
484 "<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_qam" to
485 download firmwares for 8VSB and QAM64/256, respectively. Copy them to
486 /usr/lib/hotplug/firmware or /lib/firmware (depending on
487 configuration of firmware hotplug).
488
489config DVB_BCM3510
490 tristate "Broadcom BCM3510"
491 depends on DVB_CORE && I2C
492 default m if DVB_FE_CUSTOMISE
493 help
494 An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
495 support this frontend.
496
497config DVB_LGDT330X
498 tristate "LG Electronics LGDT3302/LGDT3303 based"
499 depends on DVB_CORE && I2C
500 default m if DVB_FE_CUSTOMISE
501 help
502 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
503 to support this frontend.
504
505config DVB_LGDT3305
506 tristate "LG Electronics LGDT3304 and LGDT3305 based"
507 depends on DVB_CORE && I2C
508 default m if DVB_FE_CUSTOMISE
509 help
510 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
511 to support this frontend.
512
513config DVB_S5H1409
514 tristate "Samsung S5H1409 based"
515 depends on DVB_CORE && I2C
516 default m if DVB_FE_CUSTOMISE
517 help
518 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
519 to support this frontend.
520
521config DVB_AU8522
522 tristate "Auvitek AU8522 based"
523 depends on DVB_CORE && I2C && VIDEO_V4L2
524 default m if DVB_FE_CUSTOMISE
525 help
526 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
527 to support this frontend.
528
529config DVB_S5H1411
530 tristate "Samsung S5H1411 based"
531 depends on DVB_CORE && I2C
532 default m if DVB_FE_CUSTOMISE
533 help
534 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
535 to support this frontend.
536
537comment "ISDB-T (terrestrial) frontends"
538 depends on DVB_CORE
539
540config DVB_S921
541 tristate "Sharp S921 frontend"
542 depends on DVB_CORE && I2C
543 default m if DVB_FE_CUSTOMISE
544 help
545 AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module.
546 Say Y when you want to support this frontend.
547
548config DVB_DIB8000
549 tristate "DiBcom 8000MB/MC"
550 depends on DVB_CORE && I2C
551 default m if DVB_FE_CUSTOMISE
552 help
553 A driver for DiBcom's DiB8000 ISDB-T/ISDB-Tsb demodulator.
554 Say Y when you want to support this frontend.
555
556config DVB_MB86A20S
557 tristate "Fujitsu mb86a20s"
558 depends on DVB_CORE && I2C
559 default m if DVB_FE_CUSTOMISE
560 help
561 A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator.
562 Say Y when you want to support this frontend.
563
564comment "Digital terrestrial only tuners/PLL"
565 depends on DVB_CORE
566
567config DVB_PLL
568 tristate "Generic I2C PLL based tuners"
569 depends on DVB_CORE && I2C
570 default m if DVB_FE_CUSTOMISE
571 help
572 This module drives a number of tuners based on PLL chips with a
573 common I2C interface. Say Y when you want to support these tuners.
574
575config DVB_TUNER_DIB0070
576 tristate "DiBcom DiB0070 silicon base-band tuner"
577 depends on I2C
578 default m if DVB_FE_CUSTOMISE
579 help
580 A driver for the silicon baseband tuner DiB0070 from DiBcom.
581 This device is only used inside a SiP called together with a
582 demodulator for now.
583
584config DVB_TUNER_DIB0090
585 tristate "DiBcom DiB0090 silicon base-band tuner"
586 depends on I2C
587 default m if DVB_FE_CUSTOMISE
588 help
589 A driver for the silicon baseband tuner DiB0090 from DiBcom.
590 This device is only used inside a SiP called together with a
591 demodulator for now.
592
593comment "SEC control devices for DVB-S"
594 depends on DVB_CORE
595
596config DVB_LNBP21
597 tristate "LNBP21/LNBH24 SEC controllers"
598 depends on DVB_CORE && I2C
599 default m if DVB_FE_CUSTOMISE
600 help
601 An SEC control chips.
602
603config DVB_ISL6405
604 tristate "ISL6405 SEC controller"
605 depends on DVB_CORE && I2C
606 default m if DVB_FE_CUSTOMISE
607 help
608 An SEC control chip.
609
610config DVB_ISL6421
611 tristate "ISL6421 SEC controller"
612 depends on DVB_CORE && I2C
613 default m if DVB_FE_CUSTOMISE
614 help
615 An SEC control chip.
616
617config DVB_ISL6423
618 tristate "ISL6423 SEC controller"
619 depends on DVB_CORE && I2C
620 default m if DVB_FE_CUSTOMISE
621 help
622 A SEC controller chip from Intersil
623
624config DVB_LGS8GL5
625 tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)"
626 depends on DVB_CORE && I2C
627 default m if DVB_FE_CUSTOMISE
628 help
629 A DMB-TH tuner module. Say Y when you want to support this frontend.
630
631config DVB_LGS8GXX
632 tristate "Legend Silicon LGS8913/LGS8GL5/LGS8GXX DMB-TH demodulator"
633 depends on DVB_CORE && I2C
634 select FW_LOADER
635 default m if DVB_FE_CUSTOMISE
636 help
637 A DMB-TH tuner module. Say Y when you want to support this frontend.
638
639config DVB_ATBM8830
640 tristate "AltoBeam ATBM8830/8831 DMB-TH demodulator"
641 depends on DVB_CORE && I2C
642 default m if DVB_FE_CUSTOMISE
643 help
644 A DMB-TH tuner module. Say Y when you want to support this frontend.
645
646config DVB_TDA665x
647 tristate "TDA665x tuner"
648 depends on DVB_CORE && I2C
649 default m if DVB_FE_CUSTOMISE
650 help
651 Support for tuner modules based on Philips TDA6650/TDA6651 chips.
652 Say Y when you want to support this chip.
653
654 Currently supported tuners:
655 * Panasonic ENV57H12D5 (ET-50DT)
656
657config DVB_IX2505V
658 tristate "Sharp IX2505V silicon tuner"
659 depends on DVB_CORE && I2C
660 default m if DVB_FE_CUSTOMISE
661 help
662 A DVB-S tuner module. Say Y when you want to support this frontend.
663
664comment "Tools to develop new frontends"
665
666config DVB_DUMMY_FE
667 tristate "Dummy frontend driver"
668 default n
669endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
new file mode 100644
index 00000000000..6a6ba053ead
--- /dev/null
+++ b/drivers/media/dvb/frontends/Makefile
@@ -0,0 +1,94 @@
1#
2# Makefile for the kernel DVB frontend device drivers.
3#
4
5EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
6EXTRA_CFLAGS += -Idrivers/media/common/tuners/
7
8stb0899-objs = stb0899_drv.o stb0899_algo.o
9stv0900-objs = stv0900_core.o stv0900_sw.o
10au8522-objs = au8522_dig.o au8522_decoder.o
11drxd-objs = drxd_firm.o drxd_hard.o
12cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
13drxk-objs := drxk_hard.o
14
15obj-$(CONFIG_DVB_PLL) += dvb-pll.o
16obj-$(CONFIG_DVB_STV0299) += stv0299.o
17obj-$(CONFIG_DVB_STB0899) += stb0899.o
18obj-$(CONFIG_DVB_STB6100) += stb6100.o
19obj-$(CONFIG_DVB_SP8870) += sp8870.o
20obj-$(CONFIG_DVB_CX22700) += cx22700.o
21obj-$(CONFIG_DVB_S5H1432) += s5h1432.o
22obj-$(CONFIG_DVB_CX24110) += cx24110.o
23obj-$(CONFIG_DVB_TDA8083) += tda8083.o
24obj-$(CONFIG_DVB_L64781) += l64781.o
25obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o
26obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
27obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o
28obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o
29obj-$(CONFIG_DVB_DIB8000) += dib8000.o dibx000_common.o
30obj-$(CONFIG_DVB_DIB9000) += dib9000.o dibx000_common.o
31obj-$(CONFIG_DVB_MT312) += mt312.o
32obj-$(CONFIG_DVB_VES1820) += ves1820.o
33obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
34obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
35obj-$(CONFIG_DVB_SP887X) += sp887x.o
36obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
37obj-$(CONFIG_DVB_MT352) += mt352.o
38obj-$(CONFIG_DVB_ZL10036) += zl10036.o
39obj-$(CONFIG_DVB_ZL10039) += zl10039.o
40obj-$(CONFIG_DVB_ZL10353) += zl10353.o
41obj-$(CONFIG_DVB_CX22702) += cx22702.o
42obj-$(CONFIG_DVB_DRXD) += drxd.o
43obj-$(CONFIG_DVB_TDA10021) += tda10021.o
44obj-$(CONFIG_DVB_TDA10023) += tda10023.o
45obj-$(CONFIG_DVB_STV0297) += stv0297.o
46obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
47obj-$(CONFIG_DVB_OR51211) += or51211.o
48obj-$(CONFIG_DVB_OR51132) += or51132.o
49obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
50obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
51obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
52obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
53obj-$(CONFIG_DVB_CX24123) += cx24123.o
54obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
55obj-$(CONFIG_DVB_ISL6405) += isl6405.o
56obj-$(CONFIG_DVB_ISL6421) += isl6421.o
57obj-$(CONFIG_DVB_TDA10086) += tda10086.o
58obj-$(CONFIG_DVB_TDA826X) += tda826x.o
59obj-$(CONFIG_DVB_TDA8261) += tda8261.o
60obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
61obj-$(CONFIG_DVB_TUNER_DIB0090) += dib0090.o
62obj-$(CONFIG_DVB_TUA6100) += tua6100.o
63obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
64obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
65obj-$(CONFIG_DVB_AU8522) += au8522.o
66obj-$(CONFIG_DVB_TDA10048) += tda10048.o
67obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o
68obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
69obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o
70obj-$(CONFIG_DVB_TDA665x) += tda665x.o
71obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o
72obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o
73obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
74obj-$(CONFIG_DVB_AF9013) += af9013.o
75obj-$(CONFIG_DVB_CX24116) += cx24116.o
76obj-$(CONFIG_DVB_SI21XX) += si21xx.o
77obj-$(CONFIG_DVB_STV0288) += stv0288.o
78obj-$(CONFIG_DVB_STB6000) += stb6000.o
79obj-$(CONFIG_DVB_S921) += s921.o
80obj-$(CONFIG_DVB_STV6110) += stv6110.o
81obj-$(CONFIG_DVB_STV0900) += stv0900.o
82obj-$(CONFIG_DVB_STV090x) += stv090x.o
83obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
84obj-$(CONFIG_DVB_ISL6423) += isl6423.o
85obj-$(CONFIG_DVB_EC100) += ec100.o
86obj-$(CONFIG_DVB_DS3000) += ds3000.o
87obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
88obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
89obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
90obj-$(CONFIG_DVB_STV0367) += stv0367.o
91obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
92obj-$(CONFIG_DVB_DRXK) += drxk.o
93obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
94
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c
new file mode 100644
index 00000000000..345311c3338
--- /dev/null
+++ b/drivers/media/dvb/frontends/af9013.c
@@ -0,0 +1,1572 @@
1/*
2 * Afatech AF9013 demodulator driver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
5 *
6 * Thanks to Afatech who kindly provided information.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/string.h>
30#include <linux/slab.h>
31#include <linux/firmware.h>
32
33#include "dvb_frontend.h"
34#include "af9013_priv.h"
35#include "af9013.h"
36
37int af9013_debug;
38
39struct af9013_state {
40 struct i2c_adapter *i2c;
41 struct dvb_frontend frontend;
42
43 struct af9013_config config;
44
45 /* tuner/demod RF and IF AGC limits used for signal strength calc */
46 u8 signal_strength_en, rf_50, rf_80, if_50, if_80;
47 u16 signal_strength;
48 u32 ber;
49 u32 ucblocks;
50 u16 snr;
51 u32 frequency;
52 unsigned long next_statistics_check;
53};
54
55static u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
56
57static int af9013_write_regs(struct af9013_state *state, u8 mbox, u16 reg,
58 u8 *val, u8 len)
59{
60 u8 buf[3+len];
61 struct i2c_msg msg = {
62 .addr = state->config.demod_address,
63 .flags = 0,
64 .len = sizeof(buf),
65 .buf = buf };
66
67 buf[0] = reg >> 8;
68 buf[1] = reg & 0xff;
69 buf[2] = mbox;
70 memcpy(&buf[3], val, len);
71
72 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
73 warn("I2C write failed reg:%04x len:%d", reg, len);
74 return -EREMOTEIO;
75 }
76 return 0;
77}
78
79static int af9013_write_ofdm_regs(struct af9013_state *state, u16 reg, u8 *val,
80 u8 len)
81{
82 u8 mbox = (1 << 0)|(1 << 1)|((len - 1) << 2)|(0 << 6)|(0 << 7);
83 return af9013_write_regs(state, mbox, reg, val, len);
84}
85
86static int af9013_write_ofsm_regs(struct af9013_state *state, u16 reg, u8 *val,
87 u8 len)
88{
89 u8 mbox = (1 << 0)|(1 << 1)|((len - 1) << 2)|(1 << 6)|(1 << 7);
90 return af9013_write_regs(state, mbox, reg, val, len);
91}
92
93/* write single register */
94static int af9013_write_reg(struct af9013_state *state, u16 reg, u8 val)
95{
96 return af9013_write_ofdm_regs(state, reg, &val, 1);
97}
98
99/* read single register */
100static int af9013_read_reg(struct af9013_state *state, u16 reg, u8 *val)
101{
102 u8 obuf[3] = { reg >> 8, reg & 0xff, 0 };
103 u8 ibuf[1];
104 struct i2c_msg msg[2] = {
105 {
106 .addr = state->config.demod_address,
107 .flags = 0,
108 .len = sizeof(obuf),
109 .buf = obuf
110 }, {
111 .addr = state->config.demod_address,
112 .flags = I2C_M_RD,
113 .len = sizeof(ibuf),
114 .buf = ibuf
115 }
116 };
117
118 if (i2c_transfer(state->i2c, msg, 2) != 2) {
119 warn("I2C read failed reg:%04x", reg);
120 return -EREMOTEIO;
121 }
122 *val = ibuf[0];
123 return 0;
124}
125
126static int af9013_write_reg_bits(struct af9013_state *state, u16 reg, u8 pos,
127 u8 len, u8 val)
128{
129 int ret;
130 u8 tmp, mask;
131
132 ret = af9013_read_reg(state, reg, &tmp);
133 if (ret)
134 return ret;
135
136 mask = regmask[len - 1] << pos;
137 tmp = (tmp & ~mask) | ((val << pos) & mask);
138
139 return af9013_write_reg(state, reg, tmp);
140}
141
142static int af9013_read_reg_bits(struct af9013_state *state, u16 reg, u8 pos,
143 u8 len, u8 *val)
144{
145 int ret;
146 u8 tmp;
147
148 ret = af9013_read_reg(state, reg, &tmp);
149 if (ret)
150 return ret;
151 *val = (tmp >> pos) & regmask[len - 1];
152 return 0;
153}
154
155static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval)
156{
157 int ret;
158 u8 pos;
159 u16 addr;
160 deb_info("%s: gpio:%d gpioval:%02x\n", __func__, gpio, gpioval);
161
162/* GPIO0 & GPIO1 0xd735
163 GPIO2 & GPIO3 0xd736 */
164
165 switch (gpio) {
166 case 0:
167 case 1:
168 addr = 0xd735;
169 break;
170 case 2:
171 case 3:
172 addr = 0xd736;
173 break;
174
175 default:
176 err("invalid gpio:%d\n", gpio);
177 ret = -EINVAL;
178 goto error;
179 };
180
181 switch (gpio) {
182 case 0:
183 case 2:
184 pos = 0;
185 break;
186 case 1:
187 case 3:
188 default:
189 pos = 4;
190 break;
191 };
192
193 ret = af9013_write_reg_bits(state, addr, pos, 4, gpioval);
194
195error:
196 return ret;
197}
198
199static u32 af913_div(u32 a, u32 b, u32 x)
200{
201 u32 r = 0, c = 0, i;
202 deb_info("%s: a:%d b:%d x:%d\n", __func__, a, b, x);
203
204 if (a > b) {
205 c = a / b;
206 a = a - c * b;
207 }
208
209 for (i = 0; i < x; i++) {
210 if (a >= b) {
211 r += 1;
212 a -= b;
213 }
214 a <<= 1;
215 r <<= 1;
216 }
217 r = (c << (u32)x) + r;
218
219 deb_info("%s: a:%d b:%d x:%d r:%d r:%x\n", __func__, a, b, x, r, r);
220 return r;
221}
222
223static int af9013_set_coeff(struct af9013_state *state, fe_bandwidth_t bw)
224{
225 int ret, i, j, found;
226 deb_info("%s: adc_clock:%d bw:%d\n", __func__,
227 state->config.adc_clock, bw);
228
229 /* lookup coeff from table */
230 for (i = 0, found = 0; i < ARRAY_SIZE(coeff_table); i++) {
231 if (coeff_table[i].adc_clock == state->config.adc_clock &&
232 coeff_table[i].bw == bw) {
233 found = 1;
234 break;
235 }
236 }
237
238 if (!found) {
239 err("invalid bw or clock");
240 ret = -EINVAL;
241 goto error;
242 }
243
244 deb_info("%s: coeff: ", __func__);
245 debug_dump(coeff_table[i].val, sizeof(coeff_table[i].val), deb_info);
246
247 /* program */
248 for (j = 0; j < sizeof(coeff_table[i].val); j++) {
249 ret = af9013_write_reg(state, 0xae00 + j,
250 coeff_table[i].val[j]);
251 if (ret)
252 break;
253 }
254
255error:
256 return ret;
257}
258
259static int af9013_set_adc_ctrl(struct af9013_state *state)
260{
261 int ret;
262 u8 buf[3], tmp, i;
263 u32 adc_cw;
264
265 deb_info("%s: adc_clock:%d\n", __func__, state->config.adc_clock);
266
267 /* adc frequency type */
268 switch (state->config.adc_clock) {
269 case 28800: /* 28.800 MHz */
270 tmp = 0;
271 break;
272 case 20480: /* 20.480 MHz */
273 tmp = 1;
274 break;
275 case 28000: /* 28.000 MHz */
276 tmp = 2;
277 break;
278 case 25000: /* 25.000 MHz */
279 tmp = 3;
280 break;
281 default:
282 err("invalid xtal");
283 return -EINVAL;
284 }
285
286 adc_cw = af913_div(state->config.adc_clock*1000, 1000000ul, 19ul);
287
288 buf[0] = (u8) ((adc_cw & 0x000000ff));
289 buf[1] = (u8) ((adc_cw & 0x0000ff00) >> 8);
290 buf[2] = (u8) ((adc_cw & 0x00ff0000) >> 16);
291
292 deb_info("%s: adc_cw:", __func__);
293 debug_dump(buf, sizeof(buf), deb_info);
294
295 /* program */
296 for (i = 0; i < sizeof(buf); i++) {
297 ret = af9013_write_reg(state, 0xd180 + i, buf[i]);
298 if (ret)
299 goto error;
300 }
301 ret = af9013_write_reg_bits(state, 0x9bd2, 0, 4, tmp);
302error:
303 return ret;
304}
305
306static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw)
307{
308 int ret;
309 u16 addr;
310 u8 buf[3], i, j;
311 u32 adc_freq, freq_cw;
312 s8 bfs_spec_inv;
313 int if_sample_freq;
314
315 for (j = 0; j < 3; j++) {
316 if (j == 0) {
317 addr = 0xd140; /* fcw normal */
318 bfs_spec_inv = state->config.rf_spec_inv ? -1 : 1;
319 } else if (j == 1) {
320 addr = 0x9be7; /* fcw dummy ram */
321 bfs_spec_inv = state->config.rf_spec_inv ? -1 : 1;
322 } else {
323 addr = 0x9bea; /* fcw inverted */
324 bfs_spec_inv = state->config.rf_spec_inv ? 1 : -1;
325 }
326
327 adc_freq = state->config.adc_clock * 1000;
328 if_sample_freq = state->config.tuner_if * 1000;
329
330 /* TDA18271 uses different sampling freq for every bw */
331 if (state->config.tuner == AF9013_TUNER_TDA18271) {
332 switch (bw) {
333 case BANDWIDTH_6_MHZ:
334 if_sample_freq = 3300000; /* 3.3 MHz */
335 break;
336 case BANDWIDTH_7_MHZ:
337 if_sample_freq = 3500000; /* 3.5 MHz */
338 break;
339 case BANDWIDTH_8_MHZ:
340 default:
341 if_sample_freq = 4000000; /* 4.0 MHz */
342 break;
343 }
344 } else if (state->config.tuner == AF9013_TUNER_TDA18218) {
345 switch (bw) {
346 case BANDWIDTH_6_MHZ:
347 if_sample_freq = 3000000; /* 3 MHz */
348 break;
349 case BANDWIDTH_7_MHZ:
350 if_sample_freq = 3500000; /* 3.5 MHz */
351 break;
352 case BANDWIDTH_8_MHZ:
353 default:
354 if_sample_freq = 4000000; /* 4 MHz */
355 break;
356 }
357 }
358
359 while (if_sample_freq > (adc_freq / 2))
360 if_sample_freq = if_sample_freq - adc_freq;
361
362 if (if_sample_freq >= 0)
363 bfs_spec_inv = bfs_spec_inv * (-1);
364 else
365 if_sample_freq = if_sample_freq * (-1);
366
367 freq_cw = af913_div(if_sample_freq, adc_freq, 23ul);
368
369 if (bfs_spec_inv == -1)
370 freq_cw = 0x00800000 - freq_cw;
371
372 buf[0] = (u8) ((freq_cw & 0x000000ff));
373 buf[1] = (u8) ((freq_cw & 0x0000ff00) >> 8);
374 buf[2] = (u8) ((freq_cw & 0x007f0000) >> 16);
375
376
377 deb_info("%s: freq_cw:", __func__);
378 debug_dump(buf, sizeof(buf), deb_info);
379
380 /* program */
381 for (i = 0; i < sizeof(buf); i++) {
382 ret = af9013_write_reg(state, addr++, buf[i]);
383 if (ret)
384 goto error;
385 }
386 }
387error:
388 return ret;
389}
390
391static int af9013_set_ofdm_params(struct af9013_state *state,
392 struct dvb_ofdm_parameters *params, u8 *auto_mode)
393{
394 int ret;
395 u8 i, buf[3] = {0, 0, 0};
396 *auto_mode = 0; /* set if parameters are requested to auto set */
397
398 /* Try auto-detect transmission parameters in case of AUTO requested or
399 garbage parameters given by application for compatibility.
400 MPlayer seems to provide garbage parameters currently. */
401
402 switch (params->transmission_mode) {
403 case TRANSMISSION_MODE_AUTO:
404 *auto_mode = 1;
405 case TRANSMISSION_MODE_2K:
406 break;
407 case TRANSMISSION_MODE_8K:
408 buf[0] |= (1 << 0);
409 break;
410 default:
411 deb_info("%s: invalid transmission_mode\n", __func__);
412 *auto_mode = 1;
413 }
414
415 switch (params->guard_interval) {
416 case GUARD_INTERVAL_AUTO:
417 *auto_mode = 1;
418 case GUARD_INTERVAL_1_32:
419 break;
420 case GUARD_INTERVAL_1_16:
421 buf[0] |= (1 << 2);
422 break;
423 case GUARD_INTERVAL_1_8:
424 buf[0] |= (2 << 2);
425 break;
426 case GUARD_INTERVAL_1_4:
427 buf[0] |= (3 << 2);
428 break;
429 default:
430 deb_info("%s: invalid guard_interval\n", __func__);
431 *auto_mode = 1;
432 }
433
434 switch (params->hierarchy_information) {
435 case HIERARCHY_AUTO:
436 *auto_mode = 1;
437 case HIERARCHY_NONE:
438 break;
439 case HIERARCHY_1:
440 buf[0] |= (1 << 4);
441 break;
442 case HIERARCHY_2:
443 buf[0] |= (2 << 4);
444 break;
445 case HIERARCHY_4:
446 buf[0] |= (3 << 4);
447 break;
448 default:
449 deb_info("%s: invalid hierarchy_information\n", __func__);
450 *auto_mode = 1;
451 };
452
453 switch (params->constellation) {
454 case QAM_AUTO:
455 *auto_mode = 1;
456 case QPSK:
457 break;
458 case QAM_16:
459 buf[1] |= (1 << 6);
460 break;
461 case QAM_64:
462 buf[1] |= (2 << 6);
463 break;
464 default:
465 deb_info("%s: invalid constellation\n", __func__);
466 *auto_mode = 1;
467 }
468
469 /* Use HP. How and which case we can switch to LP? */
470 buf[1] |= (1 << 4);
471
472 switch (params->code_rate_HP) {
473 case FEC_AUTO:
474 *auto_mode = 1;
475 case FEC_1_2:
476 break;
477 case FEC_2_3:
478 buf[2] |= (1 << 0);
479 break;
480 case FEC_3_4:
481 buf[2] |= (2 << 0);
482 break;
483 case FEC_5_6:
484 buf[2] |= (3 << 0);
485 break;
486 case FEC_7_8:
487 buf[2] |= (4 << 0);
488 break;
489 default:
490 deb_info("%s: invalid code_rate_HP\n", __func__);
491 *auto_mode = 1;
492 }
493
494 switch (params->code_rate_LP) {
495 case FEC_AUTO:
496 /* if HIERARCHY_NONE and FEC_NONE then LP FEC is set to FEC_AUTO
497 by dvb_frontend.c for compatibility */
498 if (params->hierarchy_information != HIERARCHY_NONE)
499 *auto_mode = 1;
500 case FEC_1_2:
501 break;
502 case FEC_2_3:
503 buf[2] |= (1 << 3);
504 break;
505 case FEC_3_4:
506 buf[2] |= (2 << 3);
507 break;
508 case FEC_5_6:
509 buf[2] |= (3 << 3);
510 break;
511 case FEC_7_8:
512 buf[2] |= (4 << 3);
513 break;
514 case FEC_NONE:
515 if (params->hierarchy_information == HIERARCHY_AUTO)
516 break;
517 default:
518 deb_info("%s: invalid code_rate_LP\n", __func__);
519 *auto_mode = 1;
520 }
521
522 switch (params->bandwidth) {
523 case BANDWIDTH_6_MHZ:
524 break;
525 case BANDWIDTH_7_MHZ:
526 buf[1] |= (1 << 2);
527 break;
528 case BANDWIDTH_8_MHZ:
529 buf[1] |= (2 << 2);
530 break;
531 default:
532 deb_info("%s: invalid bandwidth\n", __func__);
533 buf[1] |= (2 << 2); /* cannot auto-detect BW, try 8 MHz */
534 }
535
536 /* program */
537 for (i = 0; i < sizeof(buf); i++) {
538 ret = af9013_write_reg(state, 0xd3c0 + i, buf[i]);
539 if (ret)
540 break;
541 }
542
543 return ret;
544}
545
546static int af9013_reset(struct af9013_state *state, u8 sleep)
547{
548 int ret;
549 u8 tmp, i;
550 deb_info("%s\n", __func__);
551
552 /* enable OFDM reset */
553 ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 1);
554 if (ret)
555 goto error;
556
557 /* start reset mechanism */
558 ret = af9013_write_reg(state, 0xaeff, 1);
559 if (ret)
560 goto error;
561
562 /* reset is done when bit 1 is set */
563 for (i = 0; i < 150; i++) {
564 ret = af9013_read_reg_bits(state, 0xd417, 1, 1, &tmp);
565 if (ret)
566 goto error;
567 if (tmp)
568 break; /* reset done */
569 msleep(10);
570 }
571 if (!tmp)
572 return -ETIMEDOUT;
573
574 /* don't clear reset when going to sleep */
575 if (!sleep) {
576 /* clear OFDM reset */
577 ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0);
578 if (ret)
579 goto error;
580
581 /* disable OFDM reset */
582 ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0);
583 }
584error:
585 return ret;
586}
587
588static int af9013_power_ctrl(struct af9013_state *state, u8 onoff)
589{
590 int ret;
591 deb_info("%s: onoff:%d\n", __func__, onoff);
592
593 if (onoff) {
594 /* power on */
595 ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 0);
596 if (ret)
597 goto error;
598 ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0);
599 if (ret)
600 goto error;
601 ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0);
602 } else {
603 /* power off */
604 ret = af9013_reset(state, 1);
605 if (ret)
606 goto error;
607 ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 1);
608 }
609error:
610 return ret;
611}
612
613static int af9013_lock_led(struct af9013_state *state, u8 onoff)
614{
615 deb_info("%s: onoff:%d\n", __func__, onoff);
616
617 return af9013_write_reg_bits(state, 0xd730, 0, 1, onoff);
618}
619
620static int af9013_set_frontend(struct dvb_frontend *fe,
621 struct dvb_frontend_parameters *params)
622{
623 struct af9013_state *state = fe->demodulator_priv;
624 int ret;
625 u8 auto_mode; /* auto set TPS */
626
627 deb_info("%s: freq:%d bw:%d\n", __func__, params->frequency,
628 params->u.ofdm.bandwidth);
629
630 state->frequency = params->frequency;
631
632 /* program tuner */
633 if (fe->ops.tuner_ops.set_params)
634 fe->ops.tuner_ops.set_params(fe, params);
635
636 /* program CFOE coefficients */
637 ret = af9013_set_coeff(state, params->u.ofdm.bandwidth);
638 if (ret)
639 goto error;
640
641 /* program frequency control */
642 ret = af9013_set_freq_ctrl(state, params->u.ofdm.bandwidth);
643 if (ret)
644 goto error;
645
646 /* clear TPS lock flag (inverted flag) */
647 ret = af9013_write_reg_bits(state, 0xd330, 3, 1, 1);
648 if (ret)
649 goto error;
650
651 /* clear MPEG2 lock flag */
652 ret = af9013_write_reg_bits(state, 0xd507, 6, 1, 0);
653 if (ret)
654 goto error;
655
656 /* empty channel function */
657 ret = af9013_write_reg_bits(state, 0x9bfe, 0, 1, 0);
658 if (ret)
659 goto error;
660
661 /* empty DVB-T channel function */
662 ret = af9013_write_reg_bits(state, 0x9bc2, 0, 1, 0);
663 if (ret)
664 goto error;
665
666 /* program TPS and bandwidth, check if auto mode needed */
667 ret = af9013_set_ofdm_params(state, &params->u.ofdm, &auto_mode);
668 if (ret)
669 goto error;
670
671 if (auto_mode) {
672 /* clear easy mode flag */
673 ret = af9013_write_reg(state, 0xaefd, 0);
674 deb_info("%s: auto TPS\n", __func__);
675 } else {
676 /* set easy mode flag */
677 ret = af9013_write_reg(state, 0xaefd, 1);
678 if (ret)
679 goto error;
680 ret = af9013_write_reg(state, 0xaefe, 0);
681 deb_info("%s: manual TPS\n", __func__);
682 }
683 if (ret)
684 goto error;
685
686 /* everything is set, lets try to receive channel - OFSM GO! */
687 ret = af9013_write_reg(state, 0xffff, 0);
688 if (ret)
689 goto error;
690
691error:
692 return ret;
693}
694
695static int af9013_get_frontend(struct dvb_frontend *fe,
696 struct dvb_frontend_parameters *p)
697{
698 struct af9013_state *state = fe->demodulator_priv;
699 int ret;
700 u8 i, buf[3];
701 deb_info("%s\n", __func__);
702
703 /* read TPS registers */
704 for (i = 0; i < 3; i++) {
705 ret = af9013_read_reg(state, 0xd3c0 + i, &buf[i]);
706 if (ret)
707 goto error;
708 }
709
710 switch ((buf[1] >> 6) & 3) {
711 case 0:
712 p->u.ofdm.constellation = QPSK;
713 break;
714 case 1:
715 p->u.ofdm.constellation = QAM_16;
716 break;
717 case 2:
718 p->u.ofdm.constellation = QAM_64;
719 break;
720 }
721
722 switch ((buf[0] >> 0) & 3) {
723 case 0:
724 p->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
725 break;
726 case 1:
727 p->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
728 }
729
730 switch ((buf[0] >> 2) & 3) {
731 case 0:
732 p->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
733 break;
734 case 1:
735 p->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
736 break;
737 case 2:
738 p->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
739 break;
740 case 3:
741 p->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
742 break;
743 }
744
745 switch ((buf[0] >> 4) & 7) {
746 case 0:
747 p->u.ofdm.hierarchy_information = HIERARCHY_NONE;
748 break;
749 case 1:
750 p->u.ofdm.hierarchy_information = HIERARCHY_1;
751 break;
752 case 2:
753 p->u.ofdm.hierarchy_information = HIERARCHY_2;
754 break;
755 case 3:
756 p->u.ofdm.hierarchy_information = HIERARCHY_4;
757 break;
758 }
759
760 switch ((buf[2] >> 0) & 7) {
761 case 0:
762 p->u.ofdm.code_rate_HP = FEC_1_2;
763 break;
764 case 1:
765 p->u.ofdm.code_rate_HP = FEC_2_3;
766 break;
767 case 2:
768 p->u.ofdm.code_rate_HP = FEC_3_4;
769 break;
770 case 3:
771 p->u.ofdm.code_rate_HP = FEC_5_6;
772 break;
773 case 4:
774 p->u.ofdm.code_rate_HP = FEC_7_8;
775 break;
776 }
777
778 switch ((buf[2] >> 3) & 7) {
779 case 0:
780 p->u.ofdm.code_rate_LP = FEC_1_2;
781 break;
782 case 1:
783 p->u.ofdm.code_rate_LP = FEC_2_3;
784 break;
785 case 2:
786 p->u.ofdm.code_rate_LP = FEC_3_4;
787 break;
788 case 3:
789 p->u.ofdm.code_rate_LP = FEC_5_6;
790 break;
791 case 4:
792 p->u.ofdm.code_rate_LP = FEC_7_8;
793 break;
794 }
795
796 switch ((buf[1] >> 2) & 3) {
797 case 0:
798 p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
799 break;
800 case 1:
801 p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
802 break;
803 case 2:
804 p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
805 break;
806 }
807
808 p->inversion = INVERSION_AUTO;
809 p->frequency = state->frequency;
810
811error:
812 return ret;
813}
814
815static int af9013_update_ber_unc(struct dvb_frontend *fe)
816{
817 struct af9013_state *state = fe->demodulator_priv;
818 int ret;
819 u8 buf[3], i;
820 u32 error_bit_count = 0;
821 u32 total_bit_count = 0;
822 u32 abort_packet_count = 0;
823
824 state->ber = 0;
825
826 /* check if error bit count is ready */
827 ret = af9013_read_reg_bits(state, 0xd391, 4, 1, &buf[0]);
828 if (ret)
829 goto error;
830 if (!buf[0])
831 goto exit;
832
833 /* get RSD packet abort count */
834 for (i = 0; i < 2; i++) {
835 ret = af9013_read_reg(state, 0xd38a + i, &buf[i]);
836 if (ret)
837 goto error;
838 }
839 abort_packet_count = (buf[1] << 8) + buf[0];
840
841 /* get error bit count */
842 for (i = 0; i < 3; i++) {
843 ret = af9013_read_reg(state, 0xd387 + i, &buf[i]);
844 if (ret)
845 goto error;
846 }
847 error_bit_count = (buf[2] << 16) + (buf[1] << 8) + buf[0];
848 error_bit_count = error_bit_count - abort_packet_count * 8 * 8;
849
850 /* get used RSD counting period (10000 RSD packets used) */
851 for (i = 0; i < 2; i++) {
852 ret = af9013_read_reg(state, 0xd385 + i, &buf[i]);
853 if (ret)
854 goto error;
855 }
856 total_bit_count = (buf[1] << 8) + buf[0];
857 total_bit_count = total_bit_count - abort_packet_count;
858 total_bit_count = total_bit_count * 204 * 8;
859
860 if (total_bit_count)
861 state->ber = error_bit_count * 1000000000 / total_bit_count;
862
863 state->ucblocks += abort_packet_count;
864
865 deb_info("%s: err bits:%d total bits:%d abort count:%d\n", __func__,
866 error_bit_count, total_bit_count, abort_packet_count);
867
868 /* set BER counting range */
869 ret = af9013_write_reg(state, 0xd385, 10000 & 0xff);
870 if (ret)
871 goto error;
872 ret = af9013_write_reg(state, 0xd386, 10000 >> 8);
873 if (ret)
874 goto error;
875 /* reset and start BER counter */
876 ret = af9013_write_reg_bits(state, 0xd391, 4, 1, 1);
877 if (ret)
878 goto error;
879
880exit:
881error:
882 return ret;
883}
884
885static int af9013_update_snr(struct dvb_frontend *fe)
886{
887 struct af9013_state *state = fe->demodulator_priv;
888 int ret;
889 u8 buf[3], i, len;
890 u32 quant = 0;
891 struct snr_table *uninitialized_var(snr_table);
892
893 /* check if quantizer ready (for snr) */
894 ret = af9013_read_reg_bits(state, 0xd2e1, 3, 1, &buf[0]);
895 if (ret)
896 goto error;
897 if (buf[0]) {
898 /* quantizer ready - read it */
899 for (i = 0; i < 3; i++) {
900 ret = af9013_read_reg(state, 0xd2e3 + i, &buf[i]);
901 if (ret)
902 goto error;
903 }
904 quant = (buf[2] << 16) + (buf[1] << 8) + buf[0];
905
906 /* read current constellation */
907 ret = af9013_read_reg(state, 0xd3c1, &buf[0]);
908 if (ret)
909 goto error;
910
911 switch ((buf[0] >> 6) & 3) {
912 case 0:
913 len = ARRAY_SIZE(qpsk_snr_table);
914 snr_table = qpsk_snr_table;
915 break;
916 case 1:
917 len = ARRAY_SIZE(qam16_snr_table);
918 snr_table = qam16_snr_table;
919 break;
920 case 2:
921 len = ARRAY_SIZE(qam64_snr_table);
922 snr_table = qam64_snr_table;
923 break;
924 default:
925 len = 0;
926 break;
927 }
928
929 if (len) {
930 for (i = 0; i < len; i++) {
931 if (quant < snr_table[i].val) {
932 state->snr = snr_table[i].snr * 10;
933 break;
934 }
935 }
936 }
937
938 /* set quantizer super frame count */
939 ret = af9013_write_reg(state, 0xd2e2, 1);
940 if (ret)
941 goto error;
942
943 /* check quantizer availability */
944 for (i = 0; i < 10; i++) {
945 msleep(10);
946 ret = af9013_read_reg_bits(state, 0xd2e6, 0, 1,
947 &buf[0]);
948 if (ret)
949 goto error;
950 if (!buf[0])
951 break;
952 }
953
954 /* reset quantizer */
955 ret = af9013_write_reg_bits(state, 0xd2e1, 3, 1, 1);
956 if (ret)
957 goto error;
958 }
959
960error:
961 return ret;
962}
963
964static int af9013_update_signal_strength(struct dvb_frontend *fe)
965{
966 struct af9013_state *state = fe->demodulator_priv;
967 int ret = 0;
968 u8 rf_gain, if_gain;
969 int signal_strength;
970
971 deb_info("%s\n", __func__);
972
973 if (state->signal_strength_en) {
974 ret = af9013_read_reg(state, 0xd07c, &rf_gain);
975 if (ret)
976 goto error;
977 ret = af9013_read_reg(state, 0xd07d, &if_gain);
978 if (ret)
979 goto error;
980 signal_strength = (0xffff / \
981 (9 * (state->rf_50 + state->if_50) - \
982 11 * (state->rf_80 + state->if_80))) * \
983 (10 * (rf_gain + if_gain) - \
984 11 * (state->rf_80 + state->if_80));
985 if (signal_strength < 0)
986 signal_strength = 0;
987 else if (signal_strength > 0xffff)
988 signal_strength = 0xffff;
989
990 state->signal_strength = signal_strength;
991 } else {
992 state->signal_strength = 0;
993 }
994
995error:
996 return ret;
997}
998
999static int af9013_update_statistics(struct dvb_frontend *fe)
1000{
1001 struct af9013_state *state = fe->demodulator_priv;
1002 int ret;
1003
1004 if (time_before(jiffies, state->next_statistics_check))
1005 return 0;
1006
1007 /* set minimum statistic update interval */
1008 state->next_statistics_check = jiffies + msecs_to_jiffies(1200);
1009
1010 ret = af9013_update_signal_strength(fe);
1011 if (ret)
1012 goto error;
1013 ret = af9013_update_snr(fe);
1014 if (ret)
1015 goto error;
1016 ret = af9013_update_ber_unc(fe);
1017 if (ret)
1018 goto error;
1019
1020error:
1021 return ret;
1022}
1023
1024static int af9013_get_tune_settings(struct dvb_frontend *fe,
1025 struct dvb_frontend_tune_settings *fesettings)
1026{
1027 fesettings->min_delay_ms = 800;
1028 fesettings->step_size = 0;
1029 fesettings->max_drift = 0;
1030
1031 return 0;
1032}
1033
1034static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status)
1035{
1036 struct af9013_state *state = fe->demodulator_priv;
1037 int ret = 0;
1038 u8 tmp;
1039 *status = 0;
1040
1041 /* MPEG2 lock */
1042 ret = af9013_read_reg_bits(state, 0xd507, 6, 1, &tmp);
1043 if (ret)
1044 goto error;
1045 if (tmp)
1046 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
1047 FE_HAS_SYNC | FE_HAS_LOCK;
1048
1049 if (!*status) {
1050 /* TPS lock */
1051 ret = af9013_read_reg_bits(state, 0xd330, 3, 1, &tmp);
1052 if (ret)
1053 goto error;
1054 if (tmp)
1055 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
1056 FE_HAS_VITERBI;
1057 }
1058
1059 if (!*status) {
1060 /* CFO lock */
1061 ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp);
1062 if (ret)
1063 goto error;
1064 if (tmp)
1065 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
1066 }
1067
1068 if (!*status) {
1069 /* SFOE lock */
1070 ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp);
1071 if (ret)
1072 goto error;
1073 if (tmp)
1074 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
1075 }
1076
1077 if (!*status) {
1078 /* AGC lock */
1079 ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp);
1080 if (ret)
1081 goto error;
1082 if (tmp)
1083 *status |= FE_HAS_SIGNAL;
1084 }
1085
1086 ret = af9013_update_statistics(fe);
1087
1088error:
1089 return ret;
1090}
1091
1092
1093static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber)
1094{
1095 struct af9013_state *state = fe->demodulator_priv;
1096 int ret;
1097 ret = af9013_update_statistics(fe);
1098 *ber = state->ber;
1099 return ret;
1100}
1101
1102static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1103{
1104 struct af9013_state *state = fe->demodulator_priv;
1105 int ret;
1106 ret = af9013_update_statistics(fe);
1107 *strength = state->signal_strength;
1108 return ret;
1109}
1110
1111static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr)
1112{
1113 struct af9013_state *state = fe->demodulator_priv;
1114 int ret;
1115 ret = af9013_update_statistics(fe);
1116 *snr = state->snr;
1117 return ret;
1118}
1119
1120static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
1121{
1122 struct af9013_state *state = fe->demodulator_priv;
1123 int ret;
1124 ret = af9013_update_statistics(fe);
1125 *ucblocks = state->ucblocks;
1126 return ret;
1127}
1128
1129static int af9013_sleep(struct dvb_frontend *fe)
1130{
1131 struct af9013_state *state = fe->demodulator_priv;
1132 int ret;
1133 deb_info("%s\n", __func__);
1134
1135 ret = af9013_lock_led(state, 0);
1136 if (ret)
1137 goto error;
1138
1139 ret = af9013_power_ctrl(state, 0);
1140error:
1141 return ret;
1142}
1143
1144static int af9013_init(struct dvb_frontend *fe)
1145{
1146 struct af9013_state *state = fe->demodulator_priv;
1147 int ret, i, len;
1148 u8 tmp0, tmp1;
1149 struct regdesc *init;
1150 deb_info("%s\n", __func__);
1151
1152 /* reset OFDM */
1153 ret = af9013_reset(state, 0);
1154 if (ret)
1155 goto error;
1156
1157 /* power on */
1158 ret = af9013_power_ctrl(state, 1);
1159 if (ret)
1160 goto error;
1161
1162 /* enable ADC */
1163 ret = af9013_write_reg(state, 0xd73a, 0xa4);
1164 if (ret)
1165 goto error;
1166
1167 /* write API version to firmware */
1168 for (i = 0; i < sizeof(state->config.api_version); i++) {
1169 ret = af9013_write_reg(state, 0x9bf2 + i,
1170 state->config.api_version[i]);
1171 if (ret)
1172 goto error;
1173 }
1174
1175 /* program ADC control */
1176 ret = af9013_set_adc_ctrl(state);
1177 if (ret)
1178 goto error;
1179
1180 /* set I2C master clock */
1181 ret = af9013_write_reg(state, 0xd416, 0x14);
1182 if (ret)
1183 goto error;
1184
1185 /* set 16 embx */
1186 ret = af9013_write_reg_bits(state, 0xd700, 1, 1, 1);
1187 if (ret)
1188 goto error;
1189
1190 /* set no trigger */
1191 ret = af9013_write_reg_bits(state, 0xd700, 2, 1, 0);
1192 if (ret)
1193 goto error;
1194
1195 /* set read-update bit for constellation */
1196 ret = af9013_write_reg_bits(state, 0xd371, 1, 1, 1);
1197 if (ret)
1198 goto error;
1199
1200 /* enable FEC monitor */
1201 ret = af9013_write_reg_bits(state, 0xd392, 1, 1, 1);
1202 if (ret)
1203 goto error;
1204
1205 /* load OFSM settings */
1206 deb_info("%s: load ofsm settings\n", __func__);
1207 len = ARRAY_SIZE(ofsm_init);
1208 init = ofsm_init;
1209 for (i = 0; i < len; i++) {
1210 ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos,
1211 init[i].len, init[i].val);
1212 if (ret)
1213 goto error;
1214 }
1215
1216 /* load tuner specific settings */
1217 deb_info("%s: load tuner specific settings\n", __func__);
1218 switch (state->config.tuner) {
1219 case AF9013_TUNER_MXL5003D:
1220 len = ARRAY_SIZE(tuner_init_mxl5003d);
1221 init = tuner_init_mxl5003d;
1222 break;
1223 case AF9013_TUNER_MXL5005D:
1224 case AF9013_TUNER_MXL5005R:
1225 case AF9013_TUNER_MXL5007T:
1226 len = ARRAY_SIZE(tuner_init_mxl5005);
1227 init = tuner_init_mxl5005;
1228 break;
1229 case AF9013_TUNER_ENV77H11D5:
1230 len = ARRAY_SIZE(tuner_init_env77h11d5);
1231 init = tuner_init_env77h11d5;
1232 break;
1233 case AF9013_TUNER_MT2060:
1234 len = ARRAY_SIZE(tuner_init_mt2060);
1235 init = tuner_init_mt2060;
1236 break;
1237 case AF9013_TUNER_MC44S803:
1238 len = ARRAY_SIZE(tuner_init_mc44s803);
1239 init = tuner_init_mc44s803;
1240 break;
1241 case AF9013_TUNER_QT1010:
1242 case AF9013_TUNER_QT1010A:
1243 len = ARRAY_SIZE(tuner_init_qt1010);
1244 init = tuner_init_qt1010;
1245 break;
1246 case AF9013_TUNER_MT2060_2:
1247 len = ARRAY_SIZE(tuner_init_mt2060_2);
1248 init = tuner_init_mt2060_2;
1249 break;
1250 case AF9013_TUNER_TDA18271:
1251 case AF9013_TUNER_TDA18218:
1252 len = ARRAY_SIZE(tuner_init_tda18271);
1253 init = tuner_init_tda18271;
1254 break;
1255 case AF9013_TUNER_UNKNOWN:
1256 default:
1257 len = ARRAY_SIZE(tuner_init_unknown);
1258 init = tuner_init_unknown;
1259 break;
1260 }
1261
1262 for (i = 0; i < len; i++) {
1263 ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos,
1264 init[i].len, init[i].val);
1265 if (ret)
1266 goto error;
1267 }
1268
1269 /* set TS mode */
1270 deb_info("%s: setting ts mode\n", __func__);
1271 tmp0 = 0; /* parallel mode */
1272 tmp1 = 0; /* serial mode */
1273 switch (state->config.output_mode) {
1274 case AF9013_OUTPUT_MODE_PARALLEL:
1275 tmp0 = 1;
1276 break;
1277 case AF9013_OUTPUT_MODE_SERIAL:
1278 tmp1 = 1;
1279 break;
1280 case AF9013_OUTPUT_MODE_USB:
1281 /* usb mode for AF9015 */
1282 default:
1283 break;
1284 }
1285 ret = af9013_write_reg_bits(state, 0xd500, 1, 1, tmp0); /* parallel */
1286 if (ret)
1287 goto error;
1288 ret = af9013_write_reg_bits(state, 0xd500, 2, 1, tmp1); /* serial */
1289 if (ret)
1290 goto error;
1291
1292 /* enable lock led */
1293 ret = af9013_lock_led(state, 1);
1294 if (ret)
1295 goto error;
1296
1297 /* read values needed for signal strength calculation */
1298 ret = af9013_read_reg_bits(state, 0x9bee, 0, 1,
1299 &state->signal_strength_en);
1300 if (ret)
1301 goto error;
1302
1303 if (state->signal_strength_en) {
1304 ret = af9013_read_reg(state, 0x9bbd, &state->rf_50);
1305 if (ret)
1306 goto error;
1307 ret = af9013_read_reg(state, 0x9bd0, &state->rf_80);
1308 if (ret)
1309 goto error;
1310 ret = af9013_read_reg(state, 0x9be2, &state->if_50);
1311 if (ret)
1312 goto error;
1313 ret = af9013_read_reg(state, 0x9be4, &state->if_80);
1314 if (ret)
1315 goto error;
1316 }
1317
1318error:
1319 return ret;
1320}
1321
1322static struct dvb_frontend_ops af9013_ops;
1323
1324static int af9013_download_firmware(struct af9013_state *state)
1325{
1326 int i, len, remaining, ret;
1327 const struct firmware *fw;
1328 u16 checksum = 0;
1329 u8 val;
1330 u8 fw_params[4];
1331 u8 *fw_file = AF9013_DEFAULT_FIRMWARE;
1332
1333 msleep(100);
1334 /* check whether firmware is already running */
1335 ret = af9013_read_reg(state, 0x98be, &val);
1336 if (ret)
1337 goto error;
1338 else
1339 deb_info("%s: firmware status:%02x\n", __func__, val);
1340
1341 if (val == 0x0c) /* fw is running, no need for download */
1342 goto exit;
1343
1344 info("found a '%s' in cold state, will try to load a firmware",
1345 af9013_ops.info.name);
1346
1347 /* request the firmware, this will block and timeout */
1348 ret = request_firmware(&fw, fw_file, state->i2c->dev.parent);
1349 if (ret) {
1350 err("did not find the firmware file. (%s) "
1351 "Please see linux/Documentation/dvb/ for more details" \
1352 " on firmware-problems. (%d)",
1353 fw_file, ret);
1354 goto error;
1355 }
1356
1357 info("downloading firmware from file '%s'", fw_file);
1358
1359 /* calc checksum */
1360 for (i = 0; i < fw->size; i++)
1361 checksum += fw->data[i];
1362
1363 fw_params[0] = checksum >> 8;
1364 fw_params[1] = checksum & 0xff;
1365 fw_params[2] = fw->size >> 8;
1366 fw_params[3] = fw->size & 0xff;
1367
1368 /* write fw checksum & size */
1369 ret = af9013_write_ofsm_regs(state, 0x50fc,
1370 fw_params, sizeof(fw_params));
1371 if (ret)
1372 goto error_release;
1373
1374 #define FW_ADDR 0x5100 /* firmware start address */
1375 #define LEN_MAX 16 /* max packet size */
1376 for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
1377 len = remaining;
1378 if (len > LEN_MAX)
1379 len = LEN_MAX;
1380
1381 ret = af9013_write_ofsm_regs(state,
1382 FW_ADDR + fw->size - remaining,
1383 (u8 *) &fw->data[fw->size - remaining], len);
1384 if (ret) {
1385 err("firmware download failed:%d", ret);
1386 goto error_release;
1387 }
1388 }
1389
1390 /* request boot firmware */
1391 ret = af9013_write_reg(state, 0xe205, 1);
1392 if (ret)
1393 goto error_release;
1394
1395 for (i = 0; i < 15; i++) {
1396 msleep(100);
1397
1398 /* check firmware status */
1399 ret = af9013_read_reg(state, 0x98be, &val);
1400 if (ret)
1401 goto error_release;
1402
1403 deb_info("%s: firmware status:%02x\n", __func__, val);
1404
1405 if (val == 0x0c || val == 0x04) /* success or fail */
1406 break;
1407 }
1408
1409 if (val == 0x04) {
1410 err("firmware did not run");
1411 ret = -1;
1412 } else if (val != 0x0c) {
1413 err("firmware boot timeout");
1414 ret = -1;
1415 }
1416
1417error_release:
1418 release_firmware(fw);
1419error:
1420exit:
1421 if (!ret)
1422 info("found a '%s' in warm state.", af9013_ops.info.name);
1423 return ret;
1424}
1425
1426static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
1427{
1428 int ret;
1429 struct af9013_state *state = fe->demodulator_priv;
1430 deb_info("%s: enable:%d\n", __func__, enable);
1431
1432 if (state->config.output_mode == AF9013_OUTPUT_MODE_USB)
1433 ret = af9013_write_reg_bits(state, 0xd417, 3, 1, enable);
1434 else
1435 ret = af9013_write_reg_bits(state, 0xd607, 2, 1, enable);
1436
1437 return ret;
1438}
1439
1440static void af9013_release(struct dvb_frontend *fe)
1441{
1442 struct af9013_state *state = fe->demodulator_priv;
1443 kfree(state);
1444}
1445
1446static struct dvb_frontend_ops af9013_ops;
1447
1448struct dvb_frontend *af9013_attach(const struct af9013_config *config,
1449 struct i2c_adapter *i2c)
1450{
1451 int ret;
1452 struct af9013_state *state = NULL;
1453 u8 buf[4], i;
1454
1455 /* allocate memory for the internal state */
1456 state = kzalloc(sizeof(struct af9013_state), GFP_KERNEL);
1457 if (state == NULL)
1458 goto error;
1459
1460 /* setup the state */
1461 state->i2c = i2c;
1462 memcpy(&state->config, config, sizeof(struct af9013_config));
1463
1464 /* download firmware */
1465 if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) {
1466 ret = af9013_download_firmware(state);
1467 if (ret)
1468 goto error;
1469 }
1470
1471 /* firmware version */
1472 for (i = 0; i < 4; i++) {
1473 ret = af9013_read_reg(state, 0x5103 + i, &buf[i]);
1474 if (ret)
1475 goto error;
1476 }
1477 info("firmware version:%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]);
1478
1479 /* chip version */
1480 ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]);
1481 if (ret)
1482 goto error;
1483
1484 /* ROM version */
1485 for (i = 0; i < 2; i++) {
1486 ret = af9013_read_reg(state, 0x116b + i, &buf[i]);
1487 if (ret)
1488 goto error;
1489 }
1490 deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__,
1491 buf[2], buf[0], buf[1]);
1492
1493 /* settings for mp2if */
1494 if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) {
1495 /* AF9015 split PSB to 1.5k + 0.5k */
1496 ret = af9013_write_reg_bits(state, 0xd50b, 2, 1, 1);
1497 } else {
1498 /* AF9013 change the output bit to data7 */
1499 ret = af9013_write_reg_bits(state, 0xd500, 3, 1, 1);
1500 if (ret)
1501 goto error;
1502 /* AF9013 set mpeg to full speed */
1503 ret = af9013_write_reg_bits(state, 0xd502, 4, 1, 1);
1504 }
1505 if (ret)
1506 goto error;
1507 ret = af9013_write_reg_bits(state, 0xd520, 4, 1, 1);
1508 if (ret)
1509 goto error;
1510
1511 /* set GPIOs */
1512 for (i = 0; i < sizeof(state->config.gpio); i++) {
1513 ret = af9013_set_gpio(state, i, state->config.gpio[i]);
1514 if (ret)
1515 goto error;
1516 }
1517
1518 /* create dvb_frontend */
1519 memcpy(&state->frontend.ops, &af9013_ops,
1520 sizeof(struct dvb_frontend_ops));
1521 state->frontend.demodulator_priv = state;
1522
1523 return &state->frontend;
1524error:
1525 kfree(state);
1526 return NULL;
1527}
1528EXPORT_SYMBOL(af9013_attach);
1529
1530static struct dvb_frontend_ops af9013_ops = {
1531 .info = {
1532 .name = "Afatech AF9013 DVB-T",
1533 .type = FE_OFDM,
1534 .frequency_min = 174000000,
1535 .frequency_max = 862000000,
1536 .frequency_stepsize = 250000,
1537 .frequency_tolerance = 0,
1538 .caps =
1539 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1540 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1541 FE_CAN_QPSK | FE_CAN_QAM_16 |
1542 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1543 FE_CAN_TRANSMISSION_MODE_AUTO |
1544 FE_CAN_GUARD_INTERVAL_AUTO |
1545 FE_CAN_HIERARCHY_AUTO |
1546 FE_CAN_RECOVER |
1547 FE_CAN_MUTE_TS
1548 },
1549
1550 .release = af9013_release,
1551 .init = af9013_init,
1552 .sleep = af9013_sleep,
1553 .i2c_gate_ctrl = af9013_i2c_gate_ctrl,
1554
1555 .set_frontend = af9013_set_frontend,
1556 .get_frontend = af9013_get_frontend,
1557
1558 .get_tune_settings = af9013_get_tune_settings,
1559
1560 .read_status = af9013_read_status,
1561 .read_ber = af9013_read_ber,
1562 .read_signal_strength = af9013_read_signal_strength,
1563 .read_snr = af9013_read_snr,
1564 .read_ucblocks = af9013_read_ucblocks,
1565};
1566
1567module_param_named(debug, af9013_debug, int, 0644);
1568MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1569
1570MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1571MODULE_DESCRIPTION("Afatech AF9013 DVB-T demodulator driver");
1572MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/af9013.h b/drivers/media/dvb/frontends/af9013.h
new file mode 100644
index 00000000000..e53d873f755
--- /dev/null
+++ b/drivers/media/dvb/frontends/af9013.h
@@ -0,0 +1,109 @@
1/*
2 * Afatech AF9013 demodulator driver
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 _AF9013_H_
25#define _AF9013_H_
26
27#include <linux/dvb/frontend.h>
28
29enum af9013_ts_mode {
30 AF9013_OUTPUT_MODE_PARALLEL,
31 AF9013_OUTPUT_MODE_SERIAL,
32 AF9013_OUTPUT_MODE_USB, /* only for AF9015 */
33};
34
35enum af9013_tuner {
36 AF9013_TUNER_MXL5003D = 3, /* MaxLinear */
37 AF9013_TUNER_MXL5005D = 13, /* MaxLinear */
38 AF9013_TUNER_MXL5005R = 30, /* MaxLinear */
39 AF9013_TUNER_ENV77H11D5 = 129, /* Panasonic */
40 AF9013_TUNER_MT2060 = 130, /* Microtune */
41 AF9013_TUNER_MC44S803 = 133, /* Freescale */
42 AF9013_TUNER_QT1010 = 134, /* Quantek */
43 AF9013_TUNER_UNKNOWN = 140, /* for can tuners ? */
44 AF9013_TUNER_MT2060_2 = 147, /* Microtune */
45 AF9013_TUNER_TDA18271 = 156, /* NXP */
46 AF9013_TUNER_QT1010A = 162, /* Quantek */
47 AF9013_TUNER_MXL5007T = 177, /* MaxLinear */
48 AF9013_TUNER_TDA18218 = 179, /* NXP */
49};
50
51/* AF9013/5 GPIOs (mostly guessed)
52 demod#1-gpio#0 - set demod#2 i2c-addr for dual devices
53 demod#1-gpio#1 - xtal setting (?)
54 demod#1-gpio#3 - tuner#1
55 demod#2-gpio#0 - tuner#2
56 demod#2-gpio#1 - xtal setting (?)
57*/
58#define AF9013_GPIO_ON (1 << 0)
59#define AF9013_GPIO_EN (1 << 1)
60#define AF9013_GPIO_O (1 << 2)
61#define AF9013_GPIO_I (1 << 3)
62
63#define AF9013_GPIO_LO (AF9013_GPIO_ON|AF9013_GPIO_EN)
64#define AF9013_GPIO_HI (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O)
65
66#define AF9013_GPIO_TUNER_ON (AF9013_GPIO_ON|AF9013_GPIO_EN)
67#define AF9013_GPIO_TUNER_OFF (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O)
68
69struct af9013_config {
70 /* demodulator's I2C address */
71 u8 demod_address;
72
73 /* frequencies in kHz */
74 u32 adc_clock;
75
76 /* tuner ID */
77 u8 tuner;
78
79 /* tuner IF */
80 u16 tuner_if;
81
82 /* TS data output mode */
83 u8 output_mode:2;
84
85 /* RF spectrum inversion */
86 u8 rf_spec_inv:1;
87
88 /* API version */
89 u8 api_version[4];
90
91 /* GPIOs */
92 u8 gpio[4];
93};
94
95
96#if defined(CONFIG_DVB_AF9013) || \
97 (defined(CONFIG_DVB_AF9013_MODULE) && defined(MODULE))
98extern struct dvb_frontend *af9013_attach(const struct af9013_config *config,
99 struct i2c_adapter *i2c);
100#else
101static inline struct dvb_frontend *af9013_attach(
102const struct af9013_config *config, struct i2c_adapter *i2c)
103{
104 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
105 return NULL;
106}
107#endif /* CONFIG_DVB_AF9013 */
108
109#endif /* _AF9013_H_ */
diff --git a/drivers/media/dvb/frontends/af9013_priv.h b/drivers/media/dvb/frontends/af9013_priv.h
new file mode 100644
index 00000000000..e00b2a4a2db
--- /dev/null
+++ b/drivers/media/dvb/frontends/af9013_priv.h
@@ -0,0 +1,923 @@
1/*
2 * Afatech AF9013 demodulator driver
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 _AF9013_PRIV_
25#define _AF9013_PRIV_
26
27#define LOG_PREFIX "af9013"
28extern int af9013_debug;
29
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_++) \
36 func("%02x ", b[loop_]); \
37 func("\n");\
38}
39
40#define deb_info(args...) dprintk(af9013_debug, 0x01, args)
41
42#undef err
43#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
44#undef info
45#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
46#undef warn
47#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
48
49#define AF9013_DEFAULT_FIRMWARE "dvb-fe-af9013.fw"
50
51struct regdesc {
52 u16 addr;
53 u8 pos:4;
54 u8 len:4;
55 u8 val;
56};
57
58struct snr_table {
59 u32 val;
60 u8 snr;
61};
62
63struct coeff {
64 u32 adc_clock;
65 fe_bandwidth_t bw;
66 u8 val[24];
67};
68
69/* pre-calculated coeff lookup table */
70static struct coeff coeff_table[] = {
71 /* 28.800 MHz */
72 { 28800, BANDWIDTH_8_MHZ, { 0x02, 0x8a, 0x28, 0xa3, 0x05, 0x14,
73 0x51, 0x11, 0x00, 0xa2, 0x8f, 0x3d, 0x00, 0xa2, 0x8a,
74 0x29, 0x00, 0xa2, 0x85, 0x14, 0x01, 0x45, 0x14, 0x14 } },
75 { 28800, BANDWIDTH_7_MHZ, { 0x02, 0x38, 0xe3, 0x8e, 0x04, 0x71,
76 0xc7, 0x07, 0x00, 0x8e, 0x3d, 0x55, 0x00, 0x8e, 0x38,
77 0xe4, 0x00, 0x8e, 0x34, 0x72, 0x01, 0x1c, 0x71, 0x32 } },
78 { 28800, BANDWIDTH_6_MHZ, { 0x01, 0xe7, 0x9e, 0x7a, 0x03, 0xcf,
79 0x3c, 0x3d, 0x00, 0x79, 0xeb, 0x6e, 0x00, 0x79, 0xe7,
80 0x9e, 0x00, 0x79, 0xe3, 0xcf, 0x00, 0xf3, 0xcf, 0x0f } },
81 /* 20.480 MHz */
82 { 20480, BANDWIDTH_8_MHZ, { 0x03, 0x92, 0x49, 0x26, 0x07, 0x24,
83 0x92, 0x13, 0x00, 0xe4, 0x99, 0x6e, 0x00, 0xe4, 0x92,
84 0x49, 0x00, 0xe4, 0x8b, 0x25, 0x01, 0xc9, 0x24, 0x25 } },
85 { 20480, BANDWIDTH_7_MHZ, { 0x03, 0x20, 0x00, 0x01, 0x06, 0x40,
86 0x00, 0x00, 0x00, 0xc8, 0x06, 0x40, 0x00, 0xc8, 0x00,
87 0x00, 0x00, 0xc7, 0xf9, 0xc0, 0x01, 0x90, 0x00, 0x00 } },
88 { 20480, BANDWIDTH_6_MHZ, { 0x02, 0xad, 0xb6, 0xdc, 0x05, 0x5b,
89 0x6d, 0x2e, 0x00, 0xab, 0x73, 0x13, 0x00, 0xab, 0x6d,
90 0xb7, 0x00, 0xab, 0x68, 0x5c, 0x01, 0x56, 0xdb, 0x1c } },
91 /* 28.000 MHz */
92 { 28000, BANDWIDTH_8_MHZ, { 0x02, 0x9c, 0xbc, 0x15, 0x05, 0x39,
93 0x78, 0x0a, 0x00, 0xa7, 0x34, 0x3f, 0x00, 0xa7, 0x2f,
94 0x05, 0x00, 0xa7, 0x29, 0xcc, 0x01, 0x4e, 0x5e, 0x03 } },
95 { 28000, BANDWIDTH_7_MHZ, { 0x02, 0x49, 0x24, 0x92, 0x04, 0x92,
96 0x49, 0x09, 0x00, 0x92, 0x4d, 0xb7, 0x00, 0x92, 0x49,
97 0x25, 0x00, 0x92, 0x44, 0x92, 0x01, 0x24, 0x92, 0x12 } },
98 { 28000, BANDWIDTH_6_MHZ, { 0x01, 0xf5, 0x8d, 0x10, 0x03, 0xeb,
99 0x1a, 0x08, 0x00, 0x7d, 0x67, 0x2f, 0x00, 0x7d, 0x63,
100 0x44, 0x00, 0x7d, 0x5f, 0x59, 0x00, 0xfa, 0xc6, 0x22 } },
101 /* 25.000 MHz */
102 { 25000, BANDWIDTH_8_MHZ, { 0x02, 0xec, 0xfb, 0x9d, 0x05, 0xd9,
103 0xf7, 0x0e, 0x00, 0xbb, 0x44, 0xc1, 0x00, 0xbb, 0x3e,
104 0xe7, 0x00, 0xbb, 0x39, 0x0d, 0x01, 0x76, 0x7d, 0x34 } },
105 { 25000, BANDWIDTH_7_MHZ, { 0x02, 0x8f, 0x5c, 0x29, 0x05, 0x1e,
106 0xb8, 0x14, 0x00, 0xa3, 0xdc, 0x29, 0x00, 0xa3, 0xd7,
107 0x0a, 0x00, 0xa3, 0xd1, 0xec, 0x01, 0x47, 0xae, 0x05 } },
108 { 25000, BANDWIDTH_6_MHZ, { 0x02, 0x31, 0xbc, 0xb5, 0x04, 0x63,
109 0x79, 0x1b, 0x00, 0x8c, 0x73, 0x91, 0x00, 0x8c, 0x6f,
110 0x2d, 0x00, 0x8c, 0x6a, 0xca, 0x01, 0x18, 0xde, 0x17 } },
111};
112
113/* QPSK SNR lookup table */
114static struct snr_table qpsk_snr_table[] = {
115 { 0x0b4771, 0 },
116 { 0x0c1aed, 1 },
117 { 0x0d0d27, 2 },
118 { 0x0e4d19, 3 },
119 { 0x0e5da8, 4 },
120 { 0x107097, 5 },
121 { 0x116975, 6 },
122 { 0x1252d9, 7 },
123 { 0x131fa4, 8 },
124 { 0x13d5e1, 9 },
125 { 0x148e53, 10 },
126 { 0x15358b, 11 },
127 { 0x15dd29, 12 },
128 { 0x168112, 13 },
129 { 0x170b61, 14 },
130 { 0xffffff, 15 },
131};
132
133/* QAM16 SNR lookup table */
134static struct snr_table qam16_snr_table[] = {
135 { 0x05eb62, 5 },
136 { 0x05fecf, 6 },
137 { 0x060b80, 7 },
138 { 0x062501, 8 },
139 { 0x064865, 9 },
140 { 0x069604, 10 },
141 { 0x06f356, 11 },
142 { 0x07706a, 12 },
143 { 0x0804d3, 13 },
144 { 0x089d1a, 14 },
145 { 0x093e3d, 15 },
146 { 0x09e35d, 16 },
147 { 0x0a7c3c, 17 },
148 { 0x0afaf8, 18 },
149 { 0x0b719d, 19 },
150 { 0xffffff, 20 },
151};
152
153/* QAM64 SNR lookup table */
154static struct snr_table qam64_snr_table[] = {
155 { 0x03109b, 12 },
156 { 0x0310d4, 13 },
157 { 0x031920, 14 },
158 { 0x0322d0, 15 },
159 { 0x0339fc, 16 },
160 { 0x0364a1, 17 },
161 { 0x038bcc, 18 },
162 { 0x03c7d3, 19 },
163 { 0x0408cc, 20 },
164 { 0x043bed, 21 },
165 { 0x048061, 22 },
166 { 0x04be95, 23 },
167 { 0x04fa7d, 24 },
168 { 0x052405, 25 },
169 { 0x05570d, 26 },
170 { 0xffffff, 27 },
171};
172
173static struct regdesc ofsm_init[] = {
174 { 0xd73a, 0, 8, 0xa1 },
175 { 0xd73b, 0, 8, 0x1f },
176 { 0xd73c, 4, 4, 0x0a },
177 { 0xd732, 3, 1, 0x00 },
178 { 0xd731, 4, 2, 0x03 },
179 { 0xd73d, 7, 1, 0x01 },
180 { 0xd740, 0, 1, 0x00 },
181 { 0xd740, 1, 1, 0x00 },
182 { 0xd740, 2, 1, 0x00 },
183 { 0xd740, 3, 1, 0x01 },
184 { 0xd3c1, 4, 1, 0x01 },
185 { 0x9124, 0, 8, 0x58 },
186 { 0x9125, 0, 2, 0x02 },
187 { 0xd3a2, 0, 8, 0x00 },
188 { 0xd3a3, 0, 8, 0x04 },
189 { 0xd305, 0, 8, 0x32 },
190 { 0xd306, 0, 8, 0x10 },
191 { 0xd304, 0, 8, 0x04 },
192 { 0x9112, 0, 1, 0x01 },
193 { 0x911d, 0, 1, 0x01 },
194 { 0x911a, 0, 1, 0x01 },
195 { 0x911b, 0, 1, 0x01 },
196 { 0x9bce, 0, 4, 0x02 },
197 { 0x9116, 0, 1, 0x01 },
198 { 0x9122, 0, 8, 0xd0 },
199 { 0xd2e0, 0, 8, 0xd0 },
200 { 0xd2e9, 0, 4, 0x0d },
201 { 0xd38c, 0, 8, 0xfc },
202 { 0xd38d, 0, 8, 0x00 },
203 { 0xd38e, 0, 8, 0x7e },
204 { 0xd38f, 0, 8, 0x00 },
205 { 0xd390, 0, 8, 0x2f },
206 { 0xd145, 4, 1, 0x01 },
207 { 0xd1a9, 4, 1, 0x01 },
208 { 0xd158, 5, 3, 0x01 },
209 { 0xd159, 0, 6, 0x06 },
210 { 0xd167, 0, 8, 0x00 },
211 { 0xd168, 0, 4, 0x07 },
212 { 0xd1c3, 5, 3, 0x00 },
213 { 0xd1c4, 0, 6, 0x00 },
214 { 0xd1c5, 0, 7, 0x10 },
215 { 0xd1c6, 0, 3, 0x02 },
216 { 0xd080, 2, 5, 0x03 },
217 { 0xd081, 4, 4, 0x09 },
218 { 0xd098, 4, 4, 0x0f },
219 { 0xd098, 0, 4, 0x03 },
220 { 0xdbc0, 4, 1, 0x01 },
221 { 0xdbc7, 0, 8, 0x08 },
222 { 0xdbc8, 4, 4, 0x00 },
223 { 0xdbc9, 0, 5, 0x01 },
224 { 0xd280, 0, 8, 0xe0 },
225 { 0xd281, 0, 8, 0xff },
226 { 0xd282, 0, 8, 0xff },
227 { 0xd283, 0, 8, 0xc3 },
228 { 0xd284, 0, 8, 0xff },
229 { 0xd285, 0, 4, 0x01 },
230 { 0xd0f0, 0, 7, 0x1a },
231 { 0xd0f1, 4, 1, 0x01 },
232 { 0xd0f2, 0, 8, 0x0c },
233 { 0xd101, 5, 3, 0x06 },
234 { 0xd103, 0, 4, 0x08 },
235 { 0xd0f8, 0, 7, 0x20 },
236 { 0xd111, 5, 1, 0x00 },
237 { 0xd111, 6, 1, 0x00 },
238 { 0x910b, 0, 8, 0x0a },
239 { 0x9115, 0, 8, 0x02 },
240 { 0x910c, 0, 8, 0x02 },
241 { 0x910d, 0, 8, 0x08 },
242 { 0x910e, 0, 8, 0x0a },
243 { 0x9bf6, 0, 8, 0x06 },
244 { 0x9bf8, 0, 8, 0x02 },
245 { 0x9bf7, 0, 8, 0x05 },
246 { 0x9bf9, 0, 8, 0x0f },
247 { 0x9bfc, 0, 8, 0x13 },
248 { 0x9bd3, 0, 8, 0xff },
249 { 0x9bbe, 0, 1, 0x01 },
250 { 0x9bcc, 0, 1, 0x01 },
251};
252
253/* Panasonic ENV77H11D5 tuner init
254 AF9013_TUNER_ENV77H11D5 = 129 */
255static struct regdesc tuner_init_env77h11d5[] = {
256 { 0x9bd5, 0, 8, 0x01 },
257 { 0x9bd6, 0, 8, 0x03 },
258 { 0x9bbe, 0, 8, 0x01 },
259 { 0xd1a0, 1, 1, 0x01 },
260 { 0xd000, 0, 1, 0x01 },
261 { 0xd000, 1, 1, 0x00 },
262 { 0xd001, 1, 1, 0x01 },
263 { 0xd001, 0, 1, 0x00 },
264 { 0xd001, 5, 1, 0x00 },
265 { 0xd002, 0, 5, 0x19 },
266 { 0xd003, 0, 5, 0x1a },
267 { 0xd004, 0, 5, 0x19 },
268 { 0xd005, 0, 5, 0x1a },
269 { 0xd00e, 0, 5, 0x10 },
270 { 0xd00f, 0, 3, 0x04 },
271 { 0xd00f, 3, 3, 0x05 },
272 { 0xd010, 0, 3, 0x04 },
273 { 0xd010, 3, 3, 0x05 },
274 { 0xd016, 4, 4, 0x03 },
275 { 0xd01f, 0, 6, 0x0a },
276 { 0xd020, 0, 6, 0x0a },
277 { 0x9bda, 0, 8, 0x00 },
278 { 0x9be3, 0, 8, 0x00 },
279 { 0xd015, 0, 8, 0x50 },
280 { 0xd016, 0, 1, 0x00 },
281 { 0xd044, 0, 8, 0x46 },
282 { 0xd045, 0, 1, 0x00 },
283 { 0xd008, 0, 8, 0xdf },
284 { 0xd009, 0, 2, 0x02 },
285 { 0xd006, 0, 8, 0x44 },
286 { 0xd007, 0, 2, 0x01 },
287 { 0xd00c, 0, 8, 0xeb },
288 { 0xd00d, 0, 2, 0x02 },
289 { 0xd00a, 0, 8, 0xf4 },
290 { 0xd00b, 0, 2, 0x01 },
291 { 0x9bba, 0, 8, 0xf9 },
292 { 0x9bc3, 0, 8, 0xdf },
293 { 0x9bc4, 0, 8, 0x02 },
294 { 0x9bc5, 0, 8, 0xeb },
295 { 0x9bc6, 0, 8, 0x02 },
296 { 0x9bc9, 0, 8, 0x52 },
297 { 0xd011, 0, 8, 0x3c },
298 { 0xd012, 0, 2, 0x01 },
299 { 0xd013, 0, 8, 0xf7 },
300 { 0xd014, 0, 2, 0x02 },
301 { 0xd040, 0, 8, 0x0b },
302 { 0xd041, 0, 2, 0x02 },
303 { 0xd042, 0, 8, 0x4d },
304 { 0xd043, 0, 2, 0x00 },
305 { 0xd045, 1, 1, 0x00 },
306 { 0x9bcf, 0, 1, 0x01 },
307 { 0xd045, 2, 1, 0x01 },
308 { 0xd04f, 0, 8, 0x9a },
309 { 0xd050, 0, 1, 0x01 },
310 { 0xd051, 0, 8, 0x5a },
311 { 0xd052, 0, 1, 0x01 },
312 { 0xd053, 0, 8, 0x50 },
313 { 0xd054, 0, 8, 0x46 },
314 { 0x9bd7, 0, 8, 0x0a },
315 { 0x9bd8, 0, 8, 0x14 },
316 { 0x9bd9, 0, 8, 0x08 },
317};
318
319/* Microtune MT2060 tuner init
320 AF9013_TUNER_MT2060 = 130 */
321static struct regdesc tuner_init_mt2060[] = {
322 { 0x9bd5, 0, 8, 0x01 },
323 { 0x9bd6, 0, 8, 0x07 },
324 { 0xd1a0, 1, 1, 0x01 },
325 { 0xd000, 0, 1, 0x01 },
326 { 0xd000, 1, 1, 0x00 },
327 { 0xd001, 1, 1, 0x01 },
328 { 0xd001, 0, 1, 0x00 },
329 { 0xd001, 5, 1, 0x00 },
330 { 0xd002, 0, 5, 0x19 },
331 { 0xd003, 0, 5, 0x1a },
332 { 0xd004, 0, 5, 0x19 },
333 { 0xd005, 0, 5, 0x1a },
334 { 0xd00e, 0, 5, 0x10 },
335 { 0xd00f, 0, 3, 0x04 },
336 { 0xd00f, 3, 3, 0x05 },
337 { 0xd010, 0, 3, 0x04 },
338 { 0xd010, 3, 3, 0x05 },
339 { 0xd016, 4, 4, 0x03 },
340 { 0xd01f, 0, 6, 0x0a },
341 { 0xd020, 0, 6, 0x0a },
342 { 0x9bda, 0, 8, 0x00 },
343 { 0x9be3, 0, 8, 0x00 },
344 { 0x9bbe, 0, 1, 0x00 },
345 { 0x9bcc, 0, 1, 0x00 },
346 { 0x9bb9, 0, 8, 0x75 },
347 { 0x9bcd, 0, 8, 0x24 },
348 { 0x9bff, 0, 8, 0x30 },
349 { 0xd015, 0, 8, 0x46 },
350 { 0xd016, 0, 1, 0x00 },
351 { 0xd044, 0, 8, 0x46 },
352 { 0xd045, 0, 1, 0x00 },
353 { 0xd008, 0, 8, 0x0f },
354 { 0xd009, 0, 2, 0x02 },
355 { 0xd006, 0, 8, 0x32 },
356 { 0xd007, 0, 2, 0x01 },
357 { 0xd00c, 0, 8, 0x36 },
358 { 0xd00d, 0, 2, 0x03 },
359 { 0xd00a, 0, 8, 0x35 },
360 { 0xd00b, 0, 2, 0x01 },
361 { 0x9bc7, 0, 8, 0x07 },
362 { 0x9bc8, 0, 8, 0x90 },
363 { 0x9bc3, 0, 8, 0x0f },
364 { 0x9bc4, 0, 8, 0x02 },
365 { 0x9bc5, 0, 8, 0x36 },
366 { 0x9bc6, 0, 8, 0x03 },
367 { 0x9bba, 0, 8, 0xc9 },
368 { 0x9bc9, 0, 8, 0x79 },
369 { 0xd011, 0, 8, 0x10 },
370 { 0xd012, 0, 2, 0x01 },
371 { 0xd013, 0, 8, 0x45 },
372 { 0xd014, 0, 2, 0x03 },
373 { 0xd040, 0, 8, 0x98 },
374 { 0xd041, 0, 2, 0x00 },
375 { 0xd042, 0, 8, 0xcf },
376 { 0xd043, 0, 2, 0x03 },
377 { 0xd045, 1, 1, 0x00 },
378 { 0x9bcf, 0, 1, 0x01 },
379 { 0xd045, 2, 1, 0x01 },
380 { 0xd04f, 0, 8, 0x9a },
381 { 0xd050, 0, 1, 0x01 },
382 { 0xd051, 0, 8, 0x5a },
383 { 0xd052, 0, 1, 0x01 },
384 { 0xd053, 0, 8, 0x50 },
385 { 0xd054, 0, 8, 0x46 },
386 { 0x9bd7, 0, 8, 0x0a },
387 { 0x9bd8, 0, 8, 0x14 },
388 { 0x9bd9, 0, 8, 0x08 },
389 { 0x9bd0, 0, 8, 0xcc },
390 { 0x9be4, 0, 8, 0xa0 },
391 { 0x9bbd, 0, 8, 0x8e },
392 { 0x9be2, 0, 8, 0x4d },
393 { 0x9bee, 0, 1, 0x01 },
394};
395
396/* Microtune MT2060 tuner init
397 AF9013_TUNER_MT2060_2 = 147 */
398static struct regdesc tuner_init_mt2060_2[] = {
399 { 0x9bd5, 0, 8, 0x01 },
400 { 0x9bd6, 0, 8, 0x06 },
401 { 0x9bbe, 0, 8, 0x01 },
402 { 0xd1a0, 1, 1, 0x01 },
403 { 0xd000, 0, 1, 0x01 },
404 { 0xd000, 1, 1, 0x00 },
405 { 0xd001, 1, 1, 0x01 },
406 { 0xd001, 0, 1, 0x00 },
407 { 0xd001, 5, 1, 0x00 },
408 { 0xd002, 0, 5, 0x19 },
409 { 0xd003, 0, 5, 0x1a },
410 { 0xd004, 0, 5, 0x19 },
411 { 0xd005, 0, 5, 0x1a },
412 { 0xd00e, 0, 5, 0x10 },
413 { 0xd00f, 0, 3, 0x04 },
414 { 0xd00f, 3, 3, 0x05 },
415 { 0xd010, 0, 3, 0x04 },
416 { 0xd010, 3, 3, 0x05 },
417 { 0xd016, 4, 4, 0x03 },
418 { 0xd01f, 0, 6, 0x0a },
419 { 0xd020, 0, 6, 0x0a },
420 { 0xd015, 0, 8, 0x46 },
421 { 0xd016, 0, 1, 0x00 },
422 { 0xd044, 0, 8, 0x46 },
423 { 0xd045, 0, 1, 0x00 },
424 { 0xd008, 0, 8, 0x0f },
425 { 0xd009, 0, 2, 0x02 },
426 { 0xd006, 0, 8, 0x32 },
427 { 0xd007, 0, 2, 0x01 },
428 { 0xd00c, 0, 8, 0x36 },
429 { 0xd00d, 0, 2, 0x03 },
430 { 0xd00a, 0, 8, 0x35 },
431 { 0xd00b, 0, 2, 0x01 },
432 { 0x9bc7, 0, 8, 0x07 },
433 { 0x9bc8, 0, 8, 0x90 },
434 { 0x9bc3, 0, 8, 0x0f },
435 { 0x9bc4, 0, 8, 0x02 },
436 { 0x9bc5, 0, 8, 0x36 },
437 { 0x9bc6, 0, 8, 0x03 },
438 { 0x9bba, 0, 8, 0xc9 },
439 { 0x9bc9, 0, 8, 0x79 },
440 { 0xd011, 0, 8, 0x10 },
441 { 0xd012, 0, 2, 0x01 },
442 { 0xd013, 0, 8, 0x45 },
443 { 0xd014, 0, 2, 0x03 },
444 { 0xd040, 0, 8, 0x98 },
445 { 0xd041, 0, 2, 0x00 },
446 { 0xd042, 0, 8, 0xcf },
447 { 0xd043, 0, 2, 0x03 },
448 { 0xd045, 1, 1, 0x00 },
449 { 0x9bcf, 0, 8, 0x01 },
450 { 0xd045, 2, 1, 0x01 },
451 { 0xd04f, 0, 8, 0x9a },
452 { 0xd050, 0, 1, 0x01 },
453 { 0xd051, 0, 8, 0x5a },
454 { 0xd052, 0, 1, 0x01 },
455 { 0xd053, 0, 8, 0x96 },
456 { 0xd054, 0, 8, 0x46 },
457 { 0xd045, 7, 1, 0x00 },
458 { 0x9bd7, 0, 8, 0x0a },
459 { 0x9bd8, 0, 8, 0x14 },
460 { 0x9bd9, 0, 8, 0x08 },
461};
462
463/* MaxLinear MXL5003 tuner init
464 AF9013_TUNER_MXL5003D = 3 */
465static struct regdesc tuner_init_mxl5003d[] = {
466 { 0x9bd5, 0, 8, 0x01 },
467 { 0x9bd6, 0, 8, 0x09 },
468 { 0xd1a0, 1, 1, 0x01 },
469 { 0xd000, 0, 1, 0x01 },
470 { 0xd000, 1, 1, 0x00 },
471 { 0xd001, 1, 1, 0x01 },
472 { 0xd001, 0, 1, 0x00 },
473 { 0xd001, 5, 1, 0x00 },
474 { 0xd002, 0, 5, 0x19 },
475 { 0xd003, 0, 5, 0x1a },
476 { 0xd004, 0, 5, 0x19 },
477 { 0xd005, 0, 5, 0x1a },
478 { 0xd00e, 0, 5, 0x10 },
479 { 0xd00f, 0, 3, 0x04 },
480 { 0xd00f, 3, 3, 0x05 },
481 { 0xd010, 0, 3, 0x04 },
482 { 0xd010, 3, 3, 0x05 },
483 { 0xd016, 4, 4, 0x03 },
484 { 0xd01f, 0, 6, 0x0a },
485 { 0xd020, 0, 6, 0x0a },
486 { 0x9bda, 0, 8, 0x00 },
487 { 0x9be3, 0, 8, 0x00 },
488 { 0x9bfc, 0, 8, 0x0f },
489 { 0x9bf6, 0, 8, 0x01 },
490 { 0x9bbe, 0, 1, 0x01 },
491 { 0xd015, 0, 8, 0x33 },
492 { 0xd016, 0, 1, 0x00 },
493 { 0xd044, 0, 8, 0x40 },
494 { 0xd045, 0, 1, 0x00 },
495 { 0xd008, 0, 8, 0x0f },
496 { 0xd009, 0, 2, 0x02 },
497 { 0xd006, 0, 8, 0x6c },
498 { 0xd007, 0, 2, 0x00 },
499 { 0xd00c, 0, 8, 0x3d },
500 { 0xd00d, 0, 2, 0x00 },
501 { 0xd00a, 0, 8, 0x45 },
502 { 0xd00b, 0, 2, 0x01 },
503 { 0x9bc7, 0, 8, 0x07 },
504 { 0x9bc8, 0, 8, 0x52 },
505 { 0x9bc3, 0, 8, 0x0f },
506 { 0x9bc4, 0, 8, 0x02 },
507 { 0x9bc5, 0, 8, 0x3d },
508 { 0x9bc6, 0, 8, 0x00 },
509 { 0x9bba, 0, 8, 0xa2 },
510 { 0x9bc9, 0, 8, 0xa0 },
511 { 0xd011, 0, 8, 0x56 },
512 { 0xd012, 0, 2, 0x00 },
513 { 0xd013, 0, 8, 0x50 },
514 { 0xd014, 0, 2, 0x00 },
515 { 0xd040, 0, 8, 0x56 },
516 { 0xd041, 0, 2, 0x00 },
517 { 0xd042, 0, 8, 0x50 },
518 { 0xd043, 0, 2, 0x00 },
519 { 0xd045, 1, 1, 0x00 },
520 { 0x9bcf, 0, 8, 0x01 },
521 { 0xd045, 2, 1, 0x01 },
522 { 0xd04f, 0, 8, 0x9a },
523 { 0xd050, 0, 1, 0x01 },
524 { 0xd051, 0, 8, 0x5a },
525 { 0xd052, 0, 1, 0x01 },
526 { 0xd053, 0, 8, 0x50 },
527 { 0xd054, 0, 8, 0x46 },
528 { 0x9bd7, 0, 8, 0x0a },
529 { 0x9bd8, 0, 8, 0x14 },
530 { 0x9bd9, 0, 8, 0x08 },
531};
532
533/* MaxLinear MXL5005S & MXL5007T tuner init
534 AF9013_TUNER_MXL5005D = 13
535 AF9013_TUNER_MXL5005R = 30
536 AF9013_TUNER_MXL5007T = 177 */
537static struct regdesc tuner_init_mxl5005[] = {
538 { 0x9bd5, 0, 8, 0x01 },
539 { 0x9bd6, 0, 8, 0x07 },
540 { 0xd1a0, 1, 1, 0x01 },
541 { 0xd000, 0, 1, 0x01 },
542 { 0xd000, 1, 1, 0x00 },
543 { 0xd001, 1, 1, 0x01 },
544 { 0xd001, 0, 1, 0x00 },
545 { 0xd001, 5, 1, 0x00 },
546 { 0xd002, 0, 5, 0x19 },
547 { 0xd003, 0, 5, 0x1a },
548 { 0xd004, 0, 5, 0x19 },
549 { 0xd005, 0, 5, 0x1a },
550 { 0xd00e, 0, 5, 0x10 },
551 { 0xd00f, 0, 3, 0x04 },
552 { 0xd00f, 3, 3, 0x05 },
553 { 0xd010, 0, 3, 0x04 },
554 { 0xd010, 3, 3, 0x05 },
555 { 0xd016, 4, 4, 0x03 },
556 { 0xd01f, 0, 6, 0x0a },
557 { 0xd020, 0, 6, 0x0a },
558 { 0x9bda, 0, 8, 0x01 },
559 { 0x9be3, 0, 8, 0x01 },
560 { 0x9bbe, 0, 1, 0x01 },
561 { 0x9bcc, 0, 1, 0x01 },
562 { 0x9bb9, 0, 8, 0x00 },
563 { 0x9bcd, 0, 8, 0x28 },
564 { 0x9bff, 0, 8, 0x24 },
565 { 0xd015, 0, 8, 0x40 },
566 { 0xd016, 0, 1, 0x00 },
567 { 0xd044, 0, 8, 0x40 },
568 { 0xd045, 0, 1, 0x00 },
569 { 0xd008, 0, 8, 0x0f },
570 { 0xd009, 0, 2, 0x02 },
571 { 0xd006, 0, 8, 0x73 },
572 { 0xd007, 0, 2, 0x01 },
573 { 0xd00c, 0, 8, 0xfa },
574 { 0xd00d, 0, 2, 0x01 },
575 { 0xd00a, 0, 8, 0xff },
576 { 0xd00b, 0, 2, 0x01 },
577 { 0x9bc7, 0, 8, 0x23 },
578 { 0x9bc8, 0, 8, 0x55 },
579 { 0x9bc3, 0, 8, 0x01 },
580 { 0x9bc4, 0, 8, 0x02 },
581 { 0x9bc5, 0, 8, 0xfa },
582 { 0x9bc6, 0, 8, 0x01 },
583 { 0x9bba, 0, 8, 0xff },
584 { 0x9bc9, 0, 8, 0xff },
585 { 0x9bd3, 0, 8, 0x95 },
586 { 0xd011, 0, 8, 0x70 },
587 { 0xd012, 0, 2, 0x01 },
588 { 0xd013, 0, 8, 0xfb },
589 { 0xd014, 0, 2, 0x01 },
590 { 0xd040, 0, 8, 0x70 },
591 { 0xd041, 0, 2, 0x01 },
592 { 0xd042, 0, 8, 0xfb },
593 { 0xd043, 0, 2, 0x01 },
594 { 0xd045, 1, 1, 0x00 },
595 { 0x9bcf, 0, 1, 0x01 },
596 { 0xd045, 2, 1, 0x01 },
597 { 0xd04f, 0, 8, 0x9a },
598 { 0xd050, 0, 1, 0x01 },
599 { 0xd051, 0, 8, 0x5a },
600 { 0xd052, 0, 1, 0x01 },
601 { 0xd053, 0, 8, 0x50 },
602 { 0xd054, 0, 8, 0x46 },
603 { 0x9bd7, 0, 8, 0x0a },
604 { 0x9bd8, 0, 8, 0x14 },
605 { 0x9bd9, 0, 8, 0x08 },
606 { 0x9bd0, 0, 8, 0x93 },
607 { 0x9be4, 0, 8, 0xfe },
608 { 0x9bbd, 0, 8, 0x63 },
609 { 0x9be2, 0, 8, 0xfe },
610 { 0x9bee, 0, 1, 0x01 },
611};
612
613/* Quantek QT1010 tuner init
614 AF9013_TUNER_QT1010 = 134
615 AF9013_TUNER_QT1010A = 162 */
616static struct regdesc tuner_init_qt1010[] = {
617 { 0x9bd5, 0, 8, 0x01 },
618 { 0x9bd6, 0, 8, 0x09 },
619 { 0xd1a0, 1, 1, 0x01 },
620 { 0xd000, 0, 1, 0x01 },
621 { 0xd000, 1, 1, 0x00 },
622 { 0xd001, 1, 1, 0x01 },
623 { 0xd001, 0, 1, 0x00 },
624 { 0xd001, 5, 1, 0x00 },
625 { 0xd002, 0, 5, 0x19 },
626 { 0xd003, 0, 5, 0x1a },
627 { 0xd004, 0, 5, 0x19 },
628 { 0xd005, 0, 5, 0x1a },
629 { 0xd00e, 0, 5, 0x10 },
630 { 0xd00f, 0, 3, 0x04 },
631 { 0xd00f, 3, 3, 0x05 },
632 { 0xd010, 0, 3, 0x04 },
633 { 0xd010, 3, 3, 0x05 },
634 { 0xd016, 4, 4, 0x03 },
635 { 0xd01f, 0, 6, 0x0a },
636 { 0xd020, 0, 6, 0x0a },
637 { 0x9bda, 0, 8, 0x01 },
638 { 0x9be3, 0, 8, 0x01 },
639 { 0xd015, 0, 8, 0x46 },
640 { 0xd016, 0, 1, 0x00 },
641 { 0xd044, 0, 8, 0x46 },
642 { 0xd045, 0, 1, 0x00 },
643 { 0x9bbe, 0, 1, 0x01 },
644 { 0x9bcc, 0, 1, 0x01 },
645 { 0x9bb9, 0, 8, 0x00 },
646 { 0x9bcd, 0, 8, 0x28 },
647 { 0x9bff, 0, 8, 0x20 },
648 { 0xd008, 0, 8, 0x0f },
649 { 0xd009, 0, 2, 0x02 },
650 { 0xd006, 0, 8, 0x99 },
651 { 0xd007, 0, 2, 0x01 },
652 { 0xd00c, 0, 8, 0x0f },
653 { 0xd00d, 0, 2, 0x02 },
654 { 0xd00a, 0, 8, 0x50 },
655 { 0xd00b, 0, 2, 0x01 },
656 { 0x9bc7, 0, 8, 0x00 },
657 { 0x9bc8, 0, 8, 0x00 },
658 { 0x9bc3, 0, 8, 0x0f },
659 { 0x9bc4, 0, 8, 0x02 },
660 { 0x9bc5, 0, 8, 0x0f },
661 { 0x9bc6, 0, 8, 0x02 },
662 { 0x9bba, 0, 8, 0xc5 },
663 { 0x9bc9, 0, 8, 0xff },
664 { 0xd011, 0, 8, 0x58 },
665 { 0xd012, 0, 2, 0x02 },
666 { 0xd013, 0, 8, 0x89 },
667 { 0xd014, 0, 2, 0x01 },
668 { 0xd040, 0, 8, 0x58 },
669 { 0xd041, 0, 2, 0x02 },
670 { 0xd042, 0, 8, 0x89 },
671 { 0xd043, 0, 2, 0x01 },
672 { 0xd045, 1, 1, 0x00 },
673 { 0x9bcf, 0, 1, 0x01 },
674 { 0xd045, 2, 1, 0x01 },
675 { 0xd04f, 0, 8, 0x9a },
676 { 0xd050, 0, 1, 0x01 },
677 { 0xd051, 0, 8, 0x5a },
678 { 0xd052, 0, 1, 0x01 },
679 { 0xd053, 0, 8, 0x50 },
680 { 0xd054, 0, 8, 0x46 },
681 { 0x9bd7, 0, 8, 0x0a },
682 { 0x9bd8, 0, 8, 0x14 },
683 { 0x9bd9, 0, 8, 0x08 },
684 { 0x9bd0, 0, 8, 0xcd },
685 { 0x9be4, 0, 8, 0xbb },
686 { 0x9bbd, 0, 8, 0x93 },
687 { 0x9be2, 0, 8, 0x80 },
688 { 0x9bee, 0, 1, 0x01 },
689};
690
691/* Freescale MC44S803 tuner init
692 AF9013_TUNER_MC44S803 = 133 */
693static struct regdesc tuner_init_mc44s803[] = {
694 { 0x9bd5, 0, 8, 0x01 },
695 { 0x9bd6, 0, 8, 0x06 },
696 { 0xd1a0, 1, 1, 0x01 },
697 { 0xd000, 0, 1, 0x01 },
698 { 0xd000, 1, 1, 0x00 },
699 { 0xd001, 1, 1, 0x01 },
700 { 0xd001, 0, 1, 0x00 },
701 { 0xd001, 5, 1, 0x00 },
702 { 0xd002, 0, 5, 0x19 },
703 { 0xd003, 0, 5, 0x1a },
704 { 0xd004, 0, 5, 0x19 },
705 { 0xd005, 0, 5, 0x1a },
706 { 0xd00e, 0, 5, 0x10 },
707 { 0xd00f, 0, 3, 0x04 },
708 { 0xd00f, 3, 3, 0x05 },
709 { 0xd010, 0, 3, 0x04 },
710 { 0xd010, 3, 3, 0x05 },
711 { 0xd016, 4, 4, 0x03 },
712 { 0xd01f, 0, 6, 0x0a },
713 { 0xd020, 0, 6, 0x0a },
714 { 0x9bda, 0, 8, 0x00 },
715 { 0x9be3, 0, 8, 0x00 },
716 { 0x9bf6, 0, 8, 0x01 },
717 { 0x9bf8, 0, 8, 0x02 },
718 { 0x9bf9, 0, 8, 0x02 },
719 { 0x9bfc, 0, 8, 0x1f },
720 { 0x9bbe, 0, 1, 0x01 },
721 { 0x9bcc, 0, 1, 0x01 },
722 { 0x9bb9, 0, 8, 0x00 },
723 { 0x9bcd, 0, 8, 0x24 },
724 { 0x9bff, 0, 8, 0x24 },
725 { 0xd015, 0, 8, 0x46 },
726 { 0xd016, 0, 1, 0x00 },
727 { 0xd044, 0, 8, 0x46 },
728 { 0xd045, 0, 1, 0x00 },
729 { 0xd008, 0, 8, 0x01 },
730 { 0xd009, 0, 2, 0x02 },
731 { 0xd006, 0, 8, 0x7b },
732 { 0xd007, 0, 2, 0x00 },
733 { 0xd00c, 0, 8, 0x7c },
734 { 0xd00d, 0, 2, 0x02 },
735 { 0xd00a, 0, 8, 0xfe },
736 { 0xd00b, 0, 2, 0x01 },
737 { 0x9bc7, 0, 8, 0x08 },
738 { 0x9bc8, 0, 8, 0x9a },
739 { 0x9bc3, 0, 8, 0x01 },
740 { 0x9bc4, 0, 8, 0x02 },
741 { 0x9bc5, 0, 8, 0x7c },
742 { 0x9bc6, 0, 8, 0x02 },
743 { 0x9bba, 0, 8, 0xfc },
744 { 0x9bc9, 0, 8, 0xaa },
745 { 0xd011, 0, 8, 0x6b },
746 { 0xd012, 0, 2, 0x00 },
747 { 0xd013, 0, 8, 0x88 },
748 { 0xd014, 0, 2, 0x02 },
749 { 0xd040, 0, 8, 0x6b },
750 { 0xd041, 0, 2, 0x00 },
751 { 0xd042, 0, 8, 0x7c },
752 { 0xd043, 0, 2, 0x02 },
753 { 0xd045, 1, 1, 0x00 },
754 { 0x9bcf, 0, 1, 0x01 },
755 { 0xd045, 2, 1, 0x01 },
756 { 0xd04f, 0, 8, 0x9a },
757 { 0xd050, 0, 1, 0x01 },
758 { 0xd051, 0, 8, 0x5a },
759 { 0xd052, 0, 1, 0x01 },
760 { 0xd053, 0, 8, 0x50 },
761 { 0xd054, 0, 8, 0x46 },
762 { 0x9bd7, 0, 8, 0x0a },
763 { 0x9bd8, 0, 8, 0x14 },
764 { 0x9bd9, 0, 8, 0x08 },
765 { 0x9bd0, 0, 8, 0x9e },
766 { 0x9be4, 0, 8, 0xff },
767 { 0x9bbd, 0, 8, 0x9e },
768 { 0x9be2, 0, 8, 0x25 },
769 { 0x9bee, 0, 1, 0x01 },
770 { 0xd73b, 3, 1, 0x00 },
771};
772
773/* unknown, probably for tin can tuner, tuner init
774 AF9013_TUNER_UNKNOWN = 140 */
775static struct regdesc tuner_init_unknown[] = {
776 { 0x9bd5, 0, 8, 0x01 },
777 { 0x9bd6, 0, 8, 0x02 },
778 { 0xd1a0, 1, 1, 0x01 },
779 { 0xd000, 0, 1, 0x01 },
780 { 0xd000, 1, 1, 0x00 },
781 { 0xd001, 1, 1, 0x01 },
782 { 0xd001, 0, 1, 0x00 },
783 { 0xd001, 5, 1, 0x00 },
784 { 0xd002, 0, 5, 0x19 },
785 { 0xd003, 0, 5, 0x1a },
786 { 0xd004, 0, 5, 0x19 },
787 { 0xd005, 0, 5, 0x1a },
788 { 0xd00e, 0, 5, 0x10 },
789 { 0xd00f, 0, 3, 0x04 },
790 { 0xd00f, 3, 3, 0x05 },
791 { 0xd010, 0, 3, 0x04 },
792 { 0xd010, 3, 3, 0x05 },
793 { 0xd016, 4, 4, 0x03 },
794 { 0xd01f, 0, 6, 0x0a },
795 { 0xd020, 0, 6, 0x0a },
796 { 0x9bda, 0, 8, 0x01 },
797 { 0x9be3, 0, 8, 0x01 },
798 { 0xd1a0, 1, 1, 0x00 },
799 { 0x9bbe, 0, 1, 0x01 },
800 { 0x9bcc, 0, 1, 0x01 },
801 { 0x9bb9, 0, 8, 0x00 },
802 { 0x9bcd, 0, 8, 0x18 },
803 { 0x9bff, 0, 8, 0x2c },
804 { 0xd015, 0, 8, 0x46 },
805 { 0xd016, 0, 1, 0x00 },
806 { 0xd044, 0, 8, 0x46 },
807 { 0xd045, 0, 1, 0x00 },
808 { 0xd008, 0, 8, 0xdf },
809 { 0xd009, 0, 2, 0x02 },
810 { 0xd006, 0, 8, 0x44 },
811 { 0xd007, 0, 2, 0x01 },
812 { 0xd00c, 0, 8, 0x00 },
813 { 0xd00d, 0, 2, 0x02 },
814 { 0xd00a, 0, 8, 0xf6 },
815 { 0xd00b, 0, 2, 0x01 },
816 { 0x9bba, 0, 8, 0xf9 },
817 { 0x9bc8, 0, 8, 0xaa },
818 { 0x9bc3, 0, 8, 0xdf },
819 { 0x9bc4, 0, 8, 0x02 },
820 { 0x9bc5, 0, 8, 0x00 },
821 { 0x9bc6, 0, 8, 0x02 },
822 { 0x9bc9, 0, 8, 0xf0 },
823 { 0xd011, 0, 8, 0x3c },
824 { 0xd012, 0, 2, 0x01 },
825 { 0xd013, 0, 8, 0xf7 },
826 { 0xd014, 0, 2, 0x02 },
827 { 0xd040, 0, 8, 0x0b },
828 { 0xd041, 0, 2, 0x02 },
829 { 0xd042, 0, 8, 0x4d },
830 { 0xd043, 0, 2, 0x00 },
831 { 0xd045, 1, 1, 0x00 },
832 { 0x9bcf, 0, 1, 0x01 },
833 { 0xd045, 2, 1, 0x01 },
834 { 0xd04f, 0, 8, 0x9a },
835 { 0xd050, 0, 1, 0x01 },
836 { 0xd051, 0, 8, 0x5a },
837 { 0xd052, 0, 1, 0x01 },
838 { 0xd053, 0, 8, 0x50 },
839 { 0xd054, 0, 8, 0x46 },
840 { 0x9bd7, 0, 8, 0x0a },
841 { 0x9bd8, 0, 8, 0x14 },
842 { 0x9bd9, 0, 8, 0x08 },
843};
844
845/* NXP TDA18271 & TDA18218 tuner init
846 AF9013_TUNER_TDA18271 = 156
847 AF9013_TUNER_TDA18218 = 179 */
848static struct regdesc tuner_init_tda18271[] = {
849 { 0x9bd5, 0, 8, 0x01 },
850 { 0x9bd6, 0, 8, 0x04 },
851 { 0xd1a0, 1, 1, 0x01 },
852 { 0xd000, 0, 1, 0x01 },
853 { 0xd000, 1, 1, 0x00 },
854 { 0xd001, 1, 1, 0x01 },
855 { 0xd001, 0, 1, 0x00 },
856 { 0xd001, 5, 1, 0x00 },
857 { 0xd002, 0, 5, 0x19 },
858 { 0xd003, 0, 5, 0x1a },
859 { 0xd004, 0, 5, 0x19 },
860 { 0xd005, 0, 5, 0x1a },
861 { 0xd00e, 0, 5, 0x10 },
862 { 0xd00f, 0, 3, 0x04 },
863 { 0xd00f, 3, 3, 0x05 },
864 { 0xd010, 0, 3, 0x04 },
865 { 0xd010, 3, 3, 0x05 },
866 { 0xd016, 4, 4, 0x03 },
867 { 0xd01f, 0, 6, 0x0a },
868 { 0xd020, 0, 6, 0x0a },
869 { 0x9bda, 0, 8, 0x01 },
870 { 0x9be3, 0, 8, 0x01 },
871 { 0xd1a0, 1, 1, 0x00 },
872 { 0x9bbe, 0, 1, 0x01 },
873 { 0x9bcc, 0, 1, 0x01 },
874 { 0x9bb9, 0, 8, 0x00 },
875 { 0x9bcd, 0, 8, 0x18 },
876 { 0x9bff, 0, 8, 0x2c },
877 { 0xd015, 0, 8, 0x46 },
878 { 0xd016, 0, 1, 0x00 },
879 { 0xd044, 0, 8, 0x46 },
880 { 0xd045, 0, 1, 0x00 },
881 { 0xd008, 0, 8, 0xdf },
882 { 0xd009, 0, 2, 0x02 },
883 { 0xd006, 0, 8, 0x44 },
884 { 0xd007, 0, 2, 0x01 },
885 { 0xd00c, 0, 8, 0x00 },
886 { 0xd00d, 0, 2, 0x02 },
887 { 0xd00a, 0, 8, 0xf6 },
888 { 0xd00b, 0, 2, 0x01 },
889 { 0x9bba, 0, 8, 0xf9 },
890 { 0x9bc8, 0, 8, 0xaa },
891 { 0x9bc3, 0, 8, 0xdf },
892 { 0x9bc4, 0, 8, 0x02 },
893 { 0x9bc5, 0, 8, 0x00 },
894 { 0x9bc6, 0, 8, 0x02 },
895 { 0x9bc9, 0, 8, 0xf0 },
896 { 0xd011, 0, 8, 0x3c },
897 { 0xd012, 0, 2, 0x01 },
898 { 0xd013, 0, 8, 0xf7 },
899 { 0xd014, 0, 2, 0x02 },
900 { 0xd040, 0, 8, 0x0b },
901 { 0xd041, 0, 2, 0x02 },
902 { 0xd042, 0, 8, 0x4d },
903 { 0xd043, 0, 2, 0x00 },
904 { 0xd045, 1, 1, 0x00 },
905 { 0x9bcf, 0, 1, 0x01 },
906 { 0xd045, 2, 1, 0x01 },
907 { 0xd04f, 0, 8, 0x9a },
908 { 0xd050, 0, 1, 0x01 },
909 { 0xd051, 0, 8, 0x5a },
910 { 0xd052, 0, 1, 0x01 },
911 { 0xd053, 0, 8, 0x50 },
912 { 0xd054, 0, 8, 0x46 },
913 { 0x9bd7, 0, 8, 0x0a },
914 { 0x9bd8, 0, 8, 0x14 },
915 { 0x9bd9, 0, 8, 0x08 },
916 { 0x9bd0, 0, 8, 0xa8 },
917 { 0x9be4, 0, 8, 0x7f },
918 { 0x9bbd, 0, 8, 0xa8 },
919 { 0x9be2, 0, 8, 0x20 },
920 { 0x9bee, 0, 1, 0x01 },
921};
922
923#endif /* _AF9013_PRIV_ */
diff --git a/drivers/media/dvb/frontends/atbm8830.c b/drivers/media/dvb/frontends/atbm8830.c
new file mode 100644
index 00000000000..1539ea1f81a
--- /dev/null
+++ b/drivers/media/dvb/frontends/atbm8830.c
@@ -0,0 +1,509 @@
1/*
2 * Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
3 * ATBM8830, ATBM8831
4 *
5 * Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
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#include <asm/div64.h>
23#include "dvb_frontend.h"
24
25#include "atbm8830.h"
26#include "atbm8830_priv.h"
27
28#define dprintk(args...) \
29 do { \
30 if (debug) \
31 printk(KERN_DEBUG "atbm8830: " args); \
32 } while (0)
33
34static int debug;
35
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
38
39static int atbm8830_write_reg(struct atbm_state *priv, u16 reg, u8 data)
40{
41 int ret = 0;
42 u8 dev_addr;
43 u8 buf1[] = { reg >> 8, reg & 0xFF };
44 u8 buf2[] = { data };
45 struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 };
46 struct i2c_msg msg2 = { .flags = 0, .buf = buf2, .len = 1 };
47
48 dev_addr = priv->config->demod_address;
49 msg1.addr = dev_addr;
50 msg2.addr = dev_addr;
51
52 if (debug >= 2)
53 dprintk("%s: reg=0x%04X, data=0x%02X\n", __func__, reg, data);
54
55 ret = i2c_transfer(priv->i2c, &msg1, 1);
56 if (ret != 1)
57 return -EIO;
58
59 ret = i2c_transfer(priv->i2c, &msg2, 1);
60 return (ret != 1) ? -EIO : 0;
61}
62
63static int atbm8830_read_reg(struct atbm_state *priv, u16 reg, u8 *p_data)
64{
65 int ret;
66 u8 dev_addr;
67
68 u8 buf1[] = { reg >> 8, reg & 0xFF };
69 u8 buf2[] = { 0 };
70 struct i2c_msg msg1 = { .flags = 0, .buf = buf1, .len = 2 };
71 struct i2c_msg msg2 = { .flags = I2C_M_RD, .buf = buf2, .len = 1 };
72
73 dev_addr = priv->config->demod_address;
74 msg1.addr = dev_addr;
75 msg2.addr = dev_addr;
76
77 ret = i2c_transfer(priv->i2c, &msg1, 1);
78 if (ret != 1) {
79 dprintk("%s: error reg=0x%04x, ret=%i\n", __func__, reg, ret);
80 return -EIO;
81 }
82
83 ret = i2c_transfer(priv->i2c, &msg2, 1);
84 if (ret != 1)
85 return -EIO;
86
87 *p_data = buf2[0];
88 if (debug >= 2)
89 dprintk("%s: reg=0x%04X, data=0x%02X\n",
90 __func__, reg, buf2[0]);
91
92 return 0;
93}
94
95/* Lock register latch so that multi-register read is atomic */
96static inline int atbm8830_reglatch_lock(struct atbm_state *priv, int lock)
97{
98 return atbm8830_write_reg(priv, REG_READ_LATCH, lock ? 1 : 0);
99}
100
101static int set_osc_freq(struct atbm_state *priv, u32 freq /*in kHz*/)
102{
103 u32 val;
104 u64 t;
105
106 /* 0x100000 * freq / 30.4MHz */
107 t = (u64)0x100000 * freq;
108 do_div(t, 30400);
109 val = t;
110
111 atbm8830_write_reg(priv, REG_OSC_CLK, val);
112 atbm8830_write_reg(priv, REG_OSC_CLK + 1, val >> 8);
113 atbm8830_write_reg(priv, REG_OSC_CLK + 2, val >> 16);
114
115 return 0;
116}
117
118static int set_if_freq(struct atbm_state *priv, u32 freq /*in kHz*/)
119{
120
121 u32 fs = priv->config->osc_clk_freq;
122 u64 t;
123 u32 val;
124 u8 dat;
125
126 if (freq != 0) {
127 /* 2 * PI * (freq - fs) / fs * (2 ^ 22) */
128 t = (u64) 2 * 31416 * (freq - fs);
129 t <<= 22;
130 do_div(t, fs);
131 do_div(t, 1000);
132 val = t;
133
134 atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 1);
135 atbm8830_write_reg(priv, REG_IF_FREQ, val);
136 atbm8830_write_reg(priv, REG_IF_FREQ+1, val >> 8);
137 atbm8830_write_reg(priv, REG_IF_FREQ+2, val >> 16);
138
139 atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat);
140 dat &= 0xFC;
141 atbm8830_write_reg(priv, REG_ADC_CONFIG, dat);
142 } else {
143 /* Zero IF */
144 atbm8830_write_reg(priv, REG_TUNER_BASEBAND, 0);
145
146 atbm8830_read_reg(priv, REG_ADC_CONFIG, &dat);
147 dat &= 0xFC;
148 dat |= 0x02;
149 atbm8830_write_reg(priv, REG_ADC_CONFIG, dat);
150
151 if (priv->config->zif_swap_iq)
152 atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x03);
153 else
154 atbm8830_write_reg(priv, REG_SWAP_I_Q, 0x01);
155 }
156
157 return 0;
158}
159
160static int is_locked(struct atbm_state *priv, u8 *locked)
161{
162 u8 status;
163
164 atbm8830_read_reg(priv, REG_LOCK_STATUS, &status);
165
166 if (locked != NULL)
167 *locked = (status == 1);
168 return 0;
169}
170
171static int set_agc_config(struct atbm_state *priv,
172 u8 min, u8 max, u8 hold_loop)
173{
174 /* no effect if both min and max are zero */
175 if (!min && !max)
176 return 0;
177
178 atbm8830_write_reg(priv, REG_AGC_MIN, min);
179 atbm8830_write_reg(priv, REG_AGC_MAX, max);
180 atbm8830_write_reg(priv, REG_AGC_HOLD_LOOP, hold_loop);
181
182 return 0;
183}
184
185static int set_static_channel_mode(struct atbm_state *priv)
186{
187 int i;
188
189 for (i = 0; i < 5; i++)
190 atbm8830_write_reg(priv, 0x099B + i, 0x08);
191
192 atbm8830_write_reg(priv, 0x095B, 0x7F);
193 atbm8830_write_reg(priv, 0x09CB, 0x01);
194 atbm8830_write_reg(priv, 0x09CC, 0x7F);
195 atbm8830_write_reg(priv, 0x09CD, 0x7F);
196 atbm8830_write_reg(priv, 0x0E01, 0x20);
197
198 /* For single carrier */
199 atbm8830_write_reg(priv, 0x0B03, 0x0A);
200 atbm8830_write_reg(priv, 0x0935, 0x10);
201 atbm8830_write_reg(priv, 0x0936, 0x08);
202 atbm8830_write_reg(priv, 0x093E, 0x08);
203 atbm8830_write_reg(priv, 0x096E, 0x06);
204
205 /* frame_count_max0 */
206 atbm8830_write_reg(priv, 0x0B09, 0x00);
207 /* frame_count_max1 */
208 atbm8830_write_reg(priv, 0x0B0A, 0x08);
209
210 return 0;
211}
212
213static int set_ts_config(struct atbm_state *priv)
214{
215 const struct atbm8830_config *cfg = priv->config;
216
217 /*Set parallel/serial ts mode*/
218 atbm8830_write_reg(priv, REG_TS_SERIAL, cfg->serial_ts ? 1 : 0);
219 atbm8830_write_reg(priv, REG_TS_CLK_MODE, cfg->serial_ts ? 1 : 0);
220 /*Set ts sampling edge*/
221 atbm8830_write_reg(priv, REG_TS_SAMPLE_EDGE,
222 cfg->ts_sampling_edge ? 1 : 0);
223 /*Set ts clock freerun*/
224 atbm8830_write_reg(priv, REG_TS_CLK_FREERUN,
225 cfg->ts_clk_gated ? 0 : 1);
226
227 return 0;
228}
229
230static int atbm8830_init(struct dvb_frontend *fe)
231{
232 struct atbm_state *priv = fe->demodulator_priv;
233 const struct atbm8830_config *cfg = priv->config;
234
235 /*Set oscillator frequency*/
236 set_osc_freq(priv, cfg->osc_clk_freq);
237
238 /*Set IF frequency*/
239 set_if_freq(priv, cfg->if_freq);
240
241 /*Set AGC Config*/
242 set_agc_config(priv, cfg->agc_min, cfg->agc_max,
243 cfg->agc_hold_loop);
244
245 /*Set static channel mode*/
246 set_static_channel_mode(priv);
247
248 set_ts_config(priv);
249 /*Turn off DSP reset*/
250 atbm8830_write_reg(priv, 0x000A, 0);
251
252 /*SW version test*/
253 atbm8830_write_reg(priv, 0x020C, 11);
254
255 /* Run */
256 atbm8830_write_reg(priv, REG_DEMOD_RUN, 1);
257
258 return 0;
259}
260
261
262static void atbm8830_release(struct dvb_frontend *fe)
263{
264 struct atbm_state *state = fe->demodulator_priv;
265 dprintk("%s\n", __func__);
266
267 kfree(state);
268}
269
270static int atbm8830_set_fe(struct dvb_frontend *fe,
271 struct dvb_frontend_parameters *fe_params)
272{
273 struct atbm_state *priv = fe->demodulator_priv;
274 int i;
275 u8 locked = 0;
276 dprintk("%s\n", __func__);
277
278 /* set frequency */
279 if (fe->ops.tuner_ops.set_params) {
280 if (fe->ops.i2c_gate_ctrl)
281 fe->ops.i2c_gate_ctrl(fe, 1);
282 fe->ops.tuner_ops.set_params(fe, fe_params);
283 if (fe->ops.i2c_gate_ctrl)
284 fe->ops.i2c_gate_ctrl(fe, 0);
285 }
286
287 /* start auto lock */
288 for (i = 0; i < 10; i++) {
289 mdelay(100);
290 dprintk("Try %d\n", i);
291 is_locked(priv, &locked);
292 if (locked != 0) {
293 dprintk("ATBM8830 locked!\n");
294 break;
295 }
296 }
297
298 return 0;
299}
300
301static int atbm8830_get_fe(struct dvb_frontend *fe,
302 struct dvb_frontend_parameters *fe_params)
303{
304 dprintk("%s\n", __func__);
305
306 /* TODO: get real readings from device */
307 /* inversion status */
308 fe_params->inversion = INVERSION_OFF;
309
310 /* bandwidth */
311 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
312
313 fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
314 fe_params->u.ofdm.code_rate_LP = FEC_AUTO;
315
316 fe_params->u.ofdm.constellation = QAM_AUTO;
317
318 /* transmission mode */
319 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
320
321 /* guard interval */
322 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
323
324 /* hierarchy */
325 fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE;
326
327 return 0;
328}
329
330static int atbm8830_get_tune_settings(struct dvb_frontend *fe,
331 struct dvb_frontend_tune_settings *fesettings)
332{
333 fesettings->min_delay_ms = 0;
334 fesettings->step_size = 0;
335 fesettings->max_drift = 0;
336 return 0;
337}
338
339static int atbm8830_read_status(struct dvb_frontend *fe, fe_status_t *fe_status)
340{
341 struct atbm_state *priv = fe->demodulator_priv;
342 u8 locked = 0;
343 u8 agc_locked = 0;
344
345 dprintk("%s\n", __func__);
346 *fe_status = 0;
347
348 is_locked(priv, &locked);
349 if (locked) {
350 *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
351 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
352 }
353 dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
354
355 atbm8830_read_reg(priv, REG_AGC_LOCK, &agc_locked);
356 dprintk("AGC Lock: %d\n", agc_locked);
357
358 return 0;
359}
360
361static int atbm8830_read_ber(struct dvb_frontend *fe, u32 *ber)
362{
363 struct atbm_state *priv = fe->demodulator_priv;
364 u32 frame_err;
365 u8 t;
366
367 dprintk("%s\n", __func__);
368
369 atbm8830_reglatch_lock(priv, 1);
370
371 atbm8830_read_reg(priv, REG_FRAME_ERR_CNT + 1, &t);
372 frame_err = t & 0x7F;
373 frame_err <<= 8;
374 atbm8830_read_reg(priv, REG_FRAME_ERR_CNT, &t);
375 frame_err |= t;
376
377 atbm8830_reglatch_lock(priv, 0);
378
379 *ber = frame_err * 100 / 32767;
380
381 dprintk("%s: ber=0x%x\n", __func__, *ber);
382 return 0;
383}
384
385static int atbm8830_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
386{
387 struct atbm_state *priv = fe->demodulator_priv;
388 u32 pwm;
389 u8 t;
390
391 dprintk("%s\n", __func__);
392 atbm8830_reglatch_lock(priv, 1);
393
394 atbm8830_read_reg(priv, REG_AGC_PWM_VAL + 1, &t);
395 pwm = t & 0x03;
396 pwm <<= 8;
397 atbm8830_read_reg(priv, REG_AGC_PWM_VAL, &t);
398 pwm |= t;
399
400 atbm8830_reglatch_lock(priv, 0);
401
402 dprintk("AGC PWM = 0x%02X\n", pwm);
403 pwm = 0x400 - pwm;
404
405 *signal = pwm * 0x10000 / 0x400;
406
407 return 0;
408}
409
410static int atbm8830_read_snr(struct dvb_frontend *fe, u16 *snr)
411{
412 dprintk("%s\n", __func__);
413 *snr = 0;
414 return 0;
415}
416
417static int atbm8830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
418{
419 dprintk("%s\n", __func__);
420 *ucblocks = 0;
421 return 0;
422}
423
424static int atbm8830_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
425{
426 struct atbm_state *priv = fe->demodulator_priv;
427
428 return atbm8830_write_reg(priv, REG_I2C_GATE, enable ? 1 : 0);
429}
430
431static struct dvb_frontend_ops atbm8830_ops = {
432 .info = {
433 .name = "AltoBeam ATBM8830/8831 DMB-TH",
434 .type = FE_OFDM,
435 .frequency_min = 474000000,
436 .frequency_max = 858000000,
437 .frequency_stepsize = 10000,
438 .caps =
439 FE_CAN_FEC_AUTO |
440 FE_CAN_QAM_AUTO |
441 FE_CAN_TRANSMISSION_MODE_AUTO |
442 FE_CAN_GUARD_INTERVAL_AUTO
443 },
444
445 .release = atbm8830_release,
446
447 .init = atbm8830_init,
448 .sleep = NULL,
449 .write = NULL,
450 .i2c_gate_ctrl = atbm8830_i2c_gate_ctrl,
451
452 .set_frontend = atbm8830_set_fe,
453 .get_frontend = atbm8830_get_fe,
454 .get_tune_settings = atbm8830_get_tune_settings,
455
456 .read_status = atbm8830_read_status,
457 .read_ber = atbm8830_read_ber,
458 .read_signal_strength = atbm8830_read_signal_strength,
459 .read_snr = atbm8830_read_snr,
460 .read_ucblocks = atbm8830_read_ucblocks,
461};
462
463struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
464 struct i2c_adapter *i2c)
465{
466 struct atbm_state *priv = NULL;
467 u8 data = 0;
468
469 dprintk("%s()\n", __func__);
470
471 if (config == NULL || i2c == NULL)
472 return NULL;
473
474 priv = kzalloc(sizeof(struct atbm_state), GFP_KERNEL);
475 if (priv == NULL)
476 goto error_out;
477
478 priv->config = config;
479 priv->i2c = i2c;
480
481 /* check if the demod is there */
482 if (atbm8830_read_reg(priv, REG_CHIP_ID, &data) != 0) {
483 dprintk("%s atbm8830/8831 not found at i2c addr 0x%02X\n",
484 __func__, priv->config->demod_address);
485 goto error_out;
486 }
487 dprintk("atbm8830 chip id: 0x%02X\n", data);
488
489 memcpy(&priv->frontend.ops, &atbm8830_ops,
490 sizeof(struct dvb_frontend_ops));
491 priv->frontend.demodulator_priv = priv;
492
493 atbm8830_init(&priv->frontend);
494
495 atbm8830_i2c_gate_ctrl(&priv->frontend, 1);
496
497 return &priv->frontend;
498
499error_out:
500 dprintk("%s() error_out\n", __func__);
501 kfree(priv);
502 return NULL;
503
504}
505EXPORT_SYMBOL(atbm8830_attach);
506
507MODULE_DESCRIPTION("AltoBeam ATBM8830/8831 GB20600 demodulator driver");
508MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
509MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/atbm8830.h b/drivers/media/dvb/frontends/atbm8830.h
new file mode 100644
index 00000000000..024273374bd
--- /dev/null
+++ b/drivers/media/dvb/frontends/atbm8830.h
@@ -0,0 +1,76 @@
1/*
2 * Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
3 * ATBM8830, ATBM8831
4 *
5 * Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
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#ifndef __ATBM8830_H__
23#define __ATBM8830_H__
24
25#include <linux/dvb/frontend.h>
26#include <linux/i2c.h>
27
28#define ATBM8830_PROD_8830 0
29#define ATBM8830_PROD_8831 1
30
31struct atbm8830_config {
32
33 /* product type */
34 u8 prod;
35
36 /* the demodulator's i2c address */
37 u8 demod_address;
38
39 /* parallel or serial transport stream */
40 u8 serial_ts;
41
42 /* transport stream clock output only when receiving valid stream */
43 u8 ts_clk_gated;
44
45 /* Decoder sample TS data at rising edge of clock */
46 u8 ts_sampling_edge;
47
48 /* Oscillator clock frequency */
49 u32 osc_clk_freq; /* in kHz */
50
51 /* IF frequency */
52 u32 if_freq; /* in kHz */
53
54 /* Swap I/Q for zero IF */
55 u8 zif_swap_iq;
56
57 /* Tuner AGC settings */
58 u8 agc_min;
59 u8 agc_max;
60 u8 agc_hold_loop;
61};
62
63#if defined(CONFIG_DVB_ATBM8830) || \
64 (defined(CONFIG_DVB_ATBM8830_MODULE) && defined(MODULE))
65extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
66 struct i2c_adapter *i2c);
67#else
68static inline
69struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
70 struct i2c_adapter *i2c) {
71 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
72 return NULL;
73}
74#endif /* CONFIG_DVB_ATBM8830 */
75
76#endif /* __ATBM8830_H__ */
diff --git a/drivers/media/dvb/frontends/atbm8830_priv.h b/drivers/media/dvb/frontends/atbm8830_priv.h
new file mode 100644
index 00000000000..d460058d497
--- /dev/null
+++ b/drivers/media/dvb/frontends/atbm8830_priv.h
@@ -0,0 +1,75 @@
1/*
2 * Support for AltoBeam GB20600 (a.k.a DMB-TH) demodulator
3 * ATBM8830, ATBM8831
4 *
5 * Copyright (C) 2009 David T.L. Wong <davidtlwong@gmail.com>
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#ifndef __ATBM8830_PRIV_H
23#define __ATBM8830_PRIV_H
24
25struct atbm_state {
26 struct i2c_adapter *i2c;
27 /* configuration settings */
28 const struct atbm8830_config *config;
29 struct dvb_frontend frontend;
30};
31
32#define REG_CHIP_ID 0x0000
33#define REG_TUNER_BASEBAND 0x0001
34#define REG_DEMOD_RUN 0x0004
35#define REG_DSP_RESET 0x0005
36#define REG_RAM_RESET 0x0006
37#define REG_ADC_RESET 0x0007
38#define REG_TSPORT_RESET 0x0008
39#define REG_BLKERR_POL 0x000C
40#define REG_I2C_GATE 0x0103
41#define REG_TS_SAMPLE_EDGE 0x0301
42#define REG_TS_PKT_LEN_204 0x0302
43#define REG_TS_PKT_LEN_AUTO 0x0303
44#define REG_TS_SERIAL 0x0305
45#define REG_TS_CLK_FREERUN 0x0306
46#define REG_TS_VALID_MODE 0x0307
47#define REG_TS_CLK_MODE 0x030B /* 1 for serial, 0 for parallel */
48
49#define REG_TS_ERRBIT_USE 0x030C
50#define REG_LOCK_STATUS 0x030D
51#define REG_ADC_CONFIG 0x0602
52#define REG_CARRIER_OFFSET 0x0827 /* 0x0827-0x0829 little endian */
53#define REG_DETECTED_PN_MODE 0x082D
54#define REG_READ_LATCH 0x084D
55#define REG_IF_FREQ 0x0A00 /* 0x0A00-0x0A02 little endian */
56#define REG_OSC_CLK 0x0A03 /* 0x0A03-0x0A05 little endian */
57#define REG_BYPASS_CCI 0x0A06
58#define REG_ANALOG_LUMA_DETECTED 0x0A25
59#define REG_ANALOG_AUDIO_DETECTED 0x0A26
60#define REG_ANALOG_CHROMA_DETECTED 0x0A39
61#define REG_FRAME_ERR_CNT 0x0B04
62#define REG_USE_EXT_ADC 0x0C00
63#define REG_SWAP_I_Q 0x0C01
64#define REG_TPS_MANUAL 0x0D01
65#define REG_TPS_CONFIG 0x0D02
66#define REG_BYPASS_DEINTERLEAVER 0x0E00
67#define REG_AGC_TARGET 0x1003 /* 0x1003-0x1005 little endian */
68#define REG_AGC_MIN 0x1020
69#define REG_AGC_MAX 0x1023
70#define REG_AGC_LOCK 0x1027
71#define REG_AGC_PWM_VAL 0x1028 /* 0x1028-0x1029 little endian */
72#define REG_AGC_HOLD_LOOP 0x1031
73
74#endif
75
diff --git a/drivers/media/dvb/frontends/au8522.h b/drivers/media/dvb/frontends/au8522.h
new file mode 100644
index 00000000000..565dcf31af5
--- /dev/null
+++ b/drivers/media/dvb/frontends/au8522.h
@@ -0,0 +1,98 @@
1/*
2 Auvitek AU8522 QAM/8VSB demodulator driver
3
4 Copyright (C) 2008 Steven Toth <stoth@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 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 __AU8522_H__
23#define __AU8522_H__
24
25#include <linux/dvb/frontend.h>
26
27enum au8522_if_freq {
28 AU8522_IF_6MHZ = 0,
29 AU8522_IF_4MHZ,
30 AU8522_IF_3_25MHZ,
31};
32
33struct au8522_led_config {
34 u16 vsb8_strong;
35 u16 qam64_strong;
36 u16 qam256_strong;
37
38 u16 gpio_output;
39 /* unset hi bits, set low bits */
40 u16 gpio_output_enable;
41 u16 gpio_output_disable;
42
43 u16 gpio_leds;
44 u8 *led_states;
45 unsigned int num_led_states;
46};
47
48struct au8522_config {
49 /* the demodulator's i2c address */
50 u8 demod_address;
51
52 /* Return lock status based on tuner lock, or demod lock */
53#define AU8522_TUNERLOCKING 0
54#define AU8522_DEMODLOCKING 1
55 u8 status_mode;
56
57 struct au8522_led_config *led_cfg;
58
59 enum au8522_if_freq vsb_if;
60 enum au8522_if_freq qam_if;
61};
62
63#if defined(CONFIG_DVB_AU8522) || \
64 (defined(CONFIG_DVB_AU8522_MODULE) && defined(MODULE))
65extern struct dvb_frontend *au8522_attach(const struct au8522_config *config,
66 struct i2c_adapter *i2c);
67#else
68static inline
69struct dvb_frontend *au8522_attach(const struct au8522_config *config,
70 struct i2c_adapter *i2c)
71{
72 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
73 return NULL;
74}
75#endif /* CONFIG_DVB_AU8522 */
76
77/* Other modes may need to be added later */
78enum au8522_video_input {
79 AU8522_COMPOSITE_CH1 = 1,
80 AU8522_COMPOSITE_CH2,
81 AU8522_COMPOSITE_CH3,
82 AU8522_COMPOSITE_CH4,
83 AU8522_COMPOSITE_CH4_SIF,
84 AU8522_SVIDEO_CH13,
85 AU8522_SVIDEO_CH24,
86};
87
88enum au8522_audio_input {
89 AU8522_AUDIO_NONE,
90 AU8522_AUDIO_SIF,
91};
92
93#endif /* __AU8522_H__ */
94
95/*
96 * Local variables:
97 * c-basic-offset: 8
98 */
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
new file mode 100644
index 00000000000..2b248c12f40
--- /dev/null
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -0,0 +1,853 @@
1/*
2 * Auvitek AU8522 QAM/8VSB demodulator driver and video decoder
3 *
4 * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
5 * Copyright (C) 2005-2008 Auvitek International, Ltd.
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
9 * As published by the Free Software Foundation; either version 2
10 * of the License, or (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., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 */
22
23/* Developer notes:
24 *
25 * VBI support is not yet working
26 * Enough is implemented here for CVBS and S-Video inputs, but the actual
27 * analog demodulator code isn't implemented (not needed for xc5000 since it
28 * has its own demodulator and outputs CVBS)
29 *
30 */
31
32#include <linux/kernel.h>
33#include <linux/slab.h>
34#include <linux/videodev2.h>
35#include <linux/i2c.h>
36#include <linux/delay.h>
37#include <media/v4l2-common.h>
38#include <media/v4l2-chip-ident.h>
39#include <media/v4l2-device.h>
40#include "au8522.h"
41#include "au8522_priv.h"
42
43MODULE_AUTHOR("Devin Heitmueller");
44MODULE_LICENSE("GPL");
45
46static int au8522_analog_debug;
47
48
49module_param_named(analog_debug, au8522_analog_debug, int, 0644);
50
51MODULE_PARM_DESC(analog_debug,
52 "Analog debugging messages [0=Off (default) 1=On]");
53
54struct au8522_register_config {
55 u16 reg_name;
56 u8 reg_val[8];
57};
58
59
60/* Video Decoder Filter Coefficients
61 The values are as follows from left to right
62 0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13"
63*/
64static const struct au8522_register_config filter_coef[] = {
65 {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} },
66 {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} },
67 {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} },
68 {AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00} },
69 {AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00} },
70 {AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00} },
71 {AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00} },
72 {AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00} },
73 {AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00} },
74 {AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40} },
75 {AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09} },
76 {AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38} },
77 {AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff} },
78 {AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7} },
79 {AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf} },
80 {AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06} },
81 {AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30} },
82 {AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01} },
83 {AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd} },
84 {AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf} },
85 {AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7} },
86 {AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb} },
87 {AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0} },
88 {AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f} },
89 {AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8} },
90 {AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb} },
91 {AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5} },
92 {AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e} },
93 {AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15} },
94 {AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34} },
95
96};
97#define NUM_FILTER_COEF (sizeof(filter_coef)\
98 / sizeof(struct au8522_register_config))
99
100
101/* Registers 0x060b through 0x0652 are the LP Filter coefficients
102 The values are as follows from left to right
103 0="SIF" 1="ATVRF/ATVRF13"
104 Note: the "ATVRF/ATVRF13" mode has never been tested
105*/
106static const struct au8522_register_config lpfilter_coef[] = {
107 {0x060b, {0x21, 0x0b} },
108 {0x060c, {0xad, 0xad} },
109 {0x060d, {0x70, 0xf0} },
110 {0x060e, {0xea, 0xe9} },
111 {0x060f, {0xdd, 0xdd} },
112 {0x0610, {0x08, 0x64} },
113 {0x0611, {0x60, 0x60} },
114 {0x0612, {0xf8, 0xb2} },
115 {0x0613, {0x01, 0x02} },
116 {0x0614, {0xe4, 0xb4} },
117 {0x0615, {0x19, 0x02} },
118 {0x0616, {0xae, 0x2e} },
119 {0x0617, {0xee, 0xc5} },
120 {0x0618, {0x56, 0x56} },
121 {0x0619, {0x30, 0x58} },
122 {0x061a, {0xf9, 0xf8} },
123 {0x061b, {0x24, 0x64} },
124 {0x061c, {0x07, 0x07} },
125 {0x061d, {0x30, 0x30} },
126 {0x061e, {0xa9, 0xed} },
127 {0x061f, {0x09, 0x0b} },
128 {0x0620, {0x42, 0xc2} },
129 {0x0621, {0x1d, 0x2a} },
130 {0x0622, {0xd6, 0x56} },
131 {0x0623, {0x95, 0x8b} },
132 {0x0624, {0x2b, 0x2b} },
133 {0x0625, {0x30, 0x24} },
134 {0x0626, {0x3e, 0x3e} },
135 {0x0627, {0x62, 0xe2} },
136 {0x0628, {0xe9, 0xf5} },
137 {0x0629, {0x99, 0x19} },
138 {0x062a, {0xd4, 0x11} },
139 {0x062b, {0x03, 0x04} },
140 {0x062c, {0xb5, 0x85} },
141 {0x062d, {0x1e, 0x20} },
142 {0x062e, {0x2a, 0xea} },
143 {0x062f, {0xd7, 0xd2} },
144 {0x0630, {0x15, 0x15} },
145 {0x0631, {0xa3, 0xa9} },
146 {0x0632, {0x1f, 0x1f} },
147 {0x0633, {0xf9, 0xd1} },
148 {0x0634, {0xc0, 0xc3} },
149 {0x0635, {0x4d, 0x8d} },
150 {0x0636, {0x21, 0x31} },
151 {0x0637, {0x83, 0x83} },
152 {0x0638, {0x08, 0x8c} },
153 {0x0639, {0x19, 0x19} },
154 {0x063a, {0x45, 0xa5} },
155 {0x063b, {0xef, 0xec} },
156 {0x063c, {0x8a, 0x8a} },
157 {0x063d, {0xf4, 0xf6} },
158 {0x063e, {0x8f, 0x8f} },
159 {0x063f, {0x44, 0x0c} },
160 {0x0640, {0xef, 0xf0} },
161 {0x0641, {0x66, 0x66} },
162 {0x0642, {0xcc, 0xd2} },
163 {0x0643, {0x41, 0x41} },
164 {0x0644, {0x63, 0x93} },
165 {0x0645, {0x8e, 0x8e} },
166 {0x0646, {0xa2, 0x42} },
167 {0x0647, {0x7b, 0x7b} },
168 {0x0648, {0x04, 0x04} },
169 {0x0649, {0x00, 0x00} },
170 {0x064a, {0x40, 0x40} },
171 {0x064b, {0x8c, 0x98} },
172 {0x064c, {0x00, 0x00} },
173 {0x064d, {0x63, 0xc3} },
174 {0x064e, {0x04, 0x04} },
175 {0x064f, {0x20, 0x20} },
176 {0x0650, {0x00, 0x00} },
177 {0x0651, {0x40, 0x40} },
178 {0x0652, {0x01, 0x01} },
179};
180#define NUM_LPFILTER_COEF (sizeof(lpfilter_coef)\
181 / sizeof(struct au8522_register_config))
182
183static inline struct au8522_state *to_state(struct v4l2_subdev *sd)
184{
185 return container_of(sd, struct au8522_state, sd);
186}
187
188static void setup_vbi(struct au8522_state *state, int aud_input)
189{
190 int i;
191
192 /* These are set to zero regardless of what mode we're in */
193 au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, 0x00);
194 au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_L_REG018H, 0x00);
195 au8522_writereg(state, AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H, 0x00);
196 au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH, 0x00);
197 au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH, 0x00);
198 au8522_writereg(state, AU8522_TVDEC_VBI_USER_THRESH1_REG01CH, 0x00);
199 au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00);
200 au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00);
201 au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00);
202 au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H,
203 0x00);
204 au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H,
205 0x00);
206 au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H,
207 0x00);
208
209 /* Setup the VBI registers */
210 for (i = 0x30; i < 0x60; i++)
211 au8522_writereg(state, i, 0x40);
212
213 /* For some reason, every register is 0x40 except register 0x44
214 (confirmed via the HVR-950q USB capture) */
215 au8522_writereg(state, 0x44, 0x60);
216
217 /* Enable VBI (we always do this regardless of whether the user is
218 viewing closed caption info) */
219 au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H,
220 AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON);
221
222}
223
224static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
225{
226 int i;
227 int filter_coef_type;
228
229 /* Provide reasonable defaults for picture tuning values */
230 au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07);
231 au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed);
232 state->brightness = 0xed - 128;
233 au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79);
234 state->contrast = 0x79;
235 au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80);
236 au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80);
237 state->saturation = 0x80;
238 au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
239 au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
240 state->hue = 0x00;
241
242 /* Other decoder registers */
243 au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
244
245 if (input_mode == 0x23) {
246 /* S-Video input mapping */
247 au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04);
248 } else {
249 /* All other modes (CVBS/ATVRF etc.) */
250 au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00);
251 }
252
253 au8522_writereg(state, AU8522_TVDEC_PGA_REG012H,
254 AU8522_TVDEC_PGA_REG012H_CVBS);
255 au8522_writereg(state, AU8522_TVDEC_COMB_MODE_REG015H,
256 AU8522_TVDEC_COMB_MODE_REG015H_CVBS);
257 au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H,
258 AU8522_TVDED_DBG_MODE_REG060H_CVBS);
259 au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
260 AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13);
261 au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
262 AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13);
263 au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H,
264 AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS);
265 au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H,
266 AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS);
267 au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR1_REG065H,
268 AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS);
269 au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR2_REG066H,
270 AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS);
271 au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR3_REG067H,
272 AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS);
273 au8522_writereg(state, AU8522_TVDEC_COMB_NOTCH_THR_REG068H,
274 AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS);
275 au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR1_REG069H,
276 AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS);
277 au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR2_REG06AH,
278 AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
279 au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
280 AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
281 if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
282 input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
283 au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
284 AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO);
285 au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
286 AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_SVIDEO);
287 } else {
288 au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
289 AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
290 au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
291 AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
292 }
293 au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH,
294 AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS);
295 au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH,
296 AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS);
297 au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H,
298 AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS);
299 au8522_writereg(state, AU8522_REG071H, AU8522_REG071H_CVBS);
300 au8522_writereg(state, AU8522_REG072H, AU8522_REG072H_CVBS);
301 au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H,
302 AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS);
303 au8522_writereg(state, AU8522_REG074H, AU8522_REG074H_CVBS);
304 au8522_writereg(state, AU8522_REG075H, AU8522_REG075H_CVBS);
305 au8522_writereg(state, AU8522_TVDEC_DCAGC_CTRL_REG077H,
306 AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS);
307 au8522_writereg(state, AU8522_TVDEC_PIC_START_ADJ_REG078H,
308 AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS);
309 au8522_writereg(state, AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H,
310 AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS);
311 au8522_writereg(state, AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH,
312 AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS);
313 au8522_writereg(state, AU8522_TVDEC_INTRP_CTRL_REG07BH,
314 AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS);
315 au8522_writereg(state, AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H,
316 AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS);
317 au8522_writereg(state, AU8522_TOREGAAGC_REG0E5H,
318 AU8522_TOREGAAGC_REG0E5H_CVBS);
319 au8522_writereg(state, AU8522_REG016H, AU8522_REG016H_CVBS);
320
321 setup_vbi(state, 0);
322
323 if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
324 input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
325 /* Despite what the table says, for the HVR-950q we still need
326 to be in CVBS mode for the S-Video input (reason unknown). */
327 /* filter_coef_type = 3; */
328 filter_coef_type = 5;
329 } else {
330 filter_coef_type = 5;
331 }
332
333 /* Load the Video Decoder Filter Coefficients */
334 for (i = 0; i < NUM_FILTER_COEF; i++) {
335 au8522_writereg(state, filter_coef[i].reg_name,
336 filter_coef[i].reg_val[filter_coef_type]);
337 }
338
339 /* It's not clear what these registers are for, but they are always
340 set to the same value regardless of what mode we're in */
341 au8522_writereg(state, AU8522_REG42EH, 0x87);
342 au8522_writereg(state, AU8522_REG42FH, 0xa2);
343 au8522_writereg(state, AU8522_REG430H, 0xbf);
344 au8522_writereg(state, AU8522_REG431H, 0xcb);
345 au8522_writereg(state, AU8522_REG432H, 0xa1);
346 au8522_writereg(state, AU8522_REG433H, 0x41);
347 au8522_writereg(state, AU8522_REG434H, 0x88);
348 au8522_writereg(state, AU8522_REG435H, 0xc2);
349 au8522_writereg(state, AU8522_REG436H, 0x3c);
350}
351
352static void au8522_setup_cvbs_mode(struct au8522_state *state)
353{
354 /* here we're going to try the pre-programmed route */
355 au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
356 AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
357
358 /* PGA in automatic mode */
359 au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
360
361 /* Enable clamping control */
362 au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
363
364 au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
365 AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
366
367 setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
368
369 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
370 AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
371}
372
373static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
374{
375 /* here we're going to try the pre-programmed route */
376 au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
377 AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
378
379 /* It's not clear why we have to have the PGA in automatic mode while
380 enabling clamp control, but it's what Windows does */
381 au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
382
383 /* Enable clamping control */
384 au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
385
386 /* Disable automatic PGA (since the CVBS is coming from the tuner) */
387 au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
388
389 /* Set input mode to CVBS on channel 4 with SIF audio input enabled */
390 au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
391 AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
392
393 setup_decoder_defaults(state,
394 AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
395
396 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
397 AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
398}
399
400static void au8522_setup_svideo_mode(struct au8522_state *state)
401{
402 au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
403 AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO);
404
405 /* Set input to Y on Channe1, C on Channel 3 */
406 au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
407 AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
408
409 /* PGA in automatic mode */
410 au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
411
412 /* Enable clamping control */
413 au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
414
415 setup_decoder_defaults(state,
416 AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
417
418 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
419 AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
420}
421
422/* ----------------------------------------------------------------------- */
423
424static void disable_audio_input(struct au8522_state *state)
425{
426 au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
427 au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
428 au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
429
430 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04);
431 au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02);
432
433 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
434 AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO);
435}
436
437/* 0=disable, 1=SIF */
438static void set_audio_input(struct au8522_state *state, int aud_input)
439{
440 int i;
441
442 /* Note that this function needs to be used in conjunction with setting
443 the input routing via register 0x81 */
444
445 if (aud_input == AU8522_AUDIO_NONE) {
446 disable_audio_input(state);
447 return;
448 }
449
450 if (aud_input != AU8522_AUDIO_SIF) {
451 /* The caller asked for a mode we don't currently support */
452 printk(KERN_ERR "Unsupported audio mode requested! mode=%d\n",
453 aud_input);
454 return;
455 }
456
457 /* Load the Audio Decoder Filter Coefficients */
458 for (i = 0; i < NUM_LPFILTER_COEF; i++) {
459 au8522_writereg(state, lpfilter_coef[i].reg_name,
460 lpfilter_coef[i].reg_val[0]);
461 }
462
463 /* Setup audio */
464 au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
465 au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
466 au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
467 au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
468 au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
469 msleep(150);
470 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00);
471 msleep(1);
472 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d);
473 msleep(50);
474 au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
475 au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
476 au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0xff);
477 msleep(80);
478 au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
479 au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
480 au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
481 au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x82);
482 msleep(70);
483 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09);
484 au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
485 au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0xc2);
486}
487
488/* ----------------------------------------------------------------------- */
489
490static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
491{
492 struct au8522_state *state = to_state(sd);
493
494 switch (ctrl->id) {
495 case V4L2_CID_BRIGHTNESS:
496 state->brightness = ctrl->value;
497 au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH,
498 ctrl->value - 128);
499 break;
500 case V4L2_CID_CONTRAST:
501 state->contrast = ctrl->value;
502 au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH,
503 ctrl->value);
504 break;
505 case V4L2_CID_SATURATION:
506 state->saturation = ctrl->value;
507 au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH,
508 ctrl->value);
509 au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH,
510 ctrl->value);
511 break;
512 case V4L2_CID_HUE:
513 state->hue = ctrl->value;
514 au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH,
515 ctrl->value >> 8);
516 au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH,
517 ctrl->value & 0xFF);
518 break;
519 case V4L2_CID_AUDIO_VOLUME:
520 case V4L2_CID_AUDIO_BASS:
521 case V4L2_CID_AUDIO_TREBLE:
522 case V4L2_CID_AUDIO_BALANCE:
523 case V4L2_CID_AUDIO_MUTE:
524 /* Not yet implemented */
525 default:
526 return -EINVAL;
527 }
528
529 return 0;
530}
531
532static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
533{
534 struct au8522_state *state = to_state(sd);
535
536 /* Note that we are using values cached in the state structure instead
537 of reading the registers due to issues with i2c reads not working
538 properly/consistently yet on the HVR-950q */
539
540 switch (ctrl->id) {
541 case V4L2_CID_BRIGHTNESS:
542 ctrl->value = state->brightness;
543 break;
544 case V4L2_CID_CONTRAST:
545 ctrl->value = state->contrast;
546 break;
547 case V4L2_CID_SATURATION:
548 ctrl->value = state->saturation;
549 break;
550 case V4L2_CID_HUE:
551 ctrl->value = state->hue;
552 break;
553 case V4L2_CID_AUDIO_VOLUME:
554 case V4L2_CID_AUDIO_BASS:
555 case V4L2_CID_AUDIO_TREBLE:
556 case V4L2_CID_AUDIO_BALANCE:
557 case V4L2_CID_AUDIO_MUTE:
558 /* Not yet supported */
559 default:
560 return -EINVAL;
561 }
562
563 return 0;
564}
565
566/* ----------------------------------------------------------------------- */
567
568#ifdef CONFIG_VIDEO_ADV_DEBUG
569static int au8522_g_register(struct v4l2_subdev *sd,
570 struct v4l2_dbg_register *reg)
571{
572 struct i2c_client *client = v4l2_get_subdevdata(sd);
573 struct au8522_state *state = to_state(sd);
574
575 if (!v4l2_chip_match_i2c_client(client, &reg->match))
576 return -EINVAL;
577 if (!capable(CAP_SYS_ADMIN))
578 return -EPERM;
579 reg->val = au8522_readreg(state, reg->reg & 0xffff);
580 return 0;
581}
582
583static int au8522_s_register(struct v4l2_subdev *sd,
584 struct v4l2_dbg_register *reg)
585{
586 struct i2c_client *client = v4l2_get_subdevdata(sd);
587 struct au8522_state *state = to_state(sd);
588
589 if (!v4l2_chip_match_i2c_client(client, &reg->match))
590 return -EINVAL;
591 if (!capable(CAP_SYS_ADMIN))
592 return -EPERM;
593 au8522_writereg(state, reg->reg, reg->val & 0xff);
594 return 0;
595}
596#endif
597
598static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
599{
600 struct au8522_state *state = to_state(sd);
601
602 if (enable) {
603 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
604 0x01);
605 msleep(1);
606 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
607 AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
608 } else {
609 /* This does not completely power down the device
610 (it only reduces it from around 140ma to 80ma) */
611 au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
612 1 << 5);
613 }
614 return 0;
615}
616
617static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
618{
619 switch (qc->id) {
620 case V4L2_CID_CONTRAST:
621 return v4l2_ctrl_query_fill(qc, 0, 255, 1,
622 AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
623 case V4L2_CID_BRIGHTNESS:
624 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 109);
625 case V4L2_CID_SATURATION:
626 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
627 case V4L2_CID_HUE:
628 return v4l2_ctrl_query_fill(qc, -32768, 32768, 1, 0);
629 default:
630 break;
631 }
632
633 qc->type = 0;
634 return -EINVAL;
635}
636
637static int au8522_reset(struct v4l2_subdev *sd, u32 val)
638{
639 struct au8522_state *state = to_state(sd);
640
641 state->operational_mode = AU8522_ANALOG_MODE;
642
643 /* Clear out any state associated with the digital side of the
644 chip, so that when it gets powered back up it won't think
645 that it is already tuned */
646 state->current_frequency = 0;
647
648 au8522_writereg(state, 0xa4, 1 << 5);
649
650 return 0;
651}
652
653static int au8522_s_video_routing(struct v4l2_subdev *sd,
654 u32 input, u32 output, u32 config)
655{
656 struct au8522_state *state = to_state(sd);
657
658 au8522_reset(sd, 0);
659
660 /* Jam open the i2c gate to the tuner. We do this here to handle the
661 case where the user went into digital mode (causing the gate to be
662 closed), and then came back to analog mode */
663 au8522_writereg(state, 0x106, 1);
664
665 if (input == AU8522_COMPOSITE_CH1) {
666 au8522_setup_cvbs_mode(state);
667 } else if (input == AU8522_SVIDEO_CH13) {
668 au8522_setup_svideo_mode(state);
669 } else if (input == AU8522_COMPOSITE_CH4_SIF) {
670 au8522_setup_cvbs_tuner_mode(state);
671 } else {
672 printk(KERN_ERR "au8522 mode not currently supported\n");
673 return -EINVAL;
674 }
675 return 0;
676}
677
678static int au8522_s_audio_routing(struct v4l2_subdev *sd,
679 u32 input, u32 output, u32 config)
680{
681 struct au8522_state *state = to_state(sd);
682 set_audio_input(state, input);
683 return 0;
684}
685
686static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
687{
688 int val = 0;
689 struct au8522_state *state = to_state(sd);
690 u8 lock_status;
691
692 /* Interrogate the decoder to see if we are getting a real signal */
693 lock_status = au8522_readreg(state, 0x00);
694 if (lock_status == 0xa2)
695 vt->signal = 0xffff;
696 else
697 vt->signal = 0x00;
698
699 vt->capability |=
700 V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
701 V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
702
703 val = V4L2_TUNER_SUB_MONO;
704 vt->rxsubchans = val;
705 vt->audmode = V4L2_TUNER_MODE_STEREO;
706 return 0;
707}
708
709static int au8522_g_chip_ident(struct v4l2_subdev *sd,
710 struct v4l2_dbg_chip_ident *chip)
711{
712 struct au8522_state *state = to_state(sd);
713 struct i2c_client *client = v4l2_get_subdevdata(sd);
714
715 return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
716}
717
718static int au8522_log_status(struct v4l2_subdev *sd)
719{
720 /* FIXME: Add some status info here */
721 return 0;
722}
723
724/* ----------------------------------------------------------------------- */
725
726static const struct v4l2_subdev_core_ops au8522_core_ops = {
727 .log_status = au8522_log_status,
728 .g_chip_ident = au8522_g_chip_ident,
729 .g_ctrl = au8522_g_ctrl,
730 .s_ctrl = au8522_s_ctrl,
731 .queryctrl = au8522_queryctrl,
732 .reset = au8522_reset,
733#ifdef CONFIG_VIDEO_ADV_DEBUG
734 .g_register = au8522_g_register,
735 .s_register = au8522_s_register,
736#endif
737};
738
739static const struct v4l2_subdev_tuner_ops au8522_tuner_ops = {
740 .g_tuner = au8522_g_tuner,
741};
742
743static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
744 .s_routing = au8522_s_audio_routing,
745};
746
747static const struct v4l2_subdev_video_ops au8522_video_ops = {
748 .s_routing = au8522_s_video_routing,
749 .s_stream = au8522_s_stream,
750};
751
752static const struct v4l2_subdev_ops au8522_ops = {
753 .core = &au8522_core_ops,
754 .tuner = &au8522_tuner_ops,
755 .audio = &au8522_audio_ops,
756 .video = &au8522_video_ops,
757};
758
759/* ----------------------------------------------------------------------- */
760
761static int au8522_probe(struct i2c_client *client,
762 const struct i2c_device_id *did)
763{
764 struct au8522_state *state;
765 struct v4l2_subdev *sd;
766 int instance;
767 struct au8522_config *demod_config;
768
769 /* Check if the adapter supports the needed features */
770 if (!i2c_check_functionality(client->adapter,
771 I2C_FUNC_SMBUS_BYTE_DATA)) {
772 return -EIO;
773 }
774
775 /* allocate memory for the internal state */
776 instance = au8522_get_state(&state, client->adapter, client->addr);
777 switch (instance) {
778 case 0:
779 printk(KERN_ERR "au8522_decoder allocation failed\n");
780 return -EIO;
781 case 1:
782 /* new demod instance */
783 printk(KERN_INFO "au8522_decoder creating new instance...\n");
784 break;
785 default:
786 /* existing demod instance */
787 printk(KERN_INFO "au8522_decoder attach existing instance.\n");
788 break;
789 }
790
791 demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
792 if (demod_config == NULL) {
793 if (instance == 1)
794 kfree(state);
795 return -ENOMEM;
796 }
797 demod_config->demod_address = 0x8e >> 1;
798
799 state->config = demod_config;
800 state->i2c = client->adapter;
801
802 sd = &state->sd;
803 v4l2_i2c_subdev_init(sd, client, &au8522_ops);
804
805 state->c = client;
806 state->vid_input = AU8522_COMPOSITE_CH1;
807 state->aud_input = AU8522_AUDIO_NONE;
808 state->id = 8522;
809 state->rev = 0;
810
811 /* Jam open the i2c gate to the tuner */
812 au8522_writereg(state, 0x106, 1);
813
814 return 0;
815}
816
817static int au8522_remove(struct i2c_client *client)
818{
819 struct v4l2_subdev *sd = i2c_get_clientdata(client);
820 v4l2_device_unregister_subdev(sd);
821 au8522_release_state(to_state(sd));
822 return 0;
823}
824
825static const struct i2c_device_id au8522_id[] = {
826 {"au8522", 0},
827 {}
828};
829
830MODULE_DEVICE_TABLE(i2c, au8522_id);
831
832static struct i2c_driver au8522_driver = {
833 .driver = {
834 .owner = THIS_MODULE,
835 .name = "au8522",
836 },
837 .probe = au8522_probe,
838 .remove = au8522_remove,
839 .id_table = au8522_id,
840};
841
842static __init int init_au8522(void)
843{
844 return i2c_add_driver(&au8522_driver);
845}
846
847static __exit void exit_au8522(void)
848{
849 i2c_del_driver(&au8522_driver);
850}
851
852module_init(init_au8522);
853module_exit(exit_au8522);
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c
new file mode 100644
index 00000000000..1d572940e24
--- /dev/null
+++ b/drivers/media/dvb/frontends/au8522_dig.c
@@ -0,0 +1,1013 @@
1/*
2 Auvitek AU8522 QAM/8VSB demodulator driver
3
4 Copyright (C) 2008 Steven Toth <stoth@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 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 <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/delay.h>
27#include "dvb_frontend.h"
28#include "au8522.h"
29#include "au8522_priv.h"
30
31static int debug;
32
33/* Despite the name "hybrid_tuner", the framework works just as well for
34 hybrid demodulators as well... */
35static LIST_HEAD(hybrid_tuner_instance_list);
36static DEFINE_MUTEX(au8522_list_mutex);
37
38#define dprintk(arg...)\
39 do { if (debug)\
40 printk(arg);\
41 } while (0)
42
43/* 16 bit registers, 8 bit values */
44int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
45{
46 int ret;
47 u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
48
49 struct i2c_msg msg = { .addr = state->config->demod_address,
50 .flags = 0, .buf = buf, .len = 3 };
51
52 ret = i2c_transfer(state->i2c, &msg, 1);
53
54 if (ret != 1)
55 printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
56 "ret == %i)\n", __func__, reg, data, ret);
57
58 return (ret != 1) ? -1 : 0;
59}
60
61u8 au8522_readreg(struct au8522_state *state, u16 reg)
62{
63 int ret;
64 u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff };
65 u8 b1[] = { 0 };
66
67 struct i2c_msg msg[] = {
68 { .addr = state->config->demod_address, .flags = 0,
69 .buf = b0, .len = 2 },
70 { .addr = state->config->demod_address, .flags = I2C_M_RD,
71 .buf = b1, .len = 1 } };
72
73 ret = i2c_transfer(state->i2c, msg, 2);
74
75 if (ret != 2)
76 printk(KERN_ERR "%s: readreg error (ret == %i)\n",
77 __func__, ret);
78 return b1[0];
79}
80
81static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
82{
83 struct au8522_state *state = fe->demodulator_priv;
84
85 dprintk("%s(%d)\n", __func__, enable);
86
87 if (state->operational_mode == AU8522_ANALOG_MODE) {
88 /* We're being asked to manage the gate even though we're
89 not in digital mode. This can occur if we get switched
90 over to analog mode before the dvb_frontend kernel thread
91 has completely shutdown */
92 return 0;
93 }
94
95 if (enable)
96 return au8522_writereg(state, 0x106, 1);
97 else
98 return au8522_writereg(state, 0x106, 0);
99}
100
101struct mse2snr_tab {
102 u16 val;
103 u16 data;
104};
105
106/* VSB SNR lookup table */
107static struct mse2snr_tab vsb_mse2snr_tab[] = {
108 { 0, 270 },
109 { 2, 250 },
110 { 3, 240 },
111 { 5, 230 },
112 { 7, 220 },
113 { 9, 210 },
114 { 12, 200 },
115 { 13, 195 },
116 { 15, 190 },
117 { 17, 185 },
118 { 19, 180 },
119 { 21, 175 },
120 { 24, 170 },
121 { 27, 165 },
122 { 31, 160 },
123 { 32, 158 },
124 { 33, 156 },
125 { 36, 152 },
126 { 37, 150 },
127 { 39, 148 },
128 { 40, 146 },
129 { 41, 144 },
130 { 43, 142 },
131 { 44, 140 },
132 { 48, 135 },
133 { 50, 130 },
134 { 43, 142 },
135 { 53, 125 },
136 { 56, 120 },
137 { 256, 115 },
138};
139
140/* QAM64 SNR lookup table */
141static struct mse2snr_tab qam64_mse2snr_tab[] = {
142 { 15, 0 },
143 { 16, 290 },
144 { 17, 288 },
145 { 18, 286 },
146 { 19, 284 },
147 { 20, 282 },
148 { 21, 281 },
149 { 22, 279 },
150 { 23, 277 },
151 { 24, 275 },
152 { 25, 273 },
153 { 26, 271 },
154 { 27, 269 },
155 { 28, 268 },
156 { 29, 266 },
157 { 30, 264 },
158 { 31, 262 },
159 { 32, 260 },
160 { 33, 259 },
161 { 34, 258 },
162 { 35, 256 },
163 { 36, 255 },
164 { 37, 254 },
165 { 38, 252 },
166 { 39, 251 },
167 { 40, 250 },
168 { 41, 249 },
169 { 42, 248 },
170 { 43, 246 },
171 { 44, 245 },
172 { 45, 244 },
173 { 46, 242 },
174 { 47, 241 },
175 { 48, 240 },
176 { 50, 239 },
177 { 51, 238 },
178 { 53, 237 },
179 { 54, 236 },
180 { 56, 235 },
181 { 57, 234 },
182 { 59, 233 },
183 { 60, 232 },
184 { 62, 231 },
185 { 63, 230 },
186 { 65, 229 },
187 { 67, 228 },
188 { 68, 227 },
189 { 70, 226 },
190 { 71, 225 },
191 { 73, 224 },
192 { 74, 223 },
193 { 76, 222 },
194 { 78, 221 },
195 { 80, 220 },
196 { 82, 219 },
197 { 85, 218 },
198 { 88, 217 },
199 { 90, 216 },
200 { 92, 215 },
201 { 93, 214 },
202 { 94, 212 },
203 { 95, 211 },
204 { 97, 210 },
205 { 99, 209 },
206 { 101, 208 },
207 { 102, 207 },
208 { 104, 206 },
209 { 107, 205 },
210 { 111, 204 },
211 { 114, 203 },
212 { 118, 202 },
213 { 122, 201 },
214 { 125, 200 },
215 { 128, 199 },
216 { 130, 198 },
217 { 132, 197 },
218 { 256, 190 },
219};
220
221/* QAM256 SNR lookup table */
222static struct mse2snr_tab qam256_mse2snr_tab[] = {
223 { 16, 0 },
224 { 17, 400 },
225 { 18, 398 },
226 { 19, 396 },
227 { 20, 394 },
228 { 21, 392 },
229 { 22, 390 },
230 { 23, 388 },
231 { 24, 386 },
232 { 25, 384 },
233 { 26, 382 },
234 { 27, 380 },
235 { 28, 379 },
236 { 29, 378 },
237 { 30, 377 },
238 { 31, 376 },
239 { 32, 375 },
240 { 33, 374 },
241 { 34, 373 },
242 { 35, 372 },
243 { 36, 371 },
244 { 37, 370 },
245 { 38, 362 },
246 { 39, 354 },
247 { 40, 346 },
248 { 41, 338 },
249 { 42, 330 },
250 { 43, 328 },
251 { 44, 326 },
252 { 45, 324 },
253 { 46, 322 },
254 { 47, 320 },
255 { 48, 319 },
256 { 49, 318 },
257 { 50, 317 },
258 { 51, 316 },
259 { 52, 315 },
260 { 53, 314 },
261 { 54, 313 },
262 { 55, 312 },
263 { 56, 311 },
264 { 57, 310 },
265 { 58, 308 },
266 { 59, 306 },
267 { 60, 304 },
268 { 61, 302 },
269 { 62, 300 },
270 { 63, 298 },
271 { 65, 295 },
272 { 68, 294 },
273 { 70, 293 },
274 { 73, 292 },
275 { 76, 291 },
276 { 78, 290 },
277 { 79, 289 },
278 { 81, 288 },
279 { 82, 287 },
280 { 83, 286 },
281 { 84, 285 },
282 { 85, 284 },
283 { 86, 283 },
284 { 88, 282 },
285 { 89, 281 },
286 { 256, 280 },
287};
288
289static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse,
290 u16 *snr)
291{
292 int i, ret = -EINVAL;
293 dprintk("%s()\n", __func__);
294
295 for (i = 0; i < sz; i++) {
296 if (mse < tab[i].val) {
297 *snr = tab[i].data;
298 ret = 0;
299 break;
300 }
301 }
302 dprintk("%s() snr=%d\n", __func__, *snr);
303 return ret;
304}
305
306static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq)
307{
308 struct au8522_state *state = fe->demodulator_priv;
309 u8 r0b5, r0b6, r0b7;
310 char *ifmhz;
311
312 switch (if_freq) {
313 case AU8522_IF_3_25MHZ:
314 ifmhz = "3.25";
315 r0b5 = 0x00;
316 r0b6 = 0x3d;
317 r0b7 = 0xa0;
318 break;
319 case AU8522_IF_4MHZ:
320 ifmhz = "4.00";
321 r0b5 = 0x00;
322 r0b6 = 0x4b;
323 r0b7 = 0xd9;
324 break;
325 case AU8522_IF_6MHZ:
326 ifmhz = "6.00";
327 r0b5 = 0xfb;
328 r0b6 = 0x8e;
329 r0b7 = 0x39;
330 break;
331 default:
332 dprintk("%s() IF Frequency not supported\n", __func__);
333 return -EINVAL;
334 }
335 dprintk("%s() %s MHz\n", __func__, ifmhz);
336 au8522_writereg(state, 0x80b5, r0b5);
337 au8522_writereg(state, 0x80b6, r0b6);
338 au8522_writereg(state, 0x80b7, r0b7);
339
340 return 0;
341}
342
343/* VSB Modulation table */
344static struct {
345 u16 reg;
346 u16 data;
347} VSB_mod_tab[] = {
348 { 0x8090, 0x84 },
349 { 0x4092, 0x11 },
350 { 0x2005, 0x00 },
351 { 0x8091, 0x80 },
352 { 0x80a3, 0x0c },
353 { 0x80a4, 0xe8 },
354 { 0x8081, 0xc4 },
355 { 0x80a5, 0x40 },
356 { 0x80a7, 0x40 },
357 { 0x80a6, 0x67 },
358 { 0x8262, 0x20 },
359 { 0x821c, 0x30 },
360 { 0x80d8, 0x1a },
361 { 0x8227, 0xa0 },
362 { 0x8121, 0xff },
363 { 0x80a8, 0xf0 },
364 { 0x80a9, 0x05 },
365 { 0x80aa, 0x77 },
366 { 0x80ab, 0xf0 },
367 { 0x80ac, 0x05 },
368 { 0x80ad, 0x77 },
369 { 0x80ae, 0x41 },
370 { 0x80af, 0x66 },
371 { 0x821b, 0xcc },
372 { 0x821d, 0x80 },
373 { 0x80a4, 0xe8 },
374 { 0x8231, 0x13 },
375};
376
377/* QAM64 Modulation table */
378static struct {
379 u16 reg;
380 u16 data;
381} QAM64_mod_tab[] = {
382 { 0x00a3, 0x09 },
383 { 0x00a4, 0x00 },
384 { 0x0081, 0xc4 },
385 { 0x00a5, 0x40 },
386 { 0x00aa, 0x77 },
387 { 0x00ad, 0x77 },
388 { 0x00a6, 0x67 },
389 { 0x0262, 0x20 },
390 { 0x021c, 0x30 },
391 { 0x00b8, 0x3e },
392 { 0x00b9, 0xf0 },
393 { 0x00ba, 0x01 },
394 { 0x00bb, 0x18 },
395 { 0x00bc, 0x50 },
396 { 0x00bd, 0x00 },
397 { 0x00be, 0xea },
398 { 0x00bf, 0xef },
399 { 0x00c0, 0xfc },
400 { 0x00c1, 0xbd },
401 { 0x00c2, 0x1f },
402 { 0x00c3, 0xfc },
403 { 0x00c4, 0xdd },
404 { 0x00c5, 0xaf },
405 { 0x00c6, 0x00 },
406 { 0x00c7, 0x38 },
407 { 0x00c8, 0x30 },
408 { 0x00c9, 0x05 },
409 { 0x00ca, 0x4a },
410 { 0x00cb, 0xd0 },
411 { 0x00cc, 0x01 },
412 { 0x00cd, 0xd9 },
413 { 0x00ce, 0x6f },
414 { 0x00cf, 0xf9 },
415 { 0x00d0, 0x70 },
416 { 0x00d1, 0xdf },
417 { 0x00d2, 0xf7 },
418 { 0x00d3, 0xc2 },
419 { 0x00d4, 0xdf },
420 { 0x00d5, 0x02 },
421 { 0x00d6, 0x9a },
422 { 0x00d7, 0xd0 },
423 { 0x0250, 0x0d },
424 { 0x0251, 0xcd },
425 { 0x0252, 0xe0 },
426 { 0x0253, 0x05 },
427 { 0x0254, 0xa7 },
428 { 0x0255, 0xff },
429 { 0x0256, 0xed },
430 { 0x0257, 0x5b },
431 { 0x0258, 0xae },
432 { 0x0259, 0xe6 },
433 { 0x025a, 0x3d },
434 { 0x025b, 0x0f },
435 { 0x025c, 0x0d },
436 { 0x025d, 0xea },
437 { 0x025e, 0xf2 },
438 { 0x025f, 0x51 },
439 { 0x0260, 0xf5 },
440 { 0x0261, 0x06 },
441 { 0x021a, 0x00 },
442 { 0x0546, 0x40 },
443 { 0x0210, 0xc7 },
444 { 0x0211, 0xaa },
445 { 0x0212, 0xab },
446 { 0x0213, 0x02 },
447 { 0x0502, 0x00 },
448 { 0x0121, 0x04 },
449 { 0x0122, 0x04 },
450 { 0x052e, 0x10 },
451 { 0x00a4, 0xca },
452 { 0x00a7, 0x40 },
453 { 0x0526, 0x01 },
454};
455
456/* QAM256 Modulation table */
457static struct {
458 u16 reg;
459 u16 data;
460} QAM256_mod_tab[] = {
461 { 0x80a3, 0x09 },
462 { 0x80a4, 0x00 },
463 { 0x8081, 0xc4 },
464 { 0x80a5, 0x40 },
465 { 0x80aa, 0x77 },
466 { 0x80ad, 0x77 },
467 { 0x80a6, 0x67 },
468 { 0x8262, 0x20 },
469 { 0x821c, 0x30 },
470 { 0x80b8, 0x3e },
471 { 0x80b9, 0xf0 },
472 { 0x80ba, 0x01 },
473 { 0x80bb, 0x18 },
474 { 0x80bc, 0x50 },
475 { 0x80bd, 0x00 },
476 { 0x80be, 0xea },
477 { 0x80bf, 0xef },
478 { 0x80c0, 0xfc },
479 { 0x80c1, 0xbd },
480 { 0x80c2, 0x1f },
481 { 0x80c3, 0xfc },
482 { 0x80c4, 0xdd },
483 { 0x80c5, 0xaf },
484 { 0x80c6, 0x00 },
485 { 0x80c7, 0x38 },
486 { 0x80c8, 0x30 },
487 { 0x80c9, 0x05 },
488 { 0x80ca, 0x4a },
489 { 0x80cb, 0xd0 },
490 { 0x80cc, 0x01 },
491 { 0x80cd, 0xd9 },
492 { 0x80ce, 0x6f },
493 { 0x80cf, 0xf9 },
494 { 0x80d0, 0x70 },
495 { 0x80d1, 0xdf },
496 { 0x80d2, 0xf7 },
497 { 0x80d3, 0xc2 },
498 { 0x80d4, 0xdf },
499 { 0x80d5, 0x02 },
500 { 0x80d6, 0x9a },
501 { 0x80d7, 0xd0 },
502 { 0x8250, 0x0d },
503 { 0x8251, 0xcd },
504 { 0x8252, 0xe0 },
505 { 0x8253, 0x05 },
506 { 0x8254, 0xa7 },
507 { 0x8255, 0xff },
508 { 0x8256, 0xed },
509 { 0x8257, 0x5b },
510 { 0x8258, 0xae },
511 { 0x8259, 0xe6 },
512 { 0x825a, 0x3d },
513 { 0x825b, 0x0f },
514 { 0x825c, 0x0d },
515 { 0x825d, 0xea },
516 { 0x825e, 0xf2 },
517 { 0x825f, 0x51 },
518 { 0x8260, 0xf5 },
519 { 0x8261, 0x06 },
520 { 0x821a, 0x00 },
521 { 0x8546, 0x40 },
522 { 0x8210, 0x26 },
523 { 0x8211, 0xf6 },
524 { 0x8212, 0x84 },
525 { 0x8213, 0x02 },
526 { 0x8502, 0x01 },
527 { 0x8121, 0x04 },
528 { 0x8122, 0x04 },
529 { 0x852e, 0x10 },
530 { 0x80a4, 0xca },
531 { 0x80a7, 0x40 },
532 { 0x8526, 0x01 },
533};
534
535static int au8522_enable_modulation(struct dvb_frontend *fe,
536 fe_modulation_t m)
537{
538 struct au8522_state *state = fe->demodulator_priv;
539 int i;
540
541 dprintk("%s(0x%08x)\n", __func__, m);
542
543 switch (m) {
544 case VSB_8:
545 dprintk("%s() VSB_8\n", __func__);
546 for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++)
547 au8522_writereg(state,
548 VSB_mod_tab[i].reg,
549 VSB_mod_tab[i].data);
550 au8522_set_if(fe, state->config->vsb_if);
551 break;
552 case QAM_64:
553 dprintk("%s() QAM 64\n", __func__);
554 for (i = 0; i < ARRAY_SIZE(QAM64_mod_tab); i++)
555 au8522_writereg(state,
556 QAM64_mod_tab[i].reg,
557 QAM64_mod_tab[i].data);
558 au8522_set_if(fe, state->config->qam_if);
559 break;
560 case QAM_256:
561 dprintk("%s() QAM 256\n", __func__);
562 for (i = 0; i < ARRAY_SIZE(QAM256_mod_tab); i++)
563 au8522_writereg(state,
564 QAM256_mod_tab[i].reg,
565 QAM256_mod_tab[i].data);
566 au8522_set_if(fe, state->config->qam_if);
567 break;
568 default:
569 dprintk("%s() Invalid modulation\n", __func__);
570 return -EINVAL;
571 }
572
573 state->current_modulation = m;
574
575 return 0;
576}
577
578/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
579static int au8522_set_frontend(struct dvb_frontend *fe,
580 struct dvb_frontend_parameters *p)
581{
582 struct au8522_state *state = fe->demodulator_priv;
583 int ret = -EINVAL;
584
585 dprintk("%s(frequency=%d)\n", __func__, p->frequency);
586
587 if ((state->current_frequency == p->frequency) &&
588 (state->current_modulation == p->u.vsb.modulation))
589 return 0;
590
591 au8522_enable_modulation(fe, p->u.vsb.modulation);
592
593 /* Allow the demod to settle */
594 msleep(100);
595
596 if (fe->ops.tuner_ops.set_params) {
597 if (fe->ops.i2c_gate_ctrl)
598 fe->ops.i2c_gate_ctrl(fe, 1);
599 ret = fe->ops.tuner_ops.set_params(fe, p);
600 if (fe->ops.i2c_gate_ctrl)
601 fe->ops.i2c_gate_ctrl(fe, 0);
602 }
603
604 if (ret < 0)
605 return ret;
606
607 state->current_frequency = p->frequency;
608
609 return 0;
610}
611
612/* Reset the demod hardware and reset all of the configuration registers
613 to a default state. */
614int au8522_init(struct dvb_frontend *fe)
615{
616 struct au8522_state *state = fe->demodulator_priv;
617 dprintk("%s()\n", __func__);
618
619 state->operational_mode = AU8522_DIGITAL_MODE;
620
621 /* Clear out any state associated with the digital side of the
622 chip, so that when it gets powered back up it won't think
623 that it is already tuned */
624 state->current_frequency = 0;
625
626 au8522_writereg(state, 0xa4, 1 << 5);
627
628 au8522_i2c_gate_ctrl(fe, 1);
629
630 return 0;
631}
632
633static int au8522_led_gpio_enable(struct au8522_state *state, int onoff)
634{
635 struct au8522_led_config *led_config = state->config->led_cfg;
636 u8 val;
637
638 /* bail out if we can't control an LED */
639 if (!led_config || !led_config->gpio_output ||
640 !led_config->gpio_output_enable || !led_config->gpio_output_disable)
641 return 0;
642
643 val = au8522_readreg(state, 0x4000 |
644 (led_config->gpio_output & ~0xc000));
645 if (onoff) {
646 /* enable GPIO output */
647 val &= ~((led_config->gpio_output_enable >> 8) & 0xff);
648 val |= (led_config->gpio_output_enable & 0xff);
649 } else {
650 /* disable GPIO output */
651 val &= ~((led_config->gpio_output_disable >> 8) & 0xff);
652 val |= (led_config->gpio_output_disable & 0xff);
653 }
654 return au8522_writereg(state, 0x8000 |
655 (led_config->gpio_output & ~0xc000), val);
656}
657
658/* led = 0 | off
659 * led = 1 | signal ok
660 * led = 2 | signal strong
661 * led < 0 | only light led if leds are currently off
662 */
663static int au8522_led_ctrl(struct au8522_state *state, int led)
664{
665 struct au8522_led_config *led_config = state->config->led_cfg;
666 int i, ret = 0;
667
668 /* bail out if we can't control an LED */
669 if (!led_config || !led_config->gpio_leds ||
670 !led_config->num_led_states || !led_config->led_states)
671 return 0;
672
673 if (led < 0) {
674 /* if LED is already lit, then leave it as-is */
675 if (state->led_state)
676 return 0;
677 else
678 led *= -1;
679 }
680
681 /* toggle LED if changing state */
682 if (state->led_state != led) {
683 u8 val;
684
685 dprintk("%s: %d\n", __func__, led);
686
687 au8522_led_gpio_enable(state, 1);
688
689 val = au8522_readreg(state, 0x4000 |
690 (led_config->gpio_leds & ~0xc000));
691
692 /* start with all leds off */
693 for (i = 0; i < led_config->num_led_states; i++)
694 val &= ~led_config->led_states[i];
695
696 /* set selected LED state */
697 if (led < led_config->num_led_states)
698 val |= led_config->led_states[led];
699 else if (led_config->num_led_states)
700 val |=
701 led_config->led_states[led_config->num_led_states - 1];
702
703 ret = au8522_writereg(state, 0x8000 |
704 (led_config->gpio_leds & ~0xc000), val);
705 if (ret < 0)
706 return ret;
707
708 state->led_state = led;
709
710 if (led == 0)
711 au8522_led_gpio_enable(state, 0);
712 }
713
714 return 0;
715}
716
717int au8522_sleep(struct dvb_frontend *fe)
718{
719 struct au8522_state *state = fe->demodulator_priv;
720 dprintk("%s()\n", __func__);
721
722 /* Only power down if the digital side is currently using the chip */
723 if (state->operational_mode == AU8522_ANALOG_MODE) {
724 /* We're not in one of the expected power modes, which means
725 that the DVB thread is probably telling us to go to sleep
726 even though the analog frontend has already started using
727 the chip. So ignore the request */
728 return 0;
729 }
730
731 /* turn off led */
732 au8522_led_ctrl(state, 0);
733
734 /* Power down the chip */
735 au8522_writereg(state, 0xa4, 1 << 5);
736
737 state->current_frequency = 0;
738
739 return 0;
740}
741
742static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
743{
744 struct au8522_state *state = fe->demodulator_priv;
745 u8 reg;
746 u32 tuner_status = 0;
747
748 *status = 0;
749
750 if (state->current_modulation == VSB_8) {
751 dprintk("%s() Checking VSB_8\n", __func__);
752 reg = au8522_readreg(state, 0x4088);
753 if ((reg & 0x03) == 0x03)
754 *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
755 } else {
756 dprintk("%s() Checking QAM\n", __func__);
757 reg = au8522_readreg(state, 0x4541);
758 if (reg & 0x80)
759 *status |= FE_HAS_VITERBI;
760 if (reg & 0x20)
761 *status |= FE_HAS_LOCK | FE_HAS_SYNC;
762 }
763
764 switch (state->config->status_mode) {
765 case AU8522_DEMODLOCKING:
766 dprintk("%s() DEMODLOCKING\n", __func__);
767 if (*status & FE_HAS_VITERBI)
768 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
769 break;
770 case AU8522_TUNERLOCKING:
771 /* Get the tuner status */
772 dprintk("%s() TUNERLOCKING\n", __func__);
773 if (fe->ops.tuner_ops.get_status) {
774 if (fe->ops.i2c_gate_ctrl)
775 fe->ops.i2c_gate_ctrl(fe, 1);
776
777 fe->ops.tuner_ops.get_status(fe, &tuner_status);
778
779 if (fe->ops.i2c_gate_ctrl)
780 fe->ops.i2c_gate_ctrl(fe, 0);
781 }
782 if (tuner_status)
783 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
784 break;
785 }
786 state->fe_status = *status;
787
788 if (*status & FE_HAS_LOCK)
789 /* turn on LED, if it isn't on already */
790 au8522_led_ctrl(state, -1);
791 else
792 /* turn off LED */
793 au8522_led_ctrl(state, 0);
794
795 dprintk("%s() status 0x%08x\n", __func__, *status);
796
797 return 0;
798}
799
800static int au8522_led_status(struct au8522_state *state, const u16 *snr)
801{
802 struct au8522_led_config *led_config = state->config->led_cfg;
803 int led;
804 u16 strong;
805
806 /* bail out if we can't control an LED */
807 if (!led_config)
808 return 0;
809
810 if (0 == (state->fe_status & FE_HAS_LOCK))
811 return au8522_led_ctrl(state, 0);
812 else if (state->current_modulation == QAM_256)
813 strong = led_config->qam256_strong;
814 else if (state->current_modulation == QAM_64)
815 strong = led_config->qam64_strong;
816 else /* (state->current_modulation == VSB_8) */
817 strong = led_config->vsb8_strong;
818
819 if (*snr >= strong)
820 led = 2;
821 else
822 led = 1;
823
824 if ((state->led_state) &&
825 (((strong < *snr) ? (*snr - strong) : (strong - *snr)) <= 10))
826 /* snr didn't change enough to bother
827 * changing the color of the led */
828 return 0;
829
830 return au8522_led_ctrl(state, led);
831}
832
833static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
834{
835 struct au8522_state *state = fe->demodulator_priv;
836 int ret = -EINVAL;
837
838 dprintk("%s()\n", __func__);
839
840 if (state->current_modulation == QAM_256)
841 ret = au8522_mse2snr_lookup(qam256_mse2snr_tab,
842 ARRAY_SIZE(qam256_mse2snr_tab),
843 au8522_readreg(state, 0x4522),
844 snr);
845 else if (state->current_modulation == QAM_64)
846 ret = au8522_mse2snr_lookup(qam64_mse2snr_tab,
847 ARRAY_SIZE(qam64_mse2snr_tab),
848 au8522_readreg(state, 0x4522),
849 snr);
850 else /* VSB_8 */
851 ret = au8522_mse2snr_lookup(vsb_mse2snr_tab,
852 ARRAY_SIZE(vsb_mse2snr_tab),
853 au8522_readreg(state, 0x4311),
854 snr);
855
856 if (state->config->led_cfg)
857 au8522_led_status(state, snr);
858
859 return ret;
860}
861
862static int au8522_read_signal_strength(struct dvb_frontend *fe,
863 u16 *signal_strength)
864{
865 return au8522_read_snr(fe, signal_strength);
866}
867
868static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
869{
870 struct au8522_state *state = fe->demodulator_priv;
871
872 if (state->current_modulation == VSB_8)
873 *ucblocks = au8522_readreg(state, 0x4087);
874 else
875 *ucblocks = au8522_readreg(state, 0x4543);
876
877 return 0;
878}
879
880static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber)
881{
882 return au8522_read_ucblocks(fe, ber);
883}
884
885static int au8522_get_frontend(struct dvb_frontend *fe,
886 struct dvb_frontend_parameters *p)
887{
888 struct au8522_state *state = fe->demodulator_priv;
889
890 p->frequency = state->current_frequency;
891 p->u.vsb.modulation = state->current_modulation;
892
893 return 0;
894}
895
896static int au8522_get_tune_settings(struct dvb_frontend *fe,
897 struct dvb_frontend_tune_settings *tune)
898{
899 tune->min_delay_ms = 1000;
900 return 0;
901}
902
903static struct dvb_frontend_ops au8522_ops;
904
905int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
906 u8 client_address)
907{
908 int ret;
909
910 mutex_lock(&au8522_list_mutex);
911 ret = hybrid_tuner_request_state(struct au8522_state, (*state),
912 hybrid_tuner_instance_list,
913 i2c, client_address, "au8522");
914 mutex_unlock(&au8522_list_mutex);
915
916 return ret;
917}
918
919void au8522_release_state(struct au8522_state *state)
920{
921 mutex_lock(&au8522_list_mutex);
922 if (state != NULL)
923 hybrid_tuner_release_state(state);
924 mutex_unlock(&au8522_list_mutex);
925}
926
927
928static void au8522_release(struct dvb_frontend *fe)
929{
930 struct au8522_state *state = fe->demodulator_priv;
931 au8522_release_state(state);
932}
933
934struct dvb_frontend *au8522_attach(const struct au8522_config *config,
935 struct i2c_adapter *i2c)
936{
937 struct au8522_state *state = NULL;
938 int instance;
939
940 /* allocate memory for the internal state */
941 instance = au8522_get_state(&state, i2c, config->demod_address);
942 switch (instance) {
943 case 0:
944 dprintk("%s state allocation failed\n", __func__);
945 break;
946 case 1:
947 /* new demod instance */
948 dprintk("%s using new instance\n", __func__);
949 break;
950 default:
951 /* existing demod instance */
952 dprintk("%s using existing instance\n", __func__);
953 break;
954 }
955
956 /* setup the state */
957 state->config = config;
958 state->i2c = i2c;
959 state->operational_mode = AU8522_DIGITAL_MODE;
960
961 /* create dvb_frontend */
962 memcpy(&state->frontend.ops, &au8522_ops,
963 sizeof(struct dvb_frontend_ops));
964 state->frontend.demodulator_priv = state;
965
966 if (au8522_init(&state->frontend) != 0) {
967 printk(KERN_ERR "%s: Failed to initialize correctly\n",
968 __func__);
969 goto error;
970 }
971
972 /* Note: Leaving the I2C gate open here. */
973 au8522_i2c_gate_ctrl(&state->frontend, 1);
974
975 return &state->frontend;
976
977error:
978 au8522_release_state(state);
979 return NULL;
980}
981EXPORT_SYMBOL(au8522_attach);
982
983static struct dvb_frontend_ops au8522_ops = {
984
985 .info = {
986 .name = "Auvitek AU8522 QAM/8VSB Frontend",
987 .type = FE_ATSC,
988 .frequency_min = 54000000,
989 .frequency_max = 858000000,
990 .frequency_stepsize = 62500,
991 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
992 },
993
994 .init = au8522_init,
995 .sleep = au8522_sleep,
996 .i2c_gate_ctrl = au8522_i2c_gate_ctrl,
997 .set_frontend = au8522_set_frontend,
998 .get_frontend = au8522_get_frontend,
999 .get_tune_settings = au8522_get_tune_settings,
1000 .read_status = au8522_read_status,
1001 .read_ber = au8522_read_ber,
1002 .read_signal_strength = au8522_read_signal_strength,
1003 .read_snr = au8522_read_snr,
1004 .read_ucblocks = au8522_read_ucblocks,
1005 .release = au8522_release,
1006};
1007
1008module_param(debug, int, 0644);
1009MODULE_PARM_DESC(debug, "Enable verbose debug messages");
1010
1011MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver");
1012MODULE_AUTHOR("Steven Toth");
1013MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h
new file mode 100644
index 00000000000..751e17d692a
--- /dev/null
+++ b/drivers/media/dvb/frontends/au8522_priv.h
@@ -0,0 +1,421 @@
1/*
2 Auvitek AU8522 QAM/8VSB demodulator driver
3
4 Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
5 Copyright (C) 2008 Devin Heitmueller <dheitmueller@linuxtv.org>
6 Copyright (C) 2005-2008 Auvitek International, Ltd.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22*/
23
24#include <linux/kernel.h>
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/string.h>
28#include <linux/slab.h>
29#include <linux/delay.h>
30#include <linux/videodev2.h>
31#include <media/v4l2-device.h>
32#include <linux/i2c.h>
33#include "dvb_frontend.h"
34#include "au8522.h"
35#include "tuner-i2c.h"
36
37#define AU8522_ANALOG_MODE 0
38#define AU8522_DIGITAL_MODE 1
39
40struct au8522_state {
41 struct i2c_client *c;
42 struct i2c_adapter *i2c;
43
44 u8 operational_mode;
45
46 /* Used for sharing of the state between analog and digital mode */
47 struct tuner_i2c_props i2c_props;
48 struct list_head hybrid_tuner_instance_list;
49
50 /* configuration settings */
51 const struct au8522_config *config;
52
53 struct dvb_frontend frontend;
54
55 u32 current_frequency;
56 fe_modulation_t current_modulation;
57
58 u32 fe_status;
59 unsigned int led_state;
60
61 /* Analog settings */
62 struct v4l2_subdev sd;
63 v4l2_std_id std;
64 int vid_input;
65 int aud_input;
66 u32 id;
67 u32 rev;
68 u8 brightness;
69 u8 contrast;
70 u8 saturation;
71 s16 hue;
72};
73
74/* These are routines shared by both the VSB/QAM demodulator and the analog
75 decoder */
76int au8522_writereg(struct au8522_state *state, u16 reg, u8 data);
77u8 au8522_readreg(struct au8522_state *state, u16 reg);
78int au8522_init(struct dvb_frontend *fe);
79int au8522_sleep(struct dvb_frontend *fe);
80
81int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
82 u8 client_address);
83void au8522_release_state(struct au8522_state *state);
84
85/* REGISTERS */
86#define AU8522_INPUT_CONTROL_REG081H 0x081
87#define AU8522_PGA_CONTROL_REG082H 0x082
88#define AU8522_CLAMPING_CONTROL_REG083H 0x083
89
90#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H 0x0A3
91#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H 0x0A4
92#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H 0x0A5
93#define AU8522_AGC_CONTROL_RANGE_REG0A6H 0x0A6
94#define AU8522_SYSTEM_GAIN_CONTROL_REG0A7H 0x0A7
95#define AU8522_TUNER_AGC_RF_STOP_REG0A8H 0x0A8
96#define AU8522_TUNER_AGC_RF_START_REG0A9H 0x0A9
97#define AU8522_TUNER_RF_AGC_DEFAULT_REG0AAH 0x0AA
98#define AU8522_TUNER_AGC_IF_STOP_REG0ABH 0x0AB
99#define AU8522_TUNER_AGC_IF_START_REG0ACH 0x0AC
100#define AU8522_TUNER_AGC_IF_DEFAULT_REG0ADH 0x0AD
101#define AU8522_TUNER_AGC_STEP_REG0AEH 0x0AE
102#define AU8522_TUNER_GAIN_STEP_REG0AFH 0x0AF
103
104/* Receiver registers */
105#define AU8522_FRMREGTHRD1_REG0B0H 0x0B0
106#define AU8522_FRMREGAGC1H_REG0B1H 0x0B1
107#define AU8522_FRMREGSHIFT1_REG0B2H 0x0B2
108#define AU8522_TOREGAGC1_REG0B3H 0x0B3
109#define AU8522_TOREGASHIFT1_REG0B4H 0x0B4
110#define AU8522_FRMREGBBH_REG0B5H 0x0B5
111#define AU8522_FRMREGBBM_REG0B6H 0x0B6
112#define AU8522_FRMREGBBL_REG0B7H 0x0B7
113/* 0xB8 TO 0xD7 are the filter coefficients */
114#define AU8522_FRMREGTHRD2_REG0D8H 0x0D8
115#define AU8522_FRMREGAGC2H_REG0D9H 0x0D9
116#define AU8522_TOREGAGC2_REG0DAH 0x0DA
117#define AU8522_TOREGSHIFT2_REG0DBH 0x0DB
118#define AU8522_FRMREGPILOTH_REG0DCH 0x0DC
119#define AU8522_FRMREGPILOTM_REG0DDH 0x0DD
120#define AU8522_FRMREGPILOTL_REG0DEH 0x0DE
121#define AU8522_TOREGFREQ_REG0DFH 0x0DF
122
123#define AU8522_RX_PGA_RFOUT_REG0EBH 0x0EB
124#define AU8522_RX_PGA_IFOUT_REG0ECH 0x0EC
125#define AU8522_RX_PGA_PGAOUT_REG0EDH 0x0ED
126
127#define AU8522_CHIP_MODE_REG0FEH 0x0FE
128
129/* I2C bus control registers */
130#define AU8522_I2C_CONTROL_REG0_REG090H 0x090
131#define AU8522_I2C_CONTROL_REG1_REG091H 0x091
132#define AU8522_I2C_STATUS_REG092H 0x092
133#define AU8522_I2C_WR_DATA0_REG093H 0x093
134#define AU8522_I2C_WR_DATA1_REG094H 0x094
135#define AU8522_I2C_WR_DATA2_REG095H 0x095
136#define AU8522_I2C_WR_DATA3_REG096H 0x096
137#define AU8522_I2C_WR_DATA4_REG097H 0x097
138#define AU8522_I2C_WR_DATA5_REG098H 0x098
139#define AU8522_I2C_WR_DATA6_REG099H 0x099
140#define AU8522_I2C_WR_DATA7_REG09AH 0x09A
141#define AU8522_I2C_RD_DATA0_REG09BH 0x09B
142#define AU8522_I2C_RD_DATA1_REG09CH 0x09C
143#define AU8522_I2C_RD_DATA2_REG09DH 0x09D
144#define AU8522_I2C_RD_DATA3_REG09EH 0x09E
145#define AU8522_I2C_RD_DATA4_REG09FH 0x09F
146#define AU8522_I2C_RD_DATA5_REG0A0H 0x0A0
147#define AU8522_I2C_RD_DATA6_REG0A1H 0x0A1
148#define AU8522_I2C_RD_DATA7_REG0A2H 0x0A2
149
150#define AU8522_ENA_USB_REG101H 0x101
151
152#define AU8522_I2S_CTRL_0_REG110H 0x110
153#define AU8522_I2S_CTRL_1_REG111H 0x111
154#define AU8522_I2S_CTRL_2_REG112H 0x112
155
156#define AU8522_FRMREGFFECONTROL_REG121H 0x121
157#define AU8522_FRMREGDFECONTROL_REG122H 0x122
158
159#define AU8522_CARRFREQOFFSET0_REG201H 0x201
160#define AU8522_CARRFREQOFFSET1_REG202H 0x202
161
162#define AU8522_DECIMATION_GAIN_REG21AH 0x21A
163#define AU8522_FRMREGIFSLP_REG21BH 0x21B
164#define AU8522_FRMREGTHRDL2_REG21CH 0x21C
165#define AU8522_FRMREGSTEP3DB_REG21DH 0x21D
166#define AU8522_DAGC_GAIN_ADJUSTMENT_REG21EH 0x21E
167#define AU8522_FRMREGPLLMODE_REG21FH 0x21F
168#define AU8522_FRMREGCSTHRD_REG220H 0x220
169#define AU8522_FRMREGCRLOCKDMAX_REG221H 0x221
170#define AU8522_FRMREGCRPERIODMASK_REG222H 0x222
171#define AU8522_FRMREGCRLOCK0THH_REG223H 0x223
172#define AU8522_FRMREGCRLOCK1THH_REG224H 0x224
173#define AU8522_FRMREGCRLOCK0THL_REG225H 0x225
174#define AU8522_FRMREGCRLOCK1THL_REG226H 0x226
175#define AU_FRMREGPLLACQPHASESCL_REG227H 0x227
176#define AU8522_FRMREGFREQFBCTRL_REG228H 0x228
177
178/* Analog TV Decoder */
179#define AU8522_TVDEC_STATUS_REG000H 0x000
180#define AU8522_TVDEC_INT_STATUS_REG001H 0x001
181#define AU8522_TVDEC_MACROVISION_STATUS_REG002H 0x002
182#define AU8522_TVDEC_SHARPNESSREG009H 0x009
183#define AU8522_TVDEC_BRIGHTNESS_REG00AH 0x00A
184#define AU8522_TVDEC_CONTRAST_REG00BH 0x00B
185#define AU8522_TVDEC_SATURATION_CB_REG00CH 0x00C
186#define AU8522_TVDEC_SATURATION_CR_REG00DH 0x00D
187#define AU8522_TVDEC_HUE_H_REG00EH 0x00E
188#define AU8522_TVDEC_HUE_L_REG00FH 0x00F
189#define AU8522_TVDEC_INT_MASK_REG010H 0x010
190#define AU8522_VIDEO_MODE_REG011H 0x011
191#define AU8522_TVDEC_PGA_REG012H 0x012
192#define AU8522_TVDEC_COMB_MODE_REG015H 0x015
193#define AU8522_REG016H 0x016
194#define AU8522_TVDED_DBG_MODE_REG060H 0x060
195#define AU8522_TVDEC_FORMAT_CTRL1_REG061H 0x061
196#define AU8522_TVDEC_FORMAT_CTRL2_REG062H 0x062
197#define AU8522_TVDEC_VCR_DET_LLIM_REG063H 0x063
198#define AU8522_TVDEC_VCR_DET_HLIM_REG064H 0x064
199#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H 0x065
200#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H 0x066
201#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H 0x067
202#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H 0x068
203#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H 0x069
204#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH 0x06A
205#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH 0x06B
206#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH 0x06C
207#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH 0x06D
208#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH 0x06E
209#define AU8522_TVDEC_UV_SEP_THR_REG06FH 0x06F
210#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H 0x070
211#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H 0x073
212#define AU8522_TVDEC_DCAGC_CTRL_REG077H 0x077
213#define AU8522_TVDEC_PIC_START_ADJ_REG078H 0x078
214#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H 0x079
215#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH 0x07A
216#define AU8522_TVDEC_INTRP_CTRL_REG07BH 0x07B
217#define AU8522_TVDEC_PLL_STATUS_REG07EH 0x07E
218#define AU8522_TVDEC_FSC_FREQ_REG07FH 0x07F
219
220#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H 0x0E4
221#define AU8522_TOREGAAGC_REG0E5H 0x0E5
222
223#define AU8522_TVDEC_CHROMA_AGC_REG401H 0x401
224#define AU8522_TVDEC_CHROMA_SFT_REG402H 0x402
225#define AU8522_FILTER_COEF_R410 0x410
226#define AU8522_FILTER_COEF_R411 0x411
227#define AU8522_FILTER_COEF_R412 0x412
228#define AU8522_FILTER_COEF_R413 0x413
229#define AU8522_FILTER_COEF_R414 0x414
230#define AU8522_FILTER_COEF_R415 0x415
231#define AU8522_FILTER_COEF_R416 0x416
232#define AU8522_FILTER_COEF_R417 0x417
233#define AU8522_FILTER_COEF_R418 0x418
234#define AU8522_FILTER_COEF_R419 0x419
235#define AU8522_FILTER_COEF_R41A 0x41A
236#define AU8522_FILTER_COEF_R41B 0x41B
237#define AU8522_FILTER_COEF_R41C 0x41C
238#define AU8522_FILTER_COEF_R41D 0x41D
239#define AU8522_FILTER_COEF_R41E 0x41E
240#define AU8522_FILTER_COEF_R41F 0x41F
241#define AU8522_FILTER_COEF_R420 0x420
242#define AU8522_FILTER_COEF_R421 0x421
243#define AU8522_FILTER_COEF_R422 0x422
244#define AU8522_FILTER_COEF_R423 0x423
245#define AU8522_FILTER_COEF_R424 0x424
246#define AU8522_FILTER_COEF_R425 0x425
247#define AU8522_FILTER_COEF_R426 0x426
248#define AU8522_FILTER_COEF_R427 0x427
249#define AU8522_FILTER_COEF_R428 0x428
250#define AU8522_FILTER_COEF_R429 0x429
251#define AU8522_FILTER_COEF_R42A 0x42A
252#define AU8522_FILTER_COEF_R42B 0x42B
253#define AU8522_FILTER_COEF_R42C 0x42C
254#define AU8522_FILTER_COEF_R42D 0x42D
255
256/* VBI Control Registers */
257#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H 0x004
258#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H 0x005
259#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H 0x006
260#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H 0x007
261#define AU8522_TVDEC_VBI_CTRL_H_REG017H 0x017
262#define AU8522_TVDEC_VBI_CTRL_L_REG018H 0x018
263#define AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H 0x019
264#define AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH 0x01A
265#define AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH 0x01B
266#define AU8522_TVDEC_VBI_USER_THRESH1_REG01CH 0x01C
267#define AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH 0x01E
268#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH 0x01F
269#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H 0x020
270#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H 0x021
271#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H 0x022
272#define AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H 0x023
273
274#define AU8522_REG071H 0x071
275#define AU8522_REG072H 0x072
276#define AU8522_REG074H 0x074
277#define AU8522_REG075H 0x075
278
279/* Digital Demodulator Registers */
280#define AU8522_FRAME_COUNT0_REG084H 0x084
281#define AU8522_RS_STATUS_G0_REG085H 0x085
282#define AU8522_RS_STATUS_B0_REG086H 0x086
283#define AU8522_RS_STATUS_E_REG087H 0x087
284#define AU8522_DEMODULATION_STATUS_REG088H 0x088
285#define AU8522_TOREGTRESTATUS_REG0E6H 0x0E6
286#define AU8522_TSPORT_CONTROL_REG10BH 0x10B
287#define AU8522_TSTHES_REG10CH 0x10C
288#define AU8522_FRMREGDFEKEEP_REG301H 0x301
289#define AU8522_DFE_AVERAGE_REG302H 0x302
290#define AU8522_FRMREGEQLERRWIN_REG303H 0x303
291#define AU8522_FRMREGFFEKEEP_REG304H 0x304
292#define AU8522_FRMREGDFECONTROL1_REG305H 0x305
293#define AU8522_FRMREGEQLERRLOW_REG306H 0x306
294
295#define AU8522_REG42EH 0x42E
296#define AU8522_REG42FH 0x42F
297#define AU8522_REG430H 0x430
298#define AU8522_REG431H 0x431
299#define AU8522_REG432H 0x432
300#define AU8522_REG433H 0x433
301#define AU8522_REG434H 0x434
302#define AU8522_REG435H 0x435
303#define AU8522_REG436H 0x436
304
305/* GPIO Registers */
306#define AU8522_GPIO_CONTROL_REG0E0H 0x0E0
307#define AU8522_GPIO_STATUS_REG0E1H 0x0E1
308#define AU8522_GPIO_DATA_REG0E2H 0x0E2
309
310/* Audio Control Registers */
311#define AU8522_AUDIOAGC_REG0EEH 0x0EE
312#define AU8522_AUDIO_STATUS_REG0F0H 0x0F0
313#define AU8522_AUDIO_MODE_REG0F1H 0x0F1
314#define AU8522_AUDIO_VOLUME_L_REG0F2H 0x0F2
315#define AU8522_AUDIO_VOLUME_R_REG0F3H 0x0F3
316#define AU8522_AUDIO_VOLUME_REG0F4H 0x0F4
317#define AU8522_FRMREGAUPHASE_REG0F7H 0x0F7
318#define AU8522_REG0F9H 0x0F9
319
320#define AU8522_AUDIOAGC2_REG605H 0x605
321#define AU8522_AUDIOFREQ_REG606H 0x606
322
323
324/**************************************************************/
325
326#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4
327#define AU8522_INPUT_CONTROL_REG081H_ATVRF 0xC4
328#define AU8522_INPUT_CONTROL_REG081H_ATVRF13 0xC4
329#define AU8522_INPUT_CONTROL_REG081H_J83B64 0xC4
330#define AU8522_INPUT_CONTROL_REG081H_J83B256 0xC4
331#define AU8522_INPUT_CONTROL_REG081H_CVBS 0x20
332#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH1 0xA2
333#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH2 0xA0
334#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH3 0x69
335#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4 0x68
336#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF 0x28
337/* CH1 AS Y,CH3 AS C */
338#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 0x23
339/* CH2 AS Y,CH4 AS C */
340#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24 0x20
341#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC 0x0C
342#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64 0x09
343#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256 0x09
344#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS 0x12
345#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF 0x1A
346#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF13 0x1A
347#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO 0x02
348
349#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CLEAR 0x00
350#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO 0x9C
351#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS 0x9D
352#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATSC 0xE8
353#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256 0xCA
354#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64 0xCA
355#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF 0xDD
356#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF13 0xDD
357#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_PAL 0xDD
358#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_FM 0xDD
359
360#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATSC 0x80
361#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256 0x80
362#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64 0x80
363#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_ATSC 0x40
364#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B256 0x40
365#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B64 0x40
366#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_CLEAR 0x00
367#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF 0x01
368#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF13 0x01
369#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO 0x04
370#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_CVBS 0x01
371#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM 0x03
372#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS 0x09
373#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PAL 0x01
374#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_FM 0x01
375
376/* STILL NEED TO BE REFACTORED @@@@@@@@@@@@@@ */
377#define AU8522_TVDEC_CONTRAST_REG00BH_CVBS 0x79
378#define AU8522_TVDEC_SATURATION_CB_REG00CH_CVBS 0x80
379#define AU8522_TVDEC_SATURATION_CR_REG00DH_CVBS 0x80
380#define AU8522_TVDEC_HUE_H_REG00EH_CVBS 0x00
381#define AU8522_TVDEC_HUE_L_REG00FH_CVBS 0x00
382#define AU8522_TVDEC_PGA_REG012H_CVBS 0x0F
383#define AU8522_TVDEC_COMB_MODE_REG015H_CVBS 0x00
384#define AU8522_REG016H_CVBS 0x00
385#define AU8522_TVDED_DBG_MODE_REG060H_CVBS 0x00
386#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS 0x0B
387#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13 0x03
388#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13 0x00
389#define AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS 0x19
390#define AU8522_REG0F9H_AUDIO 0x20
391#define AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS 0xA7
392#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS 0x0A
393#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS 0x32
394#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS 0x19
395#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS 0x23
396#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS 0x41
397#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS 0x0A
398#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS 0x32
399#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS 0x34
400#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO 0x2a
401#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS 0x05
402#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_SVIDEO 0x15
403#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS 0x6E
404#define AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS 0x0F
405#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS 0x80
406#define AU8522_REG071H_CVBS 0x18
407#define AU8522_REG072H_CVBS 0x30
408#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS 0xF0
409#define AU8522_REG074H_CVBS 0x80
410#define AU8522_REG075H_CVBS 0xF0
411#define AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS 0xFB
412#define AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS 0x04
413#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS 0x00
414#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS 0x00
415#define AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS 0xEE
416#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS 0xFE
417#define AU8522_TOREGAAGC_REG0E5H_CVBS 0x00
418#define AU8522_TVDEC_VBI6A_REG035H_CVBS 0x40
419
420/* Enables Closed captioning */
421#define AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON 0x21
diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c
new file mode 100644
index 00000000000..8aff5868a5e
--- /dev/null
+++ b/drivers/media/dvb/frontends/bcm3510.c
@@ -0,0 +1,854 @@
1/*
2 * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
3 *
4 * Copyright (C) 2001-5, B2C2 inc.
5 *
6 * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
7 *
8 * This driver is "hard-coded" to be used with the 1st generation of
9 * Technisat/B2C2's Air2PC ATSC PCI/USB cards/boxes. The pll-programming
10 * (Panasonic CT10S) is located here, which is actually wrong. Unless there is
11 * another device with a BCM3510, this is no problem.
12 *
13 * The driver works also with QAM64 DVB-C, but had an unreasonable high
14 * UNC. (Tested with the Air2PC ATSC 1st generation)
15 *
16 * You'll need a firmware for this driver in order to get it running. It is
17 * called "dvb-fe-bcm3510-01.fw".
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; either version 2 of the License, or (at your option)
22 * any later version.
23 *
24 * This program is distributed in the hope that it will be useful, but WITHOUT
25 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
27 * more details.
28 *
29 * You should have received a copy of the GNU General Public License along with
30 * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
31 * Ave, Cambridge, MA 02139, USA.
32 */
33
34#include <linux/init.h>
35#include <linux/module.h>
36#include <linux/device.h>
37#include <linux/firmware.h>
38#include <linux/jiffies.h>
39#include <linux/string.h>
40#include <linux/slab.h>
41#include <linux/mutex.h>
42
43#include "dvb_frontend.h"
44#include "bcm3510.h"
45#include "bcm3510_priv.h"
46
47struct bcm3510_state {
48
49 struct i2c_adapter* i2c;
50 const struct bcm3510_config* config;
51 struct dvb_frontend frontend;
52
53 /* demodulator private data */
54 struct mutex hab_mutex;
55 u8 firmware_loaded:1;
56
57 unsigned long next_status_check;
58 unsigned long status_check_interval;
59 struct bcm3510_hab_cmd_status1 status1;
60 struct bcm3510_hab_cmd_status2 status2;
61};
62
63static int debug;
64module_param(debug, int, 0644);
65MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c (|-able)).");
66
67#define dprintk(level,x...) if (level & debug) printk(x)
68#define dbufout(b,l,m) {\
69 int i; \
70 for (i = 0; i < l; i++) \
71 m("%02x ",b[i]); \
72}
73#define deb_info(args...) dprintk(0x01,args)
74#define deb_i2c(args...) dprintk(0x02,args)
75#define deb_hab(args...) dprintk(0x04,args)
76
77/* transfer functions */
78static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
79{
80 u8 b[256];
81 int err;
82 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = len + 1 };
83
84 b[0] = reg;
85 memcpy(&b[1],buf,len);
86
87 deb_i2c("i2c wr %02x: ",reg);
88 dbufout(buf,len,deb_i2c);
89 deb_i2c("\n");
90
91 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
92
93 deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n",
94 __func__, state->config->demod_address, reg, err);
95 return -EREMOTEIO;
96 }
97
98 return 0;
99}
100
101static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len)
102{
103 struct i2c_msg msg[] = {
104 { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
105 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len }
106 };
107 int err;
108
109 memset(buf,0,len);
110
111 if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
112 deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n",
113 __func__, state->config->demod_address, reg, err);
114 return -EREMOTEIO;
115 }
116 deb_i2c("i2c rd %02x: ",reg);
117 dbufout(buf,len,deb_i2c);
118 deb_i2c("\n");
119
120 return 0;
121}
122
123static int bcm3510_writeB(struct bcm3510_state *state, u8 reg, bcm3510_register_value v)
124{
125 return bcm3510_writebytes(state,reg,&v.raw,1);
126}
127
128static int bcm3510_readB(struct bcm3510_state *state, u8 reg, bcm3510_register_value *v)
129{
130 return bcm3510_readbytes(state,reg,&v->raw,1);
131}
132
133/* Host Access Buffer transfers */
134static int bcm3510_hab_get_response(struct bcm3510_state *st, u8 *buf, int len)
135{
136 bcm3510_register_value v;
137 int ret,i;
138
139 v.HABADR_a6.HABADR = 0;
140 if ((ret = bcm3510_writeB(st,0xa6,v)) < 0)
141 return ret;
142
143 for (i = 0; i < len; i++) {
144 if ((ret = bcm3510_readB(st,0xa7,&v)) < 0)
145 return ret;
146 buf[i] = v.HABDATA_a7;
147 }
148 return 0;
149}
150
151static int bcm3510_hab_send_request(struct bcm3510_state *st, u8 *buf, int len)
152{
153 bcm3510_register_value v,hab;
154 int ret,i;
155 unsigned long t;
156
157/* Check if any previous HAB request still needs to be serviced by the
158 * Acquisition Processor before sending new request */
159 if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
160 return ret;
161 if (v.HABSTAT_a8.HABR) {
162 deb_info("HAB is running already - clearing it.\n");
163 v.HABSTAT_a8.HABR = 0;
164 bcm3510_writeB(st,0xa8,v);
165// return -EBUSY;
166 }
167
168/* Send the start HAB Address (automatically incremented after write of
169 * HABDATA) and write the HAB Data */
170 hab.HABADR_a6.HABADR = 0;
171 if ((ret = bcm3510_writeB(st,0xa6,hab)) < 0)
172 return ret;
173
174 for (i = 0; i < len; i++) {
175 hab.HABDATA_a7 = buf[i];
176 if ((ret = bcm3510_writeB(st,0xa7,hab)) < 0)
177 return ret;
178 }
179
180/* Set the HABR bit to indicate AP request in progress (LBHABR allows HABR to
181 * be written) */
182 v.raw = 0; v.HABSTAT_a8.HABR = 1; v.HABSTAT_a8.LDHABR = 1;
183 if ((ret = bcm3510_writeB(st,0xa8,v)) < 0)
184 return ret;
185
186/* Polling method: Wait until the AP finishes processing the HAB request */
187 t = jiffies + 1*HZ;
188 while (time_before(jiffies, t)) {
189 deb_info("waiting for HAB to complete\n");
190 msleep(10);
191 if ((ret = bcm3510_readB(st,0xa8,&v)) < 0)
192 return ret;
193
194 if (!v.HABSTAT_a8.HABR)
195 return 0;
196 }
197
198 deb_info("send_request execution timed out.\n");
199 return -ETIMEDOUT;
200}
201
202static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *obuf, u8 olen, u8 *ibuf, u8 ilen)
203{
204 u8 ob[olen+2],ib[ilen+2];
205 int ret = 0;
206
207 ob[0] = cmd;
208 ob[1] = msgid;
209 memcpy(&ob[2],obuf,olen);
210
211 deb_hab("hab snd: ");
212 dbufout(ob,olen+2,deb_hab);
213 deb_hab("\n");
214
215 if (mutex_lock_interruptible(&st->hab_mutex) < 0)
216 return -EAGAIN;
217
218 if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 ||
219 (ret = bcm3510_hab_get_response(st, ib, ilen+2)) < 0)
220 goto error;
221
222 deb_hab("hab get: ");
223 dbufout(ib,ilen+2,deb_hab);
224 deb_hab("\n");
225
226 memcpy(ibuf,&ib[2],ilen);
227error:
228 mutex_unlock(&st->hab_mutex);
229 return ret;
230}
231
232#if 0
233/* not needed, we use a semaphore to prevent HAB races */
234static int bcm3510_is_ap_ready(struct bcm3510_state *st)
235{
236 bcm3510_register_value ap,hab;
237 int ret;
238
239 if ((ret = bcm3510_readB(st,0xa8,&hab)) < 0 ||
240 (ret = bcm3510_readB(st,0xa2,&ap) < 0))
241 return ret;
242
243 if (ap.APSTAT1_a2.RESET || ap.APSTAT1_a2.IDLE || ap.APSTAT1_a2.STOP || hab.HABSTAT_a8.HABR) {
244 deb_info("AP is busy\n");
245 return -EBUSY;
246 }
247
248 return 0;
249}
250#endif
251
252static int bcm3510_bert_reset(struct bcm3510_state *st)
253{
254 bcm3510_register_value b;
255 int ret;
256
257 if ((ret = bcm3510_readB(st,0xfa,&b)) < 0)
258 return ret;
259
260 b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
261 b.BERCTL_fa.RESYNC = 1; bcm3510_writeB(st,0xfa,b);
262 b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b);
263 b.BERCTL_fa.CNTCTL = 1; b.BERCTL_fa.BITCNT = 1; bcm3510_writeB(st,0xfa,b);
264
265 /* clear residual bit counter TODO */
266 return 0;
267}
268
269static int bcm3510_refresh_state(struct bcm3510_state *st)
270{
271 if (time_after(jiffies,st->next_status_check)) {
272 bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS1, NULL,0, (u8 *)&st->status1, sizeof(st->status1));
273 bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS2, NULL,0, (u8 *)&st->status2, sizeof(st->status2));
274 st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
275 }
276 return 0;
277}
278
279static int bcm3510_read_status(struct dvb_frontend *fe, fe_status_t *status)
280{
281 struct bcm3510_state* st = fe->demodulator_priv;
282 bcm3510_refresh_state(st);
283
284 *status = 0;
285 if (st->status1.STATUS1.RECEIVER_LOCK)
286 *status |= FE_HAS_LOCK | FE_HAS_SYNC;
287
288 if (st->status1.STATUS1.FEC_LOCK)
289 *status |= FE_HAS_VITERBI;
290
291 if (st->status1.STATUS1.OUT_PLL_LOCK)
292 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
293
294 if (*status & FE_HAS_LOCK)
295 st->status_check_interval = 1500;
296 else /* more frequently checks if no lock has been achieved yet */
297 st->status_check_interval = 500;
298
299 deb_info("real_status: %02x\n",*status);
300 return 0;
301}
302
303static int bcm3510_read_ber(struct dvb_frontend* fe, u32* ber)
304{
305 struct bcm3510_state* st = fe->demodulator_priv;
306 bcm3510_refresh_state(st);
307
308 *ber = (st->status2.LDBER0 << 16) | (st->status2.LDBER1 << 8) | st->status2.LDBER2;
309 return 0;
310}
311
312static int bcm3510_read_unc(struct dvb_frontend* fe, u32* unc)
313{
314 struct bcm3510_state* st = fe->demodulator_priv;
315 bcm3510_refresh_state(st);
316 *unc = (st->status2.LDUERC0 << 8) | st->status2.LDUERC1;
317 return 0;
318}
319
320static int bcm3510_read_signal_strength(struct dvb_frontend* fe, u16* strength)
321{
322 struct bcm3510_state* st = fe->demodulator_priv;
323 s32 t;
324
325 bcm3510_refresh_state(st);
326 t = st->status2.SIGNAL;
327
328 if (t > 190)
329 t = 190;
330 if (t < 90)
331 t = 90;
332
333 t -= 90;
334 t = t * 0xff / 100;
335 /* normalize if necessary */
336 *strength = (t << 8) | t;
337 return 0;
338}
339
340static int bcm3510_read_snr(struct dvb_frontend* fe, u16* snr)
341{
342 struct bcm3510_state* st = fe->demodulator_priv;
343 bcm3510_refresh_state(st);
344
345 *snr = st->status1.SNR_EST0*1000 + ((st->status1.SNR_EST1*1000) >> 8);
346 return 0;
347}
348
349/* tuner frontend programming */
350static int bcm3510_tuner_cmd(struct bcm3510_state* st,u8 bc, u16 n, u8 a)
351{
352 struct bcm3510_hab_cmd_tune c;
353 memset(&c,0,sizeof(struct bcm3510_hab_cmd_tune));
354
355/* I2C Mode disabled, set 16 control / Data pairs */
356 c.length = 0x10;
357 c.clock_width = 0;
358/* CS1, CS0, DATA, CLK bits control the tuner RF_AGC_SEL pin is set to
359 * logic high (as Configuration) */
360 c.misc = 0x10;
361/* Set duration of the initial state of TUNCTL = 3.34 micro Sec */
362 c.TUNCTL_state = 0x40;
363
364/* PRESCALER DIVIDE RATIO | BC1_2_3_4; (band switch), 1stosc REFERENCE COUNTER REF_S12 and REF_S11 */
365 c.ctl_dat[0].ctrl.size = BITS_8;
366 c.ctl_dat[0].data = 0x80 | bc;
367
368/* Control DATA pin, 1stosc REFERENCE COUNTER REF_S10 to REF_S3 */
369 c.ctl_dat[1].ctrl.size = BITS_8;
370 c.ctl_dat[1].data = 4;
371
372/* set CONTROL BIT 1 to 1, 1stosc REFERENCE COUNTER REF_S2 to REF_S1 */
373 c.ctl_dat[2].ctrl.size = BITS_3;
374 c.ctl_dat[2].data = 0x20;
375
376/* control CS0 pin, pulse byte ? */
377 c.ctl_dat[3].ctrl.size = BITS_3;
378 c.ctl_dat[3].ctrl.clk_off = 1;
379 c.ctl_dat[3].ctrl.cs0 = 1;
380 c.ctl_dat[3].data = 0x40;
381
382/* PGM_S18 to PGM_S11 */
383 c.ctl_dat[4].ctrl.size = BITS_8;
384 c.ctl_dat[4].data = n >> 3;
385
386/* PGM_S10 to PGM_S8, SWL_S7 to SWL_S3 */
387 c.ctl_dat[5].ctrl.size = BITS_8;
388 c.ctl_dat[5].data = ((n & 0x7) << 5) | (a >> 2);
389
390/* SWL_S2 and SWL_S1, set CONTROL BIT 2 to 0 */
391 c.ctl_dat[6].ctrl.size = BITS_3;
392 c.ctl_dat[6].data = (a << 6) & 0xdf;
393
394/* control CS0 pin, pulse byte ? */
395 c.ctl_dat[7].ctrl.size = BITS_3;
396 c.ctl_dat[7].ctrl.clk_off = 1;
397 c.ctl_dat[7].ctrl.cs0 = 1;
398 c.ctl_dat[7].data = 0x40;
399
400/* PRESCALER DIVIDE RATIO, 2ndosc REFERENCE COUNTER REF_S12 and REF_S11 */
401 c.ctl_dat[8].ctrl.size = BITS_8;
402 c.ctl_dat[8].data = 0x80;
403
404/* 2ndosc REFERENCE COUNTER REF_S10 to REF_S3 */
405 c.ctl_dat[9].ctrl.size = BITS_8;
406 c.ctl_dat[9].data = 0x10;
407
408/* set CONTROL BIT 1 to 1, 2ndosc REFERENCE COUNTER REF_S2 to REF_S1 */
409 c.ctl_dat[10].ctrl.size = BITS_3;
410 c.ctl_dat[10].data = 0x20;
411
412/* pulse byte */
413 c.ctl_dat[11].ctrl.size = BITS_3;
414 c.ctl_dat[11].ctrl.clk_off = 1;
415 c.ctl_dat[11].ctrl.cs1 = 1;
416 c.ctl_dat[11].data = 0x40;
417
418/* PGM_S18 to PGM_S11 */
419 c.ctl_dat[12].ctrl.size = BITS_8;
420 c.ctl_dat[12].data = 0x2a;
421
422/* PGM_S10 to PGM_S8 and SWL_S7 to SWL_S3 */
423 c.ctl_dat[13].ctrl.size = BITS_8;
424 c.ctl_dat[13].data = 0x8e;
425
426/* SWL_S2 and SWL_S1 and set CONTROL BIT 2 to 0 */
427 c.ctl_dat[14].ctrl.size = BITS_3;
428 c.ctl_dat[14].data = 0;
429
430/* Pulse Byte */
431 c.ctl_dat[15].ctrl.size = BITS_3;
432 c.ctl_dat[15].ctrl.clk_off = 1;
433 c.ctl_dat[15].ctrl.cs1 = 1;
434 c.ctl_dat[15].data = 0x40;
435
436 return bcm3510_do_hab_cmd(st,CMD_TUNE, MSGID_TUNE,(u8 *) &c,sizeof(c), NULL, 0);
437}
438
439static int bcm3510_set_freq(struct bcm3510_state* st,u32 freq)
440{
441 u8 bc,a;
442 u16 n;
443 s32 YIntercept,Tfvco1;
444
445 freq /= 1000;
446
447 deb_info("%dkHz:",freq);
448 /* set Band Switch */
449 if (freq <= 168000)
450 bc = 0x1c;
451 else if (freq <= 378000)
452 bc = 0x2c;
453 else
454 bc = 0x30;
455
456 if (freq >= 470000) {
457 freq -= 470001;
458 YIntercept = 18805;
459 } else if (freq >= 90000) {
460 freq -= 90001;
461 YIntercept = 15005;
462 } else if (freq >= 76000){
463 freq -= 76001;
464 YIntercept = 14865;
465 } else {
466 freq -= 54001;
467 YIntercept = 14645;
468 }
469
470 Tfvco1 = (((freq/6000)*60 + YIntercept)*4)/10;
471
472 n = Tfvco1 >> 6;
473 a = Tfvco1 & 0x3f;
474
475 deb_info(" BC1_2_3_4: %x, N: %x A: %x\n", bc, n, a);
476 if (n >= 16 && n <= 2047)
477 return bcm3510_tuner_cmd(st,bc,n,a);
478
479 return -EINVAL;
480}
481
482static int bcm3510_set_frontend(struct dvb_frontend* fe,
483 struct dvb_frontend_parameters *p)
484{
485 struct bcm3510_state* st = fe->demodulator_priv;
486 struct bcm3510_hab_cmd_ext_acquire cmd;
487 struct bcm3510_hab_cmd_bert_control bert;
488 int ret;
489
490 memset(&cmd,0,sizeof(cmd));
491 switch (p->u.vsb.modulation) {
492 case QAM_256:
493 cmd.ACQUIRE0.MODE = 0x1;
494 cmd.ACQUIRE1.SYM_RATE = 0x1;
495 cmd.ACQUIRE1.IF_FREQ = 0x1;
496 break;
497 case QAM_64:
498 cmd.ACQUIRE0.MODE = 0x2;
499 cmd.ACQUIRE1.SYM_RATE = 0x2;
500 cmd.ACQUIRE1.IF_FREQ = 0x1;
501 break;
502/* case QAM_256:
503 cmd.ACQUIRE0.MODE = 0x3;
504 break;
505 case QAM_128:
506 cmd.ACQUIRE0.MODE = 0x4;
507 break;
508 case QAM_64:
509 cmd.ACQUIRE0.MODE = 0x5;
510 break;
511 case QAM_32:
512 cmd.ACQUIRE0.MODE = 0x6;
513 break;
514 case QAM_16:
515 cmd.ACQUIRE0.MODE = 0x7;
516 break;*/
517 case VSB_8:
518 cmd.ACQUIRE0.MODE = 0x8;
519 cmd.ACQUIRE1.SYM_RATE = 0x0;
520 cmd.ACQUIRE1.IF_FREQ = 0x0;
521 break;
522 case VSB_16:
523 cmd.ACQUIRE0.MODE = 0x9;
524 cmd.ACQUIRE1.SYM_RATE = 0x0;
525 cmd.ACQUIRE1.IF_FREQ = 0x0;
526 default:
527 return -EINVAL;
528 };
529 cmd.ACQUIRE0.OFFSET = 0;
530 cmd.ACQUIRE0.NTSCSWEEP = 1;
531 cmd.ACQUIRE0.FA = 1;
532 cmd.ACQUIRE0.BW = 0;
533
534/* if (enableOffset) {
535 cmd.IF_OFFSET0 = xx;
536 cmd.IF_OFFSET1 = xx;
537
538 cmd.SYM_OFFSET0 = xx;
539 cmd.SYM_OFFSET1 = xx;
540 if (enableNtscSweep) {
541 cmd.NTSC_OFFSET0;
542 cmd.NTSC_OFFSET1;
543 }
544 } */
545 bcm3510_do_hab_cmd(st, CMD_ACQUIRE, MSGID_EXT_TUNER_ACQUIRE, (u8 *) &cmd, sizeof(cmd), NULL, 0);
546
547/* doing it with different MSGIDs, data book and source differs */
548 bert.BE = 0;
549 bert.unused = 0;
550 bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_CONTROL, (u8 *) &bert, sizeof(bert), NULL, 0);
551 bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_SET, (u8 *) &bert, sizeof(bert), NULL, 0);
552
553 bcm3510_bert_reset(st);
554
555 if ((ret = bcm3510_set_freq(st,p->frequency)) < 0)
556 return ret;
557
558 memset(&st->status1,0,sizeof(st->status1));
559 memset(&st->status2,0,sizeof(st->status2));
560 st->status_check_interval = 500;
561
562/* Give the AP some time */
563 msleep(200);
564
565 return 0;
566}
567
568static int bcm3510_sleep(struct dvb_frontend* fe)
569{
570 return 0;
571}
572
573static int bcm3510_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s)
574{
575 s->min_delay_ms = 1000;
576 s->step_size = 0;
577 s->max_drift = 0;
578 return 0;
579}
580
581static void bcm3510_release(struct dvb_frontend* fe)
582{
583 struct bcm3510_state* state = fe->demodulator_priv;
584 kfree(state);
585}
586
587/* firmware download:
588 * firmware file is build up like this:
589 * 16bit addr, 16bit length, 8byte of length
590 */
591#define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw"
592
593static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, const u8 *b,
594 u16 len)
595{
596 int ret = 0,i;
597 bcm3510_register_value vH, vL,vD;
598
599 vH.MADRH_a9 = addr >> 8;
600 vL.MADRL_aa = addr;
601 if ((ret = bcm3510_writeB(st,0xa9,vH)) < 0) return ret;
602 if ((ret = bcm3510_writeB(st,0xaa,vL)) < 0) return ret;
603
604 for (i = 0; i < len; i++) {
605 vD.MDATA_ab = b[i];
606 if ((ret = bcm3510_writeB(st,0xab,vD)) < 0)
607 return ret;
608 }
609
610 return 0;
611}
612
613static int bcm3510_download_firmware(struct dvb_frontend* fe)
614{
615 struct bcm3510_state* st = fe->demodulator_priv;
616 const struct firmware *fw;
617 u16 addr,len;
618 const u8 *b;
619 int ret,i;
620
621 deb_info("requesting firmware\n");
622 if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) {
623 err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
624 return ret;
625 }
626 deb_info("got firmware: %zd\n",fw->size);
627
628 b = fw->data;
629 for (i = 0; i < fw->size;) {
630 addr = le16_to_cpu( *( (u16 *)&b[i] ) );
631 len = le16_to_cpu( *( (u16 *)&b[i+2] ) );
632 deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size);
633 if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) {
634 err("firmware download failed: %d\n",ret);
635 return ret;
636 }
637 i += 4 + len;
638 }
639 release_firmware(fw);
640 deb_info("firmware download successfully completed\n");
641 return 0;
642}
643
644static int bcm3510_check_firmware_version(struct bcm3510_state *st)
645{
646 struct bcm3510_hab_cmd_get_version_info ver;
647 bcm3510_do_hab_cmd(st,CMD_GET_VERSION_INFO,MSGID_GET_VERSION_INFO,NULL,0,(u8*)&ver,sizeof(ver));
648
649 deb_info("Version information: 0x%02x 0x%02x 0x%02x 0x%02x\n",
650 ver.microcode_version, ver.script_version, ver.config_version, ver.demod_version);
651
652 if (ver.script_version == BCM3510_DEF_SCRIPT_VERSION &&
653 ver.config_version == BCM3510_DEF_CONFIG_VERSION &&
654 ver.demod_version == BCM3510_DEF_DEMOD_VERSION)
655 return 0;
656
657 deb_info("version check failed\n");
658 return -ENODEV;
659}
660
661/* (un)resetting the AP */
662static int bcm3510_reset(struct bcm3510_state *st)
663{
664 int ret;
665 unsigned long t;
666 bcm3510_register_value v;
667
668 bcm3510_readB(st,0xa0,&v); v.HCTL1_a0.RESET = 1;
669 if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
670 return ret;
671
672 t = jiffies + 3*HZ;
673 while (time_before(jiffies, t)) {
674 msleep(10);
675 if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
676 return ret;
677
678 if (v.APSTAT1_a2.RESET)
679 return 0;
680 }
681 deb_info("reset timed out\n");
682 return -ETIMEDOUT;
683}
684
685static int bcm3510_clear_reset(struct bcm3510_state *st)
686{
687 bcm3510_register_value v;
688 int ret;
689 unsigned long t;
690
691 v.raw = 0;
692 if ((ret = bcm3510_writeB(st,0xa0,v)) < 0)
693 return ret;
694
695 t = jiffies + 3*HZ;
696 while (time_before(jiffies, t)) {
697 msleep(10);
698 if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
699 return ret;
700
701 /* verify that reset is cleared */
702 if (!v.APSTAT1_a2.RESET)
703 return 0;
704 }
705 deb_info("reset clear timed out\n");
706 return -ETIMEDOUT;
707}
708
709static int bcm3510_init_cold(struct bcm3510_state *st)
710{
711 int ret;
712 bcm3510_register_value v;
713
714 /* read Acquisation Processor status register and check it is not in RUN mode */
715 if ((ret = bcm3510_readB(st,0xa2,&v)) < 0)
716 return ret;
717 if (v.APSTAT1_a2.RUN) {
718 deb_info("AP is already running - firmware already loaded.\n");
719 return 0;
720 }
721
722 deb_info("reset?\n");
723 if ((ret = bcm3510_reset(st)) < 0)
724 return ret;
725
726 deb_info("tristate?\n");
727 /* tri-state */
728 v.TSTCTL_2e.CTL = 0;
729 if ((ret = bcm3510_writeB(st,0x2e,v)) < 0)
730 return ret;
731
732 deb_info("firmware?\n");
733 if ((ret = bcm3510_download_firmware(&st->frontend)) < 0 ||
734 (ret = bcm3510_clear_reset(st)) < 0)
735 return ret;
736
737 /* anything left here to Let the acquisition processor begin execution at program counter 0000 ??? */
738
739 return 0;
740}
741
742static int bcm3510_init(struct dvb_frontend* fe)
743{
744 struct bcm3510_state* st = fe->demodulator_priv;
745 bcm3510_register_value j;
746 struct bcm3510_hab_cmd_set_agc c;
747 int ret;
748
749 if ((ret = bcm3510_readB(st,0xca,&j)) < 0)
750 return ret;
751
752 deb_info("JDEC: %02x\n",j.raw);
753
754 switch (j.JDEC_ca.JDEC) {
755 case JDEC_WAIT_AT_RAM:
756 deb_info("attempting to download firmware\n");
757 if ((ret = bcm3510_init_cold(st)) < 0)
758 return ret;
759 case JDEC_EEPROM_LOAD_WAIT: /* fall-through is wanted */
760 deb_info("firmware is loaded\n");
761 bcm3510_check_firmware_version(st);
762 break;
763 default:
764 return -ENODEV;
765 }
766
767 memset(&c,0,1);
768 c.SEL = 1;
769 bcm3510_do_hab_cmd(st,CMD_AUTO_PARAM,MSGID_SET_RF_AGC_SEL,(u8 *)&c,sizeof(c),NULL,0);
770
771 return 0;
772}
773
774
775static struct dvb_frontend_ops bcm3510_ops;
776
777struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config,
778 struct i2c_adapter *i2c)
779{
780 struct bcm3510_state* state = NULL;
781 int ret;
782 bcm3510_register_value v;
783
784 /* allocate memory for the internal state */
785 state = kzalloc(sizeof(struct bcm3510_state), GFP_KERNEL);
786 if (state == NULL)
787 goto error;
788
789 /* setup the state */
790
791 state->config = config;
792 state->i2c = i2c;
793
794 /* create dvb_frontend */
795 memcpy(&state->frontend.ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops));
796 state->frontend.demodulator_priv = state;
797
798 mutex_init(&state->hab_mutex);
799
800 if ((ret = bcm3510_readB(state,0xe0,&v)) < 0)
801 goto error;
802
803 deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER);
804
805 if ((v.REVID_e0.REV != 0x1 && v.REVID_e0.LAYER != 0xb) && /* cold */
806 (v.REVID_e0.REV != 0x8 && v.REVID_e0.LAYER != 0x0)) /* warm */
807 goto error;
808
809 info("Revision: 0x%1x, Layer: 0x%1x.",v.REVID_e0.REV,v.REVID_e0.LAYER);
810
811 bcm3510_reset(state);
812
813 return &state->frontend;
814
815error:
816 kfree(state);
817 return NULL;
818}
819EXPORT_SYMBOL(bcm3510_attach);
820
821static struct dvb_frontend_ops bcm3510_ops = {
822
823 .info = {
824 .name = "Broadcom BCM3510 VSB/QAM frontend",
825 .type = FE_ATSC,
826 .frequency_min = 54000000,
827 .frequency_max = 803000000,
828 /* stepsize is just a guess */
829 .frequency_stepsize = 0,
830 .caps =
831 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
832 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
833 FE_CAN_8VSB | FE_CAN_16VSB |
834 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256
835 },
836
837 .release = bcm3510_release,
838
839 .init = bcm3510_init,
840 .sleep = bcm3510_sleep,
841
842 .set_frontend = bcm3510_set_frontend,
843 .get_tune_settings = bcm3510_get_tune_settings,
844
845 .read_status = bcm3510_read_status,
846 .read_ber = bcm3510_read_ber,
847 .read_signal_strength = bcm3510_read_signal_strength,
848 .read_snr = bcm3510_read_snr,
849 .read_ucblocks = bcm3510_read_unc,
850};
851
852MODULE_DESCRIPTION("Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver");
853MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>");
854MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/bcm3510.h b/drivers/media/dvb/frontends/bcm3510.h
new file mode 100644
index 00000000000..f4575c0cc44
--- /dev/null
+++ b/drivers/media/dvb/frontends/bcm3510.h
@@ -0,0 +1,49 @@
1/*
2 * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
3 *
4 * Copyright (C) 2001-5, B2C2 inc.
5 *
6 * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
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#ifndef BCM3510_H
23#define BCM3510_H
24
25#include <linux/dvb/frontend.h>
26#include <linux/firmware.h>
27
28struct bcm3510_config
29{
30 /* the demodulator's i2c address */
31 u8 demod_address;
32
33 /* request firmware for device */
34 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
35};
36
37#if defined(CONFIG_DVB_BCM3510) || (defined(CONFIG_DVB_BCM3510_MODULE) && defined(MODULE))
38extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
39 struct i2c_adapter* i2c);
40#else
41static inline struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
42 struct i2c_adapter* i2c)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
45 return NULL;
46}
47#endif // CONFIG_DVB_BCM3510
48
49#endif
diff --git a/drivers/media/dvb/frontends/bcm3510_priv.h b/drivers/media/dvb/frontends/bcm3510_priv.h
new file mode 100644
index 00000000000..3bb1bc2a04f
--- /dev/null
+++ b/drivers/media/dvb/frontends/bcm3510_priv.h
@@ -0,0 +1,460 @@
1/*
2 * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC)
3 *
4 * Copyright (C) 2001-5, B2C2 inc.
5 *
6 * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de>
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#ifndef __BCM3510_PRIV_H__
23#define __BCM3510_PRIV_H__
24
25#define PACKED __attribute__((packed))
26
27#undef err
28#define err(format, arg...) printk(KERN_ERR "bcm3510: " format "\n" , ## arg)
29#undef info
30#define info(format, arg...) printk(KERN_INFO "bcm3510: " format "\n" , ## arg)
31#undef warn
32#define warn(format, arg...) printk(KERN_WARNING "bcm3510: " format "\n" , ## arg)
33
34
35#define PANASONIC_FIRST_IF_BASE_IN_KHz 1407500
36#define BCM3510_SYMBOL_RATE 5381000
37
38typedef union {
39 u8 raw;
40
41 struct {
42 u8 CTL :8;
43 } TSTCTL_2e;
44
45 u8 LDCERC_4e;
46 u8 LDUERC_4f;
47 u8 LD_BER0_65;
48 u8 LD_BER1_66;
49 u8 LD_BER2_67;
50 u8 LD_BER3_68;
51
52 struct {
53 u8 RESET :1;
54 u8 IDLE :1;
55 u8 STOP :1;
56 u8 HIRQ0 :1;
57 u8 HIRQ1 :1;
58 u8 na0 :1;
59 u8 HABAV :1;
60 u8 na1 :1;
61 } HCTL1_a0;
62
63 struct {
64 u8 na0 :1;
65 u8 IDLMSK :1;
66 u8 STMSK :1;
67 u8 I0MSK :1;
68 u8 I1MSK :1;
69 u8 na1 :1;
70 u8 HABMSK :1;
71 u8 na2 :1;
72 } HCTLMSK_a1;
73
74 struct {
75 u8 RESET :1;
76 u8 IDLE :1;
77 u8 STOP :1;
78 u8 RUN :1;
79 u8 HABAV :1;
80 u8 MEMAV :1;
81 u8 ALDONE :1;
82 u8 REIRQ :1;
83 } APSTAT1_a2;
84
85 struct {
86 u8 RSTMSK :1;
87 u8 IMSK :1;
88 u8 SMSK :1;
89 u8 RMSK :1;
90 u8 HABMSK :1;
91 u8 MAVMSK :1;
92 u8 ALDMSK :1;
93 u8 REMSK :1;
94 } APMSK1_a3;
95
96 u8 APSTAT2_a4;
97 u8 APMSK2_a5;
98
99 struct {
100 u8 HABADR :7;
101 u8 na :1;
102 } HABADR_a6;
103
104 u8 HABDATA_a7;
105
106 struct {
107 u8 HABR :1;
108 u8 LDHABR :1;
109 u8 APMSK :1;
110 u8 HMSK :1;
111 u8 LDMSK :1;
112 u8 na :3;
113 } HABSTAT_a8;
114
115 u8 MADRH_a9;
116 u8 MADRL_aa;
117 u8 MDATA_ab;
118
119 struct {
120#define JDEC_WAIT_AT_RAM 0x7
121#define JDEC_EEPROM_LOAD_WAIT 0x4
122 u8 JDEC :3;
123 u8 na :5;
124 } JDEC_ca;
125
126 struct {
127 u8 REV :4;
128 u8 LAYER :4;
129 } REVID_e0;
130
131 struct {
132 u8 unk0 :1;
133 u8 CNTCTL :1;
134 u8 BITCNT :1;
135 u8 unk1 :1;
136 u8 RESYNC :1;
137 u8 unk2 :3;
138 } BERCTL_fa;
139
140 struct {
141 u8 CSEL0 :1;
142 u8 CLKED0 :1;
143 u8 CSEL1 :1;
144 u8 CLKED1 :1;
145 u8 CLKLEV :1;
146 u8 SPIVAR :1;
147 u8 na :2;
148 } TUNSET_fc;
149
150 struct {
151 u8 CLK :1;
152 u8 DATA :1;
153 u8 CS0 :1;
154 u8 CS1 :1;
155 u8 AGCSEL :1;
156 u8 na0 :1;
157 u8 TUNSEL :1;
158 u8 na1 :1;
159 } TUNCTL_fd;
160
161 u8 TUNSEL0_fe;
162 u8 TUNSEL1_ff;
163
164} bcm3510_register_value;
165
166/* HAB commands */
167
168/* version */
169#define CMD_GET_VERSION_INFO 0x3D
170#define MSGID_GET_VERSION_INFO 0x15
171struct bcm3510_hab_cmd_get_version_info {
172 u8 microcode_version;
173 u8 script_version;
174 u8 config_version;
175 u8 demod_version;
176} PACKED;
177
178#define BCM3510_DEF_MICROCODE_VERSION 0x0E
179#define BCM3510_DEF_SCRIPT_VERSION 0x06
180#define BCM3510_DEF_CONFIG_VERSION 0x01
181#define BCM3510_DEF_DEMOD_VERSION 0xB1
182
183/* acquire */
184#define CMD_ACQUIRE 0x38
185
186#define MSGID_EXT_TUNER_ACQUIRE 0x0A
187struct bcm3510_hab_cmd_ext_acquire {
188 struct {
189 u8 MODE :4;
190 u8 BW :1;
191 u8 FA :1;
192 u8 NTSCSWEEP :1;
193 u8 OFFSET :1;
194 } PACKED ACQUIRE0; /* control_byte */
195
196 struct {
197 u8 IF_FREQ :3;
198 u8 zero0 :1;
199 u8 SYM_RATE :3;
200 u8 zero1 :1;
201 } PACKED ACQUIRE1; /* sym_if */
202
203 u8 IF_OFFSET0; /* IF_Offset_10hz */
204 u8 IF_OFFSET1;
205 u8 SYM_OFFSET0; /* SymbolRateOffset */
206 u8 SYM_OFFSET1;
207 u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */
208 u8 NTSC_OFFSET1;
209} PACKED;
210
211#define MSGID_INT_TUNER_ACQUIRE 0x0B
212struct bcm3510_hab_cmd_int_acquire {
213 struct {
214 u8 MODE :4;
215 u8 BW :1;
216 u8 FA :1;
217 u8 NTSCSWEEP :1;
218 u8 OFFSET :1;
219 } PACKED ACQUIRE0; /* control_byte */
220
221 struct {
222 u8 IF_FREQ :3;
223 u8 zero0 :1;
224 u8 SYM_RATE :3;
225 u8 zero1 :1;
226 } PACKED ACQUIRE1; /* sym_if */
227
228 u8 TUNER_FREQ0;
229 u8 TUNER_FREQ1;
230 u8 TUNER_FREQ2;
231 u8 TUNER_FREQ3;
232 u8 IF_OFFSET0; /* IF_Offset_10hz */
233 u8 IF_OFFSET1;
234 u8 SYM_OFFSET0; /* SymbolRateOffset */
235 u8 SYM_OFFSET1;
236 u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */
237 u8 NTSC_OFFSET1;
238} PACKED;
239
240/* modes */
241#define BCM3510_QAM16 = 0x01
242#define BCM3510_QAM32 = 0x02
243#define BCM3510_QAM64 = 0x03
244#define BCM3510_QAM128 = 0x04
245#define BCM3510_QAM256 = 0x05
246#define BCM3510_8VSB = 0x0B
247#define BCM3510_16VSB = 0x0D
248
249/* IF_FREQS */
250#define BCM3510_IF_TERRESTRIAL 0x0
251#define BCM3510_IF_CABLE 0x1
252#define BCM3510_IF_USE_CMD 0x7
253
254/* SYM_RATE */
255#define BCM3510_SR_8VSB 0x0 /* 5381119 s/sec */
256#define BCM3510_SR_256QAM 0x1 /* 5360537 s/sec */
257#define BCM3510_SR_16QAM 0x2 /* 5056971 s/sec */
258#define BCM3510_SR_MISC 0x3 /* 5000000 s/sec */
259#define BCM3510_SR_USE_CMD 0x7
260
261/* special symbol rate */
262#define CMD_SET_VALUE_NOT_LISTED 0x2d
263#define MSGID_SET_SYMBOL_RATE_NOT_LISTED 0x0c
264struct bcm3510_hab_cmd_set_sr_not_listed {
265 u8 HOST_SYM_RATE0;
266 u8 HOST_SYM_RATE1;
267 u8 HOST_SYM_RATE2;
268 u8 HOST_SYM_RATE3;
269} PACKED;
270
271/* special IF */
272#define MSGID_SET_IF_FREQ_NOT_LISTED 0x0d
273struct bcm3510_hab_cmd_set_if_freq_not_listed {
274 u8 HOST_IF_FREQ0;
275 u8 HOST_IF_FREQ1;
276 u8 HOST_IF_FREQ2;
277 u8 HOST_IF_FREQ3;
278} PACKED;
279
280/* auto reacquire */
281#define CMD_AUTO_PARAM 0x2a
282#define MSGID_AUTO_REACQUIRE 0x0e
283struct bcm3510_hab_cmd_auto_reacquire {
284 u8 ACQ :1; /* on/off*/
285 u8 unused :7;
286} PACKED;
287
288#define MSGID_SET_RF_AGC_SEL 0x12
289struct bcm3510_hab_cmd_set_agc {
290 u8 LVL :1;
291 u8 unused :6;
292 u8 SEL :1;
293} PACKED;
294
295#define MSGID_SET_AUTO_INVERSION 0x14
296struct bcm3510_hab_cmd_auto_inversion {
297 u8 AI :1;
298 u8 unused :7;
299} PACKED;
300
301
302/* bert control */
303#define CMD_STATE_CONTROL 0x12
304#define MSGID_BERT_CONTROL 0x0e
305#define MSGID_BERT_SET 0xfa
306struct bcm3510_hab_cmd_bert_control {
307 u8 BE :1;
308 u8 unused :7;
309} PACKED;
310
311#define MSGID_TRI_STATE 0x2e
312struct bcm3510_hab_cmd_tri_state {
313 u8 RE :1; /* a/d ram port pins */
314 u8 PE :1; /* baud clock pin */
315 u8 AC :1; /* a/d clock pin */
316 u8 BE :1; /* baud clock pin */
317 u8 unused :4;
318} PACKED;
319
320
321/* tune */
322#define CMD_TUNE 0x38
323#define MSGID_TUNE 0x16
324struct bcm3510_hab_cmd_tune_ctrl_data_pair {
325 struct {
326#define BITS_8 0x07
327#define BITS_7 0x06
328#define BITS_6 0x05
329#define BITS_5 0x04
330#define BITS_4 0x03
331#define BITS_3 0x02
332#define BITS_2 0x01
333#define BITS_1 0x00
334 u8 size :3;
335 u8 unk :2;
336 u8 clk_off :1;
337 u8 cs0 :1;
338 u8 cs1 :1;
339
340 } PACKED ctrl;
341
342 u8 data;
343} PACKED;
344
345struct bcm3510_hab_cmd_tune {
346 u8 length;
347 u8 clock_width;
348 u8 misc;
349 u8 TUNCTL_state;
350
351 struct bcm3510_hab_cmd_tune_ctrl_data_pair ctl_dat[16];
352} PACKED;
353
354#define CMD_STATUS 0x38
355#define MSGID_STATUS1 0x08
356struct bcm3510_hab_cmd_status1 {
357 struct {
358 u8 EQ_MODE :4;
359 u8 reserved :2;
360 u8 QRE :1; /* if QSE and the spectrum is inversed */
361 u8 QSE :1; /* automatic spectral inversion */
362 } PACKED STATUS0;
363
364 struct {
365 u8 RECEIVER_LOCK :1;
366 u8 FEC_LOCK :1;
367 u8 OUT_PLL_LOCK :1;
368 u8 reserved :5;
369 } PACKED STATUS1;
370
371 struct {
372 u8 reserved :2;
373 u8 BW :1;
374 u8 NTE :1; /* NTSC filter sweep enabled */
375 u8 AQI :1; /* currently acquiring */
376 u8 FA :1; /* fast acquisition */
377 u8 ARI :1; /* auto reacquire */
378 u8 TI :1; /* programming the tuner */
379 } PACKED STATUS2;
380 u8 STATUS3;
381 u8 SNR_EST0;
382 u8 SNR_EST1;
383 u8 TUNER_FREQ0;
384 u8 TUNER_FREQ1;
385 u8 TUNER_FREQ2;
386 u8 TUNER_FREQ3;
387 u8 SYM_RATE0;
388 u8 SYM_RATE1;
389 u8 SYM_RATE2;
390 u8 SYM_RATE3;
391 u8 SYM_OFFSET0;
392 u8 SYM_OFFSET1;
393 u8 SYM_ERROR0;
394 u8 SYM_ERROR1;
395 u8 IF_FREQ0;
396 u8 IF_FREQ1;
397 u8 IF_FREQ2;
398 u8 IF_FREQ3;
399 u8 IF_OFFSET0;
400 u8 IF_OFFSET1;
401 u8 IF_ERROR0;
402 u8 IF_ERROR1;
403 u8 NTSC_FILTER0;
404 u8 NTSC_FILTER1;
405 u8 NTSC_FILTER2;
406 u8 NTSC_FILTER3;
407 u8 NTSC_OFFSET0;
408 u8 NTSC_OFFSET1;
409 u8 NTSC_ERROR0;
410 u8 NTSC_ERROR1;
411 u8 INT_AGC_LEVEL0;
412 u8 INT_AGC_LEVEL1;
413 u8 EXT_AGC_LEVEL0;
414 u8 EXT_AGC_LEVEL1;
415} PACKED;
416
417#define MSGID_STATUS2 0x14
418struct bcm3510_hab_cmd_status2 {
419 struct {
420 u8 EQ_MODE :4;
421 u8 reserved :2;
422 u8 QRE :1;
423 u8 QSR :1;
424 } PACKED STATUS0;
425 struct {
426 u8 RL :1;
427 u8 FL :1;
428 u8 OL :1;
429 u8 reserved :5;
430 } PACKED STATUS1;
431 u8 SYMBOL_RATE0;
432 u8 SYMBOL_RATE1;
433 u8 SYMBOL_RATE2;
434 u8 SYMBOL_RATE3;
435 u8 LDCERC0;
436 u8 LDCERC1;
437 u8 LDCERC2;
438 u8 LDCERC3;
439 u8 LDUERC0;
440 u8 LDUERC1;
441 u8 LDUERC2;
442 u8 LDUERC3;
443 u8 LDBER0;
444 u8 LDBER1;
445 u8 LDBER2;
446 u8 LDBER3;
447 struct {
448 u8 MODE_TYPE :4; /* acquire mode 0 */
449 u8 reservd :4;
450 } MODE_TYPE;
451 u8 SNR_EST0;
452 u8 SNR_EST1;
453 u8 SIGNAL;
454} PACKED;
455
456#define CMD_SET_RF_BW_NOT_LISTED 0x3f
457#define MSGID_SET_RF_BW_NOT_LISTED 0x11
458/* TODO */
459
460#endif
diff --git a/drivers/media/dvb/frontends/bsbe1-d01a.h b/drivers/media/dvb/frontends/bsbe1-d01a.h
new file mode 100644
index 00000000000..7ed3c424178
--- /dev/null
+++ b/drivers/media/dvb/frontends/bsbe1-d01a.h
@@ -0,0 +1,146 @@
1/*
2 * bsbe1-d01a.h - ALPS BSBE1-D01A tuner support
3 *
4 * Copyright (C) 2011 Oliver Endriss <o.endriss@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
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 *
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 *
23 *
24 * the project's page is at http://www.linuxtv.org
25 */
26
27#ifndef BSBE1_D01A_H
28#define BSBE1_D01A_H
29
30#include "stb6000.h"
31#include "stv0288.h"
32
33static u8 stv0288_bsbe1_d01a_inittab[] = {
34 0x01, 0x15,
35 0x02, 0x20,
36 0x09, 0x0,
37 0x0a, 0x4,
38 0x0b, 0x0,
39 0x0c, 0x0,
40 0x0d, 0x0,
41 0x0e, 0xd4,
42 0x0f, 0x30,
43 0x11, 0x80,
44 0x12, 0x03,
45 0x13, 0x48,
46 0x14, 0x84,
47 0x15, 0x45,
48 0x16, 0xb7,
49 0x17, 0x9c,
50 0x18, 0x0,
51 0x19, 0xa6,
52 0x1a, 0x88,
53 0x1b, 0x8f,
54 0x1c, 0xf0,
55 0x20, 0x0b,
56 0x21, 0x54,
57 0x22, 0x0,
58 0x23, 0x0,
59 0x2b, 0xff,
60 0x2c, 0xf7,
61 0x30, 0x0,
62 0x31, 0x1e,
63 0x32, 0x14,
64 0x33, 0x0f,
65 0x34, 0x09,
66 0x35, 0x0c,
67 0x36, 0x05,
68 0x37, 0x2f,
69 0x38, 0x16,
70 0x39, 0xbd,
71 0x3a, 0x03,
72 0x3b, 0x13,
73 0x3c, 0x11,
74 0x3d, 0x30,
75 0x40, 0x63,
76 0x41, 0x04,
77 0x42, 0x60,
78 0x43, 0x00,
79 0x44, 0x00,
80 0x45, 0x00,
81 0x46, 0x00,
82 0x47, 0x00,
83 0x4a, 0x00,
84 0x50, 0x10,
85 0x51, 0x36,
86 0x52, 0x09,
87 0x53, 0x94,
88 0x54, 0x62,
89 0x55, 0x29,
90 0x56, 0x64,
91 0x57, 0x2b,
92 0x58, 0x54,
93 0x59, 0x86,
94 0x5a, 0x0,
95 0x5b, 0x9b,
96 0x5c, 0x08,
97 0x5d, 0x7f,
98 0x5e, 0x0,
99 0x5f, 0xff,
100 0x70, 0x0,
101 0x71, 0x0,
102 0x72, 0x0,
103 0x74, 0x0,
104 0x75, 0x0,
105 0x76, 0x0,
106 0x81, 0x0,
107 0x82, 0x3f,
108 0x83, 0x3f,
109 0x84, 0x0,
110 0x85, 0x0,
111 0x88, 0x0,
112 0x89, 0x0,
113 0x8a, 0x0,
114 0x8b, 0x0,
115 0x8c, 0x0,
116 0x90, 0x0,
117 0x91, 0x0,
118 0x92, 0x0,
119 0x93, 0x0,
120 0x94, 0x1c,
121 0x97, 0x0,
122 0xa0, 0x48,
123 0xa1, 0x0,
124 0xb0, 0xb8,
125 0xb1, 0x3a,
126 0xb2, 0x10,
127 0xb3, 0x82,
128 0xb4, 0x80,
129 0xb5, 0x82,
130 0xb6, 0x82,
131 0xb7, 0x82,
132 0xb8, 0x20,
133 0xb9, 0x0,
134 0xf0, 0x0,
135 0xf1, 0x0,
136 0xf2, 0xc0,
137 0xff, 0xff,
138};
139
140static struct stv0288_config stv0288_bsbe1_d01a_config = {
141 .demod_address = 0x68,
142 .min_delay_ms = 100,
143 .inittab = stv0288_bsbe1_d01a_inittab,
144};
145
146#endif
diff --git a/drivers/media/dvb/frontends/bsbe1.h b/drivers/media/dvb/frontends/bsbe1.h
new file mode 100644
index 00000000000..5e431ebd089
--- /dev/null
+++ b/drivers/media/dvb/frontends/bsbe1.h
@@ -0,0 +1,105 @@
1/*
2 * bsbe1.h - ALPS BSBE1 tuner support
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
20 *
21 *
22 * the project's page is at http://www.linuxtv.org
23 */
24
25#ifndef BSBE1_H
26#define BSBE1_H
27
28static u8 alps_bsbe1_inittab[] = {
29 0x01, 0x15, /* XTAL = 4MHz, VCO = 352 MHz */
30 0x02, 0x30, /* MCLK = 88 MHz */
31 0x03, 0x00, /* ACR output 0 */
32 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
33 0x05, 0x05, /* I2CT = 0, SCLT = 1, SDAT = 1 */
34 0x06, 0x00, /* DAC output 0 */
35 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
36 0x09, 0x00, /* FIFO */
37 0x0c, 0x51, /* OP1/OP0 normal, val = 1 (LNB power on) */
38 0x0d, 0x82, /* DC offset compensation = on, beta_agc1 = 2 */
39 0x0f, 0x92, /* AGC1R */
40 0x10, 0x34, /* AGC2O */
41 0x11, 0x84, /* TLSR */
42 0x12, 0xb9, /* CFD */
43 0x15, 0xc9, /* lock detector threshold */
44 0x28, 0x00, /* out imp: normal, type: parallel, FEC mode: QPSK */
45 0x33, 0xfc, /* RS control */
46 0x34, 0x93, /* count viterbi bit errors per 2E18 bytes */
47 0xff, 0xff
48};
49
50
51static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
52{
53 u8 aclk = 0;
54 u8 bclk = 0;
55
56 if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
57 else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
58 else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
59 else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
60 else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
61 else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
62
63 stv0299_writereg(fe, 0x13, aclk);
64 stv0299_writereg(fe, 0x14, bclk);
65 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
66 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
67 stv0299_writereg(fe, 0x21, (ratio ) & 0xf0);
68
69 return 0;
70}
71
72static int alps_bsbe1_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
73{
74 int ret;
75 u8 data[4];
76 u32 div;
77 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
78 struct i2c_adapter *i2c = fe->tuner_priv;
79
80 if ((params->frequency < 950000) || (params->frequency > 2150000))
81 return -EINVAL;
82
83 div = params->frequency / 1000;
84 data[0] = (div >> 8) & 0x7f;
85 data[1] = div & 0xff;
86 data[2] = 0x80 | ((div & 0x18000) >> 10) | 0x1;
87 data[3] = 0xe0;
88
89 if (fe->ops.i2c_gate_ctrl)
90 fe->ops.i2c_gate_ctrl(fe, 1);
91 ret = i2c_transfer(i2c, &msg, 1);
92 return (ret != 1) ? -EIO : 0;
93}
94
95static struct stv0299_config alps_bsbe1_config = {
96 .demod_address = 0x68,
97 .inittab = alps_bsbe1_inittab,
98 .mclk = 88000000UL,
99 .invert = 1,
100 .skip_reinit = 0,
101 .min_delay_ms = 100,
102 .set_symbol_rate = alps_bsbe1_set_symbol_rate,
103};
104
105#endif
diff --git a/drivers/media/dvb/frontends/bsru6.h b/drivers/media/dvb/frontends/bsru6.h
new file mode 100644
index 00000000000..c480c839b30
--- /dev/null
+++ b/drivers/media/dvb/frontends/bsru6.h
@@ -0,0 +1,142 @@
1/*
2 * bsru6.h - ALPS BSRU6 tuner support (moved from budget-ci.c)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
20 *
21 *
22 * the project's page is at http://www.linuxtv.org
23 */
24
25#ifndef BSRU6_H
26#define BSRU6_H
27
28static u8 alps_bsru6_inittab[] = {
29 0x01, 0x15,
30 0x02, 0x30,
31 0x03, 0x00,
32 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
33 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
34 0x06, 0x40, /* DAC not used, set to high impendance mode */
35 0x07, 0x00, /* DAC LSB */
36 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
37 0x09, 0x00, /* FIFO */
38 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
39 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
40 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
41 0x10, 0x3f, // AGC2 0x3d
42 0x11, 0x84,
43 0x12, 0xb9,
44 0x15, 0xc9, // lock detector threshold
45 0x16, 0x00,
46 0x17, 0x00,
47 0x18, 0x00,
48 0x19, 0x00,
49 0x1a, 0x00,
50 0x1f, 0x50,
51 0x20, 0x00,
52 0x21, 0x00,
53 0x22, 0x00,
54 0x23, 0x00,
55 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
56 0x29, 0x1e, // 1/2 threshold
57 0x2a, 0x14, // 2/3 threshold
58 0x2b, 0x0f, // 3/4 threshold
59 0x2c, 0x09, // 5/6 threshold
60 0x2d, 0x05, // 7/8 threshold
61 0x2e, 0x01,
62 0x31, 0x1f, // test all FECs
63 0x32, 0x19, // viterbi and synchro search
64 0x33, 0xfc, // rs control
65 0x34, 0x93, // error control
66 0x0f, 0x52,
67 0xff, 0xff
68};
69
70static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
71{
72 u8 aclk = 0;
73 u8 bclk = 0;
74
75 if (srate < 1500000) {
76 aclk = 0xb7;
77 bclk = 0x47;
78 } else if (srate < 3000000) {
79 aclk = 0xb7;
80 bclk = 0x4b;
81 } else if (srate < 7000000) {
82 aclk = 0xb7;
83 bclk = 0x4f;
84 } else if (srate < 14000000) {
85 aclk = 0xb7;
86 bclk = 0x53;
87 } else if (srate < 30000000) {
88 aclk = 0xb6;
89 bclk = 0x53;
90 } else if (srate < 45000000) {
91 aclk = 0xb4;
92 bclk = 0x51;
93 }
94
95 stv0299_writereg(fe, 0x13, aclk);
96 stv0299_writereg(fe, 0x14, bclk);
97 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
98 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
99 stv0299_writereg(fe, 0x21, ratio & 0xf0);
100
101 return 0;
102}
103
104static int alps_bsru6_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
105{
106 u8 buf[4];
107 u32 div;
108 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
109 struct i2c_adapter *i2c = fe->tuner_priv;
110
111 if ((params->frequency < 950000) || (params->frequency > 2150000))
112 return -EINVAL;
113
114 div = (params->frequency + (125 - 1)) / 125; // round correctly
115 buf[0] = (div >> 8) & 0x7f;
116 buf[1] = div & 0xff;
117 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
118 buf[3] = 0xC4;
119
120 if (params->frequency > 1530000)
121 buf[3] = 0xc0;
122
123 if (fe->ops.i2c_gate_ctrl)
124 fe->ops.i2c_gate_ctrl(fe, 1);
125 if (i2c_transfer(i2c, &msg, 1) != 1)
126 return -EIO;
127 return 0;
128}
129
130static struct stv0299_config alps_bsru6_config = {
131 .demod_address = 0x68,
132 .inittab = alps_bsru6_inittab,
133 .mclk = 88000000UL,
134 .invert = 1,
135 .skip_reinit = 0,
136 .lock_output = STV0299_LOCKOUTPUT_1,
137 .volt13_op0_op1 = STV0299_VOLT13_OP1,
138 .min_delay_ms = 100,
139 .set_symbol_rate = alps_bsru6_set_symbol_rate,
140};
141
142#endif
diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c
new file mode 100644
index 00000000000..0142214b013
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22700.c
@@ -0,0 +1,440 @@
1/*
2 Conexant cx22700 DVB OFDM demodulator driver
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 Holger Waechtler <holger@convergence.de>
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/kernel.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28#include "dvb_frontend.h"
29#include "cx22700.h"
30
31
32struct cx22700_state {
33
34 struct i2c_adapter* i2c;
35
36 const struct cx22700_config* config;
37
38 struct dvb_frontend frontend;
39};
40
41
42static int debug;
43#define dprintk(args...) \
44 do { \
45 if (debug) printk(KERN_DEBUG "cx22700: " args); \
46 } while (0)
47
48static u8 init_tab [] = {
49 0x04, 0x10,
50 0x05, 0x09,
51 0x06, 0x00,
52 0x08, 0x04,
53 0x09, 0x00,
54 0x0a, 0x01,
55 0x15, 0x40,
56 0x16, 0x10,
57 0x17, 0x87,
58 0x18, 0x17,
59 0x1a, 0x10,
60 0x25, 0x04,
61 0x2e, 0x00,
62 0x39, 0x00,
63 0x3a, 0x04,
64 0x45, 0x08,
65 0x46, 0x02,
66 0x47, 0x05,
67};
68
69
70static int cx22700_writereg (struct cx22700_state* state, u8 reg, u8 data)
71{
72 int ret;
73 u8 buf [] = { reg, data };
74 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
75
76 dprintk ("%s\n", __func__);
77
78 ret = i2c_transfer (state->i2c, &msg, 1);
79
80 if (ret != 1)
81 printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
82 __func__, reg, data, ret);
83
84 return (ret != 1) ? -1 : 0;
85}
86
87static int cx22700_readreg (struct cx22700_state* state, u8 reg)
88{
89 int ret;
90 u8 b0 [] = { reg };
91 u8 b1 [] = { 0 };
92 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
93 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
94
95 dprintk ("%s\n", __func__);
96
97 ret = i2c_transfer (state->i2c, msg, 2);
98
99 if (ret != 2) return -EIO;
100
101 return b1[0];
102}
103
104static int cx22700_set_inversion (struct cx22700_state* state, int inversion)
105{
106 u8 val;
107
108 dprintk ("%s\n", __func__);
109
110 switch (inversion) {
111 case INVERSION_AUTO:
112 return -EOPNOTSUPP;
113 case INVERSION_ON:
114 val = cx22700_readreg (state, 0x09);
115 return cx22700_writereg (state, 0x09, val | 0x01);
116 case INVERSION_OFF:
117 val = cx22700_readreg (state, 0x09);
118 return cx22700_writereg (state, 0x09, val & 0xfe);
119 default:
120 return -EINVAL;
121 }
122}
123
124static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_parameters *p)
125{
126 static const u8 qam_tab [4] = { 0, 1, 0, 2 };
127 static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 };
128 u8 val;
129
130 dprintk ("%s\n", __func__);
131
132 if (p->code_rate_HP < FEC_1_2 || p->code_rate_HP > FEC_7_8)
133 return -EINVAL;
134
135 if (p->code_rate_LP < FEC_1_2 || p->code_rate_LP > FEC_7_8)
136 return -EINVAL;
137
138 if (p->code_rate_HP == FEC_4_5 || p->code_rate_LP == FEC_4_5)
139 return -EINVAL;
140
141 if (p->guard_interval < GUARD_INTERVAL_1_32 ||
142 p->guard_interval > GUARD_INTERVAL_1_4)
143 return -EINVAL;
144
145 if (p->transmission_mode != TRANSMISSION_MODE_2K &&
146 p->transmission_mode != TRANSMISSION_MODE_8K)
147 return -EINVAL;
148
149 if (p->constellation != QPSK &&
150 p->constellation != QAM_16 &&
151 p->constellation != QAM_64)
152 return -EINVAL;
153
154 if (p->hierarchy_information < HIERARCHY_NONE ||
155 p->hierarchy_information > HIERARCHY_4)
156 return -EINVAL;
157
158 if (p->bandwidth < BANDWIDTH_8_MHZ || p->bandwidth > BANDWIDTH_6_MHZ)
159 return -EINVAL;
160
161 if (p->bandwidth == BANDWIDTH_7_MHZ)
162 cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 | 0x10));
163 else
164 cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 & ~0x10));
165
166 val = qam_tab[p->constellation - QPSK];
167 val |= p->hierarchy_information - HIERARCHY_NONE;
168
169 cx22700_writereg (state, 0x04, val);
170
171 val = fec_tab[p->code_rate_HP - FEC_1_2] << 3;
172 val |= fec_tab[p->code_rate_LP - FEC_1_2];
173
174 cx22700_writereg (state, 0x05, val);
175
176 val = (p->guard_interval - GUARD_INTERVAL_1_32) << 2;
177 val |= p->transmission_mode - TRANSMISSION_MODE_2K;
178
179 cx22700_writereg (state, 0x06, val);
180
181 cx22700_writereg (state, 0x08, 0x04 | 0x02); /* use user tps parameters */
182 cx22700_writereg (state, 0x08, 0x04); /* restart acquisition */
183
184 return 0;
185}
186
187static int cx22700_get_tps (struct cx22700_state* state, struct dvb_ofdm_parameters *p)
188{
189 static const fe_modulation_t qam_tab [3] = { QPSK, QAM_16, QAM_64 };
190 static const fe_code_rate_t fec_tab [5] = { FEC_1_2, FEC_2_3, FEC_3_4,
191 FEC_5_6, FEC_7_8 };
192 u8 val;
193
194 dprintk ("%s\n", __func__);
195
196 if (!(cx22700_readreg(state, 0x07) & 0x20)) /* tps valid? */
197 return -EAGAIN;
198
199 val = cx22700_readreg (state, 0x01);
200
201 if ((val & 0x7) > 4)
202 p->hierarchy_information = HIERARCHY_AUTO;
203 else
204 p->hierarchy_information = HIERARCHY_NONE + (val & 0x7);
205
206 if (((val >> 3) & 0x3) > 2)
207 p->constellation = QAM_AUTO;
208 else
209 p->constellation = qam_tab[(val >> 3) & 0x3];
210
211 val = cx22700_readreg (state, 0x02);
212
213 if (((val >> 3) & 0x07) > 4)
214 p->code_rate_HP = FEC_AUTO;
215 else
216 p->code_rate_HP = fec_tab[(val >> 3) & 0x07];
217
218 if ((val & 0x07) > 4)
219 p->code_rate_LP = FEC_AUTO;
220 else
221 p->code_rate_LP = fec_tab[val & 0x07];
222
223 val = cx22700_readreg (state, 0x03);
224
225 p->guard_interval = GUARD_INTERVAL_1_32 + ((val >> 6) & 0x3);
226 p->transmission_mode = TRANSMISSION_MODE_2K + ((val >> 5) & 0x1);
227
228 return 0;
229}
230
231static int cx22700_init (struct dvb_frontend* fe)
232
233{ struct cx22700_state* state = fe->demodulator_priv;
234 int i;
235
236 dprintk("cx22700_init: init chip\n");
237
238 cx22700_writereg (state, 0x00, 0x02); /* soft reset */
239 cx22700_writereg (state, 0x00, 0x00);
240
241 msleep(10);
242
243 for (i=0; i<sizeof(init_tab); i+=2)
244 cx22700_writereg (state, init_tab[i], init_tab[i+1]);
245
246 cx22700_writereg (state, 0x00, 0x01);
247
248 return 0;
249}
250
251static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status)
252{
253 struct cx22700_state* state = fe->demodulator_priv;
254
255 u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
256 | (cx22700_readreg (state, 0x0e) << 1);
257 u8 sync = cx22700_readreg (state, 0x07);
258
259 *status = 0;
260
261 if (rs_ber < 0xff00)
262 *status |= FE_HAS_SIGNAL;
263
264 if (sync & 0x20)
265 *status |= FE_HAS_CARRIER;
266
267 if (sync & 0x10)
268 *status |= FE_HAS_VITERBI;
269
270 if (sync & 0x10)
271 *status |= FE_HAS_SYNC;
272
273 if (*status == 0x0f)
274 *status |= FE_HAS_LOCK;
275
276 return 0;
277}
278
279static int cx22700_read_ber(struct dvb_frontend* fe, u32* ber)
280{
281 struct cx22700_state* state = fe->demodulator_priv;
282
283 *ber = cx22700_readreg (state, 0x0c) & 0x7f;
284 cx22700_writereg (state, 0x0c, 0x00);
285
286 return 0;
287}
288
289static int cx22700_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
290{
291 struct cx22700_state* state = fe->demodulator_priv;
292
293 u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
294 | (cx22700_readreg (state, 0x0e) << 1);
295 *signal_strength = ~rs_ber;
296
297 return 0;
298}
299
300static int cx22700_read_snr(struct dvb_frontend* fe, u16* snr)
301{
302 struct cx22700_state* state = fe->demodulator_priv;
303
304 u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9)
305 | (cx22700_readreg (state, 0x0e) << 1);
306 *snr = ~rs_ber;
307
308 return 0;
309}
310
311static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
312{
313 struct cx22700_state* state = fe->demodulator_priv;
314
315 *ucblocks = cx22700_readreg (state, 0x0f);
316 cx22700_writereg (state, 0x0f, 0x00);
317
318 return 0;
319}
320
321static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
322{
323 struct cx22700_state* state = fe->demodulator_priv;
324
325 cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/
326 cx22700_writereg (state, 0x00, 0x00);
327
328 if (fe->ops.tuner_ops.set_params) {
329 fe->ops.tuner_ops.set_params(fe, p);
330 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
331 }
332
333 cx22700_set_inversion (state, p->inversion);
334 cx22700_set_tps (state, &p->u.ofdm);
335 cx22700_writereg (state, 0x37, 0x01); /* PAL loop filter off */
336 cx22700_writereg (state, 0x00, 0x01); /* restart acquire */
337
338 return 0;
339}
340
341static int cx22700_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
342{
343 struct cx22700_state* state = fe->demodulator_priv;
344 u8 reg09 = cx22700_readreg (state, 0x09);
345
346 p->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF;
347 return cx22700_get_tps (state, &p->u.ofdm);
348}
349
350static int cx22700_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
351{
352 struct cx22700_state* state = fe->demodulator_priv;
353
354 if (enable) {
355 return cx22700_writereg(state, 0x0a, 0x00);
356 } else {
357 return cx22700_writereg(state, 0x0a, 0x01);
358 }
359}
360
361static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
362{
363 fesettings->min_delay_ms = 150;
364 fesettings->step_size = 166667;
365 fesettings->max_drift = 166667*2;
366 return 0;
367}
368
369static void cx22700_release(struct dvb_frontend* fe)
370{
371 struct cx22700_state* state = fe->demodulator_priv;
372 kfree(state);
373}
374
375static struct dvb_frontend_ops cx22700_ops;
376
377struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
378 struct i2c_adapter* i2c)
379{
380 struct cx22700_state* state = NULL;
381
382 /* allocate memory for the internal state */
383 state = kzalloc(sizeof(struct cx22700_state), GFP_KERNEL);
384 if (state == NULL) goto error;
385
386 /* setup the state */
387 state->config = config;
388 state->i2c = i2c;
389
390 /* check if the demod is there */
391 if (cx22700_readreg(state, 0x07) < 0) goto error;
392
393 /* create dvb_frontend */
394 memcpy(&state->frontend.ops, &cx22700_ops, sizeof(struct dvb_frontend_ops));
395 state->frontend.demodulator_priv = state;
396 return &state->frontend;
397
398error:
399 kfree(state);
400 return NULL;
401}
402
403static struct dvb_frontend_ops cx22700_ops = {
404
405 .info = {
406 .name = "Conexant CX22700 DVB-T",
407 .type = FE_OFDM,
408 .frequency_min = 470000000,
409 .frequency_max = 860000000,
410 .frequency_stepsize = 166667,
411 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
412 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
413 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
414 FE_CAN_RECOVER
415 },
416
417 .release = cx22700_release,
418
419 .init = cx22700_init,
420 .i2c_gate_ctrl = cx22700_i2c_gate_ctrl,
421
422 .set_frontend = cx22700_set_frontend,
423 .get_frontend = cx22700_get_frontend,
424 .get_tune_settings = cx22700_get_tune_settings,
425
426 .read_status = cx22700_read_status,
427 .read_ber = cx22700_read_ber,
428 .read_signal_strength = cx22700_read_signal_strength,
429 .read_snr = cx22700_read_snr,
430 .read_ucblocks = cx22700_read_ucblocks,
431};
432
433module_param(debug, int, 0644);
434MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
435
436MODULE_DESCRIPTION("Conexant CX22700 DVB-T Demodulator driver");
437MODULE_AUTHOR("Holger Waechtler");
438MODULE_LICENSE("GPL");
439
440EXPORT_SYMBOL(cx22700_attach);
diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h
new file mode 100644
index 00000000000..4757a930ca0
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22700.h
@@ -0,0 +1,46 @@
1/*
2 Conexant CX22700 DVB OFDM demodulator driver
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 Holger Waechtler <holger@convergence.de>
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#ifndef CX22700_H
24#define CX22700_H
25
26#include <linux/dvb/frontend.h>
27
28struct cx22700_config
29{
30 /* the demodulator's i2c address */
31 u8 demod_address;
32};
33
34#if defined(CONFIG_DVB_CX22700) || (defined(CONFIG_DVB_CX22700_MODULE) && defined(MODULE))
35extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
36 struct i2c_adapter* i2c);
37#else
38static inline struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
39 struct i2c_adapter* i2c)
40{
41 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
42 return NULL;
43}
44#endif // CONFIG_DVB_CX22700
45
46#endif // CX22700_H
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
new file mode 100644
index 00000000000..3139558148b
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -0,0 +1,638 @@
1/*
2 Conexant 22702 DVB OFDM demodulator driver
3
4 based on:
5 Alps TDMB7 DVB OFDM demodulator driver
6
7 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
8 Holger Waechtler <holger@convergence.de>
9
10 Copyright (C) 2004 Steven Toth <stoth@linuxtv.org>
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, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/string.h>
32#include <linux/slab.h>
33#include <linux/delay.h>
34#include "dvb_frontend.h"
35#include "cx22702.h"
36
37struct cx22702_state {
38
39 struct i2c_adapter *i2c;
40
41 /* configuration settings */
42 const struct cx22702_config *config;
43
44 struct dvb_frontend frontend;
45
46 /* previous uncorrected block counter */
47 u8 prevUCBlocks;
48};
49
50static int debug;
51module_param(debug, int, 0644);
52MODULE_PARM_DESC(debug, "Enable verbose debug messages");
53
54#define dprintk if (debug) printk
55
56/* Register values to initialise the demod */
57static const u8 init_tab[] = {
58 0x00, 0x00, /* Stop acquisition */
59 0x0B, 0x06,
60 0x09, 0x01,
61 0x0D, 0x41,
62 0x16, 0x32,
63 0x20, 0x0A,
64 0x21, 0x17,
65 0x24, 0x3e,
66 0x26, 0xff,
67 0x27, 0x10,
68 0x28, 0x00,
69 0x29, 0x00,
70 0x2a, 0x10,
71 0x2b, 0x00,
72 0x2c, 0x10,
73 0x2d, 0x00,
74 0x48, 0xd4,
75 0x49, 0x56,
76 0x6b, 0x1e,
77 0xc8, 0x02,
78 0xf9, 0x00,
79 0xfa, 0x00,
80 0xfb, 0x00,
81 0xfc, 0x00,
82 0xfd, 0x00,
83};
84
85static int cx22702_writereg(struct cx22702_state *state, u8 reg, u8 data)
86{
87 int ret;
88 u8 buf[] = { reg, data };
89 struct i2c_msg msg = {
90 .addr = state->config->demod_address, .flags = 0,
91 .buf = buf, .len = 2 };
92
93 ret = i2c_transfer(state->i2c, &msg, 1);
94
95 if (unlikely(ret != 1)) {
96 printk(KERN_ERR
97 "%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
98 __func__, reg, data, ret);
99 return -1;
100 }
101
102 return 0;
103}
104
105static u8 cx22702_readreg(struct cx22702_state *state, u8 reg)
106{
107 int ret;
108 u8 data;
109
110 struct i2c_msg msg[] = {
111 { .addr = state->config->demod_address, .flags = 0,
112 .buf = &reg, .len = 1 },
113 { .addr = state->config->demod_address, .flags = I2C_M_RD,
114 .buf = &data, .len = 1 } };
115
116 ret = i2c_transfer(state->i2c, msg, 2);
117
118 if (unlikely(ret != 2)) {
119 printk(KERN_ERR "%s: error (reg == 0x%02x, ret == %i)\n",
120 __func__, reg, ret);
121 return 0;
122 }
123
124 return data;
125}
126
127static int cx22702_set_inversion(struct cx22702_state *state, int inversion)
128{
129 u8 val;
130
131 val = cx22702_readreg(state, 0x0C);
132 switch (inversion) {
133 case INVERSION_AUTO:
134 return -EOPNOTSUPP;
135 case INVERSION_ON:
136 val |= 0x01;
137 break;
138 case INVERSION_OFF:
139 val &= 0xfe;
140 break;
141 default:
142 return -EINVAL;
143 }
144 return cx22702_writereg(state, 0x0C, val);
145}
146
147/* Retrieve the demod settings */
148static int cx22702_get_tps(struct cx22702_state *state,
149 struct dvb_ofdm_parameters *p)
150{
151 u8 val;
152
153 /* Make sure the TPS regs are valid */
154 if (!(cx22702_readreg(state, 0x0A) & 0x20))
155 return -EAGAIN;
156
157 val = cx22702_readreg(state, 0x01);
158 switch ((val & 0x18) >> 3) {
159 case 0:
160 p->constellation = QPSK;
161 break;
162 case 1:
163 p->constellation = QAM_16;
164 break;
165 case 2:
166 p->constellation = QAM_64;
167 break;
168 }
169 switch (val & 0x07) {
170 case 0:
171 p->hierarchy_information = HIERARCHY_NONE;
172 break;
173 case 1:
174 p->hierarchy_information = HIERARCHY_1;
175 break;
176 case 2:
177 p->hierarchy_information = HIERARCHY_2;
178 break;
179 case 3:
180 p->hierarchy_information = HIERARCHY_4;
181 break;
182 }
183
184
185 val = cx22702_readreg(state, 0x02);
186 switch ((val & 0x38) >> 3) {
187 case 0:
188 p->code_rate_HP = FEC_1_2;
189 break;
190 case 1:
191 p->code_rate_HP = FEC_2_3;
192 break;
193 case 2:
194 p->code_rate_HP = FEC_3_4;
195 break;
196 case 3:
197 p->code_rate_HP = FEC_5_6;
198 break;
199 case 4:
200 p->code_rate_HP = FEC_7_8;
201 break;
202 }
203 switch (val & 0x07) {
204 case 0:
205 p->code_rate_LP = FEC_1_2;
206 break;
207 case 1:
208 p->code_rate_LP = FEC_2_3;
209 break;
210 case 2:
211 p->code_rate_LP = FEC_3_4;
212 break;
213 case 3:
214 p->code_rate_LP = FEC_5_6;
215 break;
216 case 4:
217 p->code_rate_LP = FEC_7_8;
218 break;
219 }
220
221 val = cx22702_readreg(state, 0x03);
222 switch ((val & 0x0c) >> 2) {
223 case 0:
224 p->guard_interval = GUARD_INTERVAL_1_32;
225 break;
226 case 1:
227 p->guard_interval = GUARD_INTERVAL_1_16;
228 break;
229 case 2:
230 p->guard_interval = GUARD_INTERVAL_1_8;
231 break;
232 case 3:
233 p->guard_interval = GUARD_INTERVAL_1_4;
234 break;
235 }
236 switch (val & 0x03) {
237 case 0:
238 p->transmission_mode = TRANSMISSION_MODE_2K;
239 break;
240 case 1:
241 p->transmission_mode = TRANSMISSION_MODE_8K;
242 break;
243 }
244
245 return 0;
246}
247
248static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
249{
250 struct cx22702_state *state = fe->demodulator_priv;
251 u8 val;
252
253 dprintk("%s(%d)\n", __func__, enable);
254 val = cx22702_readreg(state, 0x0D);
255 if (enable)
256 val &= 0xfe;
257 else
258 val |= 0x01;
259 return cx22702_writereg(state, 0x0D, val);
260}
261
262/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
263static int cx22702_set_tps(struct dvb_frontend *fe,
264 struct dvb_frontend_parameters *p)
265{
266 u8 val;
267 struct cx22702_state *state = fe->demodulator_priv;
268
269 if (fe->ops.tuner_ops.set_params) {
270 fe->ops.tuner_ops.set_params(fe, p);
271 if (fe->ops.i2c_gate_ctrl)
272 fe->ops.i2c_gate_ctrl(fe, 0);
273 }
274
275 /* set inversion */
276 cx22702_set_inversion(state, p->inversion);
277
278 /* set bandwidth */
279 val = cx22702_readreg(state, 0x0C) & 0xcf;
280 switch (p->u.ofdm.bandwidth) {
281 case BANDWIDTH_6_MHZ:
282 val |= 0x20;
283 break;
284 case BANDWIDTH_7_MHZ:
285 val |= 0x10;
286 break;
287 case BANDWIDTH_8_MHZ:
288 break;
289 default:
290 dprintk("%s: invalid bandwidth\n", __func__);
291 return -EINVAL;
292 }
293 cx22702_writereg(state, 0x0C, val);
294
295 p->u.ofdm.code_rate_LP = FEC_AUTO; /* temp hack as manual not working */
296
297 /* use auto configuration? */
298 if ((p->u.ofdm.hierarchy_information == HIERARCHY_AUTO) ||
299 (p->u.ofdm.constellation == QAM_AUTO) ||
300 (p->u.ofdm.code_rate_HP == FEC_AUTO) ||
301 (p->u.ofdm.code_rate_LP == FEC_AUTO) ||
302 (p->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO) ||
303 (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO)) {
304
305 /* TPS Source - use hardware driven values */
306 cx22702_writereg(state, 0x06, 0x10);
307 cx22702_writereg(state, 0x07, 0x9);
308 cx22702_writereg(state, 0x08, 0xC1);
309 cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B)
310 & 0xfc);
311 cx22702_writereg(state, 0x0C,
312 (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40);
313 cx22702_writereg(state, 0x00, 0x01); /* Begin acquisition */
314 dprintk("%s: Autodetecting\n", __func__);
315 return 0;
316 }
317
318 /* manually programmed values */
319 switch (p->u.ofdm.constellation) { /* mask 0x18 */
320 case QPSK:
321 val = 0x00;
322 break;
323 case QAM_16:
324 val = 0x08;
325 break;
326 case QAM_64:
327 val = 0x10;
328 break;
329 default:
330 dprintk("%s: invalid constellation\n", __func__);
331 return -EINVAL;
332 }
333 switch (p->u.ofdm.hierarchy_information) { /* mask 0x07 */
334 case HIERARCHY_NONE:
335 break;
336 case HIERARCHY_1:
337 val |= 0x01;
338 break;
339 case HIERARCHY_2:
340 val |= 0x02;
341 break;
342 case HIERARCHY_4:
343 val |= 0x03;
344 break;
345 default:
346 dprintk("%s: invalid hierarchy\n", __func__);
347 return -EINVAL;
348 }
349 cx22702_writereg(state, 0x06, val);
350
351 switch (p->u.ofdm.code_rate_HP) { /* mask 0x38 */
352 case FEC_NONE:
353 case FEC_1_2:
354 val = 0x00;
355 break;
356 case FEC_2_3:
357 val = 0x08;
358 break;
359 case FEC_3_4:
360 val = 0x10;
361 break;
362 case FEC_5_6:
363 val = 0x18;
364 break;
365 case FEC_7_8:
366 val = 0x20;
367 break;
368 default:
369 dprintk("%s: invalid code_rate_HP\n", __func__);
370 return -EINVAL;
371 }
372 switch (p->u.ofdm.code_rate_LP) { /* mask 0x07 */
373 case FEC_NONE:
374 case FEC_1_2:
375 break;
376 case FEC_2_3:
377 val |= 0x01;
378 break;
379 case FEC_3_4:
380 val |= 0x02;
381 break;
382 case FEC_5_6:
383 val |= 0x03;
384 break;
385 case FEC_7_8:
386 val |= 0x04;
387 break;
388 default:
389 dprintk("%s: invalid code_rate_LP\n", __func__);
390 return -EINVAL;
391 }
392 cx22702_writereg(state, 0x07, val);
393
394 switch (p->u.ofdm.guard_interval) { /* mask 0x0c */
395 case GUARD_INTERVAL_1_32:
396 val = 0x00;
397 break;
398 case GUARD_INTERVAL_1_16:
399 val = 0x04;
400 break;
401 case GUARD_INTERVAL_1_8:
402 val = 0x08;
403 break;
404 case GUARD_INTERVAL_1_4:
405 val = 0x0c;
406 break;
407 default:
408 dprintk("%s: invalid guard_interval\n", __func__);
409 return -EINVAL;
410 }
411 switch (p->u.ofdm.transmission_mode) { /* mask 0x03 */
412 case TRANSMISSION_MODE_2K:
413 break;
414 case TRANSMISSION_MODE_8K:
415 val |= 0x1;
416 break;
417 default:
418 dprintk("%s: invalid transmission_mode\n", __func__);
419 return -EINVAL;
420 }
421 cx22702_writereg(state, 0x08, val);
422 cx22702_writereg(state, 0x0B,
423 (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02);
424 cx22702_writereg(state, 0x0C,
425 (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40);
426
427 /* Begin channel acquisition */
428 cx22702_writereg(state, 0x00, 0x01);
429
430 return 0;
431}
432
433/* Reset the demod hardware and reset all of the configuration registers
434 to a default state. */
435static int cx22702_init(struct dvb_frontend *fe)
436{
437 int i;
438 struct cx22702_state *state = fe->demodulator_priv;
439
440 cx22702_writereg(state, 0x00, 0x02);
441
442 msleep(10);
443
444 for (i = 0; i < ARRAY_SIZE(init_tab); i += 2)
445 cx22702_writereg(state, init_tab[i], init_tab[i + 1]);
446
447 cx22702_writereg(state, 0xf8, (state->config->output_mode << 1)
448 & 0x02);
449
450 cx22702_i2c_gate_ctrl(fe, 0);
451
452 return 0;
453}
454
455static int cx22702_read_status(struct dvb_frontend *fe, fe_status_t *status)
456{
457 struct cx22702_state *state = fe->demodulator_priv;
458 u8 reg0A;
459 u8 reg23;
460
461 *status = 0;
462
463 reg0A = cx22702_readreg(state, 0x0A);
464 reg23 = cx22702_readreg(state, 0x23);
465
466 dprintk("%s: status demod=0x%02x agc=0x%02x\n"
467 , __func__, reg0A, reg23);
468
469 if (reg0A & 0x10) {
470 *status |= FE_HAS_LOCK;
471 *status |= FE_HAS_VITERBI;
472 *status |= FE_HAS_SYNC;
473 }
474
475 if (reg0A & 0x20)
476 *status |= FE_HAS_CARRIER;
477
478 if (reg23 < 0xf0)
479 *status |= FE_HAS_SIGNAL;
480
481 return 0;
482}
483
484static int cx22702_read_ber(struct dvb_frontend *fe, u32 *ber)
485{
486 struct cx22702_state *state = fe->demodulator_priv;
487
488 if (cx22702_readreg(state, 0xE4) & 0x02) {
489 /* Realtime statistics */
490 *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
491 | (cx22702_readreg(state, 0xDF) & 0x7F);
492 } else {
493 /* Averagtine statistics */
494 *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
495 | cx22702_readreg(state, 0xDF);
496 }
497
498 return 0;
499}
500
501static int cx22702_read_signal_strength(struct dvb_frontend *fe,
502 u16 *signal_strength)
503{
504 struct cx22702_state *state = fe->demodulator_priv;
505
506 u16 rs_ber;
507 rs_ber = cx22702_readreg(state, 0x23);
508 *signal_strength = (rs_ber << 8) | rs_ber;
509
510 return 0;
511}
512
513static int cx22702_read_snr(struct dvb_frontend *fe, u16 *snr)
514{
515 struct cx22702_state *state = fe->demodulator_priv;
516
517 u16 rs_ber;
518 if (cx22702_readreg(state, 0xE4) & 0x02) {
519 /* Realtime statistics */
520 rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
521 | (cx22702_readreg(state, 0xDF) & 0x7F);
522 } else {
523 /* Averagine statistics */
524 rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 8
525 | cx22702_readreg(state, 0xDF);
526 }
527 *snr = ~rs_ber;
528
529 return 0;
530}
531
532static int cx22702_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
533{
534 struct cx22702_state *state = fe->demodulator_priv;
535
536 u8 _ucblocks;
537
538 /* RS Uncorrectable Packet Count then reset */
539 _ucblocks = cx22702_readreg(state, 0xE3);
540 if (state->prevUCBlocks < _ucblocks)
541 *ucblocks = (_ucblocks - state->prevUCBlocks);
542 else
543 *ucblocks = state->prevUCBlocks - _ucblocks;
544 state->prevUCBlocks = _ucblocks;
545
546 return 0;
547}
548
549static int cx22702_get_frontend(struct dvb_frontend *fe,
550 struct dvb_frontend_parameters *p)
551{
552 struct cx22702_state *state = fe->demodulator_priv;
553
554 u8 reg0C = cx22702_readreg(state, 0x0C);
555
556 p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF;
557 return cx22702_get_tps(state, &p->u.ofdm);
558}
559
560static int cx22702_get_tune_settings(struct dvb_frontend *fe,
561 struct dvb_frontend_tune_settings *tune)
562{
563 tune->min_delay_ms = 1000;
564 return 0;
565}
566
567static void cx22702_release(struct dvb_frontend *fe)
568{
569 struct cx22702_state *state = fe->demodulator_priv;
570 kfree(state);
571}
572
573static const struct dvb_frontend_ops cx22702_ops;
574
575struct dvb_frontend *cx22702_attach(const struct cx22702_config *config,
576 struct i2c_adapter *i2c)
577{
578 struct cx22702_state *state = NULL;
579
580 /* allocate memory for the internal state */
581 state = kzalloc(sizeof(struct cx22702_state), GFP_KERNEL);
582 if (state == NULL)
583 goto error;
584
585 /* setup the state */
586 state->config = config;
587 state->i2c = i2c;
588
589 /* check if the demod is there */
590 if (cx22702_readreg(state, 0x1f) != 0x3)
591 goto error;
592
593 /* create dvb_frontend */
594 memcpy(&state->frontend.ops, &cx22702_ops,
595 sizeof(struct dvb_frontend_ops));
596 state->frontend.demodulator_priv = state;
597 return &state->frontend;
598
599error:
600 kfree(state);
601 return NULL;
602}
603EXPORT_SYMBOL(cx22702_attach);
604
605static const struct dvb_frontend_ops cx22702_ops = {
606
607 .info = {
608 .name = "Conexant CX22702 DVB-T",
609 .type = FE_OFDM,
610 .frequency_min = 177000000,
611 .frequency_max = 858000000,
612 .frequency_stepsize = 166666,
613 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
614 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
615 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
616 FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
617 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
618 },
619
620 .release = cx22702_release,
621
622 .init = cx22702_init,
623 .i2c_gate_ctrl = cx22702_i2c_gate_ctrl,
624
625 .set_frontend = cx22702_set_tps,
626 .get_frontend = cx22702_get_frontend,
627 .get_tune_settings = cx22702_get_tune_settings,
628
629 .read_status = cx22702_read_status,
630 .read_ber = cx22702_read_ber,
631 .read_signal_strength = cx22702_read_signal_strength,
632 .read_snr = cx22702_read_snr,
633 .read_ucblocks = cx22702_read_ucblocks,
634};
635
636MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver");
637MODULE_AUTHOR("Steven Toth");
638MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
new file mode 100644
index 00000000000..f154e1f428e
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -0,0 +1,58 @@
1/*
2 Conexant 22702 DVB OFDM demodulator driver
3
4 based on:
5 Alps TDMB7 DVB OFDM demodulator driver
6
7 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
8 Holger Waechtler <holger@convergence.de>
9
10 Copyright (C) 2004 Steven Toth <stoth@linuxtv.org>
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, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27
28#ifndef CX22702_H
29#define CX22702_H
30
31#include <linux/dvb/frontend.h>
32
33struct cx22702_config {
34 /* the demodulator's i2c address */
35 u8 demod_address;
36
37 /* serial/parallel output */
38#define CX22702_PARALLEL_OUTPUT 0
39#define CX22702_SERIAL_OUTPUT 1
40 u8 output_mode;
41};
42
43#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) \
44 && defined(MODULE))
45extern struct dvb_frontend *cx22702_attach(
46 const struct cx22702_config *config,
47 struct i2c_adapter *i2c);
48#else
49static inline struct dvb_frontend *cx22702_attach(
50 const struct cx22702_config *config,
51 struct i2c_adapter *i2c)
52{
53 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
54 return NULL;
55}
56#endif
57
58#endif
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
new file mode 100644
index 00000000000..bf9c999aa47
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -0,0 +1,667 @@
1/*
2 cx24110 - Single Chip Satellite Channel Receiver driver module
3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
5 work
6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
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
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., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23*/
24
25#include <linux/slab.h>
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/init.h>
29
30#include "dvb_frontend.h"
31#include "cx24110.h"
32
33
34struct cx24110_state {
35
36 struct i2c_adapter* i2c;
37
38 const struct cx24110_config* config;
39
40 struct dvb_frontend frontend;
41
42 u32 lastber;
43 u32 lastbler;
44 u32 lastesn0;
45};
46
47static int debug;
48#define dprintk(args...) \
49 do { \
50 if (debug) printk(KERN_DEBUG "cx24110: " args); \
51 } while (0)
52
53static struct {u8 reg; u8 data;} cx24110_regdata[]=
54 /* Comments beginning with @ denote this value should
55 be the default */
56 {{0x09,0x01}, /* SoftResetAll */
57 {0x09,0x00}, /* release reset */
58 {0x01,0xe8}, /* MSB of code rate 27.5MS/s */
59 {0x02,0x17}, /* middle byte " */
60 {0x03,0x29}, /* LSB " */
61 {0x05,0x03}, /* @ DVB mode, standard code rate 3/4 */
62 {0x06,0xa5}, /* @ PLL 60MHz */
63 {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */
64 {0x0a,0x00}, /* @ partial chip disables, do not set */
65 {0x0b,0x01}, /* set output clock in gapped mode, start signal low
66 active for first byte */
67 {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */
68 {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */
69 {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1
70 to avoid starting the BER counter. Reset the
71 CRC test bit. Finite counting selected */
72 {0x15,0xff}, /* @ size of the limited time window for RS BER
73 estimation. It is <value>*256 RS blocks, this
74 gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */
75 {0x16,0x00}, /* @ enable all RS output ports */
76 {0x17,0x04}, /* @ time window allowed for the RS to sync */
77 {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned
78 for automatically */
79 /* leave the current code rate and normalization
80 registers as they are after reset... */
81 {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting
82 only once */
83 {0x23,0x18}, /* @ size of the limited time window for Viterbi BER
84 estimation. It is <value>*65536 channel bits, i.e.
85 approx. 38ms at 27.5MS/s, rate 3/4 */
86 {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */
87 /* leave front-end AGC parameters at default values */
88 /* leave decimation AGC parameters at default values */
89 {0x35,0x40}, /* disable all interrupts. They are not connected anyway */
90 {0x36,0xff}, /* clear all interrupt pending flags */
91 {0x37,0x00}, /* @ fully enable AutoAcqq state machine */
92 {0x38,0x07}, /* @ enable fade recovery, but not autostart AutoAcq */
93 /* leave the equalizer parameters on their default values */
94 /* leave the final AGC parameters on their default values */
95 {0x41,0x00}, /* @ MSB of front-end derotator frequency */
96 {0x42,0x00}, /* @ middle bytes " */
97 {0x43,0x00}, /* @ LSB " */
98 /* leave the carrier tracking loop parameters on default */
99 /* leave the bit timing loop parameters at default */
100 {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */
101 /* the cx24108 data sheet for symbol rates above 15MS/s */
102 {0x57,0x00}, /* @ Filter sigma delta enabled, positive */
103 {0x61,0x95}, /* GPIO pins 1-4 have special function */
104 {0x62,0x05}, /* GPIO pin 5 has special function, pin 6 is GPIO */
105 {0x63,0x00}, /* All GPIO pins use CMOS output characteristics */
106 {0x64,0x20}, /* GPIO 6 is input, all others are outputs */
107 {0x6d,0x30}, /* tuner auto mode clock freq 62kHz */
108 {0x70,0x15}, /* use auto mode, tuner word is 21 bits long */
109 {0x73,0x00}, /* @ disable several demod bypasses */
110 {0x74,0x00}, /* @ " */
111 {0x75,0x00} /* @ " */
112 /* the remaining registers are for SEC */
113 };
114
115
116static int cx24110_writereg (struct cx24110_state* state, int reg, int data)
117{
118 u8 buf [] = { reg, data };
119 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
120 int err;
121
122 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
123 dprintk ("%s: writereg error (err == %i, reg == 0x%02x,"
124 " data == 0x%02x)\n", __func__, err, reg, data);
125 return -EREMOTEIO;
126 }
127
128 return 0;
129}
130
131static int cx24110_readreg (struct cx24110_state* state, u8 reg)
132{
133 int ret;
134 u8 b0 [] = { reg };
135 u8 b1 [] = { 0 };
136 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
137 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
138
139 ret = i2c_transfer(state->i2c, msg, 2);
140
141 if (ret != 2) return ret;
142
143 return b1[0];
144}
145
146static int cx24110_set_inversion (struct cx24110_state* state, fe_spectral_inversion_t inversion)
147{
148/* fixme (low): error handling */
149
150 switch (inversion) {
151 case INVERSION_OFF:
152 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
153 /* AcqSpectrInvDis on. No idea why someone should want this */
154 cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)&0xf7);
155 /* Initial value 0 at start of acq */
156 cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)&0xef);
157 /* current value 0 */
158 /* The cx24110 manual tells us this reg is read-only.
159 But what the heck... set it ayways */
160 break;
161 case INVERSION_ON:
162 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1);
163 /* AcqSpectrInvDis on. No idea why someone should want this */
164 cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)|0x08);
165 /* Initial value 1 at start of acq */
166 cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)|0x10);
167 /* current value 1 */
168 break;
169 case INVERSION_AUTO:
170 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xfe);
171 /* AcqSpectrInvDis off. Leave initial & current states as is */
172 break;
173 default:
174 return -EINVAL;
175 }
176
177 return 0;
178}
179
180static int cx24110_set_fec (struct cx24110_state* state, fe_code_rate_t fec)
181{
182/* fixme (low): error handling */
183
184 static const int rate[]={-1,1,2,3,5,7,-1};
185 static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1};
186 static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1};
187
188 /* Well, the AutoAcq engine of the cx24106 and 24110 automatically
189 searches all enabled viterbi rates, and can handle non-standard
190 rates as well. */
191
192 if (fec>FEC_AUTO)
193 fec=FEC_AUTO;
194
195 if (fec==FEC_AUTO) { /* (re-)establish AutoAcq behaviour */
196 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xdf);
197 /* clear AcqVitDis bit */
198 cx24110_writereg(state,0x18,0xae);
199 /* allow all DVB standard code rates */
200 cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|0x3);
201 /* set nominal Viterbi rate 3/4 */
202 cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|0x3);
203 /* set current Viterbi rate 3/4 */
204 cx24110_writereg(state,0x1a,0x05); cx24110_writereg(state,0x1b,0x06);
205 /* set the puncture registers for code rate 3/4 */
206 return 0;
207 } else {
208 cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x20);
209 /* set AcqVitDis bit */
210 if(rate[fec]>0) {
211 cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|rate[fec]);
212 /* set nominal Viterbi rate */
213 cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|rate[fec]);
214 /* set current Viterbi rate */
215 cx24110_writereg(state,0x1a,g1[fec]);
216 cx24110_writereg(state,0x1b,g2[fec]);
217 /* not sure if this is the right way: I always used AutoAcq mode */
218 } else
219 return -EOPNOTSUPP;
220/* fixme (low): which is the correct return code? */
221 };
222 return 0;
223}
224
225static fe_code_rate_t cx24110_get_fec (struct cx24110_state* state)
226{
227 int i;
228
229 i=cx24110_readreg(state,0x22)&0x0f;
230 if(!(i&0x08)) {
231 return FEC_1_2 + i - 1;
232 } else {
233/* fixme (low): a special code rate has been selected. In theory, we need to
234 return a denominator value, a numerator value, and a pair of puncture
235 maps to correctly describe this mode. But this should never happen in
236 practice, because it cannot be set by cx24110_get_fec. */
237 return FEC_NONE;
238 }
239}
240
241static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
242{
243/* fixme (low): add error handling */
244 u32 ratio;
245 u32 tmp, fclk, BDRI;
246
247 static const u32 bands[]={5000000UL,15000000UL,90999000UL/2};
248 int i;
249
250 dprintk("cx24110 debug: entering %s(%d)\n",__func__,srate);
251 if (srate>90999000UL/2)
252 srate=90999000UL/2;
253 if (srate<500000)
254 srate=500000;
255
256 for(i = 0; (i < ARRAY_SIZE(bands)) && (srate>bands[i]); i++)
257 ;
258 /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz,
259 and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult,
260 R06[3:0] PLLphaseDetGain */
261 tmp=cx24110_readreg(state,0x07)&0xfc;
262 if(srate<90999000UL/4) { /* sample rate 45MHz*/
263 cx24110_writereg(state,0x07,tmp);
264 cx24110_writereg(state,0x06,0x78);
265 fclk=90999000UL/2;
266 } else if(srate<60666000UL/2) { /* sample rate 60MHz */
267 cx24110_writereg(state,0x07,tmp|0x1);
268 cx24110_writereg(state,0x06,0xa5);
269 fclk=60666000UL;
270 } else if(srate<80888000UL/2) { /* sample rate 80MHz */
271 cx24110_writereg(state,0x07,tmp|0x2);
272 cx24110_writereg(state,0x06,0x87);
273 fclk=80888000UL;
274 } else { /* sample rate 90MHz */
275 cx24110_writereg(state,0x07,tmp|0x3);
276 cx24110_writereg(state,0x06,0x78);
277 fclk=90999000UL;
278 };
279 dprintk("cx24110 debug: fclk %d Hz\n",fclk);
280 /* we need to divide two integers with approx. 27 bits in 32 bit
281 arithmetic giving a 25 bit result */
282 /* the maximum dividend is 90999000/2, 0x02b6446c, this number is
283 also the most complex divisor. Hence, the dividend has,
284 assuming 32bit unsigned arithmetic, 6 clear bits on top, the
285 divisor 2 unused bits at the bottom. Also, the quotient is
286 always less than 1/2. Borrowed from VES1893.c, of course */
287
288 tmp=srate<<6;
289 BDRI=fclk>>2;
290 ratio=(tmp/BDRI);
291
292 tmp=(tmp%BDRI)<<8;
293 ratio=(ratio<<8)+(tmp/BDRI);
294
295 tmp=(tmp%BDRI)<<8;
296 ratio=(ratio<<8)+(tmp/BDRI);
297
298 tmp=(tmp%BDRI)<<1;
299 ratio=(ratio<<1)+(tmp/BDRI);
300
301 dprintk("srate= %d (range %d, up to %d)\n", srate,i,bands[i]);
302 dprintk("fclk = %d\n", fclk);
303 dprintk("ratio= %08x\n", ratio);
304
305 cx24110_writereg(state, 0x1, (ratio>>16)&0xff);
306 cx24110_writereg(state, 0x2, (ratio>>8)&0xff);
307 cx24110_writereg(state, 0x3, (ratio)&0xff);
308
309 return 0;
310
311}
312
313static int _cx24110_pll_write (struct dvb_frontend* fe, const u8 buf[], int len)
314{
315 struct cx24110_state *state = fe->demodulator_priv;
316
317 if (len != 3)
318 return -EINVAL;
319
320/* tuner data is 21 bits long, must be left-aligned in data */
321/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */
322/* FIXME (low): add error handling, avoid infinite loops if HW fails... */
323
324 cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */
325 cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */
326
327 /* if the auto tuner writer is still busy, clear it out */
328 while (cx24110_readreg(state,0x6d)&0x80)
329 cx24110_writereg(state,0x72,0);
330
331 /* write the topmost 8 bits */
332 cx24110_writereg(state,0x72,buf[0]);
333
334 /* wait for the send to be completed */
335 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
336 ;
337
338 /* send another 8 bytes */
339 cx24110_writereg(state,0x72,buf[1]);
340 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
341 ;
342
343 /* and the topmost 5 bits of this byte */
344 cx24110_writereg(state,0x72,buf[2]);
345 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
346 ;
347
348 /* now strobe the enable line once */
349 cx24110_writereg(state,0x6d,0x32);
350 cx24110_writereg(state,0x6d,0x30);
351
352 return 0;
353}
354
355static int cx24110_initfe(struct dvb_frontend* fe)
356{
357 struct cx24110_state *state = fe->demodulator_priv;
358/* fixme (low): error handling */
359 int i;
360
361 dprintk("%s: init chip\n", __func__);
362
363 for(i = 0; i < ARRAY_SIZE(cx24110_regdata); i++) {
364 cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data);
365 };
366
367 return 0;
368}
369
370static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
371{
372 struct cx24110_state *state = fe->demodulator_priv;
373
374 switch (voltage) {
375 case SEC_VOLTAGE_13:
376 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0xc0);
377 case SEC_VOLTAGE_18:
378 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0x40);
379 default:
380 return -EINVAL;
381 };
382}
383
384static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
385{
386 int rv, bit;
387 struct cx24110_state *state = fe->demodulator_priv;
388 unsigned long timeout;
389
390 if (burst == SEC_MINI_A)
391 bit = 0x00;
392 else if (burst == SEC_MINI_B)
393 bit = 0x08;
394 else
395 return -EINVAL;
396
397 rv = cx24110_readreg(state, 0x77);
398 if (!(rv & 0x04))
399 cx24110_writereg(state, 0x77, rv | 0x04);
400
401 rv = cx24110_readreg(state, 0x76);
402 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit));
403 timeout = jiffies + msecs_to_jiffies(100);
404 while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
405 ; /* wait for LNB ready */
406
407 return 0;
408}
409
410static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
411 struct dvb_diseqc_master_cmd *cmd)
412{
413 int i, rv;
414 struct cx24110_state *state = fe->demodulator_priv;
415 unsigned long timeout;
416
417 if (cmd->msg_len < 3 || cmd->msg_len > 6)
418 return -EINVAL; /* not implemented */
419
420 for (i = 0; i < cmd->msg_len; i++)
421 cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
422
423 rv = cx24110_readreg(state, 0x77);
424 if (rv & 0x04) {
425 cx24110_writereg(state, 0x77, rv & ~0x04);
426 msleep(30); /* reportedly fixes switching problems */
427 }
428
429 rv = cx24110_readreg(state, 0x76);
430
431 cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
432 timeout = jiffies + msecs_to_jiffies(100);
433 while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40))
434 ; /* wait for LNB ready */
435
436 return 0;
437}
438
439static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status)
440{
441 struct cx24110_state *state = fe->demodulator_priv;
442
443 int sync = cx24110_readreg (state, 0x55);
444
445 *status = 0;
446
447 if (sync & 0x10)
448 *status |= FE_HAS_SIGNAL;
449
450 if (sync & 0x08)
451 *status |= FE_HAS_CARRIER;
452
453 sync = cx24110_readreg (state, 0x08);
454
455 if (sync & 0x40)
456 *status |= FE_HAS_VITERBI;
457
458 if (sync & 0x20)
459 *status |= FE_HAS_SYNC;
460
461 if ((sync & 0x60) == 0x60)
462 *status |= FE_HAS_LOCK;
463
464 return 0;
465}
466
467static int cx24110_read_ber(struct dvb_frontend* fe, u32* ber)
468{
469 struct cx24110_state *state = fe->demodulator_priv;
470
471 /* fixme (maybe): value range is 16 bit. Scale? */
472 if(cx24110_readreg(state,0x24)&0x10) {
473 /* the Viterbi error counter has finished one counting window */
474 cx24110_writereg(state,0x24,0x04); /* select the ber reg */
475 state->lastber=cx24110_readreg(state,0x25)|
476 (cx24110_readreg(state,0x26)<<8);
477 cx24110_writereg(state,0x24,0x04); /* start new count window */
478 cx24110_writereg(state,0x24,0x14);
479 }
480 *ber = state->lastber;
481
482 return 0;
483}
484
485static int cx24110_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
486{
487 struct cx24110_state *state = fe->demodulator_priv;
488
489/* no provision in hardware. Read the frontend AGC accumulator. No idea how to scale this, but I know it is 2s complement */
490 u8 signal = cx24110_readreg (state, 0x27)+128;
491 *signal_strength = (signal << 8) | signal;
492
493 return 0;
494}
495
496static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr)
497{
498 struct cx24110_state *state = fe->demodulator_priv;
499
500 /* no provision in hardware. Can be computed from the Es/N0 estimator, but I don't know how. */
501 if(cx24110_readreg(state,0x6a)&0x80) {
502 /* the Es/N0 error counter has finished one counting window */
503 state->lastesn0=cx24110_readreg(state,0x69)|
504 (cx24110_readreg(state,0x68)<<8);
505 cx24110_writereg(state,0x6a,0x84); /* start new count window */
506 }
507 *snr = state->lastesn0;
508
509 return 0;
510}
511
512static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
513{
514 struct cx24110_state *state = fe->demodulator_priv;
515 u32 lastbyer;
516
517 if(cx24110_readreg(state,0x10)&0x40) {
518 /* the RS error counter has finished one counting window */
519 cx24110_writereg(state,0x10,0x60); /* select the byer reg */
520 lastbyer=cx24110_readreg(state,0x12)|
521 (cx24110_readreg(state,0x13)<<8)|
522 (cx24110_readreg(state,0x14)<<16);
523 cx24110_writereg(state,0x10,0x70); /* select the bler reg */
524 state->lastbler=cx24110_readreg(state,0x12)|
525 (cx24110_readreg(state,0x13)<<8)|
526 (cx24110_readreg(state,0x14)<<16);
527 cx24110_writereg(state,0x10,0x20); /* start new count window */
528 }
529 *ucblocks = state->lastbler;
530
531 return 0;
532}
533
534static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
535{
536 struct cx24110_state *state = fe->demodulator_priv;
537
538
539 if (fe->ops.tuner_ops.set_params) {
540 fe->ops.tuner_ops.set_params(fe, p);
541 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
542 }
543
544 cx24110_set_inversion (state, p->inversion);
545 cx24110_set_fec (state, p->u.qpsk.fec_inner);
546 cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate);
547 cx24110_writereg(state,0x04,0x05); /* start acquisition */
548
549 return 0;
550}
551
552static int cx24110_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
553{
554 struct cx24110_state *state = fe->demodulator_priv;
555 s32 afc; unsigned sclk;
556
557/* cannot read back tuner settings (freq). Need to have some private storage */
558
559 sclk = cx24110_readreg (state, 0x07) & 0x03;
560/* ok, real AFC (FEDR) freq. is afc/2^24*fsamp, fsamp=45/60/80/90MHz.
561 * Need 64 bit arithmetic. Is thiss possible in the kernel? */
562 if (sclk==0) sclk=90999000L/2L;
563 else if (sclk==1) sclk=60666000L;
564 else if (sclk==2) sclk=80888000L;
565 else sclk=90999000L;
566 sclk>>=8;
567 afc = sclk*(cx24110_readreg (state, 0x44)&0x1f)+
568 ((sclk*cx24110_readreg (state, 0x45))>>8)+
569 ((sclk*cx24110_readreg (state, 0x46))>>16);
570
571 p->frequency += afc;
572 p->inversion = (cx24110_readreg (state, 0x22) & 0x10) ?
573 INVERSION_ON : INVERSION_OFF;
574 p->u.qpsk.fec_inner = cx24110_get_fec (state);
575
576 return 0;
577}
578
579static int cx24110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
580{
581 struct cx24110_state *state = fe->demodulator_priv;
582
583 return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&~0x10)|(((tone==SEC_TONE_ON))?0x10:0));
584}
585
586static void cx24110_release(struct dvb_frontend* fe)
587{
588 struct cx24110_state* state = fe->demodulator_priv;
589 kfree(state);
590}
591
592static struct dvb_frontend_ops cx24110_ops;
593
594struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
595 struct i2c_adapter* i2c)
596{
597 struct cx24110_state* state = NULL;
598 int ret;
599
600 /* allocate memory for the internal state */
601 state = kzalloc(sizeof(struct cx24110_state), GFP_KERNEL);
602 if (state == NULL) goto error;
603
604 /* setup the state */
605 state->config = config;
606 state->i2c = i2c;
607 state->lastber = 0;
608 state->lastbler = 0;
609 state->lastesn0 = 0;
610
611 /* check if the demod is there */
612 ret = cx24110_readreg(state, 0x00);
613 if ((ret != 0x5a) && (ret != 0x69)) goto error;
614
615 /* create dvb_frontend */
616 memcpy(&state->frontend.ops, &cx24110_ops, sizeof(struct dvb_frontend_ops));
617 state->frontend.demodulator_priv = state;
618 return &state->frontend;
619
620error:
621 kfree(state);
622 return NULL;
623}
624
625static struct dvb_frontend_ops cx24110_ops = {
626
627 .info = {
628 .name = "Conexant CX24110 DVB-S",
629 .type = FE_QPSK,
630 .frequency_min = 950000,
631 .frequency_max = 2150000,
632 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
633 .frequency_tolerance = 29500,
634 .symbol_rate_min = 1000000,
635 .symbol_rate_max = 45000000,
636 .caps = FE_CAN_INVERSION_AUTO |
637 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
638 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
639 FE_CAN_QPSK | FE_CAN_RECOVER
640 },
641
642 .release = cx24110_release,
643
644 .init = cx24110_initfe,
645 .write = _cx24110_pll_write,
646 .set_frontend = cx24110_set_frontend,
647 .get_frontend = cx24110_get_frontend,
648 .read_status = cx24110_read_status,
649 .read_ber = cx24110_read_ber,
650 .read_signal_strength = cx24110_read_signal_strength,
651 .read_snr = cx24110_read_snr,
652 .read_ucblocks = cx24110_read_ucblocks,
653
654 .diseqc_send_master_cmd = cx24110_send_diseqc_msg,
655 .set_tone = cx24110_set_tone,
656 .set_voltage = cx24110_set_voltage,
657 .diseqc_send_burst = cx24110_diseqc_send_burst,
658};
659
660module_param(debug, int, 0644);
661MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
662
663MODULE_DESCRIPTION("Conexant CX24110 DVB-S Demodulator driver");
664MODULE_AUTHOR("Peter Hettkamp");
665MODULE_LICENSE("GPL");
666
667EXPORT_SYMBOL(cx24110_attach);
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
new file mode 100644
index 00000000000..fdcceee91f3
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24110.h
@@ -0,0 +1,61 @@
1/*
2 cx24110 - Single Chip Satellite Channel Receiver driver module
3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
5 work
6 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
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
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., 675 Mass Ave, Cambridge, MA 02139, USA.
22
23*/
24
25#ifndef CX24110_H
26#define CX24110_H
27
28#include <linux/dvb/frontend.h>
29
30struct cx24110_config
31{
32 /* the demodulator's i2c address */
33 u8 demod_address;
34};
35
36static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val)
37{
38 u8 buf[] = {
39 (u8)((val >> 24) & 0xff),
40 (u8)((val >> 16) & 0xff),
41 (u8)((val >> 8) & 0xff)
42 };
43
44 if (fe->ops.write)
45 return fe->ops.write(fe, buf, 3);
46 return 0;
47}
48
49#if defined(CONFIG_DVB_CX24110) || (defined(CONFIG_DVB_CX24110_MODULE) && defined(MODULE))
50extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
51 struct i2c_adapter* i2c);
52#else
53static inline struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
54 struct i2c_adapter* i2c)
55{
56 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
57 return NULL;
58}
59#endif // CONFIG_DVB_CX24110
60
61#endif // CX24110_H
diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c
new file mode 100644
index 00000000000..c341d57d5e8
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24113.c
@@ -0,0 +1,620 @@
1/*
2 * Driver for Conexant CX24113/CX24128 Tuner (Satellite)
3 *
4 * Copyright (C) 2007-8 Patrick Boettcher <pb@linuxtv.org>
5 *
6 * Developed for BBTI / Technisat
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 *
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., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/slab.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/init.h>
28
29#include "dvb_frontend.h"
30#include "cx24113.h"
31
32static int debug;
33
34#define cx_info(args...) do { printk(KERN_INFO "CX24113: " args); } while (0)
35#define cx_err(args...) do { printk(KERN_ERR "CX24113: " args); } while (0)
36
37#define dprintk(args...) \
38 do { \
39 if (debug) { \
40 printk(KERN_DEBUG "CX24113: %s: ", __func__); \
41 printk(args); \
42 } \
43 } while (0)
44
45struct cx24113_state {
46 struct i2c_adapter *i2c;
47 const struct cx24113_config *config;
48
49#define REV_CX24113 0x23
50 u8 rev;
51 u8 ver;
52
53 u8 icp_mode:1;
54
55#define ICP_LEVEL1 0
56#define ICP_LEVEL2 1
57#define ICP_LEVEL3 2
58#define ICP_LEVEL4 3
59 u8 icp_man:2;
60 u8 icp_auto_low:2;
61 u8 icp_auto_mlow:2;
62 u8 icp_auto_mhi:2;
63 u8 icp_auto_hi:2;
64 u8 icp_dig;
65
66#define LNA_MIN_GAIN 0
67#define LNA_MID_GAIN 1
68#define LNA_MAX_GAIN 2
69 u8 lna_gain:2;
70
71 u8 acp_on:1;
72
73 u8 vco_mode:2;
74 u8 vco_shift:1;
75#define VCOBANDSEL_6 0x80
76#define VCOBANDSEL_5 0x01
77#define VCOBANDSEL_4 0x02
78#define VCOBANDSEL_3 0x04
79#define VCOBANDSEL_2 0x08
80#define VCOBANDSEL_1 0x10
81 u8 vco_band;
82
83#define VCODIV4 4
84#define VCODIV2 2
85 u8 vcodiv;
86
87 u8 bs_delay:4;
88 u16 bs_freqcnt:13;
89 u16 bs_rdiv;
90 u8 prescaler_mode:1;
91
92 u8 rfvga_bias_ctrl;
93
94 s16 tuner_gain_thres;
95 u8 gain_level;
96
97 u32 frequency;
98
99 u8 refdiv;
100
101 u8 Fwindow_enabled;
102};
103
104static int cx24113_writereg(struct cx24113_state *state, int reg, int data)
105{
106 u8 buf[] = { reg, data };
107 struct i2c_msg msg = { .addr = state->config->i2c_addr,
108 .flags = 0, .buf = buf, .len = 2 };
109 int err = i2c_transfer(state->i2c, &msg, 1);
110 if (err != 1) {
111 printk(KERN_DEBUG "%s: writereg error(err == %i, reg == 0x%02x,"
112 " data == 0x%02x)\n", __func__, err, reg, data);
113 return err;
114 }
115
116 return 0;
117}
118
119static int cx24113_readreg(struct cx24113_state *state, u8 reg)
120{
121 int ret;
122 u8 b;
123 struct i2c_msg msg[] = {
124 { .addr = state->config->i2c_addr,
125 .flags = 0, .buf = &reg, .len = 1 },
126 { .addr = state->config->i2c_addr,
127 .flags = I2C_M_RD, .buf = &b, .len = 1 }
128 };
129
130 ret = i2c_transfer(state->i2c, msg, 2);
131
132 if (ret != 2) {
133 printk(KERN_DEBUG "%s: reg=0x%x (error=%d)\n",
134 __func__, reg, ret);
135 return ret;
136 }
137
138 return b;
139}
140
141static void cx24113_set_parameters(struct cx24113_state *state)
142{
143 u8 r;
144
145 r = cx24113_readreg(state, 0x10) & 0x82;
146 r |= state->icp_mode;
147 r |= state->icp_man << 4;
148 r |= state->icp_dig << 2;
149 r |= state->prescaler_mode << 5;
150 cx24113_writereg(state, 0x10, r);
151
152 r = (state->icp_auto_low << 0) | (state->icp_auto_mlow << 2)
153 | (state->icp_auto_mhi << 4) | (state->icp_auto_hi << 6);
154 cx24113_writereg(state, 0x11, r);
155
156 if (state->rev == REV_CX24113) {
157 r = cx24113_readreg(state, 0x20) & 0xec;
158 r |= state->lna_gain;
159 r |= state->rfvga_bias_ctrl << 4;
160 cx24113_writereg(state, 0x20, r);
161 }
162
163 r = cx24113_readreg(state, 0x12) & 0x03;
164 r |= state->acp_on << 2;
165 r |= state->bs_delay << 4;
166 cx24113_writereg(state, 0x12, r);
167
168 r = cx24113_readreg(state, 0x18) & 0x40;
169 r |= state->vco_shift;
170 if (state->vco_band == VCOBANDSEL_6)
171 r |= (1 << 7);
172 else
173 r |= (state->vco_band << 1);
174 cx24113_writereg(state, 0x18, r);
175
176 r = cx24113_readreg(state, 0x14) & 0x20;
177 r |= (state->vco_mode << 6) | ((state->bs_freqcnt >> 8) & 0x1f);
178 cx24113_writereg(state, 0x14, r);
179 cx24113_writereg(state, 0x15, (state->bs_freqcnt & 0xff));
180
181 cx24113_writereg(state, 0x16, (state->bs_rdiv >> 4) & 0xff);
182 r = (cx24113_readreg(state, 0x17) & 0x0f) |
183 ((state->bs_rdiv & 0x0f) << 4);
184 cx24113_writereg(state, 0x17, r);
185}
186
187#define VGA_0 0x00
188#define VGA_1 0x04
189#define VGA_2 0x02
190#define VGA_3 0x06
191#define VGA_4 0x01
192#define VGA_5 0x05
193#define VGA_6 0x03
194#define VGA_7 0x07
195
196#define RFVGA_0 0x00
197#define RFVGA_1 0x01
198#define RFVGA_2 0x02
199#define RFVGA_3 0x03
200
201static int cx24113_set_gain_settings(struct cx24113_state *state,
202 s16 power_estimation)
203{
204 u8 ampout = cx24113_readreg(state, 0x1d) & 0xf0,
205 vga = cx24113_readreg(state, 0x1f) & 0x3f,
206 rfvga = cx24113_readreg(state, 0x20) & 0xf3;
207 u8 gain_level = power_estimation >= state->tuner_gain_thres;
208
209 dprintk("power estimation: %d, thres: %d, gain_level: %d/%d\n",
210 power_estimation, state->tuner_gain_thres,
211 state->gain_level, gain_level);
212
213 if (gain_level == state->gain_level)
214 return 0; /* nothing to be done */
215
216 ampout |= 0xf;
217
218 if (gain_level) {
219 rfvga |= RFVGA_0 << 2;
220 vga |= (VGA_7 << 3) | VGA_7;
221 } else {
222 rfvga |= RFVGA_2 << 2;
223 vga |= (VGA_6 << 3) | VGA_2;
224 }
225 state->gain_level = gain_level;
226
227 cx24113_writereg(state, 0x1d, ampout);
228 cx24113_writereg(state, 0x1f, vga);
229 cx24113_writereg(state, 0x20, rfvga);
230
231 return 1; /* did something */
232}
233
234static int cx24113_set_Fref(struct cx24113_state *state, u8 high)
235{
236 u8 xtal = cx24113_readreg(state, 0x02);
237 if (state->rev == 0x43 && state->vcodiv == VCODIV4)
238 high = 1;
239
240 xtal &= ~0x2;
241 if (high)
242 xtal |= high << 1;
243 return cx24113_writereg(state, 0x02, xtal);
244}
245
246static int cx24113_enable(struct cx24113_state *state, u8 enable)
247{
248 u8 r21 = (cx24113_readreg(state, 0x21) & 0xc0) | enable;
249 if (state->rev == REV_CX24113)
250 r21 |= (1 << 1);
251 return cx24113_writereg(state, 0x21, r21);
252}
253
254static int cx24113_set_bandwidth(struct cx24113_state *state, u32 bandwidth_khz)
255{
256 u8 r;
257
258 if (bandwidth_khz <= 19000)
259 r = 0x03 << 6;
260 else if (bandwidth_khz <= 25000)
261 r = 0x02 << 6;
262 else
263 r = 0x01 << 6;
264
265 dprintk("bandwidth to be set: %d\n", bandwidth_khz);
266 bandwidth_khz *= 10;
267 bandwidth_khz -= 10000;
268 bandwidth_khz /= 1000;
269 bandwidth_khz += 5;
270 bandwidth_khz /= 10;
271
272 dprintk("bandwidth: %d %d\n", r >> 6, bandwidth_khz);
273
274 r |= bandwidth_khz & 0x3f;
275
276 return cx24113_writereg(state, 0x1e, r);
277}
278
279static int cx24113_set_clk_inversion(struct cx24113_state *state, u8 on)
280{
281 u8 r = (cx24113_readreg(state, 0x10) & 0x7f) | ((on & 0x1) << 7);
282 return cx24113_writereg(state, 0x10, r);
283}
284
285static int cx24113_get_status(struct dvb_frontend *fe, u32 *status)
286{
287 struct cx24113_state *state = fe->tuner_priv;
288 u8 r = (cx24113_readreg(state, 0x10) & 0x02) >> 1;
289 if (r)
290 *status |= TUNER_STATUS_LOCKED;
291 dprintk("PLL locked: %d\n", r);
292 return 0;
293}
294
295static u8 cx24113_set_ref_div(struct cx24113_state *state, u8 refdiv)
296{
297 if (state->rev == 0x43 && state->vcodiv == VCODIV4)
298 refdiv = 2;
299 return state->refdiv = refdiv;
300}
301
302static void cx24113_calc_pll_nf(struct cx24113_state *state, u16 *n, s32 *f)
303{
304 s32 N;
305 s64 F;
306 u64 dividend;
307 u8 R, r;
308 u8 vcodiv;
309 u8 factor;
310 s32 freq_hz = state->frequency * 1000;
311
312 if (state->config->xtal_khz < 20000)
313 factor = 1;
314 else
315 factor = 2;
316
317 if (state->rev == REV_CX24113) {
318 if (state->frequency >= 1100000)
319 vcodiv = VCODIV2;
320 else
321 vcodiv = VCODIV4;
322 } else {
323 if (state->frequency >= 1165000)
324 vcodiv = VCODIV2;
325 else
326 vcodiv = VCODIV4;
327 }
328 state->vcodiv = vcodiv;
329
330 dprintk("calculating N/F for %dHz with vcodiv %d\n", freq_hz, vcodiv);
331 R = 0;
332 do {
333 R = cx24113_set_ref_div(state, R + 1);
334
335 /* calculate tuner PLL settings: */
336 N = (freq_hz / 100 * vcodiv) * R;
337 N /= (state->config->xtal_khz) * factor * 2;
338 N += 5; /* For round up. */
339 N /= 10;
340 N -= 32;
341 } while (N < 6 && R < 3);
342
343 if (N < 6) {
344 cx_err("strange frequency: N < 6\n");
345 return;
346 }
347 F = freq_hz;
348 F *= (u64) (R * vcodiv * 262144);
349 dprintk("1 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
350 /* do_div needs an u64 as first argument */
351 dividend = F;
352 do_div(dividend, state->config->xtal_khz * 1000 * factor * 2);
353 F = dividend;
354 dprintk("2 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
355 F -= (N + 32) * 262144;
356
357 dprintk("3 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
358
359 if (state->Fwindow_enabled) {
360 if (F > (262144 / 2 - 1638))
361 F = 262144 / 2 - 1638;
362 if (F < (-262144 / 2 + 1638))
363 F = -262144 / 2 + 1638;
364 if ((F < 3277 && F > 0) || (F > -3277 && F < 0)) {
365 F = 0;
366 r = cx24113_readreg(state, 0x10);
367 cx24113_writereg(state, 0x10, r | (1 << 6));
368 }
369 }
370 dprintk("4 N: %d, F: %lld, R: %d\n", N, (long long)F, R);
371
372 *n = (u16) N;
373 *f = (s32) F;
374}
375
376
377static void cx24113_set_nfr(struct cx24113_state *state, u16 n, s32 f, u8 r)
378{
379 u8 reg;
380 cx24113_writereg(state, 0x19, (n >> 1) & 0xff);
381
382 reg = ((n & 0x1) << 7) | ((f >> 11) & 0x7f);
383 cx24113_writereg(state, 0x1a, reg);
384
385 cx24113_writereg(state, 0x1b, (f >> 3) & 0xff);
386
387 reg = cx24113_readreg(state, 0x1c) & 0x1f;
388 cx24113_writereg(state, 0x1c, reg | ((f & 0x7) << 5));
389
390 cx24113_set_Fref(state, r - 1);
391}
392
393static int cx24113_set_frequency(struct cx24113_state *state, u32 frequency)
394{
395 u8 r = 1; /* or 2 */
396 u16 n = 6;
397 s32 f = 0;
398
399 r = cx24113_readreg(state, 0x14);
400 cx24113_writereg(state, 0x14, r & 0x3f);
401
402 r = cx24113_readreg(state, 0x10);
403 cx24113_writereg(state, 0x10, r & 0xbf);
404
405 state->frequency = frequency;
406
407 dprintk("tuning to frequency: %d\n", frequency);
408
409 cx24113_calc_pll_nf(state, &n, &f);
410 cx24113_set_nfr(state, n, f, state->refdiv);
411
412 r = cx24113_readreg(state, 0x18) & 0xbf;
413 if (state->vcodiv != VCODIV2)
414 r |= 1 << 6;
415 cx24113_writereg(state, 0x18, r);
416
417 /* The need for this sleep is not clear. But helps in some cases */
418 msleep(5);
419
420 r = cx24113_readreg(state, 0x1c) & 0xef;
421 cx24113_writereg(state, 0x1c, r | (1 << 4));
422 return 0;
423}
424
425static int cx24113_init(struct dvb_frontend *fe)
426{
427 struct cx24113_state *state = fe->tuner_priv;
428 int ret;
429
430 state->tuner_gain_thres = -50;
431 state->gain_level = 255; /* to force a gain-setting initialization */
432 state->icp_mode = 0;
433
434 if (state->config->xtal_khz < 11000) {
435 state->icp_auto_hi = ICP_LEVEL4;
436 state->icp_auto_mhi = ICP_LEVEL4;
437 state->icp_auto_mlow = ICP_LEVEL3;
438 state->icp_auto_low = ICP_LEVEL3;
439 } else {
440 state->icp_auto_hi = ICP_LEVEL4;
441 state->icp_auto_mhi = ICP_LEVEL4;
442 state->icp_auto_mlow = ICP_LEVEL3;
443 state->icp_auto_low = ICP_LEVEL2;
444 }
445
446 state->icp_dig = ICP_LEVEL3;
447 state->icp_man = ICP_LEVEL1;
448 state->acp_on = 1;
449 state->vco_mode = 0;
450 state->vco_shift = 0;
451 state->vco_band = VCOBANDSEL_1;
452 state->bs_delay = 8;
453 state->bs_freqcnt = 0x0fff;
454 state->bs_rdiv = 0x0fff;
455 state->prescaler_mode = 0;
456 state->lna_gain = LNA_MAX_GAIN;
457 state->rfvga_bias_ctrl = 1;
458 state->Fwindow_enabled = 1;
459
460 cx24113_set_Fref(state, 0);
461 cx24113_enable(state, 0x3d);
462 cx24113_set_parameters(state);
463
464 cx24113_set_gain_settings(state, -30);
465
466 cx24113_set_bandwidth(state, 18025);
467 cx24113_set_clk_inversion(state, 1);
468
469 if (state->config->xtal_khz >= 40000)
470 ret = cx24113_writereg(state, 0x02,
471 (cx24113_readreg(state, 0x02) & 0xfb) | (1 << 2));
472 else
473 ret = cx24113_writereg(state, 0x02,
474 (cx24113_readreg(state, 0x02) & 0xfb) | (0 << 2));
475
476 return ret;
477}
478
479static int cx24113_set_params(struct dvb_frontend *fe,
480 struct dvb_frontend_parameters *p)
481{
482 struct cx24113_state *state = fe->tuner_priv;
483 /* for a ROLL-OFF factor of 0.35, 0.2: 600, 0.25: 625 */
484 u32 roll_off = 675;
485 u32 bw;
486
487 bw = ((p->u.qpsk.symbol_rate/100) * roll_off) / 1000;
488 bw += (10000000/100) + 5;
489 bw /= 10;
490 bw += 1000;
491 cx24113_set_bandwidth(state, bw);
492
493 cx24113_set_frequency(state, p->frequency);
494 msleep(5);
495 return cx24113_get_status(fe, &bw);
496}
497
498static s8 cx24113_agc_table[2][10] = {
499 {-54, -41, -35, -30, -25, -21, -16, -10, -6, -2},
500 {-39, -35, -30, -25, -19, -15, -11, -5, 1, 9},
501};
502
503void cx24113_agc_callback(struct dvb_frontend *fe)
504{
505 struct cx24113_state *state = fe->tuner_priv;
506 s16 s, i;
507 if (!fe->ops.read_signal_strength)
508 return;
509
510 do {
511 /* this only works with the current CX24123 implementation */
512 fe->ops.read_signal_strength(fe, (u16 *) &s);
513 s >>= 8;
514 dprintk("signal strength: %d\n", s);
515 for (i = 0; i < sizeof(cx24113_agc_table[0]); i++)
516 if (cx24113_agc_table[state->gain_level][i] > s)
517 break;
518 s = -25 - i*5;
519 } while (cx24113_set_gain_settings(state, s));
520}
521EXPORT_SYMBOL(cx24113_agc_callback);
522
523static int cx24113_get_frequency(struct dvb_frontend *fe, u32 *frequency)
524{
525 struct cx24113_state *state = fe->tuner_priv;
526 *frequency = state->frequency;
527 return 0;
528}
529
530static int cx24113_release(struct dvb_frontend *fe)
531{
532 struct cx24113_state *state = fe->tuner_priv;
533 dprintk("\n");
534 fe->tuner_priv = NULL;
535 kfree(state);
536 return 0;
537}
538
539static const struct dvb_tuner_ops cx24113_tuner_ops = {
540 .info = {
541 .name = "Conexant CX24113",
542 .frequency_min = 950000,
543 .frequency_max = 2150000,
544 .frequency_step = 125,
545 },
546
547 .release = cx24113_release,
548
549 .init = cx24113_init,
550 .sleep = NULL,
551
552 .set_params = cx24113_set_params,
553 .get_frequency = cx24113_get_frequency,
554 .get_bandwidth = NULL,
555 .get_status = cx24113_get_status,
556};
557
558struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe,
559 const struct cx24113_config *config, struct i2c_adapter *i2c)
560{
561 /* allocate memory for the internal state */
562 struct cx24113_state *state =
563 kzalloc(sizeof(struct cx24113_state), GFP_KERNEL);
564 int rc;
565 if (state == NULL) {
566 cx_err("Unable to kzalloc\n");
567 goto error;
568 }
569
570 /* setup the state */
571 state->config = config;
572 state->i2c = i2c;
573
574 cx_info("trying to detect myself\n");
575
576 /* making a dummy read, because of some expected troubles
577 * after power on */
578 cx24113_readreg(state, 0x00);
579
580 rc = cx24113_readreg(state, 0x00);
581 if (rc < 0) {
582 cx_info("CX24113 not found.\n");
583 goto error;
584 }
585 state->rev = rc;
586
587 switch (rc) {
588 case 0x43:
589 cx_info("detected CX24113 variant\n");
590 break;
591 case REV_CX24113:
592 cx_info("successfully detected\n");
593 break;
594 default:
595 cx_err("unsupported device id: %x\n", state->rev);
596 goto error;
597 }
598 state->ver = cx24113_readreg(state, 0x01);
599 cx_info("version: %x\n", state->ver);
600
601 /* create dvb_frontend */
602 memcpy(&fe->ops.tuner_ops, &cx24113_tuner_ops,
603 sizeof(struct dvb_tuner_ops));
604 fe->tuner_priv = state;
605 return fe;
606
607error:
608 kfree(state);
609
610 return NULL;
611}
612EXPORT_SYMBOL(cx24113_attach);
613
614module_param(debug, int, 0644);
615MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
616
617MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>");
618MODULE_DESCRIPTION("DVB Frontend module for Conexant CX24113/CX24128hardware");
619MODULE_LICENSE("GPL");
620
diff --git a/drivers/media/dvb/frontends/cx24113.h b/drivers/media/dvb/frontends/cx24113.h
new file mode 100644
index 00000000000..01eb7b9c28f
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24113.h
@@ -0,0 +1,53 @@
1/*
2 * Driver for Conexant CX24113/CX24128 Tuner (Satellite)
3 *
4 * Copyright (C) 2007-8 Patrick Boettcher <pb@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 as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef CX24113_H
23#define CX24113_H
24
25struct dvb_frontend;
26
27struct cx24113_config {
28 u8 i2c_addr; /* 0x14 or 0x54 */
29
30 u32 xtal_khz;
31};
32
33#if defined(CONFIG_DVB_TUNER_CX24113) || \
34 (defined(CONFIG_DVB_TUNER_CX24113_MODULE) && defined(MODULE))
35extern struct dvb_frontend *cx24113_attach(struct dvb_frontend *,
36 const struct cx24113_config *config, struct i2c_adapter *i2c);
37
38extern void cx24113_agc_callback(struct dvb_frontend *fe);
39#else
40static inline struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe,
41 const struct cx24113_config *config, struct i2c_adapter *i2c)
42{
43 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
44 return NULL;
45}
46
47static inline void cx24113_agc_callback(struct dvb_frontend *fe)
48{
49 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
50}
51#endif
52
53#endif /* CX24113_H */
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c
new file mode 100644
index 00000000000..ccd05255d52
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24116.c
@@ -0,0 +1,1518 @@
1/*
2 Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
3
4 Copyright (C) 2006-2008 Steven Toth <stoth@hauppauge.com>
5 Copyright (C) 2006-2007 Georg Acher
6 Copyright (C) 2007-2008 Darron Broad
7 March 2007
8 Fixed some bugs.
9 Added diseqc support.
10 Added corrected signal strength support.
11 August 2007
12 Sync with legacy version.
13 Some clean ups.
14 Copyright (C) 2008 Igor Liplianin
15 September, 9th 2008
16 Fixed locking on high symbol rates (>30000).
17 Implement MPEG initialization parameter.
18 January, 17th 2009
19 Fill set_voltage with actually control voltage code.
20 Correct set tone to not affect voltage.
21
22 This program is free software; you can redistribute it and/or modify
23 it under the terms of the GNU General Public License as published by
24 the Free Software Foundation; either version 2 of the License, or
25 (at your option) any later version.
26
27 This program is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
31
32 You should have received a copy of the GNU General Public License
33 along with this program; if not, write to the Free Software
34 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35*/
36
37#include <linux/slab.h>
38#include <linux/kernel.h>
39#include <linux/module.h>
40#include <linux/moduleparam.h>
41#include <linux/init.h>
42#include <linux/firmware.h>
43
44#include "dvb_frontend.h"
45#include "cx24116.h"
46
47static int debug;
48module_param(debug, int, 0644);
49MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
50
51#define dprintk(args...) \
52 do { \
53 if (debug) \
54 printk(KERN_INFO "cx24116: " args); \
55 } while (0)
56
57#define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
58#define CX24116_SEARCH_RANGE_KHZ 5000
59
60/* known registers */
61#define CX24116_REG_COMMAND (0x00) /* command args 0x00..0x1e */
62#define CX24116_REG_EXECUTE (0x1f) /* execute command */
63#define CX24116_REG_MAILBOX (0x96) /* FW or multipurpose mailbox? */
64#define CX24116_REG_RESET (0x20) /* reset status > 0 */
65#define CX24116_REG_SIGNAL (0x9e) /* signal low */
66#define CX24116_REG_SSTATUS (0x9d) /* signal high / status */
67#define CX24116_REG_QUALITY8 (0xa3)
68#define CX24116_REG_QSTATUS (0xbc)
69#define CX24116_REG_QUALITY0 (0xd5)
70#define CX24116_REG_BER0 (0xc9)
71#define CX24116_REG_BER8 (0xc8)
72#define CX24116_REG_BER16 (0xc7)
73#define CX24116_REG_BER24 (0xc6)
74#define CX24116_REG_UCB0 (0xcb)
75#define CX24116_REG_UCB8 (0xca)
76#define CX24116_REG_CLKDIV (0xf3)
77#define CX24116_REG_RATEDIV (0xf9)
78
79/* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */
80#define CX24116_REG_FECSTATUS (0x9c)
81
82/* FECSTATUS bits */
83/* mask to determine configured fec (not tuned) or actual fec (tuned) */
84#define CX24116_FEC_FECMASK (0x1f)
85
86/* Select DVB-S demodulator, else DVB-S2 */
87#define CX24116_FEC_DVBS (0x20)
88#define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */
89
90/* Pilot mode requested when tuning else always reset when tuned */
91#define CX24116_FEC_PILOT (0x80)
92
93/* arg buffer size */
94#define CX24116_ARGLEN (0x1e)
95
96/* rolloff */
97#define CX24116_ROLLOFF_020 (0x00)
98#define CX24116_ROLLOFF_025 (0x01)
99#define CX24116_ROLLOFF_035 (0x02)
100
101/* pilot bit */
102#define CX24116_PILOT_OFF (0x00)
103#define CX24116_PILOT_ON (0x40)
104
105/* signal status */
106#define CX24116_HAS_SIGNAL (0x01)
107#define CX24116_HAS_CARRIER (0x02)
108#define CX24116_HAS_VITERBI (0x04)
109#define CX24116_HAS_SYNCLOCK (0x08)
110#define CX24116_HAS_UNKNOWN1 (0x10)
111#define CX24116_HAS_UNKNOWN2 (0x20)
112#define CX24116_STATUS_MASK (0x0f)
113#define CX24116_SIGNAL_MASK (0xc0)
114
115#define CX24116_DISEQC_TONEOFF (0) /* toneburst never sent */
116#define CX24116_DISEQC_TONECACHE (1) /* toneburst cached */
117#define CX24116_DISEQC_MESGCACHE (2) /* message cached */
118
119/* arg offset for DiSEqC */
120#define CX24116_DISEQC_BURST (1)
121#define CX24116_DISEQC_ARG2_2 (2) /* unknown value=2 */
122#define CX24116_DISEQC_ARG3_0 (3) /* unknown value=0 */
123#define CX24116_DISEQC_ARG4_0 (4) /* unknown value=0 */
124#define CX24116_DISEQC_MSGLEN (5)
125#define CX24116_DISEQC_MSGOFS (6)
126
127/* DiSEqC burst */
128#define CX24116_DISEQC_MINI_A (0)
129#define CX24116_DISEQC_MINI_B (1)
130
131/* DiSEqC tone burst */
132static int toneburst = 1;
133module_param(toneburst, int, 0644);
134MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\
135 "2=MESSAGE CACHE (default:1)");
136
137/* SNR measurements */
138static int esno_snr;
139module_param(esno_snr, int, 0644);
140MODULE_PARM_DESC(esno_snr, "SNR return units, 0=PERCENTAGE 0-100, "\
141 "1=ESNO(db * 10) (default:0)");
142
143enum cmds {
144 CMD_SET_VCO = 0x10,
145 CMD_TUNEREQUEST = 0x11,
146 CMD_MPEGCONFIG = 0x13,
147 CMD_TUNERINIT = 0x14,
148 CMD_BANDWIDTH = 0x15,
149 CMD_GETAGC = 0x19,
150 CMD_LNBCONFIG = 0x20,
151 CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */
152 CMD_LNBDCLEVEL = 0x22,
153 CMD_SET_TONE = 0x23,
154 CMD_UPDFWVERS = 0x35,
155 CMD_TUNERSLEEP = 0x36,
156 CMD_AGCCONTROL = 0x3b, /* Unknown */
157};
158
159/* The Demod/Tuner can't easily provide these, we cache them */
160struct cx24116_tuning {
161 u32 frequency;
162 u32 symbol_rate;
163 fe_spectral_inversion_t inversion;
164 fe_code_rate_t fec;
165
166 fe_delivery_system_t delsys;
167 fe_modulation_t modulation;
168 fe_pilot_t pilot;
169 fe_rolloff_t rolloff;
170
171 /* Demod values */
172 u8 fec_val;
173 u8 fec_mask;
174 u8 inversion_val;
175 u8 pilot_val;
176 u8 rolloff_val;
177};
178
179/* Basic commands that are sent to the firmware */
180struct cx24116_cmd {
181 u8 len;
182 u8 args[CX24116_ARGLEN];
183};
184
185struct cx24116_state {
186 struct i2c_adapter *i2c;
187 const struct cx24116_config *config;
188
189 struct dvb_frontend frontend;
190
191 struct cx24116_tuning dcur;
192 struct cx24116_tuning dnxt;
193
194 u8 skip_fw_load;
195 u8 burst;
196 struct cx24116_cmd dsec_cmd;
197};
198
199static int cx24116_writereg(struct cx24116_state *state, int reg, int data)
200{
201 u8 buf[] = { reg, data };
202 struct i2c_msg msg = { .addr = state->config->demod_address,
203 .flags = 0, .buf = buf, .len = 2 };
204 int err;
205
206 if (debug > 1)
207 printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n",
208 __func__, reg, data);
209
210 err = i2c_transfer(state->i2c, &msg, 1);
211 if (err != 1) {
212 printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
213 " value == 0x%02x)\n", __func__, err, reg, data);
214 return -EREMOTEIO;
215 }
216
217 return 0;
218}
219
220/* Bulk byte writes to a single I2C address, for 32k firmware load */
221static int cx24116_writeregN(struct cx24116_state *state, int reg,
222 const u8 *data, u16 len)
223{
224 int ret = -EREMOTEIO;
225 struct i2c_msg msg;
226 u8 *buf;
227
228 buf = kmalloc(len + 1, GFP_KERNEL);
229 if (buf == NULL) {
230 printk("Unable to kmalloc\n");
231 ret = -ENOMEM;
232 goto error;
233 }
234
235 *(buf) = reg;
236 memcpy(buf + 1, data, len);
237
238 msg.addr = state->config->demod_address;
239 msg.flags = 0;
240 msg.buf = buf;
241 msg.len = len + 1;
242
243 if (debug > 1)
244 printk(KERN_INFO "cx24116: %s: write regN 0x%02x, len = %d\n",
245 __func__, reg, len);
246
247 ret = i2c_transfer(state->i2c, &msg, 1);
248 if (ret != 1) {
249 printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n",
250 __func__, ret, reg);
251 ret = -EREMOTEIO;
252 }
253
254error:
255 kfree(buf);
256
257 return ret;
258}
259
260static int cx24116_readreg(struct cx24116_state *state, u8 reg)
261{
262 int ret;
263 u8 b0[] = { reg };
264 u8 b1[] = { 0 };
265 struct i2c_msg msg[] = {
266 { .addr = state->config->demod_address, .flags = 0,
267 .buf = b0, .len = 1 },
268 { .addr = state->config->demod_address, .flags = I2C_M_RD,
269 .buf = b1, .len = 1 }
270 };
271
272 ret = i2c_transfer(state->i2c, msg, 2);
273
274 if (ret != 2) {
275 printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
276 __func__, reg, ret);
277 return ret;
278 }
279
280 if (debug > 1)
281 printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n",
282 reg, b1[0]);
283
284 return b1[0];
285}
286
287static int cx24116_set_inversion(struct cx24116_state *state,
288 fe_spectral_inversion_t inversion)
289{
290 dprintk("%s(%d)\n", __func__, inversion);
291
292 switch (inversion) {
293 case INVERSION_OFF:
294 state->dnxt.inversion_val = 0x00;
295 break;
296 case INVERSION_ON:
297 state->dnxt.inversion_val = 0x04;
298 break;
299 case INVERSION_AUTO:
300 state->dnxt.inversion_val = 0x0C;
301 break;
302 default:
303 return -EINVAL;
304 }
305
306 state->dnxt.inversion = inversion;
307
308 return 0;
309}
310
311/*
312 * modfec (modulation and FEC)
313 * ===========================
314 *
315 * MOD FEC mask/val standard
316 * ---- -------- ----------- --------
317 * QPSK FEC_1_2 0x02 0x02+X DVB-S
318 * QPSK FEC_2_3 0x04 0x02+X DVB-S
319 * QPSK FEC_3_4 0x08 0x02+X DVB-S
320 * QPSK FEC_4_5 0x10 0x02+X DVB-S (?)
321 * QPSK FEC_5_6 0x20 0x02+X DVB-S
322 * QPSK FEC_6_7 0x40 0x02+X DVB-S
323 * QPSK FEC_7_8 0x80 0x02+X DVB-S
324 * QPSK FEC_8_9 0x01 0x02+X DVB-S (?) (NOT SUPPORTED?)
325 * QPSK AUTO 0xff 0x02+X DVB-S
326 *
327 * For DVB-S high byte probably represents FEC
328 * and low byte selects the modulator. The high
329 * byte is search range mask. Bit 5 may turn
330 * on DVB-S and remaining bits represent some
331 * kind of calibration (how/what i do not know).
332 *
333 * Eg.(2/3) szap "Zone Horror"
334 *
335 * mask/val = 0x04, 0x20
336 * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK
337 *
338 * mask/val = 0x04, 0x30
339 * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK
340 *
341 * After tuning FECSTATUS contains actual FEC
342 * in use numbered 1 through to 8 for 1/2 .. 2/3 etc
343 *
344 * NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only)
345 *
346 * NBC-QPSK FEC_1_2 0x00, 0x04 DVB-S2
347 * NBC-QPSK FEC_3_5 0x00, 0x05 DVB-S2
348 * NBC-QPSK FEC_2_3 0x00, 0x06 DVB-S2
349 * NBC-QPSK FEC_3_4 0x00, 0x07 DVB-S2
350 * NBC-QPSK FEC_4_5 0x00, 0x08 DVB-S2
351 * NBC-QPSK FEC_5_6 0x00, 0x09 DVB-S2
352 * NBC-QPSK FEC_8_9 0x00, 0x0a DVB-S2
353 * NBC-QPSK FEC_9_10 0x00, 0x0b DVB-S2
354 *
355 * NBC-8PSK FEC_3_5 0x00, 0x0c DVB-S2
356 * NBC-8PSK FEC_2_3 0x00, 0x0d DVB-S2
357 * NBC-8PSK FEC_3_4 0x00, 0x0e DVB-S2
358 * NBC-8PSK FEC_5_6 0x00, 0x0f DVB-S2
359 * NBC-8PSK FEC_8_9 0x00, 0x10 DVB-S2
360 * NBC-8PSK FEC_9_10 0x00, 0x11 DVB-S2
361 *
362 * For DVB-S2 low bytes selects both modulator
363 * and FEC. High byte is meaningless here. To
364 * set pilot, bit 6 (0x40) is set. When inspecting
365 * FECSTATUS bit 7 (0x80) represents the pilot
366 * selection whilst not tuned. When tuned, actual FEC
367 * in use is found in FECSTATUS as per above. Pilot
368 * value is reset.
369 */
370
371/* A table of modulation, fec and configuration bytes for the demod.
372 * Not all S2 mmodulation schemes are support and not all rates with
373 * a scheme are support. Especially, no auto detect when in S2 mode.
374 */
375static struct cx24116_modfec {
376 fe_delivery_system_t delivery_system;
377 fe_modulation_t modulation;
378 fe_code_rate_t fec;
379 u8 mask; /* In DVBS mode this is used to autodetect */
380 u8 val; /* Passed to the firmware to indicate mode selection */
381} CX24116_MODFEC_MODES[] = {
382 /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */
383
384 /*mod fec mask val */
385 { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 },
386 { SYS_DVBS, QPSK, FEC_1_2, 0x02, 0x2e }, /* 00000010 00101110 */
387 { SYS_DVBS, QPSK, FEC_2_3, 0x04, 0x2f }, /* 00000100 00101111 */
388 { SYS_DVBS, QPSK, FEC_3_4, 0x08, 0x30 }, /* 00001000 00110000 */
389 { SYS_DVBS, QPSK, FEC_4_5, 0xfe, 0x30 }, /* 000?0000 ? */
390 { SYS_DVBS, QPSK, FEC_5_6, 0x20, 0x31 }, /* 00100000 00110001 */
391 { SYS_DVBS, QPSK, FEC_6_7, 0xfe, 0x30 }, /* 0?000000 ? */
392 { SYS_DVBS, QPSK, FEC_7_8, 0x80, 0x32 }, /* 10000000 00110010 */
393 { SYS_DVBS, QPSK, FEC_8_9, 0xfe, 0x30 }, /* 0000000? ? */
394 { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 },
395 /* NBC-QPSK */
396 { SYS_DVBS2, QPSK, FEC_1_2, 0x00, 0x04 },
397 { SYS_DVBS2, QPSK, FEC_3_5, 0x00, 0x05 },
398 { SYS_DVBS2, QPSK, FEC_2_3, 0x00, 0x06 },
399 { SYS_DVBS2, QPSK, FEC_3_4, 0x00, 0x07 },
400 { SYS_DVBS2, QPSK, FEC_4_5, 0x00, 0x08 },
401 { SYS_DVBS2, QPSK, FEC_5_6, 0x00, 0x09 },
402 { SYS_DVBS2, QPSK, FEC_8_9, 0x00, 0x0a },
403 { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b },
404 /* 8PSK */
405 { SYS_DVBS2, PSK_8, FEC_3_5, 0x00, 0x0c },
406 { SYS_DVBS2, PSK_8, FEC_2_3, 0x00, 0x0d },
407 { SYS_DVBS2, PSK_8, FEC_3_4, 0x00, 0x0e },
408 { SYS_DVBS2, PSK_8, FEC_5_6, 0x00, 0x0f },
409 { SYS_DVBS2, PSK_8, FEC_8_9, 0x00, 0x10 },
410 { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 },
411 /*
412 * `val' can be found in the FECSTATUS register when tuning.
413 * FECSTATUS will give the actual FEC in use if tuning was successful.
414 */
415};
416
417static int cx24116_lookup_fecmod(struct cx24116_state *state,
418 fe_delivery_system_t d, fe_modulation_t m, fe_code_rate_t f)
419{
420 int i, ret = -EOPNOTSUPP;
421
422 dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f);
423
424 for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) {
425 if ((d == CX24116_MODFEC_MODES[i].delivery_system) &&
426 (m == CX24116_MODFEC_MODES[i].modulation) &&
427 (f == CX24116_MODFEC_MODES[i].fec)) {
428 ret = i;
429 break;
430 }
431 }
432
433 return ret;
434}
435
436static int cx24116_set_fec(struct cx24116_state *state,
437 fe_delivery_system_t delsys, fe_modulation_t mod, fe_code_rate_t fec)
438{
439 int ret = 0;
440
441 dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec);
442
443 ret = cx24116_lookup_fecmod(state, delsys, mod, fec);
444
445 if (ret < 0)
446 return ret;
447
448 state->dnxt.fec = fec;
449 state->dnxt.fec_val = CX24116_MODFEC_MODES[ret].val;
450 state->dnxt.fec_mask = CX24116_MODFEC_MODES[ret].mask;
451 dprintk("%s() mask/val = 0x%02x/0x%02x\n", __func__,
452 state->dnxt.fec_mask, state->dnxt.fec_val);
453
454 return 0;
455}
456
457static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate)
458{
459 dprintk("%s(%d)\n", __func__, rate);
460
461 /* check if symbol rate is within limits */
462 if ((rate > state->frontend.ops.info.symbol_rate_max) ||
463 (rate < state->frontend.ops.info.symbol_rate_min)) {
464 dprintk("%s() unsupported symbol_rate = %d\n", __func__, rate);
465 return -EOPNOTSUPP;
466 }
467
468 state->dnxt.symbol_rate = rate;
469 dprintk("%s() symbol_rate = %d\n", __func__, rate);
470
471 return 0;
472}
473
474static int cx24116_load_firmware(struct dvb_frontend *fe,
475 const struct firmware *fw);
476
477static int cx24116_firmware_ondemand(struct dvb_frontend *fe)
478{
479 struct cx24116_state *state = fe->demodulator_priv;
480 const struct firmware *fw;
481 int ret = 0;
482
483 dprintk("%s()\n", __func__);
484
485 if (cx24116_readreg(state, 0x20) > 0) {
486
487 if (state->skip_fw_load)
488 return 0;
489
490 /* Load firmware */
491 /* request the firmware, this will block until loaded */
492 printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n",
493 __func__, CX24116_DEFAULT_FIRMWARE);
494 ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE,
495 state->i2c->dev.parent);
496 printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n",
497 __func__);
498 if (ret) {
499 printk(KERN_ERR "%s: No firmware uploaded "
500 "(timeout or file not found?)\n", __func__);
501 return ret;
502 }
503
504 /* Make sure we don't recurse back through here
505 * during loading */
506 state->skip_fw_load = 1;
507
508 ret = cx24116_load_firmware(fe, fw);
509 if (ret)
510 printk(KERN_ERR "%s: Writing firmware to device failed\n",
511 __func__);
512
513 release_firmware(fw);
514
515 printk(KERN_INFO "%s: Firmware upload %s\n", __func__,
516 ret == 0 ? "complete" : "failed");
517
518 /* Ensure firmware is always loaded if required */
519 state->skip_fw_load = 0;
520 }
521
522 return ret;
523}
524
525/* Take a basic firmware command structure, format it
526 * and forward it for processing
527 */
528static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd)
529{
530 struct cx24116_state *state = fe->demodulator_priv;
531 int i, ret;
532
533 dprintk("%s()\n", __func__);
534
535 /* Load the firmware if required */
536 ret = cx24116_firmware_ondemand(fe);
537 if (ret != 0) {
538 printk(KERN_ERR "%s(): Unable initialise the firmware\n",
539 __func__);
540 return ret;
541 }
542
543 /* Write the command */
544 for (i = 0; i < cmd->len ; i++) {
545 dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]);
546 cx24116_writereg(state, i, cmd->args[i]);
547 }
548
549 /* Start execution and wait for cmd to terminate */
550 cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01);
551 while (cx24116_readreg(state, CX24116_REG_EXECUTE)) {
552 msleep(10);
553 if (i++ > 64) {
554 /* Avoid looping forever if the firmware does
555 not respond */
556 printk(KERN_WARNING "%s() Firmware not responding\n",
557 __func__);
558 return -EREMOTEIO;
559 }
560 }
561 return 0;
562}
563
564static int cx24116_load_firmware(struct dvb_frontend *fe,
565 const struct firmware *fw)
566{
567 struct cx24116_state *state = fe->demodulator_priv;
568 struct cx24116_cmd cmd;
569 int i, ret, len, max, remaining;
570 unsigned char vers[4];
571
572 dprintk("%s\n", __func__);
573 dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
574 fw->size,
575 fw->data[0],
576 fw->data[1],
577 fw->data[fw->size-2],
578 fw->data[fw->size-1]);
579
580 /* Toggle 88x SRST pin to reset demod */
581 if (state->config->reset_device)
582 state->config->reset_device(fe);
583
584 /* Begin the firmware load process */
585 /* Prepare the demod, load the firmware, cleanup after load */
586
587 /* Init PLL */
588 cx24116_writereg(state, 0xE5, 0x00);
589 cx24116_writereg(state, 0xF1, 0x08);
590 cx24116_writereg(state, 0xF2, 0x13);
591
592 /* Start PLL */
593 cx24116_writereg(state, 0xe0, 0x03);
594 cx24116_writereg(state, 0xe0, 0x00);
595
596 /* Unknown */
597 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
598 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
599
600 /* Unknown */
601 cx24116_writereg(state, 0xF0, 0x03);
602 cx24116_writereg(state, 0xF4, 0x81);
603 cx24116_writereg(state, 0xF5, 0x00);
604 cx24116_writereg(state, 0xF6, 0x00);
605
606 /* Split firmware to the max I2C write len and write.
607 * Writes whole firmware as one write when i2c_wr_max is set to 0. */
608 if (state->config->i2c_wr_max)
609 max = state->config->i2c_wr_max;
610 else
611 max = INT_MAX; /* enough for 32k firmware */
612
613 for (remaining = fw->size; remaining > 0; remaining -= max - 1) {
614 len = remaining;
615 if (len > max - 1)
616 len = max - 1;
617
618 cx24116_writeregN(state, 0xF7, &fw->data[fw->size - remaining],
619 len);
620 }
621
622 cx24116_writereg(state, 0xF4, 0x10);
623 cx24116_writereg(state, 0xF0, 0x00);
624 cx24116_writereg(state, 0xF8, 0x06);
625
626 /* Firmware CMD 10: VCO config */
627 cmd.args[0x00] = CMD_SET_VCO;
628 cmd.args[0x01] = 0x05;
629 cmd.args[0x02] = 0xdc;
630 cmd.args[0x03] = 0xda;
631 cmd.args[0x04] = 0xae;
632 cmd.args[0x05] = 0xaa;
633 cmd.args[0x06] = 0x04;
634 cmd.args[0x07] = 0x9d;
635 cmd.args[0x08] = 0xfc;
636 cmd.args[0x09] = 0x06;
637 cmd.len = 0x0a;
638 ret = cx24116_cmd_execute(fe, &cmd);
639 if (ret != 0)
640 return ret;
641
642 cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00);
643
644 /* Firmware CMD 14: Tuner config */
645 cmd.args[0x00] = CMD_TUNERINIT;
646 cmd.args[0x01] = 0x00;
647 cmd.args[0x02] = 0x00;
648 cmd.len = 0x03;
649 ret = cx24116_cmd_execute(fe, &cmd);
650 if (ret != 0)
651 return ret;
652
653 cx24116_writereg(state, 0xe5, 0x00);
654
655 /* Firmware CMD 13: MPEG config */
656 cmd.args[0x00] = CMD_MPEGCONFIG;
657 cmd.args[0x01] = 0x01;
658 cmd.args[0x02] = 0x75;
659 cmd.args[0x03] = 0x00;
660 if (state->config->mpg_clk_pos_pol)
661 cmd.args[0x04] = state->config->mpg_clk_pos_pol;
662 else
663 cmd.args[0x04] = 0x02;
664 cmd.args[0x05] = 0x00;
665 cmd.len = 0x06;
666 ret = cx24116_cmd_execute(fe, &cmd);
667 if (ret != 0)
668 return ret;
669
670 /* Firmware CMD 35: Get firmware version */
671 cmd.args[0x00] = CMD_UPDFWVERS;
672 cmd.len = 0x02;
673 for (i = 0; i < 4; i++) {
674 cmd.args[0x01] = i;
675 ret = cx24116_cmd_execute(fe, &cmd);
676 if (ret != 0)
677 return ret;
678 vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX);
679 }
680 printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__,
681 vers[0], vers[1], vers[2], vers[3]);
682
683 return 0;
684}
685
686static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status)
687{
688 struct cx24116_state *state = fe->demodulator_priv;
689
690 int lock = cx24116_readreg(state, CX24116_REG_SSTATUS) &
691 CX24116_STATUS_MASK;
692
693 dprintk("%s: status = 0x%02x\n", __func__, lock);
694
695 *status = 0;
696
697 if (lock & CX24116_HAS_SIGNAL)
698 *status |= FE_HAS_SIGNAL;
699 if (lock & CX24116_HAS_CARRIER)
700 *status |= FE_HAS_CARRIER;
701 if (lock & CX24116_HAS_VITERBI)
702 *status |= FE_HAS_VITERBI;
703 if (lock & CX24116_HAS_SYNCLOCK)
704 *status |= FE_HAS_SYNC | FE_HAS_LOCK;
705
706 return 0;
707}
708
709static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber)
710{
711 struct cx24116_state *state = fe->demodulator_priv;
712
713 dprintk("%s()\n", __func__);
714
715 *ber = (cx24116_readreg(state, CX24116_REG_BER24) << 24) |
716 (cx24116_readreg(state, CX24116_REG_BER16) << 16) |
717 (cx24116_readreg(state, CX24116_REG_BER8) << 8) |
718 cx24116_readreg(state, CX24116_REG_BER0);
719
720 return 0;
721}
722
723/* TODO Determine function and scale appropriately */
724static int cx24116_read_signal_strength(struct dvb_frontend *fe,
725 u16 *signal_strength)
726{
727 struct cx24116_state *state = fe->demodulator_priv;
728 struct cx24116_cmd cmd;
729 int ret;
730 u16 sig_reading;
731
732 dprintk("%s()\n", __func__);
733
734 /* Firmware CMD 19: Get AGC */
735 cmd.args[0x00] = CMD_GETAGC;
736 cmd.len = 0x01;
737 ret = cx24116_cmd_execute(fe, &cmd);
738 if (ret != 0)
739 return ret;
740
741 sig_reading =
742 (cx24116_readreg(state,
743 CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) |
744 (cx24116_readreg(state, CX24116_REG_SIGNAL) << 6);
745 *signal_strength = 0 - sig_reading;
746
747 dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n",
748 __func__, sig_reading, *signal_strength);
749
750 return 0;
751}
752
753/* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */
754static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr)
755{
756 struct cx24116_state *state = fe->demodulator_priv;
757 u8 snr_reading;
758 static const u32 snr_tab[] = { /* 10 x Table (rounded up) */
759 0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667,
760 0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667,
761 0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667,
762 0x18000 };
763
764 dprintk("%s()\n", __func__);
765
766 snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0);
767
768 if (snr_reading >= 0xa0 /* 100% */)
769 *snr = 0xffff;
770 else
771 *snr = snr_tab[(snr_reading & 0xf0) >> 4] +
772 (snr_tab[(snr_reading & 0x0f)] >> 4);
773
774 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
775 snr_reading, *snr);
776
777 return 0;
778}
779
780/* The reelbox patches show the value in the registers represents
781 * ESNO, from 0->30db (values 0->300). We provide this value by
782 * default.
783 */
784static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr)
785{
786 struct cx24116_state *state = fe->demodulator_priv;
787
788 dprintk("%s()\n", __func__);
789
790 *snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 |
791 cx24116_readreg(state, CX24116_REG_QUALITY0);
792
793 dprintk("%s: raw 0x%04x\n", __func__, *snr);
794
795 return 0;
796}
797
798static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr)
799{
800 if (esno_snr == 1)
801 return cx24116_read_snr_esno(fe, snr);
802 else
803 return cx24116_read_snr_pct(fe, snr);
804}
805
806static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
807{
808 struct cx24116_state *state = fe->demodulator_priv;
809
810 dprintk("%s()\n", __func__);
811
812 *ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) |
813 cx24116_readreg(state, CX24116_REG_UCB0);
814
815 return 0;
816}
817
818/* Overwrite the current tuning params, we are about to tune */
819static void cx24116_clone_params(struct dvb_frontend *fe)
820{
821 struct cx24116_state *state = fe->demodulator_priv;
822 memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
823}
824
825/* Wait for LNB */
826static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
827{
828 struct cx24116_state *state = fe->demodulator_priv;
829 int i;
830
831 dprintk("%s() qstatus = 0x%02x\n", __func__,
832 cx24116_readreg(state, CX24116_REG_QSTATUS));
833
834 /* Wait for up to 300 ms */
835 for (i = 0; i < 30 ; i++) {
836 if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20)
837 return 0;
838 msleep(10);
839 }
840
841 dprintk("%s(): LNB not ready\n", __func__);
842
843 return -ETIMEDOUT; /* -EBUSY ? */
844}
845
846static int cx24116_set_voltage(struct dvb_frontend *fe,
847 fe_sec_voltage_t voltage)
848{
849 struct cx24116_cmd cmd;
850 int ret;
851
852 dprintk("%s: %s\n", __func__,
853 voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
854 voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
855
856 /* Wait for LNB ready */
857 ret = cx24116_wait_for_lnb(fe);
858 if (ret != 0)
859 return ret;
860
861 /* Wait for voltage/min repeat delay */
862 msleep(100);
863
864 cmd.args[0x00] = CMD_LNBDCLEVEL;
865 cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00);
866 cmd.len = 0x02;
867
868 /* Min delay time before DiSEqC send */
869 msleep(15);
870
871 return cx24116_cmd_execute(fe, &cmd);
872}
873
874static int cx24116_set_tone(struct dvb_frontend *fe,
875 fe_sec_tone_mode_t tone)
876{
877 struct cx24116_cmd cmd;
878 int ret;
879
880 dprintk("%s(%d)\n", __func__, tone);
881 if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
882 printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
883 return -EINVAL;
884 }
885
886 /* Wait for LNB ready */
887 ret = cx24116_wait_for_lnb(fe);
888 if (ret != 0)
889 return ret;
890
891 /* Min delay time after DiSEqC send */
892 msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
893
894 /* Now we set the tone */
895 cmd.args[0x00] = CMD_SET_TONE;
896 cmd.args[0x01] = 0x00;
897 cmd.args[0x02] = 0x00;
898
899 switch (tone) {
900 case SEC_TONE_ON:
901 dprintk("%s: setting tone on\n", __func__);
902 cmd.args[0x03] = 0x01;
903 break;
904 case SEC_TONE_OFF:
905 dprintk("%s: setting tone off\n", __func__);
906 cmd.args[0x03] = 0x00;
907 break;
908 }
909 cmd.len = 0x04;
910
911 /* Min delay time before DiSEqC send */
912 msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
913
914 return cx24116_cmd_execute(fe, &cmd);
915}
916
917/* Initialise DiSEqC */
918static int cx24116_diseqc_init(struct dvb_frontend *fe)
919{
920 struct cx24116_state *state = fe->demodulator_priv;
921 struct cx24116_cmd cmd;
922 int ret;
923
924 /* Firmware CMD 20: LNB/DiSEqC config */
925 cmd.args[0x00] = CMD_LNBCONFIG;
926 cmd.args[0x01] = 0x00;
927 cmd.args[0x02] = 0x10;
928 cmd.args[0x03] = 0x00;
929 cmd.args[0x04] = 0x8f;
930 cmd.args[0x05] = 0x28;
931 cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01;
932 cmd.args[0x07] = 0x01;
933 cmd.len = 0x08;
934 ret = cx24116_cmd_execute(fe, &cmd);
935 if (ret != 0)
936 return ret;
937
938 /* Prepare a DiSEqC command */
939 state->dsec_cmd.args[0x00] = CMD_LNBSEND;
940
941 /* DiSEqC burst */
942 state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A;
943
944 /* Unknown */
945 state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02;
946 state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00;
947 /* Continuation flag? */
948 state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00;
949
950 /* DiSEqC message length */
951 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00;
952
953 /* Command length */
954 state->dsec_cmd.len = CX24116_DISEQC_MSGOFS;
955
956 return 0;
957}
958
959/* Send DiSEqC message with derived burst (hack) || previous burst */
960static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
961 struct dvb_diseqc_master_cmd *d)
962{
963 struct cx24116_state *state = fe->demodulator_priv;
964 int i, ret;
965
966 /* Dump DiSEqC message */
967 if (debug) {
968 printk(KERN_INFO "cx24116: %s(", __func__);
969 for (i = 0 ; i < d->msg_len ;) {
970 printk(KERN_INFO "0x%02x", d->msg[i]);
971 if (++i < d->msg_len)
972 printk(KERN_INFO ", ");
973 }
974 printk(") toneburst=%d\n", toneburst);
975 }
976
977 /* Validate length */
978 if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS))
979 return -EINVAL;
980
981 /* DiSEqC message */
982 for (i = 0; i < d->msg_len; i++)
983 state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i];
984
985 /* DiSEqC message length */
986 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len;
987
988 /* Command length */
989 state->dsec_cmd.len = CX24116_DISEQC_MSGOFS +
990 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN];
991
992 /* DiSEqC toneburst */
993 if (toneburst == CX24116_DISEQC_MESGCACHE)
994 /* Message is cached */
995 return 0;
996
997 else if (toneburst == CX24116_DISEQC_TONEOFF)
998 /* Message is sent without burst */
999 state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0;
1000
1001 else if (toneburst == CX24116_DISEQC_TONECACHE) {
1002 /*
1003 * Message is sent with derived else cached burst
1004 *
1005 * WRITE PORT GROUP COMMAND 38
1006 *
1007 * 0/A/A: E0 10 38 F0..F3
1008 * 1/B/B: E0 10 38 F4..F7
1009 * 2/C/A: E0 10 38 F8..FB
1010 * 3/D/B: E0 10 38 FC..FF
1011 *
1012 * databyte[3]= 8421:8421
1013 * ABCD:WXYZ
1014 * CLR :SET
1015 *
1016 * WX= PORT SELECT 0..3 (X=TONEBURST)
1017 * Y = VOLTAGE (0=13V, 1=18V)
1018 * Z = BAND (0=LOW, 1=HIGH(22K))
1019 */
1020 if (d->msg_len >= 4 && d->msg[2] == 0x38)
1021 state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1022 ((d->msg[3] & 4) >> 2);
1023 if (debug)
1024 dprintk("%s burst=%d\n", __func__,
1025 state->dsec_cmd.args[CX24116_DISEQC_BURST]);
1026 }
1027
1028 /* Wait for LNB ready */
1029 ret = cx24116_wait_for_lnb(fe);
1030 if (ret != 0)
1031 return ret;
1032
1033 /* Wait for voltage/min repeat delay */
1034 msleep(100);
1035
1036 /* Command */
1037 ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1038 if (ret != 0)
1039 return ret;
1040 /*
1041 * Wait for send
1042 *
1043 * Eutelsat spec:
1044 * >15ms delay + (XXX determine if FW does this, see set_tone)
1045 * 13.5ms per byte +
1046 * >15ms delay +
1047 * 12.5ms burst +
1048 * >15ms delay (XXX determine if FW does this, see set_tone)
1049 */
1050 msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) +
1051 ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60));
1052
1053 return 0;
1054}
1055
1056/* Send DiSEqC burst */
1057static int cx24116_diseqc_send_burst(struct dvb_frontend *fe,
1058 fe_sec_mini_cmd_t burst)
1059{
1060 struct cx24116_state *state = fe->demodulator_priv;
1061 int ret;
1062
1063 dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst);
1064
1065 /* DiSEqC burst */
1066 if (burst == SEC_MINI_A)
1067 state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1068 CX24116_DISEQC_MINI_A;
1069 else if (burst == SEC_MINI_B)
1070 state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1071 CX24116_DISEQC_MINI_B;
1072 else
1073 return -EINVAL;
1074
1075 /* DiSEqC toneburst */
1076 if (toneburst != CX24116_DISEQC_MESGCACHE)
1077 /* Burst is cached */
1078 return 0;
1079
1080 /* Burst is to be sent with cached message */
1081
1082 /* Wait for LNB ready */
1083 ret = cx24116_wait_for_lnb(fe);
1084 if (ret != 0)
1085 return ret;
1086
1087 /* Wait for voltage/min repeat delay */
1088 msleep(100);
1089
1090 /* Command */
1091 ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1092 if (ret != 0)
1093 return ret;
1094
1095 /*
1096 * Wait for send
1097 *
1098 * Eutelsat spec:
1099 * >15ms delay + (XXX determine if FW does this, see set_tone)
1100 * 13.5ms per byte +
1101 * >15ms delay +
1102 * 12.5ms burst +
1103 * >15ms delay (XXX determine if FW does this, see set_tone)
1104 */
1105 msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60);
1106
1107 return 0;
1108}
1109
1110static void cx24116_release(struct dvb_frontend *fe)
1111{
1112 struct cx24116_state *state = fe->demodulator_priv;
1113 dprintk("%s\n", __func__);
1114 kfree(state);
1115}
1116
1117static struct dvb_frontend_ops cx24116_ops;
1118
1119struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
1120 struct i2c_adapter *i2c)
1121{
1122 struct cx24116_state *state = NULL;
1123 int ret;
1124
1125 dprintk("%s\n", __func__);
1126
1127 /* allocate memory for the internal state */
1128 state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL);
1129 if (state == NULL)
1130 goto error1;
1131
1132 state->config = config;
1133 state->i2c = i2c;
1134
1135 /* check if the demod is present */
1136 ret = (cx24116_readreg(state, 0xFF) << 8) |
1137 cx24116_readreg(state, 0xFE);
1138 if (ret != 0x0501) {
1139 printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n");
1140 goto error2;
1141 }
1142
1143 /* create dvb_frontend */
1144 memcpy(&state->frontend.ops, &cx24116_ops,
1145 sizeof(struct dvb_frontend_ops));
1146 state->frontend.demodulator_priv = state;
1147 return &state->frontend;
1148
1149error2: kfree(state);
1150error1: return NULL;
1151}
1152EXPORT_SYMBOL(cx24116_attach);
1153
1154/*
1155 * Initialise or wake up device
1156 *
1157 * Power config will reset and load initial firmware if required
1158 */
1159static int cx24116_initfe(struct dvb_frontend *fe)
1160{
1161 struct cx24116_state *state = fe->demodulator_priv;
1162 struct cx24116_cmd cmd;
1163 int ret;
1164
1165 dprintk("%s()\n", __func__);
1166
1167 /* Power on */
1168 cx24116_writereg(state, 0xe0, 0);
1169 cx24116_writereg(state, 0xe1, 0);
1170 cx24116_writereg(state, 0xea, 0);
1171
1172 /* Firmware CMD 36: Power config */
1173 cmd.args[0x00] = CMD_TUNERSLEEP;
1174 cmd.args[0x01] = 0;
1175 cmd.len = 0x02;
1176 ret = cx24116_cmd_execute(fe, &cmd);
1177 if (ret != 0)
1178 return ret;
1179
1180 ret = cx24116_diseqc_init(fe);
1181 if (ret != 0)
1182 return ret;
1183
1184 /* HVR-4000 needs this */
1185 return cx24116_set_voltage(fe, SEC_VOLTAGE_13);
1186}
1187
1188/*
1189 * Put device to sleep
1190 */
1191static int cx24116_sleep(struct dvb_frontend *fe)
1192{
1193 struct cx24116_state *state = fe->demodulator_priv;
1194 struct cx24116_cmd cmd;
1195 int ret;
1196
1197 dprintk("%s()\n", __func__);
1198
1199 /* Firmware CMD 36: Power config */
1200 cmd.args[0x00] = CMD_TUNERSLEEP;
1201 cmd.args[0x01] = 1;
1202 cmd.len = 0x02;
1203 ret = cx24116_cmd_execute(fe, &cmd);
1204 if (ret != 0)
1205 return ret;
1206
1207 /* Power off (Shutdown clocks) */
1208 cx24116_writereg(state, 0xea, 0xff);
1209 cx24116_writereg(state, 0xe1, 1);
1210 cx24116_writereg(state, 0xe0, 1);
1211
1212 return 0;
1213}
1214
1215static int cx24116_set_property(struct dvb_frontend *fe,
1216 struct dtv_property *tvp)
1217{
1218 dprintk("%s(..)\n", __func__);
1219 return 0;
1220}
1221
1222static int cx24116_get_property(struct dvb_frontend *fe,
1223 struct dtv_property *tvp)
1224{
1225 dprintk("%s(..)\n", __func__);
1226 return 0;
1227}
1228
1229/* dvb-core told us to tune, the tv property cache will be complete,
1230 * it's safe for is to pull values and use them for tuning purposes.
1231 */
1232static int cx24116_set_frontend(struct dvb_frontend *fe,
1233 struct dvb_frontend_parameters *p)
1234{
1235 struct cx24116_state *state = fe->demodulator_priv;
1236 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1237 struct cx24116_cmd cmd;
1238 fe_status_t tunerstat;
1239 int i, status, ret, retune = 1;
1240
1241 dprintk("%s()\n", __func__);
1242
1243 switch (c->delivery_system) {
1244 case SYS_DVBS:
1245 dprintk("%s: DVB-S delivery system selected\n", __func__);
1246
1247 /* Only QPSK is supported for DVB-S */
1248 if (c->modulation != QPSK) {
1249 dprintk("%s: unsupported modulation selected (%d)\n",
1250 __func__, c->modulation);
1251 return -EOPNOTSUPP;
1252 }
1253
1254 /* Pilot doesn't exist in DVB-S, turn bit off */
1255 state->dnxt.pilot_val = CX24116_PILOT_OFF;
1256
1257 /* DVB-S only supports 0.35 */
1258 if (c->rolloff != ROLLOFF_35) {
1259 dprintk("%s: unsupported rolloff selected (%d)\n",
1260 __func__, c->rolloff);
1261 return -EOPNOTSUPP;
1262 }
1263 state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1264 break;
1265
1266 case SYS_DVBS2:
1267 dprintk("%s: DVB-S2 delivery system selected\n", __func__);
1268
1269 /*
1270 * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2,
1271 * but not hardware auto detection
1272 */
1273 if (c->modulation != PSK_8 && c->modulation != QPSK) {
1274 dprintk("%s: unsupported modulation selected (%d)\n",
1275 __func__, c->modulation);
1276 return -EOPNOTSUPP;
1277 }
1278
1279 switch (c->pilot) {
1280 case PILOT_AUTO: /* Not supported but emulated */
1281 state->dnxt.pilot_val = (c->modulation == QPSK)
1282 ? CX24116_PILOT_OFF : CX24116_PILOT_ON;
1283 retune++;
1284 break;
1285 case PILOT_OFF:
1286 state->dnxt.pilot_val = CX24116_PILOT_OFF;
1287 break;
1288 case PILOT_ON:
1289 state->dnxt.pilot_val = CX24116_PILOT_ON;
1290 break;
1291 default:
1292 dprintk("%s: unsupported pilot mode selected (%d)\n",
1293 __func__, c->pilot);
1294 return -EOPNOTSUPP;
1295 }
1296
1297 switch (c->rolloff) {
1298 case ROLLOFF_20:
1299 state->dnxt.rolloff_val = CX24116_ROLLOFF_020;
1300 break;
1301 case ROLLOFF_25:
1302 state->dnxt.rolloff_val = CX24116_ROLLOFF_025;
1303 break;
1304 case ROLLOFF_35:
1305 state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1306 break;
1307 case ROLLOFF_AUTO: /* Rolloff must be explicit */
1308 default:
1309 dprintk("%s: unsupported rolloff selected (%d)\n",
1310 __func__, c->rolloff);
1311 return -EOPNOTSUPP;
1312 }
1313 break;
1314
1315 default:
1316 dprintk("%s: unsupported delivery system selected (%d)\n",
1317 __func__, c->delivery_system);
1318 return -EOPNOTSUPP;
1319 }
1320 state->dnxt.delsys = c->delivery_system;
1321 state->dnxt.modulation = c->modulation;
1322 state->dnxt.frequency = c->frequency;
1323 state->dnxt.pilot = c->pilot;
1324 state->dnxt.rolloff = c->rolloff;
1325
1326 ret = cx24116_set_inversion(state, c->inversion);
1327 if (ret != 0)
1328 return ret;
1329
1330 /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
1331 ret = cx24116_set_fec(state, c->delivery_system, c->modulation, c->fec_inner);
1332 if (ret != 0)
1333 return ret;
1334
1335 ret = cx24116_set_symbolrate(state, c->symbol_rate);
1336 if (ret != 0)
1337 return ret;
1338
1339 /* discard the 'current' tuning parameters and prepare to tune */
1340 cx24116_clone_params(fe);
1341
1342 dprintk("%s: delsys = %d\n", __func__, state->dcur.delsys);
1343 dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation);
1344 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency);
1345 dprintk("%s: pilot = %d (val = 0x%02x)\n", __func__,
1346 state->dcur.pilot, state->dcur.pilot_val);
1347 dprintk("%s: retune = %d\n", __func__, retune);
1348 dprintk("%s: rolloff = %d (val = 0x%02x)\n", __func__,
1349 state->dcur.rolloff, state->dcur.rolloff_val);
1350 dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
1351 dprintk("%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__,
1352 state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val);
1353 dprintk("%s: Inversion = %d (val = 0x%02x)\n", __func__,
1354 state->dcur.inversion, state->dcur.inversion_val);
1355
1356 /* This is also done in advise/acquire on HVR4000 but not on LITE */
1357 if (state->config->set_ts_params)
1358 state->config->set_ts_params(fe, 0);
1359
1360 /* Set/Reset B/W */
1361 cmd.args[0x00] = CMD_BANDWIDTH;
1362 cmd.args[0x01] = 0x01;
1363 cmd.len = 0x02;
1364 ret = cx24116_cmd_execute(fe, &cmd);
1365 if (ret != 0)
1366 return ret;
1367
1368 /* Prepare a tune request */
1369 cmd.args[0x00] = CMD_TUNEREQUEST;
1370
1371 /* Frequency */
1372 cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16;
1373 cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8;
1374 cmd.args[0x03] = (state->dcur.frequency & 0x0000ff);
1375
1376 /* Symbol Rate */
1377 cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8;
1378 cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff);
1379
1380 /* Automatic Inversion */
1381 cmd.args[0x06] = state->dcur.inversion_val;
1382
1383 /* Modulation / FEC / Pilot */
1384 cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val;
1385
1386 cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8;
1387 cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff;
1388 cmd.args[0x0a] = 0x00;
1389 cmd.args[0x0b] = 0x00;
1390 cmd.args[0x0c] = state->dcur.rolloff_val;
1391 cmd.args[0x0d] = state->dcur.fec_mask;
1392
1393 if (state->dcur.symbol_rate > 30000000) {
1394 cmd.args[0x0e] = 0x04;
1395 cmd.args[0x0f] = 0x00;
1396 cmd.args[0x10] = 0x01;
1397 cmd.args[0x11] = 0x77;
1398 cmd.args[0x12] = 0x36;
1399 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44);
1400 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01);
1401 } else {
1402 cmd.args[0x0e] = 0x06;
1403 cmd.args[0x0f] = 0x00;
1404 cmd.args[0x10] = 0x00;
1405 cmd.args[0x11] = 0xFA;
1406 cmd.args[0x12] = 0x24;
1407 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
1408 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
1409 }
1410
1411 cmd.len = 0x13;
1412
1413 /* We need to support pilot and non-pilot tuning in the
1414 * driver automatically. This is a workaround for because
1415 * the demod does not support autodetect.
1416 */
1417 do {
1418 /* Reset status register */
1419 status = cx24116_readreg(state, CX24116_REG_SSTATUS)
1420 & CX24116_SIGNAL_MASK;
1421 cx24116_writereg(state, CX24116_REG_SSTATUS, status);
1422
1423 /* Tune */
1424 ret = cx24116_cmd_execute(fe, &cmd);
1425 if (ret != 0)
1426 break;
1427
1428 /*
1429 * Wait for up to 500 ms before retrying
1430 *
1431 * If we are able to tune then generally it occurs within 100ms.
1432 * If it takes longer, try a different toneburst setting.
1433 */
1434 for (i = 0; i < 50 ; i++) {
1435 cx24116_read_status(fe, &tunerstat);
1436 status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC);
1437 if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) {
1438 dprintk("%s: Tuned\n", __func__);
1439 goto tuned;
1440 }
1441 msleep(10);
1442 }
1443
1444 dprintk("%s: Not tuned\n", __func__);
1445
1446 /* Toggle pilot bit when in auto-pilot */
1447 if (state->dcur.pilot == PILOT_AUTO)
1448 cmd.args[0x07] ^= CX24116_PILOT_ON;
1449 } while (--retune);
1450
1451tuned: /* Set/Reset B/W */
1452 cmd.args[0x00] = CMD_BANDWIDTH;
1453 cmd.args[0x01] = 0x00;
1454 cmd.len = 0x02;
1455 return cx24116_cmd_execute(fe, &cmd);
1456}
1457
1458static int cx24116_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *params,
1459 unsigned int mode_flags, unsigned int *delay, fe_status_t *status)
1460{
1461 *delay = HZ / 5;
1462 if (params) {
1463 int ret = cx24116_set_frontend(fe, params);
1464 if (ret)
1465 return ret;
1466 }
1467 return cx24116_read_status(fe, status);
1468}
1469
1470static int cx24116_get_algo(struct dvb_frontend *fe)
1471{
1472 return DVBFE_ALGO_HW;
1473}
1474
1475static struct dvb_frontend_ops cx24116_ops = {
1476
1477 .info = {
1478 .name = "Conexant CX24116/CX24118",
1479 .type = FE_QPSK,
1480 .frequency_min = 950000,
1481 .frequency_max = 2150000,
1482 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
1483 .frequency_tolerance = 5000,
1484 .symbol_rate_min = 1000000,
1485 .symbol_rate_max = 45000000,
1486 .caps = FE_CAN_INVERSION_AUTO |
1487 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1488 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1489 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1490 FE_CAN_2G_MODULATION |
1491 FE_CAN_QPSK | FE_CAN_RECOVER
1492 },
1493
1494 .release = cx24116_release,
1495
1496 .init = cx24116_initfe,
1497 .sleep = cx24116_sleep,
1498 .read_status = cx24116_read_status,
1499 .read_ber = cx24116_read_ber,
1500 .read_signal_strength = cx24116_read_signal_strength,
1501 .read_snr = cx24116_read_snr,
1502 .read_ucblocks = cx24116_read_ucblocks,
1503 .set_tone = cx24116_set_tone,
1504 .set_voltage = cx24116_set_voltage,
1505 .diseqc_send_master_cmd = cx24116_send_diseqc_msg,
1506 .diseqc_send_burst = cx24116_diseqc_send_burst,
1507 .get_frontend_algo = cx24116_get_algo,
1508 .tune = cx24116_tune,
1509
1510 .set_property = cx24116_set_property,
1511 .get_property = cx24116_get_property,
1512 .set_frontend = cx24116_set_frontend,
1513};
1514
1515MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware");
1516MODULE_AUTHOR("Steven Toth");
1517MODULE_LICENSE("GPL");
1518
diff --git a/drivers/media/dvb/frontends/cx24116.h b/drivers/media/dvb/frontends/cx24116.h
new file mode 100644
index 00000000000..7d90ab949c0
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24116.h
@@ -0,0 +1,58 @@
1/*
2 Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
3
4 Copyright (C) 2006 Steven Toth <stoth@linuxtv.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 CX24116_H
22#define CX24116_H
23
24#include <linux/dvb/frontend.h>
25
26struct cx24116_config {
27 /* the demodulator's i2c address */
28 u8 demod_address;
29
30 /* Need to set device param for start_dma */
31 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
32
33 /* Need to reset device during firmware loading */
34 int (*reset_device)(struct dvb_frontend *fe);
35
36 /* Need to set MPEG parameters */
37 u8 mpg_clk_pos_pol:0x02;
38
39 /* max bytes I2C provider can write at once */
40 u16 i2c_wr_max;
41};
42
43#if defined(CONFIG_DVB_CX24116) || \
44 (defined(CONFIG_DVB_CX24116_MODULE) && defined(MODULE))
45extern struct dvb_frontend *cx24116_attach(
46 const struct cx24116_config *config,
47 struct i2c_adapter *i2c);
48#else
49static inline struct dvb_frontend *cx24116_attach(
50 const struct cx24116_config *config,
51 struct i2c_adapter *i2c)
52{
53 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
54 return NULL;
55}
56#endif
57
58#endif /* CX24116_H */
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
new file mode 100644
index 00000000000..b1dd8acc607
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -0,0 +1,1167 @@
1/*
2 * Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
3 *
4 * Copyright (C) 2005 Steven Toth <stoth@linuxtv.org>
5 *
6 * Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc>
7 *
8 * Support for CX24123/CX24113-NIM by Patrick Boettcher <pb@linuxtv.org>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (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 GNU
18 * 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
25#include <linux/slab.h>
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/init.h>
29
30#include "dvb_frontend.h"
31#include "cx24123.h"
32
33#define XTAL 10111000
34
35static int force_band;
36module_param(force_band, int, 0644);
37MODULE_PARM_DESC(force_band, "Force a specific band select "\
38 "(1-9, default:off).");
39
40static int debug;
41module_param(debug, int, 0644);
42MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
43
44#define info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0)
45#define err(args...) do { printk(KERN_ERR "CX24123: " args); } while (0)
46
47#define dprintk(args...) \
48 do { \
49 if (debug) { \
50 printk(KERN_DEBUG "CX24123: %s: ", __func__); \
51 printk(args); \
52 } \
53 } while (0)
54
55struct cx24123_state {
56 struct i2c_adapter *i2c;
57 const struct cx24123_config *config;
58
59 struct dvb_frontend frontend;
60
61 /* Some PLL specifics for tuning */
62 u32 VCAarg;
63 u32 VGAarg;
64 u32 bandselectarg;
65 u32 pllarg;
66 u32 FILTune;
67
68 struct i2c_adapter tuner_i2c_adapter;
69
70 u8 demod_rev;
71
72 /* The Demod/Tuner can't easily provide these, we cache them */
73 u32 currentfreq;
74 u32 currentsymbolrate;
75};
76
77/* Various tuner defaults need to be established for a given symbol rate Sps */
78static struct cx24123_AGC_val {
79 u32 symbolrate_low;
80 u32 symbolrate_high;
81 u32 VCAprogdata;
82 u32 VGAprogdata;
83 u32 FILTune;
84} cx24123_AGC_vals[] =
85{
86 {
87 .symbolrate_low = 1000000,
88 .symbolrate_high = 4999999,
89 /* the specs recommend other values for VGA offsets,
90 but tests show they are wrong */
91 .VGAprogdata = (1 << 19) | (0x180 << 9) | 0x1e0,
92 .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x07,
93 .FILTune = 0x27f /* 0.41 V */
94 },
95 {
96 .symbolrate_low = 5000000,
97 .symbolrate_high = 14999999,
98 .VGAprogdata = (1 << 19) | (0x180 << 9) | 0x1e0,
99 .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x1f,
100 .FILTune = 0x317 /* 0.90 V */
101 },
102 {
103 .symbolrate_low = 15000000,
104 .symbolrate_high = 45000000,
105 .VGAprogdata = (1 << 19) | (0x100 << 9) | 0x180,
106 .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x3f,
107 .FILTune = 0x145 /* 2.70 V */
108 },
109};
110
111/*
112 * Various tuner defaults need to be established for a given frequency kHz.
113 * fixme: The bounds on the bands do not match the doc in real life.
114 * fixme: Some of them have been moved, other might need adjustment.
115 */
116static struct cx24123_bandselect_val {
117 u32 freq_low;
118 u32 freq_high;
119 u32 VCOdivider;
120 u32 progdata;
121} cx24123_bandselect_vals[] =
122{
123 /* band 1 */
124 {
125 .freq_low = 950000,
126 .freq_high = 1074999,
127 .VCOdivider = 4,
128 .progdata = (0 << 19) | (0 << 9) | 0x40,
129 },
130
131 /* band 2 */
132 {
133 .freq_low = 1075000,
134 .freq_high = 1177999,
135 .VCOdivider = 4,
136 .progdata = (0 << 19) | (0 << 9) | 0x80,
137 },
138
139 /* band 3 */
140 {
141 .freq_low = 1178000,
142 .freq_high = 1295999,
143 .VCOdivider = 2,
144 .progdata = (0 << 19) | (1 << 9) | 0x01,
145 },
146
147 /* band 4 */
148 {
149 .freq_low = 1296000,
150 .freq_high = 1431999,
151 .VCOdivider = 2,
152 .progdata = (0 << 19) | (1 << 9) | 0x02,
153 },
154
155 /* band 5 */
156 {
157 .freq_low = 1432000,
158 .freq_high = 1575999,
159 .VCOdivider = 2,
160 .progdata = (0 << 19) | (1 << 9) | 0x04,
161 },
162
163 /* band 6 */
164 {
165 .freq_low = 1576000,
166 .freq_high = 1717999,
167 .VCOdivider = 2,
168 .progdata = (0 << 19) | (1 << 9) | 0x08,
169 },
170
171 /* band 7 */
172 {
173 .freq_low = 1718000,
174 .freq_high = 1855999,
175 .VCOdivider = 2,
176 .progdata = (0 << 19) | (1 << 9) | 0x10,
177 },
178
179 /* band 8 */
180 {
181 .freq_low = 1856000,
182 .freq_high = 2035999,
183 .VCOdivider = 2,
184 .progdata = (0 << 19) | (1 << 9) | 0x20,
185 },
186
187 /* band 9 */
188 {
189 .freq_low = 2036000,
190 .freq_high = 2150000,
191 .VCOdivider = 2,
192 .progdata = (0 << 19) | (1 << 9) | 0x40,
193 },
194};
195
196static struct {
197 u8 reg;
198 u8 data;
199} cx24123_regdata[] =
200{
201 {0x00, 0x03}, /* Reset system */
202 {0x00, 0x00}, /* Clear reset */
203 {0x03, 0x07}, /* QPSK, DVB, Auto Acquisition (default) */
204 {0x04, 0x10}, /* MPEG */
205 {0x05, 0x04}, /* MPEG */
206 {0x06, 0x31}, /* MPEG (default) */
207 {0x0b, 0x00}, /* Freq search start point (default) */
208 {0x0c, 0x00}, /* Demodulator sample gain (default) */
209 {0x0d, 0x7f}, /* Force driver to shift until the maximum (+-10 MHz) */
210 {0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */
211 {0x0f, 0xfe}, /* FEC search mask (all supported codes) */
212 {0x10, 0x01}, /* Default search inversion, no repeat (default) */
213 {0x16, 0x00}, /* Enable reading of frequency */
214 {0x17, 0x01}, /* Enable EsNO Ready Counter */
215 {0x1c, 0x80}, /* Enable error counter */
216 {0x20, 0x00}, /* Tuner burst clock rate = 500KHz */
217 {0x21, 0x15}, /* Tuner burst mode, word length = 0x15 */
218 {0x28, 0x00}, /* Enable FILTERV with positive pol., DiSEqC 2.x off */
219 {0x29, 0x00}, /* DiSEqC LNB_DC off */
220 {0x2a, 0xb0}, /* DiSEqC Parameters (default) */
221 {0x2b, 0x73}, /* DiSEqC Tone Frequency (default) */
222 {0x2c, 0x00}, /* DiSEqC Message (0x2c - 0x31) */
223 {0x2d, 0x00},
224 {0x2e, 0x00},
225 {0x2f, 0x00},
226 {0x30, 0x00},
227 {0x31, 0x00},
228 {0x32, 0x8c}, /* DiSEqC Parameters (default) */
229 {0x33, 0x00}, /* Interrupts off (0x33 - 0x34) */
230 {0x34, 0x00},
231 {0x35, 0x03}, /* DiSEqC Tone Amplitude (default) */
232 {0x36, 0x02}, /* DiSEqC Parameters (default) */
233 {0x37, 0x3a}, /* DiSEqC Parameters (default) */
234 {0x3a, 0x00}, /* Enable AGC accumulator (for signal strength) */
235 {0x44, 0x00}, /* Constellation (default) */
236 {0x45, 0x00}, /* Symbol count (default) */
237 {0x46, 0x0d}, /* Symbol rate estimator on (default) */
238 {0x56, 0xc1}, /* Error Counter = Viterbi BER */
239 {0x57, 0xff}, /* Error Counter Window (default) */
240 {0x5c, 0x20}, /* Acquisition AFC Expiration window (default is 0x10) */
241 {0x67, 0x83}, /* Non-DCII symbol clock */
242};
243
244static int cx24123_i2c_writereg(struct cx24123_state *state,
245 u8 i2c_addr, int reg, int data)
246{
247 u8 buf[] = { reg, data };
248 struct i2c_msg msg = {
249 .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
250 };
251 int err;
252
253 /* printk(KERN_DEBUG "wr(%02x): %02x %02x\n", i2c_addr, reg, data); */
254
255 err = i2c_transfer(state->i2c, &msg, 1);
256 if (err != 1) {
257 printk("%s: writereg error(err == %i, reg == 0x%02x,"
258 " data == 0x%02x)\n", __func__, err, reg, data);
259 return err;
260 }
261
262 return 0;
263}
264
265static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg)
266{
267 int ret;
268 u8 b = 0;
269 struct i2c_msg msg[] = {
270 { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
271 { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &b, .len = 1 }
272 };
273
274 ret = i2c_transfer(state->i2c, msg, 2);
275
276 if (ret != 2) {
277 err("%s: reg=0x%x (error=%d)\n", __func__, reg, ret);
278 return ret;
279 }
280
281 /* printk(KERN_DEBUG "rd(%02x): %02x %02x\n", i2c_addr, reg, b); */
282
283 return b;
284}
285
286#define cx24123_readreg(state, reg) \
287 cx24123_i2c_readreg(state, state->config->demod_address, reg)
288#define cx24123_writereg(state, reg, val) \
289 cx24123_i2c_writereg(state, state->config->demod_address, reg, val)
290
291static int cx24123_set_inversion(struct cx24123_state *state,
292 fe_spectral_inversion_t inversion)
293{
294 u8 nom_reg = cx24123_readreg(state, 0x0e);
295 u8 auto_reg = cx24123_readreg(state, 0x10);
296
297 switch (inversion) {
298 case INVERSION_OFF:
299 dprintk("inversion off\n");
300 cx24123_writereg(state, 0x0e, nom_reg & ~0x80);
301 cx24123_writereg(state, 0x10, auto_reg | 0x80);
302 break;
303 case INVERSION_ON:
304 dprintk("inversion on\n");
305 cx24123_writereg(state, 0x0e, nom_reg | 0x80);
306 cx24123_writereg(state, 0x10, auto_reg | 0x80);
307 break;
308 case INVERSION_AUTO:
309 dprintk("inversion auto\n");
310 cx24123_writereg(state, 0x10, auto_reg & ~0x80);
311 break;
312 default:
313 return -EINVAL;
314 }
315
316 return 0;
317}
318
319static int cx24123_get_inversion(struct cx24123_state *state,
320 fe_spectral_inversion_t *inversion)
321{
322 u8 val;
323
324 val = cx24123_readreg(state, 0x1b) >> 7;
325
326 if (val == 0) {
327 dprintk("read inversion off\n");
328 *inversion = INVERSION_OFF;
329 } else {
330 dprintk("read inversion on\n");
331 *inversion = INVERSION_ON;
332 }
333
334 return 0;
335}
336
337static int cx24123_set_fec(struct cx24123_state *state, fe_code_rate_t fec)
338{
339 u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07;
340
341 if ((fec < FEC_NONE) || (fec > FEC_AUTO))
342 fec = FEC_AUTO;
343
344 /* Set the soft decision threshold */
345 if (fec == FEC_1_2)
346 cx24123_writereg(state, 0x43,
347 cx24123_readreg(state, 0x43) | 0x01);
348 else
349 cx24123_writereg(state, 0x43,
350 cx24123_readreg(state, 0x43) & ~0x01);
351
352 switch (fec) {
353 case FEC_1_2:
354 dprintk("set FEC to 1/2\n");
355 cx24123_writereg(state, 0x0e, nom_reg | 0x01);
356 cx24123_writereg(state, 0x0f, 0x02);
357 break;
358 case FEC_2_3:
359 dprintk("set FEC to 2/3\n");
360 cx24123_writereg(state, 0x0e, nom_reg | 0x02);
361 cx24123_writereg(state, 0x0f, 0x04);
362 break;
363 case FEC_3_4:
364 dprintk("set FEC to 3/4\n");
365 cx24123_writereg(state, 0x0e, nom_reg | 0x03);
366 cx24123_writereg(state, 0x0f, 0x08);
367 break;
368 case FEC_4_5:
369 dprintk("set FEC to 4/5\n");
370 cx24123_writereg(state, 0x0e, nom_reg | 0x04);
371 cx24123_writereg(state, 0x0f, 0x10);
372 break;
373 case FEC_5_6:
374 dprintk("set FEC to 5/6\n");
375 cx24123_writereg(state, 0x0e, nom_reg | 0x05);
376 cx24123_writereg(state, 0x0f, 0x20);
377 break;
378 case FEC_6_7:
379 dprintk("set FEC to 6/7\n");
380 cx24123_writereg(state, 0x0e, nom_reg | 0x06);
381 cx24123_writereg(state, 0x0f, 0x40);
382 break;
383 case FEC_7_8:
384 dprintk("set FEC to 7/8\n");
385 cx24123_writereg(state, 0x0e, nom_reg | 0x07);
386 cx24123_writereg(state, 0x0f, 0x80);
387 break;
388 case FEC_AUTO:
389 dprintk("set FEC to auto\n");
390 cx24123_writereg(state, 0x0f, 0xfe);
391 break;
392 default:
393 return -EOPNOTSUPP;
394 }
395
396 return 0;
397}
398
399static int cx24123_get_fec(struct cx24123_state *state, fe_code_rate_t *fec)
400{
401 int ret;
402
403 ret = cx24123_readreg(state, 0x1b);
404 if (ret < 0)
405 return ret;
406 ret = ret & 0x07;
407
408 switch (ret) {
409 case 1:
410 *fec = FEC_1_2;
411 break;
412 case 2:
413 *fec = FEC_2_3;
414 break;
415 case 3:
416 *fec = FEC_3_4;
417 break;
418 case 4:
419 *fec = FEC_4_5;
420 break;
421 case 5:
422 *fec = FEC_5_6;
423 break;
424 case 6:
425 *fec = FEC_6_7;
426 break;
427 case 7:
428 *fec = FEC_7_8;
429 break;
430 default:
431 /* this can happen when there's no lock */
432 *fec = FEC_NONE;
433 }
434
435 return 0;
436}
437
438/* Approximation of closest integer of log2(a/b). It actually gives the
439 lowest integer i such that 2^i >= round(a/b) */
440static u32 cx24123_int_log2(u32 a, u32 b)
441{
442 u32 exp, nearest = 0;
443 u32 div = a / b;
444 if (a % b >= b / 2)
445 ++div;
446 if (div < (1 << 31)) {
447 for (exp = 1; div > exp; nearest++)
448 exp += exp;
449 }
450 return nearest;
451}
452
453static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
454{
455 u32 tmp, sample_rate, ratio, sample_gain;
456 u8 pll_mult;
457
458 /* check if symbol rate is within limits */
459 if ((srate > state->frontend.ops.info.symbol_rate_max) ||
460 (srate < state->frontend.ops.info.symbol_rate_min))
461 return -EOPNOTSUPP;
462
463 /* choose the sampling rate high enough for the required operation,
464 while optimizing the power consumed by the demodulator */
465 if (srate < (XTAL*2)/2)
466 pll_mult = 2;
467 else if (srate < (XTAL*3)/2)
468 pll_mult = 3;
469 else if (srate < (XTAL*4)/2)
470 pll_mult = 4;
471 else if (srate < (XTAL*5)/2)
472 pll_mult = 5;
473 else if (srate < (XTAL*6)/2)
474 pll_mult = 6;
475 else if (srate < (XTAL*7)/2)
476 pll_mult = 7;
477 else if (srate < (XTAL*8)/2)
478 pll_mult = 8;
479 else
480 pll_mult = 9;
481
482
483 sample_rate = pll_mult * XTAL;
484
485 /*
486 SYSSymbolRate[21:0] = (srate << 23) / sample_rate
487
488 We have to use 32 bit unsigned arithmetic without precision loss.
489 The maximum srate is 45000000 or 0x02AEA540. This number has
490 only 6 clear bits on top, hence we can shift it left only 6 bits
491 at a time. Borrowed from cx24110.c
492 */
493
494 tmp = srate << 6;
495 ratio = tmp / sample_rate;
496
497 tmp = (tmp % sample_rate) << 6;
498 ratio = (ratio << 6) + (tmp / sample_rate);
499
500 tmp = (tmp % sample_rate) << 6;
501 ratio = (ratio << 6) + (tmp / sample_rate);
502
503 tmp = (tmp % sample_rate) << 5;
504 ratio = (ratio << 5) + (tmp / sample_rate);
505
506
507 cx24123_writereg(state, 0x01, pll_mult * 6);
508
509 cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f);
510 cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff);
511 cx24123_writereg(state, 0x0a, ratio & 0xff);
512
513 /* also set the demodulator sample gain */
514 sample_gain = cx24123_int_log2(sample_rate, srate);
515 tmp = cx24123_readreg(state, 0x0c) & ~0xe0;
516 cx24123_writereg(state, 0x0c, tmp | sample_gain << 5);
517
518 dprintk("srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n",
519 srate, ratio, sample_rate, sample_gain);
520
521 return 0;
522}
523
524/*
525 * Based on the required frequency and symbolrate, the tuner AGC has
526 * to be configured and the correct band selected.
527 * Calculate those values.
528 */
529static int cx24123_pll_calculate(struct dvb_frontend *fe,
530 struct dvb_frontend_parameters *p)
531{
532 struct cx24123_state *state = fe->demodulator_priv;
533 u32 ndiv = 0, adiv = 0, vco_div = 0;
534 int i = 0;
535 int pump = 2;
536 int band = 0;
537 int num_bands = ARRAY_SIZE(cx24123_bandselect_vals);
538 struct cx24123_bandselect_val *bsv = NULL;
539 struct cx24123_AGC_val *agcv = NULL;
540
541 /* Defaults for low freq, low rate */
542 state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
543 state->VGAarg = cx24123_AGC_vals[0].VGAprogdata;
544 state->bandselectarg = cx24123_bandselect_vals[0].progdata;
545 vco_div = cx24123_bandselect_vals[0].VCOdivider;
546
547 /* For the given symbol rate, determine the VCA, VGA and
548 * FILTUNE programming bits */
549 for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) {
550 agcv = &cx24123_AGC_vals[i];
551 if ((agcv->symbolrate_low <= p->u.qpsk.symbol_rate) &&
552 (agcv->symbolrate_high >= p->u.qpsk.symbol_rate)) {
553 state->VCAarg = agcv->VCAprogdata;
554 state->VGAarg = agcv->VGAprogdata;
555 state->FILTune = agcv->FILTune;
556 }
557 }
558
559 /* determine the band to use */
560 if (force_band < 1 || force_band > num_bands) {
561 for (i = 0; i < num_bands; i++) {
562 bsv = &cx24123_bandselect_vals[i];
563 if ((bsv->freq_low <= p->frequency) &&
564 (bsv->freq_high >= p->frequency))
565 band = i;
566 }
567 } else
568 band = force_band - 1;
569
570 state->bandselectarg = cx24123_bandselect_vals[band].progdata;
571 vco_div = cx24123_bandselect_vals[band].VCOdivider;
572
573 /* determine the charge pump current */
574 if (p->frequency < (cx24123_bandselect_vals[band].freq_low +
575 cx24123_bandselect_vals[band].freq_high) / 2)
576 pump = 0x01;
577 else
578 pump = 0x02;
579
580 /* Determine the N/A dividers for the requested lband freq (in kHz). */
581 /* Note: the reference divider R=10, frequency is in KHz,
582 * XTAL is in Hz */
583 ndiv = (((p->frequency * vco_div * 10) /
584 (2 * XTAL / 1000)) / 32) & 0x1ff;
585 adiv = (((p->frequency * vco_div * 10) /
586 (2 * XTAL / 1000)) % 32) & 0x1f;
587
588 if (adiv == 0 && ndiv > 0)
589 ndiv--;
590
591 /* control bits 11, refdiv 11, charge pump polarity 1,
592 * charge pump current, ndiv, adiv */
593 state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) |
594 (pump << 14) | (ndiv << 5) | adiv;
595
596 return 0;
597}
598
599/*
600 * Tuner data is 21 bits long, must be left-aligned in data.
601 * Tuner cx24109 is written through a dedicated 3wire interface
602 * on the demod chip.
603 */
604static int cx24123_pll_writereg(struct dvb_frontend *fe,
605 struct dvb_frontend_parameters *p, u32 data)
606{
607 struct cx24123_state *state = fe->demodulator_priv;
608 unsigned long timeout;
609
610 dprintk("pll writereg called, data=0x%08x\n", data);
611
612 /* align the 21 bytes into to bit23 boundary */
613 data = data << 3;
614
615 /* Reset the demod pll word length to 0x15 bits */
616 cx24123_writereg(state, 0x21, 0x15);
617
618 /* write the msb 8 bits, wait for the send to be completed */
619 timeout = jiffies + msecs_to_jiffies(40);
620 cx24123_writereg(state, 0x22, (data >> 16) & 0xff);
621 while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
622 if (time_after(jiffies, timeout)) {
623 err("%s: demodulator is not responding, "\
624 "possibly hung, aborting.\n", __func__);
625 return -EREMOTEIO;
626 }
627 msleep(10);
628 }
629
630 /* send another 8 bytes, wait for the send to be completed */
631 timeout = jiffies + msecs_to_jiffies(40);
632 cx24123_writereg(state, 0x22, (data >> 8) & 0xff);
633 while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
634 if (time_after(jiffies, timeout)) {
635 err("%s: demodulator is not responding, "\
636 "possibly hung, aborting.\n", __func__);
637 return -EREMOTEIO;
638 }
639 msleep(10);
640 }
641
642 /* send the lower 5 bits of this byte, padded with 3 LBB,
643 * wait for the send to be completed */
644 timeout = jiffies + msecs_to_jiffies(40);
645 cx24123_writereg(state, 0x22, (data) & 0xff);
646 while ((cx24123_readreg(state, 0x20) & 0x80)) {
647 if (time_after(jiffies, timeout)) {
648 err("%s: demodulator is not responding," \
649 "possibly hung, aborting.\n", __func__);
650 return -EREMOTEIO;
651 }
652 msleep(10);
653 }
654
655 /* Trigger the demod to configure the tuner */
656 cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2);
657 cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd);
658
659 return 0;
660}
661
662static int cx24123_pll_tune(struct dvb_frontend *fe,
663 struct dvb_frontend_parameters *p)
664{
665 struct cx24123_state *state = fe->demodulator_priv;
666 u8 val;
667
668 dprintk("frequency=%i\n", p->frequency);
669
670 if (cx24123_pll_calculate(fe, p) != 0) {
671 err("%s: cx24123_pll_calcutate failed\n", __func__);
672 return -EINVAL;
673 }
674
675 /* Write the new VCO/VGA */
676 cx24123_pll_writereg(fe, p, state->VCAarg);
677 cx24123_pll_writereg(fe, p, state->VGAarg);
678
679 /* Write the new bandselect and pll args */
680 cx24123_pll_writereg(fe, p, state->bandselectarg);
681 cx24123_pll_writereg(fe, p, state->pllarg);
682
683 /* set the FILTUNE voltage */
684 val = cx24123_readreg(state, 0x28) & ~0x3;
685 cx24123_writereg(state, 0x27, state->FILTune >> 2);
686 cx24123_writereg(state, 0x28, val | (state->FILTune & 0x3));
687
688 dprintk("pll tune VCA=%d, band=%d, pll=%d\n", state->VCAarg,
689 state->bandselectarg, state->pllarg);
690
691 return 0;
692}
693
694
695/*
696 * 0x23:
697 * [7:7] = BTI enabled
698 * [6:6] = I2C repeater enabled
699 * [5:5] = I2C repeater start
700 * [0:0] = BTI start
701 */
702
703/* mode == 1 -> i2c-repeater, 0 -> bti */
704static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start)
705{
706 u8 r = cx24123_readreg(state, 0x23) & 0x1e;
707 if (mode)
708 r |= (1 << 6) | (start << 5);
709 else
710 r |= (1 << 7) | (start);
711 return cx24123_writereg(state, 0x23, r);
712}
713
714static int cx24123_initfe(struct dvb_frontend *fe)
715{
716 struct cx24123_state *state = fe->demodulator_priv;
717 int i;
718
719 dprintk("init frontend\n");
720
721 /* Configure the demod to a good set of defaults */
722 for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++)
723 cx24123_writereg(state, cx24123_regdata[i].reg,
724 cx24123_regdata[i].data);
725
726 /* Set the LNB polarity */
727 if (state->config->lnb_polarity)
728 cx24123_writereg(state, 0x32,
729 cx24123_readreg(state, 0x32) | 0x02);
730
731 if (state->config->dont_use_pll)
732 cx24123_repeater_mode(state, 1, 0);
733
734 return 0;
735}
736
737static int cx24123_set_voltage(struct dvb_frontend *fe,
738 fe_sec_voltage_t voltage)
739{
740 struct cx24123_state *state = fe->demodulator_priv;
741 u8 val;
742
743 val = cx24123_readreg(state, 0x29) & ~0x40;
744
745 switch (voltage) {
746 case SEC_VOLTAGE_13:
747 dprintk("setting voltage 13V\n");
748 return cx24123_writereg(state, 0x29, val & 0x7f);
749 case SEC_VOLTAGE_18:
750 dprintk("setting voltage 18V\n");
751 return cx24123_writereg(state, 0x29, val | 0x80);
752 case SEC_VOLTAGE_OFF:
753 /* already handled in cx88-dvb */
754 return 0;
755 default:
756 return -EINVAL;
757 };
758
759 return 0;
760}
761
762/* wait for diseqc queue to become ready (or timeout) */
763static void cx24123_wait_for_diseqc(struct cx24123_state *state)
764{
765 unsigned long timeout = jiffies + msecs_to_jiffies(200);
766 while (!(cx24123_readreg(state, 0x29) & 0x40)) {
767 if (time_after(jiffies, timeout)) {
768 err("%s: diseqc queue not ready, " \
769 "command may be lost.\n", __func__);
770 break;
771 }
772 msleep(10);
773 }
774}
775
776static int cx24123_send_diseqc_msg(struct dvb_frontend *fe,
777 struct dvb_diseqc_master_cmd *cmd)
778{
779 struct cx24123_state *state = fe->demodulator_priv;
780 int i, val, tone;
781
782 dprintk("\n");
783
784 /* stop continuous tone if enabled */
785 tone = cx24123_readreg(state, 0x29);
786 if (tone & 0x10)
787 cx24123_writereg(state, 0x29, tone & ~0x50);
788
789 /* wait for diseqc queue ready */
790 cx24123_wait_for_diseqc(state);
791
792 /* select tone mode */
793 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
794
795 for (i = 0; i < cmd->msg_len; i++)
796 cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
797
798 val = cx24123_readreg(state, 0x29);
799 cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) |
800 ((cmd->msg_len-3) & 3));
801
802 /* wait for diseqc message to finish sending */
803 cx24123_wait_for_diseqc(state);
804
805 /* restart continuous tone if enabled */
806 if (tone & 0x10)
807 cx24123_writereg(state, 0x29, tone & ~0x40);
808
809 return 0;
810}
811
812static int cx24123_diseqc_send_burst(struct dvb_frontend *fe,
813 fe_sec_mini_cmd_t burst)
814{
815 struct cx24123_state *state = fe->demodulator_priv;
816 int val, tone;
817
818 dprintk("\n");
819
820 /* stop continuous tone if enabled */
821 tone = cx24123_readreg(state, 0x29);
822 if (tone & 0x10)
823 cx24123_writereg(state, 0x29, tone & ~0x50);
824
825 /* wait for diseqc queue ready */
826 cx24123_wait_for_diseqc(state);
827
828 /* select tone mode */
829 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4);
830 msleep(30);
831 val = cx24123_readreg(state, 0x29);
832 if (burst == SEC_MINI_A)
833 cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00));
834 else if (burst == SEC_MINI_B)
835 cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x08));
836 else
837 return -EINVAL;
838
839 cx24123_wait_for_diseqc(state);
840 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
841
842 /* restart continuous tone if enabled */
843 if (tone & 0x10)
844 cx24123_writereg(state, 0x29, tone & ~0x40);
845
846 return 0;
847}
848
849static int cx24123_read_status(struct dvb_frontend *fe, fe_status_t *status)
850{
851 struct cx24123_state *state = fe->demodulator_priv;
852 int sync = cx24123_readreg(state, 0x14);
853
854 *status = 0;
855 if (state->config->dont_use_pll) {
856 u32 tun_status = 0;
857 if (fe->ops.tuner_ops.get_status)
858 fe->ops.tuner_ops.get_status(fe, &tun_status);
859 if (tun_status & TUNER_STATUS_LOCKED)
860 *status |= FE_HAS_SIGNAL;
861 } else {
862 int lock = cx24123_readreg(state, 0x20);
863 if (lock & 0x01)
864 *status |= FE_HAS_SIGNAL;
865 }
866
867 if (sync & 0x02)
868 *status |= FE_HAS_CARRIER; /* Phase locked */
869 if (sync & 0x04)
870 *status |= FE_HAS_VITERBI;
871
872 /* Reed-Solomon Status */
873 if (sync & 0x08)
874 *status |= FE_HAS_SYNC;
875 if (sync & 0x80)
876 *status |= FE_HAS_LOCK; /*Full Sync */
877
878 return 0;
879}
880
881/*
882 * Configured to return the measurement of errors in blocks,
883 * because no UCBLOCKS value is available, so this value doubles up
884 * to satisfy both measurements.
885 */
886static int cx24123_read_ber(struct dvb_frontend *fe, u32 *ber)
887{
888 struct cx24123_state *state = fe->demodulator_priv;
889
890 /* The true bit error rate is this value divided by
891 the window size (set as 256 * 255) */
892 *ber = ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
893 (cx24123_readreg(state, 0x1d) << 8 |
894 cx24123_readreg(state, 0x1e));
895
896 dprintk("BER = %d\n", *ber);
897
898 return 0;
899}
900
901static int cx24123_read_signal_strength(struct dvb_frontend *fe,
902 u16 *signal_strength)
903{
904 struct cx24123_state *state = fe->demodulator_priv;
905
906 /* larger = better */
907 *signal_strength = cx24123_readreg(state, 0x3b) << 8;
908
909 dprintk("Signal strength = %d\n", *signal_strength);
910
911 return 0;
912}
913
914static int cx24123_read_snr(struct dvb_frontend *fe, u16 *snr)
915{
916 struct cx24123_state *state = fe->demodulator_priv;
917
918 /* Inverted raw Es/N0 count, totally bogus but better than the
919 BER threshold. */
920 *snr = 65535 - (((u16)cx24123_readreg(state, 0x18) << 8) |
921 (u16)cx24123_readreg(state, 0x19));
922
923 dprintk("read S/N index = %d\n", *snr);
924
925 return 0;
926}
927
928static int cx24123_set_frontend(struct dvb_frontend *fe,
929 struct dvb_frontend_parameters *p)
930{
931 struct cx24123_state *state = fe->demodulator_priv;
932
933 dprintk("\n");
934
935 if (state->config->set_ts_params)
936 state->config->set_ts_params(fe, 0);
937
938 state->currentfreq = p->frequency;
939 state->currentsymbolrate = p->u.qpsk.symbol_rate;
940
941 cx24123_set_inversion(state, p->inversion);
942 cx24123_set_fec(state, p->u.qpsk.fec_inner);
943 cx24123_set_symbolrate(state, p->u.qpsk.symbol_rate);
944
945 if (!state->config->dont_use_pll)
946 cx24123_pll_tune(fe, p);
947 else if (fe->ops.tuner_ops.set_params)
948 fe->ops.tuner_ops.set_params(fe, p);
949 else
950 err("it seems I don't have a tuner...");
951
952 /* Enable automatic acquisition and reset cycle */
953 cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07));
954 cx24123_writereg(state, 0x00, 0x10);
955 cx24123_writereg(state, 0x00, 0);
956
957 if (state->config->agc_callback)
958 state->config->agc_callback(fe);
959
960 return 0;
961}
962
963static int cx24123_get_frontend(struct dvb_frontend *fe,
964 struct dvb_frontend_parameters *p)
965{
966 struct cx24123_state *state = fe->demodulator_priv;
967
968 dprintk("\n");
969
970 if (cx24123_get_inversion(state, &p->inversion) != 0) {
971 err("%s: Failed to get inversion status\n", __func__);
972 return -EREMOTEIO;
973 }
974 if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) {
975 err("%s: Failed to get fec status\n", __func__);
976 return -EREMOTEIO;
977 }
978 p->frequency = state->currentfreq;
979 p->u.qpsk.symbol_rate = state->currentsymbolrate;
980
981 return 0;
982}
983
984static int cx24123_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
985{
986 struct cx24123_state *state = fe->demodulator_priv;
987 u8 val;
988
989 /* wait for diseqc queue ready */
990 cx24123_wait_for_diseqc(state);
991
992 val = cx24123_readreg(state, 0x29) & ~0x40;
993
994 switch (tone) {
995 case SEC_TONE_ON:
996 dprintk("setting tone on\n");
997 return cx24123_writereg(state, 0x29, val | 0x10);
998 case SEC_TONE_OFF:
999 dprintk("setting tone off\n");
1000 return cx24123_writereg(state, 0x29, val & 0xef);
1001 default:
1002 err("CASE reached default with tone=%d\n", tone);
1003 return -EINVAL;
1004 }
1005
1006 return 0;
1007}
1008
1009static int cx24123_tune(struct dvb_frontend *fe,
1010 struct dvb_frontend_parameters *params,
1011 unsigned int mode_flags,
1012 unsigned int *delay,
1013 fe_status_t *status)
1014{
1015 int retval = 0;
1016
1017 if (params != NULL)
1018 retval = cx24123_set_frontend(fe, params);
1019
1020 if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
1021 cx24123_read_status(fe, status);
1022 *delay = HZ/10;
1023
1024 return retval;
1025}
1026
1027static int cx24123_get_algo(struct dvb_frontend *fe)
1028{
1029 return 1; /* FE_ALGO_HW */
1030}
1031
1032static void cx24123_release(struct dvb_frontend *fe)
1033{
1034 struct cx24123_state *state = fe->demodulator_priv;
1035 dprintk("\n");
1036 i2c_del_adapter(&state->tuner_i2c_adapter);
1037 kfree(state);
1038}
1039
1040static int cx24123_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap,
1041 struct i2c_msg msg[], int num)
1042{
1043 struct cx24123_state *state = i2c_get_adapdata(i2c_adap);
1044 /* this repeater closes after the first stop */
1045 cx24123_repeater_mode(state, 1, 1);
1046 return i2c_transfer(state->i2c, msg, num);
1047}
1048
1049static u32 cx24123_tuner_i2c_func(struct i2c_adapter *adapter)
1050{
1051 return I2C_FUNC_I2C;
1052}
1053
1054static struct i2c_algorithm cx24123_tuner_i2c_algo = {
1055 .master_xfer = cx24123_tuner_i2c_tuner_xfer,
1056 .functionality = cx24123_tuner_i2c_func,
1057};
1058
1059struct i2c_adapter *
1060 cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe)
1061{
1062 struct cx24123_state *state = fe->demodulator_priv;
1063 return &state->tuner_i2c_adapter;
1064}
1065EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter);
1066
1067static struct dvb_frontend_ops cx24123_ops;
1068
1069struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
1070 struct i2c_adapter *i2c)
1071{
1072 /* allocate memory for the internal state */
1073 struct cx24123_state *state =
1074 kzalloc(sizeof(struct cx24123_state), GFP_KERNEL);
1075
1076 dprintk("\n");
1077 if (state == NULL) {
1078 err("Unable to kzalloc\n");
1079 goto error;
1080 }
1081
1082 /* setup the state */
1083 state->config = config;
1084 state->i2c = i2c;
1085
1086 /* check if the demod is there */
1087 state->demod_rev = cx24123_readreg(state, 0x00);
1088 switch (state->demod_rev) {
1089 case 0xe1:
1090 info("detected CX24123C\n");
1091 break;
1092 case 0xd1:
1093 info("detected CX24123\n");
1094 break;
1095 default:
1096 err("wrong demod revision: %x\n", state->demod_rev);
1097 goto error;
1098 }
1099
1100 /* create dvb_frontend */
1101 memcpy(&state->frontend.ops, &cx24123_ops,
1102 sizeof(struct dvb_frontend_ops));
1103 state->frontend.demodulator_priv = state;
1104
1105 /* create tuner i2c adapter */
1106 if (config->dont_use_pll)
1107 cx24123_repeater_mode(state, 1, 0);
1108
1109 strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
1110 sizeof(state->tuner_i2c_adapter.name));
1111 state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo;
1112 state->tuner_i2c_adapter.algo_data = NULL;
1113 i2c_set_adapdata(&state->tuner_i2c_adapter, state);
1114 if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) {
1115 err("tuner i2c bus could not be initialized\n");
1116 goto error;
1117 }
1118
1119 return &state->frontend;
1120
1121error:
1122 kfree(state);
1123
1124 return NULL;
1125}
1126EXPORT_SYMBOL(cx24123_attach);
1127
1128static struct dvb_frontend_ops cx24123_ops = {
1129
1130 .info = {
1131 .name = "Conexant CX24123/CX24109",
1132 .type = FE_QPSK,
1133 .frequency_min = 950000,
1134 .frequency_max = 2150000,
1135 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
1136 .frequency_tolerance = 5000,
1137 .symbol_rate_min = 1000000,
1138 .symbol_rate_max = 45000000,
1139 .caps = FE_CAN_INVERSION_AUTO |
1140 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1141 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1142 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1143 FE_CAN_QPSK | FE_CAN_RECOVER
1144 },
1145
1146 .release = cx24123_release,
1147
1148 .init = cx24123_initfe,
1149 .set_frontend = cx24123_set_frontend,
1150 .get_frontend = cx24123_get_frontend,
1151 .read_status = cx24123_read_status,
1152 .read_ber = cx24123_read_ber,
1153 .read_signal_strength = cx24123_read_signal_strength,
1154 .read_snr = cx24123_read_snr,
1155 .diseqc_send_master_cmd = cx24123_send_diseqc_msg,
1156 .diseqc_send_burst = cx24123_diseqc_send_burst,
1157 .set_tone = cx24123_set_tone,
1158 .set_voltage = cx24123_set_voltage,
1159 .tune = cx24123_tune,
1160 .get_frontend_algo = cx24123_get_algo,
1161};
1162
1163MODULE_DESCRIPTION("DVB Frontend module for Conexant " \
1164 "CX24123/CX24109/CX24113 hardware");
1165MODULE_AUTHOR("Steven Toth");
1166MODULE_LICENSE("GPL");
1167
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h
new file mode 100644
index 00000000000..51ae866e9fe
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24123.h
@@ -0,0 +1,61 @@
1/*
2 Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver
3
4 Copyright (C) 2005 Steven Toth <stoth@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 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 CX24123_H
22#define CX24123_H
23
24#include <linux/dvb/frontend.h>
25
26struct cx24123_config {
27 /* the demodulator's i2c address */
28 u8 demod_address;
29
30 /* Need to set device param for start_dma */
31 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
32
33 /* 0 = LNB voltage normal, 1 = LNB voltage inverted */
34 int lnb_polarity;
35
36 /* this device has another tuner */
37 u8 dont_use_pll;
38 void (*agc_callback) (struct dvb_frontend *);
39};
40
41#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) \
42 && defined(MODULE))
43extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
44 struct i2c_adapter *i2c);
45extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *);
46#else
47static inline struct dvb_frontend *cx24123_attach(
48 const struct cx24123_config *config, struct i2c_adapter *i2c)
49{
50 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
51 return NULL;
52}
53static struct i2c_adapter *
54 cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe)
55{
56 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
57 return NULL;
58}
59#endif
60
61#endif /* CX24123_H */
diff --git a/drivers/media/dvb/frontends/cxd2820r.h b/drivers/media/dvb/frontends/cxd2820r.h
new file mode 100644
index 00000000000..2906582dc94
--- /dev/null
+++ b/drivers/media/dvb/frontends/cxd2820r.h
@@ -0,0 +1,118 @@
1/*
2 * Sony CXD2820R demodulator driver
3 *
4 * Copyright (C) 2010 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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21
22#ifndef CXD2820R_H
23#define CXD2820R_H
24
25#include <linux/dvb/frontend.h>
26
27#define CXD2820R_GPIO_D (0 << 0) /* disable */
28#define CXD2820R_GPIO_E (1 << 0) /* enable */
29#define CXD2820R_GPIO_O (0 << 1) /* output */
30#define CXD2820R_GPIO_I (1 << 1) /* input */
31#define CXD2820R_GPIO_L (0 << 2) /* output low */
32#define CXD2820R_GPIO_H (1 << 2) /* output high */
33
34#define CXD2820R_TS_SERIAL 0x08
35#define CXD2820R_TS_SERIAL_MSB 0x28
36#define CXD2820R_TS_PARALLEL 0x30
37#define CXD2820R_TS_PARALLEL_MSB 0x70
38
39struct cxd2820r_config {
40 /* Demodulator I2C address.
41 * Driver determines DVB-C slave I2C address automatically from master
42 * address.
43 * Default: none, must set
44 * Values: 0x6c, 0x6d
45 */
46 u8 i2c_address;
47
48 /* TS output mode.
49 * Default: none, must set.
50 * Values:
51 */
52 u8 ts_mode;
53
54 /* IF AGC polarity.
55 * Default: 0
56 * Values: 0, 1
57 */
58 bool if_agc_polarity;
59
60 /* Spectrum inversion.
61 * Default: 0
62 * Values: 0, 1
63 */
64 bool spec_inv;
65
66 /* IFs for all used modes.
67 * Default: none, must set
68 * Values: <kHz>
69 */
70 u16 if_dvbt_6;
71 u16 if_dvbt_7;
72 u16 if_dvbt_8;
73 u16 if_dvbt2_5;
74 u16 if_dvbt2_6;
75 u16 if_dvbt2_7;
76 u16 if_dvbt2_8;
77 u16 if_dvbc;
78
79 /* GPIOs for all used modes.
80 * Default: none, disabled
81 * Values: <see above>
82 */
83 u8 gpio_dvbt[3];
84 u8 gpio_dvbt2[3];
85 u8 gpio_dvbc[3];
86};
87
88
89#if defined(CONFIG_DVB_CXD2820R) || \
90 (defined(CONFIG_DVB_CXD2820R_MODULE) && defined(MODULE))
91extern struct dvb_frontend *cxd2820r_attach(
92 const struct cxd2820r_config *config,
93 struct i2c_adapter *i2c,
94 struct dvb_frontend *fe
95);
96extern struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(
97 struct dvb_frontend *fe
98);
99#else
100static inline struct dvb_frontend *cxd2820r_attach(
101 const struct cxd2820r_config *config,
102 struct i2c_adapter *i2c,
103 struct dvb_frontend *fe
104)
105{
106 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
107 return NULL;
108}
109static inline struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(
110 struct dvb_frontend *fe
111)
112{
113 return NULL;
114}
115
116#endif
117
118#endif /* CXD2820R_H */
diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb/frontends/cxd2820r_c.c
new file mode 100644
index 00000000000..3c07d400731
--- /dev/null
+++ b/drivers/media/dvb/frontends/cxd2820r_c.c
@@ -0,0 +1,338 @@
1/*
2 * Sony CXD2820R demodulator driver
3 *
4 * Copyright (C) 2010 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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21
22#include "cxd2820r_priv.h"
23
24int cxd2820r_set_frontend_c(struct dvb_frontend *fe,
25 struct dvb_frontend_parameters *params)
26{
27 struct cxd2820r_priv *priv = fe->demodulator_priv;
28 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
29 int ret, i;
30 u8 buf[2];
31 u16 if_ctl;
32 u64 num;
33 struct reg_val_mask tab[] = {
34 { 0x00080, 0x01, 0xff },
35 { 0x00081, 0x05, 0xff },
36 { 0x00085, 0x07, 0xff },
37 { 0x00088, 0x01, 0xff },
38
39 { 0x00082, 0x20, 0x60 },
40 { 0x1016a, 0x48, 0xff },
41 { 0x100a5, 0x00, 0x01 },
42 { 0x10020, 0x06, 0x07 },
43 { 0x10059, 0x50, 0xff },
44 { 0x10087, 0x0c, 0x3c },
45 { 0x1008b, 0x07, 0xff },
46 { 0x1001f, priv->cfg.if_agc_polarity << 7, 0x80 },
47 { 0x10070, priv->cfg.ts_mode, 0xff },
48 };
49
50 dbg("%s: RF=%d SR=%d", __func__, c->frequency, c->symbol_rate);
51
52 /* update GPIOs */
53 ret = cxd2820r_gpio(fe);
54 if (ret)
55 goto error;
56
57 /* program tuner */
58 if (fe->ops.tuner_ops.set_params)
59 fe->ops.tuner_ops.set_params(fe, params);
60
61 if (priv->delivery_system != SYS_DVBC_ANNEX_AC) {
62 for (i = 0; i < ARRAY_SIZE(tab); i++) {
63 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
64 tab[i].val, tab[i].mask);
65 if (ret)
66 goto error;
67 }
68 }
69
70 priv->delivery_system = SYS_DVBC_ANNEX_AC;
71 priv->ber_running = 0; /* tune stops BER counter */
72
73 num = priv->cfg.if_dvbc;
74 num *= 0x4000;
75 if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
76 buf[0] = (if_ctl >> 8) & 0x3f;
77 buf[1] = (if_ctl >> 0) & 0xff;
78
79 ret = cxd2820r_wr_regs(priv, 0x10042, buf, 2);
80 if (ret)
81 goto error;
82
83 ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
84 if (ret)
85 goto error;
86
87 ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
88 if (ret)
89 goto error;
90
91 return ret;
92error:
93 dbg("%s: failed:%d", __func__, ret);
94 return ret;
95}
96
97int cxd2820r_get_frontend_c(struct dvb_frontend *fe,
98 struct dvb_frontend_parameters *p)
99{
100 struct cxd2820r_priv *priv = fe->demodulator_priv;
101 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
102 int ret;
103 u8 buf[2];
104
105 ret = cxd2820r_rd_regs(priv, 0x1001a, buf, 2);
106 if (ret)
107 goto error;
108
109 c->symbol_rate = 2500 * ((buf[0] & 0x0f) << 8 | buf[1]);
110
111 ret = cxd2820r_rd_reg(priv, 0x10019, &buf[0]);
112 if (ret)
113 goto error;
114
115 switch ((buf[0] >> 0) & 0x03) {
116 case 0:
117 c->modulation = QAM_16;
118 break;
119 case 1:
120 c->modulation = QAM_32;
121 break;
122 case 2:
123 c->modulation = QAM_64;
124 break;
125 case 3:
126 c->modulation = QAM_128;
127 break;
128 case 4:
129 c->modulation = QAM_256;
130 break;
131 }
132
133 switch ((buf[0] >> 7) & 0x01) {
134 case 0:
135 c->inversion = INVERSION_OFF;
136 break;
137 case 1:
138 c->inversion = INVERSION_ON;
139 break;
140 }
141
142 return ret;
143error:
144 dbg("%s: failed:%d", __func__, ret);
145 return ret;
146}
147
148int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber)
149{
150 struct cxd2820r_priv *priv = fe->demodulator_priv;
151 int ret;
152 u8 buf[3], start_ber = 0;
153 *ber = 0;
154
155 if (priv->ber_running) {
156 ret = cxd2820r_rd_regs(priv, 0x10076, buf, sizeof(buf));
157 if (ret)
158 goto error;
159
160 if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) {
161 *ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0];
162 start_ber = 1;
163 }
164 } else {
165 priv->ber_running = 1;
166 start_ber = 1;
167 }
168
169 if (start_ber) {
170 /* (re)start BER */
171 ret = cxd2820r_wr_reg(priv, 0x10079, 0x01);
172 if (ret)
173 goto error;
174 }
175
176 return ret;
177error:
178 dbg("%s: failed:%d", __func__, ret);
179 return ret;
180}
181
182int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe,
183 u16 *strength)
184{
185 struct cxd2820r_priv *priv = fe->demodulator_priv;
186 int ret;
187 u8 buf[2];
188 u16 tmp;
189
190 ret = cxd2820r_rd_regs(priv, 0x10049, buf, sizeof(buf));
191 if (ret)
192 goto error;
193
194 tmp = (buf[0] & 0x03) << 8 | buf[1];
195 tmp = (~tmp & 0x03ff);
196
197 if (tmp == 512)
198 /* ~no signal */
199 tmp = 0;
200 else if (tmp > 350)
201 tmp = 350;
202
203 /* scale value to 0x0000-0xffff */
204 *strength = tmp * 0xffff / (350-0);
205
206 return ret;
207error:
208 dbg("%s: failed:%d", __func__, ret);
209 return ret;
210}
211
212int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr)
213{
214 struct cxd2820r_priv *priv = fe->demodulator_priv;
215 int ret;
216 u8 tmp;
217 unsigned int A, B;
218 /* report SNR in dB * 10 */
219
220 ret = cxd2820r_rd_reg(priv, 0x10019, &tmp);
221 if (ret)
222 goto error;
223
224 if (((tmp >> 0) & 0x03) % 2) {
225 A = 875;
226 B = 650;
227 } else {
228 A = 950;
229 B = 760;
230 }
231
232 ret = cxd2820r_rd_reg(priv, 0x1004d, &tmp);
233 if (ret)
234 goto error;
235
236 #define CXD2820R_LOG2_E_24 24204406 /* log2(e) << 24 */
237 if (tmp)
238 *snr = A * (intlog2(B / tmp) >> 5) / (CXD2820R_LOG2_E_24 >> 5)
239 / 10;
240 else
241 *snr = 0;
242
243 return ret;
244error:
245 dbg("%s: failed:%d", __func__, ret);
246 return ret;
247}
248
249int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks)
250{
251 *ucblocks = 0;
252 /* no way to read ? */
253 return 0;
254}
255
256int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status)
257{
258 struct cxd2820r_priv *priv = fe->demodulator_priv;
259 int ret;
260 u8 buf[2];
261 *status = 0;
262
263 ret = cxd2820r_rd_regs(priv, 0x10088, buf, sizeof(buf));
264 if (ret)
265 goto error;
266
267 if (((buf[0] >> 0) & 0x01) == 1) {
268 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
269 FE_HAS_VITERBI | FE_HAS_SYNC;
270
271 if (((buf[1] >> 3) & 0x01) == 1) {
272 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
273 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
274 }
275 }
276
277 dbg("%s: lock=%02x %02x", __func__, buf[0], buf[1]);
278
279 return ret;
280error:
281 dbg("%s: failed:%d", __func__, ret);
282 return ret;
283}
284
285int cxd2820r_init_c(struct dvb_frontend *fe)
286{
287 struct cxd2820r_priv *priv = fe->demodulator_priv;
288 int ret;
289
290 ret = cxd2820r_wr_reg(priv, 0x00085, 0x07);
291 if (ret)
292 goto error;
293
294 return ret;
295error:
296 dbg("%s: failed:%d", __func__, ret);
297 return ret;
298}
299
300int cxd2820r_sleep_c(struct dvb_frontend *fe)
301{
302 struct cxd2820r_priv *priv = fe->demodulator_priv;
303 int ret, i;
304 struct reg_val_mask tab[] = {
305 { 0x000ff, 0x1f, 0xff },
306 { 0x00085, 0x00, 0xff },
307 { 0x00088, 0x01, 0xff },
308 { 0x00081, 0x00, 0xff },
309 { 0x00080, 0x00, 0xff },
310 };
311
312 dbg("%s", __func__);
313
314 priv->delivery_system = SYS_UNDEFINED;
315
316 for (i = 0; i < ARRAY_SIZE(tab); i++) {
317 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
318 tab[i].mask);
319 if (ret)
320 goto error;
321 }
322
323 return ret;
324error:
325 dbg("%s: failed:%d", __func__, ret);
326 return ret;
327}
328
329int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
330 struct dvb_frontend_tune_settings *s)
331{
332 s->min_delay_ms = 500;
333 s->step_size = 0; /* no zigzag */
334 s->max_drift = 0;
335
336 return 0;
337}
338
diff --git a/drivers/media/dvb/frontends/cxd2820r_core.c b/drivers/media/dvb/frontends/cxd2820r_core.c
new file mode 100644
index 00000000000..d416e85589e
--- /dev/null
+++ b/drivers/media/dvb/frontends/cxd2820r_core.c
@@ -0,0 +1,929 @@
1/*
2 * Sony CXD2820R demodulator driver
3 *
4 * Copyright (C) 2010 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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21
22#include "cxd2820r_priv.h"
23
24int cxd2820r_debug;
25module_param_named(debug, cxd2820r_debug, int, 0644);
26MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
27
28/* write multiple registers */
29static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
30 u8 *val, int len)
31{
32 int ret;
33 u8 buf[len+1];
34 struct i2c_msg msg[1] = {
35 {
36 .addr = i2c,
37 .flags = 0,
38 .len = sizeof(buf),
39 .buf = buf,
40 }
41 };
42
43 buf[0] = reg;
44 memcpy(&buf[1], val, len);
45
46 ret = i2c_transfer(priv->i2c, msg, 1);
47 if (ret == 1) {
48 ret = 0;
49 } else {
50 warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
51 ret = -EREMOTEIO;
52 }
53 return ret;
54}
55
56/* read multiple registers */
57static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
58 u8 *val, int len)
59{
60 int ret;
61 u8 buf[len];
62 struct i2c_msg msg[2] = {
63 {
64 .addr = i2c,
65 .flags = 0,
66 .len = 1,
67 .buf = &reg,
68 }, {
69 .addr = i2c,
70 .flags = I2C_M_RD,
71 .len = sizeof(buf),
72 .buf = buf,
73 }
74 };
75
76 ret = i2c_transfer(priv->i2c, msg, 2);
77 if (ret == 2) {
78 memcpy(val, buf, len);
79 ret = 0;
80 } else {
81 warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
82 ret = -EREMOTEIO;
83 }
84
85 return ret;
86}
87
88/* write multiple registers */
89int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
90 int len)
91{
92 int ret;
93 u8 i2c_addr;
94 u8 reg = (reginfo >> 0) & 0xff;
95 u8 bank = (reginfo >> 8) & 0xff;
96 u8 i2c = (reginfo >> 16) & 0x01;
97
98 /* select I2C */
99 if (i2c)
100 i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
101 else
102 i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
103
104 /* switch bank if needed */
105 if (bank != priv->bank[i2c]) {
106 ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
107 if (ret)
108 return ret;
109 priv->bank[i2c] = bank;
110 }
111 return cxd2820r_wr_regs_i2c(priv, i2c_addr, reg, val, len);
112}
113
114/* read multiple registers */
115int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
116 int len)
117{
118 int ret;
119 u8 i2c_addr;
120 u8 reg = (reginfo >> 0) & 0xff;
121 u8 bank = (reginfo >> 8) & 0xff;
122 u8 i2c = (reginfo >> 16) & 0x01;
123
124 /* select I2C */
125 if (i2c)
126 i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
127 else
128 i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
129
130 /* switch bank if needed */
131 if (bank != priv->bank[i2c]) {
132 ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
133 if (ret)
134 return ret;
135 priv->bank[i2c] = bank;
136 }
137 return cxd2820r_rd_regs_i2c(priv, i2c_addr, reg, val, len);
138}
139
140/* write single register */
141int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val)
142{
143 return cxd2820r_wr_regs(priv, reg, &val, 1);
144}
145
146/* read single register */
147int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val)
148{
149 return cxd2820r_rd_regs(priv, reg, val, 1);
150}
151
152/* write single register with mask */
153int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
154 u8 mask)
155{
156 int ret;
157 u8 tmp;
158
159 /* no need for read if whole reg is written */
160 if (mask != 0xff) {
161 ret = cxd2820r_rd_reg(priv, reg, &tmp);
162 if (ret)
163 return ret;
164
165 val &= mask;
166 tmp &= ~mask;
167 val |= tmp;
168 }
169
170 return cxd2820r_wr_reg(priv, reg, val);
171}
172
173int cxd2820r_gpio(struct dvb_frontend *fe)
174{
175 struct cxd2820r_priv *priv = fe->demodulator_priv;
176 int ret, i;
177 u8 *gpio, tmp0, tmp1;
178 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
179
180 switch (fe->dtv_property_cache.delivery_system) {
181 case SYS_DVBT:
182 gpio = priv->cfg.gpio_dvbt;
183 break;
184 case SYS_DVBT2:
185 gpio = priv->cfg.gpio_dvbt2;
186 break;
187 case SYS_DVBC_ANNEX_AC:
188 gpio = priv->cfg.gpio_dvbc;
189 break;
190 default:
191 ret = -EINVAL;
192 goto error;
193 }
194
195 /* update GPIOs only when needed */
196 if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio)))
197 return 0;
198
199 tmp0 = 0x00;
200 tmp1 = 0x00;
201 for (i = 0; i < sizeof(priv->gpio); i++) {
202 /* enable / disable */
203 if (gpio[i] & CXD2820R_GPIO_E)
204 tmp0 |= (2 << 6) >> (2 * i);
205 else
206 tmp0 |= (1 << 6) >> (2 * i);
207
208 /* input / output */
209 if (gpio[i] & CXD2820R_GPIO_I)
210 tmp1 |= (1 << (3 + i));
211 else
212 tmp1 |= (0 << (3 + i));
213
214 /* high / low */
215 if (gpio[i] & CXD2820R_GPIO_H)
216 tmp1 |= (1 << (0 + i));
217 else
218 tmp1 |= (0 << (0 + i));
219
220 dbg("%s: GPIO i=%d %02x %02x", __func__, i, tmp0, tmp1);
221 }
222
223 dbg("%s: wr gpio=%02x %02x", __func__, tmp0, tmp1);
224
225 /* write bits [7:2] */
226 ret = cxd2820r_wr_reg_mask(priv, 0x00089, tmp0, 0xfc);
227 if (ret)
228 goto error;
229
230 /* write bits [5:0] */
231 ret = cxd2820r_wr_reg_mask(priv, 0x0008e, tmp1, 0x3f);
232 if (ret)
233 goto error;
234
235 memcpy(priv->gpio, gpio, sizeof(priv->gpio));
236
237 return ret;
238error:
239 dbg("%s: failed:%d", __func__, ret);
240 return ret;
241}
242
243/* lock FE */
244static int cxd2820r_lock(struct cxd2820r_priv *priv, int active_fe)
245{
246 int ret = 0;
247 dbg("%s: active_fe=%d", __func__, active_fe);
248
249 mutex_lock(&priv->fe_lock);
250
251 /* -1=NONE, 0=DVB-T/T2, 1=DVB-C */
252 if (priv->active_fe == active_fe)
253 ;
254 else if (priv->active_fe == -1)
255 priv->active_fe = active_fe;
256 else
257 ret = -EBUSY;
258
259 mutex_unlock(&priv->fe_lock);
260
261 return ret;
262}
263
264/* unlock FE */
265static void cxd2820r_unlock(struct cxd2820r_priv *priv, int active_fe)
266{
267 dbg("%s: active_fe=%d", __func__, active_fe);
268
269 mutex_lock(&priv->fe_lock);
270
271 /* -1=NONE, 0=DVB-T/T2, 1=DVB-C */
272 if (priv->active_fe == active_fe)
273 priv->active_fe = -1;
274
275 mutex_unlock(&priv->fe_lock);
276
277 return;
278}
279
280/* 64 bit div with round closest, like DIV_ROUND_CLOSEST but 64 bit */
281u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor)
282{
283 return div_u64(dividend + (divisor / 2), divisor);
284}
285
286static int cxd2820r_set_frontend(struct dvb_frontend *fe,
287 struct dvb_frontend_parameters *p)
288{
289 struct cxd2820r_priv *priv = fe->demodulator_priv;
290 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
291 int ret;
292 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
293
294 if (fe->ops.info.type == FE_OFDM) {
295 /* DVB-T/T2 */
296 ret = cxd2820r_lock(priv, 0);
297 if (ret)
298 return ret;
299
300 switch (priv->delivery_system) {
301 case SYS_UNDEFINED:
302 if (c->delivery_system == SYS_DVBT) {
303 /* SLEEP => DVB-T */
304 ret = cxd2820r_set_frontend_t(fe, p);
305 } else {
306 /* SLEEP => DVB-T2 */
307 ret = cxd2820r_set_frontend_t2(fe, p);
308 }
309 break;
310 case SYS_DVBT:
311 if (c->delivery_system == SYS_DVBT) {
312 /* DVB-T => DVB-T */
313 ret = cxd2820r_set_frontend_t(fe, p);
314 } else if (c->delivery_system == SYS_DVBT2) {
315 /* DVB-T => DVB-T2 */
316 ret = cxd2820r_sleep_t(fe);
317 if (ret)
318 break;
319 ret = cxd2820r_set_frontend_t2(fe, p);
320 }
321 break;
322 case SYS_DVBT2:
323 if (c->delivery_system == SYS_DVBT2) {
324 /* DVB-T2 => DVB-T2 */
325 ret = cxd2820r_set_frontend_t2(fe, p);
326 } else if (c->delivery_system == SYS_DVBT) {
327 /* DVB-T2 => DVB-T */
328 ret = cxd2820r_sleep_t2(fe);
329 if (ret)
330 break;
331 ret = cxd2820r_set_frontend_t(fe, p);
332 }
333 break;
334 default:
335 dbg("%s: error state=%d", __func__,
336 priv->delivery_system);
337 ret = -EINVAL;
338 }
339 } else {
340 /* DVB-C */
341 ret = cxd2820r_lock(priv, 1);
342 if (ret)
343 return ret;
344
345 ret = cxd2820r_set_frontend_c(fe, p);
346 }
347
348 return ret;
349}
350
351static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status)
352{
353 struct cxd2820r_priv *priv = fe->demodulator_priv;
354 int ret;
355 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
356
357 if (fe->ops.info.type == FE_OFDM) {
358 /* DVB-T/T2 */
359 ret = cxd2820r_lock(priv, 0);
360 if (ret)
361 return ret;
362
363 switch (fe->dtv_property_cache.delivery_system) {
364 case SYS_DVBT:
365 ret = cxd2820r_read_status_t(fe, status);
366 break;
367 case SYS_DVBT2:
368 ret = cxd2820r_read_status_t2(fe, status);
369 break;
370 default:
371 ret = -EINVAL;
372 }
373 } else {
374 /* DVB-C */
375 ret = cxd2820r_lock(priv, 1);
376 if (ret)
377 return ret;
378
379 ret = cxd2820r_read_status_c(fe, status);
380 }
381
382 return ret;
383}
384
385static int cxd2820r_get_frontend(struct dvb_frontend *fe,
386 struct dvb_frontend_parameters *p)
387{
388 struct cxd2820r_priv *priv = fe->demodulator_priv;
389 int ret;
390 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
391
392 if (fe->ops.info.type == FE_OFDM) {
393 /* DVB-T/T2 */
394 ret = cxd2820r_lock(priv, 0);
395 if (ret)
396 return ret;
397
398 switch (fe->dtv_property_cache.delivery_system) {
399 case SYS_DVBT:
400 ret = cxd2820r_get_frontend_t(fe, p);
401 break;
402 case SYS_DVBT2:
403 ret = cxd2820r_get_frontend_t2(fe, p);
404 break;
405 default:
406 ret = -EINVAL;
407 }
408 } else {
409 /* DVB-C */
410 ret = cxd2820r_lock(priv, 1);
411 if (ret)
412 return ret;
413
414 ret = cxd2820r_get_frontend_c(fe, p);
415 }
416
417 return ret;
418}
419
420static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber)
421{
422 struct cxd2820r_priv *priv = fe->demodulator_priv;
423 int ret;
424 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
425
426 if (fe->ops.info.type == FE_OFDM) {
427 /* DVB-T/T2 */
428 ret = cxd2820r_lock(priv, 0);
429 if (ret)
430 return ret;
431
432 switch (fe->dtv_property_cache.delivery_system) {
433 case SYS_DVBT:
434 ret = cxd2820r_read_ber_t(fe, ber);
435 break;
436 case SYS_DVBT2:
437 ret = cxd2820r_read_ber_t2(fe, ber);
438 break;
439 default:
440 ret = -EINVAL;
441 }
442 } else {
443 /* DVB-C */
444 ret = cxd2820r_lock(priv, 1);
445 if (ret)
446 return ret;
447
448 ret = cxd2820r_read_ber_c(fe, ber);
449 }
450
451 return ret;
452}
453
454static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
455{
456 struct cxd2820r_priv *priv = fe->demodulator_priv;
457 int ret;
458 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
459
460 if (fe->ops.info.type == FE_OFDM) {
461 /* DVB-T/T2 */
462 ret = cxd2820r_lock(priv, 0);
463 if (ret)
464 return ret;
465
466 switch (fe->dtv_property_cache.delivery_system) {
467 case SYS_DVBT:
468 ret = cxd2820r_read_signal_strength_t(fe, strength);
469 break;
470 case SYS_DVBT2:
471 ret = cxd2820r_read_signal_strength_t2(fe, strength);
472 break;
473 default:
474 ret = -EINVAL;
475 }
476 } else {
477 /* DVB-C */
478 ret = cxd2820r_lock(priv, 1);
479 if (ret)
480 return ret;
481
482 ret = cxd2820r_read_signal_strength_c(fe, strength);
483 }
484
485 return ret;
486}
487
488static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr)
489{
490 struct cxd2820r_priv *priv = fe->demodulator_priv;
491 int ret;
492 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
493
494 if (fe->ops.info.type == FE_OFDM) {
495 /* DVB-T/T2 */
496 ret = cxd2820r_lock(priv, 0);
497 if (ret)
498 return ret;
499
500 switch (fe->dtv_property_cache.delivery_system) {
501 case SYS_DVBT:
502 ret = cxd2820r_read_snr_t(fe, snr);
503 break;
504 case SYS_DVBT2:
505 ret = cxd2820r_read_snr_t2(fe, snr);
506 break;
507 default:
508 ret = -EINVAL;
509 }
510 } else {
511 /* DVB-C */
512 ret = cxd2820r_lock(priv, 1);
513 if (ret)
514 return ret;
515
516 ret = cxd2820r_read_snr_c(fe, snr);
517 }
518
519 return ret;
520}
521
522static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
523{
524 struct cxd2820r_priv *priv = fe->demodulator_priv;
525 int ret;
526 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
527
528 if (fe->ops.info.type == FE_OFDM) {
529 /* DVB-T/T2 */
530 ret = cxd2820r_lock(priv, 0);
531 if (ret)
532 return ret;
533
534 switch (fe->dtv_property_cache.delivery_system) {
535 case SYS_DVBT:
536 ret = cxd2820r_read_ucblocks_t(fe, ucblocks);
537 break;
538 case SYS_DVBT2:
539 ret = cxd2820r_read_ucblocks_t2(fe, ucblocks);
540 break;
541 default:
542 ret = -EINVAL;
543 }
544 } else {
545 /* DVB-C */
546 ret = cxd2820r_lock(priv, 1);
547 if (ret)
548 return ret;
549
550 ret = cxd2820r_read_ucblocks_c(fe, ucblocks);
551 }
552
553 return ret;
554}
555
556static int cxd2820r_init(struct dvb_frontend *fe)
557{
558 struct cxd2820r_priv *priv = fe->demodulator_priv;
559 int ret;
560 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
561
562 priv->delivery_system = SYS_UNDEFINED;
563 /* delivery system is unknown at that (init) phase */
564
565 if (fe->ops.info.type == FE_OFDM) {
566 /* DVB-T/T2 */
567 ret = cxd2820r_lock(priv, 0);
568 if (ret)
569 return ret;
570
571 ret = cxd2820r_init_t(fe);
572 } else {
573 /* DVB-C */
574 ret = cxd2820r_lock(priv, 1);
575 if (ret)
576 return ret;
577
578 ret = cxd2820r_init_c(fe);
579 }
580
581 return ret;
582}
583
584static int cxd2820r_sleep(struct dvb_frontend *fe)
585{
586 struct cxd2820r_priv *priv = fe->demodulator_priv;
587 int ret;
588 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
589
590 if (fe->ops.info.type == FE_OFDM) {
591 /* DVB-T/T2 */
592 ret = cxd2820r_lock(priv, 0);
593 if (ret)
594 return ret;
595
596 switch (fe->dtv_property_cache.delivery_system) {
597 case SYS_DVBT:
598 ret = cxd2820r_sleep_t(fe);
599 break;
600 case SYS_DVBT2:
601 ret = cxd2820r_sleep_t2(fe);
602 break;
603 default:
604 ret = -EINVAL;
605 }
606
607 cxd2820r_unlock(priv, 0);
608 } else {
609 /* DVB-C */
610 ret = cxd2820r_lock(priv, 1);
611 if (ret)
612 return ret;
613
614 ret = cxd2820r_sleep_c(fe);
615
616 cxd2820r_unlock(priv, 1);
617 }
618
619 return ret;
620}
621
622static int cxd2820r_get_tune_settings(struct dvb_frontend *fe,
623 struct dvb_frontend_tune_settings *s)
624{
625 struct cxd2820r_priv *priv = fe->demodulator_priv;
626 int ret;
627 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
628
629 if (fe->ops.info.type == FE_OFDM) {
630 /* DVB-T/T2 */
631 ret = cxd2820r_lock(priv, 0);
632 if (ret)
633 return ret;
634
635 switch (fe->dtv_property_cache.delivery_system) {
636 case SYS_DVBT:
637 ret = cxd2820r_get_tune_settings_t(fe, s);
638 break;
639 case SYS_DVBT2:
640 ret = cxd2820r_get_tune_settings_t2(fe, s);
641 break;
642 default:
643 ret = -EINVAL;
644 }
645 } else {
646 /* DVB-C */
647 ret = cxd2820r_lock(priv, 1);
648 if (ret)
649 return ret;
650
651 ret = cxd2820r_get_tune_settings_c(fe, s);
652 }
653
654 return ret;
655}
656
657static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe,
658 struct dvb_frontend_parameters *p)
659{
660 struct cxd2820r_priv *priv = fe->demodulator_priv;
661 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
662 int ret, i;
663 fe_status_t status = 0;
664 dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
665
666 /* switch between DVB-T and DVB-T2 when tune fails */
667 if (priv->last_tune_failed) {
668 if (priv->delivery_system == SYS_DVBT)
669 c->delivery_system = SYS_DVBT2;
670 else
671 c->delivery_system = SYS_DVBT;
672 }
673
674 /* set frontend */
675 ret = cxd2820r_set_frontend(fe, p);
676 if (ret)
677 goto error;
678
679
680 /* frontend lock wait loop count */
681 switch (priv->delivery_system) {
682 case SYS_DVBT:
683 i = 20;
684 break;
685 case SYS_DVBT2:
686 i = 40;
687 break;
688 case SYS_UNDEFINED:
689 default:
690 i = 0;
691 break;
692 }
693
694 /* wait frontend lock */
695 for (; i > 0; i--) {
696 dbg("%s: LOOP=%d", __func__, i);
697 msleep(50);
698 ret = cxd2820r_read_status(fe, &status);
699 if (ret)
700 goto error;
701
702 if (status & FE_HAS_SIGNAL)
703 break;
704 }
705
706 /* check if we have a valid signal */
707 if (status) {
708 priv->last_tune_failed = 0;
709 return DVBFE_ALGO_SEARCH_SUCCESS;
710 } else {
711 priv->last_tune_failed = 1;
712 return DVBFE_ALGO_SEARCH_AGAIN;
713 }
714
715error:
716 dbg("%s: failed:%d", __func__, ret);
717 return DVBFE_ALGO_SEARCH_ERROR;
718}
719
720static int cxd2820r_get_frontend_algo(struct dvb_frontend *fe)
721{
722 return DVBFE_ALGO_CUSTOM;
723}
724
725static void cxd2820r_release(struct dvb_frontend *fe)
726{
727 struct cxd2820r_priv *priv = fe->demodulator_priv;
728 dbg("%s", __func__);
729
730 if (fe->ops.info.type == FE_OFDM) {
731 i2c_del_adapter(&priv->tuner_i2c_adapter);
732 kfree(priv);
733 }
734
735 return;
736}
737
738static u32 cxd2820r_tuner_i2c_func(struct i2c_adapter *adapter)
739{
740 return I2C_FUNC_I2C;
741}
742
743static int cxd2820r_tuner_i2c_xfer(struct i2c_adapter *i2c_adap,
744 struct i2c_msg msg[], int num)
745{
746 struct cxd2820r_priv *priv = i2c_get_adapdata(i2c_adap);
747 int ret;
748 u8 *obuf = kmalloc(msg[0].len + 2, GFP_KERNEL);
749 struct i2c_msg msg2[2] = {
750 {
751 .addr = priv->cfg.i2c_address,
752 .flags = 0,
753 .len = msg[0].len + 2,
754 .buf = obuf,
755 }, {
756 .addr = priv->cfg.i2c_address,
757 .flags = I2C_M_RD,
758 .len = msg[1].len,
759 .buf = msg[1].buf,
760 }
761 };
762
763 if (!obuf)
764 return -ENOMEM;
765
766 obuf[0] = 0x09;
767 obuf[1] = (msg[0].addr << 1);
768 if (num == 2) { /* I2C read */
769 obuf[1] = (msg[0].addr << 1) | I2C_M_RD; /* I2C RD flag */
770 msg2[0].len = msg[0].len + 2 - 1; /* '-1' maybe HW bug ? */
771 }
772 memcpy(&obuf[2], msg[0].buf, msg[0].len);
773
774 ret = i2c_transfer(priv->i2c, msg2, num);
775 if (ret < 0)
776 warn("tuner i2c failed ret:%d", ret);
777
778 kfree(obuf);
779
780 return ret;
781}
782
783static struct i2c_algorithm cxd2820r_tuner_i2c_algo = {
784 .master_xfer = cxd2820r_tuner_i2c_xfer,
785 .functionality = cxd2820r_tuner_i2c_func,
786};
787
788struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(struct dvb_frontend *fe)
789{
790 struct cxd2820r_priv *priv = fe->demodulator_priv;
791 return &priv->tuner_i2c_adapter;
792}
793EXPORT_SYMBOL(cxd2820r_get_tuner_i2c_adapter);
794
795static struct dvb_frontend_ops cxd2820r_ops[2];
796
797struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
798 struct i2c_adapter *i2c, struct dvb_frontend *fe)
799{
800 int ret;
801 struct cxd2820r_priv *priv = NULL;
802 u8 tmp;
803
804 if (fe == NULL) {
805 /* FE0 */
806 /* allocate memory for the internal priv */
807 priv = kzalloc(sizeof(struct cxd2820r_priv), GFP_KERNEL);
808 if (priv == NULL)
809 goto error;
810
811 /* setup the priv */
812 priv->i2c = i2c;
813 memcpy(&priv->cfg, cfg, sizeof(struct cxd2820r_config));
814 mutex_init(&priv->fe_lock);
815
816 priv->active_fe = -1; /* NONE */
817
818 /* check if the demod is there */
819 priv->bank[0] = priv->bank[1] = 0xff;
820 ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp);
821 dbg("%s: chip id=%02x", __func__, tmp);
822 if (ret || tmp != 0xe1)
823 goto error;
824
825 /* create frontends */
826 memcpy(&priv->fe[0].ops, &cxd2820r_ops[0],
827 sizeof(struct dvb_frontend_ops));
828 memcpy(&priv->fe[1].ops, &cxd2820r_ops[1],
829 sizeof(struct dvb_frontend_ops));
830
831 priv->fe[0].demodulator_priv = priv;
832 priv->fe[1].demodulator_priv = priv;
833
834 /* create tuner i2c adapter */
835 strlcpy(priv->tuner_i2c_adapter.name,
836 "CXD2820R tuner I2C adapter",
837 sizeof(priv->tuner_i2c_adapter.name));
838 priv->tuner_i2c_adapter.algo = &cxd2820r_tuner_i2c_algo;
839 priv->tuner_i2c_adapter.algo_data = NULL;
840 i2c_set_adapdata(&priv->tuner_i2c_adapter, priv);
841 if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) {
842 err("tuner I2C bus could not be initialized");
843 goto error;
844 }
845
846 return &priv->fe[0];
847
848 } else {
849 /* FE1: FE0 given as pointer, just return FE1 we have
850 * already created */
851 priv = fe->demodulator_priv;
852 return &priv->fe[1];
853 }
854
855error:
856 kfree(priv);
857 return NULL;
858}
859EXPORT_SYMBOL(cxd2820r_attach);
860
861static struct dvb_frontend_ops cxd2820r_ops[2] = {
862 {
863 /* DVB-T/T2 */
864 .info = {
865 .name = "Sony CXD2820R (DVB-T/T2)",
866 .type = FE_OFDM,
867 .caps =
868 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
869 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
870 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
871 FE_CAN_QPSK | FE_CAN_QAM_16 |
872 FE_CAN_QAM_64 | FE_CAN_QAM_256 |
873 FE_CAN_QAM_AUTO |
874 FE_CAN_TRANSMISSION_MODE_AUTO |
875 FE_CAN_GUARD_INTERVAL_AUTO |
876 FE_CAN_HIERARCHY_AUTO |
877 FE_CAN_MUTE_TS |
878 FE_CAN_2G_MODULATION
879 },
880
881 .release = cxd2820r_release,
882 .init = cxd2820r_init,
883 .sleep = cxd2820r_sleep,
884
885 .get_tune_settings = cxd2820r_get_tune_settings,
886
887 .get_frontend = cxd2820r_get_frontend,
888
889 .get_frontend_algo = cxd2820r_get_frontend_algo,
890 .search = cxd2820r_search,
891
892 .read_status = cxd2820r_read_status,
893 .read_snr = cxd2820r_read_snr,
894 .read_ber = cxd2820r_read_ber,
895 .read_ucblocks = cxd2820r_read_ucblocks,
896 .read_signal_strength = cxd2820r_read_signal_strength,
897 },
898 {
899 /* DVB-C */
900 .info = {
901 .name = "Sony CXD2820R (DVB-C)",
902 .type = FE_QAM,
903 .caps =
904 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
905 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
906 FE_CAN_FEC_AUTO
907 },
908
909 .release = cxd2820r_release,
910 .init = cxd2820r_init,
911 .sleep = cxd2820r_sleep,
912
913 .get_tune_settings = cxd2820r_get_tune_settings,
914
915 .set_frontend = cxd2820r_set_frontend,
916 .get_frontend = cxd2820r_get_frontend,
917
918 .read_status = cxd2820r_read_status,
919 .read_snr = cxd2820r_read_snr,
920 .read_ber = cxd2820r_read_ber,
921 .read_ucblocks = cxd2820r_read_ucblocks,
922 .read_signal_strength = cxd2820r_read_signal_strength,
923 },
924};
925
926
927MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
928MODULE_DESCRIPTION("Sony CXD2820R demodulator driver");
929MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/cxd2820r_priv.h b/drivers/media/dvb/frontends/cxd2820r_priv.h
new file mode 100644
index 00000000000..0c0ebc9d5c4
--- /dev/null
+++ b/drivers/media/dvb/frontends/cxd2820r_priv.h
@@ -0,0 +1,166 @@
1/*
2 * Sony CXD2820R demodulator driver
3 *
4 * Copyright (C) 2010 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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21
22#ifndef CXD2820R_PRIV_H
23#define CXD2820R_PRIV_H
24
25#include <linux/dvb/version.h>
26#include "dvb_frontend.h"
27#include "dvb_math.h"
28#include "cxd2820r.h"
29
30#define LOG_PREFIX "cxd2820r"
31
32#undef dbg
33#define dbg(f, arg...) \
34 if (cxd2820r_debug) \
35 printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
36#undef err
37#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
38#undef info
39#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
40#undef warn
41#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
42
43struct reg_val_mask {
44 u32 reg;
45 u8 val;
46 u8 mask;
47};
48
49struct cxd2820r_priv {
50 struct i2c_adapter *i2c;
51 struct dvb_frontend fe[2];
52 struct cxd2820r_config cfg;
53 struct i2c_adapter tuner_i2c_adapter;
54
55 struct mutex fe_lock; /* FE lock */
56 int active_fe:2; /* FE lock, -1=NONE, 0=DVB-T/T2, 1=DVB-C */
57
58 bool ber_running;
59
60 u8 bank[2];
61 u8 gpio[3];
62
63 fe_delivery_system_t delivery_system;
64 bool last_tune_failed; /* for switch between T and T2 tune */
65};
66
67/* cxd2820r_core.c */
68
69extern int cxd2820r_debug;
70
71int cxd2820r_gpio(struct dvb_frontend *fe);
72
73int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
74 u8 mask);
75
76int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
77 int len);
78
79u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor);
80
81int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
82 int len);
83
84int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
85 int len);
86
87int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val);
88
89int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val);
90
91/* cxd2820r_c.c */
92
93int cxd2820r_get_frontend_c(struct dvb_frontend *fe,
94 struct dvb_frontend_parameters *p);
95
96int cxd2820r_set_frontend_c(struct dvb_frontend *fe,
97 struct dvb_frontend_parameters *params);
98
99int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status);
100
101int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber);
102
103int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe, u16 *strength);
104
105int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr);
106
107int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks);
108
109int cxd2820r_init_c(struct dvb_frontend *fe);
110
111int cxd2820r_sleep_c(struct dvb_frontend *fe);
112
113int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
114 struct dvb_frontend_tune_settings *s);
115
116/* cxd2820r_t.c */
117
118int cxd2820r_get_frontend_t(struct dvb_frontend *fe,
119 struct dvb_frontend_parameters *p);
120
121int cxd2820r_set_frontend_t(struct dvb_frontend *fe,
122 struct dvb_frontend_parameters *params);
123
124int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status);
125
126int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber);
127
128int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe, u16 *strength);
129
130int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr);
131
132int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks);
133
134int cxd2820r_init_t(struct dvb_frontend *fe);
135
136int cxd2820r_sleep_t(struct dvb_frontend *fe);
137
138int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
139 struct dvb_frontend_tune_settings *s);
140
141/* cxd2820r_t2.c */
142
143int cxd2820r_get_frontend_t2(struct dvb_frontend *fe,
144 struct dvb_frontend_parameters *p);
145
146int cxd2820r_set_frontend_t2(struct dvb_frontend *fe,
147 struct dvb_frontend_parameters *params);
148
149int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status);
150
151int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber);
152
153int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe, u16 *strength);
154
155int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr);
156
157int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks);
158
159int cxd2820r_init_t2(struct dvb_frontend *fe);
160
161int cxd2820r_sleep_t2(struct dvb_frontend *fe);
162
163int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
164 struct dvb_frontend_tune_settings *s);
165
166#endif /* CXD2820R_PRIV_H */
diff --git a/drivers/media/dvb/frontends/cxd2820r_t.c b/drivers/media/dvb/frontends/cxd2820r_t.c
new file mode 100644
index 00000000000..6582564c930
--- /dev/null
+++ b/drivers/media/dvb/frontends/cxd2820r_t.c
@@ -0,0 +1,449 @@
1/*
2 * Sony CXD2820R demodulator driver
3 *
4 * Copyright (C) 2010 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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21
22#include "cxd2820r_priv.h"
23
24int cxd2820r_set_frontend_t(struct dvb_frontend *fe,
25 struct dvb_frontend_parameters *p)
26{
27 struct cxd2820r_priv *priv = fe->demodulator_priv;
28 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
29 int ret, i;
30 u32 if_khz, if_ctl;
31 u64 num;
32 u8 buf[3], bw_param;
33 u8 bw_params1[][5] = {
34 { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
35 { 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
36 { 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
37 };
38 u8 bw_params2[][2] = {
39 { 0x1f, 0xdc }, /* 6 MHz */
40 { 0x12, 0xf8 }, /* 7 MHz */
41 { 0x01, 0xe0 }, /* 8 MHz */
42 };
43 struct reg_val_mask tab[] = {
44 { 0x00080, 0x00, 0xff },
45 { 0x00081, 0x03, 0xff },
46 { 0x00085, 0x07, 0xff },
47 { 0x00088, 0x01, 0xff },
48
49 { 0x00070, priv->cfg.ts_mode, 0xff },
50 { 0x000cb, priv->cfg.if_agc_polarity << 6, 0x40 },
51 { 0x000a5, 0x00, 0x01 },
52 { 0x00082, 0x20, 0x60 },
53 { 0x000c2, 0xc3, 0xff },
54 { 0x0016a, 0x50, 0xff },
55 { 0x00427, 0x41, 0xff },
56 };
57
58 dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
59
60 /* update GPIOs */
61 ret = cxd2820r_gpio(fe);
62 if (ret)
63 goto error;
64
65 /* program tuner */
66 if (fe->ops.tuner_ops.set_params)
67 fe->ops.tuner_ops.set_params(fe, p);
68
69 if (priv->delivery_system != SYS_DVBT) {
70 for (i = 0; i < ARRAY_SIZE(tab); i++) {
71 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
72 tab[i].val, tab[i].mask);
73 if (ret)
74 goto error;
75 }
76 }
77
78 priv->delivery_system = SYS_DVBT;
79 priv->ber_running = 0; /* tune stops BER counter */
80
81 switch (c->bandwidth_hz) {
82 case 6000000:
83 if_khz = priv->cfg.if_dvbt_6;
84 i = 0;
85 bw_param = 2;
86 break;
87 case 7000000:
88 if_khz = priv->cfg.if_dvbt_7;
89 i = 1;
90 bw_param = 1;
91 break;
92 case 8000000:
93 if_khz = priv->cfg.if_dvbt_8;
94 i = 2;
95 bw_param = 0;
96 break;
97 default:
98 return -EINVAL;
99 }
100
101 num = if_khz;
102 num *= 0x1000000;
103 if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
104 buf[0] = ((if_ctl >> 16) & 0xff);
105 buf[1] = ((if_ctl >> 8) & 0xff);
106 buf[2] = ((if_ctl >> 0) & 0xff);
107
108 ret = cxd2820r_wr_regs(priv, 0x000b6, buf, 3);
109 if (ret)
110 goto error;
111
112 ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[i], 5);
113 if (ret)
114 goto error;
115
116 ret = cxd2820r_wr_reg_mask(priv, 0x000d7, bw_param << 6, 0xc0);
117 if (ret)
118 goto error;
119
120 ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[i], 2);
121 if (ret)
122 goto error;
123
124 ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
125 if (ret)
126 goto error;
127
128 ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
129 if (ret)
130 goto error;
131
132 return ret;
133error:
134 dbg("%s: failed:%d", __func__, ret);
135 return ret;
136}
137
138int cxd2820r_get_frontend_t(struct dvb_frontend *fe,
139 struct dvb_frontend_parameters *p)
140{
141 struct cxd2820r_priv *priv = fe->demodulator_priv;
142 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
143 int ret;
144 u8 buf[2];
145
146 ret = cxd2820r_rd_regs(priv, 0x0002f, buf, sizeof(buf));
147 if (ret)
148 goto error;
149
150 switch ((buf[0] >> 6) & 0x03) {
151 case 0:
152 c->modulation = QPSK;
153 break;
154 case 1:
155 c->modulation = QAM_16;
156 break;
157 case 2:
158 c->modulation = QAM_64;
159 break;
160 }
161
162 switch ((buf[1] >> 1) & 0x03) {
163 case 0:
164 c->transmission_mode = TRANSMISSION_MODE_2K;
165 break;
166 case 1:
167 c->transmission_mode = TRANSMISSION_MODE_8K;
168 break;
169 }
170
171 switch ((buf[1] >> 3) & 0x03) {
172 case 0:
173 c->guard_interval = GUARD_INTERVAL_1_32;
174 break;
175 case 1:
176 c->guard_interval = GUARD_INTERVAL_1_16;
177 break;
178 case 2:
179 c->guard_interval = GUARD_INTERVAL_1_8;
180 break;
181 case 3:
182 c->guard_interval = GUARD_INTERVAL_1_4;
183 break;
184 }
185
186 switch ((buf[0] >> 3) & 0x07) {
187 case 0:
188 c->hierarchy = HIERARCHY_NONE;
189 break;
190 case 1:
191 c->hierarchy = HIERARCHY_1;
192 break;
193 case 2:
194 c->hierarchy = HIERARCHY_2;
195 break;
196 case 3:
197 c->hierarchy = HIERARCHY_4;
198 break;
199 }
200
201 switch ((buf[0] >> 0) & 0x07) {
202 case 0:
203 c->code_rate_HP = FEC_1_2;
204 break;
205 case 1:
206 c->code_rate_HP = FEC_2_3;
207 break;
208 case 2:
209 c->code_rate_HP = FEC_3_4;
210 break;
211 case 3:
212 c->code_rate_HP = FEC_5_6;
213 break;
214 case 4:
215 c->code_rate_HP = FEC_7_8;
216 break;
217 }
218
219 switch ((buf[1] >> 5) & 0x07) {
220 case 0:
221 c->code_rate_LP = FEC_1_2;
222 break;
223 case 1:
224 c->code_rate_LP = FEC_2_3;
225 break;
226 case 2:
227 c->code_rate_LP = FEC_3_4;
228 break;
229 case 3:
230 c->code_rate_LP = FEC_5_6;
231 break;
232 case 4:
233 c->code_rate_LP = FEC_7_8;
234 break;
235 }
236
237 ret = cxd2820r_rd_reg(priv, 0x007c6, &buf[0]);
238 if (ret)
239 goto error;
240
241 switch ((buf[0] >> 0) & 0x01) {
242 case 0:
243 c->inversion = INVERSION_OFF;
244 break;
245 case 1:
246 c->inversion = INVERSION_ON;
247 break;
248 }
249
250 return ret;
251error:
252 dbg("%s: failed:%d", __func__, ret);
253 return ret;
254}
255
256int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber)
257{
258 struct cxd2820r_priv *priv = fe->demodulator_priv;
259 int ret;
260 u8 buf[3], start_ber = 0;
261 *ber = 0;
262
263 if (priv->ber_running) {
264 ret = cxd2820r_rd_regs(priv, 0x00076, buf, sizeof(buf));
265 if (ret)
266 goto error;
267
268 if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) {
269 *ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0];
270 start_ber = 1;
271 }
272 } else {
273 priv->ber_running = 1;
274 start_ber = 1;
275 }
276
277 if (start_ber) {
278 /* (re)start BER */
279 ret = cxd2820r_wr_reg(priv, 0x00079, 0x01);
280 if (ret)
281 goto error;
282 }
283
284 return ret;
285error:
286 dbg("%s: failed:%d", __func__, ret);
287 return ret;
288}
289
290int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe,
291 u16 *strength)
292{
293 struct cxd2820r_priv *priv = fe->demodulator_priv;
294 int ret;
295 u8 buf[2];
296 u16 tmp;
297
298 ret = cxd2820r_rd_regs(priv, 0x00026, buf, sizeof(buf));
299 if (ret)
300 goto error;
301
302 tmp = (buf[0] & 0x0f) << 8 | buf[1];
303 tmp = ~tmp & 0x0fff;
304
305 /* scale value to 0x0000-0xffff from 0x0000-0x0fff */
306 *strength = tmp * 0xffff / 0x0fff;
307
308 return ret;
309error:
310 dbg("%s: failed:%d", __func__, ret);
311 return ret;
312}
313
314int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr)
315{
316 struct cxd2820r_priv *priv = fe->demodulator_priv;
317 int ret;
318 u8 buf[2];
319 u16 tmp;
320 /* report SNR in dB * 10 */
321
322 ret = cxd2820r_rd_regs(priv, 0x00028, buf, sizeof(buf));
323 if (ret)
324 goto error;
325
326 tmp = (buf[0] & 0x1f) << 8 | buf[1];
327 #define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */
328 if (tmp)
329 *snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24)
330 / 100);
331 else
332 *snr = 0;
333
334 dbg("%s: dBx10=%d val=%04x", __func__, *snr, tmp);
335
336 return ret;
337error:
338 dbg("%s: failed:%d", __func__, ret);
339 return ret;
340}
341
342int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks)
343{
344 *ucblocks = 0;
345 /* no way to read ? */
346 return 0;
347}
348
349int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status)
350{
351 struct cxd2820r_priv *priv = fe->demodulator_priv;
352 int ret;
353 u8 buf[4];
354 *status = 0;
355
356 ret = cxd2820r_rd_reg(priv, 0x00010, &buf[0]);
357 if (ret)
358 goto error;
359
360 if ((buf[0] & 0x07) == 6) {
361 ret = cxd2820r_rd_reg(priv, 0x00073, &buf[1]);
362 if (ret)
363 goto error;
364
365 if (((buf[1] >> 3) & 0x01) == 1) {
366 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
367 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
368 } else {
369 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
370 FE_HAS_VITERBI | FE_HAS_SYNC;
371 }
372 } else {
373 ret = cxd2820r_rd_reg(priv, 0x00014, &buf[2]);
374 if (ret)
375 goto error;
376
377 if ((buf[2] & 0x0f) >= 4) {
378 ret = cxd2820r_rd_reg(priv, 0x00a14, &buf[3]);
379 if (ret)
380 goto error;
381
382 if (((buf[3] >> 4) & 0x01) == 1)
383 *status |= FE_HAS_SIGNAL;
384 }
385 }
386
387 dbg("%s: lock=%02x %02x %02x %02x", __func__,
388 buf[0], buf[1], buf[2], buf[3]);
389
390 return ret;
391error:
392 dbg("%s: failed:%d", __func__, ret);
393 return ret;
394}
395
396int cxd2820r_init_t(struct dvb_frontend *fe)
397{
398 struct cxd2820r_priv *priv = fe->demodulator_priv;
399 int ret;
400
401 ret = cxd2820r_wr_reg(priv, 0x00085, 0x07);
402 if (ret)
403 goto error;
404
405 return ret;
406error:
407 dbg("%s: failed:%d", __func__, ret);
408 return ret;
409}
410
411int cxd2820r_sleep_t(struct dvb_frontend *fe)
412{
413 struct cxd2820r_priv *priv = fe->demodulator_priv;
414 int ret, i;
415 struct reg_val_mask tab[] = {
416 { 0x000ff, 0x1f, 0xff },
417 { 0x00085, 0x00, 0xff },
418 { 0x00088, 0x01, 0xff },
419 { 0x00081, 0x00, 0xff },
420 { 0x00080, 0x00, 0xff },
421 };
422
423 dbg("%s", __func__);
424
425 priv->delivery_system = SYS_UNDEFINED;
426
427 for (i = 0; i < ARRAY_SIZE(tab); i++) {
428 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
429 tab[i].mask);
430 if (ret)
431 goto error;
432 }
433
434 return ret;
435error:
436 dbg("%s: failed:%d", __func__, ret);
437 return ret;
438}
439
440int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
441 struct dvb_frontend_tune_settings *s)
442{
443 s->min_delay_ms = 500;
444 s->step_size = fe->ops.info.frequency_stepsize * 2;
445 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
446
447 return 0;
448}
449
diff --git a/drivers/media/dvb/frontends/cxd2820r_t2.c b/drivers/media/dvb/frontends/cxd2820r_t2.c
new file mode 100644
index 00000000000..c47b35c8acf
--- /dev/null
+++ b/drivers/media/dvb/frontends/cxd2820r_t2.c
@@ -0,0 +1,423 @@
1/*
2 * Sony CXD2820R demodulator driver
3 *
4 * Copyright (C) 2010 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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21
22#include "cxd2820r_priv.h"
23
24int cxd2820r_set_frontend_t2(struct dvb_frontend *fe,
25 struct dvb_frontend_parameters *params)
26{
27 struct cxd2820r_priv *priv = fe->demodulator_priv;
28 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
29 int ret, i;
30 u32 if_khz, if_ctl;
31 u64 num;
32 u8 buf[3], bw_param;
33 u8 bw_params1[][5] = {
34 { 0x1c, 0xb3, 0x33, 0x33, 0x33 }, /* 5 MHz */
35 { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
36 { 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
37 { 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
38 };
39 struct reg_val_mask tab[] = {
40 { 0x00080, 0x02, 0xff },
41 { 0x00081, 0x20, 0xff },
42 { 0x00085, 0x07, 0xff },
43 { 0x00088, 0x01, 0xff },
44 { 0x02069, 0x01, 0xff },
45
46 { 0x0207f, 0x2a, 0xff },
47 { 0x02082, 0x0a, 0xff },
48 { 0x02083, 0x0a, 0xff },
49 { 0x020cb, priv->cfg.if_agc_polarity << 6, 0x40 },
50 { 0x02070, priv->cfg.ts_mode, 0xff },
51 { 0x020b5, priv->cfg.spec_inv << 4, 0x10 },
52 { 0x02567, 0x07, 0x0f },
53 { 0x02569, 0x03, 0x03 },
54 { 0x02595, 0x1a, 0xff },
55 { 0x02596, 0x50, 0xff },
56 { 0x02a8c, 0x00, 0xff },
57 { 0x02a8d, 0x34, 0xff },
58 { 0x02a45, 0x06, 0x07 },
59 { 0x03f10, 0x0d, 0xff },
60 { 0x03f11, 0x02, 0xff },
61 { 0x03f12, 0x01, 0xff },
62 { 0x03f23, 0x2c, 0xff },
63 { 0x03f51, 0x13, 0xff },
64 { 0x03f52, 0x01, 0xff },
65 { 0x03f53, 0x00, 0xff },
66 { 0x027e6, 0x14, 0xff },
67 { 0x02786, 0x02, 0x07 },
68 { 0x02787, 0x40, 0xe0 },
69 { 0x027ef, 0x10, 0x18 },
70 };
71
72 dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
73
74 /* update GPIOs */
75 ret = cxd2820r_gpio(fe);
76 if (ret)
77 goto error;
78
79 /* program tuner */
80 if (fe->ops.tuner_ops.set_params)
81 fe->ops.tuner_ops.set_params(fe, params);
82
83 if (priv->delivery_system != SYS_DVBT2) {
84 for (i = 0; i < ARRAY_SIZE(tab); i++) {
85 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
86 tab[i].val, tab[i].mask);
87 if (ret)
88 goto error;
89 }
90 }
91
92 priv->delivery_system = SYS_DVBT2;
93
94 switch (c->bandwidth_hz) {
95 case 5000000:
96 if_khz = priv->cfg.if_dvbt2_5;
97 i = 0;
98 bw_param = 3;
99 break;
100 case 6000000:
101 if_khz = priv->cfg.if_dvbt2_6;
102 i = 1;
103 bw_param = 2;
104 break;
105 case 7000000:
106 if_khz = priv->cfg.if_dvbt2_7;
107 i = 2;
108 bw_param = 1;
109 break;
110 case 8000000:
111 if_khz = priv->cfg.if_dvbt2_8;
112 i = 3;
113 bw_param = 0;
114 break;
115 default:
116 return -EINVAL;
117 }
118
119 num = if_khz;
120 num *= 0x1000000;
121 if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
122 buf[0] = ((if_ctl >> 16) & 0xff);
123 buf[1] = ((if_ctl >> 8) & 0xff);
124 buf[2] = ((if_ctl >> 0) & 0xff);
125
126 ret = cxd2820r_wr_regs(priv, 0x020b6, buf, 3);
127 if (ret)
128 goto error;
129
130 ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[i], 5);
131 if (ret)
132 goto error;
133
134 ret = cxd2820r_wr_reg_mask(priv, 0x020d7, bw_param << 6, 0xc0);
135 if (ret)
136 goto error;
137
138 ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
139 if (ret)
140 goto error;
141
142 ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
143 if (ret)
144 goto error;
145
146 return ret;
147error:
148 dbg("%s: failed:%d", __func__, ret);
149 return ret;
150
151}
152
153int cxd2820r_get_frontend_t2(struct dvb_frontend *fe,
154 struct dvb_frontend_parameters *p)
155{
156 struct cxd2820r_priv *priv = fe->demodulator_priv;
157 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
158 int ret;
159 u8 buf[2];
160
161 ret = cxd2820r_rd_regs(priv, 0x0205c, buf, 2);
162 if (ret)
163 goto error;
164
165 switch ((buf[0] >> 0) & 0x07) {
166 case 0:
167 c->transmission_mode = TRANSMISSION_MODE_2K;
168 break;
169 case 1:
170 c->transmission_mode = TRANSMISSION_MODE_8K;
171 break;
172 case 2:
173 c->transmission_mode = TRANSMISSION_MODE_4K;
174 break;
175 case 3:
176 c->transmission_mode = TRANSMISSION_MODE_1K;
177 break;
178 case 4:
179 c->transmission_mode = TRANSMISSION_MODE_16K;
180 break;
181 case 5:
182 c->transmission_mode = TRANSMISSION_MODE_32K;
183 break;
184 }
185
186 switch ((buf[1] >> 4) & 0x07) {
187 case 0:
188 c->guard_interval = GUARD_INTERVAL_1_32;
189 break;
190 case 1:
191 c->guard_interval = GUARD_INTERVAL_1_16;
192 break;
193 case 2:
194 c->guard_interval = GUARD_INTERVAL_1_8;
195 break;
196 case 3:
197 c->guard_interval = GUARD_INTERVAL_1_4;
198 break;
199 case 4:
200 c->guard_interval = GUARD_INTERVAL_1_128;
201 break;
202 case 5:
203 c->guard_interval = GUARD_INTERVAL_19_128;
204 break;
205 case 6:
206 c->guard_interval = GUARD_INTERVAL_19_256;
207 break;
208 }
209
210 ret = cxd2820r_rd_regs(priv, 0x0225b, buf, 2);
211 if (ret)
212 goto error;
213
214 switch ((buf[0] >> 0) & 0x07) {
215 case 0:
216 c->fec_inner = FEC_1_2;
217 break;
218 case 1:
219 c->fec_inner = FEC_3_5;
220 break;
221 case 2:
222 c->fec_inner = FEC_2_3;
223 break;
224 case 3:
225 c->fec_inner = FEC_3_4;
226 break;
227 case 4:
228 c->fec_inner = FEC_4_5;
229 break;
230 case 5:
231 c->fec_inner = FEC_5_6;
232 break;
233 }
234
235 switch ((buf[1] >> 0) & 0x07) {
236 case 0:
237 c->modulation = QPSK;
238 break;
239 case 1:
240 c->modulation = QAM_16;
241 break;
242 case 2:
243 c->modulation = QAM_64;
244 break;
245 case 3:
246 c->modulation = QAM_256;
247 break;
248 }
249
250 ret = cxd2820r_rd_reg(priv, 0x020b5, &buf[0]);
251 if (ret)
252 goto error;
253
254 switch ((buf[0] >> 4) & 0x01) {
255 case 0:
256 c->inversion = INVERSION_OFF;
257 break;
258 case 1:
259 c->inversion = INVERSION_ON;
260 break;
261 }
262
263 return ret;
264error:
265 dbg("%s: failed:%d", __func__, ret);
266 return ret;
267}
268
269int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status)
270{
271 struct cxd2820r_priv *priv = fe->demodulator_priv;
272 int ret;
273 u8 buf[1];
274 *status = 0;
275
276 ret = cxd2820r_rd_reg(priv, 0x02010 , &buf[0]);
277 if (ret)
278 goto error;
279
280 if ((buf[0] & 0x07) == 6) {
281 if (((buf[0] >> 5) & 0x01) == 1) {
282 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
283 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
284 } else {
285 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
286 FE_HAS_VITERBI | FE_HAS_SYNC;
287 }
288 }
289
290 dbg("%s: lock=%02x", __func__, buf[0]);
291
292 return ret;
293error:
294 dbg("%s: failed:%d", __func__, ret);
295 return ret;
296}
297
298int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber)
299{
300 struct cxd2820r_priv *priv = fe->demodulator_priv;
301 int ret;
302 u8 buf[4];
303 unsigned int errbits;
304 *ber = 0;
305 /* FIXME: correct calculation */
306
307 ret = cxd2820r_rd_regs(priv, 0x02039, buf, sizeof(buf));
308 if (ret)
309 goto error;
310
311 if ((buf[0] >> 4) & 0x01) {
312 errbits = (buf[0] & 0x0f) << 24 | buf[1] << 16 |
313 buf[2] << 8 | buf[3];
314
315 if (errbits)
316 *ber = errbits * 64 / 16588800;
317 }
318
319 return ret;
320error:
321 dbg("%s: failed:%d", __func__, ret);
322 return ret;
323}
324
325int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe,
326 u16 *strength)
327{
328 struct cxd2820r_priv *priv = fe->demodulator_priv;
329 int ret;
330 u8 buf[2];
331 u16 tmp;
332
333 ret = cxd2820r_rd_regs(priv, 0x02026, buf, sizeof(buf));
334 if (ret)
335 goto error;
336
337 tmp = (buf[0] & 0x0f) << 8 | buf[1];
338 tmp = ~tmp & 0x0fff;
339
340 /* scale value to 0x0000-0xffff from 0x0000-0x0fff */
341 *strength = tmp * 0xffff / 0x0fff;
342
343 return ret;
344error:
345 dbg("%s: failed:%d", __func__, ret);
346 return ret;
347}
348
349int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr)
350{
351 struct cxd2820r_priv *priv = fe->demodulator_priv;
352 int ret;
353 u8 buf[2];
354 u16 tmp;
355 /* report SNR in dB * 10 */
356
357 ret = cxd2820r_rd_regs(priv, 0x02028, buf, sizeof(buf));
358 if (ret)
359 goto error;
360
361 tmp = (buf[0] & 0x0f) << 8 | buf[1];
362 #define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */
363 if (tmp)
364 *snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24)
365 / 100);
366 else
367 *snr = 0;
368
369 dbg("%s: dBx10=%d val=%04x", __func__, *snr, tmp);
370
371 return ret;
372error:
373 dbg("%s: failed:%d", __func__, ret);
374 return ret;
375}
376
377int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks)
378{
379 *ucblocks = 0;
380 /* no way to read ? */
381 return 0;
382}
383
384int cxd2820r_sleep_t2(struct dvb_frontend *fe)
385{
386 struct cxd2820r_priv *priv = fe->demodulator_priv;
387 int ret, i;
388 struct reg_val_mask tab[] = {
389 { 0x000ff, 0x1f, 0xff },
390 { 0x00085, 0x00, 0xff },
391 { 0x00088, 0x01, 0xff },
392 { 0x02069, 0x00, 0xff },
393 { 0x00081, 0x00, 0xff },
394 { 0x00080, 0x00, 0xff },
395 };
396
397 dbg("%s", __func__);
398
399 for (i = 0; i < ARRAY_SIZE(tab); i++) {
400 ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
401 tab[i].mask);
402 if (ret)
403 goto error;
404 }
405
406 priv->delivery_system = SYS_UNDEFINED;
407
408 return ret;
409error:
410 dbg("%s: failed:%d", __func__, ret);
411 return ret;
412}
413
414int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
415 struct dvb_frontend_tune_settings *s)
416{
417 s->min_delay_ms = 1500;
418 s->step_size = fe->ops.info.frequency_stepsize * 2;
419 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
420
421 return 0;
422}
423
diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c
new file mode 100644
index 00000000000..dc1cb17a6ea
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib0070.c
@@ -0,0 +1,780 @@
1/*
2 * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner.
3 *
4 * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 *
22 * This code is more or less generated from another driver, please
23 * excuse some codingstyle oddities.
24 *
25 */
26
27#include <linux/kernel.h>
28#include <linux/slab.h>
29#include <linux/i2c.h>
30#include <linux/mutex.h>
31
32#include "dvb_frontend.h"
33
34#include "dib0070.h"
35#include "dibx000_common.h"
36
37static int debug;
38module_param(debug, int, 0644);
39MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
40
41#define dprintk(args...) do { \
42 if (debug) { \
43 printk(KERN_DEBUG "DiB0070: "); \
44 printk(args); \
45 printk("\n"); \
46 } \
47} while (0)
48
49#define DIB0070_P1D 0x00
50#define DIB0070_P1F 0x01
51#define DIB0070_P1G 0x03
52#define DIB0070S_P1A 0x02
53
54struct dib0070_state {
55 struct i2c_adapter *i2c;
56 struct dvb_frontend *fe;
57 const struct dib0070_config *cfg;
58 u16 wbd_ff_offset;
59 u8 revision;
60
61 enum frontend_tune_state tune_state;
62 u32 current_rf;
63
64 /* for the captrim binary search */
65 s8 step;
66 u16 adc_diff;
67
68 s8 captrim;
69 s8 fcaptrim;
70 u16 lo4;
71
72 const struct dib0070_tuning *current_tune_table_index;
73 const struct dib0070_lna_match *lna_match;
74
75 u8 wbd_gain_current;
76 u16 wbd_offset_3_3[2];
77
78 /* for the I2C transfer */
79 struct i2c_msg msg[2];
80 u8 i2c_write_buffer[3];
81 u8 i2c_read_buffer[2];
82 struct mutex i2c_buffer_lock;
83};
84
85static u16 dib0070_read_reg(struct dib0070_state *state, u8 reg)
86{
87 u16 ret;
88
89 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
90 dprintk("could not acquire lock");
91 return 0;
92 }
93
94 state->i2c_write_buffer[0] = reg;
95
96 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
97 state->msg[0].addr = state->cfg->i2c_address;
98 state->msg[0].flags = 0;
99 state->msg[0].buf = state->i2c_write_buffer;
100 state->msg[0].len = 1;
101 state->msg[1].addr = state->cfg->i2c_address;
102 state->msg[1].flags = I2C_M_RD;
103 state->msg[1].buf = state->i2c_read_buffer;
104 state->msg[1].len = 2;
105
106 if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
107 printk(KERN_WARNING "DiB0070 I2C read failed\n");
108 ret = 0;
109 } else
110 ret = (state->i2c_read_buffer[0] << 8)
111 | state->i2c_read_buffer[1];
112
113 mutex_unlock(&state->i2c_buffer_lock);
114 return ret;
115}
116
117static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
118{
119 int ret;
120
121 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
122 dprintk("could not acquire lock");
123 return -EINVAL;
124 }
125 state->i2c_write_buffer[0] = reg;
126 state->i2c_write_buffer[1] = val >> 8;
127 state->i2c_write_buffer[2] = val & 0xff;
128
129 memset(state->msg, 0, sizeof(struct i2c_msg));
130 state->msg[0].addr = state->cfg->i2c_address;
131 state->msg[0].flags = 0;
132 state->msg[0].buf = state->i2c_write_buffer;
133 state->msg[0].len = 3;
134
135 if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
136 printk(KERN_WARNING "DiB0070 I2C write failed\n");
137 ret = -EREMOTEIO;
138 } else
139 ret = 0;
140
141 mutex_unlock(&state->i2c_buffer_lock);
142 return ret;
143}
144
145#define HARD_RESET(state) do { \
146 state->cfg->sleep(state->fe, 0); \
147 if (state->cfg->reset) { \
148 state->cfg->reset(state->fe,1); msleep(10); \
149 state->cfg->reset(state->fe,0); msleep(10); \
150 } \
151} while (0)
152
153static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
154{
155 struct dib0070_state *state = fe->tuner_priv;
156 u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
157
158 if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 7000)
159 tmp |= (0 << 14);
160 else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 6000)
161 tmp |= (1 << 14);
162 else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 5000)
163 tmp |= (2 << 14);
164 else
165 tmp |= (3 << 14);
166
167 dib0070_write_reg(state, 0x02, tmp);
168
169 /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
170 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
171 u16 value = dib0070_read_reg(state, 0x17);
172
173 dib0070_write_reg(state, 0x17, value & 0xfffc);
174 tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
175 dib0070_write_reg(state, 0x01, tmp | (60 << 9));
176
177 dib0070_write_reg(state, 0x17, value);
178 }
179 return 0;
180}
181
182static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state *tune_state)
183{
184 int8_t step_sign;
185 u16 adc;
186 int ret = 0;
187
188 if (*tune_state == CT_TUNER_STEP_0) {
189
190 dib0070_write_reg(state, 0x0f, 0xed10);
191 dib0070_write_reg(state, 0x17, 0x0034);
192
193 dib0070_write_reg(state, 0x18, 0x0032);
194 state->step = state->captrim = state->fcaptrim = 64;
195 state->adc_diff = 3000;
196 ret = 20;
197
198 *tune_state = CT_TUNER_STEP_1;
199 } else if (*tune_state == CT_TUNER_STEP_1) {
200 state->step /= 2;
201 dib0070_write_reg(state, 0x14, state->lo4 | state->captrim);
202 ret = 15;
203
204 *tune_state = CT_TUNER_STEP_2;
205 } else if (*tune_state == CT_TUNER_STEP_2) {
206
207 adc = dib0070_read_reg(state, 0x19);
208
209 dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024);
210
211 if (adc >= 400) {
212 adc -= 400;
213 step_sign = -1;
214 } else {
215 adc = 400 - adc;
216 step_sign = 1;
217 }
218
219 if (adc < state->adc_diff) {
220 dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff);
221 state->adc_diff = adc;
222 state->fcaptrim = state->captrim;
223
224
225
226 }
227 state->captrim += (step_sign * state->step);
228
229 if (state->step >= 1)
230 *tune_state = CT_TUNER_STEP_1;
231 else
232 *tune_state = CT_TUNER_STEP_3;
233
234 } else if (*tune_state == CT_TUNER_STEP_3) {
235 dib0070_write_reg(state, 0x14, state->lo4 | state->fcaptrim);
236 dib0070_write_reg(state, 0x18, 0x07ff);
237 *tune_state = CT_TUNER_STEP_4;
238 }
239
240 return ret;
241}
242
243static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
244{
245 struct dib0070_state *state = fe->tuner_priv;
246 u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
247 dprintk("CTRL_LO5: 0x%x", lo5);
248 return dib0070_write_reg(state, 0x15, lo5);
249}
250
251void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
252{
253 struct dib0070_state *state = fe->tuner_priv;
254
255 if (open) {
256 dib0070_write_reg(state, 0x1b, 0xff00);
257 dib0070_write_reg(state, 0x1a, 0x0000);
258 } else {
259 dib0070_write_reg(state, 0x1b, 0x4112);
260 if (state->cfg->vga_filter != 0) {
261 dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
262 dprintk("vga filter register is set to %x", state->cfg->vga_filter);
263 } else
264 dib0070_write_reg(state, 0x1a, 0x0009);
265 }
266}
267
268EXPORT_SYMBOL(dib0070_ctrl_agc_filter);
269struct dib0070_tuning {
270 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
271 u8 switch_trim;
272 u8 vco_band;
273 u8 hfdiv;
274 u8 vco_multi;
275 u8 presc;
276 u8 wbdmux;
277 u16 tuner_enable;
278};
279
280struct dib0070_lna_match {
281 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
282 u8 lna_band;
283};
284
285static const struct dib0070_tuning dib0070s_tuning_table[] = {
286 { 570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800 }, /* UHF */
287 { 700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800 },
288 { 863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800 },
289 { 1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND */
290 { 1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
291 { 2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
292 { 0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000 }, /* SBAND */
293};
294
295static const struct dib0070_tuning dib0070_tuning_table[] = {
296 { 115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000 }, /* FM below 92MHz cannot be tuned */
297 { 179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000 }, /* VHF */
298 { 189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000 },
299 { 250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000 },
300 { 569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800 }, /* UHF */
301 { 699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800 },
302 { 863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800 },
303 { 0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400 }, /* LBAND or everything higher than UHF */
304};
305
306static const struct dib0070_lna_match dib0070_lna_flip_chip[] = {
307 { 180000, 0 }, /* VHF */
308 { 188000, 1 },
309 { 196400, 2 },
310 { 250000, 3 },
311 { 550000, 0 }, /* UHF */
312 { 590000, 1 },
313 { 666000, 3 },
314 { 864000, 5 },
315 { 1500000, 0 }, /* LBAND or everything higher than UHF */
316 { 1600000, 1 },
317 { 2000000, 3 },
318 { 0xffffffff, 7 },
319};
320
321static const struct dib0070_lna_match dib0070_lna[] = {
322 { 180000, 0 }, /* VHF */
323 { 188000, 1 },
324 { 196400, 2 },
325 { 250000, 3 },
326 { 550000, 2 }, /* UHF */
327 { 650000, 3 },
328 { 750000, 5 },
329 { 850000, 6 },
330 { 864000, 7 },
331 { 1500000, 0 }, /* LBAND or everything higher than UHF */
332 { 1600000, 1 },
333 { 2000000, 3 },
334 { 0xffffffff, 7 },
335};
336
337#define LPF 100
338static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
339{
340 struct dib0070_state *state = fe->tuner_priv;
341
342 const struct dib0070_tuning *tune;
343 const struct dib0070_lna_match *lna_match;
344
345 enum frontend_tune_state *tune_state = &state->tune_state;
346 int ret = 10; /* 1ms is the default delay most of the time */
347
348 u8 band = (u8)BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency/1000);
349 u32 freq = fe->dtv_property_cache.frequency/1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
350
351#ifdef CONFIG_SYS_ISDBT
352 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
353 if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2)
354 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
355 || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
356 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == (state->fe->dtv_property_cache.isdbt_sb_segment_count / 2)))
357 || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
358 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))))
359 freq += 850;
360#endif
361 if (state->current_rf != freq) {
362
363 switch (state->revision) {
364 case DIB0070S_P1A:
365 tune = dib0070s_tuning_table;
366 lna_match = dib0070_lna;
367 break;
368 default:
369 tune = dib0070_tuning_table;
370 if (state->cfg->flip_chip)
371 lna_match = dib0070_lna_flip_chip;
372 else
373 lna_match = dib0070_lna;
374 break;
375 }
376 while (freq > tune->max_freq) /* find the right one */
377 tune++;
378 while (freq > lna_match->max_freq) /* find the right one */
379 lna_match++;
380
381 state->current_tune_table_index = tune;
382 state->lna_match = lna_match;
383 }
384
385 if (*tune_state == CT_TUNER_START) {
386 dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
387 if (state->current_rf != freq) {
388 u8 REFDIV;
389 u32 FBDiv, Rest, FREF, VCOF_kHz;
390 u8 Den;
391
392 state->current_rf = freq;
393 state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
394
395
396 dib0070_write_reg(state, 0x17, 0x30);
397
398
399 VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
400
401 switch (band) {
402 case BAND_VHF:
403 REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
404 break;
405 case BAND_FM:
406 REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
407 break;
408 default:
409 REFDIV = (u8) (state->cfg->clock_khz / 10000);
410 break;
411 }
412 FREF = state->cfg->clock_khz / REFDIV;
413
414
415
416 switch (state->revision) {
417 case DIB0070S_P1A:
418 FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
419 Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
420 break;
421
422 case DIB0070_P1G:
423 case DIB0070_P1F:
424 default:
425 FBDiv = (freq / (FREF / 2));
426 Rest = 2 * freq - FBDiv * FREF;
427 break;
428 }
429
430 if (Rest < LPF)
431 Rest = 0;
432 else if (Rest < 2 * LPF)
433 Rest = 2 * LPF;
434 else if (Rest > (FREF - LPF)) {
435 Rest = 0;
436 FBDiv += 1;
437 } else if (Rest > (FREF - 2 * LPF))
438 Rest = FREF - 2 * LPF;
439 Rest = (Rest * 6528) / (FREF / 10);
440
441 Den = 1;
442 if (Rest > 0) {
443 state->lo4 |= (1 << 14) | (1 << 12);
444 Den = 255;
445 }
446
447
448 dib0070_write_reg(state, 0x11, (u16)FBDiv);
449 dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
450 dib0070_write_reg(state, 0x13, (u16) Rest);
451
452 if (state->revision == DIB0070S_P1A) {
453
454 if (band == BAND_SBAND) {
455 dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
456 dib0070_write_reg(state, 0x1d, 0xFFFF);
457 } else
458 dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
459 }
460
461 dib0070_write_reg(state, 0x20,
462 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
463
464 dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
465 dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
466 dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
467 dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
468 dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
469 dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
470
471 *tune_state = CT_TUNER_STEP_0;
472 } else { /* we are already tuned to this frequency - the configuration is correct */
473 ret = 50; /* wakeup time */
474 *tune_state = CT_TUNER_STEP_5;
475 }
476 } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
477
478 ret = dib0070_captrim(state, tune_state);
479
480 } else if (*tune_state == CT_TUNER_STEP_4) {
481 const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
482 if (tmp != NULL) {
483 while (freq/1000 > tmp->freq) /* find the right one */
484 tmp++;
485 dib0070_write_reg(state, 0x0f,
486 (0 << 15) | (1 << 14) | (3 << 12)
487 | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7)
488 | (state->current_tune_table_index->wbdmux << 0));
489 state->wbd_gain_current = tmp->wbd_gain_val;
490 } else {
491 dib0070_write_reg(state, 0x0f,
492 (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index->
493 wbdmux << 0));
494 state->wbd_gain_current = 6;
495 }
496
497 dib0070_write_reg(state, 0x06, 0x3fff);
498 dib0070_write_reg(state, 0x07,
499 (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0));
500 dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
501 dib0070_write_reg(state, 0x0d, 0x0d80);
502
503
504 dib0070_write_reg(state, 0x18, 0x07ff);
505 dib0070_write_reg(state, 0x17, 0x0033);
506
507
508 *tune_state = CT_TUNER_STEP_5;
509 } else if (*tune_state == CT_TUNER_STEP_5) {
510 dib0070_set_bandwidth(fe, ch);
511 *tune_state = CT_TUNER_STOP;
512 } else {
513 ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */
514 }
515 return ret;
516}
517
518
519static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
520{
521 struct dib0070_state *state = fe->tuner_priv;
522 uint32_t ret;
523
524 state->tune_state = CT_TUNER_START;
525
526 do {
527 ret = dib0070_tune_digital(fe, p);
528 if (ret != FE_CALLBACK_TIME_NEVER)
529 msleep(ret/10);
530 else
531 break;
532 } while (state->tune_state != CT_TUNER_STOP);
533
534 return 0;
535}
536
537static int dib0070_wakeup(struct dvb_frontend *fe)
538{
539 struct dib0070_state *state = fe->tuner_priv;
540 if (state->cfg->sleep)
541 state->cfg->sleep(fe, 0);
542 return 0;
543}
544
545static int dib0070_sleep(struct dvb_frontend *fe)
546{
547 struct dib0070_state *state = fe->tuner_priv;
548 if (state->cfg->sleep)
549 state->cfg->sleep(fe, 1);
550 return 0;
551}
552
553u8 dib0070_get_rf_output(struct dvb_frontend *fe)
554{
555 struct dib0070_state *state = fe->tuner_priv;
556 return (dib0070_read_reg(state, 0x07) >> 11) & 0x3;
557}
558EXPORT_SYMBOL(dib0070_get_rf_output);
559
560int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no)
561{
562 struct dib0070_state *state = fe->tuner_priv;
563 u16 rxrf2 = dib0070_read_reg(state, 0x07) & 0xfe7ff;
564 if (no > 3)
565 no = 3;
566 if (no < 1)
567 no = 1;
568 return dib0070_write_reg(state, 0x07, rxrf2 | (no << 11));
569}
570EXPORT_SYMBOL(dib0070_set_rf_output);
571
572static const u16 dib0070_p1f_defaults[] =
573
574{
575 7, 0x02,
576 0x0008,
577 0x0000,
578 0x0000,
579 0x0000,
580 0x0000,
581 0x0002,
582 0x0100,
583
584 3, 0x0d,
585 0x0d80,
586 0x0001,
587 0x0000,
588
589 4, 0x11,
590 0x0000,
591 0x0103,
592 0x0000,
593 0x0000,
594
595 3, 0x16,
596 0x0004 | 0x0040,
597 0x0030,
598 0x07ff,
599
600 6, 0x1b,
601 0x4112,
602 0xff00,
603 0xc07f,
604 0x0000,
605 0x0180,
606 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
607
608 0,
609};
610
611static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain)
612{
613 u16 tuner_en = dib0070_read_reg(state, 0x20);
614 u16 offset;
615
616 dib0070_write_reg(state, 0x18, 0x07ff);
617 dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
618 dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
619 msleep(9);
620 offset = dib0070_read_reg(state, 0x19);
621 dib0070_write_reg(state, 0x20, tuner_en);
622 return offset;
623}
624
625static void dib0070_wbd_offset_calibration(struct dib0070_state *state)
626{
627 u8 gain;
628 for (gain = 6; gain < 8; gain++) {
629 state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
630 dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain-6]);
631 }
632}
633
634u16 dib0070_wbd_offset(struct dvb_frontend *fe)
635{
636 struct dib0070_state *state = fe->tuner_priv;
637 const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
638 u32 freq = fe->dtv_property_cache.frequency/1000;
639
640 if (tmp != NULL) {
641 while (freq/1000 > tmp->freq) /* find the right one */
642 tmp++;
643 state->wbd_gain_current = tmp->wbd_gain_val;
644 } else
645 state->wbd_gain_current = 6;
646
647 return state->wbd_offset_3_3[state->wbd_gain_current - 6];
648}
649EXPORT_SYMBOL(dib0070_wbd_offset);
650
651#define pgm_read_word(w) (*w)
652static int dib0070_reset(struct dvb_frontend *fe)
653{
654 struct dib0070_state *state = fe->tuner_priv;
655 u16 l, r, *n;
656
657 HARD_RESET(state);
658
659
660#ifndef FORCE_SBAND_TUNER
661 if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1)
662 state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff;
663 else
664#else
665#warning forcing SBAND
666#endif
667 state->revision = DIB0070S_P1A;
668
669 /* P1F or not */
670 dprintk("Revision: %x", state->revision);
671
672 if (state->revision == DIB0070_P1D) {
673 dprintk("Error: this driver is not to be used meant for P1D or earlier");
674 return -EINVAL;
675 }
676
677 n = (u16 *) dib0070_p1f_defaults;
678 l = pgm_read_word(n++);
679 while (l) {
680 r = pgm_read_word(n++);
681 do {
682 dib0070_write_reg(state, (u8)r, pgm_read_word(n++));
683 r++;
684 } while (--l);
685 l = pgm_read_word(n++);
686 }
687
688 if (state->cfg->force_crystal_mode != 0)
689 r = state->cfg->force_crystal_mode;
690 else if (state->cfg->clock_khz >= 24000)
691 r = 1;
692 else
693 r = 2;
694
695
696 r |= state->cfg->osc_buffer_state << 3;
697
698 dib0070_write_reg(state, 0x10, r);
699 dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 5));
700
701 if (state->cfg->invert_iq) {
702 r = dib0070_read_reg(state, 0x02) & 0xffdf;
703 dib0070_write_reg(state, 0x02, r | (1 << 5));
704 }
705
706 if (state->revision == DIB0070S_P1A)
707 dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
708 else
709 dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter);
710
711 dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8);
712
713 dib0070_wbd_offset_calibration(state);
714
715 return 0;
716}
717
718static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency)
719{
720 struct dib0070_state *state = fe->tuner_priv;
721
722 *frequency = 1000 * state->current_rf;
723 return 0;
724}
725
726static int dib0070_release(struct dvb_frontend *fe)
727{
728 kfree(fe->tuner_priv);
729 fe->tuner_priv = NULL;
730 return 0;
731}
732
733static const struct dvb_tuner_ops dib0070_ops = {
734 .info = {
735 .name = "DiBcom DiB0070",
736 .frequency_min = 45000000,
737 .frequency_max = 860000000,
738 .frequency_step = 1000,
739 },
740 .release = dib0070_release,
741
742 .init = dib0070_wakeup,
743 .sleep = dib0070_sleep,
744 .set_params = dib0070_tune,
745
746 .get_frequency = dib0070_get_frequency,
747// .get_bandwidth = dib0070_get_bandwidth
748};
749
750struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
751{
752 struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL);
753 if (state == NULL)
754 return NULL;
755
756 state->cfg = cfg;
757 state->i2c = i2c;
758 state->fe = fe;
759 mutex_init(&state->i2c_buffer_lock);
760 fe->tuner_priv = state;
761
762 if (dib0070_reset(fe) != 0)
763 goto free_mem;
764
765 printk(KERN_INFO "DiB0070: successfully identified\n");
766 memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops));
767
768 fe->tuner_priv = state;
769 return fe;
770
771free_mem:
772 kfree(state);
773 fe->tuner_priv = NULL;
774 return NULL;
775}
776EXPORT_SYMBOL(dib0070_attach);
777
778MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
779MODULE_DESCRIPTION("Driver for the DiBcom 0070 base-band RF Tuner");
780MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h
new file mode 100644
index 00000000000..45c31fae396
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib0070.h
@@ -0,0 +1,76 @@
1/*
2 * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner.
3 *
4 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 */
10#ifndef DIB0070_H
11#define DIB0070_H
12
13struct dvb_frontend;
14struct i2c_adapter;
15
16#define DEFAULT_DIB0070_I2C_ADDRESS 0x60
17
18struct dib0070_wbd_gain_cfg {
19 u16 freq;
20 u16 wbd_gain_val;
21};
22
23struct dib0070_config {
24 u8 i2c_address;
25
26 /* tuner pins controlled externally */
27 int (*reset) (struct dvb_frontend *, int);
28 int (*sleep) (struct dvb_frontend *, int);
29
30 /* offset in kHz */
31 int freq_offset_khz_uhf;
32 int freq_offset_khz_vhf;
33
34 u8 osc_buffer_state; /* 0= normal, 1= tri-state */
35 u32 clock_khz;
36 u8 clock_pad_drive; /* (Drive + 1) * 2mA */
37
38 u8 invert_iq; /* invert Q - in case I or Q is inverted on the board */
39
40 u8 force_crystal_mode; /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */
41
42 u8 flip_chip;
43 u8 enable_third_order_filter;
44 u8 charge_pump;
45
46 const struct dib0070_wbd_gain_cfg *wbd_gain;
47
48 u8 vga_filter;
49};
50
51#if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE))
52extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
53extern u16 dib0070_wbd_offset(struct dvb_frontend *);
54extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
55extern u8 dib0070_get_rf_output(struct dvb_frontend *fe);
56extern int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no);
57#else
58static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
59{
60 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
61 return NULL;
62}
63
64static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
65{
66 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
67 return 0;
68}
69
70static inline void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
71{
72 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
73}
74#endif
75
76#endif
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c
new file mode 100644
index 00000000000..b174d1c7858
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib0090.c
@@ -0,0 +1,2539 @@
1/*
2 * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
3 *
4 * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 *
22 * This code is more or less generated from another driver, please
23 * excuse some codingstyle oddities.
24 *
25 */
26
27#include <linux/kernel.h>
28#include <linux/slab.h>
29#include <linux/i2c.h>
30#include <linux/mutex.h>
31
32#include "dvb_frontend.h"
33
34#include "dib0090.h"
35#include "dibx000_common.h"
36
37static int debug;
38module_param(debug, int, 0644);
39MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
40
41#define dprintk(args...) do { \
42 if (debug) { \
43 printk(KERN_DEBUG "DiB0090: "); \
44 printk(args); \
45 printk("\n"); \
46 } \
47} while (0)
48
49#define CONFIG_SYS_DVBT
50#define CONFIG_SYS_ISDBT
51#define CONFIG_BAND_CBAND
52#define CONFIG_BAND_VHF
53#define CONFIG_BAND_UHF
54#define CONFIG_DIB0090_USE_PWM_AGC
55
56#define EN_LNA0 0x8000
57#define EN_LNA1 0x4000
58#define EN_LNA2 0x2000
59#define EN_LNA3 0x1000
60#define EN_MIX0 0x0800
61#define EN_MIX1 0x0400
62#define EN_MIX2 0x0200
63#define EN_MIX3 0x0100
64#define EN_IQADC 0x0040
65#define EN_PLL 0x0020
66#define EN_TX 0x0010
67#define EN_BB 0x0008
68#define EN_LO 0x0004
69#define EN_BIAS 0x0001
70
71#define EN_IQANA 0x0002
72#define EN_DIGCLK 0x0080 /* not in the 0x24 reg, only in 0x1b */
73#define EN_CRYSTAL 0x0002
74
75#define EN_UHF 0x22E9
76#define EN_VHF 0x44E9
77#define EN_LBD 0x11E9
78#define EN_SBD 0x44E9
79#define EN_CAB 0x88E9
80
81/* Calibration defines */
82#define DC_CAL 0x1
83#define WBD_CAL 0x2
84#define TEMP_CAL 0x4
85#define CAPTRIM_CAL 0x8
86
87#define KROSUS_PLL_LOCKED 0x800
88#define KROSUS 0x2
89
90/* Use those defines to identify SOC version */
91#define SOC 0x02
92#define SOC_7090_P1G_11R1 0x82
93#define SOC_7090_P1G_21R1 0x8a
94#define SOC_8090_P1G_11R1 0x86
95#define SOC_8090_P1G_21R1 0x8e
96
97/* else use thos ones to check */
98#define P1A_B 0x0
99#define P1C 0x1
100#define P1D_E_F 0x3
101#define P1G 0x7
102#define P1G_21R2 0xf
103
104#define MP001 0x1 /* Single 9090/8096 */
105#define MP005 0x4 /* Single Sband */
106#define MP008 0x6 /* Dual diversity VHF-UHF-LBAND */
107#define MP009 0x7 /* Dual diversity 29098 CBAND-UHF-LBAND-SBAND */
108
109#define pgm_read_word(w) (*w)
110
111struct dc_calibration;
112
113struct dib0090_tuning {
114 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
115 u8 switch_trim;
116 u8 lna_tune;
117 u16 lna_bias;
118 u16 v2i;
119 u16 mix;
120 u16 load;
121 u16 tuner_enable;
122};
123
124struct dib0090_pll {
125 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
126 u8 vco_band;
127 u8 hfdiv_code;
128 u8 hfdiv;
129 u8 topresc;
130};
131
132struct dib0090_identity {
133 u8 version;
134 u8 product;
135 u8 p1g;
136 u8 in_soc;
137};
138
139struct dib0090_state {
140 struct i2c_adapter *i2c;
141 struct dvb_frontend *fe;
142 const struct dib0090_config *config;
143
144 u8 current_band;
145 enum frontend_tune_state tune_state;
146 u32 current_rf;
147
148 u16 wbd_offset;
149 s16 wbd_target; /* in dB */
150
151 s16 rf_gain_limit; /* take-over-point: where to split between bb and rf gain */
152 s16 current_gain; /* keeps the currently programmed gain */
153 u8 agc_step; /* new binary search */
154
155 u16 gain[2]; /* for channel monitoring */
156
157 const u16 *rf_ramp;
158 const u16 *bb_ramp;
159
160 /* for the software AGC ramps */
161 u16 bb_1_def;
162 u16 rf_lt_def;
163 u16 gain_reg[4];
164
165 /* for the captrim/dc-offset search */
166 s8 step;
167 s16 adc_diff;
168 s16 min_adc_diff;
169
170 s8 captrim;
171 s8 fcaptrim;
172
173 const struct dc_calibration *dc;
174 u16 bb6, bb7;
175
176 const struct dib0090_tuning *current_tune_table_index;
177 const struct dib0090_pll *current_pll_table_index;
178
179 u8 tuner_is_tuned;
180 u8 agc_freeze;
181
182 struct dib0090_identity identity;
183
184 u32 rf_request;
185 u8 current_standard;
186
187 u8 calibrate;
188 u32 rest;
189 u16 bias;
190 s16 temperature;
191
192 u8 wbd_calibration_gain;
193 const struct dib0090_wbd_slope *current_wbd_table;
194 u16 wbdmux;
195
196 /* for the I2C transfer */
197 struct i2c_msg msg[2];
198 u8 i2c_write_buffer[3];
199 u8 i2c_read_buffer[2];
200 struct mutex i2c_buffer_lock;
201};
202
203struct dib0090_fw_state {
204 struct i2c_adapter *i2c;
205 struct dvb_frontend *fe;
206 struct dib0090_identity identity;
207 const struct dib0090_config *config;
208
209 /* for the I2C transfer */
210 struct i2c_msg msg;
211 u8 i2c_write_buffer[2];
212 u8 i2c_read_buffer[2];
213 struct mutex i2c_buffer_lock;
214};
215
216static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
217{
218 u16 ret;
219
220 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
221 dprintk("could not acquire lock");
222 return 0;
223 }
224
225 state->i2c_write_buffer[0] = reg;
226
227 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
228 state->msg[0].addr = state->config->i2c_address;
229 state->msg[0].flags = 0;
230 state->msg[0].buf = state->i2c_write_buffer;
231 state->msg[0].len = 1;
232 state->msg[1].addr = state->config->i2c_address;
233 state->msg[1].flags = I2C_M_RD;
234 state->msg[1].buf = state->i2c_read_buffer;
235 state->msg[1].len = 2;
236
237 if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
238 printk(KERN_WARNING "DiB0090 I2C read failed\n");
239 ret = 0;
240 } else
241 ret = (state->i2c_read_buffer[0] << 8)
242 | state->i2c_read_buffer[1];
243
244 mutex_unlock(&state->i2c_buffer_lock);
245 return ret;
246}
247
248static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
249{
250 int ret;
251
252 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
253 dprintk("could not acquire lock");
254 return -EINVAL;
255 }
256
257 state->i2c_write_buffer[0] = reg & 0xff;
258 state->i2c_write_buffer[1] = val >> 8;
259 state->i2c_write_buffer[2] = val & 0xff;
260
261 memset(state->msg, 0, sizeof(struct i2c_msg));
262 state->msg[0].addr = state->config->i2c_address;
263 state->msg[0].flags = 0;
264 state->msg[0].buf = state->i2c_write_buffer;
265 state->msg[0].len = 3;
266
267 if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
268 printk(KERN_WARNING "DiB0090 I2C write failed\n");
269 ret = -EREMOTEIO;
270 } else
271 ret = 0;
272
273 mutex_unlock(&state->i2c_buffer_lock);
274 return ret;
275}
276
277static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
278{
279 u16 ret;
280
281 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
282 dprintk("could not acquire lock");
283 return 0;
284 }
285
286 state->i2c_write_buffer[0] = reg;
287
288 memset(&state->msg, 0, sizeof(struct i2c_msg));
289 state->msg.addr = reg;
290 state->msg.flags = I2C_M_RD;
291 state->msg.buf = state->i2c_read_buffer;
292 state->msg.len = 2;
293 if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
294 printk(KERN_WARNING "DiB0090 I2C read failed\n");
295 ret = 0;
296 } else
297 ret = (state->i2c_read_buffer[0] << 8)
298 | state->i2c_read_buffer[1];
299
300 mutex_unlock(&state->i2c_buffer_lock);
301 return ret;
302}
303
304static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
305{
306 int ret;
307
308 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
309 dprintk("could not acquire lock");
310 return -EINVAL;
311 }
312
313 state->i2c_write_buffer[0] = val >> 8;
314 state->i2c_write_buffer[1] = val & 0xff;
315
316 memset(&state->msg, 0, sizeof(struct i2c_msg));
317 state->msg.addr = reg;
318 state->msg.flags = 0;
319 state->msg.buf = state->i2c_write_buffer;
320 state->msg.len = 2;
321 if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
322 printk(KERN_WARNING "DiB0090 I2C write failed\n");
323 ret = -EREMOTEIO;
324 } else
325 ret = 0;
326
327 mutex_unlock(&state->i2c_buffer_lock);
328 return ret;
329}
330
331#define HARD_RESET(state) do { if (cfg->reset) { if (cfg->sleep) cfg->sleep(fe, 0); msleep(10); cfg->reset(fe, 1); msleep(10); cfg->reset(fe, 0); msleep(10); } } while (0)
332#define ADC_TARGET -220
333#define GAIN_ALPHA 5
334#define WBD_ALPHA 6
335#define LPF 100
336static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c)
337{
338 do {
339 dib0090_write_reg(state, r++, *b++);
340 } while (--c);
341}
342
343static int dib0090_identify(struct dvb_frontend *fe)
344{
345 struct dib0090_state *state = fe->tuner_priv;
346 u16 v;
347 struct dib0090_identity *identity = &state->identity;
348
349 v = dib0090_read_reg(state, 0x1a);
350
351 identity->p1g = 0;
352 identity->in_soc = 0;
353
354 dprintk("Tuner identification (Version = 0x%04x)", v);
355
356 /* without PLL lock info */
357 v &= ~KROSUS_PLL_LOCKED;
358
359 identity->version = v & 0xff;
360 identity->product = (v >> 8) & 0xf;
361
362 if (identity->product != KROSUS)
363 goto identification_error;
364
365 if ((identity->version & 0x3) == SOC) {
366 identity->in_soc = 1;
367 switch (identity->version) {
368 case SOC_8090_P1G_11R1:
369 dprintk("SOC 8090 P1-G11R1 Has been detected");
370 identity->p1g = 1;
371 break;
372 case SOC_8090_P1G_21R1:
373 dprintk("SOC 8090 P1-G21R1 Has been detected");
374 identity->p1g = 1;
375 break;
376 case SOC_7090_P1G_11R1:
377 dprintk("SOC 7090 P1-G11R1 Has been detected");
378 identity->p1g = 1;
379 break;
380 case SOC_7090_P1G_21R1:
381 dprintk("SOC 7090 P1-G21R1 Has been detected");
382 identity->p1g = 1;
383 break;
384 default:
385 goto identification_error;
386 }
387 } else {
388 switch ((identity->version >> 5) & 0x7) {
389 case MP001:
390 dprintk("MP001 : 9090/8096");
391 break;
392 case MP005:
393 dprintk("MP005 : Single Sband");
394 break;
395 case MP008:
396 dprintk("MP008 : diversity VHF-UHF-LBAND");
397 break;
398 case MP009:
399 dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND");
400 break;
401 default:
402 goto identification_error;
403 }
404
405 switch (identity->version & 0x1f) {
406 case P1G_21R2:
407 dprintk("P1G_21R2 detected");
408 identity->p1g = 1;
409 break;
410 case P1G:
411 dprintk("P1G detected");
412 identity->p1g = 1;
413 break;
414 case P1D_E_F:
415 dprintk("P1D/E/F detected");
416 break;
417 case P1C:
418 dprintk("P1C detected");
419 break;
420 case P1A_B:
421 dprintk("P1-A/B detected: driver is deactivated - not available");
422 goto identification_error;
423 break;
424 default:
425 goto identification_error;
426 }
427 }
428
429 return 0;
430
431identification_error:
432 return -EIO;
433}
434
435static int dib0090_fw_identify(struct dvb_frontend *fe)
436{
437 struct dib0090_fw_state *state = fe->tuner_priv;
438 struct dib0090_identity *identity = &state->identity;
439
440 u16 v = dib0090_fw_read_reg(state, 0x1a);
441 identity->p1g = 0;
442 identity->in_soc = 0;
443
444 dprintk("FE: Tuner identification (Version = 0x%04x)", v);
445
446 /* without PLL lock info */
447 v &= ~KROSUS_PLL_LOCKED;
448
449 identity->version = v & 0xff;
450 identity->product = (v >> 8) & 0xf;
451
452 if (identity->product != KROSUS)
453 goto identification_error;
454
455 if ((identity->version & 0x3) == SOC) {
456 identity->in_soc = 1;
457 switch (identity->version) {
458 case SOC_8090_P1G_11R1:
459 dprintk("SOC 8090 P1-G11R1 Has been detected");
460 identity->p1g = 1;
461 break;
462 case SOC_8090_P1G_21R1:
463 dprintk("SOC 8090 P1-G21R1 Has been detected");
464 identity->p1g = 1;
465 break;
466 case SOC_7090_P1G_11R1:
467 dprintk("SOC 7090 P1-G11R1 Has been detected");
468 identity->p1g = 1;
469 break;
470 case SOC_7090_P1G_21R1:
471 dprintk("SOC 7090 P1-G21R1 Has been detected");
472 identity->p1g = 1;
473 break;
474 default:
475 goto identification_error;
476 }
477 } else {
478 switch ((identity->version >> 5) & 0x7) {
479 case MP001:
480 dprintk("MP001 : 9090/8096");
481 break;
482 case MP005:
483 dprintk("MP005 : Single Sband");
484 break;
485 case MP008:
486 dprintk("MP008 : diversity VHF-UHF-LBAND");
487 break;
488 case MP009:
489 dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND");
490 break;
491 default:
492 goto identification_error;
493 }
494
495 switch (identity->version & 0x1f) {
496 case P1G_21R2:
497 dprintk("P1G_21R2 detected");
498 identity->p1g = 1;
499 break;
500 case P1G:
501 dprintk("P1G detected");
502 identity->p1g = 1;
503 break;
504 case P1D_E_F:
505 dprintk("P1D/E/F detected");
506 break;
507 case P1C:
508 dprintk("P1C detected");
509 break;
510 case P1A_B:
511 dprintk("P1-A/B detected: driver is deactivated - not available");
512 goto identification_error;
513 break;
514 default:
515 goto identification_error;
516 }
517 }
518
519 return 0;
520
521identification_error:
522 return -EIO;;
523}
524
525static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
526{
527 struct dib0090_state *state = fe->tuner_priv;
528 u16 PllCfg, i, v;
529
530 HARD_RESET(state);
531
532 dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
533 dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
534
535 if (!cfg->in_soc) {
536 /* adcClkOutRatio=8->7, release reset */
537 dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
538 if (cfg->clkoutdrive != 0)
539 dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
540 | (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
541 else
542 dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
543 | (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
544 }
545
546 /* Read Pll current config * */
547 PllCfg = dib0090_read_reg(state, 0x21);
548
549 /** Reconfigure PLL if current setting is different from default setting **/
550 if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && (!cfg->in_soc)
551 && !cfg->io.pll_bypass) {
552
553 /* Set Bypass mode */
554 PllCfg |= (1 << 15);
555 dib0090_write_reg(state, 0x21, PllCfg);
556
557 /* Set Reset Pll */
558 PllCfg &= ~(1 << 13);
559 dib0090_write_reg(state, 0x21, PllCfg);
560
561 /*** Set new Pll configuration in bypass and reset state ***/
562 PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
563 dib0090_write_reg(state, 0x21, PllCfg);
564
565 /* Remove Reset Pll */
566 PllCfg |= (1 << 13);
567 dib0090_write_reg(state, 0x21, PllCfg);
568
569 /*** Wait for PLL lock ***/
570 i = 100;
571 do {
572 v = !!(dib0090_read_reg(state, 0x1a) & 0x800);
573 if (v)
574 break;
575 } while (--i);
576
577 if (i == 0) {
578 dprintk("Pll: Unable to lock Pll");
579 return;
580 }
581
582 /* Finally Remove Bypass mode */
583 PllCfg &= ~(1 << 15);
584 dib0090_write_reg(state, 0x21, PllCfg);
585 }
586
587 if (cfg->io.pll_bypass) {
588 PllCfg |= (cfg->io.pll_bypass << 15);
589 dib0090_write_reg(state, 0x21, PllCfg);
590 }
591}
592
593static int dib0090_fw_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
594{
595 struct dib0090_fw_state *state = fe->tuner_priv;
596 u16 PllCfg;
597 u16 v;
598 int i;
599
600 dprintk("fw reset digital");
601 HARD_RESET(state);
602
603 dib0090_fw_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
604 dib0090_fw_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
605
606 dib0090_fw_write_reg(state, 0x20,
607 ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (cfg->data_tx_drv << 4) | cfg->ls_cfg_pad_drv);
608
609 v = (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 9) | (0 << 8) | (cfg->clkouttobamse << 4) | (0 << 2) | (0);
610 if (cfg->clkoutdrive != 0)
611 v |= cfg->clkoutdrive << 5;
612 else
613 v |= 7 << 5;
614
615 v |= 2 << 10;
616 dib0090_fw_write_reg(state, 0x23, v);
617
618 /* Read Pll current config * */
619 PllCfg = dib0090_fw_read_reg(state, 0x21);
620
621 /** Reconfigure PLL if current setting is different from default setting **/
622 if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && !cfg->io.pll_bypass) {
623
624 /* Set Bypass mode */
625 PllCfg |= (1 << 15);
626 dib0090_fw_write_reg(state, 0x21, PllCfg);
627
628 /* Set Reset Pll */
629 PllCfg &= ~(1 << 13);
630 dib0090_fw_write_reg(state, 0x21, PllCfg);
631
632 /*** Set new Pll configuration in bypass and reset state ***/
633 PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
634 dib0090_fw_write_reg(state, 0x21, PllCfg);
635
636 /* Remove Reset Pll */
637 PllCfg |= (1 << 13);
638 dib0090_fw_write_reg(state, 0x21, PllCfg);
639
640 /*** Wait for PLL lock ***/
641 i = 100;
642 do {
643 v = !!(dib0090_fw_read_reg(state, 0x1a) & 0x800);
644 if (v)
645 break;
646 } while (--i);
647
648 if (i == 0) {
649 dprintk("Pll: Unable to lock Pll");
650 return -EIO;
651 }
652
653 /* Finally Remove Bypass mode */
654 PllCfg &= ~(1 << 15);
655 dib0090_fw_write_reg(state, 0x21, PllCfg);
656 }
657
658 if (cfg->io.pll_bypass) {
659 PllCfg |= (cfg->io.pll_bypass << 15);
660 dib0090_fw_write_reg(state, 0x21, PllCfg);
661 }
662
663 return dib0090_fw_identify(fe);
664}
665
666static int dib0090_wakeup(struct dvb_frontend *fe)
667{
668 struct dib0090_state *state = fe->tuner_priv;
669 if (state->config->sleep)
670 state->config->sleep(fe, 0);
671
672 /* enable dataTX in case we have been restarted in the wrong moment */
673 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
674 return 0;
675}
676
677static int dib0090_sleep(struct dvb_frontend *fe)
678{
679 struct dib0090_state *state = fe->tuner_priv;
680 if (state->config->sleep)
681 state->config->sleep(fe, 1);
682 return 0;
683}
684
685void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
686{
687 struct dib0090_state *state = fe->tuner_priv;
688 if (fast)
689 dib0090_write_reg(state, 0x04, 0);
690 else
691 dib0090_write_reg(state, 0x04, 1);
692}
693
694EXPORT_SYMBOL(dib0090_dcc_freq);
695
696static const u16 bb_ramp_pwm_normal_socs[] = {
697 550, /* max BB gain in 10th of dB */
698 (1 << 9) | 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
699 440,
700 (4 << 9) | 0, /* BB_RAMP3 = 26dB */
701 (0 << 9) | 208, /* BB_RAMP4 */
702 (4 << 9) | 208, /* BB_RAMP5 = 29dB */
703 (0 << 9) | 440, /* BB_RAMP6 */
704};
705
706static const u16 rf_ramp_pwm_cband_7090[] = {
707 280, /* max RF gain in 10th of dB */
708 18, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
709 504, /* ramp_max = maximum X used on the ramp */
710 (29 << 10) | 364, /* RF_RAMP5, LNA 1 = 8dB */
711 (0 << 10) | 504, /* RF_RAMP6, LNA 1 */
712 (60 << 10) | 228, /* RF_RAMP7, LNA 2 = 7.7dB */
713 (0 << 10) | 364, /* RF_RAMP8, LNA 2 */
714 (34 << 10) | 109, /* GAIN_4_1, LNA 3 = 6.8dB */
715 (0 << 10) | 228, /* GAIN_4_2, LNA 3 */
716 (37 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */
717 (0 << 10) | 109, /* RF_RAMP4, LNA 4 */
718};
719
720static const u16 rf_ramp_pwm_cband_8090[] = {
721 345, /* max RF gain in 10th of dB */
722 29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
723 1000, /* ramp_max = maximum X used on the ramp */
724 (35 << 10) | 772, /* RF_RAMP3, LNA 1 = 8dB */
725 (0 << 10) | 1000, /* RF_RAMP4, LNA 1 */
726 (58 << 10) | 496, /* RF_RAMP5, LNA 2 = 9.5dB */
727 (0 << 10) | 772, /* RF_RAMP6, LNA 2 */
728 (27 << 10) | 200, /* RF_RAMP7, LNA 3 = 10.5dB */
729 (0 << 10) | 496, /* RF_RAMP8, LNA 3 */
730 (40 << 10) | 0, /* GAIN_4_1, LNA 4 = 7dB */
731 (0 << 10) | 200, /* GAIN_4_2, LNA 4 */
732};
733
734static const u16 rf_ramp_pwm_uhf_7090[] = {
735 407, /* max RF gain in 10th of dB */
736 13, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
737 529, /* ramp_max = maximum X used on the ramp */
738 (23 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
739 (0 << 10) | 176, /* RF_RAMP4, LNA 1 */
740 (63 << 10) | 400, /* RF_RAMP5, LNA 2 = 8dB */
741 (0 << 10) | 529, /* RF_RAMP6, LNA 2 */
742 (48 << 10) | 316, /* RF_RAMP7, LNA 3 = 6.8dB */
743 (0 << 10) | 400, /* RF_RAMP8, LNA 3 */
744 (29 << 10) | 176, /* GAIN_4_1, LNA 4 = 11.5dB */
745 (0 << 10) | 316, /* GAIN_4_2, LNA 4 */
746};
747
748static const u16 rf_ramp_pwm_uhf_8090[] = {
749 388, /* max RF gain in 10th of dB */
750 26, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
751 1008, /* ramp_max = maximum X used on the ramp */
752 (11 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
753 (0 << 10) | 369, /* RF_RAMP4, LNA 1 */
754 (41 << 10) | 809, /* RF_RAMP5, LNA 2 = 8dB */
755 (0 << 10) | 1008, /* RF_RAMP6, LNA 2 */
756 (27 << 10) | 659, /* RF_RAMP7, LNA 3 = 6dB */
757 (0 << 10) | 809, /* RF_RAMP8, LNA 3 */
758 (14 << 10) | 369, /* GAIN_4_1, LNA 4 = 11.5dB */
759 (0 << 10) | 659, /* GAIN_4_2, LNA 4 */
760};
761
762static const u16 rf_ramp_pwm_cband[] = {
763 0, /* max RF gain in 10th of dB */
764 0, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
765 0, /* ramp_max = maximum X used on the ramp */
766 (0 << 10) | 0, /* 0x2c, LNA 1 = 0dB */
767 (0 << 10) | 0, /* 0x2d, LNA 1 */
768 (0 << 10) | 0, /* 0x2e, LNA 2 = 0dB */
769 (0 << 10) | 0, /* 0x2f, LNA 2 */
770 (0 << 10) | 0, /* 0x30, LNA 3 = 0dB */
771 (0 << 10) | 0, /* 0x31, LNA 3 */
772 (0 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */
773 (0 << 10) | 0, /* GAIN_4_2, LNA 4 */
774};
775
776static const u16 rf_ramp_vhf[] = {
777 412, /* max RF gain in 10th of dB */
778 132, 307, 127, /* LNA1, 13.2dB */
779 105, 412, 255, /* LNA2, 10.5dB */
780 50, 50, 127, /* LNA3, 5dB */
781 125, 175, 127, /* LNA4, 12.5dB */
782 0, 0, 127, /* CBAND, 0dB */
783};
784
785static const u16 rf_ramp_uhf[] = {
786 412, /* max RF gain in 10th of dB */
787 132, 307, 127, /* LNA1 : total gain = 13.2dB, point on the ramp where this amp is full gain, value to write to get full gain */
788 105, 412, 255, /* LNA2 : 10.5 dB */
789 50, 50, 127, /* LNA3 : 5.0 dB */
790 125, 175, 127, /* LNA4 : 12.5 dB */
791 0, 0, 127, /* CBAND : 0.0 dB */
792};
793
794static const u16 rf_ramp_cband_broadmatching[] = /* for p1G only */
795{
796 314, /* Calibrated at 200MHz order has been changed g4-g3-g2-g1 */
797 84, 314, 127, /* LNA1 */
798 80, 230, 255, /* LNA2 */
799 80, 150, 127, /* LNA3 It was measured 12dB, do not lock if 120 */
800 70, 70, 127, /* LNA4 */
801 0, 0, 127, /* CBAND */
802};
803
804static const u16 rf_ramp_cband[] = {
805 332, /* max RF gain in 10th of dB */
806 132, 252, 127, /* LNA1, dB */
807 80, 332, 255, /* LNA2, dB */
808 0, 0, 127, /* LNA3, dB */
809 0, 0, 127, /* LNA4, dB */
810 120, 120, 127, /* LT1 CBAND */
811};
812
813static const u16 rf_ramp_pwm_vhf[] = {
814 404, /* max RF gain in 10th of dB */
815 25, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
816 1011, /* ramp_max = maximum X used on the ramp */
817 (6 << 10) | 417, /* 0x2c, LNA 1 = 13.2dB */
818 (0 << 10) | 756, /* 0x2d, LNA 1 */
819 (16 << 10) | 756, /* 0x2e, LNA 2 = 10.5dB */
820 (0 << 10) | 1011, /* 0x2f, LNA 2 */
821 (16 << 10) | 290, /* 0x30, LNA 3 = 5dB */
822 (0 << 10) | 417, /* 0x31, LNA 3 */
823 (7 << 10) | 0, /* GAIN_4_1, LNA 4 = 12.5dB */
824 (0 << 10) | 290, /* GAIN_4_2, LNA 4 */
825};
826
827static const u16 rf_ramp_pwm_uhf[] = {
828 404, /* max RF gain in 10th of dB */
829 25, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
830 1011, /* ramp_max = maximum X used on the ramp */
831 (6 << 10) | 417, /* 0x2c, LNA 1 = 13.2dB */
832 (0 << 10) | 756, /* 0x2d, LNA 1 */
833 (16 << 10) | 756, /* 0x2e, LNA 2 = 10.5dB */
834 (0 << 10) | 1011, /* 0x2f, LNA 2 */
835 (16 << 10) | 0, /* 0x30, LNA 3 = 5dB */
836 (0 << 10) | 127, /* 0x31, LNA 3 */
837 (7 << 10) | 127, /* GAIN_4_1, LNA 4 = 12.5dB */
838 (0 << 10) | 417, /* GAIN_4_2, LNA 4 */
839};
840
841static const u16 bb_ramp_boost[] = {
842 550, /* max BB gain in 10th of dB */
843 260, 260, 26, /* BB1, 26dB */
844 290, 550, 29, /* BB2, 29dB */
845};
846
847static const u16 bb_ramp_pwm_normal[] = {
848 500, /* max RF gain in 10th of dB */
849 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x34 */
850 400,
851 (2 << 9) | 0, /* 0x35 = 21dB */
852 (0 << 9) | 168, /* 0x36 */
853 (2 << 9) | 168, /* 0x37 = 29dB */
854 (0 << 9) | 400, /* 0x38 */
855};
856
857struct slope {
858 s16 range;
859 s16 slope;
860};
861static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
862{
863 u8 i;
864 u16 rest;
865 u16 ret = 0;
866 for (i = 0; i < num; i++) {
867 if (val > slopes[i].range)
868 rest = slopes[i].range;
869 else
870 rest = val;
871 ret += (rest * slopes[i].slope) / slopes[i].range;
872 val -= rest;
873 }
874 return ret;
875}
876
877static const struct slope dib0090_wbd_slopes[3] = {
878 {66, 120}, /* -64,-52: offset - 65 */
879 {600, 170}, /* -52,-35: 65 - 665 */
880 {170, 250}, /* -45,-10: 665 - 835 */
881};
882
883static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd)
884{
885 wbd &= 0x3ff;
886 if (wbd < state->wbd_offset)
887 wbd = 0;
888 else
889 wbd -= state->wbd_offset;
890 /* -64dB is the floor */
891 return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd);
892}
893
894static void dib0090_wbd_target(struct dib0090_state *state, u32 rf)
895{
896 u16 offset = 250;
897
898 /* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */
899
900 if (state->current_band == BAND_VHF)
901 offset = 650;
902#ifndef FIRMWARE_FIREFLY
903 if (state->current_band == BAND_VHF)
904 offset = state->config->wbd_vhf_offset;
905 if (state->current_band == BAND_CBAND)
906 offset = state->config->wbd_cband_offset;
907#endif
908
909 state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset);
910 dprintk("wbd-target: %d dB", (u32) state->wbd_target);
911}
912
913static const int gain_reg_addr[4] = {
914 0x08, 0x0a, 0x0f, 0x01
915};
916
917static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force)
918{
919 u16 rf, bb, ref;
920 u16 i, v, gain_reg[4] = { 0 }, gain;
921 const u16 *g;
922
923 if (top_delta < -511)
924 top_delta = -511;
925 if (top_delta > 511)
926 top_delta = 511;
927
928 if (force) {
929 top_delta *= (1 << WBD_ALPHA);
930 gain_delta *= (1 << GAIN_ALPHA);
931 }
932
933 if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit)) /* overflow */
934 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
935 else
936 state->rf_gain_limit += top_delta;
937
938 if (state->rf_gain_limit < 0) /*underflow */
939 state->rf_gain_limit = 0;
940
941 /* use gain as a temporary variable and correct current_gain */
942 gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA;
943 if (gain_delta >= ((s16) gain - state->current_gain)) /* overflow */
944 state->current_gain = gain;
945 else
946 state->current_gain += gain_delta;
947 /* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */
948 if (state->current_gain < 0)
949 state->current_gain = 0;
950
951 /* now split total gain to rf and bb gain */
952 gain = state->current_gain >> GAIN_ALPHA;
953
954 /* requested gain is bigger than rf gain limit - ACI/WBD adjustment */
955 if (gain > (state->rf_gain_limit >> WBD_ALPHA)) {
956 rf = state->rf_gain_limit >> WBD_ALPHA;
957 bb = gain - rf;
958 if (bb > state->bb_ramp[0])
959 bb = state->bb_ramp[0];
960 } else { /* high signal level -> all gains put on RF */
961 rf = gain;
962 bb = 0;
963 }
964
965 state->gain[0] = rf;
966 state->gain[1] = bb;
967
968 /* software ramp */
969 /* Start with RF gains */
970 g = state->rf_ramp + 1; /* point on RF LNA1 max gain */
971 ref = rf;
972 for (i = 0; i < 7; i++) { /* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */
973 if (g[0] == 0 || ref < (g[1] - g[0])) /* if total gain of the current amp is null or this amp is not concerned because it starts to work from an higher gain value */
974 v = 0; /* force the gain to write for the current amp to be null */
975 else if (ref >= g[1]) /* Gain to set is higher than the high working point of this amp */
976 v = g[2]; /* force this amp to be full gain */
977 else /* compute the value to set to this amp because we are somewhere in his range */
978 v = ((ref - (g[1] - g[0])) * g[2]) / g[0];
979
980 if (i == 0) /* LNA 1 reg mapping */
981 gain_reg[0] = v;
982 else if (i == 1) /* LNA 2 reg mapping */
983 gain_reg[0] |= v << 7;
984 else if (i == 2) /* LNA 3 reg mapping */
985 gain_reg[1] = v;
986 else if (i == 3) /* LNA 4 reg mapping */
987 gain_reg[1] |= v << 7;
988 else if (i == 4) /* CBAND LNA reg mapping */
989 gain_reg[2] = v | state->rf_lt_def;
990 else if (i == 5) /* BB gain 1 reg mapping */
991 gain_reg[3] = v << 3;
992 else if (i == 6) /* BB gain 2 reg mapping */
993 gain_reg[3] |= v << 8;
994
995 g += 3; /* go to next gain bloc */
996
997 /* When RF is finished, start with BB */
998 if (i == 4) {
999 g = state->bb_ramp + 1; /* point on BB gain 1 max gain */
1000 ref = bb;
1001 }
1002 }
1003 gain_reg[3] |= state->bb_1_def;
1004 gain_reg[3] |= ((bb % 10) * 100) / 125;
1005
1006#ifdef DEBUG_AGC
1007 dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x", rf, bb, rf + bb,
1008 gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]);
1009#endif
1010
1011 /* Write the amplifier regs */
1012 for (i = 0; i < 4; i++) {
1013 v = gain_reg[i];
1014 if (force || state->gain_reg[i] != v) {
1015 state->gain_reg[i] = v;
1016 dib0090_write_reg(state, gain_reg_addr[i], v);
1017 }
1018 }
1019}
1020
1021static void dib0090_set_boost(struct dib0090_state *state, int onoff)
1022{
1023 state->bb_1_def &= 0xdfff;
1024 state->bb_1_def |= onoff << 13;
1025}
1026
1027static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg)
1028{
1029 state->rf_ramp = cfg;
1030}
1031
1032static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg)
1033{
1034 state->rf_ramp = cfg;
1035
1036 dib0090_write_reg(state, 0x2a, 0xffff);
1037
1038 dprintk("total RF gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x2a));
1039
1040 dib0090_write_regs(state, 0x2c, cfg + 3, 6);
1041 dib0090_write_regs(state, 0x3e, cfg + 9, 2);
1042}
1043
1044static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg)
1045{
1046 state->bb_ramp = cfg;
1047 dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
1048}
1049
1050static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
1051{
1052 state->bb_ramp = cfg;
1053
1054 dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
1055
1056 dib0090_write_reg(state, 0x33, 0xffff);
1057 dprintk("total BB gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x33));
1058 dib0090_write_regs(state, 0x35, cfg + 3, 4);
1059}
1060
1061void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
1062{
1063 struct dib0090_state *state = fe->tuner_priv;
1064 /* reset the AGC */
1065
1066 if (state->config->use_pwm_agc) {
1067#ifdef CONFIG_BAND_SBAND
1068 if (state->current_band == BAND_SBAND) {
1069 dib0090_set_rframp_pwm(state, rf_ramp_pwm_sband);
1070 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_boost);
1071 } else
1072#endif
1073#ifdef CONFIG_BAND_CBAND
1074 if (state->current_band == BAND_CBAND) {
1075 if (state->identity.in_soc) {
1076 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
1077 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1078 dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_8090);
1079 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1080 dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090);
1081 } else {
1082 dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband);
1083 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1084 }
1085 } else
1086#endif
1087#ifdef CONFIG_BAND_VHF
1088 if (state->current_band == BAND_VHF) {
1089 if (state->identity.in_soc) {
1090 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
1091 } else {
1092 dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf);
1093 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1094 }
1095 } else
1096#endif
1097 {
1098 if (state->identity.in_soc) {
1099 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1100 dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_8090);
1101 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1102 dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_7090);
1103 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
1104 } else {
1105 dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf);
1106 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1107 }
1108 }
1109
1110 if (state->rf_ramp[0] != 0)
1111 dib0090_write_reg(state, 0x32, (3 << 11));
1112 else
1113 dib0090_write_reg(state, 0x32, (0 << 11));
1114
1115 dib0090_write_reg(state, 0x04, 0x01);
1116 dib0090_write_reg(state, 0x39, (1 << 10));
1117 }
1118}
1119
1120EXPORT_SYMBOL(dib0090_pwm_gain_reset);
1121
1122static u32 dib0090_get_slow_adc_val(struct dib0090_state *state)
1123{
1124 u16 adc_val = dib0090_read_reg(state, 0x1d);
1125 if (state->identity.in_soc)
1126 adc_val >>= 2;
1127 return adc_val;
1128}
1129
1130int dib0090_gain_control(struct dvb_frontend *fe)
1131{
1132 struct dib0090_state *state = fe->tuner_priv;
1133 enum frontend_tune_state *tune_state = &state->tune_state;
1134 int ret = 10;
1135
1136 u16 wbd_val = 0;
1137 u8 apply_gain_immediatly = 1;
1138 s16 wbd_error = 0, adc_error = 0;
1139
1140 if (*tune_state == CT_AGC_START) {
1141 state->agc_freeze = 0;
1142 dib0090_write_reg(state, 0x04, 0x0);
1143
1144#ifdef CONFIG_BAND_SBAND
1145 if (state->current_band == BAND_SBAND) {
1146 dib0090_set_rframp(state, rf_ramp_sband);
1147 dib0090_set_bbramp(state, bb_ramp_boost);
1148 } else
1149#endif
1150#ifdef CONFIG_BAND_VHF
1151 if (state->current_band == BAND_VHF && !state->identity.p1g) {
1152 dib0090_set_rframp(state, rf_ramp_vhf);
1153 dib0090_set_bbramp(state, bb_ramp_boost);
1154 } else
1155#endif
1156#ifdef CONFIG_BAND_CBAND
1157 if (state->current_band == BAND_CBAND && !state->identity.p1g) {
1158 dib0090_set_rframp(state, rf_ramp_cband);
1159 dib0090_set_bbramp(state, bb_ramp_boost);
1160 } else
1161#endif
1162 if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
1163 dib0090_set_rframp(state, rf_ramp_cband_broadmatching);
1164 dib0090_set_bbramp(state, bb_ramp_boost);
1165 } else {
1166 dib0090_set_rframp(state, rf_ramp_uhf);
1167 dib0090_set_bbramp(state, bb_ramp_boost);
1168 }
1169
1170 dib0090_write_reg(state, 0x32, 0);
1171 dib0090_write_reg(state, 0x39, 0);
1172
1173 dib0090_wbd_target(state, state->current_rf);
1174
1175 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
1176 state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA;
1177
1178 *tune_state = CT_AGC_STEP_0;
1179 } else if (!state->agc_freeze) {
1180 s16 wbd = 0, i, cnt;
1181
1182 int adc;
1183 wbd_val = dib0090_get_slow_adc_val(state);
1184
1185 if (*tune_state == CT_AGC_STEP_0)
1186 cnt = 5;
1187 else
1188 cnt = 1;
1189
1190 for (i = 0; i < cnt; i++) {
1191 wbd_val = dib0090_get_slow_adc_val(state);
1192 wbd += dib0090_wbd_to_db(state, wbd_val);
1193 }
1194 wbd /= cnt;
1195 wbd_error = state->wbd_target - wbd;
1196
1197 if (*tune_state == CT_AGC_STEP_0) {
1198 if (wbd_error < 0 && state->rf_gain_limit > 0 && !state->identity.p1g) {
1199#ifdef CONFIG_BAND_CBAND
1200 /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */
1201 u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
1202 if (state->current_band == BAND_CBAND && ltg2) {
1203 ltg2 >>= 1;
1204 state->rf_lt_def &= ltg2 << 10; /* reduce in 3 steps from 7 to 0 */
1205 }
1206#endif
1207 } else {
1208 state->agc_step = 0;
1209 *tune_state = CT_AGC_STEP_1;
1210 }
1211 } else {
1212 /* calc the adc power */
1213 adc = state->config->get_adc_power(fe);
1214 adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21; /* included in [0:-700] */
1215
1216 adc_error = (s16) (((s32) ADC_TARGET) - adc);
1217#ifdef CONFIG_STANDARD_DAB
1218 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
1219 adc_error -= 10;
1220#endif
1221#ifdef CONFIG_STANDARD_DVBT
1222 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
1223 (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
1224 adc_error += 60;
1225#endif
1226#ifdef CONFIG_SYS_ISDBT
1227 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
1228 0)
1229 &&
1230 ((state->fe->dtv_property_cache.layer[0].modulation ==
1231 QAM_64)
1232 || (state->fe->dtv_property_cache.
1233 layer[0].modulation == QAM_16)))
1234 ||
1235 ((state->fe->dtv_property_cache.layer[1].segment_count >
1236 0)
1237 &&
1238 ((state->fe->dtv_property_cache.layer[1].modulation ==
1239 QAM_64)
1240 || (state->fe->dtv_property_cache.
1241 layer[1].modulation == QAM_16)))
1242 ||
1243 ((state->fe->dtv_property_cache.layer[2].segment_count >
1244 0)
1245 &&
1246 ((state->fe->dtv_property_cache.layer[2].modulation ==
1247 QAM_64)
1248 || (state->fe->dtv_property_cache.
1249 layer[2].modulation == QAM_16)))
1250 )
1251 )
1252 adc_error += 60;
1253#endif
1254
1255 if (*tune_state == CT_AGC_STEP_1) { /* quickly go to the correct range of the ADC power */
1256 if (ABS(adc_error) < 50 || state->agc_step++ > 5) {
1257
1258#ifdef CONFIG_STANDARD_DAB
1259 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) {
1260 dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63)); /* cap value = 63 : narrow BB filter : Fc = 1.8MHz */
1261 dib0090_write_reg(state, 0x04, 0x0);
1262 } else
1263#endif
1264 {
1265 dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32));
1266 dib0090_write_reg(state, 0x04, 0x01); /*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */
1267 }
1268
1269 *tune_state = CT_AGC_STOP;
1270 }
1271 } else {
1272 /* everything higher than or equal to CT_AGC_STOP means tracking */
1273 ret = 100; /* 10ms interval */
1274 apply_gain_immediatly = 0;
1275 }
1276 }
1277#ifdef DEBUG_AGC
1278 dprintk
1279 ("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
1280 (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
1281 (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
1282#endif
1283 }
1284
1285 /* apply gain */
1286 if (!state->agc_freeze)
1287 dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
1288 return ret;
1289}
1290
1291EXPORT_SYMBOL(dib0090_gain_control);
1292
1293void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
1294{
1295 struct dib0090_state *state = fe->tuner_priv;
1296 if (rf)
1297 *rf = state->gain[0];
1298 if (bb)
1299 *bb = state->gain[1];
1300 if (rf_gain_limit)
1301 *rf_gain_limit = state->rf_gain_limit;
1302 if (rflt)
1303 *rflt = (state->rf_lt_def >> 10) & 0x7;
1304}
1305
1306EXPORT_SYMBOL(dib0090_get_current_gain);
1307
1308u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
1309{
1310 struct dib0090_state *state = fe->tuner_priv;
1311 u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000;
1312 s32 current_temp = state->temperature;
1313 s32 wbd_thot, wbd_tcold;
1314 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1315
1316 while (f_MHz > wbd->max_freq)
1317 wbd++;
1318
1319 dprintk("using wbd-table-entry with max freq %d", wbd->max_freq);
1320
1321 if (current_temp < 0)
1322 current_temp = 0;
1323 if (current_temp > 128)
1324 current_temp = 128;
1325
1326 state->wbdmux &= ~(7 << 13);
1327 if (wbd->wbd_gain != 0)
1328 state->wbdmux |= (wbd->wbd_gain << 13);
1329 else
1330 state->wbdmux |= (4 << 13);
1331
1332 dib0090_write_reg(state, 0x10, state->wbdmux);
1333
1334 wbd_thot = wbd->offset_hot - (((u32) wbd->slope_hot * f_MHz) >> 6);
1335 wbd_tcold = wbd->offset_cold - (((u32) wbd->slope_cold * f_MHz) >> 6);
1336
1337 wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7;
1338
1339 state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold);
1340 dprintk("wbd-target: %d dB", (u32) state->wbd_target);
1341 dprintk("wbd offset applied is %d", wbd_tcold);
1342
1343 return state->wbd_offset + wbd_tcold;
1344}
1345
1346EXPORT_SYMBOL(dib0090_get_wbd_offset);
1347
1348static const u16 dib0090_defaults[] = {
1349
1350 25, 0x01,
1351 0x0000,
1352 0x99a0,
1353 0x6008,
1354 0x0000,
1355 0x8bcb,
1356 0x0000,
1357 0x0405,
1358 0x0000,
1359 0x0000,
1360 0x0000,
1361 0xb802,
1362 0x0300,
1363 0x2d12,
1364 0xbac0,
1365 0x7c00,
1366 0xdbb9,
1367 0x0954,
1368 0x0743,
1369 0x8000,
1370 0x0001,
1371 0x0040,
1372 0x0100,
1373 0x0000,
1374 0xe910,
1375 0x149e,
1376
1377 1, 0x1c,
1378 0xff2d,
1379
1380 1, 0x39,
1381 0x0000,
1382
1383 2, 0x1e,
1384 0x07FF,
1385 0x0007,
1386
1387 1, 0x24,
1388 EN_UHF | EN_CRYSTAL,
1389
1390 2, 0x3c,
1391 0x3ff,
1392 0x111,
1393 0
1394};
1395
1396static const u16 dib0090_p1g_additionnal_defaults[] = {
1397 1, 0x05,
1398 0xabcd,
1399
1400 1, 0x11,
1401 0x00b4,
1402
1403 1, 0x1c,
1404 0xfffd,
1405
1406 1, 0x40,
1407 0x108,
1408 0
1409};
1410
1411static void dib0090_set_default_config(struct dib0090_state *state, const u16 * n)
1412{
1413 u16 l, r;
1414
1415 l = pgm_read_word(n++);
1416 while (l) {
1417 r = pgm_read_word(n++);
1418 do {
1419 dib0090_write_reg(state, r, pgm_read_word(n++));
1420 r++;
1421 } while (--l);
1422 l = pgm_read_word(n++);
1423 }
1424}
1425
1426#define CAP_VALUE_MIN (u8) 9
1427#define CAP_VALUE_MAX (u8) 40
1428#define HR_MIN (u8) 25
1429#define HR_MAX (u8) 40
1430#define POLY_MIN (u8) 0
1431#define POLY_MAX (u8) 8
1432
1433void dib0090_set_EFUSE(struct dib0090_state *state)
1434{
1435 u8 c, h, n;
1436 u16 e2, e4;
1437 u16 cal;
1438
1439 e2 = dib0090_read_reg(state, 0x26);
1440 e4 = dib0090_read_reg(state, 0x28);
1441
1442 if ((state->identity.version == P1D_E_F) ||
1443 (state->identity.version == P1G) || (e2 == 0xffff)) {
1444
1445 dib0090_write_reg(state, 0x22, 0x10);
1446 cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff;
1447
1448 if ((cal < 670) || (cal == 1023))
1449 cal = 850;
1450 n = 165 - ((cal * 10)>>6) ;
1451 e2 = e4 = (3<<12) | (34<<6) | (n);
1452 }
1453
1454 if (e2 != e4)
1455 e2 &= e4; /* Remove the redundancy */
1456
1457 if (e2 != 0xffff) {
1458 c = e2 & 0x3f;
1459 n = (e2 >> 12) & 0xf;
1460 h = (e2 >> 6) & 0x3f;
1461
1462 if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN))
1463 c = 32;
1464 if ((h >= HR_MAX) || (h <= HR_MIN))
1465 h = 34;
1466 if ((n >= POLY_MAX) || (n <= POLY_MIN))
1467 n = 3;
1468
1469 dib0090_write_reg(state, 0x13, (h << 10)) ;
1470 e2 = (n<<11) | ((h>>2)<<6) | (c);
1471 dib0090_write_reg(state, 0x2, e2) ; /* Load the BB_2 */
1472 }
1473}
1474
1475static int dib0090_reset(struct dvb_frontend *fe)
1476{
1477 struct dib0090_state *state = fe->tuner_priv;
1478
1479 dib0090_reset_digital(fe, state->config);
1480 if (dib0090_identify(fe) < 0)
1481 return -EIO;
1482
1483#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
1484 if (!(state->identity.version & 0x1)) /* it is P1B - reset is already done */
1485 return 0;
1486#endif
1487
1488 if (!state->identity.in_soc) {
1489 if ((dib0090_read_reg(state, 0x1a) >> 5) & 0x2)
1490 dib0090_write_reg(state, 0x1b, (EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1491 else
1492 dib0090_write_reg(state, 0x1b, (EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1493 }
1494
1495 dib0090_set_default_config(state, dib0090_defaults);
1496
1497 if (state->identity.in_soc)
1498 dib0090_write_reg(state, 0x18, 0x2910); /* charge pump current = 0 */
1499
1500 if (state->identity.p1g)
1501 dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults);
1502
1503 /* Update the efuse : Only available for KROSUS > P1C and SOC as well*/
1504 if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc))
1505 dib0090_set_EFUSE(state);
1506
1507 /* Congigure in function of the crystal */
1508 if (state->config->io.clock_khz >= 24000)
1509 dib0090_write_reg(state, 0x14, 1);
1510 else
1511 dib0090_write_reg(state, 0x14, 2);
1512 dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
1513
1514 state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL; /* enable iq-offset-calibration and wbd-calibration when tuning next time */
1515
1516 return 0;
1517}
1518
1519#define steps(u) (((u) > 15) ? ((u)-16) : (u))
1520#define INTERN_WAIT 10
1521static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1522{
1523 int ret = INTERN_WAIT * 10;
1524
1525 switch (*tune_state) {
1526 case CT_TUNER_STEP_2:
1527 /* Turns to positive */
1528 dib0090_write_reg(state, 0x1f, 0x7);
1529 *tune_state = CT_TUNER_STEP_3;
1530 break;
1531
1532 case CT_TUNER_STEP_3:
1533 state->adc_diff = dib0090_read_reg(state, 0x1d);
1534
1535 /* Turns to negative */
1536 dib0090_write_reg(state, 0x1f, 0x4);
1537 *tune_state = CT_TUNER_STEP_4;
1538 break;
1539
1540 case CT_TUNER_STEP_4:
1541 state->adc_diff -= dib0090_read_reg(state, 0x1d);
1542 *tune_state = CT_TUNER_STEP_5;
1543 ret = 0;
1544 break;
1545
1546 default:
1547 break;
1548 }
1549
1550 return ret;
1551}
1552
1553struct dc_calibration {
1554 u8 addr;
1555 u8 offset;
1556 u8 pga:1;
1557 u16 bb1;
1558 u8 i:1;
1559};
1560
1561static const struct dc_calibration dc_table[] = {
1562 /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
1563 {0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1},
1564 {0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0},
1565 /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
1566 {0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1},
1567 {0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0},
1568 {0},
1569};
1570
1571static const struct dc_calibration dc_p1g_table[] = {
1572 /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
1573 /* addr ; trim reg offset ; pga ; CTRL_BB1 value ; i or q */
1574 {0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1},
1575 {0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0},
1576 /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
1577 {0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1},
1578 {0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0},
1579 {0},
1580};
1581
1582static void dib0090_set_trim(struct dib0090_state *state)
1583{
1584 u16 *val;
1585
1586 if (state->dc->addr == 0x07)
1587 val = &state->bb7;
1588 else
1589 val = &state->bb6;
1590
1591 *val &= ~(0x1f << state->dc->offset);
1592 *val |= state->step << state->dc->offset;
1593
1594 dib0090_write_reg(state, state->dc->addr, *val);
1595}
1596
1597static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1598{
1599 int ret = 0;
1600 u16 reg;
1601
1602 switch (*tune_state) {
1603 case CT_TUNER_START:
1604 dprintk("Start DC offset calibration");
1605
1606 /* force vcm2 = 0.8V */
1607 state->bb6 = 0;
1608 state->bb7 = 0x040d;
1609
1610 /* the LNA AND LO are off */
1611 reg = dib0090_read_reg(state, 0x24) & 0x0ffb; /* shutdown lna and lo */
1612 dib0090_write_reg(state, 0x24, reg);
1613
1614 state->wbdmux = dib0090_read_reg(state, 0x10);
1615 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3);
1616 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
1617
1618 state->dc = dc_table;
1619
1620 if (state->identity.p1g)
1621 state->dc = dc_p1g_table;
1622 *tune_state = CT_TUNER_STEP_0;
1623
1624 /* fall through */
1625
1626 case CT_TUNER_STEP_0:
1627 dprintk("Sart/continue DC calibration for %s path", (state->dc->i == 1) ? "I" : "Q");
1628 dib0090_write_reg(state, 0x01, state->dc->bb1);
1629 dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
1630
1631 state->step = 0;
1632 state->min_adc_diff = 1023;
1633 *tune_state = CT_TUNER_STEP_1;
1634 ret = 50;
1635 break;
1636
1637 case CT_TUNER_STEP_1:
1638 dib0090_set_trim(state);
1639 *tune_state = CT_TUNER_STEP_2;
1640 break;
1641
1642 case CT_TUNER_STEP_2:
1643 case CT_TUNER_STEP_3:
1644 case CT_TUNER_STEP_4:
1645 ret = dib0090_get_offset(state, tune_state);
1646 break;
1647
1648 case CT_TUNER_STEP_5: /* found an offset */
1649 dprintk("adc_diff = %d, current step= %d", (u32) state->adc_diff, state->step);
1650 if (state->step == 0 && state->adc_diff < 0) {
1651 state->min_adc_diff = -1023;
1652 dprintk("Change of sign of the minimum adc diff");
1653 }
1654
1655 dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d", state->adc_diff, state->min_adc_diff, state->step);
1656
1657 /* first turn for this frequency */
1658 if (state->step == 0) {
1659 if (state->dc->pga && state->adc_diff < 0)
1660 state->step = 0x10;
1661 if (state->dc->pga == 0 && state->adc_diff > 0)
1662 state->step = 0x10;
1663 }
1664
1665 /* Look for a change of Sign in the Adc_diff.min_adc_diff is used to STORE the setp N-1 */
1666 if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) {
1667 /* stop search when the delta the sign is changing and Steps =15 and Step=0 is force for continuance */
1668 state->step++;
1669 state->min_adc_diff = state->adc_diff;
1670 *tune_state = CT_TUNER_STEP_1;
1671 } else {
1672 /* the minimum was what we have seen in the step before */
1673 if (ABS(state->adc_diff) > ABS(state->min_adc_diff)) {
1674 dprintk("Since adc_diff N = %d > adc_diff step N-1 = %d, Come back one step", state->adc_diff, state->min_adc_diff);
1675 state->step--;
1676 }
1677
1678 dib0090_set_trim(state);
1679 dprintk("BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->dc->addr, state->adc_diff, state->step);
1680
1681 state->dc++;
1682 if (state->dc->addr == 0) /* done */
1683 *tune_state = CT_TUNER_STEP_6;
1684 else
1685 *tune_state = CT_TUNER_STEP_0;
1686
1687 }
1688 break;
1689
1690 case CT_TUNER_STEP_6:
1691 dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
1692 dib0090_write_reg(state, 0x1f, 0x7);
1693 *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */
1694 state->calibrate &= ~DC_CAL;
1695 default:
1696 break;
1697 }
1698 return ret;
1699}
1700
1701static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1702{
1703 u8 wbd_gain;
1704 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1705
1706 switch (*tune_state) {
1707 case CT_TUNER_START:
1708 while (state->current_rf / 1000 > wbd->max_freq)
1709 wbd++;
1710 if (wbd->wbd_gain != 0)
1711 wbd_gain = wbd->wbd_gain;
1712 else {
1713 wbd_gain = 4;
1714#if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
1715 if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
1716 wbd_gain = 2;
1717#endif
1718 }
1719
1720 if (wbd_gain == state->wbd_calibration_gain) { /* the WBD calibration has already been done */
1721 *tune_state = CT_TUNER_START;
1722 state->calibrate &= ~WBD_CAL;
1723 return 0;
1724 }
1725
1726 dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
1727
1728 dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
1729 *tune_state = CT_TUNER_STEP_0;
1730 state->wbd_calibration_gain = wbd_gain;
1731 return 90; /* wait for the WBDMUX to switch and for the ADC to sample */
1732
1733 case CT_TUNER_STEP_0:
1734 state->wbd_offset = dib0090_get_slow_adc_val(state);
1735 dprintk("WBD calibration offset = %d", state->wbd_offset);
1736 *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */
1737 state->calibrate &= ~WBD_CAL;
1738 break;
1739
1740 default:
1741 break;
1742 }
1743 return 0;
1744}
1745
1746static void dib0090_set_bandwidth(struct dib0090_state *state)
1747{
1748 u16 tmp;
1749
1750 if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
1751 tmp = (3 << 14);
1752 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
1753 tmp = (2 << 14);
1754 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
1755 tmp = (1 << 14);
1756 else
1757 tmp = (0 << 14);
1758
1759 state->bb_1_def &= 0x3fff;
1760 state->bb_1_def |= tmp;
1761
1762 dib0090_write_reg(state, 0x01, state->bb_1_def); /* be sure that we have the right bb-filter */
1763
1764 dib0090_write_reg(state, 0x03, 0x6008); /* = 0x6008 : vcm3_trim = 1 ; filter2_gm1_trim = 8 ; filter2_cutoff_freq = 0 */
1765 dib0090_write_reg(state, 0x04, 0x1); /* 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast */
1766 if (state->identity.in_soc) {
1767 dib0090_write_reg(state, 0x05, 0x9bcf); /* attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 1 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 15 */
1768 } else {
1769 dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f)); /* 22 = cap_value */
1770 dib0090_write_reg(state, 0x05, 0xabcd); /* = 0xabcd : attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 2 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 13 */
1771 }
1772}
1773
1774static const struct dib0090_pll dib0090_pll_table[] = {
1775#ifdef CONFIG_BAND_CBAND
1776 {56000, 0, 9, 48, 6},
1777 {70000, 1, 9, 48, 6},
1778 {87000, 0, 8, 32, 4},
1779 {105000, 1, 8, 32, 4},
1780 {115000, 0, 7, 24, 6},
1781 {140000, 1, 7, 24, 6},
1782 {170000, 0, 6, 16, 4},
1783#endif
1784#ifdef CONFIG_BAND_VHF
1785 {200000, 1, 6, 16, 4},
1786 {230000, 0, 5, 12, 6},
1787 {280000, 1, 5, 12, 6},
1788 {340000, 0, 4, 8, 4},
1789 {380000, 1, 4, 8, 4},
1790 {450000, 0, 3, 6, 6},
1791#endif
1792#ifdef CONFIG_BAND_UHF
1793 {580000, 1, 3, 6, 6},
1794 {700000, 0, 2, 4, 4},
1795 {860000, 1, 2, 4, 4},
1796#endif
1797#ifdef CONFIG_BAND_LBAND
1798 {1800000, 1, 0, 2, 4},
1799#endif
1800#ifdef CONFIG_BAND_SBAND
1801 {2900000, 0, 14, 1, 4},
1802#endif
1803};
1804
1805static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
1806
1807#ifdef CONFIG_BAND_CBAND
1808 {184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1809 {227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1810 {380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1811#endif
1812#ifdef CONFIG_BAND_UHF
1813 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1814 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1815 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1816 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1817 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1818 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1819#endif
1820#ifdef CONFIG_BAND_LBAND
1821 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1822 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1823 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1824#endif
1825#ifdef CONFIG_BAND_SBAND
1826 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1827 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1828#endif
1829};
1830
1831static const struct dib0090_tuning dib0090_tuning_table[] = {
1832
1833#ifdef CONFIG_BAND_CBAND
1834 {170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1835#endif
1836#ifdef CONFIG_BAND_VHF
1837 {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1838 {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1839 {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1840#endif
1841#ifdef CONFIG_BAND_UHF
1842 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1843 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1844 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1845 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1846 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1847 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1848#endif
1849#ifdef CONFIG_BAND_LBAND
1850 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1851 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1852 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1853#endif
1854#ifdef CONFIG_BAND_SBAND
1855 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1856 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1857#endif
1858};
1859
1860static const struct dib0090_tuning dib0090_p1g_tuning_table[] = {
1861#ifdef CONFIG_BAND_CBAND
1862 {170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB},
1863#endif
1864#ifdef CONFIG_BAND_VHF
1865 {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1866 {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1867 {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1868#endif
1869#ifdef CONFIG_BAND_UHF
1870 {510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1871 {540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1872 {600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1873 {630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1874 {680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1875 {720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1876 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1877#endif
1878#ifdef CONFIG_BAND_LBAND
1879 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1880 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1881 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1882#endif
1883#ifdef CONFIG_BAND_SBAND
1884 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1885 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1886#endif
1887};
1888
1889static const struct dib0090_pll dib0090_p1g_pll_table[] = {
1890#ifdef CONFIG_BAND_CBAND
1891 {57000, 0, 11, 48, 6},
1892 {70000, 1, 11, 48, 6},
1893 {86000, 0, 10, 32, 4},
1894 {105000, 1, 10, 32, 4},
1895 {115000, 0, 9, 24, 6},
1896 {140000, 1, 9, 24, 6},
1897 {170000, 0, 8, 16, 4},
1898#endif
1899#ifdef CONFIG_BAND_VHF
1900 {200000, 1, 8, 16, 4},
1901 {230000, 0, 7, 12, 6},
1902 {280000, 1, 7, 12, 6},
1903 {340000, 0, 6, 8, 4},
1904 {380000, 1, 6, 8, 4},
1905 {455000, 0, 5, 6, 6},
1906#endif
1907#ifdef CONFIG_BAND_UHF
1908 {580000, 1, 5, 6, 6},
1909 {680000, 0, 4, 4, 4},
1910 {860000, 1, 4, 4, 4},
1911#endif
1912#ifdef CONFIG_BAND_LBAND
1913 {1800000, 1, 2, 2, 4},
1914#endif
1915#ifdef CONFIG_BAND_SBAND
1916 {2900000, 0, 1, 1, 6},
1917#endif
1918};
1919
1920static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = {
1921#ifdef CONFIG_BAND_CBAND
1922 {184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1923 {227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1924 {380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1925#endif
1926#ifdef CONFIG_BAND_UHF
1927 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1928 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1929 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1930 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1931 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1932 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1933#endif
1934#ifdef CONFIG_BAND_LBAND
1935 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1936 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1937 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1938#endif
1939#ifdef CONFIG_BAND_SBAND
1940 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1941 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1942#endif
1943};
1944
1945static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = {
1946#ifdef CONFIG_BAND_CBAND
1947 {300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
1948 {380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
1949 {570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
1950 {858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
1951#endif
1952};
1953
1954static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1955{
1956 int ret = 0;
1957 u16 lo4 = 0xe900;
1958
1959 s16 adc_target;
1960 u16 adc;
1961 s8 step_sign;
1962 u8 force_soft_search = 0;
1963
1964 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1965 force_soft_search = 1;
1966
1967 if (*tune_state == CT_TUNER_START) {
1968 dprintk("Start Captrim search : %s", (force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO");
1969 dib0090_write_reg(state, 0x10, 0x2B1);
1970 dib0090_write_reg(state, 0x1e, 0x0032);
1971
1972 if (!state->tuner_is_tuned) {
1973 /* prepare a complete captrim */
1974 if (!state->identity.p1g || force_soft_search)
1975 state->step = state->captrim = state->fcaptrim = 64;
1976
1977 state->current_rf = state->rf_request;
1978 } else { /* we are already tuned to this frequency - the configuration is correct */
1979 if (!state->identity.p1g || force_soft_search) {
1980 /* do a minimal captrim even if the frequency has not changed */
1981 state->step = 4;
1982 state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
1983 }
1984 }
1985 state->adc_diff = 3000;
1986 *tune_state = CT_TUNER_STEP_0;
1987
1988 } else if (*tune_state == CT_TUNER_STEP_0) {
1989 if (state->identity.p1g && !force_soft_search) {
1990 u8 ratio = 31;
1991
1992 dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1);
1993 dib0090_read_reg(state, 0x40);
1994 ret = 50;
1995 } else {
1996 state->step /= 2;
1997 dib0090_write_reg(state, 0x18, lo4 | state->captrim);
1998
1999 if (state->identity.in_soc)
2000 ret = 25;
2001 }
2002 *tune_state = CT_TUNER_STEP_1;
2003
2004 } else if (*tune_state == CT_TUNER_STEP_1) {
2005 if (state->identity.p1g && !force_soft_search) {
2006 dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0);
2007 dib0090_read_reg(state, 0x40);
2008
2009 state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F;
2010 dprintk("***Final Captrim= 0x%x", state->fcaptrim);
2011 *tune_state = CT_TUNER_STEP_3;
2012
2013 } else {
2014 /* MERGE for all krosus before P1G */
2015 adc = dib0090_get_slow_adc_val(state);
2016 dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024);
2017
2018 if (state->rest == 0 || state->identity.in_soc) { /* Just for 8090P SOCS where auto captrim HW bug : TO CHECK IN ACI for SOCS !!! if 400 for 8090p SOC => tune issue !!! */
2019 adc_target = 200;
2020 } else
2021 adc_target = 400;
2022
2023 if (adc >= adc_target) {
2024 adc -= adc_target;
2025 step_sign = -1;
2026 } else {
2027 adc = adc_target - adc;
2028 step_sign = 1;
2029 }
2030
2031 if (adc < state->adc_diff) {
2032 dprintk("CAPTRIM=%d is closer to target (%d/%d)", (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
2033 state->adc_diff = adc;
2034 state->fcaptrim = state->captrim;
2035 }
2036
2037 state->captrim += step_sign * state->step;
2038 if (state->step >= 1)
2039 *tune_state = CT_TUNER_STEP_0;
2040 else
2041 *tune_state = CT_TUNER_STEP_2;
2042
2043 ret = 25;
2044 }
2045 } else if (*tune_state == CT_TUNER_STEP_2) { /* this step is only used by krosus < P1G */
2046 /*write the final cptrim config */
2047 dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
2048
2049 *tune_state = CT_TUNER_STEP_3;
2050
2051 } else if (*tune_state == CT_TUNER_STEP_3) {
2052 state->calibrate &= ~CAPTRIM_CAL;
2053 *tune_state = CT_TUNER_STEP_0;
2054 }
2055
2056 return ret;
2057}
2058
2059static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2060{
2061 int ret = 15;
2062 s16 val;
2063
2064 switch (*tune_state) {
2065 case CT_TUNER_START:
2066 state->wbdmux = dib0090_read_reg(state, 0x10);
2067 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3));
2068
2069 state->bias = dib0090_read_reg(state, 0x13);
2070 dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8));
2071
2072 *tune_state = CT_TUNER_STEP_0;
2073 /* wait for the WBDMUX to switch and for the ADC to sample */
2074 break;
2075
2076 case CT_TUNER_STEP_0:
2077 state->adc_diff = dib0090_get_slow_adc_val(state);
2078 dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8));
2079 *tune_state = CT_TUNER_STEP_1;
2080 break;
2081
2082 case CT_TUNER_STEP_1:
2083 val = dib0090_get_slow_adc_val(state);
2084 state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55;
2085
2086 dprintk("temperature: %d C", state->temperature - 30);
2087
2088 *tune_state = CT_TUNER_STEP_2;
2089 break;
2090
2091 case CT_TUNER_STEP_2:
2092 dib0090_write_reg(state, 0x13, state->bias);
2093 dib0090_write_reg(state, 0x10, state->wbdmux); /* write back original WBDMUX */
2094
2095 *tune_state = CT_TUNER_START;
2096 state->calibrate &= ~TEMP_CAL;
2097 if (state->config->analog_output == 0)
2098 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2099
2100 break;
2101
2102 default:
2103 ret = 0;
2104 break;
2105 }
2106 return ret;
2107}
2108
2109#define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */
2110static int dib0090_tune(struct dvb_frontend *fe)
2111{
2112 struct dib0090_state *state = fe->tuner_priv;
2113 const struct dib0090_tuning *tune = state->current_tune_table_index;
2114 const struct dib0090_pll *pll = state->current_pll_table_index;
2115 enum frontend_tune_state *tune_state = &state->tune_state;
2116
2117 u16 lo5, lo6, Den, tmp;
2118 u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
2119 int ret = 10; /* 1ms is the default delay most of the time */
2120 u8 c, i;
2121
2122 /************************* VCO ***************************/
2123 /* Default values for FG */
2124 /* from these are needed : */
2125 /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv */
2126
2127 /* in any case we first need to do a calibration if needed */
2128 if (*tune_state == CT_TUNER_START) {
2129 /* deactivate DataTX before some calibrations */
2130 if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL))
2131 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
2132 else
2133 /* Activate DataTX in case a calibration has been done before */
2134 if (state->config->analog_output == 0)
2135 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2136 }
2137
2138 if (state->calibrate & DC_CAL)
2139 return dib0090_dc_offset_calibration(state, tune_state);
2140 else if (state->calibrate & WBD_CAL) {
2141 if (state->current_rf == 0)
2142 state->current_rf = state->fe->dtv_property_cache.frequency / 1000;
2143 return dib0090_wbd_calibration(state, tune_state);
2144 } else if (state->calibrate & TEMP_CAL)
2145 return dib0090_get_temperature(state, tune_state);
2146 else if (state->calibrate & CAPTRIM_CAL)
2147 return dib0090_captrim_search(state, tune_state);
2148
2149 if (*tune_state == CT_TUNER_START) {
2150 /* if soc and AGC pwm control, disengage mux to be able to R/W access to 0x01 register to set the right filter (cutoff_freq_select) during the tune sequence, otherwise, SOC SERPAR error when accessing to 0x01 */
2151 if (state->config->use_pwm_agc && state->identity.in_soc) {
2152 tmp = dib0090_read_reg(state, 0x39);
2153 if ((tmp >> 10) & 0x1)
2154 dib0090_write_reg(state, 0x39, tmp & ~(1 << 10));
2155 }
2156
2157 state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000);
2158 state->rf_request =
2159 state->fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
2160 BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->
2161 freq_offset_khz_vhf);
2162
2163 /* in ISDB-T 1seg we shift tuning frequency */
2164 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1
2165 && state->fe->dtv_property_cache.isdbt_partial_reception == 0)) {
2166 const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if;
2167 u8 found_offset = 0;
2168 u32 margin_khz = 100;
2169
2170 if (LUT_offset != NULL) {
2171 while (LUT_offset->RF_freq != 0xffff) {
2172 if (((state->rf_request > (LUT_offset->RF_freq - margin_khz))
2173 && (state->rf_request < (LUT_offset->RF_freq + margin_khz)))
2174 && LUT_offset->std == state->fe->dtv_property_cache.delivery_system) {
2175 state->rf_request += LUT_offset->offset_khz;
2176 found_offset = 1;
2177 break;
2178 }
2179 LUT_offset++;
2180 }
2181 }
2182
2183 if (found_offset == 0)
2184 state->rf_request += 400;
2185 }
2186 if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) {
2187 state->tuner_is_tuned = 0;
2188 state->current_rf = 0;
2189 state->current_standard = 0;
2190
2191 tune = dib0090_tuning_table;
2192 if (state->identity.p1g)
2193 tune = dib0090_p1g_tuning_table;
2194
2195 tmp = (state->identity.version >> 5) & 0x7;
2196
2197 if (state->identity.in_soc) {
2198 if (state->config->force_cband_input) { /* Use the CBAND input for all band */
2199 if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
2200 || state->current_band & BAND_UHF) {
2201 state->current_band = BAND_CBAND;
2202 tune = dib0090_tuning_table_cband_7090;
2203 }
2204 } else { /* Use the CBAND input for all band under UHF */
2205 if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
2206 state->current_band = BAND_CBAND;
2207 tune = dib0090_tuning_table_cband_7090;
2208 }
2209 }
2210 } else
2211 if (tmp == 0x4 || tmp == 0x7) {
2212 /* CBAND tuner version for VHF */
2213 if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) {
2214 state->current_band = BAND_CBAND; /* Force CBAND */
2215
2216 tune = dib0090_tuning_table_fm_vhf_on_cband;
2217 if (state->identity.p1g)
2218 tune = dib0090_p1g_tuning_table_fm_vhf_on_cband;
2219 }
2220 }
2221
2222 pll = dib0090_pll_table;
2223 if (state->identity.p1g)
2224 pll = dib0090_p1g_pll_table;
2225
2226 /* Look for the interval */
2227 while (state->rf_request > tune->max_freq)
2228 tune++;
2229 while (state->rf_request > pll->max_freq)
2230 pll++;
2231
2232 state->current_tune_table_index = tune;
2233 state->current_pll_table_index = pll;
2234
2235 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
2236
2237 VCOF_kHz = (pll->hfdiv * state->rf_request) * 2;
2238
2239 FREF = state->config->io.clock_khz;
2240 if (state->config->fref_clock_ratio != 0)
2241 FREF /= state->config->fref_clock_ratio;
2242
2243 FBDiv = (VCOF_kHz / pll->topresc / FREF);
2244 Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
2245
2246 if (Rest < LPF)
2247 Rest = 0;
2248 else if (Rest < 2 * LPF)
2249 Rest = 2 * LPF;
2250 else if (Rest > (FREF - LPF)) {
2251 Rest = 0;
2252 FBDiv += 1;
2253 } else if (Rest > (FREF - 2 * LPF))
2254 Rest = FREF - 2 * LPF;
2255 Rest = (Rest * 6528) / (FREF / 10);
2256 state->rest = Rest;
2257
2258 /* external loop filter, otherwise:
2259 * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4;
2260 * lo6 = 0x0e34 */
2261
2262 if (Rest == 0) {
2263 if (pll->vco_band)
2264 lo5 = 0x049f;
2265 else
2266 lo5 = 0x041f;
2267 } else {
2268 if (pll->vco_band)
2269 lo5 = 0x049e;
2270 else if (state->config->analog_output)
2271 lo5 = 0x041d;
2272 else
2273 lo5 = 0x041c;
2274 }
2275
2276 if (state->identity.p1g) { /* Bias is done automatically in P1G */
2277 if (state->identity.in_soc) {
2278 if (state->identity.version == SOC_8090_P1G_11R1)
2279 lo5 = 0x46f;
2280 else
2281 lo5 = 0x42f;
2282 } else
2283 lo5 = 0x42c;
2284 }
2285
2286 lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7); /* bit 15 is the split to the slave, we do not do it here */
2287
2288 if (!state->config->io.pll_int_loop_filt) {
2289 if (state->identity.in_soc)
2290 lo6 = 0xff98;
2291 else if (state->identity.p1g || (Rest == 0))
2292 lo6 = 0xfff8;
2293 else
2294 lo6 = 0xff28;
2295 } else
2296 lo6 = (state->config->io.pll_int_loop_filt << 3);
2297
2298 Den = 1;
2299
2300 if (Rest > 0) {
2301 if (state->config->analog_output)
2302 lo6 |= (1 << 2) | 2;
2303 else {
2304 if (state->identity.in_soc)
2305 lo6 |= (1 << 2) | 2;
2306 else
2307 lo6 |= (1 << 2) | 2;
2308 }
2309 Den = 255;
2310 }
2311 dib0090_write_reg(state, 0x15, (u16) FBDiv);
2312 if (state->config->fref_clock_ratio != 0)
2313 dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio);
2314 else
2315 dib0090_write_reg(state, 0x16, (Den << 8) | 1);
2316 dib0090_write_reg(state, 0x17, (u16) Rest);
2317 dib0090_write_reg(state, 0x19, lo5);
2318 dib0090_write_reg(state, 0x1c, lo6);
2319
2320 lo6 = tune->tuner_enable;
2321 if (state->config->analog_output)
2322 lo6 = (lo6 & 0xff9f) | 0x2;
2323
2324 dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL);
2325
2326 }
2327
2328 state->current_rf = state->rf_request;
2329 state->current_standard = state->fe->dtv_property_cache.delivery_system;
2330
2331 ret = 20;
2332 state->calibrate = CAPTRIM_CAL; /* captrim serach now */
2333 }
2334
2335 else if (*tune_state == CT_TUNER_STEP_0) { /* Warning : because of captrim cal, if you change this step, change it also in _cal.c file because it is the step following captrim cal state machine */
2336 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
2337
2338 while (state->current_rf / 1000 > wbd->max_freq)
2339 wbd++;
2340
2341 dib0090_write_reg(state, 0x1e, 0x07ff);
2342 dprintk("Final Captrim: %d", (u32) state->fcaptrim);
2343 dprintk("HFDIV code: %d", (u32) pll->hfdiv_code);
2344 dprintk("VCO = %d", (u32) pll->vco_band);
2345 dprintk("VCOF in kHz: %d ((%d*%d) << 1))", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request);
2346 dprintk("REFDIV: %d, FREF: %d", (u32) 1, (u32) state->config->io.clock_khz);
2347 dprintk("FBDIV: %d, Rest: %d", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
2348 dprintk("Num: %d, Den: %d, SD: %d", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8),
2349 (u32) dib0090_read_reg(state, 0x1c) & 0x3);
2350
2351#define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */
2352 c = 4;
2353 i = 3;
2354
2355 if (wbd->wbd_gain != 0)
2356 c = wbd->wbd_gain;
2357
2358 state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1));
2359 dib0090_write_reg(state, 0x10, state->wbdmux);
2360
2361 if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) {
2362 dprintk("P1G : The cable band is selected and lna_tune = %d", tune->lna_tune);
2363 dib0090_write_reg(state, 0x09, tune->lna_bias);
2364 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim));
2365 } else
2366 dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias);
2367
2368 dib0090_write_reg(state, 0x0c, tune->v2i);
2369 dib0090_write_reg(state, 0x0d, tune->mix);
2370 dib0090_write_reg(state, 0x0e, tune->load);
2371 *tune_state = CT_TUNER_STEP_1;
2372
2373 } else if (*tune_state == CT_TUNER_STEP_1) {
2374 /* initialize the lt gain register */
2375 state->rf_lt_def = 0x7c00;
2376
2377 dib0090_set_bandwidth(state);
2378 state->tuner_is_tuned = 1;
2379
2380 state->calibrate |= WBD_CAL;
2381 state->calibrate |= TEMP_CAL;
2382 *tune_state = CT_TUNER_STOP;
2383 } else
2384 ret = FE_CALLBACK_TIME_NEVER;
2385 return ret;
2386}
2387
2388static int dib0090_release(struct dvb_frontend *fe)
2389{
2390 kfree(fe->tuner_priv);
2391 fe->tuner_priv = NULL;
2392 return 0;
2393}
2394
2395enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
2396{
2397 struct dib0090_state *state = fe->tuner_priv;
2398
2399 return state->tune_state;
2400}
2401
2402EXPORT_SYMBOL(dib0090_get_tune_state);
2403
2404int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2405{
2406 struct dib0090_state *state = fe->tuner_priv;
2407
2408 state->tune_state = tune_state;
2409 return 0;
2410}
2411
2412EXPORT_SYMBOL(dib0090_set_tune_state);
2413
2414static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
2415{
2416 struct dib0090_state *state = fe->tuner_priv;
2417
2418 *frequency = 1000 * state->current_rf;
2419 return 0;
2420}
2421
2422static int dib0090_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
2423{
2424 struct dib0090_state *state = fe->tuner_priv;
2425 u32 ret;
2426
2427 state->tune_state = CT_TUNER_START;
2428
2429 do {
2430 ret = dib0090_tune(fe);
2431 if (ret != FE_CALLBACK_TIME_NEVER)
2432 msleep(ret / 10);
2433 else
2434 break;
2435 } while (state->tune_state != CT_TUNER_STOP);
2436
2437 return 0;
2438}
2439
2440static const struct dvb_tuner_ops dib0090_ops = {
2441 .info = {
2442 .name = "DiBcom DiB0090",
2443 .frequency_min = 45000000,
2444 .frequency_max = 860000000,
2445 .frequency_step = 1000,
2446 },
2447 .release = dib0090_release,
2448
2449 .init = dib0090_wakeup,
2450 .sleep = dib0090_sleep,
2451 .set_params = dib0090_set_params,
2452 .get_frequency = dib0090_get_frequency,
2453};
2454
2455static const struct dvb_tuner_ops dib0090_fw_ops = {
2456 .info = {
2457 .name = "DiBcom DiB0090",
2458 .frequency_min = 45000000,
2459 .frequency_max = 860000000,
2460 .frequency_step = 1000,
2461 },
2462 .release = dib0090_release,
2463
2464 .init = NULL,
2465 .sleep = NULL,
2466 .set_params = NULL,
2467 .get_frequency = NULL,
2468};
2469
2470static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = {
2471 {470, 0, 250, 0, 100, 4},
2472 {860, 51, 866, 21, 375, 4},
2473 {1700, 0, 800, 0, 850, 4},
2474 {2900, 0, 250, 0, 100, 6},
2475 {0xFFFF, 0, 0, 0, 0, 0},
2476};
2477
2478struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2479{
2480 struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
2481 if (st == NULL)
2482 return NULL;
2483
2484 st->config = config;
2485 st->i2c = i2c;
2486 st->fe = fe;
2487 mutex_init(&st->i2c_buffer_lock);
2488 fe->tuner_priv = st;
2489
2490 if (config->wbd == NULL)
2491 st->current_wbd_table = dib0090_wbd_table_default;
2492 else
2493 st->current_wbd_table = config->wbd;
2494
2495 if (dib0090_reset(fe) != 0)
2496 goto free_mem;
2497
2498 printk(KERN_INFO "DiB0090: successfully identified\n");
2499 memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops));
2500
2501 return fe;
2502 free_mem:
2503 kfree(st);
2504 fe->tuner_priv = NULL;
2505 return NULL;
2506}
2507
2508EXPORT_SYMBOL(dib0090_register);
2509
2510struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2511{
2512 struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL);
2513 if (st == NULL)
2514 return NULL;
2515
2516 st->config = config;
2517 st->i2c = i2c;
2518 st->fe = fe;
2519 mutex_init(&st->i2c_buffer_lock);
2520 fe->tuner_priv = st;
2521
2522 if (dib0090_fw_reset_digital(fe, st->config) != 0)
2523 goto free_mem;
2524
2525 dprintk("DiB0090 FW: successfully identified");
2526 memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops));
2527
2528 return fe;
2529free_mem:
2530 kfree(st);
2531 fe->tuner_priv = NULL;
2532 return NULL;
2533}
2534EXPORT_SYMBOL(dib0090_fw_register);
2535
2536MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
2537MODULE_AUTHOR("Olivier Grenie <olivier.grenie@dibcom.fr>");
2538MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
2539MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib0090.h b/drivers/media/dvb/frontends/dib0090.h
new file mode 100644
index 00000000000..13d85244ec1
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib0090.h
@@ -0,0 +1,139 @@
1/*
2 * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
3 *
4 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 */
10#ifndef DIB0090_H
11#define DIB0090_H
12
13struct dvb_frontend;
14struct i2c_adapter;
15
16#define DEFAULT_DIB0090_I2C_ADDRESS 0x60
17
18struct dib0090_io_config {
19 u32 clock_khz;
20
21 u8 pll_bypass:1;
22 u8 pll_range:1;
23 u8 pll_prediv:6;
24 u8 pll_loopdiv:6;
25
26 u8 adc_clock_ratio; /* valid is 8, 7 ,6 */
27 u16 pll_int_loop_filt;
28};
29
30struct dib0090_wbd_slope {
31 u16 max_freq; /* for every frequency less than or equal to that field: this information is correct */
32 u16 slope_cold;
33 u16 offset_cold;
34 u16 slope_hot;
35 u16 offset_hot;
36 u8 wbd_gain;
37};
38
39struct dib0090_low_if_offset_table {
40 int std;
41 u32 RF_freq;
42 s32 offset_khz;
43};
44
45struct dib0090_config {
46 struct dib0090_io_config io;
47 int (*reset) (struct dvb_frontend *, int);
48 int (*sleep) (struct dvb_frontend *, int);
49
50 /* offset in kHz */
51 int freq_offset_khz_uhf;
52 int freq_offset_khz_vhf;
53
54 int (*get_adc_power) (struct dvb_frontend *);
55
56 u8 clkouttobamse:1; /* activate or deactivate clock output */
57 u8 analog_output;
58
59 u8 i2c_address;
60 /* add drives and other things if necessary */
61 u16 wbd_vhf_offset;
62 u16 wbd_cband_offset;
63 u8 use_pwm_agc;
64 u8 clkoutdrive;
65
66 u8 ls_cfg_pad_drv;
67 u8 data_tx_drv;
68
69 u8 in_soc;
70 const struct dib0090_low_if_offset_table *low_if;
71 u8 fref_clock_ratio;
72 u16 force_cband_input;
73 struct dib0090_wbd_slope *wbd;
74};
75
76#if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE))
77extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
78extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
79extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast);
80extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe);
81extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner);
82extern int dib0090_gain_control(struct dvb_frontend *fe);
83extern enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe);
84extern int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
85extern void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt);
86#else
87static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config)
88{
89 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
90 return NULL;
91}
92
93static inline struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config)
94{
95 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
96 return NULL;
97}
98
99static inline void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
100{
101 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
102}
103
104static inline void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
105{
106 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
107}
108
109static inline u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner)
110{
111 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
112 return 0;
113}
114
115static inline int dib0090_gain_control(struct dvb_frontend *fe)
116{
117 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
118 return -ENODEV;
119}
120
121static inline enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
122{
123 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
124 return CT_DONE;
125}
126
127static inline int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
128{
129 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
130 return -ENODEV;
131}
132
133static inline void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
134{
135 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
136}
137#endif
138
139#endif
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h
new file mode 100644
index 00000000000..ba917359fa6
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000.h
@@ -0,0 +1,56 @@
1/*
2 * public header file of the frontend drivers for mobile DVB-T demodulators
3 * DiBcom 3000M-B and DiBcom 3000P/M-C (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * based on GPL code from DibCom, which has
8 *
9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
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, version 2.
14 *
15 * Acknowledgements
16 *
17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
18 * sources, on which this driver (and the dvb-dibusb) are based.
19 *
20 * see Documentation/dvb/README.dibusb for more information
21 *
22 */
23
24#ifndef DIB3000_H
25#define DIB3000_H
26
27#include <linux/dvb/frontend.h>
28
29struct dib3000_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33};
34
35struct dib_fe_xfer_ops
36{
37 /* pid and transfer handling is done in the demodulator */
38 int (*pid_parse)(struct dvb_frontend *fe, int onoff);
39 int (*fifo_ctrl)(struct dvb_frontend *fe, int onoff);
40 int (*pid_ctrl)(struct dvb_frontend *fe, int index, int pid, int onoff);
41 int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
42};
43
44#if defined(CONFIG_DVB_DIB3000MB) || (defined(CONFIG_DVB_DIB3000MB_MODULE) && defined(MODULE))
45extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
46 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
47#else
48static inline struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
49 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
50{
51 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
52 return NULL;
53}
54#endif // CONFIG_DVB_DIB3000MB
55
56#endif // DIB3000_H
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
new file mode 100644
index 00000000000..e80c5979636
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -0,0 +1,834 @@
1/*
2 * Frontend driver for mobile DVB-T demodulator DiBcom 3000M-B
3 * DiBcom (http://www.dibcom.fr/)
4 *
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * based on GPL code from DibCom, which has
8 *
9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
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, version 2.
14 *
15 * Acknowledgements
16 *
17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
18 * sources, on which this driver (and the dvb-dibusb) are based.
19 *
20 * see Documentation/dvb/README.dibusb for more information
21 *
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/string.h>
29#include <linux/slab.h>
30
31#include "dvb_frontend.h"
32
33#include "dib3000.h"
34#include "dib3000mb_priv.h"
35
36/* Version information */
37#define DRIVER_VERSION "0.1"
38#define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator"
39#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
40
41static int debug;
42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able)).");
44
45#define deb_info(args...) dprintk(0x01,args)
46#define deb_i2c(args...) dprintk(0x02,args)
47#define deb_srch(args...) dprintk(0x04,args)
48#define deb_info(args...) dprintk(0x01,args)
49#define deb_xfer(args...) dprintk(0x02,args)
50#define deb_setf(args...) dprintk(0x04,args)
51#define deb_getf(args...) dprintk(0x08,args)
52
53static int dib3000_read_reg(struct dib3000_state *state, u16 reg)
54{
55 u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
56 u8 rb[2];
57 struct i2c_msg msg[] = {
58 { .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 },
59 { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
60 };
61
62 if (i2c_transfer(state->i2c, msg, 2) != 2)
63 deb_i2c("i2c read error\n");
64
65 deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,
66 (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]);
67
68 return (rb[0] << 8) | rb[1];
69}
70
71static int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val)
72{
73 u8 b[] = {
74 (reg >> 8) & 0xff, reg & 0xff,
75 (val >> 8) & 0xff, val & 0xff,
76 };
77 struct i2c_msg msg[] = {
78 { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 }
79 };
80 deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val);
81
82 return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
83}
84
85static int dib3000_search_status(u16 irq,u16 lock)
86{
87 if (irq & 0x02) {
88 if (lock & 0x01) {
89 deb_srch("auto search succeeded\n");
90 return 1; // auto search succeeded
91 } else {
92 deb_srch("auto search not successful\n");
93 return 0; // auto search failed
94 }
95 } else if (irq & 0x01) {
96 deb_srch("auto search failed\n");
97 return 0; // auto search failed
98 }
99 return -1; // try again
100}
101
102/* for auto search */
103static u16 dib3000_seq[2][2][2] = /* fft,gua, inv */
104 { /* fft */
105 { /* gua */
106 { 0, 1 }, /* 0 0 { 0,1 } */
107 { 3, 9 }, /* 0 1 { 0,1 } */
108 },
109 {
110 { 2, 5 }, /* 1 0 { 0,1 } */
111 { 6, 11 }, /* 1 1 { 0,1 } */
112 }
113 };
114
115static int dib3000mb_get_frontend(struct dvb_frontend* fe,
116 struct dvb_frontend_parameters *fep);
117
118static int dib3000mb_set_frontend(struct dvb_frontend* fe,
119 struct dvb_frontend_parameters *fep, int tuner)
120{
121 struct dib3000_state* state = fe->demodulator_priv;
122 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
123 fe_code_rate_t fe_cr = FEC_NONE;
124 int search_state, seq;
125
126 if (tuner && fe->ops.tuner_ops.set_params) {
127 fe->ops.tuner_ops.set_params(fe, fep);
128 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
129
130 deb_setf("bandwidth: ");
131 switch (ofdm->bandwidth) {
132 case BANDWIDTH_8_MHZ:
133 deb_setf("8 MHz\n");
134 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
135 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
136 break;
137 case BANDWIDTH_7_MHZ:
138 deb_setf("7 MHz\n");
139 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]);
140 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz);
141 break;
142 case BANDWIDTH_6_MHZ:
143 deb_setf("6 MHz\n");
144 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]);
145 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz);
146 break;
147 case BANDWIDTH_AUTO:
148 return -EOPNOTSUPP;
149 default:
150 err("unknown bandwidth value.");
151 return -EINVAL;
152 }
153 }
154 wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
155
156 deb_setf("transmission mode: ");
157 switch (ofdm->transmission_mode) {
158 case TRANSMISSION_MODE_2K:
159 deb_setf("2k\n");
160 wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_2K);
161 break;
162 case TRANSMISSION_MODE_8K:
163 deb_setf("8k\n");
164 wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_8K);
165 break;
166 case TRANSMISSION_MODE_AUTO:
167 deb_setf("auto\n");
168 break;
169 default:
170 return -EINVAL;
171 }
172
173 deb_setf("guard: ");
174 switch (ofdm->guard_interval) {
175 case GUARD_INTERVAL_1_32:
176 deb_setf("1_32\n");
177 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_32);
178 break;
179 case GUARD_INTERVAL_1_16:
180 deb_setf("1_16\n");
181 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_16);
182 break;
183 case GUARD_INTERVAL_1_8:
184 deb_setf("1_8\n");
185 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_8);
186 break;
187 case GUARD_INTERVAL_1_4:
188 deb_setf("1_4\n");
189 wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_4);
190 break;
191 case GUARD_INTERVAL_AUTO:
192 deb_setf("auto\n");
193 break;
194 default:
195 return -EINVAL;
196 }
197
198 deb_setf("inversion: ");
199 switch (fep->inversion) {
200 case INVERSION_OFF:
201 deb_setf("off\n");
202 wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_OFF);
203 break;
204 case INVERSION_AUTO:
205 deb_setf("auto ");
206 break;
207 case INVERSION_ON:
208 deb_setf("on\n");
209 wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_ON);
210 break;
211 default:
212 return -EINVAL;
213 }
214
215 deb_setf("constellation: ");
216 switch (ofdm->constellation) {
217 case QPSK:
218 deb_setf("qpsk\n");
219 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_QPSK);
220 break;
221 case QAM_16:
222 deb_setf("qam16\n");
223 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_16QAM);
224 break;
225 case QAM_64:
226 deb_setf("qam64\n");
227 wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_64QAM);
228 break;
229 case QAM_AUTO:
230 break;
231 default:
232 return -EINVAL;
233 }
234 deb_setf("hierarchy: ");
235 switch (ofdm->hierarchy_information) {
236 case HIERARCHY_NONE:
237 deb_setf("none ");
238 /* fall through */
239 case HIERARCHY_1:
240 deb_setf("alpha=1\n");
241 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1);
242 break;
243 case HIERARCHY_2:
244 deb_setf("alpha=2\n");
245 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2);
246 break;
247 case HIERARCHY_4:
248 deb_setf("alpha=4\n");
249 wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4);
250 break;
251 case HIERARCHY_AUTO:
252 deb_setf("alpha=auto\n");
253 break;
254 default:
255 return -EINVAL;
256 }
257
258 deb_setf("hierarchy: ");
259 if (ofdm->hierarchy_information == HIERARCHY_NONE) {
260 deb_setf("none\n");
261 wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_OFF);
262 wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_HP);
263 fe_cr = ofdm->code_rate_HP;
264 } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) {
265 deb_setf("on\n");
266 wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_ON);
267 wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_LP);
268 fe_cr = ofdm->code_rate_LP;
269 }
270 deb_setf("fec: ");
271 switch (fe_cr) {
272 case FEC_1_2:
273 deb_setf("1_2\n");
274 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_1_2);
275 break;
276 case FEC_2_3:
277 deb_setf("2_3\n");
278 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_2_3);
279 break;
280 case FEC_3_4:
281 deb_setf("3_4\n");
282 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_3_4);
283 break;
284 case FEC_5_6:
285 deb_setf("5_6\n");
286 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_5_6);
287 break;
288 case FEC_7_8:
289 deb_setf("7_8\n");
290 wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_7_8);
291 break;
292 case FEC_NONE:
293 deb_setf("none ");
294 break;
295 case FEC_AUTO:
296 deb_setf("auto\n");
297 break;
298 default:
299 return -EINVAL;
300 }
301
302 seq = dib3000_seq
303 [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO]
304 [ofdm->guard_interval == GUARD_INTERVAL_AUTO]
305 [fep->inversion == INVERSION_AUTO];
306
307 deb_setf("seq? %d\n", seq);
308
309 wr(DIB3000MB_REG_SEQ, seq);
310
311 wr(DIB3000MB_REG_ISI, seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE);
312
313 if (ofdm->transmission_mode == TRANSMISSION_MODE_2K) {
314 if (ofdm->guard_interval == GUARD_INTERVAL_1_8) {
315 wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_2K_1_8);
316 } else {
317 wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_DEFAULT);
318 }
319
320 wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_2K);
321 } else {
322 wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_DEFAULT);
323 }
324
325 wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_OFF);
326 wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
327 wr(DIB3000MB_REG_MOBILE_MODE, DIB3000MB_MOBILE_MODE_OFF);
328
329 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_high);
330
331 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_ACTIVATE);
332
333 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC + DIB3000MB_RESTART_CTRL);
334 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
335
336 /* wait for AGC lock */
337 msleep(70);
338
339 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
340
341 /* something has to be auto searched */
342 if (ofdm->constellation == QAM_AUTO ||
343 ofdm->hierarchy_information == HIERARCHY_AUTO ||
344 fe_cr == FEC_AUTO ||
345 fep->inversion == INVERSION_AUTO) {
346 int as_count=0;
347
348 deb_setf("autosearch enabled.\n");
349
350 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
351
352 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AUTO_SEARCH);
353 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
354
355 while ((search_state =
356 dib3000_search_status(
357 rd(DIB3000MB_REG_AS_IRQ_PENDING),
358 rd(DIB3000MB_REG_LOCK2_VALUE))) < 0 && as_count++ < 100)
359 msleep(1);
360
361 deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count);
362
363 if (search_state == 1) {
364 struct dvb_frontend_parameters feps;
365 if (dib3000mb_get_frontend(fe, &feps) == 0) {
366 deb_setf("reading tuning data from frontend succeeded.\n");
367 return dib3000mb_set_frontend(fe, &feps, 0);
368 }
369 }
370
371 } else {
372 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_CTRL);
373 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF);
374 }
375
376 return 0;
377}
378
379static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode)
380{
381 struct dib3000_state* state = fe->demodulator_priv;
382
383 deb_info("dib3000mb is getting up.\n");
384 wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP);
385
386 wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC);
387
388 wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE);
389 wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE_RST);
390
391 wr(DIB3000MB_REG_CLOCK, DIB3000MB_CLOCK_DEFAULT);
392
393 wr(DIB3000MB_REG_ELECT_OUT_MODE, DIB3000MB_ELECT_OUT_MODE_ON);
394
395 wr(DIB3000MB_REG_DDS_FREQ_MSB, DIB3000MB_DDS_FREQ_MSB);
396 wr(DIB3000MB_REG_DDS_FREQ_LSB, DIB3000MB_DDS_FREQ_LSB);
397
398 wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]);
399
400 wr_foreach(dib3000mb_reg_impulse_noise,
401 dib3000mb_impulse_noise_values[DIB3000MB_IMPNOISE_OFF]);
402
403 wr_foreach(dib3000mb_reg_agc_gain, dib3000mb_default_agc_gain);
404
405 wr(DIB3000MB_REG_PHASE_NOISE, DIB3000MB_PHASE_NOISE_DEFAULT);
406
407 wr_foreach(dib3000mb_reg_phase_noise, dib3000mb_default_noise_phase);
408
409 wr_foreach(dib3000mb_reg_lock_duration, dib3000mb_default_lock_duration);
410
411 wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low);
412
413 wr(DIB3000MB_REG_LOCK0_MASK, DIB3000MB_LOCK0_DEFAULT);
414 wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
415 wr(DIB3000MB_REG_LOCK2_MASK, DIB3000MB_LOCK2_DEFAULT);
416 wr(DIB3000MB_REG_SEQ, dib3000_seq[1][1][1]);
417
418 wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz);
419
420 wr(DIB3000MB_REG_UNK_68, DIB3000MB_UNK_68);
421 wr(DIB3000MB_REG_UNK_69, DIB3000MB_UNK_69);
422 wr(DIB3000MB_REG_UNK_71, DIB3000MB_UNK_71);
423 wr(DIB3000MB_REG_UNK_77, DIB3000MB_UNK_77);
424 wr(DIB3000MB_REG_UNK_78, DIB3000MB_UNK_78);
425 wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT);
426 wr(DIB3000MB_REG_UNK_92, DIB3000MB_UNK_92);
427 wr(DIB3000MB_REG_UNK_96, DIB3000MB_UNK_96);
428 wr(DIB3000MB_REG_UNK_97, DIB3000MB_UNK_97);
429 wr(DIB3000MB_REG_UNK_106, DIB3000MB_UNK_106);
430 wr(DIB3000MB_REG_UNK_107, DIB3000MB_UNK_107);
431 wr(DIB3000MB_REG_UNK_108, DIB3000MB_UNK_108);
432 wr(DIB3000MB_REG_UNK_122, DIB3000MB_UNK_122);
433 wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF);
434 wr(DIB3000MB_REG_BERLEN, DIB3000MB_BERLEN_DEFAULT);
435
436 wr_foreach(dib3000mb_reg_filter_coeffs, dib3000mb_filter_coeffs);
437
438 wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_ON);
439 wr(DIB3000MB_REG_MULTI_DEMOD_MSB, DIB3000MB_MULTI_DEMOD_MSB);
440 wr(DIB3000MB_REG_MULTI_DEMOD_LSB, DIB3000MB_MULTI_DEMOD_LSB);
441
442 wr(DIB3000MB_REG_OUTPUT_MODE, DIB3000MB_OUTPUT_MODE_SLAVE);
443
444 wr(DIB3000MB_REG_FIFO_142, DIB3000MB_FIFO_142);
445 wr(DIB3000MB_REG_MPEG2_OUT_MODE, DIB3000MB_MPEG2_OUT_MODE_188);
446 wr(DIB3000MB_REG_PID_PARSE, DIB3000MB_PID_PARSE_ACTIVATE);
447 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
448 wr(DIB3000MB_REG_FIFO_146, DIB3000MB_FIFO_146);
449 wr(DIB3000MB_REG_FIFO_147, DIB3000MB_FIFO_147);
450
451 wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF);
452
453 return 0;
454}
455
456static int dib3000mb_get_frontend(struct dvb_frontend* fe,
457 struct dvb_frontend_parameters *fep)
458{
459 struct dib3000_state* state = fe->demodulator_priv;
460 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
461 fe_code_rate_t *cr;
462 u16 tps_val;
463 int inv_test1,inv_test2;
464 u32 dds_val, threshold = 0x800000;
465
466 if (!rd(DIB3000MB_REG_TPS_LOCK))
467 return 0;
468
469 dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB);
470 deb_getf("DDS_VAL: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB));
471 if (dds_val < threshold)
472 inv_test1 = 0;
473 else if (dds_val == threshold)
474 inv_test1 = 1;
475 else
476 inv_test1 = 2;
477
478 dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB);
479 deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB));
480 if (dds_val < threshold)
481 inv_test2 = 0;
482 else if (dds_val == threshold)
483 inv_test2 = 1;
484 else
485 inv_test2 = 2;
486
487 fep->inversion =
488 ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) ||
489 ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?
490 INVERSION_ON : INVERSION_OFF;
491
492 deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion);
493
494 switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) {
495 case DIB3000_CONSTELLATION_QPSK:
496 deb_getf("QPSK ");
497 ofdm->constellation = QPSK;
498 break;
499 case DIB3000_CONSTELLATION_16QAM:
500 deb_getf("QAM16 ");
501 ofdm->constellation = QAM_16;
502 break;
503 case DIB3000_CONSTELLATION_64QAM:
504 deb_getf("QAM64 ");
505 ofdm->constellation = QAM_64;
506 break;
507 default:
508 err("Unexpected constellation returned by TPS (%d)", tps_val);
509 break;
510 }
511 deb_getf("TPS: %d\n", tps_val);
512
513 if (rd(DIB3000MB_REG_TPS_HRCH)) {
514 deb_getf("HRCH ON\n");
515 cr = &ofdm->code_rate_LP;
516 ofdm->code_rate_HP = FEC_NONE;
517 switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) {
518 case DIB3000_ALPHA_0:
519 deb_getf("HIERARCHY_NONE ");
520 ofdm->hierarchy_information = HIERARCHY_NONE;
521 break;
522 case DIB3000_ALPHA_1:
523 deb_getf("HIERARCHY_1 ");
524 ofdm->hierarchy_information = HIERARCHY_1;
525 break;
526 case DIB3000_ALPHA_2:
527 deb_getf("HIERARCHY_2 ");
528 ofdm->hierarchy_information = HIERARCHY_2;
529 break;
530 case DIB3000_ALPHA_4:
531 deb_getf("HIERARCHY_4 ");
532 ofdm->hierarchy_information = HIERARCHY_4;
533 break;
534 default:
535 err("Unexpected ALPHA value returned by TPS (%d)", tps_val);
536 break;
537 }
538 deb_getf("TPS: %d\n", tps_val);
539
540 tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP);
541 } else {
542 deb_getf("HRCH OFF\n");
543 cr = &ofdm->code_rate_HP;
544 ofdm->code_rate_LP = FEC_NONE;
545 ofdm->hierarchy_information = HIERARCHY_NONE;
546
547 tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP);
548 }
549
550 switch (tps_val) {
551 case DIB3000_FEC_1_2:
552 deb_getf("FEC_1_2 ");
553 *cr = FEC_1_2;
554 break;
555 case DIB3000_FEC_2_3:
556 deb_getf("FEC_2_3 ");
557 *cr = FEC_2_3;
558 break;
559 case DIB3000_FEC_3_4:
560 deb_getf("FEC_3_4 ");
561 *cr = FEC_3_4;
562 break;
563 case DIB3000_FEC_5_6:
564 deb_getf("FEC_5_6 ");
565 *cr = FEC_4_5;
566 break;
567 case DIB3000_FEC_7_8:
568 deb_getf("FEC_7_8 ");
569 *cr = FEC_7_8;
570 break;
571 default:
572 err("Unexpected FEC returned by TPS (%d)", tps_val);
573 break;
574 }
575 deb_getf("TPS: %d\n",tps_val);
576
577 switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) {
578 case DIB3000_GUARD_TIME_1_32:
579 deb_getf("GUARD_INTERVAL_1_32 ");
580 ofdm->guard_interval = GUARD_INTERVAL_1_32;
581 break;
582 case DIB3000_GUARD_TIME_1_16:
583 deb_getf("GUARD_INTERVAL_1_16 ");
584 ofdm->guard_interval = GUARD_INTERVAL_1_16;
585 break;
586 case DIB3000_GUARD_TIME_1_8:
587 deb_getf("GUARD_INTERVAL_1_8 ");
588 ofdm->guard_interval = GUARD_INTERVAL_1_8;
589 break;
590 case DIB3000_GUARD_TIME_1_4:
591 deb_getf("GUARD_INTERVAL_1_4 ");
592 ofdm->guard_interval = GUARD_INTERVAL_1_4;
593 break;
594 default:
595 err("Unexpected Guard Time returned by TPS (%d)", tps_val);
596 break;
597 }
598 deb_getf("TPS: %d\n", tps_val);
599
600 switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) {
601 case DIB3000_TRANSMISSION_MODE_2K:
602 deb_getf("TRANSMISSION_MODE_2K ");
603 ofdm->transmission_mode = TRANSMISSION_MODE_2K;
604 break;
605 case DIB3000_TRANSMISSION_MODE_8K:
606 deb_getf("TRANSMISSION_MODE_8K ");
607 ofdm->transmission_mode = TRANSMISSION_MODE_8K;
608 break;
609 default:
610 err("unexpected transmission mode return by TPS (%d)", tps_val);
611 break;
612 }
613 deb_getf("TPS: %d\n", tps_val);
614
615 return 0;
616}
617
618static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat)
619{
620 struct dib3000_state* state = fe->demodulator_priv;
621
622 *stat = 0;
623
624 if (rd(DIB3000MB_REG_AGC_LOCK))
625 *stat |= FE_HAS_SIGNAL;
626 if (rd(DIB3000MB_REG_CARRIER_LOCK))
627 *stat |= FE_HAS_CARRIER;
628 if (rd(DIB3000MB_REG_VIT_LCK))
629 *stat |= FE_HAS_VITERBI;
630 if (rd(DIB3000MB_REG_TS_SYNC_LOCK))
631 *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
632
633 deb_getf("actual status is %2x\n",*stat);
634
635 deb_getf("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n",
636 rd(DIB3000MB_REG_TPS_LOCK),
637 rd(DIB3000MB_REG_TPS_QAM),
638 rd(DIB3000MB_REG_TPS_HRCH),
639 rd(DIB3000MB_REG_TPS_VIT_ALPHA),
640 rd(DIB3000MB_REG_TPS_CODE_RATE_HP),
641 rd(DIB3000MB_REG_TPS_CODE_RATE_LP),
642 rd(DIB3000MB_REG_TPS_GUARD_TIME),
643 rd(DIB3000MB_REG_TPS_FFT),
644 rd(DIB3000MB_REG_TPS_CELL_ID));
645
646 //*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
647 return 0;
648}
649
650static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber)
651{
652 struct dib3000_state* state = fe->demodulator_priv;
653
654 *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB));
655 return 0;
656}
657
658/* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */
659static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
660{
661 struct dib3000_state* state = fe->demodulator_priv;
662
663 *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170;
664 return 0;
665}
666
667static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr)
668{
669 struct dib3000_state* state = fe->demodulator_priv;
670 short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER);
671 int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) |
672 rd(DIB3000MB_REG_NOISE_POWER_LSB);
673 *snr = (sigpow << 8) / ((icipow > 0) ? icipow : 1);
674 return 0;
675}
676
677static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
678{
679 struct dib3000_state* state = fe->demodulator_priv;
680
681 *unc = rd(DIB3000MB_REG_PACKET_ERROR_RATE);
682 return 0;
683}
684
685static int dib3000mb_sleep(struct dvb_frontend* fe)
686{
687 struct dib3000_state* state = fe->demodulator_priv;
688 deb_info("dib3000mb is going to bed.\n");
689 wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN);
690 return 0;
691}
692
693static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
694{
695 tune->min_delay_ms = 800;
696 return 0;
697}
698
699static int dib3000mb_fe_init_nonmobile(struct dvb_frontend* fe)
700{
701 return dib3000mb_fe_init(fe, 0);
702}
703
704static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep)
705{
706 return dib3000mb_set_frontend(fe, fep, 1);
707}
708
709static void dib3000mb_release(struct dvb_frontend* fe)
710{
711 struct dib3000_state *state = fe->demodulator_priv;
712 kfree(state);
713}
714
715/* pid filter and transfer stuff */
716static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
717{
718 struct dib3000_state *state = fe->demodulator_priv;
719 pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
720 wr(index+DIB3000MB_REG_FIRST_PID,pid);
721 return 0;
722}
723
724static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff)
725{
726 struct dib3000_state *state = fe->demodulator_priv;
727
728 deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
729 if (onoff) {
730 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_ACTIVATE);
731 } else {
732 wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT);
733 }
734 return 0;
735}
736
737static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff)
738{
739 struct dib3000_state *state = fe->demodulator_priv;
740 deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
741 wr(DIB3000MB_REG_PID_PARSE,onoff);
742 return 0;
743}
744
745static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr)
746{
747 struct dib3000_state *state = fe->demodulator_priv;
748 if (onoff) {
749 wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
750 } else {
751 wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
752 }
753 return 0;
754}
755
756static struct dvb_frontend_ops dib3000mb_ops;
757
758struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
759 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
760{
761 struct dib3000_state* state = NULL;
762
763 /* allocate memory for the internal state */
764 state = kzalloc(sizeof(struct dib3000_state), GFP_KERNEL);
765 if (state == NULL)
766 goto error;
767
768 /* setup the state */
769 state->i2c = i2c;
770 memcpy(&state->config,config,sizeof(struct dib3000_config));
771
772 /* check for the correct demod */
773 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
774 goto error;
775
776 if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID)
777 goto error;
778
779 /* create dvb_frontend */
780 memcpy(&state->frontend.ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops));
781 state->frontend.demodulator_priv = state;
782
783 /* set the xfer operations */
784 xfer_ops->pid_parse = dib3000mb_pid_parse;
785 xfer_ops->fifo_ctrl = dib3000mb_fifo_control;
786 xfer_ops->pid_ctrl = dib3000mb_pid_control;
787 xfer_ops->tuner_pass_ctrl = dib3000mb_tuner_pass_ctrl;
788
789 return &state->frontend;
790
791error:
792 kfree(state);
793 return NULL;
794}
795
796static struct dvb_frontend_ops dib3000mb_ops = {
797
798 .info = {
799 .name = "DiBcom 3000M-B DVB-T",
800 .type = FE_OFDM,
801 .frequency_min = 44250000,
802 .frequency_max = 867250000,
803 .frequency_stepsize = 62500,
804 .caps = FE_CAN_INVERSION_AUTO |
805 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
806 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
807 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
808 FE_CAN_TRANSMISSION_MODE_AUTO |
809 FE_CAN_GUARD_INTERVAL_AUTO |
810 FE_CAN_RECOVER |
811 FE_CAN_HIERARCHY_AUTO,
812 },
813
814 .release = dib3000mb_release,
815
816 .init = dib3000mb_fe_init_nonmobile,
817 .sleep = dib3000mb_sleep,
818
819 .set_frontend = dib3000mb_set_frontend_and_tuner,
820 .get_frontend = dib3000mb_get_frontend,
821 .get_tune_settings = dib3000mb_fe_get_tune_settings,
822
823 .read_status = dib3000mb_read_status,
824 .read_ber = dib3000mb_read_ber,
825 .read_signal_strength = dib3000mb_read_signal_strength,
826 .read_snr = dib3000mb_read_snr,
827 .read_ucblocks = dib3000mb_read_unc_blocks,
828};
829
830MODULE_AUTHOR(DRIVER_AUTHOR);
831MODULE_DESCRIPTION(DRIVER_DESC);
832MODULE_LICENSE("GPL");
833
834EXPORT_SYMBOL(dib3000mb_attach);
diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h
new file mode 100644
index 00000000000..16c526591f3
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mb_priv.h
@@ -0,0 +1,556 @@
1/*
2 * dib3000mb_priv.h
3 *
4 * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 * for more information see dib3000mb.c .
11 */
12
13#ifndef __DIB3000MB_PRIV_H_INCLUDED__
14#define __DIB3000MB_PRIV_H_INCLUDED__
15
16/* info and err, taken from usb.h, if there is anything available like by default. */
17#define err(format, arg...) printk(KERN_ERR "dib3000: " format "\n" , ## arg)
18#define info(format, arg...) printk(KERN_INFO "dib3000: " format "\n" , ## arg)
19#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg)
20
21/* handy shortcuts */
22#define rd(reg) dib3000_read_reg(state,reg)
23
24#define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \
25 { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; }
26
27#define wr_foreach(a,v) { int i; \
28 if (sizeof(a) != sizeof(v)) \
29 err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\
30 for (i=0; i < sizeof(a)/sizeof(u16); i++) \
31 wr(a[i],v[i]); \
32 }
33
34#define set_or(reg,val) wr(reg,rd(reg) | val)
35
36#define set_and(reg,val) wr(reg,rd(reg) & val)
37
38/* debug */
39
40#define dprintk(level,args...) \
41 do { if ((debug & level)) { printk(args); } } while (0)
42
43/* mask for enabling a specific pid for the pid_filter */
44#define DIB3000_ACTIVATE_PID_FILTERING (0x2000)
45
46/* common values for tuning */
47#define DIB3000_ALPHA_0 ( 0)
48#define DIB3000_ALPHA_1 ( 1)
49#define DIB3000_ALPHA_2 ( 2)
50#define DIB3000_ALPHA_4 ( 4)
51
52#define DIB3000_CONSTELLATION_QPSK ( 0)
53#define DIB3000_CONSTELLATION_16QAM ( 1)
54#define DIB3000_CONSTELLATION_64QAM ( 2)
55
56#define DIB3000_GUARD_TIME_1_32 ( 0)
57#define DIB3000_GUARD_TIME_1_16 ( 1)
58#define DIB3000_GUARD_TIME_1_8 ( 2)
59#define DIB3000_GUARD_TIME_1_4 ( 3)
60
61#define DIB3000_TRANSMISSION_MODE_2K ( 0)
62#define DIB3000_TRANSMISSION_MODE_8K ( 1)
63
64#define DIB3000_SELECT_LP ( 0)
65#define DIB3000_SELECT_HP ( 1)
66
67#define DIB3000_FEC_1_2 ( 1)
68#define DIB3000_FEC_2_3 ( 2)
69#define DIB3000_FEC_3_4 ( 3)
70#define DIB3000_FEC_5_6 ( 5)
71#define DIB3000_FEC_7_8 ( 7)
72
73#define DIB3000_HRCH_OFF ( 0)
74#define DIB3000_HRCH_ON ( 1)
75
76#define DIB3000_DDS_INVERSION_OFF ( 0)
77#define DIB3000_DDS_INVERSION_ON ( 1)
78
79#define DIB3000_TUNER_WRITE_ENABLE(a) (0xffff & (a << 8))
80#define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7)))
81
82#define DIB3000_REG_MANUFACTOR_ID ( 1025)
83#define DIB3000_I2C_ID_DIBCOM (0x01b3)
84
85#define DIB3000_REG_DEVICE_ID ( 1026)
86#define DIB3000MB_DEVICE_ID (0x3000)
87#define DIB3000MC_DEVICE_ID (0x3001)
88#define DIB3000P_DEVICE_ID (0x3002)
89
90/* frontend state */
91struct dib3000_state {
92 struct i2c_adapter* i2c;
93
94/* configuration settings */
95 struct dib3000_config config;
96
97 struct dvb_frontend frontend;
98 int timing_offset;
99 int timing_offset_comp_done;
100
101 fe_bandwidth_t last_tuned_bw;
102 u32 last_tuned_freq;
103};
104
105/* register addresses and some of their default values */
106
107/* restart subsystems */
108#define DIB3000MB_REG_RESTART ( 0)
109
110#define DIB3000MB_RESTART_OFF ( 0)
111#define DIB3000MB_RESTART_AUTO_SEARCH (1 << 1)
112#define DIB3000MB_RESTART_CTRL (1 << 2)
113#define DIB3000MB_RESTART_AGC (1 << 3)
114
115/* FFT size */
116#define DIB3000MB_REG_FFT ( 1)
117
118/* Guard time */
119#define DIB3000MB_REG_GUARD_TIME ( 2)
120
121/* QAM */
122#define DIB3000MB_REG_QAM ( 3)
123
124/* Alpha coefficient high priority Viterbi algorithm */
125#define DIB3000MB_REG_VIT_ALPHA ( 4)
126
127/* spectrum inversion */
128#define DIB3000MB_REG_DDS_INV ( 5)
129
130/* DDS frequency value (IF position) ad ? values don't match reg_3000mb.txt */
131#define DIB3000MB_REG_DDS_FREQ_MSB ( 6)
132#define DIB3000MB_REG_DDS_FREQ_LSB ( 7)
133#define DIB3000MB_DDS_FREQ_MSB ( 178)
134#define DIB3000MB_DDS_FREQ_LSB ( 8990)
135
136/* timing frequency (carrier spacing) */
137static u16 dib3000mb_reg_timing_freq[] = { 8,9 };
138static u16 dib3000mb_timing_freq[][2] = {
139 { 126 , 48873 }, /* 6 MHz */
140 { 147 , 57019 }, /* 7 MHz */
141 { 168 , 65164 }, /* 8 MHz */
142};
143
144/* impulse noise parameter */
145/* 36 ??? */
146
147static u16 dib3000mb_reg_impulse_noise[] = { 10,11,12,15,36 };
148
149enum dib3000mb_impulse_noise_type {
150 DIB3000MB_IMPNOISE_OFF,
151 DIB3000MB_IMPNOISE_MOBILE,
152 DIB3000MB_IMPNOISE_FIXED,
153 DIB3000MB_IMPNOISE_DEFAULT
154};
155
156static u16 dib3000mb_impulse_noise_values[][5] = {
157 { 0x0000, 0x0004, 0x0014, 0x01ff, 0x0399 }, /* off */
158 { 0x0001, 0x0004, 0x0014, 0x01ff, 0x037b }, /* mobile */
159 { 0x0001, 0x0004, 0x0020, 0x01bd, 0x0399 }, /* fixed */
160 { 0x0000, 0x0002, 0x000a, 0x01ff, 0x0399 }, /* default */
161};
162
163/*
164 * Dual Automatic-Gain-Control
165 * - gains RF in tuner (AGC1)
166 * - gains IF after filtering (AGC2)
167 */
168
169/* also from 16 to 18 */
170static u16 dib3000mb_reg_agc_gain[] = {
171 19,20,21,22,23,24,25,26,27,28,29,30,31,32
172};
173
174static u16 dib3000mb_default_agc_gain[] =
175 { 0x0001, 52429, 623, 128, 166, 195, 61, /* RF ??? */
176 0x0001, 53766, 38011, 0, 90, 33, 23 }; /* IF ??? */
177
178/* phase noise */
179/* 36 is set when setting the impulse noise */
180static u16 dib3000mb_reg_phase_noise[] = { 33,34,35,37,38 };
181
182static u16 dib3000mb_default_noise_phase[] = { 2, 544, 0, 5, 4 };
183
184/* lock duration */
185static u16 dib3000mb_reg_lock_duration[] = { 39,40 };
186static u16 dib3000mb_default_lock_duration[] = { 135, 135 };
187
188/* AGC loop bandwidth */
189static u16 dib3000mb_reg_agc_bandwidth[] = { 43,44,45,46,47,48,49,50 };
190
191static u16 dib3000mb_agc_bandwidth_low[] =
192 { 2088, 10, 2088, 10, 3448, 5, 3448, 5 };
193static u16 dib3000mb_agc_bandwidth_high[] =
194 { 2349, 5, 2349, 5, 2586, 2, 2586, 2 };
195
196/*
197 * lock0 definition (coff_lock)
198 */
199#define DIB3000MB_REG_LOCK0_MASK ( 51)
200#define DIB3000MB_LOCK0_DEFAULT ( 4)
201
202/*
203 * lock1 definition (cpil_lock)
204 * for auto search
205 * which values hide behind the lock masks
206 */
207#define DIB3000MB_REG_LOCK1_MASK ( 52)
208#define DIB3000MB_LOCK1_SEARCH_4 (0x0004)
209#define DIB3000MB_LOCK1_SEARCH_2048 (0x0800)
210#define DIB3000MB_LOCK1_DEFAULT (0x0001)
211
212/*
213 * lock2 definition (fec_lock) */
214#define DIB3000MB_REG_LOCK2_MASK ( 53)
215#define DIB3000MB_LOCK2_DEFAULT (0x0080)
216
217/*
218 * SEQ ? what was that again ... :)
219 * changes when, inversion, guard time and fft is
220 * either automatically detected or not
221 */
222#define DIB3000MB_REG_SEQ ( 54)
223
224/* bandwidth */
225static u16 dib3000mb_reg_bandwidth[] = { 55,56,57,58,59,60,61,62,63,64,65,66,67 };
226static u16 dib3000mb_bandwidth_6mhz[] =
227 { 0, 33, 53312, 112, 46635, 563, 36565, 0, 1000, 0, 1010, 1, 45264 };
228
229static u16 dib3000mb_bandwidth_7mhz[] =
230 { 0, 28, 64421, 96, 39973, 483, 3255, 0, 1000, 0, 1010, 1, 45264 };
231
232static u16 dib3000mb_bandwidth_8mhz[] =
233 { 0, 25, 23600, 84, 34976, 422, 43808, 0, 1000, 0, 1010, 1, 45264 };
234
235#define DIB3000MB_REG_UNK_68 ( 68)
236#define DIB3000MB_UNK_68 ( 0)
237
238#define DIB3000MB_REG_UNK_69 ( 69)
239#define DIB3000MB_UNK_69 ( 0)
240
241#define DIB3000MB_REG_UNK_71 ( 71)
242#define DIB3000MB_UNK_71 ( 0)
243
244#define DIB3000MB_REG_UNK_77 ( 77)
245#define DIB3000MB_UNK_77 ( 6)
246
247#define DIB3000MB_REG_UNK_78 ( 78)
248#define DIB3000MB_UNK_78 (0x0080)
249
250/* isi */
251#define DIB3000MB_REG_ISI ( 79)
252#define DIB3000MB_ISI_ACTIVATE ( 0)
253#define DIB3000MB_ISI_INHIBIT ( 1)
254
255/* sync impovement */
256#define DIB3000MB_REG_SYNC_IMPROVEMENT ( 84)
257#define DIB3000MB_SYNC_IMPROVE_2K_1_8 ( 3)
258#define DIB3000MB_SYNC_IMPROVE_DEFAULT ( 0)
259
260/* phase noise compensation inhibition */
261#define DIB3000MB_REG_PHASE_NOISE ( 87)
262#define DIB3000MB_PHASE_NOISE_DEFAULT ( 0)
263
264#define DIB3000MB_REG_UNK_92 ( 92)
265#define DIB3000MB_UNK_92 (0x0080)
266
267#define DIB3000MB_REG_UNK_96 ( 96)
268#define DIB3000MB_UNK_96 (0x0010)
269
270#define DIB3000MB_REG_UNK_97 ( 97)
271#define DIB3000MB_UNK_97 (0x0009)
272
273/* mobile mode ??? */
274#define DIB3000MB_REG_MOBILE_MODE ( 101)
275#define DIB3000MB_MOBILE_MODE_ON ( 1)
276#define DIB3000MB_MOBILE_MODE_OFF ( 0)
277
278#define DIB3000MB_REG_UNK_106 ( 106)
279#define DIB3000MB_UNK_106 (0x0080)
280
281#define DIB3000MB_REG_UNK_107 ( 107)
282#define DIB3000MB_UNK_107 (0x0080)
283
284#define DIB3000MB_REG_UNK_108 ( 108)
285#define DIB3000MB_UNK_108 (0x0080)
286
287/* fft */
288#define DIB3000MB_REG_UNK_121 ( 121)
289#define DIB3000MB_UNK_121_2K ( 7)
290#define DIB3000MB_UNK_121_DEFAULT ( 5)
291
292#define DIB3000MB_REG_UNK_122 ( 122)
293#define DIB3000MB_UNK_122 ( 2867)
294
295/* QAM for mobile mode */
296#define DIB3000MB_REG_MOBILE_MODE_QAM ( 126)
297#define DIB3000MB_MOBILE_MODE_QAM_64 ( 3)
298#define DIB3000MB_MOBILE_MODE_QAM_QPSK_16 ( 1)
299#define DIB3000MB_MOBILE_MODE_QAM_OFF ( 0)
300
301/*
302 * data diversity when having more than one chip on-board
303 * see also DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY
304 */
305#define DIB3000MB_REG_DATA_IN_DIVERSITY ( 127)
306#define DIB3000MB_DATA_DIVERSITY_IN_OFF ( 0)
307#define DIB3000MB_DATA_DIVERSITY_IN_ON ( 2)
308
309/* vit hrch */
310#define DIB3000MB_REG_VIT_HRCH ( 128)
311
312/* vit code rate */
313#define DIB3000MB_REG_VIT_CODE_RATE ( 129)
314
315/* vit select hp */
316#define DIB3000MB_REG_VIT_HP ( 130)
317
318/* time frame for Bit-Error-Rate calculation */
319#define DIB3000MB_REG_BERLEN ( 135)
320#define DIB3000MB_BERLEN_LONG ( 0)
321#define DIB3000MB_BERLEN_DEFAULT ( 1)
322#define DIB3000MB_BERLEN_MEDIUM ( 2)
323#define DIB3000MB_BERLEN_SHORT ( 3)
324
325/* 142 - 152 FIFO parameters
326 * which is what ?
327 */
328
329#define DIB3000MB_REG_FIFO_142 ( 142)
330#define DIB3000MB_FIFO_142 ( 0)
331
332/* MPEG2 TS output mode */
333#define DIB3000MB_REG_MPEG2_OUT_MODE ( 143)
334#define DIB3000MB_MPEG2_OUT_MODE_204 ( 0)
335#define DIB3000MB_MPEG2_OUT_MODE_188 ( 1)
336
337#define DIB3000MB_REG_PID_PARSE ( 144)
338#define DIB3000MB_PID_PARSE_INHIBIT ( 0)
339#define DIB3000MB_PID_PARSE_ACTIVATE ( 1)
340
341#define DIB3000MB_REG_FIFO ( 145)
342#define DIB3000MB_FIFO_INHIBIT ( 1)
343#define DIB3000MB_FIFO_ACTIVATE ( 0)
344
345#define DIB3000MB_REG_FIFO_146 ( 146)
346#define DIB3000MB_FIFO_146 ( 3)
347
348#define DIB3000MB_REG_FIFO_147 ( 147)
349#define DIB3000MB_FIFO_147 (0x0100)
350
351/*
352 * pidfilter
353 * it is not a hardware pidfilter but a filter which drops all pids
354 * except the ones set. Necessary because of the limited USB1.1 bandwidth.
355 * regs 153-168
356 */
357
358#define DIB3000MB_REG_FIRST_PID ( 153)
359#define DIB3000MB_NUM_PIDS ( 16)
360
361/*
362 * output mode
363 * USB devices have to use 'slave'-mode
364 * see also DIB3000MB_REG_ELECT_OUT_MODE
365 */
366#define DIB3000MB_REG_OUTPUT_MODE ( 169)
367#define DIB3000MB_OUTPUT_MODE_GATED_CLK ( 0)
368#define DIB3000MB_OUTPUT_MODE_CONT_CLK ( 1)
369#define DIB3000MB_OUTPUT_MODE_SERIAL ( 2)
370#define DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY ( 5)
371#define DIB3000MB_OUTPUT_MODE_SLAVE ( 6)
372
373/* irq event mask */
374#define DIB3000MB_REG_IRQ_EVENT_MASK ( 170)
375#define DIB3000MB_IRQ_EVENT_MASK ( 0)
376
377/* filter coefficients */
378static u16 dib3000mb_reg_filter_coeffs[] = {
379 171, 172, 173, 174, 175, 176, 177, 178,
380 179, 180, 181, 182, 183, 184, 185, 186,
381 188, 189, 190, 191, 192, 194
382};
383
384static u16 dib3000mb_filter_coeffs[] = {
385 226, 160, 29,
386 979, 998, 19,
387 22, 1019, 1006,
388 1022, 12, 6,
389 1017, 1017, 3,
390 6, 1019,
391 1021, 2, 3,
392 1, 0,
393};
394
395/*
396 * mobile algorithm (when you are moving with your device)
397 * but not faster than 90 km/h
398 */
399#define DIB3000MB_REG_MOBILE_ALGO ( 195)
400#define DIB3000MB_MOBILE_ALGO_ON ( 0)
401#define DIB3000MB_MOBILE_ALGO_OFF ( 1)
402
403/* multiple demodulators algorithm */
404#define DIB3000MB_REG_MULTI_DEMOD_MSB ( 206)
405#define DIB3000MB_REG_MULTI_DEMOD_LSB ( 207)
406
407/* terminator, no more demods */
408#define DIB3000MB_MULTI_DEMOD_MSB ( 32767)
409#define DIB3000MB_MULTI_DEMOD_LSB ( 4095)
410
411/* bring the device into a known */
412#define DIB3000MB_REG_RESET_DEVICE ( 1024)
413#define DIB3000MB_RESET_DEVICE (0x812c)
414#define DIB3000MB_RESET_DEVICE_RST ( 0)
415
416/* hardware clock configuration */
417#define DIB3000MB_REG_CLOCK ( 1027)
418#define DIB3000MB_CLOCK_DEFAULT (0x9000)
419#define DIB3000MB_CLOCK_DIVERSITY (0x92b0)
420
421/* power down config */
422#define DIB3000MB_REG_POWER_CONTROL ( 1028)
423#define DIB3000MB_POWER_DOWN ( 1)
424#define DIB3000MB_POWER_UP ( 0)
425
426/* electrical output mode */
427#define DIB3000MB_REG_ELECT_OUT_MODE ( 1029)
428#define DIB3000MB_ELECT_OUT_MODE_OFF ( 0)
429#define DIB3000MB_ELECT_OUT_MODE_ON ( 1)
430
431/* set the tuner i2c address */
432#define DIB3000MB_REG_TUNER ( 1089)
433
434/* monitoring registers (read only) */
435
436/* agc loop locked (size: 1) */
437#define DIB3000MB_REG_AGC_LOCK ( 324)
438
439/* agc power (size: 16) */
440#define DIB3000MB_REG_AGC_POWER ( 325)
441
442/* agc1 value (16) */
443#define DIB3000MB_REG_AGC1_VALUE ( 326)
444
445/* agc2 value (16) */
446#define DIB3000MB_REG_AGC2_VALUE ( 327)
447
448/* total RF power (16), can be used for signal strength */
449#define DIB3000MB_REG_RF_POWER ( 328)
450
451/* dds_frequency with offset (24) */
452#define DIB3000MB_REG_DDS_VALUE_MSB ( 339)
453#define DIB3000MB_REG_DDS_VALUE_LSB ( 340)
454
455/* timing offset signed (24) */
456#define DIB3000MB_REG_TIMING_OFFSET_MSB ( 341)
457#define DIB3000MB_REG_TIMING_OFFSET_LSB ( 342)
458
459/* fft start position (13) */
460#define DIB3000MB_REG_FFT_WINDOW_POS ( 353)
461
462/* carriers locked (1) */
463#define DIB3000MB_REG_CARRIER_LOCK ( 355)
464
465/* noise power (24) */
466#define DIB3000MB_REG_NOISE_POWER_MSB ( 372)
467#define DIB3000MB_REG_NOISE_POWER_LSB ( 373)
468
469#define DIB3000MB_REG_MOBILE_NOISE_MSB ( 374)
470#define DIB3000MB_REG_MOBILE_NOISE_LSB ( 375)
471
472/*
473 * signal power (16), this and the above can be
474 * used to calculate the signal/noise - ratio
475 */
476#define DIB3000MB_REG_SIGNAL_POWER ( 380)
477
478/* mer (24) */
479#define DIB3000MB_REG_MER_MSB ( 381)
480#define DIB3000MB_REG_MER_LSB ( 382)
481
482/*
483 * Transmission Parameter Signalling (TPS)
484 * the following registers can be used to get TPS-information.
485 * The values are according to the DVB-T standard.
486 */
487
488/* TPS locked (1) */
489#define DIB3000MB_REG_TPS_LOCK ( 394)
490
491/* QAM from TPS (2) (values according to DIB3000MB_REG_QAM) */
492#define DIB3000MB_REG_TPS_QAM ( 398)
493
494/* hierarchy from TPS (1) */
495#define DIB3000MB_REG_TPS_HRCH ( 399)
496
497/* alpha from TPS (3) (values according to DIB3000MB_REG_VIT_ALPHA) */
498#define DIB3000MB_REG_TPS_VIT_ALPHA ( 400)
499
500/* code rate high priority from TPS (3) (values according to DIB3000MB_FEC_*) */
501#define DIB3000MB_REG_TPS_CODE_RATE_HP ( 401)
502
503/* code rate low priority from TPS (3) if DIB3000MB_REG_TPS_VIT_ALPHA */
504#define DIB3000MB_REG_TPS_CODE_RATE_LP ( 402)
505
506/* guard time from TPS (2) (values according to DIB3000MB_REG_GUARD_TIME */
507#define DIB3000MB_REG_TPS_GUARD_TIME ( 403)
508
509/* fft size from TPS (2) (values according to DIB3000MB_REG_FFT) */
510#define DIB3000MB_REG_TPS_FFT ( 404)
511
512/* cell id from TPS (16) */
513#define DIB3000MB_REG_TPS_CELL_ID ( 406)
514
515/* TPS (68) */
516#define DIB3000MB_REG_TPS_1 ( 408)
517#define DIB3000MB_REG_TPS_2 ( 409)
518#define DIB3000MB_REG_TPS_3 ( 410)
519#define DIB3000MB_REG_TPS_4 ( 411)
520#define DIB3000MB_REG_TPS_5 ( 412)
521
522/* bit error rate (before RS correction) (21) */
523#define DIB3000MB_REG_BER_MSB ( 414)
524#define DIB3000MB_REG_BER_LSB ( 415)
525
526/* packet error rate (uncorrected TS packets) (16) */
527#define DIB3000MB_REG_PACKET_ERROR_RATE ( 417)
528
529/* uncorrected packet count (16) */
530#define DIB3000MB_REG_UNC ( 420)
531
532/* viterbi locked (1) */
533#define DIB3000MB_REG_VIT_LCK ( 421)
534
535/* viterbi inidcator (16) */
536#define DIB3000MB_REG_VIT_INDICATOR ( 422)
537
538/* transport stream sync lock (1) */
539#define DIB3000MB_REG_TS_SYNC_LOCK ( 423)
540
541/* transport stream RS lock (1) */
542#define DIB3000MB_REG_TS_RS_LOCK ( 424)
543
544/* lock mask 0 value (1) */
545#define DIB3000MB_REG_LOCK0_VALUE ( 425)
546
547/* lock mask 1 value (1) */
548#define DIB3000MB_REG_LOCK1_VALUE ( 426)
549
550/* lock mask 2 value (1) */
551#define DIB3000MB_REG_LOCK2_VALUE ( 427)
552
553/* interrupt pending for auto search */
554#define DIB3000MB_REG_AS_IRQ_PENDING ( 434)
555
556#endif
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
new file mode 100644
index 00000000000..088e7fadbe3
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -0,0 +1,934 @@
1/*
2 * Driver for DiBcom DiB3000MC/P-demodulator.
3 *
4 * Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/)
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
7 * This code is partially based on the previous dib3000mc.c .
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2.
12 */
13
14#include <linux/kernel.h>
15#include <linux/slab.h>
16#include <linux/i2c.h>
17
18#include "dvb_frontend.h"
19
20#include "dib3000mc.h"
21
22static int debug;
23module_param(debug, int, 0644);
24MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
25
26static int buggy_sfn_workaround;
27module_param(buggy_sfn_workaround, int, 0644);
28MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
29
30#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0)
31
32struct dib3000mc_state {
33 struct dvb_frontend demod;
34 struct dib3000mc_config *cfg;
35
36 u8 i2c_addr;
37 struct i2c_adapter *i2c_adap;
38
39 struct dibx000_i2c_master i2c_master;
40
41 u32 timf;
42
43 fe_bandwidth_t current_bandwidth;
44
45 u16 dev_id;
46
47 u8 sfn_workaround_active :1;
48};
49
50static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
51{
52 u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
53 u8 rb[2];
54 struct i2c_msg msg[2] = {
55 { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
56 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
57 };
58
59 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
60 dprintk("i2c read error on %d\n",reg);
61
62 return (rb[0] << 8) | rb[1];
63}
64
65static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
66{
67 u8 b[4] = {
68 (reg >> 8) & 0xff, reg & 0xff,
69 (val >> 8) & 0xff, val & 0xff,
70 };
71 struct i2c_msg msg = {
72 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
73 };
74 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
75}
76
77static int dib3000mc_identify(struct dib3000mc_state *state)
78{
79 u16 value;
80 if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
81 dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
82 return -EREMOTEIO;
83 }
84
85 value = dib3000mc_read_word(state, 1026);
86 if (value != 0x3001 && value != 0x3002) {
87 dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value);
88 return -EREMOTEIO;
89 }
90 state->dev_id = value;
91
92 dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id);
93
94 return 0;
95}
96
97static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset)
98{
99 u32 timf;
100
101 if (state->timf == 0) {
102 timf = 1384402; // default value for 8MHz
103 if (update_offset)
104 msleep(200); // first time we do an update
105 } else
106 timf = state->timf;
107
108 timf *= (bw / 1000);
109
110 if (update_offset) {
111 s16 tim_offs = dib3000mc_read_word(state, 416);
112
113 if (tim_offs & 0x2000)
114 tim_offs -= 0x4000;
115
116 if (nfft == TRANSMISSION_MODE_2K)
117 tim_offs *= 4;
118
119 timf += tim_offs;
120 state->timf = timf / (bw / 1000);
121 }
122
123 dprintk("timf: %d\n", timf);
124
125 dib3000mc_write_word(state, 23, (u16) (timf >> 16));
126 dib3000mc_write_word(state, 24, (u16) (timf ) & 0xffff);
127
128 return 0;
129}
130
131static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
132{
133 u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
134 if (state->cfg->pwm3_inversion) {
135 reg_51 = (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
136 reg_52 |= (1 << 2);
137 } else {
138 reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
139 reg_52 |= (1 << 8);
140 }
141 dib3000mc_write_word(state, 51, reg_51);
142 dib3000mc_write_word(state, 52, reg_52);
143
144 if (state->cfg->use_pwm3)
145 dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
146 else
147 dib3000mc_write_word(state, 245, 0);
148
149 dib3000mc_write_word(state, 1040, 0x3);
150 return 0;
151}
152
153static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
154{
155 int ret = 0;
156 u16 fifo_threshold = 1792;
157 u16 outreg = 0;
158 u16 outmode = 0;
159 u16 elecout = 1;
160 u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
161
162 dprintk("-I- Setting output mode for demod %p to %d\n",
163 &state->demod, mode);
164
165 switch (mode) {
166 case OUTMODE_HIGH_Z: // disable
167 elecout = 0;
168 break;
169 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
170 outmode = 0;
171 break;
172 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
173 outmode = 1;
174 break;
175 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
176 outmode = 2;
177 break;
178 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
179 elecout = 3;
180 /*ADDR @ 206 :
181 P_smo_error_discard [1;6:6] = 0
182 P_smo_rs_discard [1;5:5] = 0
183 P_smo_pid_parse [1;4:4] = 0
184 P_smo_fifo_flush [1;3:3] = 0
185 P_smo_mode [2;2:1] = 11
186 P_smo_ovf_prot [1;0:0] = 0
187 */
188 smo_reg |= 3 << 1;
189 fifo_threshold = 512;
190 outmode = 5;
191 break;
192 case OUTMODE_DIVERSITY:
193 outmode = 4;
194 elecout = 1;
195 break;
196 default:
197 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
198 outmode = 0;
199 break;
200 }
201
202 if ((state->cfg->output_mpeg2_in_188_bytes))
203 smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1
204
205 outreg = dib3000mc_read_word(state, 244) & 0x07FF;
206 outreg |= (outmode << 11);
207 ret |= dib3000mc_write_word(state, 244, outreg);
208 ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/
209 ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */
210 ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */
211 return ret;
212}
213
214static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw)
215{
216 u16 bw_cfg[6] = { 0 };
217 u16 imp_bw_cfg[3] = { 0 };
218 u16 reg;
219
220/* settings here are for 27.7MHz */
221 switch (bw) {
222 case 8000:
223 bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
224 imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
225 break;
226
227 case 7000:
228 bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
229 imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
230 break;
231
232 case 6000:
233 bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
234 imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
235 break;
236
237 case 5000:
238 bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
239 imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
240 break;
241
242 default: return -EINVAL;
243 }
244
245 for (reg = 6; reg < 12; reg++)
246 dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
247 dib3000mc_write_word(state, 12, 0x0000);
248 dib3000mc_write_word(state, 13, 0x03e8);
249 dib3000mc_write_word(state, 14, 0x0000);
250 dib3000mc_write_word(state, 15, 0x03f2);
251 dib3000mc_write_word(state, 16, 0x0001);
252 dib3000mc_write_word(state, 17, 0xb0d0);
253 // P_sec_len
254 dib3000mc_write_word(state, 18, 0x0393);
255 dib3000mc_write_word(state, 19, 0x8700);
256
257 for (reg = 55; reg < 58; reg++)
258 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
259
260 // Timing configuration
261 dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0);
262
263 return 0;
264}
265
266static u16 impulse_noise_val[29] =
267
268{
269 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
270 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
271 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
272};
273
274static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
275{
276 u16 i;
277 for (i = 58; i < 87; i++)
278 dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
279
280 if (nfft == TRANSMISSION_MODE_8K) {
281 dib3000mc_write_word(state, 58, 0x3b);
282 dib3000mc_write_word(state, 84, 0x00);
283 dib3000mc_write_word(state, 85, 0x8200);
284 }
285
286 dib3000mc_write_word(state, 34, 0x1294);
287 dib3000mc_write_word(state, 35, 0x1ff8);
288 if (mode == 1)
289 dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
290}
291
292static int dib3000mc_init(struct dvb_frontend *demod)
293{
294 struct dib3000mc_state *state = demod->demodulator_priv;
295 struct dibx000_agc_config *agc = state->cfg->agc;
296
297 // Restart Configuration
298 dib3000mc_write_word(state, 1027, 0x8000);
299 dib3000mc_write_word(state, 1027, 0x0000);
300
301 // power up the demod + mobility configuration
302 dib3000mc_write_word(state, 140, 0x0000);
303 dib3000mc_write_word(state, 1031, 0);
304
305 if (state->cfg->mobile_mode) {
306 dib3000mc_write_word(state, 139, 0x0000);
307 dib3000mc_write_word(state, 141, 0x0000);
308 dib3000mc_write_word(state, 175, 0x0002);
309 dib3000mc_write_word(state, 1032, 0x0000);
310 } else {
311 dib3000mc_write_word(state, 139, 0x0001);
312 dib3000mc_write_word(state, 141, 0x0000);
313 dib3000mc_write_word(state, 175, 0x0000);
314 dib3000mc_write_word(state, 1032, 0x012C);
315 }
316 dib3000mc_write_word(state, 1033, 0x0000);
317
318 // P_clk_cfg
319 dib3000mc_write_word(state, 1037, 0x3130);
320
321 // other configurations
322
323 // P_ctrl_sfreq
324 dib3000mc_write_word(state, 33, (5 << 0));
325 dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
326
327 // Phase noise control
328 // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
329 dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
330
331 if (state->cfg->phase_noise_mode == 0)
332 dib3000mc_write_word(state, 111, 0x00);
333 else
334 dib3000mc_write_word(state, 111, 0x02);
335
336 // P_agc_global
337 dib3000mc_write_word(state, 50, 0x8000);
338
339 // agc setup misc
340 dib3000mc_setup_pwm_state(state);
341
342 // P_agc_counter_lock
343 dib3000mc_write_word(state, 53, 0x87);
344 // P_agc_counter_unlock
345 dib3000mc_write_word(state, 54, 0x87);
346
347 /* agc */
348 dib3000mc_write_word(state, 36, state->cfg->max_time);
349 dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0));
350 dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
351 dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
352
353 // set_agc_loop_Bw
354 dib3000mc_write_word(state, 40, 0x0179);
355 dib3000mc_write_word(state, 41, 0x03f0);
356
357 dib3000mc_write_word(state, 42, agc->agc1_max);
358 dib3000mc_write_word(state, 43, agc->agc1_min);
359 dib3000mc_write_word(state, 44, agc->agc2_max);
360 dib3000mc_write_word(state, 45, agc->agc2_min);
361 dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
362 dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
363 dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
364 dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
365
366// Begin: TimeOut registers
367 // P_pha3_thres
368 dib3000mc_write_word(state, 110, 3277);
369 // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
370 dib3000mc_write_word(state, 26, 0x6680);
371 // lock_mask0
372 dib3000mc_write_word(state, 1, 4);
373 // lock_mask1
374 dib3000mc_write_word(state, 2, 4);
375 // lock_mask2
376 dib3000mc_write_word(state, 3, 0x1000);
377 // P_search_maxtrial=1
378 dib3000mc_write_word(state, 5, 1);
379
380 dib3000mc_set_bandwidth(state, 8000);
381
382 // div_lock_mask
383 dib3000mc_write_word(state, 4, 0x814);
384
385 dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
386 dib3000mc_write_word(state, 22, 0x463d);
387
388 // Spurious rm cfg
389 // P_cspu_regul, P_cspu_win_cut
390 dib3000mc_write_word(state, 120, 0x200f);
391 // P_adp_selec_monit
392 dib3000mc_write_word(state, 134, 0);
393
394 // Fec cfg
395 dib3000mc_write_word(state, 195, 0x10);
396
397 // diversity register: P_dvsy_sync_wait..
398 dib3000mc_write_word(state, 180, 0x2FF0);
399
400 // Impulse noise configuration
401 dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K);
402
403 // output mode set-up
404 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
405
406 /* close the i2c-gate */
407 dib3000mc_write_word(state, 769, (1 << 7) );
408
409 return 0;
410}
411
412static int dib3000mc_sleep(struct dvb_frontend *demod)
413{
414 struct dib3000mc_state *state = demod->demodulator_priv;
415
416 dib3000mc_write_word(state, 1031, 0xFFFF);
417 dib3000mc_write_word(state, 1032, 0xFFFF);
418 dib3000mc_write_word(state, 1033, 0xFFF0);
419
420 return 0;
421}
422
423static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
424{
425 u16 cfg[4] = { 0 },reg;
426 switch (qam) {
427 case QPSK:
428 cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
429 break;
430 case QAM_16:
431 cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
432 break;
433 case QAM_64:
434 cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
435 break;
436 }
437 for (reg = 129; reg < 133; reg++)
438 dib3000mc_write_word(state, reg, cfg[reg - 129]);
439}
440
441static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dvb_frontend_parameters *ch, u16 seq)
442{
443 u16 value;
444 dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
445 dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 0);
446
447// if (boost)
448// dib3000mc_write_word(state, 100, (11 << 6) + 6);
449// else
450 dib3000mc_write_word(state, 100, (16 << 6) + 9);
451
452 dib3000mc_write_word(state, 1027, 0x0800);
453 dib3000mc_write_word(state, 1027, 0x0000);
454
455 //Default cfg isi offset adp
456 dib3000mc_write_word(state, 26, 0x6680);
457 dib3000mc_write_word(state, 29, 0x1273);
458 dib3000mc_write_word(state, 33, 5);
459 dib3000mc_set_adp_cfg(state, QAM_16);
460 dib3000mc_write_word(state, 133, 15564);
461
462 dib3000mc_write_word(state, 12 , 0x0);
463 dib3000mc_write_word(state, 13 , 0x3e8);
464 dib3000mc_write_word(state, 14 , 0x0);
465 dib3000mc_write_word(state, 15 , 0x3f2);
466
467 dib3000mc_write_word(state, 93,0);
468 dib3000mc_write_word(state, 94,0);
469 dib3000mc_write_word(state, 95,0);
470 dib3000mc_write_word(state, 96,0);
471 dib3000mc_write_word(state, 97,0);
472 dib3000mc_write_word(state, 98,0);
473
474 dib3000mc_set_impulse_noise(state, 0, ch->u.ofdm.transmission_mode);
475
476 value = 0;
477 switch (ch->u.ofdm.transmission_mode) {
478 case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
479 default:
480 case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
481 }
482 switch (ch->u.ofdm.guard_interval) {
483 case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
484 case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
485 case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
486 default:
487 case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
488 }
489 switch (ch->u.ofdm.constellation) {
490 case QPSK: value |= (0 << 3); break;
491 case QAM_16: value |= (1 << 3); break;
492 default:
493 case QAM_64: value |= (2 << 3); break;
494 }
495 switch (HIERARCHY_1) {
496 case HIERARCHY_2: value |= 2; break;
497 case HIERARCHY_4: value |= 4; break;
498 default:
499 case HIERARCHY_1: value |= 1; break;
500 }
501 dib3000mc_write_word(state, 0, value);
502 dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
503
504 value = 0;
505 if (ch->u.ofdm.hierarchy_information == 1)
506 value |= (1 << 4);
507 if (1 == 1)
508 value |= 1;
509 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
510 case FEC_2_3: value |= (2 << 1); break;
511 case FEC_3_4: value |= (3 << 1); break;
512 case FEC_5_6: value |= (5 << 1); break;
513 case FEC_7_8: value |= (7 << 1); break;
514 default:
515 case FEC_1_2: value |= (1 << 1); break;
516 }
517 dib3000mc_write_word(state, 181, value);
518
519 // diversity synchro delay add 50% SFN margin
520 switch (ch->u.ofdm.transmission_mode) {
521 case TRANSMISSION_MODE_8K: value = 256; break;
522 case TRANSMISSION_MODE_2K:
523 default: value = 64; break;
524 }
525 switch (ch->u.ofdm.guard_interval) {
526 case GUARD_INTERVAL_1_16: value *= 2; break;
527 case GUARD_INTERVAL_1_8: value *= 4; break;
528 case GUARD_INTERVAL_1_4: value *= 8; break;
529 default:
530 case GUARD_INTERVAL_1_32: value *= 1; break;
531 }
532 value <<= 4;
533 value |= dib3000mc_read_word(state, 180) & 0x000f;
534 dib3000mc_write_word(state, 180, value);
535
536 // restart demod
537 value = dib3000mc_read_word(state, 0);
538 dib3000mc_write_word(state, 0, value | (1 << 9));
539 dib3000mc_write_word(state, 0, value);
540
541 msleep(30);
542
543 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->u.ofdm.transmission_mode);
544}
545
546static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *chan)
547{
548 struct dib3000mc_state *state = demod->demodulator_priv;
549 u16 reg;
550// u32 val;
551 struct dvb_frontend_parameters schan;
552
553 schan = *chan;
554
555 /* TODO what is that ? */
556
557 /* a channel for autosearch */
558 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
559 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
560 schan.u.ofdm.constellation = QAM_64;
561 schan.u.ofdm.code_rate_HP = FEC_2_3;
562 schan.u.ofdm.code_rate_LP = FEC_2_3;
563 schan.u.ofdm.hierarchy_information = 0;
564
565 dib3000mc_set_channel_cfg(state, &schan, 11);
566
567 reg = dib3000mc_read_word(state, 0);
568 dib3000mc_write_word(state, 0, reg | (1 << 8));
569 dib3000mc_read_word(state, 511);
570 dib3000mc_write_word(state, 0, reg);
571
572 return 0;
573}
574
575static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
576{
577 struct dib3000mc_state *state = demod->demodulator_priv;
578 u16 irq_pending = dib3000mc_read_word(state, 511);
579
580 if (irq_pending & 0x1) // failed
581 return 1;
582
583 if (irq_pending & 0x2) // succeeded
584 return 2;
585
586 return 0; // still pending
587}
588
589static int dib3000mc_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
590{
591 struct dib3000mc_state *state = demod->demodulator_priv;
592
593 // ** configure demod **
594 dib3000mc_set_channel_cfg(state, ch, 0);
595
596 // activates isi
597 if (state->sfn_workaround_active) {
598 dprintk("SFN workaround is active\n");
599 dib3000mc_write_word(state, 29, 0x1273);
600 dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift
601 } else {
602 dib3000mc_write_word(state, 29, 0x1073);
603 dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift
604 }
605
606 dib3000mc_set_adp_cfg(state, (u8)ch->u.ofdm.constellation);
607 if (ch->u.ofdm.transmission_mode == TRANSMISSION_MODE_8K) {
608 dib3000mc_write_word(state, 26, 38528);
609 dib3000mc_write_word(state, 33, 8);
610 } else {
611 dib3000mc_write_word(state, 26, 30336);
612 dib3000mc_write_word(state, 33, 6);
613 }
614
615 if (dib3000mc_read_word(state, 509) & 0x80)
616 dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 1);
617
618 return 0;
619}
620
621struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
622{
623 struct dib3000mc_state *st = demod->demodulator_priv;
624 return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
625}
626
627EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
628
629static int dib3000mc_get_frontend(struct dvb_frontend* fe,
630 struct dvb_frontend_parameters *fep)
631{
632 struct dib3000mc_state *state = fe->demodulator_priv;
633 u16 tps = dib3000mc_read_word(state,458);
634
635 fep->inversion = INVERSION_AUTO;
636
637 fep->u.ofdm.bandwidth = state->current_bandwidth;
638
639 switch ((tps >> 8) & 0x1) {
640 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
641 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
642 }
643
644 switch (tps & 0x3) {
645 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
646 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
647 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
648 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
649 }
650
651 switch ((tps >> 13) & 0x3) {
652 case 0: fep->u.ofdm.constellation = QPSK; break;
653 case 1: fep->u.ofdm.constellation = QAM_16; break;
654 case 2:
655 default: fep->u.ofdm.constellation = QAM_64; break;
656 }
657
658 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
659 /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
660
661 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
662 switch ((tps >> 5) & 0x7) {
663 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
664 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
665 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
666 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
667 case 7:
668 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
669
670 }
671
672 switch ((tps >> 2) & 0x7) {
673 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
674 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
675 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
676 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
677 case 7:
678 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
679 }
680
681 return 0;
682}
683
684static int dib3000mc_set_frontend(struct dvb_frontend* fe,
685 struct dvb_frontend_parameters *fep)
686{
687 struct dib3000mc_state *state = fe->demodulator_priv;
688 int ret;
689
690 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
691
692 state->current_bandwidth = fep->u.ofdm.bandwidth;
693 dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
694
695 /* maybe the parameter has been changed */
696 state->sfn_workaround_active = buggy_sfn_workaround;
697
698 if (fe->ops.tuner_ops.set_params) {
699 fe->ops.tuner_ops.set_params(fe, fep);
700 msleep(100);
701 }
702
703 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
704 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
705 fep->u.ofdm.constellation == QAM_AUTO ||
706 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
707 int i = 1000, found;
708
709 dib3000mc_autosearch_start(fe, fep);
710 do {
711 msleep(1);
712 found = dib3000mc_autosearch_is_irq(fe);
713 } while (found == 0 && i--);
714
715 dprintk("autosearch returns: %d\n",found);
716 if (found == 0 || found == 1)
717 return 0; // no channel found
718
719 dib3000mc_get_frontend(fe, fep);
720 }
721
722 ret = dib3000mc_tune(fe, fep);
723
724 /* make this a config parameter */
725 dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
726 return ret;
727}
728
729static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
730{
731 struct dib3000mc_state *state = fe->demodulator_priv;
732 u16 lock = dib3000mc_read_word(state, 509);
733
734 *stat = 0;
735
736 if (lock & 0x8000)
737 *stat |= FE_HAS_SIGNAL;
738 if (lock & 0x3000)
739 *stat |= FE_HAS_CARRIER;
740 if (lock & 0x0100)
741 *stat |= FE_HAS_VITERBI;
742 if (lock & 0x0010)
743 *stat |= FE_HAS_SYNC;
744 if (lock & 0x0008)
745 *stat |= FE_HAS_LOCK;
746
747 return 0;
748}
749
750static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
751{
752 struct dib3000mc_state *state = fe->demodulator_priv;
753 *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
754 return 0;
755}
756
757static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
758{
759 struct dib3000mc_state *state = fe->demodulator_priv;
760 *unc = dib3000mc_read_word(state, 508);
761 return 0;
762}
763
764static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
765{
766 struct dib3000mc_state *state = fe->demodulator_priv;
767 u16 val = dib3000mc_read_word(state, 392);
768 *strength = 65535 - val;
769 return 0;
770}
771
772static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
773{
774 *snr = 0x0000;
775 return 0;
776}
777
778static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
779{
780 tune->min_delay_ms = 1000;
781 return 0;
782}
783
784static void dib3000mc_release(struct dvb_frontend *fe)
785{
786 struct dib3000mc_state *state = fe->demodulator_priv;
787 dibx000_exit_i2c_master(&state->i2c_master);
788 kfree(state);
789}
790
791int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
792{
793 struct dib3000mc_state *state = fe->demodulator_priv;
794 dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0);
795 return 0;
796}
797EXPORT_SYMBOL(dib3000mc_pid_control);
798
799int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
800{
801 struct dib3000mc_state *state = fe->demodulator_priv;
802 u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
803 tmp |= (onoff << 4);
804 return dib3000mc_write_word(state, 206, tmp);
805}
806EXPORT_SYMBOL(dib3000mc_pid_parse);
807
808void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
809{
810 struct dib3000mc_state *state = fe->demodulator_priv;
811 state->cfg = cfg;
812}
813EXPORT_SYMBOL(dib3000mc_set_config);
814
815int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
816{
817 struct dib3000mc_state *dmcst;
818 int k;
819 u8 new_addr;
820
821 static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
822
823 dmcst = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
824 if (dmcst == NULL)
825 return -ENOMEM;
826
827 dmcst->i2c_adap = i2c;
828
829 for (k = no_of_demods-1; k >= 0; k--) {
830 dmcst->cfg = &cfg[k];
831
832 /* designated i2c address */
833 new_addr = DIB3000MC_I2C_ADDRESS[k];
834 dmcst->i2c_addr = new_addr;
835 if (dib3000mc_identify(dmcst) != 0) {
836 dmcst->i2c_addr = default_addr;
837 if (dib3000mc_identify(dmcst) != 0) {
838 dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
839 kfree(dmcst);
840 return -ENODEV;
841 }
842 }
843
844 dib3000mc_set_output_mode(dmcst, OUTMODE_MPEG2_PAR_CONT_CLK);
845
846 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
847 dib3000mc_write_word(dmcst, 1024, (new_addr << 3) | 0x1);
848 dmcst->i2c_addr = new_addr;
849 }
850
851 for (k = 0; k < no_of_demods; k++) {
852 dmcst->cfg = &cfg[k];
853 dmcst->i2c_addr = DIB3000MC_I2C_ADDRESS[k];
854
855 dib3000mc_write_word(dmcst, 1024, dmcst->i2c_addr << 3);
856
857 /* turn off data output */
858 dib3000mc_set_output_mode(dmcst, OUTMODE_HIGH_Z);
859 }
860
861 kfree(dmcst);
862 return 0;
863}
864EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
865
866static struct dvb_frontend_ops dib3000mc_ops;
867
868struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
869{
870 struct dvb_frontend *demod;
871 struct dib3000mc_state *st;
872 st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
873 if (st == NULL)
874 return NULL;
875
876 st->cfg = cfg;
877 st->i2c_adap = i2c_adap;
878 st->i2c_addr = i2c_addr;
879
880 demod = &st->demod;
881 demod->demodulator_priv = st;
882 memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
883
884 if (dib3000mc_identify(st) != 0)
885 goto error;
886
887 dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
888
889 dib3000mc_write_word(st, 1037, 0x3130);
890
891 return demod;
892
893error:
894 kfree(st);
895 return NULL;
896}
897EXPORT_SYMBOL(dib3000mc_attach);
898
899static struct dvb_frontend_ops dib3000mc_ops = {
900 .info = {
901 .name = "DiBcom 3000MC/P",
902 .type = FE_OFDM,
903 .frequency_min = 44250000,
904 .frequency_max = 867250000,
905 .frequency_stepsize = 62500,
906 .caps = FE_CAN_INVERSION_AUTO |
907 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
908 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
909 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
910 FE_CAN_TRANSMISSION_MODE_AUTO |
911 FE_CAN_GUARD_INTERVAL_AUTO |
912 FE_CAN_RECOVER |
913 FE_CAN_HIERARCHY_AUTO,
914 },
915
916 .release = dib3000mc_release,
917
918 .init = dib3000mc_init,
919 .sleep = dib3000mc_sleep,
920
921 .set_frontend = dib3000mc_set_frontend,
922 .get_tune_settings = dib3000mc_fe_get_tune_settings,
923 .get_frontend = dib3000mc_get_frontend,
924
925 .read_status = dib3000mc_read_status,
926 .read_ber = dib3000mc_read_ber,
927 .read_signal_strength = dib3000mc_read_signal_strength,
928 .read_snr = dib3000mc_read_snr,
929 .read_ucblocks = dib3000mc_read_unc_blocks,
930};
931
932MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
933MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
934MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h
new file mode 100644
index 00000000000..d75ffad2d75
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mc.h
@@ -0,0 +1,85 @@
1/*
2 * Driver for DiBcom DiB3000MC/P-demodulator.
3 *
4 * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/)
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher\@desy.de)
6 *
7 * This code is partially based on the previous dib3000mc.c .
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2.
12 */
13#ifndef DIB3000MC_H
14#define DIB3000MC_H
15
16#include "dibx000_common.h"
17
18struct dib3000mc_config {
19 struct dibx000_agc_config *agc;
20
21 u8 phase_noise_mode;
22 u8 impulse_noise_mode;
23
24 u8 pwm3_inversion;
25 u8 use_pwm3;
26 u16 pwm3_value;
27
28 u16 max_time;
29 u16 ln_adc_level;
30
31 u8 agc_command1 :1;
32 u8 agc_command2 :1;
33
34 u8 mobile_mode;
35
36 u8 output_mpeg2_in_188_bytes;
37};
38
39#define DEFAULT_DIB3000MC_I2C_ADDRESS 16
40#define DEFAULT_DIB3000P_I2C_ADDRESS 24
41
42#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && \
43 defined(MODULE))
44extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap,
45 u8 i2c_addr,
46 struct dib3000mc_config *cfg);
47extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c,
48 int no_of_demods, u8 default_addr,
49 struct dib3000mc_config cfg[]);
50extern
51struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod,
52 int gating);
53#else
54static inline
55struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
56 struct dib3000mc_config *cfg)
57{
58 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
59 return NULL;
60}
61
62static inline
63int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c,
64 int no_of_demods, u8 default_addr,
65 struct dib3000mc_config cfg[])
66{
67 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
68 return -ENODEV;
69}
70
71static inline
72struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod,
73 int gating)
74{
75 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
76 return NULL;
77}
78#endif // CONFIG_DVB_DIB3000MC
79
80extern int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff);
81extern int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff);
82
83extern void dib3000mc_set_config(struct dvb_frontend *, struct dib3000mc_config *);
84
85#endif
diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c
new file mode 100644
index 00000000000..dbb76d75c93
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib7000m.c
@@ -0,0 +1,1467 @@
1/*
2 * Linux-DVB Driver for DiBcom's DiB7000M and
3 * first generation DiB7000P-demodulator-family.
4 *
5 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
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, version 2.
10 */
11#include <linux/kernel.h>
12#include <linux/slab.h>
13#include <linux/i2c.h>
14#include <linux/mutex.h>
15
16#include "dvb_frontend.h"
17
18#include "dib7000m.h"
19
20static int debug;
21module_param(debug, int, 0644);
22MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
23
24#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000M: "); printk(args); printk("\n"); } } while (0)
25
26struct dib7000m_state {
27 struct dvb_frontend demod;
28 struct dib7000m_config cfg;
29
30 u8 i2c_addr;
31 struct i2c_adapter *i2c_adap;
32
33 struct dibx000_i2c_master i2c_master;
34
35/* offset is 1 in case of the 7000MC */
36 u8 reg_offs;
37
38 u16 wbd_ref;
39
40 u8 current_band;
41 fe_bandwidth_t current_bandwidth;
42 struct dibx000_agc_config *current_agc;
43 u32 timf;
44 u32 timf_default;
45 u32 internal_clk;
46
47 u8 div_force_off : 1;
48 u8 div_state : 1;
49 u16 div_sync_wait;
50
51 u16 revision;
52
53 u8 agc_state;
54
55 /* for the I2C transfer */
56 struct i2c_msg msg[2];
57 u8 i2c_write_buffer[4];
58 u8 i2c_read_buffer[2];
59 struct mutex i2c_buffer_lock;
60};
61
62enum dib7000m_power_mode {
63 DIB7000M_POWER_ALL = 0,
64
65 DIB7000M_POWER_NO,
66 DIB7000M_POWER_INTERF_ANALOG_AGC,
67 DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
68 DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD,
69 DIB7000M_POWER_INTERFACE_ONLY,
70};
71
72static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
73{
74 u16 ret;
75
76 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
77 dprintk("could not acquire lock");
78 return 0;
79 }
80
81 state->i2c_write_buffer[0] = (reg >> 8) | 0x80;
82 state->i2c_write_buffer[1] = reg & 0xff;
83
84 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
85 state->msg[0].addr = state->i2c_addr >> 1;
86 state->msg[0].flags = 0;
87 state->msg[0].buf = state->i2c_write_buffer;
88 state->msg[0].len = 2;
89 state->msg[1].addr = state->i2c_addr >> 1;
90 state->msg[1].flags = I2C_M_RD;
91 state->msg[1].buf = state->i2c_read_buffer;
92 state->msg[1].len = 2;
93
94 if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
95 dprintk("i2c read error on %d",reg);
96
97 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
98 mutex_unlock(&state->i2c_buffer_lock);
99
100 return ret;
101}
102
103static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
104{
105 int ret;
106
107 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
108 dprintk("could not acquire lock");
109 return -EINVAL;
110 }
111
112 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
113 state->i2c_write_buffer[1] = reg & 0xff;
114 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
115 state->i2c_write_buffer[3] = val & 0xff;
116
117 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
118 state->msg[0].addr = state->i2c_addr >> 1;
119 state->msg[0].flags = 0;
120 state->msg[0].buf = state->i2c_write_buffer;
121 state->msg[0].len = 4;
122
123 ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
124 -EREMOTEIO : 0);
125 mutex_unlock(&state->i2c_buffer_lock);
126 return ret;
127}
128static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
129{
130 u16 l = 0, r, *n;
131 n = buf;
132 l = *n++;
133 while (l) {
134 r = *n++;
135
136 if (state->reg_offs && (r >= 112 && r <= 331)) // compensate for 7000MC
137 r++;
138
139 do {
140 dib7000m_write_word(state, r, *n++);
141 r++;
142 } while (--l);
143 l = *n++;
144 }
145}
146
147static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
148{
149 int ret = 0;
150 u16 outreg, fifo_threshold, smo_mode,
151 sram = 0x0005; /* by default SRAM output is disabled */
152
153 outreg = 0;
154 fifo_threshold = 1792;
155 smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1);
156
157 dprintk( "setting output mode for demod %p to %d", &state->demod, mode);
158
159 switch (mode) {
160 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
161 outreg = (1 << 10); /* 0x0400 */
162 break;
163 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
164 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
165 break;
166 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
167 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
168 break;
169 case OUTMODE_DIVERSITY:
170 if (state->cfg.hostbus_diversity)
171 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
172 else
173 sram |= 0x0c00;
174 break;
175 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
176 smo_mode |= (3 << 1);
177 fifo_threshold = 512;
178 outreg = (1 << 10) | (5 << 6);
179 break;
180 case OUTMODE_HIGH_Z: // disable
181 outreg = 0;
182 break;
183 default:
184 dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod);
185 break;
186 }
187
188 if (state->cfg.output_mpeg2_in_188_bytes)
189 smo_mode |= (1 << 5) ;
190
191 ret |= dib7000m_write_word(state, 294 + state->reg_offs, smo_mode);
192 ret |= dib7000m_write_word(state, 295 + state->reg_offs, fifo_threshold); /* synchronous fread */
193 ret |= dib7000m_write_word(state, 1795, outreg);
194 ret |= dib7000m_write_word(state, 1805, sram);
195
196 if (state->revision == 0x4003) {
197 u16 clk_cfg1 = dib7000m_read_word(state, 909) & 0xfffd;
198 if (mode == OUTMODE_DIVERSITY)
199 clk_cfg1 |= (1 << 1); // P_O_CLK_en
200 dib7000m_write_word(state, 909, clk_cfg1);
201 }
202 return ret;
203}
204
205static void dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode)
206{
207 /* by default everything is going to be powered off */
208 u16 reg_903 = 0xffff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906 = 0x3fff;
209 u8 offset = 0;
210
211 /* now, depending on the requested mode, we power on */
212 switch (mode) {
213 /* power up everything in the demod */
214 case DIB7000M_POWER_ALL:
215 reg_903 = 0x0000; reg_904 = 0x0000; reg_905 = 0x0000; reg_906 = 0x0000;
216 break;
217
218 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
219 case DIB7000M_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C or SRAM */
220 reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
221 break;
222
223 case DIB7000M_POWER_INTERF_ANALOG_AGC:
224 reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
225 reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
226 reg_906 &= ~((1 << 0));
227 break;
228
229 case DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
230 reg_903 = 0x0000; reg_904 = 0x801f; reg_905 = 0x0000; reg_906 = 0x0000;
231 break;
232
233 case DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD:
234 reg_903 = 0x0000; reg_904 = 0x8000; reg_905 = 0x010b; reg_906 = 0x0000;
235 break;
236 case DIB7000M_POWER_NO:
237 break;
238 }
239
240 /* always power down unused parts */
241 if (!state->cfg.mobile_mode)
242 reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
243
244 /* P_sdio_select_clk = 0 on MC and after*/
245 if (state->revision != 0x4000)
246 reg_906 <<= 1;
247
248 if (state->revision == 0x4003)
249 offset = 1;
250
251 dib7000m_write_word(state, 903 + offset, reg_903);
252 dib7000m_write_word(state, 904 + offset, reg_904);
253 dib7000m_write_word(state, 905 + offset, reg_905);
254 dib7000m_write_word(state, 906 + offset, reg_906);
255}
256
257static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc_states no)
258{
259 int ret = 0;
260 u16 reg_913 = dib7000m_read_word(state, 913),
261 reg_914 = dib7000m_read_word(state, 914);
262
263 switch (no) {
264 case DIBX000_SLOW_ADC_ON:
265 reg_914 |= (1 << 1) | (1 << 0);
266 ret |= dib7000m_write_word(state, 914, reg_914);
267 reg_914 &= ~(1 << 1);
268 break;
269
270 case DIBX000_SLOW_ADC_OFF:
271 reg_914 |= (1 << 1) | (1 << 0);
272 break;
273
274 case DIBX000_ADC_ON:
275 if (state->revision == 0x4000) { // workaround for PA/MA
276 // power-up ADC
277 dib7000m_write_word(state, 913, 0);
278 dib7000m_write_word(state, 914, reg_914 & 0x3);
279 // power-down bandgag
280 dib7000m_write_word(state, 913, (1 << 15));
281 dib7000m_write_word(state, 914, reg_914 & 0x3);
282 }
283
284 reg_913 &= 0x0fff;
285 reg_914 &= 0x0003;
286 break;
287
288 case DIBX000_ADC_OFF: // leave the VBG voltage on
289 reg_913 |= (1 << 14) | (1 << 13) | (1 << 12);
290 reg_914 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
291 break;
292
293 case DIBX000_VBG_ENABLE:
294 reg_913 &= ~(1 << 15);
295 break;
296
297 case DIBX000_VBG_DISABLE:
298 reg_913 |= (1 << 15);
299 break;
300
301 default:
302 break;
303 }
304
305// dprintk( "913: %x, 914: %x", reg_913, reg_914);
306 ret |= dib7000m_write_word(state, 913, reg_913);
307 ret |= dib7000m_write_word(state, 914, reg_914);
308
309 return ret;
310}
311
312static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw)
313{
314 u32 timf;
315
316 // store the current bandwidth for later use
317 state->current_bandwidth = bw;
318
319 if (state->timf == 0) {
320 dprintk( "using default timf");
321 timf = state->timf_default;
322 } else {
323 dprintk( "using updated timf");
324 timf = state->timf;
325 }
326
327 timf = timf * (bw / 50) / 160;
328
329 dib7000m_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
330 dib7000m_write_word(state, 24, (u16) ((timf ) & 0xffff));
331
332 return 0;
333}
334
335static int dib7000m_set_diversity_in(struct dvb_frontend *demod, int onoff)
336{
337 struct dib7000m_state *state = demod->demodulator_priv;
338
339 if (state->div_force_off) {
340 dprintk( "diversity combination deactivated - forced by COFDM parameters");
341 onoff = 0;
342 }
343 state->div_state = (u8)onoff;
344
345 if (onoff) {
346 dib7000m_write_word(state, 263 + state->reg_offs, 6);
347 dib7000m_write_word(state, 264 + state->reg_offs, 6);
348 dib7000m_write_word(state, 266 + state->reg_offs, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
349 } else {
350 dib7000m_write_word(state, 263 + state->reg_offs, 1);
351 dib7000m_write_word(state, 264 + state->reg_offs, 0);
352 dib7000m_write_word(state, 266 + state->reg_offs, 0);
353 }
354
355 return 0;
356}
357
358static int dib7000m_sad_calib(struct dib7000m_state *state)
359{
360
361/* internal */
362// dib7000m_write_word(state, 928, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
363 dib7000m_write_word(state, 929, (0 << 1) | (0 << 0));
364 dib7000m_write_word(state, 930, 776); // 0.625*3.3 / 4096
365
366 /* do the calibration */
367 dib7000m_write_word(state, 929, (1 << 0));
368 dib7000m_write_word(state, 929, (0 << 0));
369
370 msleep(1);
371
372 return 0;
373}
374
375static void dib7000m_reset_pll_common(struct dib7000m_state *state, const struct dibx000_bandwidth_config *bw)
376{
377 dib7000m_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
378 dib7000m_write_word(state, 19, (u16) ( (bw->internal*1000) & 0xffff));
379 dib7000m_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff));
380 dib7000m_write_word(state, 22, (u16) ( bw->ifreq & 0xffff));
381
382 dib7000m_write_word(state, 928, bw->sad_cfg);
383}
384
385static void dib7000m_reset_pll(struct dib7000m_state *state)
386{
387 const struct dibx000_bandwidth_config *bw = state->cfg.bw;
388 u16 reg_907,reg_910;
389
390 /* default */
391 reg_907 = (bw->pll_bypass << 15) | (bw->modulo << 7) |
392 (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) |
393 (bw->enable_refdiv << 1) | (0 << 0);
394 reg_910 = (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset;
395
396 // for this oscillator frequency should be 30 MHz for the Master (default values in the board_parameters give that value)
397 // this is only working only for 30 MHz crystals
398 if (!state->cfg.quartz_direct) {
399 reg_910 |= (1 << 5); // forcing the predivider to 1
400
401 // if the previous front-end is baseband, its output frequency is 15 MHz (prev freq divided by 2)
402 if(state->cfg.input_clk_is_div_2)
403 reg_907 |= (16 << 9);
404 else // otherwise the previous front-end puts out its input (default 30MHz) - no extra division necessary
405 reg_907 |= (8 << 9);
406 } else {
407 reg_907 |= (bw->pll_ratio & 0x3f) << 9;
408 reg_910 |= (bw->pll_prediv << 5);
409 }
410
411 dib7000m_write_word(state, 910, reg_910); // pll cfg
412 dib7000m_write_word(state, 907, reg_907); // clk cfg0
413 dib7000m_write_word(state, 908, 0x0006); // clk_cfg1
414
415 dib7000m_reset_pll_common(state, bw);
416}
417
418static void dib7000mc_reset_pll(struct dib7000m_state *state)
419{
420 const struct dibx000_bandwidth_config *bw = state->cfg.bw;
421 u16 clk_cfg1;
422
423 // clk_cfg0
424 dib7000m_write_word(state, 907, (bw->pll_prediv << 8) | (bw->pll_ratio << 0));
425
426 // clk_cfg1
427 //dib7000m_write_word(state, 908, (1 << 14) | (3 << 12) |(0 << 11) |
428 clk_cfg1 = (0 << 14) | (3 << 12) |(0 << 11) |
429 (bw->IO_CLK_en_core << 10) | (bw->bypclk_div << 5) | (bw->enable_refdiv << 4) |
430 (1 << 3) | (bw->pll_range << 1) | (bw->pll_reset << 0);
431 dib7000m_write_word(state, 908, clk_cfg1);
432 clk_cfg1 = (clk_cfg1 & 0xfff7) | (bw->pll_bypass << 3);
433 dib7000m_write_word(state, 908, clk_cfg1);
434
435 // smpl_cfg
436 dib7000m_write_word(state, 910, (1 << 12) | (2 << 10) | (bw->modulo << 8) | (bw->ADClkSrc << 7));
437
438 dib7000m_reset_pll_common(state, bw);
439}
440
441static int dib7000m_reset_gpio(struct dib7000m_state *st)
442{
443 /* reset the GPIOs */
444 dib7000m_write_word(st, 773, st->cfg.gpio_dir);
445 dib7000m_write_word(st, 774, st->cfg.gpio_val);
446
447 /* TODO 782 is P_gpio_od */
448
449 dib7000m_write_word(st, 775, st->cfg.gpio_pwm_pos);
450
451 dib7000m_write_word(st, 780, st->cfg.pwm_freq_div);
452 return 0;
453}
454
455static u16 dib7000m_defaults_common[] =
456
457{
458 // auto search configuration
459 3, 2,
460 0x0004,
461 0x1000,
462 0x0814,
463
464 12, 6,
465 0x001b,
466 0x7740,
467 0x005b,
468 0x8d80,
469 0x01c9,
470 0xc380,
471 0x0000,
472 0x0080,
473 0x0000,
474 0x0090,
475 0x0001,
476 0xd4c0,
477
478 1, 26,
479 0x6680, // P_corm_thres Lock algorithms configuration
480
481 1, 170,
482 0x0410, // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on
483
484 8, 173,
485 0,
486 0,
487 0,
488 0,
489 0,
490 0,
491 0,
492 0,
493
494 1, 182,
495 8192, // P_fft_nb_to_cut
496
497 2, 195,
498 0x0ccd, // P_pha3_thres
499 0, // P_cti_use_cpe, P_cti_use_prog
500
501 1, 205,
502 0x200f, // P_cspu_regul, P_cspu_win_cut
503
504 5, 214,
505 0x023d, // P_adp_regul_cnt
506 0x00a4, // P_adp_noise_cnt
507 0x00a4, // P_adp_regul_ext
508 0x7ff0, // P_adp_noise_ext
509 0x3ccc, // P_adp_fil
510
511 1, 226,
512 0, // P_2d_byp_ti_num
513
514 1, 255,
515 0x800, // P_equal_thres_wgn
516
517 1, 263,
518 0x0001,
519
520 1, 281,
521 0x0010, // P_fec_*
522
523 1, 294,
524 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
525
526 0
527};
528
529static u16 dib7000m_defaults[] =
530
531{
532 /* set ADC level to -16 */
533 11, 76,
534 (1 << 13) - 825 - 117,
535 (1 << 13) - 837 - 117,
536 (1 << 13) - 811 - 117,
537 (1 << 13) - 766 - 117,
538 (1 << 13) - 737 - 117,
539 (1 << 13) - 693 - 117,
540 (1 << 13) - 648 - 117,
541 (1 << 13) - 619 - 117,
542 (1 << 13) - 575 - 117,
543 (1 << 13) - 531 - 117,
544 (1 << 13) - 501 - 117,
545
546 // Tuner IO bank: max drive (14mA)
547 1, 912,
548 0x2c8a,
549
550 1, 1817,
551 1,
552
553 0,
554};
555
556static int dib7000m_demod_reset(struct dib7000m_state *state)
557{
558 dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
559
560 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
561 dib7000m_set_adc_state(state, DIBX000_VBG_ENABLE);
562
563 /* restart all parts */
564 dib7000m_write_word(state, 898, 0xffff);
565 dib7000m_write_word(state, 899, 0xffff);
566 dib7000m_write_word(state, 900, 0xff0f);
567 dib7000m_write_word(state, 901, 0xfffc);
568
569 dib7000m_write_word(state, 898, 0);
570 dib7000m_write_word(state, 899, 0);
571 dib7000m_write_word(state, 900, 0);
572 dib7000m_write_word(state, 901, 0);
573
574 if (state->revision == 0x4000)
575 dib7000m_reset_pll(state);
576 else
577 dib7000mc_reset_pll(state);
578
579 if (dib7000m_reset_gpio(state) != 0)
580 dprintk( "GPIO reset was not successful.");
581
582 if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
583 dprintk( "OUTPUT_MODE could not be reset.");
584
585 /* unforce divstr regardless whether i2c enumeration was done or not */
586 dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) );
587
588 dib7000m_set_bandwidth(state, 8000);
589
590 dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON);
591 dib7000m_sad_calib(state);
592 dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
593
594 if (state->cfg.dvbt_mode)
595 dib7000m_write_word(state, 1796, 0x0); // select DVB-T output
596
597 if (state->cfg.mobile_mode)
598 dib7000m_write_word(state, 261 + state->reg_offs, 2);
599 else
600 dib7000m_write_word(state, 224 + state->reg_offs, 1);
601
602 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
603 if(state->cfg.tuner_is_baseband)
604 dib7000m_write_word(state, 36, 0x0755);
605 else
606 dib7000m_write_word(state, 36, 0x1f55);
607
608 // P_divclksel=3 P_divbitsel=1
609 if (state->revision == 0x4000)
610 dib7000m_write_word(state, 909, (3 << 10) | (1 << 6));
611 else
612 dib7000m_write_word(state, 909, (3 << 4) | 1);
613
614 dib7000m_write_tab(state, dib7000m_defaults_common);
615 dib7000m_write_tab(state, dib7000m_defaults);
616
617 dib7000m_set_power_mode(state, DIB7000M_POWER_INTERFACE_ONLY);
618
619 state->internal_clk = state->cfg.bw->internal;
620
621 return 0;
622}
623
624static void dib7000m_restart_agc(struct dib7000m_state *state)
625{
626 // P_restart_iqc & P_restart_agc
627 dib7000m_write_word(state, 898, 0x0c00);
628 dib7000m_write_word(state, 898, 0x0000);
629}
630
631static int dib7000m_agc_soft_split(struct dib7000m_state *state)
632{
633 u16 agc,split_offset;
634
635 if(!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
636 return 0;
637
638 // n_agc_global
639 agc = dib7000m_read_word(state, 390);
640
641 if (agc > state->current_agc->split.min_thres)
642 split_offset = state->current_agc->split.min;
643 else if (agc < state->current_agc->split.max_thres)
644 split_offset = state->current_agc->split.max;
645 else
646 split_offset = state->current_agc->split.max *
647 (agc - state->current_agc->split.min_thres) /
648 (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
649
650 dprintk( "AGC split_offset: %d",split_offset);
651
652 // P_agc_force_split and P_agc_split_offset
653 return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset);
654}
655
656static int dib7000m_update_lna(struct dib7000m_state *state)
657{
658 u16 dyn_gain;
659
660 if (state->cfg.update_lna) {
661 // read dyn_gain here (because it is demod-dependent and not fe)
662 dyn_gain = dib7000m_read_word(state, 390);
663
664 if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
665 dib7000m_restart_agc(state);
666 return 1;
667 }
668 }
669 return 0;
670}
671
672static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
673{
674 struct dibx000_agc_config *agc = NULL;
675 int i;
676 if (state->current_band == band && state->current_agc != NULL)
677 return 0;
678 state->current_band = band;
679
680 for (i = 0; i < state->cfg.agc_config_count; i++)
681 if (state->cfg.agc[i].band_caps & band) {
682 agc = &state->cfg.agc[i];
683 break;
684 }
685
686 if (agc == NULL) {
687 dprintk( "no valid AGC configuration found for band 0x%02x",band);
688 return -EINVAL;
689 }
690
691 state->current_agc = agc;
692
693 /* AGC */
694 dib7000m_write_word(state, 72 , agc->setup);
695 dib7000m_write_word(state, 73 , agc->inv_gain);
696 dib7000m_write_word(state, 74 , agc->time_stabiliz);
697 dib7000m_write_word(state, 97 , (agc->alpha_level << 12) | agc->thlock);
698
699 // Demod AGC loop configuration
700 dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp);
701 dib7000m_write_word(state, 99, (agc->beta_mant << 6) | agc->beta_exp);
702
703 dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
704 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
705
706 /* AGC continued */
707 if (state->wbd_ref != 0)
708 dib7000m_write_word(state, 102, state->wbd_ref);
709 else // use default
710 dib7000m_write_word(state, 102, agc->wbd_ref);
711
712 dib7000m_write_word(state, 103, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8) );
713 dib7000m_write_word(state, 104, agc->agc1_max);
714 dib7000m_write_word(state, 105, agc->agc1_min);
715 dib7000m_write_word(state, 106, agc->agc2_max);
716 dib7000m_write_word(state, 107, agc->agc2_min);
717 dib7000m_write_word(state, 108, (agc->agc1_pt1 << 8) | agc->agc1_pt2 );
718 dib7000m_write_word(state, 109, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
719 dib7000m_write_word(state, 110, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
720 dib7000m_write_word(state, 111, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
721
722 if (state->revision > 0x4000) { // settings for the MC
723 dib7000m_write_word(state, 71, agc->agc1_pt3);
724// dprintk( "929: %x %d %d",
725// (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2), agc->wbd_inv, agc->wbd_sel);
726 dib7000m_write_word(state, 929, (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
727 } else {
728 // wrong default values
729 u16 b[9] = { 676, 696, 717, 737, 758, 778, 799, 819, 840 };
730 for (i = 0; i < 9; i++)
731 dib7000m_write_word(state, 88 + i, b[i]);
732 }
733 return 0;
734}
735
736static void dib7000m_update_timf(struct dib7000m_state *state)
737{
738 u32 timf = (dib7000m_read_word(state, 436) << 16) | dib7000m_read_word(state, 437);
739 state->timf = timf * 160 / (state->current_bandwidth / 50);
740 dib7000m_write_word(state, 23, (u16) (timf >> 16));
741 dib7000m_write_word(state, 24, (u16) (timf & 0xffff));
742 dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->timf_default);
743}
744
745static int dib7000m_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
746{
747 struct dib7000m_state *state = demod->demodulator_priv;
748 u16 cfg_72 = dib7000m_read_word(state, 72);
749 int ret = -1;
750 u8 *agc_state = &state->agc_state;
751 u8 agc_split;
752
753 switch (state->agc_state) {
754 case 0:
755 // set power-up level: interf+analog+AGC
756 dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC);
757 dib7000m_set_adc_state(state, DIBX000_ADC_ON);
758
759 if (dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
760 return -1;
761
762 ret = 7; /* ADC power up */
763 (*agc_state)++;
764 break;
765
766 case 1:
767 /* AGC initialization */
768 if (state->cfg.agc_control)
769 state->cfg.agc_control(&state->demod, 1);
770
771 dib7000m_write_word(state, 75, 32768);
772 if (!state->current_agc->perform_agc_softsplit) {
773 /* we are using the wbd - so slow AGC startup */
774 dib7000m_write_word(state, 103, 1 << 8); /* force 0 split on WBD and restart AGC */
775 (*agc_state)++;
776 ret = 5;
777 } else {
778 /* default AGC startup */
779 (*agc_state) = 4;
780 /* wait AGC rough lock time */
781 ret = 7;
782 }
783
784 dib7000m_restart_agc(state);
785 break;
786
787 case 2: /* fast split search path after 5sec */
788 dib7000m_write_word(state, 72, cfg_72 | (1 << 4)); /* freeze AGC loop */
789 dib7000m_write_word(state, 103, 2 << 9); /* fast split search 0.25kHz */
790 (*agc_state)++;
791 ret = 14;
792 break;
793
794 case 3: /* split search ended */
795 agc_split = (u8)dib7000m_read_word(state, 392); /* store the split value for the next time */
796 dib7000m_write_word(state, 75, dib7000m_read_word(state, 390)); /* set AGC gain start value */
797
798 dib7000m_write_word(state, 72, cfg_72 & ~(1 << 4)); /* std AGC loop */
799 dib7000m_write_word(state, 103, (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
800
801 dib7000m_restart_agc(state);
802
803 dprintk( "SPLIT %p: %hd", demod, agc_split);
804
805 (*agc_state)++;
806 ret = 5;
807 break;
808
809 case 4: /* LNA startup */
810 /* wait AGC accurate lock time */
811 ret = 7;
812
813 if (dib7000m_update_lna(state))
814 // wait only AGC rough lock time
815 ret = 5;
816 else
817 (*agc_state)++;
818 break;
819
820 case 5:
821 dib7000m_agc_soft_split(state);
822
823 if (state->cfg.agc_control)
824 state->cfg.agc_control(&state->demod, 0);
825
826 (*agc_state)++;
827 break;
828
829 default:
830 break;
831 }
832 return ret;
833}
834
835static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_frontend_parameters *ch, u8 seq)
836{
837 u16 value, est[4];
838
839 dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
840
841 /* nfft, guard, qam, alpha */
842 value = 0;
843 switch (ch->u.ofdm.transmission_mode) {
844 case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
845 case TRANSMISSION_MODE_4K: value |= (2 << 7); break;
846 default:
847 case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
848 }
849 switch (ch->u.ofdm.guard_interval) {
850 case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
851 case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
852 case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
853 default:
854 case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
855 }
856 switch (ch->u.ofdm.constellation) {
857 case QPSK: value |= (0 << 3); break;
858 case QAM_16: value |= (1 << 3); break;
859 default:
860 case QAM_64: value |= (2 << 3); break;
861 }
862 switch (HIERARCHY_1) {
863 case HIERARCHY_2: value |= 2; break;
864 case HIERARCHY_4: value |= 4; break;
865 default:
866 case HIERARCHY_1: value |= 1; break;
867 }
868 dib7000m_write_word(state, 0, value);
869 dib7000m_write_word(state, 5, (seq << 4));
870
871 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
872 value = 0;
873 if (1 != 0)
874 value |= (1 << 6);
875 if (ch->u.ofdm.hierarchy_information == 1)
876 value |= (1 << 4);
877 if (1 == 1)
878 value |= 1;
879 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
880 case FEC_2_3: value |= (2 << 1); break;
881 case FEC_3_4: value |= (3 << 1); break;
882 case FEC_5_6: value |= (5 << 1); break;
883 case FEC_7_8: value |= (7 << 1); break;
884 default:
885 case FEC_1_2: value |= (1 << 1); break;
886 }
887 dib7000m_write_word(state, 267 + state->reg_offs, value);
888
889 /* offset loop parameters */
890
891 /* P_timf_alpha = 6, P_corm_alpha=6, P_corm_thres=0x80 */
892 dib7000m_write_word(state, 26, (6 << 12) | (6 << 8) | 0x80);
893
894 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=1, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
895 dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (1 << 9) | (3 << 5) | (1 << 4) | (0x3));
896
897 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max=3 */
898 dib7000m_write_word(state, 32, (0 << 4) | 0x3);
899
900 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step=5 */
901 dib7000m_write_word(state, 33, (0 << 4) | 0x5);
902
903 /* P_dvsy_sync_wait */
904 switch (ch->u.ofdm.transmission_mode) {
905 case TRANSMISSION_MODE_8K: value = 256; break;
906 case TRANSMISSION_MODE_4K: value = 128; break;
907 case TRANSMISSION_MODE_2K:
908 default: value = 64; break;
909 }
910 switch (ch->u.ofdm.guard_interval) {
911 case GUARD_INTERVAL_1_16: value *= 2; break;
912 case GUARD_INTERVAL_1_8: value *= 4; break;
913 case GUARD_INTERVAL_1_4: value *= 8; break;
914 default:
915 case GUARD_INTERVAL_1_32: value *= 1; break;
916 }
917 state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
918
919 /* deactive the possibility of diversity reception if extended interleave - not for 7000MC */
920 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
921 if (1 == 1 || state->revision > 0x4000)
922 state->div_force_off = 0;
923 else
924 state->div_force_off = 1;
925 dib7000m_set_diversity_in(&state->demod, state->div_state);
926
927 /* channel estimation fine configuration */
928 switch (ch->u.ofdm.constellation) {
929 case QAM_64:
930 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
931 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
932 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
933 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
934 break;
935 case QAM_16:
936 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
937 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
938 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
939 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
940 break;
941 default:
942 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
943 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
944 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */
945 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
946 break;
947 }
948 for (value = 0; value < 4; value++)
949 dib7000m_write_word(state, 214 + value + state->reg_offs, est[value]);
950
951 // set power-up level: autosearch
952 dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD);
953}
954
955static int dib7000m_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
956{
957 struct dib7000m_state *state = demod->demodulator_priv;
958 struct dvb_frontend_parameters schan;
959 int ret = 0;
960 u32 value, factor;
961
962 schan = *ch;
963
964 schan.u.ofdm.constellation = QAM_64;
965 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
966 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
967 schan.u.ofdm.code_rate_HP = FEC_2_3;
968 schan.u.ofdm.code_rate_LP = FEC_3_4;
969 schan.u.ofdm.hierarchy_information = 0;
970
971 dib7000m_set_channel(state, &schan, 7);
972
973 factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
974 if (factor >= 5000)
975 factor = 1;
976 else
977 factor = 6;
978
979 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
980 value = 30 * state->internal_clk * factor;
981 ret |= dib7000m_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
982 ret |= dib7000m_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time
983 value = 100 * state->internal_clk * factor;
984 ret |= dib7000m_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
985 ret |= dib7000m_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time
986 value = 500 * state->internal_clk * factor;
987 ret |= dib7000m_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
988 ret |= dib7000m_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time
989
990 // start search
991 value = dib7000m_read_word(state, 0);
992 ret |= dib7000m_write_word(state, 0, (u16) (value | (1 << 9)));
993
994 /* clear n_irq_pending */
995 if (state->revision == 0x4000)
996 dib7000m_write_word(state, 1793, 0);
997 else
998 dib7000m_read_word(state, 537);
999
1000 ret |= dib7000m_write_word(state, 0, (u16) value);
1001
1002 return ret;
1003}
1004
1005static int dib7000m_autosearch_irq(struct dib7000m_state *state, u16 reg)
1006{
1007 u16 irq_pending = dib7000m_read_word(state, reg);
1008
1009 if (irq_pending & 0x1) { // failed
1010 dprintk( "autosearch failed");
1011 return 1;
1012 }
1013
1014 if (irq_pending & 0x2) { // succeeded
1015 dprintk( "autosearch succeeded");
1016 return 2;
1017 }
1018 return 0; // still pending
1019}
1020
1021static int dib7000m_autosearch_is_irq(struct dvb_frontend *demod)
1022{
1023 struct dib7000m_state *state = demod->demodulator_priv;
1024 if (state->revision == 0x4000)
1025 return dib7000m_autosearch_irq(state, 1793);
1026 else
1027 return dib7000m_autosearch_irq(state, 537);
1028}
1029
1030static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1031{
1032 struct dib7000m_state *state = demod->demodulator_priv;
1033 int ret = 0;
1034 u16 value;
1035
1036 // we are already tuned - just resuming from suspend
1037 if (ch != NULL)
1038 dib7000m_set_channel(state, ch, 0);
1039 else
1040 return -EINVAL;
1041
1042 // restart demod
1043 ret |= dib7000m_write_word(state, 898, 0x4000);
1044 ret |= dib7000m_write_word(state, 898, 0x0000);
1045 msleep(45);
1046
1047 dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD);
1048 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
1049 ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
1050
1051 // never achieved a lock before - wait for timfreq to update
1052 if (state->timf == 0)
1053 msleep(200);
1054
1055 //dump_reg(state);
1056 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1057 value = (6 << 8) | 0x80;
1058 switch (ch->u.ofdm.transmission_mode) {
1059 case TRANSMISSION_MODE_2K: value |= (7 << 12); break;
1060 case TRANSMISSION_MODE_4K: value |= (8 << 12); break;
1061 default:
1062 case TRANSMISSION_MODE_8K: value |= (9 << 12); break;
1063 }
1064 ret |= dib7000m_write_word(state, 26, value);
1065
1066 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1067 value = (0 << 4);
1068 switch (ch->u.ofdm.transmission_mode) {
1069 case TRANSMISSION_MODE_2K: value |= 0x6; break;
1070 case TRANSMISSION_MODE_4K: value |= 0x7; break;
1071 default:
1072 case TRANSMISSION_MODE_8K: value |= 0x8; break;
1073 }
1074 ret |= dib7000m_write_word(state, 32, value);
1075
1076 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1077 value = (0 << 4);
1078 switch (ch->u.ofdm.transmission_mode) {
1079 case TRANSMISSION_MODE_2K: value |= 0x6; break;
1080 case TRANSMISSION_MODE_4K: value |= 0x7; break;
1081 default:
1082 case TRANSMISSION_MODE_8K: value |= 0x8; break;
1083 }
1084 ret |= dib7000m_write_word(state, 33, value);
1085
1086 // we achieved a lock - it's time to update the timf freq
1087 if ((dib7000m_read_word(state, 535) >> 6) & 0x1)
1088 dib7000m_update_timf(state);
1089
1090 dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1091 return ret;
1092}
1093
1094static int dib7000m_wakeup(struct dvb_frontend *demod)
1095{
1096 struct dib7000m_state *state = demod->demodulator_priv;
1097
1098 dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
1099
1100 if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1101 dprintk( "could not start Slow ADC");
1102
1103 return 0;
1104}
1105
1106static int dib7000m_sleep(struct dvb_frontend *demod)
1107{
1108 struct dib7000m_state *st = demod->demodulator_priv;
1109 dib7000m_set_output_mode(st, OUTMODE_HIGH_Z);
1110 dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY);
1111 return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) |
1112 dib7000m_set_adc_state(st, DIBX000_ADC_OFF);
1113}
1114
1115static int dib7000m_identify(struct dib7000m_state *state)
1116{
1117 u16 value;
1118
1119 if ((value = dib7000m_read_word(state, 896)) != 0x01b3) {
1120 dprintk( "wrong Vendor ID (0x%x)",value);
1121 return -EREMOTEIO;
1122 }
1123
1124 state->revision = dib7000m_read_word(state, 897);
1125 if (state->revision != 0x4000 &&
1126 state->revision != 0x4001 &&
1127 state->revision != 0x4002 &&
1128 state->revision != 0x4003) {
1129 dprintk( "wrong Device ID (0x%x)",value);
1130 return -EREMOTEIO;
1131 }
1132
1133 /* protect this driver to be used with 7000PC */
1134 if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) {
1135 dprintk( "this driver does not work with DiB7000PC");
1136 return -EREMOTEIO;
1137 }
1138
1139 switch (state->revision) {
1140 case 0x4000: dprintk( "found DiB7000MA/PA/MB/PB"); break;
1141 case 0x4001: state->reg_offs = 1; dprintk( "found DiB7000HC"); break;
1142 case 0x4002: state->reg_offs = 1; dprintk( "found DiB7000MC"); break;
1143 case 0x4003: state->reg_offs = 1; dprintk( "found DiB9000"); break;
1144 }
1145
1146 return 0;
1147}
1148
1149
1150static int dib7000m_get_frontend(struct dvb_frontend* fe,
1151 struct dvb_frontend_parameters *fep)
1152{
1153 struct dib7000m_state *state = fe->demodulator_priv;
1154 u16 tps = dib7000m_read_word(state,480);
1155
1156 fep->inversion = INVERSION_AUTO;
1157
1158 fep->u.ofdm.bandwidth = state->current_bandwidth;
1159
1160 switch ((tps >> 8) & 0x3) {
1161 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
1162 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
1163 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1164 }
1165
1166 switch (tps & 0x3) {
1167 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
1168 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
1169 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
1170 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
1171 }
1172
1173 switch ((tps >> 14) & 0x3) {
1174 case 0: fep->u.ofdm.constellation = QPSK; break;
1175 case 1: fep->u.ofdm.constellation = QAM_16; break;
1176 case 2:
1177 default: fep->u.ofdm.constellation = QAM_64; break;
1178 }
1179
1180 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1181 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1182
1183 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1184 switch ((tps >> 5) & 0x7) {
1185 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
1186 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
1187 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
1188 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
1189 case 7:
1190 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
1191
1192 }
1193
1194 switch ((tps >> 2) & 0x7) {
1195 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
1196 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
1197 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
1198 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
1199 case 7:
1200 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
1201 }
1202
1203 /* native interleaver: (dib7000m_read_word(state, 481) >> 5) & 0x1 */
1204
1205 return 0;
1206}
1207
1208static int dib7000m_set_frontend(struct dvb_frontend* fe,
1209 struct dvb_frontend_parameters *fep)
1210{
1211 struct dib7000m_state *state = fe->demodulator_priv;
1212 int time, ret;
1213
1214 dib7000m_set_output_mode(state, OUTMODE_HIGH_Z);
1215
1216 state->current_bandwidth = fep->u.ofdm.bandwidth;
1217 dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
1218
1219 if (fe->ops.tuner_ops.set_params)
1220 fe->ops.tuner_ops.set_params(fe, fep);
1221
1222 /* start up the AGC */
1223 state->agc_state = 0;
1224 do {
1225 time = dib7000m_agc_startup(fe, fep);
1226 if (time != -1)
1227 msleep(time);
1228 } while (time != -1);
1229
1230 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1231 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
1232 fep->u.ofdm.constellation == QAM_AUTO ||
1233 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1234 int i = 800, found;
1235
1236 dib7000m_autosearch_start(fe, fep);
1237 do {
1238 msleep(1);
1239 found = dib7000m_autosearch_is_irq(fe);
1240 } while (found == 0 && i--);
1241
1242 dprintk("autosearch returns: %d",found);
1243 if (found == 0 || found == 1)
1244 return 0; // no channel found
1245
1246 dib7000m_get_frontend(fe, fep);
1247 }
1248
1249 ret = dib7000m_tune(fe, fep);
1250
1251 /* make this a config parameter */
1252 dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO);
1253 return ret;
1254}
1255
1256static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat)
1257{
1258 struct dib7000m_state *state = fe->demodulator_priv;
1259 u16 lock = dib7000m_read_word(state, 535);
1260
1261 *stat = 0;
1262
1263 if (lock & 0x8000)
1264 *stat |= FE_HAS_SIGNAL;
1265 if (lock & 0x3000)
1266 *stat |= FE_HAS_CARRIER;
1267 if (lock & 0x0100)
1268 *stat |= FE_HAS_VITERBI;
1269 if (lock & 0x0010)
1270 *stat |= FE_HAS_SYNC;
1271 if (lock & 0x0008)
1272 *stat |= FE_HAS_LOCK;
1273
1274 return 0;
1275}
1276
1277static int dib7000m_read_ber(struct dvb_frontend *fe, u32 *ber)
1278{
1279 struct dib7000m_state *state = fe->demodulator_priv;
1280 *ber = (dib7000m_read_word(state, 526) << 16) | dib7000m_read_word(state, 527);
1281 return 0;
1282}
1283
1284static int dib7000m_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
1285{
1286 struct dib7000m_state *state = fe->demodulator_priv;
1287 *unc = dib7000m_read_word(state, 534);
1288 return 0;
1289}
1290
1291static int dib7000m_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1292{
1293 struct dib7000m_state *state = fe->demodulator_priv;
1294 u16 val = dib7000m_read_word(state, 390);
1295 *strength = 65535 - val;
1296 return 0;
1297}
1298
1299static int dib7000m_read_snr(struct dvb_frontend* fe, u16 *snr)
1300{
1301 *snr = 0x0000;
1302 return 0;
1303}
1304
1305static int dib7000m_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
1306{
1307 tune->min_delay_ms = 1000;
1308 return 0;
1309}
1310
1311static void dib7000m_release(struct dvb_frontend *demod)
1312{
1313 struct dib7000m_state *st = demod->demodulator_priv;
1314 dibx000_exit_i2c_master(&st->i2c_master);
1315 kfree(st);
1316}
1317
1318struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1319{
1320 struct dib7000m_state *st = demod->demodulator_priv;
1321 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1322}
1323EXPORT_SYMBOL(dib7000m_get_i2c_master);
1324
1325int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1326{
1327 struct dib7000m_state *state = fe->demodulator_priv;
1328 u16 val = dib7000m_read_word(state, 294 + state->reg_offs) & 0xffef;
1329 val |= (onoff & 0x1) << 4;
1330 dprintk("PID filter enabled %d", onoff);
1331 return dib7000m_write_word(state, 294 + state->reg_offs, val);
1332}
1333EXPORT_SYMBOL(dib7000m_pid_filter_ctrl);
1334
1335int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1336{
1337 struct dib7000m_state *state = fe->demodulator_priv;
1338 dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1339 return dib7000m_write_word(state, 300 + state->reg_offs + id,
1340 onoff ? (1 << 13) | pid : 0);
1341}
1342EXPORT_SYMBOL(dib7000m_pid_filter);
1343
1344#if 0
1345/* used with some prototype boards */
1346int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods,
1347 u8 default_addr, struct dib7000m_config cfg[])
1348{
1349 struct dib7000m_state st = { .i2c_adap = i2c };
1350 int k = 0;
1351 u8 new_addr = 0;
1352
1353 for (k = no_of_demods-1; k >= 0; k--) {
1354 st.cfg = cfg[k];
1355
1356 /* designated i2c address */
1357 new_addr = (0x40 + k) << 1;
1358 st.i2c_addr = new_addr;
1359 if (dib7000m_identify(&st) != 0) {
1360 st.i2c_addr = default_addr;
1361 if (dib7000m_identify(&st) != 0) {
1362 dprintk("DiB7000M #%d: not identified", k);
1363 return -EIO;
1364 }
1365 }
1366
1367 /* start diversity to pull_down div_str - just for i2c-enumeration */
1368 dib7000m_set_output_mode(&st, OUTMODE_DIVERSITY);
1369
1370 dib7000m_write_word(&st, 1796, 0x0); // select DVB-T output
1371
1372 /* set new i2c address and force divstart */
1373 dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2);
1374
1375 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1376 }
1377
1378 for (k = 0; k < no_of_demods; k++) {
1379 st.cfg = cfg[k];
1380 st.i2c_addr = (0x40 + k) << 1;
1381
1382 // unforce divstr
1383 dib7000m_write_word(&st,1794, st.i2c_addr << 2);
1384
1385 /* deactivate div - it was just for i2c-enumeration */
1386 dib7000m_set_output_mode(&st, OUTMODE_HIGH_Z);
1387 }
1388
1389 return 0;
1390}
1391EXPORT_SYMBOL(dib7000m_i2c_enumeration);
1392#endif
1393
1394static struct dvb_frontend_ops dib7000m_ops;
1395struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg)
1396{
1397 struct dvb_frontend *demod;
1398 struct dib7000m_state *st;
1399 st = kzalloc(sizeof(struct dib7000m_state), GFP_KERNEL);
1400 if (st == NULL)
1401 return NULL;
1402
1403 memcpy(&st->cfg, cfg, sizeof(struct dib7000m_config));
1404 st->i2c_adap = i2c_adap;
1405 st->i2c_addr = i2c_addr;
1406
1407 demod = &st->demod;
1408 demod->demodulator_priv = st;
1409 memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops));
1410 mutex_init(&st->i2c_buffer_lock);
1411
1412 st->timf_default = cfg->bw->timf;
1413
1414 if (dib7000m_identify(st) != 0)
1415 goto error;
1416
1417 if (st->revision == 0x4000)
1418 dibx000_init_i2c_master(&st->i2c_master, DIB7000, st->i2c_adap, st->i2c_addr);
1419 else
1420 dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c_adap, st->i2c_addr);
1421
1422 dib7000m_demod_reset(st);
1423
1424 return demod;
1425
1426error:
1427 kfree(st);
1428 return NULL;
1429}
1430EXPORT_SYMBOL(dib7000m_attach);
1431
1432static struct dvb_frontend_ops dib7000m_ops = {
1433 .info = {
1434 .name = "DiBcom 7000MA/MB/PA/PB/MC",
1435 .type = FE_OFDM,
1436 .frequency_min = 44250000,
1437 .frequency_max = 867250000,
1438 .frequency_stepsize = 62500,
1439 .caps = FE_CAN_INVERSION_AUTO |
1440 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1441 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1442 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1443 FE_CAN_TRANSMISSION_MODE_AUTO |
1444 FE_CAN_GUARD_INTERVAL_AUTO |
1445 FE_CAN_RECOVER |
1446 FE_CAN_HIERARCHY_AUTO,
1447 },
1448
1449 .release = dib7000m_release,
1450
1451 .init = dib7000m_wakeup,
1452 .sleep = dib7000m_sleep,
1453
1454 .set_frontend = dib7000m_set_frontend,
1455 .get_tune_settings = dib7000m_fe_get_tune_settings,
1456 .get_frontend = dib7000m_get_frontend,
1457
1458 .read_status = dib7000m_read_status,
1459 .read_ber = dib7000m_read_ber,
1460 .read_signal_strength = dib7000m_read_signal_strength,
1461 .read_snr = dib7000m_read_snr,
1462 .read_ucblocks = dib7000m_read_unc_blocks,
1463};
1464
1465MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1466MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator");
1467MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib7000m.h b/drivers/media/dvb/frontends/dib7000m.h
new file mode 100644
index 00000000000..81fcf2241c6
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib7000m.h
@@ -0,0 +1,90 @@
1#ifndef DIB7000M_H
2#define DIB7000M_H
3
4#include "dibx000_common.h"
5
6struct dib7000m_config {
7 u8 dvbt_mode;
8 u8 output_mpeg2_in_188_bytes;
9 u8 hostbus_diversity;
10 u8 tuner_is_baseband;
11 u8 mobile_mode;
12 int (*update_lna) (struct dvb_frontend *, u16 agc_global);
13
14 u8 agc_config_count;
15 struct dibx000_agc_config *agc;
16
17 struct dibx000_bandwidth_config *bw;
18
19#define DIB7000M_GPIO_DEFAULT_DIRECTIONS 0xffff
20 u16 gpio_dir;
21#define DIB7000M_GPIO_DEFAULT_VALUES 0x0000
22 u16 gpio_val;
23#define DIB7000M_GPIO_PWM_POS0(v) ((v & 0xf) << 12)
24#define DIB7000M_GPIO_PWM_POS1(v) ((v & 0xf) << 8 )
25#define DIB7000M_GPIO_PWM_POS2(v) ((v & 0xf) << 4 )
26#define DIB7000M_GPIO_PWM_POS3(v) (v & 0xf)
27#define DIB7000M_GPIO_DEFAULT_PWM_POS 0xffff
28 u16 gpio_pwm_pos;
29
30 u16 pwm_freq_div;
31
32 u8 quartz_direct;
33
34 u8 input_clk_is_div_2;
35
36 int (*agc_control) (struct dvb_frontend *, u8 before);
37};
38
39#define DEFAULT_DIB7000M_I2C_ADDRESS 18
40
41#if defined(CONFIG_DVB_DIB7000M) || (defined(CONFIG_DVB_DIB7000M_MODULE) && \
42 defined(MODULE))
43extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
44 u8 i2c_addr,
45 struct dib7000m_config *cfg);
46extern struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *,
47 enum dibx000_i2c_interface,
48 int);
49extern int dib7000m_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
50extern int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
51#else
52static inline
53struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
54 u8 i2c_addr, struct dib7000m_config *cfg)
55{
56 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
57 return NULL;
58}
59
60static inline
61struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *demod,
62 enum dibx000_i2c_interface intf,
63 int gating)
64{
65 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
66 return NULL;
67}
68static inline int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id,
69 u16 pid, u8 onoff)
70{
71 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
72 return -ENODEV;
73}
74
75static inline int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe,
76 uint8_t onoff)
77{
78 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
79 return -ENODEV;
80}
81#endif
82
83/* TODO
84extern INT dib7000m_set_gpio(struct dibDemod *demod, UCHAR num, UCHAR dir, UCHAR val);
85extern INT dib7000m_enable_vbg_voltage(struct dibDemod *demod);
86extern void dib7000m_set_hostbus_diversity(struct dibDemod *demod, UCHAR onoff);
87extern USHORT dib7000m_get_current_agc_global(struct dibDemod *demod);
88*/
89
90#endif
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
new file mode 100644
index 00000000000..4eb9c2b49cd
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -0,0 +1,2426 @@
1/*
2 * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
3 *
4 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 */
10#include <linux/kernel.h>
11#include <linux/slab.h>
12#include <linux/i2c.h>
13#include <linux/mutex.h>
14
15#include "dvb_math.h"
16#include "dvb_frontend.h"
17
18#include "dib7000p.h"
19
20static int debug;
21module_param(debug, int, 0644);
22MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
23
24static int buggy_sfn_workaround;
25module_param(buggy_sfn_workaround, int, 0644);
26MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
27
28#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
29
30struct i2c_device {
31 struct i2c_adapter *i2c_adap;
32 u8 i2c_addr;
33};
34
35struct dib7000p_state {
36 struct dvb_frontend demod;
37 struct dib7000p_config cfg;
38
39 u8 i2c_addr;
40 struct i2c_adapter *i2c_adap;
41
42 struct dibx000_i2c_master i2c_master;
43
44 u16 wbd_ref;
45
46 u8 current_band;
47 u32 current_bandwidth;
48 struct dibx000_agc_config *current_agc;
49 u32 timf;
50
51 u8 div_force_off:1;
52 u8 div_state:1;
53 u16 div_sync_wait;
54
55 u8 agc_state;
56
57 u16 gpio_dir;
58 u16 gpio_val;
59
60 u8 sfn_workaround_active:1;
61
62#define SOC7090 0x7090
63 u16 version;
64
65 u16 tuner_enable;
66 struct i2c_adapter dib7090_tuner_adap;
67
68 /* for the I2C transfer */
69 struct i2c_msg msg[2];
70 u8 i2c_write_buffer[4];
71 u8 i2c_read_buffer[2];
72 struct mutex i2c_buffer_lock;
73};
74
75enum dib7000p_power_mode {
76 DIB7000P_POWER_ALL = 0,
77 DIB7000P_POWER_ANALOG_ADC,
78 DIB7000P_POWER_INTERFACE_ONLY,
79};
80
81static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
82static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
83
84static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
85{
86 u16 ret;
87
88 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
89 dprintk("could not acquire lock");
90 return 0;
91 }
92
93 state->i2c_write_buffer[0] = reg >> 8;
94 state->i2c_write_buffer[1] = reg & 0xff;
95
96 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
97 state->msg[0].addr = state->i2c_addr >> 1;
98 state->msg[0].flags = 0;
99 state->msg[0].buf = state->i2c_write_buffer;
100 state->msg[0].len = 2;
101 state->msg[1].addr = state->i2c_addr >> 1;
102 state->msg[1].flags = I2C_M_RD;
103 state->msg[1].buf = state->i2c_read_buffer;
104 state->msg[1].len = 2;
105
106 if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
107 dprintk("i2c read error on %d", reg);
108
109 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
110 mutex_unlock(&state->i2c_buffer_lock);
111 return ret;
112}
113
114static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
115{
116 int ret;
117
118 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
119 dprintk("could not acquire lock");
120 return -EINVAL;
121 }
122
123 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
124 state->i2c_write_buffer[1] = reg & 0xff;
125 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
126 state->i2c_write_buffer[3] = val & 0xff;
127
128 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
129 state->msg[0].addr = state->i2c_addr >> 1;
130 state->msg[0].flags = 0;
131 state->msg[0].buf = state->i2c_write_buffer;
132 state->msg[0].len = 4;
133
134 ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
135 -EREMOTEIO : 0);
136 mutex_unlock(&state->i2c_buffer_lock);
137 return ret;
138}
139
140static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
141{
142 u16 l = 0, r, *n;
143 n = buf;
144 l = *n++;
145 while (l) {
146 r = *n++;
147
148 do {
149 dib7000p_write_word(state, r, *n++);
150 r++;
151 } while (--l);
152 l = *n++;
153 }
154}
155
156static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
157{
158 int ret = 0;
159 u16 outreg, fifo_threshold, smo_mode;
160
161 outreg = 0;
162 fifo_threshold = 1792;
163 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
164
165 dprintk("setting output mode for demod %p to %d", &state->demod, mode);
166
167 switch (mode) {
168 case OUTMODE_MPEG2_PAR_GATED_CLK:
169 outreg = (1 << 10); /* 0x0400 */
170 break;
171 case OUTMODE_MPEG2_PAR_CONT_CLK:
172 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
173 break;
174 case OUTMODE_MPEG2_SERIAL:
175 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
176 break;
177 case OUTMODE_DIVERSITY:
178 if (state->cfg.hostbus_diversity)
179 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
180 else
181 outreg = (1 << 11);
182 break;
183 case OUTMODE_MPEG2_FIFO:
184 smo_mode |= (3 << 1);
185 fifo_threshold = 512;
186 outreg = (1 << 10) | (5 << 6);
187 break;
188 case OUTMODE_ANALOG_ADC:
189 outreg = (1 << 10) | (3 << 6);
190 break;
191 case OUTMODE_HIGH_Z:
192 outreg = 0;
193 break;
194 default:
195 dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod);
196 break;
197 }
198
199 if (state->cfg.output_mpeg2_in_188_bytes)
200 smo_mode |= (1 << 5);
201
202 ret |= dib7000p_write_word(state, 235, smo_mode);
203 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
204 if (state->version != SOC7090)
205 ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */
206
207 return ret;
208}
209
210static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
211{
212 struct dib7000p_state *state = demod->demodulator_priv;
213
214 if (state->div_force_off) {
215 dprintk("diversity combination deactivated - forced by COFDM parameters");
216 onoff = 0;
217 dib7000p_write_word(state, 207, 0);
218 } else
219 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
220
221 state->div_state = (u8) onoff;
222
223 if (onoff) {
224 dib7000p_write_word(state, 204, 6);
225 dib7000p_write_word(state, 205, 16);
226 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
227 } else {
228 dib7000p_write_word(state, 204, 1);
229 dib7000p_write_word(state, 205, 0);
230 }
231
232 return 0;
233}
234
235static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
236{
237 /* by default everything is powered off */
238 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
239
240 /* now, depending on the requested mode, we power on */
241 switch (mode) {
242 /* power up everything in the demod */
243 case DIB7000P_POWER_ALL:
244 reg_774 = 0x0000;
245 reg_775 = 0x0000;
246 reg_776 = 0x0;
247 reg_899 = 0x0;
248 if (state->version == SOC7090)
249 reg_1280 &= 0x001f;
250 else
251 reg_1280 &= 0x01ff;
252 break;
253
254 case DIB7000P_POWER_ANALOG_ADC:
255 /* dem, cfg, iqc, sad, agc */
256 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
257 /* nud */
258 reg_776 &= ~((1 << 0));
259 /* Dout */
260 if (state->version != SOC7090)
261 reg_1280 &= ~((1 << 11));
262 reg_1280 &= ~(1 << 6);
263 /* fall through wanted to enable the interfaces */
264
265 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
266 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
267 if (state->version == SOC7090)
268 reg_1280 &= ~((1 << 7) | (1 << 5));
269 else
270 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
271 break;
272
273/* TODO following stuff is just converted from the dib7000-driver - check when is used what */
274 }
275
276 dib7000p_write_word(state, 774, reg_774);
277 dib7000p_write_word(state, 775, reg_775);
278 dib7000p_write_word(state, 776, reg_776);
279 dib7000p_write_word(state, 899, reg_899);
280 dib7000p_write_word(state, 1280, reg_1280);
281
282 return 0;
283}
284
285static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
286{
287 u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909);
288 u16 reg;
289
290 switch (no) {
291 case DIBX000_SLOW_ADC_ON:
292 if (state->version == SOC7090) {
293 reg = dib7000p_read_word(state, 1925);
294
295 dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2)); /* en_slowAdc = 1 & reset_sladc = 1 */
296
297 reg = dib7000p_read_word(state, 1925); /* read acces to make it works... strange ... */
298 msleep(200);
299 dib7000p_write_word(state, 1925, reg & ~(1 << 4)); /* en_slowAdc = 1 & reset_sladc = 0 */
300
301 reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
302 dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524); /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
303 } else {
304 reg_909 |= (1 << 1) | (1 << 0);
305 dib7000p_write_word(state, 909, reg_909);
306 reg_909 &= ~(1 << 1);
307 }
308 break;
309
310 case DIBX000_SLOW_ADC_OFF:
311 if (state->version == SOC7090) {
312 reg = dib7000p_read_word(state, 1925);
313 dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
314 } else
315 reg_909 |= (1 << 1) | (1 << 0);
316 break;
317
318 case DIBX000_ADC_ON:
319 reg_908 &= 0x0fff;
320 reg_909 &= 0x0003;
321 break;
322
323 case DIBX000_ADC_OFF:
324 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
325 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
326 break;
327
328 case DIBX000_VBG_ENABLE:
329 reg_908 &= ~(1 << 15);
330 break;
331
332 case DIBX000_VBG_DISABLE:
333 reg_908 |= (1 << 15);
334 break;
335
336 default:
337 break;
338 }
339
340// dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
341
342 reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
343 reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
344
345 dib7000p_write_word(state, 908, reg_908);
346 dib7000p_write_word(state, 909, reg_909);
347}
348
349static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
350{
351 u32 timf;
352
353 // store the current bandwidth for later use
354 state->current_bandwidth = bw;
355
356 if (state->timf == 0) {
357 dprintk("using default timf");
358 timf = state->cfg.bw->timf;
359 } else {
360 dprintk("using updated timf");
361 timf = state->timf;
362 }
363
364 timf = timf * (bw / 50) / 160;
365
366 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
367 dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
368
369 return 0;
370}
371
372static int dib7000p_sad_calib(struct dib7000p_state *state)
373{
374/* internal */
375 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
376
377 if (state->version == SOC7090)
378 dib7000p_write_word(state, 74, 2048);
379 else
380 dib7000p_write_word(state, 74, 776);
381
382 /* do the calibration */
383 dib7000p_write_word(state, 73, (1 << 0));
384 dib7000p_write_word(state, 73, (0 << 0));
385
386 msleep(1);
387
388 return 0;
389}
390
391int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
392{
393 struct dib7000p_state *state = demod->demodulator_priv;
394 if (value > 4095)
395 value = 4095;
396 state->wbd_ref = value;
397 return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
398}
399EXPORT_SYMBOL(dib7000p_set_wbd_ref);
400
401static void dib7000p_reset_pll(struct dib7000p_state *state)
402{
403 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
404 u16 clk_cfg0;
405
406 if (state->version == SOC7090) {
407 dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
408
409 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
410 ;
411
412 dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
413 } else {
414 /* force PLL bypass */
415 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
416 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
417
418 dib7000p_write_word(state, 900, clk_cfg0);
419
420 /* P_pll_cfg */
421 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
422 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
423 dib7000p_write_word(state, 900, clk_cfg0);
424 }
425
426 dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
427 dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
428 dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
429 dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
430
431 dib7000p_write_word(state, 72, bw->sad_cfg);
432}
433
434static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
435{
436 u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
437 internal |= (u32) dib7000p_read_word(state, 19);
438 internal /= 1000;
439
440 return internal;
441}
442
443int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
444{
445 struct dib7000p_state *state = fe->demodulator_priv;
446 u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
447 u8 loopdiv, prediv;
448 u32 internal, xtal;
449
450 /* get back old values */
451 prediv = reg_1856 & 0x3f;
452 loopdiv = (reg_1856 >> 6) & 0x3f;
453
454 if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
455 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
456 reg_1856 &= 0xf000;
457 reg_1857 = dib7000p_read_word(state, 1857);
458 dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15));
459
460 dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
461
462 /* write new system clk into P_sec_len */
463 internal = dib7000p_get_internal_freq(state);
464 xtal = (internal / loopdiv) * prediv;
465 internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio; /* new internal */
466 dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
467 dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
468
469 dib7000p_write_word(state, 1857, reg_1857 | (1 << 15));
470
471 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
472 dprintk("Waiting for PLL to lock");
473
474 return 0;
475 }
476 return -EIO;
477}
478EXPORT_SYMBOL(dib7000p_update_pll);
479
480static int dib7000p_reset_gpio(struct dib7000p_state *st)
481{
482 /* reset the GPIOs */
483 dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
484
485 dib7000p_write_word(st, 1029, st->gpio_dir);
486 dib7000p_write_word(st, 1030, st->gpio_val);
487
488 /* TODO 1031 is P_gpio_od */
489
490 dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
491
492 dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
493 return 0;
494}
495
496static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
497{
498 st->gpio_dir = dib7000p_read_word(st, 1029);
499 st->gpio_dir &= ~(1 << num); /* reset the direction bit */
500 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
501 dib7000p_write_word(st, 1029, st->gpio_dir);
502
503 st->gpio_val = dib7000p_read_word(st, 1030);
504 st->gpio_val &= ~(1 << num); /* reset the direction bit */
505 st->gpio_val |= (val & 0x01) << num; /* set the new value */
506 dib7000p_write_word(st, 1030, st->gpio_val);
507
508 return 0;
509}
510
511int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
512{
513 struct dib7000p_state *state = demod->demodulator_priv;
514 return dib7000p_cfg_gpio(state, num, dir, val);
515}
516EXPORT_SYMBOL(dib7000p_set_gpio);
517
518static u16 dib7000p_defaults[] = {
519 // auto search configuration
520 3, 2,
521 0x0004,
522 0x1000,
523 0x0814, /* Equal Lock */
524
525 12, 6,
526 0x001b,
527 0x7740,
528 0x005b,
529 0x8d80,
530 0x01c9,
531 0xc380,
532 0x0000,
533 0x0080,
534 0x0000,
535 0x0090,
536 0x0001,
537 0xd4c0,
538
539 1, 26,
540 0x6680,
541
542 /* set ADC level to -16 */
543 11, 79,
544 (1 << 13) - 825 - 117,
545 (1 << 13) - 837 - 117,
546 (1 << 13) - 811 - 117,
547 (1 << 13) - 766 - 117,
548 (1 << 13) - 737 - 117,
549 (1 << 13) - 693 - 117,
550 (1 << 13) - 648 - 117,
551 (1 << 13) - 619 - 117,
552 (1 << 13) - 575 - 117,
553 (1 << 13) - 531 - 117,
554 (1 << 13) - 501 - 117,
555
556 1, 142,
557 0x0410,
558
559 /* disable power smoothing */
560 8, 145,
561 0,
562 0,
563 0,
564 0,
565 0,
566 0,
567 0,
568 0,
569
570 1, 154,
571 1 << 13,
572
573 1, 168,
574 0x0ccd,
575
576 1, 183,
577 0x200f,
578
579 1, 212,
580 0x169,
581
582 5, 187,
583 0x023d,
584 0x00a4,
585 0x00a4,
586 0x7ff0,
587 0x3ccc,
588
589 1, 198,
590 0x800,
591
592 1, 222,
593 0x0010,
594
595 1, 235,
596 0x0062,
597
598 2, 901,
599 0x0006,
600 (3 << 10) | (1 << 6),
601
602 1, 905,
603 0x2c8e,
604
605 0,
606};
607
608static int dib7000p_demod_reset(struct dib7000p_state *state)
609{
610 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
611
612 if (state->version == SOC7090)
613 dibx000_reset_i2c_master(&state->i2c_master);
614
615 dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
616
617 /* restart all parts */
618 dib7000p_write_word(state, 770, 0xffff);
619 dib7000p_write_word(state, 771, 0xffff);
620 dib7000p_write_word(state, 772, 0x001f);
621 dib7000p_write_word(state, 898, 0x0003);
622 dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
623
624 dib7000p_write_word(state, 770, 0);
625 dib7000p_write_word(state, 771, 0);
626 dib7000p_write_word(state, 772, 0);
627 dib7000p_write_word(state, 898, 0);
628 dib7000p_write_word(state, 1280, 0);
629
630 /* default */
631 dib7000p_reset_pll(state);
632
633 if (dib7000p_reset_gpio(state) != 0)
634 dprintk("GPIO reset was not successful.");
635
636 if (state->version == SOC7090) {
637 dib7000p_write_word(state, 899, 0);
638
639 /* impulse noise */
640 dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
641 dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
642 dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
643 dib7000p_write_word(state, 273, (1<<6) | 30);
644 }
645 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
646 dprintk("OUTPUT_MODE could not be reset.");
647
648 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
649 dib7000p_sad_calib(state);
650 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
651
652 /* unforce divstr regardless whether i2c enumeration was done or not */
653 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
654
655 dib7000p_set_bandwidth(state, 8000);
656
657 if (state->version == SOC7090) {
658 dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
659 } else {
660 if (state->cfg.tuner_is_baseband)
661 dib7000p_write_word(state, 36, 0x0755);
662 else
663 dib7000p_write_word(state, 36, 0x1f55);
664 }
665
666 dib7000p_write_tab(state, dib7000p_defaults);
667
668 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
669
670 return 0;
671}
672
673static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
674{
675 u16 tmp = 0;
676 tmp = dib7000p_read_word(state, 903);
677 dib7000p_write_word(state, 903, (tmp | 0x1));
678 tmp = dib7000p_read_word(state, 900);
679 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));
680}
681
682static void dib7000p_restart_agc(struct dib7000p_state *state)
683{
684 // P_restart_iqc & P_restart_agc
685 dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
686 dib7000p_write_word(state, 770, 0x0000);
687}
688
689static int dib7000p_update_lna(struct dib7000p_state *state)
690{
691 u16 dyn_gain;
692
693 if (state->cfg.update_lna) {
694 dyn_gain = dib7000p_read_word(state, 394);
695 if (state->cfg.update_lna(&state->demod, dyn_gain)) {
696 dib7000p_restart_agc(state);
697 return 1;
698 }
699 }
700
701 return 0;
702}
703
704static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
705{
706 struct dibx000_agc_config *agc = NULL;
707 int i;
708 if (state->current_band == band && state->current_agc != NULL)
709 return 0;
710 state->current_band = band;
711
712 for (i = 0; i < state->cfg.agc_config_count; i++)
713 if (state->cfg.agc[i].band_caps & band) {
714 agc = &state->cfg.agc[i];
715 break;
716 }
717
718 if (agc == NULL) {
719 dprintk("no valid AGC configuration found for band 0x%02x", band);
720 return -EINVAL;
721 }
722
723 state->current_agc = agc;
724
725 /* AGC */
726 dib7000p_write_word(state, 75, agc->setup);
727 dib7000p_write_word(state, 76, agc->inv_gain);
728 dib7000p_write_word(state, 77, agc->time_stabiliz);
729 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
730
731 // Demod AGC loop configuration
732 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
733 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
734
735 /* AGC continued */
736 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
737 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
738
739 if (state->wbd_ref != 0)
740 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
741 else
742 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
743
744 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
745
746 dib7000p_write_word(state, 107, agc->agc1_max);
747 dib7000p_write_word(state, 108, agc->agc1_min);
748 dib7000p_write_word(state, 109, agc->agc2_max);
749 dib7000p_write_word(state, 110, agc->agc2_min);
750 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
751 dib7000p_write_word(state, 112, agc->agc1_pt3);
752 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
753 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
754 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
755 return 0;
756}
757
758static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
759{
760 u32 internal = dib7000p_get_internal_freq(state);
761 s32 unit_khz_dds_val = 67108864 / (internal); /* 2**26 / Fsampling is the unit 1KHz offset */
762 u32 abs_offset_khz = ABS(offset_khz);
763 u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
764 u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
765
766 dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert);
767
768 if (offset_khz < 0)
769 unit_khz_dds_val *= -1;
770
771 /* IF tuner */
772 if (invert)
773 dds -= (abs_offset_khz * unit_khz_dds_val); /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
774 else
775 dds += (abs_offset_khz * unit_khz_dds_val);
776
777 if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */
778 dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
779 dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
780 }
781}
782
783static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
784{
785 struct dib7000p_state *state = demod->demodulator_priv;
786 int ret = -1;
787 u8 *agc_state = &state->agc_state;
788 u8 agc_split;
789 u16 reg;
790 u32 upd_demod_gain_period = 0x1000;
791
792 switch (state->agc_state) {
793 case 0:
794 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
795 if (state->version == SOC7090) {
796 reg = dib7000p_read_word(state, 0x79b) & 0xff00;
797 dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF); /* lsb */
798 dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF));
799
800 /* enable adc i & q */
801 reg = dib7000p_read_word(state, 0x780);
802 dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
803 } else {
804 dib7000p_set_adc_state(state, DIBX000_ADC_ON);
805 dib7000p_pll_clk_cfg(state);
806 }
807
808 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
809 return -1;
810
811 dib7000p_set_dds(state, 0);
812 ret = 7;
813 (*agc_state)++;
814 break;
815
816 case 1:
817 if (state->cfg.agc_control)
818 state->cfg.agc_control(&state->demod, 1);
819
820 dib7000p_write_word(state, 78, 32768);
821 if (!state->current_agc->perform_agc_softsplit) {
822 /* we are using the wbd - so slow AGC startup */
823 /* force 0 split on WBD and restart AGC */
824 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
825 (*agc_state)++;
826 ret = 5;
827 } else {
828 /* default AGC startup */
829 (*agc_state) = 4;
830 /* wait AGC rough lock time */
831 ret = 7;
832 }
833
834 dib7000p_restart_agc(state);
835 break;
836
837 case 2: /* fast split search path after 5sec */
838 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
839 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
840 (*agc_state)++;
841 ret = 14;
842 break;
843
844 case 3: /* split search ended */
845 agc_split = (u8) dib7000p_read_word(state, 396); /* store the split value for the next time */
846 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
847
848 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */
849 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
850
851 dib7000p_restart_agc(state);
852
853 dprintk("SPLIT %p: %hd", demod, agc_split);
854
855 (*agc_state)++;
856 ret = 5;
857 break;
858
859 case 4: /* LNA startup */
860 ret = 7;
861
862 if (dib7000p_update_lna(state))
863 ret = 5;
864 else
865 (*agc_state)++;
866 break;
867
868 case 5:
869 if (state->cfg.agc_control)
870 state->cfg.agc_control(&state->demod, 0);
871 (*agc_state)++;
872 break;
873 default:
874 break;
875 }
876 return ret;
877}
878
879static void dib7000p_update_timf(struct dib7000p_state *state)
880{
881 u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
882 state->timf = timf * 160 / (state->current_bandwidth / 50);
883 dib7000p_write_word(state, 23, (u16) (timf >> 16));
884 dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
885 dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf);
886
887}
888
889u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
890{
891 struct dib7000p_state *state = fe->demodulator_priv;
892 switch (op) {
893 case DEMOD_TIMF_SET:
894 state->timf = timf;
895 break;
896 case DEMOD_TIMF_UPDATE:
897 dib7000p_update_timf(state);
898 break;
899 case DEMOD_TIMF_GET:
900 break;
901 }
902 dib7000p_set_bandwidth(state, state->current_bandwidth);
903 return state->timf;
904}
905EXPORT_SYMBOL(dib7000p_ctrl_timf);
906
907static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
908{
909 u16 value, est[4];
910
911 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
912
913 /* nfft, guard, qam, alpha */
914 value = 0;
915 switch (ch->u.ofdm.transmission_mode) {
916 case TRANSMISSION_MODE_2K:
917 value |= (0 << 7);
918 break;
919 case TRANSMISSION_MODE_4K:
920 value |= (2 << 7);
921 break;
922 default:
923 case TRANSMISSION_MODE_8K:
924 value |= (1 << 7);
925 break;
926 }
927 switch (ch->u.ofdm.guard_interval) {
928 case GUARD_INTERVAL_1_32:
929 value |= (0 << 5);
930 break;
931 case GUARD_INTERVAL_1_16:
932 value |= (1 << 5);
933 break;
934 case GUARD_INTERVAL_1_4:
935 value |= (3 << 5);
936 break;
937 default:
938 case GUARD_INTERVAL_1_8:
939 value |= (2 << 5);
940 break;
941 }
942 switch (ch->u.ofdm.constellation) {
943 case QPSK:
944 value |= (0 << 3);
945 break;
946 case QAM_16:
947 value |= (1 << 3);
948 break;
949 default:
950 case QAM_64:
951 value |= (2 << 3);
952 break;
953 }
954 switch (HIERARCHY_1) {
955 case HIERARCHY_2:
956 value |= 2;
957 break;
958 case HIERARCHY_4:
959 value |= 4;
960 break;
961 default:
962 case HIERARCHY_1:
963 value |= 1;
964 break;
965 }
966 dib7000p_write_word(state, 0, value);
967 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
968
969 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
970 value = 0;
971 if (1 != 0)
972 value |= (1 << 6);
973 if (ch->u.ofdm.hierarchy_information == 1)
974 value |= (1 << 4);
975 if (1 == 1)
976 value |= 1;
977 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
978 case FEC_2_3:
979 value |= (2 << 1);
980 break;
981 case FEC_3_4:
982 value |= (3 << 1);
983 break;
984 case FEC_5_6:
985 value |= (5 << 1);
986 break;
987 case FEC_7_8:
988 value |= (7 << 1);
989 break;
990 default:
991 case FEC_1_2:
992 value |= (1 << 1);
993 break;
994 }
995 dib7000p_write_word(state, 208, value);
996
997 /* offset loop parameters */
998 dib7000p_write_word(state, 26, 0x6680);
999 dib7000p_write_word(state, 32, 0x0003);
1000 dib7000p_write_word(state, 29, 0x1273);
1001 dib7000p_write_word(state, 33, 0x0005);
1002
1003 /* P_dvsy_sync_wait */
1004 switch (ch->u.ofdm.transmission_mode) {
1005 case TRANSMISSION_MODE_8K:
1006 value = 256;
1007 break;
1008 case TRANSMISSION_MODE_4K:
1009 value = 128;
1010 break;
1011 case TRANSMISSION_MODE_2K:
1012 default:
1013 value = 64;
1014 break;
1015 }
1016 switch (ch->u.ofdm.guard_interval) {
1017 case GUARD_INTERVAL_1_16:
1018 value *= 2;
1019 break;
1020 case GUARD_INTERVAL_1_8:
1021 value *= 4;
1022 break;
1023 case GUARD_INTERVAL_1_4:
1024 value *= 8;
1025 break;
1026 default:
1027 case GUARD_INTERVAL_1_32:
1028 value *= 1;
1029 break;
1030 }
1031 if (state->cfg.diversity_delay == 0)
1032 state->div_sync_wait = (value * 3) / 2 + 48;
1033 else
1034 state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay;
1035
1036 /* deactive the possibility of diversity reception if extended interleaver */
1037 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
1038 dib7000p_set_diversity_in(&state->demod, state->div_state);
1039
1040 /* channel estimation fine configuration */
1041 switch (ch->u.ofdm.constellation) {
1042 case QAM_64:
1043 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1044 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1045 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1046 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1047 break;
1048 case QAM_16:
1049 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1050 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1051 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1052 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1053 break;
1054 default:
1055 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1056 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1057 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1058 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1059 break;
1060 }
1061 for (value = 0; value < 4; value++)
1062 dib7000p_write_word(state, 187 + value, est[value]);
1063}
1064
1065static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1066{
1067 struct dib7000p_state *state = demod->demodulator_priv;
1068 struct dvb_frontend_parameters schan;
1069 u32 value, factor;
1070 u32 internal = dib7000p_get_internal_freq(state);
1071
1072 schan = *ch;
1073 schan.u.ofdm.constellation = QAM_64;
1074 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1075 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1076 schan.u.ofdm.code_rate_HP = FEC_2_3;
1077 schan.u.ofdm.code_rate_LP = FEC_3_4;
1078 schan.u.ofdm.hierarchy_information = 0;
1079
1080 dib7000p_set_channel(state, &schan, 7);
1081
1082 factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
1083 if (factor >= 5000)
1084 factor = 1;
1085 else
1086 factor = 6;
1087
1088 value = 30 * internal * factor;
1089 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
1090 dib7000p_write_word(state, 7, (u16) (value & 0xffff));
1091 value = 100 * internal * factor;
1092 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
1093 dib7000p_write_word(state, 9, (u16) (value & 0xffff));
1094 value = 500 * internal * factor;
1095 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
1096 dib7000p_write_word(state, 11, (u16) (value & 0xffff));
1097
1098 value = dib7000p_read_word(state, 0);
1099 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
1100 dib7000p_read_word(state, 1284);
1101 dib7000p_write_word(state, 0, (u16) value);
1102
1103 return 0;
1104}
1105
1106static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
1107{
1108 struct dib7000p_state *state = demod->demodulator_priv;
1109 u16 irq_pending = dib7000p_read_word(state, 1284);
1110
1111 if (irq_pending & 0x1)
1112 return 1;
1113
1114 if (irq_pending & 0x2)
1115 return 2;
1116
1117 return 0;
1118}
1119
1120static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
1121{
1122 static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
1123 static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
1124 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
1125 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
1126 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
1127 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
1128 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
1129 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
1130 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
1131 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
1132 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
1133 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
1134 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
1135 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
1136 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
1137 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
1138 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1139 255, 255, 255, 255, 255, 255
1140 };
1141
1142 u32 xtal = state->cfg.bw->xtal_hz / 1000;
1143 int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
1144 int k;
1145 int coef_re[8], coef_im[8];
1146 int bw_khz = bw;
1147 u32 pha;
1148
1149 dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
1150
1151 if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
1152 return;
1153
1154 bw_khz /= 100;
1155
1156 dib7000p_write_word(state, 142, 0x0610);
1157
1158 for (k = 0; k < 8; k++) {
1159 pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
1160
1161 if (pha == 0) {
1162 coef_re[k] = 256;
1163 coef_im[k] = 0;
1164 } else if (pha < 256) {
1165 coef_re[k] = sine[256 - (pha & 0xff)];
1166 coef_im[k] = sine[pha & 0xff];
1167 } else if (pha == 256) {
1168 coef_re[k] = 0;
1169 coef_im[k] = 256;
1170 } else if (pha < 512) {
1171 coef_re[k] = -sine[pha & 0xff];
1172 coef_im[k] = sine[256 - (pha & 0xff)];
1173 } else if (pha == 512) {
1174 coef_re[k] = -256;
1175 coef_im[k] = 0;
1176 } else if (pha < 768) {
1177 coef_re[k] = -sine[256 - (pha & 0xff)];
1178 coef_im[k] = -sine[pha & 0xff];
1179 } else if (pha == 768) {
1180 coef_re[k] = 0;
1181 coef_im[k] = -256;
1182 } else {
1183 coef_re[k] = sine[pha & 0xff];
1184 coef_im[k] = -sine[256 - (pha & 0xff)];
1185 }
1186
1187 coef_re[k] *= notch[k];
1188 coef_re[k] += (1 << 14);
1189 if (coef_re[k] >= (1 << 24))
1190 coef_re[k] = (1 << 24) - 1;
1191 coef_re[k] /= (1 << 15);
1192
1193 coef_im[k] *= notch[k];
1194 coef_im[k] += (1 << 14);
1195 if (coef_im[k] >= (1 << 24))
1196 coef_im[k] = (1 << 24) - 1;
1197 coef_im[k] /= (1 << 15);
1198
1199 dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
1200
1201 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1202 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
1203 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1204 }
1205 dib7000p_write_word(state, 143, 0);
1206}
1207
1208static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1209{
1210 struct dib7000p_state *state = demod->demodulator_priv;
1211 u16 tmp = 0;
1212
1213 if (ch != NULL)
1214 dib7000p_set_channel(state, ch, 0);
1215 else
1216 return -EINVAL;
1217
1218 // restart demod
1219 dib7000p_write_word(state, 770, 0x4000);
1220 dib7000p_write_word(state, 770, 0x0000);
1221 msleep(45);
1222
1223 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
1224 tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
1225 if (state->sfn_workaround_active) {
1226 dprintk("SFN workaround is active");
1227 tmp |= (1 << 9);
1228 dib7000p_write_word(state, 166, 0x4000);
1229 } else {
1230 dib7000p_write_word(state, 166, 0x0000);
1231 }
1232 dib7000p_write_word(state, 29, tmp);
1233
1234 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
1235 if (state->timf == 0)
1236 msleep(200);
1237
1238 /* offset loop parameters */
1239
1240 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1241 tmp = (6 << 8) | 0x80;
1242 switch (ch->u.ofdm.transmission_mode) {
1243 case TRANSMISSION_MODE_2K:
1244 tmp |= (2 << 12);
1245 break;
1246 case TRANSMISSION_MODE_4K:
1247 tmp |= (3 << 12);
1248 break;
1249 default:
1250 case TRANSMISSION_MODE_8K:
1251 tmp |= (4 << 12);
1252 break;
1253 }
1254 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */
1255
1256 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1257 tmp = (0 << 4);
1258 switch (ch->u.ofdm.transmission_mode) {
1259 case TRANSMISSION_MODE_2K:
1260 tmp |= 0x6;
1261 break;
1262 case TRANSMISSION_MODE_4K:
1263 tmp |= 0x7;
1264 break;
1265 default:
1266 case TRANSMISSION_MODE_8K:
1267 tmp |= 0x8;
1268 break;
1269 }
1270 dib7000p_write_word(state, 32, tmp);
1271
1272 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1273 tmp = (0 << 4);
1274 switch (ch->u.ofdm.transmission_mode) {
1275 case TRANSMISSION_MODE_2K:
1276 tmp |= 0x6;
1277 break;
1278 case TRANSMISSION_MODE_4K:
1279 tmp |= 0x7;
1280 break;
1281 default:
1282 case TRANSMISSION_MODE_8K:
1283 tmp |= 0x8;
1284 break;
1285 }
1286 dib7000p_write_word(state, 33, tmp);
1287
1288 tmp = dib7000p_read_word(state, 509);
1289 if (!((tmp >> 6) & 0x1)) {
1290 /* restart the fec */
1291 tmp = dib7000p_read_word(state, 771);
1292 dib7000p_write_word(state, 771, tmp | (1 << 1));
1293 dib7000p_write_word(state, 771, tmp);
1294 msleep(40);
1295 tmp = dib7000p_read_word(state, 509);
1296 }
1297 // we achieved a lock - it's time to update the osc freq
1298 if ((tmp >> 6) & 0x1) {
1299 dib7000p_update_timf(state);
1300 /* P_timf_alpha += 2 */
1301 tmp = dib7000p_read_word(state, 26);
1302 dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
1303 }
1304
1305 if (state->cfg.spur_protect)
1306 dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1307
1308 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1309 return 0;
1310}
1311
1312static int dib7000p_wakeup(struct dvb_frontend *demod)
1313{
1314 struct dib7000p_state *state = demod->demodulator_priv;
1315 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
1316 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1317 if (state->version == SOC7090)
1318 dib7000p_sad_calib(state);
1319 return 0;
1320}
1321
1322static int dib7000p_sleep(struct dvb_frontend *demod)
1323{
1324 struct dib7000p_state *state = demod->demodulator_priv;
1325 if (state->version == SOC7090)
1326 return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1327 return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1328}
1329
1330static int dib7000p_identify(struct dib7000p_state *st)
1331{
1332 u16 value;
1333 dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr);
1334
1335 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1336 dprintk("wrong Vendor ID (read=0x%x)", value);
1337 return -EREMOTEIO;
1338 }
1339
1340 if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1341 dprintk("wrong Device ID (%x)", value);
1342 return -EREMOTEIO;
1343 }
1344
1345 return 0;
1346}
1347
1348static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1349{
1350 struct dib7000p_state *state = fe->demodulator_priv;
1351 u16 tps = dib7000p_read_word(state, 463);
1352
1353 fep->inversion = INVERSION_AUTO;
1354
1355 fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth);
1356
1357 switch ((tps >> 8) & 0x3) {
1358 case 0:
1359 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
1360 break;
1361 case 1:
1362 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1363 break;
1364 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1365 }
1366
1367 switch (tps & 0x3) {
1368 case 0:
1369 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1370 break;
1371 case 1:
1372 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
1373 break;
1374 case 2:
1375 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
1376 break;
1377 case 3:
1378 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
1379 break;
1380 }
1381
1382 switch ((tps >> 14) & 0x3) {
1383 case 0:
1384 fep->u.ofdm.constellation = QPSK;
1385 break;
1386 case 1:
1387 fep->u.ofdm.constellation = QAM_16;
1388 break;
1389 case 2:
1390 default:
1391 fep->u.ofdm.constellation = QAM_64;
1392 break;
1393 }
1394
1395 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1396 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1397
1398 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1399 switch ((tps >> 5) & 0x7) {
1400 case 1:
1401 fep->u.ofdm.code_rate_HP = FEC_1_2;
1402 break;
1403 case 2:
1404 fep->u.ofdm.code_rate_HP = FEC_2_3;
1405 break;
1406 case 3:
1407 fep->u.ofdm.code_rate_HP = FEC_3_4;
1408 break;
1409 case 5:
1410 fep->u.ofdm.code_rate_HP = FEC_5_6;
1411 break;
1412 case 7:
1413 default:
1414 fep->u.ofdm.code_rate_HP = FEC_7_8;
1415 break;
1416
1417 }
1418
1419 switch ((tps >> 2) & 0x7) {
1420 case 1:
1421 fep->u.ofdm.code_rate_LP = FEC_1_2;
1422 break;
1423 case 2:
1424 fep->u.ofdm.code_rate_LP = FEC_2_3;
1425 break;
1426 case 3:
1427 fep->u.ofdm.code_rate_LP = FEC_3_4;
1428 break;
1429 case 5:
1430 fep->u.ofdm.code_rate_LP = FEC_5_6;
1431 break;
1432 case 7:
1433 default:
1434 fep->u.ofdm.code_rate_LP = FEC_7_8;
1435 break;
1436 }
1437
1438 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1439
1440 return 0;
1441}
1442
1443static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1444{
1445 struct dib7000p_state *state = fe->demodulator_priv;
1446 int time, ret;
1447
1448 if (state->version == SOC7090) {
1449 dib7090_set_diversity_in(fe, 0);
1450 dib7090_set_output_mode(fe, OUTMODE_HIGH_Z);
1451 } else
1452 dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
1453
1454 /* maybe the parameter has been changed */
1455 state->sfn_workaround_active = buggy_sfn_workaround;
1456
1457 if (fe->ops.tuner_ops.set_params)
1458 fe->ops.tuner_ops.set_params(fe, fep);
1459
1460 /* start up the AGC */
1461 state->agc_state = 0;
1462 do {
1463 time = dib7000p_agc_startup(fe, fep);
1464 if (time != -1)
1465 msleep(time);
1466 } while (time != -1);
1467
1468 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1469 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1470 int i = 800, found;
1471
1472 dib7000p_autosearch_start(fe, fep);
1473 do {
1474 msleep(1);
1475 found = dib7000p_autosearch_is_irq(fe);
1476 } while (found == 0 && i--);
1477
1478 dprintk("autosearch returns: %d", found);
1479 if (found == 0 || found == 1)
1480 return 0;
1481
1482 dib7000p_get_frontend(fe, fep);
1483 }
1484
1485 ret = dib7000p_tune(fe, fep);
1486
1487 /* make this a config parameter */
1488 if (state->version == SOC7090)
1489 dib7090_set_output_mode(fe, state->cfg.output_mode);
1490 else
1491 dib7000p_set_output_mode(state, state->cfg.output_mode);
1492
1493 return ret;
1494}
1495
1496static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
1497{
1498 struct dib7000p_state *state = fe->demodulator_priv;
1499 u16 lock = dib7000p_read_word(state, 509);
1500
1501 *stat = 0;
1502
1503 if (lock & 0x8000)
1504 *stat |= FE_HAS_SIGNAL;
1505 if (lock & 0x3000)
1506 *stat |= FE_HAS_CARRIER;
1507 if (lock & 0x0100)
1508 *stat |= FE_HAS_VITERBI;
1509 if (lock & 0x0010)
1510 *stat |= FE_HAS_SYNC;
1511 if ((lock & 0x0038) == 0x38)
1512 *stat |= FE_HAS_LOCK;
1513
1514 return 0;
1515}
1516
1517static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
1518{
1519 struct dib7000p_state *state = fe->demodulator_priv;
1520 *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1521 return 0;
1522}
1523
1524static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
1525{
1526 struct dib7000p_state *state = fe->demodulator_priv;
1527 *unc = dib7000p_read_word(state, 506);
1528 return 0;
1529}
1530
1531static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1532{
1533 struct dib7000p_state *state = fe->demodulator_priv;
1534 u16 val = dib7000p_read_word(state, 394);
1535 *strength = 65535 - val;
1536 return 0;
1537}
1538
1539static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
1540{
1541 struct dib7000p_state *state = fe->demodulator_priv;
1542 u16 val;
1543 s32 signal_mant, signal_exp, noise_mant, noise_exp;
1544 u32 result = 0;
1545
1546 val = dib7000p_read_word(state, 479);
1547 noise_mant = (val >> 4) & 0xff;
1548 noise_exp = ((val & 0xf) << 2);
1549 val = dib7000p_read_word(state, 480);
1550 noise_exp += ((val >> 14) & 0x3);
1551 if ((noise_exp & 0x20) != 0)
1552 noise_exp -= 0x40;
1553
1554 signal_mant = (val >> 6) & 0xFF;
1555 signal_exp = (val & 0x3F);
1556 if ((signal_exp & 0x20) != 0)
1557 signal_exp -= 0x40;
1558
1559 if (signal_mant != 0)
1560 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
1561 else
1562 result = intlog10(2) * 10 * signal_exp - 100;
1563
1564 if (noise_mant != 0)
1565 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
1566 else
1567 result -= intlog10(2) * 10 * noise_exp - 100;
1568
1569 *snr = result / ((1 << 24) / 10);
1570 return 0;
1571}
1572
1573static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1574{
1575 tune->min_delay_ms = 1000;
1576 return 0;
1577}
1578
1579static void dib7000p_release(struct dvb_frontend *demod)
1580{
1581 struct dib7000p_state *st = demod->demodulator_priv;
1582 dibx000_exit_i2c_master(&st->i2c_master);
1583 i2c_del_adapter(&st->dib7090_tuner_adap);
1584 kfree(st);
1585}
1586
1587int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1588{
1589 u8 *tx, *rx;
1590 struct i2c_msg msg[2] = {
1591 {.addr = 18 >> 1, .flags = 0, .len = 2},
1592 {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
1593 };
1594 int ret = 0;
1595
1596 tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1597 if (!tx)
1598 return -ENOMEM;
1599 rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1600 if (!rx) {
1601 goto rx_memory_error;
1602 ret = -ENOMEM;
1603 }
1604
1605 msg[0].buf = tx;
1606 msg[1].buf = rx;
1607
1608 tx[0] = 0x03;
1609 tx[1] = 0x00;
1610
1611 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1612 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1613 dprintk("-D- DiB7000PC detected");
1614 return 1;
1615 }
1616
1617 msg[0].addr = msg[1].addr = 0x40;
1618
1619 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1620 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1621 dprintk("-D- DiB7000PC detected");
1622 return 1;
1623 }
1624
1625 dprintk("-D- DiB7000PC not detected");
1626
1627 kfree(rx);
1628rx_memory_error:
1629 kfree(tx);
1630 return ret;
1631}
1632EXPORT_SYMBOL(dib7000pc_detection);
1633
1634struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1635{
1636 struct dib7000p_state *st = demod->demodulator_priv;
1637 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1638}
1639EXPORT_SYMBOL(dib7000p_get_i2c_master);
1640
1641int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1642{
1643 struct dib7000p_state *state = fe->demodulator_priv;
1644 u16 val = dib7000p_read_word(state, 235) & 0xffef;
1645 val |= (onoff & 0x1) << 4;
1646 dprintk("PID filter enabled %d", onoff);
1647 return dib7000p_write_word(state, 235, val);
1648}
1649EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
1650
1651int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1652{
1653 struct dib7000p_state *state = fe->demodulator_priv;
1654 dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1655 return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
1656}
1657EXPORT_SYMBOL(dib7000p_pid_filter);
1658
1659int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
1660{
1661 struct dib7000p_state *dpst;
1662 int k = 0;
1663 u8 new_addr = 0;
1664
1665 dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
1666 if (!dpst)
1667 return -ENOMEM;
1668
1669 dpst->i2c_adap = i2c;
1670 mutex_init(&dpst->i2c_buffer_lock);
1671
1672 for (k = no_of_demods - 1; k >= 0; k--) {
1673 dpst->cfg = cfg[k];
1674
1675 /* designated i2c address */
1676 if (cfg[k].default_i2c_addr != 0)
1677 new_addr = cfg[k].default_i2c_addr + (k << 1);
1678 else
1679 new_addr = (0x40 + k) << 1;
1680 dpst->i2c_addr = new_addr;
1681 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1682 if (dib7000p_identify(dpst) != 0) {
1683 dpst->i2c_addr = default_addr;
1684 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1685 if (dib7000p_identify(dpst) != 0) {
1686 dprintk("DiB7000P #%d: not identified\n", k);
1687 kfree(dpst);
1688 return -EIO;
1689 }
1690 }
1691
1692 /* start diversity to pull_down div_str - just for i2c-enumeration */
1693 dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY);
1694
1695 /* set new i2c address and force divstart */
1696 dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2);
1697
1698 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1699 }
1700
1701 for (k = 0; k < no_of_demods; k++) {
1702 dpst->cfg = cfg[k];
1703 if (cfg[k].default_i2c_addr != 0)
1704 dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
1705 else
1706 dpst->i2c_addr = (0x40 + k) << 1;
1707
1708 // unforce divstr
1709 dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
1710
1711 /* deactivate div - it was just for i2c-enumeration */
1712 dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z);
1713 }
1714
1715 kfree(dpst);
1716 return 0;
1717}
1718EXPORT_SYMBOL(dib7000p_i2c_enumeration);
1719
1720static const s32 lut_1000ln_mant[] = {
1721 6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
1722};
1723
1724static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
1725{
1726 struct dib7000p_state *state = fe->demodulator_priv;
1727 u32 tmp_val = 0, exp = 0, mant = 0;
1728 s32 pow_i;
1729 u16 buf[2];
1730 u8 ix = 0;
1731
1732 buf[0] = dib7000p_read_word(state, 0x184);
1733 buf[1] = dib7000p_read_word(state, 0x185);
1734 pow_i = (buf[0] << 16) | buf[1];
1735 dprintk("raw pow_i = %d", pow_i);
1736
1737 tmp_val = pow_i;
1738 while (tmp_val >>= 1)
1739 exp++;
1740
1741 mant = (pow_i * 1000 / (1 << exp));
1742 dprintk(" mant = %d exp = %d", mant / 1000, exp);
1743
1744 ix = (u8) ((mant - 1000) / 100); /* index of the LUT */
1745 dprintk(" ix = %d", ix);
1746
1747 pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
1748 pow_i = (pow_i << 8) / 1000;
1749 dprintk(" pow_i = %d", pow_i);
1750
1751 return pow_i;
1752}
1753
1754static int map_addr_to_serpar_number(struct i2c_msg *msg)
1755{
1756 if ((msg->buf[0] <= 15))
1757 msg->buf[0] -= 1;
1758 else if (msg->buf[0] == 17)
1759 msg->buf[0] = 15;
1760 else if (msg->buf[0] == 16)
1761 msg->buf[0] = 17;
1762 else if (msg->buf[0] == 19)
1763 msg->buf[0] = 16;
1764 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1765 msg->buf[0] -= 3;
1766 else if (msg->buf[0] == 28)
1767 msg->buf[0] = 23;
1768 else
1769 return -EINVAL;
1770 return 0;
1771}
1772
1773static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1774{
1775 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1776 u8 n_overflow = 1;
1777 u16 i = 1000;
1778 u16 serpar_num = msg[0].buf[0];
1779
1780 while (n_overflow == 1 && i) {
1781 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1782 i--;
1783 if (i == 0)
1784 dprintk("Tuner ITF: write busy (overflow)");
1785 }
1786 dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1787 dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1788
1789 return num;
1790}
1791
1792static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1793{
1794 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1795 u8 n_overflow = 1, n_empty = 1;
1796 u16 i = 1000;
1797 u16 serpar_num = msg[0].buf[0];
1798 u16 read_word;
1799
1800 while (n_overflow == 1 && i) {
1801 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1802 i--;
1803 if (i == 0)
1804 dprintk("TunerITF: read busy (overflow)");
1805 }
1806 dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
1807
1808 i = 1000;
1809 while (n_empty == 1 && i) {
1810 n_empty = dib7000p_read_word(state, 1984) & 0x1;
1811 i--;
1812 if (i == 0)
1813 dprintk("TunerITF: read busy (empty)");
1814 }
1815 read_word = dib7000p_read_word(state, 1987);
1816 msg[1].buf[0] = (read_word >> 8) & 0xff;
1817 msg[1].buf[1] = (read_word) & 0xff;
1818
1819 return num;
1820}
1821
1822static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1823{
1824 if (map_addr_to_serpar_number(&msg[0]) == 0) { /* else = Tuner regs to ignore : DIG_CFG, CTRL_RF_LT, PLL_CFG, PWM1_REG, ADCCLK, DIG_CFG_3; SLEEP_EN... */
1825 if (num == 1) { /* write */
1826 return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
1827 } else { /* read */
1828 return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
1829 }
1830 }
1831 return num;
1832}
1833
1834int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address)
1835{
1836 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1837 u16 word;
1838
1839 if (num == 1) { /* write */
1840 dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1841 } else {
1842 word = dib7000p_read_word(state, apb_address);
1843 msg[1].buf[0] = (word >> 8) & 0xff;
1844 msg[1].buf[1] = (word) & 0xff;
1845 }
1846
1847 return num;
1848}
1849
1850static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1851{
1852 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1853
1854 u16 apb_address = 0, word;
1855 int i = 0;
1856 switch (msg[0].buf[0]) {
1857 case 0x12:
1858 apb_address = 1920;
1859 break;
1860 case 0x14:
1861 apb_address = 1921;
1862 break;
1863 case 0x24:
1864 apb_address = 1922;
1865 break;
1866 case 0x1a:
1867 apb_address = 1923;
1868 break;
1869 case 0x22:
1870 apb_address = 1924;
1871 break;
1872 case 0x33:
1873 apb_address = 1926;
1874 break;
1875 case 0x34:
1876 apb_address = 1927;
1877 break;
1878 case 0x35:
1879 apb_address = 1928;
1880 break;
1881 case 0x36:
1882 apb_address = 1929;
1883 break;
1884 case 0x37:
1885 apb_address = 1930;
1886 break;
1887 case 0x38:
1888 apb_address = 1931;
1889 break;
1890 case 0x39:
1891 apb_address = 1932;
1892 break;
1893 case 0x2a:
1894 apb_address = 1935;
1895 break;
1896 case 0x2b:
1897 apb_address = 1936;
1898 break;
1899 case 0x2c:
1900 apb_address = 1937;
1901 break;
1902 case 0x2d:
1903 apb_address = 1938;
1904 break;
1905 case 0x2e:
1906 apb_address = 1939;
1907 break;
1908 case 0x2f:
1909 apb_address = 1940;
1910 break;
1911 case 0x30:
1912 apb_address = 1941;
1913 break;
1914 case 0x31:
1915 apb_address = 1942;
1916 break;
1917 case 0x32:
1918 apb_address = 1943;
1919 break;
1920 case 0x3e:
1921 apb_address = 1944;
1922 break;
1923 case 0x3f:
1924 apb_address = 1945;
1925 break;
1926 case 0x40:
1927 apb_address = 1948;
1928 break;
1929 case 0x25:
1930 apb_address = 914;
1931 break;
1932 case 0x26:
1933 apb_address = 915;
1934 break;
1935 case 0x27:
1936 apb_address = 916;
1937 break;
1938 case 0x28:
1939 apb_address = 917;
1940 break;
1941 case 0x1d:
1942 i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
1943 word = dib7000p_read_word(state, 384 + i);
1944 msg[1].buf[0] = (word >> 8) & 0xff;
1945 msg[1].buf[1] = (word) & 0xff;
1946 return num;
1947 case 0x1f:
1948 if (num == 1) { /* write */
1949 word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
1950 word &= 0x3;
1951 word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12);
1952 dib7000p_write_word(state, 72, word); /* Set the proper input */
1953 return num;
1954 }
1955 }
1956
1957 if (apb_address != 0) /* R/W acces via APB */
1958 return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
1959 else /* R/W access via SERPAR */
1960 return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
1961
1962 return 0;
1963}
1964
1965static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
1966{
1967 return I2C_FUNC_I2C;
1968}
1969
1970static struct i2c_algorithm dib7090_tuner_xfer_algo = {
1971 .master_xfer = dib7090_tuner_xfer,
1972 .functionality = dib7000p_i2c_func,
1973};
1974
1975struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
1976{
1977 struct dib7000p_state *st = fe->demodulator_priv;
1978 return &st->dib7090_tuner_adap;
1979}
1980EXPORT_SYMBOL(dib7090_get_i2c_tuner);
1981
1982static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
1983{
1984 u16 reg;
1985
1986 /* drive host bus 2, 3, 4 */
1987 reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1988 reg |= (drive << 12) | (drive << 6) | drive;
1989 dib7000p_write_word(state, 1798, reg);
1990
1991 /* drive host bus 5,6 */
1992 reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1993 reg |= (drive << 8) | (drive << 2);
1994 dib7000p_write_word(state, 1799, reg);
1995
1996 /* drive host bus 7, 8, 9 */
1997 reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1998 reg |= (drive << 12) | (drive << 6) | drive;
1999 dib7000p_write_word(state, 1800, reg);
2000
2001 /* drive host bus 10, 11 */
2002 reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
2003 reg |= (drive << 8) | (drive << 2);
2004 dib7000p_write_word(state, 1801, reg);
2005
2006 /* drive host bus 12, 13, 14 */
2007 reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2008 reg |= (drive << 12) | (drive << 6) | drive;
2009 dib7000p_write_word(state, 1802, reg);
2010
2011 return 0;
2012}
2013
2014static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
2015{
2016 u32 quantif = 3;
2017 u32 nom = (insertExtSynchro * P_Kin + syncSize);
2018 u32 denom = P_Kout;
2019 u32 syncFreq = ((nom << quantif) / denom);
2020
2021 if ((syncFreq & ((1 << quantif) - 1)) != 0)
2022 syncFreq = (syncFreq >> quantif) + 1;
2023 else
2024 syncFreq = (syncFreq >> quantif);
2025
2026 if (syncFreq != 0)
2027 syncFreq = syncFreq - 1;
2028
2029 return syncFreq;
2030}
2031
2032static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
2033{
2034 u8 index_buf;
2035 u16 rx_copy_buf[22];
2036
2037 dprintk("Configure DibStream Tx");
2038 for (index_buf = 0; index_buf < 22; index_buf++)
2039 rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf);
2040
2041 dib7000p_write_word(state, 1615, 1);
2042 dib7000p_write_word(state, 1603, P_Kin);
2043 dib7000p_write_word(state, 1605, P_Kout);
2044 dib7000p_write_word(state, 1606, insertExtSynchro);
2045 dib7000p_write_word(state, 1608, synchroMode);
2046 dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
2047 dib7000p_write_word(state, 1610, syncWord & 0xffff);
2048 dib7000p_write_word(state, 1612, syncSize);
2049 dib7000p_write_word(state, 1615, 0);
2050
2051 for (index_buf = 0; index_buf < 22; index_buf++)
2052 dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]);
2053
2054 return 0;
2055}
2056
2057static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
2058 u32 dataOutRate)
2059{
2060 u32 syncFreq;
2061
2062 dprintk("Configure DibStream Rx");
2063 if ((P_Kin != 0) && (P_Kout != 0)) {
2064 syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
2065 dib7000p_write_word(state, 1542, syncFreq);
2066 }
2067 dib7000p_write_word(state, 1554, 1);
2068 dib7000p_write_word(state, 1536, P_Kin);
2069 dib7000p_write_word(state, 1537, P_Kout);
2070 dib7000p_write_word(state, 1539, synchroMode);
2071 dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
2072 dib7000p_write_word(state, 1541, syncWord & 0xffff);
2073 dib7000p_write_word(state, 1543, syncSize);
2074 dib7000p_write_word(state, 1544, dataOutRate);
2075 dib7000p_write_word(state, 1554, 0);
2076
2077 return 0;
2078}
2079
2080static int dib7090_enDivOnHostBus(struct dib7000p_state *state)
2081{
2082 u16 reg;
2083
2084 dprintk("Enable Diversity on host bus");
2085 reg = (1 << 8) | (1 << 5);
2086 dib7000p_write_word(state, 1288, reg);
2087
2088 return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
2089}
2090
2091static int dib7090_enAdcOnHostBus(struct dib7000p_state *state)
2092{
2093 u16 reg;
2094
2095 dprintk("Enable ADC on host bus");
2096 reg = (1 << 7) | (1 << 5);
2097 dib7000p_write_word(state, 1288, reg);
2098
2099 return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
2100}
2101
2102static int dib7090_enMpegOnHostBus(struct dib7000p_state *state)
2103{
2104 u16 reg;
2105
2106 dprintk("Enable Mpeg on host bus");
2107 reg = (1 << 9) | (1 << 5);
2108 dib7000p_write_word(state, 1288, reg);
2109
2110 return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
2111}
2112
2113static int dib7090_enMpegInput(struct dib7000p_state *state)
2114{
2115 dprintk("Enable Mpeg input");
2116 return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2117}
2118
2119static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
2120{
2121 u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1);
2122
2123 dprintk("Enable Mpeg mux");
2124 dib7000p_write_word(state, 1287, reg);
2125
2126 reg &= ~(1 << 7);
2127 dib7000p_write_word(state, 1287, reg);
2128
2129 reg = (1 << 4);
2130 dib7000p_write_word(state, 1288, reg);
2131
2132 return 0;
2133}
2134
2135static int dib7090_disableMpegMux(struct dib7000p_state *state)
2136{
2137 u16 reg;
2138
2139 dprintk("Disable Mpeg mux");
2140 dib7000p_write_word(state, 1288, 0);
2141
2142 reg = dib7000p_read_word(state, 1287);
2143 reg &= ~(1 << 7);
2144 dib7000p_write_word(state, 1287, reg);
2145
2146 return 0;
2147}
2148
2149static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode)
2150{
2151 struct dib7000p_state *state = fe->demodulator_priv;
2152
2153 switch (mode) {
2154 case INPUT_MODE_DIVERSITY:
2155 dprintk("Enable diversity INPUT");
2156 dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
2157 break;
2158 case INPUT_MODE_MPEG:
2159 dprintk("Enable Mpeg INPUT");
2160 dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2161 break;
2162 case INPUT_MODE_OFF:
2163 default:
2164 dprintk("Disable INPUT");
2165 dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0);
2166 break;
2167 }
2168 return 0;
2169}
2170
2171static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
2172{
2173 switch (onoff) {
2174 case 0: /* only use the internal way - not the diversity input */
2175 dib7090_set_input_mode(fe, INPUT_MODE_MPEG);
2176 break;
2177 case 1: /* both ways */
2178 case 2: /* only the diversity input */
2179 dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY);
2180 break;
2181 }
2182
2183 return 0;
2184}
2185
2186static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
2187{
2188 struct dib7000p_state *state = fe->demodulator_priv;
2189
2190 u16 outreg, smo_mode, fifo_threshold;
2191 u8 prefer_mpeg_mux_use = 1;
2192 int ret = 0;
2193
2194 dib7090_host_bus_drive(state, 1);
2195
2196 fifo_threshold = 1792;
2197 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
2198 outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2199
2200 switch (mode) {
2201 case OUTMODE_HIGH_Z:
2202 outreg = 0;
2203 break;
2204
2205 case OUTMODE_MPEG2_SERIAL:
2206 if (prefer_mpeg_mux_use) {
2207 dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux");
2208 dib7090_enMpegOnHostBus(state);
2209 dib7090_enMpegInput(state);
2210 if (state->cfg.enMpegOutput == 1)
2211 dib7090_enMpegMux(state, 3, 1, 1);
2212
2213 } else { /* Use Smooth block */
2214 dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc");
2215 dib7090_disableMpegMux(state);
2216 dib7000p_write_word(state, 1288, (1 << 6));
2217 outreg |= (2 << 6) | (0 << 1);
2218 }
2219 break;
2220
2221 case OUTMODE_MPEG2_PAR_GATED_CLK:
2222 if (prefer_mpeg_mux_use) {
2223 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
2224 dib7090_enMpegOnHostBus(state);
2225 dib7090_enMpegInput(state);
2226 if (state->cfg.enMpegOutput == 1)
2227 dib7090_enMpegMux(state, 2, 0, 0);
2228 } else { /* Use Smooth block */
2229 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block");
2230 dib7090_disableMpegMux(state);
2231 dib7000p_write_word(state, 1288, (1 << 6));
2232 outreg |= (0 << 6);
2233 }
2234 break;
2235
2236 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
2237 dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block");
2238 dib7090_disableMpegMux(state);
2239 dib7000p_write_word(state, 1288, (1 << 6));
2240 outreg |= (1 << 6);
2241 break;
2242
2243 case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */
2244 dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block");
2245 dib7090_disableMpegMux(state);
2246 dib7000p_write_word(state, 1288, (1 << 6));
2247 outreg |= (5 << 6);
2248 smo_mode |= (3 << 1);
2249 fifo_threshold = 512;
2250 break;
2251
2252 case OUTMODE_DIVERSITY:
2253 dprintk("Sip 7090P setting output mode MODE_DIVERSITY");
2254 dib7090_disableMpegMux(state);
2255 dib7090_enDivOnHostBus(state);
2256 break;
2257
2258 case OUTMODE_ANALOG_ADC:
2259 dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC");
2260 dib7090_enAdcOnHostBus(state);
2261 break;
2262 }
2263
2264 if (state->cfg.output_mpeg2_in_188_bytes)
2265 smo_mode |= (1 << 5);
2266
2267 ret |= dib7000p_write_word(state, 235, smo_mode);
2268 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
2269 ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10)); /* allways set Dout active = 1 !!! */
2270
2271 return ret;
2272}
2273
2274int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
2275{
2276 struct dib7000p_state *state = fe->demodulator_priv;
2277 u16 en_cur_state;
2278
2279 dprintk("sleep dib7090: %d", onoff);
2280
2281 en_cur_state = dib7000p_read_word(state, 1922);
2282
2283 if (en_cur_state > 0xff)
2284 state->tuner_enable = en_cur_state;
2285
2286 if (onoff)
2287 en_cur_state &= 0x00ff;
2288 else {
2289 if (state->tuner_enable != 0)
2290 en_cur_state = state->tuner_enable;
2291 }
2292
2293 dib7000p_write_word(state, 1922, en_cur_state);
2294
2295 return 0;
2296}
2297EXPORT_SYMBOL(dib7090_tuner_sleep);
2298
2299int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
2300{
2301 dprintk("AGC restart callback: %d", restart);
2302 return 0;
2303}
2304EXPORT_SYMBOL(dib7090_agc_restart);
2305
2306int dib7090_get_adc_power(struct dvb_frontend *fe)
2307{
2308 return dib7000p_get_adc_power(fe);
2309}
2310EXPORT_SYMBOL(dib7090_get_adc_power);
2311
2312int dib7090_slave_reset(struct dvb_frontend *fe)
2313{
2314 struct dib7000p_state *state = fe->demodulator_priv;
2315 u16 reg;
2316
2317 reg = dib7000p_read_word(state, 1794);
2318 dib7000p_write_word(state, 1794, reg | (4 << 12));
2319
2320 dib7000p_write_word(state, 1032, 0xffff);
2321 return 0;
2322}
2323EXPORT_SYMBOL(dib7090_slave_reset);
2324
2325static struct dvb_frontend_ops dib7000p_ops;
2326struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
2327{
2328 struct dvb_frontend *demod;
2329 struct dib7000p_state *st;
2330 st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
2331 if (st == NULL)
2332 return NULL;
2333
2334 memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
2335 st->i2c_adap = i2c_adap;
2336 st->i2c_addr = i2c_addr;
2337 st->gpio_val = cfg->gpio_val;
2338 st->gpio_dir = cfg->gpio_dir;
2339
2340 /* Ensure the output mode remains at the previous default if it's
2341 * not specifically set by the caller.
2342 */
2343 if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2344 st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2345
2346 demod = &st->demod;
2347 demod->demodulator_priv = st;
2348 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
2349 mutex_init(&st->i2c_buffer_lock);
2350
2351 dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */
2352
2353 if (dib7000p_identify(st) != 0)
2354 goto error;
2355
2356 st->version = dib7000p_read_word(st, 897);
2357
2358 /* FIXME: make sure the dev.parent field is initialized, or else
2359 request_firmware() will hit an OOPS (this should be moved somewhere
2360 more common) */
2361 st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
2362
2363 /* FIXME: make sure the dev.parent field is initialized, or else
2364 request_firmware() will hit an OOPS (this should be moved somewhere
2365 more common) */
2366 st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
2367
2368 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
2369
2370 /* init 7090 tuner adapter */
2371 strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name));
2372 st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
2373 st->dib7090_tuner_adap.algo_data = NULL;
2374 st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
2375 i2c_set_adapdata(&st->dib7090_tuner_adap, st);
2376 i2c_add_adapter(&st->dib7090_tuner_adap);
2377
2378 dib7000p_demod_reset(st);
2379
2380 if (st->version == SOC7090) {
2381 dib7090_set_output_mode(demod, st->cfg.output_mode);
2382 dib7090_set_diversity_in(demod, 0);
2383 }
2384
2385 return demod;
2386
2387error:
2388 kfree(st);
2389 return NULL;
2390}
2391EXPORT_SYMBOL(dib7000p_attach);
2392
2393static struct dvb_frontend_ops dib7000p_ops = {
2394 .info = {
2395 .name = "DiBcom 7000PC",
2396 .type = FE_OFDM,
2397 .frequency_min = 44250000,
2398 .frequency_max = 867250000,
2399 .frequency_stepsize = 62500,
2400 .caps = FE_CAN_INVERSION_AUTO |
2401 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2402 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2403 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2404 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2405 },
2406
2407 .release = dib7000p_release,
2408
2409 .init = dib7000p_wakeup,
2410 .sleep = dib7000p_sleep,
2411
2412 .set_frontend = dib7000p_set_frontend,
2413 .get_tune_settings = dib7000p_fe_get_tune_settings,
2414 .get_frontend = dib7000p_get_frontend,
2415
2416 .read_status = dib7000p_read_status,
2417 .read_ber = dib7000p_read_ber,
2418 .read_signal_strength = dib7000p_read_signal_strength,
2419 .read_snr = dib7000p_read_snr,
2420 .read_ucblocks = dib7000p_read_unc_blocks,
2421};
2422
2423MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
2424MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
2425MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
2426MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h
new file mode 100644
index 00000000000..0179f9474ba
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib7000p.h
@@ -0,0 +1,156 @@
1#ifndef DIB7000P_H
2#define DIB7000P_H
3
4#include "dibx000_common.h"
5
6struct dib7000p_config {
7 u8 output_mpeg2_in_188_bytes;
8 u8 hostbus_diversity;
9 u8 tuner_is_baseband;
10 int (*update_lna) (struct dvb_frontend *, u16 agc_global);
11
12 u8 agc_config_count;
13 struct dibx000_agc_config *agc;
14 struct dibx000_bandwidth_config *bw;
15
16#define DIB7000P_GPIO_DEFAULT_DIRECTIONS 0xffff
17 u16 gpio_dir;
18#define DIB7000P_GPIO_DEFAULT_VALUES 0x0000
19 u16 gpio_val;
20#define DIB7000P_GPIO_PWM_POS0(v) ((v & 0xf) << 12)
21#define DIB7000P_GPIO_PWM_POS1(v) ((v & 0xf) << 8 )
22#define DIB7000P_GPIO_PWM_POS2(v) ((v & 0xf) << 4 )
23#define DIB7000P_GPIO_PWM_POS3(v) (v & 0xf)
24#define DIB7000P_GPIO_DEFAULT_PWM_POS 0xffff
25 u16 gpio_pwm_pos;
26
27 u16 pwm_freq_div;
28
29 u8 quartz_direct;
30
31 u8 spur_protect;
32
33 int (*agc_control) (struct dvb_frontend *, u8 before);
34
35 u8 output_mode;
36 u8 disable_sample_and_hold:1;
37
38 u8 enable_current_mirror:1;
39 u16 diversity_delay;
40
41 u8 default_i2c_addr;
42 u8 enMpegOutput:1;
43};
44
45#define DEFAULT_DIB7000P_I2C_ADDRESS 18
46
47#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && \
48 defined(MODULE))
49extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
50extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
51extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
52extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
53extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
54extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
55extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
56extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
57extern int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw);
58extern u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf);
59extern int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart);
60extern int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff);
61extern int dib7090_get_adc_power(struct dvb_frontend *fe);
62extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe);
63extern int dib7090_slave_reset(struct dvb_frontend *fe);
64#else
65static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
66{
67 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
68 return NULL;
69}
70
71static inline struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
72{
73 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
74 return NULL;
75}
76
77static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
78{
79 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
80 return -ENODEV;
81}
82
83static inline int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
84{
85 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
86 return -ENODEV;
87}
88
89static inline int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
90{
91 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
92 return -ENODEV;
93}
94
95static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap)
96{
97 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
98 return -ENODEV;
99}
100
101static inline int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
102{
103 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
104 return -ENODEV;
105}
106
107static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff)
108{
109 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
110 return -ENODEV;
111}
112
113static inline int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
114{
115 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
116 return -ENODEV;
117}
118
119static inline u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
120{
121 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
122 return 0;
123}
124
125static inline int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
126{
127 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
128 return -ENODEV;
129}
130
131static inline int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
132{
133 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
134 return -ENODEV;
135}
136
137static inline int dib7090_get_adc_power(struct dvb_frontend *fe)
138{
139 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
140 return -ENODEV;
141}
142
143static inline struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
144{
145 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
146 return NULL;
147}
148
149static inline int dib7090_slave_reset(struct dvb_frontend *fe)
150{
151 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
152 return -ENODEV;
153}
154#endif
155
156#endif
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
new file mode 100644
index 00000000000..fe284d5292f
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib8000.c
@@ -0,0 +1,2669 @@
1/*
2 * Linux-DVB Driver for DiBcom's DiB8000 chip (ISDB-T).
3 *
4 * Copyright (C) 2009 DiBcom (http://www.dibcom.fr/)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 */
10#include <linux/kernel.h>
11#include <linux/slab.h>
12#include <linux/i2c.h>
13#include <linux/mutex.h>
14
15#include "dvb_math.h"
16
17#include "dvb_frontend.h"
18
19#include "dib8000.h"
20
21#define LAYER_ALL -1
22#define LAYER_A 1
23#define LAYER_B 2
24#define LAYER_C 3
25
26#define FE_CALLBACK_TIME_NEVER 0xffffffff
27#define MAX_NUMBER_OF_FRONTENDS 6
28
29static int debug;
30module_param(debug, int, 0644);
31MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
32
33#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
34
35#define FE_STATUS_TUNE_FAILED 0
36
37struct i2c_device {
38 struct i2c_adapter *adap;
39 u8 addr;
40 u8 *i2c_write_buffer;
41 u8 *i2c_read_buffer;
42 struct mutex *i2c_buffer_lock;
43};
44
45struct dib8000_state {
46 struct dib8000_config cfg;
47
48 struct i2c_device i2c;
49
50 struct dibx000_i2c_master i2c_master;
51
52 u16 wbd_ref;
53
54 u8 current_band;
55 u32 current_bandwidth;
56 struct dibx000_agc_config *current_agc;
57 u32 timf;
58 u32 timf_default;
59
60 u8 div_force_off:1;
61 u8 div_state:1;
62 u16 div_sync_wait;
63
64 u8 agc_state;
65 u8 differential_constellation;
66 u8 diversity_onoff;
67
68 s16 ber_monitored_layer;
69 u16 gpio_dir;
70 u16 gpio_val;
71
72 u16 revision;
73 u8 isdbt_cfg_loaded;
74 enum frontend_tune_state tune_state;
75 u32 status;
76
77 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
78
79 /* for the I2C transfer */
80 struct i2c_msg msg[2];
81 u8 i2c_write_buffer[4];
82 u8 i2c_read_buffer[2];
83 struct mutex i2c_buffer_lock;
84};
85
86enum dib8000_power_mode {
87 DIB8000M_POWER_ALL = 0,
88 DIB8000M_POWER_INTERFACE_ONLY,
89};
90
91static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
92{
93 u16 ret;
94 struct i2c_msg msg[2] = {
95 {.addr = i2c->addr >> 1, .flags = 0, .len = 2},
96 {.addr = i2c->addr >> 1, .flags = I2C_M_RD, .len = 2},
97 };
98
99 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
100 dprintk("could not acquire lock");
101 return 0;
102 }
103
104 msg[0].buf = i2c->i2c_write_buffer;
105 msg[0].buf[0] = reg >> 8;
106 msg[0].buf[1] = reg & 0xff;
107 msg[1].buf = i2c->i2c_read_buffer;
108
109 if (i2c_transfer(i2c->adap, msg, 2) != 2)
110 dprintk("i2c read error on %d", reg);
111
112 ret = (msg[1].buf[0] << 8) | msg[1].buf[1];
113 mutex_unlock(i2c->i2c_buffer_lock);
114 return ret;
115}
116
117static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
118{
119 u16 ret;
120
121 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
122 dprintk("could not acquire lock");
123 return 0;
124 }
125
126 state->i2c_write_buffer[0] = reg >> 8;
127 state->i2c_write_buffer[1] = reg & 0xff;
128
129 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
130 state->msg[0].addr = state->i2c.addr >> 1;
131 state->msg[0].flags = 0;
132 state->msg[0].buf = state->i2c_write_buffer;
133 state->msg[0].len = 2;
134 state->msg[1].addr = state->i2c.addr >> 1;
135 state->msg[1].flags = I2C_M_RD;
136 state->msg[1].buf = state->i2c_read_buffer;
137 state->msg[1].len = 2;
138
139 if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
140 dprintk("i2c read error on %d", reg);
141
142 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
143 mutex_unlock(&state->i2c_buffer_lock);
144
145 return ret;
146}
147
148static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
149{
150 u16 rw[2];
151
152 rw[0] = dib8000_read_word(state, reg + 0);
153 rw[1] = dib8000_read_word(state, reg + 1);
154
155 return ((rw[0] << 16) | (rw[1]));
156}
157
158static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
159{
160 struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, .len = 4};
161 int ret = 0;
162
163 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
164 dprintk("could not acquire lock");
165 return -EINVAL;
166 }
167
168 msg.buf = i2c->i2c_write_buffer;
169 msg.buf[0] = (reg >> 8) & 0xff;
170 msg.buf[1] = reg & 0xff;
171 msg.buf[2] = (val >> 8) & 0xff;
172 msg.buf[3] = val & 0xff;
173
174 ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
175 mutex_unlock(i2c->i2c_buffer_lock);
176
177 return ret;
178}
179
180static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
181{
182 int ret;
183
184 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
185 dprintk("could not acquire lock");
186 return -EINVAL;
187 }
188
189 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
190 state->i2c_write_buffer[1] = reg & 0xff;
191 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
192 state->i2c_write_buffer[3] = val & 0xff;
193
194 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
195 state->msg[0].addr = state->i2c.addr >> 1;
196 state->msg[0].flags = 0;
197 state->msg[0].buf = state->i2c_write_buffer;
198 state->msg[0].len = 4;
199
200 ret = (i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ?
201 -EREMOTEIO : 0);
202 mutex_unlock(&state->i2c_buffer_lock);
203
204 return ret;
205}
206
207static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
208 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
209 (920 << 5) | 0x09
210};
211
212static const s16 coeff_2k_sb_1seg[8] = {
213 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
214};
215
216static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
217 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
218 (-931 << 5) | 0x0f
219};
220
221static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
222 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
223 (982 << 5) | 0x0c
224};
225
226static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
227 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
228 (-720 << 5) | 0x0d
229};
230
231static const s16 coeff_2k_sb_3seg[8] = {
232 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
233 (-610 << 5) | 0x0a
234};
235
236static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
237 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
238 (-922 << 5) | 0x0d
239};
240
241static const s16 coeff_4k_sb_1seg[8] = {
242 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
243 (-655 << 5) | 0x0a
244};
245
246static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
247 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
248 (-958 << 5) | 0x13
249};
250
251static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
252 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
253 (-568 << 5) | 0x0f
254};
255
256static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
257 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
258 (-848 << 5) | 0x13
259};
260
261static const s16 coeff_4k_sb_3seg[8] = {
262 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
263 (-869 << 5) | 0x13
264};
265
266static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
267 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
268 (-598 << 5) | 0x10
269};
270
271static const s16 coeff_8k_sb_1seg[8] = {
272 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
273 (585 << 5) | 0x0f
274};
275
276static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
277 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
278 (0 << 5) | 0x14
279};
280
281static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
282 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
283 (-877 << 5) | 0x15
284};
285
286static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
287 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
288 (-921 << 5) | 0x14
289};
290
291static const s16 coeff_8k_sb_3seg[8] = {
292 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
293 (690 << 5) | 0x14
294};
295
296static const s16 ana_fe_coeff_3seg[24] = {
297 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
298};
299
300static const s16 ana_fe_coeff_1seg[24] = {
301 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
302};
303
304static const s16 ana_fe_coeff_13seg[24] = {
305 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
306};
307
308static u16 fft_to_mode(struct dib8000_state *state)
309{
310 u16 mode;
311 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
312 case TRANSMISSION_MODE_2K:
313 mode = 1;
314 break;
315 case TRANSMISSION_MODE_4K:
316 mode = 2;
317 break;
318 default:
319 case TRANSMISSION_MODE_AUTO:
320 case TRANSMISSION_MODE_8K:
321 mode = 3;
322 break;
323 }
324 return mode;
325}
326
327static void dib8000_set_acquisition_mode(struct dib8000_state *state)
328{
329 u16 nud = dib8000_read_word(state, 298);
330 nud |= (1 << 3) | (1 << 0);
331 dprintk("acquisition mode activated");
332 dib8000_write_word(state, 298, nud);
333}
334static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
335{
336 struct dib8000_state *state = fe->demodulator_priv;
337
338 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
339
340 outreg = 0;
341 fifo_threshold = 1792;
342 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
343
344 dprintk("-I- Setting output mode for demod %p to %d",
345 &state->fe[0], mode);
346
347 switch (mode) {
348 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
349 outreg = (1 << 10); /* 0x0400 */
350 break;
351 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
352 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
353 break;
354 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
355 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
356 break;
357 case OUTMODE_DIVERSITY:
358 if (state->cfg.hostbus_diversity) {
359 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
360 sram &= 0xfdff;
361 } else
362 sram |= 0x0c00;
363 break;
364 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
365 smo_mode |= (3 << 1);
366 fifo_threshold = 512;
367 outreg = (1 << 10) | (5 << 6);
368 break;
369 case OUTMODE_HIGH_Z: // disable
370 outreg = 0;
371 break;
372
373 case OUTMODE_ANALOG_ADC:
374 outreg = (1 << 10) | (3 << 6);
375 dib8000_set_acquisition_mode(state);
376 break;
377
378 default:
379 dprintk("Unhandled output_mode passed to be set for demod %p",
380 &state->fe[0]);
381 return -EINVAL;
382 }
383
384 if (state->cfg.output_mpeg2_in_188_bytes)
385 smo_mode |= (1 << 5);
386
387 dib8000_write_word(state, 299, smo_mode);
388 dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
389 dib8000_write_word(state, 1286, outreg);
390 dib8000_write_word(state, 1291, sram);
391
392 return 0;
393}
394
395static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
396{
397 struct dib8000_state *state = fe->demodulator_priv;
398 u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
399
400 if (!state->differential_constellation) {
401 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
402 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
403 } else {
404 dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0
405 dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0
406 }
407 state->diversity_onoff = onoff;
408
409 switch (onoff) {
410 case 0: /* only use the internal way - not the diversity input */
411 dib8000_write_word(state, 270, 1);
412 dib8000_write_word(state, 271, 0);
413 break;
414 case 1: /* both ways */
415 dib8000_write_word(state, 270, 6);
416 dib8000_write_word(state, 271, 6);
417 break;
418 case 2: /* only the diversity input */
419 dib8000_write_word(state, 270, 0);
420 dib8000_write_word(state, 271, 1);
421 break;
422 }
423 return 0;
424}
425
426static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
427{
428 /* by default everything is going to be powered off */
429 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
430 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
431 reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
432
433 /* now, depending on the requested mode, we power on */
434 switch (mode) {
435 /* power up everything in the demod */
436 case DIB8000M_POWER_ALL:
437 reg_774 = 0x0000;
438 reg_775 = 0x0000;
439 reg_776 = 0x0000;
440 reg_900 &= 0xfffc;
441 reg_1280 &= 0x00ff;
442 break;
443 case DIB8000M_POWER_INTERFACE_ONLY:
444 reg_1280 &= 0x00ff;
445 break;
446 }
447
448 dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
449 dib8000_write_word(state, 774, reg_774);
450 dib8000_write_word(state, 775, reg_775);
451 dib8000_write_word(state, 776, reg_776);
452 dib8000_write_word(state, 900, reg_900);
453 dib8000_write_word(state, 1280, reg_1280);
454}
455
456static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
457{
458 int ret = 0;
459 u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908);
460
461 switch (no) {
462 case DIBX000_SLOW_ADC_ON:
463 reg_908 |= (1 << 1) | (1 << 0);
464 ret |= dib8000_write_word(state, 908, reg_908);
465 reg_908 &= ~(1 << 1);
466 break;
467
468 case DIBX000_SLOW_ADC_OFF:
469 reg_908 |= (1 << 1) | (1 << 0);
470 break;
471
472 case DIBX000_ADC_ON:
473 reg_907 &= 0x0fff;
474 reg_908 &= 0x0003;
475 break;
476
477 case DIBX000_ADC_OFF: // leave the VBG voltage on
478 reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
479 reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
480 break;
481
482 case DIBX000_VBG_ENABLE:
483 reg_907 &= ~(1 << 15);
484 break;
485
486 case DIBX000_VBG_DISABLE:
487 reg_907 |= (1 << 15);
488 break;
489
490 default:
491 break;
492 }
493
494 ret |= dib8000_write_word(state, 907, reg_907);
495 ret |= dib8000_write_word(state, 908, reg_908);
496
497 return ret;
498}
499
500static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
501{
502 struct dib8000_state *state = fe->demodulator_priv;
503 u32 timf;
504
505 if (bw == 0)
506 bw = 6000;
507
508 if (state->timf == 0) {
509 dprintk("using default timf");
510 timf = state->timf_default;
511 } else {
512 dprintk("using updated timf");
513 timf = state->timf;
514 }
515
516 dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
517 dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
518
519 return 0;
520}
521
522static int dib8000_sad_calib(struct dib8000_state *state)
523{
524/* internal */
525 dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
526 dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096
527
528 /* do the calibration */
529 dib8000_write_word(state, 923, (1 << 0));
530 dib8000_write_word(state, 923, (0 << 0));
531
532 msleep(1);
533 return 0;
534}
535
536int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
537{
538 struct dib8000_state *state = fe->demodulator_priv;
539 if (value > 4095)
540 value = 4095;
541 state->wbd_ref = value;
542 return dib8000_write_word(state, 106, value);
543}
544
545EXPORT_SYMBOL(dib8000_set_wbd_ref);
546static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
547{
548 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
549 dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); /* P_sec_len */
550 dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff));
551 dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
552 dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
553 dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
554
555 dib8000_write_word(state, 922, bw->sad_cfg);
556}
557
558static void dib8000_reset_pll(struct dib8000_state *state)
559{
560 const struct dibx000_bandwidth_config *pll = state->cfg.pll;
561 u16 clk_cfg1;
562
563 // clk_cfg0
564 dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
565
566 // clk_cfg1
567 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
568 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) |
569 (pll->pll_range << 1) | (pll->pll_reset << 0);
570
571 dib8000_write_word(state, 902, clk_cfg1);
572 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
573 dib8000_write_word(state, 902, clk_cfg1);
574
575 dprintk("clk_cfg1: 0x%04x", clk_cfg1); /* 0x507 1 0 1 000 0 0 11 1 */
576
577 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
578 if (state->cfg.pll->ADClkSrc == 0)
579 dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) |
580 (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
581 else if (state->cfg.refclksel != 0)
582 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
583 ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) |
584 (pll->ADClkSrc << 7) | (0 << 1));
585 else
586 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
587
588 dib8000_reset_pll_common(state, pll);
589}
590
591static int dib8000_reset_gpio(struct dib8000_state *st)
592{
593 /* reset the GPIOs */
594 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
595 dib8000_write_word(st, 1030, st->cfg.gpio_val);
596
597 /* TODO 782 is P_gpio_od */
598
599 dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
600
601 dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
602 return 0;
603}
604
605static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
606{
607 st->cfg.gpio_dir = dib8000_read_word(st, 1029);
608 st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */
609 st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
610 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
611
612 st->cfg.gpio_val = dib8000_read_word(st, 1030);
613 st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */
614 st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */
615 dib8000_write_word(st, 1030, st->cfg.gpio_val);
616
617 dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
618
619 return 0;
620}
621
622int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
623{
624 struct dib8000_state *state = fe->demodulator_priv;
625 return dib8000_cfg_gpio(state, num, dir, val);
626}
627
628EXPORT_SYMBOL(dib8000_set_gpio);
629static const u16 dib8000_defaults[] = {
630 /* auto search configuration - lock0 by default waiting
631 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
632 3, 7,
633 0x0004,
634 0x0400,
635 0x0814,
636
637 12, 11,
638 0x001b,
639 0x7740,
640 0x005b,
641 0x8d80,
642 0x01c9,
643 0xc380,
644 0x0000,
645 0x0080,
646 0x0000,
647 0x0090,
648 0x0001,
649 0xd4c0,
650
651 /*1, 32,
652 0x6680 // P_corm_thres Lock algorithms configuration */
653
654 11, 80, /* set ADC level to -16 */
655 (1 << 13) - 825 - 117,
656 (1 << 13) - 837 - 117,
657 (1 << 13) - 811 - 117,
658 (1 << 13) - 766 - 117,
659 (1 << 13) - 737 - 117,
660 (1 << 13) - 693 - 117,
661 (1 << 13) - 648 - 117,
662 (1 << 13) - 619 - 117,
663 (1 << 13) - 575 - 117,
664 (1 << 13) - 531 - 117,
665 (1 << 13) - 501 - 117,
666
667 4, 108,
668 0,
669 0,
670 0,
671 0,
672
673 1, 175,
674 0x0410,
675 1, 179,
676 8192, // P_fft_nb_to_cut
677
678 6, 181,
679 0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
680 0x2800,
681 0x2800,
682 0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
683 0x2800,
684 0x2800,
685
686 2, 193,
687 0x0666, // P_pha3_thres
688 0x0000, // P_cti_use_cpe, P_cti_use_prog
689
690 2, 205,
691 0x200f, // P_cspu_regul, P_cspu_win_cut
692 0x000f, // P_des_shift_work
693
694 5, 215,
695 0x023d, // P_adp_regul_cnt
696 0x00a4, // P_adp_noise_cnt
697 0x00a4, // P_adp_regul_ext
698 0x7ff0, // P_adp_noise_ext
699 0x3ccc, // P_adp_fil
700
701 1, 230,
702 0x0000, // P_2d_byp_ti_num
703
704 1, 263,
705 0x800, //P_equal_thres_wgn
706
707 1, 268,
708 (2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode
709
710 1, 270,
711 0x0001, // P_div_lock0_wait
712 1, 285,
713 0x0020, //p_fec_
714 1, 299,
715 0x0062, /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
716
717 1, 338,
718 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
719 (1 << 10) |
720 (0 << 9) | /* P_ctrl_pre_freq_inh=0 */
721 (3 << 5) | /* P_ctrl_pre_freq_step=3 */
722 (1 << 0), /* P_pre_freq_win_len=1 */
723
724 1, 903,
725 (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
726
727 0,
728};
729
730static u16 dib8000_identify(struct i2c_device *client)
731{
732 u16 value;
733
734 //because of glitches sometimes
735 value = dib8000_i2c_read16(client, 896);
736
737 if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
738 dprintk("wrong Vendor ID (read=0x%x)", value);
739 return 0;
740 }
741
742 value = dib8000_i2c_read16(client, 897);
743 if (value != 0x8000 && value != 0x8001 && value != 0x8002) {
744 dprintk("wrong Device ID (%x)", value);
745 return 0;
746 }
747
748 switch (value) {
749 case 0x8000:
750 dprintk("found DiB8000A");
751 break;
752 case 0x8001:
753 dprintk("found DiB8000B");
754 break;
755 case 0x8002:
756 dprintk("found DiB8000C");
757 break;
758 }
759 return value;
760}
761
762static int dib8000_reset(struct dvb_frontend *fe)
763{
764 struct dib8000_state *state = fe->demodulator_priv;
765
766 dib8000_write_word(state, 1287, 0x0003); /* sram lead in, rdy */
767
768 if ((state->revision = dib8000_identify(&state->i2c)) == 0)
769 return -EINVAL;
770
771 if (state->revision == 0x8000)
772 dprintk("error : dib8000 MA not supported");
773
774 dibx000_reset_i2c_master(&state->i2c_master);
775
776 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
777
778 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
779 dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
780
781 /* restart all parts */
782 dib8000_write_word(state, 770, 0xffff);
783 dib8000_write_word(state, 771, 0xffff);
784 dib8000_write_word(state, 772, 0xfffc);
785 dib8000_write_word(state, 898, 0x000c); // sad
786 dib8000_write_word(state, 1280, 0x004d);
787 dib8000_write_word(state, 1281, 0x000c);
788
789 dib8000_write_word(state, 770, 0x0000);
790 dib8000_write_word(state, 771, 0x0000);
791 dib8000_write_word(state, 772, 0x0000);
792 dib8000_write_word(state, 898, 0x0004); // sad
793 dib8000_write_word(state, 1280, 0x0000);
794 dib8000_write_word(state, 1281, 0x0000);
795
796 /* drives */
797 if (state->cfg.drives)
798 dib8000_write_word(state, 906, state->cfg.drives);
799 else {
800 dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
801 dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust
802 }
803
804 dib8000_reset_pll(state);
805
806 if (dib8000_reset_gpio(state) != 0)
807 dprintk("GPIO reset was not successful.");
808
809 if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0)
810 dprintk("OUTPUT_MODE could not be resetted.");
811
812 state->current_agc = NULL;
813
814 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
815 /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
816 if (state->cfg.pll->ifreq == 0)
817 dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */
818 else
819 dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */
820
821 {
822 u16 l = 0, r;
823 const u16 *n;
824 n = dib8000_defaults;
825 l = *n++;
826 while (l) {
827 r = *n++;
828 do {
829 dib8000_write_word(state, r, *n++);
830 r++;
831 } while (--l);
832 l = *n++;
833 }
834 }
835 state->isdbt_cfg_loaded = 0;
836
837 //div_cfg override for special configs
838 if (state->cfg.div_cfg != 0)
839 dib8000_write_word(state, 903, state->cfg.div_cfg);
840
841 /* unforce divstr regardless whether i2c enumeration was done or not */
842 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
843
844 dib8000_set_bandwidth(fe, 6000);
845
846 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
847 dib8000_sad_calib(state);
848 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
849
850 dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
851
852 return 0;
853}
854
855static void dib8000_restart_agc(struct dib8000_state *state)
856{
857 // P_restart_iqc & P_restart_agc
858 dib8000_write_word(state, 770, 0x0a00);
859 dib8000_write_word(state, 770, 0x0000);
860}
861
862static int dib8000_update_lna(struct dib8000_state *state)
863{
864 u16 dyn_gain;
865
866 if (state->cfg.update_lna) {
867 // read dyn_gain here (because it is demod-dependent and not tuner)
868 dyn_gain = dib8000_read_word(state, 390);
869
870 if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
871 dib8000_restart_agc(state);
872 return 1;
873 }
874 }
875 return 0;
876}
877
878static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
879{
880 struct dibx000_agc_config *agc = NULL;
881 int i;
882 if (state->current_band == band && state->current_agc != NULL)
883 return 0;
884 state->current_band = band;
885
886 for (i = 0; i < state->cfg.agc_config_count; i++)
887 if (state->cfg.agc[i].band_caps & band) {
888 agc = &state->cfg.agc[i];
889 break;
890 }
891
892 if (agc == NULL) {
893 dprintk("no valid AGC configuration found for band 0x%02x", band);
894 return -EINVAL;
895 }
896
897 state->current_agc = agc;
898
899 /* AGC */
900 dib8000_write_word(state, 76, agc->setup);
901 dib8000_write_word(state, 77, agc->inv_gain);
902 dib8000_write_word(state, 78, agc->time_stabiliz);
903 dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
904
905 // Demod AGC loop configuration
906 dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
907 dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
908
909 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
910 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
911
912 /* AGC continued */
913 if (state->wbd_ref != 0)
914 dib8000_write_word(state, 106, state->wbd_ref);
915 else // use default
916 dib8000_write_word(state, 106, agc->wbd_ref);
917 dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
918 dib8000_write_word(state, 108, agc->agc1_max);
919 dib8000_write_word(state, 109, agc->agc1_min);
920 dib8000_write_word(state, 110, agc->agc2_max);
921 dib8000_write_word(state, 111, agc->agc2_min);
922 dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
923 dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
924 dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
925 dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
926
927 dib8000_write_word(state, 75, agc->agc1_pt3);
928 dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); /*LB : 929 -> 923 */
929
930 return 0;
931}
932
933void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
934{
935 struct dib8000_state *state = fe->demodulator_priv;
936 dib8000_set_adc_state(state, DIBX000_ADC_ON);
937 dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
938}
939EXPORT_SYMBOL(dib8000_pwm_agc_reset);
940
941static int dib8000_agc_soft_split(struct dib8000_state *state)
942{
943 u16 agc, split_offset;
944
945 if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
946 return FE_CALLBACK_TIME_NEVER;
947
948 // n_agc_global
949 agc = dib8000_read_word(state, 390);
950
951 if (agc > state->current_agc->split.min_thres)
952 split_offset = state->current_agc->split.min;
953 else if (agc < state->current_agc->split.max_thres)
954 split_offset = state->current_agc->split.max;
955 else
956 split_offset = state->current_agc->split.max *
957 (agc - state->current_agc->split.min_thres) /
958 (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
959
960 dprintk("AGC split_offset: %d", split_offset);
961
962 // P_agc_force_split and P_agc_split_offset
963 dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
964 return 5000;
965}
966
967static int dib8000_agc_startup(struct dvb_frontend *fe)
968{
969 struct dib8000_state *state = fe->demodulator_priv;
970 enum frontend_tune_state *tune_state = &state->tune_state;
971
972 int ret = 0;
973
974 switch (*tune_state) {
975 case CT_AGC_START:
976 // set power-up level: interf+analog+AGC
977
978 dib8000_set_adc_state(state, DIBX000_ADC_ON);
979
980 if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
981 *tune_state = CT_AGC_STOP;
982 state->status = FE_STATUS_TUNE_FAILED;
983 break;
984 }
985
986 ret = 70;
987 *tune_state = CT_AGC_STEP_0;
988 break;
989
990 case CT_AGC_STEP_0:
991 //AGC initialization
992 if (state->cfg.agc_control)
993 state->cfg.agc_control(fe, 1);
994
995 dib8000_restart_agc(state);
996
997 // wait AGC rough lock time
998 ret = 50;
999 *tune_state = CT_AGC_STEP_1;
1000 break;
1001
1002 case CT_AGC_STEP_1:
1003 // wait AGC accurate lock time
1004 ret = 70;
1005
1006 if (dib8000_update_lna(state))
1007 // wait only AGC rough lock time
1008 ret = 50;
1009 else
1010 *tune_state = CT_AGC_STEP_2;
1011 break;
1012
1013 case CT_AGC_STEP_2:
1014 dib8000_agc_soft_split(state);
1015
1016 if (state->cfg.agc_control)
1017 state->cfg.agc_control(fe, 0);
1018
1019 *tune_state = CT_AGC_STOP;
1020 break;
1021 default:
1022 ret = dib8000_agc_soft_split(state);
1023 break;
1024 }
1025 return ret;
1026
1027}
1028
1029static const s32 lut_1000ln_mant[] =
1030{
1031 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
1032};
1033
1034s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
1035{
1036 struct dib8000_state *state = fe->demodulator_priv;
1037 u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
1038 s32 val;
1039
1040 val = dib8000_read32(state, 384);
1041 if (mode) {
1042 tmp_val = val;
1043 while (tmp_val >>= 1)
1044 exp++;
1045 mant = (val * 1000 / (1<<exp));
1046 ix = (u8)((mant-1000)/100); /* index of the LUT */
1047 val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
1048 val = (val*256)/1000;
1049 }
1050 return val;
1051}
1052EXPORT_SYMBOL(dib8000_get_adc_power);
1053
1054static void dib8000_update_timf(struct dib8000_state *state)
1055{
1056 u32 timf = state->timf = dib8000_read32(state, 435);
1057
1058 dib8000_write_word(state, 29, (u16) (timf >> 16));
1059 dib8000_write_word(state, 30, (u16) (timf & 0xffff));
1060 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
1061}
1062
1063static const u16 adc_target_16dB[11] = {
1064 (1 << 13) - 825 - 117,
1065 (1 << 13) - 837 - 117,
1066 (1 << 13) - 811 - 117,
1067 (1 << 13) - 766 - 117,
1068 (1 << 13) - 737 - 117,
1069 (1 << 13) - 693 - 117,
1070 (1 << 13) - 648 - 117,
1071 (1 << 13) - 619 - 117,
1072 (1 << 13) - 575 - 117,
1073 (1 << 13) - 531 - 117,
1074 (1 << 13) - 501 - 117
1075};
1076static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
1077
1078static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
1079{
1080 u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
1081 u8 guard, crate, constellation, timeI;
1082 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
1083 const s16 *ncoeff = NULL, *ana_fe;
1084 u16 tmcc_pow = 0;
1085 u16 coff_pow = 0x2800;
1086 u16 init_prbs = 0xfff;
1087 u16 ana_gain = 0;
1088
1089 if (state->ber_monitored_layer != LAYER_ALL)
1090 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
1091 else
1092 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
1093
1094 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
1095 dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i);
1096
1097 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1098 //compute new dds_freq for the seg and adjust prbs
1099 int seg_offset =
1100 state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx -
1101 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) -
1102 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2);
1103 int clk = state->cfg.pll->internal;
1104 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
1105 int dds_offset = seg_offset * segtodds;
1106 int new_dds, sub_channel;
1107 if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1108 dds_offset -= (int)(segtodds / 2);
1109
1110 if (state->cfg.pll->ifreq == 0) {
1111 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) {
1112 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
1113 new_dds = dds_offset;
1114 } else
1115 new_dds = dds_offset;
1116
1117 // We shift tuning frequency if the wanted segment is :
1118 // - the segment of center frequency with an odd total number of segments
1119 // - the segment to the left of center frequency with an even total number of segments
1120 // - the segment to the right of center frequency with an even total number of segments
1121 if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT)
1122 && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1123 && (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1124 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1125 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1126 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1127 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2)))
1128 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1129 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1130 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1131 )) {
1132 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1133 }
1134 } else {
1135 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0)
1136 new_dds = state->cfg.pll->ifreq - dds_offset;
1137 else
1138 new_dds = state->cfg.pll->ifreq + dds_offset;
1139 }
1140 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1141 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1142 if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1143 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1144 else
1145 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1146 sub_channel -= 6;
1147
1148 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1149 || state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1150 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
1151 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
1152 } else {
1153 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
1154 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
1155 }
1156
1157 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1158 case TRANSMISSION_MODE_2K:
1159 switch (sub_channel) {
1160 case -6:
1161 init_prbs = 0x0;
1162 break; // 41, 0, 1
1163 case -5:
1164 init_prbs = 0x423;
1165 break; // 02~04
1166 case -4:
1167 init_prbs = 0x9;
1168 break; // 05~07
1169 case -3:
1170 init_prbs = 0x5C7;
1171 break; // 08~10
1172 case -2:
1173 init_prbs = 0x7A6;
1174 break; // 11~13
1175 case -1:
1176 init_prbs = 0x3D8;
1177 break; // 14~16
1178 case 0:
1179 init_prbs = 0x527;
1180 break; // 17~19
1181 case 1:
1182 init_prbs = 0x7FF;
1183 break; // 20~22
1184 case 2:
1185 init_prbs = 0x79B;
1186 break; // 23~25
1187 case 3:
1188 init_prbs = 0x3D6;
1189 break; // 26~28
1190 case 4:
1191 init_prbs = 0x3A2;
1192 break; // 29~31
1193 case 5:
1194 init_prbs = 0x53B;
1195 break; // 32~34
1196 case 6:
1197 init_prbs = 0x2F4;
1198 break; // 35~37
1199 default:
1200 case 7:
1201 init_prbs = 0x213;
1202 break; // 38~40
1203 }
1204 break;
1205
1206 case TRANSMISSION_MODE_4K:
1207 switch (sub_channel) {
1208 case -6:
1209 init_prbs = 0x0;
1210 break; // 41, 0, 1
1211 case -5:
1212 init_prbs = 0x208;
1213 break; // 02~04
1214 case -4:
1215 init_prbs = 0xC3;
1216 break; // 05~07
1217 case -3:
1218 init_prbs = 0x7B9;
1219 break; // 08~10
1220 case -2:
1221 init_prbs = 0x423;
1222 break; // 11~13
1223 case -1:
1224 init_prbs = 0x5C7;
1225 break; // 14~16
1226 case 0:
1227 init_prbs = 0x3D8;
1228 break; // 17~19
1229 case 1:
1230 init_prbs = 0x7FF;
1231 break; // 20~22
1232 case 2:
1233 init_prbs = 0x3D6;
1234 break; // 23~25
1235 case 3:
1236 init_prbs = 0x53B;
1237 break; // 26~28
1238 case 4:
1239 init_prbs = 0x213;
1240 break; // 29~31
1241 case 5:
1242 init_prbs = 0x29;
1243 break; // 32~34
1244 case 6:
1245 init_prbs = 0xD0;
1246 break; // 35~37
1247 default:
1248 case 7:
1249 init_prbs = 0x48E;
1250 break; // 38~40
1251 }
1252 break;
1253
1254 default:
1255 case TRANSMISSION_MODE_8K:
1256 switch (sub_channel) {
1257 case -6:
1258 init_prbs = 0x0;
1259 break; // 41, 0, 1
1260 case -5:
1261 init_prbs = 0x740;
1262 break; // 02~04
1263 case -4:
1264 init_prbs = 0x069;
1265 break; // 05~07
1266 case -3:
1267 init_prbs = 0x7DD;
1268 break; // 08~10
1269 case -2:
1270 init_prbs = 0x208;
1271 break; // 11~13
1272 case -1:
1273 init_prbs = 0x7B9;
1274 break; // 14~16
1275 case 0:
1276 init_prbs = 0x5C7;
1277 break; // 17~19
1278 case 1:
1279 init_prbs = 0x7FF;
1280 break; // 20~22
1281 case 2:
1282 init_prbs = 0x53B;
1283 break; // 23~25
1284 case 3:
1285 init_prbs = 0x29;
1286 break; // 26~28
1287 case 4:
1288 init_prbs = 0x48E;
1289 break; // 29~31
1290 case 5:
1291 init_prbs = 0x4C4;
1292 break; // 32~34
1293 case 6:
1294 init_prbs = 0x367;
1295 break; // 33~37
1296 default:
1297 case 7:
1298 init_prbs = 0x684;
1299 break; // 38~40
1300 }
1301 break;
1302 }
1303 } else {
1304 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
1305 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
1306 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
1307 }
1308 /*P_mode == ?? */
1309 dib8000_write_word(state, 10, (seq << 4));
1310 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
1311
1312 switch (state->fe[0]->dtv_property_cache.guard_interval) {
1313 case GUARD_INTERVAL_1_32:
1314 guard = 0;
1315 break;
1316 case GUARD_INTERVAL_1_16:
1317 guard = 1;
1318 break;
1319 case GUARD_INTERVAL_1_8:
1320 guard = 2;
1321 break;
1322 case GUARD_INTERVAL_1_4:
1323 default:
1324 guard = 3;
1325 break;
1326 }
1327
1328 dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
1329
1330 max_constellation = DQPSK;
1331 for (i = 0; i < 3; i++) {
1332 switch (state->fe[0]->dtv_property_cache.layer[i].modulation) {
1333 case DQPSK:
1334 constellation = 0;
1335 break;
1336 case QPSK:
1337 constellation = 1;
1338 break;
1339 case QAM_16:
1340 constellation = 2;
1341 break;
1342 case QAM_64:
1343 default:
1344 constellation = 3;
1345 break;
1346 }
1347
1348 switch (state->fe[0]->dtv_property_cache.layer[i].fec) {
1349 case FEC_1_2:
1350 crate = 1;
1351 break;
1352 case FEC_2_3:
1353 crate = 2;
1354 break;
1355 case FEC_3_4:
1356 crate = 3;
1357 break;
1358 case FEC_5_6:
1359 crate = 5;
1360 break;
1361 case FEC_7_8:
1362 default:
1363 crate = 7;
1364 break;
1365 }
1366
1367 if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) &&
1368 ((state->fe[0]->dtv_property_cache.layer[i].interleaving <= 3) ||
1369 (state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1))
1370 )
1371 timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving;
1372 else
1373 timeI = 0;
1374 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
1375 (crate << 3) | timeI);
1376 if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) {
1377 switch (max_constellation) {
1378 case DQPSK:
1379 case QPSK:
1380 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 ||
1381 state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
1382 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
1383 break;
1384 case QAM_16:
1385 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
1386 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
1387 break;
1388 }
1389 }
1390 }
1391
1392 mode = fft_to_mode(state);
1393
1394 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
1395
1396 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
1397 ((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache.
1398 isdbt_sb_mode & 1) << 4));
1399
1400 dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval);
1401
1402 /* signal optimization parameter */
1403
1404 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) {
1405 seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
1406 for (i = 1; i < 3; i++)
1407 nbseg_diff +=
1408 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
1409 for (i = 0; i < nbseg_diff; i++)
1410 seg_diff_mask |= 1 << permu_seg[i + 1];
1411 } else {
1412 for (i = 0; i < 3; i++)
1413 nbseg_diff +=
1414 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
1415 for (i = 0; i < nbseg_diff; i++)
1416 seg_diff_mask |= 1 << permu_seg[i];
1417 }
1418 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
1419
1420 state->differential_constellation = (seg_diff_mask != 0);
1421 dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
1422
1423 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1424 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
1425 seg_mask13 = 0x00E0;
1426 else // 1-segment
1427 seg_mask13 = 0x0040;
1428 } else
1429 seg_mask13 = 0x1fff;
1430
1431 // WRITE: Mode & Diff mask
1432 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
1433
1434 if ((seg_diff_mask) || (state->fe[0]->dtv_property_cache.isdbt_sb_mode))
1435 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
1436 else
1437 dib8000_write_word(state, 268, (2 << 9) | 39); //init value
1438
1439 // ---- SMALL ----
1440 // P_small_seg_diff
1441 dib8000_write_word(state, 352, seg_diff_mask); // ADDR 352
1442
1443 dib8000_write_word(state, 353, seg_mask13); // ADDR 353
1444
1445/* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
1446
1447 // ---- SMALL ----
1448 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1449 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1450 case TRANSMISSION_MODE_2K:
1451 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1452 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1453 ncoeff = coeff_2k_sb_1seg_dqpsk;
1454 else // QPSK or QAM
1455 ncoeff = coeff_2k_sb_1seg;
1456 } else { // 3-segments
1457 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1458 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
1459 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
1460 else // QPSK or QAM on external segments
1461 ncoeff = coeff_2k_sb_3seg_0dqpsk;
1462 } else { // QPSK or QAM on central segment
1463 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
1464 ncoeff = coeff_2k_sb_3seg_1dqpsk;
1465 else // QPSK or QAM on external segments
1466 ncoeff = coeff_2k_sb_3seg;
1467 }
1468 }
1469 break;
1470
1471 case TRANSMISSION_MODE_4K:
1472 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1473 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1474 ncoeff = coeff_4k_sb_1seg_dqpsk;
1475 else // QPSK or QAM
1476 ncoeff = coeff_4k_sb_1seg;
1477 } else { // 3-segments
1478 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1479 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1480 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
1481 } else { // QPSK or QAM on external segments
1482 ncoeff = coeff_4k_sb_3seg_0dqpsk;
1483 }
1484 } else { // QPSK or QAM on central segment
1485 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1486 ncoeff = coeff_4k_sb_3seg_1dqpsk;
1487 } else // QPSK or QAM on external segments
1488 ncoeff = coeff_4k_sb_3seg;
1489 }
1490 }
1491 break;
1492
1493 case TRANSMISSION_MODE_AUTO:
1494 case TRANSMISSION_MODE_8K:
1495 default:
1496 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1497 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1498 ncoeff = coeff_8k_sb_1seg_dqpsk;
1499 else // QPSK or QAM
1500 ncoeff = coeff_8k_sb_1seg;
1501 } else { // 3-segments
1502 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1503 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1504 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
1505 } else { // QPSK or QAM on external segments
1506 ncoeff = coeff_8k_sb_3seg_0dqpsk;
1507 }
1508 } else { // QPSK or QAM on central segment
1509 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1510 ncoeff = coeff_8k_sb_3seg_1dqpsk;
1511 } else // QPSK or QAM on external segments
1512 ncoeff = coeff_8k_sb_3seg;
1513 }
1514 }
1515 break;
1516 }
1517 for (i = 0; i < 8; i++)
1518 dib8000_write_word(state, 343 + i, ncoeff[i]);
1519 }
1520
1521 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
1522 dib8000_write_word(state, 351,
1523 (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
1524
1525 // ---- COFF ----
1526 // Carloff, the most robust
1527 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1528
1529 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
1530 // P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1
1531 dib8000_write_word(state, 187,
1532 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2)
1533 | 0x3);
1534
1535/* // P_small_coef_ext_enable = 1 */
1536/* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
1537
1538 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1539
1540 // P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1)
1541 if (mode == 3)
1542 dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
1543 else
1544 dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
1545 // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
1546 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
1547 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
1548 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1549 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1550 // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1551 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1552
1553 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1554 dib8000_write_word(state, 181, 300);
1555 dib8000_write_word(state, 182, 150);
1556 dib8000_write_word(state, 183, 80);
1557 dib8000_write_word(state, 184, 300);
1558 dib8000_write_word(state, 185, 150);
1559 dib8000_write_word(state, 186, 80);
1560 } else { // Sound Broadcasting mode 3 seg
1561 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
1562 /* if (mode == 3) */
1563 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
1564 /* else */
1565 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
1566 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
1567
1568 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
1569 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
1570 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
1571 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1572 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1573 //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1574 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1575
1576 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1577 dib8000_write_word(state, 181, 350);
1578 dib8000_write_word(state, 182, 300);
1579 dib8000_write_word(state, 183, 250);
1580 dib8000_write_word(state, 184, 350);
1581 dib8000_write_word(state, 185, 300);
1582 dib8000_write_word(state, 186, 250);
1583 }
1584
1585 } else if (state->isdbt_cfg_loaded == 0) { // if not Sound Broadcasting mode : put default values for 13 segments
1586 dib8000_write_word(state, 180, (16 << 6) | 9);
1587 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
1588 coff_pow = 0x2800;
1589 for (i = 0; i < 6; i++)
1590 dib8000_write_word(state, 181 + i, coff_pow);
1591
1592 // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
1593 // P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1
1594 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
1595
1596 // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
1597 dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
1598 // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
1599 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1600 }
1601 // ---- FFT ----
1602 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1603 dib8000_write_word(state, 178, 64); // P_fft_powrange=64
1604 else
1605 dib8000_write_word(state, 178, 32); // P_fft_powrange=32
1606
1607 /* make the cpil_coff_lock more robust but slower p_coff_winlen
1608 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
1609 */
1610 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
1611 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
1612
1613 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */
1614 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */
1615 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
1616 if ((!state->fe[0]->dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
1617 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
1618 else
1619 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
1620 dib8000_write_word(state, 287, ~seg_mask13 | 0x1000); /* P_tmcc_seg_inh */
1621 //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
1622 if (!autosearching)
1623 dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
1624 else
1625 dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
1626 dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
1627
1628 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
1629
1630 /* offset loop parameters */
1631 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1632 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1633 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1634 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
1635
1636 else // Sound Broadcasting mode 3 seg
1637 /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1638 dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
1639 } else
1640 // TODO in 13 seg, timf_alpha can always be the same or not ?
1641 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
1642 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
1643
1644 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1645 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1646 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
1647 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
1648
1649 else // Sound Broadcasting mode 3 seg
1650 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
1651 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
1652 } else
1653 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
1654 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
1655
1656 /* P_dvsy_sync_wait - reuse mode */
1657 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1658 case TRANSMISSION_MODE_8K:
1659 mode = 256;
1660 break;
1661 case TRANSMISSION_MODE_4K:
1662 mode = 128;
1663 break;
1664 default:
1665 case TRANSMISSION_MODE_2K:
1666 mode = 64;
1667 break;
1668 }
1669 if (state->cfg.diversity_delay == 0)
1670 mode = (mode * (1 << (guard)) * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
1671 else
1672 mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for DVSY-fifo
1673 mode <<= 4;
1674 dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
1675
1676 /* channel estimation fine configuration */
1677 switch (max_constellation) {
1678 case QAM_64:
1679 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1680 coeff[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1681 coeff[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1682 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1683 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1684 //if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
1685 break;
1686 case QAM_16:
1687 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1688 coeff[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1689 coeff[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1690 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1691 coeff[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1692 //if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
1693 break;
1694 default:
1695 ana_gain = 0; // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
1696 coeff[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1697 coeff[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1698 coeff[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1699 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1700 break;
1701 }
1702 for (mode = 0; mode < 4; mode++)
1703 dib8000_write_word(state, 215 + mode, coeff[mode]);
1704
1705 // update ana_gain depending on max constellation
1706 dib8000_write_word(state, 116, ana_gain);
1707 // update ADC target depending on ana_gain
1708 if (ana_gain) { // set -16dB ADC target for ana_gain=-1
1709 for (i = 0; i < 10; i++)
1710 dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
1711 } else { // set -22dB ADC target for ana_gain=0
1712 for (i = 0; i < 10; i++)
1713 dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
1714 }
1715
1716 // ---- ANA_FE ----
1717 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1718 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
1719 ana_fe = ana_fe_coeff_3seg;
1720 else // 1-segment
1721 ana_fe = ana_fe_coeff_1seg;
1722 } else
1723 ana_fe = ana_fe_coeff_13seg;
1724
1725 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
1726 for (mode = 0; mode < 24; mode++)
1727 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
1728
1729 // ---- CHAN_BLK ----
1730 for (i = 0; i < 13; i++) {
1731 if ((((~seg_diff_mask) >> i) & 1) == 1) {
1732 P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
1733 P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
1734 }
1735 }
1736 dib8000_write_word(state, 222, P_cfr_left_edge); // P_cfr_left_edge
1737 dib8000_write_word(state, 223, P_cfr_right_edge); // P_cfr_right_edge
1738 // "P_cspu_left_edge" not used => do not care
1739 // "P_cspu_right_edge" not used => do not care
1740
1741 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1742 dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1
1743 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
1744 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0
1745 && state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
1746 //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
1747 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15
1748 }
1749 } else if (state->isdbt_cfg_loaded == 0) {
1750 dib8000_write_word(state, 228, 0); // default value
1751 dib8000_write_word(state, 265, 31); // default value
1752 dib8000_write_word(state, 205, 0x200f); // init value
1753 }
1754 // ---- TMCC ----
1755 for (i = 0; i < 3; i++)
1756 tmcc_pow +=
1757 (((state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe[0]->dtv_property_cache.layer[i].segment_count);
1758 // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
1759 // Threshold is set at 1/4 of max power.
1760 tmcc_pow *= (1 << (9 - 2));
1761
1762 dib8000_write_word(state, 290, tmcc_pow); // P_tmcc_dec_thres_2k
1763 dib8000_write_word(state, 291, tmcc_pow); // P_tmcc_dec_thres_4k
1764 dib8000_write_word(state, 292, tmcc_pow); // P_tmcc_dec_thres_8k
1765 //dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
1766 // ---- PHA3 ----
1767
1768 if (state->isdbt_cfg_loaded == 0)
1769 dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */
1770
1771 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1772 state->isdbt_cfg_loaded = 0;
1773 else
1774 state->isdbt_cfg_loaded = 1;
1775
1776}
1777
1778static int dib8000_autosearch_start(struct dvb_frontend *fe)
1779{
1780 u8 factor;
1781 u32 value;
1782 struct dib8000_state *state = fe->demodulator_priv;
1783
1784 int slist = 0;
1785
1786 state->fe[0]->dtv_property_cache.inversion = 0;
1787 if (!state->fe[0]->dtv_property_cache.isdbt_sb_mode)
1788 state->fe[0]->dtv_property_cache.layer[0].segment_count = 13;
1789 state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64;
1790 state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3;
1791 state->fe[0]->dtv_property_cache.layer[0].interleaving = 0;
1792
1793 //choose the right list, in sb, always do everything
1794 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1795 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1796 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1797 slist = 7;
1798 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
1799 } else {
1800 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
1801 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1802 slist = 7;
1803 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2
1804 } else
1805 slist = 3;
1806 } else {
1807 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1808 slist = 2;
1809 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1810 } else
1811 slist = 0;
1812 }
1813
1814 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
1815 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1816 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
1817 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1818
1819 dprintk("using list for autosearch : %d", slist);
1820 dib8000_set_channel(state, (unsigned char)slist, 1);
1821 //dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1822
1823 factor = 1;
1824
1825 //set lock_mask values
1826 dib8000_write_word(state, 6, 0x4);
1827 dib8000_write_word(state, 7, 0x8);
1828 dib8000_write_word(state, 8, 0x1000);
1829
1830 //set lock_mask wait time values
1831 value = 50 * state->cfg.pll->internal * factor;
1832 dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
1833 dib8000_write_word(state, 12, (u16) (value & 0xffff)); // lock0 wait time
1834 value = 100 * state->cfg.pll->internal * factor;
1835 dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
1836 dib8000_write_word(state, 14, (u16) (value & 0xffff)); // lock1 wait time
1837 value = 1000 * state->cfg.pll->internal * factor;
1838 dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
1839 dib8000_write_word(state, 16, (u16) (value & 0xffff)); // lock2 wait time
1840
1841 value = dib8000_read_word(state, 0);
1842 dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
1843 dib8000_read_word(state, 1284); // reset the INT. n_irq_pending
1844 dib8000_write_word(state, 0, (u16) value);
1845
1846 }
1847
1848 return 0;
1849}
1850
1851static int dib8000_autosearch_irq(struct dvb_frontend *fe)
1852{
1853 struct dib8000_state *state = fe->demodulator_priv;
1854 u16 irq_pending = dib8000_read_word(state, 1284);
1855
1856 if (irq_pending & 0x1) { // failed
1857 dprintk("dib8000_autosearch_irq failed");
1858 return 1;
1859 }
1860
1861 if (irq_pending & 0x2) { // succeeded
1862 dprintk("dib8000_autosearch_irq succeeded");
1863 return 2;
1864 }
1865
1866 return 0; // still pending
1867}
1868
1869static int dib8000_tune(struct dvb_frontend *fe)
1870{
1871 struct dib8000_state *state = fe->demodulator_priv;
1872 int ret = 0;
1873 u16 value, mode = fft_to_mode(state);
1874
1875 // we are already tuned - just resuming from suspend
1876 if (state == NULL)
1877 return -EINVAL;
1878
1879 dib8000_set_bandwidth(fe, state->fe[0]->dtv_property_cache.bandwidth_hz / 1000);
1880 dib8000_set_channel(state, 0, 0);
1881
1882 // restart demod
1883 ret |= dib8000_write_word(state, 770, 0x4000);
1884 ret |= dib8000_write_word(state, 770, 0x0000);
1885 msleep(45);
1886
1887 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
1888 /* ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) ); workaround inh_isi stays at 1 */
1889
1890 // never achieved a lock before - wait for timfreq to update
1891 if (state->timf == 0) {
1892 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1893 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1894 msleep(300);
1895 else // Sound Broadcasting mode 3 seg
1896 msleep(500);
1897 } else // 13 seg
1898 msleep(200);
1899 }
1900 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1901 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1902
1903 /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */
1904 dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
1905 //dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
1906
1907 /* P_ctrl_sfreq_step= (12-P_mode) P_ctrl_sfreq_inh =0 P_ctrl_pha_off_max */
1908 ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
1909
1910 } else { // Sound Broadcasting mode 3 seg
1911
1912 /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 alpha to check on board */
1913 dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
1914
1915 ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
1916 }
1917
1918 } else { // 13 seg
1919 /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 alpha to check on board */
1920 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
1921
1922 ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
1923
1924 }
1925
1926 // we achieved a coff_cpil_lock - it's time to update the timf
1927 if ((dib8000_read_word(state, 568) >> 11) & 0x1)
1928 dib8000_update_timf(state);
1929
1930 //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
1931 dib8000_write_word(state, 6, 0x200);
1932
1933 if (state->revision == 0x8002) {
1934 value = dib8000_read_word(state, 903);
1935 dib8000_write_word(state, 903, value & ~(1 << 3));
1936 msleep(1);
1937 dib8000_write_word(state, 903, value | (1 << 3));
1938 }
1939
1940 return ret;
1941}
1942
1943static int dib8000_wakeup(struct dvb_frontend *fe)
1944{
1945 struct dib8000_state *state = fe->demodulator_priv;
1946 u8 index_frontend;
1947 int ret;
1948
1949 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
1950 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1951 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1952 dprintk("could not start Slow ADC");
1953
1954 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1955 ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
1956 if (ret < 0)
1957 return ret;
1958 }
1959
1960 return 0;
1961}
1962
1963static int dib8000_sleep(struct dvb_frontend *fe)
1964{
1965 struct dib8000_state *state = fe->demodulator_priv;
1966 u8 index_frontend;
1967 int ret;
1968
1969 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1970 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
1971 if (ret < 0)
1972 return ret;
1973 }
1974
1975 dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
1976 dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
1977 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
1978}
1979
1980enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
1981{
1982 struct dib8000_state *state = fe->demodulator_priv;
1983 return state->tune_state;
1984}
1985EXPORT_SYMBOL(dib8000_get_tune_state);
1986
1987int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
1988{
1989 struct dib8000_state *state = fe->demodulator_priv;
1990 state->tune_state = tune_state;
1991 return 0;
1992}
1993EXPORT_SYMBOL(dib8000_set_tune_state);
1994
1995static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1996{
1997 struct dib8000_state *state = fe->demodulator_priv;
1998 u16 i, val = 0;
1999 fe_status_t stat;
2000 u8 index_frontend, sub_index_frontend;
2001
2002 fe->dtv_property_cache.bandwidth_hz = 6000000;
2003
2004 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2005 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
2006 if (stat&FE_HAS_SYNC) {
2007 dprintk("TMCC lock on the slave%i", index_frontend);
2008 /* synchronize the cache with the other frontends */
2009 state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep);
2010 for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) {
2011 if (sub_index_frontend != index_frontend) {
2012 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
2013 state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
2014 state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
2015 state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
2016 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
2017 for (i = 0; i < 3; i++) {
2018 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
2019 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
2020 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
2021 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
2022 }
2023 }
2024 }
2025 return 0;
2026 }
2027 }
2028
2029 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
2030
2031 val = dib8000_read_word(state, 570);
2032 fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
2033 switch ((val & 0x30) >> 4) {
2034 case 1:
2035 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
2036 break;
2037 case 3:
2038 default:
2039 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
2040 break;
2041 }
2042
2043 switch (val & 0x3) {
2044 case 0:
2045 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
2046 dprintk("dib8000_get_frontend GI = 1/32 ");
2047 break;
2048 case 1:
2049 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
2050 dprintk("dib8000_get_frontend GI = 1/16 ");
2051 break;
2052 case 2:
2053 dprintk("dib8000_get_frontend GI = 1/8 ");
2054 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
2055 break;
2056 case 3:
2057 dprintk("dib8000_get_frontend GI = 1/4 ");
2058 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
2059 break;
2060 }
2061
2062 val = dib8000_read_word(state, 505);
2063 fe->dtv_property_cache.isdbt_partial_reception = val & 1;
2064 dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
2065
2066 for (i = 0; i < 3; i++) {
2067 val = dib8000_read_word(state, 493 + i);
2068 fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
2069 dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
2070
2071 val = dib8000_read_word(state, 499 + i);
2072 fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
2073 dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
2074
2075 val = dib8000_read_word(state, 481 + i);
2076 switch (val & 0x7) {
2077 case 1:
2078 fe->dtv_property_cache.layer[i].fec = FEC_1_2;
2079 dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
2080 break;
2081 case 2:
2082 fe->dtv_property_cache.layer[i].fec = FEC_2_3;
2083 dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
2084 break;
2085 case 3:
2086 fe->dtv_property_cache.layer[i].fec = FEC_3_4;
2087 dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
2088 break;
2089 case 5:
2090 fe->dtv_property_cache.layer[i].fec = FEC_5_6;
2091 dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
2092 break;
2093 default:
2094 fe->dtv_property_cache.layer[i].fec = FEC_7_8;
2095 dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
2096 break;
2097 }
2098
2099 val = dib8000_read_word(state, 487 + i);
2100 switch (val & 0x3) {
2101 case 0:
2102 dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
2103 fe->dtv_property_cache.layer[i].modulation = DQPSK;
2104 break;
2105 case 1:
2106 fe->dtv_property_cache.layer[i].modulation = QPSK;
2107 dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
2108 break;
2109 case 2:
2110 fe->dtv_property_cache.layer[i].modulation = QAM_16;
2111 dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
2112 break;
2113 case 3:
2114 default:
2115 dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
2116 fe->dtv_property_cache.layer[i].modulation = QAM_64;
2117 break;
2118 }
2119 }
2120
2121 /* synchronize the cache with the other frontends */
2122 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2123 state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode;
2124 state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
2125 state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
2126 state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
2127 state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception;
2128 for (i = 0; i < 3; i++) {
2129 state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count;
2130 state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving;
2131 state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec;
2132 state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation;
2133 }
2134 }
2135 return 0;
2136}
2137
2138static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
2139{
2140 struct dib8000_state *state = fe->demodulator_priv;
2141 u8 nbr_pending, exit_condition, index_frontend;
2142 s8 index_frontend_success = -1;
2143 int time, ret;
2144 int time_slave = FE_CALLBACK_TIME_NEVER;
2145
2146 if (state->fe[0]->dtv_property_cache.frequency == 0) {
2147 dprintk("dib8000: must at least specify frequency ");
2148 return 0;
2149 }
2150
2151 if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
2152 dprintk("dib8000: no bandwidth specified, set to default ");
2153 state->fe[0]->dtv_property_cache.bandwidth_hz = 6000000;
2154 }
2155
2156 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2157 /* synchronization of the cache */
2158 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
2159 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
2160
2161 dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);
2162 if (state->fe[index_frontend]->ops.tuner_ops.set_params)
2163 state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend], fep);
2164
2165 dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
2166 }
2167
2168 /* start up the AGC */
2169 do {
2170 time = dib8000_agc_startup(state->fe[0]);
2171 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2172 time_slave = dib8000_agc_startup(state->fe[index_frontend]);
2173 if (time == FE_CALLBACK_TIME_NEVER)
2174 time = time_slave;
2175 else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
2176 time = time_slave;
2177 }
2178 if (time != FE_CALLBACK_TIME_NEVER)
2179 msleep(time / 10);
2180 else
2181 break;
2182 exit_condition = 1;
2183 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2184 if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
2185 exit_condition = 0;
2186 break;
2187 }
2188 }
2189 } while (exit_condition == 0);
2190
2191 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2192 dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
2193
2194 if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) ||
2195 (state->fe[0]->dtv_property_cache.inversion == INVERSION_AUTO) ||
2196 (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
2197 (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
2198 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
2199 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0xff) &&
2200 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0) &&
2201 ((state->fe[0]->dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
2202 (state->fe[0]->dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
2203 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2204 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0xff) &&
2205 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0) &&
2206 ((state->fe[0]->dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2207 (state->fe[0]->dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2208 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2209 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0xff) &&
2210 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0) &&
2211 ((state->fe[0]->dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2212 (state->fe[0]->dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2213 (((state->fe[0]->dtv_property_cache.layer[0].segment_count == 0) ||
2214 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2215 ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) ||
2216 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2217 ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
2218 int i = 80000;
2219 u8 found = 0;
2220 u8 tune_failed = 0;
2221
2222 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2223 dib8000_set_bandwidth(state->fe[index_frontend], fe->dtv_property_cache.bandwidth_hz / 1000);
2224 dib8000_autosearch_start(state->fe[index_frontend]);
2225 }
2226
2227 do {
2228 msleep(20);
2229 nbr_pending = 0;
2230 exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
2231 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2232 if (((tune_failed >> index_frontend) & 0x1) == 0) {
2233 found = dib8000_autosearch_irq(state->fe[index_frontend]);
2234 switch (found) {
2235 case 0: /* tune pending */
2236 nbr_pending++;
2237 break;
2238 case 2:
2239 dprintk("autosearch succeed on the frontend%i", index_frontend);
2240 exit_condition = 2;
2241 index_frontend_success = index_frontend;
2242 break;
2243 default:
2244 dprintk("unhandled autosearch result");
2245 case 1:
2246 dprintk("autosearch failed for the frontend%i", index_frontend);
2247 break;
2248 }
2249 }
2250 }
2251
2252 /* if all tune are done and no success, exit: tune failed */
2253 if ((nbr_pending == 0) && (exit_condition == 0))
2254 exit_condition = 1;
2255 } while ((exit_condition == 0) && i--);
2256
2257 if (exit_condition == 1) { /* tune failed */
2258 dprintk("tune failed");
2259 return 0;
2260 }
2261
2262 dprintk("tune success on frontend%i", index_frontend_success);
2263
2264 dib8000_get_frontend(fe, fep);
2265 }
2266
2267 for (index_frontend = 0, ret = 0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2268 ret = dib8000_tune(state->fe[index_frontend]);
2269
2270 /* set output mode and diversity input */
2271 dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
2272 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2273 dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);
2274 dib8000_set_diversity_in(state->fe[index_frontend-1], 1);
2275 }
2276
2277 /* turn off the diversity of the last chip */
2278 dib8000_set_diversity_in(state->fe[index_frontend-1], 0);
2279
2280 return ret;
2281}
2282
2283static u16 dib8000_read_lock(struct dvb_frontend *fe)
2284{
2285 struct dib8000_state *state = fe->demodulator_priv;
2286
2287 return dib8000_read_word(state, 568);
2288}
2289
2290static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2291{
2292 struct dib8000_state *state = fe->demodulator_priv;
2293 u16 lock_slave = 0, lock = dib8000_read_word(state, 568);
2294 u8 index_frontend;
2295
2296 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2297 lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
2298
2299 *stat = 0;
2300
2301 if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1))
2302 *stat |= FE_HAS_SIGNAL;
2303
2304 if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */
2305 *stat |= FE_HAS_CARRIER;
2306
2307 if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */
2308 *stat |= FE_HAS_SYNC;
2309
2310 if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */
2311 *stat |= FE_HAS_LOCK;
2312
2313 if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) {
2314 lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
2315 if (lock & 0x01)
2316 *stat |= FE_HAS_VITERBI;
2317
2318 lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
2319 if (lock & 0x01)
2320 *stat |= FE_HAS_VITERBI;
2321
2322 lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
2323 if (lock & 0x01)
2324 *stat |= FE_HAS_VITERBI;
2325 }
2326
2327 return 0;
2328}
2329
2330static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
2331{
2332 struct dib8000_state *state = fe->demodulator_priv;
2333 *ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561); // 13 segments
2334 return 0;
2335}
2336
2337static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2338{
2339 struct dib8000_state *state = fe->demodulator_priv;
2340 *unc = dib8000_read_word(state, 565); // packet error on 13 seg
2341 return 0;
2342}
2343
2344static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2345{
2346 struct dib8000_state *state = fe->demodulator_priv;
2347 u8 index_frontend;
2348 u16 val;
2349
2350 *strength = 0;
2351 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2352 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
2353 if (val > 65535 - *strength)
2354 *strength = 65535;
2355 else
2356 *strength += val;
2357 }
2358
2359 val = 65535 - dib8000_read_word(state, 390);
2360 if (val > 65535 - *strength)
2361 *strength = 65535;
2362 else
2363 *strength += val;
2364 return 0;
2365}
2366
2367static u32 dib8000_get_snr(struct dvb_frontend *fe)
2368{
2369 struct dib8000_state *state = fe->demodulator_priv;
2370 u32 n, s, exp;
2371 u16 val;
2372
2373 val = dib8000_read_word(state, 542);
2374 n = (val >> 6) & 0xff;
2375 exp = (val & 0x3f);
2376 if ((exp & 0x20) != 0)
2377 exp -= 0x40;
2378 n <<= exp+16;
2379
2380 val = dib8000_read_word(state, 543);
2381 s = (val >> 6) & 0xff;
2382 exp = (val & 0x3f);
2383 if ((exp & 0x20) != 0)
2384 exp -= 0x40;
2385 s <<= exp+16;
2386
2387 if (n > 0) {
2388 u32 t = (s/n) << 16;
2389 return t + ((s << 16) - n*t) / n;
2390 }
2391 return 0xffffffff;
2392}
2393
2394static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
2395{
2396 struct dib8000_state *state = fe->demodulator_priv;
2397 u8 index_frontend;
2398 u32 snr_master;
2399
2400 snr_master = dib8000_get_snr(fe);
2401 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2402 snr_master += dib8000_get_snr(state->fe[index_frontend]);
2403
2404 if (snr_master != 0) {
2405 snr_master = 10*intlog10(snr_master>>16);
2406 *snr = snr_master / ((1 << 24) / 10);
2407 }
2408 else
2409 *snr = 0;
2410
2411 return 0;
2412}
2413
2414int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
2415{
2416 struct dib8000_state *state = fe->demodulator_priv;
2417 u8 index_frontend = 1;
2418
2419 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2420 index_frontend++;
2421 if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
2422 dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
2423 state->fe[index_frontend] = fe_slave;
2424 return 0;
2425 }
2426
2427 dprintk("too many slave frontend");
2428 return -ENOMEM;
2429}
2430EXPORT_SYMBOL(dib8000_set_slave_frontend);
2431
2432int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
2433{
2434 struct dib8000_state *state = fe->demodulator_priv;
2435 u8 index_frontend = 1;
2436
2437 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2438 index_frontend++;
2439 if (index_frontend != 1) {
2440 dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1);
2441 state->fe[index_frontend] = NULL;
2442 return 0;
2443 }
2444
2445 dprintk("no frontend to be removed");
2446 return -ENODEV;
2447}
2448EXPORT_SYMBOL(dib8000_remove_slave_frontend);
2449
2450struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
2451{
2452 struct dib8000_state *state = fe->demodulator_priv;
2453
2454 if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
2455 return NULL;
2456 return state->fe[slave_index];
2457}
2458EXPORT_SYMBOL(dib8000_get_slave_frontend);
2459
2460
2461int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
2462{
2463 int k = 0, ret = 0;
2464 u8 new_addr = 0;
2465 struct i2c_device client = {.adap = host };
2466
2467 client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
2468 if (!client.i2c_write_buffer) {
2469 dprintk("%s: not enough memory", __func__);
2470 return -ENOMEM;
2471 }
2472 client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
2473 if (!client.i2c_read_buffer) {
2474 dprintk("%s: not enough memory", __func__);
2475 ret = -ENOMEM;
2476 goto error_memory_read;
2477 }
2478 client.i2c_buffer_lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
2479 if (!client.i2c_buffer_lock) {
2480 dprintk("%s: not enough memory", __func__);
2481 ret = -ENOMEM;
2482 goto error_memory_lock;
2483 }
2484 mutex_init(client.i2c_buffer_lock);
2485
2486 for (k = no_of_demods - 1; k >= 0; k--) {
2487 /* designated i2c address */
2488 new_addr = first_addr + (k << 1);
2489
2490 client.addr = new_addr;
2491 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2492 if (dib8000_identify(&client) == 0) {
2493 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2494 client.addr = default_addr;
2495 if (dib8000_identify(&client) == 0) {
2496 dprintk("#%d: not identified", k);
2497 ret = -EINVAL;
2498 goto error;
2499 }
2500 }
2501
2502 /* start diversity to pull_down div_str - just for i2c-enumeration */
2503 dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
2504
2505 /* set new i2c address and force divstart */
2506 dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
2507 client.addr = new_addr;
2508 dib8000_identify(&client);
2509
2510 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
2511 }
2512
2513 for (k = 0; k < no_of_demods; k++) {
2514 new_addr = first_addr | (k << 1);
2515 client.addr = new_addr;
2516
2517 // unforce divstr
2518 dib8000_i2c_write16(&client, 1285, new_addr << 2);
2519
2520 /* deactivate div - it was just for i2c-enumeration */
2521 dib8000_i2c_write16(&client, 1286, 0);
2522 }
2523
2524error:
2525 kfree(client.i2c_buffer_lock);
2526error_memory_lock:
2527 kfree(client.i2c_read_buffer);
2528error_memory_read:
2529 kfree(client.i2c_write_buffer);
2530
2531 return ret;
2532}
2533
2534EXPORT_SYMBOL(dib8000_i2c_enumeration);
2535static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
2536{
2537 tune->min_delay_ms = 1000;
2538 tune->step_size = 0;
2539 tune->max_drift = 0;
2540 return 0;
2541}
2542
2543static void dib8000_release(struct dvb_frontend *fe)
2544{
2545 struct dib8000_state *st = fe->demodulator_priv;
2546 u8 index_frontend;
2547
2548 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
2549 dvb_frontend_detach(st->fe[index_frontend]);
2550
2551 dibx000_exit_i2c_master(&st->i2c_master);
2552 kfree(st->fe[0]);
2553 kfree(st);
2554}
2555
2556struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
2557{
2558 struct dib8000_state *st = fe->demodulator_priv;
2559 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
2560}
2561
2562EXPORT_SYMBOL(dib8000_get_i2c_master);
2563
2564int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
2565{
2566 struct dib8000_state *st = fe->demodulator_priv;
2567 u16 val = dib8000_read_word(st, 299) & 0xffef;
2568 val |= (onoff & 0x1) << 4;
2569
2570 dprintk("pid filter enabled %d", onoff);
2571 return dib8000_write_word(st, 299, val);
2572}
2573EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
2574
2575int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
2576{
2577 struct dib8000_state *st = fe->demodulator_priv;
2578 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
2579 return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
2580}
2581EXPORT_SYMBOL(dib8000_pid_filter);
2582
2583static const struct dvb_frontend_ops dib8000_ops = {
2584 .info = {
2585 .name = "DiBcom 8000 ISDB-T",
2586 .type = FE_OFDM,
2587 .frequency_min = 44250000,
2588 .frequency_max = 867250000,
2589 .frequency_stepsize = 62500,
2590 .caps = FE_CAN_INVERSION_AUTO |
2591 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2592 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2593 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2594 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2595 },
2596
2597 .release = dib8000_release,
2598
2599 .init = dib8000_wakeup,
2600 .sleep = dib8000_sleep,
2601
2602 .set_frontend = dib8000_set_frontend,
2603 .get_tune_settings = dib8000_fe_get_tune_settings,
2604 .get_frontend = dib8000_get_frontend,
2605
2606 .read_status = dib8000_read_status,
2607 .read_ber = dib8000_read_ber,
2608 .read_signal_strength = dib8000_read_signal_strength,
2609 .read_snr = dib8000_read_snr,
2610 .read_ucblocks = dib8000_read_unc_blocks,
2611};
2612
2613struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
2614{
2615 struct dvb_frontend *fe;
2616 struct dib8000_state *state;
2617
2618 dprintk("dib8000_attach");
2619
2620 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
2621 if (state == NULL)
2622 return NULL;
2623 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
2624 if (fe == NULL)
2625 goto error;
2626
2627 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
2628 state->i2c.adap = i2c_adap;
2629 state->i2c.addr = i2c_addr;
2630 state->i2c.i2c_write_buffer = state->i2c_write_buffer;
2631 state->i2c.i2c_read_buffer = state->i2c_read_buffer;
2632 mutex_init(&state->i2c_buffer_lock);
2633 state->i2c.i2c_buffer_lock = &state->i2c_buffer_lock;
2634 state->gpio_val = cfg->gpio_val;
2635 state->gpio_dir = cfg->gpio_dir;
2636
2637 /* Ensure the output mode remains at the previous default if it's
2638 * not specifically set by the caller.
2639 */
2640 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2641 state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2642
2643 state->fe[0] = fe;
2644 fe->demodulator_priv = state;
2645 memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
2646
2647 state->timf_default = cfg->pll->timf;
2648
2649 if (dib8000_identify(&state->i2c) == 0)
2650 goto error;
2651
2652 dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
2653
2654 dib8000_reset(fe);
2655
2656 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
2657
2658 return fe;
2659
2660 error:
2661 kfree(state);
2662 return NULL;
2663}
2664
2665EXPORT_SYMBOL(dib8000_attach);
2666
2667MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
2668MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
2669MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h
new file mode 100644
index 00000000000..617f9eba3a0
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib8000.h
@@ -0,0 +1,136 @@
1#ifndef DIB8000_H
2#define DIB8000_H
3
4#include "dibx000_common.h"
5
6struct dib8000_config {
7 u8 output_mpeg2_in_188_bytes;
8 u8 hostbus_diversity;
9 u8 tuner_is_baseband;
10 int (*update_lna) (struct dvb_frontend *, u16 agc_global);
11
12 u8 agc_config_count;
13 struct dibx000_agc_config *agc;
14 struct dibx000_bandwidth_config *pll;
15
16#define DIB8000_GPIO_DEFAULT_DIRECTIONS 0xffff
17 u16 gpio_dir;
18#define DIB8000_GPIO_DEFAULT_VALUES 0x0000
19 u16 gpio_val;
20#define DIB8000_GPIO_PWM_POS0(v) ((v & 0xf) << 12)
21#define DIB8000_GPIO_PWM_POS1(v) ((v & 0xf) << 8 )
22#define DIB8000_GPIO_PWM_POS2(v) ((v & 0xf) << 4 )
23#define DIB8000_GPIO_PWM_POS3(v) (v & 0xf)
24#define DIB8000_GPIO_DEFAULT_PWM_POS 0xffff
25 u16 gpio_pwm_pos;
26 u16 pwm_freq_div;
27
28 void (*agc_control) (struct dvb_frontend *, u8 before);
29
30 u16 drives;
31 u16 diversity_delay;
32 u8 div_cfg;
33 u8 output_mode;
34 u8 refclksel;
35};
36
37#define DEFAULT_DIB8000_I2C_ADDRESS 18
38
39#if defined(CONFIG_DVB_DIB8000) || (defined(CONFIG_DVB_DIB8000_MODULE) && defined(MODULE))
40extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
41extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
42
43extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr);
44
45extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
46extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
47extern int dib8000_pid_filter_ctrl(struct dvb_frontend *, u8 onoff);
48extern int dib8000_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
49extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state);
50extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe);
51extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe);
52extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode);
53extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
54extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe);
55extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
56#else
57static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
58{
59 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
60 return NULL;
61}
62
63static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
64{
65 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
66 return NULL;
67}
68
69static inline int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
70{
71 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
72 return -ENODEV;
73}
74
75static inline int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
76{
77 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
78 return -ENODEV;
79}
80
81static inline int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
82{
83 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
84 return -ENODEV;
85}
86
87static inline int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
88{
89 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
90 return -ENODEV;
91}
92
93static inline int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
94{
95 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
96 return -ENODEV;
97}
98static inline int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
99{
100 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
101 return -ENODEV;
102}
103static inline enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
104{
105 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
106 return CT_SHUTDOWN;
107}
108static inline void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
109{
110 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
111}
112static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
113{
114 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
115 return 0;
116}
117static inline int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
118{
119 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
120 return -ENODEV;
121}
122
123int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
124{
125 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
126 return -ENODEV;
127}
128
129static inline struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
130{
131 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
132 return NULL;
133}
134#endif
135
136#endif
diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c
new file mode 100644
index 00000000000..b931074a952
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib9000.c
@@ -0,0 +1,2529 @@
1/*
2 * Linux-DVB Driver for DiBcom's DiB9000 and demodulator-family.
3 *
4 * Copyright (C) 2005-10 DiBcom (http://www.dibcom.fr/)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 */
10#include <linux/kernel.h>
11#include <linux/i2c.h>
12#include <linux/mutex.h>
13
14#include "dvb_math.h"
15#include "dvb_frontend.h"
16
17#include "dib9000.h"
18#include "dibx000_common.h"
19
20static int debug;
21module_param(debug, int, 0644);
22MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
23
24#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB9000: "); printk(args); printk("\n"); } } while (0)
25#define MAX_NUMBER_OF_FRONTENDS 6
26
27struct i2c_device {
28 struct i2c_adapter *i2c_adap;
29 u8 i2c_addr;
30 u8 *i2c_read_buffer;
31 u8 *i2c_write_buffer;
32};
33
34/* lock */
35#define DIB_LOCK struct mutex
36#define DibAcquireLock(lock) do { if (mutex_lock_interruptible(lock) < 0) dprintk("could not get the lock"); } while (0)
37#define DibReleaseLock(lock) mutex_unlock(lock)
38#define DibInitLock(lock) mutex_init(lock)
39#define DibFreeLock(lock)
40
41struct dib9000_pid_ctrl {
42#define DIB9000_PID_FILTER_CTRL 0
43#define DIB9000_PID_FILTER 1
44 u8 cmd;
45 u8 id;
46 u16 pid;
47 u8 onoff;
48};
49
50struct dib9000_state {
51 struct i2c_device i2c;
52
53 struct dibx000_i2c_master i2c_master;
54 struct i2c_adapter tuner_adap;
55 struct i2c_adapter component_bus;
56
57 u16 revision;
58 u8 reg_offs;
59
60 enum frontend_tune_state tune_state;
61 u32 status;
62 struct dvb_frontend_parametersContext channel_status;
63
64 u8 fe_id;
65
66#define DIB9000_GPIO_DEFAULT_DIRECTIONS 0xffff
67 u16 gpio_dir;
68#define DIB9000_GPIO_DEFAULT_VALUES 0x0000
69 u16 gpio_val;
70#define DIB9000_GPIO_DEFAULT_PWM_POS 0xffff
71 u16 gpio_pwm_pos;
72
73 union { /* common for all chips */
74 struct {
75 u8 mobile_mode:1;
76 } host;
77
78 struct {
79 struct dib9000_fe_memory_map {
80 u16 addr;
81 u16 size;
82 } fe_mm[18];
83 u8 memcmd;
84
85 DIB_LOCK mbx_if_lock; /* to protect read/write operations */
86 DIB_LOCK mbx_lock; /* to protect the whole mailbox handling */
87
88 DIB_LOCK mem_lock; /* to protect the memory accesses */
89 DIB_LOCK mem_mbx_lock; /* to protect the memory-based mailbox */
90
91#define MBX_MAX_WORDS (256 - 200 - 2)
92#define DIB9000_MSG_CACHE_SIZE 2
93 u16 message_cache[DIB9000_MSG_CACHE_SIZE][MBX_MAX_WORDS];
94 u8 fw_is_running;
95 } risc;
96 } platform;
97
98 union { /* common for all platforms */
99 struct {
100 struct dib9000_config cfg;
101 } d9;
102 } chip;
103
104 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
105 u16 component_bus_speed;
106
107 /* for the I2C transfer */
108 struct i2c_msg msg[2];
109 u8 i2c_write_buffer[255];
110 u8 i2c_read_buffer[255];
111 DIB_LOCK demod_lock;
112 u8 get_frontend_internal;
113 struct dib9000_pid_ctrl pid_ctrl[10];
114 s8 pid_ctrl_index; /* -1: empty list; -2: do not use the list */
115};
116
117static const u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
118 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
119 0, 0, 0, 0, 0, 0, 0, 0
120};
121
122enum dib9000_power_mode {
123 DIB9000_POWER_ALL = 0,
124
125 DIB9000_POWER_NO,
126 DIB9000_POWER_INTERF_ANALOG_AGC,
127 DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
128 DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD,
129 DIB9000_POWER_INTERFACE_ONLY,
130};
131
132enum dib9000_out_messages {
133 OUT_MSG_HBM_ACK,
134 OUT_MSG_HOST_BUF_FAIL,
135 OUT_MSG_REQ_VERSION,
136 OUT_MSG_BRIDGE_I2C_W,
137 OUT_MSG_BRIDGE_I2C_R,
138 OUT_MSG_BRIDGE_APB_W,
139 OUT_MSG_BRIDGE_APB_R,
140 OUT_MSG_SCAN_CHANNEL,
141 OUT_MSG_MONIT_DEMOD,
142 OUT_MSG_CONF_GPIO,
143 OUT_MSG_DEBUG_HELP,
144 OUT_MSG_SUBBAND_SEL,
145 OUT_MSG_ENABLE_TIME_SLICE,
146 OUT_MSG_FE_FW_DL,
147 OUT_MSG_FE_CHANNEL_SEARCH,
148 OUT_MSG_FE_CHANNEL_TUNE,
149 OUT_MSG_FE_SLEEP,
150 OUT_MSG_FE_SYNC,
151 OUT_MSG_CTL_MONIT,
152
153 OUT_MSG_CONF_SVC,
154 OUT_MSG_SET_HBM,
155 OUT_MSG_INIT_DEMOD,
156 OUT_MSG_ENABLE_DIVERSITY,
157 OUT_MSG_SET_OUTPUT_MODE,
158 OUT_MSG_SET_PRIORITARY_CHANNEL,
159 OUT_MSG_ACK_FRG,
160 OUT_MSG_INIT_PMU,
161};
162
163enum dib9000_in_messages {
164 IN_MSG_DATA,
165 IN_MSG_FRAME_INFO,
166 IN_MSG_CTL_MONIT,
167 IN_MSG_ACK_FREE_ITEM,
168 IN_MSG_DEBUG_BUF,
169 IN_MSG_MPE_MONITOR,
170 IN_MSG_RAWTS_MONITOR,
171 IN_MSG_END_BRIDGE_I2C_RW,
172 IN_MSG_END_BRIDGE_APB_RW,
173 IN_MSG_VERSION,
174 IN_MSG_END_OF_SCAN,
175 IN_MSG_MONIT_DEMOD,
176 IN_MSG_ERROR,
177 IN_MSG_FE_FW_DL_DONE,
178 IN_MSG_EVENT,
179 IN_MSG_ACK_CHANGE_SVC,
180 IN_MSG_HBM_PROF,
181};
182
183/* memory_access requests */
184#define FE_MM_W_CHANNEL 0
185#define FE_MM_W_FE_INFO 1
186#define FE_MM_RW_SYNC 2
187
188#define FE_SYNC_CHANNEL 1
189#define FE_SYNC_W_GENERIC_MONIT 2
190#define FE_SYNC_COMPONENT_ACCESS 3
191
192#define FE_MM_R_CHANNEL_SEARCH_STATE 3
193#define FE_MM_R_CHANNEL_UNION_CONTEXT 4
194#define FE_MM_R_FE_INFO 5
195#define FE_MM_R_FE_MONITOR 6
196
197#define FE_MM_W_CHANNEL_HEAD 7
198#define FE_MM_W_CHANNEL_UNION 8
199#define FE_MM_W_CHANNEL_CONTEXT 9
200#define FE_MM_R_CHANNEL_UNION 10
201#define FE_MM_R_CHANNEL_CONTEXT 11
202#define FE_MM_R_CHANNEL_TUNE_STATE 12
203
204#define FE_MM_R_GENERIC_MONITORING_SIZE 13
205#define FE_MM_W_GENERIC_MONITORING 14
206#define FE_MM_R_GENERIC_MONITORING 15
207
208#define FE_MM_W_COMPONENT_ACCESS 16
209#define FE_MM_RW_COMPONENT_ACCESS_BUFFER 17
210static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len);
211static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len);
212
213static u16 to_fw_output_mode(u16 mode)
214{
215 switch (mode) {
216 case OUTMODE_HIGH_Z:
217 return 0;
218 case OUTMODE_MPEG2_PAR_GATED_CLK:
219 return 4;
220 case OUTMODE_MPEG2_PAR_CONT_CLK:
221 return 8;
222 case OUTMODE_MPEG2_SERIAL:
223 return 16;
224 case OUTMODE_DIVERSITY:
225 return 128;
226 case OUTMODE_MPEG2_FIFO:
227 return 2;
228 case OUTMODE_ANALOG_ADC:
229 return 1;
230 default:
231 return 0;
232 }
233}
234
235static u16 dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 * b, u32 len, u16 attribute)
236{
237 u32 chunk_size = 126;
238 u32 l;
239 int ret;
240
241 if (state->platform.risc.fw_is_running && (reg < 1024))
242 return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len);
243
244 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
245 state->msg[0].addr = state->i2c.i2c_addr >> 1;
246 state->msg[0].flags = 0;
247 state->msg[0].buf = state->i2c_write_buffer;
248 state->msg[0].len = 2;
249 state->msg[1].addr = state->i2c.i2c_addr >> 1;
250 state->msg[1].flags = I2C_M_RD;
251 state->msg[1].buf = b;
252 state->msg[1].len = len;
253
254 state->i2c_write_buffer[0] = reg >> 8;
255 state->i2c_write_buffer[1] = reg & 0xff;
256
257 if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
258 state->i2c_write_buffer[0] |= (1 << 5);
259 if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
260 state->i2c_write_buffer[0] |= (1 << 4);
261
262 do {
263 l = len < chunk_size ? len : chunk_size;
264 state->msg[1].len = l;
265 state->msg[1].buf = b;
266 ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 2) != 2 ? -EREMOTEIO : 0;
267 if (ret != 0) {
268 dprintk("i2c read error on %d", reg);
269 return -EREMOTEIO;
270 }
271
272 b += l;
273 len -= l;
274
275 if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))
276 reg += l / 2;
277 } while ((ret == 0) && len);
278
279 return 0;
280}
281
282static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg)
283{
284 struct i2c_msg msg[2] = {
285 {.addr = i2c->i2c_addr >> 1, .flags = 0,
286 .buf = i2c->i2c_write_buffer, .len = 2},
287 {.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD,
288 .buf = i2c->i2c_read_buffer, .len = 2},
289 };
290
291 i2c->i2c_write_buffer[0] = reg >> 8;
292 i2c->i2c_write_buffer[1] = reg & 0xff;
293
294 if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) {
295 dprintk("read register %x error", reg);
296 return 0;
297 }
298
299 return (i2c->i2c_read_buffer[0] << 8) | i2c->i2c_read_buffer[1];
300}
301
302static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg)
303{
304 if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2, 0) != 0)
305 return 0;
306 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
307}
308
309static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute)
310{
311 if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2,
312 attribute) != 0)
313 return 0;
314 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
315}
316
317#define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
318
319static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * buf, u32 len, u16 attribute)
320{
321 u32 chunk_size = 126;
322 u32 l;
323 int ret;
324
325 if (state->platform.risc.fw_is_running && (reg < 1024)) {
326 if (dib9000_risc_apb_access_write
327 (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0)
328 return -EINVAL;
329 return 0;
330 }
331
332 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
333 state->msg[0].addr = state->i2c.i2c_addr >> 1;
334 state->msg[0].flags = 0;
335 state->msg[0].buf = state->i2c_write_buffer;
336 state->msg[0].len = len + 2;
337
338 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
339 state->i2c_write_buffer[1] = (reg) & 0xff;
340
341 if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
342 state->i2c_write_buffer[0] |= (1 << 5);
343 if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
344 state->i2c_write_buffer[0] |= (1 << 4);
345
346 do {
347 l = len < chunk_size ? len : chunk_size;
348 state->msg[0].len = l + 2;
349 memcpy(&state->i2c_write_buffer[2], buf, l);
350
351 ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
352
353 buf += l;
354 len -= l;
355
356 if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))
357 reg += l / 2;
358 } while ((ret == 0) && len);
359
360 return ret;
361}
362
363static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
364{
365 struct i2c_msg msg = {
366 .addr = i2c->i2c_addr >> 1, .flags = 0,
367 .buf = i2c->i2c_write_buffer, .len = 4
368 };
369
370 i2c->i2c_write_buffer[0] = (reg >> 8) & 0xff;
371 i2c->i2c_write_buffer[1] = reg & 0xff;
372 i2c->i2c_write_buffer[2] = (val >> 8) & 0xff;
373 i2c->i2c_write_buffer[3] = val & 0xff;
374
375 return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
376}
377
378static inline int dib9000_write_word(struct dib9000_state *state, u16 reg, u16 val)
379{
380 u8 b[2] = { val >> 8, val & 0xff };
381 return dib9000_write16_attr(state, reg, b, 2, 0);
382}
383
384static inline int dib9000_write_word_attr(struct dib9000_state *state, u16 reg, u16 val, u16 attribute)
385{
386 u8 b[2] = { val >> 8, val & 0xff };
387 return dib9000_write16_attr(state, reg, b, 2, attribute);
388}
389
390#define dib9000_write(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, 0)
391#define dib9000_write16_noinc(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
392#define dib9000_write16_noinc_attr(state, reg, buf, len, attribute) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | (attribute))
393
394#define dib9000_mbx_send(state, id, data, len) dib9000_mbx_send_attr(state, id, data, len, 0)
395#define dib9000_mbx_get_message(state, id, msg, len) dib9000_mbx_get_message_attr(state, id, msg, len, 0)
396
397#define MAC_IRQ (1 << 1)
398#define IRQ_POL_MSK (1 << 4)
399
400#define dib9000_risc_mem_read_chunks(state, b, len) dib9000_read16_attr(state, 1063, b, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
401#define dib9000_risc_mem_write_chunks(state, buf, len) dib9000_write16_attr(state, 1063, buf, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
402
403static void dib9000_risc_mem_setup_cmd(struct dib9000_state *state, u32 addr, u32 len, u8 reading)
404{
405 u8 b[14] = { 0 };
406
407/* dprintk("%d memcmd: %d %d %d\n", state->fe_id, addr, addr+len, len); */
408/* b[0] = 0 << 7; */
409 b[1] = 1;
410
411/* b[2] = 0; */
412/* b[3] = 0; */
413 b[4] = (u8) (addr >> 8);
414 b[5] = (u8) (addr & 0xff);
415
416/* b[10] = 0; */
417/* b[11] = 0; */
418 b[12] = (u8) (addr >> 8);
419 b[13] = (u8) (addr & 0xff);
420
421 addr += len;
422/* b[6] = 0; */
423/* b[7] = 0; */
424 b[8] = (u8) (addr >> 8);
425 b[9] = (u8) (addr & 0xff);
426
427 dib9000_write(state, 1056, b, 14);
428 if (reading)
429 dib9000_write_word(state, 1056, (1 << 15) | 1);
430 state->platform.risc.memcmd = -1; /* if it was called directly reset it - to force a future setup-call to set it */
431}
432
433static void dib9000_risc_mem_setup(struct dib9000_state *state, u8 cmd)
434{
435 struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd & 0x7f];
436 /* decide whether we need to "refresh" the memory controller */
437 if (state->platform.risc.memcmd == cmd && /* same command */
438 !(cmd & 0x80 && m->size < 67)) /* and we do not want to read something with less than 67 bytes looping - working around a bug in the memory controller */
439 return;
440 dib9000_risc_mem_setup_cmd(state, m->addr, m->size, cmd & 0x80);
441 state->platform.risc.memcmd = cmd;
442}
443
444static int dib9000_risc_mem_read(struct dib9000_state *state, u8 cmd, u8 * b, u16 len)
445{
446 if (!state->platform.risc.fw_is_running)
447 return -EIO;
448
449 DibAcquireLock(&state->platform.risc.mem_lock);
450 dib9000_risc_mem_setup(state, cmd | 0x80);
451 dib9000_risc_mem_read_chunks(state, b, len);
452 DibReleaseLock(&state->platform.risc.mem_lock);
453 return 0;
454}
455
456static int dib9000_risc_mem_write(struct dib9000_state *state, u8 cmd, const u8 * b)
457{
458 struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd];
459 if (!state->platform.risc.fw_is_running)
460 return -EIO;
461
462 DibAcquireLock(&state->platform.risc.mem_lock);
463 dib9000_risc_mem_setup(state, cmd);
464 dib9000_risc_mem_write_chunks(state, b, m->size);
465 DibReleaseLock(&state->platform.risc.mem_lock);
466 return 0;
467}
468
469static int dib9000_firmware_download(struct dib9000_state *state, u8 risc_id, u16 key, const u8 * code, u32 len)
470{
471 u16 offs;
472
473 if (risc_id == 1)
474 offs = 16;
475 else
476 offs = 0;
477
478 /* config crtl reg */
479 dib9000_write_word(state, 1024 + offs, 0x000f);
480 dib9000_write_word(state, 1025 + offs, 0);
481 dib9000_write_word(state, 1031 + offs, key);
482
483 dprintk("going to download %dB of microcode", len);
484 if (dib9000_write16_noinc(state, 1026 + offs, (u8 *) code, (u16) len) != 0) {
485 dprintk("error while downloading microcode for RISC %c", 'A' + risc_id);
486 return -EIO;
487 }
488
489 dprintk("Microcode for RISC %c loaded", 'A' + risc_id);
490
491 return 0;
492}
493
494static int dib9000_mbx_host_init(struct dib9000_state *state, u8 risc_id)
495{
496 u16 mbox_offs;
497 u16 reset_reg;
498 u16 tries = 1000;
499
500 if (risc_id == 1)
501 mbox_offs = 16;
502 else
503 mbox_offs = 0;
504
505 /* Reset mailbox */
506 dib9000_write_word(state, 1027 + mbox_offs, 0x8000);
507
508 /* Read reset status */
509 do {
510 reset_reg = dib9000_read_word(state, 1027 + mbox_offs);
511 msleep(100);
512 } while ((reset_reg & 0x8000) && --tries);
513
514 if (reset_reg & 0x8000) {
515 dprintk("MBX: init ERROR, no response from RISC %c", 'A' + risc_id);
516 return -EIO;
517 }
518 dprintk("MBX: initialized");
519 return 0;
520}
521
522#define MAX_MAILBOX_TRY 100
523static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data, u8 len, u16 attr)
524{
525 u8 *d, b[2];
526 u16 tmp;
527 u16 size;
528 u32 i;
529 int ret = 0;
530
531 if (!state->platform.risc.fw_is_running)
532 return -EINVAL;
533
534 DibAcquireLock(&state->platform.risc.mbx_if_lock);
535 tmp = MAX_MAILBOX_TRY;
536 do {
537 size = dib9000_read_word_attr(state, 1043, attr) & 0xff;
538 if ((size + len + 1) > MBX_MAX_WORDS && --tmp) {
539 dprintk("MBX: RISC mbx full, retrying");
540 msleep(100);
541 } else
542 break;
543 } while (1);
544
545 /*dprintk( "MBX: size: %d", size); */
546
547 if (tmp == 0) {
548 ret = -EINVAL;
549 goto out;
550 }
551#ifdef DUMP_MSG
552 dprintk("--> %02x %d ", id, len + 1);
553 for (i = 0; i < len; i++)
554 dprintk("%04x ", data[i]);
555 dprintk("\n");
556#endif
557
558 /* byte-order conversion - works on big (where it is not necessary) or little endian */
559 d = (u8 *) data;
560 for (i = 0; i < len; i++) {
561 tmp = data[i];
562 *d++ = tmp >> 8;
563 *d++ = tmp & 0xff;
564 }
565
566 /* write msg */
567 b[0] = id;
568 b[1] = len + 1;
569 if (dib9000_write16_noinc_attr(state, 1045, b, 2, attr) != 0 || dib9000_write16_noinc_attr(state, 1045, (u8 *) data, len * 2, attr) != 0) {
570 ret = -EIO;
571 goto out;
572 }
573
574 /* update register nb_mes_in_RX */
575 ret = (u8) dib9000_write_word_attr(state, 1043, 1 << 14, attr);
576
577out:
578 DibReleaseLock(&state->platform.risc.mbx_if_lock);
579
580 return ret;
581}
582
583static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id, u16 attr)
584{
585#ifdef DUMP_MSG
586 u16 *d = data;
587#endif
588
589 u16 tmp, i;
590 u8 size;
591 u8 mc_base;
592
593 if (!state->platform.risc.fw_is_running)
594 return 0;
595
596 DibAcquireLock(&state->platform.risc.mbx_if_lock);
597 if (risc_id == 1)
598 mc_base = 16;
599 else
600 mc_base = 0;
601
602 /* Length and type in the first word */
603 *data = dib9000_read_word_attr(state, 1029 + mc_base, attr);
604
605 size = *data & 0xff;
606 if (size <= MBX_MAX_WORDS) {
607 data++;
608 size--; /* Initial word already read */
609
610 dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, size * 2, attr);
611
612 /* to word conversion */
613 for (i = 0; i < size; i++) {
614 tmp = *data;
615 *data = (tmp >> 8) | (tmp << 8);
616 data++;
617 }
618
619#ifdef DUMP_MSG
620 dprintk("<-- ");
621 for (i = 0; i < size + 1; i++)
622 dprintk("%04x ", d[i]);
623 dprintk("\n");
624#endif
625 } else {
626 dprintk("MBX: message is too big for message cache (%d), flushing message", size);
627 size--; /* Initial word already read */
628 while (size--)
629 dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, 2, attr);
630 }
631 /* Update register nb_mes_in_TX */
632 dib9000_write_word_attr(state, 1028 + mc_base, 1 << 14, attr);
633
634 DibReleaseLock(&state->platform.risc.mbx_if_lock);
635
636 return size + 1;
637}
638
639static int dib9000_risc_debug_buf(struct dib9000_state *state, u16 * data, u8 size)
640{
641 u32 ts = data[1] << 16 | data[0];
642 char *b = (char *)&data[2];
643
644 b[2 * (size - 2) - 1] = '\0'; /* Bullet proof the buffer */
645 if (*b == '~') {
646 b++;
647 dprintk(b);
648 } else
649 dprintk("RISC%d: %d.%04d %s", state->fe_id, ts / 10000, ts % 10000, *b ? b : "<emtpy>");
650 return 1;
651}
652
653static int dib9000_mbx_fetch_to_cache(struct dib9000_state *state, u16 attr)
654{
655 int i;
656 u8 size;
657 u16 *block;
658 /* find a free slot */
659 for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {
660 block = state->platform.risc.message_cache[i];
661 if (*block == 0) {
662 size = dib9000_mbx_read(state, block, 1, attr);
663
664/* dprintk( "MBX: fetched %04x message to cache", *block); */
665
666 switch (*block >> 8) {
667 case IN_MSG_DEBUG_BUF:
668 dib9000_risc_debug_buf(state, block + 1, size); /* debug-messages are going to be printed right away */
669 *block = 0; /* free the block */
670 break;
671#if 0
672 case IN_MSG_DATA: /* FE-TRACE */
673 dib9000_risc_data_process(state, block + 1, size);
674 *block = 0;
675 break;
676#endif
677 default:
678 break;
679 }
680
681 return 1;
682 }
683 }
684 dprintk("MBX: no free cache-slot found for new message...");
685 return -1;
686}
687
688static u8 dib9000_mbx_count(struct dib9000_state *state, u8 risc_id, u16 attr)
689{
690 if (risc_id == 0)
691 return (u8) (dib9000_read_word_attr(state, 1028, attr) >> 10) & 0x1f; /* 5 bit field */
692 else
693 return (u8) (dib9000_read_word_attr(state, 1044, attr) >> 8) & 0x7f; /* 7 bit field */
694}
695
696static int dib9000_mbx_process(struct dib9000_state *state, u16 attr)
697{
698 int ret = 0;
699 u16 tmp;
700
701 if (!state->platform.risc.fw_is_running)
702 return -1;
703
704 DibAcquireLock(&state->platform.risc.mbx_lock);
705
706 if (dib9000_mbx_count(state, 1, attr)) /* 1=RiscB */
707 ret = dib9000_mbx_fetch_to_cache(state, attr);
708
709 tmp = dib9000_read_word_attr(state, 1229, attr); /* Clear the IRQ */
710/* if (tmp) */
711/* dprintk( "cleared IRQ: %x", tmp); */
712 DibReleaseLock(&state->platform.risc.mbx_lock);
713
714 return ret;
715}
716
717static int dib9000_mbx_get_message_attr(struct dib9000_state *state, u16 id, u16 * msg, u8 * size, u16 attr)
718{
719 u8 i;
720 u16 *block;
721 u16 timeout = 30;
722
723 *msg = 0;
724 do {
725 /* dib9000_mbx_get_from_cache(); */
726 for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {
727 block = state->platform.risc.message_cache[i];
728 if ((*block >> 8) == id) {
729 *size = (*block & 0xff) - 1;
730 memcpy(msg, block + 1, (*size) * 2);
731 *block = 0; /* free the block */
732 i = 0; /* signal that we found a message */
733 break;
734 }
735 }
736
737 if (i == 0)
738 break;
739
740 if (dib9000_mbx_process(state, attr) == -1) /* try to fetch one message - if any */
741 return -1;
742
743 } while (--timeout);
744
745 if (timeout == 0) {
746 dprintk("waiting for message %d timed out", id);
747 return -1;
748 }
749
750 return i == 0;
751}
752
753static int dib9000_risc_check_version(struct dib9000_state *state)
754{
755 u8 r[4];
756 u8 size;
757 u16 fw_version = 0;
758
759 if (dib9000_mbx_send(state, OUT_MSG_REQ_VERSION, &fw_version, 1) != 0)
760 return -EIO;
761
762 if (dib9000_mbx_get_message(state, IN_MSG_VERSION, (u16 *) r, &size) < 0)
763 return -EIO;
764
765 fw_version = (r[0] << 8) | r[1];
766 dprintk("RISC: ver: %d.%02d (IC: %d)", fw_version >> 10, fw_version & 0x3ff, (r[2] << 8) | r[3]);
767
768 if ((fw_version >> 10) != 7)
769 return -EINVAL;
770
771 switch (fw_version & 0x3ff) {
772 case 11:
773 case 12:
774 case 14:
775 case 15:
776 case 16:
777 case 17:
778 break;
779 default:
780 dprintk("RISC: invalid firmware version");
781 return -EINVAL;
782 }
783
784 dprintk("RISC: valid firmware version");
785 return 0;
786}
787
788static int dib9000_fw_boot(struct dib9000_state *state, const u8 * codeA, u32 lenA, const u8 * codeB, u32 lenB)
789{
790 /* Reconfig pool mac ram */
791 dib9000_write_word(state, 1225, 0x02); /* A: 8k C, 4 k D - B: 32k C 6 k D - IRAM 96k */
792 dib9000_write_word(state, 1226, 0x05);
793
794 /* Toggles IP crypto to Host APB interface. */
795 dib9000_write_word(state, 1542, 1);
796
797 /* Set jump and no jump in the dma box */
798 dib9000_write_word(state, 1074, 0);
799 dib9000_write_word(state, 1075, 0);
800
801 /* Set MAC as APB Master. */
802 dib9000_write_word(state, 1237, 0);
803
804 /* Reset the RISCs */
805 if (codeA != NULL)
806 dib9000_write_word(state, 1024, 2);
807 else
808 dib9000_write_word(state, 1024, 15);
809 if (codeB != NULL)
810 dib9000_write_word(state, 1040, 2);
811
812 if (codeA != NULL)
813 dib9000_firmware_download(state, 0, 0x1234, codeA, lenA);
814 if (codeB != NULL)
815 dib9000_firmware_download(state, 1, 0x1234, codeB, lenB);
816
817 /* Run the RISCs */
818 if (codeA != NULL)
819 dib9000_write_word(state, 1024, 0);
820 if (codeB != NULL)
821 dib9000_write_word(state, 1040, 0);
822
823 if (codeA != NULL)
824 if (dib9000_mbx_host_init(state, 0) != 0)
825 return -EIO;
826 if (codeB != NULL)
827 if (dib9000_mbx_host_init(state, 1) != 0)
828 return -EIO;
829
830 msleep(100);
831 state->platform.risc.fw_is_running = 1;
832
833 if (dib9000_risc_check_version(state) != 0)
834 return -EINVAL;
835
836 state->platform.risc.memcmd = 0xff;
837 return 0;
838}
839
840static u16 dib9000_identify(struct i2c_device *client)
841{
842 u16 value;
843
844 value = dib9000_i2c_read16(client, 896);
845 if (value != 0x01b3) {
846 dprintk("wrong Vendor ID (0x%x)", value);
847 return 0;
848 }
849
850 value = dib9000_i2c_read16(client, 897);
851 if (value != 0x4000 && value != 0x4001 && value != 0x4002 && value != 0x4003 && value != 0x4004 && value != 0x4005) {
852 dprintk("wrong Device ID (0x%x)", value);
853 return 0;
854 }
855
856 /* protect this driver to be used with 7000PC */
857 if (value == 0x4000 && dib9000_i2c_read16(client, 769) == 0x4000) {
858 dprintk("this driver does not work with DiB7000PC");
859 return 0;
860 }
861
862 switch (value) {
863 case 0x4000:
864 dprintk("found DiB7000MA/PA/MB/PB");
865 break;
866 case 0x4001:
867 dprintk("found DiB7000HC");
868 break;
869 case 0x4002:
870 dprintk("found DiB7000MC");
871 break;
872 case 0x4003:
873 dprintk("found DiB9000A");
874 break;
875 case 0x4004:
876 dprintk("found DiB9000H");
877 break;
878 case 0x4005:
879 dprintk("found DiB9000M");
880 break;
881 }
882
883 return value;
884}
885
886static void dib9000_set_power_mode(struct dib9000_state *state, enum dib9000_power_mode mode)
887{
888 /* by default everything is going to be powered off */
889 u16 reg_903 = 0x3fff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906;
890 u8 offset;
891
892 if (state->revision == 0x4003 || state->revision == 0x4004 || state->revision == 0x4005)
893 offset = 1;
894 else
895 offset = 0;
896
897 reg_906 = dib9000_read_word(state, 906 + offset) | 0x3; /* keep settings for RISC */
898
899 /* now, depending on the requested mode, we power on */
900 switch (mode) {
901 /* power up everything in the demod */
902 case DIB9000_POWER_ALL:
903 reg_903 = 0x0000;
904 reg_904 = 0x0000;
905 reg_905 = 0x0000;
906 reg_906 = 0x0000;
907 break;
908
909 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
910 case DIB9000_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C or SRAM */
911 reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
912 break;
913
914 case DIB9000_POWER_INTERF_ANALOG_AGC:
915 reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
916 reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
917 reg_906 &= ~((1 << 0));
918 break;
919
920 case DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
921 reg_903 = 0x0000;
922 reg_904 = 0x801f;
923 reg_905 = 0x0000;
924 reg_906 &= ~((1 << 0));
925 break;
926
927 case DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD:
928 reg_903 = 0x0000;
929 reg_904 = 0x8000;
930 reg_905 = 0x010b;
931 reg_906 &= ~((1 << 0));
932 break;
933 default:
934 case DIB9000_POWER_NO:
935 break;
936 }
937
938 /* always power down unused parts */
939 if (!state->platform.host.mobile_mode)
940 reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
941
942 /* P_sdio_select_clk = 0 on MC and after */
943 if (state->revision != 0x4000)
944 reg_906 <<= 1;
945
946 dib9000_write_word(state, 903 + offset, reg_903);
947 dib9000_write_word(state, 904 + offset, reg_904);
948 dib9000_write_word(state, 905 + offset, reg_905);
949 dib9000_write_word(state, 906 + offset, reg_906);
950}
951
952static int dib9000_fw_reset(struct dvb_frontend *fe)
953{
954 struct dib9000_state *state = fe->demodulator_priv;
955
956 dib9000_write_word(state, 1817, 0x0003);
957
958 dib9000_write_word(state, 1227, 1);
959 dib9000_write_word(state, 1227, 0);
960
961 switch ((state->revision = dib9000_identify(&state->i2c))) {
962 case 0x4003:
963 case 0x4004:
964 case 0x4005:
965 state->reg_offs = 1;
966 break;
967 default:
968 return -EINVAL;
969 }
970
971 /* reset the i2c-master to use the host interface */
972 dibx000_reset_i2c_master(&state->i2c_master);
973
974 dib9000_set_power_mode(state, DIB9000_POWER_ALL);
975
976 /* unforce divstr regardless whether i2c enumeration was done or not */
977 dib9000_write_word(state, 1794, dib9000_read_word(state, 1794) & ~(1 << 1));
978 dib9000_write_word(state, 1796, 0);
979 dib9000_write_word(state, 1805, 0x805);
980
981 /* restart all parts */
982 dib9000_write_word(state, 898, 0xffff);
983 dib9000_write_word(state, 899, 0xffff);
984 dib9000_write_word(state, 900, 0x0001);
985 dib9000_write_word(state, 901, 0xff19);
986 dib9000_write_word(state, 902, 0x003c);
987
988 dib9000_write_word(state, 898, 0);
989 dib9000_write_word(state, 899, 0);
990 dib9000_write_word(state, 900, 0);
991 dib9000_write_word(state, 901, 0);
992 dib9000_write_word(state, 902, 0);
993
994 dib9000_write_word(state, 911, state->chip.d9.cfg.if_drives);
995
996 dib9000_set_power_mode(state, DIB9000_POWER_INTERFACE_ONLY);
997
998 return 0;
999}
1000
1001static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len)
1002{
1003 u16 mb[10];
1004 u8 i, s;
1005
1006 if (address >= 1024 || !state->platform.risc.fw_is_running)
1007 return -EINVAL;
1008
1009 /* dprintk( "APB access thru rd fw %d %x", address, attribute); */
1010
1011 mb[0] = (u16) address;
1012 mb[1] = len / 2;
1013 dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_R, mb, 2, attribute);
1014 switch (dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute)) {
1015 case 1:
1016 s--;
1017 for (i = 0; i < s; i++) {
1018 b[i * 2] = (mb[i + 1] >> 8) & 0xff;
1019 b[i * 2 + 1] = (mb[i + 1]) & 0xff;
1020 }
1021 return 0;
1022 default:
1023 return -EIO;
1024 }
1025 return -EIO;
1026}
1027
1028static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len)
1029{
1030 u16 mb[10];
1031 u8 s, i;
1032
1033 if (address >= 1024 || !state->platform.risc.fw_is_running)
1034 return -EINVAL;
1035
1036 /* dprintk( "APB access thru wr fw %d %x", address, attribute); */
1037
1038 mb[0] = (unsigned short)address;
1039 for (i = 0; i < len && i < 20; i += 2)
1040 mb[1 + (i / 2)] = (b[i] << 8 | b[i + 1]);
1041
1042 dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, 1 + len / 2, attribute);
1043 return dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute) == 1 ? 0 : -EINVAL;
1044}
1045
1046static int dib9000_fw_memmbx_sync(struct dib9000_state *state, u8 i)
1047{
1048 u8 index_loop = 10;
1049
1050 if (!state->platform.risc.fw_is_running)
1051 return 0;
1052 dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i);
1053 do {
1054 dib9000_risc_mem_read(state, FE_MM_RW_SYNC, state->i2c_read_buffer, 1);
1055 } while (state->i2c_read_buffer[0] && index_loop--);
1056
1057 if (index_loop > 0)
1058 return 0;
1059 return -EIO;
1060}
1061
1062static int dib9000_fw_init(struct dib9000_state *state)
1063{
1064 struct dibGPIOFunction *f;
1065 u16 b[40] = { 0 };
1066 u8 i;
1067 u8 size;
1068
1069 if (dib9000_fw_boot(state, NULL, 0, state->chip.d9.cfg.microcode_B_fe_buffer, state->chip.d9.cfg.microcode_B_fe_size) != 0)
1070 return -EIO;
1071
1072 /* initialize the firmware */
1073 for (i = 0; i < ARRAY_SIZE(state->chip.d9.cfg.gpio_function); i++) {
1074 f = &state->chip.d9.cfg.gpio_function[i];
1075 if (f->mask) {
1076 switch (f->function) {
1077 case BOARD_GPIO_FUNCTION_COMPONENT_ON:
1078 b[0] = (u16) f->mask;
1079 b[1] = (u16) f->direction;
1080 b[2] = (u16) f->value;
1081 break;
1082 case BOARD_GPIO_FUNCTION_COMPONENT_OFF:
1083 b[3] = (u16) f->mask;
1084 b[4] = (u16) f->direction;
1085 b[5] = (u16) f->value;
1086 break;
1087 }
1088 }
1089 }
1090 if (dib9000_mbx_send(state, OUT_MSG_CONF_GPIO, b, 15) != 0)
1091 return -EIO;
1092
1093 /* subband */
1094 b[0] = state->chip.d9.cfg.subband.size; /* type == 0 -> GPIO - PWM not yet supported */
1095 for (i = 0; i < state->chip.d9.cfg.subband.size; i++) {
1096 b[1 + i * 4] = state->chip.d9.cfg.subband.subband[i].f_mhz;
1097 b[2 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.mask;
1098 b[3 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.direction;
1099 b[4 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.value;
1100 }
1101 b[1 + i * 4] = 0; /* fe_id */
1102 if (dib9000_mbx_send(state, OUT_MSG_SUBBAND_SEL, b, 2 + 4 * i) != 0)
1103 return -EIO;
1104
1105 /* 0 - id, 1 - no_of_frontends */
1106 b[0] = (0 << 8) | 1;
1107 /* 0 = i2c-address demod, 0 = tuner */
1108 b[1] = (0 << 8) | (0);
1109 b[2] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000) >> 16) & 0xffff);
1110 b[3] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000)) & 0xffff);
1111 b[4] = (u16) ((state->chip.d9.cfg.vcxo_timer >> 16) & 0xffff);
1112 b[5] = (u16) ((state->chip.d9.cfg.vcxo_timer) & 0xffff);
1113 b[6] = (u16) ((state->chip.d9.cfg.timing_frequency >> 16) & 0xffff);
1114 b[7] = (u16) ((state->chip.d9.cfg.timing_frequency) & 0xffff);
1115 b[29] = state->chip.d9.cfg.if_drives;
1116 if (dib9000_mbx_send(state, OUT_MSG_INIT_DEMOD, b, ARRAY_SIZE(b)) != 0)
1117 return -EIO;
1118
1119 if (dib9000_mbx_send(state, OUT_MSG_FE_FW_DL, NULL, 0) != 0)
1120 return -EIO;
1121
1122 if (dib9000_mbx_get_message(state, IN_MSG_FE_FW_DL_DONE, b, &size) < 0)
1123 return -EIO;
1124
1125 if (size > ARRAY_SIZE(b)) {
1126 dprintk("error : firmware returned %dbytes needed but the used buffer has only %dbytes\n Firmware init ABORTED", size,
1127 (int)ARRAY_SIZE(b));
1128 return -EINVAL;
1129 }
1130
1131 for (i = 0; i < size; i += 2) {
1132 state->platform.risc.fe_mm[i / 2].addr = b[i + 0];
1133 state->platform.risc.fe_mm[i / 2].size = b[i + 1];
1134 }
1135
1136 return 0;
1137}
1138
1139static void dib9000_fw_set_channel_head(struct dib9000_state *state, struct dvb_frontend_parameters *ch)
1140{
1141 u8 b[9];
1142 u32 freq = state->fe[0]->dtv_property_cache.frequency / 1000;
1143 if (state->fe_id % 2)
1144 freq += 101;
1145
1146 b[0] = (u8) ((freq >> 0) & 0xff);
1147 b[1] = (u8) ((freq >> 8) & 0xff);
1148 b[2] = (u8) ((freq >> 16) & 0xff);
1149 b[3] = (u8) ((freq >> 24) & 0xff);
1150 b[4] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 0) & 0xff);
1151 b[5] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 8) & 0xff);
1152 b[6] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 16) & 0xff);
1153 b[7] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 24) & 0xff);
1154 b[8] = 0x80; /* do not wait for CELL ID when doing autosearch */
1155 if (state->fe[0]->dtv_property_cache.delivery_system == SYS_DVBT)
1156 b[8] |= 1;
1157 dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_HEAD, b);
1158}
1159
1160static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_parameters *channel)
1161{
1162 struct dib9000_state *state = fe->demodulator_priv;
1163 struct dibDVBTChannel {
1164 s8 spectrum_inversion;
1165
1166 s8 nfft;
1167 s8 guard;
1168 s8 constellation;
1169
1170 s8 hrch;
1171 s8 alpha;
1172 s8 code_rate_hp;
1173 s8 code_rate_lp;
1174 s8 select_hp;
1175
1176 s8 intlv_native;
1177 };
1178 struct dibDVBTChannel *ch;
1179 int ret = 0;
1180
1181 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
1182 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
1183 goto error;
1184 ret = -EIO;
1185 }
1186
1187 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION,
1188 state->i2c_read_buffer, sizeof(struct dibDVBTChannel));
1189 ch = (struct dibDVBTChannel *)state->i2c_read_buffer;
1190
1191
1192 switch (ch->spectrum_inversion & 0x7) {
1193 case 1:
1194 state->fe[0]->dtv_property_cache.inversion = INVERSION_ON;
1195 break;
1196 case 0:
1197 state->fe[0]->dtv_property_cache.inversion = INVERSION_OFF;
1198 break;
1199 default:
1200 case -1:
1201 state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO;
1202 break;
1203 }
1204 switch (ch->nfft) {
1205 case 0:
1206 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
1207 break;
1208 case 2:
1209 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_4K;
1210 break;
1211 case 1:
1212 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1213 break;
1214 default:
1215 case -1:
1216 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
1217 break;
1218 }
1219 switch (ch->guard) {
1220 case 0:
1221 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
1222 break;
1223 case 1:
1224 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
1225 break;
1226 case 2:
1227 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1228 break;
1229 case 3:
1230 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
1231 break;
1232 default:
1233 case -1:
1234 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
1235 break;
1236 }
1237 switch (ch->constellation) {
1238 case 2:
1239 state->fe[0]->dtv_property_cache.modulation = QAM_64;
1240 break;
1241 case 1:
1242 state->fe[0]->dtv_property_cache.modulation = QAM_16;
1243 break;
1244 case 0:
1245 state->fe[0]->dtv_property_cache.modulation = QPSK;
1246 break;
1247 default:
1248 case -1:
1249 state->fe[0]->dtv_property_cache.modulation = QAM_AUTO;
1250 break;
1251 }
1252 switch (ch->hrch) {
1253 case 0:
1254 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE;
1255 break;
1256 case 1:
1257 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_1;
1258 break;
1259 default:
1260 case -1:
1261 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
1262 break;
1263 }
1264 switch (ch->code_rate_hp) {
1265 case 1:
1266 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2;
1267 break;
1268 case 2:
1269 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_2_3;
1270 break;
1271 case 3:
1272 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_3_4;
1273 break;
1274 case 5:
1275 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_5_6;
1276 break;
1277 case 7:
1278 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_7_8;
1279 break;
1280 default:
1281 case -1:
1282 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO;
1283 break;
1284 }
1285 switch (ch->code_rate_lp) {
1286 case 1:
1287 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2;
1288 break;
1289 case 2:
1290 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_2_3;
1291 break;
1292 case 3:
1293 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_3_4;
1294 break;
1295 case 5:
1296 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_5_6;
1297 break;
1298 case 7:
1299 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_7_8;
1300 break;
1301 default:
1302 case -1:
1303 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_AUTO;
1304 break;
1305 }
1306
1307error:
1308 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
1309 return ret;
1310}
1311
1312static int dib9000_fw_set_channel_union(struct dvb_frontend *fe, struct dvb_frontend_parameters *channel)
1313{
1314 struct dib9000_state *state = fe->demodulator_priv;
1315 struct dibDVBTChannel {
1316 s8 spectrum_inversion;
1317
1318 s8 nfft;
1319 s8 guard;
1320 s8 constellation;
1321
1322 s8 hrch;
1323 s8 alpha;
1324 s8 code_rate_hp;
1325 s8 code_rate_lp;
1326 s8 select_hp;
1327
1328 s8 intlv_native;
1329 };
1330 struct dibDVBTChannel ch;
1331
1332 switch (state->fe[0]->dtv_property_cache.inversion) {
1333 case INVERSION_ON:
1334 ch.spectrum_inversion = 1;
1335 break;
1336 case INVERSION_OFF:
1337 ch.spectrum_inversion = 0;
1338 break;
1339 default:
1340 case INVERSION_AUTO:
1341 ch.spectrum_inversion = -1;
1342 break;
1343 }
1344 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1345 case TRANSMISSION_MODE_2K:
1346 ch.nfft = 0;
1347 break;
1348 case TRANSMISSION_MODE_4K:
1349 ch.nfft = 2;
1350 break;
1351 case TRANSMISSION_MODE_8K:
1352 ch.nfft = 1;
1353 break;
1354 default:
1355 case TRANSMISSION_MODE_AUTO:
1356 ch.nfft = 1;
1357 break;
1358 }
1359 switch (state->fe[0]->dtv_property_cache.guard_interval) {
1360 case GUARD_INTERVAL_1_32:
1361 ch.guard = 0;
1362 break;
1363 case GUARD_INTERVAL_1_16:
1364 ch.guard = 1;
1365 break;
1366 case GUARD_INTERVAL_1_8:
1367 ch.guard = 2;
1368 break;
1369 case GUARD_INTERVAL_1_4:
1370 ch.guard = 3;
1371 break;
1372 default:
1373 case GUARD_INTERVAL_AUTO:
1374 ch.guard = -1;
1375 break;
1376 }
1377 switch (state->fe[0]->dtv_property_cache.modulation) {
1378 case QAM_64:
1379 ch.constellation = 2;
1380 break;
1381 case QAM_16:
1382 ch.constellation = 1;
1383 break;
1384 case QPSK:
1385 ch.constellation = 0;
1386 break;
1387 default:
1388 case QAM_AUTO:
1389 ch.constellation = -1;
1390 break;
1391 }
1392 switch (state->fe[0]->dtv_property_cache.hierarchy) {
1393 case HIERARCHY_NONE:
1394 ch.hrch = 0;
1395 break;
1396 case HIERARCHY_1:
1397 case HIERARCHY_2:
1398 case HIERARCHY_4:
1399 ch.hrch = 1;
1400 break;
1401 default:
1402 case HIERARCHY_AUTO:
1403 ch.hrch = -1;
1404 break;
1405 }
1406 ch.alpha = 1;
1407 switch (state->fe[0]->dtv_property_cache.code_rate_HP) {
1408 case FEC_1_2:
1409 ch.code_rate_hp = 1;
1410 break;
1411 case FEC_2_3:
1412 ch.code_rate_hp = 2;
1413 break;
1414 case FEC_3_4:
1415 ch.code_rate_hp = 3;
1416 break;
1417 case FEC_5_6:
1418 ch.code_rate_hp = 5;
1419 break;
1420 case FEC_7_8:
1421 ch.code_rate_hp = 7;
1422 break;
1423 default:
1424 case FEC_AUTO:
1425 ch.code_rate_hp = -1;
1426 break;
1427 }
1428 switch (state->fe[0]->dtv_property_cache.code_rate_LP) {
1429 case FEC_1_2:
1430 ch.code_rate_lp = 1;
1431 break;
1432 case FEC_2_3:
1433 ch.code_rate_lp = 2;
1434 break;
1435 case FEC_3_4:
1436 ch.code_rate_lp = 3;
1437 break;
1438 case FEC_5_6:
1439 ch.code_rate_lp = 5;
1440 break;
1441 case FEC_7_8:
1442 ch.code_rate_lp = 7;
1443 break;
1444 default:
1445 case FEC_AUTO:
1446 ch.code_rate_lp = -1;
1447 break;
1448 }
1449 ch.select_hp = 1;
1450 ch.intlv_native = 1;
1451
1452 dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_UNION, (u8 *) &ch);
1453
1454 return 0;
1455}
1456
1457static int dib9000_fw_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
1458{
1459 struct dib9000_state *state = fe->demodulator_priv;
1460 int ret = 10, search = state->channel_status.status == CHANNEL_STATUS_PARAMETERS_UNKNOWN;
1461 s8 i;
1462
1463 switch (state->tune_state) {
1464 case CT_DEMOD_START:
1465 dib9000_fw_set_channel_head(state, ch);
1466
1467 /* write the channel context - a channel is initialized to 0, so it is OK */
1468 dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_CONTEXT, (u8 *) fe_info);
1469 dib9000_risc_mem_write(state, FE_MM_W_FE_INFO, (u8 *) fe_info);
1470
1471 if (search)
1472 dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_SEARCH, NULL, 0);
1473 else {
1474 dib9000_fw_set_channel_union(fe, ch);
1475 dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_TUNE, NULL, 0);
1476 }
1477 state->tune_state = CT_DEMOD_STEP_1;
1478 break;
1479 case CT_DEMOD_STEP_1:
1480 if (search)
1481 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, state->i2c_read_buffer, 1);
1482 else
1483 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, state->i2c_read_buffer, 1);
1484 i = (s8)state->i2c_read_buffer[0];
1485 switch (i) { /* something happened */
1486 case 0:
1487 break;
1488 case -2: /* tps locks are "slower" than MPEG locks -> even in autosearch data is OK here */
1489 if (search)
1490 state->status = FE_STATUS_DEMOD_SUCCESS;
1491 else {
1492 state->tune_state = CT_DEMOD_STOP;
1493 state->status = FE_STATUS_LOCKED;
1494 }
1495 break;
1496 default:
1497 state->status = FE_STATUS_TUNE_FAILED;
1498 state->tune_state = CT_DEMOD_STOP;
1499 break;
1500 }
1501 break;
1502 default:
1503 ret = FE_CALLBACK_TIME_NEVER;
1504 break;
1505 }
1506
1507 return ret;
1508}
1509
1510static int dib9000_fw_set_diversity_in(struct dvb_frontend *fe, int onoff)
1511{
1512 struct dib9000_state *state = fe->demodulator_priv;
1513 u16 mode = (u16) onoff;
1514 return dib9000_mbx_send(state, OUT_MSG_ENABLE_DIVERSITY, &mode, 1);
1515}
1516
1517static int dib9000_fw_set_output_mode(struct dvb_frontend *fe, int mode)
1518{
1519 struct dib9000_state *state = fe->demodulator_priv;
1520 u16 outreg, smo_mode;
1521
1522 dprintk("setting output mode for demod %p to %d", fe, mode);
1523
1524 switch (mode) {
1525 case OUTMODE_MPEG2_PAR_GATED_CLK:
1526 outreg = (1 << 10); /* 0x0400 */
1527 break;
1528 case OUTMODE_MPEG2_PAR_CONT_CLK:
1529 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
1530 break;
1531 case OUTMODE_MPEG2_SERIAL:
1532 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
1533 break;
1534 case OUTMODE_DIVERSITY:
1535 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
1536 break;
1537 case OUTMODE_MPEG2_FIFO:
1538 outreg = (1 << 10) | (5 << 6);
1539 break;
1540 case OUTMODE_HIGH_Z:
1541 outreg = 0;
1542 break;
1543 default:
1544 dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe[0]);
1545 return -EINVAL;
1546 }
1547
1548 dib9000_write_word(state, 1795, outreg);
1549
1550 switch (mode) {
1551 case OUTMODE_MPEG2_PAR_GATED_CLK:
1552 case OUTMODE_MPEG2_PAR_CONT_CLK:
1553 case OUTMODE_MPEG2_SERIAL:
1554 case OUTMODE_MPEG2_FIFO:
1555 smo_mode = (dib9000_read_word(state, 295) & 0x0010) | (1 << 1);
1556 if (state->chip.d9.cfg.output_mpeg2_in_188_bytes)
1557 smo_mode |= (1 << 5);
1558 dib9000_write_word(state, 295, smo_mode);
1559 break;
1560 }
1561
1562 outreg = to_fw_output_mode(mode);
1563 return dib9000_mbx_send(state, OUT_MSG_SET_OUTPUT_MODE, &outreg, 1);
1564}
1565
1566static int dib9000_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1567{
1568 struct dib9000_state *state = i2c_get_adapdata(i2c_adap);
1569 u16 i, len, t, index_msg;
1570
1571 for (index_msg = 0; index_msg < num; index_msg++) {
1572 if (msg[index_msg].flags & I2C_M_RD) { /* read */
1573 len = msg[index_msg].len;
1574 if (len > 16)
1575 len = 16;
1576
1577 if (dib9000_read_word(state, 790) != 0)
1578 dprintk("TunerITF: read busy");
1579
1580 dib9000_write_word(state, 784, (u16) (msg[index_msg].addr));
1581 dib9000_write_word(state, 787, (len / 2) - 1);
1582 dib9000_write_word(state, 786, 1); /* start read */
1583
1584 i = 1000;
1585 while (dib9000_read_word(state, 790) != (len / 2) && i)
1586 i--;
1587
1588 if (i == 0)
1589 dprintk("TunerITF: read failed");
1590
1591 for (i = 0; i < len; i += 2) {
1592 t = dib9000_read_word(state, 785);
1593 msg[index_msg].buf[i] = (t >> 8) & 0xff;
1594 msg[index_msg].buf[i + 1] = (t) & 0xff;
1595 }
1596 if (dib9000_read_word(state, 790) != 0)
1597 dprintk("TunerITF: read more data than expected");
1598 } else {
1599 i = 1000;
1600 while (dib9000_read_word(state, 789) && i)
1601 i--;
1602 if (i == 0)
1603 dprintk("TunerITF: write busy");
1604
1605 len = msg[index_msg].len;
1606 if (len > 16)
1607 len = 16;
1608
1609 for (i = 0; i < len; i += 2)
1610 dib9000_write_word(state, 785, (msg[index_msg].buf[i] << 8) | msg[index_msg].buf[i + 1]);
1611 dib9000_write_word(state, 784, (u16) msg[index_msg].addr);
1612 dib9000_write_word(state, 787, (len / 2) - 1);
1613 dib9000_write_word(state, 786, 0); /* start write */
1614
1615 i = 1000;
1616 while (dib9000_read_word(state, 791) > 0 && i)
1617 i--;
1618 if (i == 0)
1619 dprintk("TunerITF: write failed");
1620 }
1621 }
1622 return num;
1623}
1624
1625int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed)
1626{
1627 struct dib9000_state *state = fe->demodulator_priv;
1628
1629 state->component_bus_speed = speed;
1630 return 0;
1631}
1632EXPORT_SYMBOL(dib9000_fw_set_component_bus_speed);
1633
1634static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1635{
1636 struct dib9000_state *state = i2c_get_adapdata(i2c_adap);
1637 u8 type = 0; /* I2C */
1638 u8 port = DIBX000_I2C_INTERFACE_GPIO_3_4;
1639 u16 scl = state->component_bus_speed; /* SCL frequency */
1640 struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[FE_MM_RW_COMPONENT_ACCESS_BUFFER];
1641 u8 p[13] = { 0 };
1642
1643 p[0] = type;
1644 p[1] = port;
1645 p[2] = msg[0].addr << 1;
1646
1647 p[3] = (u8) scl & 0xff; /* scl */
1648 p[4] = (u8) (scl >> 8);
1649
1650 p[7] = 0;
1651 p[8] = 0;
1652
1653 p[9] = (u8) (msg[0].len);
1654 p[10] = (u8) (msg[0].len >> 8);
1655 if ((num > 1) && (msg[1].flags & I2C_M_RD)) {
1656 p[11] = (u8) (msg[1].len);
1657 p[12] = (u8) (msg[1].len >> 8);
1658 } else {
1659 p[11] = 0;
1660 p[12] = 0;
1661 }
1662
1663 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
1664
1665 dib9000_risc_mem_write(state, FE_MM_W_COMPONENT_ACCESS, p);
1666
1667 { /* write-part */
1668 dib9000_risc_mem_setup_cmd(state, m->addr, msg[0].len, 0);
1669 dib9000_risc_mem_write_chunks(state, msg[0].buf, msg[0].len);
1670 }
1671
1672 /* do the transaction */
1673 if (dib9000_fw_memmbx_sync(state, FE_SYNC_COMPONENT_ACCESS) < 0) {
1674 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
1675 return 0;
1676 }
1677
1678 /* read back any possible result */
1679 if ((num > 1) && (msg[1].flags & I2C_M_RD))
1680 dib9000_risc_mem_read(state, FE_MM_RW_COMPONENT_ACCESS_BUFFER, msg[1].buf, msg[1].len);
1681
1682 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
1683
1684 return num;
1685}
1686
1687static u32 dib9000_i2c_func(struct i2c_adapter *adapter)
1688{
1689 return I2C_FUNC_I2C;
1690}
1691
1692static struct i2c_algorithm dib9000_tuner_algo = {
1693 .master_xfer = dib9000_tuner_xfer,
1694 .functionality = dib9000_i2c_func,
1695};
1696
1697static struct i2c_algorithm dib9000_component_bus_algo = {
1698 .master_xfer = dib9000_fw_component_bus_xfer,
1699 .functionality = dib9000_i2c_func,
1700};
1701
1702struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe)
1703{
1704 struct dib9000_state *st = fe->demodulator_priv;
1705 return &st->tuner_adap;
1706}
1707EXPORT_SYMBOL(dib9000_get_tuner_interface);
1708
1709struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe)
1710{
1711 struct dib9000_state *st = fe->demodulator_priv;
1712 return &st->component_bus;
1713}
1714EXPORT_SYMBOL(dib9000_get_component_bus_interface);
1715
1716struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
1717{
1718 struct dib9000_state *st = fe->demodulator_priv;
1719 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1720}
1721EXPORT_SYMBOL(dib9000_get_i2c_master);
1722
1723int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c)
1724{
1725 struct dib9000_state *st = fe->demodulator_priv;
1726
1727 st->i2c.i2c_adap = i2c;
1728 return 0;
1729}
1730EXPORT_SYMBOL(dib9000_set_i2c_adapter);
1731
1732static int dib9000_cfg_gpio(struct dib9000_state *st, u8 num, u8 dir, u8 val)
1733{
1734 st->gpio_dir = dib9000_read_word(st, 773);
1735 st->gpio_dir &= ~(1 << num); /* reset the direction bit */
1736 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
1737 dib9000_write_word(st, 773, st->gpio_dir);
1738
1739 st->gpio_val = dib9000_read_word(st, 774);
1740 st->gpio_val &= ~(1 << num); /* reset the direction bit */
1741 st->gpio_val |= (val & 0x01) << num; /* set the new value */
1742 dib9000_write_word(st, 774, st->gpio_val);
1743
1744 dprintk("gpio dir: %04x: gpio val: %04x", st->gpio_dir, st->gpio_val);
1745
1746 return 0;
1747}
1748
1749int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
1750{
1751 struct dib9000_state *state = fe->demodulator_priv;
1752 return dib9000_cfg_gpio(state, num, dir, val);
1753}
1754EXPORT_SYMBOL(dib9000_set_gpio);
1755
1756int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1757{
1758 struct dib9000_state *state = fe->demodulator_priv;
1759 u16 val;
1760 int ret;
1761
1762 if ((state->pid_ctrl_index != -2) && (state->pid_ctrl_index < 9)) {
1763 /* postpone the pid filtering cmd */
1764 dprintk("pid filter cmd postpone");
1765 state->pid_ctrl_index++;
1766 state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER_CTRL;
1767 state->pid_ctrl[state->pid_ctrl_index].onoff = onoff;
1768 return 0;
1769 }
1770
1771 DibAcquireLock(&state->demod_lock);
1772
1773 val = dib9000_read_word(state, 294 + 1) & 0xffef;
1774 val |= (onoff & 0x1) << 4;
1775
1776 dprintk("PID filter enabled %d", onoff);
1777 ret = dib9000_write_word(state, 294 + 1, val);
1778 DibReleaseLock(&state->demod_lock);
1779 return ret;
1780
1781}
1782EXPORT_SYMBOL(dib9000_fw_pid_filter_ctrl);
1783
1784int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1785{
1786 struct dib9000_state *state = fe->demodulator_priv;
1787 int ret;
1788
1789 if (state->pid_ctrl_index != -2) {
1790 /* postpone the pid filtering cmd */
1791 dprintk("pid filter postpone");
1792 if (state->pid_ctrl_index < 9) {
1793 state->pid_ctrl_index++;
1794 state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER;
1795 state->pid_ctrl[state->pid_ctrl_index].id = id;
1796 state->pid_ctrl[state->pid_ctrl_index].pid = pid;
1797 state->pid_ctrl[state->pid_ctrl_index].onoff = onoff;
1798 } else
1799 dprintk("can not add any more pid ctrl cmd");
1800 return 0;
1801 }
1802
1803 DibAcquireLock(&state->demod_lock);
1804 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
1805 ret = dib9000_write_word(state, 300 + 1 + id,
1806 onoff ? (1 << 13) | pid : 0);
1807 DibReleaseLock(&state->demod_lock);
1808 return ret;
1809}
1810EXPORT_SYMBOL(dib9000_fw_pid_filter);
1811
1812int dib9000_firmware_post_pll_init(struct dvb_frontend *fe)
1813{
1814 struct dib9000_state *state = fe->demodulator_priv;
1815 return dib9000_fw_init(state);
1816}
1817EXPORT_SYMBOL(dib9000_firmware_post_pll_init);
1818
1819static void dib9000_release(struct dvb_frontend *demod)
1820{
1821 struct dib9000_state *st = demod->demodulator_priv;
1822 u8 index_frontend;
1823
1824 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
1825 dvb_frontend_detach(st->fe[index_frontend]);
1826
1827 DibFreeLock(&state->platform.risc.mbx_if_lock);
1828 DibFreeLock(&state->platform.risc.mbx_lock);
1829 DibFreeLock(&state->platform.risc.mem_lock);
1830 DibFreeLock(&state->platform.risc.mem_mbx_lock);
1831 DibFreeLock(&state->demod_lock);
1832 dibx000_exit_i2c_master(&st->i2c_master);
1833
1834 i2c_del_adapter(&st->tuner_adap);
1835 i2c_del_adapter(&st->component_bus);
1836 kfree(st->fe[0]);
1837 kfree(st);
1838}
1839
1840static int dib9000_wakeup(struct dvb_frontend *fe)
1841{
1842 return 0;
1843}
1844
1845static int dib9000_sleep(struct dvb_frontend *fe)
1846{
1847 struct dib9000_state *state = fe->demodulator_priv;
1848 u8 index_frontend;
1849 int ret = 0;
1850
1851 DibAcquireLock(&state->demod_lock);
1852 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1853 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
1854 if (ret < 0)
1855 goto error;
1856 }
1857 ret = dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0);
1858
1859error:
1860 DibReleaseLock(&state->demod_lock);
1861 return ret;
1862}
1863
1864static int dib9000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1865{
1866 tune->min_delay_ms = 1000;
1867 return 0;
1868}
1869
1870static int dib9000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1871{
1872 struct dib9000_state *state = fe->demodulator_priv;
1873 u8 index_frontend, sub_index_frontend;
1874 fe_status_t stat;
1875 int ret = 0;
1876
1877 if (state->get_frontend_internal == 0)
1878 DibAcquireLock(&state->demod_lock);
1879
1880 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1881 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
1882 if (stat & FE_HAS_SYNC) {
1883 dprintk("TPS lock on the slave%i", index_frontend);
1884
1885 /* synchronize the cache with the other frontends */
1886 state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep);
1887 for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL);
1888 sub_index_frontend++) {
1889 if (sub_index_frontend != index_frontend) {
1890 state->fe[sub_index_frontend]->dtv_property_cache.modulation =
1891 state->fe[index_frontend]->dtv_property_cache.modulation;
1892 state->fe[sub_index_frontend]->dtv_property_cache.inversion =
1893 state->fe[index_frontend]->dtv_property_cache.inversion;
1894 state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode =
1895 state->fe[index_frontend]->dtv_property_cache.transmission_mode;
1896 state->fe[sub_index_frontend]->dtv_property_cache.guard_interval =
1897 state->fe[index_frontend]->dtv_property_cache.guard_interval;
1898 state->fe[sub_index_frontend]->dtv_property_cache.hierarchy =
1899 state->fe[index_frontend]->dtv_property_cache.hierarchy;
1900 state->fe[sub_index_frontend]->dtv_property_cache.code_rate_HP =
1901 state->fe[index_frontend]->dtv_property_cache.code_rate_HP;
1902 state->fe[sub_index_frontend]->dtv_property_cache.code_rate_LP =
1903 state->fe[index_frontend]->dtv_property_cache.code_rate_LP;
1904 state->fe[sub_index_frontend]->dtv_property_cache.rolloff =
1905 state->fe[index_frontend]->dtv_property_cache.rolloff;
1906 }
1907 }
1908 ret = 0;
1909 goto return_value;
1910 }
1911 }
1912
1913 /* get the channel from master chip */
1914 ret = dib9000_fw_get_channel(fe, fep);
1915 if (ret != 0)
1916 goto return_value;
1917
1918 /* synchronize the cache with the other frontends */
1919 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1920 state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
1921 state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
1922 state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
1923 state->fe[index_frontend]->dtv_property_cache.modulation = fe->dtv_property_cache.modulation;
1924 state->fe[index_frontend]->dtv_property_cache.hierarchy = fe->dtv_property_cache.hierarchy;
1925 state->fe[index_frontend]->dtv_property_cache.code_rate_HP = fe->dtv_property_cache.code_rate_HP;
1926 state->fe[index_frontend]->dtv_property_cache.code_rate_LP = fe->dtv_property_cache.code_rate_LP;
1927 state->fe[index_frontend]->dtv_property_cache.rolloff = fe->dtv_property_cache.rolloff;
1928 }
1929 ret = 0;
1930
1931return_value:
1932 if (state->get_frontend_internal == 0)
1933 DibReleaseLock(&state->demod_lock);
1934 return ret;
1935}
1936
1937static int dib9000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
1938{
1939 struct dib9000_state *state = fe->demodulator_priv;
1940 state->tune_state = tune_state;
1941 if (tune_state == CT_DEMOD_START)
1942 state->status = FE_STATUS_TUNE_PENDING;
1943
1944 return 0;
1945}
1946
1947static u32 dib9000_get_status(struct dvb_frontend *fe)
1948{
1949 struct dib9000_state *state = fe->demodulator_priv;
1950 return state->status;
1951}
1952
1953static int dib9000_set_channel_status(struct dvb_frontend *fe, struct dvb_frontend_parametersContext *channel_status)
1954{
1955 struct dib9000_state *state = fe->demodulator_priv;
1956
1957 memcpy(&state->channel_status, channel_status, sizeof(struct dvb_frontend_parametersContext));
1958 return 0;
1959}
1960
1961static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1962{
1963 struct dib9000_state *state = fe->demodulator_priv;
1964 int sleep_time, sleep_time_slave;
1965 u32 frontend_status;
1966 u8 nbr_pending, exit_condition, index_frontend, index_frontend_success;
1967 struct dvb_frontend_parametersContext channel_status;
1968
1969 /* check that the correct parameters are set */
1970 if (state->fe[0]->dtv_property_cache.frequency == 0) {
1971 dprintk("dib9000: must specify frequency ");
1972 return 0;
1973 }
1974
1975 if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
1976 dprintk("dib9000: must specify bandwidth ");
1977 return 0;
1978 }
1979
1980 state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */
1981 DibAcquireLock(&state->demod_lock);
1982
1983 fe->dtv_property_cache.delivery_system = SYS_DVBT;
1984
1985 /* set the master status */
1986 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1987 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1988 /* no channel specified, autosearch the channel */
1989 state->channel_status.status = CHANNEL_STATUS_PARAMETERS_UNKNOWN;
1990 } else
1991 state->channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
1992
1993 /* set mode and status for the different frontends */
1994 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1995 dib9000_fw_set_diversity_in(state->fe[index_frontend], 1);
1996
1997 /* synchronization of the cache */
1998 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
1999
2000 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_DVBT;
2001 dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);
2002
2003 dib9000_set_channel_status(state->fe[index_frontend], &state->channel_status);
2004 dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
2005 }
2006
2007 /* actual tune */
2008 exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
2009 index_frontend_success = 0;
2010 do {
2011 sleep_time = dib9000_fw_tune(state->fe[0], NULL);
2012 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2013 sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend], NULL);
2014 if (sleep_time == FE_CALLBACK_TIME_NEVER)
2015 sleep_time = sleep_time_slave;
2016 else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))
2017 sleep_time = sleep_time_slave;
2018 }
2019 if (sleep_time != FE_CALLBACK_TIME_NEVER)
2020 msleep(sleep_time / 10);
2021 else
2022 break;
2023
2024 nbr_pending = 0;
2025 exit_condition = 0;
2026 index_frontend_success = 0;
2027 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2028 frontend_status = -dib9000_get_status(state->fe[index_frontend]);
2029 if (frontend_status > -FE_STATUS_TUNE_PENDING) {
2030 exit_condition = 2; /* tune success */
2031 index_frontend_success = index_frontend;
2032 break;
2033 }
2034 if (frontend_status == -FE_STATUS_TUNE_PENDING)
2035 nbr_pending++; /* some frontends are still tuning */
2036 }
2037 if ((exit_condition != 2) && (nbr_pending == 0))
2038 exit_condition = 1; /* if all tune are done and no success, exit: tune failed */
2039
2040 } while (exit_condition == 0);
2041
2042 /* check the tune result */
2043 if (exit_condition == 1) { /* tune failed */
2044 dprintk("tune failed");
2045 DibReleaseLock(&state->demod_lock);
2046 /* tune failed; put all the pid filtering cmd to junk */
2047 state->pid_ctrl_index = -1;
2048 return 0;
2049 }
2050
2051 dprintk("tune success on frontend%i", index_frontend_success);
2052
2053 /* synchronize all the channel cache */
2054 state->get_frontend_internal = 1;
2055 dib9000_get_frontend(state->fe[0], fep);
2056 state->get_frontend_internal = 0;
2057
2058 /* retune the other frontends with the found channel */
2059 channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
2060 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2061 /* only retune the frontends which was not tuned success */
2062 if (index_frontend != index_frontend_success) {
2063 dib9000_set_channel_status(state->fe[index_frontend], &channel_status);
2064 dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
2065 }
2066 }
2067 do {
2068 sleep_time = FE_CALLBACK_TIME_NEVER;
2069 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2070 if (index_frontend != index_frontend_success) {
2071 sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend], NULL);
2072 if (sleep_time == FE_CALLBACK_TIME_NEVER)
2073 sleep_time = sleep_time_slave;
2074 else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))
2075 sleep_time = sleep_time_slave;
2076 }
2077 }
2078 if (sleep_time != FE_CALLBACK_TIME_NEVER)
2079 msleep(sleep_time / 10);
2080 else
2081 break;
2082
2083 nbr_pending = 0;
2084 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2085 if (index_frontend != index_frontend_success) {
2086 frontend_status = -dib9000_get_status(state->fe[index_frontend]);
2087 if ((index_frontend != index_frontend_success) && (frontend_status == -FE_STATUS_TUNE_PENDING))
2088 nbr_pending++; /* some frontends are still tuning */
2089 }
2090 }
2091 } while (nbr_pending != 0);
2092
2093 /* set the output mode */
2094 dib9000_fw_set_output_mode(state->fe[0], state->chip.d9.cfg.output_mode);
2095 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2096 dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);
2097
2098 /* turn off the diversity for the last frontend */
2099 dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0);
2100
2101 DibReleaseLock(&state->demod_lock);
2102 if (state->pid_ctrl_index >= 0) {
2103 u8 index_pid_filter_cmd;
2104 u8 pid_ctrl_index = state->pid_ctrl_index;
2105
2106 state->pid_ctrl_index = -2;
2107 for (index_pid_filter_cmd = 0;
2108 index_pid_filter_cmd <= pid_ctrl_index;
2109 index_pid_filter_cmd++) {
2110 if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER_CTRL)
2111 dib9000_fw_pid_filter_ctrl(state->fe[0],
2112 state->pid_ctrl[index_pid_filter_cmd].onoff);
2113 else if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER)
2114 dib9000_fw_pid_filter(state->fe[0],
2115 state->pid_ctrl[index_pid_filter_cmd].id,
2116 state->pid_ctrl[index_pid_filter_cmd].pid,
2117 state->pid_ctrl[index_pid_filter_cmd].onoff);
2118 }
2119 }
2120 /* do not postpone any more the pid filtering */
2121 state->pid_ctrl_index = -2;
2122
2123 return 0;
2124}
2125
2126static u16 dib9000_read_lock(struct dvb_frontend *fe)
2127{
2128 struct dib9000_state *state = fe->demodulator_priv;
2129
2130 return dib9000_read_word(state, 535);
2131}
2132
2133static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2134{
2135 struct dib9000_state *state = fe->demodulator_priv;
2136 u8 index_frontend;
2137 u16 lock = 0, lock_slave = 0;
2138
2139 DibAcquireLock(&state->demod_lock);
2140 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2141 lock_slave |= dib9000_read_lock(state->fe[index_frontend]);
2142
2143 lock = dib9000_read_word(state, 535);
2144
2145 *stat = 0;
2146
2147 if ((lock & 0x8000) || (lock_slave & 0x8000))
2148 *stat |= FE_HAS_SIGNAL;
2149 if ((lock & 0x3000) || (lock_slave & 0x3000))
2150 *stat |= FE_HAS_CARRIER;
2151 if ((lock & 0x0100) || (lock_slave & 0x0100))
2152 *stat |= FE_HAS_VITERBI;
2153 if (((lock & 0x0038) == 0x38) || ((lock_slave & 0x0038) == 0x38))
2154 *stat |= FE_HAS_SYNC;
2155 if ((lock & 0x0008) || (lock_slave & 0x0008))
2156 *stat |= FE_HAS_LOCK;
2157
2158 DibReleaseLock(&state->demod_lock);
2159
2160 return 0;
2161}
2162
2163static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
2164{
2165 struct dib9000_state *state = fe->demodulator_priv;
2166 u16 *c;
2167 int ret = 0;
2168
2169 DibAcquireLock(&state->demod_lock);
2170 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2171 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2172 ret = -EIO;
2173 goto error;
2174 }
2175 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR,
2176 state->i2c_read_buffer, 16 * 2);
2177 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2178
2179 c = (u16 *)state->i2c_read_buffer;
2180
2181 *ber = c[10] << 16 | c[11];
2182
2183error:
2184 DibReleaseLock(&state->demod_lock);
2185 return ret;
2186}
2187
2188static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2189{
2190 struct dib9000_state *state = fe->demodulator_priv;
2191 u8 index_frontend;
2192 u16 *c = (u16 *)state->i2c_read_buffer;
2193 u16 val;
2194 int ret = 0;
2195
2196 DibAcquireLock(&state->demod_lock);
2197 *strength = 0;
2198 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2199 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
2200 if (val > 65535 - *strength)
2201 *strength = 65535;
2202 else
2203 *strength += val;
2204 }
2205
2206 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2207 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2208 ret = -EIO;
2209 goto error;
2210 }
2211 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
2212 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2213
2214 val = 65535 - c[4];
2215 if (val > 65535 - *strength)
2216 *strength = 65535;
2217 else
2218 *strength += val;
2219
2220error:
2221 DibReleaseLock(&state->demod_lock);
2222 return ret;
2223}
2224
2225static u32 dib9000_get_snr(struct dvb_frontend *fe)
2226{
2227 struct dib9000_state *state = fe->demodulator_priv;
2228 u16 *c = (u16 *)state->i2c_read_buffer;
2229 u32 n, s, exp;
2230 u16 val;
2231
2232 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2233 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
2234 return -EIO;
2235 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
2236 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2237
2238 val = c[7];
2239 n = (val >> 4) & 0xff;
2240 exp = ((val & 0xf) << 2);
2241 val = c[8];
2242 exp += ((val >> 14) & 0x3);
2243 if ((exp & 0x20) != 0)
2244 exp -= 0x40;
2245 n <<= exp + 16;
2246
2247 s = (val >> 6) & 0xFF;
2248 exp = (val & 0x3F);
2249 if ((exp & 0x20) != 0)
2250 exp -= 0x40;
2251 s <<= exp + 16;
2252
2253 if (n > 0) {
2254 u32 t = (s / n) << 16;
2255 return t + ((s << 16) - n * t) / n;
2256 }
2257 return 0xffffffff;
2258}
2259
2260static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
2261{
2262 struct dib9000_state *state = fe->demodulator_priv;
2263 u8 index_frontend;
2264 u32 snr_master;
2265
2266 DibAcquireLock(&state->demod_lock);
2267 snr_master = dib9000_get_snr(fe);
2268 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2269 snr_master += dib9000_get_snr(state->fe[index_frontend]);
2270
2271 if ((snr_master >> 16) != 0) {
2272 snr_master = 10 * intlog10(snr_master >> 16);
2273 *snr = snr_master / ((1 << 24) / 10);
2274 } else
2275 *snr = 0;
2276
2277 DibReleaseLock(&state->demod_lock);
2278
2279 return 0;
2280}
2281
2282static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2283{
2284 struct dib9000_state *state = fe->demodulator_priv;
2285 u16 *c = (u16 *)state->i2c_read_buffer;
2286 int ret = 0;
2287
2288 DibAcquireLock(&state->demod_lock);
2289 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2290 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
2291 ret = -EIO;
2292 goto error;
2293 }
2294 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
2295 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2296
2297 *unc = c[12];
2298
2299error:
2300 DibReleaseLock(&state->demod_lock);
2301 return ret;
2302}
2303
2304int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr)
2305{
2306 int k = 0, ret = 0;
2307 u8 new_addr = 0;
2308 struct i2c_device client = {.i2c_adap = i2c };
2309
2310 client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
2311 if (!client.i2c_write_buffer) {
2312 dprintk("%s: not enough memory", __func__);
2313 return -ENOMEM;
2314 }
2315 client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
2316 if (!client.i2c_read_buffer) {
2317 dprintk("%s: not enough memory", __func__);
2318 ret = -ENOMEM;
2319 goto error_memory;
2320 }
2321
2322 client.i2c_addr = default_addr + 16;
2323 dib9000_i2c_write16(&client, 1796, 0x0);
2324
2325 for (k = no_of_demods - 1; k >= 0; k--) {
2326 /* designated i2c address */
2327 new_addr = first_addr + (k << 1);
2328 client.i2c_addr = default_addr;
2329
2330 dib9000_i2c_write16(&client, 1817, 3);
2331 dib9000_i2c_write16(&client, 1796, 0);
2332 dib9000_i2c_write16(&client, 1227, 1);
2333 dib9000_i2c_write16(&client, 1227, 0);
2334
2335 client.i2c_addr = new_addr;
2336 dib9000_i2c_write16(&client, 1817, 3);
2337 dib9000_i2c_write16(&client, 1796, 0);
2338 dib9000_i2c_write16(&client, 1227, 1);
2339 dib9000_i2c_write16(&client, 1227, 0);
2340
2341 if (dib9000_identify(&client) == 0) {
2342 client.i2c_addr = default_addr;
2343 if (dib9000_identify(&client) == 0) {
2344 dprintk("DiB9000 #%d: not identified", k);
2345 ret = -EIO;
2346 goto error;
2347 }
2348 }
2349
2350 dib9000_i2c_write16(&client, 1795, (1 << 10) | (4 << 6));
2351 dib9000_i2c_write16(&client, 1794, (new_addr << 2) | 2);
2352
2353 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
2354 }
2355
2356 for (k = 0; k < no_of_demods; k++) {
2357 new_addr = first_addr | (k << 1);
2358 client.i2c_addr = new_addr;
2359
2360 dib9000_i2c_write16(&client, 1794, (new_addr << 2));
2361 dib9000_i2c_write16(&client, 1795, 0);
2362 }
2363
2364error:
2365 kfree(client.i2c_read_buffer);
2366error_memory:
2367 kfree(client.i2c_write_buffer);
2368
2369 return ret;
2370}
2371EXPORT_SYMBOL(dib9000_i2c_enumeration);
2372
2373int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
2374{
2375 struct dib9000_state *state = fe->demodulator_priv;
2376 u8 index_frontend = 1;
2377
2378 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2379 index_frontend++;
2380 if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
2381 dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
2382 state->fe[index_frontend] = fe_slave;
2383 return 0;
2384 }
2385
2386 dprintk("too many slave frontend");
2387 return -ENOMEM;
2388}
2389EXPORT_SYMBOL(dib9000_set_slave_frontend);
2390
2391int dib9000_remove_slave_frontend(struct dvb_frontend *fe)
2392{
2393 struct dib9000_state *state = fe->demodulator_priv;
2394 u8 index_frontend = 1;
2395
2396 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2397 index_frontend++;
2398 if (index_frontend != 1) {
2399 dprintk("remove slave fe %p (index %i)", state->fe[index_frontend - 1], index_frontend - 1);
2400 state->fe[index_frontend] = NULL;
2401 return 0;
2402 }
2403
2404 dprintk("no frontend to be removed");
2405 return -ENODEV;
2406}
2407EXPORT_SYMBOL(dib9000_remove_slave_frontend);
2408
2409struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
2410{
2411 struct dib9000_state *state = fe->demodulator_priv;
2412
2413 if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
2414 return NULL;
2415 return state->fe[slave_index];
2416}
2417EXPORT_SYMBOL(dib9000_get_slave_frontend);
2418
2419static struct dvb_frontend_ops dib9000_ops;
2420struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg)
2421{
2422 struct dvb_frontend *fe;
2423 struct dib9000_state *st;
2424 st = kzalloc(sizeof(struct dib9000_state), GFP_KERNEL);
2425 if (st == NULL)
2426 return NULL;
2427 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
2428 if (fe == NULL) {
2429 kfree(st);
2430 return NULL;
2431 }
2432
2433 memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config));
2434 st->i2c.i2c_adap = i2c_adap;
2435 st->i2c.i2c_addr = i2c_addr;
2436 st->i2c.i2c_write_buffer = st->i2c_write_buffer;
2437 st->i2c.i2c_read_buffer = st->i2c_read_buffer;
2438
2439 st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS;
2440 st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES;
2441 st->gpio_pwm_pos = DIB9000_GPIO_DEFAULT_PWM_POS;
2442
2443 DibInitLock(&st->platform.risc.mbx_if_lock);
2444 DibInitLock(&st->platform.risc.mbx_lock);
2445 DibInitLock(&st->platform.risc.mem_lock);
2446 DibInitLock(&st->platform.risc.mem_mbx_lock);
2447 DibInitLock(&st->demod_lock);
2448 st->get_frontend_internal = 0;
2449
2450 st->pid_ctrl_index = -2;
2451
2452 st->fe[0] = fe;
2453 fe->demodulator_priv = st;
2454 memcpy(&st->fe[0]->ops, &dib9000_ops, sizeof(struct dvb_frontend_ops));
2455
2456 /* Ensure the output mode remains at the previous default if it's
2457 * not specifically set by the caller.
2458 */
2459 if ((st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2460 st->chip.d9.cfg.output_mode = OUTMODE_MPEG2_FIFO;
2461
2462 if (dib9000_identify(&st->i2c) == 0)
2463 goto error;
2464
2465 dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c.i2c_adap, st->i2c.i2c_addr);
2466
2467 st->tuner_adap.dev.parent = i2c_adap->dev.parent;
2468 strncpy(st->tuner_adap.name, "DIB9000_FW TUNER ACCESS", sizeof(st->tuner_adap.name));
2469 st->tuner_adap.algo = &dib9000_tuner_algo;
2470 st->tuner_adap.algo_data = NULL;
2471 i2c_set_adapdata(&st->tuner_adap, st);
2472 if (i2c_add_adapter(&st->tuner_adap) < 0)
2473 goto error;
2474
2475 st->component_bus.dev.parent = i2c_adap->dev.parent;
2476 strncpy(st->component_bus.name, "DIB9000_FW COMPONENT BUS ACCESS", sizeof(st->component_bus.name));
2477 st->component_bus.algo = &dib9000_component_bus_algo;
2478 st->component_bus.algo_data = NULL;
2479 st->component_bus_speed = 340;
2480 i2c_set_adapdata(&st->component_bus, st);
2481 if (i2c_add_adapter(&st->component_bus) < 0)
2482 goto component_bus_add_error;
2483
2484 dib9000_fw_reset(fe);
2485
2486 return fe;
2487
2488component_bus_add_error:
2489 i2c_del_adapter(&st->tuner_adap);
2490error:
2491 kfree(st);
2492 return NULL;
2493}
2494EXPORT_SYMBOL(dib9000_attach);
2495
2496static struct dvb_frontend_ops dib9000_ops = {
2497 .info = {
2498 .name = "DiBcom 9000",
2499 .type = FE_OFDM,
2500 .frequency_min = 44250000,
2501 .frequency_max = 867250000,
2502 .frequency_stepsize = 62500,
2503 .caps = FE_CAN_INVERSION_AUTO |
2504 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2505 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2506 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2507 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2508 },
2509
2510 .release = dib9000_release,
2511
2512 .init = dib9000_wakeup,
2513 .sleep = dib9000_sleep,
2514
2515 .set_frontend = dib9000_set_frontend,
2516 .get_tune_settings = dib9000_fe_get_tune_settings,
2517 .get_frontend = dib9000_get_frontend,
2518
2519 .read_status = dib9000_read_status,
2520 .read_ber = dib9000_read_ber,
2521 .read_signal_strength = dib9000_read_signal_strength,
2522 .read_snr = dib9000_read_snr,
2523 .read_ucblocks = dib9000_read_unc_blocks,
2524};
2525
2526MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
2527MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
2528MODULE_DESCRIPTION("Driver for the DiBcom 9000 COFDM demodulator");
2529MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib9000.h b/drivers/media/dvb/frontends/dib9000.h
new file mode 100644
index 00000000000..b5781a48034
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib9000.h
@@ -0,0 +1,131 @@
1#ifndef DIB9000_H
2#define DIB9000_H
3
4#include "dibx000_common.h"
5
6struct dib9000_config {
7 u8 dvbt_mode;
8 u8 output_mpeg2_in_188_bytes;
9 u8 hostbus_diversity;
10 struct dibx000_bandwidth_config *bw;
11
12 u16 if_drives;
13
14 u32 timing_frequency;
15 u32 xtal_clock_khz;
16 u32 vcxo_timer;
17 u32 demod_clock_khz;
18
19 const u8 *microcode_B_fe_buffer;
20 u32 microcode_B_fe_size;
21
22 struct dibGPIOFunction gpio_function[2];
23 struct dibSubbandSelection subband;
24
25 u8 output_mode;
26};
27
28#define DEFAULT_DIB9000_I2C_ADDRESS 18
29
30#if defined(CONFIG_DVB_DIB9000) || (defined(CONFIG_DVB_DIB9000_MODULE) && defined(MODULE))
31extern struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg);
32extern int dib9000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr);
33extern struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe);
34extern struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating);
35extern int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val);
36extern int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
37extern int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff);
38extern int dib9000_firmware_post_pll_init(struct dvb_frontend *fe);
39extern int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
40extern int dib9000_remove_slave_frontend(struct dvb_frontend *fe);
41extern struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
42extern struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe);
43extern int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c);
44extern int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed);
45#else
46static inline struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib9000_config *cfg)
47{
48 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
49 return NULL;
50}
51
52static inline struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
53{
54 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
55 return NULL;
56}
57
58static inline int dib9000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
59{
60 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
61 return -ENODEV;
62}
63
64static inline struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe)
65{
66 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
67 return NULL;
68}
69
70static inline int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
71{
72 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
73 return -ENODEV;
74}
75
76static inline int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
77{
78 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
79 return -ENODEV;
80}
81
82static inline int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
83{
84 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
85 return -ENODEV;
86}
87
88static inline int dib9000_firmware_post_pll_init(struct dvb_frontend *fe)
89{
90 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
91 return -ENODEV;
92}
93
94static inline int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
95{
96 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
97 return -ENODEV;
98}
99
100int dib9000_remove_slave_frontend(struct dvb_frontend *fe)
101{
102 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
103 return -ENODEV;
104}
105
106static inline struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
107{
108 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
109 return NULL;
110}
111
112static inline struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe)
113{
114 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
115 return NULL;
116}
117
118static inline int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c)
119{
120 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
121 return -ENODEV;
122}
123
124static inline int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed)
125{
126 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
127 return -ENODEV;
128}
129#endif
130
131#endif
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
new file mode 100644
index 00000000000..774d507b66c
--- /dev/null
+++ b/drivers/media/dvb/frontends/dibx000_common.c
@@ -0,0 +1,514 @@
1#include <linux/i2c.h>
2#include <linux/mutex.h>
3
4#include "dibx000_common.h"
5
6static int debug;
7module_param(debug, int, 0644);
8MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
9
10#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); printk("\n"); } } while (0)
11
12static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
13{
14 int ret;
15
16 if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
17 dprintk("could not acquire lock");
18 return -EINVAL;
19 }
20
21 mst->i2c_write_buffer[0] = (reg >> 8) & 0xff;
22 mst->i2c_write_buffer[1] = reg & 0xff;
23 mst->i2c_write_buffer[2] = (val >> 8) & 0xff;
24 mst->i2c_write_buffer[3] = val & 0xff;
25
26 memset(mst->msg, 0, sizeof(struct i2c_msg));
27 mst->msg[0].addr = mst->i2c_addr;
28 mst->msg[0].flags = 0;
29 mst->msg[0].buf = mst->i2c_write_buffer;
30 mst->msg[0].len = 4;
31
32 ret = i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0;
33 mutex_unlock(&mst->i2c_buffer_lock);
34
35 return ret;
36}
37
38static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
39{
40 u16 ret;
41
42 if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
43 dprintk("could not acquire lock");
44 return 0;
45 }
46
47 mst->i2c_write_buffer[0] = reg >> 8;
48 mst->i2c_write_buffer[1] = reg & 0xff;
49
50 memset(mst->msg, 0, 2 * sizeof(struct i2c_msg));
51 mst->msg[0].addr = mst->i2c_addr;
52 mst->msg[0].flags = 0;
53 mst->msg[0].buf = mst->i2c_write_buffer;
54 mst->msg[0].len = 2;
55 mst->msg[1].addr = mst->i2c_addr;
56 mst->msg[1].flags = I2C_M_RD;
57 mst->msg[1].buf = mst->i2c_read_buffer;
58 mst->msg[1].len = 2;
59
60 if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2)
61 dprintk("i2c read error on %d", reg);
62
63 ret = (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1];
64 mutex_unlock(&mst->i2c_buffer_lock);
65
66 return ret;
67}
68
69static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
70{
71 int i = 100;
72 u16 status;
73
74 while (((status = dibx000_read_word(mst, mst->base_reg + 2)) & 0x0100) == 0 && --i > 0)
75 ;
76
77 /* i2c timed out */
78 if (i == 0)
79 return -EREMOTEIO;
80
81 /* no acknowledge */
82 if ((status & 0x0080) == 0)
83 return -EREMOTEIO;
84
85 return 0;
86}
87
88static int dibx000_master_i2c_write(struct dibx000_i2c_master *mst, struct i2c_msg *msg, u8 stop)
89{
90 u16 data;
91 u16 da;
92 u16 i;
93 u16 txlen = msg->len, len;
94 const u8 *b = msg->buf;
95
96 while (txlen) {
97 dibx000_read_word(mst, mst->base_reg + 2);
98
99 len = txlen > 8 ? 8 : txlen;
100 for (i = 0; i < len; i += 2) {
101 data = *b++ << 8;
102 if (i+1 < len)
103 data |= *b++;
104 dibx000_write_word(mst, mst->base_reg, data);
105 }
106 da = (((u8) (msg->addr)) << 9) |
107 (1 << 8) |
108 (1 << 7) |
109 (0 << 6) |
110 (0 << 5) |
111 ((len & 0x7) << 2) |
112 (0 << 1) |
113 (0 << 0);
114
115 if (txlen == msg->len)
116 da |= 1 << 5; /* start */
117
118 if (txlen-len == 0 && stop)
119 da |= 1 << 6; /* stop */
120
121 dibx000_write_word(mst, mst->base_reg+1, da);
122
123 if (dibx000_is_i2c_done(mst) != 0)
124 return -EREMOTEIO;
125 txlen -= len;
126 }
127
128 return 0;
129}
130
131static int dibx000_master_i2c_read(struct dibx000_i2c_master *mst, struct i2c_msg *msg)
132{
133 u16 da;
134 u8 *b = msg->buf;
135 u16 rxlen = msg->len, len;
136
137 while (rxlen) {
138 len = rxlen > 8 ? 8 : rxlen;
139 da = (((u8) (msg->addr)) << 9) |
140 (1 << 8) |
141 (1 << 7) |
142 (0 << 6) |
143 (0 << 5) |
144 ((len & 0x7) << 2) |
145 (1 << 1) |
146 (0 << 0);
147
148 if (rxlen == msg->len)
149 da |= 1 << 5; /* start */
150
151 if (rxlen-len == 0)
152 da |= 1 << 6; /* stop */
153 dibx000_write_word(mst, mst->base_reg+1, da);
154
155 if (dibx000_is_i2c_done(mst) != 0)
156 return -EREMOTEIO;
157
158 rxlen -= len;
159
160 while (len) {
161 da = dibx000_read_word(mst, mst->base_reg);
162 *b++ = (da >> 8) & 0xff;
163 len--;
164 if (len >= 1) {
165 *b++ = da & 0xff;
166 len--;
167 }
168 }
169 }
170
171 return 0;
172}
173
174int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed)
175{
176 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
177
178 if (mst->device_rev < DIB7000MC && speed < 235)
179 speed = 235;
180 return dibx000_write_word(mst, mst->base_reg + 3, (u16)(60000 / speed));
181
182}
183EXPORT_SYMBOL(dibx000_i2c_set_speed);
184
185static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
186{
187 return I2C_FUNC_I2C;
188}
189
190static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
191 enum dibx000_i2c_interface intf)
192{
193 if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
194 dprintk("selecting interface: %d", intf);
195 mst->selected_interface = intf;
196 return dibx000_write_word(mst, mst->base_reg + 4, intf);
197 }
198 return 0;
199}
200
201static int dibx000_i2c_master_xfer_gpio12(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
202{
203 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
204 int msg_index;
205 int ret = 0;
206
207 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_1_2);
208 for (msg_index = 0; msg_index < num; msg_index++) {
209 if (msg[msg_index].flags & I2C_M_RD) {
210 ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
211 if (ret != 0)
212 return 0;
213 } else {
214 ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
215 if (ret != 0)
216 return 0;
217 }
218 }
219
220 return num;
221}
222
223static int dibx000_i2c_master_xfer_gpio34(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
224{
225 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
226 int msg_index;
227 int ret = 0;
228
229 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_3_4);
230 for (msg_index = 0; msg_index < num; msg_index++) {
231 if (msg[msg_index].flags & I2C_M_RD) {
232 ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
233 if (ret != 0)
234 return 0;
235 } else {
236 ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
237 if (ret != 0)
238 return 0;
239 }
240 }
241
242 return num;
243}
244
245static struct i2c_algorithm dibx000_i2c_master_gpio12_xfer_algo = {
246 .master_xfer = dibx000_i2c_master_xfer_gpio12,
247 .functionality = dibx000_i2c_func,
248};
249
250static struct i2c_algorithm dibx000_i2c_master_gpio34_xfer_algo = {
251 .master_xfer = dibx000_i2c_master_xfer_gpio34,
252 .functionality = dibx000_i2c_func,
253};
254
255static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
256 u8 addr, int onoff)
257{
258 u16 val;
259
260
261 if (onoff)
262 val = addr << 8; // bit 7 = use master or not, if 0, the gate is open
263 else
264 val = 1 << 7;
265
266 if (mst->device_rev > DIB7000)
267 val <<= 1;
268
269 tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
270 tx[1] = ((mst->base_reg + 1) & 0xff);
271 tx[2] = val >> 8;
272 tx[3] = val & 0xff;
273
274 return 0;
275}
276
277static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
278 struct i2c_msg msg[], int num)
279{
280 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
281 int ret;
282
283 if (num > 32) {
284 dprintk("%s: too much I2C message to be transmitted (%i).\
285 Maximum is 32", __func__, num);
286 return -ENOMEM;
287 }
288
289 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
290
291 if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
292 dprintk("could not acquire lock");
293 return -EINVAL;
294 }
295
296 memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
297
298 /* open the gate */
299 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
300 mst->msg[0].addr = mst->i2c_addr;
301 mst->msg[0].buf = &mst->i2c_write_buffer[0];
302 mst->msg[0].len = 4;
303
304 memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
305
306 /* close the gate */
307 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
308 mst->msg[num + 1].addr = mst->i2c_addr;
309 mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
310 mst->msg[num + 1].len = 4;
311
312 ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ?
313 num : -EIO);
314
315 mutex_unlock(&mst->i2c_buffer_lock);
316 return ret;
317}
318
319static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
320 .master_xfer = dibx000_i2c_gated_gpio67_xfer,
321 .functionality = dibx000_i2c_func,
322};
323
324static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
325 struct i2c_msg msg[], int num)
326{
327 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
328 int ret;
329
330 if (num > 32) {
331 dprintk("%s: too much I2C message to be transmitted (%i).\
332 Maximum is 32", __func__, num);
333 return -ENOMEM;
334 }
335
336 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
337
338 if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
339 dprintk("could not acquire lock");
340 return -EINVAL;
341 }
342 memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
343
344 /* open the gate */
345 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
346 mst->msg[0].addr = mst->i2c_addr;
347 mst->msg[0].buf = &mst->i2c_write_buffer[0];
348 mst->msg[0].len = 4;
349
350 memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
351
352 /* close the gate */
353 dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
354 mst->msg[num + 1].addr = mst->i2c_addr;
355 mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
356 mst->msg[num + 1].len = 4;
357
358 ret = (i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ?
359 num : -EIO);
360 mutex_unlock(&mst->i2c_buffer_lock);
361 return ret;
362}
363
364static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
365 .master_xfer = dibx000_i2c_gated_tuner_xfer,
366 .functionality = dibx000_i2c_func,
367};
368
369struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
370 enum dibx000_i2c_interface intf,
371 int gating)
372{
373 struct i2c_adapter *i2c = NULL;
374
375 switch (intf) {
376 case DIBX000_I2C_INTERFACE_TUNER:
377 if (gating)
378 i2c = &mst->gated_tuner_i2c_adap;
379 break;
380 case DIBX000_I2C_INTERFACE_GPIO_1_2:
381 if (!gating)
382 i2c = &mst->master_i2c_adap_gpio12;
383 break;
384 case DIBX000_I2C_INTERFACE_GPIO_3_4:
385 if (!gating)
386 i2c = &mst->master_i2c_adap_gpio34;
387 break;
388 case DIBX000_I2C_INTERFACE_GPIO_6_7:
389 if (gating)
390 i2c = &mst->master_i2c_adap_gpio67;
391 break;
392 default:
393 printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
394 break;
395 }
396
397 return i2c;
398}
399
400EXPORT_SYMBOL(dibx000_get_i2c_adapter);
401
402void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
403{
404 /* initialize the i2c-master by closing the gate */
405 u8 tx[4];
406 struct i2c_msg m = {.addr = mst->i2c_addr,.buf = tx,.len = 4 };
407
408 dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
409 i2c_transfer(mst->i2c_adap, &m, 1);
410 mst->selected_interface = 0xff; // the first time force a select of the I2C
411 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
412}
413
414EXPORT_SYMBOL(dibx000_reset_i2c_master);
415
416static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
417 struct i2c_algorithm *algo, const char *name,
418 struct dibx000_i2c_master *mst)
419{
420 strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
421 i2c_adap->algo = algo;
422 i2c_adap->algo_data = NULL;
423 i2c_set_adapdata(i2c_adap, mst);
424 if (i2c_add_adapter(i2c_adap) < 0)
425 return -ENODEV;
426 return 0;
427}
428
429int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
430 struct i2c_adapter *i2c_adap, u8 i2c_addr)
431{
432 int ret;
433
434 mutex_init(&mst->i2c_buffer_lock);
435 if (mutex_lock_interruptible(&mst->i2c_buffer_lock) < 0) {
436 dprintk("could not acquire lock");
437 return -EINVAL;
438 }
439 memset(mst->msg, 0, sizeof(struct i2c_msg));
440 mst->msg[0].addr = i2c_addr >> 1;
441 mst->msg[0].flags = 0;
442 mst->msg[0].buf = mst->i2c_write_buffer;
443 mst->msg[0].len = 4;
444
445 mst->device_rev = device_rev;
446 mst->i2c_adap = i2c_adap;
447 mst->i2c_addr = i2c_addr >> 1;
448
449 if (device_rev == DIB7000P || device_rev == DIB8000)
450 mst->base_reg = 1024;
451 else
452 mst->base_reg = 768;
453
454 mst->gated_tuner_i2c_adap.dev.parent = mst->i2c_adap->dev.parent;
455 if (i2c_adapter_init
456 (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
457 "DiBX000 tuner I2C bus", mst) != 0)
458 printk(KERN_ERR
459 "DiBX000: could not initialize the tuner i2c_adapter\n");
460
461 mst->master_i2c_adap_gpio12.dev.parent = mst->i2c_adap->dev.parent;
462 if (i2c_adapter_init
463 (&mst->master_i2c_adap_gpio12, &dibx000_i2c_master_gpio12_xfer_algo,
464 "DiBX000 master GPIO12 I2C bus", mst) != 0)
465 printk(KERN_ERR
466 "DiBX000: could not initialize the master i2c_adapter\n");
467
468 mst->master_i2c_adap_gpio34.dev.parent = mst->i2c_adap->dev.parent;
469 if (i2c_adapter_init
470 (&mst->master_i2c_adap_gpio34, &dibx000_i2c_master_gpio34_xfer_algo,
471 "DiBX000 master GPIO34 I2C bus", mst) != 0)
472 printk(KERN_ERR
473 "DiBX000: could not initialize the master i2c_adapter\n");
474
475 mst->master_i2c_adap_gpio67.dev.parent = mst->i2c_adap->dev.parent;
476 if (i2c_adapter_init
477 (&mst->master_i2c_adap_gpio67, &dibx000_i2c_gated_gpio67_algo,
478 "DiBX000 master GPIO67 I2C bus", mst) != 0)
479 printk(KERN_ERR
480 "DiBX000: could not initialize the master i2c_adapter\n");
481
482 /* initialize the i2c-master by closing the gate */
483 dibx000_i2c_gate_ctrl(mst, mst->i2c_write_buffer, 0, 0);
484
485 ret = (i2c_transfer(i2c_adap, mst->msg, 1) == 1);
486 mutex_unlock(&mst->i2c_buffer_lock);
487
488 return ret;
489}
490
491EXPORT_SYMBOL(dibx000_init_i2c_master);
492
493void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
494{
495 i2c_del_adapter(&mst->gated_tuner_i2c_adap);
496 i2c_del_adapter(&mst->master_i2c_adap_gpio12);
497 i2c_del_adapter(&mst->master_i2c_adap_gpio34);
498 i2c_del_adapter(&mst->master_i2c_adap_gpio67);
499}
500EXPORT_SYMBOL(dibx000_exit_i2c_master);
501
502
503u32 systime(void)
504{
505 struct timespec t;
506
507 t = current_kernel_time();
508 return (t.tv_sec * 10000) + (t.tv_nsec / 100000);
509}
510EXPORT_SYMBOL(systime);
511
512MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
513MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
514MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h
new file mode 100644
index 00000000000..5e011474be4
--- /dev/null
+++ b/drivers/media/dvb/frontends/dibx000_common.h
@@ -0,0 +1,279 @@
1#ifndef DIBX000_COMMON_H
2#define DIBX000_COMMON_H
3
4enum dibx000_i2c_interface {
5 DIBX000_I2C_INTERFACE_TUNER = 0,
6 DIBX000_I2C_INTERFACE_GPIO_1_2 = 1,
7 DIBX000_I2C_INTERFACE_GPIO_3_4 = 2,
8 DIBX000_I2C_INTERFACE_GPIO_6_7 = 3
9};
10
11struct dibx000_i2c_master {
12#define DIB3000MC 1
13#define DIB7000 2
14#define DIB7000P 11
15#define DIB7000MC 12
16#define DIB8000 13
17 u16 device_rev;
18
19 enum dibx000_i2c_interface selected_interface;
20
21/* struct i2c_adapter tuner_i2c_adap; */
22 struct i2c_adapter gated_tuner_i2c_adap;
23 struct i2c_adapter master_i2c_adap_gpio12;
24 struct i2c_adapter master_i2c_adap_gpio34;
25 struct i2c_adapter master_i2c_adap_gpio67;
26
27 struct i2c_adapter *i2c_adap;
28 u8 i2c_addr;
29
30 u16 base_reg;
31
32 /* for the I2C transfer */
33 struct i2c_msg msg[34];
34 u8 i2c_write_buffer[8];
35 u8 i2c_read_buffer[2];
36 struct mutex i2c_buffer_lock;
37};
38
39extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
40 u16 device_rev, struct i2c_adapter *i2c_adap,
41 u8 i2c_addr);
42extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master
43 *mst,
44 enum dibx000_i2c_interface
45 intf, int gating);
46extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
47extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst);
48extern int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed);
49
50extern u32 systime(void);
51
52#define BAND_LBAND 0x01
53#define BAND_UHF 0x02
54#define BAND_VHF 0x04
55#define BAND_SBAND 0x08
56#define BAND_FM 0x10
57#define BAND_CBAND 0x20
58
59#define BAND_OF_FREQUENCY(freq_kHz) ((freq_kHz) <= 170000 ? BAND_CBAND : \
60 (freq_kHz) <= 115000 ? BAND_FM : \
61 (freq_kHz) <= 250000 ? BAND_VHF : \
62 (freq_kHz) <= 863000 ? BAND_UHF : \
63 (freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND )
64
65struct dibx000_agc_config {
66 /* defines the capabilities of this AGC-setting - using the BAND_-defines */
67 u8 band_caps;
68
69 u16 setup;
70
71 u16 inv_gain;
72 u16 time_stabiliz;
73
74 u8 alpha_level;
75 u16 thlock;
76
77 u8 wbd_inv;
78 u16 wbd_ref;
79 u8 wbd_sel;
80 u8 wbd_alpha;
81
82 u16 agc1_max;
83 u16 agc1_min;
84 u16 agc2_max;
85 u16 agc2_min;
86
87 u8 agc1_pt1;
88 u8 agc1_pt2;
89 u8 agc1_pt3;
90
91 u8 agc1_slope1;
92 u8 agc1_slope2;
93
94 u8 agc2_pt1;
95 u8 agc2_pt2;
96
97 u8 agc2_slope1;
98 u8 agc2_slope2;
99
100 u8 alpha_mant;
101 u8 alpha_exp;
102
103 u8 beta_mant;
104 u8 beta_exp;
105
106 u8 perform_agc_softsplit;
107
108 struct {
109 u16 min;
110 u16 max;
111 u16 min_thres;
112 u16 max_thres;
113 } split;
114};
115
116struct dibx000_bandwidth_config {
117 u32 internal;
118 u32 sampling;
119
120 u8 pll_prediv;
121 u8 pll_ratio;
122 u8 pll_range;
123 u8 pll_reset;
124 u8 pll_bypass;
125
126 u8 enable_refdiv;
127 u8 bypclk_div;
128 u8 IO_CLK_en_core;
129 u8 ADClkSrc;
130 u8 modulo;
131
132 u16 sad_cfg;
133
134 u32 ifreq;
135 u32 timf;
136
137 u32 xtal_hz;
138};
139
140enum dibx000_adc_states {
141 DIBX000_SLOW_ADC_ON = 0,
142 DIBX000_SLOW_ADC_OFF,
143 DIBX000_ADC_ON,
144 DIBX000_ADC_OFF,
145 DIBX000_VBG_ENABLE,
146 DIBX000_VBG_DISABLE,
147};
148
149#define BANDWIDTH_TO_KHZ(v) ((v) == BANDWIDTH_8_MHZ ? 8000 : \
150 (v) == BANDWIDTH_7_MHZ ? 7000 : \
151 (v) == BANDWIDTH_6_MHZ ? 6000 : 8000)
152
153#define BANDWIDTH_TO_INDEX(v) ( \
154 (v) == 8000 ? BANDWIDTH_8_MHZ : \
155 (v) == 7000 ? BANDWIDTH_7_MHZ : \
156 (v) == 6000 ? BANDWIDTH_6_MHZ : BANDWIDTH_8_MHZ )
157
158/* Chip output mode. */
159#define OUTMODE_HIGH_Z 0
160#define OUTMODE_MPEG2_PAR_GATED_CLK 1
161#define OUTMODE_MPEG2_PAR_CONT_CLK 2
162#define OUTMODE_MPEG2_SERIAL 7
163#define OUTMODE_DIVERSITY 4
164#define OUTMODE_MPEG2_FIFO 5
165#define OUTMODE_ANALOG_ADC 6
166
167#define INPUT_MODE_OFF 0x11
168#define INPUT_MODE_DIVERSITY 0x12
169#define INPUT_MODE_MPEG 0x13
170
171enum frontend_tune_state {
172 CT_TUNER_START = 10,
173 CT_TUNER_STEP_0,
174 CT_TUNER_STEP_1,
175 CT_TUNER_STEP_2,
176 CT_TUNER_STEP_3,
177 CT_TUNER_STEP_4,
178 CT_TUNER_STEP_5,
179 CT_TUNER_STEP_6,
180 CT_TUNER_STEP_7,
181 CT_TUNER_STOP,
182
183 CT_AGC_START = 20,
184 CT_AGC_STEP_0,
185 CT_AGC_STEP_1,
186 CT_AGC_STEP_2,
187 CT_AGC_STEP_3,
188 CT_AGC_STEP_4,
189 CT_AGC_STOP,
190
191 CT_DEMOD_START = 30,
192 CT_DEMOD_STEP_1,
193 CT_DEMOD_STEP_2,
194 CT_DEMOD_STEP_3,
195 CT_DEMOD_STEP_4,
196 CT_DEMOD_STEP_5,
197 CT_DEMOD_STEP_6,
198 CT_DEMOD_STEP_7,
199 CT_DEMOD_STEP_8,
200 CT_DEMOD_STEP_9,
201 CT_DEMOD_STEP_10,
202 CT_DEMOD_SEARCH_NEXT = 41,
203 CT_DEMOD_STEP_LOCKED,
204 CT_DEMOD_STOP,
205
206 CT_DONE = 100,
207 CT_SHUTDOWN,
208
209};
210
211struct dvb_frontend_parametersContext {
212#define CHANNEL_STATUS_PARAMETERS_UNKNOWN 0x01
213#define CHANNEL_STATUS_PARAMETERS_SET 0x02
214 u8 status;
215 u32 tune_time_estimation[2];
216 s32 tps_available;
217 u16 tps[9];
218};
219
220#define FE_STATUS_TUNE_FAILED 0
221#define FE_STATUS_TUNE_TIMED_OUT -1
222#define FE_STATUS_TUNE_TIME_TOO_SHORT -2
223#define FE_STATUS_TUNE_PENDING -3
224#define FE_STATUS_STD_SUCCESS -4
225#define FE_STATUS_FFT_SUCCESS -5
226#define FE_STATUS_DEMOD_SUCCESS -6
227#define FE_STATUS_LOCKED -7
228#define FE_STATUS_DATA_LOCKED -8
229
230#define FE_CALLBACK_TIME_NEVER 0xffffffff
231
232#define ABS(x) ((x < 0) ? (-x) : (x))
233
234#define DATA_BUS_ACCESS_MODE_8BIT 0x01
235#define DATA_BUS_ACCESS_MODE_16BIT 0x02
236#define DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT 0x10
237
238struct dibGPIOFunction {
239#define BOARD_GPIO_COMPONENT_BUS_ADAPTER 1
240#define BOARD_GPIO_COMPONENT_DEMOD 2
241 u8 component;
242
243#define BOARD_GPIO_FUNCTION_BOARD_ON 1
244#define BOARD_GPIO_FUNCTION_BOARD_OFF 2
245#define BOARD_GPIO_FUNCTION_COMPONENT_ON 3
246#define BOARD_GPIO_FUNCTION_COMPONENT_OFF 4
247#define BOARD_GPIO_FUNCTION_SUBBAND_PWM 5
248#define BOARD_GPIO_FUNCTION_SUBBAND_GPIO 6
249 u8 function;
250
251/* mask, direction and value are used specify which GPIO to change GPIO0
252 * is LSB and possible GPIO31 is MSB. The same bit-position as in the
253 * mask is used for the direction and the value. Direction == 1 is OUT,
254 * 0 == IN. For direction "OUT" value is either 1 or 0, for direction IN
255 * value has no meaning.
256 *
257 * In case of BOARD_GPIO_FUNCTION_PWM mask is giving the GPIO to be
258 * used to do the PWM. Direction gives the PWModulator to be used.
259 * Value gives the PWM value in device-dependent scale.
260 */
261 u32 mask;
262 u32 direction;
263 u32 value;
264};
265
266#define MAX_NB_SUBBANDS 8
267struct dibSubbandSelection {
268 u8 size; /* Actual number of subbands. */
269 struct {
270 u16 f_mhz;
271 struct dibGPIOFunction gpio;
272 } subband[MAX_NB_SUBBANDS];
273};
274
275#define DEMOD_TIMF_SET 0x00
276#define DEMOD_TIMF_GET 0x01
277#define DEMOD_TIMF_UPDATE 0x02
278
279#endif
diff --git a/drivers/media/dvb/frontends/drxd.h b/drivers/media/dvb/frontends/drxd.h
new file mode 100644
index 00000000000..7113535844f
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxd.h
@@ -0,0 +1,61 @@
1/*
2 * drxd.h: DRXD DVB-T demodulator driver
3 *
4 * Copyright (C) 2005-2007 Micronas
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
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 *
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., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#ifndef _DRXD_H_
25#define _DRXD_H_
26
27#include <linux/types.h>
28#include <linux/i2c.h>
29
30struct drxd_config {
31 u8 index;
32
33 u8 pll_address;
34 u8 pll_type;
35#define DRXD_PLL_NONE 0
36#define DRXD_PLL_DTT7520X 1
37#define DRXD_PLL_MT3X0823 2
38
39 u32 clock;
40 u8 insert_rs_byte;
41
42 u8 demod_address;
43 u8 demoda_address;
44 u8 demod_revision;
45
46 /* If the tuner is not behind an i2c gate, be sure to flip this bit
47 or else the i2c bus could get wedged */
48 u8 disable_i2c_gate_ctrl;
49
50 u32 IF;
51 int (*pll_set) (void *priv, void *priv_params,
52 u8 pll_addr, u8 demoda_addr, s32 *off);
53 s16(*osc_deviation) (void *priv, s16 dev, int flag);
54};
55
56extern
57struct dvb_frontend *drxd_attach(const struct drxd_config *config,
58 void *priv, struct i2c_adapter *i2c,
59 struct device *dev);
60extern int drxd_config_i2c(struct dvb_frontend *, int);
61#endif
diff --git a/drivers/media/dvb/frontends/drxd_firm.c b/drivers/media/dvb/frontends/drxd_firm.c
new file mode 100644
index 00000000000..5418b0b1dad
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxd_firm.c
@@ -0,0 +1,929 @@
1/*
2 * drxd_firm.c : DRXD firmware tables
3 *
4 * Copyright (C) 2006-2007 Micronas
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
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 *
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., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24/* TODO: generate this file with a script from a settings file */
25
26/* Contains A2 firmware version: 1.4.2
27 * Contains B1 firmware version: 3.3.33
28 * Contains settings from driver 1.4.23
29*/
30
31#include "drxd_firm.h"
32
33#define ADDRESS(x) ((x) & 0xFF), (((x)>>8) & 0xFF), (((x)>>16) & 0xFF), (((x)>>24) & 0xFF)
34#define LENGTH(x) ((x) & 0xFF), (((x)>>8) & 0xFF)
35
36/* Is written via block write, must be little endian */
37#define DATA16(x) ((x) & 0xFF), (((x)>>8) & 0xFF)
38
39#define WRBLOCK(a, l) ADDRESS(a), LENGTH(l)
40#define WR16(a, d) ADDRESS(a), LENGTH(1), DATA16(d)
41
42#define END_OF_TABLE 0xFF, 0xFF, 0xFF, 0xFF
43
44/* HI firmware patches */
45
46#define HI_TR_FUNC_ADDR HI_IF_RAM_USR_BEGIN__A
47#define HI_TR_FUNC_SIZE 9 /* size of this function in instruction words */
48
49u8 DRXD_InitAtomicRead[] = {
50 WRBLOCK(HI_TR_FUNC_ADDR, HI_TR_FUNC_SIZE),
51 0x26, 0x00, /* 0 -> ring.rdy; */
52 0x60, 0x04, /* r0rami.dt -> ring.xba; */
53 0x61, 0x04, /* r0rami.dt -> ring.xad; */
54 0xE3, 0x07, /* HI_RA_RAM_USR_BEGIN -> ring.iad; */
55 0x40, 0x00, /* (long immediate) */
56 0x64, 0x04, /* r0rami.dt -> ring.len; */
57 0x65, 0x04, /* r0rami.dt -> ring.ctl; */
58 0x26, 0x00, /* 0 -> ring.rdy; */
59 0x38, 0x00, /* 0 -> jumps.ad; */
60 END_OF_TABLE
61};
62
63/* Pins D0 and D1 of the parallel MPEG output can be used
64 to set the I2C address of a device. */
65
66#define HI_RST_FUNC_ADDR (HI_IF_RAM_USR_BEGIN__A + HI_TR_FUNC_SIZE)
67#define HI_RST_FUNC_SIZE 54 /* size of this function in instruction words */
68
69/* D0 Version */
70u8 DRXD_HiI2cPatch_1[] = {
71 WRBLOCK(HI_RST_FUNC_ADDR, HI_RST_FUNC_SIZE),
72 0xC8, 0x07, 0x01, 0x00, /* MASK -> reg0.dt; */
73 0xE0, 0x07, 0x15, 0x02, /* (EC__BLK << 6) + EC_OC_REG__BNK -> ring.xba; */
74 0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad; */
75 0xA2, 0x00, /* M_BNK_ID_DAT -> ring.iba; */
76 0x23, 0x00, /* &data -> ring.iad; */
77 0x24, 0x00, /* 0 -> ring.len; */
78 0xA5, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl; */
79 0x26, 0x00, /* 0 -> ring.rdy; */
80 0x42, 0x00, /* &data+1 -> w0ram.ad; */
81 0xC0, 0x07, 0xFF, 0x0F, /* -1 -> w0ram.dt; */
82 0x63, 0x00, /* &data+1 -> ring.iad; */
83 0x65, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl; */
84 0x26, 0x00, /* 0 -> ring.rdy; */
85 0xE1, 0x07, 0x38, 0x00, /* EC_OC_REG_OCR_MPG_USR_DAT__A -> ring.xad; */
86 0xA5, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl; */
87 0x26, 0x00, /* 0 -> ring.rdy; */
88 0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad; */
89 0x23, 0x00, /* &data -> ring.iad; */
90 0x65, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl; */
91 0x26, 0x00, /* 0 -> ring.rdy; */
92 0x42, 0x00, /* &data+1 -> w0ram.ad; */
93 0x0F, 0x04, /* r0ram.dt -> and.op; */
94 0x1C, 0x06, /* reg0.dt -> and.tr; */
95 0xCF, 0x04, /* and.rs -> add.op; */
96 0xD0, 0x07, 0x70, 0x00, /* DEF_DEV_ID -> add.tr; */
97 0xD0, 0x04, /* add.rs -> add.tr; */
98 0xC8, 0x04, /* add.rs -> reg0.dt; */
99 0x60, 0x00, /* reg0.dt -> w0ram.dt; */
100 0xC2, 0x07, 0x10, 0x00, /* SLV0_BASE -> w0rami.ad; */
101 0x01, 0x00, /* 0 -> w0rami.dt; */
102 0x01, 0x06, /* reg0.dt -> w0rami.dt; */
103 0xC2, 0x07, 0x20, 0x00, /* SLV1_BASE -> w0rami.ad; */
104 0x01, 0x00, /* 0 -> w0rami.dt; */
105 0x01, 0x06, /* reg0.dt -> w0rami.dt; */
106 0xC2, 0x07, 0x30, 0x00, /* CMD_BASE -> w0rami.ad; */
107 0x01, 0x00, /* 0 -> w0rami.dt; */
108 0x01, 0x00, /* 0 -> w0rami.dt; */
109 0x01, 0x00, /* 0 -> w0rami.dt; */
110 0x68, 0x00, /* M_IC_SEL_PT1 -> i2c.sel; */
111 0x29, 0x00, /* M_IC_CMD_RESET -> i2c.cmd; */
112 0x28, 0x00, /* M_IC_SEL_PT0 -> i2c.sel; */
113 0x29, 0x00, /* M_IC_CMD_RESET -> i2c.cmd; */
114 0xF8, 0x07, 0x2F, 0x00, /* 0x2F -> jumps.ad; */
115
116 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 0) + 1)),
117 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
118 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 1) + 1)),
119 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
120 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 2) + 1)),
121 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
122 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 3) + 1)),
123 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
124
125 /* Force quick and dirty reset */
126 WR16(B_HI_CT_REG_COMM_STATE__A, 0),
127 END_OF_TABLE
128};
129
130/* D0,D1 Version */
131u8 DRXD_HiI2cPatch_3[] = {
132 WRBLOCK(HI_RST_FUNC_ADDR, HI_RST_FUNC_SIZE),
133 0xC8, 0x07, 0x03, 0x00, /* MASK -> reg0.dt; */
134 0xE0, 0x07, 0x15, 0x02, /* (EC__BLK << 6) + EC_OC_REG__BNK -> ring.xba; */
135 0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad; */
136 0xA2, 0x00, /* M_BNK_ID_DAT -> ring.iba; */
137 0x23, 0x00, /* &data -> ring.iad; */
138 0x24, 0x00, /* 0 -> ring.len; */
139 0xA5, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl; */
140 0x26, 0x00, /* 0 -> ring.rdy; */
141 0x42, 0x00, /* &data+1 -> w0ram.ad; */
142 0xC0, 0x07, 0xFF, 0x0F, /* -1 -> w0ram.dt; */
143 0x63, 0x00, /* &data+1 -> ring.iad; */
144 0x65, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl; */
145 0x26, 0x00, /* 0 -> ring.rdy; */
146 0xE1, 0x07, 0x38, 0x00, /* EC_OC_REG_OCR_MPG_USR_DAT__A -> ring.xad; */
147 0xA5, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl; */
148 0x26, 0x00, /* 0 -> ring.rdy; */
149 0xE1, 0x07, 0x12, 0x00, /* EC_OC_REG_OC_MPG_SIO__A -> ring.xad; */
150 0x23, 0x00, /* &data -> ring.iad; */
151 0x65, 0x02, /* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl; */
152 0x26, 0x00, /* 0 -> ring.rdy; */
153 0x42, 0x00, /* &data+1 -> w0ram.ad; */
154 0x0F, 0x04, /* r0ram.dt -> and.op; */
155 0x1C, 0x06, /* reg0.dt -> and.tr; */
156 0xCF, 0x04, /* and.rs -> add.op; */
157 0xD0, 0x07, 0x70, 0x00, /* DEF_DEV_ID -> add.tr; */
158 0xD0, 0x04, /* add.rs -> add.tr; */
159 0xC8, 0x04, /* add.rs -> reg0.dt; */
160 0x60, 0x00, /* reg0.dt -> w0ram.dt; */
161 0xC2, 0x07, 0x10, 0x00, /* SLV0_BASE -> w0rami.ad; */
162 0x01, 0x00, /* 0 -> w0rami.dt; */
163 0x01, 0x06, /* reg0.dt -> w0rami.dt; */
164 0xC2, 0x07, 0x20, 0x00, /* SLV1_BASE -> w0rami.ad; */
165 0x01, 0x00, /* 0 -> w0rami.dt; */
166 0x01, 0x06, /* reg0.dt -> w0rami.dt; */
167 0xC2, 0x07, 0x30, 0x00, /* CMD_BASE -> w0rami.ad; */
168 0x01, 0x00, /* 0 -> w0rami.dt; */
169 0x01, 0x00, /* 0 -> w0rami.dt; */
170 0x01, 0x00, /* 0 -> w0rami.dt; */
171 0x68, 0x00, /* M_IC_SEL_PT1 -> i2c.sel; */
172 0x29, 0x00, /* M_IC_CMD_RESET -> i2c.cmd; */
173 0x28, 0x00, /* M_IC_SEL_PT0 -> i2c.sel; */
174 0x29, 0x00, /* M_IC_CMD_RESET -> i2c.cmd; */
175 0xF8, 0x07, 0x2F, 0x00, /* 0x2F -> jumps.ad; */
176
177 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 0) + 1)),
178 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
179 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 1) + 1)),
180 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
181 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 2) + 1)),
182 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
183 WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 3) + 1)),
184 (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
185
186 /* Force quick and dirty reset */
187 WR16(B_HI_CT_REG_COMM_STATE__A, 0),
188 END_OF_TABLE
189};
190
191u8 DRXD_ResetCEFR[] = {
192 WRBLOCK(CE_REG_FR_TREAL00__A, 57),
193 0x52, 0x00, /* CE_REG_FR_TREAL00__A */
194 0x00, 0x00, /* CE_REG_FR_TIMAG00__A */
195 0x52, 0x00, /* CE_REG_FR_TREAL01__A */
196 0x00, 0x00, /* CE_REG_FR_TIMAG01__A */
197 0x52, 0x00, /* CE_REG_FR_TREAL02__A */
198 0x00, 0x00, /* CE_REG_FR_TIMAG02__A */
199 0x52, 0x00, /* CE_REG_FR_TREAL03__A */
200 0x00, 0x00, /* CE_REG_FR_TIMAG03__A */
201 0x52, 0x00, /* CE_REG_FR_TREAL04__A */
202 0x00, 0x00, /* CE_REG_FR_TIMAG04__A */
203 0x52, 0x00, /* CE_REG_FR_TREAL05__A */
204 0x00, 0x00, /* CE_REG_FR_TIMAG05__A */
205 0x52, 0x00, /* CE_REG_FR_TREAL06__A */
206 0x00, 0x00, /* CE_REG_FR_TIMAG06__A */
207 0x52, 0x00, /* CE_REG_FR_TREAL07__A */
208 0x00, 0x00, /* CE_REG_FR_TIMAG07__A */
209 0x52, 0x00, /* CE_REG_FR_TREAL08__A */
210 0x00, 0x00, /* CE_REG_FR_TIMAG08__A */
211 0x52, 0x00, /* CE_REG_FR_TREAL09__A */
212 0x00, 0x00, /* CE_REG_FR_TIMAG09__A */
213 0x52, 0x00, /* CE_REG_FR_TREAL10__A */
214 0x00, 0x00, /* CE_REG_FR_TIMAG10__A */
215 0x52, 0x00, /* CE_REG_FR_TREAL11__A */
216 0x00, 0x00, /* CE_REG_FR_TIMAG11__A */
217
218 0x52, 0x00, /* CE_REG_FR_MID_TAP__A */
219
220 0x0B, 0x00, /* CE_REG_FR_SQS_G00__A */
221 0x0B, 0x00, /* CE_REG_FR_SQS_G01__A */
222 0x0B, 0x00, /* CE_REG_FR_SQS_G02__A */
223 0x0B, 0x00, /* CE_REG_FR_SQS_G03__A */
224 0x0B, 0x00, /* CE_REG_FR_SQS_G04__A */
225 0x0B, 0x00, /* CE_REG_FR_SQS_G05__A */
226 0x0B, 0x00, /* CE_REG_FR_SQS_G06__A */
227 0x0B, 0x00, /* CE_REG_FR_SQS_G07__A */
228 0x0B, 0x00, /* CE_REG_FR_SQS_G08__A */
229 0x0B, 0x00, /* CE_REG_FR_SQS_G09__A */
230 0x0B, 0x00, /* CE_REG_FR_SQS_G10__A */
231 0x0B, 0x00, /* CE_REG_FR_SQS_G11__A */
232 0x0B, 0x00, /* CE_REG_FR_SQS_G12__A */
233
234 0xFF, 0x01, /* CE_REG_FR_RIO_G00__A */
235 0x90, 0x01, /* CE_REG_FR_RIO_G01__A */
236 0x0B, 0x01, /* CE_REG_FR_RIO_G02__A */
237 0xC8, 0x00, /* CE_REG_FR_RIO_G03__A */
238 0xA0, 0x00, /* CE_REG_FR_RIO_G04__A */
239 0x85, 0x00, /* CE_REG_FR_RIO_G05__A */
240 0x72, 0x00, /* CE_REG_FR_RIO_G06__A */
241 0x64, 0x00, /* CE_REG_FR_RIO_G07__A */
242 0x59, 0x00, /* CE_REG_FR_RIO_G08__A */
243 0x50, 0x00, /* CE_REG_FR_RIO_G09__A */
244 0x49, 0x00, /* CE_REG_FR_RIO_G10__A */
245
246 0x10, 0x00, /* CE_REG_FR_MODE__A */
247 0x78, 0x00, /* CE_REG_FR_SQS_TRH__A */
248 0x00, 0x00, /* CE_REG_FR_RIO_GAIN__A */
249 0x00, 0x02, /* CE_REG_FR_BYPASS__A */
250 0x0D, 0x00, /* CE_REG_FR_PM_SET__A */
251 0x07, 0x00, /* CE_REG_FR_ERR_SH__A */
252 0x04, 0x00, /* CE_REG_FR_MAN_SH__A */
253 0x06, 0x00, /* CE_REG_FR_TAP_SH__A */
254
255 END_OF_TABLE
256};
257
258u8 DRXD_InitFEA2_1[] = {
259 WRBLOCK(FE_AD_REG_PD__A, 3),
260 0x00, 0x00, /* FE_AD_REG_PD__A */
261 0x01, 0x00, /* FE_AD_REG_INVEXT__A */
262 0x00, 0x00, /* FE_AD_REG_CLKNEG__A */
263
264 WRBLOCK(FE_AG_REG_DCE_AUR_CNT__A, 2),
265 0x10, 0x00, /* FE_AG_REG_DCE_AUR_CNT__A */
266 0x10, 0x00, /* FE_AG_REG_DCE_RUR_CNT__A */
267
268 WRBLOCK(FE_AG_REG_ACE_AUR_CNT__A, 2),
269 0x0E, 0x00, /* FE_AG_REG_ACE_AUR_CNT__A */
270 0x00, 0x00, /* FE_AG_REG_ACE_RUR_CNT__A */
271
272 WRBLOCK(FE_AG_REG_EGC_FLA_RGN__A, 5),
273 0x04, 0x00, /* FE_AG_REG_EGC_FLA_RGN__A */
274 0x1F, 0x00, /* FE_AG_REG_EGC_SLO_RGN__A */
275 0x00, 0x00, /* FE_AG_REG_EGC_JMP_PSN__A */
276 0x00, 0x00, /* FE_AG_REG_EGC_FLA_INC__A */
277 0x00, 0x00, /* FE_AG_REG_EGC_FLA_DEC__A */
278
279 WRBLOCK(FE_AG_REG_GC1_AGC_MAX__A, 2),
280 0xFF, 0x01, /* FE_AG_REG_GC1_AGC_MAX__A */
281 0x00, 0xFE, /* FE_AG_REG_GC1_AGC_MIN__A */
282
283 WRBLOCK(FE_AG_REG_IND_WIN__A, 29),
284 0x00, 0x00, /* FE_AG_REG_IND_WIN__A */
285 0x05, 0x00, /* FE_AG_REG_IND_THD_LOL__A */
286 0x0F, 0x00, /* FE_AG_REG_IND_THD_HIL__A */
287 0x00, 0x00, /* FE_AG_REG_IND_DEL__A don't care */
288 0x1E, 0x00, /* FE_AG_REG_IND_PD1_WRI__A */
289 0x0C, 0x00, /* FE_AG_REG_PDA_AUR_CNT__A */
290 0x00, 0x00, /* FE_AG_REG_PDA_RUR_CNT__A */
291 0x00, 0x00, /* FE_AG_REG_PDA_AVE_DAT__A don't care */
292 0x00, 0x00, /* FE_AG_REG_PDC_RUR_CNT__A */
293 0x01, 0x00, /* FE_AG_REG_PDC_SET_LVL__A */
294 0x02, 0x00, /* FE_AG_REG_PDC_FLA_RGN__A */
295 0x00, 0x00, /* FE_AG_REG_PDC_JMP_PSN__A don't care */
296 0xFF, 0xFF, /* FE_AG_REG_PDC_FLA_STP__A */
297 0xFF, 0xFF, /* FE_AG_REG_PDC_SLO_STP__A */
298 0x00, 0x1F, /* FE_AG_REG_PDC_PD2_WRI__A don't care */
299 0x00, 0x00, /* FE_AG_REG_PDC_MAP_DAT__A don't care */
300 0x02, 0x00, /* FE_AG_REG_PDC_MAX__A */
301 0x0C, 0x00, /* FE_AG_REG_TGA_AUR_CNT__A */
302 0x00, 0x00, /* FE_AG_REG_TGA_RUR_CNT__A */
303 0x00, 0x00, /* FE_AG_REG_TGA_AVE_DAT__A don't care */
304 0x00, 0x00, /* FE_AG_REG_TGC_RUR_CNT__A */
305 0x22, 0x00, /* FE_AG_REG_TGC_SET_LVL__A */
306 0x15, 0x00, /* FE_AG_REG_TGC_FLA_RGN__A */
307 0x00, 0x00, /* FE_AG_REG_TGC_JMP_PSN__A don't care */
308 0x01, 0x00, /* FE_AG_REG_TGC_FLA_STP__A */
309 0x0A, 0x00, /* FE_AG_REG_TGC_SLO_STP__A */
310 0x00, 0x00, /* FE_AG_REG_TGC_MAP_DAT__A don't care */
311 0x10, 0x00, /* FE_AG_REG_FGA_AUR_CNT__A */
312 0x10, 0x00, /* FE_AG_REG_FGA_RUR_CNT__A */
313
314 WRBLOCK(FE_AG_REG_BGC_FGC_WRI__A, 2),
315 0x00, 0x00, /* FE_AG_REG_BGC_FGC_WRI__A */
316 0x00, 0x00, /* FE_AG_REG_BGC_CGC_WRI__A */
317
318 WRBLOCK(FE_FD_REG_SCL__A, 3),
319 0x05, 0x00, /* FE_FD_REG_SCL__A */
320 0x03, 0x00, /* FE_FD_REG_MAX_LEV__A */
321 0x05, 0x00, /* FE_FD_REG_NR__A */
322
323 WRBLOCK(FE_CF_REG_SCL__A, 5),
324 0x16, 0x00, /* FE_CF_REG_SCL__A */
325 0x04, 0x00, /* FE_CF_REG_MAX_LEV__A */
326 0x06, 0x00, /* FE_CF_REG_NR__A */
327 0x00, 0x00, /* FE_CF_REG_IMP_VAL__A */
328 0x01, 0x00, /* FE_CF_REG_MEAS_VAL__A */
329
330 WRBLOCK(FE_CU_REG_FRM_CNT_RST__A, 2),
331 0x00, 0x08, /* FE_CU_REG_FRM_CNT_RST__A */
332 0x00, 0x00, /* FE_CU_REG_FRM_CNT_STR__A */
333
334 END_OF_TABLE
335};
336
337 /* with PGA */
338/* WR16COND( DRXD_WITH_PGA, FE_AG_REG_AG_PGA_MODE__A , 0x0004), */
339 /* without PGA */
340/* WR16COND( DRXD_WITHOUT_PGA, FE_AG_REG_AG_PGA_MODE__A , 0x0001), */
341/* WR16(FE_AG_REG_AG_AGC_SIO__A, (extAttr -> FeAgRegAgAgcSio), 0x0000 );*/
342/* WR16(FE_AG_REG_AG_PWD__A ,(extAttr -> FeAgRegAgPwd), 0x0000 );*/
343
344u8 DRXD_InitFEA2_2[] = {
345 WR16(FE_AG_REG_CDR_RUR_CNT__A, 0x0010),
346 WR16(FE_AG_REG_FGM_WRI__A, 48),
347 /* Activate measurement, activate scale */
348 WR16(FE_FD_REG_MEAS_VAL__A, 0x0001),
349
350 WR16(FE_CU_REG_COMM_EXEC__A, 0x0001),
351 WR16(FE_CF_REG_COMM_EXEC__A, 0x0001),
352 WR16(FE_IF_REG_COMM_EXEC__A, 0x0001),
353 WR16(FE_FD_REG_COMM_EXEC__A, 0x0001),
354 WR16(FE_FS_REG_COMM_EXEC__A, 0x0001),
355 WR16(FE_AD_REG_COMM_EXEC__A, 0x0001),
356 WR16(FE_AG_REG_COMM_EXEC__A, 0x0001),
357 WR16(FE_AG_REG_AG_MODE_LOP__A, 0x895E),
358
359 END_OF_TABLE
360};
361
362u8 DRXD_InitFEB1_1[] = {
363 WR16(B_FE_AD_REG_PD__A, 0x0000),
364 WR16(B_FE_AD_REG_CLKNEG__A, 0x0000),
365 WR16(B_FE_AG_REG_BGC_FGC_WRI__A, 0x0000),
366 WR16(B_FE_AG_REG_BGC_CGC_WRI__A, 0x0000),
367 WR16(B_FE_AG_REG_AG_MODE_LOP__A, 0x000a),
368 WR16(B_FE_AG_REG_IND_PD1_WRI__A, 35),
369 WR16(B_FE_AG_REG_IND_WIN__A, 0),
370 WR16(B_FE_AG_REG_IND_THD_LOL__A, 8),
371 WR16(B_FE_AG_REG_IND_THD_HIL__A, 8),
372 WR16(B_FE_CF_REG_IMP_VAL__A, 1),
373 WR16(B_FE_AG_REG_EGC_FLA_RGN__A, 7),
374 END_OF_TABLE
375};
376
377 /* with PGA */
378/* WR16(B_FE_AG_REG_AG_PGA_MODE__A , 0x0000, 0x0000); */
379 /* without PGA */
380/* WR16(B_FE_AG_REG_AG_PGA_MODE__A ,
381 B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN, 0x0000);*/
382 /* WR16(B_FE_AG_REG_AG_AGC_SIO__A,(extAttr -> FeAgRegAgAgcSio), 0x0000 );*//*added HS 23-05-2005 */
383/* WR16(B_FE_AG_REG_AG_PWD__A ,(extAttr -> FeAgRegAgPwd), 0x0000 );*/
384
385u8 DRXD_InitFEB1_2[] = {
386 WR16(B_FE_COMM_EXEC__A, 0x0001),
387
388 /* RF-AGC setup */
389 WR16(B_FE_AG_REG_PDA_AUR_CNT__A, 0x0C),
390 WR16(B_FE_AG_REG_PDC_SET_LVL__A, 0x01),
391 WR16(B_FE_AG_REG_PDC_FLA_RGN__A, 0x02),
392 WR16(B_FE_AG_REG_PDC_FLA_STP__A, 0xFFFF),
393 WR16(B_FE_AG_REG_PDC_SLO_STP__A, 0xFFFF),
394 WR16(B_FE_AG_REG_PDC_MAX__A, 0x02),
395 WR16(B_FE_AG_REG_TGA_AUR_CNT__A, 0x0C),
396 WR16(B_FE_AG_REG_TGC_SET_LVL__A, 0x22),
397 WR16(B_FE_AG_REG_TGC_FLA_RGN__A, 0x15),
398 WR16(B_FE_AG_REG_TGC_FLA_STP__A, 0x01),
399 WR16(B_FE_AG_REG_TGC_SLO_STP__A, 0x0A),
400
401 WR16(B_FE_CU_REG_DIV_NFC_CLP__A, 0),
402 WR16(B_FE_CU_REG_CTR_NFC_OCR__A, 25000),
403 WR16(B_FE_CU_REG_CTR_NFC_ICR__A, 1),
404 END_OF_TABLE
405};
406
407u8 DRXD_InitCPA2[] = {
408 WRBLOCK(CP_REG_BR_SPL_OFFSET__A, 2),
409 0x07, 0x00, /* CP_REG_BR_SPL_OFFSET__A */
410 0x0A, 0x00, /* CP_REG_BR_STR_DEL__A */
411
412 WRBLOCK(CP_REG_RT_ANG_INC0__A, 4),
413 0x00, 0x00, /* CP_REG_RT_ANG_INC0__A */
414 0x00, 0x00, /* CP_REG_RT_ANG_INC1__A */
415 0x03, 0x00, /* CP_REG_RT_DETECT_ENA__A */
416 0x03, 0x00, /* CP_REG_RT_DETECT_TRH__A */
417
418 WRBLOCK(CP_REG_AC_NEXP_OFFS__A, 5),
419 0x32, 0x00, /* CP_REG_AC_NEXP_OFFS__A */
420 0x62, 0x00, /* CP_REG_AC_AVER_POW__A */
421 0x82, 0x00, /* CP_REG_AC_MAX_POW__A */
422 0x26, 0x00, /* CP_REG_AC_WEIGHT_MAN__A */
423 0x0F, 0x00, /* CP_REG_AC_WEIGHT_EXP__A */
424
425 WRBLOCK(CP_REG_AC_AMP_MODE__A, 2),
426 0x02, 0x00, /* CP_REG_AC_AMP_MODE__A */
427 0x01, 0x00, /* CP_REG_AC_AMP_FIX__A */
428
429 WR16(CP_REG_INTERVAL__A, 0x0005),
430 WR16(CP_REG_RT_EXP_MARG__A, 0x0004),
431 WR16(CP_REG_AC_ANG_MODE__A, 0x0003),
432
433 WR16(CP_REG_COMM_EXEC__A, 0x0001),
434 END_OF_TABLE
435};
436
437u8 DRXD_InitCPB1[] = {
438 WR16(B_CP_REG_BR_SPL_OFFSET__A, 0x0008),
439 WR16(B_CP_COMM_EXEC__A, 0x0001),
440 END_OF_TABLE
441};
442
443u8 DRXD_InitCEA2[] = {
444 WRBLOCK(CE_REG_AVG_POW__A, 4),
445 0x62, 0x00, /* CE_REG_AVG_POW__A */
446 0x78, 0x00, /* CE_REG_MAX_POW__A */
447 0x62, 0x00, /* CE_REG_ATT__A */
448 0x17, 0x00, /* CE_REG_NRED__A */
449
450 WRBLOCK(CE_REG_NE_ERR_SELECT__A, 2),
451 0x07, 0x00, /* CE_REG_NE_ERR_SELECT__A */
452 0xEB, 0xFF, /* CE_REG_NE_TD_CAL__A */
453
454 WRBLOCK(CE_REG_NE_MIXAVG__A, 2),
455 0x06, 0x00, /* CE_REG_NE_MIXAVG__A */
456 0x00, 0x00, /* CE_REG_NE_NUPD_OFS__A */
457
458 WRBLOCK(CE_REG_PE_NEXP_OFFS__A, 2),
459 0x00, 0x00, /* CE_REG_PE_NEXP_OFFS__A */
460 0x00, 0x00, /* CE_REG_PE_TIMESHIFT__A */
461
462 WRBLOCK(CE_REG_TP_A0_TAP_NEW__A, 3),
463 0x00, 0x01, /* CE_REG_TP_A0_TAP_NEW__A */
464 0x01, 0x00, /* CE_REG_TP_A0_TAP_NEW_VALID__A */
465 0x0E, 0x00, /* CE_REG_TP_A0_MU_LMS_STEP__A */
466
467 WRBLOCK(CE_REG_TP_A1_TAP_NEW__A, 3),
468 0x00, 0x00, /* CE_REG_TP_A1_TAP_NEW__A */
469 0x01, 0x00, /* CE_REG_TP_A1_TAP_NEW_VALID__A */
470 0x0A, 0x00, /* CE_REG_TP_A1_MU_LMS_STEP__A */
471
472 WRBLOCK(CE_REG_FI_SHT_INCR__A, 2),
473 0x12, 0x00, /* CE_REG_FI_SHT_INCR__A */
474 0x0C, 0x00, /* CE_REG_FI_EXP_NORM__A */
475
476 WRBLOCK(CE_REG_IR_INPUTSEL__A, 3),
477 0x00, 0x00, /* CE_REG_IR_INPUTSEL__A */
478 0x00, 0x00, /* CE_REG_IR_STARTPOS__A */
479 0xFF, 0x00, /* CE_REG_IR_NEXP_THRES__A */
480
481 WR16(CE_REG_TI_NEXP_OFFS__A, 0x0000),
482
483 END_OF_TABLE
484};
485
486u8 DRXD_InitCEB1[] = {
487 WR16(B_CE_REG_TI_PHN_ENABLE__A, 0x0001),
488 WR16(B_CE_REG_FR_PM_SET__A, 0x000D),
489
490 END_OF_TABLE
491};
492
493u8 DRXD_InitEQA2[] = {
494 WRBLOCK(EQ_REG_OT_QNT_THRES0__A, 4),
495 0x1E, 0x00, /* EQ_REG_OT_QNT_THRES0__A */
496 0x1F, 0x00, /* EQ_REG_OT_QNT_THRES1__A */
497 0x06, 0x00, /* EQ_REG_OT_CSI_STEP__A */
498 0x02, 0x00, /* EQ_REG_OT_CSI_OFFSET__A */
499
500 WR16(EQ_REG_TD_REQ_SMB_CNT__A, 0x0200),
501 WR16(EQ_REG_IS_CLIP_EXP__A, 0x001F),
502 WR16(EQ_REG_SN_OFFSET__A, (u16) (-7)),
503 WR16(EQ_REG_RC_SEL_CAR__A, 0x0002),
504 WR16(EQ_REG_COMM_EXEC__A, 0x0001),
505 END_OF_TABLE
506};
507
508u8 DRXD_InitEQB1[] = {
509 WR16(B_EQ_REG_COMM_EXEC__A, 0x0001),
510 END_OF_TABLE
511};
512
513u8 DRXD_ResetECRAM[] = {
514 /* Reset packet sync bytes in EC_VD ram */
515 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
516 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
517 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
518 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
519 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
520 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
521 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
522 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
523 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
524 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
525 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
526
527 /* Reset packet sync bytes in EC_RS ram */
528 WR16(EC_RS_EC_RAM__A, 0x0000),
529 WR16(EC_RS_EC_RAM__A + 204, 0x0000),
530 END_OF_TABLE
531};
532
533u8 DRXD_InitECA2[] = {
534 WRBLOCK(EC_SB_REG_CSI_HI__A, 6),
535 0x1F, 0x00, /* EC_SB_REG_CSI_HI__A */
536 0x1E, 0x00, /* EC_SB_REG_CSI_LO__A */
537 0x01, 0x00, /* EC_SB_REG_SMB_TGL__A */
538 0x7F, 0x00, /* EC_SB_REG_SNR_HI__A */
539 0x7F, 0x00, /* EC_SB_REG_SNR_MID__A */
540 0x7F, 0x00, /* EC_SB_REG_SNR_LO__A */
541
542 WRBLOCK(EC_RS_REG_REQ_PCK_CNT__A, 2),
543 0x00, 0x10, /* EC_RS_REG_REQ_PCK_CNT__A */
544 DATA16(EC_RS_REG_VAL_PCK), /* EC_RS_REG_VAL__A */
545
546 WRBLOCK(EC_OC_REG_TMD_TOP_MODE__A, 5),
547 0x03, 0x00, /* EC_OC_REG_TMD_TOP_MODE__A */
548 0xF4, 0x01, /* EC_OC_REG_TMD_TOP_CNT__A */
549 0xC0, 0x03, /* EC_OC_REG_TMD_HIL_MAR__A */
550 0x40, 0x00, /* EC_OC_REG_TMD_LOL_MAR__A */
551 0x03, 0x00, /* EC_OC_REG_TMD_CUR_CNT__A */
552
553 WRBLOCK(EC_OC_REG_AVR_ASH_CNT__A, 2),
554 0x06, 0x00, /* EC_OC_REG_AVR_ASH_CNT__A */
555 0x02, 0x00, /* EC_OC_REG_AVR_BSH_CNT__A */
556
557 WRBLOCK(EC_OC_REG_RCN_MODE__A, 7),
558 0x07, 0x00, /* EC_OC_REG_RCN_MODE__A */
559 0x00, 0x00, /* EC_OC_REG_RCN_CRA_LOP__A */
560 0xc0, 0x00, /* EC_OC_REG_RCN_CRA_HIP__A */
561 0x00, 0x10, /* EC_OC_REG_RCN_CST_LOP__A */
562 0x00, 0x00, /* EC_OC_REG_RCN_CST_HIP__A */
563 0xFF, 0x01, /* EC_OC_REG_RCN_SET_LVL__A */
564 0x0D, 0x00, /* EC_OC_REG_RCN_GAI_LVL__A */
565
566 WRBLOCK(EC_OC_REG_RCN_CLP_LOP__A, 2),
567 0x00, 0x00, /* EC_OC_REG_RCN_CLP_LOP__A */
568 0xC0, 0x00, /* EC_OC_REG_RCN_CLP_HIP__A */
569
570 WR16(EC_SB_REG_CSI_OFS__A, 0x0001),
571 WR16(EC_VD_REG_FORCE__A, 0x0002),
572 WR16(EC_VD_REG_REQ_SMB_CNT__A, 0x0001),
573 WR16(EC_VD_REG_RLK_ENA__A, 0x0001),
574 WR16(EC_OD_REG_SYNC__A, 0x0664),
575 WR16(EC_OC_REG_OC_MON_SIO__A, 0x0000),
576 WR16(EC_OC_REG_SNC_ISC_LVL__A, 0x0D0C),
577 /* Output zero on monitorbus pads, power saving */
578 WR16(EC_OC_REG_OCR_MON_UOS__A,
579 (EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE |
580 EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE |
581 EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE |
582 EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE |
583 EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE |
584 EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE |
585 EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE |
586 EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE |
587 EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE |
588 EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE |
589 EC_OC_REG_OCR_MON_UOS_VAL_ENABLE |
590 EC_OC_REG_OCR_MON_UOS_CLK_ENABLE)),
591 WR16(EC_OC_REG_OCR_MON_WRI__A,
592 EC_OC_REG_OCR_MON_WRI_INIT),
593
594/* CHK_ERROR(ResetECRAM(demod)); */
595 /* Reset packet sync bytes in EC_VD ram */
596 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
597 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
598 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
599 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
600 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
601 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
602 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
603 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
604 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
605 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
606 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
607
608 /* Reset packet sync bytes in EC_RS ram */
609 WR16(EC_RS_EC_RAM__A, 0x0000),
610 WR16(EC_RS_EC_RAM__A + 204, 0x0000),
611
612 WR16(EC_SB_REG_COMM_EXEC__A, 0x0001),
613 WR16(EC_VD_REG_COMM_EXEC__A, 0x0001),
614 WR16(EC_OD_REG_COMM_EXEC__A, 0x0001),
615 WR16(EC_RS_REG_COMM_EXEC__A, 0x0001),
616 END_OF_TABLE
617};
618
619u8 DRXD_InitECB1[] = {
620 WR16(B_EC_SB_REG_CSI_OFS0__A, 0x0001),
621 WR16(B_EC_SB_REG_CSI_OFS1__A, 0x0001),
622 WR16(B_EC_SB_REG_CSI_OFS2__A, 0x0001),
623 WR16(B_EC_SB_REG_CSI_LO__A, 0x000c),
624 WR16(B_EC_SB_REG_CSI_HI__A, 0x0018),
625 WR16(B_EC_SB_REG_SNR_HI__A, 0x007f),
626 WR16(B_EC_SB_REG_SNR_MID__A, 0x007f),
627 WR16(B_EC_SB_REG_SNR_LO__A, 0x007f),
628
629 WR16(B_EC_OC_REG_DTO_CLKMODE__A, 0x0002),
630 WR16(B_EC_OC_REG_DTO_PER__A, 0x0006),
631 WR16(B_EC_OC_REG_DTO_BUR__A, 0x0001),
632 WR16(B_EC_OC_REG_RCR_CLKMODE__A, 0x0000),
633 WR16(B_EC_OC_REG_RCN_GAI_LVL__A, 0x000D),
634 WR16(B_EC_OC_REG_OC_MPG_SIO__A, 0x0000),
635
636 /* Needed because shadow registers do not have correct default value */
637 WR16(B_EC_OC_REG_RCN_CST_LOP__A, 0x1000),
638 WR16(B_EC_OC_REG_RCN_CST_HIP__A, 0x0000),
639 WR16(B_EC_OC_REG_RCN_CRA_LOP__A, 0x0000),
640 WR16(B_EC_OC_REG_RCN_CRA_HIP__A, 0x00C0),
641 WR16(B_EC_OC_REG_RCN_CLP_LOP__A, 0x0000),
642 WR16(B_EC_OC_REG_RCN_CLP_HIP__A, 0x00C0),
643 WR16(B_EC_OC_REG_DTO_INC_LOP__A, 0x0000),
644 WR16(B_EC_OC_REG_DTO_INC_HIP__A, 0x00C0),
645
646 WR16(B_EC_OD_REG_SYNC__A, 0x0664),
647 WR16(B_EC_RS_REG_REQ_PCK_CNT__A, 0x1000),
648
649/* CHK_ERROR(ResetECRAM(demod)); */
650 /* Reset packet sync bytes in EC_VD ram */
651 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
652 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
653 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
654 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
655 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
656 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
657 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
658 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
659 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
660 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
661 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
662
663 /* Reset packet sync bytes in EC_RS ram */
664 WR16(EC_RS_EC_RAM__A, 0x0000),
665 WR16(EC_RS_EC_RAM__A + 204, 0x0000),
666
667 WR16(B_EC_SB_REG_COMM_EXEC__A, 0x0001),
668 WR16(B_EC_VD_REG_COMM_EXEC__A, 0x0001),
669 WR16(B_EC_OD_REG_COMM_EXEC__A, 0x0001),
670 WR16(B_EC_RS_REG_COMM_EXEC__A, 0x0001),
671 END_OF_TABLE
672};
673
674u8 DRXD_ResetECA2[] = {
675
676 WR16(EC_OC_REG_COMM_EXEC__A, 0x0000),
677 WR16(EC_OD_REG_COMM_EXEC__A, 0x0000),
678
679 WRBLOCK(EC_OC_REG_TMD_TOP_MODE__A, 5),
680 0x03, 0x00, /* EC_OC_REG_TMD_TOP_MODE__A */
681 0xF4, 0x01, /* EC_OC_REG_TMD_TOP_CNT__A */
682 0xC0, 0x03, /* EC_OC_REG_TMD_HIL_MAR__A */
683 0x40, 0x00, /* EC_OC_REG_TMD_LOL_MAR__A */
684 0x03, 0x00, /* EC_OC_REG_TMD_CUR_CNT__A */
685
686 WRBLOCK(EC_OC_REG_AVR_ASH_CNT__A, 2),
687 0x06, 0x00, /* EC_OC_REG_AVR_ASH_CNT__A */
688 0x02, 0x00, /* EC_OC_REG_AVR_BSH_CNT__A */
689
690 WRBLOCK(EC_OC_REG_RCN_MODE__A, 7),
691 0x07, 0x00, /* EC_OC_REG_RCN_MODE__A */
692 0x00, 0x00, /* EC_OC_REG_RCN_CRA_LOP__A */
693 0xc0, 0x00, /* EC_OC_REG_RCN_CRA_HIP__A */
694 0x00, 0x10, /* EC_OC_REG_RCN_CST_LOP__A */
695 0x00, 0x00, /* EC_OC_REG_RCN_CST_HIP__A */
696 0xFF, 0x01, /* EC_OC_REG_RCN_SET_LVL__A */
697 0x0D, 0x00, /* EC_OC_REG_RCN_GAI_LVL__A */
698
699 WRBLOCK(EC_OC_REG_RCN_CLP_LOP__A, 2),
700 0x00, 0x00, /* EC_OC_REG_RCN_CLP_LOP__A */
701 0xC0, 0x00, /* EC_OC_REG_RCN_CLP_HIP__A */
702
703 WR16(EC_OD_REG_SYNC__A, 0x0664),
704 WR16(EC_OC_REG_OC_MON_SIO__A, 0x0000),
705 WR16(EC_OC_REG_SNC_ISC_LVL__A, 0x0D0C),
706 /* Output zero on monitorbus pads, power saving */
707 WR16(EC_OC_REG_OCR_MON_UOS__A,
708 (EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE |
709 EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE |
710 EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE |
711 EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE |
712 EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE |
713 EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE |
714 EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE |
715 EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE |
716 EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE |
717 EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE |
718 EC_OC_REG_OCR_MON_UOS_VAL_ENABLE |
719 EC_OC_REG_OCR_MON_UOS_CLK_ENABLE)),
720 WR16(EC_OC_REG_OCR_MON_WRI__A,
721 EC_OC_REG_OCR_MON_WRI_INIT),
722
723/* CHK_ERROR(ResetECRAM(demod)); */
724 /* Reset packet sync bytes in EC_VD ram */
725 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
726 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
727 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
728 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
729 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
730 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
731 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
732 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
733 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
734 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
735 WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
736
737 /* Reset packet sync bytes in EC_RS ram */
738 WR16(EC_RS_EC_RAM__A, 0x0000),
739 WR16(EC_RS_EC_RAM__A + 204, 0x0000),
740
741 WR16(EC_OD_REG_COMM_EXEC__A, 0x0001),
742 END_OF_TABLE
743};
744
745u8 DRXD_InitSC[] = {
746 WR16(SC_COMM_EXEC__A, 0),
747 WR16(SC_COMM_STATE__A, 0),
748
749#ifdef COMPILE_FOR_QT
750 WR16(SC_RA_RAM_BE_OPT_DELAY__A, 0x100),
751#endif
752
753 /* SC is not started, this is done in SetChannels() */
754 END_OF_TABLE
755};
756
757/* Diversity settings */
758
759u8 DRXD_InitDiversityFront[] = {
760 /* Start demod ********* RF in , diversity out **************************** */
761 WR16(B_SC_RA_RAM_CONFIG__A, B_SC_RA_RAM_CONFIG_FR_ENABLE__M |
762 B_SC_RA_RAM_CONFIG_FREQSCAN__M),
763
764 WR16(B_SC_RA_RAM_LC_ABS_2K__A, 0x7),
765 WR16(B_SC_RA_RAM_LC_ABS_8K__A, 0x7),
766 WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A, IRLEN_COARSE_8K),
767 WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A, 1 << (11 - IRLEN_COARSE_8K)),
768 WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A, 1 << (17 - IRLEN_COARSE_8K)),
769 WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A, IRLEN_FINE_8K),
770 WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A, 1 << (11 - IRLEN_FINE_8K)),
771 WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A, 1 << (17 - IRLEN_FINE_8K)),
772
773 WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A, IRLEN_COARSE_2K),
774 WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A, 1 << (11 - IRLEN_COARSE_2K)),
775 WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A, 1 << (17 - IRLEN_COARSE_2K)),
776 WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A, IRLEN_FINE_2K),
777 WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A, 1 << (11 - IRLEN_FINE_2K)),
778 WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A, 1 << (17 - IRLEN_FINE_2K)),
779
780 WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, 7),
781 WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, 4),
782 WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, 7),
783 WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, 4),
784 WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, 500),
785
786 WR16(B_CC_REG_DIVERSITY__A, 0x0001),
787 WR16(B_EC_OC_REG_OC_MODE_HIP__A, 0x0010),
788 WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_PASS_B_CE |
789 B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE | B_EQ_REG_RC_SEL_CAR_MEAS_B_CE),
790
791 /* 0x2a ), *//* CE to PASS mux */
792
793 END_OF_TABLE
794};
795
796u8 DRXD_InitDiversityEnd[] = {
797 /* End demod *********** combining RF in and diversity in, MPEG TS out **** */
798 /* disable near/far; switch on timing slave mode */
799 WR16(B_SC_RA_RAM_CONFIG__A, B_SC_RA_RAM_CONFIG_FR_ENABLE__M |
800 B_SC_RA_RAM_CONFIG_FREQSCAN__M |
801 B_SC_RA_RAM_CONFIG_DIV_ECHO_ENABLE__M |
802 B_SC_RA_RAM_CONFIG_SLAVE__M |
803 B_SC_RA_RAM_CONFIG_DIV_BLANK_ENABLE__M
804/* MV from CtrlDiversity */
805 ),
806#ifdef DRXDDIV_SRMM_SLAVING
807 WR16(SC_RA_RAM_LC_ABS_2K__A, 0x3c7),
808 WR16(SC_RA_RAM_LC_ABS_8K__A, 0x3c7),
809#else
810 WR16(SC_RA_RAM_LC_ABS_2K__A, 0x7),
811 WR16(SC_RA_RAM_LC_ABS_8K__A, 0x7),
812#endif
813
814 WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A, IRLEN_COARSE_8K),
815 WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A, 1 << (11 - IRLEN_COARSE_8K)),
816 WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A, 1 << (17 - IRLEN_COARSE_8K)),
817 WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A, IRLEN_FINE_8K),
818 WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A, 1 << (11 - IRLEN_FINE_8K)),
819 WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A, 1 << (17 - IRLEN_FINE_8K)),
820
821 WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A, IRLEN_COARSE_2K),
822 WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A, 1 << (11 - IRLEN_COARSE_2K)),
823 WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A, 1 << (17 - IRLEN_COARSE_2K)),
824 WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A, IRLEN_FINE_2K),
825 WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A, 1 << (11 - IRLEN_FINE_2K)),
826 WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A, 1 << (17 - IRLEN_FINE_2K)),
827
828 WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, 7),
829 WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, 4),
830 WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, 7),
831 WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, 4),
832 WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, 500),
833
834 WR16(B_CC_REG_DIVERSITY__A, 0x0001),
835 END_OF_TABLE
836};
837
838u8 DRXD_DisableDiversity[] = {
839 WR16(B_SC_RA_RAM_LC_ABS_2K__A, B_SC_RA_RAM_LC_ABS_2K__PRE),
840 WR16(B_SC_RA_RAM_LC_ABS_8K__A, B_SC_RA_RAM_LC_ABS_8K__PRE),
841 WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A,
842 B_SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE),
843 WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A,
844 B_SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE),
845 WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A,
846 B_SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE),
847 WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A,
848 B_SC_RA_RAM_IR_FINE_8K_LENGTH__PRE),
849 WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A,
850 B_SC_RA_RAM_IR_FINE_8K_FREQINC__PRE),
851 WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A,
852 B_SC_RA_RAM_IR_FINE_8K_KAISINC__PRE),
853
854 WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A,
855 B_SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE),
856 WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A,
857 B_SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE),
858 WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A,
859 B_SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE),
860 WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A,
861 B_SC_RA_RAM_IR_FINE_2K_LENGTH__PRE),
862 WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A,
863 B_SC_RA_RAM_IR_FINE_2K_FREQINC__PRE),
864 WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A,
865 B_SC_RA_RAM_IR_FINE_2K_KAISINC__PRE),
866
867 WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, B_LC_RA_RAM_FILTER_CRMM_A__PRE),
868 WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, B_LC_RA_RAM_FILTER_CRMM_B__PRE),
869 WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, B_LC_RA_RAM_FILTER_SRMM_A__PRE),
870 WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, B_LC_RA_RAM_FILTER_SRMM_B__PRE),
871 WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, B_LC_RA_RAM_FILTER_SYM_SET__PRE),
872
873 WR16(B_CC_REG_DIVERSITY__A, 0x0000),
874 WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_INIT), /* combining disabled */
875
876 END_OF_TABLE
877};
878
879u8 DRXD_StartDiversityFront[] = {
880 /* Start demod, RF in and diversity out, no combining */
881 WR16(B_FE_CF_REG_IMP_VAL__A, 0x0),
882 WR16(B_FE_AD_REG_FDB_IN__A, 0x0),
883 WR16(B_FE_AD_REG_INVEXT__A, 0x0),
884 WR16(B_EQ_REG_COMM_MB__A, 0x12), /* EQ to MB out */
885 WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_PASS_B_CE | /* CE to PASS mux */
886 B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE | B_EQ_REG_RC_SEL_CAR_MEAS_B_CE),
887
888 WR16(SC_RA_RAM_ECHO_SHIFT_LIM__A, 2),
889
890 END_OF_TABLE
891};
892
893u8 DRXD_StartDiversityEnd[] = {
894 /* End demod, combining RF in and diversity in, MPEG TS out */
895 WR16(B_FE_CF_REG_IMP_VAL__A, 0x0), /* disable impulse noise cruncher */
896 WR16(B_FE_AD_REG_INVEXT__A, 0x0), /* clock inversion (for sohard board) */
897 WR16(B_CP_REG_BR_STR_DEL__A, 10), /* apperently no mb delay matching is best */
898
899 WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_DIV_ON | /* org = 0x81 combining enabled */
900 B_EQ_REG_RC_SEL_CAR_MEAS_A_CC |
901 B_EQ_REG_RC_SEL_CAR_PASS_A_CC | B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC),
902
903 END_OF_TABLE
904};
905
906u8 DRXD_DiversityDelay8MHZ[] = {
907 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A, 1150 - 50),
908 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A, 1100 - 50),
909 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A, 1000 - 50),
910 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A, 800 - 50),
911 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A, 5420 - 50),
912 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A, 5200 - 50),
913 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A, 4800 - 50),
914 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A, 4000 - 50),
915 END_OF_TABLE
916};
917
918u8 DRXD_DiversityDelay6MHZ[] = /* also used ok for 7 MHz */
919{
920 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A, 1100 - 50),
921 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A, 1000 - 50),
922 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A, 900 - 50),
923 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A, 600 - 50),
924 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A, 5300 - 50),
925 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A, 5000 - 50),
926 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A, 4500 - 50),
927 WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A, 3500 - 50),
928 END_OF_TABLE
929};
diff --git a/drivers/media/dvb/frontends/drxd_firm.h b/drivers/media/dvb/frontends/drxd_firm.h
new file mode 100644
index 00000000000..41597e89941
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxd_firm.h
@@ -0,0 +1,115 @@
1/*
2 * drxd_firm.h
3 *
4 * Copyright (C) 2006-2007 Micronas
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
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 *
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., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#ifndef _DRXD_FIRM_H_
25#define _DRXD_FIRM_H_
26
27#include <linux/types.h>
28#include "drxd_map_firm.h"
29
30#define VERSION_MAJOR 1
31#define VERSION_MINOR 4
32#define VERSION_PATCH 23
33
34#define HI_TR_FUNC_ADDR HI_IF_RAM_USR_BEGIN__A
35
36#define DRXD_MAX_RETRIES (1000)
37#define HI_I2C_DELAY 84
38#define HI_I2C_BRIDGE_DELAY 750
39
40#define EQ_TD_TPS_PWR_UNKNOWN 0x00C0 /* Unknown configurations */
41#define EQ_TD_TPS_PWR_QPSK 0x016a
42#define EQ_TD_TPS_PWR_QAM16_ALPHAN 0x0195
43#define EQ_TD_TPS_PWR_QAM16_ALPHA1 0x0195
44#define EQ_TD_TPS_PWR_QAM16_ALPHA2 0x011E
45#define EQ_TD_TPS_PWR_QAM16_ALPHA4 0x01CE
46#define EQ_TD_TPS_PWR_QAM64_ALPHAN 0x019F
47#define EQ_TD_TPS_PWR_QAM64_ALPHA1 0x019F
48#define EQ_TD_TPS_PWR_QAM64_ALPHA2 0x00F8
49#define EQ_TD_TPS_PWR_QAM64_ALPHA4 0x014D
50
51#define DRXD_DEF_AG_PWD_CONSUMER 0x000E
52#define DRXD_DEF_AG_PWD_PRO 0x0000
53#define DRXD_DEF_AG_AGC_SIO 0x0000
54
55#define DRXD_FE_CTRL_MAX 1023
56
57#define DRXD_OSCDEV_DO_SCAN (16)
58
59#define DRXD_OSCDEV_DONT_SCAN (0)
60
61#define DRXD_OSCDEV_STEP (275)
62
63#define DRXD_SCAN_TIMEOUT (650)
64
65#define DRXD_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
66#define DRXD_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
67#define DRXD_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
68
69#define IRLEN_COARSE_8K (10)
70#define IRLEN_FINE_8K (10)
71#define IRLEN_COARSE_2K (7)
72#define IRLEN_FINE_2K (9)
73#define DIFF_INVALID (511)
74#define DIFF_TARGET (4)
75#define DIFF_MARGIN (1)
76
77extern u8 DRXD_InitAtomicRead[];
78extern u8 DRXD_HiI2cPatch_1[];
79extern u8 DRXD_HiI2cPatch_3[];
80
81extern u8 DRXD_InitSC[];
82
83extern u8 DRXD_ResetCEFR[];
84extern u8 DRXD_InitFEA2_1[];
85extern u8 DRXD_InitFEA2_2[];
86extern u8 DRXD_InitCPA2[];
87extern u8 DRXD_InitCEA2[];
88extern u8 DRXD_InitEQA2[];
89extern u8 DRXD_InitECA2[];
90extern u8 DRXD_ResetECA2[];
91extern u8 DRXD_ResetECRAM[];
92
93extern u8 DRXD_A2_microcode[];
94extern u32 DRXD_A2_microcode_length;
95
96extern u8 DRXD_InitFEB1_1[];
97extern u8 DRXD_InitFEB1_2[];
98extern u8 DRXD_InitCPB1[];
99extern u8 DRXD_InitCEB1[];
100extern u8 DRXD_InitEQB1[];
101extern u8 DRXD_InitECB1[];
102
103extern u8 DRXD_InitDiversityFront[];
104extern u8 DRXD_InitDiversityEnd[];
105extern u8 DRXD_DisableDiversity[];
106extern u8 DRXD_StartDiversityFront[];
107extern u8 DRXD_StartDiversityEnd[];
108
109extern u8 DRXD_DiversityDelay8MHZ[];
110extern u8 DRXD_DiversityDelay6MHZ[];
111
112extern u8 DRXD_B1_microcode[];
113extern u32 DRXD_B1_microcode_length;
114
115#endif
diff --git a/drivers/media/dvb/frontends/drxd_hard.c b/drivers/media/dvb/frontends/drxd_hard.c
new file mode 100644
index 00000000000..2238bf0be95
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxd_hard.c
@@ -0,0 +1,3002 @@
1/*
2 * drxd_hard.c: DVB-T Demodulator Micronas DRX3975D-A2,DRX397xD-B1
3 *
4 * Copyright (C) 2003-2007 Micronas
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
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 *
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., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/firmware.h>
30#include <linux/i2c.h>
31#include <asm/div64.h>
32
33#include "dvb_frontend.h"
34#include "drxd.h"
35#include "drxd_firm.h"
36
37#define DRX_FW_FILENAME_A2 "drxd-a2-1.1.fw"
38#define DRX_FW_FILENAME_B1 "drxd-b1-1.1.fw"
39
40#define CHUNK_SIZE 48
41
42#define DRX_I2C_RMW 0x10
43#define DRX_I2C_BROADCAST 0x20
44#define DRX_I2C_CLEARCRC 0x80
45#define DRX_I2C_SINGLE_MASTER 0xC0
46#define DRX_I2C_MODEFLAGS 0xC0
47#define DRX_I2C_FLAGS 0xF0
48
49#ifndef SIZEOF_ARRAY
50#define SIZEOF_ARRAY(array) (sizeof((array))/sizeof((array)[0]))
51#endif
52
53#define DEFAULT_LOCK_TIMEOUT 1100
54
55#define DRX_CHANNEL_AUTO 0
56#define DRX_CHANNEL_HIGH 1
57#define DRX_CHANNEL_LOW 2
58
59#define DRX_LOCK_MPEG 1
60#define DRX_LOCK_FEC 2
61#define DRX_LOCK_DEMOD 4
62
63/****************************************************************************/
64
65enum CSCDState {
66 CSCD_INIT = 0,
67 CSCD_SET,
68 CSCD_SAVED
69};
70
71enum CDrxdState {
72 DRXD_UNINITIALIZED = 0,
73 DRXD_STOPPED,
74 DRXD_STARTED
75};
76
77enum AGC_CTRL_MODE {
78 AGC_CTRL_AUTO = 0,
79 AGC_CTRL_USER,
80 AGC_CTRL_OFF
81};
82
83enum OperationMode {
84 OM_Default,
85 OM_DVBT_Diversity_Front,
86 OM_DVBT_Diversity_End
87};
88
89struct SCfgAgc {
90 enum AGC_CTRL_MODE ctrlMode;
91 u16 outputLevel; /* range [0, ... , 1023], 1/n of fullscale range */
92 u16 settleLevel; /* range [0, ... , 1023], 1/n of fullscale range */
93 u16 minOutputLevel; /* range [0, ... , 1023], 1/n of fullscale range */
94 u16 maxOutputLevel; /* range [0, ... , 1023], 1/n of fullscale range */
95 u16 speed; /* range [0, ... , 1023], 1/n of fullscale range */
96
97 u16 R1;
98 u16 R2;
99 u16 R3;
100};
101
102struct SNoiseCal {
103 int cpOpt;
104 u16 cpNexpOfs;
105 u16 tdCal2k;
106 u16 tdCal8k;
107};
108
109enum app_env {
110 APPENV_STATIC = 0,
111 APPENV_PORTABLE = 1,
112 APPENV_MOBILE = 2
113};
114
115enum EIFFilter {
116 IFFILTER_SAW = 0,
117 IFFILTER_DISCRETE = 1
118};
119
120struct drxd_state {
121 struct dvb_frontend frontend;
122 struct dvb_frontend_ops ops;
123 struct dvb_frontend_parameters param;
124
125 const struct firmware *fw;
126 struct device *dev;
127
128 struct i2c_adapter *i2c;
129 void *priv;
130 struct drxd_config config;
131
132 int i2c_access;
133 int init_done;
134 struct mutex mutex;
135
136 u8 chip_adr;
137 u16 hi_cfg_timing_div;
138 u16 hi_cfg_bridge_delay;
139 u16 hi_cfg_wakeup_key;
140 u16 hi_cfg_ctrl;
141
142 u16 intermediate_freq;
143 u16 osc_clock_freq;
144
145 enum CSCDState cscd_state;
146 enum CDrxdState drxd_state;
147
148 u16 sys_clock_freq;
149 s16 osc_clock_deviation;
150 u16 expected_sys_clock_freq;
151
152 u16 insert_rs_byte;
153 u16 enable_parallel;
154
155 int operation_mode;
156
157 struct SCfgAgc if_agc_cfg;
158 struct SCfgAgc rf_agc_cfg;
159
160 struct SNoiseCal noise_cal;
161
162 u32 fe_fs_add_incr;
163 u32 org_fe_fs_add_incr;
164 u16 current_fe_if_incr;
165
166 u16 m_FeAgRegAgPwd;
167 u16 m_FeAgRegAgAgcSio;
168
169 u16 m_EcOcRegOcModeLop;
170 u16 m_EcOcRegSncSncLvl;
171 u8 *m_InitAtomicRead;
172 u8 *m_HiI2cPatch;
173
174 u8 *m_ResetCEFR;
175 u8 *m_InitFE_1;
176 u8 *m_InitFE_2;
177 u8 *m_InitCP;
178 u8 *m_InitCE;
179 u8 *m_InitEQ;
180 u8 *m_InitSC;
181 u8 *m_InitEC;
182 u8 *m_ResetECRAM;
183 u8 *m_InitDiversityFront;
184 u8 *m_InitDiversityEnd;
185 u8 *m_DisableDiversity;
186 u8 *m_StartDiversityFront;
187 u8 *m_StartDiversityEnd;
188
189 u8 *m_DiversityDelay8MHZ;
190 u8 *m_DiversityDelay6MHZ;
191
192 u8 *microcode;
193 u32 microcode_length;
194
195 int type_A;
196 int PGA;
197 int diversity;
198 int tuner_mirrors;
199
200 enum app_env app_env_default;
201 enum app_env app_env_diversity;
202
203};
204
205/****************************************************************************/
206/* I2C **********************************************************************/
207/****************************************************************************/
208
209static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 * data, int len)
210{
211 struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = data, .len = len };
212
213 if (i2c_transfer(adap, &msg, 1) != 1)
214 return -1;
215 return 0;
216}
217
218static int i2c_read(struct i2c_adapter *adap,
219 u8 adr, u8 *msg, int len, u8 *answ, int alen)
220{
221 struct i2c_msg msgs[2] = {
222 {
223 .addr = adr, .flags = 0,
224 .buf = msg, .len = len
225 }, {
226 .addr = adr, .flags = I2C_M_RD,
227 .buf = answ, .len = alen
228 }
229 };
230 if (i2c_transfer(adap, msgs, 2) != 2)
231 return -1;
232 return 0;
233}
234
235static inline u32 MulDiv32(u32 a, u32 b, u32 c)
236{
237 u64 tmp64;
238
239 tmp64 = (u64)a * (u64)b;
240 do_div(tmp64, c);
241
242 return (u32) tmp64;
243}
244
245static int Read16(struct drxd_state *state, u32 reg, u16 *data, u8 flags)
246{
247 u8 adr = state->config.demod_address;
248 u8 mm1[4] = { reg & 0xff, (reg >> 16) & 0xff,
249 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
250 };
251 u8 mm2[2];
252 if (i2c_read(state->i2c, adr, mm1, 4, mm2, 2) < 0)
253 return -1;
254 if (data)
255 *data = mm2[0] | (mm2[1] << 8);
256 return mm2[0] | (mm2[1] << 8);
257}
258
259static int Read32(struct drxd_state *state, u32 reg, u32 *data, u8 flags)
260{
261 u8 adr = state->config.demod_address;
262 u8 mm1[4] = { reg & 0xff, (reg >> 16) & 0xff,
263 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
264 };
265 u8 mm2[4];
266
267 if (i2c_read(state->i2c, adr, mm1, 4, mm2, 4) < 0)
268 return -1;
269 if (data)
270 *data =
271 mm2[0] | (mm2[1] << 8) | (mm2[2] << 16) | (mm2[3] << 24);
272 return 0;
273}
274
275static int Write16(struct drxd_state *state, u32 reg, u16 data, u8 flags)
276{
277 u8 adr = state->config.demod_address;
278 u8 mm[6] = { reg & 0xff, (reg >> 16) & 0xff,
279 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff,
280 data & 0xff, (data >> 8) & 0xff
281 };
282
283 if (i2c_write(state->i2c, adr, mm, 6) < 0)
284 return -1;
285 return 0;
286}
287
288static int Write32(struct drxd_state *state, u32 reg, u32 data, u8 flags)
289{
290 u8 adr = state->config.demod_address;
291 u8 mm[8] = { reg & 0xff, (reg >> 16) & 0xff,
292 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff,
293 data & 0xff, (data >> 8) & 0xff,
294 (data >> 16) & 0xff, (data >> 24) & 0xff
295 };
296
297 if (i2c_write(state->i2c, adr, mm, 8) < 0)
298 return -1;
299 return 0;
300}
301
302static int write_chunk(struct drxd_state *state,
303 u32 reg, u8 *data, u32 len, u8 flags)
304{
305 u8 adr = state->config.demod_address;
306 u8 mm[CHUNK_SIZE + 4] = { reg & 0xff, (reg >> 16) & 0xff,
307 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
308 };
309 int i;
310
311 for (i = 0; i < len; i++)
312 mm[4 + i] = data[i];
313 if (i2c_write(state->i2c, adr, mm, 4 + len) < 0) {
314 printk(KERN_ERR "error in write_chunk\n");
315 return -1;
316 }
317 return 0;
318}
319
320static int WriteBlock(struct drxd_state *state,
321 u32 Address, u16 BlockSize, u8 *pBlock, u8 Flags)
322{
323 while (BlockSize > 0) {
324 u16 Chunk = BlockSize > CHUNK_SIZE ? CHUNK_SIZE : BlockSize;
325
326 if (write_chunk(state, Address, pBlock, Chunk, Flags) < 0)
327 return -1;
328 pBlock += Chunk;
329 Address += (Chunk >> 1);
330 BlockSize -= Chunk;
331 }
332 return 0;
333}
334
335static int WriteTable(struct drxd_state *state, u8 * pTable)
336{
337 int status = 0;
338
339 if (pTable == NULL)
340 return 0;
341
342 while (!status) {
343 u16 Length;
344 u32 Address = pTable[0] | (pTable[1] << 8) |
345 (pTable[2] << 16) | (pTable[3] << 24);
346
347 if (Address == 0xFFFFFFFF)
348 break;
349 pTable += sizeof(u32);
350
351 Length = pTable[0] | (pTable[1] << 8);
352 pTable += sizeof(u16);
353 if (!Length)
354 break;
355 status = WriteBlock(state, Address, Length * 2, pTable, 0);
356 pTable += (Length * 2);
357 }
358 return status;
359}
360
361/****************************************************************************/
362/****************************************************************************/
363/****************************************************************************/
364
365static int ResetCEFR(struct drxd_state *state)
366{
367 return WriteTable(state, state->m_ResetCEFR);
368}
369
370static int InitCP(struct drxd_state *state)
371{
372 return WriteTable(state, state->m_InitCP);
373}
374
375static int InitCE(struct drxd_state *state)
376{
377 int status;
378 enum app_env AppEnv = state->app_env_default;
379
380 do {
381 status = WriteTable(state, state->m_InitCE);
382 if (status < 0)
383 break;
384
385 if (state->operation_mode == OM_DVBT_Diversity_Front ||
386 state->operation_mode == OM_DVBT_Diversity_End) {
387 AppEnv = state->app_env_diversity;
388 }
389 if (AppEnv == APPENV_STATIC) {
390 status = Write16(state, CE_REG_TAPSET__A, 0x0000, 0);
391 if (status < 0)
392 break;
393 } else if (AppEnv == APPENV_PORTABLE) {
394 status = Write16(state, CE_REG_TAPSET__A, 0x0001, 0);
395 if (status < 0)
396 break;
397 } else if (AppEnv == APPENV_MOBILE && state->type_A) {
398 status = Write16(state, CE_REG_TAPSET__A, 0x0002, 0);
399 if (status < 0)
400 break;
401 } else if (AppEnv == APPENV_MOBILE && !state->type_A) {
402 status = Write16(state, CE_REG_TAPSET__A, 0x0006, 0);
403 if (status < 0)
404 break;
405 }
406
407 /* start ce */
408 status = Write16(state, B_CE_REG_COMM_EXEC__A, 0x0001, 0);
409 if (status < 0)
410 break;
411 } while (0);
412 return status;
413}
414
415static int StopOC(struct drxd_state *state)
416{
417 int status = 0;
418 u16 ocSyncLvl = 0;
419 u16 ocModeLop = state->m_EcOcRegOcModeLop;
420 u16 dtoIncLop = 0;
421 u16 dtoIncHip = 0;
422
423 do {
424 /* Store output configuration */
425 status = Read16(state, EC_OC_REG_SNC_ISC_LVL__A, &ocSyncLvl, 0);
426 if (status < 0)
427 break;
428 /* CHK_ERROR(Read16(EC_OC_REG_OC_MODE_LOP__A, &ocModeLop)); */
429 state->m_EcOcRegSncSncLvl = ocSyncLvl;
430 /* m_EcOcRegOcModeLop = ocModeLop; */
431
432 /* Flush FIFO (byte-boundary) at fixed rate */
433 status = Read16(state, EC_OC_REG_RCN_MAP_LOP__A, &dtoIncLop, 0);
434 if (status < 0)
435 break;
436 status = Read16(state, EC_OC_REG_RCN_MAP_HIP__A, &dtoIncHip, 0);
437 if (status < 0)
438 break;
439 status = Write16(state, EC_OC_REG_DTO_INC_LOP__A, dtoIncLop, 0);
440 if (status < 0)
441 break;
442 status = Write16(state, EC_OC_REG_DTO_INC_HIP__A, dtoIncHip, 0);
443 if (status < 0)
444 break;
445 ocModeLop &= ~(EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M);
446 ocModeLop |= EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC;
447 status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, ocModeLop, 0);
448 if (status < 0)
449 break;
450 status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_HOLD, 0);
451 if (status < 0)
452 break;
453
454 msleep(1);
455 /* Output pins to '0' */
456 status = Write16(state, EC_OC_REG_OCR_MPG_UOS__A, EC_OC_REG_OCR_MPG_UOS__M, 0);
457 if (status < 0)
458 break;
459
460 /* Force the OC out of sync */
461 ocSyncLvl &= ~(EC_OC_REG_SNC_ISC_LVL_OSC__M);
462 status = Write16(state, EC_OC_REG_SNC_ISC_LVL__A, ocSyncLvl, 0);
463 if (status < 0)
464 break;
465 ocModeLop &= ~(EC_OC_REG_OC_MODE_LOP_PAR_ENA__M);
466 ocModeLop |= EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE;
467 ocModeLop |= 0x2; /* Magically-out-of-sync */
468 status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, ocModeLop, 0);
469 if (status < 0)
470 break;
471 status = Write16(state, EC_OC_REG_COMM_INT_STA__A, 0x0, 0);
472 if (status < 0)
473 break;
474 status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_ACTIVE, 0);
475 if (status < 0)
476 break;
477 } while (0);
478
479 return status;
480}
481
482static int StartOC(struct drxd_state *state)
483{
484 int status = 0;
485
486 do {
487 /* Stop OC */
488 status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_HOLD, 0);
489 if (status < 0)
490 break;
491
492 /* Restore output configuration */
493 status = Write16(state, EC_OC_REG_SNC_ISC_LVL__A, state->m_EcOcRegSncSncLvl, 0);
494 if (status < 0)
495 break;
496 status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, state->m_EcOcRegOcModeLop, 0);
497 if (status < 0)
498 break;
499
500 /* Output pins active again */
501 status = Write16(state, EC_OC_REG_OCR_MPG_UOS__A, EC_OC_REG_OCR_MPG_UOS_INIT, 0);
502 if (status < 0)
503 break;
504
505 /* Start OC */
506 status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_ACTIVE, 0);
507 if (status < 0)
508 break;
509 } while (0);
510 return status;
511}
512
513static int InitEQ(struct drxd_state *state)
514{
515 return WriteTable(state, state->m_InitEQ);
516}
517
518static int InitEC(struct drxd_state *state)
519{
520 return WriteTable(state, state->m_InitEC);
521}
522
523static int InitSC(struct drxd_state *state)
524{
525 return WriteTable(state, state->m_InitSC);
526}
527
528static int InitAtomicRead(struct drxd_state *state)
529{
530 return WriteTable(state, state->m_InitAtomicRead);
531}
532
533static int CorrectSysClockDeviation(struct drxd_state *state);
534
535static int DRX_GetLockStatus(struct drxd_state *state, u32 * pLockStatus)
536{
537 u16 ScRaRamLock = 0;
538 const u16 mpeg_lock_mask = (SC_RA_RAM_LOCK_MPEG__M |
539 SC_RA_RAM_LOCK_FEC__M |
540 SC_RA_RAM_LOCK_DEMOD__M);
541 const u16 fec_lock_mask = (SC_RA_RAM_LOCK_FEC__M |
542 SC_RA_RAM_LOCK_DEMOD__M);
543 const u16 demod_lock_mask = SC_RA_RAM_LOCK_DEMOD__M;
544
545 int status;
546
547 *pLockStatus = 0;
548
549 status = Read16(state, SC_RA_RAM_LOCK__A, &ScRaRamLock, 0x0000);
550 if (status < 0) {
551 printk(KERN_ERR "Can't read SC_RA_RAM_LOCK__A status = %08x\n", status);
552 return status;
553 }
554
555 if (state->drxd_state != DRXD_STARTED)
556 return 0;
557
558 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask) {
559 *pLockStatus |= DRX_LOCK_MPEG;
560 CorrectSysClockDeviation(state);
561 }
562
563 if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
564 *pLockStatus |= DRX_LOCK_FEC;
565
566 if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
567 *pLockStatus |= DRX_LOCK_DEMOD;
568 return 0;
569}
570
571/****************************************************************************/
572
573static int SetCfgIfAgc(struct drxd_state *state, struct SCfgAgc *cfg)
574{
575 int status;
576
577 if (cfg->outputLevel > DRXD_FE_CTRL_MAX)
578 return -1;
579
580 if (cfg->ctrlMode == AGC_CTRL_USER) {
581 do {
582 u16 FeAgRegPm1AgcWri;
583 u16 FeAgRegAgModeLop;
584
585 status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &FeAgRegAgModeLop, 0);
586 if (status < 0)
587 break;
588 FeAgRegAgModeLop &= (~FE_AG_REG_AG_MODE_LOP_MODE_4__M);
589 FeAgRegAgModeLop |= FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC;
590 status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, FeAgRegAgModeLop, 0);
591 if (status < 0)
592 break;
593
594 FeAgRegPm1AgcWri = (u16) (cfg->outputLevel &
595 FE_AG_REG_PM1_AGC_WRI__M);
596 status = Write16(state, FE_AG_REG_PM1_AGC_WRI__A, FeAgRegPm1AgcWri, 0);
597 if (status < 0)
598 break;
599 } while (0);
600 } else if (cfg->ctrlMode == AGC_CTRL_AUTO) {
601 if (((cfg->maxOutputLevel) < (cfg->minOutputLevel)) ||
602 ((cfg->maxOutputLevel) > DRXD_FE_CTRL_MAX) ||
603 ((cfg->speed) > DRXD_FE_CTRL_MAX) ||
604 ((cfg->settleLevel) > DRXD_FE_CTRL_MAX)
605 )
606 return -1;
607 do {
608 u16 FeAgRegAgModeLop;
609 u16 FeAgRegEgcSetLvl;
610 u16 slope, offset;
611
612 /* == Mode == */
613
614 status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &FeAgRegAgModeLop, 0);
615 if (status < 0)
616 break;
617 FeAgRegAgModeLop &= (~FE_AG_REG_AG_MODE_LOP_MODE_4__M);
618 FeAgRegAgModeLop |=
619 FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC;
620 status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, FeAgRegAgModeLop, 0);
621 if (status < 0)
622 break;
623
624 /* == Settle level == */
625
626 FeAgRegEgcSetLvl = (u16) ((cfg->settleLevel >> 1) &
627 FE_AG_REG_EGC_SET_LVL__M);
628 status = Write16(state, FE_AG_REG_EGC_SET_LVL__A, FeAgRegEgcSetLvl, 0);
629 if (status < 0)
630 break;
631
632 /* == Min/Max == */
633
634 slope = (u16) ((cfg->maxOutputLevel -
635 cfg->minOutputLevel) / 2);
636 offset = (u16) ((cfg->maxOutputLevel +
637 cfg->minOutputLevel) / 2 - 511);
638
639 status = Write16(state, FE_AG_REG_GC1_AGC_RIC__A, slope, 0);
640 if (status < 0)
641 break;
642 status = Write16(state, FE_AG_REG_GC1_AGC_OFF__A, offset, 0);
643 if (status < 0)
644 break;
645
646 /* == Speed == */
647 {
648 const u16 maxRur = 8;
649 const u16 slowIncrDecLUT[] = { 3, 4, 4, 5, 6 };
650 const u16 fastIncrDecLUT[] = { 14, 15, 15, 16,
651 17, 18, 18, 19,
652 20, 21, 22, 23,
653 24, 26, 27, 28,
654 29, 31
655 };
656
657 u16 fineSteps = (DRXD_FE_CTRL_MAX + 1) /
658 (maxRur + 1);
659 u16 fineSpeed = (u16) (cfg->speed -
660 ((cfg->speed /
661 fineSteps) *
662 fineSteps));
663 u16 invRurCount = (u16) (cfg->speed /
664 fineSteps);
665 u16 rurCount;
666 if (invRurCount > maxRur) {
667 rurCount = 0;
668 fineSpeed += fineSteps;
669 } else {
670 rurCount = maxRur - invRurCount;
671 }
672
673 /*
674 fastInc = default *
675 (2^(fineSpeed/fineSteps))
676 => range[default...2*default>
677 slowInc = default *
678 (2^(fineSpeed/fineSteps))
679 */
680 {
681 u16 fastIncrDec =
682 fastIncrDecLUT[fineSpeed /
683 ((fineSteps /
684 (14 + 1)) + 1)];
685 u16 slowIncrDec =
686 slowIncrDecLUT[fineSpeed /
687 (fineSteps /
688 (3 + 1))];
689
690 status = Write16(state, FE_AG_REG_EGC_RUR_CNT__A, rurCount, 0);
691 if (status < 0)
692 break;
693 status = Write16(state, FE_AG_REG_EGC_FAS_INC__A, fastIncrDec, 0);
694 if (status < 0)
695 break;
696 status = Write16(state, FE_AG_REG_EGC_FAS_DEC__A, fastIncrDec, 0);
697 if (status < 0)
698 break;
699 status = Write16(state, FE_AG_REG_EGC_SLO_INC__A, slowIncrDec, 0);
700 if (status < 0)
701 break;
702 status = Write16(state, FE_AG_REG_EGC_SLO_DEC__A, slowIncrDec, 0);
703 if (status < 0)
704 break;
705 }
706 }
707 } while (0);
708
709 } else {
710 /* No OFF mode for IF control */
711 return -1;
712 }
713 return status;
714}
715
716static int SetCfgRfAgc(struct drxd_state *state, struct SCfgAgc *cfg)
717{
718 int status = 0;
719
720 if (cfg->outputLevel > DRXD_FE_CTRL_MAX)
721 return -1;
722
723 if (cfg->ctrlMode == AGC_CTRL_USER) {
724 do {
725 u16 AgModeLop = 0;
726 u16 level = (cfg->outputLevel);
727
728 if (level == DRXD_FE_CTRL_MAX)
729 level++;
730
731 status = Write16(state, FE_AG_REG_PM2_AGC_WRI__A, level, 0x0000);
732 if (status < 0)
733 break;
734
735 /*==== Mode ====*/
736
737 /* Powerdown PD2, WRI source */
738 state->m_FeAgRegAgPwd &= ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
739 state->m_FeAgRegAgPwd |=
740 FE_AG_REG_AG_PWD_PWD_PD2_DISABLE;
741 status = Write16(state, FE_AG_REG_AG_PWD__A, state->m_FeAgRegAgPwd, 0x0000);
742 if (status < 0)
743 break;
744
745 status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
746 if (status < 0)
747 break;
748 AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
749 FE_AG_REG_AG_MODE_LOP_MODE_E__M));
750 AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
751 FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC);
752 status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
753 if (status < 0)
754 break;
755
756 /* enable AGC2 pin */
757 {
758 u16 FeAgRegAgAgcSio = 0;
759 status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
760 if (status < 0)
761 break;
762 FeAgRegAgAgcSio &=
763 ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
764 FeAgRegAgAgcSio |=
765 FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT;
766 status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
767 if (status < 0)
768 break;
769 }
770
771 } while (0);
772 } else if (cfg->ctrlMode == AGC_CTRL_AUTO) {
773 u16 AgModeLop = 0;
774
775 do {
776 u16 level;
777 /* Automatic control */
778 /* Powerup PD2, AGC2 as output, TGC source */
779 (state->m_FeAgRegAgPwd) &=
780 ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
781 (state->m_FeAgRegAgPwd) |=
782 FE_AG_REG_AG_PWD_PWD_PD2_DISABLE;
783 status = Write16(state, FE_AG_REG_AG_PWD__A, (state->m_FeAgRegAgPwd), 0x0000);
784 if (status < 0)
785 break;
786
787 status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
788 if (status < 0)
789 break;
790 AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
791 FE_AG_REG_AG_MODE_LOP_MODE_E__M));
792 AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
793 FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC);
794 status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
795 if (status < 0)
796 break;
797 /* Settle level */
798 level = (((cfg->settleLevel) >> 4) &
799 FE_AG_REG_TGC_SET_LVL__M);
800 status = Write16(state, FE_AG_REG_TGC_SET_LVL__A, level, 0x0000);
801 if (status < 0)
802 break;
803
804 /* Min/max: don't care */
805
806 /* Speed: TODO */
807
808 /* enable AGC2 pin */
809 {
810 u16 FeAgRegAgAgcSio = 0;
811 status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
812 if (status < 0)
813 break;
814 FeAgRegAgAgcSio &=
815 ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
816 FeAgRegAgAgcSio |=
817 FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT;
818 status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
819 if (status < 0)
820 break;
821 }
822
823 } while (0);
824 } else {
825 u16 AgModeLop = 0;
826
827 do {
828 /* No RF AGC control */
829 /* Powerdown PD2, AGC2 as output, WRI source */
830 (state->m_FeAgRegAgPwd) &=
831 ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
832 (state->m_FeAgRegAgPwd) |=
833 FE_AG_REG_AG_PWD_PWD_PD2_ENABLE;
834 status = Write16(state, FE_AG_REG_AG_PWD__A, (state->m_FeAgRegAgPwd), 0x0000);
835 if (status < 0)
836 break;
837
838 status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
839 if (status < 0)
840 break;
841 AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
842 FE_AG_REG_AG_MODE_LOP_MODE_E__M));
843 AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
844 FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC);
845 status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
846 if (status < 0)
847 break;
848
849 /* set FeAgRegAgAgcSio AGC2 (RF) as input */
850 {
851 u16 FeAgRegAgAgcSio = 0;
852 status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
853 if (status < 0)
854 break;
855 FeAgRegAgAgcSio &=
856 ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
857 FeAgRegAgAgcSio |=
858 FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT;
859 status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
860 if (status < 0)
861 break;
862 }
863 } while (0);
864 }
865 return status;
866}
867
868static int ReadIFAgc(struct drxd_state *state, u32 * pValue)
869{
870 int status = 0;
871
872 *pValue = 0;
873 if (state->if_agc_cfg.ctrlMode != AGC_CTRL_OFF) {
874 u16 Value;
875 status = Read16(state, FE_AG_REG_GC1_AGC_DAT__A, &Value, 0);
876 Value &= FE_AG_REG_GC1_AGC_DAT__M;
877 if (status >= 0) {
878 /* 3.3V
879 |
880 R1
881 |
882 Vin - R3 - * -- Vout
883 |
884 R2
885 |
886 GND
887 */
888 u32 R1 = state->if_agc_cfg.R1;
889 u32 R2 = state->if_agc_cfg.R2;
890 u32 R3 = state->if_agc_cfg.R3;
891
892 u32 Vmax = (3300 * R2) / (R1 + R2);
893 u32 Rpar = (R2 * R3) / (R3 + R2);
894 u32 Vmin = (3300 * Rpar) / (R1 + Rpar);
895 u32 Vout = Vmin + ((Vmax - Vmin) * Value) / 1024;
896
897 *pValue = Vout;
898 }
899 }
900 return status;
901}
902
903static int load_firmware(struct drxd_state *state, const char *fw_name)
904{
905 const struct firmware *fw;
906
907 if (request_firmware(&fw, fw_name, state->dev) < 0) {
908 printk(KERN_ERR "drxd: firmware load failure [%s]\n", fw_name);
909 return -EIO;
910 }
911
912 state->microcode = kmalloc(fw->size, GFP_KERNEL);
913 if (state->microcode == NULL) {
914 release_firmware(fw);
915 printk(KERN_ERR "drxd: firmware load failure: no memory\n");
916 return -ENOMEM;
917 }
918
919 memcpy(state->microcode, fw->data, fw->size);
920 state->microcode_length = fw->size;
921 release_firmware(fw);
922 return 0;
923}
924
925static int DownloadMicrocode(struct drxd_state *state,
926 const u8 *pMCImage, u32 Length)
927{
928 u8 *pSrc;
929 u16 Flags;
930 u32 Address;
931 u16 nBlocks;
932 u16 BlockSize;
933 u16 BlockCRC;
934 u32 offset = 0;
935 int i, status = 0;
936
937 pSrc = (u8 *) pMCImage;
938 Flags = (pSrc[0] << 8) | pSrc[1];
939 pSrc += sizeof(u16);
940 offset += sizeof(u16);
941 nBlocks = (pSrc[0] << 8) | pSrc[1];
942 pSrc += sizeof(u16);
943 offset += sizeof(u16);
944
945 for (i = 0; i < nBlocks; i++) {
946 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
947 (pSrc[2] << 8) | pSrc[3];
948 pSrc += sizeof(u32);
949 offset += sizeof(u32);
950
951 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
952 pSrc += sizeof(u16);
953 offset += sizeof(u16);
954
955 Flags = (pSrc[0] << 8) | pSrc[1];
956 pSrc += sizeof(u16);
957 offset += sizeof(u16);
958
959 BlockCRC = (pSrc[0] << 8) | pSrc[1];
960 pSrc += sizeof(u16);
961 offset += sizeof(u16);
962
963 status = WriteBlock(state, Address, BlockSize,
964 pSrc, DRX_I2C_CLEARCRC);
965 if (status < 0)
966 break;
967 pSrc += BlockSize;
968 offset += BlockSize;
969 }
970
971 return status;
972}
973
974static int HI_Command(struct drxd_state *state, u16 cmd, u16 * pResult)
975{
976 u32 nrRetries = 0;
977 u16 waitCmd;
978 int status;
979
980 status = Write16(state, HI_RA_RAM_SRV_CMD__A, cmd, 0);
981 if (status < 0)
982 return status;
983
984 do {
985 nrRetries += 1;
986 if (nrRetries > DRXD_MAX_RETRIES) {
987 status = -1;
988 break;
989 };
990 status = Read16(state, HI_RA_RAM_SRV_CMD__A, &waitCmd, 0);
991 } while (waitCmd != 0);
992
993 if (status >= 0)
994 status = Read16(state, HI_RA_RAM_SRV_RES__A, pResult, 0);
995 return status;
996}
997
998static int HI_CfgCommand(struct drxd_state *state)
999{
1000 int status = 0;
1001
1002 mutex_lock(&state->mutex);
1003 Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, HI_RA_RAM_SRV_RST_KEY_ACT, 0);
1004 Write16(state, HI_RA_RAM_SRV_CFG_DIV__A, state->hi_cfg_timing_div, 0);
1005 Write16(state, HI_RA_RAM_SRV_CFG_BDL__A, state->hi_cfg_bridge_delay, 0);
1006 Write16(state, HI_RA_RAM_SRV_CFG_WUP__A, state->hi_cfg_wakeup_key, 0);
1007 Write16(state, HI_RA_RAM_SRV_CFG_ACT__A, state->hi_cfg_ctrl, 0);
1008
1009 Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, HI_RA_RAM_SRV_RST_KEY_ACT, 0);
1010
1011 if ((state->hi_cfg_ctrl & HI_RA_RAM_SRV_CFG_ACT_PWD_EXE) ==
1012 HI_RA_RAM_SRV_CFG_ACT_PWD_EXE)
1013 status = Write16(state, HI_RA_RAM_SRV_CMD__A,
1014 HI_RA_RAM_SRV_CMD_CONFIG, 0);
1015 else
1016 status = HI_Command(state, HI_RA_RAM_SRV_CMD_CONFIG, 0);
1017 mutex_unlock(&state->mutex);
1018 return status;
1019}
1020
1021static int InitHI(struct drxd_state *state)
1022{
1023 state->hi_cfg_wakeup_key = (state->chip_adr);
1024 /* port/bridge/power down ctrl */
1025 state->hi_cfg_ctrl = HI_RA_RAM_SRV_CFG_ACT_SLV0_ON;
1026 return HI_CfgCommand(state);
1027}
1028
1029static int HI_ResetCommand(struct drxd_state *state)
1030{
1031 int status;
1032
1033 mutex_lock(&state->mutex);
1034 status = Write16(state, HI_RA_RAM_SRV_RST_KEY__A,
1035 HI_RA_RAM_SRV_RST_KEY_ACT, 0);
1036 if (status == 0)
1037 status = HI_Command(state, HI_RA_RAM_SRV_CMD_RESET, 0);
1038 mutex_unlock(&state->mutex);
1039 msleep(1);
1040 return status;
1041}
1042
1043static int DRX_ConfigureI2CBridge(struct drxd_state *state, int bEnableBridge)
1044{
1045 state->hi_cfg_ctrl &= (~HI_RA_RAM_SRV_CFG_ACT_BRD__M);
1046 if (bEnableBridge)
1047 state->hi_cfg_ctrl |= HI_RA_RAM_SRV_CFG_ACT_BRD_ON;
1048 else
1049 state->hi_cfg_ctrl |= HI_RA_RAM_SRV_CFG_ACT_BRD_OFF;
1050
1051 return HI_CfgCommand(state);
1052}
1053
1054#define HI_TR_WRITE 0x9
1055#define HI_TR_READ 0xA
1056#define HI_TR_READ_WRITE 0xB
1057#define HI_TR_BROADCAST 0x4
1058
1059#if 0
1060static int AtomicReadBlock(struct drxd_state *state,
1061 u32 Addr, u16 DataSize, u8 *pData, u8 Flags)
1062{
1063 int status;
1064 int i = 0;
1065
1066 /* Parameter check */
1067 if ((!pData) || ((DataSize & 1) != 0))
1068 return -1;
1069
1070 mutex_lock(&state->mutex);
1071
1072 do {
1073 /* Instruct HI to read n bytes */
1074 /* TODO use proper names forthese egisters */
1075 status = Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, (HI_TR_FUNC_ADDR & 0xFFFF), 0);
1076 if (status < 0)
1077 break;
1078 status = Write16(state, HI_RA_RAM_SRV_CFG_DIV__A, (u16) (Addr >> 16), 0);
1079 if (status < 0)
1080 break;
1081 status = Write16(state, HI_RA_RAM_SRV_CFG_BDL__A, (u16) (Addr & 0xFFFF), 0);
1082 if (status < 0)
1083 break;
1084 status = Write16(state, HI_RA_RAM_SRV_CFG_WUP__A, (u16) ((DataSize / 2) - 1), 0);
1085 if (status < 0)
1086 break;
1087 status = Write16(state, HI_RA_RAM_SRV_CFG_ACT__A, HI_TR_READ, 0);
1088 if (status < 0)
1089 break;
1090
1091 status = HI_Command(state, HI_RA_RAM_SRV_CMD_EXECUTE, 0);
1092 if (status < 0)
1093 break;
1094
1095 } while (0);
1096
1097 if (status >= 0) {
1098 for (i = 0; i < (DataSize / 2); i += 1) {
1099 u16 word;
1100
1101 status = Read16(state, (HI_RA_RAM_USR_BEGIN__A + i),
1102 &word, 0);
1103 if (status < 0)
1104 break;
1105 pData[2 * i] = (u8) (word & 0xFF);
1106 pData[(2 * i) + 1] = (u8) (word >> 8);
1107 }
1108 }
1109 mutex_unlock(&state->mutex);
1110 return status;
1111}
1112
1113static int AtomicReadReg32(struct drxd_state *state,
1114 u32 Addr, u32 *pData, u8 Flags)
1115{
1116 u8 buf[sizeof(u32)];
1117 int status;
1118
1119 if (!pData)
1120 return -1;
1121 status = AtomicReadBlock(state, Addr, sizeof(u32), buf, Flags);
1122 *pData = (((u32) buf[0]) << 0) +
1123 (((u32) buf[1]) << 8) +
1124 (((u32) buf[2]) << 16) + (((u32) buf[3]) << 24);
1125 return status;
1126}
1127#endif
1128
1129static int StopAllProcessors(struct drxd_state *state)
1130{
1131 return Write16(state, HI_COMM_EXEC__A,
1132 SC_COMM_EXEC_CTL_STOP, DRX_I2C_BROADCAST);
1133}
1134
1135static int EnableAndResetMB(struct drxd_state *state)
1136{
1137 if (state->type_A) {
1138 /* disable? monitor bus observe @ EC_OC */
1139 Write16(state, EC_OC_REG_OC_MON_SIO__A, 0x0000, 0x0000);
1140 }
1141
1142 /* do inverse broadcast, followed by explicit write to HI */
1143 Write16(state, HI_COMM_MB__A, 0x0000, DRX_I2C_BROADCAST);
1144 Write16(state, HI_COMM_MB__A, 0x0000, 0x0000);
1145 return 0;
1146}
1147
1148static int InitCC(struct drxd_state *state)
1149{
1150 if (state->osc_clock_freq == 0 ||
1151 state->osc_clock_freq > 20000 ||
1152 (state->osc_clock_freq % 4000) != 0) {
1153 printk(KERN_ERR "invalid osc frequency %d\n", state->osc_clock_freq);
1154 return -1;
1155 }
1156
1157 Write16(state, CC_REG_OSC_MODE__A, CC_REG_OSC_MODE_M20, 0);
1158 Write16(state, CC_REG_PLL_MODE__A, CC_REG_PLL_MODE_BYPASS_PLL |
1159 CC_REG_PLL_MODE_PUMP_CUR_12, 0);
1160 Write16(state, CC_REG_REF_DIVIDE__A, state->osc_clock_freq / 4000, 0);
1161 Write16(state, CC_REG_PWD_MODE__A, CC_REG_PWD_MODE_DOWN_PLL, 0);
1162 Write16(state, CC_REG_UPDATE__A, CC_REG_UPDATE_KEY, 0);
1163
1164 return 0;
1165}
1166
1167static int ResetECOD(struct drxd_state *state)
1168{
1169 int status = 0;
1170
1171 if (state->type_A)
1172 status = Write16(state, EC_OD_REG_SYNC__A, 0x0664, 0);
1173 else
1174 status = Write16(state, B_EC_OD_REG_SYNC__A, 0x0664, 0);
1175
1176 if (!(status < 0))
1177 status = WriteTable(state, state->m_ResetECRAM);
1178 if (!(status < 0))
1179 status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0001, 0);
1180 return status;
1181}
1182
1183/* Configure PGA switch */
1184
1185static int SetCfgPga(struct drxd_state *state, int pgaSwitch)
1186{
1187 int status;
1188 u16 AgModeLop = 0;
1189 u16 AgModeHip = 0;
1190 do {
1191 if (pgaSwitch) {
1192 /* PGA on */
1193 /* fine gain */
1194 status = Read16(state, B_FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
1195 if (status < 0)
1196 break;
1197 AgModeLop &= (~(B_FE_AG_REG_AG_MODE_LOP_MODE_C__M));
1198 AgModeLop |= B_FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC;
1199 status = Write16(state, B_FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
1200 if (status < 0)
1201 break;
1202
1203 /* coarse gain */
1204 status = Read16(state, B_FE_AG_REG_AG_MODE_HIP__A, &AgModeHip, 0x0000);
1205 if (status < 0)
1206 break;
1207 AgModeHip &= (~(B_FE_AG_REG_AG_MODE_HIP_MODE_J__M));
1208 AgModeHip |= B_FE_AG_REG_AG_MODE_HIP_MODE_J_DYNAMIC;
1209 status = Write16(state, B_FE_AG_REG_AG_MODE_HIP__A, AgModeHip, 0x0000);
1210 if (status < 0)
1211 break;
1212
1213 /* enable fine and coarse gain, enable AAF,
1214 no ext resistor */
1215 status = Write16(state, B_FE_AG_REG_AG_PGA_MODE__A, B_FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN, 0x0000);
1216 if (status < 0)
1217 break;
1218 } else {
1219 /* PGA off, bypass */
1220
1221 /* fine gain */
1222 status = Read16(state, B_FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
1223 if (status < 0)
1224 break;
1225 AgModeLop &= (~(B_FE_AG_REG_AG_MODE_LOP_MODE_C__M));
1226 AgModeLop |= B_FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC;
1227 status = Write16(state, B_FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
1228 if (status < 0)
1229 break;
1230
1231 /* coarse gain */
1232 status = Read16(state, B_FE_AG_REG_AG_MODE_HIP__A, &AgModeHip, 0x0000);
1233 if (status < 0)
1234 break;
1235 AgModeHip &= (~(B_FE_AG_REG_AG_MODE_HIP_MODE_J__M));
1236 AgModeHip |= B_FE_AG_REG_AG_MODE_HIP_MODE_J_STATIC;
1237 status = Write16(state, B_FE_AG_REG_AG_MODE_HIP__A, AgModeHip, 0x0000);
1238 if (status < 0)
1239 break;
1240
1241 /* disable fine and coarse gain, enable AAF,
1242 no ext resistor */
1243 status = Write16(state, B_FE_AG_REG_AG_PGA_MODE__A, B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN, 0x0000);
1244 if (status < 0)
1245 break;
1246 }
1247 } while (0);
1248 return status;
1249}
1250
1251static int InitFE(struct drxd_state *state)
1252{
1253 int status;
1254
1255 do {
1256 status = WriteTable(state, state->m_InitFE_1);
1257 if (status < 0)
1258 break;
1259
1260 if (state->type_A) {
1261 status = Write16(state, FE_AG_REG_AG_PGA_MODE__A,
1262 FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN,
1263 0);
1264 } else {
1265 if (state->PGA)
1266 status = SetCfgPga(state, 0);
1267 else
1268 status =
1269 Write16(state, B_FE_AG_REG_AG_PGA_MODE__A,
1270 B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN,
1271 0);
1272 }
1273
1274 if (status < 0)
1275 break;
1276 status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, state->m_FeAgRegAgAgcSio, 0x0000);
1277 if (status < 0)
1278 break;
1279 status = Write16(state, FE_AG_REG_AG_PWD__A, state->m_FeAgRegAgPwd, 0x0000);
1280 if (status < 0)
1281 break;
1282
1283 status = WriteTable(state, state->m_InitFE_2);
1284 if (status < 0)
1285 break;
1286
1287 } while (0);
1288
1289 return status;
1290}
1291
1292static int InitFT(struct drxd_state *state)
1293{
1294 /*
1295 norm OFFSET, MB says =2 voor 8K en =3 voor 2K waarschijnlijk
1296 SC stuff
1297 */
1298 return Write16(state, FT_REG_COMM_EXEC__A, 0x0001, 0x0000);
1299}
1300
1301static int SC_WaitForReady(struct drxd_state *state)
1302{
1303 u16 curCmd;
1304 int i;
1305
1306 for (i = 0; i < DRXD_MAX_RETRIES; i += 1) {
1307 int status = Read16(state, SC_RA_RAM_CMD__A, &curCmd, 0);
1308 if (status == 0 || curCmd == 0)
1309 return status;
1310 }
1311 return -1;
1312}
1313
1314static int SC_SendCommand(struct drxd_state *state, u16 cmd)
1315{
1316 int status = 0;
1317 u16 errCode;
1318
1319 Write16(state, SC_RA_RAM_CMD__A, cmd, 0);
1320 SC_WaitForReady(state);
1321
1322 Read16(state, SC_RA_RAM_CMD_ADDR__A, &errCode, 0);
1323
1324 if (errCode == 0xFFFF) {
1325 printk(KERN_ERR "Command Error\n");
1326 status = -1;
1327 }
1328
1329 return status;
1330}
1331
1332static int SC_ProcStartCommand(struct drxd_state *state,
1333 u16 subCmd, u16 param0, u16 param1)
1334{
1335 int status = 0;
1336 u16 scExec;
1337
1338 mutex_lock(&state->mutex);
1339 do {
1340 Read16(state, SC_COMM_EXEC__A, &scExec, 0);
1341 if (scExec != 1) {
1342 status = -1;
1343 break;
1344 }
1345 SC_WaitForReady(state);
1346 Write16(state, SC_RA_RAM_CMD_ADDR__A, subCmd, 0);
1347 Write16(state, SC_RA_RAM_PARAM1__A, param1, 0);
1348 Write16(state, SC_RA_RAM_PARAM0__A, param0, 0);
1349
1350 SC_SendCommand(state, SC_RA_RAM_CMD_PROC_START);
1351 } while (0);
1352 mutex_unlock(&state->mutex);
1353 return status;
1354}
1355
1356static int SC_SetPrefParamCommand(struct drxd_state *state,
1357 u16 subCmd, u16 param0, u16 param1)
1358{
1359 int status;
1360
1361 mutex_lock(&state->mutex);
1362 do {
1363 status = SC_WaitForReady(state);
1364 if (status < 0)
1365 break;
1366 status = Write16(state, SC_RA_RAM_CMD_ADDR__A, subCmd, 0);
1367 if (status < 0)
1368 break;
1369 status = Write16(state, SC_RA_RAM_PARAM1__A, param1, 0);
1370 if (status < 0)
1371 break;
1372 status = Write16(state, SC_RA_RAM_PARAM0__A, param0, 0);
1373 if (status < 0)
1374 break;
1375
1376 status = SC_SendCommand(state, SC_RA_RAM_CMD_SET_PREF_PARAM);
1377 if (status < 0)
1378 break;
1379 } while (0);
1380 mutex_unlock(&state->mutex);
1381 return status;
1382}
1383
1384#if 0
1385static int SC_GetOpParamCommand(struct drxd_state *state, u16 * result)
1386{
1387 int status = 0;
1388
1389 mutex_lock(&state->mutex);
1390 do {
1391 status = SC_WaitForReady(state);
1392 if (status < 0)
1393 break;
1394 status = SC_SendCommand(state, SC_RA_RAM_CMD_GET_OP_PARAM);
1395 if (status < 0)
1396 break;
1397 status = Read16(state, SC_RA_RAM_PARAM0__A, result, 0);
1398 if (status < 0)
1399 break;
1400 } while (0);
1401 mutex_unlock(&state->mutex);
1402 return status;
1403}
1404#endif
1405
1406static int ConfigureMPEGOutput(struct drxd_state *state, int bEnableOutput)
1407{
1408 int status;
1409
1410 do {
1411 u16 EcOcRegIprInvMpg = 0;
1412 u16 EcOcRegOcModeLop = 0;
1413 u16 EcOcRegOcModeHip = 0;
1414 u16 EcOcRegOcMpgSio = 0;
1415
1416 /*CHK_ERROR(Read16(state, EC_OC_REG_OC_MODE_LOP__A, &EcOcRegOcModeLop, 0)); */
1417
1418 if (state->operation_mode == OM_DVBT_Diversity_Front) {
1419 if (bEnableOutput) {
1420 EcOcRegOcModeHip |=
1421 B_EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR;
1422 } else
1423 EcOcRegOcMpgSio |= EC_OC_REG_OC_MPG_SIO__M;
1424 EcOcRegOcModeLop |=
1425 EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE;
1426 } else {
1427 EcOcRegOcModeLop = state->m_EcOcRegOcModeLop;
1428
1429 if (bEnableOutput)
1430 EcOcRegOcMpgSio &= (~(EC_OC_REG_OC_MPG_SIO__M));
1431 else
1432 EcOcRegOcMpgSio |= EC_OC_REG_OC_MPG_SIO__M;
1433
1434 /* Don't Insert RS Byte */
1435 if (state->insert_rs_byte) {
1436 EcOcRegOcModeLop &=
1437 (~(EC_OC_REG_OC_MODE_LOP_PAR_ENA__M));
1438 EcOcRegOcModeHip &=
1439 (~EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M);
1440 EcOcRegOcModeHip |=
1441 EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE;
1442 } else {
1443 EcOcRegOcModeLop |=
1444 EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE;
1445 EcOcRegOcModeHip &=
1446 (~EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M);
1447 EcOcRegOcModeHip |=
1448 EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE;
1449 }
1450
1451 /* Mode = Parallel */
1452 if (state->enable_parallel)
1453 EcOcRegOcModeLop &=
1454 (~(EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M));
1455 else
1456 EcOcRegOcModeLop |=
1457 EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL;
1458 }
1459 /* Invert Data */
1460 /* EcOcRegIprInvMpg |= 0x00FF; */
1461 EcOcRegIprInvMpg &= (~(0x00FF));
1462
1463 /* Invert Error ( we don't use the pin ) */
1464 /* EcOcRegIprInvMpg |= 0x0100; */
1465 EcOcRegIprInvMpg &= (~(0x0100));
1466
1467 /* Invert Start ( we don't use the pin ) */
1468 /* EcOcRegIprInvMpg |= 0x0200; */
1469 EcOcRegIprInvMpg &= (~(0x0200));
1470
1471 /* Invert Valid ( we don't use the pin ) */
1472 /* EcOcRegIprInvMpg |= 0x0400; */
1473 EcOcRegIprInvMpg &= (~(0x0400));
1474
1475 /* Invert Clock */
1476 /* EcOcRegIprInvMpg |= 0x0800; */
1477 EcOcRegIprInvMpg &= (~(0x0800));
1478
1479 /* EcOcRegOcModeLop =0x05; */
1480 status = Write16(state, EC_OC_REG_IPR_INV_MPG__A, EcOcRegIprInvMpg, 0);
1481 if (status < 0)
1482 break;
1483 status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, EcOcRegOcModeLop, 0);
1484 if (status < 0)
1485 break;
1486 status = Write16(state, EC_OC_REG_OC_MODE_HIP__A, EcOcRegOcModeHip, 0x0000);
1487 if (status < 0)
1488 break;
1489 status = Write16(state, EC_OC_REG_OC_MPG_SIO__A, EcOcRegOcMpgSio, 0);
1490 if (status < 0)
1491 break;
1492 } while (0);
1493 return status;
1494}
1495
1496static int SetDeviceTypeId(struct drxd_state *state)
1497{
1498 int status = 0;
1499 u16 deviceId = 0;
1500
1501 do {
1502 status = Read16(state, CC_REG_JTAGID_L__A, &deviceId, 0);
1503 if (status < 0)
1504 break;
1505 /* TODO: why twice? */
1506 status = Read16(state, CC_REG_JTAGID_L__A, &deviceId, 0);
1507 if (status < 0)
1508 break;
1509 printk(KERN_INFO "drxd: deviceId = %04x\n", deviceId);
1510
1511 state->type_A = 0;
1512 state->PGA = 0;
1513 state->diversity = 0;
1514 if (deviceId == 0) { /* on A2 only 3975 available */
1515 state->type_A = 1;
1516 printk(KERN_INFO "DRX3975D-A2\n");
1517 } else {
1518 deviceId >>= 12;
1519 printk(KERN_INFO "DRX397%dD-B1\n", deviceId);
1520 switch (deviceId) {
1521 case 4:
1522 state->diversity = 1;
1523 case 3:
1524 case 7:
1525 state->PGA = 1;
1526 break;
1527 case 6:
1528 state->diversity = 1;
1529 case 5:
1530 case 8:
1531 break;
1532 default:
1533 status = -1;
1534 break;
1535 }
1536 }
1537 } while (0);
1538
1539 if (status < 0)
1540 return status;
1541
1542 /* Init Table selection */
1543 state->m_InitAtomicRead = DRXD_InitAtomicRead;
1544 state->m_InitSC = DRXD_InitSC;
1545 state->m_ResetECRAM = DRXD_ResetECRAM;
1546 if (state->type_A) {
1547 state->m_ResetCEFR = DRXD_ResetCEFR;
1548 state->m_InitFE_1 = DRXD_InitFEA2_1;
1549 state->m_InitFE_2 = DRXD_InitFEA2_2;
1550 state->m_InitCP = DRXD_InitCPA2;
1551 state->m_InitCE = DRXD_InitCEA2;
1552 state->m_InitEQ = DRXD_InitEQA2;
1553 state->m_InitEC = DRXD_InitECA2;
1554 if (load_firmware(state, DRX_FW_FILENAME_A2))
1555 return -EIO;
1556 } else {
1557 state->m_ResetCEFR = NULL;
1558 state->m_InitFE_1 = DRXD_InitFEB1_1;
1559 state->m_InitFE_2 = DRXD_InitFEB1_2;
1560 state->m_InitCP = DRXD_InitCPB1;
1561 state->m_InitCE = DRXD_InitCEB1;
1562 state->m_InitEQ = DRXD_InitEQB1;
1563 state->m_InitEC = DRXD_InitECB1;
1564 if (load_firmware(state, DRX_FW_FILENAME_B1))
1565 return -EIO;
1566 }
1567 if (state->diversity) {
1568 state->m_InitDiversityFront = DRXD_InitDiversityFront;
1569 state->m_InitDiversityEnd = DRXD_InitDiversityEnd;
1570 state->m_DisableDiversity = DRXD_DisableDiversity;
1571 state->m_StartDiversityFront = DRXD_StartDiversityFront;
1572 state->m_StartDiversityEnd = DRXD_StartDiversityEnd;
1573 state->m_DiversityDelay8MHZ = DRXD_DiversityDelay8MHZ;
1574 state->m_DiversityDelay6MHZ = DRXD_DiversityDelay6MHZ;
1575 } else {
1576 state->m_InitDiversityFront = NULL;
1577 state->m_InitDiversityEnd = NULL;
1578 state->m_DisableDiversity = NULL;
1579 state->m_StartDiversityFront = NULL;
1580 state->m_StartDiversityEnd = NULL;
1581 state->m_DiversityDelay8MHZ = NULL;
1582 state->m_DiversityDelay6MHZ = NULL;
1583 }
1584
1585 return status;
1586}
1587
1588static int CorrectSysClockDeviation(struct drxd_state *state)
1589{
1590 int status;
1591 s32 incr = 0;
1592 s32 nomincr = 0;
1593 u32 bandwidth = 0;
1594 u32 sysClockInHz = 0;
1595 u32 sysClockFreq = 0; /* in kHz */
1596 s16 oscClockDeviation;
1597 s16 Diff;
1598
1599 do {
1600 /* Retrieve bandwidth and incr, sanity check */
1601
1602 /* These accesses should be AtomicReadReg32, but that
1603 causes trouble (at least for diversity */
1604 status = Read32(state, LC_RA_RAM_IFINCR_NOM_L__A, ((u32 *) &nomincr), 0);
1605 if (status < 0)
1606 break;
1607 status = Read32(state, FE_IF_REG_INCR0__A, (u32 *) &incr, 0);
1608 if (status < 0)
1609 break;
1610
1611 if (state->type_A) {
1612 if ((nomincr - incr < -500) || (nomincr - incr > 500))
1613 break;
1614 } else {
1615 if ((nomincr - incr < -2000) || (nomincr - incr > 2000))
1616 break;
1617 }
1618
1619 switch (state->param.u.ofdm.bandwidth) {
1620 case BANDWIDTH_8_MHZ:
1621 bandwidth = DRXD_BANDWIDTH_8MHZ_IN_HZ;
1622 break;
1623 case BANDWIDTH_7_MHZ:
1624 bandwidth = DRXD_BANDWIDTH_7MHZ_IN_HZ;
1625 break;
1626 case BANDWIDTH_6_MHZ:
1627 bandwidth = DRXD_BANDWIDTH_6MHZ_IN_HZ;
1628 break;
1629 default:
1630 return -1;
1631 break;
1632 }
1633
1634 /* Compute new sysclock value
1635 sysClockFreq = (((incr + 2^23)*bandwidth)/2^21)/1000 */
1636 incr += (1 << 23);
1637 sysClockInHz = MulDiv32(incr, bandwidth, 1 << 21);
1638 sysClockFreq = (u32) (sysClockInHz / 1000);
1639 /* rounding */
1640 if ((sysClockInHz % 1000) > 500)
1641 sysClockFreq++;
1642
1643 /* Compute clock deviation in ppm */
1644 oscClockDeviation = (u16) ((((s32) (sysClockFreq) -
1645 (s32)
1646 (state->expected_sys_clock_freq)) *
1647 1000000L) /
1648 (s32)
1649 (state->expected_sys_clock_freq));
1650
1651 Diff = oscClockDeviation - state->osc_clock_deviation;
1652 /*printk(KERN_INFO "sysclockdiff=%d\n", Diff); */
1653 if (Diff >= -200 && Diff <= 200) {
1654 state->sys_clock_freq = (u16) sysClockFreq;
1655 if (oscClockDeviation != state->osc_clock_deviation) {
1656 if (state->config.osc_deviation) {
1657 state->config.osc_deviation(state->priv,
1658 oscClockDeviation,
1659 1);
1660 state->osc_clock_deviation =
1661 oscClockDeviation;
1662 }
1663 }
1664 /* switch OFF SRMM scan in SC */
1665 status = Write16(state, SC_RA_RAM_SAMPLE_RATE_COUNT__A, DRXD_OSCDEV_DONT_SCAN, 0);
1666 if (status < 0)
1667 break;
1668 /* overrule FE_IF internal value for
1669 proper re-locking */
1670 status = Write16(state, SC_RA_RAM_IF_SAVE__AX, state->current_fe_if_incr, 0);
1671 if (status < 0)
1672 break;
1673 state->cscd_state = CSCD_SAVED;
1674 }
1675 } while (0);
1676
1677 return status;
1678}
1679
1680static int DRX_Stop(struct drxd_state *state)
1681{
1682 int status;
1683
1684 if (state->drxd_state != DRXD_STARTED)
1685 return 0;
1686
1687 do {
1688 if (state->cscd_state != CSCD_SAVED) {
1689 u32 lock;
1690 status = DRX_GetLockStatus(state, &lock);
1691 if (status < 0)
1692 break;
1693 }
1694
1695 status = StopOC(state);
1696 if (status < 0)
1697 break;
1698
1699 state->drxd_state = DRXD_STOPPED;
1700
1701 status = ConfigureMPEGOutput(state, 0);
1702 if (status < 0)
1703 break;
1704
1705 if (state->type_A) {
1706 /* Stop relevant processors off the device */
1707 status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0000, 0x0000);
1708 if (status < 0)
1709 break;
1710
1711 status = Write16(state, SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1712 if (status < 0)
1713 break;
1714 status = Write16(state, LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1715 if (status < 0)
1716 break;
1717 } else {
1718 /* Stop all processors except HI & CC & FE */
1719 status = Write16(state, B_SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1720 if (status < 0)
1721 break;
1722 status = Write16(state, B_LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1723 if (status < 0)
1724 break;
1725 status = Write16(state, B_FT_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1726 if (status < 0)
1727 break;
1728 status = Write16(state, B_CP_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1729 if (status < 0)
1730 break;
1731 status = Write16(state, B_CE_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1732 if (status < 0)
1733 break;
1734 status = Write16(state, B_EQ_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
1735 if (status < 0)
1736 break;
1737 status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0000, 0);
1738 if (status < 0)
1739 break;
1740 }
1741
1742 } while (0);
1743 return status;
1744}
1745
1746int SetOperationMode(struct drxd_state *state, int oMode)
1747{
1748 int status;
1749
1750 do {
1751 if (state->drxd_state != DRXD_STOPPED) {
1752 status = -1;
1753 break;
1754 }
1755
1756 if (oMode == state->operation_mode) {
1757 status = 0;
1758 break;
1759 }
1760
1761 if (oMode != OM_Default && !state->diversity) {
1762 status = -1;
1763 break;
1764 }
1765
1766 switch (oMode) {
1767 case OM_DVBT_Diversity_Front:
1768 status = WriteTable(state, state->m_InitDiversityFront);
1769 break;
1770 case OM_DVBT_Diversity_End:
1771 status = WriteTable(state, state->m_InitDiversityEnd);
1772 break;
1773 case OM_Default:
1774 /* We need to check how to
1775 get DRXD out of diversity */
1776 default:
1777 status = WriteTable(state, state->m_DisableDiversity);
1778 break;
1779 }
1780 } while (0);
1781
1782 if (!status)
1783 state->operation_mode = oMode;
1784 return status;
1785}
1786
1787static int StartDiversity(struct drxd_state *state)
1788{
1789 int status = 0;
1790 u16 rcControl;
1791
1792 do {
1793 if (state->operation_mode == OM_DVBT_Diversity_Front) {
1794 status = WriteTable(state, state->m_StartDiversityFront);
1795 if (status < 0)
1796 break;
1797 } else if (state->operation_mode == OM_DVBT_Diversity_End) {
1798 status = WriteTable(state, state->m_StartDiversityEnd);
1799 if (status < 0)
1800 break;
1801 if (state->param.u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
1802 status = WriteTable(state, state->m_DiversityDelay8MHZ);
1803 if (status < 0)
1804 break;
1805 } else {
1806 status = WriteTable(state, state->m_DiversityDelay6MHZ);
1807 if (status < 0)
1808 break;
1809 }
1810
1811 status = Read16(state, B_EQ_REG_RC_SEL_CAR__A, &rcControl, 0);
1812 if (status < 0)
1813 break;
1814 rcControl &= ~(B_EQ_REG_RC_SEL_CAR_FFTMODE__M);
1815 rcControl |= B_EQ_REG_RC_SEL_CAR_DIV_ON |
1816 /* combining enabled */
1817 B_EQ_REG_RC_SEL_CAR_MEAS_A_CC |
1818 B_EQ_REG_RC_SEL_CAR_PASS_A_CC |
1819 B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC;
1820 status = Write16(state, B_EQ_REG_RC_SEL_CAR__A, rcControl, 0);
1821 if (status < 0)
1822 break;
1823 }
1824 } while (0);
1825 return status;
1826}
1827
1828static int SetFrequencyShift(struct drxd_state *state,
1829 u32 offsetFreq, int channelMirrored)
1830{
1831 int negativeShift = (state->tuner_mirrors == channelMirrored);
1832
1833 /* Handle all mirroring
1834 *
1835 * Note: ADC mirroring (aliasing) is implictly handled by limiting
1836 * feFsRegAddInc to 28 bits below
1837 * (if the result before masking is more than 28 bits, this means
1838 * that the ADC is mirroring.
1839 * The masking is in fact the aliasing of the ADC)
1840 *
1841 */
1842
1843 /* Compute register value, unsigned computation */
1844 state->fe_fs_add_incr = MulDiv32(state->intermediate_freq +
1845 offsetFreq,
1846 1 << 28, state->sys_clock_freq);
1847 /* Remove integer part */
1848 state->fe_fs_add_incr &= 0x0FFFFFFFL;
1849 if (negativeShift)
1850 state->fe_fs_add_incr = ((1 << 28) - state->fe_fs_add_incr);
1851
1852 /* Save the frequency shift without tunerOffset compensation
1853 for CtrlGetChannel. */
1854 state->org_fe_fs_add_incr = MulDiv32(state->intermediate_freq,
1855 1 << 28, state->sys_clock_freq);
1856 /* Remove integer part */
1857 state->org_fe_fs_add_incr &= 0x0FFFFFFFL;
1858 if (negativeShift)
1859 state->org_fe_fs_add_incr = ((1L << 28) -
1860 state->org_fe_fs_add_incr);
1861
1862 return Write32(state, FE_FS_REG_ADD_INC_LOP__A,
1863 state->fe_fs_add_incr, 0);
1864}
1865
1866static int SetCfgNoiseCalibration(struct drxd_state *state,
1867 struct SNoiseCal *noiseCal)
1868{
1869 u16 beOptEna;
1870 int status = 0;
1871
1872 do {
1873 status = Read16(state, SC_RA_RAM_BE_OPT_ENA__A, &beOptEna, 0);
1874 if (status < 0)
1875 break;
1876 if (noiseCal->cpOpt) {
1877 beOptEna |= (1 << SC_RA_RAM_BE_OPT_ENA_CP_OPT);
1878 } else {
1879 beOptEna &= ~(1 << SC_RA_RAM_BE_OPT_ENA_CP_OPT);
1880 status = Write16(state, CP_REG_AC_NEXP_OFFS__A, noiseCal->cpNexpOfs, 0);
1881 if (status < 0)
1882 break;
1883 }
1884 status = Write16(state, SC_RA_RAM_BE_OPT_ENA__A, beOptEna, 0);
1885 if (status < 0)
1886 break;
1887
1888 if (!state->type_A) {
1889 status = Write16(state, B_SC_RA_RAM_CO_TD_CAL_2K__A, noiseCal->tdCal2k, 0);
1890 if (status < 0)
1891 break;
1892 status = Write16(state, B_SC_RA_RAM_CO_TD_CAL_8K__A, noiseCal->tdCal8k, 0);
1893 if (status < 0)
1894 break;
1895 }
1896 } while (0);
1897
1898 return status;
1899}
1900
1901static int DRX_Start(struct drxd_state *state, s32 off)
1902{
1903 struct dvb_ofdm_parameters *p = &state->param.u.ofdm;
1904 int status;
1905
1906 u16 transmissionParams = 0;
1907 u16 operationMode = 0;
1908 u16 qpskTdTpsPwr = 0;
1909 u16 qam16TdTpsPwr = 0;
1910 u16 qam64TdTpsPwr = 0;
1911 u32 feIfIncr = 0;
1912 u32 bandwidth = 0;
1913 int mirrorFreqSpect;
1914
1915 u16 qpskSnCeGain = 0;
1916 u16 qam16SnCeGain = 0;
1917 u16 qam64SnCeGain = 0;
1918 u16 qpskIsGainMan = 0;
1919 u16 qam16IsGainMan = 0;
1920 u16 qam64IsGainMan = 0;
1921 u16 qpskIsGainExp = 0;
1922 u16 qam16IsGainExp = 0;
1923 u16 qam64IsGainExp = 0;
1924 u16 bandwidthParam = 0;
1925
1926 if (off < 0)
1927 off = (off - 500) / 1000;
1928 else
1929 off = (off + 500) / 1000;
1930
1931 do {
1932 if (state->drxd_state != DRXD_STOPPED)
1933 return -1;
1934 status = ResetECOD(state);
1935 if (status < 0)
1936 break;
1937 if (state->type_A) {
1938 status = InitSC(state);
1939 if (status < 0)
1940 break;
1941 } else {
1942 status = InitFT(state);
1943 if (status < 0)
1944 break;
1945 status = InitCP(state);
1946 if (status < 0)
1947 break;
1948 status = InitCE(state);
1949 if (status < 0)
1950 break;
1951 status = InitEQ(state);
1952 if (status < 0)
1953 break;
1954 status = InitSC(state);
1955 if (status < 0)
1956 break;
1957 }
1958
1959 /* Restore current IF & RF AGC settings */
1960
1961 status = SetCfgIfAgc(state, &state->if_agc_cfg);
1962 if (status < 0)
1963 break;
1964 status = SetCfgRfAgc(state, &state->rf_agc_cfg);
1965 if (status < 0)
1966 break;
1967
1968 mirrorFreqSpect = (state->param.inversion == INVERSION_ON);
1969
1970 switch (p->transmission_mode) {
1971 default: /* Not set, detect it automatically */
1972 operationMode |= SC_RA_RAM_OP_AUTO_MODE__M;
1973 /* fall through , try first guess DRX_FFTMODE_8K */
1974 case TRANSMISSION_MODE_8K:
1975 transmissionParams |= SC_RA_RAM_OP_PARAM_MODE_8K;
1976 if (state->type_A) {
1977 status = Write16(state, EC_SB_REG_TR_MODE__A, EC_SB_REG_TR_MODE_8K, 0x0000);
1978 if (status < 0)
1979 break;
1980 qpskSnCeGain = 99;
1981 qam16SnCeGain = 83;
1982 qam64SnCeGain = 67;
1983 }
1984 break;
1985 case TRANSMISSION_MODE_2K:
1986 transmissionParams |= SC_RA_RAM_OP_PARAM_MODE_2K;
1987 if (state->type_A) {
1988 status = Write16(state, EC_SB_REG_TR_MODE__A, EC_SB_REG_TR_MODE_2K, 0x0000);
1989 if (status < 0)
1990 break;
1991 qpskSnCeGain = 97;
1992 qam16SnCeGain = 71;
1993 qam64SnCeGain = 65;
1994 }
1995 break;
1996 }
1997
1998 switch (p->guard_interval) {
1999 case GUARD_INTERVAL_1_4:
2000 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_4;
2001 break;
2002 case GUARD_INTERVAL_1_8:
2003 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_8;
2004 break;
2005 case GUARD_INTERVAL_1_16:
2006 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_16;
2007 break;
2008 case GUARD_INTERVAL_1_32:
2009 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_32;
2010 break;
2011 default: /* Not set, detect it automatically */
2012 operationMode |= SC_RA_RAM_OP_AUTO_GUARD__M;
2013 /* try first guess 1/4 */
2014 transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_4;
2015 break;
2016 }
2017
2018 switch (p->hierarchy_information) {
2019 case HIERARCHY_1:
2020 transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A1;
2021 if (state->type_A) {
2022 status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0001, 0x0000);
2023 if (status < 0)
2024 break;
2025 status = Write16(state, EC_SB_REG_ALPHA__A, 0x0001, 0x0000);
2026 if (status < 0)
2027 break;
2028
2029 qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
2030 qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA1;
2031 qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA1;
2032
2033 qpskIsGainMan =
2034 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
2035 qam16IsGainMan =
2036 SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE;
2037 qam64IsGainMan =
2038 SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE;
2039
2040 qpskIsGainExp =
2041 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
2042 qam16IsGainExp =
2043 SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE;
2044 qam64IsGainExp =
2045 SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE;
2046 }
2047 break;
2048
2049 case HIERARCHY_2:
2050 transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A2;
2051 if (state->type_A) {
2052 status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0002, 0x0000);
2053 if (status < 0)
2054 break;
2055 status = Write16(state, EC_SB_REG_ALPHA__A, 0x0002, 0x0000);
2056 if (status < 0)
2057 break;
2058
2059 qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
2060 qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA2;
2061 qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA2;
2062
2063 qpskIsGainMan =
2064 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
2065 qam16IsGainMan =
2066 SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE;
2067 qam64IsGainMan =
2068 SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE;
2069
2070 qpskIsGainExp =
2071 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
2072 qam16IsGainExp =
2073 SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE;
2074 qam64IsGainExp =
2075 SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE;
2076 }
2077 break;
2078 case HIERARCHY_4:
2079 transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A4;
2080 if (state->type_A) {
2081 status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0003, 0x0000);
2082 if (status < 0)
2083 break;
2084 status = Write16(state, EC_SB_REG_ALPHA__A, 0x0003, 0x0000);
2085 if (status < 0)
2086 break;
2087
2088 qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
2089 qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA4;
2090 qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA4;
2091
2092 qpskIsGainMan =
2093 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
2094 qam16IsGainMan =
2095 SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE;
2096 qam64IsGainMan =
2097 SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE;
2098
2099 qpskIsGainExp =
2100 SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
2101 qam16IsGainExp =
2102 SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE;
2103 qam64IsGainExp =
2104 SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE;
2105 }
2106 break;
2107 case HIERARCHY_AUTO:
2108 default:
2109 /* Not set, detect it automatically, start with none */
2110 operationMode |= SC_RA_RAM_OP_AUTO_HIER__M;
2111 transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_NO;
2112 if (state->type_A) {
2113 status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0000, 0x0000);
2114 if (status < 0)
2115 break;
2116 status = Write16(state, EC_SB_REG_ALPHA__A, 0x0000, 0x0000);
2117 if (status < 0)
2118 break;
2119
2120 qpskTdTpsPwr = EQ_TD_TPS_PWR_QPSK;
2121 qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHAN;
2122 qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHAN;
2123
2124 qpskIsGainMan =
2125 SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE;
2126 qam16IsGainMan =
2127 SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE;
2128 qam64IsGainMan =
2129 SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE;
2130
2131 qpskIsGainExp =
2132 SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE;
2133 qam16IsGainExp =
2134 SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE;
2135 qam64IsGainExp =
2136 SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE;
2137 }
2138 break;
2139 }
2140 status = status;
2141 if (status < 0)
2142 break;
2143
2144 switch (p->constellation) {
2145 default:
2146 operationMode |= SC_RA_RAM_OP_AUTO_CONST__M;
2147 /* fall through , try first guess
2148 DRX_CONSTELLATION_QAM64 */
2149 case QAM_64:
2150 transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QAM64;
2151 if (state->type_A) {
2152 status = Write16(state, EQ_REG_OT_CONST__A, 0x0002, 0x0000);
2153 if (status < 0)
2154 break;
2155 status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_64QAM, 0x0000);
2156 if (status < 0)
2157 break;
2158 status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0020, 0x0000);
2159 if (status < 0)
2160 break;
2161 status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0008, 0x0000);
2162 if (status < 0)
2163 break;
2164 status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0002, 0x0000);
2165 if (status < 0)
2166 break;
2167
2168 status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qam64TdTpsPwr, 0x0000);
2169 if (status < 0)
2170 break;
2171 status = Write16(state, EQ_REG_SN_CEGAIN__A, qam64SnCeGain, 0x0000);
2172 if (status < 0)
2173 break;
2174 status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qam64IsGainMan, 0x0000);
2175 if (status < 0)
2176 break;
2177 status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qam64IsGainExp, 0x0000);
2178 if (status < 0)
2179 break;
2180 }
2181 break;
2182 case QPSK:
2183 transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QPSK;
2184 if (state->type_A) {
2185 status = Write16(state, EQ_REG_OT_CONST__A, 0x0000, 0x0000);
2186 if (status < 0)
2187 break;
2188 status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_QPSK, 0x0000);
2189 if (status < 0)
2190 break;
2191 status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0010, 0x0000);
2192 if (status < 0)
2193 break;
2194 status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0000, 0x0000);
2195 if (status < 0)
2196 break;
2197 status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0000, 0x0000);
2198 if (status < 0)
2199 break;
2200
2201 status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qpskTdTpsPwr, 0x0000);
2202 if (status < 0)
2203 break;
2204 status = Write16(state, EQ_REG_SN_CEGAIN__A, qpskSnCeGain, 0x0000);
2205 if (status < 0)
2206 break;
2207 status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qpskIsGainMan, 0x0000);
2208 if (status < 0)
2209 break;
2210 status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qpskIsGainExp, 0x0000);
2211 if (status < 0)
2212 break;
2213 }
2214 break;
2215
2216 case QAM_16:
2217 transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QAM16;
2218 if (state->type_A) {
2219 status = Write16(state, EQ_REG_OT_CONST__A, 0x0001, 0x0000);
2220 if (status < 0)
2221 break;
2222 status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_16QAM, 0x0000);
2223 if (status < 0)
2224 break;
2225 status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0010, 0x0000);
2226 if (status < 0)
2227 break;
2228 status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0004, 0x0000);
2229 if (status < 0)
2230 break;
2231 status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0000, 0x0000);
2232 if (status < 0)
2233 break;
2234
2235 status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qam16TdTpsPwr, 0x0000);
2236 if (status < 0)
2237 break;
2238 status = Write16(state, EQ_REG_SN_CEGAIN__A, qam16SnCeGain, 0x0000);
2239 if (status < 0)
2240 break;
2241 status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qam16IsGainMan, 0x0000);
2242 if (status < 0)
2243 break;
2244 status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qam16IsGainExp, 0x0000);
2245 if (status < 0)
2246 break;
2247 }
2248 break;
2249
2250 }
2251 status = status;
2252 if (status < 0)
2253 break;
2254
2255 switch (DRX_CHANNEL_HIGH) {
2256 default:
2257 case DRX_CHANNEL_AUTO:
2258 case DRX_CHANNEL_LOW:
2259 transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_LO;
2260 status = Write16(state, EC_SB_REG_PRIOR__A, EC_SB_REG_PRIOR_LO, 0x0000);
2261 if (status < 0)
2262 break;
2263 break;
2264 case DRX_CHANNEL_HIGH:
2265 transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_HI;
2266 status = Write16(state, EC_SB_REG_PRIOR__A, EC_SB_REG_PRIOR_HI, 0x0000);
2267 if (status < 0)
2268 break;
2269 break;
2270
2271 }
2272
2273 switch (p->code_rate_HP) {
2274 case FEC_1_2:
2275 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_1_2;
2276 if (state->type_A) {
2277 status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C1_2, 0x0000);
2278 if (status < 0)
2279 break;
2280 }
2281 break;
2282 default:
2283 operationMode |= SC_RA_RAM_OP_AUTO_RATE__M;
2284 case FEC_2_3:
2285 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_2_3;
2286 if (state->type_A) {
2287 status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C2_3, 0x0000);
2288 if (status < 0)
2289 break;
2290 }
2291 break;
2292 case FEC_3_4:
2293 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_3_4;
2294 if (state->type_A) {
2295 status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C3_4, 0x0000);
2296 if (status < 0)
2297 break;
2298 }
2299 break;
2300 case FEC_5_6:
2301 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_5_6;
2302 if (state->type_A) {
2303 status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C5_6, 0x0000);
2304 if (status < 0)
2305 break;
2306 }
2307 break;
2308 case FEC_7_8:
2309 transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_7_8;
2310 if (state->type_A) {
2311 status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C7_8, 0x0000);
2312 if (status < 0)
2313 break;
2314 }
2315 break;
2316 }
2317 status = status;
2318 if (status < 0)
2319 break;
2320
2321 /* First determine real bandwidth (Hz) */
2322 /* Also set delay for impulse noise cruncher (only A2) */
2323 /* Also set parameters for EC_OC fix, note
2324 EC_OC_REG_TMD_HIL_MAR is changed
2325 by SC for fix for some 8K,1/8 guard but is restored by
2326 InitEC and ResetEC
2327 functions */
2328 switch (p->bandwidth) {
2329 case BANDWIDTH_AUTO:
2330 case BANDWIDTH_8_MHZ:
2331 /* (64/7)*(8/8)*1000000 */
2332 bandwidth = DRXD_BANDWIDTH_8MHZ_IN_HZ;
2333
2334 bandwidthParam = 0;
2335 status = Write16(state,
2336 FE_AG_REG_IND_DEL__A, 50, 0x0000);
2337 break;
2338 case BANDWIDTH_7_MHZ:
2339 /* (64/7)*(7/8)*1000000 */
2340 bandwidth = DRXD_BANDWIDTH_7MHZ_IN_HZ;
2341 bandwidthParam = 0x4807; /*binary:0100 1000 0000 0111 */
2342 status = Write16(state,
2343 FE_AG_REG_IND_DEL__A, 59, 0x0000);
2344 break;
2345 case BANDWIDTH_6_MHZ:
2346 /* (64/7)*(6/8)*1000000 */
2347 bandwidth = DRXD_BANDWIDTH_6MHZ_IN_HZ;
2348 bandwidthParam = 0x0F07; /*binary: 0000 1111 0000 0111 */
2349 status = Write16(state,
2350 FE_AG_REG_IND_DEL__A, 71, 0x0000);
2351 break;
2352 default:
2353 status = -EINVAL;
2354 }
2355 if (status < 0)
2356 break;
2357
2358 status = Write16(state, SC_RA_RAM_BAND__A, bandwidthParam, 0x0000);
2359 if (status < 0)
2360 break;
2361
2362 {
2363 u16 sc_config;
2364 status = Read16(state, SC_RA_RAM_CONFIG__A, &sc_config, 0);
2365 if (status < 0)
2366 break;
2367
2368 /* enable SLAVE mode in 2k 1/32 to
2369 prevent timing change glitches */
2370 if ((p->transmission_mode == TRANSMISSION_MODE_2K) &&
2371 (p->guard_interval == GUARD_INTERVAL_1_32)) {
2372 /* enable slave */
2373 sc_config |= SC_RA_RAM_CONFIG_SLAVE__M;
2374 } else {
2375 /* disable slave */
2376 sc_config &= ~SC_RA_RAM_CONFIG_SLAVE__M;
2377 }
2378 status = Write16(state, SC_RA_RAM_CONFIG__A, sc_config, 0);
2379 if (status < 0)
2380 break;
2381 }
2382
2383 status = SetCfgNoiseCalibration(state, &state->noise_cal);
2384 if (status < 0)
2385 break;
2386
2387 if (state->cscd_state == CSCD_INIT) {
2388 /* switch on SRMM scan in SC */
2389 status = Write16(state, SC_RA_RAM_SAMPLE_RATE_COUNT__A, DRXD_OSCDEV_DO_SCAN, 0x0000);
2390 if (status < 0)
2391 break;
2392/* CHK_ERROR(Write16(SC_RA_RAM_SAMPLE_RATE_STEP__A, DRXD_OSCDEV_STEP, 0x0000));*/
2393 state->cscd_state = CSCD_SET;
2394 }
2395
2396 /* Now compute FE_IF_REG_INCR */
2397 /*((( SysFreq/BandWidth)/2)/2) -1) * 2^23) =>
2398 ((SysFreq / BandWidth) * (2^21) ) - (2^23) */
2399 feIfIncr = MulDiv32(state->sys_clock_freq * 1000,
2400 (1ULL << 21), bandwidth) - (1 << 23);
2401 status = Write16(state, FE_IF_REG_INCR0__A, (u16) (feIfIncr & FE_IF_REG_INCR0__M), 0x0000);
2402 if (status < 0)
2403 break;
2404 status = Write16(state, FE_IF_REG_INCR1__A, (u16) ((feIfIncr >> FE_IF_REG_INCR0__W) & FE_IF_REG_INCR1__M), 0x0000);
2405 if (status < 0)
2406 break;
2407 /* Bandwidth setting done */
2408
2409 /* Mirror & frequency offset */
2410 SetFrequencyShift(state, off, mirrorFreqSpect);
2411
2412 /* Start SC, write channel settings to SC */
2413
2414 /* Enable SC after setting all other parameters */
2415 status = Write16(state, SC_COMM_STATE__A, 0, 0x0000);
2416 if (status < 0)
2417 break;
2418 status = Write16(state, SC_COMM_EXEC__A, 1, 0x0000);
2419 if (status < 0)
2420 break;
2421
2422 /* Write SC parameter registers, operation mode */
2423#if 1
2424 operationMode = (SC_RA_RAM_OP_AUTO_MODE__M |
2425 SC_RA_RAM_OP_AUTO_GUARD__M |
2426 SC_RA_RAM_OP_AUTO_CONST__M |
2427 SC_RA_RAM_OP_AUTO_HIER__M |
2428 SC_RA_RAM_OP_AUTO_RATE__M);
2429#endif
2430 status = SC_SetPrefParamCommand(state, 0x0000, transmissionParams, operationMode);
2431 if (status < 0)
2432 break;
2433
2434 /* Start correct processes to get in lock */
2435 status = SC_ProcStartCommand(state, SC_RA_RAM_PROC_LOCKTRACK, SC_RA_RAM_SW_EVENT_RUN_NMASK__M, SC_RA_RAM_LOCKTRACK_MIN);
2436 if (status < 0)
2437 break;
2438
2439 status = StartOC(state);
2440 if (status < 0)
2441 break;
2442
2443 if (state->operation_mode != OM_Default) {
2444 status = StartDiversity(state);
2445 if (status < 0)
2446 break;
2447 }
2448
2449 state->drxd_state = DRXD_STARTED;
2450 } while (0);
2451
2452 return status;
2453}
2454
2455static int CDRXD(struct drxd_state *state, u32 IntermediateFrequency)
2456{
2457 u32 ulRfAgcOutputLevel = 0xffffffff;
2458 u32 ulRfAgcSettleLevel = 528; /* Optimum value for MT2060 */
2459 u32 ulRfAgcMinLevel = 0; /* Currently unused */
2460 u32 ulRfAgcMaxLevel = DRXD_FE_CTRL_MAX; /* Currently unused */
2461 u32 ulRfAgcSpeed = 0; /* Currently unused */
2462 u32 ulRfAgcMode = 0; /*2; Off */
2463 u32 ulRfAgcR1 = 820;
2464 u32 ulRfAgcR2 = 2200;
2465 u32 ulRfAgcR3 = 150;
2466 u32 ulIfAgcMode = 0; /* Auto */
2467 u32 ulIfAgcOutputLevel = 0xffffffff;
2468 u32 ulIfAgcSettleLevel = 0xffffffff;
2469 u32 ulIfAgcMinLevel = 0xffffffff;
2470 u32 ulIfAgcMaxLevel = 0xffffffff;
2471 u32 ulIfAgcSpeed = 0xffffffff;
2472 u32 ulIfAgcR1 = 820;
2473 u32 ulIfAgcR2 = 2200;
2474 u32 ulIfAgcR3 = 150;
2475 u32 ulClock = state->config.clock;
2476 u32 ulSerialMode = 0;
2477 u32 ulEcOcRegOcModeLop = 4; /* Dynamic DTO source */
2478 u32 ulHiI2cDelay = HI_I2C_DELAY;
2479 u32 ulHiI2cBridgeDelay = HI_I2C_BRIDGE_DELAY;
2480 u32 ulHiI2cPatch = 0;
2481 u32 ulEnvironment = APPENV_PORTABLE;
2482 u32 ulEnvironmentDiversity = APPENV_MOBILE;
2483 u32 ulIFFilter = IFFILTER_SAW;
2484
2485 state->if_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
2486 state->if_agc_cfg.outputLevel = 0;
2487 state->if_agc_cfg.settleLevel = 140;
2488 state->if_agc_cfg.minOutputLevel = 0;
2489 state->if_agc_cfg.maxOutputLevel = 1023;
2490 state->if_agc_cfg.speed = 904;
2491
2492 if (ulIfAgcMode == 1 && ulIfAgcOutputLevel <= DRXD_FE_CTRL_MAX) {
2493 state->if_agc_cfg.ctrlMode = AGC_CTRL_USER;
2494 state->if_agc_cfg.outputLevel = (u16) (ulIfAgcOutputLevel);
2495 }
2496
2497 if (ulIfAgcMode == 0 &&
2498 ulIfAgcSettleLevel <= DRXD_FE_CTRL_MAX &&
2499 ulIfAgcMinLevel <= DRXD_FE_CTRL_MAX &&
2500 ulIfAgcMaxLevel <= DRXD_FE_CTRL_MAX &&
2501 ulIfAgcSpeed <= DRXD_FE_CTRL_MAX) {
2502 state->if_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
2503 state->if_agc_cfg.settleLevel = (u16) (ulIfAgcSettleLevel);
2504 state->if_agc_cfg.minOutputLevel = (u16) (ulIfAgcMinLevel);
2505 state->if_agc_cfg.maxOutputLevel = (u16) (ulIfAgcMaxLevel);
2506 state->if_agc_cfg.speed = (u16) (ulIfAgcSpeed);
2507 }
2508
2509 state->if_agc_cfg.R1 = (u16) (ulIfAgcR1);
2510 state->if_agc_cfg.R2 = (u16) (ulIfAgcR2);
2511 state->if_agc_cfg.R3 = (u16) (ulIfAgcR3);
2512
2513 state->rf_agc_cfg.R1 = (u16) (ulRfAgcR1);
2514 state->rf_agc_cfg.R2 = (u16) (ulRfAgcR2);
2515 state->rf_agc_cfg.R3 = (u16) (ulRfAgcR3);
2516
2517 state->rf_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
2518 /* rest of the RFAgcCfg structure currently unused */
2519 if (ulRfAgcMode == 1 && ulRfAgcOutputLevel <= DRXD_FE_CTRL_MAX) {
2520 state->rf_agc_cfg.ctrlMode = AGC_CTRL_USER;
2521 state->rf_agc_cfg.outputLevel = (u16) (ulRfAgcOutputLevel);
2522 }
2523
2524 if (ulRfAgcMode == 0 &&
2525 ulRfAgcSettleLevel <= DRXD_FE_CTRL_MAX &&
2526 ulRfAgcMinLevel <= DRXD_FE_CTRL_MAX &&
2527 ulRfAgcMaxLevel <= DRXD_FE_CTRL_MAX &&
2528 ulRfAgcSpeed <= DRXD_FE_CTRL_MAX) {
2529 state->rf_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
2530 state->rf_agc_cfg.settleLevel = (u16) (ulRfAgcSettleLevel);
2531 state->rf_agc_cfg.minOutputLevel = (u16) (ulRfAgcMinLevel);
2532 state->rf_agc_cfg.maxOutputLevel = (u16) (ulRfAgcMaxLevel);
2533 state->rf_agc_cfg.speed = (u16) (ulRfAgcSpeed);
2534 }
2535
2536 if (ulRfAgcMode == 2)
2537 state->rf_agc_cfg.ctrlMode = AGC_CTRL_OFF;
2538
2539 if (ulEnvironment <= 2)
2540 state->app_env_default = (enum app_env)
2541 (ulEnvironment);
2542 if (ulEnvironmentDiversity <= 2)
2543 state->app_env_diversity = (enum app_env)
2544 (ulEnvironmentDiversity);
2545
2546 if (ulIFFilter == IFFILTER_DISCRETE) {
2547 /* discrete filter */
2548 state->noise_cal.cpOpt = 0;
2549 state->noise_cal.cpNexpOfs = 40;
2550 state->noise_cal.tdCal2k = -40;
2551 state->noise_cal.tdCal8k = -24;
2552 } else {
2553 /* SAW filter */
2554 state->noise_cal.cpOpt = 1;
2555 state->noise_cal.cpNexpOfs = 0;
2556 state->noise_cal.tdCal2k = -21;
2557 state->noise_cal.tdCal8k = -24;
2558 }
2559 state->m_EcOcRegOcModeLop = (u16) (ulEcOcRegOcModeLop);
2560
2561 state->chip_adr = (state->config.demod_address << 1) | 1;
2562 switch (ulHiI2cPatch) {
2563 case 1:
2564 state->m_HiI2cPatch = DRXD_HiI2cPatch_1;
2565 break;
2566 case 3:
2567 state->m_HiI2cPatch = DRXD_HiI2cPatch_3;
2568 break;
2569 default:
2570 state->m_HiI2cPatch = NULL;
2571 }
2572
2573 /* modify tuner and clock attributes */
2574 state->intermediate_freq = (u16) (IntermediateFrequency / 1000);
2575 /* expected system clock frequency in kHz */
2576 state->expected_sys_clock_freq = 48000;
2577 /* real system clock frequency in kHz */
2578 state->sys_clock_freq = 48000;
2579 state->osc_clock_freq = (u16) ulClock;
2580 state->osc_clock_deviation = 0;
2581 state->cscd_state = CSCD_INIT;
2582 state->drxd_state = DRXD_UNINITIALIZED;
2583
2584 state->PGA = 0;
2585 state->type_A = 0;
2586 state->tuner_mirrors = 0;
2587
2588 /* modify MPEG output attributes */
2589 state->insert_rs_byte = state->config.insert_rs_byte;
2590 state->enable_parallel = (ulSerialMode != 1);
2591
2592 /* Timing div, 250ns/Psys */
2593 /* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
2594
2595 state->hi_cfg_timing_div = (u16) ((state->sys_clock_freq / 1000) *
2596 ulHiI2cDelay) / 1000;
2597 /* Bridge delay, uses oscilator clock */
2598 /* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
2599 state->hi_cfg_bridge_delay = (u16) ((state->osc_clock_freq / 1000) *
2600 ulHiI2cBridgeDelay) / 1000;
2601
2602 state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_CONSUMER;
2603 /* state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_PRO; */
2604 state->m_FeAgRegAgAgcSio = DRXD_DEF_AG_AGC_SIO;
2605 return 0;
2606}
2607
2608int DRXD_init(struct drxd_state *state, const u8 * fw, u32 fw_size)
2609{
2610 int status = 0;
2611 u32 driverVersion;
2612
2613 if (state->init_done)
2614 return 0;
2615
2616 CDRXD(state, state->config.IF ? state->config.IF : 36000000);
2617
2618 do {
2619 state->operation_mode = OM_Default;
2620
2621 status = SetDeviceTypeId(state);
2622 if (status < 0)
2623 break;
2624
2625 /* Apply I2c address patch to B1 */
2626 if (!state->type_A && state->m_HiI2cPatch != NULL)
2627 status = WriteTable(state, state->m_HiI2cPatch);
2628 if (status < 0)
2629 break;
2630
2631 if (state->type_A) {
2632 /* HI firmware patch for UIO readout,
2633 avoid clearing of result register */
2634 status = Write16(state, 0x43012D, 0x047f, 0);
2635 if (status < 0)
2636 break;
2637 }
2638
2639 status = HI_ResetCommand(state);
2640 if (status < 0)
2641 break;
2642
2643 status = StopAllProcessors(state);
2644 if (status < 0)
2645 break;
2646 status = InitCC(state);
2647 if (status < 0)
2648 break;
2649
2650 state->osc_clock_deviation = 0;
2651
2652 if (state->config.osc_deviation)
2653 state->osc_clock_deviation =
2654 state->config.osc_deviation(state->priv, 0, 0);
2655 {
2656 /* Handle clock deviation */
2657 s32 devB;
2658 s32 devA = (s32) (state->osc_clock_deviation) *
2659 (s32) (state->expected_sys_clock_freq);
2660 /* deviation in kHz */
2661 s32 deviation = (devA / (1000000L));
2662 /* rounding, signed */
2663 if (devA > 0)
2664 devB = (2);
2665 else
2666 devB = (-2);
2667 if ((devB * (devA % 1000000L) > 1000000L)) {
2668 /* add +1 or -1 */
2669 deviation += (devB / 2);
2670 }
2671
2672 state->sys_clock_freq =
2673 (u16) ((state->expected_sys_clock_freq) +
2674 deviation);
2675 }
2676 status = InitHI(state);
2677 if (status < 0)
2678 break;
2679 status = InitAtomicRead(state);
2680 if (status < 0)
2681 break;
2682
2683 status = EnableAndResetMB(state);
2684 if (status < 0)
2685 break;
2686 if (state->type_A)
2687 status = ResetCEFR(state);
2688 if (status < 0)
2689 break;
2690
2691 if (fw) {
2692 status = DownloadMicrocode(state, fw, fw_size);
2693 if (status < 0)
2694 break;
2695 } else {
2696 status = DownloadMicrocode(state, state->microcode, state->microcode_length);
2697 if (status < 0)
2698 break;
2699 }
2700
2701 if (state->PGA) {
2702 state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_PRO;
2703 SetCfgPga(state, 0); /* PGA = 0 dB */
2704 } else {
2705 state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_CONSUMER;
2706 }
2707
2708 state->m_FeAgRegAgAgcSio = DRXD_DEF_AG_AGC_SIO;
2709
2710 status = InitFE(state);
2711 if (status < 0)
2712 break;
2713 status = InitFT(state);
2714 if (status < 0)
2715 break;
2716 status = InitCP(state);
2717 if (status < 0)
2718 break;
2719 status = InitCE(state);
2720 if (status < 0)
2721 break;
2722 status = InitEQ(state);
2723 if (status < 0)
2724 break;
2725 status = InitEC(state);
2726 if (status < 0)
2727 break;
2728 status = InitSC(state);
2729 if (status < 0)
2730 break;
2731
2732 status = SetCfgIfAgc(state, &state->if_agc_cfg);
2733 if (status < 0)
2734 break;
2735 status = SetCfgRfAgc(state, &state->rf_agc_cfg);
2736 if (status < 0)
2737 break;
2738
2739 state->cscd_state = CSCD_INIT;
2740 status = Write16(state, SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
2741 if (status < 0)
2742 break;
2743 status = Write16(state, LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
2744 if (status < 0)
2745 break;
2746
2747 driverVersion = (((VERSION_MAJOR / 10) << 4) +
2748 (VERSION_MAJOR % 10)) << 24;
2749 driverVersion += (((VERSION_MINOR / 10) << 4) +
2750 (VERSION_MINOR % 10)) << 16;
2751 driverVersion += ((VERSION_PATCH / 1000) << 12) +
2752 ((VERSION_PATCH / 100) << 8) +
2753 ((VERSION_PATCH / 10) << 4) + (VERSION_PATCH % 10);
2754
2755 status = Write32(state, SC_RA_RAM_DRIVER_VERSION__AX, driverVersion, 0);
2756 if (status < 0)
2757 break;
2758
2759 status = StopOC(state);
2760 if (status < 0)
2761 break;
2762
2763 state->drxd_state = DRXD_STOPPED;
2764 state->init_done = 1;
2765 status = 0;
2766 } while (0);
2767 return status;
2768}
2769
2770int DRXD_status(struct drxd_state *state, u32 * pLockStatus)
2771{
2772 DRX_GetLockStatus(state, pLockStatus);
2773
2774 /*if (*pLockStatus&DRX_LOCK_MPEG) */
2775 if (*pLockStatus & DRX_LOCK_FEC) {
2776 ConfigureMPEGOutput(state, 1);
2777 /* Get status again, in case we have MPEG lock now */
2778 /*DRX_GetLockStatus(state, pLockStatus); */
2779 }
2780
2781 return 0;
2782}
2783
2784/****************************************************************************/
2785/****************************************************************************/
2786/****************************************************************************/
2787
2788static int drxd_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2789{
2790 struct drxd_state *state = fe->demodulator_priv;
2791 u32 value;
2792 int res;
2793
2794 res = ReadIFAgc(state, &value);
2795 if (res < 0)
2796 *strength = 0;
2797 else
2798 *strength = 0xffff - (value << 4);
2799 return 0;
2800}
2801
2802static int drxd_read_status(struct dvb_frontend *fe, fe_status_t * status)
2803{
2804 struct drxd_state *state = fe->demodulator_priv;
2805 u32 lock;
2806
2807 DRXD_status(state, &lock);
2808 *status = 0;
2809 /* No MPEG lock in V255 firmware, bug ? */
2810#if 1
2811 if (lock & DRX_LOCK_MPEG)
2812 *status |= FE_HAS_LOCK;
2813#else
2814 if (lock & DRX_LOCK_FEC)
2815 *status |= FE_HAS_LOCK;
2816#endif
2817 if (lock & DRX_LOCK_FEC)
2818 *status |= FE_HAS_VITERBI | FE_HAS_SYNC;
2819 if (lock & DRX_LOCK_DEMOD)
2820 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
2821
2822 return 0;
2823}
2824
2825static int drxd_init(struct dvb_frontend *fe)
2826{
2827 struct drxd_state *state = fe->demodulator_priv;
2828 int err = 0;
2829
2830/* if (request_firmware(&state->fw, "drxd.fw", state->dev)<0) */
2831 return DRXD_init(state, 0, 0);
2832
2833 err = DRXD_init(state, state->fw->data, state->fw->size);
2834 release_firmware(state->fw);
2835 return err;
2836}
2837
2838int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
2839{
2840 struct drxd_state *state = fe->demodulator_priv;
2841
2842 if (state->config.disable_i2c_gate_ctrl == 1)
2843 return 0;
2844
2845 return DRX_ConfigureI2CBridge(state, onoff);
2846}
2847EXPORT_SYMBOL(drxd_config_i2c);
2848
2849static int drxd_get_tune_settings(struct dvb_frontend *fe,
2850 struct dvb_frontend_tune_settings *sets)
2851{
2852 sets->min_delay_ms = 10000;
2853 sets->max_drift = 0;
2854 sets->step_size = 0;
2855 return 0;
2856}
2857
2858static int drxd_read_ber(struct dvb_frontend *fe, u32 * ber)
2859{
2860 *ber = 0;
2861 return 0;
2862}
2863
2864static int drxd_read_snr(struct dvb_frontend *fe, u16 * snr)
2865{
2866 *snr = 0;
2867 return 0;
2868}
2869
2870static int drxd_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
2871{
2872 *ucblocks = 0;
2873 return 0;
2874}
2875
2876static int drxd_sleep(struct dvb_frontend *fe)
2877{
2878 struct drxd_state *state = fe->demodulator_priv;
2879
2880 ConfigureMPEGOutput(state, 0);
2881 return 0;
2882}
2883
2884static int drxd_get_frontend(struct dvb_frontend *fe,
2885 struct dvb_frontend_parameters *param)
2886{
2887 return 0;
2888}
2889
2890static int drxd_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
2891{
2892 return drxd_config_i2c(fe, enable);
2893}
2894
2895static int drxd_set_frontend(struct dvb_frontend *fe,
2896 struct dvb_frontend_parameters *param)
2897{
2898 struct drxd_state *state = fe->demodulator_priv;
2899 s32 off = 0;
2900
2901 state->param = *param;
2902 DRX_Stop(state);
2903
2904 if (fe->ops.tuner_ops.set_params) {
2905 fe->ops.tuner_ops.set_params(fe, param);
2906 if (fe->ops.i2c_gate_ctrl)
2907 fe->ops.i2c_gate_ctrl(fe, 0);
2908 }
2909
2910 /* FIXME: move PLL drivers */
2911 if (state->config.pll_set &&
2912 state->config.pll_set(state->priv, param,
2913 state->config.pll_address,
2914 state->config.demoda_address, &off) < 0) {
2915 printk(KERN_ERR "Error in pll_set\n");
2916 return -1;
2917 }
2918
2919 msleep(200);
2920
2921 return DRX_Start(state, off);
2922}
2923
2924static void drxd_release(struct dvb_frontend *fe)
2925{
2926 struct drxd_state *state = fe->demodulator_priv;
2927
2928 kfree(state);
2929}
2930
2931static struct dvb_frontend_ops drxd_ops = {
2932
2933 .info = {
2934 .name = "Micronas DRXD DVB-T",
2935 .type = FE_OFDM,
2936 .frequency_min = 47125000,
2937 .frequency_max = 855250000,
2938 .frequency_stepsize = 166667,
2939 .frequency_tolerance = 0,
2940 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
2941 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
2942 FE_CAN_FEC_AUTO |
2943 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
2944 FE_CAN_QAM_AUTO |
2945 FE_CAN_TRANSMISSION_MODE_AUTO |
2946 FE_CAN_GUARD_INTERVAL_AUTO |
2947 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
2948
2949 .release = drxd_release,
2950 .init = drxd_init,
2951 .sleep = drxd_sleep,
2952 .i2c_gate_ctrl = drxd_i2c_gate_ctrl,
2953
2954 .set_frontend = drxd_set_frontend,
2955 .get_frontend = drxd_get_frontend,
2956 .get_tune_settings = drxd_get_tune_settings,
2957
2958 .read_status = drxd_read_status,
2959 .read_ber = drxd_read_ber,
2960 .read_signal_strength = drxd_read_signal_strength,
2961 .read_snr = drxd_read_snr,
2962 .read_ucblocks = drxd_read_ucblocks,
2963};
2964
2965struct dvb_frontend *drxd_attach(const struct drxd_config *config,
2966 void *priv, struct i2c_adapter *i2c,
2967 struct device *dev)
2968{
2969 struct drxd_state *state = NULL;
2970
2971 state = kmalloc(sizeof(struct drxd_state), GFP_KERNEL);
2972 if (!state)
2973 return NULL;
2974 memset(state, 0, sizeof(*state));
2975
2976 memcpy(&state->ops, &drxd_ops, sizeof(struct dvb_frontend_ops));
2977 state->dev = dev;
2978 state->config = *config;
2979 state->i2c = i2c;
2980 state->priv = priv;
2981
2982 mutex_init(&state->mutex);
2983
2984 if (Read16(state, 0, 0, 0) < 0)
2985 goto error;
2986
2987 memcpy(&state->frontend.ops, &drxd_ops,
2988 sizeof(struct dvb_frontend_ops));
2989 state->frontend.demodulator_priv = state;
2990 ConfigureMPEGOutput(state, 0);
2991 return &state->frontend;
2992
2993error:
2994 printk(KERN_ERR "drxd: not found\n");
2995 kfree(state);
2996 return NULL;
2997}
2998EXPORT_SYMBOL(drxd_attach);
2999
3000MODULE_DESCRIPTION("DRXD driver");
3001MODULE_AUTHOR("Micronas");
3002MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/drxd_map_firm.h b/drivers/media/dvb/frontends/drxd_map_firm.h
new file mode 100644
index 00000000000..6bc553abf21
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxd_map_firm.h
@@ -0,0 +1,1013 @@
1/*
2 * drx3973d_map_firm.h
3 *
4 * Copyright (C) 2006-2007 Micronas
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
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 *
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., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#ifndef __DRX3973D_MAP__H__
25#define __DRX3973D_MAP__H__
26
27/*
28 * Note: originally, this file contained 12000+ lines of data
29 * Probably a few lines for every firwmare assembler instruction. However,
30 * only a few defines were actually used. So, removed all uneeded lines.
31 * If ever needed, the other lines can be easily obtained via git history.
32 */
33
34#define HI_COMM_EXEC__A 0x400000
35#define HI_COMM_MB__A 0x400002
36#define HI_CT_REG_COMM_STATE__A 0x410001
37#define HI_RA_RAM_SRV_RES__A 0x420031
38#define HI_RA_RAM_SRV_CMD__A 0x420032
39#define HI_RA_RAM_SRV_CMD_RESET 0x2
40#define HI_RA_RAM_SRV_CMD_CONFIG 0x3
41#define HI_RA_RAM_SRV_CMD_EXECUTE 0x6
42#define HI_RA_RAM_SRV_RST_KEY__A 0x420033
43#define HI_RA_RAM_SRV_RST_KEY_ACT 0x3973
44#define HI_RA_RAM_SRV_CFG_KEY__A 0x420033
45#define HI_RA_RAM_SRV_CFG_DIV__A 0x420034
46#define HI_RA_RAM_SRV_CFG_BDL__A 0x420035
47#define HI_RA_RAM_SRV_CFG_WUP__A 0x420036
48#define HI_RA_RAM_SRV_CFG_ACT__A 0x420037
49#define HI_RA_RAM_SRV_CFG_ACT_SLV0_ON 0x1
50#define HI_RA_RAM_SRV_CFG_ACT_BRD__M 0x4
51#define HI_RA_RAM_SRV_CFG_ACT_BRD_OFF 0x0
52#define HI_RA_RAM_SRV_CFG_ACT_BRD_ON 0x4
53#define HI_RA_RAM_SRV_CFG_ACT_PWD_EXE 0x8
54#define HI_RA_RAM_USR_BEGIN__A 0x420040
55#define HI_IF_RAM_TRP_BPT0__AX 0x430000
56#define HI_IF_RAM_USR_BEGIN__A 0x430200
57#define SC_COMM_EXEC__A 0x800000
58#define SC_COMM_EXEC_CTL_STOP 0x0
59#define SC_COMM_STATE__A 0x800001
60#define SC_RA_RAM_PARAM0__A 0x820040
61#define SC_RA_RAM_PARAM1__A 0x820041
62#define SC_RA_RAM_CMD_ADDR__A 0x820042
63#define SC_RA_RAM_CMD__A 0x820043
64#define SC_RA_RAM_CMD_PROC_START 0x1
65#define SC_RA_RAM_CMD_SET_PREF_PARAM 0x3
66#define SC_RA_RAM_CMD_GET_OP_PARAM 0x5
67#define SC_RA_RAM_SW_EVENT_RUN_NMASK__M 0x1
68#define SC_RA_RAM_LOCKTRACK_MIN 0x1
69#define SC_RA_RAM_OP_PARAM_MODE_2K 0x0
70#define SC_RA_RAM_OP_PARAM_MODE_8K 0x1
71#define SC_RA_RAM_OP_PARAM_GUARD_32 0x0
72#define SC_RA_RAM_OP_PARAM_GUARD_16 0x4
73#define SC_RA_RAM_OP_PARAM_GUARD_8 0x8
74#define SC_RA_RAM_OP_PARAM_GUARD_4 0xC
75#define SC_RA_RAM_OP_PARAM_CONST_QPSK 0x0
76#define SC_RA_RAM_OP_PARAM_CONST_QAM16 0x10
77#define SC_RA_RAM_OP_PARAM_CONST_QAM64 0x20
78#define SC_RA_RAM_OP_PARAM_HIER_NO 0x0
79#define SC_RA_RAM_OP_PARAM_HIER_A1 0x40
80#define SC_RA_RAM_OP_PARAM_HIER_A2 0x80
81#define SC_RA_RAM_OP_PARAM_HIER_A4 0xC0
82#define SC_RA_RAM_OP_PARAM_RATE_1_2 0x0
83#define SC_RA_RAM_OP_PARAM_RATE_2_3 0x200
84#define SC_RA_RAM_OP_PARAM_RATE_3_4 0x400
85#define SC_RA_RAM_OP_PARAM_RATE_5_6 0x600
86#define SC_RA_RAM_OP_PARAM_RATE_7_8 0x800
87#define SC_RA_RAM_OP_PARAM_PRIO_HI 0x0
88#define SC_RA_RAM_OP_PARAM_PRIO_LO 0x1000
89#define SC_RA_RAM_OP_AUTO_MODE__M 0x1
90#define SC_RA_RAM_OP_AUTO_GUARD__M 0x2
91#define SC_RA_RAM_OP_AUTO_CONST__M 0x4
92#define SC_RA_RAM_OP_AUTO_HIER__M 0x8
93#define SC_RA_RAM_OP_AUTO_RATE__M 0x10
94#define SC_RA_RAM_LOCK__A 0x82004B
95#define SC_RA_RAM_LOCK_DEMOD__M 0x1
96#define SC_RA_RAM_LOCK_FEC__M 0x2
97#define SC_RA_RAM_LOCK_MPEG__M 0x4
98#define SC_RA_RAM_BE_OPT_ENA__A 0x82004C
99#define SC_RA_RAM_BE_OPT_ENA_CP_OPT 0x1
100#define SC_RA_RAM_BE_OPT_DELAY__A 0x82004D
101#define SC_RA_RAM_CONFIG__A 0x820050
102#define SC_RA_RAM_CONFIG_FR_ENABLE__M 0x4
103#define SC_RA_RAM_CONFIG_FREQSCAN__M 0x10
104#define SC_RA_RAM_CONFIG_SLAVE__M 0x20
105#define SC_RA_RAM_IF_SAVE__AX 0x82008E
106#define SC_RA_RAM_IR_COARSE_2K_LENGTH__A 0x8200D1
107#define SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE 0x9
108#define SC_RA_RAM_IR_COARSE_2K_FREQINC__A 0x8200D2
109#define SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE 0x4
110#define SC_RA_RAM_IR_COARSE_2K_KAISINC__A 0x8200D3
111#define SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE 0x100
112#define SC_RA_RAM_IR_COARSE_8K_LENGTH__A 0x8200D4
113#define SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE 0x8
114#define SC_RA_RAM_IR_COARSE_8K_FREQINC__A 0x8200D5
115#define SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE 0x8
116#define SC_RA_RAM_IR_COARSE_8K_KAISINC__A 0x8200D6
117#define SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE 0x200
118#define SC_RA_RAM_IR_FINE_2K_LENGTH__A 0x8200D7
119#define SC_RA_RAM_IR_FINE_2K_LENGTH__PRE 0x9
120#define SC_RA_RAM_IR_FINE_2K_FREQINC__A 0x8200D8
121#define SC_RA_RAM_IR_FINE_2K_FREQINC__PRE 0x4
122#define SC_RA_RAM_IR_FINE_2K_KAISINC__A 0x8200D9
123#define SC_RA_RAM_IR_FINE_2K_KAISINC__PRE 0x100
124#define SC_RA_RAM_IR_FINE_8K_LENGTH__A 0x8200DA
125#define SC_RA_RAM_IR_FINE_8K_LENGTH__PRE 0xB
126#define SC_RA_RAM_IR_FINE_8K_FREQINC__A 0x8200DB
127#define SC_RA_RAM_IR_FINE_8K_FREQINC__PRE 0x1
128#define SC_RA_RAM_IR_FINE_8K_KAISINC__A 0x8200DC
129#define SC_RA_RAM_IR_FINE_8K_KAISINC__PRE 0x40
130#define SC_RA_RAM_ECHO_SHIFT_LIM__A 0x8200DD
131#define SC_RA_RAM_SAMPLE_RATE_COUNT__A 0x8200E8
132#define SC_RA_RAM_SAMPLE_RATE_STEP__A 0x8200E9
133#define SC_RA_RAM_BAND__A 0x8200EC
134#define SC_RA_RAM_LC_ABS_2K__A 0x8200F4
135#define SC_RA_RAM_LC_ABS_2K__PRE 0x1F
136#define SC_RA_RAM_LC_ABS_8K__A 0x8200F5
137#define SC_RA_RAM_LC_ABS_8K__PRE 0x1F
138#define SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE 0x1D6
139#define SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE 0x4
140#define SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE 0x1BB
141#define SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE 0x5
142#define SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE 0x1EF
143#define SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE 0x5
144#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE 0x15E
145#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE 0x5
146#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE 0x11A
147#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE 0x6
148#define SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE 0x1FB
149#define SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE 0x5
150#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE 0x12F
151#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE 0x5
152#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE 0x197
153#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE 0x5
154#define SC_RA_RAM_DRIVER_VERSION__AX 0x8201FE
155#define SC_RA_RAM_PROC_LOCKTRACK 0x0
156#define FE_COMM_EXEC__A 0xC00000
157#define FE_AD_REG_COMM_EXEC__A 0xC10000
158#define FE_AD_REG_FDB_IN__A 0xC10012
159#define FE_AD_REG_PD__A 0xC10013
160#define FE_AD_REG_INVEXT__A 0xC10014
161#define FE_AD_REG_CLKNEG__A 0xC10015
162#define FE_AG_REG_COMM_EXEC__A 0xC20000
163#define FE_AG_REG_AG_MODE_LOP__A 0xC20010
164#define FE_AG_REG_AG_MODE_LOP_MODE_4__M 0x10
165#define FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC 0x0
166#define FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC 0x10
167#define FE_AG_REG_AG_MODE_LOP_MODE_5__M 0x20
168#define FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC 0x0
169#define FE_AG_REG_AG_MODE_LOP_MODE_C__M 0x1000
170#define FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC 0x0
171#define FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC 0x1000
172#define FE_AG_REG_AG_MODE_LOP_MODE_E__M 0x4000
173#define FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC 0x0
174#define FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC 0x4000
175#define FE_AG_REG_AG_MODE_HIP__A 0xC20011
176#define FE_AG_REG_AG_PGA_MODE__A 0xC20012
177#define FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN 0x0
178#define FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN 0x1
179#define FE_AG_REG_AG_AGC_SIO__A 0xC20013
180#define FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M 0x2
181#define FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT 0x0
182#define FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT 0x2
183#define FE_AG_REG_AG_PWD__A 0xC20015
184#define FE_AG_REG_AG_PWD_PWD_PD2__M 0x2
185#define FE_AG_REG_AG_PWD_PWD_PD2_DISABLE 0x0
186#define FE_AG_REG_AG_PWD_PWD_PD2_ENABLE 0x2
187#define FE_AG_REG_DCE_AUR_CNT__A 0xC20016
188#define FE_AG_REG_DCE_RUR_CNT__A 0xC20017
189#define FE_AG_REG_ACE_AUR_CNT__A 0xC2001A
190#define FE_AG_REG_ACE_RUR_CNT__A 0xC2001B
191#define FE_AG_REG_CDR_RUR_CNT__A 0xC20020
192#define FE_AG_REG_EGC_RUR_CNT__A 0xC20024
193#define FE_AG_REG_EGC_SET_LVL__A 0xC20025
194#define FE_AG_REG_EGC_SET_LVL__M 0x1FF
195#define FE_AG_REG_EGC_FLA_RGN__A 0xC20026
196#define FE_AG_REG_EGC_SLO_RGN__A 0xC20027
197#define FE_AG_REG_EGC_JMP_PSN__A 0xC20028
198#define FE_AG_REG_EGC_FLA_INC__A 0xC20029
199#define FE_AG_REG_EGC_FLA_DEC__A 0xC2002A
200#define FE_AG_REG_EGC_SLO_INC__A 0xC2002B
201#define FE_AG_REG_EGC_SLO_DEC__A 0xC2002C
202#define FE_AG_REG_EGC_FAS_INC__A 0xC2002D
203#define FE_AG_REG_EGC_FAS_DEC__A 0xC2002E
204#define FE_AG_REG_PM1_AGC_WRI__A 0xC20030
205#define FE_AG_REG_PM1_AGC_WRI__M 0x7FF
206#define FE_AG_REG_GC1_AGC_RIC__A 0xC20031
207#define FE_AG_REG_GC1_AGC_OFF__A 0xC20032
208#define FE_AG_REG_GC1_AGC_MAX__A 0xC20033
209#define FE_AG_REG_GC1_AGC_MIN__A 0xC20034
210#define FE_AG_REG_GC1_AGC_DAT__A 0xC20035
211#define FE_AG_REG_GC1_AGC_DAT__M 0x3FF
212#define FE_AG_REG_PM2_AGC_WRI__A 0xC20036
213#define FE_AG_REG_IND_WIN__A 0xC2003C
214#define FE_AG_REG_IND_THD_LOL__A 0xC2003D
215#define FE_AG_REG_IND_THD_HIL__A 0xC2003E
216#define FE_AG_REG_IND_DEL__A 0xC2003F
217#define FE_AG_REG_IND_PD1_WRI__A 0xC20040
218#define FE_AG_REG_PDA_AUR_CNT__A 0xC20041
219#define FE_AG_REG_PDA_RUR_CNT__A 0xC20042
220#define FE_AG_REG_PDA_AVE_DAT__A 0xC20043
221#define FE_AG_REG_PDC_RUR_CNT__A 0xC20044
222#define FE_AG_REG_PDC_SET_LVL__A 0xC20045
223#define FE_AG_REG_PDC_FLA_RGN__A 0xC20046
224#define FE_AG_REG_PDC_JMP_PSN__A 0xC20047
225#define FE_AG_REG_PDC_FLA_STP__A 0xC20048
226#define FE_AG_REG_PDC_SLO_STP__A 0xC20049
227#define FE_AG_REG_PDC_PD2_WRI__A 0xC2004A
228#define FE_AG_REG_PDC_MAP_DAT__A 0xC2004B
229#define FE_AG_REG_PDC_MAX__A 0xC2004C
230#define FE_AG_REG_TGA_AUR_CNT__A 0xC2004D
231#define FE_AG_REG_TGA_RUR_CNT__A 0xC2004E
232#define FE_AG_REG_TGA_AVE_DAT__A 0xC2004F
233#define FE_AG_REG_TGC_RUR_CNT__A 0xC20050
234#define FE_AG_REG_TGC_SET_LVL__A 0xC20051
235#define FE_AG_REG_TGC_SET_LVL__M 0x3F
236#define FE_AG_REG_TGC_FLA_RGN__A 0xC20052
237#define FE_AG_REG_TGC_JMP_PSN__A 0xC20053
238#define FE_AG_REG_TGC_FLA_STP__A 0xC20054
239#define FE_AG_REG_TGC_SLO_STP__A 0xC20055
240#define FE_AG_REG_TGC_MAP_DAT__A 0xC20056
241#define FE_AG_REG_FGA_AUR_CNT__A 0xC20057
242#define FE_AG_REG_FGA_RUR_CNT__A 0xC20058
243#define FE_AG_REG_FGM_WRI__A 0xC20061
244#define FE_AG_REG_BGC_FGC_WRI__A 0xC20068
245#define FE_AG_REG_BGC_CGC_WRI__A 0xC20069
246#define FE_FS_REG_COMM_EXEC__A 0xC30000
247#define FE_FS_REG_ADD_INC_LOP__A 0xC30010
248#define FE_FD_REG_COMM_EXEC__A 0xC40000
249#define FE_FD_REG_SCL__A 0xC40010
250#define FE_FD_REG_MAX_LEV__A 0xC40011
251#define FE_FD_REG_NR__A 0xC40012
252#define FE_FD_REG_MEAS_VAL__A 0xC40014
253#define FE_IF_REG_COMM_EXEC__A 0xC50000
254#define FE_IF_REG_INCR0__A 0xC50010
255#define FE_IF_REG_INCR0__W 16
256#define FE_IF_REG_INCR0__M 0xFFFF
257#define FE_IF_REG_INCR1__A 0xC50011
258#define FE_IF_REG_INCR1__M 0xFF
259#define FE_CF_REG_COMM_EXEC__A 0xC60000
260#define FE_CF_REG_SCL__A 0xC60010
261#define FE_CF_REG_MAX_LEV__A 0xC60011
262#define FE_CF_REG_NR__A 0xC60012
263#define FE_CF_REG_IMP_VAL__A 0xC60013
264#define FE_CF_REG_MEAS_VAL__A 0xC60014
265#define FE_CU_REG_COMM_EXEC__A 0xC70000
266#define FE_CU_REG_FRM_CNT_RST__A 0xC70011
267#define FE_CU_REG_FRM_CNT_STR__A 0xC70012
268#define FT_COMM_EXEC__A 0x1000000
269#define FT_REG_COMM_EXEC__A 0x1010000
270#define CP_COMM_EXEC__A 0x1400000
271#define CP_REG_COMM_EXEC__A 0x1410000
272#define CP_REG_INTERVAL__A 0x1410011
273#define CP_REG_BR_SPL_OFFSET__A 0x1410023
274#define CP_REG_BR_STR_DEL__A 0x1410024
275#define CP_REG_RT_ANG_INC0__A 0x1410030
276#define CP_REG_RT_ANG_INC1__A 0x1410031
277#define CP_REG_RT_DETECT_ENA__A 0x1410032
278#define CP_REG_RT_DETECT_TRH__A 0x1410033
279#define CP_REG_RT_EXP_MARG__A 0x141003E
280#define CP_REG_AC_NEXP_OFFS__A 0x1410040
281#define CP_REG_AC_AVER_POW__A 0x1410041
282#define CP_REG_AC_MAX_POW__A 0x1410042
283#define CP_REG_AC_WEIGHT_MAN__A 0x1410043
284#define CP_REG_AC_WEIGHT_EXP__A 0x1410044
285#define CP_REG_AC_AMP_MODE__A 0x1410047
286#define CP_REG_AC_AMP_FIX__A 0x1410048
287#define CP_REG_AC_ANG_MODE__A 0x141004A
288#define CE_COMM_EXEC__A 0x1800000
289#define CE_REG_COMM_EXEC__A 0x1810000
290#define CE_REG_TAPSET__A 0x1810011
291#define CE_REG_AVG_POW__A 0x1810012
292#define CE_REG_MAX_POW__A 0x1810013
293#define CE_REG_ATT__A 0x1810014
294#define CE_REG_NRED__A 0x1810015
295#define CE_REG_NE_ERR_SELECT__A 0x1810043
296#define CE_REG_NE_TD_CAL__A 0x1810044
297#define CE_REG_NE_MIXAVG__A 0x1810046
298#define CE_REG_NE_NUPD_OFS__A 0x1810047
299#define CE_REG_PE_NEXP_OFFS__A 0x1810050
300#define CE_REG_PE_TIMESHIFT__A 0x1810051
301#define CE_REG_TP_A0_TAP_NEW__A 0x1810064
302#define CE_REG_TP_A0_TAP_NEW_VALID__A 0x1810065
303#define CE_REG_TP_A0_MU_LMS_STEP__A 0x1810066
304#define CE_REG_TP_A1_TAP_NEW__A 0x1810068
305#define CE_REG_TP_A1_TAP_NEW_VALID__A 0x1810069
306#define CE_REG_TP_A1_MU_LMS_STEP__A 0x181006A
307#define CE_REG_TI_NEXP_OFFS__A 0x1810070
308#define CE_REG_FI_SHT_INCR__A 0x1810090
309#define CE_REG_FI_EXP_NORM__A 0x1810091
310#define CE_REG_IR_INPUTSEL__A 0x18100A0
311#define CE_REG_IR_STARTPOS__A 0x18100A1
312#define CE_REG_IR_NEXP_THRES__A 0x18100A2
313#define CE_REG_FR_TREAL00__A 0x1820010
314#define CE_REG_FR_TIMAG00__A 0x1820011
315#define CE_REG_FR_TREAL01__A 0x1820012
316#define CE_REG_FR_TIMAG01__A 0x1820013
317#define CE_REG_FR_TREAL02__A 0x1820014
318#define CE_REG_FR_TIMAG02__A 0x1820015
319#define CE_REG_FR_TREAL03__A 0x1820016
320#define CE_REG_FR_TIMAG03__A 0x1820017
321#define CE_REG_FR_TREAL04__A 0x1820018
322#define CE_REG_FR_TIMAG04__A 0x1820019
323#define CE_REG_FR_TREAL05__A 0x182001A
324#define CE_REG_FR_TIMAG05__A 0x182001B
325#define CE_REG_FR_TREAL06__A 0x182001C
326#define CE_REG_FR_TIMAG06__A 0x182001D
327#define CE_REG_FR_TREAL07__A 0x182001E
328#define CE_REG_FR_TIMAG07__A 0x182001F
329#define CE_REG_FR_TREAL08__A 0x1820020
330#define CE_REG_FR_TIMAG08__A 0x1820021
331#define CE_REG_FR_TREAL09__A 0x1820022
332#define CE_REG_FR_TIMAG09__A 0x1820023
333#define CE_REG_FR_TREAL10__A 0x1820024
334#define CE_REG_FR_TIMAG10__A 0x1820025
335#define CE_REG_FR_TREAL11__A 0x1820026
336#define CE_REG_FR_TIMAG11__A 0x1820027
337#define CE_REG_FR_MID_TAP__A 0x1820028
338#define CE_REG_FR_SQS_G00__A 0x1820029
339#define CE_REG_FR_SQS_G01__A 0x182002A
340#define CE_REG_FR_SQS_G02__A 0x182002B
341#define CE_REG_FR_SQS_G03__A 0x182002C
342#define CE_REG_FR_SQS_G04__A 0x182002D
343#define CE_REG_FR_SQS_G05__A 0x182002E
344#define CE_REG_FR_SQS_G06__A 0x182002F
345#define CE_REG_FR_SQS_G07__A 0x1820030
346#define CE_REG_FR_SQS_G08__A 0x1820031
347#define CE_REG_FR_SQS_G09__A 0x1820032
348#define CE_REG_FR_SQS_G10__A 0x1820033
349#define CE_REG_FR_SQS_G11__A 0x1820034
350#define CE_REG_FR_SQS_G12__A 0x1820035
351#define CE_REG_FR_RIO_G00__A 0x1820036
352#define CE_REG_FR_RIO_G01__A 0x1820037
353#define CE_REG_FR_RIO_G02__A 0x1820038
354#define CE_REG_FR_RIO_G03__A 0x1820039
355#define CE_REG_FR_RIO_G04__A 0x182003A
356#define CE_REG_FR_RIO_G05__A 0x182003B
357#define CE_REG_FR_RIO_G06__A 0x182003C
358#define CE_REG_FR_RIO_G07__A 0x182003D
359#define CE_REG_FR_RIO_G08__A 0x182003E
360#define CE_REG_FR_RIO_G09__A 0x182003F
361#define CE_REG_FR_RIO_G10__A 0x1820040
362#define CE_REG_FR_MODE__A 0x1820041
363#define CE_REG_FR_SQS_TRH__A 0x1820042
364#define CE_REG_FR_RIO_GAIN__A 0x1820043
365#define CE_REG_FR_BYPASS__A 0x1820044
366#define CE_REG_FR_PM_SET__A 0x1820045
367#define CE_REG_FR_ERR_SH__A 0x1820046
368#define CE_REG_FR_MAN_SH__A 0x1820047
369#define CE_REG_FR_TAP_SH__A 0x1820048
370#define EQ_COMM_EXEC__A 0x1C00000
371#define EQ_REG_COMM_EXEC__A 0x1C10000
372#define EQ_REG_COMM_MB__A 0x1C10002
373#define EQ_REG_IS_GAIN_MAN__A 0x1C10015
374#define EQ_REG_IS_GAIN_EXP__A 0x1C10016
375#define EQ_REG_IS_CLIP_EXP__A 0x1C10017
376#define EQ_REG_SN_CEGAIN__A 0x1C1002A
377#define EQ_REG_SN_OFFSET__A 0x1C1002B
378#define EQ_REG_RC_SEL_CAR__A 0x1C10032
379#define EQ_REG_RC_SEL_CAR_INIT 0x0
380#define EQ_REG_RC_SEL_CAR_DIV_ON 0x1
381#define EQ_REG_RC_SEL_CAR_PASS_A_CC 0x0
382#define EQ_REG_RC_SEL_CAR_PASS_B_CE 0x2
383#define EQ_REG_RC_SEL_CAR_LOCAL_A_CC 0x0
384#define EQ_REG_RC_SEL_CAR_LOCAL_B_CE 0x8
385#define EQ_REG_RC_SEL_CAR_MEAS_A_CC 0x0
386#define EQ_REG_RC_SEL_CAR_MEAS_B_CE 0x20
387#define EQ_REG_OT_CONST__A 0x1C10046
388#define EQ_REG_OT_ALPHA__A 0x1C10047
389#define EQ_REG_OT_QNT_THRES0__A 0x1C10048
390#define EQ_REG_OT_QNT_THRES1__A 0x1C10049
391#define EQ_REG_OT_CSI_STEP__A 0x1C1004A
392#define EQ_REG_OT_CSI_OFFSET__A 0x1C1004B
393#define EQ_REG_TD_REQ_SMB_CNT__A 0x1C10061
394#define EQ_REG_TD_TPS_PWR_OFS__A 0x1C10062
395#define EC_SB_REG_COMM_EXEC__A 0x2010000
396#define EC_SB_REG_TR_MODE__A 0x2010010
397#define EC_SB_REG_TR_MODE_8K 0x0
398#define EC_SB_REG_TR_MODE_2K 0x1
399#define EC_SB_REG_CONST__A 0x2010011
400#define EC_SB_REG_CONST_QPSK 0x0
401#define EC_SB_REG_CONST_16QAM 0x1
402#define EC_SB_REG_CONST_64QAM 0x2
403#define EC_SB_REG_ALPHA__A 0x2010012
404#define EC_SB_REG_PRIOR__A 0x2010013
405#define EC_SB_REG_PRIOR_HI 0x0
406#define EC_SB_REG_PRIOR_LO 0x1
407#define EC_SB_REG_CSI_HI__A 0x2010014
408#define EC_SB_REG_CSI_LO__A 0x2010015
409#define EC_SB_REG_SMB_TGL__A 0x2010016
410#define EC_SB_REG_SNR_HI__A 0x2010017
411#define EC_SB_REG_SNR_MID__A 0x2010018
412#define EC_SB_REG_SNR_LO__A 0x2010019
413#define EC_SB_REG_SCALE_MSB__A 0x201001A
414#define EC_SB_REG_SCALE_BIT2__A 0x201001B
415#define EC_SB_REG_SCALE_LSB__A 0x201001C
416#define EC_SB_REG_CSI_OFS__A 0x201001D
417#define EC_VD_REG_COMM_EXEC__A 0x2090000
418#define EC_VD_REG_FORCE__A 0x2090010
419#define EC_VD_REG_SET_CODERATE__A 0x2090011
420#define EC_VD_REG_SET_CODERATE_C1_2 0x0
421#define EC_VD_REG_SET_CODERATE_C2_3 0x1
422#define EC_VD_REG_SET_CODERATE_C3_4 0x2
423#define EC_VD_REG_SET_CODERATE_C5_6 0x3
424#define EC_VD_REG_SET_CODERATE_C7_8 0x4
425#define EC_VD_REG_REQ_SMB_CNT__A 0x2090012
426#define EC_VD_REG_RLK_ENA__A 0x2090014
427#define EC_OD_REG_COMM_EXEC__A 0x2110000
428#define EC_OD_REG_SYNC__A 0x2110010
429#define EC_OD_DEINT_RAM__A 0x2120000
430#define EC_RS_REG_COMM_EXEC__A 0x2130000
431#define EC_RS_REG_REQ_PCK_CNT__A 0x2130010
432#define EC_RS_REG_VAL__A 0x2130011
433#define EC_RS_REG_VAL_PCK 0x1
434#define EC_RS_EC_RAM__A 0x2140000
435#define EC_OC_REG_COMM_EXEC__A 0x2150000
436#define EC_OC_REG_COMM_EXEC_CTL_ACTIVE 0x1
437#define EC_OC_REG_COMM_EXEC_CTL_HOLD 0x2
438#define EC_OC_REG_COMM_INT_STA__A 0x2150007
439#define EC_OC_REG_OC_MODE_LOP__A 0x2150010
440#define EC_OC_REG_OC_MODE_LOP_PAR_ENA__M 0x1
441#define EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE 0x0
442#define EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE 0x1
443#define EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M 0x4
444#define EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC 0x0
445#define EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M 0x80
446#define EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL 0x80
447#define EC_OC_REG_OC_MODE_HIP__A 0x2150011
448#define EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR 0x10
449#define EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M 0x200
450#define EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE 0x0
451#define EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE 0x200
452#define EC_OC_REG_OC_MPG_SIO__A 0x2150012
453#define EC_OC_REG_OC_MPG_SIO__M 0xFFF
454#define EC_OC_REG_OC_MON_SIO__A 0x2150013
455#define EC_OC_REG_DTO_INC_LOP__A 0x2150014
456#define EC_OC_REG_DTO_INC_HIP__A 0x2150015
457#define EC_OC_REG_SNC_ISC_LVL__A 0x2150016
458#define EC_OC_REG_SNC_ISC_LVL_OSC__M 0xF0
459#define EC_OC_REG_TMD_TOP_MODE__A 0x215001D
460#define EC_OC_REG_TMD_TOP_CNT__A 0x215001E
461#define EC_OC_REG_TMD_HIL_MAR__A 0x215001F
462#define EC_OC_REG_TMD_LOL_MAR__A 0x2150020
463#define EC_OC_REG_TMD_CUR_CNT__A 0x2150021
464#define EC_OC_REG_AVR_ASH_CNT__A 0x2150023
465#define EC_OC_REG_AVR_BSH_CNT__A 0x2150024
466#define EC_OC_REG_RCN_MODE__A 0x2150027
467#define EC_OC_REG_RCN_CRA_LOP__A 0x2150028
468#define EC_OC_REG_RCN_CRA_HIP__A 0x2150029
469#define EC_OC_REG_RCN_CST_LOP__A 0x215002A
470#define EC_OC_REG_RCN_CST_HIP__A 0x215002B
471#define EC_OC_REG_RCN_SET_LVL__A 0x215002C
472#define EC_OC_REG_RCN_GAI_LVL__A 0x215002D
473#define EC_OC_REG_RCN_CLP_LOP__A 0x2150032
474#define EC_OC_REG_RCN_CLP_HIP__A 0x2150033
475#define EC_OC_REG_RCN_MAP_LOP__A 0x2150034
476#define EC_OC_REG_RCN_MAP_HIP__A 0x2150035
477#define EC_OC_REG_OCR_MPG_UOS__A 0x2150036
478#define EC_OC_REG_OCR_MPG_UOS__M 0xFFF
479#define EC_OC_REG_OCR_MPG_UOS_INIT 0x0
480#define EC_OC_REG_OCR_MPG_USR_DAT__A 0x2150038
481#define EC_OC_REG_OCR_MON_UOS__A 0x2150039
482#define EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE 0x1
483#define EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE 0x2
484#define EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE 0x4
485#define EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE 0x8
486#define EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE 0x10
487#define EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE 0x20
488#define EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE 0x40
489#define EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE 0x80
490#define EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE 0x100
491#define EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE 0x200
492#define EC_OC_REG_OCR_MON_UOS_VAL_ENABLE 0x400
493#define EC_OC_REG_OCR_MON_UOS_CLK_ENABLE 0x800
494#define EC_OC_REG_OCR_MON_WRI__A 0x215003A
495#define EC_OC_REG_OCR_MON_WRI_INIT 0x0
496#define EC_OC_REG_IPR_INV_MPG__A 0x2150045
497#define CC_REG_OSC_MODE__A 0x2410010
498#define CC_REG_OSC_MODE_M20 0x1
499#define CC_REG_PLL_MODE__A 0x2410011
500#define CC_REG_PLL_MODE_BYPASS_PLL 0x1
501#define CC_REG_PLL_MODE_PUMP_CUR_12 0x14
502#define CC_REG_REF_DIVIDE__A 0x2410012
503#define CC_REG_PWD_MODE__A 0x2410015
504#define CC_REG_PWD_MODE_DOWN_PLL 0x2
505#define CC_REG_UPDATE__A 0x2410017
506#define CC_REG_UPDATE_KEY 0x3973
507#define CC_REG_JTAGID_L__A 0x2410019
508#define LC_COMM_EXEC__A 0x2800000
509#define LC_RA_RAM_IFINCR_NOM_L__A 0x282000C
510#define LC_RA_RAM_FILTER_SYM_SET__A 0x282001A
511#define LC_RA_RAM_FILTER_SYM_SET__PRE 0x3E8
512#define LC_RA_RAM_FILTER_CRMM_A__A 0x2820060
513#define LC_RA_RAM_FILTER_CRMM_A__PRE 0x4
514#define LC_RA_RAM_FILTER_CRMM_B__A 0x2820061
515#define LC_RA_RAM_FILTER_CRMM_B__PRE 0x1
516#define LC_RA_RAM_FILTER_SRMM_A__A 0x2820068
517#define LC_RA_RAM_FILTER_SRMM_A__PRE 0x4
518#define LC_RA_RAM_FILTER_SRMM_B__A 0x2820069
519#define LC_RA_RAM_FILTER_SRMM_B__PRE 0x1
520#define B_HI_COMM_EXEC__A 0x400000
521#define B_HI_COMM_MB__A 0x400002
522#define B_HI_CT_REG_COMM_STATE__A 0x410001
523#define B_HI_RA_RAM_SRV_RES__A 0x420031
524#define B_HI_RA_RAM_SRV_CMD__A 0x420032
525#define B_HI_RA_RAM_SRV_CMD_RESET 0x2
526#define B_HI_RA_RAM_SRV_CMD_CONFIG 0x3
527#define B_HI_RA_RAM_SRV_CMD_EXECUTE 0x6
528#define B_HI_RA_RAM_SRV_RST_KEY__A 0x420033
529#define B_HI_RA_RAM_SRV_RST_KEY_ACT 0x3973
530#define B_HI_RA_RAM_SRV_CFG_KEY__A 0x420033
531#define B_HI_RA_RAM_SRV_CFG_DIV__A 0x420034
532#define B_HI_RA_RAM_SRV_CFG_BDL__A 0x420035
533#define B_HI_RA_RAM_SRV_CFG_WUP__A 0x420036
534#define B_HI_RA_RAM_SRV_CFG_ACT__A 0x420037
535#define B_HI_RA_RAM_SRV_CFG_ACT_SLV0_ON 0x1
536#define B_HI_RA_RAM_SRV_CFG_ACT_BRD__M 0x4
537#define B_HI_RA_RAM_SRV_CFG_ACT_BRD_OFF 0x0
538#define B_HI_RA_RAM_SRV_CFG_ACT_BRD_ON 0x4
539#define B_HI_RA_RAM_SRV_CFG_ACT_PWD_EXE 0x8
540#define B_HI_RA_RAM_USR_BEGIN__A 0x420040
541#define B_HI_IF_RAM_TRP_BPT0__AX 0x430000
542#define B_HI_IF_RAM_USR_BEGIN__A 0x430200
543#define B_SC_COMM_EXEC__A 0x800000
544#define B_SC_COMM_EXEC_CTL_STOP 0x0
545#define B_SC_COMM_STATE__A 0x800001
546#define B_SC_RA_RAM_PARAM0__A 0x820040
547#define B_SC_RA_RAM_PARAM1__A 0x820041
548#define B_SC_RA_RAM_CMD_ADDR__A 0x820042
549#define B_SC_RA_RAM_CMD__A 0x820043
550#define B_SC_RA_RAM_CMD_PROC_START 0x1
551#define B_SC_RA_RAM_CMD_SET_PREF_PARAM 0x3
552#define B_SC_RA_RAM_CMD_GET_OP_PARAM 0x5
553#define B_SC_RA_RAM_SW_EVENT_RUN_NMASK__M 0x1
554#define B_SC_RA_RAM_LOCKTRACK_MIN 0x1
555#define B_SC_RA_RAM_OP_PARAM_MODE_2K 0x0
556#define B_SC_RA_RAM_OP_PARAM_MODE_8K 0x1
557#define B_SC_RA_RAM_OP_PARAM_GUARD_32 0x0
558#define B_SC_RA_RAM_OP_PARAM_GUARD_16 0x4
559#define B_SC_RA_RAM_OP_PARAM_GUARD_8 0x8
560#define B_SC_RA_RAM_OP_PARAM_GUARD_4 0xC
561#define B_SC_RA_RAM_OP_PARAM_CONST_QPSK 0x0
562#define B_SC_RA_RAM_OP_PARAM_CONST_QAM16 0x10
563#define B_SC_RA_RAM_OP_PARAM_CONST_QAM64 0x20
564#define B_SC_RA_RAM_OP_PARAM_HIER_NO 0x0
565#define B_SC_RA_RAM_OP_PARAM_HIER_A1 0x40
566#define B_SC_RA_RAM_OP_PARAM_HIER_A2 0x80
567#define B_SC_RA_RAM_OP_PARAM_HIER_A4 0xC0
568#define B_SC_RA_RAM_OP_PARAM_RATE_1_2 0x0
569#define B_SC_RA_RAM_OP_PARAM_RATE_2_3 0x200
570#define B_SC_RA_RAM_OP_PARAM_RATE_3_4 0x400
571#define B_SC_RA_RAM_OP_PARAM_RATE_5_6 0x600
572#define B_SC_RA_RAM_OP_PARAM_RATE_7_8 0x800
573#define B_SC_RA_RAM_OP_PARAM_PRIO_HI 0x0
574#define B_SC_RA_RAM_OP_PARAM_PRIO_LO 0x1000
575#define B_SC_RA_RAM_OP_AUTO_MODE__M 0x1
576#define B_SC_RA_RAM_OP_AUTO_GUARD__M 0x2
577#define B_SC_RA_RAM_OP_AUTO_CONST__M 0x4
578#define B_SC_RA_RAM_OP_AUTO_HIER__M 0x8
579#define B_SC_RA_RAM_OP_AUTO_RATE__M 0x10
580#define B_SC_RA_RAM_LOCK__A 0x82004B
581#define B_SC_RA_RAM_LOCK_DEMOD__M 0x1
582#define B_SC_RA_RAM_LOCK_FEC__M 0x2
583#define B_SC_RA_RAM_LOCK_MPEG__M 0x4
584#define B_SC_RA_RAM_BE_OPT_ENA__A 0x82004C
585#define B_SC_RA_RAM_BE_OPT_ENA_CP_OPT 0x1
586#define B_SC_RA_RAM_BE_OPT_DELAY__A 0x82004D
587#define B_SC_RA_RAM_CONFIG__A 0x820050
588#define B_SC_RA_RAM_CONFIG_FR_ENABLE__M 0x4
589#define B_SC_RA_RAM_CONFIG_FREQSCAN__M 0x10
590#define B_SC_RA_RAM_CONFIG_SLAVE__M 0x20
591#define B_SC_RA_RAM_CONFIG_DIV_BLANK_ENABLE__M 0x200
592#define B_SC_RA_RAM_CONFIG_DIV_ECHO_ENABLE__M 0x400
593#define B_SC_RA_RAM_CO_TD_CAL_2K__A 0x82005D
594#define B_SC_RA_RAM_CO_TD_CAL_8K__A 0x82005E
595#define B_SC_RA_RAM_IF_SAVE__AX 0x82008E
596#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A 0x820098
597#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A 0x820099
598#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A 0x82009A
599#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A 0x82009B
600#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A 0x82009C
601#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A 0x82009D
602#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A 0x82009E
603#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A 0x82009F
604#define B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A 0x8200D1
605#define B_SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE 0x9
606#define B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A 0x8200D2
607#define B_SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE 0x4
608#define B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A 0x8200D3
609#define B_SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE 0x100
610#define B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A 0x8200D4
611#define B_SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE 0x8
612#define B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A 0x8200D5
613#define B_SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE 0x8
614#define B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A 0x8200D6
615#define B_SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE 0x200
616#define B_SC_RA_RAM_IR_FINE_2K_LENGTH__A 0x8200D7
617#define B_SC_RA_RAM_IR_FINE_2K_LENGTH__PRE 0x9
618#define B_SC_RA_RAM_IR_FINE_2K_FREQINC__A 0x8200D8
619#define B_SC_RA_RAM_IR_FINE_2K_FREQINC__PRE 0x4
620#define B_SC_RA_RAM_IR_FINE_2K_KAISINC__A 0x8200D9
621#define B_SC_RA_RAM_IR_FINE_2K_KAISINC__PRE 0x100
622#define B_SC_RA_RAM_IR_FINE_8K_LENGTH__A 0x8200DA
623#define B_SC_RA_RAM_IR_FINE_8K_LENGTH__PRE 0xB
624#define B_SC_RA_RAM_IR_FINE_8K_FREQINC__A 0x8200DB
625#define B_SC_RA_RAM_IR_FINE_8K_FREQINC__PRE 0x1
626#define B_SC_RA_RAM_IR_FINE_8K_KAISINC__A 0x8200DC
627#define B_SC_RA_RAM_IR_FINE_8K_KAISINC__PRE 0x40
628#define B_SC_RA_RAM_ECHO_SHIFT_LIM__A 0x8200DD
629#define B_SC_RA_RAM_SAMPLE_RATE_COUNT__A 0x8200E8
630#define B_SC_RA_RAM_SAMPLE_RATE_STEP__A 0x8200E9
631#define B_SC_RA_RAM_BAND__A 0x8200EC
632#define B_SC_RA_RAM_LC_ABS_2K__A 0x8200F4
633#define B_SC_RA_RAM_LC_ABS_2K__PRE 0x1F
634#define B_SC_RA_RAM_LC_ABS_8K__A 0x8200F5
635#define B_SC_RA_RAM_LC_ABS_8K__PRE 0x1F
636#define B_SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE 0x100
637#define B_SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE 0x4
638#define B_SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE 0x1E2
639#define B_SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE 0x4
640#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE 0x10D
641#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE 0x5
642#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE 0x17D
643#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE 0x4
644#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE 0x133
645#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE 0x5
646#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE 0x114
647#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE 0x5
648#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE 0x14A
649#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE 0x4
650#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE 0x1BB
651#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE 0x4
652#define B_SC_RA_RAM_DRIVER_VERSION__AX 0x8201FE
653#define B_SC_RA_RAM_PROC_LOCKTRACK 0x0
654#define B_FE_COMM_EXEC__A 0xC00000
655#define B_FE_AD_REG_COMM_EXEC__A 0xC10000
656#define B_FE_AD_REG_FDB_IN__A 0xC10012
657#define B_FE_AD_REG_PD__A 0xC10013
658#define B_FE_AD_REG_INVEXT__A 0xC10014
659#define B_FE_AD_REG_CLKNEG__A 0xC10015
660#define B_FE_AG_REG_COMM_EXEC__A 0xC20000
661#define B_FE_AG_REG_AG_MODE_LOP__A 0xC20010
662#define B_FE_AG_REG_AG_MODE_LOP_MODE_4__M 0x10
663#define B_FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC 0x0
664#define B_FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC 0x10
665#define B_FE_AG_REG_AG_MODE_LOP_MODE_5__M 0x20
666#define B_FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC 0x0
667#define B_FE_AG_REG_AG_MODE_LOP_MODE_C__M 0x1000
668#define B_FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC 0x0
669#define B_FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC 0x1000
670#define B_FE_AG_REG_AG_MODE_LOP_MODE_E__M 0x4000
671#define B_FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC 0x0
672#define B_FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC 0x4000
673#define B_FE_AG_REG_AG_MODE_HIP__A 0xC20011
674#define B_FE_AG_REG_AG_MODE_HIP_MODE_J__M 0x8
675#define B_FE_AG_REG_AG_MODE_HIP_MODE_J_STATIC 0x0
676#define B_FE_AG_REG_AG_MODE_HIP_MODE_J_DYNAMIC 0x8
677#define B_FE_AG_REG_AG_PGA_MODE__A 0xC20012
678#define B_FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN 0x0
679#define B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN 0x1
680#define B_FE_AG_REG_AG_AGC_SIO__A 0xC20013
681#define B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M 0x2
682#define B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT 0x0
683#define B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT 0x2
684#define B_FE_AG_REG_AG_PWD__A 0xC20015
685#define B_FE_AG_REG_AG_PWD_PWD_PD2__M 0x2
686#define B_FE_AG_REG_AG_PWD_PWD_PD2_DISABLE 0x0
687#define B_FE_AG_REG_AG_PWD_PWD_PD2_ENABLE 0x2
688#define B_FE_AG_REG_DCE_AUR_CNT__A 0xC20016
689#define B_FE_AG_REG_DCE_RUR_CNT__A 0xC20017
690#define B_FE_AG_REG_ACE_AUR_CNT__A 0xC2001A
691#define B_FE_AG_REG_ACE_RUR_CNT__A 0xC2001B
692#define B_FE_AG_REG_CDR_RUR_CNT__A 0xC20020
693#define B_FE_AG_REG_EGC_RUR_CNT__A 0xC20024
694#define B_FE_AG_REG_EGC_SET_LVL__A 0xC20025
695#define B_FE_AG_REG_EGC_SET_LVL__M 0x1FF
696#define B_FE_AG_REG_EGC_FLA_RGN__A 0xC20026
697#define B_FE_AG_REG_EGC_SLO_RGN__A 0xC20027
698#define B_FE_AG_REG_EGC_JMP_PSN__A 0xC20028
699#define B_FE_AG_REG_EGC_FLA_INC__A 0xC20029
700#define B_FE_AG_REG_EGC_FLA_DEC__A 0xC2002A
701#define B_FE_AG_REG_EGC_SLO_INC__A 0xC2002B
702#define B_FE_AG_REG_EGC_SLO_DEC__A 0xC2002C
703#define B_FE_AG_REG_EGC_FAS_INC__A 0xC2002D
704#define B_FE_AG_REG_EGC_FAS_DEC__A 0xC2002E
705#define B_FE_AG_REG_PM1_AGC_WRI__A 0xC20030
706#define B_FE_AG_REG_PM1_AGC_WRI__M 0x7FF
707#define B_FE_AG_REG_GC1_AGC_RIC__A 0xC20031
708#define B_FE_AG_REG_GC1_AGC_OFF__A 0xC20032
709#define B_FE_AG_REG_GC1_AGC_MAX__A 0xC20033
710#define B_FE_AG_REG_GC1_AGC_MIN__A 0xC20034
711#define B_FE_AG_REG_GC1_AGC_DAT__A 0xC20035
712#define B_FE_AG_REG_GC1_AGC_DAT__M 0x3FF
713#define B_FE_AG_REG_PM2_AGC_WRI__A 0xC20036
714#define B_FE_AG_REG_IND_WIN__A 0xC2003C
715#define B_FE_AG_REG_IND_THD_LOL__A 0xC2003D
716#define B_FE_AG_REG_IND_THD_HIL__A 0xC2003E
717#define B_FE_AG_REG_IND_DEL__A 0xC2003F
718#define B_FE_AG_REG_IND_PD1_WRI__A 0xC20040
719#define B_FE_AG_REG_PDA_AUR_CNT__A 0xC20041
720#define B_FE_AG_REG_PDA_RUR_CNT__A 0xC20042
721#define B_FE_AG_REG_PDA_AVE_DAT__A 0xC20043
722#define B_FE_AG_REG_PDC_RUR_CNT__A 0xC20044
723#define B_FE_AG_REG_PDC_SET_LVL__A 0xC20045
724#define B_FE_AG_REG_PDC_FLA_RGN__A 0xC20046
725#define B_FE_AG_REG_PDC_JMP_PSN__A 0xC20047
726#define B_FE_AG_REG_PDC_FLA_STP__A 0xC20048
727#define B_FE_AG_REG_PDC_SLO_STP__A 0xC20049
728#define B_FE_AG_REG_PDC_PD2_WRI__A 0xC2004A
729#define B_FE_AG_REG_PDC_MAP_DAT__A 0xC2004B
730#define B_FE_AG_REG_PDC_MAX__A 0xC2004C
731#define B_FE_AG_REG_TGA_AUR_CNT__A 0xC2004D
732#define B_FE_AG_REG_TGA_RUR_CNT__A 0xC2004E
733#define B_FE_AG_REG_TGA_AVE_DAT__A 0xC2004F
734#define B_FE_AG_REG_TGC_RUR_CNT__A 0xC20050
735#define B_FE_AG_REG_TGC_SET_LVL__A 0xC20051
736#define B_FE_AG_REG_TGC_SET_LVL__M 0x3F
737#define B_FE_AG_REG_TGC_FLA_RGN__A 0xC20052
738#define B_FE_AG_REG_TGC_JMP_PSN__A 0xC20053
739#define B_FE_AG_REG_TGC_FLA_STP__A 0xC20054
740#define B_FE_AG_REG_TGC_SLO_STP__A 0xC20055
741#define B_FE_AG_REG_TGC_MAP_DAT__A 0xC20056
742#define B_FE_AG_REG_FGM_WRI__A 0xC20061
743#define B_FE_AG_REG_BGC_FGC_WRI__A 0xC20068
744#define B_FE_AG_REG_BGC_CGC_WRI__A 0xC20069
745#define B_FE_FS_REG_COMM_EXEC__A 0xC30000
746#define B_FE_FS_REG_ADD_INC_LOP__A 0xC30010
747#define B_FE_FD_REG_COMM_EXEC__A 0xC40000
748#define B_FE_FD_REG_SCL__A 0xC40010
749#define B_FE_FD_REG_MAX_LEV__A 0xC40011
750#define B_FE_FD_REG_NR__A 0xC40012
751#define B_FE_FD_REG_MEAS_VAL__A 0xC40014
752#define B_FE_IF_REG_COMM_EXEC__A 0xC50000
753#define B_FE_IF_REG_INCR0__A 0xC50010
754#define B_FE_IF_REG_INCR0__W 16
755#define B_FE_IF_REG_INCR0__M 0xFFFF
756#define B_FE_IF_REG_INCR1__A 0xC50011
757#define B_FE_IF_REG_INCR1__M 0xFF
758#define B_FE_CF_REG_COMM_EXEC__A 0xC60000
759#define B_FE_CF_REG_SCL__A 0xC60010
760#define B_FE_CF_REG_MAX_LEV__A 0xC60011
761#define B_FE_CF_REG_NR__A 0xC60012
762#define B_FE_CF_REG_IMP_VAL__A 0xC60013
763#define B_FE_CF_REG_MEAS_VAL__A 0xC60014
764#define B_FE_CU_REG_COMM_EXEC__A 0xC70000
765#define B_FE_CU_REG_FRM_CNT_RST__A 0xC70011
766#define B_FE_CU_REG_FRM_CNT_STR__A 0xC70012
767#define B_FE_CU_REG_CTR_NFC_ICR__A 0xC70020
768#define B_FE_CU_REG_CTR_NFC_OCR__A 0xC70021
769#define B_FE_CU_REG_DIV_NFC_CLP__A 0xC70027
770#define B_FT_COMM_EXEC__A 0x1000000
771#define B_FT_REG_COMM_EXEC__A 0x1010000
772#define B_CP_COMM_EXEC__A 0x1400000
773#define B_CP_REG_COMM_EXEC__A 0x1410000
774#define B_CP_REG_INTERVAL__A 0x1410011
775#define B_CP_REG_BR_SPL_OFFSET__A 0x1410023
776#define B_CP_REG_BR_STR_DEL__A 0x1410024
777#define B_CP_REG_RT_ANG_INC0__A 0x1410030
778#define B_CP_REG_RT_ANG_INC1__A 0x1410031
779#define B_CP_REG_RT_DETECT_TRH__A 0x1410033
780#define B_CP_REG_AC_NEXP_OFFS__A 0x1410040
781#define B_CP_REG_AC_AVER_POW__A 0x1410041
782#define B_CP_REG_AC_MAX_POW__A 0x1410042
783#define B_CP_REG_AC_WEIGHT_MAN__A 0x1410043
784#define B_CP_REG_AC_WEIGHT_EXP__A 0x1410044
785#define B_CP_REG_AC_AMP_MODE__A 0x1410047
786#define B_CP_REG_AC_AMP_FIX__A 0x1410048
787#define B_CP_REG_AC_ANG_MODE__A 0x141004A
788#define B_CE_COMM_EXEC__A 0x1800000
789#define B_CE_REG_COMM_EXEC__A 0x1810000
790#define B_CE_REG_TAPSET__A 0x1810011
791#define B_CE_REG_AVG_POW__A 0x1810012
792#define B_CE_REG_MAX_POW__A 0x1810013
793#define B_CE_REG_ATT__A 0x1810014
794#define B_CE_REG_NRED__A 0x1810015
795#define B_CE_REG_NE_ERR_SELECT__A 0x1810043
796#define B_CE_REG_NE_TD_CAL__A 0x1810044
797#define B_CE_REG_NE_MIXAVG__A 0x1810046
798#define B_CE_REG_NE_NUPD_OFS__A 0x1810047
799#define B_CE_REG_PE_NEXP_OFFS__A 0x1810050
800#define B_CE_REG_PE_TIMESHIFT__A 0x1810051
801#define B_CE_REG_TP_A0_TAP_NEW__A 0x1810064
802#define B_CE_REG_TP_A0_TAP_NEW_VALID__A 0x1810065
803#define B_CE_REG_TP_A0_MU_LMS_STEP__A 0x1810066
804#define B_CE_REG_TP_A1_TAP_NEW__A 0x1810068
805#define B_CE_REG_TP_A1_TAP_NEW_VALID__A 0x1810069
806#define B_CE_REG_TP_A1_MU_LMS_STEP__A 0x181006A
807#define B_CE_REG_TI_PHN_ENABLE__A 0x1810073
808#define B_CE_REG_FI_SHT_INCR__A 0x1810090
809#define B_CE_REG_FI_EXP_NORM__A 0x1810091
810#define B_CE_REG_IR_INPUTSEL__A 0x18100A0
811#define B_CE_REG_IR_STARTPOS__A 0x18100A1
812#define B_CE_REG_IR_NEXP_THRES__A 0x18100A2
813#define B_CE_REG_FR_TREAL00__A 0x1820010
814#define B_CE_REG_FR_TIMAG00__A 0x1820011
815#define B_CE_REG_FR_TREAL01__A 0x1820012
816#define B_CE_REG_FR_TIMAG01__A 0x1820013
817#define B_CE_REG_FR_TREAL02__A 0x1820014
818#define B_CE_REG_FR_TIMAG02__A 0x1820015
819#define B_CE_REG_FR_TREAL03__A 0x1820016
820#define B_CE_REG_FR_TIMAG03__A 0x1820017
821#define B_CE_REG_FR_TREAL04__A 0x1820018
822#define B_CE_REG_FR_TIMAG04__A 0x1820019
823#define B_CE_REG_FR_TREAL05__A 0x182001A
824#define B_CE_REG_FR_TIMAG05__A 0x182001B
825#define B_CE_REG_FR_TREAL06__A 0x182001C
826#define B_CE_REG_FR_TIMAG06__A 0x182001D
827#define B_CE_REG_FR_TREAL07__A 0x182001E
828#define B_CE_REG_FR_TIMAG07__A 0x182001F
829#define B_CE_REG_FR_TREAL08__A 0x1820020
830#define B_CE_REG_FR_TIMAG08__A 0x1820021
831#define B_CE_REG_FR_TREAL09__A 0x1820022
832#define B_CE_REG_FR_TIMAG09__A 0x1820023
833#define B_CE_REG_FR_TREAL10__A 0x1820024
834#define B_CE_REG_FR_TIMAG10__A 0x1820025
835#define B_CE_REG_FR_TREAL11__A 0x1820026
836#define B_CE_REG_FR_TIMAG11__A 0x1820027
837#define B_CE_REG_FR_MID_TAP__A 0x1820028
838#define B_CE_REG_FR_SQS_G00__A 0x1820029
839#define B_CE_REG_FR_SQS_G01__A 0x182002A
840#define B_CE_REG_FR_SQS_G02__A 0x182002B
841#define B_CE_REG_FR_SQS_G03__A 0x182002C
842#define B_CE_REG_FR_SQS_G04__A 0x182002D
843#define B_CE_REG_FR_SQS_G05__A 0x182002E
844#define B_CE_REG_FR_SQS_G06__A 0x182002F
845#define B_CE_REG_FR_SQS_G07__A 0x1820030
846#define B_CE_REG_FR_SQS_G08__A 0x1820031
847#define B_CE_REG_FR_SQS_G09__A 0x1820032
848#define B_CE_REG_FR_SQS_G10__A 0x1820033
849#define B_CE_REG_FR_SQS_G11__A 0x1820034
850#define B_CE_REG_FR_SQS_G12__A 0x1820035
851#define B_CE_REG_FR_RIO_G00__A 0x1820036
852#define B_CE_REG_FR_RIO_G01__A 0x1820037
853#define B_CE_REG_FR_RIO_G02__A 0x1820038
854#define B_CE_REG_FR_RIO_G03__A 0x1820039
855#define B_CE_REG_FR_RIO_G04__A 0x182003A
856#define B_CE_REG_FR_RIO_G05__A 0x182003B
857#define B_CE_REG_FR_RIO_G06__A 0x182003C
858#define B_CE_REG_FR_RIO_G07__A 0x182003D
859#define B_CE_REG_FR_RIO_G08__A 0x182003E
860#define B_CE_REG_FR_RIO_G09__A 0x182003F
861#define B_CE_REG_FR_RIO_G10__A 0x1820040
862#define B_CE_REG_FR_MODE__A 0x1820041
863#define B_CE_REG_FR_SQS_TRH__A 0x1820042
864#define B_CE_REG_FR_RIO_GAIN__A 0x1820043
865#define B_CE_REG_FR_BYPASS__A 0x1820044
866#define B_CE_REG_FR_PM_SET__A 0x1820045
867#define B_CE_REG_FR_ERR_SH__A 0x1820046
868#define B_CE_REG_FR_MAN_SH__A 0x1820047
869#define B_CE_REG_FR_TAP_SH__A 0x1820048
870#define B_EQ_COMM_EXEC__A 0x1C00000
871#define B_EQ_REG_COMM_EXEC__A 0x1C10000
872#define B_EQ_REG_COMM_MB__A 0x1C10002
873#define B_EQ_REG_IS_GAIN_MAN__A 0x1C10015
874#define B_EQ_REG_IS_GAIN_EXP__A 0x1C10016
875#define B_EQ_REG_IS_CLIP_EXP__A 0x1C10017
876#define B_EQ_REG_SN_CEGAIN__A 0x1C1002A
877#define B_EQ_REG_SN_OFFSET__A 0x1C1002B
878#define B_EQ_REG_RC_SEL_CAR__A 0x1C10032
879#define B_EQ_REG_RC_SEL_CAR_INIT 0x2
880#define B_EQ_REG_RC_SEL_CAR_DIV_ON 0x1
881#define B_EQ_REG_RC_SEL_CAR_PASS_A_CC 0x0
882#define B_EQ_REG_RC_SEL_CAR_PASS_B_CE 0x2
883#define B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC 0x0
884#define B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE 0x8
885#define B_EQ_REG_RC_SEL_CAR_MEAS_A_CC 0x0
886#define B_EQ_REG_RC_SEL_CAR_MEAS_B_CE 0x20
887#define B_EQ_REG_RC_SEL_CAR_FFTMODE__M 0x80
888#define B_EQ_REG_OT_CONST__A 0x1C10046
889#define B_EQ_REG_OT_ALPHA__A 0x1C10047
890#define B_EQ_REG_OT_QNT_THRES0__A 0x1C10048
891#define B_EQ_REG_OT_QNT_THRES1__A 0x1C10049
892#define B_EQ_REG_OT_CSI_STEP__A 0x1C1004A
893#define B_EQ_REG_OT_CSI_OFFSET__A 0x1C1004B
894#define B_EQ_REG_TD_REQ_SMB_CNT__A 0x1C10061
895#define B_EQ_REG_TD_TPS_PWR_OFS__A 0x1C10062
896#define B_EC_SB_REG_COMM_EXEC__A 0x2010000
897#define B_EC_SB_REG_TR_MODE__A 0x2010010
898#define B_EC_SB_REG_TR_MODE_8K 0x0
899#define B_EC_SB_REG_TR_MODE_2K 0x1
900#define B_EC_SB_REG_CONST__A 0x2010011
901#define B_EC_SB_REG_CONST_QPSK 0x0
902#define B_EC_SB_REG_CONST_16QAM 0x1
903#define B_EC_SB_REG_CONST_64QAM 0x2
904#define B_EC_SB_REG_ALPHA__A 0x2010012
905#define B_EC_SB_REG_PRIOR__A 0x2010013
906#define B_EC_SB_REG_PRIOR_HI 0x0
907#define B_EC_SB_REG_PRIOR_LO 0x1
908#define B_EC_SB_REG_CSI_HI__A 0x2010014
909#define B_EC_SB_REG_CSI_LO__A 0x2010015
910#define B_EC_SB_REG_SMB_TGL__A 0x2010016
911#define B_EC_SB_REG_SNR_HI__A 0x2010017
912#define B_EC_SB_REG_SNR_MID__A 0x2010018
913#define B_EC_SB_REG_SNR_LO__A 0x2010019
914#define B_EC_SB_REG_SCALE_MSB__A 0x201001A
915#define B_EC_SB_REG_SCALE_BIT2__A 0x201001B
916#define B_EC_SB_REG_SCALE_LSB__A 0x201001C
917#define B_EC_SB_REG_CSI_OFS0__A 0x201001D
918#define B_EC_SB_REG_CSI_OFS1__A 0x201001E
919#define B_EC_SB_REG_CSI_OFS2__A 0x201001F
920#define B_EC_VD_REG_COMM_EXEC__A 0x2090000
921#define B_EC_VD_REG_FORCE__A 0x2090010
922#define B_EC_VD_REG_SET_CODERATE__A 0x2090011
923#define B_EC_VD_REG_SET_CODERATE_C1_2 0x0
924#define B_EC_VD_REG_SET_CODERATE_C2_3 0x1
925#define B_EC_VD_REG_SET_CODERATE_C3_4 0x2
926#define B_EC_VD_REG_SET_CODERATE_C5_6 0x3
927#define B_EC_VD_REG_SET_CODERATE_C7_8 0x4
928#define B_EC_VD_REG_REQ_SMB_CNT__A 0x2090012
929#define B_EC_VD_REG_RLK_ENA__A 0x2090014
930#define B_EC_OD_REG_COMM_EXEC__A 0x2110000
931#define B_EC_OD_REG_SYNC__A 0x2110664
932#define B_EC_OD_DEINT_RAM__A 0x2120000
933#define B_EC_RS_REG_COMM_EXEC__A 0x2130000
934#define B_EC_RS_REG_REQ_PCK_CNT__A 0x2130010
935#define B_EC_RS_REG_VAL__A 0x2130011
936#define B_EC_RS_REG_VAL_PCK 0x1
937#define B_EC_RS_EC_RAM__A 0x2140000
938#define B_EC_OC_REG_COMM_EXEC__A 0x2150000
939#define B_EC_OC_REG_COMM_EXEC_CTL_ACTIVE 0x1
940#define B_EC_OC_REG_COMM_EXEC_CTL_HOLD 0x2
941#define B_EC_OC_REG_COMM_INT_STA__A 0x2150007
942#define B_EC_OC_REG_OC_MODE_LOP__A 0x2150010
943#define B_EC_OC_REG_OC_MODE_LOP_PAR_ENA__M 0x1
944#define B_EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE 0x0
945#define B_EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE 0x1
946#define B_EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M 0x4
947#define B_EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC 0x0
948#define B_EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M 0x80
949#define B_EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL 0x80
950#define B_EC_OC_REG_OC_MODE_HIP__A 0x2150011
951#define B_EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR 0x10
952#define B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M 0x200
953#define B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE 0x0
954#define B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE 0x200
955#define B_EC_OC_REG_OC_MPG_SIO__A 0x2150012
956#define B_EC_OC_REG_OC_MPG_SIO__M 0xFFF
957#define B_EC_OC_REG_DTO_INC_LOP__A 0x2150014
958#define B_EC_OC_REG_DTO_INC_HIP__A 0x2150015
959#define B_EC_OC_REG_SNC_ISC_LVL__A 0x2150016
960#define B_EC_OC_REG_SNC_ISC_LVL_OSC__M 0xF0
961#define B_EC_OC_REG_TMD_TOP_MODE__A 0x215001D
962#define B_EC_OC_REG_TMD_TOP_CNT__A 0x215001E
963#define B_EC_OC_REG_TMD_HIL_MAR__A 0x215001F
964#define B_EC_OC_REG_TMD_LOL_MAR__A 0x2150020
965#define B_EC_OC_REG_TMD_CUR_CNT__A 0x2150021
966#define B_EC_OC_REG_AVR_ASH_CNT__A 0x2150023
967#define B_EC_OC_REG_AVR_BSH_CNT__A 0x2150024
968#define B_EC_OC_REG_RCN_MODE__A 0x2150027
969#define B_EC_OC_REG_RCN_CRA_LOP__A 0x2150028
970#define B_EC_OC_REG_RCN_CRA_HIP__A 0x2150029
971#define B_EC_OC_REG_RCN_CST_LOP__A 0x215002A
972#define B_EC_OC_REG_RCN_CST_HIP__A 0x215002B
973#define B_EC_OC_REG_RCN_SET_LVL__A 0x215002C
974#define B_EC_OC_REG_RCN_GAI_LVL__A 0x215002D
975#define B_EC_OC_REG_RCN_CLP_LOP__A 0x2150032
976#define B_EC_OC_REG_RCN_CLP_HIP__A 0x2150033
977#define B_EC_OC_REG_RCN_MAP_LOP__A 0x2150034
978#define B_EC_OC_REG_RCN_MAP_HIP__A 0x2150035
979#define B_EC_OC_REG_OCR_MPG_UOS__A 0x2150036
980#define B_EC_OC_REG_OCR_MPG_UOS__M 0xFFF
981#define B_EC_OC_REG_OCR_MPG_UOS_INIT 0x0
982#define B_EC_OC_REG_OCR_MPG_USR_DAT__A 0x2150038
983#define B_EC_OC_REG_IPR_INV_MPG__A 0x2150045
984#define B_EC_OC_REG_DTO_CLKMODE__A 0x2150047
985#define B_EC_OC_REG_DTO_PER__A 0x2150048
986#define B_EC_OC_REG_DTO_BUR__A 0x2150049
987#define B_EC_OC_REG_RCR_CLKMODE__A 0x215004A
988#define B_CC_REG_OSC_MODE__A 0x2410010
989#define B_CC_REG_OSC_MODE_M20 0x1
990#define B_CC_REG_PLL_MODE__A 0x2410011
991#define B_CC_REG_PLL_MODE_BYPASS_PLL 0x1
992#define B_CC_REG_PLL_MODE_PUMP_CUR_12 0x14
993#define B_CC_REG_REF_DIVIDE__A 0x2410012
994#define B_CC_REG_PWD_MODE__A 0x2410015
995#define B_CC_REG_PWD_MODE_DOWN_PLL 0x2
996#define B_CC_REG_UPDATE__A 0x2410017
997#define B_CC_REG_UPDATE_KEY 0x3973
998#define B_CC_REG_JTAGID_L__A 0x2410019
999#define B_CC_REG_DIVERSITY__A 0x241001B
1000#define B_LC_COMM_EXEC__A 0x2800000
1001#define B_LC_RA_RAM_IFINCR_NOM_L__A 0x282000C
1002#define B_LC_RA_RAM_FILTER_SYM_SET__A 0x282001A
1003#define B_LC_RA_RAM_FILTER_SYM_SET__PRE 0x3E8
1004#define B_LC_RA_RAM_FILTER_CRMM_A__A 0x2820060
1005#define B_LC_RA_RAM_FILTER_CRMM_A__PRE 0x4
1006#define B_LC_RA_RAM_FILTER_CRMM_B__A 0x2820061
1007#define B_LC_RA_RAM_FILTER_CRMM_B__PRE 0x1
1008#define B_LC_RA_RAM_FILTER_SRMM_A__A 0x2820068
1009#define B_LC_RA_RAM_FILTER_SRMM_A__PRE 0x4
1010#define B_LC_RA_RAM_FILTER_SRMM_B__A 0x2820069
1011#define B_LC_RA_RAM_FILTER_SRMM_B__PRE 0x1
1012
1013#endif
diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h
new file mode 100644
index 00000000000..58baf419560
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxk.h
@@ -0,0 +1,47 @@
1#ifndef _DRXK_H_
2#define _DRXK_H_
3
4#include <linux/types.h>
5#include <linux/i2c.h>
6
7/**
8 * struct drxk_config - Configure the initial parameters for DRX-K
9 *
10 * adr: I2C Address of the DRX-K
11 * single_master: Device is on the single master mode
12 * no_i2c_bridge: Don't switch the I2C bridge to talk with tuner
13 * antenna_gpio: GPIO bit used to control the antenna
14 * antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1
15 * means that 1=DVBC, 0 = DVBT. Zero means the opposite.
16 * microcode_name: Name of the firmware file with the microcode
17 *
18 * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is
19 * UIO-3.
20 */
21struct drxk_config {
22 u8 adr;
23 bool single_master;
24 bool no_i2c_bridge;
25
26 bool antenna_dvbt;
27 u16 antenna_gpio;
28
29 const char *microcode_name;
30};
31
32#if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \
33 && defined(MODULE))
34extern struct dvb_frontend *drxk_attach(const struct drxk_config *config,
35 struct i2c_adapter *i2c,
36 struct dvb_frontend **fe_t);
37#else
38static inline struct dvb_frontend *drxk_attach(const struct drxk_config *config,
39 struct i2c_adapter *i2c,
40 struct dvb_frontend **fe_t)
41{
42 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
43 return NULL;
44}
45#endif
46
47#endif
diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c
new file mode 100644
index 00000000000..41b083820da
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxk_hard.c
@@ -0,0 +1,6454 @@
1/*
2 * drxk_hard: DRX-K DVB-C/T demodulator driver
3 *
4 * Copyright (C) 2010-2011 Digital Devices GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 only, as published by the Free Software Foundation.
9 *
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 *
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., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/firmware.h>
30#include <linux/i2c.h>
31#include <linux/version.h>
32#include <asm/div64.h>
33
34#include "dvb_frontend.h"
35#include "drxk.h"
36#include "drxk_hard.h"
37
38static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode);
39static int PowerDownQAM(struct drxk_state *state);
40static int SetDVBTStandard(struct drxk_state *state,
41 enum OperationMode oMode);
42static int SetQAMStandard(struct drxk_state *state,
43 enum OperationMode oMode);
44static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
45 s32 tunerFreqOffset);
46static int SetDVBTStandard(struct drxk_state *state,
47 enum OperationMode oMode);
48static int DVBTStart(struct drxk_state *state);
49static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
50 s32 tunerFreqOffset);
51static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus);
52static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus);
53static int SwitchAntennaToQAM(struct drxk_state *state);
54static int SwitchAntennaToDVBT(struct drxk_state *state);
55
56static bool IsDVBT(struct drxk_state *state)
57{
58 return state->m_OperationMode == OM_DVBT;
59}
60
61static bool IsQAM(struct drxk_state *state)
62{
63 return state->m_OperationMode == OM_QAM_ITU_A ||
64 state->m_OperationMode == OM_QAM_ITU_B ||
65 state->m_OperationMode == OM_QAM_ITU_C;
66}
67
68bool IsA1WithPatchCode(struct drxk_state *state)
69{
70 return state->m_DRXK_A1_PATCH_CODE;
71}
72
73bool IsA1WithRomCode(struct drxk_state *state)
74{
75 return state->m_DRXK_A1_ROM_CODE;
76}
77
78#define NOA1ROM 0
79
80#define DRXDAP_FASI_SHORT_FORMAT(addr) (((addr) & 0xFC30FF80) == 0)
81#define DRXDAP_FASI_LONG_FORMAT(addr) (((addr) & 0xFC30FF80) != 0)
82
83#define DEFAULT_MER_83 165
84#define DEFAULT_MER_93 250
85
86#ifndef DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH
87#define DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH (0x02)
88#endif
89
90#ifndef DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH
91#define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03)
92#endif
93
94#ifndef DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH
95#define DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH (0x06)
96#endif
97
98#define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700
99#define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500
100
101#ifndef DRXK_KI_RAGC_ATV
102#define DRXK_KI_RAGC_ATV 4
103#endif
104#ifndef DRXK_KI_IAGC_ATV
105#define DRXK_KI_IAGC_ATV 6
106#endif
107#ifndef DRXK_KI_DAGC_ATV
108#define DRXK_KI_DAGC_ATV 7
109#endif
110
111#ifndef DRXK_KI_RAGC_QAM
112#define DRXK_KI_RAGC_QAM 3
113#endif
114#ifndef DRXK_KI_IAGC_QAM
115#define DRXK_KI_IAGC_QAM 4
116#endif
117#ifndef DRXK_KI_DAGC_QAM
118#define DRXK_KI_DAGC_QAM 7
119#endif
120#ifndef DRXK_KI_RAGC_DVBT
121#define DRXK_KI_RAGC_DVBT (IsA1WithPatchCode(state) ? 3 : 2)
122#endif
123#ifndef DRXK_KI_IAGC_DVBT
124#define DRXK_KI_IAGC_DVBT (IsA1WithPatchCode(state) ? 4 : 2)
125#endif
126#ifndef DRXK_KI_DAGC_DVBT
127#define DRXK_KI_DAGC_DVBT (IsA1WithPatchCode(state) ? 10 : 7)
128#endif
129
130#ifndef DRXK_AGC_DAC_OFFSET
131#define DRXK_AGC_DAC_OFFSET (0x800)
132#endif
133
134#ifndef DRXK_BANDWIDTH_8MHZ_IN_HZ
135#define DRXK_BANDWIDTH_8MHZ_IN_HZ (0x8B8249L)
136#endif
137
138#ifndef DRXK_BANDWIDTH_7MHZ_IN_HZ
139#define DRXK_BANDWIDTH_7MHZ_IN_HZ (0x7A1200L)
140#endif
141
142#ifndef DRXK_BANDWIDTH_6MHZ_IN_HZ
143#define DRXK_BANDWIDTH_6MHZ_IN_HZ (0x68A1B6L)
144#endif
145
146#ifndef DRXK_QAM_SYMBOLRATE_MAX
147#define DRXK_QAM_SYMBOLRATE_MAX (7233000)
148#endif
149
150#define DRXK_BL_ROM_OFFSET_TAPS_DVBT 56
151#define DRXK_BL_ROM_OFFSET_TAPS_ITU_A 64
152#define DRXK_BL_ROM_OFFSET_TAPS_ITU_C 0x5FE0
153#define DRXK_BL_ROM_OFFSET_TAPS_BG 24
154#define DRXK_BL_ROM_OFFSET_TAPS_DKILLP 32
155#define DRXK_BL_ROM_OFFSET_TAPS_NTSC 40
156#define DRXK_BL_ROM_OFFSET_TAPS_FM 48
157#define DRXK_BL_ROM_OFFSET_UCODE 0
158
159#define DRXK_BLC_TIMEOUT 100
160
161#define DRXK_BLCC_NR_ELEMENTS_TAPS 2
162#define DRXK_BLCC_NR_ELEMENTS_UCODE 6
163
164#define DRXK_BLDC_NR_ELEMENTS_TAPS 28
165
166#ifndef DRXK_OFDM_NE_NOTCH_WIDTH
167#define DRXK_OFDM_NE_NOTCH_WIDTH (4)
168#endif
169
170#define DRXK_QAM_SL_SIG_POWER_QAM16 (40960)
171#define DRXK_QAM_SL_SIG_POWER_QAM32 (20480)
172#define DRXK_QAM_SL_SIG_POWER_QAM64 (43008)
173#define DRXK_QAM_SL_SIG_POWER_QAM128 (20992)
174#define DRXK_QAM_SL_SIG_POWER_QAM256 (43520)
175
176static unsigned int debug;
177module_param(debug, int, 0644);
178MODULE_PARM_DESC(debug, "enable debug messages");
179
180#define dprintk(level, fmt, arg...) do { \
181if (debug >= level) \
182 printk(KERN_DEBUG "drxk: %s" fmt, __func__, ## arg); \
183} while (0)
184
185
186static inline u32 MulDiv32(u32 a, u32 b, u32 c)
187{
188 u64 tmp64;
189
190 tmp64 = (u64) a * (u64) b;
191 do_div(tmp64, c);
192
193 return (u32) tmp64;
194}
195
196inline u32 Frac28a(u32 a, u32 c)
197{
198 int i = 0;
199 u32 Q1 = 0;
200 u32 R0 = 0;
201
202 R0 = (a % c) << 4; /* 32-28 == 4 shifts possible at max */
203 Q1 = a / c; /* integer part, only the 4 least significant bits
204 will be visible in the result */
205
206 /* division using radix 16, 7 nibbles in the result */
207 for (i = 0; i < 7; i++) {
208 Q1 = (Q1 << 4) | (R0 / c);
209 R0 = (R0 % c) << 4;
210 }
211 /* rounding */
212 if ((R0 >> 3) >= c)
213 Q1++;
214
215 return Q1;
216}
217
218static u32 Log10Times100(u32 x)
219{
220 static const u8 scale = 15;
221 static const u8 indexWidth = 5;
222 u8 i = 0;
223 u32 y = 0;
224 u32 d = 0;
225 u32 k = 0;
226 u32 r = 0;
227 /*
228 log2lut[n] = (1<<scale) * 200 * log2(1.0 + ((1.0/(1<<INDEXWIDTH)) * n))
229 0 <= n < ((1<<INDEXWIDTH)+1)
230 */
231
232 static const u32 log2lut[] = {
233 0, /* 0.000000 */
234 290941, /* 290941.300628 */
235 573196, /* 573196.476418 */
236 847269, /* 847269.179851 */
237 1113620, /* 1113620.489452 */
238 1372674, /* 1372673.576986 */
239 1624818, /* 1624817.752104 */
240 1870412, /* 1870411.981536 */
241 2109788, /* 2109787.962654 */
242 2343253, /* 2343252.817465 */
243 2571091, /* 2571091.461923 */
244 2793569, /* 2793568.696416 */
245 3010931, /* 3010931.055901 */
246 3223408, /* 3223408.452106 */
247 3431216, /* 3431215.635215 */
248 3634553, /* 3634553.498355 */
249 3833610, /* 3833610.244726 */
250 4028562, /* 4028562.434393 */
251 4219576, /* 4219575.925308 */
252 4406807, /* 4406806.721144 */
253 4590402, /* 4590401.736809 */
254 4770499, /* 4770499.491025 */
255 4947231, /* 4947230.734179 */
256 5120719, /* 5120719.018555 */
257 5291081, /* 5291081.217197 */
258 5458428, /* 5458427.996830 */
259 5622864, /* 5622864.249668 */
260 5784489, /* 5784489.488298 */
261 5943398, /* 5943398.207380 */
262 6099680, /* 6099680.215452 */
263 6253421, /* 6253420.939751 */
264 6404702, /* 6404701.706649 */
265 6553600, /* 6553600.000000 */
266 };
267
268
269 if (x == 0)
270 return 0;
271
272 /* Scale x (normalize) */
273 /* computing y in log(x/y) = log(x) - log(y) */
274 if ((x & ((0xffffffff) << (scale + 1))) == 0) {
275 for (k = scale; k > 0; k--) {
276 if (x & (((u32) 1) << scale))
277 break;
278 x <<= 1;
279 }
280 } else {
281 for (k = scale; k < 31; k++) {
282 if ((x & (((u32) (-1)) << (scale + 1))) == 0)
283 break;
284 x >>= 1;
285 }
286 }
287 /*
288 Now x has binary point between bit[scale] and bit[scale-1]
289 and 1.0 <= x < 2.0 */
290
291 /* correction for divison: log(x) = log(x/y)+log(y) */
292 y = k * ((((u32) 1) << scale) * 200);
293
294 /* remove integer part */
295 x &= ((((u32) 1) << scale) - 1);
296 /* get index */
297 i = (u8) (x >> (scale - indexWidth));
298 /* compute delta (x - a) */
299 d = x & ((((u32) 1) << (scale - indexWidth)) - 1);
300 /* compute log, multiplication (d* (..)) must be within range ! */
301 y += log2lut[i] +
302 ((d * (log2lut[i + 1] - log2lut[i])) >> (scale - indexWidth));
303 /* Conver to log10() */
304 y /= 108853; /* (log2(10) << scale) */
305 r = (y >> 1);
306 /* rounding */
307 if (y & ((u32) 1))
308 r++;
309 return r;
310}
311
312/****************************************************************************/
313/* I2C **********************************************************************/
314/****************************************************************************/
315
316static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val)
317{
318 struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
319 .buf = val, .len = 1}
320 };
321
322 return i2c_transfer(adapter, msgs, 1);
323}
324
325static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
326{
327 int status;
328 struct i2c_msg msg = {
329 .addr = adr, .flags = 0, .buf = data, .len = len };
330
331 dprintk(3, ":");
332 if (debug > 2) {
333 int i;
334 for (i = 0; i < len; i++)
335 printk(KERN_CONT " %02x", data[i]);
336 printk(KERN_CONT "\n");
337 }
338 status = i2c_transfer(adap, &msg, 1);
339 if (status >= 0 && status != 1)
340 status = -EIO;
341
342 if (status < 0)
343 printk(KERN_ERR "drxk: i2c write error at addr 0x%02x\n", adr);
344
345 return status;
346}
347
348static int i2c_read(struct i2c_adapter *adap,
349 u8 adr, u8 *msg, int len, u8 *answ, int alen)
350{
351 int status;
352 struct i2c_msg msgs[2] = {
353 {.addr = adr, .flags = 0,
354 .buf = msg, .len = len},
355 {.addr = adr, .flags = I2C_M_RD,
356 .buf = answ, .len = alen}
357 };
358
359 status = i2c_transfer(adap, msgs, 2);
360 if (status != 2) {
361 if (debug > 2)
362 printk(KERN_CONT ": ERROR!\n");
363 if (status >= 0)
364 status = -EIO;
365
366 printk(KERN_ERR "drxk: i2c read error at addr 0x%02x\n", adr);
367 return status;
368 }
369 if (debug > 2) {
370 int i;
371 dprintk(2, ": read from ");
372 for (i = 0; i < len; i++)
373 printk(KERN_CONT " %02x", msg[i]);
374 printk(KERN_CONT "Value = ");
375 for (i = 0; i < alen; i++)
376 printk(KERN_CONT " %02x", answ[i]);
377 printk(KERN_CONT "\n");
378 }
379 return 0;
380}
381
382static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
383{
384 int status;
385 u8 adr = state->demod_address, mm1[4], mm2[2], len;
386
387 if (state->single_master)
388 flags |= 0xC0;
389
390 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
391 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
392 mm1[1] = ((reg >> 16) & 0xFF);
393 mm1[2] = ((reg >> 24) & 0xFF) | flags;
394 mm1[3] = ((reg >> 7) & 0xFF);
395 len = 4;
396 } else {
397 mm1[0] = ((reg << 1) & 0xFF);
398 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
399 len = 2;
400 }
401 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
402 status = i2c_read(state->i2c, adr, mm1, len, mm2, 2);
403 if (status < 0)
404 return status;
405 if (data)
406 *data = mm2[0] | (mm2[1] << 8);
407
408 return 0;
409}
410
411static int read16(struct drxk_state *state, u32 reg, u16 *data)
412{
413 return read16_flags(state, reg, data, 0);
414}
415
416static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
417{
418 int status;
419 u8 adr = state->demod_address, mm1[4], mm2[4], len;
420
421 if (state->single_master)
422 flags |= 0xC0;
423
424 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
425 mm1[0] = (((reg << 1) & 0xFF) | 0x01);
426 mm1[1] = ((reg >> 16) & 0xFF);
427 mm1[2] = ((reg >> 24) & 0xFF) | flags;
428 mm1[3] = ((reg >> 7) & 0xFF);
429 len = 4;
430 } else {
431 mm1[0] = ((reg << 1) & 0xFF);
432 mm1[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
433 len = 2;
434 }
435 dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
436 status = i2c_read(state->i2c, adr, mm1, len, mm2, 4);
437 if (status < 0)
438 return status;
439 if (data)
440 *data = mm2[0] | (mm2[1] << 8) |
441 (mm2[2] << 16) | (mm2[3] << 24);
442
443 return 0;
444}
445
446static int read32(struct drxk_state *state, u32 reg, u32 *data)
447{
448 return read32_flags(state, reg, data, 0);
449}
450
451static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
452{
453 u8 adr = state->demod_address, mm[6], len;
454
455 if (state->single_master)
456 flags |= 0xC0;
457 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
458 mm[0] = (((reg << 1) & 0xFF) | 0x01);
459 mm[1] = ((reg >> 16) & 0xFF);
460 mm[2] = ((reg >> 24) & 0xFF) | flags;
461 mm[3] = ((reg >> 7) & 0xFF);
462 len = 4;
463 } else {
464 mm[0] = ((reg << 1) & 0xFF);
465 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
466 len = 2;
467 }
468 mm[len] = data & 0xff;
469 mm[len + 1] = (data >> 8) & 0xff;
470
471 dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
472 return i2c_write(state->i2c, adr, mm, len + 2);
473}
474
475static int write16(struct drxk_state *state, u32 reg, u16 data)
476{
477 return write16_flags(state, reg, data, 0);
478}
479
480static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
481{
482 u8 adr = state->demod_address, mm[8], len;
483
484 if (state->single_master)
485 flags |= 0xC0;
486 if (DRXDAP_FASI_LONG_FORMAT(reg) || (flags != 0)) {
487 mm[0] = (((reg << 1) & 0xFF) | 0x01);
488 mm[1] = ((reg >> 16) & 0xFF);
489 mm[2] = ((reg >> 24) & 0xFF) | flags;
490 mm[3] = ((reg >> 7) & 0xFF);
491 len = 4;
492 } else {
493 mm[0] = ((reg << 1) & 0xFF);
494 mm[1] = (((reg >> 16) & 0x0F) | ((reg >> 18) & 0xF0));
495 len = 2;
496 }
497 mm[len] = data & 0xff;
498 mm[len + 1] = (data >> 8) & 0xff;
499 mm[len + 2] = (data >> 16) & 0xff;
500 mm[len + 3] = (data >> 24) & 0xff;
501 dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
502
503 return i2c_write(state->i2c, adr, mm, len + 4);
504}
505
506static int write32(struct drxk_state *state, u32 reg, u32 data)
507{
508 return write32_flags(state, reg, data, 0);
509}
510
511static int write_block(struct drxk_state *state, u32 Address,
512 const int BlockSize, const u8 pBlock[])
513{
514 int status = 0, BlkSize = BlockSize;
515 u8 Flags = 0;
516
517 if (state->single_master)
518 Flags |= 0xC0;
519
520 while (BlkSize > 0) {
521 int Chunk = BlkSize > state->m_ChunkSize ?
522 state->m_ChunkSize : BlkSize;
523 u8 *AdrBuf = &state->Chunk[0];
524 u32 AdrLength = 0;
525
526 if (DRXDAP_FASI_LONG_FORMAT(Address) || (Flags != 0)) {
527 AdrBuf[0] = (((Address << 1) & 0xFF) | 0x01);
528 AdrBuf[1] = ((Address >> 16) & 0xFF);
529 AdrBuf[2] = ((Address >> 24) & 0xFF);
530 AdrBuf[3] = ((Address >> 7) & 0xFF);
531 AdrBuf[2] |= Flags;
532 AdrLength = 4;
533 if (Chunk == state->m_ChunkSize)
534 Chunk -= 2;
535 } else {
536 AdrBuf[0] = ((Address << 1) & 0xFF);
537 AdrBuf[1] = (((Address >> 16) & 0x0F) |
538 ((Address >> 18) & 0xF0));
539 AdrLength = 2;
540 }
541 memcpy(&state->Chunk[AdrLength], pBlock, Chunk);
542 dprintk(2, "(0x%08x, 0x%02x)\n", Address, Flags);
543 if (debug > 1) {
544 int i;
545 if (pBlock)
546 for (i = 0; i < Chunk; i++)
547 printk(KERN_CONT " %02x", pBlock[i]);
548 printk(KERN_CONT "\n");
549 }
550 status = i2c_write(state->i2c, state->demod_address,
551 &state->Chunk[0], Chunk + AdrLength);
552 if (status < 0) {
553 printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
554 __func__, Address);
555 break;
556 }
557 pBlock += Chunk;
558 Address += (Chunk >> 1);
559 BlkSize -= Chunk;
560 }
561 return status;
562}
563
564#ifndef DRXK_MAX_RETRIES_POWERUP
565#define DRXK_MAX_RETRIES_POWERUP 20
566#endif
567
568int PowerUpDevice(struct drxk_state *state)
569{
570 int status;
571 u8 data = 0;
572 u16 retryCount = 0;
573
574 dprintk(1, "\n");
575
576 status = i2c_read1(state->i2c, state->demod_address, &data);
577 if (status < 0) {
578 do {
579 data = 0;
580 status = i2c_write(state->i2c, state->demod_address,
581 &data, 1);
582 msleep(10);
583 retryCount++;
584 if (status < 0)
585 continue;
586 status = i2c_read1(state->i2c, state->demod_address,
587 &data);
588 } while (status < 0 &&
589 (retryCount < DRXK_MAX_RETRIES_POWERUP));
590 if (status < 0 && retryCount >= DRXK_MAX_RETRIES_POWERUP)
591 goto error;
592 }
593
594 /* Make sure all clk domains are active */
595 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_NONE);
596 if (status < 0)
597 goto error;
598 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
599 if (status < 0)
600 goto error;
601 /* Enable pll lock tests */
602 status = write16(state, SIO_CC_PLL_LOCK__A, 1);
603 if (status < 0)
604 goto error;
605
606 state->m_currentPowerMode = DRX_POWER_UP;
607
608error:
609 if (status < 0)
610 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
611
612 return status;
613}
614
615
616static int init_state(struct drxk_state *state)
617{
618 /*
619 * FIXME: most (all?) of the values bellow should be moved into
620 * struct drxk_config, as they are probably board-specific
621 */
622 u32 ulVSBIfAgcMode = DRXK_AGC_CTRL_AUTO;
623 u32 ulVSBIfAgcOutputLevel = 0;
624 u32 ulVSBIfAgcMinLevel = 0;
625 u32 ulVSBIfAgcMaxLevel = 0x7FFF;
626 u32 ulVSBIfAgcSpeed = 3;
627
628 u32 ulVSBRfAgcMode = DRXK_AGC_CTRL_AUTO;
629 u32 ulVSBRfAgcOutputLevel = 0;
630 u32 ulVSBRfAgcMinLevel = 0;
631 u32 ulVSBRfAgcMaxLevel = 0x7FFF;
632 u32 ulVSBRfAgcSpeed = 3;
633 u32 ulVSBRfAgcTop = 9500;
634 u32 ulVSBRfAgcCutOffCurrent = 4000;
635
636 u32 ulATVIfAgcMode = DRXK_AGC_CTRL_AUTO;
637 u32 ulATVIfAgcOutputLevel = 0;
638 u32 ulATVIfAgcMinLevel = 0;
639 u32 ulATVIfAgcMaxLevel = 0;
640 u32 ulATVIfAgcSpeed = 3;
641
642 u32 ulATVRfAgcMode = DRXK_AGC_CTRL_OFF;
643 u32 ulATVRfAgcOutputLevel = 0;
644 u32 ulATVRfAgcMinLevel = 0;
645 u32 ulATVRfAgcMaxLevel = 0;
646 u32 ulATVRfAgcTop = 9500;
647 u32 ulATVRfAgcCutOffCurrent = 4000;
648 u32 ulATVRfAgcSpeed = 3;
649
650 u32 ulQual83 = DEFAULT_MER_83;
651 u32 ulQual93 = DEFAULT_MER_93;
652
653 u32 ulDVBTStaticTSClock = 1;
654 u32 ulDVBCStaticTSClock = 1;
655
656 u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
657 u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
658
659 /* io_pad_cfg register (8 bit reg.) MSB bit is 1 (default value) */
660 /* io_pad_cfg_mode output mode is drive always */
661 /* io_pad_cfg_drive is set to power 2 (23 mA) */
662 u32 ulGPIOCfg = 0x0113;
663 u32 ulSerialMode = 1;
664 u32 ulInvertTSClock = 0;
665 u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH;
666 u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH;
667 u32 ulDVBTBitrate = 50000000;
668 u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8;
669
670 u32 ulInsertRSByte = 0;
671
672 u32 ulRfMirror = 1;
673 u32 ulPowerDown = 0;
674
675 dprintk(1, "\n");
676
677 state->m_hasLNA = false;
678 state->m_hasDVBT = false;
679 state->m_hasDVBC = false;
680 state->m_hasATV = false;
681 state->m_hasOOB = false;
682 state->m_hasAudio = false;
683
684 state->m_ChunkSize = 124;
685
686 state->m_oscClockFreq = 0;
687 state->m_smartAntInverted = false;
688 state->m_bPDownOpenBridge = false;
689
690 /* real system clock frequency in kHz */
691 state->m_sysClockFreq = 151875;
692 /* Timing div, 250ns/Psys */
693 /* Timing div, = (delay (nano seconds) * sysclk (kHz))/ 1000 */
694 state->m_HICfgTimingDiv = ((state->m_sysClockFreq / 1000) *
695 HI_I2C_DELAY) / 1000;
696 /* Clipping */
697 if (state->m_HICfgTimingDiv > SIO_HI_RA_RAM_PAR_2_CFG_DIV__M)
698 state->m_HICfgTimingDiv = SIO_HI_RA_RAM_PAR_2_CFG_DIV__M;
699 state->m_HICfgWakeUpKey = (state->demod_address << 1);
700 /* port/bridge/power down ctrl */
701 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
702
703 state->m_bPowerDown = (ulPowerDown != 0);
704
705 state->m_DRXK_A1_PATCH_CODE = false;
706 state->m_DRXK_A1_ROM_CODE = false;
707 state->m_DRXK_A2_ROM_CODE = false;
708 state->m_DRXK_A3_ROM_CODE = false;
709 state->m_DRXK_A2_PATCH_CODE = false;
710 state->m_DRXK_A3_PATCH_CODE = false;
711
712 /* Init AGC and PGA parameters */
713 /* VSB IF */
714 state->m_vsbIfAgcCfg.ctrlMode = (ulVSBIfAgcMode);
715 state->m_vsbIfAgcCfg.outputLevel = (ulVSBIfAgcOutputLevel);
716 state->m_vsbIfAgcCfg.minOutputLevel = (ulVSBIfAgcMinLevel);
717 state->m_vsbIfAgcCfg.maxOutputLevel = (ulVSBIfAgcMaxLevel);
718 state->m_vsbIfAgcCfg.speed = (ulVSBIfAgcSpeed);
719 state->m_vsbPgaCfg = 140;
720
721 /* VSB RF */
722 state->m_vsbRfAgcCfg.ctrlMode = (ulVSBRfAgcMode);
723 state->m_vsbRfAgcCfg.outputLevel = (ulVSBRfAgcOutputLevel);
724 state->m_vsbRfAgcCfg.minOutputLevel = (ulVSBRfAgcMinLevel);
725 state->m_vsbRfAgcCfg.maxOutputLevel = (ulVSBRfAgcMaxLevel);
726 state->m_vsbRfAgcCfg.speed = (ulVSBRfAgcSpeed);
727 state->m_vsbRfAgcCfg.top = (ulVSBRfAgcTop);
728 state->m_vsbRfAgcCfg.cutOffCurrent = (ulVSBRfAgcCutOffCurrent);
729 state->m_vsbPreSawCfg.reference = 0x07;
730 state->m_vsbPreSawCfg.usePreSaw = true;
731
732 state->m_Quality83percent = DEFAULT_MER_83;
733 state->m_Quality93percent = DEFAULT_MER_93;
734 if (ulQual93 <= 500 && ulQual83 < ulQual93) {
735 state->m_Quality83percent = ulQual83;
736 state->m_Quality93percent = ulQual93;
737 }
738
739 /* ATV IF */
740 state->m_atvIfAgcCfg.ctrlMode = (ulATVIfAgcMode);
741 state->m_atvIfAgcCfg.outputLevel = (ulATVIfAgcOutputLevel);
742 state->m_atvIfAgcCfg.minOutputLevel = (ulATVIfAgcMinLevel);
743 state->m_atvIfAgcCfg.maxOutputLevel = (ulATVIfAgcMaxLevel);
744 state->m_atvIfAgcCfg.speed = (ulATVIfAgcSpeed);
745
746 /* ATV RF */
747 state->m_atvRfAgcCfg.ctrlMode = (ulATVRfAgcMode);
748 state->m_atvRfAgcCfg.outputLevel = (ulATVRfAgcOutputLevel);
749 state->m_atvRfAgcCfg.minOutputLevel = (ulATVRfAgcMinLevel);
750 state->m_atvRfAgcCfg.maxOutputLevel = (ulATVRfAgcMaxLevel);
751 state->m_atvRfAgcCfg.speed = (ulATVRfAgcSpeed);
752 state->m_atvRfAgcCfg.top = (ulATVRfAgcTop);
753 state->m_atvRfAgcCfg.cutOffCurrent = (ulATVRfAgcCutOffCurrent);
754 state->m_atvPreSawCfg.reference = 0x04;
755 state->m_atvPreSawCfg.usePreSaw = true;
756
757
758 /* DVBT RF */
759 state->m_dvbtRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
760 state->m_dvbtRfAgcCfg.outputLevel = 0;
761 state->m_dvbtRfAgcCfg.minOutputLevel = 0;
762 state->m_dvbtRfAgcCfg.maxOutputLevel = 0xFFFF;
763 state->m_dvbtRfAgcCfg.top = 0x2100;
764 state->m_dvbtRfAgcCfg.cutOffCurrent = 4000;
765 state->m_dvbtRfAgcCfg.speed = 1;
766
767
768 /* DVBT IF */
769 state->m_dvbtIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
770 state->m_dvbtIfAgcCfg.outputLevel = 0;
771 state->m_dvbtIfAgcCfg.minOutputLevel = 0;
772 state->m_dvbtIfAgcCfg.maxOutputLevel = 9000;
773 state->m_dvbtIfAgcCfg.top = 13424;
774 state->m_dvbtIfAgcCfg.cutOffCurrent = 0;
775 state->m_dvbtIfAgcCfg.speed = 3;
776 state->m_dvbtIfAgcCfg.FastClipCtrlDelay = 30;
777 state->m_dvbtIfAgcCfg.IngainTgtMax = 30000;
778 /* state->m_dvbtPgaCfg = 140; */
779
780 state->m_dvbtPreSawCfg.reference = 4;
781 state->m_dvbtPreSawCfg.usePreSaw = false;
782
783 /* QAM RF */
784 state->m_qamRfAgcCfg.ctrlMode = DRXK_AGC_CTRL_OFF;
785 state->m_qamRfAgcCfg.outputLevel = 0;
786 state->m_qamRfAgcCfg.minOutputLevel = 6023;
787 state->m_qamRfAgcCfg.maxOutputLevel = 27000;
788 state->m_qamRfAgcCfg.top = 0x2380;
789 state->m_qamRfAgcCfg.cutOffCurrent = 4000;
790 state->m_qamRfAgcCfg.speed = 3;
791
792 /* QAM IF */
793 state->m_qamIfAgcCfg.ctrlMode = DRXK_AGC_CTRL_AUTO;
794 state->m_qamIfAgcCfg.outputLevel = 0;
795 state->m_qamIfAgcCfg.minOutputLevel = 0;
796 state->m_qamIfAgcCfg.maxOutputLevel = 9000;
797 state->m_qamIfAgcCfg.top = 0x0511;
798 state->m_qamIfAgcCfg.cutOffCurrent = 0;
799 state->m_qamIfAgcCfg.speed = 3;
800 state->m_qamIfAgcCfg.IngainTgtMax = 5119;
801 state->m_qamIfAgcCfg.FastClipCtrlDelay = 50;
802
803 state->m_qamPgaCfg = 140;
804 state->m_qamPreSawCfg.reference = 4;
805 state->m_qamPreSawCfg.usePreSaw = false;
806
807 state->m_OperationMode = OM_NONE;
808 state->m_DrxkState = DRXK_UNINITIALIZED;
809
810 /* MPEG output configuration */
811 state->m_enableMPEGOutput = true; /* If TRUE; enable MPEG ouput */
812 state->m_insertRSByte = false; /* If TRUE; insert RS byte */
813 state->m_enableParallel = true; /* If TRUE;
814 parallel out otherwise serial */
815 state->m_invertDATA = false; /* If TRUE; invert DATA signals */
816 state->m_invertERR = false; /* If TRUE; invert ERR signal */
817 state->m_invertSTR = false; /* If TRUE; invert STR signals */
818 state->m_invertVAL = false; /* If TRUE; invert VAL signals */
819 state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */
820 state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0);
821 state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0);
822 /* If TRUE; static MPEG clockrate will be used;
823 otherwise clockrate will adapt to the bitrate of the TS */
824
825 state->m_DVBTBitrate = ulDVBTBitrate;
826 state->m_DVBCBitrate = ulDVBCBitrate;
827
828 state->m_TSDataStrength = (ulTSDataStrength & 0x07);
829 state->m_TSClockkStrength = (ulTSClockkStrength & 0x07);
830
831 /* Maximum bitrate in b/s in case static clockrate is selected */
832 state->m_mpegTsStaticBitrate = 19392658;
833 state->m_disableTEIhandling = false;
834
835 if (ulInsertRSByte)
836 state->m_insertRSByte = true;
837
838 state->m_MpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT;
839 if (ulMpegLockTimeOut < 10000)
840 state->m_MpegLockTimeOut = ulMpegLockTimeOut;
841 state->m_DemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT;
842 if (ulDemodLockTimeOut < 10000)
843 state->m_DemodLockTimeOut = ulDemodLockTimeOut;
844
845 /* QAM defaults */
846 state->m_Constellation = DRX_CONSTELLATION_AUTO;
847 state->m_qamInterleaveMode = DRXK_QAM_I12_J17;
848 state->m_fecRsPlen = 204 * 8; /* fecRsPlen annex A */
849 state->m_fecRsPrescale = 1;
850
851 state->m_sqiSpeed = DRXK_DVBT_SQI_SPEED_MEDIUM;
852 state->m_agcFastClipCtrlDelay = 0;
853
854 state->m_GPIOCfg = (ulGPIOCfg);
855
856 state->m_bPowerDown = false;
857 state->m_currentPowerMode = DRX_POWER_DOWN;
858
859 state->m_enableParallel = (ulSerialMode == 0);
860
861 state->m_rfmirror = (ulRfMirror == 0);
862 state->m_IfAgcPol = false;
863 return 0;
864}
865
866static int DRXX_Open(struct drxk_state *state)
867{
868 int status = 0;
869 u32 jtag = 0;
870 u16 bid = 0;
871 u16 key = 0;
872
873 dprintk(1, "\n");
874 /* stop lock indicator process */
875 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
876 if (status < 0)
877 goto error;
878 /* Check device id */
879 status = read16(state, SIO_TOP_COMM_KEY__A, &key);
880 if (status < 0)
881 goto error;
882 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
883 if (status < 0)
884 goto error;
885 status = read32(state, SIO_TOP_JTAGID_LO__A, &jtag);
886 if (status < 0)
887 goto error;
888 status = read16(state, SIO_PDR_UIO_IN_HI__A, &bid);
889 if (status < 0)
890 goto error;
891 status = write16(state, SIO_TOP_COMM_KEY__A, key);
892error:
893 if (status < 0)
894 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
895 return status;
896}
897
898static int GetDeviceCapabilities(struct drxk_state *state)
899{
900 u16 sioPdrOhwCfg = 0;
901 u32 sioTopJtagidLo = 0;
902 int status;
903 const char *spin = "";
904
905 dprintk(1, "\n");
906
907 /* driver 0.9.0 */
908 /* stop lock indicator process */
909 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
910 if (status < 0)
911 goto error;
912 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
913 if (status < 0)
914 goto error;
915 status = read16(state, SIO_PDR_OHW_CFG__A, &sioPdrOhwCfg);
916 if (status < 0)
917 goto error;
918 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
919 if (status < 0)
920 goto error;
921
922 switch ((sioPdrOhwCfg & SIO_PDR_OHW_CFG_FREF_SEL__M)) {
923 case 0:
924 /* ignore (bypass ?) */
925 break;
926 case 1:
927 /* 27 MHz */
928 state->m_oscClockFreq = 27000;
929 break;
930 case 2:
931 /* 20.25 MHz */
932 state->m_oscClockFreq = 20250;
933 break;
934 case 3:
935 /* 4 MHz */
936 state->m_oscClockFreq = 20250;
937 break;
938 default:
939 printk(KERN_ERR "drxk: Clock Frequency is unkonwn\n");
940 return -EINVAL;
941 }
942 /*
943 Determine device capabilities
944 Based on pinning v14
945 */
946 status = read32(state, SIO_TOP_JTAGID_LO__A, &sioTopJtagidLo);
947 if (status < 0)
948 goto error;
949 /* driver 0.9.0 */
950 switch ((sioTopJtagidLo >> 29) & 0xF) {
951 case 0:
952 state->m_deviceSpin = DRXK_SPIN_A1;
953 spin = "A1";
954 break;
955 case 2:
956 state->m_deviceSpin = DRXK_SPIN_A2;
957 spin = "A2";
958 break;
959 case 3:
960 state->m_deviceSpin = DRXK_SPIN_A3;
961 spin = "A3";
962 break;
963 default:
964 state->m_deviceSpin = DRXK_SPIN_UNKNOWN;
965 status = -EINVAL;
966 printk(KERN_ERR "drxk: Spin unknown\n");
967 goto error2;
968 }
969 switch ((sioTopJtagidLo >> 12) & 0xFF) {
970 case 0x13:
971 /* typeId = DRX3913K_TYPE_ID */
972 state->m_hasLNA = false;
973 state->m_hasOOB = false;
974 state->m_hasATV = false;
975 state->m_hasAudio = false;
976 state->m_hasDVBT = true;
977 state->m_hasDVBC = true;
978 state->m_hasSAWSW = true;
979 state->m_hasGPIO2 = false;
980 state->m_hasGPIO1 = false;
981 state->m_hasIRQN = false;
982 break;
983 case 0x15:
984 /* typeId = DRX3915K_TYPE_ID */
985 state->m_hasLNA = false;
986 state->m_hasOOB = false;
987 state->m_hasATV = true;
988 state->m_hasAudio = false;
989 state->m_hasDVBT = true;
990 state->m_hasDVBC = false;
991 state->m_hasSAWSW = true;
992 state->m_hasGPIO2 = true;
993 state->m_hasGPIO1 = true;
994 state->m_hasIRQN = false;
995 break;
996 case 0x16:
997 /* typeId = DRX3916K_TYPE_ID */
998 state->m_hasLNA = false;
999 state->m_hasOOB = false;
1000 state->m_hasATV = true;
1001 state->m_hasAudio = false;
1002 state->m_hasDVBT = true;
1003 state->m_hasDVBC = false;
1004 state->m_hasSAWSW = true;
1005 state->m_hasGPIO2 = true;
1006 state->m_hasGPIO1 = true;
1007 state->m_hasIRQN = false;
1008 break;
1009 case 0x18:
1010 /* typeId = DRX3918K_TYPE_ID */
1011 state->m_hasLNA = false;
1012 state->m_hasOOB = false;
1013 state->m_hasATV = true;
1014 state->m_hasAudio = true;
1015 state->m_hasDVBT = true;
1016 state->m_hasDVBC = false;
1017 state->m_hasSAWSW = true;
1018 state->m_hasGPIO2 = true;
1019 state->m_hasGPIO1 = true;
1020 state->m_hasIRQN = false;
1021 break;
1022 case 0x21:
1023 /* typeId = DRX3921K_TYPE_ID */
1024 state->m_hasLNA = false;
1025 state->m_hasOOB = false;
1026 state->m_hasATV = true;
1027 state->m_hasAudio = true;
1028 state->m_hasDVBT = true;
1029 state->m_hasDVBC = true;
1030 state->m_hasSAWSW = true;
1031 state->m_hasGPIO2 = true;
1032 state->m_hasGPIO1 = true;
1033 state->m_hasIRQN = false;
1034 break;
1035 case 0x23:
1036 /* typeId = DRX3923K_TYPE_ID */
1037 state->m_hasLNA = false;
1038 state->m_hasOOB = false;
1039 state->m_hasATV = true;
1040 state->m_hasAudio = true;
1041 state->m_hasDVBT = true;
1042 state->m_hasDVBC = true;
1043 state->m_hasSAWSW = true;
1044 state->m_hasGPIO2 = true;
1045 state->m_hasGPIO1 = true;
1046 state->m_hasIRQN = false;
1047 break;
1048 case 0x25:
1049 /* typeId = DRX3925K_TYPE_ID */
1050 state->m_hasLNA = false;
1051 state->m_hasOOB = false;
1052 state->m_hasATV = true;
1053 state->m_hasAudio = true;
1054 state->m_hasDVBT = true;
1055 state->m_hasDVBC = true;
1056 state->m_hasSAWSW = true;
1057 state->m_hasGPIO2 = true;
1058 state->m_hasGPIO1 = true;
1059 state->m_hasIRQN = false;
1060 break;
1061 case 0x26:
1062 /* typeId = DRX3926K_TYPE_ID */
1063 state->m_hasLNA = false;
1064 state->m_hasOOB = false;
1065 state->m_hasATV = true;
1066 state->m_hasAudio = false;
1067 state->m_hasDVBT = true;
1068 state->m_hasDVBC = true;
1069 state->m_hasSAWSW = true;
1070 state->m_hasGPIO2 = true;
1071 state->m_hasGPIO1 = true;
1072 state->m_hasIRQN = false;
1073 break;
1074 default:
1075 printk(KERN_ERR "drxk: DeviceID 0x%02x not supported\n",
1076 ((sioTopJtagidLo >> 12) & 0xFF));
1077 status = -EINVAL;
1078 goto error2;
1079 }
1080
1081 printk(KERN_INFO
1082 "drxk: detected a drx-39%02xk, spin %s, xtal %d.%03d MHz\n",
1083 ((sioTopJtagidLo >> 12) & 0xFF), spin,
1084 state->m_oscClockFreq / 1000,
1085 state->m_oscClockFreq % 1000);
1086
1087error:
1088 if (status < 0)
1089 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1090
1091error2:
1092 return status;
1093}
1094
1095static int HI_Command(struct drxk_state *state, u16 cmd, u16 *pResult)
1096{
1097 int status;
1098 bool powerdown_cmd;
1099
1100 dprintk(1, "\n");
1101
1102 /* Write command */
1103 status = write16(state, SIO_HI_RA_RAM_CMD__A, cmd);
1104 if (status < 0)
1105 goto error;
1106 if (cmd == SIO_HI_RA_RAM_CMD_RESET)
1107 msleep(1);
1108
1109 powerdown_cmd =
1110 (bool) ((cmd == SIO_HI_RA_RAM_CMD_CONFIG) &&
1111 ((state->m_HICfgCtrl) &
1112 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M) ==
1113 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ);
1114 if (powerdown_cmd == false) {
1115 /* Wait until command rdy */
1116 u32 retryCount = 0;
1117 u16 waitCmd;
1118
1119 do {
1120 msleep(1);
1121 retryCount += 1;
1122 status = read16(state, SIO_HI_RA_RAM_CMD__A,
1123 &waitCmd);
1124 } while ((status < 0) && (retryCount < DRXK_MAX_RETRIES)
1125 && (waitCmd != 0));
1126 if (status < 0)
1127 goto error;
1128 status = read16(state, SIO_HI_RA_RAM_RES__A, pResult);
1129 }
1130error:
1131 if (status < 0)
1132 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1133
1134 return status;
1135}
1136
1137static int HI_CfgCommand(struct drxk_state *state)
1138{
1139 int status;
1140
1141 dprintk(1, "\n");
1142
1143 mutex_lock(&state->mutex);
1144
1145 status = write16(state, SIO_HI_RA_RAM_PAR_6__A, state->m_HICfgTimeout);
1146 if (status < 0)
1147 goto error;
1148 status = write16(state, SIO_HI_RA_RAM_PAR_5__A, state->m_HICfgCtrl);
1149 if (status < 0)
1150 goto error;
1151 status = write16(state, SIO_HI_RA_RAM_PAR_4__A, state->m_HICfgWakeUpKey);
1152 if (status < 0)
1153 goto error;
1154 status = write16(state, SIO_HI_RA_RAM_PAR_3__A, state->m_HICfgBridgeDelay);
1155 if (status < 0)
1156 goto error;
1157 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, state->m_HICfgTimingDiv);
1158 if (status < 0)
1159 goto error;
1160 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
1161 if (status < 0)
1162 goto error;
1163 status = HI_Command(state, SIO_HI_RA_RAM_CMD_CONFIG, 0);
1164 if (status < 0)
1165 goto error;
1166
1167 state->m_HICfgCtrl &= ~SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1168error:
1169 mutex_unlock(&state->mutex);
1170 if (status < 0)
1171 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1172 return status;
1173}
1174
1175static int InitHI(struct drxk_state *state)
1176{
1177 dprintk(1, "\n");
1178
1179 state->m_HICfgWakeUpKey = (state->demod_address << 1);
1180 state->m_HICfgTimeout = 0x96FF;
1181 /* port/bridge/power down ctrl */
1182 state->m_HICfgCtrl = SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE;
1183
1184 return HI_CfgCommand(state);
1185}
1186
1187static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable)
1188{
1189 int status = -1;
1190 u16 sioPdrMclkCfg = 0;
1191 u16 sioPdrMdxCfg = 0;
1192
1193 dprintk(1, "\n");
1194
1195 /* stop lock indicator process */
1196 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1197 if (status < 0)
1198 goto error;
1199
1200 /* MPEG TS pad configuration */
1201 status = write16(state, SIO_TOP_COMM_KEY__A, 0xFABA);
1202 if (status < 0)
1203 goto error;
1204
1205 if (mpegEnable == false) {
1206 /* Set MPEG TS pads to inputmode */
1207 status = write16(state, SIO_PDR_MSTRT_CFG__A, 0x0000);
1208 if (status < 0)
1209 goto error;
1210 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000);
1211 if (status < 0)
1212 goto error;
1213 status = write16(state, SIO_PDR_MCLK_CFG__A, 0x0000);
1214 if (status < 0)
1215 goto error;
1216 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000);
1217 if (status < 0)
1218 goto error;
1219 status = write16(state, SIO_PDR_MD0_CFG__A, 0x0000);
1220 if (status < 0)
1221 goto error;
1222 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1223 if (status < 0)
1224 goto error;
1225 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1226 if (status < 0)
1227 goto error;
1228 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1229 if (status < 0)
1230 goto error;
1231 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1232 if (status < 0)
1233 goto error;
1234 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1235 if (status < 0)
1236 goto error;
1237 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1238 if (status < 0)
1239 goto error;
1240 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1241 if (status < 0)
1242 goto error;
1243 } else {
1244 /* Enable MPEG output */
1245 sioPdrMdxCfg =
1246 ((state->m_TSDataStrength <<
1247 SIO_PDR_MD0_CFG_DRIVE__B) | 0x0003);
1248 sioPdrMclkCfg = ((state->m_TSClockkStrength <<
1249 SIO_PDR_MCLK_CFG_DRIVE__B) |
1250 0x0003);
1251
1252 status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg);
1253 if (status < 0)
1254 goto error;
1255 status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */
1256 if (status < 0)
1257 goto error;
1258 status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */
1259 if (status < 0)
1260 goto error;
1261 if (state->m_enableParallel == true) {
1262 /* paralel -> enable MD1 to MD7 */
1263 status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg);
1264 if (status < 0)
1265 goto error;
1266 status = write16(state, SIO_PDR_MD2_CFG__A, sioPdrMdxCfg);
1267 if (status < 0)
1268 goto error;
1269 status = write16(state, SIO_PDR_MD3_CFG__A, sioPdrMdxCfg);
1270 if (status < 0)
1271 goto error;
1272 status = write16(state, SIO_PDR_MD4_CFG__A, sioPdrMdxCfg);
1273 if (status < 0)
1274 goto error;
1275 status = write16(state, SIO_PDR_MD5_CFG__A, sioPdrMdxCfg);
1276 if (status < 0)
1277 goto error;
1278 status = write16(state, SIO_PDR_MD6_CFG__A, sioPdrMdxCfg);
1279 if (status < 0)
1280 goto error;
1281 status = write16(state, SIO_PDR_MD7_CFG__A, sioPdrMdxCfg);
1282 if (status < 0)
1283 goto error;
1284 } else {
1285 sioPdrMdxCfg = ((state->m_TSDataStrength <<
1286 SIO_PDR_MD0_CFG_DRIVE__B)
1287 | 0x0003);
1288 /* serial -> disable MD1 to MD7 */
1289 status = write16(state, SIO_PDR_MD1_CFG__A, 0x0000);
1290 if (status < 0)
1291 goto error;
1292 status = write16(state, SIO_PDR_MD2_CFG__A, 0x0000);
1293 if (status < 0)
1294 goto error;
1295 status = write16(state, SIO_PDR_MD3_CFG__A, 0x0000);
1296 if (status < 0)
1297 goto error;
1298 status = write16(state, SIO_PDR_MD4_CFG__A, 0x0000);
1299 if (status < 0)
1300 goto error;
1301 status = write16(state, SIO_PDR_MD5_CFG__A, 0x0000);
1302 if (status < 0)
1303 goto error;
1304 status = write16(state, SIO_PDR_MD6_CFG__A, 0x0000);
1305 if (status < 0)
1306 goto error;
1307 status = write16(state, SIO_PDR_MD7_CFG__A, 0x0000);
1308 if (status < 0)
1309 goto error;
1310 }
1311 status = write16(state, SIO_PDR_MCLK_CFG__A, sioPdrMclkCfg);
1312 if (status < 0)
1313 goto error;
1314 status = write16(state, SIO_PDR_MD0_CFG__A, sioPdrMdxCfg);
1315 if (status < 0)
1316 goto error;
1317 }
1318 /* Enable MB output over MPEG pads and ctl input */
1319 status = write16(state, SIO_PDR_MON_CFG__A, 0x0000);
1320 if (status < 0)
1321 goto error;
1322 /* Write nomagic word to enable pdr reg write */
1323 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
1324error:
1325 if (status < 0)
1326 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1327 return status;
1328}
1329
1330static int MPEGTSDisable(struct drxk_state *state)
1331{
1332 dprintk(1, "\n");
1333
1334 return MPEGTSConfigurePins(state, false);
1335}
1336
1337static int BLChainCmd(struct drxk_state *state,
1338 u16 romOffset, u16 nrOfElements, u32 timeOut)
1339{
1340 u16 blStatus = 0;
1341 int status;
1342 unsigned long end;
1343
1344 dprintk(1, "\n");
1345 mutex_lock(&state->mutex);
1346 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_CHAIN);
1347 if (status < 0)
1348 goto error;
1349 status = write16(state, SIO_BL_CHAIN_ADDR__A, romOffset);
1350 if (status < 0)
1351 goto error;
1352 status = write16(state, SIO_BL_CHAIN_LEN__A, nrOfElements);
1353 if (status < 0)
1354 goto error;
1355 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
1356 if (status < 0)
1357 goto error;
1358
1359 end = jiffies + msecs_to_jiffies(timeOut);
1360 do {
1361 msleep(1);
1362 status = read16(state, SIO_BL_STATUS__A, &blStatus);
1363 if (status < 0)
1364 goto error;
1365 } while ((blStatus == 0x1) &&
1366 ((time_is_after_jiffies(end))));
1367
1368 if (blStatus == 0x1) {
1369 printk(KERN_ERR "drxk: SIO not ready\n");
1370 status = -EINVAL;
1371 goto error2;
1372 }
1373error:
1374 if (status < 0)
1375 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1376error2:
1377 mutex_unlock(&state->mutex);
1378 return status;
1379}
1380
1381
1382static int DownloadMicrocode(struct drxk_state *state,
1383 const u8 pMCImage[], u32 Length)
1384{
1385 const u8 *pSrc = pMCImage;
1386 u16 Flags;
1387 u16 Drain;
1388 u32 Address;
1389 u16 nBlocks;
1390 u16 BlockSize;
1391 u16 BlockCRC;
1392 u32 offset = 0;
1393 u32 i;
1394 int status = 0;
1395
1396 dprintk(1, "\n");
1397
1398 /* down the drain (we don care about MAGIC_WORD) */
1399 Drain = (pSrc[0] << 8) | pSrc[1];
1400 pSrc += sizeof(u16);
1401 offset += sizeof(u16);
1402 nBlocks = (pSrc[0] << 8) | pSrc[1];
1403 pSrc += sizeof(u16);
1404 offset += sizeof(u16);
1405
1406 for (i = 0; i < nBlocks; i += 1) {
1407 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
1408 (pSrc[2] << 8) | pSrc[3];
1409 pSrc += sizeof(u32);
1410 offset += sizeof(u32);
1411
1412 BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
1413 pSrc += sizeof(u16);
1414 offset += sizeof(u16);
1415
1416 Flags = (pSrc[0] << 8) | pSrc[1];
1417 pSrc += sizeof(u16);
1418 offset += sizeof(u16);
1419
1420 BlockCRC = (pSrc[0] << 8) | pSrc[1];
1421 pSrc += sizeof(u16);
1422 offset += sizeof(u16);
1423
1424 if (offset + BlockSize > Length) {
1425 printk(KERN_ERR "drxk: Firmware is corrupted.\n");
1426 return -EINVAL;
1427 }
1428
1429 status = write_block(state, Address, BlockSize, pSrc);
1430 if (status < 0) {
1431 printk(KERN_ERR "drxk: Error %d while loading firmware\n", status);
1432 break;
1433 }
1434 pSrc += BlockSize;
1435 offset += BlockSize;
1436 }
1437 return status;
1438}
1439
1440static int DVBTEnableOFDMTokenRing(struct drxk_state *state, bool enable)
1441{
1442 int status;
1443 u16 data = 0;
1444 u16 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_ON;
1445 u16 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED;
1446 unsigned long end;
1447
1448 dprintk(1, "\n");
1449
1450 if (enable == false) {
1451 desiredCtrl = SIO_OFDM_SH_OFDM_RING_ENABLE_OFF;
1452 desiredStatus = SIO_OFDM_SH_OFDM_RING_STATUS_DOWN;
1453 }
1454
1455 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1456 if (status >= 0 && data == desiredStatus) {
1457 /* tokenring already has correct status */
1458 return status;
1459 }
1460 /* Disable/enable dvbt tokenring bridge */
1461 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, desiredCtrl);
1462
1463 end = jiffies + msecs_to_jiffies(DRXK_OFDM_TR_SHUTDOWN_TIMEOUT);
1464 do {
1465 status = read16(state, SIO_OFDM_SH_OFDM_RING_STATUS__A, &data);
1466 if ((status >= 0 && data == desiredStatus) || time_is_after_jiffies(end))
1467 break;
1468 msleep(1);
1469 } while (1);
1470 if (data != desiredStatus) {
1471 printk(KERN_ERR "drxk: SIO not ready\n");
1472 return -EINVAL;
1473 }
1474 return status;
1475}
1476
1477static int MPEGTSStop(struct drxk_state *state)
1478{
1479 int status = 0;
1480 u16 fecOcSncMode = 0;
1481 u16 fecOcIprMode = 0;
1482
1483 dprintk(1, "\n");
1484
1485 /* Gracefull shutdown (byte boundaries) */
1486 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1487 if (status < 0)
1488 goto error;
1489 fecOcSncMode |= FEC_OC_SNC_MODE_SHUTDOWN__M;
1490 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1491 if (status < 0)
1492 goto error;
1493
1494 /* Suppress MCLK during absence of data */
1495 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcIprMode);
1496 if (status < 0)
1497 goto error;
1498 fecOcIprMode |= FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M;
1499 status = write16(state, FEC_OC_IPR_MODE__A, fecOcIprMode);
1500
1501error:
1502 if (status < 0)
1503 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1504
1505 return status;
1506}
1507
1508static int scu_command(struct drxk_state *state,
1509 u16 cmd, u8 parameterLen,
1510 u16 *parameter, u8 resultLen, u16 *result)
1511{
1512#if (SCU_RAM_PARAM_0__A - SCU_RAM_PARAM_15__A) != 15
1513#error DRXK register mapping no longer compatible with this routine!
1514#endif
1515 u16 curCmd = 0;
1516 int status = -EINVAL;
1517 unsigned long end;
1518 u8 buffer[34];
1519 int cnt = 0, ii;
1520 const char *p;
1521 char errname[30];
1522
1523 dprintk(1, "\n");
1524
1525 if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) ||
1526 ((resultLen > 0) && (result == NULL)))
1527 goto error;
1528
1529 mutex_lock(&state->mutex);
1530
1531 /* assume that the command register is ready
1532 since it is checked afterwards */
1533 for (ii = parameterLen - 1; ii >= 0; ii -= 1) {
1534 buffer[cnt++] = (parameter[ii] & 0xFF);
1535 buffer[cnt++] = ((parameter[ii] >> 8) & 0xFF);
1536 }
1537 buffer[cnt++] = (cmd & 0xFF);
1538 buffer[cnt++] = ((cmd >> 8) & 0xFF);
1539
1540 write_block(state, SCU_RAM_PARAM_0__A -
1541 (parameterLen - 1), cnt, buffer);
1542 /* Wait until SCU has processed command */
1543 end = jiffies + msecs_to_jiffies(DRXK_MAX_WAITTIME);
1544 do {
1545 msleep(1);
1546 status = read16(state, SCU_RAM_COMMAND__A, &curCmd);
1547 if (status < 0)
1548 goto error;
1549 } while (!(curCmd == DRX_SCU_READY) && (time_is_after_jiffies(end)));
1550 if (curCmd != DRX_SCU_READY) {
1551 printk(KERN_ERR "drxk: SCU not ready\n");
1552 status = -EIO;
1553 goto error2;
1554 }
1555 /* read results */
1556 if ((resultLen > 0) && (result != NULL)) {
1557 s16 err;
1558 int ii;
1559
1560 for (ii = resultLen - 1; ii >= 0; ii -= 1) {
1561 status = read16(state, SCU_RAM_PARAM_0__A - ii, &result[ii]);
1562 if (status < 0)
1563 goto error;
1564 }
1565
1566 /* Check if an error was reported by SCU */
1567 err = (s16)result[0];
1568 if (err >= 0)
1569 goto error;
1570
1571 /* check for the known error codes */
1572 switch (err) {
1573 case SCU_RESULT_UNKCMD:
1574 p = "SCU_RESULT_UNKCMD";
1575 break;
1576 case SCU_RESULT_UNKSTD:
1577 p = "SCU_RESULT_UNKSTD";
1578 break;
1579 case SCU_RESULT_SIZE:
1580 p = "SCU_RESULT_SIZE";
1581 break;
1582 case SCU_RESULT_INVPAR:
1583 p = "SCU_RESULT_INVPAR";
1584 break;
1585 default: /* Other negative values are errors */
1586 sprintf(errname, "ERROR: %d\n", err);
1587 p = errname;
1588 }
1589 printk(KERN_ERR "drxk: %s while sending cmd 0x%04x with params:", p, cmd);
1590 print_hex_dump_bytes("drxk: ", DUMP_PREFIX_NONE, buffer, cnt);
1591 status = -EINVAL;
1592 goto error2;
1593 }
1594
1595error:
1596 if (status < 0)
1597 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1598error2:
1599 mutex_unlock(&state->mutex);
1600 return status;
1601}
1602
1603static int SetIqmAf(struct drxk_state *state, bool active)
1604{
1605 u16 data = 0;
1606 int status;
1607
1608 dprintk(1, "\n");
1609
1610 /* Configure IQM */
1611 status = read16(state, IQM_AF_STDBY__A, &data);
1612 if (status < 0)
1613 goto error;
1614
1615 if (!active) {
1616 data |= (IQM_AF_STDBY_STDBY_ADC_STANDBY
1617 | IQM_AF_STDBY_STDBY_AMP_STANDBY
1618 | IQM_AF_STDBY_STDBY_PD_STANDBY
1619 | IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY
1620 | IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY);
1621 } else {
1622 data &= ((~IQM_AF_STDBY_STDBY_ADC_STANDBY)
1623 & (~IQM_AF_STDBY_STDBY_AMP_STANDBY)
1624 & (~IQM_AF_STDBY_STDBY_PD_STANDBY)
1625 & (~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY)
1626 & (~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY)
1627 );
1628 }
1629 status = write16(state, IQM_AF_STDBY__A, data);
1630
1631error:
1632 if (status < 0)
1633 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1634 return status;
1635}
1636
1637static int CtrlPowerMode(struct drxk_state *state, enum DRXPowerMode *mode)
1638{
1639 int status = 0;
1640 u16 sioCcPwdMode = 0;
1641
1642 dprintk(1, "\n");
1643
1644 /* Check arguments */
1645 if (mode == NULL)
1646 return -EINVAL;
1647
1648 switch (*mode) {
1649 case DRX_POWER_UP:
1650 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_NONE;
1651 break;
1652 case DRXK_POWER_DOWN_OFDM:
1653 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OFDM;
1654 break;
1655 case DRXK_POWER_DOWN_CORE:
1656 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_CLOCK;
1657 break;
1658 case DRXK_POWER_DOWN_PLL:
1659 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_PLL;
1660 break;
1661 case DRX_POWER_DOWN:
1662 sioCcPwdMode = SIO_CC_PWD_MODE_LEVEL_OSC;
1663 break;
1664 default:
1665 /* Unknow sleep mode */
1666 return -EINVAL;
1667 }
1668
1669 /* If already in requested power mode, do nothing */
1670 if (state->m_currentPowerMode == *mode)
1671 return 0;
1672
1673 /* For next steps make sure to start from DRX_POWER_UP mode */
1674 if (state->m_currentPowerMode != DRX_POWER_UP) {
1675 status = PowerUpDevice(state);
1676 if (status < 0)
1677 goto error;
1678 status = DVBTEnableOFDMTokenRing(state, true);
1679 if (status < 0)
1680 goto error;
1681 }
1682
1683 if (*mode == DRX_POWER_UP) {
1684 /* Restore analog & pin configuartion */
1685 } else {
1686 /* Power down to requested mode */
1687 /* Backup some register settings */
1688 /* Set pins with possible pull-ups connected
1689 to them in input mode */
1690 /* Analog power down */
1691 /* ADC power down */
1692 /* Power down device */
1693 /* stop all comm_exec */
1694 /* Stop and power down previous standard */
1695 switch (state->m_OperationMode) {
1696 case OM_DVBT:
1697 status = MPEGTSStop(state);
1698 if (status < 0)
1699 goto error;
1700 status = PowerDownDVBT(state, false);
1701 if (status < 0)
1702 goto error;
1703 break;
1704 case OM_QAM_ITU_A:
1705 case OM_QAM_ITU_C:
1706 status = MPEGTSStop(state);
1707 if (status < 0)
1708 goto error;
1709 status = PowerDownQAM(state);
1710 if (status < 0)
1711 goto error;
1712 break;
1713 default:
1714 break;
1715 }
1716 status = DVBTEnableOFDMTokenRing(state, false);
1717 if (status < 0)
1718 goto error;
1719 status = write16(state, SIO_CC_PWD_MODE__A, sioCcPwdMode);
1720 if (status < 0)
1721 goto error;
1722 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
1723 if (status < 0)
1724 goto error;
1725
1726 if (*mode != DRXK_POWER_DOWN_OFDM) {
1727 state->m_HICfgCtrl |=
1728 SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
1729 status = HI_CfgCommand(state);
1730 if (status < 0)
1731 goto error;
1732 }
1733 }
1734 state->m_currentPowerMode = *mode;
1735
1736error:
1737 if (status < 0)
1738 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1739
1740 return status;
1741}
1742
1743static int PowerDownDVBT(struct drxk_state *state, bool setPowerMode)
1744{
1745 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
1746 u16 cmdResult = 0;
1747 u16 data = 0;
1748 int status;
1749
1750 dprintk(1, "\n");
1751
1752 status = read16(state, SCU_COMM_EXEC__A, &data);
1753 if (status < 0)
1754 goto error;
1755 if (data == SCU_COMM_EXEC_ACTIVE) {
1756 /* Send OFDM stop command */
1757 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
1758 if (status < 0)
1759 goto error;
1760 /* Send OFDM reset command */
1761 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
1762 if (status < 0)
1763 goto error;
1764 }
1765
1766 /* Reset datapath for OFDM, processors first */
1767 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
1768 if (status < 0)
1769 goto error;
1770 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
1771 if (status < 0)
1772 goto error;
1773 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
1774 if (status < 0)
1775 goto error;
1776
1777 /* powerdown AFE */
1778 status = SetIqmAf(state, false);
1779 if (status < 0)
1780 goto error;
1781
1782 /* powerdown to OFDM mode */
1783 if (setPowerMode) {
1784 status = CtrlPowerMode(state, &powerMode);
1785 if (status < 0)
1786 goto error;
1787 }
1788error:
1789 if (status < 0)
1790 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1791 return status;
1792}
1793
1794static int SetOperationMode(struct drxk_state *state,
1795 enum OperationMode oMode)
1796{
1797 int status = 0;
1798
1799 dprintk(1, "\n");
1800 /*
1801 Stop and power down previous standard
1802 TODO investigate total power down instead of partial
1803 power down depending on "previous" standard.
1804 */
1805
1806 /* disable HW lock indicator */
1807 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
1808 if (status < 0)
1809 goto error;
1810
1811 /* Device is already at the required mode */
1812 if (state->m_OperationMode == oMode)
1813 return 0;
1814
1815 switch (state->m_OperationMode) {
1816 /* OM_NONE was added for start up */
1817 case OM_NONE:
1818 break;
1819 case OM_DVBT:
1820 status = MPEGTSStop(state);
1821 if (status < 0)
1822 goto error;
1823 status = PowerDownDVBT(state, true);
1824 if (status < 0)
1825 goto error;
1826 state->m_OperationMode = OM_NONE;
1827 break;
1828 case OM_QAM_ITU_A: /* fallthrough */
1829 case OM_QAM_ITU_C:
1830 status = MPEGTSStop(state);
1831 if (status < 0)
1832 goto error;
1833 status = PowerDownQAM(state);
1834 if (status < 0)
1835 goto error;
1836 state->m_OperationMode = OM_NONE;
1837 break;
1838 case OM_QAM_ITU_B:
1839 default:
1840 status = -EINVAL;
1841 goto error;
1842 }
1843
1844 /*
1845 Power up new standard
1846 */
1847 switch (oMode) {
1848 case OM_DVBT:
1849 state->m_OperationMode = oMode;
1850 status = SetDVBTStandard(state, oMode);
1851 if (status < 0)
1852 goto error;
1853 break;
1854 case OM_QAM_ITU_A: /* fallthrough */
1855 case OM_QAM_ITU_C:
1856 state->m_OperationMode = oMode;
1857 status = SetQAMStandard(state, oMode);
1858 if (status < 0)
1859 goto error;
1860 break;
1861 case OM_QAM_ITU_B:
1862 default:
1863 status = -EINVAL;
1864 }
1865error:
1866 if (status < 0)
1867 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1868 return status;
1869}
1870
1871static int Start(struct drxk_state *state, s32 offsetFreq,
1872 s32 IntermediateFrequency)
1873{
1874 int status = -EINVAL;
1875
1876 u16 IFreqkHz;
1877 s32 OffsetkHz = offsetFreq / 1000;
1878
1879 dprintk(1, "\n");
1880 if (state->m_DrxkState != DRXK_STOPPED &&
1881 state->m_DrxkState != DRXK_DTV_STARTED)
1882 goto error;
1883
1884 state->m_bMirrorFreqSpect = (state->param.inversion == INVERSION_ON);
1885
1886 if (IntermediateFrequency < 0) {
1887 state->m_bMirrorFreqSpect = !state->m_bMirrorFreqSpect;
1888 IntermediateFrequency = -IntermediateFrequency;
1889 }
1890
1891 switch (state->m_OperationMode) {
1892 case OM_QAM_ITU_A:
1893 case OM_QAM_ITU_C:
1894 IFreqkHz = (IntermediateFrequency / 1000);
1895 status = SetQAM(state, IFreqkHz, OffsetkHz);
1896 if (status < 0)
1897 goto error;
1898 state->m_DrxkState = DRXK_DTV_STARTED;
1899 break;
1900 case OM_DVBT:
1901 IFreqkHz = (IntermediateFrequency / 1000);
1902 status = MPEGTSStop(state);
1903 if (status < 0)
1904 goto error;
1905 status = SetDVBT(state, IFreqkHz, OffsetkHz);
1906 if (status < 0)
1907 goto error;
1908 status = DVBTStart(state);
1909 if (status < 0)
1910 goto error;
1911 state->m_DrxkState = DRXK_DTV_STARTED;
1912 break;
1913 default:
1914 break;
1915 }
1916error:
1917 if (status < 0)
1918 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1919 return status;
1920}
1921
1922static int ShutDown(struct drxk_state *state)
1923{
1924 dprintk(1, "\n");
1925
1926 MPEGTSStop(state);
1927 return 0;
1928}
1929
1930static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
1931 u32 Time)
1932{
1933 int status = -EINVAL;
1934
1935 dprintk(1, "\n");
1936
1937 if (pLockStatus == NULL)
1938 goto error;
1939
1940 *pLockStatus = NOT_LOCKED;
1941
1942 /* define the SCU command code */
1943 switch (state->m_OperationMode) {
1944 case OM_QAM_ITU_A:
1945 case OM_QAM_ITU_B:
1946 case OM_QAM_ITU_C:
1947 status = GetQAMLockStatus(state, pLockStatus);
1948 break;
1949 case OM_DVBT:
1950 status = GetDVBTLockStatus(state, pLockStatus);
1951 break;
1952 default:
1953 break;
1954 }
1955error:
1956 if (status < 0)
1957 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1958 return status;
1959}
1960
1961static int MPEGTSStart(struct drxk_state *state)
1962{
1963 int status;
1964
1965 u16 fecOcSncMode = 0;
1966
1967 /* Allow OC to sync again */
1968 status = read16(state, FEC_OC_SNC_MODE__A, &fecOcSncMode);
1969 if (status < 0)
1970 goto error;
1971 fecOcSncMode &= ~FEC_OC_SNC_MODE_SHUTDOWN__M;
1972 status = write16(state, FEC_OC_SNC_MODE__A, fecOcSncMode);
1973 if (status < 0)
1974 goto error;
1975 status = write16(state, FEC_OC_SNC_UNLOCK__A, 1);
1976error:
1977 if (status < 0)
1978 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
1979 return status;
1980}
1981
1982static int MPEGTSDtoInit(struct drxk_state *state)
1983{
1984 int status;
1985
1986 dprintk(1, "\n");
1987
1988 /* Rate integration settings */
1989 status = write16(state, FEC_OC_RCN_CTL_STEP_LO__A, 0x0000);
1990 if (status < 0)
1991 goto error;
1992 status = write16(state, FEC_OC_RCN_CTL_STEP_HI__A, 0x000C);
1993 if (status < 0)
1994 goto error;
1995 status = write16(state, FEC_OC_RCN_GAIN__A, 0x000A);
1996 if (status < 0)
1997 goto error;
1998 status = write16(state, FEC_OC_AVR_PARM_A__A, 0x0008);
1999 if (status < 0)
2000 goto error;
2001 status = write16(state, FEC_OC_AVR_PARM_B__A, 0x0006);
2002 if (status < 0)
2003 goto error;
2004 status = write16(state, FEC_OC_TMD_HI_MARGIN__A, 0x0680);
2005 if (status < 0)
2006 goto error;
2007 status = write16(state, FEC_OC_TMD_LO_MARGIN__A, 0x0080);
2008 if (status < 0)
2009 goto error;
2010 status = write16(state, FEC_OC_TMD_COUNT__A, 0x03F4);
2011 if (status < 0)
2012 goto error;
2013
2014 /* Additional configuration */
2015 status = write16(state, FEC_OC_OCR_INVERT__A, 0);
2016 if (status < 0)
2017 goto error;
2018 status = write16(state, FEC_OC_SNC_LWM__A, 2);
2019 if (status < 0)
2020 goto error;
2021 status = write16(state, FEC_OC_SNC_HWM__A, 12);
2022error:
2023 if (status < 0)
2024 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2025
2026 return status;
2027}
2028
2029static int MPEGTSDtoSetup(struct drxk_state *state,
2030 enum OperationMode oMode)
2031{
2032 int status;
2033
2034 u16 fecOcRegMode = 0; /* FEC_OC_MODE register value */
2035 u16 fecOcRegIprMode = 0; /* FEC_OC_IPR_MODE register value */
2036 u16 fecOcDtoMode = 0; /* FEC_OC_IPR_INVERT register value */
2037 u16 fecOcFctMode = 0; /* FEC_OC_IPR_INVERT register value */
2038 u16 fecOcDtoPeriod = 2; /* FEC_OC_IPR_INVERT register value */
2039 u16 fecOcDtoBurstLen = 188; /* FEC_OC_IPR_INVERT register value */
2040 u32 fecOcRcnCtlRate = 0; /* FEC_OC_IPR_INVERT register value */
2041 u16 fecOcTmdMode = 0;
2042 u16 fecOcTmdIntUpdRate = 0;
2043 u32 maxBitRate = 0;
2044 bool staticCLK = false;
2045
2046 dprintk(1, "\n");
2047
2048 /* Check insertion of the Reed-Solomon parity bytes */
2049 status = read16(state, FEC_OC_MODE__A, &fecOcRegMode);
2050 if (status < 0)
2051 goto error;
2052 status = read16(state, FEC_OC_IPR_MODE__A, &fecOcRegIprMode);
2053 if (status < 0)
2054 goto error;
2055 fecOcRegMode &= (~FEC_OC_MODE_PARITY__M);
2056 fecOcRegIprMode &= (~FEC_OC_IPR_MODE_MVAL_DIS_PAR__M);
2057 if (state->m_insertRSByte == true) {
2058 /* enable parity symbol forward */
2059 fecOcRegMode |= FEC_OC_MODE_PARITY__M;
2060 /* MVAL disable during parity bytes */
2061 fecOcRegIprMode |= FEC_OC_IPR_MODE_MVAL_DIS_PAR__M;
2062 /* TS burst length to 204 */
2063 fecOcDtoBurstLen = 204;
2064 }
2065
2066 /* Check serial or parrallel output */
2067 fecOcRegIprMode &= (~(FEC_OC_IPR_MODE_SERIAL__M));
2068 if (state->m_enableParallel == false) {
2069 /* MPEG data output is serial -> set ipr_mode[0] */
2070 fecOcRegIprMode |= FEC_OC_IPR_MODE_SERIAL__M;
2071 }
2072
2073 switch (oMode) {
2074 case OM_DVBT:
2075 maxBitRate = state->m_DVBTBitrate;
2076 fecOcTmdMode = 3;
2077 fecOcRcnCtlRate = 0xC00000;
2078 staticCLK = state->m_DVBTStaticCLK;
2079 break;
2080 case OM_QAM_ITU_A: /* fallthrough */
2081 case OM_QAM_ITU_C:
2082 fecOcTmdMode = 0x0004;
2083 fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
2084 maxBitRate = state->m_DVBCBitrate;
2085 staticCLK = state->m_DVBCStaticCLK;
2086 break;
2087 default:
2088 status = -EINVAL;
2089 } /* switch (standard) */
2090 if (status < 0)
2091 goto error;
2092
2093 /* Configure DTO's */
2094 if (staticCLK) {
2095 u32 bitRate = 0;
2096
2097 /* Rational DTO for MCLK source (static MCLK rate),
2098 Dynamic DTO for optimal grouping
2099 (avoid intra-packet gaps),
2100 DTO offset enable to sync TS burst with MSTRT */
2101 fecOcDtoMode = (FEC_OC_DTO_MODE_DYNAMIC__M |
2102 FEC_OC_DTO_MODE_OFFSET_ENABLE__M);
2103 fecOcFctMode = (FEC_OC_FCT_MODE_RAT_ENA__M |
2104 FEC_OC_FCT_MODE_VIRT_ENA__M);
2105
2106 /* Check user defined bitrate */
2107 bitRate = maxBitRate;
2108 if (bitRate > 75900000UL) { /* max is 75.9 Mb/s */
2109 bitRate = 75900000UL;
2110 }
2111 /* Rational DTO period:
2112 dto_period = (Fsys / bitrate) - 2
2113
2114 Result should be floored,
2115 to make sure >= requested bitrate
2116 */
2117 fecOcDtoPeriod = (u16) (((state->m_sysClockFreq)
2118 * 1000) / bitRate);
2119 if (fecOcDtoPeriod <= 2)
2120 fecOcDtoPeriod = 0;
2121 else
2122 fecOcDtoPeriod -= 2;
2123 fecOcTmdIntUpdRate = 8;
2124 } else {
2125 /* (commonAttr->staticCLK == false) => dynamic mode */
2126 fecOcDtoMode = FEC_OC_DTO_MODE_DYNAMIC__M;
2127 fecOcFctMode = FEC_OC_FCT_MODE__PRE;
2128 fecOcTmdIntUpdRate = 5;
2129 }
2130
2131 /* Write appropriate registers with requested configuration */
2132 status = write16(state, FEC_OC_DTO_BURST_LEN__A, fecOcDtoBurstLen);
2133 if (status < 0)
2134 goto error;
2135 status = write16(state, FEC_OC_DTO_PERIOD__A, fecOcDtoPeriod);
2136 if (status < 0)
2137 goto error;
2138 status = write16(state, FEC_OC_DTO_MODE__A, fecOcDtoMode);
2139 if (status < 0)
2140 goto error;
2141 status = write16(state, FEC_OC_FCT_MODE__A, fecOcFctMode);
2142 if (status < 0)
2143 goto error;
2144 status = write16(state, FEC_OC_MODE__A, fecOcRegMode);
2145 if (status < 0)
2146 goto error;
2147 status = write16(state, FEC_OC_IPR_MODE__A, fecOcRegIprMode);
2148 if (status < 0)
2149 goto error;
2150
2151 /* Rate integration settings */
2152 status = write32(state, FEC_OC_RCN_CTL_RATE_LO__A, fecOcRcnCtlRate);
2153 if (status < 0)
2154 goto error;
2155 status = write16(state, FEC_OC_TMD_INT_UPD_RATE__A, fecOcTmdIntUpdRate);
2156 if (status < 0)
2157 goto error;
2158 status = write16(state, FEC_OC_TMD_MODE__A, fecOcTmdMode);
2159error:
2160 if (status < 0)
2161 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2162 return status;
2163}
2164
2165static int MPEGTSConfigurePolarity(struct drxk_state *state)
2166{
2167 u16 fecOcRegIprInvert = 0;
2168
2169 /* Data mask for the output data byte */
2170 u16 InvertDataMask =
2171 FEC_OC_IPR_INVERT_MD7__M | FEC_OC_IPR_INVERT_MD6__M |
2172 FEC_OC_IPR_INVERT_MD5__M | FEC_OC_IPR_INVERT_MD4__M |
2173 FEC_OC_IPR_INVERT_MD3__M | FEC_OC_IPR_INVERT_MD2__M |
2174 FEC_OC_IPR_INVERT_MD1__M | FEC_OC_IPR_INVERT_MD0__M;
2175
2176 dprintk(1, "\n");
2177
2178 /* Control selective inversion of output bits */
2179 fecOcRegIprInvert &= (~(InvertDataMask));
2180 if (state->m_invertDATA == true)
2181 fecOcRegIprInvert |= InvertDataMask;
2182 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MERR__M));
2183 if (state->m_invertERR == true)
2184 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MERR__M;
2185 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MSTRT__M));
2186 if (state->m_invertSTR == true)
2187 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MSTRT__M;
2188 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MVAL__M));
2189 if (state->m_invertVAL == true)
2190 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MVAL__M;
2191 fecOcRegIprInvert &= (~(FEC_OC_IPR_INVERT_MCLK__M));
2192 if (state->m_invertCLK == true)
2193 fecOcRegIprInvert |= FEC_OC_IPR_INVERT_MCLK__M;
2194
2195 return write16(state, FEC_OC_IPR_INVERT__A, fecOcRegIprInvert);
2196}
2197
2198#define SCU_RAM_AGC_KI_INV_RF_POL__M 0x4000
2199
2200static int SetAgcRf(struct drxk_state *state,
2201 struct SCfgAgc *pAgcCfg, bool isDTV)
2202{
2203 int status = -EINVAL;
2204 u16 data = 0;
2205 struct SCfgAgc *pIfAgcSettings;
2206
2207 dprintk(1, "\n");
2208
2209 if (pAgcCfg == NULL)
2210 goto error;
2211
2212 switch (pAgcCfg->ctrlMode) {
2213 case DRXK_AGC_CTRL_AUTO:
2214 /* Enable RF AGC DAC */
2215 status = read16(state, IQM_AF_STDBY__A, &data);
2216 if (status < 0)
2217 goto error;
2218 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2219 status = write16(state, IQM_AF_STDBY__A, data);
2220 if (status < 0)
2221 goto error;
2222 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2223 if (status < 0)
2224 goto error;
2225
2226 /* Enable SCU RF AGC loop */
2227 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2228
2229 /* Polarity */
2230 if (state->m_RfAgcPol)
2231 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2232 else
2233 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2234 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2235 if (status < 0)
2236 goto error;
2237
2238 /* Set speed (using complementary reduction value) */
2239 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2240 if (status < 0)
2241 goto error;
2242
2243 data &= ~SCU_RAM_AGC_KI_RED_RAGC_RED__M;
2244 data |= (~(pAgcCfg->speed <<
2245 SCU_RAM_AGC_KI_RED_RAGC_RED__B)
2246 & SCU_RAM_AGC_KI_RED_RAGC_RED__M);
2247
2248 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2249 if (status < 0)
2250 goto error;
2251
2252 if (IsDVBT(state))
2253 pIfAgcSettings = &state->m_dvbtIfAgcCfg;
2254 else if (IsQAM(state))
2255 pIfAgcSettings = &state->m_qamIfAgcCfg;
2256 else
2257 pIfAgcSettings = &state->m_atvIfAgcCfg;
2258 if (pIfAgcSettings == NULL) {
2259 status = -EINVAL;
2260 goto error;
2261 }
2262
2263 /* Set TOP, only if IF-AGC is in AUTO mode */
2264 if (pIfAgcSettings->ctrlMode == DRXK_AGC_CTRL_AUTO)
2265 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->top);
2266 if (status < 0)
2267 goto error;
2268
2269 /* Cut-Off current */
2270 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, pAgcCfg->cutOffCurrent);
2271 if (status < 0)
2272 goto error;
2273
2274 /* Max. output level */
2275 status = write16(state, SCU_RAM_AGC_RF_MAX__A, pAgcCfg->maxOutputLevel);
2276 if (status < 0)
2277 goto error;
2278
2279 break;
2280
2281 case DRXK_AGC_CTRL_USER:
2282 /* Enable RF AGC DAC */
2283 status = read16(state, IQM_AF_STDBY__A, &data);
2284 if (status < 0)
2285 goto error;
2286 data &= ~IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2287 status = write16(state, IQM_AF_STDBY__A, data);
2288 if (status < 0)
2289 goto error;
2290
2291 /* Disable SCU RF AGC loop */
2292 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2293 if (status < 0)
2294 goto error;
2295 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2296 if (state->m_RfAgcPol)
2297 data |= SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2298 else
2299 data &= ~SCU_RAM_AGC_CONFIG_INV_RF_POL__M;
2300 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2301 if (status < 0)
2302 goto error;
2303
2304 /* SCU c.o.c. to 0, enabling full control range */
2305 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, 0);
2306 if (status < 0)
2307 goto error;
2308
2309 /* Write value to output pin */
2310 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, pAgcCfg->outputLevel);
2311 if (status < 0)
2312 goto error;
2313 break;
2314
2315 case DRXK_AGC_CTRL_OFF:
2316 /* Disable RF AGC DAC */
2317 status = read16(state, IQM_AF_STDBY__A, &data);
2318 if (status < 0)
2319 goto error;
2320 data |= IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY;
2321 status = write16(state, IQM_AF_STDBY__A, data);
2322 if (status < 0)
2323 goto error;
2324
2325 /* Disable SCU RF AGC loop */
2326 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2327 if (status < 0)
2328 goto error;
2329 data |= SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M;
2330 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2331 if (status < 0)
2332 goto error;
2333 break;
2334
2335 default:
2336 status = -EINVAL;
2337
2338 }
2339error:
2340 if (status < 0)
2341 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2342 return status;
2343}
2344
2345#define SCU_RAM_AGC_KI_INV_IF_POL__M 0x2000
2346
2347static int SetAgcIf(struct drxk_state *state,
2348 struct SCfgAgc *pAgcCfg, bool isDTV)
2349{
2350 u16 data = 0;
2351 int status = 0;
2352 struct SCfgAgc *pRfAgcSettings;
2353
2354 dprintk(1, "\n");
2355
2356 switch (pAgcCfg->ctrlMode) {
2357 case DRXK_AGC_CTRL_AUTO:
2358
2359 /* Enable IF AGC DAC */
2360 status = read16(state, IQM_AF_STDBY__A, &data);
2361 if (status < 0)
2362 goto error;
2363 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2364 status = write16(state, IQM_AF_STDBY__A, data);
2365 if (status < 0)
2366 goto error;
2367
2368 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2369 if (status < 0)
2370 goto error;
2371
2372 /* Enable SCU IF AGC loop */
2373 data &= ~SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2374
2375 /* Polarity */
2376 if (state->m_IfAgcPol)
2377 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2378 else
2379 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2380 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2381 if (status < 0)
2382 goto error;
2383
2384 /* Set speed (using complementary reduction value) */
2385 status = read16(state, SCU_RAM_AGC_KI_RED__A, &data);
2386 if (status < 0)
2387 goto error;
2388 data &= ~SCU_RAM_AGC_KI_RED_IAGC_RED__M;
2389 data |= (~(pAgcCfg->speed <<
2390 SCU_RAM_AGC_KI_RED_IAGC_RED__B)
2391 & SCU_RAM_AGC_KI_RED_IAGC_RED__M);
2392
2393 status = write16(state, SCU_RAM_AGC_KI_RED__A, data);
2394 if (status < 0)
2395 goto error;
2396
2397 if (IsQAM(state))
2398 pRfAgcSettings = &state->m_qamRfAgcCfg;
2399 else
2400 pRfAgcSettings = &state->m_atvRfAgcCfg;
2401 if (pRfAgcSettings == NULL)
2402 return -1;
2403 /* Restore TOP */
2404 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pRfAgcSettings->top);
2405 if (status < 0)
2406 goto error;
2407 break;
2408
2409 case DRXK_AGC_CTRL_USER:
2410
2411 /* Enable IF AGC DAC */
2412 status = read16(state, IQM_AF_STDBY__A, &data);
2413 if (status < 0)
2414 goto error;
2415 data &= ~IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2416 status = write16(state, IQM_AF_STDBY__A, data);
2417 if (status < 0)
2418 goto error;
2419
2420 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2421 if (status < 0)
2422 goto error;
2423
2424 /* Disable SCU IF AGC loop */
2425 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2426
2427 /* Polarity */
2428 if (state->m_IfAgcPol)
2429 data |= SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2430 else
2431 data &= ~SCU_RAM_AGC_CONFIG_INV_IF_POL__M;
2432 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2433 if (status < 0)
2434 goto error;
2435
2436 /* Write value to output pin */
2437 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, pAgcCfg->outputLevel);
2438 if (status < 0)
2439 goto error;
2440 break;
2441
2442 case DRXK_AGC_CTRL_OFF:
2443
2444 /* Disable If AGC DAC */
2445 status = read16(state, IQM_AF_STDBY__A, &data);
2446 if (status < 0)
2447 goto error;
2448 data |= IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY;
2449 status = write16(state, IQM_AF_STDBY__A, data);
2450 if (status < 0)
2451 goto error;
2452
2453 /* Disable SCU IF AGC loop */
2454 status = read16(state, SCU_RAM_AGC_CONFIG__A, &data);
2455 if (status < 0)
2456 goto error;
2457 data |= SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M;
2458 status = write16(state, SCU_RAM_AGC_CONFIG__A, data);
2459 if (status < 0)
2460 goto error;
2461 break;
2462 } /* switch (agcSettingsIf->ctrlMode) */
2463
2464 /* always set the top to support
2465 configurations without if-loop */
2466 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, pAgcCfg->top);
2467error:
2468 if (status < 0)
2469 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2470 return status;
2471}
2472
2473static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
2474{
2475 u16 agcDacLvl;
2476 int status;
2477 u16 Level = 0;
2478
2479 dprintk(1, "\n");
2480
2481 status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
2482 if (status < 0) {
2483 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2484 return status;
2485 }
2486
2487 *pValue = 0;
2488
2489 if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
2490 Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
2491 if (Level < 14000)
2492 *pValue = (14000 - Level) / 4;
2493 else
2494 *pValue = 0;
2495
2496 return status;
2497}
2498
2499static int GetQAMSignalToNoise(struct drxk_state *state,
2500 s32 *pSignalToNoise)
2501{
2502 int status = 0;
2503 u16 qamSlErrPower = 0; /* accum. error between
2504 raw and sliced symbols */
2505 u32 qamSlSigPower = 0; /* used for MER, depends of
2506 QAM constellation */
2507 u32 qamSlMer = 0; /* QAM MER */
2508
2509 dprintk(1, "\n");
2510
2511 /* MER calculation */
2512
2513 /* get the register value needed for MER */
2514 status = read16(state, QAM_SL_ERR_POWER__A, &qamSlErrPower);
2515 if (status < 0) {
2516 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2517 return -EINVAL;
2518 }
2519
2520 switch (state->param.u.qam.modulation) {
2521 case QAM_16:
2522 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM16 << 2;
2523 break;
2524 case QAM_32:
2525 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM32 << 2;
2526 break;
2527 case QAM_64:
2528 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM64 << 2;
2529 break;
2530 case QAM_128:
2531 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM128 << 2;
2532 break;
2533 default:
2534 case QAM_256:
2535 qamSlSigPower = DRXK_QAM_SL_SIG_POWER_QAM256 << 2;
2536 break;
2537 }
2538
2539 if (qamSlErrPower > 0) {
2540 qamSlMer = Log10Times100(qamSlSigPower) -
2541 Log10Times100((u32) qamSlErrPower);
2542 }
2543 *pSignalToNoise = qamSlMer;
2544
2545 return status;
2546}
2547
2548static int GetDVBTSignalToNoise(struct drxk_state *state,
2549 s32 *pSignalToNoise)
2550{
2551 int status;
2552 u16 regData = 0;
2553 u32 EqRegTdSqrErrI = 0;
2554 u32 EqRegTdSqrErrQ = 0;
2555 u16 EqRegTdSqrErrExp = 0;
2556 u16 EqRegTdTpsPwrOfs = 0;
2557 u16 EqRegTdReqSmbCnt = 0;
2558 u32 tpsCnt = 0;
2559 u32 SqrErrIQ = 0;
2560 u32 a = 0;
2561 u32 b = 0;
2562 u32 c = 0;
2563 u32 iMER = 0;
2564 u16 transmissionParams = 0;
2565
2566 dprintk(1, "\n");
2567
2568 status = read16(state, OFDM_EQ_TOP_TD_TPS_PWR_OFS__A, &EqRegTdTpsPwrOfs);
2569 if (status < 0)
2570 goto error;
2571 status = read16(state, OFDM_EQ_TOP_TD_REQ_SMB_CNT__A, &EqRegTdReqSmbCnt);
2572 if (status < 0)
2573 goto error;
2574 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_EXP__A, &EqRegTdSqrErrExp);
2575 if (status < 0)
2576 goto error;
2577 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_I__A, &regData);
2578 if (status < 0)
2579 goto error;
2580 /* Extend SQR_ERR_I operational range */
2581 EqRegTdSqrErrI = (u32) regData;
2582 if ((EqRegTdSqrErrExp > 11) &&
2583 (EqRegTdSqrErrI < 0x00000FFFUL)) {
2584 EqRegTdSqrErrI += 0x00010000UL;
2585 }
2586 status = read16(state, OFDM_EQ_TOP_TD_SQR_ERR_Q__A, &regData);
2587 if (status < 0)
2588 goto error;
2589 /* Extend SQR_ERR_Q operational range */
2590 EqRegTdSqrErrQ = (u32) regData;
2591 if ((EqRegTdSqrErrExp > 11) &&
2592 (EqRegTdSqrErrQ < 0x00000FFFUL))
2593 EqRegTdSqrErrQ += 0x00010000UL;
2594
2595 status = read16(state, OFDM_SC_RA_RAM_OP_PARAM__A, &transmissionParams);
2596 if (status < 0)
2597 goto error;
2598
2599 /* Check input data for MER */
2600
2601 /* MER calculation (in 0.1 dB) without math.h */
2602 if ((EqRegTdTpsPwrOfs == 0) || (EqRegTdReqSmbCnt == 0))
2603 iMER = 0;
2604 else if ((EqRegTdSqrErrI + EqRegTdSqrErrQ) == 0) {
2605 /* No error at all, this must be the HW reset value
2606 * Apparently no first measurement yet
2607 * Set MER to 0.0 */
2608 iMER = 0;
2609 } else {
2610 SqrErrIQ = (EqRegTdSqrErrI + EqRegTdSqrErrQ) <<
2611 EqRegTdSqrErrExp;
2612 if ((transmissionParams &
2613 OFDM_SC_RA_RAM_OP_PARAM_MODE__M)
2614 == OFDM_SC_RA_RAM_OP_PARAM_MODE_2K)
2615 tpsCnt = 17;
2616 else
2617 tpsCnt = 68;
2618
2619 /* IMER = 100 * log10 (x)
2620 where x = (EqRegTdTpsPwrOfs^2 *
2621 EqRegTdReqSmbCnt * tpsCnt)/SqrErrIQ
2622
2623 => IMER = a + b -c
2624 where a = 100 * log10 (EqRegTdTpsPwrOfs^2)
2625 b = 100 * log10 (EqRegTdReqSmbCnt * tpsCnt)
2626 c = 100 * log10 (SqrErrIQ)
2627 */
2628
2629 /* log(x) x = 9bits * 9bits->18 bits */
2630 a = Log10Times100(EqRegTdTpsPwrOfs *
2631 EqRegTdTpsPwrOfs);
2632 /* log(x) x = 16bits * 7bits->23 bits */
2633 b = Log10Times100(EqRegTdReqSmbCnt * tpsCnt);
2634 /* log(x) x = (16bits + 16bits) << 15 ->32 bits */
2635 c = Log10Times100(SqrErrIQ);
2636
2637 iMER = a + b;
2638 /* No negative MER, clip to zero */
2639 if (iMER > c)
2640 iMER -= c;
2641 else
2642 iMER = 0;
2643 }
2644 *pSignalToNoise = iMER;
2645
2646error:
2647 if (status < 0)
2648 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2649 return status;
2650}
2651
2652static int GetSignalToNoise(struct drxk_state *state, s32 *pSignalToNoise)
2653{
2654 dprintk(1, "\n");
2655
2656 *pSignalToNoise = 0;
2657 switch (state->m_OperationMode) {
2658 case OM_DVBT:
2659 return GetDVBTSignalToNoise(state, pSignalToNoise);
2660 case OM_QAM_ITU_A:
2661 case OM_QAM_ITU_C:
2662 return GetQAMSignalToNoise(state, pSignalToNoise);
2663 default:
2664 break;
2665 }
2666 return 0;
2667}
2668
2669#if 0
2670static int GetDVBTQuality(struct drxk_state *state, s32 *pQuality)
2671{
2672 /* SNR Values for quasi errorfree reception rom Nordig 2.2 */
2673 int status = 0;
2674
2675 dprintk(1, "\n");
2676
2677 static s32 QE_SN[] = {
2678 51, /* QPSK 1/2 */
2679 69, /* QPSK 2/3 */
2680 79, /* QPSK 3/4 */
2681 89, /* QPSK 5/6 */
2682 97, /* QPSK 7/8 */
2683 108, /* 16-QAM 1/2 */
2684 131, /* 16-QAM 2/3 */
2685 146, /* 16-QAM 3/4 */
2686 156, /* 16-QAM 5/6 */
2687 160, /* 16-QAM 7/8 */
2688 165, /* 64-QAM 1/2 */
2689 187, /* 64-QAM 2/3 */
2690 202, /* 64-QAM 3/4 */
2691 216, /* 64-QAM 5/6 */
2692 225, /* 64-QAM 7/8 */
2693 };
2694
2695 *pQuality = 0;
2696
2697 do {
2698 s32 SignalToNoise = 0;
2699 u16 Constellation = 0;
2700 u16 CodeRate = 0;
2701 u32 SignalToNoiseRel;
2702 u32 BERQuality;
2703
2704 status = GetDVBTSignalToNoise(state, &SignalToNoise);
2705 if (status < 0)
2706 break;
2707 status = read16(state, OFDM_EQ_TOP_TD_TPS_CONST__A, &Constellation);
2708 if (status < 0)
2709 break;
2710 Constellation &= OFDM_EQ_TOP_TD_TPS_CONST__M;
2711
2712 status = read16(state, OFDM_EQ_TOP_TD_TPS_CODE_HP__A, &CodeRate);
2713 if (status < 0)
2714 break;
2715 CodeRate &= OFDM_EQ_TOP_TD_TPS_CODE_HP__M;
2716
2717 if (Constellation > OFDM_EQ_TOP_TD_TPS_CONST_64QAM ||
2718 CodeRate > OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8)
2719 break;
2720 SignalToNoiseRel = SignalToNoise -
2721 QE_SN[Constellation * 5 + CodeRate];
2722 BERQuality = 100;
2723
2724 if (SignalToNoiseRel < -70)
2725 *pQuality = 0;
2726 else if (SignalToNoiseRel < 30)
2727 *pQuality = ((SignalToNoiseRel + 70) *
2728 BERQuality) / 100;
2729 else
2730 *pQuality = BERQuality;
2731 } while (0);
2732 return 0;
2733};
2734
2735static int GetDVBCQuality(struct drxk_state *state, s32 *pQuality)
2736{
2737 int status = 0;
2738 *pQuality = 0;
2739
2740 dprintk(1, "\n");
2741
2742 do {
2743 u32 SignalToNoise = 0;
2744 u32 BERQuality = 100;
2745 u32 SignalToNoiseRel = 0;
2746
2747 status = GetQAMSignalToNoise(state, &SignalToNoise);
2748 if (status < 0)
2749 break;
2750
2751 switch (state->param.u.qam.modulation) {
2752 case QAM_16:
2753 SignalToNoiseRel = SignalToNoise - 200;
2754 break;
2755 case QAM_32:
2756 SignalToNoiseRel = SignalToNoise - 230;
2757 break; /* Not in NorDig */
2758 case QAM_64:
2759 SignalToNoiseRel = SignalToNoise - 260;
2760 break;
2761 case QAM_128:
2762 SignalToNoiseRel = SignalToNoise - 290;
2763 break;
2764 default:
2765 case QAM_256:
2766 SignalToNoiseRel = SignalToNoise - 320;
2767 break;
2768 }
2769
2770 if (SignalToNoiseRel < -70)
2771 *pQuality = 0;
2772 else if (SignalToNoiseRel < 30)
2773 *pQuality = ((SignalToNoiseRel + 70) *
2774 BERQuality) / 100;
2775 else
2776 *pQuality = BERQuality;
2777 } while (0);
2778
2779 return status;
2780}
2781
2782static int GetQuality(struct drxk_state *state, s32 *pQuality)
2783{
2784 dprintk(1, "\n");
2785
2786 switch (state->m_OperationMode) {
2787 case OM_DVBT:
2788 return GetDVBTQuality(state, pQuality);
2789 case OM_QAM_ITU_A:
2790 return GetDVBCQuality(state, pQuality);
2791 default:
2792 break;
2793 }
2794
2795 return 0;
2796}
2797#endif
2798
2799/* Free data ram in SIO HI */
2800#define SIO_HI_RA_RAM_USR_BEGIN__A 0x420040
2801#define SIO_HI_RA_RAM_USR_END__A 0x420060
2802
2803#define DRXK_HI_ATOMIC_BUF_START (SIO_HI_RA_RAM_USR_BEGIN__A)
2804#define DRXK_HI_ATOMIC_BUF_END (SIO_HI_RA_RAM_USR_BEGIN__A + 7)
2805#define DRXK_HI_ATOMIC_READ SIO_HI_RA_RAM_PAR_3_ACP_RW_READ
2806#define DRXK_HI_ATOMIC_WRITE SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE
2807
2808#define DRXDAP_FASI_ADDR2BLOCK(addr) (((addr) >> 22) & 0x3F)
2809#define DRXDAP_FASI_ADDR2BANK(addr) (((addr) >> 16) & 0x3F)
2810#define DRXDAP_FASI_ADDR2OFFSET(addr) ((addr) & 0x7FFF)
2811
2812static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
2813{
2814 int status = -EINVAL;
2815
2816 dprintk(1, "\n");
2817
2818 if (state->m_DrxkState == DRXK_UNINITIALIZED)
2819 goto error;
2820 if (state->m_DrxkState == DRXK_POWERED_DOWN)
2821 goto error;
2822
2823 if (state->no_i2c_bridge)
2824 return 0;
2825
2826 status = write16(state, SIO_HI_RA_RAM_PAR_1__A, SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY);
2827 if (status < 0)
2828 goto error;
2829 if (bEnableBridge) {
2830 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED);
2831 if (status < 0)
2832 goto error;
2833 } else {
2834 status = write16(state, SIO_HI_RA_RAM_PAR_2__A, SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN);
2835 if (status < 0)
2836 goto error;
2837 }
2838
2839 status = HI_Command(state, SIO_HI_RA_RAM_CMD_BRDCTRL, 0);
2840
2841error:
2842 if (status < 0)
2843 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2844 return status;
2845}
2846
2847static int SetPreSaw(struct drxk_state *state,
2848 struct SCfgPreSaw *pPreSawCfg)
2849{
2850 int status = -EINVAL;
2851
2852 dprintk(1, "\n");
2853
2854 if ((pPreSawCfg == NULL)
2855 || (pPreSawCfg->reference > IQM_AF_PDREF__M))
2856 goto error;
2857
2858 status = write16(state, IQM_AF_PDREF__A, pPreSawCfg->reference);
2859error:
2860 if (status < 0)
2861 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2862 return status;
2863}
2864
2865static int BLDirectCmd(struct drxk_state *state, u32 targetAddr,
2866 u16 romOffset, u16 nrOfElements, u32 timeOut)
2867{
2868 u16 blStatus = 0;
2869 u16 offset = (u16) ((targetAddr >> 0) & 0x00FFFF);
2870 u16 blockbank = (u16) ((targetAddr >> 16) & 0x000FFF);
2871 int status;
2872 unsigned long end;
2873
2874 dprintk(1, "\n");
2875
2876 mutex_lock(&state->mutex);
2877 status = write16(state, SIO_BL_MODE__A, SIO_BL_MODE_DIRECT);
2878 if (status < 0)
2879 goto error;
2880 status = write16(state, SIO_BL_TGT_HDR__A, blockbank);
2881 if (status < 0)
2882 goto error;
2883 status = write16(state, SIO_BL_TGT_ADDR__A, offset);
2884 if (status < 0)
2885 goto error;
2886 status = write16(state, SIO_BL_SRC_ADDR__A, romOffset);
2887 if (status < 0)
2888 goto error;
2889 status = write16(state, SIO_BL_SRC_LEN__A, nrOfElements);
2890 if (status < 0)
2891 goto error;
2892 status = write16(state, SIO_BL_ENABLE__A, SIO_BL_ENABLE_ON);
2893 if (status < 0)
2894 goto error;
2895
2896 end = jiffies + msecs_to_jiffies(timeOut);
2897 do {
2898 status = read16(state, SIO_BL_STATUS__A, &blStatus);
2899 if (status < 0)
2900 goto error;
2901 } while ((blStatus == 0x1) && time_is_after_jiffies(end));
2902 if (blStatus == 0x1) {
2903 printk(KERN_ERR "drxk: SIO not ready\n");
2904 status = -EINVAL;
2905 goto error2;
2906 }
2907error:
2908 if (status < 0)
2909 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2910error2:
2911 mutex_unlock(&state->mutex);
2912 return status;
2913
2914}
2915
2916static int ADCSyncMeasurement(struct drxk_state *state, u16 *count)
2917{
2918 u16 data = 0;
2919 int status;
2920
2921 dprintk(1, "\n");
2922
2923 /* Start measurement */
2924 status = write16(state, IQM_AF_COMM_EXEC__A, IQM_AF_COMM_EXEC_ACTIVE);
2925 if (status < 0)
2926 goto error;
2927 status = write16(state, IQM_AF_START_LOCK__A, 1);
2928 if (status < 0)
2929 goto error;
2930
2931 *count = 0;
2932 status = read16(state, IQM_AF_PHASE0__A, &data);
2933 if (status < 0)
2934 goto error;
2935 if (data == 127)
2936 *count = *count + 1;
2937 status = read16(state, IQM_AF_PHASE1__A, &data);
2938 if (status < 0)
2939 goto error;
2940 if (data == 127)
2941 *count = *count + 1;
2942 status = read16(state, IQM_AF_PHASE2__A, &data);
2943 if (status < 0)
2944 goto error;
2945 if (data == 127)
2946 *count = *count + 1;
2947
2948error:
2949 if (status < 0)
2950 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2951 return status;
2952}
2953
2954static int ADCSynchronization(struct drxk_state *state)
2955{
2956 u16 count = 0;
2957 int status;
2958
2959 dprintk(1, "\n");
2960
2961 status = ADCSyncMeasurement(state, &count);
2962 if (status < 0)
2963 goto error;
2964
2965 if (count == 1) {
2966 /* Try sampling on a diffrent edge */
2967 u16 clkNeg = 0;
2968
2969 status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
2970 if (status < 0)
2971 goto error;
2972 if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
2973 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
2974 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2975 clkNeg |=
2976 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG;
2977 } else {
2978 clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
2979 clkNeg |=
2980 IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS;
2981 }
2982 status = write16(state, IQM_AF_CLKNEG__A, clkNeg);
2983 if (status < 0)
2984 goto error;
2985 status = ADCSyncMeasurement(state, &count);
2986 if (status < 0)
2987 goto error;
2988 }
2989
2990 if (count < 2)
2991 status = -EINVAL;
2992error:
2993 if (status < 0)
2994 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
2995 return status;
2996}
2997
2998static int SetFrequencyShifter(struct drxk_state *state,
2999 u16 intermediateFreqkHz,
3000 s32 tunerFreqOffset, bool isDTV)
3001{
3002 bool selectPosImage = false;
3003 u32 rfFreqResidual = tunerFreqOffset;
3004 u32 fmFrequencyShift = 0;
3005 bool tunerMirror = !state->m_bMirrorFreqSpect;
3006 u32 adcFreq;
3007 bool adcFlip;
3008 int status;
3009 u32 ifFreqActual;
3010 u32 samplingFrequency = (u32) (state->m_sysClockFreq / 3);
3011 u32 frequencyShift;
3012 bool imageToSelect;
3013
3014 dprintk(1, "\n");
3015
3016 /*
3017 Program frequency shifter
3018 No need to account for mirroring on RF
3019 */
3020 if (isDTV) {
3021 if ((state->m_OperationMode == OM_QAM_ITU_A) ||
3022 (state->m_OperationMode == OM_QAM_ITU_C) ||
3023 (state->m_OperationMode == OM_DVBT))
3024 selectPosImage = true;
3025 else
3026 selectPosImage = false;
3027 }
3028 if (tunerMirror)
3029 /* tuner doesn't mirror */
3030 ifFreqActual = intermediateFreqkHz +
3031 rfFreqResidual + fmFrequencyShift;
3032 else
3033 /* tuner mirrors */
3034 ifFreqActual = intermediateFreqkHz -
3035 rfFreqResidual - fmFrequencyShift;
3036 if (ifFreqActual > samplingFrequency / 2) {
3037 /* adc mirrors */
3038 adcFreq = samplingFrequency - ifFreqActual;
3039 adcFlip = true;
3040 } else {
3041 /* adc doesn't mirror */
3042 adcFreq = ifFreqActual;
3043 adcFlip = false;
3044 }
3045
3046 frequencyShift = adcFreq;
3047 imageToSelect = state->m_rfmirror ^ tunerMirror ^
3048 adcFlip ^ selectPosImage;
3049 state->m_IqmFsRateOfs =
3050 Frac28a((frequencyShift), samplingFrequency);
3051
3052 if (imageToSelect)
3053 state->m_IqmFsRateOfs = ~state->m_IqmFsRateOfs + 1;
3054
3055 /* Program frequency shifter with tuner offset compensation */
3056 /* frequencyShift += tunerFreqOffset; TODO */
3057 status = write32(state, IQM_FS_RATE_OFS_LO__A,
3058 state->m_IqmFsRateOfs);
3059 if (status < 0)
3060 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
3061 return status;
3062}
3063
3064static int InitAGC(struct drxk_state *state, bool isDTV)
3065{
3066 u16 ingainTgt = 0;
3067 u16 ingainTgtMin = 0;
3068 u16 ingainTgtMax = 0;
3069 u16 clpCyclen = 0;
3070 u16 clpSumMin = 0;
3071 u16 clpDirTo = 0;
3072 u16 snsSumMin = 0;
3073 u16 snsSumMax = 0;
3074 u16 clpSumMax = 0;
3075 u16 snsDirTo = 0;
3076 u16 kiInnergainMin = 0;
3077 u16 ifIaccuHiTgt = 0;
3078 u16 ifIaccuHiTgtMin = 0;
3079 u16 ifIaccuHiTgtMax = 0;
3080 u16 data = 0;
3081 u16 fastClpCtrlDelay = 0;
3082 u16 clpCtrlMode = 0;
3083 int status = 0;
3084
3085 dprintk(1, "\n");
3086
3087 /* Common settings */
3088 snsSumMax = 1023;
3089 ifIaccuHiTgtMin = 2047;
3090 clpCyclen = 500;
3091 clpSumMax = 1023;
3092
3093 /* AGCInit() not available for DVBT; init done in microcode */
3094 if (!IsQAM(state)) {
3095 printk(KERN_ERR "drxk: %s: mode %d is not DVB-C\n", __func__, state->m_OperationMode);
3096 return -EINVAL;
3097 }
3098
3099 /* FIXME: Analog TV AGC require different settings */
3100
3101 /* Standard specific settings */
3102 clpSumMin = 8;
3103 clpDirTo = (u16) -9;
3104 clpCtrlMode = 0;
3105 snsSumMin = 8;
3106 snsDirTo = (u16) -9;
3107 kiInnergainMin = (u16) -1030;
3108 ifIaccuHiTgtMax = 0x2380;
3109 ifIaccuHiTgt = 0x2380;
3110 ingainTgtMin = 0x0511;
3111 ingainTgt = 0x0511;
3112 ingainTgtMax = 5119;
3113 fastClpCtrlDelay = state->m_qamIfAgcCfg.FastClipCtrlDelay;
3114
3115 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, fastClpCtrlDelay);
3116 if (status < 0)
3117 goto error;
3118
3119 status = write16(state, SCU_RAM_AGC_CLP_CTRL_MODE__A, clpCtrlMode);
3120 if (status < 0)
3121 goto error;
3122 status = write16(state, SCU_RAM_AGC_INGAIN_TGT__A, ingainTgt);
3123 if (status < 0)
3124 goto error;
3125 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A, ingainTgtMin);
3126 if (status < 0)
3127 goto error;
3128 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, ingainTgtMax);
3129 if (status < 0)
3130 goto error;
3131 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A, ifIaccuHiTgtMin);
3132 if (status < 0)
3133 goto error;
3134 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A, ifIaccuHiTgtMax);
3135 if (status < 0)
3136 goto error;
3137 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI__A, 0);
3138 if (status < 0)
3139 goto error;
3140 status = write16(state, SCU_RAM_AGC_IF_IACCU_LO__A, 0);
3141 if (status < 0)
3142 goto error;
3143 status = write16(state, SCU_RAM_AGC_RF_IACCU_HI__A, 0);
3144 if (status < 0)
3145 goto error;
3146 status = write16(state, SCU_RAM_AGC_RF_IACCU_LO__A, 0);
3147 if (status < 0)
3148 goto error;
3149 status = write16(state, SCU_RAM_AGC_CLP_SUM_MAX__A, clpSumMax);
3150 if (status < 0)
3151 goto error;
3152 status = write16(state, SCU_RAM_AGC_SNS_SUM_MAX__A, snsSumMax);
3153 if (status < 0)
3154 goto error;
3155
3156 status = write16(state, SCU_RAM_AGC_KI_INNERGAIN_MIN__A, kiInnergainMin);
3157 if (status < 0)
3158 goto error;
3159 status = write16(state, SCU_RAM_AGC_IF_IACCU_HI_TGT__A, ifIaccuHiTgt);
3160 if (status < 0)
3161 goto error;
3162 status = write16(state, SCU_RAM_AGC_CLP_CYCLEN__A, clpCyclen);
3163 if (status < 0)
3164 goto error;
3165
3166 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MAX__A, 1023);
3167 if (status < 0)
3168 goto error;
3169 status = write16(state, SCU_RAM_AGC_RF_SNS_DEV_MIN__A, (u16) -1023);
3170 if (status < 0)
3171 goto error;
3172 status = write16(state, SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A, 50);
3173 if (status < 0)
3174 goto error;
3175
3176 status = write16(state, SCU_RAM_AGC_KI_MAXMINGAIN_TH__A, 20);
3177 if (status < 0)
3178 goto error;
3179 status = write16(state, SCU_RAM_AGC_CLP_SUM_MIN__A, clpSumMin);
3180 if (status < 0)
3181 goto error;
3182 status = write16(state, SCU_RAM_AGC_SNS_SUM_MIN__A, snsSumMin);
3183 if (status < 0)
3184 goto error;
3185 status = write16(state, SCU_RAM_AGC_CLP_DIR_TO__A, clpDirTo);
3186 if (status < 0)
3187 goto error;
3188 status = write16(state, SCU_RAM_AGC_SNS_DIR_TO__A, snsDirTo);
3189 if (status < 0)
3190 goto error;
3191 status = write16(state, SCU_RAM_AGC_KI_MINGAIN__A, 0x7fff);
3192 if (status < 0)
3193 goto error;
3194 status = write16(state, SCU_RAM_AGC_KI_MAXGAIN__A, 0x0);
3195 if (status < 0)
3196 goto error;
3197 status = write16(state, SCU_RAM_AGC_KI_MIN__A, 0x0117);
3198 if (status < 0)
3199 goto error;
3200 status = write16(state, SCU_RAM_AGC_KI_MAX__A, 0x0657);
3201 if (status < 0)
3202 goto error;
3203 status = write16(state, SCU_RAM_AGC_CLP_SUM__A, 0);
3204 if (status < 0)
3205 goto error;
3206 status = write16(state, SCU_RAM_AGC_CLP_CYCCNT__A, 0);
3207 if (status < 0)
3208 goto error;
3209 status = write16(state, SCU_RAM_AGC_CLP_DIR_WD__A, 0);
3210 if (status < 0)
3211 goto error;
3212 status = write16(state, SCU_RAM_AGC_CLP_DIR_STP__A, 1);
3213 if (status < 0)
3214 goto error;
3215 status = write16(state, SCU_RAM_AGC_SNS_SUM__A, 0);
3216 if (status < 0)
3217 goto error;
3218 status = write16(state, SCU_RAM_AGC_SNS_CYCCNT__A, 0);
3219 if (status < 0)
3220 goto error;
3221 status = write16(state, SCU_RAM_AGC_SNS_DIR_WD__A, 0);
3222 if (status < 0)
3223 goto error;
3224 status = write16(state, SCU_RAM_AGC_SNS_DIR_STP__A, 1);
3225 if (status < 0)
3226 goto error;
3227 status = write16(state, SCU_RAM_AGC_SNS_CYCLEN__A, 500);
3228 if (status < 0)
3229 goto error;
3230 status = write16(state, SCU_RAM_AGC_KI_CYCLEN__A, 500);
3231 if (status < 0)
3232 goto error;
3233
3234 /* Initialize inner-loop KI gain factors */
3235 status = read16(state, SCU_RAM_AGC_KI__A, &data);
3236 if (status < 0)
3237 goto error;
3238
3239 data = 0x0657;
3240 data &= ~SCU_RAM_AGC_KI_RF__M;
3241 data |= (DRXK_KI_RAGC_QAM << SCU_RAM_AGC_KI_RF__B);
3242 data &= ~SCU_RAM_AGC_KI_IF__M;
3243 data |= (DRXK_KI_IAGC_QAM << SCU_RAM_AGC_KI_IF__B);
3244
3245 status = write16(state, SCU_RAM_AGC_KI__A, data);
3246error:
3247 if (status < 0)
3248 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
3249 return status;
3250}
3251
3252static int DVBTQAMGetAccPktErr(struct drxk_state *state, u16 *packetErr)
3253{
3254 int status;
3255
3256 dprintk(1, "\n");
3257 if (packetErr == NULL)
3258 status = write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
3259 else
3260 status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, packetErr);
3261 if (status < 0)
3262 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
3263 return status;
3264}
3265
3266static int DVBTScCommand(struct drxk_state *state,
3267 u16 cmd, u16 subcmd,
3268 u16 param0, u16 param1, u16 param2,
3269 u16 param3, u16 param4)
3270{
3271 u16 curCmd = 0;
3272 u16 errCode = 0;
3273 u16 retryCnt = 0;
3274 u16 scExec = 0;
3275 int status;
3276
3277 dprintk(1, "\n");
3278 status = read16(state, OFDM_SC_COMM_EXEC__A, &scExec);
3279 if (scExec != 1) {
3280 /* SC is not running */
3281 status = -EINVAL;
3282 }
3283 if (status < 0)
3284 goto error;
3285
3286 /* Wait until sc is ready to receive command */
3287 retryCnt = 0;
3288 do {
3289 msleep(1);
3290 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
3291 retryCnt++;
3292 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
3293 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3294 goto error;
3295
3296 /* Write sub-command */
3297 switch (cmd) {
3298 /* All commands using sub-cmd */
3299 case OFDM_SC_RA_RAM_CMD_PROC_START:
3300 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3301 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3302 status = write16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, subcmd);
3303 if (status < 0)
3304 goto error;
3305 break;
3306 default:
3307 /* Do nothing */
3308 break;
3309 }
3310
3311 /* Write needed parameters and the command */
3312 switch (cmd) {
3313 /* All commands using 5 parameters */
3314 /* All commands using 4 parameters */
3315 /* All commands using 3 parameters */
3316 /* All commands using 2 parameters */
3317 case OFDM_SC_RA_RAM_CMD_PROC_START:
3318 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3319 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3320 status = write16(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
3321 /* All commands using 1 parameters */
3322 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3323 case OFDM_SC_RA_RAM_CMD_USER_IO:
3324 status = write16(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
3325 /* All commands using 0 parameters */
3326 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3327 case OFDM_SC_RA_RAM_CMD_NULL:
3328 /* Write command */
3329 status = write16(state, OFDM_SC_RA_RAM_CMD__A, cmd);
3330 break;
3331 default:
3332 /* Unknown command */
3333 status = -EINVAL;
3334 }
3335 if (status < 0)
3336 goto error;
3337
3338 /* Wait until sc is ready processing command */
3339 retryCnt = 0;
3340 do {
3341 msleep(1);
3342 status = read16(state, OFDM_SC_RA_RAM_CMD__A, &curCmd);
3343 retryCnt++;
3344 } while ((curCmd != 0) && (retryCnt < DRXK_MAX_RETRIES));
3345 if (retryCnt >= DRXK_MAX_RETRIES && (status < 0))
3346 goto error;
3347
3348 /* Check for illegal cmd */
3349 status = read16(state, OFDM_SC_RA_RAM_CMD_ADDR__A, &errCode);
3350 if (errCode == 0xFFFF) {
3351 /* illegal command */
3352 status = -EINVAL;
3353 }
3354 if (status < 0)
3355 goto error;
3356
3357 /* Retreive results parameters from SC */
3358 switch (cmd) {
3359 /* All commands yielding 5 results */
3360 /* All commands yielding 4 results */
3361 /* All commands yielding 3 results */
3362 /* All commands yielding 2 results */
3363 /* All commands yielding 1 result */
3364 case OFDM_SC_RA_RAM_CMD_USER_IO:
3365 case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
3366 status = read16(state, OFDM_SC_RA_RAM_PARAM0__A, &(param0));
3367 /* All commands yielding 0 results */
3368 case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
3369 case OFDM_SC_RA_RAM_CMD_SET_TIMER:
3370 case OFDM_SC_RA_RAM_CMD_PROC_START:
3371 case OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM:
3372 case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
3373 case OFDM_SC_RA_RAM_CMD_NULL:
3374 break;
3375 default:
3376 /* Unknown command */
3377 status = -EINVAL;
3378 break;
3379 } /* switch (cmd->cmd) */
3380error:
3381 if (status < 0)
3382 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
3383 return status;
3384}
3385
3386static int PowerUpDVBT(struct drxk_state *state)
3387{
3388 enum DRXPowerMode powerMode = DRX_POWER_UP;
3389 int status;
3390
3391 dprintk(1, "\n");
3392 status = CtrlPowerMode(state, &powerMode);
3393 if (status < 0)
3394 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
3395 return status;
3396}
3397
3398static int DVBTCtrlSetIncEnable(struct drxk_state *state, bool *enabled)
3399{
3400 int status;
3401
3402 dprintk(1, "\n");
3403 if (*enabled == true)
3404 status = write16(state, IQM_CF_BYPASSDET__A, 0);
3405 else
3406 status = write16(state, IQM_CF_BYPASSDET__A, 1);
3407 if (status < 0)
3408 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
3409 return status;
3410}
3411
3412#define DEFAULT_FR_THRES_8K 4000
3413static int DVBTCtrlSetFrEnable(struct drxk_state *state, bool *enabled)
3414{
3415
3416 int status;
3417
3418 dprintk(1, "\n");
3419 if (*enabled == true) {
3420 /* write mask to 1 */
3421 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A,
3422 DEFAULT_FR_THRES_8K);
3423 } else {
3424 /* write mask to 0 */
3425 status = write16(state, OFDM_SC_RA_RAM_FR_THRES_8K__A, 0);
3426 }
3427 if (status < 0)
3428 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
3429
3430 return status;
3431}
3432
3433static int DVBTCtrlSetEchoThreshold(struct drxk_state *state,
3434 struct DRXKCfgDvbtEchoThres_t *echoThres)
3435{
3436 u16 data = 0;
3437 int status;
3438
3439 dprintk(1, "\n");
3440 status = read16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, &data);
3441 if (status < 0)
3442 goto error;
3443
3444 switch (echoThres->fftMode) {
3445 case DRX_FFTMODE_2K:
3446 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_2K__M;
3447 data |= ((echoThres->threshold <<
3448 OFDM_SC_RA_RAM_ECHO_THRES_2K__B)
3449 & (OFDM_SC_RA_RAM_ECHO_THRES_2K__M));
3450 break;
3451 case DRX_FFTMODE_8K:
3452 data &= ~OFDM_SC_RA_RAM_ECHO_THRES_8K__M;
3453 data |= ((echoThres->threshold <<
3454 OFDM_SC_RA_RAM_ECHO_THRES_8K__B)
3455 & (OFDM_SC_RA_RAM_ECHO_THRES_8K__M));
3456 break;
3457 default:
3458 return -EINVAL;
3459 }
3460
3461 status = write16(state, OFDM_SC_RA_RAM_ECHO_THRES__A, data);
3462error:
3463 if (status < 0)
3464 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
3465 return status;
3466}
3467
3468static int DVBTCtrlSetSqiSpeed(struct drxk_state *state,
3469 enum DRXKCfgDvbtSqiSpeed *speed)
3470{
3471 int status = -EINVAL;
3472
3473 dprintk(1, "\n");
3474
3475 switch (*speed) {
3476 case DRXK_DVBT_SQI_SPEED_FAST:
3477 case DRXK_DVBT_SQI_SPEED_MEDIUM:
3478 case DRXK_DVBT_SQI_SPEED_SLOW:
3479 break;
3480 default:
3481 goto error;
3482 }
3483 status = write16(state, SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A,
3484 (u16) *speed);
3485error:
3486 if (status < 0)
3487 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
3488 return status;
3489}
3490
3491/*============================================================================*/
3492
3493/**
3494* \brief Activate DVBT specific presets
3495* \param demod instance of demodulator.
3496* \return DRXStatus_t.
3497*
3498* Called in DVBTSetStandard
3499*
3500*/
3501static int DVBTActivatePresets(struct drxk_state *state)
3502{
3503 int status;
3504 bool setincenable = false;
3505 bool setfrenable = true;
3506
3507 struct DRXKCfgDvbtEchoThres_t echoThres2k = { 0, DRX_FFTMODE_2K };
3508 struct DRXKCfgDvbtEchoThres_t echoThres8k = { 0, DRX_FFTMODE_8K };
3509
3510 dprintk(1, "\n");
3511 status = DVBTCtrlSetIncEnable(state, &setincenable);
3512 if (status < 0)
3513 goto error;
3514 status = DVBTCtrlSetFrEnable(state, &setfrenable);
3515 if (status < 0)
3516 goto error;
3517 status = DVBTCtrlSetEchoThreshold(state, &echoThres2k);
3518 if (status < 0)
3519 goto error;
3520 status = DVBTCtrlSetEchoThreshold(state, &echoThres8k);
3521 if (status < 0)
3522 goto error;
3523 status = write16(state, SCU_RAM_AGC_INGAIN_TGT_MAX__A, state->m_dvbtIfAgcCfg.IngainTgtMax);
3524error:
3525 if (status < 0)
3526 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
3527 return status;
3528}
3529
3530/*============================================================================*/
3531
3532/**
3533* \brief Initialize channelswitch-independent settings for DVBT.
3534* \param demod instance of demodulator.
3535* \return DRXStatus_t.
3536*
3537* For ROM code channel filter taps are loaded from the bootloader. For microcode
3538* the DVB-T taps from the drxk_filters.h are used.
3539*/
3540static int SetDVBTStandard(struct drxk_state *state,
3541 enum OperationMode oMode)
3542{
3543 u16 cmdResult = 0;
3544 u16 data = 0;
3545 int status;
3546
3547 dprintk(1, "\n");
3548
3549 PowerUpDVBT(state);
3550 /* added antenna switch */
3551 SwitchAntennaToDVBT(state);
3552 /* send OFDM reset command */
3553 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
3554 if (status < 0)
3555 goto error;
3556
3557 /* send OFDM setenv command */
3558 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 0, NULL, 1, &cmdResult);
3559 if (status < 0)
3560 goto error;
3561
3562 /* reset datapath for OFDM, processors first */
3563 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3564 if (status < 0)
3565 goto error;
3566 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3567 if (status < 0)
3568 goto error;
3569 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
3570 if (status < 0)
3571 goto error;
3572
3573 /* IQM setup */
3574 /* synchronize on ofdstate->m_festart */
3575 status = write16(state, IQM_AF_UPD_SEL__A, 1);
3576 if (status < 0)
3577 goto error;
3578 /* window size for clipping ADC detection */
3579 status = write16(state, IQM_AF_CLP_LEN__A, 0);
3580 if (status < 0)
3581 goto error;
3582 /* window size for for sense pre-SAW detection */
3583 status = write16(state, IQM_AF_SNS_LEN__A, 0);
3584 if (status < 0)
3585 goto error;
3586 /* sense threshold for sense pre-SAW detection */
3587 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
3588 if (status < 0)
3589 goto error;
3590 status = SetIqmAf(state, true);
3591 if (status < 0)
3592 goto error;
3593
3594 status = write16(state, IQM_AF_AGC_RF__A, 0);
3595 if (status < 0)
3596 goto error;
3597
3598 /* Impulse noise cruncher setup */
3599 status = write16(state, IQM_AF_INC_LCT__A, 0); /* crunch in IQM_CF */
3600 if (status < 0)
3601 goto error;
3602 status = write16(state, IQM_CF_DET_LCT__A, 0); /* detect in IQM_CF */
3603 if (status < 0)
3604 goto error;
3605 status = write16(state, IQM_CF_WND_LEN__A, 3); /* peak detector window length */
3606 if (status < 0)
3607 goto error;
3608
3609 status = write16(state, IQM_RC_STRETCH__A, 16);
3610 if (status < 0)
3611 goto error;
3612 status = write16(state, IQM_CF_OUT_ENA__A, 0x4); /* enable output 2 */
3613 if (status < 0)
3614 goto error;
3615 status = write16(state, IQM_CF_DS_ENA__A, 0x4); /* decimate output 2 */
3616 if (status < 0)
3617 goto error;
3618 status = write16(state, IQM_CF_SCALE__A, 1600);
3619 if (status < 0)
3620 goto error;
3621 status = write16(state, IQM_CF_SCALE_SH__A, 0);
3622 if (status < 0)
3623 goto error;
3624
3625 /* virtual clipping threshold for clipping ADC detection */
3626 status = write16(state, IQM_AF_CLP_TH__A, 448);
3627 if (status < 0)
3628 goto error;
3629 status = write16(state, IQM_CF_DATATH__A, 495); /* crunching threshold */
3630 if (status < 0)
3631 goto error;
3632
3633 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_DVBT, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
3634 if (status < 0)
3635 goto error;
3636
3637 status = write16(state, IQM_CF_PKDTH__A, 2); /* peak detector threshold */
3638 if (status < 0)
3639 goto error;
3640 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 2);
3641 if (status < 0)
3642 goto error;
3643 /* enable power measurement interrupt */
3644 status = write16(state, IQM_CF_COMM_INT_MSK__A, 1);
3645 if (status < 0)
3646 goto error;
3647 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
3648 if (status < 0)
3649 goto error;
3650
3651 /* IQM will not be reset from here, sync ADC and update/init AGC */
3652 status = ADCSynchronization(state);
3653 if (status < 0)
3654 goto error;
3655 status = SetPreSaw(state, &state->m_dvbtPreSawCfg);
3656 if (status < 0)
3657 goto error;
3658
3659 /* Halt SCU to enable safe non-atomic accesses */
3660 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3661 if (status < 0)
3662 goto error;
3663
3664 status = SetAgcRf(state, &state->m_dvbtRfAgcCfg, true);
3665 if (status < 0)
3666 goto error;
3667 status = SetAgcIf(state, &state->m_dvbtIfAgcCfg, true);
3668 if (status < 0)
3669 goto error;
3670
3671 /* Set Noise Estimation notch width and enable DC fix */
3672 status = read16(state, OFDM_SC_RA_RAM_CONFIG__A, &data);
3673 if (status < 0)
3674 goto error;
3675 data |= OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M;
3676 status = write16(state, OFDM_SC_RA_RAM_CONFIG__A, data);
3677 if (status < 0)
3678 goto error;
3679
3680 /* Activate SCU to enable SCU commands */
3681 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
3682 if (status < 0)
3683 goto error;
3684
3685 if (!state->m_DRXK_A3_ROM_CODE) {
3686 /* AGCInit() is not done for DVBT, so set agcFastClipCtrlDelay */
3687 status = write16(state, SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A, state->m_dvbtIfAgcCfg.FastClipCtrlDelay);
3688 if (status < 0)
3689 goto error;
3690 }
3691
3692 /* OFDM_SC setup */
3693#ifdef COMPILE_FOR_NONRT
3694 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_DELAY__A, 1);
3695 if (status < 0)
3696 goto error;
3697 status = write16(state, OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A, 2);
3698 if (status < 0)
3699 goto error;
3700#endif
3701
3702 /* FEC setup */
3703 status = write16(state, FEC_DI_INPUT_CTL__A, 1); /* OFDM input */
3704 if (status < 0)
3705 goto error;
3706
3707
3708#ifdef COMPILE_FOR_NONRT
3709 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x400);
3710 if (status < 0)
3711 goto error;
3712#else
3713 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, 0x1000);
3714 if (status < 0)
3715 goto error;
3716#endif
3717 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, 0x0001);
3718 if (status < 0)
3719 goto error;
3720
3721 /* Setup MPEG bus */
3722 status = MPEGTSDtoSetup(state, OM_DVBT);
3723 if (status < 0)
3724 goto error;
3725 /* Set DVBT Presets */
3726 status = DVBTActivatePresets(state);
3727 if (status < 0)
3728 goto error;
3729
3730error:
3731 if (status < 0)
3732 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
3733 return status;
3734}
3735
3736/*============================================================================*/
3737/**
3738* \brief Start dvbt demodulating for channel.
3739* \param demod instance of demodulator.
3740* \return DRXStatus_t.
3741*/
3742static int DVBTStart(struct drxk_state *state)
3743{
3744 u16 param1;
3745 int status;
3746 /* DRXKOfdmScCmd_t scCmd; */
3747
3748 dprintk(1, "\n");
3749 /* Start correct processes to get in lock */
3750 /* DRXK: OFDM_SC_RA_RAM_PROC_LOCKTRACK is no longer in mapfile! */
3751 param1 = OFDM_SC_RA_RAM_LOCKTRACK_MIN;
3752 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_PROC_START, 0, OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M, param1, 0, 0, 0);
3753 if (status < 0)
3754 goto error;
3755 /* Start FEC OC */
3756 status = MPEGTSStart(state);
3757 if (status < 0)
3758 goto error;
3759 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
3760 if (status < 0)
3761 goto error;
3762error:
3763 if (status < 0)
3764 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
3765 return status;
3766}
3767
3768
3769/*============================================================================*/
3770
3771/**
3772* \brief Set up dvbt demodulator for channel.
3773* \param demod instance of demodulator.
3774* \return DRXStatus_t.
3775* // original DVBTSetChannel()
3776*/
3777static int SetDVBT(struct drxk_state *state, u16 IntermediateFreqkHz,
3778 s32 tunerFreqOffset)
3779{
3780 u16 cmdResult = 0;
3781 u16 transmissionParams = 0;
3782 u16 operationMode = 0;
3783 u32 iqmRcRateOfs = 0;
3784 u32 bandwidth = 0;
3785 u16 param1;
3786 int status;
3787
3788 dprintk(1, "IF =%d, TFO = %d\n", IntermediateFreqkHz, tunerFreqOffset);
3789
3790 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
3791 if (status < 0)
3792 goto error;
3793
3794 /* Halt SCU to enable safe non-atomic accesses */
3795 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
3796 if (status < 0)
3797 goto error;
3798
3799 /* Stop processors */
3800 status = write16(state, OFDM_SC_COMM_EXEC__A, OFDM_SC_COMM_EXEC_STOP);
3801 if (status < 0)
3802 goto error;
3803 status = write16(state, OFDM_LC_COMM_EXEC__A, OFDM_LC_COMM_EXEC_STOP);
3804 if (status < 0)
3805 goto error;
3806
3807 /* Mandatory fix, always stop CP, required to set spl offset back to
3808 hardware default (is set to 0 by ucode during pilot detection */
3809 status = write16(state, OFDM_CP_COMM_EXEC__A, OFDM_CP_COMM_EXEC_STOP);
3810 if (status < 0)
3811 goto error;
3812
3813 /*== Write channel settings to device =====================================*/
3814
3815 /* mode */
3816 switch (state->param.u.ofdm.transmission_mode) {
3817 case TRANSMISSION_MODE_AUTO:
3818 default:
3819 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
3820 /* fall through , try first guess DRX_FFTMODE_8K */
3821 case TRANSMISSION_MODE_8K:
3822 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
3823 break;
3824 case TRANSMISSION_MODE_2K:
3825 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_2K;
3826 break;
3827 }
3828
3829 /* guard */
3830 switch (state->param.u.ofdm.guard_interval) {
3831 default:
3832 case GUARD_INTERVAL_AUTO:
3833 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
3834 /* fall through , try first guess DRX_GUARD_1DIV4 */
3835 case GUARD_INTERVAL_1_4:
3836 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
3837 break;
3838 case GUARD_INTERVAL_1_32:
3839 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_32;
3840 break;
3841 case GUARD_INTERVAL_1_16:
3842 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_16;
3843 break;
3844 case GUARD_INTERVAL_1_8:
3845 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_8;
3846 break;
3847 }
3848
3849 /* hierarchy */
3850 switch (state->param.u.ofdm.hierarchy_information) {
3851 case HIERARCHY_AUTO:
3852 case HIERARCHY_NONE:
3853 default:
3854 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_HIER__M;
3855 /* fall through , try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
3856 /* transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO; */
3857 /* break; */
3858 case HIERARCHY_1:
3859 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
3860 break;
3861 case HIERARCHY_2:
3862 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A2;
3863 break;
3864 case HIERARCHY_4:
3865 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A4;
3866 break;
3867 }
3868
3869
3870 /* constellation */
3871 switch (state->param.u.ofdm.constellation) {
3872 case QAM_AUTO:
3873 default:
3874 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
3875 /* fall through , try first guess DRX_CONSTELLATION_QAM64 */
3876 case QAM_64:
3877 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
3878 break;
3879 case QPSK:
3880 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK;
3881 break;
3882 case QAM_16:
3883 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16;
3884 break;
3885 }
3886#if 0
3887 /* No hierachical channels support in BDA */
3888 /* Priority (only for hierarchical channels) */
3889 switch (channel->priority) {
3890 case DRX_PRIORITY_LOW:
3891 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO;
3892 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3893 OFDM_EC_SB_PRIOR_LO);
3894 break;
3895 case DRX_PRIORITY_HIGH:
3896 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3897 WR16(devAddr, OFDM_EC_SB_PRIOR__A,
3898 OFDM_EC_SB_PRIOR_HI));
3899 break;
3900 case DRX_PRIORITY_UNKNOWN: /* fall through */
3901 default:
3902 status = -EINVAL;
3903 goto error;
3904 }
3905#else
3906 /* Set Priorty high */
3907 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
3908 status = write16(state, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI);
3909 if (status < 0)
3910 goto error;
3911#endif
3912
3913 /* coderate */
3914 switch (state->param.u.ofdm.code_rate_HP) {
3915 case FEC_AUTO:
3916 default:
3917 operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
3918 /* fall through , try first guess DRX_CODERATE_2DIV3 */
3919 case FEC_2_3:
3920 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
3921 break;
3922 case FEC_1_2:
3923 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2;
3924 break;
3925 case FEC_3_4:
3926 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4;
3927 break;
3928 case FEC_5_6:
3929 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6;
3930 break;
3931 case FEC_7_8:
3932 transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8;
3933 break;
3934 }
3935
3936 /* SAW filter selection: normaly not necesarry, but if wanted
3937 the application can select a SAW filter via the driver by using UIOs */
3938 /* First determine real bandwidth (Hz) */
3939 /* Also set delay for impulse noise cruncher */
3940 /* Also set parameters for EC_OC fix, note EC_OC_REG_TMD_HIL_MAR is changed
3941 by SC for fix for some 8K,1/8 guard but is restored by InitEC and ResetEC
3942 functions */
3943 switch (state->param.u.ofdm.bandwidth) {
3944 case BANDWIDTH_AUTO:
3945 case BANDWIDTH_8_MHZ:
3946 bandwidth = DRXK_BANDWIDTH_8MHZ_IN_HZ;
3947 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3052);
3948 if (status < 0)
3949 goto error;
3950 /* cochannel protection for PAL 8 MHz */
3951 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 7);
3952 if (status < 0)
3953 goto error;
3954 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 7);
3955 if (status < 0)
3956 goto error;
3957 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 7);
3958 if (status < 0)
3959 goto error;
3960 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3961 if (status < 0)
3962 goto error;
3963 break;
3964 case BANDWIDTH_7_MHZ:
3965 bandwidth = DRXK_BANDWIDTH_7MHZ_IN_HZ;
3966 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 3491);
3967 if (status < 0)
3968 goto error;
3969 /* cochannel protection for PAL 7 MHz */
3970 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 8);
3971 if (status < 0)
3972 goto error;
3973 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 8);
3974 if (status < 0)
3975 goto error;
3976 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 4);
3977 if (status < 0)
3978 goto error;
3979 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3980 if (status < 0)
3981 goto error;
3982 break;
3983 case BANDWIDTH_6_MHZ:
3984 bandwidth = DRXK_BANDWIDTH_6MHZ_IN_HZ;
3985 status = write16(state, OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A, 4073);
3986 if (status < 0)
3987 goto error;
3988 /* cochannel protection for NTSC 6 MHz */
3989 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A, 19);
3990 if (status < 0)
3991 goto error;
3992 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A, 19);
3993 if (status < 0)
3994 goto error;
3995 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A, 14);
3996 if (status < 0)
3997 goto error;
3998 status = write16(state, OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A, 1);
3999 if (status < 0)
4000 goto error;
4001 break;
4002 default:
4003 status = -EINVAL;
4004 goto error;
4005 }
4006
4007 if (iqmRcRateOfs == 0) {
4008 /* Now compute IQM_RC_RATE_OFS
4009 (((SysFreq/BandWidth)/2)/2) -1) * 2^23)
4010 =>
4011 ((SysFreq / BandWidth) * (2^21)) - (2^23)
4012 */
4013 /* (SysFreq / BandWidth) * (2^28) */
4014 /* assert (MAX(sysClk)/MIN(bandwidth) < 16)
4015 => assert(MAX(sysClk) < 16*MIN(bandwidth))
4016 => assert(109714272 > 48000000) = true so Frac 28 can be used */
4017 iqmRcRateOfs = Frac28a((u32)
4018 ((state->m_sysClockFreq *
4019 1000) / 3), bandwidth);
4020 /* (SysFreq / BandWidth) * (2^21), rounding before truncating */
4021 if ((iqmRcRateOfs & 0x7fL) >= 0x40)
4022 iqmRcRateOfs += 0x80L;
4023 iqmRcRateOfs = iqmRcRateOfs >> 7;
4024 /* ((SysFreq / BandWidth) * (2^21)) - (2^23) */
4025 iqmRcRateOfs = iqmRcRateOfs - (1 << 23);
4026 }
4027
4028 iqmRcRateOfs &=
4029 ((((u32) IQM_RC_RATE_OFS_HI__M) <<
4030 IQM_RC_RATE_OFS_LO__W) | IQM_RC_RATE_OFS_LO__M);
4031 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRateOfs);
4032 if (status < 0)
4033 goto error;
4034
4035 /* Bandwidth setting done */
4036
4037#if 0
4038 status = DVBTSetFrequencyShift(demod, channel, tunerOffset);
4039 if (status < 0)
4040 goto error;
4041#endif
4042 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
4043 if (status < 0)
4044 goto error;
4045
4046 /*== Start SC, write channel settings to SC ===============================*/
4047
4048 /* Activate SCU to enable SCU commands */
4049 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
4050 if (status < 0)
4051 goto error;
4052
4053 /* Enable SC after setting all other parameters */
4054 status = write16(state, OFDM_SC_COMM_STATE__A, 0);
4055 if (status < 0)
4056 goto error;
4057 status = write16(state, OFDM_SC_COMM_EXEC__A, 1);
4058 if (status < 0)
4059 goto error;
4060
4061
4062 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_OFDM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
4063 if (status < 0)
4064 goto error;
4065
4066 /* Write SC parameter registers, set all AUTO flags in operation mode */
4067 param1 = (OFDM_SC_RA_RAM_OP_AUTO_MODE__M |
4068 OFDM_SC_RA_RAM_OP_AUTO_GUARD__M |
4069 OFDM_SC_RA_RAM_OP_AUTO_CONST__M |
4070 OFDM_SC_RA_RAM_OP_AUTO_HIER__M |
4071 OFDM_SC_RA_RAM_OP_AUTO_RATE__M);
4072 status = DVBTScCommand(state, OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM,
4073 0, transmissionParams, param1, 0, 0, 0);
4074 if (status < 0)
4075 goto error;
4076
4077 if (!state->m_DRXK_A3_ROM_CODE)
4078 status = DVBTCtrlSetSqiSpeed(state, &state->m_sqiSpeed);
4079error:
4080 if (status < 0)
4081 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
4082
4083 return status;
4084}
4085
4086
4087/*============================================================================*/
4088
4089/**
4090* \brief Retreive lock status .
4091* \param demod Pointer to demodulator instance.
4092* \param lockStat Pointer to lock status structure.
4093* \return DRXStatus_t.
4094*
4095*/
4096static int GetDVBTLockStatus(struct drxk_state *state, u32 *pLockStatus)
4097{
4098 int status;
4099 const u16 mpeg_lock_mask = (OFDM_SC_RA_RAM_LOCK_MPEG__M |
4100 OFDM_SC_RA_RAM_LOCK_FEC__M);
4101 const u16 fec_lock_mask = (OFDM_SC_RA_RAM_LOCK_FEC__M);
4102 const u16 demod_lock_mask = OFDM_SC_RA_RAM_LOCK_DEMOD__M;
4103
4104 u16 ScRaRamLock = 0;
4105 u16 ScCommExec = 0;
4106
4107 dprintk(1, "\n");
4108
4109 *pLockStatus = NOT_LOCKED;
4110 /* driver 0.9.0 */
4111 /* Check if SC is running */
4112 status = read16(state, OFDM_SC_COMM_EXEC__A, &ScCommExec);
4113 if (status < 0)
4114 goto end;
4115 if (ScCommExec == OFDM_SC_COMM_EXEC_STOP)
4116 goto end;
4117
4118 status = read16(state, OFDM_SC_RA_RAM_LOCK__A, &ScRaRamLock);
4119 if (status < 0)
4120 goto end;
4121
4122 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask)
4123 *pLockStatus = MPEG_LOCK;
4124 else if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
4125 *pLockStatus = FEC_LOCK;
4126 else if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
4127 *pLockStatus = DEMOD_LOCK;
4128 else if (ScRaRamLock & OFDM_SC_RA_RAM_LOCK_NODVBT__M)
4129 *pLockStatus = NEVER_LOCK;
4130end:
4131 if (status < 0)
4132 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
4133
4134 return status;
4135}
4136
4137static int PowerUpQAM(struct drxk_state *state)
4138{
4139 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
4140 int status;
4141
4142 dprintk(1, "\n");
4143 status = CtrlPowerMode(state, &powerMode);
4144 if (status < 0)
4145 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
4146
4147 return status;
4148}
4149
4150
4151/** Power Down QAM */
4152static int PowerDownQAM(struct drxk_state *state)
4153{
4154 u16 data = 0;
4155 u16 cmdResult;
4156 int status = 0;
4157
4158 dprintk(1, "\n");
4159 status = read16(state, SCU_COMM_EXEC__A, &data);
4160 if (status < 0)
4161 goto error;
4162 if (data == SCU_COMM_EXEC_ACTIVE) {
4163 /*
4164 STOP demodulator
4165 QAM and HW blocks
4166 */
4167 /* stop all comstate->m_exec */
4168 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
4169 if (status < 0)
4170 goto error;
4171 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_STOP, 0, NULL, 1, &cmdResult);
4172 if (status < 0)
4173 goto error;
4174 }
4175 /* powerdown AFE */
4176 status = SetIqmAf(state, false);
4177
4178error:
4179 if (status < 0)
4180 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
4181
4182 return status;
4183}
4184
4185/*============================================================================*/
4186
4187/**
4188* \brief Setup of the QAM Measurement intervals for signal quality
4189* \param demod instance of demod.
4190* \param constellation current constellation.
4191* \return DRXStatus_t.
4192*
4193* NOTE:
4194* Take into account that for certain settings the errorcounters can overflow.
4195* The implementation does not check this.
4196*
4197*/
4198static int SetQAMMeasurement(struct drxk_state *state,
4199 enum EDrxkConstellation constellation,
4200 u32 symbolRate)
4201{
4202 u32 fecBitsDesired = 0; /* BER accounting period */
4203 u32 fecRsPeriodTotal = 0; /* Total period */
4204 u16 fecRsPrescale = 0; /* ReedSolomon Measurement Prescale */
4205 u16 fecRsPeriod = 0; /* Value for corresponding I2C register */
4206 int status = 0;
4207
4208 dprintk(1, "\n");
4209
4210 fecRsPrescale = 1;
4211 /* fecBitsDesired = symbolRate [kHz] *
4212 FrameLenght [ms] *
4213 (constellation + 1) *
4214 SyncLoss (== 1) *
4215 ViterbiLoss (==1)
4216 */
4217 switch (constellation) {
4218 case DRX_CONSTELLATION_QAM16:
4219 fecBitsDesired = 4 * symbolRate;
4220 break;
4221 case DRX_CONSTELLATION_QAM32:
4222 fecBitsDesired = 5 * symbolRate;
4223 break;
4224 case DRX_CONSTELLATION_QAM64:
4225 fecBitsDesired = 6 * symbolRate;
4226 break;
4227 case DRX_CONSTELLATION_QAM128:
4228 fecBitsDesired = 7 * symbolRate;
4229 break;
4230 case DRX_CONSTELLATION_QAM256:
4231 fecBitsDesired = 8 * symbolRate;
4232 break;
4233 default:
4234 status = -EINVAL;
4235 }
4236 if (status < 0)
4237 goto error;
4238
4239 fecBitsDesired /= 1000; /* symbolRate [Hz] -> symbolRate [kHz] */
4240 fecBitsDesired *= 500; /* meas. period [ms] */
4241
4242 /* Annex A/C: bits/RsPeriod = 204 * 8 = 1632 */
4243 /* fecRsPeriodTotal = fecBitsDesired / 1632 */
4244 fecRsPeriodTotal = (fecBitsDesired / 1632UL) + 1; /* roughly ceil */
4245
4246 /* fecRsPeriodTotal = fecRsPrescale * fecRsPeriod */
4247 fecRsPrescale = 1 + (u16) (fecRsPeriodTotal >> 16);
4248 if (fecRsPrescale == 0) {
4249 /* Divide by zero (though impossible) */
4250 status = -EINVAL;
4251 if (status < 0)
4252 goto error;
4253 }
4254 fecRsPeriod =
4255 ((u16) fecRsPeriodTotal +
4256 (fecRsPrescale >> 1)) / fecRsPrescale;
4257
4258 /* write corresponding registers */
4259 status = write16(state, FEC_RS_MEASUREMENT_PERIOD__A, fecRsPeriod);
4260 if (status < 0)
4261 goto error;
4262 status = write16(state, FEC_RS_MEASUREMENT_PRESCALE__A, fecRsPrescale);
4263 if (status < 0)
4264 goto error;
4265 status = write16(state, FEC_OC_SNC_FAIL_PERIOD__A, fecRsPeriod);
4266error:
4267 if (status < 0)
4268 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
4269 return status;
4270}
4271
4272static int SetQAM16(struct drxk_state *state)
4273{
4274 int status = 0;
4275
4276 dprintk(1, "\n");
4277 /* QAM Equalizer Setup */
4278 /* Equalizer */
4279 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13517);
4280 if (status < 0)
4281 goto error;
4282 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 13517);
4283 if (status < 0)
4284 goto error;
4285 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 13517);
4286 if (status < 0)
4287 goto error;
4288 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13517);
4289 if (status < 0)
4290 goto error;
4291 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13517);
4292 if (status < 0)
4293 goto error;
4294 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 13517);
4295 if (status < 0)
4296 goto error;
4297 /* Decision Feedback Equalizer */
4298 status = write16(state, QAM_DQ_QUAL_FUN0__A, 2);
4299 if (status < 0)
4300 goto error;
4301 status = write16(state, QAM_DQ_QUAL_FUN1__A, 2);
4302 if (status < 0)
4303 goto error;
4304 status = write16(state, QAM_DQ_QUAL_FUN2__A, 2);
4305 if (status < 0)
4306 goto error;
4307 status = write16(state, QAM_DQ_QUAL_FUN3__A, 2);
4308 if (status < 0)
4309 goto error;
4310 status = write16(state, QAM_DQ_QUAL_FUN4__A, 2);
4311 if (status < 0)
4312 goto error;
4313 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4314 if (status < 0)
4315 goto error;
4316
4317 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4318 if (status < 0)
4319 goto error;
4320 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4321 if (status < 0)
4322 goto error;
4323 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4324 if (status < 0)
4325 goto error;
4326
4327 /* QAM Slicer Settings */
4328 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM16);
4329 if (status < 0)
4330 goto error;
4331
4332 /* QAM Loop Controller Coeficients */
4333 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4334 if (status < 0)
4335 goto error;
4336 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4337 if (status < 0)
4338 goto error;
4339 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4340 if (status < 0)
4341 goto error;
4342 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4343 if (status < 0)
4344 goto error;
4345 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4346 if (status < 0)
4347 goto error;
4348 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4349 if (status < 0)
4350 goto error;
4351 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4352 if (status < 0)
4353 goto error;
4354 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4355 if (status < 0)
4356 goto error;
4357
4358 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4359 if (status < 0)
4360 goto error;
4361 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4362 if (status < 0)
4363 goto error;
4364 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4365 if (status < 0)
4366 goto error;
4367 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4368 if (status < 0)
4369 goto error;
4370 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4371 if (status < 0)
4372 goto error;
4373 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4374 if (status < 0)
4375 goto error;
4376 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4377 if (status < 0)
4378 goto error;
4379 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4380 if (status < 0)
4381 goto error;
4382 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 32);
4383 if (status < 0)
4384 goto error;
4385 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4386 if (status < 0)
4387 goto error;
4388 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4389 if (status < 0)
4390 goto error;
4391 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4392 if (status < 0)
4393 goto error;
4394
4395
4396 /* QAM State Machine (FSM) Thresholds */
4397
4398 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 140);
4399 if (status < 0)
4400 goto error;
4401 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4402 if (status < 0)
4403 goto error;
4404 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 95);
4405 if (status < 0)
4406 goto error;
4407 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 120);
4408 if (status < 0)
4409 goto error;
4410 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 230);
4411 if (status < 0)
4412 goto error;
4413 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 105);
4414 if (status < 0)
4415 goto error;
4416
4417 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4418 if (status < 0)
4419 goto error;
4420 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4421 if (status < 0)
4422 goto error;
4423 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 24);
4424 if (status < 0)
4425 goto error;
4426
4427
4428 /* QAM FSM Tracking Parameters */
4429
4430 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 16);
4431 if (status < 0)
4432 goto error;
4433 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 220);
4434 if (status < 0)
4435 goto error;
4436 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 25);
4437 if (status < 0)
4438 goto error;
4439 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 6);
4440 if (status < 0)
4441 goto error;
4442 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -24);
4443 if (status < 0)
4444 goto error;
4445 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -65);
4446 if (status < 0)
4447 goto error;
4448 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -127);
4449 if (status < 0)
4450 goto error;
4451
4452error:
4453 if (status < 0)
4454 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
4455 return status;
4456}
4457
4458/*============================================================================*/
4459
4460/**
4461* \brief QAM32 specific setup
4462* \param demod instance of demod.
4463* \return DRXStatus_t.
4464*/
4465static int SetQAM32(struct drxk_state *state)
4466{
4467 int status = 0;
4468
4469 dprintk(1, "\n");
4470
4471 /* QAM Equalizer Setup */
4472 /* Equalizer */
4473 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6707);
4474 if (status < 0)
4475 goto error;
4476 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6707);
4477 if (status < 0)
4478 goto error;
4479 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6707);
4480 if (status < 0)
4481 goto error;
4482 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6707);
4483 if (status < 0)
4484 goto error;
4485 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6707);
4486 if (status < 0)
4487 goto error;
4488 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 6707);
4489 if (status < 0)
4490 goto error;
4491
4492 /* Decision Feedback Equalizer */
4493 status = write16(state, QAM_DQ_QUAL_FUN0__A, 3);
4494 if (status < 0)
4495 goto error;
4496 status = write16(state, QAM_DQ_QUAL_FUN1__A, 3);
4497 if (status < 0)
4498 goto error;
4499 status = write16(state, QAM_DQ_QUAL_FUN2__A, 3);
4500 if (status < 0)
4501 goto error;
4502 status = write16(state, QAM_DQ_QUAL_FUN3__A, 3);
4503 if (status < 0)
4504 goto error;
4505 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4506 if (status < 0)
4507 goto error;
4508 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4509 if (status < 0)
4510 goto error;
4511
4512 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4513 if (status < 0)
4514 goto error;
4515 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4516 if (status < 0)
4517 goto error;
4518 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4519 if (status < 0)
4520 goto error;
4521
4522 /* QAM Slicer Settings */
4523
4524 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM32);
4525 if (status < 0)
4526 goto error;
4527
4528
4529 /* QAM Loop Controller Coeficients */
4530
4531 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4532 if (status < 0)
4533 goto error;
4534 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4535 if (status < 0)
4536 goto error;
4537 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4538 if (status < 0)
4539 goto error;
4540 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4541 if (status < 0)
4542 goto error;
4543 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4544 if (status < 0)
4545 goto error;
4546 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4547 if (status < 0)
4548 goto error;
4549 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4550 if (status < 0)
4551 goto error;
4552 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4553 if (status < 0)
4554 goto error;
4555
4556 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4557 if (status < 0)
4558 goto error;
4559 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 20);
4560 if (status < 0)
4561 goto error;
4562 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 80);
4563 if (status < 0)
4564 goto error;
4565 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4566 if (status < 0)
4567 goto error;
4568 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 20);
4569 if (status < 0)
4570 goto error;
4571 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4572 if (status < 0)
4573 goto error;
4574 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4575 if (status < 0)
4576 goto error;
4577 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 16);
4578 if (status < 0)
4579 goto error;
4580 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 16);
4581 if (status < 0)
4582 goto error;
4583 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4584 if (status < 0)
4585 goto error;
4586 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4587 if (status < 0)
4588 goto error;
4589 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4590 if (status < 0)
4591 goto error;
4592
4593
4594 /* QAM State Machine (FSM) Thresholds */
4595
4596 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 90);
4597 if (status < 0)
4598 goto error;
4599 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 50);
4600 if (status < 0)
4601 goto error;
4602 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4603 if (status < 0)
4604 goto error;
4605 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4606 if (status < 0)
4607 goto error;
4608 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 170);
4609 if (status < 0)
4610 goto error;
4611 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
4612 if (status < 0)
4613 goto error;
4614
4615 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4616 if (status < 0)
4617 goto error;
4618 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4619 if (status < 0)
4620 goto error;
4621 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 10);
4622 if (status < 0)
4623 goto error;
4624
4625
4626 /* QAM FSM Tracking Parameters */
4627
4628 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4629 if (status < 0)
4630 goto error;
4631 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 140);
4632 if (status < 0)
4633 goto error;
4634 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) -8);
4635 if (status < 0)
4636 goto error;
4637 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) -16);
4638 if (status < 0)
4639 goto error;
4640 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -26);
4641 if (status < 0)
4642 goto error;
4643 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -56);
4644 if (status < 0)
4645 goto error;
4646 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -86);
4647error:
4648 if (status < 0)
4649 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
4650 return status;
4651}
4652
4653/*============================================================================*/
4654
4655/**
4656* \brief QAM64 specific setup
4657* \param demod instance of demod.
4658* \return DRXStatus_t.
4659*/
4660static int SetQAM64(struct drxk_state *state)
4661{
4662 int status = 0;
4663
4664 dprintk(1, "\n");
4665 /* QAM Equalizer Setup */
4666 /* Equalizer */
4667 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 13336);
4668 if (status < 0)
4669 goto error;
4670 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12618);
4671 if (status < 0)
4672 goto error;
4673 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 11988);
4674 if (status < 0)
4675 goto error;
4676 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 13809);
4677 if (status < 0)
4678 goto error;
4679 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13809);
4680 if (status < 0)
4681 goto error;
4682 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15609);
4683 if (status < 0)
4684 goto error;
4685
4686 /* Decision Feedback Equalizer */
4687 status = write16(state, QAM_DQ_QUAL_FUN0__A, 4);
4688 if (status < 0)
4689 goto error;
4690 status = write16(state, QAM_DQ_QUAL_FUN1__A, 4);
4691 if (status < 0)
4692 goto error;
4693 status = write16(state, QAM_DQ_QUAL_FUN2__A, 4);
4694 if (status < 0)
4695 goto error;
4696 status = write16(state, QAM_DQ_QUAL_FUN3__A, 4);
4697 if (status < 0)
4698 goto error;
4699 status = write16(state, QAM_DQ_QUAL_FUN4__A, 3);
4700 if (status < 0)
4701 goto error;
4702 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4703 if (status < 0)
4704 goto error;
4705
4706 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
4707 if (status < 0)
4708 goto error;
4709 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
4710 if (status < 0)
4711 goto error;
4712 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4713 if (status < 0)
4714 goto error;
4715
4716 /* QAM Slicer Settings */
4717 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM64);
4718 if (status < 0)
4719 goto error;
4720
4721
4722 /* QAM Loop Controller Coeficients */
4723
4724 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4725 if (status < 0)
4726 goto error;
4727 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4728 if (status < 0)
4729 goto error;
4730 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4731 if (status < 0)
4732 goto error;
4733 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4734 if (status < 0)
4735 goto error;
4736 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4737 if (status < 0)
4738 goto error;
4739 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4740 if (status < 0)
4741 goto error;
4742 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4743 if (status < 0)
4744 goto error;
4745 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4746 if (status < 0)
4747 goto error;
4748
4749 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4750 if (status < 0)
4751 goto error;
4752 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 30);
4753 if (status < 0)
4754 goto error;
4755 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 100);
4756 if (status < 0)
4757 goto error;
4758 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4759 if (status < 0)
4760 goto error;
4761 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 30);
4762 if (status < 0)
4763 goto error;
4764 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 50);
4765 if (status < 0)
4766 goto error;
4767 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4768 if (status < 0)
4769 goto error;
4770 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4771 if (status < 0)
4772 goto error;
4773 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
4774 if (status < 0)
4775 goto error;
4776 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4777 if (status < 0)
4778 goto error;
4779 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4780 if (status < 0)
4781 goto error;
4782 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
4783 if (status < 0)
4784 goto error;
4785
4786
4787 /* QAM State Machine (FSM) Thresholds */
4788
4789 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 100);
4790 if (status < 0)
4791 goto error;
4792 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4793 if (status < 0)
4794 goto error;
4795 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4796 if (status < 0)
4797 goto error;
4798 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 110);
4799 if (status < 0)
4800 goto error;
4801 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 200);
4802 if (status < 0)
4803 goto error;
4804 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 95);
4805 if (status < 0)
4806 goto error;
4807
4808 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
4809 if (status < 0)
4810 goto error;
4811 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
4812 if (status < 0)
4813 goto error;
4814 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 15);
4815 if (status < 0)
4816 goto error;
4817
4818
4819 /* QAM FSM Tracking Parameters */
4820
4821 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 12);
4822 if (status < 0)
4823 goto error;
4824 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 141);
4825 if (status < 0)
4826 goto error;
4827 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 7);
4828 if (status < 0)
4829 goto error;
4830 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 0);
4831 if (status < 0)
4832 goto error;
4833 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -15);
4834 if (status < 0)
4835 goto error;
4836 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -45);
4837 if (status < 0)
4838 goto error;
4839 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -80);
4840error:
4841 if (status < 0)
4842 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
4843
4844 return status;
4845}
4846
4847/*============================================================================*/
4848
4849/**
4850* \brief QAM128 specific setup
4851* \param demod: instance of demod.
4852* \return DRXStatus_t.
4853*/
4854static int SetQAM128(struct drxk_state *state)
4855{
4856 int status = 0;
4857
4858 dprintk(1, "\n");
4859 /* QAM Equalizer Setup */
4860 /* Equalizer */
4861 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 6564);
4862 if (status < 0)
4863 goto error;
4864 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 6598);
4865 if (status < 0)
4866 goto error;
4867 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 6394);
4868 if (status < 0)
4869 goto error;
4870 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 6409);
4871 if (status < 0)
4872 goto error;
4873 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 6656);
4874 if (status < 0)
4875 goto error;
4876 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 7238);
4877 if (status < 0)
4878 goto error;
4879
4880 /* Decision Feedback Equalizer */
4881 status = write16(state, QAM_DQ_QUAL_FUN0__A, 6);
4882 if (status < 0)
4883 goto error;
4884 status = write16(state, QAM_DQ_QUAL_FUN1__A, 6);
4885 if (status < 0)
4886 goto error;
4887 status = write16(state, QAM_DQ_QUAL_FUN2__A, 6);
4888 if (status < 0)
4889 goto error;
4890 status = write16(state, QAM_DQ_QUAL_FUN3__A, 6);
4891 if (status < 0)
4892 goto error;
4893 status = write16(state, QAM_DQ_QUAL_FUN4__A, 5);
4894 if (status < 0)
4895 goto error;
4896 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
4897 if (status < 0)
4898 goto error;
4899
4900 status = write16(state, QAM_SY_SYNC_HWM__A, 6);
4901 if (status < 0)
4902 goto error;
4903 status = write16(state, QAM_SY_SYNC_AWM__A, 5);
4904 if (status < 0)
4905 goto error;
4906 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
4907 if (status < 0)
4908 goto error;
4909
4910
4911 /* QAM Slicer Settings */
4912
4913 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM128);
4914 if (status < 0)
4915 goto error;
4916
4917
4918 /* QAM Loop Controller Coeficients */
4919
4920 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
4921 if (status < 0)
4922 goto error;
4923 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
4924 if (status < 0)
4925 goto error;
4926 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
4927 if (status < 0)
4928 goto error;
4929 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
4930 if (status < 0)
4931 goto error;
4932 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
4933 if (status < 0)
4934 goto error;
4935 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
4936 if (status < 0)
4937 goto error;
4938 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
4939 if (status < 0)
4940 goto error;
4941 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
4942 if (status < 0)
4943 goto error;
4944
4945 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
4946 if (status < 0)
4947 goto error;
4948 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 40);
4949 if (status < 0)
4950 goto error;
4951 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 120);
4952 if (status < 0)
4953 goto error;
4954 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
4955 if (status < 0)
4956 goto error;
4957 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 40);
4958 if (status < 0)
4959 goto error;
4960 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 60);
4961 if (status < 0)
4962 goto error;
4963 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
4964 if (status < 0)
4965 goto error;
4966 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
4967 if (status < 0)
4968 goto error;
4969 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 64);
4970 if (status < 0)
4971 goto error;
4972 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
4973 if (status < 0)
4974 goto error;
4975 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
4976 if (status < 0)
4977 goto error;
4978 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 0);
4979 if (status < 0)
4980 goto error;
4981
4982
4983 /* QAM State Machine (FSM) Thresholds */
4984
4985 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
4986 if (status < 0)
4987 goto error;
4988 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
4989 if (status < 0)
4990 goto error;
4991 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
4992 if (status < 0)
4993 goto error;
4994 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
4995 if (status < 0)
4996 goto error;
4997 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 140);
4998 if (status < 0)
4999 goto error;
5000 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 100);
5001 if (status < 0)
5002 goto error;
5003
5004 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5005 if (status < 0)
5006 goto error;
5007 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 5);
5008 if (status < 0)
5009 goto error;
5010
5011 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5012 if (status < 0)
5013 goto error;
5014
5015 /* QAM FSM Tracking Parameters */
5016
5017 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5018 if (status < 0)
5019 goto error;
5020 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 65);
5021 if (status < 0)
5022 goto error;
5023 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 5);
5024 if (status < 0)
5025 goto error;
5026 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 3);
5027 if (status < 0)
5028 goto error;
5029 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) -1);
5030 if (status < 0)
5031 goto error;
5032 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) -12);
5033 if (status < 0)
5034 goto error;
5035 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -23);
5036error:
5037 if (status < 0)
5038 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5039
5040 return status;
5041}
5042
5043/*============================================================================*/
5044
5045/**
5046* \brief QAM256 specific setup
5047* \param demod: instance of demod.
5048* \return DRXStatus_t.
5049*/
5050static int SetQAM256(struct drxk_state *state)
5051{
5052 int status = 0;
5053
5054 dprintk(1, "\n");
5055 /* QAM Equalizer Setup */
5056 /* Equalizer */
5057 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD0__A, 11502);
5058 if (status < 0)
5059 goto error;
5060 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD1__A, 12084);
5061 if (status < 0)
5062 goto error;
5063 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD2__A, 12543);
5064 if (status < 0)
5065 goto error;
5066 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD3__A, 12931);
5067 if (status < 0)
5068 goto error;
5069 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD4__A, 13629);
5070 if (status < 0)
5071 goto error;
5072 status = write16(state, SCU_RAM_QAM_EQ_CMA_RAD5__A, 15385);
5073 if (status < 0)
5074 goto error;
5075
5076 /* Decision Feedback Equalizer */
5077 status = write16(state, QAM_DQ_QUAL_FUN0__A, 8);
5078 if (status < 0)
5079 goto error;
5080 status = write16(state, QAM_DQ_QUAL_FUN1__A, 8);
5081 if (status < 0)
5082 goto error;
5083 status = write16(state, QAM_DQ_QUAL_FUN2__A, 8);
5084 if (status < 0)
5085 goto error;
5086 status = write16(state, QAM_DQ_QUAL_FUN3__A, 8);
5087 if (status < 0)
5088 goto error;
5089 status = write16(state, QAM_DQ_QUAL_FUN4__A, 6);
5090 if (status < 0)
5091 goto error;
5092 status = write16(state, QAM_DQ_QUAL_FUN5__A, 0);
5093 if (status < 0)
5094 goto error;
5095
5096 status = write16(state, QAM_SY_SYNC_HWM__A, 5);
5097 if (status < 0)
5098 goto error;
5099 status = write16(state, QAM_SY_SYNC_AWM__A, 4);
5100 if (status < 0)
5101 goto error;
5102 status = write16(state, QAM_SY_SYNC_LWM__A, 3);
5103 if (status < 0)
5104 goto error;
5105
5106 /* QAM Slicer Settings */
5107
5108 status = write16(state, SCU_RAM_QAM_SL_SIG_POWER__A, DRXK_QAM_SL_SIG_POWER_QAM256);
5109 if (status < 0)
5110 goto error;
5111
5112
5113 /* QAM Loop Controller Coeficients */
5114
5115 status = write16(state, SCU_RAM_QAM_LC_CA_FINE__A, 15);
5116 if (status < 0)
5117 goto error;
5118 status = write16(state, SCU_RAM_QAM_LC_CA_COARSE__A, 40);
5119 if (status < 0)
5120 goto error;
5121 status = write16(state, SCU_RAM_QAM_LC_EP_FINE__A, 12);
5122 if (status < 0)
5123 goto error;
5124 status = write16(state, SCU_RAM_QAM_LC_EP_MEDIUM__A, 24);
5125 if (status < 0)
5126 goto error;
5127 status = write16(state, SCU_RAM_QAM_LC_EP_COARSE__A, 24);
5128 if (status < 0)
5129 goto error;
5130 status = write16(state, SCU_RAM_QAM_LC_EI_FINE__A, 12);
5131 if (status < 0)
5132 goto error;
5133 status = write16(state, SCU_RAM_QAM_LC_EI_MEDIUM__A, 16);
5134 if (status < 0)
5135 goto error;
5136 status = write16(state, SCU_RAM_QAM_LC_EI_COARSE__A, 16);
5137 if (status < 0)
5138 goto error;
5139
5140 status = write16(state, SCU_RAM_QAM_LC_CP_FINE__A, 5);
5141 if (status < 0)
5142 goto error;
5143 status = write16(state, SCU_RAM_QAM_LC_CP_MEDIUM__A, 50);
5144 if (status < 0)
5145 goto error;
5146 status = write16(state, SCU_RAM_QAM_LC_CP_COARSE__A, 250);
5147 if (status < 0)
5148 goto error;
5149 status = write16(state, SCU_RAM_QAM_LC_CI_FINE__A, 5);
5150 if (status < 0)
5151 goto error;
5152 status = write16(state, SCU_RAM_QAM_LC_CI_MEDIUM__A, 50);
5153 if (status < 0)
5154 goto error;
5155 status = write16(state, SCU_RAM_QAM_LC_CI_COARSE__A, 125);
5156 if (status < 0)
5157 goto error;
5158 status = write16(state, SCU_RAM_QAM_LC_CF_FINE__A, 16);
5159 if (status < 0)
5160 goto error;
5161 status = write16(state, SCU_RAM_QAM_LC_CF_MEDIUM__A, 25);
5162 if (status < 0)
5163 goto error;
5164 status = write16(state, SCU_RAM_QAM_LC_CF_COARSE__A, 48);
5165 if (status < 0)
5166 goto error;
5167 status = write16(state, SCU_RAM_QAM_LC_CF1_FINE__A, 5);
5168 if (status < 0)
5169 goto error;
5170 status = write16(state, SCU_RAM_QAM_LC_CF1_MEDIUM__A, 10);
5171 if (status < 0)
5172 goto error;
5173 status = write16(state, SCU_RAM_QAM_LC_CF1_COARSE__A, 10);
5174 if (status < 0)
5175 goto error;
5176
5177
5178 /* QAM State Machine (FSM) Thresholds */
5179
5180 status = write16(state, SCU_RAM_QAM_FSM_RTH__A, 50);
5181 if (status < 0)
5182 goto error;
5183 status = write16(state, SCU_RAM_QAM_FSM_FTH__A, 60);
5184 if (status < 0)
5185 goto error;
5186 status = write16(state, SCU_RAM_QAM_FSM_CTH__A, 80);
5187 if (status < 0)
5188 goto error;
5189 status = write16(state, SCU_RAM_QAM_FSM_PTH__A, 100);
5190 if (status < 0)
5191 goto error;
5192 status = write16(state, SCU_RAM_QAM_FSM_QTH__A, 150);
5193 if (status < 0)
5194 goto error;
5195 status = write16(state, SCU_RAM_QAM_FSM_MTH__A, 110);
5196 if (status < 0)
5197 goto error;
5198
5199 status = write16(state, SCU_RAM_QAM_FSM_RATE_LIM__A, 40);
5200 if (status < 0)
5201 goto error;
5202 status = write16(state, SCU_RAM_QAM_FSM_COUNT_LIM__A, 4);
5203 if (status < 0)
5204 goto error;
5205 status = write16(state, SCU_RAM_QAM_FSM_FREQ_LIM__A, 12);
5206 if (status < 0)
5207 goto error;
5208
5209
5210 /* QAM FSM Tracking Parameters */
5211
5212 status = write16(state, SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A, (u16) 8);
5213 if (status < 0)
5214 goto error;
5215 status = write16(state, SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A, (u16) 74);
5216 if (status < 0)
5217 goto error;
5218 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A, (u16) 18);
5219 if (status < 0)
5220 goto error;
5221 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A, (u16) 13);
5222 if (status < 0)
5223 goto error;
5224 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A, (u16) 7);
5225 if (status < 0)
5226 goto error;
5227 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A, (u16) 0);
5228 if (status < 0)
5229 goto error;
5230 status = write16(state, SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A, (u16) -8);
5231error:
5232 if (status < 0)
5233 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5234 return status;
5235}
5236
5237
5238/*============================================================================*/
5239/**
5240* \brief Reset QAM block.
5241* \param demod: instance of demod.
5242* \param channel: pointer to channel data.
5243* \return DRXStatus_t.
5244*/
5245static int QAMResetQAM(struct drxk_state *state)
5246{
5247 int status;
5248 u16 cmdResult;
5249
5250 dprintk(1, "\n");
5251 /* Stop QAM comstate->m_exec */
5252 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_STOP);
5253 if (status < 0)
5254 goto error;
5255
5256 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_RESET, 0, NULL, 1, &cmdResult);
5257error:
5258 if (status < 0)
5259 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5260 return status;
5261}
5262
5263/*============================================================================*/
5264
5265/**
5266* \brief Set QAM symbolrate.
5267* \param demod: instance of demod.
5268* \param channel: pointer to channel data.
5269* \return DRXStatus_t.
5270*/
5271static int QAMSetSymbolrate(struct drxk_state *state)
5272{
5273 u32 adcFrequency = 0;
5274 u32 symbFreq = 0;
5275 u32 iqmRcRate = 0;
5276 u16 ratesel = 0;
5277 u32 lcSymbRate = 0;
5278 int status;
5279
5280 dprintk(1, "\n");
5281 /* Select & calculate correct IQM rate */
5282 adcFrequency = (state->m_sysClockFreq * 1000) / 3;
5283 ratesel = 0;
5284 /* printk(KERN_DEBUG "drxk: SR %d\n", state->param.u.qam.symbol_rate); */
5285 if (state->param.u.qam.symbol_rate <= 1188750)
5286 ratesel = 3;
5287 else if (state->param.u.qam.symbol_rate <= 2377500)
5288 ratesel = 2;
5289 else if (state->param.u.qam.symbol_rate <= 4755000)
5290 ratesel = 1;
5291 status = write16(state, IQM_FD_RATESEL__A, ratesel);
5292 if (status < 0)
5293 goto error;
5294
5295 /*
5296 IqmRcRate = ((Fadc / (symbolrate * (4<<ratesel))) - 1) * (1<<23)
5297 */
5298 symbFreq = state->param.u.qam.symbol_rate * (1 << ratesel);
5299 if (symbFreq == 0) {
5300 /* Divide by zero */
5301 status = -EINVAL;
5302 goto error;
5303 }
5304 iqmRcRate = (adcFrequency / symbFreq) * (1 << 21) +
5305 (Frac28a((adcFrequency % symbFreq), symbFreq) >> 7) -
5306 (1 << 23);
5307 status = write32(state, IQM_RC_RATE_OFS_LO__A, iqmRcRate);
5308 if (status < 0)
5309 goto error;
5310 state->m_iqmRcRate = iqmRcRate;
5311 /*
5312 LcSymbFreq = round (.125 * symbolrate / adcFreq * (1<<15))
5313 */
5314 symbFreq = state->param.u.qam.symbol_rate;
5315 if (adcFrequency == 0) {
5316 /* Divide by zero */
5317 status = -EINVAL;
5318 goto error;
5319 }
5320 lcSymbRate = (symbFreq / adcFrequency) * (1 << 12) +
5321 (Frac28a((symbFreq % adcFrequency), adcFrequency) >>
5322 16);
5323 if (lcSymbRate > 511)
5324 lcSymbRate = 511;
5325 status = write16(state, QAM_LC_SYMBOL_FREQ__A, (u16) lcSymbRate);
5326
5327error:
5328 if (status < 0)
5329 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5330 return status;
5331}
5332
5333/*============================================================================*/
5334
5335/**
5336* \brief Get QAM lock status.
5337* \param demod: instance of demod.
5338* \param channel: pointer to channel data.
5339* \return DRXStatus_t.
5340*/
5341
5342static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
5343{
5344 int status;
5345 u16 Result[2] = { 0, 0 };
5346
5347 dprintk(1, "\n");
5348 *pLockStatus = NOT_LOCKED;
5349 status = scu_command(state,
5350 SCU_RAM_COMMAND_STANDARD_QAM |
5351 SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
5352 Result);
5353 if (status < 0)
5354 printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
5355
5356 if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
5357 /* 0x0000 NOT LOCKED */
5358 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_LOCKED) {
5359 /* 0x4000 DEMOD LOCKED */
5360 *pLockStatus = DEMOD_LOCK;
5361 } else if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK) {
5362 /* 0x8000 DEMOD + FEC LOCKED (system lock) */
5363 *pLockStatus = MPEG_LOCK;
5364 } else {
5365 /* 0xC000 NEVER LOCKED */
5366 /* (system will never be able to lock to the signal) */
5367 /* TODO: check this, intermediate & standard specific lock states are not
5368 taken into account here */
5369 *pLockStatus = NEVER_LOCK;
5370 }
5371 return status;
5372}
5373
5374#define QAM_MIRROR__M 0x03
5375#define QAM_MIRROR_NORMAL 0x00
5376#define QAM_MIRRORED 0x01
5377#define QAM_MIRROR_AUTO_ON 0x02
5378#define QAM_LOCKRANGE__M 0x10
5379#define QAM_LOCKRANGE_NORMAL 0x10
5380
5381static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
5382 s32 tunerFreqOffset)
5383{
5384 int status;
5385 u16 setParamParameters[4] = { 0, 0, 0, 0 };
5386 u16 cmdResult;
5387
5388 dprintk(1, "\n");
5389 /*
5390 * STEP 1: reset demodulator
5391 * resets FEC DI and FEC RS
5392 * resets QAM block
5393 * resets SCU variables
5394 */
5395 status = write16(state, FEC_DI_COMM_EXEC__A, FEC_DI_COMM_EXEC_STOP);
5396 if (status < 0)
5397 goto error;
5398 status = write16(state, FEC_RS_COMM_EXEC__A, FEC_RS_COMM_EXEC_STOP);
5399 if (status < 0)
5400 goto error;
5401 status = QAMResetQAM(state);
5402 if (status < 0)
5403 goto error;
5404
5405 /*
5406 * STEP 2: configure demodulator
5407 * -set params; resets IQM,QAM,FEC HW; initializes some
5408 * SCU variables
5409 */
5410 status = QAMSetSymbolrate(state);
5411 if (status < 0)
5412 goto error;
5413
5414 /* Set params */
5415 switch (state->param.u.qam.modulation) {
5416 case QAM_256:
5417 state->m_Constellation = DRX_CONSTELLATION_QAM256;
5418 break;
5419 case QAM_AUTO:
5420 case QAM_64:
5421 state->m_Constellation = DRX_CONSTELLATION_QAM64;
5422 break;
5423 case QAM_16:
5424 state->m_Constellation = DRX_CONSTELLATION_QAM16;
5425 break;
5426 case QAM_32:
5427 state->m_Constellation = DRX_CONSTELLATION_QAM32;
5428 break;
5429 case QAM_128:
5430 state->m_Constellation = DRX_CONSTELLATION_QAM128;
5431 break;
5432 default:
5433 status = -EINVAL;
5434 break;
5435 }
5436 if (status < 0)
5437 goto error;
5438 setParamParameters[0] = state->m_Constellation; /* constellation */
5439 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5440 if (state->m_OperationMode == OM_QAM_ITU_C)
5441 setParamParameters[2] = QAM_TOP_ANNEX_C;
5442 else
5443 setParamParameters[2] = QAM_TOP_ANNEX_A;
5444 setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
5445 /* Env parameters */
5446 /* check for LOCKRANGE Extented */
5447 /* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
5448
5449 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
5450 if (status < 0) {
5451 /* Fall-back to the simpler call */
5452 if (state->m_OperationMode == OM_QAM_ITU_C)
5453 setParamParameters[0] = QAM_TOP_ANNEX_C;
5454 else
5455 setParamParameters[0] = QAM_TOP_ANNEX_A;
5456 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult);
5457 if (status < 0)
5458 goto error;
5459
5460 setParamParameters[0] = state->m_Constellation; /* constellation */
5461 setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
5462 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
5463 }
5464 if (status < 0)
5465 goto error;
5466
5467 /*
5468 * STEP 3: enable the system in a mode where the ADC provides valid
5469 * signal setup constellation independent registers
5470 */
5471#if 0
5472 status = SetFrequency(channel, tunerFreqOffset));
5473 if (status < 0)
5474 goto error;
5475#endif
5476 status = SetFrequencyShifter(state, IntermediateFreqkHz, tunerFreqOffset, true);
5477 if (status < 0)
5478 goto error;
5479
5480 /* Setup BER measurement */
5481 status = SetQAMMeasurement(state, state->m_Constellation, state->param.u. qam.symbol_rate);
5482 if (status < 0)
5483 goto error;
5484
5485 /* Reset default values */
5486 status = write16(state, IQM_CF_SCALE_SH__A, IQM_CF_SCALE_SH__PRE);
5487 if (status < 0)
5488 goto error;
5489 status = write16(state, QAM_SY_TIMEOUT__A, QAM_SY_TIMEOUT__PRE);
5490 if (status < 0)
5491 goto error;
5492
5493 /* Reset default LC values */
5494 status = write16(state, QAM_LC_RATE_LIMIT__A, 3);
5495 if (status < 0)
5496 goto error;
5497 status = write16(state, QAM_LC_LPF_FACTORP__A, 4);
5498 if (status < 0)
5499 goto error;
5500 status = write16(state, QAM_LC_LPF_FACTORI__A, 4);
5501 if (status < 0)
5502 goto error;
5503 status = write16(state, QAM_LC_MODE__A, 7);
5504 if (status < 0)
5505 goto error;
5506
5507 status = write16(state, QAM_LC_QUAL_TAB0__A, 1);
5508 if (status < 0)
5509 goto error;
5510 status = write16(state, QAM_LC_QUAL_TAB1__A, 1);
5511 if (status < 0)
5512 goto error;
5513 status = write16(state, QAM_LC_QUAL_TAB2__A, 1);
5514 if (status < 0)
5515 goto error;
5516 status = write16(state, QAM_LC_QUAL_TAB3__A, 1);
5517 if (status < 0)
5518 goto error;
5519 status = write16(state, QAM_LC_QUAL_TAB4__A, 2);
5520 if (status < 0)
5521 goto error;
5522 status = write16(state, QAM_LC_QUAL_TAB5__A, 2);
5523 if (status < 0)
5524 goto error;
5525 status = write16(state, QAM_LC_QUAL_TAB6__A, 2);
5526 if (status < 0)
5527 goto error;
5528 status = write16(state, QAM_LC_QUAL_TAB8__A, 2);
5529 if (status < 0)
5530 goto error;
5531 status = write16(state, QAM_LC_QUAL_TAB9__A, 2);
5532 if (status < 0)
5533 goto error;
5534 status = write16(state, QAM_LC_QUAL_TAB10__A, 2);
5535 if (status < 0)
5536 goto error;
5537 status = write16(state, QAM_LC_QUAL_TAB12__A, 2);
5538 if (status < 0)
5539 goto error;
5540 status = write16(state, QAM_LC_QUAL_TAB15__A, 3);
5541 if (status < 0)
5542 goto error;
5543 status = write16(state, QAM_LC_QUAL_TAB16__A, 3);
5544 if (status < 0)
5545 goto error;
5546 status = write16(state, QAM_LC_QUAL_TAB20__A, 4);
5547 if (status < 0)
5548 goto error;
5549 status = write16(state, QAM_LC_QUAL_TAB25__A, 4);
5550 if (status < 0)
5551 goto error;
5552
5553 /* Mirroring, QAM-block starting point not inverted */
5554 status = write16(state, QAM_SY_SP_INV__A, QAM_SY_SP_INV_SPECTRUM_INV_DIS);
5555 if (status < 0)
5556 goto error;
5557
5558 /* Halt SCU to enable safe non-atomic accesses */
5559 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5560 if (status < 0)
5561 goto error;
5562
5563 /* STEP 4: constellation specific setup */
5564 switch (state->param.u.qam.modulation) {
5565 case QAM_16:
5566 status = SetQAM16(state);
5567 break;
5568 case QAM_32:
5569 status = SetQAM32(state);
5570 break;
5571 case QAM_AUTO:
5572 case QAM_64:
5573 status = SetQAM64(state);
5574 break;
5575 case QAM_128:
5576 status = SetQAM128(state);
5577 break;
5578 case QAM_256:
5579 status = SetQAM256(state);
5580 break;
5581 default:
5582 status = -EINVAL;
5583 break;
5584 }
5585 if (status < 0)
5586 goto error;
5587
5588 /* Activate SCU to enable SCU commands */
5589 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5590 if (status < 0)
5591 goto error;
5592
5593 /* Re-configure MPEG output, requires knowledge of channel bitrate */
5594 /* extAttr->currentChannel.constellation = channel->constellation; */
5595 /* extAttr->currentChannel.symbolrate = channel->symbolrate; */
5596 status = MPEGTSDtoSetup(state, state->m_OperationMode);
5597 if (status < 0)
5598 goto error;
5599
5600 /* Start processes */
5601 status = MPEGTSStart(state);
5602 if (status < 0)
5603 goto error;
5604 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_ACTIVE);
5605 if (status < 0)
5606 goto error;
5607 status = write16(state, QAM_COMM_EXEC__A, QAM_COMM_EXEC_ACTIVE);
5608 if (status < 0)
5609 goto error;
5610 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_ACTIVE);
5611 if (status < 0)
5612 goto error;
5613
5614 /* STEP 5: start QAM demodulator (starts FEC, QAM and IQM HW) */
5615 status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_START, 0, NULL, 1, &cmdResult);
5616 if (status < 0)
5617 goto error;
5618
5619 /* update global DRXK data container */
5620/*? extAttr->qamInterleaveMode = DRXK_QAM_I12_J17; */
5621
5622error:
5623 if (status < 0)
5624 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5625 return status;
5626}
5627
5628static int SetQAMStandard(struct drxk_state *state,
5629 enum OperationMode oMode)
5630{
5631 int status;
5632#ifdef DRXK_QAM_TAPS
5633#define DRXK_QAMA_TAPS_SELECT
5634#include "drxk_filters.h"
5635#undef DRXK_QAMA_TAPS_SELECT
5636#endif
5637
5638 dprintk(1, "\n");
5639
5640 /* added antenna switch */
5641 SwitchAntennaToQAM(state);
5642
5643 /* Ensure correct power-up mode */
5644 status = PowerUpQAM(state);
5645 if (status < 0)
5646 goto error;
5647 /* Reset QAM block */
5648 status = QAMResetQAM(state);
5649 if (status < 0)
5650 goto error;
5651
5652 /* Setup IQM */
5653
5654 status = write16(state, IQM_COMM_EXEC__A, IQM_COMM_EXEC_B_STOP);
5655 if (status < 0)
5656 goto error;
5657 status = write16(state, IQM_AF_AMUX__A, IQM_AF_AMUX_SIGNAL2ADC);
5658 if (status < 0)
5659 goto error;
5660
5661 /* Upload IQM Channel Filter settings by
5662 boot loader from ROM table */
5663 switch (oMode) {
5664 case OM_QAM_ITU_A:
5665 status = BLChainCmd(state, DRXK_BL_ROM_OFFSET_TAPS_ITU_A, DRXK_BLCC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5666 break;
5667 case OM_QAM_ITU_C:
5668 status = BLDirectCmd(state, IQM_CF_TAP_RE0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5669 if (status < 0)
5670 goto error;
5671 status = BLDirectCmd(state, IQM_CF_TAP_IM0__A, DRXK_BL_ROM_OFFSET_TAPS_ITU_C, DRXK_BLDC_NR_ELEMENTS_TAPS, DRXK_BLC_TIMEOUT);
5672 break;
5673 default:
5674 status = -EINVAL;
5675 }
5676 if (status < 0)
5677 goto error;
5678
5679 status = write16(state, IQM_CF_OUT_ENA__A, (1 << IQM_CF_OUT_ENA_QAM__B));
5680 if (status < 0)
5681 goto error;
5682 status = write16(state, IQM_CF_SYMMETRIC__A, 0);
5683 if (status < 0)
5684 goto error;
5685 status = write16(state, IQM_CF_MIDTAP__A, ((1 << IQM_CF_MIDTAP_RE__B) | (1 << IQM_CF_MIDTAP_IM__B)));
5686 if (status < 0)
5687 goto error;
5688
5689 status = write16(state, IQM_RC_STRETCH__A, 21);
5690 if (status < 0)
5691 goto error;
5692 status = write16(state, IQM_AF_CLP_LEN__A, 0);
5693 if (status < 0)
5694 goto error;
5695 status = write16(state, IQM_AF_CLP_TH__A, 448);
5696 if (status < 0)
5697 goto error;
5698 status = write16(state, IQM_AF_SNS_LEN__A, 0);
5699 if (status < 0)
5700 goto error;
5701 status = write16(state, IQM_CF_POW_MEAS_LEN__A, 0);
5702 if (status < 0)
5703 goto error;
5704
5705 status = write16(state, IQM_FS_ADJ_SEL__A, 1);
5706 if (status < 0)
5707 goto error;
5708 status = write16(state, IQM_RC_ADJ_SEL__A, 1);
5709 if (status < 0)
5710 goto error;
5711 status = write16(state, IQM_CF_ADJ_SEL__A, 1);
5712 if (status < 0)
5713 goto error;
5714 status = write16(state, IQM_AF_UPD_SEL__A, 0);
5715 if (status < 0)
5716 goto error;
5717
5718 /* IQM Impulse Noise Processing Unit */
5719 status = write16(state, IQM_CF_CLP_VAL__A, 500);
5720 if (status < 0)
5721 goto error;
5722 status = write16(state, IQM_CF_DATATH__A, 1000);
5723 if (status < 0)
5724 goto error;
5725 status = write16(state, IQM_CF_BYPASSDET__A, 1);
5726 if (status < 0)
5727 goto error;
5728 status = write16(state, IQM_CF_DET_LCT__A, 0);
5729 if (status < 0)
5730 goto error;
5731 status = write16(state, IQM_CF_WND_LEN__A, 1);
5732 if (status < 0)
5733 goto error;
5734 status = write16(state, IQM_CF_PKDTH__A, 1);
5735 if (status < 0)
5736 goto error;
5737 status = write16(state, IQM_AF_INC_BYPASS__A, 1);
5738 if (status < 0)
5739 goto error;
5740
5741 /* turn on IQMAF. Must be done before setAgc**() */
5742 status = SetIqmAf(state, true);
5743 if (status < 0)
5744 goto error;
5745 status = write16(state, IQM_AF_START_LOCK__A, 0x01);
5746 if (status < 0)
5747 goto error;
5748
5749 /* IQM will not be reset from here, sync ADC and update/init AGC */
5750 status = ADCSynchronization(state);
5751 if (status < 0)
5752 goto error;
5753
5754 /* Set the FSM step period */
5755 status = write16(state, SCU_RAM_QAM_FSM_STEP_PERIOD__A, 2000);
5756 if (status < 0)
5757 goto error;
5758
5759 /* Halt SCU to enable safe non-atomic accesses */
5760 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_HOLD);
5761 if (status < 0)
5762 goto error;
5763
5764 /* No more resets of the IQM, current standard correctly set =>
5765 now AGCs can be configured. */
5766
5767 status = InitAGC(state, true);
5768 if (status < 0)
5769 goto error;
5770 status = SetPreSaw(state, &(state->m_qamPreSawCfg));
5771 if (status < 0)
5772 goto error;
5773
5774 /* Configure AGC's */
5775 status = SetAgcRf(state, &(state->m_qamRfAgcCfg), true);
5776 if (status < 0)
5777 goto error;
5778 status = SetAgcIf(state, &(state->m_qamIfAgcCfg), true);
5779 if (status < 0)
5780 goto error;
5781
5782 /* Activate SCU to enable SCU commands */
5783 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
5784error:
5785 if (status < 0)
5786 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5787 return status;
5788}
5789
5790static int WriteGPIO(struct drxk_state *state)
5791{
5792 int status;
5793 u16 value = 0;
5794
5795 dprintk(1, "\n");
5796 /* stop lock indicator process */
5797 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
5798 if (status < 0)
5799 goto error;
5800
5801 /* Write magic word to enable pdr reg write */
5802 status = write16(state, SIO_TOP_COMM_KEY__A, SIO_TOP_COMM_KEY_KEY);
5803 if (status < 0)
5804 goto error;
5805
5806 if (state->m_hasSAWSW) {
5807 if (state->UIO_mask & 0x0001) { /* UIO-1 */
5808 /* write to io pad configuration register - output mode */
5809 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5810 if (status < 0)
5811 goto error;
5812
5813 /* use corresponding bit in io data output registar */
5814 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5815 if (status < 0)
5816 goto error;
5817 if ((state->m_GPIO & 0x0001) == 0)
5818 value &= 0x7FFF; /* write zero to 15th bit - 1st UIO */
5819 else
5820 value |= 0x8000; /* write one to 15th bit - 1st UIO */
5821 /* write back to io data output register */
5822 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5823 if (status < 0)
5824 goto error;
5825 }
5826 if (state->UIO_mask & 0x0002) { /* UIO-2 */
5827 /* write to io pad configuration register - output mode */
5828 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5829 if (status < 0)
5830 goto error;
5831
5832 /* use corresponding bit in io data output registar */
5833 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5834 if (status < 0)
5835 goto error;
5836 if ((state->m_GPIO & 0x0002) == 0)
5837 value &= 0xBFFF; /* write zero to 14th bit - 2st UIO */
5838 else
5839 value |= 0x4000; /* write one to 14th bit - 2st UIO */
5840 /* write back to io data output register */
5841 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5842 if (status < 0)
5843 goto error;
5844 }
5845 if (state->UIO_mask & 0x0004) { /* UIO-3 */
5846 /* write to io pad configuration register - output mode */
5847 status = write16(state, SIO_PDR_SMA_TX_CFG__A, state->m_GPIOCfg);
5848 if (status < 0)
5849 goto error;
5850
5851 /* use corresponding bit in io data output registar */
5852 status = read16(state, SIO_PDR_UIO_OUT_LO__A, &value);
5853 if (status < 0)
5854 goto error;
5855 if ((state->m_GPIO & 0x0004) == 0)
5856 value &= 0xFFFB; /* write zero to 2nd bit - 3rd UIO */
5857 else
5858 value |= 0x0004; /* write one to 2nd bit - 3rd UIO */
5859 /* write back to io data output register */
5860 status = write16(state, SIO_PDR_UIO_OUT_LO__A, value);
5861 if (status < 0)
5862 goto error;
5863 }
5864 }
5865 /* Write magic word to disable pdr reg write */
5866 status = write16(state, SIO_TOP_COMM_KEY__A, 0x0000);
5867error:
5868 if (status < 0)
5869 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5870 return status;
5871}
5872
5873static int SwitchAntennaToQAM(struct drxk_state *state)
5874{
5875 int status = 0;
5876 bool gpio_state;
5877
5878 dprintk(1, "\n");
5879
5880 if (!state->antenna_gpio)
5881 return 0;
5882
5883 gpio_state = state->m_GPIO & state->antenna_gpio;
5884
5885 if (state->antenna_dvbt ^ gpio_state) {
5886 /* Antenna is on DVB-T mode. Switch */
5887 if (state->antenna_dvbt)
5888 state->m_GPIO &= ~state->antenna_gpio;
5889 else
5890 state->m_GPIO |= state->antenna_gpio;
5891 status = WriteGPIO(state);
5892 }
5893 if (status < 0)
5894 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5895 return status;
5896}
5897
5898static int SwitchAntennaToDVBT(struct drxk_state *state)
5899{
5900 int status = 0;
5901 bool gpio_state;
5902
5903 dprintk(1, "\n");
5904
5905 if (!state->antenna_gpio)
5906 return 0;
5907
5908 gpio_state = state->m_GPIO & state->antenna_gpio;
5909
5910 if (!(state->antenna_dvbt ^ gpio_state)) {
5911 /* Antenna is on DVB-C mode. Switch */
5912 if (state->antenna_dvbt)
5913 state->m_GPIO |= state->antenna_gpio;
5914 else
5915 state->m_GPIO &= ~state->antenna_gpio;
5916 status = WriteGPIO(state);
5917 }
5918 if (status < 0)
5919 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5920 return status;
5921}
5922
5923
5924static int PowerDownDevice(struct drxk_state *state)
5925{
5926 /* Power down to requested mode */
5927 /* Backup some register settings */
5928 /* Set pins with possible pull-ups connected to them in input mode */
5929 /* Analog power down */
5930 /* ADC power down */
5931 /* Power down device */
5932 int status;
5933
5934 dprintk(1, "\n");
5935 if (state->m_bPDownOpenBridge) {
5936 /* Open I2C bridge before power down of DRXK */
5937 status = ConfigureI2CBridge(state, true);
5938 if (status < 0)
5939 goto error;
5940 }
5941 /* driver 0.9.0 */
5942 status = DVBTEnableOFDMTokenRing(state, false);
5943 if (status < 0)
5944 goto error;
5945
5946 status = write16(state, SIO_CC_PWD_MODE__A, SIO_CC_PWD_MODE_LEVEL_CLOCK);
5947 if (status < 0)
5948 goto error;
5949 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
5950 if (status < 0)
5951 goto error;
5952 state->m_HICfgCtrl |= SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ;
5953 status = HI_CfgCommand(state);
5954error:
5955 if (status < 0)
5956 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
5957
5958 return status;
5959}
5960
5961static int load_microcode(struct drxk_state *state, const char *mc_name)
5962{
5963 const struct firmware *fw = NULL;
5964 int err = 0;
5965
5966 dprintk(1, "\n");
5967
5968 err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
5969 if (err < 0) {
5970 printk(KERN_ERR
5971 "drxk: Could not load firmware file %s.\n", mc_name);
5972 printk(KERN_INFO
5973 "drxk: Copy %s to your hotplug directory!\n", mc_name);
5974 return err;
5975 }
5976 err = DownloadMicrocode(state, fw->data, fw->size);
5977 release_firmware(fw);
5978 return err;
5979}
5980
5981static int init_drxk(struct drxk_state *state)
5982{
5983 int status = 0;
5984 enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
5985 u16 driverVersion;
5986
5987 dprintk(1, "\n");
5988 if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
5989 status = PowerUpDevice(state);
5990 if (status < 0)
5991 goto error;
5992 status = DRXX_Open(state);
5993 if (status < 0)
5994 goto error;
5995 /* Soft reset of OFDM-, sys- and osc-clockdomain */
5996 status = write16(state, SIO_CC_SOFT_RST__A, SIO_CC_SOFT_RST_OFDM__M | SIO_CC_SOFT_RST_SYS__M | SIO_CC_SOFT_RST_OSC__M);
5997 if (status < 0)
5998 goto error;
5999 status = write16(state, SIO_CC_UPDATE__A, SIO_CC_UPDATE_KEY);
6000 if (status < 0)
6001 goto error;
6002 /* TODO is this needed, if yes how much delay in worst case scenario */
6003 msleep(1);
6004 state->m_DRXK_A3_PATCH_CODE = true;
6005 status = GetDeviceCapabilities(state);
6006 if (status < 0)
6007 goto error;
6008
6009 /* Bridge delay, uses oscilator clock */
6010 /* Delay = (delay (nano seconds) * oscclk (kHz))/ 1000 */
6011 /* SDA brdige delay */
6012 state->m_HICfgBridgeDelay =
6013 (u16) ((state->m_oscClockFreq / 1000) *
6014 HI_I2C_BRIDGE_DELAY) / 1000;
6015 /* Clipping */
6016 if (state->m_HICfgBridgeDelay >
6017 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M) {
6018 state->m_HICfgBridgeDelay =
6019 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M;
6020 }
6021 /* SCL bridge delay, same as SDA for now */
6022 state->m_HICfgBridgeDelay +=
6023 state->m_HICfgBridgeDelay <<
6024 SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B;
6025
6026 status = InitHI(state);
6027 if (status < 0)
6028 goto error;
6029 /* disable various processes */
6030#if NOA1ROM
6031 if (!(state->m_DRXK_A1_ROM_CODE)
6032 && !(state->m_DRXK_A2_ROM_CODE))
6033#endif
6034 {
6035 status = write16(state, SCU_RAM_GPIO__A, SCU_RAM_GPIO_HW_LOCK_IND_DISABLE);
6036 if (status < 0)
6037 goto error;
6038 }
6039
6040 /* disable MPEG port */
6041 status = MPEGTSDisable(state);
6042 if (status < 0)
6043 goto error;
6044
6045 /* Stop AUD and SCU */
6046 status = write16(state, AUD_COMM_EXEC__A, AUD_COMM_EXEC_STOP);
6047 if (status < 0)
6048 goto error;
6049 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_STOP);
6050 if (status < 0)
6051 goto error;
6052
6053 /* enable token-ring bus through OFDM block for possible ucode upload */
6054 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_ON);
6055 if (status < 0)
6056 goto error;
6057
6058 /* include boot loader section */
6059 status = write16(state, SIO_BL_COMM_EXEC__A, SIO_BL_COMM_EXEC_ACTIVE);
6060 if (status < 0)
6061 goto error;
6062 status = BLChainCmd(state, 0, 6, 100);
6063 if (status < 0)
6064 goto error;
6065
6066 if (!state->microcode_name)
6067 load_microcode(state, "drxk_a3.mc");
6068 else
6069 load_microcode(state, state->microcode_name);
6070
6071 /* disable token-ring bus through OFDM block for possible ucode upload */
6072 status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
6073 if (status < 0)
6074 goto error;
6075
6076 /* Run SCU for a little while to initialize microcode version numbers */
6077 status = write16(state, SCU_COMM_EXEC__A, SCU_COMM_EXEC_ACTIVE);
6078 if (status < 0)
6079 goto error;
6080 status = DRXX_Open(state);
6081 if (status < 0)
6082 goto error;
6083 /* added for test */
6084 msleep(30);
6085
6086 powerMode = DRXK_POWER_DOWN_OFDM;
6087 status = CtrlPowerMode(state, &powerMode);
6088 if (status < 0)
6089 goto error;
6090
6091 /* Stamp driver version number in SCU data RAM in BCD code
6092 Done to enable field application engineers to retreive drxdriver version
6093 via I2C from SCU RAM.
6094 Not using SCU command interface for SCU register access since no
6095 microcode may be present.
6096 */
6097 driverVersion =
6098 (((DRXK_VERSION_MAJOR / 100) % 10) << 12) +
6099 (((DRXK_VERSION_MAJOR / 10) % 10) << 8) +
6100 ((DRXK_VERSION_MAJOR % 10) << 4) +
6101 (DRXK_VERSION_MINOR % 10);
6102 status = write16(state, SCU_RAM_DRIVER_VER_HI__A, driverVersion);
6103 if (status < 0)
6104 goto error;
6105 driverVersion =
6106 (((DRXK_VERSION_PATCH / 1000) % 10) << 12) +
6107 (((DRXK_VERSION_PATCH / 100) % 10) << 8) +
6108 (((DRXK_VERSION_PATCH / 10) % 10) << 4) +
6109 (DRXK_VERSION_PATCH % 10);
6110 status = write16(state, SCU_RAM_DRIVER_VER_LO__A, driverVersion);
6111 if (status < 0)
6112 goto error;
6113
6114 printk(KERN_INFO "DRXK driver version %d.%d.%d\n",
6115 DRXK_VERSION_MAJOR, DRXK_VERSION_MINOR,
6116 DRXK_VERSION_PATCH);
6117
6118 /* Dirty fix of default values for ROM/PATCH microcode
6119 Dirty because this fix makes it impossible to setup suitable values
6120 before calling DRX_Open. This solution requires changes to RF AGC speed
6121 to be done via the CTRL function after calling DRX_Open */
6122
6123 /* m_dvbtRfAgcCfg.speed = 3; */
6124
6125 /* Reset driver debug flags to 0 */
6126 status = write16(state, SCU_RAM_DRIVER_DEBUG__A, 0);
6127 if (status < 0)
6128 goto error;
6129 /* driver 0.9.0 */
6130 /* Setup FEC OC:
6131 NOTE: No more full FEC resets allowed afterwards!! */
6132 status = write16(state, FEC_COMM_EXEC__A, FEC_COMM_EXEC_STOP);
6133 if (status < 0)
6134 goto error;
6135 /* MPEGTS functions are still the same */
6136 status = MPEGTSDtoInit(state);
6137 if (status < 0)
6138 goto error;
6139 status = MPEGTSStop(state);
6140 if (status < 0)
6141 goto error;
6142 status = MPEGTSConfigurePolarity(state);
6143 if (status < 0)
6144 goto error;
6145 status = MPEGTSConfigurePins(state, state->m_enableMPEGOutput);
6146 if (status < 0)
6147 goto error;
6148 /* added: configure GPIO */
6149 status = WriteGPIO(state);
6150 if (status < 0)
6151 goto error;
6152
6153 state->m_DrxkState = DRXK_STOPPED;
6154
6155 if (state->m_bPowerDown) {
6156 status = PowerDownDevice(state);
6157 if (status < 0)
6158 goto error;
6159 state->m_DrxkState = DRXK_POWERED_DOWN;
6160 } else
6161 state->m_DrxkState = DRXK_STOPPED;
6162 }
6163error:
6164 if (status < 0)
6165 printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
6166
6167 return status;
6168}
6169
6170static void drxk_c_release(struct dvb_frontend *fe)
6171{
6172 struct drxk_state *state = fe->demodulator_priv;
6173
6174 dprintk(1, "\n");
6175 kfree(state);
6176}
6177
6178static int drxk_c_init(struct dvb_frontend *fe)
6179{
6180 struct drxk_state *state = fe->demodulator_priv;
6181
6182 dprintk(1, "\n");
6183 if (mutex_trylock(&state->ctlock) == 0)
6184 return -EBUSY;
6185 SetOperationMode(state, OM_QAM_ITU_A);
6186 return 0;
6187}
6188
6189static int drxk_c_sleep(struct dvb_frontend *fe)
6190{
6191 struct drxk_state *state = fe->demodulator_priv;
6192
6193 dprintk(1, "\n");
6194 ShutDown(state);
6195 mutex_unlock(&state->ctlock);
6196 return 0;
6197}
6198
6199static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
6200{
6201 struct drxk_state *state = fe->demodulator_priv;
6202
6203 dprintk(1, "%s\n", enable ? "enable" : "disable");
6204 return ConfigureI2CBridge(state, enable ? true : false);
6205}
6206
6207static int drxk_set_parameters(struct dvb_frontend *fe,
6208 struct dvb_frontend_parameters *p)
6209{
6210 struct drxk_state *state = fe->demodulator_priv;
6211 u32 IF;
6212
6213 dprintk(1, "\n");
6214 if (fe->ops.i2c_gate_ctrl)
6215 fe->ops.i2c_gate_ctrl(fe, 1);
6216 if (fe->ops.tuner_ops.set_params)
6217 fe->ops.tuner_ops.set_params(fe, p);
6218 if (fe->ops.i2c_gate_ctrl)
6219 fe->ops.i2c_gate_ctrl(fe, 0);
6220 state->param = *p;
6221 fe->ops.tuner_ops.get_frequency(fe, &IF);
6222 Start(state, 0, IF);
6223
6224 /* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
6225
6226 return 0;
6227}
6228
6229static int drxk_c_get_frontend(struct dvb_frontend *fe,
6230 struct dvb_frontend_parameters *p)
6231{
6232 dprintk(1, "\n");
6233 return 0;
6234}
6235
6236static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
6237{
6238 struct drxk_state *state = fe->demodulator_priv;
6239 u32 stat;
6240
6241 dprintk(1, "\n");
6242 *status = 0;
6243 GetLockStatus(state, &stat, 0);
6244 if (stat == MPEG_LOCK)
6245 *status |= 0x1f;
6246 if (stat == FEC_LOCK)
6247 *status |= 0x0f;
6248 if (stat == DEMOD_LOCK)
6249 *status |= 0x07;
6250 return 0;
6251}
6252
6253static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
6254{
6255 dprintk(1, "\n");
6256
6257 *ber = 0;
6258 return 0;
6259}
6260
6261static int drxk_read_signal_strength(struct dvb_frontend *fe,
6262 u16 *strength)
6263{
6264 struct drxk_state *state = fe->demodulator_priv;
6265 u32 val = 0;
6266
6267 dprintk(1, "\n");
6268 ReadIFAgc(state, &val);
6269 *strength = val & 0xffff;
6270 return 0;
6271}
6272
6273static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
6274{
6275 struct drxk_state *state = fe->demodulator_priv;
6276 s32 snr2;
6277
6278 dprintk(1, "\n");
6279 GetSignalToNoise(state, &snr2);
6280 *snr = snr2 & 0xffff;
6281 return 0;
6282}
6283
6284static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
6285{
6286 struct drxk_state *state = fe->demodulator_priv;
6287 u16 err;
6288
6289 dprintk(1, "\n");
6290 DVBTQAMGetAccPktErr(state, &err);
6291 *ucblocks = (u32) err;
6292 return 0;
6293}
6294
6295static int drxk_c_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
6296 *sets)
6297{
6298 dprintk(1, "\n");
6299 sets->min_delay_ms = 3000;
6300 sets->max_drift = 0;
6301 sets->step_size = 0;
6302 return 0;
6303}
6304
6305static void drxk_t_release(struct dvb_frontend *fe)
6306{
6307 /*
6308 * There's nothing to release here, as the state struct
6309 * is already freed by drxk_c_release.
6310 */
6311}
6312
6313static int drxk_t_init(struct dvb_frontend *fe)
6314{
6315 struct drxk_state *state = fe->demodulator_priv;
6316
6317 dprintk(1, "\n");
6318 if (mutex_trylock(&state->ctlock) == 0)
6319 return -EBUSY;
6320 SetOperationMode(state, OM_DVBT);
6321 return 0;
6322}
6323
6324static int drxk_t_sleep(struct dvb_frontend *fe)
6325{
6326 struct drxk_state *state = fe->demodulator_priv;
6327
6328 dprintk(1, "\n");
6329 mutex_unlock(&state->ctlock);
6330 return 0;
6331}
6332
6333static int drxk_t_get_frontend(struct dvb_frontend *fe,
6334 struct dvb_frontend_parameters *p)
6335{
6336 dprintk(1, "\n");
6337
6338 return 0;
6339}
6340
6341static struct dvb_frontend_ops drxk_c_ops = {
6342 .info = {
6343 .name = "DRXK DVB-C",
6344 .type = FE_QAM,
6345 .frequency_stepsize = 62500,
6346 .frequency_min = 47000000,
6347 .frequency_max = 862000000,
6348 .symbol_rate_min = 870000,
6349 .symbol_rate_max = 11700000,
6350 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
6351 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
6352 .release = drxk_c_release,
6353 .init = drxk_c_init,
6354 .sleep = drxk_c_sleep,
6355 .i2c_gate_ctrl = drxk_gate_ctrl,
6356
6357 .set_frontend = drxk_set_parameters,
6358 .get_frontend = drxk_c_get_frontend,
6359 .get_tune_settings = drxk_c_get_tune_settings,
6360
6361 .read_status = drxk_read_status,
6362 .read_ber = drxk_read_ber,
6363 .read_signal_strength = drxk_read_signal_strength,
6364 .read_snr = drxk_read_snr,
6365 .read_ucblocks = drxk_read_ucblocks,
6366};
6367
6368static struct dvb_frontend_ops drxk_t_ops = {
6369 .info = {
6370 .name = "DRXK DVB-T",
6371 .type = FE_OFDM,
6372 .frequency_min = 47125000,
6373 .frequency_max = 865000000,
6374 .frequency_stepsize = 166667,
6375 .frequency_tolerance = 0,
6376 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
6377 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
6378 FE_CAN_FEC_AUTO |
6379 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
6380 FE_CAN_QAM_AUTO |
6381 FE_CAN_TRANSMISSION_MODE_AUTO |
6382 FE_CAN_GUARD_INTERVAL_AUTO |
6383 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
6384 .release = drxk_t_release,
6385 .init = drxk_t_init,
6386 .sleep = drxk_t_sleep,
6387 .i2c_gate_ctrl = drxk_gate_ctrl,
6388
6389 .set_frontend = drxk_set_parameters,
6390 .get_frontend = drxk_t_get_frontend,
6391
6392 .read_status = drxk_read_status,
6393 .read_ber = drxk_read_ber,
6394 .read_signal_strength = drxk_read_signal_strength,
6395 .read_snr = drxk_read_snr,
6396 .read_ucblocks = drxk_read_ucblocks,
6397};
6398
6399struct dvb_frontend *drxk_attach(const struct drxk_config *config,
6400 struct i2c_adapter *i2c,
6401 struct dvb_frontend **fe_t)
6402{
6403 struct drxk_state *state = NULL;
6404 u8 adr = config->adr;
6405
6406 dprintk(1, "\n");
6407 state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
6408 if (!state)
6409 return NULL;
6410
6411 state->i2c = i2c;
6412 state->demod_address = adr;
6413 state->single_master = config->single_master;
6414 state->microcode_name = config->microcode_name;
6415 state->no_i2c_bridge = config->no_i2c_bridge;
6416 state->antenna_gpio = config->antenna_gpio;
6417 state->antenna_dvbt = config->antenna_dvbt;
6418
6419 /* NOTE: as more UIO bits will be used, add them to the mask */
6420 state->UIO_mask = config->antenna_gpio;
6421
6422 /* Default gpio to DVB-C */
6423 if (!state->antenna_dvbt && state->antenna_gpio)
6424 state->m_GPIO |= state->antenna_gpio;
6425 else
6426 state->m_GPIO &= ~state->antenna_gpio;
6427
6428 mutex_init(&state->mutex);
6429 mutex_init(&state->ctlock);
6430
6431 memcpy(&state->c_frontend.ops, &drxk_c_ops,
6432 sizeof(struct dvb_frontend_ops));
6433 memcpy(&state->t_frontend.ops, &drxk_t_ops,
6434 sizeof(struct dvb_frontend_ops));
6435 state->c_frontend.demodulator_priv = state;
6436 state->t_frontend.demodulator_priv = state;
6437
6438 init_state(state);
6439 if (init_drxk(state) < 0)
6440 goto error;
6441 *fe_t = &state->t_frontend;
6442
6443 return &state->c_frontend;
6444
6445error:
6446 printk(KERN_ERR "drxk: not found\n");
6447 kfree(state);
6448 return NULL;
6449}
6450EXPORT_SYMBOL(drxk_attach);
6451
6452MODULE_DESCRIPTION("DRX-K driver");
6453MODULE_AUTHOR("Ralph Metzler");
6454MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/drxk_hard.h b/drivers/media/dvb/frontends/drxk_hard.h
new file mode 100644
index 00000000000..a05c32eecdc
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxk_hard.h
@@ -0,0 +1,348 @@
1#include "drxk_map.h"
2
3#define DRXK_VERSION_MAJOR 0
4#define DRXK_VERSION_MINOR 9
5#define DRXK_VERSION_PATCH 4300
6
7#define HI_I2C_DELAY 42
8#define HI_I2C_BRIDGE_DELAY 350
9#define DRXK_MAX_RETRIES 100
10
11#define DRIVER_4400 1
12
13#define DRXX_JTAGID 0x039210D9
14#define DRXX_J_JTAGID 0x239310D9
15#define DRXX_K_JTAGID 0x039210D9
16
17#define DRX_UNKNOWN 254
18#define DRX_AUTO 255
19
20#define DRX_SCU_READY 0
21#define DRXK_MAX_WAITTIME (200)
22#define SCU_RESULT_OK 0
23#define SCU_RESULT_SIZE -4
24#define SCU_RESULT_INVPAR -3
25#define SCU_RESULT_UNKSTD -2
26#define SCU_RESULT_UNKCMD -1
27
28#ifndef DRXK_OFDM_TR_SHUTDOWN_TIMEOUT
29#define DRXK_OFDM_TR_SHUTDOWN_TIMEOUT (200)
30#endif
31
32#define DRXK_8VSB_MPEG_BIT_RATE 19392658UL /*bps*/
33#define DRXK_DVBT_MPEG_BIT_RATE 32000000UL /*bps*/
34#define DRXK_QAM16_MPEG_BIT_RATE 27000000UL /*bps*/
35#define DRXK_QAM32_MPEG_BIT_RATE 33000000UL /*bps*/
36#define DRXK_QAM64_MPEG_BIT_RATE 40000000UL /*bps*/
37#define DRXK_QAM128_MPEG_BIT_RATE 46000000UL /*bps*/
38#define DRXK_QAM256_MPEG_BIT_RATE 52000000UL /*bps*/
39#define DRXK_MAX_MPEG_BIT_RATE 52000000UL /*bps*/
40
41#define IQM_CF_OUT_ENA_OFDM__M 0x4
42#define IQM_FS_ADJ_SEL_B_QAM 0x1
43#define IQM_FS_ADJ_SEL_B_OFF 0x0
44#define IQM_FS_ADJ_SEL_B_VSB 0x2
45#define IQM_RC_ADJ_SEL_B_OFF 0x0
46#define IQM_RC_ADJ_SEL_B_QAM 0x1
47#define IQM_RC_ADJ_SEL_B_VSB 0x2
48
49enum OperationMode {
50 OM_NONE,
51 OM_QAM_ITU_A,
52 OM_QAM_ITU_B,
53 OM_QAM_ITU_C,
54 OM_DVBT
55};
56
57enum DRXPowerMode {
58 DRX_POWER_UP = 0,
59 DRX_POWER_MODE_1,
60 DRX_POWER_MODE_2,
61 DRX_POWER_MODE_3,
62 DRX_POWER_MODE_4,
63 DRX_POWER_MODE_5,
64 DRX_POWER_MODE_6,
65 DRX_POWER_MODE_7,
66 DRX_POWER_MODE_8,
67
68 DRX_POWER_MODE_9,
69 DRX_POWER_MODE_10,
70 DRX_POWER_MODE_11,
71 DRX_POWER_MODE_12,
72 DRX_POWER_MODE_13,
73 DRX_POWER_MODE_14,
74 DRX_POWER_MODE_15,
75 DRX_POWER_MODE_16,
76 DRX_POWER_DOWN = 255
77};
78
79
80/** /brief Intermediate power mode for DRXK, power down OFDM clock domain */
81#ifndef DRXK_POWER_DOWN_OFDM
82#define DRXK_POWER_DOWN_OFDM DRX_POWER_MODE_1
83#endif
84
85/** /brief Intermediate power mode for DRXK, power down core (sysclk) */
86#ifndef DRXK_POWER_DOWN_CORE
87#define DRXK_POWER_DOWN_CORE DRX_POWER_MODE_9
88#endif
89
90/** /brief Intermediate power mode for DRXK, power down pll (only osc runs) */
91#ifndef DRXK_POWER_DOWN_PLL
92#define DRXK_POWER_DOWN_PLL DRX_POWER_MODE_10
93#endif
94
95
96enum AGC_CTRL_MODE { DRXK_AGC_CTRL_AUTO = 0, DRXK_AGC_CTRL_USER, DRXK_AGC_CTRL_OFF };
97enum EDrxkState { DRXK_UNINITIALIZED = 0, DRXK_STOPPED, DRXK_DTV_STARTED, DRXK_ATV_STARTED, DRXK_POWERED_DOWN };
98enum EDrxkCoefArrayIndex {
99 DRXK_COEF_IDX_MN = 0,
100 DRXK_COEF_IDX_FM ,
101 DRXK_COEF_IDX_L ,
102 DRXK_COEF_IDX_LP ,
103 DRXK_COEF_IDX_BG ,
104 DRXK_COEF_IDX_DK ,
105 DRXK_COEF_IDX_I ,
106 DRXK_COEF_IDX_MAX
107};
108enum EDrxkSifAttenuation {
109 DRXK_SIF_ATTENUATION_0DB,
110 DRXK_SIF_ATTENUATION_3DB,
111 DRXK_SIF_ATTENUATION_6DB,
112 DRXK_SIF_ATTENUATION_9DB
113};
114enum EDrxkConstellation {
115 DRX_CONSTELLATION_BPSK = 0,
116 DRX_CONSTELLATION_QPSK,
117 DRX_CONSTELLATION_PSK8,
118 DRX_CONSTELLATION_QAM16,
119 DRX_CONSTELLATION_QAM32,
120 DRX_CONSTELLATION_QAM64,
121 DRX_CONSTELLATION_QAM128,
122 DRX_CONSTELLATION_QAM256,
123 DRX_CONSTELLATION_QAM512,
124 DRX_CONSTELLATION_QAM1024,
125 DRX_CONSTELLATION_UNKNOWN = DRX_UNKNOWN,
126 DRX_CONSTELLATION_AUTO = DRX_AUTO
127};
128enum EDrxkInterleaveMode {
129 DRXK_QAM_I12_J17 = 16,
130 DRXK_QAM_I_UNKNOWN = DRX_UNKNOWN
131};
132enum {
133 DRXK_SPIN_A1 = 0,
134 DRXK_SPIN_A2,
135 DRXK_SPIN_A3,
136 DRXK_SPIN_UNKNOWN
137};
138
139enum DRXKCfgDvbtSqiSpeed {
140 DRXK_DVBT_SQI_SPEED_FAST = 0,
141 DRXK_DVBT_SQI_SPEED_MEDIUM,
142 DRXK_DVBT_SQI_SPEED_SLOW,
143 DRXK_DVBT_SQI_SPEED_UNKNOWN = DRX_UNKNOWN
144} ;
145
146enum DRXFftmode_t {
147 DRX_FFTMODE_2K = 0,
148 DRX_FFTMODE_4K,
149 DRX_FFTMODE_8K,
150 DRX_FFTMODE_UNKNOWN = DRX_UNKNOWN,
151 DRX_FFTMODE_AUTO = DRX_AUTO
152};
153
154enum DRXMPEGStrWidth_t {
155 DRX_MPEG_STR_WIDTH_1,
156 DRX_MPEG_STR_WIDTH_8
157};
158
159enum DRXQamLockRange_t {
160 DRX_QAM_LOCKRANGE_NORMAL,
161 DRX_QAM_LOCKRANGE_EXTENDED
162};
163
164struct DRXKCfgDvbtEchoThres_t {
165 u16 threshold;
166 enum DRXFftmode_t fftMode;
167} ;
168
169struct SCfgAgc {
170 enum AGC_CTRL_MODE ctrlMode; /* off, user, auto */
171 u16 outputLevel; /* range dependent on AGC */
172 u16 minOutputLevel; /* range dependent on AGC */
173 u16 maxOutputLevel; /* range dependent on AGC */
174 u16 speed; /* range dependent on AGC */
175 u16 top; /* rf-agc take over point */
176 u16 cutOffCurrent; /* rf-agc is accelerated if output current
177 is below cut-off current */
178 u16 IngainTgtMax;
179 u16 FastClipCtrlDelay;
180};
181
182struct SCfgPreSaw {
183 u16 reference; /* pre SAW reference value, range 0 .. 31 */
184 bool usePreSaw; /* TRUE algorithms must use pre SAW sense */
185};
186
187struct DRXKOfdmScCmd_t {
188 u16 cmd; /**< Command number */
189 u16 subcmd; /**< Sub-command parameter*/
190 u16 param0; /**< General purpous param */
191 u16 param1; /**< General purpous param */
192 u16 param2; /**< General purpous param */
193 u16 param3; /**< General purpous param */
194 u16 param4; /**< General purpous param */
195};
196
197struct drxk_state {
198 struct dvb_frontend c_frontend;
199 struct dvb_frontend t_frontend;
200 struct dvb_frontend_parameters param;
201 struct device *dev;
202
203 struct i2c_adapter *i2c;
204 u8 demod_address;
205 void *priv;
206
207 struct mutex mutex;
208 struct mutex ctlock;
209
210 u32 m_Instance; /**< Channel 1,2,3 or 4 */
211
212 int m_ChunkSize;
213 u8 Chunk[256];
214
215 bool m_hasLNA;
216 bool m_hasDVBT;
217 bool m_hasDVBC;
218 bool m_hasAudio;
219 bool m_hasATV;
220 bool m_hasOOB;
221 bool m_hasSAWSW; /**< TRUE if mat_tx is available */
222 bool m_hasGPIO1; /**< TRUE if mat_rx is available */
223 bool m_hasGPIO2; /**< TRUE if GPIO is available */
224 bool m_hasIRQN; /**< TRUE if IRQN is available */
225 u16 m_oscClockFreq;
226 u16 m_HICfgTimingDiv;
227 u16 m_HICfgBridgeDelay;
228 u16 m_HICfgWakeUpKey;
229 u16 m_HICfgTimeout;
230 u16 m_HICfgCtrl;
231 s32 m_sysClockFreq; /**< system clock frequency in kHz */
232
233 enum EDrxkState m_DrxkState; /**< State of Drxk (init,stopped,started) */
234 enum OperationMode m_OperationMode; /**< digital standards */
235 struct SCfgAgc m_vsbRfAgcCfg; /**< settings for VSB RF-AGC */
236 struct SCfgAgc m_vsbIfAgcCfg; /**< settings for VSB IF-AGC */
237 u16 m_vsbPgaCfg; /**< settings for VSB PGA */
238 struct SCfgPreSaw m_vsbPreSawCfg; /**< settings for pre SAW sense */
239 s32 m_Quality83percent; /**< MER level (*0.1 dB) for 83% quality indication */
240 s32 m_Quality93percent; /**< MER level (*0.1 dB) for 93% quality indication */
241 bool m_smartAntInverted;
242 bool m_bDebugEnableBridge;
243 bool m_bPDownOpenBridge; /**< only open DRXK bridge before power-down once it has been accessed */
244 bool m_bPowerDown; /**< Power down when not used */
245
246 u32 m_IqmFsRateOfs; /**< frequency shift as written to DRXK register (28bit fixpoint) */
247
248 bool m_enableMPEGOutput; /**< If TRUE, enable MPEG output */
249 bool m_insertRSByte; /**< If TRUE, insert RS byte */
250 bool m_enableParallel; /**< If TRUE, parallel out otherwise serial */
251 bool m_invertDATA; /**< If TRUE, invert DATA signals */
252 bool m_invertERR; /**< If TRUE, invert ERR signal */
253 bool m_invertSTR; /**< If TRUE, invert STR signals */
254 bool m_invertVAL; /**< If TRUE, invert VAL signals */
255 bool m_invertCLK; /**< If TRUE, invert CLK signals */
256 bool m_DVBCStaticCLK;
257 bool m_DVBTStaticCLK; /**< If TRUE, static MPEG clockrate will
258 be used, otherwise clockrate will
259 adapt to the bitrate of the TS */
260 u32 m_DVBTBitrate;
261 u32 m_DVBCBitrate;
262
263 u8 m_TSDataStrength;
264 u8 m_TSClockkStrength;
265
266 enum DRXMPEGStrWidth_t m_widthSTR; /**< MPEG start width */
267 u32 m_mpegTsStaticBitrate; /**< Maximum bitrate in b/s in case
268 static clockrate is selected */
269
270 /* LARGE_INTEGER m_StartTime; */ /**< Contains the time of the last demod start */
271 s32 m_MpegLockTimeOut; /**< WaitForLockStatus Timeout (counts from start time) */
272 s32 m_DemodLockTimeOut; /**< WaitForLockStatus Timeout (counts from start time) */
273
274 bool m_disableTEIhandling;
275
276 bool m_RfAgcPol;
277 bool m_IfAgcPol;
278
279 struct SCfgAgc m_atvRfAgcCfg; /**< settings for ATV RF-AGC */
280 struct SCfgAgc m_atvIfAgcCfg; /**< settings for ATV IF-AGC */
281 struct SCfgPreSaw m_atvPreSawCfg; /**< settings for ATV pre SAW sense */
282 bool m_phaseCorrectionBypass;
283 s16 m_atvTopVidPeak;
284 u16 m_atvTopNoiseTh;
285 enum EDrxkSifAttenuation m_sifAttenuation;
286 bool m_enableCVBSOutput;
287 bool m_enableSIFOutput;
288 bool m_bMirrorFreqSpect;
289 enum EDrxkConstellation m_Constellation; /**< Constellation type of the channel */
290 u32 m_CurrSymbolRate; /**< Current QAM symbol rate */
291 struct SCfgAgc m_qamRfAgcCfg; /**< settings for QAM RF-AGC */
292 struct SCfgAgc m_qamIfAgcCfg; /**< settings for QAM IF-AGC */
293 u16 m_qamPgaCfg; /**< settings for QAM PGA */
294 struct SCfgPreSaw m_qamPreSawCfg; /**< settings for QAM pre SAW sense */
295 enum EDrxkInterleaveMode m_qamInterleaveMode; /**< QAM Interleave mode */
296 u16 m_fecRsPlen;
297 u16 m_fecRsPrescale;
298
299 enum DRXKCfgDvbtSqiSpeed m_sqiSpeed;
300
301 u16 m_GPIO;
302 u16 m_GPIOCfg;
303
304 struct SCfgAgc m_dvbtRfAgcCfg; /**< settings for QAM RF-AGC */
305 struct SCfgAgc m_dvbtIfAgcCfg; /**< settings for QAM IF-AGC */
306 struct SCfgPreSaw m_dvbtPreSawCfg; /**< settings for QAM pre SAW sense */
307
308 u16 m_agcFastClipCtrlDelay;
309 bool m_adcCompPassed;
310 u16 m_adcCompCoef[64];
311 u16 m_adcState;
312
313 u8 *m_microcode;
314 int m_microcode_length;
315 bool m_DRXK_A1_PATCH_CODE;
316 bool m_DRXK_A1_ROM_CODE;
317 bool m_DRXK_A2_ROM_CODE;
318 bool m_DRXK_A3_ROM_CODE;
319 bool m_DRXK_A2_PATCH_CODE;
320 bool m_DRXK_A3_PATCH_CODE;
321
322 bool m_rfmirror;
323 u8 m_deviceSpin;
324 u32 m_iqmRcRate;
325
326 enum DRXPowerMode m_currentPowerMode;
327
328 /*
329 * Configurable parameters at the driver. They stores the values found
330 * at struct drxk_config.
331 */
332
333 u16 UIO_mask; /* Bits used by UIO */
334
335 bool single_master;
336 bool no_i2c_bridge;
337 bool antenna_dvbt;
338 u16 antenna_gpio;
339
340 const char *microcode_name;
341};
342
343#define NEVER_LOCK 0
344#define NOT_LOCKED 1
345#define DEMOD_LOCK 2
346#define FEC_LOCK 3
347#define MPEG_LOCK 4
348
diff --git a/drivers/media/dvb/frontends/drxk_map.h b/drivers/media/dvb/frontends/drxk_map.h
new file mode 100644
index 00000000000..9b11a832886
--- /dev/null
+++ b/drivers/media/dvb/frontends/drxk_map.h
@@ -0,0 +1,449 @@
1#define AUD_COMM_EXEC__A 0x1000000
2#define AUD_COMM_EXEC_STOP 0x0
3#define FEC_COMM_EXEC__A 0x1C00000
4#define FEC_COMM_EXEC_STOP 0x0
5#define FEC_COMM_EXEC_ACTIVE 0x1
6#define FEC_DI_COMM_EXEC__A 0x1C20000
7#define FEC_DI_COMM_EXEC_STOP 0x0
8#define FEC_DI_INPUT_CTL__A 0x1C20016
9#define FEC_RS_COMM_EXEC__A 0x1C30000
10#define FEC_RS_COMM_EXEC_STOP 0x0
11#define FEC_RS_MEASUREMENT_PERIOD__A 0x1C30012
12#define FEC_RS_MEASUREMENT_PRESCALE__A 0x1C30013
13#define FEC_OC_MODE__A 0x1C40011
14#define FEC_OC_MODE_PARITY__M 0x1
15#define FEC_OC_DTO_MODE__A 0x1C40014
16#define FEC_OC_DTO_MODE_DYNAMIC__M 0x1
17#define FEC_OC_DTO_MODE_OFFSET_ENABLE__M 0x4
18#define FEC_OC_DTO_PERIOD__A 0x1C40015
19#define FEC_OC_DTO_BURST_LEN__A 0x1C40018
20#define FEC_OC_FCT_MODE__A 0x1C4001A
21#define FEC_OC_FCT_MODE__PRE 0x0
22#define FEC_OC_FCT_MODE_RAT_ENA__M 0x1
23#define FEC_OC_FCT_MODE_VIRT_ENA__M 0x2
24#define FEC_OC_TMD_MODE__A 0x1C4001E
25#define FEC_OC_TMD_COUNT__A 0x1C4001F
26#define FEC_OC_TMD_HI_MARGIN__A 0x1C40020
27#define FEC_OC_TMD_LO_MARGIN__A 0x1C40021
28#define FEC_OC_TMD_INT_UPD_RATE__A 0x1C40023
29#define FEC_OC_AVR_PARM_A__A 0x1C40026
30#define FEC_OC_AVR_PARM_B__A 0x1C40027
31#define FEC_OC_RCN_GAIN__A 0x1C4002E
32#define FEC_OC_RCN_CTL_RATE_LO__A 0x1C40030
33#define FEC_OC_RCN_CTL_STEP_LO__A 0x1C40032
34#define FEC_OC_RCN_CTL_STEP_HI__A 0x1C40033
35#define FEC_OC_SNC_MODE__A 0x1C40040
36#define FEC_OC_SNC_MODE_SHUTDOWN__M 0x10
37#define FEC_OC_SNC_LWM__A 0x1C40041
38#define FEC_OC_SNC_HWM__A 0x1C40042
39#define FEC_OC_SNC_UNLOCK__A 0x1C40043
40#define FEC_OC_SNC_FAIL_PERIOD__A 0x1C40046
41#define FEC_OC_IPR_MODE__A 0x1C40048
42#define FEC_OC_IPR_MODE_SERIAL__M 0x1
43#define FEC_OC_IPR_MODE_MCLK_DIS_DAT_ABS__M 0x4
44#define FEC_OC_IPR_MODE_MVAL_DIS_PAR__M 0x10
45#define FEC_OC_IPR_INVERT__A 0x1C40049
46#define FEC_OC_IPR_INVERT_MD0__M 0x1
47#define FEC_OC_IPR_INVERT_MD1__M 0x2
48#define FEC_OC_IPR_INVERT_MD2__M 0x4
49#define FEC_OC_IPR_INVERT_MD3__M 0x8
50#define FEC_OC_IPR_INVERT_MD4__M 0x10
51#define FEC_OC_IPR_INVERT_MD5__M 0x20
52#define FEC_OC_IPR_INVERT_MD6__M 0x40
53#define FEC_OC_IPR_INVERT_MD7__M 0x80
54#define FEC_OC_IPR_INVERT_MERR__M 0x100
55#define FEC_OC_IPR_INVERT_MSTRT__M 0x200
56#define FEC_OC_IPR_INVERT_MVAL__M 0x400
57#define FEC_OC_IPR_INVERT_MCLK__M 0x800
58#define FEC_OC_OCR_INVERT__A 0x1C40052
59#define IQM_COMM_EXEC__A 0x1800000
60#define IQM_COMM_EXEC_B_STOP 0x0
61#define IQM_COMM_EXEC_B_ACTIVE 0x1
62#define IQM_FS_RATE_OFS_LO__A 0x1820010
63#define IQM_FS_ADJ_SEL__A 0x1820014
64#define IQM_FS_ADJ_SEL_B_OFF 0x0
65#define IQM_FS_ADJ_SEL_B_QAM 0x1
66#define IQM_FS_ADJ_SEL_B_VSB 0x2
67#define IQM_FD_RATESEL__A 0x1830010
68#define IQM_RC_RATE_OFS_LO__A 0x1840010
69#define IQM_RC_RATE_OFS_LO__W 16
70#define IQM_RC_RATE_OFS_LO__M 0xFFFF
71#define IQM_RC_RATE_OFS_HI__M 0xFF
72#define IQM_RC_ADJ_SEL__A 0x1840014
73#define IQM_RC_ADJ_SEL_B_OFF 0x0
74#define IQM_RC_ADJ_SEL_B_QAM 0x1
75#define IQM_RC_ADJ_SEL_B_VSB 0x2
76#define IQM_RC_STRETCH__A 0x1840016
77#define IQM_CF_COMM_INT_MSK__A 0x1860006
78#define IQM_CF_SYMMETRIC__A 0x1860010
79#define IQM_CF_MIDTAP__A 0x1860011
80#define IQM_CF_MIDTAP_RE__B 0
81#define IQM_CF_MIDTAP_IM__B 1
82#define IQM_CF_OUT_ENA__A 0x1860012
83#define IQM_CF_OUT_ENA_QAM__B 1
84#define IQM_CF_OUT_ENA_OFDM__M 0x4
85#define IQM_CF_ADJ_SEL__A 0x1860013
86#define IQM_CF_SCALE__A 0x1860014
87#define IQM_CF_SCALE_SH__A 0x1860015
88#define IQM_CF_SCALE_SH__PRE 0x0
89#define IQM_CF_POW_MEAS_LEN__A 0x1860017
90#define IQM_CF_DS_ENA__A 0x1860019
91#define IQM_CF_TAP_RE0__A 0x1860020
92#define IQM_CF_TAP_IM0__A 0x1860040
93#define IQM_CF_CLP_VAL__A 0x1860060
94#define IQM_CF_DATATH__A 0x1860061
95#define IQM_CF_PKDTH__A 0x1860062
96#define IQM_CF_WND_LEN__A 0x1860063
97#define IQM_CF_DET_LCT__A 0x1860064
98#define IQM_CF_BYPASSDET__A 0x1860067
99#define IQM_AF_COMM_EXEC__A 0x1870000
100#define IQM_AF_COMM_EXEC_ACTIVE 0x1
101#define IQM_AF_CLKNEG__A 0x1870012
102#define IQM_AF_CLKNEG_CLKNEGDATA__M 0x2
103#define IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS 0x0
104#define IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_NEG 0x2
105#define IQM_AF_START_LOCK__A 0x187001B
106#define IQM_AF_PHASE0__A 0x187001C
107#define IQM_AF_PHASE1__A 0x187001D
108#define IQM_AF_PHASE2__A 0x187001E
109#define IQM_AF_CLP_LEN__A 0x1870023
110#define IQM_AF_CLP_TH__A 0x1870024
111#define IQM_AF_SNS_LEN__A 0x1870026
112#define IQM_AF_AGC_IF__A 0x1870028
113#define IQM_AF_AGC_RF__A 0x1870029
114#define IQM_AF_PDREF__A 0x187002B
115#define IQM_AF_PDREF__M 0x1F
116#define IQM_AF_STDBY__A 0x187002C
117#define IQM_AF_STDBY_STDBY_ADC_STANDBY 0x2
118#define IQM_AF_STDBY_STDBY_AMP_STANDBY 0x4
119#define IQM_AF_STDBY_STDBY_PD_STANDBY 0x8
120#define IQM_AF_STDBY_STDBY_TAGC_IF_STANDBY 0x10
121#define IQM_AF_STDBY_STDBY_TAGC_RF_STANDBY 0x20
122#define IQM_AF_AMUX__A 0x187002D
123#define IQM_AF_AMUX_SIGNAL2ADC 0x1
124#define IQM_AF_UPD_SEL__A 0x187002F
125#define IQM_AF_INC_LCT__A 0x1870034
126#define IQM_AF_INC_BYPASS__A 0x1870036
127#define OFDM_CP_COMM_EXEC__A 0x2800000
128#define OFDM_CP_COMM_EXEC_STOP 0x0
129#define OFDM_EC_SB_PRIOR__A 0x3410013
130#define OFDM_EC_SB_PRIOR_HI 0x0
131#define OFDM_EC_SB_PRIOR_LO 0x1
132#define OFDM_EQ_TOP_TD_TPS_CONST__A 0x3010054
133#define OFDM_EQ_TOP_TD_TPS_CONST__M 0x3
134#define OFDM_EQ_TOP_TD_TPS_CONST_64QAM 0x2
135#define OFDM_EQ_TOP_TD_TPS_CODE_HP__A 0x3010056
136#define OFDM_EQ_TOP_TD_TPS_CODE_HP__M 0x7
137#define OFDM_EQ_TOP_TD_TPS_CODE_LP_7_8 0x4
138#define OFDM_EQ_TOP_TD_SQR_ERR_I__A 0x301005E
139#define OFDM_EQ_TOP_TD_SQR_ERR_Q__A 0x301005F
140#define OFDM_EQ_TOP_TD_SQR_ERR_EXP__A 0x3010060
141#define OFDM_EQ_TOP_TD_REQ_SMB_CNT__A 0x3010061
142#define OFDM_EQ_TOP_TD_TPS_PWR_OFS__A 0x3010062
143#define OFDM_LC_COMM_EXEC__A 0x3800000
144#define OFDM_LC_COMM_EXEC_STOP 0x0
145#define OFDM_SC_COMM_EXEC__A 0x3C00000
146#define OFDM_SC_COMM_EXEC_STOP 0x0
147#define OFDM_SC_COMM_STATE__A 0x3C00001
148#define OFDM_SC_RA_RAM_PARAM0__A 0x3C20040
149#define OFDM_SC_RA_RAM_PARAM1__A 0x3C20041
150#define OFDM_SC_RA_RAM_CMD_ADDR__A 0x3C20042
151#define OFDM_SC_RA_RAM_CMD__A 0x3C20043
152#define OFDM_SC_RA_RAM_CMD_NULL 0x0
153#define OFDM_SC_RA_RAM_CMD_PROC_START 0x1
154#define OFDM_SC_RA_RAM_CMD_SET_PREF_PARAM 0x3
155#define OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM 0x4
156#define OFDM_SC_RA_RAM_CMD_GET_OP_PARAM 0x5
157#define OFDM_SC_RA_RAM_CMD_USER_IO 0x6
158#define OFDM_SC_RA_RAM_CMD_SET_TIMER 0x7
159#define OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING 0x8
160#define OFDM_SC_RA_RAM_SW_EVENT_RUN_NMASK__M 0x1
161#define OFDM_SC_RA_RAM_LOCKTRACK_MIN 0x1
162#define OFDM_SC_RA_RAM_OP_PARAM__A 0x3C20048
163#define OFDM_SC_RA_RAM_OP_PARAM_MODE__M 0x3
164#define OFDM_SC_RA_RAM_OP_PARAM_MODE_2K 0x0
165#define OFDM_SC_RA_RAM_OP_PARAM_MODE_8K 0x1
166#define OFDM_SC_RA_RAM_OP_PARAM_GUARD_32 0x0
167#define OFDM_SC_RA_RAM_OP_PARAM_GUARD_16 0x4
168#define OFDM_SC_RA_RAM_OP_PARAM_GUARD_8 0x8
169#define OFDM_SC_RA_RAM_OP_PARAM_GUARD_4 0xC
170#define OFDM_SC_RA_RAM_OP_PARAM_CONST_QPSK 0x0
171#define OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM16 0x10
172#define OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64 0x20
173#define OFDM_SC_RA_RAM_OP_PARAM_HIER_NO 0x0
174#define OFDM_SC_RA_RAM_OP_PARAM_HIER_A1 0x40
175#define OFDM_SC_RA_RAM_OP_PARAM_HIER_A2 0x80
176#define OFDM_SC_RA_RAM_OP_PARAM_HIER_A4 0xC0
177#define OFDM_SC_RA_RAM_OP_PARAM_RATE_1_2 0x0
178#define OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3 0x200
179#define OFDM_SC_RA_RAM_OP_PARAM_RATE_3_4 0x400
180#define OFDM_SC_RA_RAM_OP_PARAM_RATE_5_6 0x600
181#define OFDM_SC_RA_RAM_OP_PARAM_RATE_7_8 0x800
182#define OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI 0x0
183#define OFDM_SC_RA_RAM_OP_PARAM_PRIO_LO 0x1000
184#define OFDM_SC_RA_RAM_OP_AUTO_MODE__M 0x1
185#define OFDM_SC_RA_RAM_OP_AUTO_GUARD__M 0x2
186#define OFDM_SC_RA_RAM_OP_AUTO_CONST__M 0x4
187#define OFDM_SC_RA_RAM_OP_AUTO_HIER__M 0x8
188#define OFDM_SC_RA_RAM_OP_AUTO_RATE__M 0x10
189#define OFDM_SC_RA_RAM_LOCK__A 0x3C2004B
190#define OFDM_SC_RA_RAM_LOCK_DEMOD__M 0x1
191#define OFDM_SC_RA_RAM_LOCK_FEC__M 0x2
192#define OFDM_SC_RA_RAM_LOCK_MPEG__M 0x4
193#define OFDM_SC_RA_RAM_LOCK_NODVBT__M 0x8
194#define OFDM_SC_RA_RAM_BE_OPT_DELAY__A 0x3C2004D
195#define OFDM_SC_RA_RAM_BE_OPT_INIT_DELAY__A 0x3C2004E
196#define OFDM_SC_RA_RAM_ECHO_THRES__A 0x3C2004F
197#define OFDM_SC_RA_RAM_ECHO_THRES_8K__B 0
198#define OFDM_SC_RA_RAM_ECHO_THRES_8K__M 0xFF
199#define OFDM_SC_RA_RAM_ECHO_THRES_2K__B 8
200#define OFDM_SC_RA_RAM_ECHO_THRES_2K__M 0xFF00
201#define OFDM_SC_RA_RAM_CONFIG__A 0x3C20050
202#define OFDM_SC_RA_RAM_CONFIG_NE_FIX_ENABLE__M 0x800
203#define OFDM_SC_RA_RAM_FR_THRES_8K__A 0x3C2007D
204#define OFDM_SC_RA_RAM_NI_INIT_2K_PER_LEFT__A 0x3C200E0
205#define OFDM_SC_RA_RAM_NI_INIT_2K_PER_RIGHT__A 0x3C200E1
206#define OFDM_SC_RA_RAM_NI_INIT_8K_PER_LEFT__A 0x3C200E3
207#define OFDM_SC_RA_RAM_NI_INIT_8K_PER_RIGHT__A 0x3C200E4
208#define OFDM_SC_RA_RAM_SRMM_FIX_FACT_8K__A 0x3C200F8
209#define QAM_COMM_EXEC__A 0x1400000
210#define QAM_COMM_EXEC_STOP 0x0
211#define QAM_COMM_EXEC_ACTIVE 0x1
212#define QAM_TOP_ANNEX_A 0x0
213#define QAM_TOP_ANNEX_C 0x2
214#define QAM_SL_ERR_POWER__A 0x1430017
215#define QAM_DQ_QUAL_FUN0__A 0x1440018
216#define QAM_DQ_QUAL_FUN1__A 0x1440019
217#define QAM_DQ_QUAL_FUN2__A 0x144001A
218#define QAM_DQ_QUAL_FUN3__A 0x144001B
219#define QAM_DQ_QUAL_FUN4__A 0x144001C
220#define QAM_DQ_QUAL_FUN5__A 0x144001D
221#define QAM_LC_MODE__A 0x1450010
222#define QAM_LC_QUAL_TAB0__A 0x1450018
223#define QAM_LC_QUAL_TAB1__A 0x1450019
224#define QAM_LC_QUAL_TAB2__A 0x145001A
225#define QAM_LC_QUAL_TAB3__A 0x145001B
226#define QAM_LC_QUAL_TAB4__A 0x145001C
227#define QAM_LC_QUAL_TAB5__A 0x145001D
228#define QAM_LC_QUAL_TAB6__A 0x145001E
229#define QAM_LC_QUAL_TAB8__A 0x145001F
230#define QAM_LC_QUAL_TAB9__A 0x1450020
231#define QAM_LC_QUAL_TAB10__A 0x1450021
232#define QAM_LC_QUAL_TAB12__A 0x1450022
233#define QAM_LC_QUAL_TAB15__A 0x1450023
234#define QAM_LC_QUAL_TAB16__A 0x1450024
235#define QAM_LC_QUAL_TAB20__A 0x1450025
236#define QAM_LC_QUAL_TAB25__A 0x1450026
237#define QAM_LC_LPF_FACTORP__A 0x1450028
238#define QAM_LC_LPF_FACTORI__A 0x1450029
239#define QAM_LC_RATE_LIMIT__A 0x145002A
240#define QAM_LC_SYMBOL_FREQ__A 0x145002B
241#define QAM_SY_TIMEOUT__A 0x1470011
242#define QAM_SY_TIMEOUT__PRE 0x3A98
243#define QAM_SY_SYNC_LWM__A 0x1470012
244#define QAM_SY_SYNC_AWM__A 0x1470013
245#define QAM_SY_SYNC_HWM__A 0x1470014
246#define QAM_SY_SP_INV__A 0x1470017
247#define QAM_SY_SP_INV_SPECTRUM_INV_DIS 0x0
248#define SCU_COMM_EXEC__A 0x800000
249#define SCU_COMM_EXEC_STOP 0x0
250#define SCU_COMM_EXEC_ACTIVE 0x1
251#define SCU_COMM_EXEC_HOLD 0x2
252#define SCU_RAM_DRIVER_DEBUG__A 0x831EBF
253#define SCU_RAM_QAM_FSM_STEP_PERIOD__A 0x831EC4
254#define SCU_RAM_GPIO__A 0x831EC7
255#define SCU_RAM_GPIO_HW_LOCK_IND_DISABLE 0x0
256#define SCU_RAM_AGC_CLP_CTRL_MODE__A 0x831EC8
257#define SCU_RAM_FEC_ACCUM_PKT_FAILURES__A 0x831ECB
258#define SCU_RAM_FEC_PRE_RS_BER_FILTER_SH__A 0x831F05
259#define SCU_RAM_AGC_FAST_SNS_CTRL_DELAY__A 0x831F15
260#define SCU_RAM_AGC_KI_CYCLEN__A 0x831F17
261#define SCU_RAM_AGC_SNS_CYCLEN__A 0x831F18
262#define SCU_RAM_AGC_RF_SNS_DEV_MAX__A 0x831F19
263#define SCU_RAM_AGC_RF_SNS_DEV_MIN__A 0x831F1A
264#define SCU_RAM_AGC_RF_MAX__A 0x831F1B
265#define SCU_RAM_AGC_CONFIG__A 0x831F24
266#define SCU_RAM_AGC_CONFIG_DISABLE_RF_AGC__M 0x1
267#define SCU_RAM_AGC_CONFIG_DISABLE_IF_AGC__M 0x2
268#define SCU_RAM_AGC_CONFIG_INV_IF_POL__M 0x100
269#define SCU_RAM_AGC_CONFIG_INV_RF_POL__M 0x200
270#define SCU_RAM_AGC_KI__A 0x831F25
271#define SCU_RAM_AGC_KI_RF__B 4
272#define SCU_RAM_AGC_KI_RF__M 0xF0
273#define SCU_RAM_AGC_KI_IF__B 8
274#define SCU_RAM_AGC_KI_IF__M 0xF00
275#define SCU_RAM_AGC_KI_RED__A 0x831F26
276#define SCU_RAM_AGC_KI_RED_RAGC_RED__B 2
277#define SCU_RAM_AGC_KI_RED_RAGC_RED__M 0xC
278#define SCU_RAM_AGC_KI_RED_IAGC_RED__B 4
279#define SCU_RAM_AGC_KI_RED_IAGC_RED__M 0x30
280#define SCU_RAM_AGC_KI_INNERGAIN_MIN__A 0x831F27
281#define SCU_RAM_AGC_KI_MINGAIN__A 0x831F28
282#define SCU_RAM_AGC_KI_MAXGAIN__A 0x831F29
283#define SCU_RAM_AGC_KI_MAXMINGAIN_TH__A 0x831F2A
284#define SCU_RAM_AGC_KI_MIN__A 0x831F2B
285#define SCU_RAM_AGC_KI_MAX__A 0x831F2C
286#define SCU_RAM_AGC_CLP_SUM__A 0x831F2D
287#define SCU_RAM_AGC_CLP_SUM_MIN__A 0x831F2E
288#define SCU_RAM_AGC_CLP_SUM_MAX__A 0x831F2F
289#define SCU_RAM_AGC_CLP_CYCLEN__A 0x831F30
290#define SCU_RAM_AGC_CLP_CYCCNT__A 0x831F31
291#define SCU_RAM_AGC_CLP_DIR_TO__A 0x831F32
292#define SCU_RAM_AGC_CLP_DIR_WD__A 0x831F33
293#define SCU_RAM_AGC_CLP_DIR_STP__A 0x831F34
294#define SCU_RAM_AGC_SNS_SUM__A 0x831F35
295#define SCU_RAM_AGC_SNS_SUM_MIN__A 0x831F36
296#define SCU_RAM_AGC_SNS_SUM_MAX__A 0x831F37
297#define SCU_RAM_AGC_SNS_CYCCNT__A 0x831F38
298#define SCU_RAM_AGC_SNS_DIR_TO__A 0x831F39
299#define SCU_RAM_AGC_SNS_DIR_WD__A 0x831F3A
300#define SCU_RAM_AGC_SNS_DIR_STP__A 0x831F3B
301#define SCU_RAM_AGC_INGAIN_TGT__A 0x831F3D
302#define SCU_RAM_AGC_INGAIN_TGT_MIN__A 0x831F3E
303#define SCU_RAM_AGC_INGAIN_TGT_MAX__A 0x831F3F
304#define SCU_RAM_AGC_IF_IACCU_HI__A 0x831F40
305#define SCU_RAM_AGC_IF_IACCU_LO__A 0x831F41
306#define SCU_RAM_AGC_IF_IACCU_HI_TGT__A 0x831F42
307#define SCU_RAM_AGC_IF_IACCU_HI_TGT_MIN__A 0x831F43
308#define SCU_RAM_AGC_IF_IACCU_HI_TGT_MAX__A 0x831F44
309#define SCU_RAM_AGC_RF_IACCU_HI__A 0x831F45
310#define SCU_RAM_AGC_RF_IACCU_LO__A 0x831F46
311#define SCU_RAM_AGC_RF_IACCU_HI_CO__A 0x831F47
312#define SCU_RAM_QAM_FSM_MEDIAN_AV_MULT__A 0x831F84
313#define SCU_RAM_QAM_FSM_RADIUS_AV_LIMIT__A 0x831F85
314#define SCU_RAM_QAM_FSM_LCAVG_OFFSET1__A 0x831F86
315#define SCU_RAM_QAM_FSM_LCAVG_OFFSET2__A 0x831F87
316#define SCU_RAM_QAM_FSM_LCAVG_OFFSET3__A 0x831F88
317#define SCU_RAM_QAM_FSM_LCAVG_OFFSET4__A 0x831F89
318#define SCU_RAM_QAM_FSM_LCAVG_OFFSET5__A 0x831F8A
319#define SCU_RAM_QAM_FSM_RTH__A 0x831F8E
320#define SCU_RAM_QAM_FSM_FTH__A 0x831F8F
321#define SCU_RAM_QAM_FSM_PTH__A 0x831F90
322#define SCU_RAM_QAM_FSM_MTH__A 0x831F91
323#define SCU_RAM_QAM_FSM_CTH__A 0x831F92
324#define SCU_RAM_QAM_FSM_QTH__A 0x831F93
325#define SCU_RAM_QAM_FSM_RATE_LIM__A 0x831F94
326#define SCU_RAM_QAM_FSM_FREQ_LIM__A 0x831F95
327#define SCU_RAM_QAM_FSM_COUNT_LIM__A 0x831F96
328#define SCU_RAM_QAM_LC_CA_COARSE__A 0x831F97
329#define SCU_RAM_QAM_LC_CA_FINE__A 0x831F99
330#define SCU_RAM_QAM_LC_CP_COARSE__A 0x831F9A
331#define SCU_RAM_QAM_LC_CP_MEDIUM__A 0x831F9B
332#define SCU_RAM_QAM_LC_CP_FINE__A 0x831F9C
333#define SCU_RAM_QAM_LC_CI_COARSE__A 0x831F9D
334#define SCU_RAM_QAM_LC_CI_MEDIUM__A 0x831F9E
335#define SCU_RAM_QAM_LC_CI_FINE__A 0x831F9F
336#define SCU_RAM_QAM_LC_EP_COARSE__A 0x831FA0
337#define SCU_RAM_QAM_LC_EP_MEDIUM__A 0x831FA1
338#define SCU_RAM_QAM_LC_EP_FINE__A 0x831FA2
339#define SCU_RAM_QAM_LC_EI_COARSE__A 0x831FA3
340#define SCU_RAM_QAM_LC_EI_MEDIUM__A 0x831FA4
341#define SCU_RAM_QAM_LC_EI_FINE__A 0x831FA5
342#define SCU_RAM_QAM_LC_CF_COARSE__A 0x831FA6
343#define SCU_RAM_QAM_LC_CF_MEDIUM__A 0x831FA7
344#define SCU_RAM_QAM_LC_CF_FINE__A 0x831FA8
345#define SCU_RAM_QAM_LC_CF1_COARSE__A 0x831FA9
346#define SCU_RAM_QAM_LC_CF1_MEDIUM__A 0x831FAA
347#define SCU_RAM_QAM_LC_CF1_FINE__A 0x831FAB
348#define SCU_RAM_QAM_SL_SIG_POWER__A 0x831FAC
349#define SCU_RAM_QAM_EQ_CMA_RAD0__A 0x831FAD
350#define SCU_RAM_QAM_EQ_CMA_RAD1__A 0x831FAE
351#define SCU_RAM_QAM_EQ_CMA_RAD2__A 0x831FAF
352#define SCU_RAM_QAM_EQ_CMA_RAD3__A 0x831FB0
353#define SCU_RAM_QAM_EQ_CMA_RAD4__A 0x831FB1
354#define SCU_RAM_QAM_EQ_CMA_RAD5__A 0x831FB2
355#define SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED 0x4000
356#define SCU_RAM_QAM_LOCKED_LOCKED_LOCKED 0x8000
357#define SCU_RAM_QAM_LOCKED_LOCKED_NEVER_LOCK 0xC000
358#define SCU_RAM_AGC_FAST_CLP_CTRL_DELAY__A 0x831FEA
359#define SCU_RAM_DRIVER_VER_HI__A 0x831FEB
360#define SCU_RAM_DRIVER_VER_LO__A 0x831FEC
361#define SCU_RAM_PARAM_15__A 0x831FED
362#define SCU_RAM_PARAM_0__A 0x831FFC
363#define SCU_RAM_COMMAND__A 0x831FFD
364#define SCU_RAM_COMMAND_CMD_DEMOD_RESET 0x1
365#define SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV 0x2
366#define SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM 0x3
367#define SCU_RAM_COMMAND_CMD_DEMOD_START 0x4
368#define SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK 0x5
369#define SCU_RAM_COMMAND_CMD_DEMOD_STOP 0x9
370#define SCU_RAM_COMMAND_STANDARD_QAM 0x200
371#define SCU_RAM_COMMAND_STANDARD_OFDM 0x400
372#define SIO_TOP_COMM_KEY__A 0x41000F
373#define SIO_TOP_COMM_KEY_KEY 0xFABA
374#define SIO_TOP_JTAGID_LO__A 0x410012
375#define SIO_HI_RA_RAM_RES__A 0x420031
376#define SIO_HI_RA_RAM_CMD__A 0x420032
377#define SIO_HI_RA_RAM_CMD_RESET 0x2
378#define SIO_HI_RA_RAM_CMD_CONFIG 0x3
379#define SIO_HI_RA_RAM_CMD_BRDCTRL 0x7
380#define SIO_HI_RA_RAM_PAR_1__A 0x420033
381#define SIO_HI_RA_RAM_PAR_1_PAR1_SEC_KEY 0x3945
382#define SIO_HI_RA_RAM_PAR_2__A 0x420034
383#define SIO_HI_RA_RAM_PAR_2_CFG_DIV__M 0x7F
384#define SIO_HI_RA_RAM_PAR_2_BRD_CFG_OPEN 0x0
385#define SIO_HI_RA_RAM_PAR_2_BRD_CFG_CLOSED 0x4
386#define SIO_HI_RA_RAM_PAR_3__A 0x420035
387#define SIO_HI_RA_RAM_PAR_3_CFG_DBL_SDA__M 0x7F
388#define SIO_HI_RA_RAM_PAR_3_CFG_DBL_SCL__B 7
389#define SIO_HI_RA_RAM_PAR_3_ACP_RW_READ 0x0
390#define SIO_HI_RA_RAM_PAR_3_ACP_RW_WRITE 0x8
391#define SIO_HI_RA_RAM_PAR_4__A 0x420036
392#define SIO_HI_RA_RAM_PAR_5__A 0x420037
393#define SIO_HI_RA_RAM_PAR_5_CFG_SLV0_SLAVE 0x1
394#define SIO_HI_RA_RAM_PAR_5_CFG_SLEEP__M 0x8
395#define SIO_HI_RA_RAM_PAR_5_CFG_SLEEP_ZZZ 0x8
396#define SIO_HI_RA_RAM_PAR_6__A 0x420038
397#define SIO_CC_PLL_LOCK__A 0x450012
398#define SIO_CC_PWD_MODE__A 0x450015
399#define SIO_CC_PWD_MODE_LEVEL_NONE 0x0
400#define SIO_CC_PWD_MODE_LEVEL_OFDM 0x1
401#define SIO_CC_PWD_MODE_LEVEL_CLOCK 0x2
402#define SIO_CC_PWD_MODE_LEVEL_PLL 0x3
403#define SIO_CC_PWD_MODE_LEVEL_OSC 0x4
404#define SIO_CC_SOFT_RST__A 0x450016
405#define SIO_CC_SOFT_RST_OFDM__M 0x1
406#define SIO_CC_SOFT_RST_SYS__M 0x2
407#define SIO_CC_SOFT_RST_OSC__M 0x4
408#define SIO_CC_UPDATE__A 0x450017
409#define SIO_CC_UPDATE_KEY 0xFABA
410#define SIO_OFDM_SH_OFDM_RING_ENABLE__A 0x470010
411#define SIO_OFDM_SH_OFDM_RING_ENABLE_OFF 0x0
412#define SIO_OFDM_SH_OFDM_RING_ENABLE_ON 0x1
413#define SIO_OFDM_SH_OFDM_RING_STATUS__A 0x470012
414#define SIO_OFDM_SH_OFDM_RING_STATUS_DOWN 0x0
415#define SIO_OFDM_SH_OFDM_RING_STATUS_ENABLED 0x1
416#define SIO_BL_COMM_EXEC__A 0x480000
417#define SIO_BL_COMM_EXEC_ACTIVE 0x1
418#define SIO_BL_STATUS__A 0x480010
419#define SIO_BL_MODE__A 0x480011
420#define SIO_BL_MODE_DIRECT 0x0
421#define SIO_BL_MODE_CHAIN 0x1
422#define SIO_BL_ENABLE__A 0x480012
423#define SIO_BL_ENABLE_ON 0x1
424#define SIO_BL_TGT_HDR__A 0x480014
425#define SIO_BL_TGT_ADDR__A 0x480015
426#define SIO_BL_SRC_ADDR__A 0x480016
427#define SIO_BL_SRC_LEN__A 0x480017
428#define SIO_BL_CHAIN_ADDR__A 0x480018
429#define SIO_BL_CHAIN_LEN__A 0x480019
430#define SIO_PDR_MON_CFG__A 0x7F0010
431#define SIO_PDR_UIO_IN_HI__A 0x7F0015
432#define SIO_PDR_UIO_OUT_LO__A 0x7F0016
433#define SIO_PDR_OHW_CFG__A 0x7F001F
434#define SIO_PDR_OHW_CFG_FREF_SEL__M 0x3
435#define SIO_PDR_MSTRT_CFG__A 0x7F0025
436#define SIO_PDR_MERR_CFG__A 0x7F0026
437#define SIO_PDR_MCLK_CFG__A 0x7F0028
438#define SIO_PDR_MCLK_CFG_DRIVE__B 3
439#define SIO_PDR_MVAL_CFG__A 0x7F0029
440#define SIO_PDR_MD0_CFG__A 0x7F002A
441#define SIO_PDR_MD0_CFG_DRIVE__B 3
442#define SIO_PDR_MD1_CFG__A 0x7F002B
443#define SIO_PDR_MD2_CFG__A 0x7F002C
444#define SIO_PDR_MD3_CFG__A 0x7F002D
445#define SIO_PDR_MD4_CFG__A 0x7F002F
446#define SIO_PDR_MD5_CFG__A 0x7F0030
447#define SIO_PDR_MD6_CFG__A 0x7F0031
448#define SIO_PDR_MD7_CFG__A 0x7F0032
449#define SIO_PDR_SMA_TX_CFG__A 0x7F0038
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c
new file mode 100644
index 00000000000..90bf573308b
--- /dev/null
+++ b/drivers/media/dvb/frontends/ds3000.c
@@ -0,0 +1,1327 @@
1/*
2 Montage Technology DS3000/TS2020 - DVBS/S2 Demodulator/Tuner driver
3 Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
4
5 Copyright (C) 2009 TurboSight.com
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#include <linux/slab.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/init.h>
27#include <linux/firmware.h>
28
29#include "dvb_frontend.h"
30#include "ds3000.h"
31
32static int debug;
33
34#define dprintk(args...) \
35 do { \
36 if (debug) \
37 printk(args); \
38 } while (0)
39
40/* as of March 2009 current DS3000 firmware version is 1.78 */
41/* DS3000 FW v1.78 MD5: a32d17910c4f370073f9346e71d34b80 */
42#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds3000.fw"
43
44#define DS3000_SAMPLE_RATE 96000 /* in kHz */
45#define DS3000_XTAL_FREQ 27000 /* in kHz */
46
47/* Register values to initialise the demod in DVB-S mode */
48static u8 ds3000_dvbs_init_tab[] = {
49 0x23, 0x05,
50 0x08, 0x03,
51 0x0c, 0x00,
52 0x21, 0x54,
53 0x25, 0x82,
54 0x27, 0x31,
55 0x30, 0x08,
56 0x31, 0x40,
57 0x32, 0x32,
58 0x33, 0x35,
59 0x35, 0xff,
60 0x3a, 0x00,
61 0x37, 0x10,
62 0x38, 0x10,
63 0x39, 0x02,
64 0x42, 0x60,
65 0x4a, 0x40,
66 0x4b, 0x04,
67 0x4d, 0x91,
68 0x5d, 0xc8,
69 0x50, 0x77,
70 0x51, 0x77,
71 0x52, 0x36,
72 0x53, 0x36,
73 0x56, 0x01,
74 0x63, 0x43,
75 0x64, 0x30,
76 0x65, 0x40,
77 0x68, 0x26,
78 0x69, 0x4c,
79 0x70, 0x20,
80 0x71, 0x70,
81 0x72, 0x04,
82 0x73, 0x00,
83 0x70, 0x40,
84 0x71, 0x70,
85 0x72, 0x04,
86 0x73, 0x00,
87 0x70, 0x60,
88 0x71, 0x70,
89 0x72, 0x04,
90 0x73, 0x00,
91 0x70, 0x80,
92 0x71, 0x70,
93 0x72, 0x04,
94 0x73, 0x00,
95 0x70, 0xa0,
96 0x71, 0x70,
97 0x72, 0x04,
98 0x73, 0x00,
99 0x70, 0x1f,
100 0x76, 0x00,
101 0x77, 0xd1,
102 0x78, 0x0c,
103 0x79, 0x80,
104 0x7f, 0x04,
105 0x7c, 0x00,
106 0x80, 0x86,
107 0x81, 0xa6,
108 0x85, 0x04,
109 0xcd, 0xf4,
110 0x90, 0x33,
111 0xa0, 0x44,
112 0xc0, 0x18,
113 0xc3, 0x10,
114 0xc4, 0x08,
115 0xc5, 0x80,
116 0xc6, 0x80,
117 0xc7, 0x0a,
118 0xc8, 0x1a,
119 0xc9, 0x80,
120 0xfe, 0x92,
121 0xe0, 0xf8,
122 0xe6, 0x8b,
123 0xd0, 0x40,
124 0xf8, 0x20,
125 0xfa, 0x0f,
126 0xfd, 0x20,
127 0xad, 0x20,
128 0xae, 0x07,
129 0xb8, 0x00,
130};
131
132/* Register values to initialise the demod in DVB-S2 mode */
133static u8 ds3000_dvbs2_init_tab[] = {
134 0x23, 0x0f,
135 0x08, 0x07,
136 0x0c, 0x00,
137 0x21, 0x54,
138 0x25, 0x82,
139 0x27, 0x31,
140 0x30, 0x08,
141 0x31, 0x32,
142 0x32, 0x32,
143 0x33, 0x35,
144 0x35, 0xff,
145 0x3a, 0x00,
146 0x37, 0x10,
147 0x38, 0x10,
148 0x39, 0x02,
149 0x42, 0x60,
150 0x4a, 0x80,
151 0x4b, 0x04,
152 0x4d, 0x81,
153 0x5d, 0x88,
154 0x50, 0x36,
155 0x51, 0x36,
156 0x52, 0x36,
157 0x53, 0x36,
158 0x63, 0x60,
159 0x64, 0x10,
160 0x65, 0x10,
161 0x68, 0x04,
162 0x69, 0x29,
163 0x70, 0x20,
164 0x71, 0x70,
165 0x72, 0x04,
166 0x73, 0x00,
167 0x70, 0x40,
168 0x71, 0x70,
169 0x72, 0x04,
170 0x73, 0x00,
171 0x70, 0x60,
172 0x71, 0x70,
173 0x72, 0x04,
174 0x73, 0x00,
175 0x70, 0x80,
176 0x71, 0x70,
177 0x72, 0x04,
178 0x73, 0x00,
179 0x70, 0xa0,
180 0x71, 0x70,
181 0x72, 0x04,
182 0x73, 0x00,
183 0x70, 0x1f,
184 0xa0, 0x44,
185 0xc0, 0x08,
186 0xc1, 0x10,
187 0xc2, 0x08,
188 0xc3, 0x10,
189 0xc4, 0x08,
190 0xc5, 0xf0,
191 0xc6, 0xf0,
192 0xc7, 0x0a,
193 0xc8, 0x1a,
194 0xc9, 0x80,
195 0xca, 0x23,
196 0xcb, 0x24,
197 0xce, 0x74,
198 0x90, 0x03,
199 0x76, 0x80,
200 0x77, 0x42,
201 0x78, 0x0a,
202 0x79, 0x80,
203 0xad, 0x40,
204 0xae, 0x07,
205 0x7f, 0xd4,
206 0x7c, 0x00,
207 0x80, 0xa8,
208 0x81, 0xda,
209 0x7c, 0x01,
210 0x80, 0xda,
211 0x81, 0xec,
212 0x7c, 0x02,
213 0x80, 0xca,
214 0x81, 0xeb,
215 0x7c, 0x03,
216 0x80, 0xba,
217 0x81, 0xdb,
218 0x85, 0x08,
219 0x86, 0x00,
220 0x87, 0x02,
221 0x89, 0x80,
222 0x8b, 0x44,
223 0x8c, 0xaa,
224 0x8a, 0x10,
225 0xba, 0x00,
226 0xf5, 0x04,
227 0xfe, 0x44,
228 0xd2, 0x32,
229 0xb8, 0x00,
230};
231
232struct ds3000_state {
233 struct i2c_adapter *i2c;
234 const struct ds3000_config *config;
235 struct dvb_frontend frontend;
236 u8 skip_fw_load;
237 /* previous uncorrected block counter for DVB-S2 */
238 u16 prevUCBS2;
239};
240
241static int ds3000_writereg(struct ds3000_state *state, int reg, int data)
242{
243 u8 buf[] = { reg, data };
244 struct i2c_msg msg = { .addr = state->config->demod_address,
245 .flags = 0, .buf = buf, .len = 2 };
246 int err;
247
248 dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
249
250 err = i2c_transfer(state->i2c, &msg, 1);
251 if (err != 1) {
252 printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
253 " value == 0x%02x)\n", __func__, err, reg, data);
254 return -EREMOTEIO;
255 }
256
257 return 0;
258}
259
260static int ds3000_tuner_writereg(struct ds3000_state *state, int reg, int data)
261{
262 u8 buf[] = { reg, data };
263 struct i2c_msg msg = { .addr = 0x60,
264 .flags = 0, .buf = buf, .len = 2 };
265 int err;
266
267 dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
268
269 ds3000_writereg(state, 0x03, 0x11);
270 err = i2c_transfer(state->i2c, &msg, 1);
271 if (err != 1) {
272 printk("%s: writereg error(err == %i, reg == 0x%02x,"
273 " value == 0x%02x)\n", __func__, err, reg, data);
274 return -EREMOTEIO;
275 }
276
277 return 0;
278}
279
280/* I2C write for 8k firmware load */
281static int ds3000_writeFW(struct ds3000_state *state, int reg,
282 const u8 *data, u16 len)
283{
284 int i, ret = -EREMOTEIO;
285 struct i2c_msg msg;
286 u8 *buf;
287
288 buf = kmalloc(33, GFP_KERNEL);
289 if (buf == NULL) {
290 printk(KERN_ERR "Unable to kmalloc\n");
291 ret = -ENOMEM;
292 goto error;
293 }
294
295 *(buf) = reg;
296
297 msg.addr = state->config->demod_address;
298 msg.flags = 0;
299 msg.buf = buf;
300 msg.len = 33;
301
302 for (i = 0; i < len; i += 32) {
303 memcpy(buf + 1, data + i, 32);
304
305 dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len);
306
307 ret = i2c_transfer(state->i2c, &msg, 1);
308 if (ret != 1) {
309 printk(KERN_ERR "%s: write error(err == %i, "
310 "reg == 0x%02x\n", __func__, ret, reg);
311 ret = -EREMOTEIO;
312 }
313 }
314
315error:
316 kfree(buf);
317
318 return ret;
319}
320
321static int ds3000_readreg(struct ds3000_state *state, u8 reg)
322{
323 int ret;
324 u8 b0[] = { reg };
325 u8 b1[] = { 0 };
326 struct i2c_msg msg[] = {
327 {
328 .addr = state->config->demod_address,
329 .flags = 0,
330 .buf = b0,
331 .len = 1
332 }, {
333 .addr = state->config->demod_address,
334 .flags = I2C_M_RD,
335 .buf = b1,
336 .len = 1
337 }
338 };
339
340 ret = i2c_transfer(state->i2c, msg, 2);
341
342 if (ret != 2) {
343 printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
344 return ret;
345 }
346
347 dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
348
349 return b1[0];
350}
351
352static int ds3000_tuner_readreg(struct ds3000_state *state, u8 reg)
353{
354 int ret;
355 u8 b0[] = { reg };
356 u8 b1[] = { 0 };
357 struct i2c_msg msg[] = {
358 {
359 .addr = 0x60,
360 .flags = 0,
361 .buf = b0,
362 .len = 1
363 }, {
364 .addr = 0x60,
365 .flags = I2C_M_RD,
366 .buf = b1,
367 .len = 1
368 }
369 };
370
371 ds3000_writereg(state, 0x03, 0x12);
372 ret = i2c_transfer(state->i2c, msg, 2);
373
374 if (ret != 2) {
375 printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
376 return ret;
377 }
378
379 dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
380
381 return b1[0];
382}
383
384static int ds3000_load_firmware(struct dvb_frontend *fe,
385 const struct firmware *fw);
386
387static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
388{
389 struct ds3000_state *state = fe->demodulator_priv;
390 const struct firmware *fw;
391 int ret = 0;
392
393 dprintk("%s()\n", __func__);
394
395 if (ds3000_readreg(state, 0xb2) <= 0)
396 return ret;
397
398 if (state->skip_fw_load)
399 return 0;
400 /* Load firmware */
401 /* request the firmware, this will block until someone uploads it */
402 printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
403 DS3000_DEFAULT_FIRMWARE);
404 ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE,
405 state->i2c->dev.parent);
406 printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
407 if (ret) {
408 printk(KERN_ERR "%s: No firmware uploaded (timeout or file not "
409 "found?)\n", __func__);
410 return ret;
411 }
412
413 /* Make sure we don't recurse back through here during loading */
414 state->skip_fw_load = 1;
415
416 ret = ds3000_load_firmware(fe, fw);
417 if (ret)
418 printk("%s: Writing firmware to device failed\n", __func__);
419
420 release_firmware(fw);
421
422 dprintk("%s: Firmware upload %s\n", __func__,
423 ret == 0 ? "complete" : "failed");
424
425 /* Ensure firmware is always loaded if required */
426 state->skip_fw_load = 0;
427
428 return ret;
429}
430
431static int ds3000_load_firmware(struct dvb_frontend *fe,
432 const struct firmware *fw)
433{
434 struct ds3000_state *state = fe->demodulator_priv;
435
436 dprintk("%s\n", __func__);
437 dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
438 fw->size,
439 fw->data[0],
440 fw->data[1],
441 fw->data[fw->size - 2],
442 fw->data[fw->size - 1]);
443
444 /* Begin the firmware load process */
445 ds3000_writereg(state, 0xb2, 0x01);
446 /* write the entire firmware */
447 ds3000_writeFW(state, 0xb0, fw->data, fw->size);
448 ds3000_writereg(state, 0xb2, 0x00);
449
450 return 0;
451}
452
453static int ds3000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
454{
455 struct ds3000_state *state = fe->demodulator_priv;
456 u8 data;
457
458 dprintk("%s(%d)\n", __func__, voltage);
459
460 data = ds3000_readreg(state, 0xa2);
461 data |= 0x03; /* bit0 V/H, bit1 off/on */
462
463 switch (voltage) {
464 case SEC_VOLTAGE_18:
465 data &= ~0x03;
466 break;
467 case SEC_VOLTAGE_13:
468 data &= ~0x03;
469 data |= 0x01;
470 break;
471 case SEC_VOLTAGE_OFF:
472 break;
473 }
474
475 ds3000_writereg(state, 0xa2, data);
476
477 return 0;
478}
479
480static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
481{
482 struct ds3000_state *state = fe->demodulator_priv;
483 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
484 int lock;
485
486 *status = 0;
487
488 switch (c->delivery_system) {
489 case SYS_DVBS:
490 lock = ds3000_readreg(state, 0xd1);
491 if ((lock & 0x07) == 0x07)
492 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
493 FE_HAS_VITERBI | FE_HAS_SYNC |
494 FE_HAS_LOCK;
495
496 break;
497 case SYS_DVBS2:
498 lock = ds3000_readreg(state, 0x0d);
499 if ((lock & 0x8f) == 0x8f)
500 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
501 FE_HAS_VITERBI | FE_HAS_SYNC |
502 FE_HAS_LOCK;
503
504 break;
505 default:
506 return 1;
507 }
508
509 dprintk("%s: status = 0x%02x\n", __func__, lock);
510
511 return 0;
512}
513
514/* read DS3000 BER value */
515static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber)
516{
517 struct ds3000_state *state = fe->demodulator_priv;
518 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
519 u8 data;
520 u32 ber_reading, lpdc_frames;
521
522 dprintk("%s()\n", __func__);
523
524 switch (c->delivery_system) {
525 case SYS_DVBS:
526 /* set the number of bytes checked during
527 BER estimation */
528 ds3000_writereg(state, 0xf9, 0x04);
529 /* read BER estimation status */
530 data = ds3000_readreg(state, 0xf8);
531 /* check if BER estimation is ready */
532 if ((data & 0x10) == 0) {
533 /* this is the number of error bits,
534 to calculate the bit error rate
535 divide to 8388608 */
536 *ber = (ds3000_readreg(state, 0xf7) << 8) |
537 ds3000_readreg(state, 0xf6);
538 /* start counting error bits */
539 /* need to be set twice
540 otherwise it fails sometimes */
541 data |= 0x10;
542 ds3000_writereg(state, 0xf8, data);
543 ds3000_writereg(state, 0xf8, data);
544 } else
545 /* used to indicate that BER estimation
546 is not ready, i.e. BER is unknown */
547 *ber = 0xffffffff;
548 break;
549 case SYS_DVBS2:
550 /* read the number of LPDC decoded frames */
551 lpdc_frames = (ds3000_readreg(state, 0xd7) << 16) |
552 (ds3000_readreg(state, 0xd6) << 8) |
553 ds3000_readreg(state, 0xd5);
554 /* read the number of packets with bad CRC */
555 ber_reading = (ds3000_readreg(state, 0xf8) << 8) |
556 ds3000_readreg(state, 0xf7);
557 if (lpdc_frames > 750) {
558 /* clear LPDC frame counters */
559 ds3000_writereg(state, 0xd1, 0x01);
560 /* clear bad packets counter */
561 ds3000_writereg(state, 0xf9, 0x01);
562 /* enable bad packets counter */
563 ds3000_writereg(state, 0xf9, 0x00);
564 /* enable LPDC frame counters */
565 ds3000_writereg(state, 0xd1, 0x00);
566 *ber = ber_reading;
567 } else
568 /* used to indicate that BER estimation is not ready,
569 i.e. BER is unknown */
570 *ber = 0xffffffff;
571 break;
572 default:
573 return 1;
574 }
575
576 return 0;
577}
578
579/* read TS2020 signal strength */
580static int ds3000_read_signal_strength(struct dvb_frontend *fe,
581 u16 *signal_strength)
582{
583 struct ds3000_state *state = fe->demodulator_priv;
584 u16 sig_reading, sig_strength;
585 u8 rfgain, bbgain;
586
587 dprintk("%s()\n", __func__);
588
589 rfgain = ds3000_tuner_readreg(state, 0x3d) & 0x1f;
590 bbgain = ds3000_tuner_readreg(state, 0x21) & 0x1f;
591
592 if (rfgain > 15)
593 rfgain = 15;
594 if (bbgain > 13)
595 bbgain = 13;
596
597 sig_reading = rfgain * 2 + bbgain * 3;
598
599 sig_strength = 40 + (64 - sig_reading) * 50 / 64 ;
600
601 /* cook the value to be suitable for szap-s2 human readable output */
602 *signal_strength = sig_strength * 1000;
603
604 dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__,
605 sig_reading, *signal_strength);
606
607 return 0;
608}
609
610/* calculate DS3000 snr value in dB */
611static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr)
612{
613 struct ds3000_state *state = fe->demodulator_priv;
614 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
615 u8 snr_reading, snr_value;
616 u32 dvbs2_signal_reading, dvbs2_noise_reading, tmp;
617 static const u16 dvbs_snr_tab[] = { /* 20 x Table (rounded up) */
618 0x0000, 0x1b13, 0x2aea, 0x3627, 0x3ede, 0x45fe, 0x4c03,
619 0x513a, 0x55d4, 0x59f2, 0x5dab, 0x6111, 0x6431, 0x6717,
620 0x69c9, 0x6c4e, 0x6eac, 0x70e8, 0x7304, 0x7505
621 };
622 static const u16 dvbs2_snr_tab[] = { /* 80 x Table (rounded up) */
623 0x0000, 0x0bc2, 0x12a3, 0x1785, 0x1b4e, 0x1e65, 0x2103,
624 0x2347, 0x2546, 0x2710, 0x28ae, 0x2a28, 0x2b83, 0x2cc5,
625 0x2df1, 0x2f09, 0x3010, 0x3109, 0x31f4, 0x32d2, 0x33a6,
626 0x3470, 0x3531, 0x35ea, 0x369b, 0x3746, 0x37ea, 0x3888,
627 0x3920, 0x39b3, 0x3a42, 0x3acc, 0x3b51, 0x3bd3, 0x3c51,
628 0x3ccb, 0x3d42, 0x3db6, 0x3e27, 0x3e95, 0x3f00, 0x3f68,
629 0x3fcf, 0x4033, 0x4094, 0x40f4, 0x4151, 0x41ac, 0x4206,
630 0x425e, 0x42b4, 0x4308, 0x435b, 0x43ac, 0x43fc, 0x444a,
631 0x4497, 0x44e2, 0x452d, 0x4576, 0x45bd, 0x4604, 0x4649,
632 0x468e, 0x46d1, 0x4713, 0x4755, 0x4795, 0x47d4, 0x4813,
633 0x4851, 0x488d, 0x48c9, 0x4904, 0x493f, 0x4978, 0x49b1,
634 0x49e9, 0x4a20, 0x4a57
635 };
636
637 dprintk("%s()\n", __func__);
638
639 switch (c->delivery_system) {
640 case SYS_DVBS:
641 snr_reading = ds3000_readreg(state, 0xff);
642 snr_reading /= 8;
643 if (snr_reading == 0)
644 *snr = 0x0000;
645 else {
646 if (snr_reading > 20)
647 snr_reading = 20;
648 snr_value = dvbs_snr_tab[snr_reading - 1] * 10 / 23026;
649 /* cook the value to be suitable for szap-s2
650 human readable output */
651 *snr = snr_value * 8 * 655;
652 }
653 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
654 snr_reading, *snr);
655 break;
656 case SYS_DVBS2:
657 dvbs2_noise_reading = (ds3000_readreg(state, 0x8c) & 0x3f) +
658 (ds3000_readreg(state, 0x8d) << 4);
659 dvbs2_signal_reading = ds3000_readreg(state, 0x8e);
660 tmp = dvbs2_signal_reading * dvbs2_signal_reading >> 1;
661 if (tmp == 0) {
662 *snr = 0x0000;
663 return 0;
664 }
665 if (dvbs2_noise_reading == 0) {
666 snr_value = 0x0013;
667 /* cook the value to be suitable for szap-s2
668 human readable output */
669 *snr = 0xffff;
670 return 0;
671 }
672 if (tmp > dvbs2_noise_reading) {
673 snr_reading = tmp / dvbs2_noise_reading;
674 if (snr_reading > 80)
675 snr_reading = 80;
676 snr_value = dvbs2_snr_tab[snr_reading - 1] / 1000;
677 /* cook the value to be suitable for szap-s2
678 human readable output */
679 *snr = snr_value * 5 * 655;
680 } else {
681 snr_reading = dvbs2_noise_reading / tmp;
682 if (snr_reading > 80)
683 snr_reading = 80;
684 *snr = -(dvbs2_snr_tab[snr_reading] / 1000);
685 }
686 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
687 snr_reading, *snr);
688 break;
689 default:
690 return 1;
691 }
692
693 return 0;
694}
695
696/* read DS3000 uncorrected blocks */
697static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
698{
699 struct ds3000_state *state = fe->demodulator_priv;
700 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
701 u8 data;
702 u16 _ucblocks;
703
704 dprintk("%s()\n", __func__);
705
706 switch (c->delivery_system) {
707 case SYS_DVBS:
708 *ucblocks = (ds3000_readreg(state, 0xf5) << 8) |
709 ds3000_readreg(state, 0xf4);
710 data = ds3000_readreg(state, 0xf8);
711 /* clear packet counters */
712 data &= ~0x20;
713 ds3000_writereg(state, 0xf8, data);
714 /* enable packet counters */
715 data |= 0x20;
716 ds3000_writereg(state, 0xf8, data);
717 break;
718 case SYS_DVBS2:
719 _ucblocks = (ds3000_readreg(state, 0xe2) << 8) |
720 ds3000_readreg(state, 0xe1);
721 if (_ucblocks > state->prevUCBS2)
722 *ucblocks = _ucblocks - state->prevUCBS2;
723 else
724 *ucblocks = state->prevUCBS2 - _ucblocks;
725 state->prevUCBS2 = _ucblocks;
726 break;
727 default:
728 return 1;
729 }
730
731 return 0;
732}
733
734static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
735{
736 struct ds3000_state *state = fe->demodulator_priv;
737 u8 data;
738
739 dprintk("%s(%d)\n", __func__, tone);
740 if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
741 printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
742 return -EINVAL;
743 }
744
745 data = ds3000_readreg(state, 0xa2);
746 data &= ~0xc0;
747 ds3000_writereg(state, 0xa2, data);
748
749 switch (tone) {
750 case SEC_TONE_ON:
751 dprintk("%s: setting tone on\n", __func__);
752 data = ds3000_readreg(state, 0xa1);
753 data &= ~0x43;
754 data |= 0x04;
755 ds3000_writereg(state, 0xa1, data);
756 break;
757 case SEC_TONE_OFF:
758 dprintk("%s: setting tone off\n", __func__);
759 data = ds3000_readreg(state, 0xa2);
760 data |= 0x80;
761 ds3000_writereg(state, 0xa2, data);
762 break;
763 }
764
765 return 0;
766}
767
768static int ds3000_send_diseqc_msg(struct dvb_frontend *fe,
769 struct dvb_diseqc_master_cmd *d)
770{
771 struct ds3000_state *state = fe->demodulator_priv;
772 int i;
773 u8 data;
774
775 /* Dump DiSEqC message */
776 dprintk("%s(", __func__);
777 for (i = 0 ; i < d->msg_len;) {
778 dprintk("0x%02x", d->msg[i]);
779 if (++i < d->msg_len)
780 dprintk(", ");
781 }
782
783 /* enable DiSEqC message send pin */
784 data = ds3000_readreg(state, 0xa2);
785 data &= ~0xc0;
786 ds3000_writereg(state, 0xa2, data);
787
788 /* DiSEqC message */
789 for (i = 0; i < d->msg_len; i++)
790 ds3000_writereg(state, 0xa3 + i, d->msg[i]);
791
792 data = ds3000_readreg(state, 0xa1);
793 /* clear DiSEqC message length and status,
794 enable DiSEqC message send */
795 data &= ~0xf8;
796 /* set DiSEqC mode, modulation active during 33 pulses,
797 set DiSEqC message length */
798 data |= ((d->msg_len - 1) << 3) | 0x07;
799 ds3000_writereg(state, 0xa1, data);
800
801 /* wait up to 150ms for DiSEqC transmission to complete */
802 for (i = 0; i < 15; i++) {
803 data = ds3000_readreg(state, 0xa1);
804 if ((data & 0x40) == 0)
805 break;
806 msleep(10);
807 }
808
809 /* DiSEqC timeout after 150ms */
810 if (i == 15) {
811 data = ds3000_readreg(state, 0xa1);
812 data &= ~0x80;
813 data |= 0x40;
814 ds3000_writereg(state, 0xa1, data);
815
816 data = ds3000_readreg(state, 0xa2);
817 data &= ~0xc0;
818 data |= 0x80;
819 ds3000_writereg(state, 0xa2, data);
820
821 return 1;
822 }
823
824 data = ds3000_readreg(state, 0xa2);
825 data &= ~0xc0;
826 data |= 0x80;
827 ds3000_writereg(state, 0xa2, data);
828
829 return 0;
830}
831
832/* Send DiSEqC burst */
833static int ds3000_diseqc_send_burst(struct dvb_frontend *fe,
834 fe_sec_mini_cmd_t burst)
835{
836 struct ds3000_state *state = fe->demodulator_priv;
837 int i;
838 u8 data;
839
840 dprintk("%s()\n", __func__);
841
842 data = ds3000_readreg(state, 0xa2);
843 data &= ~0xc0;
844 ds3000_writereg(state, 0xa2, data);
845
846 /* DiSEqC burst */
847 if (burst == SEC_MINI_A)
848 /* Unmodulated tone burst */
849 ds3000_writereg(state, 0xa1, 0x02);
850 else if (burst == SEC_MINI_B)
851 /* Modulated tone burst */
852 ds3000_writereg(state, 0xa1, 0x01);
853 else
854 return -EINVAL;
855
856 msleep(13);
857 for (i = 0; i < 5; i++) {
858 data = ds3000_readreg(state, 0xa1);
859 if ((data & 0x40) == 0)
860 break;
861 msleep(1);
862 }
863
864 if (i == 5) {
865 data = ds3000_readreg(state, 0xa1);
866 data &= ~0x80;
867 data |= 0x40;
868 ds3000_writereg(state, 0xa1, data);
869
870 data = ds3000_readreg(state, 0xa2);
871 data &= ~0xc0;
872 data |= 0x80;
873 ds3000_writereg(state, 0xa2, data);
874
875 return 1;
876 }
877
878 data = ds3000_readreg(state, 0xa2);
879 data &= ~0xc0;
880 data |= 0x80;
881 ds3000_writereg(state, 0xa2, data);
882
883 return 0;
884}
885
886static void ds3000_release(struct dvb_frontend *fe)
887{
888 struct ds3000_state *state = fe->demodulator_priv;
889 dprintk("%s\n", __func__);
890 kfree(state);
891}
892
893static struct dvb_frontend_ops ds3000_ops;
894
895struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
896 struct i2c_adapter *i2c)
897{
898 struct ds3000_state *state = NULL;
899 int ret;
900
901 dprintk("%s\n", __func__);
902
903 /* allocate memory for the internal state */
904 state = kzalloc(sizeof(struct ds3000_state), GFP_KERNEL);
905 if (state == NULL) {
906 printk(KERN_ERR "Unable to kmalloc\n");
907 goto error2;
908 }
909
910 state->config = config;
911 state->i2c = i2c;
912 state->prevUCBS2 = 0;
913
914 /* check if the demod is present */
915 ret = ds3000_readreg(state, 0x00) & 0xfe;
916 if (ret != 0xe0) {
917 printk(KERN_ERR "Invalid probe, probably not a DS3000\n");
918 goto error3;
919 }
920
921 printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n",
922 ds3000_readreg(state, 0x02),
923 ds3000_readreg(state, 0x01));
924
925 memcpy(&state->frontend.ops, &ds3000_ops,
926 sizeof(struct dvb_frontend_ops));
927 state->frontend.demodulator_priv = state;
928 return &state->frontend;
929
930error3:
931 kfree(state);
932error2:
933 return NULL;
934}
935EXPORT_SYMBOL(ds3000_attach);
936
937static int ds3000_set_property(struct dvb_frontend *fe,
938 struct dtv_property *tvp)
939{
940 dprintk("%s(..)\n", __func__);
941 return 0;
942}
943
944static int ds3000_get_property(struct dvb_frontend *fe,
945 struct dtv_property *tvp)
946{
947 dprintk("%s(..)\n", __func__);
948 return 0;
949}
950
951static int ds3000_set_carrier_offset(struct dvb_frontend *fe,
952 s32 carrier_offset_khz)
953{
954 struct ds3000_state *state = fe->demodulator_priv;
955 s32 tmp;
956
957 tmp = carrier_offset_khz;
958 tmp *= 65536;
959 tmp = (2 * tmp + DS3000_SAMPLE_RATE) / (2 * DS3000_SAMPLE_RATE);
960
961 if (tmp < 0)
962 tmp += 65536;
963
964 ds3000_writereg(state, 0x5f, tmp >> 8);
965 ds3000_writereg(state, 0x5e, tmp & 0xff);
966
967 return 0;
968}
969
970static int ds3000_set_frontend(struct dvb_frontend *fe,
971 struct dvb_frontend_parameters *p)
972{
973 struct ds3000_state *state = fe->demodulator_priv;
974 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
975
976 int i;
977 fe_status_t status;
978 u8 mlpf, mlpf_new, mlpf_max, mlpf_min, nlpf, div4;
979 s32 offset_khz;
980 u16 value, ndiv;
981 u32 f3db;
982
983 dprintk("%s() ", __func__);
984
985 if (state->config->set_ts_params)
986 state->config->set_ts_params(fe, 0);
987 /* Tune */
988 /* unknown */
989 ds3000_tuner_writereg(state, 0x07, 0x02);
990 ds3000_tuner_writereg(state, 0x10, 0x00);
991 ds3000_tuner_writereg(state, 0x60, 0x79);
992 ds3000_tuner_writereg(state, 0x08, 0x01);
993 ds3000_tuner_writereg(state, 0x00, 0x01);
994 div4 = 0;
995
996 /* calculate and set freq divider */
997 if (p->frequency < 1146000) {
998 ds3000_tuner_writereg(state, 0x10, 0x11);
999 div4 = 1;
1000 ndiv = ((p->frequency * (6 + 8) * 4) +
1001 (DS3000_XTAL_FREQ / 2)) /
1002 DS3000_XTAL_FREQ - 1024;
1003 } else {
1004 ds3000_tuner_writereg(state, 0x10, 0x01);
1005 ndiv = ((p->frequency * (6 + 8) * 2) +
1006 (DS3000_XTAL_FREQ / 2)) /
1007 DS3000_XTAL_FREQ - 1024;
1008 }
1009
1010 ds3000_tuner_writereg(state, 0x01, (ndiv & 0x0f00) >> 8);
1011 ds3000_tuner_writereg(state, 0x02, ndiv & 0x00ff);
1012
1013 /* set pll */
1014 ds3000_tuner_writereg(state, 0x03, 0x06);
1015 ds3000_tuner_writereg(state, 0x51, 0x0f);
1016 ds3000_tuner_writereg(state, 0x51, 0x1f);
1017 ds3000_tuner_writereg(state, 0x50, 0x10);
1018 ds3000_tuner_writereg(state, 0x50, 0x00);
1019 msleep(5);
1020
1021 /* unknown */
1022 ds3000_tuner_writereg(state, 0x51, 0x17);
1023 ds3000_tuner_writereg(state, 0x51, 0x1f);
1024 ds3000_tuner_writereg(state, 0x50, 0x08);
1025 ds3000_tuner_writereg(state, 0x50, 0x00);
1026 msleep(5);
1027
1028 value = ds3000_tuner_readreg(state, 0x3d);
1029 value &= 0x0f;
1030 if ((value > 4) && (value < 15)) {
1031 value -= 3;
1032 if (value < 4)
1033 value = 4;
1034 value = ((value << 3) | 0x01) & 0x79;
1035 }
1036
1037 ds3000_tuner_writereg(state, 0x60, value);
1038 ds3000_tuner_writereg(state, 0x51, 0x17);
1039 ds3000_tuner_writereg(state, 0x51, 0x1f);
1040 ds3000_tuner_writereg(state, 0x50, 0x08);
1041 ds3000_tuner_writereg(state, 0x50, 0x00);
1042
1043 /* set low-pass filter period */
1044 ds3000_tuner_writereg(state, 0x04, 0x2e);
1045 ds3000_tuner_writereg(state, 0x51, 0x1b);
1046 ds3000_tuner_writereg(state, 0x51, 0x1f);
1047 ds3000_tuner_writereg(state, 0x50, 0x04);
1048 ds3000_tuner_writereg(state, 0x50, 0x00);
1049 msleep(5);
1050
1051 f3db = ((c->symbol_rate / 1000) << 2) / 5 + 2000;
1052 if ((c->symbol_rate / 1000) < 5000)
1053 f3db += 3000;
1054 if (f3db < 7000)
1055 f3db = 7000;
1056 if (f3db > 40000)
1057 f3db = 40000;
1058
1059 /* set low-pass filter baseband */
1060 value = ds3000_tuner_readreg(state, 0x26);
1061 mlpf = 0x2e * 207 / ((value << 1) + 151);
1062 mlpf_max = mlpf * 135 / 100;
1063 mlpf_min = mlpf * 78 / 100;
1064 if (mlpf_max > 63)
1065 mlpf_max = 63;
1066
1067 /* rounded to the closest integer */
1068 nlpf = ((mlpf * f3db * 1000) + (2766 * DS3000_XTAL_FREQ / 2))
1069 / (2766 * DS3000_XTAL_FREQ);
1070 if (nlpf > 23)
1071 nlpf = 23;
1072 if (nlpf < 1)
1073 nlpf = 1;
1074
1075 /* rounded to the closest integer */
1076 mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
1077 (1000 * f3db / 2)) / (1000 * f3db);
1078
1079 if (mlpf_new < mlpf_min) {
1080 nlpf++;
1081 mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
1082 (1000 * f3db / 2)) / (1000 * f3db);
1083 }
1084
1085 if (mlpf_new > mlpf_max)
1086 mlpf_new = mlpf_max;
1087
1088 ds3000_tuner_writereg(state, 0x04, mlpf_new);
1089 ds3000_tuner_writereg(state, 0x06, nlpf);
1090 ds3000_tuner_writereg(state, 0x51, 0x1b);
1091 ds3000_tuner_writereg(state, 0x51, 0x1f);
1092 ds3000_tuner_writereg(state, 0x50, 0x04);
1093 ds3000_tuner_writereg(state, 0x50, 0x00);
1094 msleep(5);
1095
1096 /* unknown */
1097 ds3000_tuner_writereg(state, 0x51, 0x1e);
1098 ds3000_tuner_writereg(state, 0x51, 0x1f);
1099 ds3000_tuner_writereg(state, 0x50, 0x01);
1100 ds3000_tuner_writereg(state, 0x50, 0x00);
1101 msleep(60);
1102
1103 offset_khz = (ndiv - ndiv % 2 + 1024) * DS3000_XTAL_FREQ
1104 / (6 + 8) / (div4 + 1) / 2 - p->frequency;
1105
1106 /* ds3000 global reset */
1107 ds3000_writereg(state, 0x07, 0x80);
1108 ds3000_writereg(state, 0x07, 0x00);
1109 /* ds3000 build-in uC reset */
1110 ds3000_writereg(state, 0xb2, 0x01);
1111 /* ds3000 software reset */
1112 ds3000_writereg(state, 0x00, 0x01);
1113
1114 switch (c->delivery_system) {
1115 case SYS_DVBS:
1116 /* initialise the demod in DVB-S mode */
1117 for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
1118 ds3000_writereg(state,
1119 ds3000_dvbs_init_tab[i],
1120 ds3000_dvbs_init_tab[i + 1]);
1121 value = ds3000_readreg(state, 0xfe);
1122 value &= 0xc0;
1123 value |= 0x1b;
1124 ds3000_writereg(state, 0xfe, value);
1125 break;
1126 case SYS_DVBS2:
1127 /* initialise the demod in DVB-S2 mode */
1128 for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
1129 ds3000_writereg(state,
1130 ds3000_dvbs2_init_tab[i],
1131 ds3000_dvbs2_init_tab[i + 1]);
1132 ds3000_writereg(state, 0xfe, 0x98);
1133 break;
1134 default:
1135 return 1;
1136 }
1137
1138 /* enable 27MHz clock output */
1139 ds3000_writereg(state, 0x29, 0x80);
1140 /* enable ac coupling */
1141 ds3000_writereg(state, 0x25, 0x8a);
1142
1143 /* enhance symbol rate performance */
1144 if ((c->symbol_rate / 1000) <= 5000) {
1145 value = 29777 / (c->symbol_rate / 1000) + 1;
1146 if (value % 2 != 0)
1147 value++;
1148 ds3000_writereg(state, 0xc3, 0x0d);
1149 ds3000_writereg(state, 0xc8, value);
1150 ds3000_writereg(state, 0xc4, 0x10);
1151 ds3000_writereg(state, 0xc7, 0x0e);
1152 } else if ((c->symbol_rate / 1000) <= 10000) {
1153 value = 92166 / (c->symbol_rate / 1000) + 1;
1154 if (value % 2 != 0)
1155 value++;
1156 ds3000_writereg(state, 0xc3, 0x07);
1157 ds3000_writereg(state, 0xc8, value);
1158 ds3000_writereg(state, 0xc4, 0x09);
1159 ds3000_writereg(state, 0xc7, 0x12);
1160 } else if ((c->symbol_rate / 1000) <= 20000) {
1161 value = 64516 / (c->symbol_rate / 1000) + 1;
1162 ds3000_writereg(state, 0xc3, value);
1163 ds3000_writereg(state, 0xc8, 0x0e);
1164 ds3000_writereg(state, 0xc4, 0x07);
1165 ds3000_writereg(state, 0xc7, 0x18);
1166 } else {
1167 value = 129032 / (c->symbol_rate / 1000) + 1;
1168 ds3000_writereg(state, 0xc3, value);
1169 ds3000_writereg(state, 0xc8, 0x0a);
1170 ds3000_writereg(state, 0xc4, 0x05);
1171 ds3000_writereg(state, 0xc7, 0x24);
1172 }
1173
1174 /* normalized symbol rate rounded to the closest integer */
1175 value = (((c->symbol_rate / 1000) << 16) +
1176 (DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
1177 ds3000_writereg(state, 0x61, value & 0x00ff);
1178 ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
1179
1180 /* co-channel interference cancellation disabled */
1181 ds3000_writereg(state, 0x56, 0x00);
1182
1183 /* equalizer disabled */
1184 ds3000_writereg(state, 0x76, 0x00);
1185
1186 /*ds3000_writereg(state, 0x08, 0x03);
1187 ds3000_writereg(state, 0xfd, 0x22);
1188 ds3000_writereg(state, 0x08, 0x07);
1189 ds3000_writereg(state, 0xfd, 0x42);
1190 ds3000_writereg(state, 0x08, 0x07);*/
1191
1192 if (state->config->ci_mode) {
1193 switch (c->delivery_system) {
1194 case SYS_DVBS:
1195 default:
1196 ds3000_writereg(state, 0xfd, 0x80);
1197 break;
1198 case SYS_DVBS2:
1199 ds3000_writereg(state, 0xfd, 0x01);
1200 break;
1201 }
1202 }
1203
1204 /* ds3000 out of software reset */
1205 ds3000_writereg(state, 0x00, 0x00);
1206 /* start ds3000 build-in uC */
1207 ds3000_writereg(state, 0xb2, 0x00);
1208
1209 ds3000_set_carrier_offset(fe, offset_khz);
1210
1211 for (i = 0; i < 30 ; i++) {
1212 ds3000_read_status(fe, &status);
1213 if (status && FE_HAS_LOCK)
1214 break;
1215
1216 msleep(10);
1217 }
1218
1219 return 0;
1220}
1221
1222static int ds3000_tune(struct dvb_frontend *fe,
1223 struct dvb_frontend_parameters *p,
1224 unsigned int mode_flags,
1225 unsigned int *delay,
1226 fe_status_t *status)
1227{
1228 if (p) {
1229 int ret = ds3000_set_frontend(fe, p);
1230 if (ret)
1231 return ret;
1232 }
1233
1234 *delay = HZ / 5;
1235
1236 return ds3000_read_status(fe, status);
1237}
1238
1239static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
1240{
1241 dprintk("%s()\n", __func__);
1242 return DVBFE_ALGO_HW;
1243}
1244
1245/*
1246 * Initialise or wake up device
1247 *
1248 * Power config will reset and load initial firmware if required
1249 */
1250static int ds3000_initfe(struct dvb_frontend *fe)
1251{
1252 struct ds3000_state *state = fe->demodulator_priv;
1253 int ret;
1254
1255 dprintk("%s()\n", __func__);
1256 /* hard reset */
1257 ds3000_writereg(state, 0x08, 0x01 | ds3000_readreg(state, 0x08));
1258 msleep(1);
1259
1260 /* TS2020 init */
1261 ds3000_tuner_writereg(state, 0x42, 0x73);
1262 ds3000_tuner_writereg(state, 0x05, 0x01);
1263 ds3000_tuner_writereg(state, 0x62, 0xf5);
1264 /* Load the firmware if required */
1265 ret = ds3000_firmware_ondemand(fe);
1266 if (ret != 0) {
1267 printk(KERN_ERR "%s: Unable initialize firmware\n", __func__);
1268 return ret;
1269 }
1270
1271 return 0;
1272}
1273
1274/* Put device to sleep */
1275static int ds3000_sleep(struct dvb_frontend *fe)
1276{
1277 dprintk("%s()\n", __func__);
1278 return 0;
1279}
1280
1281static struct dvb_frontend_ops ds3000_ops = {
1282
1283 .info = {
1284 .name = "Montage Technology DS3000/TS2020",
1285 .type = FE_QPSK,
1286 .frequency_min = 950000,
1287 .frequency_max = 2150000,
1288 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
1289 .frequency_tolerance = 5000,
1290 .symbol_rate_min = 1000000,
1291 .symbol_rate_max = 45000000,
1292 .caps = FE_CAN_INVERSION_AUTO |
1293 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1294 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1295 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1296 FE_CAN_2G_MODULATION |
1297 FE_CAN_QPSK | FE_CAN_RECOVER
1298 },
1299
1300 .release = ds3000_release,
1301
1302 .init = ds3000_initfe,
1303 .sleep = ds3000_sleep,
1304 .read_status = ds3000_read_status,
1305 .read_ber = ds3000_read_ber,
1306 .read_signal_strength = ds3000_read_signal_strength,
1307 .read_snr = ds3000_read_snr,
1308 .read_ucblocks = ds3000_read_ucblocks,
1309 .set_voltage = ds3000_set_voltage,
1310 .set_tone = ds3000_set_tone,
1311 .diseqc_send_master_cmd = ds3000_send_diseqc_msg,
1312 .diseqc_send_burst = ds3000_diseqc_send_burst,
1313 .get_frontend_algo = ds3000_get_algo,
1314
1315 .set_property = ds3000_set_property,
1316 .get_property = ds3000_get_property,
1317 .set_frontend = ds3000_set_frontend,
1318 .tune = ds3000_tune,
1319};
1320
1321module_param(debug, int, 0644);
1322MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
1323
1324MODULE_DESCRIPTION("DVB Frontend module for Montage Technology "
1325 "DS3000/TS2020 hardware");
1326MODULE_AUTHOR("Konstantin Dimitrov");
1327MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/ds3000.h b/drivers/media/dvb/frontends/ds3000.h
new file mode 100644
index 00000000000..1b736888ea3
--- /dev/null
+++ b/drivers/media/dvb/frontends/ds3000.h
@@ -0,0 +1,48 @@
1/*
2 Montage Technology DS3000/TS2020 - DVBS/S2 Satellite demod/tuner driver
3 Copyright (C) 2009 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
4
5 Copyright (C) 2009 TurboSight.com
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#ifndef DS3000_H
23#define DS3000_H
24
25#include <linux/dvb/frontend.h>
26
27struct ds3000_config {
28 /* the demodulator's i2c address */
29 u8 demod_address;
30 u8 ci_mode;
31 /* Set device param to start dma */
32 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
33};
34
35#if defined(CONFIG_DVB_DS3000) || \
36 (defined(CONFIG_DVB_DS3000_MODULE) && defined(MODULE))
37extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
38 struct i2c_adapter *i2c);
39#else
40static inline
41struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
42 struct i2c_adapter *i2c)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
45 return NULL;
46}
47#endif /* CONFIG_DVB_DS3000 */
48#endif /* DS3000_H */
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
new file mode 100644
index 00000000000..62a65efdf8d
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -0,0 +1,795 @@
1/*
2 * descriptions + helper functions for simple dvb plls.
3 *
4 * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
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 <linux/slab.h>
22#include <linux/module.h>
23#include <linux/dvb/frontend.h>
24#include <asm/types.h>
25
26#include "dvb-pll.h"
27
28struct dvb_pll_priv {
29 /* pll number */
30 int nr;
31
32 /* i2c details */
33 int pll_i2c_address;
34 struct i2c_adapter *i2c;
35
36 /* the PLL descriptor */
37 struct dvb_pll_desc *pll_desc;
38
39 /* cached frequency/bandwidth */
40 u32 frequency;
41 u32 bandwidth;
42};
43
44#define DVB_PLL_MAX 64
45
46static unsigned int dvb_pll_devcount;
47
48static int debug;
49module_param(debug, int, 0644);
50MODULE_PARM_DESC(debug, "enable verbose debug messages");
51
52static unsigned int id[DVB_PLL_MAX] =
53 { [ 0 ... (DVB_PLL_MAX-1) ] = DVB_PLL_UNDEFINED };
54module_param_array(id, int, NULL, 0644);
55MODULE_PARM_DESC(id, "force pll id to use (DEBUG ONLY)");
56
57/* ----------------------------------------------------------- */
58
59struct dvb_pll_desc {
60 char *name;
61 u32 min;
62 u32 max;
63 u32 iffreq;
64 void (*set)(struct dvb_frontend *fe, u8 *buf,
65 const struct dvb_frontend_parameters *params);
66 u8 *initdata;
67 u8 *initdata2;
68 u8 *sleepdata;
69 int count;
70 struct {
71 u32 limit;
72 u32 stepsize;
73 u8 config;
74 u8 cb;
75 } entries[12];
76};
77
78/* ----------------------------------------------------------- */
79/* descriptions */
80
81static struct dvb_pll_desc dvb_pll_thomson_dtt7579 = {
82 .name = "Thomson dtt7579",
83 .min = 177000000,
84 .max = 858000000,
85 .iffreq= 36166667,
86 .sleepdata = (u8[]){ 2, 0xb4, 0x03 },
87 .count = 4,
88 .entries = {
89 { 443250000, 166667, 0xb4, 0x02 },
90 { 542000000, 166667, 0xb4, 0x08 },
91 { 771000000, 166667, 0xbc, 0x08 },
92 { 999999999, 166667, 0xf4, 0x08 },
93 },
94};
95
96static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf,
97 const struct dvb_frontend_parameters *params)
98{
99 if (BANDWIDTH_7_MHZ == params->u.ofdm.bandwidth)
100 buf[3] |= 0x10;
101}
102
103static struct dvb_pll_desc dvb_pll_thomson_dtt759x = {
104 .name = "Thomson dtt759x",
105 .min = 177000000,
106 .max = 896000000,
107 .set = thomson_dtt759x_bw,
108 .iffreq= 36166667,
109 .sleepdata = (u8[]){ 2, 0x84, 0x03 },
110 .count = 5,
111 .entries = {
112 { 264000000, 166667, 0xb4, 0x02 },
113 { 470000000, 166667, 0xbc, 0x02 },
114 { 735000000, 166667, 0xbc, 0x08 },
115 { 835000000, 166667, 0xf4, 0x08 },
116 { 999999999, 166667, 0xfc, 0x08 },
117 },
118};
119
120static struct dvb_pll_desc dvb_pll_lg_z201 = {
121 .name = "LG z201",
122 .min = 174000000,
123 .max = 862000000,
124 .iffreq= 36166667,
125 .sleepdata = (u8[]){ 2, 0xbc, 0x03 },
126 .count = 5,
127 .entries = {
128 { 157500000, 166667, 0xbc, 0x01 },
129 { 443250000, 166667, 0xbc, 0x02 },
130 { 542000000, 166667, 0xbc, 0x04 },
131 { 830000000, 166667, 0xf4, 0x04 },
132 { 999999999, 166667, 0xfc, 0x04 },
133 },
134};
135
136static struct dvb_pll_desc dvb_pll_unknown_1 = {
137 .name = "unknown 1", /* used by dntv live dvb-t */
138 .min = 174000000,
139 .max = 862000000,
140 .iffreq= 36166667,
141 .count = 9,
142 .entries = {
143 { 150000000, 166667, 0xb4, 0x01 },
144 { 173000000, 166667, 0xbc, 0x01 },
145 { 250000000, 166667, 0xb4, 0x02 },
146 { 400000000, 166667, 0xbc, 0x02 },
147 { 420000000, 166667, 0xf4, 0x02 },
148 { 470000000, 166667, 0xfc, 0x02 },
149 { 600000000, 166667, 0xbc, 0x08 },
150 { 730000000, 166667, 0xf4, 0x08 },
151 { 999999999, 166667, 0xfc, 0x08 },
152 },
153};
154
155/* Infineon TUA6010XS
156 * used in Thomson Cable Tuner
157 */
158static struct dvb_pll_desc dvb_pll_tua6010xs = {
159 .name = "Infineon TUA6010XS",
160 .min = 44250000,
161 .max = 858000000,
162 .iffreq= 36125000,
163 .count = 3,
164 .entries = {
165 { 115750000, 62500, 0x8e, 0x03 },
166 { 403250000, 62500, 0x8e, 0x06 },
167 { 999999999, 62500, 0x8e, 0x85 },
168 },
169};
170
171/* Panasonic env57h1xd5 (some Philips PLL ?) */
172static struct dvb_pll_desc dvb_pll_env57h1xd5 = {
173 .name = "Panasonic ENV57H1XD5",
174 .min = 44250000,
175 .max = 858000000,
176 .iffreq= 36125000,
177 .count = 4,
178 .entries = {
179 { 153000000, 166667, 0xc2, 0x41 },
180 { 470000000, 166667, 0xc2, 0x42 },
181 { 526000000, 166667, 0xc2, 0x84 },
182 { 999999999, 166667, 0xc2, 0xa4 },
183 },
184};
185
186/* Philips TDA6650/TDA6651
187 * used in Panasonic ENV77H11D5
188 */
189static void tda665x_bw(struct dvb_frontend *fe, u8 *buf,
190 const struct dvb_frontend_parameters *params)
191{
192 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
193 buf[3] |= 0x08;
194}
195
196static struct dvb_pll_desc dvb_pll_tda665x = {
197 .name = "Philips TDA6650/TDA6651",
198 .min = 44250000,
199 .max = 858000000,
200 .set = tda665x_bw,
201 .iffreq= 36166667,
202 .initdata = (u8[]){ 4, 0x0b, 0xf5, 0x85, 0xab },
203 .count = 12,
204 .entries = {
205 { 93834000, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ },
206 { 123834000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
207 { 161000000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ },
208 { 163834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
209 { 253834000, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ },
210 { 383834000, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ },
211 { 443834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ },
212 { 444000000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
213 { 583834000, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ },
214 { 793834000, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ },
215 { 444834000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ },
216 { 861000000, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ },
217 }
218};
219
220/* Infineon TUA6034
221 * used in LG TDTP E102P
222 */
223static void tua6034_bw(struct dvb_frontend *fe, u8 *buf,
224 const struct dvb_frontend_parameters *params)
225{
226 if (BANDWIDTH_7_MHZ != params->u.ofdm.bandwidth)
227 buf[3] |= 0x08;
228}
229
230static struct dvb_pll_desc dvb_pll_tua6034 = {
231 .name = "Infineon TUA6034",
232 .min = 44250000,
233 .max = 858000000,
234 .iffreq= 36166667,
235 .count = 3,
236 .set = tua6034_bw,
237 .entries = {
238 { 174500000, 62500, 0xce, 0x01 },
239 { 230000000, 62500, 0xce, 0x02 },
240 { 999999999, 62500, 0xce, 0x04 },
241 },
242};
243
244/* ALPS TDED4
245 * used in Nebula-Cards and USB boxes
246 */
247static void tded4_bw(struct dvb_frontend *fe, u8 *buf,
248 const struct dvb_frontend_parameters *params)
249{
250 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
251 buf[3] |= 0x04;
252}
253
254static struct dvb_pll_desc dvb_pll_tded4 = {
255 .name = "ALPS TDED4",
256 .min = 47000000,
257 .max = 863000000,
258 .iffreq= 36166667,
259 .set = tded4_bw,
260 .count = 4,
261 .entries = {
262 { 153000000, 166667, 0x85, 0x01 },
263 { 470000000, 166667, 0x85, 0x02 },
264 { 823000000, 166667, 0x85, 0x08 },
265 { 999999999, 166667, 0x85, 0x88 },
266 }
267};
268
269/* ALPS TDHU2
270 * used in AverTVHD MCE A180
271 */
272static struct dvb_pll_desc dvb_pll_tdhu2 = {
273 .name = "ALPS TDHU2",
274 .min = 54000000,
275 .max = 864000000,
276 .iffreq= 44000000,
277 .count = 4,
278 .entries = {
279 { 162000000, 62500, 0x85, 0x01 },
280 { 426000000, 62500, 0x85, 0x02 },
281 { 782000000, 62500, 0x85, 0x08 },
282 { 999999999, 62500, 0x85, 0x88 },
283 }
284};
285
286/* Samsung TBMV30111IN / TBMV30712IN1
287 * used in Air2PC ATSC - 2nd generation (nxt2002)
288 */
289static struct dvb_pll_desc dvb_pll_samsung_tbmv = {
290 .name = "Samsung TBMV30111IN / TBMV30712IN1",
291 .min = 54000000,
292 .max = 860000000,
293 .iffreq= 44000000,
294 .count = 6,
295 .entries = {
296 { 172000000, 166667, 0xb4, 0x01 },
297 { 214000000, 166667, 0xb4, 0x02 },
298 { 467000000, 166667, 0xbc, 0x02 },
299 { 721000000, 166667, 0xbc, 0x08 },
300 { 841000000, 166667, 0xf4, 0x08 },
301 { 999999999, 166667, 0xfc, 0x02 },
302 }
303};
304
305/*
306 * Philips SD1878 Tuner.
307 */
308static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
309 .name = "Philips SD1878",
310 .min = 950000,
311 .max = 2150000,
312 .iffreq= 249, /* zero-IF, offset 249 is to round up */
313 .count = 4,
314 .entries = {
315 { 1250000, 500, 0xc4, 0x00},
316 { 1450000, 500, 0xc4, 0x40},
317 { 2050000, 500, 0xc4, 0x80},
318 { 2150000, 500, 0xc4, 0xc0},
319 },
320};
321
322static void opera1_bw(struct dvb_frontend *fe, u8 *buf,
323 const struct dvb_frontend_parameters *params)
324{
325 struct dvb_pll_priv *priv = fe->tuner_priv;
326 u32 b_w = (params->u.qpsk.symbol_rate * 27) / 32000;
327 struct i2c_msg msg = {
328 .addr = priv->pll_i2c_address,
329 .flags = 0,
330 .buf = buf,
331 .len = 4
332 };
333 int result;
334 u8 lpf;
335
336 if (fe->ops.i2c_gate_ctrl)
337 fe->ops.i2c_gate_ctrl(fe, 1);
338
339 result = i2c_transfer(priv->i2c, &msg, 1);
340 if (result != 1)
341 printk(KERN_ERR "%s: i2c_transfer failed:%d",
342 __func__, result);
343
344 if (b_w <= 10000)
345 lpf = 0xc;
346 else if (b_w <= 12000)
347 lpf = 0x2;
348 else if (b_w <= 14000)
349 lpf = 0xa;
350 else if (b_w <= 16000)
351 lpf = 0x6;
352 else if (b_w <= 18000)
353 lpf = 0xe;
354 else if (b_w <= 20000)
355 lpf = 0x1;
356 else if (b_w <= 22000)
357 lpf = 0x9;
358 else if (b_w <= 24000)
359 lpf = 0x5;
360 else if (b_w <= 26000)
361 lpf = 0xd;
362 else if (b_w <= 28000)
363 lpf = 0x3;
364 else
365 lpf = 0xb;
366 buf[2] ^= 0x1c; /* Flip bits 3-5 */
367 /* Set lpf */
368 buf[2] |= ((lpf >> 2) & 0x3) << 3;
369 buf[3] |= (lpf & 0x3) << 2;
370
371 return;
372}
373
374static struct dvb_pll_desc dvb_pll_opera1 = {
375 .name = "Opera Tuner",
376 .min = 900000,
377 .max = 2250000,
378 .initdata = (u8[]){ 4, 0x08, 0xe5, 0xe1, 0x00 },
379 .initdata2 = (u8[]){ 4, 0x08, 0xe5, 0xe5, 0x00 },
380 .iffreq= 0,
381 .set = opera1_bw,
382 .count = 8,
383 .entries = {
384 { 1064000, 500, 0xf9, 0xc2 },
385 { 1169000, 500, 0xf9, 0xe2 },
386 { 1299000, 500, 0xf9, 0x20 },
387 { 1444000, 500, 0xf9, 0x40 },
388 { 1606000, 500, 0xf9, 0x60 },
389 { 1777000, 500, 0xf9, 0x80 },
390 { 1941000, 500, 0xf9, 0xa0 },
391 { 2250000, 500, 0xf9, 0xc0 },
392 }
393};
394
395static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf,
396 const struct dvb_frontend_parameters *params)
397{
398 struct dvb_pll_priv *priv = fe->tuner_priv;
399 struct i2c_msg msg = {
400 .addr = priv->pll_i2c_address,
401 .flags = 0,
402 .buf = buf,
403 .len = 4
404 };
405 int result;
406
407 if (fe->ops.i2c_gate_ctrl)
408 fe->ops.i2c_gate_ctrl(fe, 1);
409
410 result = i2c_transfer(priv->i2c, &msg, 1);
411 if (result != 1)
412 printk(KERN_ERR "%s: i2c_transfer failed:%d",
413 __func__, result);
414
415 buf[2] = 0x9e;
416 buf[3] = 0x90;
417
418 return;
419}
420
421/* unknown pll used in Samsung DTOS403IH102A DVB-C tuner */
422static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
423 .name = "Samsung DTOS403IH102A",
424 .min = 44250000,
425 .max = 858000000,
426 .iffreq = 36125000,
427 .count = 8,
428 .set = samsung_dtos403ih102a_set,
429 .entries = {
430 { 135000000, 62500, 0xbe, 0x01 },
431 { 177000000, 62500, 0xf6, 0x01 },
432 { 370000000, 62500, 0xbe, 0x02 },
433 { 450000000, 62500, 0xf6, 0x02 },
434 { 466000000, 62500, 0xfe, 0x02 },
435 { 538000000, 62500, 0xbe, 0x08 },
436 { 826000000, 62500, 0xf6, 0x08 },
437 { 999999999, 62500, 0xfe, 0x08 },
438 }
439};
440
441/* Samsung TDTC9251DH0 DVB-T NIM, as used on AirStar 2 */
442static struct dvb_pll_desc dvb_pll_samsung_tdtc9251dh0 = {
443 .name = "Samsung TDTC9251DH0",
444 .min = 48000000,
445 .max = 863000000,
446 .iffreq = 36166667,
447 .count = 3,
448 .entries = {
449 { 157500000, 166667, 0xcc, 0x09 },
450 { 443000000, 166667, 0xcc, 0x0a },
451 { 863000000, 166667, 0xcc, 0x08 },
452 }
453};
454
455/* Samsung TBDU18132 DVB-S NIM with TSA5059 PLL, used in SkyStar2 DVB-S 2.3 */
456static struct dvb_pll_desc dvb_pll_samsung_tbdu18132 = {
457 .name = "Samsung TBDU18132",
458 .min = 950000,
459 .max = 2150000, /* guesses */
460 .iffreq = 0,
461 .count = 2,
462 .entries = {
463 { 1550000, 125, 0x84, 0x82 },
464 { 4095937, 125, 0x84, 0x80 },
465 }
466 /* TSA5059 PLL has a 17 bit divisor rather than the 15 bits supported
467 * by this driver. The two extra bits are 0x60 in the third byte. 15
468 * bits is enough for over 4 GHz, which is enough to cover the range
469 * of this tuner. We could use the additional divisor bits by adding
470 * more entries, e.g.
471 { 0x0ffff * 125 + 125/2, 125, 0x84 | 0x20, },
472 { 0x17fff * 125 + 125/2, 125, 0x84 | 0x40, },
473 { 0x1ffff * 125 + 125/2, 125, 0x84 | 0x60, }, */
474};
475
476/* Samsung TBMU24112 DVB-S NIM with SL1935 zero-IF tuner */
477static struct dvb_pll_desc dvb_pll_samsung_tbmu24112 = {
478 .name = "Samsung TBMU24112",
479 .min = 950000,
480 .max = 2150000, /* guesses */
481 .iffreq = 0,
482 .count = 2,
483 .entries = {
484 { 1500000, 125, 0x84, 0x18 },
485 { 9999999, 125, 0x84, 0x08 },
486 }
487};
488
489/* Alps TDEE4 DVB-C NIM, used on Cablestar 2 */
490/* byte 4 : 1 * * AGD R3 R2 R1 R0
491 * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1
492 * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95
493 * Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5
494 * 47 - 153 0 * 0 0 0 0 0 1 0x01
495 * 153 - 430 0 * 0 0 0 0 1 0 0x02
496 * 430 - 822 0 * 0 0 1 0 0 0 0x08
497 * 822 - 862 1 * 0 0 1 0 0 0 0x88 */
498static struct dvb_pll_desc dvb_pll_alps_tdee4 = {
499 .name = "ALPS TDEE4",
500 .min = 47000000,
501 .max = 862000000,
502 .iffreq = 36125000,
503 .count = 4,
504 .entries = {
505 { 153000000, 62500, 0x95, 0x01 },
506 { 430000000, 62500, 0x95, 0x02 },
507 { 822000000, 62500, 0x95, 0x08 },
508 { 999999999, 62500, 0x95, 0x88 },
509 }
510};
511
512/* ----------------------------------------------------------- */
513
514static struct dvb_pll_desc *pll_list[] = {
515 [DVB_PLL_UNDEFINED] = NULL,
516 [DVB_PLL_THOMSON_DTT7579] = &dvb_pll_thomson_dtt7579,
517 [DVB_PLL_THOMSON_DTT759X] = &dvb_pll_thomson_dtt759x,
518 [DVB_PLL_LG_Z201] = &dvb_pll_lg_z201,
519 [DVB_PLL_UNKNOWN_1] = &dvb_pll_unknown_1,
520 [DVB_PLL_TUA6010XS] = &dvb_pll_tua6010xs,
521 [DVB_PLL_ENV57H1XD5] = &dvb_pll_env57h1xd5,
522 [DVB_PLL_TUA6034] = &dvb_pll_tua6034,
523 [DVB_PLL_TDA665X] = &dvb_pll_tda665x,
524 [DVB_PLL_TDED4] = &dvb_pll_tded4,
525 [DVB_PLL_TDEE4] = &dvb_pll_alps_tdee4,
526 [DVB_PLL_TDHU2] = &dvb_pll_tdhu2,
527 [DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv,
528 [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261,
529 [DVB_PLL_OPERA1] = &dvb_pll_opera1,
530 [DVB_PLL_SAMSUNG_DTOS403IH102A] = &dvb_pll_samsung_dtos403ih102a,
531 [DVB_PLL_SAMSUNG_TDTC9251DH0] = &dvb_pll_samsung_tdtc9251dh0,
532 [DVB_PLL_SAMSUNG_TBDU18132] = &dvb_pll_samsung_tbdu18132,
533 [DVB_PLL_SAMSUNG_TBMU24112] = &dvb_pll_samsung_tbmu24112,
534};
535
536/* ----------------------------------------------------------- */
537/* code */
538
539static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf,
540 const struct dvb_frontend_parameters *params)
541{
542 struct dvb_pll_priv *priv = fe->tuner_priv;
543 struct dvb_pll_desc *desc = priv->pll_desc;
544 u32 div;
545 int i;
546
547 if (params->frequency != 0 && (params->frequency < desc->min ||
548 params->frequency > desc->max))
549 return -EINVAL;
550
551 for (i = 0; i < desc->count; i++) {
552 if (params->frequency > desc->entries[i].limit)
553 continue;
554 break;
555 }
556
557 if (debug)
558 printk("pll: %s: freq=%d | i=%d/%d\n", desc->name,
559 params->frequency, i, desc->count);
560 if (i == desc->count)
561 return -EINVAL;
562
563 div = (params->frequency + desc->iffreq +
564 desc->entries[i].stepsize/2) / desc->entries[i].stepsize;
565 buf[0] = div >> 8;
566 buf[1] = div & 0xff;
567 buf[2] = desc->entries[i].config;
568 buf[3] = desc->entries[i].cb;
569
570 if (desc->set)
571 desc->set(fe, buf, params);
572
573 if (debug)
574 printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
575 desc->name, div, buf[0], buf[1], buf[2], buf[3]);
576
577 // calculate the frequency we set it to
578 return (div * desc->entries[i].stepsize) - desc->iffreq;
579}
580
581static int dvb_pll_release(struct dvb_frontend *fe)
582{
583 kfree(fe->tuner_priv);
584 fe->tuner_priv = NULL;
585 return 0;
586}
587
588static int dvb_pll_sleep(struct dvb_frontend *fe)
589{
590 struct dvb_pll_priv *priv = fe->tuner_priv;
591
592 if (priv->i2c == NULL)
593 return -EINVAL;
594
595 if (priv->pll_desc->sleepdata) {
596 struct i2c_msg msg = { .flags = 0,
597 .addr = priv->pll_i2c_address,
598 .buf = priv->pll_desc->sleepdata + 1,
599 .len = priv->pll_desc->sleepdata[0] };
600
601 int result;
602
603 if (fe->ops.i2c_gate_ctrl)
604 fe->ops.i2c_gate_ctrl(fe, 1);
605 if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
606 return result;
607 }
608 return 0;
609 }
610 /* Shouldn't be called when initdata is NULL, maybe BUG()? */
611 return -EINVAL;
612}
613
614static int dvb_pll_set_params(struct dvb_frontend *fe,
615 struct dvb_frontend_parameters *params)
616{
617 struct dvb_pll_priv *priv = fe->tuner_priv;
618 u8 buf[4];
619 struct i2c_msg msg =
620 { .addr = priv->pll_i2c_address, .flags = 0,
621 .buf = buf, .len = sizeof(buf) };
622 int result;
623 u32 frequency = 0;
624
625 if (priv->i2c == NULL)
626 return -EINVAL;
627
628 if ((result = dvb_pll_configure(fe, buf, params)) < 0)
629 return result;
630 else
631 frequency = result;
632
633 if (fe->ops.i2c_gate_ctrl)
634 fe->ops.i2c_gate_ctrl(fe, 1);
635 if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) {
636 return result;
637 }
638
639 priv->frequency = frequency;
640 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
641
642 return 0;
643}
644
645static int dvb_pll_calc_regs(struct dvb_frontend *fe,
646 struct dvb_frontend_parameters *params,
647 u8 *buf, int buf_len)
648{
649 struct dvb_pll_priv *priv = fe->tuner_priv;
650 int result;
651 u32 frequency = 0;
652
653 if (buf_len < 5)
654 return -EINVAL;
655
656 if ((result = dvb_pll_configure(fe, buf+1, params)) < 0)
657 return result;
658 else
659 frequency = result;
660
661 buf[0] = priv->pll_i2c_address;
662
663 priv->frequency = frequency;
664 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
665
666 return 5;
667}
668
669static int dvb_pll_get_frequency(struct dvb_frontend *fe, u32 *frequency)
670{
671 struct dvb_pll_priv *priv = fe->tuner_priv;
672 *frequency = priv->frequency;
673 return 0;
674}
675
676static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
677{
678 struct dvb_pll_priv *priv = fe->tuner_priv;
679 *bandwidth = priv->bandwidth;
680 return 0;
681}
682
683static int dvb_pll_init(struct dvb_frontend *fe)
684{
685 struct dvb_pll_priv *priv = fe->tuner_priv;
686
687 if (priv->i2c == NULL)
688 return -EINVAL;
689
690 if (priv->pll_desc->initdata) {
691 struct i2c_msg msg = { .flags = 0,
692 .addr = priv->pll_i2c_address,
693 .buf = priv->pll_desc->initdata + 1,
694 .len = priv->pll_desc->initdata[0] };
695
696 int result;
697 if (fe->ops.i2c_gate_ctrl)
698 fe->ops.i2c_gate_ctrl(fe, 1);
699 result = i2c_transfer(priv->i2c, &msg, 1);
700 if (result != 1)
701 return result;
702 if (priv->pll_desc->initdata2) {
703 msg.buf = priv->pll_desc->initdata2 + 1;
704 msg.len = priv->pll_desc->initdata2[0];
705 if (fe->ops.i2c_gate_ctrl)
706 fe->ops.i2c_gate_ctrl(fe, 1);
707 result = i2c_transfer(priv->i2c, &msg, 1);
708 if (result != 1)
709 return result;
710 }
711 return 0;
712 }
713 /* Shouldn't be called when initdata is NULL, maybe BUG()? */
714 return -EINVAL;
715}
716
717static struct dvb_tuner_ops dvb_pll_tuner_ops = {
718 .release = dvb_pll_release,
719 .sleep = dvb_pll_sleep,
720 .init = dvb_pll_init,
721 .set_params = dvb_pll_set_params,
722 .calc_regs = dvb_pll_calc_regs,
723 .get_frequency = dvb_pll_get_frequency,
724 .get_bandwidth = dvb_pll_get_bandwidth,
725};
726
727struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr,
728 struct i2c_adapter *i2c,
729 unsigned int pll_desc_id)
730{
731 u8 b1 [] = { 0 };
732 struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD,
733 .buf = b1, .len = 1 };
734 struct dvb_pll_priv *priv = NULL;
735 int ret;
736 struct dvb_pll_desc *desc;
737
738 if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) &&
739 (id[dvb_pll_devcount] < ARRAY_SIZE(pll_list)))
740 pll_desc_id = id[dvb_pll_devcount];
741
742 BUG_ON(pll_desc_id < 1 || pll_desc_id >= ARRAY_SIZE(pll_list));
743
744 desc = pll_list[pll_desc_id];
745
746 if (i2c != NULL) {
747 if (fe->ops.i2c_gate_ctrl)
748 fe->ops.i2c_gate_ctrl(fe, 1);
749
750 ret = i2c_transfer (i2c, &msg, 1);
751 if (ret != 1)
752 return NULL;
753 if (fe->ops.i2c_gate_ctrl)
754 fe->ops.i2c_gate_ctrl(fe, 0);
755 }
756
757 priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL);
758 if (priv == NULL)
759 return NULL;
760
761 priv->pll_i2c_address = pll_addr;
762 priv->i2c = i2c;
763 priv->pll_desc = desc;
764 priv->nr = dvb_pll_devcount++;
765
766 memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops,
767 sizeof(struct dvb_tuner_ops));
768
769 strncpy(fe->ops.tuner_ops.info.name, desc->name,
770 sizeof(fe->ops.tuner_ops.info.name));
771 fe->ops.tuner_ops.info.frequency_min = desc->min;
772 fe->ops.tuner_ops.info.frequency_max = desc->max;
773 if (!desc->initdata)
774 fe->ops.tuner_ops.init = NULL;
775 if (!desc->sleepdata)
776 fe->ops.tuner_ops.sleep = NULL;
777
778 fe->tuner_priv = priv;
779
780 if ((debug) || (id[priv->nr] == pll_desc_id)) {
781 printk("dvb-pll[%d]", priv->nr);
782 if (i2c != NULL)
783 printk(" %d-%04x", i2c_adapter_id(i2c), pll_addr);
784 printk(": id# %d (%s) attached, %s\n", pll_desc_id, desc->name,
785 id[priv->nr] == pll_desc_id ?
786 "insmod option" : "autodetected");
787 }
788
789 return fe;
790}
791EXPORT_SYMBOL(dvb_pll_attach);
792
793MODULE_DESCRIPTION("dvb pll library");
794MODULE_AUTHOR("Gerd Knorr");
795MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
new file mode 100644
index 00000000000..086964344c3
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -0,0 +1,56 @@
1/*
2 * descriptions + helper functions for simple dvb plls.
3 */
4
5#ifndef __DVB_PLL_H__
6#define __DVB_PLL_H__
7
8#include <linux/i2c.h>
9#include "dvb_frontend.h"
10
11#define DVB_PLL_UNDEFINED 0
12#define DVB_PLL_THOMSON_DTT7579 1
13#define DVB_PLL_THOMSON_DTT759X 2
14#define DVB_PLL_LG_Z201 3
15#define DVB_PLL_UNKNOWN_1 4
16#define DVB_PLL_TUA6010XS 5
17#define DVB_PLL_ENV57H1XD5 6
18#define DVB_PLL_TUA6034 7
19#define DVB_PLL_TDA665X 8
20#define DVB_PLL_TDED4 9
21#define DVB_PLL_TDHU2 10
22#define DVB_PLL_SAMSUNG_TBMV 11
23#define DVB_PLL_PHILIPS_SD1878_TDA8261 12
24#define DVB_PLL_OPERA1 13
25#define DVB_PLL_SAMSUNG_DTOS403IH102A 14
26#define DVB_PLL_SAMSUNG_TDTC9251DH0 15
27#define DVB_PLL_SAMSUNG_TBDU18132 16
28#define DVB_PLL_SAMSUNG_TBMU24112 17
29#define DVB_PLL_TDEE4 18
30
31/**
32 * Attach a dvb-pll to the supplied frontend structure.
33 *
34 * @param fe Frontend to attach to.
35 * @param pll_addr i2c address of the PLL (if used).
36 * @param i2c i2c adapter to use (set to NULL if not used).
37 * @param pll_desc_id dvb_pll_desc to use.
38 * @return Frontend pointer on success, NULL on failure
39 */
40#if defined(CONFIG_DVB_PLL) || (defined(CONFIG_DVB_PLL_MODULE) && defined(MODULE))
41extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
42 int pll_addr,
43 struct i2c_adapter *i2c,
44 unsigned int pll_desc_id);
45#else
46static inline struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
47 int pll_addr,
48 struct i2c_adapter *i2c,
49 unsigned int pll_desc_id)
50{
51 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
52 return NULL;
53}
54#endif
55
56#endif
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
new file mode 100644
index 00000000000..a7fc7e53a55
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c
@@ -0,0 +1,276 @@
1/*
2 * Driver for Dummy Frontend
3 *
4 * Written by Emard <emard@softhome.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/string.h>
25#include <linux/slab.h>
26
27#include "dvb_frontend.h"
28#include "dvb_dummy_fe.h"
29
30
31struct dvb_dummy_fe_state {
32 struct dvb_frontend frontend;
33};
34
35
36static int dvb_dummy_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
37{
38 *status = FE_HAS_SIGNAL
39 | FE_HAS_CARRIER
40 | FE_HAS_VITERBI
41 | FE_HAS_SYNC
42 | FE_HAS_LOCK;
43
44 return 0;
45}
46
47static int dvb_dummy_fe_read_ber(struct dvb_frontend* fe, u32* ber)
48{
49 *ber = 0;
50 return 0;
51}
52
53static int dvb_dummy_fe_read_signal_strength(struct dvb_frontend* fe, u16* strength)
54{
55 *strength = 0;
56 return 0;
57}
58
59static int dvb_dummy_fe_read_snr(struct dvb_frontend* fe, u16* snr)
60{
61 *snr = 0;
62 return 0;
63}
64
65static int dvb_dummy_fe_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
66{
67 *ucblocks = 0;
68 return 0;
69}
70
71static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
72{
73 return 0;
74}
75
76static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
77{
78 if (fe->ops.tuner_ops.set_params) {
79 fe->ops.tuner_ops.set_params(fe, p);
80 if (fe->ops.i2c_gate_ctrl)
81 fe->ops.i2c_gate_ctrl(fe, 0);
82 }
83
84 return 0;
85}
86
87static int dvb_dummy_fe_sleep(struct dvb_frontend* fe)
88{
89 return 0;
90}
91
92static int dvb_dummy_fe_init(struct dvb_frontend* fe)
93{
94 return 0;
95}
96
97static int dvb_dummy_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
98{
99 return 0;
100}
101
102static int dvb_dummy_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
103{
104 return 0;
105}
106
107static void dvb_dummy_fe_release(struct dvb_frontend* fe)
108{
109 struct dvb_dummy_fe_state* state = fe->demodulator_priv;
110 kfree(state);
111}
112
113static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops;
114
115struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
116{
117 struct dvb_dummy_fe_state* state = NULL;
118
119 /* allocate memory for the internal state */
120 state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
121 if (state == NULL) goto error;
122
123 /* create dvb_frontend */
124 memcpy(&state->frontend.ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops));
125 state->frontend.demodulator_priv = state;
126 return &state->frontend;
127
128error:
129 kfree(state);
130 return NULL;
131}
132
133static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops;
134
135struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
136{
137 struct dvb_dummy_fe_state* state = NULL;
138
139 /* allocate memory for the internal state */
140 state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
141 if (state == NULL) goto error;
142
143 /* create dvb_frontend */
144 memcpy(&state->frontend.ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops));
145 state->frontend.demodulator_priv = state;
146 return &state->frontend;
147
148error:
149 kfree(state);
150 return NULL;
151}
152
153static struct dvb_frontend_ops dvb_dummy_fe_qam_ops;
154
155struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
156{
157 struct dvb_dummy_fe_state* state = NULL;
158
159 /* allocate memory for the internal state */
160 state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
161 if (state == NULL) goto error;
162
163 /* create dvb_frontend */
164 memcpy(&state->frontend.ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops));
165 state->frontend.demodulator_priv = state;
166 return &state->frontend;
167
168error:
169 kfree(state);
170 return NULL;
171}
172
173static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = {
174
175 .info = {
176 .name = "Dummy DVB-T",
177 .type = FE_OFDM,
178 .frequency_min = 0,
179 .frequency_max = 863250000,
180 .frequency_stepsize = 62500,
181 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
182 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
183 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
184 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
185 FE_CAN_TRANSMISSION_MODE_AUTO |
186 FE_CAN_GUARD_INTERVAL_AUTO |
187 FE_CAN_HIERARCHY_AUTO,
188 },
189
190 .release = dvb_dummy_fe_release,
191
192 .init = dvb_dummy_fe_init,
193 .sleep = dvb_dummy_fe_sleep,
194
195 .set_frontend = dvb_dummy_fe_set_frontend,
196 .get_frontend = dvb_dummy_fe_get_frontend,
197
198 .read_status = dvb_dummy_fe_read_status,
199 .read_ber = dvb_dummy_fe_read_ber,
200 .read_signal_strength = dvb_dummy_fe_read_signal_strength,
201 .read_snr = dvb_dummy_fe_read_snr,
202 .read_ucblocks = dvb_dummy_fe_read_ucblocks,
203};
204
205static struct dvb_frontend_ops dvb_dummy_fe_qam_ops = {
206
207 .info = {
208 .name = "Dummy DVB-C",
209 .type = FE_QAM,
210 .frequency_stepsize = 62500,
211 .frequency_min = 51000000,
212 .frequency_max = 858000000,
213 .symbol_rate_min = (57840000/2)/64, /* SACLK/64 == (XIN/2)/64 */
214 .symbol_rate_max = (57840000/2)/4, /* SACLK/4 */
215 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
216 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
217 FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO
218 },
219
220 .release = dvb_dummy_fe_release,
221
222 .init = dvb_dummy_fe_init,
223 .sleep = dvb_dummy_fe_sleep,
224
225 .set_frontend = dvb_dummy_fe_set_frontend,
226 .get_frontend = dvb_dummy_fe_get_frontend,
227
228 .read_status = dvb_dummy_fe_read_status,
229 .read_ber = dvb_dummy_fe_read_ber,
230 .read_signal_strength = dvb_dummy_fe_read_signal_strength,
231 .read_snr = dvb_dummy_fe_read_snr,
232 .read_ucblocks = dvb_dummy_fe_read_ucblocks,
233};
234
235static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = {
236
237 .info = {
238 .name = "Dummy DVB-S",
239 .type = FE_QPSK,
240 .frequency_min = 950000,
241 .frequency_max = 2150000,
242 .frequency_stepsize = 250, /* kHz for QPSK frontends */
243 .frequency_tolerance = 29500,
244 .symbol_rate_min = 1000000,
245 .symbol_rate_max = 45000000,
246 .caps = FE_CAN_INVERSION_AUTO |
247 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
248 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
249 FE_CAN_QPSK
250 },
251
252 .release = dvb_dummy_fe_release,
253
254 .init = dvb_dummy_fe_init,
255 .sleep = dvb_dummy_fe_sleep,
256
257 .set_frontend = dvb_dummy_fe_set_frontend,
258 .get_frontend = dvb_dummy_fe_get_frontend,
259
260 .read_status = dvb_dummy_fe_read_status,
261 .read_ber = dvb_dummy_fe_read_ber,
262 .read_signal_strength = dvb_dummy_fe_read_signal_strength,
263 .read_snr = dvb_dummy_fe_read_snr,
264 .read_ucblocks = dvb_dummy_fe_read_ucblocks,
265
266 .set_voltage = dvb_dummy_fe_set_voltage,
267 .set_tone = dvb_dummy_fe_set_tone,
268};
269
270MODULE_DESCRIPTION("DVB DUMMY Frontend");
271MODULE_AUTHOR("Emard");
272MODULE_LICENSE("GPL");
273
274EXPORT_SYMBOL(dvb_dummy_fe_ofdm_attach);
275EXPORT_SYMBOL(dvb_dummy_fe_qam_attach);
276EXPORT_SYMBOL(dvb_dummy_fe_qpsk_attach);
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.h b/drivers/media/dvb/frontends/dvb_dummy_fe.h
new file mode 100644
index 00000000000..1fcb987d638
--- /dev/null
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.h
@@ -0,0 +1,51 @@
1/*
2 * Driver for Dummy Frontend
3 *
4 * Written by Emard <emard@softhome.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#ifndef DVB_DUMMY_FE_H
23#define DVB_DUMMY_FE_H
24
25#include <linux/dvb/frontend.h>
26#include "dvb_frontend.h"
27
28#if defined(CONFIG_DVB_DUMMY_FE) || (defined(CONFIG_DVB_DUMMY_FE_MODULE) && \
29defined(MODULE))
30extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
31extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
32extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);
33#else
34static inline struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void)
35{
36 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
37 return NULL;
38}
39static inline struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
40{
41 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
42 return NULL;
43}
44static inline struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
45{
46 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
47 return NULL;
48}
49#endif /* CONFIG_DVB_DUMMY_FE */
50
51#endif // DVB_DUMMY_FE_H
diff --git a/drivers/media/dvb/frontends/ec100.c b/drivers/media/dvb/frontends/ec100.c
new file mode 100644
index 00000000000..2414dc6ee5d
--- /dev/null
+++ b/drivers/media/dvb/frontends/ec100.c
@@ -0,0 +1,335 @@
1/*
2 * E3C EC100 demodulator 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 "dvb_frontend.h"
23#include "ec100_priv.h"
24#include "ec100.h"
25
26int ec100_debug;
27module_param_named(debug, ec100_debug, int, 0644);
28MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
29
30struct ec100_state {
31 struct i2c_adapter *i2c;
32 struct dvb_frontend frontend;
33 struct ec100_config config;
34
35 u16 ber;
36};
37
38/* write single register */
39static int ec100_write_reg(struct ec100_state *state, u8 reg, u8 val)
40{
41 u8 buf[2] = {reg, val};
42 struct i2c_msg msg = {
43 .addr = state->config.demod_address,
44 .flags = 0,
45 .len = 2,
46 .buf = buf};
47
48 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
49 warn("I2C write failed reg:%02x", reg);
50 return -EREMOTEIO;
51 }
52 return 0;
53}
54
55/* read single register */
56static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val)
57{
58 struct i2c_msg msg[2] = {
59 {
60 .addr = state->config.demod_address,
61 .flags = 0,
62 .len = 1,
63 .buf = &reg
64 }, {
65 .addr = state->config.demod_address,
66 .flags = I2C_M_RD,
67 .len = 1,
68 .buf = val
69 }
70 };
71
72 if (i2c_transfer(state->i2c, msg, 2) != 2) {
73 warn("I2C read failed reg:%02x", reg);
74 return -EREMOTEIO;
75 }
76 return 0;
77}
78
79static int ec100_set_frontend(struct dvb_frontend *fe,
80 struct dvb_frontend_parameters *params)
81{
82 struct ec100_state *state = fe->demodulator_priv;
83 int ret;
84 u8 tmp, tmp2;
85
86 deb_info("%s: freq:%d bw:%d\n", __func__, params->frequency,
87 params->u.ofdm.bandwidth);
88
89 /* program tuner */
90 if (fe->ops.tuner_ops.set_params)
91 fe->ops.tuner_ops.set_params(fe, params);
92
93 ret = ec100_write_reg(state, 0x04, 0x06);
94 if (ret)
95 goto error;
96 ret = ec100_write_reg(state, 0x67, 0x58);
97 if (ret)
98 goto error;
99 ret = ec100_write_reg(state, 0x05, 0x18);
100 if (ret)
101 goto error;
102
103 /* reg/bw | 6 | 7 | 8
104 -------+------+------+------
105 A 0x1b | 0xa1 | 0xe7 | 0x2c
106 A 0x1c | 0x55 | 0x63 | 0x72
107 -------+------+------+------
108 B 0x1b | 0xb7 | 0x00 | 0x49
109 B 0x1c | 0x55 | 0x64 | 0x72 */
110
111 switch (params->u.ofdm.bandwidth) {
112 case BANDWIDTH_6_MHZ:
113 tmp = 0xb7;
114 tmp2 = 0x55;
115 break;
116 case BANDWIDTH_7_MHZ:
117 tmp = 0x00;
118 tmp2 = 0x64;
119 break;
120 case BANDWIDTH_8_MHZ:
121 default:
122 tmp = 0x49;
123 tmp2 = 0x72;
124 }
125
126 ret = ec100_write_reg(state, 0x1b, tmp);
127 if (ret)
128 goto error;
129 ret = ec100_write_reg(state, 0x1c, tmp2);
130 if (ret)
131 goto error;
132
133 ret = ec100_write_reg(state, 0x0c, 0xbb); /* if freq */
134 if (ret)
135 goto error;
136 ret = ec100_write_reg(state, 0x0d, 0x31); /* if freq */
137 if (ret)
138 goto error;
139
140 ret = ec100_write_reg(state, 0x08, 0x24);
141 if (ret)
142 goto error;
143
144 ret = ec100_write_reg(state, 0x00, 0x00); /* go */
145 if (ret)
146 goto error;
147 ret = ec100_write_reg(state, 0x00, 0x20); /* go */
148 if (ret)
149 goto error;
150
151 return ret;
152error:
153 deb_info("%s: failed:%d\n", __func__, ret);
154 return ret;
155}
156
157static int ec100_get_tune_settings(struct dvb_frontend *fe,
158 struct dvb_frontend_tune_settings *fesettings)
159{
160 fesettings->min_delay_ms = 300;
161 fesettings->step_size = 0;
162 fesettings->max_drift = 0;
163
164 return 0;
165}
166
167static int ec100_read_status(struct dvb_frontend *fe, fe_status_t *status)
168{
169 struct ec100_state *state = fe->demodulator_priv;
170 int ret;
171 u8 tmp;
172 *status = 0;
173
174 ret = ec100_read_reg(state, 0x42, &tmp);
175 if (ret)
176 goto error;
177
178 if (tmp & 0x80) {
179 /* bit7 set - have lock */
180 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
181 FE_HAS_SYNC | FE_HAS_LOCK;
182 } else {
183 ret = ec100_read_reg(state, 0x01, &tmp);
184 if (ret)
185 goto error;
186
187 if (tmp & 0x10) {
188 /* bit4 set - have signal */
189 *status |= FE_HAS_SIGNAL;
190 if (!(tmp & 0x01)) {
191 /* bit0 clear - have ~valid signal */
192 *status |= FE_HAS_CARRIER | FE_HAS_VITERBI;
193 }
194 }
195 }
196
197 return ret;
198error:
199 deb_info("%s: failed:%d\n", __func__, ret);
200 return ret;
201}
202
203static int ec100_read_ber(struct dvb_frontend *fe, u32 *ber)
204{
205 struct ec100_state *state = fe->demodulator_priv;
206 int ret;
207 u8 tmp, tmp2;
208 u16 ber2;
209
210 *ber = 0;
211
212 ret = ec100_read_reg(state, 0x65, &tmp);
213 if (ret)
214 goto error;
215 ret = ec100_read_reg(state, 0x66, &tmp2);
216 if (ret)
217 goto error;
218
219 ber2 = (tmp2 << 8) | tmp;
220
221 /* if counter overflow or clear */
222 if (ber2 < state->ber)
223 *ber = ber2;
224 else
225 *ber = ber2 - state->ber;
226
227 state->ber = ber2;
228
229 return ret;
230error:
231 deb_info("%s: failed:%d\n", __func__, ret);
232 return ret;
233}
234
235static int ec100_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
236{
237 struct ec100_state *state = fe->demodulator_priv;
238 int ret;
239 u8 tmp;
240
241 ret = ec100_read_reg(state, 0x24, &tmp);
242 if (ret) {
243 *strength = 0;
244 goto error;
245 }
246
247 *strength = ((tmp << 8) | tmp);
248
249 return ret;
250error:
251 deb_info("%s: failed:%d\n", __func__, ret);
252 return ret;
253}
254
255static int ec100_read_snr(struct dvb_frontend *fe, u16 *snr)
256{
257 *snr = 0;
258 return 0;
259}
260
261static int ec100_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
262{
263 *ucblocks = 0;
264 return 0;
265}
266
267static void ec100_release(struct dvb_frontend *fe)
268{
269 struct ec100_state *state = fe->demodulator_priv;
270 kfree(state);
271}
272
273static struct dvb_frontend_ops ec100_ops;
274
275struct dvb_frontend *ec100_attach(const struct ec100_config *config,
276 struct i2c_adapter *i2c)
277{
278 int ret;
279 struct ec100_state *state = NULL;
280 u8 tmp;
281
282 /* allocate memory for the internal state */
283 state = kzalloc(sizeof(struct ec100_state), GFP_KERNEL);
284 if (state == NULL)
285 goto error;
286
287 /* setup the state */
288 state->i2c = i2c;
289 memcpy(&state->config, config, sizeof(struct ec100_config));
290
291 /* check if the demod is there */
292 ret = ec100_read_reg(state, 0x33, &tmp);
293 if (ret || tmp != 0x0b)
294 goto error;
295
296 /* create dvb_frontend */
297 memcpy(&state->frontend.ops, &ec100_ops,
298 sizeof(struct dvb_frontend_ops));
299 state->frontend.demodulator_priv = state;
300
301 return &state->frontend;
302error:
303 kfree(state);
304 return NULL;
305}
306EXPORT_SYMBOL(ec100_attach);
307
308static struct dvb_frontend_ops ec100_ops = {
309 .info = {
310 .name = "E3C EC100 DVB-T",
311 .type = FE_OFDM,
312 .caps =
313 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
314 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
315 FE_CAN_QPSK | FE_CAN_QAM_16 |
316 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
317 FE_CAN_TRANSMISSION_MODE_AUTO |
318 FE_CAN_GUARD_INTERVAL_AUTO |
319 FE_CAN_HIERARCHY_AUTO |
320 FE_CAN_MUTE_TS
321 },
322
323 .release = ec100_release,
324 .set_frontend = ec100_set_frontend,
325 .get_tune_settings = ec100_get_tune_settings,
326 .read_status = ec100_read_status,
327 .read_ber = ec100_read_ber,
328 .read_signal_strength = ec100_read_signal_strength,
329 .read_snr = ec100_read_snr,
330 .read_ucblocks = ec100_read_ucblocks,
331};
332
333MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
334MODULE_DESCRIPTION("E3C EC100 DVB-T demodulator driver");
335MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/ec100.h b/drivers/media/dvb/frontends/ec100.h
new file mode 100644
index 00000000000..ee8e5241795
--- /dev/null
+++ b/drivers/media/dvb/frontends/ec100.h
@@ -0,0 +1,46 @@
1/*
2 * E3C EC100 demodulator 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 EC100_H
23#define EC100_H
24
25#include <linux/dvb/frontend.h>
26
27struct ec100_config {
28 /* demodulator's I2C address */
29 u8 demod_address;
30};
31
32
33#if defined(CONFIG_DVB_EC100) || \
34 (defined(CONFIG_DVB_EC100_MODULE) && defined(MODULE))
35extern struct dvb_frontend *ec100_attach(const struct ec100_config *config,
36 struct i2c_adapter *i2c);
37#else
38static inline struct dvb_frontend *ec100_attach(
39 const struct ec100_config *config, struct i2c_adapter *i2c)
40{
41 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
42 return NULL;
43}
44#endif
45
46#endif /* EC100_H */
diff --git a/drivers/media/dvb/frontends/ec100_priv.h b/drivers/media/dvb/frontends/ec100_priv.h
new file mode 100644
index 00000000000..5c990144bc4
--- /dev/null
+++ b/drivers/media/dvb/frontends/ec100_priv.h
@@ -0,0 +1,39 @@
1/*
2 * E3C EC100 demodulator 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 EC100_PRIV
23#define EC100_PRIV
24
25#define LOG_PREFIX "ec100"
26
27#define dprintk(var, level, args...) \
28 do { if ((var & level)) printk(args); } while (0)
29
30#define deb_info(args...) dprintk(ec100_debug, 0x01, args)
31
32#undef err
33#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
34#undef info
35#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
36#undef warn
37#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
38
39#endif /* EC100_PRIV */
diff --git a/drivers/media/dvb/frontends/eds1547.h b/drivers/media/dvb/frontends/eds1547.h
new file mode 100644
index 00000000000..c983f2f8580
--- /dev/null
+++ b/drivers/media/dvb/frontends/eds1547.h
@@ -0,0 +1,133 @@
1/* eds1547.h Earda EDS-1547 tuner support
2*
3* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
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#ifndef EDS1547
13#define EDS1547
14
15static u8 stv0288_earda_inittab[] = {
16 0x01, 0x57,
17 0x02, 0x20,
18 0x03, 0x8e,
19 0x04, 0x8e,
20 0x05, 0x12,
21 0x06, 0x00,
22 0x07, 0x00,
23 0x09, 0x00,
24 0x0a, 0x04,
25 0x0b, 0x00,
26 0x0c, 0x00,
27 0x0d, 0x00,
28 0x0e, 0xd4,
29 0x0f, 0x30,
30 0x11, 0x44,
31 0x12, 0x03,
32 0x13, 0x48,
33 0x14, 0x84,
34 0x15, 0x45,
35 0x16, 0xb7,
36 0x17, 0x9c,
37 0x18, 0x00,
38 0x19, 0xa6,
39 0x1a, 0x88,
40 0x1b, 0x8f,
41 0x1c, 0xf0,
42 0x20, 0x0b,
43 0x21, 0x54,
44 0x22, 0x00,
45 0x23, 0x00,
46 0x2b, 0xff,
47 0x2c, 0xf7,
48 0x30, 0x00,
49 0x31, 0x1e,
50 0x32, 0x14,
51 0x33, 0x0f,
52 0x34, 0x09,
53 0x35, 0x0c,
54 0x36, 0x05,
55 0x37, 0x2f,
56 0x38, 0x16,
57 0x39, 0xbd,
58 0x3a, 0x00,
59 0x3b, 0x13,
60 0x3c, 0x11,
61 0x3d, 0x30,
62 0x40, 0x63,
63 0x41, 0x04,
64 0x42, 0x20,
65 0x43, 0x00,
66 0x44, 0x00,
67 0x45, 0x00,
68 0x46, 0x00,
69 0x47, 0x00,
70 0x4a, 0x00,
71 0x50, 0x10,
72 0x51, 0x36,
73 0x52, 0x09,
74 0x53, 0x94,
75 0x54, 0x62,
76 0x55, 0x29,
77 0x56, 0x64,
78 0x57, 0x2b,
79 0x58, 0x54,
80 0x59, 0x86,
81 0x5a, 0x00,
82 0x5b, 0x9b,
83 0x5c, 0x08,
84 0x5d, 0x7f,
85 0x5e, 0x00,
86 0x5f, 0xff,
87 0x70, 0x00,
88 0x71, 0x00,
89 0x72, 0x00,
90 0x74, 0x00,
91 0x75, 0x00,
92 0x76, 0x00,
93 0x81, 0x00,
94 0x82, 0x3f,
95 0x83, 0x3f,
96 0x84, 0x00,
97 0x85, 0x00,
98 0x88, 0x00,
99 0x89, 0x00,
100 0x8a, 0x00,
101 0x8b, 0x00,
102 0x8c, 0x00,
103 0x90, 0x00,
104 0x91, 0x00,
105 0x92, 0x00,
106 0x93, 0x00,
107 0x94, 0x1c,
108 0x97, 0x00,
109 0xa0, 0x48,
110 0xa1, 0x00,
111 0xb0, 0xb8,
112 0xb1, 0x3a,
113 0xb2, 0x10,
114 0xb3, 0x82,
115 0xb4, 0x80,
116 0xb5, 0x82,
117 0xb6, 0x82,
118 0xb7, 0x82,
119 0xb8, 0x20,
120 0xb9, 0x00,
121 0xf0, 0x00,
122 0xf1, 0x00,
123 0xf2, 0xc0,
124 0xff,0xff,
125};
126
127static struct stv0288_config earda_config = {
128 .demod_address = 0x68,
129 .min_delay_ms = 100,
130 .inittab = stv0288_earda_inittab,
131};
132
133#endif
diff --git a/drivers/media/dvb/frontends/isl6405.c b/drivers/media/dvb/frontends/isl6405.c
new file mode 100644
index 00000000000..33d33f4d886
--- /dev/null
+++ b/drivers/media/dvb/frontends/isl6405.c
@@ -0,0 +1,164 @@
1/*
2 * isl6405.c - driver for dual lnb supply and control ic ISL6405
3 *
4 * Copyright (C) 2008 Hartmut Hackmann
5 * Copyright (C) 2006 Oliver Endriss
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
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
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 *
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 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
23 *
24 *
25 * the project's page is at http://www.linuxtv.org
26 */
27#include <linux/delay.h>
28#include <linux/errno.h>
29#include <linux/init.h>
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/string.h>
33#include <linux/slab.h>
34
35#include "dvb_frontend.h"
36#include "isl6405.h"
37
38struct isl6405 {
39 u8 config;
40 u8 override_or;
41 u8 override_and;
42 struct i2c_adapter *i2c;
43 u8 i2c_addr;
44};
45
46static int isl6405_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
47{
48 struct isl6405 *isl6405 = (struct isl6405 *) fe->sec_priv;
49 struct i2c_msg msg = { .addr = isl6405->i2c_addr, .flags = 0,
50 .buf = &isl6405->config,
51 .len = sizeof(isl6405->config) };
52
53 if (isl6405->override_or & 0x80) {
54 isl6405->config &= ~(ISL6405_VSEL2 | ISL6405_EN2);
55 switch (voltage) {
56 case SEC_VOLTAGE_OFF:
57 break;
58 case SEC_VOLTAGE_13:
59 isl6405->config |= ISL6405_EN2;
60 break;
61 case SEC_VOLTAGE_18:
62 isl6405->config |= (ISL6405_EN2 | ISL6405_VSEL2);
63 break;
64 default:
65 return -EINVAL;
66 }
67 } else {
68 isl6405->config &= ~(ISL6405_VSEL1 | ISL6405_EN1);
69 switch (voltage) {
70 case SEC_VOLTAGE_OFF:
71 break;
72 case SEC_VOLTAGE_13:
73 isl6405->config |= ISL6405_EN1;
74 break;
75 case SEC_VOLTAGE_18:
76 isl6405->config |= (ISL6405_EN1 | ISL6405_VSEL1);
77 break;
78 default:
79 return -EINVAL;
80 };
81 }
82 isl6405->config |= isl6405->override_or;
83 isl6405->config &= isl6405->override_and;
84
85 return (i2c_transfer(isl6405->i2c, &msg, 1) == 1) ? 0 : -EIO;
86}
87
88static int isl6405_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
89{
90 struct isl6405 *isl6405 = (struct isl6405 *) fe->sec_priv;
91 struct i2c_msg msg = { .addr = isl6405->i2c_addr, .flags = 0,
92 .buf = &isl6405->config,
93 .len = sizeof(isl6405->config) };
94
95 if (isl6405->override_or & 0x80) {
96 if (arg)
97 isl6405->config |= ISL6405_LLC2;
98 else
99 isl6405->config &= ~ISL6405_LLC2;
100 } else {
101 if (arg)
102 isl6405->config |= ISL6405_LLC1;
103 else
104 isl6405->config &= ~ISL6405_LLC1;
105 }
106 isl6405->config |= isl6405->override_or;
107 isl6405->config &= isl6405->override_and;
108
109 return (i2c_transfer(isl6405->i2c, &msg, 1) == 1) ? 0 : -EIO;
110}
111
112static void isl6405_release(struct dvb_frontend *fe)
113{
114 /* power off */
115 isl6405_set_voltage(fe, SEC_VOLTAGE_OFF);
116
117 /* free */
118 kfree(fe->sec_priv);
119 fe->sec_priv = NULL;
120}
121
122struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c,
123 u8 i2c_addr, u8 override_set, u8 override_clear)
124{
125 struct isl6405 *isl6405 = kmalloc(sizeof(struct isl6405), GFP_KERNEL);
126 if (!isl6405)
127 return NULL;
128
129 /* default configuration */
130 if (override_set & 0x80)
131 isl6405->config = ISL6405_ISEL2;
132 else
133 isl6405->config = ISL6405_ISEL1;
134 isl6405->i2c = i2c;
135 isl6405->i2c_addr = i2c_addr;
136 fe->sec_priv = isl6405;
137
138 /* bits which should be forced to '1' */
139 isl6405->override_or = override_set;
140
141 /* bits which should be forced to '0' */
142 isl6405->override_and = ~override_clear;
143
144 /* detect if it is present or not */
145 if (isl6405_set_voltage(fe, SEC_VOLTAGE_OFF)) {
146 kfree(isl6405);
147 fe->sec_priv = NULL;
148 return NULL;
149 }
150
151 /* install release callback */
152 fe->ops.release_sec = isl6405_release;
153
154 /* override frontend ops */
155 fe->ops.set_voltage = isl6405_set_voltage;
156 fe->ops.enable_high_lnb_voltage = isl6405_enable_high_lnb_voltage;
157
158 return fe;
159}
160EXPORT_SYMBOL(isl6405_attach);
161
162MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6405");
163MODULE_AUTHOR("Hartmut Hackmann & Oliver Endriss");
164MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/isl6405.h b/drivers/media/dvb/frontends/isl6405.h
new file mode 100644
index 00000000000..1c793d37576
--- /dev/null
+++ b/drivers/media/dvb/frontends/isl6405.h
@@ -0,0 +1,74 @@
1/*
2 * isl6405.h - driver for dual lnb supply and control ic ISL6405
3 *
4 * Copyright (C) 2008 Hartmut Hackmann
5 * Copyright (C) 2006 Oliver Endriss
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
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
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 *
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 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
23 *
24 *
25 * the project's page is at http://www.linuxtv.org
26 */
27
28#ifndef _ISL6405_H
29#define _ISL6405_H
30
31#include <linux/dvb/frontend.h>
32
33/* system register bits */
34
35/* this bit selects register (control) 1 or 2
36 note that the bit maps are different */
37
38#define ISL6405_SR 0x80
39
40/* SR = 0 */
41#define ISL6405_OLF1 0x01
42#define ISL6405_EN1 0x02
43#define ISL6405_VSEL1 0x04
44#define ISL6405_LLC1 0x08
45#define ISL6405_ENT1 0x10
46#define ISL6405_ISEL1 0x20
47#define ISL6405_DCL 0x40
48
49/* SR = 1 */
50#define ISL6405_OLF2 0x01
51#define ISL6405_OTF 0x02
52#define ISL6405_EN2 0x04
53#define ISL6405_VSEL2 0x08
54#define ISL6405_LLC2 0x10
55#define ISL6405_ENT2 0x20
56#define ISL6405_ISEL2 0x40
57
58#if defined(CONFIG_DVB_ISL6405) || (defined(CONFIG_DVB_ISL6405_MODULE) && defined(MODULE))
59/* override_set and override_clear control which system register bits (above)
60 * to always set & clear
61 */
62extern struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c,
63 u8 i2c_addr, u8 override_set, u8 override_clear);
64#else
65static inline struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe,
66 struct i2c_adapter *i2c, u8 i2c_addr,
67 u8 override_set, u8 override_clear)
68{
69 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
70 return NULL;
71}
72#endif /* CONFIG_DVB_ISL6405 */
73
74#endif
diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c
new file mode 100644
index 00000000000..684c8ec166c
--- /dev/null
+++ b/drivers/media/dvb/frontends/isl6421.c
@@ -0,0 +1,141 @@
1/*
2 * isl6421.h - driver for lnb supply and control ic ISL6421
3 *
4 * Copyright (C) 2006 Andrew de Quincey
5 * Copyright (C) 2006 Oliver Endriss
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
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
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 *
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 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
23 *
24 *
25 * the project's page is at http://www.linuxtv.org
26 */
27#include <linux/delay.h>
28#include <linux/errno.h>
29#include <linux/init.h>
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/string.h>
33#include <linux/slab.h>
34
35#include "dvb_frontend.h"
36#include "isl6421.h"
37
38struct isl6421 {
39 u8 config;
40 u8 override_or;
41 u8 override_and;
42 struct i2c_adapter *i2c;
43 u8 i2c_addr;
44};
45
46static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
47{
48 struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
49 struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0,
50 .buf = &isl6421->config,
51 .len = sizeof(isl6421->config) };
52
53 isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1);
54
55 switch(voltage) {
56 case SEC_VOLTAGE_OFF:
57 break;
58 case SEC_VOLTAGE_13:
59 isl6421->config |= ISL6421_EN1;
60 break;
61 case SEC_VOLTAGE_18:
62 isl6421->config |= (ISL6421_EN1 | ISL6421_VSEL1);
63 break;
64 default:
65 return -EINVAL;
66 };
67
68 isl6421->config |= isl6421->override_or;
69 isl6421->config &= isl6421->override_and;
70
71 return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
72}
73
74static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
75{
76 struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
77 struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0,
78 .buf = &isl6421->config,
79 .len = sizeof(isl6421->config) };
80
81 if (arg)
82 isl6421->config |= ISL6421_LLC1;
83 else
84 isl6421->config &= ~ISL6421_LLC1;
85
86 isl6421->config |= isl6421->override_or;
87 isl6421->config &= isl6421->override_and;
88
89 return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
90}
91
92static void isl6421_release(struct dvb_frontend *fe)
93{
94 /* power off */
95 isl6421_set_voltage(fe, SEC_VOLTAGE_OFF);
96
97 /* free */
98 kfree(fe->sec_priv);
99 fe->sec_priv = NULL;
100}
101
102struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
103 u8 override_set, u8 override_clear)
104{
105 struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL);
106 if (!isl6421)
107 return NULL;
108
109 /* default configuration */
110 isl6421->config = ISL6421_ISEL1;
111 isl6421->i2c = i2c;
112 isl6421->i2c_addr = i2c_addr;
113 fe->sec_priv = isl6421;
114
115 /* bits which should be forced to '1' */
116 isl6421->override_or = override_set;
117
118 /* bits which should be forced to '0' */
119 isl6421->override_and = ~override_clear;
120
121 /* detect if it is present or not */
122 if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) {
123 kfree(isl6421);
124 fe->sec_priv = NULL;
125 return NULL;
126 }
127
128 /* install release callback */
129 fe->ops.release_sec = isl6421_release;
130
131 /* override frontend ops */
132 fe->ops.set_voltage = isl6421_set_voltage;
133 fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage;
134
135 return fe;
136}
137EXPORT_SYMBOL(isl6421_attach);
138
139MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421");
140MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss");
141MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/isl6421.h b/drivers/media/dvb/frontends/isl6421.h
new file mode 100644
index 00000000000..47e4518a042
--- /dev/null
+++ b/drivers/media/dvb/frontends/isl6421.h
@@ -0,0 +1,55 @@
1/*
2 * isl6421.h - driver for lnb supply and control ic ISL6421
3 *
4 * Copyright (C) 2006 Andrew de Quincey
5 * Copyright (C) 2006 Oliver Endriss
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
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
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 *
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 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
23 *
24 *
25 * the project's page is at http://www.linuxtv.org
26 */
27
28#ifndef _ISL6421_H
29#define _ISL6421_H
30
31#include <linux/dvb/frontend.h>
32
33/* system register bits */
34#define ISL6421_OLF1 0x01
35#define ISL6421_EN1 0x02
36#define ISL6421_VSEL1 0x04
37#define ISL6421_LLC1 0x08
38#define ISL6421_ENT1 0x10
39#define ISL6421_ISEL1 0x20
40#define ISL6421_DCL 0x40
41
42#if defined(CONFIG_DVB_ISL6421) || (defined(CONFIG_DVB_ISL6421_MODULE) && defined(MODULE))
43/* override_set and override_clear control which system register bits (above) to always set & clear */
44extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
45 u8 override_set, u8 override_clear);
46#else
47static inline struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
48 u8 override_set, u8 override_clear)
49{
50 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
51 return NULL;
52}
53#endif // CONFIG_DVB_ISL6421
54
55#endif
diff --git a/drivers/media/dvb/frontends/isl6423.c b/drivers/media/dvb/frontends/isl6423.c
new file mode 100644
index 00000000000..dca5bebfeeb
--- /dev/null
+++ b/drivers/media/dvb/frontends/isl6423.c
@@ -0,0 +1,308 @@
1/*
2 Intersil ISL6423 SEC and LNB Power supply controller
3
4 Copyright (C) Manu Abraham <abraham.manu@gmail.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 <linux/delay.h>
22#include <linux/errno.h>
23#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28
29#include "dvb_frontend.h"
30#include "isl6423.h"
31
32static unsigned int verbose;
33module_param(verbose, int, 0644);
34MODULE_PARM_DESC(verbose, "Set Verbosity level");
35
36#define FE_ERROR 0
37#define FE_NOTICE 1
38#define FE_INFO 2
39#define FE_DEBUG 3
40#define FE_DEBUGREG 4
41
42#define dprintk(__y, __z, format, arg...) do { \
43 if (__z) { \
44 if ((verbose > FE_ERROR) && (verbose > __y)) \
45 printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
46 else if ((verbose > FE_NOTICE) && (verbose > __y)) \
47 printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
48 else if ((verbose > FE_INFO) && (verbose > __y)) \
49 printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
50 else if ((verbose > FE_DEBUG) && (verbose > __y)) \
51 printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
52 } else { \
53 if (verbose > __y) \
54 printk(format, ##arg); \
55 } \
56} while (0)
57
58struct isl6423_dev {
59 const struct isl6423_config *config;
60 struct i2c_adapter *i2c;
61
62 u8 reg_3;
63 u8 reg_4;
64
65 unsigned int verbose;
66};
67
68static int isl6423_write(struct isl6423_dev *isl6423, u8 reg)
69{
70 struct i2c_adapter *i2c = isl6423->i2c;
71 u8 addr = isl6423->config->addr;
72 int err = 0;
73
74 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = &reg, .len = 1 };
75
76 dprintk(FE_DEBUG, 1, "write reg %02X", reg);
77 err = i2c_transfer(i2c, &msg, 1);
78 if (err < 0)
79 goto exit;
80 return 0;
81
82exit:
83 dprintk(FE_ERROR, 1, "I/O error <%d>", err);
84 return err;
85}
86
87static int isl6423_set_modulation(struct dvb_frontend *fe)
88{
89 struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
90 const struct isl6423_config *config = isl6423->config;
91 int err = 0;
92 u8 reg_2 = 0;
93
94 reg_2 = 0x01 << 5;
95
96 if (config->mod_extern)
97 reg_2 |= (1 << 3);
98 else
99 reg_2 |= (1 << 4);
100
101 err = isl6423_write(isl6423, reg_2);
102 if (err < 0)
103 goto exit;
104 return 0;
105
106exit:
107 dprintk(FE_ERROR, 1, "I/O error <%d>", err);
108 return err;
109}
110
111static int isl6423_voltage_boost(struct dvb_frontend *fe, long arg)
112{
113 struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
114 u8 reg_3 = isl6423->reg_3;
115 u8 reg_4 = isl6423->reg_4;
116 int err = 0;
117
118 if (arg) {
119 /* EN = 1, VSPEN = 1, VBOT = 1 */
120 reg_4 |= (1 << 4);
121 reg_4 |= 0x1;
122 reg_3 |= (1 << 3);
123 } else {
124 /* EN = 1, VSPEN = 1, VBOT = 0 */
125 reg_4 |= (1 << 4);
126 reg_4 &= ~0x1;
127 reg_3 |= (1 << 3);
128 }
129 err = isl6423_write(isl6423, reg_3);
130 if (err < 0)
131 goto exit;
132
133 err = isl6423_write(isl6423, reg_4);
134 if (err < 0)
135 goto exit;
136
137 isl6423->reg_3 = reg_3;
138 isl6423->reg_4 = reg_4;
139
140 return 0;
141exit:
142 dprintk(FE_ERROR, 1, "I/O error <%d>", err);
143 return err;
144}
145
146
147static int isl6423_set_voltage(struct dvb_frontend *fe,
148 enum fe_sec_voltage voltage)
149{
150 struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
151 u8 reg_3 = isl6423->reg_3;
152 u8 reg_4 = isl6423->reg_4;
153 int err = 0;
154
155 switch (voltage) {
156 case SEC_VOLTAGE_OFF:
157 /* EN = 0 */
158 reg_4 &= ~(1 << 4);
159 break;
160
161 case SEC_VOLTAGE_13:
162 /* EN = 1, VSPEN = 1, VTOP = 0, VBOT = 0 */
163 reg_4 |= (1 << 4);
164 reg_4 &= ~0x3;
165 reg_3 |= (1 << 3);
166 break;
167
168 case SEC_VOLTAGE_18:
169 /* EN = 1, VSPEN = 1, VTOP = 1, VBOT = 0 */
170 reg_4 |= (1 << 4);
171 reg_4 |= 0x2;
172 reg_4 &= ~0x1;
173 reg_3 |= (1 << 3);
174 break;
175
176 default:
177 break;
178 }
179 err = isl6423_write(isl6423, reg_3);
180 if (err < 0)
181 goto exit;
182
183 err = isl6423_write(isl6423, reg_4);
184 if (err < 0)
185 goto exit;
186
187 isl6423->reg_3 = reg_3;
188 isl6423->reg_4 = reg_4;
189
190 return 0;
191exit:
192 dprintk(FE_ERROR, 1, "I/O error <%d>", err);
193 return err;
194}
195
196static int isl6423_set_current(struct dvb_frontend *fe)
197{
198 struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
199 u8 reg_3 = isl6423->reg_3;
200 const struct isl6423_config *config = isl6423->config;
201 int err = 0;
202
203 switch (config->current_max) {
204 case SEC_CURRENT_275m:
205 /* 275mA */
206 /* ISELH = 0, ISELL = 0 */
207 reg_3 &= ~0x3;
208 break;
209
210 case SEC_CURRENT_515m:
211 /* 515mA */
212 /* ISELH = 0, ISELL = 1 */
213 reg_3 &= ~0x2;
214 reg_3 |= 0x1;
215 break;
216
217 case SEC_CURRENT_635m:
218 /* 635mA */
219 /* ISELH = 1, ISELL = 0 */
220 reg_3 &= ~0x1;
221 reg_3 |= 0x2;
222 break;
223
224 case SEC_CURRENT_800m:
225 /* 800mA */
226 /* ISELH = 1, ISELL = 1 */
227 reg_3 |= 0x3;
228 break;
229 }
230
231 err = isl6423_write(isl6423, reg_3);
232 if (err < 0)
233 goto exit;
234
235 switch (config->curlim) {
236 case SEC_CURRENT_LIM_ON:
237 /* DCL = 0 */
238 reg_3 &= ~0x10;
239 break;
240
241 case SEC_CURRENT_LIM_OFF:
242 /* DCL = 1 */
243 reg_3 |= 0x10;
244 break;
245 }
246
247 err = isl6423_write(isl6423, reg_3);
248 if (err < 0)
249 goto exit;
250
251 isl6423->reg_3 = reg_3;
252
253 return 0;
254exit:
255 dprintk(FE_ERROR, 1, "I/O error <%d>", err);
256 return err;
257}
258
259static void isl6423_release(struct dvb_frontend *fe)
260{
261 isl6423_set_voltage(fe, SEC_VOLTAGE_OFF);
262
263 kfree(fe->sec_priv);
264 fe->sec_priv = NULL;
265}
266
267struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
268 struct i2c_adapter *i2c,
269 const struct isl6423_config *config)
270{
271 struct isl6423_dev *isl6423;
272
273 isl6423 = kzalloc(sizeof(struct isl6423_dev), GFP_KERNEL);
274 if (!isl6423)
275 return NULL;
276
277 isl6423->config = config;
278 isl6423->i2c = i2c;
279 fe->sec_priv = isl6423;
280
281 /* SR3H = 0, SR3M = 1, SR3L = 0 */
282 isl6423->reg_3 = 0x02 << 5;
283 /* SR4H = 0, SR4M = 1, SR4L = 1 */
284 isl6423->reg_4 = 0x03 << 5;
285
286 if (isl6423_set_current(fe))
287 goto exit;
288
289 if (isl6423_set_modulation(fe))
290 goto exit;
291
292 fe->ops.release_sec = isl6423_release;
293 fe->ops.set_voltage = isl6423_set_voltage;
294 fe->ops.enable_high_lnb_voltage = isl6423_voltage_boost;
295 isl6423->verbose = verbose;
296
297 return fe;
298
299exit:
300 kfree(isl6423);
301 fe->sec_priv = NULL;
302 return NULL;
303}
304EXPORT_SYMBOL(isl6423_attach);
305
306MODULE_DESCRIPTION("ISL6423 SEC");
307MODULE_AUTHOR("Manu Abraham");
308MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/isl6423.h b/drivers/media/dvb/frontends/isl6423.h
new file mode 100644
index 00000000000..e1a37fba01c
--- /dev/null
+++ b/drivers/media/dvb/frontends/isl6423.h
@@ -0,0 +1,63 @@
1/*
2 Intersil ISL6423 SEC and LNB Power supply controller
3
4 Copyright (C) Manu Abraham <abraham.manu@gmail.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 __ISL_6423_H
22#define __ISL_6423_H
23
24#include <linux/dvb/frontend.h>
25
26enum isl6423_current {
27 SEC_CURRENT_275m = 0,
28 SEC_CURRENT_515m,
29 SEC_CURRENT_635m,
30 SEC_CURRENT_800m,
31};
32
33enum isl6423_curlim {
34 SEC_CURRENT_LIM_ON = 1,
35 SEC_CURRENT_LIM_OFF
36};
37
38struct isl6423_config {
39 enum isl6423_current current_max;
40 enum isl6423_curlim curlim;
41 u8 addr;
42 u8 mod_extern;
43};
44
45#if defined(CONFIG_DVB_ISL6423) || (defined(CONFIG_DVB_ISL6423_MODULE) && defined(MODULE))
46
47
48extern struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
49 struct i2c_adapter *i2c,
50 const struct isl6423_config *config);
51
52#else
53static inline struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
54 struct i2c_adapter *i2c,
55 const struct isl6423_config *config)
56{
57 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
58 return NULL;
59}
60
61#endif /* CONFIG_DVB_ISL6423 */
62
63#endif /* __ISL_6423_H */
diff --git a/drivers/media/dvb/frontends/itd1000.c b/drivers/media/dvb/frontends/itd1000.c
new file mode 100644
index 00000000000..aa9ccb821fa
--- /dev/null
+++ b/drivers/media/dvb/frontends/itd1000.c
@@ -0,0 +1,398 @@
1/*
2 * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
3 *
4 * Copyright (c) 2007-8 Patrick Boettcher <pb@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 as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/delay.h>
25#include <linux/dvb/frontend.h>
26#include <linux/i2c.h>
27#include <linux/slab.h>
28
29#include "dvb_frontend.h"
30
31#include "itd1000.h"
32#include "itd1000_priv.h"
33
34static int debug;
35module_param(debug, int, 0644);
36MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
37
38#define itd_dbg(args...) do { \
39 if (debug) { \
40 printk(KERN_DEBUG "ITD1000: " args);\
41 } \
42} while (0)
43
44#define itd_warn(args...) do { \
45 printk(KERN_WARNING "ITD1000: " args); \
46} while (0)
47
48#define itd_info(args...) do { \
49 printk(KERN_INFO "ITD1000: " args); \
50} while (0)
51
52/* don't write more than one byte with flexcop behind */
53static int itd1000_write_regs(struct itd1000_state *state, u8 reg, u8 v[], u8 len)
54{
55 u8 buf[1+len];
56 struct i2c_msg msg = {
57 .addr = state->cfg->i2c_address, .flags = 0, .buf = buf, .len = len+1
58 };
59 buf[0] = reg;
60 memcpy(&buf[1], v, len);
61
62 /* itd_dbg("wr %02x: %02x\n", reg, v[0]); */
63
64 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
65 printk(KERN_WARNING "itd1000 I2C write failed\n");
66 return -EREMOTEIO;
67 }
68 return 0;
69}
70
71static int itd1000_read_reg(struct itd1000_state *state, u8 reg)
72{
73 u8 val;
74 struct i2c_msg msg[2] = {
75 { .addr = state->cfg->i2c_address, .flags = 0, .buf = &reg, .len = 1 },
76 { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = &val, .len = 1 },
77 };
78
79 /* ugly flexcop workaround */
80 itd1000_write_regs(state, (reg - 1) & 0xff, &state->shadow[(reg - 1) & 0xff], 1);
81
82 if (i2c_transfer(state->i2c, msg, 2) != 2) {
83 itd_warn("itd1000 I2C read failed\n");
84 return -EREMOTEIO;
85 }
86 return val;
87}
88
89static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v)
90{
91 int ret = itd1000_write_regs(state, r, &v, 1);
92 state->shadow[r] = v;
93 return ret;
94}
95
96
97static struct {
98 u32 symbol_rate;
99 u8 pgaext : 4; /* PLLFH */
100 u8 bbgvmin : 4; /* BBGVMIN */
101} itd1000_lpf_pga[] = {
102 { 0, 0x8, 0x3 },
103 { 5200000, 0x8, 0x3 },
104 { 12200000, 0x4, 0x3 },
105 { 15400000, 0x2, 0x3 },
106 { 19800000, 0x2, 0x3 },
107 { 21500000, 0x2, 0x3 },
108 { 24500000, 0x2, 0x3 },
109 { 28400000, 0x2, 0x3 },
110 { 33400000, 0x2, 0x3 },
111 { 34400000, 0x1, 0x4 },
112 { 34400000, 0x1, 0x4 },
113 { 38400000, 0x1, 0x4 },
114 { 38400000, 0x1, 0x4 },
115 { 40400000, 0x1, 0x4 },
116 { 45400000, 0x1, 0x4 },
117};
118
119static void itd1000_set_lpf_bw(struct itd1000_state *state, u32 symbol_rate)
120{
121 u8 i;
122 u8 con1 = itd1000_read_reg(state, CON1) & 0xfd;
123 u8 pllfh = itd1000_read_reg(state, PLLFH) & 0x0f;
124 u8 bbgvmin = itd1000_read_reg(state, BBGVMIN) & 0xf0;
125 u8 bw = itd1000_read_reg(state, BW) & 0xf0;
126
127 itd_dbg("symbol_rate = %d\n", symbol_rate);
128
129 /* not sure what is that ? - starting to download the table */
130 itd1000_write_reg(state, CON1, con1 | (1 << 1));
131
132 for (i = 0; i < ARRAY_SIZE(itd1000_lpf_pga); i++)
133 if (symbol_rate < itd1000_lpf_pga[i].symbol_rate) {
134 itd_dbg("symrate: index: %d pgaext: %x, bbgvmin: %x\n", i, itd1000_lpf_pga[i].pgaext, itd1000_lpf_pga[i].bbgvmin);
135 itd1000_write_reg(state, PLLFH, pllfh | (itd1000_lpf_pga[i].pgaext << 4));
136 itd1000_write_reg(state, BBGVMIN, bbgvmin | (itd1000_lpf_pga[i].bbgvmin));
137 itd1000_write_reg(state, BW, bw | (i & 0x0f));
138 break;
139 }
140
141 itd1000_write_reg(state, CON1, con1 | (0 << 1));
142}
143
144static struct {
145 u8 vcorg;
146 u32 fmax_rg;
147} itd1000_vcorg[] = {
148 { 1, 920000 },
149 { 2, 971000 },
150 { 3, 1031000 },
151 { 4, 1091000 },
152 { 5, 1171000 },
153 { 6, 1281000 },
154 { 7, 1381000 },
155 { 8, 500000 }, /* this is intentional. */
156 { 9, 1451000 },
157 { 10, 1531000 },
158 { 11, 1631000 },
159 { 12, 1741000 },
160 { 13, 1891000 },
161 { 14, 2071000 },
162 { 15, 2250000 },
163};
164
165static void itd1000_set_vco(struct itd1000_state *state, u32 freq_khz)
166{
167 u8 i;
168 u8 gvbb_i2c = itd1000_read_reg(state, GVBB_I2C) & 0xbf;
169 u8 vco_chp1_i2c = itd1000_read_reg(state, VCO_CHP1_I2C) & 0x0f;
170 u8 adcout;
171
172 /* reserved bit again (reset ?) */
173 itd1000_write_reg(state, GVBB_I2C, gvbb_i2c | (1 << 6));
174
175 for (i = 0; i < ARRAY_SIZE(itd1000_vcorg); i++) {
176 if (freq_khz < itd1000_vcorg[i].fmax_rg) {
177 itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | (itd1000_vcorg[i].vcorg << 4));
178 msleep(1);
179
180 adcout = itd1000_read_reg(state, PLLLOCK) & 0x0f;
181
182 itd_dbg("VCO: %dkHz: %d -> ADCOUT: %d %02x\n", freq_khz, itd1000_vcorg[i].vcorg, adcout, vco_chp1_i2c);
183
184 if (adcout > 13) {
185 if (!(itd1000_vcorg[i].vcorg == 7 || itd1000_vcorg[i].vcorg == 15))
186 itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg + 1) << 4));
187 } else if (adcout < 2) {
188 if (!(itd1000_vcorg[i].vcorg == 1 || itd1000_vcorg[i].vcorg == 9))
189 itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg - 1) << 4));
190 }
191 break;
192 }
193 }
194}
195
196static const struct {
197 u32 freq;
198 u8 values[10]; /* RFTR, RFST1 - RFST9 */
199} itd1000_fre_values[] = {
200 { 1075000, { 0x59, 0x1d, 0x1c, 0x17, 0x16, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
201 { 1250000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
202 { 1450000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
203 { 1650000, { 0x69, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
204 { 1750000, { 0x69, 0x1e, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
205 { 1850000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } },
206 { 1900000, { 0x69, 0x1d, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } },
207 { 1950000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0d, 0x0b, 0x0a } },
208 { 2050000, { 0x69, 0x1e, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0b, 0x0a } },
209 { 2150000, { 0x69, 0x1d, 0x1c, 0x17, 0x15, 0x14, 0x13, 0x0f, 0x0e, 0x0b } }
210};
211
212
213#define FREF 16
214
215static void itd1000_set_lo(struct itd1000_state *state, u32 freq_khz)
216{
217 int i, j;
218 u32 plln, pllf;
219 u64 tmp;
220
221 plln = (freq_khz * 1000) / 2 / FREF;
222
223 /* Compute the factional part times 1000 */
224 tmp = plln % 1000000;
225 plln /= 1000000;
226
227 tmp *= 1048576;
228 do_div(tmp, 1000000);
229 pllf = (u32) tmp;
230
231 state->frequency = ((plln * 1000) + (pllf * 1000)/1048576) * 2*FREF;
232 itd_dbg("frequency: %dkHz (wanted) %dkHz (set), PLLF = %d, PLLN = %d\n", freq_khz, state->frequency, pllf, plln);
233
234 itd1000_write_reg(state, PLLNH, 0x80); /* PLLNH */;
235 itd1000_write_reg(state, PLLNL, plln & 0xff);
236 itd1000_write_reg(state, PLLFH, (itd1000_read_reg(state, PLLFH) & 0xf0) | ((pllf >> 16) & 0x0f));
237 itd1000_write_reg(state, PLLFM, (pllf >> 8) & 0xff);
238 itd1000_write_reg(state, PLLFL, (pllf >> 0) & 0xff);
239
240 for (i = 0; i < ARRAY_SIZE(itd1000_fre_values); i++) {
241 if (freq_khz <= itd1000_fre_values[i].freq) {
242 itd_dbg("fre_values: %d\n", i);
243 itd1000_write_reg(state, RFTR, itd1000_fre_values[i].values[0]);
244 for (j = 0; j < 9; j++)
245 itd1000_write_reg(state, RFST1+j, itd1000_fre_values[i].values[j+1]);
246 break;
247 }
248 }
249
250 itd1000_set_vco(state, freq_khz);
251}
252
253static int itd1000_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
254{
255 struct itd1000_state *state = fe->tuner_priv;
256 u8 pllcon1;
257
258 itd1000_set_lo(state, p->frequency);
259 itd1000_set_lpf_bw(state, p->u.qpsk.symbol_rate);
260
261 pllcon1 = itd1000_read_reg(state, PLLCON1) & 0x7f;
262 itd1000_write_reg(state, PLLCON1, pllcon1 | (1 << 7));
263 itd1000_write_reg(state, PLLCON1, pllcon1);
264
265 return 0;
266}
267
268static int itd1000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
269{
270 struct itd1000_state *state = fe->tuner_priv;
271 *frequency = state->frequency;
272 return 0;
273}
274
275static int itd1000_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
276{
277 return 0;
278}
279
280static u8 itd1000_init_tab[][2] = {
281 { PLLCON1, 0x65 }, /* Register does not change */
282 { PLLNH, 0x80 }, /* Bits [7:6] do not change */
283 { RESERVED_0X6D, 0x3b },
284 { VCO_CHP2_I2C, 0x12 },
285 { 0x72, 0xf9 }, /* No such regsister defined */
286 { RESERVED_0X73, 0xff },
287 { RESERVED_0X74, 0xb2 },
288 { RESERVED_0X75, 0xc7 },
289 { EXTGVBBRF, 0xf0 },
290 { DIVAGCCK, 0x80 },
291 { BBTR, 0xa0 },
292 { RESERVED_0X7E, 0x4f },
293 { 0x82, 0x88 }, /* No such regsister defined */
294 { 0x83, 0x80 }, /* No such regsister defined */
295 { 0x84, 0x80 }, /* No such regsister defined */
296 { RESERVED_0X85, 0x74 },
297 { RESERVED_0X86, 0xff },
298 { RESERVED_0X88, 0x02 },
299 { RESERVED_0X89, 0x16 },
300 { RFST0, 0x1f },
301 { RESERVED_0X94, 0x66 },
302 { RESERVED_0X95, 0x66 },
303 { RESERVED_0X96, 0x77 },
304 { RESERVED_0X97, 0x99 },
305 { RESERVED_0X98, 0xff },
306 { RESERVED_0X99, 0xfc },
307 { RESERVED_0X9A, 0xba },
308 { RESERVED_0X9B, 0xaa },
309};
310
311static u8 itd1000_reinit_tab[][2] = {
312 { VCO_CHP1_I2C, 0x8a },
313 { BW, 0x87 },
314 { GVBB_I2C, 0x03 },
315 { BBGVMIN, 0x03 },
316 { CON1, 0x2e },
317};
318
319
320static int itd1000_init(struct dvb_frontend *fe)
321{
322 struct itd1000_state *state = fe->tuner_priv;
323 int i;
324
325 for (i = 0; i < ARRAY_SIZE(itd1000_init_tab); i++)
326 itd1000_write_reg(state, itd1000_init_tab[i][0], itd1000_init_tab[i][1]);
327
328 for (i = 0; i < ARRAY_SIZE(itd1000_reinit_tab); i++)
329 itd1000_write_reg(state, itd1000_reinit_tab[i][0], itd1000_reinit_tab[i][1]);
330
331 return 0;
332}
333
334static int itd1000_sleep(struct dvb_frontend *fe)
335{
336 return 0;
337}
338
339static int itd1000_release(struct dvb_frontend *fe)
340{
341 kfree(fe->tuner_priv);
342 fe->tuner_priv = NULL;
343 return 0;
344}
345
346static const struct dvb_tuner_ops itd1000_tuner_ops = {
347 .info = {
348 .name = "Integrant ITD1000",
349 .frequency_min = 950000,
350 .frequency_max = 2150000,
351 .frequency_step = 125, /* kHz for QPSK frontends */
352 },
353
354 .release = itd1000_release,
355
356 .init = itd1000_init,
357 .sleep = itd1000_sleep,
358
359 .set_params = itd1000_set_parameters,
360 .get_frequency = itd1000_get_frequency,
361 .get_bandwidth = itd1000_get_bandwidth
362};
363
364
365struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg)
366{
367 struct itd1000_state *state = NULL;
368 u8 i = 0;
369
370 state = kzalloc(sizeof(struct itd1000_state), GFP_KERNEL);
371 if (state == NULL)
372 return NULL;
373
374 state->cfg = cfg;
375 state->i2c = i2c;
376
377 i = itd1000_read_reg(state, 0);
378 if (i != 0) {
379 kfree(state);
380 return NULL;
381 }
382 itd_info("successfully identified (ID: %d)\n", i);
383
384 memset(state->shadow, 0xff, sizeof(state->shadow));
385 for (i = 0x65; i < 0x9c; i++)
386 state->shadow[i] = itd1000_read_reg(state, i);
387
388 memcpy(&fe->ops.tuner_ops, &itd1000_tuner_ops, sizeof(struct dvb_tuner_ops));
389
390 fe->tuner_priv = state;
391
392 return fe;
393}
394EXPORT_SYMBOL(itd1000_attach);
395
396MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>");
397MODULE_DESCRIPTION("Integrant ITD1000 driver");
398MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/itd1000.h b/drivers/media/dvb/frontends/itd1000.h
new file mode 100644
index 00000000000..5e18df071b8
--- /dev/null
+++ b/drivers/media/dvb/frontends/itd1000.h
@@ -0,0 +1,42 @@
1/*
2 * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
3 *
4 * Copyright (c) 2007 Patrick Boettcher <pb@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 as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#ifndef ITD1000_H
23#define ITD1000_H
24
25struct dvb_frontend;
26struct i2c_adapter;
27
28struct itd1000_config {
29 u8 i2c_address;
30};
31
32#if defined(CONFIG_DVB_TUNER_ITD1000) || (defined(CONFIG_DVB_TUNER_ITD1000_MODULE) && defined(MODULE))
33extern struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg);
34#else
35static inline struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg)
36{
37 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
38 return NULL;
39}
40#endif
41
42#endif
diff --git a/drivers/media/dvb/frontends/itd1000_priv.h b/drivers/media/dvb/frontends/itd1000_priv.h
new file mode 100644
index 00000000000..08ca851223c
--- /dev/null
+++ b/drivers/media/dvb/frontends/itd1000_priv.h
@@ -0,0 +1,88 @@
1/*
2 * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
3 *
4 * Copyright (c) 2007 Patrick Boettcher <pb@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 as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#ifndef ITD1000_PRIV_H
23#define ITD1000_PRIV_H
24
25struct itd1000_state {
26 struct itd1000_config *cfg;
27 struct i2c_adapter *i2c;
28
29 u32 frequency; /* contains the value resulting from the LO-setting */
30
31 /* ugly workaround for flexcop's incapable i2c-controller
32 * FIXME, if possible
33 */
34 u8 shadow[256];
35};
36
37enum itd1000_register {
38 VCO_CHP1 = 0x65,
39 VCO_CHP2,
40 PLLCON1,
41 PLLNH,
42 PLLNL,
43 PLLFH,
44 PLLFM,
45 PLLFL,
46 RESERVED_0X6D,
47 PLLLOCK,
48 VCO_CHP2_I2C,
49 VCO_CHP1_I2C,
50 BW,
51 RESERVED_0X73 = 0x73,
52 RESERVED_0X74,
53 RESERVED_0X75,
54 GVBB,
55 GVRF,
56 GVBB_I2C,
57 EXTGVBBRF,
58 DIVAGCCK,
59 BBTR,
60 RFTR,
61 BBGVMIN,
62 RESERVED_0X7E,
63 RESERVED_0X85 = 0x85,
64 RESERVED_0X86,
65 CON1,
66 RESERVED_0X88,
67 RESERVED_0X89,
68 RFST0,
69 RFST1,
70 RFST2,
71 RFST3,
72 RFST4,
73 RFST5,
74 RFST6,
75 RFST7,
76 RFST8,
77 RFST9,
78 RESERVED_0X94,
79 RESERVED_0X95,
80 RESERVED_0X96,
81 RESERVED_0X97,
82 RESERVED_0X98,
83 RESERVED_0X99,
84 RESERVED_0X9A,
85 RESERVED_0X9B,
86};
87
88#endif
diff --git a/drivers/media/dvb/frontends/ix2505v.c b/drivers/media/dvb/frontends/ix2505v.c
new file mode 100644
index 00000000000..9a517a4bf96
--- /dev/null
+++ b/drivers/media/dvb/frontends/ix2505v.c
@@ -0,0 +1,325 @@
1/**
2 * Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner
3 *
4 * Copyright (C) 2010 Malcolm Priestley
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 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * 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
21#include <linux/module.h>
22#include <linux/dvb/frontend.h>
23#include <linux/slab.h>
24#include <linux/types.h>
25
26#include "ix2505v.h"
27
28static int ix2505v_debug;
29#define dprintk(level, args...) do { \
30 if (ix2505v_debug & level) \
31 printk(KERN_DEBUG "ix2505v: " args); \
32} while (0)
33
34#define deb_info(args...) dprintk(0x01, args)
35#define deb_i2c(args...) dprintk(0x02, args)
36
37struct ix2505v_state {
38 struct i2c_adapter *i2c;
39 const struct ix2505v_config *config;
40 u32 frequency;
41};
42
43/**
44 * Data read format of the Sharp IX2505V B0017
45 *
46 * byte1: 1 | 1 | 0 | 0 | 0 | MA1 | MA0 | 1
47 * byte2: POR | FL | RD2 | RD1 | RD0 | X | X | X
48 *
49 * byte1 = address
50 * byte2;
51 * POR = Power on Reset (VCC H=<2.2v L=>2.2v)
52 * FL = Phase Lock (H=lock L=unlock)
53 * RD0-2 = Reserved internal operations
54 *
55 * Only POR can be used to check the tuner is present
56 *
57 * Caution: after byte2 the I2C reverts to write mode continuing to read
58 * may corrupt tuning data.
59 *
60 */
61
62static int ix2505v_read_status_reg(struct ix2505v_state *state)
63{
64 u8 addr = state->config->tuner_address;
65 u8 b2[] = {0};
66 int ret;
67
68 struct i2c_msg msg[1] = {
69 { .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 }
70 };
71
72 ret = i2c_transfer(state->i2c, msg, 1);
73 deb_i2c("Read %s ", __func__);
74
75 return (ret == 1) ? (int) b2[0] : -1;
76}
77
78static int ix2505v_write(struct ix2505v_state *state, u8 buf[], u8 count)
79{
80 struct i2c_msg msg[1] = {
81 { .addr = state->config->tuner_address, .flags = 0,
82 .buf = buf, .len = count },
83 };
84
85 int ret;
86
87 ret = i2c_transfer(state->i2c, msg, 1);
88
89 if (ret != 1) {
90 deb_i2c("%s: i2c error, ret=%d\n", __func__, ret);
91 return -EIO;
92 }
93
94 return 0;
95}
96
97static int ix2505v_release(struct dvb_frontend *fe)
98{
99 struct ix2505v_state *state = fe->tuner_priv;
100
101 fe->tuner_priv = NULL;
102 kfree(state);
103
104 return 0;
105}
106
107/**
108 * Data write format of the Sharp IX2505V B0017
109 *
110 * byte1: 1 | 1 | 0 | 0 | 0 | 0(MA1)| 0(MA0)| 0
111 * byte2: 0 | BG1 | BG2 | N8 | N7 | N6 | N5 | N4
112 * byte3: N3 | N2 | N1 | A5 | A4 | A3 | A2 | A1
113 * byte4: 1 | 1(C1) | 1(C0) | PD5 | PD4 | TM | 0(RTS)| 1(REF)
114 * byte5: BA2 | BA1 | BA0 | PSC | PD3 |PD2/TS2|DIV/TS1|PD0/TS0
115 *
116 * byte1 = address
117 *
118 * Write order
119 * 1) byte1 -> byte2 -> byte3 -> byte4 -> byte5
120 * 2) byte1 -> byte4 -> byte5 -> byte2 -> byte3
121 * 3) byte1 -> byte2 -> byte3 -> byte4
122 * 4) byte1 -> byte4 -> byte5 -> byte2
123 * 5) byte1 -> byte2 -> byte3
124 * 6) byte1 -> byte4 -> byte5
125 * 7) byte1 -> byte2
126 * 8) byte1 -> byte4
127 *
128 * Recommended Setup
129 * 1 -> 8 -> 6
130 */
131
132static int ix2505v_set_params(struct dvb_frontend *fe,
133 struct dvb_frontend_parameters *params)
134{
135 struct ix2505v_state *state = fe->tuner_priv;
136 u32 frequency = params->frequency;
137 u32 b_w = (params->u.qpsk.symbol_rate * 27) / 32000;
138 u32 div_factor, N , A, x;
139 int ret = 0, len;
140 u8 gain, cc, ref, psc, local_osc, lpf;
141 u8 data[4] = {0};
142
143 if ((frequency < fe->ops.info.frequency_min)
144 || (frequency > fe->ops.info.frequency_max))
145 return -EINVAL;
146
147 if (state->config->tuner_gain)
148 gain = (state->config->tuner_gain < 4)
149 ? state->config->tuner_gain : 0;
150 else
151 gain = 0x0;
152
153 if (state->config->tuner_chargepump)
154 cc = state->config->tuner_chargepump;
155 else
156 cc = 0x3;
157
158 ref = 8; /* REF =1 */
159 psc = 32; /* PSC = 0 */
160
161 div_factor = (frequency * ref) / 40; /* local osc = 4Mhz */
162 x = div_factor / psc;
163 N = x/100;
164 A = ((x - (N * 100)) * psc) / 100;
165
166 data[0] = ((gain & 0x3) << 5) | (N >> 3);
167 data[1] = (N << 5) | (A & 0x1f);
168 data[2] = 0x81 | ((cc & 0x3) << 5) ; /*PD5,PD4 & TM = 0|C1,C0|REF=1*/
169
170 deb_info("Frq=%d x=%d N=%d A=%d\n", frequency, x, N, A);
171
172 if (frequency <= 1065000)
173 local_osc = (6 << 5) | 2;
174 else if (frequency <= 1170000)
175 local_osc = (7 << 5) | 2;
176 else if (frequency <= 1300000)
177 local_osc = (1 << 5);
178 else if (frequency <= 1445000)
179 local_osc = (2 << 5);
180 else if (frequency <= 1607000)
181 local_osc = (3 << 5);
182 else if (frequency <= 1778000)
183 local_osc = (4 << 5);
184 else if (frequency <= 1942000)
185 local_osc = (5 << 5);
186 else /*frequency up to 2150000*/
187 local_osc = (6 << 5);
188
189 data[3] = local_osc; /* all other bits set 0 */
190
191 if (b_w <= 10000)
192 lpf = 0xc;
193 else if (b_w <= 12000)
194 lpf = 0x2;
195 else if (b_w <= 14000)
196 lpf = 0xa;
197 else if (b_w <= 16000)
198 lpf = 0x6;
199 else if (b_w <= 18000)
200 lpf = 0xe;
201 else if (b_w <= 20000)
202 lpf = 0x1;
203 else if (b_w <= 22000)
204 lpf = 0x9;
205 else if (b_w <= 24000)
206 lpf = 0x5;
207 else if (b_w <= 26000)
208 lpf = 0xd;
209 else if (b_w <= 28000)
210 lpf = 0x3;
211 else
212 lpf = 0xb;
213
214 deb_info("Osc=%x b_w=%x lpf=%x\n", local_osc, b_w, lpf);
215 deb_info("Data 0=[%x%x%x%x]\n", data[0], data[1], data[2], data[3]);
216
217 if (fe->ops.i2c_gate_ctrl)
218 fe->ops.i2c_gate_ctrl(fe, 1);
219
220 len = sizeof(data);
221 ret |= ix2505v_write(state, data, len);
222
223 data[2] |= 0x4; /* set TM = 1 other bits same */
224
225 if (fe->ops.i2c_gate_ctrl)
226 fe->ops.i2c_gate_ctrl(fe, 1);
227
228 len = 1;
229 ret |= ix2505v_write(state, &data[2], len); /* write byte 4 only */
230
231 msleep(10);
232
233 data[2] |= ((lpf >> 2) & 0x3) << 3; /* lpf */
234 data[3] |= (lpf & 0x3) << 2;
235
236 deb_info("Data 2=[%x%x]\n", data[2], data[3]);
237
238 if (fe->ops.i2c_gate_ctrl)
239 fe->ops.i2c_gate_ctrl(fe, 1);
240
241 len = 2;
242 ret |= ix2505v_write(state, &data[2], len); /* write byte 4 & 5 */
243
244 if (state->config->min_delay_ms)
245 msleep(state->config->min_delay_ms);
246
247 state->frequency = frequency;
248
249 return ret;
250}
251
252static int ix2505v_get_frequency(struct dvb_frontend *fe, u32 *frequency)
253{
254 struct ix2505v_state *state = fe->tuner_priv;
255
256 *frequency = state->frequency;
257
258 return 0;
259}
260
261static struct dvb_tuner_ops ix2505v_tuner_ops = {
262 .info = {
263 .name = "Sharp IX2505V (B0017)",
264 .frequency_min = 950000,
265 .frequency_max = 2175000
266 },
267 .release = ix2505v_release,
268 .set_params = ix2505v_set_params,
269 .get_frequency = ix2505v_get_frequency,
270};
271
272struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
273 const struct ix2505v_config *config,
274 struct i2c_adapter *i2c)
275{
276 struct ix2505v_state *state = NULL;
277 int ret;
278
279 if (NULL == config) {
280 deb_i2c("%s: no config ", __func__);
281 goto error;
282 }
283
284 state = kzalloc(sizeof(struct ix2505v_state), GFP_KERNEL);
285 if (NULL == state)
286 return NULL;
287
288 state->config = config;
289 state->i2c = i2c;
290
291 if (state->config->tuner_write_only) {
292 if (fe->ops.i2c_gate_ctrl)
293 fe->ops.i2c_gate_ctrl(fe, 1);
294
295 ret = ix2505v_read_status_reg(state);
296
297 if (ret & 0x80) {
298 deb_i2c("%s: No IX2505V found\n", __func__);
299 goto error;
300 }
301
302 if (fe->ops.i2c_gate_ctrl)
303 fe->ops.i2c_gate_ctrl(fe, 0);
304 }
305
306 fe->tuner_priv = state;
307
308 memcpy(&fe->ops.tuner_ops, &ix2505v_tuner_ops,
309 sizeof(struct dvb_tuner_ops));
310 deb_i2c("%s: initialization (%s addr=0x%02x) ok\n",
311 __func__, fe->ops.tuner_ops.info.name, config->tuner_address);
312
313 return fe;
314
315error:
316 kfree(state);
317 return NULL;
318}
319EXPORT_SYMBOL(ix2505v_attach);
320
321module_param_named(debug, ix2505v_debug, int, 0644);
322MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
323MODULE_DESCRIPTION("DVB IX2505V tuner driver");
324MODULE_AUTHOR("Malcolm Priestley");
325MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/ix2505v.h b/drivers/media/dvb/frontends/ix2505v.h
new file mode 100644
index 00000000000..67e89d616d5
--- /dev/null
+++ b/drivers/media/dvb/frontends/ix2505v.h
@@ -0,0 +1,64 @@
1/**
2 * Driver for Sharp IX2505V (marked B0017) DVB-S silicon tuner
3 *
4 * Copyright (C) 2010 Malcolm Priestley
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 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * 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 DVB_IX2505V_H
21#define DVB_IX2505V_H
22
23#include <linux/i2c.h>
24#include "dvb_frontend.h"
25
26/**
27 * Attach a ix2505v tuner to the supplied frontend structure.
28 *
29 * @param fe Frontend to attach to.
30 * @param config ix2505v_config structure
31 * @return FE pointer on success, NULL on failure.
32 */
33
34struct ix2505v_config {
35 u8 tuner_address;
36
37 /*Baseband AMP gain control 0/1=0dB(default) 2=-2bB 3=-4dB */
38 u8 tuner_gain;
39
40 /*Charge pump output +/- 0=120 1=260 2=555 3=1200(default) */
41 u8 tuner_chargepump;
42
43 /* delay after tune */
44 int min_delay_ms;
45
46 /* disables reads*/
47 u8 tuner_write_only;
48
49};
50
51#if defined(CONFIG_DVB_IX2505V) || \
52 (defined(CONFIG_DVB_IX2505V_MODULE) && defined(MODULE))
53extern struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
54 const struct ix2505v_config *config, struct i2c_adapter *i2c);
55#else
56static inline struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
57 const struct ix2505v_config *config, struct i2c_adapter *i2c)
58{
59 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
60 return NULL;
61}
62#endif
63
64#endif /* DVB_IX2505V_H */
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
new file mode 100644
index 00000000000..445fa106806
--- /dev/null
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -0,0 +1,602 @@
1/*
2 driver for LSI L64781 COFDM demodulator
3
4 Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
5 Marko Kohtala <marko.kohtala@luukku.com>
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/init.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28#include "dvb_frontend.h"
29#include "l64781.h"
30
31
32struct l64781_state {
33 struct i2c_adapter* i2c;
34 const struct l64781_config* config;
35 struct dvb_frontend frontend;
36
37 /* private demodulator data */
38 unsigned int first:1;
39};
40
41#define dprintk(args...) \
42 do { \
43 if (debug) printk(KERN_DEBUG "l64781: " args); \
44 } while (0)
45
46static int debug;
47
48module_param(debug, int, 0644);
49MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
50
51
52static int l64781_writereg (struct l64781_state* state, u8 reg, u8 data)
53{
54 int ret;
55 u8 buf [] = { reg, data };
56 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
57
58 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
59 dprintk ("%s: write_reg error (reg == %02x) = %02x!\n",
60 __func__, reg, ret);
61
62 return (ret != 1) ? -1 : 0;
63}
64
65static int l64781_readreg (struct l64781_state* state, u8 reg)
66{
67 int ret;
68 u8 b0 [] = { reg };
69 u8 b1 [] = { 0 };
70 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
71 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
72
73 ret = i2c_transfer(state->i2c, msg, 2);
74
75 if (ret != 2) return ret;
76
77 return b1[0];
78}
79
80static void apply_tps (struct l64781_state* state)
81{
82 l64781_writereg (state, 0x2a, 0x00);
83 l64781_writereg (state, 0x2a, 0x01);
84
85 /* This here is a little bit questionable because it enables
86 the automatic update of TPS registers. I think we'd need to
87 handle the IRQ from FE to update some other registers as
88 well, or at least implement some magic to tuning to correct
89 to the TPS received from transmission. */
90 l64781_writereg (state, 0x2a, 0x02);
91}
92
93
94static void reset_afc (struct l64781_state* state)
95{
96 /* Set AFC stall for the AFC_INIT_FRQ setting, TIM_STALL for
97 timing offset */
98 l64781_writereg (state, 0x07, 0x9e); /* stall AFC */
99 l64781_writereg (state, 0x08, 0); /* AFC INIT FREQ */
100 l64781_writereg (state, 0x09, 0);
101 l64781_writereg (state, 0x0a, 0);
102 l64781_writereg (state, 0x07, 0x8e);
103 l64781_writereg (state, 0x0e, 0); /* AGC gain to zero in beginning */
104 l64781_writereg (state, 0x11, 0x80); /* stall TIM */
105 l64781_writereg (state, 0x10, 0); /* TIM_OFFSET_LSB */
106 l64781_writereg (state, 0x12, 0);
107 l64781_writereg (state, 0x13, 0);
108 l64781_writereg (state, 0x11, 0x00);
109}
110
111static int reset_and_configure (struct l64781_state* state)
112{
113 u8 buf [] = { 0x06 };
114 struct i2c_msg msg = { .addr = 0x00, .flags = 0, .buf = buf, .len = 1 };
115 // NOTE: this is correct in writing to address 0x00
116
117 return (i2c_transfer(state->i2c, &msg, 1) == 1) ? 0 : -ENODEV;
118}
119
120static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_parameters *param)
121{
122 struct l64781_state* state = fe->demodulator_priv;
123 /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */
124 static const u8 fec_tab[] = { 7, 0, 1, 2, 9, 3, 10, 4 };
125 /* QPSK, QAM_16, QAM_64 */
126 static const u8 qam_tab [] = { 2, 4, 0, 6 };
127 static const u8 bw_tab [] = { 8, 7, 6 }; /* 8Mhz, 7MHz, 6MHz */
128 static const u8 guard_tab [] = { 1, 2, 4, 8 };
129 /* The Grundig 29504-401.04 Tuner comes with 18.432MHz crystal. */
130 static const u32 ppm = 8000;
131 struct dvb_ofdm_parameters *p = &param->u.ofdm;
132 u32 ddfs_offset_fixed;
133/* u32 ddfs_offset_variable = 0x6000-((1000000UL+ppm)/ */
134/* bw_tab[p->bandWidth]<<10)/15625; */
135 u32 init_freq;
136 u32 spi_bias;
137 u8 val0x04;
138 u8 val0x05;
139 u8 val0x06;
140 int bw = p->bandwidth - BANDWIDTH_8_MHZ;
141
142 if (fe->ops.tuner_ops.set_params) {
143 fe->ops.tuner_ops.set_params(fe, param);
144 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
145 }
146
147 if (param->inversion != INVERSION_ON &&
148 param->inversion != INVERSION_OFF)
149 return -EINVAL;
150
151 if (bw < 0 || bw > 2)
152 return -EINVAL;
153
154 if (p->code_rate_HP != FEC_1_2 && p->code_rate_HP != FEC_2_3 &&
155 p->code_rate_HP != FEC_3_4 && p->code_rate_HP != FEC_5_6 &&
156 p->code_rate_HP != FEC_7_8)
157 return -EINVAL;
158
159 if (p->hierarchy_information != HIERARCHY_NONE &&
160 (p->code_rate_LP != FEC_1_2 && p->code_rate_LP != FEC_2_3 &&
161 p->code_rate_LP != FEC_3_4 && p->code_rate_LP != FEC_5_6 &&
162 p->code_rate_LP != FEC_7_8))
163 return -EINVAL;
164
165 if (p->constellation != QPSK && p->constellation != QAM_16 &&
166 p->constellation != QAM_64)
167 return -EINVAL;
168
169 if (p->transmission_mode != TRANSMISSION_MODE_2K &&
170 p->transmission_mode != TRANSMISSION_MODE_8K)
171 return -EINVAL;
172
173 if (p->guard_interval < GUARD_INTERVAL_1_32 ||
174 p->guard_interval > GUARD_INTERVAL_1_4)
175 return -EINVAL;
176
177 if (p->hierarchy_information < HIERARCHY_NONE ||
178 p->hierarchy_information > HIERARCHY_4)
179 return -EINVAL;
180
181 ddfs_offset_fixed = 0x4000-(ppm<<16)/bw_tab[p->bandwidth]/1000000;
182
183 /* This works up to 20000 ppm, it overflows if too large ppm! */
184 init_freq = (((8UL<<25) + (8UL<<19) / 25*ppm / (15625/25)) /
185 bw_tab[p->bandwidth] & 0xFFFFFF);
186
187 /* SPI bias calculation is slightly modified to fit in 32bit */
188 /* will work for high ppm only... */
189 spi_bias = 378 * (1 << 10);
190 spi_bias *= 16;
191 spi_bias *= bw_tab[p->bandwidth];
192 spi_bias *= qam_tab[p->constellation];
193 spi_bias /= p->code_rate_HP + 1;
194 spi_bias /= (guard_tab[p->guard_interval] + 32);
195 spi_bias *= 1000;
196 spi_bias /= 1000 + ppm/1000;
197 spi_bias *= p->code_rate_HP;
198
199 val0x04 = (p->transmission_mode << 2) | p->guard_interval;
200 val0x05 = fec_tab[p->code_rate_HP];
201
202 if (p->hierarchy_information != HIERARCHY_NONE)
203 val0x05 |= (p->code_rate_LP - FEC_1_2) << 3;
204
205 val0x06 = (p->hierarchy_information << 2) | p->constellation;
206
207 l64781_writereg (state, 0x04, val0x04);
208 l64781_writereg (state, 0x05, val0x05);
209 l64781_writereg (state, 0x06, val0x06);
210
211 reset_afc (state);
212
213 /* Technical manual section 2.6.1, TIM_IIR_GAIN optimal values */
214 l64781_writereg (state, 0x15,
215 p->transmission_mode == TRANSMISSION_MODE_2K ? 1 : 3);
216 l64781_writereg (state, 0x16, init_freq & 0xff);
217 l64781_writereg (state, 0x17, (init_freq >> 8) & 0xff);
218 l64781_writereg (state, 0x18, (init_freq >> 16) & 0xff);
219
220 l64781_writereg (state, 0x1b, spi_bias & 0xff);
221 l64781_writereg (state, 0x1c, (spi_bias >> 8) & 0xff);
222 l64781_writereg (state, 0x1d, ((spi_bias >> 16) & 0x7f) |
223 (param->inversion == INVERSION_ON ? 0x80 : 0x00));
224
225 l64781_writereg (state, 0x22, ddfs_offset_fixed & 0xff);
226 l64781_writereg (state, 0x23, (ddfs_offset_fixed >> 8) & 0x3f);
227
228 l64781_readreg (state, 0x00); /* clear interrupt registers... */
229 l64781_readreg (state, 0x01); /* dto. */
230
231 apply_tps (state);
232
233 return 0;
234}
235
236static int get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* param)
237{
238 struct l64781_state* state = fe->demodulator_priv;
239 int tmp;
240
241
242 tmp = l64781_readreg(state, 0x04);
243 switch(tmp & 3) {
244 case 0:
245 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
246 break;
247 case 1:
248 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
249 break;
250 case 2:
251 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
252 break;
253 case 3:
254 param->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
255 break;
256 }
257 switch((tmp >> 2) & 3) {
258 case 0:
259 param->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
260 break;
261 case 1:
262 param->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
263 break;
264 default:
265 printk("Unexpected value for transmission_mode\n");
266 }
267
268
269
270 tmp = l64781_readreg(state, 0x05);
271 switch(tmp & 7) {
272 case 0:
273 param->u.ofdm.code_rate_HP = FEC_1_2;
274 break;
275 case 1:
276 param->u.ofdm.code_rate_HP = FEC_2_3;
277 break;
278 case 2:
279 param->u.ofdm.code_rate_HP = FEC_3_4;
280 break;
281 case 3:
282 param->u.ofdm.code_rate_HP = FEC_5_6;
283 break;
284 case 4:
285 param->u.ofdm.code_rate_HP = FEC_7_8;
286 break;
287 default:
288 printk("Unexpected value for code_rate_HP\n");
289 }
290 switch((tmp >> 3) & 7) {
291 case 0:
292 param->u.ofdm.code_rate_LP = FEC_1_2;
293 break;
294 case 1:
295 param->u.ofdm.code_rate_LP = FEC_2_3;
296 break;
297 case 2:
298 param->u.ofdm.code_rate_LP = FEC_3_4;
299 break;
300 case 3:
301 param->u.ofdm.code_rate_LP = FEC_5_6;
302 break;
303 case 4:
304 param->u.ofdm.code_rate_LP = FEC_7_8;
305 break;
306 default:
307 printk("Unexpected value for code_rate_LP\n");
308 }
309
310
311 tmp = l64781_readreg(state, 0x06);
312 switch(tmp & 3) {
313 case 0:
314 param->u.ofdm.constellation = QPSK;
315 break;
316 case 1:
317 param->u.ofdm.constellation = QAM_16;
318 break;
319 case 2:
320 param->u.ofdm.constellation = QAM_64;
321 break;
322 default:
323 printk("Unexpected value for constellation\n");
324 }
325 switch((tmp >> 2) & 7) {
326 case 0:
327 param->u.ofdm.hierarchy_information = HIERARCHY_NONE;
328 break;
329 case 1:
330 param->u.ofdm.hierarchy_information = HIERARCHY_1;
331 break;
332 case 2:
333 param->u.ofdm.hierarchy_information = HIERARCHY_2;
334 break;
335 case 3:
336 param->u.ofdm.hierarchy_information = HIERARCHY_4;
337 break;
338 default:
339 printk("Unexpected value for hierarchy\n");
340 }
341
342
343 tmp = l64781_readreg (state, 0x1d);
344 param->inversion = (tmp & 0x80) ? INVERSION_ON : INVERSION_OFF;
345
346 tmp = (int) (l64781_readreg (state, 0x08) |
347 (l64781_readreg (state, 0x09) << 8) |
348 (l64781_readreg (state, 0x0a) << 16));
349 param->frequency += tmp;
350
351 return 0;
352}
353
354static int l64781_read_status(struct dvb_frontend* fe, fe_status_t* status)
355{
356 struct l64781_state* state = fe->demodulator_priv;
357 int sync = l64781_readreg (state, 0x32);
358 int gain = l64781_readreg (state, 0x0e);
359
360 l64781_readreg (state, 0x00); /* clear interrupt registers... */
361 l64781_readreg (state, 0x01); /* dto. */
362
363 *status = 0;
364
365 if (gain > 5)
366 *status |= FE_HAS_SIGNAL;
367
368 if (sync & 0x02) /* VCXO locked, this criteria should be ok */
369 *status |= FE_HAS_CARRIER;
370
371 if (sync & 0x20)
372 *status |= FE_HAS_VITERBI;
373
374 if (sync & 0x40)
375 *status |= FE_HAS_SYNC;
376
377 if (sync == 0x7f)
378 *status |= FE_HAS_LOCK;
379
380 return 0;
381}
382
383static int l64781_read_ber(struct dvb_frontend* fe, u32* ber)
384{
385 struct l64781_state* state = fe->demodulator_priv;
386
387 /* XXX FIXME: set up counting period (reg 0x26...0x28)
388 */
389 *ber = l64781_readreg (state, 0x39)
390 | (l64781_readreg (state, 0x3a) << 8);
391
392 return 0;
393}
394
395static int l64781_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
396{
397 struct l64781_state* state = fe->demodulator_priv;
398
399 u8 gain = l64781_readreg (state, 0x0e);
400 *signal_strength = (gain << 8) | gain;
401
402 return 0;
403}
404
405static int l64781_read_snr(struct dvb_frontend* fe, u16* snr)
406{
407 struct l64781_state* state = fe->demodulator_priv;
408
409 u8 avg_quality = 0xff - l64781_readreg (state, 0x33);
410 *snr = (avg_quality << 8) | avg_quality; /* not exact, but...*/
411
412 return 0;
413}
414
415static int l64781_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
416{
417 struct l64781_state* state = fe->demodulator_priv;
418
419 *ucblocks = l64781_readreg (state, 0x37)
420 | (l64781_readreg (state, 0x38) << 8);
421
422 return 0;
423}
424
425static int l64781_sleep(struct dvb_frontend* fe)
426{
427 struct l64781_state* state = fe->demodulator_priv;
428
429 /* Power down */
430 return l64781_writereg (state, 0x3e, 0x5a);
431}
432
433static int l64781_init(struct dvb_frontend* fe)
434{
435 struct l64781_state* state = fe->demodulator_priv;
436
437 reset_and_configure (state);
438
439 /* Power up */
440 l64781_writereg (state, 0x3e, 0xa5);
441
442 /* Reset hard */
443 l64781_writereg (state, 0x2a, 0x04);
444 l64781_writereg (state, 0x2a, 0x00);
445
446 /* Set tuner specific things */
447 /* AFC_POL, set also in reset_afc */
448 l64781_writereg (state, 0x07, 0x8e);
449
450 /* Use internal ADC */
451 l64781_writereg (state, 0x0b, 0x81);
452
453 /* AGC loop gain, and polarity is positive */
454 l64781_writereg (state, 0x0c, 0x84);
455
456 /* Internal ADC outputs two's complement */
457 l64781_writereg (state, 0x0d, 0x8c);
458
459 /* With ppm=8000, it seems the DTR_SENSITIVITY will result in
460 value of 2 with all possible bandwidths and guard
461 intervals, which is the initial value anyway. */
462 /*l64781_writereg (state, 0x19, 0x92);*/
463
464 /* Everything is two's complement, soft bit and CSI_OUT too */
465 l64781_writereg (state, 0x1e, 0x09);
466
467 /* delay a bit after first init attempt */
468 if (state->first) {
469 state->first = 0;
470 msleep(200);
471 }
472
473 return 0;
474}
475
476static int l64781_get_tune_settings(struct dvb_frontend* fe,
477 struct dvb_frontend_tune_settings* fesettings)
478{
479 fesettings->min_delay_ms = 4000;
480 fesettings->step_size = 0;
481 fesettings->max_drift = 0;
482 return 0;
483}
484
485static void l64781_release(struct dvb_frontend* fe)
486{
487 struct l64781_state* state = fe->demodulator_priv;
488 kfree(state);
489}
490
491static struct dvb_frontend_ops l64781_ops;
492
493struct dvb_frontend* l64781_attach(const struct l64781_config* config,
494 struct i2c_adapter* i2c)
495{
496 struct l64781_state* state = NULL;
497 int reg0x3e = -1;
498 u8 b0 [] = { 0x1a };
499 u8 b1 [] = { 0x00 };
500 struct i2c_msg msg [] = { { .addr = config->demod_address, .flags = 0, .buf = b0, .len = 1 },
501 { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
502
503 /* allocate memory for the internal state */
504 state = kzalloc(sizeof(struct l64781_state), GFP_KERNEL);
505 if (state == NULL) goto error;
506
507 /* setup the state */
508 state->config = config;
509 state->i2c = i2c;
510 state->first = 1;
511
512 /**
513 * the L64781 won't show up before we send the reset_and_configure()
514 * broadcast. If nothing responds there is no L64781 on the bus...
515 */
516 if (reset_and_configure(state) < 0) {
517 dprintk("No response to reset and configure broadcast...\n");
518 goto error;
519 }
520
521 /* The chip always responds to reads */
522 if (i2c_transfer(state->i2c, msg, 2) != 2) {
523 dprintk("No response to read on I2C bus\n");
524 goto error;
525 }
526
527 /* Save current register contents for bailout */
528 reg0x3e = l64781_readreg(state, 0x3e);
529
530 /* Reading the POWER_DOWN register always returns 0 */
531 if (reg0x3e != 0) {
532 dprintk("Device doesn't look like L64781\n");
533 goto error;
534 }
535
536 /* Turn the chip off */
537 l64781_writereg (state, 0x3e, 0x5a);
538
539 /* Responds to all reads with 0 */
540 if (l64781_readreg(state, 0x1a) != 0) {
541 dprintk("Read 1 returned unexpcted value\n");
542 goto error;
543 }
544
545 /* Turn the chip on */
546 l64781_writereg (state, 0x3e, 0xa5);
547
548 /* Responds with register default value */
549 if (l64781_readreg(state, 0x1a) != 0xa1) {
550 dprintk("Read 2 returned unexpcted value\n");
551 goto error;
552 }
553
554 /* create dvb_frontend */
555 memcpy(&state->frontend.ops, &l64781_ops, sizeof(struct dvb_frontend_ops));
556 state->frontend.demodulator_priv = state;
557 return &state->frontend;
558
559error:
560 if (reg0x3e >= 0)
561 l64781_writereg (state, 0x3e, reg0x3e); /* restore reg 0x3e */
562 kfree(state);
563 return NULL;
564}
565
566static struct dvb_frontend_ops l64781_ops = {
567
568 .info = {
569 .name = "LSI L64781 DVB-T",
570 .type = FE_OFDM,
571 /* .frequency_min = ???,*/
572 /* .frequency_max = ???,*/
573 .frequency_stepsize = 166666,
574 /* .frequency_tolerance = ???,*/
575 /* .symbol_rate_tolerance = ???,*/
576 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
577 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
578 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
579 FE_CAN_MUTE_TS
580 },
581
582 .release = l64781_release,
583
584 .init = l64781_init,
585 .sleep = l64781_sleep,
586
587 .set_frontend = apply_frontend_param,
588 .get_frontend = get_frontend,
589 .get_tune_settings = l64781_get_tune_settings,
590
591 .read_status = l64781_read_status,
592 .read_ber = l64781_read_ber,
593 .read_signal_strength = l64781_read_signal_strength,
594 .read_snr = l64781_read_snr,
595 .read_ucblocks = l64781_read_ucblocks,
596};
597
598MODULE_DESCRIPTION("LSI L64781 DVB-T Demodulator driver");
599MODULE_AUTHOR("Holger Waechtler, Marko Kohtala");
600MODULE_LICENSE("GPL");
601
602EXPORT_SYMBOL(l64781_attach);
diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h
new file mode 100644
index 00000000000..1305a9e7fb0
--- /dev/null
+++ b/drivers/media/dvb/frontends/l64781.h
@@ -0,0 +1,46 @@
1/*
2 driver for LSI L64781 COFDM demodulator
3
4 Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH
5 Marko Kohtala <marko.kohtala@luukku.com>
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#ifndef L64781_H
24#define L64781_H
25
26#include <linux/dvb/frontend.h>
27
28struct l64781_config
29{
30 /* the demodulator's i2c address */
31 u8 demod_address;
32};
33
34#if defined(CONFIG_DVB_L64781) || (defined(CONFIG_DVB_L64781_MODULE) && defined(MODULE))
35extern struct dvb_frontend* l64781_attach(const struct l64781_config* config,
36 struct i2c_adapter* i2c);
37#else
38static inline struct dvb_frontend* l64781_attach(const struct l64781_config* config,
39 struct i2c_adapter* i2c)
40{
41 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
42 return NULL;
43}
44#endif // CONFIG_DVB_L64781
45
46#endif // L64781_H
diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c
new file mode 100644
index 00000000000..3272881cb11
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3305.c
@@ -0,0 +1,1222 @@
1/*
2 * Support for LG Electronics LGDT3304 and LGDT3305 - VSB/QAM
3 *
4 * Copyright (C) 2008, 2009, 2010 Michael Krufky <mkrufky@linuxtv.org>
5 *
6 * LGDT3304 support by Jarod Wilson <jarod@redhat.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
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 <asm/div64.h>
25#include <linux/dvb/frontend.h>
26#include <linux/slab.h>
27#include "dvb_math.h"
28#include "lgdt3305.h"
29
30static int debug;
31module_param(debug, int, 0644);
32MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
33
34#define DBG_INFO 1
35#define DBG_REG 2
36
37#define lg_printk(kern, fmt, arg...) \
38 printk(kern "%s: " fmt, __func__, ##arg)
39
40#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3305: " fmt, ##arg)
41#define lg_warn(fmt, arg...) lg_printk(KERN_WARNING, fmt, ##arg)
42#define lg_err(fmt, arg...) lg_printk(KERN_ERR, fmt, ##arg)
43#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
44 lg_printk(KERN_DEBUG, fmt, ##arg)
45#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
46 lg_printk(KERN_DEBUG, fmt, ##arg)
47
48#define lg_fail(ret) \
49({ \
50 int __ret; \
51 __ret = (ret < 0); \
52 if (__ret) \
53 lg_err("error %d on line %d\n", ret, __LINE__); \
54 __ret; \
55})
56
57struct lgdt3305_state {
58 struct i2c_adapter *i2c_adap;
59 const struct lgdt3305_config *cfg;
60
61 struct dvb_frontend frontend;
62
63 fe_modulation_t current_modulation;
64 u32 current_frequency;
65 u32 snr;
66};
67
68/* ------------------------------------------------------------------------ */
69
70/* FIXME: verify & document the LGDT3304 registers */
71
72#define LGDT3305_GEN_CTRL_1 0x0000
73#define LGDT3305_GEN_CTRL_2 0x0001
74#define LGDT3305_GEN_CTRL_3 0x0002
75#define LGDT3305_GEN_STATUS 0x0003
76#define LGDT3305_GEN_CONTROL 0x0007
77#define LGDT3305_GEN_CTRL_4 0x000a
78#define LGDT3305_DGTL_AGC_REF_1 0x0012
79#define LGDT3305_DGTL_AGC_REF_2 0x0013
80#define LGDT3305_CR_CTR_FREQ_1 0x0106
81#define LGDT3305_CR_CTR_FREQ_2 0x0107
82#define LGDT3305_CR_CTR_FREQ_3 0x0108
83#define LGDT3305_CR_CTR_FREQ_4 0x0109
84#define LGDT3305_CR_MSE_1 0x011b
85#define LGDT3305_CR_MSE_2 0x011c
86#define LGDT3305_CR_LOCK_STATUS 0x011d
87#define LGDT3305_CR_CTRL_7 0x0126
88#define LGDT3305_AGC_POWER_REF_1 0x0300
89#define LGDT3305_AGC_POWER_REF_2 0x0301
90#define LGDT3305_AGC_DELAY_PT_1 0x0302
91#define LGDT3305_AGC_DELAY_PT_2 0x0303
92#define LGDT3305_RFAGC_LOOP_FLTR_BW_1 0x0306
93#define LGDT3305_RFAGC_LOOP_FLTR_BW_2 0x0307
94#define LGDT3305_IFBW_1 0x0308
95#define LGDT3305_IFBW_2 0x0309
96#define LGDT3305_AGC_CTRL_1 0x030c
97#define LGDT3305_AGC_CTRL_4 0x0314
98#define LGDT3305_EQ_MSE_1 0x0413
99#define LGDT3305_EQ_MSE_2 0x0414
100#define LGDT3305_EQ_MSE_3 0x0415
101#define LGDT3305_PT_MSE_1 0x0417
102#define LGDT3305_PT_MSE_2 0x0418
103#define LGDT3305_PT_MSE_3 0x0419
104#define LGDT3305_FEC_BLOCK_CTRL 0x0504
105#define LGDT3305_FEC_LOCK_STATUS 0x050a
106#define LGDT3305_FEC_PKT_ERR_1 0x050c
107#define LGDT3305_FEC_PKT_ERR_2 0x050d
108#define LGDT3305_TP_CTRL_1 0x050e
109#define LGDT3305_BERT_PERIOD 0x0801
110#define LGDT3305_BERT_ERROR_COUNT_1 0x080a
111#define LGDT3305_BERT_ERROR_COUNT_2 0x080b
112#define LGDT3305_BERT_ERROR_COUNT_3 0x080c
113#define LGDT3305_BERT_ERROR_COUNT_4 0x080d
114
115static int lgdt3305_write_reg(struct lgdt3305_state *state, u16 reg, u8 val)
116{
117 int ret;
118 u8 buf[] = { reg >> 8, reg & 0xff, val };
119 struct i2c_msg msg = {
120 .addr = state->cfg->i2c_addr, .flags = 0,
121 .buf = buf, .len = 3,
122 };
123
124 lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
125
126 ret = i2c_transfer(state->i2c_adap, &msg, 1);
127
128 if (ret != 1) {
129 lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
130 msg.buf[0], msg.buf[1], msg.buf[2], ret);
131 if (ret < 0)
132 return ret;
133 else
134 return -EREMOTEIO;
135 }
136 return 0;
137}
138
139static int lgdt3305_read_reg(struct lgdt3305_state *state, u16 reg, u8 *val)
140{
141 int ret;
142 u8 reg_buf[] = { reg >> 8, reg & 0xff };
143 struct i2c_msg msg[] = {
144 { .addr = state->cfg->i2c_addr,
145 .flags = 0, .buf = reg_buf, .len = 2 },
146 { .addr = state->cfg->i2c_addr,
147 .flags = I2C_M_RD, .buf = val, .len = 1 },
148 };
149
150 lg_reg("reg: 0x%04x\n", reg);
151
152 ret = i2c_transfer(state->i2c_adap, msg, 2);
153
154 if (ret != 2) {
155 lg_err("error (addr %02x reg %04x error (ret == %i)\n",
156 state->cfg->i2c_addr, reg, ret);
157 if (ret < 0)
158 return ret;
159 else
160 return -EREMOTEIO;
161 }
162 return 0;
163}
164
165#define read_reg(state, reg) \
166({ \
167 u8 __val; \
168 int ret = lgdt3305_read_reg(state, reg, &__val); \
169 if (lg_fail(ret)) \
170 __val = 0; \
171 __val; \
172})
173
174static int lgdt3305_set_reg_bit(struct lgdt3305_state *state,
175 u16 reg, int bit, int onoff)
176{
177 u8 val;
178 int ret;
179
180 lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
181
182 ret = lgdt3305_read_reg(state, reg, &val);
183 if (lg_fail(ret))
184 goto fail;
185
186 val &= ~(1 << bit);
187 val |= (onoff & 1) << bit;
188
189 ret = lgdt3305_write_reg(state, reg, val);
190fail:
191 return ret;
192}
193
194struct lgdt3305_reg {
195 u16 reg;
196 u8 val;
197};
198
199static int lgdt3305_write_regs(struct lgdt3305_state *state,
200 struct lgdt3305_reg *regs, int len)
201{
202 int i, ret;
203
204 lg_reg("writing %d registers...\n", len);
205
206 for (i = 0; i < len - 1; i++) {
207 ret = lgdt3305_write_reg(state, regs[i].reg, regs[i].val);
208 if (lg_fail(ret))
209 return ret;
210 }
211 return 0;
212}
213
214/* ------------------------------------------------------------------------ */
215
216static int lgdt3305_soft_reset(struct lgdt3305_state *state)
217{
218 int ret;
219
220 lg_dbg("\n");
221
222 ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 0);
223 if (lg_fail(ret))
224 goto fail;
225
226 msleep(20);
227 ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 1);
228fail:
229 return ret;
230}
231
232static inline int lgdt3305_mpeg_mode(struct lgdt3305_state *state,
233 enum lgdt3305_mpeg_mode mode)
234{
235 lg_dbg("(%d)\n", mode);
236 return lgdt3305_set_reg_bit(state, LGDT3305_TP_CTRL_1, 5, mode);
237}
238
239static int lgdt3305_mpeg_mode_polarity(struct lgdt3305_state *state,
240 enum lgdt3305_tp_clock_edge edge,
241 enum lgdt3305_tp_valid_polarity valid)
242{
243 u8 val;
244 int ret;
245
246 lg_dbg("edge = %d, valid = %d\n", edge, valid);
247
248 ret = lgdt3305_read_reg(state, LGDT3305_TP_CTRL_1, &val);
249 if (lg_fail(ret))
250 goto fail;
251
252 val &= ~0x09;
253
254 if (edge)
255 val |= 0x08;
256 if (valid)
257 val |= 0x01;
258
259 ret = lgdt3305_write_reg(state, LGDT3305_TP_CTRL_1, val);
260 if (lg_fail(ret))
261 goto fail;
262
263 ret = lgdt3305_soft_reset(state);
264fail:
265 return ret;
266}
267
268static int lgdt3305_set_modulation(struct lgdt3305_state *state,
269 struct dvb_frontend_parameters *param)
270{
271 u8 opermode;
272 int ret;
273
274 lg_dbg("\n");
275
276 ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_1, &opermode);
277 if (lg_fail(ret))
278 goto fail;
279
280 opermode &= ~0x03;
281
282 switch (param->u.vsb.modulation) {
283 case VSB_8:
284 opermode |= 0x03;
285 break;
286 case QAM_64:
287 opermode |= 0x00;
288 break;
289 case QAM_256:
290 opermode |= 0x01;
291 break;
292 default:
293 return -EINVAL;
294 }
295 ret = lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_1, opermode);
296fail:
297 return ret;
298}
299
300static int lgdt3305_set_filter_extension(struct lgdt3305_state *state,
301 struct dvb_frontend_parameters *param)
302{
303 int val;
304
305 switch (param->u.vsb.modulation) {
306 case VSB_8:
307 val = 0;
308 break;
309 case QAM_64:
310 case QAM_256:
311 val = 1;
312 break;
313 default:
314 return -EINVAL;
315 }
316 lg_dbg("val = %d\n", val);
317
318 return lgdt3305_set_reg_bit(state, 0x043f, 2, val);
319}
320
321/* ------------------------------------------------------------------------ */
322
323static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state,
324 struct dvb_frontend_parameters *param)
325{
326 u16 agc_ref;
327
328 switch (param->u.vsb.modulation) {
329 case VSB_8:
330 agc_ref = 0x32c4;
331 break;
332 case QAM_64:
333 agc_ref = 0x2a00;
334 break;
335 case QAM_256:
336 agc_ref = 0x2a80;
337 break;
338 default:
339 return -EINVAL;
340 }
341
342 lg_dbg("agc ref: 0x%04x\n", agc_ref);
343
344 lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_1, agc_ref >> 8);
345 lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_2, agc_ref & 0xff);
346
347 return 0;
348}
349
350static int lgdt3305_rfagc_loop(struct lgdt3305_state *state,
351 struct dvb_frontend_parameters *param)
352{
353 u16 ifbw, rfbw, agcdelay;
354
355 switch (param->u.vsb.modulation) {
356 case VSB_8:
357 agcdelay = 0x04c0;
358 rfbw = 0x8000;
359 ifbw = 0x8000;
360 break;
361 case QAM_64:
362 case QAM_256:
363 agcdelay = 0x046b;
364 rfbw = 0x8889;
365 /* FIXME: investigate optimal ifbw & rfbw values for the
366 * DT3304 and re-write this switch..case block */
367 if (state->cfg->demod_chip == LGDT3304)
368 ifbw = 0x6666;
369 else /* (state->cfg->demod_chip == LGDT3305) */
370 ifbw = 0x8888;
371 break;
372 default:
373 return -EINVAL;
374 }
375
376 if (state->cfg->rf_agc_loop) {
377 lg_dbg("agcdelay: 0x%04x, rfbw: 0x%04x\n", agcdelay, rfbw);
378
379 /* rf agc loop filter bandwidth */
380 lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_1,
381 agcdelay >> 8);
382 lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_2,
383 agcdelay & 0xff);
384
385 lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_1,
386 rfbw >> 8);
387 lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_2,
388 rfbw & 0xff);
389 } else {
390 lg_dbg("ifbw: 0x%04x\n", ifbw);
391
392 /* if agc loop filter bandwidth */
393 lgdt3305_write_reg(state, LGDT3305_IFBW_1, ifbw >> 8);
394 lgdt3305_write_reg(state, LGDT3305_IFBW_2, ifbw & 0xff);
395 }
396
397 return 0;
398}
399
400static int lgdt3305_agc_setup(struct lgdt3305_state *state,
401 struct dvb_frontend_parameters *param)
402{
403 int lockdten, acqen;
404
405 switch (param->u.vsb.modulation) {
406 case VSB_8:
407 lockdten = 0;
408 acqen = 0;
409 break;
410 case QAM_64:
411 case QAM_256:
412 lockdten = 1;
413 acqen = 1;
414 break;
415 default:
416 return -EINVAL;
417 }
418
419 lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen);
420
421 /* control agc function */
422 switch (state->cfg->demod_chip) {
423 case LGDT3304:
424 lgdt3305_write_reg(state, 0x0314, 0xe1 | lockdten << 1);
425 lgdt3305_set_reg_bit(state, 0x030e, 2, acqen);
426 break;
427 case LGDT3305:
428 lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
429 lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
430 break;
431 default:
432 return -EINVAL;
433 }
434
435 return lgdt3305_rfagc_loop(state, param);
436}
437
438static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state,
439 struct dvb_frontend_parameters *param)
440{
441 u16 usref = 0;
442
443 switch (param->u.vsb.modulation) {
444 case VSB_8:
445 if (state->cfg->usref_8vsb)
446 usref = state->cfg->usref_8vsb;
447 break;
448 case QAM_64:
449 if (state->cfg->usref_qam64)
450 usref = state->cfg->usref_qam64;
451 break;
452 case QAM_256:
453 if (state->cfg->usref_qam256)
454 usref = state->cfg->usref_qam256;
455 break;
456 default:
457 return -EINVAL;
458 }
459
460 if (usref) {
461 lg_dbg("set manual mode: 0x%04x\n", usref);
462
463 lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 3, 1);
464
465 lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_1,
466 0xff & (usref >> 8));
467 lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_2,
468 0xff & (usref >> 0));
469 }
470 return 0;
471}
472
473/* ------------------------------------------------------------------------ */
474
475static int lgdt3305_spectral_inversion(struct lgdt3305_state *state,
476 struct dvb_frontend_parameters *param,
477 int inversion)
478{
479 int ret;
480
481 lg_dbg("(%d)\n", inversion);
482
483 switch (param->u.vsb.modulation) {
484 case VSB_8:
485 ret = lgdt3305_write_reg(state, LGDT3305_CR_CTRL_7,
486 inversion ? 0xf9 : 0x79);
487 break;
488 case QAM_64:
489 case QAM_256:
490 ret = lgdt3305_write_reg(state, LGDT3305_FEC_BLOCK_CTRL,
491 inversion ? 0xfd : 0xff);
492 break;
493 default:
494 ret = -EINVAL;
495 }
496 return ret;
497}
498
499static int lgdt3305_set_if(struct lgdt3305_state *state,
500 struct dvb_frontend_parameters *param)
501{
502 u16 if_freq_khz;
503 u8 nco1, nco2, nco3, nco4;
504 u64 nco;
505
506 switch (param->u.vsb.modulation) {
507 case VSB_8:
508 if_freq_khz = state->cfg->vsb_if_khz;
509 break;
510 case QAM_64:
511 case QAM_256:
512 if_freq_khz = state->cfg->qam_if_khz;
513 break;
514 default:
515 return -EINVAL;
516 }
517
518 nco = if_freq_khz / 10;
519
520 switch (param->u.vsb.modulation) {
521 case VSB_8:
522 nco <<= 24;
523 do_div(nco, 625);
524 break;
525 case QAM_64:
526 case QAM_256:
527 nco <<= 28;
528 do_div(nco, 625);
529 break;
530 default:
531 return -EINVAL;
532 }
533
534 nco1 = (nco >> 24) & 0x3f;
535 nco1 |= 0x40;
536 nco2 = (nco >> 16) & 0xff;
537 nco3 = (nco >> 8) & 0xff;
538 nco4 = nco & 0xff;
539
540 lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, nco1);
541 lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, nco2);
542 lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, nco3);
543 lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, nco4);
544
545 lg_dbg("%d KHz -> [%02x%02x%02x%02x]\n",
546 if_freq_khz, nco1, nco2, nco3, nco4);
547
548 return 0;
549}
550
551/* ------------------------------------------------------------------------ */
552
553static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
554{
555 struct lgdt3305_state *state = fe->demodulator_priv;
556
557 if (state->cfg->deny_i2c_rptr)
558 return 0;
559
560 lg_dbg("(%d)\n", enable);
561
562 return lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_2, 5,
563 enable ? 0 : 1);
564}
565
566static int lgdt3305_sleep(struct dvb_frontend *fe)
567{
568 struct lgdt3305_state *state = fe->demodulator_priv;
569 u8 gen_ctrl_3, gen_ctrl_4;
570
571 lg_dbg("\n");
572
573 gen_ctrl_3 = read_reg(state, LGDT3305_GEN_CTRL_3);
574 gen_ctrl_4 = read_reg(state, LGDT3305_GEN_CTRL_4);
575
576 /* hold in software reset while sleeping */
577 gen_ctrl_3 &= ~0x01;
578 /* tristate the IF-AGC pin */
579 gen_ctrl_3 |= 0x02;
580 /* tristate the RF-AGC pin */
581 gen_ctrl_3 |= 0x04;
582
583 /* disable vsb/qam module */
584 gen_ctrl_4 &= ~0x01;
585 /* disable adc module */
586 gen_ctrl_4 &= ~0x02;
587
588 lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_3, gen_ctrl_3);
589 lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_4, gen_ctrl_4);
590
591 return 0;
592}
593
594static int lgdt3305_init(struct dvb_frontend *fe)
595{
596 struct lgdt3305_state *state = fe->demodulator_priv;
597 int ret;
598
599 static struct lgdt3305_reg lgdt3304_init_data[] = {
600 { .reg = LGDT3305_GEN_CTRL_1, .val = 0x03, },
601 { .reg = 0x000d, .val = 0x02, },
602 { .reg = 0x000e, .val = 0x02, },
603 { .reg = LGDT3305_DGTL_AGC_REF_1, .val = 0x32, },
604 { .reg = LGDT3305_DGTL_AGC_REF_2, .val = 0xc4, },
605 { .reg = LGDT3305_CR_CTR_FREQ_1, .val = 0x00, },
606 { .reg = LGDT3305_CR_CTR_FREQ_2, .val = 0x00, },
607 { .reg = LGDT3305_CR_CTR_FREQ_3, .val = 0x00, },
608 { .reg = LGDT3305_CR_CTR_FREQ_4, .val = 0x00, },
609 { .reg = LGDT3305_CR_CTRL_7, .val = 0xf9, },
610 { .reg = 0x0112, .val = 0x17, },
611 { .reg = 0x0113, .val = 0x15, },
612 { .reg = 0x0114, .val = 0x18, },
613 { .reg = 0x0115, .val = 0xff, },
614 { .reg = 0x0116, .val = 0x3c, },
615 { .reg = 0x0214, .val = 0x67, },
616 { .reg = 0x0424, .val = 0x8d, },
617 { .reg = 0x0427, .val = 0x12, },
618 { .reg = 0x0428, .val = 0x4f, },
619 { .reg = LGDT3305_IFBW_1, .val = 0x80, },
620 { .reg = LGDT3305_IFBW_2, .val = 0x00, },
621 { .reg = 0x030a, .val = 0x08, },
622 { .reg = 0x030b, .val = 0x9b, },
623 { .reg = 0x030d, .val = 0x00, },
624 { .reg = 0x030e, .val = 0x1c, },
625 { .reg = 0x0314, .val = 0xe1, },
626 { .reg = 0x000d, .val = 0x82, },
627 { .reg = LGDT3305_TP_CTRL_1, .val = 0x5b, },
628 { .reg = LGDT3305_TP_CTRL_1, .val = 0x5b, },
629 };
630
631 static struct lgdt3305_reg lgdt3305_init_data[] = {
632 { .reg = LGDT3305_GEN_CTRL_1, .val = 0x03, },
633 { .reg = LGDT3305_GEN_CTRL_2, .val = 0xb0, },
634 { .reg = LGDT3305_GEN_CTRL_3, .val = 0x01, },
635 { .reg = LGDT3305_GEN_CONTROL, .val = 0x6f, },
636 { .reg = LGDT3305_GEN_CTRL_4, .val = 0x03, },
637 { .reg = LGDT3305_DGTL_AGC_REF_1, .val = 0x32, },
638 { .reg = LGDT3305_DGTL_AGC_REF_2, .val = 0xc4, },
639 { .reg = LGDT3305_CR_CTR_FREQ_1, .val = 0x00, },
640 { .reg = LGDT3305_CR_CTR_FREQ_2, .val = 0x00, },
641 { .reg = LGDT3305_CR_CTR_FREQ_3, .val = 0x00, },
642 { .reg = LGDT3305_CR_CTR_FREQ_4, .val = 0x00, },
643 { .reg = LGDT3305_CR_CTRL_7, .val = 0x79, },
644 { .reg = LGDT3305_AGC_POWER_REF_1, .val = 0x32, },
645 { .reg = LGDT3305_AGC_POWER_REF_2, .val = 0xc4, },
646 { .reg = LGDT3305_AGC_DELAY_PT_1, .val = 0x0d, },
647 { .reg = LGDT3305_AGC_DELAY_PT_2, .val = 0x30, },
648 { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1, .val = 0x80, },
649 { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2, .val = 0x00, },
650 { .reg = LGDT3305_IFBW_1, .val = 0x80, },
651 { .reg = LGDT3305_IFBW_2, .val = 0x00, },
652 { .reg = LGDT3305_AGC_CTRL_1, .val = 0x30, },
653 { .reg = LGDT3305_AGC_CTRL_4, .val = 0x61, },
654 { .reg = LGDT3305_FEC_BLOCK_CTRL, .val = 0xff, },
655 { .reg = LGDT3305_TP_CTRL_1, .val = 0x1b, },
656 };
657
658 lg_dbg("\n");
659
660 switch (state->cfg->demod_chip) {
661 case LGDT3304:
662 ret = lgdt3305_write_regs(state, lgdt3304_init_data,
663 ARRAY_SIZE(lgdt3304_init_data));
664 break;
665 case LGDT3305:
666 ret = lgdt3305_write_regs(state, lgdt3305_init_data,
667 ARRAY_SIZE(lgdt3305_init_data));
668 break;
669 default:
670 ret = -EINVAL;
671 }
672 if (lg_fail(ret))
673 goto fail;
674
675 ret = lgdt3305_soft_reset(state);
676fail:
677 return ret;
678}
679
680static int lgdt3304_set_parameters(struct dvb_frontend *fe,
681 struct dvb_frontend_parameters *param)
682{
683 struct lgdt3305_state *state = fe->demodulator_priv;
684 int ret;
685
686 lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation);
687
688 if (fe->ops.tuner_ops.set_params) {
689 ret = fe->ops.tuner_ops.set_params(fe, param);
690 if (fe->ops.i2c_gate_ctrl)
691 fe->ops.i2c_gate_ctrl(fe, 0);
692 if (lg_fail(ret))
693 goto fail;
694 state->current_frequency = param->frequency;
695 }
696
697 ret = lgdt3305_set_modulation(state, param);
698 if (lg_fail(ret))
699 goto fail;
700
701 ret = lgdt3305_passband_digital_agc(state, param);
702 if (lg_fail(ret))
703 goto fail;
704
705 ret = lgdt3305_agc_setup(state, param);
706 if (lg_fail(ret))
707 goto fail;
708
709 /* reg 0x030d is 3304-only... seen in vsb and qam usbsnoops... */
710 switch (param->u.vsb.modulation) {
711 case VSB_8:
712 lgdt3305_write_reg(state, 0x030d, 0x00);
713 lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, 0x4f);
714 lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, 0x0c);
715 lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, 0xac);
716 lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, 0xba);
717 break;
718 case QAM_64:
719 case QAM_256:
720 lgdt3305_write_reg(state, 0x030d, 0x14);
721 ret = lgdt3305_set_if(state, param);
722 if (lg_fail(ret))
723 goto fail;
724 break;
725 default:
726 return -EINVAL;
727 }
728
729
730 ret = lgdt3305_spectral_inversion(state, param,
731 state->cfg->spectral_inversion
732 ? 1 : 0);
733 if (lg_fail(ret))
734 goto fail;
735
736 state->current_modulation = param->u.vsb.modulation;
737
738 ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
739 if (lg_fail(ret))
740 goto fail;
741
742 /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
743 ret = lgdt3305_mpeg_mode_polarity(state,
744 state->cfg->tpclk_edge,
745 state->cfg->tpvalid_polarity);
746fail:
747 return ret;
748}
749
750static int lgdt3305_set_parameters(struct dvb_frontend *fe,
751 struct dvb_frontend_parameters *param)
752{
753 struct lgdt3305_state *state = fe->demodulator_priv;
754 int ret;
755
756 lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation);
757
758 if (fe->ops.tuner_ops.set_params) {
759 ret = fe->ops.tuner_ops.set_params(fe, param);
760 if (fe->ops.i2c_gate_ctrl)
761 fe->ops.i2c_gate_ctrl(fe, 0);
762 if (lg_fail(ret))
763 goto fail;
764 state->current_frequency = param->frequency;
765 }
766
767 ret = lgdt3305_set_modulation(state, param);
768 if (lg_fail(ret))
769 goto fail;
770
771 ret = lgdt3305_passband_digital_agc(state, param);
772 if (lg_fail(ret))
773 goto fail;
774 ret = lgdt3305_set_agc_power_ref(state, param);
775 if (lg_fail(ret))
776 goto fail;
777 ret = lgdt3305_agc_setup(state, param);
778 if (lg_fail(ret))
779 goto fail;
780
781 /* low if */
782 ret = lgdt3305_write_reg(state, LGDT3305_GEN_CONTROL, 0x2f);
783 if (lg_fail(ret))
784 goto fail;
785 ret = lgdt3305_set_reg_bit(state, LGDT3305_CR_CTR_FREQ_1, 6, 1);
786 if (lg_fail(ret))
787 goto fail;
788
789 ret = lgdt3305_set_if(state, param);
790 if (lg_fail(ret))
791 goto fail;
792 ret = lgdt3305_spectral_inversion(state, param,
793 state->cfg->spectral_inversion
794 ? 1 : 0);
795 if (lg_fail(ret))
796 goto fail;
797
798 ret = lgdt3305_set_filter_extension(state, param);
799 if (lg_fail(ret))
800 goto fail;
801
802 state->current_modulation = param->u.vsb.modulation;
803
804 ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
805 if (lg_fail(ret))
806 goto fail;
807
808 /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
809 ret = lgdt3305_mpeg_mode_polarity(state,
810 state->cfg->tpclk_edge,
811 state->cfg->tpvalid_polarity);
812fail:
813 return ret;
814}
815
816static int lgdt3305_get_frontend(struct dvb_frontend *fe,
817 struct dvb_frontend_parameters *param)
818{
819 struct lgdt3305_state *state = fe->demodulator_priv;
820
821 lg_dbg("\n");
822
823 param->u.vsb.modulation = state->current_modulation;
824 param->frequency = state->current_frequency;
825 return 0;
826}
827
828/* ------------------------------------------------------------------------ */
829
830static int lgdt3305_read_cr_lock_status(struct lgdt3305_state *state,
831 int *locked)
832{
833 u8 val;
834 int ret;
835 char *cr_lock_state = "";
836
837 *locked = 0;
838
839 ret = lgdt3305_read_reg(state, LGDT3305_CR_LOCK_STATUS, &val);
840 if (lg_fail(ret))
841 goto fail;
842
843 switch (state->current_modulation) {
844 case QAM_256:
845 case QAM_64:
846 if (val & (1 << 1))
847 *locked = 1;
848
849 switch (val & 0x07) {
850 case 0:
851 cr_lock_state = "QAM UNLOCK";
852 break;
853 case 4:
854 cr_lock_state = "QAM 1stLock";
855 break;
856 case 6:
857 cr_lock_state = "QAM 2ndLock";
858 break;
859 case 7:
860 cr_lock_state = "QAM FinalLock";
861 break;
862 default:
863 cr_lock_state = "CLOCKQAM-INVALID!";
864 break;
865 }
866 break;
867 case VSB_8:
868 if (val & (1 << 7)) {
869 *locked = 1;
870 cr_lock_state = "CLOCKVSB";
871 }
872 break;
873 default:
874 ret = -EINVAL;
875 }
876 lg_dbg("(%d) %s\n", *locked, cr_lock_state);
877fail:
878 return ret;
879}
880
881static int lgdt3305_read_fec_lock_status(struct lgdt3305_state *state,
882 int *locked)
883{
884 u8 val;
885 int ret, mpeg_lock, fec_lock, viterbi_lock;
886
887 *locked = 0;
888
889 switch (state->current_modulation) {
890 case QAM_256:
891 case QAM_64:
892 ret = lgdt3305_read_reg(state,
893 LGDT3305_FEC_LOCK_STATUS, &val);
894 if (lg_fail(ret))
895 goto fail;
896
897 mpeg_lock = (val & (1 << 0)) ? 1 : 0;
898 fec_lock = (val & (1 << 2)) ? 1 : 0;
899 viterbi_lock = (val & (1 << 3)) ? 1 : 0;
900
901 *locked = mpeg_lock && fec_lock && viterbi_lock;
902
903 lg_dbg("(%d) %s%s%s\n", *locked,
904 mpeg_lock ? "mpeg lock " : "",
905 fec_lock ? "fec lock " : "",
906 viterbi_lock ? "viterbi lock" : "");
907 break;
908 case VSB_8:
909 default:
910 ret = -EINVAL;
911 }
912fail:
913 return ret;
914}
915
916static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status)
917{
918 struct lgdt3305_state *state = fe->demodulator_priv;
919 u8 val;
920 int ret, signal, inlock, nofecerr, snrgood,
921 cr_lock, fec_lock, sync_lock;
922
923 *status = 0;
924
925 ret = lgdt3305_read_reg(state, LGDT3305_GEN_STATUS, &val);
926 if (lg_fail(ret))
927 goto fail;
928
929 signal = (val & (1 << 4)) ? 1 : 0;
930 inlock = (val & (1 << 3)) ? 0 : 1;
931 sync_lock = (val & (1 << 2)) ? 1 : 0;
932 nofecerr = (val & (1 << 1)) ? 1 : 0;
933 snrgood = (val & (1 << 0)) ? 1 : 0;
934
935 lg_dbg("%s%s%s%s%s\n",
936 signal ? "SIGNALEXIST " : "",
937 inlock ? "INLOCK " : "",
938 sync_lock ? "SYNCLOCK " : "",
939 nofecerr ? "NOFECERR " : "",
940 snrgood ? "SNRGOOD " : "");
941
942 ret = lgdt3305_read_cr_lock_status(state, &cr_lock);
943 if (lg_fail(ret))
944 goto fail;
945
946 if (signal)
947 *status |= FE_HAS_SIGNAL;
948 if (cr_lock)
949 *status |= FE_HAS_CARRIER;
950 if (nofecerr)
951 *status |= FE_HAS_VITERBI;
952 if (sync_lock)
953 *status |= FE_HAS_SYNC;
954
955 switch (state->current_modulation) {
956 case QAM_256:
957 case QAM_64:
958 /* signal bit is unreliable on the DT3304 in QAM mode */
959 if (((LGDT3304 == state->cfg->demod_chip)) && (cr_lock))
960 *status |= FE_HAS_SIGNAL;
961
962 ret = lgdt3305_read_fec_lock_status(state, &fec_lock);
963 if (lg_fail(ret))
964 goto fail;
965
966 if (fec_lock)
967 *status |= FE_HAS_LOCK;
968 break;
969 case VSB_8:
970 if (inlock)
971 *status |= FE_HAS_LOCK;
972 break;
973 default:
974 ret = -EINVAL;
975 }
976fail:
977 return ret;
978}
979
980/* ------------------------------------------------------------------------ */
981
982/* borrowed from lgdt330x.c */
983static u32 calculate_snr(u32 mse, u32 c)
984{
985 if (mse == 0) /* no signal */
986 return 0;
987
988 mse = intlog10(mse);
989 if (mse > c) {
990 /* Negative SNR, which is possible, but realisticly the
991 demod will lose lock before the signal gets this bad. The
992 API only allows for unsigned values, so just return 0 */
993 return 0;
994 }
995 return 10*(c - mse);
996}
997
998static int lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr)
999{
1000 struct lgdt3305_state *state = fe->demodulator_priv;
1001 u32 noise; /* noise value */
1002 u32 c; /* per-modulation SNR calculation constant */
1003
1004 switch (state->current_modulation) {
1005 case VSB_8:
1006#ifdef USE_PTMSE
1007 /* Use Phase Tracker Mean-Square Error Register */
1008 /* SNR for ranges from -13.11 to +44.08 */
1009 noise = ((read_reg(state, LGDT3305_PT_MSE_1) & 0x07) << 16) |
1010 (read_reg(state, LGDT3305_PT_MSE_2) << 8) |
1011 (read_reg(state, LGDT3305_PT_MSE_3) & 0xff);
1012 c = 73957994; /* log10(25*32^2)*2^24 */
1013#else
1014 /* Use Equalizer Mean-Square Error Register */
1015 /* SNR for ranges from -16.12 to +44.08 */
1016 noise = ((read_reg(state, LGDT3305_EQ_MSE_1) & 0x0f) << 16) |
1017 (read_reg(state, LGDT3305_EQ_MSE_2) << 8) |
1018 (read_reg(state, LGDT3305_EQ_MSE_3) & 0xff);
1019 c = 73957994; /* log10(25*32^2)*2^24 */
1020#endif
1021 break;
1022 case QAM_64:
1023 case QAM_256:
1024 noise = (read_reg(state, LGDT3305_CR_MSE_1) << 8) |
1025 (read_reg(state, LGDT3305_CR_MSE_2) & 0xff);
1026
1027 c = (state->current_modulation == QAM_64) ?
1028 97939837 : 98026066;
1029 /* log10(688128)*2^24 and log10(696320)*2^24 */
1030 break;
1031 default:
1032 return -EINVAL;
1033 }
1034 state->snr = calculate_snr(noise, c);
1035 /* report SNR in dB * 10 */
1036 *snr = (state->snr / ((1 << 24) / 10));
1037 lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise,
1038 state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
1039
1040 return 0;
1041}
1042
1043static int lgdt3305_read_signal_strength(struct dvb_frontend *fe,
1044 u16 *strength)
1045{
1046 /* borrowed from lgdt330x.c
1047 *
1048 * Calculate strength from SNR up to 35dB
1049 * Even though the SNR can go higher than 35dB,
1050 * there is some comfort factor in having a range of
1051 * strong signals that can show at 100%
1052 */
1053 struct lgdt3305_state *state = fe->demodulator_priv;
1054 u16 snr;
1055 int ret;
1056
1057 *strength = 0;
1058
1059 ret = fe->ops.read_snr(fe, &snr);
1060 if (lg_fail(ret))
1061 goto fail;
1062 /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
1063 /* scale the range 0 - 35*2^24 into 0 - 65535 */
1064 if (state->snr >= 8960 * 0x10000)
1065 *strength = 0xffff;
1066 else
1067 *strength = state->snr / 8960;
1068fail:
1069 return ret;
1070}
1071
1072/* ------------------------------------------------------------------------ */
1073
1074static int lgdt3305_read_ber(struct dvb_frontend *fe, u32 *ber)
1075{
1076 *ber = 0;
1077 return 0;
1078}
1079
1080static int lgdt3305_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
1081{
1082 struct lgdt3305_state *state = fe->demodulator_priv;
1083
1084 *ucblocks =
1085 (read_reg(state, LGDT3305_FEC_PKT_ERR_1) << 8) |
1086 (read_reg(state, LGDT3305_FEC_PKT_ERR_2) & 0xff);
1087
1088 return 0;
1089}
1090
1091static int lgdt3305_get_tune_settings(struct dvb_frontend *fe,
1092 struct dvb_frontend_tune_settings
1093 *fe_tune_settings)
1094{
1095 fe_tune_settings->min_delay_ms = 500;
1096 lg_dbg("\n");
1097 return 0;
1098}
1099
1100static void lgdt3305_release(struct dvb_frontend *fe)
1101{
1102 struct lgdt3305_state *state = fe->demodulator_priv;
1103 lg_dbg("\n");
1104 kfree(state);
1105}
1106
1107static struct dvb_frontend_ops lgdt3304_ops;
1108static struct dvb_frontend_ops lgdt3305_ops;
1109
1110struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
1111 struct i2c_adapter *i2c_adap)
1112{
1113 struct lgdt3305_state *state = NULL;
1114 int ret;
1115 u8 val;
1116
1117 lg_dbg("(%d-%04x)\n",
1118 i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
1119 config ? config->i2c_addr : 0);
1120
1121 state = kzalloc(sizeof(struct lgdt3305_state), GFP_KERNEL);
1122 if (state == NULL)
1123 goto fail;
1124
1125 state->cfg = config;
1126 state->i2c_adap = i2c_adap;
1127
1128 switch (config->demod_chip) {
1129 case LGDT3304:
1130 memcpy(&state->frontend.ops, &lgdt3304_ops,
1131 sizeof(struct dvb_frontend_ops));
1132 break;
1133 case LGDT3305:
1134 memcpy(&state->frontend.ops, &lgdt3305_ops,
1135 sizeof(struct dvb_frontend_ops));
1136 break;
1137 default:
1138 goto fail;
1139 }
1140 state->frontend.demodulator_priv = state;
1141
1142 /* verify that we're talking to a lg dt3304/5 */
1143 ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val);
1144 if ((lg_fail(ret)) | (val == 0))
1145 goto fail;
1146 ret = lgdt3305_write_reg(state, 0x0808, 0x80);
1147 if (lg_fail(ret))
1148 goto fail;
1149 ret = lgdt3305_read_reg(state, 0x0808, &val);
1150 if ((lg_fail(ret)) | (val != 0x80))
1151 goto fail;
1152 ret = lgdt3305_write_reg(state, 0x0808, 0x00);
1153 if (lg_fail(ret))
1154 goto fail;
1155
1156 state->current_frequency = -1;
1157 state->current_modulation = -1;
1158
1159 return &state->frontend;
1160fail:
1161 lg_warn("unable to detect %s hardware\n",
1162 config->demod_chip ? "LGDT3304" : "LGDT3305");
1163 kfree(state);
1164 return NULL;
1165}
1166EXPORT_SYMBOL(lgdt3305_attach);
1167
1168static struct dvb_frontend_ops lgdt3304_ops = {
1169 .info = {
1170 .name = "LG Electronics LGDT3304 VSB/QAM Frontend",
1171 .type = FE_ATSC,
1172 .frequency_min = 54000000,
1173 .frequency_max = 858000000,
1174 .frequency_stepsize = 62500,
1175 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
1176 },
1177 .i2c_gate_ctrl = lgdt3305_i2c_gate_ctrl,
1178 .init = lgdt3305_init,
1179 .set_frontend = lgdt3304_set_parameters,
1180 .get_frontend = lgdt3305_get_frontend,
1181 .get_tune_settings = lgdt3305_get_tune_settings,
1182 .read_status = lgdt3305_read_status,
1183 .read_ber = lgdt3305_read_ber,
1184 .read_signal_strength = lgdt3305_read_signal_strength,
1185 .read_snr = lgdt3305_read_snr,
1186 .read_ucblocks = lgdt3305_read_ucblocks,
1187 .release = lgdt3305_release,
1188};
1189
1190static struct dvb_frontend_ops lgdt3305_ops = {
1191 .info = {
1192 .name = "LG Electronics LGDT3305 VSB/QAM Frontend",
1193 .type = FE_ATSC,
1194 .frequency_min = 54000000,
1195 .frequency_max = 858000000,
1196 .frequency_stepsize = 62500,
1197 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
1198 },
1199 .i2c_gate_ctrl = lgdt3305_i2c_gate_ctrl,
1200 .init = lgdt3305_init,
1201 .sleep = lgdt3305_sleep,
1202 .set_frontend = lgdt3305_set_parameters,
1203 .get_frontend = lgdt3305_get_frontend,
1204 .get_tune_settings = lgdt3305_get_tune_settings,
1205 .read_status = lgdt3305_read_status,
1206 .read_ber = lgdt3305_read_ber,
1207 .read_signal_strength = lgdt3305_read_signal_strength,
1208 .read_snr = lgdt3305_read_snr,
1209 .read_ucblocks = lgdt3305_read_ucblocks,
1210 .release = lgdt3305_release,
1211};
1212
1213MODULE_DESCRIPTION("LG Electronics LGDT3304/5 ATSC/QAM-B Demodulator Driver");
1214MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
1215MODULE_LICENSE("GPL");
1216MODULE_VERSION("0.2");
1217
1218/*
1219 * Local variables:
1220 * c-basic-offset: 8
1221 * End:
1222 */
diff --git a/drivers/media/dvb/frontends/lgdt3305.h b/drivers/media/dvb/frontends/lgdt3305.h
new file mode 100644
index 00000000000..02172eca4d4
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3305.h
@@ -0,0 +1,91 @@
1/*
2 * Support for LG Electronics LGDT3304 and LGDT3305 - VSB/QAM
3 *
4 * Copyright (C) 2008, 2009, 2010 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 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 _LGDT3305_H_
23#define _LGDT3305_H_
24
25#include <linux/i2c.h>
26#include "dvb_frontend.h"
27
28
29enum lgdt3305_mpeg_mode {
30 LGDT3305_MPEG_PARALLEL = 0,
31 LGDT3305_MPEG_SERIAL = 1,
32};
33
34enum lgdt3305_tp_clock_edge {
35 LGDT3305_TPCLK_RISING_EDGE = 0,
36 LGDT3305_TPCLK_FALLING_EDGE = 1,
37};
38
39enum lgdt3305_tp_valid_polarity {
40 LGDT3305_TP_VALID_LOW = 0,
41 LGDT3305_TP_VALID_HIGH = 1,
42};
43
44enum lgdt_demod_chip_type {
45 LGDT3305 = 0,
46 LGDT3304 = 1,
47};
48
49struct lgdt3305_config {
50 u8 i2c_addr;
51
52 /* user defined IF frequency in KHz */
53 u16 qam_if_khz;
54 u16 vsb_if_khz;
55
56 /* AGC Power reference - defaults are used if left unset */
57 u16 usref_8vsb; /* default: 0x32c4 */
58 u16 usref_qam64; /* default: 0x5400 */
59 u16 usref_qam256; /* default: 0x2a80 */
60
61 /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */
62 unsigned int deny_i2c_rptr:1;
63
64 /* spectral inversion - 0:disabled 1:enabled */
65 unsigned int spectral_inversion:1;
66
67 /* use RF AGC loop - 0:disabled 1:enabled */
68 unsigned int rf_agc_loop:1;
69
70 enum lgdt3305_mpeg_mode mpeg_mode;
71 enum lgdt3305_tp_clock_edge tpclk_edge;
72 enum lgdt3305_tp_valid_polarity tpvalid_polarity;
73 enum lgdt_demod_chip_type demod_chip;
74};
75
76#if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \
77 defined(MODULE))
78extern
79struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
80 struct i2c_adapter *i2c_adap);
81#else
82static inline
83struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
84 struct i2c_adapter *i2c_adap)
85{
86 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
87 return NULL;
88}
89#endif /* CONFIG_DVB_LGDT3305 */
90
91#endif /* _LGDT3305_H_ */
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
new file mode 100644
index 00000000000..43971e63baa
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -0,0 +1,820 @@
1/*
2 * Support for LGDT3302 and LGDT3303 - VSB/QAM
3 *
4 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
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/*
23 * NOTES ABOUT THIS DRIVER
24 *
25 * This Linux driver supports:
26 * DViCO FusionHDTV 3 Gold-Q
27 * DViCO FusionHDTV 3 Gold-T
28 * DViCO FusionHDTV 5 Gold
29 * DViCO FusionHDTV 5 Lite
30 * DViCO FusionHDTV 5 USB Gold
31 * Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
32 * pcHDTV HD5500
33 *
34 */
35
36#include <linux/kernel.h>
37#include <linux/module.h>
38#include <linux/init.h>
39#include <linux/delay.h>
40#include <linux/string.h>
41#include <linux/slab.h>
42#include <asm/byteorder.h>
43
44#include "dvb_frontend.h"
45#include "dvb_math.h"
46#include "lgdt330x_priv.h"
47#include "lgdt330x.h"
48
49/* Use Equalizer Mean Squared Error instead of Phaser Tracker MSE */
50/* #define USE_EQMSE */
51
52static int debug;
53module_param(debug, int, 0644);
54MODULE_PARM_DESC(debug,"Turn on/off lgdt330x frontend debugging (default:off).");
55#define dprintk(args...) \
56do { \
57if (debug) printk(KERN_DEBUG "lgdt330x: " args); \
58} while (0)
59
60struct lgdt330x_state
61{
62 struct i2c_adapter* i2c;
63
64 /* Configuration settings */
65 const struct lgdt330x_config* config;
66
67 struct dvb_frontend frontend;
68
69 /* Demodulator private data */
70 fe_modulation_t current_modulation;
71 u32 snr; /* Result of last SNR calculation */
72
73 /* Tuner private data */
74 u32 current_frequency;
75};
76
77static int i2c_write_demod_bytes (struct lgdt330x_state* state,
78 u8 *buf, /* data bytes to send */
79 int len /* number of bytes to send */ )
80{
81 struct i2c_msg msg =
82 { .addr = state->config->demod_address,
83 .flags = 0,
84 .buf = buf,
85 .len = 2 };
86 int i;
87 int err;
88
89 for (i=0; i<len-1; i+=2){
90 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
91 printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __func__, msg.buf[0], msg.buf[1], err);
92 if (err < 0)
93 return err;
94 else
95 return -EREMOTEIO;
96 }
97 msg.buf += 2;
98 }
99 return 0;
100}
101
102/*
103 * This routine writes the register (reg) to the demod bus
104 * then reads the data returned for (len) bytes.
105 */
106
107static u8 i2c_read_demod_bytes (struct lgdt330x_state* state,
108 enum I2C_REG reg, u8* buf, int len)
109{
110 u8 wr [] = { reg };
111 struct i2c_msg msg [] = {
112 { .addr = state->config->demod_address,
113 .flags = 0, .buf = wr, .len = 1 },
114 { .addr = state->config->demod_address,
115 .flags = I2C_M_RD, .buf = buf, .len = len },
116 };
117 int ret;
118 ret = i2c_transfer(state->i2c, msg, 2);
119 if (ret != 2) {
120 printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __func__, state->config->demod_address, reg, ret);
121 } else {
122 ret = 0;
123 }
124 return ret;
125}
126
127/* Software reset */
128static int lgdt3302_SwReset(struct lgdt330x_state* state)
129{
130 u8 ret;
131 u8 reset[] = {
132 IRQ_MASK,
133 0x00 /* bit 6 is active low software reset
134 * bits 5-0 are 1 to mask interrupts */
135 };
136
137 ret = i2c_write_demod_bytes(state,
138 reset, sizeof(reset));
139 if (ret == 0) {
140
141 /* force reset high (inactive) and unmask interrupts */
142 reset[1] = 0x7f;
143 ret = i2c_write_demod_bytes(state,
144 reset, sizeof(reset));
145 }
146 return ret;
147}
148
149static int lgdt3303_SwReset(struct lgdt330x_state* state)
150{
151 u8 ret;
152 u8 reset[] = {
153 0x02,
154 0x00 /* bit 0 is active low software reset */
155 };
156
157 ret = i2c_write_demod_bytes(state,
158 reset, sizeof(reset));
159 if (ret == 0) {
160
161 /* force reset high (inactive) */
162 reset[1] = 0x01;
163 ret = i2c_write_demod_bytes(state,
164 reset, sizeof(reset));
165 }
166 return ret;
167}
168
169static int lgdt330x_SwReset(struct lgdt330x_state* state)
170{
171 switch (state->config->demod_chip) {
172 case LGDT3302:
173 return lgdt3302_SwReset(state);
174 case LGDT3303:
175 return lgdt3303_SwReset(state);
176 default:
177 return -ENODEV;
178 }
179}
180
181static int lgdt330x_init(struct dvb_frontend* fe)
182{
183 /* Hardware reset is done using gpio[0] of cx23880x chip.
184 * I'd like to do it here, but don't know how to find chip address.
185 * cx88-cards.c arranges for the reset bit to be inactive (high).
186 * Maybe there needs to be a callable function in cx88-core or
187 * the caller of this function needs to do it. */
188
189 /*
190 * Array of byte pairs <address, value>
191 * to initialize each different chip
192 */
193 static u8 lgdt3302_init_data[] = {
194 /* Use 50MHz parameter values from spec sheet since xtal is 50 */
195 /* Change the value of NCOCTFV[25:0] of carrier
196 recovery center frequency register */
197 VSB_CARRIER_FREQ0, 0x00,
198 VSB_CARRIER_FREQ1, 0x87,
199 VSB_CARRIER_FREQ2, 0x8e,
200 VSB_CARRIER_FREQ3, 0x01,
201 /* Change the TPCLK pin polarity
202 data is valid on falling clock */
203 DEMUX_CONTROL, 0xfb,
204 /* Change the value of IFBW[11:0] of
205 AGC IF/RF loop filter bandwidth register */
206 AGC_RF_BANDWIDTH0, 0x40,
207 AGC_RF_BANDWIDTH1, 0x93,
208 AGC_RF_BANDWIDTH2, 0x00,
209 /* Change the value of bit 6, 'nINAGCBY' and
210 'NSSEL[1:0] of ACG function control register 2 */
211 AGC_FUNC_CTRL2, 0xc6,
212 /* Change the value of bit 6 'RFFIX'
213 of AGC function control register 3 */
214 AGC_FUNC_CTRL3, 0x40,
215 /* Set the value of 'INLVTHD' register 0x2a/0x2c
216 to 0x7fe */
217 AGC_DELAY0, 0x07,
218 AGC_DELAY2, 0xfe,
219 /* Change the value of IAGCBW[15:8]
220 of inner AGC loop filter bandwidth */
221 AGC_LOOP_BANDWIDTH0, 0x08,
222 AGC_LOOP_BANDWIDTH1, 0x9a
223 };
224
225 static u8 lgdt3303_init_data[] = {
226 0x4c, 0x14
227 };
228
229 static u8 flip_1_lgdt3303_init_data[] = {
230 0x4c, 0x14,
231 0x87, 0xf3
232 };
233
234 static u8 flip_2_lgdt3303_init_data[] = {
235 0x4c, 0x14,
236 0x87, 0xda
237 };
238
239 struct lgdt330x_state* state = fe->demodulator_priv;
240 char *chip_name;
241 int err;
242
243 switch (state->config->demod_chip) {
244 case LGDT3302:
245 chip_name = "LGDT3302";
246 err = i2c_write_demod_bytes(state, lgdt3302_init_data,
247 sizeof(lgdt3302_init_data));
248 break;
249 case LGDT3303:
250 chip_name = "LGDT3303";
251 switch (state->config->clock_polarity_flip) {
252 case 2:
253 err = i2c_write_demod_bytes(state,
254 flip_2_lgdt3303_init_data,
255 sizeof(flip_2_lgdt3303_init_data));
256 break;
257 case 1:
258 err = i2c_write_demod_bytes(state,
259 flip_1_lgdt3303_init_data,
260 sizeof(flip_1_lgdt3303_init_data));
261 break;
262 case 0:
263 default:
264 err = i2c_write_demod_bytes(state, lgdt3303_init_data,
265 sizeof(lgdt3303_init_data));
266 }
267 break;
268 default:
269 chip_name = "undefined";
270 printk (KERN_WARNING "Only LGDT3302 and LGDT3303 are supported chips.\n");
271 err = -ENODEV;
272 }
273 dprintk("%s entered as %s\n", __func__, chip_name);
274 if (err < 0)
275 return err;
276 return lgdt330x_SwReset(state);
277}
278
279static int lgdt330x_read_ber(struct dvb_frontend* fe, u32* ber)
280{
281 *ber = 0; /* Not supplied by the demod chips */
282 return 0;
283}
284
285static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
286{
287 struct lgdt330x_state* state = fe->demodulator_priv;
288 int err;
289 u8 buf[2];
290
291 switch (state->config->demod_chip) {
292 case LGDT3302:
293 err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1,
294 buf, sizeof(buf));
295 break;
296 case LGDT3303:
297 err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1,
298 buf, sizeof(buf));
299 break;
300 default:
301 printk(KERN_WARNING
302 "Only LGDT3302 and LGDT3303 are supported chips.\n");
303 err = -ENODEV;
304 }
305
306 *ucblocks = (buf[0] << 8) | buf[1];
307 return 0;
308}
309
310static int lgdt330x_set_parameters(struct dvb_frontend* fe,
311 struct dvb_frontend_parameters *param)
312{
313 /*
314 * Array of byte pairs <address, value>
315 * to initialize 8VSB for lgdt3303 chip 50 MHz IF
316 */
317 static u8 lgdt3303_8vsb_44_data[] = {
318 0x04, 0x00,
319 0x0d, 0x40,
320 0x0e, 0x87,
321 0x0f, 0x8e,
322 0x10, 0x01,
323 0x47, 0x8b };
324
325 /*
326 * Array of byte pairs <address, value>
327 * to initialize QAM for lgdt3303 chip
328 */
329 static u8 lgdt3303_qam_data[] = {
330 0x04, 0x00,
331 0x0d, 0x00,
332 0x0e, 0x00,
333 0x0f, 0x00,
334 0x10, 0x00,
335 0x51, 0x63,
336 0x47, 0x66,
337 0x48, 0x66,
338 0x4d, 0x1a,
339 0x49, 0x08,
340 0x4a, 0x9b };
341
342 struct lgdt330x_state* state = fe->demodulator_priv;
343
344 static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 };
345
346 int err;
347 /* Change only if we are actually changing the modulation */
348 if (state->current_modulation != param->u.vsb.modulation) {
349 switch(param->u.vsb.modulation) {
350 case VSB_8:
351 dprintk("%s: VSB_8 MODE\n", __func__);
352
353 /* Select VSB mode */
354 top_ctrl_cfg[1] = 0x03;
355
356 /* Select ANT connector if supported by card */
357 if (state->config->pll_rf_set)
358 state->config->pll_rf_set(fe, 1);
359
360 if (state->config->demod_chip == LGDT3303) {
361 err = i2c_write_demod_bytes(state, lgdt3303_8vsb_44_data,
362 sizeof(lgdt3303_8vsb_44_data));
363 }
364 break;
365
366 case QAM_64:
367 dprintk("%s: QAM_64 MODE\n", __func__);
368
369 /* Select QAM_64 mode */
370 top_ctrl_cfg[1] = 0x00;
371
372 /* Select CABLE connector if supported by card */
373 if (state->config->pll_rf_set)
374 state->config->pll_rf_set(fe, 0);
375
376 if (state->config->demod_chip == LGDT3303) {
377 err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
378 sizeof(lgdt3303_qam_data));
379 }
380 break;
381
382 case QAM_256:
383 dprintk("%s: QAM_256 MODE\n", __func__);
384
385 /* Select QAM_256 mode */
386 top_ctrl_cfg[1] = 0x01;
387
388 /* Select CABLE connector if supported by card */
389 if (state->config->pll_rf_set)
390 state->config->pll_rf_set(fe, 0);
391
392 if (state->config->demod_chip == LGDT3303) {
393 err = i2c_write_demod_bytes(state, lgdt3303_qam_data,
394 sizeof(lgdt3303_qam_data));
395 }
396 break;
397 default:
398 printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __func__, param->u.vsb.modulation);
399 return -1;
400 }
401 /*
402 * select serial or parallel MPEG harware interface
403 * Serial: 0x04 for LGDT3302 or 0x40 for LGDT3303
404 * Parallel: 0x00
405 */
406 top_ctrl_cfg[1] |= state->config->serial_mpeg;
407
408 /* Select the requested mode */
409 i2c_write_demod_bytes(state, top_ctrl_cfg,
410 sizeof(top_ctrl_cfg));
411 if (state->config->set_ts_params)
412 state->config->set_ts_params(fe, 0);
413 state->current_modulation = param->u.vsb.modulation;
414 }
415
416 /* Tune to the specified frequency */
417 if (fe->ops.tuner_ops.set_params) {
418 fe->ops.tuner_ops.set_params(fe, param);
419 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
420 }
421
422 /* Keep track of the new frequency */
423 /* FIXME this is the wrong way to do this... */
424 /* The tuner is shared with the video4linux analog API */
425 state->current_frequency = param->frequency;
426
427 lgdt330x_SwReset(state);
428 return 0;
429}
430
431static int lgdt330x_get_frontend(struct dvb_frontend* fe,
432 struct dvb_frontend_parameters* param)
433{
434 struct lgdt330x_state *state = fe->demodulator_priv;
435 param->frequency = state->current_frequency;
436 return 0;
437}
438
439static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
440{
441 struct lgdt330x_state* state = fe->demodulator_priv;
442 u8 buf[3];
443
444 *status = 0; /* Reset status result */
445
446 /* AGC status register */
447 i2c_read_demod_bytes(state, AGC_STATUS, buf, 1);
448 dprintk("%s: AGC_STATUS = 0x%02x\n", __func__, buf[0]);
449 if ((buf[0] & 0x0c) == 0x8){
450 /* Test signal does not exist flag */
451 /* as well as the AGC lock flag. */
452 *status |= FE_HAS_SIGNAL;
453 }
454
455 /*
456 * You must set the Mask bits to 1 in the IRQ_MASK in order
457 * to see that status bit in the IRQ_STATUS register.
458 * This is done in SwReset();
459 */
460 /* signal status */
461 i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf));
462 dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __func__, buf[0], buf[1], buf[2]);
463
464
465 /* sync status */
466 if ((buf[2] & 0x03) == 0x01) {
467 *status |= FE_HAS_SYNC;
468 }
469
470 /* FEC error status */
471 if ((buf[2] & 0x0c) == 0x08) {
472 *status |= FE_HAS_LOCK;
473 *status |= FE_HAS_VITERBI;
474 }
475
476 /* Carrier Recovery Lock Status Register */
477 i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
478 dprintk("%s: CARRIER_LOCK = 0x%02x\n", __func__, buf[0]);
479 switch (state->current_modulation) {
480 case QAM_256:
481 case QAM_64:
482 /* Need to understand why there are 3 lock levels here */
483 if ((buf[0] & 0x07) == 0x07)
484 *status |= FE_HAS_CARRIER;
485 break;
486 case VSB_8:
487 if ((buf[0] & 0x80) == 0x80)
488 *status |= FE_HAS_CARRIER;
489 break;
490 default:
491 printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __func__);
492 }
493
494 return 0;
495}
496
497static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
498{
499 struct lgdt330x_state* state = fe->demodulator_priv;
500 int err;
501 u8 buf[3];
502
503 *status = 0; /* Reset status result */
504
505 /* lgdt3303 AGC status register */
506 err = i2c_read_demod_bytes(state, 0x58, buf, 1);
507 if (err < 0)
508 return err;
509
510 dprintk("%s: AGC_STATUS = 0x%02x\n", __func__, buf[0]);
511 if ((buf[0] & 0x21) == 0x01){
512 /* Test input signal does not exist flag */
513 /* as well as the AGC lock flag. */
514 *status |= FE_HAS_SIGNAL;
515 }
516
517 /* Carrier Recovery Lock Status Register */
518 i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
519 dprintk("%s: CARRIER_LOCK = 0x%02x\n", __func__, buf[0]);
520 switch (state->current_modulation) {
521 case QAM_256:
522 case QAM_64:
523 /* Need to understand why there are 3 lock levels here */
524 if ((buf[0] & 0x07) == 0x07)
525 *status |= FE_HAS_CARRIER;
526 else
527 break;
528 i2c_read_demod_bytes(state, 0x8a, buf, 1);
529 if ((buf[0] & 0x04) == 0x04)
530 *status |= FE_HAS_SYNC;
531 if ((buf[0] & 0x01) == 0x01)
532 *status |= FE_HAS_LOCK;
533 if ((buf[0] & 0x08) == 0x08)
534 *status |= FE_HAS_VITERBI;
535 break;
536 case VSB_8:
537 if ((buf[0] & 0x80) == 0x80)
538 *status |= FE_HAS_CARRIER;
539 else
540 break;
541 i2c_read_demod_bytes(state, 0x38, buf, 1);
542 if ((buf[0] & 0x02) == 0x00)
543 *status |= FE_HAS_SYNC;
544 if ((buf[0] & 0x01) == 0x01) {
545 *status |= FE_HAS_LOCK;
546 *status |= FE_HAS_VITERBI;
547 }
548 break;
549 default:
550 printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __func__);
551 }
552 return 0;
553}
554
555/* Calculate SNR estimation (scaled by 2^24)
556
557 8-VSB SNR equations from LGDT3302 and LGDT3303 datasheets, QAM
558 equations from LGDT3303 datasheet. VSB is the same between the '02
559 and '03, so maybe QAM is too? Perhaps someone with a newer datasheet
560 that has QAM information could verify?
561
562 For 8-VSB: (two ways, take your pick)
563 LGDT3302:
564 SNR_EQ = 10 * log10(25 * 24^2 / EQ_MSE)
565 LGDT3303:
566 SNR_EQ = 10 * log10(25 * 32^2 / EQ_MSE)
567 LGDT3302 & LGDT3303:
568 SNR_PT = 10 * log10(25 * 32^2 / PT_MSE) (we use this one)
569 For 64-QAM:
570 SNR = 10 * log10( 688128 / MSEQAM)
571 For 256-QAM:
572 SNR = 10 * log10( 696320 / MSEQAM)
573
574 We re-write the snr equation as:
575 SNR * 2^24 = 10*(c - intlog10(MSE))
576 Where for 256-QAM, c = log10(696320) * 2^24, and so on. */
577
578static u32 calculate_snr(u32 mse, u32 c)
579{
580 if (mse == 0) /* No signal */
581 return 0;
582
583 mse = intlog10(mse);
584 if (mse > c) {
585 /* Negative SNR, which is possible, but realisticly the
586 demod will lose lock before the signal gets this bad. The
587 API only allows for unsigned values, so just return 0 */
588 return 0;
589 }
590 return 10*(c - mse);
591}
592
593static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
594{
595 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
596 u8 buf[5]; /* read data buffer */
597 u32 noise; /* noise value */
598 u32 c; /* per-modulation SNR calculation constant */
599
600 switch(state->current_modulation) {
601 case VSB_8:
602 i2c_read_demod_bytes(state, LGDT3302_EQPH_ERR0, buf, 5);
603#ifdef USE_EQMSE
604 /* Use Equalizer Mean-Square Error Register */
605 /* SNR for ranges from -15.61 to +41.58 */
606 noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
607 c = 69765745; /* log10(25*24^2)*2^24 */
608#else
609 /* Use Phase Tracker Mean-Square Error Register */
610 /* SNR for ranges from -13.11 to +44.08 */
611 noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4];
612 c = 73957994; /* log10(25*32^2)*2^24 */
613#endif
614 break;
615 case QAM_64:
616 case QAM_256:
617 i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2);
618 noise = ((buf[0] & 3) << 8) | buf[1];
619 c = state->current_modulation == QAM_64 ? 97939837 : 98026066;
620 /* log10(688128)*2^24 and log10(696320)*2^24 */
621 break;
622 default:
623 printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n",
624 __func__);
625 return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */
626 }
627
628 state->snr = calculate_snr(noise, c);
629 *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */
630
631 dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise,
632 state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16);
633
634 return 0;
635}
636
637static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr)
638{
639 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
640 u8 buf[5]; /* read data buffer */
641 u32 noise; /* noise value */
642 u32 c; /* per-modulation SNR calculation constant */
643
644 switch(state->current_modulation) {
645 case VSB_8:
646 i2c_read_demod_bytes(state, LGDT3303_EQPH_ERR0, buf, 5);
647#ifdef USE_EQMSE
648 /* Use Equalizer Mean-Square Error Register */
649 /* SNR for ranges from -16.12 to +44.08 */
650 noise = ((buf[0] & 0x78) << 13) | (buf[1] << 8) | buf[2];
651 c = 73957994; /* log10(25*32^2)*2^24 */
652#else
653 /* Use Phase Tracker Mean-Square Error Register */
654 /* SNR for ranges from -13.11 to +44.08 */
655 noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
656 c = 73957994; /* log10(25*32^2)*2^24 */
657#endif
658 break;
659 case QAM_64:
660 case QAM_256:
661 i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2);
662 noise = (buf[0] << 8) | buf[1];
663 c = state->current_modulation == QAM_64 ? 97939837 : 98026066;
664 /* log10(688128)*2^24 and log10(696320)*2^24 */
665 break;
666 default:
667 printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n",
668 __func__);
669 return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */
670 }
671
672 state->snr = calculate_snr(noise, c);
673 *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */
674
675 dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise,
676 state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
677
678 return 0;
679}
680
681static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
682{
683 /* Calculate Strength from SNR up to 35dB */
684 /* Even though the SNR can go higher than 35dB, there is some comfort */
685 /* factor in having a range of strong signals that can show at 100% */
686 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
687 u16 snr;
688 int ret;
689
690 ret = fe->ops.read_snr(fe, &snr);
691 if (ret != 0)
692 return ret;
693 /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
694 /* scale the range 0 - 35*2^24 into 0 - 65535 */
695 if (state->snr >= 8960 * 0x10000)
696 *strength = 0xffff;
697 else
698 *strength = state->snr / 8960;
699
700 return 0;
701}
702
703static int lgdt330x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
704{
705 /* I have no idea about this - it may not be needed */
706 fe_tune_settings->min_delay_ms = 500;
707 fe_tune_settings->step_size = 0;
708 fe_tune_settings->max_drift = 0;
709 return 0;
710}
711
712static void lgdt330x_release(struct dvb_frontend* fe)
713{
714 struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv;
715 kfree(state);
716}
717
718static struct dvb_frontend_ops lgdt3302_ops;
719static struct dvb_frontend_ops lgdt3303_ops;
720
721struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
722 struct i2c_adapter* i2c)
723{
724 struct lgdt330x_state* state = NULL;
725 u8 buf[1];
726
727 /* Allocate memory for the internal state */
728 state = kzalloc(sizeof(struct lgdt330x_state), GFP_KERNEL);
729 if (state == NULL)
730 goto error;
731
732 /* Setup the state */
733 state->config = config;
734 state->i2c = i2c;
735
736 /* Create dvb_frontend */
737 switch (config->demod_chip) {
738 case LGDT3302:
739 memcpy(&state->frontend.ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
740 break;
741 case LGDT3303:
742 memcpy(&state->frontend.ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops));
743 break;
744 default:
745 goto error;
746 }
747 state->frontend.demodulator_priv = state;
748
749 /* Verify communication with demod chip */
750 if (i2c_read_demod_bytes(state, 2, buf, 1))
751 goto error;
752
753 state->current_frequency = -1;
754 state->current_modulation = -1;
755
756 return &state->frontend;
757
758error:
759 kfree(state);
760 dprintk("%s: ERROR\n",__func__);
761 return NULL;
762}
763
764static struct dvb_frontend_ops lgdt3302_ops = {
765 .info = {
766 .name= "LG Electronics LGDT3302 VSB/QAM Frontend",
767 .type = FE_ATSC,
768 .frequency_min= 54000000,
769 .frequency_max= 858000000,
770 .frequency_stepsize= 62500,
771 .symbol_rate_min = 5056941, /* QAM 64 */
772 .symbol_rate_max = 10762000, /* VSB 8 */
773 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
774 },
775 .init = lgdt330x_init,
776 .set_frontend = lgdt330x_set_parameters,
777 .get_frontend = lgdt330x_get_frontend,
778 .get_tune_settings = lgdt330x_get_tune_settings,
779 .read_status = lgdt3302_read_status,
780 .read_ber = lgdt330x_read_ber,
781 .read_signal_strength = lgdt330x_read_signal_strength,
782 .read_snr = lgdt3302_read_snr,
783 .read_ucblocks = lgdt330x_read_ucblocks,
784 .release = lgdt330x_release,
785};
786
787static struct dvb_frontend_ops lgdt3303_ops = {
788 .info = {
789 .name= "LG Electronics LGDT3303 VSB/QAM Frontend",
790 .type = FE_ATSC,
791 .frequency_min= 54000000,
792 .frequency_max= 858000000,
793 .frequency_stepsize= 62500,
794 .symbol_rate_min = 5056941, /* QAM 64 */
795 .symbol_rate_max = 10762000, /* VSB 8 */
796 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
797 },
798 .init = lgdt330x_init,
799 .set_frontend = lgdt330x_set_parameters,
800 .get_frontend = lgdt330x_get_frontend,
801 .get_tune_settings = lgdt330x_get_tune_settings,
802 .read_status = lgdt3303_read_status,
803 .read_ber = lgdt330x_read_ber,
804 .read_signal_strength = lgdt330x_read_signal_strength,
805 .read_snr = lgdt3303_read_snr,
806 .read_ucblocks = lgdt330x_read_ucblocks,
807 .release = lgdt330x_release,
808};
809
810MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
811MODULE_AUTHOR("Wilson Michaels");
812MODULE_LICENSE("GPL");
813
814EXPORT_SYMBOL(lgdt330x_attach);
815
816/*
817 * Local variables:
818 * c-basic-offset: 8
819 * End:
820 */
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h
new file mode 100644
index 00000000000..9012504f0f2
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt330x.h
@@ -0,0 +1,73 @@
1/*
2 * Support for LGDT3302 and LGDT3303 - VSB/QAM
3 *
4 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
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 LGDT330X_H
23#define LGDT330X_H
24
25#include <linux/dvb/frontend.h>
26
27typedef enum lg_chip_t {
28 UNDEFINED,
29 LGDT3302,
30 LGDT3303
31}lg_chip_type;
32
33struct lgdt330x_config
34{
35 /* The demodulator's i2c address */
36 u8 demod_address;
37
38 /* LG demodulator chip LGDT3302 or LGDT3303 */
39 lg_chip_type demod_chip;
40
41 /* MPEG hardware interface - 0:parallel 1:serial */
42 int serial_mpeg;
43
44 /* PLL interface */
45 int (*pll_rf_set) (struct dvb_frontend* fe, int index);
46
47 /* Need to set device param for start_dma */
48 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
49
50 /* Flip the polarity of the mpeg data transfer clock using alternate init data
51 * This option applies ONLY to LGDT3303 - 0:disabled (default) 1:enabled */
52 int clock_polarity_flip;
53};
54
55#if defined(CONFIG_DVB_LGDT330X) || (defined(CONFIG_DVB_LGDT330X_MODULE) && defined(MODULE))
56extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
57 struct i2c_adapter* i2c);
58#else
59static inline struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
60 struct i2c_adapter* i2c)
61{
62 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
63 return NULL;
64}
65#endif // CONFIG_DVB_LGDT330X
66
67#endif /* LGDT330X_H */
68
69/*
70 * Local variables:
71 * c-basic-offset: 8
72 * End:
73 */
diff --git a/drivers/media/dvb/frontends/lgdt330x_priv.h b/drivers/media/dvb/frontends/lgdt330x_priv.h
new file mode 100644
index 00000000000..38c76695abf
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt330x_priv.h
@@ -0,0 +1,77 @@
1/*
2 * Support for LGDT3302 and LGDT3303 - VSB/QAM
3 *
4 * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
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 _LGDT330X_PRIV_
23#define _LGDT330X_PRIV_
24
25/* i2c control register addresses */
26enum I2C_REG {
27 TOP_CONTROL= 0x00,
28 IRQ_MASK= 0x01,
29 IRQ_STATUS= 0x02,
30 VSB_CARRIER_FREQ0= 0x16,
31 VSB_CARRIER_FREQ1= 0x17,
32 VSB_CARRIER_FREQ2= 0x18,
33 VSB_CARRIER_FREQ3= 0x19,
34 CARRIER_MSEQAM1= 0x1a,
35 CARRIER_MSEQAM2= 0x1b,
36 CARRIER_LOCK= 0x1c,
37 TIMING_RECOVERY= 0x1d,
38 AGC_DELAY0= 0x2a,
39 AGC_DELAY1= 0x2b,
40 AGC_DELAY2= 0x2c,
41 AGC_RF_BANDWIDTH0= 0x2d,
42 AGC_RF_BANDWIDTH1= 0x2e,
43 AGC_RF_BANDWIDTH2= 0x2f,
44 AGC_LOOP_BANDWIDTH0= 0x30,
45 AGC_LOOP_BANDWIDTH1= 0x31,
46 AGC_FUNC_CTRL1= 0x32,
47 AGC_FUNC_CTRL2= 0x33,
48 AGC_FUNC_CTRL3= 0x34,
49 AGC_RFIF_ACC0= 0x39,
50 AGC_RFIF_ACC1= 0x3a,
51 AGC_RFIF_ACC2= 0x3b,
52 AGC_STATUS= 0x3f,
53 SYNC_STATUS_VSB= 0x43,
54 DEMUX_CONTROL= 0x66,
55 LGDT3302_EQPH_ERR0= 0x47,
56 LGDT3302_EQ_ERR1= 0x48,
57 LGDT3302_EQ_ERR2= 0x49,
58 LGDT3302_PH_ERR1= 0x4a,
59 LGDT3302_PH_ERR2= 0x4b,
60 LGDT3302_PACKET_ERR_COUNTER1= 0x6a,
61 LGDT3302_PACKET_ERR_COUNTER2= 0x6b,
62 LGDT3303_EQPH_ERR0= 0x6e,
63 LGDT3303_EQ_ERR1= 0x6f,
64 LGDT3303_EQ_ERR2= 0x70,
65 LGDT3303_PH_ERR1= 0x71,
66 LGDT3303_PH_ERR2= 0x72,
67 LGDT3303_PACKET_ERR_COUNTER1= 0x8b,
68 LGDT3303_PACKET_ERR_COUNTER2= 0x8c,
69};
70
71#endif /* _LGDT330X_PRIV_ */
72
73/*
74 * Local variables:
75 * c-basic-offset: 8
76 * End:
77 */
diff --git a/drivers/media/dvb/frontends/lgs8gl5.c b/drivers/media/dvb/frontends/lgs8gl5.c
new file mode 100644
index 00000000000..bb37ed289a0
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgs8gl5.c
@@ -0,0 +1,454 @@
1/*
2 Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver
3
4 Copyright (C) 2008 Sirius International (Hong Kong) Limited
5 Timothy Lee <timothy.lee@siriushk.com>
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/kernel.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28#include "dvb_frontend.h"
29#include "lgs8gl5.h"
30
31
32#define REG_RESET 0x02
33#define REG_RESET_OFF 0x01
34#define REG_03 0x03
35#define REG_04 0x04
36#define REG_07 0x07
37#define REG_09 0x09
38#define REG_0A 0x0a
39#define REG_0B 0x0b
40#define REG_0C 0x0c
41#define REG_37 0x37
42#define REG_STRENGTH 0x4b
43#define REG_STRENGTH_MASK 0x7f
44#define REG_STRENGTH_CARRIER 0x80
45#define REG_INVERSION 0x7c
46#define REG_INVERSION_ON 0x80
47#define REG_7D 0x7d
48#define REG_7E 0x7e
49#define REG_A2 0xa2
50#define REG_STATUS 0xa4
51#define REG_STATUS_SYNC 0x04
52#define REG_STATUS_LOCK 0x01
53
54
55struct lgs8gl5_state {
56 struct i2c_adapter *i2c;
57 const struct lgs8gl5_config *config;
58 struct dvb_frontend frontend;
59};
60
61
62static int debug;
63#define dprintk(args...) \
64 do { \
65 if (debug) \
66 printk(KERN_DEBUG "lgs8gl5: " args); \
67 } while (0)
68
69
70/* Writes into demod's register */
71static int
72lgs8gl5_write_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
73{
74 int ret;
75 u8 buf[] = {reg, data};
76 struct i2c_msg msg = {
77 .addr = state->config->demod_address,
78 .flags = 0,
79 .buf = buf,
80 .len = 2
81 };
82
83 ret = i2c_transfer(state->i2c, &msg, 1);
84 if (ret != 1)
85 dprintk("%s: error (reg=0x%02x, val=0x%02x, ret=%i)\n",
86 __func__, reg, data, ret);
87 return (ret != 1) ? -1 : 0;
88}
89
90
91/* Reads from demod's register */
92static int
93lgs8gl5_read_reg(struct lgs8gl5_state *state, u8 reg)
94{
95 int ret;
96 u8 b0[] = {reg};
97 u8 b1[] = {0};
98 struct i2c_msg msg[2] = {
99 {
100 .addr = state->config->demod_address,
101 .flags = 0,
102 .buf = b0,
103 .len = 1
104 },
105 {
106 .addr = state->config->demod_address,
107 .flags = I2C_M_RD,
108 .buf = b1,
109 .len = 1
110 }
111 };
112
113 ret = i2c_transfer(state->i2c, msg, 2);
114 if (ret != 2)
115 return -EIO;
116
117 return b1[0];
118}
119
120
121static int
122lgs8gl5_update_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
123{
124 lgs8gl5_read_reg(state, reg);
125 lgs8gl5_write_reg(state, reg, data);
126 return 0;
127}
128
129
130/* Writes into alternate device's register */
131/* TODO: Find out what that device is for! */
132static int
133lgs8gl5_update_alt_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
134{
135 int ret;
136 u8 b0[] = {reg};
137 u8 b1[] = {0};
138 u8 b2[] = {reg, data};
139 struct i2c_msg msg[3] = {
140 {
141 .addr = state->config->demod_address + 2,
142 .flags = 0,
143 .buf = b0,
144 .len = 1
145 },
146 {
147 .addr = state->config->demod_address + 2,
148 .flags = I2C_M_RD,
149 .buf = b1,
150 .len = 1
151 },
152 {
153 .addr = state->config->demod_address + 2,
154 .flags = 0,
155 .buf = b2,
156 .len = 2
157 },
158 };
159
160 ret = i2c_transfer(state->i2c, msg, 3);
161 return (ret != 3) ? -1 : 0;
162}
163
164
165static void
166lgs8gl5_soft_reset(struct lgs8gl5_state *state)
167{
168 u8 val;
169
170 dprintk("%s\n", __func__);
171
172 val = lgs8gl5_read_reg(state, REG_RESET);
173 lgs8gl5_write_reg(state, REG_RESET, val & ~REG_RESET_OFF);
174 lgs8gl5_write_reg(state, REG_RESET, val | REG_RESET_OFF);
175 msleep(5);
176}
177
178
179/* Starts demodulation */
180static void
181lgs8gl5_start_demod(struct lgs8gl5_state *state)
182{
183 u8 val;
184 int n;
185
186 dprintk("%s\n", __func__);
187
188 lgs8gl5_update_alt_reg(state, 0xc2, 0x28);
189 lgs8gl5_soft_reset(state);
190 lgs8gl5_update_reg(state, REG_07, 0x10);
191 lgs8gl5_update_reg(state, REG_07, 0x10);
192 lgs8gl5_write_reg(state, REG_09, 0x0e);
193 lgs8gl5_write_reg(state, REG_0A, 0xe5);
194 lgs8gl5_write_reg(state, REG_0B, 0x35);
195 lgs8gl5_write_reg(state, REG_0C, 0x30);
196
197 lgs8gl5_update_reg(state, REG_03, 0x00);
198 lgs8gl5_update_reg(state, REG_7E, 0x01);
199 lgs8gl5_update_alt_reg(state, 0xc5, 0x00);
200 lgs8gl5_update_reg(state, REG_04, 0x02);
201 lgs8gl5_update_reg(state, REG_37, 0x01);
202 lgs8gl5_soft_reset(state);
203
204 /* Wait for carrier */
205 for (n = 0; n < 10; n++) {
206 val = lgs8gl5_read_reg(state, REG_STRENGTH);
207 dprintk("Wait for carrier[%d] 0x%02X\n", n, val);
208 if (val & REG_STRENGTH_CARRIER)
209 break;
210 msleep(4);
211 }
212 if (!(val & REG_STRENGTH_CARRIER))
213 return;
214
215 /* Wait for lock */
216 for (n = 0; n < 20; n++) {
217 val = lgs8gl5_read_reg(state, REG_STATUS);
218 dprintk("Wait for lock[%d] 0x%02X\n", n, val);
219 if (val & REG_STATUS_LOCK)
220 break;
221 msleep(12);
222 }
223 if (!(val & REG_STATUS_LOCK))
224 return;
225
226 lgs8gl5_write_reg(state, REG_7D, lgs8gl5_read_reg(state, REG_A2));
227 lgs8gl5_soft_reset(state);
228}
229
230
231static int
232lgs8gl5_init(struct dvb_frontend *fe)
233{
234 struct lgs8gl5_state *state = fe->demodulator_priv;
235
236 dprintk("%s\n", __func__);
237
238 lgs8gl5_update_alt_reg(state, 0xc2, 0x28);
239 lgs8gl5_soft_reset(state);
240 lgs8gl5_update_reg(state, REG_07, 0x10);
241 lgs8gl5_update_reg(state, REG_07, 0x10);
242 lgs8gl5_write_reg(state, REG_09, 0x0e);
243 lgs8gl5_write_reg(state, REG_0A, 0xe5);
244 lgs8gl5_write_reg(state, REG_0B, 0x35);
245 lgs8gl5_write_reg(state, REG_0C, 0x30);
246
247 return 0;
248}
249
250
251static int
252lgs8gl5_read_status(struct dvb_frontend *fe, fe_status_t *status)
253{
254 struct lgs8gl5_state *state = fe->demodulator_priv;
255 u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
256 u8 flags = lgs8gl5_read_reg(state, REG_STATUS);
257
258 *status = 0;
259
260 if ((level & REG_STRENGTH_MASK) > 0)
261 *status |= FE_HAS_SIGNAL;
262 if (level & REG_STRENGTH_CARRIER)
263 *status |= FE_HAS_CARRIER;
264 if (flags & REG_STATUS_SYNC)
265 *status |= FE_HAS_SYNC;
266 if (flags & REG_STATUS_LOCK)
267 *status |= FE_HAS_LOCK;
268
269 return 0;
270}
271
272
273static int
274lgs8gl5_read_ber(struct dvb_frontend *fe, u32 *ber)
275{
276 *ber = 0;
277
278 return 0;
279}
280
281
282static int
283lgs8gl5_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength)
284{
285 struct lgs8gl5_state *state = fe->demodulator_priv;
286 u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
287 *signal_strength = (level & REG_STRENGTH_MASK) << 8;
288
289 return 0;
290}
291
292
293static int
294lgs8gl5_read_snr(struct dvb_frontend *fe, u16 *snr)
295{
296 struct lgs8gl5_state *state = fe->demodulator_priv;
297 u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
298 *snr = (level & REG_STRENGTH_MASK) << 8;
299
300 return 0;
301}
302
303
304static int
305lgs8gl5_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
306{
307 *ucblocks = 0;
308
309 return 0;
310}
311
312
313static int
314lgs8gl5_set_frontend(struct dvb_frontend *fe,
315 struct dvb_frontend_parameters *p)
316{
317 struct lgs8gl5_state *state = fe->demodulator_priv;
318
319 dprintk("%s\n", __func__);
320
321 if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ)
322 return -EINVAL;
323
324 if (fe->ops.tuner_ops.set_params) {
325 fe->ops.tuner_ops.set_params(fe, p);
326 if (fe->ops.i2c_gate_ctrl)
327 fe->ops.i2c_gate_ctrl(fe, 0);
328 }
329
330 /* lgs8gl5_set_inversion(state, p->inversion); */
331
332 lgs8gl5_start_demod(state);
333
334 return 0;
335}
336
337
338static int
339lgs8gl5_get_frontend(struct dvb_frontend *fe,
340 struct dvb_frontend_parameters *p)
341{
342 struct lgs8gl5_state *state = fe->demodulator_priv;
343 u8 inv = lgs8gl5_read_reg(state, REG_INVERSION);
344 struct dvb_ofdm_parameters *o = &p->u.ofdm;
345
346 p->inversion = (inv & REG_INVERSION_ON) ? INVERSION_ON : INVERSION_OFF;
347
348 o->code_rate_HP = FEC_1_2;
349 o->code_rate_LP = FEC_7_8;
350 o->guard_interval = GUARD_INTERVAL_1_32;
351 o->transmission_mode = TRANSMISSION_MODE_2K;
352 o->constellation = QAM_64;
353 o->hierarchy_information = HIERARCHY_NONE;
354 o->bandwidth = BANDWIDTH_8_MHZ;
355
356 return 0;
357}
358
359
360static int
361lgs8gl5_get_tune_settings(struct dvb_frontend *fe,
362 struct dvb_frontend_tune_settings *fesettings)
363{
364 fesettings->min_delay_ms = 240;
365 fesettings->step_size = 0;
366 fesettings->max_drift = 0;
367 return 0;
368}
369
370
371static void
372lgs8gl5_release(struct dvb_frontend *fe)
373{
374 struct lgs8gl5_state *state = fe->demodulator_priv;
375 kfree(state);
376}
377
378
379static struct dvb_frontend_ops lgs8gl5_ops;
380
381
382struct dvb_frontend*
383lgs8gl5_attach(const struct lgs8gl5_config *config, struct i2c_adapter *i2c)
384{
385 struct lgs8gl5_state *state = NULL;
386
387 dprintk("%s\n", __func__);
388
389 /* Allocate memory for the internal state */
390 state = kzalloc(sizeof(struct lgs8gl5_state), GFP_KERNEL);
391 if (state == NULL)
392 goto error;
393
394 /* Setup the state */
395 state->config = config;
396 state->i2c = i2c;
397
398 /* Check if the demod is there */
399 if (lgs8gl5_read_reg(state, REG_RESET) < 0)
400 goto error;
401
402 /* Create dvb_frontend */
403 memcpy(&state->frontend.ops, &lgs8gl5_ops,
404 sizeof(struct dvb_frontend_ops));
405 state->frontend.demodulator_priv = state;
406 return &state->frontend;
407
408error:
409 kfree(state);
410 return NULL;
411}
412EXPORT_SYMBOL(lgs8gl5_attach);
413
414
415static struct dvb_frontend_ops lgs8gl5_ops = {
416 .info = {
417 .name = "Legend Silicon LGS-8GL5 DMB-TH",
418 .type = FE_OFDM,
419 .frequency_min = 474000000,
420 .frequency_max = 858000000,
421 .frequency_stepsize = 10000,
422 .frequency_tolerance = 0,
423 .caps = FE_CAN_FEC_AUTO |
424 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 |
425 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
426 FE_CAN_TRANSMISSION_MODE_AUTO |
427 FE_CAN_BANDWIDTH_AUTO |
428 FE_CAN_GUARD_INTERVAL_AUTO |
429 FE_CAN_HIERARCHY_AUTO |
430 FE_CAN_RECOVER
431 },
432
433 .release = lgs8gl5_release,
434
435 .init = lgs8gl5_init,
436
437 .set_frontend = lgs8gl5_set_frontend,
438 .get_frontend = lgs8gl5_get_frontend,
439 .get_tune_settings = lgs8gl5_get_tune_settings,
440
441 .read_status = lgs8gl5_read_status,
442 .read_ber = lgs8gl5_read_ber,
443 .read_signal_strength = lgs8gl5_read_signal_strength,
444 .read_snr = lgs8gl5_read_snr,
445 .read_ucblocks = lgs8gl5_read_ucblocks,
446};
447
448
449module_param(debug, int, 0644);
450MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
451
452MODULE_DESCRIPTION("Legend Silicon LGS-8GL5 DMB-TH Demodulator driver");
453MODULE_AUTHOR("Timothy Lee");
454MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lgs8gl5.h b/drivers/media/dvb/frontends/lgs8gl5.h
new file mode 100644
index 00000000000..d14176787a7
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgs8gl5.h
@@ -0,0 +1,45 @@
1/*
2 Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver
3
4 Copyright (C) 2008 Sirius International (Hong Kong) Limited
5 Timothy Lee <timothy.lee@siriushk.com>
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#ifndef LGS8GL5_H
24#define LGS8GL5_H
25
26#include <linux/dvb/frontend.h>
27
28struct lgs8gl5_config {
29 /* the demodulator's i2c address */
30 u8 demod_address;
31};
32
33#if defined(CONFIG_DVB_LGS8GL5) || \
34 (defined(CONFIG_DVB_LGS8GL5_MODULE) && defined(MODULE))
35extern struct dvb_frontend *lgs8gl5_attach(
36 const struct lgs8gl5_config *config, struct i2c_adapter *i2c);
37#else
38static inline struct dvb_frontend *lgs8gl5_attach(
39 const struct lgs8gl5_config *config, struct i2c_adapter *i2c) {
40 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
41 return NULL;
42}
43#endif /* CONFIG_DVB_LGS8GL5 */
44
45#endif /* LGS8GL5_H */
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c
new file mode 100644
index 00000000000..1172b54689f
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgs8gxx.c
@@ -0,0 +1,1073 @@
1/*
2 * Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
3 * LGS8913, LGS8GL5, LGS8G75
4 * experimental support LGS8G42, LGS8G52
5 *
6 * Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
7 * Copyright (C) 2008 Sirius International (Hong Kong) Limited
8 * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
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 */
25
26#include <asm/div64.h>
27#include <linux/firmware.h>
28
29#include "dvb_frontend.h"
30
31#include "lgs8gxx.h"
32#include "lgs8gxx_priv.h"
33
34#define dprintk(args...) \
35 do { \
36 if (debug) \
37 printk(KERN_DEBUG "lgs8gxx: " args); \
38 } while (0)
39
40static int debug;
41static int fake_signal_str = 1;
42
43module_param(debug, int, 0644);
44MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
45
46module_param(fake_signal_str, int, 0644);
47MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913."
48"Signal strength calculation is slow.(default:on).");
49
50/* LGS8GXX internal helper functions */
51
52static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data)
53{
54 int ret;
55 u8 buf[] = { reg, data };
56 struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
57
58 msg.addr = priv->config->demod_address;
59 if (priv->config->prod != LGS8GXX_PROD_LGS8G75 && reg >= 0xC0)
60 msg.addr += 0x02;
61
62 if (debug >= 2)
63 dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, data);
64
65 ret = i2c_transfer(priv->i2c, &msg, 1);
66
67 if (ret != 1)
68 dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
69 __func__, reg, data, ret);
70
71 return (ret != 1) ? -1 : 0;
72}
73
74static int lgs8gxx_read_reg(struct lgs8gxx_state *priv, u8 reg, u8 *p_data)
75{
76 int ret;
77 u8 dev_addr;
78
79 u8 b0[] = { reg };
80 u8 b1[] = { 0 };
81 struct i2c_msg msg[] = {
82 { .flags = 0, .buf = b0, .len = 1 },
83 { .flags = I2C_M_RD, .buf = b1, .len = 1 },
84 };
85
86 dev_addr = priv->config->demod_address;
87 if (priv->config->prod != LGS8GXX_PROD_LGS8G75 && reg >= 0xC0)
88 dev_addr += 0x02;
89 msg[1].addr = msg[0].addr = dev_addr;
90
91 ret = i2c_transfer(priv->i2c, msg, 2);
92 if (ret != 2) {
93 dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret);
94 return -1;
95 }
96
97 *p_data = b1[0];
98 if (debug >= 2)
99 dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, b1[0]);
100 return 0;
101}
102
103static int lgs8gxx_soft_reset(struct lgs8gxx_state *priv)
104{
105 lgs8gxx_write_reg(priv, 0x02, 0x00);
106 msleep(1);
107 lgs8gxx_write_reg(priv, 0x02, 0x01);
108 msleep(100);
109
110 return 0;
111}
112
113static int wait_reg_mask(struct lgs8gxx_state *priv, u8 reg, u8 mask,
114 u8 val, u8 delay, u8 tries)
115{
116 u8 t;
117 int i;
118
119 for (i = 0; i < tries; i++) {
120 lgs8gxx_read_reg(priv, reg, &t);
121
122 if ((t & mask) == val)
123 return 0;
124 msleep(delay);
125 }
126
127 return 1;
128}
129
130static int lgs8gxx_set_ad_mode(struct lgs8gxx_state *priv)
131{
132 const struct lgs8gxx_config *config = priv->config;
133 u8 if_conf;
134
135 if_conf = 0x10; /* AGC output on, RF_AGC output off; */
136
137 if_conf |=
138 ((config->ext_adc) ? 0x80 : 0x00) |
139 ((config->if_neg_center) ? 0x04 : 0x00) |
140 ((config->if_freq == 0) ? 0x08 : 0x00) | /* Baseband */
141 ((config->adc_signed) ? 0x02 : 0x00) |
142 ((config->if_neg_edge) ? 0x01 : 0x00);
143
144 if (config->ext_adc &&
145 (config->prod == LGS8GXX_PROD_LGS8G52)) {
146 lgs8gxx_write_reg(priv, 0xBA, 0x40);
147 }
148
149 lgs8gxx_write_reg(priv, 0x07, if_conf);
150
151 return 0;
152}
153
154static int lgs8gxx_set_if_freq(struct lgs8gxx_state *priv, u32 freq /*in kHz*/)
155{
156 u64 val;
157 u32 v32;
158 u32 if_clk;
159
160 if_clk = priv->config->if_clk_freq;
161
162 val = freq;
163 if (freq != 0) {
164 val <<= 32;
165 if (if_clk != 0)
166 do_div(val, if_clk);
167 v32 = val & 0xFFFFFFFF;
168 dprintk("Set IF Freq to %dkHz\n", freq);
169 } else {
170 v32 = 0;
171 dprintk("Set IF Freq to baseband\n");
172 }
173 dprintk("AFC_INIT_FREQ = 0x%08X\n", v32);
174
175 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
176 lgs8gxx_write_reg(priv, 0x08, 0xFF & (v32));
177 lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32 >> 8));
178 lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 16));
179 lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 24));
180 } else {
181 lgs8gxx_write_reg(priv, 0x09, 0xFF & (v32));
182 lgs8gxx_write_reg(priv, 0x0A, 0xFF & (v32 >> 8));
183 lgs8gxx_write_reg(priv, 0x0B, 0xFF & (v32 >> 16));
184 lgs8gxx_write_reg(priv, 0x0C, 0xFF & (v32 >> 24));
185 }
186
187 return 0;
188}
189
190static int lgs8gxx_get_afc_phase(struct lgs8gxx_state *priv)
191{
192 u64 val;
193 u32 v32 = 0;
194 u8 reg_addr, t;
195 int i;
196
197 if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
198 reg_addr = 0x23;
199 else
200 reg_addr = 0x48;
201
202 for (i = 0; i < 4; i++) {
203 lgs8gxx_read_reg(priv, reg_addr, &t);
204 v32 <<= 8;
205 v32 |= t;
206 reg_addr--;
207 }
208
209 val = v32;
210 val *= priv->config->if_clk_freq;
211 val >>= 32;
212 dprintk("AFC = %u kHz\n", (u32)val);
213 return 0;
214}
215
216static int lgs8gxx_set_mode_auto(struct lgs8gxx_state *priv)
217{
218 u8 t;
219 u8 prod = priv->config->prod;
220
221 if (prod == LGS8GXX_PROD_LGS8913)
222 lgs8gxx_write_reg(priv, 0xC6, 0x01);
223
224 if (prod == LGS8GXX_PROD_LGS8G75) {
225 lgs8gxx_read_reg(priv, 0x0C, &t);
226 t &= (~0x04);
227 lgs8gxx_write_reg(priv, 0x0C, t | 0x80);
228 lgs8gxx_write_reg(priv, 0x39, 0x00);
229 lgs8gxx_write_reg(priv, 0x3D, 0x04);
230 } else if (prod == LGS8GXX_PROD_LGS8913 ||
231 prod == LGS8GXX_PROD_LGS8GL5 ||
232 prod == LGS8GXX_PROD_LGS8G42 ||
233 prod == LGS8GXX_PROD_LGS8G52 ||
234 prod == LGS8GXX_PROD_LGS8G54) {
235 lgs8gxx_read_reg(priv, 0x7E, &t);
236 lgs8gxx_write_reg(priv, 0x7E, t | 0x01);
237
238 /* clear FEC self reset */
239 lgs8gxx_read_reg(priv, 0xC5, &t);
240 lgs8gxx_write_reg(priv, 0xC5, t & 0xE0);
241 }
242
243 if (prod == LGS8GXX_PROD_LGS8913) {
244 /* FEC auto detect */
245 lgs8gxx_write_reg(priv, 0xC1, 0x03);
246
247 lgs8gxx_read_reg(priv, 0x7C, &t);
248 t = (t & 0x8C) | 0x03;
249 lgs8gxx_write_reg(priv, 0x7C, t);
250
251 /* BER test mode */
252 lgs8gxx_read_reg(priv, 0xC3, &t);
253 t = (t & 0xEF) | 0x10;
254 lgs8gxx_write_reg(priv, 0xC3, t);
255 }
256
257 if (priv->config->prod == LGS8GXX_PROD_LGS8G52)
258 lgs8gxx_write_reg(priv, 0xD9, 0x40);
259
260 return 0;
261}
262
263static int lgs8gxx_set_mode_manual(struct lgs8gxx_state *priv)
264{
265 int ret = 0;
266 u8 t;
267
268 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
269 u8 t2;
270 lgs8gxx_read_reg(priv, 0x0C, &t);
271 t &= (~0x80);
272 lgs8gxx_write_reg(priv, 0x0C, t);
273
274 lgs8gxx_read_reg(priv, 0x0C, &t);
275 lgs8gxx_read_reg(priv, 0x19, &t2);
276
277 if (((t&0x03) == 0x01) && (t2&0x01)) {
278 lgs8gxx_write_reg(priv, 0x6E, 0x05);
279 lgs8gxx_write_reg(priv, 0x39, 0x02);
280 lgs8gxx_write_reg(priv, 0x39, 0x03);
281 lgs8gxx_write_reg(priv, 0x3D, 0x05);
282 lgs8gxx_write_reg(priv, 0x3E, 0x28);
283 lgs8gxx_write_reg(priv, 0x53, 0x80);
284 } else {
285 lgs8gxx_write_reg(priv, 0x6E, 0x3F);
286 lgs8gxx_write_reg(priv, 0x39, 0x00);
287 lgs8gxx_write_reg(priv, 0x3D, 0x04);
288 }
289
290 lgs8gxx_soft_reset(priv);
291 return 0;
292 }
293
294 /* turn off auto-detect; manual settings */
295 lgs8gxx_write_reg(priv, 0x7E, 0);
296 if (priv->config->prod == LGS8GXX_PROD_LGS8913)
297 lgs8gxx_write_reg(priv, 0xC1, 0);
298
299 ret = lgs8gxx_read_reg(priv, 0xC5, &t);
300 t = (t & 0xE0) | 0x06;
301 lgs8gxx_write_reg(priv, 0xC5, t);
302
303 lgs8gxx_soft_reset(priv);
304
305 return 0;
306}
307
308static int lgs8gxx_is_locked(struct lgs8gxx_state *priv, u8 *locked)
309{
310 int ret = 0;
311 u8 t;
312
313 if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
314 ret = lgs8gxx_read_reg(priv, 0x13, &t);
315 else
316 ret = lgs8gxx_read_reg(priv, 0x4B, &t);
317 if (ret != 0)
318 return ret;
319
320 if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
321 *locked = ((t & 0x80) == 0x80) ? 1 : 0;
322 else
323 *locked = ((t & 0xC0) == 0xC0) ? 1 : 0;
324 return 0;
325}
326
327/* Wait for Code Acquisition Lock */
328static int lgs8gxx_wait_ca_lock(struct lgs8gxx_state *priv, u8 *locked)
329{
330 int ret = 0;
331 u8 reg, mask, val;
332
333 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
334 reg = 0x13;
335 mask = 0x80;
336 val = 0x80;
337 } else {
338 reg = 0x4B;
339 mask = 0xC0;
340 val = 0xC0;
341 }
342
343 ret = wait_reg_mask(priv, reg, mask, val, 50, 40);
344 *locked = (ret == 0) ? 1 : 0;
345
346 return 0;
347}
348
349static int lgs8gxx_is_autodetect_finished(struct lgs8gxx_state *priv,
350 u8 *finished)
351{
352 int ret = 0;
353 u8 reg, mask, val;
354
355 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
356 reg = 0x1f;
357 mask = 0xC0;
358 val = 0x80;
359 } else {
360 reg = 0xA4;
361 mask = 0x03;
362 val = 0x01;
363 }
364
365 ret = wait_reg_mask(priv, reg, mask, val, 10, 20);
366 *finished = (ret == 0) ? 1 : 0;
367
368 return 0;
369}
370
371static int lgs8gxx_autolock_gi(struct lgs8gxx_state *priv, u8 gi, u8 cpn,
372 u8 *locked)
373{
374 int err = 0;
375 u8 ad_fini = 0;
376 u8 t1, t2;
377
378 if (gi == GI_945)
379 dprintk("try GI 945\n");
380 else if (gi == GI_595)
381 dprintk("try GI 595\n");
382 else if (gi == GI_420)
383 dprintk("try GI 420\n");
384 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
385 lgs8gxx_read_reg(priv, 0x0C, &t1);
386 lgs8gxx_read_reg(priv, 0x18, &t2);
387 t1 &= ~(GI_MASK);
388 t1 |= gi;
389 t2 &= 0xFE;
390 t2 |= cpn ? 0x01 : 0x00;
391 lgs8gxx_write_reg(priv, 0x0C, t1);
392 lgs8gxx_write_reg(priv, 0x18, t2);
393 } else {
394 lgs8gxx_write_reg(priv, 0x04, gi);
395 }
396 lgs8gxx_soft_reset(priv);
397 err = lgs8gxx_wait_ca_lock(priv, locked);
398 if (err || !(*locked))
399 return err;
400 err = lgs8gxx_is_autodetect_finished(priv, &ad_fini);
401 if (err != 0)
402 return err;
403 if (ad_fini) {
404 dprintk("auto detect finished\n");
405 } else
406 *locked = 0;
407
408 return 0;
409}
410
411static int lgs8gxx_auto_detect(struct lgs8gxx_state *priv,
412 u8 *detected_param, u8 *gi)
413{
414 int i, j;
415 int err = 0;
416 u8 locked = 0, tmp_gi;
417
418 dprintk("%s\n", __func__);
419
420 lgs8gxx_set_mode_auto(priv);
421 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
422 lgs8gxx_write_reg(priv, 0x67, 0xAA);
423 lgs8gxx_write_reg(priv, 0x6E, 0x3F);
424 } else {
425 /* Guard Interval */
426 lgs8gxx_write_reg(priv, 0x03, 00);
427 }
428
429 for (i = 0; i < 2; i++) {
430 for (j = 0; j < 2; j++) {
431 tmp_gi = GI_945;
432 err = lgs8gxx_autolock_gi(priv, GI_945, j, &locked);
433 if (err)
434 goto out;
435 if (locked)
436 goto locked;
437 }
438 for (j = 0; j < 2; j++) {
439 tmp_gi = GI_420;
440 err = lgs8gxx_autolock_gi(priv, GI_420, j, &locked);
441 if (err)
442 goto out;
443 if (locked)
444 goto locked;
445 }
446 tmp_gi = GI_595;
447 err = lgs8gxx_autolock_gi(priv, GI_595, 1, &locked);
448 if (err)
449 goto out;
450 if (locked)
451 goto locked;
452 }
453
454locked:
455 if ((err == 0) && (locked == 1)) {
456 u8 t;
457
458 if (priv->config->prod != LGS8GXX_PROD_LGS8G75) {
459 lgs8gxx_read_reg(priv, 0xA2, &t);
460 *detected_param = t;
461 } else {
462 lgs8gxx_read_reg(priv, 0x1F, &t);
463 *detected_param = t & 0x3F;
464 }
465
466 if (tmp_gi == GI_945)
467 dprintk("GI 945 locked\n");
468 else if (tmp_gi == GI_595)
469 dprintk("GI 595 locked\n");
470 else if (tmp_gi == GI_420)
471 dprintk("GI 420 locked\n");
472 *gi = tmp_gi;
473 }
474 if (!locked)
475 err = -1;
476
477out:
478 return err;
479}
480
481static void lgs8gxx_auto_lock(struct lgs8gxx_state *priv)
482{
483 s8 err;
484 u8 gi = 0x2;
485 u8 detected_param = 0;
486
487 err = lgs8gxx_auto_detect(priv, &detected_param, &gi);
488
489 if (err != 0) {
490 dprintk("lgs8gxx_auto_detect failed\n");
491 } else
492 dprintk("detected param = 0x%02X\n", detected_param);
493
494 /* Apply detected parameters */
495 if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
496 u8 inter_leave_len = detected_param & TIM_MASK ;
497 /* Fix 8913 time interleaver detection bug */
498 inter_leave_len = (inter_leave_len == TIM_MIDDLE) ? 0x60 : 0x40;
499 detected_param &= CF_MASK | SC_MASK | LGS_FEC_MASK;
500 detected_param |= inter_leave_len;
501 }
502 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
503 u8 t;
504 lgs8gxx_read_reg(priv, 0x19, &t);
505 t &= 0x81;
506 t |= detected_param << 1;
507 lgs8gxx_write_reg(priv, 0x19, t);
508 } else {
509 lgs8gxx_write_reg(priv, 0x7D, detected_param);
510 if (priv->config->prod == LGS8GXX_PROD_LGS8913)
511 lgs8gxx_write_reg(priv, 0xC0, detected_param);
512 }
513 /* lgs8gxx_soft_reset(priv); */
514
515 /* Enter manual mode */
516 lgs8gxx_set_mode_manual(priv);
517
518 switch (gi) {
519 case GI_945:
520 priv->curr_gi = 945; break;
521 case GI_595:
522 priv->curr_gi = 595; break;
523 case GI_420:
524 priv->curr_gi = 420; break;
525 default:
526 priv->curr_gi = 945; break;
527 }
528}
529
530static int lgs8gxx_set_mpeg_mode(struct lgs8gxx_state *priv,
531 u8 serial, u8 clk_pol, u8 clk_gated)
532{
533 int ret = 0;
534 u8 t, reg_addr;
535
536 reg_addr = (priv->config->prod == LGS8GXX_PROD_LGS8G75) ? 0x30 : 0xC2;
537 ret = lgs8gxx_read_reg(priv, reg_addr, &t);
538 if (ret != 0)
539 return ret;
540
541 t &= 0xF8;
542 t |= serial ? TS_SERIAL : TS_PARALLEL;
543 t |= clk_pol ? TS_CLK_INVERTED : TS_CLK_NORMAL;
544 t |= clk_gated ? TS_CLK_GATED : TS_CLK_FREERUN;
545
546 ret = lgs8gxx_write_reg(priv, reg_addr, t);
547 if (ret != 0)
548 return ret;
549
550 return 0;
551}
552
553/* A/D input peak-to-peak voltage range */
554static int lgs8g75_set_adc_vpp(struct lgs8gxx_state *priv,
555 u8 sel)
556{
557 u8 r26 = 0x73, r27 = 0x90;
558
559 if (priv->config->prod != LGS8GXX_PROD_LGS8G75)
560 return 0;
561
562 r26 |= (sel & 0x01) << 7;
563 r27 |= (sel & 0x02) >> 1;
564 lgs8gxx_write_reg(priv, 0x26, r26);
565 lgs8gxx_write_reg(priv, 0x27, r27);
566
567 return 0;
568}
569
570/* LGS8913 demod frontend functions */
571
572static int lgs8913_init(struct lgs8gxx_state *priv)
573{
574 u8 t;
575
576 /* LGS8913 specific */
577 lgs8gxx_write_reg(priv, 0xc1, 0x3);
578
579 lgs8gxx_read_reg(priv, 0x7c, &t);
580 lgs8gxx_write_reg(priv, 0x7c, (t&0x8c) | 0x3);
581
582 /* LGS8913 specific */
583 lgs8gxx_read_reg(priv, 0xc3, &t);
584 lgs8gxx_write_reg(priv, 0xc3, t&0x10);
585
586
587 return 0;
588}
589
590static int lgs8g75_init_data(struct lgs8gxx_state *priv)
591{
592 const struct firmware *fw;
593 int rc;
594 int i;
595
596 rc = request_firmware(&fw, "lgs8g75.fw", &priv->i2c->dev);
597 if (rc)
598 return rc;
599
600 lgs8gxx_write_reg(priv, 0xC6, 0x40);
601
602 lgs8gxx_write_reg(priv, 0x3D, 0x04);
603 lgs8gxx_write_reg(priv, 0x39, 0x00);
604
605 lgs8gxx_write_reg(priv, 0x3A, 0x00);
606 lgs8gxx_write_reg(priv, 0x38, 0x00);
607 lgs8gxx_write_reg(priv, 0x3B, 0x00);
608 lgs8gxx_write_reg(priv, 0x38, 0x00);
609
610 for (i = 0; i < fw->size; i++) {
611 lgs8gxx_write_reg(priv, 0x38, 0x00);
612 lgs8gxx_write_reg(priv, 0x3A, (u8)(i&0xff));
613 lgs8gxx_write_reg(priv, 0x3B, (u8)(i>>8));
614 lgs8gxx_write_reg(priv, 0x3C, fw->data[i]);
615 }
616
617 lgs8gxx_write_reg(priv, 0x38, 0x00);
618
619 release_firmware(fw);
620 return 0;
621}
622
623static int lgs8gxx_init(struct dvb_frontend *fe)
624{
625 struct lgs8gxx_state *priv =
626 (struct lgs8gxx_state *)fe->demodulator_priv;
627 const struct lgs8gxx_config *config = priv->config;
628 u8 data = 0;
629 s8 err;
630 dprintk("%s\n", __func__);
631
632 lgs8gxx_read_reg(priv, 0, &data);
633 dprintk("reg 0 = 0x%02X\n", data);
634
635 if (config->prod == LGS8GXX_PROD_LGS8G75)
636 lgs8g75_set_adc_vpp(priv, config->adc_vpp);
637
638 /* Setup MPEG output format */
639 err = lgs8gxx_set_mpeg_mode(priv, config->serial_ts,
640 config->ts_clk_pol,
641 config->ts_clk_gated);
642 if (err != 0)
643 return -EIO;
644
645 if (config->prod == LGS8GXX_PROD_LGS8913)
646 lgs8913_init(priv);
647 lgs8gxx_set_if_freq(priv, priv->config->if_freq);
648 lgs8gxx_set_ad_mode(priv);
649
650 return 0;
651}
652
653static void lgs8gxx_release(struct dvb_frontend *fe)
654{
655 struct lgs8gxx_state *state = fe->demodulator_priv;
656 dprintk("%s\n", __func__);
657
658 kfree(state);
659}
660
661
662static int lgs8gxx_write(struct dvb_frontend *fe, const u8 buf[], int len)
663{
664 struct lgs8gxx_state *priv = fe->demodulator_priv;
665
666 if (len != 2)
667 return -EINVAL;
668
669 return lgs8gxx_write_reg(priv, buf[0], buf[1]);
670}
671
672static int lgs8gxx_set_fe(struct dvb_frontend *fe,
673 struct dvb_frontend_parameters *fe_params)
674{
675 struct lgs8gxx_state *priv = fe->demodulator_priv;
676
677 dprintk("%s\n", __func__);
678
679 /* set frequency */
680 if (fe->ops.tuner_ops.set_params) {
681 fe->ops.tuner_ops.set_params(fe, fe_params);
682 if (fe->ops.i2c_gate_ctrl)
683 fe->ops.i2c_gate_ctrl(fe, 0);
684 }
685
686 /* start auto lock */
687 lgs8gxx_auto_lock(priv);
688
689 msleep(10);
690
691 return 0;
692}
693
694static int lgs8gxx_get_fe(struct dvb_frontend *fe,
695 struct dvb_frontend_parameters *fe_params)
696{
697 dprintk("%s\n", __func__);
698
699 /* TODO: get real readings from device */
700 /* inversion status */
701 fe_params->inversion = INVERSION_OFF;
702
703 /* bandwidth */
704 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
705
706 fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
707 fe_params->u.ofdm.code_rate_LP = FEC_AUTO;
708
709 fe_params->u.ofdm.constellation = QAM_AUTO;
710
711 /* transmission mode */
712 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
713
714 /* guard interval */
715 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
716
717 /* hierarchy */
718 fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE;
719
720 return 0;
721}
722
723static
724int lgs8gxx_get_tune_settings(struct dvb_frontend *fe,
725 struct dvb_frontend_tune_settings *fesettings)
726{
727 /* FIXME: copy from tda1004x.c */
728 fesettings->min_delay_ms = 800;
729 fesettings->step_size = 0;
730 fesettings->max_drift = 0;
731 return 0;
732}
733
734static int lgs8gxx_read_status(struct dvb_frontend *fe, fe_status_t *fe_status)
735{
736 struct lgs8gxx_state *priv = fe->demodulator_priv;
737 s8 ret;
738 u8 t, locked = 0;
739
740 dprintk("%s\n", __func__);
741 *fe_status = 0;
742
743 lgs8gxx_get_afc_phase(priv);
744 lgs8gxx_is_locked(priv, &locked);
745 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
746 if (locked)
747 *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
748 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
749 return 0;
750 }
751
752 ret = lgs8gxx_read_reg(priv, 0x4B, &t);
753 if (ret != 0)
754 return -EIO;
755
756 dprintk("Reg 0x4B: 0x%02X\n", t);
757
758 *fe_status = 0;
759 if (priv->config->prod == LGS8GXX_PROD_LGS8913) {
760 if ((t & 0x40) == 0x40)
761 *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
762 if ((t & 0x80) == 0x80)
763 *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC |
764 FE_HAS_LOCK;
765 } else {
766 if ((t & 0x80) == 0x80)
767 *fe_status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
768 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
769 }
770
771 /* success */
772 dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
773 return 0;
774}
775
776static int lgs8gxx_read_signal_agc(struct lgs8gxx_state *priv, u16 *signal)
777{
778 u16 v;
779 u8 agc_lvl[2], cat;
780
781 dprintk("%s()\n", __func__);
782 lgs8gxx_read_reg(priv, 0x3F, &agc_lvl[0]);
783 lgs8gxx_read_reg(priv, 0x3E, &agc_lvl[1]);
784
785 v = agc_lvl[0];
786 v <<= 8;
787 v |= agc_lvl[1];
788
789 dprintk("agc_lvl: 0x%04X\n", v);
790
791 if (v < 0x100)
792 cat = 0;
793 else if (v < 0x190)
794 cat = 5;
795 else if (v < 0x2A8)
796 cat = 4;
797 else if (v < 0x381)
798 cat = 3;
799 else if (v < 0x400)
800 cat = 2;
801 else if (v == 0x400)
802 cat = 1;
803 else
804 cat = 0;
805
806 *signal = cat * 65535 / 5;
807
808 return 0;
809}
810
811static int lgs8913_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
812{
813 u8 t; s8 ret;
814 s16 max_strength = 0;
815 u8 str;
816 u16 i, gi = priv->curr_gi;
817
818 dprintk("%s\n", __func__);
819
820 ret = lgs8gxx_read_reg(priv, 0x4B, &t);
821 if (ret != 0)
822 return -EIO;
823
824 if (fake_signal_str) {
825 if ((t & 0xC0) == 0xC0) {
826 dprintk("Fake signal strength\n");
827 *signal = 0x7FFF;
828 } else
829 *signal = 0;
830 return 0;
831 }
832
833 dprintk("gi = %d\n", gi);
834 for (i = 0; i < gi; i++) {
835
836 if ((i & 0xFF) == 0)
837 lgs8gxx_write_reg(priv, 0x84, 0x03 & (i >> 8));
838 lgs8gxx_write_reg(priv, 0x83, i & 0xFF);
839
840 lgs8gxx_read_reg(priv, 0x94, &str);
841 if (max_strength < str)
842 max_strength = str;
843 }
844
845 *signal = max_strength;
846 dprintk("%s: signal=0x%02X\n", __func__, *signal);
847
848 lgs8gxx_read_reg(priv, 0x95, &t);
849 dprintk("%s: AVG Noise=0x%02X\n", __func__, t);
850
851 return 0;
852}
853
854static int lgs8g75_read_signal_strength(struct lgs8gxx_state *priv, u16 *signal)
855{
856 u8 t;
857 s16 v = 0;
858
859 dprintk("%s\n", __func__);
860
861 lgs8gxx_read_reg(priv, 0xB1, &t);
862 v |= t;
863 v <<= 8;
864 lgs8gxx_read_reg(priv, 0xB0, &t);
865 v |= t;
866
867 *signal = v;
868 dprintk("%s: signal=0x%02X\n", __func__, *signal);
869
870 return 0;
871}
872
873static int lgs8gxx_read_signal_strength(struct dvb_frontend *fe, u16 *signal)
874{
875 struct lgs8gxx_state *priv = fe->demodulator_priv;
876
877 if (priv->config->prod == LGS8GXX_PROD_LGS8913)
878 return lgs8913_read_signal_strength(priv, signal);
879 else if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
880 return lgs8g75_read_signal_strength(priv, signal);
881 else
882 return lgs8gxx_read_signal_agc(priv, signal);
883}
884
885static int lgs8gxx_read_snr(struct dvb_frontend *fe, u16 *snr)
886{
887 struct lgs8gxx_state *priv = fe->demodulator_priv;
888 u8 t;
889 *snr = 0;
890
891 if (priv->config->prod == LGS8GXX_PROD_LGS8G75)
892 lgs8gxx_read_reg(priv, 0x34, &t);
893 else
894 lgs8gxx_read_reg(priv, 0x95, &t);
895 dprintk("AVG Noise=0x%02X\n", t);
896 *snr = 256 - t;
897 *snr <<= 8;
898 dprintk("snr=0x%x\n", *snr);
899
900 return 0;
901}
902
903static int lgs8gxx_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
904{
905 *ucblocks = 0;
906 dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks);
907 return 0;
908}
909
910static void packet_counter_start(struct lgs8gxx_state *priv)
911{
912 u8 orig, t;
913
914 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
915 lgs8gxx_read_reg(priv, 0x30, &orig);
916 orig &= 0xE7;
917 t = orig | 0x10;
918 lgs8gxx_write_reg(priv, 0x30, t);
919 t = orig | 0x18;
920 lgs8gxx_write_reg(priv, 0x30, t);
921 t = orig | 0x10;
922 lgs8gxx_write_reg(priv, 0x30, t);
923 } else {
924 lgs8gxx_write_reg(priv, 0xC6, 0x01);
925 lgs8gxx_write_reg(priv, 0xC6, 0x41);
926 lgs8gxx_write_reg(priv, 0xC6, 0x01);
927 }
928}
929
930static void packet_counter_stop(struct lgs8gxx_state *priv)
931{
932 u8 t;
933
934 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
935 lgs8gxx_read_reg(priv, 0x30, &t);
936 t &= 0xE7;
937 lgs8gxx_write_reg(priv, 0x30, t);
938 } else {
939 lgs8gxx_write_reg(priv, 0xC6, 0x81);
940 }
941}
942
943static int lgs8gxx_read_ber(struct dvb_frontend *fe, u32 *ber)
944{
945 struct lgs8gxx_state *priv = fe->demodulator_priv;
946 u8 reg_err, reg_total, t;
947 u32 total_cnt = 0, err_cnt = 0;
948 int i;
949
950 dprintk("%s\n", __func__);
951
952 packet_counter_start(priv);
953 msleep(200);
954 packet_counter_stop(priv);
955
956 if (priv->config->prod == LGS8GXX_PROD_LGS8G75) {
957 reg_total = 0x28; reg_err = 0x2C;
958 } else {
959 reg_total = 0xD0; reg_err = 0xD4;
960 }
961
962 for (i = 0; i < 4; i++) {
963 total_cnt <<= 8;
964 lgs8gxx_read_reg(priv, reg_total+3-i, &t);
965 total_cnt |= t;
966 }
967 for (i = 0; i < 4; i++) {
968 err_cnt <<= 8;
969 lgs8gxx_read_reg(priv, reg_err+3-i, &t);
970 err_cnt |= t;
971 }
972 dprintk("error=%d total=%d\n", err_cnt, total_cnt);
973
974 if (total_cnt == 0)
975 *ber = 0;
976 else
977 *ber = err_cnt * 100 / total_cnt;
978
979 dprintk("%s: ber=0x%x\n", __func__, *ber);
980 return 0;
981}
982
983static int lgs8gxx_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
984{
985 struct lgs8gxx_state *priv = fe->demodulator_priv;
986
987 if (priv->config->tuner_address == 0)
988 return 0;
989 if (enable) {
990 u8 v = 0x80 | priv->config->tuner_address;
991 return lgs8gxx_write_reg(priv, 0x01, v);
992 }
993 return lgs8gxx_write_reg(priv, 0x01, 0);
994}
995
996static struct dvb_frontend_ops lgs8gxx_ops = {
997 .info = {
998 .name = "Legend Silicon LGS8913/LGS8GXX DMB-TH",
999 .type = FE_OFDM,
1000 .frequency_min = 474000000,
1001 .frequency_max = 858000000,
1002 .frequency_stepsize = 10000,
1003 .caps =
1004 FE_CAN_FEC_AUTO |
1005 FE_CAN_QAM_AUTO |
1006 FE_CAN_TRANSMISSION_MODE_AUTO |
1007 FE_CAN_GUARD_INTERVAL_AUTO
1008 },
1009
1010 .release = lgs8gxx_release,
1011
1012 .init = lgs8gxx_init,
1013 .write = lgs8gxx_write,
1014 .i2c_gate_ctrl = lgs8gxx_i2c_gate_ctrl,
1015
1016 .set_frontend = lgs8gxx_set_fe,
1017 .get_frontend = lgs8gxx_get_fe,
1018 .get_tune_settings = lgs8gxx_get_tune_settings,
1019
1020 .read_status = lgs8gxx_read_status,
1021 .read_ber = lgs8gxx_read_ber,
1022 .read_signal_strength = lgs8gxx_read_signal_strength,
1023 .read_snr = lgs8gxx_read_snr,
1024 .read_ucblocks = lgs8gxx_read_ucblocks,
1025};
1026
1027struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
1028 struct i2c_adapter *i2c)
1029{
1030 struct lgs8gxx_state *priv = NULL;
1031 u8 data = 0;
1032
1033 dprintk("%s()\n", __func__);
1034
1035 if (config == NULL || i2c == NULL)
1036 return NULL;
1037
1038 priv = kzalloc(sizeof(struct lgs8gxx_state), GFP_KERNEL);
1039 if (priv == NULL)
1040 goto error_out;
1041
1042 priv->config = config;
1043 priv->i2c = i2c;
1044
1045 /* check if the demod is there */
1046 if (lgs8gxx_read_reg(priv, 0, &data) != 0) {
1047 dprintk("%s lgs8gxx not found at i2c addr 0x%02X\n",
1048 __func__, priv->config->demod_address);
1049 goto error_out;
1050 }
1051
1052 lgs8gxx_read_reg(priv, 1, &data);
1053
1054 memcpy(&priv->frontend.ops, &lgs8gxx_ops,
1055 sizeof(struct dvb_frontend_ops));
1056 priv->frontend.demodulator_priv = priv;
1057
1058 if (config->prod == LGS8GXX_PROD_LGS8G75)
1059 lgs8g75_init_data(priv);
1060
1061 return &priv->frontend;
1062
1063error_out:
1064 dprintk("%s() error_out\n", __func__);
1065 kfree(priv);
1066 return NULL;
1067
1068}
1069EXPORT_SYMBOL(lgs8gxx_attach);
1070
1071MODULE_DESCRIPTION("Legend Silicon LGS8913/LGS8GXX DMB-TH demodulator driver");
1072MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
1073MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lgs8gxx.h b/drivers/media/dvb/frontends/lgs8gxx.h
new file mode 100644
index 00000000000..33c3c5e162f
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgs8gxx.h
@@ -0,0 +1,95 @@
1/*
2 * Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
3 * LGS8913, LGS8GL5, LGS8G75
4 * experimental support LGS8G42, LGS8G52
5 *
6 * Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
7 * Copyright (C) 2008 Sirius International (Hong Kong) Limited
8 * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
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 */
25
26#ifndef __LGS8GXX_H__
27#define __LGS8GXX_H__
28
29#include <linux/dvb/frontend.h>
30#include <linux/i2c.h>
31
32#define LGS8GXX_PROD_LGS8913 0
33#define LGS8GXX_PROD_LGS8GL5 1
34#define LGS8GXX_PROD_LGS8G42 3
35#define LGS8GXX_PROD_LGS8G52 4
36#define LGS8GXX_PROD_LGS8G54 5
37#define LGS8GXX_PROD_LGS8G75 6
38
39struct lgs8gxx_config {
40
41 /* product type */
42 u8 prod;
43
44 /* the demodulator's i2c address */
45 u8 demod_address;
46
47 /* parallel or serial transport stream */
48 u8 serial_ts;
49
50 /* transport stream polarity*/
51 u8 ts_clk_pol;
52
53 /* transport stream clock gated by ts_valid */
54 u8 ts_clk_gated;
55
56 /* A/D Clock frequency */
57 u32 if_clk_freq; /* in kHz */
58
59 /* IF frequency */
60 u32 if_freq; /* in kHz */
61
62 /*Use External ADC*/
63 u8 ext_adc;
64
65 /*External ADC output two's complement*/
66 u8 adc_signed;
67
68 /*Sample IF data at falling edge of IF_CLK*/
69 u8 if_neg_edge;
70
71 /*IF use Negative center frequency*/
72 u8 if_neg_center;
73
74 /*8G75 internal ADC input range selection*/
75 /*0: 0.8Vpp, 1: 1.0Vpp, 2: 1.6Vpp, 3: 2.0Vpp*/
76 u8 adc_vpp;
77
78 /* slave address and configuration of the tuner */
79 u8 tuner_address;
80};
81
82#if defined(CONFIG_DVB_LGS8GXX) || \
83 (defined(CONFIG_DVB_LGS8GXX_MODULE) && defined(MODULE))
84extern struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
85 struct i2c_adapter *i2c);
86#else
87static inline
88struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
89 struct i2c_adapter *i2c) {
90 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
91 return NULL;
92}
93#endif /* CONFIG_DVB_LGS8GXX */
94
95#endif /* __LGS8GXX_H__ */
diff --git a/drivers/media/dvb/frontends/lgs8gxx_priv.h b/drivers/media/dvb/frontends/lgs8gxx_priv.h
new file mode 100644
index 00000000000..8ef376f1414
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgs8gxx_priv.h
@@ -0,0 +1,70 @@
1/*
2 * Support for Legend Silicon GB20600 (a.k.a DMB-TH) demodulator
3 * LGS8913, LGS8GL5, LGS8G75
4 * experimental support LGS8G42, LGS8G52
5 *
6 * Copyright (C) 2007-2009 David T.L. Wong <davidtlwong@gmail.com>
7 * Copyright (C) 2008 Sirius International (Hong Kong) Limited
8 * Timothy Lee <timothy.lee@siriushk.com> (for initial work on LGS8GL5)
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 */
25
26#ifndef LGS8913_PRIV_H
27#define LGS8913_PRIV_H
28
29struct lgs8gxx_state {
30 struct i2c_adapter *i2c;
31 /* configuration settings */
32 const struct lgs8gxx_config *config;
33 struct dvb_frontend frontend;
34 u16 curr_gi; /* current guard interval */
35};
36
37#define SC_MASK 0x1C /* Sub-Carrier Modulation Mask */
38#define SC_QAM64 0x10 /* 64QAM modulation */
39#define SC_QAM32 0x0C /* 32QAM modulation */
40#define SC_QAM16 0x08 /* 16QAM modulation */
41#define SC_QAM4NR 0x04 /* 4QAM-NR modulation */
42#define SC_QAM4 0x00 /* 4QAM modulation */
43
44#define LGS_FEC_MASK 0x03 /* FEC Rate Mask */
45#define LGS_FEC_0_4 0x00 /* FEC Rate 0.4 */
46#define LGS_FEC_0_6 0x01 /* FEC Rate 0.6 */
47#define LGS_FEC_0_8 0x02 /* FEC Rate 0.8 */
48
49#define TIM_MASK 0x20 /* Time Interleave Length Mask */
50#define TIM_LONG 0x20 /* Time Interleave Length = 720 */
51#define TIM_MIDDLE 0x00 /* Time Interleave Length = 240 */
52
53#define CF_MASK 0x80 /* Control Frame Mask */
54#define CF_EN 0x80 /* Control Frame On */
55
56#define GI_MASK 0x03 /* Guard Interval Mask */
57#define GI_420 0x00 /* 1/9 Guard Interval */
58#define GI_595 0x01 /* */
59#define GI_945 0x02 /* 1/4 Guard Interval */
60
61
62#define TS_PARALLEL 0x00 /* Parallel TS Output a.k.a. SPI */
63#define TS_SERIAL 0x01 /* Serial TS Output a.k.a. SSI */
64#define TS_CLK_NORMAL 0x00 /* MPEG Clock Normal */
65#define TS_CLK_INVERTED 0x02 /* MPEG Clock Inverted */
66#define TS_CLK_GATED 0x00 /* MPEG clock gated */
67#define TS_CLK_FREERUN 0x04 /* MPEG clock free running*/
68
69
70#endif
diff --git a/drivers/media/dvb/frontends/lnbh24.h b/drivers/media/dvb/frontends/lnbh24.h
new file mode 100644
index 00000000000..c059b165318
--- /dev/null
+++ b/drivers/media/dvb/frontends/lnbh24.h
@@ -0,0 +1,55 @@
1/*
2 * lnbh24.h - driver for lnb supply and control ic lnbh24
3 *
4 * Copyright (C) 2009 NetUP Inc.
5 * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
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 *
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#ifndef _LNBH24_H
24#define _LNBH24_H
25
26/* system register bits */
27#define LNBH24_OLF 0x01
28#define LNBH24_OTF 0x02
29#define LNBH24_EN 0x04
30#define LNBH24_VSEL 0x08
31#define LNBH24_LLC 0x10
32#define LNBH24_TEN 0x20
33#define LNBH24_TTX 0x40
34#define LNBH24_PCL 0x80
35
36#include <linux/dvb/frontend.h>
37
38#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
39 && defined(MODULE))
40/* override_set and override_clear control which
41 system register bits (above) to always set & clear */
42extern struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
43 struct i2c_adapter *i2c, u8 override_set,
44 u8 override_clear, u8 i2c_addr);
45#else
46static inline struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
47 struct i2c_adapter *i2c, u8 override_set,
48 u8 override_clear, u8 i2c_addr)
49{
50 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
51 return NULL;
52}
53#endif
54
55#endif
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c
new file mode 100644
index 00000000000..13437259eea
--- /dev/null
+++ b/drivers/media/dvb/frontends/lnbp21.c
@@ -0,0 +1,188 @@
1/*
2 * lnbp21.c - driver for lnb supply and control ic lnbp21
3 *
4 * Copyright (C) 2006, 2009 Oliver Endriss <o.endriss@gmx.de>
5 * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
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
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
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 *
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 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
23 *
24 *
25 * the project's page is at http://www.linuxtv.org
26 */
27#include <linux/delay.h>
28#include <linux/errno.h>
29#include <linux/init.h>
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/string.h>
33#include <linux/slab.h>
34
35#include "dvb_frontend.h"
36#include "lnbp21.h"
37#include "lnbh24.h"
38
39struct lnbp21 {
40 u8 config;
41 u8 override_or;
42 u8 override_and;
43 struct i2c_adapter *i2c;
44 u8 i2c_addr;
45};
46
47static int lnbp21_set_voltage(struct dvb_frontend *fe,
48 fe_sec_voltage_t voltage)
49{
50 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
51 struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0,
52 .buf = &lnbp21->config,
53 .len = sizeof(lnbp21->config) };
54
55 lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN);
56
57 switch(voltage) {
58 case SEC_VOLTAGE_OFF:
59 break;
60 case SEC_VOLTAGE_13:
61 lnbp21->config |= LNBP21_EN;
62 break;
63 case SEC_VOLTAGE_18:
64 lnbp21->config |= (LNBP21_EN | LNBP21_VSEL);
65 break;
66 default:
67 return -EINVAL;
68 };
69
70 lnbp21->config |= lnbp21->override_or;
71 lnbp21->config &= lnbp21->override_and;
72
73 return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
74}
75
76static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
77{
78 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
79 struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0,
80 .buf = &lnbp21->config,
81 .len = sizeof(lnbp21->config) };
82
83 if (arg)
84 lnbp21->config |= LNBP21_LLC;
85 else
86 lnbp21->config &= ~LNBP21_LLC;
87
88 lnbp21->config |= lnbp21->override_or;
89 lnbp21->config &= lnbp21->override_and;
90
91 return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
92}
93
94static int lnbp21_set_tone(struct dvb_frontend *fe,
95 fe_sec_tone_mode_t tone)
96{
97 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
98 struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0,
99 .buf = &lnbp21->config,
100 .len = sizeof(lnbp21->config) };
101
102 switch (tone) {
103 case SEC_TONE_OFF:
104 lnbp21->config &= ~LNBP21_TEN;
105 break;
106 case SEC_TONE_ON:
107 lnbp21->config |= LNBP21_TEN;
108 break;
109 default:
110 return -EINVAL;
111 };
112
113 lnbp21->config |= lnbp21->override_or;
114 lnbp21->config &= lnbp21->override_and;
115
116 return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
117}
118
119static void lnbp21_release(struct dvb_frontend *fe)
120{
121 /* LNBP power off */
122 lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
123
124 /* free data */
125 kfree(fe->sec_priv);
126 fe->sec_priv = NULL;
127}
128
129static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe,
130 struct i2c_adapter *i2c, u8 override_set,
131 u8 override_clear, u8 i2c_addr, u8 config)
132{
133 struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
134 if (!lnbp21)
135 return NULL;
136
137 /* default configuration */
138 lnbp21->config = config;
139 lnbp21->i2c = i2c;
140 lnbp21->i2c_addr = i2c_addr;
141 fe->sec_priv = lnbp21;
142
143 /* bits which should be forced to '1' */
144 lnbp21->override_or = override_set;
145
146 /* bits which should be forced to '0' */
147 lnbp21->override_and = ~override_clear;
148
149 /* detect if it is present or not */
150 if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) {
151 kfree(lnbp21);
152 return NULL;
153 }
154
155 /* install release callback */
156 fe->ops.release_sec = lnbp21_release;
157
158 /* override frontend ops */
159 fe->ops.set_voltage = lnbp21_set_voltage;
160 fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
161 if (!(override_clear & LNBH24_TEN)) /*22kHz logic controlled by demod*/
162 fe->ops.set_tone = lnbp21_set_tone;
163 printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr);
164
165 return fe;
166}
167
168struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
169 struct i2c_adapter *i2c, u8 override_set,
170 u8 override_clear, u8 i2c_addr)
171{
172 return lnbx2x_attach(fe, i2c, override_set, override_clear,
173 i2c_addr, LNBH24_TTX);
174}
175EXPORT_SYMBOL(lnbh24_attach);
176
177struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
178 struct i2c_adapter *i2c, u8 override_set,
179 u8 override_clear)
180{
181 return lnbx2x_attach(fe, i2c, override_set, override_clear,
182 0x08, LNBP21_ISEL);
183}
184EXPORT_SYMBOL(lnbp21_attach);
185
186MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24");
187MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin");
188MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h
new file mode 100644
index 00000000000..fcdf1c650dd
--- /dev/null
+++ b/drivers/media/dvb/frontends/lnbp21.h
@@ -0,0 +1,75 @@
1/*
2 * lnbp21.h - driver for lnb supply and control ic lnbp21
3 *
4 * Copyright (C) 2006 Oliver Endriss
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
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 *
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
22 *
23 *
24 * the project's page is at http://www.linuxtv.org
25 */
26
27#ifndef _LNBP21_H
28#define _LNBP21_H
29
30/* system register bits */
31/* [RO] 0=OK; 1=over current limit flag */
32#define LNBP21_OLF 0x01
33/* [RO] 0=OK; 1=over temperature flag (150 C) */
34#define LNBP21_OTF 0x02
35/* [RW] 0=disable LNB power, enable loopthrough
36 1=enable LNB power, disable loopthrough */
37#define LNBP21_EN 0x04
38/* [RW] 0=low voltage (13/14V, vert pol)
39 1=high voltage (18/19V,horiz pol) */
40#define LNBP21_VSEL 0x08
41/* [RW] increase LNB voltage by 1V:
42 0=13/18V; 1=14/19V */
43#define LNBP21_LLC 0x10
44/* [RW] 0=tone controlled by DSQIN pin
45 1=tone enable, disable DSQIN */
46#define LNBP21_TEN 0x20
47/* [RW] current limit select:
48 0:Iout=500-650mA Isc=300mA
49 1:Iout=400-550mA Isc=200mA */
50#define LNBP21_ISEL 0x40
51/* [RW] short-circuit protect:
52 0=pulsed (dynamic) curr limiting
53 1=static curr limiting */
54#define LNBP21_PCL 0x80
55
56#include <linux/dvb/frontend.h>
57
58#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
59 && defined(MODULE))
60/* override_set and override_clear control which
61 system register bits (above) to always set & clear */
62extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
63 struct i2c_adapter *i2c, u8 override_set,
64 u8 override_clear);
65#else
66static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
67 struct i2c_adapter *i2c, u8 override_set,
68 u8 override_clear)
69{
70 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
71 return NULL;
72}
73#endif
74
75#endif
diff --git a/drivers/media/dvb/frontends/mb86a16.c b/drivers/media/dvb/frontends/mb86a16.c
new file mode 100644
index 00000000000..c283112051b
--- /dev/null
+++ b/drivers/media/dvb/frontends/mb86a16.c
@@ -0,0 +1,1878 @@
1/*
2 Fujitsu MB86A16 DVB-S/DSS DC Receiver driver
3
4 Copyright (C) Manu Abraham (abraham.manu@gmail.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 <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/slab.h>
26
27#include "dvb_frontend.h"
28#include "mb86a16.h"
29#include "mb86a16_priv.h"
30
31unsigned int verbose = 5;
32module_param(verbose, int, 0644);
33
34#define ABS(x) ((x) < 0 ? (-x) : (x))
35
36struct mb86a16_state {
37 struct i2c_adapter *i2c_adap;
38 const struct mb86a16_config *config;
39 struct dvb_frontend frontend;
40
41 /* tuning parameters */
42 int frequency;
43 int srate;
44
45 /* Internal stuff */
46 int master_clk;
47 int deci;
48 int csel;
49 int rsel;
50};
51
52#define MB86A16_ERROR 0
53#define MB86A16_NOTICE 1
54#define MB86A16_INFO 2
55#define MB86A16_DEBUG 3
56
57#define dprintk(x, y, z, format, arg...) do { \
58 if (z) { \
59 if ((x > MB86A16_ERROR) && (x > y)) \
60 printk(KERN_ERR "%s: " format "\n", __func__, ##arg); \
61 else if ((x > MB86A16_NOTICE) && (x > y)) \
62 printk(KERN_NOTICE "%s: " format "\n", __func__, ##arg); \
63 else if ((x > MB86A16_INFO) && (x > y)) \
64 printk(KERN_INFO "%s: " format "\n", __func__, ##arg); \
65 else if ((x > MB86A16_DEBUG) && (x > y)) \
66 printk(KERN_DEBUG "%s: " format "\n", __func__, ##arg); \
67 } else { \
68 if (x > y) \
69 printk(format, ##arg); \
70 } \
71} while (0)
72
73#define TRACE_IN dprintk(verbose, MB86A16_DEBUG, 1, "-->()")
74#define TRACE_OUT dprintk(verbose, MB86A16_DEBUG, 1, "()-->")
75
76static int mb86a16_write(struct mb86a16_state *state, u8 reg, u8 val)
77{
78 int ret;
79 u8 buf[] = { reg, val };
80
81 struct i2c_msg msg = {
82 .addr = state->config->demod_address,
83 .flags = 0,
84 .buf = buf,
85 .len = 2
86 };
87
88 dprintk(verbose, MB86A16_DEBUG, 1,
89 "writing to [0x%02x],Reg[0x%02x],Data[0x%02x]",
90 state->config->demod_address, buf[0], buf[1]);
91
92 ret = i2c_transfer(state->i2c_adap, &msg, 1);
93
94 return (ret != 1) ? -EREMOTEIO : 0;
95}
96
97static int mb86a16_read(struct mb86a16_state *state, u8 reg, u8 *val)
98{
99 int ret;
100 u8 b0[] = { reg };
101 u8 b1[] = { 0 };
102
103 struct i2c_msg msg[] = {
104 {
105 .addr = state->config->demod_address,
106 .flags = 0,
107 .buf = b0,
108 .len = 1
109 }, {
110 .addr = state->config->demod_address,
111 .flags = I2C_M_RD,
112 .buf = b1,
113 .len = 1
114 }
115 };
116 ret = i2c_transfer(state->i2c_adap, msg, 2);
117 if (ret != 2) {
118 dprintk(verbose, MB86A16_ERROR, 1, "read error(reg=0x%02x, ret=0x%i)",
119 reg, ret);
120
121 return -EREMOTEIO;
122 }
123 *val = b1[0];
124
125 return ret;
126}
127
128static int CNTM_set(struct mb86a16_state *state,
129 unsigned char timint1,
130 unsigned char timint2,
131 unsigned char cnext)
132{
133 unsigned char val;
134
135 val = (timint1 << 4) | (timint2 << 2) | cnext;
136 if (mb86a16_write(state, MB86A16_CNTMR, val) < 0)
137 goto err;
138
139 return 0;
140
141err:
142 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
143 return -EREMOTEIO;
144}
145
146static int smrt_set(struct mb86a16_state *state, int rate)
147{
148 int tmp ;
149 int m ;
150 unsigned char STOFS0, STOFS1;
151
152 m = 1 << state->deci;
153 tmp = (8192 * state->master_clk - 2 * m * rate * 8192 + state->master_clk / 2) / state->master_clk;
154
155 STOFS0 = tmp & 0x0ff;
156 STOFS1 = (tmp & 0xf00) >> 8;
157
158 if (mb86a16_write(state, MB86A16_SRATE1, (state->deci << 2) |
159 (state->csel << 1) |
160 state->rsel) < 0)
161 goto err;
162 if (mb86a16_write(state, MB86A16_SRATE2, STOFS0) < 0)
163 goto err;
164 if (mb86a16_write(state, MB86A16_SRATE3, STOFS1) < 0)
165 goto err;
166
167 return 0;
168err:
169 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
170 return -1;
171}
172
173static int srst(struct mb86a16_state *state)
174{
175 if (mb86a16_write(state, MB86A16_RESET, 0x04) < 0)
176 goto err;
177
178 return 0;
179err:
180 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
181 return -EREMOTEIO;
182
183}
184
185static int afcex_data_set(struct mb86a16_state *state,
186 unsigned char AFCEX_L,
187 unsigned char AFCEX_H)
188{
189 if (mb86a16_write(state, MB86A16_AFCEXL, AFCEX_L) < 0)
190 goto err;
191 if (mb86a16_write(state, MB86A16_AFCEXH, AFCEX_H) < 0)
192 goto err;
193
194 return 0;
195err:
196 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
197
198 return -1;
199}
200
201static int afcofs_data_set(struct mb86a16_state *state,
202 unsigned char AFCEX_L,
203 unsigned char AFCEX_H)
204{
205 if (mb86a16_write(state, 0x58, AFCEX_L) < 0)
206 goto err;
207 if (mb86a16_write(state, 0x59, AFCEX_H) < 0)
208 goto err;
209
210 return 0;
211err:
212 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
213 return -EREMOTEIO;
214}
215
216static int stlp_set(struct mb86a16_state *state,
217 unsigned char STRAS,
218 unsigned char STRBS)
219{
220 if (mb86a16_write(state, MB86A16_STRFILTCOEF1, (STRBS << 3) | (STRAS)) < 0)
221 goto err;
222
223 return 0;
224err:
225 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
226 return -EREMOTEIO;
227}
228
229static int Vi_set(struct mb86a16_state *state, unsigned char ETH, unsigned char VIA)
230{
231 if (mb86a16_write(state, MB86A16_VISET2, 0x04) < 0)
232 goto err;
233 if (mb86a16_write(state, MB86A16_VISET3, 0xf5) < 0)
234 goto err;
235
236 return 0;
237err:
238 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
239 return -EREMOTEIO;
240}
241
242static int initial_set(struct mb86a16_state *state)
243{
244 if (stlp_set(state, 5, 7))
245 goto err;
246
247 udelay(100);
248 if (afcex_data_set(state, 0, 0))
249 goto err;
250
251 udelay(100);
252 if (afcofs_data_set(state, 0, 0))
253 goto err;
254
255 udelay(100);
256 if (mb86a16_write(state, MB86A16_CRLFILTCOEF1, 0x16) < 0)
257 goto err;
258 if (mb86a16_write(state, 0x2f, 0x21) < 0)
259 goto err;
260 if (mb86a16_write(state, MB86A16_VIMAG, 0x38) < 0)
261 goto err;
262 if (mb86a16_write(state, MB86A16_FAGCS1, 0x00) < 0)
263 goto err;
264 if (mb86a16_write(state, MB86A16_FAGCS2, 0x1c) < 0)
265 goto err;
266 if (mb86a16_write(state, MB86A16_FAGCS3, 0x20) < 0)
267 goto err;
268 if (mb86a16_write(state, MB86A16_FAGCS4, 0x1e) < 0)
269 goto err;
270 if (mb86a16_write(state, MB86A16_FAGCS5, 0x23) < 0)
271 goto err;
272 if (mb86a16_write(state, 0x54, 0xff) < 0)
273 goto err;
274 if (mb86a16_write(state, MB86A16_TSOUT, 0x00) < 0)
275 goto err;
276
277 return 0;
278
279err:
280 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
281 return -EREMOTEIO;
282}
283
284static int S01T_set(struct mb86a16_state *state,
285 unsigned char s1t,
286 unsigned s0t)
287{
288 if (mb86a16_write(state, 0x33, (s1t << 3) | s0t) < 0)
289 goto err;
290
291 return 0;
292err:
293 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
294 return -EREMOTEIO;
295}
296
297
298static int EN_set(struct mb86a16_state *state,
299 int cren,
300 int afcen)
301{
302 unsigned char val;
303
304 val = 0x7a | (cren << 7) | (afcen << 2);
305 if (mb86a16_write(state, 0x49, val) < 0)
306 goto err;
307
308 return 0;
309err:
310 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
311 return -EREMOTEIO;
312}
313
314static int AFCEXEN_set(struct mb86a16_state *state,
315 int afcexen,
316 int smrt)
317{
318 unsigned char AFCA ;
319
320 if (smrt > 18875)
321 AFCA = 4;
322 else if (smrt > 9375)
323 AFCA = 3;
324 else if (smrt > 2250)
325 AFCA = 2;
326 else
327 AFCA = 1;
328
329 if (mb86a16_write(state, 0x2a, 0x02 | (afcexen << 5) | (AFCA << 2)) < 0)
330 goto err;
331
332 return 0;
333
334err:
335 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
336 return -EREMOTEIO;
337}
338
339static int DAGC_data_set(struct mb86a16_state *state,
340 unsigned char DAGCA,
341 unsigned char DAGCW)
342{
343 if (mb86a16_write(state, 0x2d, (DAGCA << 3) | DAGCW) < 0)
344 goto err;
345
346 return 0;
347
348err:
349 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
350 return -EREMOTEIO;
351}
352
353static void smrt_info_get(struct mb86a16_state *state, int rate)
354{
355 if (rate >= 37501) {
356 state->deci = 0; state->csel = 0; state->rsel = 0;
357 } else if (rate >= 30001) {
358 state->deci = 0; state->csel = 0; state->rsel = 1;
359 } else if (rate >= 26251) {
360 state->deci = 0; state->csel = 1; state->rsel = 0;
361 } else if (rate >= 22501) {
362 state->deci = 0; state->csel = 1; state->rsel = 1;
363 } else if (rate >= 18751) {
364 state->deci = 1; state->csel = 0; state->rsel = 0;
365 } else if (rate >= 15001) {
366 state->deci = 1; state->csel = 0; state->rsel = 1;
367 } else if (rate >= 13126) {
368 state->deci = 1; state->csel = 1; state->rsel = 0;
369 } else if (rate >= 11251) {
370 state->deci = 1; state->csel = 1; state->rsel = 1;
371 } else if (rate >= 9376) {
372 state->deci = 2; state->csel = 0; state->rsel = 0;
373 } else if (rate >= 7501) {
374 state->deci = 2; state->csel = 0; state->rsel = 1;
375 } else if (rate >= 6563) {
376 state->deci = 2; state->csel = 1; state->rsel = 0;
377 } else if (rate >= 5626) {
378 state->deci = 2; state->csel = 1; state->rsel = 1;
379 } else if (rate >= 4688) {
380 state->deci = 3; state->csel = 0; state->rsel = 0;
381 } else if (rate >= 3751) {
382 state->deci = 3; state->csel = 0; state->rsel = 1;
383 } else if (rate >= 3282) {
384 state->deci = 3; state->csel = 1; state->rsel = 0;
385 } else if (rate >= 2814) {
386 state->deci = 3; state->csel = 1; state->rsel = 1;
387 } else if (rate >= 2344) {
388 state->deci = 4; state->csel = 0; state->rsel = 0;
389 } else if (rate >= 1876) {
390 state->deci = 4; state->csel = 0; state->rsel = 1;
391 } else if (rate >= 1641) {
392 state->deci = 4; state->csel = 1; state->rsel = 0;
393 } else if (rate >= 1407) {
394 state->deci = 4; state->csel = 1; state->rsel = 1;
395 } else if (rate >= 1172) {
396 state->deci = 5; state->csel = 0; state->rsel = 0;
397 } else if (rate >= 939) {
398 state->deci = 5; state->csel = 0; state->rsel = 1;
399 } else if (rate >= 821) {
400 state->deci = 5; state->csel = 1; state->rsel = 0;
401 } else {
402 state->deci = 5; state->csel = 1; state->rsel = 1;
403 }
404
405 if (state->csel == 0)
406 state->master_clk = 92000;
407 else
408 state->master_clk = 61333;
409
410}
411
412static int signal_det(struct mb86a16_state *state,
413 int smrt,
414 unsigned char *SIG)
415{
416
417 int ret ;
418 int smrtd ;
419 int wait_sym ;
420
421 u32 wait_t;
422 unsigned char S[3] ;
423 int i ;
424
425 if (*SIG > 45) {
426 if (CNTM_set(state, 2, 1, 2) < 0) {
427 dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error");
428 return -1;
429 }
430 wait_sym = 40000;
431 } else {
432 if (CNTM_set(state, 3, 1, 2) < 0) {
433 dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error");
434 return -1;
435 }
436 wait_sym = 80000;
437 }
438 for (i = 0; i < 3; i++) {
439 if (i == 0)
440 smrtd = smrt * 98 / 100;
441 else if (i == 1)
442 smrtd = smrt;
443 else
444 smrtd = smrt * 102 / 100;
445 smrt_info_get(state, smrtd);
446 smrt_set(state, smrtd);
447 srst(state);
448 wait_t = (wait_sym + 99 * smrtd / 100) / smrtd;
449 if (wait_t == 0)
450 wait_t = 1;
451 msleep_interruptible(10);
452 if (mb86a16_read(state, 0x37, &(S[i])) != 2) {
453 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
454 return -EREMOTEIO;
455 }
456 }
457 if ((S[1] > S[0] * 112 / 100) &&
458 (S[1] > S[2] * 112 / 100)) {
459
460 ret = 1;
461 } else {
462 ret = 0;
463 }
464 *SIG = S[1];
465
466 if (CNTM_set(state, 0, 1, 2) < 0) {
467 dprintk(verbose, MB86A16_ERROR, 1, "CNTM set Error");
468 return -1;
469 }
470
471 return ret;
472}
473
474static int rf_val_set(struct mb86a16_state *state,
475 int f,
476 int smrt,
477 unsigned char R)
478{
479 unsigned char C, F, B;
480 int M;
481 unsigned char rf_val[5];
482 int ack = -1;
483
484 if (smrt > 37750)
485 C = 1;
486 else if (smrt > 18875)
487 C = 2;
488 else if (smrt > 5500)
489 C = 3;
490 else
491 C = 4;
492
493 if (smrt > 30500)
494 F = 3;
495 else if (smrt > 9375)
496 F = 1;
497 else if (smrt > 4625)
498 F = 0;
499 else
500 F = 2;
501
502 if (f < 1060)
503 B = 0;
504 else if (f < 1175)
505 B = 1;
506 else if (f < 1305)
507 B = 2;
508 else if (f < 1435)
509 B = 3;
510 else if (f < 1570)
511 B = 4;
512 else if (f < 1715)
513 B = 5;
514 else if (f < 1845)
515 B = 6;
516 else if (f < 1980)
517 B = 7;
518 else if (f < 2080)
519 B = 8;
520 else
521 B = 9;
522
523 M = f * (1 << R) / 2;
524
525 rf_val[0] = 0x01 | (C << 3) | (F << 1);
526 rf_val[1] = (R << 5) | ((M & 0x1f000) >> 12);
527 rf_val[2] = (M & 0x00ff0) >> 4;
528 rf_val[3] = ((M & 0x0000f) << 4) | B;
529
530 /* Frequency Set */
531 if (mb86a16_write(state, 0x21, rf_val[0]) < 0)
532 ack = 0;
533 if (mb86a16_write(state, 0x22, rf_val[1]) < 0)
534 ack = 0;
535 if (mb86a16_write(state, 0x23, rf_val[2]) < 0)
536 ack = 0;
537 if (mb86a16_write(state, 0x24, rf_val[3]) < 0)
538 ack = 0;
539 if (mb86a16_write(state, 0x25, 0x01) < 0)
540 ack = 0;
541 if (ack == 0) {
542 dprintk(verbose, MB86A16_ERROR, 1, "RF Setup - I2C transfer error");
543 return -EREMOTEIO;
544 }
545
546 return 0;
547}
548
549static int afcerr_chk(struct mb86a16_state *state)
550{
551 unsigned char AFCM_L, AFCM_H ;
552 int AFCM ;
553 int afcm, afcerr ;
554
555 if (mb86a16_read(state, 0x0e, &AFCM_L) != 2)
556 goto err;
557 if (mb86a16_read(state, 0x0f, &AFCM_H) != 2)
558 goto err;
559
560 AFCM = (AFCM_H << 8) + AFCM_L;
561
562 if (AFCM > 2048)
563 afcm = AFCM - 4096;
564 else
565 afcm = AFCM;
566 afcerr = afcm * state->master_clk / 8192;
567
568 return afcerr;
569
570err:
571 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
572 return -EREMOTEIO;
573}
574
575static int dagcm_val_get(struct mb86a16_state *state)
576{
577 int DAGCM;
578 unsigned char DAGCM_H, DAGCM_L;
579
580 if (mb86a16_read(state, 0x45, &DAGCM_L) != 2)
581 goto err;
582 if (mb86a16_read(state, 0x46, &DAGCM_H) != 2)
583 goto err;
584
585 DAGCM = (DAGCM_H << 8) + DAGCM_L;
586
587 return DAGCM;
588
589err:
590 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
591 return -EREMOTEIO;
592}
593
594static int mb86a16_read_status(struct dvb_frontend *fe, fe_status_t *status)
595{
596 u8 stat, stat2;
597 struct mb86a16_state *state = fe->demodulator_priv;
598
599 *status = 0;
600
601 if (mb86a16_read(state, MB86A16_SIG1, &stat) != 2)
602 goto err;
603 if (mb86a16_read(state, MB86A16_SIG2, &stat2) != 2)
604 goto err;
605 if ((stat > 25) && (stat2 > 25))
606 *status |= FE_HAS_SIGNAL;
607 if ((stat > 45) && (stat2 > 45))
608 *status |= FE_HAS_CARRIER;
609
610 if (mb86a16_read(state, MB86A16_STATUS, &stat) != 2)
611 goto err;
612
613 if (stat & 0x01)
614 *status |= FE_HAS_SYNC;
615 if (stat & 0x01)
616 *status |= FE_HAS_VITERBI;
617
618 if (mb86a16_read(state, MB86A16_FRAMESYNC, &stat) != 2)
619 goto err;
620
621 if ((stat & 0x0f) && (*status & FE_HAS_VITERBI))
622 *status |= FE_HAS_LOCK;
623
624 return 0;
625
626err:
627 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
628 return -EREMOTEIO;
629}
630
631static int sync_chk(struct mb86a16_state *state,
632 unsigned char *VIRM)
633{
634 unsigned char val;
635 int sync;
636
637 if (mb86a16_read(state, 0x0d, &val) != 2)
638 goto err;
639
640 dprintk(verbose, MB86A16_INFO, 1, "Status = %02x,", val);
641 sync = val & 0x01;
642 *VIRM = (val & 0x1c) >> 2;
643
644 return sync;
645err:
646 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
647 return -EREMOTEIO;
648
649}
650
651static int freqerr_chk(struct mb86a16_state *state,
652 int fTP,
653 int smrt,
654 int unit)
655{
656 unsigned char CRM, AFCML, AFCMH;
657 unsigned char temp1, temp2, temp3;
658 int crm, afcm, AFCM;
659 int crrerr, afcerr; /* kHz */
660 int frqerr; /* MHz */
661 int afcen, afcexen = 0;
662 int R, M, fOSC, fOSC_OFS;
663
664 if (mb86a16_read(state, 0x43, &CRM) != 2)
665 goto err;
666
667 if (CRM > 127)
668 crm = CRM - 256;
669 else
670 crm = CRM;
671
672 crrerr = smrt * crm / 256;
673 if (mb86a16_read(state, 0x49, &temp1) != 2)
674 goto err;
675
676 afcen = (temp1 & 0x04) >> 2;
677 if (afcen == 0) {
678 if (mb86a16_read(state, 0x2a, &temp1) != 2)
679 goto err;
680 afcexen = (temp1 & 0x20) >> 5;
681 }
682
683 if (afcen == 1) {
684 if (mb86a16_read(state, 0x0e, &AFCML) != 2)
685 goto err;
686 if (mb86a16_read(state, 0x0f, &AFCMH) != 2)
687 goto err;
688 } else if (afcexen == 1) {
689 if (mb86a16_read(state, 0x2b, &AFCML) != 2)
690 goto err;
691 if (mb86a16_read(state, 0x2c, &AFCMH) != 2)
692 goto err;
693 }
694 if ((afcen == 1) || (afcexen == 1)) {
695 smrt_info_get(state, smrt);
696 AFCM = ((AFCMH & 0x01) << 8) + AFCML;
697 if (AFCM > 255)
698 afcm = AFCM - 512;
699 else
700 afcm = AFCM;
701
702 afcerr = afcm * state->master_clk / 8192;
703 } else
704 afcerr = 0;
705
706 if (mb86a16_read(state, 0x22, &temp1) != 2)
707 goto err;
708 if (mb86a16_read(state, 0x23, &temp2) != 2)
709 goto err;
710 if (mb86a16_read(state, 0x24, &temp3) != 2)
711 goto err;
712
713 R = (temp1 & 0xe0) >> 5;
714 M = ((temp1 & 0x1f) << 12) + (temp2 << 4) + (temp3 >> 4);
715 if (R == 0)
716 fOSC = 2 * M;
717 else
718 fOSC = M;
719
720 fOSC_OFS = fOSC - fTP;
721
722 if (unit == 0) { /* MHz */
723 if (crrerr + afcerr + fOSC_OFS * 1000 >= 0)
724 frqerr = (crrerr + afcerr + fOSC_OFS * 1000 + 500) / 1000;
725 else
726 frqerr = (crrerr + afcerr + fOSC_OFS * 1000 - 500) / 1000;
727 } else { /* kHz */
728 frqerr = crrerr + afcerr + fOSC_OFS * 1000;
729 }
730
731 return frqerr;
732err:
733 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
734 return -EREMOTEIO;
735}
736
737static unsigned char vco_dev_get(struct mb86a16_state *state, int smrt)
738{
739 unsigned char R;
740
741 if (smrt > 9375)
742 R = 0;
743 else
744 R = 1;
745
746 return R;
747}
748
749static void swp_info_get(struct mb86a16_state *state,
750 int fOSC_start,
751 int smrt,
752 int v, int R,
753 int swp_ofs,
754 int *fOSC,
755 int *afcex_freq,
756 unsigned char *AFCEX_L,
757 unsigned char *AFCEX_H)
758{
759 int AFCEX ;
760 int crnt_swp_freq ;
761
762 crnt_swp_freq = fOSC_start * 1000 + v * swp_ofs;
763
764 if (R == 0)
765 *fOSC = (crnt_swp_freq + 1000) / 2000 * 2;
766 else
767 *fOSC = (crnt_swp_freq + 500) / 1000;
768
769 if (*fOSC >= crnt_swp_freq)
770 *afcex_freq = *fOSC * 1000 - crnt_swp_freq;
771 else
772 *afcex_freq = crnt_swp_freq - *fOSC * 1000;
773
774 AFCEX = *afcex_freq * 8192 / state->master_clk;
775 *AFCEX_L = AFCEX & 0x00ff;
776 *AFCEX_H = (AFCEX & 0x0f00) >> 8;
777}
778
779
780static int swp_freq_calcuation(struct mb86a16_state *state, int i, int v, int *V, int vmax, int vmin,
781 int SIGMIN, int fOSC, int afcex_freq, int swp_ofs, unsigned char *SIG1)
782{
783 int swp_freq ;
784
785 if ((i % 2 == 1) && (v <= vmax)) {
786 /* positive v (case 1) */
787 if ((v - 1 == vmin) &&
788 (*(V + 30 + v) >= 0) &&
789 (*(V + 30 + v - 1) >= 0) &&
790 (*(V + 30 + v - 1) > *(V + 30 + v)) &&
791 (*(V + 30 + v - 1) > SIGMIN)) {
792
793 swp_freq = fOSC * 1000 + afcex_freq - swp_ofs;
794 *SIG1 = *(V + 30 + v - 1);
795 } else if ((v == vmax) &&
796 (*(V + 30 + v) >= 0) &&
797 (*(V + 30 + v - 1) >= 0) &&
798 (*(V + 30 + v) > *(V + 30 + v - 1)) &&
799 (*(V + 30 + v) > SIGMIN)) {
800 /* (case 2) */
801 swp_freq = fOSC * 1000 + afcex_freq;
802 *SIG1 = *(V + 30 + v);
803 } else if ((*(V + 30 + v) > 0) &&
804 (*(V + 30 + v - 1) > 0) &&
805 (*(V + 30 + v - 2) > 0) &&
806 (*(V + 30 + v - 3) > 0) &&
807 (*(V + 30 + v - 1) > *(V + 30 + v)) &&
808 (*(V + 30 + v - 2) > *(V + 30 + v - 3)) &&
809 ((*(V + 30 + v - 1) > SIGMIN) ||
810 (*(V + 30 + v - 2) > SIGMIN))) {
811 /* (case 3) */
812 if (*(V + 30 + v - 1) >= *(V + 30 + v - 2)) {
813 swp_freq = fOSC * 1000 + afcex_freq - swp_ofs;
814 *SIG1 = *(V + 30 + v - 1);
815 } else {
816 swp_freq = fOSC * 1000 + afcex_freq - swp_ofs * 2;
817 *SIG1 = *(V + 30 + v - 2);
818 }
819 } else if ((v == vmax) &&
820 (*(V + 30 + v) >= 0) &&
821 (*(V + 30 + v - 1) >= 0) &&
822 (*(V + 30 + v - 2) >= 0) &&
823 (*(V + 30 + v) > *(V + 30 + v - 2)) &&
824 (*(V + 30 + v - 1) > *(V + 30 + v - 2)) &&
825 ((*(V + 30 + v) > SIGMIN) ||
826 (*(V + 30 + v - 1) > SIGMIN))) {
827 /* (case 4) */
828 if (*(V + 30 + v) >= *(V + 30 + v - 1)) {
829 swp_freq = fOSC * 1000 + afcex_freq;
830 *SIG1 = *(V + 30 + v);
831 } else {
832 swp_freq = fOSC * 1000 + afcex_freq - swp_ofs;
833 *SIG1 = *(V + 30 + v - 1);
834 }
835 } else {
836 swp_freq = -1 ;
837 }
838 } else if ((i % 2 == 0) && (v >= vmin)) {
839 /* Negative v (case 1) */
840 if ((*(V + 30 + v) > 0) &&
841 (*(V + 30 + v + 1) > 0) &&
842 (*(V + 30 + v + 2) > 0) &&
843 (*(V + 30 + v + 1) > *(V + 30 + v)) &&
844 (*(V + 30 + v + 1) > *(V + 30 + v + 2)) &&
845 (*(V + 30 + v + 1) > SIGMIN)) {
846
847 swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
848 *SIG1 = *(V + 30 + v + 1);
849 } else if ((v + 1 == vmax) &&
850 (*(V + 30 + v) >= 0) &&
851 (*(V + 30 + v + 1) >= 0) &&
852 (*(V + 30 + v + 1) > *(V + 30 + v)) &&
853 (*(V + 30 + v + 1) > SIGMIN)) {
854 /* (case 2) */
855 swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
856 *SIG1 = *(V + 30 + v);
857 } else if ((v == vmin) &&
858 (*(V + 30 + v) > 0) &&
859 (*(V + 30 + v + 1) > 0) &&
860 (*(V + 30 + v + 2) > 0) &&
861 (*(V + 30 + v) > *(V + 30 + v + 1)) &&
862 (*(V + 30 + v) > *(V + 30 + v + 2)) &&
863 (*(V + 30 + v) > SIGMIN)) {
864 /* (case 3) */
865 swp_freq = fOSC * 1000 + afcex_freq;
866 *SIG1 = *(V + 30 + v);
867 } else if ((*(V + 30 + v) >= 0) &&
868 (*(V + 30 + v + 1) >= 0) &&
869 (*(V + 30 + v + 2) >= 0) &&
870 (*(V + 30 + v + 3) >= 0) &&
871 (*(V + 30 + v + 1) > *(V + 30 + v)) &&
872 (*(V + 30 + v + 2) > *(V + 30 + v + 3)) &&
873 ((*(V + 30 + v + 1) > SIGMIN) ||
874 (*(V + 30 + v + 2) > SIGMIN))) {
875 /* (case 4) */
876 if (*(V + 30 + v + 1) >= *(V + 30 + v + 2)) {
877 swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
878 *SIG1 = *(V + 30 + v + 1);
879 } else {
880 swp_freq = fOSC * 1000 + afcex_freq + swp_ofs * 2;
881 *SIG1 = *(V + 30 + v + 2);
882 }
883 } else if ((*(V + 30 + v) >= 0) &&
884 (*(V + 30 + v + 1) >= 0) &&
885 (*(V + 30 + v + 2) >= 0) &&
886 (*(V + 30 + v + 3) >= 0) &&
887 (*(V + 30 + v) > *(V + 30 + v + 2)) &&
888 (*(V + 30 + v + 1) > *(V + 30 + v + 2)) &&
889 (*(V + 30 + v) > *(V + 30 + v + 3)) &&
890 (*(V + 30 + v + 1) > *(V + 30 + v + 3)) &&
891 ((*(V + 30 + v) > SIGMIN) ||
892 (*(V + 30 + v + 1) > SIGMIN))) {
893 /* (case 5) */
894 if (*(V + 30 + v) >= *(V + 30 + v + 1)) {
895 swp_freq = fOSC * 1000 + afcex_freq;
896 *SIG1 = *(V + 30 + v);
897 } else {
898 swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
899 *SIG1 = *(V + 30 + v + 1);
900 }
901 } else if ((v + 2 == vmin) &&
902 (*(V + 30 + v) >= 0) &&
903 (*(V + 30 + v + 1) >= 0) &&
904 (*(V + 30 + v + 2) >= 0) &&
905 (*(V + 30 + v + 1) > *(V + 30 + v)) &&
906 (*(V + 30 + v + 2) > *(V + 30 + v)) &&
907 ((*(V + 30 + v + 1) > SIGMIN) ||
908 (*(V + 30 + v + 2) > SIGMIN))) {
909 /* (case 6) */
910 if (*(V + 30 + v + 1) >= *(V + 30 + v + 2)) {
911 swp_freq = fOSC * 1000 + afcex_freq + swp_ofs;
912 *SIG1 = *(V + 30 + v + 1);
913 } else {
914 swp_freq = fOSC * 1000 + afcex_freq + swp_ofs * 2;
915 *SIG1 = *(V + 30 + v + 2);
916 }
917 } else if ((vmax == 0) && (vmin == 0) && (*(V + 30 + v) > SIGMIN)) {
918 swp_freq = fOSC * 1000;
919 *SIG1 = *(V + 30 + v);
920 } else
921 swp_freq = -1;
922 } else
923 swp_freq = -1;
924
925 return swp_freq;
926}
927
928static void swp_info_get2(struct mb86a16_state *state,
929 int smrt,
930 int R,
931 int swp_freq,
932 int *afcex_freq,
933 int *fOSC,
934 unsigned char *AFCEX_L,
935 unsigned char *AFCEX_H)
936{
937 int AFCEX ;
938
939 if (R == 0)
940 *fOSC = (swp_freq + 1000) / 2000 * 2;
941 else
942 *fOSC = (swp_freq + 500) / 1000;
943
944 if (*fOSC >= swp_freq)
945 *afcex_freq = *fOSC * 1000 - swp_freq;
946 else
947 *afcex_freq = swp_freq - *fOSC * 1000;
948
949 AFCEX = *afcex_freq * 8192 / state->master_clk;
950 *AFCEX_L = AFCEX & 0x00ff;
951 *AFCEX_H = (AFCEX & 0x0f00) >> 8;
952}
953
954static void afcex_info_get(struct mb86a16_state *state,
955 int afcex_freq,
956 unsigned char *AFCEX_L,
957 unsigned char *AFCEX_H)
958{
959 int AFCEX ;
960
961 AFCEX = afcex_freq * 8192 / state->master_clk;
962 *AFCEX_L = AFCEX & 0x00ff;
963 *AFCEX_H = (AFCEX & 0x0f00) >> 8;
964}
965
966static int SEQ_set(struct mb86a16_state *state, unsigned char loop)
967{
968 /* SLOCK0 = 0 */
969 if (mb86a16_write(state, 0x32, 0x02 | (loop << 2)) < 0) {
970 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
971 return -EREMOTEIO;
972 }
973
974 return 0;
975}
976
977static int iq_vt_set(struct mb86a16_state *state, unsigned char IQINV)
978{
979 /* Viterbi Rate, IQ Settings */
980 if (mb86a16_write(state, 0x06, 0xdf | (IQINV << 5)) < 0) {
981 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
982 return -EREMOTEIO;
983 }
984
985 return 0;
986}
987
988static int FEC_srst(struct mb86a16_state *state)
989{
990 if (mb86a16_write(state, MB86A16_RESET, 0x02) < 0) {
991 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
992 return -EREMOTEIO;
993 }
994
995 return 0;
996}
997
998static int S2T_set(struct mb86a16_state *state, unsigned char S2T)
999{
1000 if (mb86a16_write(state, 0x34, 0x70 | S2T) < 0) {
1001 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
1002 return -EREMOTEIO;
1003 }
1004
1005 return 0;
1006}
1007
1008static int S45T_set(struct mb86a16_state *state, unsigned char S4T, unsigned char S5T)
1009{
1010 if (mb86a16_write(state, 0x35, 0x00 | (S5T << 4) | S4T) < 0) {
1011 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
1012 return -EREMOTEIO;
1013 }
1014
1015 return 0;
1016}
1017
1018
1019static int mb86a16_set_fe(struct mb86a16_state *state)
1020{
1021 u8 agcval, cnmval;
1022
1023 int i, j;
1024 int fOSC = 0;
1025 int fOSC_start = 0;
1026 int wait_t;
1027 int fcp;
1028 int swp_ofs;
1029 int V[60];
1030 u8 SIG1MIN;
1031
1032 unsigned char CREN, AFCEN, AFCEXEN;
1033 unsigned char SIG1;
1034 unsigned char TIMINT1, TIMINT2, TIMEXT;
1035 unsigned char S0T, S1T;
1036 unsigned char S2T;
1037/* unsigned char S2T, S3T; */
1038 unsigned char S4T, S5T;
1039 unsigned char AFCEX_L, AFCEX_H;
1040 unsigned char R;
1041 unsigned char VIRM;
1042 unsigned char ETH, VIA;
1043 unsigned char junk;
1044
1045 int loop;
1046 int ftemp;
1047 int v, vmax, vmin;
1048 int vmax_his, vmin_his;
1049 int swp_freq, prev_swp_freq[20];
1050 int prev_freq_num;
1051 int signal_dupl;
1052 int afcex_freq;
1053 int signal;
1054 int afcerr;
1055 int temp_freq, delta_freq;
1056 int dagcm[4];
1057 int smrt_d;
1058/* int freq_err; */
1059 int n;
1060 int ret = -1;
1061 int sync;
1062
1063 dprintk(verbose, MB86A16_INFO, 1, "freq=%d Mhz, symbrt=%d Ksps", state->frequency, state->srate);
1064
1065 fcp = 3000;
1066 swp_ofs = state->srate / 4;
1067
1068 for (i = 0; i < 60; i++)
1069 V[i] = -1;
1070
1071 for (i = 0; i < 20; i++)
1072 prev_swp_freq[i] = 0;
1073
1074 SIG1MIN = 25;
1075
1076 for (n = 0; ((n < 3) && (ret == -1)); n++) {
1077 SEQ_set(state, 0);
1078 iq_vt_set(state, 0);
1079
1080 CREN = 0;
1081 AFCEN = 0;
1082 AFCEXEN = 1;
1083 TIMINT1 = 0;
1084 TIMINT2 = 1;
1085 TIMEXT = 2;
1086 S1T = 0;
1087 S0T = 0;
1088
1089 if (initial_set(state) < 0) {
1090 dprintk(verbose, MB86A16_ERROR, 1, "initial set failed");
1091 return -1;
1092 }
1093 if (DAGC_data_set(state, 3, 2) < 0) {
1094 dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error");
1095 return -1;
1096 }
1097 if (EN_set(state, CREN, AFCEN) < 0) {
1098 dprintk(verbose, MB86A16_ERROR, 1, "EN set error");
1099 return -1; /* (0, 0) */
1100 }
1101 if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) {
1102 dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
1103 return -1; /* (1, smrt) = (1, symbolrate) */
1104 }
1105 if (CNTM_set(state, TIMINT1, TIMINT2, TIMEXT) < 0) {
1106 dprintk(verbose, MB86A16_ERROR, 1, "CNTM set error");
1107 return -1; /* (0, 1, 2) */
1108 }
1109 if (S01T_set(state, S1T, S0T) < 0) {
1110 dprintk(verbose, MB86A16_ERROR, 1, "S01T set error");
1111 return -1; /* (0, 0) */
1112 }
1113 smrt_info_get(state, state->srate);
1114 if (smrt_set(state, state->srate) < 0) {
1115 dprintk(verbose, MB86A16_ERROR, 1, "smrt info get error");
1116 return -1;
1117 }
1118
1119 R = vco_dev_get(state, state->srate);
1120 if (R == 1)
1121 fOSC_start = state->frequency;
1122
1123 else if (R == 0) {
1124 if (state->frequency % 2 == 0) {
1125 fOSC_start = state->frequency;
1126 } else {
1127 fOSC_start = state->frequency + 1;
1128 if (fOSC_start > 2150)
1129 fOSC_start = state->frequency - 1;
1130 }
1131 }
1132 loop = 1;
1133 ftemp = fOSC_start * 1000;
1134 vmax = 0 ;
1135 while (loop == 1) {
1136 ftemp = ftemp + swp_ofs;
1137 vmax++;
1138
1139 /* Upper bound */
1140 if (ftemp > 2150000) {
1141 loop = 0;
1142 vmax--;
1143 } else {
1144 if ((ftemp == 2150000) ||
1145 (ftemp - state->frequency * 1000 >= fcp + state->srate / 4))
1146 loop = 0;
1147 }
1148 }
1149
1150 loop = 1;
1151 ftemp = fOSC_start * 1000;
1152 vmin = 0 ;
1153 while (loop == 1) {
1154 ftemp = ftemp - swp_ofs;
1155 vmin--;
1156
1157 /* Lower bound */
1158 if (ftemp < 950000) {
1159 loop = 0;
1160 vmin++;
1161 } else {
1162 if ((ftemp == 950000) ||
1163 (state->frequency * 1000 - ftemp >= fcp + state->srate / 4))
1164 loop = 0;
1165 }
1166 }
1167
1168 wait_t = (8000 + state->srate / 2) / state->srate;
1169 if (wait_t == 0)
1170 wait_t = 1;
1171
1172 i = 0;
1173 j = 0;
1174 prev_freq_num = 0;
1175 loop = 1;
1176 signal = 0;
1177 vmax_his = 0;
1178 vmin_his = 0;
1179 v = 0;
1180
1181 while (loop == 1) {
1182 swp_info_get(state, fOSC_start, state->srate,
1183 v, R, swp_ofs, &fOSC,
1184 &afcex_freq, &AFCEX_L, &AFCEX_H);
1185
1186 udelay(100);
1187 if (rf_val_set(state, fOSC, state->srate, R) < 0) {
1188 dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
1189 return -1;
1190 }
1191 udelay(100);
1192 if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
1193 dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
1194 return -1;
1195 }
1196 if (srst(state) < 0) {
1197 dprintk(verbose, MB86A16_ERROR, 1, "srst error");
1198 return -1;
1199 }
1200 msleep_interruptible(wait_t);
1201
1202 if (mb86a16_read(state, 0x37, &SIG1) != 2) {
1203 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
1204 return -1;
1205 }
1206 V[30 + v] = SIG1 ;
1207 swp_freq = swp_freq_calcuation(state, i, v, V, vmax, vmin,
1208 SIG1MIN, fOSC, afcex_freq,
1209 swp_ofs, &SIG1); /* changed */
1210
1211 signal_dupl = 0;
1212 for (j = 0; j < prev_freq_num; j++) {
1213 if ((ABS(prev_swp_freq[j] - swp_freq)) < (swp_ofs * 3 / 2)) {
1214 signal_dupl = 1;
1215 dprintk(verbose, MB86A16_INFO, 1, "Probably Duplicate Signal, j = %d", j);
1216 }
1217 }
1218 if ((signal_dupl == 0) && (swp_freq > 0) && (ABS(swp_freq - state->frequency * 1000) < fcp + state->srate / 6)) {
1219 dprintk(verbose, MB86A16_DEBUG, 1, "------ Signal detect ------ [swp_freq=[%07d, srate=%05d]]", swp_freq, state->srate);
1220 prev_swp_freq[prev_freq_num] = swp_freq;
1221 prev_freq_num++;
1222 swp_info_get2(state, state->srate, R, swp_freq,
1223 &afcex_freq, &fOSC,
1224 &AFCEX_L, &AFCEX_H);
1225
1226 if (rf_val_set(state, fOSC, state->srate, R) < 0) {
1227 dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
1228 return -1;
1229 }
1230 if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
1231 dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
1232 return -1;
1233 }
1234 signal = signal_det(state, state->srate, &SIG1);
1235 if (signal == 1) {
1236 dprintk(verbose, MB86A16_ERROR, 1, "***** Signal Found *****");
1237 loop = 0;
1238 } else {
1239 dprintk(verbose, MB86A16_ERROR, 1, "!!!!! No signal !!!!!, try again...");
1240 smrt_info_get(state, state->srate);
1241 if (smrt_set(state, state->srate) < 0) {
1242 dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
1243 return -1;
1244 }
1245 }
1246 }
1247 if (v > vmax)
1248 vmax_his = 1 ;
1249 if (v < vmin)
1250 vmin_his = 1 ;
1251 i++;
1252
1253 if ((i % 2 == 1) && (vmax_his == 1))
1254 i++;
1255 if ((i % 2 == 0) && (vmin_his == 1))
1256 i++;
1257
1258 if (i % 2 == 1)
1259 v = (i + 1) / 2;
1260 else
1261 v = -i / 2;
1262
1263 if ((vmax_his == 1) && (vmin_his == 1))
1264 loop = 0 ;
1265 }
1266
1267 if (signal == 1) {
1268 dprintk(verbose, MB86A16_INFO, 1, " Start Freq Error Check");
1269 S1T = 7 ;
1270 S0T = 1 ;
1271 CREN = 0 ;
1272 AFCEN = 1 ;
1273 AFCEXEN = 0 ;
1274
1275 if (S01T_set(state, S1T, S0T) < 0) {
1276 dprintk(verbose, MB86A16_ERROR, 1, "S01T set error");
1277 return -1;
1278 }
1279 smrt_info_get(state, state->srate);
1280 if (smrt_set(state, state->srate) < 0) {
1281 dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
1282 return -1;
1283 }
1284 if (EN_set(state, CREN, AFCEN) < 0) {
1285 dprintk(verbose, MB86A16_ERROR, 1, "EN set error");
1286 return -1;
1287 }
1288 if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) {
1289 dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
1290 return -1;
1291 }
1292 afcex_info_get(state, afcex_freq, &AFCEX_L, &AFCEX_H);
1293 if (afcofs_data_set(state, AFCEX_L, AFCEX_H) < 0) {
1294 dprintk(verbose, MB86A16_ERROR, 1, "AFCOFS data set error");
1295 return -1;
1296 }
1297 if (srst(state) < 0) {
1298 dprintk(verbose, MB86A16_ERROR, 1, "srst error");
1299 return -1;
1300 }
1301 /* delay 4~200 */
1302 wait_t = 200000 / state->master_clk + 200000 / state->srate;
1303 msleep(wait_t);
1304 afcerr = afcerr_chk(state);
1305 if (afcerr == -1)
1306 return -1;
1307
1308 swp_freq = fOSC * 1000 + afcerr ;
1309 AFCEXEN = 1 ;
1310 if (state->srate >= 1500)
1311 smrt_d = state->srate / 3;
1312 else
1313 smrt_d = state->srate / 2;
1314 smrt_info_get(state, smrt_d);
1315 if (smrt_set(state, smrt_d) < 0) {
1316 dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
1317 return -1;
1318 }
1319 if (AFCEXEN_set(state, AFCEXEN, smrt_d) < 0) {
1320 dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
1321 return -1;
1322 }
1323 R = vco_dev_get(state, smrt_d);
1324 if (DAGC_data_set(state, 2, 0) < 0) {
1325 dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error");
1326 return -1;
1327 }
1328 for (i = 0; i < 3; i++) {
1329 temp_freq = swp_freq + (i - 1) * state->srate / 8;
1330 swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
1331 if (rf_val_set(state, fOSC, smrt_d, R) < 0) {
1332 dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
1333 return -1;
1334 }
1335 if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
1336 dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
1337 return -1;
1338 }
1339 wait_t = 200000 / state->master_clk + 40000 / smrt_d;
1340 msleep(wait_t);
1341 dagcm[i] = dagcm_val_get(state);
1342 }
1343 if ((dagcm[0] > dagcm[1]) &&
1344 (dagcm[0] > dagcm[2]) &&
1345 (dagcm[0] - dagcm[1] > 2 * (dagcm[2] - dagcm[1]))) {
1346
1347 temp_freq = swp_freq - 2 * state->srate / 8;
1348 swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
1349 if (rf_val_set(state, fOSC, smrt_d, R) < 0) {
1350 dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
1351 return -1;
1352 }
1353 if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
1354 dprintk(verbose, MB86A16_ERROR, 1, "afcex data set");
1355 return -1;
1356 }
1357 wait_t = 200000 / state->master_clk + 40000 / smrt_d;
1358 msleep(wait_t);
1359 dagcm[3] = dagcm_val_get(state);
1360 if (dagcm[3] > dagcm[1])
1361 delta_freq = (dagcm[2] - dagcm[0] + dagcm[1] - dagcm[3]) * state->srate / 300;
1362 else
1363 delta_freq = 0;
1364 } else if ((dagcm[2] > dagcm[1]) &&
1365 (dagcm[2] > dagcm[0]) &&
1366 (dagcm[2] - dagcm[1] > 2 * (dagcm[0] - dagcm[1]))) {
1367
1368 temp_freq = swp_freq + 2 * state->srate / 8;
1369 swp_info_get2(state, smrt_d, R, temp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
1370 if (rf_val_set(state, fOSC, smrt_d, R) < 0) {
1371 dprintk(verbose, MB86A16_ERROR, 1, "rf val set");
1372 return -1;
1373 }
1374 if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
1375 dprintk(verbose, MB86A16_ERROR, 1, "afcex data set");
1376 return -1;
1377 }
1378 wait_t = 200000 / state->master_clk + 40000 / smrt_d;
1379 msleep(wait_t);
1380 dagcm[3] = dagcm_val_get(state);
1381 if (dagcm[3] > dagcm[1])
1382 delta_freq = (dagcm[2] - dagcm[0] + dagcm[3] - dagcm[1]) * state->srate / 300;
1383 else
1384 delta_freq = 0 ;
1385
1386 } else {
1387 delta_freq = 0 ;
1388 }
1389 dprintk(verbose, MB86A16_INFO, 1, "SWEEP Frequency = %d", swp_freq);
1390 swp_freq += delta_freq;
1391 dprintk(verbose, MB86A16_INFO, 1, "Adjusting .., DELTA Freq = %d, SWEEP Freq=%d", delta_freq, swp_freq);
1392 if (ABS(state->frequency * 1000 - swp_freq) > 3800) {
1393 dprintk(verbose, MB86A16_INFO, 1, "NO -- SIGNAL !");
1394 } else {
1395
1396 S1T = 0;
1397 S0T = 3;
1398 CREN = 1;
1399 AFCEN = 0;
1400 AFCEXEN = 1;
1401
1402 if (S01T_set(state, S1T, S0T) < 0) {
1403 dprintk(verbose, MB86A16_ERROR, 1, "S01T set error");
1404 return -1;
1405 }
1406 if (DAGC_data_set(state, 0, 0) < 0) {
1407 dprintk(verbose, MB86A16_ERROR, 1, "DAGC data set error");
1408 return -1;
1409 }
1410 R = vco_dev_get(state, state->srate);
1411 smrt_info_get(state, state->srate);
1412 if (smrt_set(state, state->srate) < 0) {
1413 dprintk(verbose, MB86A16_ERROR, 1, "smrt set error");
1414 return -1;
1415 }
1416 if (EN_set(state, CREN, AFCEN) < 0) {
1417 dprintk(verbose, MB86A16_ERROR, 1, "EN set error");
1418 return -1;
1419 }
1420 if (AFCEXEN_set(state, AFCEXEN, state->srate) < 0) {
1421 dprintk(verbose, MB86A16_ERROR, 1, "AFCEXEN set error");
1422 return -1;
1423 }
1424 swp_info_get2(state, state->srate, R, swp_freq, &afcex_freq, &fOSC, &AFCEX_L, &AFCEX_H);
1425 if (rf_val_set(state, fOSC, state->srate, R) < 0) {
1426 dprintk(verbose, MB86A16_ERROR, 1, "rf val set error");
1427 return -1;
1428 }
1429 if (afcex_data_set(state, AFCEX_L, AFCEX_H) < 0) {
1430 dprintk(verbose, MB86A16_ERROR, 1, "afcex data set error");
1431 return -1;
1432 }
1433 if (srst(state) < 0) {
1434 dprintk(verbose, MB86A16_ERROR, 1, "srst error");
1435 return -1;
1436 }
1437 wait_t = 7 + (10000 + state->srate / 2) / state->srate;
1438 if (wait_t == 0)
1439 wait_t = 1;
1440 msleep_interruptible(wait_t);
1441 if (mb86a16_read(state, 0x37, &SIG1) != 2) {
1442 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
1443 return -EREMOTEIO;
1444 }
1445
1446 if (SIG1 > 110) {
1447 S2T = 4; S4T = 1; S5T = 6; ETH = 4; VIA = 6;
1448 wait_t = 7 + (917504 + state->srate / 2) / state->srate;
1449 } else if (SIG1 > 105) {
1450 S2T = 4; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
1451 wait_t = 7 + (1048576 + state->srate / 2) / state->srate;
1452 } else if (SIG1 > 85) {
1453 S2T = 5; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
1454 wait_t = 7 + (1310720 + state->srate / 2) / state->srate;
1455 } else if (SIG1 > 65) {
1456 S2T = 6; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
1457 wait_t = 7 + (1572864 + state->srate / 2) / state->srate;
1458 } else {
1459 S2T = 7; S4T = 2; S5T = 8; ETH = 7; VIA = 2;
1460 wait_t = 7 + (2097152 + state->srate / 2) / state->srate;
1461 }
1462 wait_t *= 2; /* FOS */
1463 S2T_set(state, S2T);
1464 S45T_set(state, S4T, S5T);
1465 Vi_set(state, ETH, VIA);
1466 srst(state);
1467 msleep_interruptible(wait_t);
1468 sync = sync_chk(state, &VIRM);
1469 dprintk(verbose, MB86A16_INFO, 1, "-------- Viterbi=[%d] SYNC=[%d] ---------", VIRM, sync);
1470 if (VIRM) {
1471 if (VIRM == 4) {
1472 /* 5/6 */
1473 if (SIG1 > 110)
1474 wait_t = (786432 + state->srate / 2) / state->srate;
1475 else
1476 wait_t = (1572864 + state->srate / 2) / state->srate;
1477 if (state->srate < 5000)
1478 /* FIXME ! , should be a long wait ! */
1479 msleep_interruptible(wait_t);
1480 else
1481 msleep_interruptible(wait_t);
1482
1483 if (sync_chk(state, &junk) == 0) {
1484 iq_vt_set(state, 1);
1485 FEC_srst(state);
1486 }
1487 }
1488 /* 1/2, 2/3, 3/4, 7/8 */
1489 if (SIG1 > 110)
1490 wait_t = (786432 + state->srate / 2) / state->srate;
1491 else
1492 wait_t = (1572864 + state->srate / 2) / state->srate;
1493 msleep_interruptible(wait_t);
1494 SEQ_set(state, 1);
1495 } else {
1496 dprintk(verbose, MB86A16_INFO, 1, "NO -- SYNC");
1497 SEQ_set(state, 1);
1498 ret = -1;
1499 }
1500 }
1501 } else {
1502 dprintk(verbose, MB86A16_INFO, 1, "NO -- SIGNAL");
1503 ret = -1;
1504 }
1505
1506 sync = sync_chk(state, &junk);
1507 if (sync) {
1508 dprintk(verbose, MB86A16_INFO, 1, "******* SYNC *******");
1509 freqerr_chk(state, state->frequency, state->srate, 1);
1510 ret = 0;
1511 break;
1512 }
1513 }
1514
1515 mb86a16_read(state, 0x15, &agcval);
1516 mb86a16_read(state, 0x26, &cnmval);
1517 dprintk(verbose, MB86A16_INFO, 1, "AGC = %02x CNM = %02x", agcval, cnmval);
1518
1519 return ret;
1520}
1521
1522static int mb86a16_send_diseqc_msg(struct dvb_frontend *fe,
1523 struct dvb_diseqc_master_cmd *cmd)
1524{
1525 struct mb86a16_state *state = fe->demodulator_priv;
1526 int i;
1527 u8 regs;
1528
1529 if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA) < 0)
1530 goto err;
1531 if (mb86a16_write(state, MB86A16_DCCOUT, 0x00) < 0)
1532 goto err;
1533 if (mb86a16_write(state, MB86A16_TONEOUT2, 0x04) < 0)
1534 goto err;
1535
1536 regs = 0x18;
1537
1538 if (cmd->msg_len > 5 || cmd->msg_len < 4)
1539 return -EINVAL;
1540
1541 for (i = 0; i < cmd->msg_len; i++) {
1542 if (mb86a16_write(state, regs, cmd->msg[i]) < 0)
1543 goto err;
1544
1545 regs++;
1546 }
1547 i += 0x90;
1548
1549 msleep_interruptible(10);
1550
1551 if (mb86a16_write(state, MB86A16_DCC1, i) < 0)
1552 goto err;
1553 if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
1554 goto err;
1555
1556 return 0;
1557
1558err:
1559 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
1560 return -EREMOTEIO;
1561}
1562
1563static int mb86a16_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
1564{
1565 struct mb86a16_state *state = fe->demodulator_priv;
1566
1567 switch (burst) {
1568 case SEC_MINI_A:
1569 if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA |
1570 MB86A16_DCC1_TBEN |
1571 MB86A16_DCC1_TBO) < 0)
1572 goto err;
1573 if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
1574 goto err;
1575 break;
1576 case SEC_MINI_B:
1577 if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA |
1578 MB86A16_DCC1_TBEN) < 0)
1579 goto err;
1580 if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
1581 goto err;
1582 break;
1583 }
1584
1585 return 0;
1586err:
1587 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
1588 return -EREMOTEIO;
1589}
1590
1591static int mb86a16_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
1592{
1593 struct mb86a16_state *state = fe->demodulator_priv;
1594
1595 switch (tone) {
1596 case SEC_TONE_ON:
1597 if (mb86a16_write(state, MB86A16_TONEOUT2, 0x00) < 0)
1598 goto err;
1599 if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA |
1600 MB86A16_DCC1_CTOE) < 0)
1601
1602 goto err;
1603 if (mb86a16_write(state, MB86A16_DCCOUT, MB86A16_DCCOUT_DISEN) < 0)
1604 goto err;
1605 break;
1606 case SEC_TONE_OFF:
1607 if (mb86a16_write(state, MB86A16_TONEOUT2, 0x04) < 0)
1608 goto err;
1609 if (mb86a16_write(state, MB86A16_DCC1, MB86A16_DCC1_DISTA) < 0)
1610 goto err;
1611 if (mb86a16_write(state, MB86A16_DCCOUT, 0x00) < 0)
1612 goto err;
1613 break;
1614 default:
1615 return -EINVAL;
1616 }
1617 return 0;
1618
1619err:
1620 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
1621 return -EREMOTEIO;
1622}
1623
1624static enum dvbfe_search mb86a16_search(struct dvb_frontend *fe,
1625 struct dvb_frontend_parameters *p)
1626{
1627 struct mb86a16_state *state = fe->demodulator_priv;
1628
1629 state->frequency = p->frequency / 1000;
1630 state->srate = p->u.qpsk.symbol_rate / 1000;
1631
1632 if (!mb86a16_set_fe(state)) {
1633 dprintk(verbose, MB86A16_ERROR, 1, "Successfully acquired LOCK");
1634 return DVBFE_ALGO_SEARCH_SUCCESS;
1635 }
1636
1637 dprintk(verbose, MB86A16_ERROR, 1, "Lock acquisition failed!");
1638 return DVBFE_ALGO_SEARCH_FAILED;
1639}
1640
1641static void mb86a16_release(struct dvb_frontend *fe)
1642{
1643 struct mb86a16_state *state = fe->demodulator_priv;
1644 kfree(state);
1645}
1646
1647static int mb86a16_init(struct dvb_frontend *fe)
1648{
1649 return 0;
1650}
1651
1652static int mb86a16_sleep(struct dvb_frontend *fe)
1653{
1654 return 0;
1655}
1656
1657static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber)
1658{
1659 u8 ber_mon, ber_tab, ber_lsb, ber_mid, ber_msb, ber_tim, ber_rst;
1660 u32 timer;
1661
1662 struct mb86a16_state *state = fe->demodulator_priv;
1663
1664 *ber = 0;
1665 if (mb86a16_read(state, MB86A16_BERMON, &ber_mon) != 2)
1666 goto err;
1667 if (mb86a16_read(state, MB86A16_BERTAB, &ber_tab) != 2)
1668 goto err;
1669 if (mb86a16_read(state, MB86A16_BERLSB, &ber_lsb) != 2)
1670 goto err;
1671 if (mb86a16_read(state, MB86A16_BERMID, &ber_mid) != 2)
1672 goto err;
1673 if (mb86a16_read(state, MB86A16_BERMSB, &ber_msb) != 2)
1674 goto err;
1675 /* BER monitor invalid when BER_EN = 0 */
1676 if (ber_mon & 0x04) {
1677 /* coarse, fast calculation */
1678 *ber = ber_tab & 0x1f;
1679 dprintk(verbose, MB86A16_DEBUG, 1, "BER coarse=[0x%02x]", *ber);
1680 if (ber_mon & 0x01) {
1681 /*
1682 * BER_SEL = 1, The monitored BER is the estimated
1683 * value with a Reed-Solomon decoder error amount at
1684 * the deinterleaver output.
1685 * monitored BER is expressed as a 20 bit output in total
1686 */
1687 ber_rst = ber_mon >> 3;
1688 *ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
1689 if (ber_rst == 0)
1690 timer = 12500000;
1691 if (ber_rst == 1)
1692 timer = 25000000;
1693 if (ber_rst == 2)
1694 timer = 50000000;
1695 if (ber_rst == 3)
1696 timer = 100000000;
1697
1698 *ber /= timer;
1699 dprintk(verbose, MB86A16_DEBUG, 1, "BER fine=[0x%02x]", *ber);
1700 } else {
1701 /*
1702 * BER_SEL = 0, The monitored BER is the estimated
1703 * value with a Viterbi decoder error amount at the
1704 * QPSK demodulator output.
1705 * monitored BER is expressed as a 24 bit output in total
1706 */
1707 ber_tim = ber_mon >> 1;
1708 *ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
1709 if (ber_tim == 0)
1710 timer = 16;
1711 if (ber_tim == 1)
1712 timer = 24;
1713
1714 *ber /= 2 ^ timer;
1715 dprintk(verbose, MB86A16_DEBUG, 1, "BER fine=[0x%02x]", *ber);
1716 }
1717 }
1718 return 0;
1719err:
1720 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
1721 return -EREMOTEIO;
1722}
1723
1724static int mb86a16_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1725{
1726 u8 agcm = 0;
1727 struct mb86a16_state *state = fe->demodulator_priv;
1728
1729 *strength = 0;
1730 if (mb86a16_read(state, MB86A16_AGCM, &agcm) != 2) {
1731 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
1732 return -EREMOTEIO;
1733 }
1734
1735 *strength = ((0xff - agcm) * 100) / 256;
1736 dprintk(verbose, MB86A16_DEBUG, 1, "Signal strength=[%d %%]", (u8) *strength);
1737 *strength = (0xffff - 0xff) + agcm;
1738
1739 return 0;
1740}
1741
1742struct cnr {
1743 u8 cn_reg;
1744 u8 cn_val;
1745};
1746
1747static const struct cnr cnr_tab[] = {
1748 { 35, 2 },
1749 { 40, 3 },
1750 { 50, 4 },
1751 { 60, 5 },
1752 { 70, 6 },
1753 { 80, 7 },
1754 { 92, 8 },
1755 { 103, 9 },
1756 { 115, 10 },
1757 { 138, 12 },
1758 { 162, 15 },
1759 { 180, 18 },
1760 { 185, 19 },
1761 { 189, 20 },
1762 { 195, 22 },
1763 { 199, 24 },
1764 { 201, 25 },
1765 { 202, 26 },
1766 { 203, 27 },
1767 { 205, 28 },
1768 { 208, 30 }
1769};
1770
1771static int mb86a16_read_snr(struct dvb_frontend *fe, u16 *snr)
1772{
1773 struct mb86a16_state *state = fe->demodulator_priv;
1774 int i = 0;
1775 int low_tide = 2, high_tide = 30, q_level;
1776 u8 cn;
1777
1778 *snr = 0;
1779 if (mb86a16_read(state, 0x26, &cn) != 2) {
1780 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
1781 return -EREMOTEIO;
1782 }
1783
1784 for (i = 0; i < ARRAY_SIZE(cnr_tab); i++) {
1785 if (cn < cnr_tab[i].cn_reg) {
1786 *snr = cnr_tab[i].cn_val;
1787 break;
1788 }
1789 }
1790 q_level = (*snr * 100) / (high_tide - low_tide);
1791 dprintk(verbose, MB86A16_ERROR, 1, "SNR (Quality) = [%d dB], Level=%d %%", *snr, q_level);
1792 *snr = (0xffff - 0xff) + *snr;
1793
1794 return 0;
1795}
1796
1797static int mb86a16_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
1798{
1799 u8 dist;
1800 struct mb86a16_state *state = fe->demodulator_priv;
1801
1802 if (mb86a16_read(state, MB86A16_DISTMON, &dist) != 2) {
1803 dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
1804 return -EREMOTEIO;
1805 }
1806 *ucblocks = dist;
1807
1808 return 0;
1809}
1810
1811static enum dvbfe_algo mb86a16_frontend_algo(struct dvb_frontend *fe)
1812{
1813 return DVBFE_ALGO_CUSTOM;
1814}
1815
1816static struct dvb_frontend_ops mb86a16_ops = {
1817 .info = {
1818 .name = "Fujitsu MB86A16 DVB-S",
1819 .type = FE_QPSK,
1820 .frequency_min = 950000,
1821 .frequency_max = 2150000,
1822 .frequency_stepsize = 3000,
1823 .frequency_tolerance = 0,
1824 .symbol_rate_min = 1000000,
1825 .symbol_rate_max = 45000000,
1826 .symbol_rate_tolerance = 500,
1827 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
1828 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
1829 FE_CAN_FEC_7_8 | FE_CAN_QPSK |
1830 FE_CAN_FEC_AUTO
1831 },
1832 .release = mb86a16_release,
1833
1834 .get_frontend_algo = mb86a16_frontend_algo,
1835 .search = mb86a16_search,
1836 .init = mb86a16_init,
1837 .sleep = mb86a16_sleep,
1838 .read_status = mb86a16_read_status,
1839
1840 .read_ber = mb86a16_read_ber,
1841 .read_signal_strength = mb86a16_read_signal_strength,
1842 .read_snr = mb86a16_read_snr,
1843 .read_ucblocks = mb86a16_read_ucblocks,
1844
1845 .diseqc_send_master_cmd = mb86a16_send_diseqc_msg,
1846 .diseqc_send_burst = mb86a16_send_diseqc_burst,
1847 .set_tone = mb86a16_set_tone,
1848};
1849
1850struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config,
1851 struct i2c_adapter *i2c_adap)
1852{
1853 u8 dev_id = 0;
1854 struct mb86a16_state *state = NULL;
1855
1856 state = kmalloc(sizeof(struct mb86a16_state), GFP_KERNEL);
1857 if (state == NULL)
1858 goto error;
1859
1860 state->config = config;
1861 state->i2c_adap = i2c_adap;
1862
1863 mb86a16_read(state, 0x7f, &dev_id);
1864 if (dev_id != 0xfe)
1865 goto error;
1866
1867 memcpy(&state->frontend.ops, &mb86a16_ops, sizeof(struct dvb_frontend_ops));
1868 state->frontend.demodulator_priv = state;
1869 state->frontend.ops.set_voltage = state->config->set_voltage;
1870
1871 return &state->frontend;
1872error:
1873 kfree(state);
1874 return NULL;
1875}
1876EXPORT_SYMBOL(mb86a16_attach);
1877MODULE_LICENSE("GPL");
1878MODULE_AUTHOR("Manu Abraham");
diff --git a/drivers/media/dvb/frontends/mb86a16.h b/drivers/media/dvb/frontends/mb86a16.h
new file mode 100644
index 00000000000..6ea8c376394
--- /dev/null
+++ b/drivers/media/dvb/frontends/mb86a16.h
@@ -0,0 +1,52 @@
1/*
2 Fujitsu MB86A16 DVB-S/DSS DC Receiver driver
3
4 Copyright (C) Manu Abraham (abraham.manu@gmail.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 __MB86A16_H
22#define __MB86A16_H
23
24#include <linux/dvb/frontend.h>
25#include "dvb_frontend.h"
26
27
28struct mb86a16_config {
29 u8 demod_address;
30
31 int (*set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
32};
33
34
35
36#if defined(CONFIG_DVB_MB86A16) || (defined(CONFIG_DVB_MB86A16_MODULE) && defined(MODULE))
37
38extern struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config,
39 struct i2c_adapter *i2c_adap);
40
41#else
42
43static inline struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config,
44 struct i2c_adapter *i2c_adap)
45{
46 printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
47 return NULL;
48}
49
50#endif /* CONFIG_DVB_MB86A16 */
51
52#endif /* __MB86A16_H */
diff --git a/drivers/media/dvb/frontends/mb86a16_priv.h b/drivers/media/dvb/frontends/mb86a16_priv.h
new file mode 100644
index 00000000000..360a35acfe8
--- /dev/null
+++ b/drivers/media/dvb/frontends/mb86a16_priv.h
@@ -0,0 +1,151 @@
1/*
2 Fujitsu MB86A16 DVB-S/DSS DC Receiver driver
3
4 Copyright (C) Manu Abraham (abraham.manu@gmail.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 __MB86A16_PRIV_H
22#define __MB86A16_PRIV_H
23
24#define MB86A16_TSOUT 0x00
25#define MB86A16_TSOUT_HIZSEL (0x01 << 5)
26#define MB86A16_TSOUT_HIZCNTI (0x01 << 4)
27#define MB86A16_TSOUT_MODE (0x01 << 3)
28#define MB86A16_TSOUT_ORDER (0x01 << 2)
29#define MB86A16_TSOUT_ERROR (0x01 << 1)
30#define Mb86A16_TSOUT_EDGE (0x01 << 0)
31
32#define MB86A16_FEC 0x01
33#define MB86A16_FEC_FSYNC (0x01 << 5)
34#define MB86A16_FEC_PCKB8 (0x01 << 4)
35#define MB86A16_FEC_DVDS (0x01 << 3)
36#define MB86A16_FEC_EREN (0x01 << 2)
37#define Mb86A16_FEC_RSEN (0x01 << 1)
38#define MB86A16_FEC_DIEN (0x01 << 0)
39
40#define MB86A16_AGC 0x02
41#define MB86A16_AGC_AGMD (0x01 << 6)
42#define MB86A16_AGC_AGCW (0x0f << 2)
43#define MB86A16_AGC_AGCP (0x01 << 1)
44#define MB86A16_AGC_AGCR (0x01 << 0)
45
46#define MB86A16_SRATE1 0x03
47#define MB86A16_SRATE1_DECI (0x07 << 2)
48#define MB86A16_SRATE1_CSEL (0x01 << 1)
49#define MB86A16_SRATE1_RSEL (0x01 << 0)
50
51#define MB86A16_SRATE2 0x04
52#define MB86A16_SRATE2_STOFSL (0xff << 0)
53
54#define MB86A16_SRATE3 0x05
55#define MB86A16_SRATE2_STOFSH (0xff << 0)
56
57#define MB86A16_VITERBI 0x06
58#define MB86A16_FRAMESYNC 0x07
59#define MB86A16_CRLFILTCOEF1 0x08
60#define MB86A16_CRLFILTCOEF2 0x09
61#define MB86A16_STRFILTCOEF1 0x0a
62#define MB86A16_STRFILTCOEF2 0x0b
63#define MB86A16_RESET 0x0c
64#define MB86A16_STATUS 0x0d
65#define MB86A16_AFCML 0x0e
66#define MB86A16_AFCMH 0x0f
67#define MB86A16_BERMON 0x10
68#define MB86A16_BERTAB 0x11
69#define MB86A16_BERLSB 0x12
70#define MB86A16_BERMID 0x13
71#define MB86A16_BERMSB 0x14
72#define MB86A16_AGCM 0x15
73
74#define MB86A16_DCC1 0x16
75#define MB86A16_DCC1_DISTA (0x01 << 7)
76#define MB86A16_DCC1_PRTY (0x01 << 6)
77#define MB86A16_DCC1_CTOE (0x01 << 5)
78#define MB86A16_DCC1_TBEN (0x01 << 4)
79#define MB86A16_DCC1_TBO (0x01 << 3)
80#define MB86A16_DCC1_NUM (0x07 << 0)
81
82#define MB86A16_DCC2 0x17
83#define MB86A16_DCC2_DCBST (0x01 << 0)
84
85#define MB86A16_DCC3 0x18
86#define MB86A16_DCC3_CODE0 (0xff << 0)
87
88#define MB86A16_DCC4 0x19
89#define MB86A16_DCC4_CODE1 (0xff << 0)
90
91#define MB86A16_DCC5 0x1a
92#define MB86A16_DCC5_CODE2 (0xff << 0)
93
94#define MB86A16_DCC6 0x1b
95#define MB86A16_DCC6_CODE3 (0xff << 0)
96
97#define MB86A16_DCC7 0x1c
98#define MB86A16_DCC7_CODE4 (0xff << 0)
99
100#define MB86A16_DCC8 0x1d
101#define MB86A16_DCC8_CODE5 (0xff << 0)
102
103#define MB86A16_DCCOUT 0x1e
104#define MB86A16_DCCOUT_DISEN (0x01 << 0)
105
106#define MB86A16_TONEOUT1 0x1f
107#define MB86A16_TONE_TDIVL (0xff << 0)
108
109#define MB86A16_TONEOUT2 0x20
110#define MB86A16_TONE_TMD (0x03 << 2)
111#define MB86A16_TONE_TDIVH (0x03 << 0)
112
113#define MB86A16_FREQ1 0x21
114#define MB86A16_FREQ2 0x22
115#define MB86A16_FREQ3 0x23
116#define MB86A16_FREQ4 0x24
117#define MB86A16_FREQSET 0x25
118#define MB86A16_CNM 0x26
119#define MB86A16_PORT0 0x27
120#define MB86A16_PORT1 0x28
121#define MB86A16_DRCFILT 0x29
122#define MB86A16_AFC 0x2a
123#define MB86A16_AFCEXL 0x2b
124#define MB86A16_AFCEXH 0x2c
125#define MB86A16_DAGC 0x2d
126#define MB86A16_SEQMODE 0x32
127#define MB86A16_S0S1T 0x33
128#define MB86A16_S2S3T 0x34
129#define MB86A16_S4S5T 0x35
130#define MB86A16_CNTMR 0x36
131#define MB86A16_SIG1 0x37
132#define MB86A16_SIG2 0x38
133#define MB86A16_VIMAG 0x39
134#define MB86A16_VISET1 0x3a
135#define MB86A16_VISET2 0x3b
136#define MB86A16_VISET3 0x3c
137#define MB86A16_FAGCS1 0x3d
138#define MB86A16_FAGCS2 0x3e
139#define MB86A16_FAGCS3 0x3f
140#define MB86A16_FAGCS4 0x40
141#define MB86A16_FAGCS5 0x41
142#define MB86A16_FAGCS6 0x42
143#define MB86A16_CRM 0x43
144#define MB86A16_STRM 0x44
145#define MB86A16_DAGCML 0x45
146#define MB86A16_DAGCMH 0x46
147#define MB86A16_QPSKTST 0x49
148#define MB86A16_DISTMON 0x52
149#define MB86A16_VERSION 0x7f
150
151#endif /* __MB86A16_PRIV_H */
diff --git a/drivers/media/dvb/frontends/mb86a20s.c b/drivers/media/dvb/frontends/mb86a20s.c
new file mode 100644
index 00000000000..0f867a5055f
--- /dev/null
+++ b/drivers/media/dvb/frontends/mb86a20s.c
@@ -0,0 +1,639 @@
1/*
2 * Fujitu mb86a20s ISDB-T/ISDB-Tsb Module driver
3 *
4 * Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
5 * Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
6 *
7 * FIXME: Need to port to DVB v5.2 API
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation version 2.
12 *
13 * 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 GNU
16 * General Public License for more details.
17 */
18
19#include <linux/kernel.h>
20#include <asm/div64.h>
21
22#include "dvb_frontend.h"
23#include "mb86a20s.h"
24
25static int debug = 1;
26module_param(debug, int, 0644);
27MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
28
29#define rc(args...) do { \
30 printk(KERN_ERR "mb86a20s: " args); \
31} while (0)
32
33#define dprintk(args...) \
34 do { \
35 if (debug) { \
36 printk(KERN_DEBUG "mb86a20s: %s: ", __func__); \
37 printk(args); \
38 } \
39 } while (0)
40
41struct mb86a20s_state {
42 struct i2c_adapter *i2c;
43 const struct mb86a20s_config *config;
44
45 struct dvb_frontend frontend;
46
47 bool need_init;
48};
49
50struct regdata {
51 u8 reg;
52 u8 data;
53};
54
55/*
56 * Initialization sequence: Use whatevere default values that PV SBTVD
57 * does on its initialisation, obtained via USB snoop
58 */
59static struct regdata mb86a20s_init[] = {
60 { 0x70, 0x0f },
61 { 0x70, 0xff },
62 { 0x08, 0x01 },
63 { 0x09, 0x3e },
64 { 0x50, 0xd1 },
65 { 0x51, 0x22 },
66 { 0x39, 0x01 },
67 { 0x71, 0x00 },
68 { 0x28, 0x2a },
69 { 0x29, 0x00 },
70 { 0x2a, 0xff },
71 { 0x2b, 0x80 },
72 { 0x28, 0x20 },
73 { 0x29, 0x33 },
74 { 0x2a, 0xdf },
75 { 0x2b, 0xa9 },
76 { 0x3b, 0x21 },
77 { 0x3c, 0x3a },
78 { 0x01, 0x0d },
79 { 0x04, 0x08 },
80 { 0x05, 0x05 },
81 { 0x04, 0x0e },
82 { 0x05, 0x00 },
83 { 0x04, 0x0f },
84 { 0x05, 0x14 },
85 { 0x04, 0x0b },
86 { 0x05, 0x8c },
87 { 0x04, 0x00 },
88 { 0x05, 0x00 },
89 { 0x04, 0x01 },
90 { 0x05, 0x07 },
91 { 0x04, 0x02 },
92 { 0x05, 0x0f },
93 { 0x04, 0x03 },
94 { 0x05, 0xa0 },
95 { 0x04, 0x09 },
96 { 0x05, 0x00 },
97 { 0x04, 0x0a },
98 { 0x05, 0xff },
99 { 0x04, 0x27 },
100 { 0x05, 0x64 },
101 { 0x04, 0x28 },
102 { 0x05, 0x00 },
103 { 0x04, 0x1e },
104 { 0x05, 0xff },
105 { 0x04, 0x29 },
106 { 0x05, 0x0a },
107 { 0x04, 0x32 },
108 { 0x05, 0x0a },
109 { 0x04, 0x14 },
110 { 0x05, 0x02 },
111 { 0x04, 0x04 },
112 { 0x05, 0x00 },
113 { 0x04, 0x05 },
114 { 0x05, 0x22 },
115 { 0x04, 0x06 },
116 { 0x05, 0x0e },
117 { 0x04, 0x07 },
118 { 0x05, 0xd8 },
119 { 0x04, 0x12 },
120 { 0x05, 0x00 },
121 { 0x04, 0x13 },
122 { 0x05, 0xff },
123 { 0x52, 0x01 },
124 { 0x50, 0xa7 },
125 { 0x51, 0x00 },
126 { 0x50, 0xa8 },
127 { 0x51, 0xff },
128 { 0x50, 0xa9 },
129 { 0x51, 0xff },
130 { 0x50, 0xaa },
131 { 0x51, 0x00 },
132 { 0x50, 0xab },
133 { 0x51, 0xff },
134 { 0x50, 0xac },
135 { 0x51, 0xff },
136 { 0x50, 0xad },
137 { 0x51, 0x00 },
138 { 0x50, 0xae },
139 { 0x51, 0xff },
140 { 0x50, 0xaf },
141 { 0x51, 0xff },
142 { 0x5e, 0x07 },
143 { 0x50, 0xdc },
144 { 0x51, 0x01 },
145 { 0x50, 0xdd },
146 { 0x51, 0xf4 },
147 { 0x50, 0xde },
148 { 0x51, 0x01 },
149 { 0x50, 0xdf },
150 { 0x51, 0xf4 },
151 { 0x50, 0xe0 },
152 { 0x51, 0x01 },
153 { 0x50, 0xe1 },
154 { 0x51, 0xf4 },
155 { 0x50, 0xb0 },
156 { 0x51, 0x07 },
157 { 0x50, 0xb2 },
158 { 0x51, 0xff },
159 { 0x50, 0xb3 },
160 { 0x51, 0xff },
161 { 0x50, 0xb4 },
162 { 0x51, 0xff },
163 { 0x50, 0xb5 },
164 { 0x51, 0xff },
165 { 0x50, 0xb6 },
166 { 0x51, 0xff },
167 { 0x50, 0xb7 },
168 { 0x51, 0xff },
169 { 0x50, 0x50 },
170 { 0x51, 0x02 },
171 { 0x50, 0x51 },
172 { 0x51, 0x04 },
173 { 0x45, 0x04 },
174 { 0x48, 0x04 },
175 { 0x50, 0xd5 },
176 { 0x51, 0x01 }, /* Serial */
177 { 0x50, 0xd6 },
178 { 0x51, 0x1f },
179 { 0x50, 0xd2 },
180 { 0x51, 0x03 },
181 { 0x50, 0xd7 },
182 { 0x51, 0x3f },
183 { 0x1c, 0x01 },
184 { 0x28, 0x06 },
185 { 0x29, 0x00 },
186 { 0x2a, 0x00 },
187 { 0x2b, 0x03 },
188 { 0x28, 0x07 },
189 { 0x29, 0x00 },
190 { 0x2a, 0x00 },
191 { 0x2b, 0x0d },
192 { 0x28, 0x08 },
193 { 0x29, 0x00 },
194 { 0x2a, 0x00 },
195 { 0x2b, 0x02 },
196 { 0x28, 0x09 },
197 { 0x29, 0x00 },
198 { 0x2a, 0x00 },
199 { 0x2b, 0x01 },
200 { 0x28, 0x0a },
201 { 0x29, 0x00 },
202 { 0x2a, 0x00 },
203 { 0x2b, 0x21 },
204 { 0x28, 0x0b },
205 { 0x29, 0x00 },
206 { 0x2a, 0x00 },
207 { 0x2b, 0x29 },
208 { 0x28, 0x0c },
209 { 0x29, 0x00 },
210 { 0x2a, 0x00 },
211 { 0x2b, 0x16 },
212 { 0x28, 0x0d },
213 { 0x29, 0x00 },
214 { 0x2a, 0x00 },
215 { 0x2b, 0x31 },
216 { 0x28, 0x0e },
217 { 0x29, 0x00 },
218 { 0x2a, 0x00 },
219 { 0x2b, 0x0e },
220 { 0x28, 0x0f },
221 { 0x29, 0x00 },
222 { 0x2a, 0x00 },
223 { 0x2b, 0x4e },
224 { 0x28, 0x10 },
225 { 0x29, 0x00 },
226 { 0x2a, 0x00 },
227 { 0x2b, 0x46 },
228 { 0x28, 0x11 },
229 { 0x29, 0x00 },
230 { 0x2a, 0x00 },
231 { 0x2b, 0x0f },
232 { 0x28, 0x12 },
233 { 0x29, 0x00 },
234 { 0x2a, 0x00 },
235 { 0x2b, 0x56 },
236 { 0x28, 0x13 },
237 { 0x29, 0x00 },
238 { 0x2a, 0x00 },
239 { 0x2b, 0x35 },
240 { 0x28, 0x14 },
241 { 0x29, 0x00 },
242 { 0x2a, 0x01 },
243 { 0x2b, 0xbe },
244 { 0x28, 0x15 },
245 { 0x29, 0x00 },
246 { 0x2a, 0x01 },
247 { 0x2b, 0x84 },
248 { 0x28, 0x16 },
249 { 0x29, 0x00 },
250 { 0x2a, 0x03 },
251 { 0x2b, 0xee },
252 { 0x28, 0x17 },
253 { 0x29, 0x00 },
254 { 0x2a, 0x00 },
255 { 0x2b, 0x98 },
256 { 0x28, 0x18 },
257 { 0x29, 0x00 },
258 { 0x2a, 0x00 },
259 { 0x2b, 0x9f },
260 { 0x28, 0x19 },
261 { 0x29, 0x00 },
262 { 0x2a, 0x07 },
263 { 0x2b, 0xb2 },
264 { 0x28, 0x1a },
265 { 0x29, 0x00 },
266 { 0x2a, 0x06 },
267 { 0x2b, 0xc2 },
268 { 0x28, 0x1b },
269 { 0x29, 0x00 },
270 { 0x2a, 0x07 },
271 { 0x2b, 0x4a },
272 { 0x28, 0x1c },
273 { 0x29, 0x00 },
274 { 0x2a, 0x01 },
275 { 0x2b, 0xbc },
276 { 0x28, 0x1d },
277 { 0x29, 0x00 },
278 { 0x2a, 0x04 },
279 { 0x2b, 0xba },
280 { 0x28, 0x1e },
281 { 0x29, 0x00 },
282 { 0x2a, 0x06 },
283 { 0x2b, 0x14 },
284 { 0x50, 0x1e },
285 { 0x51, 0x5d },
286 { 0x50, 0x22 },
287 { 0x51, 0x00 },
288 { 0x50, 0x23 },
289 { 0x51, 0xc8 },
290 { 0x50, 0x24 },
291 { 0x51, 0x00 },
292 { 0x50, 0x25 },
293 { 0x51, 0xf0 },
294 { 0x50, 0x26 },
295 { 0x51, 0x00 },
296 { 0x50, 0x27 },
297 { 0x51, 0xc3 },
298 { 0x50, 0x39 },
299 { 0x51, 0x02 },
300 { 0x50, 0xd5 },
301 { 0x51, 0x01 },
302 { 0xd0, 0x00 },
303};
304
305static struct regdata mb86a20s_reset_reception[] = {
306 { 0x70, 0xf0 },
307 { 0x70, 0xff },
308 { 0x08, 0x01 },
309 { 0x08, 0x00 },
310};
311
312static int mb86a20s_i2c_writereg(struct mb86a20s_state *state,
313 u8 i2c_addr, int reg, int data)
314{
315 u8 buf[] = { reg, data };
316 struct i2c_msg msg = {
317 .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
318 };
319 int rc;
320
321 rc = i2c_transfer(state->i2c, &msg, 1);
322 if (rc != 1) {
323 printk("%s: writereg error (rc == %i, reg == 0x%02x,"
324 " data == 0x%02x)\n", __func__, rc, reg, data);
325 return rc;
326 }
327
328 return 0;
329}
330
331static int mb86a20s_i2c_writeregdata(struct mb86a20s_state *state,
332 u8 i2c_addr, struct regdata *rd, int size)
333{
334 int i, rc;
335
336 for (i = 0; i < size; i++) {
337 rc = mb86a20s_i2c_writereg(state, i2c_addr, rd[i].reg,
338 rd[i].data);
339 if (rc < 0)
340 return rc;
341 }
342 return 0;
343}
344
345static int mb86a20s_i2c_readreg(struct mb86a20s_state *state,
346 u8 i2c_addr, u8 reg)
347{
348 u8 val;
349 int rc;
350 struct i2c_msg msg[] = {
351 { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
352 { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
353 };
354
355 rc = i2c_transfer(state->i2c, msg, 2);
356
357 if (rc != 2) {
358 rc("%s: reg=0x%x (error=%d)\n", __func__, reg, rc);
359 return rc;
360 }
361
362 return val;
363}
364
365#define mb86a20s_readreg(state, reg) \
366 mb86a20s_i2c_readreg(state, state->config->demod_address, reg)
367#define mb86a20s_writereg(state, reg, val) \
368 mb86a20s_i2c_writereg(state, state->config->demod_address, reg, val)
369#define mb86a20s_writeregdata(state, regdata) \
370 mb86a20s_i2c_writeregdata(state, state->config->demod_address, \
371 regdata, ARRAY_SIZE(regdata))
372
373static int mb86a20s_initfe(struct dvb_frontend *fe)
374{
375 struct mb86a20s_state *state = fe->demodulator_priv;
376 int rc;
377 u8 regD5 = 1;
378
379 dprintk("\n");
380
381 if (fe->ops.i2c_gate_ctrl)
382 fe->ops.i2c_gate_ctrl(fe, 0);
383
384 /* Initialize the frontend */
385 rc = mb86a20s_writeregdata(state, mb86a20s_init);
386 if (rc < 0)
387 goto err;
388
389 if (!state->config->is_serial) {
390 regD5 &= ~1;
391
392 rc = mb86a20s_writereg(state, 0x50, 0xd5);
393 if (rc < 0)
394 goto err;
395 rc = mb86a20s_writereg(state, 0x51, regD5);
396 if (rc < 0)
397 goto err;
398 }
399
400 if (fe->ops.i2c_gate_ctrl)
401 fe->ops.i2c_gate_ctrl(fe, 1);
402
403err:
404 if (rc < 0) {
405 state->need_init = true;
406 printk(KERN_INFO "mb86a20s: Init failed. Will try again later\n");
407 } else {
408 state->need_init = false;
409 dprintk("Initialization succeeded.\n");
410 }
411 return rc;
412}
413
414static int mb86a20s_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
415{
416 struct mb86a20s_state *state = fe->demodulator_priv;
417 unsigned rf_max, rf_min, rf;
418 u8 val;
419
420 dprintk("\n");
421
422 if (fe->ops.i2c_gate_ctrl)
423 fe->ops.i2c_gate_ctrl(fe, 0);
424
425 /* Does a binary search to get RF strength */
426 rf_max = 0xfff;
427 rf_min = 0;
428 do {
429 rf = (rf_max + rf_min) / 2;
430 mb86a20s_writereg(state, 0x04, 0x1f);
431 mb86a20s_writereg(state, 0x05, rf >> 8);
432 mb86a20s_writereg(state, 0x04, 0x20);
433 mb86a20s_writereg(state, 0x04, rf);
434
435 val = mb86a20s_readreg(state, 0x02);
436 if (val & 0x08)
437 rf_min = (rf_max + rf_min) / 2;
438 else
439 rf_max = (rf_max + rf_min) / 2;
440 if (rf_max - rf_min < 4) {
441 *strength = (((rf_max + rf_min) / 2) * 65535) / 4095;
442 break;
443 }
444 } while (1);
445
446 dprintk("signal strength = %d\n", *strength);
447
448 if (fe->ops.i2c_gate_ctrl)
449 fe->ops.i2c_gate_ctrl(fe, 1);
450
451 return 0;
452}
453
454static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status)
455{
456 struct mb86a20s_state *state = fe->demodulator_priv;
457 u8 val;
458
459 dprintk("\n");
460 *status = 0;
461
462 if (fe->ops.i2c_gate_ctrl)
463 fe->ops.i2c_gate_ctrl(fe, 0);
464 val = mb86a20s_readreg(state, 0x0a) & 0xf;
465 if (fe->ops.i2c_gate_ctrl)
466 fe->ops.i2c_gate_ctrl(fe, 1);
467
468 if (val >= 2)
469 *status |= FE_HAS_SIGNAL;
470
471 if (val >= 4)
472 *status |= FE_HAS_CARRIER;
473
474 if (val >= 5)
475 *status |= FE_HAS_VITERBI;
476
477 if (val >= 7)
478 *status |= FE_HAS_SYNC;
479
480 if (val >= 8) /* Maybe 9? */
481 *status |= FE_HAS_LOCK;
482
483 dprintk("val = %d, status = 0x%02x\n", val, *status);
484
485 return 0;
486}
487
488static int mb86a20s_set_frontend(struct dvb_frontend *fe,
489 struct dvb_frontend_parameters *p)
490{
491 struct mb86a20s_state *state = fe->demodulator_priv;
492 int rc;
493
494 dprintk("\n");
495
496 if (fe->ops.i2c_gate_ctrl)
497 fe->ops.i2c_gate_ctrl(fe, 1);
498 dprintk("Calling tuner set parameters\n");
499 fe->ops.tuner_ops.set_params(fe, p);
500
501 /*
502 * Make it more reliable: if, for some reason, the initial
503 * device initialization doesn't happen, initialize it when
504 * a SBTVD parameters are adjusted.
505 *
506 * Unfortunately, due to a hard to track bug at tda829x/tda18271,
507 * the agc callback logic is not called during DVB attach time,
508 * causing mb86a20s to not be initialized with Kworld SBTVD.
509 * So, this hack is needed, in order to make Kworld SBTVD to work.
510 */
511 if (state->need_init)
512 mb86a20s_initfe(fe);
513
514 if (fe->ops.i2c_gate_ctrl)
515 fe->ops.i2c_gate_ctrl(fe, 0);
516 rc = mb86a20s_writeregdata(state, mb86a20s_reset_reception);
517 if (fe->ops.i2c_gate_ctrl)
518 fe->ops.i2c_gate_ctrl(fe, 1);
519
520 return rc;
521}
522
523static int mb86a20s_get_frontend(struct dvb_frontend *fe,
524 struct dvb_frontend_parameters *p)
525{
526
527 /* FIXME: For now, it does nothing */
528
529 fe->dtv_property_cache.bandwidth_hz = 6000000;
530 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
531 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
532 fe->dtv_property_cache.isdbt_partial_reception = 0;
533
534 return 0;
535}
536
537static int mb86a20s_tune(struct dvb_frontend *fe,
538 struct dvb_frontend_parameters *params,
539 unsigned int mode_flags,
540 unsigned int *delay,
541 fe_status_t *status)
542{
543 int rc = 0;
544
545 dprintk("\n");
546
547 if (params != NULL)
548 rc = mb86a20s_set_frontend(fe, params);
549
550 if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
551 mb86a20s_read_status(fe, status);
552
553 return rc;
554}
555
556static void mb86a20s_release(struct dvb_frontend *fe)
557{
558 struct mb86a20s_state *state = fe->demodulator_priv;
559
560 dprintk("\n");
561
562 kfree(state);
563}
564
565static struct dvb_frontend_ops mb86a20s_ops;
566
567struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
568 struct i2c_adapter *i2c)
569{
570 u8 rev;
571
572 /* allocate memory for the internal state */
573 struct mb86a20s_state *state =
574 kzalloc(sizeof(struct mb86a20s_state), GFP_KERNEL);
575
576 dprintk("\n");
577 if (state == NULL) {
578 rc("Unable to kzalloc\n");
579 goto error;
580 }
581
582 /* setup the state */
583 state->config = config;
584 state->i2c = i2c;
585
586 /* create dvb_frontend */
587 memcpy(&state->frontend.ops, &mb86a20s_ops,
588 sizeof(struct dvb_frontend_ops));
589 state->frontend.demodulator_priv = state;
590
591 /* Check if it is a mb86a20s frontend */
592 rev = mb86a20s_readreg(state, 0);
593
594 if (rev == 0x13) {
595 printk(KERN_INFO "Detected a Fujitsu mb86a20s frontend\n");
596 } else {
597 printk(KERN_ERR "Frontend revision %d is unknown - aborting.\n",
598 rev);
599 goto error;
600 }
601
602 return &state->frontend;
603
604error:
605 kfree(state);
606 return NULL;
607}
608EXPORT_SYMBOL(mb86a20s_attach);
609
610static struct dvb_frontend_ops mb86a20s_ops = {
611 /* Use dib8000 values per default */
612 .info = {
613 .name = "Fujitsu mb86A20s",
614 .type = FE_OFDM,
615 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_RECOVER |
616 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
617 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
618 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
619 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_QAM_AUTO |
620 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
621 /* Actually, those values depend on the used tuner */
622 .frequency_min = 45000000,
623 .frequency_max = 864000000,
624 .frequency_stepsize = 62500,
625 },
626
627 .release = mb86a20s_release,
628
629 .init = mb86a20s_initfe,
630 .set_frontend = mb86a20s_set_frontend,
631 .get_frontend = mb86a20s_get_frontend,
632 .read_status = mb86a20s_read_status,
633 .read_signal_strength = mb86a20s_read_signal_strength,
634 .tune = mb86a20s_tune,
635};
636
637MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware");
638MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
639MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/mb86a20s.h b/drivers/media/dvb/frontends/mb86a20s.h
new file mode 100644
index 00000000000..bf22e77888b
--- /dev/null
+++ b/drivers/media/dvb/frontends/mb86a20s.h
@@ -0,0 +1,52 @@
1/*
2 * Fujitsu mb86a20s driver
3 *
4 * Copyright (C) 2010 Mauro Carvalho Chehab <mchehab@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15
16#ifndef MB86A20S_H
17#define MB86A20S_H
18
19#include <linux/dvb/frontend.h>
20
21/**
22 * struct mb86a20s_config - Define the per-device attributes of the frontend
23 *
24 * @demod_address: the demodulator's i2c address
25 */
26
27struct mb86a20s_config {
28 u8 demod_address;
29 bool is_serial;
30};
31
32#if defined(CONFIG_DVB_MB86A20S) || (defined(CONFIG_DVB_MB86A20S_MODULE) \
33 && defined(MODULE))
34extern struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
35 struct i2c_adapter *i2c);
36extern struct i2c_adapter *mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *);
37#else
38static inline struct dvb_frontend *mb86a20s_attach(
39 const struct mb86a20s_config *config, struct i2c_adapter *i2c)
40{
41 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
42 return NULL;
43}
44static struct i2c_adapter *
45 mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *fe)
46{
47 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
48 return NULL;
49}
50#endif
51
52#endif /* MB86A20S */
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c
new file mode 100644
index 00000000000..83e6f1a1b70
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt312.c
@@ -0,0 +1,840 @@
1/*
2 Driver for Zarlink VP310/MT312/ZL10313 Satellite Channel Decoder
3
4 Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
5 Copyright (C) 2008 Matthias Schwarzott <zzam@gentoo.org>
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
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 References:
23 http://products.zarlink.com/product_profiles/MT312.htm
24 http://products.zarlink.com/product_profiles/SL1935.htm
25*/
26
27#include <linux/delay.h>
28#include <linux/errno.h>
29#include <linux/init.h>
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/string.h>
33#include <linux/slab.h>
34
35#include "dvb_frontend.h"
36#include "mt312_priv.h"
37#include "mt312.h"
38
39
40struct mt312_state {
41 struct i2c_adapter *i2c;
42 /* configuration settings */
43 const struct mt312_config *config;
44 struct dvb_frontend frontend;
45
46 u8 id;
47 unsigned long xtal;
48 u8 freq_mult;
49};
50
51static int debug;
52#define dprintk(args...) \
53 do { \
54 if (debug) \
55 printk(KERN_DEBUG "mt312: " args); \
56 } while (0)
57
58#define MT312_PLL_CLK 10000000UL /* 10 MHz */
59#define MT312_PLL_CLK_10_111 10111000UL /* 10.111 MHz */
60
61static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
62 u8 *buf, const size_t count)
63{
64 int ret;
65 struct i2c_msg msg[2];
66 u8 regbuf[1] = { reg };
67
68 msg[0].addr = state->config->demod_address;
69 msg[0].flags = 0;
70 msg[0].buf = regbuf;
71 msg[0].len = 1;
72 msg[1].addr = state->config->demod_address;
73 msg[1].flags = I2C_M_RD;
74 msg[1].buf = buf;
75 msg[1].len = count;
76
77 ret = i2c_transfer(state->i2c, msg, 2);
78
79 if (ret != 2) {
80 printk(KERN_DEBUG "%s: ret == %d\n", __func__, ret);
81 return -EREMOTEIO;
82 }
83
84 if (debug) {
85 int i;
86 dprintk("R(%d):", reg & 0x7f);
87 for (i = 0; i < count; i++)
88 printk(KERN_CONT " %02x", buf[i]);
89 printk("\n");
90 }
91
92 return 0;
93}
94
95static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg,
96 const u8 *src, const size_t count)
97{
98 int ret;
99 u8 buf[count + 1];
100 struct i2c_msg msg;
101
102 if (debug) {
103 int i;
104 dprintk("W(%d):", reg & 0x7f);
105 for (i = 0; i < count; i++)
106 printk(KERN_CONT " %02x", src[i]);
107 printk("\n");
108 }
109
110 buf[0] = reg;
111 memcpy(&buf[1], src, count);
112
113 msg.addr = state->config->demod_address;
114 msg.flags = 0;
115 msg.buf = buf;
116 msg.len = count + 1;
117
118 ret = i2c_transfer(state->i2c, &msg, 1);
119
120 if (ret != 1) {
121 dprintk("%s: ret == %d\n", __func__, ret);
122 return -EREMOTEIO;
123 }
124
125 return 0;
126}
127
128static inline int mt312_readreg(struct mt312_state *state,
129 const enum mt312_reg_addr reg, u8 *val)
130{
131 return mt312_read(state, reg, val, 1);
132}
133
134static inline int mt312_writereg(struct mt312_state *state,
135 const enum mt312_reg_addr reg, const u8 val)
136{
137 return mt312_write(state, reg, &val, 1);
138}
139
140static inline u32 mt312_div(u32 a, u32 b)
141{
142 return (a + (b / 2)) / b;
143}
144
145static int mt312_reset(struct mt312_state *state, const u8 full)
146{
147 return mt312_writereg(state, RESET, full ? 0x80 : 0x40);
148}
149
150static int mt312_get_inversion(struct mt312_state *state,
151 fe_spectral_inversion_t *i)
152{
153 int ret;
154 u8 vit_mode;
155
156 ret = mt312_readreg(state, VIT_MODE, &vit_mode);
157 if (ret < 0)
158 return ret;
159
160 if (vit_mode & 0x80) /* auto inversion was used */
161 *i = (vit_mode & 0x40) ? INVERSION_ON : INVERSION_OFF;
162
163 return 0;
164}
165
166static int mt312_get_symbol_rate(struct mt312_state *state, u32 *sr)
167{
168 int ret;
169 u8 sym_rate_h;
170 u8 dec_ratio;
171 u16 sym_rat_op;
172 u16 monitor;
173 u8 buf[2];
174
175 ret = mt312_readreg(state, SYM_RATE_H, &sym_rate_h);
176 if (ret < 0)
177 return ret;
178
179 if (sym_rate_h & 0x80) {
180 /* symbol rate search was used */
181 ret = mt312_writereg(state, MON_CTRL, 0x03);
182 if (ret < 0)
183 return ret;
184
185 ret = mt312_read(state, MONITOR_H, buf, sizeof(buf));
186 if (ret < 0)
187 return ret;
188
189 monitor = (buf[0] << 8) | buf[1];
190
191 dprintk("sr(auto) = %u\n",
192 mt312_div(monitor * 15625, 4));
193 } else {
194 ret = mt312_writereg(state, MON_CTRL, 0x05);
195 if (ret < 0)
196 return ret;
197
198 ret = mt312_read(state, MONITOR_H, buf, sizeof(buf));
199 if (ret < 0)
200 return ret;
201
202 dec_ratio = ((buf[0] >> 5) & 0x07) * 32;
203
204 ret = mt312_read(state, SYM_RAT_OP_H, buf, sizeof(buf));
205 if (ret < 0)
206 return ret;
207
208 sym_rat_op = (buf[0] << 8) | buf[1];
209
210 dprintk("sym_rat_op=%d dec_ratio=%d\n",
211 sym_rat_op, dec_ratio);
212 dprintk("*sr(manual) = %lu\n",
213 (((state->xtal * 8192) / (sym_rat_op + 8192)) *
214 2) - dec_ratio);
215 }
216
217 return 0;
218}
219
220static int mt312_get_code_rate(struct mt312_state *state, fe_code_rate_t *cr)
221{
222 const fe_code_rate_t fec_tab[8] =
223 { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_6_7, FEC_7_8,
224 FEC_AUTO, FEC_AUTO };
225
226 int ret;
227 u8 fec_status;
228
229 ret = mt312_readreg(state, FEC_STATUS, &fec_status);
230 if (ret < 0)
231 return ret;
232
233 *cr = fec_tab[(fec_status >> 4) & 0x07];
234
235 return 0;
236}
237
238static int mt312_initfe(struct dvb_frontend *fe)
239{
240 struct mt312_state *state = fe->demodulator_priv;
241 int ret;
242 u8 buf[2];
243
244 /* wake up */
245 ret = mt312_writereg(state, CONFIG,
246 (state->freq_mult == 6 ? 0x88 : 0x8c));
247 if (ret < 0)
248 return ret;
249
250 /* wait at least 150 usec */
251 udelay(150);
252
253 /* full reset */
254 ret = mt312_reset(state, 1);
255 if (ret < 0)
256 return ret;
257
258/* Per datasheet, write correct values. 09/28/03 ACCJr.
259 * If we don't do this, we won't get FE_HAS_VITERBI in the VP310. */
260 {
261 u8 buf_def[8] = { 0x14, 0x12, 0x03, 0x02,
262 0x01, 0x00, 0x00, 0x00 };
263
264 ret = mt312_write(state, VIT_SETUP, buf_def, sizeof(buf_def));
265 if (ret < 0)
266 return ret;
267 }
268
269 switch (state->id) {
270 case ID_ZL10313:
271 /* enable ADC */
272 ret = mt312_writereg(state, GPP_CTRL, 0x80);
273 if (ret < 0)
274 return ret;
275
276 /* configure ZL10313 for optimal ADC performance */
277 buf[0] = 0x80;
278 buf[1] = 0xB0;
279 ret = mt312_write(state, HW_CTRL, buf, 2);
280 if (ret < 0)
281 return ret;
282
283 /* enable MPEG output and ADCs */
284 ret = mt312_writereg(state, HW_CTRL, 0x00);
285 if (ret < 0)
286 return ret;
287
288 ret = mt312_writereg(state, MPEG_CTRL, 0x00);
289 if (ret < 0)
290 return ret;
291
292 break;
293 }
294
295 /* SYS_CLK */
296 buf[0] = mt312_div(state->xtal * state->freq_mult * 2, 1000000);
297
298 /* DISEQC_RATIO */
299 buf[1] = mt312_div(state->xtal, 22000 * 4);
300
301 ret = mt312_write(state, SYS_CLK, buf, sizeof(buf));
302 if (ret < 0)
303 return ret;
304
305 ret = mt312_writereg(state, SNR_THS_HIGH, 0x32);
306 if (ret < 0)
307 return ret;
308
309 /* different MOCLK polarity */
310 switch (state->id) {
311 case ID_ZL10313:
312 buf[0] = 0x33;
313 break;
314 default:
315 buf[0] = 0x53;
316 break;
317 }
318
319 ret = mt312_writereg(state, OP_CTRL, buf[0]);
320 if (ret < 0)
321 return ret;
322
323 /* TS_SW_LIM */
324 buf[0] = 0x8c;
325 buf[1] = 0x98;
326
327 ret = mt312_write(state, TS_SW_LIM_L, buf, sizeof(buf));
328 if (ret < 0)
329 return ret;
330
331 ret = mt312_writereg(state, CS_SW_LIM, 0x69);
332 if (ret < 0)
333 return ret;
334
335 return 0;
336}
337
338static int mt312_send_master_cmd(struct dvb_frontend *fe,
339 struct dvb_diseqc_master_cmd *c)
340{
341 struct mt312_state *state = fe->demodulator_priv;
342 int ret;
343 u8 diseqc_mode;
344
345 if ((c->msg_len == 0) || (c->msg_len > sizeof(c->msg)))
346 return -EINVAL;
347
348 ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode);
349 if (ret < 0)
350 return ret;
351
352 ret = mt312_write(state, (0x80 | DISEQC_INSTR), c->msg, c->msg_len);
353 if (ret < 0)
354 return ret;
355
356 ret = mt312_writereg(state, DISEQC_MODE,
357 (diseqc_mode & 0x40) | ((c->msg_len - 1) << 3)
358 | 0x04);
359 if (ret < 0)
360 return ret;
361
362 /* is there a better way to wait for message to be transmitted */
363 msleep(100);
364
365 /* set DISEQC_MODE[2:0] to zero if a return message is expected */
366 if (c->msg[0] & 0x02) {
367 ret = mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40));
368 if (ret < 0)
369 return ret;
370 }
371
372 return 0;
373}
374
375static int mt312_send_burst(struct dvb_frontend *fe, const fe_sec_mini_cmd_t c)
376{
377 struct mt312_state *state = fe->demodulator_priv;
378 const u8 mini_tab[2] = { 0x02, 0x03 };
379
380 int ret;
381 u8 diseqc_mode;
382
383 if (c > SEC_MINI_B)
384 return -EINVAL;
385
386 ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode);
387 if (ret < 0)
388 return ret;
389
390 ret = mt312_writereg(state, DISEQC_MODE,
391 (diseqc_mode & 0x40) | mini_tab[c]);
392 if (ret < 0)
393 return ret;
394
395 return 0;
396}
397
398static int mt312_set_tone(struct dvb_frontend *fe, const fe_sec_tone_mode_t t)
399{
400 struct mt312_state *state = fe->demodulator_priv;
401 const u8 tone_tab[2] = { 0x01, 0x00 };
402
403 int ret;
404 u8 diseqc_mode;
405
406 if (t > SEC_TONE_OFF)
407 return -EINVAL;
408
409 ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode);
410 if (ret < 0)
411 return ret;
412
413 ret = mt312_writereg(state, DISEQC_MODE,
414 (diseqc_mode & 0x40) | tone_tab[t]);
415 if (ret < 0)
416 return ret;
417
418 return 0;
419}
420
421static int mt312_set_voltage(struct dvb_frontend *fe, const fe_sec_voltage_t v)
422{
423 struct mt312_state *state = fe->demodulator_priv;
424 const u8 volt_tab[3] = { 0x00, 0x40, 0x00 };
425 u8 val;
426
427 if (v > SEC_VOLTAGE_OFF)
428 return -EINVAL;
429
430 val = volt_tab[v];
431 if (state->config->voltage_inverted)
432 val ^= 0x40;
433
434 return mt312_writereg(state, DISEQC_MODE, val);
435}
436
437static int mt312_read_status(struct dvb_frontend *fe, fe_status_t *s)
438{
439 struct mt312_state *state = fe->demodulator_priv;
440 int ret;
441 u8 status[3];
442
443 *s = 0;
444
445 ret = mt312_read(state, QPSK_STAT_H, status, sizeof(status));
446 if (ret < 0)
447 return ret;
448
449 dprintk("QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x,"
450 " FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]);
451
452 if (status[0] & 0xc0)
453 *s |= FE_HAS_SIGNAL; /* signal noise ratio */
454 if (status[0] & 0x04)
455 *s |= FE_HAS_CARRIER; /* qpsk carrier lock */
456 if (status[2] & 0x02)
457 *s |= FE_HAS_VITERBI; /* viterbi lock */
458 if (status[2] & 0x04)
459 *s |= FE_HAS_SYNC; /* byte align lock */
460 if (status[0] & 0x01)
461 *s |= FE_HAS_LOCK; /* qpsk lock */
462
463 return 0;
464}
465
466static int mt312_read_ber(struct dvb_frontend *fe, u32 *ber)
467{
468 struct mt312_state *state = fe->demodulator_priv;
469 int ret;
470 u8 buf[3];
471
472 ret = mt312_read(state, RS_BERCNT_H, buf, 3);
473 if (ret < 0)
474 return ret;
475
476 *ber = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) * 64;
477
478 return 0;
479}
480
481static int mt312_read_signal_strength(struct dvb_frontend *fe,
482 u16 *signal_strength)
483{
484 struct mt312_state *state = fe->demodulator_priv;
485 int ret;
486 u8 buf[3];
487 u16 agc;
488 s16 err_db;
489
490 ret = mt312_read(state, AGC_H, buf, sizeof(buf));
491 if (ret < 0)
492 return ret;
493
494 agc = (buf[0] << 6) | (buf[1] >> 2);
495 err_db = (s16) (((buf[1] & 0x03) << 14) | buf[2] << 6) >> 6;
496
497 *signal_strength = agc;
498
499 dprintk("agc=%08x err_db=%hd\n", agc, err_db);
500
501 return 0;
502}
503
504static int mt312_read_snr(struct dvb_frontend *fe, u16 *snr)
505{
506 struct mt312_state *state = fe->demodulator_priv;
507 int ret;
508 u8 buf[2];
509
510 ret = mt312_read(state, M_SNR_H, buf, sizeof(buf));
511 if (ret < 0)
512 return ret;
513
514 *snr = 0xFFFF - ((((buf[0] & 0x7f) << 8) | buf[1]) << 1);
515
516 return 0;
517}
518
519static int mt312_read_ucblocks(struct dvb_frontend *fe, u32 *ubc)
520{
521 struct mt312_state *state = fe->demodulator_priv;
522 int ret;
523 u8 buf[2];
524
525 ret = mt312_read(state, RS_UBC_H, buf, sizeof(buf));
526 if (ret < 0)
527 return ret;
528
529 *ubc = (buf[0] << 8) | buf[1];
530
531 return 0;
532}
533
534static int mt312_set_frontend(struct dvb_frontend *fe,
535 struct dvb_frontend_parameters *p)
536{
537 struct mt312_state *state = fe->demodulator_priv;
538 int ret;
539 u8 buf[5], config_val;
540 u16 sr;
541
542 const u8 fec_tab[10] =
543 { 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, 0x20, 0x3f, 0x3f };
544 const u8 inv_tab[3] = { 0x00, 0x40, 0x80 };
545
546 dprintk("%s: Freq %d\n", __func__, p->frequency);
547
548 if ((p->frequency < fe->ops.info.frequency_min)
549 || (p->frequency > fe->ops.info.frequency_max))
550 return -EINVAL;
551
552 if ((p->inversion < INVERSION_OFF)
553 || (p->inversion > INVERSION_ON))
554 return -EINVAL;
555
556 if ((p->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min)
557 || (p->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max))
558 return -EINVAL;
559
560 if ((p->u.qpsk.fec_inner < FEC_NONE)
561 || (p->u.qpsk.fec_inner > FEC_AUTO))
562 return -EINVAL;
563
564 if ((p->u.qpsk.fec_inner == FEC_4_5)
565 || (p->u.qpsk.fec_inner == FEC_8_9))
566 return -EINVAL;
567
568 switch (state->id) {
569 case ID_VP310:
570 /* For now we will do this only for the VP310.
571 * It should be better for the mt312 as well,
572 * but tuning will be slower. ACCJr 09/29/03
573 */
574 ret = mt312_readreg(state, CONFIG, &config_val);
575 if (ret < 0)
576 return ret;
577 if (p->u.qpsk.symbol_rate >= 30000000) {
578 /* Note that 30MS/s should use 90MHz */
579 if (state->freq_mult == 6) {
580 /* We are running 60MHz */
581 state->freq_mult = 9;
582 ret = mt312_initfe(fe);
583 if (ret < 0)
584 return ret;
585 }
586 } else {
587 if (state->freq_mult == 9) {
588 /* We are running 90MHz */
589 state->freq_mult = 6;
590 ret = mt312_initfe(fe);
591 if (ret < 0)
592 return ret;
593 }
594 }
595 break;
596
597 case ID_MT312:
598 case ID_ZL10313:
599 break;
600
601 default:
602 return -EINVAL;
603 }
604
605 if (fe->ops.tuner_ops.set_params) {
606 fe->ops.tuner_ops.set_params(fe, p);
607 if (fe->ops.i2c_gate_ctrl)
608 fe->ops.i2c_gate_ctrl(fe, 0);
609 }
610
611 /* sr = (u16)(sr * 256.0 / 1000000.0) */
612 sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625);
613
614 /* SYM_RATE */
615 buf[0] = (sr >> 8) & 0x3f;
616 buf[1] = (sr >> 0) & 0xff;
617
618 /* VIT_MODE */
619 buf[2] = inv_tab[p->inversion] | fec_tab[p->u.qpsk.fec_inner];
620
621 /* QPSK_CTRL */
622 buf[3] = 0x40; /* swap I and Q before QPSK demodulation */
623
624 if (p->u.qpsk.symbol_rate < 10000000)
625 buf[3] |= 0x04; /* use afc mode */
626
627 /* GO */
628 buf[4] = 0x01;
629
630 ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf));
631 if (ret < 0)
632 return ret;
633
634 mt312_reset(state, 0);
635
636 return 0;
637}
638
639static int mt312_get_frontend(struct dvb_frontend *fe,
640 struct dvb_frontend_parameters *p)
641{
642 struct mt312_state *state = fe->demodulator_priv;
643 int ret;
644
645 ret = mt312_get_inversion(state, &p->inversion);
646 if (ret < 0)
647 return ret;
648
649 ret = mt312_get_symbol_rate(state, &p->u.qpsk.symbol_rate);
650 if (ret < 0)
651 return ret;
652
653 ret = mt312_get_code_rate(state, &p->u.qpsk.fec_inner);
654 if (ret < 0)
655 return ret;
656
657 return 0;
658}
659
660static int mt312_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
661{
662 struct mt312_state *state = fe->demodulator_priv;
663
664 u8 val = 0x00;
665 int ret;
666
667 switch (state->id) {
668 case ID_ZL10313:
669 ret = mt312_readreg(state, GPP_CTRL, &val);
670 if (ret < 0)
671 goto error;
672
673 /* preserve this bit to not accidentally shutdown ADC */
674 val &= 0x80;
675 break;
676 }
677
678 if (enable)
679 val |= 0x40;
680 else
681 val &= ~0x40;
682
683 ret = mt312_writereg(state, GPP_CTRL, val);
684
685error:
686 return ret;
687}
688
689static int mt312_sleep(struct dvb_frontend *fe)
690{
691 struct mt312_state *state = fe->demodulator_priv;
692 int ret;
693 u8 config;
694
695 /* reset all registers to defaults */
696 ret = mt312_reset(state, 1);
697 if (ret < 0)
698 return ret;
699
700 if (state->id == ID_ZL10313) {
701 /* reset ADC */
702 ret = mt312_writereg(state, GPP_CTRL, 0x00);
703 if (ret < 0)
704 return ret;
705
706 /* full shutdown of ADCs, mpeg bus tristated */
707 ret = mt312_writereg(state, HW_CTRL, 0x0d);
708 if (ret < 0)
709 return ret;
710 }
711
712 ret = mt312_readreg(state, CONFIG, &config);
713 if (ret < 0)
714 return ret;
715
716 /* enter standby */
717 ret = mt312_writereg(state, CONFIG, config & 0x7f);
718 if (ret < 0)
719 return ret;
720
721 return 0;
722}
723
724static int mt312_get_tune_settings(struct dvb_frontend *fe,
725 struct dvb_frontend_tune_settings *fesettings)
726{
727 fesettings->min_delay_ms = 50;
728 fesettings->step_size = 0;
729 fesettings->max_drift = 0;
730 return 0;
731}
732
733static void mt312_release(struct dvb_frontend *fe)
734{
735 struct mt312_state *state = fe->demodulator_priv;
736 kfree(state);
737}
738
739#define MT312_SYS_CLK 90000000UL /* 90 MHz */
740static struct dvb_frontend_ops mt312_ops = {
741
742 .info = {
743 .name = "Zarlink ???? DVB-S",
744 .type = FE_QPSK,
745 .frequency_min = 950000,
746 .frequency_max = 2150000,
747 /* FIXME: adjust freq to real used xtal */
748 .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128,
749 .symbol_rate_min = MT312_SYS_CLK / 128, /* FIXME as above */
750 .symbol_rate_max = MT312_SYS_CLK / 2,
751 .caps =
752 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
753 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
754 FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_MUTE_TS |
755 FE_CAN_RECOVER
756 },
757
758 .release = mt312_release,
759
760 .init = mt312_initfe,
761 .sleep = mt312_sleep,
762 .i2c_gate_ctrl = mt312_i2c_gate_ctrl,
763
764 .set_frontend = mt312_set_frontend,
765 .get_frontend = mt312_get_frontend,
766 .get_tune_settings = mt312_get_tune_settings,
767
768 .read_status = mt312_read_status,
769 .read_ber = mt312_read_ber,
770 .read_signal_strength = mt312_read_signal_strength,
771 .read_snr = mt312_read_snr,
772 .read_ucblocks = mt312_read_ucblocks,
773
774 .diseqc_send_master_cmd = mt312_send_master_cmd,
775 .diseqc_send_burst = mt312_send_burst,
776 .set_tone = mt312_set_tone,
777 .set_voltage = mt312_set_voltage,
778};
779
780struct dvb_frontend *mt312_attach(const struct mt312_config *config,
781 struct i2c_adapter *i2c)
782{
783 struct mt312_state *state = NULL;
784
785 /* allocate memory for the internal state */
786 state = kzalloc(sizeof(struct mt312_state), GFP_KERNEL);
787 if (state == NULL)
788 goto error;
789
790 /* setup the state */
791 state->config = config;
792 state->i2c = i2c;
793
794 /* check if the demod is there */
795 if (mt312_readreg(state, ID, &state->id) < 0)
796 goto error;
797
798 /* create dvb_frontend */
799 memcpy(&state->frontend.ops, &mt312_ops,
800 sizeof(struct dvb_frontend_ops));
801 state->frontend.demodulator_priv = state;
802
803 switch (state->id) {
804 case ID_VP310:
805 strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S");
806 state->xtal = MT312_PLL_CLK;
807 state->freq_mult = 9;
808 break;
809 case ID_MT312:
810 strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S");
811 state->xtal = MT312_PLL_CLK;
812 state->freq_mult = 6;
813 break;
814 case ID_ZL10313:
815 strcpy(state->frontend.ops.info.name, "Zarlink ZL10313 DVB-S");
816 state->xtal = MT312_PLL_CLK_10_111;
817 state->freq_mult = 9;
818 break;
819 default:
820 printk(KERN_WARNING "Only Zarlink VP310/MT312/ZL10313"
821 " are supported chips.\n");
822 goto error;
823 }
824
825 return &state->frontend;
826
827error:
828 kfree(state);
829 return NULL;
830}
831EXPORT_SYMBOL(mt312_attach);
832
833module_param(debug, int, 0644);
834MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
835
836MODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver");
837MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
838MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
839MODULE_LICENSE("GPL");
840
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h
new file mode 100644
index 00000000000..29e3bb5496b
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt312.h
@@ -0,0 +1,51 @@
1/*
2 Driver for Zarlink MT312 Satellite Channel Decoder
3
4 Copyright (C) 2003 Andreas Oberritter <obi@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 as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 References:
22 http://products.zarlink.com/product_profiles/MT312.htm
23 http://products.zarlink.com/product_profiles/SL1935.htm
24*/
25
26#ifndef MT312_H
27#define MT312_H
28
29#include <linux/dvb/frontend.h>
30
31struct mt312_config {
32 /* the demodulator's i2c address */
33 u8 demod_address;
34
35 /* inverted voltage setting */
36 unsigned int voltage_inverted:1;
37};
38
39#if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE))
40struct dvb_frontend *mt312_attach(const struct mt312_config *config,
41 struct i2c_adapter *i2c);
42#else
43static inline struct dvb_frontend *mt312_attach(
44 const struct mt312_config *config, struct i2c_adapter *i2c)
45{
46 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
47 return NULL;
48}
49#endif /* CONFIG_DVB_MT312 */
50
51#endif /* MT312_H */
diff --git a/drivers/media/dvb/frontends/mt312_priv.h b/drivers/media/dvb/frontends/mt312_priv.h
new file mode 100644
index 00000000000..a3959f94d63
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt312_priv.h
@@ -0,0 +1,165 @@
1/*
2 Driver for Zarlink MT312 QPSK Frontend
3
4 Copyright (C) 2003 Andreas Oberritter <obi@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 as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef _DVB_FRONTENDS_MT312_PRIV
24#define _DVB_FRONTENDS_MT312_PRIV
25
26enum mt312_reg_addr {
27 QPSK_INT_H = 0,
28 QPSK_INT_M = 1,
29 QPSK_INT_L = 2,
30 FEC_INT = 3,
31 QPSK_STAT_H = 4,
32 QPSK_STAT_L = 5,
33 FEC_STATUS = 6,
34 LNB_FREQ_H = 7,
35 LNB_FREQ_L = 8,
36 M_SNR_H = 9,
37 M_SNR_L = 10,
38 VIT_ERRCNT_H = 11,
39 VIT_ERRCNT_M = 12,
40 VIT_ERRCNT_L = 13,
41 RS_BERCNT_H = 14,
42 RS_BERCNT_M = 15,
43 RS_BERCNT_L = 16,
44 RS_UBC_H = 17,
45 RS_UBC_L = 18,
46 SIG_LEVEL = 19,
47 GPP_CTRL = 20,
48 RESET = 21,
49 DISEQC_MODE = 22,
50 SYM_RATE_H = 23,
51 SYM_RATE_L = 24,
52 VIT_MODE = 25,
53 QPSK_CTRL = 26,
54 GO = 27,
55 IE_QPSK_H = 28,
56 IE_QPSK_M = 29,
57 IE_QPSK_L = 30,
58 IE_FEC = 31,
59 QPSK_STAT_EN = 32,
60 FEC_STAT_EN = 33,
61 SYS_CLK = 34,
62 DISEQC_RATIO = 35,
63 DISEQC_INSTR = 36,
64 FR_LIM = 37,
65 FR_OFF = 38,
66 AGC_CTRL = 39,
67 AGC_INIT = 40,
68 AGC_REF = 41,
69 AGC_MAX = 42,
70 AGC_MIN = 43,
71 AGC_LK_TH = 44,
72 TS_AGC_LK_TH = 45,
73 AGC_PWR_SET = 46,
74 QPSK_MISC = 47,
75 SNR_THS_LOW = 48,
76 SNR_THS_HIGH = 49,
77 TS_SW_RATE = 50,
78 TS_SW_LIM_L = 51,
79 TS_SW_LIM_H = 52,
80 CS_SW_RATE_1 = 53,
81 CS_SW_RATE_2 = 54,
82 CS_SW_RATE_3 = 55,
83 CS_SW_RATE_4 = 56,
84 CS_SW_LIM = 57,
85 TS_LPK = 58,
86 TS_LPK_M = 59,
87 TS_LPK_L = 60,
88 CS_KPROP_H = 61,
89 CS_KPROP_L = 62,
90 CS_KINT_H = 63,
91 CS_KINT_L = 64,
92 QPSK_SCALE = 65,
93 TLD_OUTCLK_TH = 66,
94 TLD_INCLK_TH = 67,
95 FLD_TH = 68,
96 PLD_OUTLK3 = 69,
97 PLD_OUTLK2 = 70,
98 PLD_OUTLK1 = 71,
99 PLD_OUTLK0 = 72,
100 PLD_INLK3 = 73,
101 PLD_INLK2 = 74,
102 PLD_INLK1 = 75,
103 PLD_INLK0 = 76,
104 PLD_ACC_TIME = 77,
105 SWEEP_PAR = 78,
106 STARTUP_TIME = 79,
107 LOSSLOCK_TH = 80,
108 FEC_LOCK_TM = 81,
109 LOSSLOCK_TM = 82,
110 VIT_ERRPER_H = 83,
111 VIT_ERRPER_M = 84,
112 VIT_ERRPER_L = 85,
113 HW_CTRL = 84, /* ZL10313 only */
114 MPEG_CTRL = 85, /* ZL10313 only */
115 VIT_SETUP = 86,
116 VIT_REF0 = 87,
117 VIT_REF1 = 88,
118 VIT_REF2 = 89,
119 VIT_REF3 = 90,
120 VIT_REF4 = 91,
121 VIT_REF5 = 92,
122 VIT_REF6 = 93,
123 VIT_MAXERR = 94,
124 BA_SETUPT = 95,
125 OP_CTRL = 96,
126 FEC_SETUP = 97,
127 PROG_SYNC = 98,
128 AFC_SEAR_TH = 99,
129 CSACC_DIF_TH = 100,
130 QPSK_LK_CT = 101,
131 QPSK_ST_CT = 102,
132 MON_CTRL = 103,
133 QPSK_RESET = 104,
134 QPSK_TST_CT = 105,
135 QPSK_TST_ST = 106,
136 TEST_R = 107,
137 AGC_H = 108,
138 AGC_M = 109,
139 AGC_L = 110,
140 FREQ_ERR1_H = 111,
141 FREQ_ERR1_M = 112,
142 FREQ_ERR1_L = 113,
143 FREQ_ERR2_H = 114,
144 FREQ_ERR2_L = 115,
145 SYM_RAT_OP_H = 116,
146 SYM_RAT_OP_L = 117,
147 DESEQC2_INT = 118,
148 DISEQC2_STAT = 119,
149 DISEQC2_FIFO = 120,
150 DISEQC2_CTRL1 = 121,
151 DISEQC2_CTRL2 = 122,
152 MONITOR_H = 123,
153 MONITOR_L = 124,
154 TEST_MODE = 125,
155 ID = 126,
156 CONFIG = 127
157};
158
159enum mt312_model_id {
160 ID_VP310 = 1,
161 ID_MT312 = 3,
162 ID_ZL10313 = 5,
163};
164
165#endif /* DVB_FRONTENDS_MT312_PRIV */
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
new file mode 100644
index 00000000000..319672f8e1a
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt352.c
@@ -0,0 +1,613 @@
1/*
2 * Driver for Zarlink DVB-T MT352 demodulator
3 *
4 * Written by Holger Waechtler <holger@qanu.de>
5 * and Daniel Mack <daniel@qanu.de>
6 *
7 * AVerMedia AVerTV DVB-T 771 support by
8 * Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * Support for Samsung TDTC9251DH01C(M) tuner
11 * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
12 * Amauri Celani <acelani@essegi.net>
13 *
14 * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
15 * Christopher Pascoe <c.pascoe@itee.uq.edu.au>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 *
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
31 */
32
33#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/init.h>
36#include <linux/delay.h>
37#include <linux/string.h>
38#include <linux/slab.h>
39
40#include "dvb_frontend.h"
41#include "mt352_priv.h"
42#include "mt352.h"
43
44struct mt352_state {
45 struct i2c_adapter* i2c;
46 struct dvb_frontend frontend;
47
48 /* configuration settings */
49 struct mt352_config config;
50};
51
52static int debug;
53#define dprintk(args...) \
54 do { \
55 if (debug) printk(KERN_DEBUG "mt352: " args); \
56 } while (0)
57
58static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
59{
60 struct mt352_state* state = fe->demodulator_priv;
61 u8 buf[2] = { reg, val };
62 struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0,
63 .buf = buf, .len = 2 };
64 int err = i2c_transfer(state->i2c, &msg, 1);
65 if (err != 1) {
66 printk("mt352_write() to reg %x failed (err = %d)!\n", reg, err);
67 return err;
68 }
69 return 0;
70}
71
72static int _mt352_write(struct dvb_frontend* fe, const u8 ibuf[], int ilen)
73{
74 int err,i;
75 for (i=0; i < ilen-1; i++)
76 if ((err = mt352_single_write(fe,ibuf[0]+i,ibuf[i+1])))
77 return err;
78
79 return 0;
80}
81
82static int mt352_read_register(struct mt352_state* state, u8 reg)
83{
84 int ret;
85 u8 b0 [] = { reg };
86 u8 b1 [] = { 0 };
87 struct i2c_msg msg [] = { { .addr = state->config.demod_address,
88 .flags = 0,
89 .buf = b0, .len = 1 },
90 { .addr = state->config.demod_address,
91 .flags = I2C_M_RD,
92 .buf = b1, .len = 1 } };
93
94 ret = i2c_transfer(state->i2c, msg, 2);
95
96 if (ret != 2) {
97 printk("%s: readreg error (reg=%d, ret==%i)\n",
98 __func__, reg, ret);
99 return ret;
100 }
101
102 return b1[0];
103}
104
105static int mt352_sleep(struct dvb_frontend* fe)
106{
107 static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 };
108
109 _mt352_write(fe, mt352_softdown, sizeof(mt352_softdown));
110 return 0;
111}
112
113static void mt352_calc_nominal_rate(struct mt352_state* state,
114 enum fe_bandwidth bandwidth,
115 unsigned char *buf)
116{
117 u32 adc_clock = 20480; /* 20.340 MHz */
118 u32 bw,value;
119
120 switch (bandwidth) {
121 case BANDWIDTH_6_MHZ:
122 bw = 6;
123 break;
124 case BANDWIDTH_7_MHZ:
125 bw = 7;
126 break;
127 case BANDWIDTH_8_MHZ:
128 default:
129 bw = 8;
130 break;
131 }
132 if (state->config.adc_clock)
133 adc_clock = state->config.adc_clock;
134
135 value = 64 * bw * (1<<16) / (7 * 8);
136 value = value * 1000 / adc_clock;
137 dprintk("%s: bw %d, adc_clock %d => 0x%x\n",
138 __func__, bw, adc_clock, value);
139 buf[0] = msb(value);
140 buf[1] = lsb(value);
141}
142
143static void mt352_calc_input_freq(struct mt352_state* state,
144 unsigned char *buf)
145{
146 int adc_clock = 20480; /* 20.480000 MHz */
147 int if2 = 36167; /* 36.166667 MHz */
148 int ife,value;
149
150 if (state->config.adc_clock)
151 adc_clock = state->config.adc_clock;
152 if (state->config.if2)
153 if2 = state->config.if2;
154
155 if (adc_clock >= if2 * 2)
156 ife = if2;
157 else {
158 ife = adc_clock - (if2 % adc_clock);
159 if (ife > adc_clock / 2)
160 ife = adc_clock - ife;
161 }
162 value = -16374 * ife / adc_clock;
163 dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n",
164 __func__, if2, ife, adc_clock, value, value & 0x3fff);
165 buf[0] = msb(value);
166 buf[1] = lsb(value);
167}
168
169static int mt352_set_parameters(struct dvb_frontend* fe,
170 struct dvb_frontend_parameters *param)
171{
172 struct mt352_state* state = fe->demodulator_priv;
173 unsigned char buf[13];
174 static unsigned char tuner_go[] = { 0x5d, 0x01 };
175 static unsigned char fsm_go[] = { 0x5e, 0x01 };
176 unsigned int tps = 0;
177 struct dvb_ofdm_parameters *op = &param->u.ofdm;
178
179 switch (op->code_rate_HP) {
180 case FEC_2_3:
181 tps |= (1 << 7);
182 break;
183 case FEC_3_4:
184 tps |= (2 << 7);
185 break;
186 case FEC_5_6:
187 tps |= (3 << 7);
188 break;
189 case FEC_7_8:
190 tps |= (4 << 7);
191 break;
192 case FEC_1_2:
193 case FEC_AUTO:
194 break;
195 default:
196 return -EINVAL;
197 }
198
199 switch (op->code_rate_LP) {
200 case FEC_2_3:
201 tps |= (1 << 4);
202 break;
203 case FEC_3_4:
204 tps |= (2 << 4);
205 break;
206 case FEC_5_6:
207 tps |= (3 << 4);
208 break;
209 case FEC_7_8:
210 tps |= (4 << 4);
211 break;
212 case FEC_1_2:
213 case FEC_AUTO:
214 break;
215 case FEC_NONE:
216 if (op->hierarchy_information == HIERARCHY_AUTO ||
217 op->hierarchy_information == HIERARCHY_NONE)
218 break;
219 default:
220 return -EINVAL;
221 }
222
223 switch (op->constellation) {
224 case QPSK:
225 break;
226 case QAM_AUTO:
227 case QAM_16:
228 tps |= (1 << 13);
229 break;
230 case QAM_64:
231 tps |= (2 << 13);
232 break;
233 default:
234 return -EINVAL;
235 }
236
237 switch (op->transmission_mode) {
238 case TRANSMISSION_MODE_2K:
239 case TRANSMISSION_MODE_AUTO:
240 break;
241 case TRANSMISSION_MODE_8K:
242 tps |= (1 << 0);
243 break;
244 default:
245 return -EINVAL;
246 }
247
248 switch (op->guard_interval) {
249 case GUARD_INTERVAL_1_32:
250 case GUARD_INTERVAL_AUTO:
251 break;
252 case GUARD_INTERVAL_1_16:
253 tps |= (1 << 2);
254 break;
255 case GUARD_INTERVAL_1_8:
256 tps |= (2 << 2);
257 break;
258 case GUARD_INTERVAL_1_4:
259 tps |= (3 << 2);
260 break;
261 default:
262 return -EINVAL;
263 }
264
265 switch (op->hierarchy_information) {
266 case HIERARCHY_AUTO:
267 case HIERARCHY_NONE:
268 break;
269 case HIERARCHY_1:
270 tps |= (1 << 10);
271 break;
272 case HIERARCHY_2:
273 tps |= (2 << 10);
274 break;
275 case HIERARCHY_4:
276 tps |= (3 << 10);
277 break;
278 default:
279 return -EINVAL;
280 }
281
282
283 buf[0] = TPS_GIVEN_1; /* TPS_GIVEN_1 and following registers */
284
285 buf[1] = msb(tps); /* TPS_GIVEN_(1|0) */
286 buf[2] = lsb(tps);
287
288 buf[3] = 0x50; // old
289// buf[3] = 0xf4; // pinnacle
290
291 mt352_calc_nominal_rate(state, op->bandwidth, buf+4);
292 mt352_calc_input_freq(state, buf+6);
293
294 if (state->config.no_tuner) {
295 if (fe->ops.tuner_ops.set_params) {
296 fe->ops.tuner_ops.set_params(fe, param);
297 if (fe->ops.i2c_gate_ctrl)
298 fe->ops.i2c_gate_ctrl(fe, 0);
299 }
300
301 _mt352_write(fe, buf, 8);
302 _mt352_write(fe, fsm_go, 2);
303 } else {
304 if (fe->ops.tuner_ops.calc_regs) {
305 fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5);
306 buf[8] <<= 1;
307 _mt352_write(fe, buf, sizeof(buf));
308 _mt352_write(fe, tuner_go, 2);
309 }
310 }
311
312 return 0;
313}
314
315static int mt352_get_parameters(struct dvb_frontend* fe,
316 struct dvb_frontend_parameters *param)
317{
318 struct mt352_state* state = fe->demodulator_priv;
319 u16 tps;
320 u16 div;
321 u8 trl;
322 struct dvb_ofdm_parameters *op = &param->u.ofdm;
323 static const u8 tps_fec_to_api[8] =
324 {
325 FEC_1_2,
326 FEC_2_3,
327 FEC_3_4,
328 FEC_5_6,
329 FEC_7_8,
330 FEC_AUTO,
331 FEC_AUTO,
332 FEC_AUTO
333 };
334
335 if ( (mt352_read_register(state,0x00) & 0xC0) != 0xC0 )
336 return -EINVAL;
337
338 /* Use TPS_RECEIVED-registers, not the TPS_CURRENT-registers because
339 * the mt352 sometimes works with the wrong parameters
340 */
341 tps = (mt352_read_register(state, TPS_RECEIVED_1) << 8) | mt352_read_register(state, TPS_RECEIVED_0);
342 div = (mt352_read_register(state, CHAN_START_1) << 8) | mt352_read_register(state, CHAN_START_0);
343 trl = mt352_read_register(state, TRL_NOMINAL_RATE_1);
344
345 op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7];
346 op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7];
347
348 switch ( (tps >> 13) & 3)
349 {
350 case 0:
351 op->constellation = QPSK;
352 break;
353 case 1:
354 op->constellation = QAM_16;
355 break;
356 case 2:
357 op->constellation = QAM_64;
358 break;
359 default:
360 op->constellation = QAM_AUTO;
361 break;
362 }
363
364 op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : TRANSMISSION_MODE_2K;
365
366 switch ( (tps >> 2) & 3)
367 {
368 case 0:
369 op->guard_interval = GUARD_INTERVAL_1_32;
370 break;
371 case 1:
372 op->guard_interval = GUARD_INTERVAL_1_16;
373 break;
374 case 2:
375 op->guard_interval = GUARD_INTERVAL_1_8;
376 break;
377 case 3:
378 op->guard_interval = GUARD_INTERVAL_1_4;
379 break;
380 default:
381 op->guard_interval = GUARD_INTERVAL_AUTO;
382 break;
383 }
384
385 switch ( (tps >> 10) & 7)
386 {
387 case 0:
388 op->hierarchy_information = HIERARCHY_NONE;
389 break;
390 case 1:
391 op->hierarchy_information = HIERARCHY_1;
392 break;
393 case 2:
394 op->hierarchy_information = HIERARCHY_2;
395 break;
396 case 3:
397 op->hierarchy_information = HIERARCHY_4;
398 break;
399 default:
400 op->hierarchy_information = HIERARCHY_AUTO;
401 break;
402 }
403
404 param->frequency = ( 500 * (div - IF_FREQUENCYx6) ) / 3 * 1000;
405
406 if (trl == 0x72)
407 op->bandwidth = BANDWIDTH_8_MHZ;
408 else if (trl == 0x64)
409 op->bandwidth = BANDWIDTH_7_MHZ;
410 else
411 op->bandwidth = BANDWIDTH_6_MHZ;
412
413
414 if (mt352_read_register(state, STATUS_2) & 0x02)
415 param->inversion = INVERSION_OFF;
416 else
417 param->inversion = INVERSION_ON;
418
419 return 0;
420}
421
422static int mt352_read_status(struct dvb_frontend* fe, fe_status_t* status)
423{
424 struct mt352_state* state = fe->demodulator_priv;
425 int s0, s1, s3;
426
427 /* FIXME:
428 *
429 * The MT352 design manual from Zarlink states (page 46-47):
430 *
431 * Notes about the TUNER_GO register:
432 *
433 * If the Read_Tuner_Byte (bit-1) is activated, then the tuner status
434 * byte is copied from the tuner to the STATUS_3 register and
435 * completion of the read operation is indicated by bit-5 of the
436 * INTERRUPT_3 register.
437 */
438
439 if ((s0 = mt352_read_register(state, STATUS_0)) < 0)
440 return -EREMOTEIO;
441 if ((s1 = mt352_read_register(state, STATUS_1)) < 0)
442 return -EREMOTEIO;
443 if ((s3 = mt352_read_register(state, STATUS_3)) < 0)
444 return -EREMOTEIO;
445
446 *status = 0;
447 if (s0 & (1 << 4))
448 *status |= FE_HAS_CARRIER;
449 if (s0 & (1 << 1))
450 *status |= FE_HAS_VITERBI;
451 if (s0 & (1 << 5))
452 *status |= FE_HAS_LOCK;
453 if (s1 & (1 << 1))
454 *status |= FE_HAS_SYNC;
455 if (s3 & (1 << 6))
456 *status |= FE_HAS_SIGNAL;
457
458 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
459 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
460 *status &= ~FE_HAS_LOCK;
461
462 return 0;
463}
464
465static int mt352_read_ber(struct dvb_frontend* fe, u32* ber)
466{
467 struct mt352_state* state = fe->demodulator_priv;
468
469 *ber = (mt352_read_register (state, RS_ERR_CNT_2) << 16) |
470 (mt352_read_register (state, RS_ERR_CNT_1) << 8) |
471 (mt352_read_register (state, RS_ERR_CNT_0));
472
473 return 0;
474}
475
476static int mt352_read_signal_strength(struct dvb_frontend* fe, u16* strength)
477{
478 struct mt352_state* state = fe->demodulator_priv;
479
480 /* align the 12 bit AGC gain with the most significant bits */
481 u16 signal = ((mt352_read_register(state, AGC_GAIN_1) & 0x0f) << 12) |
482 (mt352_read_register(state, AGC_GAIN_0) << 4);
483
484 /* inverse of gain is signal strength */
485 *strength = ~signal;
486 return 0;
487}
488
489static int mt352_read_snr(struct dvb_frontend* fe, u16* snr)
490{
491 struct mt352_state* state = fe->demodulator_priv;
492
493 u8 _snr = mt352_read_register (state, SNR);
494 *snr = (_snr << 8) | _snr;
495
496 return 0;
497}
498
499static int mt352_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
500{
501 struct mt352_state* state = fe->demodulator_priv;
502
503 *ucblocks = (mt352_read_register (state, RS_UBC_1) << 8) |
504 (mt352_read_register (state, RS_UBC_0));
505
506 return 0;
507}
508
509static int mt352_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
510{
511 fe_tune_settings->min_delay_ms = 800;
512 fe_tune_settings->step_size = 0;
513 fe_tune_settings->max_drift = 0;
514
515 return 0;
516}
517
518static int mt352_init(struct dvb_frontend* fe)
519{
520 struct mt352_state* state = fe->demodulator_priv;
521
522 static u8 mt352_reset_attach [] = { RESET, 0xC0 };
523
524 dprintk("%s: hello\n",__func__);
525
526 if ((mt352_read_register(state, CLOCK_CTL) & 0x10) == 0 ||
527 (mt352_read_register(state, CONFIG) & 0x20) == 0) {
528
529 /* Do a "hard" reset */
530 _mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach));
531 return state->config.demod_init(fe);
532 }
533
534 return 0;
535}
536
537static void mt352_release(struct dvb_frontend* fe)
538{
539 struct mt352_state* state = fe->demodulator_priv;
540 kfree(state);
541}
542
543static struct dvb_frontend_ops mt352_ops;
544
545struct dvb_frontend* mt352_attach(const struct mt352_config* config,
546 struct i2c_adapter* i2c)
547{
548 struct mt352_state* state = NULL;
549
550 /* allocate memory for the internal state */
551 state = kzalloc(sizeof(struct mt352_state), GFP_KERNEL);
552 if (state == NULL) goto error;
553
554 /* setup the state */
555 state->i2c = i2c;
556 memcpy(&state->config,config,sizeof(struct mt352_config));
557
558 /* check if the demod is there */
559 if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error;
560
561 /* create dvb_frontend */
562 memcpy(&state->frontend.ops, &mt352_ops, sizeof(struct dvb_frontend_ops));
563 state->frontend.demodulator_priv = state;
564 return &state->frontend;
565
566error:
567 kfree(state);
568 return NULL;
569}
570
571static struct dvb_frontend_ops mt352_ops = {
572
573 .info = {
574 .name = "Zarlink MT352 DVB-T",
575 .type = FE_OFDM,
576 .frequency_min = 174000000,
577 .frequency_max = 862000000,
578 .frequency_stepsize = 166667,
579 .frequency_tolerance = 0,
580 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
581 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
582 FE_CAN_FEC_AUTO |
583 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
584 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
585 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
586 FE_CAN_MUTE_TS
587 },
588
589 .release = mt352_release,
590
591 .init = mt352_init,
592 .sleep = mt352_sleep,
593 .write = _mt352_write,
594
595 .set_frontend = mt352_set_parameters,
596 .get_frontend = mt352_get_parameters,
597 .get_tune_settings = mt352_get_tune_settings,
598
599 .read_status = mt352_read_status,
600 .read_ber = mt352_read_ber,
601 .read_signal_strength = mt352_read_signal_strength,
602 .read_snr = mt352_read_snr,
603 .read_ucblocks = mt352_read_ucblocks,
604};
605
606module_param(debug, int, 0644);
607MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
608
609MODULE_DESCRIPTION("Zarlink MT352 DVB-T Demodulator driver");
610MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso");
611MODULE_LICENSE("GPL");
612
613EXPORT_SYMBOL(mt352_attach);
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h
new file mode 100644
index 00000000000..ca2562d6f28
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt352.h
@@ -0,0 +1,73 @@
1/*
2 * Driver for Zarlink DVB-T MT352 demodulator
3 *
4 * Written by Holger Waechtler <holger@qanu.de>
5 * and Daniel Mack <daniel@qanu.de>
6 *
7 * AVerMedia AVerTV DVB-T 771 support by
8 * Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * Support for Samsung TDTC9251DH01C(M) tuner
11 * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
12 * Amauri Celani <acelani@essegi.net>
13 *
14 * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
15 * Christopher Pascoe <c.pascoe@itee.uq.edu.au>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 *
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
31 */
32
33#ifndef MT352_H
34#define MT352_H
35
36#include <linux/dvb/frontend.h>
37
38struct mt352_config
39{
40 /* the demodulator's i2c address */
41 u8 demod_address;
42
43 /* frequencies in kHz */
44 int adc_clock; // default: 20480
45 int if2; // default: 36166
46
47 /* set if no pll is connected to the secondary i2c bus */
48 int no_tuner;
49
50 /* Initialise the demodulator and PLL. Cannot be NULL */
51 int (*demod_init)(struct dvb_frontend* fe);
52};
53
54#if defined(CONFIG_DVB_MT352) || (defined(CONFIG_DVB_MT352_MODULE) && defined(MODULE))
55extern struct dvb_frontend* mt352_attach(const struct mt352_config* config,
56 struct i2c_adapter* i2c);
57#else
58static inline struct dvb_frontend* mt352_attach(const struct mt352_config* config,
59 struct i2c_adapter* i2c)
60{
61 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
62 return NULL;
63}
64#endif // CONFIG_DVB_MT352
65
66static inline int mt352_write(struct dvb_frontend *fe, const u8 buf[], int len) {
67 int r = 0;
68 if (fe->ops.write)
69 r = fe->ops.write(fe, buf, len);
70 return r;
71}
72
73#endif // MT352_H
diff --git a/drivers/media/dvb/frontends/mt352_priv.h b/drivers/media/dvb/frontends/mt352_priv.h
new file mode 100644
index 00000000000..44ad0d4c8f1
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt352_priv.h
@@ -0,0 +1,127 @@
1/*
2 * Driver for Zarlink DVB-T MT352 demodulator
3 *
4 * Written by Holger Waechtler <holger@qanu.de>
5 * and Daniel Mack <daniel@qanu.de>
6 *
7 * AVerMedia AVerTV DVB-T 771 support by
8 * Wolfram Joost <dbox2@frokaschwei.de>
9 *
10 * Support for Samsung TDTC9251DH01C(M) tuner
11 * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it>
12 * Amauri Celani <acelani@essegi.net>
13 *
14 * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by
15 * Christopher Pascoe <c.pascoe@itee.uq.edu.au>
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 *
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
31 */
32
33#ifndef _MT352_PRIV_
34#define _MT352_PRIV_
35
36#define ID_MT352 0x13
37
38#define msb(x) (((x) >> 8) & 0xff)
39#define lsb(x) ((x) & 0xff)
40
41enum mt352_reg_addr {
42 STATUS_0 = 0x00,
43 STATUS_1 = 0x01,
44 STATUS_2 = 0x02,
45 STATUS_3 = 0x03,
46 STATUS_4 = 0x04,
47 INTERRUPT_0 = 0x05,
48 INTERRUPT_1 = 0x06,
49 INTERRUPT_2 = 0x07,
50 INTERRUPT_3 = 0x08,
51 SNR = 0x09,
52 VIT_ERR_CNT_2 = 0x0A,
53 VIT_ERR_CNT_1 = 0x0B,
54 VIT_ERR_CNT_0 = 0x0C,
55 RS_ERR_CNT_2 = 0x0D,
56 RS_ERR_CNT_1 = 0x0E,
57 RS_ERR_CNT_0 = 0x0F,
58 RS_UBC_1 = 0x10,
59 RS_UBC_0 = 0x11,
60 AGC_GAIN_3 = 0x12,
61 AGC_GAIN_2 = 0x13,
62 AGC_GAIN_1 = 0x14,
63 AGC_GAIN_0 = 0x15,
64 FREQ_OFFSET_2 = 0x17,
65 FREQ_OFFSET_1 = 0x18,
66 FREQ_OFFSET_0 = 0x19,
67 TIMING_OFFSET_1 = 0x1A,
68 TIMING_OFFSET_0 = 0x1B,
69 CHAN_FREQ_1 = 0x1C,
70 CHAN_FREQ_0 = 0x1D,
71 TPS_RECEIVED_1 = 0x1E,
72 TPS_RECEIVED_0 = 0x1F,
73 TPS_CURRENT_1 = 0x20,
74 TPS_CURRENT_0 = 0x21,
75 TPS_CELL_ID_1 = 0x22,
76 TPS_CELL_ID_0 = 0x23,
77 TPS_MISC_DATA_2 = 0x24,
78 TPS_MISC_DATA_1 = 0x25,
79 TPS_MISC_DATA_0 = 0x26,
80 RESET = 0x50,
81 TPS_GIVEN_1 = 0x51,
82 TPS_GIVEN_0 = 0x52,
83 ACQ_CTL = 0x53,
84 TRL_NOMINAL_RATE_1 = 0x54,
85 TRL_NOMINAL_RATE_0 = 0x55,
86 INPUT_FREQ_1 = 0x56,
87 INPUT_FREQ_0 = 0x57,
88 TUNER_ADDR = 0x58,
89 CHAN_START_1 = 0x59,
90 CHAN_START_0 = 0x5A,
91 CONT_1 = 0x5B,
92 CONT_0 = 0x5C,
93 TUNER_GO = 0x5D,
94 STATUS_EN_0 = 0x5F,
95 STATUS_EN_1 = 0x60,
96 INTERRUPT_EN_0 = 0x61,
97 INTERRUPT_EN_1 = 0x62,
98 INTERRUPT_EN_2 = 0x63,
99 INTERRUPT_EN_3 = 0x64,
100 AGC_TARGET = 0x67,
101 AGC_CTL = 0x68,
102 CAPT_RANGE = 0x75,
103 SNR_SELECT_1 = 0x79,
104 SNR_SELECT_0 = 0x7A,
105 RS_ERR_PER_1 = 0x7C,
106 RS_ERR_PER_0 = 0x7D,
107 CHIP_ID = 0x7F,
108 CHAN_STOP_1 = 0x80,
109 CHAN_STOP_0 = 0x81,
110 CHAN_STEP_1 = 0x82,
111 CHAN_STEP_0 = 0x83,
112 FEC_LOCK_TIME = 0x85,
113 OFDM_LOCK_TIME = 0x86,
114 ACQ_DELAY = 0x87,
115 SCAN_CTL = 0x88,
116 CLOCK_CTL = 0x89,
117 CONFIG = 0x8A,
118 MCLK_RATIO = 0x8B,
119 GPP_CTL = 0x8C,
120 ADC_CTL_1 = 0x8E,
121 ADC_CTL_0 = 0x8F
122};
123
124/* here we assume 1/6MHz == 166.66kHz stepsize */
125#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
126
127#endif /* _MT352_PRIV_ */
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
new file mode 100644
index 00000000000..eac20650499
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -0,0 +1,1241 @@
1/*
2 * Support for NXT2002 and NXT2004 - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com>
5 * Copyright (C) 2006 Michael Krufky <mkrufky@m1k.net>
6 * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
7 * and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23*/
24
25/*
26 * NOTES ABOUT THIS DRIVER
27 *
28 * This Linux driver supports:
29 * B2C2/BBTI Technisat Air2PC - ATSC (NXT2002)
30 * AverTVHD MCE A180 (NXT2004)
31 * ATI HDTV Wonder (NXT2004)
32 *
33 * This driver needs external firmware. Please use the command
34 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" or
35 * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
36 * download/extract the appropriate firmware, and then copy it to
37 * /usr/lib/hotplug/firmware/ or /lib/firmware/
38 * (depending on configuration of firmware hotplug).
39 */
40#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
41#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw"
42#define CRC_CCIT_MASK 0x1021
43
44#include <linux/kernel.h>
45#include <linux/init.h>
46#include <linux/module.h>
47#include <linux/slab.h>
48#include <linux/string.h>
49
50#include "dvb_frontend.h"
51#include "nxt200x.h"
52
53struct nxt200x_state {
54
55 struct i2c_adapter* i2c;
56 const struct nxt200x_config* config;
57 struct dvb_frontend frontend;
58
59 /* demodulator private data */
60 nxt_chip_type demod_chip;
61 u8 initialised:1;
62};
63
64static int debug;
65#define dprintk(args...) \
66 do { \
67 if (debug) printk(KERN_DEBUG "nxt200x: " args); \
68 } while (0)
69
70static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len)
71{
72 int err;
73 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len };
74
75 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
76 printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
77 __func__, addr, err);
78 return -EREMOTEIO;
79 }
80 return 0;
81}
82
83static int i2c_readbytes(struct nxt200x_state *state, u8 addr, u8 *buf, u8 len)
84{
85 int err;
86 struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
87
88 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
89 printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
90 __func__, addr, err);
91 return -EREMOTEIO;
92 }
93 return 0;
94}
95
96static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg,
97 const u8 *buf, u8 len)
98{
99 u8 buf2 [len+1];
100 int err;
101 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
102
103 buf2[0] = reg;
104 memcpy(&buf2[1], buf, len);
105
106 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
107 printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
108 __func__, state->config->demod_address, err);
109 return -EREMOTEIO;
110 }
111 return 0;
112}
113
114static int nxt200x_readbytes(struct nxt200x_state *state, u8 reg, u8 *buf, u8 len)
115{
116 u8 reg2 [] = { reg };
117
118 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
119 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
120
121 int err;
122
123 if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
124 printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
125 __func__, state->config->demod_address, err);
126 return -EREMOTEIO;
127 }
128 return 0;
129}
130
131static u16 nxt200x_crc(u16 crc, u8 c)
132{
133 u8 i;
134 u16 input = (u16) c & 0xFF;
135
136 input<<=8;
137 for(i=0; i<8; i++) {
138 if((crc^input) & 0x8000)
139 crc=(crc<<1)^CRC_CCIT_MASK;
140 else
141 crc<<=1;
142 input<<=1;
143 }
144 return crc;
145}
146
147static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
148{
149 u8 attr, len2, buf;
150 dprintk("%s\n", __func__);
151
152 /* set mutli register register */
153 nxt200x_writebytes(state, 0x35, &reg, 1);
154
155 /* send the actual data */
156 nxt200x_writebytes(state, 0x36, data, len);
157
158 switch (state->demod_chip) {
159 case NXT2002:
160 len2 = len;
161 buf = 0x02;
162 break;
163 case NXT2004:
164 /* probably not right, but gives correct values */
165 attr = 0x02;
166 if (reg & 0x80) {
167 attr = attr << 1;
168 if (reg & 0x04)
169 attr = attr >> 1;
170 }
171 /* set write bit */
172 len2 = ((attr << 4) | 0x10) | len;
173 buf = 0x80;
174 break;
175 default:
176 return -EINVAL;
177 break;
178 }
179
180 /* set multi register length */
181 nxt200x_writebytes(state, 0x34, &len2, 1);
182
183 /* toggle the multireg write bit */
184 nxt200x_writebytes(state, 0x21, &buf, 1);
185
186 nxt200x_readbytes(state, 0x21, &buf, 1);
187
188 switch (state->demod_chip) {
189 case NXT2002:
190 if ((buf & 0x02) == 0)
191 return 0;
192 break;
193 case NXT2004:
194 if (buf == 0)
195 return 0;
196 break;
197 default:
198 return -EINVAL;
199 break;
200 }
201
202 printk(KERN_WARNING "nxt200x: Error writing multireg register 0x%02X\n",reg);
203
204 return 0;
205}
206
207static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
208{
209 int i;
210 u8 buf, len2, attr;
211 dprintk("%s\n", __func__);
212
213 /* set mutli register register */
214 nxt200x_writebytes(state, 0x35, &reg, 1);
215
216 switch (state->demod_chip) {
217 case NXT2002:
218 /* set multi register length */
219 len2 = len & 0x80;
220 nxt200x_writebytes(state, 0x34, &len2, 1);
221
222 /* read the actual data */
223 nxt200x_readbytes(state, reg, data, len);
224 return 0;
225 break;
226 case NXT2004:
227 /* probably not right, but gives correct values */
228 attr = 0x02;
229 if (reg & 0x80) {
230 attr = attr << 1;
231 if (reg & 0x04)
232 attr = attr >> 1;
233 }
234
235 /* set multi register length */
236 len2 = (attr << 4) | len;
237 nxt200x_writebytes(state, 0x34, &len2, 1);
238
239 /* toggle the multireg bit*/
240 buf = 0x80;
241 nxt200x_writebytes(state, 0x21, &buf, 1);
242
243 /* read the actual data */
244 for(i = 0; i < len; i++) {
245 nxt200x_readbytes(state, 0x36 + i, &data[i], 1);
246 }
247 return 0;
248 break;
249 default:
250 return -EINVAL;
251 break;
252 }
253}
254
255static void nxt200x_microcontroller_stop (struct nxt200x_state* state)
256{
257 u8 buf, stopval, counter = 0;
258 dprintk("%s\n", __func__);
259
260 /* set correct stop value */
261 switch (state->demod_chip) {
262 case NXT2002:
263 stopval = 0x40;
264 break;
265 case NXT2004:
266 stopval = 0x10;
267 break;
268 default:
269 stopval = 0;
270 break;
271 }
272
273 buf = 0x80;
274 nxt200x_writebytes(state, 0x22, &buf, 1);
275
276 while (counter < 20) {
277 nxt200x_readbytes(state, 0x31, &buf, 1);
278 if (buf & stopval)
279 return;
280 msleep(10);
281 counter++;
282 }
283
284 printk(KERN_WARNING "nxt200x: Timeout waiting for nxt200x to stop. This is ok after firmware upload.\n");
285 return;
286}
287
288static void nxt200x_microcontroller_start (struct nxt200x_state* state)
289{
290 u8 buf;
291 dprintk("%s\n", __func__);
292
293 buf = 0x00;
294 nxt200x_writebytes(state, 0x22, &buf, 1);
295}
296
297static void nxt2004_microcontroller_init (struct nxt200x_state* state)
298{
299 u8 buf[9];
300 u8 counter = 0;
301 dprintk("%s\n", __func__);
302
303 buf[0] = 0x00;
304 nxt200x_writebytes(state, 0x2b, buf, 1);
305 buf[0] = 0x70;
306 nxt200x_writebytes(state, 0x34, buf, 1);
307 buf[0] = 0x04;
308 nxt200x_writebytes(state, 0x35, buf, 1);
309 buf[0] = 0x01; buf[1] = 0x23; buf[2] = 0x45; buf[3] = 0x67; buf[4] = 0x89;
310 buf[5] = 0xAB; buf[6] = 0xCD; buf[7] = 0xEF; buf[8] = 0xC0;
311 nxt200x_writebytes(state, 0x36, buf, 9);
312 buf[0] = 0x80;
313 nxt200x_writebytes(state, 0x21, buf, 1);
314
315 while (counter < 20) {
316 nxt200x_readbytes(state, 0x21, buf, 1);
317 if (buf[0] == 0)
318 return;
319 msleep(10);
320 counter++;
321 }
322
323 printk(KERN_WARNING "nxt200x: Timeout waiting for nxt2004 to init.\n");
324
325 return;
326}
327
328static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
329{
330 u8 buf, count = 0;
331
332 dprintk("%s\n", __func__);
333
334 dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[1], data[2], data[3], data[4]);
335
336 /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip.
337 * direct write is required for Philips TUV1236D and ALPS TDHU2 */
338 switch (state->demod_chip) {
339 case NXT2004:
340 if (i2c_writebytes(state, data[0], data+1, 4))
341 printk(KERN_WARNING "nxt200x: error writing to tuner\n");
342 /* wait until we have a lock */
343 while (count < 20) {
344 i2c_readbytes(state, data[0], &buf, 1);
345 if (buf & 0x40)
346 return 0;
347 msleep(100);
348 count++;
349 }
350 printk("nxt2004: timeout waiting for tuner lock\n");
351 break;
352 case NXT2002:
353 /* set the i2c transfer speed to the tuner */
354 buf = 0x03;
355 nxt200x_writebytes(state, 0x20, &buf, 1);
356
357 /* setup to transfer 4 bytes via i2c */
358 buf = 0x04;
359 nxt200x_writebytes(state, 0x34, &buf, 1);
360
361 /* write actual tuner bytes */
362 nxt200x_writebytes(state, 0x36, data+1, 4);
363
364 /* set tuner i2c address */
365 buf = data[0] << 1;
366 nxt200x_writebytes(state, 0x35, &buf, 1);
367
368 /* write UC Opmode to begin transfer */
369 buf = 0x80;
370 nxt200x_writebytes(state, 0x21, &buf, 1);
371
372 while (count < 20) {
373 nxt200x_readbytes(state, 0x21, &buf, 1);
374 if ((buf & 0x80)== 0x00)
375 return 0;
376 msleep(100);
377 count++;
378 }
379 printk("nxt2002: timeout error writing tuner\n");
380 break;
381 default:
382 return -EINVAL;
383 break;
384 }
385 return 0;
386}
387
388static void nxt200x_agc_reset(struct nxt200x_state* state)
389{
390 u8 buf;
391 dprintk("%s\n", __func__);
392
393 switch (state->demod_chip) {
394 case NXT2002:
395 buf = 0x08;
396 nxt200x_writebytes(state, 0x08, &buf, 1);
397 buf = 0x00;
398 nxt200x_writebytes(state, 0x08, &buf, 1);
399 break;
400 case NXT2004:
401 nxt200x_readreg_multibyte(state, 0x08, &buf, 1);
402 buf = 0x08;
403 nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
404 buf = 0x00;
405 nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
406 break;
407 default:
408 break;
409 }
410 return;
411}
412
413static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
414{
415
416 struct nxt200x_state* state = fe->demodulator_priv;
417 u8 buf[3], written = 0, chunkpos = 0;
418 u16 rambase, position, crc = 0;
419
420 dprintk("%s\n", __func__);
421 dprintk("Firmware is %zu bytes\n", fw->size);
422
423 /* Get the RAM base for this nxt2002 */
424 nxt200x_readbytes(state, 0x10, buf, 1);
425
426 if (buf[0] & 0x10)
427 rambase = 0x1000;
428 else
429 rambase = 0x0000;
430
431 dprintk("rambase on this nxt2002 is %04X\n", rambase);
432
433 /* Hold the micro in reset while loading firmware */
434 buf[0] = 0x80;
435 nxt200x_writebytes(state, 0x2B, buf, 1);
436
437 for (position = 0; position < fw->size; position++) {
438 if (written == 0) {
439 crc = 0;
440 chunkpos = 0x28;
441 buf[0] = ((rambase + position) >> 8);
442 buf[1] = (rambase + position) & 0xFF;
443 buf[2] = 0x81;
444 /* write starting address */
445 nxt200x_writebytes(state, 0x29, buf, 3);
446 }
447 written++;
448 chunkpos++;
449
450 if ((written % 4) == 0)
451 nxt200x_writebytes(state, chunkpos, &fw->data[position-3], 4);
452
453 crc = nxt200x_crc(crc, fw->data[position]);
454
455 if ((written == 255) || (position+1 == fw->size)) {
456 /* write remaining bytes of firmware */
457 nxt200x_writebytes(state, chunkpos+4-(written %4),
458 &fw->data[position-(written %4) + 1],
459 written %4);
460 buf[0] = crc << 8;
461 buf[1] = crc & 0xFF;
462
463 /* write crc */
464 nxt200x_writebytes(state, 0x2C, buf, 2);
465
466 /* do a read to stop things */
467 nxt200x_readbytes(state, 0x2A, buf, 1);
468
469 /* set transfer mode to complete */
470 buf[0] = 0x80;
471 nxt200x_writebytes(state, 0x2B, buf, 1);
472
473 written = 0;
474 }
475 }
476
477 return 0;
478};
479
480static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
481{
482
483 struct nxt200x_state* state = fe->demodulator_priv;
484 u8 buf[3];
485 u16 rambase, position, crc=0;
486
487 dprintk("%s\n", __func__);
488 dprintk("Firmware is %zu bytes\n", fw->size);
489
490 /* set rambase */
491 rambase = 0x1000;
492
493 /* hold the micro in reset while loading firmware */
494 buf[0] = 0x80;
495 nxt200x_writebytes(state, 0x2B, buf,1);
496
497 /* calculate firmware CRC */
498 for (position = 0; position < fw->size; position++) {
499 crc = nxt200x_crc(crc, fw->data[position]);
500 }
501
502 buf[0] = rambase >> 8;
503 buf[1] = rambase & 0xFF;
504 buf[2] = 0x81;
505 /* write starting address */
506 nxt200x_writebytes(state,0x29,buf,3);
507
508 for (position = 0; position < fw->size;) {
509 nxt200x_writebytes(state, 0x2C, &fw->data[position],
510 fw->size-position > 255 ? 255 : fw->size-position);
511 position += (fw->size-position > 255 ? 255 : fw->size-position);
512 }
513 buf[0] = crc >> 8;
514 buf[1] = crc & 0xFF;
515
516 dprintk("firmware crc is 0x%02X 0x%02X\n", buf[0], buf[1]);
517
518 /* write crc */
519 nxt200x_writebytes(state, 0x2C, buf,2);
520
521 /* do a read to stop things */
522 nxt200x_readbytes(state, 0x2C, buf, 1);
523
524 /* set transfer mode to complete */
525 buf[0] = 0x80;
526 nxt200x_writebytes(state, 0x2B, buf,1);
527
528 return 0;
529};
530
531static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
532 struct dvb_frontend_parameters *p)
533{
534 struct nxt200x_state* state = fe->demodulator_priv;
535 u8 buf[5];
536
537 /* stop the micro first */
538 nxt200x_microcontroller_stop(state);
539
540 if (state->demod_chip == NXT2004) {
541 /* make sure demod is set to digital */
542 buf[0] = 0x04;
543 nxt200x_writebytes(state, 0x14, buf, 1);
544 buf[0] = 0x00;
545 nxt200x_writebytes(state, 0x17, buf, 1);
546 }
547
548 /* set additional params */
549 switch (p->u.vsb.modulation) {
550 case QAM_64:
551 case QAM_256:
552 /* Set punctured clock for QAM */
553 /* This is just a guess since I am unable to test it */
554 if (state->config->set_ts_params)
555 state->config->set_ts_params(fe, 1);
556 break;
557 case VSB_8:
558 /* Set non-punctured clock for VSB */
559 if (state->config->set_ts_params)
560 state->config->set_ts_params(fe, 0);
561 break;
562 default:
563 return -EINVAL;
564 break;
565 }
566
567 if (fe->ops.tuner_ops.calc_regs) {
568 /* get tuning information */
569 fe->ops.tuner_ops.calc_regs(fe, p, buf, 5);
570
571 /* write frequency information */
572 nxt200x_writetuner(state, buf);
573 }
574
575 /* reset the agc now that tuning has been completed */
576 nxt200x_agc_reset(state);
577
578 /* set target power level */
579 switch (p->u.vsb.modulation) {
580 case QAM_64:
581 case QAM_256:
582 buf[0] = 0x74;
583 break;
584 case VSB_8:
585 buf[0] = 0x70;
586 break;
587 default:
588 return -EINVAL;
589 break;
590 }
591 nxt200x_writebytes(state, 0x42, buf, 1);
592
593 /* configure sdm */
594 switch (state->demod_chip) {
595 case NXT2002:
596 buf[0] = 0x87;
597 break;
598 case NXT2004:
599 buf[0] = 0x07;
600 break;
601 default:
602 return -EINVAL;
603 break;
604 }
605 nxt200x_writebytes(state, 0x57, buf, 1);
606
607 /* write sdm1 input */
608 buf[0] = 0x10;
609 buf[1] = 0x00;
610 switch (state->demod_chip) {
611 case NXT2002:
612 nxt200x_writereg_multibyte(state, 0x58, buf, 2);
613 break;
614 case NXT2004:
615 nxt200x_writebytes(state, 0x58, buf, 2);
616 break;
617 default:
618 return -EINVAL;
619 break;
620 }
621
622 /* write sdmx input */
623 switch (p->u.vsb.modulation) {
624 case QAM_64:
625 buf[0] = 0x68;
626 break;
627 case QAM_256:
628 buf[0] = 0x64;
629 break;
630 case VSB_8:
631 buf[0] = 0x60;
632 break;
633 default:
634 return -EINVAL;
635 break;
636 }
637 buf[1] = 0x00;
638 switch (state->demod_chip) {
639 case NXT2002:
640 nxt200x_writereg_multibyte(state, 0x5C, buf, 2);
641 break;
642 case NXT2004:
643 nxt200x_writebytes(state, 0x5C, buf, 2);
644 break;
645 default:
646 return -EINVAL;
647 break;
648 }
649
650 /* write adc power lpf fc */
651 buf[0] = 0x05;
652 nxt200x_writebytes(state, 0x43, buf, 1);
653
654 if (state->demod_chip == NXT2004) {
655 /* write ??? */
656 buf[0] = 0x00;
657 buf[1] = 0x00;
658 nxt200x_writebytes(state, 0x46, buf, 2);
659 }
660
661 /* write accumulator2 input */
662 buf[0] = 0x80;
663 buf[1] = 0x00;
664 switch (state->demod_chip) {
665 case NXT2002:
666 nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
667 break;
668 case NXT2004:
669 nxt200x_writebytes(state, 0x4B, buf, 2);
670 break;
671 default:
672 return -EINVAL;
673 break;
674 }
675
676 /* write kg1 */
677 buf[0] = 0x00;
678 nxt200x_writebytes(state, 0x4D, buf, 1);
679
680 /* write sdm12 lpf fc */
681 buf[0] = 0x44;
682 nxt200x_writebytes(state, 0x55, buf, 1);
683
684 /* write agc control reg */
685 buf[0] = 0x04;
686 nxt200x_writebytes(state, 0x41, buf, 1);
687
688 if (state->demod_chip == NXT2004) {
689 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
690 buf[0] = 0x24;
691 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
692
693 /* soft reset? */
694 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
695 buf[0] = 0x10;
696 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
697 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
698 buf[0] = 0x00;
699 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
700
701 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
702 buf[0] = 0x04;
703 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
704 buf[0] = 0x00;
705 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
706 buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
707 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
708 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
709 buf[0] = 0x11;
710 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
711 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
712 buf[0] = 0x44;
713 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
714 }
715
716 /* write agc ucgp0 */
717 switch (p->u.vsb.modulation) {
718 case QAM_64:
719 buf[0] = 0x02;
720 break;
721 case QAM_256:
722 buf[0] = 0x03;
723 break;
724 case VSB_8:
725 buf[0] = 0x00;
726 break;
727 default:
728 return -EINVAL;
729 break;
730 }
731 nxt200x_writebytes(state, 0x30, buf, 1);
732
733 /* write agc control reg */
734 buf[0] = 0x00;
735 nxt200x_writebytes(state, 0x41, buf, 1);
736
737 /* write accumulator2 input */
738 buf[0] = 0x80;
739 buf[1] = 0x00;
740 switch (state->demod_chip) {
741 case NXT2002:
742 nxt200x_writereg_multibyte(state, 0x49, buf, 2);
743 nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
744 break;
745 case NXT2004:
746 nxt200x_writebytes(state, 0x49, buf, 2);
747 nxt200x_writebytes(state, 0x4B, buf, 2);
748 break;
749 default:
750 return -EINVAL;
751 break;
752 }
753
754 /* write agc control reg */
755 buf[0] = 0x04;
756 nxt200x_writebytes(state, 0x41, buf, 1);
757
758 nxt200x_microcontroller_start(state);
759
760 if (state->demod_chip == NXT2004) {
761 nxt2004_microcontroller_init(state);
762
763 /* ???? */
764 buf[0] = 0xF0;
765 buf[1] = 0x00;
766 nxt200x_writebytes(state, 0x5C, buf, 2);
767 }
768
769 /* adjacent channel detection should be done here, but I don't
770 have any stations with this need so I cannot test it */
771
772 return 0;
773}
774
775static int nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status)
776{
777 struct nxt200x_state* state = fe->demodulator_priv;
778 u8 lock;
779 nxt200x_readbytes(state, 0x31, &lock, 1);
780
781 *status = 0;
782 if (lock & 0x20) {
783 *status |= FE_HAS_SIGNAL;
784 *status |= FE_HAS_CARRIER;
785 *status |= FE_HAS_VITERBI;
786 *status |= FE_HAS_SYNC;
787 *status |= FE_HAS_LOCK;
788 }
789 return 0;
790}
791
792static int nxt200x_read_ber(struct dvb_frontend* fe, u32* ber)
793{
794 struct nxt200x_state* state = fe->demodulator_priv;
795 u8 b[3];
796
797 nxt200x_readreg_multibyte(state, 0xE6, b, 3);
798
799 *ber = ((b[0] << 8) + b[1]) * 8;
800
801 return 0;
802}
803
804static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
805{
806 struct nxt200x_state* state = fe->demodulator_priv;
807 u8 b[2];
808 u16 temp = 0;
809
810 /* setup to read cluster variance */
811 b[0] = 0x00;
812 nxt200x_writebytes(state, 0xA1, b, 1);
813
814 /* get multreg val */
815 nxt200x_readreg_multibyte(state, 0xA6, b, 2);
816
817 temp = (b[0] << 8) | b[1];
818 *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
819
820 return 0;
821}
822
823static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr)
824{
825
826 struct nxt200x_state* state = fe->demodulator_priv;
827 u8 b[2];
828 u16 temp = 0, temp2;
829 u32 snrdb = 0;
830
831 /* setup to read cluster variance */
832 b[0] = 0x00;
833 nxt200x_writebytes(state, 0xA1, b, 1);
834
835 /* get multreg val from 0xA6 */
836 nxt200x_readreg_multibyte(state, 0xA6, b, 2);
837
838 temp = (b[0] << 8) | b[1];
839 temp2 = 0x7FFF - temp;
840
841 /* snr will be in db */
842 if (temp2 > 0x7F00)
843 snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
844 else if (temp2 > 0x7EC0)
845 snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
846 else if (temp2 > 0x7C00)
847 snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
848 else
849 snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
850
851 /* the value reported back from the frontend will be FFFF=32db 0000=0db */
852 *snr = snrdb * (0xFFFF/32000);
853
854 return 0;
855}
856
857static int nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
858{
859 struct nxt200x_state* state = fe->demodulator_priv;
860 u8 b[3];
861
862 nxt200x_readreg_multibyte(state, 0xE6, b, 3);
863 *ucblocks = b[2];
864
865 return 0;
866}
867
868static int nxt200x_sleep(struct dvb_frontend* fe)
869{
870 return 0;
871}
872
873static int nxt2002_init(struct dvb_frontend* fe)
874{
875 struct nxt200x_state* state = fe->demodulator_priv;
876 const struct firmware *fw;
877 int ret;
878 u8 buf[2];
879
880 /* request the firmware, this will block until someone uploads it */
881 printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
882 ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE,
883 state->i2c->dev.parent);
884 printk("nxt2002: Waiting for firmware upload(2)...\n");
885 if (ret) {
886 printk("nxt2002: No firmware uploaded (timeout or file not found?)\n");
887 return ret;
888 }
889
890 ret = nxt2002_load_firmware(fe, fw);
891 release_firmware(fw);
892 if (ret) {
893 printk("nxt2002: Writing firmware to device failed\n");
894 return ret;
895 }
896 printk("nxt2002: Firmware upload complete\n");
897
898 /* Put the micro into reset */
899 nxt200x_microcontroller_stop(state);
900
901 /* ensure transfer is complete */
902 buf[0]=0x00;
903 nxt200x_writebytes(state, 0x2B, buf, 1);
904
905 /* Put the micro into reset for real this time */
906 nxt200x_microcontroller_stop(state);
907
908 /* soft reset everything (agc,frontend,eq,fec)*/
909 buf[0] = 0x0F;
910 nxt200x_writebytes(state, 0x08, buf, 1);
911 buf[0] = 0x00;
912 nxt200x_writebytes(state, 0x08, buf, 1);
913
914 /* write agc sdm configure */
915 buf[0] = 0xF1;
916 nxt200x_writebytes(state, 0x57, buf, 1);
917
918 /* write mod output format */
919 buf[0] = 0x20;
920 nxt200x_writebytes(state, 0x09, buf, 1);
921
922 /* write fec mpeg mode */
923 buf[0] = 0x7E;
924 buf[1] = 0x00;
925 nxt200x_writebytes(state, 0xE9, buf, 2);
926
927 /* write mux selection */
928 buf[0] = 0x00;
929 nxt200x_writebytes(state, 0xCC, buf, 1);
930
931 return 0;
932}
933
934static int nxt2004_init(struct dvb_frontend* fe)
935{
936 struct nxt200x_state* state = fe->demodulator_priv;
937 const struct firmware *fw;
938 int ret;
939 u8 buf[3];
940
941 /* ??? */
942 buf[0]=0x00;
943 nxt200x_writebytes(state, 0x1E, buf, 1);
944
945 /* request the firmware, this will block until someone uploads it */
946 printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE);
947 ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE,
948 state->i2c->dev.parent);
949 printk("nxt2004: Waiting for firmware upload(2)...\n");
950 if (ret) {
951 printk("nxt2004: No firmware uploaded (timeout or file not found?)\n");
952 return ret;
953 }
954
955 ret = nxt2004_load_firmware(fe, fw);
956 release_firmware(fw);
957 if (ret) {
958 printk("nxt2004: Writing firmware to device failed\n");
959 return ret;
960 }
961 printk("nxt2004: Firmware upload complete\n");
962
963 /* ensure transfer is complete */
964 buf[0] = 0x01;
965 nxt200x_writebytes(state, 0x19, buf, 1);
966
967 nxt2004_microcontroller_init(state);
968 nxt200x_microcontroller_stop(state);
969 nxt200x_microcontroller_stop(state);
970 nxt2004_microcontroller_init(state);
971 nxt200x_microcontroller_stop(state);
972
973 /* soft reset everything (agc,frontend,eq,fec)*/
974 buf[0] = 0xFF;
975 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
976 buf[0] = 0x00;
977 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
978
979 /* write agc sdm configure */
980 buf[0] = 0xD7;
981 nxt200x_writebytes(state, 0x57, buf, 1);
982
983 /* ???*/
984 buf[0] = 0x07;
985 buf[1] = 0xfe;
986 nxt200x_writebytes(state, 0x35, buf, 2);
987 buf[0] = 0x12;
988 nxt200x_writebytes(state, 0x34, buf, 1);
989 buf[0] = 0x80;
990 nxt200x_writebytes(state, 0x21, buf, 1);
991
992 /* ???*/
993 buf[0] = 0x21;
994 nxt200x_writebytes(state, 0x0A, buf, 1);
995
996 /* ???*/
997 buf[0] = 0x01;
998 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
999
1000 /* write fec mpeg mode */
1001 buf[0] = 0x7E;
1002 buf[1] = 0x00;
1003 nxt200x_writebytes(state, 0xE9, buf, 2);
1004
1005 /* write mux selection */
1006 buf[0] = 0x00;
1007 nxt200x_writebytes(state, 0xCC, buf, 1);
1008
1009 /* ???*/
1010 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1011 buf[0] = 0x00;
1012 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1013
1014 /* soft reset? */
1015 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1016 buf[0] = 0x10;
1017 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1018 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1019 buf[0] = 0x00;
1020 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1021
1022 /* ???*/
1023 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1024 buf[0] = 0x01;
1025 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1026 buf[0] = 0x70;
1027 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
1028 buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66;
1029 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
1030
1031 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
1032 buf[0] = 0x11;
1033 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
1034 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1035 buf[0] = 0x40;
1036 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1037
1038 nxt200x_readbytes(state, 0x10, buf, 1);
1039 buf[0] = 0x10;
1040 nxt200x_writebytes(state, 0x10, buf, 1);
1041 nxt200x_readbytes(state, 0x0A, buf, 1);
1042 buf[0] = 0x21;
1043 nxt200x_writebytes(state, 0x0A, buf, 1);
1044
1045 nxt2004_microcontroller_init(state);
1046
1047 buf[0] = 0x21;
1048 nxt200x_writebytes(state, 0x0A, buf, 1);
1049 buf[0] = 0x7E;
1050 nxt200x_writebytes(state, 0xE9, buf, 1);
1051 buf[0] = 0x00;
1052 nxt200x_writebytes(state, 0xEA, buf, 1);
1053
1054 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1055 buf[0] = 0x00;
1056 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1057 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1058 buf[0] = 0x00;
1059 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1060
1061 /* soft reset? */
1062 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1063 buf[0] = 0x10;
1064 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1065 nxt200x_readreg_multibyte(state, 0x08, buf, 1);
1066 buf[0] = 0x00;
1067 nxt200x_writereg_multibyte(state, 0x08, buf, 1);
1068
1069 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1070 buf[0] = 0x04;
1071 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1072 buf[0] = 0x00;
1073 nxt200x_writereg_multibyte(state, 0x81, buf, 1);
1074 buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
1075 nxt200x_writereg_multibyte(state, 0x82, buf, 3);
1076
1077 nxt200x_readreg_multibyte(state, 0x88, buf, 1);
1078 buf[0] = 0x11;
1079 nxt200x_writereg_multibyte(state, 0x88, buf, 1);
1080
1081 nxt200x_readreg_multibyte(state, 0x80, buf, 1);
1082 buf[0] = 0x44;
1083 nxt200x_writereg_multibyte(state, 0x80, buf, 1);
1084
1085 /* initialize tuner */
1086 nxt200x_readbytes(state, 0x10, buf, 1);
1087 buf[0] = 0x12;
1088 nxt200x_writebytes(state, 0x10, buf, 1);
1089 buf[0] = 0x04;
1090 nxt200x_writebytes(state, 0x13, buf, 1);
1091 buf[0] = 0x00;
1092 nxt200x_writebytes(state, 0x16, buf, 1);
1093 buf[0] = 0x04;
1094 nxt200x_writebytes(state, 0x14, buf, 1);
1095 buf[0] = 0x00;
1096 nxt200x_writebytes(state, 0x14, buf, 1);
1097 nxt200x_writebytes(state, 0x17, buf, 1);
1098 nxt200x_writebytes(state, 0x14, buf, 1);
1099 nxt200x_writebytes(state, 0x17, buf, 1);
1100
1101 return 0;
1102}
1103
1104static int nxt200x_init(struct dvb_frontend* fe)
1105{
1106 struct nxt200x_state* state = fe->demodulator_priv;
1107 int ret = 0;
1108
1109 if (!state->initialised) {
1110 switch (state->demod_chip) {
1111 case NXT2002:
1112 ret = nxt2002_init(fe);
1113 break;
1114 case NXT2004:
1115 ret = nxt2004_init(fe);
1116 break;
1117 default:
1118 return -EINVAL;
1119 break;
1120 }
1121 state->initialised = 1;
1122 }
1123 return ret;
1124}
1125
1126static int nxt200x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1127{
1128 fesettings->min_delay_ms = 500;
1129 fesettings->step_size = 0;
1130 fesettings->max_drift = 0;
1131 return 0;
1132}
1133
1134static void nxt200x_release(struct dvb_frontend* fe)
1135{
1136 struct nxt200x_state* state = fe->demodulator_priv;
1137 kfree(state);
1138}
1139
1140static struct dvb_frontend_ops nxt200x_ops;
1141
1142struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
1143 struct i2c_adapter* i2c)
1144{
1145 struct nxt200x_state* state = NULL;
1146 u8 buf [] = {0,0,0,0,0};
1147
1148 /* allocate memory for the internal state */
1149 state = kzalloc(sizeof(struct nxt200x_state), GFP_KERNEL);
1150 if (state == NULL)
1151 goto error;
1152
1153 /* setup the state */
1154 state->config = config;
1155 state->i2c = i2c;
1156 state->initialised = 0;
1157
1158 /* read card id */
1159 nxt200x_readbytes(state, 0x00, buf, 5);
1160 dprintk("NXT info: %02X %02X %02X %02X %02X\n",
1161 buf[0], buf[1], buf[2], buf[3], buf[4]);
1162
1163 /* set demod chip */
1164 switch (buf[0]) {
1165 case 0x04:
1166 state->demod_chip = NXT2002;
1167 printk("nxt200x: NXT2002 Detected\n");
1168 break;
1169 case 0x05:
1170 state->demod_chip = NXT2004;
1171 printk("nxt200x: NXT2004 Detected\n");
1172 break;
1173 default:
1174 goto error;
1175 }
1176
1177 /* make sure demod chip is supported */
1178 switch (state->demod_chip) {
1179 case NXT2002:
1180 if (buf[0] != 0x04) goto error; /* device id */
1181 if (buf[1] != 0x02) goto error; /* fab id */
1182 if (buf[2] != 0x11) goto error; /* month */
1183 if (buf[3] != 0x20) goto error; /* year msb */
1184 if (buf[4] != 0x00) goto error; /* year lsb */
1185 break;
1186 case NXT2004:
1187 if (buf[0] != 0x05) goto error; /* device id */
1188 break;
1189 default:
1190 goto error;
1191 }
1192
1193 /* create dvb_frontend */
1194 memcpy(&state->frontend.ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops));
1195 state->frontend.demodulator_priv = state;
1196 return &state->frontend;
1197
1198error:
1199 kfree(state);
1200 printk("Unknown/Unsupported NXT chip: %02X %02X %02X %02X %02X\n",
1201 buf[0], buf[1], buf[2], buf[3], buf[4]);
1202 return NULL;
1203}
1204
1205static struct dvb_frontend_ops nxt200x_ops = {
1206
1207 .info = {
1208 .name = "Nextwave NXT200X VSB/QAM frontend",
1209 .type = FE_ATSC,
1210 .frequency_min = 54000000,
1211 .frequency_max = 860000000,
1212 .frequency_stepsize = 166666, /* stepsize is just a guess */
1213 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1214 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1215 FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
1216 },
1217
1218 .release = nxt200x_release,
1219
1220 .init = nxt200x_init,
1221 .sleep = nxt200x_sleep,
1222
1223 .set_frontend = nxt200x_setup_frontend_parameters,
1224 .get_tune_settings = nxt200x_get_tune_settings,
1225
1226 .read_status = nxt200x_read_status,
1227 .read_ber = nxt200x_read_ber,
1228 .read_signal_strength = nxt200x_read_signal_strength,
1229 .read_snr = nxt200x_read_snr,
1230 .read_ucblocks = nxt200x_read_ucblocks,
1231};
1232
1233module_param(debug, int, 0644);
1234MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1235
1236MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
1237MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob");
1238MODULE_LICENSE("GPL");
1239
1240EXPORT_SYMBOL(nxt200x_attach);
1241
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h
new file mode 100644
index 00000000000..f3c84583770
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt200x.h
@@ -0,0 +1,63 @@
1/*
2 * Support for NXT2002 and NXT2004 - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com)
5 * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
6 * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.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
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 NXT200X_H
25#define NXT200X_H
26
27#include <linux/dvb/frontend.h>
28#include <linux/firmware.h>
29
30typedef enum nxt_chip_t {
31 NXTUNDEFINED,
32 NXT2002,
33 NXT2004
34}nxt_chip_type;
35
36struct nxt200x_config
37{
38 /* the demodulator's i2c address */
39 u8 demod_address;
40
41 /* need to set device param for start_dma */
42 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
43};
44
45#if defined(CONFIG_DVB_NXT200X) || (defined(CONFIG_DVB_NXT200X_MODULE) && defined(MODULE))
46extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
47 struct i2c_adapter* i2c);
48#else
49static inline struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
50 struct i2c_adapter* i2c)
51{
52 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
53 return NULL;
54}
55#endif // CONFIG_DVB_NXT200X
56
57#endif /* NXT200X_H */
58
59/*
60 * Local variables:
61 * c-basic-offset: 8
62 * End:
63 */
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c
new file mode 100644
index 00000000000..6599b8fea9e
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt6000.c
@@ -0,0 +1,610 @@
1/*
2 NxtWave Communications - NXT6000 demodulator driver
3
4 Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
5 Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
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#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/slab.h>
27
28#include "dvb_frontend.h"
29#include "nxt6000_priv.h"
30#include "nxt6000.h"
31
32
33
34struct nxt6000_state {
35 struct i2c_adapter* i2c;
36 /* configuration settings */
37 const struct nxt6000_config* config;
38 struct dvb_frontend frontend;
39};
40
41static int debug;
42#define dprintk if (debug) printk
43
44static int nxt6000_writereg(struct nxt6000_state* state, u8 reg, u8 data)
45{
46 u8 buf[] = { reg, data };
47 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };
48 int ret;
49
50 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
51 dprintk("nxt6000: nxt6000_write error (reg: 0x%02X, data: 0x%02X, ret: %d)\n", reg, data, ret);
52
53 return (ret != 1) ? -EIO : 0;
54}
55
56static u8 nxt6000_readreg(struct nxt6000_state* state, u8 reg)
57{
58 int ret;
59 u8 b0[] = { reg };
60 u8 b1[] = { 0 };
61 struct i2c_msg msgs[] = {
62 {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
63 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
64 };
65
66 ret = i2c_transfer(state->i2c, msgs, 2);
67
68 if (ret != 2)
69 dprintk("nxt6000: nxt6000_read error (reg: 0x%02X, ret: %d)\n", reg, ret);
70
71 return b1[0];
72}
73
74static void nxt6000_reset(struct nxt6000_state* state)
75{
76 u8 val;
77
78 val = nxt6000_readreg(state, OFDM_COR_CTL);
79
80 nxt6000_writereg(state, OFDM_COR_CTL, val & ~COREACT);
81 nxt6000_writereg(state, OFDM_COR_CTL, val | COREACT);
82}
83
84static int nxt6000_set_bandwidth(struct nxt6000_state* state, fe_bandwidth_t bandwidth)
85{
86 u16 nominal_rate;
87 int result;
88
89 switch (bandwidth) {
90
91 case BANDWIDTH_6_MHZ:
92 nominal_rate = 0x55B7;
93 break;
94
95 case BANDWIDTH_7_MHZ:
96 nominal_rate = 0x6400;
97 break;
98
99 case BANDWIDTH_8_MHZ:
100 nominal_rate = 0x7249;
101 break;
102
103 default:
104 return -EINVAL;
105 }
106
107 if ((result = nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, nominal_rate & 0xFF)) < 0)
108 return result;
109
110 return nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, (nominal_rate >> 8) & 0xFF);
111}
112
113static int nxt6000_set_guard_interval(struct nxt6000_state* state, fe_guard_interval_t guard_interval)
114{
115 switch (guard_interval) {
116
117 case GUARD_INTERVAL_1_32:
118 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x00 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
119
120 case GUARD_INTERVAL_1_16:
121 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x01 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
122
123 case GUARD_INTERVAL_AUTO:
124 case GUARD_INTERVAL_1_8:
125 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x02 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
126
127 case GUARD_INTERVAL_1_4:
128 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x03 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
129
130 default:
131 return -EINVAL;
132 }
133}
134
135static int nxt6000_set_inversion(struct nxt6000_state* state, fe_spectral_inversion_t inversion)
136{
137 switch (inversion) {
138
139 case INVERSION_OFF:
140 return nxt6000_writereg(state, OFDM_ITB_CTL, 0x00);
141
142 case INVERSION_ON:
143 return nxt6000_writereg(state, OFDM_ITB_CTL, ITBINV);
144
145 default:
146 return -EINVAL;
147
148 }
149}
150
151static int nxt6000_set_transmission_mode(struct nxt6000_state* state, fe_transmit_mode_t transmission_mode)
152{
153 int result;
154
155 switch (transmission_mode) {
156
157 case TRANSMISSION_MODE_2K:
158 if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x00 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
159 return result;
160
161 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x00 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
162
163 case TRANSMISSION_MODE_8K:
164 case TRANSMISSION_MODE_AUTO:
165 if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x02 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
166 return result;
167
168 return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x01 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
169
170 default:
171 return -EINVAL;
172
173 }
174}
175
176static void nxt6000_setup(struct dvb_frontend* fe)
177{
178 struct nxt6000_state* state = fe->demodulator_priv;
179
180 nxt6000_writereg(state, RS_COR_SYNC_PARAM, SYNC_PARAM);
181 nxt6000_writereg(state, BER_CTRL, /*(1 << 2) | */ (0x01 << 1) | 0x01);
182 nxt6000_writereg(state, VIT_BERTIME_2, 0x00); // BER Timer = 0x000200 * 256 = 131072 bits
183 nxt6000_writereg(state, VIT_BERTIME_1, 0x02); //
184 nxt6000_writereg(state, VIT_BERTIME_0, 0x00); //
185 nxt6000_writereg(state, VIT_COR_INTEN, 0x98); // Enable BER interrupts
186 nxt6000_writereg(state, VIT_COR_CTL, 0x82); // Enable BER measurement
187 nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC | 0x02 );
188 nxt6000_writereg(state, OFDM_COR_CTL, (0x01 << 5) | (nxt6000_readreg(state, OFDM_COR_CTL) & 0x0F));
189 nxt6000_writereg(state, OFDM_COR_MODEGUARD, FORCEMODE8K | 0x02);
190 nxt6000_writereg(state, OFDM_AGC_CTL, AGCLAST | INITIAL_AGC_BW);
191 nxt6000_writereg(state, OFDM_ITB_FREQ_1, 0x06);
192 nxt6000_writereg(state, OFDM_ITB_FREQ_2, 0x31);
193 nxt6000_writereg(state, OFDM_CAS_CTL, (0x01 << 7) | (0x02 << 3) | 0x04);
194 nxt6000_writereg(state, CAS_FREQ, 0xBB); /* CHECKME */
195 nxt6000_writereg(state, OFDM_SYR_CTL, 1 << 2);
196 nxt6000_writereg(state, OFDM_PPM_CTL_1, PPM256);
197 nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, 0x49);
198 nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, 0x72);
199 nxt6000_writereg(state, ANALOG_CONTROL_0, 1 << 5);
200 nxt6000_writereg(state, EN_DMD_RACQ, (1 << 7) | (3 << 4) | 2);
201 nxt6000_writereg(state, DIAG_CONFIG, TB_SET);
202
203 if (state->config->clock_inversion)
204 nxt6000_writereg(state, SUB_DIAG_MODE_SEL, CLKINVERSION);
205 else
206 nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0);
207
208 nxt6000_writereg(state, TS_FORMAT, 0);
209}
210
211static void nxt6000_dump_status(struct nxt6000_state *state)
212{
213 u8 val;
214
215/*
216 printk("RS_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, RS_COR_STAT));
217 printk("VIT_SYNC_STATUS: 0x%02X\n", nxt6000_readreg(fe, VIT_SYNC_STATUS));
218 printk("OFDM_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_COR_STAT));
219 printk("OFDM_SYR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_SYR_STAT));
220 printk("OFDM_TPS_RCVD_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_1));
221 printk("OFDM_TPS_RCVD_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_2));
222 printk("OFDM_TPS_RCVD_3: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_3));
223 printk("OFDM_TPS_RCVD_4: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_4));
224 printk("OFDM_TPS_RESERVED_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_1));
225 printk("OFDM_TPS_RESERVED_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_2));
226*/
227 printk("NXT6000 status:");
228
229 val = nxt6000_readreg(state, RS_COR_STAT);
230
231 printk(" DATA DESCR LOCK: %d,", val & 0x01);
232 printk(" DATA SYNC LOCK: %d,", (val >> 1) & 0x01);
233
234 val = nxt6000_readreg(state, VIT_SYNC_STATUS);
235
236 printk(" VITERBI LOCK: %d,", (val >> 7) & 0x01);
237
238 switch ((val >> 4) & 0x07) {
239
240 case 0x00:
241 printk(" VITERBI CODERATE: 1/2,");
242 break;
243
244 case 0x01:
245 printk(" VITERBI CODERATE: 2/3,");
246 break;
247
248 case 0x02:
249 printk(" VITERBI CODERATE: 3/4,");
250 break;
251
252 case 0x03:
253 printk(" VITERBI CODERATE: 5/6,");
254 break;
255
256 case 0x04:
257 printk(" VITERBI CODERATE: 7/8,");
258 break;
259
260 default:
261 printk(" VITERBI CODERATE: Reserved,");
262
263 }
264
265 val = nxt6000_readreg(state, OFDM_COR_STAT);
266
267 printk(" CHCTrack: %d,", (val >> 7) & 0x01);
268 printk(" TPSLock: %d,", (val >> 6) & 0x01);
269 printk(" SYRLock: %d,", (val >> 5) & 0x01);
270 printk(" AGCLock: %d,", (val >> 4) & 0x01);
271
272 switch (val & 0x0F) {
273
274 case 0x00:
275 printk(" CoreState: IDLE,");
276 break;
277
278 case 0x02:
279 printk(" CoreState: WAIT_AGC,");
280 break;
281
282 case 0x03:
283 printk(" CoreState: WAIT_SYR,");
284 break;
285
286 case 0x04:
287 printk(" CoreState: WAIT_PPM,");
288 break;
289
290 case 0x01:
291 printk(" CoreState: WAIT_TRL,");
292 break;
293
294 case 0x05:
295 printk(" CoreState: WAIT_TPS,");
296 break;
297
298 case 0x06:
299 printk(" CoreState: MONITOR_TPS,");
300 break;
301
302 default:
303 printk(" CoreState: Reserved,");
304
305 }
306
307 val = nxt6000_readreg(state, OFDM_SYR_STAT);
308
309 printk(" SYRLock: %d,", (val >> 4) & 0x01);
310 printk(" SYRMode: %s,", (val >> 2) & 0x01 ? "8K" : "2K");
311
312 switch ((val >> 4) & 0x03) {
313
314 case 0x00:
315 printk(" SYRGuard: 1/32,");
316 break;
317
318 case 0x01:
319 printk(" SYRGuard: 1/16,");
320 break;
321
322 case 0x02:
323 printk(" SYRGuard: 1/8,");
324 break;
325
326 case 0x03:
327 printk(" SYRGuard: 1/4,");
328 break;
329 }
330
331 val = nxt6000_readreg(state, OFDM_TPS_RCVD_3);
332
333 switch ((val >> 4) & 0x07) {
334
335 case 0x00:
336 printk(" TPSLP: 1/2,");
337 break;
338
339 case 0x01:
340 printk(" TPSLP: 2/3,");
341 break;
342
343 case 0x02:
344 printk(" TPSLP: 3/4,");
345 break;
346
347 case 0x03:
348 printk(" TPSLP: 5/6,");
349 break;
350
351 case 0x04:
352 printk(" TPSLP: 7/8,");
353 break;
354
355 default:
356 printk(" TPSLP: Reserved,");
357
358 }
359
360 switch (val & 0x07) {
361
362 case 0x00:
363 printk(" TPSHP: 1/2,");
364 break;
365
366 case 0x01:
367 printk(" TPSHP: 2/3,");
368 break;
369
370 case 0x02:
371 printk(" TPSHP: 3/4,");
372 break;
373
374 case 0x03:
375 printk(" TPSHP: 5/6,");
376 break;
377
378 case 0x04:
379 printk(" TPSHP: 7/8,");
380 break;
381
382 default:
383 printk(" TPSHP: Reserved,");
384
385 }
386
387 val = nxt6000_readreg(state, OFDM_TPS_RCVD_4);
388
389 printk(" TPSMode: %s,", val & 0x01 ? "8K" : "2K");
390
391 switch ((val >> 4) & 0x03) {
392
393 case 0x00:
394 printk(" TPSGuard: 1/32,");
395 break;
396
397 case 0x01:
398 printk(" TPSGuard: 1/16,");
399 break;
400
401 case 0x02:
402 printk(" TPSGuard: 1/8,");
403 break;
404
405 case 0x03:
406 printk(" TPSGuard: 1/4,");
407 break;
408
409 }
410
411 /* Strange magic required to gain access to RF_AGC_STATUS */
412 nxt6000_readreg(state, RF_AGC_VAL_1);
413 val = nxt6000_readreg(state, RF_AGC_STATUS);
414 val = nxt6000_readreg(state, RF_AGC_STATUS);
415
416 printk(" RF AGC LOCK: %d,", (val >> 4) & 0x01);
417 printk("\n");
418}
419
420static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status)
421{
422 u8 core_status;
423 struct nxt6000_state* state = fe->demodulator_priv;
424
425 *status = 0;
426
427 core_status = nxt6000_readreg(state, OFDM_COR_STAT);
428
429 if (core_status & AGCLOCKED)
430 *status |= FE_HAS_SIGNAL;
431
432 if (nxt6000_readreg(state, OFDM_SYR_STAT) & GI14_SYR_LOCK)
433 *status |= FE_HAS_CARRIER;
434
435 if (nxt6000_readreg(state, VIT_SYNC_STATUS) & VITINSYNC)
436 *status |= FE_HAS_VITERBI;
437
438 if (nxt6000_readreg(state, RS_COR_STAT) & RSCORESTATUS)
439 *status |= FE_HAS_SYNC;
440
441 if ((core_status & TPSLOCKED) && (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)))
442 *status |= FE_HAS_LOCK;
443
444 if (debug)
445 nxt6000_dump_status(state);
446
447 return 0;
448}
449
450static int nxt6000_init(struct dvb_frontend* fe)
451{
452 struct nxt6000_state* state = fe->demodulator_priv;
453
454 nxt6000_reset(state);
455 nxt6000_setup(fe);
456
457 return 0;
458}
459
460static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *param)
461{
462 struct nxt6000_state* state = fe->demodulator_priv;
463 int result;
464
465 if (fe->ops.tuner_ops.set_params) {
466 fe->ops.tuner_ops.set_params(fe, param);
467 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
468 }
469
470 if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0)
471 return result;
472 if ((result = nxt6000_set_guard_interval(state, param->u.ofdm.guard_interval)) < 0)
473 return result;
474 if ((result = nxt6000_set_transmission_mode(state, param->u.ofdm.transmission_mode)) < 0)
475 return result;
476 if ((result = nxt6000_set_inversion(state, param->inversion)) < 0)
477 return result;
478
479 msleep(500);
480 return 0;
481}
482
483static void nxt6000_release(struct dvb_frontend* fe)
484{
485 struct nxt6000_state* state = fe->demodulator_priv;
486 kfree(state);
487}
488
489static int nxt6000_read_snr(struct dvb_frontend* fe, u16* snr)
490{
491 struct nxt6000_state* state = fe->demodulator_priv;
492
493 *snr = nxt6000_readreg( state, OFDM_CHC_SNR) / 8;
494
495 return 0;
496}
497
498static int nxt6000_read_ber(struct dvb_frontend* fe, u32* ber)
499{
500 struct nxt6000_state* state = fe->demodulator_priv;
501
502 nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18 );
503
504 *ber = (nxt6000_readreg( state, VIT_BER_1 ) << 8 ) |
505 nxt6000_readreg( state, VIT_BER_0 );
506
507 nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18); // Clear BER Done interrupts
508
509 return 0;
510}
511
512static int nxt6000_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
513{
514 struct nxt6000_state* state = fe->demodulator_priv;
515
516 *signal_strength = (short) (511 -
517 (nxt6000_readreg(state, AGC_GAIN_1) +
518 ((nxt6000_readreg(state, AGC_GAIN_2) & 0x03) << 8)));
519
520 return 0;
521}
522
523static int nxt6000_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
524{
525 tune->min_delay_ms = 500;
526 return 0;
527}
528
529static int nxt6000_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
530{
531 struct nxt6000_state* state = fe->demodulator_priv;
532
533 if (enable) {
534 return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01);
535 } else {
536 return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00);
537 }
538}
539
540static struct dvb_frontend_ops nxt6000_ops;
541
542struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
543 struct i2c_adapter* i2c)
544{
545 struct nxt6000_state* state = NULL;
546
547 /* allocate memory for the internal state */
548 state = kzalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
549 if (state == NULL) goto error;
550
551 /* setup the state */
552 state->config = config;
553 state->i2c = i2c;
554
555 /* check if the demod is there */
556 if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error;
557
558 /* create dvb_frontend */
559 memcpy(&state->frontend.ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops));
560 state->frontend.demodulator_priv = state;
561 return &state->frontend;
562
563error:
564 kfree(state);
565 return NULL;
566}
567
568static struct dvb_frontend_ops nxt6000_ops = {
569
570 .info = {
571 .name = "NxtWave NXT6000 DVB-T",
572 .type = FE_OFDM,
573 .frequency_min = 0,
574 .frequency_max = 863250000,
575 .frequency_stepsize = 62500,
576 /*.frequency_tolerance = *//* FIXME: 12% of SR */
577 .symbol_rate_min = 0, /* FIXME */
578 .symbol_rate_max = 9360000, /* FIXME */
579 .symbol_rate_tolerance = 4000,
580 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
581 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
582 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
583 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
584 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
585 FE_CAN_HIERARCHY_AUTO,
586 },
587
588 .release = nxt6000_release,
589
590 .init = nxt6000_init,
591 .i2c_gate_ctrl = nxt6000_i2c_gate_ctrl,
592
593 .get_tune_settings = nxt6000_fe_get_tune_settings,
594
595 .set_frontend = nxt6000_set_frontend,
596
597 .read_status = nxt6000_read_status,
598 .read_ber = nxt6000_read_ber,
599 .read_signal_strength = nxt6000_read_signal_strength,
600 .read_snr = nxt6000_read_snr,
601};
602
603module_param(debug, int, 0644);
604MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
605
606MODULE_DESCRIPTION("NxtWave NXT6000 DVB-T demodulator driver");
607MODULE_AUTHOR("Florian Schirmer");
608MODULE_LICENSE("GPL");
609
610EXPORT_SYMBOL(nxt6000_attach);
diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h
new file mode 100644
index 00000000000..878eb38a075
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt6000.h
@@ -0,0 +1,48 @@
1/*
2 NxtWave Communications - NXT6000 demodulator driver
3
4 Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
5 Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
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#ifndef NXT6000_H
23#define NXT6000_H
24
25#include <linux/dvb/frontend.h>
26
27struct nxt6000_config
28{
29 /* the demodulator's i2c address */
30 u8 demod_address;
31
32 /* should clock inversion be used? */
33 u8 clock_inversion:1;
34};
35
36#if defined(CONFIG_DVB_NXT6000) || (defined(CONFIG_DVB_NXT6000_MODULE) && defined(MODULE))
37extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
38 struct i2c_adapter* i2c);
39#else
40static inline struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
41 struct i2c_adapter* i2c)
42{
43 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
44 return NULL;
45}
46#endif // CONFIG_DVB_NXT6000
47
48#endif // NXT6000_H
diff --git a/drivers/media/dvb/frontends/nxt6000_priv.h b/drivers/media/dvb/frontends/nxt6000_priv.h
new file mode 100644
index 00000000000..0422e580038
--- /dev/null
+++ b/drivers/media/dvb/frontends/nxt6000_priv.h
@@ -0,0 +1,286 @@
1/*
2 * Public Include File for DRV6000 users
3 * (ie. NxtWave Communications - NXT6000 demodulator driver)
4 *
5 * Copyright (C) 2001 NxtWave Communications, Inc.
6 *
7 */
8
9/* Nxt6000 Register Addresses and Bit Masks */
10
11/* Maximum Register Number */
12#define MAXNXT6000REG (0x9A)
13
14/* 0x1B A_VIT_BER_0 aka 0x3A */
15#define A_VIT_BER_0 (0x1B)
16
17/* 0x1D A_VIT_BER_TIMER_0 aka 0x38 */
18#define A_VIT_BER_TIMER_0 (0x1D)
19
20/* 0x21 RS_COR_STAT */
21#define RS_COR_STAT (0x21)
22#define RSCORESTATUS (0x03)
23
24/* 0x22 RS_COR_INTEN */
25#define RS_COR_INTEN (0x22)
26
27/* 0x23 RS_COR_INSTAT */
28#define RS_COR_INSTAT (0x23)
29#define INSTAT_ERROR (0x04)
30#define LOCK_LOSS_BITS (0x03)
31
32/* 0x24 RS_COR_SYNC_PARAM */
33#define RS_COR_SYNC_PARAM (0x24)
34#define SYNC_PARAM (0x03)
35
36/* 0x25 BER_CTRL */
37#define BER_CTRL (0x25)
38#define BER_ENABLE (0x02)
39#define BER_RESET (0x01)
40
41/* 0x26 BER_PAY */
42#define BER_PAY (0x26)
43
44/* 0x27 BER_PKT_L */
45#define BER_PKT_L (0x27)
46#define BER_PKTOVERFLOW (0x80)
47
48/* 0x30 VIT_COR_CTL */
49#define VIT_COR_CTL (0x30)
50#define BER_CONTROL (0x02)
51#define VIT_COR_MASK (0x82)
52#define VIT_COR_RESYNC (0x80)
53
54
55/* 0x32 VIT_SYNC_STATUS */
56#define VIT_SYNC_STATUS (0x32)
57#define VITINSYNC (0x80)
58
59/* 0x33 VIT_COR_INTEN */
60#define VIT_COR_INTEN (0x33)
61#define GLOBAL_ENABLE (0x80)
62
63/* 0x34 VIT_COR_INTSTAT */
64#define VIT_COR_INTSTAT (0x34)
65#define BER_DONE (0x08)
66#define BER_OVERFLOW (0x10)
67
68/* 0x38 VIT_BERTIME_2 */
69#define VIT_BERTIME_2 (0x38)
70
71/* 0x39 VIT_BERTIME_1 */
72#define VIT_BERTIME_1 (0x39)
73
74/* 0x3A VIT_BERTIME_0 */
75#define VIT_BERTIME_0 (0x3a)
76
77 /* 0x38 OFDM_BERTimer *//* Use the alias registers */
78#define A_VIT_BER_TIMER_0 (0x1D)
79
80 /* 0x3A VIT_BER_TIMER_0 *//* Use the alias registers */
81#define A_VIT_BER_0 (0x1B)
82
83/* 0x3B VIT_BER_1 */
84#define VIT_BER_1 (0x3b)
85
86/* 0x3C VIT_BER_0 */
87#define VIT_BER_0 (0x3c)
88
89/* 0x40 OFDM_COR_CTL */
90#define OFDM_COR_CTL (0x40)
91#define COREACT (0x20)
92#define HOLDSM (0x10)
93#define WAIT_AGC (0x02)
94#define WAIT_SYR (0x03)
95
96/* 0x41 OFDM_COR_STAT */
97#define OFDM_COR_STAT (0x41)
98#define COR_STATUS (0x0F)
99#define MONITOR_TPS (0x06)
100#define TPSLOCKED (0x40)
101#define AGCLOCKED (0x10)
102
103/* 0x42 OFDM_COR_INTEN */
104#define OFDM_COR_INTEN (0x42)
105#define TPSRCVBAD (0x04)
106#define TPSRCVCHANGED (0x02)
107#define TPSRCVUPDATE (0x01)
108
109/* 0x43 OFDM_COR_INSTAT */
110#define OFDM_COR_INSTAT (0x43)
111
112/* 0x44 OFDM_COR_MODEGUARD */
113#define OFDM_COR_MODEGUARD (0x44)
114#define FORCEMODE (0x08)
115#define FORCEMODE8K (0x04)
116
117/* 0x45 OFDM_AGC_CTL */
118#define OFDM_AGC_CTL (0x45)
119#define INITIAL_AGC_BW (0x08)
120#define AGCNEG (0x02)
121#define AGCLAST (0x10)
122
123/* 0x48 OFDM_AGC_TARGET */
124#define OFDM_AGC_TARGET (0x48)
125#define OFDM_AGC_TARGET_DEFAULT (0x28)
126#define OFDM_AGC_TARGET_IMPULSE (0x38)
127
128/* 0x49 OFDM_AGC_GAIN_1 */
129#define OFDM_AGC_GAIN_1 (0x49)
130
131/* 0x4B OFDM_ITB_CTL */
132#define OFDM_ITB_CTL (0x4B)
133#define ITBINV (0x01)
134
135/* 0x49 AGC_GAIN_1 */
136#define AGC_GAIN_1 (0x49)
137
138/* 0x4A AGC_GAIN_2 */
139#define AGC_GAIN_2 (0x4A)
140
141/* 0x4C OFDM_ITB_FREQ_1 */
142#define OFDM_ITB_FREQ_1 (0x4C)
143
144/* 0x4D OFDM_ITB_FREQ_2 */
145#define OFDM_ITB_FREQ_2 (0x4D)
146
147/* 0x4E OFDM_CAS_CTL */
148#define OFDM_CAS_CTL (0x4E)
149#define ACSDIS (0x40)
150#define CCSEN (0x80)
151
152/* 0x4F CAS_FREQ */
153#define CAS_FREQ (0x4F)
154
155/* 0x51 OFDM_SYR_CTL */
156#define OFDM_SYR_CTL (0x51)
157#define SIXTH_ENABLE (0x80)
158#define SYR_TRACKING_DISABLE (0x01)
159
160/* 0x52 OFDM_SYR_STAT */
161#define OFDM_SYR_STAT (0x52)
162#define GI14_2K_SYR_LOCK (0x13)
163#define GI14_8K_SYR_LOCK (0x17)
164#define GI14_SYR_LOCK (0x10)
165
166/* 0x55 OFDM_SYR_OFFSET_1 */
167#define OFDM_SYR_OFFSET_1 (0x55)
168
169/* 0x56 OFDM_SYR_OFFSET_2 */
170#define OFDM_SYR_OFFSET_2 (0x56)
171
172/* 0x58 OFDM_SCR_CTL */
173#define OFDM_SCR_CTL (0x58)
174#define SYR_ADJ_DECAY_MASK (0x70)
175#define SYR_ADJ_DECAY (0x30)
176
177/* 0x59 OFDM_PPM_CTL_1 */
178#define OFDM_PPM_CTL_1 (0x59)
179#define PPMMAX_MASK (0x30)
180#define PPM256 (0x30)
181
182/* 0x5B OFDM_TRL_NOMINALRATE_1 */
183#define OFDM_TRL_NOMINALRATE_1 (0x5B)
184
185/* 0x5C OFDM_TRL_NOMINALRATE_2 */
186#define OFDM_TRL_NOMINALRATE_2 (0x5C)
187
188/* 0x5D OFDM_TRL_TIME_1 */
189#define OFDM_TRL_TIME_1 (0x5D)
190
191/* 0x60 OFDM_CRL_FREQ_1 */
192#define OFDM_CRL_FREQ_1 (0x60)
193
194/* 0x63 OFDM_CHC_CTL_1 */
195#define OFDM_CHC_CTL_1 (0x63)
196#define MANMEAN1 (0xF0);
197#define CHCFIR (0x01)
198
199/* 0x64 OFDM_CHC_SNR */
200#define OFDM_CHC_SNR (0x64)
201
202/* 0x65 OFDM_BDI_CTL */
203#define OFDM_BDI_CTL (0x65)
204#define LP_SELECT (0x02)
205
206/* 0x67 OFDM_TPS_RCVD_1 */
207#define OFDM_TPS_RCVD_1 (0x67)
208#define TPSFRAME (0x03)
209
210/* 0x68 OFDM_TPS_RCVD_2 */
211#define OFDM_TPS_RCVD_2 (0x68)
212
213/* 0x69 OFDM_TPS_RCVD_3 */
214#define OFDM_TPS_RCVD_3 (0x69)
215
216/* 0x6A OFDM_TPS_RCVD_4 */
217#define OFDM_TPS_RCVD_4 (0x6A)
218
219/* 0x6B OFDM_TPS_RESERVED_1 */
220#define OFDM_TPS_RESERVED_1 (0x6B)
221
222/* 0x6C OFDM_TPS_RESERVED_2 */
223#define OFDM_TPS_RESERVED_2 (0x6C)
224
225/* 0x73 OFDM_MSC_REV */
226#define OFDM_MSC_REV (0x73)
227
228/* 0x76 OFDM_SNR_CARRIER_2 */
229#define OFDM_SNR_CARRIER_2 (0x76)
230#define MEAN_MASK (0x80)
231#define MEANBIT (0x80)
232
233/* 0x80 ANALOG_CONTROL_0 */
234#define ANALOG_CONTROL_0 (0x80)
235#define POWER_DOWN_ADC (0x40)
236
237/* 0x81 ENABLE_TUNER_IIC */
238#define ENABLE_TUNER_IIC (0x81)
239#define ENABLE_TUNER_BIT (0x01)
240
241/* 0x82 EN_DMD_RACQ */
242#define EN_DMD_RACQ (0x82)
243#define EN_DMD_RACQ_REG_VAL (0x81)
244#define EN_DMD_RACQ_REG_VAL_14 (0x01)
245
246/* 0x84 SNR_COMMAND */
247#define SNR_COMMAND (0x84)
248#define SNRStat (0x80)
249
250/* 0x85 SNRCARRIERNUMBER_LSB */
251#define SNRCARRIERNUMBER_LSB (0x85)
252
253/* 0x87 SNRMINTHRESHOLD_LSB */
254#define SNRMINTHRESHOLD_LSB (0x87)
255
256/* 0x89 SNR_PER_CARRIER_LSB */
257#define SNR_PER_CARRIER_LSB (0x89)
258
259/* 0x8B SNRBELOWTHRESHOLD_LSB */
260#define SNRBELOWTHRESHOLD_LSB (0x8B)
261
262/* 0x91 RF_AGC_VAL_1 */
263#define RF_AGC_VAL_1 (0x91)
264
265/* 0x92 RF_AGC_STATUS */
266#define RF_AGC_STATUS (0x92)
267
268/* 0x98 DIAG_CONFIG */
269#define DIAG_CONFIG (0x98)
270#define DIAG_MASK (0x70)
271#define TB_SET (0x10)
272#define TRAN_SELECT (0x07)
273#define SERIAL_SELECT (0x01)
274
275/* 0x99 SUB_DIAG_MODE_SEL */
276#define SUB_DIAG_MODE_SEL (0x99)
277#define CLKINVERSION (0x01)
278
279/* 0x9A TS_FORMAT */
280#define TS_FORMAT (0x9A)
281#define ERROR_SENSE (0x08)
282#define VALID_SENSE (0x04)
283#define SYNC_SENSE (0x02)
284#define GATED_CLOCK (0x01)
285
286#define NXT6000ASICDEVICE (0x0b)
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c
new file mode 100644
index 00000000000..38e67accb8c
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51132.c
@@ -0,0 +1,625 @@
1/*
2 * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM
3 *
4 *
5 * Copyright (C) 2007 Trent Piepho <xyzzy@speakeasy.org>
6 *
7 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
8 *
9 * Based on code from Jack Kelliher (kelliher@xmission.com)
10 * Copyright (C) 2002 & pcHDTV, inc.
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, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26*/
27
28/*
29 * This driver needs two external firmware files. Please copy
30 * "dvb-fe-or51132-vsb.fw" and "dvb-fe-or51132-qam.fw" to
31 * /usr/lib/hotplug/firmware/ or /lib/firmware/
32 * (depending on configuration of firmware hotplug).
33 */
34#define OR51132_VSB_FIRMWARE "dvb-fe-or51132-vsb.fw"
35#define OR51132_QAM_FIRMWARE "dvb-fe-or51132-qam.fw"
36
37#include <linux/kernel.h>
38#include <linux/module.h>
39#include <linux/init.h>
40#include <linux/delay.h>
41#include <linux/string.h>
42#include <linux/slab.h>
43#include <asm/byteorder.h>
44
45#include "dvb_math.h"
46#include "dvb_frontend.h"
47#include "or51132.h"
48
49static int debug;
50#define dprintk(args...) \
51 do { \
52 if (debug) printk(KERN_DEBUG "or51132: " args); \
53 } while (0)
54
55
56struct or51132_state
57{
58 struct i2c_adapter* i2c;
59
60 /* Configuration settings */
61 const struct or51132_config* config;
62
63 struct dvb_frontend frontend;
64
65 /* Demodulator private data */
66 fe_modulation_t current_modulation;
67 u32 snr; /* Result of last SNR calculation */
68
69 /* Tuner private data */
70 u32 current_frequency;
71};
72
73
74/* Write buffer to demod */
75static int or51132_writebuf(struct or51132_state *state, const u8 *buf, int len)
76{
77 int err;
78 struct i2c_msg msg = { .addr = state->config->demod_address,
79 .flags = 0, .buf = (u8*)buf, .len = len };
80
81 /* msleep(20); */ /* doesn't appear to be necessary */
82 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
83 printk(KERN_WARNING "or51132: I2C write (addr 0x%02x len %d) error: %d\n",
84 msg.addr, msg.len, err);
85 return -EREMOTEIO;
86 }
87 return 0;
88}
89
90/* Write constant bytes, e.g. or51132_writebytes(state, 0x04, 0x42, 0x00);
91 Less code and more efficient that loading a buffer on the stack with
92 the bytes to send and then calling or51132_writebuf() on that. */
93#define or51132_writebytes(state, data...) \
94 ({ static const u8 _data[] = {data}; \
95 or51132_writebuf(state, _data, sizeof(_data)); })
96
97/* Read data from demod into buffer. Returns 0 on success. */
98static int or51132_readbuf(struct or51132_state *state, u8 *buf, int len)
99{
100 int err;
101 struct i2c_msg msg = { .addr = state->config->demod_address,
102 .flags = I2C_M_RD, .buf = buf, .len = len };
103
104 /* msleep(20); */ /* doesn't appear to be necessary */
105 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
106 printk(KERN_WARNING "or51132: I2C read (addr 0x%02x len %d) error: %d\n",
107 msg.addr, msg.len, err);
108 return -EREMOTEIO;
109 }
110 return 0;
111}
112
113/* Reads a 16-bit demod register. Returns <0 on error. */
114static int or51132_readreg(struct or51132_state *state, u8 reg)
115{
116 u8 buf[2] = { 0x04, reg };
117 struct i2c_msg msg[2] = {
118 {.addr = state->config->demod_address, .flags = 0,
119 .buf = buf, .len = 2 },
120 {.addr = state->config->demod_address, .flags = I2C_M_RD,
121 .buf = buf, .len = 2 }};
122 int err;
123
124 if ((err = i2c_transfer(state->i2c, msg, 2)) != 2) {
125 printk(KERN_WARNING "or51132: I2C error reading register %d: %d\n",
126 reg, err);
127 return -EREMOTEIO;
128 }
129 return buf[0] | (buf[1] << 8);
130}
131
132static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
133{
134 struct or51132_state* state = fe->demodulator_priv;
135 static const u8 run_buf[] = {0x7F,0x01};
136 u8 rec_buf[8];
137 u32 firmwareAsize, firmwareBsize;
138 int i,ret;
139
140 dprintk("Firmware is %Zd bytes\n",fw->size);
141
142 /* Get size of firmware A and B */
143 firmwareAsize = le32_to_cpu(*((__le32*)fw->data));
144 dprintk("FirmwareA is %i bytes\n",firmwareAsize);
145 firmwareBsize = le32_to_cpu(*((__le32*)(fw->data+4)));
146 dprintk("FirmwareB is %i bytes\n",firmwareBsize);
147
148 /* Upload firmware */
149 if ((ret = or51132_writebuf(state, &fw->data[8], firmwareAsize))) {
150 printk(KERN_WARNING "or51132: load_firmware error 1\n");
151 return ret;
152 }
153 if ((ret = or51132_writebuf(state, &fw->data[8+firmwareAsize],
154 firmwareBsize))) {
155 printk(KERN_WARNING "or51132: load_firmware error 2\n");
156 return ret;
157 }
158
159 if ((ret = or51132_writebuf(state, run_buf, 2))) {
160 printk(KERN_WARNING "or51132: load_firmware error 3\n");
161 return ret;
162 }
163 if ((ret = or51132_writebuf(state, run_buf, 2))) {
164 printk(KERN_WARNING "or51132: load_firmware error 4\n");
165 return ret;
166 }
167
168 /* 50ms for operation to begin */
169 msleep(50);
170
171 /* Read back ucode version to besure we loaded correctly and are really up and running */
172 /* Get uCode version */
173 if ((ret = or51132_writebytes(state, 0x10, 0x10, 0x00))) {
174 printk(KERN_WARNING "or51132: load_firmware error a\n");
175 return ret;
176 }
177 if ((ret = or51132_writebytes(state, 0x04, 0x17))) {
178 printk(KERN_WARNING "or51132: load_firmware error b\n");
179 return ret;
180 }
181 if ((ret = or51132_writebytes(state, 0x00, 0x00))) {
182 printk(KERN_WARNING "or51132: load_firmware error c\n");
183 return ret;
184 }
185 for (i=0;i<4;i++) {
186 /* Once upon a time, this command might have had something
187 to do with getting the firmware version, but it's
188 not used anymore:
189 {0x04,0x00,0x30,0x00,i+1} */
190 /* Read 8 bytes, two bytes at a time */
191 if ((ret = or51132_readbuf(state, &rec_buf[i*2], 2))) {
192 printk(KERN_WARNING
193 "or51132: load_firmware error d - %d\n",i);
194 return ret;
195 }
196 }
197
198 printk(KERN_WARNING
199 "or51132: Version: %02X%02X%02X%02X-%02X%02X%02X%02X (%02X%01X-%01X-%02X%01X-%01X)\n",
200 rec_buf[1],rec_buf[0],rec_buf[3],rec_buf[2],
201 rec_buf[5],rec_buf[4],rec_buf[7],rec_buf[6],
202 rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f,
203 rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f);
204
205 if ((ret = or51132_writebytes(state, 0x10, 0x00, 0x00))) {
206 printk(KERN_WARNING "or51132: load_firmware error e\n");
207 return ret;
208 }
209 return 0;
210};
211
212static int or51132_init(struct dvb_frontend* fe)
213{
214 return 0;
215}
216
217static int or51132_read_ber(struct dvb_frontend* fe, u32* ber)
218{
219 *ber = 0;
220 return 0;
221}
222
223static int or51132_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
224{
225 *ucblocks = 0;
226 return 0;
227}
228
229static int or51132_sleep(struct dvb_frontend* fe)
230{
231 return 0;
232}
233
234static int or51132_setmode(struct dvb_frontend* fe)
235{
236 struct or51132_state* state = fe->demodulator_priv;
237 u8 cmd_buf1[3] = {0x04, 0x01, 0x5f};
238 u8 cmd_buf2[3] = {0x1c, 0x00, 0 };
239
240 dprintk("setmode %d\n",(int)state->current_modulation);
241
242 switch (state->current_modulation) {
243 case VSB_8:
244 /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high */
245 cmd_buf1[2] = 0x50;
246 /* REC MODE inv IF spectrum, Normal */
247 cmd_buf2[1] = 0x03;
248 /* Channel MODE ATSC/VSB8 */
249 cmd_buf2[2] = 0x06;
250 break;
251 /* All QAM modes are:
252 Auto-deinterleave; MPEGser, MPEG2tr, phase noise-high
253 REC MODE Normal Carrier Lock */
254 case QAM_AUTO:
255 /* Channel MODE Auto QAM64/256 */
256 cmd_buf2[2] = 0x4f;
257 break;
258 case QAM_256:
259 /* Channel MODE QAM256 */
260 cmd_buf2[2] = 0x45;
261 break;
262 case QAM_64:
263 /* Channel MODE QAM64 */
264 cmd_buf2[2] = 0x43;
265 break;
266 default:
267 printk(KERN_WARNING
268 "or51132: setmode: Modulation set to unsupported value (%d)\n",
269 state->current_modulation);
270 return -EINVAL;
271 }
272
273 /* Set Receiver 1 register */
274 if (or51132_writebuf(state, cmd_buf1, 3)) {
275 printk(KERN_WARNING "or51132: set_mode error 1\n");
276 return -EREMOTEIO;
277 }
278 dprintk("set #1 to %02x\n", cmd_buf1[2]);
279
280 /* Set operation mode in Receiver 6 register */
281 if (or51132_writebuf(state, cmd_buf2, 3)) {
282 printk(KERN_WARNING "or51132: set_mode error 2\n");
283 return -EREMOTEIO;
284 }
285 dprintk("set #6 to 0x%02x%02x\n", cmd_buf2[1], cmd_buf2[2]);
286
287 return 0;
288}
289
290/* Some modulations use the same firmware. This classifies modulations
291 by the firmware they use. */
292#define MOD_FWCLASS_UNKNOWN 0
293#define MOD_FWCLASS_VSB 1
294#define MOD_FWCLASS_QAM 2
295static int modulation_fw_class(fe_modulation_t modulation)
296{
297 switch(modulation) {
298 case VSB_8:
299 return MOD_FWCLASS_VSB;
300 case QAM_AUTO:
301 case QAM_64:
302 case QAM_256:
303 return MOD_FWCLASS_QAM;
304 default:
305 return MOD_FWCLASS_UNKNOWN;
306 }
307}
308
309static int or51132_set_parameters(struct dvb_frontend* fe,
310 struct dvb_frontend_parameters *param)
311{
312 int ret;
313 struct or51132_state* state = fe->demodulator_priv;
314 const struct firmware *fw;
315 const char *fwname;
316 int clock_mode;
317
318 /* Upload new firmware only if we need a different one */
319 if (modulation_fw_class(state->current_modulation) !=
320 modulation_fw_class(param->u.vsb.modulation)) {
321 switch(modulation_fw_class(param->u.vsb.modulation)) {
322 case MOD_FWCLASS_VSB:
323 dprintk("set_parameters VSB MODE\n");
324 fwname = OR51132_VSB_FIRMWARE;
325
326 /* Set non-punctured clock for VSB */
327 clock_mode = 0;
328 break;
329 case MOD_FWCLASS_QAM:
330 dprintk("set_parameters QAM MODE\n");
331 fwname = OR51132_QAM_FIRMWARE;
332
333 /* Set punctured clock for QAM */
334 clock_mode = 1;
335 break;
336 default:
337 printk("or51132: Modulation type(%d) UNSUPPORTED\n",
338 param->u.vsb.modulation);
339 return -1;
340 }
341 printk("or51132: Waiting for firmware upload(%s)...\n",
342 fwname);
343 ret = request_firmware(&fw, fwname, state->i2c->dev.parent);
344 if (ret) {
345 printk(KERN_WARNING "or51132: No firmware up"
346 "loaded(timeout or file not found?)\n");
347 return ret;
348 }
349 ret = or51132_load_firmware(fe, fw);
350 release_firmware(fw);
351 if (ret) {
352 printk(KERN_WARNING "or51132: Writing firmware to "
353 "device failed!\n");
354 return ret;
355 }
356 printk("or51132: Firmware upload complete.\n");
357 state->config->set_ts_params(fe, clock_mode);
358 }
359 /* Change only if we are actually changing the modulation */
360 if (state->current_modulation != param->u.vsb.modulation) {
361 state->current_modulation = param->u.vsb.modulation;
362 or51132_setmode(fe);
363 }
364
365 if (fe->ops.tuner_ops.set_params) {
366 fe->ops.tuner_ops.set_params(fe, param);
367 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
368 }
369
370 /* Set to current mode */
371 or51132_setmode(fe);
372
373 /* Update current frequency */
374 state->current_frequency = param->frequency;
375 return 0;
376}
377
378static int or51132_get_parameters(struct dvb_frontend* fe,
379 struct dvb_frontend_parameters *param)
380{
381 struct or51132_state* state = fe->demodulator_priv;
382 int status;
383 int retry = 1;
384
385start:
386 /* Receiver Status */
387 if ((status = or51132_readreg(state, 0x00)) < 0) {
388 printk(KERN_WARNING "or51132: get_parameters: error reading receiver status\n");
389 return -EREMOTEIO;
390 }
391 switch(status&0xff) {
392 case 0x06: param->u.vsb.modulation = VSB_8; break;
393 case 0x43: param->u.vsb.modulation = QAM_64; break;
394 case 0x45: param->u.vsb.modulation = QAM_256; break;
395 default:
396 if (retry--) goto start;
397 printk(KERN_WARNING "or51132: unknown status 0x%02x\n",
398 status&0xff);
399 return -EREMOTEIO;
400 }
401
402 /* FIXME: Read frequency from frontend, take AFC into account */
403 param->frequency = state->current_frequency;
404
405 /* FIXME: How to read inversion setting? Receiver 6 register? */
406 param->inversion = INVERSION_AUTO;
407
408 return 0;
409}
410
411static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status)
412{
413 struct or51132_state* state = fe->demodulator_priv;
414 int reg;
415
416 /* Receiver Status */
417 if ((reg = or51132_readreg(state, 0x00)) < 0) {
418 printk(KERN_WARNING "or51132: read_status: error reading receiver status: %d\n", reg);
419 *status = 0;
420 return -EREMOTEIO;
421 }
422 dprintk("%s: read_status %04x\n", __func__, reg);
423
424 if (reg & 0x0100) /* Receiver Lock */
425 *status = FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|
426 FE_HAS_SYNC|FE_HAS_LOCK;
427 else
428 *status = 0;
429 return 0;
430}
431
432/* Calculate SNR estimation (scaled by 2^24)
433
434 8-VSB SNR and QAM equations from Oren datasheets
435
436 For 8-VSB:
437 SNR[dB] = 10 * log10(897152044.8282 / MSE^2 ) - K
438
439 Where K = 0 if NTSC rejection filter is OFF; and
440 K = 3 if NTSC rejection filter is ON
441
442 For QAM64:
443 SNR[dB] = 10 * log10(897152044.8282 / MSE^2 )
444
445 For QAM256:
446 SNR[dB] = 10 * log10(907832426.314266 / MSE^2 )
447
448 We re-write the snr equation as:
449 SNR * 2^24 = 10*(c - 2*intlog10(MSE))
450 Where for QAM256, c = log10(907832426.314266) * 2^24
451 and for 8-VSB and QAM64, c = log10(897152044.8282) * 2^24 */
452
453static u32 calculate_snr(u32 mse, u32 c)
454{
455 if (mse == 0) /* No signal */
456 return 0;
457
458 mse = 2*intlog10(mse);
459 if (mse > c) {
460 /* Negative SNR, which is possible, but realisticly the
461 demod will lose lock before the signal gets this bad. The
462 API only allows for unsigned values, so just return 0 */
463 return 0;
464 }
465 return 10*(c - mse);
466}
467
468static int or51132_read_snr(struct dvb_frontend* fe, u16* snr)
469{
470 struct or51132_state* state = fe->demodulator_priv;
471 int noise, reg;
472 u32 c, usK = 0;
473 int retry = 1;
474
475start:
476 /* SNR after Equalizer */
477 noise = or51132_readreg(state, 0x02);
478 if (noise < 0) {
479 printk(KERN_WARNING "or51132: read_snr: error reading equalizer\n");
480 return -EREMOTEIO;
481 }
482 dprintk("read_snr noise (%d)\n", noise);
483
484 /* Read status, contains modulation type for QAM_AUTO and
485 NTSC filter for VSB */
486 reg = or51132_readreg(state, 0x00);
487 if (reg < 0) {
488 printk(KERN_WARNING "or51132: read_snr: error reading receiver status\n");
489 return -EREMOTEIO;
490 }
491
492 switch (reg&0xff) {
493 case 0x06:
494 if (reg & 0x1000) usK = 3 << 24;
495 /* Fall through to QAM64 case */
496 case 0x43:
497 c = 150204167;
498 break;
499 case 0x45:
500 c = 150290396;
501 break;
502 default:
503 printk(KERN_WARNING "or51132: unknown status 0x%02x\n", reg&0xff);
504 if (retry--) goto start;
505 return -EREMOTEIO;
506 }
507 dprintk("%s: modulation %02x, NTSC rej O%s\n", __func__,
508 reg&0xff, reg&0x1000?"n":"ff");
509
510 /* Calculate SNR using noise, c, and NTSC rejection correction */
511 state->snr = calculate_snr(noise, c) - usK;
512 *snr = (state->snr) >> 16;
513
514 dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise,
515 state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16);
516
517 return 0;
518}
519
520static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength)
521{
522 /* Calculate Strength from SNR up to 35dB */
523 /* Even though the SNR can go higher than 35dB, there is some comfort */
524 /* factor in having a range of strong signals that can show at 100% */
525 struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv;
526 u16 snr;
527 int ret;
528
529 ret = fe->ops.read_snr(fe, &snr);
530 if (ret != 0)
531 return ret;
532 /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
533 /* scale the range 0 - 35*2^24 into 0 - 65535 */
534 if (state->snr >= 8960 * 0x10000)
535 *strength = 0xffff;
536 else
537 *strength = state->snr / 8960;
538
539 return 0;
540}
541
542static int or51132_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings)
543{
544 fe_tune_settings->min_delay_ms = 500;
545 fe_tune_settings->step_size = 0;
546 fe_tune_settings->max_drift = 0;
547
548 return 0;
549}
550
551static void or51132_release(struct dvb_frontend* fe)
552{
553 struct or51132_state* state = fe->demodulator_priv;
554 kfree(state);
555}
556
557static struct dvb_frontend_ops or51132_ops;
558
559struct dvb_frontend* or51132_attach(const struct or51132_config* config,
560 struct i2c_adapter* i2c)
561{
562 struct or51132_state* state = NULL;
563
564 /* Allocate memory for the internal state */
565 state = kzalloc(sizeof(struct or51132_state), GFP_KERNEL);
566 if (state == NULL)
567 return NULL;
568
569 /* Setup the state */
570 state->config = config;
571 state->i2c = i2c;
572 state->current_frequency = -1;
573 state->current_modulation = -1;
574
575 /* Create dvb_frontend */
576 memcpy(&state->frontend.ops, &or51132_ops, sizeof(struct dvb_frontend_ops));
577 state->frontend.demodulator_priv = state;
578 return &state->frontend;
579}
580
581static struct dvb_frontend_ops or51132_ops = {
582
583 .info = {
584 .name = "Oren OR51132 VSB/QAM Frontend",
585 .type = FE_ATSC,
586 .frequency_min = 44000000,
587 .frequency_max = 958000000,
588 .frequency_stepsize = 166666,
589 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
590 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
591 FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
592 FE_CAN_8VSB
593 },
594
595 .release = or51132_release,
596
597 .init = or51132_init,
598 .sleep = or51132_sleep,
599
600 .set_frontend = or51132_set_parameters,
601 .get_frontend = or51132_get_parameters,
602 .get_tune_settings = or51132_get_tune_settings,
603
604 .read_status = or51132_read_status,
605 .read_ber = or51132_read_ber,
606 .read_signal_strength = or51132_read_signal_strength,
607 .read_snr = or51132_read_snr,
608 .read_ucblocks = or51132_read_ucblocks,
609};
610
611module_param(debug, int, 0644);
612MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
613
614MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver");
615MODULE_AUTHOR("Kirk Lapray");
616MODULE_AUTHOR("Trent Piepho");
617MODULE_LICENSE("GPL");
618
619EXPORT_SYMBOL(or51132_attach);
620
621/*
622 * Local variables:
623 * c-basic-offset: 8
624 * End:
625 */
diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h
new file mode 100644
index 00000000000..1b8e04d973c
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51132.h
@@ -0,0 +1,55 @@
1/*
2 * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.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
22#ifndef OR51132_H
23#define OR51132_H
24
25#include <linux/firmware.h>
26#include <linux/dvb/frontend.h>
27
28struct or51132_config
29{
30 /* The demodulator's i2c address */
31 u8 demod_address;
32
33 /* Need to set device param for start_dma */
34 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
35};
36
37#if defined(CONFIG_DVB_OR51132) || (defined(CONFIG_DVB_OR51132_MODULE) && defined(MODULE))
38extern struct dvb_frontend* or51132_attach(const struct or51132_config* config,
39 struct i2c_adapter* i2c);
40#else
41static inline struct dvb_frontend* or51132_attach(const struct or51132_config* config,
42 struct i2c_adapter* i2c)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
45 return NULL;
46}
47#endif // CONFIG_DVB_OR51132
48
49#endif // OR51132_H
50
51/*
52 * Local variables:
53 * c-basic-offset: 8
54 * End:
55 */
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
new file mode 100644
index 00000000000..c709ce6771c
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -0,0 +1,582 @@
1/*
2 * Support for OR51211 (pcHDTV HD-2000) - VSB
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
5 *
6 * Based on code from Jack Kelliher (kelliher@xmission.com)
7 * Copyright (C) 2002 & pcHDTV, inc.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23*/
24
25/*
26 * This driver needs external firmware. Please use the command
27 * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
28 * download/extract it, and then copy it to /usr/lib/hotplug/firmware
29 * or /lib/firmware (depending on configuration of firmware hotplug).
30 */
31#define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw"
32
33#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/device.h>
36#include <linux/firmware.h>
37#include <linux/string.h>
38#include <linux/slab.h>
39#include <asm/byteorder.h>
40
41#include "dvb_math.h"
42#include "dvb_frontend.h"
43#include "or51211.h"
44
45static int debug;
46#define dprintk(args...) \
47 do { \
48 if (debug) printk(KERN_DEBUG "or51211: " args); \
49 } while (0)
50
51static u8 run_buf[] = {0x7f,0x01};
52static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC
53
54struct or51211_state {
55
56 struct i2c_adapter* i2c;
57
58 /* Configuration settings */
59 const struct or51211_config* config;
60
61 struct dvb_frontend frontend;
62 struct bt878* bt;
63
64 /* Demodulator private data */
65 u8 initialized:1;
66 u32 snr; /* Result of last SNR claculation */
67
68 /* Tuner private data */
69 u32 current_frequency;
70};
71
72static int i2c_writebytes (struct or51211_state* state, u8 reg, const u8 *buf,
73 int len)
74{
75 int err;
76 struct i2c_msg msg;
77 msg.addr = reg;
78 msg.flags = 0;
79 msg.len = len;
80 msg.buf = (u8 *)buf;
81
82 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
83 printk(KERN_WARNING "or51211: i2c_writebytes error "
84 "(addr %02x, err == %i)\n", reg, err);
85 return -EREMOTEIO;
86 }
87
88 return 0;
89}
90
91static int i2c_readbytes(struct or51211_state *state, u8 reg, u8 *buf, int len)
92{
93 int err;
94 struct i2c_msg msg;
95 msg.addr = reg;
96 msg.flags = I2C_M_RD;
97 msg.len = len;
98 msg.buf = buf;
99
100 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
101 printk(KERN_WARNING "or51211: i2c_readbytes error "
102 "(addr %02x, err == %i)\n", reg, err);
103 return -EREMOTEIO;
104 }
105
106 return 0;
107}
108
109static int or51211_load_firmware (struct dvb_frontend* fe,
110 const struct firmware *fw)
111{
112 struct or51211_state* state = fe->demodulator_priv;
113 u8 tudata[585];
114 int i;
115
116 dprintk("Firmware is %zd bytes\n",fw->size);
117
118 /* Get eprom data */
119 tudata[0] = 17;
120 if (i2c_writebytes(state,0x50,tudata,1)) {
121 printk(KERN_WARNING "or51211:load_firmware error eprom addr\n");
122 return -1;
123 }
124 if (i2c_readbytes(state,0x50,&tudata[145],192)) {
125 printk(KERN_WARNING "or51211: load_firmware error eprom\n");
126 return -1;
127 }
128
129 /* Create firmware buffer */
130 for (i = 0; i < 145; i++)
131 tudata[i] = fw->data[i];
132
133 for (i = 0; i < 248; i++)
134 tudata[i+337] = fw->data[145+i];
135
136 state->config->reset(fe);
137
138 if (i2c_writebytes(state,state->config->demod_address,tudata,585)) {
139 printk(KERN_WARNING "or51211: load_firmware error 1\n");
140 return -1;
141 }
142 msleep(1);
143
144 if (i2c_writebytes(state,state->config->demod_address,
145 &fw->data[393],8125)) {
146 printk(KERN_WARNING "or51211: load_firmware error 2\n");
147 return -1;
148 }
149 msleep(1);
150
151 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
152 printk(KERN_WARNING "or51211: load_firmware error 3\n");
153 return -1;
154 }
155
156 /* Wait at least 5 msec */
157 msleep(10);
158 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
159 printk(KERN_WARNING "or51211: load_firmware error 4\n");
160 return -1;
161 }
162 msleep(10);
163
164 printk("or51211: Done.\n");
165 return 0;
166};
167
168static int or51211_setmode(struct dvb_frontend* fe, int mode)
169{
170 struct or51211_state* state = fe->demodulator_priv;
171 u8 rec_buf[14];
172
173 state->config->setmode(fe, mode);
174
175 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
176 printk(KERN_WARNING "or51211: setmode error 1\n");
177 return -1;
178 }
179
180 /* Wait at least 5 msec */
181 msleep(10);
182 if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
183 printk(KERN_WARNING "or51211: setmode error 2\n");
184 return -1;
185 }
186
187 msleep(10);
188
189 /* Set operation mode in Receiver 1 register;
190 * type 1:
191 * data 0x50h Automatic sets receiver channel conditions
192 * Automatic NTSC rejection filter
193 * Enable MPEG serial data output
194 * MPEG2tr
195 * High tuner phase noise
196 * normal +/-150kHz Carrier acquisition range
197 */
198 if (i2c_writebytes(state,state->config->demod_address,cmd_buf,3)) {
199 printk(KERN_WARNING "or51211: setmode error 3\n");
200 return -1;
201 }
202
203 rec_buf[0] = 0x04;
204 rec_buf[1] = 0x00;
205 rec_buf[2] = 0x03;
206 rec_buf[3] = 0x00;
207 msleep(20);
208 if (i2c_writebytes(state,state->config->demod_address,rec_buf,3)) {
209 printk(KERN_WARNING "or51211: setmode error 5\n");
210 }
211 msleep(3);
212 if (i2c_readbytes(state,state->config->demod_address,&rec_buf[10],2)) {
213 printk(KERN_WARNING "or51211: setmode error 6");
214 return -1;
215 }
216 dprintk("setmode rec status %02x %02x\n",rec_buf[10],rec_buf[11]);
217
218 return 0;
219}
220
221static int or51211_set_parameters(struct dvb_frontend* fe,
222 struct dvb_frontend_parameters *param)
223{
224 struct or51211_state* state = fe->demodulator_priv;
225
226 /* Change only if we are actually changing the channel */
227 if (state->current_frequency != param->frequency) {
228 if (fe->ops.tuner_ops.set_params) {
229 fe->ops.tuner_ops.set_params(fe, param);
230 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
231 }
232
233 /* Set to ATSC mode */
234 or51211_setmode(fe,0);
235
236 /* Update current frequency */
237 state->current_frequency = param->frequency;
238 }
239 return 0;
240}
241
242static int or51211_read_status(struct dvb_frontend* fe, fe_status_t* status)
243{
244 struct or51211_state* state = fe->demodulator_priv;
245 unsigned char rec_buf[2];
246 unsigned char snd_buf[] = {0x04,0x00,0x03,0x00};
247 *status = 0;
248
249 /* Receiver Status */
250 if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
251 printk(KERN_WARNING "or51132: read_status write error\n");
252 return -1;
253 }
254 msleep(3);
255 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
256 printk(KERN_WARNING "or51132: read_status read error\n");
257 return -1;
258 }
259 dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]);
260
261 if (rec_buf[0] & 0x01) { /* Receiver Lock */
262 *status |= FE_HAS_SIGNAL;
263 *status |= FE_HAS_CARRIER;
264 *status |= FE_HAS_VITERBI;
265 *status |= FE_HAS_SYNC;
266 *status |= FE_HAS_LOCK;
267 }
268 return 0;
269}
270
271/* Calculate SNR estimation (scaled by 2^24)
272
273 8-VSB SNR equation from Oren datasheets
274
275 For 8-VSB:
276 SNR[dB] = 10 * log10(219037.9454 / MSE^2 )
277
278 We re-write the snr equation as:
279 SNR * 2^24 = 10*(c - 2*intlog10(MSE))
280 Where for 8-VSB, c = log10(219037.9454) * 2^24 */
281
282static u32 calculate_snr(u32 mse, u32 c)
283{
284 if (mse == 0) /* No signal */
285 return 0;
286
287 mse = 2*intlog10(mse);
288 if (mse > c) {
289 /* Negative SNR, which is possible, but realisticly the
290 demod will lose lock before the signal gets this bad. The
291 API only allows for unsigned values, so just return 0 */
292 return 0;
293 }
294 return 10*(c - mse);
295}
296
297static int or51211_read_snr(struct dvb_frontend* fe, u16* snr)
298{
299 struct or51211_state* state = fe->demodulator_priv;
300 u8 rec_buf[2];
301 u8 snd_buf[3];
302
303 /* SNR after Equalizer */
304 snd_buf[0] = 0x04;
305 snd_buf[1] = 0x00;
306 snd_buf[2] = 0x04;
307
308 if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
309 printk(KERN_WARNING "%s: error writing snr reg\n",
310 __func__);
311 return -1;
312 }
313 if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
314 printk(KERN_WARNING "%s: read_status read error\n",
315 __func__);
316 return -1;
317 }
318
319 state->snr = calculate_snr(rec_buf[0], 89599047);
320 *snr = (state->snr) >> 16;
321
322 dprintk("%s: noise = 0x%02x, snr = %d.%02d dB\n", __func__, rec_buf[0],
323 state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16);
324
325 return 0;
326}
327
328static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
329{
330 /* Calculate Strength from SNR up to 35dB */
331 /* Even though the SNR can go higher than 35dB, there is some comfort */
332 /* factor in having a range of strong signals that can show at 100% */
333 struct or51211_state* state = (struct or51211_state*)fe->demodulator_priv;
334 u16 snr;
335 int ret;
336
337 ret = fe->ops.read_snr(fe, &snr);
338 if (ret != 0)
339 return ret;
340 /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
341 /* scale the range 0 - 35*2^24 into 0 - 65535 */
342 if (state->snr >= 8960 * 0x10000)
343 *strength = 0xffff;
344 else
345 *strength = state->snr / 8960;
346
347 return 0;
348}
349
350static int or51211_read_ber(struct dvb_frontend* fe, u32* ber)
351{
352 *ber = -ENOSYS;
353 return 0;
354}
355
356static int or51211_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
357{
358 *ucblocks = -ENOSYS;
359 return 0;
360}
361
362static int or51211_sleep(struct dvb_frontend* fe)
363{
364 return 0;
365}
366
367static int or51211_init(struct dvb_frontend* fe)
368{
369 struct or51211_state* state = fe->demodulator_priv;
370 const struct or51211_config* config = state->config;
371 const struct firmware* fw;
372 unsigned char get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00};
373 unsigned char rec_buf[14];
374 int ret,i;
375
376 if (!state->initialized) {
377 /* Request the firmware, this will block until it uploads */
378 printk(KERN_INFO "or51211: Waiting for firmware upload "
379 "(%s)...\n", OR51211_DEFAULT_FIRMWARE);
380 ret = config->request_firmware(fe, &fw,
381 OR51211_DEFAULT_FIRMWARE);
382 printk(KERN_INFO "or51211:Got Hotplug firmware\n");
383 if (ret) {
384 printk(KERN_WARNING "or51211: No firmware uploaded "
385 "(timeout or file not found?)\n");
386 return ret;
387 }
388
389 ret = or51211_load_firmware(fe, fw);
390 release_firmware(fw);
391 if (ret) {
392 printk(KERN_WARNING "or51211: Writing firmware to "
393 "device failed!\n");
394 return ret;
395 }
396 printk(KERN_INFO "or51211: Firmware upload complete.\n");
397
398 /* Set operation mode in Receiver 1 register;
399 * type 1:
400 * data 0x50h Automatic sets receiver channel conditions
401 * Automatic NTSC rejection filter
402 * Enable MPEG serial data output
403 * MPEG2tr
404 * High tuner phase noise
405 * normal +/-150kHz Carrier acquisition range
406 */
407 if (i2c_writebytes(state,state->config->demod_address,
408 cmd_buf,3)) {
409 printk(KERN_WARNING "or51211: Load DVR Error 5\n");
410 return -1;
411 }
412
413 /* Read back ucode version to besure we loaded correctly */
414 /* and are really up and running */
415 rec_buf[0] = 0x04;
416 rec_buf[1] = 0x00;
417 rec_buf[2] = 0x03;
418 rec_buf[3] = 0x00;
419 msleep(30);
420 if (i2c_writebytes(state,state->config->demod_address,
421 rec_buf,3)) {
422 printk(KERN_WARNING "or51211: Load DVR Error A\n");
423 return -1;
424 }
425 msleep(3);
426 if (i2c_readbytes(state,state->config->demod_address,
427 &rec_buf[10],2)) {
428 printk(KERN_WARNING "or51211: Load DVR Error B\n");
429 return -1;
430 }
431
432 rec_buf[0] = 0x04;
433 rec_buf[1] = 0x00;
434 rec_buf[2] = 0x01;
435 rec_buf[3] = 0x00;
436 msleep(20);
437 if (i2c_writebytes(state,state->config->demod_address,
438 rec_buf,3)) {
439 printk(KERN_WARNING "or51211: Load DVR Error C\n");
440 return -1;
441 }
442 msleep(3);
443 if (i2c_readbytes(state,state->config->demod_address,
444 &rec_buf[12],2)) {
445 printk(KERN_WARNING "or51211: Load DVR Error D\n");
446 return -1;
447 }
448
449 for (i = 0; i < 8; i++)
450 rec_buf[i]=0xed;
451
452 for (i = 0; i < 5; i++) {
453 msleep(30);
454 get_ver_buf[4] = i+1;
455 if (i2c_writebytes(state,state->config->demod_address,
456 get_ver_buf,5)) {
457 printk(KERN_WARNING "or51211:Load DVR Error 6"
458 " - %d\n",i);
459 return -1;
460 }
461 msleep(3);
462
463 if (i2c_readbytes(state,state->config->demod_address,
464 &rec_buf[i*2],2)) {
465 printk(KERN_WARNING "or51211:Load DVR Error 7"
466 " - %d\n",i);
467 return -1;
468 }
469 /* If we didn't receive the right index, try again */
470 if ((int)rec_buf[i*2+1]!=i+1){
471 i--;
472 }
473 }
474 dprintk("read_fwbits %x %x %x %x %x %x %x %x %x %x\n",
475 rec_buf[0], rec_buf[1], rec_buf[2], rec_buf[3],
476 rec_buf[4], rec_buf[5], rec_buf[6], rec_buf[7],
477 rec_buf[8], rec_buf[9]);
478
479 printk(KERN_INFO "or51211: ver TU%02x%02x%02x VSB mode %02x"
480 " Status %02x\n",
481 rec_buf[2], rec_buf[4],rec_buf[6],
482 rec_buf[12],rec_buf[10]);
483
484 rec_buf[0] = 0x04;
485 rec_buf[1] = 0x00;
486 rec_buf[2] = 0x03;
487 rec_buf[3] = 0x00;
488 msleep(20);
489 if (i2c_writebytes(state,state->config->demod_address,
490 rec_buf,3)) {
491 printk(KERN_WARNING "or51211: Load DVR Error 8\n");
492 return -1;
493 }
494 msleep(20);
495 if (i2c_readbytes(state,state->config->demod_address,
496 &rec_buf[8],2)) {
497 printk(KERN_WARNING "or51211: Load DVR Error 9\n");
498 return -1;
499 }
500 state->initialized = 1;
501 }
502
503 return 0;
504}
505
506static int or51211_get_tune_settings(struct dvb_frontend* fe,
507 struct dvb_frontend_tune_settings* fesettings)
508{
509 fesettings->min_delay_ms = 500;
510 fesettings->step_size = 0;
511 fesettings->max_drift = 0;
512 return 0;
513}
514
515static void or51211_release(struct dvb_frontend* fe)
516{
517 struct or51211_state* state = fe->demodulator_priv;
518 state->config->sleep(fe);
519 kfree(state);
520}
521
522static struct dvb_frontend_ops or51211_ops;
523
524struct dvb_frontend* or51211_attach(const struct or51211_config* config,
525 struct i2c_adapter* i2c)
526{
527 struct or51211_state* state = NULL;
528
529 /* Allocate memory for the internal state */
530 state = kzalloc(sizeof(struct or51211_state), GFP_KERNEL);
531 if (state == NULL)
532 return NULL;
533
534 /* Setup the state */
535 state->config = config;
536 state->i2c = i2c;
537 state->initialized = 0;
538 state->current_frequency = 0;
539
540 /* Create dvb_frontend */
541 memcpy(&state->frontend.ops, &or51211_ops, sizeof(struct dvb_frontend_ops));
542 state->frontend.demodulator_priv = state;
543 return &state->frontend;
544}
545
546static struct dvb_frontend_ops or51211_ops = {
547
548 .info = {
549 .name = "Oren OR51211 VSB Frontend",
550 .type = FE_ATSC,
551 .frequency_min = 44000000,
552 .frequency_max = 958000000,
553 .frequency_stepsize = 166666,
554 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
555 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
556 FE_CAN_8VSB
557 },
558
559 .release = or51211_release,
560
561 .init = or51211_init,
562 .sleep = or51211_sleep,
563
564 .set_frontend = or51211_set_parameters,
565 .get_tune_settings = or51211_get_tune_settings,
566
567 .read_status = or51211_read_status,
568 .read_ber = or51211_read_ber,
569 .read_signal_strength = or51211_read_signal_strength,
570 .read_snr = or51211_read_snr,
571 .read_ucblocks = or51211_read_ucblocks,
572};
573
574module_param(debug, int, 0644);
575MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
576
577MODULE_DESCRIPTION("Oren OR51211 VSB [pcHDTV HD-2000] Demodulator Driver");
578MODULE_AUTHOR("Kirk Lapray");
579MODULE_LICENSE("GPL");
580
581EXPORT_SYMBOL(or51211_attach);
582
diff --git a/drivers/media/dvb/frontends/or51211.h b/drivers/media/dvb/frontends/or51211.h
new file mode 100644
index 00000000000..3ce0508b898
--- /dev/null
+++ b/drivers/media/dvb/frontends/or51211.h
@@ -0,0 +1,53 @@
1/*
2 * Support for OR51211 (pcHDTV HD-2000) - VSB
3 *
4 * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.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
22#ifndef OR51211_H
23#define OR51211_H
24
25#include <linux/dvb/frontend.h>
26#include <linux/firmware.h>
27
28struct or51211_config
29{
30 /* The demodulator's i2c address */
31 u8 demod_address;
32
33 /* Request firmware for device */
34 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
35 void (*setmode)(struct dvb_frontend * fe, int mode);
36 void (*reset)(struct dvb_frontend * fe);
37 void (*sleep)(struct dvb_frontend * fe);
38};
39
40#if defined(CONFIG_DVB_OR51211) || (defined(CONFIG_DVB_OR51211_MODULE) && defined(MODULE))
41extern struct dvb_frontend* or51211_attach(const struct or51211_config* config,
42 struct i2c_adapter* i2c);
43#else
44static inline struct dvb_frontend* or51211_attach(const struct or51211_config* config,
45 struct i2c_adapter* i2c)
46{
47 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
48 return NULL;
49}
50#endif // CONFIG_DVB_OR51211
51
52#endif // OR51211_H
53
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
new file mode 100644
index 00000000000..0e2f61a8978
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1409.c
@@ -0,0 +1,1001 @@
1/*
2 Samsung S5H1409 VSB/QAM demodulator driver
3
4 Copyright (C) 2006 Steven Toth <stoth@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 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 <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/slab.h>
27#include <linux/delay.h>
28#include "dvb_frontend.h"
29#include "s5h1409.h"
30
31struct s5h1409_state {
32
33 struct i2c_adapter *i2c;
34
35 /* configuration settings */
36 const struct s5h1409_config *config;
37
38 struct dvb_frontend frontend;
39
40 /* previous uncorrected block counter */
41 fe_modulation_t current_modulation;
42
43 u32 current_frequency;
44 int if_freq;
45
46 u32 is_qam_locked;
47
48 /* QAM tuning state goes through the following state transitions */
49#define QAM_STATE_UNTUNED 0
50#define QAM_STATE_TUNING_STARTED 1
51#define QAM_STATE_INTERLEAVE_SET 2
52#define QAM_STATE_QAM_OPTIMIZED_L1 3
53#define QAM_STATE_QAM_OPTIMIZED_L2 4
54#define QAM_STATE_QAM_OPTIMIZED_L3 5
55 u8 qam_state;
56};
57
58static int debug;
59module_param(debug, int, 0644);
60MODULE_PARM_DESC(debug, "Enable verbose debug messages");
61
62#define dprintk if (debug) printk
63
64/* Register values to initialise the demod, this will set VSB by default */
65static struct init_tab {
66 u8 reg;
67 u16 data;
68} init_tab[] = {
69 { 0x00, 0x0071, },
70 { 0x01, 0x3213, },
71 { 0x09, 0x0025, },
72 { 0x1c, 0x001d, },
73 { 0x1f, 0x002d, },
74 { 0x20, 0x001d, },
75 { 0x22, 0x0022, },
76 { 0x23, 0x0020, },
77 { 0x29, 0x110f, },
78 { 0x2a, 0x10b4, },
79 { 0x2b, 0x10ae, },
80 { 0x2c, 0x0031, },
81 { 0x31, 0x010d, },
82 { 0x32, 0x0100, },
83 { 0x44, 0x0510, },
84 { 0x54, 0x0104, },
85 { 0x58, 0x2222, },
86 { 0x59, 0x1162, },
87 { 0x5a, 0x3211, },
88 { 0x5d, 0x0370, },
89 { 0x5e, 0x0296, },
90 { 0x61, 0x0010, },
91 { 0x63, 0x4a00, },
92 { 0x65, 0x0800, },
93 { 0x71, 0x0003, },
94 { 0x72, 0x0470, },
95 { 0x81, 0x0002, },
96 { 0x82, 0x0600, },
97 { 0x86, 0x0002, },
98 { 0x8a, 0x2c38, },
99 { 0x8b, 0x2a37, },
100 { 0x92, 0x302f, },
101 { 0x93, 0x3332, },
102 { 0x96, 0x000c, },
103 { 0x99, 0x0101, },
104 { 0x9c, 0x2e37, },
105 { 0x9d, 0x2c37, },
106 { 0x9e, 0x2c37, },
107 { 0xab, 0x0100, },
108 { 0xac, 0x1003, },
109 { 0xad, 0x103f, },
110 { 0xe2, 0x0100, },
111 { 0xe3, 0x1000, },
112 { 0x28, 0x1010, },
113 { 0xb1, 0x000e, },
114};
115
116/* VSB SNR lookup table */
117static struct vsb_snr_tab {
118 u16 val;
119 u16 data;
120} vsb_snr_tab[] = {
121 { 924, 300, },
122 { 923, 300, },
123 { 918, 295, },
124 { 915, 290, },
125 { 911, 285, },
126 { 906, 280, },
127 { 901, 275, },
128 { 896, 270, },
129 { 891, 265, },
130 { 885, 260, },
131 { 879, 255, },
132 { 873, 250, },
133 { 864, 245, },
134 { 858, 240, },
135 { 850, 235, },
136 { 841, 230, },
137 { 832, 225, },
138 { 823, 220, },
139 { 812, 215, },
140 { 802, 210, },
141 { 788, 205, },
142 { 778, 200, },
143 { 767, 195, },
144 { 753, 190, },
145 { 740, 185, },
146 { 725, 180, },
147 { 707, 175, },
148 { 689, 170, },
149 { 671, 165, },
150 { 656, 160, },
151 { 637, 155, },
152 { 616, 150, },
153 { 542, 145, },
154 { 519, 140, },
155 { 507, 135, },
156 { 497, 130, },
157 { 492, 125, },
158 { 474, 120, },
159 { 300, 111, },
160 { 0, 0, },
161};
162
163/* QAM64 SNR lookup table */
164static struct qam64_snr_tab {
165 u16 val;
166 u16 data;
167} qam64_snr_tab[] = {
168 { 1, 0, },
169 { 12, 300, },
170 { 15, 290, },
171 { 18, 280, },
172 { 22, 270, },
173 { 23, 268, },
174 { 24, 266, },
175 { 25, 264, },
176 { 27, 262, },
177 { 28, 260, },
178 { 29, 258, },
179 { 30, 256, },
180 { 32, 254, },
181 { 33, 252, },
182 { 34, 250, },
183 { 35, 249, },
184 { 36, 248, },
185 { 37, 247, },
186 { 38, 246, },
187 { 39, 245, },
188 { 40, 244, },
189 { 41, 243, },
190 { 42, 241, },
191 { 43, 240, },
192 { 44, 239, },
193 { 45, 238, },
194 { 46, 237, },
195 { 47, 236, },
196 { 48, 235, },
197 { 49, 234, },
198 { 50, 233, },
199 { 51, 232, },
200 { 52, 231, },
201 { 53, 230, },
202 { 55, 229, },
203 { 56, 228, },
204 { 57, 227, },
205 { 58, 226, },
206 { 59, 225, },
207 { 60, 224, },
208 { 62, 223, },
209 { 63, 222, },
210 { 65, 221, },
211 { 66, 220, },
212 { 68, 219, },
213 { 69, 218, },
214 { 70, 217, },
215 { 72, 216, },
216 { 73, 215, },
217 { 75, 214, },
218 { 76, 213, },
219 { 78, 212, },
220 { 80, 211, },
221 { 81, 210, },
222 { 83, 209, },
223 { 84, 208, },
224 { 85, 207, },
225 { 87, 206, },
226 { 89, 205, },
227 { 91, 204, },
228 { 93, 203, },
229 { 95, 202, },
230 { 96, 201, },
231 { 104, 200, },
232 { 255, 0, },
233};
234
235/* QAM256 SNR lookup table */
236static struct qam256_snr_tab {
237 u16 val;
238 u16 data;
239} qam256_snr_tab[] = {
240 { 1, 0, },
241 { 12, 400, },
242 { 13, 390, },
243 { 15, 380, },
244 { 17, 360, },
245 { 19, 350, },
246 { 22, 348, },
247 { 23, 346, },
248 { 24, 344, },
249 { 25, 342, },
250 { 26, 340, },
251 { 27, 336, },
252 { 28, 334, },
253 { 29, 332, },
254 { 30, 330, },
255 { 31, 328, },
256 { 32, 326, },
257 { 33, 325, },
258 { 34, 322, },
259 { 35, 320, },
260 { 37, 318, },
261 { 39, 316, },
262 { 40, 314, },
263 { 41, 312, },
264 { 42, 310, },
265 { 43, 308, },
266 { 46, 306, },
267 { 47, 304, },
268 { 49, 302, },
269 { 51, 300, },
270 { 53, 298, },
271 { 54, 297, },
272 { 55, 296, },
273 { 56, 295, },
274 { 57, 294, },
275 { 59, 293, },
276 { 60, 292, },
277 { 61, 291, },
278 { 63, 290, },
279 { 64, 289, },
280 { 65, 288, },
281 { 66, 287, },
282 { 68, 286, },
283 { 69, 285, },
284 { 71, 284, },
285 { 72, 283, },
286 { 74, 282, },
287 { 75, 281, },
288 { 76, 280, },
289 { 77, 279, },
290 { 78, 278, },
291 { 81, 277, },
292 { 83, 276, },
293 { 84, 275, },
294 { 86, 274, },
295 { 87, 273, },
296 { 89, 272, },
297 { 90, 271, },
298 { 92, 270, },
299 { 93, 269, },
300 { 95, 268, },
301 { 96, 267, },
302 { 98, 266, },
303 { 100, 265, },
304 { 102, 264, },
305 { 104, 263, },
306 { 105, 262, },
307 { 106, 261, },
308 { 110, 260, },
309 { 255, 0, },
310};
311
312/* 8 bit registers, 16 bit values */
313static int s5h1409_writereg(struct s5h1409_state *state, u8 reg, u16 data)
314{
315 int ret;
316 u8 buf[] = { reg, data >> 8, data & 0xff };
317
318 struct i2c_msg msg = { .addr = state->config->demod_address,
319 .flags = 0, .buf = buf, .len = 3 };
320
321 ret = i2c_transfer(state->i2c, &msg, 1);
322
323 if (ret != 1)
324 printk(KERN_ERR "%s: error (reg == 0x%02x, val == 0x%04x, "
325 "ret == %i)\n", __func__, reg, data, ret);
326
327 return (ret != 1) ? -1 : 0;
328}
329
330static u16 s5h1409_readreg(struct s5h1409_state *state, u8 reg)
331{
332 int ret;
333 u8 b0[] = { reg };
334 u8 b1[] = { 0, 0 };
335
336 struct i2c_msg msg[] = {
337 { .addr = state->config->demod_address, .flags = 0,
338 .buf = b0, .len = 1 },
339 { .addr = state->config->demod_address, .flags = I2C_M_RD,
340 .buf = b1, .len = 2 } };
341
342 ret = i2c_transfer(state->i2c, msg, 2);
343
344 if (ret != 2)
345 printk("%s: readreg error (ret == %i)\n", __func__, ret);
346 return (b1[0] << 8) | b1[1];
347}
348
349static int s5h1409_softreset(struct dvb_frontend *fe)
350{
351 struct s5h1409_state *state = fe->demodulator_priv;
352
353 dprintk("%s()\n", __func__);
354
355 s5h1409_writereg(state, 0xf5, 0);
356 s5h1409_writereg(state, 0xf5, 1);
357 state->is_qam_locked = 0;
358 state->qam_state = QAM_STATE_UNTUNED;
359 return 0;
360}
361
362#define S5H1409_VSB_IF_FREQ 5380
363#define S5H1409_QAM_IF_FREQ (state->config->qam_if)
364
365static int s5h1409_set_if_freq(struct dvb_frontend *fe, int KHz)
366{
367 struct s5h1409_state *state = fe->demodulator_priv;
368
369 dprintk("%s(%d KHz)\n", __func__, KHz);
370
371 switch (KHz) {
372 case 4000:
373 s5h1409_writereg(state, 0x87, 0x014b);
374 s5h1409_writereg(state, 0x88, 0x0cb5);
375 s5h1409_writereg(state, 0x89, 0x03e2);
376 break;
377 case 5380:
378 case 44000:
379 default:
380 s5h1409_writereg(state, 0x87, 0x01be);
381 s5h1409_writereg(state, 0x88, 0x0436);
382 s5h1409_writereg(state, 0x89, 0x054d);
383 break;
384 }
385 state->if_freq = KHz;
386
387 return 0;
388}
389
390static int s5h1409_set_spectralinversion(struct dvb_frontend *fe, int inverted)
391{
392 struct s5h1409_state *state = fe->demodulator_priv;
393
394 dprintk("%s(%d)\n", __func__, inverted);
395
396 if (inverted == 1)
397 return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */
398 else
399 return s5h1409_writereg(state, 0x1b, 0x0110); /* Normal */
400}
401
402static int s5h1409_enable_modulation(struct dvb_frontend *fe,
403 fe_modulation_t m)
404{
405 struct s5h1409_state *state = fe->demodulator_priv;
406
407 dprintk("%s(0x%08x)\n", __func__, m);
408
409 switch (m) {
410 case VSB_8:
411 dprintk("%s() VSB_8\n", __func__);
412 if (state->if_freq != S5H1409_VSB_IF_FREQ)
413 s5h1409_set_if_freq(fe, S5H1409_VSB_IF_FREQ);
414 s5h1409_writereg(state, 0xf4, 0);
415 break;
416 case QAM_64:
417 case QAM_256:
418 case QAM_AUTO:
419 dprintk("%s() QAM_AUTO (64/256)\n", __func__);
420 if (state->if_freq != S5H1409_QAM_IF_FREQ)
421 s5h1409_set_if_freq(fe, S5H1409_QAM_IF_FREQ);
422 s5h1409_writereg(state, 0xf4, 1);
423 s5h1409_writereg(state, 0x85, 0x110);
424 break;
425 default:
426 dprintk("%s() Invalid modulation\n", __func__);
427 return -EINVAL;
428 }
429
430 state->current_modulation = m;
431 s5h1409_softreset(fe);
432
433 return 0;
434}
435
436static int s5h1409_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
437{
438 struct s5h1409_state *state = fe->demodulator_priv;
439
440 dprintk("%s(%d)\n", __func__, enable);
441
442 if (enable)
443 return s5h1409_writereg(state, 0xf3, 1);
444 else
445 return s5h1409_writereg(state, 0xf3, 0);
446}
447
448static int s5h1409_set_gpio(struct dvb_frontend *fe, int enable)
449{
450 struct s5h1409_state *state = fe->demodulator_priv;
451
452 dprintk("%s(%d)\n", __func__, enable);
453
454 if (enable)
455 return s5h1409_writereg(state, 0xe3,
456 s5h1409_readreg(state, 0xe3) | 0x1100);
457 else
458 return s5h1409_writereg(state, 0xe3,
459 s5h1409_readreg(state, 0xe3) & 0xfeff);
460}
461
462static int s5h1409_sleep(struct dvb_frontend *fe, int enable)
463{
464 struct s5h1409_state *state = fe->demodulator_priv;
465
466 dprintk("%s(%d)\n", __func__, enable);
467
468 return s5h1409_writereg(state, 0xf2, enable);
469}
470
471static int s5h1409_register_reset(struct dvb_frontend *fe)
472{
473 struct s5h1409_state *state = fe->demodulator_priv;
474
475 dprintk("%s()\n", __func__);
476
477 return s5h1409_writereg(state, 0xfa, 0);
478}
479
480static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe)
481{
482 struct s5h1409_state *state = fe->demodulator_priv;
483 u16 reg;
484
485 if (state->qam_state < QAM_STATE_INTERLEAVE_SET) {
486 /* We should not perform amhum optimization until
487 the interleave mode has been configured */
488 return;
489 }
490
491 if (state->qam_state == QAM_STATE_QAM_OPTIMIZED_L3) {
492 /* We've already reached the maximum optimization level, so
493 dont bother banging on the status registers */
494 return;
495 }
496
497 /* QAM EQ lock check */
498 reg = s5h1409_readreg(state, 0xf0);
499
500 if ((reg >> 13) & 0x1) {
501 reg &= 0xff;
502
503 s5h1409_writereg(state, 0x96, 0x000c);
504 if (reg < 0x68) {
505 if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L3) {
506 dprintk("%s() setting QAM state to OPT_L3\n",
507 __func__);
508 s5h1409_writereg(state, 0x93, 0x3130);
509 s5h1409_writereg(state, 0x9e, 0x2836);
510 state->qam_state = QAM_STATE_QAM_OPTIMIZED_L3;
511 }
512 } else {
513 if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L2) {
514 dprintk("%s() setting QAM state to OPT_L2\n",
515 __func__);
516 s5h1409_writereg(state, 0x93, 0x3332);
517 s5h1409_writereg(state, 0x9e, 0x2c37);
518 state->qam_state = QAM_STATE_QAM_OPTIMIZED_L2;
519 }
520 }
521
522 } else {
523 if (state->qam_state < QAM_STATE_QAM_OPTIMIZED_L1) {
524 dprintk("%s() setting QAM state to OPT_L1\n", __func__);
525 s5h1409_writereg(state, 0x96, 0x0008);
526 s5h1409_writereg(state, 0x93, 0x3332);
527 s5h1409_writereg(state, 0x9e, 0x2c37);
528 state->qam_state = QAM_STATE_QAM_OPTIMIZED_L1;
529 }
530 }
531}
532
533static void s5h1409_set_qam_amhum_mode_legacy(struct dvb_frontend *fe)
534{
535 struct s5h1409_state *state = fe->demodulator_priv;
536 u16 reg;
537
538 if (state->is_qam_locked)
539 return;
540
541 /* QAM EQ lock check */
542 reg = s5h1409_readreg(state, 0xf0);
543
544 if ((reg >> 13) & 0x1) {
545
546 state->is_qam_locked = 1;
547 reg &= 0xff;
548
549 s5h1409_writereg(state, 0x96, 0x00c);
550 if ((reg < 0x38) || (reg > 0x68)) {
551 s5h1409_writereg(state, 0x93, 0x3332);
552 s5h1409_writereg(state, 0x9e, 0x2c37);
553 } else {
554 s5h1409_writereg(state, 0x93, 0x3130);
555 s5h1409_writereg(state, 0x9e, 0x2836);
556 }
557
558 } else {
559 s5h1409_writereg(state, 0x96, 0x0008);
560 s5h1409_writereg(state, 0x93, 0x3332);
561 s5h1409_writereg(state, 0x9e, 0x2c37);
562 }
563}
564
565static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe)
566{
567 struct s5h1409_state *state = fe->demodulator_priv;
568 u16 reg, reg1, reg2;
569
570 if (state->qam_state >= QAM_STATE_INTERLEAVE_SET) {
571 /* We've done the optimization already */
572 return;
573 }
574
575 reg = s5h1409_readreg(state, 0xf1);
576
577 /* Master lock */
578 if ((reg >> 15) & 0x1) {
579 if (state->qam_state == QAM_STATE_UNTUNED ||
580 state->qam_state == QAM_STATE_TUNING_STARTED) {
581 dprintk("%s() setting QAM state to INTERLEAVE_SET\n",
582 __func__);
583 reg1 = s5h1409_readreg(state, 0xb2);
584 reg2 = s5h1409_readreg(state, 0xad);
585
586 s5h1409_writereg(state, 0x96, 0x0020);
587 s5h1409_writereg(state, 0xad,
588 (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)));
589 state->qam_state = QAM_STATE_INTERLEAVE_SET;
590 }
591 } else {
592 if (state->qam_state == QAM_STATE_UNTUNED) {
593 dprintk("%s() setting QAM state to TUNING_STARTED\n",
594 __func__);
595 s5h1409_writereg(state, 0x96, 0x08);
596 s5h1409_writereg(state, 0xab,
597 s5h1409_readreg(state, 0xab) | 0x1001);
598 state->qam_state = QAM_STATE_TUNING_STARTED;
599 }
600 }
601}
602
603static void s5h1409_set_qam_interleave_mode_legacy(struct dvb_frontend *fe)
604{
605 struct s5h1409_state *state = fe->demodulator_priv;
606 u16 reg, reg1, reg2;
607
608 reg = s5h1409_readreg(state, 0xf1);
609
610 /* Master lock */
611 if ((reg >> 15) & 0x1) {
612 if (state->qam_state != 2) {
613 state->qam_state = 2;
614 reg1 = s5h1409_readreg(state, 0xb2);
615 reg2 = s5h1409_readreg(state, 0xad);
616
617 s5h1409_writereg(state, 0x96, 0x20);
618 s5h1409_writereg(state, 0xad,
619 (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)));
620 s5h1409_writereg(state, 0xab,
621 s5h1409_readreg(state, 0xab) & 0xeffe);
622 }
623 } else {
624 if (state->qam_state != 1) {
625 state->qam_state = 1;
626 s5h1409_writereg(state, 0x96, 0x08);
627 s5h1409_writereg(state, 0xab,
628 s5h1409_readreg(state, 0xab) | 0x1001);
629 }
630 }
631}
632
633/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
634static int s5h1409_set_frontend(struct dvb_frontend *fe,
635 struct dvb_frontend_parameters *p)
636{
637 struct s5h1409_state *state = fe->demodulator_priv;
638
639 dprintk("%s(frequency=%d)\n", __func__, p->frequency);
640
641 s5h1409_softreset(fe);
642
643 state->current_frequency = p->frequency;
644
645 s5h1409_enable_modulation(fe, p->u.vsb.modulation);
646
647 if (fe->ops.tuner_ops.set_params) {
648 if (fe->ops.i2c_gate_ctrl)
649 fe->ops.i2c_gate_ctrl(fe, 1);
650 fe->ops.tuner_ops.set_params(fe, p);
651 if (fe->ops.i2c_gate_ctrl)
652 fe->ops.i2c_gate_ctrl(fe, 0);
653 }
654
655 /* Issue a reset to the demod so it knows to resync against the
656 newly tuned frequency */
657 s5h1409_softreset(fe);
658
659 /* Optimize the demod for QAM */
660 if (state->current_modulation != VSB_8) {
661 /* This almost certainly applies to all boards, but for now
662 only do it for the HVR-1600. Once the other boards are
663 tested, the "legacy" versions can just go away */
664 if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
665 s5h1409_set_qam_interleave_mode(fe);
666 s5h1409_set_qam_amhum_mode(fe);
667 } else {
668 s5h1409_set_qam_amhum_mode_legacy(fe);
669 s5h1409_set_qam_interleave_mode_legacy(fe);
670 }
671 }
672
673 return 0;
674}
675
676static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode)
677{
678 struct s5h1409_state *state = fe->demodulator_priv;
679 u16 val;
680
681 dprintk("%s(%d)\n", __func__, mode);
682
683 val = s5h1409_readreg(state, 0xac) & 0xcfff;
684 switch (mode) {
685 case S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK:
686 val |= 0x0000;
687 break;
688 case S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK:
689 dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode);
690 val |= 0x1000;
691 break;
692 case S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK:
693 val |= 0x2000;
694 break;
695 case S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK:
696 val |= 0x3000;
697 break;
698 default:
699 return -EINVAL;
700 }
701
702 /* Configure MPEG Signal Timing charactistics */
703 return s5h1409_writereg(state, 0xac, val);
704}
705
706/* Reset the demod hardware and reset all of the configuration registers
707 to a default state. */
708static int s5h1409_init(struct dvb_frontend *fe)
709{
710 int i;
711
712 struct s5h1409_state *state = fe->demodulator_priv;
713 dprintk("%s()\n", __func__);
714
715 s5h1409_sleep(fe, 0);
716 s5h1409_register_reset(fe);
717
718 for (i = 0; i < ARRAY_SIZE(init_tab); i++)
719 s5h1409_writereg(state, init_tab[i].reg, init_tab[i].data);
720
721 /* The datasheet says that after initialisation, VSB is default */
722 state->current_modulation = VSB_8;
723
724 /* Optimize for the HVR-1600 if appropriate. Note that some of these
725 may get folded into the generic case after testing with other
726 devices */
727 if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
728 /* VSB AGC REF */
729 s5h1409_writereg(state, 0x09, 0x0050);
730
731 /* Unknown but Windows driver does it... */
732 s5h1409_writereg(state, 0x21, 0x0001);
733 s5h1409_writereg(state, 0x50, 0x030e);
734
735 /* QAM AGC REF */
736 s5h1409_writereg(state, 0x82, 0x0800);
737 }
738
739 if (state->config->output_mode == S5H1409_SERIAL_OUTPUT)
740 s5h1409_writereg(state, 0xab,
741 s5h1409_readreg(state, 0xab) | 0x100); /* Serial */
742 else
743 s5h1409_writereg(state, 0xab,
744 s5h1409_readreg(state, 0xab) & 0xfeff); /* Parallel */
745
746 s5h1409_set_spectralinversion(fe, state->config->inversion);
747 s5h1409_set_if_freq(fe, state->if_freq);
748 s5h1409_set_gpio(fe, state->config->gpio);
749 s5h1409_set_mpeg_timing(fe, state->config->mpeg_timing);
750 s5h1409_softreset(fe);
751
752 /* Note: Leaving the I2C gate closed. */
753 s5h1409_i2c_gate_ctrl(fe, 0);
754
755 return 0;
756}
757
758static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status)
759{
760 struct s5h1409_state *state = fe->demodulator_priv;
761 u16 reg;
762 u32 tuner_status = 0;
763
764 *status = 0;
765
766 /* Optimize the demod for QAM */
767 if (state->current_modulation != VSB_8) {
768 /* This almost certainly applies to all boards, but for now
769 only do it for the HVR-1600. Once the other boards are
770 tested, the "legacy" versions can just go away */
771 if (state->config->hvr1600_opt == S5H1409_HVR1600_OPTIMIZE) {
772 s5h1409_set_qam_interleave_mode(fe);
773 s5h1409_set_qam_amhum_mode(fe);
774 }
775 }
776
777 /* Get the demodulator status */
778 reg = s5h1409_readreg(state, 0xf1);
779 if (reg & 0x1000)
780 *status |= FE_HAS_VITERBI;
781 if (reg & 0x8000)
782 *status |= FE_HAS_LOCK | FE_HAS_SYNC;
783
784 switch (state->config->status_mode) {
785 case S5H1409_DEMODLOCKING:
786 if (*status & FE_HAS_VITERBI)
787 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
788 break;
789 case S5H1409_TUNERLOCKING:
790 /* Get the tuner status */
791 if (fe->ops.tuner_ops.get_status) {
792 if (fe->ops.i2c_gate_ctrl)
793 fe->ops.i2c_gate_ctrl(fe, 1);
794
795 fe->ops.tuner_ops.get_status(fe, &tuner_status);
796
797 if (fe->ops.i2c_gate_ctrl)
798 fe->ops.i2c_gate_ctrl(fe, 0);
799 }
800 if (tuner_status)
801 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
802 break;
803 }
804
805 dprintk("%s() status 0x%08x\n", __func__, *status);
806
807 return 0;
808}
809
810static int s5h1409_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
811{
812 int i, ret = -EINVAL;
813 dprintk("%s()\n", __func__);
814
815 for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) {
816 if (v < qam256_snr_tab[i].val) {
817 *snr = qam256_snr_tab[i].data;
818 ret = 0;
819 break;
820 }
821 }
822 return ret;
823}
824
825static int s5h1409_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
826{
827 int i, ret = -EINVAL;
828 dprintk("%s()\n", __func__);
829
830 for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) {
831 if (v < qam64_snr_tab[i].val) {
832 *snr = qam64_snr_tab[i].data;
833 ret = 0;
834 break;
835 }
836 }
837 return ret;
838}
839
840static int s5h1409_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
841{
842 int i, ret = -EINVAL;
843 dprintk("%s()\n", __func__);
844
845 for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) {
846 if (v > vsb_snr_tab[i].val) {
847 *snr = vsb_snr_tab[i].data;
848 ret = 0;
849 break;
850 }
851 }
852 dprintk("%s() snr=%d\n", __func__, *snr);
853 return ret;
854}
855
856static int s5h1409_read_snr(struct dvb_frontend *fe, u16 *snr)
857{
858 struct s5h1409_state *state = fe->demodulator_priv;
859 u16 reg;
860 dprintk("%s()\n", __func__);
861
862 switch (state->current_modulation) {
863 case QAM_64:
864 reg = s5h1409_readreg(state, 0xf0) & 0xff;
865 return s5h1409_qam64_lookup_snr(fe, snr, reg);
866 case QAM_256:
867 reg = s5h1409_readreg(state, 0xf0) & 0xff;
868 return s5h1409_qam256_lookup_snr(fe, snr, reg);
869 case VSB_8:
870 reg = s5h1409_readreg(state, 0xf1) & 0x3ff;
871 return s5h1409_vsb_lookup_snr(fe, snr, reg);
872 default:
873 break;
874 }
875
876 return -EINVAL;
877}
878
879static int s5h1409_read_signal_strength(struct dvb_frontend *fe,
880 u16 *signal_strength)
881{
882 return s5h1409_read_snr(fe, signal_strength);
883}
884
885static int s5h1409_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
886{
887 struct s5h1409_state *state = fe->demodulator_priv;
888
889 *ucblocks = s5h1409_readreg(state, 0xb5);
890
891 return 0;
892}
893
894static int s5h1409_read_ber(struct dvb_frontend *fe, u32 *ber)
895{
896 return s5h1409_read_ucblocks(fe, ber);
897}
898
899static int s5h1409_get_frontend(struct dvb_frontend *fe,
900 struct dvb_frontend_parameters *p)
901{
902 struct s5h1409_state *state = fe->demodulator_priv;
903
904 p->frequency = state->current_frequency;
905 p->u.vsb.modulation = state->current_modulation;
906
907 return 0;
908}
909
910static int s5h1409_get_tune_settings(struct dvb_frontend *fe,
911 struct dvb_frontend_tune_settings *tune)
912{
913 tune->min_delay_ms = 1000;
914 return 0;
915}
916
917static void s5h1409_release(struct dvb_frontend *fe)
918{
919 struct s5h1409_state *state = fe->demodulator_priv;
920 kfree(state);
921}
922
923static struct dvb_frontend_ops s5h1409_ops;
924
925struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
926 struct i2c_adapter *i2c)
927{
928 struct s5h1409_state *state = NULL;
929 u16 reg;
930
931 /* allocate memory for the internal state */
932 state = kzalloc(sizeof(struct s5h1409_state), GFP_KERNEL);
933 if (state == NULL)
934 goto error;
935
936 /* setup the state */
937 state->config = config;
938 state->i2c = i2c;
939 state->current_modulation = 0;
940 state->if_freq = S5H1409_VSB_IF_FREQ;
941
942 /* check if the demod exists */
943 reg = s5h1409_readreg(state, 0x04);
944 if ((reg != 0x0066) && (reg != 0x007f))
945 goto error;
946
947 /* create dvb_frontend */
948 memcpy(&state->frontend.ops, &s5h1409_ops,
949 sizeof(struct dvb_frontend_ops));
950 state->frontend.demodulator_priv = state;
951
952 if (s5h1409_init(&state->frontend) != 0) {
953 printk(KERN_ERR "%s: Failed to initialize correctly\n",
954 __func__);
955 goto error;
956 }
957
958 /* Note: Leaving the I2C gate open here. */
959 s5h1409_i2c_gate_ctrl(&state->frontend, 1);
960
961 return &state->frontend;
962
963error:
964 kfree(state);
965 return NULL;
966}
967EXPORT_SYMBOL(s5h1409_attach);
968
969static struct dvb_frontend_ops s5h1409_ops = {
970
971 .info = {
972 .name = "Samsung S5H1409 QAM/8VSB Frontend",
973 .type = FE_ATSC,
974 .frequency_min = 54000000,
975 .frequency_max = 858000000,
976 .frequency_stepsize = 62500,
977 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
978 },
979
980 .init = s5h1409_init,
981 .i2c_gate_ctrl = s5h1409_i2c_gate_ctrl,
982 .set_frontend = s5h1409_set_frontend,
983 .get_frontend = s5h1409_get_frontend,
984 .get_tune_settings = s5h1409_get_tune_settings,
985 .read_status = s5h1409_read_status,
986 .read_ber = s5h1409_read_ber,
987 .read_signal_strength = s5h1409_read_signal_strength,
988 .read_snr = s5h1409_read_snr,
989 .read_ucblocks = s5h1409_read_ucblocks,
990 .release = s5h1409_release,
991};
992
993MODULE_DESCRIPTION("Samsung S5H1409 QAM-B/ATSC Demodulator driver");
994MODULE_AUTHOR("Steven Toth");
995MODULE_LICENSE("GPL");
996
997
998/*
999 * Local variables:
1000 * c-basic-offset: 8
1001 */
diff --git a/drivers/media/dvb/frontends/s5h1409.h b/drivers/media/dvb/frontends/s5h1409.h
new file mode 100644
index 00000000000..91f2ebd1a53
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1409.h
@@ -0,0 +1,88 @@
1/*
2 Samsung S5H1409 VSB/QAM demodulator driver
3
4 Copyright (C) 2006 Steven Toth <stoth@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 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 __S5H1409_H__
23#define __S5H1409_H__
24
25#include <linux/dvb/frontend.h>
26
27struct s5h1409_config {
28 /* the demodulator's i2c address */
29 u8 demod_address;
30
31 /* serial/parallel output */
32#define S5H1409_PARALLEL_OUTPUT 0
33#define S5H1409_SERIAL_OUTPUT 1
34 u8 output_mode;
35
36 /* GPIO Setting */
37#define S5H1409_GPIO_OFF 0
38#define S5H1409_GPIO_ON 1
39 u8 gpio;
40
41 /* IF Freq for QAM in KHz, VSB is hardcoded to 5380 */
42 u16 qam_if;
43
44 /* Spectral Inversion */
45#define S5H1409_INVERSION_OFF 0
46#define S5H1409_INVERSION_ON 1
47 u8 inversion;
48
49 /* Return lock status based on tuner lock, or demod lock */
50#define S5H1409_TUNERLOCKING 0
51#define S5H1409_DEMODLOCKING 1
52 u8 status_mode;
53
54 /* MPEG signal timing */
55#define S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0
56#define S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1
57#define S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2
58#define S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
59 u16 mpeg_timing;
60
61 /* HVR-1600 optimizations (to better work with MXL5005s)
62 Note: some of these are likely to be folded into the generic driver
63 after being regression tested with other boards */
64#define S5H1409_HVR1600_NOOPTIMIZE 0
65#define S5H1409_HVR1600_OPTIMIZE 1
66 u8 hvr1600_opt;
67};
68
69#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \
70 && defined(MODULE))
71extern struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
72 struct i2c_adapter *i2c);
73#else
74static inline struct dvb_frontend *s5h1409_attach(
75 const struct s5h1409_config *config,
76 struct i2c_adapter *i2c)
77{
78 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
79 return NULL;
80}
81#endif /* CONFIG_DVB_S5H1409 */
82
83#endif /* __S5H1409_H__ */
84
85/*
86 * Local variables:
87 * c-basic-offset: 8
88 */
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c
new file mode 100644
index 00000000000..d8adf1e3201
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1411.c
@@ -0,0 +1,923 @@
1/*
2 Samsung S5H1411 VSB/QAM demodulator driver
3
4 Copyright (C) 2008 Steven Toth <stoth@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 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 <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/slab.h>
27#include <linux/delay.h>
28#include "dvb_frontend.h"
29#include "s5h1411.h"
30
31struct s5h1411_state {
32
33 struct i2c_adapter *i2c;
34
35 /* configuration settings */
36 const struct s5h1411_config *config;
37
38 struct dvb_frontend frontend;
39
40 fe_modulation_t current_modulation;
41 unsigned int first_tune:1;
42
43 u32 current_frequency;
44 int if_freq;
45
46 u8 inversion;
47};
48
49static int debug;
50
51#define dprintk(arg...) do { \
52 if (debug) \
53 printk(arg); \
54 } while (0)
55
56/* Register values to initialise the demod, defaults to VSB */
57static struct init_tab {
58 u8 addr;
59 u8 reg;
60 u16 data;
61} init_tab[] = {
62 { S5H1411_I2C_TOP_ADDR, 0x00, 0x0071, },
63 { S5H1411_I2C_TOP_ADDR, 0x08, 0x0047, },
64 { S5H1411_I2C_TOP_ADDR, 0x1c, 0x0400, },
65 { S5H1411_I2C_TOP_ADDR, 0x1e, 0x0370, },
66 { S5H1411_I2C_TOP_ADDR, 0x1f, 0x342c, },
67 { S5H1411_I2C_TOP_ADDR, 0x24, 0x0231, },
68 { S5H1411_I2C_TOP_ADDR, 0x25, 0x1011, },
69 { S5H1411_I2C_TOP_ADDR, 0x26, 0x0f07, },
70 { S5H1411_I2C_TOP_ADDR, 0x27, 0x0f04, },
71 { S5H1411_I2C_TOP_ADDR, 0x28, 0x070f, },
72 { S5H1411_I2C_TOP_ADDR, 0x29, 0x2820, },
73 { S5H1411_I2C_TOP_ADDR, 0x2a, 0x102e, },
74 { S5H1411_I2C_TOP_ADDR, 0x2b, 0x0220, },
75 { S5H1411_I2C_TOP_ADDR, 0x2e, 0x0d0e, },
76 { S5H1411_I2C_TOP_ADDR, 0x2f, 0x1013, },
77 { S5H1411_I2C_TOP_ADDR, 0x31, 0x171b, },
78 { S5H1411_I2C_TOP_ADDR, 0x32, 0x0e0f, },
79 { S5H1411_I2C_TOP_ADDR, 0x33, 0x0f10, },
80 { S5H1411_I2C_TOP_ADDR, 0x34, 0x170e, },
81 { S5H1411_I2C_TOP_ADDR, 0x35, 0x4b10, },
82 { S5H1411_I2C_TOP_ADDR, 0x36, 0x0f17, },
83 { S5H1411_I2C_TOP_ADDR, 0x3c, 0x1577, },
84 { S5H1411_I2C_TOP_ADDR, 0x3d, 0x081a, },
85 { S5H1411_I2C_TOP_ADDR, 0x3e, 0x77ee, },
86 { S5H1411_I2C_TOP_ADDR, 0x40, 0x1e09, },
87 { S5H1411_I2C_TOP_ADDR, 0x41, 0x0f0c, },
88 { S5H1411_I2C_TOP_ADDR, 0x42, 0x1f10, },
89 { S5H1411_I2C_TOP_ADDR, 0x4d, 0x0509, },
90 { S5H1411_I2C_TOP_ADDR, 0x4e, 0x0a00, },
91 { S5H1411_I2C_TOP_ADDR, 0x50, 0x0000, },
92 { S5H1411_I2C_TOP_ADDR, 0x5b, 0x0000, },
93 { S5H1411_I2C_TOP_ADDR, 0x5c, 0x0008, },
94 { S5H1411_I2C_TOP_ADDR, 0x57, 0x1101, },
95 { S5H1411_I2C_TOP_ADDR, 0x65, 0x007c, },
96 { S5H1411_I2C_TOP_ADDR, 0x68, 0x0512, },
97 { S5H1411_I2C_TOP_ADDR, 0x69, 0x0258, },
98 { S5H1411_I2C_TOP_ADDR, 0x70, 0x0004, },
99 { S5H1411_I2C_TOP_ADDR, 0x71, 0x0007, },
100 { S5H1411_I2C_TOP_ADDR, 0x76, 0x00a9, },
101 { S5H1411_I2C_TOP_ADDR, 0x78, 0x3141, },
102 { S5H1411_I2C_TOP_ADDR, 0x7a, 0x3141, },
103 { S5H1411_I2C_TOP_ADDR, 0xb3, 0x8003, },
104 { S5H1411_I2C_TOP_ADDR, 0xb5, 0xa6bb, },
105 { S5H1411_I2C_TOP_ADDR, 0xb6, 0x0609, },
106 { S5H1411_I2C_TOP_ADDR, 0xb7, 0x2f06, },
107 { S5H1411_I2C_TOP_ADDR, 0xb8, 0x003f, },
108 { S5H1411_I2C_TOP_ADDR, 0xb9, 0x2700, },
109 { S5H1411_I2C_TOP_ADDR, 0xba, 0xfac8, },
110 { S5H1411_I2C_TOP_ADDR, 0xbe, 0x1003, },
111 { S5H1411_I2C_TOP_ADDR, 0xbf, 0x103f, },
112 { S5H1411_I2C_TOP_ADDR, 0xce, 0x2000, },
113 { S5H1411_I2C_TOP_ADDR, 0xcf, 0x0800, },
114 { S5H1411_I2C_TOP_ADDR, 0xd0, 0x0800, },
115 { S5H1411_I2C_TOP_ADDR, 0xd1, 0x0400, },
116 { S5H1411_I2C_TOP_ADDR, 0xd2, 0x0800, },
117 { S5H1411_I2C_TOP_ADDR, 0xd3, 0x2000, },
118 { S5H1411_I2C_TOP_ADDR, 0xd4, 0x3000, },
119 { S5H1411_I2C_TOP_ADDR, 0xdb, 0x4a9b, },
120 { S5H1411_I2C_TOP_ADDR, 0xdc, 0x1000, },
121 { S5H1411_I2C_TOP_ADDR, 0xde, 0x0001, },
122 { S5H1411_I2C_TOP_ADDR, 0xdf, 0x0000, },
123 { S5H1411_I2C_TOP_ADDR, 0xe3, 0x0301, },
124 { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0000, },
125 { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0001, },
126 { S5H1411_I2C_QAM_ADDR, 0x08, 0x0600, },
127 { S5H1411_I2C_QAM_ADDR, 0x18, 0x4201, },
128 { S5H1411_I2C_QAM_ADDR, 0x1e, 0x6476, },
129 { S5H1411_I2C_QAM_ADDR, 0x21, 0x0830, },
130 { S5H1411_I2C_QAM_ADDR, 0x0c, 0x5679, },
131 { S5H1411_I2C_QAM_ADDR, 0x0d, 0x579b, },
132 { S5H1411_I2C_QAM_ADDR, 0x24, 0x0102, },
133 { S5H1411_I2C_QAM_ADDR, 0x31, 0x7488, },
134 { S5H1411_I2C_QAM_ADDR, 0x32, 0x0a08, },
135 { S5H1411_I2C_QAM_ADDR, 0x3d, 0x8689, },
136 { S5H1411_I2C_QAM_ADDR, 0x49, 0x0048, },
137 { S5H1411_I2C_QAM_ADDR, 0x57, 0x2012, },
138 { S5H1411_I2C_QAM_ADDR, 0x5d, 0x7676, },
139 { S5H1411_I2C_QAM_ADDR, 0x04, 0x0400, },
140 { S5H1411_I2C_QAM_ADDR, 0x58, 0x00c0, },
141 { S5H1411_I2C_QAM_ADDR, 0x5b, 0x0100, },
142};
143
144/* VSB SNR lookup table */
145static struct vsb_snr_tab {
146 u16 val;
147 u16 data;
148} vsb_snr_tab[] = {
149 { 0x39f, 300, },
150 { 0x39b, 295, },
151 { 0x397, 290, },
152 { 0x394, 285, },
153 { 0x38f, 280, },
154 { 0x38b, 275, },
155 { 0x387, 270, },
156 { 0x382, 265, },
157 { 0x37d, 260, },
158 { 0x377, 255, },
159 { 0x370, 250, },
160 { 0x36a, 245, },
161 { 0x364, 240, },
162 { 0x35b, 235, },
163 { 0x353, 230, },
164 { 0x349, 225, },
165 { 0x340, 320, },
166 { 0x337, 215, },
167 { 0x327, 210, },
168 { 0x31b, 205, },
169 { 0x310, 200, },
170 { 0x302, 195, },
171 { 0x2f3, 190, },
172 { 0x2e4, 185, },
173 { 0x2d7, 180, },
174 { 0x2cd, 175, },
175 { 0x2bb, 170, },
176 { 0x2a9, 165, },
177 { 0x29e, 160, },
178 { 0x284, 155, },
179 { 0x27a, 150, },
180 { 0x260, 145, },
181 { 0x23a, 140, },
182 { 0x224, 135, },
183 { 0x213, 130, },
184 { 0x204, 125, },
185 { 0x1fe, 120, },
186 { 0, 0, },
187};
188
189/* QAM64 SNR lookup table */
190static struct qam64_snr_tab {
191 u16 val;
192 u16 data;
193} qam64_snr_tab[] = {
194 { 0x0001, 0, },
195 { 0x0af0, 300, },
196 { 0x0d80, 290, },
197 { 0x10a0, 280, },
198 { 0x14b5, 270, },
199 { 0x1590, 268, },
200 { 0x1680, 266, },
201 { 0x17b0, 264, },
202 { 0x18c0, 262, },
203 { 0x19b0, 260, },
204 { 0x1ad0, 258, },
205 { 0x1d00, 256, },
206 { 0x1da0, 254, },
207 { 0x1ef0, 252, },
208 { 0x2050, 250, },
209 { 0x20f0, 249, },
210 { 0x21d0, 248, },
211 { 0x22b0, 247, },
212 { 0x23a0, 246, },
213 { 0x2470, 245, },
214 { 0x24f0, 244, },
215 { 0x25a0, 243, },
216 { 0x26c0, 242, },
217 { 0x27b0, 241, },
218 { 0x28d0, 240, },
219 { 0x29b0, 239, },
220 { 0x2ad0, 238, },
221 { 0x2ba0, 237, },
222 { 0x2c80, 236, },
223 { 0x2d20, 235, },
224 { 0x2e00, 234, },
225 { 0x2f10, 233, },
226 { 0x3050, 232, },
227 { 0x3190, 231, },
228 { 0x3300, 230, },
229 { 0x3340, 229, },
230 { 0x3200, 228, },
231 { 0x3550, 227, },
232 { 0x3610, 226, },
233 { 0x3600, 225, },
234 { 0x3700, 224, },
235 { 0x3800, 223, },
236 { 0x3920, 222, },
237 { 0x3a20, 221, },
238 { 0x3b30, 220, },
239 { 0x3d00, 219, },
240 { 0x3e00, 218, },
241 { 0x4000, 217, },
242 { 0x4100, 216, },
243 { 0x4300, 215, },
244 { 0x4400, 214, },
245 { 0x4600, 213, },
246 { 0x4700, 212, },
247 { 0x4800, 211, },
248 { 0x4a00, 210, },
249 { 0x4b00, 209, },
250 { 0x4d00, 208, },
251 { 0x4f00, 207, },
252 { 0x5050, 206, },
253 { 0x5200, 205, },
254 { 0x53c0, 204, },
255 { 0x5450, 203, },
256 { 0x5650, 202, },
257 { 0x5820, 201, },
258 { 0x6000, 200, },
259 { 0xffff, 0, },
260};
261
262/* QAM256 SNR lookup table */
263static struct qam256_snr_tab {
264 u16 val;
265 u16 data;
266} qam256_snr_tab[] = {
267 { 0x0001, 0, },
268 { 0x0970, 400, },
269 { 0x0a90, 390, },
270 { 0x0b90, 380, },
271 { 0x0d90, 370, },
272 { 0x0ff0, 360, },
273 { 0x1240, 350, },
274 { 0x1345, 348, },
275 { 0x13c0, 346, },
276 { 0x14c0, 344, },
277 { 0x1500, 342, },
278 { 0x1610, 340, },
279 { 0x1700, 338, },
280 { 0x1800, 336, },
281 { 0x18b0, 334, },
282 { 0x1900, 332, },
283 { 0x1ab0, 330, },
284 { 0x1bc0, 328, },
285 { 0x1cb0, 326, },
286 { 0x1db0, 324, },
287 { 0x1eb0, 322, },
288 { 0x2030, 320, },
289 { 0x2200, 318, },
290 { 0x2280, 316, },
291 { 0x2410, 314, },
292 { 0x25b0, 312, },
293 { 0x27a0, 310, },
294 { 0x2840, 308, },
295 { 0x29d0, 306, },
296 { 0x2b10, 304, },
297 { 0x2d30, 302, },
298 { 0x2f20, 300, },
299 { 0x30c0, 298, },
300 { 0x3260, 297, },
301 { 0x32c0, 296, },
302 { 0x3300, 295, },
303 { 0x33b0, 294, },
304 { 0x34b0, 293, },
305 { 0x35a0, 292, },
306 { 0x3650, 291, },
307 { 0x3800, 290, },
308 { 0x3900, 289, },
309 { 0x3a50, 288, },
310 { 0x3b30, 287, },
311 { 0x3cb0, 286, },
312 { 0x3e20, 285, },
313 { 0x3fa0, 284, },
314 { 0x40a0, 283, },
315 { 0x41c0, 282, },
316 { 0x42f0, 281, },
317 { 0x44a0, 280, },
318 { 0x4600, 279, },
319 { 0x47b0, 278, },
320 { 0x4900, 277, },
321 { 0x4a00, 276, },
322 { 0x4ba0, 275, },
323 { 0x4d00, 274, },
324 { 0x4f00, 273, },
325 { 0x5000, 272, },
326 { 0x51f0, 272, },
327 { 0x53a0, 270, },
328 { 0x5520, 269, },
329 { 0x5700, 268, },
330 { 0x5800, 267, },
331 { 0x5a00, 266, },
332 { 0x5c00, 265, },
333 { 0x5d00, 264, },
334 { 0x5f00, 263, },
335 { 0x6000, 262, },
336 { 0x6200, 261, },
337 { 0x6400, 260, },
338 { 0xffff, 0, },
339};
340
341/* 8 bit registers, 16 bit values */
342static int s5h1411_writereg(struct s5h1411_state *state,
343 u8 addr, u8 reg, u16 data)
344{
345 int ret;
346 u8 buf[] = { reg, data >> 8, data & 0xff };
347
348 struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
349
350 ret = i2c_transfer(state->i2c, &msg, 1);
351
352 if (ret != 1)
353 printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, "
354 "ret == %i)\n", __func__, addr, reg, data, ret);
355
356 return (ret != 1) ? -1 : 0;
357}
358
359static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg)
360{
361 int ret;
362 u8 b0[] = { reg };
363 u8 b1[] = { 0, 0 };
364
365 struct i2c_msg msg[] = {
366 { .addr = addr, .flags = 0, .buf = b0, .len = 1 },
367 { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
368
369 ret = i2c_transfer(state->i2c, msg, 2);
370
371 if (ret != 2)
372 printk(KERN_ERR "%s: readreg error (ret == %i)\n",
373 __func__, ret);
374 return (b1[0] << 8) | b1[1];
375}
376
377static int s5h1411_softreset(struct dvb_frontend *fe)
378{
379 struct s5h1411_state *state = fe->demodulator_priv;
380
381 dprintk("%s()\n", __func__);
382
383 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 0);
384 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 1);
385 return 0;
386}
387
388static int s5h1411_set_if_freq(struct dvb_frontend *fe, int KHz)
389{
390 struct s5h1411_state *state = fe->demodulator_priv;
391
392 dprintk("%s(%d KHz)\n", __func__, KHz);
393
394 switch (KHz) {
395 case 3250:
396 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x10d5);
397 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x5342);
398 s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x10d9);
399 break;
400 case 3500:
401 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1225);
402 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x1e96);
403 s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1225);
404 break;
405 case 4000:
406 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x14bc);
407 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0xb53e);
408 s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x14bd);
409 break;
410 default:
411 dprintk("%s(%d KHz) Invalid, defaulting to 5380\n",
412 __func__, KHz);
413 /* no break, need to continue */
414 case 5380:
415 case 44000:
416 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1be4);
417 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x3655);
418 s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1be4);
419 break;
420 }
421
422 state->if_freq = KHz;
423
424 return 0;
425}
426
427static int s5h1411_set_mpeg_timing(struct dvb_frontend *fe, int mode)
428{
429 struct s5h1411_state *state = fe->demodulator_priv;
430 u16 val;
431
432 dprintk("%s(%d)\n", __func__, mode);
433
434 val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbe) & 0xcfff;
435 switch (mode) {
436 case S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK:
437 val |= 0x0000;
438 break;
439 case S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK:
440 dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode);
441 val |= 0x1000;
442 break;
443 case S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK:
444 val |= 0x2000;
445 break;
446 case S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK:
447 val |= 0x3000;
448 break;
449 default:
450 return -EINVAL;
451 }
452
453 /* Configure MPEG Signal Timing charactistics */
454 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbe, val);
455}
456
457static int s5h1411_set_spectralinversion(struct dvb_frontend *fe, int inversion)
458{
459 struct s5h1411_state *state = fe->demodulator_priv;
460 u16 val;
461
462 dprintk("%s(%d)\n", __func__, inversion);
463 val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x24) & ~0x1000;
464
465 if (inversion == 1)
466 val |= 0x1000; /* Inverted */
467
468 state->inversion = inversion;
469 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x24, val);
470}
471
472static int s5h1411_set_serialmode(struct dvb_frontend *fe, int serial)
473{
474 struct s5h1411_state *state = fe->demodulator_priv;
475 u16 val;
476
477 dprintk("%s(%d)\n", __func__, serial);
478 val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbd) & ~0x100;
479
480 if (serial == 1)
481 val |= 0x100;
482
483 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, val);
484}
485
486static int s5h1411_enable_modulation(struct dvb_frontend *fe,
487 fe_modulation_t m)
488{
489 struct s5h1411_state *state = fe->demodulator_priv;
490
491 dprintk("%s(0x%08x)\n", __func__, m);
492
493 if ((state->first_tune == 0) && (m == state->current_modulation)) {
494 dprintk("%s() Already at desired modulation. Skipping...\n",
495 __func__);
496 return 0;
497 }
498
499 switch (m) {
500 case VSB_8:
501 dprintk("%s() VSB_8\n", __func__);
502 s5h1411_set_if_freq(fe, state->config->vsb_if);
503 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x71);
504 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x00);
505 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0xf1);
506 break;
507 case QAM_64:
508 case QAM_256:
509 case QAM_AUTO:
510 dprintk("%s() QAM_AUTO (64/256)\n", __func__);
511 s5h1411_set_if_freq(fe, state->config->qam_if);
512 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x0171);
513 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x0001);
514 s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x16, 0x1101);
515 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0x00f0);
516 break;
517 default:
518 dprintk("%s() Invalid modulation\n", __func__);
519 return -EINVAL;
520 }
521
522 state->current_modulation = m;
523 state->first_tune = 0;
524 s5h1411_softreset(fe);
525
526 return 0;
527}
528
529static int s5h1411_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
530{
531 struct s5h1411_state *state = fe->demodulator_priv;
532
533 dprintk("%s(%d)\n", __func__, enable);
534
535 if (enable)
536 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1);
537 else
538 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 0);
539}
540
541static int s5h1411_set_gpio(struct dvb_frontend *fe, int enable)
542{
543 struct s5h1411_state *state = fe->demodulator_priv;
544 u16 val;
545
546 dprintk("%s(%d)\n", __func__, enable);
547
548 val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xe0) & ~0x02;
549
550 if (enable)
551 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0,
552 val | 0x02);
553 else
554 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, val);
555}
556
557static int s5h1411_set_powerstate(struct dvb_frontend *fe, int enable)
558{
559 struct s5h1411_state *state = fe->demodulator_priv;
560
561 dprintk("%s(%d)\n", __func__, enable);
562
563 if (enable)
564 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 1);
565 else {
566 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 0);
567 s5h1411_softreset(fe);
568 }
569
570 return 0;
571}
572
573static int s5h1411_sleep(struct dvb_frontend *fe)
574{
575 return s5h1411_set_powerstate(fe, 1);
576}
577
578static int s5h1411_register_reset(struct dvb_frontend *fe)
579{
580 struct s5h1411_state *state = fe->demodulator_priv;
581
582 dprintk("%s()\n", __func__);
583
584 return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf3, 0);
585}
586
587/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
588static int s5h1411_set_frontend(struct dvb_frontend *fe,
589 struct dvb_frontend_parameters *p)
590{
591 struct s5h1411_state *state = fe->demodulator_priv;
592
593 dprintk("%s(frequency=%d)\n", __func__, p->frequency);
594
595 s5h1411_softreset(fe);
596
597 state->current_frequency = p->frequency;
598
599 s5h1411_enable_modulation(fe, p->u.vsb.modulation);
600
601 if (fe->ops.tuner_ops.set_params) {
602 if (fe->ops.i2c_gate_ctrl)
603 fe->ops.i2c_gate_ctrl(fe, 1);
604
605 fe->ops.tuner_ops.set_params(fe, p);
606
607 if (fe->ops.i2c_gate_ctrl)
608 fe->ops.i2c_gate_ctrl(fe, 0);
609 }
610
611 /* Issue a reset to the demod so it knows to resync against the
612 newly tuned frequency */
613 s5h1411_softreset(fe);
614
615 return 0;
616}
617
618/* Reset the demod hardware and reset all of the configuration registers
619 to a default state. */
620static int s5h1411_init(struct dvb_frontend *fe)
621{
622 struct s5h1411_state *state = fe->demodulator_priv;
623 int i;
624
625 dprintk("%s()\n", __func__);
626
627 s5h1411_set_powerstate(fe, 0);
628 s5h1411_register_reset(fe);
629
630 for (i = 0; i < ARRAY_SIZE(init_tab); i++)
631 s5h1411_writereg(state, init_tab[i].addr,
632 init_tab[i].reg,
633 init_tab[i].data);
634
635 /* The datasheet says that after initialisation, VSB is default */
636 state->current_modulation = VSB_8;
637
638 /* Although the datasheet says it's in VSB, empirical evidence
639 shows problems getting lock on the first tuning request. Make
640 sure we call enable_modulation the first time around */
641 state->first_tune = 1;
642
643 if (state->config->output_mode == S5H1411_SERIAL_OUTPUT)
644 /* Serial */
645 s5h1411_set_serialmode(fe, 1);
646 else
647 /* Parallel */
648 s5h1411_set_serialmode(fe, 0);
649
650 s5h1411_set_spectralinversion(fe, state->config->inversion);
651 s5h1411_set_if_freq(fe, state->config->vsb_if);
652 s5h1411_set_gpio(fe, state->config->gpio);
653 s5h1411_set_mpeg_timing(fe, state->config->mpeg_timing);
654 s5h1411_softreset(fe);
655
656 /* Note: Leaving the I2C gate closed. */
657 s5h1411_i2c_gate_ctrl(fe, 0);
658
659 return 0;
660}
661
662static int s5h1411_read_status(struct dvb_frontend *fe, fe_status_t *status)
663{
664 struct s5h1411_state *state = fe->demodulator_priv;
665 u16 reg;
666 u32 tuner_status = 0;
667
668 *status = 0;
669
670 /* Register F2 bit 15 = Master Lock, removed */
671
672 switch (state->current_modulation) {
673 case QAM_64:
674 case QAM_256:
675 reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf0);
676 if (reg & 0x10) /* QAM FEC Lock */
677 *status |= FE_HAS_SYNC | FE_HAS_LOCK;
678 if (reg & 0x100) /* QAM EQ Lock */
679 *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;
680
681 break;
682 case VSB_8:
683 reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2);
684 if (reg & 0x1000) /* FEC Lock */
685 *status |= FE_HAS_SYNC | FE_HAS_LOCK;
686 if (reg & 0x2000) /* EQ Lock */
687 *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;
688
689 reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x53);
690 if (reg & 0x1) /* AFC Lock */
691 *status |= FE_HAS_SIGNAL;
692
693 break;
694 default:
695 return -EINVAL;
696 }
697
698 switch (state->config->status_mode) {
699 case S5H1411_DEMODLOCKING:
700 if (*status & FE_HAS_VITERBI)
701 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
702 break;
703 case S5H1411_TUNERLOCKING:
704 /* Get the tuner status */
705 if (fe->ops.tuner_ops.get_status) {
706 if (fe->ops.i2c_gate_ctrl)
707 fe->ops.i2c_gate_ctrl(fe, 1);
708
709 fe->ops.tuner_ops.get_status(fe, &tuner_status);
710
711 if (fe->ops.i2c_gate_ctrl)
712 fe->ops.i2c_gate_ctrl(fe, 0);
713 }
714 if (tuner_status)
715 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
716 break;
717 }
718
719 dprintk("%s() status 0x%08x\n", __func__, *status);
720
721 return 0;
722}
723
724static int s5h1411_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
725{
726 int i, ret = -EINVAL;
727 dprintk("%s()\n", __func__);
728
729 for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) {
730 if (v < qam256_snr_tab[i].val) {
731 *snr = qam256_snr_tab[i].data;
732 ret = 0;
733 break;
734 }
735 }
736 return ret;
737}
738
739static int s5h1411_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
740{
741 int i, ret = -EINVAL;
742 dprintk("%s()\n", __func__);
743
744 for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) {
745 if (v < qam64_snr_tab[i].val) {
746 *snr = qam64_snr_tab[i].data;
747 ret = 0;
748 break;
749 }
750 }
751 return ret;
752}
753
754static int s5h1411_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
755{
756 int i, ret = -EINVAL;
757 dprintk("%s()\n", __func__);
758
759 for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) {
760 if (v > vsb_snr_tab[i].val) {
761 *snr = vsb_snr_tab[i].data;
762 ret = 0;
763 break;
764 }
765 }
766 dprintk("%s() snr=%d\n", __func__, *snr);
767 return ret;
768}
769
770static int s5h1411_read_snr(struct dvb_frontend *fe, u16 *snr)
771{
772 struct s5h1411_state *state = fe->demodulator_priv;
773 u16 reg;
774 dprintk("%s()\n", __func__);
775
776 switch (state->current_modulation) {
777 case QAM_64:
778 reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1);
779 return s5h1411_qam64_lookup_snr(fe, snr, reg);
780 case QAM_256:
781 reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1);
782 return s5h1411_qam256_lookup_snr(fe, snr, reg);
783 case VSB_8:
784 reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR,
785 0xf2) & 0x3ff;
786 return s5h1411_vsb_lookup_snr(fe, snr, reg);
787 default:
788 break;
789 }
790
791 return -EINVAL;
792}
793
794static int s5h1411_read_signal_strength(struct dvb_frontend *fe,
795 u16 *signal_strength)
796{
797 return s5h1411_read_snr(fe, signal_strength);
798}
799
800static int s5h1411_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
801{
802 struct s5h1411_state *state = fe->demodulator_priv;
803
804 *ucblocks = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xc9);
805
806 return 0;
807}
808
809static int s5h1411_read_ber(struct dvb_frontend *fe, u32 *ber)
810{
811 return s5h1411_read_ucblocks(fe, ber);
812}
813
814static int s5h1411_get_frontend(struct dvb_frontend *fe,
815 struct dvb_frontend_parameters *p)
816{
817 struct s5h1411_state *state = fe->demodulator_priv;
818
819 p->frequency = state->current_frequency;
820 p->u.vsb.modulation = state->current_modulation;
821
822 return 0;
823}
824
825static int s5h1411_get_tune_settings(struct dvb_frontend *fe,
826 struct dvb_frontend_tune_settings *tune)
827{
828 tune->min_delay_ms = 1000;
829 return 0;
830}
831
832static void s5h1411_release(struct dvb_frontend *fe)
833{
834 struct s5h1411_state *state = fe->demodulator_priv;
835 kfree(state);
836}
837
838static struct dvb_frontend_ops s5h1411_ops;
839
840struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
841 struct i2c_adapter *i2c)
842{
843 struct s5h1411_state *state = NULL;
844 u16 reg;
845
846 /* allocate memory for the internal state */
847 state = kzalloc(sizeof(struct s5h1411_state), GFP_KERNEL);
848 if (state == NULL)
849 goto error;
850
851 /* setup the state */
852 state->config = config;
853 state->i2c = i2c;
854 state->current_modulation = VSB_8;
855 state->inversion = state->config->inversion;
856
857 /* check if the demod exists */
858 reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x05);
859 if (reg != 0x0066)
860 goto error;
861
862 /* create dvb_frontend */
863 memcpy(&state->frontend.ops, &s5h1411_ops,
864 sizeof(struct dvb_frontend_ops));
865
866 state->frontend.demodulator_priv = state;
867
868 if (s5h1411_init(&state->frontend) != 0) {
869 printk(KERN_ERR "%s: Failed to initialize correctly\n",
870 __func__);
871 goto error;
872 }
873
874 /* Note: Leaving the I2C gate open here. */
875 s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1);
876
877 /* Put the device into low-power mode until first use */
878 s5h1411_set_powerstate(&state->frontend, 1);
879
880 return &state->frontend;
881
882error:
883 kfree(state);
884 return NULL;
885}
886EXPORT_SYMBOL(s5h1411_attach);
887
888static struct dvb_frontend_ops s5h1411_ops = {
889
890 .info = {
891 .name = "Samsung S5H1411 QAM/8VSB Frontend",
892 .type = FE_ATSC,
893 .frequency_min = 54000000,
894 .frequency_max = 858000000,
895 .frequency_stepsize = 62500,
896 .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
897 },
898
899 .init = s5h1411_init,
900 .sleep = s5h1411_sleep,
901 .i2c_gate_ctrl = s5h1411_i2c_gate_ctrl,
902 .set_frontend = s5h1411_set_frontend,
903 .get_frontend = s5h1411_get_frontend,
904 .get_tune_settings = s5h1411_get_tune_settings,
905 .read_status = s5h1411_read_status,
906 .read_ber = s5h1411_read_ber,
907 .read_signal_strength = s5h1411_read_signal_strength,
908 .read_snr = s5h1411_read_snr,
909 .read_ucblocks = s5h1411_read_ucblocks,
910 .release = s5h1411_release,
911};
912
913module_param(debug, int, 0644);
914MODULE_PARM_DESC(debug, "Enable verbose debug messages");
915
916MODULE_DESCRIPTION("Samsung S5H1411 QAM-B/ATSC Demodulator driver");
917MODULE_AUTHOR("Steven Toth");
918MODULE_LICENSE("GPL");
919
920/*
921 * Local variables:
922 * c-basic-offset: 8
923 */
diff --git a/drivers/media/dvb/frontends/s5h1411.h b/drivers/media/dvb/frontends/s5h1411.h
new file mode 100644
index 00000000000..45ec0f82989
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1411.h
@@ -0,0 +1,90 @@
1/*
2 Samsung S5H1411 VSB/QAM demodulator driver
3
4 Copyright (C) 2008 Steven Toth <stoth@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 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 __S5H1411_H__
23#define __S5H1411_H__
24
25#include <linux/dvb/frontend.h>
26
27#define S5H1411_I2C_TOP_ADDR (0x32 >> 1)
28#define S5H1411_I2C_QAM_ADDR (0x34 >> 1)
29
30struct s5h1411_config {
31
32 /* serial/parallel output */
33#define S5H1411_PARALLEL_OUTPUT 0
34#define S5H1411_SERIAL_OUTPUT 1
35 u8 output_mode;
36
37 /* GPIO Setting */
38#define S5H1411_GPIO_OFF 0
39#define S5H1411_GPIO_ON 1
40 u8 gpio;
41
42 /* MPEG signal timing */
43#define S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0
44#define S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1
45#define S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2
46#define S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
47 u16 mpeg_timing;
48
49 /* IF Freq for QAM and VSB in KHz */
50#define S5H1411_IF_3250 3250
51#define S5H1411_IF_3500 3500
52#define S5H1411_IF_4000 4000
53#define S5H1411_IF_5380 5380
54#define S5H1411_IF_44000 44000
55#define S5H1411_VSB_IF_DEFAULT S5H1411_IF_44000
56#define S5H1411_QAM_IF_DEFAULT S5H1411_IF_44000
57 u16 qam_if;
58 u16 vsb_if;
59
60 /* Spectral Inversion */
61#define S5H1411_INVERSION_OFF 0
62#define S5H1411_INVERSION_ON 1
63 u8 inversion;
64
65 /* Return lock status based on tuner lock, or demod lock */
66#define S5H1411_TUNERLOCKING 0
67#define S5H1411_DEMODLOCKING 1
68 u8 status_mode;
69};
70
71#if defined(CONFIG_DVB_S5H1411) || \
72 (defined(CONFIG_DVB_S5H1411_MODULE) && defined(MODULE))
73extern struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
74 struct i2c_adapter *i2c);
75#else
76static inline struct dvb_frontend *s5h1411_attach(
77 const struct s5h1411_config *config,
78 struct i2c_adapter *i2c)
79{
80 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
81 return NULL;
82}
83#endif /* CONFIG_DVB_S5H1411 */
84
85#endif /* __S5H1411_H__ */
86
87/*
88 * Local variables:
89 * c-basic-offset: 8
90 */
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
new file mode 100644
index 00000000000..3879d2e378a
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -0,0 +1,981 @@
1/*
2 * Driver for
3 * Samsung S5H1420 and
4 * PnpNetwork PN1010 QPSK Demodulator
5 *
6 * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
7 * Copyright (C) 2005-8 Patrick Boettcher <pb@linuxtv.org>
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 *
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
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/init.h>
28#include <linux/string.h>
29#include <linux/slab.h>
30#include <linux/delay.h>
31#include <linux/jiffies.h>
32#include <asm/div64.h>
33
34#include <linux/i2c.h>
35
36
37#include "dvb_frontend.h"
38#include "s5h1420.h"
39#include "s5h1420_priv.h"
40
41#define TONE_FREQ 22000
42
43struct s5h1420_state {
44 struct i2c_adapter* i2c;
45 const struct s5h1420_config* config;
46
47 struct dvb_frontend frontend;
48 struct i2c_adapter tuner_i2c_adapter;
49
50 u8 CON_1_val;
51
52 u8 postlocked:1;
53 u32 fclk;
54 u32 tunedfreq;
55 fe_code_rate_t fec_inner;
56 u32 symbol_rate;
57
58 /* FIXME: ugly workaround for flexcop's incapable i2c-controller
59 * it does not support repeated-start, workaround: write addr-1
60 * and then read
61 */
62 u8 shadow[256];
63};
64
65static u32 s5h1420_getsymbolrate(struct s5h1420_state* state);
66static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
67 struct dvb_frontend_tune_settings* fesettings);
68
69
70static int debug;
71module_param(debug, int, 0644);
72MODULE_PARM_DESC(debug, "enable debugging");
73
74#define dprintk(x...) do { \
75 if (debug) \
76 printk(KERN_DEBUG "S5H1420: " x); \
77} while (0)
78
79static u8 s5h1420_readreg(struct s5h1420_state *state, u8 reg)
80{
81 int ret;
82 u8 b[2];
83 struct i2c_msg msg[] = {
84 { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = 2 },
85 { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
86 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = 1 },
87 };
88
89 b[0] = (reg - 1) & 0xff;
90 b[1] = state->shadow[(reg - 1) & 0xff];
91
92 if (state->config->repeated_start_workaround) {
93 ret = i2c_transfer(state->i2c, msg, 3);
94 if (ret != 3)
95 return ret;
96 } else {
97 ret = i2c_transfer(state->i2c, &msg[1], 1);
98 if (ret != 1)
99 return ret;
100 ret = i2c_transfer(state->i2c, &msg[2], 1);
101 if (ret != 1)
102 return ret;
103 }
104
105 /* dprintk("rd(%02x): %02x %02x\n", state->config->demod_address, reg, b[0]); */
106
107 return b[0];
108}
109
110static int s5h1420_writereg (struct s5h1420_state* state, u8 reg, u8 data)
111{
112 u8 buf[] = { reg, data };
113 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
114 int err;
115
116 /* dprintk("wr(%02x): %02x %02x\n", state->config->demod_address, reg, data); */
117 err = i2c_transfer(state->i2c, &msg, 1);
118 if (err != 1) {
119 dprintk("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
120 return -EREMOTEIO;
121 }
122 state->shadow[reg] = data;
123
124 return 0;
125}
126
127static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
128{
129 struct s5h1420_state* state = fe->demodulator_priv;
130
131 dprintk("enter %s\n", __func__);
132
133 switch(voltage) {
134 case SEC_VOLTAGE_13:
135 s5h1420_writereg(state, 0x3c,
136 (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02);
137 break;
138
139 case SEC_VOLTAGE_18:
140 s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) | 0x03);
141 break;
142
143 case SEC_VOLTAGE_OFF:
144 s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) & 0xfd);
145 break;
146 }
147
148 dprintk("leave %s\n", __func__);
149 return 0;
150}
151
152static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
153{
154 struct s5h1420_state* state = fe->demodulator_priv;
155
156 dprintk("enter %s\n", __func__);
157 switch(tone) {
158 case SEC_TONE_ON:
159 s5h1420_writereg(state, 0x3b,
160 (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08);
161 break;
162
163 case SEC_TONE_OFF:
164 s5h1420_writereg(state, 0x3b,
165 (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
166 break;
167 }
168 dprintk("leave %s\n", __func__);
169
170 return 0;
171}
172
173static int s5h1420_send_master_cmd (struct dvb_frontend* fe,
174 struct dvb_diseqc_master_cmd* cmd)
175{
176 struct s5h1420_state* state = fe->demodulator_priv;
177 u8 val;
178 int i;
179 unsigned long timeout;
180 int result = 0;
181
182 dprintk("enter %s\n", __func__);
183 if (cmd->msg_len > 8)
184 return -EINVAL;
185
186 /* setup for DISEQC */
187 val = s5h1420_readreg(state, 0x3b);
188 s5h1420_writereg(state, 0x3b, 0x02);
189 msleep(15);
190
191 /* write the DISEQC command bytes */
192 for(i=0; i< cmd->msg_len; i++) {
193 s5h1420_writereg(state, 0x3d + i, cmd->msg[i]);
194 }
195
196 /* kick off transmission */
197 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) |
198 ((cmd->msg_len-1) << 4) | 0x08);
199
200 /* wait for transmission to complete */
201 timeout = jiffies + ((100*HZ) / 1000);
202 while(time_before(jiffies, timeout)) {
203 if (!(s5h1420_readreg(state, 0x3b) & 0x08))
204 break;
205
206 msleep(5);
207 }
208 if (time_after(jiffies, timeout))
209 result = -ETIMEDOUT;
210
211 /* restore original settings */
212 s5h1420_writereg(state, 0x3b, val);
213 msleep(15);
214 dprintk("leave %s\n", __func__);
215 return result;
216}
217
218static int s5h1420_recv_slave_reply (struct dvb_frontend* fe,
219 struct dvb_diseqc_slave_reply* reply)
220{
221 struct s5h1420_state* state = fe->demodulator_priv;
222 u8 val;
223 int i;
224 int length;
225 unsigned long timeout;
226 int result = 0;
227
228 /* setup for DISEQC receive */
229 val = s5h1420_readreg(state, 0x3b);
230 s5h1420_writereg(state, 0x3b, 0x82); /* FIXME: guess - do we need to set DIS_RDY(0x08) in receive mode? */
231 msleep(15);
232
233 /* wait for reception to complete */
234 timeout = jiffies + ((reply->timeout*HZ) / 1000);
235 while(time_before(jiffies, timeout)) {
236 if (!(s5h1420_readreg(state, 0x3b) & 0x80)) /* FIXME: do we test DIS_RDY(0x08) or RCV_EN(0x80)? */
237 break;
238
239 msleep(5);
240 }
241 if (time_after(jiffies, timeout)) {
242 result = -ETIMEDOUT;
243 goto exit;
244 }
245
246 /* check error flag - FIXME: not sure what this does - docs do not describe
247 * beyond "error flag for diseqc receive data :( */
248 if (s5h1420_readreg(state, 0x49)) {
249 result = -EIO;
250 goto exit;
251 }
252
253 /* check length */
254 length = (s5h1420_readreg(state, 0x3b) & 0x70) >> 4;
255 if (length > sizeof(reply->msg)) {
256 result = -EOVERFLOW;
257 goto exit;
258 }
259 reply->msg_len = length;
260
261 /* extract data */
262 for(i=0; i< length; i++) {
263 reply->msg[i] = s5h1420_readreg(state, 0x3d + i);
264 }
265
266exit:
267 /* restore original settings */
268 s5h1420_writereg(state, 0x3b, val);
269 msleep(15);
270 return result;
271}
272
273static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
274{
275 struct s5h1420_state* state = fe->demodulator_priv;
276 u8 val;
277 int result = 0;
278 unsigned long timeout;
279
280 /* setup for tone burst */
281 val = s5h1420_readreg(state, 0x3b);
282 s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x70) | 0x01);
283
284 /* set value for B position if requested */
285 if (minicmd == SEC_MINI_B) {
286 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x04);
287 }
288 msleep(15);
289
290 /* start transmission */
291 s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08);
292
293 /* wait for transmission to complete */
294 timeout = jiffies + ((100*HZ) / 1000);
295 while(time_before(jiffies, timeout)) {
296 if (!(s5h1420_readreg(state, 0x3b) & 0x08))
297 break;
298
299 msleep(5);
300 }
301 if (time_after(jiffies, timeout))
302 result = -ETIMEDOUT;
303
304 /* restore original settings */
305 s5h1420_writereg(state, 0x3b, val);
306 msleep(15);
307 return result;
308}
309
310static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state)
311{
312 u8 val;
313 fe_status_t status = 0;
314
315 val = s5h1420_readreg(state, 0x14);
316 if (val & 0x02)
317 status |= FE_HAS_SIGNAL;
318 if (val & 0x01)
319 status |= FE_HAS_CARRIER;
320 val = s5h1420_readreg(state, 0x36);
321 if (val & 0x01)
322 status |= FE_HAS_VITERBI;
323 if (val & 0x20)
324 status |= FE_HAS_SYNC;
325 if (status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|FE_HAS_SYNC))
326 status |= FE_HAS_LOCK;
327
328 return status;
329}
330
331static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
332{
333 struct s5h1420_state* state = fe->demodulator_priv;
334 u8 val;
335
336 dprintk("enter %s\n", __func__);
337
338 if (status == NULL)
339 return -EINVAL;
340
341 /* determine lock state */
342 *status = s5h1420_get_status_bits(state);
343
344 /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert
345 the inversion, wait a bit and check again */
346 if (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI)) {
347 val = s5h1420_readreg(state, Vit10);
348 if ((val & 0x07) == 0x03) {
349 if (val & 0x08)
350 s5h1420_writereg(state, Vit09, 0x13);
351 else
352 s5h1420_writereg(state, Vit09, 0x1b);
353
354 /* wait a bit then update lock status */
355 mdelay(200);
356 *status = s5h1420_get_status_bits(state);
357 }
358 }
359
360 /* perform post lock setup */
361 if ((*status & FE_HAS_LOCK) && !state->postlocked) {
362
363 /* calculate the data rate */
364 u32 tmp = s5h1420_getsymbolrate(state);
365 switch (s5h1420_readreg(state, Vit10) & 0x07) {
366 case 0: tmp = (tmp * 2 * 1) / 2; break;
367 case 1: tmp = (tmp * 2 * 2) / 3; break;
368 case 2: tmp = (tmp * 2 * 3) / 4; break;
369 case 3: tmp = (tmp * 2 * 5) / 6; break;
370 case 4: tmp = (tmp * 2 * 6) / 7; break;
371 case 5: tmp = (tmp * 2 * 7) / 8; break;
372 }
373
374 if (tmp == 0) {
375 printk(KERN_ERR "s5h1420: avoided division by 0\n");
376 tmp = 1;
377 }
378 tmp = state->fclk / tmp;
379
380
381 /* set the MPEG_CLK_INTL for the calculated data rate */
382 if (tmp < 2)
383 val = 0x00;
384 else if (tmp < 5)
385 val = 0x01;
386 else if (tmp < 9)
387 val = 0x02;
388 else if (tmp < 13)
389 val = 0x03;
390 else if (tmp < 17)
391 val = 0x04;
392 else if (tmp < 25)
393 val = 0x05;
394 else if (tmp < 33)
395 val = 0x06;
396 else
397 val = 0x07;
398 dprintk("for MPEG_CLK_INTL %d %x\n", tmp, val);
399
400 s5h1420_writereg(state, FEC01, 0x18);
401 s5h1420_writereg(state, FEC01, 0x10);
402 s5h1420_writereg(state, FEC01, val);
403
404 /* Enable "MPEG_Out" */
405 val = s5h1420_readreg(state, Mpeg02);
406 s5h1420_writereg(state, Mpeg02, val | (1 << 6));
407
408 /* kicker disable */
409 val = s5h1420_readreg(state, QPSK01) & 0x7f;
410 s5h1420_writereg(state, QPSK01, val);
411
412 /* DC freeze TODO it was never activated by default or it can stay activated */
413
414 if (s5h1420_getsymbolrate(state) >= 20000000) {
415 s5h1420_writereg(state, Loop04, 0x8a);
416 s5h1420_writereg(state, Loop05, 0x6a);
417 } else {
418 s5h1420_writereg(state, Loop04, 0x58);
419 s5h1420_writereg(state, Loop05, 0x27);
420 }
421
422 /* post-lock processing has been done! */
423 state->postlocked = 1;
424 }
425
426 dprintk("leave %s\n", __func__);
427
428 return 0;
429}
430
431static int s5h1420_read_ber(struct dvb_frontend* fe, u32* ber)
432{
433 struct s5h1420_state* state = fe->demodulator_priv;
434
435 s5h1420_writereg(state, 0x46, 0x1d);
436 mdelay(25);
437
438 *ber = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
439
440 return 0;
441}
442
443static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength)
444{
445 struct s5h1420_state* state = fe->demodulator_priv;
446
447 u8 val = s5h1420_readreg(state, 0x15);
448
449 *strength = (u16) ((val << 8) | val);
450
451 return 0;
452}
453
454static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
455{
456 struct s5h1420_state* state = fe->demodulator_priv;
457
458 s5h1420_writereg(state, 0x46, 0x1f);
459 mdelay(25);
460
461 *ucblocks = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47);
462
463 return 0;
464}
465
466static void s5h1420_reset(struct s5h1420_state* state)
467{
468 dprintk("%s\n", __func__);
469 s5h1420_writereg (state, 0x01, 0x08);
470 s5h1420_writereg (state, 0x01, 0x00);
471 udelay(10);
472}
473
474static void s5h1420_setsymbolrate(struct s5h1420_state* state,
475 struct dvb_frontend_parameters *p)
476{
477 u8 v;
478 u64 val;
479
480 dprintk("enter %s\n", __func__);
481
482 val = ((u64) p->u.qpsk.symbol_rate / 1000ULL) * (1ULL<<24);
483 if (p->u.qpsk.symbol_rate < 29000000)
484 val *= 2;
485 do_div(val, (state->fclk / 1000));
486
487 dprintk("symbol rate register: %06llx\n", (unsigned long long)val);
488
489 v = s5h1420_readreg(state, Loop01);
490 s5h1420_writereg(state, Loop01, v & 0x7f);
491 s5h1420_writereg(state, Tnco01, val >> 16);
492 s5h1420_writereg(state, Tnco02, val >> 8);
493 s5h1420_writereg(state, Tnco03, val & 0xff);
494 s5h1420_writereg(state, Loop01, v | 0x80);
495 dprintk("leave %s\n", __func__);
496}
497
498static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
499{
500 return state->symbol_rate;
501}
502
503static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset)
504{
505 int val;
506 u8 v;
507
508 dprintk("enter %s\n", __func__);
509
510 /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
511 * divide fclk by 1000000 to get the correct value. */
512 val = -(int) ((freqoffset * (1<<24)) / (state->fclk / 1000000));
513
514 dprintk("phase rotator/freqoffset: %d %06x\n", freqoffset, val);
515
516 v = s5h1420_readreg(state, Loop01);
517 s5h1420_writereg(state, Loop01, v & 0xbf);
518 s5h1420_writereg(state, Pnco01, val >> 16);
519 s5h1420_writereg(state, Pnco02, val >> 8);
520 s5h1420_writereg(state, Pnco03, val & 0xff);
521 s5h1420_writereg(state, Loop01, v | 0x40);
522 dprintk("leave %s\n", __func__);
523}
524
525static int s5h1420_getfreqoffset(struct s5h1420_state* state)
526{
527 int val;
528
529 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08);
530 val = s5h1420_readreg(state, 0x0e) << 16;
531 val |= s5h1420_readreg(state, 0x0f) << 8;
532 val |= s5h1420_readreg(state, 0x10);
533 s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
534
535 if (val & 0x800000)
536 val |= 0xff000000;
537
538 /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
539 * divide fclk by 1000000 to get the correct value. */
540 val = (((-val) * (state->fclk/1000000)) / (1<<24));
541
542 return val;
543}
544
545static void s5h1420_setfec_inversion(struct s5h1420_state* state,
546 struct dvb_frontend_parameters *p)
547{
548 u8 inversion = 0;
549 u8 vit08, vit09;
550
551 dprintk("enter %s\n", __func__);
552
553 if (p->inversion == INVERSION_OFF)
554 inversion = state->config->invert ? 0x08 : 0;
555 else if (p->inversion == INVERSION_ON)
556 inversion = state->config->invert ? 0 : 0x08;
557
558 if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
559 vit08 = 0x3f;
560 vit09 = 0;
561 } else {
562 switch(p->u.qpsk.fec_inner) {
563 case FEC_1_2:
564 vit08 = 0x01; vit09 = 0x10;
565 break;
566
567 case FEC_2_3:
568 vit08 = 0x02; vit09 = 0x11;
569 break;
570
571 case FEC_3_4:
572 vit08 = 0x04; vit09 = 0x12;
573 break;
574
575 case FEC_5_6:
576 vit08 = 0x08; vit09 = 0x13;
577 break;
578
579 case FEC_6_7:
580 vit08 = 0x10; vit09 = 0x14;
581 break;
582
583 case FEC_7_8:
584 vit08 = 0x20; vit09 = 0x15;
585 break;
586
587 default:
588 return;
589 }
590 }
591 vit09 |= inversion;
592 dprintk("fec: %02x %02x\n", vit08, vit09);
593 s5h1420_writereg(state, Vit08, vit08);
594 s5h1420_writereg(state, Vit09, vit09);
595 dprintk("leave %s\n", __func__);
596}
597
598static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state)
599{
600 switch(s5h1420_readreg(state, 0x32) & 0x07) {
601 case 0:
602 return FEC_1_2;
603
604 case 1:
605 return FEC_2_3;
606
607 case 2:
608 return FEC_3_4;
609
610 case 3:
611 return FEC_5_6;
612
613 case 4:
614 return FEC_6_7;
615
616 case 5:
617 return FEC_7_8;
618 }
619
620 return FEC_NONE;
621}
622
623static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state)
624{
625 if (s5h1420_readreg(state, 0x32) & 0x08)
626 return INVERSION_ON;
627
628 return INVERSION_OFF;
629}
630
631static int s5h1420_set_frontend(struct dvb_frontend* fe,
632 struct dvb_frontend_parameters *p)
633{
634 struct s5h1420_state* state = fe->demodulator_priv;
635 int frequency_delta;
636 struct dvb_frontend_tune_settings fesettings;
637 uint8_t clock_setting;
638
639 dprintk("enter %s\n", __func__);
640
641 /* check if we should do a fast-tune */
642 memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters));
643 s5h1420_get_tune_settings(fe, &fesettings);
644 frequency_delta = p->frequency - state->tunedfreq;
645 if ((frequency_delta > -fesettings.max_drift) &&
646 (frequency_delta < fesettings.max_drift) &&
647 (frequency_delta != 0) &&
648 (state->fec_inner == p->u.qpsk.fec_inner) &&
649 (state->symbol_rate == p->u.qpsk.symbol_rate)) {
650
651 if (fe->ops.tuner_ops.set_params) {
652 fe->ops.tuner_ops.set_params(fe, p);
653 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
654 }
655 if (fe->ops.tuner_ops.get_frequency) {
656 u32 tmp;
657 fe->ops.tuner_ops.get_frequency(fe, &tmp);
658 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
659 s5h1420_setfreqoffset(state, p->frequency - tmp);
660 } else {
661 s5h1420_setfreqoffset(state, 0);
662 }
663 dprintk("simple tune\n");
664 return 0;
665 }
666 dprintk("tuning demod\n");
667
668 /* first of all, software reset */
669 s5h1420_reset(state);
670
671 /* set s5h1420 fclk PLL according to desired symbol rate */
672 if (p->u.qpsk.symbol_rate > 33000000)
673 state->fclk = 80000000;
674 else if (p->u.qpsk.symbol_rate > 28500000)
675 state->fclk = 59000000;
676 else if (p->u.qpsk.symbol_rate > 25000000)
677 state->fclk = 86000000;
678 else if (p->u.qpsk.symbol_rate > 1900000)
679 state->fclk = 88000000;
680 else
681 state->fclk = 44000000;
682
683 /* Clock */
684 switch (state->fclk) {
685 default:
686 case 88000000:
687 clock_setting = 80;
688 break;
689 case 86000000:
690 clock_setting = 78;
691 break;
692 case 80000000:
693 clock_setting = 72;
694 break;
695 case 59000000:
696 clock_setting = 51;
697 break;
698 case 44000000:
699 clock_setting = 36;
700 break;
701 }
702 dprintk("pll01: %d, ToneFreq: %d\n", state->fclk/1000000 - 8, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32));
703 s5h1420_writereg(state, PLL01, state->fclk/1000000 - 8);
704 s5h1420_writereg(state, PLL02, 0x40);
705 s5h1420_writereg(state, DiS01, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32));
706
707 /* TODO DC offset removal, config parameter ? */
708 if (p->u.qpsk.symbol_rate > 29000000)
709 s5h1420_writereg(state, QPSK01, 0xae | 0x10);
710 else
711 s5h1420_writereg(state, QPSK01, 0xac | 0x10);
712
713 /* set misc registers */
714 s5h1420_writereg(state, CON_1, 0x00);
715 s5h1420_writereg(state, QPSK02, 0x00);
716 s5h1420_writereg(state, Pre01, 0xb0);
717
718 s5h1420_writereg(state, Loop01, 0xF0);
719 s5h1420_writereg(state, Loop02, 0x2a); /* e7 for s5h1420 */
720 s5h1420_writereg(state, Loop03, 0x79); /* 78 for s5h1420 */
721 if (p->u.qpsk.symbol_rate > 20000000)
722 s5h1420_writereg(state, Loop04, 0x79);
723 else
724 s5h1420_writereg(state, Loop04, 0x58);
725 s5h1420_writereg(state, Loop05, 0x6b);
726
727 if (p->u.qpsk.symbol_rate >= 8000000)
728 s5h1420_writereg(state, Post01, (0 << 6) | 0x10);
729 else if (p->u.qpsk.symbol_rate >= 4000000)
730 s5h1420_writereg(state, Post01, (1 << 6) | 0x10);
731 else
732 s5h1420_writereg(state, Post01, (3 << 6) | 0x10);
733
734 s5h1420_writereg(state, Monitor12, 0x00); /* unfreeze DC compensation */
735
736 s5h1420_writereg(state, Sync01, 0x33);
737 s5h1420_writereg(state, Mpeg01, state->config->cdclk_polarity);
738 s5h1420_writereg(state, Mpeg02, 0x3d); /* Parallel output more, disabled -> enabled later */
739 s5h1420_writereg(state, Err01, 0x03); /* 0x1d for s5h1420 */
740
741 s5h1420_writereg(state, Vit06, 0x6e); /* 0x8e for s5h1420 */
742 s5h1420_writereg(state, DiS03, 0x00);
743 s5h1420_writereg(state, Rf01, 0x61); /* Tuner i2c address - for the gate controller */
744
745 /* set tuner PLL */
746 if (fe->ops.tuner_ops.set_params) {
747 fe->ops.tuner_ops.set_params(fe, p);
748 if (fe->ops.i2c_gate_ctrl)
749 fe->ops.i2c_gate_ctrl(fe, 0);
750 s5h1420_setfreqoffset(state, 0);
751 }
752
753 /* set the reset of the parameters */
754 s5h1420_setsymbolrate(state, p);
755 s5h1420_setfec_inversion(state, p);
756
757 /* start QPSK */
758 s5h1420_writereg(state, QPSK01, s5h1420_readreg(state, QPSK01) | 1);
759
760 state->fec_inner = p->u.qpsk.fec_inner;
761 state->symbol_rate = p->u.qpsk.symbol_rate;
762 state->postlocked = 0;
763 state->tunedfreq = p->frequency;
764
765 dprintk("leave %s\n", __func__);
766 return 0;
767}
768
769static int s5h1420_get_frontend(struct dvb_frontend* fe,
770 struct dvb_frontend_parameters *p)
771{
772 struct s5h1420_state* state = fe->demodulator_priv;
773
774 p->frequency = state->tunedfreq + s5h1420_getfreqoffset(state);
775 p->inversion = s5h1420_getinversion(state);
776 p->u.qpsk.symbol_rate = s5h1420_getsymbolrate(state);
777 p->u.qpsk.fec_inner = s5h1420_getfec(state);
778
779 return 0;
780}
781
782static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
783 struct dvb_frontend_tune_settings* fesettings)
784{
785 if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) {
786 fesettings->min_delay_ms = 50;
787 fesettings->step_size = 2000;
788 fesettings->max_drift = 8000;
789 } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) {
790 fesettings->min_delay_ms = 100;
791 fesettings->step_size = 1500;
792 fesettings->max_drift = 9000;
793 } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) {
794 fesettings->min_delay_ms = 100;
795 fesettings->step_size = 1000;
796 fesettings->max_drift = 8000;
797 } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) {
798 fesettings->min_delay_ms = 100;
799 fesettings->step_size = 500;
800 fesettings->max_drift = 7000;
801 } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) {
802 fesettings->min_delay_ms = 200;
803 fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
804 fesettings->max_drift = 14 * fesettings->step_size;
805 } else {
806 fesettings->min_delay_ms = 200;
807 fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
808 fesettings->max_drift = 18 * fesettings->step_size;
809 }
810
811 return 0;
812}
813
814static int s5h1420_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
815{
816 struct s5h1420_state* state = fe->demodulator_priv;
817
818 if (enable)
819 return s5h1420_writereg(state, 0x02, state->CON_1_val | 1);
820 else
821 return s5h1420_writereg(state, 0x02, state->CON_1_val & 0xfe);
822}
823
824static int s5h1420_init (struct dvb_frontend* fe)
825{
826 struct s5h1420_state* state = fe->demodulator_priv;
827
828 /* disable power down and do reset */
829 state->CON_1_val = state->config->serial_mpeg << 4;
830 s5h1420_writereg(state, 0x02, state->CON_1_val);
831 msleep(10);
832 s5h1420_reset(state);
833
834 return 0;
835}
836
837static int s5h1420_sleep(struct dvb_frontend* fe)
838{
839 struct s5h1420_state* state = fe->demodulator_priv;
840 state->CON_1_val = 0x12;
841 return s5h1420_writereg(state, 0x02, state->CON_1_val);
842}
843
844static void s5h1420_release(struct dvb_frontend* fe)
845{
846 struct s5h1420_state* state = fe->demodulator_priv;
847 i2c_del_adapter(&state->tuner_i2c_adapter);
848 kfree(state);
849}
850
851static u32 s5h1420_tuner_i2c_func(struct i2c_adapter *adapter)
852{
853 return I2C_FUNC_I2C;
854}
855
856static int s5h1420_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
857{
858 struct s5h1420_state *state = i2c_get_adapdata(i2c_adap);
859 struct i2c_msg m[1 + num];
860 u8 tx_open[2] = { CON_1, state->CON_1_val | 1 }; /* repeater stops once there was a stop condition */
861
862 memset(m, 0, sizeof(struct i2c_msg) * (1 + num));
863
864 m[0].addr = state->config->demod_address;
865 m[0].buf = tx_open;
866 m[0].len = 2;
867
868 memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
869
870 return i2c_transfer(state->i2c, m, 1+num) == 1 + num ? num : -EIO;
871}
872
873static struct i2c_algorithm s5h1420_tuner_i2c_algo = {
874 .master_xfer = s5h1420_tuner_i2c_tuner_xfer,
875 .functionality = s5h1420_tuner_i2c_func,
876};
877
878struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe)
879{
880 struct s5h1420_state *state = fe->demodulator_priv;
881 return &state->tuner_i2c_adapter;
882}
883EXPORT_SYMBOL(s5h1420_get_tuner_i2c_adapter);
884
885static struct dvb_frontend_ops s5h1420_ops;
886
887struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
888 struct i2c_adapter *i2c)
889{
890 /* allocate memory for the internal state */
891 struct s5h1420_state *state = kzalloc(sizeof(struct s5h1420_state), GFP_KERNEL);
892 u8 i;
893
894 if (state == NULL)
895 goto error;
896
897 /* setup the state */
898 state->config = config;
899 state->i2c = i2c;
900 state->postlocked = 0;
901 state->fclk = 88000000;
902 state->tunedfreq = 0;
903 state->fec_inner = FEC_NONE;
904 state->symbol_rate = 0;
905
906 /* check if the demod is there + identify it */
907 i = s5h1420_readreg(state, ID01);
908 if (i != 0x03)
909 goto error;
910
911 memset(state->shadow, 0xff, sizeof(state->shadow));
912
913 for (i = 0; i < 0x50; i++)
914 state->shadow[i] = s5h1420_readreg(state, i);
915
916 /* create dvb_frontend */
917 memcpy(&state->frontend.ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops));
918 state->frontend.demodulator_priv = state;
919
920 /* create tuner i2c adapter */
921 strlcpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus",
922 sizeof(state->tuner_i2c_adapter.name));
923 state->tuner_i2c_adapter.algo = &s5h1420_tuner_i2c_algo;
924 state->tuner_i2c_adapter.algo_data = NULL;
925 i2c_set_adapdata(&state->tuner_i2c_adapter, state);
926 if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) {
927 printk(KERN_ERR "S5H1420/PN1010: tuner i2c bus could not be initialized\n");
928 goto error;
929 }
930
931 return &state->frontend;
932
933error:
934 kfree(state);
935 return NULL;
936}
937EXPORT_SYMBOL(s5h1420_attach);
938
939static struct dvb_frontend_ops s5h1420_ops = {
940
941 .info = {
942 .name = "Samsung S5H1420/PnpNetwork PN1010 DVB-S",
943 .type = FE_QPSK,
944 .frequency_min = 950000,
945 .frequency_max = 2150000,
946 .frequency_stepsize = 125, /* kHz for QPSK frontends */
947 .frequency_tolerance = 29500,
948 .symbol_rate_min = 1000000,
949 .symbol_rate_max = 45000000,
950 /* .symbol_rate_tolerance = ???,*/
951 .caps = FE_CAN_INVERSION_AUTO |
952 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
953 FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
954 FE_CAN_QPSK
955 },
956
957 .release = s5h1420_release,
958
959 .init = s5h1420_init,
960 .sleep = s5h1420_sleep,
961 .i2c_gate_ctrl = s5h1420_i2c_gate_ctrl,
962
963 .set_frontend = s5h1420_set_frontend,
964 .get_frontend = s5h1420_get_frontend,
965 .get_tune_settings = s5h1420_get_tune_settings,
966
967 .read_status = s5h1420_read_status,
968 .read_ber = s5h1420_read_ber,
969 .read_signal_strength = s5h1420_read_signal_strength,
970 .read_ucblocks = s5h1420_read_ucblocks,
971
972 .diseqc_send_master_cmd = s5h1420_send_master_cmd,
973 .diseqc_recv_slave_reply = s5h1420_recv_slave_reply,
974 .diseqc_send_burst = s5h1420_send_burst,
975 .set_tone = s5h1420_set_tone,
976 .set_voltage = s5h1420_set_voltage,
977};
978
979MODULE_DESCRIPTION("Samsung S5H1420/PnpNetwork PN1010 DVB-S Demodulator driver");
980MODULE_AUTHOR("Andrew de Quincey, Patrick Boettcher");
981MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
new file mode 100644
index 00000000000..ff308136d86
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -0,0 +1,61 @@
1/*
2 * Driver for
3 * Samsung S5H1420 and
4 * PnpNetwork PN1010 QPSK Demodulator
5 *
6 * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
7 * Copyright (C) 2005-8 Patrick Boettcher <pb@linuxtv.org>
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 *
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#ifndef S5H1420_H
25#define S5H1420_H
26
27#include <linux/dvb/frontend.h>
28
29struct s5h1420_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* does the inversion require inversion? */
35 u8 invert:1;
36
37 u8 repeated_start_workaround:1;
38 u8 cdclk_polarity:1; /* 1 == falling edge, 0 == raising edge */
39
40 u8 serial_mpeg:1;
41};
42
43#if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE))
44extern struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
45 struct i2c_adapter *i2c);
46extern struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe);
47#else
48static inline struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
49 struct i2c_adapter *i2c)
50{
51 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
52 return NULL;
53}
54
55static inline struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe)
56{
57 return NULL;
58}
59#endif // CONFIG_DVB_S5H1420
60
61#endif // S5H1420_H
diff --git a/drivers/media/dvb/frontends/s5h1420_priv.h b/drivers/media/dvb/frontends/s5h1420_priv.h
new file mode 100644
index 00000000000..d9c58d28181
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1420_priv.h
@@ -0,0 +1,102 @@
1/*
2 * Driver for
3 * Samsung S5H1420 and
4 * PnpNetwork PN1010 QPSK Demodulator
5 *
6 * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
7 * Copyright (C) 2005 Patrick Boettcher <pb@linuxtv.org>
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; either version 2 of the License, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the
17 *
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License along with
21 * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
22 * Ave, Cambridge, MA 02139, USA.
23 */
24#ifndef S5H1420_PRIV
25#define S5H1420_PRIV
26
27#include <asm/types.h>
28
29enum s5h1420_register {
30 ID01 = 0x00,
31 CON_0 = 0x01,
32 CON_1 = 0x02,
33 PLL01 = 0x03,
34 PLL02 = 0x04,
35 QPSK01 = 0x05,
36 QPSK02 = 0x06,
37 Pre01 = 0x07,
38 Post01 = 0x08,
39 Loop01 = 0x09,
40 Loop02 = 0x0a,
41 Loop03 = 0x0b,
42 Loop04 = 0x0c,
43 Loop05 = 0x0d,
44 Pnco01 = 0x0e,
45 Pnco02 = 0x0f,
46 Pnco03 = 0x10,
47 Tnco01 = 0x11,
48 Tnco02 = 0x12,
49 Tnco03 = 0x13,
50 Monitor01 = 0x14,
51 Monitor02 = 0x15,
52 Monitor03 = 0x16,
53 Monitor04 = 0x17,
54 Monitor05 = 0x18,
55 Monitor06 = 0x19,
56 Monitor07 = 0x1a,
57 Monitor12 = 0x1f,
58
59 FEC01 = 0x22,
60 Soft01 = 0x23,
61 Soft02 = 0x24,
62 Soft03 = 0x25,
63 Soft04 = 0x26,
64 Soft05 = 0x27,
65 Soft06 = 0x28,
66 Vit01 = 0x29,
67 Vit02 = 0x2a,
68 Vit03 = 0x2b,
69 Vit04 = 0x2c,
70 Vit05 = 0x2d,
71 Vit06 = 0x2e,
72 Vit07 = 0x2f,
73 Vit08 = 0x30,
74 Vit09 = 0x31,
75 Vit10 = 0x32,
76 Vit11 = 0x33,
77 Vit12 = 0x34,
78 Sync01 = 0x35,
79 Sync02 = 0x36,
80 Rs01 = 0x37,
81 Mpeg01 = 0x38,
82 Mpeg02 = 0x39,
83 DiS01 = 0x3a,
84 DiS02 = 0x3b,
85 DiS03 = 0x3c,
86 DiS04 = 0x3d,
87 DiS05 = 0x3e,
88 DiS06 = 0x3f,
89 DiS07 = 0x40,
90 DiS08 = 0x41,
91 DiS09 = 0x42,
92 DiS10 = 0x43,
93 DiS11 = 0x44,
94 Rf01 = 0x45,
95 Err01 = 0x46,
96 Err02 = 0x47,
97 Err03 = 0x48,
98 Err04 = 0x49,
99};
100
101
102#endif
diff --git a/drivers/media/dvb/frontends/s5h1432.c b/drivers/media/dvb/frontends/s5h1432.c
new file mode 100644
index 00000000000..0c6dcb90d16
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1432.c
@@ -0,0 +1,415 @@
1/*
2 * Samsung s5h1432 DVB-T demodulator driver
3 *
4 * Copyright (C) 2009 Bill Liu <Bill.Liu@Conexant.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 <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/string.h>
25#include <linux/slab.h>
26#include <linux/delay.h>
27#include "dvb_frontend.h"
28#include "s5h1432.h"
29
30struct s5h1432_state {
31
32 struct i2c_adapter *i2c;
33
34 /* configuration settings */
35 const struct s5h1432_config *config;
36
37 struct dvb_frontend frontend;
38
39 fe_modulation_t current_modulation;
40 unsigned int first_tune:1;
41
42 u32 current_frequency;
43 int if_freq;
44
45 u8 inversion;
46};
47
48static int debug;
49
50#define dprintk(arg...) do { \
51 if (debug) \
52 printk(arg); \
53 } while (0)
54
55static int s5h1432_writereg(struct s5h1432_state *state,
56 u8 addr, u8 reg, u8 data)
57{
58 int ret;
59 u8 buf[] = { reg, data };
60
61 struct i2c_msg msg = {.addr = addr, .flags = 0, .buf = buf, .len = 2 };
62
63 ret = i2c_transfer(state->i2c, &msg, 1);
64
65 if (ret != 1)
66 printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, "
67 "ret == %i)\n", __func__, addr, reg, data, ret);
68
69 return (ret != 1) ? -1 : 0;
70}
71
72static u8 s5h1432_readreg(struct s5h1432_state *state, u8 addr, u8 reg)
73{
74 int ret;
75 u8 b0[] = { reg };
76 u8 b1[] = { 0 };
77
78 struct i2c_msg msg[] = {
79 {.addr = addr, .flags = 0, .buf = b0, .len = 1},
80 {.addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 1}
81 };
82
83 ret = i2c_transfer(state->i2c, msg, 2);
84
85 if (ret != 2)
86 printk(KERN_ERR "%s: readreg error (ret == %i)\n",
87 __func__, ret);
88 return b1[0];
89}
90
91static int s5h1432_sleep(struct dvb_frontend *fe)
92{
93 return 0;
94}
95
96static int s5h1432_set_channel_bandwidth(struct dvb_frontend *fe,
97 u32 bandwidth)
98{
99 struct s5h1432_state *state = fe->demodulator_priv;
100
101 u8 reg = 0;
102
103 /* Register [0x2E] bit 3:2 : 8MHz = 0; 7MHz = 1; 6MHz = 2 */
104 reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x2E);
105 reg &= ~(0x0C);
106 switch (bandwidth) {
107 case 6:
108 reg |= 0x08;
109 break;
110 case 7:
111 reg |= 0x04;
112 break;
113 case 8:
114 reg |= 0x00;
115 break;
116 default:
117 return 0;
118 }
119 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2E, reg);
120 return 1;
121}
122
123static int s5h1432_set_IF(struct dvb_frontend *fe, u32 ifFreqHz)
124{
125 struct s5h1432_state *state = fe->demodulator_priv;
126
127 switch (ifFreqHz) {
128 case TAIWAN_HI_IF_FREQ_44_MHZ:
129 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55);
130 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55);
131 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x15);
132 break;
133 case EUROPE_HI_IF_FREQ_36_MHZ:
134 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00);
135 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00);
136 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0x40);
137 break;
138 case IF_FREQ_6_MHZ:
139 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x00);
140 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x00);
141 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xe0);
142 break;
143 case IF_FREQ_3point3_MHZ:
144 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66);
145 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66);
146 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE);
147 break;
148 case IF_FREQ_3point5_MHZ:
149 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x55);
150 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x55);
151 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xED);
152 break;
153 case IF_FREQ_4_MHZ:
154 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0xAA);
155 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0xAA);
156 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEA);
157 break;
158 default:
159 {
160 u32 value = 0;
161 value = (u32) (((48000 - (ifFreqHz / 1000)) * 512 *
162 (u32) 32768) / (48 * 1000));
163 printk(KERN_INFO
164 "Default IFFreq %d :reg value = 0x%x\n",
165 ifFreqHz, value);
166 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4,
167 (u8) value & 0xFF);
168 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5,
169 (u8) (value >> 8) & 0xFF);
170 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7,
171 (u8) (value >> 16) & 0xFF);
172 break;
173 }
174
175 }
176
177 return 1;
178}
179
180/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
181static int s5h1432_set_frontend(struct dvb_frontend *fe,
182 struct dvb_frontend_parameters *p)
183{
184 u32 dvb_bandwidth = 8;
185 struct s5h1432_state *state = fe->demodulator_priv;
186
187 if (p->frequency == state->current_frequency) {
188 /*current_frequency = p->frequency; */
189 /*state->current_frequency = p->frequency; */
190 } else {
191 fe->ops.tuner_ops.set_params(fe, p);
192 msleep(300);
193 s5h1432_set_channel_bandwidth(fe, dvb_bandwidth);
194 switch (p->u.ofdm.bandwidth) {
195 case BANDWIDTH_6_MHZ:
196 dvb_bandwidth = 6;
197 s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
198 break;
199 case BANDWIDTH_7_MHZ:
200 dvb_bandwidth = 7;
201 s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
202 break;
203 case BANDWIDTH_8_MHZ:
204 dvb_bandwidth = 8;
205 s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
206 break;
207 default:
208 return 0;
209 }
210 /*fe->ops.tuner_ops.set_params(fe, p); */
211/*Soft Reset chip*/
212 msleep(30);
213 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
214 msleep(30);
215 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
216
217 s5h1432_set_channel_bandwidth(fe, dvb_bandwidth);
218 switch (p->u.ofdm.bandwidth) {
219 case BANDWIDTH_6_MHZ:
220 dvb_bandwidth = 6;
221 s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
222 break;
223 case BANDWIDTH_7_MHZ:
224 dvb_bandwidth = 7;
225 s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
226 break;
227 case BANDWIDTH_8_MHZ:
228 dvb_bandwidth = 8;
229 s5h1432_set_IF(fe, IF_FREQ_4_MHZ);
230 break;
231 default:
232 return 0;
233 }
234 /*fe->ops.tuner_ops.set_params(fe,p); */
235 /*Soft Reset chip*/
236 msleep(30);
237 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
238 msleep(30);
239 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
240
241 }
242
243 state->current_frequency = p->frequency;
244
245 return 0;
246}
247
248static int s5h1432_init(struct dvb_frontend *fe)
249{
250 struct s5h1432_state *state = fe->demodulator_priv;
251
252 u8 reg = 0;
253 state->current_frequency = 0;
254 printk(KERN_INFO " s5h1432_init().\n");
255
256 /*Set VSB mode as default, this also does a soft reset */
257 /*Initialize registers */
258
259 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x04, 0xa8);
260 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x05, 0x01);
261 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x07, 0x70);
262 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x19, 0x80);
263 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1b, 0x9D);
264 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1c, 0x30);
265 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1d, 0x20);
266 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x1B);
267 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x2e, 0x40);
268 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, 0x84);
269 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x50, 0x5a);
270 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x5a, 0xd3);
271 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x68, 0x50);
272 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xb8, 0x3c);
273 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xc4, 0x10);
274 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xcc, 0x9c);
275 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xDA, 0x00);
276 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe1, 0x94);
277 /* s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf4, 0xa1); */
278 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xf9, 0x00);
279
280 /*For NXP tuner*/
281
282 /*Set 3.3MHz as default IF frequency */
283 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe4, 0x66);
284 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe5, 0x66);
285 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0xe7, 0xEE);
286 /* Set reg 0x1E to get the full dynamic range */
287 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x1e, 0x31);
288
289 /* Mode setting in demod */
290 reg = s5h1432_readreg(state, S5H1432_I2C_TOP_ADDR, 0x42);
291 reg |= 0x80;
292 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x42, reg);
293 /* Serial mode */
294
295 /* Soft Reset chip */
296
297 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1a);
298 msleep(30);
299 s5h1432_writereg(state, S5H1432_I2C_TOP_ADDR, 0x09, 0x1b);
300
301
302 return 0;
303}
304
305static int s5h1432_read_status(struct dvb_frontend *fe, fe_status_t *status)
306{
307 return 0;
308}
309
310static int s5h1432_read_signal_strength(struct dvb_frontend *fe,
311 u16 *signal_strength)
312{
313 return 0;
314}
315
316static int s5h1432_read_snr(struct dvb_frontend *fe, u16 *snr)
317{
318 return 0;
319}
320
321static int s5h1432_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
322{
323
324 return 0;
325}
326
327static int s5h1432_read_ber(struct dvb_frontend *fe, u32 *ber)
328{
329 return 0;
330}
331
332static int s5h1432_get_frontend(struct dvb_frontend *fe,
333 struct dvb_frontend_parameters *p)
334{
335 return 0;
336}
337
338static int s5h1432_get_tune_settings(struct dvb_frontend *fe,
339 struct dvb_frontend_tune_settings *tune)
340{
341 return 0;
342}
343
344static void s5h1432_release(struct dvb_frontend *fe)
345{
346 struct s5h1432_state *state = fe->demodulator_priv;
347 kfree(state);
348}
349
350static struct dvb_frontend_ops s5h1432_ops;
351
352struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config,
353 struct i2c_adapter *i2c)
354{
355 struct s5h1432_state *state = NULL;
356
357 printk(KERN_INFO " Enter s5h1432_attach(). attach success!\n");
358 /* allocate memory for the internal state */
359 state = kmalloc(sizeof(struct s5h1432_state), GFP_KERNEL);
360 if (state == NULL)
361 goto error;
362
363 /* setup the state */
364 state->config = config;
365 state->i2c = i2c;
366 state->current_modulation = QAM_16;
367 state->inversion = state->config->inversion;
368
369 /* create dvb_frontend */
370 memcpy(&state->frontend.ops, &s5h1432_ops,
371 sizeof(struct dvb_frontend_ops));
372
373 state->frontend.demodulator_priv = state;
374
375 return &state->frontend;
376
377error:
378 kfree(state);
379 return NULL;
380}
381EXPORT_SYMBOL(s5h1432_attach);
382
383static struct dvb_frontend_ops s5h1432_ops = {
384
385 .info = {
386 .name = "Samsung s5h1432 DVB-T Frontend",
387 .type = FE_OFDM,
388 .frequency_min = 177000000,
389 .frequency_max = 858000000,
390 .frequency_stepsize = 166666,
391 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
392 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
393 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
394 FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
395 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER},
396
397 .init = s5h1432_init,
398 .sleep = s5h1432_sleep,
399 .set_frontend = s5h1432_set_frontend,
400 .get_frontend = s5h1432_get_frontend,
401 .get_tune_settings = s5h1432_get_tune_settings,
402 .read_status = s5h1432_read_status,
403 .read_ber = s5h1432_read_ber,
404 .read_signal_strength = s5h1432_read_signal_strength,
405 .read_snr = s5h1432_read_snr,
406 .read_ucblocks = s5h1432_read_ucblocks,
407 .release = s5h1432_release,
408};
409
410module_param(debug, int, 0644);
411MODULE_PARM_DESC(debug, "Enable verbose debug messages");
412
413MODULE_DESCRIPTION("Samsung s5h1432 DVB-T Demodulator driver");
414MODULE_AUTHOR("Bill Liu");
415MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/s5h1432.h b/drivers/media/dvb/frontends/s5h1432.h
new file mode 100644
index 00000000000..b57438c3254
--- /dev/null
+++ b/drivers/media/dvb/frontends/s5h1432.h
@@ -0,0 +1,91 @@
1/*
2 * Samsung s5h1432 VSB/QAM demodulator driver
3 *
4 * Copyright (C) 2009 Bill Liu <Bill.Liu@Conexant.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
22#ifndef __S5H1432_H__
23#define __S5H1432_H__
24
25#include <linux/dvb/frontend.h>
26
27#define S5H1432_I2C_TOP_ADDR (0x02 >> 1)
28
29#define TAIWAN_HI_IF_FREQ_44_MHZ 44000000
30#define EUROPE_HI_IF_FREQ_36_MHZ 36000000
31#define IF_FREQ_6_MHZ 6000000
32#define IF_FREQ_3point3_MHZ 3300000
33#define IF_FREQ_3point5_MHZ 3500000
34#define IF_FREQ_4_MHZ 4000000
35
36struct s5h1432_config {
37
38 /* serial/parallel output */
39#define S5H1432_PARALLEL_OUTPUT 0
40#define S5H1432_SERIAL_OUTPUT 1
41 u8 output_mode;
42
43 /* GPIO Setting */
44#define S5H1432_GPIO_OFF 0
45#define S5H1432_GPIO_ON 1
46 u8 gpio;
47
48 /* MPEG signal timing */
49#define S5H1432_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0
50#define S5H1432_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1
51#define S5H1432_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2
52#define S5H1432_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
53 u16 mpeg_timing;
54
55 /* IF Freq for QAM and VSB in KHz */
56#define S5H1432_IF_3250 3250
57#define S5H1432_IF_3500 3500
58#define S5H1432_IF_4000 4000
59#define S5H1432_IF_5380 5380
60#define S5H1432_IF_44000 44000
61#define S5H1432_VSB_IF_DEFAULT s5h1432_IF_44000
62#define S5H1432_QAM_IF_DEFAULT s5h1432_IF_44000
63 u16 qam_if;
64 u16 vsb_if;
65
66 /* Spectral Inversion */
67#define S5H1432_INVERSION_OFF 0
68#define S5H1432_INVERSION_ON 1
69 u8 inversion;
70
71 /* Return lock status based on tuner lock, or demod lock */
72#define S5H1432_TUNERLOCKING 0
73#define S5H1432_DEMODLOCKING 1
74 u8 status_mode;
75};
76
77#if defined(CONFIG_DVB_S5H1432) || \
78 (defined(CONFIG_DVB_S5H1432_MODULE) && defined(MODULE))
79extern struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config,
80 struct i2c_adapter *i2c);
81#else
82static inline struct dvb_frontend *s5h1432_attach(const struct s5h1432_config
83 *config,
84 struct i2c_adapter *i2c)
85{
86 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
87 return NULL;
88}
89#endif /* CONFIG_DVB_s5h1432 */
90
91#endif /* __s5h1432_H__ */
diff --git a/drivers/media/dvb/frontends/s921.c b/drivers/media/dvb/frontends/s921.c
new file mode 100644
index 00000000000..ca0103d5f14
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921.c
@@ -0,0 +1,548 @@
1/*
2 * Sharp VA3A5JZ921 One Seg Broadcast Module driver
3 * This device is labeled as just S. 921 at the top of the frontend can
4 *
5 * Copyright (C) 2009-2010 Mauro Carvalho Chehab <mchehab@redhat.com>
6 * Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
7 *
8 * Developed for Leadership SBTVD 1seg device sold in Brazil
9 *
10 * Frontend module based on cx24123 driver, getting some info from
11 * the old s921 driver.
12 *
13 * FIXME: Need to port to DVB v5.2 API
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation version 2.
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 GNU
22 * General Public License for more details.
23 */
24
25#include <linux/kernel.h>
26#include <asm/div64.h>
27
28#include "dvb_frontend.h"
29#include "s921.h"
30
31static int debug = 1;
32module_param(debug, int, 0644);
33MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
34
35#define rc(args...) do { \
36 printk(KERN_ERR "s921: " args); \
37} while (0)
38
39#define dprintk(args...) \
40 do { \
41 if (debug) { \
42 printk(KERN_DEBUG "s921: %s: ", __func__); \
43 printk(args); \
44 } \
45 } while (0)
46
47struct s921_state {
48 struct i2c_adapter *i2c;
49 const struct s921_config *config;
50
51 struct dvb_frontend frontend;
52
53 /* The Demod can't easily provide these, we cache them */
54 u32 currentfreq;
55};
56
57/*
58 * Various tuner defaults need to be established for a given frequency kHz.
59 * fixme: The bounds on the bands do not match the doc in real life.
60 * fixme: Some of them have been moved, other might need adjustment.
61 */
62static struct s921_bandselect_val {
63 u32 freq_low;
64 u8 band_reg;
65} s921_bandselect[] = {
66 { 0, 0x7b },
67 { 485140000, 0x5b },
68 { 515140000, 0x3b },
69 { 545140000, 0x1b },
70 { 599140000, 0xfb },
71 { 623140000, 0xdb },
72 { 659140000, 0xbb },
73 { 713140000, 0x9b },
74};
75
76struct regdata {
77 u8 reg;
78 u8 data;
79};
80
81static struct regdata s921_init[] = {
82 { 0x01, 0x80 }, /* Probably, a reset sequence */
83 { 0x01, 0x40 },
84 { 0x01, 0x80 },
85 { 0x01, 0x40 },
86
87 { 0x02, 0x00 },
88 { 0x03, 0x40 },
89 { 0x04, 0x01 },
90 { 0x05, 0x00 },
91 { 0x06, 0x00 },
92 { 0x07, 0x00 },
93 { 0x08, 0x00 },
94 { 0x09, 0x00 },
95 { 0x0a, 0x00 },
96 { 0x0b, 0x5a },
97 { 0x0c, 0x00 },
98 { 0x0d, 0x00 },
99 { 0x0f, 0x00 },
100 { 0x13, 0x1b },
101 { 0x14, 0x80 },
102 { 0x15, 0x40 },
103 { 0x17, 0x70 },
104 { 0x18, 0x01 },
105 { 0x19, 0x12 },
106 { 0x1a, 0x01 },
107 { 0x1b, 0x12 },
108 { 0x1c, 0xa0 },
109 { 0x1d, 0x00 },
110 { 0x1e, 0x0a },
111 { 0x1f, 0x08 },
112 { 0x20, 0x40 },
113 { 0x21, 0xff },
114 { 0x22, 0x4c },
115 { 0x23, 0x4e },
116 { 0x24, 0x4c },
117 { 0x25, 0x00 },
118 { 0x26, 0x00 },
119 { 0x27, 0xf4 },
120 { 0x28, 0x60 },
121 { 0x29, 0x88 },
122 { 0x2a, 0x40 },
123 { 0x2b, 0x40 },
124 { 0x2c, 0xff },
125 { 0x2d, 0x00 },
126 { 0x2e, 0xff },
127 { 0x2f, 0x00 },
128 { 0x30, 0x20 },
129 { 0x31, 0x06 },
130 { 0x32, 0x0c },
131 { 0x34, 0x0f },
132 { 0x37, 0xfe },
133 { 0x38, 0x00 },
134 { 0x39, 0x63 },
135 { 0x3a, 0x10 },
136 { 0x3b, 0x10 },
137 { 0x47, 0x00 },
138 { 0x49, 0xe5 },
139 { 0x4b, 0x00 },
140 { 0x50, 0xc0 },
141 { 0x52, 0x20 },
142 { 0x54, 0x5a },
143 { 0x55, 0x5b },
144 { 0x56, 0x40 },
145 { 0x57, 0x70 },
146 { 0x5c, 0x50 },
147 { 0x5d, 0x00 },
148 { 0x62, 0x17 },
149 { 0x63, 0x2f },
150 { 0x64, 0x6f },
151 { 0x68, 0x00 },
152 { 0x69, 0x89 },
153 { 0x6a, 0x00 },
154 { 0x6b, 0x00 },
155 { 0x6c, 0x00 },
156 { 0x6d, 0x00 },
157 { 0x6e, 0x00 },
158 { 0x70, 0x10 },
159 { 0x71, 0x00 },
160 { 0x75, 0x00 },
161 { 0x76, 0x30 },
162 { 0x77, 0x01 },
163 { 0xaf, 0x00 },
164 { 0xb0, 0xa0 },
165 { 0xb2, 0x3d },
166 { 0xb3, 0x25 },
167 { 0xb4, 0x8b },
168 { 0xb5, 0x4b },
169 { 0xb6, 0x3f },
170 { 0xb7, 0xff },
171 { 0xb8, 0xff },
172 { 0xb9, 0xfc },
173 { 0xba, 0x00 },
174 { 0xbb, 0x00 },
175 { 0xbc, 0x00 },
176 { 0xd0, 0x30 },
177 { 0xe4, 0x84 },
178 { 0xf0, 0x48 },
179 { 0xf1, 0x19 },
180 { 0xf2, 0x5a },
181 { 0xf3, 0x8e },
182 { 0xf4, 0x2d },
183 { 0xf5, 0x07 },
184 { 0xf6, 0x5a },
185 { 0xf7, 0xba },
186 { 0xf8, 0xd7 },
187};
188
189static struct regdata s921_prefreq[] = {
190 { 0x47, 0x60 },
191 { 0x68, 0x00 },
192 { 0x69, 0x89 },
193 { 0xf0, 0x48 },
194 { 0xf1, 0x19 },
195};
196
197static struct regdata s921_postfreq[] = {
198 { 0xf5, 0xae },
199 { 0xf6, 0xb7 },
200 { 0xf7, 0xba },
201 { 0xf8, 0xd7 },
202 { 0x68, 0x0a },
203 { 0x69, 0x09 },
204};
205
206static int s921_i2c_writereg(struct s921_state *state,
207 u8 i2c_addr, int reg, int data)
208{
209 u8 buf[] = { reg, data };
210 struct i2c_msg msg = {
211 .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
212 };
213 int rc;
214
215 rc = i2c_transfer(state->i2c, &msg, 1);
216 if (rc != 1) {
217 printk("%s: writereg rcor(rc == %i, reg == 0x%02x,"
218 " data == 0x%02x)\n", __func__, rc, reg, data);
219 return rc;
220 }
221
222 return 0;
223}
224
225static int s921_i2c_writeregdata(struct s921_state *state, u8 i2c_addr,
226 struct regdata *rd, int size)
227{
228 int i, rc;
229
230 for (i = 0; i < size; i++) {
231 rc = s921_i2c_writereg(state, i2c_addr, rd[i].reg, rd[i].data);
232 if (rc < 0)
233 return rc;
234 }
235 return 0;
236}
237
238static int s921_i2c_readreg(struct s921_state *state, u8 i2c_addr, u8 reg)
239{
240 u8 val;
241 int rc;
242 struct i2c_msg msg[] = {
243 { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
244 { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
245 };
246
247 rc = i2c_transfer(state->i2c, msg, 2);
248
249 if (rc != 2) {
250 rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc);
251 return rc;
252 }
253
254 return val;
255}
256
257#define s921_readreg(state, reg) \
258 s921_i2c_readreg(state, state->config->demod_address, reg)
259#define s921_writereg(state, reg, val) \
260 s921_i2c_writereg(state, state->config->demod_address, reg, val)
261#define s921_writeregdata(state, regdata) \
262 s921_i2c_writeregdata(state, state->config->demod_address, \
263 regdata, ARRAY_SIZE(regdata))
264
265static int s921_pll_tune(struct dvb_frontend *fe,
266 struct dvb_frontend_parameters *p)
267{
268 struct s921_state *state = fe->demodulator_priv;
269 int band, rc, i;
270 unsigned long f_offset;
271 u8 f_switch;
272 u64 offset;
273
274 dprintk("frequency=%i\n", p->frequency);
275
276 for (band = 0; band < ARRAY_SIZE(s921_bandselect); band++)
277 if (p->frequency < s921_bandselect[band].freq_low)
278 break;
279 band--;
280
281 if (band < 0) {
282 rc("%s: frequency out of range\n", __func__);
283 return -EINVAL;
284 }
285
286 f_switch = s921_bandselect[band].band_reg;
287
288 offset = ((u64)p->frequency) * 258;
289 do_div(offset, 6000000);
290 f_offset = ((unsigned long)offset) + 2321;
291
292 rc = s921_writeregdata(state, s921_prefreq);
293 if (rc < 0)
294 return rc;
295
296 rc = s921_writereg(state, 0xf2, (f_offset >> 8) & 0xff);
297 if (rc < 0)
298 return rc;
299
300 rc = s921_writereg(state, 0xf3, f_offset & 0xff);
301 if (rc < 0)
302 return rc;
303
304 rc = s921_writereg(state, 0xf4, f_switch);
305 if (rc < 0)
306 return rc;
307
308 rc = s921_writeregdata(state, s921_postfreq);
309 if (rc < 0)
310 return rc;
311
312 for (i = 0 ; i < 6; i++) {
313 rc = s921_readreg(state, 0x80);
314 dprintk("status 0x80: %02x\n", rc);
315 }
316 rc = s921_writereg(state, 0x01, 0x40);
317 if (rc < 0)
318 return rc;
319
320 rc = s921_readreg(state, 0x01);
321 dprintk("status 0x01: %02x\n", rc);
322
323 rc = s921_readreg(state, 0x80);
324 dprintk("status 0x80: %02x\n", rc);
325
326 rc = s921_readreg(state, 0x80);
327 dprintk("status 0x80: %02x\n", rc);
328
329 rc = s921_readreg(state, 0x32);
330 dprintk("status 0x32: %02x\n", rc);
331
332 dprintk("pll tune band=%d, pll=%d\n", f_switch, (int)f_offset);
333
334 return 0;
335}
336
337static int s921_initfe(struct dvb_frontend *fe)
338{
339 struct s921_state *state = fe->demodulator_priv;
340 int rc;
341
342 dprintk("\n");
343
344 rc = s921_writeregdata(state, s921_init);
345 if (rc < 0)
346 return rc;
347
348 return 0;
349}
350
351static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status)
352{
353 struct s921_state *state = fe->demodulator_priv;
354 int regstatus, rc;
355
356 *status = 0;
357
358 rc = s921_readreg(state, 0x81);
359 if (rc < 0)
360 return rc;
361
362 regstatus = rc << 8;
363
364 rc = s921_readreg(state, 0x82);
365 if (rc < 0)
366 return rc;
367
368 regstatus |= rc;
369
370 dprintk("status = %04x\n", regstatus);
371
372 /* Full Sync - We don't know what each bit means on regs 0x81/0x82 */
373 if ((regstatus & 0xff) == 0x40) {
374 *status = FE_HAS_SIGNAL |
375 FE_HAS_CARRIER |
376 FE_HAS_VITERBI |
377 FE_HAS_SYNC |
378 FE_HAS_LOCK;
379 } else if (regstatus & 0x40) {
380 /* This is close to Full Sync, but not enough to get useful info */
381 *status = FE_HAS_SIGNAL |
382 FE_HAS_CARRIER |
383 FE_HAS_VITERBI |
384 FE_HAS_SYNC;
385 }
386
387 return 0;
388}
389
390static int s921_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
391{
392 fe_status_t status;
393 struct s921_state *state = fe->demodulator_priv;
394 int rc;
395
396 /* FIXME: Use the proper register for it... 0x80? */
397 rc = s921_read_status(fe, &status);
398 if (rc < 0)
399 return rc;
400
401 *strength = (status & FE_HAS_LOCK) ? 0xffff : 0;
402
403 dprintk("strength = 0x%04x\n", *strength);
404
405 rc = s921_readreg(state, 0x01);
406 dprintk("status 0x01: %02x\n", rc);
407
408 rc = s921_readreg(state, 0x80);
409 dprintk("status 0x80: %02x\n", rc);
410
411 rc = s921_readreg(state, 0x32);
412 dprintk("status 0x32: %02x\n", rc);
413
414 return 0;
415}
416
417static int s921_set_frontend(struct dvb_frontend *fe,
418 struct dvb_frontend_parameters *p)
419{
420 struct s921_state *state = fe->demodulator_priv;
421 int rc;
422
423 dprintk("\n");
424
425 /* FIXME: We don't know how to use non-auto mode */
426
427 rc = s921_pll_tune(fe, p);
428 if (rc < 0)
429 return rc;
430
431 state->currentfreq = p->frequency;
432
433 return 0;
434}
435
436static int s921_get_frontend(struct dvb_frontend *fe,
437 struct dvb_frontend_parameters *p)
438{
439 struct s921_state *state = fe->demodulator_priv;
440
441 /* FIXME: Probably it is possible to get it from regs f1 and f2 */
442 p->frequency = state->currentfreq;
443
444 return 0;
445}
446
447static int s921_tune(struct dvb_frontend *fe,
448 struct dvb_frontend_parameters *params,
449 unsigned int mode_flags,
450 unsigned int *delay,
451 fe_status_t *status)
452{
453 int rc = 0;
454
455 dprintk("\n");
456
457 if (params != NULL)
458 rc = s921_set_frontend(fe, params);
459
460 if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
461 s921_read_status(fe, status);
462
463 return rc;
464}
465
466static int s921_get_algo(struct dvb_frontend *fe)
467{
468 return 1; /* FE_ALGO_HW */
469}
470
471static void s921_release(struct dvb_frontend *fe)
472{
473 struct s921_state *state = fe->demodulator_priv;
474
475 dprintk("\n");
476 kfree(state);
477}
478
479static struct dvb_frontend_ops s921_ops;
480
481struct dvb_frontend *s921_attach(const struct s921_config *config,
482 struct i2c_adapter *i2c)
483{
484 /* allocate memory for the internal state */
485 struct s921_state *state =
486 kzalloc(sizeof(struct s921_state), GFP_KERNEL);
487
488 dprintk("\n");
489 if (state == NULL) {
490 rc("Unable to kzalloc\n");
491 goto rcor;
492 }
493
494 /* setup the state */
495 state->config = config;
496 state->i2c = i2c;
497
498 /* create dvb_frontend */
499 memcpy(&state->frontend.ops, &s921_ops,
500 sizeof(struct dvb_frontend_ops));
501 state->frontend.demodulator_priv = state;
502
503 return &state->frontend;
504
505rcor:
506 kfree(state);
507
508 return NULL;
509}
510EXPORT_SYMBOL(s921_attach);
511
512static struct dvb_frontend_ops s921_ops = {
513 /* Use dib8000 values per default */
514 .info = {
515 .name = "Sharp S921",
516 .type = FE_OFDM,
517 .frequency_min = 470000000,
518 /*
519 * Max should be 770MHz instead, according with Sharp docs,
520 * but Leadership doc says it works up to 806 MHz. This is
521 * required to get channel 69, used in Brazil
522 */
523 .frequency_max = 806000000,
524 .frequency_tolerance = 0,
525 .caps = FE_CAN_INVERSION_AUTO |
526 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
527 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
528 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
529 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
530 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |
531 FE_CAN_HIERARCHY_AUTO,
532 },
533
534 .release = s921_release,
535
536 .init = s921_initfe,
537 .set_frontend = s921_set_frontend,
538 .get_frontend = s921_get_frontend,
539 .read_status = s921_read_status,
540 .read_signal_strength = s921_read_signal_strength,
541 .tune = s921_tune,
542 .get_frontend_algo = s921_get_algo,
543};
544
545MODULE_DESCRIPTION("DVB Frontend module for Sharp S921 hardware");
546MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
547MODULE_AUTHOR("Douglas Landgraf <dougsland@redhat.com>");
548MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/s921.h b/drivers/media/dvb/frontends/s921.h
new file mode 100644
index 00000000000..f220d8299c8
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921.h
@@ -0,0 +1,47 @@
1/*
2 * Sharp s921 driver
3 *
4 * Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@redhat.com>
5 * Copyright (C) 2009 Douglas Landgraf <dougsland@redhat.com>
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 version 2.
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 GNU
14 * General Public License for more details.
15 */
16
17#ifndef S921_H
18#define S921_H
19
20#include <linux/dvb/frontend.h>
21
22struct s921_config {
23 /* the demodulator's i2c address */
24 u8 demod_address;
25};
26
27#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) \
28 && defined(MODULE))
29extern struct dvb_frontend *s921_attach(const struct s921_config *config,
30 struct i2c_adapter *i2c);
31extern struct i2c_adapter *s921_get_tuner_i2c_adapter(struct dvb_frontend *);
32#else
33static inline struct dvb_frontend *s921_attach(
34 const struct s921_config *config, struct i2c_adapter *i2c)
35{
36 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
37 return NULL;
38}
39static struct i2c_adapter *
40 s921_get_tuner_i2c_adapter(struct dvb_frontend *fe)
41{
42 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
43 return NULL;
44}
45#endif
46
47#endif /* S921_H */
diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb/frontends/si21xx.c
new file mode 100644
index 00000000000..4b0c99a08a8
--- /dev/null
+++ b/drivers/media/dvb/frontends/si21xx.c
@@ -0,0 +1,967 @@
1/* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator
2*
3* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
4*
5* This program is free software; you can redistribute it and/or modify
6* it under the terms of the GNU General Public License as published by
7* the Free Software Foundation; either version 2 of the License, or
8* (at your option) any later version.
9*
10*/
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/string.h>
15#include <linux/slab.h>
16#include <linux/jiffies.h>
17#include <asm/div64.h>
18
19#include "dvb_frontend.h"
20#include "si21xx.h"
21
22#define REVISION_REG 0x00
23#define SYSTEM_MODE_REG 0x01
24#define TS_CTRL_REG_1 0x02
25#define TS_CTRL_REG_2 0x03
26#define PIN_CTRL_REG_1 0x04
27#define PIN_CTRL_REG_2 0x05
28#define LOCK_STATUS_REG_1 0x0f
29#define LOCK_STATUS_REG_2 0x10
30#define ACQ_STATUS_REG 0x11
31#define ACQ_CTRL_REG_1 0x13
32#define ACQ_CTRL_REG_2 0x14
33#define PLL_DIVISOR_REG 0x15
34#define COARSE_TUNE_REG 0x16
35#define FINE_TUNE_REG_L 0x17
36#define FINE_TUNE_REG_H 0x18
37
38#define ANALOG_AGC_POWER_LEVEL_REG 0x28
39#define CFO_ESTIMATOR_CTRL_REG_1 0x29
40#define CFO_ESTIMATOR_CTRL_REG_2 0x2a
41#define CFO_ESTIMATOR_CTRL_REG_3 0x2b
42
43#define SYM_RATE_ESTIMATE_REG_L 0x31
44#define SYM_RATE_ESTIMATE_REG_M 0x32
45#define SYM_RATE_ESTIMATE_REG_H 0x33
46
47#define CFO_ESTIMATOR_OFFSET_REG_L 0x36
48#define CFO_ESTIMATOR_OFFSET_REG_H 0x37
49#define CFO_ERROR_REG_L 0x38
50#define CFO_ERROR_REG_H 0x39
51#define SYM_RATE_ESTIMATOR_CTRL_REG 0x3a
52
53#define SYM_RATE_REG_L 0x3f
54#define SYM_RATE_REG_M 0x40
55#define SYM_RATE_REG_H 0x41
56#define SYM_RATE_ESTIMATOR_MAXIMUM_REG 0x42
57#define SYM_RATE_ESTIMATOR_MINIMUM_REG 0x43
58
59#define C_N_ESTIMATOR_CTRL_REG 0x7c
60#define C_N_ESTIMATOR_THRSHLD_REG 0x7d
61#define C_N_ESTIMATOR_LEVEL_REG_L 0x7e
62#define C_N_ESTIMATOR_LEVEL_REG_H 0x7f
63
64#define BLIND_SCAN_CTRL_REG 0x80
65
66#define LSA_CTRL_REG_1 0x8D
67#define SPCTRM_TILT_CORR_THRSHLD_REG 0x8f
68#define ONE_DB_BNDWDTH_THRSHLD_REG 0x90
69#define TWO_DB_BNDWDTH_THRSHLD_REG 0x91
70#define THREE_DB_BNDWDTH_THRSHLD_REG 0x92
71#define INBAND_POWER_THRSHLD_REG 0x93
72#define REF_NOISE_LVL_MRGN_THRSHLD_REG 0x94
73
74#define VIT_SRCH_CTRL_REG_1 0xa0
75#define VIT_SRCH_CTRL_REG_2 0xa1
76#define VIT_SRCH_CTRL_REG_3 0xa2
77#define VIT_SRCH_STATUS_REG 0xa3
78#define VITERBI_BER_COUNT_REG_L 0xab
79#define REED_SOLOMON_CTRL_REG 0xb0
80#define REED_SOLOMON_ERROR_COUNT_REG_L 0xb1
81#define PRBS_CTRL_REG 0xb5
82
83#define LNB_CTRL_REG_1 0xc0
84#define LNB_CTRL_REG_2 0xc1
85#define LNB_CTRL_REG_3 0xc2
86#define LNB_CTRL_REG_4 0xc3
87#define LNB_CTRL_STATUS_REG 0xc4
88#define LNB_FIFO_REGS_0 0xc5
89#define LNB_FIFO_REGS_1 0xc6
90#define LNB_FIFO_REGS_2 0xc7
91#define LNB_FIFO_REGS_3 0xc8
92#define LNB_FIFO_REGS_4 0xc9
93#define LNB_FIFO_REGS_5 0xca
94#define LNB_SUPPLY_CTRL_REG_1 0xcb
95#define LNB_SUPPLY_CTRL_REG_2 0xcc
96#define LNB_SUPPLY_CTRL_REG_3 0xcd
97#define LNB_SUPPLY_CTRL_REG_4 0xce
98#define LNB_SUPPLY_STATUS_REG 0xcf
99
100#define FAIL -1
101#define PASS 0
102
103#define ALLOWABLE_FS_COUNT 10
104#define STATUS_BER 0
105#define STATUS_UCBLOCKS 1
106
107static int debug;
108#define dprintk(args...) \
109 do { \
110 if (debug) \
111 printk(KERN_DEBUG "si21xx: " args); \
112 } while (0)
113
114enum {
115 ACTIVE_HIGH,
116 ACTIVE_LOW
117};
118enum {
119 BYTE_WIDE,
120 BIT_WIDE
121};
122enum {
123 CLK_GAPPED_MODE,
124 CLK_CONTINUOUS_MODE
125};
126enum {
127 RISING_EDGE,
128 FALLING_EDGE
129};
130enum {
131 MSB_FIRST,
132 LSB_FIRST
133};
134enum {
135 SERIAL,
136 PARALLEL
137};
138
139struct si21xx_state {
140 struct i2c_adapter *i2c;
141 const struct si21xx_config *config;
142 struct dvb_frontend frontend;
143 u8 initialised:1;
144 int errmode;
145 int fs; /*Sampling rate of the ADC in MHz*/
146};
147
148/* register default initialization */
149static u8 serit_sp1511lhb_inittab[] = {
150 0x01, 0x28, /* set i2c_inc_disable */
151 0x20, 0x03,
152 0x27, 0x20,
153 0xe0, 0x45,
154 0xe1, 0x08,
155 0xfe, 0x01,
156 0x01, 0x28,
157 0x89, 0x09,
158 0x04, 0x80,
159 0x05, 0x01,
160 0x06, 0x00,
161 0x20, 0x03,
162 0x24, 0x88,
163 0x29, 0x09,
164 0x2a, 0x0f,
165 0x2c, 0x10,
166 0x2d, 0x19,
167 0x2e, 0x08,
168 0x2f, 0x10,
169 0x30, 0x19,
170 0x34, 0x20,
171 0x35, 0x03,
172 0x45, 0x02,
173 0x46, 0x45,
174 0x47, 0xd0,
175 0x48, 0x00,
176 0x49, 0x40,
177 0x4a, 0x03,
178 0x4c, 0xfd,
179 0x4f, 0x2e,
180 0x50, 0x2e,
181 0x51, 0x10,
182 0x52, 0x10,
183 0x56, 0x92,
184 0x59, 0x00,
185 0x5a, 0x2d,
186 0x5b, 0x33,
187 0x5c, 0x1f,
188 0x5f, 0x76,
189 0x62, 0xc0,
190 0x63, 0xc0,
191 0x64, 0xf3,
192 0x65, 0xf3,
193 0x79, 0x40,
194 0x6a, 0x40,
195 0x6b, 0x0a,
196 0x6c, 0x80,
197 0x6d, 0x27,
198 0x71, 0x06,
199 0x75, 0x60,
200 0x78, 0x00,
201 0x79, 0xb5,
202 0x7c, 0x05,
203 0x7d, 0x1a,
204 0x87, 0x55,
205 0x88, 0x72,
206 0x8f, 0x08,
207 0x90, 0xe0,
208 0x94, 0x40,
209 0xa0, 0x3f,
210 0xa1, 0xc0,
211 0xa4, 0xcc,
212 0xa5, 0x66,
213 0xa6, 0x66,
214 0xa7, 0x7b,
215 0xa8, 0x7b,
216 0xa9, 0x7b,
217 0xaa, 0x9a,
218 0xed, 0x04,
219 0xad, 0x00,
220 0xae, 0x03,
221 0xcc, 0xab,
222 0x01, 0x08,
223 0xff, 0xff
224};
225
226/* low level read/writes */
227static int si21_writeregs(struct si21xx_state *state, u8 reg1,
228 u8 *data, int len)
229{
230 int ret;
231 u8 buf[60];/* = { reg1, data };*/
232 struct i2c_msg msg = {
233 .addr = state->config->demod_address,
234 .flags = 0,
235 .buf = buf,
236 .len = len + 1
237 };
238
239 msg.buf[0] = reg1;
240 memcpy(msg.buf + 1, data, len);
241
242 ret = i2c_transfer(state->i2c, &msg, 1);
243
244 if (ret != 1)
245 dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, "
246 "ret == %i)\n", __func__, reg1, data[0], ret);
247
248 return (ret != 1) ? -EREMOTEIO : 0;
249}
250
251static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
252{
253 int ret;
254 u8 buf[] = { reg, data };
255 struct i2c_msg msg = {
256 .addr = state->config->demod_address,
257 .flags = 0,
258 .buf = buf,
259 .len = 2
260 };
261
262 ret = i2c_transfer(state->i2c, &msg, 1);
263
264 if (ret != 1)
265 dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, "
266 "ret == %i)\n", __func__, reg, data, ret);
267
268 return (ret != 1) ? -EREMOTEIO : 0;
269}
270
271static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len)
272{
273 struct si21xx_state *state = fe->demodulator_priv;
274
275 if (len != 2)
276 return -EINVAL;
277
278 return si21_writereg(state, buf[0], buf[1]);
279}
280
281static u8 si21_readreg(struct si21xx_state *state, u8 reg)
282{
283 int ret;
284 u8 b0[] = { reg };
285 u8 b1[] = { 0 };
286 struct i2c_msg msg[] = {
287 {
288 .addr = state->config->demod_address,
289 .flags = 0,
290 .buf = b0,
291 .len = 1
292 }, {
293 .addr = state->config->demod_address,
294 .flags = I2C_M_RD,
295 .buf = b1,
296 .len = 1
297 }
298 };
299
300 ret = i2c_transfer(state->i2c, msg, 2);
301
302 if (ret != 2)
303 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
304 __func__, reg, ret);
305
306 return b1[0];
307}
308
309static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
310{
311 int ret;
312 struct i2c_msg msg[] = {
313 {
314 .addr = state->config->demod_address,
315 .flags = 0,
316 .buf = &reg1,
317 .len = 1
318 }, {
319 .addr = state->config->demod_address,
320 .flags = I2C_M_RD,
321 .buf = b,
322 .len = len
323 }
324 };
325
326 ret = i2c_transfer(state->i2c, msg, 2);
327
328 if (ret != 2)
329 dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
330
331 return ret == 2 ? 0 : -1;
332}
333
334static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
335{
336 unsigned long start = jiffies;
337
338 dprintk("%s\n", __func__);
339
340 while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) {
341 if (jiffies - start > timeout) {
342 dprintk("%s: timeout!!\n", __func__);
343 return -ETIMEDOUT;
344 }
345 msleep(10);
346 };
347
348 return 0;
349}
350
351static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
352{
353 struct si21xx_state *state = fe->demodulator_priv;
354 u32 sym_rate, data_rate;
355 int i;
356 u8 sym_rate_bytes[3];
357
358 dprintk("%s : srate = %i\n", __func__ , srate);
359
360 if ((srate < 1000000) || (srate > 45000000))
361 return -EINVAL;
362
363 data_rate = srate;
364 sym_rate = 0;
365
366 for (i = 0; i < 4; ++i) {
367 sym_rate /= 100;
368 sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
369 state->fs;
370 data_rate /= 100;
371 }
372 for (i = 0; i < 3; ++i)
373 sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
374
375 si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
376
377 return 0;
378}
379
380static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
381 struct dvb_diseqc_master_cmd *m)
382{
383 struct si21xx_state *state = fe->demodulator_priv;
384 u8 lnb_status;
385 u8 LNB_CTRL_1;
386 int status;
387
388 dprintk("%s\n", __func__);
389
390 status = PASS;
391 LNB_CTRL_1 = 0;
392
393 status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
394 status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
395
396 /*fill the FIFO*/
397 status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
398
399 LNB_CTRL_1 = (lnb_status & 0x70);
400 LNB_CTRL_1 |= m->msg_len;
401
402 LNB_CTRL_1 |= 0x80; /* begin LNB signaling */
403
404 status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
405
406 return status;
407}
408
409static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
410 fe_sec_mini_cmd_t burst)
411{
412 struct si21xx_state *state = fe->demodulator_priv;
413 u8 val;
414
415 dprintk("%s\n", __func__);
416
417 if (si21xx_wait_diseqc_idle(state, 100) < 0)
418 return -ETIMEDOUT;
419
420 val = (0x80 | si21_readreg(state, 0xc1));
421 if (si21_writereg(state, LNB_CTRL_REG_1,
422 burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10)))
423 return -EREMOTEIO;
424
425 if (si21xx_wait_diseqc_idle(state, 100) < 0)
426 return -ETIMEDOUT;
427
428 if (si21_writereg(state, LNB_CTRL_REG_1, val))
429 return -EREMOTEIO;
430
431 return 0;
432}
433/* 30.06.2008 */
434static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
435{
436 struct si21xx_state *state = fe->demodulator_priv;
437 u8 val;
438
439 dprintk("%s\n", __func__);
440 val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
441
442 switch (tone) {
443 case SEC_TONE_ON:
444 return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
445
446 case SEC_TONE_OFF:
447 return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
448
449 default:
450 return -EINVAL;
451 }
452}
453
454static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
455{
456 struct si21xx_state *state = fe->demodulator_priv;
457
458 u8 val;
459 dprintk("%s: %s\n", __func__,
460 volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
461 volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
462
463
464 val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
465
466 switch (volt) {
467 case SEC_VOLTAGE_18:
468 return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
469 break;
470 case SEC_VOLTAGE_13:
471 return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
472 break;
473 default:
474 return -EINVAL;
475 };
476}
477
478static int si21xx_init(struct dvb_frontend *fe)
479{
480 struct si21xx_state *state = fe->demodulator_priv;
481 int i;
482 int status = 0;
483 u8 reg1;
484 u8 val;
485 u8 reg2[2];
486
487 dprintk("%s\n", __func__);
488
489 for (i = 0; ; i += 2) {
490 reg1 = serit_sp1511lhb_inittab[i];
491 val = serit_sp1511lhb_inittab[i+1];
492 if (reg1 == 0xff && val == 0xff)
493 break;
494 si21_writeregs(state, reg1, &val, 1);
495 }
496
497 /*DVB QPSK SYSTEM MODE REG*/
498 reg1 = 0x08;
499 si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
500
501 /*transport stream config*/
502 /*
503 mode = PARALLEL;
504 sdata_form = LSB_FIRST;
505 clk_edge = FALLING_EDGE;
506 clk_mode = CLK_GAPPED_MODE;
507 strt_len = BYTE_WIDE;
508 sync_pol = ACTIVE_HIGH;
509 val_pol = ACTIVE_HIGH;
510 err_pol = ACTIVE_HIGH;
511 sclk_rate = 0x00;
512 parity = 0x00 ;
513 data_delay = 0x00;
514 clk_delay = 0x00;
515 pclk_smooth = 0x00;
516 */
517 reg2[0] =
518 PARALLEL + (LSB_FIRST << 1)
519 + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3)
520 + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5)
521 + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7);
522
523 reg2[1] = 0;
524 /* sclk_rate + (parity << 2)
525 + (data_delay << 3) + (clk_delay << 4)
526 + (pclk_smooth << 5);
527 */
528 status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
529 if (status != 0)
530 dprintk(" %s : TS Set Error\n", __func__);
531
532 return 0;
533
534}
535
536static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status)
537{
538 struct si21xx_state *state = fe->demodulator_priv;
539 u8 regs_read[2];
540 u8 reg_read;
541 u8 i;
542 u8 lock;
543 u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
544
545 si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
546 reg_read = 0;
547
548 for (i = 0; i < 7; ++i)
549 reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
550
551 lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
552
553 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
554 *status = 0;
555
556 if (signal > 10)
557 *status |= FE_HAS_SIGNAL;
558
559 if (lock & 0x2)
560 *status |= FE_HAS_CARRIER;
561
562 if (lock & 0x20)
563 *status |= FE_HAS_VITERBI;
564
565 if (lock & 0x40)
566 *status |= FE_HAS_SYNC;
567
568 if ((lock & 0x7b) == 0x7b)
569 *status |= FE_HAS_LOCK;
570
571 return 0;
572}
573
574static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
575{
576 struct si21xx_state *state = fe->demodulator_priv;
577
578 /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
579 (u8*)agclevel, 0x01);*/
580
581 u16 signal = (3 * si21_readreg(state, 0x27) *
582 si21_readreg(state, 0x28));
583
584 dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
585 si21_readreg(state, 0x27),
586 si21_readreg(state, 0x28), (int) signal);
587
588 signal <<= 4;
589 *strength = signal;
590
591 return 0;
592}
593
594static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
595{
596 struct si21xx_state *state = fe->demodulator_priv;
597
598 dprintk("%s\n", __func__);
599
600 if (state->errmode != STATUS_BER)
601 return 0;
602
603 *ber = (si21_readreg(state, 0x1d) << 8) |
604 si21_readreg(state, 0x1e);
605
606 return 0;
607}
608
609static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
610{
611 struct si21xx_state *state = fe->demodulator_priv;
612
613 s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
614 si21_readreg(state, 0x25));
615 xsnr = 3 * (xsnr - 0xa100);
616 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
617
618 dprintk("%s\n", __func__);
619
620 return 0;
621}
622
623static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
624{
625 struct si21xx_state *state = fe->demodulator_priv;
626
627 dprintk("%s\n", __func__);
628
629 if (state->errmode != STATUS_UCBLOCKS)
630 *ucblocks = 0;
631 else
632 *ucblocks = (si21_readreg(state, 0x1d) << 8) |
633 si21_readreg(state, 0x1e);
634
635 return 0;
636}
637
638/* initiates a channel acquisition sequence
639 using the specified symbol rate and code rate */
640static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
641 fe_code_rate_t crate)
642{
643
644 struct si21xx_state *state = fe->demodulator_priv;
645 u8 coderates[] = {
646 0x0, 0x01, 0x02, 0x04, 0x00,
647 0x8, 0x10, 0x20, 0x00, 0x3f
648 };
649
650 u8 coderate_ptr;
651 int status;
652 u8 start_acq = 0x80;
653 u8 reg, regs[3];
654
655 dprintk("%s\n", __func__);
656
657 status = PASS;
658 coderate_ptr = coderates[crate];
659
660 si21xx_set_symbolrate(fe, symbrate);
661
662 /* write code rates to use in the Viterbi search */
663 status |= si21_writeregs(state,
664 VIT_SRCH_CTRL_REG_1,
665 &coderate_ptr, 0x01);
666
667 /* clear acq_start bit */
668 status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
669 reg &= ~start_acq;
670 status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
671
672 /* use new Carrier Frequency Offset Estimator (QuickLock) */
673 regs[0] = 0xCB;
674 regs[1] = 0x40;
675 regs[2] = 0xCB;
676
677 status |= si21_writeregs(state,
678 TWO_DB_BNDWDTH_THRSHLD_REG,
679 &regs[0], 0x03);
680 reg = 0x56;
681 status |= si21_writeregs(state,
682 LSA_CTRL_REG_1, &reg, 1);
683 reg = 0x05;
684 status |= si21_writeregs(state,
685 BLIND_SCAN_CTRL_REG, &reg, 1);
686 /* start automatic acq */
687 status |= si21_writeregs(state,
688 ACQ_CTRL_REG_2, &start_acq, 0x01);
689
690 return status;
691}
692
693static int si21xx_set_property(struct dvb_frontend *fe, struct dtv_property *p)
694{
695 dprintk("%s(..)\n", __func__);
696 return 0;
697}
698
699static int si21xx_get_property(struct dvb_frontend *fe, struct dtv_property *p)
700{
701 dprintk("%s(..)\n", __func__);
702 return 0;
703}
704
705static int si21xx_set_frontend(struct dvb_frontend *fe,
706 struct dvb_frontend_parameters *dfp)
707{
708 struct si21xx_state *state = fe->demodulator_priv;
709 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
710
711 /* freq Channel carrier frequency in KHz (i.e. 1550000 KHz)
712 datarate Channel symbol rate in Sps (i.e. 22500000 Sps)*/
713
714 /* in MHz */
715 unsigned char coarse_tune_freq;
716 int fine_tune_freq;
717 unsigned char sample_rate = 0;
718 /* boolean */
719 bool inband_interferer_ind;
720
721 /* INTERMEDIATE VALUES */
722 int icoarse_tune_freq; /* MHz */
723 int ifine_tune_freq; /* MHz */
724 unsigned int band_high;
725 unsigned int band_low;
726 unsigned int x1;
727 unsigned int x2;
728 int i;
729 bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
730 bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
731 int status;
732
733 /* allowable sample rates for ADC in MHz */
734 int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
735 196, 204, 205, 206, 207
736 };
737 /* in MHz */
738 int if_limit_high;
739 int if_limit_low;
740 int lnb_lo;
741 int lnb_uncertanity;
742
743 int rf_freq;
744 int data_rate;
745 unsigned char regs[4];
746
747 dprintk("%s : FE_SET_FRONTEND\n", __func__);
748
749 if (c->delivery_system != SYS_DVBS) {
750 dprintk("%s: unsupported delivery system selected (%d)\n",
751 __func__, c->delivery_system);
752 return -EOPNOTSUPP;
753 }
754
755 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
756 inband_interferer_div2[i] = inband_interferer_div4[i] = false;
757
758 if_limit_high = -700000;
759 if_limit_low = -100000;
760 /* in MHz */
761 lnb_lo = 0;
762 lnb_uncertanity = 0;
763
764 rf_freq = 10 * c->frequency ;
765 data_rate = c->symbol_rate / 100;
766
767 status = PASS;
768
769 band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
770 + (data_rate * 135)) / 200;
771
772 band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
773 + (data_rate * 135)) / 200;
774
775
776 icoarse_tune_freq = 100000 *
777 (((rf_freq - lnb_lo) -
778 (if_limit_low + if_limit_high) / 2)
779 / 100000);
780
781 ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
782
783 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
784 x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
785 (afs[i] * 2500) + afs[i] * 2500;
786
787 x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
788 (afs[i] * 2500);
789
790 if (((band_low < x1) && (x1 < band_high)) ||
791 ((band_low < x2) && (x2 < band_high)))
792 inband_interferer_div4[i] = true;
793
794 }
795
796 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
797 x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
798 (afs[i] * 5000) + afs[i] * 5000;
799
800 x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
801 (afs[i] * 5000);
802
803 if (((band_low < x1) && (x1 < band_high)) ||
804 ((band_low < x2) && (x2 < band_high)))
805 inband_interferer_div2[i] = true;
806 }
807
808 inband_interferer_ind = true;
809 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
810 if (inband_interferer_div2[i] || inband_interferer_div4[i]) {
811 inband_interferer_ind = false;
812 break;
813 }
814 }
815
816 if (inband_interferer_ind) {
817 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
818 if (!inband_interferer_div2[i]) {
819 sample_rate = (u8) afs[i];
820 break;
821 }
822 }
823 } else {
824 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
825 if ((inband_interferer_div2[i] ||
826 !inband_interferer_div4[i])) {
827 sample_rate = (u8) afs[i];
828 break;
829 }
830 }
831
832 }
833
834 if (sample_rate > 207 || sample_rate < 192)
835 sample_rate = 200;
836
837 fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
838 ((sample_rate) * 1000));
839
840 coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
841
842 regs[0] = sample_rate;
843 regs[1] = coarse_tune_freq;
844 regs[2] = fine_tune_freq & 0xFF;
845 regs[3] = fine_tune_freq >> 8 & 0xFF;
846
847 status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
848
849 state->fs = sample_rate;/*ADC MHz*/
850 si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
851
852 return 0;
853}
854
855static int si21xx_sleep(struct dvb_frontend *fe)
856{
857 struct si21xx_state *state = fe->demodulator_priv;
858 u8 regdata;
859
860 dprintk("%s\n", __func__);
861
862 si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
863 regdata |= 1 << 6;
864 si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
865 state->initialised = 0;
866
867 return 0;
868}
869
870static void si21xx_release(struct dvb_frontend *fe)
871{
872 struct si21xx_state *state = fe->demodulator_priv;
873
874 dprintk("%s\n", __func__);
875
876 kfree(state);
877}
878
879static struct dvb_frontend_ops si21xx_ops = {
880
881 .info = {
882 .name = "SL SI21XX DVB-S",
883 .type = FE_QPSK,
884 .frequency_min = 950000,
885 .frequency_max = 2150000,
886 .frequency_stepsize = 125, /* kHz for QPSK frontends */
887 .frequency_tolerance = 0,
888 .symbol_rate_min = 1000000,
889 .symbol_rate_max = 45000000,
890 .symbol_rate_tolerance = 500, /* ppm */
891 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
892 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
893 FE_CAN_QPSK |
894 FE_CAN_FEC_AUTO
895 },
896
897 .release = si21xx_release,
898 .init = si21xx_init,
899 .sleep = si21xx_sleep,
900 .write = si21_write,
901 .read_status = si21_read_status,
902 .read_ber = si21_read_ber,
903 .read_signal_strength = si21_read_signal_strength,
904 .read_snr = si21_read_snr,
905 .read_ucblocks = si21_read_ucblocks,
906 .diseqc_send_master_cmd = si21xx_send_diseqc_msg,
907 .diseqc_send_burst = si21xx_send_diseqc_burst,
908 .set_tone = si21xx_set_tone,
909 .set_voltage = si21xx_set_voltage,
910
911 .set_property = si21xx_set_property,
912 .get_property = si21xx_get_property,
913 .set_frontend = si21xx_set_frontend,
914};
915
916struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
917 struct i2c_adapter *i2c)
918{
919 struct si21xx_state *state = NULL;
920 int id;
921
922 dprintk("%s\n", __func__);
923
924 /* allocate memory for the internal state */
925 state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
926 if (state == NULL)
927 goto error;
928
929 /* setup the state */
930 state->config = config;
931 state->i2c = i2c;
932 state->initialised = 0;
933 state->errmode = STATUS_BER;
934
935 /* check if the demod is there */
936 id = si21_readreg(state, SYSTEM_MODE_REG);
937 si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */
938 msleep(200);
939 id = si21_readreg(state, 0x00);
940
941 /* register 0x00 contains:
942 0x34 for SI2107
943 0x24 for SI2108
944 0x14 for SI2109
945 0x04 for SI2110
946 */
947 if (id != 0x04 && id != 0x14)
948 goto error;
949
950 /* create dvb_frontend */
951 memcpy(&state->frontend.ops, &si21xx_ops,
952 sizeof(struct dvb_frontend_ops));
953 state->frontend.demodulator_priv = state;
954 return &state->frontend;
955
956error:
957 kfree(state);
958 return NULL;
959}
960EXPORT_SYMBOL(si21xx_attach);
961
962module_param(debug, int, 0644);
963MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
964
965MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
966MODULE_AUTHOR("Igor M. Liplianin");
967MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/si21xx.h b/drivers/media/dvb/frontends/si21xx.h
new file mode 100644
index 00000000000..141b5b8a5f6
--- /dev/null
+++ b/drivers/media/dvb/frontends/si21xx.h
@@ -0,0 +1,37 @@
1#ifndef SI21XX_H
2#define SI21XX_H
3
4#include <linux/dvb/frontend.h>
5#include "dvb_frontend.h"
6
7struct si21xx_config {
8 /* the demodulator's i2c address */
9 u8 demod_address;
10
11 /* minimum delay before retuning */
12 int min_delay_ms;
13};
14
15#if defined(CONFIG_DVB_SI21XX) || \
16 (defined(CONFIG_DVB_SI21XX_MODULE) && defined(MODULE))
17extern struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
18 struct i2c_adapter *i2c);
19#else
20static inline struct dvb_frontend *si21xx_attach(
21 const struct si21xx_config *config, struct i2c_adapter *i2c)
22{
23 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
24 return NULL;
25}
26#endif
27
28static inline int si21xx_writeregister(struct dvb_frontend *fe, u8 reg, u8 val)
29{
30 int r = 0;
31 u8 buf[] = {reg, val};
32 if (fe->ops.write)
33 r = fe->ops.write(fe, buf, 2);
34 return r;
35}
36
37#endif
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c
new file mode 100644
index 00000000000..b85eb60a893
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp8870.c
@@ -0,0 +1,619 @@
1/*
2 Driver for Spase SP8870 demodulator
3
4 Copyright (C) 1999 Juergen Peitz
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22/*
23 * This driver needs external firmware. Please use the command
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to
25 * download/extract it, and then copy it to /usr/lib/hotplug/firmware
26 * or /lib/firmware (depending on configuration of firmware hotplug).
27 */
28#define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw"
29
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/device.h>
33#include <linux/firmware.h>
34#include <linux/delay.h>
35#include <linux/string.h>
36#include <linux/slab.h>
37
38#include "dvb_frontend.h"
39#include "sp8870.h"
40
41
42struct sp8870_state {
43
44 struct i2c_adapter* i2c;
45
46 const struct sp8870_config* config;
47
48 struct dvb_frontend frontend;
49
50 /* demodulator private data */
51 u8 initialised:1;
52};
53
54static int debug;
55#define dprintk(args...) \
56 do { \
57 if (debug) printk(KERN_DEBUG "sp8870: " args); \
58 } while (0)
59
60/* firmware size for sp8870 */
61#define SP8870_FIRMWARE_SIZE 16382
62
63/* starting point for firmware in file 'Sc_main.mc' */
64#define SP8870_FIRMWARE_OFFSET 0x0A
65
66static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data)
67{
68 u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff };
69 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 };
70 int err;
71
72 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
73 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
74 return -EREMOTEIO;
75 }
76
77 return 0;
78}
79
80static int sp8870_readreg (struct sp8870_state* state, u16 reg)
81{
82 int ret;
83 u8 b0 [] = { reg >> 8 , reg & 0xff };
84 u8 b1 [] = { 0, 0 };
85 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
86 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
87
88 ret = i2c_transfer (state->i2c, msg, 2);
89
90 if (ret != 2) {
91 dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
92 return -1;
93 }
94
95 return (b1[0] << 8 | b1[1]);
96}
97
98static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw)
99{
100 struct i2c_msg msg;
101 const char *fw_buf = fw->data;
102 int fw_pos;
103 u8 tx_buf[255];
104 int tx_len;
105 int err = 0;
106
107 dprintk ("%s: ...\n", __func__);
108
109 if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET)
110 return -EINVAL;
111
112 // system controller stop
113 sp8870_writereg(state, 0x0F00, 0x0000);
114
115 // instruction RAM register hiword
116 sp8870_writereg(state, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF));
117
118 // instruction RAM MWR
119 sp8870_writereg(state, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16));
120
121 // do firmware upload
122 fw_pos = SP8870_FIRMWARE_OFFSET;
123 while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){
124 tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos;
125 // write register 0xCF0A
126 tx_buf[0] = 0xCF;
127 tx_buf[1] = 0x0A;
128 memcpy(&tx_buf[2], fw_buf + fw_pos, tx_len);
129 msg.addr = state->config->demod_address;
130 msg.flags = 0;
131 msg.buf = tx_buf;
132 msg.len = tx_len + 2;
133 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
134 printk("%s: firmware upload failed!\n", __func__);
135 printk ("%s: i2c error (err == %i)\n", __func__, err);
136 return err;
137 }
138 fw_pos += tx_len;
139 }
140
141 dprintk ("%s: done!\n", __func__);
142 return 0;
143};
144
145static void sp8870_microcontroller_stop (struct sp8870_state* state)
146{
147 sp8870_writereg(state, 0x0F08, 0x000);
148 sp8870_writereg(state, 0x0F09, 0x000);
149
150 // microcontroller STOP
151 sp8870_writereg(state, 0x0F00, 0x000);
152}
153
154static void sp8870_microcontroller_start (struct sp8870_state* state)
155{
156 sp8870_writereg(state, 0x0F08, 0x000);
157 sp8870_writereg(state, 0x0F09, 0x000);
158
159 // microcontroller START
160 sp8870_writereg(state, 0x0F00, 0x001);
161 // not documented but if we don't read 0x0D01 out here
162 // we don't get a correct data valid signal
163 sp8870_readreg(state, 0x0D01);
164}
165
166static int sp8870_read_data_valid_signal(struct sp8870_state* state)
167{
168 return (sp8870_readreg(state, 0x0D02) > 0);
169}
170
171static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05)
172{
173 int known_parameters = 1;
174
175 *reg0xc05 = 0x000;
176
177 switch (p->u.ofdm.constellation) {
178 case QPSK:
179 break;
180 case QAM_16:
181 *reg0xc05 |= (1 << 10);
182 break;
183 case QAM_64:
184 *reg0xc05 |= (2 << 10);
185 break;
186 case QAM_AUTO:
187 known_parameters = 0;
188 break;
189 default:
190 return -EINVAL;
191 };
192
193 switch (p->u.ofdm.hierarchy_information) {
194 case HIERARCHY_NONE:
195 break;
196 case HIERARCHY_1:
197 *reg0xc05 |= (1 << 7);
198 break;
199 case HIERARCHY_2:
200 *reg0xc05 |= (2 << 7);
201 break;
202 case HIERARCHY_4:
203 *reg0xc05 |= (3 << 7);
204 break;
205 case HIERARCHY_AUTO:
206 known_parameters = 0;
207 break;
208 default:
209 return -EINVAL;
210 };
211
212 switch (p->u.ofdm.code_rate_HP) {
213 case FEC_1_2:
214 break;
215 case FEC_2_3:
216 *reg0xc05 |= (1 << 3);
217 break;
218 case FEC_3_4:
219 *reg0xc05 |= (2 << 3);
220 break;
221 case FEC_5_6:
222 *reg0xc05 |= (3 << 3);
223 break;
224 case FEC_7_8:
225 *reg0xc05 |= (4 << 3);
226 break;
227 case FEC_AUTO:
228 known_parameters = 0;
229 break;
230 default:
231 return -EINVAL;
232 };
233
234 if (known_parameters)
235 *reg0xc05 |= (2 << 1); /* use specified parameters */
236 else
237 *reg0xc05 |= (1 << 1); /* enable autoprobing */
238
239 return 0;
240}
241
242static int sp8870_wake_up(struct sp8870_state* state)
243{
244 // enable TS output and interface pins
245 return sp8870_writereg(state, 0xC18, 0x00D);
246}
247
248static int sp8870_set_frontend_parameters (struct dvb_frontend* fe,
249 struct dvb_frontend_parameters *p)
250{
251 struct sp8870_state* state = fe->demodulator_priv;
252 int err;
253 u16 reg0xc05;
254
255 if ((err = configure_reg0xc05(p, &reg0xc05)))
256 return err;
257
258 // system controller stop
259 sp8870_microcontroller_stop(state);
260
261 // set tuner parameters
262 if (fe->ops.tuner_ops.set_params) {
263 fe->ops.tuner_ops.set_params(fe, p);
264 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
265 }
266
267 // sample rate correction bit [23..17]
268 sp8870_writereg(state, 0x0319, 0x000A);
269
270 // sample rate correction bit [16..0]
271 sp8870_writereg(state, 0x031A, 0x0AAB);
272
273 // integer carrier offset
274 sp8870_writereg(state, 0x0309, 0x0400);
275
276 // fractional carrier offset
277 sp8870_writereg(state, 0x030A, 0x0000);
278
279 // filter for 6/7/8 Mhz channel
280 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
281 sp8870_writereg(state, 0x0311, 0x0002);
282 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
283 sp8870_writereg(state, 0x0311, 0x0001);
284 else
285 sp8870_writereg(state, 0x0311, 0x0000);
286
287 // scan order: 2k first = 0x0000, 8k first = 0x0001
288 if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K)
289 sp8870_writereg(state, 0x0338, 0x0000);
290 else
291 sp8870_writereg(state, 0x0338, 0x0001);
292
293 sp8870_writereg(state, 0xc05, reg0xc05);
294
295 // read status reg in order to clear pending irqs
296 sp8870_readreg(state, 0x200);
297
298 // system controller start
299 sp8870_microcontroller_start(state);
300
301 return 0;
302}
303
304static int sp8870_init (struct dvb_frontend* fe)
305{
306 struct sp8870_state* state = fe->demodulator_priv;
307 const struct firmware *fw = NULL;
308
309 sp8870_wake_up(state);
310 if (state->initialised) return 0;
311 state->initialised = 1;
312
313 dprintk ("%s\n", __func__);
314
315
316 /* request the firmware, this will block until someone uploads it */
317 printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
318 if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
319 printk("sp8870: no firmware upload (timeout or file not found?)\n");
320 return -EIO;
321 }
322
323 if (sp8870_firmware_upload(state, fw)) {
324 printk("sp8870: writing firmware to device failed\n");
325 release_firmware(fw);
326 return -EIO;
327 }
328 release_firmware(fw);
329 printk("sp8870: firmware upload complete\n");
330
331 /* enable TS output and interface pins */
332 sp8870_writereg(state, 0xc18, 0x00d);
333
334 // system controller stop
335 sp8870_microcontroller_stop(state);
336
337 // ADC mode
338 sp8870_writereg(state, 0x0301, 0x0003);
339
340 // Reed Solomon parity bytes passed to output
341 sp8870_writereg(state, 0x0C13, 0x0001);
342
343 // MPEG clock is suppressed if no valid data
344 sp8870_writereg(state, 0x0C14, 0x0001);
345
346 /* bit 0x010: enable data valid signal */
347 sp8870_writereg(state, 0x0D00, 0x010);
348 sp8870_writereg(state, 0x0D01, 0x000);
349
350 return 0;
351}
352
353static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status)
354{
355 struct sp8870_state* state = fe->demodulator_priv;
356 int status;
357 int signal;
358
359 *fe_status = 0;
360
361 status = sp8870_readreg (state, 0x0200);
362 if (status < 0)
363 return -EIO;
364
365 signal = sp8870_readreg (state, 0x0303);
366 if (signal < 0)
367 return -EIO;
368
369 if (signal > 0x0F)
370 *fe_status |= FE_HAS_SIGNAL;
371 if (status & 0x08)
372 *fe_status |= FE_HAS_SYNC;
373 if (status & 0x04)
374 *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI;
375
376 return 0;
377}
378
379static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber)
380{
381 struct sp8870_state* state = fe->demodulator_priv;
382 int ret;
383 u32 tmp;
384
385 *ber = 0;
386
387 ret = sp8870_readreg(state, 0xC08);
388 if (ret < 0)
389 return -EIO;
390
391 tmp = ret & 0x3F;
392
393 ret = sp8870_readreg(state, 0xC07);
394 if (ret < 0)
395 return -EIO;
396
397 tmp = ret << 6;
398
399 if (tmp >= 0x3FFF0)
400 tmp = ~0;
401
402 *ber = tmp;
403
404 return 0;
405}
406
407static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
408{
409 struct sp8870_state* state = fe->demodulator_priv;
410 int ret;
411 u16 tmp;
412
413 *signal = 0;
414
415 ret = sp8870_readreg (state, 0x306);
416 if (ret < 0)
417 return -EIO;
418
419 tmp = ret << 8;
420
421 ret = sp8870_readreg (state, 0x303);
422 if (ret < 0)
423 return -EIO;
424
425 tmp |= ret;
426
427 if (tmp)
428 *signal = 0xFFFF - tmp;
429
430 return 0;
431}
432
433static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks)
434{
435 struct sp8870_state* state = fe->demodulator_priv;
436 int ret;
437
438 *ublocks = 0;
439
440 ret = sp8870_readreg(state, 0xC0C);
441 if (ret < 0)
442 return -EIO;
443
444 if (ret == 0xFFFF)
445 ret = ~0;
446
447 *ublocks = ret;
448
449 return 0;
450}
451
452/* number of trials to recover from lockup */
453#define MAXTRIALS 5
454/* maximum checks for data valid signal */
455#define MAXCHECKS 100
456
457/* only for debugging: counter for detected lockups */
458static int lockups;
459/* only for debugging: counter for channel switches */
460static int switches;
461
462static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
463{
464 struct sp8870_state* state = fe->demodulator_priv;
465
466 /*
467 The firmware of the sp8870 sometimes locks up after setting frontend parameters.
468 We try to detect this by checking the data valid signal.
469 If it is not set after MAXCHECKS we try to recover the lockup by setting
470 the frontend parameters again.
471 */
472
473 int err = 0;
474 int valid = 0;
475 int trials = 0;
476 int check_count = 0;
477
478 dprintk("%s: frequency = %i\n", __func__, p->frequency);
479
480 for (trials = 1; trials <= MAXTRIALS; trials++) {
481
482 if ((err = sp8870_set_frontend_parameters(fe, p)))
483 return err;
484
485 for (check_count = 0; check_count < MAXCHECKS; check_count++) {
486// valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0);
487 valid = sp8870_read_data_valid_signal(state);
488 if (valid) {
489 dprintk("%s: delay = %i usec\n",
490 __func__, check_count * 10);
491 break;
492 }
493 udelay(10);
494 }
495 if (valid)
496 break;
497 }
498
499 if (!valid) {
500 printk("%s: firmware crash!!!!!!\n", __func__);
501 return -EIO;
502 }
503
504 if (debug) {
505 if (valid) {
506 if (trials > 1) {
507 printk("%s: firmware lockup!!!\n", __func__);
508 printk("%s: recovered after %i trial(s))\n", __func__, trials - 1);
509 lockups++;
510 }
511 }
512 switches++;
513 printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups);
514 }
515
516 return 0;
517}
518
519static int sp8870_sleep(struct dvb_frontend* fe)
520{
521 struct sp8870_state* state = fe->demodulator_priv;
522
523 // tristate TS output and disable interface pins
524 return sp8870_writereg(state, 0xC18, 0x000);
525}
526
527static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
528{
529 fesettings->min_delay_ms = 350;
530 fesettings->step_size = 0;
531 fesettings->max_drift = 0;
532 return 0;
533}
534
535static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
536{
537 struct sp8870_state* state = fe->demodulator_priv;
538
539 if (enable) {
540 return sp8870_writereg(state, 0x206, 0x001);
541 } else {
542 return sp8870_writereg(state, 0x206, 0x000);
543 }
544}
545
546static void sp8870_release(struct dvb_frontend* fe)
547{
548 struct sp8870_state* state = fe->demodulator_priv;
549 kfree(state);
550}
551
552static struct dvb_frontend_ops sp8870_ops;
553
554struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
555 struct i2c_adapter* i2c)
556{
557 struct sp8870_state* state = NULL;
558
559 /* allocate memory for the internal state */
560 state = kzalloc(sizeof(struct sp8870_state), GFP_KERNEL);
561 if (state == NULL) goto error;
562
563 /* setup the state */
564 state->config = config;
565 state->i2c = i2c;
566 state->initialised = 0;
567
568 /* check if the demod is there */
569 if (sp8870_readreg(state, 0x0200) < 0) goto error;
570
571 /* create dvb_frontend */
572 memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops));
573 state->frontend.demodulator_priv = state;
574 return &state->frontend;
575
576error:
577 kfree(state);
578 return NULL;
579}
580
581static struct dvb_frontend_ops sp8870_ops = {
582
583 .info = {
584 .name = "Spase SP8870 DVB-T",
585 .type = FE_OFDM,
586 .frequency_min = 470000000,
587 .frequency_max = 860000000,
588 .frequency_stepsize = 166666,
589 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
590 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
591 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
592 FE_CAN_QPSK | FE_CAN_QAM_16 |
593 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
594 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER
595 },
596
597 .release = sp8870_release,
598
599 .init = sp8870_init,
600 .sleep = sp8870_sleep,
601 .i2c_gate_ctrl = sp8870_i2c_gate_ctrl,
602
603 .set_frontend = sp8870_set_frontend,
604 .get_tune_settings = sp8870_get_tune_settings,
605
606 .read_status = sp8870_read_status,
607 .read_ber = sp8870_read_ber,
608 .read_signal_strength = sp8870_read_signal_strength,
609 .read_ucblocks = sp8870_read_uncorrected_blocks,
610};
611
612module_param(debug, int, 0644);
613MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
614
615MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver");
616MODULE_AUTHOR("Juergen Peitz");
617MODULE_LICENSE("GPL");
618
619EXPORT_SYMBOL(sp8870_attach);
diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h
new file mode 100644
index 00000000000..a764a793c7d
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp8870.h
@@ -0,0 +1,50 @@
1/*
2 Driver for Spase SP8870 demodulator
3
4 Copyright (C) 1999 Juergen Peitz
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef SP8870_H
24#define SP8870_H
25
26#include <linux/dvb/frontend.h>
27#include <linux/firmware.h>
28
29struct sp8870_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* request firmware for device */
35 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
36};
37
38#if defined(CONFIG_DVB_SP8870) || (defined(CONFIG_DVB_SP8870_MODULE) && defined(MODULE))
39extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
40 struct i2c_adapter* i2c);
41#else
42static inline struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
43 struct i2c_adapter* i2c)
44{
45 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
46 return NULL;
47}
48#endif // CONFIG_DVB_SP8870
49
50#endif // SP8870_H
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
new file mode 100644
index 00000000000..4a7c3d84260
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -0,0 +1,617 @@
1/*
2 Driver for the Spase sp887x demodulator
3*/
4
5/*
6 * This driver needs external firmware. Please use the command
7 * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
8 * download/extract it, and then copy it to /usr/lib/hotplug/firmware
9 * or /lib/firmware (depending on configuration of firmware hotplug).
10 */
11#define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw"
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/device.h>
16#include <linux/firmware.h>
17#include <linux/string.h>
18#include <linux/slab.h>
19
20#include "dvb_frontend.h"
21#include "sp887x.h"
22
23
24struct sp887x_state {
25 struct i2c_adapter* i2c;
26 const struct sp887x_config* config;
27 struct dvb_frontend frontend;
28
29 /* demodulator private data */
30 u8 initialised:1;
31};
32
33static int debug;
34#define dprintk(args...) \
35 do { \
36 if (debug) printk(KERN_DEBUG "sp887x: " args); \
37 } while (0)
38
39static int i2c_writebytes (struct sp887x_state* state, u8 *buf, u8 len)
40{
41 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = len };
42 int err;
43
44 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
45 printk ("%s: i2c write error (addr %02x, err == %i)\n",
46 __func__, state->config->demod_address, err);
47 return -EREMOTEIO;
48 }
49
50 return 0;
51}
52
53static int sp887x_writereg (struct sp887x_state* state, u16 reg, u16 data)
54{
55 u8 b0 [] = { reg >> 8 , reg & 0xff, data >> 8, data & 0xff };
56 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 4 };
57 int ret;
58
59 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) {
60 /**
61 * in case of soft reset we ignore ACK errors...
62 */
63 if (!(reg == 0xf1a && data == 0x000 &&
64 (ret == -EREMOTEIO || ret == -EFAULT)))
65 {
66 printk("%s: writereg error "
67 "(reg %03x, data %03x, ret == %i)\n",
68 __func__, reg & 0xffff, data & 0xffff, ret);
69 return ret;
70 }
71 }
72
73 return 0;
74}
75
76static int sp887x_readreg (struct sp887x_state* state, u16 reg)
77{
78 u8 b0 [] = { reg >> 8 , reg & 0xff };
79 u8 b1 [2];
80 int ret;
81 struct i2c_msg msg[] = {{ .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
82 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 }};
83
84 if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
85 printk("%s: readreg error (ret == %i)\n", __func__, ret);
86 return -1;
87 }
88
89 return (((b1[0] << 8) | b1[1]) & 0xfff);
90}
91
92static void sp887x_microcontroller_stop (struct sp887x_state* state)
93{
94 dprintk("%s\n", __func__);
95 sp887x_writereg(state, 0xf08, 0x000);
96 sp887x_writereg(state, 0xf09, 0x000);
97
98 /* microcontroller STOP */
99 sp887x_writereg(state, 0xf00, 0x000);
100}
101
102static void sp887x_microcontroller_start (struct sp887x_state* state)
103{
104 dprintk("%s\n", __func__);
105 sp887x_writereg(state, 0xf08, 0x000);
106 sp887x_writereg(state, 0xf09, 0x000);
107
108 /* microcontroller START */
109 sp887x_writereg(state, 0xf00, 0x001);
110}
111
112static void sp887x_setup_agc (struct sp887x_state* state)
113{
114 /* setup AGC parameters */
115 dprintk("%s\n", __func__);
116 sp887x_writereg(state, 0x33c, 0x054);
117 sp887x_writereg(state, 0x33b, 0x04c);
118 sp887x_writereg(state, 0x328, 0x000);
119 sp887x_writereg(state, 0x327, 0x005);
120 sp887x_writereg(state, 0x326, 0x001);
121 sp887x_writereg(state, 0x325, 0x001);
122 sp887x_writereg(state, 0x324, 0x001);
123 sp887x_writereg(state, 0x318, 0x050);
124 sp887x_writereg(state, 0x317, 0x3fe);
125 sp887x_writereg(state, 0x316, 0x001);
126 sp887x_writereg(state, 0x313, 0x005);
127 sp887x_writereg(state, 0x312, 0x002);
128 sp887x_writereg(state, 0x306, 0x000);
129 sp887x_writereg(state, 0x303, 0x000);
130}
131
132#define BLOCKSIZE 30
133#define FW_SIZE 0x4000
134/**
135 * load firmware and setup MPEG interface...
136 */
137static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw)
138{
139 struct sp887x_state* state = fe->demodulator_priv;
140 u8 buf [BLOCKSIZE+2];
141 int i;
142 int fw_size = fw->size;
143 const unsigned char *mem = fw->data;
144
145 dprintk("%s\n", __func__);
146
147 /* ignore the first 10 bytes, then we expect 0x4000 bytes of firmware */
148 if (fw_size < FW_SIZE+10)
149 return -ENODEV;
150
151 mem = fw->data + 10;
152
153 /* soft reset */
154 sp887x_writereg(state, 0xf1a, 0x000);
155
156 sp887x_microcontroller_stop (state);
157
158 printk ("%s: firmware upload... ", __func__);
159
160 /* setup write pointer to -1 (end of memory) */
161 /* bit 0x8000 in address is set to enable 13bit mode */
162 sp887x_writereg(state, 0x8f08, 0x1fff);
163
164 /* dummy write (wrap around to start of memory) */
165 sp887x_writereg(state, 0x8f0a, 0x0000);
166
167 for (i = 0; i < FW_SIZE; i += BLOCKSIZE) {
168 int c = BLOCKSIZE;
169 int err;
170
171 if (i+c > FW_SIZE)
172 c = FW_SIZE - i;
173
174 /* bit 0x8000 in address is set to enable 13bit mode */
175 /* bit 0x4000 enables multibyte read/write transfers */
176 /* write register is 0xf0a */
177 buf[0] = 0xcf;
178 buf[1] = 0x0a;
179
180 memcpy(&buf[2], mem + i, c);
181
182 if ((err = i2c_writebytes (state, buf, c+2)) < 0) {
183 printk ("failed.\n");
184 printk ("%s: i2c error (err == %i)\n", __func__, err);
185 return err;
186 }
187 }
188
189 /* don't write RS bytes between packets */
190 sp887x_writereg(state, 0xc13, 0x001);
191
192 /* suppress clock if (!data_valid) */
193 sp887x_writereg(state, 0xc14, 0x000);
194
195 /* setup MPEG interface... */
196 sp887x_writereg(state, 0xc1a, 0x872);
197 sp887x_writereg(state, 0xc1b, 0x001);
198 sp887x_writereg(state, 0xc1c, 0x000); /* parallel mode (serial mode == 1) */
199 sp887x_writereg(state, 0xc1a, 0x871);
200
201 /* ADC mode, 2 for MT8872, 3 for SP8870/SP8871 */
202 sp887x_writereg(state, 0x301, 0x002);
203
204 sp887x_setup_agc(state);
205
206 /* bit 0x010: enable data valid signal */
207 sp887x_writereg(state, 0xd00, 0x010);
208 sp887x_writereg(state, 0x0d1, 0x000);
209 return 0;
210};
211
212static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05)
213{
214 int known_parameters = 1;
215
216 *reg0xc05 = 0x000;
217
218 switch (p->u.ofdm.constellation) {
219 case QPSK:
220 break;
221 case QAM_16:
222 *reg0xc05 |= (1 << 10);
223 break;
224 case QAM_64:
225 *reg0xc05 |= (2 << 10);
226 break;
227 case QAM_AUTO:
228 known_parameters = 0;
229 break;
230 default:
231 return -EINVAL;
232 };
233
234 switch (p->u.ofdm.hierarchy_information) {
235 case HIERARCHY_NONE:
236 break;
237 case HIERARCHY_1:
238 *reg0xc05 |= (1 << 7);
239 break;
240 case HIERARCHY_2:
241 *reg0xc05 |= (2 << 7);
242 break;
243 case HIERARCHY_4:
244 *reg0xc05 |= (3 << 7);
245 break;
246 case HIERARCHY_AUTO:
247 known_parameters = 0;
248 break;
249 default:
250 return -EINVAL;
251 };
252
253 switch (p->u.ofdm.code_rate_HP) {
254 case FEC_1_2:
255 break;
256 case FEC_2_3:
257 *reg0xc05 |= (1 << 3);
258 break;
259 case FEC_3_4:
260 *reg0xc05 |= (2 << 3);
261 break;
262 case FEC_5_6:
263 *reg0xc05 |= (3 << 3);
264 break;
265 case FEC_7_8:
266 *reg0xc05 |= (4 << 3);
267 break;
268 case FEC_AUTO:
269 known_parameters = 0;
270 break;
271 default:
272 return -EINVAL;
273 };
274
275 if (known_parameters)
276 *reg0xc05 |= (2 << 1); /* use specified parameters */
277 else
278 *reg0xc05 |= (1 << 1); /* enable autoprobing */
279
280 return 0;
281}
282
283/**
284 * estimates division of two 24bit numbers,
285 * derived from the ves1820/stv0299 driver code
286 */
287static void divide (int n, int d, int *quotient_i, int *quotient_f)
288{
289 unsigned int q, r;
290
291 r = (n % d) << 8;
292 q = (r / d);
293
294 if (quotient_i)
295 *quotient_i = q;
296
297 if (quotient_f) {
298 r = (r % d) << 8;
299 q = (q << 8) | (r / d);
300 r = (r % d) << 8;
301 *quotient_f = (q << 8) | (r / d);
302 }
303}
304
305static void sp887x_correct_offsets (struct sp887x_state* state,
306 struct dvb_frontend_parameters *p,
307 int actual_freq)
308{
309 static const u32 srate_correction [] = { 1879617, 4544878, 8098561 };
310 int bw_index = p->u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
311 int freq_offset = actual_freq - p->frequency;
312 int sysclock = 61003; //[kHz]
313 int ifreq = 36000000;
314 int freq;
315 int frequency_shift;
316
317 if (p->inversion == INVERSION_ON)
318 freq = ifreq - freq_offset;
319 else
320 freq = ifreq + freq_offset;
321
322 divide(freq / 333, sysclock, NULL, &frequency_shift);
323
324 if (p->inversion == INVERSION_ON)
325 frequency_shift = -frequency_shift;
326
327 /* sample rate correction */
328 sp887x_writereg(state, 0x319, srate_correction[bw_index] >> 12);
329 sp887x_writereg(state, 0x31a, srate_correction[bw_index] & 0xfff);
330
331 /* carrier offset correction */
332 sp887x_writereg(state, 0x309, frequency_shift >> 12);
333 sp887x_writereg(state, 0x30a, frequency_shift & 0xfff);
334}
335
336static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe,
337 struct dvb_frontend_parameters *p)
338{
339 struct sp887x_state* state = fe->demodulator_priv;
340 unsigned actual_freq;
341 int err;
342 u16 val, reg0xc05;
343
344 if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ &&
345 p->u.ofdm.bandwidth != BANDWIDTH_7_MHZ &&
346 p->u.ofdm.bandwidth != BANDWIDTH_6_MHZ)
347 return -EINVAL;
348
349 if ((err = configure_reg0xc05(p, &reg0xc05)))
350 return err;
351
352 sp887x_microcontroller_stop(state);
353
354 /* setup the PLL */
355 if (fe->ops.tuner_ops.set_params) {
356 fe->ops.tuner_ops.set_params(fe, p);
357 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
358 }
359 if (fe->ops.tuner_ops.get_frequency) {
360 fe->ops.tuner_ops.get_frequency(fe, &actual_freq);
361 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
362 } else {
363 actual_freq = p->frequency;
364 }
365
366 /* read status reg in order to clear <pending irqs */
367 sp887x_readreg(state, 0x200);
368
369 sp887x_correct_offsets(state, p, actual_freq);
370
371 /* filter for 6/7/8 Mhz channel */
372 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
373 val = 2;
374 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
375 val = 1;
376 else
377 val = 0;
378
379 sp887x_writereg(state, 0x311, val);
380
381 /* scan order: 2k first = 0, 8k first = 1 */
382 if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K)
383 sp887x_writereg(state, 0x338, 0x000);
384 else
385 sp887x_writereg(state, 0x338, 0x001);
386
387 sp887x_writereg(state, 0xc05, reg0xc05);
388
389 if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ)
390 val = 2 << 3;
391 else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ)
392 val = 3 << 3;
393 else
394 val = 0 << 3;
395
396 /* enable OFDM and SAW bits as lock indicators in sync register 0xf17,
397 * optimize algorithm for given bandwidth...
398 */
399 sp887x_writereg(state, 0xf14, 0x160 | val);
400 sp887x_writereg(state, 0xf15, 0x000);
401
402 sp887x_microcontroller_start(state);
403 return 0;
404}
405
406static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status)
407{
408 struct sp887x_state* state = fe->demodulator_priv;
409 u16 snr12 = sp887x_readreg(state, 0xf16);
410 u16 sync0x200 = sp887x_readreg(state, 0x200);
411 u16 sync0xf17 = sp887x_readreg(state, 0xf17);
412
413 *status = 0;
414
415 if (snr12 > 0x00f)
416 *status |= FE_HAS_SIGNAL;
417
418 //if (sync0x200 & 0x004)
419 // *status |= FE_HAS_SYNC | FE_HAS_CARRIER;
420
421 //if (sync0x200 & 0x008)
422 // *status |= FE_HAS_VITERBI;
423
424 if ((sync0xf17 & 0x00f) == 0x002) {
425 *status |= FE_HAS_LOCK;
426 *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_CARRIER;
427 }
428
429 if (sync0x200 & 0x001) { /* tuner adjustment requested...*/
430 int steps = (sync0x200 >> 4) & 0x00f;
431 if (steps & 0x008)
432 steps = -steps;
433 dprintk("sp887x: implement tuner adjustment (%+i steps)!!\n",
434 steps);
435 }
436
437 return 0;
438}
439
440static int sp887x_read_ber(struct dvb_frontend* fe, u32* ber)
441{
442 struct sp887x_state* state = fe->demodulator_priv;
443
444 *ber = (sp887x_readreg(state, 0xc08) & 0x3f) |
445 (sp887x_readreg(state, 0xc07) << 6);
446 sp887x_writereg(state, 0xc08, 0x000);
447 sp887x_writereg(state, 0xc07, 0x000);
448 if (*ber >= 0x3fff0)
449 *ber = ~0;
450
451 return 0;
452}
453
454static int sp887x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
455{
456 struct sp887x_state* state = fe->demodulator_priv;
457
458 u16 snr12 = sp887x_readreg(state, 0xf16);
459 u32 signal = 3 * (snr12 << 4);
460 *strength = (signal < 0xffff) ? signal : 0xffff;
461
462 return 0;
463}
464
465static int sp887x_read_snr(struct dvb_frontend* fe, u16* snr)
466{
467 struct sp887x_state* state = fe->demodulator_priv;
468
469 u16 snr12 = sp887x_readreg(state, 0xf16);
470 *snr = (snr12 << 4) | (snr12 >> 8);
471
472 return 0;
473}
474
475static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
476{
477 struct sp887x_state* state = fe->demodulator_priv;
478
479 *ucblocks = sp887x_readreg(state, 0xc0c);
480 if (*ucblocks == 0xfff)
481 *ucblocks = ~0;
482
483 return 0;
484}
485
486static int sp887x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
487{
488 struct sp887x_state* state = fe->demodulator_priv;
489
490 if (enable) {
491 return sp887x_writereg(state, 0x206, 0x001);
492 } else {
493 return sp887x_writereg(state, 0x206, 0x000);
494 }
495}
496
497static int sp887x_sleep(struct dvb_frontend* fe)
498{
499 struct sp887x_state* state = fe->demodulator_priv;
500
501 /* tristate TS output and disable interface pins */
502 sp887x_writereg(state, 0xc18, 0x000);
503
504 return 0;
505}
506
507static int sp887x_init(struct dvb_frontend* fe)
508{
509 struct sp887x_state* state = fe->demodulator_priv;
510 const struct firmware *fw = NULL;
511 int ret;
512
513 if (!state->initialised) {
514 /* request the firmware, this will block until someone uploads it */
515 printk("sp887x: waiting for firmware upload (%s)...\n", SP887X_DEFAULT_FIRMWARE);
516 ret = state->config->request_firmware(fe, &fw, SP887X_DEFAULT_FIRMWARE);
517 if (ret) {
518 printk("sp887x: no firmware upload (timeout or file not found?)\n");
519 return ret;
520 }
521
522 ret = sp887x_initial_setup(fe, fw);
523 release_firmware(fw);
524 if (ret) {
525 printk("sp887x: writing firmware to device failed\n");
526 return ret;
527 }
528 printk("sp887x: firmware upload complete\n");
529 state->initialised = 1;
530 }
531
532 /* enable TS output and interface pins */
533 sp887x_writereg(state, 0xc18, 0x00d);
534
535 return 0;
536}
537
538static int sp887x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
539{
540 fesettings->min_delay_ms = 350;
541 fesettings->step_size = 166666*2;
542 fesettings->max_drift = (166666*2)+1;
543 return 0;
544}
545
546static void sp887x_release(struct dvb_frontend* fe)
547{
548 struct sp887x_state* state = fe->demodulator_priv;
549 kfree(state);
550}
551
552static struct dvb_frontend_ops sp887x_ops;
553
554struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
555 struct i2c_adapter* i2c)
556{
557 struct sp887x_state* state = NULL;
558
559 /* allocate memory for the internal state */
560 state = kzalloc(sizeof(struct sp887x_state), GFP_KERNEL);
561 if (state == NULL) goto error;
562
563 /* setup the state */
564 state->config = config;
565 state->i2c = i2c;
566 state->initialised = 0;
567
568 /* check if the demod is there */
569 if (sp887x_readreg(state, 0x0200) < 0) goto error;
570
571 /* create dvb_frontend */
572 memcpy(&state->frontend.ops, &sp887x_ops, sizeof(struct dvb_frontend_ops));
573 state->frontend.demodulator_priv = state;
574 return &state->frontend;
575
576error:
577 kfree(state);
578 return NULL;
579}
580
581static struct dvb_frontend_ops sp887x_ops = {
582
583 .info = {
584 .name = "Spase SP887x DVB-T",
585 .type = FE_OFDM,
586 .frequency_min = 50500000,
587 .frequency_max = 858000000,
588 .frequency_stepsize = 166666,
589 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
590 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
591 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
592 FE_CAN_RECOVER
593 },
594
595 .release = sp887x_release,
596
597 .init = sp887x_init,
598 .sleep = sp887x_sleep,
599 .i2c_gate_ctrl = sp887x_i2c_gate_ctrl,
600
601 .set_frontend = sp887x_setup_frontend_parameters,
602 .get_tune_settings = sp887x_get_tune_settings,
603
604 .read_status = sp887x_read_status,
605 .read_ber = sp887x_read_ber,
606 .read_signal_strength = sp887x_read_signal_strength,
607 .read_snr = sp887x_read_snr,
608 .read_ucblocks = sp887x_read_ucblocks,
609};
610
611module_param(debug, int, 0644);
612MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
613
614MODULE_DESCRIPTION("Spase sp887x DVB-T demodulator driver");
615MODULE_LICENSE("GPL");
616
617EXPORT_SYMBOL(sp887x_attach);
diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h
new file mode 100644
index 00000000000..04eff6e0eef
--- /dev/null
+++ b/drivers/media/dvb/frontends/sp887x.h
@@ -0,0 +1,32 @@
1/*
2 Driver for the Spase sp887x demodulator
3*/
4
5#ifndef SP887X_H
6#define SP887X_H
7
8#include <linux/dvb/frontend.h>
9#include <linux/firmware.h>
10
11struct sp887x_config
12{
13 /* the demodulator's i2c address */
14 u8 demod_address;
15
16 /* request firmware for device */
17 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
18};
19
20#if defined(CONFIG_DVB_SP887X) || (defined(CONFIG_DVB_SP887X_MODULE) && defined(MODULE))
21extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
22 struct i2c_adapter* i2c);
23#else
24static inline struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
25 struct i2c_adapter* i2c)
26{
27 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
28 return NULL;
29}
30#endif // CONFIG_DVB_SP887X
31
32#endif // SP887X_H
diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c
new file mode 100644
index 00000000000..d70eee00f33
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_algo.c
@@ -0,0 +1,1522 @@
1/*
2 STB0899 Multistandard Frontend driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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#include "stb0899_drv.h"
23#include "stb0899_priv.h"
24#include "stb0899_reg.h"
25
26static inline u32 stb0899_do_div(u64 n, u32 d)
27{
28 /* wrap do_div() for ease of use */
29
30 do_div(n, d);
31 return n;
32}
33
34#if 0
35/* These functions are currently unused */
36/*
37 * stb0899_calc_srate
38 * Compute symbol rate
39 */
40static u32 stb0899_calc_srate(u32 master_clk, u8 *sfr)
41{
42 u64 tmp;
43
44 /* srate = (SFR * master_clk) >> 20 */
45
46 /* sfr is of size 20 bit, stored with an offset of 4 bit */
47 tmp = (((u32)sfr[0]) << 16) | (((u32)sfr[1]) << 8) | sfr[2];
48 tmp &= ~0xf;
49 tmp *= master_clk;
50 tmp >>= 24;
51
52 return tmp;
53}
54
55/*
56 * stb0899_get_srate
57 * Get the current symbol rate
58 */
59static u32 stb0899_get_srate(struct stb0899_state *state)
60{
61 struct stb0899_internal *internal = &state->internal;
62 u8 sfr[3];
63
64 stb0899_read_regs(state, STB0899_SFRH, sfr, 3);
65
66 return stb0899_calc_srate(internal->master_clk, sfr);
67}
68#endif
69
70/*
71 * stb0899_set_srate
72 * Set symbol frequency
73 * MasterClock: master clock frequency (hz)
74 * SymbolRate: symbol rate (bauds)
75 * return symbol frequency
76 */
77static u32 stb0899_set_srate(struct stb0899_state *state, u32 master_clk, u32 srate)
78{
79 u32 tmp;
80 u8 sfr[3];
81
82 dprintk(state->verbose, FE_DEBUG, 1, "-->");
83 /*
84 * in order to have the maximum precision, the symbol rate entered into
85 * the chip is computed as the closest value of the "true value".
86 * In this purpose, the symbol rate value is rounded (1 is added on the bit
87 * below the LSB )
88 *
89 * srate = (SFR * master_clk) >> 20
90 * <=>
91 * SFR = srate << 20 / master_clk
92 *
93 * rounded:
94 * SFR = (srate << 21 + master_clk) / (2 * master_clk)
95 *
96 * stored as 20 bit number with an offset of 4 bit:
97 * sfr = SFR << 4;
98 */
99
100 tmp = stb0899_do_div((((u64)srate) << 21) + master_clk, 2 * master_clk);
101 tmp <<= 4;
102
103 sfr[0] = tmp >> 16;
104 sfr[1] = tmp >> 8;
105 sfr[2] = tmp;
106
107 stb0899_write_regs(state, STB0899_SFRH, sfr, 3);
108
109 return srate;
110}
111
112/*
113 * stb0899_calc_derot_time
114 * Compute the amount of time needed by the derotator to lock
115 * SymbolRate: Symbol rate
116 * return: derotator time constant (ms)
117 */
118static long stb0899_calc_derot_time(long srate)
119{
120 if (srate > 0)
121 return (100000 / (srate / 1000));
122 else
123 return 0;
124}
125
126/*
127 * stb0899_carr_width
128 * Compute the width of the carrier
129 * return: width of carrier (kHz or Mhz)
130 */
131long stb0899_carr_width(struct stb0899_state *state)
132{
133 struct stb0899_internal *internal = &state->internal;
134
135 return (internal->srate + (internal->srate * internal->rolloff) / 100);
136}
137
138/*
139 * stb0899_first_subrange
140 * Compute the first subrange of the search
141 */
142static void stb0899_first_subrange(struct stb0899_state *state)
143{
144 struct stb0899_internal *internal = &state->internal;
145 struct stb0899_params *params = &state->params;
146 struct stb0899_config *config = state->config;
147
148 int range = 0;
149 u32 bandwidth = 0;
150
151 if (config->tuner_get_bandwidth) {
152 stb0899_i2c_gate_ctrl(&state->frontend, 1);
153 config->tuner_get_bandwidth(&state->frontend, &bandwidth);
154 stb0899_i2c_gate_ctrl(&state->frontend, 0);
155 range = bandwidth - stb0899_carr_width(state) / 2;
156 }
157
158 if (range > 0)
159 internal->sub_range = min(internal->srch_range, range);
160 else
161 internal->sub_range = 0;
162
163 internal->freq = params->freq;
164 internal->tuner_offst = 0L;
165 internal->sub_dir = 1;
166}
167
168/*
169 * stb0899_check_tmg
170 * check for timing lock
171 * internal.Ttiming: time to wait for loop lock
172 */
173static enum stb0899_status stb0899_check_tmg(struct stb0899_state *state)
174{
175 struct stb0899_internal *internal = &state->internal;
176 int lock;
177 u8 reg;
178 s8 timing;
179
180 msleep(internal->t_derot);
181
182 stb0899_write_reg(state, STB0899_RTF, 0xf2);
183 reg = stb0899_read_reg(state, STB0899_TLIR);
184 lock = STB0899_GETFIELD(TLIR_TMG_LOCK_IND, reg);
185 timing = stb0899_read_reg(state, STB0899_RTF);
186
187 if (lock >= 42) {
188 if ((lock > 48) && (abs(timing) >= 110)) {
189 internal->status = ANALOGCARRIER;
190 dprintk(state->verbose, FE_DEBUG, 1, "-->ANALOG Carrier !");
191 } else {
192 internal->status = TIMINGOK;
193 dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK !");
194 }
195 } else {
196 internal->status = NOTIMING;
197 dprintk(state->verbose, FE_DEBUG, 1, "-->NO TIMING !");
198 }
199 return internal->status;
200}
201
202/*
203 * stb0899_search_tmg
204 * perform a fs/2 zig-zag to find timing
205 */
206static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state)
207{
208 struct stb0899_internal *internal = &state->internal;
209 struct stb0899_params *params = &state->params;
210
211 short int derot_step, derot_freq = 0, derot_limit, next_loop = 3;
212 int index = 0;
213 u8 cfr[2];
214
215 internal->status = NOTIMING;
216
217 /* timing loop computation & symbol rate optimisation */
218 derot_limit = (internal->sub_range / 2L) / internal->mclk;
219 derot_step = (params->srate / 2L) / internal->mclk;
220
221 while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) {
222 index++;
223 derot_freq += index * internal->direction * derot_step; /* next derot zig zag position */
224
225 if (abs(derot_freq) > derot_limit)
226 next_loop--;
227
228 if (next_loop) {
229 STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
230 STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
231 stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
232 }
233 internal->direction = -internal->direction; /* Change zigzag direction */
234 }
235
236 if (internal->status == TIMINGOK) {
237 stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
238 internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
239 dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK ! Derot Freq = %d", internal->derot_freq);
240 }
241
242 return internal->status;
243}
244
245/*
246 * stb0899_check_carrier
247 * Check for carrier found
248 */
249static enum stb0899_status stb0899_check_carrier(struct stb0899_state *state)
250{
251 struct stb0899_internal *internal = &state->internal;
252 u8 reg;
253
254 msleep(internal->t_derot); /* wait for derotator ok */
255
256 reg = stb0899_read_reg(state, STB0899_CFD);
257 STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
258 stb0899_write_reg(state, STB0899_CFD, reg);
259
260 reg = stb0899_read_reg(state, STB0899_DSTATUS);
261 dprintk(state->verbose, FE_DEBUG, 1, "--------------------> STB0899_DSTATUS=[0x%02x]", reg);
262 if (STB0899_GETFIELD(CARRIER_FOUND, reg)) {
263 internal->status = CARRIEROK;
264 dprintk(state->verbose, FE_DEBUG, 1, "-------------> CARRIEROK !");
265 } else {
266 internal->status = NOCARRIER;
267 dprintk(state->verbose, FE_DEBUG, 1, "-------------> NOCARRIER !");
268 }
269
270 return internal->status;
271}
272
273/*
274 * stb0899_search_carrier
275 * Search for a QPSK carrier with the derotator
276 */
277static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state)
278{
279 struct stb0899_internal *internal = &state->internal;
280
281 short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3;
282 int index = 0;
283 u8 cfr[2];
284 u8 reg;
285
286 internal->status = NOCARRIER;
287 derot_limit = (internal->sub_range / 2L) / internal->mclk;
288 derot_freq = internal->derot_freq;
289
290 reg = stb0899_read_reg(state, STB0899_CFD);
291 STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
292 stb0899_write_reg(state, STB0899_CFD, reg);
293
294 do {
295 dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk);
296 if (stb0899_check_carrier(state) == NOCARRIER) {
297 index++;
298 last_derot_freq = derot_freq;
299 derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */
300
301 if(abs(derot_freq) > derot_limit)
302 next_loop--;
303
304 if (next_loop) {
305 reg = stb0899_read_reg(state, STB0899_CFD);
306 STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
307 stb0899_write_reg(state, STB0899_CFD, reg);
308
309 STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
310 STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
311 stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
312 }
313 }
314
315 internal->direction = -internal->direction; /* Change zigzag direction */
316 } while ((internal->status != CARRIEROK) && next_loop);
317
318 if (internal->status == CARRIEROK) {
319 stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
320 internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
321 dprintk(state->verbose, FE_DEBUG, 1, "----> CARRIER OK !, Derot Freq=%d", internal->derot_freq);
322 } else {
323 internal->derot_freq = last_derot_freq;
324 }
325
326 return internal->status;
327}
328
329/*
330 * stb0899_check_data
331 * Check for data found
332 */
333static enum stb0899_status stb0899_check_data(struct stb0899_state *state)
334{
335 struct stb0899_internal *internal = &state->internal;
336 struct stb0899_params *params = &state->params;
337
338 int lock = 0, index = 0, dataTime = 500, loop;
339 u8 reg;
340
341 internal->status = NODATA;
342
343 /* RESET FEC */
344 reg = stb0899_read_reg(state, STB0899_TSTRES);
345 STB0899_SETFIELD_VAL(FRESACS, reg, 1);
346 stb0899_write_reg(state, STB0899_TSTRES, reg);
347 msleep(1);
348 reg = stb0899_read_reg(state, STB0899_TSTRES);
349 STB0899_SETFIELD_VAL(FRESACS, reg, 0);
350 stb0899_write_reg(state, STB0899_TSTRES, reg);
351
352 if (params->srate <= 2000000)
353 dataTime = 2000;
354 else if (params->srate <= 5000000)
355 dataTime = 1500;
356 else if (params->srate <= 15000000)
357 dataTime = 1000;
358 else
359 dataTime = 500;
360
361 stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop */
362 while (1) {
363 /* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP */
364 reg = stb0899_read_reg(state, STB0899_VSTATUS);
365 lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg);
366 loop = STB0899_GETFIELD(VSTATUS_END_LOOPVIT, reg);
367
368 if (lock || loop || (index > dataTime))
369 break;
370 index++;
371 }
372
373 if (lock) { /* DATA LOCK indicator */
374 internal->status = DATAOK;
375 dprintk(state->verbose, FE_DEBUG, 1, "-----------------> DATA OK !");
376 }
377
378 return internal->status;
379}
380
381/*
382 * stb0899_search_data
383 * Search for a QPSK carrier with the derotator
384 */
385static enum stb0899_status stb0899_search_data(struct stb0899_state *state)
386{
387 short int derot_freq, derot_step, derot_limit, next_loop = 3;
388 u8 cfr[2];
389 u8 reg;
390 int index = 1;
391
392 struct stb0899_internal *internal = &state->internal;
393 struct stb0899_params *params = &state->params;
394
395 derot_step = (params->srate / 4L) / internal->mclk;
396 derot_limit = (internal->sub_range / 2L) / internal->mclk;
397 derot_freq = internal->derot_freq;
398
399 do {
400 if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) {
401
402 derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */
403 if (abs(derot_freq) > derot_limit)
404 next_loop--;
405
406 if (next_loop) {
407 dprintk(state->verbose, FE_DEBUG, 1, "Derot freq=%d, mclk=%d", derot_freq, internal->mclk);
408 reg = stb0899_read_reg(state, STB0899_CFD);
409 STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
410 stb0899_write_reg(state, STB0899_CFD, reg);
411
412 STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq));
413 STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq));
414 stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */
415
416 stb0899_check_carrier(state);
417 index++;
418 }
419 }
420 internal->direction = -internal->direction; /* change zig zag direction */
421 } while ((internal->status != DATAOK) && next_loop);
422
423 if (internal->status == DATAOK) {
424 stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */
425 internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]);
426 dprintk(state->verbose, FE_DEBUG, 1, "------> DATAOK ! Derot Freq=%d", internal->derot_freq);
427 }
428
429 return internal->status;
430}
431
432/*
433 * stb0899_check_range
434 * check if the found frequency is in the correct range
435 */
436static enum stb0899_status stb0899_check_range(struct stb0899_state *state)
437{
438 struct stb0899_internal *internal = &state->internal;
439 struct stb0899_params *params = &state->params;
440
441 int range_offst, tp_freq;
442
443 range_offst = internal->srch_range / 2000;
444 tp_freq = internal->freq + (internal->derot_freq * internal->mclk) / 1000;
445
446 if ((tp_freq >= params->freq - range_offst) && (tp_freq <= params->freq + range_offst)) {
447 internal->status = RANGEOK;
448 dprintk(state->verbose, FE_DEBUG, 1, "----> RANGEOK !");
449 } else {
450 internal->status = OUTOFRANGE;
451 dprintk(state->verbose, FE_DEBUG, 1, "----> OUT OF RANGE !");
452 }
453
454 return internal->status;
455}
456
457/*
458 * NextSubRange
459 * Compute the next subrange of the search
460 */
461static void next_sub_range(struct stb0899_state *state)
462{
463 struct stb0899_internal *internal = &state->internal;
464 struct stb0899_params *params = &state->params;
465
466 long old_sub_range;
467
468 if (internal->sub_dir > 0) {
469 old_sub_range = internal->sub_range;
470 internal->sub_range = min((internal->srch_range / 2) -
471 (internal->tuner_offst + internal->sub_range / 2),
472 internal->sub_range);
473
474 if (internal->sub_range < 0)
475 internal->sub_range = 0;
476
477 internal->tuner_offst += (old_sub_range + internal->sub_range) / 2;
478 }
479
480 internal->freq = params->freq + (internal->sub_dir * internal->tuner_offst) / 1000;
481 internal->sub_dir = -internal->sub_dir;
482}
483
484/*
485 * stb0899_dvbs_algo
486 * Search for a signal, timing, carrier and data for a
487 * given frequency in a given range
488 */
489enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state)
490{
491 struct stb0899_params *params = &state->params;
492 struct stb0899_internal *internal = &state->internal;
493 struct stb0899_config *config = state->config;
494
495 u8 bclc, reg;
496 u8 cfr[2];
497 u8 eq_const[10];
498 s32 clnI = 3;
499 u32 bandwidth = 0;
500
501 /* BETA values rated @ 99MHz */
502 s32 betaTab[5][4] = {
503 /* 5 10 20 30MBps */
504 { 37, 34, 32, 31 }, /* QPSK 1/2 */
505 { 37, 35, 33, 31 }, /* QPSK 2/3 */
506 { 37, 35, 33, 31 }, /* QPSK 3/4 */
507 { 37, 36, 33, 32 }, /* QPSK 5/6 */
508 { 37, 36, 33, 32 } /* QPSK 7/8 */
509 };
510
511 internal->direction = 1;
512
513 stb0899_set_srate(state, internal->master_clk, params->srate);
514 /* Carrier loop optimization versus symbol rate for acquisition*/
515 if (params->srate <= 5000000) {
516 stb0899_write_reg(state, STB0899_ACLC, 0x89);
517 bclc = stb0899_read_reg(state, STB0899_BCLC);
518 STB0899_SETFIELD_VAL(BETA, bclc, 0x1c);
519 stb0899_write_reg(state, STB0899_BCLC, bclc);
520 clnI = 0;
521 } else if (params->srate <= 15000000) {
522 stb0899_write_reg(state, STB0899_ACLC, 0xc9);
523 bclc = stb0899_read_reg(state, STB0899_BCLC);
524 STB0899_SETFIELD_VAL(BETA, bclc, 0x22);
525 stb0899_write_reg(state, STB0899_BCLC, bclc);
526 clnI = 1;
527 } else if(params->srate <= 25000000) {
528 stb0899_write_reg(state, STB0899_ACLC, 0x89);
529 bclc = stb0899_read_reg(state, STB0899_BCLC);
530 STB0899_SETFIELD_VAL(BETA, bclc, 0x27);
531 stb0899_write_reg(state, STB0899_BCLC, bclc);
532 clnI = 2;
533 } else {
534 stb0899_write_reg(state, STB0899_ACLC, 0xc8);
535 bclc = stb0899_read_reg(state, STB0899_BCLC);
536 STB0899_SETFIELD_VAL(BETA, bclc, 0x29);
537 stb0899_write_reg(state, STB0899_BCLC, bclc);
538 clnI = 3;
539 }
540
541 dprintk(state->verbose, FE_DEBUG, 1, "Set the timing loop to acquisition");
542 /* Set the timing loop to acquisition */
543 stb0899_write_reg(state, STB0899_RTC, 0x46);
544 stb0899_write_reg(state, STB0899_CFD, 0xee);
545
546 /* !! WARNING !!
547 * Do not read any status variables while acquisition,
548 * If any needed, read before the acquisition starts
549 * querying status while acquiring causes the
550 * acquisition to go bad and hence no locks.
551 */
552 dprintk(state->verbose, FE_DEBUG, 1, "Derot Percent=%d Srate=%d mclk=%d",
553 internal->derot_percent, params->srate, internal->mclk);
554
555 /* Initial calculations */
556 internal->derot_step = internal->derot_percent * (params->srate / 1000L) / internal->mclk; /* DerotStep/1000 * Fsymbol */
557 internal->t_derot = stb0899_calc_derot_time(params->srate);
558 internal->t_data = 500;
559
560 dprintk(state->verbose, FE_DEBUG, 1, "RESET stream merger");
561 /* RESET Stream merger */
562 reg = stb0899_read_reg(state, STB0899_TSTRES);
563 STB0899_SETFIELD_VAL(FRESRS, reg, 1);
564 stb0899_write_reg(state, STB0899_TSTRES, reg);
565
566 /*
567 * Set KDIVIDER to an intermediate value between
568 * 1/2 and 7/8 for acquisition
569 */
570 reg = stb0899_read_reg(state, STB0899_DEMAPVIT);
571 STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 60);
572 stb0899_write_reg(state, STB0899_DEMAPVIT, reg);
573
574 stb0899_write_reg(state, STB0899_EQON, 0x01); /* Equalizer OFF while acquiring */
575 stb0899_write_reg(state, STB0899_VITSYNC, 0x19);
576
577 stb0899_first_subrange(state);
578 do {
579 /* Initialisations */
580 cfr[0] = cfr[1] = 0;
581 stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* RESET derotator frequency */
582
583 stb0899_write_reg(state, STB0899_RTF, 0);
584 reg = stb0899_read_reg(state, STB0899_CFD);
585 STB0899_SETFIELD_VAL(CFD_ON, reg, 1);
586 stb0899_write_reg(state, STB0899_CFD, reg);
587
588 internal->derot_freq = 0;
589 internal->status = NOAGC1;
590
591 /* enable tuner I/O */
592 stb0899_i2c_gate_ctrl(&state->frontend, 1);
593
594 /* Move tuner to frequency */
595 dprintk(state->verbose, FE_DEBUG, 1, "Tuner set frequency");
596 if (state->config->tuner_set_frequency)
597 state->config->tuner_set_frequency(&state->frontend, internal->freq);
598
599 if (state->config->tuner_get_frequency)
600 state->config->tuner_get_frequency(&state->frontend, &internal->freq);
601
602 msleep(internal->t_agc1 + internal->t_agc2 + internal->t_derot); /* AGC1, AGC2 and timing loop */
603 dprintk(state->verbose, FE_DEBUG, 1, "current derot freq=%d", internal->derot_freq);
604 internal->status = AGC1OK;
605
606 /* There is signal in the band */
607 if (config->tuner_get_bandwidth)
608 config->tuner_get_bandwidth(&state->frontend, &bandwidth);
609
610 /* disable tuner I/O */
611 stb0899_i2c_gate_ctrl(&state->frontend, 0);
612
613 if (params->srate <= bandwidth / 2)
614 stb0899_search_tmg(state); /* For low rates (SCPC) */
615 else
616 stb0899_check_tmg(state); /* For high rates (MCPC) */
617
618 if (internal->status == TIMINGOK) {
619 dprintk(state->verbose, FE_DEBUG, 1,
620 "TIMING OK ! Derot freq=%d, mclk=%d",
621 internal->derot_freq, internal->mclk);
622
623 if (stb0899_search_carrier(state) == CARRIEROK) { /* Search for carrier */
624 dprintk(state->verbose, FE_DEBUG, 1,
625 "CARRIER OK ! Derot freq=%d, mclk=%d",
626 internal->derot_freq, internal->mclk);
627
628 if (stb0899_search_data(state) == DATAOK) { /* Check for data */
629 dprintk(state->verbose, FE_DEBUG, 1,
630 "DATA OK ! Derot freq=%d, mclk=%d",
631 internal->derot_freq, internal->mclk);
632
633 if (stb0899_check_range(state) == RANGEOK) {
634 dprintk(state->verbose, FE_DEBUG, 1,
635 "RANGE OK ! derot freq=%d, mclk=%d",
636 internal->derot_freq, internal->mclk);
637
638 internal->freq = params->freq + ((internal->derot_freq * internal->mclk) / 1000);
639 reg = stb0899_read_reg(state, STB0899_PLPARM);
640 internal->fecrate = STB0899_GETFIELD(VITCURPUN, reg);
641 dprintk(state->verbose, FE_DEBUG, 1,
642 "freq=%d, internal resultant freq=%d",
643 params->freq, internal->freq);
644
645 dprintk(state->verbose, FE_DEBUG, 1,
646 "internal puncture rate=%d",
647 internal->fecrate);
648 }
649 }
650 }
651 }
652 if (internal->status != RANGEOK)
653 next_sub_range(state);
654
655 } while (internal->sub_range && internal->status != RANGEOK);
656
657 /* Set the timing loop to tracking */
658 stb0899_write_reg(state, STB0899_RTC, 0x33);
659 stb0899_write_reg(state, STB0899_CFD, 0xf7);
660 /* if locked and range ok, set Kdiv */
661 if (internal->status == RANGEOK) {
662 dprintk(state->verbose, FE_DEBUG, 1, "Locked & Range OK !");
663 stb0899_write_reg(state, STB0899_EQON, 0x41); /* Equalizer OFF while acquiring */
664 stb0899_write_reg(state, STB0899_VITSYNC, 0x39); /* SN to b'11 for acquisition */
665
666 /*
667 * Carrier loop optimization versus
668 * symbol Rate/Puncture Rate for Tracking
669 */
670 reg = stb0899_read_reg(state, STB0899_BCLC);
671 switch (internal->fecrate) {
672 case STB0899_FEC_1_2: /* 13 */
673 stb0899_write_reg(state, STB0899_DEMAPVIT, 0x1a);
674 STB0899_SETFIELD_VAL(BETA, reg, betaTab[0][clnI]);
675 stb0899_write_reg(state, STB0899_BCLC, reg);
676 break;
677 case STB0899_FEC_2_3: /* 18 */
678 stb0899_write_reg(state, STB0899_DEMAPVIT, 44);
679 STB0899_SETFIELD_VAL(BETA, reg, betaTab[1][clnI]);
680 stb0899_write_reg(state, STB0899_BCLC, reg);
681 break;
682 case STB0899_FEC_3_4: /* 21 */
683 stb0899_write_reg(state, STB0899_DEMAPVIT, 60);
684 STB0899_SETFIELD_VAL(BETA, reg, betaTab[2][clnI]);
685 stb0899_write_reg(state, STB0899_BCLC, reg);
686 break;
687 case STB0899_FEC_5_6: /* 24 */
688 stb0899_write_reg(state, STB0899_DEMAPVIT, 75);
689 STB0899_SETFIELD_VAL(BETA, reg, betaTab[3][clnI]);
690 stb0899_write_reg(state, STB0899_BCLC, reg);
691 break;
692 case STB0899_FEC_6_7: /* 25 */
693 stb0899_write_reg(state, STB0899_DEMAPVIT, 88);
694 stb0899_write_reg(state, STB0899_ACLC, 0x88);
695 stb0899_write_reg(state, STB0899_BCLC, 0x9a);
696 break;
697 case STB0899_FEC_7_8: /* 26 */
698 stb0899_write_reg(state, STB0899_DEMAPVIT, 94);
699 STB0899_SETFIELD_VAL(BETA, reg, betaTab[4][clnI]);
700 stb0899_write_reg(state, STB0899_BCLC, reg);
701 break;
702 default:
703 dprintk(state->verbose, FE_DEBUG, 1, "Unsupported Puncture Rate");
704 break;
705 }
706 /* release stream merger RESET */
707 reg = stb0899_read_reg(state, STB0899_TSTRES);
708 STB0899_SETFIELD_VAL(FRESRS, reg, 0);
709 stb0899_write_reg(state, STB0899_TSTRES, reg);
710
711 /* disable carrier detector */
712 reg = stb0899_read_reg(state, STB0899_CFD);
713 STB0899_SETFIELD_VAL(CFD_ON, reg, 0);
714 stb0899_write_reg(state, STB0899_CFD, reg);
715
716 stb0899_read_regs(state, STB0899_EQUAI1, eq_const, 10);
717 }
718
719 return internal->status;
720}
721
722/*
723 * stb0899_dvbs2_config_uwp
724 * Configure UWP state machine
725 */
726static void stb0899_dvbs2_config_uwp(struct stb0899_state *state)
727{
728 struct stb0899_internal *internal = &state->internal;
729 struct stb0899_config *config = state->config;
730 u32 uwp1, uwp2, uwp3, reg;
731
732 uwp1 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1);
733 uwp2 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL2);
734 uwp3 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL3);
735
736 STB0899_SETFIELD_VAL(UWP_ESN0_AVE, uwp1, config->esno_ave);
737 STB0899_SETFIELD_VAL(UWP_ESN0_QUANT, uwp1, config->esno_quant);
738 STB0899_SETFIELD_VAL(UWP_TH_SOF, uwp1, config->uwp_threshold_sof);
739
740 STB0899_SETFIELD_VAL(FE_COARSE_TRK, uwp2, internal->av_frame_coarse);
741 STB0899_SETFIELD_VAL(FE_FINE_TRK, uwp2, internal->av_frame_fine);
742 STB0899_SETFIELD_VAL(UWP_MISS_TH, uwp2, config->miss_threshold);
743
744 STB0899_SETFIELD_VAL(UWP_TH_ACQ, uwp3, config->uwp_threshold_acq);
745 STB0899_SETFIELD_VAL(UWP_TH_TRACK, uwp3, config->uwp_threshold_track);
746
747 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL1, STB0899_OFF0_UWP_CNTRL1, uwp1);
748 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL2, STB0899_OFF0_UWP_CNTRL2, uwp2);
749 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL3, STB0899_OFF0_UWP_CNTRL3, uwp3);
750
751 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, SOF_SRCH_TO);
752 STB0899_SETFIELD_VAL(SOF_SEARCH_TIMEOUT, reg, config->sof_search_timeout);
753 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_SOF_SRCH_TO, STB0899_OFF0_SOF_SRCH_TO, reg);
754}
755
756/*
757 * stb0899_dvbs2_config_csm_auto
758 * Set CSM to AUTO mode
759 */
760static void stb0899_dvbs2_config_csm_auto(struct stb0899_state *state)
761{
762 u32 reg;
763
764 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
765 STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, reg, 1);
766 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, reg);
767}
768
769static long Log2Int(int number)
770{
771 int i;
772
773 i = 0;
774 while ((1 << i) <= abs(number))
775 i++;
776
777 if (number == 0)
778 i = 1;
779
780 return i - 1;
781}
782
783/*
784 * stb0899_dvbs2_calc_srate
785 * compute BTR_NOM_FREQ for the symbol rate
786 */
787static u32 stb0899_dvbs2_calc_srate(struct stb0899_state *state)
788{
789 struct stb0899_internal *internal = &state->internal;
790 struct stb0899_config *config = state->config;
791
792 u32 dec_ratio, dec_rate, decim, remain, intval, btr_nom_freq;
793 u32 master_clk, srate;
794
795 dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
796 dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
797 dec_rate = Log2Int(dec_ratio);
798 decim = 1 << dec_rate;
799 master_clk = internal->master_clk / 1000;
800 srate = internal->srate / 1000;
801
802 if (decim <= 4) {
803 intval = (decim * (1 << (config->btr_nco_bits - 1))) / master_clk;
804 remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk;
805 } else {
806 intval = (1 << (config->btr_nco_bits - 1)) / (master_clk / 100) * decim / 100;
807 remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk;
808 }
809 btr_nom_freq = (intval * srate) + ((remain * srate) / master_clk);
810
811 return btr_nom_freq;
812}
813
814/*
815 * stb0899_dvbs2_calc_dev
816 * compute the correction to be applied to symbol rate
817 */
818static u32 stb0899_dvbs2_calc_dev(struct stb0899_state *state)
819{
820 struct stb0899_internal *internal = &state->internal;
821 u32 dec_ratio, correction, master_clk, srate;
822
823 dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
824 dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
825
826 master_clk = internal->master_clk / 1000; /* for integer Caculation*/
827 srate = internal->srate / 1000; /* for integer Caculation*/
828 correction = (512 * master_clk) / (2 * dec_ratio * srate);
829
830 return correction;
831}
832
833/*
834 * stb0899_dvbs2_set_srate
835 * Set DVBS2 symbol rate
836 */
837static void stb0899_dvbs2_set_srate(struct stb0899_state *state)
838{
839 struct stb0899_internal *internal = &state->internal;
840
841 u32 dec_ratio, dec_rate, win_sel, decim, f_sym, btr_nom_freq;
842 u32 correction, freq_adj, band_lim, decim_cntrl, reg;
843 u8 anti_alias;
844
845 /*set decimation to 1*/
846 dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
847 dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
848 dec_rate = Log2Int(dec_ratio);
849
850 win_sel = 0;
851 if (dec_rate >= 5)
852 win_sel = dec_rate - 4;
853
854 decim = (1 << dec_rate);
855 /* (FSamp/Fsymbol *100) for integer Caculation */
856 f_sym = internal->master_clk / ((decim * internal->srate) / 1000);
857
858 if (f_sym <= 2250) /* don't band limit signal going into btr block*/
859 band_lim = 1;
860 else
861 band_lim = 0; /* band limit signal going into btr block*/
862
863 decim_cntrl = ((win_sel << 3) & 0x18) + ((band_lim << 5) & 0x20) + (dec_rate & 0x7);
864 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DECIM_CNTRL, STB0899_OFF0_DECIM_CNTRL, decim_cntrl);
865
866 if (f_sym <= 3450)
867 anti_alias = 0;
868 else if (f_sym <= 4250)
869 anti_alias = 1;
870 else
871 anti_alias = 2;
872
873 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ANTI_ALIAS_SEL, STB0899_OFF0_ANTI_ALIAS_SEL, anti_alias);
874 btr_nom_freq = stb0899_dvbs2_calc_srate(state);
875 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_NOM_FREQ, STB0899_OFF0_BTR_NOM_FREQ, btr_nom_freq);
876
877 correction = stb0899_dvbs2_calc_dev(state);
878 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL);
879 STB0899_SETFIELD_VAL(BTR_FREQ_CORR, reg, correction);
880 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg);
881
882 /* scale UWP+CSM frequency to sample rate*/
883 freq_adj = internal->srate / (internal->master_clk / 4096);
884 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_FREQ_ADJ_SCALE, STB0899_OFF0_FREQ_ADJ_SCALE, freq_adj);
885}
886
887/*
888 * stb0899_dvbs2_set_btr_loopbw
889 * set bit timing loop bandwidth as a percentage of the symbol rate
890 */
891static void stb0899_dvbs2_set_btr_loopbw(struct stb0899_state *state)
892{
893 struct stb0899_internal *internal = &state->internal;
894 struct stb0899_config *config = state->config;
895
896 u32 sym_peak = 23, zeta = 707, loopbw_percent = 60;
897 s32 dec_ratio, dec_rate, k_btr1_rshft, k_btr1, k_btr0_rshft;
898 s32 k_btr0, k_btr2_rshft, k_direct_shift, k_indirect_shift;
899 u32 decim, K, wn, k_direct, k_indirect;
900 u32 reg;
901
902 dec_ratio = (internal->master_clk * 2) / (5 * internal->srate);
903 dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio;
904 dec_rate = Log2Int(dec_ratio);
905 decim = (1 << dec_rate);
906
907 sym_peak *= 576000;
908 K = (1 << config->btr_nco_bits) / (internal->master_clk / 1000);
909 K *= (internal->srate / 1000000) * decim; /*k=k 10^-8*/
910
911 if (K != 0) {
912 K = sym_peak / K;
913 wn = (4 * zeta * zeta) + 1000000;
914 wn = (2 * (loopbw_percent * 1000) * 40 * zeta) /wn; /*wn =wn 10^-8*/
915
916 k_indirect = (wn * wn) / K;
917 k_indirect = k_indirect; /*kindirect = kindirect 10^-6*/
918 k_direct = (2 * wn * zeta) / K; /*kDirect = kDirect 10^-2*/
919 k_direct *= 100;
920
921 k_direct_shift = Log2Int(k_direct) - Log2Int(10000) - 2;
922 k_btr1_rshft = (-1 * k_direct_shift) + config->btr_gain_shift_offset;
923 k_btr1 = k_direct / (1 << k_direct_shift);
924 k_btr1 /= 10000;
925
926 k_indirect_shift = Log2Int(k_indirect + 15) - 20 /*- 2*/;
927 k_btr0_rshft = (-1 * k_indirect_shift) + config->btr_gain_shift_offset;
928 k_btr0 = k_indirect * (1 << (-k_indirect_shift));
929 k_btr0 /= 1000000;
930
931 k_btr2_rshft = 0;
932 if (k_btr0_rshft > 15) {
933 k_btr2_rshft = k_btr0_rshft - 15;
934 k_btr0_rshft = 15;
935 }
936 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_LOOP_GAIN);
937 STB0899_SETFIELD_VAL(KBTR0_RSHFT, reg, k_btr0_rshft);
938 STB0899_SETFIELD_VAL(KBTR0, reg, k_btr0);
939 STB0899_SETFIELD_VAL(KBTR1_RSHFT, reg, k_btr1_rshft);
940 STB0899_SETFIELD_VAL(KBTR1, reg, k_btr1);
941 STB0899_SETFIELD_VAL(KBTR2_RSHFT, reg, k_btr2_rshft);
942 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, reg);
943 } else
944 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, 0xc4c4f);
945}
946
947/*
948 * stb0899_dvbs2_set_carr_freq
949 * set nominal frequency for carrier search
950 */
951static void stb0899_dvbs2_set_carr_freq(struct stb0899_state *state, s32 carr_freq, u32 master_clk)
952{
953 struct stb0899_config *config = state->config;
954 s32 crl_nom_freq;
955 u32 reg;
956
957 crl_nom_freq = (1 << config->crl_nco_bits) / master_clk;
958 crl_nom_freq *= carr_freq;
959 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
960 STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, crl_nom_freq);
961 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
962}
963
964/*
965 * stb0899_dvbs2_init_calc
966 * Initialize DVBS2 UWP, CSM, carrier and timing loops
967 */
968static void stb0899_dvbs2_init_calc(struct stb0899_state *state)
969{
970 struct stb0899_internal *internal = &state->internal;
971 s32 steps, step_size;
972 u32 range, reg;
973
974 /* config uwp and csm */
975 stb0899_dvbs2_config_uwp(state);
976 stb0899_dvbs2_config_csm_auto(state);
977
978 /* initialize BTR */
979 stb0899_dvbs2_set_srate(state);
980 stb0899_dvbs2_set_btr_loopbw(state);
981
982 if (internal->srate / 1000000 >= 15)
983 step_size = (1 << 17) / 5;
984 else if (internal->srate / 1000000 >= 10)
985 step_size = (1 << 17) / 7;
986 else if (internal->srate / 1000000 >= 5)
987 step_size = (1 << 17) / 10;
988 else
989 step_size = (1 << 17) / 4;
990
991 range = internal->srch_range / 1000000;
992 steps = (10 * range * (1 << 17)) / (step_size * (internal->srate / 1000000));
993 steps = (steps + 6) / 10;
994 steps = (steps == 0) ? 1 : steps;
995 if (steps % 2 == 0)
996 stb0899_dvbs2_set_carr_freq(state, internal->center_freq -
997 (internal->step_size * (internal->srate / 20000000)),
998 (internal->master_clk) / 1000000);
999 else
1000 stb0899_dvbs2_set_carr_freq(state, internal->center_freq, (internal->master_clk) / 1000000);
1001
1002 /*Set Carrier Search params (zigzag, num steps and freq step size*/
1003 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, ACQ_CNTRL2);
1004 STB0899_SETFIELD_VAL(ZIGZAG, reg, 1);
1005 STB0899_SETFIELD_VAL(NUM_STEPS, reg, steps);
1006 STB0899_SETFIELD_VAL(FREQ_STEPSIZE, reg, step_size);
1007 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQ_CNTRL2, STB0899_OFF0_ACQ_CNTRL2, reg);
1008}
1009
1010/*
1011 * stb0899_dvbs2_btr_init
1012 * initialize the timing loop
1013 */
1014static void stb0899_dvbs2_btr_init(struct stb0899_state *state)
1015{
1016 u32 reg;
1017
1018 /* set enable BTR loopback */
1019 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL);
1020 STB0899_SETFIELD_VAL(INTRP_PHS_SENSE, reg, 1);
1021 STB0899_SETFIELD_VAL(BTR_ERR_ENA, reg, 1);
1022 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg);
1023
1024 /* fix btr freq accum at 0 */
1025 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x10000000);
1026 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x00000000);
1027
1028 /* fix btr freq accum at 0 */
1029 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x10000000);
1030 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x00000000);
1031}
1032
1033/*
1034 * stb0899_dvbs2_reacquire
1035 * trigger a DVB-S2 acquisition
1036 */
1037static void stb0899_dvbs2_reacquire(struct stb0899_state *state)
1038{
1039 u32 reg = 0;
1040
1041 /* demod soft reset */
1042 STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 1);
1043 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg);
1044
1045 /*Reset Timing Loop */
1046 stb0899_dvbs2_btr_init(state);
1047
1048 /* reset Carrier loop */
1049 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, (1 << 30));
1050 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, 0);
1051 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_LOOP_GAIN, STB0899_OFF0_CRL_LOOP_GAIN, 0);
1052 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, (1 << 30));
1053 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, 0);
1054
1055 /*release demod soft reset */
1056 reg = 0;
1057 STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 0);
1058 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg);
1059
1060 /* start acquisition process */
1061 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQUIRE_TRIG, STB0899_OFF0_ACQUIRE_TRIG, 1);
1062 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_LOCK_LOST, STB0899_OFF0_LOCK_LOST, 0);
1063
1064 /* equalizer Init */
1065 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 1);
1066
1067 /*Start equilizer */
1068 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 0);
1069
1070 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
1071 STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0);
1072 STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 0);
1073 STB0899_SETFIELD_VAL(EQ_DELAY, reg, 0x05);
1074 STB0899_SETFIELD_VAL(EQ_ADAPT_MODE, reg, 0x01);
1075 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
1076
1077 /* RESET Packet delineator */
1078 stb0899_write_reg(state, STB0899_PDELCTRL, 0x4a);
1079}
1080
1081/*
1082 * stb0899_dvbs2_get_dmd_status
1083 * get DVB-S2 Demod LOCK status
1084 */
1085static enum stb0899_status stb0899_dvbs2_get_dmd_status(struct stb0899_state *state, int timeout)
1086{
1087 int time = -10, lock = 0, uwp, csm;
1088 u32 reg;
1089
1090 do {
1091 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STATUS);
1092 dprintk(state->verbose, FE_DEBUG, 1, "DMD_STATUS=[0x%02x]", reg);
1093 if (STB0899_GETFIELD(IF_AGC_LOCK, reg))
1094 dprintk(state->verbose, FE_DEBUG, 1, "------------->IF AGC LOCKED !");
1095 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2);
1096 dprintk(state->verbose, FE_DEBUG, 1, "----------->DMD STAT2=[0x%02x]", reg);
1097 uwp = STB0899_GETFIELD(UWP_LOCK, reg);
1098 csm = STB0899_GETFIELD(CSM_LOCK, reg);
1099 if (uwp && csm)
1100 lock = 1;
1101
1102 time += 10;
1103 msleep(10);
1104
1105 } while ((!lock) && (time <= timeout));
1106
1107 if (lock) {
1108 dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 LOCK !");
1109 return DVBS2_DEMOD_LOCK;
1110 } else {
1111 return DVBS2_DEMOD_NOLOCK;
1112 }
1113}
1114
1115/*
1116 * stb0899_dvbs2_get_data_lock
1117 * get FEC status
1118 */
1119static int stb0899_dvbs2_get_data_lock(struct stb0899_state *state, int timeout)
1120{
1121 int time = 0, lock = 0;
1122 u8 reg;
1123
1124 while ((!lock) && (time < timeout)) {
1125 reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1);
1126 dprintk(state->verbose, FE_DEBUG, 1, "---------> CFGPDELSTATUS=[0x%02x]", reg);
1127 lock = STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg);
1128 time++;
1129 }
1130
1131 return lock;
1132}
1133
1134/*
1135 * stb0899_dvbs2_get_fec_status
1136 * get DVB-S2 FEC LOCK status
1137 */
1138static enum stb0899_status stb0899_dvbs2_get_fec_status(struct stb0899_state *state, int timeout)
1139{
1140 int time = 0, Locked;
1141
1142 do {
1143 Locked = stb0899_dvbs2_get_data_lock(state, 1);
1144 time++;
1145 msleep(1);
1146
1147 } while ((!Locked) && (time < timeout));
1148
1149 if (Locked) {
1150 dprintk(state->verbose, FE_DEBUG, 1, "---------->DVB-S2 FEC LOCK !");
1151 return DVBS2_FEC_LOCK;
1152 } else {
1153 return DVBS2_FEC_NOLOCK;
1154 }
1155}
1156
1157
1158/*
1159 * stb0899_dvbs2_init_csm
1160 * set parameters for manual mode
1161 */
1162static void stb0899_dvbs2_init_csm(struct stb0899_state *state, int pilots, enum stb0899_modcod modcod)
1163{
1164 struct stb0899_internal *internal = &state->internal;
1165
1166 s32 dvt_tbl = 1, two_pass = 0, agc_gain = 6, agc_shift = 0, loop_shift = 0, phs_diff_thr = 0x80;
1167 s32 gamma_acq, gamma_rho_acq, gamma_trk, gamma_rho_trk, lock_count_thr;
1168 u32 csm1, csm2, csm3, csm4;
1169
1170 if (((internal->master_clk / internal->srate) <= 4) && (modcod <= 11) && (pilots == 1)) {
1171 switch (modcod) {
1172 case STB0899_QPSK_12:
1173 gamma_acq = 25;
1174 gamma_rho_acq = 2700;
1175 gamma_trk = 12;
1176 gamma_rho_trk = 180;
1177 lock_count_thr = 8;
1178 break;
1179 case STB0899_QPSK_35:
1180 gamma_acq = 38;
1181 gamma_rho_acq = 7182;
1182 gamma_trk = 14;
1183 gamma_rho_trk = 308;
1184 lock_count_thr = 8;
1185 break;
1186 case STB0899_QPSK_23:
1187 gamma_acq = 42;
1188 gamma_rho_acq = 9408;
1189 gamma_trk = 17;
1190 gamma_rho_trk = 476;
1191 lock_count_thr = 8;
1192 break;
1193 case STB0899_QPSK_34:
1194 gamma_acq = 53;
1195 gamma_rho_acq = 16642;
1196 gamma_trk = 19;
1197 gamma_rho_trk = 646;
1198 lock_count_thr = 8;
1199 break;
1200 case STB0899_QPSK_45:
1201 gamma_acq = 53;
1202 gamma_rho_acq = 17119;
1203 gamma_trk = 22;
1204 gamma_rho_trk = 880;
1205 lock_count_thr = 8;
1206 break;
1207 case STB0899_QPSK_56:
1208 gamma_acq = 55;
1209 gamma_rho_acq = 19250;
1210 gamma_trk = 23;
1211 gamma_rho_trk = 989;
1212 lock_count_thr = 8;
1213 break;
1214 case STB0899_QPSK_89:
1215 gamma_acq = 60;
1216 gamma_rho_acq = 24240;
1217 gamma_trk = 24;
1218 gamma_rho_trk = 1176;
1219 lock_count_thr = 8;
1220 break;
1221 case STB0899_QPSK_910:
1222 gamma_acq = 66;
1223 gamma_rho_acq = 29634;
1224 gamma_trk = 24;
1225 gamma_rho_trk = 1176;
1226 lock_count_thr = 8;
1227 break;
1228 default:
1229 gamma_acq = 66;
1230 gamma_rho_acq = 29634;
1231 gamma_trk = 24;
1232 gamma_rho_trk = 1176;
1233 lock_count_thr = 8;
1234 break;
1235 }
1236
1237 csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
1238 STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, csm1, 0);
1239 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
1240
1241 csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
1242 csm2 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL2);
1243 csm3 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL3);
1244 csm4 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL4);
1245
1246 STB0899_SETFIELD_VAL(CSM_DVT_TABLE, csm1, dvt_tbl);
1247 STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, two_pass);
1248 STB0899_SETFIELD_VAL(CSM_AGC_GAIN, csm1, agc_gain);
1249 STB0899_SETFIELD_VAL(CSM_AGC_SHIFT, csm1, agc_shift);
1250 STB0899_SETFIELD_VAL(FE_LOOP_SHIFT, csm1, loop_shift);
1251 STB0899_SETFIELD_VAL(CSM_GAMMA_ACQ, csm2, gamma_acq);
1252 STB0899_SETFIELD_VAL(CSM_GAMMA_RHOACQ, csm2, gamma_rho_acq);
1253 STB0899_SETFIELD_VAL(CSM_GAMMA_TRACK, csm3, gamma_trk);
1254 STB0899_SETFIELD_VAL(CSM_GAMMA_RHOTRACK, csm3, gamma_rho_trk);
1255 STB0899_SETFIELD_VAL(CSM_LOCKCOUNT_THRESH, csm4, lock_count_thr);
1256 STB0899_SETFIELD_VAL(CSM_PHASEDIFF_THRESH, csm4, phs_diff_thr);
1257
1258 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
1259 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL2, STB0899_OFF0_CSM_CNTRL2, csm2);
1260 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL3, STB0899_OFF0_CSM_CNTRL3, csm3);
1261 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL4, STB0899_OFF0_CSM_CNTRL4, csm4);
1262 }
1263}
1264
1265/*
1266 * stb0899_dvbs2_get_srate
1267 * get DVB-S2 Symbol Rate
1268 */
1269static u32 stb0899_dvbs2_get_srate(struct stb0899_state *state)
1270{
1271 struct stb0899_internal *internal = &state->internal;
1272 struct stb0899_config *config = state->config;
1273
1274 u32 bTrNomFreq, srate, decimRate, intval1, intval2, reg;
1275 int div1, div2, rem1, rem2;
1276
1277 div1 = config->btr_nco_bits / 2;
1278 div2 = config->btr_nco_bits - div1 - 1;
1279
1280 bTrNomFreq = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_NOM_FREQ);
1281
1282 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DECIM_CNTRL);
1283 decimRate = STB0899_GETFIELD(DECIM_RATE, reg);
1284 decimRate = (1 << decimRate);
1285
1286 intval1 = internal->master_clk / (1 << div1);
1287 intval2 = bTrNomFreq / (1 << div2);
1288
1289 rem1 = internal->master_clk % (1 << div1);
1290 rem2 = bTrNomFreq % (1 << div2);
1291 /* only for integer calculation */
1292 srate = (intval1 * intval2) + ((intval1 * rem2) / (1 << div2)) + ((intval2 * rem1) / (1 << div1));
1293 srate /= decimRate; /*symbrate = (btrnomfreq_register_val*MasterClock)/2^(27+decim_rate_field) */
1294
1295 return srate;
1296}
1297
1298/*
1299 * stb0899_dvbs2_algo
1300 * Search for signal, timing, carrier and data for a given
1301 * frequency in a given range
1302 */
1303enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state)
1304{
1305 struct stb0899_internal *internal = &state->internal;
1306 enum stb0899_modcod modcod;
1307
1308 s32 offsetfreq, searchTime, FecLockTime, pilots, iqSpectrum;
1309 int i = 0;
1310 u32 reg, csm1;
1311
1312 if (internal->srate <= 2000000) {
1313 searchTime = 5000; /* 5000 ms max time to lock UWP and CSM, SYMB <= 2Mbs */
1314 FecLockTime = 350; /* 350 ms max time to lock FEC, SYMB <= 2Mbs */
1315 } else if (internal->srate <= 5000000) {
1316 searchTime = 2500; /* 2500 ms max time to lock UWP and CSM, 2Mbs < SYMB <= 5Mbs */
1317 FecLockTime = 170; /* 170 ms max time to lock FEC, 2Mbs< SYMB <= 5Mbs */
1318 } else if (internal->srate <= 10000000) {
1319 searchTime = 1500; /* 1500 ms max time to lock UWP and CSM, 5Mbs <SYMB <= 10Mbs */
1320 FecLockTime = 80; /* 80 ms max time to lock FEC, 5Mbs< SYMB <= 10Mbs */
1321 } else if (internal->srate <= 15000000) {
1322 searchTime = 500; /* 500 ms max time to lock UWP and CSM, 10Mbs <SYMB <= 15Mbs */
1323 FecLockTime = 50; /* 50 ms max time to lock FEC, 10Mbs< SYMB <= 15Mbs */
1324 } else if (internal->srate <= 20000000) {
1325 searchTime = 300; /* 300 ms max time to lock UWP and CSM, 15Mbs < SYMB <= 20Mbs */
1326 FecLockTime = 30; /* 50 ms max time to lock FEC, 15Mbs< SYMB <= 20Mbs */
1327 } else if (internal->srate <= 25000000) {
1328 searchTime = 250; /* 250 ms max time to lock UWP and CSM, 20 Mbs < SYMB <= 25Mbs */
1329 FecLockTime = 25; /* 25 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs */
1330 } else {
1331 searchTime = 150; /* 150 ms max time to lock UWP and CSM, SYMB > 25Mbs */
1332 FecLockTime = 20; /* 20 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs */
1333 }
1334
1335 /* Maintain Stream Merger in reset during acquisition */
1336 reg = stb0899_read_reg(state, STB0899_TSTRES);
1337 STB0899_SETFIELD_VAL(FRESRS, reg, 1);
1338 stb0899_write_reg(state, STB0899_TSTRES, reg);
1339
1340 /* enable tuner I/O */
1341 stb0899_i2c_gate_ctrl(&state->frontend, 1);
1342
1343 /* Move tuner to frequency */
1344 if (state->config->tuner_set_frequency)
1345 state->config->tuner_set_frequency(&state->frontend, internal->freq);
1346 if (state->config->tuner_get_frequency)
1347 state->config->tuner_get_frequency(&state->frontend, &internal->freq);
1348
1349 /* disable tuner I/O */
1350 stb0899_i2c_gate_ctrl(&state->frontend, 0);
1351
1352 /* Set IF AGC to acquisition */
1353 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
1354 STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg, 4);
1355 STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 32);
1356 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
1357
1358 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2);
1359 STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 0);
1360 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
1361
1362 /* Initialisation */
1363 stb0899_dvbs2_init_calc(state);
1364
1365 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
1366 switch (internal->inversion) {
1367 case IQ_SWAP_OFF:
1368 STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 0);
1369 break;
1370 case IQ_SWAP_ON:
1371 STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
1372 break;
1373 case IQ_SWAP_AUTO: /* use last successful search first */
1374 STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1);
1375 break;
1376 }
1377 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
1378 stb0899_dvbs2_reacquire(state);
1379
1380 /* Wait for demod lock (UWP and CSM) */
1381 internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
1382
1383 if (internal->status == DVBS2_DEMOD_LOCK) {
1384 dprintk(state->verbose, FE_DEBUG, 1, "------------> DVB-S2 DEMOD LOCK !");
1385 i = 0;
1386 /* Demod Locked, check FEC status */
1387 internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
1388
1389 /*If false lock (UWP and CSM Locked but no FEC) try 3 time max*/
1390 while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
1391 /* Read the frequency offset*/
1392 offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
1393
1394 /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
1395 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
1396 STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
1397 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
1398 stb0899_dvbs2_reacquire(state);
1399 internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
1400 i++;
1401 }
1402 }
1403
1404 if (internal->status != DVBS2_FEC_LOCK) {
1405 if (internal->inversion == IQ_SWAP_AUTO) {
1406 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
1407 iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg);
1408 /* IQ Spectrum Inversion */
1409 STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum);
1410 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg);
1411 /* start acquistion process */
1412 stb0899_dvbs2_reacquire(state);
1413
1414 /* Wait for demod lock (UWP and CSM) */
1415 internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime);
1416 if (internal->status == DVBS2_DEMOD_LOCK) {
1417 i = 0;
1418 /* Demod Locked, check FEC */
1419 internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
1420 /*try thrice for false locks, (UWP and CSM Locked but no FEC) */
1421 while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
1422 /* Read the frequency offset*/
1423 offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
1424
1425 /* Set the Nominal frequency to the found frequency offset for the next reacquire*/
1426 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ);
1427 STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq);
1428 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg);
1429
1430 stb0899_dvbs2_reacquire(state);
1431 internal->status = stb0899_dvbs2_get_fec_status(state, searchTime);
1432 i++;
1433 }
1434 }
1435/*
1436 if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED)
1437 pParams->IQLocked = !iqSpectrum;
1438*/
1439 }
1440 }
1441 if (internal->status == DVBS2_FEC_LOCK) {
1442 dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 FEC Lock !");
1443 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
1444 modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
1445 pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;
1446
1447 if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) &&
1448 (INRANGE(STB0899_QPSK_23, modcod, STB0899_QPSK_910)) &&
1449 (pilots == 1)) {
1450
1451 stb0899_dvbs2_init_csm(state, pilots, modcod);
1452 /* Wait for UWP,CSM and data LOCK 20ms max */
1453 internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
1454
1455 i = 0;
1456 while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) {
1457 csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
1458 STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 1);
1459 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
1460 csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1);
1461 STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 0);
1462 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1);
1463
1464 internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime);
1465 i++;
1466 }
1467 }
1468
1469 if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) &&
1470 (INRANGE(STB0899_QPSK_12, modcod, STB0899_QPSK_35)) &&
1471 (pilots == 1)) {
1472
1473 /* Equalizer Disable update */
1474 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
1475 STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 1);
1476 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
1477 }
1478
1479 /* slow down the Equalizer once locked */
1480 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL);
1481 STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0x02);
1482 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg);
1483
1484 /* Store signal parameters */
1485 offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ);
1486
1487 offsetfreq = offsetfreq / ((1 << 30) / 1000);
1488 offsetfreq *= (internal->master_clk / 1000000);
1489 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2);
1490 if (STB0899_GETFIELD(SPECTRUM_INVERT, reg))
1491 offsetfreq *= -1;
1492
1493 internal->freq = internal->freq - offsetfreq;
1494 internal->srate = stb0899_dvbs2_get_srate(state);
1495
1496 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
1497 internal->modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2;
1498 internal->pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01;
1499 internal->frame_length = (STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 1) & 0x01;
1500
1501 /* Set IF AGC to tracking */
1502 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
1503 STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg, 3);
1504
1505 /* if QPSK 1/2,QPSK 3/5 or QPSK 2/3 set IF AGC reference to 16 otherwise 32*/
1506 if (INRANGE(STB0899_QPSK_12, internal->modcod, STB0899_QPSK_23))
1507 STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 16);
1508
1509 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
1510
1511 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2);
1512 STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 7);
1513 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg);
1514 }
1515
1516 /* Release Stream Merger Reset */
1517 reg = stb0899_read_reg(state, STB0899_TSTRES);
1518 STB0899_SETFIELD_VAL(FRESRS, reg, 0);
1519 stb0899_write_reg(state, STB0899_TSTRES, reg);
1520
1521 return internal->status;
1522}
diff --git a/drivers/media/dvb/frontends/stb0899_cfg.h b/drivers/media/dvb/frontends/stb0899_cfg.h
new file mode 100644
index 00000000000..0867906d3ff
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_cfg.h
@@ -0,0 +1,287 @@
1/*
2 STB0899 Multistandard Frontend driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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#ifndef __STB0899_CFG_H
23#define __STB0899_CFG_H
24
25static const struct stb0899_s2_reg stb0899_s2_init_2[] = {
26
27 { STB0899_OFF0_DMD_STATUS , STB0899_BASE_DMD_STATUS , 0x00000103 }, /* DMDSTATUS */
28 { STB0899_OFF0_CRL_FREQ , STB0899_BASE_CRL_FREQ , 0x3ed1da56 }, /* CRLFREQ */
29 { STB0899_OFF0_BTR_FREQ , STB0899_BASE_BTR_FREQ , 0x00004000 }, /* BTRFREQ */
30 { STB0899_OFF0_IF_AGC_GAIN , STB0899_BASE_IF_AGC_GAIN , 0x00002ade }, /* IFAGCGAIN */
31 { STB0899_OFF0_BB_AGC_GAIN , STB0899_BASE_BB_AGC_GAIN , 0x000001bc }, /* BBAGCGAIN */
32 { STB0899_OFF0_DC_OFFSET , STB0899_BASE_DC_OFFSET , 0x00000200 }, /* DCOFFSET */
33 { STB0899_OFF0_DMD_CNTRL , STB0899_BASE_DMD_CNTRL , 0x0000000f }, /* DMDCNTRL */
34
35 { STB0899_OFF0_IF_AGC_CNTRL , STB0899_BASE_IF_AGC_CNTRL , 0x03fb4a20 }, /* IFAGCCNTRL */
36 { STB0899_OFF0_BB_AGC_CNTRL , STB0899_BASE_BB_AGC_CNTRL , 0x00200c97 }, /* BBAGCCNTRL */
37
38 { STB0899_OFF0_CRL_CNTRL , STB0899_BASE_CRL_CNTRL , 0x00000016 }, /* CRLCNTRL */
39 { STB0899_OFF0_CRL_PHS_INIT , STB0899_BASE_CRL_PHS_INIT , 0x00000000 }, /* CRLPHSINIT */
40 { STB0899_OFF0_CRL_FREQ_INIT , STB0899_BASE_CRL_FREQ_INIT , 0x00000000 }, /* CRLFREQINIT */
41 { STB0899_OFF0_CRL_LOOP_GAIN , STB0899_BASE_CRL_LOOP_GAIN , 0x00000000 }, /* CRLLOOPGAIN */
42 { STB0899_OFF0_CRL_NOM_FREQ , STB0899_BASE_CRL_NOM_FREQ , 0x3ed097b6 }, /* CRLNOMFREQ */
43 { STB0899_OFF0_CRL_SWP_RATE , STB0899_BASE_CRL_SWP_RATE , 0x00000000 }, /* CRLSWPRATE */
44 { STB0899_OFF0_CRL_MAX_SWP , STB0899_BASE_CRL_MAX_SWP , 0x00000000 }, /* CRLMAXSWP */
45 { STB0899_OFF0_CRL_LK_CNTRL , STB0899_BASE_CRL_LK_CNTRL , 0x0f6cdc01 }, /* CRLLKCNTRL */
46 { STB0899_OFF0_DECIM_CNTRL , STB0899_BASE_DECIM_CNTRL , 0x00000000 }, /* DECIMCNTRL */
47 { STB0899_OFF0_BTR_CNTRL , STB0899_BASE_BTR_CNTRL , 0x00003993 }, /* BTRCNTRL */
48 { STB0899_OFF0_BTR_LOOP_GAIN , STB0899_BASE_BTR_LOOP_GAIN , 0x000d3c6f }, /* BTRLOOPGAIN */
49 { STB0899_OFF0_BTR_PHS_INIT , STB0899_BASE_BTR_PHS_INIT , 0x00000000 }, /* BTRPHSINIT */
50 { STB0899_OFF0_BTR_FREQ_INIT , STB0899_BASE_BTR_FREQ_INIT , 0x00000000 }, /* BTRFREQINIT */
51 { STB0899_OFF0_BTR_NOM_FREQ , STB0899_BASE_BTR_NOM_FREQ , 0x0238e38e }, /* BTRNOMFREQ */
52 { STB0899_OFF0_BTR_LK_CNTRL , STB0899_BASE_BTR_LK_CNTRL , 0x00000000 }, /* BTRLKCNTRL */
53 { STB0899_OFF0_DECN_CNTRL , STB0899_BASE_DECN_CNTRL , 0x00000000 }, /* DECNCNTRL */
54 { STB0899_OFF0_TP_CNTRL , STB0899_BASE_TP_CNTRL , 0x00000000 }, /* TPCNTRL */
55 { STB0899_OFF0_TP_BUF_STATUS , STB0899_BASE_TP_BUF_STATUS , 0x00000000 }, /* TPBUFSTATUS */
56 { STB0899_OFF0_DC_ESTIM , STB0899_BASE_DC_ESTIM , 0x00000000 }, /* DCESTIM */
57 { STB0899_OFF0_FLL_CNTRL , STB0899_BASE_FLL_CNTRL , 0x00000000 }, /* FLLCNTRL */
58 { STB0899_OFF0_FLL_FREQ_WD , STB0899_BASE_FLL_FREQ_WD , 0x40070000 }, /* FLLFREQWD */
59 { STB0899_OFF0_ANTI_ALIAS_SEL , STB0899_BASE_ANTI_ALIAS_SEL , 0x00000001 }, /* ANTIALIASSEL */
60 { STB0899_OFF0_RRC_ALPHA , STB0899_BASE_RRC_ALPHA , 0x00000002 }, /* RRCALPHA */
61 { STB0899_OFF0_DC_ADAPT_LSHFT , STB0899_BASE_DC_ADAPT_LSHFT , 0x00000000 }, /* DCADAPTISHFT */
62 { STB0899_OFF0_IMB_OFFSET , STB0899_BASE_IMB_OFFSET , 0x0000fe01 }, /* IMBOFFSET */
63 { STB0899_OFF0_IMB_ESTIMATE , STB0899_BASE_IMB_ESTIMATE , 0x00000000 }, /* IMBESTIMATE */
64 { STB0899_OFF0_IMB_CNTRL , STB0899_BASE_IMB_CNTRL , 0x00000001 }, /* IMBCNTRL */
65 { STB0899_OFF0_IF_AGC_CNTRL2 , STB0899_BASE_IF_AGC_CNTRL2 , 0x00005007 }, /* IFAGCCNTRL2 */
66 { STB0899_OFF0_DMD_CNTRL2 , STB0899_BASE_DMD_CNTRL2 , 0x00000002 }, /* DMDCNTRL2 */
67 { STB0899_OFF0_TP_BUFFER , STB0899_BASE_TP_BUFFER , 0x00000000 }, /* TPBUFFER */
68 { STB0899_OFF0_TP_BUFFER1 , STB0899_BASE_TP_BUFFER1 , 0x00000000 }, /* TPBUFFER1 */
69 { STB0899_OFF0_TP_BUFFER2 , STB0899_BASE_TP_BUFFER2 , 0x00000000 }, /* TPBUFFER2 */
70 { STB0899_OFF0_TP_BUFFER3 , STB0899_BASE_TP_BUFFER3 , 0x00000000 }, /* TPBUFFER3 */
71 { STB0899_OFF0_TP_BUFFER4 , STB0899_BASE_TP_BUFFER4 , 0x00000000 }, /* TPBUFFER4 */
72 { STB0899_OFF0_TP_BUFFER5 , STB0899_BASE_TP_BUFFER5 , 0x00000000 }, /* TPBUFFER5 */
73 { STB0899_OFF0_TP_BUFFER6 , STB0899_BASE_TP_BUFFER6 , 0x00000000 }, /* TPBUFFER6 */
74 { STB0899_OFF0_TP_BUFFER7 , STB0899_BASE_TP_BUFFER7 , 0x00000000 }, /* TPBUFFER7 */
75 { STB0899_OFF0_TP_BUFFER8 , STB0899_BASE_TP_BUFFER8 , 0x00000000 }, /* TPBUFFER8 */
76 { STB0899_OFF0_TP_BUFFER9 , STB0899_BASE_TP_BUFFER9 , 0x00000000 }, /* TPBUFFER9 */
77 { STB0899_OFF0_TP_BUFFER10 , STB0899_BASE_TP_BUFFER10 , 0x00000000 }, /* TPBUFFER10 */
78 { STB0899_OFF0_TP_BUFFER11 , STB0899_BASE_TP_BUFFER11 , 0x00000000 }, /* TPBUFFER11 */
79 { STB0899_OFF0_TP_BUFFER12 , STB0899_BASE_TP_BUFFER12 , 0x00000000 }, /* TPBUFFER12 */
80 { STB0899_OFF0_TP_BUFFER13 , STB0899_BASE_TP_BUFFER13 , 0x00000000 }, /* TPBUFFER13 */
81 { STB0899_OFF0_TP_BUFFER14 , STB0899_BASE_TP_BUFFER14 , 0x00000000 }, /* TPBUFFER14 */
82 { STB0899_OFF0_TP_BUFFER15 , STB0899_BASE_TP_BUFFER15 , 0x00000000 }, /* TPBUFFER15 */
83 { STB0899_OFF0_TP_BUFFER16 , STB0899_BASE_TP_BUFFER16 , 0x0000ff00 }, /* TPBUFFER16 */
84 { STB0899_OFF0_TP_BUFFER17 , STB0899_BASE_TP_BUFFER17 , 0x00000100 }, /* TPBUFFER17 */
85 { STB0899_OFF0_TP_BUFFER18 , STB0899_BASE_TP_BUFFER18 , 0x0000fe01 }, /* TPBUFFER18 */
86 { STB0899_OFF0_TP_BUFFER19 , STB0899_BASE_TP_BUFFER19 , 0x000004fe }, /* TPBUFFER19 */
87 { STB0899_OFF0_TP_BUFFER20 , STB0899_BASE_TP_BUFFER20 , 0x0000cfe7 }, /* TPBUFFER20 */
88 { STB0899_OFF0_TP_BUFFER21 , STB0899_BASE_TP_BUFFER21 , 0x0000bec6 }, /* TPBUFFER21 */
89 { STB0899_OFF0_TP_BUFFER22 , STB0899_BASE_TP_BUFFER22 , 0x0000c2bf }, /* TPBUFFER22 */
90 { STB0899_OFF0_TP_BUFFER23 , STB0899_BASE_TP_BUFFER23 , 0x0000c1c1 }, /* TPBUFFER23 */
91 { STB0899_OFF0_TP_BUFFER24 , STB0899_BASE_TP_BUFFER24 , 0x0000c1c1 }, /* TPBUFFER24 */
92 { STB0899_OFF0_TP_BUFFER25 , STB0899_BASE_TP_BUFFER25 , 0x0000c1c1 }, /* TPBUFFER25 */
93 { STB0899_OFF0_TP_BUFFER26 , STB0899_BASE_TP_BUFFER26 , 0x0000c1c1 }, /* TPBUFFER26 */
94 { STB0899_OFF0_TP_BUFFER27 , STB0899_BASE_TP_BUFFER27 , 0x0000c1c0 }, /* TPBUFFER27 */
95 { STB0899_OFF0_TP_BUFFER28 , STB0899_BASE_TP_BUFFER28 , 0x0000c0c0 }, /* TPBUFFER28 */
96 { STB0899_OFF0_TP_BUFFER29 , STB0899_BASE_TP_BUFFER29 , 0x0000c1c1 }, /* TPBUFFER29 */
97 { STB0899_OFF0_TP_BUFFER30 , STB0899_BASE_TP_BUFFER30 , 0x0000c1c1 }, /* TPBUFFER30 */
98 { STB0899_OFF0_TP_BUFFER31 , STB0899_BASE_TP_BUFFER31 , 0x0000c0c1 }, /* TPBUFFER31 */
99 { STB0899_OFF0_TP_BUFFER32 , STB0899_BASE_TP_BUFFER32 , 0x0000c0c1 }, /* TPBUFFER32 */
100 { STB0899_OFF0_TP_BUFFER33 , STB0899_BASE_TP_BUFFER33 , 0x0000c1c1 }, /* TPBUFFER33 */
101 { STB0899_OFF0_TP_BUFFER34 , STB0899_BASE_TP_BUFFER34 , 0x0000c1c1 }, /* TPBUFFER34 */
102 { STB0899_OFF0_TP_BUFFER35 , STB0899_BASE_TP_BUFFER35 , 0x0000c0c1 }, /* TPBUFFER35 */
103 { STB0899_OFF0_TP_BUFFER36 , STB0899_BASE_TP_BUFFER36 , 0x0000c1c1 }, /* TPBUFFER36 */
104 { STB0899_OFF0_TP_BUFFER37 , STB0899_BASE_TP_BUFFER37 , 0x0000c0c1 }, /* TPBUFFER37 */
105 { STB0899_OFF0_TP_BUFFER38 , STB0899_BASE_TP_BUFFER38 , 0x0000c1c1 }, /* TPBUFFER38 */
106 { STB0899_OFF0_TP_BUFFER39 , STB0899_BASE_TP_BUFFER39 , 0x0000c0c0 }, /* TPBUFFER39 */
107 { STB0899_OFF0_TP_BUFFER40 , STB0899_BASE_TP_BUFFER40 , 0x0000c1c0 }, /* TPBUFFER40 */
108 { STB0899_OFF0_TP_BUFFER41 , STB0899_BASE_TP_BUFFER41 , 0x0000c1c1 }, /* TPBUFFER41 */
109 { STB0899_OFF0_TP_BUFFER42 , STB0899_BASE_TP_BUFFER42 , 0x0000c0c0 }, /* TPBUFFER42 */
110 { STB0899_OFF0_TP_BUFFER43 , STB0899_BASE_TP_BUFFER43 , 0x0000c1c0 }, /* TPBUFFER43 */
111 { STB0899_OFF0_TP_BUFFER44 , STB0899_BASE_TP_BUFFER44 , 0x0000c0c1 }, /* TPBUFFER44 */
112 { STB0899_OFF0_TP_BUFFER45 , STB0899_BASE_TP_BUFFER45 , 0x0000c1be }, /* TPBUFFER45 */
113 { STB0899_OFF0_TP_BUFFER46 , STB0899_BASE_TP_BUFFER46 , 0x0000c1c9 }, /* TPBUFFER46 */
114 { STB0899_OFF0_TP_BUFFER47 , STB0899_BASE_TP_BUFFER47 , 0x0000c0da }, /* TPBUFFER47 */
115 { STB0899_OFF0_TP_BUFFER48 , STB0899_BASE_TP_BUFFER48 , 0x0000c0ba }, /* TPBUFFER48 */
116 { STB0899_OFF0_TP_BUFFER49 , STB0899_BASE_TP_BUFFER49 , 0x0000c1c4 }, /* TPBUFFER49 */
117 { STB0899_OFF0_TP_BUFFER50 , STB0899_BASE_TP_BUFFER50 , 0x0000c1bf }, /* TPBUFFER50 */
118 { STB0899_OFF0_TP_BUFFER51 , STB0899_BASE_TP_BUFFER51 , 0x0000c0c1 }, /* TPBUFFER51 */
119 { STB0899_OFF0_TP_BUFFER52 , STB0899_BASE_TP_BUFFER52 , 0x0000c1c0 }, /* TPBUFFER52 */
120 { STB0899_OFF0_TP_BUFFER53 , STB0899_BASE_TP_BUFFER53 , 0x0000c0c1 }, /* TPBUFFER53 */
121 { STB0899_OFF0_TP_BUFFER54 , STB0899_BASE_TP_BUFFER54 , 0x0000c1c1 }, /* TPBUFFER54 */
122 { STB0899_OFF0_TP_BUFFER55 , STB0899_BASE_TP_BUFFER55 , 0x0000c1c1 }, /* TPBUFFER55 */
123 { STB0899_OFF0_TP_BUFFER56 , STB0899_BASE_TP_BUFFER56 , 0x0000c1c1 }, /* TPBUFFER56 */
124 { STB0899_OFF0_TP_BUFFER57 , STB0899_BASE_TP_BUFFER57 , 0x0000c1c1 }, /* TPBUFFER57 */
125 { STB0899_OFF0_TP_BUFFER58 , STB0899_BASE_TP_BUFFER58 , 0x0000c1c1 }, /* TPBUFFER58 */
126 { STB0899_OFF0_TP_BUFFER59 , STB0899_BASE_TP_BUFFER59 , 0x0000c1c1 }, /* TPBUFFER59 */
127 { STB0899_OFF0_TP_BUFFER60 , STB0899_BASE_TP_BUFFER60 , 0x0000c1c1 }, /* TPBUFFER60 */
128 { STB0899_OFF0_TP_BUFFER61 , STB0899_BASE_TP_BUFFER61 , 0x0000c1c1 }, /* TPBUFFER61 */
129 { STB0899_OFF0_TP_BUFFER62 , STB0899_BASE_TP_BUFFER62 , 0x0000c1c1 }, /* TPBUFFER62 */
130 { STB0899_OFF0_TP_BUFFER63 , STB0899_BASE_TP_BUFFER63 , 0x0000c1c0 }, /* TPBUFFER63 */
131 { STB0899_OFF0_RESET_CNTRL , STB0899_BASE_RESET_CNTRL , 0x00000001 }, /* RESETCNTRL */
132 { STB0899_OFF0_ACM_ENABLE , STB0899_BASE_ACM_ENABLE , 0x00005654 }, /* ACMENABLE */
133 { STB0899_OFF0_DESCR_CNTRL , STB0899_BASE_DESCR_CNTRL , 0x00000000 }, /* DESCRCNTRL */
134 { STB0899_OFF0_CSM_CNTRL1 , STB0899_BASE_CSM_CNTRL1 , 0x00020019 }, /* CSMCNTRL1 */
135 { STB0899_OFF0_CSM_CNTRL2 , STB0899_BASE_CSM_CNTRL2 , 0x004b3237 }, /* CSMCNTRL2 */
136 { STB0899_OFF0_CSM_CNTRL3 , STB0899_BASE_CSM_CNTRL3 , 0x0003dd17 }, /* CSMCNTRL3 */
137 { STB0899_OFF0_CSM_CNTRL4 , STB0899_BASE_CSM_CNTRL4 , 0x00008008 }, /* CSMCNTRL4 */
138 { STB0899_OFF0_UWP_CNTRL1 , STB0899_BASE_UWP_CNTRL1 , 0x002a3106 }, /* UWPCNTRL1 */
139 { STB0899_OFF0_UWP_CNTRL2 , STB0899_BASE_UWP_CNTRL2 , 0x0006140a }, /* UWPCNTRL2 */
140 { STB0899_OFF0_UWP_STAT1 , STB0899_BASE_UWP_STAT1 , 0x00008000 }, /* UWPSTAT1 */
141 { STB0899_OFF0_UWP_STAT2 , STB0899_BASE_UWP_STAT2 , 0x00000000 }, /* UWPSTAT2 */
142 { STB0899_OFF0_DMD_STAT2 , STB0899_BASE_DMD_STAT2 , 0x00000000 }, /* DMDSTAT2 */
143 { STB0899_OFF0_FREQ_ADJ_SCALE , STB0899_BASE_FREQ_ADJ_SCALE , 0x00000471 }, /* FREQADJSCALE */
144 { STB0899_OFF0_UWP_CNTRL3 , STB0899_BASE_UWP_CNTRL3 , 0x017b0465 }, /* UWPCNTRL3 */
145 { STB0899_OFF0_SYM_CLK_SEL , STB0899_BASE_SYM_CLK_SEL , 0x00000002 }, /* SYMCLKSEL */
146 { STB0899_OFF0_SOF_SRCH_TO , STB0899_BASE_SOF_SRCH_TO , 0x00196464 }, /* SOFSRCHTO */
147 { STB0899_OFF0_ACQ_CNTRL1 , STB0899_BASE_ACQ_CNTRL1 , 0x00000603 }, /* ACQCNTRL1 */
148 { STB0899_OFF0_ACQ_CNTRL2 , STB0899_BASE_ACQ_CNTRL2 , 0x02046666 }, /* ACQCNTRL2 */
149 { STB0899_OFF0_ACQ_CNTRL3 , STB0899_BASE_ACQ_CNTRL3 , 0x10046583 }, /* ACQCNTRL3 */
150 { STB0899_OFF0_FE_SETTLE , STB0899_BASE_FE_SETTLE , 0x00010404 }, /* FESETTLE */
151 { STB0899_OFF0_AC_DWELL , STB0899_BASE_AC_DWELL , 0x0002aa8a }, /* ACDWELL */
152 { STB0899_OFF0_ACQUIRE_TRIG , STB0899_BASE_ACQUIRE_TRIG , 0x00000000 }, /* ACQUIRETRIG */
153 { STB0899_OFF0_LOCK_LOST , STB0899_BASE_LOCK_LOST , 0x00000001 }, /* LOCKLOST */
154 { STB0899_OFF0_ACQ_STAT1 , STB0899_BASE_ACQ_STAT1 , 0x00000500 }, /* ACQSTAT1 */
155 { STB0899_OFF0_ACQ_TIMEOUT , STB0899_BASE_ACQ_TIMEOUT , 0x0028a0a0 }, /* ACQTIMEOUT */
156 { STB0899_OFF0_ACQ_TIME , STB0899_BASE_ACQ_TIME , 0x00000000 }, /* ACQTIME */
157 { STB0899_OFF0_FINAL_AGC_CNTRL , STB0899_BASE_FINAL_AGC_CNTRL , 0x00800c17 }, /* FINALAGCCNTRL*/
158 { STB0899_OFF0_FINAL_AGC_GAIN , STB0899_BASE_FINAL_AGC_GAIN , 0x00000000 }, /* FINALAGCCGAIN*/
159 { STB0899_OFF0_EQUALIZER_INIT , STB0899_BASE_EQUALIZER_INIT , 0x00000000 }, /* EQUILIZERINIT*/
160 { STB0899_OFF0_EQ_CNTRL , STB0899_BASE_EQ_CNTRL , 0x00054802 }, /* EQCNTL */
161 { STB0899_OFF0_EQ_I_INIT_COEFF_0, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF0 */
162 { STB0899_OFF1_EQ_I_INIT_COEFF_1, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF1 */
163 { STB0899_OFF2_EQ_I_INIT_COEFF_2, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF2 */
164 { STB0899_OFF3_EQ_I_INIT_COEFF_3, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF3 */
165 { STB0899_OFF4_EQ_I_INIT_COEFF_4, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF4 */
166 { STB0899_OFF5_EQ_I_INIT_COEFF_5, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000400 }, /* EQIINITCOEFF5 */
167 { STB0899_OFF6_EQ_I_INIT_COEFF_6, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF6 */
168 { STB0899_OFF7_EQ_I_INIT_COEFF_7, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF7 */
169 { STB0899_OFF8_EQ_I_INIT_COEFF_8, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF8 */
170 { STB0899_OFF9_EQ_I_INIT_COEFF_9, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF9 */
171 { STB0899_OFFa_EQ_I_INIT_COEFF_10,STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF10*/
172 { STB0899_OFF0_EQ_Q_INIT_COEFF_0, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF0 */
173 { STB0899_OFF1_EQ_Q_INIT_COEFF_1, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF1 */
174 { STB0899_OFF2_EQ_Q_INIT_COEFF_2, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF2 */
175 { STB0899_OFF3_EQ_Q_INIT_COEFF_3, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF3 */
176 { STB0899_OFF4_EQ_Q_INIT_COEFF_4, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF4 */
177 { STB0899_OFF5_EQ_Q_INIT_COEFF_5, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF5 */
178 { STB0899_OFF6_EQ_Q_INIT_COEFF_6, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF6 */
179 { STB0899_OFF7_EQ_Q_INIT_COEFF_7, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF7 */
180 { STB0899_OFF8_EQ_Q_INIT_COEFF_8, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF8 */
181 { STB0899_OFF9_EQ_Q_INIT_COEFF_9, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF9 */
182 { STB0899_OFFa_EQ_Q_INIT_COEFF_10,STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF10*/
183 { STB0899_OFF0_EQ_I_OUT_COEFF_0 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT0 */
184 { STB0899_OFF1_EQ_I_OUT_COEFF_1 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT1 */
185 { STB0899_OFF2_EQ_I_OUT_COEFF_2 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT2 */
186 { STB0899_OFF3_EQ_I_OUT_COEFF_3 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT3 */
187 { STB0899_OFF4_EQ_I_OUT_COEFF_4 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT4 */
188 { STB0899_OFF5_EQ_I_OUT_COEFF_5 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT5 */
189 { STB0899_OFF6_EQ_I_OUT_COEFF_6 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT6 */
190 { STB0899_OFF7_EQ_I_OUT_COEFF_7 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT7 */
191 { STB0899_OFF8_EQ_I_OUT_COEFF_8 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT8 */
192 { STB0899_OFF9_EQ_I_OUT_COEFF_9 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT9 */
193 { STB0899_OFFa_EQ_I_OUT_COEFF_10,STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT10*/
194 { STB0899_OFF0_EQ_Q_OUT_COEFF_0 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT0 */
195 { STB0899_OFF1_EQ_Q_OUT_COEFF_1 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT1 */
196 { STB0899_OFF2_EQ_Q_OUT_COEFF_2 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT2 */
197 { STB0899_OFF3_EQ_Q_OUT_COEFF_3 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT3 */
198 { STB0899_OFF4_EQ_Q_OUT_COEFF_4 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT4 */
199 { STB0899_OFF5_EQ_Q_OUT_COEFF_5 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT5 */
200 { STB0899_OFF6_EQ_Q_OUT_COEFF_6 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT6 */
201 { STB0899_OFF7_EQ_Q_OUT_COEFF_7 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT7 */
202 { STB0899_OFF8_EQ_Q_OUT_COEFF_8 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT8 */
203 { STB0899_OFF9_EQ_Q_OUT_COEFF_9 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT9 */
204 { STB0899_OFFa_EQ_Q_OUT_COEFF_10, STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT10*/
205 { 0xffff , 0xffffffff , 0xffffffff },
206};
207static const struct stb0899_s2_reg stb0899_s2_init_4[] = {
208 { STB0899_OFF0_BLOCK_LNGTH , STB0899_BASE_BLOCK_LNGTH , 0x00000008 }, /* BLOCKLNGTH */
209 { STB0899_OFF0_ROW_STR , STB0899_BASE_ROW_STR , 0x000000b4 }, /* ROWSTR */
210 { STB0899_OFF0_BN_END_ADDR , STB0899_BASE_BN_END_ADDR , 0x000004b5 }, /* BNANDADDR */
211 { STB0899_OFF0_CN_END_ADDR , STB0899_BASE_CN_END_ADDR , 0x00000b4b }, /* CNANDADDR */
212 { STB0899_OFF0_INFO_LENGTH , STB0899_BASE_INFO_LENGTH , 0x00000078 }, /* INFOLENGTH */
213 { STB0899_OFF0_BOT_ADDR , STB0899_BASE_BOT_ADDR , 0x000001e0 }, /* BOT_ADDR */
214 { STB0899_OFF0_BCH_BLK_LN , STB0899_BASE_BCH_BLK_LN , 0x0000a8c0 }, /* BCHBLKLN */
215 { STB0899_OFF0_BCH_T , STB0899_BASE_BCH_T , 0x0000000c }, /* BCHT */
216 { STB0899_OFF0_CNFG_MODE , STB0899_BASE_CNFG_MODE , 0x00000001 }, /* CNFGMODE */
217 { STB0899_OFF0_LDPC_STAT , STB0899_BASE_LDPC_STAT , 0x0000000d }, /* LDPCSTAT */
218 { STB0899_OFF0_ITER_SCALE , STB0899_BASE_ITER_SCALE , 0x00000040 }, /* ITERSCALE */
219 { STB0899_OFF0_INPUT_MODE , STB0899_BASE_INPUT_MODE , 0x00000000 }, /* INPUTMODE */
220 { STB0899_OFF0_LDPCDECRST , STB0899_BASE_LDPCDECRST , 0x00000000 }, /* LDPCDECRST */
221 { STB0899_OFF0_CLK_PER_BYTE_RW , STB0899_BASE_CLK_PER_BYTE_RW , 0x00000008 }, /* CLKPERBYTE */
222 { STB0899_OFF0_BCH_ERRORS , STB0899_BASE_BCH_ERRORS , 0x00000000 }, /* BCHERRORS */
223 { STB0899_OFF0_LDPC_ERRORS , STB0899_BASE_LDPC_ERRORS , 0x00000000 }, /* LDPCERRORS */
224 { STB0899_OFF0_BCH_MODE , STB0899_BASE_BCH_MODE , 0x00000000 }, /* BCHMODE */
225 { STB0899_OFF0_ERR_ACC_PER , STB0899_BASE_ERR_ACC_PER , 0x00000008 }, /* ERRACCPER */
226 { STB0899_OFF0_BCH_ERR_ACC , STB0899_BASE_BCH_ERR_ACC , 0x00000000 }, /* BCHERRACC */
227 { STB0899_OFF0_FEC_TP_SEL , STB0899_BASE_FEC_TP_SEL , 0x00000000 }, /* FECTPSEL */
228 { 0xffff , 0xffffffff , 0xffffffff },
229};
230
231static const struct stb0899_s1_reg stb0899_s1_init_5[] = {
232 { STB0899_TSTCK , 0x00 },
233 { STB0899_TSTRES , 0x00 },
234 { STB0899_TSTOUT , 0x00 },
235 { STB0899_TSTIN , 0x00 },
236 { STB0899_TSTSYS , 0x00 },
237 { STB0899_TSTCHIP , 0x00 },
238 { STB0899_TSTFREE , 0x00 },
239 { STB0899_TSTI2C , 0x00 },
240 { STB0899_BITSPEEDM , 0x00 },
241 { STB0899_BITSPEEDL , 0x00 },
242 { STB0899_TBUSBIT , 0x00 },
243 { STB0899_TSTDIS , 0x00 },
244 { STB0899_TSTDISRX , 0x00 },
245 { STB0899_TSTJETON , 0x00 },
246 { STB0899_TSTDCADJ , 0x00 },
247 { STB0899_TSTAGC1 , 0x00 },
248 { STB0899_TSTAGC1N , 0x00 },
249 { STB0899_TSTPOLYPH , 0x00 },
250 { STB0899_TSTR , 0x00 },
251 { STB0899_TSTAGC2 , 0x00 },
252 { STB0899_TSTCTL1 , 0x00 },
253 { STB0899_TSTCTL2 , 0x00 },
254 { STB0899_TSTCTL3 , 0x00 },
255 { STB0899_TSTDEMAP , 0x00 },
256 { STB0899_TSTDEMAP2 , 0x00 },
257 { STB0899_TSTDEMMON , 0x00 },
258 { STB0899_TSTRATE , 0x00 },
259 { STB0899_TSTSELOUT , 0x00 },
260 { STB0899_TSYNC , 0x00 },
261 { STB0899_TSTERR , 0x00 },
262 { STB0899_TSTRAM1 , 0x00 },
263 { STB0899_TSTVSELOUT , 0x00 },
264 { STB0899_TSTFORCEIN , 0x00 },
265 { STB0899_TSTRS1 , 0x00 },
266 { STB0899_TSTRS2 , 0x00 },
267 { STB0899_TSTRS3 , 0x00 },
268 { STB0899_GHOSTREG , 0x81 },
269 { 0xffff , 0xff },
270};
271
272#define STB0899_DVBS2_ESNO_AVE 3
273#define STB0899_DVBS2_ESNO_QUANT 32
274#define STB0899_DVBS2_AVFRAMES_COARSE 10
275#define STB0899_DVBS2_AVFRAMES_FINE 20
276#define STB0899_DVBS2_MISS_THRESHOLD 6
277#define STB0899_DVBS2_UWP_THRESHOLD_ACQ 1125
278#define STB0899_DVBS2_UWP_THRESHOLD_TRACK 758
279#define STB0899_DVBS2_UWP_THRESHOLD_SOF 1350
280#define STB0899_DVBS2_SOF_SEARCH_TIMEOUT 1664100
281
282#define STB0899_DVBS2_BTR_NCO_BITS 28
283#define STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET 15
284#define STB0899_DVBS2_CRL_NCO_BITS 30
285#define STB0899_DVBS2_LDPC_MAX_ITER 70
286
287#endif //__STB0899_CFG_H
diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c
new file mode 100644
index 00000000000..37a222d9ddb
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_drv.c
@@ -0,0 +1,1686 @@
1/*
2 STB0899 Multistandard Frontend driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/slab.h>
26#include <linux/string.h>
27
28#include <linux/dvb/frontend.h>
29#include "dvb_frontend.h"
30
31#include "stb0899_drv.h"
32#include "stb0899_priv.h"
33#include "stb0899_reg.h"
34
35static unsigned int verbose = 0;//1;
36module_param(verbose, int, 0644);
37
38/* C/N in dB/10, NIRM/NIRL */
39static const struct stb0899_tab stb0899_cn_tab[] = {
40 { 200, 2600 },
41 { 190, 2700 },
42 { 180, 2860 },
43 { 170, 3020 },
44 { 160, 3210 },
45 { 150, 3440 },
46 { 140, 3710 },
47 { 130, 4010 },
48 { 120, 4360 },
49 { 110, 4740 },
50 { 100, 5190 },
51 { 90, 5670 },
52 { 80, 6200 },
53 { 70, 6770 },
54 { 60, 7360 },
55 { 50, 7970 },
56 { 40, 8250 },
57 { 30, 9000 },
58 { 20, 9450 },
59 { 15, 9600 },
60};
61
62/* DVB-S AGCIQ_VALUE vs. signal level in dBm/10.
63 * As measured, connected to a modulator.
64 * -8.0 to -50.0 dBm directly connected,
65 * -52.0 to -74.8 with extra attenuation.
66 * Cut-off to AGCIQ_VALUE = 0x80 below -74.8dBm.
67 * Crude linear extrapolation below -84.8dBm and above -8.0dBm.
68 */
69static const struct stb0899_tab stb0899_dvbsrf_tab[] = {
70 { -950, -128 },
71 { -748, -94 },
72 { -745, -92 },
73 { -735, -90 },
74 { -720, -87 },
75 { -670, -77 },
76 { -640, -70 },
77 { -610, -62 },
78 { -600, -60 },
79 { -590, -56 },
80 { -560, -41 },
81 { -540, -25 },
82 { -530, -17 },
83 { -520, -11 },
84 { -500, 1 },
85 { -490, 6 },
86 { -480, 10 },
87 { -440, 22 },
88 { -420, 27 },
89 { -400, 31 },
90 { -380, 34 },
91 { -340, 40 },
92 { -320, 43 },
93 { -280, 48 },
94 { -250, 52 },
95 { -230, 55 },
96 { -180, 61 },
97 { -140, 66 },
98 { -90, 73 },
99 { -80, 74 },
100 { 500, 127 }
101};
102
103/* DVB-S2 IF_AGC_GAIN vs. signal level in dBm/10.
104 * As measured, connected to a modulator.
105 * -8.0 to -50.1 dBm directly connected,
106 * -53.0 to -76.6 with extra attenuation.
107 * Cut-off to IF_AGC_GAIN = 0x3fff below -76.6dBm.
108 * Crude linear extrapolation below -76.6dBm and above -8.0dBm.
109 */
110static const struct stb0899_tab stb0899_dvbs2rf_tab[] = {
111 { 700, 0 },
112 { -80, 3217 },
113 { -150, 3893 },
114 { -190, 4217 },
115 { -240, 4621 },
116 { -280, 4945 },
117 { -320, 5273 },
118 { -350, 5545 },
119 { -370, 5741 },
120 { -410, 6147 },
121 { -450, 6671 },
122 { -490, 7413 },
123 { -501, 7665 },
124 { -530, 8767 },
125 { -560, 10219 },
126 { -580, 10939 },
127 { -590, 11518 },
128 { -600, 11723 },
129 { -650, 12659 },
130 { -690, 13219 },
131 { -730, 13645 },
132 { -750, 13909 },
133 { -766, 14153 },
134 { -999, 16383 }
135};
136
137/* DVB-S2 Es/N0 quant in dB/100 vs read value * 100*/
138static struct stb0899_tab stb0899_quant_tab[] = {
139 { 0, 0 },
140 { 0, 100 },
141 { 600, 200 },
142 { 950, 299 },
143 { 1200, 398 },
144 { 1400, 501 },
145 { 1560, 603 },
146 { 1690, 700 },
147 { 1810, 804 },
148 { 1910, 902 },
149 { 2000, 1000 },
150 { 2080, 1096 },
151 { 2160, 1202 },
152 { 2230, 1303 },
153 { 2350, 1496 },
154 { 2410, 1603 },
155 { 2460, 1698 },
156 { 2510, 1799 },
157 { 2600, 1995 },
158 { 2650, 2113 },
159 { 2690, 2213 },
160 { 2720, 2291 },
161 { 2760, 2399 },
162 { 2800, 2512 },
163 { 2860, 2692 },
164 { 2930, 2917 },
165 { 2960, 3020 },
166 { 3010, 3199 },
167 { 3040, 3311 },
168 { 3060, 3388 },
169 { 3120, 3631 },
170 { 3190, 3936 },
171 { 3400, 5012 },
172 { 3610, 6383 },
173 { 3800, 7943 },
174 { 4210, 12735 },
175 { 4500, 17783 },
176 { 4690, 22131 },
177 { 4810, 25410 }
178};
179
180/* DVB-S2 Es/N0 estimate in dB/100 vs read value */
181static struct stb0899_tab stb0899_est_tab[] = {
182 { 0, 0 },
183 { 0, 1 },
184 { 301, 2 },
185 { 1204, 16 },
186 { 1806, 64 },
187 { 2408, 256 },
188 { 2709, 512 },
189 { 3010, 1023 },
190 { 3311, 2046 },
191 { 3612, 4093 },
192 { 3823, 6653 },
193 { 3913, 8185 },
194 { 4010, 10233 },
195 { 4107, 12794 },
196 { 4214, 16368 },
197 { 4266, 18450 },
198 { 4311, 20464 },
199 { 4353, 22542 },
200 { 4391, 24604 },
201 { 4425, 26607 },
202 { 4457, 28642 },
203 { 4487, 30690 },
204 { 4515, 32734 },
205 { 4612, 40926 },
206 { 4692, 49204 },
207 { 4816, 65464 },
208 { 4913, 81846 },
209 { 4993, 98401 },
210 { 5060, 114815 },
211 { 5118, 131220 },
212 { 5200, 158489 },
213 { 5300, 199526 },
214 { 5400, 251189 },
215 { 5500, 316228 },
216 { 5600, 398107 },
217 { 5720, 524807 },
218 { 5721, 526017 },
219};
220
221static int _stb0899_read_reg(struct stb0899_state *state, unsigned int reg)
222{
223 int ret;
224
225 u8 b0[] = { reg >> 8, reg & 0xff };
226 u8 buf;
227
228 struct i2c_msg msg[] = {
229 {
230 .addr = state->config->demod_address,
231 .flags = 0,
232 .buf = b0,
233 .len = 2
234 },{
235 .addr = state->config->demod_address,
236 .flags = I2C_M_RD,
237 .buf = &buf,
238 .len = 1
239 }
240 };
241
242 ret = i2c_transfer(state->i2c, msg, 2);
243 if (ret != 2) {
244 if (ret != -ERESTARTSYS)
245 dprintk(state->verbose, FE_ERROR, 1,
246 "Read error, Reg=[0x%02x], Status=%d",
247 reg, ret);
248
249 return ret < 0 ? ret : -EREMOTEIO;
250 }
251 if (unlikely(*state->verbose >= FE_DEBUGREG))
252 dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%02x], data=%02x",
253 reg, buf);
254
255 return (unsigned int)buf;
256}
257
258int stb0899_read_reg(struct stb0899_state *state, unsigned int reg)
259{
260 int result;
261
262 result = _stb0899_read_reg(state, reg);
263 /*
264 * Bug ID 9:
265 * access to 0xf2xx/0xf6xx
266 * must be followed by read from 0xf2ff/0xf6ff.
267 */
268 if ((reg != 0xf2ff) && (reg != 0xf6ff) &&
269 (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
270 _stb0899_read_reg(state, (reg | 0x00ff));
271
272 return result;
273}
274
275u32 _stb0899_read_s2reg(struct stb0899_state *state,
276 u32 stb0899_i2cdev,
277 u32 stb0899_base_addr,
278 u16 stb0899_reg_offset)
279{
280 int status;
281 u32 data;
282 u8 buf[7] = { 0 };
283 u16 tmpaddr;
284
285 u8 buf_0[] = {
286 GETBYTE(stb0899_i2cdev, BYTE1), /* 0xf3 S2 Base Address (MSB) */
287 GETBYTE(stb0899_i2cdev, BYTE0), /* 0xfc S2 Base Address (LSB) */
288 GETBYTE(stb0899_base_addr, BYTE0), /* 0x00 Base Address (LSB) */
289 GETBYTE(stb0899_base_addr, BYTE1), /* 0x04 Base Address (LSB) */
290 GETBYTE(stb0899_base_addr, BYTE2), /* 0x00 Base Address (MSB) */
291 GETBYTE(stb0899_base_addr, BYTE3), /* 0x00 Base Address (MSB) */
292 };
293 u8 buf_1[] = {
294 0x00, /* 0xf3 Reg Offset */
295 0x00, /* 0x44 Reg Offset */
296 };
297
298 struct i2c_msg msg_0 = {
299 .addr = state->config->demod_address,
300 .flags = 0,
301 .buf = buf_0,
302 .len = 6
303 };
304
305 struct i2c_msg msg_1 = {
306 .addr = state->config->demod_address,
307 .flags = 0,
308 .buf = buf_1,
309 .len = 2
310 };
311
312 struct i2c_msg msg_r = {
313 .addr = state->config->demod_address,
314 .flags = I2C_M_RD,
315 .buf = buf,
316 .len = 4
317 };
318
319 tmpaddr = stb0899_reg_offset & 0xff00;
320 if (!(stb0899_reg_offset & 0x8))
321 tmpaddr = stb0899_reg_offset | 0x20;
322
323 buf_1[0] = GETBYTE(tmpaddr, BYTE1);
324 buf_1[1] = GETBYTE(tmpaddr, BYTE0);
325
326 status = i2c_transfer(state->i2c, &msg_0, 1);
327 if (status < 1) {
328 if (status != -ERESTARTSYS)
329 printk(KERN_ERR "%s ERR(1), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
330 __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
331
332 goto err;
333 }
334
335 /* Dummy */
336 status = i2c_transfer(state->i2c, &msg_1, 1);
337 if (status < 1)
338 goto err;
339
340 status = i2c_transfer(state->i2c, &msg_r, 1);
341 if (status < 1)
342 goto err;
343
344 buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1);
345 buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0);
346
347 /* Actual */
348 status = i2c_transfer(state->i2c, &msg_1, 1);
349 if (status < 1) {
350 if (status != -ERESTARTSYS)
351 printk(KERN_ERR "%s ERR(2), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
352 __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
353 goto err;
354 }
355
356 status = i2c_transfer(state->i2c, &msg_r, 1);
357 if (status < 1) {
358 if (status != -ERESTARTSYS)
359 printk(KERN_ERR "%s ERR(3), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n",
360 __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status);
361 return status < 0 ? status : -EREMOTEIO;
362 }
363
364 data = MAKEWORD32(buf[3], buf[2], buf[1], buf[0]);
365 if (unlikely(*state->verbose >= FE_DEBUGREG))
366 printk(KERN_DEBUG "%s Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n",
367 __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, data);
368
369 return data;
370
371err:
372 return status < 0 ? status : -EREMOTEIO;
373}
374
375int stb0899_write_s2reg(struct stb0899_state *state,
376 u32 stb0899_i2cdev,
377 u32 stb0899_base_addr,
378 u16 stb0899_reg_offset,
379 u32 stb0899_data)
380{
381 int status;
382
383 /* Base Address Setup */
384 u8 buf_0[] = {
385 GETBYTE(stb0899_i2cdev, BYTE1), /* 0xf3 S2 Base Address (MSB) */
386 GETBYTE(stb0899_i2cdev, BYTE0), /* 0xfc S2 Base Address (LSB) */
387 GETBYTE(stb0899_base_addr, BYTE0), /* 0x00 Base Address (LSB) */
388 GETBYTE(stb0899_base_addr, BYTE1), /* 0x04 Base Address (LSB) */
389 GETBYTE(stb0899_base_addr, BYTE2), /* 0x00 Base Address (MSB) */
390 GETBYTE(stb0899_base_addr, BYTE3), /* 0x00 Base Address (MSB) */
391 };
392 u8 buf_1[] = {
393 0x00, /* 0xf3 Reg Offset */
394 0x00, /* 0x44 Reg Offset */
395 0x00, /* data */
396 0x00, /* data */
397 0x00, /* data */
398 0x00, /* data */
399 };
400
401 struct i2c_msg msg_0 = {
402 .addr = state->config->demod_address,
403 .flags = 0,
404 .buf = buf_0,
405 .len = 6
406 };
407
408 struct i2c_msg msg_1 = {
409 .addr = state->config->demod_address,
410 .flags = 0,
411 .buf = buf_1,
412 .len = 6
413 };
414
415 buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1);
416 buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0);
417 buf_1[2] = GETBYTE(stb0899_data, BYTE0);
418 buf_1[3] = GETBYTE(stb0899_data, BYTE1);
419 buf_1[4] = GETBYTE(stb0899_data, BYTE2);
420 buf_1[5] = GETBYTE(stb0899_data, BYTE3);
421
422 if (unlikely(*state->verbose >= FE_DEBUGREG))
423 printk(KERN_DEBUG "%s Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n",
424 __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data);
425
426 status = i2c_transfer(state->i2c, &msg_0, 1);
427 if (unlikely(status < 1)) {
428 if (status != -ERESTARTSYS)
429 printk(KERN_ERR "%s ERR (1), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n",
430 __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status);
431 goto err;
432 }
433 status = i2c_transfer(state->i2c, &msg_1, 1);
434 if (unlikely(status < 1)) {
435 if (status != -ERESTARTSYS)
436 printk(KERN_ERR "%s ERR (2), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n",
437 __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status);
438
439 return status < 0 ? status : -EREMOTEIO;
440 }
441
442 return 0;
443
444err:
445 return status < 0 ? status : -EREMOTEIO;
446}
447
448int stb0899_read_regs(struct stb0899_state *state, unsigned int reg, u8 *buf, u32 count)
449{
450 int status;
451
452 u8 b0[] = { reg >> 8, reg & 0xff };
453
454 struct i2c_msg msg[] = {
455 {
456 .addr = state->config->demod_address,
457 .flags = 0,
458 .buf = b0,
459 .len = 2
460 },{
461 .addr = state->config->demod_address,
462 .flags = I2C_M_RD,
463 .buf = buf,
464 .len = count
465 }
466 };
467
468 status = i2c_transfer(state->i2c, msg, 2);
469 if (status != 2) {
470 if (status != -ERESTARTSYS)
471 printk(KERN_ERR "%s Read error, Reg=[0x%04x], Count=%u, Status=%d\n",
472 __func__, reg, count, status);
473 goto err;
474 }
475 /*
476 * Bug ID 9:
477 * access to 0xf2xx/0xf6xx
478 * must be followed by read from 0xf2ff/0xf6ff.
479 */
480 if ((reg != 0xf2ff) && (reg != 0xf6ff) &&
481 (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
482 _stb0899_read_reg(state, (reg | 0x00ff));
483
484 if (unlikely(*state->verbose >= FE_DEBUGREG)) {
485 int i;
486
487 printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
488 for (i = 0; i < count; i++) {
489 printk(" %02x", buf[i]);
490 }
491 printk("\n");
492 }
493
494 return 0;
495err:
496 return status < 0 ? status : -EREMOTEIO;
497}
498
499int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, u32 count)
500{
501 int ret;
502 u8 buf[2 + count];
503 struct i2c_msg i2c_msg = {
504 .addr = state->config->demod_address,
505 .flags = 0,
506 .buf = buf,
507 .len = 2 + count
508 };
509
510 buf[0] = reg >> 8;
511 buf[1] = reg & 0xff;
512 memcpy(&buf[2], data, count);
513
514 if (unlikely(*state->verbose >= FE_DEBUGREG)) {
515 int i;
516
517 printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
518 for (i = 0; i < count; i++)
519 printk(" %02x", data[i]);
520 printk("\n");
521 }
522 ret = i2c_transfer(state->i2c, &i2c_msg, 1);
523
524 /*
525 * Bug ID 9:
526 * access to 0xf2xx/0xf6xx
527 * must be followed by read from 0xf2ff/0xf6ff.
528 */
529 if ((((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600)))
530 stb0899_read_reg(state, (reg | 0x00ff));
531
532 if (ret != 1) {
533 if (ret != -ERESTARTSYS)
534 dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d",
535 reg, data[0], count, ret);
536 return ret < 0 ? ret : -EREMOTEIO;
537 }
538
539 return 0;
540}
541
542int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data)
543{
544 return stb0899_write_regs(state, reg, &data, 1);
545}
546
547/*
548 * stb0899_get_mclk
549 * Get STB0899 master clock frequency
550 * ExtClk: external clock frequency (Hz)
551 */
552static u32 stb0899_get_mclk(struct stb0899_state *state)
553{
554 u32 mclk = 0, div = 0;
555
556 div = stb0899_read_reg(state, STB0899_NCOARSE);
557 mclk = (div + 1) * state->config->xtal_freq / 6;
558 dprintk(state->verbose, FE_DEBUG, 1, "div=%d, mclk=%d", div, mclk);
559
560 return mclk;
561}
562
563/*
564 * stb0899_set_mclk
565 * Set STB0899 master Clock frequency
566 * Mclk: demodulator master clock
567 * ExtClk: external clock frequency (Hz)
568 */
569static void stb0899_set_mclk(struct stb0899_state *state, u32 Mclk)
570{
571 struct stb0899_internal *internal = &state->internal;
572 u8 mdiv = 0;
573
574 dprintk(state->verbose, FE_DEBUG, 1, "state->config=%p", state->config);
575 mdiv = ((6 * Mclk) / state->config->xtal_freq) - 1;
576 dprintk(state->verbose, FE_DEBUG, 1, "mdiv=%d", mdiv);
577
578 stb0899_write_reg(state, STB0899_NCOARSE, mdiv);
579 internal->master_clk = stb0899_get_mclk(state);
580
581 dprintk(state->verbose, FE_DEBUG, 1, "MasterCLOCK=%d", internal->master_clk);
582}
583
584static int stb0899_postproc(struct stb0899_state *state, u8 ctl, int enable)
585{
586 struct stb0899_config *config = state->config;
587 const struct stb0899_postproc *postproc = config->postproc;
588
589 /* post process event */
590 if (postproc) {
591 if (enable) {
592 if (postproc[ctl].level == STB0899_GPIOPULLUP)
593 stb0899_write_reg(state, postproc[ctl].gpio, 0x02);
594 else
595 stb0899_write_reg(state, postproc[ctl].gpio, 0x82);
596 } else {
597 if (postproc[ctl].level == STB0899_GPIOPULLUP)
598 stb0899_write_reg(state, postproc[ctl].gpio, 0x82);
599 else
600 stb0899_write_reg(state, postproc[ctl].gpio, 0x02);
601 }
602 }
603 return 0;
604}
605
606static void stb0899_release(struct dvb_frontend *fe)
607{
608 struct stb0899_state *state = fe->demodulator_priv;
609
610 dprintk(state->verbose, FE_DEBUG, 1, "Release Frontend");
611 /* post process event */
612 stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0);
613 kfree(state);
614}
615
616/*
617 * stb0899_get_alpha
618 * return: rolloff
619 */
620static int stb0899_get_alpha(struct stb0899_state *state)
621{
622 u8 mode_coeff;
623
624 mode_coeff = stb0899_read_reg(state, STB0899_DEMOD);
625
626 if (STB0899_GETFIELD(MODECOEFF, mode_coeff) == 1)
627 return 20;
628 else
629 return 35;
630}
631
632/*
633 * stb0899_init_calc
634 */
635static void stb0899_init_calc(struct stb0899_state *state)
636{
637 struct stb0899_internal *internal = &state->internal;
638 int master_clk;
639 u8 agc[2];
640 u8 agc1cn;
641 u32 reg;
642
643 /* Read registers (in burst mode) */
644 agc1cn = stb0899_read_reg(state, STB0899_AGC1CN);
645 stb0899_read_regs(state, STB0899_AGC1REF, agc, 2); /* AGC1R and AGC2O */
646
647 /* Initial calculations */
648 master_clk = stb0899_get_mclk(state);
649 internal->t_agc1 = 0;
650 internal->t_agc2 = 0;
651 internal->master_clk = master_clk;
652 internal->mclk = master_clk / 65536L;
653 internal->rolloff = stb0899_get_alpha(state);
654
655 /* DVBS2 Initial calculations */
656 /* Set AGC value to the middle */
657 internal->agc_gain = 8154;
658 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL);
659 STB0899_SETFIELD_VAL(IF_GAIN_INIT, reg, internal->agc_gain);
660 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg);
661
662 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, RRC_ALPHA);
663 internal->rrc_alpha = STB0899_GETFIELD(RRC_ALPHA, reg);
664
665 internal->center_freq = 0;
666 internal->av_frame_coarse = 10;
667 internal->av_frame_fine = 20;
668 internal->step_size = 2;
669/*
670 if ((pParams->SpectralInv == FE_IQ_NORMAL) || (pParams->SpectralInv == FE_IQ_AUTO))
671 pParams->IQLocked = 0;
672 else
673 pParams->IQLocked = 1;
674*/
675}
676
677static int stb0899_wait_diseqc_fifo_empty(struct stb0899_state *state, int timeout)
678{
679 u8 reg = 0;
680 unsigned long start = jiffies;
681
682 while (1) {
683 reg = stb0899_read_reg(state, STB0899_DISSTATUS);
684 if (!STB0899_GETFIELD(FIFOFULL, reg))
685 break;
686 if ((jiffies - start) > timeout) {
687 dprintk(state->verbose, FE_ERROR, 1, "timed out !!");
688 return -ETIMEDOUT;
689 }
690 }
691
692 return 0;
693}
694
695static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
696{
697 struct stb0899_state *state = fe->demodulator_priv;
698 u8 reg, i;
699
700 if (cmd->msg_len > 8)
701 return -EINVAL;
702
703 /* enable FIFO precharge */
704 reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
705 STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 1);
706 stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
707 for (i = 0; i < cmd->msg_len; i++) {
708 /* wait for FIFO empty */
709 if (stb0899_wait_diseqc_fifo_empty(state, 10) < 0)
710 return -ETIMEDOUT;
711
712 stb0899_write_reg(state, STB0899_DISFIFO, cmd->msg[i]);
713 }
714 reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
715 STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0);
716 stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
717 msleep(100);
718 return 0;
719}
720
721static int stb0899_wait_diseqc_rxidle(struct stb0899_state *state, int timeout)
722{
723 u8 reg = 0;
724 unsigned long start = jiffies;
725
726 while (!STB0899_GETFIELD(RXEND, reg)) {
727 reg = stb0899_read_reg(state, STB0899_DISRX_ST0);
728 if (jiffies - start > timeout) {
729 dprintk(state->verbose, FE_ERROR, 1, "timed out!!");
730 return -ETIMEDOUT;
731 }
732 msleep(10);
733 }
734
735 return 0;
736}
737
738static int stb0899_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply)
739{
740 struct stb0899_state *state = fe->demodulator_priv;
741 u8 reg, length = 0, i;
742 int result;
743
744 if (stb0899_wait_diseqc_rxidle(state, 100) < 0)
745 return -ETIMEDOUT;
746
747 reg = stb0899_read_reg(state, STB0899_DISRX_ST0);
748 if (STB0899_GETFIELD(RXEND, reg)) {
749
750 reg = stb0899_read_reg(state, STB0899_DISRX_ST1);
751 length = STB0899_GETFIELD(FIFOBYTENBR, reg);
752
753 if (length > sizeof (reply->msg)) {
754 result = -EOVERFLOW;
755 goto exit;
756 }
757 reply->msg_len = length;
758
759 /* extract data */
760 for (i = 0; i < length; i++)
761 reply->msg[i] = stb0899_read_reg(state, STB0899_DISFIFO);
762 }
763
764 return 0;
765exit:
766
767 return result;
768}
769
770static int stb0899_wait_diseqc_txidle(struct stb0899_state *state, int timeout)
771{
772 u8 reg = 0;
773 unsigned long start = jiffies;
774
775 while (!STB0899_GETFIELD(TXIDLE, reg)) {
776 reg = stb0899_read_reg(state, STB0899_DISSTATUS);
777 if (jiffies - start > timeout) {
778 dprintk(state->verbose, FE_ERROR, 1, "timed out!!");
779 return -ETIMEDOUT;
780 }
781 msleep(10);
782 }
783 return 0;
784}
785
786static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
787{
788 struct stb0899_state *state = fe->demodulator_priv;
789 u8 reg, old_state;
790
791 /* wait for diseqc idle */
792 if (stb0899_wait_diseqc_txidle(state, 100) < 0)
793 return -ETIMEDOUT;
794
795 reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
796 old_state = reg;
797 /* set to burst mode */
798 STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x03);
799 STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x01);
800 stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
801 switch (burst) {
802 case SEC_MINI_A:
803 /* unmodulated */
804 stb0899_write_reg(state, STB0899_DISFIFO, 0x00);
805 break;
806 case SEC_MINI_B:
807 /* modulated */
808 stb0899_write_reg(state, STB0899_DISFIFO, 0xff);
809 break;
810 }
811 reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
812 STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x00);
813 stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
814 /* wait for diseqc idle */
815 if (stb0899_wait_diseqc_txidle(state, 100) < 0)
816 return -ETIMEDOUT;
817
818 /* restore state */
819 stb0899_write_reg(state, STB0899_DISCNTRL1, old_state);
820
821 return 0;
822}
823
824static int stb0899_diseqc_init(struct stb0899_state *state)
825{
826 struct dvb_diseqc_master_cmd tx_data;
827/*
828 struct dvb_diseqc_slave_reply rx_data;
829*/
830 u8 f22_tx, f22_rx, reg;
831
832 u32 mclk, tx_freq = 22000;/* count = 0, i; */
833 tx_data.msg[0] = 0xe2;
834 tx_data.msg_len = 3;
835 reg = stb0899_read_reg(state, STB0899_DISCNTRL2);
836 STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0);
837 stb0899_write_reg(state, STB0899_DISCNTRL2, reg);
838
839 /* disable Tx spy */
840 reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
841 STB0899_SETFIELD_VAL(DISEQCRESET, reg, 1);
842 stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
843
844 reg = stb0899_read_reg(state, STB0899_DISCNTRL1);
845 STB0899_SETFIELD_VAL(DISEQCRESET, reg, 0);
846 stb0899_write_reg(state, STB0899_DISCNTRL1, reg);
847
848 mclk = stb0899_get_mclk(state);
849 f22_tx = mclk / (tx_freq * 32);
850 stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* DiSEqC Tx freq */
851 state->rx_freq = 20000;
852 f22_rx = mclk / (state->rx_freq * 32);
853
854 return 0;
855}
856
857static int stb0899_sleep(struct dvb_frontend *fe)
858{
859 struct stb0899_state *state = fe->demodulator_priv;
860/*
861 u8 reg;
862*/
863 dprintk(state->verbose, FE_DEBUG, 1, "Going to Sleep .. (Really tired .. :-))");
864 /* post process event */
865 stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0);
866
867 return 0;
868}
869
870static int stb0899_wakeup(struct dvb_frontend *fe)
871{
872 int rc;
873 struct stb0899_state *state = fe->demodulator_priv;
874
875 if ((rc = stb0899_write_reg(state, STB0899_SYNTCTRL, STB0899_SELOSCI)))
876 return rc;
877 /* Activate all clocks; DVB-S2 registers are inaccessible otherwise. */
878 if ((rc = stb0899_write_reg(state, STB0899_STOPCLK1, 0x00)))
879 return rc;
880 if ((rc = stb0899_write_reg(state, STB0899_STOPCLK2, 0x00)))
881 return rc;
882
883 /* post process event */
884 stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 1);
885
886 return 0;
887}
888
889static int stb0899_init(struct dvb_frontend *fe)
890{
891 int i;
892 struct stb0899_state *state = fe->demodulator_priv;
893 struct stb0899_config *config = state->config;
894
895 dprintk(state->verbose, FE_DEBUG, 1, "Initializing STB0899 ... ");
896
897 /* init device */
898 dprintk(state->verbose, FE_DEBUG, 1, "init device");
899 for (i = 0; config->init_dev[i].address != 0xffff; i++)
900 stb0899_write_reg(state, config->init_dev[i].address, config->init_dev[i].data);
901
902 dprintk(state->verbose, FE_DEBUG, 1, "init S2 demod");
903 /* init S2 demod */
904 for (i = 0; config->init_s2_demod[i].offset != 0xffff; i++)
905 stb0899_write_s2reg(state, STB0899_S2DEMOD,
906 config->init_s2_demod[i].base_address,
907 config->init_s2_demod[i].offset,
908 config->init_s2_demod[i].data);
909
910 dprintk(state->verbose, FE_DEBUG, 1, "init S1 demod");
911 /* init S1 demod */
912 for (i = 0; config->init_s1_demod[i].address != 0xffff; i++)
913 stb0899_write_reg(state, config->init_s1_demod[i].address, config->init_s1_demod[i].data);
914
915 dprintk(state->verbose, FE_DEBUG, 1, "init S2 FEC");
916 /* init S2 fec */
917 for (i = 0; config->init_s2_fec[i].offset != 0xffff; i++)
918 stb0899_write_s2reg(state, STB0899_S2FEC,
919 config->init_s2_fec[i].base_address,
920 config->init_s2_fec[i].offset,
921 config->init_s2_fec[i].data);
922
923 dprintk(state->verbose, FE_DEBUG, 1, "init TST");
924 /* init test */
925 for (i = 0; config->init_tst[i].address != 0xffff; i++)
926 stb0899_write_reg(state, config->init_tst[i].address, config->init_tst[i].data);
927
928 stb0899_init_calc(state);
929 stb0899_diseqc_init(state);
930
931 return 0;
932}
933
934static int stb0899_table_lookup(const struct stb0899_tab *tab, int max, int val)
935{
936 int res = 0;
937 int min = 0, med;
938
939 if (val < tab[min].read)
940 res = tab[min].real;
941 else if (val >= tab[max].read)
942 res = tab[max].real;
943 else {
944 while ((max - min) > 1) {
945 med = (max + min) / 2;
946 if (val >= tab[min].read && val < tab[med].read)
947 max = med;
948 else
949 min = med;
950 }
951 res = ((val - tab[min].read) *
952 (tab[max].real - tab[min].real) /
953 (tab[max].read - tab[min].read)) +
954 tab[min].real;
955 }
956
957 return res;
958}
959
960static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
961{
962 struct stb0899_state *state = fe->demodulator_priv;
963 struct stb0899_internal *internal = &state->internal;
964
965 int val;
966 u32 reg;
967 switch (state->delsys) {
968 case SYS_DVBS:
969 case SYS_DSS:
970 if (internal->lock) {
971 reg = stb0899_read_reg(state, STB0899_VSTATUS);
972 if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
973
974 reg = stb0899_read_reg(state, STB0899_AGCIQIN);
975 val = (s32)(s8)STB0899_GETFIELD(AGCIQVALUE, reg);
976
977 *strength = stb0899_table_lookup(stb0899_dvbsrf_tab, ARRAY_SIZE(stb0899_dvbsrf_tab) - 1, val);
978 *strength += 750;
979 dprintk(state->verbose, FE_DEBUG, 1, "AGCIQVALUE = 0x%02x, C = %d * 0.1 dBm",
980 val & 0xff, *strength);
981 }
982 }
983 break;
984 case SYS_DVBS2:
985 if (internal->lock) {
986 reg = STB0899_READ_S2REG(STB0899_DEMOD, IF_AGC_GAIN);
987 val = STB0899_GETFIELD(IF_AGC_GAIN, reg);
988
989 *strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val);
990 *strength += 750;
991 dprintk(state->verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm",
992 val & 0x3fff, *strength);
993 }
994 break;
995 default:
996 dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
997 return -EINVAL;
998 }
999
1000 return 0;
1001}
1002
1003static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr)
1004{
1005 struct stb0899_state *state = fe->demodulator_priv;
1006 struct stb0899_internal *internal = &state->internal;
1007
1008 unsigned int val, quant, quantn = -1, est, estn = -1;
1009 u8 buf[2];
1010 u32 reg;
1011
1012 reg = stb0899_read_reg(state, STB0899_VSTATUS);
1013 switch (state->delsys) {
1014 case SYS_DVBS:
1015 case SYS_DSS:
1016 if (internal->lock) {
1017 if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
1018
1019 stb0899_read_regs(state, STB0899_NIRM, buf, 2);
1020 val = MAKEWORD16(buf[0], buf[1]);
1021
1022 *snr = stb0899_table_lookup(stb0899_cn_tab, ARRAY_SIZE(stb0899_cn_tab) - 1, val);
1023 dprintk(state->verbose, FE_DEBUG, 1, "NIR = 0x%02x%02x = %u, C/N = %d * 0.1 dBm\n",
1024 buf[0], buf[1], val, *snr);
1025 }
1026 }
1027 break;
1028 case SYS_DVBS2:
1029 if (internal->lock) {
1030 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1);
1031 quant = STB0899_GETFIELD(UWP_ESN0_QUANT, reg);
1032 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2);
1033 est = STB0899_GETFIELD(ESN0_EST, reg);
1034 if (est == 1)
1035 val = 301; /* C/N = 30.1 dB */
1036 else if (est == 2)
1037 val = 270; /* C/N = 27.0 dB */
1038 else {
1039 /* quantn = 100 * log(quant^2) */
1040 quantn = stb0899_table_lookup(stb0899_quant_tab, ARRAY_SIZE(stb0899_quant_tab) - 1, quant * 100);
1041 /* estn = 100 * log(est) */
1042 estn = stb0899_table_lookup(stb0899_est_tab, ARRAY_SIZE(stb0899_est_tab) - 1, est);
1043 /* snr(dBm/10) = -10*(log(est)-log(quant^2)) => snr(dBm/10) = (100*log(quant^2)-100*log(est))/10 */
1044 val = (quantn - estn) / 10;
1045 }
1046 *snr = val;
1047 dprintk(state->verbose, FE_DEBUG, 1, "Es/N0 quant = %d (%d) estimate = %u (%d), C/N = %d * 0.1 dBm",
1048 quant, quantn, est, estn, val);
1049 }
1050 break;
1051 default:
1052 dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
1053 return -EINVAL;
1054 }
1055
1056 return 0;
1057}
1058
1059static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status)
1060{
1061 struct stb0899_state *state = fe->demodulator_priv;
1062 struct stb0899_internal *internal = &state->internal;
1063 u8 reg;
1064 *status = 0;
1065
1066 switch (state->delsys) {
1067 case SYS_DVBS:
1068 case SYS_DSS:
1069 dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S/DSS");
1070 if (internal->lock) {
1071 reg = stb0899_read_reg(state, STB0899_VSTATUS);
1072 if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) {
1073 dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_CARRIER | FE_HAS_LOCK");
1074 *status |= FE_HAS_CARRIER | FE_HAS_LOCK;
1075
1076 reg = stb0899_read_reg(state, STB0899_PLPARM);
1077 if (STB0899_GETFIELD(VITCURPUN, reg)) {
1078 dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_VITERBI | FE_HAS_SYNC");
1079 *status |= FE_HAS_VITERBI | FE_HAS_SYNC;
1080 /* post process event */
1081 stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1);
1082 }
1083 }
1084 }
1085 break;
1086 case SYS_DVBS2:
1087 dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S2");
1088 if (internal->lock) {
1089 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2);
1090 if (STB0899_GETFIELD(UWP_LOCK, reg) && STB0899_GETFIELD(CSM_LOCK, reg)) {
1091 *status |= FE_HAS_CARRIER;
1092 dprintk(state->verbose, FE_DEBUG, 1,
1093 "UWP & CSM Lock ! ---> DVB-S2 FE_HAS_CARRIER");
1094
1095 reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1);
1096 if (STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg)) {
1097 *status |= FE_HAS_LOCK;
1098 dprintk(state->verbose, FE_DEBUG, 1,
1099 "Packet Delineator Locked ! -----> DVB-S2 FE_HAS_LOCK");
1100
1101 }
1102 if (STB0899_GETFIELD(CONTINUOUS_STREAM, reg)) {
1103 *status |= FE_HAS_VITERBI;
1104 dprintk(state->verbose, FE_DEBUG, 1,
1105 "Packet Delineator found VITERBI ! -----> DVB-S2 FE_HAS_VITERBI");
1106 }
1107 if (STB0899_GETFIELD(ACCEPTED_STREAM, reg)) {
1108 *status |= FE_HAS_SYNC;
1109 dprintk(state->verbose, FE_DEBUG, 1,
1110 "Packet Delineator found SYNC ! -----> DVB-S2 FE_HAS_SYNC");
1111 /* post process event */
1112 stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1);
1113 }
1114 }
1115 }
1116 break;
1117 default:
1118 dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
1119 return -EINVAL;
1120 }
1121 return 0;
1122}
1123
1124/*
1125 * stb0899_get_error
1126 * viterbi error for DVB-S/DSS
1127 * packet error for DVB-S2
1128 * Bit Error Rate or Packet Error Rate * 10 ^ 7
1129 */
1130static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber)
1131{
1132 struct stb0899_state *state = fe->demodulator_priv;
1133 struct stb0899_internal *internal = &state->internal;
1134
1135 u8 lsb, msb;
1136 u32 i;
1137
1138 *ber = 0;
1139
1140 switch (state->delsys) {
1141 case SYS_DVBS:
1142 case SYS_DSS:
1143 if (internal->lock) {
1144 /* average 5 BER values */
1145 for (i = 0; i < 5; i++) {
1146 msleep(100);
1147 lsb = stb0899_read_reg(state, STB0899_ECNT1L);
1148 msb = stb0899_read_reg(state, STB0899_ECNT1M);
1149 *ber += MAKEWORD16(msb, lsb);
1150 }
1151 *ber /= 5;
1152 /* Viterbi Check */
1153 if (STB0899_GETFIELD(VSTATUS_PRFVIT, internal->v_status)) {
1154 /* Error Rate */
1155 *ber *= 9766;
1156 /* ber = ber * 10 ^ 7 */
1157 *ber /= (-1 + (1 << (2 * STB0899_GETFIELD(NOE, internal->err_ctrl))));
1158 *ber /= 8;
1159 }
1160 }
1161 break;
1162 case SYS_DVBS2:
1163 if (internal->lock) {
1164 /* Average 5 PER values */
1165 for (i = 0; i < 5; i++) {
1166 msleep(100);
1167 lsb = stb0899_read_reg(state, STB0899_ECNT1L);
1168 msb = stb0899_read_reg(state, STB0899_ECNT1M);
1169 *ber += MAKEWORD16(msb, lsb);
1170 }
1171 /* ber = ber * 10 ^ 7 */
1172 *ber *= 10000000;
1173 *ber /= (-1 + (1 << (4 + 2 * STB0899_GETFIELD(NOE, internal->err_ctrl))));
1174 }
1175 break;
1176 default:
1177 dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system");
1178 return -EINVAL;
1179 }
1180
1181 return 0;
1182}
1183
1184static int stb0899_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
1185{
1186 struct stb0899_state *state = fe->demodulator_priv;
1187
1188 switch (voltage) {
1189 case SEC_VOLTAGE_13:
1190 stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82);
1191 stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02);
1192 stb0899_write_reg(state, STB0899_GPIO02CFG, 0x00);
1193 break;
1194 case SEC_VOLTAGE_18:
1195 stb0899_write_reg(state, STB0899_GPIO00CFG, 0x02);
1196 stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02);
1197 stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82);
1198 break;
1199 case SEC_VOLTAGE_OFF:
1200 stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82);
1201 stb0899_write_reg(state, STB0899_GPIO01CFG, 0x82);
1202 stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82);
1203 break;
1204 default:
1205 return -EINVAL;
1206 }
1207
1208 return 0;
1209}
1210
1211static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
1212{
1213 struct stb0899_state *state = fe->demodulator_priv;
1214 struct stb0899_internal *internal = &state->internal;
1215
1216 u8 div, reg;
1217
1218 /* wait for diseqc idle */
1219 if (stb0899_wait_diseqc_txidle(state, 100) < 0)
1220 return -ETIMEDOUT;
1221
1222 switch (tone) {
1223 case SEC_TONE_ON:
1224 div = (internal->master_clk / 100) / 5632;
1225 div = (div + 5) / 10;
1226 stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x66);
1227 reg = stb0899_read_reg(state, STB0899_ACRPRESC);
1228 STB0899_SETFIELD_VAL(ACRPRESC, reg, 0x03);
1229 stb0899_write_reg(state, STB0899_ACRPRESC, reg);
1230 stb0899_write_reg(state, STB0899_ACRDIV1, div);
1231 break;
1232 case SEC_TONE_OFF:
1233 stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x20);
1234 break;
1235 default:
1236 return -EINVAL;
1237 }
1238 return 0;
1239}
1240
1241int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
1242{
1243 int i2c_stat;
1244 struct stb0899_state *state = fe->demodulator_priv;
1245
1246 i2c_stat = stb0899_read_reg(state, STB0899_I2CRPT);
1247 if (i2c_stat < 0)
1248 goto err;
1249
1250 if (enable) {
1251 dprintk(state->verbose, FE_DEBUG, 1, "Enabling I2C Repeater ...");
1252 i2c_stat |= STB0899_I2CTON;
1253 if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0)
1254 goto err;
1255 } else {
1256 dprintk(state->verbose, FE_DEBUG, 1, "Disabling I2C Repeater ...");
1257 i2c_stat &= ~STB0899_I2CTON;
1258 if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0)
1259 goto err;
1260 }
1261 return 0;
1262err:
1263 dprintk(state->verbose, FE_ERROR, 1, "I2C Repeater control failed");
1264 return -EREMOTEIO;
1265}
1266
1267
1268static inline void CONVERT32(u32 x, char *str)
1269{
1270 *str++ = (x >> 24) & 0xff;
1271 *str++ = (x >> 16) & 0xff;
1272 *str++ = (x >> 8) & 0xff;
1273 *str++ = (x >> 0) & 0xff;
1274 *str = '\0';
1275}
1276
1277int stb0899_get_dev_id(struct stb0899_state *state)
1278{
1279 u8 chip_id, release;
1280 u16 id;
1281 u32 demod_ver = 0, fec_ver = 0;
1282 char demod_str[5] = { 0 };
1283 char fec_str[5] = { 0 };
1284
1285 id = stb0899_read_reg(state, STB0899_DEV_ID);
1286 dprintk(state->verbose, FE_DEBUG, 1, "ID reg=[0x%02x]", id);
1287 chip_id = STB0899_GETFIELD(CHIP_ID, id);
1288 release = STB0899_GETFIELD(CHIP_REL, id);
1289
1290 dprintk(state->verbose, FE_ERROR, 1, "Device ID=[%d], Release=[%d]",
1291 chip_id, release);
1292
1293 CONVERT32(STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CORE_ID), (char *)&demod_str);
1294
1295 demod_ver = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_VERSION_ID);
1296 dprintk(state->verbose, FE_ERROR, 1, "Demodulator Core ID=[%s], Version=[%d]", (char *) &demod_str, demod_ver);
1297 CONVERT32(STB0899_READ_S2REG(STB0899_S2FEC, FEC_CORE_ID_REG), (char *)&fec_str);
1298 fec_ver = STB0899_READ_S2REG(STB0899_S2FEC, FEC_VER_ID_REG);
1299 if (! (chip_id > 0)) {
1300 dprintk(state->verbose, FE_ERROR, 1, "couldn't find a STB 0899");
1301
1302 return -ENODEV;
1303 }
1304 dprintk(state->verbose, FE_ERROR, 1, "FEC Core ID=[%s], Version=[%d]", (char*) &fec_str, fec_ver);
1305
1306 return 0;
1307}
1308
1309static void stb0899_set_delivery(struct stb0899_state *state)
1310{
1311 u8 reg;
1312 u8 stop_clk[2];
1313
1314 stop_clk[0] = stb0899_read_reg(state, STB0899_STOPCLK1);
1315 stop_clk[1] = stb0899_read_reg(state, STB0899_STOPCLK2);
1316
1317 switch (state->delsys) {
1318 case SYS_DVBS:
1319 dprintk(state->verbose, FE_DEBUG, 1, "Delivery System -- DVB-S");
1320 /* FECM/Viterbi ON */
1321 reg = stb0899_read_reg(state, STB0899_FECM);
1322 STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0);
1323 STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1);
1324 stb0899_write_reg(state, STB0899_FECM, reg);
1325
1326 stb0899_write_reg(state, STB0899_RSULC, 0xb1);
1327 stb0899_write_reg(state, STB0899_TSULC, 0x40);
1328 stb0899_write_reg(state, STB0899_RSLLC, 0x42);
1329 stb0899_write_reg(state, STB0899_TSLPL, 0x12);
1330
1331 reg = stb0899_read_reg(state, STB0899_TSTRES);
1332 STB0899_SETFIELD_VAL(FRESLDPC, reg, 1);
1333 stb0899_write_reg(state, STB0899_TSTRES, reg);
1334
1335 STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
1336 STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1);
1337 STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1);
1338
1339 STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1);
1340 STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1);
1341
1342 STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 1);
1343 STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
1344
1345 STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1);
1346 break;
1347 case SYS_DVBS2:
1348 /* FECM/Viterbi OFF */
1349 reg = stb0899_read_reg(state, STB0899_FECM);
1350 STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0);
1351 STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 0);
1352 stb0899_write_reg(state, STB0899_FECM, reg);
1353
1354 stb0899_write_reg(state, STB0899_RSULC, 0xb1);
1355 stb0899_write_reg(state, STB0899_TSULC, 0x42);
1356 stb0899_write_reg(state, STB0899_RSLLC, 0x40);
1357 stb0899_write_reg(state, STB0899_TSLPL, 0x02);
1358
1359 reg = stb0899_read_reg(state, STB0899_TSTRES);
1360 STB0899_SETFIELD_VAL(FRESLDPC, reg, 0);
1361 stb0899_write_reg(state, STB0899_TSTRES, reg);
1362
1363 STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
1364 STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 0);
1365 STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 0);
1366
1367 STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 0);
1368 STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 0);
1369
1370 STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 0);
1371 STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
1372
1373 STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 0);
1374 break;
1375 case SYS_DSS:
1376 /* FECM/Viterbi ON */
1377 reg = stb0899_read_reg(state, STB0899_FECM);
1378 STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 1);
1379 STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1);
1380 stb0899_write_reg(state, STB0899_FECM, reg);
1381
1382 stb0899_write_reg(state, STB0899_RSULC, 0xa1);
1383 stb0899_write_reg(state, STB0899_TSULC, 0x61);
1384 stb0899_write_reg(state, STB0899_RSLLC, 0x42);
1385
1386 reg = stb0899_read_reg(state, STB0899_TSTRES);
1387 STB0899_SETFIELD_VAL(FRESLDPC, reg, 1);
1388 stb0899_write_reg(state, STB0899_TSTRES, reg);
1389
1390 STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1);
1391 STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1);
1392 STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1);
1393
1394 STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1);
1395 STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1);
1396
1397 STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0);
1398
1399 STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1);
1400 break;
1401 default:
1402 dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system");
1403 break;
1404 }
1405 STB0899_SETFIELD_VAL(STOP_CKADCI108, stop_clk[0], 0);
1406 stb0899_write_regs(state, STB0899_STOPCLK1, stop_clk, 2);
1407}
1408
1409/*
1410 * stb0899_set_iterations
1411 * set the LDPC iteration scale function
1412 */
1413static void stb0899_set_iterations(struct stb0899_state *state)
1414{
1415 struct stb0899_internal *internal = &state->internal;
1416 struct stb0899_config *config = state->config;
1417
1418 s32 iter_scale;
1419 u32 reg;
1420
1421 iter_scale = 17 * (internal->master_clk / 1000);
1422 iter_scale += 410000;
1423 iter_scale /= (internal->srate / 1000000);
1424 iter_scale /= 1000;
1425
1426 if (iter_scale > config->ldpc_max_iter)
1427 iter_scale = config->ldpc_max_iter;
1428
1429 reg = STB0899_READ_S2REG(STB0899_S2DEMOD, MAX_ITER);
1430 STB0899_SETFIELD_VAL(MAX_ITERATIONS, reg, iter_scale);
1431 stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_MAX_ITER, STB0899_OFF0_MAX_ITER, reg);
1432}
1433
1434static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1435{
1436 struct stb0899_state *state = fe->demodulator_priv;
1437 struct stb0899_params *i_params = &state->params;
1438 struct stb0899_internal *internal = &state->internal;
1439 struct stb0899_config *config = state->config;
1440 struct dtv_frontend_properties *props = &fe->dtv_property_cache;
1441
1442 u32 SearchRange, gain;
1443
1444 i_params->freq = p->frequency;
1445 i_params->srate = p->u.qpsk.symbol_rate;
1446 state->delsys = props->delivery_system;
1447 dprintk(state->verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys);
1448
1449 SearchRange = 10000000;
1450 dprintk(state->verbose, FE_DEBUG, 1, "Frequency=%d, Srate=%d", i_params->freq, i_params->srate);
1451 /* checking Search Range is meaningless for a fixed 3 Mhz */
1452 if (INRANGE(i_params->srate, 1000000, 45000000)) {
1453 dprintk(state->verbose, FE_DEBUG, 1, "Parameters IN RANGE");
1454 stb0899_set_delivery(state);
1455
1456 if (state->config->tuner_set_rfsiggain) {
1457 if (internal->srate > 15000000)
1458 gain = 8; /* 15Mb < srate < 45Mb, gain = 8dB */
1459 else if (internal->srate > 5000000)
1460 gain = 12; /* 5Mb < srate < 15Mb, gain = 12dB */
1461 else
1462 gain = 14; /* 1Mb < srate < 5Mb, gain = 14db */
1463 state->config->tuner_set_rfsiggain(fe, gain);
1464 }
1465
1466 if (i_params->srate <= 5000000)
1467 stb0899_set_mclk(state, config->lo_clk);
1468 else
1469 stb0899_set_mclk(state, config->hi_clk);
1470
1471 switch (state->delsys) {
1472 case SYS_DVBS:
1473 case SYS_DSS:
1474 dprintk(state->verbose, FE_DEBUG, 1, "DVB-S delivery system");
1475 internal->freq = i_params->freq;
1476 internal->srate = i_params->srate;
1477 /*
1478 * search = user search range +
1479 * 500Khz +
1480 * 2 * Tuner_step_size +
1481 * 10% of the symbol rate
1482 */
1483 internal->srch_range = SearchRange + 1500000 + (i_params->srate / 5);
1484 internal->derot_percent = 30;
1485
1486 /* What to do for tuners having no bandwidth setup ? */
1487 /* enable tuner I/O */
1488 stb0899_i2c_gate_ctrl(&state->frontend, 1);
1489
1490 if (state->config->tuner_set_bandwidth)
1491 state->config->tuner_set_bandwidth(fe, (13 * (stb0899_carr_width(state) + SearchRange)) / 10);
1492 if (state->config->tuner_get_bandwidth)
1493 state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
1494
1495 /* disable tuner I/O */
1496 stb0899_i2c_gate_ctrl(&state->frontend, 0);
1497
1498 /* Set DVB-S1 AGC */
1499 stb0899_write_reg(state, STB0899_AGCRFCFG, 0x11);
1500
1501 /* Run the search algorithm */
1502 dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S search algo ..");
1503 if (stb0899_dvbs_algo(state) == RANGEOK) {
1504 internal->lock = 1;
1505 dprintk(state->verbose, FE_DEBUG, 1,
1506 "-------------------------------------> DVB-S LOCK !");
1507
1508// stb0899_write_reg(state, STB0899_ERRCTRL1, 0x3d); /* Viterbi Errors */
1509// internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS);
1510// internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1);
1511// dprintk(state->verbose, FE_DEBUG, 1, "VSTATUS=0x%02x", internal->v_status);
1512// dprintk(state->verbose, FE_DEBUG, 1, "ERR_CTRL=0x%02x", internal->err_ctrl);
1513
1514 return DVBFE_ALGO_SEARCH_SUCCESS;
1515 } else {
1516 internal->lock = 0;
1517
1518 return DVBFE_ALGO_SEARCH_FAILED;
1519 }
1520 break;
1521 case SYS_DVBS2:
1522 internal->freq = i_params->freq;
1523 internal->srate = i_params->srate;
1524 internal->srch_range = SearchRange;
1525
1526 /* enable tuner I/O */
1527 stb0899_i2c_gate_ctrl(&state->frontend, 1);
1528
1529 if (state->config->tuner_set_bandwidth)
1530 state->config->tuner_set_bandwidth(fe, (stb0899_carr_width(state) + SearchRange));
1531 if (state->config->tuner_get_bandwidth)
1532 state->config->tuner_get_bandwidth(fe, &internal->tuner_bw);
1533
1534 /* disable tuner I/O */
1535 stb0899_i2c_gate_ctrl(&state->frontend, 0);
1536
1537// pParams->SpectralInv = pSearch->IQ_Inversion;
1538
1539 /* Set DVB-S2 AGC */
1540 stb0899_write_reg(state, STB0899_AGCRFCFG, 0x1c);
1541
1542 /* Set IterScale =f(MCLK,SYMB) */
1543 stb0899_set_iterations(state);
1544
1545 /* Run the search algorithm */
1546 dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S2 search algo ..");
1547 if (stb0899_dvbs2_algo(state) == DVBS2_FEC_LOCK) {
1548 internal->lock = 1;
1549 dprintk(state->verbose, FE_DEBUG, 1,
1550 "-------------------------------------> DVB-S2 LOCK !");
1551
1552// stb0899_write_reg(state, STB0899_ERRCTRL1, 0xb6); /* Packet Errors */
1553// internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS);
1554// internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1);
1555
1556 return DVBFE_ALGO_SEARCH_SUCCESS;
1557 } else {
1558 internal->lock = 0;
1559
1560 return DVBFE_ALGO_SEARCH_FAILED;
1561 }
1562 break;
1563 default:
1564 dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system");
1565 return DVBFE_ALGO_SEARCH_INVALID;
1566 }
1567 }
1568
1569 return DVBFE_ALGO_SEARCH_ERROR;
1570}
1571/*
1572 * stb0899_track
1573 * periodically check the signal level against a specified
1574 * threshold level and perform derotator centering.
1575 * called once we have a lock from a successful search
1576 * event.
1577 *
1578 * Will be called periodically called to maintain the
1579 * lock.
1580 *
1581 * Will be used to get parameters as well as info from
1582 * the decoded baseband header
1583 *
1584 * Once a new lock has established, the internal state
1585 * frequency (internal->freq) is updated
1586 */
1587static int stb0899_track(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1588{
1589 return 0;
1590}
1591
1592static int stb0899_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1593{
1594 struct stb0899_state *state = fe->demodulator_priv;
1595 struct stb0899_internal *internal = &state->internal;
1596
1597 dprintk(state->verbose, FE_DEBUG, 1, "Get params");
1598 p->u.qpsk.symbol_rate = internal->srate;
1599
1600 return 0;
1601}
1602
1603static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe)
1604{
1605 return DVBFE_ALGO_CUSTOM;
1606}
1607
1608static struct dvb_frontend_ops stb0899_ops = {
1609
1610 .info = {
1611 .name = "STB0899 Multistandard",
1612 .type = FE_QPSK,
1613 .frequency_min = 950000,
1614 .frequency_max = 2150000,
1615 .frequency_stepsize = 0,
1616 .frequency_tolerance = 0,
1617 .symbol_rate_min = 5000000,
1618 .symbol_rate_max = 45000000,
1619
1620 .caps = FE_CAN_INVERSION_AUTO |
1621 FE_CAN_FEC_AUTO |
1622 FE_CAN_2G_MODULATION |
1623 FE_CAN_QPSK
1624 },
1625
1626 .release = stb0899_release,
1627 .init = stb0899_init,
1628 .sleep = stb0899_sleep,
1629// .wakeup = stb0899_wakeup,
1630
1631 .i2c_gate_ctrl = stb0899_i2c_gate_ctrl,
1632
1633 .get_frontend_algo = stb0899_frontend_algo,
1634 .search = stb0899_search,
1635 .track = stb0899_track,
1636 .get_frontend = stb0899_get_frontend,
1637
1638
1639 .read_status = stb0899_read_status,
1640 .read_snr = stb0899_read_snr,
1641 .read_signal_strength = stb0899_read_signal_strength,
1642 .read_ber = stb0899_read_ber,
1643
1644 .set_voltage = stb0899_set_voltage,
1645 .set_tone = stb0899_set_tone,
1646
1647 .diseqc_send_master_cmd = stb0899_send_diseqc_msg,
1648 .diseqc_recv_slave_reply = stb0899_recv_slave_reply,
1649 .diseqc_send_burst = stb0899_send_diseqc_burst,
1650};
1651
1652struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c)
1653{
1654 struct stb0899_state *state = NULL;
1655 enum stb0899_inversion inversion;
1656
1657 state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL);
1658 if (state == NULL)
1659 goto error;
1660
1661 inversion = config->inversion;
1662 state->verbose = &verbose;
1663 state->config = config;
1664 state->i2c = i2c;
1665 state->frontend.ops = stb0899_ops;
1666 state->frontend.demodulator_priv = state;
1667 state->internal.inversion = inversion;
1668
1669 stb0899_wakeup(&state->frontend);
1670 if (stb0899_get_dev_id(state) == -ENODEV) {
1671 printk("%s: Exiting .. !\n", __func__);
1672 goto error;
1673 }
1674
1675 printk("%s: Attaching STB0899 \n", __func__);
1676 return &state->frontend;
1677
1678error:
1679 kfree(state);
1680 return NULL;
1681}
1682EXPORT_SYMBOL(stb0899_attach);
1683MODULE_PARM_DESC(verbose, "Set Verbosity level");
1684MODULE_AUTHOR("Manu Abraham");
1685MODULE_DESCRIPTION("STB0899 Multi-Std frontend");
1686MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stb0899_drv.h b/drivers/media/dvb/frontends/stb0899_drv.h
new file mode 100644
index 00000000000..98b200ce0c3
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_drv.h
@@ -0,0 +1,162 @@
1/*
2 STB0899 Multistandard Frontend driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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#ifndef __STB0899_DRV_H
23#define __STB0899_DRV_H
24
25#include <linux/kernel.h>
26#include <linux/module.h>
27
28#include "dvb_frontend.h"
29
30#define STB0899_TSMODE_SERIAL 1
31#define STB0899_CLKPOL_FALLING 2
32#define STB0899_CLKNULL_PARITY 3
33#define STB0899_SYNC_FORCED 4
34#define STB0899_FECMODE_DSS 5
35
36struct stb0899_s1_reg {
37 u16 address;
38 u8 data;
39};
40
41struct stb0899_s2_reg {
42 u16 offset;
43 u32 base_address;
44 u32 data;
45};
46
47enum stb0899_inversion {
48 IQ_SWAP_OFF = 0,
49 IQ_SWAP_ON,
50 IQ_SWAP_AUTO
51};
52
53#define STB0899_GPIO00 0xf140
54#define STB0899_GPIO01 0xf141
55#define STB0899_GPIO02 0xf142
56#define STB0899_GPIO03 0xf143
57#define STB0899_GPIO04 0xf144
58#define STB0899_GPIO05 0xf145
59#define STB0899_GPIO06 0xf146
60#define STB0899_GPIO07 0xf147
61#define STB0899_GPIO08 0xf148
62#define STB0899_GPIO09 0xf149
63#define STB0899_GPIO10 0xf14a
64#define STB0899_GPIO11 0xf14b
65#define STB0899_GPIO12 0xf14c
66#define STB0899_GPIO13 0xf14d
67#define STB0899_GPIO14 0xf14e
68#define STB0899_GPIO15 0xf14f
69#define STB0899_GPIO16 0xf150
70#define STB0899_GPIO17 0xf151
71#define STB0899_GPIO18 0xf152
72#define STB0899_GPIO19 0xf153
73#define STB0899_GPIO20 0xf154
74
75#define STB0899_GPIOPULLUP 0x01 /* Output device is connected to Vdd */
76#define STB0899_GPIOPULLDN 0x00 /* Output device is connected to Vss */
77
78#define STB0899_POSTPROC_GPIO_POWER 0x00
79#define STB0899_POSTPROC_GPIO_LOCK 0x01
80
81/*
82 * Post process output configuration control
83 * 1. POWER ON/OFF (index 0)
84 * 2. FE_HAS_LOCK/LOCK_LOSS (index 1)
85 *
86 * @gpio = one of the above listed GPIO's
87 * @level = output state: pulled up or low
88 */
89struct stb0899_postproc {
90 u16 gpio;
91 u8 level;
92};
93
94struct stb0899_config {
95 const struct stb0899_s1_reg *init_dev;
96 const struct stb0899_s2_reg *init_s2_demod;
97 const struct stb0899_s1_reg *init_s1_demod;
98 const struct stb0899_s2_reg *init_s2_fec;
99 const struct stb0899_s1_reg *init_tst;
100
101 const struct stb0899_postproc *postproc;
102
103 enum stb0899_inversion inversion;
104
105 u32 xtal_freq;
106
107 u8 demod_address;
108 u8 ts_output_mode;
109 u8 block_sync_mode;
110 u8 ts_pfbit_toggle;
111
112 u8 clock_polarity;
113 u8 data_clk_parity;
114 u8 fec_mode;
115 u8 data_output_ctl;
116 u8 data_fifo_mode;
117 u8 out_rate_comp;
118 u8 i2c_repeater;
119// int inversion;
120 int lo_clk;
121 int hi_clk;
122
123 u32 esno_ave;
124 u32 esno_quant;
125 u32 avframes_coarse;
126 u32 avframes_fine;
127 u32 miss_threshold;
128 u32 uwp_threshold_acq;
129 u32 uwp_threshold_track;
130 u32 uwp_threshold_sof;
131 u32 sof_search_timeout;
132
133 u32 btr_nco_bits;
134 u32 btr_gain_shift_offset;
135 u32 crl_nco_bits;
136 u32 ldpc_max_iter;
137
138 int (*tuner_set_frequency)(struct dvb_frontend *fe, u32 frequency);
139 int (*tuner_get_frequency)(struct dvb_frontend *fe, u32 *frequency);
140 int (*tuner_set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
141 int (*tuner_get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
142 int (*tuner_set_rfsiggain)(struct dvb_frontend *fe, u32 rf_gain);
143};
144
145#if defined(CONFIG_DVB_STB0899) || (defined(CONFIG_DVB_STB0899_MODULE) && defined(MODULE))
146
147extern struct dvb_frontend *stb0899_attach(struct stb0899_config *config,
148 struct i2c_adapter *i2c);
149
150#else
151
152static inline struct dvb_frontend *stb0899_attach(struct stb0899_config *config,
153 struct i2c_adapter *i2c)
154{
155 printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
156 return NULL;
157}
158
159#endif //CONFIG_DVB_STB0899
160
161
162#endif
diff --git a/drivers/media/dvb/frontends/stb0899_priv.h b/drivers/media/dvb/frontends/stb0899_priv.h
new file mode 100644
index 00000000000..82395b91281
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_priv.h
@@ -0,0 +1,263 @@
1/*
2 STB0899 Multistandard Frontend driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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#ifndef __STB0899_PRIV_H
23#define __STB0899_PRIV_H
24
25#include "dvb_frontend.h"
26#include "stb0899_drv.h"
27
28#define FE_ERROR 0
29#define FE_NOTICE 1
30#define FE_INFO 2
31#define FE_DEBUG 3
32#define FE_DEBUGREG 4
33
34#define dprintk(x, y, z, format, arg...) do { \
35 if (z) { \
36 if ((*x > FE_ERROR) && (*x > y)) \
37 printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
38 else if ((*x > FE_NOTICE) && (*x > y)) \
39 printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
40 else if ((*x > FE_INFO) && (*x > y)) \
41 printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
42 else if ((*x > FE_DEBUG) && (*x > y)) \
43 printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
44 } else { \
45 if (*x > y) \
46 printk(format, ##arg); \
47 } \
48} while(0)
49
50#define INRANGE(val, x, y) (((x <= val) && (val <= y)) || \
51 ((y <= val) && (val <= x)) ? 1 : 0)
52
53#define BYTE0 0
54#define BYTE1 8
55#define BYTE2 16
56#define BYTE3 24
57
58#define GETBYTE(x, y) (((x) >> (y)) & 0xff)
59#define MAKEWORD32(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
60#define MAKEWORD16(a, b) (((a) << 8) | (b))
61
62#define LSB(x) ((x & 0xff))
63#define MSB(y) ((y >> 8) & 0xff)
64
65
66#define STB0899_GETFIELD(bitf, val) ((val >> STB0899_OFFST_##bitf) & ((1 << STB0899_WIDTH_##bitf) - 1))
67
68
69#define STB0899_SETFIELD(mask, val, width, offset) (mask & (~(((1 << width) - 1) << \
70 offset))) | ((val & \
71 ((1 << width) - 1)) << offset)
72
73#define STB0899_SETFIELD_VAL(bitf, mask, val) (mask = (mask & (~(((1 << STB0899_WIDTH_##bitf) - 1) <<\
74 STB0899_OFFST_##bitf))) | \
75 (val << STB0899_OFFST_##bitf))
76
77
78enum stb0899_status {
79 NOAGC1 = 0,
80 AGC1OK,
81 NOTIMING,
82 ANALOGCARRIER,
83 TIMINGOK,
84 NOAGC2,
85 AGC2OK,
86 NOCARRIER,
87 CARRIEROK,
88 NODATA,
89 FALSELOCK,
90 DATAOK,
91 OUTOFRANGE,
92 RANGEOK,
93 DVBS2_DEMOD_LOCK,
94 DVBS2_DEMOD_NOLOCK,
95 DVBS2_FEC_LOCK,
96 DVBS2_FEC_NOLOCK
97};
98
99enum stb0899_modcod {
100 STB0899_DUMMY_PLF,
101 STB0899_QPSK_14,
102 STB0899_QPSK_13,
103 STB0899_QPSK_25,
104 STB0899_QPSK_12,
105 STB0899_QPSK_35,
106 STB0899_QPSK_23,
107 STB0899_QPSK_34,
108 STB0899_QPSK_45,
109 STB0899_QPSK_56,
110 STB0899_QPSK_89,
111 STB0899_QPSK_910,
112 STB0899_8PSK_35,
113 STB0899_8PSK_23,
114 STB0899_8PSK_34,
115 STB0899_8PSK_56,
116 STB0899_8PSK_89,
117 STB0899_8PSK_910,
118 STB0899_16APSK_23,
119 STB0899_16APSK_34,
120 STB0899_16APSK_45,
121 STB0899_16APSK_56,
122 STB0899_16APSK_89,
123 STB0899_16APSK_910,
124 STB0899_32APSK_34,
125 STB0899_32APSK_45,
126 STB0899_32APSK_56,
127 STB0899_32APSK_89,
128 STB0899_32APSK_910
129};
130
131enum stb0899_frame {
132 STB0899_LONG_FRAME,
133 STB0899_SHORT_FRAME
134};
135
136enum stb0899_alpha {
137 RRC_20,
138 RRC_25,
139 RRC_35
140};
141
142struct stb0899_tab {
143 s32 real;
144 s32 read;
145};
146
147enum stb0899_fec {
148 STB0899_FEC_1_2 = 13,
149 STB0899_FEC_2_3 = 18,
150 STB0899_FEC_3_4 = 21,
151 STB0899_FEC_5_6 = 24,
152 STB0899_FEC_6_7 = 25,
153 STB0899_FEC_7_8 = 26
154};
155
156struct stb0899_params {
157 u32 freq; /* Frequency */
158 u32 srate; /* Symbol rate */
159 enum fe_code_rate fecrate;
160};
161
162struct stb0899_internal {
163 u32 master_clk;
164 u32 freq; /* Demod internal Frequency */
165 u32 srate; /* Demod internal Symbol rate */
166 enum stb0899_fec fecrate; /* Demod internal FEC rate */
167 s32 srch_range; /* Demod internal Search Range */
168 s32 sub_range; /* Demod current sub range (Hz) */
169 s32 tuner_step; /* Tuner step (Hz) */
170 s32 tuner_offst; /* Relative offset to carrier (Hz) */
171 u32 tuner_bw; /* Current bandwidth of the tuner (Hz) */
172
173 s32 mclk; /* Masterclock Divider factor (binary) */
174 s32 rolloff; /* Current RollOff of the filter (x100) */
175
176 s16 derot_freq; /* Current derotator frequency (Hz) */
177 s16 derot_percent;
178
179 s16 direction; /* Current derotator search direction */
180 s16 derot_step; /* Derotator step (binary value) */
181 s16 t_derot; /* Derotator time constant (ms) */
182 s16 t_data; /* Data recovery time constant (ms) */
183 s16 sub_dir; /* Direction of the next sub range */
184
185 s16 t_agc1; /* Agc1 time constant (ms) */
186 s16 t_agc2; /* Agc2 time constant (ms) */
187
188 u32 lock; /* Demod internal lock state */
189 enum stb0899_status status; /* Demod internal status */
190
191 /* DVB-S2 */
192 s32 agc_gain; /* RF AGC Gain */
193 s32 center_freq; /* Nominal carrier frequency */
194 s32 av_frame_coarse; /* Coarse carrier freq search frames */
195 s32 av_frame_fine; /* Fine carrier freq search frames */
196
197 s16 step_size; /* Carrier frequency search step size */
198
199 enum stb0899_alpha rrc_alpha;
200 enum stb0899_inversion inversion;
201 enum stb0899_modcod modcod;
202 u8 pilots; /* Pilots found */
203
204 enum stb0899_frame frame_length;
205 u8 v_status; /* VSTATUS */
206 u8 err_ctrl; /* ERRCTRLn */
207};
208
209struct stb0899_state {
210 struct i2c_adapter *i2c;
211 struct stb0899_config *config;
212 struct dvb_frontend frontend;
213
214 u32 *verbose; /* Cached module verbosity level */
215
216 struct stb0899_internal internal; /* Device internal parameters */
217
218 /* cached params from API */
219 enum fe_delivery_system delsys;
220 struct stb0899_params params;
221
222 u32 rx_freq; /* DiSEqC 2.0 receiver freq */
223 struct mutex search_lock;
224};
225/* stb0899.c */
226extern int stb0899_read_reg(struct stb0899_state *state,
227 unsigned int reg);
228
229extern u32 _stb0899_read_s2reg(struct stb0899_state *state,
230 u32 stb0899_i2cdev,
231 u32 stb0899_base_addr,
232 u16 stb0899_reg_offset);
233
234extern int stb0899_read_regs(struct stb0899_state *state,
235 unsigned int reg, u8 *buf,
236 u32 count);
237
238extern int stb0899_write_regs(struct stb0899_state *state,
239 unsigned int reg, u8 *data,
240 u32 count);
241
242extern int stb0899_write_reg(struct stb0899_state *state,
243 unsigned int reg,
244 u8 data);
245
246extern int stb0899_write_s2reg(struct stb0899_state *state,
247 u32 stb0899_i2cdev,
248 u32 stb0899_base_addr,
249 u16 stb0899_reg_offset,
250 u32 stb0899_data);
251
252extern int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
253
254
255#define STB0899_READ_S2REG(DEVICE, REG) (_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG))
256//#define STB0899_WRITE_S2REG(DEVICE, REG, DATA) (_stb0899_write_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG, DATA))
257
258/* stb0899_algo.c */
259extern enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state);
260extern enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state);
261extern long stb0899_carr_width(struct stb0899_state *state);
262
263#endif //__STB0899_PRIV_H
diff --git a/drivers/media/dvb/frontends/stb0899_reg.h b/drivers/media/dvb/frontends/stb0899_reg.h
new file mode 100644
index 00000000000..ba1ed56304a
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb0899_reg.h
@@ -0,0 +1,2027 @@
1/*
2 STB0899 Multistandard Frontend driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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#ifndef __STB0899_REG_H
23#define __STB0899_REG_H
24
25/* S1 */
26#define STB0899_DEV_ID 0xf000
27#define STB0899_CHIP_ID (0x0f << 4)
28#define STB0899_OFFST_CHIP_ID 4
29#define STB0899_WIDTH_CHIP_ID 4
30#define STB0899_CHIP_REL (0x0f << 0)
31#define STB0899_OFFST_CHIP_REL 0
32#define STB0899_WIDTH_CHIP_REL 4
33
34#define STB0899_DEMOD 0xf40e
35#define STB0899_MODECOEFF (0x01 << 0)
36#define STB0899_OFFST_MODECOEFF 0
37#define STB0899_WIDTH_MODECOEFF 1
38
39#define STB0899_RCOMPC 0xf410
40#define STB0899_AGC1CN 0xf412
41#define STB0899_AGC1REF 0xf413
42#define STB0899_RTC 0xf417
43#define STB0899_TMGCFG 0xf418
44#define STB0899_AGC2REF 0xf419
45#define STB0899_TLSR 0xf41a
46
47#define STB0899_CFD 0xf41b
48#define STB0899_CFD_ON (0x01 << 7)
49#define STB0899_OFFST_CFD_ON 7
50#define STB0899_WIDTH_CFD_ON 1
51
52#define STB0899_ACLC 0xf41c
53
54#define STB0899_BCLC 0xf41d
55#define STB0899_OFFST_ALGO 6
56#define STB0899_WIDTH_ALGO_QPSK2 2
57#define STB0899_ALGO_QPSK2 (2 << 6)
58#define STB0899_ALGO_QPSK1 (1 << 6)
59#define STB0899_ALGO_BPSK (0 << 6)
60#define STB0899_OFFST_BETA 0
61#define STB0899_WIDTH_BETA 6
62
63#define STB0899_EQON 0xf41e
64#define STB0899_LDT 0xf41f
65#define STB0899_LDT2 0xf420
66#define STB0899_EQUALREF 0xf425
67#define STB0899_TMGRAMP 0xf426
68#define STB0899_TMGTHD 0xf427
69#define STB0899_IDCCOMP 0xf428
70#define STB0899_QDCCOMP 0xf429
71#define STB0899_POWERI 0xf42a
72#define STB0899_POWERQ 0xf42b
73#define STB0899_RCOMP 0xf42c
74
75#define STB0899_AGCIQIN 0xf42e
76#define STB0899_AGCIQVALUE (0xff << 0)
77#define STB0899_OFFST_AGCIQVALUE 0
78#define STB0899_WIDTH_AGCIQVALUE 8
79
80#define STB0899_AGC2I1 0xf436
81#define STB0899_AGC2I2 0xf437
82
83#define STB0899_TLIR 0xf438
84#define STB0899_TLIR_TMG_LOCK_IND (0xff << 0)
85#define STB0899_OFFST_TLIR_TMG_LOCK_IND 0
86#define STB0899_WIDTH_TLIR_TMG_LOCK_IND 8
87
88#define STB0899_RTF 0xf439
89#define STB0899_RTF_TIMING_LOOP_FREQ (0xff << 0)
90#define STB0899_OFFST_RTF_TIMING_LOOP_FREQ 0
91#define STB0899_WIDTH_RTF_TIMING_LOOP_FREQ 8
92
93#define STB0899_DSTATUS 0xf43a
94#define STB0899_CARRIER_FOUND (0x01 << 7)
95#define STB0899_OFFST_CARRIER_FOUND 7
96#define STB0899_WIDTH_CARRIER_FOUND 1
97#define STB0899_TMG_LOCK (0x01 << 6)
98#define STB0899_OFFST_TMG_LOCK 6
99#define STB0899_WIDTH_TMG_LOCK 1
100#define STB0899_DEMOD_LOCK (0x01 << 5)
101#define STB0899_OFFST_DEMOD_LOCK 5
102#define STB0899_WIDTH_DEMOD_LOCK 1
103#define STB0899_TMG_AUTO (0x01 << 4)
104#define STB0899_OFFST_TMG_AUTO 4
105#define STB0899_WIDTH_TMG_AUTO 1
106#define STB0899_END_MAIN (0x01 << 3)
107#define STB0899_OFFST_END_MAIN 3
108#define STB0899_WIDTH_END_MAIN 1
109
110#define STB0899_LDI 0xf43b
111#define STB0899_OFFST_LDI 0
112#define STB0899_WIDTH_LDI 8
113
114#define STB0899_CFRM 0xf43e
115#define STB0899_OFFST_CFRM 0
116#define STB0899_WIDTH_CFRM 8
117
118#define STB0899_CFRL 0xf43f
119#define STB0899_OFFST_CFRL 0
120#define STB0899_WIDTH_CFRL 8
121
122#define STB0899_NIRM 0xf440
123#define STB0899_OFFST_NIRM 0
124#define STB0899_WIDTH_NIRM 8
125
126#define STB0899_NIRL 0xf441
127#define STB0899_OFFST_NIRL 0
128#define STB0899_WIDTH_NIRL 8
129
130#define STB0899_ISYMB 0xf444
131#define STB0899_QSYMB 0xf445
132
133#define STB0899_SFRH 0xf446
134#define STB0899_OFFST_SFRH 0
135#define STB0899_WIDTH_SFRH 8
136
137#define STB0899_SFRM 0xf447
138#define STB0899_OFFST_SFRM 0
139#define STB0899_WIDTH_SFRM 8
140
141#define STB0899_SFRL 0xf448
142#define STB0899_OFFST_SFRL 4
143#define STB0899_WIDTH_SFRL 4
144
145#define STB0899_SFRUPH 0xf44c
146#define STB0899_SFRUPM 0xf44d
147#define STB0899_SFRUPL 0xf44e
148
149#define STB0899_EQUAI1 0xf4e0
150#define STB0899_EQUAQ1 0xf4e1
151#define STB0899_EQUAI2 0xf4e2
152#define STB0899_EQUAQ2 0xf4e3
153#define STB0899_EQUAI3 0xf4e4
154#define STB0899_EQUAQ3 0xf4e5
155#define STB0899_EQUAI4 0xf4e6
156#define STB0899_EQUAQ4 0xf4e7
157#define STB0899_EQUAI5 0xf4e8
158#define STB0899_EQUAQ5 0xf4e9
159
160#define STB0899_DSTATUS2 0xf50c
161#define STB0899_DS2_TMG_AUTOSRCH (0x01 << 7)
162#define STB8999_OFFST_DS2_TMG_AUTOSRCH 7
163#define STB0899_WIDTH_DS2_TMG_AUTOSRCH 1
164#define STB0899_DS2_END_MAINLOOP (0x01 << 6)
165#define STB0899_OFFST_DS2_END_MAINLOOP 6
166#define STB0899_WIDTH_DS2_END_MAINLOOP 1
167#define STB0899_DS2_CFSYNC (0x01 << 5)
168#define STB0899_OFFST_DS2_CFSYNC 5
169#define STB0899_WIDTH_DS2_CFSYNC 1
170#define STB0899_DS2_TMGLOCK (0x01 << 4)
171#define STB0899_OFFST_DS2_TMGLOCK 4
172#define STB0899_WIDTH_DS2_TMGLOCK 1
173#define STB0899_DS2_DEMODWAIT (0x01 << 3)
174#define STB0899_OFFST_DS2_DEMODWAIT 3
175#define STB0899_WIDTH_DS2_DEMODWAIT 1
176#define STB0899_DS2_FECON (0x01 << 1)
177#define STB0899_OFFST_DS2_FECON 1
178#define STB0899_WIDTH_DS2_FECON 1
179
180/* S1 FEC */
181#define STB0899_VSTATUS 0xf50d
182#define STB0899_VSTATUS_VITERBI_ON (0x01 << 7)
183#define STB0899_OFFST_VSTATUS_VITERBI_ON 7
184#define STB0899_WIDTH_VSTATUS_VITERBI_ON 1
185#define STB0899_VSTATUS_END_LOOPVIT (0x01 << 6)
186#define STB0899_OFFST_VSTATUS_END_LOOPVIT 6
187#define STB0899_WIDTH_VSTATUS_END_LOOPVIT 1
188#define STB0899_VSTATUS_PRFVIT (0x01 << 4)
189#define STB0899_OFFST_VSTATUS_PRFVIT 4
190#define STB0899_WIDTH_VSTATUS_PRFVIT 1
191#define STB0899_VSTATUS_LOCKEDVIT (0x01 << 3)
192#define STB0899_OFFST_VSTATUS_LOCKEDVIT 3
193#define STB0899_WIDTH_VSTATUS_LOCKEDVIT 1
194
195#define STB0899_VERROR 0xf50f
196
197#define STB0899_IQSWAP 0xf523
198#define STB0899_SYM (0x01 << 3)
199#define STB0899_OFFST_SYM 3
200#define STB0899_WIDTH_SYM 1
201
202#define STB0899_FECAUTO1 0xf530
203#define STB0899_DSSSRCH (0x01 << 3)
204#define STB0899_OFFST_DSSSRCH 3
205#define STB0899_WIDTH_DSSSRCH 1
206#define STB0899_SYMSRCH (0x01 << 2)
207#define STB0899_OFFST_SYMSRCH 2
208#define STB0899_WIDTH_SYMSRCH 1
209#define STB0899_QPSKSRCH (0x01 << 1)
210#define STB0899_OFFST_QPSKSRCH 1
211#define STB0899_WIDTH_QPSKSRCH 1
212#define STB0899_BPSKSRCH (0x01 << 0)
213#define STB0899_OFFST_BPSKSRCH 0
214#define STB0899_WIDTH_BPSKSRCH 1
215
216#define STB0899_FECM 0xf533
217#define STB0899_FECM_NOT_DVB (0x01 << 7)
218#define STB0899_OFFST_FECM_NOT_DVB 7
219#define STB0899_WIDTH_FECM_NOT_DVB 1
220#define STB0899_FECM_RSVD1 (0x07 << 4)
221#define STB0899_OFFST_FECM_RSVD1 4
222#define STB0899_WIDTH_FECM_RSVD1 3
223#define STB0899_FECM_VITERBI_ON (0x01 << 3)
224#define STB0899_OFFST_FECM_VITERBI_ON 3
225#define STB0899_WIDTH_FECM_VITERBI_ON 1
226#define STB0899_FECM_RSVD0 (0x01 << 2)
227#define STB0899_OFFST_FECM_RSVD0 2
228#define STB0899_WIDTH_FECM_RSVD0 1
229#define STB0899_FECM_SYNCDIS (0x01 << 1)
230#define STB0899_OFFST_FECM_SYNCDIS 1
231#define STB0899_WIDTH_FECM_SYNCDIS 1
232#define STB0899_FECM_SYMI (0x01 << 0)
233#define STB0899_OFFST_FECM_SYMI 0
234#define STB0899_WIDTH_FECM_SYMI 1
235
236#define STB0899_VTH12 0xf534
237#define STB0899_VTH23 0xf535
238#define STB0899_VTH34 0xf536
239#define STB0899_VTH56 0xf537
240#define STB0899_VTH67 0xf538
241#define STB0899_VTH78 0xf539
242
243#define STB0899_PRVIT 0xf53c
244#define STB0899_PR_7_8 (0x01 << 5)
245#define STB0899_OFFST_PR_7_8 5
246#define STB0899_WIDTH_PR_7_8 1
247#define STB0899_PR_6_7 (0x01 << 4)
248#define STB0899_OFFST_PR_6_7 4
249#define STB0899_WIDTH_PR_6_7 1
250#define STB0899_PR_5_6 (0x01 << 3)
251#define STB0899_OFFST_PR_5_6 3
252#define STB0899_WIDTH_PR_5_6 1
253#define STB0899_PR_3_4 (0x01 << 2)
254#define STB0899_OFFST_PR_3_4 2
255#define STB0899_WIDTH_PR_3_4 1
256#define STB0899_PR_2_3 (0x01 << 1)
257#define STB0899_OFFST_PR_2_3 1
258#define STB0899_WIDTH_PR_2_3 1
259#define STB0899_PR_1_2 (0x01 << 0)
260#define STB0899_OFFST_PR_1_2 0
261#define STB0899_WIDTH_PR_1_2 1
262
263#define STB0899_VITSYNC 0xf53d
264#define STB0899_AM (0x01 << 7)
265#define STB0899_OFFST_AM 7
266#define STB0899_WIDTH_AM 1
267#define STB0899_FREEZE (0x01 << 6)
268#define STB0899_OFFST_FREEZE 6
269#define STB0899_WIDTH_FREEZE 1
270#define STB0899_SN_65536 (0x03 << 4)
271#define STB0899_OFFST_SN_65536 4
272#define STB0899_WIDTH_SN_65536 2
273#define STB0899_SN_16384 (0x01 << 5)
274#define STB0899_OFFST_SN_16384 5
275#define STB0899_WIDTH_SN_16384 1
276#define STB0899_SN_4096 (0x01 << 4)
277#define STB0899_OFFST_SN_4096 4
278#define STB0899_WIDTH_SN_4096 1
279#define STB0899_SN_1024 (0x00 << 4)
280#define STB0899_OFFST_SN_1024 4
281#define STB0899_WIDTH_SN_1024 0
282#define STB0899_TO_128 (0x03 << 2)
283#define STB0899_OFFST_TO_128 2
284#define STB0899_WIDTH_TO_128 2
285#define STB0899_TO_64 (0x01 << 3)
286#define STB0899_OFFST_TO_64 3
287#define STB0899_WIDTH_TO_64 1
288#define STB0899_TO_32 (0x01 << 2)
289#define STB0899_OFFST_TO_32 2
290#define STB0899_WIDTH_TO_32 1
291#define STB0899_TO_16 (0x00 << 2)
292#define STB0899_OFFST_TO_16 2
293#define STB0899_WIDTH_TO_16 0
294#define STB0899_HYST_128 (0x03 << 1)
295#define STB0899_OFFST_HYST_128 1
296#define STB0899_WIDTH_HYST_128 2
297#define STB0899_HYST_64 (0x01 << 1)
298#define STB0899_OFFST_HYST_64 1
299#define STB0899_WIDTH_HYST_64 1
300#define STB0899_HYST_32 (0x01 << 0)
301#define STB0899_OFFST_HYST_32 0
302#define STB0899_WIDTH_HYST_32 1
303#define STB0899_HYST_16 (0x00 << 0)
304#define STB0899_OFFST_HYST_16 0
305#define STB0899_WIDTH_HYST_16 0
306
307#define STB0899_RSULC 0xf548
308#define STB0899_ULDIL_ON (0x01 << 7)
309#define STB0899_OFFST_ULDIL_ON 7
310#define STB0899_WIDTH_ULDIL_ON 1
311#define STB0899_ULAUTO_ON (0x01 << 6)
312#define STB0899_OFFST_ULAUTO_ON 6
313#define STB0899_WIDTH_ULAUTO_ON 1
314#define STB0899_ULRS_ON (0x01 << 5)
315#define STB0899_OFFST_ULRS_ON 5
316#define STB0899_WIDTH_ULRS_ON 1
317#define STB0899_ULDESCRAM_ON (0x01 << 4)
318#define STB0899_OFFST_ULDESCRAM_ON 4
319#define STB0899_WIDTH_ULDESCRAM_ON 1
320#define STB0899_UL_DISABLE (0x01 << 2)
321#define STB0899_OFFST_UL_DISABLE 2
322#define STB0899_WIDTH_UL_DISABLE 1
323#define STB0899_NOFTHRESHOLD (0x01 << 0)
324#define STB0899_OFFST_NOFTHRESHOLD 0
325#define STB0899_WIDTH_NOFTHRESHOLD 1
326
327#define STB0899_RSLLC 0xf54a
328#define STB0899_DEMAPVIT 0xf583
329#define STB0899_DEMAPVIT_RSVD (0x01 << 7)
330#define STB0899_OFFST_DEMAPVIT_RSVD 7
331#define STB0899_WIDTH_DEMAPVIT_RSVD 1
332#define STB0899_DEMAPVIT_KDIVIDER (0x7f << 0)
333#define STB0899_OFFST_DEMAPVIT_KDIVIDER 0
334#define STB0899_WIDTH_DEMAPVIT_KDIVIDER 7
335
336#define STB0899_PLPARM 0xf58c
337#define STB0899_VITMAPPING (0x07 << 5)
338#define STB0899_OFFST_VITMAPPING 5
339#define STB0899_WIDTH_VITMAPPING 3
340#define STB0899_VITMAPPING_BPSK (0x01 << 5)
341#define STB0899_OFFST_VITMAPPING_BPSK 5
342#define STB0899_WIDTH_VITMAPPING_BPSK 1
343#define STB0899_VITMAPPING_QPSK (0x00 << 5)
344#define STB0899_OFFST_VITMAPPING_QPSK 5
345#define STB0899_WIDTH_VITMAPPING_QPSK 0
346#define STB0899_VITCURPUN (0x1f << 0)
347#define STB0899_OFFST_VITCURPUN 0
348#define STB0899_WIDTH_VITCURPUN 5
349#define STB0899_VITCURPUN_1_2 (0x0d << 0)
350#define STB0899_VITCURPUN_2_3 (0x12 << 0)
351#define STB0899_VITCURPUN_3_4 (0x15 << 0)
352#define STB0899_VITCURPUN_5_6 (0x18 << 0)
353#define STB0899_VITCURPUN_6_7 (0x19 << 0)
354#define STB0899_VITCURPUN_7_8 (0x1a << 0)
355
356/* S2 DEMOD */
357#define STB0899_OFF0_DMD_STATUS 0xf300
358#define STB0899_BASE_DMD_STATUS 0x00000000
359#define STB0899_IF_AGC_LOCK (0x01 << 8)
360#define STB0899_OFFST_IF_AGC_LOCK 0
361#define STB0899_WIDTH_IF_AGC_LOCK 1
362
363#define STB0899_OFF0_CRL_FREQ 0xf304
364#define STB0899_BASE_CRL_FREQ 0x00000000
365#define STB0899_CARR_FREQ (0x3fffffff << 0)
366#define STB0899_OFFST_CARR_FREQ 0
367#define STB0899_WIDTH_CARR_FREQ 30
368
369#define STB0899_OFF0_BTR_FREQ 0xf308
370#define STB0899_BASE_BTR_FREQ 0x00000000
371#define STB0899_BTR_FREQ (0xfffffff << 0)
372#define STB0899_OFFST_BTR_FREQ 0
373#define STB0899_WIDTH_BTR_FREQ 28
374
375#define STB0899_OFF0_IF_AGC_GAIN 0xf30c
376#define STB0899_BASE_IF_AGC_GAIN 0x00000000
377#define STB0899_IF_AGC_GAIN (0x3fff < 0)
378#define STB0899_OFFST_IF_AGC_GAIN 0
379#define STB0899_WIDTH_IF_AGC_GAIN 14
380
381#define STB0899_OFF0_BB_AGC_GAIN 0xf310
382#define STB0899_BASE_BB_AGC_GAIN 0x00000000
383#define STB0899_BB_AGC_GAIN (0x3fff < 0)
384#define STB0899_OFFST_BB_AGC_GAIN 0
385#define STB0899_WIDTH_BB_AGC_GAIN 14
386
387#define STB0899_OFF0_DC_OFFSET 0xf314
388#define STB0899_BASE_DC_OFFSET 0x00000000
389#define STB0899_I (0xff < 8)
390#define STB0899_OFFST_I 8
391#define STB0899_WIDTH_I 8
392#define STB0899_Q (0xff < 0)
393#define STB0899_OFFST_Q 8
394#define STB0899_WIDTH_Q 8
395
396#define STB0899_OFF0_DMD_CNTRL 0xf31c
397#define STB0899_BASE_DMD_CNTRL 0x00000000
398#define STB0899_ADC0_PINS1IN (0x01 << 6)
399#define STB0899_OFFST_ADC0_PINS1IN 6
400#define STB0899_WIDTH_ADC0_PINS1IN 1
401#define STB0899_IN2COMP1_OFFBIN0 (0x01 << 3)
402#define STB0899_OFFST_IN2COMP1_OFFBIN0 3
403#define STB0899_WIDTH_IN2COMP1_OFFBIN0 1
404#define STB0899_DC_COMP (0x01 << 2)
405#define STB0899_OFFST_DC_COMP 2
406#define STB0899_WIDTH_DC_COMP 1
407#define STB0899_MODMODE (0x03 << 0)
408#define STB0899_OFFST_MODMODE 0
409#define STB0899_WIDTH_MODMODE 2
410
411#define STB0899_OFF0_IF_AGC_CNTRL 0xf320
412#define STB0899_BASE_IF_AGC_CNTRL 0x00000000
413#define STB0899_IF_GAIN_INIT (0x3fff << 13)
414#define STB0899_OFFST_IF_GAIN_INIT 13
415#define STB0899_WIDTH_IF_GAIN_INIT 14
416#define STB0899_IF_GAIN_SENSE (0x01 << 12)
417#define STB0899_OFFST_IF_GAIN_SENSE 12
418#define STB0899_WIDTH_IF_GAIN_SENSE 1
419#define STB0899_IF_LOOP_GAIN (0x0f << 8)
420#define STB0899_OFFST_IF_LOOP_GAIN 8
421#define STB0899_WIDTH_IF_LOOP_GAIN 4
422#define STB0899_IF_LD_GAIN_INIT (0x01 << 7)
423#define STB0899_OFFST_IF_LD_GAIN_INIT 7
424#define STB0899_WIDTH_IF_LD_GAIN_INIT 1
425#define STB0899_IF_AGC_REF (0x7f << 0)
426#define STB0899_OFFST_IF_AGC_REF 0
427#define STB0899_WIDTH_IF_AGC_REF 7
428
429#define STB0899_OFF0_BB_AGC_CNTRL 0xf324
430#define STB0899_BASE_BB_AGC_CNTRL 0x00000000
431#define STB0899_BB_GAIN_INIT (0x3fff << 12)
432#define STB0899_OFFST_BB_GAIN_INIT 12
433#define STB0899_WIDTH_BB_GAIN_INIT 14
434#define STB0899_BB_LOOP_GAIN (0x0f << 8)
435#define STB0899_OFFST_BB_LOOP_GAIN 8
436#define STB0899_WIDTH_BB_LOOP_GAIN 4
437#define STB0899_BB_LD_GAIN_INIT (0x01 << 7)
438#define STB0899_OFFST_BB_LD_GAIN_INIT 7
439#define STB0899_WIDTH_BB_LD_GAIN_INIT 1
440#define STB0899_BB_AGC_REF (0x7f << 0)
441#define STB0899_OFFST_BB_AGC_REF 0
442#define STB0899_WIDTH_BB_AGC_REF 7
443
444#define STB0899_OFF0_CRL_CNTRL 0xf328
445#define STB0899_BASE_CRL_CNTRL 0x00000000
446#define STB0899_CRL_LOCK_CLEAR (0x01 << 5)
447#define STB0899_OFFST_CRL_LOCK_CLEAR 5
448#define STB0899_WIDTH_CRL_LOCK_CLEAR 1
449#define STB0899_CRL_SWPR_CLEAR (0x01 << 4)
450#define STB0899_OFFST_CRL_SWPR_CLEAR 4
451#define STB0899_WIDTH_CRL_SWPR_CLEAR 1
452#define STB0899_CRL_SWP_ENA (0x01 << 3)
453#define STB0899_OFFST_CRL_SWP_ENA 3
454#define STB0899_WIDTH_CRL_SWP_ENA 1
455#define STB0899_CRL_DET_SEL (0x01 << 2)
456#define STB0899_OFFST_CRL_DET_SEL 2
457#define STB0899_WIDTH_CRL_DET_SEL 1
458#define STB0899_CRL_SENSE (0x01 << 1)
459#define STB0899_OFFST_CRL_SENSE 1
460#define STB0899_WIDTH_CRL_SENSE 1
461#define STB0899_CRL_PHSERR_CLEAR (0x01 << 0)
462#define STB0899_OFFST_CRL_PHSERR_CLEAR 0
463#define STB0899_WIDTH_CRL_PHSERR_CLEAR 1
464
465#define STB0899_OFF0_CRL_PHS_INIT 0xf32c
466#define STB0899_BASE_CRL_PHS_INIT 0x00000000
467#define STB0899_CRL_PHS_INIT_31 (0x1 << 30)
468#define STB0899_OFFST_CRL_PHS_INIT_31 30
469#define STB0899_WIDTH_CRL_PHS_INIT_31 1
470#define STB0899_CRL_LD_INIT_PHASE (0x1 << 24)
471#define STB0899_OFFST_CRL_LD_INIT_PHASE 24
472#define STB0899_WIDTH_CRL_LD_INIT_PHASE 1
473#define STB0899_CRL_INIT_PHASE (0xffffff << 0)
474#define STB0899_OFFST_CRL_INIT_PHASE 0
475#define STB0899_WIDTH_CRL_INIT_PHASE 24
476
477#define STB0899_OFF0_CRL_FREQ_INIT 0xf330
478#define STB0899_BASE_CRL_FREQ_INIT 0x00000000
479#define STB0899_CRL_FREQ_INIT_31 (0x1 << 30)
480#define STB0899_OFFST_CRL_FREQ_INIT_31 30
481#define STB0899_WIDTH_CRL_FREQ_INIT_31 1
482#define STB0899_CRL_LD_FREQ_INIT (0x1 << 24)
483#define STB0899_OFFST_CRL_LD_FREQ_INIT 24
484#define STB0899_WIDTH_CRL_LD_FREQ_INIT 1
485#define STB0899_CRL_FREQ_INIT (0xffffff << 0)
486#define STB0899_OFFST_CRL_FREQ_INIT 0
487#define STB0899_WIDTH_CRL_FREQ_INIT 24
488
489#define STB0899_OFF0_CRL_LOOP_GAIN 0xf334
490#define STB0899_BASE_CRL_LOOP_GAIN 0x00000000
491#define STB0899_KCRL2_RSHFT (0xf << 16)
492#define STB0899_OFFST_KCRL2_RSHFT 16
493#define STB0899_WIDTH_KCRL2_RSHFT 4
494#define STB0899_KCRL1 (0xf << 12)
495#define STB0899_OFFST_KCRL1 12
496#define STB0899_WIDTH_KCRL1 4
497#define STB0899_KCRL1_RSHFT (0xf << 8)
498#define STB0899_OFFST_KCRL1_RSHFT 8
499#define STB0899_WIDTH_KCRL1_RSHFT 4
500#define STB0899_KCRL0 (0xf << 4)
501#define STB0899_OFFST_KCRL0 4
502#define STB0899_WIDTH_KCRL0 4
503#define STB0899_KCRL0_RSHFT (0xf << 0)
504#define STB0899_OFFST_KCRL0_RSHFT 0
505#define STB0899_WIDTH_KCRL0_RSHFT 4
506
507#define STB0899_OFF0_CRL_NOM_FREQ 0xf338
508#define STB0899_BASE_CRL_NOM_FREQ 0x00000000
509#define STB0899_CRL_NOM_FREQ (0x3fffffff << 0)
510#define STB0899_OFFST_CRL_NOM_FREQ 0
511#define STB0899_WIDTH_CRL_NOM_FREQ 30
512
513#define STB0899_OFF0_CRL_SWP_RATE 0xf33c
514#define STB0899_BASE_CRL_SWP_RATE 0x00000000
515#define STB0899_CRL_SWP_RATE (0x3fffffff << 0)
516#define STB0899_OFFST_CRL_SWP_RATE 0
517#define STB0899_WIDTH_CRL_SWP_RATE 30
518
519#define STB0899_OFF0_CRL_MAX_SWP 0xf340
520#define STB0899_BASE_CRL_MAX_SWP 0x00000000
521#define STB0899_CRL_MAX_SWP (0x3fffffff << 0)
522#define STB0899_OFFST_CRL_MAX_SWP 0
523#define STB0899_WIDTH_CRL_MAX_SWP 30
524
525#define STB0899_OFF0_CRL_LK_CNTRL 0xf344
526#define STB0899_BASE_CRL_LK_CNTRL 0x00000000
527
528#define STB0899_OFF0_DECIM_CNTRL 0xf348
529#define STB0899_BASE_DECIM_CNTRL 0x00000000
530#define STB0899_BAND_LIMIT_B (0x01 << 5)
531#define STB0899_OFFST_BAND_LIMIT_B 5
532#define STB0899_WIDTH_BAND_LIMIT_B 1
533#define STB0899_WIN_SEL (0x03 << 3)
534#define STB0899_OFFST_WIN_SEL 3
535#define STB0899_WIDTH_WIN_SEL 2
536#define STB0899_DECIM_RATE (0x07 << 0)
537#define STB0899_OFFST_DECIM_RATE 0
538#define STB0899_WIDTH_DECIM_RATE 3
539
540#define STB0899_OFF0_BTR_CNTRL 0xf34c
541#define STB0899_BASE_BTR_CNTRL 0x00000000
542#define STB0899_BTR_FREQ_CORR (0x7ff << 4)
543#define STB0899_OFFST_BTR_FREQ_CORR 4
544#define STB0899_WIDTH_BTR_FREQ_CORR 11
545#define STB0899_BTR_CLR_LOCK (0x01 << 3)
546#define STB0899_OFFST_BTR_CLR_LOCK 3
547#define STB0899_WIDTH_BTR_CLR_LOCK 1
548#define STB0899_BTR_SENSE (0x01 << 2)
549#define STB0899_OFFST_BTR_SENSE 2
550#define STB0899_WIDTH_BTR_SENSE 1
551#define STB0899_BTR_ERR_ENA (0x01 << 1)
552#define STB0899_OFFST_BTR_ERR_ENA 1
553#define STB0899_WIDTH_BTR_ERR_ENA 1
554#define STB0899_INTRP_PHS_SENSE (0x01 << 0)
555#define STB0899_OFFST_INTRP_PHS_SENSE 0
556#define STB0899_WIDTH_INTRP_PHS_SENSE 1
557
558#define STB0899_OFF0_BTR_LOOP_GAIN 0xf350
559#define STB0899_BASE_BTR_LOOP_GAIN 0x00000000
560#define STB0899_KBTR2_RSHFT (0x0f << 16)
561#define STB0899_OFFST_KBTR2_RSHFT 16
562#define STB0899_WIDTH_KBTR2_RSHFT 4
563#define STB0899_KBTR1 (0x0f << 12)
564#define STB0899_OFFST_KBTR1 12
565#define STB0899_WIDTH_KBTR1 4
566#define STB0899_KBTR1_RSHFT (0x0f << 8)
567#define STB0899_OFFST_KBTR1_RSHFT 8
568#define STB0899_WIDTH_KBTR1_RSHFT 4
569#define STB0899_KBTR0 (0x0f << 4)
570#define STB0899_OFFST_KBTR0 4
571#define STB0899_WIDTH_KBTR0 4
572#define STB0899_KBTR0_RSHFT (0x0f << 0)
573#define STB0899_OFFST_KBTR0_RSHFT 0
574#define STB0899_WIDTH_KBTR0_RSHFT 4
575
576#define STB0899_OFF0_BTR_PHS_INIT 0xf354
577#define STB0899_BASE_BTR_PHS_INIT 0x00000000
578#define STB0899_BTR_LD_PHASE_INIT (0x01 << 28)
579#define STB0899_OFFST_BTR_LD_PHASE_INIT 28
580#define STB0899_WIDTH_BTR_LD_PHASE_INIT 1
581#define STB0899_BTR_INIT_PHASE (0xfffffff << 0)
582#define STB0899_OFFST_BTR_INIT_PHASE 0
583#define STB0899_WIDTH_BTR_INIT_PHASE 28
584
585#define STB0899_OFF0_BTR_FREQ_INIT 0xf358
586#define STB0899_BASE_BTR_FREQ_INIT 0x00000000
587#define STB0899_BTR_LD_FREQ_INIT (1 << 28)
588#define STB0899_OFFST_BTR_LD_FREQ_INIT 28
589#define STB0899_WIDTH_BTR_LD_FREQ_INIT 1
590#define STB0899_BTR_FREQ_INIT (0xfffffff << 0)
591#define STB0899_OFFST_BTR_FREQ_INIT 0
592#define STB0899_WIDTH_BTR_FREQ_INIT 28
593
594#define STB0899_OFF0_BTR_NOM_FREQ 0xf35c
595#define STB0899_BASE_BTR_NOM_FREQ 0x00000000
596#define STB0899_BTR_NOM_FREQ (0xfffffff << 0)
597#define STB0899_OFFST_BTR_NOM_FREQ 0
598#define STB0899_WIDTH_BTR_NOM_FREQ 28
599
600#define STB0899_OFF0_BTR_LK_CNTRL 0xf360
601#define STB0899_BASE_BTR_LK_CNTRL 0x00000000
602#define STB0899_BTR_MIN_ENERGY (0x0f << 24)
603#define STB0899_OFFST_BTR_MIN_ENERGY 24
604#define STB0899_WIDTH_BTR_MIN_ENERGY 4
605#define STB0899_BTR_LOCK_TH_LO (0xff << 16)
606#define STB0899_OFFST_BTR_LOCK_TH_LO 16
607#define STB0899_WIDTH_BTR_LOCK_TH_LO 8
608#define STB0899_BTR_LOCK_TH_HI (0xff << 8)
609#define STB0899_OFFST_BTR_LOCK_TH_HI 8
610#define STB0899_WIDTH_BTR_LOCK_TH_HI 8
611#define STB0899_BTR_LOCK_GAIN (0x03 << 6)
612#define STB0899_OFFST_BTR_LOCK_GAIN 6
613#define STB0899_WIDTH_BTR_LOCK_GAIN 2
614#define STB0899_BTR_LOCK_LEAK (0x3f << 0)
615#define STB0899_OFFST_BTR_LOCK_LEAK 0
616#define STB0899_WIDTH_BTR_LOCK_LEAK 6
617
618#define STB0899_OFF0_DECN_CNTRL 0xf364
619#define STB0899_BASE_DECN_CNTRL 0x00000000
620
621#define STB0899_OFF0_TP_CNTRL 0xf368
622#define STB0899_BASE_TP_CNTRL 0x00000000
623
624#define STB0899_OFF0_TP_BUF_STATUS 0xf36c
625#define STB0899_BASE_TP_BUF_STATUS 0x00000000
626#define STB0899_TP_BUFFER_FULL (1 << 0)
627
628#define STB0899_OFF0_DC_ESTIM 0xf37c
629#define STB0899_BASE_DC_ESTIM 0x0000
630#define STB0899_I_DC_ESTIMATE (0xff << 8)
631#define STB0899_OFFST_I_DC_ESTIMATE 8
632#define STB0899_WIDTH_I_DC_ESTIMATE 8
633#define STB0899_Q_DC_ESTIMATE (0xff << 0)
634#define STB0899_OFFST_Q_DC_ESTIMATE 0
635#define STB0899_WIDTH_Q_DC_ESTIMATE 8
636
637#define STB0899_OFF0_FLL_CNTRL 0xf310
638#define STB0899_BASE_FLL_CNTRL 0x00000020
639#define STB0899_CRL_FLL_ACC (0x01 << 4)
640#define STB0899_OFFST_CRL_FLL_ACC 4
641#define STB0899_WIDTH_CRL_FLL_ACC 1
642#define STB0899_FLL_AVG_PERIOD (0x0f << 0)
643#define STB0899_OFFST_FLL_AVG_PERIOD 0
644#define STB0899_WIDTH_FLL_AVG_PERIOD 4
645
646#define STB0899_OFF0_FLL_FREQ_WD 0xf314
647#define STB0899_BASE_FLL_FREQ_WD 0x00000020
648#define STB0899_FLL_FREQ_WD (0xffffffff << 0)
649#define STB0899_OFFST_FLL_FREQ_WD 0
650#define STB0899_WIDTH_FLL_FREQ_WD 32
651
652#define STB0899_OFF0_ANTI_ALIAS_SEL 0xf358
653#define STB0899_BASE_ANTI_ALIAS_SEL 0x00000020
654#define STB0899_ANTI_ALIAS_SELB (0x03 << 0)
655#define STB0899_OFFST_ANTI_ALIAS_SELB 0
656#define STB0899_WIDTH_ANTI_ALIAS_SELB 2
657
658#define STB0899_OFF0_RRC_ALPHA 0xf35c
659#define STB0899_BASE_RRC_ALPHA 0x00000020
660#define STB0899_RRC_ALPHA (0x03 << 0)
661#define STB0899_OFFST_RRC_ALPHA 0
662#define STB0899_WIDTH_RRC_ALPHA 2
663
664#define STB0899_OFF0_DC_ADAPT_LSHFT 0xf360
665#define STB0899_BASE_DC_ADAPT_LSHFT 0x00000020
666#define STB0899_DC_ADAPT_LSHFT (0x077 << 0)
667#define STB0899_OFFST_DC_ADAPT_LSHFT 0
668#define STB0899_WIDTH_DC_ADAPT_LSHFT 3
669
670#define STB0899_OFF0_IMB_OFFSET 0xf364
671#define STB0899_BASE_IMB_OFFSET 0x00000020
672#define STB0899_PHS_IMB_COMP (0xff << 8)
673#define STB0899_OFFST_PHS_IMB_COMP 8
674#define STB0899_WIDTH_PHS_IMB_COMP 8
675#define STB0899_AMPL_IMB_COMP (0xff << 0)
676#define STB0899_OFFST_AMPL_IMB_COMP 0
677#define STB0899_WIDTH_AMPL_IMB_COMP 8
678
679#define STB0899_OFF0_IMB_ESTIMATE 0xf368
680#define STB0899_BASE_IMB_ESTIMATE 0x00000020
681#define STB0899_PHS_IMB_ESTIMATE (0xff << 8)
682#define STB0899_OFFST_PHS_IMB_ESTIMATE 8
683#define STB0899_WIDTH_PHS_IMB_ESTIMATE 8
684#define STB0899_AMPL_IMB_ESTIMATE (0xff << 0)
685#define STB0899_OFFST_AMPL_IMB_ESTIMATE 0
686#define STB0899_WIDTH_AMPL_IMB_ESTIMATE 8
687
688#define STB0899_OFF0_IMB_CNTRL 0xf36c
689#define STB0899_BASE_IMB_CNTRL 0x00000020
690#define STB0899_PHS_ADAPT_LSHFT (0x07 << 4)
691#define STB0899_OFFST_PHS_ADAPT_LSHFT 4
692#define STB0899_WIDTH_PHS_ADAPT_LSHFT 3
693#define STB0899_AMPL_ADAPT_LSHFT (0x07 << 1)
694#define STB0899_OFFST_AMPL_ADAPT_LSHFT 1
695#define STB0899_WIDTH_AMPL_ADAPT_LSHFT 3
696#define STB0899_IMB_COMP (0x01 << 0)
697#define STB0899_OFFST_IMB_COMP 0
698#define STB0899_WIDTH_IMB_COMP 1
699
700#define STB0899_OFF0_IF_AGC_CNTRL2 0xf374
701#define STB0899_BASE_IF_AGC_CNTRL2 0x00000020
702#define STB0899_IF_AGC_LOCK_TH (0xff << 11)
703#define STB0899_OFFST_IF_AGC_LOCK_TH 11
704#define STB0899_WIDTH_IF_AGC_LOCK_TH 8
705#define STB0899_IF_AGC_SD_DIV (0xff << 3)
706#define STB0899_OFFST_IF_AGC_SD_DIV 3
707#define STB0899_WIDTH_IF_AGC_SD_DIV 8
708#define STB0899_IF_AGC_DUMP_PER (0x07 << 0)
709#define STB0899_OFFST_IF_AGC_DUMP_PER 0
710#define STB0899_WIDTH_IF_AGC_DUMP_PER 3
711
712#define STB0899_OFF0_DMD_CNTRL2 0xf378
713#define STB0899_BASE_DMD_CNTRL2 0x00000020
714#define STB0899_SPECTRUM_INVERT (0x01 << 2)
715#define STB0899_OFFST_SPECTRUM_INVERT 2
716#define STB0899_WIDTH_SPECTRUM_INVERT 1
717#define STB0899_AGC_MODE (0x01 << 1)
718#define STB0899_OFFST_AGC_MODE 1
719#define STB0899_WIDTH_AGC_MODE 1
720#define STB0899_CRL_FREQ_ADJ (0x01 << 0)
721#define STB0899_OFFST_CRL_FREQ_ADJ 0
722#define STB0899_WIDTH_CRL_FREQ_ADJ 1
723
724#define STB0899_OFF0_TP_BUFFER 0xf300
725#define STB0899_BASE_TP_BUFFER 0x00000040
726#define STB0899_TP_BUFFER_IN (0xffff << 0)
727#define STB0899_OFFST_TP_BUFFER_IN 0
728#define STB0899_WIDTH_TP_BUFFER_IN 16
729
730#define STB0899_OFF0_TP_BUFFER1 0xf304
731#define STB0899_BASE_TP_BUFFER1 0x00000040
732#define STB0899_OFF0_TP_BUFFER2 0xf308
733#define STB0899_BASE_TP_BUFFER2 0x00000040
734#define STB0899_OFF0_TP_BUFFER3 0xf30c
735#define STB0899_BASE_TP_BUFFER3 0x00000040
736#define STB0899_OFF0_TP_BUFFER4 0xf310
737#define STB0899_BASE_TP_BUFFER4 0x00000040
738#define STB0899_OFF0_TP_BUFFER5 0xf314
739#define STB0899_BASE_TP_BUFFER5 0x00000040
740#define STB0899_OFF0_TP_BUFFER6 0xf318
741#define STB0899_BASE_TP_BUFFER6 0x00000040
742#define STB0899_OFF0_TP_BUFFER7 0xf31c
743#define STB0899_BASE_TP_BUFFER7 0x00000040
744#define STB0899_OFF0_TP_BUFFER8 0xf320
745#define STB0899_BASE_TP_BUFFER8 0x00000040
746#define STB0899_OFF0_TP_BUFFER9 0xf324
747#define STB0899_BASE_TP_BUFFER9 0x00000040
748#define STB0899_OFF0_TP_BUFFER10 0xf328
749#define STB0899_BASE_TP_BUFFER10 0x00000040
750#define STB0899_OFF0_TP_BUFFER11 0xf32c
751#define STB0899_BASE_TP_BUFFER11 0x00000040
752#define STB0899_OFF0_TP_BUFFER12 0xf330
753#define STB0899_BASE_TP_BUFFER12 0x00000040
754#define STB0899_OFF0_TP_BUFFER13 0xf334
755#define STB0899_BASE_TP_BUFFER13 0x00000040
756#define STB0899_OFF0_TP_BUFFER14 0xf338
757#define STB0899_BASE_TP_BUFFER14 0x00000040
758#define STB0899_OFF0_TP_BUFFER15 0xf33c
759#define STB0899_BASE_TP_BUFFER15 0x00000040
760#define STB0899_OFF0_TP_BUFFER16 0xf340
761#define STB0899_BASE_TP_BUFFER16 0x00000040
762#define STB0899_OFF0_TP_BUFFER17 0xf344
763#define STB0899_BASE_TP_BUFFER17 0x00000040
764#define STB0899_OFF0_TP_BUFFER18 0xf348
765#define STB0899_BASE_TP_BUFFER18 0x00000040
766#define STB0899_OFF0_TP_BUFFER19 0xf34c
767#define STB0899_BASE_TP_BUFFER19 0x00000040
768#define STB0899_OFF0_TP_BUFFER20 0xf350
769#define STB0899_BASE_TP_BUFFER20 0x00000040
770#define STB0899_OFF0_TP_BUFFER21 0xf354
771#define STB0899_BASE_TP_BUFFER21 0x00000040
772#define STB0899_OFF0_TP_BUFFER22 0xf358
773#define STB0899_BASE_TP_BUFFER22 0x00000040
774#define STB0899_OFF0_TP_BUFFER23 0xf35c
775#define STB0899_BASE_TP_BUFFER23 0x00000040
776#define STB0899_OFF0_TP_BUFFER24 0xf360
777#define STB0899_BASE_TP_BUFFER24 0x00000040
778#define STB0899_OFF0_TP_BUFFER25 0xf364
779#define STB0899_BASE_TP_BUFFER25 0x00000040
780#define STB0899_OFF0_TP_BUFFER26 0xf368
781#define STB0899_BASE_TP_BUFFER26 0x00000040
782#define STB0899_OFF0_TP_BUFFER27 0xf36c
783#define STB0899_BASE_TP_BUFFER27 0x00000040
784#define STB0899_OFF0_TP_BUFFER28 0xf370
785#define STB0899_BASE_TP_BUFFER28 0x00000040
786#define STB0899_OFF0_TP_BUFFER29 0xf374
787#define STB0899_BASE_TP_BUFFER29 0x00000040
788#define STB0899_OFF0_TP_BUFFER30 0xf378
789#define STB0899_BASE_TP_BUFFER30 0x00000040
790#define STB0899_OFF0_TP_BUFFER31 0xf37c
791#define STB0899_BASE_TP_BUFFER31 0x00000040
792#define STB0899_OFF0_TP_BUFFER32 0xf300
793#define STB0899_BASE_TP_BUFFER32 0x00000060
794#define STB0899_OFF0_TP_BUFFER33 0xf304
795#define STB0899_BASE_TP_BUFFER33 0x00000060
796#define STB0899_OFF0_TP_BUFFER34 0xf308
797#define STB0899_BASE_TP_BUFFER34 0x00000060
798#define STB0899_OFF0_TP_BUFFER35 0xf30c
799#define STB0899_BASE_TP_BUFFER35 0x00000060
800#define STB0899_OFF0_TP_BUFFER36 0xf310
801#define STB0899_BASE_TP_BUFFER36 0x00000060
802#define STB0899_OFF0_TP_BUFFER37 0xf314
803#define STB0899_BASE_TP_BUFFER37 0x00000060
804#define STB0899_OFF0_TP_BUFFER38 0xf318
805#define STB0899_BASE_TP_BUFFER38 0x00000060
806#define STB0899_OFF0_TP_BUFFER39 0xf31c
807#define STB0899_BASE_TP_BUFFER39 0x00000060
808#define STB0899_OFF0_TP_BUFFER40 0xf320
809#define STB0899_BASE_TP_BUFFER40 0x00000060
810#define STB0899_OFF0_TP_BUFFER41 0xf324
811#define STB0899_BASE_TP_BUFFER41 0x00000060
812#define STB0899_OFF0_TP_BUFFER42 0xf328
813#define STB0899_BASE_TP_BUFFER42 0x00000060
814#define STB0899_OFF0_TP_BUFFER43 0xf32c
815#define STB0899_BASE_TP_BUFFER43 0x00000060
816#define STB0899_OFF0_TP_BUFFER44 0xf330
817#define STB0899_BASE_TP_BUFFER44 0x00000060
818#define STB0899_OFF0_TP_BUFFER45 0xf334
819#define STB0899_BASE_TP_BUFFER45 0x00000060
820#define STB0899_OFF0_TP_BUFFER46 0xf338
821#define STB0899_BASE_TP_BUFFER46 0x00000060
822#define STB0899_OFF0_TP_BUFFER47 0xf33c
823#define STB0899_BASE_TP_BUFFER47 0x00000060
824#define STB0899_OFF0_TP_BUFFER48 0xf340
825#define STB0899_BASE_TP_BUFFER48 0x00000060
826#define STB0899_OFF0_TP_BUFFER49 0xf344
827#define STB0899_BASE_TP_BUFFER49 0x00000060
828#define STB0899_OFF0_TP_BUFFER50 0xf348
829#define STB0899_BASE_TP_BUFFER50 0x00000060
830#define STB0899_OFF0_TP_BUFFER51 0xf34c
831#define STB0899_BASE_TP_BUFFER51 0x00000060
832#define STB0899_OFF0_TP_BUFFER52 0xf350
833#define STB0899_BASE_TP_BUFFER52 0x00000060
834#define STB0899_OFF0_TP_BUFFER53 0xf354
835#define STB0899_BASE_TP_BUFFER53 0x00000060
836#define STB0899_OFF0_TP_BUFFER54 0xf358
837#define STB0899_BASE_TP_BUFFER54 0x00000060
838#define STB0899_OFF0_TP_BUFFER55 0xf35c
839#define STB0899_BASE_TP_BUFFER55 0x00000060
840#define STB0899_OFF0_TP_BUFFER56 0xf360
841#define STB0899_BASE_TP_BUFFER56 0x00000060
842#define STB0899_OFF0_TP_BUFFER57 0xf364
843#define STB0899_BASE_TP_BUFFER57 0x00000060
844#define STB0899_OFF0_TP_BUFFER58 0xf368
845#define STB0899_BASE_TP_BUFFER58 0x00000060
846#define STB0899_OFF0_TP_BUFFER59 0xf36c
847#define STB0899_BASE_TP_BUFFER59 0x00000060
848#define STB0899_OFF0_TP_BUFFER60 0xf370
849#define STB0899_BASE_TP_BUFFER60 0x00000060
850#define STB0899_OFF0_TP_BUFFER61 0xf374
851#define STB0899_BASE_TP_BUFFER61 0x00000060
852#define STB0899_OFF0_TP_BUFFER62 0xf378
853#define STB0899_BASE_TP_BUFFER62 0x00000060
854#define STB0899_OFF0_TP_BUFFER63 0xf37c
855#define STB0899_BASE_TP_BUFFER63 0x00000060
856
857#define STB0899_OFF0_RESET_CNTRL 0xf300
858#define STB0899_BASE_RESET_CNTRL 0x00000400
859#define STB0899_DVBS2_RESET (0x01 << 0)
860#define STB0899_OFFST_DVBS2_RESET 0
861#define STB0899_WIDTH_DVBS2_RESET 1
862
863#define STB0899_OFF0_ACM_ENABLE 0xf304
864#define STB0899_BASE_ACM_ENABLE 0x00000400
865#define STB0899_ACM_ENABLE 1
866
867#define STB0899_OFF0_DESCR_CNTRL 0xf30c
868#define STB0899_BASE_DESCR_CNTRL 0x00000400
869#define STB0899_OFFST_DESCR_CNTRL 0
870#define STB0899_WIDTH_DESCR_CNTRL 16
871
872#define STB0899_OFF0_UWP_CNTRL1 0xf320
873#define STB0899_BASE_UWP_CNTRL1 0x00000400
874#define STB0899_UWP_TH_SOF (0x7fff << 11)
875#define STB0899_OFFST_UWP_TH_SOF 11
876#define STB0899_WIDTH_UWP_TH_SOF 15
877#define STB0899_UWP_ESN0_QUANT (0xff << 3)
878#define STB0899_OFFST_UWP_ESN0_QUANT 3
879#define STB0899_WIDTH_UWP_ESN0_QUANT 8
880#define STB0899_UWP_ESN0_AVE (0x03 << 1)
881#define STB0899_OFFST_UWP_ESN0_AVE 1
882#define STB0899_WIDTH_UWP_ESN0_AVE 2
883#define STB0899_UWP_START (0x01 << 0)
884#define STB0899_OFFST_UWP_START 0
885#define STB0899_WIDTH_UWP_START 1
886
887#define STB0899_OFF0_UWP_CNTRL2 0xf324
888#define STB0899_BASE_UWP_CNTRL2 0x00000400
889#define STB0899_UWP_MISS_TH (0xff << 16)
890#define STB0899_OFFST_UWP_MISS_TH 16
891#define STB0899_WIDTH_UWP_MISS_TH 8
892#define STB0899_FE_FINE_TRK (0xff << 8)
893#define STB0899_OFFST_FE_FINE_TRK 8
894#define STB0899_WIDTH_FE_FINE_TRK 8
895#define STB0899_FE_COARSE_TRK (0xff << 0)
896#define STB0899_OFFST_FE_COARSE_TRK 0
897#define STB0899_WIDTH_FE_COARSE_TRK 8
898
899#define STB0899_OFF0_UWP_STAT1 0xf328
900#define STB0899_BASE_UWP_STAT1 0x00000400
901#define STB0899_UWP_STATE (0x03ff << 15)
902#define STB0899_OFFST_UWP_STATE 15
903#define STB0899_WIDTH_UWP_STATE 10
904#define STB0899_UW_MAX_PEAK (0x7fff << 0)
905#define STB0899_OFFST_UW_MAX_PEAK 0
906#define STB0899_WIDTH_UW_MAX_PEAK 15
907
908#define STB0899_OFF0_UWP_STAT2 0xf32c
909#define STB0899_BASE_UWP_STAT2 0x00000400
910#define STB0899_ESNO_EST (0x07ffff << 7)
911#define STB0899_OFFST_ESN0_EST 7
912#define STB0899_WIDTH_ESN0_EST 19
913#define STB0899_UWP_DECODE_MOD (0x7f << 0)
914#define STB0899_OFFST_UWP_DECODE_MOD 0
915#define STB0899_WIDTH_UWP_DECODE_MOD 7
916
917#define STB0899_OFF0_DMD_CORE_ID 0xf334
918#define STB0899_BASE_DMD_CORE_ID 0x00000400
919#define STB0899_CORE_ID (0xffffffff << 0)
920#define STB0899_OFFST_CORE_ID 0
921#define STB0899_WIDTH_CORE_ID 32
922
923#define STB0899_OFF0_DMD_VERSION_ID 0xf33c
924#define STB0899_BASE_DMD_VERSION_ID 0x00000400
925#define STB0899_VERSION_ID (0xff << 0)
926#define STB0899_OFFST_VERSION_ID 0
927#define STB0899_WIDTH_VERSION_ID 8
928
929#define STB0899_OFF0_DMD_STAT2 0xf340
930#define STB0899_BASE_DMD_STAT2 0x00000400
931#define STB0899_CSM_LOCK (0x01 << 1)
932#define STB0899_OFFST_CSM_LOCK 1
933#define STB0899_WIDTH_CSM_LOCK 1
934#define STB0899_UWP_LOCK (0x01 << 0)
935#define STB0899_OFFST_UWP_LOCK 0
936#define STB0899_WIDTH_UWP_LOCK 1
937
938#define STB0899_OFF0_FREQ_ADJ_SCALE 0xf344
939#define STB0899_BASE_FREQ_ADJ_SCALE 0x00000400
940#define STB0899_FREQ_ADJ_SCALE (0x0fff << 0)
941#define STB0899_OFFST_FREQ_ADJ_SCALE 0
942#define STB0899_WIDTH_FREQ_ADJ_SCALE 12
943
944#define STB0899_OFF0_UWP_CNTRL3 0xf34c
945#define STB0899_BASE_UWP_CNTRL3 0x00000400
946#define STB0899_UWP_TH_TRACK (0x7fff << 15)
947#define STB0899_OFFST_UWP_TH_TRACK 15
948#define STB0899_WIDTH_UWP_TH_TRACK 15
949#define STB0899_UWP_TH_ACQ (0x7fff << 0)
950#define STB0899_OFFST_UWP_TH_ACQ 0
951#define STB0899_WIDTH_UWP_TH_ACQ 15
952
953#define STB0899_OFF0_SYM_CLK_SEL 0xf350
954#define STB0899_BASE_SYM_CLK_SEL 0x00000400
955#define STB0899_SYM_CLK_SEL (0x03 << 0)
956#define STB0899_OFFST_SYM_CLK_SEL 0
957#define STB0899_WIDTH_SYM_CLK_SEL 2
958
959#define STB0899_OFF0_SOF_SRCH_TO 0xf354
960#define STB0899_BASE_SOF_SRCH_TO 0x00000400
961#define STB0899_SOF_SEARCH_TIMEOUT (0x3fffff << 0)
962#define STB0899_OFFST_SOF_SEARCH_TIMEOUT 0
963#define STB0899_WIDTH_SOF_SEARCH_TIMEOUT 22
964
965#define STB0899_OFF0_ACQ_CNTRL1 0xf358
966#define STB0899_BASE_ACQ_CNTRL1 0x00000400
967#define STB0899_FE_FINE_ACQ (0xff << 8)
968#define STB0899_OFFST_FE_FINE_ACQ 8
969#define STB0899_WIDTH_FE_FINE_ACQ 8
970#define STB0899_FE_COARSE_ACQ (0xff << 0)
971#define STB0899_OFFST_FE_COARSE_ACQ 0
972#define STB0899_WIDTH_FE_COARSE_ACQ 8
973
974#define STB0899_OFF0_ACQ_CNTRL2 0xf35c
975#define STB0899_BASE_ACQ_CNTRL2 0x00000400
976#define STB0899_ZIGZAG (0x01 << 25)
977#define STB0899_OFFST_ZIGZAG 25
978#define STB0899_WIDTH_ZIGZAG 1
979#define STB0899_NUM_STEPS (0xff << 17)
980#define STB0899_OFFST_NUM_STEPS 17
981#define STB0899_WIDTH_NUM_STEPS 8
982#define STB0899_FREQ_STEPSIZE (0x1ffff << 0)
983#define STB0899_OFFST_FREQ_STEPSIZE 0
984#define STB0899_WIDTH_FREQ_STEPSIZE 17
985
986#define STB0899_OFF0_ACQ_CNTRL3 0xf360
987#define STB0899_BASE_ACQ_CNTRL3 0x00000400
988#define STB0899_THRESHOLD_SCL (0x3f << 23)
989#define STB0899_OFFST_THRESHOLD_SCL 23
990#define STB0899_WIDTH_THRESHOLD_SCL 6
991#define STB0899_UWP_TH_SRCH (0x7fff << 8)
992#define STB0899_OFFST_UWP_TH_SRCH 8
993#define STB0899_WIDTH_UWP_TH_SRCH 15
994#define STB0899_AUTO_REACQUIRE (0x01 << 7)
995#define STB0899_OFFST_AUTO_REACQUIRE 7
996#define STB0899_WIDTH_AUTO_REACQUIRE 1
997#define STB0899_TRACK_LOCK_SEL (0x01 << 6)
998#define STB0899_OFFST_TRACK_LOCK_SEL 6
999#define STB0899_WIDTH_TRACK_LOCK_SEL 1
1000#define STB0899_ACQ_SEARCH_MODE (0x03 << 4)
1001#define STB0899_OFFST_ACQ_SEARCH_MODE 4
1002#define STB0899_WIDTH_ACQ_SEARCH_MODE 2
1003#define STB0899_CONFIRM_FRAMES (0x0f << 0)
1004#define STB0899_OFFST_CONFIRM_FRAMES 0
1005#define STB0899_WIDTH_CONFIRM_FRAMES 4
1006
1007#define STB0899_OFF0_FE_SETTLE 0xf364
1008#define STB0899_BASE_FE_SETTLE 0x00000400
1009#define STB0899_SETTLING_TIME (0x3fffff << 0)
1010#define STB0899_OFFST_SETTLING_TIME 0
1011#define STB0899_WIDTH_SETTLING_TIME 22
1012
1013#define STB0899_OFF0_AC_DWELL 0xf368
1014#define STB0899_BASE_AC_DWELL 0x00000400
1015#define STB0899_DWELL_TIME (0x3fffff << 0)
1016#define STB0899_OFFST_DWELL_TIME 0
1017#define STB0899_WIDTH_DWELL_TIME 22
1018
1019#define STB0899_OFF0_ACQUIRE_TRIG 0xf36c
1020#define STB0899_BASE_ACQUIRE_TRIG 0x00000400
1021#define STB0899_ACQUIRE (0x01 << 0)
1022#define STB0899_OFFST_ACQUIRE 0
1023#define STB0899_WIDTH_ACQUIRE 1
1024
1025#define STB0899_OFF0_LOCK_LOST 0xf370
1026#define STB0899_BASE_LOCK_LOST 0x00000400
1027#define STB0899_LOCK_LOST (0x01 << 0)
1028#define STB0899_OFFST_LOCK_LOST 0
1029#define STB0899_WIDTH_LOCK_LOST 1
1030
1031#define STB0899_OFF0_ACQ_STAT1 0xf374
1032#define STB0899_BASE_ACQ_STAT1 0x00000400
1033#define STB0899_STEP_FREQ (0x1fffff << 11)
1034#define STB0899_OFFST_STEP_FREQ 11
1035#define STB0899_WIDTH_STEP_FREQ 21
1036#define STB0899_ACQ_STATE (0x07 << 8)
1037#define STB0899_OFFST_ACQ_STATE 8
1038#define STB0899_WIDTH_ACQ_STATE 3
1039#define STB0899_UW_DETECT_COUNT (0xff << 0)
1040#define STB0899_OFFST_UW_DETECT_COUNT 0
1041#define STB0899_WIDTH_UW_DETECT_COUNT 8
1042
1043#define STB0899_OFF0_ACQ_TIMEOUT 0xf378
1044#define STB0899_BASE_ACQ_TIMEOUT 0x00000400
1045#define STB0899_ACQ_TIMEOUT (0x3fffff << 0)
1046#define STB0899_OFFST_ACQ_TIMEOUT 0
1047#define STB0899_WIDTH_ACQ_TIMEOUT 22
1048
1049#define STB0899_OFF0_ACQ_TIME 0xf37c
1050#define STB0899_BASE_ACQ_TIME 0x00000400
1051#define STB0899_ACQ_TIME_SYM (0xffffff << 0)
1052#define STB0899_OFFST_ACQ_TIME_SYM 0
1053#define STB0899_WIDTH_ACQ_TIME_SYM 24
1054
1055#define STB0899_OFF0_FINAL_AGC_CNTRL 0xf308
1056#define STB0899_BASE_FINAL_AGC_CNTRL 0x00000440
1057#define STB0899_FINAL_GAIN_INIT (0x3fff << 12)
1058#define STB0899_OFFST_FINAL_GAIN_INIT 12
1059#define STB0899_WIDTH_FINAL_GAIN_INIT 14
1060#define STB0899_FINAL_LOOP_GAIN (0x0f << 8)
1061#define STB0899_OFFST_FINAL_LOOP_GAIN 8
1062#define STB0899_WIDTH_FINAL_LOOP_GAIN 4
1063#define STB0899_FINAL_LD_GAIN_INIT (0x01 << 7)
1064#define STB0899_OFFST_FINAL_LD_GAIN_INIT 7
1065#define STB0899_WIDTH_FINAL_LD_GAIN_INIT 1
1066#define STB0899_FINAL_AGC_REF (0x7f << 0)
1067#define STB0899_OFFST_FINAL_AGC_REF 0
1068#define STB0899_WIDTH_FINAL_AGC_REF 7
1069
1070#define STB0899_OFF0_FINAL_AGC_GAIN 0xf30c
1071#define STB0899_BASE_FINAL_AGC_GAIN 0x00000440
1072#define STB0899_FINAL_AGC_GAIN (0x3fff << 0)
1073#define STB0899_OFFST_FINAL_AGC_GAIN 0
1074#define STB0899_WIDTH_FINAL_AGC_GAIN 14
1075
1076#define STB0899_OFF0_EQUALIZER_INIT 0xf310
1077#define STB0899_BASE_EQUALIZER_INIT 0x00000440
1078#define STB0899_EQ_SRST (0x01 << 1)
1079#define STB0899_OFFST_EQ_SRST 1
1080#define STB0899_WIDTH_EQ_SRST 1
1081#define STB0899_EQ_INIT (0x01 << 0)
1082#define STB0899_OFFST_EQ_INIT 0
1083#define STB0899_WIDTH_EQ_INIT 1
1084
1085#define STB0899_OFF0_EQ_CNTRL 0xf314
1086#define STB0899_BASE_EQ_CNTRL 0x00000440
1087#define STB0899_EQ_ADAPT_MODE (0x01 << 18)
1088#define STB0899_OFFST_EQ_ADAPT_MODE 18
1089#define STB0899_WIDTH_EQ_ADAPT_MODE 1
1090#define STB0899_EQ_DELAY (0x0f << 14)
1091#define STB0899_OFFST_EQ_DELAY 14
1092#define STB0899_WIDTH_EQ_DELAY 4
1093#define STB0899_EQ_QUANT_LEVEL (0xff << 6)
1094#define STB0899_OFFST_EQ_QUANT_LEVEL 6
1095#define STB0899_WIDTH_EQ_QUANT_LEVEL 8
1096#define STB0899_EQ_DISABLE_UPDATE (0x01 << 5)
1097#define STB0899_OFFST_EQ_DISABLE_UPDATE 5
1098#define STB0899_WIDTH_EQ_DISABLE_UPDATE 1
1099#define STB0899_EQ_BYPASS (0x01 << 4)
1100#define STB0899_OFFST_EQ_BYPASS 4
1101#define STB0899_WIDTH_EQ_BYPASS 1
1102#define STB0899_EQ_SHIFT (0x0f << 0)
1103#define STB0899_OFFST_EQ_SHIFT 0
1104#define STB0899_WIDTH_EQ_SHIFT 4
1105
1106#define STB0899_OFF0_EQ_I_INIT_COEFF_0 0xf320
1107#define STB0899_OFF1_EQ_I_INIT_COEFF_1 0xf324
1108#define STB0899_OFF2_EQ_I_INIT_COEFF_2 0xf328
1109#define STB0899_OFF3_EQ_I_INIT_COEFF_3 0xf32c
1110#define STB0899_OFF4_EQ_I_INIT_COEFF_4 0xf330
1111#define STB0899_OFF5_EQ_I_INIT_COEFF_5 0xf334
1112#define STB0899_OFF6_EQ_I_INIT_COEFF_6 0xf338
1113#define STB0899_OFF7_EQ_I_INIT_COEFF_7 0xf33c
1114#define STB0899_OFF8_EQ_I_INIT_COEFF_8 0xf340
1115#define STB0899_OFF9_EQ_I_INIT_COEFF_9 0xf344
1116#define STB0899_OFFa_EQ_I_INIT_COEFF_10 0xf348
1117#define STB0899_BASE_EQ_I_INIT_COEFF_N 0x00000440
1118#define STB0899_EQ_I_INIT_COEFF_N (0x0fff << 0)
1119#define STB0899_OFFST_EQ_I_INIT_COEFF_N 0
1120#define STB0899_WIDTH_EQ_I_INIT_COEFF_N 12
1121
1122#define STB0899_OFF0_EQ_Q_INIT_COEFF_0 0xf350
1123#define STB0899_OFF1_EQ_Q_INIT_COEFF_1 0xf354
1124#define STB0899_OFF2_EQ_Q_INIT_COEFF_2 0xf358
1125#define STB0899_OFF3_EQ_Q_INIT_COEFF_3 0xf35c
1126#define STB0899_OFF4_EQ_Q_INIT_COEFF_4 0xf360
1127#define STB0899_OFF5_EQ_Q_INIT_COEFF_5 0xf364
1128#define STB0899_OFF6_EQ_Q_INIT_COEFF_6 0xf368
1129#define STB0899_OFF7_EQ_Q_INIT_COEFF_7 0xf36c
1130#define STB0899_OFF8_EQ_Q_INIT_COEFF_8 0xf370
1131#define STB0899_OFF9_EQ_Q_INIT_COEFF_9 0xf374
1132#define STB0899_OFFa_EQ_Q_INIT_COEFF_10 0xf378
1133#define STB0899_BASE_EQ_Q_INIT_COEFF_N 0x00000440
1134#define STB0899_EQ_Q_INIT_COEFF_N (0x0fff << 0)
1135#define STB0899_OFFST_EQ_Q_INIT_COEFF_N 0
1136#define STB0899_WIDTH_EQ_Q_INIT_COEFF_N 12
1137
1138#define STB0899_OFF0_EQ_I_OUT_COEFF_0 0xf300
1139#define STB0899_OFF1_EQ_I_OUT_COEFF_1 0xf304
1140#define STB0899_OFF2_EQ_I_OUT_COEFF_2 0xf308
1141#define STB0899_OFF3_EQ_I_OUT_COEFF_3 0xf30c
1142#define STB0899_OFF4_EQ_I_OUT_COEFF_4 0xf310
1143#define STB0899_OFF5_EQ_I_OUT_COEFF_5 0xf314
1144#define STB0899_OFF6_EQ_I_OUT_COEFF_6 0xf318
1145#define STB0899_OFF7_EQ_I_OUT_COEFF_7 0xf31c
1146#define STB0899_OFF8_EQ_I_OUT_COEFF_8 0xf320
1147#define STB0899_OFF9_EQ_I_OUT_COEFF_9 0xf324
1148#define STB0899_OFFa_EQ_I_OUT_COEFF_10 0xf328
1149#define STB0899_BASE_EQ_I_OUT_COEFF_N 0x00000460
1150#define STB0899_EQ_I_OUT_COEFF_N (0x0fff << 0)
1151#define STB0899_OFFST_EQ_I_OUT_COEFF_N 0
1152#define STB0899_WIDTH_EQ_I_OUT_COEFF_N 12
1153
1154#define STB0899_OFF0_EQ_Q_OUT_COEFF_0 0xf330
1155#define STB0899_OFF1_EQ_Q_OUT_COEFF_1 0xf334
1156#define STB0899_OFF2_EQ_Q_OUT_COEFF_2 0xf338
1157#define STB0899_OFF3_EQ_Q_OUT_COEFF_3 0xf33c
1158#define STB0899_OFF4_EQ_Q_OUT_COEFF_4 0xf340
1159#define STB0899_OFF5_EQ_Q_OUT_COEFF_5 0xf344
1160#define STB0899_OFF6_EQ_Q_OUT_COEFF_6 0xf348
1161#define STB0899_OFF7_EQ_Q_OUT_COEFF_7 0xf34c
1162#define STB0899_OFF8_EQ_Q_OUT_COEFF_8 0xf350
1163#define STB0899_OFF9_EQ_Q_OUT_COEFF_9 0xf354
1164#define STB0899_OFFa_EQ_Q_OUT_COEFF_10 0xf358
1165#define STB0899_BASE_EQ_Q_OUT_COEFF_N 0x00000460
1166#define STB0899_EQ_Q_OUT_COEFF_N (0x0fff << 0)
1167#define STB0899_OFFST_EQ_Q_OUT_COEFF_N 0
1168#define STB0899_WIDTH_EQ_Q_OUT_COEFF_N 12
1169
1170/* S2 FEC */
1171#define STB0899_OFF0_BLOCK_LNGTH 0xfa04
1172#define STB0899_BASE_BLOCK_LNGTH 0x00000000
1173#define STB0899_BLOCK_LENGTH (0xff << 0)
1174#define STB0899_OFFST_BLOCK_LENGTH 0
1175#define STB0899_WIDTH_BLOCK_LENGTH 8
1176
1177#define STB0899_OFF0_ROW_STR 0xfa08
1178#define STB0899_BASE_ROW_STR 0x00000000
1179#define STB0899_ROW_STRIDE (0xff << 0)
1180#define STB0899_OFFST_ROW_STRIDE 0
1181#define STB0899_WIDTH_ROW_STRIDE 8
1182
1183#define STB0899_OFF0_MAX_ITER 0xfa0c
1184#define STB0899_BASE_MAX_ITER 0x00000000
1185#define STB0899_MAX_ITERATIONS (0xff << 0)
1186#define STB0899_OFFST_MAX_ITERATIONS 0
1187#define STB0899_WIDTH_MAX_ITERATIONS 8
1188
1189#define STB0899_OFF0_BN_END_ADDR 0xfa10
1190#define STB0899_BASE_BN_END_ADDR 0x00000000
1191#define STB0899_BN_END_ADDR (0x0fff << 0)
1192#define STB0899_OFFST_BN_END_ADDR 0
1193#define STB0899_WIDTH_BN_END_ADDR 12
1194
1195#define STB0899_OFF0_CN_END_ADDR 0xfa14
1196#define STB0899_BASE_CN_END_ADDR 0x00000000
1197#define STB0899_CN_END_ADDR (0x0fff << 0)
1198#define STB0899_OFFST_CN_END_ADDR 0
1199#define STB0899_WIDTH_CN_END_ADDR 12
1200
1201#define STB0899_OFF0_INFO_LENGTH 0xfa1c
1202#define STB0899_BASE_INFO_LENGTH 0x00000000
1203#define STB0899_INFO_LENGTH (0xff << 0)
1204#define STB0899_OFFST_INFO_LENGTH 0
1205#define STB0899_WIDTH_INFO_LENGTH 8
1206
1207#define STB0899_OFF0_BOT_ADDR 0xfa20
1208#define STB0899_BASE_BOT_ADDR 0x00000000
1209#define STB0899_BOTTOM_BASE_ADDR (0x03ff << 0)
1210#define STB0899_OFFST_BOTTOM_BASE_ADDR 0
1211#define STB0899_WIDTH_BOTTOM_BASE_ADDR 10
1212
1213#define STB0899_OFF0_BCH_BLK_LN 0xfa24
1214#define STB0899_BASE_BCH_BLK_LN 0x00000000
1215#define STB0899_BCH_BLOCK_LENGTH (0xffff << 0)
1216#define STB0899_OFFST_BCH_BLOCK_LENGTH 0
1217#define STB0899_WIDTH_BCH_BLOCK_LENGTH 16
1218
1219#define STB0899_OFF0_BCH_T 0xfa28
1220#define STB0899_BASE_BCH_T 0x00000000
1221#define STB0899_BCH_T (0x0f << 0)
1222#define STB0899_OFFST_BCH_T 0
1223#define STB0899_WIDTH_BCH_T 4
1224
1225#define STB0899_OFF0_CNFG_MODE 0xfa00
1226#define STB0899_BASE_CNFG_MODE 0x00000800
1227#define STB0899_MODCOD (0x1f << 2)
1228#define STB0899_OFFST_MODCOD 2
1229#define STB0899_WIDTH_MODCOD 5
1230#define STB0899_MODCOD_SEL (0x01 << 1)
1231#define STB0899_OFFST_MODCOD_SEL 1
1232#define STB0899_WIDTH_MODCOD_SEL 1
1233#define STB0899_CONFIG_MODE (0x01 << 0)
1234#define STB0899_OFFST_CONFIG_MODE 0
1235#define STB0899_WIDTH_CONFIG_MODE 1
1236
1237#define STB0899_OFF0_LDPC_STAT 0xfa04
1238#define STB0899_BASE_LDPC_STAT 0x00000800
1239#define STB0899_ITERATION (0xff << 3)
1240#define STB0899_OFFST_ITERATION 3
1241#define STB0899_WIDTH_ITERATION 8
1242#define STB0899_LDPC_DEC_STATE (0x07 << 0)
1243#define STB0899_OFFST_LDPC_DEC_STATE 0
1244#define STB0899_WIDTH_LDPC_DEC_STATE 3
1245
1246#define STB0899_OFF0_ITER_SCALE 0xfa08
1247#define STB0899_BASE_ITER_SCALE 0x00000800
1248#define STB0899_ITERATION_SCALE (0xff << 0)
1249#define STB0899_OFFST_ITERATION_SCALE 0
1250#define STB0899_WIDTH_ITERATION_SCALE 8
1251
1252#define STB0899_OFF0_INPUT_MODE 0xfa0c
1253#define STB0899_BASE_INPUT_MODE 0x00000800
1254#define STB0899_SD_BLOCK1_STREAM0 (0x01 << 0)
1255#define STB0899_OFFST_SD_BLOCK1_STREAM0 0
1256#define STB0899_WIDTH_SD_BLOCK1_STREAM0 1
1257
1258#define STB0899_OFF0_LDPCDECRST 0xfa10
1259#define STB0899_BASE_LDPCDECRST 0x00000800
1260#define STB0899_LDPC_DEC_RST (0x01 << 0)
1261#define STB0899_OFFST_LDPC_DEC_RST 0
1262#define STB0899_WIDTH_LDPC_DEC_RST 1
1263
1264#define STB0899_OFF0_CLK_PER_BYTE_RW 0xfa14
1265#define STB0899_BASE_CLK_PER_BYTE_RW 0x00000800
1266#define STB0899_CLKS_PER_BYTE (0x0f << 0)
1267#define STB0899_OFFST_CLKS_PER_BYTE 0
1268#define STB0899_WIDTH_CLKS_PER_BYTE 5
1269
1270#define STB0899_OFF0_BCH_ERRORS 0xfa18
1271#define STB0899_BASE_BCH_ERRORS 0x00000800
1272#define STB0899_BCH_ERRORS (0x0f << 0)
1273#define STB0899_OFFST_BCH_ERRORS 0
1274#define STB0899_WIDTH_BCH_ERRORS 4
1275
1276#define STB0899_OFF0_LDPC_ERRORS 0xfa1c
1277#define STB0899_BASE_LDPC_ERRORS 0x00000800
1278#define STB0899_LDPC_ERRORS (0xffff << 0)
1279#define STB0899_OFFST_LDPC_ERRORS 0
1280#define STB0899_WIDTH_LDPC_ERRORS 16
1281
1282#define STB0899_OFF0_BCH_MODE 0xfa20
1283#define STB0899_BASE_BCH_MODE 0x00000800
1284#define STB0899_BCH_CORRECT_N (0x01 << 1)
1285#define STB0899_OFFST_BCH_CORRECT_N 1
1286#define STB0899_WIDTH_BCH_CORRECT_N 1
1287#define STB0899_FULL_BYPASS (0x01 << 0)
1288#define STB0899_OFFST_FULL_BYPASS 0
1289#define STB0899_WIDTH_FULL_BYPASS 1
1290
1291#define STB0899_OFF0_ERR_ACC_PER 0xfa24
1292#define STB0899_BASE_ERR_ACC_PER 0x00000800
1293#define STB0899_BCH_ERR_ACC_PERIOD (0x0f << 0)
1294#define STB0899_OFFST_BCH_ERR_ACC_PERIOD 0
1295#define STB0899_WIDTH_BCH_ERR_ACC_PERIOD 4
1296
1297#define STB0899_OFF0_BCH_ERR_ACC 0xfa28
1298#define STB0899_BASE_BCH_ERR_ACC 0x00000800
1299#define STB0899_BCH_ERR_ACCUM (0xff << 0)
1300#define STB0899_OFFST_BCH_ERR_ACCUM 0
1301#define STB0899_WIDTH_BCH_ERR_ACCUM 8
1302
1303#define STB0899_OFF0_FEC_CORE_ID_REG 0xfa2c
1304#define STB0899_BASE_FEC_CORE_ID_REG 0x00000800
1305#define STB0899_FEC_CORE_ID (0xffffffff << 0)
1306#define STB0899_OFFST_FEC_CORE_ID 0
1307#define STB0899_WIDTH_FEC_CORE_ID 32
1308
1309#define STB0899_OFF0_FEC_VER_ID_REG 0xfa34
1310#define STB0899_BASE_FEC_VER_ID_REG 0x00000800
1311#define STB0899_FEC_VER_ID (0xff << 0)
1312#define STB0899_OFFST_FEC_VER_ID 0
1313#define STB0899_WIDTH_FEC_VER_ID 8
1314
1315#define STB0899_OFF0_FEC_TP_SEL 0xfa38
1316#define STB0899_BASE_FEC_TP_SEL 0x00000800
1317
1318#define STB0899_OFF0_CSM_CNTRL1 0xf310
1319#define STB0899_BASE_CSM_CNTRL1 0x00000400
1320#define STB0899_CSM_FORCE_FREQLOCK (0x01 << 19)
1321#define STB0899_OFFST_CSM_FORCE_FREQLOCK 19
1322#define STB0899_WIDTH_CSM_FORCE_FREQLOCK 1
1323#define STB0899_CSM_FREQ_LOCKSTATE (0x01 << 18)
1324#define STB0899_OFFST_CSM_FREQ_LOCKSTATE 18
1325#define STB0899_WIDTH_CSM_FREQ_LOCKSTATE 1
1326#define STB0899_CSM_AUTO_PARAM (0x01 << 17)
1327#define STB0899_OFFST_CSM_AUTO_PARAM 17
1328#define STB0899_WIDTH_CSM_AUTO_PARAM 1
1329#define STB0899_FE_LOOP_SHIFT (0x07 << 14)
1330#define STB0899_OFFST_FE_LOOP_SHIFT 14
1331#define STB0899_WIDTH_FE_LOOP_SHIFT 3
1332#define STB0899_CSM_AGC_SHIFT (0x07 << 11)
1333#define STB0899_OFFST_CSM_AGC_SHIFT 11
1334#define STB0899_WIDTH_CSM_AGC_SHIFT 3
1335#define STB0899_CSM_AGC_GAIN (0x1ff << 2)
1336#define STB0899_OFFST_CSM_AGC_GAIN 2
1337#define STB0899_WIDTH_CSM_AGC_GAIN 9
1338#define STB0899_CSM_TWO_PASS (0x01 << 1)
1339#define STB0899_OFFST_CSM_TWO_PASS 1
1340#define STB0899_WIDTH_CSM_TWO_PASS 1
1341#define STB0899_CSM_DVT_TABLE (0x01 << 0)
1342#define STB0899_OFFST_CSM_DVT_TABLE 0
1343#define STB0899_WIDTH_CSM_DVT_TABLE 1
1344
1345#define STB0899_OFF0_CSM_CNTRL2 0xf314
1346#define STB0899_BASE_CSM_CNTRL2 0x00000400
1347#define STB0899_CSM_GAMMA_RHO_ACQ (0x1ff << 9)
1348#define STB0899_OFFST_CSM_GAMMA_RHOACQ 9
1349#define STB0899_WIDTH_CSM_GAMMA_RHOACQ 9
1350#define STB0899_CSM_GAMMA_ACQ (0x1ff << 0)
1351#define STB0899_OFFST_CSM_GAMMA_ACQ 0
1352#define STB0899_WIDTH_CSM_GAMMA_ACQ 9
1353
1354#define STB0899_OFF0_CSM_CNTRL3 0xf318
1355#define STB0899_BASE_CSM_CNTRL3 0x00000400
1356#define STB0899_CSM_GAMMA_RHO_TRACK (0x1ff << 9)
1357#define STB0899_OFFST_CSM_GAMMA_RHOTRACK 9
1358#define STB0899_WIDTH_CSM_GAMMA_RHOTRACK 9
1359#define STB0899_CSM_GAMMA_TRACK (0x1ff << 0)
1360#define STB0899_OFFST_CSM_GAMMA_TRACK 0
1361#define STB0899_WIDTH_CSM_GAMMA_TRACK 9
1362
1363#define STB0899_OFF0_CSM_CNTRL4 0xf31c
1364#define STB0899_BASE_CSM_CNTRL4 0x00000400
1365#define STB0899_CSM_PHASEDIFF_THRESH (0x0f << 8)
1366#define STB0899_OFFST_CSM_PHASEDIFF_THRESH 8
1367#define STB0899_WIDTH_CSM_PHASEDIFF_THRESH 4
1368#define STB0899_CSM_LOCKCOUNT_THRESH (0xff << 0)
1369#define STB0899_OFFST_CSM_LOCKCOUNT_THRESH 0
1370#define STB0899_WIDTH_CSM_LOCKCOUNT_THRESH 8
1371
1372/* Check on chapter 8 page 42 */
1373#define STB0899_ERRCTRL1 0xf574
1374#define STB0899_ERRCTRL2 0xf575
1375#define STB0899_ERRCTRL3 0xf576
1376#define STB0899_ERR_SRC_S1 (0x1f << 3)
1377#define STB0899_OFFST_ERR_SRC_S1 3
1378#define STB0899_WIDTH_ERR_SRC_S1 5
1379#define STB0899_ERR_SRC_S2 (0x0f << 0)
1380#define STB0899_OFFST_ERR_SRC_S2 0
1381#define STB0899_WIDTH_ERR_SRC_S2 4
1382#define STB0899_NOE (0x07 << 0)
1383#define STB0899_OFFST_NOE 0
1384#define STB0899_WIDTH_NOE 3
1385
1386#define STB0899_ECNT1M 0xf524
1387#define STB0899_ECNT1L 0xf525
1388#define STB0899_ECNT2M 0xf526
1389#define STB0899_ECNT2L 0xf527
1390#define STB0899_ECNT3M 0xf528
1391#define STB0899_ECNT3L 0xf529
1392
1393#define STB0899_DMONMSK1 0xf57b
1394#define STB0899_DMONMSK1_WAIT_1STEP (1 << 7)
1395#define STB0899_DMONMSK1_FREE_14 (1 << 6)
1396#define STB0899_DMONMSK1_AVRGVIT_CALC (1 << 5)
1397#define STB0899_DMONMSK1_FREE_12 (1 << 4)
1398#define STB0899_DMONMSK1_FREE_11 (1 << 3)
1399#define STB0899_DMONMSK1_B0DIV_CALC (1 << 2)
1400#define STB0899_DMONMSK1_KDIVB1_CALC (1 << 1)
1401#define STB0899_DMONMSK1_KDIVB2_CALC (1 << 0)
1402
1403#define STB0899_DMONMSK0 0xf57c
1404#define STB0899_DMONMSK0_SMOTTH_CALC (1 << 7)
1405#define STB0899_DMONMSK0_FREE_6 (1 << 6)
1406#define STB0899_DMONMSK0_SIGPOWER_CALC (1 << 5)
1407#define STB0899_DMONMSK0_QSEUIL_CALC (1 << 4)
1408#define STB0899_DMONMSK0_FREE_3 (1 << 3)
1409#define STB0899_DMONMSK0_FREE_2 (1 << 2)
1410#define STB0899_DMONMSK0_KVDIVB1_CALC (1 << 1)
1411#define STB0899_DMONMSK0_KVDIVB2_CALC (1 << 0)
1412
1413#define STB0899_TSULC 0xf549
1414#define STB0899_ULNOSYNCBYTES (0x01 << 7)
1415#define STB0899_OFFST_ULNOSYNCBYTES 7
1416#define STB0899_WIDTH_ULNOSYNCBYTES 1
1417#define STB0899_ULPARITY_ON (0x01 << 6)
1418#define STB0899_OFFST_ULPARITY_ON 6
1419#define STB0899_WIDTH_ULPARITY_ON 1
1420#define STB0899_ULSYNCOUTRS (0x01 << 5)
1421#define STB0899_OFFST_ULSYNCOUTRS 5
1422#define STB0899_WIDTH_ULSYNCOUTRS 1
1423#define STB0899_ULDSS_PACKETS (0x01 << 0)
1424#define STB0899_OFFST_ULDSS_PACKETS 0
1425#define STB0899_WIDTH_ULDSS_PACKETS 1
1426
1427#define STB0899_TSLPL 0xf54b
1428#define STB0899_LLDVBS2_MODE (0x01 << 4)
1429#define STB0899_OFFST_LLDVBS2_MODE 4
1430#define STB0899_WIDTH_LLDVBS2_MODE 1
1431#define STB0899_LLISSYI_ON (0x01 << 3)
1432#define STB0899_OFFST_LLISSYI_ON 3
1433#define STB0899_WIDTH_LLISSYI_ON 1
1434#define STB0899_LLNPD_ON (0x01 << 2)
1435#define STB0899_OFFST_LLNPD_ON 2
1436#define STB0899_WIDTH_LLNPD_ON 1
1437#define STB0899_LLCRC8_ON (0x01 << 1)
1438#define STB0899_OFFST_LLCRC8_ON 1
1439#define STB0899_WIDTH_LLCRC8_ON 1
1440
1441#define STB0899_TSCFGH 0xf54c
1442#define STB0899_OUTRS_PS (0x01 << 6)
1443#define STB0899_OFFST_OUTRS_PS 6
1444#define STB0899_WIDTH_OUTRS_PS 1
1445#define STB0899_SYNCBYTE (0x01 << 5)
1446#define STB0899_OFFST_SYNCBYTE 5
1447#define STB0899_WIDTH_SYNCBYTE 1
1448#define STB0899_PFBIT (0x01 << 4)
1449#define STB0899_OFFST_PFBIT 4
1450#define STB0899_WIDTH_PFBIT 1
1451#define STB0899_ERR_BIT (0x01 << 3)
1452#define STB0899_OFFST_ERR_BIT 3
1453#define STB0899_WIDTH_ERR_BIT 1
1454#define STB0899_MPEG (0x01 << 2)
1455#define STB0899_OFFST_MPEG 2
1456#define STB0899_WIDTH_MPEG 1
1457#define STB0899_CLK_POL (0x01 << 1)
1458#define STB0899_OFFST_CLK_POL 1
1459#define STB0899_WIDTH_CLK_POL 1
1460#define STB0899_FORCE0 (0x01 << 0)
1461#define STB0899_OFFST_FORCE0 0
1462#define STB0899_WIDTH_FORCE0 1
1463
1464#define STB0899_TSCFGM 0xf54d
1465#define STB0899_LLPRIORITY (0x01 << 3)
1466#define STB0899_OFFST_LLPRIORIY 3
1467#define STB0899_WIDTH_LLPRIORITY 1
1468#define STB0899_EN188 (0x01 << 2)
1469#define STB0899_OFFST_EN188 2
1470#define STB0899_WIDTH_EN188 1
1471
1472#define STB0899_TSCFGL 0xf54e
1473#define STB0899_DEL_ERRPCK (0x01 << 7)
1474#define STB0899_OFFST_DEL_ERRPCK 7
1475#define STB0899_WIDTH_DEL_ERRPCK 1
1476#define STB0899_ERRFLAGSTD (0x01 << 5)
1477#define STB0899_OFFST_ERRFLAGSTD 5
1478#define STB0899_WIDTH_ERRFLAGSTD 1
1479#define STB0899_MPEGERR (0x01 << 4)
1480#define STB0899_OFFST_MPEGERR 4
1481#define STB0899_WIDTH_MPEGERR 1
1482#define STB0899_BCH_CHK (0x01 << 3)
1483#define STB0899_OFFST_BCH_CHK 5
1484#define STB0899_WIDTH_BCH_CHK 1
1485#define STB0899_CRC8CHK (0x01 << 2)
1486#define STB0899_OFFST_CRC8CHK 2
1487#define STB0899_WIDTH_CRC8CHK 1
1488#define STB0899_SPEC_INFO (0x01 << 1)
1489#define STB0899_OFFST_SPEC_INFO 1
1490#define STB0899_WIDTH_SPEC_INFO 1
1491#define STB0899_LOW_PRIO_CLK (0x01 << 0)
1492#define STB0899_OFFST_LOW_PRIO_CLK 0
1493#define STB0899_WIDTH_LOW_PRIO_CLK 1
1494#define STB0899_ERROR_NORM (0x00 << 0)
1495#define STB0899_OFFST_ERROR_NORM 0
1496#define STB0899_WIDTH_ERROR_NORM 0
1497
1498#define STB0899_TSOUT 0xf54f
1499#define STB0899_RSSYNCDEL 0xf550
1500#define STB0899_TSINHDELH 0xf551
1501#define STB0899_TSINHDELM 0xf552
1502#define STB0899_TSINHDELL 0xf553
1503#define STB0899_TSLLSTKM 0xf55a
1504#define STB0899_TSLLSTKL 0xf55b
1505#define STB0899_TSULSTKM 0xf55c
1506#define STB0899_TSULSTKL 0xf55d
1507#define STB0899_TSSTATUS 0xf561
1508
1509#define STB0899_PDELCTRL 0xf600
1510#define STB0899_INVERT_RES (0x01 << 7)
1511#define STB0899_OFFST_INVERT_RES 7
1512#define STB0899_WIDTH_INVERT_RES 1
1513#define STB0899_FORCE_ACCEPTED (0x01 << 6)
1514#define STB0899_OFFST_FORCE_ACCEPTED 6
1515#define STB0899_WIDTH_FORCE_ACCEPTED 1
1516#define STB0899_FILTER_EN (0x01 << 5)
1517#define STB0899_OFFST_FILTER_EN 5
1518#define STB0899_WIDTH_FILTER_EN 1
1519#define STB0899_LOCKFALL_THRESH (0x01 << 4)
1520#define STB0899_OFFST_LOCKFALL_THRESH 4
1521#define STB0899_WIDTH_LOCKFALL_THRESH 1
1522#define STB0899_HYST_EN (0x01 << 3)
1523#define STB0899_OFFST_HYST_EN 3
1524#define STB0899_WIDTH_HYST_EN 1
1525#define STB0899_HYST_SWRST (0x01 << 2)
1526#define STB0899_OFFST_HYST_SWRST 2
1527#define STB0899_WIDTH_HYST_SWRST 1
1528#define STB0899_ALGO_EN (0x01 << 1)
1529#define STB0899_OFFST_ALGO_EN 1
1530#define STB0899_WIDTH_ALGO_EN 1
1531#define STB0899_ALGO_SWRST (0x01 << 0)
1532#define STB0899_OFFST_ALGO_SWRST 0
1533#define STB0899_WIDTH_ALGO_SWRST 1
1534
1535#define STB0899_PDELCTRL2 0xf601
1536#define STB0899_BBHCTRL1 0xf602
1537#define STB0899_BBHCTRL2 0xf603
1538#define STB0899_HYSTTHRESH 0xf604
1539
1540#define STB0899_MATCSTM 0xf605
1541#define STB0899_MATCSTL 0xf606
1542#define STB0899_UPLCSTM 0xf607
1543#define STB0899_UPLCSTL 0xf608
1544#define STB0899_DFLCSTM 0xf609
1545#define STB0899_DFLCSTL 0xf60a
1546#define STB0899_SYNCCST 0xf60b
1547#define STB0899_SYNCDCSTM 0xf60c
1548#define STB0899_SYNCDCSTL 0xf60d
1549#define STB0899_ISI_ENTRY 0xf60e
1550#define STB0899_ISI_BIT_EN 0xf60f
1551#define STB0899_MATSTRM 0xf610
1552#define STB0899_MATSTRL 0xf611
1553#define STB0899_UPLSTRM 0xf612
1554#define STB0899_UPLSTRL 0xf613
1555#define STB0899_DFLSTRM 0xf614
1556#define STB0899_DFLSTRL 0xf615
1557#define STB0899_SYNCSTR 0xf616
1558#define STB0899_SYNCDSTRM 0xf617
1559#define STB0899_SYNCDSTRL 0xf618
1560
1561#define STB0899_CFGPDELSTATUS1 0xf619
1562#define STB0899_BADDFL (0x01 << 6)
1563#define STB0899_OFFST_BADDFL 6
1564#define STB0899_WIDTH_BADDFL 1
1565#define STB0899_CONTINUOUS_STREAM (0x01 << 5)
1566#define STB0899_OFFST_CONTINUOUS_STREAM 5
1567#define STB0899_WIDTH_CONTINUOUS_STREAM 1
1568#define STB0899_ACCEPTED_STREAM (0x01 << 4)
1569#define STB0899_OFFST_ACCEPTED_STREAM 4
1570#define STB0899_WIDTH_ACCEPTED_STREAM 1
1571#define STB0899_BCH_ERRFLAG (0x01 << 3)
1572#define STB0899_OFFST_BCH_ERRFLAG 3
1573#define STB0899_WIDTH_BCH_ERRFLAG 1
1574#define STB0899_CRCRES (0x01 << 2)
1575#define STB0899_OFFST_CRCRES 2
1576#define STB0899_WIDTH_CRCRES 1
1577#define STB0899_CFGPDELSTATUS_LOCK (0x01 << 1)
1578#define STB0899_OFFST_CFGPDELSTATUS_LOCK 1
1579#define STB0899_WIDTH_CFGPDELSTATUS_LOCK 1
1580#define STB0899_1STLOCK (0x01 << 0)
1581#define STB0899_OFFST_1STLOCK 0
1582#define STB0899_WIDTH_1STLOCK 1
1583
1584#define STB0899_CFGPDELSTATUS2 0xf61a
1585#define STB0899_BBFERRORM 0xf61b
1586#define STB0899_BBFERRORL 0xf61c
1587#define STB0899_UPKTERRORM 0xf61d
1588#define STB0899_UPKTERRORL 0xf61e
1589
1590#define STB0899_TSTCK 0xff10
1591
1592#define STB0899_TSTRES 0xff11
1593#define STB0899_FRESLDPC (0x01 << 7)
1594#define STB0899_OFFST_FRESLDPC 7
1595#define STB0899_WIDTH_FRESLDPC 1
1596#define STB0899_FRESRS (0x01 << 6)
1597#define STB0899_OFFST_FRESRS 6
1598#define STB0899_WIDTH_FRESRS 1
1599#define STB0899_FRESVIT (0x01 << 5)
1600#define STB0899_OFFST_FRESVIT 5
1601#define STB0899_WIDTH_FRESVIT 1
1602#define STB0899_FRESMAS1_2 (0x01 << 4)
1603#define STB0899_OFFST_FRESMAS1_2 4
1604#define STB0899_WIDTH_FRESMAS1_2 1
1605#define STB0899_FRESACS (0x01 << 3)
1606#define STB0899_OFFST_FRESACS 3
1607#define STB0899_WIDTH_FRESACS 1
1608#define STB0899_FRESSYM (0x01 << 2)
1609#define STB0899_OFFST_FRESSYM 2
1610#define STB0899_WIDTH_FRESSYM 1
1611#define STB0899_FRESMAS (0x01 << 1)
1612#define STB0899_OFFST_FRESMAS 1
1613#define STB0899_WIDTH_FRESMAS 1
1614#define STB0899_FRESINT (0x01 << 0)
1615#define STB0899_OFFST_FRESINIT 0
1616#define STB0899_WIDTH_FRESINIT 1
1617
1618#define STB0899_TSTOUT 0xff12
1619#define STB0899_EN_SIGNATURE (0x01 << 7)
1620#define STB0899_OFFST_EN_SIGNATURE 7
1621#define STB0899_WIDTH_EN_SIGNATURE 1
1622#define STB0899_BCLK_CLK (0x01 << 6)
1623#define STB0899_OFFST_BCLK_CLK 6
1624#define STB0899_WIDTH_BCLK_CLK 1
1625#define STB0899_SGNL_OUT (0x01 << 5)
1626#define STB0899_OFFST_SGNL_OUT 5
1627#define STB0899_WIDTH_SGNL_OUT 1
1628#define STB0899_TS (0x01 << 4)
1629#define STB0899_OFFST_TS 4
1630#define STB0899_WIDTH_TS 1
1631#define STB0899_CTEST (0x01 << 0)
1632#define STB0899_OFFST_CTEST 0
1633#define STB0899_WIDTH_CTEST 1
1634
1635#define STB0899_TSTIN 0xff13
1636#define STB0899_TEST_IN (0x01 << 7)
1637#define STB0899_OFFST_TEST_IN 7
1638#define STB0899_WIDTH_TEST_IN 1
1639#define STB0899_EN_ADC (0x01 << 6)
1640#define STB0899_OFFST_EN_ADC 6
1641#define STB0899_WIDTH_ENADC 1
1642#define STB0899_SGN_ADC (0x01 << 5)
1643#define STB0899_OFFST_SGN_ADC 5
1644#define STB0899_WIDTH_SGN_ADC 1
1645#define STB0899_BCLK_IN (0x01 << 4)
1646#define STB0899_OFFST_BCLK_IN 4
1647#define STB0899_WIDTH_BCLK_IN 1
1648#define STB0899_JETONIN_MODE (0x01 << 3)
1649#define STB0899_OFFST_JETONIN_MODE 3
1650#define STB0899_WIDTH_JETONIN_MODE 1
1651#define STB0899_BCLK_VALUE (0x01 << 2)
1652#define STB0899_OFFST_BCLK_VALUE 2
1653#define STB0899_WIDTH_BCLK_VALUE 1
1654#define STB0899_SGNRST_T12 (0x01 << 1)
1655#define STB0899_OFFST_SGNRST_T12 1
1656#define STB0899_WIDTH_SGNRST_T12 1
1657#define STB0899_LOWSP_ENAX (0x01 << 0)
1658#define STB0899_OFFST_LOWSP_ENAX 0
1659#define STB0899_WIDTH_LOWSP_ENAX 1
1660
1661#define STB0899_TSTSYS 0xff14
1662#define STB0899_TSTCHIP 0xff15
1663#define STB0899_TSTFREE 0xff16
1664#define STB0899_TSTI2C 0xff17
1665#define STB0899_BITSPEEDM 0xff1c
1666#define STB0899_BITSPEEDL 0xff1d
1667#define STB0899_TBUSBIT 0xff1e
1668#define STB0899_TSTDIS 0xff24
1669#define STB0899_TSTDISRX 0xff25
1670#define STB0899_TSTJETON 0xff28
1671#define STB0899_TSTDCADJ 0xff40
1672#define STB0899_TSTAGC1 0xff41
1673#define STB0899_TSTAGC1N 0xff42
1674#define STB0899_TSTPOLYPH 0xff48
1675#define STB0899_TSTR 0xff49
1676#define STB0899_TSTAGC2 0xff4a
1677#define STB0899_TSTCTL1 0xff4b
1678#define STB0899_TSTCTL2 0xff4c
1679#define STB0899_TSTCTL3 0xff4d
1680#define STB0899_TSTDEMAP 0xff50
1681#define STB0899_TSTDEMAP2 0xff51
1682#define STB0899_TSTDEMMON 0xff52
1683#define STB0899_TSTRATE 0xff53
1684#define STB0899_TSTSELOUT 0xff54
1685#define STB0899_TSYNC 0xff55
1686#define STB0899_TSTERR 0xff56
1687#define STB0899_TSTRAM1 0xff58
1688#define STB0899_TSTVSELOUT 0xff59
1689#define STB0899_TSTFORCEIN 0xff5a
1690#define STB0899_TSTRS1 0xff5c
1691#define STB0899_TSTRS2 0xff5d
1692#define STB0899_TSTRS3 0xff53
1693
1694#define STB0899_INTBUFSTATUS 0xf200
1695#define STB0899_INTBUFCTRL 0xf201
1696#define STB0899_PCKLENUL 0xf55e
1697#define STB0899_PCKLENLL 0xf55f
1698#define STB0899_RSPCKLEN 0xf560
1699
1700/* 2 registers */
1701#define STB0899_SYNCDCST 0xf60c
1702
1703/* DiSEqC */
1704#define STB0899_DISCNTRL1 0xf0a0
1705#define STB0899_TIMOFF (0x01 << 7)
1706#define STB0899_OFFST_TIMOFF 7
1707#define STB0899_WIDTH_TIMOFF 1
1708#define STB0899_DISEQCRESET (0x01 << 6)
1709#define STB0899_OFFST_DISEQCRESET 6
1710#define STB0899_WIDTH_DISEQCRESET 1
1711#define STB0899_TIMCMD (0x03 << 4)
1712#define STB0899_OFFST_TIMCMD 4
1713#define STB0899_WIDTH_TIMCMD 2
1714#define STB0899_DISPRECHARGE (0x01 << 2)
1715#define STB0899_OFFST_DISPRECHARGE 2
1716#define STB0899_WIDTH_DISPRECHARGE 1
1717#define STB0899_DISEQCMODE (0x03 << 0)
1718#define STB0899_OFFST_DISEQCMODE 0
1719#define STB0899_WIDTH_DISEQCMODE 2
1720
1721#define STB0899_DISCNTRL2 0xf0a1
1722#define STB0899_RECEIVER_ON (0x01 << 7)
1723#define STB0899_OFFST_RECEIVER_ON 7
1724#define STB0899_WIDTH_RECEIVER_ON 1
1725#define STB0899_IGNO_SHORT_22K (0x01 << 6)
1726#define STB0899_OFFST_IGNO_SHORT_22K 6
1727#define STB0899_WIDTH_IGNO_SHORT_22K 1
1728#define STB0899_ONECHIP_TRX (0x01 << 5)
1729#define STB0899_OFFST_ONECHIP_TRX 5
1730#define STB0899_WIDTH_ONECHIP_TRX 1
1731#define STB0899_EXT_ENVELOP (0x01 << 4)
1732#define STB0899_OFFST_EXT_ENVELOP 4
1733#define STB0899_WIDTH_EXT_ENVELOP 1
1734#define STB0899_PIN_SELECT (0x03 << 2)
1735#define STB0899_OFFST_PIN_SELCT 2
1736#define STB0899_WIDTH_PIN_SELCT 2
1737#define STB0899_IRQ_RXEND (0x01 << 1)
1738#define STB0899_OFFST_IRQ_RXEND 1
1739#define STB0899_WIDTH_IRQ_RXEND 1
1740#define STB0899_IRQ_4NBYTES (0x01 << 0)
1741#define STB0899_OFFST_IRQ_4NBYTES 0
1742#define STB0899_WIDTH_IRQ_4NBYTES 1
1743
1744#define STB0899_DISRX_ST0 0xf0a4
1745#define STB0899_RXEND (0x01 << 7)
1746#define STB0899_OFFST_RXEND 7
1747#define STB0899_WIDTH_RXEND 1
1748#define STB0899_RXACTIVE (0x01 << 6)
1749#define STB0899_OFFST_RXACTIVE 6
1750#define STB0899_WIDTH_RXACTIVE 1
1751#define STB0899_SHORT22K (0x01 << 5)
1752#define STB0899_OFFST_SHORT22K 5
1753#define STB0899_WIDTH_SHORT22K 1
1754#define STB0899_CONTTONE (0x01 << 4)
1755#define STB0899_OFFST_CONTTONE 4
1756#define STB0899_WIDTH_CONTONE 1
1757#define STB0899_4BFIFOREDY (0x01 << 3)
1758#define STB0899_OFFST_4BFIFOREDY 3
1759#define STB0899_WIDTH_4BFIFOREDY 1
1760#define STB0899_FIFOEMPTY (0x01 << 2)
1761#define STB0899_OFFST_FIFOEMPTY 2
1762#define STB0899_WIDTH_FIFOEMPTY 1
1763#define STB0899_ABORTTRX (0x01 << 0)
1764#define STB0899_OFFST_ABORTTRX 0
1765#define STB0899_WIDTH_ABORTTRX 1
1766
1767#define STB0899_DISRX_ST1 0xf0a5
1768#define STB0899_RXFAIL (0x01 << 7)
1769#define STB0899_OFFST_RXFAIL 7
1770#define STB0899_WIDTH_RXFAIL 1
1771#define STB0899_FIFOPFAIL (0x01 << 6)
1772#define STB0899_OFFST_FIFOPFAIL 6
1773#define STB0899_WIDTH_FIFOPFAIL 1
1774#define STB0899_RXNONBYTES (0x01 << 5)
1775#define STB0899_OFFST_RXNONBYTES 5
1776#define STB0899_WIDTH_RXNONBYTES 1
1777#define STB0899_FIFOOVF (0x01 << 4)
1778#define STB0899_OFFST_FIFOOVF 4
1779#define STB0899_WIDTH_FIFOOVF 1
1780#define STB0899_FIFOBYTENBR (0x0f << 0)
1781#define STB0899_OFFST_FIFOBYTENBR 0
1782#define STB0899_WIDTH_FIFOBYTENBR 4
1783
1784#define STB0899_DISPARITY 0xf0a6
1785
1786#define STB0899_DISFIFO 0xf0a7
1787
1788#define STB0899_DISSTATUS 0xf0a8
1789#define STB0899_FIFOFULL (0x01 << 6)
1790#define STB0899_OFFST_FIFOFULL 6
1791#define STB0899_WIDTH_FIFOFULL 1
1792#define STB0899_TXIDLE (0x01 << 5)
1793#define STB0899_OFFST_TXIDLE 5
1794#define STB0899_WIDTH_TXIDLE 1
1795#define STB0899_GAPBURST (0x01 << 4)
1796#define STB0899_OFFST_GAPBURST 4
1797#define STB0899_WIDTH_GAPBURST 1
1798#define STB0899_TXFIFOBYTES (0x0f << 0)
1799#define STB0899_OFFST_TXFIFOBYTES 0
1800#define STB0899_WIDTH_TXFIFOBYTES 4
1801#define STB0899_DISF22 0xf0a9
1802
1803#define STB0899_DISF22RX 0xf0aa
1804
1805/* General Purpose */
1806#define STB0899_SYSREG 0xf101
1807#define STB0899_ACRPRESC 0xf110
1808#define STB0899_OFFST_RSVD2 7
1809#define STB0899_WIDTH_RSVD2 1
1810#define STB0899_OFFST_ACRPRESC 4
1811#define STB0899_WIDTH_ACRPRESC 3
1812#define STB0899_OFFST_RSVD1 3
1813#define STB0899_WIDTH_RSVD1 1
1814#define STB0899_OFFST_ACRPRESC2 0
1815#define STB0899_WIDTH_ACRPRESC2 3
1816
1817#define STB0899_ACRDIV1 0xf111
1818#define STB0899_ACRDIV2 0xf112
1819#define STB0899_DACR1 0xf113
1820#define STB0899_DACR2 0xf114
1821#define STB0899_OUTCFG 0xf11c
1822#define STB0899_MODECFG 0xf11d
1823#define STB0899_NCOARSE 0xf1b3
1824
1825#define STB0899_SYNTCTRL 0xf1b6
1826#define STB0899_STANDBY (0x01 << 7)
1827#define STB0899_OFFST_STANDBY 7
1828#define STB0899_WIDTH_STANDBY 1
1829#define STB0899_BYPASSPLL (0x01 << 6)
1830#define STB0899_OFFST_BYPASSPLL 6
1831#define STB0899_WIDTH_BYPASSPLL 1
1832#define STB0899_SEL1XRATIO (0x01 << 5)
1833#define STB0899_OFFST_SEL1XRATIO 5
1834#define STB0899_WIDTH_SEL1XRATIO 1
1835#define STB0899_SELOSCI (0x01 << 1)
1836#define STB0899_OFFST_SELOSCI 1
1837#define STB0899_WIDTH_SELOSCI 1
1838
1839#define STB0899_FILTCTRL 0xf1b7
1840#define STB0899_SYSCTRL 0xf1b8
1841
1842#define STB0899_STOPCLK1 0xf1c2
1843#define STB0899_STOP_CKINTBUF108 (0x01 << 7)
1844#define STB0899_OFFST_STOP_CKINTBUF108 7
1845#define STB0899_WIDTH_STOP_CKINTBUF108 1
1846#define STB0899_STOP_CKINTBUF216 (0x01 << 6)
1847#define STB0899_OFFST_STOP_CKINTBUF216 6
1848#define STB0899_WIDTH_STOP_CKINTBUF216 1
1849#define STB0899_STOP_CHK8PSK (0x01 << 5)
1850#define STB0899_OFFST_STOP_CHK8PSK 5
1851#define STB0899_WIDTH_STOP_CHK8PSK 1
1852#define STB0899_STOP_CKFEC108 (0x01 << 4)
1853#define STB0899_OFFST_STOP_CKFEC108 4
1854#define STB0899_WIDTH_STOP_CKFEC108 1
1855#define STB0899_STOP_CKFEC216 (0x01 << 3)
1856#define STB0899_OFFST_STOP_CKFEC216 3
1857#define STB0899_WIDTH_STOP_CKFEC216 1
1858#define STB0899_STOP_CKCORE216 (0x01 << 2)
1859#define STB0899_OFFST_STOP_CKCORE216 2
1860#define STB0899_WIDTH_STOP_CKCORE216 1
1861#define STB0899_STOP_CKADCI108 (0x01 << 1)
1862#define STB0899_OFFST_STOP_CKADCI108 1
1863#define STB0899_WIDTH_STOP_CKADCI108 1
1864#define STB0899_STOP_INVCKADCI108 (0x01 << 0)
1865#define STB0899_OFFST_STOP_INVCKADCI108 0
1866#define STB0899_WIDTH_STOP_INVCKADCI108 1
1867
1868#define STB0899_STOPCLK2 0xf1c3
1869#define STB0899_STOP_CKS2DMD108 (0x01 << 2)
1870#define STB0899_OFFST_STOP_CKS2DMD108 2
1871#define STB0899_WIDTH_STOP_CKS2DMD108 1
1872#define STB0899_STOP_CKPKDLIN108 (0x01 << 1)
1873#define STB0899_OFFST_STOP_CKPKDLIN108 1
1874#define STB0899_WIDTH_STOP_CKPKDLIN108 1
1875#define STB0899_STOP_CKPKDLIN216 (0x01 << 0)
1876#define STB0899_OFFST_STOP_CKPKDLIN216 0
1877#define STB0899_WIDTH_STOP_CKPKDLIN216 1
1878
1879#define STB0899_TSTTNR1 0xf1e0
1880#define STB0899_BYPASS_ADC (0x01 << 7)
1881#define STB0899_OFFST_BYPASS_ADC 7
1882#define STB0899_WIDTH_BYPASS_ADC 1
1883#define STB0899_INVADCICKOUT (0x01 << 6)
1884#define STB0899_OFFST_INVADCICKOUT 6
1885#define STB0899_WIDTH_INVADCICKOUT 1
1886#define STB0899_ADCTEST_VOLTAGE (0x03 << 4)
1887#define STB0899_OFFST_ADCTEST_VOLTAGE 4
1888#define STB0899_WIDTH_ADCTEST_VOLTAGE 1
1889#define STB0899_ADC_RESET (0x01 << 3)
1890#define STB0899_OFFST_ADC_RESET 3
1891#define STB0899_WIDTH_ADC_RESET 1
1892#define STB0899_TSTTNR1_2 (0x01 << 2)
1893#define STB0899_OFFST_TSTTNR1_2 2
1894#define STB0899_WIDTH_TSTTNR1_2 1
1895#define STB0899_ADCPON (0x01 << 1)
1896#define STB0899_OFFST_ADCPON 1
1897#define STB0899_WIDTH_ADCPON 1
1898#define STB0899_ADCIN_MODE (0x01 << 0)
1899#define STB0899_OFFST_ADCIN_MODE 0
1900#define STB0899_WIDTH_ADCIN_MODE 1
1901
1902#define STB0899_TSTTNR2 0xf1e1
1903#define STB0899_TSTTNR2_7 (0x01 << 7)
1904#define STB0899_OFFST_TSTTNR2_7 7
1905#define STB0899_WIDTH_TSTTNR2_7 1
1906#define STB0899_NOT_DISRX_WIRED (0x01 << 6)
1907#define STB0899_OFFST_NOT_DISRX_WIRED 6
1908#define STB0899_WIDTH_NOT_DISRX_WIRED 1
1909#define STB0899_DISEQC_DCURRENT (0x01 << 5)
1910#define STB0899_OFFST_DISEQC_DCURRENT 5
1911#define STB0899_WIDTH_DISEQC_DCURRENT 1
1912#define STB0899_DISEQC_ZCURRENT (0x01 << 4)
1913#define STB0899_OFFST_DISEQC_ZCURRENT 4
1914#define STB0899_WIDTH_DISEQC_ZCURRENT 1
1915#define STB0899_DISEQC_SINC_SOURCE (0x03 << 2)
1916#define STB0899_OFFST_DISEQC_SINC_SOURCE 2
1917#define STB0899_WIDTH_DISEQC_SINC_SOURCE 2
1918#define STB0899_SELIQSRC (0x03 << 0)
1919#define STB0899_OFFST_SELIQSRC 0
1920#define STB0899_WIDTH_SELIQSRC 2
1921
1922#define STB0899_TSTTNR3 0xf1e2
1923
1924#define STB0899_I2CCFG 0xf129
1925#define STB0899_I2CCFGRSVD (0x0f << 4)
1926#define STB0899_OFFST_I2CCFGRSVD 4
1927#define STB0899_WIDTH_I2CCFGRSVD 4
1928#define STB0899_I2CFASTMODE (0x01 << 3)
1929#define STB0899_OFFST_I2CFASTMODE 3
1930#define STB0899_WIDTH_I2CFASTMODE 1
1931#define STB0899_STATUSWR (0x01 << 2)
1932#define STB0899_OFFST_STATUSWR 2
1933#define STB0899_WIDTH_STATUSWR 1
1934#define STB0899_I2CADDRINC (0x03 << 0)
1935#define STB0899_OFFST_I2CADDRINC 0
1936#define STB0899_WIDTH_I2CADDRINC 2
1937
1938#define STB0899_I2CRPT 0xf12a
1939#define STB0899_I2CTON (0x01 << 7)
1940#define STB0899_OFFST_I2CTON 7
1941#define STB0899_WIDTH_I2CTON 1
1942#define STB0899_ENARPTLEVEL (0x01 << 6)
1943#define STB0899_OFFST_ENARPTLEVEL 6
1944#define STB0899_WIDTH_ENARPTLEVEL 2
1945#define STB0899_SCLTDELAY (0x01 << 3)
1946#define STB0899_OFFST_SCLTDELAY 3
1947#define STB0899_WIDTH_SCLTDELAY 1
1948#define STB0899_STOPENA (0x01 << 2)
1949#define STB0899_OFFST_STOPENA 2
1950#define STB0899_WIDTH_STOPENA 1
1951#define STB0899_STOPSDAT2SDA (0x01 << 1)
1952#define STB0899_OFFST_STOPSDAT2SDA 1
1953#define STB0899_WIDTH_STOPSDAT2SDA 1
1954
1955#define STB0899_IOPVALUE8 0xf136
1956#define STB0899_IOPVALUE7 0xf137
1957#define STB0899_IOPVALUE6 0xf138
1958#define STB0899_IOPVALUE5 0xf139
1959#define STB0899_IOPVALUE4 0xf13a
1960#define STB0899_IOPVALUE3 0xf13b
1961#define STB0899_IOPVALUE2 0xf13c
1962#define STB0899_IOPVALUE1 0xf13d
1963#define STB0899_IOPVALUE0 0xf13e
1964
1965#define STB0899_GPIO00CFG 0xf140
1966
1967#define STB0899_GPIO01CFG 0xf141
1968#define STB0899_GPIO02CFG 0xf142
1969#define STB0899_GPIO03CFG 0xf143
1970#define STB0899_GPIO04CFG 0xf144
1971#define STB0899_GPIO05CFG 0xf145
1972#define STB0899_GPIO06CFG 0xf146
1973#define STB0899_GPIO07CFG 0xf147
1974#define STB0899_GPIO08CFG 0xf148
1975#define STB0899_GPIO09CFG 0xf149
1976#define STB0899_GPIO10CFG 0xf14a
1977#define STB0899_GPIO11CFG 0xf14b
1978#define STB0899_GPIO12CFG 0xf14c
1979#define STB0899_GPIO13CFG 0xf14d
1980#define STB0899_GPIO14CFG 0xf14e
1981#define STB0899_GPIO15CFG 0xf14f
1982#define STB0899_GPIO16CFG 0xf150
1983#define STB0899_GPIO17CFG 0xf151
1984#define STB0899_GPIO18CFG 0xf152
1985#define STB0899_GPIO19CFG 0xf153
1986#define STB0899_GPIO20CFG 0xf154
1987
1988#define STB0899_SDATCFG 0xf155
1989#define STB0899_SCLTCFG 0xf156
1990#define STB0899_AGCRFCFG 0xf157
1991#define STB0899_GPIO22 0xf158 /* AGCBB2CFG */
1992#define STB0899_GPIO21 0xf159 /* AGCBB1CFG */
1993#define STB0899_DIRCLKCFG 0xf15a
1994#define STB0899_CLKOUT27CFG 0xf15b
1995#define STB0899_STDBYCFG 0xf15c
1996#define STB0899_CS0CFG 0xf15d
1997#define STB0899_CS1CFG 0xf15e
1998#define STB0899_DISEQCOCFG 0xf15f
1999
2000#define STB0899_GPIO32CFG 0xf160
2001#define STB0899_GPIO33CFG 0xf161
2002#define STB0899_GPIO34CFG 0xf162
2003#define STB0899_GPIO35CFG 0xf163
2004#define STB0899_GPIO36CFG 0xf164
2005#define STB0899_GPIO37CFG 0xf165
2006#define STB0899_GPIO38CFG 0xf166
2007#define STB0899_GPIO39CFG 0xf167
2008
2009#define STB0899_IRQSTATUS_3 0xf120
2010#define STB0899_IRQSTATUS_2 0xf121
2011#define STB0899_IRQSTATUS_1 0xf122
2012#define STB0899_IRQSTATUS_0 0xf123
2013
2014#define STB0899_IRQMSK_3 0xf124
2015#define STB0899_IRQMSK_2 0xf125
2016#define STB0899_IRQMSK_1 0xf126
2017#define STB0899_IRQMSK_0 0xf127
2018
2019#define STB0899_IRQCFG 0xf128
2020
2021#define STB0899_GHOSTREG 0xf000
2022
2023#define STB0899_S2DEMOD 0xf3fc
2024#define STB0899_S2FEC 0xfafc
2025
2026
2027#endif
diff --git a/drivers/media/dvb/frontends/stb6000.c b/drivers/media/dvb/frontends/stb6000.c
new file mode 100644
index 00000000000..ed699647050
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6000.c
@@ -0,0 +1,256 @@
1 /*
2 Driver for ST STB6000 DVBS Silicon tuner
3
4 Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23#include <linux/slab.h>
24#include <linux/module.h>
25#include <linux/dvb/frontend.h>
26#include <asm/types.h>
27
28#include "stb6000.h"
29
30static int debug;
31#define dprintk(args...) \
32 do { \
33 if (debug) \
34 printk(KERN_DEBUG "stb6000: " args); \
35 } while (0)
36
37struct stb6000_priv {
38 /* i2c details */
39 int i2c_address;
40 struct i2c_adapter *i2c;
41 u32 frequency;
42};
43
44static int stb6000_release(struct dvb_frontend *fe)
45{
46 kfree(fe->tuner_priv);
47 fe->tuner_priv = NULL;
48 return 0;
49}
50
51static int stb6000_sleep(struct dvb_frontend *fe)
52{
53 struct stb6000_priv *priv = fe->tuner_priv;
54 int ret;
55 u8 buf[] = { 10, 0 };
56 struct i2c_msg msg = {
57 .addr = priv->i2c_address,
58 .flags = 0,
59 .buf = buf,
60 .len = 2
61 };
62
63 dprintk("%s:\n", __func__);
64
65 if (fe->ops.i2c_gate_ctrl)
66 fe->ops.i2c_gate_ctrl(fe, 1);
67
68 ret = i2c_transfer(priv->i2c, &msg, 1);
69 if (ret != 1)
70 dprintk("%s: i2c error\n", __func__);
71
72 if (fe->ops.i2c_gate_ctrl)
73 fe->ops.i2c_gate_ctrl(fe, 0);
74
75 return (ret == 1) ? 0 : ret;
76}
77
78static int stb6000_set_params(struct dvb_frontend *fe,
79 struct dvb_frontend_parameters *params)
80{
81 struct stb6000_priv *priv = fe->tuner_priv;
82 unsigned int n, m;
83 int ret;
84 u32 freq_mhz;
85 int bandwidth;
86 u8 buf[12];
87 struct i2c_msg msg = {
88 .addr = priv->i2c_address,
89 .flags = 0,
90 .buf = buf,
91 .len = 12
92 };
93
94 dprintk("%s:\n", __func__);
95
96 freq_mhz = params->frequency / 1000;
97 bandwidth = params->u.qpsk.symbol_rate / 1000000;
98
99 if (bandwidth > 31)
100 bandwidth = 31;
101
102 if ((freq_mhz > 949) && (freq_mhz < 2151)) {
103 buf[0] = 0x01;
104 buf[1] = 0xac;
105 if (freq_mhz < 1950)
106 buf[1] = 0xaa;
107 if (freq_mhz < 1800)
108 buf[1] = 0xa8;
109 if (freq_mhz < 1650)
110 buf[1] = 0xa6;
111 if (freq_mhz < 1530)
112 buf[1] = 0xa5;
113 if (freq_mhz < 1470)
114 buf[1] = 0xa4;
115 if (freq_mhz < 1370)
116 buf[1] = 0xa2;
117 if (freq_mhz < 1300)
118 buf[1] = 0xa1;
119 if (freq_mhz < 1200)
120 buf[1] = 0xa0;
121 if (freq_mhz < 1075)
122 buf[1] = 0xbc;
123 if (freq_mhz < 1000)
124 buf[1] = 0xba;
125 if (freq_mhz < 1075) {
126 n = freq_mhz / 8; /* vco=lo*4 */
127 m = 2;
128 } else {
129 n = freq_mhz / 16; /* vco=lo*2 */
130 m = 1;
131 }
132 buf[2] = n >> 1;
133 buf[3] = (unsigned char)(((n & 1) << 7) |
134 (m * freq_mhz - n * 16) | 0x60);
135 buf[4] = 0x04;
136 buf[5] = 0x0e;
137
138 buf[6] = (unsigned char)(bandwidth);
139
140 buf[7] = 0xd8;
141 buf[8] = 0xd0;
142 buf[9] = 0x50;
143 buf[10] = 0xeb;
144 buf[11] = 0x4f;
145
146 if (fe->ops.i2c_gate_ctrl)
147 fe->ops.i2c_gate_ctrl(fe, 1);
148
149 ret = i2c_transfer(priv->i2c, &msg, 1);
150 if (ret != 1)
151 dprintk("%s: i2c error\n", __func__);
152
153 udelay(10);
154 if (fe->ops.i2c_gate_ctrl)
155 fe->ops.i2c_gate_ctrl(fe, 0);
156
157 buf[0] = 0x07;
158 buf[1] = 0xdf;
159 buf[2] = 0xd0;
160 buf[3] = 0x50;
161 buf[4] = 0xfb;
162 msg.len = 5;
163
164 if (fe->ops.i2c_gate_ctrl)
165 fe->ops.i2c_gate_ctrl(fe, 1);
166
167 ret = i2c_transfer(priv->i2c, &msg, 1);
168 if (ret != 1)
169 dprintk("%s: i2c error\n", __func__);
170
171 udelay(10);
172 if (fe->ops.i2c_gate_ctrl)
173 fe->ops.i2c_gate_ctrl(fe, 0);
174
175 priv->frequency = freq_mhz * 1000;
176
177 return (ret == 1) ? 0 : ret;
178 }
179 return -1;
180}
181
182static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
183{
184 struct stb6000_priv *priv = fe->tuner_priv;
185 *frequency = priv->frequency;
186 return 0;
187}
188
189static struct dvb_tuner_ops stb6000_tuner_ops = {
190 .info = {
191 .name = "ST STB6000",
192 .frequency_min = 950000,
193 .frequency_max = 2150000
194 },
195 .release = stb6000_release,
196 .sleep = stb6000_sleep,
197 .set_params = stb6000_set_params,
198 .get_frequency = stb6000_get_frequency,
199};
200
201struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
202 struct i2c_adapter *i2c)
203{
204 struct stb6000_priv *priv = NULL;
205 u8 b0[] = { 0 };
206 u8 b1[] = { 0, 0 };
207 struct i2c_msg msg[2] = {
208 {
209 .addr = addr,
210 .flags = 0,
211 .buf = b0,
212 .len = 0
213 }, {
214 .addr = addr,
215 .flags = I2C_M_RD,
216 .buf = b1,
217 .len = 2
218 }
219 };
220 int ret;
221
222 dprintk("%s:\n", __func__);
223
224 if (fe->ops.i2c_gate_ctrl)
225 fe->ops.i2c_gate_ctrl(fe, 1);
226
227 /* is some i2c device here ? */
228 ret = i2c_transfer(i2c, msg, 2);
229 if (fe->ops.i2c_gate_ctrl)
230 fe->ops.i2c_gate_ctrl(fe, 0);
231
232 if (ret != 2)
233 return NULL;
234
235 priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL);
236 if (priv == NULL)
237 return NULL;
238
239 priv->i2c_address = addr;
240 priv->i2c = i2c;
241
242 memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops,
243 sizeof(struct dvb_tuner_ops));
244
245 fe->tuner_priv = priv;
246
247 return fe;
248}
249EXPORT_SYMBOL(stb6000_attach);
250
251module_param(debug, int, 0644);
252MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
253
254MODULE_DESCRIPTION("DVB STB6000 driver");
255MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
256MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stb6000.h b/drivers/media/dvb/frontends/stb6000.h
new file mode 100644
index 00000000000..7be479c22d5
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6000.h
@@ -0,0 +1,51 @@
1 /*
2 Driver for ST stb6000 DVBS Silicon tuner
3
4 Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23#ifndef __DVB_STB6000_H__
24#define __DVB_STB6000_H__
25
26#include <linux/i2c.h>
27#include "dvb_frontend.h"
28
29/**
30 * Attach a stb6000 tuner to the supplied frontend structure.
31 *
32 * @param fe Frontend to attach to.
33 * @param addr i2c address of the tuner.
34 * @param i2c i2c adapter to use.
35 * @return FE pointer on success, NULL on failure.
36 */
37#if defined(CONFIG_DVB_STB6000) || (defined(CONFIG_DVB_STB6000_MODULE) \
38 && defined(MODULE))
39extern struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
40 struct i2c_adapter *i2c);
41#else
42static inline struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe,
43 int addr,
44 struct i2c_adapter *i2c)
45{
46 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
47 return NULL;
48}
49#endif /* CONFIG_DVB_STB6000 */
50
51#endif /* __DVB_STB6000_H__ */
diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c
new file mode 100644
index 00000000000..bc1a8af4f6e
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6100.c
@@ -0,0 +1,612 @@
1/*
2 STB6100 Silicon Tuner
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/slab.h>
26#include <linux/string.h>
27
28#include "dvb_frontend.h"
29#include "stb6100.h"
30
31static unsigned int verbose;
32module_param(verbose, int, 0644);
33
34
35#define FE_ERROR 0
36#define FE_NOTICE 1
37#define FE_INFO 2
38#define FE_DEBUG 3
39
40#define dprintk(x, y, z, format, arg...) do { \
41 if (z) { \
42 if ((x > FE_ERROR) && (x > y)) \
43 printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
44 else if ((x > FE_NOTICE) && (x > y)) \
45 printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
46 else if ((x > FE_INFO) && (x > y)) \
47 printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
48 else if ((x > FE_DEBUG) && (x > y)) \
49 printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
50 } else { \
51 if (x > y) \
52 printk(format, ##arg); \
53 } \
54} while (0)
55
56struct stb6100_lkup {
57 u32 val_low;
58 u32 val_high;
59 u8 reg;
60};
61
62static int stb6100_release(struct dvb_frontend *fe);
63
64static const struct stb6100_lkup lkup[] = {
65 { 0, 950000, 0x0a },
66 { 950000, 1000000, 0x0a },
67 { 1000000, 1075000, 0x0c },
68 { 1075000, 1200000, 0x00 },
69 { 1200000, 1300000, 0x01 },
70 { 1300000, 1370000, 0x02 },
71 { 1370000, 1470000, 0x04 },
72 { 1470000, 1530000, 0x05 },
73 { 1530000, 1650000, 0x06 },
74 { 1650000, 1800000, 0x08 },
75 { 1800000, 1950000, 0x0a },
76 { 1950000, 2150000, 0x0c },
77 { 2150000, 9999999, 0x0c },
78 { 0, 0, 0x00 }
79};
80
81/* Register names for easy debugging. */
82static const char *stb6100_regnames[] = {
83 [STB6100_LD] = "LD",
84 [STB6100_VCO] = "VCO",
85 [STB6100_NI] = "NI",
86 [STB6100_NF_LSB] = "NF",
87 [STB6100_K] = "K",
88 [STB6100_G] = "G",
89 [STB6100_F] = "F",
90 [STB6100_DLB] = "DLB",
91 [STB6100_TEST1] = "TEST1",
92 [STB6100_FCCK] = "FCCK",
93 [STB6100_LPEN] = "LPEN",
94 [STB6100_TEST3] = "TEST3",
95};
96
97/* Template for normalisation, i.e. setting unused or undocumented
98 * bits as required according to the documentation.
99 */
100struct stb6100_regmask {
101 u8 mask;
102 u8 set;
103};
104
105static const struct stb6100_regmask stb6100_template[] = {
106 [STB6100_LD] = { 0xff, 0x00 },
107 [STB6100_VCO] = { 0xff, 0x00 },
108 [STB6100_NI] = { 0xff, 0x00 },
109 [STB6100_NF_LSB] = { 0xff, 0x00 },
110 [STB6100_K] = { 0xc7, 0x38 },
111 [STB6100_G] = { 0xef, 0x10 },
112 [STB6100_F] = { 0x1f, 0xc0 },
113 [STB6100_DLB] = { 0x38, 0xc4 },
114 [STB6100_TEST1] = { 0x00, 0x8f },
115 [STB6100_FCCK] = { 0x40, 0x0d },
116 [STB6100_LPEN] = { 0xf0, 0x0b },
117 [STB6100_TEST3] = { 0x00, 0xde },
118};
119
120/*
121 * Currently unused. Some boards might need it in the future
122 */
123static inline void stb6100_normalise_regs(u8 regs[])
124{
125 int i;
126
127 for (i = 0; i < STB6100_NUMREGS; i++)
128 regs[i] = (regs[i] & stb6100_template[i].mask) | stb6100_template[i].set;
129}
130
131static int stb6100_read_regs(struct stb6100_state *state, u8 regs[])
132{
133 int rc;
134 struct i2c_msg msg = {
135 .addr = state->config->tuner_address,
136 .flags = I2C_M_RD,
137 .buf = regs,
138 .len = STB6100_NUMREGS
139 };
140
141 rc = i2c_transfer(state->i2c, &msg, 1);
142 if (unlikely(rc != 1)) {
143 dprintk(verbose, FE_ERROR, 1, "Read (0x%x) err, rc=[%d]",
144 state->config->tuner_address, rc);
145
146 return -EREMOTEIO;
147 }
148 if (unlikely(verbose > FE_DEBUG)) {
149 int i;
150
151 dprintk(verbose, FE_DEBUG, 1, " Read from 0x%02x", state->config->tuner_address);
152 for (i = 0; i < STB6100_NUMREGS; i++)
153 dprintk(verbose, FE_DEBUG, 1, " %s: 0x%02x", stb6100_regnames[i], regs[i]);
154 }
155 return 0;
156}
157
158static int stb6100_read_reg(struct stb6100_state *state, u8 reg)
159{
160 u8 regs[STB6100_NUMREGS];
161 int rc;
162
163 struct i2c_msg msg = {
164 .addr = state->config->tuner_address + reg,
165 .flags = I2C_M_RD,
166 .buf = regs,
167 .len = 1
168 };
169
170 rc = i2c_transfer(state->i2c, &msg, 1);
171
172 if (unlikely(reg >= STB6100_NUMREGS)) {
173 dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
174 return -EINVAL;
175 }
176 if (unlikely(verbose > FE_DEBUG)) {
177 dprintk(verbose, FE_DEBUG, 1, " Read from 0x%02x", state->config->tuner_address);
178 dprintk(verbose, FE_DEBUG, 1, " %s: 0x%02x", stb6100_regnames[reg], regs[0]);
179 }
180
181 return (unsigned int)regs[0];
182}
183
184static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int start, int len)
185{
186 int rc;
187 u8 cmdbuf[len + 1];
188 struct i2c_msg msg = {
189 .addr = state->config->tuner_address,
190 .flags = 0,
191 .buf = cmdbuf,
192 .len = len + 1
193 };
194
195 if (unlikely(start < 1 || start + len > STB6100_NUMREGS)) {
196 dprintk(verbose, FE_ERROR, 1, "Invalid register range %d:%d",
197 start, len);
198 return -EINVAL;
199 }
200 memcpy(&cmdbuf[1], buf, len);
201 cmdbuf[0] = start;
202
203 if (unlikely(verbose > FE_DEBUG)) {
204 int i;
205
206 dprintk(verbose, FE_DEBUG, 1, " Write @ 0x%02x: [%d:%d]", state->config->tuner_address, start, len);
207 for (i = 0; i < len; i++)
208 dprintk(verbose, FE_DEBUG, 1, " %s: 0x%02x", stb6100_regnames[start + i], buf[i]);
209 }
210 rc = i2c_transfer(state->i2c, &msg, 1);
211 if (unlikely(rc != 1)) {
212 dprintk(verbose, FE_ERROR, 1, "(0x%x) write err [%d:%d], rc=[%d]",
213 (unsigned int)state->config->tuner_address, start, len, rc);
214 return -EREMOTEIO;
215 }
216 return 0;
217}
218
219static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data)
220{
221 if (unlikely(reg >= STB6100_NUMREGS)) {
222 dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
223 return -EREMOTEIO;
224 }
225 data = (data & stb6100_template[reg].mask) | stb6100_template[reg].set;
226 return stb6100_write_reg_range(state, &data, reg, 1);
227}
228
229
230static int stb6100_get_status(struct dvb_frontend *fe, u32 *status)
231{
232 int rc;
233 struct stb6100_state *state = fe->tuner_priv;
234
235 rc = stb6100_read_reg(state, STB6100_LD);
236 if (rc < 0) {
237 dprintk(verbose, FE_ERROR, 1, "%s failed", __func__);
238 return rc;
239 }
240 return (rc & STB6100_LD_LOCK) ? TUNER_STATUS_LOCKED : 0;
241}
242
243static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
244{
245 int rc;
246 u8 f;
247 struct stb6100_state *state = fe->tuner_priv;
248
249 rc = stb6100_read_reg(state, STB6100_F);
250 if (rc < 0)
251 return rc;
252 f = rc & STB6100_F_F;
253
254 state->status.bandwidth = (f + 5) * 2000; /* x2 for ZIF */
255
256 *bandwidth = state->bandwidth = state->status.bandwidth * 1000;
257 dprintk(verbose, FE_DEBUG, 1, "bandwidth = %u Hz", state->bandwidth);
258 return 0;
259}
260
261static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
262{
263 u32 tmp;
264 int rc;
265 struct stb6100_state *state = fe->tuner_priv;
266
267 dprintk(verbose, FE_DEBUG, 1, "set bandwidth to %u Hz", bandwidth);
268
269 bandwidth /= 2; /* ZIF */
270
271 if (bandwidth >= 36000000) /* F[4:0] BW/2 max =31+5=36 mhz for F=31 */
272 tmp = 31;
273 else if (bandwidth <= 5000000) /* bw/2 min = 5Mhz for F=0 */
274 tmp = 0;
275 else /* if 5 < bw/2 < 36 */
276 tmp = (bandwidth + 500000) / 1000000 - 5;
277
278 /* Turn on LPF bandwidth setting clock control,
279 * set bandwidth, wait 10ms, turn off.
280 */
281 rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d | STB6100_FCCK_FCCK);
282 if (rc < 0)
283 return rc;
284 rc = stb6100_write_reg(state, STB6100_F, 0xc0 | tmp);
285 if (rc < 0)
286 return rc;
287
288 msleep(5); /* This is dangerous as another (related) thread may start */
289
290 rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d);
291 if (rc < 0)
292 return rc;
293
294 msleep(10); /* This is dangerous as another (related) thread may start */
295
296 return 0;
297}
298
299static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
300{
301 int rc;
302 u32 nint, nfrac, fvco;
303 int psd2, odiv;
304 struct stb6100_state *state = fe->tuner_priv;
305 u8 regs[STB6100_NUMREGS];
306
307 rc = stb6100_read_regs(state, regs);
308 if (rc < 0)
309 return rc;
310
311 odiv = (regs[STB6100_VCO] & STB6100_VCO_ODIV) >> STB6100_VCO_ODIV_SHIFT;
312 psd2 = (regs[STB6100_K] & STB6100_K_PSD2) >> STB6100_K_PSD2_SHIFT;
313 nint = regs[STB6100_NI];
314 nfrac = ((regs[STB6100_K] & STB6100_K_NF_MSB) << 8) | regs[STB6100_NF_LSB];
315 fvco = (nfrac * state->reference >> (9 - psd2)) + (nint * state->reference << psd2);
316 *frequency = state->frequency = fvco >> (odiv + 1);
317
318 dprintk(verbose, FE_DEBUG, 1,
319 "frequency = %u kHz, odiv = %u, psd2 = %u, fxtal = %u kHz, fvco = %u kHz, N(I) = %u, N(F) = %u",
320 state->frequency, odiv, psd2, state->reference, fvco, nint, nfrac);
321 return 0;
322}
323
324
325static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
326{
327 int rc;
328 const struct stb6100_lkup *ptr;
329 struct stb6100_state *state = fe->tuner_priv;
330 struct dvb_frontend_parameters p;
331
332 u32 srate = 0, fvco, nint, nfrac;
333 u8 regs[STB6100_NUMREGS];
334 u8 g, psd2, odiv;
335
336 dprintk(verbose, FE_DEBUG, 1, "Version 2010-8-14 13:51");
337
338 if (fe->ops.get_frontend) {
339 dprintk(verbose, FE_DEBUG, 1, "Get frontend parameters");
340 fe->ops.get_frontend(fe, &p);
341 }
342 srate = p.u.qpsk.symbol_rate;
343
344 /* Set up tuner cleanly, LPF calibration on */
345 rc = stb6100_write_reg(state, STB6100_FCCK, 0x4d | STB6100_FCCK_FCCK);
346 if (rc < 0)
347 return rc; /* allow LPF calibration */
348
349 /* PLL Loop disabled, bias on, VCO on, synth on */
350 regs[STB6100_LPEN] = 0xeb;
351 rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN]);
352 if (rc < 0)
353 return rc;
354
355 /* Program the registers with their data values */
356
357 /* VCO divide ratio (LO divide ratio, VCO prescaler enable). */
358 if (frequency <= 1075000)
359 odiv = 1;
360 else
361 odiv = 0;
362
363 /* VCO enabled, search clock off as per LL3.7, 3.4.1 */
364 regs[STB6100_VCO] = 0xe0 | (odiv << STB6100_VCO_ODIV_SHIFT);
365
366 /* OSM */
367 for (ptr = lkup;
368 (ptr->val_high != 0) && !CHKRANGE(frequency, ptr->val_low, ptr->val_high);
369 ptr++);
370
371 if (ptr->val_high == 0) {
372 printk(KERN_ERR "%s: frequency out of range: %u kHz\n", __func__, frequency);
373 return -EINVAL;
374 }
375 regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_OSM) | ptr->reg;
376 rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
377 if (rc < 0)
378 return rc;
379
380 if ((frequency > 1075000) && (frequency <= 1325000))
381 psd2 = 0;
382 else
383 psd2 = 1;
384 /* F(VCO) = F(LO) * (ODIV == 0 ? 2 : 4) */
385 fvco = frequency << (1 + odiv);
386 /* N(I) = floor(f(VCO) / (f(XTAL) * (PSD2 ? 2 : 1))) */
387 nint = fvco / (state->reference << psd2);
388 /* N(F) = round(f(VCO) / f(XTAL) * (PSD2 ? 2 : 1) - N(I)) * 2 ^ 9 */
389 nfrac = DIV_ROUND_CLOSEST((fvco - (nint * state->reference << psd2))
390 << (9 - psd2), state->reference);
391
392 /* NI */
393 regs[STB6100_NI] = nint;
394 rc = stb6100_write_reg(state, STB6100_NI, regs[STB6100_NI]);
395 if (rc < 0)
396 return rc;
397
398 /* NF */
399 regs[STB6100_NF_LSB] = nfrac;
400 rc = stb6100_write_reg(state, STB6100_NF_LSB, regs[STB6100_NF_LSB]);
401 if (rc < 0)
402 return rc;
403
404 /* K */
405 regs[STB6100_K] = (0x38 & ~STB6100_K_PSD2) | (psd2 << STB6100_K_PSD2_SHIFT);
406 regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_NF_MSB) | ((nfrac >> 8) & STB6100_K_NF_MSB);
407 rc = stb6100_write_reg(state, STB6100_K, regs[STB6100_K]);
408 if (rc < 0)
409 return rc;
410
411 /* G Baseband gain. */
412 if (srate >= 15000000)
413 g = 9; /* +4 dB */
414 else if (srate >= 5000000)
415 g = 11; /* +8 dB */
416 else
417 g = 14; /* +14 dB */
418
419 regs[STB6100_G] = (0x10 & ~STB6100_G_G) | g;
420 regs[STB6100_G] &= ~STB6100_G_GCT; /* mask GCT */
421 regs[STB6100_G] |= (1 << 5); /* 2Vp-p Mode */
422 rc = stb6100_write_reg(state, STB6100_G, regs[STB6100_G]);
423 if (rc < 0)
424 return rc;
425
426 /* F we don't write as it is set up in BW set */
427
428 /* DLB set DC servo loop BW to 160Hz (LLA 3.8 / 2.1) */
429 regs[STB6100_DLB] = 0xcc;
430 rc = stb6100_write_reg(state, STB6100_DLB, regs[STB6100_DLB]);
431 if (rc < 0)
432 return rc;
433
434 dprintk(verbose, FE_DEBUG, 1,
435 "frequency = %u, srate = %u, g = %u, odiv = %u, psd2 = %u, fxtal = %u, osm = %u, fvco = %u, N(I) = %u, N(F) = %u",
436 frequency, srate, (unsigned int)g, (unsigned int)odiv,
437 (unsigned int)psd2, state->reference,
438 ptr->reg, fvco, nint, nfrac);
439
440 /* Set up the test registers */
441 regs[STB6100_TEST1] = 0x8f;
442 rc = stb6100_write_reg(state, STB6100_TEST1, regs[STB6100_TEST1]);
443 if (rc < 0)
444 return rc;
445 regs[STB6100_TEST3] = 0xde;
446 rc = stb6100_write_reg(state, STB6100_TEST3, regs[STB6100_TEST3]);
447 if (rc < 0)
448 return rc;
449
450 /* Bring up tuner according to LLA 3.7 3.4.1, step 2 */
451 regs[STB6100_LPEN] = 0xfb; /* PLL Loop enabled, bias on, VCO on, synth on */
452 rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN]);
453 if (rc < 0)
454 return rc;
455
456 msleep(2);
457
458 /* Bring up tuner according to LLA 3.7 3.4.1, step 3 */
459 regs[STB6100_VCO] &= ~STB6100_VCO_OCK; /* VCO fast search */
460 rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
461 if (rc < 0)
462 return rc;
463
464 msleep(10); /* This is dangerous as another (related) thread may start */ /* wait for LO to lock */
465
466 regs[STB6100_VCO] &= ~STB6100_VCO_OSCH; /* vco search disabled */
467 regs[STB6100_VCO] |= STB6100_VCO_OCK; /* search clock off */
468 rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO]);
469 if (rc < 0)
470 return rc;
471
472 rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d);
473 if (rc < 0)
474 return rc; /* Stop LPF calibration */
475
476 msleep(10); /* This is dangerous as another (related) thread may start */
477 /* wait for stabilisation, (should not be necessary) */
478 return 0;
479}
480
481static int stb6100_sleep(struct dvb_frontend *fe)
482{
483 /* TODO: power down */
484 return 0;
485}
486
487static int stb6100_init(struct dvb_frontend *fe)
488{
489 struct stb6100_state *state = fe->tuner_priv;
490 struct tuner_state *status = &state->status;
491
492 status->tunerstep = 125000;
493 status->ifreq = 0;
494 status->refclock = 27000000; /* Hz */
495 status->iqsense = 1;
496 status->bandwidth = 36000; /* kHz */
497 state->bandwidth = status->bandwidth * 1000; /* Hz */
498 state->reference = status->refclock / 1000; /* kHz */
499
500 /* Set default bandwidth. Modified, PN 13-May-10 */
501 return 0;
502}
503
504static int stb6100_get_state(struct dvb_frontend *fe,
505 enum tuner_param param,
506 struct tuner_state *state)
507{
508 switch (param) {
509 case DVBFE_TUNER_FREQUENCY:
510 stb6100_get_frequency(fe, &state->frequency);
511 break;
512 case DVBFE_TUNER_TUNERSTEP:
513 break;
514 case DVBFE_TUNER_IFFREQ:
515 break;
516 case DVBFE_TUNER_BANDWIDTH:
517 stb6100_get_bandwidth(fe, &state->bandwidth);
518 break;
519 case DVBFE_TUNER_REFCLOCK:
520 break;
521 default:
522 break;
523 }
524
525 return 0;
526}
527
528static int stb6100_set_state(struct dvb_frontend *fe,
529 enum tuner_param param,
530 struct tuner_state *state)
531{
532 struct stb6100_state *tstate = fe->tuner_priv;
533
534 switch (param) {
535 case DVBFE_TUNER_FREQUENCY:
536 stb6100_set_frequency(fe, state->frequency);
537 tstate->frequency = state->frequency;
538 break;
539 case DVBFE_TUNER_TUNERSTEP:
540 break;
541 case DVBFE_TUNER_IFFREQ:
542 break;
543 case DVBFE_TUNER_BANDWIDTH:
544 stb6100_set_bandwidth(fe, state->bandwidth);
545 tstate->bandwidth = state->bandwidth;
546 break;
547 case DVBFE_TUNER_REFCLOCK:
548 break;
549 default:
550 break;
551 }
552
553 return 0;
554}
555
556static struct dvb_tuner_ops stb6100_ops = {
557 .info = {
558 .name = "STB6100 Silicon Tuner",
559 .frequency_min = 950000,
560 .frequency_max = 2150000,
561 .frequency_step = 0,
562 },
563
564 .init = stb6100_init,
565 .sleep = stb6100_sleep,
566 .get_status = stb6100_get_status,
567 .get_state = stb6100_get_state,
568 .set_state = stb6100_set_state,
569 .release = stb6100_release
570};
571
572struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
573 const struct stb6100_config *config,
574 struct i2c_adapter *i2c)
575{
576 struct stb6100_state *state = NULL;
577
578 state = kzalloc(sizeof (struct stb6100_state), GFP_KERNEL);
579 if (state == NULL)
580 goto error;
581
582 state->config = config;
583 state->i2c = i2c;
584 state->frontend = fe;
585 state->reference = config->refclock / 1000; /* kHz */
586 fe->tuner_priv = state;
587 fe->ops.tuner_ops = stb6100_ops;
588
589 printk("%s: Attaching STB6100 \n", __func__);
590 return fe;
591
592error:
593 kfree(state);
594 return NULL;
595}
596
597static int stb6100_release(struct dvb_frontend *fe)
598{
599 struct stb6100_state *state = fe->tuner_priv;
600
601 fe->tuner_priv = NULL;
602 kfree(state);
603
604 return 0;
605}
606
607EXPORT_SYMBOL(stb6100_attach);
608MODULE_PARM_DESC(verbose, "Set Verbosity level");
609
610MODULE_AUTHOR("Manu Abraham");
611MODULE_DESCRIPTION("STB6100 Silicon tuner");
612MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stb6100.h b/drivers/media/dvb/frontends/stb6100.h
new file mode 100644
index 00000000000..2ab096614b3
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6100.h
@@ -0,0 +1,115 @@
1/*
2 STB6100 Silicon Tuner
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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#ifndef __STB_6100_REG_H
23#define __STB_6100_REG_H
24
25#include <linux/dvb/frontend.h>
26#include "dvb_frontend.h"
27
28#define STB6100_LD 0x00
29#define STB6100_LD_LOCK (1 << 0)
30
31#define STB6100_VCO 0x01
32#define STB6100_VCO_OSCH (0x01 << 7)
33#define STB6100_VCO_OSCH_SHIFT 7
34#define STB6100_VCO_OCK (0x03 << 5)
35#define STB6100_VCO_OCK_SHIFT 5
36#define STB6100_VCO_ODIV (0x01 << 4)
37#define STB6100_VCO_ODIV_SHIFT 4
38#define STB6100_VCO_OSM (0x0f << 0)
39
40#define STB6100_NI 0x02
41#define STB6100_NF_LSB 0x03
42
43#define STB6100_K 0x04
44#define STB6100_K_PSD2 (0x01 << 2)
45#define STB6100_K_PSD2_SHIFT 2
46#define STB6100_K_NF_MSB (0x03 << 0)
47
48#define STB6100_G 0x05
49#define STB6100_G_G (0x0f << 0)
50#define STB6100_G_GCT (0x07 << 5)
51
52#define STB6100_F 0x06
53#define STB6100_F_F (0x1f << 0)
54
55#define STB6100_DLB 0x07
56
57#define STB6100_TEST1 0x08
58
59#define STB6100_FCCK 0x09
60#define STB6100_FCCK_FCCK (0x01 << 6)
61
62#define STB6100_LPEN 0x0a
63#define STB6100_LPEN_LPEN (0x01 << 4)
64#define STB6100_LPEN_SYNP (0x01 << 5)
65#define STB6100_LPEN_OSCP (0x01 << 6)
66#define STB6100_LPEN_BEN (0x01 << 7)
67
68#define STB6100_TEST3 0x0b
69
70#define STB6100_NUMREGS 0x0c
71
72
73#define INRANGE(val, x, y) (((x <= val) && (val <= y)) || \
74 ((y <= val) && (val <= x)) ? 1 : 0)
75
76#define CHKRANGE(val, x, y) (((val >= x) && (val < y)) ? 1 : 0)
77
78struct stb6100_config {
79 u8 tuner_address;
80 u32 refclock;
81};
82
83struct stb6100_state {
84 struct i2c_adapter *i2c;
85
86 const struct stb6100_config *config;
87 struct dvb_tuner_ops ops;
88 struct dvb_frontend *frontend;
89 struct tuner_state status;
90
91 u32 frequency;
92 u32 srate;
93 u32 bandwidth;
94 u32 reference;
95};
96
97#if defined(CONFIG_DVB_STB6100) || (defined(CONFIG_DVB_STB6100_MODULE) && defined(MODULE))
98
99extern struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
100 const struct stb6100_config *config,
101 struct i2c_adapter *i2c);
102
103#else
104
105static inline struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe,
106 const struct stb6100_config *config,
107 struct i2c_adapter *i2c)
108{
109 printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
110 return NULL;
111}
112
113#endif //CONFIG_DVB_STB6100
114
115#endif
diff --git a/drivers/media/dvb/frontends/stb6100_cfg.h b/drivers/media/dvb/frontends/stb6100_cfg.h
new file mode 100644
index 00000000000..6314d18c797
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6100_cfg.h
@@ -0,0 +1,104 @@
1/*
2 STB6100 Silicon Tuner
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 Copyright (C) ST Microelectronics
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
22static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
23{
24 struct dvb_frontend_ops *frontend_ops = NULL;
25 struct dvb_tuner_ops *tuner_ops = NULL;
26 struct tuner_state t_state;
27 int err = 0;
28
29 if (&fe->ops)
30 frontend_ops = &fe->ops;
31 if (&frontend_ops->tuner_ops)
32 tuner_ops = &frontend_ops->tuner_ops;
33 if (tuner_ops->get_state) {
34 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
35 printk("%s: Invalid parameter\n", __func__);
36 return err;
37 }
38 *frequency = t_state.frequency;
39 }
40 return 0;
41}
42
43static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
44{
45 struct dvb_frontend_ops *frontend_ops = NULL;
46 struct dvb_tuner_ops *tuner_ops = NULL;
47 struct tuner_state t_state;
48 int err = 0;
49
50 t_state.frequency = frequency;
51 if (&fe->ops)
52 frontend_ops = &fe->ops;
53 if (&frontend_ops->tuner_ops)
54 tuner_ops = &frontend_ops->tuner_ops;
55 if (tuner_ops->set_state) {
56 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
57 printk("%s: Invalid parameter\n", __func__);
58 return err;
59 }
60 }
61 return 0;
62}
63
64static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
65{
66 struct dvb_frontend_ops *frontend_ops = &fe->ops;
67 struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
68 struct tuner_state t_state;
69 int err = 0;
70
71 if (&fe->ops)
72 frontend_ops = &fe->ops;
73 if (&frontend_ops->tuner_ops)
74 tuner_ops = &frontend_ops->tuner_ops;
75 if (tuner_ops->get_state) {
76 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
77 printk("%s: Invalid parameter\n", __func__);
78 return err;
79 }
80 *bandwidth = t_state.bandwidth;
81 }
82 return 0;
83}
84
85static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
86{
87 struct dvb_frontend_ops *frontend_ops = NULL;
88 struct dvb_tuner_ops *tuner_ops = NULL;
89 struct tuner_state t_state;
90 int err = 0;
91
92 t_state.bandwidth = bandwidth;
93 if (&fe->ops)
94 frontend_ops = &fe->ops;
95 if (&frontend_ops->tuner_ops)
96 tuner_ops = &frontend_ops->tuner_ops;
97 if (tuner_ops->set_state) {
98 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
99 printk("%s: Invalid parameter\n", __func__);
100 return err;
101 }
102 }
103 return 0;
104}
diff --git a/drivers/media/dvb/frontends/stb6100_proc.h b/drivers/media/dvb/frontends/stb6100_proc.h
new file mode 100644
index 00000000000..112163a4862
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6100_proc.h
@@ -0,0 +1,138 @@
1/*
2 STB6100 Silicon Tuner wrapper
3 Copyright (C)2009 Igor M. Liplianin (liplianin@me.by)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 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
20static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency)
21{
22 struct dvb_frontend_ops *frontend_ops = NULL;
23 struct dvb_tuner_ops *tuner_ops = NULL;
24 struct tuner_state state;
25 int err = 0;
26
27 if (&fe->ops)
28 frontend_ops = &fe->ops;
29 if (&frontend_ops->tuner_ops)
30 tuner_ops = &frontend_ops->tuner_ops;
31 if (tuner_ops->get_state) {
32 if (frontend_ops->i2c_gate_ctrl)
33 frontend_ops->i2c_gate_ctrl(fe, 1);
34
35 err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &state);
36 if (err < 0) {
37 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
38 return err;
39 }
40
41 if (frontend_ops->i2c_gate_ctrl)
42 frontend_ops->i2c_gate_ctrl(fe, 0);
43
44 *frequency = state.frequency;
45 }
46
47 return 0;
48}
49
50static int stb6100_set_freq(struct dvb_frontend *fe, u32 frequency)
51{
52 struct dvb_frontend_ops *frontend_ops = NULL;
53 struct dvb_tuner_ops *tuner_ops = NULL;
54 struct tuner_state state;
55 int err = 0;
56
57 state.frequency = frequency;
58 if (&fe->ops)
59 frontend_ops = &fe->ops;
60 if (&frontend_ops->tuner_ops)
61 tuner_ops = &frontend_ops->tuner_ops;
62 if (tuner_ops->set_state) {
63 if (frontend_ops->i2c_gate_ctrl)
64 frontend_ops->i2c_gate_ctrl(fe, 1);
65
66 err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &state);
67 if (err < 0) {
68 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
69 return err;
70 }
71
72 if (frontend_ops->i2c_gate_ctrl)
73 frontend_ops->i2c_gate_ctrl(fe, 0);
74
75 }
76
77 return 0;
78}
79
80static int stb6100_get_bandw(struct dvb_frontend *fe, u32 *bandwidth)
81{
82 struct dvb_frontend_ops *frontend_ops = NULL;
83 struct dvb_tuner_ops *tuner_ops = NULL;
84 struct tuner_state state;
85 int err = 0;
86
87 if (&fe->ops)
88 frontend_ops = &fe->ops;
89 if (&frontend_ops->tuner_ops)
90 tuner_ops = &frontend_ops->tuner_ops;
91 if (tuner_ops->get_state) {
92 if (frontend_ops->i2c_gate_ctrl)
93 frontend_ops->i2c_gate_ctrl(fe, 1);
94
95 err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &state);
96 if (err < 0) {
97 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
98 return err;
99 }
100
101 if (frontend_ops->i2c_gate_ctrl)
102 frontend_ops->i2c_gate_ctrl(fe, 0);
103
104 *bandwidth = state.bandwidth;
105 }
106
107 return 0;
108}
109
110static int stb6100_set_bandw(struct dvb_frontend *fe, u32 bandwidth)
111{
112 struct dvb_frontend_ops *frontend_ops = NULL;
113 struct dvb_tuner_ops *tuner_ops = NULL;
114 struct tuner_state state;
115 int err = 0;
116
117 state.bandwidth = bandwidth;
118 if (&fe->ops)
119 frontend_ops = &fe->ops;
120 if (&frontend_ops->tuner_ops)
121 tuner_ops = &frontend_ops->tuner_ops;
122 if (tuner_ops->set_state) {
123 if (frontend_ops->i2c_gate_ctrl)
124 frontend_ops->i2c_gate_ctrl(fe, 1);
125
126 err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &state);
127 if (err < 0) {
128 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
129 return err;
130 }
131
132 if (frontend_ops->i2c_gate_ctrl)
133 frontend_ops->i2c_gate_ctrl(fe, 0);
134
135 }
136
137 return 0;
138}
diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c
new file mode 100644
index 00000000000..8e0cfadba68
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0288.c
@@ -0,0 +1,624 @@
1/*
2 Driver for ST STV0288 demodulator
3 Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
4 for Reel Multimedia
5 Copyright (C) 2008 TurboSight.com, Bob Liu <bob@turbosight.com>
6 Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
7 Removed stb6000 specific tuner code and revised some
8 procedures.
9 2010-09-01 Josef Pavlik <josef@pavlik.it>
10 Fixed diseqc_msg, diseqc_burst and set_tone problems
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, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27
28#include <linux/init.h>
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/string.h>
32#include <linux/slab.h>
33#include <linux/jiffies.h>
34#include <asm/div64.h>
35
36#include "dvb_frontend.h"
37#include "stv0288.h"
38
39struct stv0288_state {
40 struct i2c_adapter *i2c;
41 const struct stv0288_config *config;
42 struct dvb_frontend frontend;
43
44 u8 initialised:1;
45 u32 tuner_frequency;
46 u32 symbol_rate;
47 fe_code_rate_t fec_inner;
48 int errmode;
49};
50
51#define STATUS_BER 0
52#define STATUS_UCBLOCKS 1
53
54static int debug;
55static int debug_legacy_dish_switch;
56#define dprintk(args...) \
57 do { \
58 if (debug) \
59 printk(KERN_DEBUG "stv0288: " args); \
60 } while (0)
61
62
63static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data)
64{
65 int ret;
66 u8 buf[] = { reg, data };
67 struct i2c_msg msg = {
68 .addr = state->config->demod_address,
69 .flags = 0,
70 .buf = buf,
71 .len = 2
72 };
73
74 ret = i2c_transfer(state->i2c, &msg, 1);
75
76 if (ret != 1)
77 dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
78 "ret == %i)\n", __func__, reg, data, ret);
79
80 return (ret != 1) ? -EREMOTEIO : 0;
81}
82
83static int stv0288_write(struct dvb_frontend *fe, const u8 buf[], int len)
84{
85 struct stv0288_state *state = fe->demodulator_priv;
86
87 if (len != 2)
88 return -EINVAL;
89
90 return stv0288_writeregI(state, buf[0], buf[1]);
91}
92
93static u8 stv0288_readreg(struct stv0288_state *state, u8 reg)
94{
95 int ret;
96 u8 b0[] = { reg };
97 u8 b1[] = { 0 };
98 struct i2c_msg msg[] = {
99 {
100 .addr = state->config->demod_address,
101 .flags = 0,
102 .buf = b0,
103 .len = 1
104 }, {
105 .addr = state->config->demod_address,
106 .flags = I2C_M_RD,
107 .buf = b1,
108 .len = 1
109 }
110 };
111
112 ret = i2c_transfer(state->i2c, msg, 2);
113
114 if (ret != 2)
115 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
116 __func__, reg, ret);
117
118 return b1[0];
119}
120
121static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate)
122{
123 struct stv0288_state *state = fe->demodulator_priv;
124 unsigned int temp;
125 unsigned char b[3];
126
127 if ((srate < 1000000) || (srate > 45000000))
128 return -EINVAL;
129
130 temp = (unsigned int)srate / 1000;
131
132 temp = temp * 32768;
133 temp = temp / 25;
134 temp = temp / 125;
135 b[0] = (unsigned char)((temp >> 12) & 0xff);
136 b[1] = (unsigned char)((temp >> 4) & 0xff);
137 b[2] = (unsigned char)((temp << 4) & 0xf0);
138 stv0288_writeregI(state, 0x28, 0x80); /* SFRH */
139 stv0288_writeregI(state, 0x29, 0); /* SFRM */
140 stv0288_writeregI(state, 0x2a, 0); /* SFRL */
141
142 stv0288_writeregI(state, 0x28, b[0]);
143 stv0288_writeregI(state, 0x29, b[1]);
144 stv0288_writeregI(state, 0x2a, b[2]);
145 dprintk("stv0288: stv0288_set_symbolrate\n");
146
147 return 0;
148}
149
150static int stv0288_send_diseqc_msg(struct dvb_frontend *fe,
151 struct dvb_diseqc_master_cmd *m)
152{
153 struct stv0288_state *state = fe->demodulator_priv;
154
155 int i;
156
157 dprintk("%s\n", __func__);
158
159 stv0288_writeregI(state, 0x09, 0);
160 msleep(30);
161 stv0288_writeregI(state, 0x05, 0x12);/* modulated mode, single shot */
162
163 for (i = 0; i < m->msg_len; i++) {
164 if (stv0288_writeregI(state, 0x06, m->msg[i]))
165 return -EREMOTEIO;
166 }
167 msleep(m->msg_len*12);
168 return 0;
169}
170
171static int stv0288_send_diseqc_burst(struct dvb_frontend *fe,
172 fe_sec_mini_cmd_t burst)
173{
174 struct stv0288_state *state = fe->demodulator_priv;
175
176 dprintk("%s\n", __func__);
177
178 if (stv0288_writeregI(state, 0x05, 0x03))/* burst mode, single shot */
179 return -EREMOTEIO;
180
181 if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff))
182 return -EREMOTEIO;
183
184 msleep(15);
185 if (stv0288_writeregI(state, 0x05, 0x12))
186 return -EREMOTEIO;
187
188 return 0;
189}
190
191static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
192{
193 struct stv0288_state *state = fe->demodulator_priv;
194
195 switch (tone) {
196 case SEC_TONE_ON:
197 if (stv0288_writeregI(state, 0x05, 0x10))/* cont carrier */
198 return -EREMOTEIO;
199 break;
200
201 case SEC_TONE_OFF:
202 if (stv0288_writeregI(state, 0x05, 0x12))/* burst mode off*/
203 return -EREMOTEIO;
204 break;
205
206 default:
207 return -EINVAL;
208 }
209 return 0;
210}
211
212static u8 stv0288_inittab[] = {
213 0x01, 0x15,
214 0x02, 0x20,
215 0x09, 0x0,
216 0x0a, 0x4,
217 0x0b, 0x0,
218 0x0c, 0x0,
219 0x0d, 0x0,
220 0x0e, 0xd4,
221 0x0f, 0x30,
222 0x11, 0x80,
223 0x12, 0x03,
224 0x13, 0x48,
225 0x14, 0x84,
226 0x15, 0x45,
227 0x16, 0xb7,
228 0x17, 0x9c,
229 0x18, 0x0,
230 0x19, 0xa6,
231 0x1a, 0x88,
232 0x1b, 0x8f,
233 0x1c, 0xf0,
234 0x20, 0x0b,
235 0x21, 0x54,
236 0x22, 0x0,
237 0x23, 0x0,
238 0x2b, 0xff,
239 0x2c, 0xf7,
240 0x30, 0x0,
241 0x31, 0x1e,
242 0x32, 0x14,
243 0x33, 0x0f,
244 0x34, 0x09,
245 0x35, 0x0c,
246 0x36, 0x05,
247 0x37, 0x2f,
248 0x38, 0x16,
249 0x39, 0xbe,
250 0x3a, 0x0,
251 0x3b, 0x13,
252 0x3c, 0x11,
253 0x3d, 0x30,
254 0x40, 0x63,
255 0x41, 0x04,
256 0x42, 0x20,
257 0x43, 0x00,
258 0x44, 0x00,
259 0x45, 0x00,
260 0x46, 0x00,
261 0x47, 0x00,
262 0x4a, 0x00,
263 0x50, 0x10,
264 0x51, 0x38,
265 0x52, 0x21,
266 0x58, 0x54,
267 0x59, 0x86,
268 0x5a, 0x0,
269 0x5b, 0x9b,
270 0x5c, 0x08,
271 0x5d, 0x7f,
272 0x5e, 0x0,
273 0x5f, 0xff,
274 0x70, 0x0,
275 0x71, 0x0,
276 0x72, 0x0,
277 0x74, 0x0,
278 0x75, 0x0,
279 0x76, 0x0,
280 0x81, 0x0,
281 0x82, 0x3f,
282 0x83, 0x3f,
283 0x84, 0x0,
284 0x85, 0x0,
285 0x88, 0x0,
286 0x89, 0x0,
287 0x8a, 0x0,
288 0x8b, 0x0,
289 0x8c, 0x0,
290 0x90, 0x0,
291 0x91, 0x0,
292 0x92, 0x0,
293 0x93, 0x0,
294 0x94, 0x1c,
295 0x97, 0x0,
296 0xa0, 0x48,
297 0xa1, 0x0,
298 0xb0, 0xb8,
299 0xb1, 0x3a,
300 0xb2, 0x10,
301 0xb3, 0x82,
302 0xb4, 0x80,
303 0xb5, 0x82,
304 0xb6, 0x82,
305 0xb7, 0x82,
306 0xb8, 0x20,
307 0xb9, 0x0,
308 0xf0, 0x0,
309 0xf1, 0x0,
310 0xf2, 0xc0,
311 0x51, 0x36,
312 0x52, 0x09,
313 0x53, 0x94,
314 0x54, 0x62,
315 0x55, 0x29,
316 0x56, 0x64,
317 0x57, 0x2b,
318 0xff, 0xff,
319};
320
321static int stv0288_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
322{
323 dprintk("%s: %s\n", __func__,
324 volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
325 volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
326
327 return 0;
328}
329
330static int stv0288_init(struct dvb_frontend *fe)
331{
332 struct stv0288_state *state = fe->demodulator_priv;
333 int i;
334 u8 reg;
335 u8 val;
336
337 dprintk("stv0288: init chip\n");
338 stv0288_writeregI(state, 0x41, 0x04);
339 msleep(50);
340
341 /* we have default inittab */
342 if (state->config->inittab == NULL) {
343 for (i = 0; !(stv0288_inittab[i] == 0xff &&
344 stv0288_inittab[i + 1] == 0xff); i += 2)
345 stv0288_writeregI(state, stv0288_inittab[i],
346 stv0288_inittab[i + 1]);
347 } else {
348 for (i = 0; ; i += 2) {
349 reg = state->config->inittab[i];
350 val = state->config->inittab[i+1];
351 if (reg == 0xff && val == 0xff)
352 break;
353 stv0288_writeregI(state, reg, val);
354 }
355 }
356 return 0;
357}
358
359static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status)
360{
361 struct stv0288_state *state = fe->demodulator_priv;
362
363 u8 sync = stv0288_readreg(state, 0x24);
364 if (sync == 255)
365 sync = 0;
366
367 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
368
369 *status = 0;
370 if (sync & 0x80)
371 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
372 if (sync & 0x10)
373 *status |= FE_HAS_VITERBI;
374 if (sync & 0x08) {
375 *status |= FE_HAS_LOCK;
376 dprintk("stv0288 has locked\n");
377 }
378
379 return 0;
380}
381
382static int stv0288_read_ber(struct dvb_frontend *fe, u32 *ber)
383{
384 struct stv0288_state *state = fe->demodulator_priv;
385
386 if (state->errmode != STATUS_BER)
387 return 0;
388 *ber = (stv0288_readreg(state, 0x26) << 8) |
389 stv0288_readreg(state, 0x27);
390 dprintk("stv0288_read_ber %d\n", *ber);
391
392 return 0;
393}
394
395
396static int stv0288_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
397{
398 struct stv0288_state *state = fe->demodulator_priv;
399
400 s32 signal = 0xffff - ((stv0288_readreg(state, 0x10) << 8));
401
402
403 signal = signal * 5 / 4;
404 *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
405 dprintk("stv0288_read_signal_strength %d\n", *strength);
406
407 return 0;
408}
409static int stv0288_sleep(struct dvb_frontend *fe)
410{
411 struct stv0288_state *state = fe->demodulator_priv;
412
413 stv0288_writeregI(state, 0x41, 0x84);
414 state->initialised = 0;
415
416 return 0;
417}
418static int stv0288_read_snr(struct dvb_frontend *fe, u16 *snr)
419{
420 struct stv0288_state *state = fe->demodulator_priv;
421
422 s32 xsnr = 0xffff - ((stv0288_readreg(state, 0x2d) << 8)
423 | stv0288_readreg(state, 0x2e));
424 xsnr = 3 * (xsnr - 0xa100);
425 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
426 dprintk("stv0288_read_snr %d\n", *snr);
427
428 return 0;
429}
430
431static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
432{
433 struct stv0288_state *state = fe->demodulator_priv;
434
435 if (state->errmode != STATUS_BER)
436 return 0;
437 *ucblocks = (stv0288_readreg(state, 0x26) << 8) |
438 stv0288_readreg(state, 0x27);
439 dprintk("stv0288_read_ber %d\n", *ucblocks);
440
441 return 0;
442}
443
444static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p)
445{
446 dprintk("%s(..)\n", __func__);
447 return 0;
448}
449
450static int stv0288_get_property(struct dvb_frontend *fe, struct dtv_property *p)
451{
452 dprintk("%s(..)\n", __func__);
453 return 0;
454}
455
456static int stv0288_set_frontend(struct dvb_frontend *fe,
457 struct dvb_frontend_parameters *dfp)
458{
459 struct stv0288_state *state = fe->demodulator_priv;
460 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
461
462 char tm;
463 unsigned char tda[3];
464
465 dprintk("%s : FE_SET_FRONTEND\n", __func__);
466
467 if (c->delivery_system != SYS_DVBS) {
468 dprintk("%s: unsupported delivery "
469 "system selected (%d)\n",
470 __func__, c->delivery_system);
471 return -EOPNOTSUPP;
472 }
473
474 if (state->config->set_ts_params)
475 state->config->set_ts_params(fe, 0);
476
477 /* only frequency & symbol_rate are used for tuner*/
478 dfp->frequency = c->frequency;
479 dfp->u.qpsk.symbol_rate = c->symbol_rate;
480 if (fe->ops.tuner_ops.set_params) {
481 fe->ops.tuner_ops.set_params(fe, dfp);
482 if (fe->ops.i2c_gate_ctrl)
483 fe->ops.i2c_gate_ctrl(fe, 0);
484 }
485
486 udelay(10);
487 stv0288_set_symbolrate(fe, c->symbol_rate);
488 /* Carrier lock control register */
489 stv0288_writeregI(state, 0x15, 0xc5);
490
491 tda[0] = 0x2b; /* CFRM */
492 tda[2] = 0x0; /* CFRL */
493 for (tm = -6; tm < 7;) {
494 /* Viterbi status */
495 if (stv0288_readreg(state, 0x24) & 0x8)
496 break;
497
498 tda[2] += 40;
499 if (tda[2] < 40)
500 tm++;
501 tda[1] = (unsigned char)tm;
502 stv0288_writeregI(state, 0x2b, tda[1]);
503 stv0288_writeregI(state, 0x2c, tda[2]);
504 udelay(30);
505 }
506
507 state->tuner_frequency = c->frequency;
508 state->fec_inner = FEC_AUTO;
509 state->symbol_rate = c->symbol_rate;
510
511 return 0;
512}
513
514static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
515{
516 struct stv0288_state *state = fe->demodulator_priv;
517
518 if (enable)
519 stv0288_writeregI(state, 0x01, 0xb5);
520 else
521 stv0288_writeregI(state, 0x01, 0x35);
522
523 udelay(1);
524
525 return 0;
526}
527
528static void stv0288_release(struct dvb_frontend *fe)
529{
530 struct stv0288_state *state = fe->demodulator_priv;
531 kfree(state);
532}
533
534static struct dvb_frontend_ops stv0288_ops = {
535
536 .info = {
537 .name = "ST STV0288 DVB-S",
538 .type = FE_QPSK,
539 .frequency_min = 950000,
540 .frequency_max = 2150000,
541 .frequency_stepsize = 1000, /* kHz for QPSK frontends */
542 .frequency_tolerance = 0,
543 .symbol_rate_min = 1000000,
544 .symbol_rate_max = 45000000,
545 .symbol_rate_tolerance = 500, /* ppm */
546 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
547 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
548 FE_CAN_QPSK |
549 FE_CAN_FEC_AUTO
550 },
551
552 .release = stv0288_release,
553 .init = stv0288_init,
554 .sleep = stv0288_sleep,
555 .write = stv0288_write,
556 .i2c_gate_ctrl = stv0288_i2c_gate_ctrl,
557 .read_status = stv0288_read_status,
558 .read_ber = stv0288_read_ber,
559 .read_signal_strength = stv0288_read_signal_strength,
560 .read_snr = stv0288_read_snr,
561 .read_ucblocks = stv0288_read_ucblocks,
562 .diseqc_send_master_cmd = stv0288_send_diseqc_msg,
563 .diseqc_send_burst = stv0288_send_diseqc_burst,
564 .set_tone = stv0288_set_tone,
565 .set_voltage = stv0288_set_voltage,
566
567 .set_property = stv0288_set_property,
568 .get_property = stv0288_get_property,
569 .set_frontend = stv0288_set_frontend,
570};
571
572struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
573 struct i2c_adapter *i2c)
574{
575 struct stv0288_state *state = NULL;
576 int id;
577
578 /* allocate memory for the internal state */
579 state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL);
580 if (state == NULL)
581 goto error;
582
583 /* setup the state */
584 state->config = config;
585 state->i2c = i2c;
586 state->initialised = 0;
587 state->tuner_frequency = 0;
588 state->symbol_rate = 0;
589 state->fec_inner = 0;
590 state->errmode = STATUS_BER;
591
592 stv0288_writeregI(state, 0x41, 0x04);
593 msleep(200);
594 id = stv0288_readreg(state, 0x00);
595 dprintk("stv0288 id %x\n", id);
596
597 /* register 0x00 contains 0x11 for STV0288 */
598 if (id != 0x11)
599 goto error;
600
601 /* create dvb_frontend */
602 memcpy(&state->frontend.ops, &stv0288_ops,
603 sizeof(struct dvb_frontend_ops));
604 state->frontend.demodulator_priv = state;
605 return &state->frontend;
606
607error:
608 kfree(state);
609
610 return NULL;
611}
612EXPORT_SYMBOL(stv0288_attach);
613
614module_param(debug_legacy_dish_switch, int, 0444);
615MODULE_PARM_DESC(debug_legacy_dish_switch,
616 "Enable timing analysis for Dish Network legacy switches");
617
618module_param(debug, int, 0644);
619MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
620
621MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
622MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
623MODULE_LICENSE("GPL");
624
diff --git a/drivers/media/dvb/frontends/stv0288.h b/drivers/media/dvb/frontends/stv0288.h
new file mode 100644
index 00000000000..f2b53db0606
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0288.h
@@ -0,0 +1,67 @@
1/*
2 Driver for ST STV0288 demodulator
3
4 Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
5 for Reel Multimedia
6 Copyright (C) 2008 TurboSight.com, <bob@turbosight.com>
7 Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
8 Removed stb6000 specific tuner code and revised some
9 procedures.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/
26
27#ifndef STV0288_H
28#define STV0288_H
29
30#include <linux/dvb/frontend.h>
31#include "dvb_frontend.h"
32
33struct stv0288_config {
34 /* the demodulator's i2c address */
35 u8 demod_address;
36
37 u8* inittab;
38
39 /* minimum delay before retuning */
40 int min_delay_ms;
41
42 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
43};
44
45#if defined(CONFIG_DVB_STV0288) || (defined(CONFIG_DVB_STV0288_MODULE) && \
46 defined(MODULE))
47extern struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
48 struct i2c_adapter *i2c);
49#else
50static inline struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
51 struct i2c_adapter *i2c)
52{
53 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
54 return NULL;
55}
56#endif /* CONFIG_DVB_STV0288 */
57
58static inline int stv0288_writereg(struct dvb_frontend *fe, u8 reg, u8 val)
59{
60 int r = 0;
61 u8 buf[] = { reg, val };
62 if (fe->ops.write)
63 r = fe->ops.write(fe, buf, 2);
64 return r;
65}
66
67#endif /* STV0288_H */
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c
new file mode 100644
index 00000000000..84d88f33275
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0297.c
@@ -0,0 +1,723 @@
1/*
2 Driver for STV0297 demodulator
3
4 Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
5 Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de>
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#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/delay.h>
27#include <linux/jiffies.h>
28#include <linux/slab.h>
29
30#include "dvb_frontend.h"
31#include "stv0297.h"
32
33struct stv0297_state {
34 struct i2c_adapter *i2c;
35 const struct stv0297_config *config;
36 struct dvb_frontend frontend;
37
38 unsigned long last_ber;
39 unsigned long base_freq;
40};
41
42#if 1
43#define dprintk(x...) printk(x)
44#else
45#define dprintk(x...)
46#endif
47
48#define STV0297_CLOCK_KHZ 28900
49
50
51static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data)
52{
53 int ret;
54 u8 buf[] = { reg, data };
55 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };
56
57 ret = i2c_transfer(state->i2c, &msg, 1);
58
59 if (ret != 1)
60 dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
61 "ret == %i)\n", __func__, reg, data, ret);
62
63 return (ret != 1) ? -1 : 0;
64}
65
66static int stv0297_readreg(struct stv0297_state *state, u8 reg)
67{
68 int ret;
69 u8 b0[] = { reg };
70 u8 b1[] = { 0 };
71 struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
72 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
73 };
74
75 // this device needs a STOP between the register and data
76 if (state->config->stop_during_read) {
77 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
78 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
79 return -1;
80 }
81 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
82 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
83 return -1;
84 }
85 } else {
86 if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
87 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
88 return -1;
89 }
90 }
91
92 return b1[0];
93}
94
95static int stv0297_writereg_mask(struct stv0297_state *state, u8 reg, u8 mask, u8 data)
96{
97 int val;
98
99 val = stv0297_readreg(state, reg);
100 val &= ~mask;
101 val |= (data & mask);
102 stv0297_writereg(state, reg, val);
103
104 return 0;
105}
106
107static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len)
108{
109 int ret;
110 struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf =
111 &reg1,.len = 1},
112 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b,.len = len}
113 };
114
115 // this device needs a STOP between the register and data
116 if (state->config->stop_during_read) {
117 if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
118 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret);
119 return -1;
120 }
121 if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
122 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret);
123 return -1;
124 }
125 } else {
126 if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
127 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret);
128 return -1;
129 }
130 }
131
132 return 0;
133}
134
135static u32 stv0297_get_symbolrate(struct stv0297_state *state)
136{
137 u64 tmp;
138
139 tmp = stv0297_readreg(state, 0x55);
140 tmp |= stv0297_readreg(state, 0x56) << 8;
141 tmp |= stv0297_readreg(state, 0x57) << 16;
142 tmp |= stv0297_readreg(state, 0x58) << 24;
143
144 tmp *= STV0297_CLOCK_KHZ;
145 tmp >>= 32;
146
147 return (u32) tmp;
148}
149
150static void stv0297_set_symbolrate(struct stv0297_state *state, u32 srate)
151{
152 long tmp;
153
154 tmp = 131072L * srate; /* 131072 = 2^17 */
155 tmp = tmp / (STV0297_CLOCK_KHZ / 4); /* 1/4 = 2^-2 */
156 tmp = tmp * 8192L; /* 8192 = 2^13 */
157
158 stv0297_writereg(state, 0x55, (unsigned char) (tmp & 0xFF));
159 stv0297_writereg(state, 0x56, (unsigned char) (tmp >> 8));
160 stv0297_writereg(state, 0x57, (unsigned char) (tmp >> 16));
161 stv0297_writereg(state, 0x58, (unsigned char) (tmp >> 24));
162}
163
164static void stv0297_set_sweeprate(struct stv0297_state *state, short fshift, long symrate)
165{
166 long tmp;
167
168 tmp = (long) fshift *262144L; /* 262144 = 2*18 */
169 tmp /= symrate;
170 tmp *= 1024; /* 1024 = 2*10 */
171
172 // adjust
173 if (tmp >= 0) {
174 tmp += 500000;
175 } else {
176 tmp -= 500000;
177 }
178 tmp /= 1000000;
179
180 stv0297_writereg(state, 0x60, tmp & 0xFF);
181 stv0297_writereg_mask(state, 0x69, 0xF0, (tmp >> 4) & 0xf0);
182}
183
184static void stv0297_set_carrieroffset(struct stv0297_state *state, long offset)
185{
186 long tmp;
187
188 /* symrate is hardcoded to 10000 */
189 tmp = offset * 26844L; /* (2**28)/10000 */
190 if (tmp < 0)
191 tmp += 0x10000000;
192 tmp &= 0x0FFFFFFF;
193
194 stv0297_writereg(state, 0x66, (unsigned char) (tmp & 0xFF));
195 stv0297_writereg(state, 0x67, (unsigned char) (tmp >> 8));
196 stv0297_writereg(state, 0x68, (unsigned char) (tmp >> 16));
197 stv0297_writereg_mask(state, 0x69, 0x0F, (tmp >> 24) & 0x0f);
198}
199
200/*
201static long stv0297_get_carrieroffset(struct stv0297_state *state)
202{
203 s64 tmp;
204
205 stv0297_writereg(state, 0x6B, 0x00);
206
207 tmp = stv0297_readreg(state, 0x66);
208 tmp |= (stv0297_readreg(state, 0x67) << 8);
209 tmp |= (stv0297_readreg(state, 0x68) << 16);
210 tmp |= (stv0297_readreg(state, 0x69) & 0x0F) << 24;
211
212 tmp *= stv0297_get_symbolrate(state);
213 tmp >>= 28;
214
215 return (s32) tmp;
216}
217*/
218
219static void stv0297_set_initialdemodfreq(struct stv0297_state *state, long freq)
220{
221 s32 tmp;
222
223 if (freq > 10000)
224 freq -= STV0297_CLOCK_KHZ;
225
226 tmp = (STV0297_CLOCK_KHZ * 1000) / (1 << 16);
227 tmp = (freq * 1000) / tmp;
228 if (tmp > 0xffff)
229 tmp = 0xffff;
230
231 stv0297_writereg_mask(state, 0x25, 0x80, 0x80);
232 stv0297_writereg(state, 0x21, tmp >> 8);
233 stv0297_writereg(state, 0x20, tmp);
234}
235
236static int stv0297_set_qam(struct stv0297_state *state, fe_modulation_t modulation)
237{
238 int val = 0;
239
240 switch (modulation) {
241 case QAM_16:
242 val = 0;
243 break;
244
245 case QAM_32:
246 val = 1;
247 break;
248
249 case QAM_64:
250 val = 4;
251 break;
252
253 case QAM_128:
254 val = 2;
255 break;
256
257 case QAM_256:
258 val = 3;
259 break;
260
261 default:
262 return -EINVAL;
263 }
264
265 stv0297_writereg_mask(state, 0x00, 0x70, val << 4);
266
267 return 0;
268}
269
270static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_inversion_t inversion)
271{
272 int val = 0;
273
274 switch (inversion) {
275 case INVERSION_OFF:
276 val = 0;
277 break;
278
279 case INVERSION_ON:
280 val = 1;
281 break;
282
283 default:
284 return -EINVAL;
285 }
286
287 stv0297_writereg_mask(state, 0x83, 0x08, val << 3);
288
289 return 0;
290}
291
292static int stv0297_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
293{
294 struct stv0297_state *state = fe->demodulator_priv;
295
296 if (enable) {
297 stv0297_writereg(state, 0x87, 0x78);
298 stv0297_writereg(state, 0x86, 0xc8);
299 }
300
301 return 0;
302}
303
304static int stv0297_init(struct dvb_frontend *fe)
305{
306 struct stv0297_state *state = fe->demodulator_priv;
307 int i;
308
309 /* load init table */
310 for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2)
311 stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]);
312 msleep(200);
313
314 state->last_ber = 0;
315
316 return 0;
317}
318
319static int stv0297_sleep(struct dvb_frontend *fe)
320{
321 struct stv0297_state *state = fe->demodulator_priv;
322
323 stv0297_writereg_mask(state, 0x80, 1, 1);
324
325 return 0;
326}
327
328static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status)
329{
330 struct stv0297_state *state = fe->demodulator_priv;
331
332 u8 sync = stv0297_readreg(state, 0xDF);
333
334 *status = 0;
335 if (sync & 0x80)
336 *status |=
337 FE_HAS_SYNC | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK;
338 return 0;
339}
340
341static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber)
342{
343 struct stv0297_state *state = fe->demodulator_priv;
344 u8 BER[3];
345
346 stv0297_readregs(state, 0xA0, BER, 3);
347 if (!(BER[0] & 0x80)) {
348 state->last_ber = BER[2] << 8 | BER[1];
349 stv0297_writereg_mask(state, 0xA0, 0x80, 0x80);
350 }
351
352 *ber = state->last_ber;
353
354 return 0;
355}
356
357
358static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
359{
360 struct stv0297_state *state = fe->demodulator_priv;
361 u8 STRENGTH[3];
362 u16 tmp;
363
364 stv0297_readregs(state, 0x41, STRENGTH, 3);
365 tmp = (STRENGTH[1] & 0x03) << 8 | STRENGTH[0];
366 if (STRENGTH[2] & 0x20) {
367 if (tmp < 0x200)
368 tmp = 0;
369 else
370 tmp = tmp - 0x200;
371 } else {
372 if (tmp > 0x1ff)
373 tmp = 0;
374 else
375 tmp = 0x1ff - tmp;
376 }
377 *strength = (tmp << 7) | (tmp >> 2);
378 return 0;
379}
380
381static int stv0297_read_snr(struct dvb_frontend *fe, u16 * snr)
382{
383 struct stv0297_state *state = fe->demodulator_priv;
384 u8 SNR[2];
385
386 stv0297_readregs(state, 0x07, SNR, 2);
387 *snr = SNR[1] << 8 | SNR[0];
388
389 return 0;
390}
391
392static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
393{
394 struct stv0297_state *state = fe->demodulator_priv;
395
396 stv0297_writereg_mask(state, 0xDF, 0x03, 0x03); /* freeze the counters */
397
398 *ucblocks = (stv0297_readreg(state, 0xD5) << 8)
399 | stv0297_readreg(state, 0xD4);
400
401 stv0297_writereg_mask(state, 0xDF, 0x03, 0x02); /* clear the counters */
402 stv0297_writereg_mask(state, 0xDF, 0x03, 0x01); /* re-enable the counters */
403
404 return 0;
405}
406
407static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
408{
409 struct stv0297_state *state = fe->demodulator_priv;
410 int u_threshold;
411 int initial_u;
412 int blind_u;
413 int delay;
414 int sweeprate;
415 int carrieroffset;
416 unsigned long starttime;
417 unsigned long timeout;
418 fe_spectral_inversion_t inversion;
419
420 switch (p->u.qam.modulation) {
421 case QAM_16:
422 case QAM_32:
423 case QAM_64:
424 delay = 100;
425 sweeprate = 1000;
426 break;
427
428 case QAM_128:
429 case QAM_256:
430 delay = 200;
431 sweeprate = 500;
432 break;
433
434 default:
435 return -EINVAL;
436 }
437
438 // determine inversion dependent parameters
439 inversion = p->inversion;
440 if (state->config->invert)
441 inversion = (inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;
442 carrieroffset = -330;
443 switch (inversion) {
444 case INVERSION_OFF:
445 break;
446
447 case INVERSION_ON:
448 sweeprate = -sweeprate;
449 carrieroffset = -carrieroffset;
450 break;
451
452 default:
453 return -EINVAL;
454 }
455
456 stv0297_init(fe);
457 if (fe->ops.tuner_ops.set_params) {
458 fe->ops.tuner_ops.set_params(fe, p);
459 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
460 }
461
462 /* clear software interrupts */
463 stv0297_writereg(state, 0x82, 0x0);
464
465 /* set initial demodulation frequency */
466 stv0297_set_initialdemodfreq(state, 7250);
467
468 /* setup AGC */
469 stv0297_writereg_mask(state, 0x43, 0x10, 0x00);
470 stv0297_writereg(state, 0x41, 0x00);
471 stv0297_writereg_mask(state, 0x42, 0x03, 0x01);
472 stv0297_writereg_mask(state, 0x36, 0x60, 0x00);
473 stv0297_writereg_mask(state, 0x36, 0x18, 0x00);
474 stv0297_writereg_mask(state, 0x71, 0x80, 0x80);
475 stv0297_writereg(state, 0x72, 0x00);
476 stv0297_writereg(state, 0x73, 0x00);
477 stv0297_writereg_mask(state, 0x74, 0x0F, 0x00);
478 stv0297_writereg_mask(state, 0x43, 0x08, 0x00);
479 stv0297_writereg_mask(state, 0x71, 0x80, 0x00);
480
481 /* setup STL */
482 stv0297_writereg_mask(state, 0x5a, 0x20, 0x20);
483 stv0297_writereg_mask(state, 0x5b, 0x02, 0x02);
484 stv0297_writereg_mask(state, 0x5b, 0x02, 0x00);
485 stv0297_writereg_mask(state, 0x5b, 0x01, 0x00);
486 stv0297_writereg_mask(state, 0x5a, 0x40, 0x40);
487
488 /* disable frequency sweep */
489 stv0297_writereg_mask(state, 0x6a, 0x01, 0x00);
490
491 /* reset deinterleaver */
492 stv0297_writereg_mask(state, 0x81, 0x01, 0x01);
493 stv0297_writereg_mask(state, 0x81, 0x01, 0x00);
494
495 /* ??? */
496 stv0297_writereg_mask(state, 0x83, 0x20, 0x20);
497 stv0297_writereg_mask(state, 0x83, 0x20, 0x00);
498
499 /* reset equaliser */
500 u_threshold = stv0297_readreg(state, 0x00) & 0xf;
501 initial_u = stv0297_readreg(state, 0x01) >> 4;
502 blind_u = stv0297_readreg(state, 0x01) & 0xf;
503 stv0297_writereg_mask(state, 0x84, 0x01, 0x01);
504 stv0297_writereg_mask(state, 0x84, 0x01, 0x00);
505 stv0297_writereg_mask(state, 0x00, 0x0f, u_threshold);
506 stv0297_writereg_mask(state, 0x01, 0xf0, initial_u << 4);
507 stv0297_writereg_mask(state, 0x01, 0x0f, blind_u);
508
509 /* data comes from internal A/D */
510 stv0297_writereg_mask(state, 0x87, 0x80, 0x00);
511
512 /* clear phase registers */
513 stv0297_writereg(state, 0x63, 0x00);
514 stv0297_writereg(state, 0x64, 0x00);
515 stv0297_writereg(state, 0x65, 0x00);
516 stv0297_writereg(state, 0x66, 0x00);
517 stv0297_writereg(state, 0x67, 0x00);
518 stv0297_writereg(state, 0x68, 0x00);
519 stv0297_writereg_mask(state, 0x69, 0x0f, 0x00);
520
521 /* set parameters */
522 stv0297_set_qam(state, p->u.qam.modulation);
523 stv0297_set_symbolrate(state, p->u.qam.symbol_rate / 1000);
524 stv0297_set_sweeprate(state, sweeprate, p->u.qam.symbol_rate / 1000);
525 stv0297_set_carrieroffset(state, carrieroffset);
526 stv0297_set_inversion(state, inversion);
527
528 /* kick off lock */
529 /* Disable corner detection for higher QAMs */
530 if (p->u.qam.modulation == QAM_128 ||
531 p->u.qam.modulation == QAM_256)
532 stv0297_writereg_mask(state, 0x88, 0x08, 0x00);
533 else
534 stv0297_writereg_mask(state, 0x88, 0x08, 0x08);
535
536 stv0297_writereg_mask(state, 0x5a, 0x20, 0x00);
537 stv0297_writereg_mask(state, 0x6a, 0x01, 0x01);
538 stv0297_writereg_mask(state, 0x43, 0x40, 0x40);
539 stv0297_writereg_mask(state, 0x5b, 0x30, 0x00);
540 stv0297_writereg_mask(state, 0x03, 0x0c, 0x0c);
541 stv0297_writereg_mask(state, 0x03, 0x03, 0x03);
542 stv0297_writereg_mask(state, 0x43, 0x10, 0x10);
543
544 /* wait for WGAGC lock */
545 starttime = jiffies;
546 timeout = jiffies + msecs_to_jiffies(2000);
547 while (time_before(jiffies, timeout)) {
548 msleep(10);
549 if (stv0297_readreg(state, 0x43) & 0x08)
550 break;
551 }
552 if (time_after(jiffies, timeout)) {
553 goto timeout;
554 }
555 msleep(20);
556
557 /* wait for equaliser partial convergence */
558 timeout = jiffies + msecs_to_jiffies(500);
559 while (time_before(jiffies, timeout)) {
560 msleep(10);
561
562 if (stv0297_readreg(state, 0x82) & 0x04) {
563 break;
564 }
565 }
566 if (time_after(jiffies, timeout)) {
567 goto timeout;
568 }
569
570 /* wait for equaliser full convergence */
571 timeout = jiffies + msecs_to_jiffies(delay);
572 while (time_before(jiffies, timeout)) {
573 msleep(10);
574
575 if (stv0297_readreg(state, 0x82) & 0x08) {
576 break;
577 }
578 }
579 if (time_after(jiffies, timeout)) {
580 goto timeout;
581 }
582
583 /* disable sweep */
584 stv0297_writereg_mask(state, 0x6a, 1, 0);
585 stv0297_writereg_mask(state, 0x88, 8, 0);
586
587 /* wait for main lock */
588 timeout = jiffies + msecs_to_jiffies(20);
589 while (time_before(jiffies, timeout)) {
590 msleep(10);
591
592 if (stv0297_readreg(state, 0xDF) & 0x80) {
593 break;
594 }
595 }
596 if (time_after(jiffies, timeout)) {
597 goto timeout;
598 }
599 msleep(100);
600
601 /* is it still locked after that delay? */
602 if (!(stv0297_readreg(state, 0xDF) & 0x80)) {
603 goto timeout;
604 }
605
606 /* success!! */
607 stv0297_writereg_mask(state, 0x5a, 0x40, 0x00);
608 state->base_freq = p->frequency;
609 return 0;
610
611timeout:
612 stv0297_writereg_mask(state, 0x6a, 0x01, 0x00);
613 return 0;
614}
615
616static int stv0297_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
617{
618 struct stv0297_state *state = fe->demodulator_priv;
619 int reg_00, reg_83;
620
621 reg_00 = stv0297_readreg(state, 0x00);
622 reg_83 = stv0297_readreg(state, 0x83);
623
624 p->frequency = state->base_freq;
625 p->inversion = (reg_83 & 0x08) ? INVERSION_ON : INVERSION_OFF;
626 if (state->config->invert)
627 p->inversion = (p->inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON;
628 p->u.qam.symbol_rate = stv0297_get_symbolrate(state) * 1000;
629 p->u.qam.fec_inner = FEC_NONE;
630
631 switch ((reg_00 >> 4) & 0x7) {
632 case 0:
633 p->u.qam.modulation = QAM_16;
634 break;
635 case 1:
636 p->u.qam.modulation = QAM_32;
637 break;
638 case 2:
639 p->u.qam.modulation = QAM_128;
640 break;
641 case 3:
642 p->u.qam.modulation = QAM_256;
643 break;
644 case 4:
645 p->u.qam.modulation = QAM_64;
646 break;
647 }
648
649 return 0;
650}
651
652static void stv0297_release(struct dvb_frontend *fe)
653{
654 struct stv0297_state *state = fe->demodulator_priv;
655 kfree(state);
656}
657
658static struct dvb_frontend_ops stv0297_ops;
659
660struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
661 struct i2c_adapter *i2c)
662{
663 struct stv0297_state *state = NULL;
664
665 /* allocate memory for the internal state */
666 state = kzalloc(sizeof(struct stv0297_state), GFP_KERNEL);
667 if (state == NULL)
668 goto error;
669
670 /* setup the state */
671 state->config = config;
672 state->i2c = i2c;
673 state->last_ber = 0;
674 state->base_freq = 0;
675
676 /* check if the demod is there */
677 if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20)
678 goto error;
679
680 /* create dvb_frontend */
681 memcpy(&state->frontend.ops, &stv0297_ops, sizeof(struct dvb_frontend_ops));
682 state->frontend.demodulator_priv = state;
683 return &state->frontend;
684
685error:
686 kfree(state);
687 return NULL;
688}
689
690static struct dvb_frontend_ops stv0297_ops = {
691
692 .info = {
693 .name = "ST STV0297 DVB-C",
694 .type = FE_QAM,
695 .frequency_min = 47000000,
696 .frequency_max = 862000000,
697 .frequency_stepsize = 62500,
698 .symbol_rate_min = 870000,
699 .symbol_rate_max = 11700000,
700 .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
701 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO},
702
703 .release = stv0297_release,
704
705 .init = stv0297_init,
706 .sleep = stv0297_sleep,
707 .i2c_gate_ctrl = stv0297_i2c_gate_ctrl,
708
709 .set_frontend = stv0297_set_frontend,
710 .get_frontend = stv0297_get_frontend,
711
712 .read_status = stv0297_read_status,
713 .read_ber = stv0297_read_ber,
714 .read_signal_strength = stv0297_read_signal_strength,
715 .read_snr = stv0297_read_snr,
716 .read_ucblocks = stv0297_read_ucblocks,
717};
718
719MODULE_DESCRIPTION("ST STV0297 DVB-C Demodulator driver");
720MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey");
721MODULE_LICENSE("GPL");
722
723EXPORT_SYMBOL(stv0297_attach);
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h
new file mode 100644
index 00000000000..3f8f9468f38
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0297.h
@@ -0,0 +1,57 @@
1/*
2 Driver for STV0297 demodulator
3
4 Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de>
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 STV0297_H
22#define STV0297_H
23
24#include <linux/dvb/frontend.h>
25#include "dvb_frontend.h"
26
27struct stv0297_config
28{
29 /* the demodulator's i2c address */
30 u8 demod_address;
31
32 /* inittab - array of pairs of values.
33 * First of each pair is the register, second is the value.
34 * List should be terminated with an 0xff, 0xff pair.
35 */
36 u8* inittab;
37
38 /* does the "inversion" need inverted? */
39 u8 invert:1;
40
41 /* set to 1 if the device requires an i2c STOP during reading */
42 u8 stop_during_read:1;
43};
44
45#if defined(CONFIG_DVB_STV0297) || (defined(CONFIG_DVB_STV0297_MODULE) && defined(MODULE))
46extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
47 struct i2c_adapter* i2c);
48#else
49static inline struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
50 struct i2c_adapter* i2c)
51{
52 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
53 return NULL;
54}
55#endif // CONFIG_DVB_STV0297
56
57#endif // STV0297_H
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
new file mode 100644
index 00000000000..42684bec888
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -0,0 +1,760 @@
1/*
2 Driver for ST STV0299 demodulator
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 <ralph@convergence.de>,
6 <holger@convergence.de>,
7 <js@convergence.de>
8
9
10 Philips SU1278/SH
11
12 Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
13
14
15 LG TDQF-S001F
16
17 Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
18 & Andreas Oberritter <obi@linuxtv.org>
19
20
21 Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
22
23 Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
24
25 Support for Philips SU1278 on Technotrend hardware
26
27 Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
28
29 This program is free software; you can redistribute it and/or modify
30 it under the terms of the GNU General Public License as published by
31 the Free Software Foundation; either version 2 of the License, or
32 (at your option) any later version.
33
34 This program is distributed in the hope that it will be useful,
35 but WITHOUT ANY WARRANTY; without even the implied warranty of
36 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 GNU General Public License for more details.
38
39 You should have received a copy of the GNU General Public License
40 along with this program; if not, write to the Free Software
41 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42
43*/
44
45#include <linux/init.h>
46#include <linux/kernel.h>
47#include <linux/module.h>
48#include <linux/string.h>
49#include <linux/slab.h>
50#include <linux/jiffies.h>
51#include <asm/div64.h>
52
53#include "dvb_frontend.h"
54#include "stv0299.h"
55
56struct stv0299_state {
57 struct i2c_adapter* i2c;
58 const struct stv0299_config* config;
59 struct dvb_frontend frontend;
60
61 u8 initialised:1;
62 u32 tuner_frequency;
63 u32 symbol_rate;
64 fe_code_rate_t fec_inner;
65 int errmode;
66 u32 ucblocks;
67 u8 mcr_reg;
68};
69
70#define STATUS_BER 0
71#define STATUS_UCBLOCKS 1
72
73static int debug;
74static int debug_legacy_dish_switch;
75#define dprintk(args...) \
76 do { \
77 if (debug) printk(KERN_DEBUG "stv0299: " args); \
78 } while (0)
79
80
81static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data)
82{
83 int ret;
84 u8 buf [] = { reg, data };
85 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
86
87 ret = i2c_transfer (state->i2c, &msg, 1);
88
89 if (ret != 1)
90 dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
91 "ret == %i)\n", __func__, reg, data, ret);
92
93 return (ret != 1) ? -EREMOTEIO : 0;
94}
95
96static int stv0299_write(struct dvb_frontend* fe, const u8 buf[], int len)
97{
98 struct stv0299_state* state = fe->demodulator_priv;
99
100 if (len != 2)
101 return -EINVAL;
102
103 return stv0299_writeregI(state, buf[0], buf[1]);
104}
105
106static u8 stv0299_readreg (struct stv0299_state* state, u8 reg)
107{
108 int ret;
109 u8 b0 [] = { reg };
110 u8 b1 [] = { 0 };
111 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
112 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
113
114 ret = i2c_transfer (state->i2c, msg, 2);
115
116 if (ret != 2)
117 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
118 __func__, reg, ret);
119
120 return b1[0];
121}
122
123static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len)
124{
125 int ret;
126 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg1, .len = 1 },
127 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
128
129 ret = i2c_transfer (state->i2c, msg, 2);
130
131 if (ret != 2)
132 dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
133
134 return ret == 2 ? 0 : ret;
135}
136
137static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec)
138{
139 dprintk ("%s\n", __func__);
140
141 switch (fec) {
142 case FEC_AUTO:
143 {
144 return stv0299_writeregI (state, 0x31, 0x1f);
145 }
146 case FEC_1_2:
147 {
148 return stv0299_writeregI (state, 0x31, 0x01);
149 }
150 case FEC_2_3:
151 {
152 return stv0299_writeregI (state, 0x31, 0x02);
153 }
154 case FEC_3_4:
155 {
156 return stv0299_writeregI (state, 0x31, 0x04);
157 }
158 case FEC_5_6:
159 {
160 return stv0299_writeregI (state, 0x31, 0x08);
161 }
162 case FEC_7_8:
163 {
164 return stv0299_writeregI (state, 0x31, 0x10);
165 }
166 default:
167 {
168 return -EINVAL;
169 }
170 }
171}
172
173static fe_code_rate_t stv0299_get_fec (struct stv0299_state* state)
174{
175 static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6,
176 FEC_7_8, FEC_1_2 };
177 u8 index;
178
179 dprintk ("%s\n", __func__);
180
181 index = stv0299_readreg (state, 0x1b);
182 index &= 0x7;
183
184 if (index > 4)
185 return FEC_AUTO;
186
187 return fec_tab [index];
188}
189
190static int stv0299_wait_diseqc_fifo (struct stv0299_state* state, int timeout)
191{
192 unsigned long start = jiffies;
193
194 dprintk ("%s\n", __func__);
195
196 while (stv0299_readreg(state, 0x0a) & 1) {
197 if (jiffies - start > timeout) {
198 dprintk ("%s: timeout!!\n", __func__);
199 return -ETIMEDOUT;
200 }
201 msleep(10);
202 };
203
204 return 0;
205}
206
207static int stv0299_wait_diseqc_idle (struct stv0299_state* state, int timeout)
208{
209 unsigned long start = jiffies;
210
211 dprintk ("%s\n", __func__);
212
213 while ((stv0299_readreg(state, 0x0a) & 3) != 2 ) {
214 if (jiffies - start > timeout) {
215 dprintk ("%s: timeout!!\n", __func__);
216 return -ETIMEDOUT;
217 }
218 msleep(10);
219 };
220
221 return 0;
222}
223
224static int stv0299_set_symbolrate (struct dvb_frontend* fe, u32 srate)
225{
226 struct stv0299_state* state = fe->demodulator_priv;
227 u64 big = srate;
228 u32 ratio;
229
230 // check rate is within limits
231 if ((srate < 1000000) || (srate > 45000000)) return -EINVAL;
232
233 // calculate value to program
234 big = big << 20;
235 big += (state->config->mclk-1); // round correctly
236 do_div(big, state->config->mclk);
237 ratio = big << 4;
238
239 return state->config->set_symbol_rate(fe, srate, ratio);
240}
241
242static int stv0299_get_symbolrate (struct stv0299_state* state)
243{
244 u32 Mclk = state->config->mclk / 4096L;
245 u32 srate;
246 s32 offset;
247 u8 sfr[3];
248 s8 rtf;
249
250 dprintk ("%s\n", __func__);
251
252 stv0299_readregs (state, 0x1f, sfr, 3);
253 stv0299_readregs (state, 0x1a, (u8 *)&rtf, 1);
254
255 srate = (sfr[0] << 8) | sfr[1];
256 srate *= Mclk;
257 srate /= 16;
258 srate += (sfr[2] >> 4) * Mclk / 256;
259 offset = (s32) rtf * (srate / 4096L);
260 offset /= 128;
261
262 dprintk ("%s : srate = %i\n", __func__, srate);
263 dprintk ("%s : ofset = %i\n", __func__, offset);
264
265 srate += offset;
266
267 srate += 1000;
268 srate /= 2000;
269 srate *= 2000;
270
271 return srate;
272}
273
274static int stv0299_send_diseqc_msg (struct dvb_frontend* fe,
275 struct dvb_diseqc_master_cmd *m)
276{
277 struct stv0299_state* state = fe->demodulator_priv;
278 u8 val;
279 int i;
280
281 dprintk ("%s\n", __func__);
282
283 if (stv0299_wait_diseqc_idle (state, 100) < 0)
284 return -ETIMEDOUT;
285
286 val = stv0299_readreg (state, 0x08);
287
288 if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x6)) /* DiSEqC mode */
289 return -EREMOTEIO;
290
291 for (i=0; i<m->msg_len; i++) {
292 if (stv0299_wait_diseqc_fifo (state, 100) < 0)
293 return -ETIMEDOUT;
294
295 if (stv0299_writeregI (state, 0x09, m->msg[i]))
296 return -EREMOTEIO;
297 }
298
299 if (stv0299_wait_diseqc_idle (state, 100) < 0)
300 return -ETIMEDOUT;
301
302 return 0;
303}
304
305static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
306{
307 struct stv0299_state* state = fe->demodulator_priv;
308 u8 val;
309
310 dprintk ("%s\n", __func__);
311
312 if (stv0299_wait_diseqc_idle (state, 100) < 0)
313 return -ETIMEDOUT;
314
315 val = stv0299_readreg (state, 0x08);
316
317 if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x2)) /* burst mode */
318 return -EREMOTEIO;
319
320 if (stv0299_writeregI (state, 0x09, burst == SEC_MINI_A ? 0x00 : 0xff))
321 return -EREMOTEIO;
322
323 if (stv0299_wait_diseqc_idle (state, 100) < 0)
324 return -ETIMEDOUT;
325
326 if (stv0299_writeregI (state, 0x08, val))
327 return -EREMOTEIO;
328
329 return 0;
330}
331
332static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
333{
334 struct stv0299_state* state = fe->demodulator_priv;
335 u8 val;
336
337 if (stv0299_wait_diseqc_idle (state, 100) < 0)
338 return -ETIMEDOUT;
339
340 val = stv0299_readreg (state, 0x08);
341
342 switch (tone) {
343 case SEC_TONE_ON:
344 return stv0299_writeregI (state, 0x08, val | 0x3);
345
346 case SEC_TONE_OFF:
347 return stv0299_writeregI (state, 0x08, (val & ~0x3) | 0x02);
348
349 default:
350 return -EINVAL;
351 }
352}
353
354static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
355{
356 struct stv0299_state* state = fe->demodulator_priv;
357 u8 reg0x08;
358 u8 reg0x0c;
359
360 dprintk("%s: %s\n", __func__,
361 voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
362 voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
363
364 reg0x08 = stv0299_readreg (state, 0x08);
365 reg0x0c = stv0299_readreg (state, 0x0c);
366
367 /**
368 * H/V switching over OP0, OP1 and OP2 are LNB power enable bits
369 */
370 reg0x0c &= 0x0f;
371 reg0x08 = (reg0x08 & 0x3f) | (state->config->lock_output << 6);
372
373 switch (voltage) {
374 case SEC_VOLTAGE_13:
375 if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0)
376 reg0x0c |= 0x10; /* OP1 off, OP0 on */
377 else
378 reg0x0c |= 0x40; /* OP1 on, OP0 off */
379 break;
380 case SEC_VOLTAGE_18:
381 reg0x0c |= 0x50; /* OP1 on, OP0 on */
382 break;
383 case SEC_VOLTAGE_OFF:
384 /* LNB power off! */
385 reg0x08 = 0x00;
386 reg0x0c = 0x00;
387 break;
388 default:
389 return -EINVAL;
390 };
391
392 if (state->config->op0_off)
393 reg0x0c &= ~0x10;
394
395 stv0299_writeregI(state, 0x08, reg0x08);
396 return stv0299_writeregI(state, 0x0c, reg0x0c);
397}
398
399static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd)
400{
401 struct stv0299_state* state = fe->demodulator_priv;
402 u8 reg0x08;
403 u8 reg0x0c;
404 u8 lv_mask = 0x40;
405 u8 last = 1;
406 int i;
407 struct timeval nexttime;
408 struct timeval tv[10];
409
410 reg0x08 = stv0299_readreg (state, 0x08);
411 reg0x0c = stv0299_readreg (state, 0x0c);
412 reg0x0c &= 0x0f;
413 stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6));
414 if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0)
415 lv_mask = 0x10;
416
417 cmd = cmd << 1;
418 if (debug_legacy_dish_switch)
419 printk ("%s switch command: 0x%04lx\n",__func__, cmd);
420
421 do_gettimeofday (&nexttime);
422 if (debug_legacy_dish_switch)
423 memcpy (&tv[0], &nexttime, sizeof (struct timeval));
424 stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */
425
426 dvb_frontend_sleep_until(&nexttime, 32000);
427
428 for (i=0; i<9; i++) {
429 if (debug_legacy_dish_switch)
430 do_gettimeofday (&tv[i+1]);
431 if((cmd & 0x01) != last) {
432 /* set voltage to (last ? 13V : 18V) */
433 stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50));
434 last = (last) ? 0 : 1;
435 }
436
437 cmd = cmd >> 1;
438
439 if (i != 8)
440 dvb_frontend_sleep_until(&nexttime, 8000);
441 }
442 if (debug_legacy_dish_switch) {
443 printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
444 __func__, fe->dvb->num);
445 for (i = 1; i < 10; i++)
446 printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
447 }
448
449 return 0;
450}
451
452static int stv0299_init (struct dvb_frontend* fe)
453{
454 struct stv0299_state* state = fe->demodulator_priv;
455 int i;
456 u8 reg;
457 u8 val;
458
459 dprintk("stv0299: init chip\n");
460
461 stv0299_writeregI(state, 0x02, 0x30 | state->mcr_reg);
462 msleep(50);
463
464 for (i = 0; ; i += 2) {
465 reg = state->config->inittab[i];
466 val = state->config->inittab[i+1];
467 if (reg == 0xff && val == 0xff)
468 break;
469 if (reg == 0x0c && state->config->op0_off)
470 val &= ~0x10;
471 if (reg == 0x2)
472 state->mcr_reg = val & 0xf;
473 stv0299_writeregI(state, reg, val);
474 }
475
476 return 0;
477}
478
479static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status)
480{
481 struct stv0299_state* state = fe->demodulator_priv;
482
483 u8 signal = 0xff - stv0299_readreg (state, 0x18);
484 u8 sync = stv0299_readreg (state, 0x1b);
485
486 dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
487 *status = 0;
488
489 if (signal > 10)
490 *status |= FE_HAS_SIGNAL;
491
492 if (sync & 0x80)
493 *status |= FE_HAS_CARRIER;
494
495 if (sync & 0x10)
496 *status |= FE_HAS_VITERBI;
497
498 if (sync & 0x08)
499 *status |= FE_HAS_SYNC;
500
501 if ((sync & 0x98) == 0x98)
502 *status |= FE_HAS_LOCK;
503
504 return 0;
505}
506
507static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber)
508{
509 struct stv0299_state* state = fe->demodulator_priv;
510
511 if (state->errmode != STATUS_BER)
512 return -ENOSYS;
513
514 *ber = stv0299_readreg(state, 0x1e) | (stv0299_readreg(state, 0x1d) << 8);
515
516 return 0;
517}
518
519static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength)
520{
521 struct stv0299_state* state = fe->demodulator_priv;
522
523 s32 signal = 0xffff - ((stv0299_readreg (state, 0x18) << 8)
524 | stv0299_readreg (state, 0x19));
525
526 dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __func__,
527 stv0299_readreg (state, 0x18),
528 stv0299_readreg (state, 0x19), (int) signal);
529
530 signal = signal * 5 / 4;
531 *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
532
533 return 0;
534}
535
536static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr)
537{
538 struct stv0299_state* state = fe->demodulator_priv;
539
540 s32 xsnr = 0xffff - ((stv0299_readreg (state, 0x24) << 8)
541 | stv0299_readreg (state, 0x25));
542 xsnr = 3 * (xsnr - 0xa100);
543 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
544
545 return 0;
546}
547
548static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
549{
550 struct stv0299_state* state = fe->demodulator_priv;
551
552 if (state->errmode != STATUS_UCBLOCKS)
553 return -ENOSYS;
554
555 state->ucblocks += stv0299_readreg(state, 0x1e);
556 state->ucblocks += (stv0299_readreg(state, 0x1d) << 8);
557 *ucblocks = state->ucblocks;
558
559 return 0;
560}
561
562static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p)
563{
564 struct stv0299_state* state = fe->demodulator_priv;
565 int invval = 0;
566
567 dprintk ("%s : FE_SET_FRONTEND\n", __func__);
568 if (state->config->set_ts_params)
569 state->config->set_ts_params(fe, 0);
570
571 // set the inversion
572 if (p->inversion == INVERSION_OFF) invval = 0;
573 else if (p->inversion == INVERSION_ON) invval = 1;
574 else {
575 printk("stv0299 does not support auto-inversion\n");
576 return -EINVAL;
577 }
578 if (state->config->invert) invval = (~invval) & 1;
579 stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval);
580
581 if (fe->ops.tuner_ops.set_params) {
582 fe->ops.tuner_ops.set_params(fe, p);
583 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
584 }
585
586 stv0299_set_FEC (state, p->u.qpsk.fec_inner);
587 stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate);
588 stv0299_writeregI(state, 0x22, 0x00);
589 stv0299_writeregI(state, 0x23, 0x00);
590
591 state->tuner_frequency = p->frequency;
592 state->fec_inner = p->u.qpsk.fec_inner;
593 state->symbol_rate = p->u.qpsk.symbol_rate;
594
595 return 0;
596}
597
598static int stv0299_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p)
599{
600 struct stv0299_state* state = fe->demodulator_priv;
601 s32 derot_freq;
602 int invval;
603
604 derot_freq = (s32)(s16) ((stv0299_readreg (state, 0x22) << 8)
605 | stv0299_readreg (state, 0x23));
606
607 derot_freq *= (state->config->mclk >> 16);
608 derot_freq += 500;
609 derot_freq /= 1000;
610
611 p->frequency += derot_freq;
612
613 invval = stv0299_readreg (state, 0x0c) & 1;
614 if (state->config->invert) invval = (~invval) & 1;
615 p->inversion = invval ? INVERSION_ON : INVERSION_OFF;
616
617 p->u.qpsk.fec_inner = stv0299_get_fec (state);
618 p->u.qpsk.symbol_rate = stv0299_get_symbolrate (state);
619
620 return 0;
621}
622
623static int stv0299_sleep(struct dvb_frontend* fe)
624{
625 struct stv0299_state* state = fe->demodulator_priv;
626
627 stv0299_writeregI(state, 0x02, 0xb0 | state->mcr_reg);
628 state->initialised = 0;
629
630 return 0;
631}
632
633static int stv0299_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
634{
635 struct stv0299_state* state = fe->demodulator_priv;
636
637 if (enable) {
638 stv0299_writeregI(state, 0x05, 0xb5);
639 } else {
640 stv0299_writeregI(state, 0x05, 0x35);
641 }
642 udelay(1);
643 return 0;
644}
645
646static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
647{
648 struct stv0299_state* state = fe->demodulator_priv;
649
650 fesettings->min_delay_ms = state->config->min_delay_ms;
651 if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) {
652 fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000;
653 fesettings->max_drift = 5000;
654 } else {
655 fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000;
656 fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000;
657 }
658 return 0;
659}
660
661static void stv0299_release(struct dvb_frontend* fe)
662{
663 struct stv0299_state* state = fe->demodulator_priv;
664 kfree(state);
665}
666
667static struct dvb_frontend_ops stv0299_ops;
668
669struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
670 struct i2c_adapter* i2c)
671{
672 struct stv0299_state* state = NULL;
673 int id;
674
675 /* allocate memory for the internal state */
676 state = kzalloc(sizeof(struct stv0299_state), GFP_KERNEL);
677 if (state == NULL) goto error;
678
679 /* setup the state */
680 state->config = config;
681 state->i2c = i2c;
682 state->initialised = 0;
683 state->tuner_frequency = 0;
684 state->symbol_rate = 0;
685 state->fec_inner = 0;
686 state->errmode = STATUS_BER;
687
688 /* check if the demod is there */
689 stv0299_writeregI(state, 0x02, 0x30); /* standby off */
690 msleep(200);
691 id = stv0299_readreg(state, 0x00);
692
693 /* register 0x00 contains 0xa1 for STV0299 and STV0299B */
694 /* register 0x00 might contain 0x80 when returning from standby */
695 if (id != 0xa1 && id != 0x80) goto error;
696
697 /* create dvb_frontend */
698 memcpy(&state->frontend.ops, &stv0299_ops, sizeof(struct dvb_frontend_ops));
699 state->frontend.demodulator_priv = state;
700 return &state->frontend;
701
702error:
703 kfree(state);
704 return NULL;
705}
706
707static struct dvb_frontend_ops stv0299_ops = {
708
709 .info = {
710 .name = "ST STV0299 DVB-S",
711 .type = FE_QPSK,
712 .frequency_min = 950000,
713 .frequency_max = 2150000,
714 .frequency_stepsize = 125, /* kHz for QPSK frontends */
715 .frequency_tolerance = 0,
716 .symbol_rate_min = 1000000,
717 .symbol_rate_max = 45000000,
718 .symbol_rate_tolerance = 500, /* ppm */
719 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
720 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
721 FE_CAN_QPSK |
722 FE_CAN_FEC_AUTO
723 },
724
725 .release = stv0299_release,
726
727 .init = stv0299_init,
728 .sleep = stv0299_sleep,
729 .write = stv0299_write,
730 .i2c_gate_ctrl = stv0299_i2c_gate_ctrl,
731
732 .set_frontend = stv0299_set_frontend,
733 .get_frontend = stv0299_get_frontend,
734 .get_tune_settings = stv0299_get_tune_settings,
735
736 .read_status = stv0299_read_status,
737 .read_ber = stv0299_read_ber,
738 .read_signal_strength = stv0299_read_signal_strength,
739 .read_snr = stv0299_read_snr,
740 .read_ucblocks = stv0299_read_ucblocks,
741
742 .diseqc_send_master_cmd = stv0299_send_diseqc_msg,
743 .diseqc_send_burst = stv0299_send_diseqc_burst,
744 .set_tone = stv0299_set_tone,
745 .set_voltage = stv0299_set_voltage,
746 .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd,
747};
748
749module_param(debug_legacy_dish_switch, int, 0444);
750MODULE_PARM_DESC(debug_legacy_dish_switch, "Enable timing analysis for Dish Network legacy switches");
751
752module_param(debug, int, 0644);
753MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
754
755MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver");
756MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, "
757 "Andreas Oberritter, Andrew de Quincey, Kenneth Aafly");
758MODULE_LICENSE("GPL");
759
760EXPORT_SYMBOL(stv0299_attach);
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
new file mode 100644
index 00000000000..ba219b767a6
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -0,0 +1,118 @@
1/*
2 Driver for ST STV0299 demodulator
3
4 Copyright (C) 2001-2002 Convergence Integrated Media GmbH
5 <ralph@convergence.de>,
6 <holger@convergence.de>,
7 <js@convergence.de>
8
9
10 Philips SU1278/SH
11
12 Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de>
13
14
15 LG TDQF-S001F
16
17 Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net>
18 & Andreas Oberritter <obi@linuxtv.org>
19
20
21 Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B
22
23 Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>:
24
25 Support for Philips SU1278 on Technotrend hardware
26
27 Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
28
29 This program is free software; you can redistribute it and/or modify
30 it under the terms of the GNU General Public License as published by
31 the Free Software Foundation; either version 2 of the License, or
32 (at your option) any later version.
33
34 This program is distributed in the hope that it will be useful,
35 but WITHOUT ANY WARRANTY; without even the implied warranty of
36 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 GNU General Public License for more details.
38
39 You should have received a copy of the GNU General Public License
40 along with this program; if not, write to the Free Software
41 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42
43*/
44
45#ifndef STV0299_H
46#define STV0299_H
47
48#include <linux/dvb/frontend.h>
49#include "dvb_frontend.h"
50
51#define STV0299_LOCKOUTPUT_0 0
52#define STV0299_LOCKOUTPUT_1 1
53#define STV0299_LOCKOUTPUT_CF 2
54#define STV0299_LOCKOUTPUT_LK 3
55
56#define STV0299_VOLT13_OP0 0
57#define STV0299_VOLT13_OP1 1
58
59struct stv0299_config
60{
61 /* the demodulator's i2c address */
62 u8 demod_address;
63
64 /* inittab - array of pairs of values.
65 * First of each pair is the register, second is the value.
66 * List should be terminated with an 0xff, 0xff pair.
67 */
68 const u8* inittab;
69
70 /* master clock to use */
71 u32 mclk;
72
73 /* does the inversion require inversion? */
74 u8 invert:1;
75
76 /* Skip reinitialisation? */
77 u8 skip_reinit:1;
78
79 /* LOCK OUTPUT setting */
80 u8 lock_output:2;
81
82 /* Is 13v controlled by OP0 or OP1? */
83 u8 volt13_op0_op1:1;
84
85 /* Turn-off OP0? */
86 u8 op0_off:1;
87
88 /* minimum delay before retuning */
89 int min_delay_ms;
90
91 /* Set the symbol rate */
92 int (*set_symbol_rate)(struct dvb_frontend *fe, u32 srate, u32 ratio);
93
94 /* Set device param to start dma */
95 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
96};
97
98#if defined(CONFIG_DVB_STV0299) || (defined(CONFIG_DVB_STV0299_MODULE) && defined(MODULE))
99extern struct dvb_frontend *stv0299_attach(const struct stv0299_config *config,
100 struct i2c_adapter *i2c);
101#else
102static inline struct dvb_frontend *stv0299_attach(const struct stv0299_config *config,
103 struct i2c_adapter *i2c)
104{
105 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
106 return NULL;
107}
108#endif // CONFIG_DVB_STV0299
109
110static inline int stv0299_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
111 int r = 0;
112 u8 buf[] = {reg, val};
113 if (fe->ops.write)
114 r = fe->ops.write(fe, buf, 2);
115 return r;
116}
117
118#endif // STV0299_H
diff --git a/drivers/media/dvb/frontends/stv0367.c b/drivers/media/dvb/frontends/stv0367.c
new file mode 100644
index 00000000000..e57ab53e2e2
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0367.c
@@ -0,0 +1,3459 @@
1/*
2 * stv0367.c
3 *
4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/string.h>
29#include <linux/slab.h>
30#include <linux/i2c.h>
31
32#include "stv0367.h"
33#include "stv0367_regs.h"
34#include "stv0367_priv.h"
35
36static int stvdebug;
37module_param_named(debug, stvdebug, int, 0644);
38
39static int i2cdebug;
40module_param_named(i2c_debug, i2cdebug, int, 0644);
41
42#define dprintk(args...) \
43 do { \
44 if (stvdebug) \
45 printk(KERN_DEBUG args); \
46 } while (0)
47 /* DVB-C */
48
49struct stv0367cab_state {
50 enum stv0367_cab_signal_type state;
51 u32 mclk;
52 u32 adc_clk;
53 s32 search_range;
54 s32 derot_offset;
55 /* results */
56 int locked; /* channel found */
57 u32 freq_khz; /* found frequency (in kHz) */
58 u32 symbol_rate; /* found symbol rate (in Bds) */
59 enum stv0367cab_mod modulation; /* modulation */
60 fe_spectral_inversion_t spect_inv; /* Spectrum Inversion */
61};
62
63struct stv0367ter_state {
64 /* DVB-T */
65 enum stv0367_ter_signal_type state;
66 enum stv0367_ter_if_iq_mode if_iq_mode;
67 enum stv0367_ter_mode mode;/* mode 2K or 8K */
68 fe_guard_interval_t guard;
69 enum stv0367_ter_hierarchy hierarchy;
70 u32 frequency;
71 fe_spectral_inversion_t sense; /* current search spectrum */
72 u8 force; /* force mode/guard */
73 u8 bw; /* channel width 6, 7 or 8 in MHz */
74 u8 pBW; /* channel width used during previous lock */
75 u32 pBER;
76 u32 pPER;
77 u32 ucblocks;
78 s8 echo_pos; /* echo position */
79 u8 first_lock;
80 u8 unlock_counter;
81 u32 agc_val;
82};
83
84struct stv0367_state {
85 struct dvb_frontend fe;
86 struct i2c_adapter *i2c;
87 /* config settings */
88 const struct stv0367_config *config;
89 u8 chip_id;
90 /* DVB-C */
91 struct stv0367cab_state *cab_state;
92 /* DVB-T */
93 struct stv0367ter_state *ter_state;
94};
95
96struct st_register {
97 u16 addr;
98 u8 value;
99};
100
101/* values for STV4100 XTAL=30M int clk=53.125M*/
102static struct st_register def0367ter[STV0367TER_NBREGS] = {
103 {R367TER_ID, 0x60},
104 {R367TER_I2CRPT, 0xa0},
105 /* {R367TER_I2CRPT, 0x22},*/
106 {R367TER_TOPCTRL, 0x00},/* for xc5000; was 0x02 */
107 {R367TER_IOCFG0, 0x40},
108 {R367TER_DAC0R, 0x00},
109 {R367TER_IOCFG1, 0x00},
110 {R367TER_DAC1R, 0x00},
111 {R367TER_IOCFG2, 0x62},
112 {R367TER_SDFR, 0x00},
113 {R367TER_STATUS, 0xf8},
114 {R367TER_AUX_CLK, 0x0a},
115 {R367TER_FREESYS1, 0x00},
116 {R367TER_FREESYS2, 0x00},
117 {R367TER_FREESYS3, 0x00},
118 {R367TER_GPIO_CFG, 0x55},
119 {R367TER_GPIO_CMD, 0x00},
120 {R367TER_AGC2MAX, 0xff},
121 {R367TER_AGC2MIN, 0x00},
122 {R367TER_AGC1MAX, 0xff},
123 {R367TER_AGC1MIN, 0x00},
124 {R367TER_AGCR, 0xbc},
125 {R367TER_AGC2TH, 0x00},
126 {R367TER_AGC12C, 0x00},
127 {R367TER_AGCCTRL1, 0x85},
128 {R367TER_AGCCTRL2, 0x1f},
129 {R367TER_AGC1VAL1, 0x00},
130 {R367TER_AGC1VAL2, 0x00},
131 {R367TER_AGC2VAL1, 0x6f},
132 {R367TER_AGC2VAL2, 0x05},
133 {R367TER_AGC2PGA, 0x00},
134 {R367TER_OVF_RATE1, 0x00},
135 {R367TER_OVF_RATE2, 0x00},
136 {R367TER_GAIN_SRC1, 0xaa},/* for xc5000; was 0x2b */
137 {R367TER_GAIN_SRC2, 0xd6},/* for xc5000; was 0x04 */
138 {R367TER_INC_DEROT1, 0x55},
139 {R367TER_INC_DEROT2, 0x55},
140 {R367TER_PPM_CPAMP_DIR, 0x2c},
141 {R367TER_PPM_CPAMP_INV, 0x00},
142 {R367TER_FREESTFE_1, 0x00},
143 {R367TER_FREESTFE_2, 0x1c},
144 {R367TER_DCOFFSET, 0x00},
145 {R367TER_EN_PROCESS, 0x05},
146 {R367TER_SDI_SMOOTHER, 0x80},
147 {R367TER_FE_LOOP_OPEN, 0x1c},
148 {R367TER_FREQOFF1, 0x00},
149 {R367TER_FREQOFF2, 0x00},
150 {R367TER_FREQOFF3, 0x00},
151 {R367TER_TIMOFF1, 0x00},
152 {R367TER_TIMOFF2, 0x00},
153 {R367TER_EPQ, 0x02},
154 {R367TER_EPQAUTO, 0x01},
155 {R367TER_SYR_UPDATE, 0xf5},
156 {R367TER_CHPFREE, 0x00},
157 {R367TER_PPM_STATE_MAC, 0x23},
158 {R367TER_INR_THRESHOLD, 0xff},
159 {R367TER_EPQ_TPS_ID_CELL, 0xf9},
160 {R367TER_EPQ_CFG, 0x00},
161 {R367TER_EPQ_STATUS, 0x01},
162 {R367TER_AUTORELOCK, 0x81},
163 {R367TER_BER_THR_VMSB, 0x00},
164 {R367TER_BER_THR_MSB, 0x00},
165 {R367TER_BER_THR_LSB, 0x00},
166 {R367TER_CCD, 0x83},
167 {R367TER_SPECTR_CFG, 0x00},
168 {R367TER_CHC_DUMMY, 0x18},
169 {R367TER_INC_CTL, 0x88},
170 {R367TER_INCTHRES_COR1, 0xb4},
171 {R367TER_INCTHRES_COR2, 0x96},
172 {R367TER_INCTHRES_DET1, 0x0e},
173 {R367TER_INCTHRES_DET2, 0x11},
174 {R367TER_IIR_CELLNB, 0x8d},
175 {R367TER_IIRCX_COEFF1_MSB, 0x00},
176 {R367TER_IIRCX_COEFF1_LSB, 0x00},
177 {R367TER_IIRCX_COEFF2_MSB, 0x09},
178 {R367TER_IIRCX_COEFF2_LSB, 0x18},
179 {R367TER_IIRCX_COEFF3_MSB, 0x14},
180 {R367TER_IIRCX_COEFF3_LSB, 0x9c},
181 {R367TER_IIRCX_COEFF4_MSB, 0x00},
182 {R367TER_IIRCX_COEFF4_LSB, 0x00},
183 {R367TER_IIRCX_COEFF5_MSB, 0x36},
184 {R367TER_IIRCX_COEFF5_LSB, 0x42},
185 {R367TER_FEPATH_CFG, 0x00},
186 {R367TER_PMC1_FUNC, 0x65},
187 {R367TER_PMC1_FOR, 0x00},
188 {R367TER_PMC2_FUNC, 0x00},
189 {R367TER_STATUS_ERR_DA, 0xe0},
190 {R367TER_DIG_AGC_R, 0xfe},
191 {R367TER_COMAGC_TARMSB, 0x0b},
192 {R367TER_COM_AGC_TAR_ENMODE, 0x41},
193 {R367TER_COM_AGC_CFG, 0x3e},
194 {R367TER_COM_AGC_GAIN1, 0x39},
195 {R367TER_AUT_AGC_TARGETMSB, 0x0b},
196 {R367TER_LOCK_DET_MSB, 0x01},
197 {R367TER_AGCTAR_LOCK_LSBS, 0x40},
198 {R367TER_AUT_GAIN_EN, 0xf4},
199 {R367TER_AUT_CFG, 0xf0},
200 {R367TER_LOCKN, 0x23},
201 {R367TER_INT_X_3, 0x00},
202 {R367TER_INT_X_2, 0x03},
203 {R367TER_INT_X_1, 0x8d},
204 {R367TER_INT_X_0, 0xa0},
205 {R367TER_MIN_ERRX_MSB, 0x00},
206 {R367TER_COR_CTL, 0x23},
207 {R367TER_COR_STAT, 0xf6},
208 {R367TER_COR_INTEN, 0x00},
209 {R367TER_COR_INTSTAT, 0x3f},
210 {R367TER_COR_MODEGUARD, 0x03},
211 {R367TER_AGC_CTL, 0x08},
212 {R367TER_AGC_MANUAL1, 0x00},
213 {R367TER_AGC_MANUAL2, 0x00},
214 {R367TER_AGC_TARG, 0x16},
215 {R367TER_AGC_GAIN1, 0x53},
216 {R367TER_AGC_GAIN2, 0x1d},
217 {R367TER_RESERVED_1, 0x00},
218 {R367TER_RESERVED_2, 0x00},
219 {R367TER_RESERVED_3, 0x00},
220 {R367TER_CAS_CTL, 0x44},
221 {R367TER_CAS_FREQ, 0xb3},
222 {R367TER_CAS_DAGCGAIN, 0x12},
223 {R367TER_SYR_CTL, 0x04},
224 {R367TER_SYR_STAT, 0x10},
225 {R367TER_SYR_NCO1, 0x00},
226 {R367TER_SYR_NCO2, 0x00},
227 {R367TER_SYR_OFFSET1, 0x00},
228 {R367TER_SYR_OFFSET2, 0x00},
229 {R367TER_FFT_CTL, 0x00},
230 {R367TER_SCR_CTL, 0x70},
231 {R367TER_PPM_CTL1, 0xf8},
232 {R367TER_TRL_CTL, 0x14},/* for xc5000; was 0xac */
233 {R367TER_TRL_NOMRATE1, 0xae},/* for xc5000; was 0x1e */
234 {R367TER_TRL_NOMRATE2, 0x56},/* for xc5000; was 0x58 */
235 {R367TER_TRL_TIME1, 0x1d},
236 {R367TER_TRL_TIME2, 0xfc},
237 {R367TER_CRL_CTL, 0x24},
238 {R367TER_CRL_FREQ1, 0xad},
239 {R367TER_CRL_FREQ2, 0x9d},
240 {R367TER_CRL_FREQ3, 0xff},
241 {R367TER_CHC_CTL, 0x01},
242 {R367TER_CHC_SNR, 0xf0},
243 {R367TER_BDI_CTL, 0x00},
244 {R367TER_DMP_CTL, 0x00},
245 {R367TER_TPS_RCVD1, 0x30},
246 {R367TER_TPS_RCVD2, 0x02},
247 {R367TER_TPS_RCVD3, 0x01},
248 {R367TER_TPS_RCVD4, 0x00},
249 {R367TER_TPS_ID_CELL1, 0x00},
250 {R367TER_TPS_ID_CELL2, 0x00},
251 {R367TER_TPS_RCVD5_SET1, 0x02},
252 {R367TER_TPS_SET2, 0x02},
253 {R367TER_TPS_SET3, 0x01},
254 {R367TER_TPS_CTL, 0x00},
255 {R367TER_CTL_FFTOSNUM, 0x34},
256 {R367TER_TESTSELECT, 0x09},
257 {R367TER_MSC_REV, 0x0a},
258 {R367TER_PIR_CTL, 0x00},
259 {R367TER_SNR_CARRIER1, 0xa1},
260 {R367TER_SNR_CARRIER2, 0x9a},
261 {R367TER_PPM_CPAMP, 0x2c},
262 {R367TER_TSM_AP0, 0x00},
263 {R367TER_TSM_AP1, 0x00},
264 {R367TER_TSM_AP2 , 0x00},
265 {R367TER_TSM_AP3, 0x00},
266 {R367TER_TSM_AP4, 0x00},
267 {R367TER_TSM_AP5, 0x00},
268 {R367TER_TSM_AP6, 0x00},
269 {R367TER_TSM_AP7, 0x00},
270 {R367TER_TSTRES, 0x00},
271 {R367TER_ANACTRL, 0x0D},/* PLL stoped, restart at init!!! */
272 {R367TER_TSTBUS, 0x00},
273 {R367TER_TSTRATE, 0x00},
274 {R367TER_CONSTMODE, 0x01},
275 {R367TER_CONSTCARR1, 0x00},
276 {R367TER_CONSTCARR2, 0x00},
277 {R367TER_ICONSTEL, 0x0a},
278 {R367TER_QCONSTEL, 0x15},
279 {R367TER_TSTBISTRES0, 0x00},
280 {R367TER_TSTBISTRES1, 0x00},
281 {R367TER_TSTBISTRES2, 0x28},
282 {R367TER_TSTBISTRES3, 0x00},
283 {R367TER_RF_AGC1, 0xff},
284 {R367TER_RF_AGC2, 0x83},
285 {R367TER_ANADIGCTRL, 0x19},
286 {R367TER_PLLMDIV, 0x01},/* for xc5000; was 0x0c */
287 {R367TER_PLLNDIV, 0x06},/* for xc5000; was 0x55 */
288 {R367TER_PLLSETUP, 0x18},
289 {R367TER_DUAL_AD12, 0x0C},/* for xc5000 AGC voltage 1.6V */
290 {R367TER_TSTBIST, 0x00},
291 {R367TER_PAD_COMP_CTRL, 0x00},
292 {R367TER_PAD_COMP_WR, 0x00},
293 {R367TER_PAD_COMP_RD, 0xe0},
294 {R367TER_SYR_TARGET_FFTADJT_MSB, 0x00},
295 {R367TER_SYR_TARGET_FFTADJT_LSB, 0x00},
296 {R367TER_SYR_TARGET_CHCADJT_MSB, 0x00},
297 {R367TER_SYR_TARGET_CHCADJT_LSB, 0x00},
298 {R367TER_SYR_FLAG, 0x00},
299 {R367TER_CRL_TARGET1, 0x00},
300 {R367TER_CRL_TARGET2, 0x00},
301 {R367TER_CRL_TARGET3, 0x00},
302 {R367TER_CRL_TARGET4, 0x00},
303 {R367TER_CRL_FLAG, 0x00},
304 {R367TER_TRL_TARGET1, 0x00},
305 {R367TER_TRL_TARGET2, 0x00},
306 {R367TER_TRL_CHC, 0x00},
307 {R367TER_CHC_SNR_TARG, 0x00},
308 {R367TER_TOP_TRACK, 0x00},
309 {R367TER_TRACKER_FREE1, 0x00},
310 {R367TER_ERROR_CRL1, 0x00},
311 {R367TER_ERROR_CRL2, 0x00},
312 {R367TER_ERROR_CRL3, 0x00},
313 {R367TER_ERROR_CRL4, 0x00},
314 {R367TER_DEC_NCO1, 0x2c},
315 {R367TER_DEC_NCO2, 0x0f},
316 {R367TER_DEC_NCO3, 0x20},
317 {R367TER_SNR, 0xf1},
318 {R367TER_SYR_FFTADJ1, 0x00},
319 {R367TER_SYR_FFTADJ2, 0x00},
320 {R367TER_SYR_CHCADJ1, 0x00},
321 {R367TER_SYR_CHCADJ2, 0x00},
322 {R367TER_SYR_OFF, 0x00},
323 {R367TER_PPM_OFFSET1, 0x00},
324 {R367TER_PPM_OFFSET2, 0x03},
325 {R367TER_TRACKER_FREE2, 0x00},
326 {R367TER_DEBG_LT10, 0x00},
327 {R367TER_DEBG_LT11, 0x00},
328 {R367TER_DEBG_LT12, 0x00},
329 {R367TER_DEBG_LT13, 0x00},
330 {R367TER_DEBG_LT14, 0x00},
331 {R367TER_DEBG_LT15, 0x00},
332 {R367TER_DEBG_LT16, 0x00},
333 {R367TER_DEBG_LT17, 0x00},
334 {R367TER_DEBG_LT18, 0x00},
335 {R367TER_DEBG_LT19, 0x00},
336 {R367TER_DEBG_LT1A, 0x00},
337 {R367TER_DEBG_LT1B, 0x00},
338 {R367TER_DEBG_LT1C, 0x00},
339 {R367TER_DEBG_LT1D, 0x00},
340 {R367TER_DEBG_LT1E, 0x00},
341 {R367TER_DEBG_LT1F, 0x00},
342 {R367TER_RCCFGH, 0x00},
343 {R367TER_RCCFGM, 0x00},
344 {R367TER_RCCFGL, 0x00},
345 {R367TER_RCINSDELH, 0x00},
346 {R367TER_RCINSDELM, 0x00},
347 {R367TER_RCINSDELL, 0x00},
348 {R367TER_RCSTATUS, 0x00},
349 {R367TER_RCSPEED, 0x6f},
350 {R367TER_RCDEBUGM, 0xe7},
351 {R367TER_RCDEBUGL, 0x9b},
352 {R367TER_RCOBSCFG, 0x00},
353 {R367TER_RCOBSM, 0x00},
354 {R367TER_RCOBSL, 0x00},
355 {R367TER_RCFECSPY, 0x00},
356 {R367TER_RCFSPYCFG, 0x00},
357 {R367TER_RCFSPYDATA, 0x00},
358 {R367TER_RCFSPYOUT, 0x00},
359 {R367TER_RCFSTATUS, 0x00},
360 {R367TER_RCFGOODPACK, 0x00},
361 {R367TER_RCFPACKCNT, 0x00},
362 {R367TER_RCFSPYMISC, 0x00},
363 {R367TER_RCFBERCPT4, 0x00},
364 {R367TER_RCFBERCPT3, 0x00},
365 {R367TER_RCFBERCPT2, 0x00},
366 {R367TER_RCFBERCPT1, 0x00},
367 {R367TER_RCFBERCPT0, 0x00},
368 {R367TER_RCFBERERR2, 0x00},
369 {R367TER_RCFBERERR1, 0x00},
370 {R367TER_RCFBERERR0, 0x00},
371 {R367TER_RCFSTATESM, 0x00},
372 {R367TER_RCFSTATESL, 0x00},
373 {R367TER_RCFSPYBER, 0x00},
374 {R367TER_RCFSPYDISTM, 0x00},
375 {R367TER_RCFSPYDISTL, 0x00},
376 {R367TER_RCFSPYOBS7, 0x00},
377 {R367TER_RCFSPYOBS6, 0x00},
378 {R367TER_RCFSPYOBS5, 0x00},
379 {R367TER_RCFSPYOBS4, 0x00},
380 {R367TER_RCFSPYOBS3, 0x00},
381 {R367TER_RCFSPYOBS2, 0x00},
382 {R367TER_RCFSPYOBS1, 0x00},
383 {R367TER_RCFSPYOBS0, 0x00},
384 {R367TER_TSGENERAL, 0x00},
385 {R367TER_RC1SPEED, 0x6f},
386 {R367TER_TSGSTATUS, 0x18},
387 {R367TER_FECM, 0x01},
388 {R367TER_VTH12, 0xff},
389 {R367TER_VTH23, 0xa1},
390 {R367TER_VTH34, 0x64},
391 {R367TER_VTH56, 0x40},
392 {R367TER_VTH67, 0x00},
393 {R367TER_VTH78, 0x2c},
394 {R367TER_VITCURPUN, 0x12},
395 {R367TER_VERROR, 0x01},
396 {R367TER_PRVIT, 0x3f},
397 {R367TER_VAVSRVIT, 0x00},
398 {R367TER_VSTATUSVIT, 0xbd},
399 {R367TER_VTHINUSE, 0xa1},
400 {R367TER_KDIV12, 0x20},
401 {R367TER_KDIV23, 0x40},
402 {R367TER_KDIV34, 0x20},
403 {R367TER_KDIV56, 0x30},
404 {R367TER_KDIV67, 0x00},
405 {R367TER_KDIV78, 0x30},
406 {R367TER_SIGPOWER, 0x54},
407 {R367TER_DEMAPVIT, 0x40},
408 {R367TER_VITSCALE, 0x00},
409 {R367TER_FFEC1PRG, 0x00},
410 {R367TER_FVITCURPUN, 0x12},
411 {R367TER_FVERROR, 0x01},
412 {R367TER_FVSTATUSVIT, 0xbd},
413 {R367TER_DEBUG_LT1, 0x00},
414 {R367TER_DEBUG_LT2, 0x00},
415 {R367TER_DEBUG_LT3, 0x00},
416 {R367TER_TSTSFMET, 0x00},
417 {R367TER_SELOUT, 0x00},
418 {R367TER_TSYNC, 0x00},
419 {R367TER_TSTERR, 0x00},
420 {R367TER_TSFSYNC, 0x00},
421 {R367TER_TSTSFERR, 0x00},
422 {R367TER_TSTTSSF1, 0x01},
423 {R367TER_TSTTSSF2, 0x1f},
424 {R367TER_TSTTSSF3, 0x00},
425 {R367TER_TSTTS1, 0x00},
426 {R367TER_TSTTS2, 0x1f},
427 {R367TER_TSTTS3, 0x01},
428 {R367TER_TSTTS4, 0x00},
429 {R367TER_TSTTSRC, 0x00},
430 {R367TER_TSTTSRS, 0x00},
431 {R367TER_TSSTATEM, 0xb0},
432 {R367TER_TSSTATEL, 0x40},
433 {R367TER_TSCFGH, 0xC0},
434 {R367TER_TSCFGM, 0xc0},/* for xc5000; was 0x00 */
435 {R367TER_TSCFGL, 0x20},
436 {R367TER_TSSYNC, 0x00},
437 {R367TER_TSINSDELH, 0x00},
438 {R367TER_TSINSDELM, 0x00},
439 {R367TER_TSINSDELL, 0x00},
440 {R367TER_TSDIVN, 0x03},
441 {R367TER_TSDIVPM, 0x00},
442 {R367TER_TSDIVPL, 0x00},
443 {R367TER_TSDIVQM, 0x00},
444 {R367TER_TSDIVQL, 0x00},
445 {R367TER_TSDILSTKM, 0x00},
446 {R367TER_TSDILSTKL, 0x00},
447 {R367TER_TSSPEED, 0x40},/* for xc5000; was 0x6f */
448 {R367TER_TSSTATUS, 0x81},
449 {R367TER_TSSTATUS2, 0x6a},
450 {R367TER_TSBITRATEM, 0x0f},
451 {R367TER_TSBITRATEL, 0xc6},
452 {R367TER_TSPACKLENM, 0x00},
453 {R367TER_TSPACKLENL, 0xfc},
454 {R367TER_TSBLOCLENM, 0x0a},
455 {R367TER_TSBLOCLENL, 0x80},
456 {R367TER_TSDLYH, 0x90},
457 {R367TER_TSDLYM, 0x68},
458 {R367TER_TSDLYL, 0x01},
459 {R367TER_TSNPDAV, 0x00},
460 {R367TER_TSBUFSTATH, 0x00},
461 {R367TER_TSBUFSTATM, 0x00},
462 {R367TER_TSBUFSTATL, 0x00},
463 {R367TER_TSDEBUGM, 0xcf},
464 {R367TER_TSDEBUGL, 0x1e},
465 {R367TER_TSDLYSETH, 0x00},
466 {R367TER_TSDLYSETM, 0x68},
467 {R367TER_TSDLYSETL, 0x00},
468 {R367TER_TSOBSCFG, 0x00},
469 {R367TER_TSOBSM, 0x47},
470 {R367TER_TSOBSL, 0x1f},
471 {R367TER_ERRCTRL1, 0x95},
472 {R367TER_ERRCNT1H, 0x80},
473 {R367TER_ERRCNT1M, 0x00},
474 {R367TER_ERRCNT1L, 0x00},
475 {R367TER_ERRCTRL2, 0x95},
476 {R367TER_ERRCNT2H, 0x00},
477 {R367TER_ERRCNT2M, 0x00},
478 {R367TER_ERRCNT2L, 0x00},
479 {R367TER_FECSPY, 0x88},
480 {R367TER_FSPYCFG, 0x2c},
481 {R367TER_FSPYDATA, 0x3a},
482 {R367TER_FSPYOUT, 0x06},
483 {R367TER_FSTATUS, 0x61},
484 {R367TER_FGOODPACK, 0xff},
485 {R367TER_FPACKCNT, 0xff},
486 {R367TER_FSPYMISC, 0x66},
487 {R367TER_FBERCPT4, 0x00},
488 {R367TER_FBERCPT3, 0x00},
489 {R367TER_FBERCPT2, 0x36},
490 {R367TER_FBERCPT1, 0x36},
491 {R367TER_FBERCPT0, 0x14},
492 {R367TER_FBERERR2, 0x00},
493 {R367TER_FBERERR1, 0x03},
494 {R367TER_FBERERR0, 0x28},
495 {R367TER_FSTATESM, 0x00},
496 {R367TER_FSTATESL, 0x02},
497 {R367TER_FSPYBER, 0x00},
498 {R367TER_FSPYDISTM, 0x01},
499 {R367TER_FSPYDISTL, 0x9f},
500 {R367TER_FSPYOBS7, 0xc9},
501 {R367TER_FSPYOBS6, 0x99},
502 {R367TER_FSPYOBS5, 0x08},
503 {R367TER_FSPYOBS4, 0xec},
504 {R367TER_FSPYOBS3, 0x01},
505 {R367TER_FSPYOBS2, 0x0f},
506 {R367TER_FSPYOBS1, 0xf5},
507 {R367TER_FSPYOBS0, 0x08},
508 {R367TER_SFDEMAP, 0x40},
509 {R367TER_SFERROR, 0x00},
510 {R367TER_SFAVSR, 0x30},
511 {R367TER_SFECSTATUS, 0xcc},
512 {R367TER_SFKDIV12, 0x20},
513 {R367TER_SFKDIV23, 0x40},
514 {R367TER_SFKDIV34, 0x20},
515 {R367TER_SFKDIV56, 0x20},
516 {R367TER_SFKDIV67, 0x00},
517 {R367TER_SFKDIV78, 0x20},
518 {R367TER_SFDILSTKM, 0x00},
519 {R367TER_SFDILSTKL, 0x00},
520 {R367TER_SFSTATUS, 0xb5},
521 {R367TER_SFDLYH, 0x90},
522 {R367TER_SFDLYM, 0x60},
523 {R367TER_SFDLYL, 0x01},
524 {R367TER_SFDLYSETH, 0xc0},
525 {R367TER_SFDLYSETM, 0x60},
526 {R367TER_SFDLYSETL, 0x00},
527 {R367TER_SFOBSCFG, 0x00},
528 {R367TER_SFOBSM, 0x47},
529 {R367TER_SFOBSL, 0x05},
530 {R367TER_SFECINFO, 0x40},
531 {R367TER_SFERRCTRL, 0x74},
532 {R367TER_SFERRCNTH, 0x80},
533 {R367TER_SFERRCNTM , 0x00},
534 {R367TER_SFERRCNTL, 0x00},
535 {R367TER_SYMBRATEM, 0x2f},
536 {R367TER_SYMBRATEL, 0x50},
537 {R367TER_SYMBSTATUS, 0x7f},
538 {R367TER_SYMBCFG, 0x00},
539 {R367TER_SYMBFIFOM, 0xf4},
540 {R367TER_SYMBFIFOL, 0x0d},
541 {R367TER_SYMBOFFSM, 0xf0},
542 {R367TER_SYMBOFFSL, 0x2d},
543 {R367TER_DEBUG_LT4, 0x00},
544 {R367TER_DEBUG_LT5, 0x00},
545 {R367TER_DEBUG_LT6, 0x00},
546 {R367TER_DEBUG_LT7, 0x00},
547 {R367TER_DEBUG_LT8, 0x00},
548 {R367TER_DEBUG_LT9, 0x00},
549};
550
551#define RF_LOOKUP_TABLE_SIZE 31
552#define RF_LOOKUP_TABLE2_SIZE 16
553/* RF Level (for RF AGC->AGC1) Lookup Table, depends on the board and tuner.*/
554s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
555 {/*AGC1*/
556 48, 50, 51, 53, 54, 56, 57, 58, 60, 61, 62, 63,
557 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
558 76, 77, 78, 80, 83, 85, 88,
559 }, {/*RF(dbm)*/
560 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
561 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 47,
562 49, 50, 52, 53, 54, 55, 56,
563 }
564};
565/* RF Level (for IF AGC->AGC2) Lookup Table, depends on the board and tuner.*/
566s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_SIZE] = {
567 {/*AGC2*/
568 28, 29, 31, 32, 34, 35, 36, 37,
569 38, 39, 40, 41, 42, 43, 44, 45,
570 }, {/*RF(dbm)*/
571 57, 58, 59, 60, 61, 62, 63, 64,
572 65, 66, 67, 68, 69, 70, 71, 72,
573 }
574};
575
576static struct st_register def0367cab[STV0367CAB_NBREGS] = {
577 {R367CAB_ID, 0x60},
578 {R367CAB_I2CRPT, 0xa0},
579 /*{R367CAB_I2CRPT, 0x22},*/
580 {R367CAB_TOPCTRL, 0x10},
581 {R367CAB_IOCFG0, 0x80},
582 {R367CAB_DAC0R, 0x00},
583 {R367CAB_IOCFG1, 0x00},
584 {R367CAB_DAC1R, 0x00},
585 {R367CAB_IOCFG2, 0x00},
586 {R367CAB_SDFR, 0x00},
587 {R367CAB_AUX_CLK, 0x00},
588 {R367CAB_FREESYS1, 0x00},
589 {R367CAB_FREESYS2, 0x00},
590 {R367CAB_FREESYS3, 0x00},
591 {R367CAB_GPIO_CFG, 0x55},
592 {R367CAB_GPIO_CMD, 0x01},
593 {R367CAB_TSTRES, 0x00},
594 {R367CAB_ANACTRL, 0x0d},/* was 0x00 need to check - I.M.L.*/
595 {R367CAB_TSTBUS, 0x00},
596 {R367CAB_RF_AGC1, 0xea},
597 {R367CAB_RF_AGC2, 0x82},
598 {R367CAB_ANADIGCTRL, 0x0b},
599 {R367CAB_PLLMDIV, 0x01},
600 {R367CAB_PLLNDIV, 0x08},
601 {R367CAB_PLLSETUP, 0x18},
602 {R367CAB_DUAL_AD12, 0x0C}, /* for xc5000 AGC voltage 1.6V */
603 {R367CAB_TSTBIST, 0x00},
604 {R367CAB_CTRL_1, 0x00},
605 {R367CAB_CTRL_2, 0x03},
606 {R367CAB_IT_STATUS1, 0x2b},
607 {R367CAB_IT_STATUS2, 0x08},
608 {R367CAB_IT_EN1, 0x00},
609 {R367CAB_IT_EN2, 0x00},
610 {R367CAB_CTRL_STATUS, 0x04},
611 {R367CAB_TEST_CTL, 0x00},
612 {R367CAB_AGC_CTL, 0x73},
613 {R367CAB_AGC_IF_CFG, 0x50},
614 {R367CAB_AGC_RF_CFG, 0x00},
615 {R367CAB_AGC_PWM_CFG, 0x03},
616 {R367CAB_AGC_PWR_REF_L, 0x5a},
617 {R367CAB_AGC_PWR_REF_H, 0x00},
618 {R367CAB_AGC_RF_TH_L, 0xff},
619 {R367CAB_AGC_RF_TH_H, 0x07},
620 {R367CAB_AGC_IF_LTH_L, 0x00},
621 {R367CAB_AGC_IF_LTH_H, 0x08},
622 {R367CAB_AGC_IF_HTH_L, 0xff},
623 {R367CAB_AGC_IF_HTH_H, 0x07},
624 {R367CAB_AGC_PWR_RD_L, 0xa0},
625 {R367CAB_AGC_PWR_RD_M, 0xe9},
626 {R367CAB_AGC_PWR_RD_H, 0x03},
627 {R367CAB_AGC_PWM_IFCMD_L, 0xe4},
628 {R367CAB_AGC_PWM_IFCMD_H, 0x00},
629 {R367CAB_AGC_PWM_RFCMD_L, 0xff},
630 {R367CAB_AGC_PWM_RFCMD_H, 0x07},
631 {R367CAB_IQDEM_CFG, 0x01},
632 {R367CAB_MIX_NCO_LL, 0x22},
633 {R367CAB_MIX_NCO_HL, 0x96},
634 {R367CAB_MIX_NCO_HH, 0x55},
635 {R367CAB_SRC_NCO_LL, 0xff},
636 {R367CAB_SRC_NCO_LH, 0x0c},
637 {R367CAB_SRC_NCO_HL, 0xf5},
638 {R367CAB_SRC_NCO_HH, 0x20},
639 {R367CAB_IQDEM_GAIN_SRC_L, 0x06},
640 {R367CAB_IQDEM_GAIN_SRC_H, 0x01},
641 {R367CAB_IQDEM_DCRM_CFG_LL, 0xfe},
642 {R367CAB_IQDEM_DCRM_CFG_LH, 0xff},
643 {R367CAB_IQDEM_DCRM_CFG_HL, 0x0f},
644 {R367CAB_IQDEM_DCRM_CFG_HH, 0x00},
645 {R367CAB_IQDEM_ADJ_COEFF0, 0x34},
646 {R367CAB_IQDEM_ADJ_COEFF1, 0xae},
647 {R367CAB_IQDEM_ADJ_COEFF2, 0x46},
648 {R367CAB_IQDEM_ADJ_COEFF3, 0x77},
649 {R367CAB_IQDEM_ADJ_COEFF4, 0x96},
650 {R367CAB_IQDEM_ADJ_COEFF5, 0x69},
651 {R367CAB_IQDEM_ADJ_COEFF6, 0xc7},
652 {R367CAB_IQDEM_ADJ_COEFF7, 0x01},
653 {R367CAB_IQDEM_ADJ_EN, 0x04},
654 {R367CAB_IQDEM_ADJ_AGC_REF, 0x94},
655 {R367CAB_ALLPASSFILT1, 0xc9},
656 {R367CAB_ALLPASSFILT2, 0x2d},
657 {R367CAB_ALLPASSFILT3, 0xa3},
658 {R367CAB_ALLPASSFILT4, 0xfb},
659 {R367CAB_ALLPASSFILT5, 0xf6},
660 {R367CAB_ALLPASSFILT6, 0x45},
661 {R367CAB_ALLPASSFILT7, 0x6f},
662 {R367CAB_ALLPASSFILT8, 0x7e},
663 {R367CAB_ALLPASSFILT9, 0x05},
664 {R367CAB_ALLPASSFILT10, 0x0a},
665 {R367CAB_ALLPASSFILT11, 0x51},
666 {R367CAB_TRL_AGC_CFG, 0x20},
667 {R367CAB_TRL_LPF_CFG, 0x28},
668 {R367CAB_TRL_LPF_ACQ_GAIN, 0x44},
669 {R367CAB_TRL_LPF_TRK_GAIN, 0x22},
670 {R367CAB_TRL_LPF_OUT_GAIN, 0x03},
671 {R367CAB_TRL_LOCKDET_LTH, 0x04},
672 {R367CAB_TRL_LOCKDET_HTH, 0x11},
673 {R367CAB_TRL_LOCKDET_TRGVAL, 0x20},
674 {R367CAB_IQ_QAM, 0x01},
675 {R367CAB_FSM_STATE, 0xa0},
676 {R367CAB_FSM_CTL, 0x08},
677 {R367CAB_FSM_STS, 0x0c},
678 {R367CAB_FSM_SNR0_HTH, 0x00},
679 {R367CAB_FSM_SNR1_HTH, 0x00},
680 {R367CAB_FSM_SNR2_HTH, 0x23},/* 0x00 */
681 {R367CAB_FSM_SNR0_LTH, 0x00},
682 {R367CAB_FSM_SNR1_LTH, 0x00},
683 {R367CAB_FSM_EQA1_HTH, 0x00},
684 {R367CAB_FSM_TEMPO, 0x32},
685 {R367CAB_FSM_CONFIG, 0x03},
686 {R367CAB_EQU_I_TESTTAP_L, 0x11},
687 {R367CAB_EQU_I_TESTTAP_M, 0x00},
688 {R367CAB_EQU_I_TESTTAP_H, 0x00},
689 {R367CAB_EQU_TESTAP_CFG, 0x00},
690 {R367CAB_EQU_Q_TESTTAP_L, 0xff},
691 {R367CAB_EQU_Q_TESTTAP_M, 0x00},
692 {R367CAB_EQU_Q_TESTTAP_H, 0x00},
693 {R367CAB_EQU_TAP_CTRL, 0x00},
694 {R367CAB_EQU_CTR_CRL_CONTROL_L, 0x11},
695 {R367CAB_EQU_CTR_CRL_CONTROL_H, 0x05},
696 {R367CAB_EQU_CTR_HIPOW_L, 0x00},
697 {R367CAB_EQU_CTR_HIPOW_H, 0x00},
698 {R367CAB_EQU_I_EQU_LO, 0xef},
699 {R367CAB_EQU_I_EQU_HI, 0x00},
700 {R367CAB_EQU_Q_EQU_LO, 0xee},
701 {R367CAB_EQU_Q_EQU_HI, 0x00},
702 {R367CAB_EQU_MAPPER, 0xc5},
703 {R367CAB_EQU_SWEEP_RATE, 0x80},
704 {R367CAB_EQU_SNR_LO, 0x64},
705 {R367CAB_EQU_SNR_HI, 0x03},
706 {R367CAB_EQU_GAMMA_LO, 0x00},
707 {R367CAB_EQU_GAMMA_HI, 0x00},
708 {R367CAB_EQU_ERR_GAIN, 0x36},
709 {R367CAB_EQU_RADIUS, 0xaa},
710 {R367CAB_EQU_FFE_MAINTAP, 0x00},
711 {R367CAB_EQU_FFE_LEAKAGE, 0x63},
712 {R367CAB_EQU_FFE_MAINTAP_POS, 0xdf},
713 {R367CAB_EQU_GAIN_WIDE, 0x88},
714 {R367CAB_EQU_GAIN_NARROW, 0x41},
715 {R367CAB_EQU_CTR_LPF_GAIN, 0xd1},
716 {R367CAB_EQU_CRL_LPF_GAIN, 0xa7},
717 {R367CAB_EQU_GLOBAL_GAIN, 0x06},
718 {R367CAB_EQU_CRL_LD_SEN, 0x85},
719 {R367CAB_EQU_CRL_LD_VAL, 0xe2},
720 {R367CAB_EQU_CRL_TFR, 0x20},
721 {R367CAB_EQU_CRL_BISTH_LO, 0x00},
722 {R367CAB_EQU_CRL_BISTH_HI, 0x00},
723 {R367CAB_EQU_SWEEP_RANGE_LO, 0x00},
724 {R367CAB_EQU_SWEEP_RANGE_HI, 0x00},
725 {R367CAB_EQU_CRL_LIMITER, 0x40},
726 {R367CAB_EQU_MODULUS_MAP, 0x90},
727 {R367CAB_EQU_PNT_GAIN, 0xa7},
728 {R367CAB_FEC_AC_CTR_0, 0x16},
729 {R367CAB_FEC_AC_CTR_1, 0x0b},
730 {R367CAB_FEC_AC_CTR_2, 0x88},
731 {R367CAB_FEC_AC_CTR_3, 0x02},
732 {R367CAB_FEC_STATUS, 0x12},
733 {R367CAB_RS_COUNTER_0, 0x7d},
734 {R367CAB_RS_COUNTER_1, 0xd0},
735 {R367CAB_RS_COUNTER_2, 0x19},
736 {R367CAB_RS_COUNTER_3, 0x0b},
737 {R367CAB_RS_COUNTER_4, 0xa3},
738 {R367CAB_RS_COUNTER_5, 0x00},
739 {R367CAB_BERT_0, 0x01},
740 {R367CAB_BERT_1, 0x25},
741 {R367CAB_BERT_2, 0x41},
742 {R367CAB_BERT_3, 0x39},
743 {R367CAB_OUTFORMAT_0, 0xc2},
744 {R367CAB_OUTFORMAT_1, 0x22},
745 {R367CAB_SMOOTHER_2, 0x28},
746 {R367CAB_TSMF_CTRL_0, 0x01},
747 {R367CAB_TSMF_CTRL_1, 0xc6},
748 {R367CAB_TSMF_CTRL_3, 0x43},
749 {R367CAB_TS_ON_ID_0, 0x00},
750 {R367CAB_TS_ON_ID_1, 0x00},
751 {R367CAB_TS_ON_ID_2, 0x00},
752 {R367CAB_TS_ON_ID_3, 0x00},
753 {R367CAB_RE_STATUS_0, 0x00},
754 {R367CAB_RE_STATUS_1, 0x00},
755 {R367CAB_RE_STATUS_2, 0x00},
756 {R367CAB_RE_STATUS_3, 0x00},
757 {R367CAB_TS_STATUS_0, 0x00},
758 {R367CAB_TS_STATUS_1, 0x00},
759 {R367CAB_TS_STATUS_2, 0xa0},
760 {R367CAB_TS_STATUS_3, 0x00},
761 {R367CAB_T_O_ID_0, 0x00},
762 {R367CAB_T_O_ID_1, 0x00},
763 {R367CAB_T_O_ID_2, 0x00},
764 {R367CAB_T_O_ID_3, 0x00},
765};
766
767static
768int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
769{
770 u8 buf[len + 2];
771 struct i2c_msg msg = {
772 .addr = state->config->demod_address,
773 .flags = 0,
774 .buf = buf,
775 .len = len + 2
776 };
777 int ret;
778
779 buf[0] = MSB(reg);
780 buf[1] = LSB(reg);
781 memcpy(buf + 2, data, len);
782
783 if (i2cdebug)
784 printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, buf[2]);
785
786 ret = i2c_transfer(state->i2c, &msg, 1);
787 if (ret != 1)
788 printk(KERN_ERR "%s: i2c write error!\n", __func__);
789
790 return (ret != 1) ? -EREMOTEIO : 0;
791}
792
793static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
794{
795 return stv0367_writeregs(state, reg, &data, 1);
796}
797
798static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
799{
800 u8 b0[] = { 0, 0 };
801 u8 b1[] = { 0 };
802 struct i2c_msg msg[] = {
803 {
804 .addr = state->config->demod_address,
805 .flags = 0,
806 .buf = b0,
807 .len = 2
808 }, {
809 .addr = state->config->demod_address,
810 .flags = I2C_M_RD,
811 .buf = b1,
812 .len = 1
813 }
814 };
815 int ret;
816
817 b0[0] = MSB(reg);
818 b0[1] = LSB(reg);
819
820 ret = i2c_transfer(state->i2c, msg, 2);
821 if (ret != 2)
822 printk(KERN_ERR "%s: i2c read error\n", __func__);
823
824 if (i2cdebug)
825 printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, b1[0]);
826
827 return b1[0];
828}
829
830static void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
831{
832 u8 position = 0, i = 0;
833
834 (*mask) = label & 0xff;
835
836 while ((position == 0) && (i < 8)) {
837 position = ((*mask) >> i) & 0x01;
838 i++;
839 }
840
841 (*pos) = (i - 1);
842}
843
844static void stv0367_writebits(struct stv0367_state *state, u32 label, u8 val)
845{
846 u8 reg, mask, pos;
847
848 reg = stv0367_readreg(state, (label >> 16) & 0xffff);
849 extract_mask_pos(label, &mask, &pos);
850
851 val = mask & (val << pos);
852
853 reg = (reg & (~mask)) | val;
854 stv0367_writereg(state, (label >> 16) & 0xffff, reg);
855
856}
857
858static void stv0367_setbits(u8 *reg, u32 label, u8 val)
859{
860 u8 mask, pos;
861
862 extract_mask_pos(label, &mask, &pos);
863
864 val = mask & (val << pos);
865
866 (*reg) = ((*reg) & (~mask)) | val;
867}
868
869static u8 stv0367_readbits(struct stv0367_state *state, u32 label)
870{
871 u8 val = 0xff;
872 u8 mask, pos;
873
874 extract_mask_pos(label, &mask, &pos);
875
876 val = stv0367_readreg(state, label >> 16);
877 val = (val & mask) >> pos;
878
879 return val;
880}
881
882u8 stv0367_getbits(u8 reg, u32 label)
883{
884 u8 mask, pos;
885
886 extract_mask_pos(label, &mask, &pos);
887
888 return (reg & mask) >> pos;
889}
890
891static int stv0367ter_gate_ctrl(struct dvb_frontend *fe, int enable)
892{
893 struct stv0367_state *state = fe->demodulator_priv;
894 u8 tmp = stv0367_readreg(state, R367TER_I2CRPT);
895
896 dprintk("%s:\n", __func__);
897
898 if (enable) {
899 stv0367_setbits(&tmp, F367TER_STOP_ENABLE, 0);
900 stv0367_setbits(&tmp, F367TER_I2CT_ON, 1);
901 } else {
902 stv0367_setbits(&tmp, F367TER_STOP_ENABLE, 1);
903 stv0367_setbits(&tmp, F367TER_I2CT_ON, 0);
904 }
905
906 stv0367_writereg(state, R367TER_I2CRPT, tmp);
907
908 return 0;
909}
910
911static u32 stv0367_get_tuner_freq(struct dvb_frontend *fe)
912{
913 struct dvb_frontend_ops *frontend_ops = NULL;
914 struct dvb_tuner_ops *tuner_ops = NULL;
915 u32 freq = 0;
916 int err = 0;
917
918 dprintk("%s:\n", __func__);
919
920
921 if (&fe->ops)
922 frontend_ops = &fe->ops;
923 if (&frontend_ops->tuner_ops)
924 tuner_ops = &frontend_ops->tuner_ops;
925 if (tuner_ops->get_frequency) {
926 err = tuner_ops->get_frequency(fe, &freq);
927 if (err < 0) {
928 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
929 return err;
930 }
931
932 dprintk("%s: frequency=%d\n", __func__, freq);
933
934 } else
935 return -1;
936
937 return freq;
938}
939
940static u16 CellsCoeffs_8MHz_367cofdm[3][6][5] = {
941 {
942 {0x10EF, 0xE205, 0x10EF, 0xCE49, 0x6DA7}, /* CELL 1 COEFFS 27M*/
943 {0x2151, 0xc557, 0x2151, 0xc705, 0x6f93}, /* CELL 2 COEFFS */
944 {0x2503, 0xc000, 0x2503, 0xc375, 0x7194}, /* CELL 3 COEFFS */
945 {0x20E9, 0xca94, 0x20e9, 0xc153, 0x7194}, /* CELL 4 COEFFS */
946 {0x06EF, 0xF852, 0x06EF, 0xC057, 0x7207}, /* CELL 5 COEFFS */
947 {0x0000, 0x0ECC, 0x0ECC, 0x0000, 0x3647} /* CELL 6 COEFFS */
948 }, {
949 {0x10A0, 0xE2AF, 0x10A1, 0xCE76, 0x6D6D}, /* CELL 1 COEFFS 25M*/
950 {0x20DC, 0xC676, 0x20D9, 0xC80A, 0x6F29},
951 {0x2532, 0xC000, 0x251D, 0xC391, 0x706F},
952 {0x1F7A, 0xCD2B, 0x2032, 0xC15E, 0x711F},
953 {0x0698, 0xFA5E, 0x0568, 0xC059, 0x7193},
954 {0x0000, 0x0918, 0x149C, 0x0000, 0x3642} /* CELL 6 COEFFS */
955 }, {
956 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
957 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
958 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
959 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
960 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
961 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
962 }
963};
964
965static u16 CellsCoeffs_7MHz_367cofdm[3][6][5] = {
966 {
967 {0x12CA, 0xDDAF, 0x12CA, 0xCCEB, 0x6FB1}, /* CELL 1 COEFFS 27M*/
968 {0x2329, 0xC000, 0x2329, 0xC6B0, 0x725F}, /* CELL 2 COEFFS */
969 {0x2394, 0xC000, 0x2394, 0xC2C7, 0x7410}, /* CELL 3 COEFFS */
970 {0x251C, 0xC000, 0x251C, 0xC103, 0x74D9}, /* CELL 4 COEFFS */
971 {0x0804, 0xF546, 0x0804, 0xC040, 0x7544}, /* CELL 5 COEFFS */
972 {0x0000, 0x0CD9, 0x0CD9, 0x0000, 0x370A} /* CELL 6 COEFFS */
973 }, {
974 {0x1285, 0xDE47, 0x1285, 0xCD17, 0x6F76}, /*25M*/
975 {0x234C, 0xC000, 0x2348, 0xC6DA, 0x7206},
976 {0x23B4, 0xC000, 0x23AC, 0xC2DB, 0x73B3},
977 {0x253D, 0xC000, 0x25B6, 0xC10B, 0x747F},
978 {0x0721, 0xF79C, 0x065F, 0xC041, 0x74EB},
979 {0x0000, 0x08FA, 0x1162, 0x0000, 0x36FF}
980 }, {
981 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
982 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
983 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
984 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
985 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
986 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
987 }
988};
989
990static u16 CellsCoeffs_6MHz_367cofdm[3][6][5] = {
991 {
992 {0x1699, 0xD5B8, 0x1699, 0xCBC3, 0x713B}, /* CELL 1 COEFFS 27M*/
993 {0x2245, 0xC000, 0x2245, 0xC568, 0x74D5}, /* CELL 2 COEFFS */
994 {0x227F, 0xC000, 0x227F, 0xC1FC, 0x76C6}, /* CELL 3 COEFFS */
995 {0x235E, 0xC000, 0x235E, 0xC0A7, 0x778A}, /* CELL 4 COEFFS */
996 {0x0ECB, 0xEA0B, 0x0ECB, 0xC027, 0x77DD}, /* CELL 5 COEFFS */
997 {0x0000, 0x0B68, 0x0B68, 0x0000, 0xC89A}, /* CELL 6 COEFFS */
998 }, {
999 {0x1655, 0xD64E, 0x1658, 0xCBEF, 0x70FE}, /*25M*/
1000 {0x225E, 0xC000, 0x2256, 0xC589, 0x7489},
1001 {0x2293, 0xC000, 0x2295, 0xC209, 0x767E},
1002 {0x2377, 0xC000, 0x23AA, 0xC0AB, 0x7746},
1003 {0x0DC7, 0xEBC8, 0x0D07, 0xC027, 0x7799},
1004 {0x0000, 0x0888, 0x0E9C, 0x0000, 0x3757}
1005
1006 }, {
1007 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
1008 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1009 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1010 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1011 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1012 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
1013 }
1014};
1015
1016static u32 stv0367ter_get_mclk(struct stv0367_state *state, u32 ExtClk_Hz)
1017{
1018 u32 mclk_Hz = 0; /* master clock frequency (Hz) */
1019 u32 m, n, p;
1020
1021 dprintk("%s:\n", __func__);
1022
1023 if (stv0367_readbits(state, F367TER_BYPASS_PLLXN) == 0) {
1024 n = (u32)stv0367_readbits(state, F367TER_PLL_NDIV);
1025 if (n == 0)
1026 n = n + 1;
1027
1028 m = (u32)stv0367_readbits(state, F367TER_PLL_MDIV);
1029 if (m == 0)
1030 m = m + 1;
1031
1032 p = (u32)stv0367_readbits(state, F367TER_PLL_PDIV);
1033 if (p > 5)
1034 p = 5;
1035
1036 mclk_Hz = ((ExtClk_Hz / 2) * n) / (m * (1 << p));
1037
1038 dprintk("N=%d M=%d P=%d mclk_Hz=%d ExtClk_Hz=%d\n",
1039 n, m, p, mclk_Hz, ExtClk_Hz);
1040 } else
1041 mclk_Hz = ExtClk_Hz;
1042
1043 dprintk("%s: mclk_Hz=%d\n", __func__, mclk_Hz);
1044
1045 return mclk_Hz;
1046}
1047
1048static int stv0367ter_filt_coeff_init(struct stv0367_state *state,
1049 u16 CellsCoeffs[3][6][5], u32 DemodXtal)
1050{
1051 int i, j, k, freq;
1052
1053 dprintk("%s:\n", __func__);
1054
1055 freq = stv0367ter_get_mclk(state, DemodXtal);
1056
1057 if (freq == 53125000)
1058 k = 1; /* equivalent to Xtal 25M on 362*/
1059 else if (freq == 54000000)
1060 k = 0; /* equivalent to Xtal 27M on 362*/
1061 else if (freq == 52500000)
1062 k = 2; /* equivalent to Xtal 30M on 362*/
1063 else
1064 return 0;
1065
1066 for (i = 1; i <= 6; i++) {
1067 stv0367_writebits(state, F367TER_IIR_CELL_NB, i - 1);
1068
1069 for (j = 1; j <= 5; j++) {
1070 stv0367_writereg(state,
1071 (R367TER_IIRCX_COEFF1_MSB + 2 * (j - 1)),
1072 MSB(CellsCoeffs[k][i-1][j-1]));
1073 stv0367_writereg(state,
1074 (R367TER_IIRCX_COEFF1_LSB + 2 * (j - 1)),
1075 LSB(CellsCoeffs[k][i-1][j-1]));
1076 }
1077 }
1078
1079 return 1;
1080
1081}
1082
1083static void stv0367ter_agc_iir_lock_detect_set(struct stv0367_state *state)
1084{
1085 dprintk("%s:\n", __func__);
1086
1087 stv0367_writebits(state, F367TER_LOCK_DETECT_LSB, 0x00);
1088
1089 /* Lock detect 1 */
1090 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x00);
1091 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x06);
1092 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x04);
1093
1094 /* Lock detect 2 */
1095 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x01);
1096 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x06);
1097 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x04);
1098
1099 /* Lock detect 3 */
1100 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x02);
1101 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x01);
1102 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x00);
1103
1104 /* Lock detect 4 */
1105 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x03);
1106 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x01);
1107 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x00);
1108
1109}
1110
1111static int stv0367_iir_filt_init(struct stv0367_state *state, u8 Bandwidth,
1112 u32 DemodXtalValue)
1113{
1114 dprintk("%s:\n", __func__);
1115
1116 stv0367_writebits(state, F367TER_NRST_IIR, 0);
1117
1118 switch (Bandwidth) {
1119 case 6:
1120 if (!stv0367ter_filt_coeff_init(state,
1121 CellsCoeffs_6MHz_367cofdm,
1122 DemodXtalValue))
1123 return 0;
1124 break;
1125 case 7:
1126 if (!stv0367ter_filt_coeff_init(state,
1127 CellsCoeffs_7MHz_367cofdm,
1128 DemodXtalValue))
1129 return 0;
1130 break;
1131 case 8:
1132 if (!stv0367ter_filt_coeff_init(state,
1133 CellsCoeffs_8MHz_367cofdm,
1134 DemodXtalValue))
1135 return 0;
1136 break;
1137 default:
1138 return 0;
1139 }
1140
1141 stv0367_writebits(state, F367TER_NRST_IIR, 1);
1142
1143 return 1;
1144}
1145
1146static void stv0367ter_agc_iir_rst(struct stv0367_state *state)
1147{
1148
1149 u8 com_n;
1150
1151 dprintk("%s:\n", __func__);
1152
1153 com_n = stv0367_readbits(state, F367TER_COM_N);
1154
1155 stv0367_writebits(state, F367TER_COM_N, 0x07);
1156
1157 stv0367_writebits(state, F367TER_COM_SOFT_RSTN, 0x00);
1158 stv0367_writebits(state, F367TER_COM_AGC_ON, 0x00);
1159
1160 stv0367_writebits(state, F367TER_COM_SOFT_RSTN, 0x01);
1161 stv0367_writebits(state, F367TER_COM_AGC_ON, 0x01);
1162
1163 stv0367_writebits(state, F367TER_COM_N, com_n);
1164
1165}
1166
1167static int stv0367ter_duration(s32 mode, int tempo1, int tempo2, int tempo3)
1168{
1169 int local_tempo = 0;
1170 switch (mode) {
1171 case 0:
1172 local_tempo = tempo1;
1173 break;
1174 case 1:
1175 local_tempo = tempo2;
1176 break ;
1177
1178 case 2:
1179 local_tempo = tempo3;
1180 break;
1181
1182 default:
1183 break;
1184 }
1185 /* msleep(local_tempo); */
1186 return local_tempo;
1187}
1188
1189static enum
1190stv0367_ter_signal_type stv0367ter_check_syr(struct stv0367_state *state)
1191{
1192 int wd = 100;
1193 unsigned short int SYR_var;
1194 s32 SYRStatus;
1195
1196 dprintk("%s:\n", __func__);
1197
1198 SYR_var = stv0367_readbits(state, F367TER_SYR_LOCK);
1199
1200 while ((!SYR_var) && (wd > 0)) {
1201 usleep_range(2000, 3000);
1202 wd -= 2;
1203 SYR_var = stv0367_readbits(state, F367TER_SYR_LOCK);
1204 }
1205
1206 if (!SYR_var)
1207 SYRStatus = FE_TER_NOSYMBOL;
1208 else
1209 SYRStatus = FE_TER_SYMBOLOK;
1210
1211 dprintk("stv0367ter_check_syr SYRStatus %s\n",
1212 SYR_var == 0 ? "No Symbol" : "OK");
1213
1214 return SYRStatus;
1215}
1216
1217static enum
1218stv0367_ter_signal_type stv0367ter_check_cpamp(struct stv0367_state *state,
1219 s32 FFTmode)
1220{
1221
1222 s32 CPAMPvalue = 0, CPAMPStatus, CPAMPMin;
1223 int wd = 0;
1224
1225 dprintk("%s:\n", __func__);
1226
1227 switch (FFTmode) {
1228 case 0: /*2k mode*/
1229 CPAMPMin = 20;
1230 wd = 10;
1231 break;
1232 case 1: /*8k mode*/
1233 CPAMPMin = 80;
1234 wd = 55;
1235 break;
1236 case 2: /*4k mode*/
1237 CPAMPMin = 40;
1238 wd = 30;
1239 break;
1240 default:
1241 CPAMPMin = 0xffff; /*drives to NOCPAMP */
1242 break;
1243 }
1244
1245 dprintk("%s: CPAMPMin=%d wd=%d\n", __func__, CPAMPMin, wd);
1246
1247 CPAMPvalue = stv0367_readbits(state, F367TER_PPM_CPAMP_DIRECT);
1248 while ((CPAMPvalue < CPAMPMin) && (wd > 0)) {
1249 usleep_range(1000, 2000);
1250 wd -= 1;
1251 CPAMPvalue = stv0367_readbits(state, F367TER_PPM_CPAMP_DIRECT);
1252 /*dprintk("CPAMPvalue= %d at wd=%d\n",CPAMPvalue,wd); */
1253 }
1254 dprintk("******last CPAMPvalue= %d at wd=%d\n", CPAMPvalue, wd);
1255 if (CPAMPvalue < CPAMPMin) {
1256 CPAMPStatus = FE_TER_NOCPAMP;
1257 printk(KERN_ERR "CPAMP failed\n");
1258 } else {
1259 printk(KERN_ERR "CPAMP OK !\n");
1260 CPAMPStatus = FE_TER_CPAMPOK;
1261 }
1262
1263 return CPAMPStatus;
1264}
1265
1266enum
1267stv0367_ter_signal_type stv0367ter_lock_algo(struct stv0367_state *state)
1268{
1269 enum stv0367_ter_signal_type ret_flag;
1270 short int wd, tempo;
1271 u8 try, u_var1 = 0, u_var2 = 0, u_var3 = 0, u_var4 = 0, mode, guard;
1272 u8 tmp, tmp2;
1273
1274 dprintk("%s:\n", __func__);
1275
1276 if (state == NULL)
1277 return FE_TER_SWNOK;
1278
1279 try = 0;
1280 do {
1281 ret_flag = FE_TER_LOCKOK;
1282
1283 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
1284
1285 if (state->config->if_iq_mode != 0)
1286 stv0367_writebits(state, F367TER_COM_N, 0x07);
1287
1288 stv0367_writebits(state, F367TER_GUARD, 3);/* suggest 2k 1/4 */
1289 stv0367_writebits(state, F367TER_MODE, 0);
1290 stv0367_writebits(state, F367TER_SYR_TR_DIS, 0);
1291 usleep_range(5000, 10000);
1292
1293 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
1294
1295
1296 if (stv0367ter_check_syr(state) == FE_TER_NOSYMBOL)
1297 return FE_TER_NOSYMBOL;
1298 else { /*
1299 if chip locked on wrong mode first try,
1300 it must lock correctly second try */
1301 mode = stv0367_readbits(state, F367TER_SYR_MODE);
1302 if (stv0367ter_check_cpamp(state, mode) ==
1303 FE_TER_NOCPAMP) {
1304 if (try == 0)
1305 ret_flag = FE_TER_NOCPAMP;
1306
1307 }
1308 }
1309
1310 try++;
1311 } while ((try < 10) && (ret_flag != FE_TER_LOCKOK));
1312
1313 tmp = stv0367_readreg(state, R367TER_SYR_STAT);
1314 tmp2 = stv0367_readreg(state, R367TER_STATUS);
1315 dprintk("state=%p\n", state);
1316 dprintk("LOCK OK! mode=%d SYR_STAT=0x%x R367TER_STATUS=0x%x\n",
1317 mode, tmp, tmp2);
1318
1319 tmp = stv0367_readreg(state, R367TER_PRVIT);
1320 tmp2 = stv0367_readreg(state, R367TER_I2CRPT);
1321 dprintk("PRVIT=0x%x I2CRPT=0x%x\n", tmp, tmp2);
1322
1323 tmp = stv0367_readreg(state, R367TER_GAIN_SRC1);
1324 dprintk("GAIN_SRC1=0x%x\n", tmp);
1325
1326 if ((mode != 0) && (mode != 1) && (mode != 2))
1327 return FE_TER_SWNOK;
1328
1329 /*guard=stv0367_readbits(state,F367TER_SYR_GUARD); */
1330
1331 /*suppress EPQ auto for SYR_GARD 1/16 or 1/32
1332 and set channel predictor in automatic */
1333#if 0
1334 switch (guard) {
1335
1336 case 0:
1337 case 1:
1338 stv0367_writebits(state, F367TER_AUTO_LE_EN, 0);
1339 stv0367_writereg(state, R367TER_CHC_CTL, 0x01);
1340 break;
1341 case 2:
1342 case 3:
1343 stv0367_writebits(state, F367TER_AUTO_LE_EN, 1);
1344 stv0367_writereg(state, R367TER_CHC_CTL, 0x11);
1345 break;
1346
1347 default:
1348 return FE_TER_SWNOK;
1349 }
1350#endif
1351
1352 /*reset fec an reedsolo FOR 367 only*/
1353 stv0367_writebits(state, F367TER_RST_SFEC, 1);
1354 stv0367_writebits(state, F367TER_RST_REEDSOLO, 1);
1355 usleep_range(1000, 2000);
1356 stv0367_writebits(state, F367TER_RST_SFEC, 0);
1357 stv0367_writebits(state, F367TER_RST_REEDSOLO, 0);
1358
1359 u_var1 = stv0367_readbits(state, F367TER_LK);
1360 u_var2 = stv0367_readbits(state, F367TER_PRF);
1361 u_var3 = stv0367_readbits(state, F367TER_TPS_LOCK);
1362 /* u_var4=stv0367_readbits(state,F367TER_TSFIFO_LINEOK); */
1363
1364 wd = stv0367ter_duration(mode, 125, 500, 250);
1365 tempo = stv0367ter_duration(mode, 4, 16, 8);
1366
1367 /*while ( ((!u_var1)||(!u_var2)||(!u_var3)||(!u_var4)) && (wd>=0)) */
1368 while (((!u_var1) || (!u_var2) || (!u_var3)) && (wd >= 0)) {
1369 usleep_range(1000 * tempo, 1000 * (tempo + 1));
1370 wd -= tempo;
1371 u_var1 = stv0367_readbits(state, F367TER_LK);
1372 u_var2 = stv0367_readbits(state, F367TER_PRF);
1373 u_var3 = stv0367_readbits(state, F367TER_TPS_LOCK);
1374 /*u_var4=stv0367_readbits(state, F367TER_TSFIFO_LINEOK); */
1375 }
1376
1377 if (!u_var1)
1378 return FE_TER_NOLOCK;
1379
1380
1381 if (!u_var2)
1382 return FE_TER_NOPRFOUND;
1383
1384 if (!u_var3)
1385 return FE_TER_NOTPS;
1386
1387 guard = stv0367_readbits(state, F367TER_SYR_GUARD);
1388 stv0367_writereg(state, R367TER_CHC_CTL, 0x11);
1389 switch (guard) {
1390 case 0:
1391 case 1:
1392 stv0367_writebits(state, F367TER_AUTO_LE_EN, 0);
1393 /*stv0367_writereg(state,R367TER_CHC_CTL, 0x1);*/
1394 stv0367_writebits(state, F367TER_SYR_FILTER, 0);
1395 break;
1396 case 2:
1397 case 3:
1398 stv0367_writebits(state, F367TER_AUTO_LE_EN, 1);
1399 /*stv0367_writereg(state,R367TER_CHC_CTL, 0x11);*/
1400 stv0367_writebits(state, F367TER_SYR_FILTER, 1);
1401 break;
1402
1403 default:
1404 return FE_TER_SWNOK;
1405 }
1406
1407 /* apply Sfec workaround if 8K 64QAM CR!=1/2*/
1408 if ((stv0367_readbits(state, F367TER_TPS_CONST) == 2) &&
1409 (mode == 1) &&
1410 (stv0367_readbits(state, F367TER_TPS_HPCODE) != 0)) {
1411 stv0367_writereg(state, R367TER_SFDLYSETH, 0xc0);
1412 stv0367_writereg(state, R367TER_SFDLYSETM, 0x60);
1413 stv0367_writereg(state, R367TER_SFDLYSETL, 0x0);
1414 } else
1415 stv0367_writereg(state, R367TER_SFDLYSETH, 0x0);
1416
1417 wd = stv0367ter_duration(mode, 125, 500, 250);
1418 u_var4 = stv0367_readbits(state, F367TER_TSFIFO_LINEOK);
1419
1420 while ((!u_var4) && (wd >= 0)) {
1421 usleep_range(1000 * tempo, 1000 * (tempo + 1));
1422 wd -= tempo;
1423 u_var4 = stv0367_readbits(state, F367TER_TSFIFO_LINEOK);
1424 }
1425
1426 if (!u_var4)
1427 return FE_TER_NOLOCK;
1428
1429 /* for 367 leave COM_N at 0x7 for IQ_mode*/
1430 /*if(ter_state->if_iq_mode!=FE_TER_NORMAL_IF_TUNER) {
1431 tempo=0;
1432 while ((stv0367_readbits(state,F367TER_COM_USEGAINTRK)!=1) &&
1433 (stv0367_readbits(state,F367TER_COM_AGCLOCK)!=1)&&(tempo<100)) {
1434 ChipWaitOrAbort(state,1);
1435 tempo+=1;
1436 }
1437
1438 stv0367_writebits(state,F367TER_COM_N,0x17);
1439 } */
1440
1441 stv0367_writebits(state, F367TER_SYR_TR_DIS, 1);
1442
1443 dprintk("FE_TER_LOCKOK !!!\n");
1444
1445 return FE_TER_LOCKOK;
1446
1447}
1448
1449static void stv0367ter_set_ts_mode(struct stv0367_state *state,
1450 enum stv0367_ts_mode PathTS)
1451{
1452
1453 dprintk("%s:\n", __func__);
1454
1455 if (state == NULL)
1456 return;
1457
1458 stv0367_writebits(state, F367TER_TS_DIS, 0);
1459 switch (PathTS) {
1460 default:
1461 /*for removing warning :default we can assume in parallel mode*/
1462 case STV0367_PARALLEL_PUNCT_CLOCK:
1463 stv0367_writebits(state, F367TER_TSFIFO_SERIAL, 0);
1464 stv0367_writebits(state, F367TER_TSFIFO_DVBCI, 0);
1465 break;
1466 case STV0367_SERIAL_PUNCT_CLOCK:
1467 stv0367_writebits(state, F367TER_TSFIFO_SERIAL, 1);
1468 stv0367_writebits(state, F367TER_TSFIFO_DVBCI, 1);
1469 break;
1470 }
1471}
1472
1473static void stv0367ter_set_clk_pol(struct stv0367_state *state,
1474 enum stv0367_clk_pol clock)
1475{
1476
1477 dprintk("%s:\n", __func__);
1478
1479 if (state == NULL)
1480 return;
1481
1482 switch (clock) {
1483 case STV0367_RISINGEDGE_CLOCK:
1484 stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 1);
1485 break;
1486 case STV0367_FALLINGEDGE_CLOCK:
1487 stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 0);
1488 break;
1489 /*case FE_TER_CLOCK_POLARITY_DEFAULT:*/
1490 default:
1491 stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 0);
1492 break;
1493 }
1494}
1495
1496#if 0
1497static void stv0367ter_core_sw(struct stv0367_state *state)
1498{
1499
1500 dprintk("%s:\n", __func__);
1501
1502 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
1503 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
1504 msleep(350);
1505}
1506#endif
1507static int stv0367ter_standby(struct dvb_frontend *fe, u8 standby_on)
1508{
1509 struct stv0367_state *state = fe->demodulator_priv;
1510
1511 dprintk("%s:\n", __func__);
1512
1513 if (standby_on) {
1514 stv0367_writebits(state, F367TER_STDBY, 1);
1515 stv0367_writebits(state, F367TER_STDBY_FEC, 1);
1516 stv0367_writebits(state, F367TER_STDBY_CORE, 1);
1517 } else {
1518 stv0367_writebits(state, F367TER_STDBY, 0);
1519 stv0367_writebits(state, F367TER_STDBY_FEC, 0);
1520 stv0367_writebits(state, F367TER_STDBY_CORE, 0);
1521 }
1522
1523 return 0;
1524}
1525
1526static int stv0367ter_sleep(struct dvb_frontend *fe)
1527{
1528 return stv0367ter_standby(fe, 1);
1529}
1530
1531int stv0367ter_init(struct dvb_frontend *fe)
1532{
1533 struct stv0367_state *state = fe->demodulator_priv;
1534 struct stv0367ter_state *ter_state = state->ter_state;
1535 int i;
1536
1537 dprintk("%s:\n", __func__);
1538
1539 ter_state->pBER = 0;
1540
1541 for (i = 0; i < STV0367TER_NBREGS; i++)
1542 stv0367_writereg(state, def0367ter[i].addr,
1543 def0367ter[i].value);
1544
1545 switch (state->config->xtal) {
1546 /*set internal freq to 53.125MHz */
1547 case 25000000:
1548 stv0367_writereg(state, R367TER_PLLMDIV, 0xa);
1549 stv0367_writereg(state, R367TER_PLLNDIV, 0x55);
1550 stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
1551 break;
1552 default:
1553 case 27000000:
1554 dprintk("FE_STV0367TER_SetCLKgen for 27Mhz\n");
1555 stv0367_writereg(state, R367TER_PLLMDIV, 0x1);
1556 stv0367_writereg(state, R367TER_PLLNDIV, 0x8);
1557 stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
1558 break;
1559 case 30000000:
1560 stv0367_writereg(state, R367TER_PLLMDIV, 0xc);
1561 stv0367_writereg(state, R367TER_PLLNDIV, 0x55);
1562 stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
1563 break;
1564 }
1565
1566 stv0367_writereg(state, R367TER_I2CRPT, 0xa0);
1567 stv0367_writereg(state, R367TER_ANACTRL, 0x00);
1568
1569 /*Set TS1 and TS2 to serial or parallel mode */
1570 stv0367ter_set_ts_mode(state, state->config->ts_mode);
1571 stv0367ter_set_clk_pol(state, state->config->clk_pol);
1572
1573 state->chip_id = stv0367_readreg(state, R367TER_ID);
1574 ter_state->first_lock = 0;
1575 ter_state->unlock_counter = 2;
1576
1577 return 0;
1578}
1579
1580static int stv0367ter_algo(struct dvb_frontend *fe,
1581 struct dvb_frontend_parameters *param)
1582{
1583 struct stv0367_state *state = fe->demodulator_priv;
1584 struct stv0367ter_state *ter_state = state->ter_state;
1585 int offset = 0, tempo = 0;
1586 u8 u_var;
1587 u8 /*constell,*/ counter, tps_rcvd[2];
1588 s8 step;
1589 s32 timing_offset = 0;
1590 u32 trl_nomrate = 0, InternalFreq = 0, temp = 0;
1591
1592 dprintk("%s:\n", __func__);
1593
1594 ter_state->frequency = param->frequency;
1595 ter_state->force = FE_TER_FORCENONE
1596 + stv0367_readbits(state, F367TER_FORCE) * 2;
1597 ter_state->if_iq_mode = state->config->if_iq_mode;
1598 switch (state->config->if_iq_mode) {
1599 case FE_TER_NORMAL_IF_TUNER: /* Normal IF mode */
1600 dprintk("ALGO: FE_TER_NORMAL_IF_TUNER selected\n");
1601 stv0367_writebits(state, F367TER_TUNER_BB, 0);
1602 stv0367_writebits(state, F367TER_LONGPATH_IF, 0);
1603 stv0367_writebits(state, F367TER_DEMUX_SWAP, 0);
1604 break;
1605 case FE_TER_LONGPATH_IF_TUNER: /* Long IF mode */
1606 dprintk("ALGO: FE_TER_LONGPATH_IF_TUNER selected\n");
1607 stv0367_writebits(state, F367TER_TUNER_BB, 0);
1608 stv0367_writebits(state, F367TER_LONGPATH_IF, 1);
1609 stv0367_writebits(state, F367TER_DEMUX_SWAP, 1);
1610 break;
1611 case FE_TER_IQ_TUNER: /* IQ mode */
1612 dprintk("ALGO: FE_TER_IQ_TUNER selected\n");
1613 stv0367_writebits(state, F367TER_TUNER_BB, 1);
1614 stv0367_writebits(state, F367TER_PPM_INVSEL, 0);
1615 break;
1616 default:
1617 printk(KERN_ERR "ALGO: wrong TUNER type selected\n");
1618 return -EINVAL;
1619 }
1620
1621 usleep_range(5000, 7000);
1622
1623 switch (param->inversion) {
1624 case INVERSION_AUTO:
1625 default:
1626 dprintk("%s: inversion AUTO\n", __func__);
1627 if (ter_state->if_iq_mode == FE_TER_IQ_TUNER)
1628 stv0367_writebits(state, F367TER_IQ_INVERT,
1629 ter_state->sense);
1630 else
1631 stv0367_writebits(state, F367TER_INV_SPECTR,
1632 ter_state->sense);
1633
1634 break;
1635 case INVERSION_ON:
1636 case INVERSION_OFF:
1637 if (ter_state->if_iq_mode == FE_TER_IQ_TUNER)
1638 stv0367_writebits(state, F367TER_IQ_INVERT,
1639 param->inversion);
1640 else
1641 stv0367_writebits(state, F367TER_INV_SPECTR,
1642 param->inversion);
1643
1644 break;
1645 }
1646
1647 if ((ter_state->if_iq_mode != FE_TER_NORMAL_IF_TUNER) &&
1648 (ter_state->pBW != ter_state->bw)) {
1649 stv0367ter_agc_iir_lock_detect_set(state);
1650
1651 /*set fine agc target to 180 for LPIF or IQ mode*/
1652 /* set Q_AGCTarget */
1653 stv0367_writebits(state, F367TER_SEL_IQNTAR, 1);
1654 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_MSB, 0xB);
1655 /*stv0367_writebits(state,AUT_AGC_TARGET_LSB,0x04); */
1656
1657 /* set Q_AGCTarget */
1658 stv0367_writebits(state, F367TER_SEL_IQNTAR, 0);
1659 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_MSB, 0xB);
1660 /*stv0367_writebits(state,AUT_AGC_TARGET_LSB,0x04); */
1661
1662 if (!stv0367_iir_filt_init(state, ter_state->bw,
1663 state->config->xtal))
1664 return -EINVAL;
1665 /*set IIR filter once for 6,7 or 8MHz BW*/
1666 ter_state->pBW = ter_state->bw;
1667
1668 stv0367ter_agc_iir_rst(state);
1669 }
1670
1671 if (ter_state->hierarchy == FE_TER_HIER_LOW_PRIO)
1672 stv0367_writebits(state, F367TER_BDI_LPSEL, 0x01);
1673 else
1674 stv0367_writebits(state, F367TER_BDI_LPSEL, 0x00);
1675
1676 InternalFreq = stv0367ter_get_mclk(state, state->config->xtal) / 1000;
1677 temp = (int)
1678 ((((ter_state->bw * 64 * (1 << 15) * 100)
1679 / (InternalFreq)) * 10) / 7);
1680
1681 stv0367_writebits(state, F367TER_TRL_NOMRATE_LSB, temp % 2);
1682 temp = temp / 2;
1683 stv0367_writebits(state, F367TER_TRL_NOMRATE_HI, temp / 256);
1684 stv0367_writebits(state, F367TER_TRL_NOMRATE_LO, temp % 256);
1685
1686 temp = stv0367_readbits(state, F367TER_TRL_NOMRATE_HI) * 512 +
1687 stv0367_readbits(state, F367TER_TRL_NOMRATE_LO) * 2 +
1688 stv0367_readbits(state, F367TER_TRL_NOMRATE_LSB);
1689 temp = (int)(((1 << 17) * ter_state->bw * 1000) / (7 * (InternalFreq)));
1690 stv0367_writebits(state, F367TER_GAIN_SRC_HI, temp / 256);
1691 stv0367_writebits(state, F367TER_GAIN_SRC_LO, temp % 256);
1692 temp = stv0367_readbits(state, F367TER_GAIN_SRC_HI) * 256 +
1693 stv0367_readbits(state, F367TER_GAIN_SRC_LO);
1694
1695 temp = (int)
1696 ((InternalFreq - state->config->if_khz) * (1 << 16)
1697 / (InternalFreq));
1698
1699 dprintk("DEROT temp=0x%x\n", temp);
1700 stv0367_writebits(state, F367TER_INC_DEROT_HI, temp / 256);
1701 stv0367_writebits(state, F367TER_INC_DEROT_LO, temp % 256);
1702
1703 ter_state->echo_pos = 0;
1704 ter_state->ucblocks = 0; /* liplianin */
1705 ter_state->pBER = 0; /* liplianin */
1706 stv0367_writebits(state, F367TER_LONG_ECHO, ter_state->echo_pos);
1707
1708 if (stv0367ter_lock_algo(state) != FE_TER_LOCKOK)
1709 return 0;
1710
1711 ter_state->state = FE_TER_LOCKOK;
1712 /* update results */
1713 tps_rcvd[0] = stv0367_readreg(state, R367TER_TPS_RCVD2);
1714 tps_rcvd[1] = stv0367_readreg(state, R367TER_TPS_RCVD3);
1715
1716 ter_state->mode = stv0367_readbits(state, F367TER_SYR_MODE);
1717 ter_state->guard = stv0367_readbits(state, F367TER_SYR_GUARD);
1718
1719 ter_state->first_lock = 1; /* we know sense now :) */
1720
1721 ter_state->agc_val =
1722 (stv0367_readbits(state, F367TER_AGC1_VAL_LO) << 16) +
1723 (stv0367_readbits(state, F367TER_AGC1_VAL_HI) << 24) +
1724 stv0367_readbits(state, F367TER_AGC2_VAL_LO) +
1725 (stv0367_readbits(state, F367TER_AGC2_VAL_HI) << 8);
1726
1727 /* Carrier offset calculation */
1728 stv0367_writebits(state, F367TER_FREEZE, 1);
1729 offset = (stv0367_readbits(state, F367TER_CRL_FOFFSET_VHI) << 16) ;
1730 offset += (stv0367_readbits(state, F367TER_CRL_FOFFSET_HI) << 8);
1731 offset += (stv0367_readbits(state, F367TER_CRL_FOFFSET_LO));
1732 stv0367_writebits(state, F367TER_FREEZE, 0);
1733 if (offset > 8388607)
1734 offset -= 16777216;
1735
1736 offset = offset * 2 / 16384;
1737
1738 if (ter_state->mode == FE_TER_MODE_2K)
1739 offset = (offset * 4464) / 1000;/*** 1 FFT BIN=4.464khz***/
1740 else if (ter_state->mode == FE_TER_MODE_4K)
1741 offset = (offset * 223) / 100;/*** 1 FFT BIN=2.23khz***/
1742 else if (ter_state->mode == FE_TER_MODE_8K)
1743 offset = (offset * 111) / 100;/*** 1 FFT BIN=1.1khz***/
1744
1745 if (stv0367_readbits(state, F367TER_PPM_INVSEL) == 1) {
1746 if ((stv0367_readbits(state, F367TER_INV_SPECTR) ==
1747 (stv0367_readbits(state,
1748 F367TER_STATUS_INV_SPECRUM) == 1)))
1749 offset = offset * -1;
1750 }
1751
1752 if (ter_state->bw == 6)
1753 offset = (offset * 6) / 8;
1754 else if (ter_state->bw == 7)
1755 offset = (offset * 7) / 8;
1756
1757 ter_state->frequency += offset;
1758
1759 tempo = 10; /* exit even if timing_offset stays null */
1760 while ((timing_offset == 0) && (tempo > 0)) {
1761 usleep_range(10000, 20000); /*was 20ms */
1762 /* fine tuning of timing offset if required */
1763 timing_offset = stv0367_readbits(state, F367TER_TRL_TOFFSET_LO)
1764 + 256 * stv0367_readbits(state,
1765 F367TER_TRL_TOFFSET_HI);
1766 if (timing_offset >= 32768)
1767 timing_offset -= 65536;
1768 trl_nomrate = (512 * stv0367_readbits(state,
1769 F367TER_TRL_NOMRATE_HI)
1770 + stv0367_readbits(state, F367TER_TRL_NOMRATE_LO) * 2
1771 + stv0367_readbits(state, F367TER_TRL_NOMRATE_LSB));
1772
1773 timing_offset = ((signed)(1000000 / trl_nomrate) *
1774 timing_offset) / 2048;
1775 tempo--;
1776 }
1777
1778 if (timing_offset <= 0) {
1779 timing_offset = (timing_offset - 11) / 22;
1780 step = -1;
1781 } else {
1782 timing_offset = (timing_offset + 11) / 22;
1783 step = 1;
1784 }
1785
1786 for (counter = 0; counter < abs(timing_offset); counter++) {
1787 trl_nomrate += step;
1788 stv0367_writebits(state, F367TER_TRL_NOMRATE_LSB,
1789 trl_nomrate % 2);
1790 stv0367_writebits(state, F367TER_TRL_NOMRATE_LO,
1791 trl_nomrate / 2);
1792 usleep_range(1000, 2000);
1793 }
1794
1795 usleep_range(5000, 6000);
1796 /* unlocks could happen in case of trl centring big step,
1797 then a core off/on restarts demod */
1798 u_var = stv0367_readbits(state, F367TER_LK);
1799
1800 if (!u_var) {
1801 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
1802 msleep(20);
1803 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
1804 }
1805
1806 return 0;
1807}
1808
1809static int stv0367ter_set_frontend(struct dvb_frontend *fe,
1810 struct dvb_frontend_parameters *param)
1811{
1812 struct dvb_ofdm_parameters *op = &param->u.ofdm;
1813 struct stv0367_state *state = fe->demodulator_priv;
1814 struct stv0367ter_state *ter_state = state->ter_state;
1815
1816 /*u8 trials[2]; */
1817 s8 num_trials, index;
1818 u8 SenseTrials[] = { INVERSION_ON, INVERSION_OFF };
1819
1820 stv0367ter_init(fe);
1821
1822 if (fe->ops.tuner_ops.set_params) {
1823 if (fe->ops.i2c_gate_ctrl)
1824 fe->ops.i2c_gate_ctrl(fe, 1);
1825 fe->ops.tuner_ops.set_params(fe, param);
1826 if (fe->ops.i2c_gate_ctrl)
1827 fe->ops.i2c_gate_ctrl(fe, 0);
1828 }
1829
1830 switch (op->transmission_mode) {
1831 default:
1832 case TRANSMISSION_MODE_AUTO:
1833 case TRANSMISSION_MODE_2K:
1834 ter_state->mode = FE_TER_MODE_2K;
1835 break;
1836/* case TRANSMISSION_MODE_4K:
1837 pLook.mode = FE_TER_MODE_4K;
1838 break;*/
1839 case TRANSMISSION_MODE_8K:
1840 ter_state->mode = FE_TER_MODE_8K;
1841 break;
1842 }
1843
1844 switch (op->guard_interval) {
1845 default:
1846 case GUARD_INTERVAL_1_32:
1847 case GUARD_INTERVAL_1_16:
1848 case GUARD_INTERVAL_1_8:
1849 case GUARD_INTERVAL_1_4:
1850 ter_state->guard = op->guard_interval;
1851 break;
1852 case GUARD_INTERVAL_AUTO:
1853 ter_state->guard = GUARD_INTERVAL_1_32;
1854 break;
1855 }
1856
1857 switch (op->bandwidth) {
1858 case BANDWIDTH_6_MHZ:
1859 ter_state->bw = FE_TER_CHAN_BW_6M;
1860 break;
1861 case BANDWIDTH_7_MHZ:
1862 ter_state->bw = FE_TER_CHAN_BW_7M;
1863 break;
1864 case BANDWIDTH_8_MHZ:
1865 default:
1866 ter_state->bw = FE_TER_CHAN_BW_8M;
1867 }
1868
1869 ter_state->hierarchy = FE_TER_HIER_NONE;
1870
1871 switch (param->inversion) {
1872 case INVERSION_OFF:
1873 case INVERSION_ON:
1874 num_trials = 1;
1875 break;
1876 default:
1877 num_trials = 2;
1878 if (ter_state->first_lock)
1879 num_trials = 1;
1880 break;
1881 }
1882
1883 ter_state->state = FE_TER_NOLOCK;
1884 index = 0;
1885
1886 while (((index) < num_trials) && (ter_state->state != FE_TER_LOCKOK)) {
1887 if (!ter_state->first_lock) {
1888 if (param->inversion == INVERSION_AUTO)
1889 ter_state->sense = SenseTrials[index];
1890
1891 }
1892 stv0367ter_algo(fe,/* &pLook, result,*/ param);
1893
1894 if ((ter_state->state == FE_TER_LOCKOK) &&
1895 (param->inversion == INVERSION_AUTO) &&
1896 (index == 1)) {
1897 /* invert spectrum sense */
1898 SenseTrials[index] = SenseTrials[0];
1899 SenseTrials[(index + 1) % 2] = (SenseTrials[1] + 1) % 2;
1900 }
1901
1902 index++;
1903 }
1904
1905 return 0;
1906}
1907
1908static int stv0367ter_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
1909{
1910 struct stv0367_state *state = fe->demodulator_priv;
1911 struct stv0367ter_state *ter_state = state->ter_state;
1912 u32 errs = 0;
1913
1914 /*wait for counting completion*/
1915 if (stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 0) {
1916 errs =
1917 ((u32)stv0367_readbits(state, F367TER_ERR_CNT1)
1918 * (1 << 16))
1919 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_HI)
1920 * (1 << 8))
1921 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_LO));
1922 ter_state->ucblocks = errs;
1923 }
1924
1925 (*ucblocks) = ter_state->ucblocks;
1926
1927 return 0;
1928}
1929
1930static int stv0367ter_get_frontend(struct dvb_frontend *fe,
1931 struct dvb_frontend_parameters *param)
1932{
1933 struct stv0367_state *state = fe->demodulator_priv;
1934 struct stv0367ter_state *ter_state = state->ter_state;
1935 struct dvb_ofdm_parameters *op = &param->u.ofdm;
1936 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1937
1938 int error = 0;
1939 enum stv0367_ter_mode mode;
1940 int constell = 0,/* snr = 0,*/ Data = 0;
1941
1942 param->frequency = stv0367_get_tuner_freq(fe);
1943 if ((int)param->frequency < 0)
1944 param->frequency = c->frequency;
1945
1946 constell = stv0367_readbits(state, F367TER_TPS_CONST);
1947 if (constell == 0)
1948 op->constellation = QPSK;
1949 else if (constell == 1)
1950 op->constellation = QAM_16;
1951 else
1952 op->constellation = QAM_64;
1953
1954 param->inversion = stv0367_readbits(state, F367TER_INV_SPECTR);
1955
1956 /* Get the Hierarchical mode */
1957 Data = stv0367_readbits(state, F367TER_TPS_HIERMODE);
1958
1959 switch (Data) {
1960 case 0:
1961 op->hierarchy_information = HIERARCHY_NONE;
1962 break;
1963 case 1:
1964 op->hierarchy_information = HIERARCHY_1;
1965 break;
1966 case 2:
1967 op->hierarchy_information = HIERARCHY_2;
1968 break;
1969 case 3:
1970 op->hierarchy_information = HIERARCHY_4;
1971 break;
1972 default:
1973 op->hierarchy_information = HIERARCHY_AUTO;
1974 break; /* error */
1975 }
1976
1977 /* Get the FEC Rate */
1978 if (ter_state->hierarchy == FE_TER_HIER_LOW_PRIO)
1979 Data = stv0367_readbits(state, F367TER_TPS_LPCODE);
1980 else
1981 Data = stv0367_readbits(state, F367TER_TPS_HPCODE);
1982
1983 switch (Data) {
1984 case 0:
1985 op->code_rate_HP = FEC_1_2;
1986 break;
1987 case 1:
1988 op->code_rate_HP = FEC_2_3;
1989 break;
1990 case 2:
1991 op->code_rate_HP = FEC_3_4;
1992 break;
1993 case 3:
1994 op->code_rate_HP = FEC_5_6;
1995 break;
1996 case 4:
1997 op->code_rate_HP = FEC_7_8;
1998 break;
1999 default:
2000 op->code_rate_HP = FEC_AUTO;
2001 break; /* error */
2002 }
2003
2004 mode = stv0367_readbits(state, F367TER_SYR_MODE);
2005
2006 switch (mode) {
2007 case FE_TER_MODE_2K:
2008 op->transmission_mode = TRANSMISSION_MODE_2K;
2009 break;
2010/* case FE_TER_MODE_4K:
2011 op->transmission_mode = TRANSMISSION_MODE_4K;
2012 break;*/
2013 case FE_TER_MODE_8K:
2014 op->transmission_mode = TRANSMISSION_MODE_8K;
2015 break;
2016 default:
2017 op->transmission_mode = TRANSMISSION_MODE_AUTO;
2018 }
2019
2020 op->guard_interval = stv0367_readbits(state, F367TER_SYR_GUARD);
2021
2022 return error;
2023}
2024
2025static int stv0367ter_read_snr(struct dvb_frontend *fe, u16 *snr)
2026{
2027 struct stv0367_state *state = fe->demodulator_priv;
2028 u32 snru32 = 0;
2029 int cpt = 0;
2030 u8 cut = stv0367_readbits(state, F367TER_IDENTIFICATIONREG);
2031
2032 while (cpt < 10) {
2033 usleep_range(2000, 3000);
2034 if (cut == 0x50) /*cut 1.0 cut 1.1*/
2035 snru32 += stv0367_readbits(state, F367TER_CHCSNR) / 4;
2036 else /*cu2.0*/
2037 snru32 += 125 * stv0367_readbits(state, F367TER_CHCSNR);
2038
2039 cpt++;
2040 }
2041
2042 snru32 /= 10;/*average on 10 values*/
2043
2044 *snr = snru32 / 1000;
2045
2046 return 0;
2047}
2048
2049#if 0
2050static int stv0367ter_status(struct dvb_frontend *fe)
2051{
2052
2053 struct stv0367_state *state = fe->demodulator_priv;
2054 struct stv0367ter_state *ter_state = state->ter_state;
2055 int locked = FALSE;
2056
2057 locked = (stv0367_readbits(state, F367TER_LK));
2058 if (!locked)
2059 ter_state->unlock_counter += 1;
2060 else
2061 ter_state->unlock_counter = 0;
2062
2063 if (ter_state->unlock_counter > 2) {
2064 if (!stv0367_readbits(state, F367TER_TPS_LOCK) ||
2065 (!stv0367_readbits(state, F367TER_LK))) {
2066 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
2067 usleep_range(2000, 3000);
2068 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
2069 msleep(350);
2070 locked = (stv0367_readbits(state, F367TER_TPS_LOCK)) &&
2071 (stv0367_readbits(state, F367TER_LK));
2072 }
2073
2074 }
2075
2076 return locked;
2077}
2078#endif
2079static int stv0367ter_read_status(struct dvb_frontend *fe, fe_status_t *status)
2080{
2081 struct stv0367_state *state = fe->demodulator_priv;
2082
2083 dprintk("%s:\n", __func__);
2084
2085 *status = 0;
2086
2087 if (stv0367_readbits(state, F367TER_LK)) {
2088 *status |= FE_HAS_LOCK;
2089 dprintk("%s: stv0367 has locked\n", __func__);
2090 }
2091
2092 return 0;
2093}
2094
2095static int stv0367ter_read_ber(struct dvb_frontend *fe, u32 *ber)
2096{
2097 struct stv0367_state *state = fe->demodulator_priv;
2098 struct stv0367ter_state *ter_state = state->ter_state;
2099 u32 Errors = 0, tber = 0, temporary = 0;
2100 int abc = 0, def = 0;
2101
2102
2103 /*wait for counting completion*/
2104 if (stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 0)
2105 Errors = ((u32)stv0367_readbits(state, F367TER_SFEC_ERR_CNT)
2106 * (1 << 16))
2107 + ((u32)stv0367_readbits(state, F367TER_SFEC_ERR_CNT_HI)
2108 * (1 << 8))
2109 + ((u32)stv0367_readbits(state,
2110 F367TER_SFEC_ERR_CNT_LO));
2111 /*measurement not completed, load previous value*/
2112 else {
2113 tber = ter_state->pBER;
2114 return 0;
2115 }
2116
2117 abc = stv0367_readbits(state, F367TER_SFEC_ERR_SOURCE);
2118 def = stv0367_readbits(state, F367TER_SFEC_NUM_EVENT);
2119
2120 if (Errors == 0) {
2121 tber = 0;
2122 } else if (abc == 0x7) {
2123 if (Errors <= 4) {
2124 temporary = (Errors * 1000000000) / (8 * (1 << 14));
2125 temporary = temporary;
2126 } else if (Errors <= 42) {
2127 temporary = (Errors * 100000000) / (8 * (1 << 14));
2128 temporary = temporary * 10;
2129 } else if (Errors <= 429) {
2130 temporary = (Errors * 10000000) / (8 * (1 << 14));
2131 temporary = temporary * 100;
2132 } else if (Errors <= 4294) {
2133 temporary = (Errors * 1000000) / (8 * (1 << 14));
2134 temporary = temporary * 1000;
2135 } else if (Errors <= 42949) {
2136 temporary = (Errors * 100000) / (8 * (1 << 14));
2137 temporary = temporary * 10000;
2138 } else if (Errors <= 429496) {
2139 temporary = (Errors * 10000) / (8 * (1 << 14));
2140 temporary = temporary * 100000;
2141 } else { /*if (Errors<4294967) 2^22 max error*/
2142 temporary = (Errors * 1000) / (8 * (1 << 14));
2143 temporary = temporary * 100000; /* still to *10 */
2144 }
2145
2146 /* Byte error*/
2147 if (def == 2)
2148 /*tber=Errors/(8*(1 <<14));*/
2149 tber = temporary;
2150 else if (def == 3)
2151 /*tber=Errors/(8*(1 <<16));*/
2152 tber = temporary / 4;
2153 else if (def == 4)
2154 /*tber=Errors/(8*(1 <<18));*/
2155 tber = temporary / 16;
2156 else if (def == 5)
2157 /*tber=Errors/(8*(1 <<20));*/
2158 tber = temporary / 64;
2159 else if (def == 6)
2160 /*tber=Errors/(8*(1 <<22));*/
2161 tber = temporary / 256;
2162 else
2163 /* should not pass here*/
2164 tber = 0;
2165
2166 if ((Errors < 4294967) && (Errors > 429496))
2167 tber *= 10;
2168
2169 }
2170
2171 /* save actual value */
2172 ter_state->pBER = tber;
2173
2174 (*ber) = tber;
2175
2176 return 0;
2177}
2178#if 0
2179static u32 stv0367ter_get_per(struct stv0367_state *state)
2180{
2181 struct stv0367ter_state *ter_state = state->ter_state;
2182 u32 Errors = 0, Per = 0, temporary = 0;
2183 int abc = 0, def = 0, cpt = 0;
2184
2185 while (((stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 1) &&
2186 (cpt < 400)) || ((Errors == 0) && (cpt < 400))) {
2187 usleep_range(1000, 2000);
2188 Errors = ((u32)stv0367_readbits(state, F367TER_ERR_CNT1)
2189 * (1 << 16))
2190 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_HI)
2191 * (1 << 8))
2192 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_LO));
2193 cpt++;
2194 }
2195 abc = stv0367_readbits(state, F367TER_ERR_SRC1);
2196 def = stv0367_readbits(state, F367TER_NUM_EVT1);
2197
2198 if (Errors == 0)
2199 Per = 0;
2200 else if (abc == 0x9) {
2201 if (Errors <= 4) {
2202 temporary = (Errors * 1000000000) / (8 * (1 << 8));
2203 temporary = temporary;
2204 } else if (Errors <= 42) {
2205 temporary = (Errors * 100000000) / (8 * (1 << 8));
2206 temporary = temporary * 10;
2207 } else if (Errors <= 429) {
2208 temporary = (Errors * 10000000) / (8 * (1 << 8));
2209 temporary = temporary * 100;
2210 } else if (Errors <= 4294) {
2211 temporary = (Errors * 1000000) / (8 * (1 << 8));
2212 temporary = temporary * 1000;
2213 } else if (Errors <= 42949) {
2214 temporary = (Errors * 100000) / (8 * (1 << 8));
2215 temporary = temporary * 10000;
2216 } else { /*if(Errors<=429496) 2^16 errors max*/
2217 temporary = (Errors * 10000) / (8 * (1 << 8));
2218 temporary = temporary * 100000;
2219 }
2220
2221 /* pkt error*/
2222 if (def == 2)
2223 /*Per=Errors/(1 << 8);*/
2224 Per = temporary;
2225 else if (def == 3)
2226 /*Per=Errors/(1 << 10);*/
2227 Per = temporary / 4;
2228 else if (def == 4)
2229 /*Per=Errors/(1 << 12);*/
2230 Per = temporary / 16;
2231 else if (def == 5)
2232 /*Per=Errors/(1 << 14);*/
2233 Per = temporary / 64;
2234 else if (def == 6)
2235 /*Per=Errors/(1 << 16);*/
2236 Per = temporary / 256;
2237 else
2238 Per = 0;
2239
2240 }
2241 /* save actual value */
2242 ter_state->pPER = Per;
2243
2244 return Per;
2245}
2246#endif
2247static int stv0367_get_tune_settings(struct dvb_frontend *fe,
2248 struct dvb_frontend_tune_settings
2249 *fe_tune_settings)
2250{
2251 fe_tune_settings->min_delay_ms = 1000;
2252 fe_tune_settings->step_size = 0;
2253 fe_tune_settings->max_drift = 0;
2254
2255 return 0;
2256}
2257
2258static void stv0367_release(struct dvb_frontend *fe)
2259{
2260 struct stv0367_state *state = fe->demodulator_priv;
2261
2262 kfree(state->ter_state);
2263 kfree(state->cab_state);
2264 kfree(state);
2265}
2266
2267static struct dvb_frontend_ops stv0367ter_ops = {
2268 .info = {
2269 .name = "ST STV0367 DVB-T",
2270 .type = FE_OFDM,
2271 .frequency_min = 47000000,
2272 .frequency_max = 862000000,
2273 .frequency_stepsize = 15625,
2274 .frequency_tolerance = 0,
2275 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
2276 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
2277 FE_CAN_FEC_AUTO |
2278 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
2279 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
2280 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
2281 FE_CAN_INVERSION_AUTO |
2282 FE_CAN_MUTE_TS
2283 },
2284 .release = stv0367_release,
2285 .init = stv0367ter_init,
2286 .sleep = stv0367ter_sleep,
2287 .i2c_gate_ctrl = stv0367ter_gate_ctrl,
2288 .set_frontend = stv0367ter_set_frontend,
2289 .get_frontend = stv0367ter_get_frontend,
2290 .get_tune_settings = stv0367_get_tune_settings,
2291 .read_status = stv0367ter_read_status,
2292 .read_ber = stv0367ter_read_ber,/* too slow */
2293/* .read_signal_strength = stv0367_read_signal_strength,*/
2294 .read_snr = stv0367ter_read_snr,
2295 .read_ucblocks = stv0367ter_read_ucblocks,
2296};
2297
2298struct dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
2299 struct i2c_adapter *i2c)
2300{
2301 struct stv0367_state *state = NULL;
2302 struct stv0367ter_state *ter_state = NULL;
2303
2304 /* allocate memory for the internal state */
2305 state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL);
2306 if (state == NULL)
2307 goto error;
2308 ter_state = kzalloc(sizeof(struct stv0367ter_state), GFP_KERNEL);
2309 if (ter_state == NULL)
2310 goto error;
2311
2312 /* setup the state */
2313 state->i2c = i2c;
2314 state->config = config;
2315 state->ter_state = ter_state;
2316 state->fe.ops = stv0367ter_ops;
2317 state->fe.demodulator_priv = state;
2318 state->chip_id = stv0367_readreg(state, 0xf000);
2319
2320 dprintk("%s: chip_id = 0x%x\n", __func__, state->chip_id);
2321
2322 /* check if the demod is there */
2323 if ((state->chip_id != 0x50) && (state->chip_id != 0x60))
2324 goto error;
2325
2326 return &state->fe;
2327
2328error:
2329 kfree(ter_state);
2330 kfree(state);
2331 return NULL;
2332}
2333EXPORT_SYMBOL(stv0367ter_attach);
2334
2335static int stv0367cab_gate_ctrl(struct dvb_frontend *fe, int enable)
2336{
2337 struct stv0367_state *state = fe->demodulator_priv;
2338
2339 dprintk("%s:\n", __func__);
2340
2341 stv0367_writebits(state, F367CAB_I2CT_ON, (enable > 0) ? 1 : 0);
2342
2343 return 0;
2344}
2345
2346static u32 stv0367cab_get_mclk(struct dvb_frontend *fe, u32 ExtClk_Hz)
2347{
2348 struct stv0367_state *state = fe->demodulator_priv;
2349 u32 mclk_Hz = 0;/* master clock frequency (Hz) */
2350 u32 M, N, P;
2351
2352
2353 if (stv0367_readbits(state, F367CAB_BYPASS_PLLXN) == 0) {
2354 N = (u32)stv0367_readbits(state, F367CAB_PLL_NDIV);
2355 if (N == 0)
2356 N = N + 1;
2357
2358 M = (u32)stv0367_readbits(state, F367CAB_PLL_MDIV);
2359 if (M == 0)
2360 M = M + 1;
2361
2362 P = (u32)stv0367_readbits(state, F367CAB_PLL_PDIV);
2363
2364 if (P > 5)
2365 P = 5;
2366
2367 mclk_Hz = ((ExtClk_Hz / 2) * N) / (M * (1 << P));
2368 dprintk("stv0367cab_get_mclk BYPASS_PLLXN mclk_Hz=%d\n",
2369 mclk_Hz);
2370 } else
2371 mclk_Hz = ExtClk_Hz;
2372
2373 dprintk("stv0367cab_get_mclk final mclk_Hz=%d\n", mclk_Hz);
2374
2375 return mclk_Hz;
2376}
2377
2378static u32 stv0367cab_get_adc_freq(struct dvb_frontend *fe, u32 ExtClk_Hz)
2379{
2380 u32 ADCClk_Hz = ExtClk_Hz;
2381
2382 ADCClk_Hz = stv0367cab_get_mclk(fe, ExtClk_Hz);
2383
2384 return ADCClk_Hz;
2385}
2386
2387enum stv0367cab_mod stv0367cab_SetQamSize(struct stv0367_state *state,
2388 u32 SymbolRate,
2389 enum stv0367cab_mod QAMSize)
2390{
2391 /* Set QAM size */
2392 stv0367_writebits(state, F367CAB_QAM_MODE, QAMSize);
2393
2394 /* Set Registers settings specific to the QAM size */
2395 switch (QAMSize) {
2396 case FE_CAB_MOD_QAM4:
2397 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2398 break;
2399 case FE_CAB_MOD_QAM16:
2400 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x64);
2401 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2402 stv0367_writereg(state, R367CAB_FSM_STATE, 0x90);
2403 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2404 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2405 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x95);
2406 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
2407 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0x8a);
2408 break;
2409 case FE_CAB_MOD_QAM32:
2410 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2411 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x6e);
2412 stv0367_writereg(state, R367CAB_FSM_STATE, 0xb0);
2413 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2414 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xb7);
2415 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x9d);
2416 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x7f);
2417 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
2418 break;
2419 case FE_CAB_MOD_QAM64:
2420 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x82);
2421 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x5a);
2422 if (SymbolRate > 45000000) {
2423 stv0367_writereg(state, R367CAB_FSM_STATE, 0xb0);
2424 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2425 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa5);
2426 } else if (SymbolRate > 25000000) {
2427 stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
2428 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2429 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa6);
2430 } else {
2431 stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
2432 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xd1);
2433 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2434 }
2435 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x95);
2436 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
2437 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0x99);
2438 break;
2439 case FE_CAB_MOD_QAM128:
2440 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2441 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x76);
2442 stv0367_writereg(state, R367CAB_FSM_STATE, 0x90);
2443 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xb1);
2444 if (SymbolRate > 45000000)
2445 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2446 else if (SymbolRate > 25000000)
2447 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa6);
2448 else
2449 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0x97);
2450
2451 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x8e);
2452 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x7f);
2453 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
2454 break;
2455 case FE_CAB_MOD_QAM256:
2456 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x94);
2457 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x5a);
2458 stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
2459 if (SymbolRate > 45000000)
2460 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2461 else if (SymbolRate > 25000000)
2462 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2463 else
2464 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xd1);
2465
2466 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2467 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x85);
2468 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
2469 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
2470 break;
2471 case FE_CAB_MOD_QAM512:
2472 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2473 break;
2474 case FE_CAB_MOD_QAM1024:
2475 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2476 break;
2477 default:
2478 break;
2479 }
2480
2481 return QAMSize;
2482}
2483
2484static u32 stv0367cab_set_derot_freq(struct stv0367_state *state,
2485 u32 adc_hz, s32 derot_hz)
2486{
2487 u32 sampled_if = 0;
2488 u32 adc_khz;
2489
2490 adc_khz = adc_hz / 1000;
2491
2492 dprintk("%s: adc_hz=%d derot_hz=%d\n", __func__, adc_hz, derot_hz);
2493
2494 if (adc_khz != 0) {
2495 if (derot_hz < 1000000)
2496 derot_hz = adc_hz / 4; /* ZIF operation */
2497 if (derot_hz > adc_hz)
2498 derot_hz = derot_hz - adc_hz;
2499 sampled_if = (u32)derot_hz / 1000;
2500 sampled_if *= 32768;
2501 sampled_if /= adc_khz;
2502 sampled_if *= 256;
2503 }
2504
2505 if (sampled_if > 8388607)
2506 sampled_if = 8388607;
2507
2508 dprintk("%s: sampled_if=0x%x\n", __func__, sampled_if);
2509
2510 stv0367_writereg(state, R367CAB_MIX_NCO_LL, sampled_if);
2511 stv0367_writereg(state, R367CAB_MIX_NCO_HL, (sampled_if >> 8));
2512 stv0367_writebits(state, F367CAB_MIX_NCO_INC_HH, (sampled_if >> 16));
2513
2514 return derot_hz;
2515}
2516
2517static u32 stv0367cab_get_derot_freq(struct stv0367_state *state, u32 adc_hz)
2518{
2519 u32 sampled_if;
2520
2521 sampled_if = stv0367_readbits(state, F367CAB_MIX_NCO_INC_LL) +
2522 (stv0367_readbits(state, F367CAB_MIX_NCO_INC_HL) << 8) +
2523 (stv0367_readbits(state, F367CAB_MIX_NCO_INC_HH) << 16);
2524
2525 sampled_if /= 256;
2526 sampled_if *= (adc_hz / 1000);
2527 sampled_if += 1;
2528 sampled_if /= 32768;
2529
2530 return sampled_if;
2531}
2532
2533static u32 stv0367cab_set_srate(struct stv0367_state *state, u32 adc_hz,
2534 u32 mclk_hz, u32 SymbolRate,
2535 enum stv0367cab_mod QAMSize)
2536{
2537 u32 QamSizeCorr = 0;
2538 u32 u32_tmp = 0, u32_tmp1 = 0;
2539 u32 adp_khz;
2540
2541 dprintk("%s:\n", __func__);
2542
2543 /* Set Correction factor of SRC gain */
2544 switch (QAMSize) {
2545 case FE_CAB_MOD_QAM4:
2546 QamSizeCorr = 1110;
2547 break;
2548 case FE_CAB_MOD_QAM16:
2549 QamSizeCorr = 1032;
2550 break;
2551 case FE_CAB_MOD_QAM32:
2552 QamSizeCorr = 954;
2553 break;
2554 case FE_CAB_MOD_QAM64:
2555 QamSizeCorr = 983;
2556 break;
2557 case FE_CAB_MOD_QAM128:
2558 QamSizeCorr = 957;
2559 break;
2560 case FE_CAB_MOD_QAM256:
2561 QamSizeCorr = 948;
2562 break;
2563 case FE_CAB_MOD_QAM512:
2564 QamSizeCorr = 0;
2565 break;
2566 case FE_CAB_MOD_QAM1024:
2567 QamSizeCorr = 944;
2568 break;
2569 default:
2570 break;
2571 }
2572
2573 /* Transfer ratio calculation */
2574 if (adc_hz != 0) {
2575 u32_tmp = 256 * SymbolRate;
2576 u32_tmp = u32_tmp / adc_hz;
2577 }
2578 stv0367_writereg(state, R367CAB_EQU_CRL_TFR, (u8)u32_tmp);
2579
2580 /* Symbol rate and SRC gain calculation */
2581 adp_khz = (mclk_hz >> 1) / 1000;/* TRL works at half the system clock */
2582 if (adp_khz != 0) {
2583 u32_tmp = SymbolRate;
2584 u32_tmp1 = SymbolRate;
2585
2586 if (u32_tmp < 2097152) { /* 2097152 = 2^21 */
2587 /* Symbol rate calculation */
2588 u32_tmp *= 2048; /* 2048 = 2^11 */
2589 u32_tmp = u32_tmp / adp_khz;
2590 u32_tmp = u32_tmp * 16384; /* 16384 = 2^14 */
2591 u32_tmp /= 125 ; /* 125 = 1000/2^3 */
2592 u32_tmp = u32_tmp * 8; /* 8 = 2^3 */
2593
2594 /* SRC Gain Calculation */
2595 u32_tmp1 *= 2048; /* *2*2^10 */
2596 u32_tmp1 /= 439; /* *2/878 */
2597 u32_tmp1 *= 256; /* *2^8 */
2598 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
2599 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2600 u32_tmp1 = u32_tmp1 / 10000000;
2601
2602 } else if (u32_tmp < 4194304) { /* 4194304 = 2**22 */
2603 /* Symbol rate calculation */
2604 u32_tmp *= 1024 ; /* 1024 = 2**10 */
2605 u32_tmp = u32_tmp / adp_khz;
2606 u32_tmp = u32_tmp * 16384; /* 16384 = 2**14 */
2607 u32_tmp /= 125 ; /* 125 = 1000/2**3 */
2608 u32_tmp = u32_tmp * 16; /* 16 = 2**4 */
2609
2610 /* SRC Gain Calculation */
2611 u32_tmp1 *= 1024; /* *2*2^9 */
2612 u32_tmp1 /= 439; /* *2/878 */
2613 u32_tmp1 *= 256; /* *2^8 */
2614 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz)*/
2615 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2616 u32_tmp1 = u32_tmp1 / 5000000;
2617 } else if (u32_tmp < 8388607) { /* 8388607 = 2**23 */
2618 /* Symbol rate calculation */
2619 u32_tmp *= 512 ; /* 512 = 2**9 */
2620 u32_tmp = u32_tmp / adp_khz;
2621 u32_tmp = u32_tmp * 16384; /* 16384 = 2**14 */
2622 u32_tmp /= 125 ; /* 125 = 1000/2**3 */
2623 u32_tmp = u32_tmp * 32; /* 32 = 2**5 */
2624
2625 /* SRC Gain Calculation */
2626 u32_tmp1 *= 512; /* *2*2^8 */
2627 u32_tmp1 /= 439; /* *2/878 */
2628 u32_tmp1 *= 256; /* *2^8 */
2629 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
2630 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2631 u32_tmp1 = u32_tmp1 / 2500000;
2632 } else {
2633 /* Symbol rate calculation */
2634 u32_tmp *= 256 ; /* 256 = 2**8 */
2635 u32_tmp = u32_tmp / adp_khz;
2636 u32_tmp = u32_tmp * 16384; /* 16384 = 2**13 */
2637 u32_tmp /= 125 ; /* 125 = 1000/2**3 */
2638 u32_tmp = u32_tmp * 64; /* 64 = 2**6 */
2639
2640 /* SRC Gain Calculation */
2641 u32_tmp1 *= 256; /* 2*2^7 */
2642 u32_tmp1 /= 439; /* *2/878 */
2643 u32_tmp1 *= 256; /* *2^8 */
2644 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
2645 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2646 u32_tmp1 = u32_tmp1 / 1250000;
2647 }
2648 }
2649#if 0
2650 /* Filters' coefficients are calculated and written
2651 into registers only if the filters are enabled */
2652 if (stv0367_readbits(state, F367CAB_ADJ_EN)) {
2653 stv0367cab_SetIirAdjacentcoefficient(state, mclk_hz,
2654 SymbolRate);
2655 /* AllPass filter must be enabled
2656 when the adjacents filter is used */
2657 stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 1);
2658 stv0367cab_SetAllPasscoefficient(state, mclk_hz, SymbolRate);
2659 } else
2660 /* AllPass filter must be disabled
2661 when the adjacents filter is not used */
2662#endif
2663 stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 0);
2664
2665 stv0367_writereg(state, R367CAB_SRC_NCO_LL, u32_tmp);
2666 stv0367_writereg(state, R367CAB_SRC_NCO_LH, (u32_tmp >> 8));
2667 stv0367_writereg(state, R367CAB_SRC_NCO_HL, (u32_tmp >> 16));
2668 stv0367_writereg(state, R367CAB_SRC_NCO_HH, (u32_tmp >> 24));
2669
2670 stv0367_writereg(state, R367CAB_IQDEM_GAIN_SRC_L, u32_tmp1 & 0x00ff);
2671 stv0367_writebits(state, F367CAB_GAIN_SRC_HI, (u32_tmp1 >> 8) & 0x00ff);
2672
2673 return SymbolRate ;
2674}
2675
2676static u32 stv0367cab_GetSymbolRate(struct stv0367_state *state, u32 mclk_hz)
2677{
2678 u32 regsym;
2679 u32 adp_khz;
2680
2681 regsym = stv0367_readreg(state, R367CAB_SRC_NCO_LL) +
2682 (stv0367_readreg(state, R367CAB_SRC_NCO_LH) << 8) +
2683 (stv0367_readreg(state, R367CAB_SRC_NCO_HL) << 16) +
2684 (stv0367_readreg(state, R367CAB_SRC_NCO_HH) << 24);
2685
2686 adp_khz = (mclk_hz >> 1) / 1000;/* TRL works at half the system clock */
2687
2688 if (regsym < 134217728) { /* 134217728L = 2**27*/
2689 regsym = regsym * 32; /* 32 = 2**5 */
2690 regsym = regsym / 32768; /* 32768L = 2**15 */
2691 regsym = adp_khz * regsym; /* AdpClk in kHz */
2692 regsym = regsym / 128; /* 128 = 2**7 */
2693 regsym *= 125 ; /* 125 = 1000/2**3 */
2694 regsym /= 2048 ; /* 2048 = 2**11 */
2695 } else if (regsym < 268435456) { /* 268435456L = 2**28 */
2696 regsym = regsym * 16; /* 16 = 2**4 */
2697 regsym = regsym / 32768; /* 32768L = 2**15 */
2698 regsym = adp_khz * regsym; /* AdpClk in kHz */
2699 regsym = regsym / 128; /* 128 = 2**7 */
2700 regsym *= 125 ; /* 125 = 1000/2**3*/
2701 regsym /= 1024 ; /* 256 = 2**10*/
2702 } else if (regsym < 536870912) { /* 536870912L = 2**29*/
2703 regsym = regsym * 8; /* 8 = 2**3 */
2704 regsym = regsym / 32768; /* 32768L = 2**15 */
2705 regsym = adp_khz * regsym; /* AdpClk in kHz */
2706 regsym = regsym / 128; /* 128 = 2**7 */
2707 regsym *= 125 ; /* 125 = 1000/2**3 */
2708 regsym /= 512 ; /* 128 = 2**9 */
2709 } else {
2710 regsym = regsym * 4; /* 4 = 2**2 */
2711 regsym = regsym / 32768; /* 32768L = 2**15 */
2712 regsym = adp_khz * regsym; /* AdpClk in kHz */
2713 regsym = regsym / 128; /* 128 = 2**7 */
2714 regsym *= 125 ; /* 125 = 1000/2**3 */
2715 regsym /= 256 ; /* 64 = 2**8 */
2716 }
2717
2718 return regsym;
2719}
2720
2721static int stv0367cab_read_status(struct dvb_frontend *fe, fe_status_t *status)
2722{
2723 struct stv0367_state *state = fe->demodulator_priv;
2724
2725 dprintk("%s:\n", __func__);
2726
2727 *status = 0;
2728
2729 if (stv0367_readbits(state, F367CAB_QAMFEC_LOCK)) {
2730 *status |= FE_HAS_LOCK;
2731 dprintk("%s: stv0367 has locked\n", __func__);
2732 }
2733
2734 return 0;
2735}
2736
2737static int stv0367cab_standby(struct dvb_frontend *fe, u8 standby_on)
2738{
2739 struct stv0367_state *state = fe->demodulator_priv;
2740
2741 dprintk("%s:\n", __func__);
2742
2743 if (standby_on) {
2744 stv0367_writebits(state, F367CAB_BYPASS_PLLXN, 0x03);
2745 stv0367_writebits(state, F367CAB_STDBY_PLLXN, 0x01);
2746 stv0367_writebits(state, F367CAB_STDBY, 1);
2747 stv0367_writebits(state, F367CAB_STDBY_CORE, 1);
2748 stv0367_writebits(state, F367CAB_EN_BUFFER_I, 0);
2749 stv0367_writebits(state, F367CAB_EN_BUFFER_Q, 0);
2750 stv0367_writebits(state, F367CAB_POFFQ, 1);
2751 stv0367_writebits(state, F367CAB_POFFI, 1);
2752 } else {
2753 stv0367_writebits(state, F367CAB_STDBY_PLLXN, 0x00);
2754 stv0367_writebits(state, F367CAB_BYPASS_PLLXN, 0x00);
2755 stv0367_writebits(state, F367CAB_STDBY, 0);
2756 stv0367_writebits(state, F367CAB_STDBY_CORE, 0);
2757 stv0367_writebits(state, F367CAB_EN_BUFFER_I, 1);
2758 stv0367_writebits(state, F367CAB_EN_BUFFER_Q, 1);
2759 stv0367_writebits(state, F367CAB_POFFQ, 0);
2760 stv0367_writebits(state, F367CAB_POFFI, 0);
2761 }
2762
2763 return 0;
2764}
2765
2766static int stv0367cab_sleep(struct dvb_frontend *fe)
2767{
2768 return stv0367cab_standby(fe, 1);
2769}
2770
2771int stv0367cab_init(struct dvb_frontend *fe)
2772{
2773 struct stv0367_state *state = fe->demodulator_priv;
2774 struct stv0367cab_state *cab_state = state->cab_state;
2775 int i;
2776
2777 dprintk("%s:\n", __func__);
2778
2779 for (i = 0; i < STV0367CAB_NBREGS; i++)
2780 stv0367_writereg(state, def0367cab[i].addr,
2781 def0367cab[i].value);
2782
2783 switch (state->config->ts_mode) {
2784 case STV0367_DVBCI_CLOCK:
2785 dprintk("Setting TSMode = STV0367_DVBCI_CLOCK\n");
2786 stv0367_writebits(state, F367CAB_OUTFORMAT, 0x03);
2787 break;
2788 case STV0367_SERIAL_PUNCT_CLOCK:
2789 case STV0367_SERIAL_CONT_CLOCK:
2790 stv0367_writebits(state, F367CAB_OUTFORMAT, 0x01);
2791 break;
2792 case STV0367_PARALLEL_PUNCT_CLOCK:
2793 case STV0367_OUTPUTMODE_DEFAULT:
2794 stv0367_writebits(state, F367CAB_OUTFORMAT, 0x00);
2795 break;
2796 }
2797
2798 switch (state->config->clk_pol) {
2799 case STV0367_RISINGEDGE_CLOCK:
2800 stv0367_writebits(state, F367CAB_CLK_POLARITY, 0x00);
2801 break;
2802 case STV0367_FALLINGEDGE_CLOCK:
2803 case STV0367_CLOCKPOLARITY_DEFAULT:
2804 stv0367_writebits(state, F367CAB_CLK_POLARITY, 0x01);
2805 break;
2806 }
2807
2808 stv0367_writebits(state, F367CAB_SYNC_STRIP, 0x00);
2809
2810 stv0367_writebits(state, F367CAB_CT_NBST, 0x01);
2811
2812 stv0367_writebits(state, F367CAB_TS_SWAP, 0x01);
2813
2814 stv0367_writebits(state, F367CAB_FIFO_BYPASS, 0x00);
2815
2816 stv0367_writereg(state, R367CAB_ANACTRL, 0x00);/*PLL enabled and used */
2817
2818 cab_state->mclk = stv0367cab_get_mclk(fe, state->config->xtal);
2819 cab_state->adc_clk = stv0367cab_get_adc_freq(fe, state->config->xtal);
2820
2821 return 0;
2822}
2823static
2824enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state,
2825 struct dvb_frontend_parameters *param)
2826{
2827 struct dvb_qam_parameters *op = &param->u.qam;
2828 struct stv0367cab_state *cab_state = state->cab_state;
2829 enum stv0367_cab_signal_type signalType = FE_CAB_NOAGC;
2830 u32 QAMFEC_Lock, QAM_Lock, u32_tmp,
2831 LockTime, TRLTimeOut, AGCTimeOut, CRLSymbols,
2832 CRLTimeOut, EQLTimeOut, DemodTimeOut, FECTimeOut;
2833 u8 TrackAGCAccum;
2834 s32 tmp;
2835
2836 dprintk("%s:\n", __func__);
2837
2838 /* Timeouts calculation */
2839 /* A max lock time of 25 ms is allowed for delayed AGC */
2840 AGCTimeOut = 25;
2841 /* 100000 symbols needed by the TRL as a maximum value */
2842 TRLTimeOut = 100000000 / op->symbol_rate;
2843 /* CRLSymbols is the needed number of symbols to achieve a lock
2844 within [-4%, +4%] of the symbol rate.
2845 CRL timeout is calculated
2846 for a lock within [-search_range, +search_range].
2847 EQL timeout can be changed depending on
2848 the micro-reflections we want to handle.
2849 A characterization must be performed
2850 with these echoes to get new timeout values.
2851 */
2852 switch (op->modulation) {
2853 case QAM_16:
2854 CRLSymbols = 150000;
2855 EQLTimeOut = 100;
2856 break;
2857 case QAM_32:
2858 CRLSymbols = 250000;
2859 EQLTimeOut = 100;
2860 break;
2861 case QAM_64:
2862 CRLSymbols = 200000;
2863 EQLTimeOut = 100;
2864 break;
2865 case QAM_128:
2866 CRLSymbols = 250000;
2867 EQLTimeOut = 100;
2868 break;
2869 case QAM_256:
2870 CRLSymbols = 250000;
2871 EQLTimeOut = 100;
2872 break;
2873 default:
2874 CRLSymbols = 200000;
2875 EQLTimeOut = 100;
2876 break;
2877 }
2878#if 0
2879 if (pIntParams->search_range < 0) {
2880 CRLTimeOut = (25 * CRLSymbols *
2881 (-pIntParams->search_range / 1000)) /
2882 (pIntParams->symbol_rate / 1000);
2883 } else
2884#endif
2885 CRLTimeOut = (25 * CRLSymbols * (cab_state->search_range / 1000)) /
2886 (op->symbol_rate / 1000);
2887
2888 CRLTimeOut = (1000 * CRLTimeOut) / op->symbol_rate;
2889 /* Timeouts below 50ms are coerced */
2890 if (CRLTimeOut < 50)
2891 CRLTimeOut = 50;
2892 /* A maximum of 100 TS packets is needed to get FEC lock even in case
2893 the spectrum inversion needs to be changed.
2894 This is equal to 20 ms in case of the lowest symbol rate of 0.87Msps
2895 */
2896 FECTimeOut = 20;
2897 DemodTimeOut = AGCTimeOut + TRLTimeOut + CRLTimeOut + EQLTimeOut;
2898
2899 dprintk("%s: DemodTimeOut=%d\n", __func__, DemodTimeOut);
2900
2901 /* Reset the TRL to ensure nothing starts until the
2902 AGC is stable which ensures a better lock time
2903 */
2904 stv0367_writereg(state, R367CAB_CTRL_1, 0x04);
2905 /* Set AGC accumulation time to minimum and lock threshold to maximum
2906 in order to speed up the AGC lock */
2907 TrackAGCAccum = stv0367_readbits(state, F367CAB_AGC_ACCUMRSTSEL);
2908 stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, 0x0);
2909 /* Modulus Mapper is disabled */
2910 stv0367_writebits(state, F367CAB_MODULUSMAP_EN, 0);
2911 /* Disable the sweep function */
2912 stv0367_writebits(state, F367CAB_SWEEP_EN, 0);
2913 /* The sweep function is never used, Sweep rate must be set to 0 */
2914 /* Set the derotator frequency in Hz */
2915 stv0367cab_set_derot_freq(state, cab_state->adc_clk,
2916 (1000 * (s32)state->config->if_khz + cab_state->derot_offset));
2917 /* Disable the Allpass Filter when the symbol rate is out of range */
2918 if ((op->symbol_rate > 10800000) | (op->symbol_rate < 1800000)) {
2919 stv0367_writebits(state, F367CAB_ADJ_EN, 0);
2920 stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 0);
2921 }
2922#if 0
2923 /* Check if the tuner is locked */
2924 tuner_lock = stv0367cab_tuner_get_status(fe);
2925 if (tuner_lock == 0)
2926 return FE_367CAB_NOTUNER;
2927#endif
2928 /* Relase the TRL to start demodulator acquisition */
2929 /* Wait for QAM lock */
2930 LockTime = 0;
2931 stv0367_writereg(state, R367CAB_CTRL_1, 0x00);
2932 do {
2933 QAM_Lock = stv0367_readbits(state, F367CAB_FSM_STATUS);
2934 if ((LockTime >= (DemodTimeOut - EQLTimeOut)) &&
2935 (QAM_Lock == 0x04))
2936 /*
2937 * We don't wait longer, the frequency/phase offset
2938 * must be too big
2939 */
2940 LockTime = DemodTimeOut;
2941 else if ((LockTime >= (AGCTimeOut + TRLTimeOut)) &&
2942 (QAM_Lock == 0x02))
2943 /*
2944 * We don't wait longer, either there is no signal or
2945 * it is not the right symbol rate or it is an analog
2946 * carrier
2947 */
2948 {
2949 LockTime = DemodTimeOut;
2950 u32_tmp = stv0367_readbits(state,
2951 F367CAB_AGC_PWR_WORD_LO) +
2952 (stv0367_readbits(state,
2953 F367CAB_AGC_PWR_WORD_ME) << 8) +
2954 (stv0367_readbits(state,
2955 F367CAB_AGC_PWR_WORD_HI) << 16);
2956 if (u32_tmp >= 131072)
2957 u32_tmp = 262144 - u32_tmp;
2958 u32_tmp = u32_tmp / (1 << (11 - stv0367_readbits(state,
2959 F367CAB_AGC_IF_BWSEL)));
2960
2961 if (u32_tmp < stv0367_readbits(state,
2962 F367CAB_AGC_PWRREF_LO) +
2963 256 * stv0367_readbits(state,
2964 F367CAB_AGC_PWRREF_HI) - 10)
2965 QAM_Lock = 0x0f;
2966 } else {
2967 usleep_range(10000, 20000);
2968 LockTime += 10;
2969 }
2970 dprintk("QAM_Lock=0x%x LockTime=%d\n", QAM_Lock, LockTime);
2971 tmp = stv0367_readreg(state, R367CAB_IT_STATUS1);
2972
2973 dprintk("R367CAB_IT_STATUS1=0x%x\n", tmp);
2974
2975 } while (((QAM_Lock != 0x0c) && (QAM_Lock != 0x0b)) &&
2976 (LockTime < DemodTimeOut));
2977
2978 dprintk("QAM_Lock=0x%x\n", QAM_Lock);
2979
2980 tmp = stv0367_readreg(state, R367CAB_IT_STATUS1);
2981 dprintk("R367CAB_IT_STATUS1=0x%x\n", tmp);
2982 tmp = stv0367_readreg(state, R367CAB_IT_STATUS2);
2983 dprintk("R367CAB_IT_STATUS2=0x%x\n", tmp);
2984
2985 tmp = stv0367cab_get_derot_freq(state, cab_state->adc_clk);
2986 dprintk("stv0367cab_get_derot_freq=0x%x\n", tmp);
2987
2988 if ((QAM_Lock == 0x0c) || (QAM_Lock == 0x0b)) {
2989 /* Wait for FEC lock */
2990 LockTime = 0;
2991 do {
2992 usleep_range(5000, 7000);
2993 LockTime += 5;
2994 QAMFEC_Lock = stv0367_readbits(state,
2995 F367CAB_QAMFEC_LOCK);
2996 } while (!QAMFEC_Lock && (LockTime < FECTimeOut));
2997 } else
2998 QAMFEC_Lock = 0;
2999
3000 if (QAMFEC_Lock) {
3001 signalType = FE_CAB_DATAOK;
3002 cab_state->modulation = op->modulation;
3003 cab_state->spect_inv = stv0367_readbits(state,
3004 F367CAB_QUAD_INV);
3005#if 0
3006/* not clear for me */
3007 if (state->config->if_khz != 0) {
3008 if (state->config->if_khz > cab_state->adc_clk / 1000) {
3009 cab_state->freq_khz =
3010 FE_Cab_TunerGetFrequency(pIntParams->hTuner)
3011 - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
3012 - cab_state->adc_clk / 1000 + state->config->if_khz;
3013 } else {
3014 cab_state->freq_khz =
3015 FE_Cab_TunerGetFrequency(pIntParams->hTuner)
3016 - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
3017 + state->config->if_khz;
3018 }
3019 } else {
3020 cab_state->freq_khz =
3021 FE_Cab_TunerGetFrequency(pIntParams->hTuner) +
3022 stv0367cab_get_derot_freq(state,
3023 cab_state->adc_clk) -
3024 cab_state->adc_clk / 4000;
3025 }
3026#endif
3027 cab_state->symbol_rate = stv0367cab_GetSymbolRate(state,
3028 cab_state->mclk);
3029 cab_state->locked = 1;
3030
3031 /* stv0367_setbits(state, F367CAB_AGC_ACCUMRSTSEL,7);*/
3032 } else {
3033 switch (QAM_Lock) {
3034 case 1:
3035 signalType = FE_CAB_NOAGC;
3036 break;
3037 case 2:
3038 signalType = FE_CAB_NOTIMING;
3039 break;
3040 case 3:
3041 signalType = FE_CAB_TIMINGOK;
3042 break;
3043 case 4:
3044 signalType = FE_CAB_NOCARRIER;
3045 break;
3046 case 5:
3047 signalType = FE_CAB_CARRIEROK;
3048 break;
3049 case 7:
3050 signalType = FE_CAB_NOBLIND;
3051 break;
3052 case 8:
3053 signalType = FE_CAB_BLINDOK;
3054 break;
3055 case 10:
3056 signalType = FE_CAB_NODEMOD;
3057 break;
3058 case 11:
3059 signalType = FE_CAB_DEMODOK;
3060 break;
3061 case 12:
3062 signalType = FE_CAB_DEMODOK;
3063 break;
3064 case 13:
3065 signalType = FE_CAB_NODEMOD;
3066 break;
3067 case 14:
3068 signalType = FE_CAB_NOBLIND;
3069 break;
3070 case 15:
3071 signalType = FE_CAB_NOSIGNAL;
3072 break;
3073 default:
3074 break;
3075 }
3076
3077 }
3078
3079 /* Set the AGC control values to tracking values */
3080 stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, TrackAGCAccum);
3081 return signalType;
3082}
3083
3084static int stv0367cab_set_frontend(struct dvb_frontend *fe,
3085 struct dvb_frontend_parameters *param)
3086{
3087 struct stv0367_state *state = fe->demodulator_priv;
3088 struct stv0367cab_state *cab_state = state->cab_state;
3089 struct dvb_qam_parameters *op = &param->u.qam;
3090 enum stv0367cab_mod QAMSize = 0;
3091
3092 dprintk("%s: freq = %d, srate = %d\n", __func__,
3093 param->frequency, op->symbol_rate);
3094
3095 cab_state->derot_offset = 0;
3096
3097 switch (op->modulation) {
3098 case QAM_16:
3099 QAMSize = FE_CAB_MOD_QAM16;
3100 break;
3101 case QAM_32:
3102 QAMSize = FE_CAB_MOD_QAM32;
3103 break;
3104 case QAM_64:
3105 QAMSize = FE_CAB_MOD_QAM64;
3106 break;
3107 case QAM_128:
3108 QAMSize = FE_CAB_MOD_QAM128;
3109 break;
3110 case QAM_256:
3111 QAMSize = FE_CAB_MOD_QAM256;
3112 break;
3113 default:
3114 break;
3115 }
3116
3117 stv0367cab_init(fe);
3118
3119 /* Tuner Frequency Setting */
3120 if (fe->ops.tuner_ops.set_params) {
3121 if (fe->ops.i2c_gate_ctrl)
3122 fe->ops.i2c_gate_ctrl(fe, 1);
3123 fe->ops.tuner_ops.set_params(fe, param);
3124 if (fe->ops.i2c_gate_ctrl)
3125 fe->ops.i2c_gate_ctrl(fe, 0);
3126 }
3127
3128 stv0367cab_SetQamSize(
3129 state,
3130 op->symbol_rate,
3131 QAMSize);
3132
3133 stv0367cab_set_srate(state,
3134 cab_state->adc_clk,
3135 cab_state->mclk,
3136 op->symbol_rate,
3137 QAMSize);
3138 /* Search algorithm launch, [-1.1*RangeOffset, +1.1*RangeOffset] scan */
3139 cab_state->state = stv0367cab_algo(state, param);
3140 return 0;
3141}
3142
3143static int stv0367cab_get_frontend(struct dvb_frontend *fe,
3144 struct dvb_frontend_parameters *param)
3145{
3146 struct stv0367_state *state = fe->demodulator_priv;
3147 struct stv0367cab_state *cab_state = state->cab_state;
3148 struct dvb_qam_parameters *op = &param->u.qam;
3149
3150 enum stv0367cab_mod QAMSize;
3151
3152 dprintk("%s:\n", __func__);
3153
3154 op->symbol_rate = stv0367cab_GetSymbolRate(state, cab_state->mclk);
3155
3156 QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE);
3157 switch (QAMSize) {
3158 case FE_CAB_MOD_QAM16:
3159 op->modulation = QAM_16;
3160 break;
3161 case FE_CAB_MOD_QAM32:
3162 op->modulation = QAM_32;
3163 break;
3164 case FE_CAB_MOD_QAM64:
3165 op->modulation = QAM_64;
3166 break;
3167 case FE_CAB_MOD_QAM128:
3168 op->modulation = QAM_128;
3169 break;
3170 case QAM_256:
3171 op->modulation = QAM_256;
3172 break;
3173 default:
3174 break;
3175 }
3176
3177 param->frequency = stv0367_get_tuner_freq(fe);
3178
3179 dprintk("%s: tuner frequency = %d\n", __func__, param->frequency);
3180
3181 if (state->config->if_khz == 0) {
3182 param->frequency +=
3183 (stv0367cab_get_derot_freq(state, cab_state->adc_clk) -
3184 cab_state->adc_clk / 4000);
3185 return 0;
3186 }
3187
3188 if (state->config->if_khz > cab_state->adc_clk / 1000)
3189 param->frequency += (state->config->if_khz
3190 - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
3191 - cab_state->adc_clk / 1000);
3192 else
3193 param->frequency += (state->config->if_khz
3194 - stv0367cab_get_derot_freq(state, cab_state->adc_clk));
3195
3196 return 0;
3197}
3198
3199#if 0
3200void stv0367cab_GetErrorCount(state, enum stv0367cab_mod QAMSize,
3201 u32 symbol_rate, FE_367qam_Monitor *Monitor_results)
3202{
3203 stv0367cab_OptimiseNByteAndGetBER(state, QAMSize, symbol_rate, Monitor_results);
3204 stv0367cab_GetPacketsCount(state, Monitor_results);
3205
3206 return;
3207}
3208
3209static int stv0367cab_read_ber(struct dvb_frontend *fe, u32 *ber)
3210{
3211 struct stv0367_state *state = fe->demodulator_priv;
3212
3213 return 0;
3214}
3215#endif
3216static s32 stv0367cab_get_rf_lvl(struct stv0367_state *state)
3217{
3218 s32 rfLevel = 0;
3219 s32 RfAgcPwm = 0, IfAgcPwm = 0;
3220 u8 i;
3221
3222 stv0367_writebits(state, F367CAB_STDBY_ADCGP, 0x0);
3223
3224 RfAgcPwm =
3225 (stv0367_readbits(state, F367CAB_RF_AGC1_LEVEL_LO) & 0x03) +
3226 (stv0367_readbits(state, F367CAB_RF_AGC1_LEVEL_HI) << 2);
3227 RfAgcPwm = 100 * RfAgcPwm / 1023;
3228
3229 IfAgcPwm =
3230 stv0367_readbits(state, F367CAB_AGC_IF_PWMCMD_LO) +
3231 (stv0367_readbits(state, F367CAB_AGC_IF_PWMCMD_HI) << 8);
3232 if (IfAgcPwm >= 2048)
3233 IfAgcPwm -= 2048;
3234 else
3235 IfAgcPwm += 2048;
3236
3237 IfAgcPwm = 100 * IfAgcPwm / 4095;
3238
3239 /* For DTT75467 on NIM */
3240 if (RfAgcPwm < 90 && IfAgcPwm < 28) {
3241 for (i = 0; i < RF_LOOKUP_TABLE_SIZE; i++) {
3242 if (RfAgcPwm <= stv0367cab_RF_LookUp1[0][i]) {
3243 rfLevel = (-1) * stv0367cab_RF_LookUp1[1][i];
3244 break;
3245 }
3246 }
3247 if (i == RF_LOOKUP_TABLE_SIZE)
3248 rfLevel = -56;
3249 } else { /*if IF AGC>10*/
3250 for (i = 0; i < RF_LOOKUP_TABLE2_SIZE; i++) {
3251 if (IfAgcPwm <= stv0367cab_RF_LookUp2[0][i]) {
3252 rfLevel = (-1) * stv0367cab_RF_LookUp2[1][i];
3253 break;
3254 }
3255 }
3256 if (i == RF_LOOKUP_TABLE2_SIZE)
3257 rfLevel = -72;
3258 }
3259 return rfLevel;
3260}
3261
3262static int stv0367cab_read_strength(struct dvb_frontend *fe, u16 *strength)
3263{
3264 struct stv0367_state *state = fe->demodulator_priv;
3265
3266 s32 signal = stv0367cab_get_rf_lvl(state);
3267
3268 dprintk("%s: signal=%d dBm\n", __func__, signal);
3269
3270 if (signal <= -72)
3271 *strength = 65535;
3272 else
3273 *strength = (22 + signal) * (-1311);
3274
3275 dprintk("%s: strength=%d\n", __func__, (*strength));
3276
3277 return 0;
3278}
3279
3280static int stv0367cab_read_snr(struct dvb_frontend *fe, u16 *snr)
3281{
3282 struct stv0367_state *state = fe->demodulator_priv;
3283 u32 noisepercentage;
3284 enum stv0367cab_mod QAMSize;
3285 u32 regval = 0, temp = 0;
3286 int power, i;
3287
3288 QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE);
3289 switch (QAMSize) {
3290 case FE_CAB_MOD_QAM4:
3291 power = 21904;
3292 break;
3293 case FE_CAB_MOD_QAM16:
3294 power = 20480;
3295 break;
3296 case FE_CAB_MOD_QAM32:
3297 power = 23040;
3298 break;
3299 case FE_CAB_MOD_QAM64:
3300 power = 21504;
3301 break;
3302 case FE_CAB_MOD_QAM128:
3303 power = 23616;
3304 break;
3305 case FE_CAB_MOD_QAM256:
3306 power = 21760;
3307 break;
3308 case FE_CAB_MOD_QAM512:
3309 power = 1;
3310 break;
3311 case FE_CAB_MOD_QAM1024:
3312 power = 21280;
3313 break;
3314 default:
3315 power = 1;
3316 break;
3317 }
3318
3319 for (i = 0; i < 10; i++) {
3320 regval += (stv0367_readbits(state, F367CAB_SNR_LO)
3321 + 256 * stv0367_readbits(state, F367CAB_SNR_HI));
3322 }
3323
3324 regval /= 10; /*for average over 10 times in for loop above*/
3325 if (regval != 0) {
3326 temp = power
3327 * (1 << (3 + stv0367_readbits(state, F367CAB_SNR_PER)));
3328 temp /= regval;
3329 }
3330
3331 /* table values, not needed to calculate logarithms */
3332 if (temp >= 5012)
3333 noisepercentage = 100;
3334 else if (temp >= 3981)
3335 noisepercentage = 93;
3336 else if (temp >= 3162)
3337 noisepercentage = 86;
3338 else if (temp >= 2512)
3339 noisepercentage = 79;
3340 else if (temp >= 1995)
3341 noisepercentage = 72;
3342 else if (temp >= 1585)
3343 noisepercentage = 65;
3344 else if (temp >= 1259)
3345 noisepercentage = 58;
3346 else if (temp >= 1000)
3347 noisepercentage = 50;
3348 else if (temp >= 794)
3349 noisepercentage = 43;
3350 else if (temp >= 501)
3351 noisepercentage = 36;
3352 else if (temp >= 316)
3353 noisepercentage = 29;
3354 else if (temp >= 200)
3355 noisepercentage = 22;
3356 else if (temp >= 158)
3357 noisepercentage = 14;
3358 else if (temp >= 126)
3359 noisepercentage = 7;
3360 else
3361 noisepercentage = 0;
3362
3363 dprintk("%s: noisepercentage=%d\n", __func__, noisepercentage);
3364
3365 *snr = (noisepercentage * 65535) / 100;
3366
3367 return 0;
3368}
3369
3370static int stv0367cab_read_ucblcks(struct dvb_frontend *fe, u32 *ucblocks)
3371{
3372 struct stv0367_state *state = fe->demodulator_priv;
3373 int corrected, tscount;
3374
3375 *ucblocks = (stv0367_readreg(state, R367CAB_RS_COUNTER_5) << 8)
3376 | stv0367_readreg(state, R367CAB_RS_COUNTER_4);
3377 corrected = (stv0367_readreg(state, R367CAB_RS_COUNTER_3) << 8)
3378 | stv0367_readreg(state, R367CAB_RS_COUNTER_2);
3379 tscount = (stv0367_readreg(state, R367CAB_RS_COUNTER_2) << 8)
3380 | stv0367_readreg(state, R367CAB_RS_COUNTER_1);
3381
3382 dprintk("%s: uncorrected blocks=%d corrected blocks=%d tscount=%d\n",
3383 __func__, *ucblocks, corrected, tscount);
3384
3385 return 0;
3386};
3387
3388static struct dvb_frontend_ops stv0367cab_ops = {
3389 .info = {
3390 .name = "ST STV0367 DVB-C",
3391 .type = FE_QAM,
3392 .frequency_min = 47000000,
3393 .frequency_max = 862000000,
3394 .frequency_stepsize = 62500,
3395 .symbol_rate_min = 870000,
3396 .symbol_rate_max = 11700000,
3397 .caps = 0x400 |/* FE_CAN_QAM_4 */
3398 FE_CAN_QAM_16 | FE_CAN_QAM_32 |
3399 FE_CAN_QAM_64 | FE_CAN_QAM_128 |
3400 FE_CAN_QAM_256 | FE_CAN_FEC_AUTO
3401 },
3402 .release = stv0367_release,
3403 .init = stv0367cab_init,
3404 .sleep = stv0367cab_sleep,
3405 .i2c_gate_ctrl = stv0367cab_gate_ctrl,
3406 .set_frontend = stv0367cab_set_frontend,
3407 .get_frontend = stv0367cab_get_frontend,
3408 .read_status = stv0367cab_read_status,
3409/* .read_ber = stv0367cab_read_ber, */
3410 .read_signal_strength = stv0367cab_read_strength,
3411 .read_snr = stv0367cab_read_snr,
3412 .read_ucblocks = stv0367cab_read_ucblcks,
3413 .get_tune_settings = stv0367_get_tune_settings,
3414};
3415
3416struct dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
3417 struct i2c_adapter *i2c)
3418{
3419 struct stv0367_state *state = NULL;
3420 struct stv0367cab_state *cab_state = NULL;
3421
3422 /* allocate memory for the internal state */
3423 state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL);
3424 if (state == NULL)
3425 goto error;
3426 cab_state = kzalloc(sizeof(struct stv0367cab_state), GFP_KERNEL);
3427 if (cab_state == NULL)
3428 goto error;
3429
3430 /* setup the state */
3431 state->i2c = i2c;
3432 state->config = config;
3433 cab_state->search_range = 280000;
3434 state->cab_state = cab_state;
3435 state->fe.ops = stv0367cab_ops;
3436 state->fe.demodulator_priv = state;
3437 state->chip_id = stv0367_readreg(state, 0xf000);
3438
3439 dprintk("%s: chip_id = 0x%x\n", __func__, state->chip_id);
3440
3441 /* check if the demod is there */
3442 if ((state->chip_id != 0x50) && (state->chip_id != 0x60))
3443 goto error;
3444
3445 return &state->fe;
3446
3447error:
3448 kfree(cab_state);
3449 kfree(state);
3450 return NULL;
3451}
3452EXPORT_SYMBOL(stv0367cab_attach);
3453
3454MODULE_PARM_DESC(debug, "Set debug");
3455MODULE_PARM_DESC(i2c_debug, "Set i2c debug");
3456
3457MODULE_AUTHOR("Igor M. Liplianin");
3458MODULE_DESCRIPTION("ST STV0367 DVB-C/T demodulator driver");
3459MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv0367.h b/drivers/media/dvb/frontends/stv0367.h
new file mode 100644
index 00000000000..93cc4a57eea
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0367.h
@@ -0,0 +1,66 @@
1/*
2 * stv0367.h
3 *
4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef STV0367_H
27#define STV0367_H
28
29#include <linux/dvb/frontend.h>
30#include "dvb_frontend.h"
31
32struct stv0367_config {
33 u8 demod_address;
34 u32 xtal;
35 u32 if_khz;/*4500*/
36 int if_iq_mode;
37 int ts_mode;
38 int clk_pol;
39};
40
41#if defined(CONFIG_DVB_STV0367) || (defined(CONFIG_DVB_STV0367_MODULE) \
42 && defined(MODULE))
43extern struct
44dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
45 struct i2c_adapter *i2c);
46extern struct
47dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
48 struct i2c_adapter *i2c);
49#else
50static inline struct
51dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
52 struct i2c_adapter *i2c)
53{
54 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
55 return NULL;
56}
57static inline struct
58dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
59 struct i2c_adapter *i2c)
60{
61 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
62 return NULL;
63}
64#endif
65
66#endif
diff --git a/drivers/media/dvb/frontends/stv0367_priv.h b/drivers/media/dvb/frontends/stv0367_priv.h
new file mode 100644
index 00000000000..995db0689dd
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0367_priv.h
@@ -0,0 +1,212 @@
1/*
2 * stv0367_priv.h
3 *
4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25/* Common driver error constants */
26
27#ifndef STV0367_PRIV_H
28#define STV0367_PRIV_H
29
30#ifndef TRUE
31 #define TRUE (1 == 1)
32#endif
33#ifndef FALSE
34 #define FALSE (!TRUE)
35#endif
36
37#ifndef NULL
38#define NULL 0
39#endif
40
41/* MACRO definitions */
42#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
43#define MAX(X, Y) ((X) >= (Y) ? (X) : (Y))
44#define MIN(X, Y) ((X) <= (Y) ? (X) : (Y))
45#define INRANGE(X, Y, Z) \
46 ((((X) <= (Y)) && ((Y) <= (Z))) || \
47 (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0)
48
49#ifndef MAKEWORD
50#define MAKEWORD(X, Y) (((X) << 8) + (Y))
51#endif
52
53#define LSB(X) (((X) & 0xff))
54#define MSB(Y) (((Y) >> 8) & 0xff)
55#define MMSB(Y)(((Y) >> 16) & 0xff)
56
57enum stv0367_ter_signal_type {
58 FE_TER_NOAGC = 0,
59 FE_TER_AGCOK = 5,
60 FE_TER_NOTPS = 6,
61 FE_TER_TPSOK = 7,
62 FE_TER_NOSYMBOL = 8,
63 FE_TER_BAD_CPQ = 9,
64 FE_TER_PRFOUNDOK = 10,
65 FE_TER_NOPRFOUND = 11,
66 FE_TER_LOCKOK = 12,
67 FE_TER_NOLOCK = 13,
68 FE_TER_SYMBOLOK = 15,
69 FE_TER_CPAMPOK = 16,
70 FE_TER_NOCPAMP = 17,
71 FE_TER_SWNOK = 18
72};
73
74enum stv0367_ts_mode {
75 STV0367_OUTPUTMODE_DEFAULT,
76 STV0367_SERIAL_PUNCT_CLOCK,
77 STV0367_SERIAL_CONT_CLOCK,
78 STV0367_PARALLEL_PUNCT_CLOCK,
79 STV0367_DVBCI_CLOCK
80};
81
82enum stv0367_clk_pol {
83 STV0367_CLOCKPOLARITY_DEFAULT,
84 STV0367_RISINGEDGE_CLOCK,
85 STV0367_FALLINGEDGE_CLOCK
86};
87
88enum stv0367_ter_bw {
89 FE_TER_CHAN_BW_6M = 6,
90 FE_TER_CHAN_BW_7M = 7,
91 FE_TER_CHAN_BW_8M = 8
92};
93
94#if 0
95enum FE_TER_Rate_TPS {
96 FE_TER_TPS_1_2 = 0,
97 FE_TER_TPS_2_3 = 1,
98 FE_TER_TPS_3_4 = 2,
99 FE_TER_TPS_5_6 = 3,
100 FE_TER_TPS_7_8 = 4
101};
102#endif
103
104enum stv0367_ter_mode {
105 FE_TER_MODE_2K,
106 FE_TER_MODE_8K,
107 FE_TER_MODE_4K
108};
109#if 0
110enum FE_TER_Hierarchy_Alpha {
111 FE_TER_HIER_ALPHA_NONE, /* Regular modulation */
112 FE_TER_HIER_ALPHA_1, /* Hierarchical modulation a = 1*/
113 FE_TER_HIER_ALPHA_2, /* Hierarchical modulation a = 2*/
114 FE_TER_HIER_ALPHA_4 /* Hierarchical modulation a = 4*/
115};
116#endif
117enum stv0367_ter_hierarchy {
118 FE_TER_HIER_NONE, /*Hierarchy None*/
119 FE_TER_HIER_LOW_PRIO, /*Hierarchy : Low Priority*/
120 FE_TER_HIER_HIGH_PRIO, /*Hierarchy : High Priority*/
121 FE_TER_HIER_PRIO_ANY /*Hierarchy :Any*/
122};
123
124#if 0
125enum fe_stv0367_ter_spec {
126 FE_TER_INVERSION_NONE = 0,
127 FE_TER_INVERSION = 1,
128 FE_TER_INVERSION_AUTO = 2,
129 FE_TER_INVERSION_UNK = 4
130};
131#endif
132
133enum stv0367_ter_if_iq_mode {
134 FE_TER_NORMAL_IF_TUNER = 0,
135 FE_TER_LONGPATH_IF_TUNER = 1,
136 FE_TER_IQ_TUNER = 2
137
138};
139
140#if 0
141enum FE_TER_FECRate {
142 FE_TER_FEC_NONE = 0x00, /* no FEC rate specified */
143 FE_TER_FEC_ALL = 0xFF, /* Logical OR of all FECs */
144 FE_TER_FEC_1_2 = 1,
145 FE_TER_FEC_2_3 = (1 << 1),
146 FE_TER_FEC_3_4 = (1 << 2),
147 FE_TER_FEC_4_5 = (1 << 3),
148 FE_TER_FEC_5_6 = (1 << 4),
149 FE_TER_FEC_6_7 = (1 << 5),
150 FE_TER_FEC_7_8 = (1 << 6),
151 FE_TER_FEC_8_9 = (1 << 7)
152};
153
154enum FE_TER_Rate {
155 FE_TER_FE_1_2 = 0,
156 FE_TER_FE_2_3 = 1,
157 FE_TER_FE_3_4 = 2,
158 FE_TER_FE_5_6 = 3,
159 FE_TER_FE_6_7 = 4,
160 FE_TER_FE_7_8 = 5
161};
162#endif
163
164enum stv0367_ter_force {
165 FE_TER_FORCENONE = 0,
166 FE_TER_FORCE_M_G = 1
167};
168
169enum stv0367cab_mod {
170 FE_CAB_MOD_QAM4,
171 FE_CAB_MOD_QAM16,
172 FE_CAB_MOD_QAM32,
173 FE_CAB_MOD_QAM64,
174 FE_CAB_MOD_QAM128,
175 FE_CAB_MOD_QAM256,
176 FE_CAB_MOD_QAM512,
177 FE_CAB_MOD_QAM1024
178};
179#if 0
180enum {
181 FE_CAB_FEC_A = 1, /* J83 Annex A */
182 FE_CAB_FEC_B = (1 << 1),/* J83 Annex B */
183 FE_CAB_FEC_C = (1 << 2) /* J83 Annex C */
184} FE_CAB_FECType_t;
185#endif
186struct stv0367_cab_signal_info {
187 int locked;
188 u32 frequency; /* kHz */
189 u32 symbol_rate; /* Mbds */
190 enum stv0367cab_mod modulation;
191 fe_spectral_inversion_t spect_inv;
192 s32 Power_dBmx10; /* Power of the RF signal (dBm x 10) */
193 u32 CN_dBx10; /* Carrier to noise ratio (dB x 10) */
194 u32 BER; /* Bit error rate (x 10000000) */
195};
196
197enum stv0367_cab_signal_type {
198 FE_CAB_NOTUNER,
199 FE_CAB_NOAGC,
200 FE_CAB_NOSIGNAL,
201 FE_CAB_NOTIMING,
202 FE_CAB_TIMINGOK,
203 FE_CAB_NOCARRIER,
204 FE_CAB_CARRIEROK,
205 FE_CAB_NOBLIND,
206 FE_CAB_BLINDOK,
207 FE_CAB_NODEMOD,
208 FE_CAB_DEMODOK,
209 FE_CAB_DATAOK
210};
211
212#endif
diff --git a/drivers/media/dvb/frontends/stv0367_regs.h b/drivers/media/dvb/frontends/stv0367_regs.h
new file mode 100644
index 00000000000..a96fbdc7e25
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0367_regs.h
@@ -0,0 +1,3614 @@
1/*
2 * stv0367_regs.h
3 *
4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef STV0367_REGS_H
27#define STV0367_REGS_H
28
29/* ID */
30#define R367TER_ID 0xf000
31#define F367TER_IDENTIFICATIONREG 0xf00000ff
32
33/* I2CRPT */
34#define R367TER_I2CRPT 0xf001
35#define F367TER_I2CT_ON 0xf0010080
36#define F367TER_ENARPT_LEVEL 0xf0010070
37#define F367TER_SCLT_DELAY 0xf0010008
38#define F367TER_SCLT_NOD 0xf0010004
39#define F367TER_STOP_ENABLE 0xf0010002
40#define F367TER_SDAT_NOD 0xf0010001
41
42/* TOPCTRL */
43#define R367TER_TOPCTRL 0xf002
44#define F367TER_STDBY 0xf0020080
45#define F367TER_STDBY_FEC 0xf0020040
46#define F367TER_STDBY_CORE 0xf0020020
47#define F367TER_QAM_COFDM 0xf0020010
48#define F367TER_TS_DIS 0xf0020008
49#define F367TER_DIR_CLK_216 0xf0020004
50#define F367TER_TUNER_BB 0xf0020002
51#define F367TER_DVBT_H 0xf0020001
52
53/* IOCFG0 */
54#define R367TER_IOCFG0 0xf003
55#define F367TER_OP0_SD 0xf0030080
56#define F367TER_OP0_VAL 0xf0030040
57#define F367TER_OP0_OD 0xf0030020
58#define F367TER_OP0_INV 0xf0030010
59#define F367TER_OP0_DACVALUE_HI 0xf003000f
60
61/* DAc0R */
62#define R367TER_DAC0R 0xf004
63#define F367TER_OP0_DACVALUE_LO 0xf00400ff
64
65/* IOCFG1 */
66#define R367TER_IOCFG1 0xf005
67#define F367TER_IP0 0xf0050040
68#define F367TER_OP1_OD 0xf0050020
69#define F367TER_OP1_INV 0xf0050010
70#define F367TER_OP1_DACVALUE_HI 0xf005000f
71
72/* DAC1R */
73#define R367TER_DAC1R 0xf006
74#define F367TER_OP1_DACVALUE_LO 0xf00600ff
75
76/* IOCFG2 */
77#define R367TER_IOCFG2 0xf007
78#define F367TER_OP2_LOCK_CONF 0xf00700e0
79#define F367TER_OP2_OD 0xf0070010
80#define F367TER_OP2_VAL 0xf0070008
81#define F367TER_OP1_LOCK_CONF 0xf0070007
82
83/* SDFR */
84#define R367TER_SDFR 0xf008
85#define F367TER_OP0_FREQ 0xf00800f0
86#define F367TER_OP1_FREQ 0xf008000f
87
88/* STATUS */
89#define R367TER_STATUS 0xf009
90#define F367TER_TPS_LOCK 0xf0090080
91#define F367TER_SYR_LOCK 0xf0090040
92#define F367TER_AGC_LOCK 0xf0090020
93#define F367TER_PRF 0xf0090010
94#define F367TER_LK 0xf0090008
95#define F367TER_PR 0xf0090007
96
97/* AUX_CLK */
98#define R367TER_AUX_CLK 0xf00a
99#define F367TER_AUXFEC_CTL 0xf00a00c0
100#define F367TER_DIS_CKX4 0xf00a0020
101#define F367TER_CKSEL 0xf00a0018
102#define F367TER_CKDIV_PROG 0xf00a0006
103#define F367TER_AUXCLK_ENA 0xf00a0001
104
105/* FREESYS1 */
106#define R367TER_FREESYS1 0xf00b
107#define F367TER_FREE_SYS1 0xf00b00ff
108
109/* FREESYS2 */
110#define R367TER_FREESYS2 0xf00c
111#define F367TER_FREE_SYS2 0xf00c00ff
112
113/* FREESYS3 */
114#define R367TER_FREESYS3 0xf00d
115#define F367TER_FREE_SYS3 0xf00d00ff
116
117/* GPIO_CFG */
118#define R367TER_GPIO_CFG 0xf00e
119#define F367TER_GPIO7_NOD 0xf00e0080
120#define F367TER_GPIO7_CFG 0xf00e0040
121#define F367TER_GPIO6_NOD 0xf00e0020
122#define F367TER_GPIO6_CFG 0xf00e0010
123#define F367TER_GPIO5_NOD 0xf00e0008
124#define F367TER_GPIO5_CFG 0xf00e0004
125#define F367TER_GPIO4_NOD 0xf00e0002
126#define F367TER_GPIO4_CFG 0xf00e0001
127
128/* GPIO_CMD */
129#define R367TER_GPIO_CMD 0xf00f
130#define F367TER_GPIO7_VAL 0xf00f0008
131#define F367TER_GPIO6_VAL 0xf00f0004
132#define F367TER_GPIO5_VAL 0xf00f0002
133#define F367TER_GPIO4_VAL 0xf00f0001
134
135/* AGC2MAX */
136#define R367TER_AGC2MAX 0xf010
137#define F367TER_AGC2_MAX 0xf01000ff
138
139/* AGC2MIN */
140#define R367TER_AGC2MIN 0xf011
141#define F367TER_AGC2_MIN 0xf01100ff
142
143/* AGC1MAX */
144#define R367TER_AGC1MAX 0xf012
145#define F367TER_AGC1_MAX 0xf01200ff
146
147/* AGC1MIN */
148#define R367TER_AGC1MIN 0xf013
149#define F367TER_AGC1_MIN 0xf01300ff
150
151/* AGCR */
152#define R367TER_AGCR 0xf014
153#define F367TER_RATIO_A 0xf01400e0
154#define F367TER_RATIO_B 0xf0140018
155#define F367TER_RATIO_C 0xf0140007
156
157/* AGC2TH */
158#define R367TER_AGC2TH 0xf015
159#define F367TER_AGC2_THRES 0xf01500ff
160
161/* AGC12c */
162#define R367TER_AGC12C 0xf016
163#define F367TER_AGC1_IV 0xf0160080
164#define F367TER_AGC1_OD 0xf0160040
165#define F367TER_AGC1_LOAD 0xf0160020
166#define F367TER_AGC2_IV 0xf0160010
167#define F367TER_AGC2_OD 0xf0160008
168#define F367TER_AGC2_LOAD 0xf0160004
169#define F367TER_AGC12_MODE 0xf0160003
170
171/* AGCCTRL1 */
172#define R367TER_AGCCTRL1 0xf017
173#define F367TER_DAGC_ON 0xf0170080
174#define F367TER_INVERT_AGC12 0xf0170040
175#define F367TER_AGC1_MODE 0xf0170008
176#define F367TER_AGC2_MODE 0xf0170007
177
178/* AGCCTRL2 */
179#define R367TER_AGCCTRL2 0xf018
180#define F367TER_FRZ2_CTRL 0xf0180060
181#define F367TER_FRZ1_CTRL 0xf0180018
182#define F367TER_TIME_CST 0xf0180007
183
184/* AGC1VAL1 */
185#define R367TER_AGC1VAL1 0xf019
186#define F367TER_AGC1_VAL_LO 0xf01900ff
187
188/* AGC1VAL2 */
189#define R367TER_AGC1VAL2 0xf01a
190#define F367TER_AGC1_VAL_HI 0xf01a000f
191
192/* AGC2VAL1 */
193#define R367TER_AGC2VAL1 0xf01b
194#define F367TER_AGC2_VAL_LO 0xf01b00ff
195
196/* AGC2VAL2 */
197#define R367TER_AGC2VAL2 0xf01c
198#define F367TER_AGC2_VAL_HI 0xf01c000f
199
200/* AGC2PGA */
201#define R367TER_AGC2PGA 0xf01d
202#define F367TER_AGC2_PGA 0xf01d00ff
203
204/* OVF_RATE1 */
205#define R367TER_OVF_RATE1 0xf01e
206#define F367TER_OVF_RATE_HI 0xf01e000f
207
208/* OVF_RATE2 */
209#define R367TER_OVF_RATE2 0xf01f
210#define F367TER_OVF_RATE_LO 0xf01f00ff
211
212/* GAIN_SRC1 */
213#define R367TER_GAIN_SRC1 0xf020
214#define F367TER_INV_SPECTR 0xf0200080
215#define F367TER_IQ_INVERT 0xf0200040
216#define F367TER_INR_BYPASS 0xf0200020
217#define F367TER_STATUS_INV_SPECRUM 0xf0200010
218#define F367TER_GAIN_SRC_HI 0xf020000f
219
220/* GAIN_SRC2 */
221#define R367TER_GAIN_SRC2 0xf021
222#define F367TER_GAIN_SRC_LO 0xf02100ff
223
224/* INC_DEROT1 */
225#define R367TER_INC_DEROT1 0xf022
226#define F367TER_INC_DEROT_HI 0xf02200ff
227
228/* INC_DEROT2 */
229#define R367TER_INC_DEROT2 0xf023
230#define F367TER_INC_DEROT_LO 0xf02300ff
231
232/* PPM_CPAMP_DIR */
233#define R367TER_PPM_CPAMP_DIR 0xf024
234#define F367TER_PPM_CPAMP_DIRECT 0xf02400ff
235
236/* PPM_CPAMP_INV */
237#define R367TER_PPM_CPAMP_INV 0xf025
238#define F367TER_PPM_CPAMP_INVER 0xf02500ff
239
240/* FREESTFE_1 */
241#define R367TER_FREESTFE_1 0xf026
242#define F367TER_SYMBOL_NUMBER_INC 0xf02600c0
243#define F367TER_SEL_LSB 0xf0260004
244#define F367TER_AVERAGE_ON 0xf0260002
245#define F367TER_DC_ADJ 0xf0260001
246
247/* FREESTFE_2 */
248#define R367TER_FREESTFE_2 0xf027
249#define F367TER_SEL_SRCOUT 0xf02700c0
250#define F367TER_SEL_SYRTHR 0xf027001f
251
252/* DCOFFSET */
253#define R367TER_DCOFFSET 0xf028
254#define F367TER_SELECT_I_Q 0xf0280080
255#define F367TER_DC_OFFSET 0xf028007f
256
257/* EN_PROCESS */
258#define R367TER_EN_PROCESS 0xf029
259#define F367TER_FREE 0xf02900f0
260#define F367TER_ENAB_MANUAL 0xf0290001
261
262/* SDI_SMOOTHER */
263#define R367TER_SDI_SMOOTHER 0xf02a
264#define F367TER_DIS_SMOOTH 0xf02a0080
265#define F367TER_SDI_INC_SMOOTHER 0xf02a007f
266
267/* FE_LOOP_OPEN */
268#define R367TER_FE_LOOP_OPEN 0xf02b
269#define F367TER_TRL_LOOP_OP 0xf02b0002
270#define F367TER_CRL_LOOP_OP 0xf02b0001
271
272/* FREQOFF1 */
273#define R367TER_FREQOFF1 0xf02c
274#define F367TER_FREQ_OFFSET_LOOP_OPEN_VHI 0xf02c00ff
275
276/* FREQOFF2 */
277#define R367TER_FREQOFF2 0xf02d
278#define F367TER_FREQ_OFFSET_LOOP_OPEN_HI 0xf02d00ff
279
280/* FREQOFF3 */
281#define R367TER_FREQOFF3 0xf02e
282#define F367TER_FREQ_OFFSET_LOOP_OPEN_LO 0xf02e00ff
283
284/* TIMOFF1 */
285#define R367TER_TIMOFF1 0xf02f
286#define F367TER_TIM_OFFSET_LOOP_OPEN_HI 0xf02f00ff
287
288/* TIMOFF2 */
289#define R367TER_TIMOFF2 0xf030
290#define F367TER_TIM_OFFSET_LOOP_OPEN_LO 0xf03000ff
291
292/* EPQ */
293#define R367TER_EPQ 0xf031
294#define F367TER_EPQ1 0xf03100ff
295
296/* EPQAUTO */
297#define R367TER_EPQAUTO 0xf032
298#define F367TER_EPQ2 0xf03200ff
299
300/* SYR_UPDATE */
301#define R367TER_SYR_UPDATE 0xf033
302#define F367TER_SYR_PROTV 0xf0330080
303#define F367TER_SYR_PROTV_GAIN 0xf0330060
304#define F367TER_SYR_FILTER 0xf0330010
305#define F367TER_SYR_TRACK_THRES 0xf033000c
306
307/* CHPFREE */
308#define R367TER_CHPFREE 0xf034
309#define F367TER_CHP_FREE 0xf03400ff
310
311/* PPM_STATE_MAC */
312#define R367TER_PPM_STATE_MAC 0xf035
313#define F367TER_PPM_STATE_MACHINE_DECODER 0xf035003f
314
315/* INR_THRESHOLD */
316#define R367TER_INR_THRESHOLD 0xf036
317#define F367TER_INR_THRESH 0xf03600ff
318
319/* EPQ_TPS_ID_CELL */
320#define R367TER_EPQ_TPS_ID_CELL 0xf037
321#define F367TER_ENABLE_LGTH_TO_CF 0xf0370080
322#define F367TER_DIS_TPS_RSVD 0xf0370040
323#define F367TER_DIS_BCH 0xf0370020
324#define F367TER_DIS_ID_CEL 0xf0370010
325#define F367TER_TPS_ADJUST_SYM 0xf037000f
326
327/* EPQ_CFG */
328#define R367TER_EPQ_CFG 0xf038
329#define F367TER_EPQ_RANGE 0xf0380002
330#define F367TER_EPQ_SOFT 0xf0380001
331
332/* EPQ_STATUS */
333#define R367TER_EPQ_STATUS 0xf039
334#define F367TER_SLOPE_INC 0xf03900fc
335#define F367TER_TPS_FIELD 0xf0390003
336
337/* AUTORELOCK */
338#define R367TER_AUTORELOCK 0xf03a
339#define F367TER_BYPASS_BER_TEMPO 0xf03a0080
340#define F367TER_BER_TEMPO 0xf03a0070
341#define F367TER_BYPASS_COFDM_TEMPO 0xf03a0008
342#define F367TER_COFDM_TEMPO 0xf03a0007
343
344/* BER_THR_VMSB */
345#define R367TER_BER_THR_VMSB 0xf03b
346#define F367TER_BER_THRESHOLD_HI 0xf03b00ff
347
348/* BER_THR_MSB */
349#define R367TER_BER_THR_MSB 0xf03c
350#define F367TER_BER_THRESHOLD_MID 0xf03c00ff
351
352/* BER_THR_LSB */
353#define R367TER_BER_THR_LSB 0xf03d
354#define F367TER_BER_THRESHOLD_LO 0xf03d00ff
355
356/* CCD */
357#define R367TER_CCD 0xf03e
358#define F367TER_CCD_DETECTED 0xf03e0080
359#define F367TER_CCD_RESET 0xf03e0040
360#define F367TER_CCD_THRESHOLD 0xf03e000f
361
362/* SPECTR_CFG */
363#define R367TER_SPECTR_CFG 0xf03f
364#define F367TER_SPECT_CFG 0xf03f0003
365
366/* CONSTMU_MSB */
367#define R367TER_CONSTMU_MSB 0xf040
368#define F367TER_CONSTMU_FREEZE 0xf0400080
369#define F367TER_CONSTNU_FORCE_EN 0xf0400040
370#define F367TER_CONST_MU_MSB 0xf040003f
371
372/* CONSTMU_LSB */
373#define R367TER_CONSTMU_LSB 0xf041
374#define F367TER_CONST_MU_LSB 0xf04100ff
375
376/* CONSTMU_MAX_MSB */
377#define R367TER_CONSTMU_MAX_MSB 0xf042
378#define F367TER_CONST_MU_MAX_MSB 0xf042003f
379
380/* CONSTMU_MAX_LSB */
381#define R367TER_CONSTMU_MAX_LSB 0xf043
382#define F367TER_CONST_MU_MAX_LSB 0xf04300ff
383
384/* ALPHANOISE */
385#define R367TER_ALPHANOISE 0xf044
386#define F367TER_USE_ALLFILTER 0xf0440080
387#define F367TER_INTER_ON 0xf0440040
388#define F367TER_ALPHA_NOISE 0xf044001f
389
390/* MAXGP_MSB */
391#define R367TER_MAXGP_MSB 0xf045
392#define F367TER_MUFILTER_LENGTH 0xf04500f0
393#define F367TER_MAX_GP_MSB 0xf045000f
394
395/* MAXGP_LSB */
396#define R367TER_MAXGP_LSB 0xf046
397#define F367TER_MAX_GP_LSB 0xf04600ff
398
399/* ALPHAMSB */
400#define R367TER_ALPHAMSB 0xf047
401#define F367TER_CHC_DATARATE 0xf04700c0
402#define F367TER_ALPHA_MSB 0xf047003f
403
404/* ALPHALSB */
405#define R367TER_ALPHALSB 0xf048
406#define F367TER_ALPHA_LSB 0xf04800ff
407
408/* PILOT_ACCU */
409#define R367TER_PILOT_ACCU 0xf049
410#define F367TER_USE_SCAT4ADDAPT 0xf0490080
411#define F367TER_PILOT_ACC 0xf049001f
412
413/* PILOTMU_ACCU */
414#define R367TER_PILOTMU_ACCU 0xf04a
415#define F367TER_DISCARD_BAD_SP 0xf04a0080
416#define F367TER_DISCARD_BAD_CP 0xf04a0040
417#define F367TER_PILOT_MU_ACCU 0xf04a001f
418
419/* FILT_CHANNEL_EST */
420#define R367TER_FILT_CHANNEL_EST 0xf04b
421#define F367TER_USE_FILT_PILOT 0xf04b0080
422#define F367TER_FILT_CHANNEL 0xf04b007f
423
424/* ALPHA_NOPISE_FREQ */
425#define R367TER_ALPHA_NOPISE_FREQ 0xf04c
426#define F367TER_NOISE_FREQ_FILT 0xf04c0040
427#define F367TER_ALPHA_NOISE_FREQ 0xf04c003f
428
429/* RATIO_PILOT */
430#define R367TER_RATIO_PILOT 0xf04d
431#define F367TER_RATIO_MEAN_SP 0xf04d00f0
432#define F367TER_RATIO_MEAN_CP 0xf04d000f
433
434/* CHC_CTL */
435#define R367TER_CHC_CTL 0xf04e
436#define F367TER_TRACK_EN 0xf04e0080
437#define F367TER_NOISE_NORM_EN 0xf04e0040
438#define F367TER_FORCE_CHC_RESET 0xf04e0020
439#define F367TER_SHORT_TIME 0xf04e0010
440#define F367TER_FORCE_STATE_EN 0xf04e0008
441#define F367TER_FORCE_STATE 0xf04e0007
442
443/* EPQ_ADJUST */
444#define R367TER_EPQ_ADJUST 0xf04f
445#define F367TER_ADJUST_SCAT_IND 0xf04f00c0
446#define F367TER_ONE_SYMBOL 0xf04f0010
447#define F367TER_EPQ_DECAY 0xf04f000e
448#define F367TER_HOLD_SLOPE 0xf04f0001
449
450/* EPQ_THRES */
451#define R367TER_EPQ_THRES 0xf050
452#define F367TER_EPQ_THR 0xf05000ff
453
454/* OMEGA_CTL */
455#define R367TER_OMEGA_CTL 0xf051
456#define F367TER_OMEGA_RST 0xf0510080
457#define F367TER_FREEZE_OMEGA 0xf0510040
458#define F367TER_OMEGA_SEL 0xf051003f
459
460/* GP_CTL */
461#define R367TER_GP_CTL 0xf052
462#define F367TER_CHC_STATE 0xf05200e0
463#define F367TER_FREEZE_GP 0xf0520010
464#define F367TER_GP_SEL 0xf052000f
465
466/* MUMSB */
467#define R367TER_MUMSB 0xf053
468#define F367TER_MU_MSB 0xf053007f
469
470/* MULSB */
471#define R367TER_MULSB 0xf054
472#define F367TER_MU_LSB 0xf05400ff
473
474/* GPMSB */
475#define R367TER_GPMSB 0xf055
476#define F367TER_CSI_THRESHOLD 0xf05500e0
477#define F367TER_GP_MSB 0xf055000f
478
479/* GPLSB */
480#define R367TER_GPLSB 0xf056
481#define F367TER_GP_LSB 0xf05600ff
482
483/* OMEGAMSB */
484#define R367TER_OMEGAMSB 0xf057
485#define F367TER_OMEGA_MSB 0xf057007f
486
487/* OMEGALSB */
488#define R367TER_OMEGALSB 0xf058
489#define F367TER_OMEGA_LSB 0xf05800ff
490
491/* SCAT_NB */
492#define R367TER_SCAT_NB 0xf059
493#define F367TER_CHC_TEST 0xf05900f8
494#define F367TER_SCAT_NUMB 0xf0590003
495
496/* CHC_DUMMY */
497#define R367TER_CHC_DUMMY 0xf05a
498#define F367TER_CHC_DUM 0xf05a00ff
499
500/* INC_CTL */
501#define R367TER_INC_CTL 0xf05b
502#define F367TER_INC_BYPASS 0xf05b0080
503#define F367TER_INC_NDEPTH 0xf05b000c
504#define F367TER_INC_MADEPTH 0xf05b0003
505
506/* INCTHRES_COR1 */
507#define R367TER_INCTHRES_COR1 0xf05c
508#define F367TER_INC_THRES_COR1 0xf05c00ff
509
510/* INCTHRES_COR2 */
511#define R367TER_INCTHRES_COR2 0xf05d
512#define F367TER_INC_THRES_COR2 0xf05d00ff
513
514/* INCTHRES_DET1 */
515#define R367TER_INCTHRES_DET1 0xf05e
516#define F367TER_INC_THRES_DET1 0xf05e003f
517
518/* INCTHRES_DET2 */
519#define R367TER_INCTHRES_DET2 0xf05f
520#define F367TER_INC_THRES_DET2 0xf05f003f
521
522/* IIR_CELLNB */
523#define R367TER_IIR_CELLNB 0xf060
524#define F367TER_NRST_IIR 0xf0600080
525#define F367TER_IIR_CELL_NB 0xf0600007
526
527/* IIRCX_COEFF1_MSB */
528#define R367TER_IIRCX_COEFF1_MSB 0xf061
529#define F367TER_IIR_CX_COEFF1_MSB 0xf06100ff
530
531/* IIRCX_COEFF1_LSB */
532#define R367TER_IIRCX_COEFF1_LSB 0xf062
533#define F367TER_IIR_CX_COEFF1_LSB 0xf06200ff
534
535/* IIRCX_COEFF2_MSB */
536#define R367TER_IIRCX_COEFF2_MSB 0xf063
537#define F367TER_IIR_CX_COEFF2_MSB 0xf06300ff
538
539/* IIRCX_COEFF2_LSB */
540#define R367TER_IIRCX_COEFF2_LSB 0xf064
541#define F367TER_IIR_CX_COEFF2_LSB 0xf06400ff
542
543/* IIRCX_COEFF3_MSB */
544#define R367TER_IIRCX_COEFF3_MSB 0xf065
545#define F367TER_IIR_CX_COEFF3_MSB 0xf06500ff
546
547/* IIRCX_COEFF3_LSB */
548#define R367TER_IIRCX_COEFF3_LSB 0xf066
549#define F367TER_IIR_CX_COEFF3_LSB 0xf06600ff
550
551/* IIRCX_COEFF4_MSB */
552#define R367TER_IIRCX_COEFF4_MSB 0xf067
553#define F367TER_IIR_CX_COEFF4_MSB 0xf06700ff
554
555/* IIRCX_COEFF4_LSB */
556#define R367TER_IIRCX_COEFF4_LSB 0xf068
557#define F367TER_IIR_CX_COEFF4_LSB 0xf06800ff
558
559/* IIRCX_COEFF5_MSB */
560#define R367TER_IIRCX_COEFF5_MSB 0xf069
561#define F367TER_IIR_CX_COEFF5_MSB 0xf06900ff
562
563/* IIRCX_COEFF5_LSB */
564#define R367TER_IIRCX_COEFF5_LSB 0xf06a
565#define F367TER_IIR_CX_COEFF5_LSB 0xf06a00ff
566
567/* FEPATH_CFG */
568#define R367TER_FEPATH_CFG 0xf06b
569#define F367TER_DEMUX_SWAP 0xf06b0004
570#define F367TER_DIGAGC_SWAP 0xf06b0002
571#define F367TER_LONGPATH_IF 0xf06b0001
572
573/* PMC1_FUNC */
574#define R367TER_PMC1_FUNC 0xf06c
575#define F367TER_SOFT_RSTN 0xf06c0080
576#define F367TER_PMC1_AVERAGE_TIME 0xf06c0078
577#define F367TER_PMC1_WAIT_TIME 0xf06c0006
578#define F367TER_PMC1_2N_SEL 0xf06c0001
579
580/* PMC1_FOR */
581#define R367TER_PMC1_FOR 0xf06d
582#define F367TER_PMC1_FORCE 0xf06d0080
583#define F367TER_PMC1_FORCE_VALUE 0xf06d007c
584
585/* PMC2_FUNC */
586#define R367TER_PMC2_FUNC 0xf06e
587#define F367TER_PMC2_SOFT_STN 0xf06e0080
588#define F367TER_PMC2_ACCU_TIME 0xf06e0070
589#define F367TER_PMC2_CMDP_MN 0xf06e0008
590#define F367TER_PMC2_SWAP 0xf06e0004
591
592/* STATUS_ERR_DA */
593#define R367TER_STATUS_ERR_DA 0xf06f
594#define F367TER_COM_USEGAINTRK 0xf06f0080
595#define F367TER_COM_AGCLOCK 0xf06f0040
596#define F367TER_AUT_AGCLOCK 0xf06f0020
597#define F367TER_MIN_ERR_X_LSB 0xf06f000f
598
599/* DIG_AGC_R */
600#define R367TER_DIG_AGC_R 0xf070
601#define F367TER_COM_SOFT_RSTN 0xf0700080
602#define F367TER_COM_AGC_ON 0xf0700040
603#define F367TER_COM_EARLY 0xf0700020
604#define F367TER_AUT_SOFT_RESETN 0xf0700010
605#define F367TER_AUT_AGC_ON 0xf0700008
606#define F367TER_AUT_EARLY 0xf0700004
607#define F367TER_AUT_ROT_EN 0xf0700002
608#define F367TER_LOCK_SOFT_RESETN 0xf0700001
609
610/* COMAGC_TARMSB */
611#define R367TER_COMAGC_TARMSB 0xf071
612#define F367TER_COM_AGC_TARGET_MSB 0xf07100ff
613
614/* COM_AGC_TAR_ENMODE */
615#define R367TER_COM_AGC_TAR_ENMODE 0xf072
616#define F367TER_COM_AGC_TARGET_LSB 0xf07200f0
617#define F367TER_COM_ENMODE 0xf072000f
618
619/* COM_AGC_CFG */
620#define R367TER_COM_AGC_CFG 0xf073
621#define F367TER_COM_N 0xf07300f8
622#define F367TER_COM_STABMODE 0xf0730006
623#define F367TER_ERR_SEL 0xf0730001
624
625/* COM_AGC_GAIN1 */
626#define R367TER_COM_AGC_GAIN1 0xf074
627#define F367TER_COM_GAIN1aCK 0xf07400f0
628#define F367TER_COM_GAIN1TRK 0xf074000f
629
630/* AUT_AGC_TARGETMSB */
631#define R367TER_AUT_AGC_TARGETMSB 0xf075
632#define F367TER_AUT_AGC_TARGET_MSB 0xf07500ff
633
634/* LOCK_DET_MSB */
635#define R367TER_LOCK_DET_MSB 0xf076
636#define F367TER_LOCK_DETECT_MSB 0xf07600ff
637
638/* AGCTAR_LOCK_LSBS */
639#define R367TER_AGCTAR_LOCK_LSBS 0xf077
640#define F367TER_AUT_AGC_TARGET_LSB 0xf07700f0
641#define F367TER_LOCK_DETECT_LSB 0xf077000f
642
643/* AUT_GAIN_EN */
644#define R367TER_AUT_GAIN_EN 0xf078
645#define F367TER_AUT_ENMODE 0xf07800f0
646#define F367TER_AUT_GAIN2 0xf078000f
647
648/* AUT_CFG */
649#define R367TER_AUT_CFG 0xf079
650#define F367TER_AUT_N 0xf07900f8
651#define F367TER_INT_CHOICE 0xf0790006
652#define F367TER_INT_LOAD 0xf0790001
653
654/* LOCKN */
655#define R367TER_LOCKN 0xf07a
656#define F367TER_LOCK_N 0xf07a00f8
657#define F367TER_SEL_IQNTAR 0xf07a0004
658#define F367TER_LOCK_DETECT_CHOICE 0xf07a0003
659
660/* INT_X_3 */
661#define R367TER_INT_X_3 0xf07b
662#define F367TER_INT_X3 0xf07b00ff
663
664/* INT_X_2 */
665#define R367TER_INT_X_2 0xf07c
666#define F367TER_INT_X2 0xf07c00ff
667
668/* INT_X_1 */
669#define R367TER_INT_X_1 0xf07d
670#define F367TER_INT_X1 0xf07d00ff
671
672/* INT_X_0 */
673#define R367TER_INT_X_0 0xf07e
674#define F367TER_INT_X0 0xf07e00ff
675
676/* MIN_ERRX_MSB */
677#define R367TER_MIN_ERRX_MSB 0xf07f
678#define F367TER_MIN_ERR_X_MSB 0xf07f00ff
679
680/* COR_CTL */
681#define R367TER_COR_CTL 0xf080
682#define F367TER_CORE_ACTIVE 0xf0800020
683#define F367TER_HOLD 0xf0800010
684#define F367TER_CORE_STATE_CTL 0xf080000f
685
686/* COR_STAT */
687#define R367TER_COR_STAT 0xf081
688#define F367TER_SCATT_LOCKED 0xf0810080
689#define F367TER_TPS_LOCKED 0xf0810040
690#define F367TER_SYR_LOCKED_COR 0xf0810020
691#define F367TER_AGC_LOCKED_STAT 0xf0810010
692#define F367TER_CORE_STATE_STAT 0xf081000f
693
694/* COR_INTEN */
695#define R367TER_COR_INTEN 0xf082
696#define F367TER_INTEN 0xf0820080
697#define F367TER_INTEN_SYR 0xf0820020
698#define F367TER_INTEN_FFT 0xf0820010
699#define F367TER_INTEN_AGC 0xf0820008
700#define F367TER_INTEN_TPS1 0xf0820004
701#define F367TER_INTEN_TPS2 0xf0820002
702#define F367TER_INTEN_TPS3 0xf0820001
703
704/* COR_INTSTAT */
705#define R367TER_COR_INTSTAT 0xf083
706#define F367TER_INTSTAT_SYR 0xf0830020
707#define F367TER_INTSTAT_FFT 0xf0830010
708#define F367TER_INTSAT_AGC 0xf0830008
709#define F367TER_INTSTAT_TPS1 0xf0830004
710#define F367TER_INTSTAT_TPS2 0xf0830002
711#define F367TER_INTSTAT_TPS3 0xf0830001
712
713/* COR_MODEGUARD */
714#define R367TER_COR_MODEGUARD 0xf084
715#define F367TER_FORCE 0xf0840010
716#define F367TER_MODE 0xf084000c
717#define F367TER_GUARD 0xf0840003
718
719/* AGC_CTL */
720#define R367TER_AGC_CTL 0xf085
721#define F367TER_AGC_TIMING_FACTOR 0xf08500e0
722#define F367TER_AGC_LAST 0xf0850010
723#define F367TER_AGC_GAIN 0xf085000c
724#define F367TER_AGC_NEG 0xf0850002
725#define F367TER_AGC_SET 0xf0850001
726
727/* AGC_MANUAL1 */
728#define R367TER_AGC_MANUAL1 0xf086
729#define F367TER_AGC_VAL_LO 0xf08600ff
730
731/* AGC_MANUAL2 */
732#define R367TER_AGC_MANUAL2 0xf087
733#define F367TER_AGC_VAL_HI 0xf087000f
734
735/* AGC_TARG */
736#define R367TER_AGC_TARG 0xf088
737#define F367TER_AGC_TARGET 0xf08800ff
738
739/* AGC_GAIN1 */
740#define R367TER_AGC_GAIN1 0xf089
741#define F367TER_AGC_GAIN_LO 0xf08900ff
742
743/* AGC_GAIN2 */
744#define R367TER_AGC_GAIN2 0xf08a
745#define F367TER_AGC_LOCKED_GAIN2 0xf08a0010
746#define F367TER_AGC_GAIN_HI 0xf08a000f
747
748/* RESERVED_1 */
749#define R367TER_RESERVED_1 0xf08b
750#define F367TER_RESERVED1 0xf08b00ff
751
752/* RESERVED_2 */
753#define R367TER_RESERVED_2 0xf08c
754#define F367TER_RESERVED2 0xf08c00ff
755
756/* RESERVED_3 */
757#define R367TER_RESERVED_3 0xf08d
758#define F367TER_RESERVED3 0xf08d00ff
759
760/* CAS_CTL */
761#define R367TER_CAS_CTL 0xf08e
762#define F367TER_CCS_ENABLE 0xf08e0080
763#define F367TER_ACS_DISABLE 0xf08e0040
764#define F367TER_DAGC_DIS 0xf08e0020
765#define F367TER_DAGC_GAIN 0xf08e0018
766#define F367TER_CCSMU 0xf08e0007
767
768/* CAS_FREQ */
769#define R367TER_CAS_FREQ 0xf08f
770#define F367TER_CCS_FREQ 0xf08f00ff
771
772/* CAS_DAGCGAIN */
773#define R367TER_CAS_DAGCGAIN 0xf090
774#define F367TER_CAS_DAGC_GAIN 0xf09000ff
775
776/* SYR_CTL */
777#define R367TER_SYR_CTL 0xf091
778#define F367TER_SICTH_ENABLE 0xf0910080
779#define F367TER_LONG_ECHO 0xf0910078
780#define F367TER_AUTO_LE_EN 0xf0910004
781#define F367TER_SYR_BYPASS 0xf0910002
782#define F367TER_SYR_TR_DIS 0xf0910001
783
784/* SYR_STAT */
785#define R367TER_SYR_STAT 0xf092
786#define F367TER_SYR_LOCKED_STAT 0xf0920010
787#define F367TER_SYR_MODE 0xf092000c
788#define F367TER_SYR_GUARD 0xf0920003
789
790/* SYR_NCO1 */
791#define R367TER_SYR_NCO1 0xf093
792#define F367TER_SYR_NCO_LO 0xf09300ff
793
794/* SYR_NCO2 */
795#define R367TER_SYR_NCO2 0xf094
796#define F367TER_SYR_NCO_HI 0xf094003f
797
798/* SYR_OFFSET1 */
799#define R367TER_SYR_OFFSET1 0xf095
800#define F367TER_SYR_OFFSET_LO 0xf09500ff
801
802/* SYR_OFFSET2 */
803#define R367TER_SYR_OFFSET2 0xf096
804#define F367TER_SYR_OFFSET_HI 0xf096003f
805
806/* FFT_CTL */
807#define R367TER_FFT_CTL 0xf097
808#define F367TER_SHIFT_FFT_TRIG 0xf0970018
809#define F367TER_FFT_TRIGGER 0xf0970004
810#define F367TER_FFT_MANUAL 0xf0970002
811#define F367TER_IFFT_MODE 0xf0970001
812
813/* SCR_CTL */
814#define R367TER_SCR_CTL 0xf098
815#define F367TER_SYRADJDECAY 0xf0980070
816#define F367TER_SCR_CPEDIS 0xf0980002
817#define F367TER_SCR_DIS 0xf0980001
818
819/* PPM_CTL1 */
820#define R367TER_PPM_CTL1 0xf099
821#define F367TER_PPM_MAXFREQ 0xf0990030
822#define F367TER_PPM_MAXTIM 0xf0990008
823#define F367TER_PPM_INVSEL 0xf0990004
824#define F367TER_PPM_SCATDIS 0xf0990002
825#define F367TER_PPM_BYP 0xf0990001
826
827/* TRL_CTL */
828#define R367TER_TRL_CTL 0xf09a
829#define F367TER_TRL_NOMRATE_LSB 0xf09a0080
830#define F367TER_TRL_GAIN_FACTOR 0xf09a0078
831#define F367TER_TRL_LOOPGAIN 0xf09a0007
832
833/* TRL_NOMRATE1 */
834#define R367TER_TRL_NOMRATE1 0xf09b
835#define F367TER_TRL_NOMRATE_LO 0xf09b00ff
836
837/* TRL_NOMRATE2 */
838#define R367TER_TRL_NOMRATE2 0xf09c
839#define F367TER_TRL_NOMRATE_HI 0xf09c00ff
840
841/* TRL_TIME1 */
842#define R367TER_TRL_TIME1 0xf09d
843#define F367TER_TRL_TOFFSET_LO 0xf09d00ff
844
845/* TRL_TIME2 */
846#define R367TER_TRL_TIME2 0xf09e
847#define F367TER_TRL_TOFFSET_HI 0xf09e00ff
848
849/* CRL_CTL */
850#define R367TER_CRL_CTL 0xf09f
851#define F367TER_CRL_DIS 0xf09f0080
852#define F367TER_CRL_GAIN_FACTOR 0xf09f0078
853#define F367TER_CRL_LOOPGAIN 0xf09f0007
854
855/* CRL_FREQ1 */
856#define R367TER_CRL_FREQ1 0xf0a0
857#define F367TER_CRL_FOFFSET_LO 0xf0a000ff
858
859/* CRL_FREQ2 */
860#define R367TER_CRL_FREQ2 0xf0a1
861#define F367TER_CRL_FOFFSET_HI 0xf0a100ff
862
863/* CRL_FREQ3 */
864#define R367TER_CRL_FREQ3 0xf0a2
865#define F367TER_CRL_FOFFSET_VHI 0xf0a200ff
866
867/* TPS_SFRAME_CTL */
868#define R367TER_TPS_SFRAME_CTL 0xf0a3
869#define F367TER_TPS_SFRAME_SYNC 0xf0a30001
870
871/* CHC_SNR */
872#define R367TER_CHC_SNR 0xf0a4
873#define F367TER_CHCSNR 0xf0a400ff
874
875/* BDI_CTL */
876#define R367TER_BDI_CTL 0xf0a5
877#define F367TER_BDI_LPSEL 0xf0a50002
878#define F367TER_BDI_SERIAL 0xf0a50001
879
880/* DMP_CTL */
881#define R367TER_DMP_CTL 0xf0a6
882#define F367TER_DMP_SCALING_FACTOR 0xf0a6001e
883#define F367TER_DMP_SDDIS 0xf0a60001
884
885/* TPS_RCVD1 */
886#define R367TER_TPS_RCVD1 0xf0a7
887#define F367TER_TPS_CHANGE 0xf0a70040
888#define F367TER_BCH_OK 0xf0a70020
889#define F367TER_TPS_SYNC 0xf0a70010
890#define F367TER_TPS_FRAME 0xf0a70003
891
892/* TPS_RCVD2 */
893#define R367TER_TPS_RCVD2 0xf0a8
894#define F367TER_TPS_HIERMODE 0xf0a80070
895#define F367TER_TPS_CONST 0xf0a80003
896
897/* TPS_RCVD3 */
898#define R367TER_TPS_RCVD3 0xf0a9
899#define F367TER_TPS_LPCODE 0xf0a90070
900#define F367TER_TPS_HPCODE 0xf0a90007
901
902/* TPS_RCVD4 */
903#define R367TER_TPS_RCVD4 0xf0aa
904#define F367TER_TPS_GUARD 0xf0aa0030
905#define F367TER_TPS_MODE 0xf0aa0003
906
907/* TPS_ID_CELL1 */
908#define R367TER_TPS_ID_CELL1 0xf0ab
909#define F367TER_TPS_ID_CELL_LO 0xf0ab00ff
910
911/* TPS_ID_CELL2 */
912#define R367TER_TPS_ID_CELL2 0xf0ac
913#define F367TER_TPS_ID_CELL_HI 0xf0ac00ff
914
915/* TPS_RCVD5_SET1 */
916#define R367TER_TPS_RCVD5_SET1 0xf0ad
917#define F367TER_TPS_NA 0xf0ad00fC
918#define F367TER_TPS_SETFRAME 0xf0ad0003
919
920/* TPS_SET2 */
921#define R367TER_TPS_SET2 0xf0ae
922#define F367TER_TPS_SETHIERMODE 0xf0ae0070
923#define F367TER_TPS_SETCONST 0xf0ae0003
924
925/* TPS_SET3 */
926#define R367TER_TPS_SET3 0xf0af
927#define F367TER_TPS_SETLPCODE 0xf0af0070
928#define F367TER_TPS_SETHPCODE 0xf0af0007
929
930/* TPS_CTL */
931#define R367TER_TPS_CTL 0xf0b0
932#define F367TER_TPS_IMM 0xf0b00004
933#define F367TER_TPS_BCHDIS 0xf0b00002
934#define F367TER_TPS_UPDDIS 0xf0b00001
935
936/* CTL_FFTOSNUM */
937#define R367TER_CTL_FFTOSNUM 0xf0b1
938#define F367TER_SYMBOL_NUMBER 0xf0b1007f
939
940/* TESTSELECT */
941#define R367TER_TESTSELECT 0xf0b2
942#define F367TER_TEST_SELECT 0xf0b2001f
943
944/* MSC_REV */
945#define R367TER_MSC_REV 0xf0b3
946#define F367TER_REV_NUMBER 0xf0b300ff
947
948/* PIR_CTL */
949#define R367TER_PIR_CTL 0xf0b4
950#define F367TER_FREEZE 0xf0b40001
951
952/* SNR_CARRIER1 */
953#define R367TER_SNR_CARRIER1 0xf0b5
954#define F367TER_SNR_CARRIER_LO 0xf0b500ff
955
956/* SNR_CARRIER2 */
957#define R367TER_SNR_CARRIER2 0xf0b6
958#define F367TER_MEAN 0xf0b600c0
959#define F367TER_SNR_CARRIER_HI 0xf0b6001f
960
961/* PPM_CPAMP */
962#define R367TER_PPM_CPAMP 0xf0b7
963#define F367TER_PPM_CPC 0xf0b700ff
964
965/* TSM_AP0 */
966#define R367TER_TSM_AP0 0xf0b8
967#define F367TER_ADDRESS_BYTE_0 0xf0b800ff
968
969/* TSM_AP1 */
970#define R367TER_TSM_AP1 0xf0b9
971#define F367TER_ADDRESS_BYTE_1 0xf0b900ff
972
973/* TSM_AP2 */
974#define R367TER_TSM_AP2 0xf0bA
975#define F367TER_DATA_BYTE_0 0xf0ba00ff
976
977/* TSM_AP3 */
978#define R367TER_TSM_AP3 0xf0bB
979#define F367TER_DATA_BYTE_1 0xf0bb00ff
980
981/* TSM_AP4 */
982#define R367TER_TSM_AP4 0xf0bC
983#define F367TER_DATA_BYTE_2 0xf0bc00ff
984
985/* TSM_AP5 */
986#define R367TER_TSM_AP5 0xf0bD
987#define F367TER_DATA_BYTE_3 0xf0bd00ff
988
989/* TSM_AP6 */
990#define R367TER_TSM_AP6 0xf0bE
991#define F367TER_TSM_AP_6 0xf0be00ff
992
993/* TSM_AP7 */
994#define R367TER_TSM_AP7 0xf0bF
995#define F367TER_MEM_SELECT_BYTE 0xf0bf00ff
996
997/* TSTRES */
998#define R367TER_TSTRES 0xf0c0
999#define F367TER_FRES_DISPLAY 0xf0c00080
1000#define F367TER_FRES_FIFO_AD 0xf0c00020
1001#define F367TER_FRESRS 0xf0c00010
1002#define F367TER_FRESACS 0xf0c00008
1003#define F367TER_FRESFEC 0xf0c00004
1004#define F367TER_FRES_PRIF 0xf0c00002
1005#define F367TER_FRESCORE 0xf0c00001
1006
1007/* ANACTRL */
1008#define R367TER_ANACTRL 0xf0c1
1009#define F367TER_BYPASS_XTAL 0xf0c10040
1010#define F367TER_BYPASS_PLLXN 0xf0c1000c
1011#define F367TER_DIS_PAD_OSC 0xf0c10002
1012#define F367TER_STDBY_PLLXN 0xf0c10001
1013
1014/* TSTBUS */
1015#define R367TER_TSTBUS 0xf0c2
1016#define F367TER_TS_BYTE_CLK_INV 0xf0c20080
1017#define F367TER_CFG_IP 0xf0c20070
1018#define F367TER_CFG_TST 0xf0c2000f
1019
1020/* TSTRATE */
1021#define R367TER_TSTRATE 0xf0c6
1022#define F367TER_FORCEPHA 0xf0c60080
1023#define F367TER_FNEWPHA 0xf0c60010
1024#define F367TER_FROT90 0xf0c60008
1025#define F367TER_FR 0xf0c60007
1026
1027/* CONSTMODE */
1028#define R367TER_CONSTMODE 0xf0cb
1029#define F367TER_TST_PRIF 0xf0cb00e0
1030#define F367TER_CAR_TYPE 0xf0cb0018
1031#define F367TER_CONST_MODE 0xf0cb0003
1032
1033/* CONSTCARR1 */
1034#define R367TER_CONSTCARR1 0xf0cc
1035#define F367TER_CONST_CARR_LO 0xf0cc00ff
1036
1037/* CONSTCARR2 */
1038#define R367TER_CONSTCARR2 0xf0cd
1039#define F367TER_CONST_CARR_HI 0xf0cd001f
1040
1041/* ICONSTEL */
1042#define R367TER_ICONSTEL 0xf0ce
1043#define F367TER_PICONSTEL 0xf0ce00ff
1044
1045/* QCONSTEL */
1046#define R367TER_QCONSTEL 0xf0cf
1047#define F367TER_PQCONSTEL 0xf0cf00ff
1048
1049/* TSTBISTRES0 */
1050#define R367TER_TSTBISTRES0 0xf0d0
1051#define F367TER_BEND_PPM 0xf0d00080
1052#define F367TER_BBAD_PPM 0xf0d00040
1053#define F367TER_BEND_FFTW 0xf0d00020
1054#define F367TER_BBAD_FFTW 0xf0d00010
1055#define F367TER_BEND_FFT_BUF 0xf0d00008
1056#define F367TER_BBAD_FFT_BUF 0xf0d00004
1057#define F367TER_BEND_SYR 0xf0d00002
1058#define F367TER_BBAD_SYR 0xf0d00001
1059
1060/* TSTBISTRES1 */
1061#define R367TER_TSTBISTRES1 0xf0d1
1062#define F367TER_BEND_CHC_CP 0xf0d10080
1063#define F367TER_BBAD_CHC_CP 0xf0d10040
1064#define F367TER_BEND_CHCI 0xf0d10020
1065#define F367TER_BBAD_CHCI 0xf0d10010
1066#define F367TER_BEND_BDI 0xf0d10008
1067#define F367TER_BBAD_BDI 0xf0d10004
1068#define F367TER_BEND_SDI 0xf0d10002
1069#define F367TER_BBAD_SDI 0xf0d10001
1070
1071/* TSTBISTRES2 */
1072#define R367TER_TSTBISTRES2 0xf0d2
1073#define F367TER_BEND_CHC_INC 0xf0d20080
1074#define F367TER_BBAD_CHC_INC 0xf0d20040
1075#define F367TER_BEND_CHC_SPP 0xf0d20020
1076#define F367TER_BBAD_CHC_SPP 0xf0d20010
1077#define F367TER_BEND_CHC_CPP 0xf0d20008
1078#define F367TER_BBAD_CHC_CPP 0xf0d20004
1079#define F367TER_BEND_CHC_SP 0xf0d20002
1080#define F367TER_BBAD_CHC_SP 0xf0d20001
1081
1082/* TSTBISTRES3 */
1083#define R367TER_TSTBISTRES3 0xf0d3
1084#define F367TER_BEND_QAM 0xf0d30080
1085#define F367TER_BBAD_QAM 0xf0d30040
1086#define F367TER_BEND_SFEC_VIT 0xf0d30020
1087#define F367TER_BBAD_SFEC_VIT 0xf0d30010
1088#define F367TER_BEND_SFEC_DLINE 0xf0d30008
1089#define F367TER_BBAD_SFEC_DLINE 0xf0d30004
1090#define F367TER_BEND_SFEC_HW 0xf0d30002
1091#define F367TER_BBAD_SFEC_HW 0xf0d30001
1092
1093/* RF_AGC1 */
1094#define R367TER_RF_AGC1 0xf0d4
1095#define F367TER_RF_AGC1_LEVEL_HI 0xf0d400ff
1096
1097/* RF_AGC2 */
1098#define R367TER_RF_AGC2 0xf0d5
1099#define F367TER_REF_ADGP 0xf0d50080
1100#define F367TER_STDBY_ADCGP 0xf0d50020
1101#define F367TER_CHANNEL_SEL 0xf0d5001c
1102#define F367TER_RF_AGC1_LEVEL_LO 0xf0d50003
1103
1104/* ANADIGCTRL */
1105#define R367TER_ANADIGCTRL 0xf0d7
1106#define F367TER_SEL_CLKDEM 0xf0d70020
1107#define F367TER_EN_BUFFER_Q 0xf0d70010
1108#define F367TER_EN_BUFFER_I 0xf0d70008
1109#define F367TER_ADC_RIS_EGDE 0xf0d70004
1110#define F367TER_SGN_ADC 0xf0d70002
1111#define F367TER_SEL_AD12_SYNC 0xf0d70001
1112
1113/* PLLMDIV */
1114#define R367TER_PLLMDIV 0xf0d8
1115#define F367TER_PLL_MDIV 0xf0d800ff
1116
1117/* PLLNDIV */
1118#define R367TER_PLLNDIV 0xf0d9
1119#define F367TER_PLL_NDIV 0xf0d900ff
1120
1121/* PLLSETUP */
1122#define R367TER_PLLSETUP 0xf0dA
1123#define F367TER_PLL_PDIV 0xf0da0070
1124#define F367TER_PLL_KDIV 0xf0da000f
1125
1126/* DUAL_AD12 */
1127#define R367TER_DUAL_AD12 0xf0dB
1128#define F367TER_FS20M 0xf0db0020
1129#define F367TER_FS50M 0xf0db0010
1130#define F367TER_INMODe0 0xf0db0008
1131#define F367TER_POFFQ 0xf0db0004
1132#define F367TER_POFFI 0xf0db0002
1133#define F367TER_INMODE1 0xf0db0001
1134
1135/* TSTBIST */
1136#define R367TER_TSTBIST 0xf0dC
1137#define F367TER_TST_BYP_CLK 0xf0dc0080
1138#define F367TER_TST_GCLKENA_STD 0xf0dc0040
1139#define F367TER_TST_GCLKENA 0xf0dc0020
1140#define F367TER_TST_MEMBIST 0xf0dc001f
1141
1142/* PAD_COMP_CTRL */
1143#define R367TER_PAD_COMP_CTRL 0xf0dD
1144#define F367TER_COMPTQ 0xf0dd0010
1145#define F367TER_COMPEN 0xf0dd0008
1146#define F367TER_FREEZE2 0xf0dd0004
1147#define F367TER_SLEEP_INHBT 0xf0dd0002
1148#define F367TER_CHIP_SLEEP 0xf0dd0001
1149
1150/* PAD_COMP_WR */
1151#define R367TER_PAD_COMP_WR 0xf0de
1152#define F367TER_WR_ASRC 0xf0de007f
1153
1154/* PAD_COMP_RD */
1155#define R367TER_PAD_COMP_RD 0xf0df
1156#define F367TER_COMPOK 0xf0df0080
1157#define F367TER_RD_ASRC 0xf0df007f
1158
1159/* SYR_TARGET_FFTADJT_MSB */
1160#define R367TER_SYR_TARGET_FFTADJT_MSB 0xf100
1161#define F367TER_SYR_START 0xf1000080
1162#define F367TER_SYR_TARGET_FFTADJ_HI 0xf100000f
1163
1164/* SYR_TARGET_FFTADJT_LSB */
1165#define R367TER_SYR_TARGET_FFTADJT_LSB 0xf101
1166#define F367TER_SYR_TARGET_FFTADJ_LO 0xf10100ff
1167
1168/* SYR_TARGET_CHCADJT_MSB */
1169#define R367TER_SYR_TARGET_CHCADJT_MSB 0xf102
1170#define F367TER_SYR_TARGET_CHCADJ_HI 0xf102000f
1171
1172/* SYR_TARGET_CHCADJT_LSB */
1173#define R367TER_SYR_TARGET_CHCADJT_LSB 0xf103
1174#define F367TER_SYR_TARGET_CHCADJ_LO 0xf10300ff
1175
1176/* SYR_FLAG */
1177#define R367TER_SYR_FLAG 0xf104
1178#define F367TER_TRIG_FLG1 0xf1040080
1179#define F367TER_TRIG_FLG0 0xf1040040
1180#define F367TER_FFT_FLG1 0xf1040008
1181#define F367TER_FFT_FLG0 0xf1040004
1182#define F367TER_CHC_FLG1 0xf1040002
1183#define F367TER_CHC_FLG0 0xf1040001
1184
1185/* CRL_TARGET1 */
1186#define R367TER_CRL_TARGET1 0xf105
1187#define F367TER_CRL_START 0xf1050080
1188#define F367TER_CRL_TARGET_VHI 0xf105000f
1189
1190/* CRL_TARGET2 */
1191#define R367TER_CRL_TARGET2 0xf106
1192#define F367TER_CRL_TARGET_HI 0xf10600ff
1193
1194/* CRL_TARGET3 */
1195#define R367TER_CRL_TARGET3 0xf107
1196#define F367TER_CRL_TARGET_LO 0xf10700ff
1197
1198/* CRL_TARGET4 */
1199#define R367TER_CRL_TARGET4 0xf108
1200#define F367TER_CRL_TARGET_VLO 0xf10800ff
1201
1202/* CRL_FLAG */
1203#define R367TER_CRL_FLAG 0xf109
1204#define F367TER_CRL_FLAG1 0xf1090002
1205#define F367TER_CRL_FLAG0 0xf1090001
1206
1207/* TRL_TARGET1 */
1208#define R367TER_TRL_TARGET1 0xf10a
1209#define F367TER_TRL_TARGET_HI 0xf10a00ff
1210
1211/* TRL_TARGET2 */
1212#define R367TER_TRL_TARGET2 0xf10b
1213#define F367TER_TRL_TARGET_LO 0xf10b00ff
1214
1215/* TRL_CHC */
1216#define R367TER_TRL_CHC 0xf10c
1217#define F367TER_TRL_START 0xf10c0080
1218#define F367TER_CHC_START 0xf10c0040
1219#define F367TER_TRL_FLAG1 0xf10c0002
1220#define F367TER_TRL_FLAG0 0xf10c0001
1221
1222/* CHC_SNR_TARG */
1223#define R367TER_CHC_SNR_TARG 0xf10d
1224#define F367TER_CHC_SNR_TARGET 0xf10d00ff
1225
1226/* TOP_TRACK */
1227#define R367TER_TOP_TRACK 0xf10e
1228#define F367TER_TOP_START 0xf10e0080
1229#define F367TER_FIRST_FLAG 0xf10e0070
1230#define F367TER_TOP_FLAG1 0xf10e0008
1231#define F367TER_TOP_FLAG0 0xf10e0004
1232#define F367TER_CHC_FLAG1 0xf10e0002
1233#define F367TER_CHC_FLAG0 0xf10e0001
1234
1235/* TRACKER_FREE1 */
1236#define R367TER_TRACKER_FREE1 0xf10f
1237#define F367TER_TRACKER_FREE_1 0xf10f00ff
1238
1239/* ERROR_CRL1 */
1240#define R367TER_ERROR_CRL1 0xf110
1241#define F367TER_ERROR_CRL_VHI 0xf11000ff
1242
1243/* ERROR_CRL2 */
1244#define R367TER_ERROR_CRL2 0xf111
1245#define F367TER_ERROR_CRL_HI 0xf11100ff
1246
1247/* ERROR_CRL3 */
1248#define R367TER_ERROR_CRL3 0xf112
1249#define F367TER_ERROR_CRL_LOI 0xf11200ff
1250
1251/* ERROR_CRL4 */
1252#define R367TER_ERROR_CRL4 0xf113
1253#define F367TER_ERROR_CRL_VLO 0xf11300ff
1254
1255/* DEC_NCO1 */
1256#define R367TER_DEC_NCO1 0xf114
1257#define F367TER_DEC_NCO_VHI 0xf11400ff
1258
1259/* DEC_NCO2 */
1260#define R367TER_DEC_NCO2 0xf115
1261#define F367TER_DEC_NCO_HI 0xf11500ff
1262
1263/* DEC_NCO3 */
1264#define R367TER_DEC_NCO3 0xf116
1265#define F367TER_DEC_NCO_LO 0xf11600ff
1266
1267/* SNR */
1268#define R367TER_SNR 0xf117
1269#define F367TER_SNRATIO 0xf11700ff
1270
1271/* SYR_FFTADJ1 */
1272#define R367TER_SYR_FFTADJ1 0xf118
1273#define F367TER_SYR_FFTADJ_HI 0xf11800ff
1274
1275/* SYR_FFTADJ2 */
1276#define R367TER_SYR_FFTADJ2 0xf119
1277#define F367TER_SYR_FFTADJ_LO 0xf11900ff
1278
1279/* SYR_CHCADJ1 */
1280#define R367TER_SYR_CHCADJ1 0xf11a
1281#define F367TER_SYR_CHCADJ_HI 0xf11a00ff
1282
1283/* SYR_CHCADJ2 */
1284#define R367TER_SYR_CHCADJ2 0xf11b
1285#define F367TER_SYR_CHCADJ_LO 0xf11b00ff
1286
1287/* SYR_OFF */
1288#define R367TER_SYR_OFF 0xf11c
1289#define F367TER_SYR_OFFSET 0xf11c00ff
1290
1291/* PPM_OFFSET1 */
1292#define R367TER_PPM_OFFSET1 0xf11d
1293#define F367TER_PPM_OFFSET_HI 0xf11d00ff
1294
1295/* PPM_OFFSET2 */
1296#define R367TER_PPM_OFFSET2 0xf11e
1297#define F367TER_PPM_OFFSET_LO 0xf11e00ff
1298
1299/* TRACKER_FREE2 */
1300#define R367TER_TRACKER_FREE2 0xf11f
1301#define F367TER_TRACKER_FREE_2 0xf11f00ff
1302
1303/* DEBG_LT10 */
1304#define R367TER_DEBG_LT10 0xf120
1305#define F367TER_DEBUG_LT10 0xf12000ff
1306
1307/* DEBG_LT11 */
1308#define R367TER_DEBG_LT11 0xf121
1309#define F367TER_DEBUG_LT11 0xf12100ff
1310
1311/* DEBG_LT12 */
1312#define R367TER_DEBG_LT12 0xf122
1313#define F367TER_DEBUG_LT12 0xf12200ff
1314
1315/* DEBG_LT13 */
1316#define R367TER_DEBG_LT13 0xf123
1317#define F367TER_DEBUG_LT13 0xf12300ff
1318
1319/* DEBG_LT14 */
1320#define R367TER_DEBG_LT14 0xf124
1321#define F367TER_DEBUG_LT14 0xf12400ff
1322
1323/* DEBG_LT15 */
1324#define R367TER_DEBG_LT15 0xf125
1325#define F367TER_DEBUG_LT15 0xf12500ff
1326
1327/* DEBG_LT16 */
1328#define R367TER_DEBG_LT16 0xf126
1329#define F367TER_DEBUG_LT16 0xf12600ff
1330
1331/* DEBG_LT17 */
1332#define R367TER_DEBG_LT17 0xf127
1333#define F367TER_DEBUG_LT17 0xf12700ff
1334
1335/* DEBG_LT18 */
1336#define R367TER_DEBG_LT18 0xf128
1337#define F367TER_DEBUG_LT18 0xf12800ff
1338
1339/* DEBG_LT19 */
1340#define R367TER_DEBG_LT19 0xf129
1341#define F367TER_DEBUG_LT19 0xf12900ff
1342
1343/* DEBG_LT1a */
1344#define R367TER_DEBG_LT1A 0xf12a
1345#define F367TER_DEBUG_LT1A 0xf12a00ff
1346
1347/* DEBG_LT1b */
1348#define R367TER_DEBG_LT1B 0xf12b
1349#define F367TER_DEBUG_LT1B 0xf12b00ff
1350
1351/* DEBG_LT1c */
1352#define R367TER_DEBG_LT1C 0xf12c
1353#define F367TER_DEBUG_LT1C 0xf12c00ff
1354
1355/* DEBG_LT1D */
1356#define R367TER_DEBG_LT1D 0xf12d
1357#define F367TER_DEBUG_LT1D 0xf12d00ff
1358
1359/* DEBG_LT1E */
1360#define R367TER_DEBG_LT1E 0xf12e
1361#define F367TER_DEBUG_LT1E 0xf12e00ff
1362
1363/* DEBG_LT1F */
1364#define R367TER_DEBG_LT1F 0xf12f
1365#define F367TER_DEBUG_LT1F 0xf12f00ff
1366
1367/* RCCFGH */
1368#define R367TER_RCCFGH 0xf200
1369#define F367TER_TSRCFIFO_DVBCI 0xf2000080
1370#define F367TER_TSRCFIFO_SERIAL 0xf2000040
1371#define F367TER_TSRCFIFO_DISABLE 0xf2000020
1372#define F367TER_TSFIFO_2TORC 0xf2000010
1373#define F367TER_TSRCFIFO_HSGNLOUT 0xf2000008
1374#define F367TER_TSRCFIFO_ERRMODE 0xf2000006
1375#define F367TER_RCCFGH_0 0xf2000001
1376
1377/* RCCFGM */
1378#define R367TER_RCCFGM 0xf201
1379#define F367TER_TSRCFIFO_MANSPEED 0xf20100c0
1380#define F367TER_TSRCFIFO_PERMDATA 0xf2010020
1381#define F367TER_TSRCFIFO_NONEWSGNL 0xf2010010
1382#define F367TER_RCBYTE_OVERSAMPLING 0xf201000e
1383#define F367TER_TSRCFIFO_INVDATA 0xf2010001
1384
1385/* RCCFGL */
1386#define R367TER_RCCFGL 0xf202
1387#define F367TER_TSRCFIFO_BCLKDEL1cK 0xf20200c0
1388#define F367TER_RCCFGL_5 0xf2020020
1389#define F367TER_TSRCFIFO_DUTY50 0xf2020010
1390#define F367TER_TSRCFIFO_NSGNL2dATA 0xf2020008
1391#define F367TER_TSRCFIFO_DISSERMUX 0xf2020004
1392#define F367TER_RCCFGL_1 0xf2020002
1393#define F367TER_TSRCFIFO_STOPCKDIS 0xf2020001
1394
1395/* RCINSDELH */
1396#define R367TER_RCINSDELH 0xf203
1397#define F367TER_TSRCDEL_SYNCBYTE 0xf2030080
1398#define F367TER_TSRCDEL_XXHEADER 0xf2030040
1399#define F367TER_TSRCDEL_BBHEADER 0xf2030020
1400#define F367TER_TSRCDEL_DATAFIELD 0xf2030010
1401#define F367TER_TSRCINSDEL_ISCR 0xf2030008
1402#define F367TER_TSRCINSDEL_NPD 0xf2030004
1403#define F367TER_TSRCINSDEL_RSPARITY 0xf2030002
1404#define F367TER_TSRCINSDEL_CRC8 0xf2030001
1405
1406/* RCINSDELM */
1407#define R367TER_RCINSDELM 0xf204
1408#define F367TER_TSRCINS_BBPADDING 0xf2040080
1409#define F367TER_TSRCINS_BCHFEC 0xf2040040
1410#define F367TER_TSRCINS_LDPCFEC 0xf2040020
1411#define F367TER_TSRCINS_EMODCOD 0xf2040010
1412#define F367TER_TSRCINS_TOKEN 0xf2040008
1413#define F367TER_TSRCINS_XXXERR 0xf2040004
1414#define F367TER_TSRCINS_MATYPE 0xf2040002
1415#define F367TER_TSRCINS_UPL 0xf2040001
1416
1417/* RCINSDELL */
1418#define R367TER_RCINSDELL 0xf205
1419#define F367TER_TSRCINS_DFL 0xf2050080
1420#define F367TER_TSRCINS_SYNCD 0xf2050040
1421#define F367TER_TSRCINS_BLOCLEN 0xf2050020
1422#define F367TER_TSRCINS_SIGPCOUNT 0xf2050010
1423#define F367TER_TSRCINS_FIFO 0xf2050008
1424#define F367TER_TSRCINS_REALPACK 0xf2050004
1425#define F367TER_TSRCINS_TSCONFIG 0xf2050002
1426#define F367TER_TSRCINS_LATENCY 0xf2050001
1427
1428/* RCSTATUS */
1429#define R367TER_RCSTATUS 0xf206
1430#define F367TER_TSRCFIFO_LINEOK 0xf2060080
1431#define F367TER_TSRCFIFO_ERROR 0xf2060040
1432#define F367TER_TSRCFIFO_DATA7 0xf2060020
1433#define F367TER_RCSTATUS_4 0xf2060010
1434#define F367TER_TSRCFIFO_DEMODSEL 0xf2060008
1435#define F367TER_TSRC1FIFOSPEED_STORE 0xf2060004
1436#define F367TER_RCSTATUS_1 0xf2060002
1437#define F367TER_TSRCSERIAL_IMPOSSIBLE 0xf2060001
1438
1439/* RCSPEED */
1440#define R367TER_RCSPEED 0xf207
1441#define F367TER_TSRCFIFO_OUTSPEED 0xf20700ff
1442
1443/* RCDEBUGM */
1444#define R367TER_RCDEBUGM 0xf208
1445#define F367TER_SD_UNSYNC 0xf2080080
1446#define F367TER_ULFLOCK_DETECTM 0xf2080040
1447#define F367TER_SUL_SELECTOS 0xf2080020
1448#define F367TER_DILUL_NOSCRBLE 0xf2080010
1449#define F367TER_NUL_SCRB 0xf2080008
1450#define F367TER_UL_SCRB 0xf2080004
1451#define F367TER_SCRAULBAD 0xf2080002
1452#define F367TER_SCRAUL_UNSYNC 0xf2080001
1453
1454/* RCDEBUGL */
1455#define R367TER_RCDEBUGL 0xf209
1456#define F367TER_RS_ERR 0xf2090080
1457#define F367TER_LLFLOCK_DETECTM 0xf2090040
1458#define F367TER_NOT_SUL_SELECTOS 0xf2090020
1459#define F367TER_DILLL_NOSCRBLE 0xf2090010
1460#define F367TER_NLL_SCRB 0xf2090008
1461#define F367TER_LL_SCRB 0xf2090004
1462#define F367TER_SCRALLBAD 0xf2090002
1463#define F367TER_SCRALL_UNSYNC 0xf2090001
1464
1465/* RCOBSCFG */
1466#define R367TER_RCOBSCFG 0xf20a
1467#define F367TER_TSRCFIFO_OBSCFG 0xf20a00ff
1468
1469/* RCOBSM */
1470#define R367TER_RCOBSM 0xf20b
1471#define F367TER_TSRCFIFO_OBSDATA_HI 0xf20b00ff
1472
1473/* RCOBSL */
1474#define R367TER_RCOBSL 0xf20c
1475#define F367TER_TSRCFIFO_OBSDATA_LO 0xf20c00ff
1476
1477/* RCFECSPY */
1478#define R367TER_RCFECSPY 0xf210
1479#define F367TER_SPYRC_ENABLE 0xf2100080
1480#define F367TER_RCNO_SYNCBYTE 0xf2100040
1481#define F367TER_RCSERIAL_MODE 0xf2100020
1482#define F367TER_RCUNUSUAL_PACKET 0xf2100010
1483#define F367TER_BERRCMETER_DATAMODE 0xf210000c
1484#define F367TER_BERRCMETER_LMODE 0xf2100002
1485#define F367TER_BERRCMETER_RESET 0xf2100001
1486
1487/* RCFSPYCFG */
1488#define R367TER_RCFSPYCFG 0xf211
1489#define F367TER_FECSPYRC_INPUT 0xf21100c0
1490#define F367TER_RCRST_ON_ERROR 0xf2110020
1491#define F367TER_RCONE_SHOT 0xf2110010
1492#define F367TER_RCI2C_MODE 0xf211000c
1493#define F367TER_SPYRC_HSTERESIS 0xf2110003
1494
1495/* RCFSPYDATA */
1496#define R367TER_RCFSPYDATA 0xf212
1497#define F367TER_SPYRC_STUFFING 0xf2120080
1498#define F367TER_RCNOERR_PKTJITTER 0xf2120040
1499#define F367TER_SPYRC_CNULLPKT 0xf2120020
1500#define F367TER_SPYRC_OUTDATA_MODE 0xf212001f
1501
1502/* RCFSPYOUT */
1503#define R367TER_RCFSPYOUT 0xf213
1504#define F367TER_FSPYRC_DIRECT 0xf2130080
1505#define F367TER_RCFSPYOUT_6 0xf2130040
1506#define F367TER_SPYRC_OUTDATA_BUS 0xf2130038
1507#define F367TER_RCSTUFF_MODE 0xf2130007
1508
1509/* RCFSTATUS */
1510#define R367TER_RCFSTATUS 0xf214
1511#define F367TER_SPYRC_ENDSIM 0xf2140080
1512#define F367TER_RCVALID_SIM 0xf2140040
1513#define F367TER_RCFOUND_SIGNAL 0xf2140020
1514#define F367TER_RCDSS_SYNCBYTE 0xf2140010
1515#define F367TER_RCRESULT_STATE 0xf214000f
1516
1517/* RCFGOODPACK */
1518#define R367TER_RCFGOODPACK 0xf215
1519#define F367TER_RCGOOD_PACKET 0xf21500ff
1520
1521/* RCFPACKCNT */
1522#define R367TER_RCFPACKCNT 0xf216
1523#define F367TER_RCPACKET_COUNTER 0xf21600ff
1524
1525/* RCFSPYMISC */
1526#define R367TER_RCFSPYMISC 0xf217
1527#define F367TER_RCLABEL_COUNTER 0xf21700ff
1528
1529/* RCFBERCPT4 */
1530#define R367TER_RCFBERCPT4 0xf218
1531#define F367TER_FBERRCMETER_CPT_MMMMSB 0xf21800ff
1532
1533/* RCFBERCPT3 */
1534#define R367TER_RCFBERCPT3 0xf219
1535#define F367TER_FBERRCMETER_CPT_MMMSB 0xf21900ff
1536
1537/* RCFBERCPT2 */
1538#define R367TER_RCFBERCPT2 0xf21a
1539#define F367TER_FBERRCMETER_CPT_MMSB 0xf21a00ff
1540
1541/* RCFBERCPT1 */
1542#define R367TER_RCFBERCPT1 0xf21b
1543#define F367TER_FBERRCMETER_CPT_MSB 0xf21b00ff
1544
1545/* RCFBERCPT0 */
1546#define R367TER_RCFBERCPT0 0xf21c
1547#define F367TER_FBERRCMETER_CPT_LSB 0xf21c00ff
1548
1549/* RCFBERERR2 */
1550#define R367TER_RCFBERERR2 0xf21d
1551#define F367TER_FBERRCMETER_ERR_HI 0xf21d00ff
1552
1553/* RCFBERERR1 */
1554#define R367TER_RCFBERERR1 0xf21e
1555#define F367TER_FBERRCMETER_ERR 0xf21e00ff
1556
1557/* RCFBERERR0 */
1558#define R367TER_RCFBERERR0 0xf21f
1559#define F367TER_FBERRCMETER_ERR_LO 0xf21f00ff
1560
1561/* RCFSTATESM */
1562#define R367TER_RCFSTATESM 0xf220
1563#define F367TER_RCRSTATE_F 0xf2200080
1564#define F367TER_RCRSTATE_E 0xf2200040
1565#define F367TER_RCRSTATE_D 0xf2200020
1566#define F367TER_RCRSTATE_C 0xf2200010
1567#define F367TER_RCRSTATE_B 0xf2200008
1568#define F367TER_RCRSTATE_A 0xf2200004
1569#define F367TER_RCRSTATE_9 0xf2200002
1570#define F367TER_RCRSTATE_8 0xf2200001
1571
1572/* RCFSTATESL */
1573#define R367TER_RCFSTATESL 0xf221
1574#define F367TER_RCRSTATE_7 0xf2210080
1575#define F367TER_RCRSTATE_6 0xf2210040
1576#define F367TER_RCRSTATE_5 0xf2210020
1577#define F367TER_RCRSTATE_4 0xf2210010
1578#define F367TER_RCRSTATE_3 0xf2210008
1579#define F367TER_RCRSTATE_2 0xf2210004
1580#define F367TER_RCRSTATE_1 0xf2210002
1581#define F367TER_RCRSTATE_0 0xf2210001
1582
1583/* RCFSPYBER */
1584#define R367TER_RCFSPYBER 0xf222
1585#define F367TER_RCFSPYBER_7 0xf2220080
1586#define F367TER_SPYRCOBS_XORREAD 0xf2220040
1587#define F367TER_FSPYRCBER_OBSMODE 0xf2220020
1588#define F367TER_FSPYRCBER_SYNCBYT 0xf2220010
1589#define F367TER_FSPYRCBER_UNSYNC 0xf2220008
1590#define F367TER_FSPYRCBER_CTIME 0xf2220007
1591
1592/* RCFSPYDISTM */
1593#define R367TER_RCFSPYDISTM 0xf223
1594#define F367TER_RCPKTTIME_DISTANCE_HI 0xf22300ff
1595
1596/* RCFSPYDISTL */
1597#define R367TER_RCFSPYDISTL 0xf224
1598#define F367TER_RCPKTTIME_DISTANCE_LO 0xf22400ff
1599
1600/* RCFSPYOBS7 */
1601#define R367TER_RCFSPYOBS7 0xf228
1602#define F367TER_RCSPYOBS_SPYFAIL 0xf2280080
1603#define F367TER_RCSPYOBS_SPYFAIL1 0xf2280040
1604#define F367TER_RCSPYOBS_ERROR 0xf2280020
1605#define F367TER_RCSPYOBS_STROUT 0xf2280010
1606#define F367TER_RCSPYOBS_RESULTSTATE1 0xf228000f
1607
1608/* RCFSPYOBS6 */
1609#define R367TER_RCFSPYOBS6 0xf229
1610#define F367TER_RCSPYOBS_RESULTSTATe0 0xf22900f0
1611#define F367TER_RCSPYOBS_RESULTSTATEM1 0xf229000f
1612
1613/* RCFSPYOBS5 */
1614#define R367TER_RCFSPYOBS5 0xf22a
1615#define F367TER_RCSPYOBS_BYTEOFPACKET1 0xf22a00ff
1616
1617/* RCFSPYOBS4 */
1618#define R367TER_RCFSPYOBS4 0xf22b
1619#define F367TER_RCSPYOBS_BYTEVALUE1 0xf22b00ff
1620
1621/* RCFSPYOBS3 */
1622#define R367TER_RCFSPYOBS3 0xf22c
1623#define F367TER_RCSPYOBS_DATA1 0xf22c00ff
1624
1625/* RCFSPYOBS2 */
1626#define R367TER_RCFSPYOBS2 0xf22d
1627#define F367TER_RCSPYOBS_DATa0 0xf22d00ff
1628
1629/* RCFSPYOBS1 */
1630#define R367TER_RCFSPYOBS1 0xf22e
1631#define F367TER_RCSPYOBS_DATAM1 0xf22e00ff
1632
1633/* RCFSPYOBS0 */
1634#define R367TER_RCFSPYOBS0 0xf22f
1635#define F367TER_RCSPYOBS_DATAM2 0xf22f00ff
1636
1637/* TSGENERAL */
1638#define R367TER_TSGENERAL 0xf230
1639#define F367TER_TSGENERAL_7 0xf2300080
1640#define F367TER_TSGENERAL_6 0xf2300040
1641#define F367TER_TSFIFO_BCLK1aLL 0xf2300020
1642#define F367TER_TSGENERAL_4 0xf2300010
1643#define F367TER_MUXSTREAM_OUTMODE 0xf2300008
1644#define F367TER_TSFIFO_PERMPARAL 0xf2300006
1645#define F367TER_RST_REEDSOLO 0xf2300001
1646
1647/* RC1SPEED */
1648#define R367TER_RC1SPEED 0xf231
1649#define F367TER_TSRCFIFO1_OUTSPEED 0xf23100ff
1650
1651/* TSGSTATUS */
1652#define R367TER_TSGSTATUS 0xf232
1653#define F367TER_TSGSTATUS_7 0xf2320080
1654#define F367TER_TSGSTATUS_6 0xf2320040
1655#define F367TER_RSMEM_FULL 0xf2320020
1656#define F367TER_RS_MULTCALC 0xf2320010
1657#define F367TER_RSIN_OVERTIME 0xf2320008
1658#define F367TER_TSFIFO3_DEMODSEL 0xf2320004
1659#define F367TER_TSFIFO2_DEMODSEL 0xf2320002
1660#define F367TER_TSFIFO1_DEMODSEL 0xf2320001
1661
1662
1663/* FECM */
1664#define R367TER_FECM 0xf233
1665#define F367TER_DSS_DVB 0xf2330080
1666#define F367TER_DEMOD_BYPASS 0xf2330040
1667#define F367TER_CMP_SLOWMODE 0xf2330020
1668#define F367TER_DSS_SRCH 0xf2330010
1669#define F367TER_FECM_3 0xf2330008
1670#define F367TER_DIFF_MODEVIT 0xf2330004
1671#define F367TER_SYNCVIT 0xf2330002
1672#define F367TER_I2CSYM 0xf2330001
1673
1674/* VTH12 */
1675#define R367TER_VTH12 0xf234
1676#define F367TER_VTH_12 0xf23400ff
1677
1678/* VTH23 */
1679#define R367TER_VTH23 0xf235
1680#define F367TER_VTH_23 0xf23500ff
1681
1682/* VTH34 */
1683#define R367TER_VTH34 0xf236
1684#define F367TER_VTH_34 0xf23600ff
1685
1686/* VTH56 */
1687#define R367TER_VTH56 0xf237
1688#define F367TER_VTH_56 0xf23700ff
1689
1690/* VTH67 */
1691#define R367TER_VTH67 0xf238
1692#define F367TER_VTH_67 0xf23800ff
1693
1694/* VTH78 */
1695#define R367TER_VTH78 0xf239
1696#define F367TER_VTH_78 0xf23900ff
1697
1698/* VITCURPUN */
1699#define R367TER_VITCURPUN 0xf23a
1700#define F367TER_VIT_MAPPING 0xf23a00e0
1701#define F367TER_VIT_CURPUN 0xf23a001f
1702
1703/* VERROR */
1704#define R367TER_VERROR 0xf23b
1705#define F367TER_REGERR_VIT 0xf23b00ff
1706
1707/* PRVIT */
1708#define R367TER_PRVIT 0xf23c
1709#define F367TER_PRVIT_7 0xf23c0080
1710#define F367TER_DIS_VTHLOCK 0xf23c0040
1711#define F367TER_E7_8VIT 0xf23c0020
1712#define F367TER_E6_7VIT 0xf23c0010
1713#define F367TER_E5_6VIT 0xf23c0008
1714#define F367TER_E3_4VIT 0xf23c0004
1715#define F367TER_E2_3VIT 0xf23c0002
1716#define F367TER_E1_2VIT 0xf23c0001
1717
1718/* VAVSRVIT */
1719#define R367TER_VAVSRVIT 0xf23d
1720#define F367TER_AMVIT 0xf23d0080
1721#define F367TER_FROZENVIT 0xf23d0040
1722#define F367TER_SNVIT 0xf23d0030
1723#define F367TER_TOVVIT 0xf23d000c
1724#define F367TER_HYPVIT 0xf23d0003
1725
1726/* VSTATUSVIT */
1727#define R367TER_VSTATUSVIT 0xf23e
1728#define F367TER_VITERBI_ON 0xf23e0080
1729#define F367TER_END_LOOPVIT 0xf23e0040
1730#define F367TER_VITERBI_DEPRF 0xf23e0020
1731#define F367TER_PRFVIT 0xf23e0010
1732#define F367TER_LOCKEDVIT 0xf23e0008
1733#define F367TER_VITERBI_DELOCK 0xf23e0004
1734#define F367TER_VIT_DEMODSEL 0xf23e0002
1735#define F367TER_VITERBI_COMPOUT 0xf23e0001
1736
1737/* VTHINUSE */
1738#define R367TER_VTHINUSE 0xf23f
1739#define F367TER_VIT_INUSE 0xf23f00ff
1740
1741/* KDIV12 */
1742#define R367TER_KDIV12 0xf240
1743#define F367TER_KDIV12_MANUAL 0xf2400080
1744#define F367TER_K_DIVIDER_12 0xf240007f
1745
1746/* KDIV23 */
1747#define R367TER_KDIV23 0xf241
1748#define F367TER_KDIV23_MANUAL 0xf2410080
1749#define F367TER_K_DIVIDER_23 0xf241007f
1750
1751/* KDIV34 */
1752#define R367TER_KDIV34 0xf242
1753#define F367TER_KDIV34_MANUAL 0xf2420080
1754#define F367TER_K_DIVIDER_34 0xf242007f
1755
1756/* KDIV56 */
1757#define R367TER_KDIV56 0xf243
1758#define F367TER_KDIV56_MANUAL 0xf2430080
1759#define F367TER_K_DIVIDER_56 0xf243007f
1760
1761/* KDIV67 */
1762#define R367TER_KDIV67 0xf244
1763#define F367TER_KDIV67_MANUAL 0xf2440080
1764#define F367TER_K_DIVIDER_67 0xf244007f
1765
1766/* KDIV78 */
1767#define R367TER_KDIV78 0xf245
1768#define F367TER_KDIV78_MANUAL 0xf2450080
1769#define F367TER_K_DIVIDER_78 0xf245007f
1770
1771/* SIGPOWER */
1772#define R367TER_SIGPOWER 0xf246
1773#define F367TER_SIGPOWER_MANUAL 0xf2460080
1774#define F367TER_SIG_POWER 0xf246007f
1775
1776/* DEMAPVIT */
1777#define R367TER_DEMAPVIT 0xf247
1778#define F367TER_DEMAPVIT_7 0xf2470080
1779#define F367TER_K_DIVIDER_VIT 0xf247007f
1780
1781/* VITSCALE */
1782#define R367TER_VITSCALE 0xf248
1783#define F367TER_NVTH_NOSRANGE 0xf2480080
1784#define F367TER_VERROR_MAXMODE 0xf2480040
1785#define F367TER_KDIV_MODE 0xf2480030
1786#define F367TER_NSLOWSN_LOCKED 0xf2480008
1787#define F367TER_DELOCK_PRFLOSS 0xf2480004
1788#define F367TER_DIS_RSFLOCK 0xf2480002
1789#define F367TER_VITSCALE_0 0xf2480001
1790
1791/* FFEC1PRG */
1792#define R367TER_FFEC1PRG 0xf249
1793#define F367TER_FDSS_DVB 0xf2490080
1794#define F367TER_FDSS_SRCH 0xf2490040
1795#define F367TER_FFECPROG_5 0xf2490020
1796#define F367TER_FFECPROG_4 0xf2490010
1797#define F367TER_FFECPROG_3 0xf2490008
1798#define F367TER_FFECPROG_2 0xf2490004
1799#define F367TER_FTS1_DISABLE 0xf2490002
1800#define F367TER_FTS2_DISABLE 0xf2490001
1801
1802/* FVITCURPUN */
1803#define R367TER_FVITCURPUN 0xf24a
1804#define F367TER_FVIT_MAPPING 0xf24a00e0
1805#define F367TER_FVIT_CURPUN 0xf24a001f
1806
1807/* FVERROR */
1808#define R367TER_FVERROR 0xf24b
1809#define F367TER_FREGERR_VIT 0xf24b00ff
1810
1811/* FVSTATUSVIT */
1812#define R367TER_FVSTATUSVIT 0xf24c
1813#define F367TER_FVITERBI_ON 0xf24c0080
1814#define F367TER_F1END_LOOPVIT 0xf24c0040
1815#define F367TER_FVITERBI_DEPRF 0xf24c0020
1816#define F367TER_FPRFVIT 0xf24c0010
1817#define F367TER_FLOCKEDVIT 0xf24c0008
1818#define F367TER_FVITERBI_DELOCK 0xf24c0004
1819#define F367TER_FVIT_DEMODSEL 0xf24c0002
1820#define F367TER_FVITERBI_COMPOUT 0xf24c0001
1821
1822/* DEBUG_LT1 */
1823#define R367TER_DEBUG_LT1 0xf24d
1824#define F367TER_DBG_LT1 0xf24d00ff
1825
1826/* DEBUG_LT2 */
1827#define R367TER_DEBUG_LT2 0xf24e
1828#define F367TER_DBG_LT2 0xf24e00ff
1829
1830/* DEBUG_LT3 */
1831#define R367TER_DEBUG_LT3 0xf24f
1832#define F367TER_DBG_LT3 0xf24f00ff
1833
1834/* TSTSFMET */
1835#define R367TER_TSTSFMET 0xf250
1836#define F367TER_TSTSFEC_METRIQUES 0xf25000ff
1837
1838/* SELOUT */
1839#define R367TER_SELOUT 0xf252
1840#define F367TER_EN_SYNC 0xf2520080
1841#define F367TER_EN_TBUSDEMAP 0xf2520040
1842#define F367TER_SELOUT_5 0xf2520020
1843#define F367TER_SELOUT_4 0xf2520010
1844#define F367TER_TSTSYNCHRO_MODE 0xf2520002
1845
1846/* TSYNC */
1847#define R367TER_TSYNC 0xf253
1848#define F367TER_CURPUN_INCMODE 0xf2530080
1849#define F367TER_CERR_TSTMODE 0xf2530040
1850#define F367TER_SHIFTSOF_MODE 0xf2530030
1851#define F367TER_SLOWPHA_MODE 0xf2530008
1852#define F367TER_PXX_BYPALL 0xf2530004
1853#define F367TER_FROTA45_FIRST 0xf2530002
1854#define F367TER_TST_BCHERROR 0xf2530001
1855
1856/* TSTERR */
1857#define R367TER_TSTERR 0xf254
1858#define F367TER_TST_LONGPKT 0xf2540080
1859#define F367TER_TST_ISSYION 0xf2540040
1860#define F367TER_TST_NPDON 0xf2540020
1861#define F367TER_TSTERR_4 0xf2540010
1862#define F367TER_TRACEBACK_MODE 0xf2540008
1863#define F367TER_TST_RSPARITY 0xf2540004
1864#define F367TER_METRIQUE_MODE 0xf2540003
1865
1866/* TSFSYNC */
1867#define R367TER_TSFSYNC 0xf255
1868#define F367TER_EN_SFECSYNC 0xf2550080
1869#define F367TER_EN_SFECDEMAP 0xf2550040
1870#define F367TER_SFCERR_TSTMODE 0xf2550020
1871#define F367TER_SFECPXX_BYPALL 0xf2550010
1872#define F367TER_SFECTSTSYNCHRO_MODE 0xf255000f
1873
1874/* TSTSFERR */
1875#define R367TER_TSTSFERR 0xf256
1876#define F367TER_TSTSTERR_7 0xf2560080
1877#define F367TER_TSTSTERR_6 0xf2560040
1878#define F367TER_TSTSTERR_5 0xf2560020
1879#define F367TER_TSTSTERR_4 0xf2560010
1880#define F367TER_SFECTRACEBACK_MODE 0xf2560008
1881#define F367TER_SFEC_NCONVPROG 0xf2560004
1882#define F367TER_SFECMETRIQUE_MODE 0xf2560003
1883
1884/* TSTTSSF1 */
1885#define R367TER_TSTTSSF1 0xf258
1886#define F367TER_TSTERSSF 0xf2580080
1887#define F367TER_TSTTSSFEN 0xf2580040
1888#define F367TER_SFEC_OUTMODE 0xf2580030
1889#define F367TER_XLSF_NOFTHRESHOLD 0xf2580008
1890#define F367TER_TSTTSSF_STACKSEL 0xf2580007
1891
1892/* TSTTSSF2 */
1893#define R367TER_TSTTSSF2 0xf259
1894#define F367TER_DILSF_DBBHEADER 0xf2590080
1895#define F367TER_TSTTSSF_DISBUG 0xf2590040
1896#define F367TER_TSTTSSF_NOBADSTART 0xf2590020
1897#define F367TER_TSTTSSF_SELECT 0xf259001f
1898
1899/* TSTTSSF3 */
1900#define R367TER_TSTTSSF3 0xf25a
1901#define F367TER_TSTTSSF3_7 0xf25a0080
1902#define F367TER_TSTTSSF3_6 0xf25a0040
1903#define F367TER_TSTTSSF3_5 0xf25a0020
1904#define F367TER_TSTTSSF3_4 0xf25a0010
1905#define F367TER_TSTTSSF3_3 0xf25a0008
1906#define F367TER_TSTTSSF3_2 0xf25a0004
1907#define F367TER_TSTTSSF3_1 0xf25a0002
1908#define F367TER_DISSF_CLKENABLE 0xf25a0001
1909
1910/* TSTTS1 */
1911#define R367TER_TSTTS1 0xf25c
1912#define F367TER_TSTERS 0xf25c0080
1913#define F367TER_TSFIFO_DSSSYNCB 0xf25c0040
1914#define F367TER_TSTTS_FSPYBEFRS 0xf25c0020
1915#define F367TER_NFORCE_SYNCBYTE 0xf25c0010
1916#define F367TER_XL_NOFTHRESHOLD 0xf25c0008
1917#define F367TER_TSTTS_FRFORCEPKT 0xf25c0004
1918#define F367TER_DESCR_NOTAUTO 0xf25c0002
1919#define F367TER_TSTTSEN 0xf25c0001
1920
1921/* TSTTS2 */
1922#define R367TER_TSTTS2 0xf25d
1923#define F367TER_DIL_DBBHEADER 0xf25d0080
1924#define F367TER_TSTTS_NOBADXXX 0xf25d0040
1925#define F367TER_TSFIFO_DELSPEEDUP 0xf25d0020
1926#define F367TER_TSTTS_SELECT 0xf25d001f
1927
1928/* TSTTS3 */
1929#define R367TER_TSTTS3 0xf25e
1930#define F367TER_TSTTS_NOPKTGAIN 0xf25e0080
1931#define F367TER_TSTTS_NOPKTENE 0xf25e0040
1932#define F367TER_TSTTS_ISOLATION 0xf25e0020
1933#define F367TER_TSTTS_DISBUG 0xf25e0010
1934#define F367TER_TSTTS_NOBADSTART 0xf25e0008
1935#define F367TER_TSTTS_STACKSEL 0xf25e0007
1936
1937/* TSTTS4 */
1938#define R367TER_TSTTS4 0xf25f
1939#define F367TER_TSTTS4_7 0xf25f0080
1940#define F367TER_TSTTS4_6 0xf25f0040
1941#define F367TER_TSTTS4_5 0xf25f0020
1942#define F367TER_TSTTS_DISDSTATE 0xf25f0010
1943#define F367TER_TSTTS_FASTNOSYNC 0xf25f0008
1944#define F367TER_EXT_FECSPYIN 0xf25f0004
1945#define F367TER_TSTTS_NODPZERO 0xf25f0002
1946#define F367TER_TSTTS_NODIV3 0xf25f0001
1947
1948/* TSTTSRC */
1949#define R367TER_TSTTSRC 0xf26c
1950#define F367TER_TSTTSRC_7 0xf26c0080
1951#define F367TER_TSRCFIFO_DSSSYNCB 0xf26c0040
1952#define F367TER_TSRCFIFO_DPUNACTIVE 0xf26c0020
1953#define F367TER_TSRCFIFO_DELSPEEDUP 0xf26c0010
1954#define F367TER_TSTTSRC_NODIV3 0xf26c0008
1955#define F367TER_TSTTSRC_FRFORCEPKT 0xf26c0004
1956#define F367TER_SAT25_SDDORIGINE 0xf26c0002
1957#define F367TER_TSTTSRC_INACTIVE 0xf26c0001
1958
1959/* TSTTSRS */
1960#define R367TER_TSTTSRS 0xf26d
1961#define F367TER_TSTTSRS_7 0xf26d0080
1962#define F367TER_TSTTSRS_6 0xf26d0040
1963#define F367TER_TSTTSRS_5 0xf26d0020
1964#define F367TER_TSTTSRS_4 0xf26d0010
1965#define F367TER_TSTTSRS_3 0xf26d0008
1966#define F367TER_TSTTSRS_2 0xf26d0004
1967#define F367TER_TSTRS_DISRS2 0xf26d0002
1968#define F367TER_TSTRS_DISRS1 0xf26d0001
1969
1970/* TSSTATEM */
1971#define R367TER_TSSTATEM 0xf270
1972#define F367TER_TSDIL_ON 0xf2700080
1973#define F367TER_TSSKIPRS_ON 0xf2700040
1974#define F367TER_TSRS_ON 0xf2700020
1975#define F367TER_TSDESCRAMB_ON 0xf2700010
1976#define F367TER_TSFRAME_MODE 0xf2700008
1977#define F367TER_TS_DISABLE 0xf2700004
1978#define F367TER_TSACM_MODE 0xf2700002
1979#define F367TER_TSOUT_NOSYNC 0xf2700001
1980
1981/* TSSTATEL */
1982#define R367TER_TSSTATEL 0xf271
1983#define F367TER_TSNOSYNCBYTE 0xf2710080
1984#define F367TER_TSPARITY_ON 0xf2710040
1985#define F367TER_TSSYNCOUTRS_ON 0xf2710020
1986#define F367TER_TSDVBS2_MODE 0xf2710010
1987#define F367TER_TSISSYI_ON 0xf2710008
1988#define F367TER_TSNPD_ON 0xf2710004
1989#define F367TER_TSCRC8_ON 0xf2710002
1990#define F367TER_TSDSS_PACKET 0xf2710001
1991
1992/* TSCFGH */
1993#define R367TER_TSCFGH 0xf272
1994#define F367TER_TSFIFO_DVBCI 0xf2720080
1995#define F367TER_TSFIFO_SERIAL 0xf2720040
1996#define F367TER_TSFIFO_TEIUPDATE 0xf2720020
1997#define F367TER_TSFIFO_DUTY50 0xf2720010
1998#define F367TER_TSFIFO_HSGNLOUT 0xf2720008
1999#define F367TER_TSFIFO_ERRMODE 0xf2720006
2000#define F367TER_RST_HWARE 0xf2720001
2001
2002/* TSCFGM */
2003#define R367TER_TSCFGM 0xf273
2004#define F367TER_TSFIFO_MANSPEED 0xf27300c0
2005#define F367TER_TSFIFO_PERMDATA 0xf2730020
2006#define F367TER_TSFIFO_NONEWSGNL 0xf2730010
2007#define F367TER_TSFIFO_BITSPEED 0xf2730008
2008#define F367TER_NPD_SPECDVBS2 0xf2730004
2009#define F367TER_TSFIFO_STOPCKDIS 0xf2730002
2010#define F367TER_TSFIFO_INVDATA 0xf2730001
2011
2012/* TSCFGL */
2013#define R367TER_TSCFGL 0xf274
2014#define F367TER_TSFIFO_BCLKDEL1cK 0xf27400c0
2015#define F367TER_BCHERROR_MODE 0xf2740030
2016#define F367TER_TSFIFO_NSGNL2dATA 0xf2740008
2017#define F367TER_TSFIFO_EMBINDVB 0xf2740004
2018#define F367TER_TSFIFO_DPUNACT 0xf2740002
2019#define F367TER_TSFIFO_NPDOFF 0xf2740001
2020
2021/* TSSYNC */
2022#define R367TER_TSSYNC 0xf275
2023#define F367TER_TSFIFO_PERMUTE 0xf2750080
2024#define F367TER_TSFIFO_FISCR3B 0xf2750060
2025#define F367TER_TSFIFO_SYNCMODE 0xf2750018
2026#define F367TER_TSFIFO_SYNCSEL 0xf2750007
2027
2028/* TSINSDELH */
2029#define R367TER_TSINSDELH 0xf276
2030#define F367TER_TSDEL_SYNCBYTE 0xf2760080
2031#define F367TER_TSDEL_XXHEADER 0xf2760040
2032#define F367TER_TSDEL_BBHEADER 0xf2760020
2033#define F367TER_TSDEL_DATAFIELD 0xf2760010
2034#define F367TER_TSINSDEL_ISCR 0xf2760008
2035#define F367TER_TSINSDEL_NPD 0xf2760004
2036#define F367TER_TSINSDEL_RSPARITY 0xf2760002
2037#define F367TER_TSINSDEL_CRC8 0xf2760001
2038
2039/* TSINSDELM */
2040#define R367TER_TSINSDELM 0xf277
2041#define F367TER_TSINS_BBPADDING 0xf2770080
2042#define F367TER_TSINS_BCHFEC 0xf2770040
2043#define F367TER_TSINS_LDPCFEC 0xf2770020
2044#define F367TER_TSINS_EMODCOD 0xf2770010
2045#define F367TER_TSINS_TOKEN 0xf2770008
2046#define F367TER_TSINS_XXXERR 0xf2770004
2047#define F367TER_TSINS_MATYPE 0xf2770002
2048#define F367TER_TSINS_UPL 0xf2770001
2049
2050/* TSINSDELL */
2051#define R367TER_TSINSDELL 0xf278
2052#define F367TER_TSINS_DFL 0xf2780080
2053#define F367TER_TSINS_SYNCD 0xf2780040
2054#define F367TER_TSINS_BLOCLEN 0xf2780020
2055#define F367TER_TSINS_SIGPCOUNT 0xf2780010
2056#define F367TER_TSINS_FIFO 0xf2780008
2057#define F367TER_TSINS_REALPACK 0xf2780004
2058#define F367TER_TSINS_TSCONFIG 0xf2780002
2059#define F367TER_TSINS_LATENCY 0xf2780001
2060
2061/* TSDIVN */
2062#define R367TER_TSDIVN 0xf279
2063#define F367TER_TSFIFO_LOWSPEED 0xf2790080
2064#define F367TER_BYTE_OVERSAMPLING 0xf2790070
2065#define F367TER_TSMANUAL_PACKETNBR 0xf279000f
2066
2067/* TSDIVPM */
2068#define R367TER_TSDIVPM 0xf27a
2069#define F367TER_TSMANUAL_P_HI 0xf27a00ff
2070
2071/* TSDIVPL */
2072#define R367TER_TSDIVPL 0xf27b
2073#define F367TER_TSMANUAL_P_LO 0xf27b00ff
2074
2075/* TSDIVQM */
2076#define R367TER_TSDIVQM 0xf27c
2077#define F367TER_TSMANUAL_Q_HI 0xf27c00ff
2078
2079/* TSDIVQL */
2080#define R367TER_TSDIVQL 0xf27d
2081#define F367TER_TSMANUAL_Q_LO 0xf27d00ff
2082
2083/* TSDILSTKM */
2084#define R367TER_TSDILSTKM 0xf27e
2085#define F367TER_TSFIFO_DILSTK_HI 0xf27e00ff
2086
2087/* TSDILSTKL */
2088#define R367TER_TSDILSTKL 0xf27f
2089#define F367TER_TSFIFO_DILSTK_LO 0xf27f00ff
2090
2091/* TSSPEED */
2092#define R367TER_TSSPEED 0xf280
2093#define F367TER_TSFIFO_OUTSPEED 0xf28000ff
2094
2095/* TSSTATUS */
2096#define R367TER_TSSTATUS 0xf281
2097#define F367TER_TSFIFO_LINEOK 0xf2810080
2098#define F367TER_TSFIFO_ERROR 0xf2810040
2099#define F367TER_TSFIFO_DATA7 0xf2810020
2100#define F367TER_TSFIFO_NOSYNC 0xf2810010
2101#define F367TER_ISCR_INITIALIZED 0xf2810008
2102#define F367TER_ISCR_UPDATED 0xf2810004
2103#define F367TER_SOFFIFO_UNREGUL 0xf2810002
2104#define F367TER_DIL_READY 0xf2810001
2105
2106/* TSSTATUS2 */
2107#define R367TER_TSSTATUS2 0xf282
2108#define F367TER_TSFIFO_DEMODSEL 0xf2820080
2109#define F367TER_TSFIFOSPEED_STORE 0xf2820040
2110#define F367TER_DILXX_RESET 0xf2820020
2111#define F367TER_TSSERIAL_IMPOSSIBLE 0xf2820010
2112#define F367TER_TSFIFO_UNDERSPEED 0xf2820008
2113#define F367TER_BITSPEED_EVENT 0xf2820004
2114#define F367TER_UL_SCRAMBDETECT 0xf2820002
2115#define F367TER_ULDTV67_FALSELOCK 0xf2820001
2116
2117/* TSBITRATEM */
2118#define R367TER_TSBITRATEM 0xf283
2119#define F367TER_TSFIFO_BITRATE_HI 0xf28300ff
2120
2121/* TSBITRATEL */
2122#define R367TER_TSBITRATEL 0xf284
2123#define F367TER_TSFIFO_BITRATE_LO 0xf28400ff
2124
2125/* TSPACKLENM */
2126#define R367TER_TSPACKLENM 0xf285
2127#define F367TER_TSFIFO_PACKCPT 0xf28500e0
2128#define F367TER_DIL_RPLEN_HI 0xf285001f
2129
2130/* TSPACKLENL */
2131#define R367TER_TSPACKLENL 0xf286
2132#define F367TER_DIL_RPLEN_LO 0xf28600ff
2133
2134/* TSBLOCLENM */
2135#define R367TER_TSBLOCLENM 0xf287
2136#define F367TER_TSFIFO_PFLEN_HI 0xf28700ff
2137
2138/* TSBLOCLENL */
2139#define R367TER_TSBLOCLENL 0xf288
2140#define F367TER_TSFIFO_PFLEN_LO 0xf28800ff
2141
2142/* TSDLYH */
2143#define R367TER_TSDLYH 0xf289
2144#define F367TER_SOFFIFO_TSTIMEVALID 0xf2890080
2145#define F367TER_SOFFIFO_SPEEDUP 0xf2890040
2146#define F367TER_SOFFIFO_STOP 0xf2890020
2147#define F367TER_SOFFIFO_REGULATED 0xf2890010
2148#define F367TER_SOFFIFO_REALSBOFF_HI 0xf289000f
2149
2150/* TSDLYM */
2151#define R367TER_TSDLYM 0xf28a
2152#define F367TER_SOFFIFO_REALSBOFF_MED 0xf28a00ff
2153
2154/* TSDLYL */
2155#define R367TER_TSDLYL 0xf28b
2156#define F367TER_SOFFIFO_REALSBOFF_LO 0xf28b00ff
2157
2158/* TSNPDAV */
2159#define R367TER_TSNPDAV 0xf28c
2160#define F367TER_TSNPD_AVERAGE 0xf28c00ff
2161
2162/* TSBUFSTATH */
2163#define R367TER_TSBUFSTATH 0xf28d
2164#define F367TER_TSISCR_3BYTES 0xf28d0080
2165#define F367TER_TSISCR_NEWDATA 0xf28d0040
2166#define F367TER_TSISCR_BUFSTAT_HI 0xf28d003f
2167
2168/* TSBUFSTATM */
2169#define R367TER_TSBUFSTATM 0xf28e
2170#define F367TER_TSISCR_BUFSTAT_MED 0xf28e00ff
2171
2172/* TSBUFSTATL */
2173#define R367TER_TSBUFSTATL 0xf28f
2174#define F367TER_TSISCR_BUFSTAT_LO 0xf28f00ff
2175
2176/* TSDEBUGM */
2177#define R367TER_TSDEBUGM 0xf290
2178#define F367TER_TSFIFO_ILLPACKET 0xf2900080
2179#define F367TER_DIL_NOSYNC 0xf2900040
2180#define F367TER_DIL_ISCR 0xf2900020
2181#define F367TER_DILOUT_BSYNCB 0xf2900010
2182#define F367TER_TSFIFO_EMPTYPKT 0xf2900008
2183#define F367TER_TSFIFO_EMPTYRD 0xf2900004
2184#define F367TER_SOFFIFO_STOPM 0xf2900002
2185#define F367TER_SOFFIFO_SPEEDUPM 0xf2900001
2186
2187/* TSDEBUGL */
2188#define R367TER_TSDEBUGL 0xf291
2189#define F367TER_TSFIFO_PACKLENFAIL 0xf2910080
2190#define F367TER_TSFIFO_SYNCBFAIL 0xf2910040
2191#define F367TER_TSFIFO_VITLIBRE 0xf2910020
2192#define F367TER_TSFIFO_BOOSTSPEEDM 0xf2910010
2193#define F367TER_TSFIFO_UNDERSPEEDM 0xf2910008
2194#define F367TER_TSFIFO_ERROR_EVNT 0xf2910004
2195#define F367TER_TSFIFO_FULL 0xf2910002
2196#define F367TER_TSFIFO_OVERFLOWM 0xf2910001
2197
2198/* TSDLYSETH */
2199#define R367TER_TSDLYSETH 0xf292
2200#define F367TER_SOFFIFO_OFFSET 0xf29200e0
2201#define F367TER_SOFFIFO_SYMBOFFSET_HI 0xf292001f
2202
2203/* TSDLYSETM */
2204#define R367TER_TSDLYSETM 0xf293
2205#define F367TER_SOFFIFO_SYMBOFFSET_MED 0xf29300ff
2206
2207/* TSDLYSETL */
2208#define R367TER_TSDLYSETL 0xf294
2209#define F367TER_SOFFIFO_SYMBOFFSET_LO 0xf29400ff
2210
2211/* TSOBSCFG */
2212#define R367TER_TSOBSCFG 0xf295
2213#define F367TER_TSFIFO_OBSCFG 0xf29500ff
2214
2215/* TSOBSM */
2216#define R367TER_TSOBSM 0xf296
2217#define F367TER_TSFIFO_OBSDATA_HI 0xf29600ff
2218
2219/* TSOBSL */
2220#define R367TER_TSOBSL 0xf297
2221#define F367TER_TSFIFO_OBSDATA_LO 0xf29700ff
2222
2223/* ERRCTRL1 */
2224#define R367TER_ERRCTRL1 0xf298
2225#define F367TER_ERR_SRC1 0xf29800f0
2226#define F367TER_ERRCTRL1_3 0xf2980008
2227#define F367TER_NUM_EVT1 0xf2980007
2228
2229/* ERRCNT1H */
2230#define R367TER_ERRCNT1H 0xf299
2231#define F367TER_ERRCNT1_OLDVALUE 0xf2990080
2232#define F367TER_ERR_CNT1 0xf299007f
2233
2234/* ERRCNT1M */
2235#define R367TER_ERRCNT1M 0xf29a
2236#define F367TER_ERR_CNT1_HI 0xf29a00ff
2237
2238/* ERRCNT1L */
2239#define R367TER_ERRCNT1L 0xf29b
2240#define F367TER_ERR_CNT1_LO 0xf29b00ff
2241
2242/* ERRCTRL2 */
2243#define R367TER_ERRCTRL2 0xf29c
2244#define F367TER_ERR_SRC2 0xf29c00f0
2245#define F367TER_ERRCTRL2_3 0xf29c0008
2246#define F367TER_NUM_EVT2 0xf29c0007
2247
2248/* ERRCNT2H */
2249#define R367TER_ERRCNT2H 0xf29d
2250#define F367TER_ERRCNT2_OLDVALUE 0xf29d0080
2251#define F367TER_ERR_CNT2_HI 0xf29d007f
2252
2253/* ERRCNT2M */
2254#define R367TER_ERRCNT2M 0xf29e
2255#define F367TER_ERR_CNT2_MED 0xf29e00ff
2256
2257/* ERRCNT2L */
2258#define R367TER_ERRCNT2L 0xf29f
2259#define F367TER_ERR_CNT2_LO 0xf29f00ff
2260
2261/* FECSPY */
2262#define R367TER_FECSPY 0xf2a0
2263#define F367TER_SPY_ENABLE 0xf2a00080
2264#define F367TER_NO_SYNCBYTE 0xf2a00040
2265#define F367TER_SERIAL_MODE 0xf2a00020
2266#define F367TER_UNUSUAL_PACKET 0xf2a00010
2267#define F367TER_BERMETER_DATAMODE 0xf2a0000c
2268#define F367TER_BERMETER_LMODE 0xf2a00002
2269#define F367TER_BERMETER_RESET 0xf2a00001
2270
2271/* FSPYCFG */
2272#define R367TER_FSPYCFG 0xf2a1
2273#define F367TER_FECSPY_INPUT 0xf2a100c0
2274#define F367TER_RST_ON_ERROR 0xf2a10020
2275#define F367TER_ONE_SHOT 0xf2a10010
2276#define F367TER_I2C_MOD 0xf2a1000c
2277#define F367TER_SPY_HYSTERESIS 0xf2a10003
2278
2279/* FSPYDATA */
2280#define R367TER_FSPYDATA 0xf2a2
2281#define F367TER_SPY_STUFFING 0xf2a20080
2282#define F367TER_NOERROR_PKTJITTER 0xf2a20040
2283#define F367TER_SPY_CNULLPKT 0xf2a20020
2284#define F367TER_SPY_OUTDATA_MODE 0xf2a2001f
2285
2286/* FSPYOUT */
2287#define R367TER_FSPYOUT 0xf2a3
2288#define F367TER_FSPY_DIRECT 0xf2a30080
2289#define F367TER_FSPYOUT_6 0xf2a30040
2290#define F367TER_SPY_OUTDATA_BUS 0xf2a30038
2291#define F367TER_STUFF_MODE 0xf2a30007
2292
2293/* FSTATUS */
2294#define R367TER_FSTATUS 0xf2a4
2295#define F367TER_SPY_ENDSIM 0xf2a40080
2296#define F367TER_VALID_SIM 0xf2a40040
2297#define F367TER_FOUND_SIGNAL 0xf2a40020
2298#define F367TER_DSS_SYNCBYTE 0xf2a40010
2299#define F367TER_RESULT_STATE 0xf2a4000f
2300
2301/* FGOODPACK */
2302#define R367TER_FGOODPACK 0xf2a5
2303#define F367TER_FGOOD_PACKET 0xf2a500ff
2304
2305/* FPACKCNT */
2306#define R367TER_FPACKCNT 0xf2a6
2307#define F367TER_FPACKET_COUNTER 0xf2a600ff
2308
2309/* FSPYMISC */
2310#define R367TER_FSPYMISC 0xf2a7
2311#define F367TER_FLABEL_COUNTER 0xf2a700ff
2312
2313/* FBERCPT4 */
2314#define R367TER_FBERCPT4 0xf2a8
2315#define F367TER_FBERMETER_CPT5 0xf2a800ff
2316
2317/* FBERCPT3 */
2318#define R367TER_FBERCPT3 0xf2a9
2319#define F367TER_FBERMETER_CPT4 0xf2a900ff
2320
2321/* FBERCPT2 */
2322#define R367TER_FBERCPT2 0xf2aa
2323#define F367TER_FBERMETER_CPT3 0xf2aa00ff
2324
2325/* FBERCPT1 */
2326#define R367TER_FBERCPT1 0xf2ab
2327#define F367TER_FBERMETER_CPT2 0xf2ab00ff
2328
2329/* FBERCPT0 */
2330#define R367TER_FBERCPT0 0xf2ac
2331#define F367TER_FBERMETER_CPT1 0xf2ac00ff
2332
2333/* FBERERR2 */
2334#define R367TER_FBERERR2 0xf2ad
2335#define F367TER_FBERMETER_ERR_HI 0xf2ad00ff
2336
2337/* FBERERR1 */
2338#define R367TER_FBERERR1 0xf2ae
2339#define F367TER_FBERMETER_ERR_MED 0xf2ae00ff
2340
2341/* FBERERR0 */
2342#define R367TER_FBERERR0 0xf2af
2343#define F367TER_FBERMETER_ERR_LO 0xf2af00ff
2344
2345/* FSTATESM */
2346#define R367TER_FSTATESM 0xf2b0
2347#define F367TER_RSTATE_F 0xf2b00080
2348#define F367TER_RSTATE_E 0xf2b00040
2349#define F367TER_RSTATE_D 0xf2b00020
2350#define F367TER_RSTATE_C 0xf2b00010
2351#define F367TER_RSTATE_B 0xf2b00008
2352#define F367TER_RSTATE_A 0xf2b00004
2353#define F367TER_RSTATE_9 0xf2b00002
2354#define F367TER_RSTATE_8 0xf2b00001
2355
2356/* FSTATESL */
2357#define R367TER_FSTATESL 0xf2b1
2358#define F367TER_RSTATE_7 0xf2b10080
2359#define F367TER_RSTATE_6 0xf2b10040
2360#define F367TER_RSTATE_5 0xf2b10020
2361#define F367TER_RSTATE_4 0xf2b10010
2362#define F367TER_RSTATE_3 0xf2b10008
2363#define F367TER_RSTATE_2 0xf2b10004
2364#define F367TER_RSTATE_1 0xf2b10002
2365#define F367TER_RSTATE_0 0xf2b10001
2366
2367/* FSPYBER */
2368#define R367TER_FSPYBER 0xf2b2
2369#define F367TER_FSPYBER_7 0xf2b20080
2370#define F367TER_FSPYOBS_XORREAD 0xf2b20040
2371#define F367TER_FSPYBER_OBSMODE 0xf2b20020
2372#define F367TER_FSPYBER_SYNCBYTE 0xf2b20010
2373#define F367TER_FSPYBER_UNSYNC 0xf2b20008
2374#define F367TER_FSPYBER_CTIME 0xf2b20007
2375
2376/* FSPYDISTM */
2377#define R367TER_FSPYDISTM 0xf2b3
2378#define F367TER_PKTTIME_DISTANCE_HI 0xf2b300ff
2379
2380/* FSPYDISTL */
2381#define R367TER_FSPYDISTL 0xf2b4
2382#define F367TER_PKTTIME_DISTANCE_LO 0xf2b400ff
2383
2384/* FSPYOBS7 */
2385#define R367TER_FSPYOBS7 0xf2b8
2386#define F367TER_FSPYOBS_SPYFAIL 0xf2b80080
2387#define F367TER_FSPYOBS_SPYFAIL1 0xf2b80040
2388#define F367TER_FSPYOBS_ERROR 0xf2b80020
2389#define F367TER_FSPYOBS_STROUT 0xf2b80010
2390#define F367TER_FSPYOBS_RESULTSTATE1 0xf2b8000f
2391
2392/* FSPYOBS6 */
2393#define R367TER_FSPYOBS6 0xf2b9
2394#define F367TER_FSPYOBS_RESULTSTATe0 0xf2b900f0
2395#define F367TER_FSPYOBS_RESULTSTATEM1 0xf2b9000f
2396
2397/* FSPYOBS5 */
2398#define R367TER_FSPYOBS5 0xf2ba
2399#define F367TER_FSPYOBS_BYTEOFPACKET1 0xf2ba00ff
2400
2401/* FSPYOBS4 */
2402#define R367TER_FSPYOBS4 0xf2bb
2403#define F367TER_FSPYOBS_BYTEVALUE1 0xf2bb00ff
2404
2405/* FSPYOBS3 */
2406#define R367TER_FSPYOBS3 0xf2bc
2407#define F367TER_FSPYOBS_DATA1 0xf2bc00ff
2408
2409/* FSPYOBS2 */
2410#define R367TER_FSPYOBS2 0xf2bd
2411#define F367TER_FSPYOBS_DATa0 0xf2bd00ff
2412
2413/* FSPYOBS1 */
2414#define R367TER_FSPYOBS1 0xf2be
2415#define F367TER_FSPYOBS_DATAM1 0xf2be00ff
2416
2417/* FSPYOBS0 */
2418#define R367TER_FSPYOBS0 0xf2bf
2419#define F367TER_FSPYOBS_DATAM2 0xf2bf00ff
2420
2421/* SFDEMAP */
2422#define R367TER_SFDEMAP 0xf2c0
2423#define F367TER_SFDEMAP_7 0xf2c00080
2424#define F367TER_SFEC_K_DIVIDER_VIT 0xf2c0007f
2425
2426/* SFERROR */
2427#define R367TER_SFERROR 0xf2c1
2428#define F367TER_SFEC_REGERR_VIT 0xf2c100ff
2429
2430/* SFAVSR */
2431#define R367TER_SFAVSR 0xf2c2
2432#define F367TER_SFEC_SUMERRORS 0xf2c20080
2433#define F367TER_SERROR_MAXMODE 0xf2c20040
2434#define F367TER_SN_SFEC 0xf2c20030
2435#define F367TER_KDIV_MODE_SFEC 0xf2c2000c
2436#define F367TER_SFAVSR_1 0xf2c20002
2437#define F367TER_SFAVSR_0 0xf2c20001
2438
2439/* SFECSTATUS */
2440#define R367TER_SFECSTATUS 0xf2c3
2441#define F367TER_SFEC_ON 0xf2c30080
2442#define F367TER_SFSTATUS_6 0xf2c30040
2443#define F367TER_SFSTATUS_5 0xf2c30020
2444#define F367TER_SFSTATUS_4 0xf2c30010
2445#define F367TER_LOCKEDSFEC 0xf2c30008
2446#define F367TER_SFEC_DELOCK 0xf2c30004
2447#define F367TER_SFEC_DEMODSEL1 0xf2c30002
2448#define F367TER_SFEC_OVFON 0xf2c30001
2449
2450/* SFKDIV12 */
2451#define R367TER_SFKDIV12 0xf2c4
2452#define F367TER_SFECKDIV12_MAN 0xf2c40080
2453#define F367TER_SFEC_K_DIVIDER_12 0xf2c4007f
2454
2455/* SFKDIV23 */
2456#define R367TER_SFKDIV23 0xf2c5
2457#define F367TER_SFECKDIV23_MAN 0xf2c50080
2458#define F367TER_SFEC_K_DIVIDER_23 0xf2c5007f
2459
2460/* SFKDIV34 */
2461#define R367TER_SFKDIV34 0xf2c6
2462#define F367TER_SFECKDIV34_MAN 0xf2c60080
2463#define F367TER_SFEC_K_DIVIDER_34 0xf2c6007f
2464
2465/* SFKDIV56 */
2466#define R367TER_SFKDIV56 0xf2c7
2467#define F367TER_SFECKDIV56_MAN 0xf2c70080
2468#define F367TER_SFEC_K_DIVIDER_56 0xf2c7007f
2469
2470/* SFKDIV67 */
2471#define R367TER_SFKDIV67 0xf2c8
2472#define F367TER_SFECKDIV67_MAN 0xf2c80080
2473#define F367TER_SFEC_K_DIVIDER_67 0xf2c8007f
2474
2475/* SFKDIV78 */
2476#define R367TER_SFKDIV78 0xf2c9
2477#define F367TER_SFECKDIV78_MAN 0xf2c90080
2478#define F367TER_SFEC_K_DIVIDER_78 0xf2c9007f
2479
2480/* SFDILSTKM */
2481#define R367TER_SFDILSTKM 0xf2ca
2482#define F367TER_SFEC_PACKCPT 0xf2ca00e0
2483#define F367TER_SFEC_DILSTK_HI 0xf2ca001f
2484
2485/* SFDILSTKL */
2486#define R367TER_SFDILSTKL 0xf2cb
2487#define F367TER_SFEC_DILSTK_LO 0xf2cb00ff
2488
2489/* SFSTATUS */
2490#define R367TER_SFSTATUS 0xf2cc
2491#define F367TER_SFEC_LINEOK 0xf2cc0080
2492#define F367TER_SFEC_ERROR 0xf2cc0040
2493#define F367TER_SFEC_DATA7 0xf2cc0020
2494#define F367TER_SFEC_OVERFLOW 0xf2cc0010
2495#define F367TER_SFEC_DEMODSEL2 0xf2cc0008
2496#define F367TER_SFEC_NOSYNC 0xf2cc0004
2497#define F367TER_SFEC_UNREGULA 0xf2cc0002
2498#define F367TER_SFEC_READY 0xf2cc0001
2499
2500/* SFDLYH */
2501#define R367TER_SFDLYH 0xf2cd
2502#define F367TER_SFEC_TSTIMEVALID 0xf2cd0080
2503#define F367TER_SFEC_SPEEDUP 0xf2cd0040
2504#define F367TER_SFEC_STOP 0xf2cd0020
2505#define F367TER_SFEC_REGULATED 0xf2cd0010
2506#define F367TER_SFEC_REALSYMBOFFSET 0xf2cd000f
2507
2508/* SFDLYM */
2509#define R367TER_SFDLYM 0xf2ce
2510#define F367TER_SFEC_REALSYMBOFFSET_HI 0xf2ce00ff
2511
2512/* SFDLYL */
2513#define R367TER_SFDLYL 0xf2cf
2514#define F367TER_SFEC_REALSYMBOFFSET_LO 0xf2cf00ff
2515
2516/* SFDLYSETH */
2517#define R367TER_SFDLYSETH 0xf2d0
2518#define F367TER_SFEC_OFFSET 0xf2d000e0
2519#define F367TER_SFECDLYSETH_4 0xf2d00010
2520#define F367TER_RST_SFEC 0xf2d00008
2521#define F367TER_SFECDLYSETH_2 0xf2d00004
2522#define F367TER_SFEC_DISABLE 0xf2d00002
2523#define F367TER_SFEC_UNREGUL 0xf2d00001
2524
2525/* SFDLYSETM */
2526#define R367TER_SFDLYSETM 0xf2d1
2527#define F367TER_SFECDLYSETM_7 0xf2d10080
2528#define F367TER_SFEC_SYMBOFFSET_HI 0xf2d1007f
2529
2530/* SFDLYSETL */
2531#define R367TER_SFDLYSETL 0xf2d2
2532#define F367TER_SFEC_SYMBOFFSET_LO 0xf2d200ff
2533
2534/* SFOBSCFG */
2535#define R367TER_SFOBSCFG 0xf2d3
2536#define F367TER_SFEC_OBSCFG 0xf2d300ff
2537
2538/* SFOBSM */
2539#define R367TER_SFOBSM 0xf2d4
2540#define F367TER_SFEC_OBSDATA_HI 0xf2d400ff
2541
2542/* SFOBSL */
2543#define R367TER_SFOBSL 0xf2d5
2544#define F367TER_SFEC_OBSDATA_LO 0xf2d500ff
2545
2546/* SFECINFO */
2547#define R367TER_SFECINFO 0xf2d6
2548#define F367TER_SFECINFO_7 0xf2d60080
2549#define F367TER_SFEC_SYNCDLSB 0xf2d60070
2550#define F367TER_SFCE_S1cPHASE 0xf2d6000f
2551
2552/* SFERRCTRL */
2553#define R367TER_SFERRCTRL 0xf2d8
2554#define F367TER_SFEC_ERR_SOURCE 0xf2d800f0
2555#define F367TER_SFERRCTRL_3 0xf2d80008
2556#define F367TER_SFEC_NUM_EVENT 0xf2d80007
2557
2558/* SFERRCNTH */
2559#define R367TER_SFERRCNTH 0xf2d9
2560#define F367TER_SFERRC_OLDVALUE 0xf2d90080
2561#define F367TER_SFEC_ERR_CNT 0xf2d9007f
2562
2563/* SFERRCNTM */
2564#define R367TER_SFERRCNTM 0xf2da
2565#define F367TER_SFEC_ERR_CNT_HI 0xf2da00ff
2566
2567/* SFERRCNTL */
2568#define R367TER_SFERRCNTL 0xf2db
2569#define F367TER_SFEC_ERR_CNT_LO 0xf2db00ff
2570
2571/* SYMBRATEM */
2572#define R367TER_SYMBRATEM 0xf2e0
2573#define F367TER_DEFGEN_SYMBRATE_HI 0xf2e000ff
2574
2575/* SYMBRATEL */
2576#define R367TER_SYMBRATEL 0xf2e1
2577#define F367TER_DEFGEN_SYMBRATE_LO 0xf2e100ff
2578
2579/* SYMBSTATUS */
2580#define R367TER_SYMBSTATUS 0xf2e2
2581#define F367TER_SYMBDLINE2_OFF 0xf2e20080
2582#define F367TER_SDDL_REINIT1 0xf2e20040
2583#define F367TER_SDD_REINIT1 0xf2e20020
2584#define F367TER_TOKENID_ERROR 0xf2e20010
2585#define F367TER_SYMBRATE_OVERFLOW 0xf2e20008
2586#define F367TER_SYMBRATE_UNDERFLOW 0xf2e20004
2587#define F367TER_TOKENID_RSTEVENT 0xf2e20002
2588#define F367TER_TOKENID_RESET1 0xf2e20001
2589
2590/* SYMBCFG */
2591#define R367TER_SYMBCFG 0xf2e3
2592#define F367TER_SYMBCFG_7 0xf2e30080
2593#define F367TER_SYMBCFG_6 0xf2e30040
2594#define F367TER_SYMBCFG_5 0xf2e30020
2595#define F367TER_SYMBCFG_4 0xf2e30010
2596#define F367TER_SYMRATE_FSPEED 0xf2e3000c
2597#define F367TER_SYMRATE_SSPEED 0xf2e30003
2598
2599/* SYMBFIFOM */
2600#define R367TER_SYMBFIFOM 0xf2e4
2601#define F367TER_SYMBFIFOM_7 0xf2e40080
2602#define F367TER_SYMBFIFOM_6 0xf2e40040
2603#define F367TER_DEFGEN_SYMFIFO_HI 0xf2e4003f
2604
2605/* SYMBFIFOL */
2606#define R367TER_SYMBFIFOL 0xf2e5
2607#define F367TER_DEFGEN_SYMFIFO_LO 0xf2e500ff
2608
2609/* SYMBOFFSM */
2610#define R367TER_SYMBOFFSM 0xf2e6
2611#define F367TER_TOKENID_RESET2 0xf2e60080
2612#define F367TER_SDDL_REINIT2 0xf2e60040
2613#define F367TER_SDD_REINIT2 0xf2e60020
2614#define F367TER_SYMBOFFSM_4 0xf2e60010
2615#define F367TER_SYMBOFFSM_3 0xf2e60008
2616#define F367TER_DEFGEN_SYMBOFFSET_HI 0xf2e60007
2617
2618/* SYMBOFFSL */
2619#define R367TER_SYMBOFFSL 0xf2e7
2620#define F367TER_DEFGEN_SYMBOFFSET_LO 0xf2e700ff
2621
2622/* DEBUG_LT4 */
2623#define R367TER_DEBUG_LT4 0xf400
2624#define F367TER_F_DEBUG_LT4 0xf40000ff
2625
2626/* DEBUG_LT5 */
2627#define R367TER_DEBUG_LT5 0xf401
2628#define F367TER_F_DEBUG_LT5 0xf40100ff
2629
2630/* DEBUG_LT6 */
2631#define R367TER_DEBUG_LT6 0xf402
2632#define F367TER_F_DEBUG_LT6 0xf40200ff
2633
2634/* DEBUG_LT7 */
2635#define R367TER_DEBUG_LT7 0xf403
2636#define F367TER_F_DEBUG_LT7 0xf40300ff
2637
2638/* DEBUG_LT8 */
2639#define R367TER_DEBUG_LT8 0xf404
2640#define F367TER_F_DEBUG_LT8 0xf40400ff
2641
2642/* DEBUG_LT9 */
2643#define R367TER_DEBUG_LT9 0xf405
2644#define F367TER_F_DEBUG_LT9 0xf40500ff
2645
2646#define STV0367TER_NBREGS 445
2647
2648/* ID */
2649#define R367CAB_ID 0xf000
2650#define F367CAB_IDENTIFICATIONREGISTER 0xf00000ff
2651
2652/* I2CRPT */
2653#define R367CAB_I2CRPT 0xf001
2654#define F367CAB_I2CT_ON 0xf0010080
2655#define F367CAB_ENARPT_LEVEL 0xf0010070
2656#define F367CAB_SCLT_DELAY 0xf0010008
2657#define F367CAB_SCLT_NOD 0xf0010004
2658#define F367CAB_STOP_ENABLE 0xf0010002
2659#define F367CAB_SDAT_NOD 0xf0010001
2660
2661/* TOPCTRL */
2662#define R367CAB_TOPCTRL 0xf002
2663#define F367CAB_STDBY 0xf0020080
2664#define F367CAB_STDBY_CORE 0xf0020020
2665#define F367CAB_QAM_COFDM 0xf0020010
2666#define F367CAB_TS_DIS 0xf0020008
2667#define F367CAB_DIR_CLK_216 0xf0020004
2668
2669/* IOCFG0 */
2670#define R367CAB_IOCFG0 0xf003
2671#define F367CAB_OP0_SD 0xf0030080
2672#define F367CAB_OP0_VAL 0xf0030040
2673#define F367CAB_OP0_OD 0xf0030020
2674#define F367CAB_OP0_INV 0xf0030010
2675#define F367CAB_OP0_DACVALUE_HI 0xf003000f
2676
2677/* DAc0R */
2678#define R367CAB_DAC0R 0xf004
2679#define F367CAB_OP0_DACVALUE_LO 0xf00400ff
2680
2681/* IOCFG1 */
2682#define R367CAB_IOCFG1 0xf005
2683#define F367CAB_IP0 0xf0050040
2684#define F367CAB_OP1_OD 0xf0050020
2685#define F367CAB_OP1_INV 0xf0050010
2686#define F367CAB_OP1_DACVALUE_HI 0xf005000f
2687
2688/* DAC1R */
2689#define R367CAB_DAC1R 0xf006
2690#define F367CAB_OP1_DACVALUE_LO 0xf00600ff
2691
2692/* IOCFG2 */
2693#define R367CAB_IOCFG2 0xf007
2694#define F367CAB_OP2_LOCK_CONF 0xf00700e0
2695#define F367CAB_OP2_OD 0xf0070010
2696#define F367CAB_OP2_VAL 0xf0070008
2697#define F367CAB_OP1_LOCK_CONF 0xf0070007
2698
2699/* SDFR */
2700#define R367CAB_SDFR 0xf008
2701#define F367CAB_OP0_FREQ 0xf00800f0
2702#define F367CAB_OP1_FREQ 0xf008000f
2703
2704/* AUX_CLK */
2705#define R367CAB_AUX_CLK 0xf00a
2706#define F367CAB_AUXFEC_CTL 0xf00a00c0
2707#define F367CAB_DIS_CKX4 0xf00a0020
2708#define F367CAB_CKSEL 0xf00a0018
2709#define F367CAB_CKDIV_PROG 0xf00a0006
2710#define F367CAB_AUXCLK_ENA 0xf00a0001
2711
2712/* FREESYS1 */
2713#define R367CAB_FREESYS1 0xf00b
2714#define F367CAB_FREESYS_1 0xf00b00ff
2715
2716/* FREESYS2 */
2717#define R367CAB_FREESYS2 0xf00c
2718#define F367CAB_FREESYS_2 0xf00c00ff
2719
2720/* FREESYS3 */
2721#define R367CAB_FREESYS3 0xf00d
2722#define F367CAB_FREESYS_3 0xf00d00ff
2723
2724/* GPIO_CFG */
2725#define R367CAB_GPIO_CFG 0xf00e
2726#define F367CAB_GPIO7_OD 0xf00e0080
2727#define F367CAB_GPIO7_CFG 0xf00e0040
2728#define F367CAB_GPIO6_OD 0xf00e0020
2729#define F367CAB_GPIO6_CFG 0xf00e0010
2730#define F367CAB_GPIO5_OD 0xf00e0008
2731#define F367CAB_GPIO5_CFG 0xf00e0004
2732#define F367CAB_GPIO4_OD 0xf00e0002
2733#define F367CAB_GPIO4_CFG 0xf00e0001
2734
2735/* GPIO_CMD */
2736#define R367CAB_GPIO_CMD 0xf00f
2737#define F367CAB_GPIO7_VAL 0xf00f0008
2738#define F367CAB_GPIO6_VAL 0xf00f0004
2739#define F367CAB_GPIO5_VAL 0xf00f0002
2740#define F367CAB_GPIO4_VAL 0xf00f0001
2741
2742/* TSTRES */
2743#define R367CAB_TSTRES 0xf0c0
2744#define F367CAB_FRES_DISPLAY 0xf0c00080
2745#define F367CAB_FRES_FIFO_AD 0xf0c00020
2746#define F367CAB_FRESRS 0xf0c00010
2747#define F367CAB_FRESACS 0xf0c00008
2748#define F367CAB_FRESFEC 0xf0c00004
2749#define F367CAB_FRES_PRIF 0xf0c00002
2750#define F367CAB_FRESCORE 0xf0c00001
2751
2752/* ANACTRL */
2753#define R367CAB_ANACTRL 0xf0c1
2754#define F367CAB_BYPASS_XTAL 0xf0c10040
2755#define F367CAB_BYPASS_PLLXN 0xf0c1000c
2756#define F367CAB_DIS_PAD_OSC 0xf0c10002
2757#define F367CAB_STDBY_PLLXN 0xf0c10001
2758
2759/* TSTBUS */
2760#define R367CAB_TSTBUS 0xf0c2
2761#define F367CAB_TS_BYTE_CLK_INV 0xf0c20080
2762#define F367CAB_CFG_IP 0xf0c20070
2763#define F367CAB_CFG_TST 0xf0c2000f
2764
2765/* RF_AGC1 */
2766#define R367CAB_RF_AGC1 0xf0d4
2767#define F367CAB_RF_AGC1_LEVEL_HI 0xf0d400ff
2768
2769/* RF_AGC2 */
2770#define R367CAB_RF_AGC2 0xf0d5
2771#define F367CAB_REF_ADGP 0xf0d50080
2772#define F367CAB_STDBY_ADCGP 0xf0d50020
2773#define F367CAB_RF_AGC1_LEVEL_LO 0xf0d50003
2774
2775/* ANADIGCTRL */
2776#define R367CAB_ANADIGCTRL 0xf0d7
2777#define F367CAB_SEL_CLKDEM 0xf0d70020
2778#define F367CAB_EN_BUFFER_Q 0xf0d70010
2779#define F367CAB_EN_BUFFER_I 0xf0d70008
2780#define F367CAB_ADC_RIS_EGDE 0xf0d70004
2781#define F367CAB_SGN_ADC 0xf0d70002
2782#define F367CAB_SEL_AD12_SYNC 0xf0d70001
2783
2784/* PLLMDIV */
2785#define R367CAB_PLLMDIV 0xf0d8
2786#define F367CAB_PLL_MDIV 0xf0d800ff
2787
2788/* PLLNDIV */
2789#define R367CAB_PLLNDIV 0xf0d9
2790#define F367CAB_PLL_NDIV 0xf0d900ff
2791
2792/* PLLSETUP */
2793#define R367CAB_PLLSETUP 0xf0da
2794#define F367CAB_PLL_PDIV 0xf0da0070
2795#define F367CAB_PLL_KDIV 0xf0da000f
2796
2797/* DUAL_AD12 */
2798#define R367CAB_DUAL_AD12 0xf0db
2799#define F367CAB_FS20M 0xf0db0020
2800#define F367CAB_FS50M 0xf0db0010
2801#define F367CAB_INMODe0 0xf0db0008
2802#define F367CAB_POFFQ 0xf0db0004
2803#define F367CAB_POFFI 0xf0db0002
2804#define F367CAB_INMODE1 0xf0db0001
2805
2806/* TSTBIST */
2807#define R367CAB_TSTBIST 0xf0dc
2808#define F367CAB_TST_BYP_CLK 0xf0dc0080
2809#define F367CAB_TST_GCLKENA_STD 0xf0dc0040
2810#define F367CAB_TST_GCLKENA 0xf0dc0020
2811#define F367CAB_TST_MEMBIST 0xf0dc001f
2812
2813/* CTRL_1 */
2814#define R367CAB_CTRL_1 0xf402
2815#define F367CAB_SOFT_RST 0xf4020080
2816#define F367CAB_EQU_RST 0xf4020008
2817#define F367CAB_CRL_RST 0xf4020004
2818#define F367CAB_TRL_RST 0xf4020002
2819#define F367CAB_AGC_RST 0xf4020001
2820
2821/* CTRL_2 */
2822#define R367CAB_CTRL_2 0xf403
2823#define F367CAB_DEINT_RST 0xf4030008
2824#define F367CAB_RS_RST 0xf4030004
2825
2826/* IT_STATUS1 */
2827#define R367CAB_IT_STATUS1 0xf408
2828#define F367CAB_SWEEP_OUT 0xf4080080
2829#define F367CAB_FSM_CRL 0xf4080040
2830#define F367CAB_CRL_LOCK 0xf4080020
2831#define F367CAB_MFSM 0xf4080010
2832#define F367CAB_TRL_LOCK 0xf4080008
2833#define F367CAB_TRL_AGC_LIMIT 0xf4080004
2834#define F367CAB_ADJ_AGC_LOCK 0xf4080002
2835#define F367CAB_AGC_QAM_LOCK 0xf4080001
2836
2837/* IT_STATUS2 */
2838#define R367CAB_IT_STATUS2 0xf409
2839#define F367CAB_TSMF_CNT 0xf4090080
2840#define F367CAB_TSMF_EOF 0xf4090040
2841#define F367CAB_TSMF_RDY 0xf4090020
2842#define F367CAB_FEC_NOCORR 0xf4090010
2843#define F367CAB_SYNCSTATE 0xf4090008
2844#define F367CAB_DEINT_LOCK 0xf4090004
2845#define F367CAB_FADDING_FRZ 0xf4090002
2846#define F367CAB_TAPMON_ALARM 0xf4090001
2847
2848/* IT_EN1 */
2849#define R367CAB_IT_EN1 0xf40a
2850#define F367CAB_SWEEP_OUTE 0xf40a0080
2851#define F367CAB_FSM_CRLE 0xf40a0040
2852#define F367CAB_CRL_LOCKE 0xf40a0020
2853#define F367CAB_MFSME 0xf40a0010
2854#define F367CAB_TRL_LOCKE 0xf40a0008
2855#define F367CAB_TRL_AGC_LIMITE 0xf40a0004
2856#define F367CAB_ADJ_AGC_LOCKE 0xf40a0002
2857#define F367CAB_AGC_LOCKE 0xf40a0001
2858
2859/* IT_EN2 */
2860#define R367CAB_IT_EN2 0xf40b
2861#define F367CAB_TSMF_CNTE 0xf40b0080
2862#define F367CAB_TSMF_EOFE 0xf40b0040
2863#define F367CAB_TSMF_RDYE 0xf40b0020
2864#define F367CAB_FEC_NOCORRE 0xf40b0010
2865#define F367CAB_SYNCSTATEE 0xf40b0008
2866#define F367CAB_DEINT_LOCKE 0xf40b0004
2867#define F367CAB_FADDING_FRZE 0xf40b0002
2868#define F367CAB_TAPMON_ALARME 0xf40b0001
2869
2870/* CTRL_STATUS */
2871#define R367CAB_CTRL_STATUS 0xf40c
2872#define F367CAB_QAMFEC_LOCK 0xf40c0004
2873#define F367CAB_TSMF_LOCK 0xf40c0002
2874#define F367CAB_TSMF_ERROR 0xf40c0001
2875
2876/* TEST_CTL */
2877#define R367CAB_TEST_CTL 0xf40f
2878#define F367CAB_TST_BLK_SEL 0xf40f0060
2879#define F367CAB_TST_BUS_SEL 0xf40f001f
2880
2881/* AGC_CTL */
2882#define R367CAB_AGC_CTL 0xf410
2883#define F367CAB_AGC_LCK_TH 0xf41000f0
2884#define F367CAB_AGC_ACCUMRSTSEL 0xf4100007
2885
2886/* AGC_IF_CFG */
2887#define R367CAB_AGC_IF_CFG 0xf411
2888#define F367CAB_AGC_IF_BWSEL 0xf41100f0
2889#define F367CAB_AGC_IF_FREEZE 0xf4110002
2890
2891/* AGC_RF_CFG */
2892#define R367CAB_AGC_RF_CFG 0xf412
2893#define F367CAB_AGC_RF_BWSEL 0xf4120070
2894#define F367CAB_AGC_RF_FREEZE 0xf4120002
2895
2896/* AGC_PWM_CFG */
2897#define R367CAB_AGC_PWM_CFG 0xf413
2898#define F367CAB_AGC_RF_PWM_TST 0xf4130080
2899#define F367CAB_AGC_RF_PWM_INV 0xf4130040
2900#define F367CAB_AGC_IF_PWM_TST 0xf4130008
2901#define F367CAB_AGC_IF_PWM_INV 0xf4130004
2902#define F367CAB_AGC_PWM_CLKDIV 0xf4130003
2903
2904/* AGC_PWR_REF_L */
2905#define R367CAB_AGC_PWR_REF_L 0xf414
2906#define F367CAB_AGC_PWRREF_LO 0xf41400ff
2907
2908/* AGC_PWR_REF_H */
2909#define R367CAB_AGC_PWR_REF_H 0xf415
2910#define F367CAB_AGC_PWRREF_HI 0xf4150003
2911
2912/* AGC_RF_TH_L */
2913#define R367CAB_AGC_RF_TH_L 0xf416
2914#define F367CAB_AGC_RF_TH_LO 0xf41600ff
2915
2916/* AGC_RF_TH_H */
2917#define R367CAB_AGC_RF_TH_H 0xf417
2918#define F367CAB_AGC_RF_TH_HI 0xf417000f
2919
2920/* AGC_IF_LTH_L */
2921#define R367CAB_AGC_IF_LTH_L 0xf418
2922#define F367CAB_AGC_IF_THLO_LO 0xf41800ff
2923
2924/* AGC_IF_LTH_H */
2925#define R367CAB_AGC_IF_LTH_H 0xf419
2926#define F367CAB_AGC_IF_THLO_HI 0xf419000f
2927
2928/* AGC_IF_HTH_L */
2929#define R367CAB_AGC_IF_HTH_L 0xf41a
2930#define F367CAB_AGC_IF_THHI_LO 0xf41a00ff
2931
2932/* AGC_IF_HTH_H */
2933#define R367CAB_AGC_IF_HTH_H 0xf41b
2934#define F367CAB_AGC_IF_THHI_HI 0xf41b000f
2935
2936/* AGC_PWR_RD_L */
2937#define R367CAB_AGC_PWR_RD_L 0xf41c
2938#define F367CAB_AGC_PWR_WORD_LO 0xf41c00ff
2939
2940/* AGC_PWR_RD_M */
2941#define R367CAB_AGC_PWR_RD_M 0xf41d
2942#define F367CAB_AGC_PWR_WORD_ME 0xf41d00ff
2943
2944/* AGC_PWR_RD_H */
2945#define R367CAB_AGC_PWR_RD_H 0xf41e
2946#define F367CAB_AGC_PWR_WORD_HI 0xf41e0003
2947
2948/* AGC_PWM_IFCMD_L */
2949#define R367CAB_AGC_PWM_IFCMD_L 0xf420
2950#define F367CAB_AGC_IF_PWMCMD_LO 0xf42000ff
2951
2952/* AGC_PWM_IFCMD_H */
2953#define R367CAB_AGC_PWM_IFCMD_H 0xf421
2954#define F367CAB_AGC_IF_PWMCMD_HI 0xf421000f
2955
2956/* AGC_PWM_RFCMD_L */
2957#define R367CAB_AGC_PWM_RFCMD_L 0xf422
2958#define F367CAB_AGC_RF_PWMCMD_LO 0xf42200ff
2959
2960/* AGC_PWM_RFCMD_H */
2961#define R367CAB_AGC_PWM_RFCMD_H 0xf423
2962#define F367CAB_AGC_RF_PWMCMD_HI 0xf423000f
2963
2964/* IQDEM_CFG */
2965#define R367CAB_IQDEM_CFG 0xf424
2966#define F367CAB_IQDEM_CLK_SEL 0xf4240004
2967#define F367CAB_IQDEM_INVIQ 0xf4240002
2968#define F367CAB_IQDEM_A2dTYPE 0xf4240001
2969
2970/* MIX_NCO_LL */
2971#define R367CAB_MIX_NCO_LL 0xf425
2972#define F367CAB_MIX_NCO_INC_LL 0xf42500ff
2973
2974/* MIX_NCO_HL */
2975#define R367CAB_MIX_NCO_HL 0xf426
2976#define F367CAB_MIX_NCO_INC_HL 0xf42600ff
2977
2978/* MIX_NCO_HH */
2979#define R367CAB_MIX_NCO_HH 0xf427
2980#define F367CAB_MIX_NCO_INVCNST 0xf4270080
2981#define F367CAB_MIX_NCO_INC_HH 0xf427007f
2982
2983/* SRC_NCO_LL */
2984#define R367CAB_SRC_NCO_LL 0xf428
2985#define F367CAB_SRC_NCO_INC_LL 0xf42800ff
2986
2987/* SRC_NCO_LH */
2988#define R367CAB_SRC_NCO_LH 0xf429
2989#define F367CAB_SRC_NCO_INC_LH 0xf42900ff
2990
2991/* SRC_NCO_HL */
2992#define R367CAB_SRC_NCO_HL 0xf42a
2993#define F367CAB_SRC_NCO_INC_HL 0xf42a00ff
2994
2995/* SRC_NCO_HH */
2996#define R367CAB_SRC_NCO_HH 0xf42b
2997#define F367CAB_SRC_NCO_INC_HH 0xf42b007f
2998
2999/* IQDEM_GAIN_SRC_L */
3000#define R367CAB_IQDEM_GAIN_SRC_L 0xf42c
3001#define F367CAB_GAIN_SRC_LO 0xf42c00ff
3002
3003/* IQDEM_GAIN_SRC_H */
3004#define R367CAB_IQDEM_GAIN_SRC_H 0xf42d
3005#define F367CAB_GAIN_SRC_HI 0xf42d0003
3006
3007/* IQDEM_DCRM_CFG_LL */
3008#define R367CAB_IQDEM_DCRM_CFG_LL 0xf430
3009#define F367CAB_DCRM0_DCIN_L 0xf43000ff
3010
3011/* IQDEM_DCRM_CFG_LH */
3012#define R367CAB_IQDEM_DCRM_CFG_LH 0xf431
3013#define F367CAB_DCRM1_I_DCIN_L 0xf43100fc
3014#define F367CAB_DCRM0_DCIN_H 0xf4310003
3015
3016/* IQDEM_DCRM_CFG_HL */
3017#define R367CAB_IQDEM_DCRM_CFG_HL 0xf432
3018#define F367CAB_DCRM1_Q_DCIN_L 0xf43200f0
3019#define F367CAB_DCRM1_I_DCIN_H 0xf432000f
3020
3021/* IQDEM_DCRM_CFG_HH */
3022#define R367CAB_IQDEM_DCRM_CFG_HH 0xf433
3023#define F367CAB_DCRM1_FRZ 0xf4330080
3024#define F367CAB_DCRM0_FRZ 0xf4330040
3025#define F367CAB_DCRM1_Q_DCIN_H 0xf433003f
3026
3027/* IQDEM_ADJ_COEFf0 */
3028#define R367CAB_IQDEM_ADJ_COEFF0 0xf434
3029#define F367CAB_ADJIIR_COEFF10_L 0xf43400ff
3030
3031/* IQDEM_ADJ_COEFF1 */
3032#define R367CAB_IQDEM_ADJ_COEFF1 0xf435
3033#define F367CAB_ADJIIR_COEFF11_L 0xf43500fc
3034#define F367CAB_ADJIIR_COEFF10_H 0xf4350003
3035
3036/* IQDEM_ADJ_COEFF2 */
3037#define R367CAB_IQDEM_ADJ_COEFF2 0xf436
3038#define F367CAB_ADJIIR_COEFF12_L 0xf43600f0
3039#define F367CAB_ADJIIR_COEFF11_H 0xf436000f
3040
3041/* IQDEM_ADJ_COEFF3 */
3042#define R367CAB_IQDEM_ADJ_COEFF3 0xf437
3043#define F367CAB_ADJIIR_COEFF20_L 0xf43700c0
3044#define F367CAB_ADJIIR_COEFF12_H 0xf437003f
3045
3046/* IQDEM_ADJ_COEFF4 */
3047#define R367CAB_IQDEM_ADJ_COEFF4 0xf438
3048#define F367CAB_ADJIIR_COEFF20_H 0xf43800ff
3049
3050/* IQDEM_ADJ_COEFF5 */
3051#define R367CAB_IQDEM_ADJ_COEFF5 0xf439
3052#define F367CAB_ADJIIR_COEFF21_L 0xf43900ff
3053
3054/* IQDEM_ADJ_COEFF6 */
3055#define R367CAB_IQDEM_ADJ_COEFF6 0xf43a
3056#define F367CAB_ADJIIR_COEFF22_L 0xf43a00fc
3057#define F367CAB_ADJIIR_COEFF21_H 0xf43a0003
3058
3059/* IQDEM_ADJ_COEFF7 */
3060#define R367CAB_IQDEM_ADJ_COEFF7 0xf43b
3061#define F367CAB_ADJIIR_COEFF22_H 0xf43b000f
3062
3063/* IQDEM_ADJ_EN */
3064#define R367CAB_IQDEM_ADJ_EN 0xf43c
3065#define F367CAB_ALLPASSFILT_EN 0xf43c0008
3066#define F367CAB_ADJ_AGC_EN 0xf43c0004
3067#define F367CAB_ADJ_COEFF_FRZ 0xf43c0002
3068#define F367CAB_ADJ_EN 0xf43c0001
3069
3070/* IQDEM_ADJ_AGC_REF */
3071#define R367CAB_IQDEM_ADJ_AGC_REF 0xf43d
3072#define F367CAB_ADJ_AGC_REF 0xf43d00ff
3073
3074/* ALLPASSFILT1 */
3075#define R367CAB_ALLPASSFILT1 0xf440
3076#define F367CAB_ALLPASSFILT_COEFF1_LO 0xf44000ff
3077
3078/* ALLPASSFILT2 */
3079#define R367CAB_ALLPASSFILT2 0xf441
3080#define F367CAB_ALLPASSFILT_COEFF1_ME 0xf44100ff
3081
3082/* ALLPASSFILT3 */
3083#define R367CAB_ALLPASSFILT3 0xf442
3084#define F367CAB_ALLPASSFILT_COEFF2_LO 0xf44200c0
3085#define F367CAB_ALLPASSFILT_COEFF1_HI 0xf442003f
3086
3087/* ALLPASSFILT4 */
3088#define R367CAB_ALLPASSFILT4 0xf443
3089#define F367CAB_ALLPASSFILT_COEFF2_MEL 0xf44300ff
3090
3091/* ALLPASSFILT5 */
3092#define R367CAB_ALLPASSFILT5 0xf444
3093#define F367CAB_ALLPASSFILT_COEFF2_MEH 0xf44400ff
3094
3095/* ALLPASSFILT6 */
3096#define R367CAB_ALLPASSFILT6 0xf445
3097#define F367CAB_ALLPASSFILT_COEFF3_LO 0xf44500f0
3098#define F367CAB_ALLPASSFILT_COEFF2_HI 0xf445000f
3099
3100/* ALLPASSFILT7 */
3101#define R367CAB_ALLPASSFILT7 0xf446
3102#define F367CAB_ALLPASSFILT_COEFF3_MEL 0xf44600ff
3103
3104/* ALLPASSFILT8 */
3105#define R367CAB_ALLPASSFILT8 0xf447
3106#define F367CAB_ALLPASSFILT_COEFF3_MEH 0xf44700ff
3107
3108/* ALLPASSFILT9 */
3109#define R367CAB_ALLPASSFILT9 0xf448
3110#define F367CAB_ALLPASSFILT_COEFF4_LO 0xf44800fc
3111#define F367CAB_ALLPASSFILT_COEFF3_HI 0xf4480003
3112
3113/* ALLPASSFILT10 */
3114#define R367CAB_ALLPASSFILT10 0xf449
3115#define F367CAB_ALLPASSFILT_COEFF4_ME 0xf44900ff
3116
3117/* ALLPASSFILT11 */
3118#define R367CAB_ALLPASSFILT11 0xf44a
3119#define F367CAB_ALLPASSFILT_COEFF4_HI 0xf44a00ff
3120
3121/* TRL_AGC_CFG */
3122#define R367CAB_TRL_AGC_CFG 0xf450
3123#define F367CAB_TRL_AGC_FREEZE 0xf4500080
3124#define F367CAB_TRL_AGC_REF 0xf450007f
3125
3126/* TRL_LPF_CFG */
3127#define R367CAB_TRL_LPF_CFG 0xf454
3128#define F367CAB_NYQPOINT_INV 0xf4540040
3129#define F367CAB_TRL_SHIFT 0xf4540030
3130#define F367CAB_NYQ_COEFF_SEL 0xf454000c
3131#define F367CAB_TRL_LPF_FREEZE 0xf4540002
3132#define F367CAB_TRL_LPF_CRT 0xf4540001
3133
3134/* TRL_LPF_ACQ_GAIN */
3135#define R367CAB_TRL_LPF_ACQ_GAIN 0xf455
3136#define F367CAB_TRL_GDIR_ACQ 0xf4550070
3137#define F367CAB_TRL_GINT_ACQ 0xf4550007
3138
3139/* TRL_LPF_TRK_GAIN */
3140#define R367CAB_TRL_LPF_TRK_GAIN 0xf456
3141#define F367CAB_TRL_GDIR_TRK 0xf4560070
3142#define F367CAB_TRL_GINT_TRK 0xf4560007
3143
3144/* TRL_LPF_OUT_GAIN */
3145#define R367CAB_TRL_LPF_OUT_GAIN 0xf457
3146#define F367CAB_TRL_GAIN_OUT 0xf4570007
3147
3148/* TRL_LOCKDET_LTH */
3149#define R367CAB_TRL_LOCKDET_LTH 0xf458
3150#define F367CAB_TRL_LCK_THLO 0xf4580007
3151
3152/* TRL_LOCKDET_HTH */
3153#define R367CAB_TRL_LOCKDET_HTH 0xf459
3154#define F367CAB_TRL_LCK_THHI 0xf45900ff
3155
3156/* TRL_LOCKDET_TRGVAL */
3157#define R367CAB_TRL_LOCKDET_TRGVAL 0xf45a
3158#define F367CAB_TRL_LCK_TRG 0xf45a00ff
3159
3160/* IQ_QAM */
3161#define R367CAB_IQ_QAM 0xf45c
3162#define F367CAB_IQ_INPUT 0xf45c0008
3163#define F367CAB_DETECT_MODE 0xf45c0007
3164
3165/* FSM_STATE */
3166#define R367CAB_FSM_STATE 0xf460
3167#define F367CAB_CRL_DFE 0xf4600080
3168#define F367CAB_DFE_START 0xf4600040
3169#define F367CAB_CTRLG_START 0xf4600030
3170#define F367CAB_FSM_FORCESTATE 0xf460000f
3171
3172/* FSM_CTL */
3173#define R367CAB_FSM_CTL 0xf461
3174#define F367CAB_FEC2_EN 0xf4610040
3175#define F367CAB_SIT_EN 0xf4610020
3176#define F367CAB_TRL_AHEAD 0xf4610010
3177#define F367CAB_TRL2_EN 0xf4610008
3178#define F367CAB_FSM_EQA1_EN 0xf4610004
3179#define F367CAB_FSM_BKP_DIS 0xf4610002
3180#define F367CAB_FSM_FORCE_EN 0xf4610001
3181
3182/* FSM_STS */
3183#define R367CAB_FSM_STS 0xf462
3184#define F367CAB_FSM_STATUS 0xf462000f
3185
3186/* FSM_SNR0_HTH */
3187#define R367CAB_FSM_SNR0_HTH 0xf463
3188#define F367CAB_SNR0_HTH 0xf46300ff
3189
3190/* FSM_SNR1_HTH */
3191#define R367CAB_FSM_SNR1_HTH 0xf464
3192#define F367CAB_SNR1_HTH 0xf46400ff
3193
3194/* FSM_SNR2_HTH */
3195#define R367CAB_FSM_SNR2_HTH 0xf465
3196#define F367CAB_SNR2_HTH 0xf46500ff
3197
3198/* FSM_SNR0_LTH */
3199#define R367CAB_FSM_SNR0_LTH 0xf466
3200#define F367CAB_SNR0_LTH 0xf46600ff
3201
3202/* FSM_SNR1_LTH */
3203#define R367CAB_FSM_SNR1_LTH 0xf467
3204#define F367CAB_SNR1_LTH 0xf46700ff
3205
3206/* FSM_EQA1_HTH */
3207#define R367CAB_FSM_EQA1_HTH 0xf468
3208#define F367CAB_SNR3_HTH_LO 0xf46800f0
3209#define F367CAB_EQA1_HTH 0xf468000f
3210
3211/* FSM_TEMPO */
3212#define R367CAB_FSM_TEMPO 0xf469
3213#define F367CAB_SIT 0xf46900c0
3214#define F367CAB_WST 0xf4690038
3215#define F367CAB_ELT 0xf4690006
3216#define F367CAB_SNR3_HTH_HI 0xf4690001
3217
3218/* FSM_CONFIG */
3219#define R367CAB_FSM_CONFIG 0xf46a
3220#define F367CAB_FEC2_DFEOFF 0xf46a0004
3221#define F367CAB_PRIT_STATE 0xf46a0002
3222#define F367CAB_MODMAP_STATE 0xf46a0001
3223
3224/* EQU_I_TESTTAP_L */
3225#define R367CAB_EQU_I_TESTTAP_L 0xf474
3226#define F367CAB_I_TEST_TAP_L 0xf47400ff
3227
3228/* EQU_I_TESTTAP_M */
3229#define R367CAB_EQU_I_TESTTAP_M 0xf475
3230#define F367CAB_I_TEST_TAP_M 0xf47500ff
3231
3232/* EQU_I_TESTTAP_H */
3233#define R367CAB_EQU_I_TESTTAP_H 0xf476
3234#define F367CAB_I_TEST_TAP_H 0xf476001f
3235
3236/* EQU_TESTAP_CFG */
3237#define R367CAB_EQU_TESTAP_CFG 0xf477
3238#define F367CAB_TEST_FFE_DFE_SEL 0xf4770040
3239#define F367CAB_TEST_TAP_SELECT 0xf477003f
3240
3241/* EQU_Q_TESTTAP_L */
3242#define R367CAB_EQU_Q_TESTTAP_L 0xf478
3243#define F367CAB_Q_TEST_TAP_L 0xf47800ff
3244
3245/* EQU_Q_TESTTAP_M */
3246#define R367CAB_EQU_Q_TESTTAP_M 0xf479
3247#define F367CAB_Q_TEST_TAP_M 0xf47900ff
3248
3249/* EQU_Q_TESTTAP_H */
3250#define R367CAB_EQU_Q_TESTTAP_H 0xf47a
3251#define F367CAB_Q_TEST_TAP_H 0xf47a001f
3252
3253/* EQU_TAP_CTRL */
3254#define R367CAB_EQU_TAP_CTRL 0xf47b
3255#define F367CAB_MTAP_FRZ 0xf47b0010
3256#define F367CAB_PRE_FREEZE 0xf47b0008
3257#define F367CAB_DFE_TAPMON_EN 0xf47b0004
3258#define F367CAB_FFE_TAPMON_EN 0xf47b0002
3259#define F367CAB_MTAP_ONLY 0xf47b0001
3260
3261/* EQU_CTR_CRL_CONTROL_L */
3262#define R367CAB_EQU_CTR_CRL_CONTROL_L 0xf47c
3263#define F367CAB_EQU_CTR_CRL_CONTROL_LO 0xf47c00ff
3264
3265/* EQU_CTR_CRL_CONTROL_H */
3266#define R367CAB_EQU_CTR_CRL_CONTROL_H 0xf47d
3267#define F367CAB_EQU_CTR_CRL_CONTROL_HI 0xf47d00ff
3268
3269/* EQU_CTR_HIPOW_L */
3270#define R367CAB_EQU_CTR_HIPOW_L 0xf47e
3271#define F367CAB_CTR_HIPOW_L 0xf47e00ff
3272
3273/* EQU_CTR_HIPOW_H */
3274#define R367CAB_EQU_CTR_HIPOW_H 0xf47f
3275#define F367CAB_CTR_HIPOW_H 0xf47f00ff
3276
3277/* EQU_I_EQU_LO */
3278#define R367CAB_EQU_I_EQU_LO 0xf480
3279#define F367CAB_EQU_I_EQU_L 0xf48000ff
3280
3281/* EQU_I_EQU_HI */
3282#define R367CAB_EQU_I_EQU_HI 0xf481
3283#define F367CAB_EQU_I_EQU_H 0xf4810003
3284
3285/* EQU_Q_EQU_LO */
3286#define R367CAB_EQU_Q_EQU_LO 0xf482
3287#define F367CAB_EQU_Q_EQU_L 0xf48200ff
3288
3289/* EQU_Q_EQU_HI */
3290#define R367CAB_EQU_Q_EQU_HI 0xf483
3291#define F367CAB_EQU_Q_EQU_H 0xf4830003
3292
3293/* EQU_MAPPER */
3294#define R367CAB_EQU_MAPPER 0xf484
3295#define F367CAB_QUAD_AUTO 0xf4840080
3296#define F367CAB_QUAD_INV 0xf4840040
3297#define F367CAB_QAM_MODE 0xf4840007
3298
3299/* EQU_SWEEP_RATE */
3300#define R367CAB_EQU_SWEEP_RATE 0xf485
3301#define F367CAB_SNR_PER 0xf48500c0
3302#define F367CAB_SWEEP_RATE 0xf485003f
3303
3304/* EQU_SNR_LO */
3305#define R367CAB_EQU_SNR_LO 0xf486
3306#define F367CAB_SNR_LO 0xf48600ff
3307
3308/* EQU_SNR_HI */
3309#define R367CAB_EQU_SNR_HI 0xf487
3310#define F367CAB_SNR_HI 0xf48700ff
3311
3312/* EQU_GAMMA_LO */
3313#define R367CAB_EQU_GAMMA_LO 0xf488
3314#define F367CAB_GAMMA_LO 0xf48800ff
3315
3316/* EQU_GAMMA_HI */
3317#define R367CAB_EQU_GAMMA_HI 0xf489
3318#define F367CAB_GAMMA_ME 0xf48900ff
3319
3320/* EQU_ERR_GAIN */
3321#define R367CAB_EQU_ERR_GAIN 0xf48a
3322#define F367CAB_EQA1MU 0xf48a0070
3323#define F367CAB_CRL2MU 0xf48a000e
3324#define F367CAB_GAMMA_HI 0xf48a0001
3325
3326/* EQU_RADIUS */
3327#define R367CAB_EQU_RADIUS 0xf48b
3328#define F367CAB_RADIUS 0xf48b00ff
3329
3330/* EQU_FFE_MAINTAP */
3331#define R367CAB_EQU_FFE_MAINTAP 0xf48c
3332#define F367CAB_FFE_MAINTAP_INIT 0xf48c00ff
3333
3334/* EQU_FFE_LEAKAGE */
3335#define R367CAB_EQU_FFE_LEAKAGE 0xf48e
3336#define F367CAB_LEAK_PER 0xf48e00f0
3337#define F367CAB_EQU_OUTSEL 0xf48e0002
3338#define F367CAB_PNT2dFE 0xf48e0001
3339
3340/* EQU_FFE_MAINTAP_POS */
3341#define R367CAB_EQU_FFE_MAINTAP_POS 0xf48f
3342#define F367CAB_FFE_LEAK_EN 0xf48f0080
3343#define F367CAB_DFE_LEAK_EN 0xf48f0040
3344#define F367CAB_FFE_MAINTAP_POS 0xf48f003f
3345
3346/* EQU_GAIN_WIDE */
3347#define R367CAB_EQU_GAIN_WIDE 0xf490
3348#define F367CAB_DFE_GAIN_WIDE 0xf49000f0
3349#define F367CAB_FFE_GAIN_WIDE 0xf490000f
3350
3351/* EQU_GAIN_NARROW */
3352#define R367CAB_EQU_GAIN_NARROW 0xf491
3353#define F367CAB_DFE_GAIN_NARROW 0xf49100f0
3354#define F367CAB_FFE_GAIN_NARROW 0xf491000f
3355
3356/* EQU_CTR_LPF_GAIN */
3357#define R367CAB_EQU_CTR_LPF_GAIN 0xf492
3358#define F367CAB_CTR_GTO 0xf4920080
3359#define F367CAB_CTR_GDIR 0xf4920070
3360#define F367CAB_SWEEP_EN 0xf4920008
3361#define F367CAB_CTR_GINT 0xf4920007
3362
3363/* EQU_CRL_LPF_GAIN */
3364#define R367CAB_EQU_CRL_LPF_GAIN 0xf493
3365#define F367CAB_CRL_GTO 0xf4930080
3366#define F367CAB_CRL_GDIR 0xf4930070
3367#define F367CAB_SWEEP_DIR 0xf4930008
3368#define F367CAB_CRL_GINT 0xf4930007
3369
3370/* EQU_GLOBAL_GAIN */
3371#define R367CAB_EQU_GLOBAL_GAIN 0xf494
3372#define F367CAB_CRL_GAIN 0xf49400f8
3373#define F367CAB_CTR_INC_GAIN 0xf4940004
3374#define F367CAB_CTR_FRAC 0xf4940003
3375
3376/* EQU_CRL_LD_SEN */
3377#define R367CAB_EQU_CRL_LD_SEN 0xf495
3378#define F367CAB_CTR_BADPOINT_EN 0xf4950080
3379#define F367CAB_CTR_GAIN 0xf4950070
3380#define F367CAB_LIMANEN 0xf4950008
3381#define F367CAB_CRL_LD_SEN 0xf4950007
3382
3383/* EQU_CRL_LD_VAL */
3384#define R367CAB_EQU_CRL_LD_VAL 0xf496
3385#define F367CAB_CRL_BISTH_LIMIT 0xf4960080
3386#define F367CAB_CARE_EN 0xf4960040
3387#define F367CAB_CRL_LD_PER 0xf4960030
3388#define F367CAB_CRL_LD_WST 0xf496000c
3389#define F367CAB_CRL_LD_TFS 0xf4960003
3390
3391/* EQU_CRL_TFR */
3392#define R367CAB_EQU_CRL_TFR 0xf497
3393#define F367CAB_CRL_LD_TFR 0xf49700ff
3394
3395/* EQU_CRL_BISTH_LO */
3396#define R367CAB_EQU_CRL_BISTH_LO 0xf498
3397#define F367CAB_CRL_BISTH_LO 0xf49800ff
3398
3399/* EQU_CRL_BISTH_HI */
3400#define R367CAB_EQU_CRL_BISTH_HI 0xf499
3401#define F367CAB_CRL_BISTH_HI 0xf49900ff
3402
3403/* EQU_SWEEP_RANGE_LO */
3404#define R367CAB_EQU_SWEEP_RANGE_LO 0xf49a
3405#define F367CAB_SWEEP_RANGE_LO 0xf49a00ff
3406
3407/* EQU_SWEEP_RANGE_HI */
3408#define R367CAB_EQU_SWEEP_RANGE_HI 0xf49b
3409#define F367CAB_SWEEP_RANGE_HI 0xf49b00ff
3410
3411/* EQU_CRL_LIMITER */
3412#define R367CAB_EQU_CRL_LIMITER 0xf49c
3413#define F367CAB_BISECTOR_EN 0xf49c0080
3414#define F367CAB_PHEST128_EN 0xf49c0040
3415#define F367CAB_CRL_LIM 0xf49c003f
3416
3417/* EQU_MODULUS_MAP */
3418#define R367CAB_EQU_MODULUS_MAP 0xf49d
3419#define F367CAB_PNT_DEPTH 0xf49d00e0
3420#define F367CAB_MODULUS_CMP 0xf49d001f
3421
3422/* EQU_PNT_GAIN */
3423#define R367CAB_EQU_PNT_GAIN 0xf49e
3424#define F367CAB_PNT_EN 0xf49e0080
3425#define F367CAB_MODULUSMAP_EN 0xf49e0040
3426#define F367CAB_PNT_GAIN 0xf49e003f
3427
3428/* FEC_AC_CTR_0 */
3429#define R367CAB_FEC_AC_CTR_0 0xf4a8
3430#define F367CAB_BE_BYPASS 0xf4a80020
3431#define F367CAB_REFRESH47 0xf4a80010
3432#define F367CAB_CT_NBST 0xf4a80008
3433#define F367CAB_TEI_ENA 0xf4a80004
3434#define F367CAB_DS_ENA 0xf4a80002
3435#define F367CAB_TSMF_EN 0xf4a80001
3436
3437/* FEC_AC_CTR_1 */
3438#define R367CAB_FEC_AC_CTR_1 0xf4a9
3439#define F367CAB_DEINT_DEPTH 0xf4a900ff
3440
3441/* FEC_AC_CTR_2 */
3442#define R367CAB_FEC_AC_CTR_2 0xf4aa
3443#define F367CAB_DEINT_M 0xf4aa00f8
3444#define F367CAB_DIS_UNLOCK 0xf4aa0004
3445#define F367CAB_DESCR_MODE 0xf4aa0003
3446
3447/* FEC_AC_CTR_3 */
3448#define R367CAB_FEC_AC_CTR_3 0xf4ab
3449#define F367CAB_DI_UNLOCK 0xf4ab0080
3450#define F367CAB_DI_FREEZE 0xf4ab0040
3451#define F367CAB_MISMATCH 0xf4ab0030
3452#define F367CAB_ACQ_MODE 0xf4ab000c
3453#define F367CAB_TRK_MODE 0xf4ab0003
3454
3455/* FEC_STATUS */
3456#define R367CAB_FEC_STATUS 0xf4ac
3457#define F367CAB_DEINT_SMCNTR 0xf4ac00e0
3458#define F367CAB_DEINT_SYNCSTATE 0xf4ac0018
3459#define F367CAB_DEINT_SYNLOST 0xf4ac0004
3460#define F367CAB_DESCR_SYNCSTATE 0xf4ac0002
3461
3462/* RS_COUNTER_0 */
3463#define R367CAB_RS_COUNTER_0 0xf4ae
3464#define F367CAB_BK_CT_L 0xf4ae00ff
3465
3466/* RS_COUNTER_1 */
3467#define R367CAB_RS_COUNTER_1 0xf4af
3468#define F367CAB_BK_CT_H 0xf4af00ff
3469
3470/* RS_COUNTER_2 */
3471#define R367CAB_RS_COUNTER_2 0xf4b0
3472#define F367CAB_CORR_CT_L 0xf4b000ff
3473
3474/* RS_COUNTER_3 */
3475#define R367CAB_RS_COUNTER_3 0xf4b1
3476#define F367CAB_CORR_CT_H 0xf4b100ff
3477
3478/* RS_COUNTER_4 */
3479#define R367CAB_RS_COUNTER_4 0xf4b2
3480#define F367CAB_UNCORR_CT_L 0xf4b200ff
3481
3482/* RS_COUNTER_5 */
3483#define R367CAB_RS_COUNTER_5 0xf4b3
3484#define F367CAB_UNCORR_CT_H 0xf4b300ff
3485
3486/* BERT_0 */
3487#define R367CAB_BERT_0 0xf4b4
3488#define F367CAB_RS_NOCORR 0xf4b40004
3489#define F367CAB_CT_HOLD 0xf4b40002
3490#define F367CAB_CT_CLEAR 0xf4b40001
3491
3492/* BERT_1 */
3493#define R367CAB_BERT_1 0xf4b5
3494#define F367CAB_BERT_ON 0xf4b50020
3495#define F367CAB_BERT_ERR_SRC 0xf4b50010
3496#define F367CAB_BERT_ERR_MODE 0xf4b50008
3497#define F367CAB_BERT_NBYTE 0xf4b50007
3498
3499/* BERT_2 */
3500#define R367CAB_BERT_2 0xf4b6
3501#define F367CAB_BERT_ERRCOUNT_L 0xf4b600ff
3502
3503/* BERT_3 */
3504#define R367CAB_BERT_3 0xf4b7
3505#define F367CAB_BERT_ERRCOUNT_H 0xf4b700ff
3506
3507/* OUTFORMAT_0 */
3508#define R367CAB_OUTFORMAT_0 0xf4b8
3509#define F367CAB_CLK_POLARITY 0xf4b80080
3510#define F367CAB_FEC_TYPE 0xf4b80040
3511#define F367CAB_SYNC_STRIP 0xf4b80008
3512#define F367CAB_TS_SWAP 0xf4b80004
3513#define F367CAB_OUTFORMAT 0xf4b80003
3514
3515/* OUTFORMAT_1 */
3516#define R367CAB_OUTFORMAT_1 0xf4b9
3517#define F367CAB_CI_DIVRANGE 0xf4b900ff
3518
3519/* SMOOTHER_2 */
3520#define R367CAB_SMOOTHER_2 0xf4be
3521#define F367CAB_FIFO_BYPASS 0xf4be0020
3522
3523/* TSMF_CTRL_0 */
3524#define R367CAB_TSMF_CTRL_0 0xf4c0
3525#define F367CAB_TS_NUMBER 0xf4c0001e
3526#define F367CAB_SEL_MODE 0xf4c00001
3527
3528/* TSMF_CTRL_1 */
3529#define R367CAB_TSMF_CTRL_1 0xf4c1
3530#define F367CAB_CHECK_ERROR_BIT 0xf4c10080
3531#define F367CAB_CHCK_F_SYNC 0xf4c10040
3532#define F367CAB_H_MODE 0xf4c10008
3533#define F367CAB_D_V_MODE 0xf4c10004
3534#define F367CAB_MODE 0xf4c10003
3535
3536/* TSMF_CTRL_3 */
3537#define R367CAB_TSMF_CTRL_3 0xf4c3
3538#define F367CAB_SYNC_IN_COUNT 0xf4c300f0
3539#define F367CAB_SYNC_OUT_COUNT 0xf4c3000f
3540
3541/* TS_ON_ID_0 */
3542#define R367CAB_TS_ON_ID_0 0xf4c4
3543#define F367CAB_TS_ID_L 0xf4c400ff
3544
3545/* TS_ON_ID_1 */
3546#define R367CAB_TS_ON_ID_1 0xf4c5
3547#define F367CAB_TS_ID_H 0xf4c500ff
3548
3549/* TS_ON_ID_2 */
3550#define R367CAB_TS_ON_ID_2 0xf4c6
3551#define F367CAB_ON_ID_L 0xf4c600ff
3552
3553/* TS_ON_ID_3 */
3554#define R367CAB_TS_ON_ID_3 0xf4c7
3555#define F367CAB_ON_ID_H 0xf4c700ff
3556
3557/* RE_STATUS_0 */
3558#define R367CAB_RE_STATUS_0 0xf4c8
3559#define F367CAB_RECEIVE_STATUS_L 0xf4c800ff
3560
3561/* RE_STATUS_1 */
3562#define R367CAB_RE_STATUS_1 0xf4c9
3563#define F367CAB_RECEIVE_STATUS_LH 0xf4c900ff
3564
3565/* RE_STATUS_2 */
3566#define R367CAB_RE_STATUS_2 0xf4ca
3567#define F367CAB_RECEIVE_STATUS_HL 0xf4ca00ff
3568
3569/* RE_STATUS_3 */
3570#define R367CAB_RE_STATUS_3 0xf4cb
3571#define F367CAB_RECEIVE_STATUS_HH 0xf4cb003f
3572
3573/* TS_STATUS_0 */
3574#define R367CAB_TS_STATUS_0 0xf4cc
3575#define F367CAB_TS_STATUS_L 0xf4cc00ff
3576
3577/* TS_STATUS_1 */
3578#define R367CAB_TS_STATUS_1 0xf4cd
3579#define F367CAB_TS_STATUS_H 0xf4cd007f
3580
3581/* TS_STATUS_2 */
3582#define R367CAB_TS_STATUS_2 0xf4ce
3583#define F367CAB_ERROR 0xf4ce0080
3584#define F367CAB_EMERGENCY 0xf4ce0040
3585#define F367CAB_CRE_TS 0xf4ce0030
3586#define F367CAB_VER 0xf4ce000e
3587#define F367CAB_M_LOCK 0xf4ce0001
3588
3589/* TS_STATUS_3 */
3590#define R367CAB_TS_STATUS_3 0xf4cf
3591#define F367CAB_UPDATE_READY 0xf4cf0080
3592#define F367CAB_END_FRAME_HEADER 0xf4cf0040
3593#define F367CAB_CONTCNT 0xf4cf0020
3594#define F367CAB_TS_IDENTIFIER_SEL 0xf4cf000f
3595
3596/* T_O_ID_0 */
3597#define R367CAB_T_O_ID_0 0xf4d0
3598#define F367CAB_ON_ID_I_L 0xf4d000ff
3599
3600/* T_O_ID_1 */
3601#define R367CAB_T_O_ID_1 0xf4d1
3602#define F367CAB_ON_ID_I_H 0xf4d100ff
3603
3604/* T_O_ID_2 */
3605#define R367CAB_T_O_ID_2 0xf4d2
3606#define F367CAB_TS_ID_I_L 0xf4d200ff
3607
3608/* T_O_ID_3 */
3609#define R367CAB_T_O_ID_3 0xf4d3
3610#define F367CAB_TS_ID_I_H 0xf4d300ff
3611
3612#define STV0367CAB_NBREGS 187
3613
3614#endif
diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h
new file mode 100644
index 00000000000..91c7ee8b231
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900.h
@@ -0,0 +1,74 @@
1/*
2 * stv0900.h
3 *
4 * Driver for ST STV0900 satellite demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2009 NetUP Inc.
8 * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef STV0900_H
27#define STV0900_H
28
29#include <linux/dvb/frontend.h>
30#include "dvb_frontend.h"
31
32struct stv0900_reg {
33 u16 addr;
34 u8 val;
35};
36
37struct stv0900_config {
38 u8 demod_address;
39 u8 demod_mode;
40 u32 xtal;
41 u8 clkmode;/* 0 for CLKI, 2 for XTALI */
42
43 u8 diseqc_mode;
44
45 u8 path1_mode;
46 u8 path2_mode;
47 struct stv0900_reg *ts_config_regs;
48 u8 tun1_maddress;/* 0, 1, 2, 3 for 0xc0, 0xc2, 0xc4, 0xc6 */
49 u8 tun2_maddress;
50 u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */
51 u8 tun2_adc;
52 u8 tun1_type;/* for now 3 for stb6100 auto, else - software */
53 u8 tun2_type;
54 /* Set device param to start dma */
55 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
56 /* Hook for Lock LED */
57 void (*set_lock_led)(struct dvb_frontend *fe, int offon);
58};
59
60#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \
61 && defined(MODULE))
62extern struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
63 struct i2c_adapter *i2c, int demod);
64#else
65static inline struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
66 struct i2c_adapter *i2c, int demod)
67{
68 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
69 return NULL;
70}
71#endif
72
73#endif
74
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
new file mode 100644
index 00000000000..0ca316d6fff
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_core.c
@@ -0,0 +1,1986 @@
1/*
2 * stv0900_core.c
3 *
4 * Driver for ST STV0900 satellite demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2009 NetUP Inc.
8 * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/string.h>
29#include <linux/slab.h>
30#include <linux/i2c.h>
31
32#include "stv0900.h"
33#include "stv0900_reg.h"
34#include "stv0900_priv.h"
35#include "stv0900_init.h"
36
37int stvdebug = 1;
38module_param_named(debug, stvdebug, int, 0644);
39
40/* internal params node */
41struct stv0900_inode {
42 /* pointer for internal params, one for each pair of demods */
43 struct stv0900_internal *internal;
44 struct stv0900_inode *next_inode;
45};
46
47/* first internal params */
48static struct stv0900_inode *stv0900_first_inode;
49
50/* find chip by i2c adapter and i2c address */
51static struct stv0900_inode *find_inode(struct i2c_adapter *i2c_adap,
52 u8 i2c_addr)
53{
54 struct stv0900_inode *temp_chip = stv0900_first_inode;
55
56 if (temp_chip != NULL) {
57 /*
58 Search of the last stv0900 chip or
59 find it by i2c adapter and i2c address */
60 while ((temp_chip != NULL) &&
61 ((temp_chip->internal->i2c_adap != i2c_adap) ||
62 (temp_chip->internal->i2c_addr != i2c_addr)))
63
64 temp_chip = temp_chip->next_inode;
65
66 }
67
68 return temp_chip;
69}
70
71/* deallocating chip */
72static void remove_inode(struct stv0900_internal *internal)
73{
74 struct stv0900_inode *prev_node = stv0900_first_inode;
75 struct stv0900_inode *del_node = find_inode(internal->i2c_adap,
76 internal->i2c_addr);
77
78 if (del_node != NULL) {
79 if (del_node == stv0900_first_inode) {
80 stv0900_first_inode = del_node->next_inode;
81 } else {
82 while (prev_node->next_inode != del_node)
83 prev_node = prev_node->next_inode;
84
85 if (del_node->next_inode == NULL)
86 prev_node->next_inode = NULL;
87 else
88 prev_node->next_inode =
89 prev_node->next_inode->next_inode;
90 }
91
92 kfree(del_node);
93 }
94}
95
96/* allocating new chip */
97static struct stv0900_inode *append_internal(struct stv0900_internal *internal)
98{
99 struct stv0900_inode *new_node = stv0900_first_inode;
100
101 if (new_node == NULL) {
102 new_node = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL);
103 stv0900_first_inode = new_node;
104 } else {
105 while (new_node->next_inode != NULL)
106 new_node = new_node->next_inode;
107
108 new_node->next_inode = kmalloc(sizeof(struct stv0900_inode),
109 GFP_KERNEL);
110 if (new_node->next_inode != NULL)
111 new_node = new_node->next_inode;
112 else
113 new_node = NULL;
114 }
115
116 if (new_node != NULL) {
117 new_node->internal = internal;
118 new_node->next_inode = NULL;
119 }
120
121 return new_node;
122}
123
124s32 ge2comp(s32 a, s32 width)
125{
126 if (width == 32)
127 return a;
128 else
129 return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a;
130}
131
132void stv0900_write_reg(struct stv0900_internal *intp, u16 reg_addr,
133 u8 reg_data)
134{
135 u8 data[3];
136 int ret;
137 struct i2c_msg i2cmsg = {
138 .addr = intp->i2c_addr,
139 .flags = 0,
140 .len = 3,
141 .buf = data,
142 };
143
144 data[0] = MSB(reg_addr);
145 data[1] = LSB(reg_addr);
146 data[2] = reg_data;
147
148 ret = i2c_transfer(intp->i2c_adap, &i2cmsg, 1);
149 if (ret != 1)
150 dprintk("%s: i2c error %d\n", __func__, ret);
151}
152
153u8 stv0900_read_reg(struct stv0900_internal *intp, u16 reg)
154{
155 int ret;
156 u8 b0[] = { MSB(reg), LSB(reg) };
157 u8 buf = 0;
158 struct i2c_msg msg[] = {
159 {
160 .addr = intp->i2c_addr,
161 .flags = 0,
162 .buf = b0,
163 .len = 2,
164 }, {
165 .addr = intp->i2c_addr,
166 .flags = I2C_M_RD,
167 .buf = &buf,
168 .len = 1,
169 },
170 };
171
172 ret = i2c_transfer(intp->i2c_adap, msg, 2);
173 if (ret != 2)
174 dprintk("%s: i2c error %d, reg[0x%02x]\n",
175 __func__, ret, reg);
176
177 return buf;
178}
179
180static void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
181{
182 u8 position = 0, i = 0;
183
184 (*mask) = label & 0xff;
185
186 while ((position == 0) && (i < 8)) {
187 position = ((*mask) >> i) & 0x01;
188 i++;
189 }
190
191 (*pos) = (i - 1);
192}
193
194void stv0900_write_bits(struct stv0900_internal *intp, u32 label, u8 val)
195{
196 u8 reg, mask, pos;
197
198 reg = stv0900_read_reg(intp, (label >> 16) & 0xffff);
199 extract_mask_pos(label, &mask, &pos);
200
201 val = mask & (val << pos);
202
203 reg = (reg & (~mask)) | val;
204 stv0900_write_reg(intp, (label >> 16) & 0xffff, reg);
205
206}
207
208u8 stv0900_get_bits(struct stv0900_internal *intp, u32 label)
209{
210 u8 val = 0xff;
211 u8 mask, pos;
212
213 extract_mask_pos(label, &mask, &pos);
214
215 val = stv0900_read_reg(intp, label >> 16);
216 val = (val & mask) >> pos;
217
218 return val;
219}
220
221static enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *intp)
222{
223 s32 i;
224
225 if (intp == NULL)
226 return STV0900_INVALID_HANDLE;
227
228 intp->chip_id = stv0900_read_reg(intp, R0900_MID);
229
230 if (intp->errs != STV0900_NO_ERROR)
231 return intp->errs;
232
233 /*Startup sequence*/
234 stv0900_write_reg(intp, R0900_P1_DMDISTATE, 0x5c);
235 stv0900_write_reg(intp, R0900_P2_DMDISTATE, 0x5c);
236 msleep(3);
237 stv0900_write_reg(intp, R0900_P1_TNRCFG, 0x6c);
238 stv0900_write_reg(intp, R0900_P2_TNRCFG, 0x6f);
239 stv0900_write_reg(intp, R0900_P1_I2CRPT, 0x20);
240 stv0900_write_reg(intp, R0900_P2_I2CRPT, 0x20);
241 stv0900_write_reg(intp, R0900_NCOARSE, 0x13);
242 msleep(3);
243 stv0900_write_reg(intp, R0900_I2CCFG, 0x08);
244
245 switch (intp->clkmode) {
246 case 0:
247 case 2:
248 stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20
249 | intp->clkmode);
250 break;
251 default:
252 /* preserve SELOSCI bit */
253 i = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL);
254 stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | i);
255 break;
256 }
257
258 msleep(3);
259 for (i = 0; i < 181; i++)
260 stv0900_write_reg(intp, STV0900_InitVal[i][0],
261 STV0900_InitVal[i][1]);
262
263 if (stv0900_read_reg(intp, R0900_MID) >= 0x20) {
264 stv0900_write_reg(intp, R0900_TSGENERAL, 0x0c);
265 for (i = 0; i < 32; i++)
266 stv0900_write_reg(intp, STV0900_Cut20_AddOnVal[i][0],
267 STV0900_Cut20_AddOnVal[i][1]);
268 }
269
270 stv0900_write_reg(intp, R0900_P1_FSPYCFG, 0x6c);
271 stv0900_write_reg(intp, R0900_P2_FSPYCFG, 0x6c);
272
273 stv0900_write_reg(intp, R0900_P1_PDELCTRL2, 0x01);
274 stv0900_write_reg(intp, R0900_P2_PDELCTRL2, 0x21);
275
276 stv0900_write_reg(intp, R0900_P1_PDELCTRL3, 0x20);
277 stv0900_write_reg(intp, R0900_P2_PDELCTRL3, 0x20);
278
279 stv0900_write_reg(intp, R0900_TSTRES0, 0x80);
280 stv0900_write_reg(intp, R0900_TSTRES0, 0x00);
281
282 return STV0900_NO_ERROR;
283}
284
285static u32 stv0900_get_mclk_freq(struct stv0900_internal *intp, u32 ext_clk)
286{
287 u32 mclk = 90000000, div = 0, ad_div = 0;
288
289 div = stv0900_get_bits(intp, F0900_M_DIV);
290 ad_div = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
291
292 mclk = (div + 1) * ext_clk / ad_div;
293
294 dprintk("%s: Calculated Mclk = %d\n", __func__, mclk);
295
296 return mclk;
297}
298
299static enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *intp, u32 mclk)
300{
301 u32 m_div, clk_sel;
302
303 dprintk("%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
304 intp->quartz);
305
306 if (intp == NULL)
307 return STV0900_INVALID_HANDLE;
308
309 if (intp->errs)
310 return STV0900_I2C_ERROR;
311
312 clk_sel = ((stv0900_get_bits(intp, F0900_SELX1RATIO) == 1) ? 4 : 6);
313 m_div = ((clk_sel * mclk) / intp->quartz) - 1;
314 stv0900_write_bits(intp, F0900_M_DIV, m_div);
315 intp->mclk = stv0900_get_mclk_freq(intp,
316 intp->quartz);
317
318 /*Set the DiseqC frequency to 22KHz */
319 /*
320 Formula:
321 DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg)
322 DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg)
323 */
324 m_div = intp->mclk / 704000;
325 stv0900_write_reg(intp, R0900_P1_F22TX, m_div);
326 stv0900_write_reg(intp, R0900_P1_F22RX, m_div);
327
328 stv0900_write_reg(intp, R0900_P2_F22TX, m_div);
329 stv0900_write_reg(intp, R0900_P2_F22RX, m_div);
330
331 if ((intp->errs))
332 return STV0900_I2C_ERROR;
333
334 return STV0900_NO_ERROR;
335}
336
337static u32 stv0900_get_err_count(struct stv0900_internal *intp, int cntr,
338 enum fe_stv0900_demod_num demod)
339{
340 u32 lsb, msb, hsb, err_val;
341
342 switch (cntr) {
343 case 0:
344 default:
345 hsb = stv0900_get_bits(intp, ERR_CNT12);
346 msb = stv0900_get_bits(intp, ERR_CNT11);
347 lsb = stv0900_get_bits(intp, ERR_CNT10);
348 break;
349 case 1:
350 hsb = stv0900_get_bits(intp, ERR_CNT22);
351 msb = stv0900_get_bits(intp, ERR_CNT21);
352 lsb = stv0900_get_bits(intp, ERR_CNT20);
353 break;
354 }
355
356 err_val = (hsb << 16) + (msb << 8) + (lsb);
357
358 return err_val;
359}
360
361static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
362{
363 struct stv0900_state *state = fe->demodulator_priv;
364 struct stv0900_internal *intp = state->internal;
365 enum fe_stv0900_demod_num demod = state->demod;
366
367 stv0900_write_bits(intp, I2CT_ON, enable);
368
369 return 0;
370}
371
372static void stv0900_set_ts_parallel_serial(struct stv0900_internal *intp,
373 enum fe_stv0900_clock_type path1_ts,
374 enum fe_stv0900_clock_type path2_ts)
375{
376
377 dprintk("%s\n", __func__);
378
379 if (intp->chip_id >= 0x20) {
380 switch (path1_ts) {
381 case STV0900_PARALLEL_PUNCT_CLOCK:
382 case STV0900_DVBCI_CLOCK:
383 switch (path2_ts) {
384 case STV0900_SERIAL_PUNCT_CLOCK:
385 case STV0900_SERIAL_CONT_CLOCK:
386 default:
387 stv0900_write_reg(intp, R0900_TSGENERAL,
388 0x00);
389 break;
390 case STV0900_PARALLEL_PUNCT_CLOCK:
391 case STV0900_DVBCI_CLOCK:
392 stv0900_write_reg(intp, R0900_TSGENERAL,
393 0x06);
394 stv0900_write_bits(intp,
395 F0900_P1_TSFIFO_MANSPEED, 3);
396 stv0900_write_bits(intp,
397 F0900_P2_TSFIFO_MANSPEED, 0);
398 stv0900_write_reg(intp,
399 R0900_P1_TSSPEED, 0x14);
400 stv0900_write_reg(intp,
401 R0900_P2_TSSPEED, 0x28);
402 break;
403 }
404 break;
405 case STV0900_SERIAL_PUNCT_CLOCK:
406 case STV0900_SERIAL_CONT_CLOCK:
407 default:
408 switch (path2_ts) {
409 case STV0900_SERIAL_PUNCT_CLOCK:
410 case STV0900_SERIAL_CONT_CLOCK:
411 default:
412 stv0900_write_reg(intp,
413 R0900_TSGENERAL, 0x0C);
414 break;
415 case STV0900_PARALLEL_PUNCT_CLOCK:
416 case STV0900_DVBCI_CLOCK:
417 stv0900_write_reg(intp,
418 R0900_TSGENERAL, 0x0A);
419 dprintk("%s: 0x0a\n", __func__);
420 break;
421 }
422 break;
423 }
424 } else {
425 switch (path1_ts) {
426 case STV0900_PARALLEL_PUNCT_CLOCK:
427 case STV0900_DVBCI_CLOCK:
428 switch (path2_ts) {
429 case STV0900_SERIAL_PUNCT_CLOCK:
430 case STV0900_SERIAL_CONT_CLOCK:
431 default:
432 stv0900_write_reg(intp, R0900_TSGENERAL1X,
433 0x10);
434 break;
435 case STV0900_PARALLEL_PUNCT_CLOCK:
436 case STV0900_DVBCI_CLOCK:
437 stv0900_write_reg(intp, R0900_TSGENERAL1X,
438 0x16);
439 stv0900_write_bits(intp,
440 F0900_P1_TSFIFO_MANSPEED, 3);
441 stv0900_write_bits(intp,
442 F0900_P2_TSFIFO_MANSPEED, 0);
443 stv0900_write_reg(intp, R0900_P1_TSSPEED,
444 0x14);
445 stv0900_write_reg(intp, R0900_P2_TSSPEED,
446 0x28);
447 break;
448 }
449
450 break;
451 case STV0900_SERIAL_PUNCT_CLOCK:
452 case STV0900_SERIAL_CONT_CLOCK:
453 default:
454 switch (path2_ts) {
455 case STV0900_SERIAL_PUNCT_CLOCK:
456 case STV0900_SERIAL_CONT_CLOCK:
457 default:
458 stv0900_write_reg(intp, R0900_TSGENERAL1X,
459 0x14);
460 break;
461 case STV0900_PARALLEL_PUNCT_CLOCK:
462 case STV0900_DVBCI_CLOCK:
463 stv0900_write_reg(intp, R0900_TSGENERAL1X,
464 0x12);
465 dprintk("%s: 0x12\n", __func__);
466 break;
467 }
468
469 break;
470 }
471 }
472
473 switch (path1_ts) {
474 case STV0900_PARALLEL_PUNCT_CLOCK:
475 stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x00);
476 stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x00);
477 break;
478 case STV0900_DVBCI_CLOCK:
479 stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x00);
480 stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x01);
481 break;
482 case STV0900_SERIAL_PUNCT_CLOCK:
483 stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x01);
484 stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x00);
485 break;
486 case STV0900_SERIAL_CONT_CLOCK:
487 stv0900_write_bits(intp, F0900_P1_TSFIFO_SERIAL, 0x01);
488 stv0900_write_bits(intp, F0900_P1_TSFIFO_DVBCI, 0x01);
489 break;
490 default:
491 break;
492 }
493
494 switch (path2_ts) {
495 case STV0900_PARALLEL_PUNCT_CLOCK:
496 stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x00);
497 stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x00);
498 break;
499 case STV0900_DVBCI_CLOCK:
500 stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x00);
501 stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x01);
502 break;
503 case STV0900_SERIAL_PUNCT_CLOCK:
504 stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x01);
505 stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x00);
506 break;
507 case STV0900_SERIAL_CONT_CLOCK:
508 stv0900_write_bits(intp, F0900_P2_TSFIFO_SERIAL, 0x01);
509 stv0900_write_bits(intp, F0900_P2_TSFIFO_DVBCI, 0x01);
510 break;
511 default:
512 break;
513 }
514
515 stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1);
516 stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0);
517 stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1);
518 stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0);
519}
520
521void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
522 u32 bandwidth)
523{
524 struct dvb_frontend_ops *frontend_ops = NULL;
525 struct dvb_tuner_ops *tuner_ops = NULL;
526
527 if (&fe->ops)
528 frontend_ops = &fe->ops;
529
530 if (&frontend_ops->tuner_ops)
531 tuner_ops = &frontend_ops->tuner_ops;
532
533 if (tuner_ops->set_frequency) {
534 if ((tuner_ops->set_frequency(fe, frequency)) < 0)
535 dprintk("%s: Invalid parameter\n", __func__);
536 else
537 dprintk("%s: Frequency=%d\n", __func__, frequency);
538
539 }
540
541 if (tuner_ops->set_bandwidth) {
542 if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0)
543 dprintk("%s: Invalid parameter\n", __func__);
544 else
545 dprintk("%s: Bandwidth=%d\n", __func__, bandwidth);
546
547 }
548}
549
550void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
551{
552 struct dvb_frontend_ops *frontend_ops = NULL;
553 struct dvb_tuner_ops *tuner_ops = NULL;
554
555 if (&fe->ops)
556 frontend_ops = &fe->ops;
557
558 if (&frontend_ops->tuner_ops)
559 tuner_ops = &frontend_ops->tuner_ops;
560
561 if (tuner_ops->set_bandwidth) {
562 if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0)
563 dprintk("%s: Invalid parameter\n", __func__);
564 else
565 dprintk("%s: Bandwidth=%d\n", __func__, bandwidth);
566
567 }
568}
569
570u32 stv0900_get_freq_auto(struct stv0900_internal *intp, int demod)
571{
572 u32 freq, round;
573 /* Formulat :
574 Tuner_Frequency(MHz) = Regs / 64
575 Tuner_granularity(MHz) = Regs / 2048
576 real_Tuner_Frequency = Tuner_Frequency(MHz) - Tuner_granularity(MHz)
577 */
578 freq = (stv0900_get_bits(intp, TUN_RFFREQ2) << 10) +
579 (stv0900_get_bits(intp, TUN_RFFREQ1) << 2) +
580 stv0900_get_bits(intp, TUN_RFFREQ0);
581
582 freq = (freq * 1000) / 64;
583
584 round = (stv0900_get_bits(intp, TUN_RFRESTE1) >> 2) +
585 stv0900_get_bits(intp, TUN_RFRESTE0);
586
587 round = (round * 1000) / 2048;
588
589 return freq + round;
590}
591
592void stv0900_set_tuner_auto(struct stv0900_internal *intp, u32 Frequency,
593 u32 Bandwidth, int demod)
594{
595 u32 tunerFrequency;
596 /* Formulat:
597 Tuner_frequency_reg= Frequency(MHz)*64
598 */
599 tunerFrequency = (Frequency * 64) / 1000;
600
601 stv0900_write_bits(intp, TUN_RFFREQ2, (tunerFrequency >> 10));
602 stv0900_write_bits(intp, TUN_RFFREQ1, (tunerFrequency >> 2) & 0xff);
603 stv0900_write_bits(intp, TUN_RFFREQ0, (tunerFrequency & 0x03));
604 /* Low Pass Filter = BW /2 (MHz)*/
605 stv0900_write_bits(intp, TUN_BW, Bandwidth / 2000000);
606 /* Tuner Write trig */
607 stv0900_write_reg(intp, TNRLD, 1);
608}
609
610static s32 stv0900_get_rf_level(struct stv0900_internal *intp,
611 const struct stv0900_table *lookup,
612 enum fe_stv0900_demod_num demod)
613{
614 s32 agc_gain = 0,
615 imin,
616 imax,
617 i,
618 rf_lvl = 0;
619
620 dprintk("%s\n", __func__);
621
622 if ((lookup == NULL) || (lookup->size <= 0))
623 return 0;
624
625 agc_gain = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
626 stv0900_get_bits(intp, AGCIQ_VALUE0));
627
628 imin = 0;
629 imax = lookup->size - 1;
630 if (INRANGE(lookup->table[imin].regval, agc_gain,
631 lookup->table[imax].regval)) {
632 while ((imax - imin) > 1) {
633 i = (imax + imin) >> 1;
634
635 if (INRANGE(lookup->table[imin].regval,
636 agc_gain,
637 lookup->table[i].regval))
638 imax = i;
639 else
640 imin = i;
641 }
642
643 rf_lvl = (s32)agc_gain - lookup->table[imin].regval;
644 rf_lvl *= (lookup->table[imax].realval -
645 lookup->table[imin].realval);
646 rf_lvl /= (lookup->table[imax].regval -
647 lookup->table[imin].regval);
648 rf_lvl += lookup->table[imin].realval;
649 } else if (agc_gain > lookup->table[0].regval)
650 rf_lvl = 5;
651 else if (agc_gain < lookup->table[lookup->size-1].regval)
652 rf_lvl = -100;
653
654 dprintk("%s: RFLevel = %d\n", __func__, rf_lvl);
655
656 return rf_lvl;
657}
658
659static int stv0900_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
660{
661 struct stv0900_state *state = fe->demodulator_priv;
662 struct stv0900_internal *internal = state->internal;
663 s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf,
664 state->demod);
665
666 rflevel = (rflevel + 100) * (65535 / 70);
667 if (rflevel < 0)
668 rflevel = 0;
669
670 if (rflevel > 65535)
671 rflevel = 65535;
672
673 *strength = rflevel;
674
675 return 0;
676}
677
678static s32 stv0900_carr_get_quality(struct dvb_frontend *fe,
679 const struct stv0900_table *lookup)
680{
681 struct stv0900_state *state = fe->demodulator_priv;
682 struct stv0900_internal *intp = state->internal;
683 enum fe_stv0900_demod_num demod = state->demod;
684
685 s32 c_n = -100,
686 regval,
687 imin,
688 imax,
689 i,
690 noise_field1,
691 noise_field0;
692
693 dprintk("%s\n", __func__);
694
695 if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) {
696 noise_field1 = NOSPLHT_NORMED1;
697 noise_field0 = NOSPLHT_NORMED0;
698 } else {
699 noise_field1 = NOSDATAT_NORMED1;
700 noise_field0 = NOSDATAT_NORMED0;
701 }
702
703 if (stv0900_get_bits(intp, LOCK_DEFINITIF)) {
704 if ((lookup != NULL) && lookup->size) {
705 regval = 0;
706 msleep(5);
707 for (i = 0; i < 16; i++) {
708 regval += MAKEWORD(stv0900_get_bits(intp,
709 noise_field1),
710 stv0900_get_bits(intp,
711 noise_field0));
712 msleep(1);
713 }
714
715 regval /= 16;
716 imin = 0;
717 imax = lookup->size - 1;
718 if (INRANGE(lookup->table[imin].regval,
719 regval,
720 lookup->table[imax].regval)) {
721 while ((imax - imin) > 1) {
722 i = (imax + imin) >> 1;
723 if (INRANGE(lookup->table[imin].regval,
724 regval,
725 lookup->table[i].regval))
726 imax = i;
727 else
728 imin = i;
729 }
730
731 c_n = ((regval - lookup->table[imin].regval)
732 * (lookup->table[imax].realval
733 - lookup->table[imin].realval)
734 / (lookup->table[imax].regval
735 - lookup->table[imin].regval))
736 + lookup->table[imin].realval;
737 } else if (regval < lookup->table[imin].regval)
738 c_n = 1000;
739 }
740 }
741
742 return c_n;
743}
744
745static int stv0900_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
746{
747 struct stv0900_state *state = fe->demodulator_priv;
748 struct stv0900_internal *intp = state->internal;
749 enum fe_stv0900_demod_num demod = state->demod;
750 u8 err_val1, err_val0;
751 u32 header_err_val = 0;
752
753 *ucblocks = 0x0;
754 if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) {
755 /* DVB-S2 delineator errors count */
756
757 /* retreiving number for errnous headers */
758 err_val1 = stv0900_read_reg(intp, BBFCRCKO1);
759 err_val0 = stv0900_read_reg(intp, BBFCRCKO0);
760 header_err_val = (err_val1 << 8) | err_val0;
761
762 /* retreiving number for errnous packets */
763 err_val1 = stv0900_read_reg(intp, UPCRCKO1);
764 err_val0 = stv0900_read_reg(intp, UPCRCKO0);
765 *ucblocks = (err_val1 << 8) | err_val0;
766 *ucblocks += header_err_val;
767 }
768
769 return 0;
770}
771
772static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr)
773{
774 s32 snrlcl = stv0900_carr_get_quality(fe,
775 (const struct stv0900_table *)&stv0900_s2_cn);
776 snrlcl = (snrlcl + 30) * 384;
777 if (snrlcl < 0)
778 snrlcl = 0;
779
780 if (snrlcl > 65535)
781 snrlcl = 65535;
782
783 *snr = snrlcl;
784
785 return 0;
786}
787
788static u32 stv0900_get_ber(struct stv0900_internal *intp,
789 enum fe_stv0900_demod_num demod)
790{
791 u32 ber = 10000000, i;
792 s32 demod_state;
793
794 demod_state = stv0900_get_bits(intp, HEADER_MODE);
795
796 switch (demod_state) {
797 case STV0900_SEARCH:
798 case STV0900_PLH_DETECTED:
799 default:
800 ber = 10000000;
801 break;
802 case STV0900_DVBS_FOUND:
803 ber = 0;
804 for (i = 0; i < 5; i++) {
805 msleep(5);
806 ber += stv0900_get_err_count(intp, 0, demod);
807 }
808
809 ber /= 5;
810 if (stv0900_get_bits(intp, PRFVIT)) {
811 ber *= 9766;
812 ber = ber >> 13;
813 }
814
815 break;
816 case STV0900_DVBS2_FOUND:
817 ber = 0;
818 for (i = 0; i < 5; i++) {
819 msleep(5);
820 ber += stv0900_get_err_count(intp, 0, demod);
821 }
822
823 ber /= 5;
824 if (stv0900_get_bits(intp, PKTDELIN_LOCK)) {
825 ber *= 9766;
826 ber = ber >> 13;
827 }
828
829 break;
830 }
831
832 return ber;
833}
834
835static int stv0900_read_ber(struct dvb_frontend *fe, u32 *ber)
836{
837 struct stv0900_state *state = fe->demodulator_priv;
838 struct stv0900_internal *internal = state->internal;
839
840 *ber = stv0900_get_ber(internal, state->demod);
841
842 return 0;
843}
844
845int stv0900_get_demod_lock(struct stv0900_internal *intp,
846 enum fe_stv0900_demod_num demod, s32 time_out)
847{
848 s32 timer = 0,
849 lock = 0;
850
851 enum fe_stv0900_search_state dmd_state;
852
853 while ((timer < time_out) && (lock == 0)) {
854 dmd_state = stv0900_get_bits(intp, HEADER_MODE);
855 dprintk("Demod State = %d\n", dmd_state);
856 switch (dmd_state) {
857 case STV0900_SEARCH:
858 case STV0900_PLH_DETECTED:
859 default:
860 lock = 0;
861 break;
862 case STV0900_DVBS2_FOUND:
863 case STV0900_DVBS_FOUND:
864 lock = stv0900_get_bits(intp, LOCK_DEFINITIF);
865 break;
866 }
867
868 if (lock == 0)
869 msleep(10);
870
871 timer += 10;
872 }
873
874 if (lock)
875 dprintk("DEMOD LOCK OK\n");
876 else
877 dprintk("DEMOD LOCK FAIL\n");
878
879 return lock;
880}
881
882void stv0900_stop_all_s2_modcod(struct stv0900_internal *intp,
883 enum fe_stv0900_demod_num demod)
884{
885 s32 regflist,
886 i;
887
888 dprintk("%s\n", __func__);
889
890 regflist = MODCODLST0;
891
892 for (i = 0; i < 16; i++)
893 stv0900_write_reg(intp, regflist + i, 0xff);
894}
895
896void stv0900_activate_s2_modcod(struct stv0900_internal *intp,
897 enum fe_stv0900_demod_num demod)
898{
899 u32 matype,
900 mod_code,
901 fmod,
902 reg_index,
903 field_index;
904
905 dprintk("%s\n", __func__);
906
907 if (intp->chip_id <= 0x11) {
908 msleep(5);
909
910 mod_code = stv0900_read_reg(intp, PLHMODCOD);
911 matype = mod_code & 0x3;
912 mod_code = (mod_code & 0x7f) >> 2;
913
914 reg_index = MODCODLSTF - mod_code / 2;
915 field_index = mod_code % 2;
916
917 switch (matype) {
918 case 0:
919 default:
920 fmod = 14;
921 break;
922 case 1:
923 fmod = 13;
924 break;
925 case 2:
926 fmod = 11;
927 break;
928 case 3:
929 fmod = 7;
930 break;
931 }
932
933 if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910))
934 && (matype <= 1)) {
935 if (field_index == 0)
936 stv0900_write_reg(intp, reg_index,
937 0xf0 | fmod);
938 else
939 stv0900_write_reg(intp, reg_index,
940 (fmod << 4) | 0xf);
941 }
942
943 } else if (intp->chip_id >= 0x12) {
944 for (reg_index = 0; reg_index < 7; reg_index++)
945 stv0900_write_reg(intp, MODCODLST0 + reg_index, 0xff);
946
947 stv0900_write_reg(intp, MODCODLSTE, 0xff);
948 stv0900_write_reg(intp, MODCODLSTF, 0xcf);
949 for (reg_index = 0; reg_index < 8; reg_index++)
950 stv0900_write_reg(intp, MODCODLST7 + reg_index, 0xcc);
951
952
953 }
954}
955
956void stv0900_activate_s2_modcod_single(struct stv0900_internal *intp,
957 enum fe_stv0900_demod_num demod)
958{
959 u32 reg_index;
960
961 dprintk("%s\n", __func__);
962
963 stv0900_write_reg(intp, MODCODLST0, 0xff);
964 stv0900_write_reg(intp, MODCODLST1, 0xf0);
965 stv0900_write_reg(intp, MODCODLSTF, 0x0f);
966 for (reg_index = 0; reg_index < 13; reg_index++)
967 stv0900_write_reg(intp, MODCODLST2 + reg_index, 0);
968
969}
970
971static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe)
972{
973 return DVBFE_ALGO_CUSTOM;
974}
975
976static int stb0900_set_property(struct dvb_frontend *fe,
977 struct dtv_property *tvp)
978{
979 dprintk("%s(..)\n", __func__);
980
981 return 0;
982}
983
984static int stb0900_get_property(struct dvb_frontend *fe,
985 struct dtv_property *tvp)
986{
987 dprintk("%s(..)\n", __func__);
988
989 return 0;
990}
991
992void stv0900_start_search(struct stv0900_internal *intp,
993 enum fe_stv0900_demod_num demod)
994{
995 u32 freq;
996 s16 freq_s16 ;
997
998 stv0900_write_bits(intp, DEMOD_MODE, 0x1f);
999 if (intp->chip_id == 0x10)
1000 stv0900_write_reg(intp, CORRELEXP, 0xaa);
1001
1002 if (intp->chip_id < 0x20)
1003 stv0900_write_reg(intp, CARHDR, 0x55);
1004
1005 if (intp->chip_id <= 0x20) {
1006 if (intp->symbol_rate[0] <= 5000000) {
1007 stv0900_write_reg(intp, CARCFG, 0x44);
1008 stv0900_write_reg(intp, CFRUP1, 0x0f);
1009 stv0900_write_reg(intp, CFRUP0, 0xff);
1010 stv0900_write_reg(intp, CFRLOW1, 0xf0);
1011 stv0900_write_reg(intp, CFRLOW0, 0x00);
1012 stv0900_write_reg(intp, RTCS2, 0x68);
1013 } else {
1014 stv0900_write_reg(intp, CARCFG, 0xc4);
1015 stv0900_write_reg(intp, RTCS2, 0x44);
1016 }
1017
1018 } else { /*cut 3.0 above*/
1019 if (intp->symbol_rate[demod] <= 5000000)
1020 stv0900_write_reg(intp, RTCS2, 0x68);
1021 else
1022 stv0900_write_reg(intp, RTCS2, 0x44);
1023
1024 stv0900_write_reg(intp, CARCFG, 0x46);
1025 if (intp->srch_algo[demod] == STV0900_WARM_START) {
1026 freq = 1000 << 16;
1027 freq /= (intp->mclk / 1000);
1028 freq_s16 = (s16)freq;
1029 } else {
1030 freq = (intp->srch_range[demod] / 2000);
1031 if (intp->symbol_rate[demod] <= 5000000)
1032 freq += 80;
1033 else
1034 freq += 600;
1035
1036 freq = freq << 16;
1037 freq /= (intp->mclk / 1000);
1038 freq_s16 = (s16)freq;
1039 }
1040
1041 stv0900_write_bits(intp, CFR_UP1, MSB(freq_s16));
1042 stv0900_write_bits(intp, CFR_UP0, LSB(freq_s16));
1043 freq_s16 *= (-1);
1044 stv0900_write_bits(intp, CFR_LOW1, MSB(freq_s16));
1045 stv0900_write_bits(intp, CFR_LOW0, LSB(freq_s16));
1046 }
1047
1048 stv0900_write_reg(intp, CFRINIT1, 0);
1049 stv0900_write_reg(intp, CFRINIT0, 0);
1050
1051 if (intp->chip_id >= 0x20) {
1052 stv0900_write_reg(intp, EQUALCFG, 0x41);
1053 stv0900_write_reg(intp, FFECFG, 0x41);
1054
1055 if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) ||
1056 (intp->srch_standard[demod] == STV0900_SEARCH_DSS) ||
1057 (intp->srch_standard[demod] == STV0900_AUTO_SEARCH)) {
1058 stv0900_write_reg(intp, VITSCALE,
1059 0x82);
1060 stv0900_write_reg(intp, VAVSRVIT, 0x0);
1061 }
1062 }
1063
1064 stv0900_write_reg(intp, SFRSTEP, 0x00);
1065 stv0900_write_reg(intp, TMGTHRISE, 0xe0);
1066 stv0900_write_reg(intp, TMGTHFALL, 0xc0);
1067 stv0900_write_bits(intp, SCAN_ENABLE, 0);
1068 stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
1069 stv0900_write_bits(intp, S1S2_SEQUENTIAL, 0);
1070 stv0900_write_reg(intp, RTC, 0x88);
1071 if (intp->chip_id >= 0x20) {
1072 if (intp->symbol_rate[demod] < 2000000) {
1073 if (intp->chip_id <= 0x20)
1074 stv0900_write_reg(intp, CARFREQ, 0x39);
1075 else /*cut 3.0*/
1076 stv0900_write_reg(intp, CARFREQ, 0x89);
1077
1078 stv0900_write_reg(intp, CARHDR, 0x40);
1079 } else if (intp->symbol_rate[demod] < 10000000) {
1080 stv0900_write_reg(intp, CARFREQ, 0x4c);
1081 stv0900_write_reg(intp, CARHDR, 0x20);
1082 } else {
1083 stv0900_write_reg(intp, CARFREQ, 0x4b);
1084 stv0900_write_reg(intp, CARHDR, 0x20);
1085 }
1086
1087 } else {
1088 if (intp->symbol_rate[demod] < 10000000)
1089 stv0900_write_reg(intp, CARFREQ, 0xef);
1090 else
1091 stv0900_write_reg(intp, CARFREQ, 0xed);
1092 }
1093
1094 switch (intp->srch_algo[demod]) {
1095 case STV0900_WARM_START:
1096 stv0900_write_reg(intp, DMDISTATE, 0x1f);
1097 stv0900_write_reg(intp, DMDISTATE, 0x18);
1098 break;
1099 case STV0900_COLD_START:
1100 stv0900_write_reg(intp, DMDISTATE, 0x1f);
1101 stv0900_write_reg(intp, DMDISTATE, 0x15);
1102 break;
1103 default:
1104 break;
1105 }
1106}
1107
1108u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode,
1109 s32 pilot, u8 chip_id)
1110{
1111 u8 aclc_value = 0x29;
1112 s32 i;
1113 const struct stv0900_car_loop_optim *cls2, *cllqs2, *cllas2;
1114
1115 dprintk("%s\n", __func__);
1116
1117 if (chip_id <= 0x12) {
1118 cls2 = FE_STV0900_S2CarLoop;
1119 cllqs2 = FE_STV0900_S2LowQPCarLoopCut30;
1120 cllas2 = FE_STV0900_S2APSKCarLoopCut30;
1121 } else if (chip_id == 0x20) {
1122 cls2 = FE_STV0900_S2CarLoopCut20;
1123 cllqs2 = FE_STV0900_S2LowQPCarLoopCut20;
1124 cllas2 = FE_STV0900_S2APSKCarLoopCut20;
1125 } else {
1126 cls2 = FE_STV0900_S2CarLoopCut30;
1127 cllqs2 = FE_STV0900_S2LowQPCarLoopCut30;
1128 cllas2 = FE_STV0900_S2APSKCarLoopCut30;
1129 }
1130
1131 if (modcode < STV0900_QPSK_12) {
1132 i = 0;
1133 while ((i < 3) && (modcode != cllqs2[i].modcode))
1134 i++;
1135
1136 if (i >= 3)
1137 i = 2;
1138 } else {
1139 i = 0;
1140 while ((i < 14) && (modcode != cls2[i].modcode))
1141 i++;
1142
1143 if (i >= 14) {
1144 i = 0;
1145 while ((i < 11) && (modcode != cllas2[i].modcode))
1146 i++;
1147
1148 if (i >= 11)
1149 i = 10;
1150 }
1151 }
1152
1153 if (modcode <= STV0900_QPSK_25) {
1154 if (pilot) {
1155 if (srate <= 3000000)
1156 aclc_value = cllqs2[i].car_loop_pilots_on_2;
1157 else if (srate <= 7000000)
1158 aclc_value = cllqs2[i].car_loop_pilots_on_5;
1159 else if (srate <= 15000000)
1160 aclc_value = cllqs2[i].car_loop_pilots_on_10;
1161 else if (srate <= 25000000)
1162 aclc_value = cllqs2[i].car_loop_pilots_on_20;
1163 else
1164 aclc_value = cllqs2[i].car_loop_pilots_on_30;
1165 } else {
1166 if (srate <= 3000000)
1167 aclc_value = cllqs2[i].car_loop_pilots_off_2;
1168 else if (srate <= 7000000)
1169 aclc_value = cllqs2[i].car_loop_pilots_off_5;
1170 else if (srate <= 15000000)
1171 aclc_value = cllqs2[i].car_loop_pilots_off_10;
1172 else if (srate <= 25000000)
1173 aclc_value = cllqs2[i].car_loop_pilots_off_20;
1174 else
1175 aclc_value = cllqs2[i].car_loop_pilots_off_30;
1176 }
1177
1178 } else if (modcode <= STV0900_8PSK_910) {
1179 if (pilot) {
1180 if (srate <= 3000000)
1181 aclc_value = cls2[i].car_loop_pilots_on_2;
1182 else if (srate <= 7000000)
1183 aclc_value = cls2[i].car_loop_pilots_on_5;
1184 else if (srate <= 15000000)
1185 aclc_value = cls2[i].car_loop_pilots_on_10;
1186 else if (srate <= 25000000)
1187 aclc_value = cls2[i].car_loop_pilots_on_20;
1188 else
1189 aclc_value = cls2[i].car_loop_pilots_on_30;
1190 } else {
1191 if (srate <= 3000000)
1192 aclc_value = cls2[i].car_loop_pilots_off_2;
1193 else if (srate <= 7000000)
1194 aclc_value = cls2[i].car_loop_pilots_off_5;
1195 else if (srate <= 15000000)
1196 aclc_value = cls2[i].car_loop_pilots_off_10;
1197 else if (srate <= 25000000)
1198 aclc_value = cls2[i].car_loop_pilots_off_20;
1199 else
1200 aclc_value = cls2[i].car_loop_pilots_off_30;
1201 }
1202
1203 } else {
1204 if (srate <= 3000000)
1205 aclc_value = cllas2[i].car_loop_pilots_on_2;
1206 else if (srate <= 7000000)
1207 aclc_value = cllas2[i].car_loop_pilots_on_5;
1208 else if (srate <= 15000000)
1209 aclc_value = cllas2[i].car_loop_pilots_on_10;
1210 else if (srate <= 25000000)
1211 aclc_value = cllas2[i].car_loop_pilots_on_20;
1212 else
1213 aclc_value = cllas2[i].car_loop_pilots_on_30;
1214 }
1215
1216 return aclc_value;
1217}
1218
1219u8 stv0900_get_optim_short_carr_loop(s32 srate,
1220 enum fe_stv0900_modulation modulation,
1221 u8 chip_id)
1222{
1223 const struct stv0900_short_frames_car_loop_optim *s2scl;
1224 const struct stv0900_short_frames_car_loop_optim_vs_mod *s2sclc30;
1225 s32 mod_index = 0;
1226 u8 aclc_value = 0x0b;
1227
1228 dprintk("%s\n", __func__);
1229
1230 s2scl = FE_STV0900_S2ShortCarLoop;
1231 s2sclc30 = FE_STV0900_S2ShortCarLoopCut30;
1232
1233 switch (modulation) {
1234 case STV0900_QPSK:
1235 default:
1236 mod_index = 0;
1237 break;
1238 case STV0900_8PSK:
1239 mod_index = 1;
1240 break;
1241 case STV0900_16APSK:
1242 mod_index = 2;
1243 break;
1244 case STV0900_32APSK:
1245 mod_index = 3;
1246 break;
1247 }
1248
1249 if (chip_id >= 0x30) {
1250 if (srate <= 3000000)
1251 aclc_value = s2sclc30[mod_index].car_loop_2;
1252 else if (srate <= 7000000)
1253 aclc_value = s2sclc30[mod_index].car_loop_5;
1254 else if (srate <= 15000000)
1255 aclc_value = s2sclc30[mod_index].car_loop_10;
1256 else if (srate <= 25000000)
1257 aclc_value = s2sclc30[mod_index].car_loop_20;
1258 else
1259 aclc_value = s2sclc30[mod_index].car_loop_30;
1260
1261 } else if (chip_id >= 0x20) {
1262 if (srate <= 3000000)
1263 aclc_value = s2scl[mod_index].car_loop_cut20_2;
1264 else if (srate <= 7000000)
1265 aclc_value = s2scl[mod_index].car_loop_cut20_5;
1266 else if (srate <= 15000000)
1267 aclc_value = s2scl[mod_index].car_loop_cut20_10;
1268 else if (srate <= 25000000)
1269 aclc_value = s2scl[mod_index].car_loop_cut20_20;
1270 else
1271 aclc_value = s2scl[mod_index].car_loop_cut20_30;
1272
1273 } else {
1274 if (srate <= 3000000)
1275 aclc_value = s2scl[mod_index].car_loop_cut12_2;
1276 else if (srate <= 7000000)
1277 aclc_value = s2scl[mod_index].car_loop_cut12_5;
1278 else if (srate <= 15000000)
1279 aclc_value = s2scl[mod_index].car_loop_cut12_10;
1280 else if (srate <= 25000000)
1281 aclc_value = s2scl[mod_index].car_loop_cut12_20;
1282 else
1283 aclc_value = s2scl[mod_index].car_loop_cut12_30;
1284
1285 }
1286
1287 return aclc_value;
1288}
1289
1290static
1291enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *intp,
1292 enum fe_stv0900_demod_mode LDPC_Mode,
1293 enum fe_stv0900_demod_num demod)
1294{
1295 enum fe_stv0900_error error = STV0900_NO_ERROR;
1296 s32 reg_ind;
1297
1298 dprintk("%s\n", __func__);
1299
1300 switch (LDPC_Mode) {
1301 case STV0900_DUAL:
1302 default:
1303 if ((intp->demod_mode != STV0900_DUAL)
1304 || (stv0900_get_bits(intp, F0900_DDEMOD) != 1)) {
1305 stv0900_write_reg(intp, R0900_GENCFG, 0x1d);
1306
1307 intp->demod_mode = STV0900_DUAL;
1308
1309 stv0900_write_bits(intp, F0900_FRESFEC, 1);
1310 stv0900_write_bits(intp, F0900_FRESFEC, 0);
1311
1312 for (reg_ind = 0; reg_ind < 7; reg_ind++)
1313 stv0900_write_reg(intp,
1314 R0900_P1_MODCODLST0 + reg_ind,
1315 0xff);
1316 for (reg_ind = 0; reg_ind < 8; reg_ind++)
1317 stv0900_write_reg(intp,
1318 R0900_P1_MODCODLST7 + reg_ind,
1319 0xcc);
1320
1321 stv0900_write_reg(intp, R0900_P1_MODCODLSTE, 0xff);
1322 stv0900_write_reg(intp, R0900_P1_MODCODLSTF, 0xcf);
1323
1324 for (reg_ind = 0; reg_ind < 7; reg_ind++)
1325 stv0900_write_reg(intp,
1326 R0900_P2_MODCODLST0 + reg_ind,
1327 0xff);
1328 for (reg_ind = 0; reg_ind < 8; reg_ind++)
1329 stv0900_write_reg(intp,
1330 R0900_P2_MODCODLST7 + reg_ind,
1331 0xcc);
1332
1333 stv0900_write_reg(intp, R0900_P2_MODCODLSTE, 0xff);
1334 stv0900_write_reg(intp, R0900_P2_MODCODLSTF, 0xcf);
1335 }
1336
1337 break;
1338 case STV0900_SINGLE:
1339 if (demod == STV0900_DEMOD_2) {
1340 stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_1);
1341 stv0900_activate_s2_modcod_single(intp,
1342 STV0900_DEMOD_2);
1343 stv0900_write_reg(intp, R0900_GENCFG, 0x06);
1344 } else {
1345 stv0900_stop_all_s2_modcod(intp, STV0900_DEMOD_2);
1346 stv0900_activate_s2_modcod_single(intp,
1347 STV0900_DEMOD_1);
1348 stv0900_write_reg(intp, R0900_GENCFG, 0x04);
1349 }
1350
1351 intp->demod_mode = STV0900_SINGLE;
1352
1353 stv0900_write_bits(intp, F0900_FRESFEC, 1);
1354 stv0900_write_bits(intp, F0900_FRESFEC, 0);
1355 stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 1);
1356 stv0900_write_bits(intp, F0900_P1_ALGOSWRST, 0);
1357 stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 1);
1358 stv0900_write_bits(intp, F0900_P2_ALGOSWRST, 0);
1359 break;
1360 }
1361
1362 return error;
1363}
1364
1365static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
1366 struct stv0900_init_params *p_init)
1367{
1368 struct stv0900_state *state = fe->demodulator_priv;
1369 enum fe_stv0900_error error = STV0900_NO_ERROR;
1370 enum fe_stv0900_error demodError = STV0900_NO_ERROR;
1371 struct stv0900_internal *intp = NULL;
1372 int selosci, i;
1373
1374 struct stv0900_inode *temp_int = find_inode(state->i2c_adap,
1375 state->config->demod_address);
1376
1377 dprintk("%s\n", __func__);
1378
1379 if ((temp_int != NULL) && (p_init->demod_mode == STV0900_DUAL)) {
1380 state->internal = temp_int->internal;
1381 (state->internal->dmds_used)++;
1382 dprintk("%s: Find Internal Structure!\n", __func__);
1383 return STV0900_NO_ERROR;
1384 } else {
1385 state->internal = kmalloc(sizeof(struct stv0900_internal),
1386 GFP_KERNEL);
1387 if (state->internal == NULL)
1388 return STV0900_INVALID_HANDLE;
1389 temp_int = append_internal(state->internal);
1390 if (temp_int == NULL) {
1391 kfree(state->internal);
1392 state->internal = NULL;
1393 return STV0900_INVALID_HANDLE;
1394 }
1395 state->internal->dmds_used = 1;
1396 state->internal->i2c_adap = state->i2c_adap;
1397 state->internal->i2c_addr = state->config->demod_address;
1398 state->internal->clkmode = state->config->clkmode;
1399 state->internal->errs = STV0900_NO_ERROR;
1400 dprintk("%s: Create New Internal Structure!\n", __func__);
1401 }
1402
1403 if (state->internal == NULL) {
1404 error = STV0900_INVALID_HANDLE;
1405 return error;
1406 }
1407
1408 demodError = stv0900_initialize(state->internal);
1409 if (demodError == STV0900_NO_ERROR) {
1410 error = STV0900_NO_ERROR;
1411 } else {
1412 if (demodError == STV0900_INVALID_HANDLE)
1413 error = STV0900_INVALID_HANDLE;
1414 else
1415 error = STV0900_I2C_ERROR;
1416
1417 return error;
1418 }
1419
1420 intp = state->internal;
1421
1422 intp->demod_mode = p_init->demod_mode;
1423 stv0900_st_dvbs2_single(intp, intp->demod_mode, STV0900_DEMOD_1);
1424 intp->chip_id = stv0900_read_reg(intp, R0900_MID);
1425 intp->rolloff = p_init->rolloff;
1426 intp->quartz = p_init->dmd_ref_clk;
1427
1428 stv0900_write_bits(intp, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
1429 stv0900_write_bits(intp, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
1430
1431 intp->ts_config = p_init->ts_config;
1432 if (intp->ts_config == NULL)
1433 stv0900_set_ts_parallel_serial(intp,
1434 p_init->path1_ts_clock,
1435 p_init->path2_ts_clock);
1436 else {
1437 for (i = 0; intp->ts_config[i].addr != 0xffff; i++)
1438 stv0900_write_reg(intp,
1439 intp->ts_config[i].addr,
1440 intp->ts_config[i].val);
1441
1442 stv0900_write_bits(intp, F0900_P2_RST_HWARE, 1);
1443 stv0900_write_bits(intp, F0900_P2_RST_HWARE, 0);
1444 stv0900_write_bits(intp, F0900_P1_RST_HWARE, 1);
1445 stv0900_write_bits(intp, F0900_P1_RST_HWARE, 0);
1446 }
1447
1448 intp->tuner_type[0] = p_init->tuner1_type;
1449 intp->tuner_type[1] = p_init->tuner2_type;
1450 /* tuner init */
1451 switch (p_init->tuner1_type) {
1452 case 3: /*FE_AUTO_STB6100:*/
1453 stv0900_write_reg(intp, R0900_P1_TNRCFG, 0x3c);
1454 stv0900_write_reg(intp, R0900_P1_TNRCFG2, 0x86);
1455 stv0900_write_reg(intp, R0900_P1_TNRCFG3, 0x18);
1456 stv0900_write_reg(intp, R0900_P1_TNRXTAL, 27); /* 27MHz */
1457 stv0900_write_reg(intp, R0900_P1_TNRSTEPS, 0x05);
1458 stv0900_write_reg(intp, R0900_P1_TNRGAIN, 0x17);
1459 stv0900_write_reg(intp, R0900_P1_TNRADJ, 0x1f);
1460 stv0900_write_reg(intp, R0900_P1_TNRCTL2, 0x0);
1461 stv0900_write_bits(intp, F0900_P1_TUN_TYPE, 3);
1462 break;
1463 /* case FE_SW_TUNER: */
1464 default:
1465 stv0900_write_bits(intp, F0900_P1_TUN_TYPE, 6);
1466 break;
1467 }
1468
1469 stv0900_write_bits(intp, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
1470 switch (p_init->tuner1_adc) {
1471 case 1:
1472 stv0900_write_reg(intp, R0900_TSTTNR1, 0x26);
1473 break;
1474 default:
1475 break;
1476 }
1477
1478 stv0900_write_reg(intp, R0900_P1_TNRLD, 1); /* hw tuner */
1479
1480 /* tuner init */
1481 switch (p_init->tuner2_type) {
1482 case 3: /*FE_AUTO_STB6100:*/
1483 stv0900_write_reg(intp, R0900_P2_TNRCFG, 0x3c);
1484 stv0900_write_reg(intp, R0900_P2_TNRCFG2, 0x86);
1485 stv0900_write_reg(intp, R0900_P2_TNRCFG3, 0x18);
1486 stv0900_write_reg(intp, R0900_P2_TNRXTAL, 27); /* 27MHz */
1487 stv0900_write_reg(intp, R0900_P2_TNRSTEPS, 0x05);
1488 stv0900_write_reg(intp, R0900_P2_TNRGAIN, 0x17);
1489 stv0900_write_reg(intp, R0900_P2_TNRADJ, 0x1f);
1490 stv0900_write_reg(intp, R0900_P2_TNRCTL2, 0x0);
1491 stv0900_write_bits(intp, F0900_P2_TUN_TYPE, 3);
1492 break;
1493 /* case FE_SW_TUNER: */
1494 default:
1495 stv0900_write_bits(intp, F0900_P2_TUN_TYPE, 6);
1496 break;
1497 }
1498
1499 stv0900_write_bits(intp, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress);
1500 switch (p_init->tuner2_adc) {
1501 case 1:
1502 stv0900_write_reg(intp, R0900_TSTTNR3, 0x26);
1503 break;
1504 default:
1505 break;
1506 }
1507
1508 stv0900_write_reg(intp, R0900_P2_TNRLD, 1); /* hw tuner */
1509
1510 stv0900_write_bits(intp, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inv);
1511 stv0900_write_bits(intp, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inv);
1512 stv0900_set_mclk(intp, 135000000);
1513 msleep(3);
1514
1515 switch (intp->clkmode) {
1516 case 0:
1517 case 2:
1518 stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | intp->clkmode);
1519 break;
1520 default:
1521 selosci = 0x02 & stv0900_read_reg(intp, R0900_SYNTCTRL);
1522 stv0900_write_reg(intp, R0900_SYNTCTRL, 0x20 | selosci);
1523 break;
1524 }
1525 msleep(3);
1526
1527 intp->mclk = stv0900_get_mclk_freq(intp, intp->quartz);
1528 if (intp->errs)
1529 error = STV0900_I2C_ERROR;
1530
1531 return error;
1532}
1533
1534static int stv0900_status(struct stv0900_internal *intp,
1535 enum fe_stv0900_demod_num demod)
1536{
1537 enum fe_stv0900_search_state demod_state;
1538 int locked = FALSE;
1539 u8 tsbitrate0_val, tsbitrate1_val;
1540 s32 bitrate;
1541
1542 demod_state = stv0900_get_bits(intp, HEADER_MODE);
1543 switch (demod_state) {
1544 case STV0900_SEARCH:
1545 case STV0900_PLH_DETECTED:
1546 default:
1547 locked = FALSE;
1548 break;
1549 case STV0900_DVBS2_FOUND:
1550 locked = stv0900_get_bits(intp, LOCK_DEFINITIF) &&
1551 stv0900_get_bits(intp, PKTDELIN_LOCK) &&
1552 stv0900_get_bits(intp, TSFIFO_LINEOK);
1553 break;
1554 case STV0900_DVBS_FOUND:
1555 locked = stv0900_get_bits(intp, LOCK_DEFINITIF) &&
1556 stv0900_get_bits(intp, LOCKEDVIT) &&
1557 stv0900_get_bits(intp, TSFIFO_LINEOK);
1558 break;
1559 }
1560
1561 dprintk("%s: locked = %d\n", __func__, locked);
1562
1563 if (stvdebug) {
1564 /* Print TS bitrate */
1565 tsbitrate0_val = stv0900_read_reg(intp, TSBITRATE0);
1566 tsbitrate1_val = stv0900_read_reg(intp, TSBITRATE1);
1567 /* Formula Bit rate = Mclk * px_tsfifo_bitrate / 16384 */
1568 bitrate = (stv0900_get_mclk_freq(intp, intp->quartz)/1000000)
1569 * (tsbitrate1_val << 8 | tsbitrate0_val);
1570 bitrate /= 16384;
1571 dprintk("TS bitrate = %d Mbit/sec \n", bitrate);
1572 };
1573
1574 return locked;
1575}
1576
1577static enum dvbfe_search stv0900_search(struct dvb_frontend *fe,
1578 struct dvb_frontend_parameters *params)
1579{
1580 struct stv0900_state *state = fe->demodulator_priv;
1581 struct stv0900_internal *intp = state->internal;
1582 enum fe_stv0900_demod_num demod = state->demod;
1583 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1584
1585 struct stv0900_search_params p_search;
1586 struct stv0900_signal_info p_result = intp->result[demod];
1587
1588 enum fe_stv0900_error error = STV0900_NO_ERROR;
1589
1590 dprintk("%s: ", __func__);
1591
1592 if (!(INRANGE(100000, c->symbol_rate, 70000000)))
1593 return DVBFE_ALGO_SEARCH_FAILED;
1594
1595 if (state->config->set_ts_params)
1596 state->config->set_ts_params(fe, 0);
1597
1598 p_result.locked = FALSE;
1599 p_search.path = demod;
1600 p_search.frequency = c->frequency;
1601 p_search.symbol_rate = c->symbol_rate;
1602 p_search.search_range = 10000000;
1603 p_search.fec = STV0900_FEC_UNKNOWN;
1604 p_search.standard = STV0900_AUTO_SEARCH;
1605 p_search.iq_inversion = STV0900_IQ_AUTO;
1606 p_search.search_algo = STV0900_BLIND_SEARCH;
1607 /* Speeds up DVB-S searching */
1608 if (c->delivery_system == SYS_DVBS)
1609 p_search.standard = STV0900_SEARCH_DVBS1;
1610
1611 intp->srch_standard[demod] = p_search.standard;
1612 intp->symbol_rate[demod] = p_search.symbol_rate;
1613 intp->srch_range[demod] = p_search.search_range;
1614 intp->freq[demod] = p_search.frequency;
1615 intp->srch_algo[demod] = p_search.search_algo;
1616 intp->srch_iq_inv[demod] = p_search.iq_inversion;
1617 intp->fec[demod] = p_search.fec;
1618 if ((stv0900_algo(fe) == STV0900_RANGEOK) &&
1619 (intp->errs == STV0900_NO_ERROR)) {
1620 p_result.locked = intp->result[demod].locked;
1621 p_result.standard = intp->result[demod].standard;
1622 p_result.frequency = intp->result[demod].frequency;
1623 p_result.symbol_rate = intp->result[demod].symbol_rate;
1624 p_result.fec = intp->result[demod].fec;
1625 p_result.modcode = intp->result[demod].modcode;
1626 p_result.pilot = intp->result[demod].pilot;
1627 p_result.frame_len = intp->result[demod].frame_len;
1628 p_result.spectrum = intp->result[demod].spectrum;
1629 p_result.rolloff = intp->result[demod].rolloff;
1630 p_result.modulation = intp->result[demod].modulation;
1631 } else {
1632 p_result.locked = FALSE;
1633 switch (intp->err[demod]) {
1634 case STV0900_I2C_ERROR:
1635 error = STV0900_I2C_ERROR;
1636 break;
1637 case STV0900_NO_ERROR:
1638 default:
1639 error = STV0900_SEARCH_FAILED;
1640 break;
1641 }
1642 }
1643
1644 if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) {
1645 dprintk("Search Success\n");
1646 return DVBFE_ALGO_SEARCH_SUCCESS;
1647 } else {
1648 dprintk("Search Fail\n");
1649 return DVBFE_ALGO_SEARCH_FAILED;
1650 }
1651
1652}
1653
1654static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status)
1655{
1656 struct stv0900_state *state = fe->demodulator_priv;
1657
1658 dprintk("%s: ", __func__);
1659
1660 if ((stv0900_status(state->internal, state->demod)) == TRUE) {
1661 dprintk("DEMOD LOCK OK\n");
1662 *status = FE_HAS_CARRIER
1663 | FE_HAS_VITERBI
1664 | FE_HAS_SYNC
1665 | FE_HAS_LOCK;
1666 if (state->config->set_lock_led)
1667 state->config->set_lock_led(fe, 1);
1668 } else {
1669 *status = 0;
1670 if (state->config->set_lock_led)
1671 state->config->set_lock_led(fe, 0);
1672 dprintk("DEMOD LOCK FAIL\n");
1673 }
1674
1675 return 0;
1676}
1677
1678static int stv0900_track(struct dvb_frontend *fe,
1679 struct dvb_frontend_parameters *p)
1680{
1681 return 0;
1682}
1683
1684static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts)
1685{
1686
1687 struct stv0900_state *state = fe->demodulator_priv;
1688 struct stv0900_internal *intp = state->internal;
1689 enum fe_stv0900_demod_num demod = state->demod;
1690
1691 if (stop_ts == TRUE)
1692 stv0900_write_bits(intp, RST_HWARE, 1);
1693 else
1694 stv0900_write_bits(intp, RST_HWARE, 0);
1695
1696 return 0;
1697}
1698
1699static int stv0900_diseqc_init(struct dvb_frontend *fe)
1700{
1701 struct stv0900_state *state = fe->demodulator_priv;
1702 struct stv0900_internal *intp = state->internal;
1703 enum fe_stv0900_demod_num demod = state->demod;
1704
1705 stv0900_write_bits(intp, DISTX_MODE, state->config->diseqc_mode);
1706 stv0900_write_bits(intp, DISEQC_RESET, 1);
1707 stv0900_write_bits(intp, DISEQC_RESET, 0);
1708
1709 return 0;
1710}
1711
1712static int stv0900_init(struct dvb_frontend *fe)
1713{
1714 dprintk("%s\n", __func__);
1715
1716 stv0900_stop_ts(fe, 1);
1717 stv0900_diseqc_init(fe);
1718
1719 return 0;
1720}
1721
1722static int stv0900_diseqc_send(struct stv0900_internal *intp , u8 *data,
1723 u32 NbData, enum fe_stv0900_demod_num demod)
1724{
1725 s32 i = 0;
1726
1727 stv0900_write_bits(intp, DIS_PRECHARGE, 1);
1728 while (i < NbData) {
1729 while (stv0900_get_bits(intp, FIFO_FULL))
1730 ;/* checkpatch complains */
1731 stv0900_write_reg(intp, DISTXDATA, data[i]);
1732 i++;
1733 }
1734
1735 stv0900_write_bits(intp, DIS_PRECHARGE, 0);
1736 i = 0;
1737 while ((stv0900_get_bits(intp, TX_IDLE) != 1) && (i < 10)) {
1738 msleep(10);
1739 i++;
1740 }
1741
1742 return 0;
1743}
1744
1745static int stv0900_send_master_cmd(struct dvb_frontend *fe,
1746 struct dvb_diseqc_master_cmd *cmd)
1747{
1748 struct stv0900_state *state = fe->demodulator_priv;
1749
1750 return stv0900_diseqc_send(state->internal,
1751 cmd->msg,
1752 cmd->msg_len,
1753 state->demod);
1754}
1755
1756static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
1757{
1758 struct stv0900_state *state = fe->demodulator_priv;
1759 struct stv0900_internal *intp = state->internal;
1760 enum fe_stv0900_demod_num demod = state->demod;
1761 u8 data;
1762
1763
1764 switch (burst) {
1765 case SEC_MINI_A:
1766 stv0900_write_bits(intp, DISTX_MODE, 3);/* Unmodulated */
1767 data = 0x00;
1768 stv0900_diseqc_send(intp, &data, 1, state->demod);
1769 break;
1770 case SEC_MINI_B:
1771 stv0900_write_bits(intp, DISTX_MODE, 2);/* Modulated */
1772 data = 0xff;
1773 stv0900_diseqc_send(intp, &data, 1, state->demod);
1774 break;
1775 }
1776
1777 return 0;
1778}
1779
1780static int stv0900_recv_slave_reply(struct dvb_frontend *fe,
1781 struct dvb_diseqc_slave_reply *reply)
1782{
1783 struct stv0900_state *state = fe->demodulator_priv;
1784 struct stv0900_internal *intp = state->internal;
1785 enum fe_stv0900_demod_num demod = state->demod;
1786 s32 i = 0;
1787
1788 reply->msg_len = 0;
1789
1790 while ((stv0900_get_bits(intp, RX_END) != 1) && (i < 10)) {
1791 msleep(10);
1792 i++;
1793 }
1794
1795 if (stv0900_get_bits(intp, RX_END)) {
1796 reply->msg_len = stv0900_get_bits(intp, FIFO_BYTENBR);
1797
1798 for (i = 0; i < reply->msg_len; i++)
1799 reply->msg[i] = stv0900_read_reg(intp, DISRXDATA);
1800 }
1801
1802 return 0;
1803}
1804
1805static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t toneoff)
1806{
1807 struct stv0900_state *state = fe->demodulator_priv;
1808 struct stv0900_internal *intp = state->internal;
1809 enum fe_stv0900_demod_num demod = state->demod;
1810
1811 dprintk("%s: %s\n", __func__, ((toneoff == 0) ? "On" : "Off"));
1812
1813 switch (toneoff) {
1814 case SEC_TONE_ON:
1815 /*Set the DiseqC mode to 22Khz _continues_ tone*/
1816 stv0900_write_bits(intp, DISTX_MODE, 0);
1817 stv0900_write_bits(intp, DISEQC_RESET, 1);
1818 /*release DiseqC reset to enable the 22KHz tone*/
1819 stv0900_write_bits(intp, DISEQC_RESET, 0);
1820 break;
1821 case SEC_TONE_OFF:
1822 /*return diseqc mode to config->diseqc_mode.
1823 Usually it's without _continues_ tone */
1824 stv0900_write_bits(intp, DISTX_MODE,
1825 state->config->diseqc_mode);
1826 /*maintain the DiseqC reset to disable the 22KHz tone*/
1827 stv0900_write_bits(intp, DISEQC_RESET, 1);
1828 stv0900_write_bits(intp, DISEQC_RESET, 0);
1829 break;
1830 default:
1831 return -EINVAL;
1832 }
1833
1834 return 0;
1835}
1836
1837static void stv0900_release(struct dvb_frontend *fe)
1838{
1839 struct stv0900_state *state = fe->demodulator_priv;
1840
1841 dprintk("%s\n", __func__);
1842
1843 if (state->config->set_lock_led)
1844 state->config->set_lock_led(fe, 0);
1845
1846 if ((--(state->internal->dmds_used)) <= 0) {
1847
1848 dprintk("%s: Actually removing\n", __func__);
1849
1850 remove_inode(state->internal);
1851 kfree(state->internal);
1852 }
1853
1854 kfree(state);
1855}
1856
1857static int stv0900_sleep(struct dvb_frontend *fe)
1858{
1859 struct stv0900_state *state = fe->demodulator_priv;
1860
1861 dprintk("%s\n", __func__);
1862
1863 if (state->config->set_lock_led)
1864 state->config->set_lock_led(fe, 0);
1865
1866 return 0;
1867}
1868
1869static int stv0900_get_frontend(struct dvb_frontend *fe,
1870 struct dvb_frontend_parameters *p)
1871{
1872 struct stv0900_state *state = fe->demodulator_priv;
1873 struct stv0900_internal *intp = state->internal;
1874 enum fe_stv0900_demod_num demod = state->demod;
1875 struct stv0900_signal_info p_result = intp->result[demod];
1876
1877 p->frequency = p_result.locked ? p_result.frequency : 0;
1878 p->u.qpsk.symbol_rate = p_result.locked ? p_result.symbol_rate : 0;
1879 return 0;
1880}
1881
1882static struct dvb_frontend_ops stv0900_ops = {
1883
1884 .info = {
1885 .name = "STV0900 frontend",
1886 .type = FE_QPSK,
1887 .frequency_min = 950000,
1888 .frequency_max = 2150000,
1889 .frequency_stepsize = 125,
1890 .frequency_tolerance = 0,
1891 .symbol_rate_min = 1000000,
1892 .symbol_rate_max = 45000000,
1893 .symbol_rate_tolerance = 500,
1894 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
1895 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
1896 FE_CAN_FEC_7_8 | FE_CAN_QPSK |
1897 FE_CAN_2G_MODULATION |
1898 FE_CAN_FEC_AUTO
1899 },
1900 .release = stv0900_release,
1901 .init = stv0900_init,
1902 .get_frontend = stv0900_get_frontend,
1903 .sleep = stv0900_sleep,
1904 .get_frontend_algo = stv0900_frontend_algo,
1905 .i2c_gate_ctrl = stv0900_i2c_gate_ctrl,
1906 .diseqc_send_master_cmd = stv0900_send_master_cmd,
1907 .diseqc_send_burst = stv0900_send_burst,
1908 .diseqc_recv_slave_reply = stv0900_recv_slave_reply,
1909 .set_tone = stv0900_set_tone,
1910 .set_property = stb0900_set_property,
1911 .get_property = stb0900_get_property,
1912 .search = stv0900_search,
1913 .track = stv0900_track,
1914 .read_status = stv0900_read_status,
1915 .read_ber = stv0900_read_ber,
1916 .read_signal_strength = stv0900_read_signal_strength,
1917 .read_snr = stv0900_read_snr,
1918 .read_ucblocks = stv0900_read_ucblocks,
1919};
1920
1921struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
1922 struct i2c_adapter *i2c,
1923 int demod)
1924{
1925 struct stv0900_state *state = NULL;
1926 struct stv0900_init_params init_params;
1927 enum fe_stv0900_error err_stv0900;
1928
1929 state = kzalloc(sizeof(struct stv0900_state), GFP_KERNEL);
1930 if (state == NULL)
1931 goto error;
1932
1933 state->demod = demod;
1934 state->config = config;
1935 state->i2c_adap = i2c;
1936
1937 memcpy(&state->frontend.ops, &stv0900_ops,
1938 sizeof(struct dvb_frontend_ops));
1939 state->frontend.demodulator_priv = state;
1940
1941 switch (demod) {
1942 case 0:
1943 case 1:
1944 init_params.dmd_ref_clk = config->xtal;
1945 init_params.demod_mode = config->demod_mode;
1946 init_params.rolloff = STV0900_35;
1947 init_params.path1_ts_clock = config->path1_mode;
1948 init_params.tun1_maddress = config->tun1_maddress;
1949 init_params.tun1_iq_inv = STV0900_IQ_NORMAL;
1950 init_params.tuner1_adc = config->tun1_adc;
1951 init_params.tuner1_type = config->tun1_type;
1952 init_params.path2_ts_clock = config->path2_mode;
1953 init_params.ts_config = config->ts_config_regs;
1954 init_params.tun2_maddress = config->tun2_maddress;
1955 init_params.tuner2_adc = config->tun2_adc;
1956 init_params.tuner2_type = config->tun2_type;
1957 init_params.tun2_iq_inv = STV0900_IQ_SWAPPED;
1958
1959 err_stv0900 = stv0900_init_internal(&state->frontend,
1960 &init_params);
1961
1962 if (err_stv0900)
1963 goto error;
1964
1965 break;
1966 default:
1967 goto error;
1968 break;
1969 }
1970
1971 dprintk("%s: Attaching STV0900 demodulator(%d) \n", __func__, demod);
1972 return &state->frontend;
1973
1974error:
1975 dprintk("%s: Failed to attach STV0900 demodulator(%d) \n",
1976 __func__, demod);
1977 kfree(state);
1978 return NULL;
1979}
1980EXPORT_SYMBOL(stv0900_attach);
1981
1982MODULE_PARM_DESC(debug, "Set debug");
1983
1984MODULE_AUTHOR("Igor M. Liplianin");
1985MODULE_DESCRIPTION("ST STV0900 frontend");
1986MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv0900_init.h b/drivers/media/dvb/frontends/stv0900_init.h
new file mode 100644
index 00000000000..b684df9995d
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_init.h
@@ -0,0 +1,584 @@
1/*
2 * stv0900_init.h
3 *
4 * Driver for ST STV0900 satellite demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2009 NetUP Inc.
8 * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef STV0900_INIT_H
27#define STV0900_INIT_H
28
29#include "stv0900_priv.h"
30
31/* DVBS2 C/N Look-Up table */
32static const struct stv0900_table stv0900_s2_cn = {
33 55,
34 {
35 { -30, 13348 }, /*C/N=-3dB*/
36 { -20, 12640 }, /*C/N=-2dB*/
37 { -10, 11883 }, /*C/N=-1dB*/
38 { 0, 11101 }, /*C/N=-0dB*/
39 { 5, 10718 }, /*C/N=0.5dB*/
40 { 10, 10339 }, /*C/N=1.0dB*/
41 { 15, 9947 }, /*C/N=1.5dB*/
42 { 20, 9552 }, /*C/N=2.0dB*/
43 { 25, 9183 }, /*C/N=2.5dB*/
44 { 30, 8799 }, /*C/N=3.0dB*/
45 { 35, 8422 }, /*C/N=3.5dB*/
46 { 40, 8062 }, /*C/N=4.0dB*/
47 { 45, 7707 }, /*C/N=4.5dB*/
48 { 50, 7353 }, /*C/N=5.0dB*/
49 { 55, 7025 }, /*C/N=5.5dB*/
50 { 60, 6684 }, /*C/N=6.0dB*/
51 { 65, 6331 }, /*C/N=6.5dB*/
52 { 70, 6036 }, /*C/N=7.0dB*/
53 { 75, 5727 }, /*C/N=7.5dB*/
54 { 80, 5437 }, /*C/N=8.0dB*/
55 { 85, 5164 }, /*C/N=8.5dB*/
56 { 90, 4902 }, /*C/N=9.0dB*/
57 { 95, 4653 }, /*C/N=9.5dB*/
58 { 100, 4408 }, /*C/N=10.0dB*/
59 { 105, 4187 }, /*C/N=10.5dB*/
60 { 110, 3961 }, /*C/N=11.0dB*/
61 { 115, 3751 }, /*C/N=11.5dB*/
62 { 120, 3558 }, /*C/N=12.0dB*/
63 { 125, 3368 }, /*C/N=12.5dB*/
64 { 130, 3191 }, /*C/N=13.0dB*/
65 { 135, 3017 }, /*C/N=13.5dB*/
66 { 140, 2862 }, /*C/N=14.0dB*/
67 { 145, 2710 }, /*C/N=14.5dB*/
68 { 150, 2565 }, /*C/N=15.0dB*/
69 { 160, 2300 }, /*C/N=16.0dB*/
70 { 170, 2058 }, /*C/N=17.0dB*/
71 { 180, 1849 }, /*C/N=18.0dB*/
72 { 190, 1663 }, /*C/N=19.0dB*/
73 { 200, 1495 }, /*C/N=20.0dB*/
74 { 210, 1349 }, /*C/N=21.0dB*/
75 { 220, 1222 }, /*C/N=22.0dB*/
76 { 230, 1110 }, /*C/N=23.0dB*/
77 { 240, 1011 }, /*C/N=24.0dB*/
78 { 250, 925 }, /*C/N=25.0dB*/
79 { 260, 853 }, /*C/N=26.0dB*/
80 { 270, 789 }, /*C/N=27.0dB*/
81 { 280, 734 }, /*C/N=28.0dB*/
82 { 290, 690 }, /*C/N=29.0dB*/
83 { 300, 650 }, /*C/N=30.0dB*/
84 { 310, 619 }, /*C/N=31.0dB*/
85 { 320, 593 }, /*C/N=32.0dB*/
86 { 330, 571 }, /*C/N=33.0dB*/
87 { 400, 498 }, /*C/N=40.0dB*/
88 { 450, 484 }, /*C/N=45.0dB*/
89 { 500, 481 } /*C/N=50.0dB*/
90 }
91};
92
93/* RF level C/N Look-Up table */
94static const struct stv0900_table stv0900_rf = {
95 14,
96 {
97 { -5, 0xCAA1 }, /*-5dBm*/
98 { -10, 0xC229 }, /*-10dBm*/
99 { -15, 0xBB08 }, /*-15dBm*/
100 { -20, 0xB4BC }, /*-20dBm*/
101 { -25, 0xAD5A }, /*-25dBm*/
102 { -30, 0xA298 }, /*-30dBm*/
103 { -35, 0x98A8 }, /*-35dBm*/
104 { -40, 0x8389 }, /*-40dBm*/
105 { -45, 0x59BE }, /*-45dBm*/
106 { -50, 0x3A14 }, /*-50dBm*/
107 { -55, 0x2D11 }, /*-55dBm*/
108 { -60, 0x210D }, /*-60dBm*/
109 { -65, 0xA14F }, /*-65dBm*/
110 { -70, 0x7AA } /*-70dBm*/
111 }
112};
113
114struct stv0900_car_loop_optim {
115 enum fe_stv0900_modcode modcode;
116 u8 car_loop_pilots_on_2;
117 u8 car_loop_pilots_off_2;
118 u8 car_loop_pilots_on_5;
119 u8 car_loop_pilots_off_5;
120 u8 car_loop_pilots_on_10;
121 u8 car_loop_pilots_off_10;
122 u8 car_loop_pilots_on_20;
123 u8 car_loop_pilots_off_20;
124 u8 car_loop_pilots_on_30;
125 u8 car_loop_pilots_off_30;
126
127};
128
129struct stv0900_short_frames_car_loop_optim {
130 enum fe_stv0900_modulation modulation;
131 u8 car_loop_cut12_2; /* Cut 1.2, SR<=3msps */
132 u8 car_loop_cut20_2; /* Cut 2.0, SR<3msps */
133 u8 car_loop_cut12_5; /* Cut 1.2, 3<SR<=7msps */
134 u8 car_loop_cut20_5; /* Cut 2.0, 3<SR<=7msps */
135 u8 car_loop_cut12_10; /* Cut 1.2, 7<SR<=15msps */
136 u8 car_loop_cut20_10; /* Cut 2.0, 7<SR<=15msps */
137 u8 car_loop_cut12_20; /* Cut 1.2, 10<SR<=25msps */
138 u8 car_loop_cut20_20; /* Cut 2.0, 10<SR<=25msps */
139 u8 car_loop_cut12_30; /* Cut 1.2, 25<SR<=45msps */
140 u8 car_loop_cut20_30; /* Cut 2.0, 10<SR<=45msps */
141
142};
143
144struct stv0900_short_frames_car_loop_optim_vs_mod {
145 enum fe_stv0900_modulation modulation;
146 u8 car_loop_2; /* SR<3msps */
147 u8 car_loop_5; /* 3<SR<=7msps */
148 u8 car_loop_10; /* 7<SR<=15msps */
149 u8 car_loop_20; /* 10<SR<=25msps */
150 u8 car_loop_30; /* 10<SR<=45msps */
151};
152
153/* Cut 1.x Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
154static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = {
155 /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
156 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
157 { STV0900_QPSK_12, 0x1C, 0x0D, 0x1B, 0x2C, 0x3A,
158 0x1C, 0x2A, 0x3B, 0x2A, 0x1B },
159 { STV0900_QPSK_35, 0x2C, 0x0D, 0x2B, 0x2C, 0x3A,
160 0x0C, 0x3A, 0x2B, 0x2A, 0x0B },
161 { STV0900_QPSK_23, 0x2C, 0x0D, 0x2B, 0x2C, 0x0B,
162 0x0C, 0x3A, 0x1B, 0x2A, 0x3A },
163 { STV0900_QPSK_34, 0x3C, 0x0D, 0x3B, 0x1C, 0x0B,
164 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
165 { STV0900_QPSK_45, 0x3C, 0x0D, 0x3B, 0x1C, 0x0B,
166 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
167 { STV0900_QPSK_56, 0x0D, 0x0D, 0x3B, 0x1C, 0x0B,
168 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
169 { STV0900_QPSK_89, 0x0D, 0x0D, 0x3B, 0x1C, 0x1B,
170 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
171 { STV0900_QPSK_910, 0x1D, 0x0D, 0x3B, 0x1C, 0x1B,
172 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
173 { STV0900_8PSK_35, 0x29, 0x3B, 0x09, 0x2B, 0x38,
174 0x0B, 0x18, 0x1A, 0x08, 0x0A },
175 { STV0900_8PSK_23, 0x0A, 0x3B, 0x29, 0x2B, 0x19,
176 0x0B, 0x38, 0x1A, 0x18, 0x0A },
177 { STV0900_8PSK_34, 0x3A, 0x3B, 0x2A, 0x2B, 0x39,
178 0x0B, 0x19, 0x1A, 0x38, 0x0A },
179 { STV0900_8PSK_56, 0x1B, 0x3B, 0x0B, 0x2B, 0x1A,
180 0x0B, 0x39, 0x1A, 0x19, 0x0A },
181 { STV0900_8PSK_89, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A,
182 0x0B, 0x39, 0x1A, 0x29, 0x39 },
183 { STV0900_8PSK_910, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A,
184 0x0B, 0x39, 0x1A, 0x29, 0x39 }
185};
186
187
188/* Cut 2.0 Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
189static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
190 /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
191 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
192 { STV0900_QPSK_12, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D,
193 0x1F, 0x3D, 0x3E, 0x3D, 0x1E },
194 { STV0900_QPSK_35, 0x2F, 0x3F, 0x2E, 0x2F, 0x3D,
195 0x0F, 0x0E, 0x2E, 0x3D, 0x0E },
196 { STV0900_QPSK_23, 0x2F, 0x3F, 0x2E, 0x2F, 0x0E,
197 0x0F, 0x0E, 0x1E, 0x3D, 0x3D },
198 { STV0900_QPSK_34, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E,
199 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
200 { STV0900_QPSK_45, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E,
201 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
202 { STV0900_QPSK_56, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E,
203 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
204 { STV0900_QPSK_89, 0x3F, 0x3F, 0x3E, 0x1F, 0x1E,
205 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
206 { STV0900_QPSK_910, 0x3F, 0x3F, 0x3E, 0x1F, 0x1E,
207 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
208 { STV0900_8PSK_35, 0x3c, 0x0c, 0x1c, 0x3b, 0x0c,
209 0x3b, 0x2b, 0x2b, 0x1b, 0x2b },
210 { STV0900_8PSK_23, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c,
211 0x3b, 0x0c, 0x2b, 0x2b, 0x2b },
212 { STV0900_8PSK_34, 0x0e, 0x1c, 0x3d, 0x0c, 0x0d,
213 0x3b, 0x2c, 0x3b, 0x0c, 0x2b },
214 { STV0900_8PSK_56, 0x2e, 0x3e, 0x1e, 0x2e, 0x2d,
215 0x1e, 0x3c, 0x2d, 0x2c, 0x1d },
216 { STV0900_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d,
217 0x1e, 0x0d, 0x2d, 0x3c, 0x1d },
218 { STV0900_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d,
219 0x1e, 0x1d, 0x2d, 0x0d, 0x1d },
220};
221
222
223
224/* Cut 2.0 Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame */
225static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = {
226 /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
227 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
228 { STV0900_16APSK_23, 0x0C, 0x0C, 0x0C, 0x0C, 0x1D,
229 0x0C, 0x3C, 0x0C, 0x2C, 0x0C },
230 { STV0900_16APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E,
231 0x0C, 0x2D, 0x0C, 0x1D, 0x0C },
232 { STV0900_16APSK_45, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E,
233 0x0C, 0x3D, 0x0C, 0x2D, 0x0C },
234 { STV0900_16APSK_56, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E,
235 0x0C, 0x3D, 0x0C, 0x2D, 0x0C },
236 { STV0900_16APSK_89, 0x0C, 0x0C, 0x0C, 0x0C, 0x2E,
237 0x0C, 0x0E, 0x0C, 0x3D, 0x0C },
238 { STV0900_16APSK_910, 0x0C, 0x0C, 0x0C, 0x0C, 0x2E,
239 0x0C, 0x0E, 0x0C, 0x3D, 0x0C },
240 { STV0900_32APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
241 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
242 { STV0900_32APSK_45, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
243 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
244 { STV0900_32APSK_56, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
245 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
246 { STV0900_32APSK_89, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
247 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
248 { STV0900_32APSK_910, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
249 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
250};
251
252
253/* Cut 2.0 Tracking carrier loop carrier QPSK 1/4 to QPSK 2/5 long Frame */
254static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut20[3] = {
255 /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
256 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
257 { STV0900_QPSK_14, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D,
258 0x2F, 0x2D, 0x1F, 0x3D, 0x3E },
259 { STV0900_QPSK_13, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D,
260 0x2F, 0x3D, 0x0F, 0x3D, 0x2E },
261 { STV0900_QPSK_25, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D,
262 0x1F, 0x3D, 0x3E, 0x3D, 0x2E }
263};
264
265
266/* Cut 2.0 Tracking carrier loop carrier short Frame, cut 1.2 and 2.0 */
267static const
268struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4] = {
269 /*Mod 2Mcut1.2 2Mcut2.0 5Mcut1.2 5Mcut2.0 10Mcut1.2
270 10Mcut2.0 20Mcut1.2 20M_cut2.0 30Mcut1.2 30Mcut2.0*/
271 { STV0900_QPSK, 0x3C, 0x2F, 0x2B, 0x2E, 0x0B,
272 0x0E, 0x3A, 0x0E, 0x2A, 0x3D },
273 { STV0900_8PSK, 0x0B, 0x3E, 0x2A, 0x0E, 0x0A,
274 0x2D, 0x19, 0x0D, 0x09, 0x3C },
275 { STV0900_16APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B,
276 0x1E, 0x3A, 0x3D, 0x2A, 0x2D },
277 { STV0900_32APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B,
278 0x1E, 0x3A, 0x3D, 0x2A, 0x2D }
279};
280
281static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut30[14] = {
282 /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
283 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
284 { STV0900_QPSK_12, 0x3C, 0x2C, 0x0C, 0x2C, 0x1B,
285 0x2C, 0x1B, 0x1C, 0x0B, 0x3B },
286 { STV0900_QPSK_35, 0x0D, 0x0D, 0x0C, 0x0D, 0x1B,
287 0x3C, 0x1B, 0x1C, 0x0B, 0x3B },
288 { STV0900_QPSK_23, 0x1D, 0x0D, 0x0C, 0x1D, 0x2B,
289 0x3C, 0x1B, 0x1C, 0x0B, 0x3B },
290 { STV0900_QPSK_34, 0x1D, 0x1D, 0x0C, 0x1D, 0x2B,
291 0x3C, 0x1B, 0x1C, 0x0B, 0x3B },
292 { STV0900_QPSK_45, 0x2D, 0x1D, 0x1C, 0x1D, 0x2B,
293 0x3C, 0x2B, 0x0C, 0x1B, 0x3B },
294 { STV0900_QPSK_56, 0x2D, 0x1D, 0x1C, 0x1D, 0x2B,
295 0x3C, 0x2B, 0x0C, 0x1B, 0x3B },
296 { STV0900_QPSK_89, 0x3D, 0x2D, 0x1C, 0x1D, 0x3B,
297 0x3C, 0x2B, 0x0C, 0x1B, 0x3B },
298 { STV0900_QPSK_910, 0x3D, 0x2D, 0x1C, 0x1D, 0x3B,
299 0x3C, 0x2B, 0x0C, 0x1B, 0x3B },
300 { STV0900_8PSK_35, 0x39, 0x19, 0x39, 0x19, 0x19,
301 0x19, 0x19, 0x19, 0x09, 0x19 },
302 { STV0900_8PSK_23, 0x2A, 0x39, 0x1A, 0x0A, 0x39,
303 0x0A, 0x29, 0x39, 0x29, 0x0A },
304 { STV0900_8PSK_34, 0x0B, 0x3A, 0x0B, 0x0B, 0x3A,
305 0x1B, 0x1A, 0x0B, 0x1A, 0x3A },
306 { STV0900_8PSK_56, 0x0C, 0x1B, 0x3B, 0x2B, 0x1B,
307 0x3B, 0x3A, 0x3B, 0x3A, 0x1B },
308 { STV0900_8PSK_89, 0x2C, 0x2C, 0x2C, 0x1C, 0x2B,
309 0x0C, 0x0B, 0x3B, 0x0B, 0x1B },
310 { STV0900_8PSK_910, 0x2C, 0x3C, 0x2C, 0x1C, 0x3B,
311 0x1C, 0x0B, 0x3B, 0x0B, 0x1B }
312};
313
314static const
315struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut30[11] = {
316 /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
317 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
318 { STV0900_16APSK_23, 0x0A, 0x0A, 0x0A, 0x0A, 0x1A,
319 0x0A, 0x3A, 0x0A, 0x2A, 0x0A },
320 { STV0900_16APSK_34, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B,
321 0x0A, 0x3B, 0x0A, 0x1B, 0x0A },
322 { STV0900_16APSK_45, 0x0A, 0x0A, 0x0A, 0x0A, 0x1B,
323 0x0A, 0x3B, 0x0A, 0x2B, 0x0A },
324 { STV0900_16APSK_56, 0x0A, 0x0A, 0x0A, 0x0A, 0x1B,
325 0x0A, 0x3B, 0x0A, 0x2B, 0x0A },
326 { STV0900_16APSK_89, 0x0A, 0x0A, 0x0A, 0x0A, 0x2B,
327 0x0A, 0x0C, 0x0A, 0x3B, 0x0A },
328 { STV0900_16APSK_910, 0x0A, 0x0A, 0x0A, 0x0A, 0x2B,
329 0x0A, 0x0C, 0x0A, 0x3B, 0x0A },
330 { STV0900_32APSK_34, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
331 0x0A, 0x0A, 0x0A, 0x0A, 0x0A },
332 { STV0900_32APSK_45, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
333 0x0A, 0x0A, 0x0A, 0x0A, 0x0A },
334 { STV0900_32APSK_56, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
335 0x0A, 0x0A, 0x0A, 0x0A, 0x0A },
336 { STV0900_32APSK_89, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
337 0x0A, 0x0A, 0x0A, 0x0A, 0x0A },
338 { STV0900_32APSK_910, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
339 0x0A, 0x0A, 0x0A, 0x0A, 0x0A }
340};
341
342static const
343struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut30[3] = {
344 /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
345 10MPoff 20MPon 20MPoff 30MPon 30MPoff*/
346 { STV0900_QPSK_14, 0x0C, 0x3C, 0x0B, 0x3C, 0x2A,
347 0x2C, 0x2A, 0x1C, 0x3A, 0x3B },
348 { STV0900_QPSK_13, 0x0C, 0x3C, 0x0B, 0x3C, 0x2A,
349 0x2C, 0x3A, 0x0C, 0x3A, 0x2B },
350 { STV0900_QPSK_25, 0x1C, 0x3C, 0x1B, 0x3C, 0x3A,
351 0x1C, 0x3A, 0x3B, 0x3A, 0x2B }
352};
353
354static const struct stv0900_short_frames_car_loop_optim_vs_mod
355FE_STV0900_S2ShortCarLoopCut30[4] = {
356 /*Mod 2Mcut3.0 5Mcut3.0 10Mcut3.0 20Mcut3.0 30Mcut3.0*/
357 { STV0900_QPSK, 0x2C, 0x2B, 0x0B, 0x0B, 0x3A },
358 { STV0900_8PSK, 0x3B, 0x0B, 0x2A, 0x0A, 0x39 },
359 { STV0900_16APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A },
360 { STV0900_32APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A },
361
362};
363
364static const u16 STV0900_InitVal[181][2] = {
365 { R0900_OUTCFG , 0x00 },
366 { R0900_AGCRF1CFG , 0x11 },
367 { R0900_AGCRF2CFG , 0x13 },
368 { R0900_TSGENERAL1X , 0x14 },
369 { R0900_TSTTNR2 , 0x21 },
370 { R0900_TSTTNR4 , 0x21 },
371 { R0900_P2_DISTXCTL , 0x22 },
372 { R0900_P2_F22TX , 0xc0 },
373 { R0900_P2_F22RX , 0xc0 },
374 { R0900_P2_DISRXCTL , 0x00 },
375 { R0900_P2_TNRSTEPS , 0x87 },
376 { R0900_P2_TNRGAIN , 0x09 },
377 { R0900_P2_DMDCFGMD , 0xF9 },
378 { R0900_P2_DEMOD , 0x08 },
379 { R0900_P2_DMDCFG3 , 0xc4 },
380 { R0900_P2_CARFREQ , 0xed },
381 { R0900_P2_TNRCFG2 , 0x02 },
382 { R0900_P2_TNRCFG3 , 0x02 },
383 { R0900_P2_LDT , 0xd0 },
384 { R0900_P2_LDT2 , 0xb8 },
385 { R0900_P2_TMGCFG , 0xd2 },
386 { R0900_P2_TMGTHRISE , 0x20 },
387 { R0900_P2_TMGTHFALL , 0x00 },
388 { R0900_P2_FECSPY , 0x88 },
389 { R0900_P2_FSPYDATA , 0x3a },
390 { R0900_P2_FBERCPT4 , 0x00 },
391 { R0900_P2_FSPYBER , 0x10 },
392 { R0900_P2_ERRCTRL1 , 0x35 },
393 { R0900_P2_ERRCTRL2 , 0xc1 },
394 { R0900_P2_CFRICFG , 0xf8 },
395 { R0900_P2_NOSCFG , 0x1c },
396 { R0900_P2_DMDT0M , 0x20 },
397 { R0900_P2_CORRELMANT , 0x70 },
398 { R0900_P2_CORRELABS , 0x88 },
399 { R0900_P2_AGC2O , 0x5b },
400 { R0900_P2_AGC2REF , 0x38 },
401 { R0900_P2_CARCFG , 0xe4 },
402 { R0900_P2_ACLC , 0x1A },
403 { R0900_P2_BCLC , 0x09 },
404 { R0900_P2_CARHDR , 0x08 },
405 { R0900_P2_KREFTMG , 0xc1 },
406 { R0900_P2_SFRUPRATIO , 0xf0 },
407 { R0900_P2_SFRLOWRATIO , 0x70 },
408 { R0900_P2_SFRSTEP , 0x58 },
409 { R0900_P2_TMGCFG2 , 0x01 },
410 { R0900_P2_CAR2CFG , 0x26 },
411 { R0900_P2_BCLC2S2Q , 0x86 },
412 { R0900_P2_BCLC2S28 , 0x86 },
413 { R0900_P2_SMAPCOEF7 , 0x77 },
414 { R0900_P2_SMAPCOEF6 , 0x85 },
415 { R0900_P2_SMAPCOEF5 , 0x77 },
416 { R0900_P2_TSCFGL , 0x20 },
417 { R0900_P2_DMDCFG2 , 0x3b },
418 { R0900_P2_MODCODLST0 , 0xff },
419 { R0900_P2_MODCODLST1 , 0xff },
420 { R0900_P2_MODCODLST2 , 0xff },
421 { R0900_P2_MODCODLST3 , 0xff },
422 { R0900_P2_MODCODLST4 , 0xff },
423 { R0900_P2_MODCODLST5 , 0xff },
424 { R0900_P2_MODCODLST6 , 0xff },
425 { R0900_P2_MODCODLST7 , 0xcc },
426 { R0900_P2_MODCODLST8 , 0xcc },
427 { R0900_P2_MODCODLST9 , 0xcc },
428 { R0900_P2_MODCODLSTA , 0xcc },
429 { R0900_P2_MODCODLSTB , 0xcc },
430 { R0900_P2_MODCODLSTC , 0xcc },
431 { R0900_P2_MODCODLSTD , 0xcc },
432 { R0900_P2_MODCODLSTE , 0xcc },
433 { R0900_P2_MODCODLSTF , 0xcf },
434 { R0900_P1_DISTXCTL , 0x22 },
435 { R0900_P1_F22TX , 0xc0 },
436 { R0900_P1_F22RX , 0xc0 },
437 { R0900_P1_DISRXCTL , 0x00 },
438 { R0900_P1_TNRSTEPS , 0x87 },
439 { R0900_P1_TNRGAIN , 0x09 },
440 { R0900_P1_DMDCFGMD , 0xf9 },
441 { R0900_P1_DEMOD , 0x08 },
442 { R0900_P1_DMDCFG3 , 0xc4 },
443 { R0900_P1_DMDT0M , 0x20 },
444 { R0900_P1_CARFREQ , 0xed },
445 { R0900_P1_TNRCFG2 , 0x82 },
446 { R0900_P1_TNRCFG3 , 0x02 },
447 { R0900_P1_LDT , 0xd0 },
448 { R0900_P1_LDT2 , 0xb8 },
449 { R0900_P1_TMGCFG , 0xd2 },
450 { R0900_P1_TMGTHRISE , 0x20 },
451 { R0900_P1_TMGTHFALL , 0x00 },
452 { R0900_P1_SFRUPRATIO , 0xf0 },
453 { R0900_P1_SFRLOWRATIO , 0x70 },
454 { R0900_P1_TSCFGL , 0x20 },
455 { R0900_P1_FECSPY , 0x88 },
456 { R0900_P1_FSPYDATA , 0x3a },
457 { R0900_P1_FBERCPT4 , 0x00 },
458 { R0900_P1_FSPYBER , 0x10 },
459 { R0900_P1_ERRCTRL1 , 0x35 },
460 { R0900_P1_ERRCTRL2 , 0xc1 },
461 { R0900_P1_CFRICFG , 0xf8 },
462 { R0900_P1_NOSCFG , 0x1c },
463 { R0900_P1_CORRELMANT , 0x70 },
464 { R0900_P1_CORRELABS , 0x88 },
465 { R0900_P1_AGC2O , 0x5b },
466 { R0900_P1_AGC2REF , 0x38 },
467 { R0900_P1_CARCFG , 0xe4 },
468 { R0900_P1_ACLC , 0x1A },
469 { R0900_P1_BCLC , 0x09 },
470 { R0900_P1_CARHDR , 0x08 },
471 { R0900_P1_KREFTMG , 0xc1 },
472 { R0900_P1_SFRSTEP , 0x58 },
473 { R0900_P1_TMGCFG2 , 0x01 },
474 { R0900_P1_CAR2CFG , 0x26 },
475 { R0900_P1_BCLC2S2Q , 0x86 },
476 { R0900_P1_BCLC2S28 , 0x86 },
477 { R0900_P1_SMAPCOEF7 , 0x77 },
478 { R0900_P1_SMAPCOEF6 , 0x85 },
479 { R0900_P1_SMAPCOEF5 , 0x77 },
480 { R0900_P1_DMDCFG2 , 0x3b },
481 { R0900_P1_MODCODLST0 , 0xff },
482 { R0900_P1_MODCODLST1 , 0xff },
483 { R0900_P1_MODCODLST2 , 0xff },
484 { R0900_P1_MODCODLST3 , 0xff },
485 { R0900_P1_MODCODLST4 , 0xff },
486 { R0900_P1_MODCODLST5 , 0xff },
487 { R0900_P1_MODCODLST6 , 0xff },
488 { R0900_P1_MODCODLST7 , 0xcc },
489 { R0900_P1_MODCODLST8 , 0xcc },
490 { R0900_P1_MODCODLST9 , 0xcc },
491 { R0900_P1_MODCODLSTA , 0xcc },
492 { R0900_P1_MODCODLSTB , 0xcc },
493 { R0900_P1_MODCODLSTC , 0xcc },
494 { R0900_P1_MODCODLSTD , 0xcc },
495 { R0900_P1_MODCODLSTE , 0xcc },
496 { R0900_P1_MODCODLSTF , 0xcf },
497 { R0900_GENCFG , 0x1d },
498 { R0900_NBITER_NF4 , 0x37 },
499 { R0900_NBITER_NF5 , 0x29 },
500 { R0900_NBITER_NF6 , 0x37 },
501 { R0900_NBITER_NF7 , 0x33 },
502 { R0900_NBITER_NF8 , 0x31 },
503 { R0900_NBITER_NF9 , 0x2f },
504 { R0900_NBITER_NF10 , 0x39 },
505 { R0900_NBITER_NF11 , 0x3a },
506 { R0900_NBITER_NF12 , 0x29 },
507 { R0900_NBITER_NF13 , 0x37 },
508 { R0900_NBITER_NF14 , 0x33 },
509 { R0900_NBITER_NF15 , 0x2f },
510 { R0900_NBITER_NF16 , 0x39 },
511 { R0900_NBITER_NF17 , 0x3a },
512 { R0900_NBITERNOERR , 0x04 },
513 { R0900_GAINLLR_NF4 , 0x0C },
514 { R0900_GAINLLR_NF5 , 0x0F },
515 { R0900_GAINLLR_NF6 , 0x11 },
516 { R0900_GAINLLR_NF7 , 0x14 },
517 { R0900_GAINLLR_NF8 , 0x17 },
518 { R0900_GAINLLR_NF9 , 0x19 },
519 { R0900_GAINLLR_NF10 , 0x20 },
520 { R0900_GAINLLR_NF11 , 0x21 },
521 { R0900_GAINLLR_NF12 , 0x0D },
522 { R0900_GAINLLR_NF13 , 0x0F },
523 { R0900_GAINLLR_NF14 , 0x13 },
524 { R0900_GAINLLR_NF15 , 0x1A },
525 { R0900_GAINLLR_NF16 , 0x1F },
526 { R0900_GAINLLR_NF17 , 0x21 },
527 { R0900_RCCFG2 , 0x20 },
528 { R0900_P1_FECM , 0x01 }, /*disable DSS modes*/
529 { R0900_P2_FECM , 0x01 }, /*disable DSS modes*/
530 { R0900_P1_PRVIT , 0x2F }, /*disable puncture rate 6/7*/
531 { R0900_P2_PRVIT , 0x2F }, /*disable puncture rate 6/7*/
532 { R0900_STROUT1CFG , 0x4c },
533 { R0900_STROUT2CFG , 0x4c },
534 { R0900_CLKOUT1CFG , 0x50 },
535 { R0900_CLKOUT2CFG , 0x50 },
536 { R0900_DPN1CFG , 0x4a },
537 { R0900_DPN2CFG , 0x4a },
538 { R0900_DATA71CFG , 0x52 },
539 { R0900_DATA72CFG , 0x52 },
540 { R0900_P1_TSCFGM , 0xc0 },
541 { R0900_P2_TSCFGM , 0xc0 },
542 { R0900_P1_TSCFGH , 0xe0 }, /* DVB-CI timings */
543 { R0900_P2_TSCFGH , 0xe0 }, /* DVB-CI timings */
544 { R0900_P1_TSSPEED , 0x40 },
545 { R0900_P2_TSSPEED , 0x40 },
546};
547
548static const u16 STV0900_Cut20_AddOnVal[32][2] = {
549 { R0900_P2_DMDCFG3 , 0xe8 },
550 { R0900_P2_DMDCFG4 , 0x10 },
551 { R0900_P2_CARFREQ , 0x38 },
552 { R0900_P2_CARHDR , 0x20 },
553 { R0900_P2_KREFTMG , 0x5a },
554 { R0900_P2_SMAPCOEF7 , 0x06 },
555 { R0900_P2_SMAPCOEF6 , 0x00 },
556 { R0900_P2_SMAPCOEF5 , 0x04 },
557 { R0900_P2_NOSCFG , 0x0c },
558 { R0900_P1_DMDCFG3 , 0xe8 },
559 { R0900_P1_DMDCFG4 , 0x10 },
560 { R0900_P1_CARFREQ , 0x38 },
561 { R0900_P1_CARHDR , 0x20 },
562 { R0900_P1_KREFTMG , 0x5a },
563 { R0900_P1_SMAPCOEF7 , 0x06 },
564 { R0900_P1_SMAPCOEF6 , 0x00 },
565 { R0900_P1_SMAPCOEF5 , 0x04 },
566 { R0900_P1_NOSCFG , 0x0c },
567 { R0900_GAINLLR_NF4 , 0x21 },
568 { R0900_GAINLLR_NF5 , 0x21 },
569 { R0900_GAINLLR_NF6 , 0x20 },
570 { R0900_GAINLLR_NF7 , 0x1F },
571 { R0900_GAINLLR_NF8 , 0x1E },
572 { R0900_GAINLLR_NF9 , 0x1E },
573 { R0900_GAINLLR_NF10 , 0x1D },
574 { R0900_GAINLLR_NF11 , 0x1B },
575 { R0900_GAINLLR_NF12 , 0x20 },
576 { R0900_GAINLLR_NF13 , 0x20 },
577 { R0900_GAINLLR_NF14 , 0x20 },
578 { R0900_GAINLLR_NF15 , 0x20 },
579 { R0900_GAINLLR_NF16 , 0x20 },
580 { R0900_GAINLLR_NF17 , 0x21 }
581
582};
583
584#endif
diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h
new file mode 100644
index 00000000000..e0ea74c8e09
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_priv.h
@@ -0,0 +1,408 @@
1/*
2 * stv0900_priv.h
3 *
4 * Driver for ST STV0900 satellite demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2009 NetUP Inc.
8 * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef STV0900_PRIV_H
27#define STV0900_PRIV_H
28
29#include <linux/i2c.h>
30
31#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
32#define INRANGE(X, Y, Z) ((((X) <= (Y)) && ((Y) <= (Z))) \
33 || (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0)
34
35#ifndef MAKEWORD
36#define MAKEWORD(X, Y) (((X) << 8) + (Y))
37#endif
38
39#define LSB(X) (((X) & 0xFF))
40#define MSB(Y) (((Y) >> 8) & 0xFF)
41
42#ifndef TRUE
43#define TRUE (1 == 1)
44#endif
45#ifndef FALSE
46#define FALSE (!TRUE)
47#endif
48
49#define dprintk(args...) \
50 do { \
51 if (stvdebug) \
52 printk(KERN_DEBUG args); \
53 } while (0)
54
55#define STV0900_MAXLOOKUPSIZE 500
56#define STV0900_BLIND_SEARCH_AGC2_TH 700
57#define STV0900_BLIND_SEARCH_AGC2_TH_CUT30 1400
58#define IQPOWER_THRESHOLD 30
59
60/* One point of the lookup table */
61struct stv000_lookpoint {
62 s32 realval;/* real value */
63 s32 regval;/* binary value */
64};
65
66/* Lookup table definition */
67struct stv0900_table{
68 s32 size;/* Size of the lookup table */
69 struct stv000_lookpoint table[STV0900_MAXLOOKUPSIZE];/* Lookup table */
70};
71
72enum fe_stv0900_error {
73 STV0900_NO_ERROR = 0,
74 STV0900_INVALID_HANDLE,
75 STV0900_BAD_PARAMETER,
76 STV0900_I2C_ERROR,
77 STV0900_SEARCH_FAILED,
78};
79
80enum fe_stv0900_clock_type {
81 STV0900_USE_REGISTERS_DEFAULT,
82 STV0900_SERIAL_PUNCT_CLOCK,/*Serial punctured clock */
83 STV0900_SERIAL_CONT_CLOCK,/*Serial continues clock */
84 STV0900_PARALLEL_PUNCT_CLOCK,/*Parallel punctured clock */
85 STV0900_DVBCI_CLOCK/*Parallel continues clock : DVBCI */
86};
87
88enum fe_stv0900_search_state {
89 STV0900_SEARCH = 0,
90 STV0900_PLH_DETECTED,
91 STV0900_DVBS2_FOUND,
92 STV0900_DVBS_FOUND
93
94};
95
96enum fe_stv0900_ldpc_state {
97 STV0900_PATH1_OFF_PATH2_OFF = 0,
98 STV0900_PATH1_ON_PATH2_OFF = 1,
99 STV0900_PATH1_OFF_PATH2_ON = 2,
100 STV0900_PATH1_ON_PATH2_ON = 3
101};
102
103enum fe_stv0900_signal_type {
104 STV0900_NOAGC1 = 0,
105 STV0900_AGC1OK,
106 STV0900_NOTIMING,
107 STV0900_ANALOGCARRIER,
108 STV0900_TIMINGOK,
109 STV0900_NOAGC2,
110 STV0900_AGC2OK,
111 STV0900_NOCARRIER,
112 STV0900_CARRIEROK,
113 STV0900_NODATA,
114 STV0900_DATAOK,
115 STV0900_OUTOFRANGE,
116 STV0900_RANGEOK
117};
118
119enum fe_stv0900_demod_num {
120 STV0900_DEMOD_1,
121 STV0900_DEMOD_2
122};
123
124enum fe_stv0900_tracking_standard {
125 STV0900_DVBS1_STANDARD,/* Found Standard*/
126 STV0900_DVBS2_STANDARD,
127 STV0900_DSS_STANDARD,
128 STV0900_TURBOCODE_STANDARD,
129 STV0900_UNKNOWN_STANDARD
130};
131
132enum fe_stv0900_search_standard {
133 STV0900_AUTO_SEARCH,
134 STV0900_SEARCH_DVBS1,/* Search Standard*/
135 STV0900_SEARCH_DVBS2,
136 STV0900_SEARCH_DSS,
137 STV0900_SEARCH_TURBOCODE
138};
139
140enum fe_stv0900_search_algo {
141 STV0900_BLIND_SEARCH,/* offset freq and SR are Unknown */
142 STV0900_COLD_START,/* only the SR is known */
143 STV0900_WARM_START/* offset freq and SR are known */
144};
145
146enum fe_stv0900_modulation {
147 STV0900_QPSK,
148 STV0900_8PSK,
149 STV0900_16APSK,
150 STV0900_32APSK,
151 STV0900_UNKNOWN
152};
153
154enum fe_stv0900_modcode {
155 STV0900_DUMMY_PLF,
156 STV0900_QPSK_14,
157 STV0900_QPSK_13,
158 STV0900_QPSK_25,
159 STV0900_QPSK_12,
160 STV0900_QPSK_35,
161 STV0900_QPSK_23,
162 STV0900_QPSK_34,
163 STV0900_QPSK_45,
164 STV0900_QPSK_56,
165 STV0900_QPSK_89,
166 STV0900_QPSK_910,
167 STV0900_8PSK_35,
168 STV0900_8PSK_23,
169 STV0900_8PSK_34,
170 STV0900_8PSK_56,
171 STV0900_8PSK_89,
172 STV0900_8PSK_910,
173 STV0900_16APSK_23,
174 STV0900_16APSK_34,
175 STV0900_16APSK_45,
176 STV0900_16APSK_56,
177 STV0900_16APSK_89,
178 STV0900_16APSK_910,
179 STV0900_32APSK_34,
180 STV0900_32APSK_45,
181 STV0900_32APSK_56,
182 STV0900_32APSK_89,
183 STV0900_32APSK_910,
184 STV0900_MODCODE_UNKNOWN
185};
186
187enum fe_stv0900_fec {/*DVBS1, DSS and turbo code puncture rate*/
188 STV0900_FEC_1_2 = 0,
189 STV0900_FEC_2_3,
190 STV0900_FEC_3_4,
191 STV0900_FEC_4_5,/*for turbo code only*/
192 STV0900_FEC_5_6,
193 STV0900_FEC_6_7,/*for DSS only */
194 STV0900_FEC_7_8,
195 STV0900_FEC_8_9,/*for turbo code only*/
196 STV0900_FEC_UNKNOWN
197};
198
199enum fe_stv0900_frame_length {
200 STV0900_LONG_FRAME,
201 STV0900_SHORT_FRAME
202};
203
204enum fe_stv0900_pilot {
205 STV0900_PILOTS_OFF,
206 STV0900_PILOTS_ON
207};
208
209enum fe_stv0900_rolloff {
210 STV0900_35,
211 STV0900_25,
212 STV0900_20
213};
214
215enum fe_stv0900_search_iq {
216 STV0900_IQ_AUTO,
217 STV0900_IQ_AUTO_NORMAL_FIRST,
218 STV0900_IQ_FORCE_NORMAL,
219 STV0900_IQ_FORCE_SWAPPED
220};
221
222enum stv0900_iq_inversion {
223 STV0900_IQ_NORMAL,
224 STV0900_IQ_SWAPPED
225};
226
227enum fe_stv0900_diseqc_mode {
228 STV0900_22KHZ_Continues = 0,
229 STV0900_DISEQC_2_3_PWM = 2,
230 STV0900_DISEQC_3_3_PWM = 3,
231 STV0900_DISEQC_2_3_ENVELOP = 4,
232 STV0900_DISEQC_3_3_ENVELOP = 5
233};
234
235enum fe_stv0900_demod_mode {
236 STV0900_SINGLE = 0,
237 STV0900_DUAL
238};
239
240struct stv0900_init_params{
241 u32 dmd_ref_clk;/* Reference,Input clock for the demod in Hz */
242
243 /* Demodulator Type (single demod or dual demod) */
244 enum fe_stv0900_demod_mode demod_mode;
245 enum fe_stv0900_rolloff rolloff;
246 enum fe_stv0900_clock_type path1_ts_clock;
247
248 u8 tun1_maddress;
249 int tuner1_adc;
250 int tuner1_type;
251
252 /* IQ from the tuner1 to the demod */
253 enum stv0900_iq_inversion tun1_iq_inv;
254 enum fe_stv0900_clock_type path2_ts_clock;
255
256 u8 tun2_maddress;
257 int tuner2_adc;
258 int tuner2_type;
259
260 /* IQ from the tuner2 to the demod */
261 enum stv0900_iq_inversion tun2_iq_inv;
262 struct stv0900_reg *ts_config;
263};
264
265struct stv0900_search_params {
266 enum fe_stv0900_demod_num path;/* Path Used demod1 or 2 */
267
268 u32 frequency;/* Transponder frequency (in KHz) */
269 u32 symbol_rate;/* Transponder symbol rate (in bds)*/
270 u32 search_range;/* Range of the search (in Hz) */
271
272 enum fe_stv0900_search_standard standard;
273 enum fe_stv0900_modulation modulation;
274 enum fe_stv0900_fec fec;
275 enum fe_stv0900_modcode modcode;
276 enum fe_stv0900_search_iq iq_inversion;
277 enum fe_stv0900_search_algo search_algo;
278
279};
280
281struct stv0900_signal_info {
282 int locked;/* Transponder locked */
283 u32 frequency;/* Transponder frequency (in KHz) */
284 u32 symbol_rate;/* Transponder symbol rate (in Mbds) */
285
286 enum fe_stv0900_tracking_standard standard;
287 enum fe_stv0900_fec fec;
288 enum fe_stv0900_modcode modcode;
289 enum fe_stv0900_modulation modulation;
290 enum fe_stv0900_pilot pilot;
291 enum fe_stv0900_frame_length frame_len;
292 enum stv0900_iq_inversion spectrum;
293 enum fe_stv0900_rolloff rolloff;
294
295 s32 Power;/* Power of the RF signal (dBm) */
296 s32 C_N;/* Carrier to noise ratio (dB x10)*/
297 u32 BER;/* Bit error rate (x10^7) */
298
299};
300
301struct stv0900_internal{
302 s32 quartz;
303 s32 mclk;
304 /* manual RollOff for DVBS1/DSS only */
305 enum fe_stv0900_rolloff rolloff;
306 /* Demodulator use for single demod or for dual demod) */
307 enum fe_stv0900_demod_mode demod_mode;
308
309 /*Demods */
310 s32 freq[2];
311 s32 bw[2];
312 s32 symbol_rate[2];
313 s32 srch_range[2];
314 /* for software/auto tuner */
315 int tuner_type[2];
316
317 /* algorithm for search Blind, Cold or Warm*/
318 enum fe_stv0900_search_algo srch_algo[2];
319 /* search standard: Auto, DVBS1/DSS only or DVBS2 only*/
320 enum fe_stv0900_search_standard srch_standard[2];
321 /* inversion search : auto, auto norma first, normal or inverted */
322 enum fe_stv0900_search_iq srch_iq_inv[2];
323 enum fe_stv0900_modcode modcode[2];
324 enum fe_stv0900_modulation modulation[2];
325 enum fe_stv0900_fec fec[2];
326
327 struct stv0900_signal_info result[2];
328 enum fe_stv0900_error err[2];
329
330
331 struct i2c_adapter *i2c_adap;
332 u8 i2c_addr;
333 u8 clkmode;/* 0 for CLKI, 2 for XTALI */
334 u8 chip_id;
335 struct stv0900_reg *ts_config;
336 enum fe_stv0900_error errs;
337 int dmds_used;
338};
339
340/* state for each demod */
341struct stv0900_state {
342 /* pointer for internal params, one for each pair of demods */
343 struct stv0900_internal *internal;
344 struct i2c_adapter *i2c_adap;
345 const struct stv0900_config *config;
346 struct dvb_frontend frontend;
347 int demod;
348};
349
350extern int stvdebug;
351
352extern s32 ge2comp(s32 a, s32 width);
353
354extern void stv0900_write_reg(struct stv0900_internal *i_params,
355 u16 reg_addr, u8 reg_data);
356
357extern u8 stv0900_read_reg(struct stv0900_internal *i_params,
358 u16 reg_addr);
359
360extern void stv0900_write_bits(struct stv0900_internal *i_params,
361 u32 label, u8 val);
362
363extern u8 stv0900_get_bits(struct stv0900_internal *i_params,
364 u32 label);
365
366extern int stv0900_get_demod_lock(struct stv0900_internal *i_params,
367 enum fe_stv0900_demod_num demod, s32 time_out);
368extern int stv0900_check_signal_presence(struct stv0900_internal *i_params,
369 enum fe_stv0900_demod_num demod);
370
371extern enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe);
372
373extern void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
374 u32 bandwidth);
375extern void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth);
376
377extern void stv0900_start_search(struct stv0900_internal *i_params,
378 enum fe_stv0900_demod_num demod);
379
380extern u8 stv0900_get_optim_carr_loop(s32 srate,
381 enum fe_stv0900_modcode modcode,
382 s32 pilot, u8 chip_id);
383
384extern u8 stv0900_get_optim_short_carr_loop(s32 srate,
385 enum fe_stv0900_modulation modulation,
386 u8 chip_id);
387
388extern void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
389 enum fe_stv0900_demod_num demod);
390
391extern void stv0900_activate_s2_modcod(struct stv0900_internal *i_params,
392 enum fe_stv0900_demod_num demod);
393
394extern void stv0900_activate_s2_modcod_single(struct stv0900_internal *i_params,
395 enum fe_stv0900_demod_num demod);
396
397extern enum
398fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
399 enum fe_stv0900_demod_num demod);
400
401extern u32
402stv0900_get_freq_auto(struct stv0900_internal *intp, int demod);
403
404extern void
405stv0900_set_tuner_auto(struct stv0900_internal *intp, u32 Frequency,
406 u32 Bandwidth, int demod);
407
408#endif
diff --git a/drivers/media/dvb/frontends/stv0900_reg.h b/drivers/media/dvb/frontends/stv0900_reg.h
new file mode 100644
index 00000000000..731afe93a82
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_reg.h
@@ -0,0 +1,3981 @@
1/*
2 * stv0900_reg.h
3 *
4 * Driver for ST STV0900 satellite demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2009 NetUP Inc.
8 * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef STV0900_REG_H
27#define STV0900_REG_H
28
29extern s32 shiftx(s32 x, int demod, s32 shift);
30
31#define REGx(x) shiftx(x, demod, 0x200)
32#define FLDx(x) shiftx(x, demod, 0x2000000)
33
34/*MID*/
35#define R0900_MID 0xf100
36#define F0900_MCHIP_IDENT 0xf10000f0
37#define F0900_MRELEASE 0xf100000f
38
39/*DACR1*/
40#define R0900_DACR1 0xf113
41#define F0900_DAC_MODE 0xf11300e0
42#define F0900_DAC_VALUE1 0xf113000f
43
44/*DACR2*/
45#define R0900_DACR2 0xf114
46#define F0900_DAC_VALUE0 0xf11400ff
47
48/*OUTCFG*/
49#define R0900_OUTCFG 0xf11c
50#define F0900_OUTSERRS1_HZ 0xf11c0040
51#define F0900_OUTSERRS2_HZ 0xf11c0020
52#define F0900_OUTSERRS3_HZ 0xf11c0010
53#define F0900_OUTPARRS3_HZ 0xf11c0008
54
55/*IRQSTATUS3*/
56#define R0900_IRQSTATUS3 0xf120
57#define F0900_SPLL_LOCK 0xf1200020
58#define F0900_SSTREAM_LCK_3 0xf1200010
59#define F0900_SSTREAM_LCK_2 0xf1200008
60#define F0900_SSTREAM_LCK_1 0xf1200004
61#define F0900_SDVBS1_PRF_2 0xf1200002
62#define F0900_SDVBS1_PRF_1 0xf1200001
63
64/*IRQSTATUS2*/
65#define R0900_IRQSTATUS2 0xf121
66#define F0900_SSPY_ENDSIM_3 0xf1210080
67#define F0900_SSPY_ENDSIM_2 0xf1210040
68#define F0900_SSPY_ENDSIM_1 0xf1210020
69#define F0900_SPKTDEL_ERROR_2 0xf1210010
70#define F0900_SPKTDEL_LOCKB_2 0xf1210008
71#define F0900_SPKTDEL_LOCK_2 0xf1210004
72#define F0900_SPKTDEL_ERROR_1 0xf1210002
73#define F0900_SPKTDEL_LOCKB_1 0xf1210001
74
75/*IRQSTATUS1*/
76#define R0900_IRQSTATUS1 0xf122
77#define F0900_SPKTDEL_LOCK_1 0xf1220080
78#define F0900_SDEMOD_LOCKB_2 0xf1220004
79#define F0900_SDEMOD_LOCK_2 0xf1220002
80#define F0900_SDEMOD_IRQ_2 0xf1220001
81
82/*IRQSTATUS0*/
83#define R0900_IRQSTATUS0 0xf123
84#define F0900_SDEMOD_LOCKB_1 0xf1230080
85#define F0900_SDEMOD_LOCK_1 0xf1230040
86#define F0900_SDEMOD_IRQ_1 0xf1230020
87#define F0900_SBCH_ERRFLAG 0xf1230010
88#define F0900_SDISEQC2RX_IRQ 0xf1230008
89#define F0900_SDISEQC2TX_IRQ 0xf1230004
90#define F0900_SDISEQC1RX_IRQ 0xf1230002
91#define F0900_SDISEQC1TX_IRQ 0xf1230001
92
93/*IRQMASK3*/
94#define R0900_IRQMASK3 0xf124
95#define F0900_MPLL_LOCK 0xf1240020
96#define F0900_MSTREAM_LCK_3 0xf1240010
97#define F0900_MSTREAM_LCK_2 0xf1240008
98#define F0900_MSTREAM_LCK_1 0xf1240004
99#define F0900_MDVBS1_PRF_2 0xf1240002
100#define F0900_MDVBS1_PRF_1 0xf1240001
101
102/*IRQMASK2*/
103#define R0900_IRQMASK2 0xf125
104#define F0900_MSPY_ENDSIM_3 0xf1250080
105#define F0900_MSPY_ENDSIM_2 0xf1250040
106#define F0900_MSPY_ENDSIM_1 0xf1250020
107#define F0900_MPKTDEL_ERROR_2 0xf1250010
108#define F0900_MPKTDEL_LOCKB_2 0xf1250008
109#define F0900_MPKTDEL_LOCK_2 0xf1250004
110#define F0900_MPKTDEL_ERROR_1 0xf1250002
111#define F0900_MPKTDEL_LOCKB_1 0xf1250001
112
113/*IRQMASK1*/
114#define R0900_IRQMASK1 0xf126
115#define F0900_MPKTDEL_LOCK_1 0xf1260080
116#define F0900_MEXTPINB2 0xf1260040
117#define F0900_MEXTPIN2 0xf1260020
118#define F0900_MEXTPINB1 0xf1260010
119#define F0900_MEXTPIN1 0xf1260008
120#define F0900_MDEMOD_LOCKB_2 0xf1260004
121#define F0900_MDEMOD_LOCK_2 0xf1260002
122#define F0900_MDEMOD_IRQ_2 0xf1260001
123
124/*IRQMASK0*/
125#define R0900_IRQMASK0 0xf127
126#define F0900_MDEMOD_LOCKB_1 0xf1270080
127#define F0900_MDEMOD_LOCK_1 0xf1270040
128#define F0900_MDEMOD_IRQ_1 0xf1270020
129#define F0900_MBCH_ERRFLAG 0xf1270010
130#define F0900_MDISEQC2RX_IRQ 0xf1270008
131#define F0900_MDISEQC2TX_IRQ 0xf1270004
132#define F0900_MDISEQC1RX_IRQ 0xf1270002
133#define F0900_MDISEQC1TX_IRQ 0xf1270001
134
135/*I2CCFG*/
136#define R0900_I2CCFG 0xf129
137#define F0900_I2C_FASTMODE 0xf1290008
138#define F0900_I2CADDR_INC 0xf1290003
139
140/*P1_I2CRPT*/
141#define R0900_P1_I2CRPT 0xf12a
142#define I2CRPT shiftx(R0900_P1_I2CRPT, demod, -1)
143#define F0900_P1_I2CT_ON 0xf12a0080
144#define I2CT_ON shiftx(F0900_P1_I2CT_ON, demod, -0x10000)
145#define F0900_P1_ENARPT_LEVEL 0xf12a0070
146#define F0900_P1_SCLT_DELAY 0xf12a0008
147#define F0900_P1_STOP_ENABLE 0xf12a0004
148#define F0900_P1_STOP_SDAT2SDA 0xf12a0002
149
150/*P2_I2CRPT*/
151#define R0900_P2_I2CRPT 0xf12b
152#define F0900_P2_I2CT_ON 0xf12b0080
153#define F0900_P2_ENARPT_LEVEL 0xf12b0070
154#define F0900_P2_SCLT_DELAY 0xf12b0008
155#define F0900_P2_STOP_ENABLE 0xf12b0004
156#define F0900_P2_STOP_SDAT2SDA 0xf12b0002
157
158/*IOPVALUE6*/
159#define R0900_IOPVALUE6 0xf138
160#define F0900_VSCL 0xf1380004
161#define F0900_VSDA 0xf1380002
162#define F0900_VDATA3_0 0xf1380001
163
164/*IOPVALUE5*/
165#define R0900_IOPVALUE5 0xf139
166#define F0900_VDATA3_1 0xf1390080
167#define F0900_VDATA3_2 0xf1390040
168#define F0900_VDATA3_3 0xf1390020
169#define F0900_VDATA3_4 0xf1390010
170#define F0900_VDATA3_5 0xf1390008
171#define F0900_VDATA3_6 0xf1390004
172#define F0900_VDATA3_7 0xf1390002
173#define F0900_VCLKOUT3 0xf1390001
174
175/*IOPVALUE4*/
176#define R0900_IOPVALUE4 0xf13a
177#define F0900_VSTROUT3 0xf13a0080
178#define F0900_VDPN3 0xf13a0040
179#define F0900_VERROR3 0xf13a0020
180#define F0900_VDATA2_7 0xf13a0010
181#define F0900_VCLKOUT2 0xf13a0008
182#define F0900_VSTROUT2 0xf13a0004
183#define F0900_VDPN2 0xf13a0002
184#define F0900_VERROR2 0xf13a0001
185
186/*IOPVALUE3*/
187#define R0900_IOPVALUE3 0xf13b
188#define F0900_VDATA1_7 0xf13b0080
189#define F0900_VCLKOUT1 0xf13b0040
190#define F0900_VSTROUT1 0xf13b0020
191#define F0900_VDPN1 0xf13b0010
192#define F0900_VERROR1 0xf13b0008
193#define F0900_VCLKOUT27 0xf13b0004
194#define F0900_VDISEQCOUT2 0xf13b0002
195#define F0900_VSCLT2 0xf13b0001
196
197/*IOPVALUE2*/
198#define R0900_IOPVALUE2 0xf13c
199#define F0900_VSDAT2 0xf13c0080
200#define F0900_VAGCRF2 0xf13c0040
201#define F0900_VDISEQCOUT1 0xf13c0020
202#define F0900_VSCLT1 0xf13c0010
203#define F0900_VSDAT1 0xf13c0008
204#define F0900_VAGCRF1 0xf13c0004
205#define F0900_VDIRCLK 0xf13c0002
206#define F0900_VSTDBY 0xf13c0001
207
208/*IOPVALUE1*/
209#define R0900_IOPVALUE1 0xf13d
210#define F0900_VCS1 0xf13d0080
211#define F0900_VCS0 0xf13d0040
212#define F0900_VGPIO13 0xf13d0020
213#define F0900_VGPIO12 0xf13d0010
214#define F0900_VGPIO11 0xf13d0008
215#define F0900_VGPIO10 0xf13d0004
216#define F0900_VGPIO9 0xf13d0002
217#define F0900_VGPIO8 0xf13d0001
218
219/*IOPVALUE0*/
220#define R0900_IOPVALUE0 0xf13e
221#define F0900_VGPIO7 0xf13e0080
222#define F0900_VGPIO6 0xf13e0040
223#define F0900_VGPIO5 0xf13e0020
224#define F0900_VGPIO4 0xf13e0010
225#define F0900_VGPIO3 0xf13e0008
226#define F0900_VGPIO2 0xf13e0004
227#define F0900_VGPIO1 0xf13e0002
228#define F0900_VCLKI2 0xf13e0001
229
230/*CLKI2CFG*/
231#define R0900_CLKI2CFG 0xf140
232#define F0900_CLKI2_OPD 0xf1400080
233#define F0900_CLKI2_CONFIG 0xf140007e
234#define F0900_CLKI2_XOR 0xf1400001
235
236/*GPIO1CFG*/
237#define R0900_GPIO1CFG 0xf141
238#define F0900_GPIO1_OPD 0xf1410080
239#define F0900_GPIO1_CONFIG 0xf141007e
240#define F0900_GPIO1_XOR 0xf1410001
241
242/*GPIO2CFG*/
243#define R0900_GPIO2CFG 0xf142
244#define F0900_GPIO2_OPD 0xf1420080
245#define F0900_GPIO2_CONFIG 0xf142007e
246#define F0900_GPIO2_XOR 0xf1420001
247
248/*GPIO3CFG*/
249#define R0900_GPIO3CFG 0xf143
250#define F0900_GPIO3_OPD 0xf1430080
251#define F0900_GPIO3_CONFIG 0xf143007e
252#define F0900_GPIO3_XOR 0xf1430001
253
254/*GPIO4CFG*/
255#define R0900_GPIO4CFG 0xf144
256#define F0900_GPIO4_OPD 0xf1440080
257#define F0900_GPIO4_CONFIG 0xf144007e
258#define F0900_GPIO4_XOR 0xf1440001
259
260/*GPIO5CFG*/
261#define R0900_GPIO5CFG 0xf145
262#define F0900_GPIO5_OPD 0xf1450080
263#define F0900_GPIO5_CONFIG 0xf145007e
264#define F0900_GPIO5_XOR 0xf1450001
265
266/*GPIO6CFG*/
267#define R0900_GPIO6CFG 0xf146
268#define F0900_GPIO6_OPD 0xf1460080
269#define F0900_GPIO6_CONFIG 0xf146007e
270#define F0900_GPIO6_XOR 0xf1460001
271
272/*GPIO7CFG*/
273#define R0900_GPIO7CFG 0xf147
274#define F0900_GPIO7_OPD 0xf1470080
275#define F0900_GPIO7_CONFIG 0xf147007e
276#define F0900_GPIO7_XOR 0xf1470001
277
278/*GPIO8CFG*/
279#define R0900_GPIO8CFG 0xf148
280#define F0900_GPIO8_OPD 0xf1480080
281#define F0900_GPIO8_CONFIG 0xf148007e
282#define F0900_GPIO8_XOR 0xf1480001
283
284/*GPIO9CFG*/
285#define R0900_GPIO9CFG 0xf149
286#define F0900_GPIO9_OPD 0xf1490080
287#define F0900_GPIO9_CONFIG 0xf149007e
288#define F0900_GPIO9_XOR 0xf1490001
289
290/*GPIO10CFG*/
291#define R0900_GPIO10CFG 0xf14a
292#define F0900_GPIO10_OPD 0xf14a0080
293#define F0900_GPIO10_CONFIG 0xf14a007e
294#define F0900_GPIO10_XOR 0xf14a0001
295
296/*GPIO11CFG*/
297#define R0900_GPIO11CFG 0xf14b
298#define F0900_GPIO11_OPD 0xf14b0080
299#define F0900_GPIO11_CONFIG 0xf14b007e
300#define F0900_GPIO11_XOR 0xf14b0001
301
302/*GPIO12CFG*/
303#define R0900_GPIO12CFG 0xf14c
304#define F0900_GPIO12_OPD 0xf14c0080
305#define F0900_GPIO12_CONFIG 0xf14c007e
306#define F0900_GPIO12_XOR 0xf14c0001
307
308/*GPIO13CFG*/
309#define R0900_GPIO13CFG 0xf14d
310#define F0900_GPIO13_OPD 0xf14d0080
311#define F0900_GPIO13_CONFIG 0xf14d007e
312#define F0900_GPIO13_XOR 0xf14d0001
313
314/*CS0CFG*/
315#define R0900_CS0CFG 0xf14e
316#define F0900_CS0_OPD 0xf14e0080
317#define F0900_CS0_CONFIG 0xf14e007e
318#define F0900_CS0_XOR 0xf14e0001
319
320/*CS1CFG*/
321#define R0900_CS1CFG 0xf14f
322#define F0900_CS1_OPD 0xf14f0080
323#define F0900_CS1_CONFIG 0xf14f007e
324#define F0900_CS1_XOR 0xf14f0001
325
326/*STDBYCFG*/
327#define R0900_STDBYCFG 0xf150
328#define F0900_STDBY_OPD 0xf1500080
329#define F0900_STDBY_CONFIG 0xf150007e
330#define F0900_STBDY_XOR 0xf1500001
331
332/*DIRCLKCFG*/
333#define R0900_DIRCLKCFG 0xf151
334#define F0900_DIRCLK_OPD 0xf1510080
335#define F0900_DIRCLK_CONFIG 0xf151007e
336#define F0900_DIRCLK_XOR 0xf1510001
337
338/*AGCRF1CFG*/
339#define R0900_AGCRF1CFG 0xf152
340#define F0900_AGCRF1_OPD 0xf1520080
341#define F0900_AGCRF1_CONFIG 0xf152007e
342#define F0900_AGCRF1_XOR 0xf1520001
343
344/*SDAT1CFG*/
345#define R0900_SDAT1CFG 0xf153
346#define F0900_SDAT1_OPD 0xf1530080
347#define F0900_SDAT1_CONFIG 0xf153007e
348#define F0900_SDAT1_XOR 0xf1530001
349
350/*SCLT1CFG*/
351#define R0900_SCLT1CFG 0xf154
352#define F0900_SCLT1_OPD 0xf1540080
353#define F0900_SCLT1_CONFIG 0xf154007e
354#define F0900_SCLT1_XOR 0xf1540001
355
356/*DISEQCO1CFG*/
357#define R0900_DISEQCO1CFG 0xf155
358#define F0900_DISEQCO1_OPD 0xf1550080
359#define F0900_DISEQCO1_CONFIG 0xf155007e
360#define F0900_DISEQC1_XOR 0xf1550001
361
362/*AGCRF2CFG*/
363#define R0900_AGCRF2CFG 0xf156
364#define F0900_AGCRF2_OPD 0xf1560080
365#define F0900_AGCRF2_CONFIG 0xf156007e
366#define F0900_AGCRF2_XOR 0xf1560001
367
368/*SDAT2CFG*/
369#define R0900_SDAT2CFG 0xf157
370#define F0900_SDAT2_OPD 0xf1570080
371#define F0900_SDAT2_CONFIG 0xf157007e
372#define F0900_SDAT2_XOR 0xf1570001
373
374/*SCLT2CFG*/
375#define R0900_SCLT2CFG 0xf158
376#define F0900_SCLT2_OPD 0xf1580080
377#define F0900_SCLT2_CONFIG 0xf158007e
378#define F0900_SCLT2_XOR 0xf1580001
379
380/*DISEQCO2CFG*/
381#define R0900_DISEQCO2CFG 0xf159
382#define F0900_DISEQCO2_OPD 0xf1590080
383#define F0900_DISEQCO2_CONFIG 0xf159007e
384#define F0900_DISEQC2_XOR 0xf1590001
385
386/*CLKOUT27CFG*/
387#define R0900_CLKOUT27CFG 0xf15a
388#define F0900_CLKOUT27_OPD 0xf15a0080
389#define F0900_CLKOUT27_CONFIG 0xf15a007e
390#define F0900_CLKOUT27_XOR 0xf15a0001
391
392/*ERROR1CFG*/
393#define R0900_ERROR1CFG 0xf15b
394#define F0900_ERROR1_OPD 0xf15b0080
395#define F0900_ERROR1_CONFIG 0xf15b007e
396#define F0900_ERROR1_XOR 0xf15b0001
397
398/*DPN1CFG*/
399#define R0900_DPN1CFG 0xf15c
400#define F0900_DPN1_OPD 0xf15c0080
401#define F0900_DPN1_CONFIG 0xf15c007e
402#define F0900_DPN1_XOR 0xf15c0001
403
404/*STROUT1CFG*/
405#define R0900_STROUT1CFG 0xf15d
406#define F0900_STROUT1_OPD 0xf15d0080
407#define F0900_STROUT1_CONFIG 0xf15d007e
408#define F0900_STROUT1_XOR 0xf15d0001
409
410/*CLKOUT1CFG*/
411#define R0900_CLKOUT1CFG 0xf15e
412#define F0900_CLKOUT1_OPD 0xf15e0080
413#define F0900_CLKOUT1_CONFIG 0xf15e007e
414#define F0900_CLKOUT1_XOR 0xf15e0001
415
416/*DATA71CFG*/
417#define R0900_DATA71CFG 0xf15f
418#define F0900_DATA71_OPD 0xf15f0080
419#define F0900_DATA71_CONFIG 0xf15f007e
420#define F0900_DATA71_XOR 0xf15f0001
421
422/*ERROR2CFG*/
423#define R0900_ERROR2CFG 0xf160
424#define F0900_ERROR2_OPD 0xf1600080
425#define F0900_ERROR2_CONFIG 0xf160007e
426#define F0900_ERROR2_XOR 0xf1600001
427
428/*DPN2CFG*/
429#define R0900_DPN2CFG 0xf161
430#define F0900_DPN2_OPD 0xf1610080
431#define F0900_DPN2_CONFIG 0xf161007e
432#define F0900_DPN2_XOR 0xf1610001
433
434/*STROUT2CFG*/
435#define R0900_STROUT2CFG 0xf162
436#define F0900_STROUT2_OPD 0xf1620080
437#define F0900_STROUT2_CONFIG 0xf162007e
438#define F0900_STROUT2_XOR 0xf1620001
439
440/*CLKOUT2CFG*/
441#define R0900_CLKOUT2CFG 0xf163
442#define F0900_CLKOUT2_OPD 0xf1630080
443#define F0900_CLKOUT2_CONFIG 0xf163007e
444#define F0900_CLKOUT2_XOR 0xf1630001
445
446/*DATA72CFG*/
447#define R0900_DATA72CFG 0xf164
448#define F0900_DATA72_OPD 0xf1640080
449#define F0900_DATA72_CONFIG 0xf164007e
450#define F0900_DATA72_XOR 0xf1640001
451
452/*ERROR3CFG*/
453#define R0900_ERROR3CFG 0xf165
454#define F0900_ERROR3_OPD 0xf1650080
455#define F0900_ERROR3_CONFIG 0xf165007e
456#define F0900_ERROR3_XOR 0xf1650001
457
458/*DPN3CFG*/
459#define R0900_DPN3CFG 0xf166
460#define F0900_DPN3_OPD 0xf1660080
461#define F0900_DPN3_CONFIG 0xf166007e
462#define F0900_DPN3_XOR 0xf1660001
463
464/*STROUT3CFG*/
465#define R0900_STROUT3CFG 0xf167
466#define F0900_STROUT3_OPD 0xf1670080
467#define F0900_STROUT3_CONFIG 0xf167007e
468#define F0900_STROUT3_XOR 0xf1670001
469
470/*CLKOUT3CFG*/
471#define R0900_CLKOUT3CFG 0xf168
472#define F0900_CLKOUT3_OPD 0xf1680080
473#define F0900_CLKOUT3_CONFIG 0xf168007e
474#define F0900_CLKOUT3_XOR 0xf1680001
475
476/*DATA73CFG*/
477#define R0900_DATA73CFG 0xf169
478#define F0900_DATA73_OPD 0xf1690080
479#define F0900_DATA73_CONFIG 0xf169007e
480#define F0900_DATA73_XOR 0xf1690001
481
482/*STRSTATUS1*/
483#define R0900_STRSTATUS1 0xf16a
484#define F0900_STRSTATUS_SEL2 0xf16a00f0
485#define F0900_STRSTATUS_SEL1 0xf16a000f
486
487/*STRSTATUS2*/
488#define R0900_STRSTATUS2 0xf16b
489#define F0900_STRSTATUS_SEL4 0xf16b00f0
490#define F0900_STRSTATUS_SEL3 0xf16b000f
491
492/*STRSTATUS3*/
493#define R0900_STRSTATUS3 0xf16c
494#define F0900_STRSTATUS_SEL6 0xf16c00f0
495#define F0900_STRSTATUS_SEL5 0xf16c000f
496
497/*FSKTFC2*/
498#define R0900_FSKTFC2 0xf170
499#define F0900_FSKT_KMOD 0xf17000fc
500#define F0900_FSKT_CAR2 0xf1700003
501
502/*FSKTFC1*/
503#define R0900_FSKTFC1 0xf171
504#define F0900_FSKT_CAR1 0xf17100ff
505
506/*FSKTFC0*/
507#define R0900_FSKTFC0 0xf172
508#define F0900_FSKT_CAR0 0xf17200ff
509
510/*FSKTDELTAF1*/
511#define R0900_FSKTDELTAF1 0xf173
512#define F0900_FSKT_DELTAF1 0xf173000f
513
514/*FSKTDELTAF0*/
515#define R0900_FSKTDELTAF0 0xf174
516#define F0900_FSKT_DELTAF0 0xf17400ff
517
518/*FSKTCTRL*/
519#define R0900_FSKTCTRL 0xf175
520#define F0900_FSKT_EN_SGN 0xf1750040
521#define F0900_FSKT_MOD_SGN 0xf1750020
522#define F0900_FSKT_MOD_EN 0xf175001c
523#define F0900_FSKT_DACMODE 0xf1750003
524
525/*FSKRFC2*/
526#define R0900_FSKRFC2 0xf176
527#define F0900_FSKR_DETSGN 0xf1760040
528#define F0900_FSKR_OUTSGN 0xf1760020
529#define F0900_FSKR_KAGC 0xf176001c
530#define F0900_FSKR_CAR2 0xf1760003
531
532/*FSKRFC1*/
533#define R0900_FSKRFC1 0xf177
534#define F0900_FSKR_CAR1 0xf17700ff
535
536/*FSKRFC0*/
537#define R0900_FSKRFC0 0xf178
538#define F0900_FSKR_CAR0 0xf17800ff
539
540/*FSKRK1*/
541#define R0900_FSKRK1 0xf179
542#define F0900_FSKR_K1_EXP 0xf17900e0
543#define F0900_FSKR_K1_MANT 0xf179001f
544
545/*FSKRK2*/
546#define R0900_FSKRK2 0xf17a
547#define F0900_FSKR_K2_EXP 0xf17a00e0
548#define F0900_FSKR_K2_MANT 0xf17a001f
549
550/*FSKRAGCR*/
551#define R0900_FSKRAGCR 0xf17b
552#define F0900_FSKR_OUTCTL 0xf17b00c0
553#define F0900_FSKR_AGC_REF 0xf17b003f
554
555/*FSKRAGC*/
556#define R0900_FSKRAGC 0xf17c
557#define F0900_FSKR_AGC_ACCU 0xf17c00ff
558
559/*FSKRALPHA*/
560#define R0900_FSKRALPHA 0xf17d
561#define F0900_FSKR_ALPHA_EXP 0xf17d001c
562#define F0900_FSKR_ALPHA_M 0xf17d0003
563
564/*FSKRPLTH1*/
565#define R0900_FSKRPLTH1 0xf17e
566#define F0900_FSKR_BETA 0xf17e00f0
567#define F0900_FSKR_PLL_TRESH1 0xf17e000f
568
569/*FSKRPLTH0*/
570#define R0900_FSKRPLTH0 0xf17f
571#define F0900_FSKR_PLL_TRESH0 0xf17f00ff
572
573/*FSKRDF1*/
574#define R0900_FSKRDF1 0xf180
575#define F0900_FSKR_OUT 0xf1800080
576#define F0900_FSKR_DELTAF1 0xf180001f
577
578/*FSKRDF0*/
579#define R0900_FSKRDF0 0xf181
580#define F0900_FSKR_DELTAF0 0xf18100ff
581
582/*FSKRSTEPP*/
583#define R0900_FSKRSTEPP 0xf182
584#define F0900_FSKR_STEP_PLUS 0xf18200ff
585
586/*FSKRSTEPM*/
587#define R0900_FSKRSTEPM 0xf183
588#define F0900_FSKR_STEP_MINUS 0xf18300ff
589
590/*FSKRDET1*/
591#define R0900_FSKRDET1 0xf184
592#define F0900_FSKR_DETECT 0xf1840080
593#define F0900_FSKR_CARDET_ACCU1 0xf184000f
594
595/*FSKRDET0*/
596#define R0900_FSKRDET0 0xf185
597#define F0900_FSKR_CARDET_ACCU0 0xf18500ff
598
599/*FSKRDTH1*/
600#define R0900_FSKRDTH1 0xf186
601#define F0900_FSKR_CARLOSS_THRESH1 0xf18600f0
602#define F0900_FSKR_CARDET_THRESH1 0xf186000f
603
604/*FSKRDTH0*/
605#define R0900_FSKRDTH0 0xf187
606#define F0900_FSKR_CARDET_THRESH0 0xf18700ff
607
608/*FSKRLOSS*/
609#define R0900_FSKRLOSS 0xf188
610#define F0900_FSKR_CARLOSS_THRESH0 0xf18800ff
611
612/*P2_DISTXCTL*/
613#define R0900_P2_DISTXCTL 0xf190
614#define F0900_P2_TIM_OFF 0xf1900080
615#define F0900_P2_DISEQC_RESET 0xf1900040
616#define F0900_P2_TIM_CMD 0xf1900030
617#define F0900_P2_DIS_PRECHARGE 0xf1900008
618#define F0900_P2_DISTX_MODE 0xf1900007
619
620/*P2_DISRXCTL*/
621#define R0900_P2_DISRXCTL 0xf191
622#define F0900_P2_RECEIVER_ON 0xf1910080
623#define F0900_P2_IGNO_SHORT22K 0xf1910040
624#define F0900_P2_ONECHIP_TRX 0xf1910020
625#define F0900_P2_EXT_ENVELOP 0xf1910010
626#define F0900_P2_PIN_SELECT0 0xf191000c
627#define F0900_P2_IRQ_RXEND 0xf1910002
628#define F0900_P2_IRQ_4NBYTES 0xf1910001
629
630/*P2_DISRX_ST0*/
631#define R0900_P2_DISRX_ST0 0xf194
632#define F0900_P2_RX_END 0xf1940080
633#define F0900_P2_RX_ACTIVE 0xf1940040
634#define F0900_P2_SHORT_22KHZ 0xf1940020
635#define F0900_P2_CONT_TONE 0xf1940010
636#define F0900_P2_FIFO_4BREADY 0xf1940008
637#define F0900_P2_FIFO_EMPTY 0xf1940004
638#define F0900_P2_ABORT_DISRX 0xf1940001
639
640/*P2_DISRX_ST1*/
641#define R0900_P2_DISRX_ST1 0xf195
642#define F0900_P2_RX_FAIL 0xf1950080
643#define F0900_P2_FIFO_PARITYFAIL 0xf1950040
644#define F0900_P2_RX_NONBYTE 0xf1950020
645#define F0900_P2_FIFO_OVERFLOW 0xf1950010
646#define F0900_P2_FIFO_BYTENBR 0xf195000f
647
648/*P2_DISRXDATA*/
649#define R0900_P2_DISRXDATA 0xf196
650#define F0900_P2_DISRX_DATA 0xf19600ff
651
652/*P2_DISTXDATA*/
653#define R0900_P2_DISTXDATA 0xf197
654#define F0900_P2_DISEQC_FIFO 0xf19700ff
655
656/*P2_DISTXSTATUS*/
657#define R0900_P2_DISTXSTATUS 0xf198
658#define F0900_P2_TX_FAIL 0xf1980080
659#define F0900_P2_FIFO_FULL 0xf1980040
660#define F0900_P2_TX_IDLE 0xf1980020
661#define F0900_P2_GAP_BURST 0xf1980010
662#define F0900_P2_TXFIFO_BYTES 0xf198000f
663
664/*P2_F22TX*/
665#define R0900_P2_F22TX 0xf199
666#define F0900_P2_F22_REG 0xf19900ff
667
668/*P2_F22RX*/
669#define R0900_P2_F22RX 0xf19a
670#define F0900_P2_F22RX_REG 0xf19a00ff
671
672/*P2_ACRPRESC*/
673#define R0900_P2_ACRPRESC 0xf19c
674#define F0900_P2_ACR_PRESC 0xf19c0007
675
676/*P2_ACRDIV*/
677#define R0900_P2_ACRDIV 0xf19d
678#define F0900_P2_ACR_DIV 0xf19d00ff
679
680/*P1_DISTXCTL*/
681#define R0900_P1_DISTXCTL 0xf1a0
682#define DISTXCTL shiftx(R0900_P1_DISTXCTL, demod, 0x10)
683#define F0900_P1_TIM_OFF 0xf1a00080
684#define F0900_P1_DISEQC_RESET 0xf1a00040
685#define DISEQC_RESET shiftx(F0900_P1_DISEQC_RESET, demod, 0x100000)
686#define F0900_P1_TIM_CMD 0xf1a00030
687#define F0900_P1_DIS_PRECHARGE 0xf1a00008
688#define DIS_PRECHARGE shiftx(F0900_P1_DIS_PRECHARGE, demod, 0x100000)
689#define F0900_P1_DISTX_MODE 0xf1a00007
690#define DISTX_MODE shiftx(F0900_P1_DISTX_MODE, demod, 0x100000)
691
692/*P1_DISRXCTL*/
693#define R0900_P1_DISRXCTL 0xf1a1
694#define DISRXCTL shiftx(R0900_P1_DISRXCTL, demod, 0x10)
695#define F0900_P1_RECEIVER_ON 0xf1a10080
696#define F0900_P1_IGNO_SHORT22K 0xf1a10040
697#define F0900_P1_ONECHIP_TRX 0xf1a10020
698#define F0900_P1_EXT_ENVELOP 0xf1a10010
699#define F0900_P1_PIN_SELECT0 0xf1a1000c
700#define F0900_P1_IRQ_RXEND 0xf1a10002
701#define F0900_P1_IRQ_4NBYTES 0xf1a10001
702
703/*P1_DISRX_ST0*/
704#define R0900_P1_DISRX_ST0 0xf1a4
705#define DISRX_ST0 shiftx(R0900_P1_DISRX_ST0, demod, 0x10)
706#define F0900_P1_RX_END 0xf1a40080
707#define RX_END shiftx(F0900_P1_RX_END, demod, 0x100000)
708#define F0900_P1_RX_ACTIVE 0xf1a40040
709#define F0900_P1_SHORT_22KHZ 0xf1a40020
710#define F0900_P1_CONT_TONE 0xf1a40010
711#define F0900_P1_FIFO_4BREADY 0xf1a40008
712#define F0900_P1_FIFO_EMPTY 0xf1a40004
713#define F0900_P1_ABORT_DISRX 0xf1a40001
714
715/*P1_DISRX_ST1*/
716#define R0900_P1_DISRX_ST1 0xf1a5
717#define DISRX_ST1 shiftx(R0900_P1_DISRX_ST1, demod, 0x10)
718#define F0900_P1_RX_FAIL 0xf1a50080
719#define F0900_P1_FIFO_PARITYFAIL 0xf1a50040
720#define F0900_P1_RX_NONBYTE 0xf1a50020
721#define F0900_P1_FIFO_OVERFLOW 0xf1a50010
722#define F0900_P1_FIFO_BYTENBR 0xf1a5000f
723#define FIFO_BYTENBR shiftx(F0900_P1_FIFO_BYTENBR, demod, 0x100000)
724
725/*P1_DISRXDATA*/
726#define R0900_P1_DISRXDATA 0xf1a6
727#define DISRXDATA shiftx(R0900_P1_DISRXDATA, demod, 0x10)
728#define F0900_P1_DISRX_DATA 0xf1a600ff
729
730/*P1_DISTXDATA*/
731#define R0900_P1_DISTXDATA 0xf1a7
732#define DISTXDATA shiftx(R0900_P1_DISTXDATA, demod, 0x10)
733#define F0900_P1_DISEQC_FIFO 0xf1a700ff
734
735/*P1_DISTXSTATUS*/
736#define R0900_P1_DISTXSTATUS 0xf1a8
737#define F0900_P1_TX_FAIL 0xf1a80080
738#define F0900_P1_FIFO_FULL 0xf1a80040
739#define FIFO_FULL shiftx(F0900_P1_FIFO_FULL, demod, 0x100000)
740#define F0900_P1_TX_IDLE 0xf1a80020
741#define TX_IDLE shiftx(F0900_P1_TX_IDLE, demod, 0x100000)
742#define F0900_P1_GAP_BURST 0xf1a80010
743#define F0900_P1_TXFIFO_BYTES 0xf1a8000f
744
745/*P1_F22TX*/
746#define R0900_P1_F22TX 0xf1a9
747#define F22TX shiftx(R0900_P1_F22TX, demod, 0x10)
748#define F0900_P1_F22_REG 0xf1a900ff
749
750/*P1_F22RX*/
751#define R0900_P1_F22RX 0xf1aa
752#define F22RX shiftx(R0900_P1_F22RX, demod, 0x10)
753#define F0900_P1_F22RX_REG 0xf1aa00ff
754
755/*P1_ACRPRESC*/
756#define R0900_P1_ACRPRESC 0xf1ac
757#define ACRPRESC shiftx(R0900_P1_ACRPRESC, demod, 0x10)
758#define F0900_P1_ACR_PRESC 0xf1ac0007
759
760/*P1_ACRDIV*/
761#define R0900_P1_ACRDIV 0xf1ad
762#define ACRDIV shiftx(R0900_P1_ACRDIV, demod, 0x10)
763#define F0900_P1_ACR_DIV 0xf1ad00ff
764
765/*NCOARSE*/
766#define R0900_NCOARSE 0xf1b3
767#define F0900_M_DIV 0xf1b300ff
768
769/*SYNTCTRL*/
770#define R0900_SYNTCTRL 0xf1b6
771#define F0900_STANDBY 0xf1b60080
772#define F0900_BYPASSPLLCORE 0xf1b60040
773#define F0900_SELX1RATIO 0xf1b60020
774#define F0900_STOP_PLL 0xf1b60008
775#define F0900_BYPASSPLLFSK 0xf1b60004
776#define F0900_SELOSCI 0xf1b60002
777#define F0900_BYPASSPLLADC 0xf1b60001
778
779/*FILTCTRL*/
780#define R0900_FILTCTRL 0xf1b7
781#define F0900_INV_CLK135 0xf1b70080
782#define F0900_SEL_FSKCKDIV 0xf1b70004
783#define F0900_INV_CLKFSK 0xf1b70002
784#define F0900_BYPASS_APPLI 0xf1b70001
785
786/*PLLSTAT*/
787#define R0900_PLLSTAT 0xf1b8
788#define F0900_PLLLOCK 0xf1b80001
789
790/*STOPCLK1*/
791#define R0900_STOPCLK1 0xf1c2
792#define F0900_STOP_CLKPKDT2 0xf1c20040
793#define F0900_STOP_CLKPKDT1 0xf1c20020
794#define F0900_STOP_CLKFEC 0xf1c20010
795#define F0900_STOP_CLKADCI2 0xf1c20008
796#define F0900_INV_CLKADCI2 0xf1c20004
797#define F0900_STOP_CLKADCI1 0xf1c20002
798#define F0900_INV_CLKADCI1 0xf1c20001
799
800/*STOPCLK2*/
801#define R0900_STOPCLK2 0xf1c3
802#define F0900_STOP_CLKSAMP2 0xf1c30010
803#define F0900_STOP_CLKSAMP1 0xf1c30008
804#define F0900_STOP_CLKVIT2 0xf1c30004
805#define F0900_STOP_CLKVIT1 0xf1c30002
806#define STOP_CLKVIT shiftx(F0900_STOP_CLKVIT1, demod, -2)
807#define F0900_STOP_CLKTS 0xf1c30001
808
809/*TSTTNR0*/
810#define R0900_TSTTNR0 0xf1df
811#define F0900_SEL_FSK 0xf1df0080
812#define F0900_FSK_PON 0xf1df0004
813
814/*TSTTNR1*/
815#define R0900_TSTTNR1 0xf1e0
816#define F0900_ADC1_PON 0xf1e00002
817#define F0900_ADC1_INMODE 0xf1e00001
818
819/*TSTTNR2*/
820#define R0900_TSTTNR2 0xf1e1
821#define F0900_DISEQC1_PON 0xf1e10020
822
823/*TSTTNR3*/
824#define R0900_TSTTNR3 0xf1e2
825#define F0900_ADC2_PON 0xf1e20002
826#define F0900_ADC2_INMODE 0xf1e20001
827
828/*TSTTNR4*/
829#define R0900_TSTTNR4 0xf1e3
830#define F0900_DISEQC2_PON 0xf1e30020
831
832/*P2_IQCONST*/
833#define R0900_P2_IQCONST 0xf200
834#define F0900_P2_CONSTEL_SELECT 0xf2000060
835#define F0900_P2_IQSYMB_SEL 0xf200001f
836
837/*P2_NOSCFG*/
838#define R0900_P2_NOSCFG 0xf201
839#define F0900_P2_DUMMYPL_NOSDATA 0xf2010020
840#define F0900_P2_NOSPLH_BETA 0xf2010018
841#define F0900_P2_NOSDATA_BETA 0xf2010007
842
843/*P2_ISYMB*/
844#define R0900_P2_ISYMB 0xf202
845#define F0900_P2_I_SYMBOL 0xf20201ff
846
847/*P2_QSYMB*/
848#define R0900_P2_QSYMB 0xf203
849#define F0900_P2_Q_SYMBOL 0xf20301ff
850
851/*P2_AGC1CFG*/
852#define R0900_P2_AGC1CFG 0xf204
853#define F0900_P2_DC_FROZEN 0xf2040080
854#define F0900_P2_DC_CORRECT 0xf2040040
855#define F0900_P2_AMM_FROZEN 0xf2040020
856#define F0900_P2_AMM_CORRECT 0xf2040010
857#define F0900_P2_QUAD_FROZEN 0xf2040008
858#define F0900_P2_QUAD_CORRECT 0xf2040004
859
860/*P2_AGC1CN*/
861#define R0900_P2_AGC1CN 0xf206
862#define F0900_P2_AGC1_LOCKED 0xf2060080
863#define F0900_P2_AGC1_MINPOWER 0xf2060010
864#define F0900_P2_AGCOUT_FAST 0xf2060008
865#define F0900_P2_AGCIQ_BETA 0xf2060007
866
867/*P2_AGC1REF*/
868#define R0900_P2_AGC1REF 0xf207
869#define F0900_P2_AGCIQ_REF 0xf20700ff
870
871/*P2_IDCCOMP*/
872#define R0900_P2_IDCCOMP 0xf208
873#define F0900_P2_IAVERAGE_ADJ 0xf20801ff
874
875/*P2_QDCCOMP*/
876#define R0900_P2_QDCCOMP 0xf209
877#define F0900_P2_QAVERAGE_ADJ 0xf20901ff
878
879/*P2_POWERI*/
880#define R0900_P2_POWERI 0xf20a
881#define F0900_P2_POWER_I 0xf20a00ff
882
883/*P2_POWERQ*/
884#define R0900_P2_POWERQ 0xf20b
885#define F0900_P2_POWER_Q 0xf20b00ff
886
887/*P2_AGC1AMM*/
888#define R0900_P2_AGC1AMM 0xf20c
889#define F0900_P2_AMM_VALUE 0xf20c00ff
890
891/*P2_AGC1QUAD*/
892#define R0900_P2_AGC1QUAD 0xf20d
893#define F0900_P2_QUAD_VALUE 0xf20d01ff
894
895/*P2_AGCIQIN1*/
896#define R0900_P2_AGCIQIN1 0xf20e
897#define F0900_P2_AGCIQ_VALUE1 0xf20e00ff
898
899/*P2_AGCIQIN0*/
900#define R0900_P2_AGCIQIN0 0xf20f
901#define F0900_P2_AGCIQ_VALUE0 0xf20f00ff
902
903/*P2_DEMOD*/
904#define R0900_P2_DEMOD 0xf210
905#define F0900_P2_MANUALS2_ROLLOFF 0xf2100080
906#define F0900_P2_SPECINV_CONTROL 0xf2100030
907#define F0900_P2_FORCE_ENASAMP 0xf2100008
908#define F0900_P2_MANUALSX_ROLLOFF 0xf2100004
909#define F0900_P2_ROLLOFF_CONTROL 0xf2100003
910
911/*P2_DMDMODCOD*/
912#define R0900_P2_DMDMODCOD 0xf211
913#define F0900_P2_MANUAL_MODCOD 0xf2110080
914#define F0900_P2_DEMOD_MODCOD 0xf211007c
915#define F0900_P2_DEMOD_TYPE 0xf2110003
916
917/*P2_DSTATUS*/
918#define R0900_P2_DSTATUS 0xf212
919#define F0900_P2_CAR_LOCK 0xf2120080
920#define F0900_P2_TMGLOCK_QUALITY 0xf2120060
921#define F0900_P2_LOCK_DEFINITIF 0xf2120008
922#define F0900_P2_OVADC_DETECT 0xf2120001
923
924/*P2_DSTATUS2*/
925#define R0900_P2_DSTATUS2 0xf213
926#define F0900_P2_DEMOD_DELOCK 0xf2130080
927#define F0900_P2_AGC1_NOSIGNALACK 0xf2130008
928#define F0900_P2_AGC2_OVERFLOW 0xf2130004
929#define F0900_P2_CFR_OVERFLOW 0xf2130002
930#define F0900_P2_GAMMA_OVERUNDER 0xf2130001
931
932/*P2_DMDCFGMD*/
933#define R0900_P2_DMDCFGMD 0xf214
934#define F0900_P2_DVBS2_ENABLE 0xf2140080
935#define F0900_P2_DVBS1_ENABLE 0xf2140040
936#define F0900_P2_SCAN_ENABLE 0xf2140010
937#define F0900_P2_CFR_AUTOSCAN 0xf2140008
938#define F0900_P2_TUN_RNG 0xf2140003
939
940/*P2_DMDCFG2*/
941#define R0900_P2_DMDCFG2 0xf215
942#define F0900_P2_S1S2_SEQUENTIAL 0xf2150040
943#define F0900_P2_INFINITE_RELOCK 0xf2150010
944
945/*P2_DMDISTATE*/
946#define R0900_P2_DMDISTATE 0xf216
947#define F0900_P2_I2C_DEMOD_MODE 0xf216001f
948
949/*P2_DMDT0M*/
950#define R0900_P2_DMDT0M 0xf217
951#define F0900_P2_DMDT0_MIN 0xf21700ff
952
953/*P2_DMDSTATE*/
954#define R0900_P2_DMDSTATE 0xf21b
955#define F0900_P2_HEADER_MODE 0xf21b0060
956
957/*P2_DMDFLYW*/
958#define R0900_P2_DMDFLYW 0xf21c
959#define F0900_P2_I2C_IRQVAL 0xf21c00f0
960#define F0900_P2_FLYWHEEL_CPT 0xf21c000f
961
962/*P2_DSTATUS3*/
963#define R0900_P2_DSTATUS3 0xf21d
964#define F0900_P2_DEMOD_CFGMODE 0xf21d0060
965
966/*P2_DMDCFG3*/
967#define R0900_P2_DMDCFG3 0xf21e
968#define F0900_P2_NOSTOP_FIFOFULL 0xf21e0008
969
970/*P2_DMDCFG4*/
971#define R0900_P2_DMDCFG4 0xf21f
972#define F0900_P2_TUNER_NRELAUNCH 0xf21f0008
973
974/*P2_CORRELMANT*/
975#define R0900_P2_CORRELMANT 0xf220
976#define F0900_P2_CORREL_MANT 0xf22000ff
977
978/*P2_CORRELABS*/
979#define R0900_P2_CORRELABS 0xf221
980#define F0900_P2_CORREL_ABS 0xf22100ff
981
982/*P2_CORRELEXP*/
983#define R0900_P2_CORRELEXP 0xf222
984#define F0900_P2_CORREL_ABSEXP 0xf22200f0
985#define F0900_P2_CORREL_EXP 0xf222000f
986
987/*P2_PLHMODCOD*/
988#define R0900_P2_PLHMODCOD 0xf224
989#define F0900_P2_SPECINV_DEMOD 0xf2240080
990#define F0900_P2_PLH_MODCOD 0xf224007c
991#define F0900_P2_PLH_TYPE 0xf2240003
992
993/*P2_DMDREG*/
994#define R0900_P2_DMDREG 0xf225
995#define F0900_P2_DECIM_PLFRAMES 0xf2250001
996
997/*P2_AGC2O*/
998#define R0900_P2_AGC2O 0xf22c
999#define F0900_P2_AGC2_COEF 0xf22c0007
1000
1001/*P2_AGC2REF*/
1002#define R0900_P2_AGC2REF 0xf22d
1003#define F0900_P2_AGC2_REF 0xf22d00ff
1004
1005/*P2_AGC1ADJ*/
1006#define R0900_P2_AGC1ADJ 0xf22e
1007#define F0900_P2_AGC1_ADJUSTED 0xf22e007f
1008
1009/*P2_AGC2I1*/
1010#define R0900_P2_AGC2I1 0xf236
1011#define F0900_P2_AGC2_INTEGRATOR1 0xf23600ff
1012
1013/*P2_AGC2I0*/
1014#define R0900_P2_AGC2I0 0xf237
1015#define F0900_P2_AGC2_INTEGRATOR0 0xf23700ff
1016
1017/*P2_CARCFG*/
1018#define R0900_P2_CARCFG 0xf238
1019#define F0900_P2_CFRUPLOW_AUTO 0xf2380080
1020#define F0900_P2_CFRUPLOW_TEST 0xf2380040
1021#define F0900_P2_ROTAON 0xf2380004
1022#define F0900_P2_PH_DET_ALGO 0xf2380003
1023
1024/*P2_ACLC*/
1025#define R0900_P2_ACLC 0xf239
1026#define F0900_P2_CAR_ALPHA_MANT 0xf2390030
1027#define F0900_P2_CAR_ALPHA_EXP 0xf239000f
1028
1029/*P2_BCLC*/
1030#define R0900_P2_BCLC 0xf23a
1031#define F0900_P2_CAR_BETA_MANT 0xf23a0030
1032#define F0900_P2_CAR_BETA_EXP 0xf23a000f
1033
1034/*P2_CARFREQ*/
1035#define R0900_P2_CARFREQ 0xf23d
1036#define F0900_P2_KC_COARSE_EXP 0xf23d00f0
1037#define F0900_P2_BETA_FREQ 0xf23d000f
1038
1039/*P2_CARHDR*/
1040#define R0900_P2_CARHDR 0xf23e
1041#define F0900_P2_K_FREQ_HDR 0xf23e00ff
1042
1043/*P2_LDT*/
1044#define R0900_P2_LDT 0xf23f
1045#define F0900_P2_CARLOCK_THRES 0xf23f01ff
1046
1047/*P2_LDT2*/
1048#define R0900_P2_LDT2 0xf240
1049#define F0900_P2_CARLOCK_THRES2 0xf24001ff
1050
1051/*P2_CFRICFG*/
1052#define R0900_P2_CFRICFG 0xf241
1053#define F0900_P2_NEG_CFRSTEP 0xf2410001
1054
1055/*P2_CFRUP1*/
1056#define R0900_P2_CFRUP1 0xf242
1057#define F0900_P2_CFR_UP1 0xf24201ff
1058
1059/*P2_CFRUP0*/
1060#define R0900_P2_CFRUP0 0xf243
1061#define F0900_P2_CFR_UP0 0xf24300ff
1062
1063/*P2_CFRLOW1*/
1064#define R0900_P2_CFRLOW1 0xf246
1065#define F0900_P2_CFR_LOW1 0xf24601ff
1066
1067/*P2_CFRLOW0*/
1068#define R0900_P2_CFRLOW0 0xf247
1069#define F0900_P2_CFR_LOW0 0xf24700ff
1070
1071/*P2_CFRINIT1*/
1072#define R0900_P2_CFRINIT1 0xf248
1073#define F0900_P2_CFR_INIT1 0xf24801ff
1074
1075/*P2_CFRINIT0*/
1076#define R0900_P2_CFRINIT0 0xf249
1077#define F0900_P2_CFR_INIT0 0xf24900ff
1078
1079/*P2_CFRINC1*/
1080#define R0900_P2_CFRINC1 0xf24a
1081#define F0900_P2_MANUAL_CFRINC 0xf24a0080
1082#define F0900_P2_CFR_INC1 0xf24a003f
1083
1084/*P2_CFRINC0*/
1085#define R0900_P2_CFRINC0 0xf24b
1086#define F0900_P2_CFR_INC0 0xf24b00f8
1087
1088/*P2_CFR2*/
1089#define R0900_P2_CFR2 0xf24c
1090#define F0900_P2_CAR_FREQ2 0xf24c01ff
1091
1092/*P2_CFR1*/
1093#define R0900_P2_CFR1 0xf24d
1094#define F0900_P2_CAR_FREQ1 0xf24d00ff
1095
1096/*P2_CFR0*/
1097#define R0900_P2_CFR0 0xf24e
1098#define F0900_P2_CAR_FREQ0 0xf24e00ff
1099
1100/*P2_LDI*/
1101#define R0900_P2_LDI 0xf24f
1102#define F0900_P2_LOCK_DET_INTEGR 0xf24f01ff
1103
1104/*P2_TMGCFG*/
1105#define R0900_P2_TMGCFG 0xf250
1106#define F0900_P2_TMGLOCK_BETA 0xf25000c0
1107#define F0900_P2_DO_TIMING_CORR 0xf2500010
1108#define F0900_P2_TMG_MINFREQ 0xf2500003
1109
1110/*P2_RTC*/
1111#define R0900_P2_RTC 0xf251
1112#define F0900_P2_TMGALPHA_EXP 0xf25100f0
1113#define F0900_P2_TMGBETA_EXP 0xf251000f
1114
1115/*P2_RTCS2*/
1116#define R0900_P2_RTCS2 0xf252
1117#define F0900_P2_TMGALPHAS2_EXP 0xf25200f0
1118#define F0900_P2_TMGBETAS2_EXP 0xf252000f
1119
1120/*P2_TMGTHRISE*/
1121#define R0900_P2_TMGTHRISE 0xf253
1122#define F0900_P2_TMGLOCK_THRISE 0xf25300ff
1123
1124/*P2_TMGTHFALL*/
1125#define R0900_P2_TMGTHFALL 0xf254
1126#define F0900_P2_TMGLOCK_THFALL 0xf25400ff
1127
1128/*P2_SFRUPRATIO*/
1129#define R0900_P2_SFRUPRATIO 0xf255
1130#define F0900_P2_SFR_UPRATIO 0xf25500ff
1131
1132/*P2_SFRLOWRATIO*/
1133#define R0900_P2_SFRLOWRATIO 0xf256
1134#define F0900_P2_SFR_LOWRATIO 0xf25600ff
1135
1136/*P2_KREFTMG*/
1137#define R0900_P2_KREFTMG 0xf258
1138#define F0900_P2_KREF_TMG 0xf25800ff
1139
1140/*P2_SFRSTEP*/
1141#define R0900_P2_SFRSTEP 0xf259
1142#define F0900_P2_SFR_SCANSTEP 0xf25900f0
1143#define F0900_P2_SFR_CENTERSTEP 0xf259000f
1144
1145/*P2_TMGCFG2*/
1146#define R0900_P2_TMGCFG2 0xf25a
1147#define F0900_P2_SFRRATIO_FINE 0xf25a0001
1148
1149/*P2_KREFTMG2*/
1150#define R0900_P2_KREFTMG2 0xf25b
1151#define F0900_P2_KREF_TMG2 0xf25b00ff
1152
1153/*P2_SFRINIT1*/
1154#define R0900_P2_SFRINIT1 0xf25e
1155#define F0900_P2_SFR_INIT1 0xf25e007f
1156
1157/*P2_SFRINIT0*/
1158#define R0900_P2_SFRINIT0 0xf25f
1159#define F0900_P2_SFR_INIT0 0xf25f00ff
1160
1161/*P2_SFRUP1*/
1162#define R0900_P2_SFRUP1 0xf260
1163#define F0900_P2_AUTO_GUP 0xf2600080
1164#define F0900_P2_SYMB_FREQ_UP1 0xf260007f
1165
1166/*P2_SFRUP0*/
1167#define R0900_P2_SFRUP0 0xf261
1168#define F0900_P2_SYMB_FREQ_UP0 0xf26100ff
1169
1170/*P2_SFRLOW1*/
1171#define R0900_P2_SFRLOW1 0xf262
1172#define F0900_P2_AUTO_GLOW 0xf2620080
1173#define F0900_P2_SYMB_FREQ_LOW1 0xf262007f
1174
1175/*P2_SFRLOW0*/
1176#define R0900_P2_SFRLOW0 0xf263
1177#define F0900_P2_SYMB_FREQ_LOW0 0xf26300ff
1178
1179/*P2_SFR3*/
1180#define R0900_P2_SFR3 0xf264
1181#define F0900_P2_SYMB_FREQ3 0xf26400ff
1182
1183/*P2_SFR2*/
1184#define R0900_P2_SFR2 0xf265
1185#define F0900_P2_SYMB_FREQ2 0xf26500ff
1186
1187/*P2_SFR1*/
1188#define R0900_P2_SFR1 0xf266
1189#define F0900_P2_SYMB_FREQ1 0xf26600ff
1190
1191/*P2_SFR0*/
1192#define R0900_P2_SFR0 0xf267
1193#define F0900_P2_SYMB_FREQ0 0xf26700ff
1194
1195/*P2_TMGREG2*/
1196#define R0900_P2_TMGREG2 0xf268
1197#define F0900_P2_TMGREG2 0xf26800ff
1198
1199/*P2_TMGREG1*/
1200#define R0900_P2_TMGREG1 0xf269
1201#define F0900_P2_TMGREG1 0xf26900ff
1202
1203/*P2_TMGREG0*/
1204#define R0900_P2_TMGREG0 0xf26a
1205#define F0900_P2_TMGREG0 0xf26a00ff
1206
1207/*P2_TMGLOCK1*/
1208#define R0900_P2_TMGLOCK1 0xf26b
1209#define F0900_P2_TMGLOCK_LEVEL1 0xf26b01ff
1210
1211/*P2_TMGLOCK0*/
1212#define R0900_P2_TMGLOCK0 0xf26c
1213#define F0900_P2_TMGLOCK_LEVEL0 0xf26c00ff
1214
1215/*P2_TMGOBS*/
1216#define R0900_P2_TMGOBS 0xf26d
1217#define F0900_P2_ROLLOFF_STATUS 0xf26d00c0
1218
1219/*P2_EQUALCFG*/
1220#define R0900_P2_EQUALCFG 0xf26f
1221#define F0900_P2_EQUAL_ON 0xf26f0040
1222#define F0900_P2_MU_EQUALDFE 0xf26f0007
1223
1224/*P2_EQUAI1*/
1225#define R0900_P2_EQUAI1 0xf270
1226#define F0900_P2_EQUA_ACCI1 0xf27001ff
1227
1228/*P2_EQUAQ1*/
1229#define R0900_P2_EQUAQ1 0xf271
1230#define F0900_P2_EQUA_ACCQ1 0xf27101ff
1231
1232/*P2_EQUAI2*/
1233#define R0900_P2_EQUAI2 0xf272
1234#define F0900_P2_EQUA_ACCI2 0xf27201ff
1235
1236/*P2_EQUAQ2*/
1237#define R0900_P2_EQUAQ2 0xf273
1238#define F0900_P2_EQUA_ACCQ2 0xf27301ff
1239
1240/*P2_EQUAI3*/
1241#define R0900_P2_EQUAI3 0xf274
1242#define F0900_P2_EQUA_ACCI3 0xf27401ff
1243
1244/*P2_EQUAQ3*/
1245#define R0900_P2_EQUAQ3 0xf275
1246#define F0900_P2_EQUA_ACCQ3 0xf27501ff
1247
1248/*P2_EQUAI4*/
1249#define R0900_P2_EQUAI4 0xf276
1250#define F0900_P2_EQUA_ACCI4 0xf27601ff
1251
1252/*P2_EQUAQ4*/
1253#define R0900_P2_EQUAQ4 0xf277
1254#define F0900_P2_EQUA_ACCQ4 0xf27701ff
1255
1256/*P2_EQUAI5*/
1257#define R0900_P2_EQUAI5 0xf278
1258#define F0900_P2_EQUA_ACCI5 0xf27801ff
1259
1260/*P2_EQUAQ5*/
1261#define R0900_P2_EQUAQ5 0xf279
1262#define F0900_P2_EQUA_ACCQ5 0xf27901ff
1263
1264/*P2_EQUAI6*/
1265#define R0900_P2_EQUAI6 0xf27a
1266#define F0900_P2_EQUA_ACCI6 0xf27a01ff
1267
1268/*P2_EQUAQ6*/
1269#define R0900_P2_EQUAQ6 0xf27b
1270#define F0900_P2_EQUA_ACCQ6 0xf27b01ff
1271
1272/*P2_EQUAI7*/
1273#define R0900_P2_EQUAI7 0xf27c
1274#define F0900_P2_EQUA_ACCI7 0xf27c01ff
1275
1276/*P2_EQUAQ7*/
1277#define R0900_P2_EQUAQ7 0xf27d
1278#define F0900_P2_EQUA_ACCQ7 0xf27d01ff
1279
1280/*P2_EQUAI8*/
1281#define R0900_P2_EQUAI8 0xf27e
1282#define F0900_P2_EQUA_ACCI8 0xf27e01ff
1283
1284/*P2_EQUAQ8*/
1285#define R0900_P2_EQUAQ8 0xf27f
1286#define F0900_P2_EQUA_ACCQ8 0xf27f01ff
1287
1288/*P2_NNOSDATAT1*/
1289#define R0900_P2_NNOSDATAT1 0xf280
1290#define F0900_P2_NOSDATAT_NORMED1 0xf28000ff
1291
1292/*P2_NNOSDATAT0*/
1293#define R0900_P2_NNOSDATAT0 0xf281
1294#define F0900_P2_NOSDATAT_NORMED0 0xf28100ff
1295
1296/*P2_NNOSDATA1*/
1297#define R0900_P2_NNOSDATA1 0xf282
1298#define F0900_P2_NOSDATA_NORMED1 0xf28200ff
1299
1300/*P2_NNOSDATA0*/
1301#define R0900_P2_NNOSDATA0 0xf283
1302#define F0900_P2_NOSDATA_NORMED0 0xf28300ff
1303
1304/*P2_NNOSPLHT1*/
1305#define R0900_P2_NNOSPLHT1 0xf284
1306#define F0900_P2_NOSPLHT_NORMED1 0xf28400ff
1307
1308/*P2_NNOSPLHT0*/
1309#define R0900_P2_NNOSPLHT0 0xf285
1310#define F0900_P2_NOSPLHT_NORMED0 0xf28500ff
1311
1312/*P2_NNOSPLH1*/
1313#define R0900_P2_NNOSPLH1 0xf286
1314#define F0900_P2_NOSPLH_NORMED1 0xf28600ff
1315
1316/*P2_NNOSPLH0*/
1317#define R0900_P2_NNOSPLH0 0xf287
1318#define F0900_P2_NOSPLH_NORMED0 0xf28700ff
1319
1320/*P2_NOSDATAT1*/
1321#define R0900_P2_NOSDATAT1 0xf288
1322#define F0900_P2_NOSDATAT_UNNORMED1 0xf28800ff
1323
1324/*P2_NOSDATAT0*/
1325#define R0900_P2_NOSDATAT0 0xf289
1326#define F0900_P2_NOSDATAT_UNNORMED0 0xf28900ff
1327
1328/*P2_NOSDATA1*/
1329#define R0900_P2_NOSDATA1 0xf28a
1330#define F0900_P2_NOSDATA_UNNORMED1 0xf28a00ff
1331
1332/*P2_NOSDATA0*/
1333#define R0900_P2_NOSDATA0 0xf28b
1334#define F0900_P2_NOSDATA_UNNORMED0 0xf28b00ff
1335
1336/*P2_NOSPLHT1*/
1337#define R0900_P2_NOSPLHT1 0xf28c
1338#define F0900_P2_NOSPLHT_UNNORMED1 0xf28c00ff
1339
1340/*P2_NOSPLHT0*/
1341#define R0900_P2_NOSPLHT0 0xf28d
1342#define F0900_P2_NOSPLHT_UNNORMED0 0xf28d00ff
1343
1344/*P2_NOSPLH1*/
1345#define R0900_P2_NOSPLH1 0xf28e
1346#define F0900_P2_NOSPLH_UNNORMED1 0xf28e00ff
1347
1348/*P2_NOSPLH0*/
1349#define R0900_P2_NOSPLH0 0xf28f
1350#define F0900_P2_NOSPLH_UNNORMED0 0xf28f00ff
1351
1352/*P2_CAR2CFG*/
1353#define R0900_P2_CAR2CFG 0xf290
1354#define F0900_P2_CARRIER3_DISABLE 0xf2900040
1355#define F0900_P2_ROTA2ON 0xf2900004
1356#define F0900_P2_PH_DET_ALGO2 0xf2900003
1357
1358/*P2_CFR2CFR1*/
1359#define R0900_P2_CFR2CFR1 0xf291
1360#define F0900_P2_CFR2TOCFR1_DVBS1 0xf29100c0
1361#define F0900_P2_EN_S2CAR2CENTER 0xf2910020
1362#define F0900_P2_DIS_BCHERRCFR2 0xf2910010
1363#define F0900_P2_CFR2TOCFR1_BETA 0xf2910007
1364
1365/*P2_CFR22*/
1366#define R0900_P2_CFR22 0xf293
1367#define F0900_P2_CAR2_FREQ2 0xf29301ff
1368
1369/*P2_CFR21*/
1370#define R0900_P2_CFR21 0xf294
1371#define F0900_P2_CAR2_FREQ1 0xf29400ff
1372
1373/*P2_CFR20*/
1374#define R0900_P2_CFR20 0xf295
1375#define F0900_P2_CAR2_FREQ0 0xf29500ff
1376
1377/*P2_ACLC2S2Q*/
1378#define R0900_P2_ACLC2S2Q 0xf297
1379#define F0900_P2_ENAB_SPSKSYMB 0xf2970080
1380#define F0900_P2_CAR2S2_Q_ALPH_M 0xf2970030
1381#define F0900_P2_CAR2S2_Q_ALPH_E 0xf297000f
1382
1383/*P2_ACLC2S28*/
1384#define R0900_P2_ACLC2S28 0xf298
1385#define F0900_P2_OLDI3Q_MODE 0xf2980080
1386#define F0900_P2_CAR2S2_8_ALPH_M 0xf2980030
1387#define F0900_P2_CAR2S2_8_ALPH_E 0xf298000f
1388
1389/*P2_ACLC2S216A*/
1390#define R0900_P2_ACLC2S216A 0xf299
1391#define F0900_P2_DIS_C3STOPA2 0xf2990080
1392#define F0900_P2_CAR2S2_16ADERAT 0xf2990040
1393#define F0900_P2_CAR2S2_16A_ALPH_M 0xf2990030
1394#define F0900_P2_CAR2S2_16A_ALPH_E 0xf299000f
1395
1396/*P2_ACLC2S232A*/
1397#define R0900_P2_ACLC2S232A 0xf29a
1398#define F0900_P2_CAR2S2_32ADERAT 0xf29a0040
1399#define F0900_P2_CAR2S2_32A_ALPH_M 0xf29a0030
1400#define F0900_P2_CAR2S2_32A_ALPH_E 0xf29a000f
1401
1402/*P2_BCLC2S2Q*/
1403#define R0900_P2_BCLC2S2Q 0xf29c
1404#define F0900_P2_CAR2S2_Q_BETA_M 0xf29c0030
1405#define F0900_P2_CAR2S2_Q_BETA_E 0xf29c000f
1406
1407/*P2_BCLC2S28*/
1408#define R0900_P2_BCLC2S28 0xf29d
1409#define F0900_P2_CAR2S2_8_BETA_M 0xf29d0030
1410#define F0900_P2_CAR2S2_8_BETA_E 0xf29d000f
1411
1412/*P2_BCLC2S216A*/
1413#define R0900_P2_BCLC2S216A 0xf29e
1414
1415/*P2_BCLC2S232A*/
1416#define R0900_P2_BCLC2S232A 0xf29f
1417
1418/*P2_PLROOT2*/
1419#define R0900_P2_PLROOT2 0xf2ac
1420#define F0900_P2_PLSCRAMB_MODE 0xf2ac000c
1421#define F0900_P2_PLSCRAMB_ROOT2 0xf2ac0003
1422
1423/*P2_PLROOT1*/
1424#define R0900_P2_PLROOT1 0xf2ad
1425#define F0900_P2_PLSCRAMB_ROOT1 0xf2ad00ff
1426
1427/*P2_PLROOT0*/
1428#define R0900_P2_PLROOT0 0xf2ae
1429#define F0900_P2_PLSCRAMB_ROOT0 0xf2ae00ff
1430
1431/*P2_MODCODLST0*/
1432#define R0900_P2_MODCODLST0 0xf2b0
1433
1434/*P2_MODCODLST1*/
1435#define R0900_P2_MODCODLST1 0xf2b1
1436#define F0900_P2_DIS_MODCOD29 0xf2b100f0
1437#define F0900_P2_DIS_32PSK_9_10 0xf2b1000f
1438
1439/*P2_MODCODLST2*/
1440#define R0900_P2_MODCODLST2 0xf2b2
1441#define F0900_P2_DIS_32PSK_8_9 0xf2b200f0
1442#define F0900_P2_DIS_32PSK_5_6 0xf2b2000f
1443
1444/*P2_MODCODLST3*/
1445#define R0900_P2_MODCODLST3 0xf2b3
1446#define F0900_P2_DIS_32PSK_4_5 0xf2b300f0
1447#define F0900_P2_DIS_32PSK_3_4 0xf2b3000f
1448
1449/*P2_MODCODLST4*/
1450#define R0900_P2_MODCODLST4 0xf2b4
1451#define F0900_P2_DIS_16PSK_9_10 0xf2b400f0
1452#define F0900_P2_DIS_16PSK_8_9 0xf2b4000f
1453
1454/*P2_MODCODLST5*/
1455#define R0900_P2_MODCODLST5 0xf2b5
1456#define F0900_P2_DIS_16PSK_5_6 0xf2b500f0
1457#define F0900_P2_DIS_16PSK_4_5 0xf2b5000f
1458
1459/*P2_MODCODLST6*/
1460#define R0900_P2_MODCODLST6 0xf2b6
1461#define F0900_P2_DIS_16PSK_3_4 0xf2b600f0
1462#define F0900_P2_DIS_16PSK_2_3 0xf2b6000f
1463
1464/*P2_MODCODLST7*/
1465#define R0900_P2_MODCODLST7 0xf2b7
1466#define F0900_P2_DIS_8P_9_10 0xf2b700f0
1467#define F0900_P2_DIS_8P_8_9 0xf2b7000f
1468
1469/*P2_MODCODLST8*/
1470#define R0900_P2_MODCODLST8 0xf2b8
1471#define F0900_P2_DIS_8P_5_6 0xf2b800f0
1472#define F0900_P2_DIS_8P_3_4 0xf2b8000f
1473
1474/*P2_MODCODLST9*/
1475#define R0900_P2_MODCODLST9 0xf2b9
1476#define F0900_P2_DIS_8P_2_3 0xf2b900f0
1477#define F0900_P2_DIS_8P_3_5 0xf2b9000f
1478
1479/*P2_MODCODLSTA*/
1480#define R0900_P2_MODCODLSTA 0xf2ba
1481#define F0900_P2_DIS_QP_9_10 0xf2ba00f0
1482#define F0900_P2_DIS_QP_8_9 0xf2ba000f
1483
1484/*P2_MODCODLSTB*/
1485#define R0900_P2_MODCODLSTB 0xf2bb
1486#define F0900_P2_DIS_QP_5_6 0xf2bb00f0
1487#define F0900_P2_DIS_QP_4_5 0xf2bb000f
1488
1489/*P2_MODCODLSTC*/
1490#define R0900_P2_MODCODLSTC 0xf2bc
1491#define F0900_P2_DIS_QP_3_4 0xf2bc00f0
1492#define F0900_P2_DIS_QP_2_3 0xf2bc000f
1493
1494/*P2_MODCODLSTD*/
1495#define R0900_P2_MODCODLSTD 0xf2bd
1496#define F0900_P2_DIS_QP_3_5 0xf2bd00f0
1497#define F0900_P2_DIS_QP_1_2 0xf2bd000f
1498
1499/*P2_MODCODLSTE*/
1500#define R0900_P2_MODCODLSTE 0xf2be
1501#define F0900_P2_DIS_QP_2_5 0xf2be00f0
1502#define F0900_P2_DIS_QP_1_3 0xf2be000f
1503
1504/*P2_MODCODLSTF*/
1505#define R0900_P2_MODCODLSTF 0xf2bf
1506#define F0900_P2_DIS_QP_1_4 0xf2bf00f0
1507
1508/*P2_GAUSSR0*/
1509#define R0900_P2_GAUSSR0 0xf2c0
1510#define F0900_P2_EN_CCIMODE 0xf2c00080
1511#define F0900_P2_R0_GAUSSIEN 0xf2c0007f
1512
1513/*P2_CCIR0*/
1514#define R0900_P2_CCIR0 0xf2c1
1515#define F0900_P2_CCIDETECT_PLHONLY 0xf2c10080
1516#define F0900_P2_R0_CCI 0xf2c1007f
1517
1518/*P2_CCIQUANT*/
1519#define R0900_P2_CCIQUANT 0xf2c2
1520#define F0900_P2_CCI_BETA 0xf2c200e0
1521#define F0900_P2_CCI_QUANT 0xf2c2001f
1522
1523/*P2_CCITHRES*/
1524#define R0900_P2_CCITHRES 0xf2c3
1525#define F0900_P2_CCI_THRESHOLD 0xf2c300ff
1526
1527/*P2_CCIACC*/
1528#define R0900_P2_CCIACC 0xf2c4
1529#define F0900_P2_CCI_VALUE 0xf2c400ff
1530
1531/*P2_DMDRESCFG*/
1532#define R0900_P2_DMDRESCFG 0xf2c6
1533#define F0900_P2_DMDRES_RESET 0xf2c60080
1534#define F0900_P2_DMDRES_STRALL 0xf2c60008
1535#define F0900_P2_DMDRES_NEWONLY 0xf2c60004
1536#define F0900_P2_DMDRES_NOSTORE 0xf2c60002
1537
1538/*P2_DMDRESADR*/
1539#define R0900_P2_DMDRESADR 0xf2c7
1540#define F0900_P2_DMDRES_VALIDCFR 0xf2c70040
1541#define F0900_P2_DMDRES_MEMFULL 0xf2c70030
1542#define F0900_P2_DMDRES_RESNBR 0xf2c7000f
1543
1544/*P2_DMDRESDATA7*/
1545#define R0900_P2_DMDRESDATA7 0xf2c8
1546#define F0900_P2_DMDRES_DATA7 0xf2c800ff
1547
1548/*P2_DMDRESDATA6*/
1549#define R0900_P2_DMDRESDATA6 0xf2c9
1550#define F0900_P2_DMDRES_DATA6 0xf2c900ff
1551
1552/*P2_DMDRESDATA5*/
1553#define R0900_P2_DMDRESDATA5 0xf2ca
1554#define F0900_P2_DMDRES_DATA5 0xf2ca00ff
1555
1556/*P2_DMDRESDATA4*/
1557#define R0900_P2_DMDRESDATA4 0xf2cb
1558#define F0900_P2_DMDRES_DATA4 0xf2cb00ff
1559
1560/*P2_DMDRESDATA3*/
1561#define R0900_P2_DMDRESDATA3 0xf2cc
1562#define F0900_P2_DMDRES_DATA3 0xf2cc00ff
1563
1564/*P2_DMDRESDATA2*/
1565#define R0900_P2_DMDRESDATA2 0xf2cd
1566#define F0900_P2_DMDRES_DATA2 0xf2cd00ff
1567
1568/*P2_DMDRESDATA1*/
1569#define R0900_P2_DMDRESDATA1 0xf2ce
1570#define F0900_P2_DMDRES_DATA1 0xf2ce00ff
1571
1572/*P2_DMDRESDATA0*/
1573#define R0900_P2_DMDRESDATA0 0xf2cf
1574#define F0900_P2_DMDRES_DATA0 0xf2cf00ff
1575
1576/*P2_FFEI1*/
1577#define R0900_P2_FFEI1 0xf2d0
1578#define F0900_P2_FFE_ACCI1 0xf2d001ff
1579
1580/*P2_FFEQ1*/
1581#define R0900_P2_FFEQ1 0xf2d1
1582#define F0900_P2_FFE_ACCQ1 0xf2d101ff
1583
1584/*P2_FFEI2*/
1585#define R0900_P2_FFEI2 0xf2d2
1586#define F0900_P2_FFE_ACCI2 0xf2d201ff
1587
1588/*P2_FFEQ2*/
1589#define R0900_P2_FFEQ2 0xf2d3
1590#define F0900_P2_FFE_ACCQ2 0xf2d301ff
1591
1592/*P2_FFEI3*/
1593#define R0900_P2_FFEI3 0xf2d4
1594#define F0900_P2_FFE_ACCI3 0xf2d401ff
1595
1596/*P2_FFEQ3*/
1597#define R0900_P2_FFEQ3 0xf2d5
1598#define F0900_P2_FFE_ACCQ3 0xf2d501ff
1599
1600/*P2_FFEI4*/
1601#define R0900_P2_FFEI4 0xf2d6
1602#define F0900_P2_FFE_ACCI4 0xf2d601ff
1603
1604/*P2_FFEQ4*/
1605#define R0900_P2_FFEQ4 0xf2d7
1606#define F0900_P2_FFE_ACCQ4 0xf2d701ff
1607
1608/*P2_FFECFG*/
1609#define R0900_P2_FFECFG 0xf2d8
1610#define F0900_P2_EQUALFFE_ON 0xf2d80040
1611#define F0900_P2_MU_EQUALFFE 0xf2d80007
1612
1613/*P2_TNRCFG*/
1614#define R0900_P2_TNRCFG 0xf2e0
1615#define F0900_P2_TUN_ACKFAIL 0xf2e00080
1616#define F0900_P2_TUN_TYPE 0xf2e00070
1617#define F0900_P2_TUN_SECSTOP 0xf2e00008
1618#define F0900_P2_TUN_VCOSRCH 0xf2e00004
1619#define F0900_P2_TUN_MADDRESS 0xf2e00003
1620
1621/*P2_TNRCFG2*/
1622#define R0900_P2_TNRCFG2 0xf2e1
1623#define F0900_P2_TUN_IQSWAP 0xf2e10080
1624#define F0900_P2_DIS_BWCALC 0xf2e10004
1625#define F0900_P2_SHORT_WAITSTATES 0xf2e10002
1626
1627/*P2_TNRXTAL*/
1628#define R0900_P2_TNRXTAL 0xf2e4
1629#define F0900_P2_TUN_XTALFREQ 0xf2e4001f
1630
1631/*P2_TNRSTEPS*/
1632#define R0900_P2_TNRSTEPS 0xf2e7
1633#define F0900_P2_TUNER_BW0P125 0xf2e70080
1634#define F0900_P2_BWINC_OFFSET 0xf2e70170
1635#define F0900_P2_SOFTSTEP_RNG 0xf2e70008
1636#define F0900_P2_TUN_BWOFFSET 0xf2e70007
1637
1638/*P2_TNRGAIN*/
1639#define R0900_P2_TNRGAIN 0xf2e8
1640#define F0900_P2_TUN_KDIVEN 0xf2e800c0
1641#define F0900_P2_STB6X00_OCK 0xf2e80030
1642#define F0900_P2_TUN_GAIN 0xf2e8000f
1643
1644/*P2_TNRRF1*/
1645#define R0900_P2_TNRRF1 0xf2e9
1646#define F0900_P2_TUN_RFFREQ2 0xf2e900ff
1647
1648/*P2_TNRRF0*/
1649#define R0900_P2_TNRRF0 0xf2ea
1650#define F0900_P2_TUN_RFFREQ1 0xf2ea00ff
1651
1652/*P2_TNRBW*/
1653#define R0900_P2_TNRBW 0xf2eb
1654#define F0900_P2_TUN_RFFREQ0 0xf2eb00c0
1655#define F0900_P2_TUN_BW 0xf2eb003f
1656
1657/*P2_TNRADJ*/
1658#define R0900_P2_TNRADJ 0xf2ec
1659#define F0900_P2_STB61X0_CALTIME 0xf2ec0040
1660
1661/*P2_TNRCTL2*/
1662#define R0900_P2_TNRCTL2 0xf2ed
1663#define F0900_P2_STB61X0_RCCKOFF 0xf2ed0080
1664#define F0900_P2_STB61X0_ICP_SDOFF 0xf2ed0040
1665#define F0900_P2_STB61X0_DCLOOPOFF 0xf2ed0020
1666#define F0900_P2_STB61X0_REFOUTSEL 0xf2ed0010
1667#define F0900_P2_STB61X0_CALOFF 0xf2ed0008
1668#define F0900_P2_STB6XX0_LPT_BEN 0xf2ed0004
1669#define F0900_P2_STB6XX0_RX_OSCP 0xf2ed0002
1670#define F0900_P2_STB6XX0_SYN 0xf2ed0001
1671
1672/*P2_TNRCFG3*/
1673#define R0900_P2_TNRCFG3 0xf2ee
1674#define F0900_P2_TUN_PLLFREQ 0xf2ee001c
1675#define F0900_P2_TUN_I2CFREQ_MODE 0xf2ee0003
1676
1677/*P2_TNRLAUNCH*/
1678#define R0900_P2_TNRLAUNCH 0xf2f0
1679
1680/*P2_TNRLD*/
1681#define R0900_P2_TNRLD 0xf2f0
1682#define F0900_P2_TUNLD_VCOING 0xf2f00080
1683#define F0900_P2_TUN_REG1FAIL 0xf2f00040
1684#define F0900_P2_TUN_REG2FAIL 0xf2f00020
1685#define F0900_P2_TUN_REG3FAIL 0xf2f00010
1686#define F0900_P2_TUN_REG4FAIL 0xf2f00008
1687#define F0900_P2_TUN_REG5FAIL 0xf2f00004
1688#define F0900_P2_TUN_BWING 0xf2f00002
1689#define F0900_P2_TUN_LOCKED 0xf2f00001
1690
1691/*P2_TNROBSL*/
1692#define R0900_P2_TNROBSL 0xf2f6
1693#define F0900_P2_TUN_I2CABORTED 0xf2f60080
1694#define F0900_P2_TUN_LPEN 0xf2f60040
1695#define F0900_P2_TUN_FCCK 0xf2f60020
1696#define F0900_P2_TUN_I2CLOCKED 0xf2f60010
1697#define F0900_P2_TUN_PROGDONE 0xf2f6000c
1698#define F0900_P2_TUN_RFRESTE1 0xf2f60003
1699
1700/*P2_TNRRESTE*/
1701#define R0900_P2_TNRRESTE 0xf2f7
1702#define F0900_P2_TUN_RFRESTE0 0xf2f700ff
1703
1704/*P2_SMAPCOEF7*/
1705#define R0900_P2_SMAPCOEF7 0xf300
1706#define F0900_P2_DIS_QSCALE 0xf3000080
1707#define F0900_P2_SMAPCOEF_Q_LLR12 0xf300017f
1708
1709/*P2_SMAPCOEF6*/
1710#define R0900_P2_SMAPCOEF6 0xf301
1711#define F0900_P2_ADJ_8PSKLLR1 0xf3010004
1712#define F0900_P2_OLD_8PSKLLR1 0xf3010002
1713#define F0900_P2_DIS_AB8PSK 0xf3010001
1714
1715/*P2_SMAPCOEF5*/
1716#define R0900_P2_SMAPCOEF5 0xf302
1717#define F0900_P2_DIS_8SCALE 0xf3020080
1718#define F0900_P2_SMAPCOEF_8P_LLR23 0xf302017f
1719
1720/*P2_NCO2MAX1*/
1721#define R0900_P2_NCO2MAX1 0xf314
1722#define F0900_P2_TETA2_MAXVABS1 0xf31400ff
1723
1724/*P2_NCO2MAX0*/
1725#define R0900_P2_NCO2MAX0 0xf315
1726#define F0900_P2_TETA2_MAXVABS0 0xf31500ff
1727
1728/*P2_NCO2FR1*/
1729#define R0900_P2_NCO2FR1 0xf316
1730#define F0900_P2_NCO2FINAL_ANGLE1 0xf31600ff
1731
1732/*P2_NCO2FR0*/
1733#define R0900_P2_NCO2FR0 0xf317
1734#define F0900_P2_NCO2FINAL_ANGLE0 0xf31700ff
1735
1736/*P2_CFR2AVRGE1*/
1737#define R0900_P2_CFR2AVRGE1 0xf318
1738#define F0900_P2_I2C_CFR2AVERAGE1 0xf31800ff
1739
1740/*P2_CFR2AVRGE0*/
1741#define R0900_P2_CFR2AVRGE0 0xf319
1742#define F0900_P2_I2C_CFR2AVERAGE0 0xf31900ff
1743
1744/*P2_DMDPLHSTAT*/
1745#define R0900_P2_DMDPLHSTAT 0xf320
1746#define F0900_P2_PLH_STATISTIC 0xf32000ff
1747
1748/*P2_LOCKTIME3*/
1749#define R0900_P2_LOCKTIME3 0xf322
1750#define F0900_P2_DEMOD_LOCKTIME3 0xf32200ff
1751
1752/*P2_LOCKTIME2*/
1753#define R0900_P2_LOCKTIME2 0xf323
1754#define F0900_P2_DEMOD_LOCKTIME2 0xf32300ff
1755
1756/*P2_LOCKTIME1*/
1757#define R0900_P2_LOCKTIME1 0xf324
1758#define F0900_P2_DEMOD_LOCKTIME1 0xf32400ff
1759
1760/*P2_LOCKTIME0*/
1761#define R0900_P2_LOCKTIME0 0xf325
1762#define F0900_P2_DEMOD_LOCKTIME0 0xf32500ff
1763
1764/*P2_VITSCALE*/
1765#define R0900_P2_VITSCALE 0xf332
1766#define F0900_P2_NVTH_NOSRANGE 0xf3320080
1767#define F0900_P2_VERROR_MAXMODE 0xf3320040
1768#define F0900_P2_NSLOWSN_LOCKED 0xf3320008
1769#define F0900_P2_DIS_RSFLOCK 0xf3320002
1770
1771/*P2_FECM*/
1772#define R0900_P2_FECM 0xf333
1773#define F0900_P2_DSS_DVB 0xf3330080
1774#define F0900_P2_DSS_SRCH 0xf3330010
1775#define F0900_P2_SYNCVIT 0xf3330002
1776#define F0900_P2_IQINV 0xf3330001
1777
1778/*P2_VTH12*/
1779#define R0900_P2_VTH12 0xf334
1780#define F0900_P2_VTH12 0xf33400ff
1781
1782/*P2_VTH23*/
1783#define R0900_P2_VTH23 0xf335
1784#define F0900_P2_VTH23 0xf33500ff
1785
1786/*P2_VTH34*/
1787#define R0900_P2_VTH34 0xf336
1788#define F0900_P2_VTH34 0xf33600ff
1789
1790/*P2_VTH56*/
1791#define R0900_P2_VTH56 0xf337
1792#define F0900_P2_VTH56 0xf33700ff
1793
1794/*P2_VTH67*/
1795#define R0900_P2_VTH67 0xf338
1796#define F0900_P2_VTH67 0xf33800ff
1797
1798/*P2_VTH78*/
1799#define R0900_P2_VTH78 0xf339
1800#define F0900_P2_VTH78 0xf33900ff
1801
1802/*P2_VITCURPUN*/
1803#define R0900_P2_VITCURPUN 0xf33a
1804#define F0900_P2_VIT_CURPUN 0xf33a001f
1805
1806/*P2_VERROR*/
1807#define R0900_P2_VERROR 0xf33b
1808#define F0900_P2_REGERR_VIT 0xf33b00ff
1809
1810/*P2_PRVIT*/
1811#define R0900_P2_PRVIT 0xf33c
1812#define F0900_P2_DIS_VTHLOCK 0xf33c0040
1813#define F0900_P2_E7_8VIT 0xf33c0020
1814#define F0900_P2_E6_7VIT 0xf33c0010
1815#define F0900_P2_E5_6VIT 0xf33c0008
1816#define F0900_P2_E3_4VIT 0xf33c0004
1817#define F0900_P2_E2_3VIT 0xf33c0002
1818#define F0900_P2_E1_2VIT 0xf33c0001
1819
1820/*P2_VAVSRVIT*/
1821#define R0900_P2_VAVSRVIT 0xf33d
1822#define F0900_P2_AMVIT 0xf33d0080
1823#define F0900_P2_FROZENVIT 0xf33d0040
1824#define F0900_P2_SNVIT 0xf33d0030
1825#define F0900_P2_TOVVIT 0xf33d000c
1826#define F0900_P2_HYPVIT 0xf33d0003
1827
1828/*P2_VSTATUSVIT*/
1829#define R0900_P2_VSTATUSVIT 0xf33e
1830#define F0900_P2_PRFVIT 0xf33e0010
1831#define F0900_P2_LOCKEDVIT 0xf33e0008
1832
1833/*P2_VTHINUSE*/
1834#define R0900_P2_VTHINUSE 0xf33f
1835#define F0900_P2_VIT_INUSE 0xf33f00ff
1836
1837/*P2_KDIV12*/
1838#define R0900_P2_KDIV12 0xf340
1839#define F0900_P2_K_DIVIDER_12 0xf340007f
1840
1841/*P2_KDIV23*/
1842#define R0900_P2_KDIV23 0xf341
1843#define F0900_P2_K_DIVIDER_23 0xf341007f
1844
1845/*P2_KDIV34*/
1846#define R0900_P2_KDIV34 0xf342
1847#define F0900_P2_K_DIVIDER_34 0xf342007f
1848
1849/*P2_KDIV56*/
1850#define R0900_P2_KDIV56 0xf343
1851#define F0900_P2_K_DIVIDER_56 0xf343007f
1852
1853/*P2_KDIV67*/
1854#define R0900_P2_KDIV67 0xf344
1855#define F0900_P2_K_DIVIDER_67 0xf344007f
1856
1857/*P2_KDIV78*/
1858#define R0900_P2_KDIV78 0xf345
1859#define F0900_P2_K_DIVIDER_78 0xf345007f
1860
1861/*P2_PDELCTRL1*/
1862#define R0900_P2_PDELCTRL1 0xf350
1863#define F0900_P2_INV_MISMASK 0xf3500080
1864#define F0900_P2_FILTER_EN 0xf3500020
1865#define F0900_P2_EN_MIS00 0xf3500002
1866#define F0900_P2_ALGOSWRST 0xf3500001
1867
1868/*P2_PDELCTRL2*/
1869#define R0900_P2_PDELCTRL2 0xf351
1870#define F0900_P2_RESET_UPKO_COUNT 0xf3510040
1871#define F0900_P2_FRAME_MODE 0xf3510002
1872#define F0900_P2_NOBCHERRFLG_USE 0xf3510001
1873
1874/*P2_HYSTTHRESH*/
1875#define R0900_P2_HYSTTHRESH 0xf354
1876#define F0900_P2_UNLCK_THRESH 0xf35400f0
1877#define F0900_P2_DELIN_LCK_THRESH 0xf354000f
1878
1879/*P2_ISIENTRY*/
1880#define R0900_P2_ISIENTRY 0xf35e
1881#define F0900_P2_ISI_ENTRY 0xf35e00ff
1882
1883/*P2_ISIBITENA*/
1884#define R0900_P2_ISIBITENA 0xf35f
1885#define F0900_P2_ISI_BIT_EN 0xf35f00ff
1886
1887/*P2_MATSTR1*/
1888#define R0900_P2_MATSTR1 0xf360
1889#define F0900_P2_MATYPE_CURRENT1 0xf36000ff
1890
1891/*P2_MATSTR0*/
1892#define R0900_P2_MATSTR0 0xf361
1893#define F0900_P2_MATYPE_CURRENT0 0xf36100ff
1894
1895/*P2_UPLSTR1*/
1896#define R0900_P2_UPLSTR1 0xf362
1897#define F0900_P2_UPL_CURRENT1 0xf36200ff
1898
1899/*P2_UPLSTR0*/
1900#define R0900_P2_UPLSTR0 0xf363
1901#define F0900_P2_UPL_CURRENT0 0xf36300ff
1902
1903/*P2_DFLSTR1*/
1904#define R0900_P2_DFLSTR1 0xf364
1905#define F0900_P2_DFL_CURRENT1 0xf36400ff
1906
1907/*P2_DFLSTR0*/
1908#define R0900_P2_DFLSTR0 0xf365
1909#define F0900_P2_DFL_CURRENT0 0xf36500ff
1910
1911/*P2_SYNCSTR*/
1912#define R0900_P2_SYNCSTR 0xf366
1913#define F0900_P2_SYNC_CURRENT 0xf36600ff
1914
1915/*P2_SYNCDSTR1*/
1916#define R0900_P2_SYNCDSTR1 0xf367
1917#define F0900_P2_SYNCD_CURRENT1 0xf36700ff
1918
1919/*P2_SYNCDSTR0*/
1920#define R0900_P2_SYNCDSTR0 0xf368
1921#define F0900_P2_SYNCD_CURRENT0 0xf36800ff
1922
1923/*P2_PDELSTATUS1*/
1924#define R0900_P2_PDELSTATUS1 0xf369
1925#define F0900_P2_PKTDELIN_DELOCK 0xf3690080
1926#define F0900_P2_SYNCDUPDFL_BADDFL 0xf3690040
1927#define F0900_P2_CONTINUOUS_STREAM 0xf3690020
1928#define F0900_P2_UNACCEPTED_STREAM 0xf3690010
1929#define F0900_P2_BCH_ERROR_FLAG 0xf3690008
1930#define F0900_P2_PKTDELIN_LOCK 0xf3690002
1931#define F0900_P2_FIRST_LOCK 0xf3690001
1932
1933/*P2_PDELSTATUS2*/
1934#define R0900_P2_PDELSTATUS2 0xf36a
1935#define F0900_P2_FRAME_MODCOD 0xf36a007c
1936#define F0900_P2_FRAME_TYPE 0xf36a0003
1937
1938/*P2_BBFCRCKO1*/
1939#define R0900_P2_BBFCRCKO1 0xf36b
1940#define F0900_P2_BBHCRC_KOCNT1 0xf36b00ff
1941
1942/*P2_BBFCRCKO0*/
1943#define R0900_P2_BBFCRCKO0 0xf36c
1944#define F0900_P2_BBHCRC_KOCNT0 0xf36c00ff
1945
1946/*P2_UPCRCKO1*/
1947#define R0900_P2_UPCRCKO1 0xf36d
1948#define F0900_P2_PKTCRC_KOCNT1 0xf36d00ff
1949
1950/*P2_UPCRCKO0*/
1951#define R0900_P2_UPCRCKO0 0xf36e
1952#define F0900_P2_PKTCRC_KOCNT0 0xf36e00ff
1953
1954/*P2_PDELCTRL3*/
1955#define R0900_P2_PDELCTRL3 0xf36f
1956#define F0900_P2_PKTDEL_CONTFAIL 0xf36f0080
1957#define F0900_P2_NOFIFO_BCHERR 0xf36f0020
1958
1959/*P2_TSSTATEM*/
1960#define R0900_P2_TSSTATEM 0xf370
1961#define F0900_P2_TSDIL_ON 0xf3700080
1962#define F0900_P2_TSRS_ON 0xf3700020
1963#define F0900_P2_TSDESCRAMB_ON 0xf3700010
1964#define F0900_P2_TSFRAME_MODE 0xf3700008
1965#define F0900_P2_TS_DISABLE 0xf3700004
1966#define F0900_P2_TSOUT_NOSYNC 0xf3700001
1967
1968/*P2_TSCFGH*/
1969#define R0900_P2_TSCFGH 0xf372
1970#define F0900_P2_TSFIFO_DVBCI 0xf3720080
1971#define F0900_P2_TSFIFO_SERIAL 0xf3720040
1972#define F0900_P2_TSFIFO_TEIUPDATE 0xf3720020
1973#define F0900_P2_TSFIFO_DUTY50 0xf3720010
1974#define F0900_P2_TSFIFO_HSGNLOUT 0xf3720008
1975#define F0900_P2_TSFIFO_ERRMODE 0xf3720006
1976#define F0900_P2_RST_HWARE 0xf3720001
1977
1978/*P2_TSCFGM*/
1979#define R0900_P2_TSCFGM 0xf373
1980#define F0900_P2_TSFIFO_MANSPEED 0xf37300c0
1981#define F0900_P2_TSFIFO_PERMDATA 0xf3730020
1982#define F0900_P2_TSFIFO_DPUNACT 0xf3730002
1983#define F0900_P2_TSFIFO_INVDATA 0xf3730001
1984
1985/*P2_TSCFGL*/
1986#define R0900_P2_TSCFGL 0xf374
1987#define F0900_P2_TSFIFO_BCLKDEL1CK 0xf37400c0
1988#define F0900_P2_BCHERROR_MODE 0xf3740030
1989#define F0900_P2_TSFIFO_NSGNL2DATA 0xf3740008
1990#define F0900_P2_TSFIFO_EMBINDVB 0xf3740004
1991#define F0900_P2_TSFIFO_BITSPEED 0xf3740003
1992
1993/*P2_TSINSDELH*/
1994#define R0900_P2_TSINSDELH 0xf376
1995#define F0900_P2_TSDEL_SYNCBYTE 0xf3760080
1996#define F0900_P2_TSDEL_XXHEADER 0xf3760040
1997#define F0900_P2_TSDEL_BBHEADER 0xf3760020
1998#define F0900_P2_TSDEL_DATAFIELD 0xf3760010
1999#define F0900_P2_TSINSDEL_ISCR 0xf3760008
2000#define F0900_P2_TSINSDEL_NPD 0xf3760004
2001#define F0900_P2_TSINSDEL_RSPARITY 0xf3760002
2002#define F0900_P2_TSINSDEL_CRC8 0xf3760001
2003
2004/*P2_TSDIVN*/
2005#define R0900_P2_TSDIVN 0xf379
2006#define F0900_P2_TSFIFO_SPEEDMODE 0xf37900c0
2007
2008/*P2_TSCFG4*/
2009#define R0900_P2_TSCFG4 0xf37a
2010#define F0900_P2_TSFIFO_TSSPEEDMODE 0xf37a00c0
2011
2012/*P2_TSSPEED*/
2013#define R0900_P2_TSSPEED 0xf380
2014#define F0900_P2_TSFIFO_OUTSPEED 0xf38000ff
2015
2016/*P2_TSSTATUS*/
2017#define R0900_P2_TSSTATUS 0xf381
2018#define F0900_P2_TSFIFO_LINEOK 0xf3810080
2019#define F0900_P2_TSFIFO_ERROR 0xf3810040
2020#define F0900_P2_DIL_READY 0xf3810001
2021
2022/*P2_TSSTATUS2*/
2023#define R0900_P2_TSSTATUS2 0xf382
2024#define F0900_P2_TSFIFO_DEMODSEL 0xf3820080
2025#define F0900_P2_TSFIFOSPEED_STORE 0xf3820040
2026#define F0900_P2_DILXX_RESET 0xf3820020
2027#define F0900_P2_TSSERIAL_IMPOS 0xf3820010
2028#define F0900_P2_SCRAMBDETECT 0xf3820002
2029
2030/*P2_TSBITRATE1*/
2031#define R0900_P2_TSBITRATE1 0xf383
2032#define F0900_P2_TSFIFO_BITRATE1 0xf38300ff
2033
2034/*P2_TSBITRATE0*/
2035#define R0900_P2_TSBITRATE0 0xf384
2036#define F0900_P2_TSFIFO_BITRATE0 0xf38400ff
2037
2038/*P2_ERRCTRL1*/
2039#define R0900_P2_ERRCTRL1 0xf398
2040#define F0900_P2_ERR_SOURCE1 0xf39800f0
2041#define F0900_P2_NUM_EVENT1 0xf3980007
2042
2043/*P2_ERRCNT12*/
2044#define R0900_P2_ERRCNT12 0xf399
2045#define F0900_P2_ERRCNT1_OLDVALUE 0xf3990080
2046#define F0900_P2_ERR_CNT12 0xf399007f
2047
2048/*P2_ERRCNT11*/
2049#define R0900_P2_ERRCNT11 0xf39a
2050#define F0900_P2_ERR_CNT11 0xf39a00ff
2051
2052/*P2_ERRCNT10*/
2053#define R0900_P2_ERRCNT10 0xf39b
2054#define F0900_P2_ERR_CNT10 0xf39b00ff
2055
2056/*P2_ERRCTRL2*/
2057#define R0900_P2_ERRCTRL2 0xf39c
2058#define F0900_P2_ERR_SOURCE2 0xf39c00f0
2059#define F0900_P2_NUM_EVENT2 0xf39c0007
2060
2061/*P2_ERRCNT22*/
2062#define R0900_P2_ERRCNT22 0xf39d
2063#define F0900_P2_ERRCNT2_OLDVALUE 0xf39d0080
2064#define F0900_P2_ERR_CNT22 0xf39d007f
2065
2066/*P2_ERRCNT21*/
2067#define R0900_P2_ERRCNT21 0xf39e
2068#define F0900_P2_ERR_CNT21 0xf39e00ff
2069
2070/*P2_ERRCNT20*/
2071#define R0900_P2_ERRCNT20 0xf39f
2072#define F0900_P2_ERR_CNT20 0xf39f00ff
2073
2074/*P2_FECSPY*/
2075#define R0900_P2_FECSPY 0xf3a0
2076#define F0900_P2_SPY_ENABLE 0xf3a00080
2077#define F0900_P2_NO_SYNCBYTE 0xf3a00040
2078#define F0900_P2_SERIAL_MODE 0xf3a00020
2079#define F0900_P2_UNUSUAL_PACKET 0xf3a00010
2080#define F0900_P2_BERMETER_DATAMODE 0xf3a00008
2081#define F0900_P2_BERMETER_LMODE 0xf3a00002
2082#define F0900_P2_BERMETER_RESET 0xf3a00001
2083
2084/*P2_FSPYCFG*/
2085#define R0900_P2_FSPYCFG 0xf3a1
2086#define F0900_P2_FECSPY_INPUT 0xf3a100c0
2087#define F0900_P2_RST_ON_ERROR 0xf3a10020
2088#define F0900_P2_ONE_SHOT 0xf3a10010
2089#define F0900_P2_I2C_MODE 0xf3a1000c
2090#define F0900_P2_SPY_HYSTERESIS 0xf3a10003
2091
2092/*P2_FSPYDATA*/
2093#define R0900_P2_FSPYDATA 0xf3a2
2094#define F0900_P2_SPY_STUFFING 0xf3a20080
2095#define F0900_P2_SPY_CNULLPKT 0xf3a20020
2096#define F0900_P2_SPY_OUTDATA_MODE 0xf3a2001f
2097
2098/*P2_FSPYOUT*/
2099#define R0900_P2_FSPYOUT 0xf3a3
2100#define F0900_P2_FSPY_DIRECT 0xf3a30080
2101#define F0900_P2_STUFF_MODE 0xf3a30007
2102
2103/*P2_FSTATUS*/
2104#define R0900_P2_FSTATUS 0xf3a4
2105#define F0900_P2_SPY_ENDSIM 0xf3a40080
2106#define F0900_P2_VALID_SIM 0xf3a40040
2107#define F0900_P2_FOUND_SIGNAL 0xf3a40020
2108#define F0900_P2_DSS_SYNCBYTE 0xf3a40010
2109#define F0900_P2_RESULT_STATE 0xf3a4000f
2110
2111/*P2_FBERCPT4*/
2112#define R0900_P2_FBERCPT4 0xf3a8
2113#define F0900_P2_FBERMETER_CPT4 0xf3a800ff
2114
2115/*P2_FBERCPT3*/
2116#define R0900_P2_FBERCPT3 0xf3a9
2117#define F0900_P2_FBERMETER_CPT3 0xf3a900ff
2118
2119/*P2_FBERCPT2*/
2120#define R0900_P2_FBERCPT2 0xf3aa
2121#define F0900_P2_FBERMETER_CPT2 0xf3aa00ff
2122
2123/*P2_FBERCPT1*/
2124#define R0900_P2_FBERCPT1 0xf3ab
2125#define F0900_P2_FBERMETER_CPT1 0xf3ab00ff
2126
2127/*P2_FBERCPT0*/
2128#define R0900_P2_FBERCPT0 0xf3ac
2129#define F0900_P2_FBERMETER_CPT0 0xf3ac00ff
2130
2131/*P2_FBERERR2*/
2132#define R0900_P2_FBERERR2 0xf3ad
2133#define F0900_P2_FBERMETER_ERR2 0xf3ad00ff
2134
2135/*P2_FBERERR1*/
2136#define R0900_P2_FBERERR1 0xf3ae
2137#define F0900_P2_FBERMETER_ERR1 0xf3ae00ff
2138
2139/*P2_FBERERR0*/
2140#define R0900_P2_FBERERR0 0xf3af
2141#define F0900_P2_FBERMETER_ERR0 0xf3af00ff
2142
2143/*P2_FSPYBER*/
2144#define R0900_P2_FSPYBER 0xf3b2
2145#define F0900_P2_FSPYBER_SYNCBYTE 0xf3b20010
2146#define F0900_P2_FSPYBER_UNSYNC 0xf3b20008
2147#define F0900_P2_FSPYBER_CTIME 0xf3b20007
2148
2149/*P1_IQCONST*/
2150#define R0900_P1_IQCONST 0xf400
2151#define IQCONST REGx(R0900_P1_IQCONST)
2152#define F0900_P1_CONSTEL_SELECT 0xf4000060
2153#define F0900_P1_IQSYMB_SEL 0xf400001f
2154
2155/*P1_NOSCFG*/
2156#define R0900_P1_NOSCFG 0xf401
2157#define NOSCFG REGx(R0900_P1_NOSCFG)
2158#define F0900_P1_DUMMYPL_NOSDATA 0xf4010020
2159#define F0900_P1_NOSPLH_BETA 0xf4010018
2160#define F0900_P1_NOSDATA_BETA 0xf4010007
2161
2162/*P1_ISYMB*/
2163#define R0900_P1_ISYMB 0xf402
2164#define ISYMB REGx(R0900_P1_ISYMB)
2165#define F0900_P1_I_SYMBOL 0xf40201ff
2166
2167/*P1_QSYMB*/
2168#define R0900_P1_QSYMB 0xf403
2169#define QSYMB REGx(R0900_P1_QSYMB)
2170#define F0900_P1_Q_SYMBOL 0xf40301ff
2171
2172/*P1_AGC1CFG*/
2173#define R0900_P1_AGC1CFG 0xf404
2174#define AGC1CFG REGx(R0900_P1_AGC1CFG)
2175#define F0900_P1_DC_FROZEN 0xf4040080
2176#define F0900_P1_DC_CORRECT 0xf4040040
2177#define F0900_P1_AMM_FROZEN 0xf4040020
2178#define F0900_P1_AMM_CORRECT 0xf4040010
2179#define F0900_P1_QUAD_FROZEN 0xf4040008
2180#define F0900_P1_QUAD_CORRECT 0xf4040004
2181
2182/*P1_AGC1CN*/
2183#define R0900_P1_AGC1CN 0xf406
2184#define AGC1CN REGx(R0900_P1_AGC1CN)
2185#define F0900_P1_AGC1_LOCKED 0xf4060080
2186#define F0900_P1_AGC1_MINPOWER 0xf4060010
2187#define F0900_P1_AGCOUT_FAST 0xf4060008
2188#define F0900_P1_AGCIQ_BETA 0xf4060007
2189
2190/*P1_AGC1REF*/
2191#define R0900_P1_AGC1REF 0xf407
2192#define AGC1REF REGx(R0900_P1_AGC1REF)
2193#define F0900_P1_AGCIQ_REF 0xf40700ff
2194
2195/*P1_IDCCOMP*/
2196#define R0900_P1_IDCCOMP 0xf408
2197#define IDCCOMP REGx(R0900_P1_IDCCOMP)
2198#define F0900_P1_IAVERAGE_ADJ 0xf40801ff
2199
2200/*P1_QDCCOMP*/
2201#define R0900_P1_QDCCOMP 0xf409
2202#define QDCCOMP REGx(R0900_P1_QDCCOMP)
2203#define F0900_P1_QAVERAGE_ADJ 0xf40901ff
2204
2205/*P1_POWERI*/
2206#define R0900_P1_POWERI 0xf40a
2207#define POWERI REGx(R0900_P1_POWERI)
2208#define F0900_P1_POWER_I 0xf40a00ff
2209#define POWER_I FLDx(F0900_P1_POWER_I)
2210
2211/*P1_POWERQ*/
2212#define R0900_P1_POWERQ 0xf40b
2213#define POWERQ REGx(R0900_P1_POWERQ)
2214#define F0900_P1_POWER_Q 0xf40b00ff
2215#define POWER_Q FLDx(F0900_P1_POWER_Q)
2216
2217/*P1_AGC1AMM*/
2218#define R0900_P1_AGC1AMM 0xf40c
2219#define AGC1AMM REGx(R0900_P1_AGC1AMM)
2220#define F0900_P1_AMM_VALUE 0xf40c00ff
2221
2222/*P1_AGC1QUAD*/
2223#define R0900_P1_AGC1QUAD 0xf40d
2224#define AGC1QUAD REGx(R0900_P1_AGC1QUAD)
2225#define F0900_P1_QUAD_VALUE 0xf40d01ff
2226
2227/*P1_AGCIQIN1*/
2228#define R0900_P1_AGCIQIN1 0xf40e
2229#define AGCIQIN1 REGx(R0900_P1_AGCIQIN1)
2230#define F0900_P1_AGCIQ_VALUE1 0xf40e00ff
2231#define AGCIQ_VALUE1 FLDx(F0900_P1_AGCIQ_VALUE1)
2232
2233/*P1_AGCIQIN0*/
2234#define R0900_P1_AGCIQIN0 0xf40f
2235#define AGCIQIN0 REGx(R0900_P1_AGCIQIN0)
2236#define F0900_P1_AGCIQ_VALUE0 0xf40f00ff
2237#define AGCIQ_VALUE0 FLDx(F0900_P1_AGCIQ_VALUE0)
2238
2239/*P1_DEMOD*/
2240#define R0900_P1_DEMOD 0xf410
2241#define DEMOD REGx(R0900_P1_DEMOD)
2242#define F0900_P1_MANUALS2_ROLLOFF 0xf4100080
2243#define MANUALS2_ROLLOFF FLDx(F0900_P1_MANUALS2_ROLLOFF)
2244
2245#define F0900_P1_SPECINV_CONTROL 0xf4100030
2246#define SPECINV_CONTROL FLDx(F0900_P1_SPECINV_CONTROL)
2247#define F0900_P1_FORCE_ENASAMP 0xf4100008
2248#define F0900_P1_MANUALSX_ROLLOFF 0xf4100004
2249#define MANUALSX_ROLLOFF FLDx(F0900_P1_MANUALSX_ROLLOFF)
2250#define F0900_P1_ROLLOFF_CONTROL 0xf4100003
2251#define ROLLOFF_CONTROL FLDx(F0900_P1_ROLLOFF_CONTROL)
2252
2253/*P1_DMDMODCOD*/
2254#define R0900_P1_DMDMODCOD 0xf411
2255#define DMDMODCOD REGx(R0900_P1_DMDMODCOD)
2256#define F0900_P1_MANUAL_MODCOD 0xf4110080
2257#define F0900_P1_DEMOD_MODCOD 0xf411007c
2258#define DEMOD_MODCOD FLDx(F0900_P1_DEMOD_MODCOD)
2259#define F0900_P1_DEMOD_TYPE 0xf4110003
2260#define DEMOD_TYPE FLDx(F0900_P1_DEMOD_TYPE)
2261
2262/*P1_DSTATUS*/
2263#define R0900_P1_DSTATUS 0xf412
2264#define DSTATUS REGx(R0900_P1_DSTATUS)
2265#define F0900_P1_CAR_LOCK 0xf4120080
2266#define F0900_P1_TMGLOCK_QUALITY 0xf4120060
2267#define TMGLOCK_QUALITY FLDx(F0900_P1_TMGLOCK_QUALITY)
2268#define F0900_P1_LOCK_DEFINITIF 0xf4120008
2269#define LOCK_DEFINITIF FLDx(F0900_P1_LOCK_DEFINITIF)
2270#define F0900_P1_OVADC_DETECT 0xf4120001
2271
2272/*P1_DSTATUS2*/
2273#define R0900_P1_DSTATUS2 0xf413
2274#define DSTATUS2 REGx(R0900_P1_DSTATUS2)
2275#define F0900_P1_DEMOD_DELOCK 0xf4130080
2276#define F0900_P1_AGC1_NOSIGNALACK 0xf4130008
2277#define F0900_P1_AGC2_OVERFLOW 0xf4130004
2278#define F0900_P1_CFR_OVERFLOW 0xf4130002
2279#define F0900_P1_GAMMA_OVERUNDER 0xf4130001
2280
2281/*P1_DMDCFGMD*/
2282#define R0900_P1_DMDCFGMD 0xf414
2283#define DMDCFGMD REGx(R0900_P1_DMDCFGMD)
2284#define F0900_P1_DVBS2_ENABLE 0xf4140080
2285#define DVBS2_ENABLE FLDx(F0900_P1_DVBS2_ENABLE)
2286#define F0900_P1_DVBS1_ENABLE 0xf4140040
2287#define DVBS1_ENABLE FLDx(F0900_P1_DVBS1_ENABLE)
2288#define F0900_P1_SCAN_ENABLE 0xf4140010
2289#define SCAN_ENABLE FLDx(F0900_P1_SCAN_ENABLE)
2290#define F0900_P1_CFR_AUTOSCAN 0xf4140008
2291#define CFR_AUTOSCAN FLDx(F0900_P1_CFR_AUTOSCAN)
2292#define F0900_P1_TUN_RNG 0xf4140003
2293
2294/*P1_DMDCFG2*/
2295#define R0900_P1_DMDCFG2 0xf415
2296#define DMDCFG2 REGx(R0900_P1_DMDCFG2)
2297#define F0900_P1_S1S2_SEQUENTIAL 0xf4150040
2298#define S1S2_SEQUENTIAL FLDx(F0900_P1_S1S2_SEQUENTIAL)
2299#define F0900_P1_INFINITE_RELOCK 0xf4150010
2300
2301/*P1_DMDISTATE*/
2302#define R0900_P1_DMDISTATE 0xf416
2303#define DMDISTATE REGx(R0900_P1_DMDISTATE)
2304#define F0900_P1_I2C_DEMOD_MODE 0xf416001f
2305#define DEMOD_MODE FLDx(F0900_P1_I2C_DEMOD_MODE)
2306
2307/*P1_DMDT0M*/
2308#define R0900_P1_DMDT0M 0xf417
2309#define DMDT0M REGx(R0900_P1_DMDT0M)
2310#define F0900_P1_DMDT0_MIN 0xf41700ff
2311
2312/*P1_DMDSTATE*/
2313#define R0900_P1_DMDSTATE 0xf41b
2314#define DMDSTATE REGx(R0900_P1_DMDSTATE)
2315#define F0900_P1_HEADER_MODE 0xf41b0060
2316#define HEADER_MODE FLDx(F0900_P1_HEADER_MODE)
2317
2318/*P1_DMDFLYW*/
2319#define R0900_P1_DMDFLYW 0xf41c
2320#define DMDFLYW REGx(R0900_P1_DMDFLYW)
2321#define F0900_P1_I2C_IRQVAL 0xf41c00f0
2322#define F0900_P1_FLYWHEEL_CPT 0xf41c000f
2323#define FLYWHEEL_CPT FLDx(F0900_P1_FLYWHEEL_CPT)
2324
2325/*P1_DSTATUS3*/
2326#define R0900_P1_DSTATUS3 0xf41d
2327#define DSTATUS3 REGx(R0900_P1_DSTATUS3)
2328#define F0900_P1_DEMOD_CFGMODE 0xf41d0060
2329
2330/*P1_DMDCFG3*/
2331#define R0900_P1_DMDCFG3 0xf41e
2332#define DMDCFG3 REGx(R0900_P1_DMDCFG3)
2333#define F0900_P1_NOSTOP_FIFOFULL 0xf41e0008
2334
2335/*P1_DMDCFG4*/
2336#define R0900_P1_DMDCFG4 0xf41f
2337#define DMDCFG4 REGx(R0900_P1_DMDCFG4)
2338#define F0900_P1_TUNER_NRELAUNCH 0xf41f0008
2339
2340/*P1_CORRELMANT*/
2341#define R0900_P1_CORRELMANT 0xf420
2342#define CORRELMANT REGx(R0900_P1_CORRELMANT)
2343#define F0900_P1_CORREL_MANT 0xf42000ff
2344
2345/*P1_CORRELABS*/
2346#define R0900_P1_CORRELABS 0xf421
2347#define CORRELABS REGx(R0900_P1_CORRELABS)
2348#define F0900_P1_CORREL_ABS 0xf42100ff
2349
2350/*P1_CORRELEXP*/
2351#define R0900_P1_CORRELEXP 0xf422
2352#define CORRELEXP REGx(R0900_P1_CORRELEXP)
2353#define F0900_P1_CORREL_ABSEXP 0xf42200f0
2354#define F0900_P1_CORREL_EXP 0xf422000f
2355
2356/*P1_PLHMODCOD*/
2357#define R0900_P1_PLHMODCOD 0xf424
2358#define PLHMODCOD REGx(R0900_P1_PLHMODCOD)
2359#define F0900_P1_SPECINV_DEMOD 0xf4240080
2360#define SPECINV_DEMOD FLDx(F0900_P1_SPECINV_DEMOD)
2361#define F0900_P1_PLH_MODCOD 0xf424007c
2362#define F0900_P1_PLH_TYPE 0xf4240003
2363
2364/*P1_DMDREG*/
2365#define R0900_P1_DMDREG 0xf425
2366#define DMDREG REGx(R0900_P1_DMDREG)
2367#define F0900_P1_DECIM_PLFRAMES 0xf4250001
2368
2369/*P1_AGC2O*/
2370#define R0900_P1_AGC2O 0xf42c
2371#define AGC2O REGx(R0900_P1_AGC2O)
2372#define F0900_P1_AGC2_COEF 0xf42c0007
2373
2374/*P1_AGC2REF*/
2375#define R0900_P1_AGC2REF 0xf42d
2376#define AGC2REF REGx(R0900_P1_AGC2REF)
2377#define F0900_P1_AGC2_REF 0xf42d00ff
2378
2379/*P1_AGC1ADJ*/
2380#define R0900_P1_AGC1ADJ 0xf42e
2381#define AGC1ADJ REGx(R0900_P1_AGC1ADJ)
2382#define F0900_P1_AGC1_ADJUSTED 0xf42e007f
2383
2384/*P1_AGC2I1*/
2385#define R0900_P1_AGC2I1 0xf436
2386#define AGC2I1 REGx(R0900_P1_AGC2I1)
2387#define F0900_P1_AGC2_INTEGRATOR1 0xf43600ff
2388
2389/*P1_AGC2I0*/
2390#define R0900_P1_AGC2I0 0xf437
2391#define AGC2I0 REGx(R0900_P1_AGC2I0)
2392#define F0900_P1_AGC2_INTEGRATOR0 0xf43700ff
2393
2394/*P1_CARCFG*/
2395#define R0900_P1_CARCFG 0xf438
2396#define CARCFG REGx(R0900_P1_CARCFG)
2397#define F0900_P1_CFRUPLOW_AUTO 0xf4380080
2398#define F0900_P1_CFRUPLOW_TEST 0xf4380040
2399#define F0900_P1_ROTAON 0xf4380004
2400#define F0900_P1_PH_DET_ALGO 0xf4380003
2401
2402/*P1_ACLC*/
2403#define R0900_P1_ACLC 0xf439
2404#define ACLC REGx(R0900_P1_ACLC)
2405#define F0900_P1_CAR_ALPHA_MANT 0xf4390030
2406#define F0900_P1_CAR_ALPHA_EXP 0xf439000f
2407
2408/*P1_BCLC*/
2409#define R0900_P1_BCLC 0xf43a
2410#define BCLC REGx(R0900_P1_BCLC)
2411#define F0900_P1_CAR_BETA_MANT 0xf43a0030
2412#define F0900_P1_CAR_BETA_EXP 0xf43a000f
2413
2414/*P1_CARFREQ*/
2415#define R0900_P1_CARFREQ 0xf43d
2416#define CARFREQ REGx(R0900_P1_CARFREQ)
2417#define F0900_P1_KC_COARSE_EXP 0xf43d00f0
2418#define F0900_P1_BETA_FREQ 0xf43d000f
2419
2420/*P1_CARHDR*/
2421#define R0900_P1_CARHDR 0xf43e
2422#define CARHDR REGx(R0900_P1_CARHDR)
2423#define F0900_P1_K_FREQ_HDR 0xf43e00ff
2424
2425/*P1_LDT*/
2426#define R0900_P1_LDT 0xf43f
2427#define LDT REGx(R0900_P1_LDT)
2428#define F0900_P1_CARLOCK_THRES 0xf43f01ff
2429
2430/*P1_LDT2*/
2431#define R0900_P1_LDT2 0xf440
2432#define LDT2 REGx(R0900_P1_LDT2)
2433#define F0900_P1_CARLOCK_THRES2 0xf44001ff
2434
2435/*P1_CFRICFG*/
2436#define R0900_P1_CFRICFG 0xf441
2437#define CFRICFG REGx(R0900_P1_CFRICFG)
2438#define F0900_P1_NEG_CFRSTEP 0xf4410001
2439
2440/*P1_CFRUP1*/
2441#define R0900_P1_CFRUP1 0xf442
2442#define CFRUP1 REGx(R0900_P1_CFRUP1)
2443#define F0900_P1_CFR_UP1 0xf44201ff
2444#define CFR_UP1 FLDx(F0900_P1_CFR_UP1)
2445
2446/*P1_CFRUP0*/
2447#define R0900_P1_CFRUP0 0xf443
2448#define CFRUP0 REGx(R0900_P1_CFRUP0)
2449#define F0900_P1_CFR_UP0 0xf44300ff
2450#define CFR_UP0 FLDx(F0900_P1_CFR_UP0)
2451
2452/*P1_CFRLOW1*/
2453#define R0900_P1_CFRLOW1 0xf446
2454#define CFRLOW1 REGx(R0900_P1_CFRLOW1)
2455#define F0900_P1_CFR_LOW1 0xf44601ff
2456#define CFR_LOW1 FLDx(F0900_P1_CFR_LOW1)
2457
2458/*P1_CFRLOW0*/
2459#define R0900_P1_CFRLOW0 0xf447
2460#define CFRLOW0 REGx(R0900_P1_CFRLOW0)
2461#define F0900_P1_CFR_LOW0 0xf44700ff
2462#define CFR_LOW0 FLDx(F0900_P1_CFR_LOW0)
2463
2464/*P1_CFRINIT1*/
2465#define R0900_P1_CFRINIT1 0xf448
2466#define CFRINIT1 REGx(R0900_P1_CFRINIT1)
2467#define F0900_P1_CFR_INIT1 0xf44801ff
2468#define CFR_INIT1 FLDx(F0900_P1_CFR_INIT1)
2469
2470/*P1_CFRINIT0*/
2471#define R0900_P1_CFRINIT0 0xf449
2472#define CFRINIT0 REGx(R0900_P1_CFRINIT0)
2473#define F0900_P1_CFR_INIT0 0xf44900ff
2474#define CFR_INIT0 FLDx(F0900_P1_CFR_INIT0)
2475
2476/*P1_CFRINC1*/
2477#define R0900_P1_CFRINC1 0xf44a
2478#define CFRINC1 REGx(R0900_P1_CFRINC1)
2479#define F0900_P1_MANUAL_CFRINC 0xf44a0080
2480#define F0900_P1_CFR_INC1 0xf44a003f
2481
2482/*P1_CFRINC0*/
2483#define R0900_P1_CFRINC0 0xf44b
2484#define CFRINC0 REGx(R0900_P1_CFRINC0)
2485#define F0900_P1_CFR_INC0 0xf44b00f8
2486
2487/*P1_CFR2*/
2488#define R0900_P1_CFR2 0xf44c
2489#define CFR2 REGx(R0900_P1_CFR2)
2490#define F0900_P1_CAR_FREQ2 0xf44c01ff
2491#define CAR_FREQ2 FLDx(F0900_P1_CAR_FREQ2)
2492
2493/*P1_CFR1*/
2494#define R0900_P1_CFR1 0xf44d
2495#define CFR1 REGx(R0900_P1_CFR1)
2496#define F0900_P1_CAR_FREQ1 0xf44d00ff
2497#define CAR_FREQ1 FLDx(F0900_P1_CAR_FREQ1)
2498
2499/*P1_CFR0*/
2500#define R0900_P1_CFR0 0xf44e
2501#define CFR0 REGx(R0900_P1_CFR0)
2502#define F0900_P1_CAR_FREQ0 0xf44e00ff
2503#define CAR_FREQ0 FLDx(F0900_P1_CAR_FREQ0)
2504
2505/*P1_LDI*/
2506#define R0900_P1_LDI 0xf44f
2507#define LDI REGx(R0900_P1_LDI)
2508#define F0900_P1_LOCK_DET_INTEGR 0xf44f01ff
2509
2510/*P1_TMGCFG*/
2511#define R0900_P1_TMGCFG 0xf450
2512#define TMGCFG REGx(R0900_P1_TMGCFG)
2513#define F0900_P1_TMGLOCK_BETA 0xf45000c0
2514#define F0900_P1_DO_TIMING_CORR 0xf4500010
2515#define F0900_P1_TMG_MINFREQ 0xf4500003
2516
2517/*P1_RTC*/
2518#define R0900_P1_RTC 0xf451
2519#define RTC REGx(R0900_P1_RTC)
2520#define F0900_P1_TMGALPHA_EXP 0xf45100f0
2521#define F0900_P1_TMGBETA_EXP 0xf451000f
2522
2523/*P1_RTCS2*/
2524#define R0900_P1_RTCS2 0xf452
2525#define RTCS2 REGx(R0900_P1_RTCS2)
2526#define F0900_P1_TMGALPHAS2_EXP 0xf45200f0
2527#define F0900_P1_TMGBETAS2_EXP 0xf452000f
2528
2529/*P1_TMGTHRISE*/
2530#define R0900_P1_TMGTHRISE 0xf453
2531#define TMGTHRISE REGx(R0900_P1_TMGTHRISE)
2532#define F0900_P1_TMGLOCK_THRISE 0xf45300ff
2533
2534/*P1_TMGTHFALL*/
2535#define R0900_P1_TMGTHFALL 0xf454
2536#define TMGTHFALL REGx(R0900_P1_TMGTHFALL)
2537#define F0900_P1_TMGLOCK_THFALL 0xf45400ff
2538
2539/*P1_SFRUPRATIO*/
2540#define R0900_P1_SFRUPRATIO 0xf455
2541#define SFRUPRATIO REGx(R0900_P1_SFRUPRATIO)
2542#define F0900_P1_SFR_UPRATIO 0xf45500ff
2543
2544/*P1_SFRLOWRATIO*/
2545#define R0900_P1_SFRLOWRATIO 0xf456
2546#define F0900_P1_SFR_LOWRATIO 0xf45600ff
2547
2548/*P1_KREFTMG*/
2549#define R0900_P1_KREFTMG 0xf458
2550#define KREFTMG REGx(R0900_P1_KREFTMG)
2551#define F0900_P1_KREF_TMG 0xf45800ff
2552
2553/*P1_SFRSTEP*/
2554#define R0900_P1_SFRSTEP 0xf459
2555#define SFRSTEP REGx(R0900_P1_SFRSTEP)
2556#define F0900_P1_SFR_SCANSTEP 0xf45900f0
2557#define F0900_P1_SFR_CENTERSTEP 0xf459000f
2558
2559/*P1_TMGCFG2*/
2560#define R0900_P1_TMGCFG2 0xf45a
2561#define TMGCFG2 REGx(R0900_P1_TMGCFG2)
2562#define F0900_P1_SFRRATIO_FINE 0xf45a0001
2563
2564/*P1_KREFTMG2*/
2565#define R0900_P1_KREFTMG2 0xf45b
2566#define KREFTMG2 REGx(R0900_P1_KREFTMG2)
2567#define F0900_P1_KREF_TMG2 0xf45b00ff
2568
2569/*P1_SFRINIT1*/
2570#define R0900_P1_SFRINIT1 0xf45e
2571#define SFRINIT1 REGx(R0900_P1_SFRINIT1)
2572#define F0900_P1_SFR_INIT1 0xf45e007f
2573
2574/*P1_SFRINIT0*/
2575#define R0900_P1_SFRINIT0 0xf45f
2576#define SFRINIT0 REGx(R0900_P1_SFRINIT0)
2577#define F0900_P1_SFR_INIT0 0xf45f00ff
2578
2579/*P1_SFRUP1*/
2580#define R0900_P1_SFRUP1 0xf460
2581#define SFRUP1 REGx(R0900_P1_SFRUP1)
2582#define F0900_P1_AUTO_GUP 0xf4600080
2583#define AUTO_GUP FLDx(F0900_P1_AUTO_GUP)
2584#define F0900_P1_SYMB_FREQ_UP1 0xf460007f
2585
2586/*P1_SFRUP0*/
2587#define R0900_P1_SFRUP0 0xf461
2588#define SFRUP0 REGx(R0900_P1_SFRUP0)
2589#define F0900_P1_SYMB_FREQ_UP0 0xf46100ff
2590
2591/*P1_SFRLOW1*/
2592#define R0900_P1_SFRLOW1 0xf462
2593#define SFRLOW1 REGx(R0900_P1_SFRLOW1)
2594#define F0900_P1_AUTO_GLOW 0xf4620080
2595#define AUTO_GLOW FLDx(F0900_P1_AUTO_GLOW)
2596#define F0900_P1_SYMB_FREQ_LOW1 0xf462007f
2597
2598/*P1_SFRLOW0*/
2599#define R0900_P1_SFRLOW0 0xf463
2600#define SFRLOW0 REGx(R0900_P1_SFRLOW0)
2601#define F0900_P1_SYMB_FREQ_LOW0 0xf46300ff
2602
2603/*P1_SFR3*/
2604#define R0900_P1_SFR3 0xf464
2605#define SFR3 REGx(R0900_P1_SFR3)
2606#define F0900_P1_SYMB_FREQ3 0xf46400ff
2607#define SYMB_FREQ3 FLDx(F0900_P1_SYMB_FREQ3)
2608
2609/*P1_SFR2*/
2610#define R0900_P1_SFR2 0xf465
2611#define SFR2 REGx(R0900_P1_SFR2)
2612#define F0900_P1_SYMB_FREQ2 0xf46500ff
2613#define SYMB_FREQ2 FLDx(F0900_P1_SYMB_FREQ2)
2614
2615/*P1_SFR1*/
2616#define R0900_P1_SFR1 0xf466
2617#define SFR1 REGx(R0900_P1_SFR1)
2618#define F0900_P1_SYMB_FREQ1 0xf46600ff
2619#define SYMB_FREQ1 FLDx(F0900_P1_SYMB_FREQ1)
2620
2621/*P1_SFR0*/
2622#define R0900_P1_SFR0 0xf467
2623#define SFR0 REGx(R0900_P1_SFR0)
2624#define F0900_P1_SYMB_FREQ0 0xf46700ff
2625#define SYMB_FREQ0 FLDx(F0900_P1_SYMB_FREQ0)
2626
2627/*P1_TMGREG2*/
2628#define R0900_P1_TMGREG2 0xf468
2629#define TMGREG2 REGx(R0900_P1_TMGREG2)
2630#define F0900_P1_TMGREG2 0xf46800ff
2631
2632/*P1_TMGREG1*/
2633#define R0900_P1_TMGREG1 0xf469
2634#define TMGREG1 REGx(R0900_P1_TMGREG1)
2635#define F0900_P1_TMGREG1 0xf46900ff
2636
2637/*P1_TMGREG0*/
2638#define R0900_P1_TMGREG0 0xf46a
2639#define TMGREG0 REGx(R0900_P1_TMGREG0)
2640#define F0900_P1_TMGREG0 0xf46a00ff
2641
2642/*P1_TMGLOCK1*/
2643#define R0900_P1_TMGLOCK1 0xf46b
2644#define TMGLOCK1 REGx(R0900_P1_TMGLOCK1)
2645#define F0900_P1_TMGLOCK_LEVEL1 0xf46b01ff
2646
2647/*P1_TMGLOCK0*/
2648#define R0900_P1_TMGLOCK0 0xf46c
2649#define TMGLOCK0 REGx(R0900_P1_TMGLOCK0)
2650#define F0900_P1_TMGLOCK_LEVEL0 0xf46c00ff
2651
2652/*P1_TMGOBS*/
2653#define R0900_P1_TMGOBS 0xf46d
2654#define TMGOBS REGx(R0900_P1_TMGOBS)
2655#define F0900_P1_ROLLOFF_STATUS 0xf46d00c0
2656#define ROLLOFF_STATUS FLDx(F0900_P1_ROLLOFF_STATUS)
2657
2658/*P1_EQUALCFG*/
2659#define R0900_P1_EQUALCFG 0xf46f
2660#define EQUALCFG REGx(R0900_P1_EQUALCFG)
2661#define F0900_P1_EQUAL_ON 0xf46f0040
2662#define F0900_P1_MU_EQUALDFE 0xf46f0007
2663
2664/*P1_EQUAI1*/
2665#define R0900_P1_EQUAI1 0xf470
2666#define EQUAI1 REGx(R0900_P1_EQUAI1)
2667#define F0900_P1_EQUA_ACCI1 0xf47001ff
2668
2669/*P1_EQUAQ1*/
2670#define R0900_P1_EQUAQ1 0xf471
2671#define EQUAQ1 REGx(R0900_P1_EQUAQ1)
2672#define F0900_P1_EQUA_ACCQ1 0xf47101ff
2673
2674/*P1_EQUAI2*/
2675#define R0900_P1_EQUAI2 0xf472
2676#define EQUAI2 REGx(R0900_P1_EQUAI2)
2677#define F0900_P1_EQUA_ACCI2 0xf47201ff
2678
2679/*P1_EQUAQ2*/
2680#define R0900_P1_EQUAQ2 0xf473
2681#define EQUAQ2 REGx(R0900_P1_EQUAQ2)
2682#define F0900_P1_EQUA_ACCQ2 0xf47301ff
2683
2684/*P1_EQUAI3*/
2685#define R0900_P1_EQUAI3 0xf474
2686#define EQUAI3 REGx(R0900_P1_EQUAI3)
2687#define F0900_P1_EQUA_ACCI3 0xf47401ff
2688
2689/*P1_EQUAQ3*/
2690#define R0900_P1_EQUAQ3 0xf475
2691#define EQUAQ3 REGx(R0900_P1_EQUAQ3)
2692#define F0900_P1_EQUA_ACCQ3 0xf47501ff
2693
2694/*P1_EQUAI4*/
2695#define R0900_P1_EQUAI4 0xf476
2696#define EQUAI4 REGx(R0900_P1_EQUAI4)
2697#define F0900_P1_EQUA_ACCI4 0xf47601ff
2698
2699/*P1_EQUAQ4*/
2700#define R0900_P1_EQUAQ4 0xf477
2701#define EQUAQ4 REGx(R0900_P1_EQUAQ4)
2702#define F0900_P1_EQUA_ACCQ4 0xf47701ff
2703
2704/*P1_EQUAI5*/
2705#define R0900_P1_EQUAI5 0xf478
2706#define EQUAI5 REGx(R0900_P1_EQUAI5)
2707#define F0900_P1_EQUA_ACCI5 0xf47801ff
2708
2709/*P1_EQUAQ5*/
2710#define R0900_P1_EQUAQ5 0xf479
2711#define EQUAQ5 REGx(R0900_P1_EQUAQ5)
2712#define F0900_P1_EQUA_ACCQ5 0xf47901ff
2713
2714/*P1_EQUAI6*/
2715#define R0900_P1_EQUAI6 0xf47a
2716#define EQUAI6 REGx(R0900_P1_EQUAI6)
2717#define F0900_P1_EQUA_ACCI6 0xf47a01ff
2718
2719/*P1_EQUAQ6*/
2720#define R0900_P1_EQUAQ6 0xf47b
2721#define EQUAQ6 REGx(R0900_P1_EQUAQ6)
2722#define F0900_P1_EQUA_ACCQ6 0xf47b01ff
2723
2724/*P1_EQUAI7*/
2725#define R0900_P1_EQUAI7 0xf47c
2726#define EQUAI7 REGx(R0900_P1_EQUAI7)
2727#define F0900_P1_EQUA_ACCI7 0xf47c01ff
2728
2729/*P1_EQUAQ7*/
2730#define R0900_P1_EQUAQ7 0xf47d
2731#define EQUAQ7 REGx(R0900_P1_EQUAQ7)
2732#define F0900_P1_EQUA_ACCQ7 0xf47d01ff
2733
2734/*P1_EQUAI8*/
2735#define R0900_P1_EQUAI8 0xf47e
2736#define EQUAI8 REGx(R0900_P1_EQUAI8)
2737#define F0900_P1_EQUA_ACCI8 0xf47e01ff
2738
2739/*P1_EQUAQ8*/
2740#define R0900_P1_EQUAQ8 0xf47f
2741#define EQUAQ8 REGx(R0900_P1_EQUAQ8)
2742#define F0900_P1_EQUA_ACCQ8 0xf47f01ff
2743
2744/*P1_NNOSDATAT1*/
2745#define R0900_P1_NNOSDATAT1 0xf480
2746#define NNOSDATAT1 REGx(R0900_P1_NNOSDATAT1)
2747#define F0900_P1_NOSDATAT_NORMED1 0xf48000ff
2748#define NOSDATAT_NORMED1 FLDx(F0900_P1_NOSDATAT_NORMED1)
2749
2750/*P1_NNOSDATAT0*/
2751#define R0900_P1_NNOSDATAT0 0xf481
2752#define NNOSDATAT0 REGx(R0900_P1_NNOSDATAT0)
2753#define F0900_P1_NOSDATAT_NORMED0 0xf48100ff
2754#define NOSDATAT_NORMED0 FLDx(F0900_P1_NOSDATAT_NORMED0)
2755
2756/*P1_NNOSDATA1*/
2757#define R0900_P1_NNOSDATA1 0xf482
2758#define NNOSDATA1 REGx(R0900_P1_NNOSDATA1)
2759#define F0900_P1_NOSDATA_NORMED1 0xf48200ff
2760
2761/*P1_NNOSDATA0*/
2762#define R0900_P1_NNOSDATA0 0xf483
2763#define NNOSDATA0 REGx(R0900_P1_NNOSDATA0)
2764#define F0900_P1_NOSDATA_NORMED0 0xf48300ff
2765
2766/*P1_NNOSPLHT1*/
2767#define R0900_P1_NNOSPLHT1 0xf484
2768#define NNOSPLHT1 REGx(R0900_P1_NNOSPLHT1)
2769#define F0900_P1_NOSPLHT_NORMED1 0xf48400ff
2770#define NOSPLHT_NORMED1 FLDx(F0900_P1_NOSPLHT_NORMED1)
2771
2772/*P1_NNOSPLHT0*/
2773#define R0900_P1_NNOSPLHT0 0xf485
2774#define NNOSPLHT0 REGx(R0900_P1_NNOSPLHT0)
2775#define F0900_P1_NOSPLHT_NORMED0 0xf48500ff
2776#define NOSPLHT_NORMED0 FLDx(F0900_P1_NOSPLHT_NORMED0)
2777
2778/*P1_NNOSPLH1*/
2779#define R0900_P1_NNOSPLH1 0xf486
2780#define NNOSPLH1 REGx(R0900_P1_NNOSPLH1)
2781#define F0900_P1_NOSPLH_NORMED1 0xf48600ff
2782
2783/*P1_NNOSPLH0*/
2784#define R0900_P1_NNOSPLH0 0xf487
2785#define NNOSPLH0 REGx(R0900_P1_NNOSPLH0)
2786#define F0900_P1_NOSPLH_NORMED0 0xf48700ff
2787
2788/*P1_NOSDATAT1*/
2789#define R0900_P1_NOSDATAT1 0xf488
2790#define NOSDATAT1 REGx(R0900_P1_NOSDATAT1)
2791#define F0900_P1_NOSDATAT_UNNORMED1 0xf48800ff
2792
2793/*P1_NOSDATAT0*/
2794#define R0900_P1_NOSDATAT0 0xf489
2795#define NOSDATAT0 REGx(R0900_P1_NOSDATAT0)
2796#define F0900_P1_NOSDATAT_UNNORMED0 0xf48900ff
2797
2798/*P1_NOSDATA1*/
2799#define R0900_P1_NOSDATA1 0xf48a
2800#define NOSDATA1 REGx(R0900_P1_NOSDATA1)
2801#define F0900_P1_NOSDATA_UNNORMED1 0xf48a00ff
2802
2803/*P1_NOSDATA0*/
2804#define R0900_P1_NOSDATA0 0xf48b
2805#define NOSDATA0 REGx(R0900_P1_NOSDATA0)
2806#define F0900_P1_NOSDATA_UNNORMED0 0xf48b00ff
2807
2808/*P1_NOSPLHT1*/
2809#define R0900_P1_NOSPLHT1 0xf48c
2810#define NOSPLHT1 REGx(R0900_P1_NOSPLHT1)
2811#define F0900_P1_NOSPLHT_UNNORMED1 0xf48c00ff
2812
2813/*P1_NOSPLHT0*/
2814#define R0900_P1_NOSPLHT0 0xf48d
2815#define NOSPLHT0 REGx(R0900_P1_NOSPLHT0)
2816#define F0900_P1_NOSPLHT_UNNORMED0 0xf48d00ff
2817
2818/*P1_NOSPLH1*/
2819#define R0900_P1_NOSPLH1 0xf48e
2820#define NOSPLH1 REGx(R0900_P1_NOSPLH1)
2821#define F0900_P1_NOSPLH_UNNORMED1 0xf48e00ff
2822
2823/*P1_NOSPLH0*/
2824#define R0900_P1_NOSPLH0 0xf48f
2825#define NOSPLH0 REGx(R0900_P1_NOSPLH0)
2826#define F0900_P1_NOSPLH_UNNORMED0 0xf48f00ff
2827
2828/*P1_CAR2CFG*/
2829#define R0900_P1_CAR2CFG 0xf490
2830#define CAR2CFG REGx(R0900_P1_CAR2CFG)
2831#define F0900_P1_CARRIER3_DISABLE 0xf4900040
2832#define F0900_P1_ROTA2ON 0xf4900004
2833#define F0900_P1_PH_DET_ALGO2 0xf4900003
2834
2835/*P1_CFR2CFR1*/
2836#define R0900_P1_CFR2CFR1 0xf491
2837#define CFR2CFR1 REGx(R0900_P1_CFR2CFR1)
2838#define F0900_P1_CFR2TOCFR1_DVBS1 0xf49100c0
2839#define F0900_P1_EN_S2CAR2CENTER 0xf4910020
2840#define F0900_P1_DIS_BCHERRCFR2 0xf4910010
2841#define F0900_P1_CFR2TOCFR1_BETA 0xf4910007
2842
2843/*P1_CFR22*/
2844#define R0900_P1_CFR22 0xf493
2845#define CFR22 REGx(R0900_P1_CFR22)
2846#define F0900_P1_CAR2_FREQ2 0xf49301ff
2847
2848/*P1_CFR21*/
2849#define R0900_P1_CFR21 0xf494
2850#define CFR21 REGx(R0900_P1_CFR21)
2851#define F0900_P1_CAR2_FREQ1 0xf49400ff
2852
2853/*P1_CFR20*/
2854#define R0900_P1_CFR20 0xf495
2855#define CFR20 REGx(R0900_P1_CFR20)
2856#define F0900_P1_CAR2_FREQ0 0xf49500ff
2857
2858/*P1_ACLC2S2Q*/
2859#define R0900_P1_ACLC2S2Q 0xf497
2860#define ACLC2S2Q REGx(R0900_P1_ACLC2S2Q)
2861#define F0900_P1_ENAB_SPSKSYMB 0xf4970080
2862#define F0900_P1_CAR2S2_Q_ALPH_M 0xf4970030
2863#define F0900_P1_CAR2S2_Q_ALPH_E 0xf497000f
2864
2865/*P1_ACLC2S28*/
2866#define R0900_P1_ACLC2S28 0xf498
2867#define ACLC2S28 REGx(R0900_P1_ACLC2S28)
2868#define F0900_P1_OLDI3Q_MODE 0xf4980080
2869#define F0900_P1_CAR2S2_8_ALPH_M 0xf4980030
2870#define F0900_P1_CAR2S2_8_ALPH_E 0xf498000f
2871
2872/*P1_ACLC2S216A*/
2873#define R0900_P1_ACLC2S216A 0xf499
2874#define ACLC2S216A REGx(R0900_P1_ACLC2S216A)
2875#define F0900_P1_DIS_C3STOPA2 0xf4990080
2876#define F0900_P1_CAR2S2_16ADERAT 0xf4990040
2877#define F0900_P1_CAR2S2_16A_ALPH_M 0xf4990030
2878#define F0900_P1_CAR2S2_16A_ALPH_E 0xf499000f
2879
2880/*P1_ACLC2S232A*/
2881#define R0900_P1_ACLC2S232A 0xf49a
2882#define ACLC2S232A REGx(R0900_P1_ACLC2S232A)
2883#define F0900_P1_CAR2S2_32ADERAT 0xf49a0040
2884#define F0900_P1_CAR2S2_32A_ALPH_M 0xf49a0030
2885#define F0900_P1_CAR2S2_32A_ALPH_E 0xf49a000f
2886
2887/*P1_BCLC2S2Q*/
2888#define R0900_P1_BCLC2S2Q 0xf49c
2889#define BCLC2S2Q REGx(R0900_P1_BCLC2S2Q)
2890#define F0900_P1_CAR2S2_Q_BETA_M 0xf49c0030
2891#define F0900_P1_CAR2S2_Q_BETA_E 0xf49c000f
2892
2893/*P1_BCLC2S28*/
2894#define R0900_P1_BCLC2S28 0xf49d
2895#define BCLC2S28 REGx(R0900_P1_BCLC2S28)
2896#define F0900_P1_CAR2S2_8_BETA_M 0xf49d0030
2897#define F0900_P1_CAR2S2_8_BETA_E 0xf49d000f
2898
2899/*P1_BCLC2S216A*/
2900#define R0900_P1_BCLC2S216A 0xf49e
2901#define BCLC2S216A REGx(R0900_P1_BCLC2S216A)
2902
2903/*P1_BCLC2S232A*/
2904#define R0900_P1_BCLC2S232A 0xf49f
2905#define BCLC2S232A REGx(R0900_P1_BCLC2S232A)
2906
2907/*P1_PLROOT2*/
2908#define R0900_P1_PLROOT2 0xf4ac
2909#define PLROOT2 REGx(R0900_P1_PLROOT2)
2910#define F0900_P1_PLSCRAMB_MODE 0xf4ac000c
2911#define F0900_P1_PLSCRAMB_ROOT2 0xf4ac0003
2912
2913/*P1_PLROOT1*/
2914#define R0900_P1_PLROOT1 0xf4ad
2915#define PLROOT1 REGx(R0900_P1_PLROOT1)
2916#define F0900_P1_PLSCRAMB_ROOT1 0xf4ad00ff
2917
2918/*P1_PLROOT0*/
2919#define R0900_P1_PLROOT0 0xf4ae
2920#define PLROOT0 REGx(R0900_P1_PLROOT0)
2921#define F0900_P1_PLSCRAMB_ROOT0 0xf4ae00ff
2922
2923/*P1_MODCODLST0*/
2924#define R0900_P1_MODCODLST0 0xf4b0
2925#define MODCODLST0 REGx(R0900_P1_MODCODLST0)
2926
2927/*P1_MODCODLST1*/
2928#define R0900_P1_MODCODLST1 0xf4b1
2929#define MODCODLST1 REGx(R0900_P1_MODCODLST1)
2930#define F0900_P1_DIS_MODCOD29 0xf4b100f0
2931#define F0900_P1_DIS_32PSK_9_10 0xf4b1000f
2932
2933/*P1_MODCODLST2*/
2934#define R0900_P1_MODCODLST2 0xf4b2
2935#define MODCODLST2 REGx(R0900_P1_MODCODLST2)
2936#define F0900_P1_DIS_32PSK_8_9 0xf4b200f0
2937#define F0900_P1_DIS_32PSK_5_6 0xf4b2000f
2938
2939/*P1_MODCODLST3*/
2940#define R0900_P1_MODCODLST3 0xf4b3
2941#define MODCODLST3 REGx(R0900_P1_MODCODLST3)
2942#define F0900_P1_DIS_32PSK_4_5 0xf4b300f0
2943#define F0900_P1_DIS_32PSK_3_4 0xf4b3000f
2944
2945/*P1_MODCODLST4*/
2946#define R0900_P1_MODCODLST4 0xf4b4
2947#define MODCODLST4 REGx(R0900_P1_MODCODLST4)
2948#define F0900_P1_DIS_16PSK_9_10 0xf4b400f0
2949#define F0900_P1_DIS_16PSK_8_9 0xf4b4000f
2950
2951/*P1_MODCODLST5*/
2952#define R0900_P1_MODCODLST5 0xf4b5
2953#define MODCODLST5 REGx(R0900_P1_MODCODLST5)
2954#define F0900_P1_DIS_16PSK_5_6 0xf4b500f0
2955#define F0900_P1_DIS_16PSK_4_5 0xf4b5000f
2956
2957/*P1_MODCODLST6*/
2958#define R0900_P1_MODCODLST6 0xf4b6
2959#define MODCODLST6 REGx(R0900_P1_MODCODLST6)
2960#define F0900_P1_DIS_16PSK_3_4 0xf4b600f0
2961#define F0900_P1_DIS_16PSK_2_3 0xf4b6000f
2962
2963/*P1_MODCODLST7*/
2964#define R0900_P1_MODCODLST7 0xf4b7
2965#define MODCODLST7 REGx(R0900_P1_MODCODLST7)
2966#define F0900_P1_DIS_8P_9_10 0xf4b700f0
2967#define F0900_P1_DIS_8P_8_9 0xf4b7000f
2968
2969/*P1_MODCODLST8*/
2970#define R0900_P1_MODCODLST8 0xf4b8
2971#define MODCODLST8 REGx(R0900_P1_MODCODLST8)
2972#define F0900_P1_DIS_8P_5_6 0xf4b800f0
2973#define F0900_P1_DIS_8P_3_4 0xf4b8000f
2974
2975/*P1_MODCODLST9*/
2976#define R0900_P1_MODCODLST9 0xf4b9
2977#define MODCODLST9 REGx(R0900_P1_MODCODLST9)
2978#define F0900_P1_DIS_8P_2_3 0xf4b900f0
2979#define F0900_P1_DIS_8P_3_5 0xf4b9000f
2980
2981/*P1_MODCODLSTA*/
2982#define R0900_P1_MODCODLSTA 0xf4ba
2983#define MODCODLSTA REGx(R0900_P1_MODCODLSTA)
2984#define F0900_P1_DIS_QP_9_10 0xf4ba00f0
2985#define F0900_P1_DIS_QP_8_9 0xf4ba000f
2986
2987/*P1_MODCODLSTB*/
2988#define R0900_P1_MODCODLSTB 0xf4bb
2989#define MODCODLSTB REGx(R0900_P1_MODCODLSTB)
2990#define F0900_P1_DIS_QP_5_6 0xf4bb00f0
2991#define F0900_P1_DIS_QP_4_5 0xf4bb000f
2992
2993/*P1_MODCODLSTC*/
2994#define R0900_P1_MODCODLSTC 0xf4bc
2995#define MODCODLSTC REGx(R0900_P1_MODCODLSTC)
2996#define F0900_P1_DIS_QP_3_4 0xf4bc00f0
2997#define F0900_P1_DIS_QP_2_3 0xf4bc000f
2998
2999/*P1_MODCODLSTD*/
3000#define R0900_P1_MODCODLSTD 0xf4bd
3001#define MODCODLSTD REGx(R0900_P1_MODCODLSTD)
3002#define F0900_P1_DIS_QP_3_5 0xf4bd00f0
3003#define F0900_P1_DIS_QP_1_2 0xf4bd000f
3004
3005/*P1_MODCODLSTE*/
3006#define R0900_P1_MODCODLSTE 0xf4be
3007#define MODCODLSTE REGx(R0900_P1_MODCODLSTE)
3008#define F0900_P1_DIS_QP_2_5 0xf4be00f0
3009#define F0900_P1_DIS_QP_1_3 0xf4be000f
3010
3011/*P1_MODCODLSTF*/
3012#define R0900_P1_MODCODLSTF 0xf4bf
3013#define MODCODLSTF REGx(R0900_P1_MODCODLSTF)
3014#define F0900_P1_DIS_QP_1_4 0xf4bf00f0
3015
3016/*P1_GAUSSR0*/
3017#define R0900_P1_GAUSSR0 0xf4c0
3018#define GAUSSR0 REGx(R0900_P1_GAUSSR0)
3019#define F0900_P1_EN_CCIMODE 0xf4c00080
3020#define F0900_P1_R0_GAUSSIEN 0xf4c0007f
3021
3022/*P1_CCIR0*/
3023#define R0900_P1_CCIR0 0xf4c1
3024#define CCIR0 REGx(R0900_P1_CCIR0)
3025#define F0900_P1_CCIDETECT_PLHONLY 0xf4c10080
3026#define F0900_P1_R0_CCI 0xf4c1007f
3027
3028/*P1_CCIQUANT*/
3029#define R0900_P1_CCIQUANT 0xf4c2
3030#define CCIQUANT REGx(R0900_P1_CCIQUANT)
3031#define F0900_P1_CCI_BETA 0xf4c200e0
3032#define F0900_P1_CCI_QUANT 0xf4c2001f
3033
3034/*P1_CCITHRES*/
3035#define R0900_P1_CCITHRES 0xf4c3
3036#define CCITHRES REGx(R0900_P1_CCITHRES)
3037#define F0900_P1_CCI_THRESHOLD 0xf4c300ff
3038
3039/*P1_CCIACC*/
3040#define R0900_P1_CCIACC 0xf4c4
3041#define CCIACC REGx(R0900_P1_CCIACC)
3042#define F0900_P1_CCI_VALUE 0xf4c400ff
3043
3044/*P1_DMDRESCFG*/
3045#define R0900_P1_DMDRESCFG 0xf4c6
3046#define DMDRESCFG REGx(R0900_P1_DMDRESCFG)
3047#define F0900_P1_DMDRES_RESET 0xf4c60080
3048#define F0900_P1_DMDRES_STRALL 0xf4c60008
3049#define F0900_P1_DMDRES_NEWONLY 0xf4c60004
3050#define F0900_P1_DMDRES_NOSTORE 0xf4c60002
3051
3052/*P1_DMDRESADR*/
3053#define R0900_P1_DMDRESADR 0xf4c7
3054#define DMDRESADR REGx(R0900_P1_DMDRESADR)
3055#define F0900_P1_DMDRES_VALIDCFR 0xf4c70040
3056#define F0900_P1_DMDRES_MEMFULL 0xf4c70030
3057#define F0900_P1_DMDRES_RESNBR 0xf4c7000f
3058
3059/*P1_DMDRESDATA7*/
3060#define R0900_P1_DMDRESDATA7 0xf4c8
3061#define F0900_P1_DMDRES_DATA7 0xf4c800ff
3062
3063/*P1_DMDRESDATA6*/
3064#define R0900_P1_DMDRESDATA6 0xf4c9
3065#define F0900_P1_DMDRES_DATA6 0xf4c900ff
3066
3067/*P1_DMDRESDATA5*/
3068#define R0900_P1_DMDRESDATA5 0xf4ca
3069#define F0900_P1_DMDRES_DATA5 0xf4ca00ff
3070
3071/*P1_DMDRESDATA4*/
3072#define R0900_P1_DMDRESDATA4 0xf4cb
3073#define F0900_P1_DMDRES_DATA4 0xf4cb00ff
3074
3075/*P1_DMDRESDATA3*/
3076#define R0900_P1_DMDRESDATA3 0xf4cc
3077#define F0900_P1_DMDRES_DATA3 0xf4cc00ff
3078
3079/*P1_DMDRESDATA2*/
3080#define R0900_P1_DMDRESDATA2 0xf4cd
3081#define F0900_P1_DMDRES_DATA2 0xf4cd00ff
3082
3083/*P1_DMDRESDATA1*/
3084#define R0900_P1_DMDRESDATA1 0xf4ce
3085#define F0900_P1_DMDRES_DATA1 0xf4ce00ff
3086
3087/*P1_DMDRESDATA0*/
3088#define R0900_P1_DMDRESDATA0 0xf4cf
3089#define F0900_P1_DMDRES_DATA0 0xf4cf00ff
3090
3091/*P1_FFEI1*/
3092#define R0900_P1_FFEI1 0xf4d0
3093#define FFEI1 REGx(R0900_P1_FFEI1)
3094#define F0900_P1_FFE_ACCI1 0xf4d001ff
3095
3096/*P1_FFEQ1*/
3097#define R0900_P1_FFEQ1 0xf4d1
3098#define FFEQ1 REGx(R0900_P1_FFEQ1)
3099#define F0900_P1_FFE_ACCQ1 0xf4d101ff
3100
3101/*P1_FFEI2*/
3102#define R0900_P1_FFEI2 0xf4d2
3103#define FFEI2 REGx(R0900_P1_FFEI2)
3104#define F0900_P1_FFE_ACCI2 0xf4d201ff
3105
3106/*P1_FFEQ2*/
3107#define R0900_P1_FFEQ2 0xf4d3
3108#define FFEQ2 REGx(R0900_P1_FFEQ2)
3109#define F0900_P1_FFE_ACCQ2 0xf4d301ff
3110
3111/*P1_FFEI3*/
3112#define R0900_P1_FFEI3 0xf4d4
3113#define FFEI3 REGx(R0900_P1_FFEI3)
3114#define F0900_P1_FFE_ACCI3 0xf4d401ff
3115
3116/*P1_FFEQ3*/
3117#define R0900_P1_FFEQ3 0xf4d5
3118#define FFEQ3 REGx(R0900_P1_FFEQ3)
3119#define F0900_P1_FFE_ACCQ3 0xf4d501ff
3120
3121/*P1_FFEI4*/
3122#define R0900_P1_FFEI4 0xf4d6
3123#define FFEI4 REGx(R0900_P1_FFEI4)
3124#define F0900_P1_FFE_ACCI4 0xf4d601ff
3125
3126/*P1_FFEQ4*/
3127#define R0900_P1_FFEQ4 0xf4d7
3128#define FFEQ4 REGx(R0900_P1_FFEQ4)
3129#define F0900_P1_FFE_ACCQ4 0xf4d701ff
3130
3131/*P1_FFECFG*/
3132#define R0900_P1_FFECFG 0xf4d8
3133#define FFECFG REGx(R0900_P1_FFECFG)
3134#define F0900_P1_EQUALFFE_ON 0xf4d80040
3135#define F0900_P1_MU_EQUALFFE 0xf4d80007
3136
3137/*P1_TNRCFG*/
3138#define R0900_P1_TNRCFG 0xf4e0
3139#define TNRCFG REGx(R0900_P1_TNRCFG)
3140#define F0900_P1_TUN_ACKFAIL 0xf4e00080
3141#define F0900_P1_TUN_TYPE 0xf4e00070
3142#define F0900_P1_TUN_SECSTOP 0xf4e00008
3143#define F0900_P1_TUN_VCOSRCH 0xf4e00004
3144#define F0900_P1_TUN_MADDRESS 0xf4e00003
3145
3146/*P1_TNRCFG2*/
3147#define R0900_P1_TNRCFG2 0xf4e1
3148#define TNRCFG2 REGx(R0900_P1_TNRCFG2)
3149#define F0900_P1_TUN_IQSWAP 0xf4e10080
3150#define F0900_P1_DIS_BWCALC 0xf4e10004
3151#define F0900_P1_SHORT_WAITSTATES 0xf4e10002
3152
3153/*P1_TNRXTAL*/
3154#define R0900_P1_TNRXTAL 0xf4e4
3155#define TNRXTAL REGx(R0900_P1_TNRXTAL)
3156#define F0900_P1_TUN_XTALFREQ 0xf4e4001f
3157
3158/*P1_TNRSTEPS*/
3159#define R0900_P1_TNRSTEPS 0xf4e7
3160#define TNRSTEPS REGx(R0900_P1_TNRSTEPS)
3161#define F0900_P1_TUNER_BW0P125 0xf4e70080
3162#define F0900_P1_BWINC_OFFSET 0xf4e70170
3163#define F0900_P1_SOFTSTEP_RNG 0xf4e70008
3164#define F0900_P1_TUN_BWOFFSET 0xf4e70007
3165
3166/*P1_TNRGAIN*/
3167#define R0900_P1_TNRGAIN 0xf4e8
3168#define TNRGAIN REGx(R0900_P1_TNRGAIN)
3169#define F0900_P1_TUN_KDIVEN 0xf4e800c0
3170#define F0900_P1_STB6X00_OCK 0xf4e80030
3171#define F0900_P1_TUN_GAIN 0xf4e8000f
3172
3173/*P1_TNRRF1*/
3174#define R0900_P1_TNRRF1 0xf4e9
3175#define TNRRF1 REGx(R0900_P1_TNRRF1)
3176#define F0900_P1_TUN_RFFREQ2 0xf4e900ff
3177#define TUN_RFFREQ2 FLDx(F0900_P1_TUN_RFFREQ2)
3178
3179/*P1_TNRRF0*/
3180#define R0900_P1_TNRRF0 0xf4ea
3181#define TNRRF0 REGx(R0900_P1_TNRRF0)
3182#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff
3183#define TUN_RFFREQ1 FLDx(F0900_P1_TUN_RFFREQ1)
3184
3185/*P1_TNRBW*/
3186#define R0900_P1_TNRBW 0xf4eb
3187#define TNRBW REGx(R0900_P1_TNRBW)
3188#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0
3189#define TUN_RFFREQ0 FLDx(F0900_P1_TUN_RFFREQ0)
3190#define F0900_P1_TUN_BW 0xf4eb003f
3191#define TUN_BW FLDx(F0900_P1_TUN_BW)
3192
3193/*P1_TNRADJ*/
3194#define R0900_P1_TNRADJ 0xf4ec
3195#define TNRADJ REGx(R0900_P1_TNRADJ)
3196#define F0900_P1_STB61X0_CALTIME 0xf4ec0040
3197
3198/*P1_TNRCTL2*/
3199#define R0900_P1_TNRCTL2 0xf4ed
3200#define TNRCTL2 REGx(R0900_P1_TNRCTL2)
3201#define F0900_P1_STB61X0_RCCKOFF 0xf4ed0080
3202#define F0900_P1_STB61X0_ICP_SDOFF 0xf4ed0040
3203#define F0900_P1_STB61X0_DCLOOPOFF 0xf4ed0020
3204#define F0900_P1_STB61X0_REFOUTSEL 0xf4ed0010
3205#define F0900_P1_STB61X0_CALOFF 0xf4ed0008
3206#define F0900_P1_STB6XX0_LPT_BEN 0xf4ed0004
3207#define F0900_P1_STB6XX0_RX_OSCP 0xf4ed0002
3208#define F0900_P1_STB6XX0_SYN 0xf4ed0001
3209
3210/*P1_TNRCFG3*/
3211#define R0900_P1_TNRCFG3 0xf4ee
3212#define TNRCFG3 REGx(R0900_P1_TNRCFG3)
3213#define F0900_P1_TUN_PLLFREQ 0xf4ee001c
3214#define F0900_P1_TUN_I2CFREQ_MODE 0xf4ee0003
3215
3216/*P1_TNRLAUNCH*/
3217#define R0900_P1_TNRLAUNCH 0xf4f0
3218#define TNRLAUNCH REGx(R0900_P1_TNRLAUNCH)
3219
3220/*P1_TNRLD*/
3221#define R0900_P1_TNRLD 0xf4f0
3222#define TNRLD REGx(R0900_P1_TNRLD)
3223#define F0900_P1_TUNLD_VCOING 0xf4f00080
3224#define F0900_P1_TUN_REG1FAIL 0xf4f00040
3225#define F0900_P1_TUN_REG2FAIL 0xf4f00020
3226#define F0900_P1_TUN_REG3FAIL 0xf4f00010
3227#define F0900_P1_TUN_REG4FAIL 0xf4f00008
3228#define F0900_P1_TUN_REG5FAIL 0xf4f00004
3229#define F0900_P1_TUN_BWING 0xf4f00002
3230#define F0900_P1_TUN_LOCKED 0xf4f00001
3231
3232/*P1_TNROBSL*/
3233#define R0900_P1_TNROBSL 0xf4f6
3234#define TNROBSL REGx(R0900_P1_TNROBSL)
3235#define F0900_P1_TUN_I2CABORTED 0xf4f60080
3236#define F0900_P1_TUN_LPEN 0xf4f60040
3237#define F0900_P1_TUN_FCCK 0xf4f60020
3238#define F0900_P1_TUN_I2CLOCKED 0xf4f60010
3239#define F0900_P1_TUN_PROGDONE 0xf4f6000c
3240#define F0900_P1_TUN_RFRESTE1 0xf4f60003
3241#define TUN_RFRESTE1 FLDx(F0900_P1_TUN_RFRESTE1)
3242
3243/*P1_TNRRESTE*/
3244#define R0900_P1_TNRRESTE 0xf4f7
3245#define TNRRESTE REGx(R0900_P1_TNRRESTE)
3246#define F0900_P1_TUN_RFRESTE0 0xf4f700ff
3247#define TUN_RFRESTE0 FLDx(F0900_P1_TUN_RFRESTE0)
3248
3249/*P1_SMAPCOEF7*/
3250#define R0900_P1_SMAPCOEF7 0xf500
3251#define SMAPCOEF7 REGx(R0900_P1_SMAPCOEF7)
3252#define F0900_P1_DIS_QSCALE 0xf5000080
3253#define F0900_P1_SMAPCOEF_Q_LLR12 0xf500017f
3254
3255/*P1_SMAPCOEF6*/
3256#define R0900_P1_SMAPCOEF6 0xf501
3257#define SMAPCOEF6 REGx(R0900_P1_SMAPCOEF6)
3258#define F0900_P1_ADJ_8PSKLLR1 0xf5010004
3259#define F0900_P1_OLD_8PSKLLR1 0xf5010002
3260#define F0900_P1_DIS_AB8PSK 0xf5010001
3261
3262/*P1_SMAPCOEF5*/
3263#define R0900_P1_SMAPCOEF5 0xf502
3264#define SMAPCOEF5 REGx(R0900_P1_SMAPCOEF5)
3265#define F0900_P1_DIS_8SCALE 0xf5020080
3266#define F0900_P1_SMAPCOEF_8P_LLR23 0xf502017f
3267
3268/*P1_NCO2MAX1*/
3269#define R0900_P1_NCO2MAX1 0xf514
3270#define NCO2MAX1 REGx(R0900_P1_NCO2MAX1)
3271#define F0900_P1_TETA2_MAXVABS1 0xf51400ff
3272
3273/*P1_NCO2MAX0*/
3274#define R0900_P1_NCO2MAX0 0xf515
3275#define NCO2MAX0 REGx(R0900_P1_NCO2MAX0)
3276#define F0900_P1_TETA2_MAXVABS0 0xf51500ff
3277
3278/*P1_NCO2FR1*/
3279#define R0900_P1_NCO2FR1 0xf516
3280#define NCO2FR1 REGx(R0900_P1_NCO2FR1)
3281#define F0900_P1_NCO2FINAL_ANGLE1 0xf51600ff
3282
3283/*P1_NCO2FR0*/
3284#define R0900_P1_NCO2FR0 0xf517
3285#define NCO2FR0 REGx(R0900_P1_NCO2FR0)
3286#define F0900_P1_NCO2FINAL_ANGLE0 0xf51700ff
3287
3288/*P1_CFR2AVRGE1*/
3289#define R0900_P1_CFR2AVRGE1 0xf518
3290#define CFR2AVRGE1 REGx(R0900_P1_CFR2AVRGE1)
3291#define F0900_P1_I2C_CFR2AVERAGE1 0xf51800ff
3292
3293/*P1_CFR2AVRGE0*/
3294#define R0900_P1_CFR2AVRGE0 0xf519
3295#define CFR2AVRGE0 REGx(R0900_P1_CFR2AVRGE0)
3296#define F0900_P1_I2C_CFR2AVERAGE0 0xf51900ff
3297
3298/*P1_DMDPLHSTAT*/
3299#define R0900_P1_DMDPLHSTAT 0xf520
3300#define DMDPLHSTAT REGx(R0900_P1_DMDPLHSTAT)
3301#define F0900_P1_PLH_STATISTIC 0xf52000ff
3302
3303/*P1_LOCKTIME3*/
3304#define R0900_P1_LOCKTIME3 0xf522
3305#define LOCKTIME3 REGx(R0900_P1_LOCKTIME3)
3306#define F0900_P1_DEMOD_LOCKTIME3 0xf52200ff
3307
3308/*P1_LOCKTIME2*/
3309#define R0900_P1_LOCKTIME2 0xf523
3310#define LOCKTIME2 REGx(R0900_P1_LOCKTIME2)
3311#define F0900_P1_DEMOD_LOCKTIME2 0xf52300ff
3312
3313/*P1_LOCKTIME1*/
3314#define R0900_P1_LOCKTIME1 0xf524
3315#define LOCKTIME1 REGx(R0900_P1_LOCKTIME1)
3316#define F0900_P1_DEMOD_LOCKTIME1 0xf52400ff
3317
3318/*P1_LOCKTIME0*/
3319#define R0900_P1_LOCKTIME0 0xf525
3320#define LOCKTIME0 REGx(R0900_P1_LOCKTIME0)
3321#define F0900_P1_DEMOD_LOCKTIME0 0xf52500ff
3322
3323/*P1_VITSCALE*/
3324#define R0900_P1_VITSCALE 0xf532
3325#define VITSCALE REGx(R0900_P1_VITSCALE)
3326#define F0900_P1_NVTH_NOSRANGE 0xf5320080
3327#define F0900_P1_VERROR_MAXMODE 0xf5320040
3328#define F0900_P1_NSLOWSN_LOCKED 0xf5320008
3329#define F0900_P1_DIS_RSFLOCK 0xf5320002
3330
3331/*P1_FECM*/
3332#define R0900_P1_FECM 0xf533
3333#define FECM REGx(R0900_P1_FECM)
3334#define F0900_P1_DSS_DVB 0xf5330080
3335#define DSS_DVB FLDx(F0900_P1_DSS_DVB)
3336#define F0900_P1_DSS_SRCH 0xf5330010
3337#define F0900_P1_SYNCVIT 0xf5330002
3338#define F0900_P1_IQINV 0xf5330001
3339#define IQINV FLDx(F0900_P1_IQINV)
3340
3341/*P1_VTH12*/
3342#define R0900_P1_VTH12 0xf534
3343#define VTH12 REGx(R0900_P1_VTH12)
3344#define F0900_P1_VTH12 0xf53400ff
3345
3346/*P1_VTH23*/
3347#define R0900_P1_VTH23 0xf535
3348#define VTH23 REGx(R0900_P1_VTH23)
3349#define F0900_P1_VTH23 0xf53500ff
3350
3351/*P1_VTH34*/
3352#define R0900_P1_VTH34 0xf536
3353#define VTH34 REGx(R0900_P1_VTH34)
3354#define F0900_P1_VTH34 0xf53600ff
3355
3356/*P1_VTH56*/
3357#define R0900_P1_VTH56 0xf537
3358#define VTH56 REGx(R0900_P1_VTH56)
3359#define F0900_P1_VTH56 0xf53700ff
3360
3361/*P1_VTH67*/
3362#define R0900_P1_VTH67 0xf538
3363#define VTH67 REGx(R0900_P1_VTH67)
3364#define F0900_P1_VTH67 0xf53800ff
3365
3366/*P1_VTH78*/
3367#define R0900_P1_VTH78 0xf539
3368#define VTH78 REGx(R0900_P1_VTH78)
3369#define F0900_P1_VTH78 0xf53900ff
3370
3371/*P1_VITCURPUN*/
3372#define R0900_P1_VITCURPUN 0xf53a
3373#define VITCURPUN REGx(R0900_P1_VITCURPUN)
3374#define F0900_P1_VIT_CURPUN 0xf53a001f
3375#define VIT_CURPUN FLDx(F0900_P1_VIT_CURPUN)
3376
3377/*P1_VERROR*/
3378#define R0900_P1_VERROR 0xf53b
3379#define VERROR REGx(R0900_P1_VERROR)
3380#define F0900_P1_REGERR_VIT 0xf53b00ff
3381
3382/*P1_PRVIT*/
3383#define R0900_P1_PRVIT 0xf53c
3384#define PRVIT REGx(R0900_P1_PRVIT)
3385#define F0900_P1_DIS_VTHLOCK 0xf53c0040
3386#define F0900_P1_E7_8VIT 0xf53c0020
3387#define F0900_P1_E6_7VIT 0xf53c0010
3388#define F0900_P1_E5_6VIT 0xf53c0008
3389#define F0900_P1_E3_4VIT 0xf53c0004
3390#define F0900_P1_E2_3VIT 0xf53c0002
3391#define F0900_P1_E1_2VIT 0xf53c0001
3392
3393/*P1_VAVSRVIT*/
3394#define R0900_P1_VAVSRVIT 0xf53d
3395#define VAVSRVIT REGx(R0900_P1_VAVSRVIT)
3396#define F0900_P1_AMVIT 0xf53d0080
3397#define F0900_P1_FROZENVIT 0xf53d0040
3398#define F0900_P1_SNVIT 0xf53d0030
3399#define F0900_P1_TOVVIT 0xf53d000c
3400#define F0900_P1_HYPVIT 0xf53d0003
3401
3402/*P1_VSTATUSVIT*/
3403#define R0900_P1_VSTATUSVIT 0xf53e
3404#define VSTATUSVIT REGx(R0900_P1_VSTATUSVIT)
3405#define F0900_P1_PRFVIT 0xf53e0010
3406#define PRFVIT FLDx(F0900_P1_PRFVIT)
3407#define F0900_P1_LOCKEDVIT 0xf53e0008
3408#define LOCKEDVIT FLDx(F0900_P1_LOCKEDVIT)
3409
3410/*P1_VTHINUSE*/
3411#define R0900_P1_VTHINUSE 0xf53f
3412#define VTHINUSE REGx(R0900_P1_VTHINUSE)
3413#define F0900_P1_VIT_INUSE 0xf53f00ff
3414
3415/*P1_KDIV12*/
3416#define R0900_P1_KDIV12 0xf540
3417#define KDIV12 REGx(R0900_P1_KDIV12)
3418#define F0900_P1_K_DIVIDER_12 0xf540007f
3419
3420/*P1_KDIV23*/
3421#define R0900_P1_KDIV23 0xf541
3422#define KDIV23 REGx(R0900_P1_KDIV23)
3423#define F0900_P1_K_DIVIDER_23 0xf541007f
3424
3425/*P1_KDIV34*/
3426#define R0900_P1_KDIV34 0xf542
3427#define KDIV34 REGx(R0900_P1_KDIV34)
3428#define F0900_P1_K_DIVIDER_34 0xf542007f
3429
3430/*P1_KDIV56*/
3431#define R0900_P1_KDIV56 0xf543
3432#define KDIV56 REGx(R0900_P1_KDIV56)
3433#define F0900_P1_K_DIVIDER_56 0xf543007f
3434
3435/*P1_KDIV67*/
3436#define R0900_P1_KDIV67 0xf544
3437#define KDIV67 REGx(R0900_P1_KDIV67)
3438#define F0900_P1_K_DIVIDER_67 0xf544007f
3439
3440/*P1_KDIV78*/
3441#define R0900_P1_KDIV78 0xf545
3442#define KDIV78 REGx(R0900_P1_KDIV78)
3443#define F0900_P1_K_DIVIDER_78 0xf545007f
3444
3445/*P1_PDELCTRL1*/
3446#define R0900_P1_PDELCTRL1 0xf550
3447#define PDELCTRL1 REGx(R0900_P1_PDELCTRL1)
3448#define F0900_P1_INV_MISMASK 0xf5500080
3449#define F0900_P1_FILTER_EN 0xf5500020
3450#define F0900_P1_EN_MIS00 0xf5500002
3451#define F0900_P1_ALGOSWRST 0xf5500001
3452#define ALGOSWRST FLDx(F0900_P1_ALGOSWRST)
3453
3454/*P1_PDELCTRL2*/
3455#define R0900_P1_PDELCTRL2 0xf551
3456#define PDELCTRL2 REGx(R0900_P1_PDELCTRL2)
3457#define F0900_P1_RESET_UPKO_COUNT 0xf5510040
3458#define RESET_UPKO_COUNT FLDx(F0900_P1_RESET_UPKO_COUNT)
3459#define F0900_P1_FRAME_MODE 0xf5510002
3460#define F0900_P1_NOBCHERRFLG_USE 0xf5510001
3461
3462/*P1_HYSTTHRESH*/
3463#define R0900_P1_HYSTTHRESH 0xf554
3464#define HYSTTHRESH REGx(R0900_P1_HYSTTHRESH)
3465#define F0900_P1_UNLCK_THRESH 0xf55400f0
3466#define F0900_P1_DELIN_LCK_THRESH 0xf554000f
3467
3468/*P1_ISIENTRY*/
3469#define R0900_P1_ISIENTRY 0xf55e
3470#define ISIENTRY REGx(R0900_P1_ISIENTRY)
3471#define F0900_P1_ISI_ENTRY 0xf55e00ff
3472
3473/*P1_ISIBITENA*/
3474#define R0900_P1_ISIBITENA 0xf55f
3475#define ISIBITENA REGx(R0900_P1_ISIBITENA)
3476#define F0900_P1_ISI_BIT_EN 0xf55f00ff
3477
3478/*P1_MATSTR1*/
3479#define R0900_P1_MATSTR1 0xf560
3480#define MATSTR1 REGx(R0900_P1_MATSTR1)
3481#define F0900_P1_MATYPE_CURRENT1 0xf56000ff
3482
3483/*P1_MATSTR0*/
3484#define R0900_P1_MATSTR0 0xf561
3485#define MATSTR0 REGx(R0900_P1_MATSTR0)
3486#define F0900_P1_MATYPE_CURRENT0 0xf56100ff
3487
3488/*P1_UPLSTR1*/
3489#define R0900_P1_UPLSTR1 0xf562
3490#define UPLSTR1 REGx(R0900_P1_UPLSTR1)
3491#define F0900_P1_UPL_CURRENT1 0xf56200ff
3492
3493/*P1_UPLSTR0*/
3494#define R0900_P1_UPLSTR0 0xf563
3495#define UPLSTR0 REGx(R0900_P1_UPLSTR0)
3496#define F0900_P1_UPL_CURRENT0 0xf56300ff
3497
3498/*P1_DFLSTR1*/
3499#define R0900_P1_DFLSTR1 0xf564
3500#define DFLSTR1 REGx(R0900_P1_DFLSTR1)
3501#define F0900_P1_DFL_CURRENT1 0xf56400ff
3502
3503/*P1_DFLSTR0*/
3504#define R0900_P1_DFLSTR0 0xf565
3505#define DFLSTR0 REGx(R0900_P1_DFLSTR0)
3506#define F0900_P1_DFL_CURRENT0 0xf56500ff
3507
3508/*P1_SYNCSTR*/
3509#define R0900_P1_SYNCSTR 0xf566
3510#define SYNCSTR REGx(R0900_P1_SYNCSTR)
3511#define F0900_P1_SYNC_CURRENT 0xf56600ff
3512
3513/*P1_SYNCDSTR1*/
3514#define R0900_P1_SYNCDSTR1 0xf567
3515#define SYNCDSTR1 REGx(R0900_P1_SYNCDSTR1)
3516#define F0900_P1_SYNCD_CURRENT1 0xf56700ff
3517
3518/*P1_SYNCDSTR0*/
3519#define R0900_P1_SYNCDSTR0 0xf568
3520#define SYNCDSTR0 REGx(R0900_P1_SYNCDSTR0)
3521#define F0900_P1_SYNCD_CURRENT0 0xf56800ff
3522
3523/*P1_PDELSTATUS1*/
3524#define R0900_P1_PDELSTATUS1 0xf569
3525#define F0900_P1_PKTDELIN_DELOCK 0xf5690080
3526#define F0900_P1_SYNCDUPDFL_BADDFL 0xf5690040
3527#define F0900_P1_CONTINUOUS_STREAM 0xf5690020
3528#define F0900_P1_UNACCEPTED_STREAM 0xf5690010
3529#define F0900_P1_BCH_ERROR_FLAG 0xf5690008
3530#define F0900_P1_PKTDELIN_LOCK 0xf5690002
3531#define PKTDELIN_LOCK FLDx(F0900_P1_PKTDELIN_LOCK)
3532#define F0900_P1_FIRST_LOCK 0xf5690001
3533
3534/*P1_PDELSTATUS2*/
3535#define R0900_P1_PDELSTATUS2 0xf56a
3536#define F0900_P1_FRAME_MODCOD 0xf56a007c
3537#define F0900_P1_FRAME_TYPE 0xf56a0003
3538
3539/*P1_BBFCRCKO1*/
3540#define R0900_P1_BBFCRCKO1 0xf56b
3541#define BBFCRCKO1 REGx(R0900_P1_BBFCRCKO1)
3542#define F0900_P1_BBHCRC_KOCNT1 0xf56b00ff
3543
3544/*P1_BBFCRCKO0*/
3545#define R0900_P1_BBFCRCKO0 0xf56c
3546#define BBFCRCKO0 REGx(R0900_P1_BBFCRCKO0)
3547#define F0900_P1_BBHCRC_KOCNT0 0xf56c00ff
3548
3549/*P1_UPCRCKO1*/
3550#define R0900_P1_UPCRCKO1 0xf56d
3551#define UPCRCKO1 REGx(R0900_P1_UPCRCKO1)
3552#define F0900_P1_PKTCRC_KOCNT1 0xf56d00ff
3553
3554/*P1_UPCRCKO0*/
3555#define R0900_P1_UPCRCKO0 0xf56e
3556#define UPCRCKO0 REGx(R0900_P1_UPCRCKO0)
3557#define F0900_P1_PKTCRC_KOCNT0 0xf56e00ff
3558
3559/*P1_PDELCTRL3*/
3560#define R0900_P1_PDELCTRL3 0xf56f
3561#define PDELCTRL3 REGx(R0900_P1_PDELCTRL3)
3562#define F0900_P1_PKTDEL_CONTFAIL 0xf56f0080
3563#define F0900_P1_NOFIFO_BCHERR 0xf56f0020
3564
3565/*P1_TSSTATEM*/
3566#define R0900_P1_TSSTATEM 0xf570
3567#define TSSTATEM REGx(R0900_P1_TSSTATEM)
3568#define F0900_P1_TSDIL_ON 0xf5700080
3569#define F0900_P1_TSRS_ON 0xf5700020
3570#define F0900_P1_TSDESCRAMB_ON 0xf5700010
3571#define F0900_P1_TSFRAME_MODE 0xf5700008
3572#define F0900_P1_TS_DISABLE 0xf5700004
3573#define F0900_P1_TSOUT_NOSYNC 0xf5700001
3574
3575/*P1_TSCFGH*/
3576#define R0900_P1_TSCFGH 0xf572
3577#define TSCFGH REGx(R0900_P1_TSCFGH)
3578#define F0900_P1_TSFIFO_DVBCI 0xf5720080
3579#define F0900_P1_TSFIFO_SERIAL 0xf5720040
3580#define F0900_P1_TSFIFO_TEIUPDATE 0xf5720020
3581#define F0900_P1_TSFIFO_DUTY50 0xf5720010
3582#define F0900_P1_TSFIFO_HSGNLOUT 0xf5720008
3583#define F0900_P1_TSFIFO_ERRMODE 0xf5720006
3584#define F0900_P1_RST_HWARE 0xf5720001
3585#define RST_HWARE FLDx(F0900_P1_RST_HWARE)
3586
3587/*P1_TSCFGM*/
3588#define R0900_P1_TSCFGM 0xf573
3589#define TSCFGM REGx(R0900_P1_TSCFGM)
3590#define F0900_P1_TSFIFO_MANSPEED 0xf57300c0
3591#define F0900_P1_TSFIFO_PERMDATA 0xf5730020
3592#define F0900_P1_TSFIFO_DPUNACT 0xf5730002
3593#define F0900_P1_TSFIFO_INVDATA 0xf5730001
3594
3595/*P1_TSCFGL*/
3596#define R0900_P1_TSCFGL 0xf574
3597#define TSCFGL REGx(R0900_P1_TSCFGL)
3598#define F0900_P1_TSFIFO_BCLKDEL1CK 0xf57400c0
3599#define F0900_P1_BCHERROR_MODE 0xf5740030
3600#define F0900_P1_TSFIFO_NSGNL2DATA 0xf5740008
3601#define F0900_P1_TSFIFO_EMBINDVB 0xf5740004
3602#define F0900_P1_TSFIFO_BITSPEED 0xf5740003
3603
3604/*P1_TSINSDELH*/
3605#define R0900_P1_TSINSDELH 0xf576
3606#define TSINSDELH REGx(R0900_P1_TSINSDELH)
3607#define F0900_P1_TSDEL_SYNCBYTE 0xf5760080
3608#define F0900_P1_TSDEL_XXHEADER 0xf5760040
3609#define F0900_P1_TSDEL_BBHEADER 0xf5760020
3610#define F0900_P1_TSDEL_DATAFIELD 0xf5760010
3611#define F0900_P1_TSINSDEL_ISCR 0xf5760008
3612#define F0900_P1_TSINSDEL_NPD 0xf5760004
3613#define F0900_P1_TSINSDEL_RSPARITY 0xf5760002
3614#define F0900_P1_TSINSDEL_CRC8 0xf5760001
3615
3616/*P1_TSDIVN*/
3617#define R0900_P1_TSDIVN 0xf579
3618#define TSDIVN REGx(R0900_P1_TSDIVN)
3619#define F0900_P1_TSFIFO_SPEEDMODE 0xf57900c0
3620
3621/*P1_TSCFG4*/
3622#define R0900_P1_TSCFG4 0xf57a
3623#define TSCFG4 REGx(R0900_P1_TSCFG4)
3624#define F0900_P1_TSFIFO_TSSPEEDMODE 0xf57a00c0
3625
3626/*P1_TSSPEED*/
3627#define R0900_P1_TSSPEED 0xf580
3628#define TSSPEED REGx(R0900_P1_TSSPEED)
3629#define F0900_P1_TSFIFO_OUTSPEED 0xf58000ff
3630
3631/*P1_TSSTATUS*/
3632#define R0900_P1_TSSTATUS 0xf581
3633#define TSSTATUS REGx(R0900_P1_TSSTATUS)
3634#define F0900_P1_TSFIFO_LINEOK 0xf5810080
3635#define TSFIFO_LINEOK FLDx(F0900_P1_TSFIFO_LINEOK)
3636#define F0900_P1_TSFIFO_ERROR 0xf5810040
3637#define F0900_P1_DIL_READY 0xf5810001
3638
3639/*P1_TSSTATUS2*/
3640#define R0900_P1_TSSTATUS2 0xf582
3641#define TSSTATUS2 REGx(R0900_P1_TSSTATUS2)
3642#define F0900_P1_TSFIFO_DEMODSEL 0xf5820080
3643#define F0900_P1_TSFIFOSPEED_STORE 0xf5820040
3644#define F0900_P1_DILXX_RESET 0xf5820020
3645#define F0900_P1_TSSERIAL_IMPOS 0xf5820010
3646#define F0900_P1_SCRAMBDETECT 0xf5820002
3647
3648/*P1_TSBITRATE1*/
3649#define R0900_P1_TSBITRATE1 0xf583
3650#define TSBITRATE1 REGx(R0900_P1_TSBITRATE1)
3651#define F0900_P1_TSFIFO_BITRATE1 0xf58300ff
3652
3653/*P1_TSBITRATE0*/
3654#define R0900_P1_TSBITRATE0 0xf584
3655#define TSBITRATE0 REGx(R0900_P1_TSBITRATE0)
3656#define F0900_P1_TSFIFO_BITRATE0 0xf58400ff
3657
3658/*P1_ERRCTRL1*/
3659#define R0900_P1_ERRCTRL1 0xf598
3660#define ERRCTRL1 REGx(R0900_P1_ERRCTRL1)
3661#define F0900_P1_ERR_SOURCE1 0xf59800f0
3662#define F0900_P1_NUM_EVENT1 0xf5980007
3663
3664/*P1_ERRCNT12*/
3665#define R0900_P1_ERRCNT12 0xf599
3666#define ERRCNT12 REGx(R0900_P1_ERRCNT12)
3667#define F0900_P1_ERRCNT1_OLDVALUE 0xf5990080
3668#define F0900_P1_ERR_CNT12 0xf599007f
3669#define ERR_CNT12 FLDx(F0900_P1_ERR_CNT12)
3670
3671/*P1_ERRCNT11*/
3672#define R0900_P1_ERRCNT11 0xf59a
3673#define ERRCNT11 REGx(R0900_P1_ERRCNT11)
3674#define F0900_P1_ERR_CNT11 0xf59a00ff
3675#define ERR_CNT11 FLDx(F0900_P1_ERR_CNT11)
3676
3677/*P1_ERRCNT10*/
3678#define R0900_P1_ERRCNT10 0xf59b
3679#define ERRCNT10 REGx(R0900_P1_ERRCNT10)
3680#define F0900_P1_ERR_CNT10 0xf59b00ff
3681#define ERR_CNT10 FLDx(F0900_P1_ERR_CNT10)
3682
3683/*P1_ERRCTRL2*/
3684#define R0900_P1_ERRCTRL2 0xf59c
3685#define ERRCTRL2 REGx(R0900_P1_ERRCTRL2)
3686#define F0900_P1_ERR_SOURCE2 0xf59c00f0
3687#define F0900_P1_NUM_EVENT2 0xf59c0007
3688
3689/*P1_ERRCNT22*/
3690#define R0900_P1_ERRCNT22 0xf59d
3691#define ERRCNT22 REGx(R0900_P1_ERRCNT22)
3692#define F0900_P1_ERRCNT2_OLDVALUE 0xf59d0080
3693#define F0900_P1_ERR_CNT22 0xf59d007f
3694#define ERR_CNT22 FLDx(F0900_P1_ERR_CNT22)
3695
3696/*P1_ERRCNT21*/
3697#define R0900_P1_ERRCNT21 0xf59e
3698#define ERRCNT21 REGx(R0900_P1_ERRCNT21)
3699#define F0900_P1_ERR_CNT21 0xf59e00ff
3700#define ERR_CNT21 FLDx(F0900_P1_ERR_CNT21)
3701
3702/*P1_ERRCNT20*/
3703#define R0900_P1_ERRCNT20 0xf59f
3704#define ERRCNT20 REGx(R0900_P1_ERRCNT20)
3705#define F0900_P1_ERR_CNT20 0xf59f00ff
3706#define ERR_CNT20 FLDx(F0900_P1_ERR_CNT20)
3707
3708/*P1_FECSPY*/
3709#define R0900_P1_FECSPY 0xf5a0
3710#define FECSPY REGx(R0900_P1_FECSPY)
3711#define F0900_P1_SPY_ENABLE 0xf5a00080
3712#define F0900_P1_NO_SYNCBYTE 0xf5a00040
3713#define F0900_P1_SERIAL_MODE 0xf5a00020
3714#define F0900_P1_UNUSUAL_PACKET 0xf5a00010
3715#define F0900_P1_BERMETER_DATAMODE 0xf5a00008
3716#define F0900_P1_BERMETER_LMODE 0xf5a00002
3717#define F0900_P1_BERMETER_RESET 0xf5a00001
3718
3719/*P1_FSPYCFG*/
3720#define R0900_P1_FSPYCFG 0xf5a1
3721#define FSPYCFG REGx(R0900_P1_FSPYCFG)
3722#define F0900_P1_FECSPY_INPUT 0xf5a100c0
3723#define F0900_P1_RST_ON_ERROR 0xf5a10020
3724#define F0900_P1_ONE_SHOT 0xf5a10010
3725#define F0900_P1_I2C_MODE 0xf5a1000c
3726#define F0900_P1_SPY_HYSTERESIS 0xf5a10003
3727
3728/*P1_FSPYDATA*/
3729#define R0900_P1_FSPYDATA 0xf5a2
3730#define FSPYDATA REGx(R0900_P1_FSPYDATA)
3731#define F0900_P1_SPY_STUFFING 0xf5a20080
3732#define F0900_P1_SPY_CNULLPKT 0xf5a20020
3733#define F0900_P1_SPY_OUTDATA_MODE 0xf5a2001f
3734
3735/*P1_FSPYOUT*/
3736#define R0900_P1_FSPYOUT 0xf5a3
3737#define FSPYOUT REGx(R0900_P1_FSPYOUT)
3738#define F0900_P1_FSPY_DIRECT 0xf5a30080
3739#define F0900_P1_STUFF_MODE 0xf5a30007
3740
3741/*P1_FSTATUS*/
3742#define R0900_P1_FSTATUS 0xf5a4
3743#define FSTATUS REGx(R0900_P1_FSTATUS)
3744#define F0900_P1_SPY_ENDSIM 0xf5a40080
3745#define F0900_P1_VALID_SIM 0xf5a40040
3746#define F0900_P1_FOUND_SIGNAL 0xf5a40020
3747#define F0900_P1_DSS_SYNCBYTE 0xf5a40010
3748#define F0900_P1_RESULT_STATE 0xf5a4000f
3749
3750/*P1_FBERCPT4*/
3751#define R0900_P1_FBERCPT4 0xf5a8
3752#define FBERCPT4 REGx(R0900_P1_FBERCPT4)
3753#define F0900_P1_FBERMETER_CPT4 0xf5a800ff
3754
3755/*P1_FBERCPT3*/
3756#define R0900_P1_FBERCPT3 0xf5a9
3757#define FBERCPT3 REGx(R0900_P1_FBERCPT3)
3758#define F0900_P1_FBERMETER_CPT3 0xf5a900ff
3759
3760/*P1_FBERCPT2*/
3761#define R0900_P1_FBERCPT2 0xf5aa
3762#define FBERCPT2 REGx(R0900_P1_FBERCPT2)
3763#define F0900_P1_FBERMETER_CPT2 0xf5aa00ff
3764
3765/*P1_FBERCPT1*/
3766#define R0900_P1_FBERCPT1 0xf5ab
3767#define FBERCPT1 REGx(R0900_P1_FBERCPT1)
3768#define F0900_P1_FBERMETER_CPT1 0xf5ab00ff
3769
3770/*P1_FBERCPT0*/
3771#define R0900_P1_FBERCPT0 0xf5ac
3772#define FBERCPT0 REGx(R0900_P1_FBERCPT0)
3773#define F0900_P1_FBERMETER_CPT0 0xf5ac00ff
3774
3775/*P1_FBERERR2*/
3776#define R0900_P1_FBERERR2 0xf5ad
3777#define FBERERR2 REGx(R0900_P1_FBERERR2)
3778#define F0900_P1_FBERMETER_ERR2 0xf5ad00ff
3779
3780/*P1_FBERERR1*/
3781#define R0900_P1_FBERERR1 0xf5ae
3782#define FBERERR1 REGx(R0900_P1_FBERERR1)
3783#define F0900_P1_FBERMETER_ERR1 0xf5ae00ff
3784
3785/*P1_FBERERR0*/
3786#define R0900_P1_FBERERR0 0xf5af
3787#define FBERERR0 REGx(R0900_P1_FBERERR0)
3788#define F0900_P1_FBERMETER_ERR0 0xf5af00ff
3789
3790/*P1_FSPYBER*/
3791#define R0900_P1_FSPYBER 0xf5b2
3792#define FSPYBER REGx(R0900_P1_FSPYBER)
3793#define F0900_P1_FSPYBER_SYNCBYTE 0xf5b20010
3794#define F0900_P1_FSPYBER_UNSYNC 0xf5b20008
3795#define F0900_P1_FSPYBER_CTIME 0xf5b20007
3796
3797/*RCCFG2*/
3798#define R0900_RCCFG2 0xf600
3799
3800/*TSGENERAL*/
3801#define R0900_TSGENERAL 0xf630
3802#define F0900_TSFIFO_DISTS2PAR 0xf6300040
3803#define F0900_MUXSTREAM_OUTMODE 0xf6300008
3804#define F0900_TSFIFO_PERMPARAL 0xf6300006
3805
3806/*TSGENERAL1X*/
3807#define R0900_TSGENERAL1X 0xf670
3808
3809/*NBITER_NF4*/
3810#define R0900_NBITER_NF4 0xfa03
3811#define F0900_NBITER_NF_QP_1_2 0xfa0300ff
3812
3813/*NBITER_NF5*/
3814#define R0900_NBITER_NF5 0xfa04
3815#define F0900_NBITER_NF_QP_3_5 0xfa0400ff
3816
3817/*NBITER_NF6*/
3818#define R0900_NBITER_NF6 0xfa05
3819#define F0900_NBITER_NF_QP_2_3 0xfa0500ff
3820
3821/*NBITER_NF7*/
3822#define R0900_NBITER_NF7 0xfa06
3823#define F0900_NBITER_NF_QP_3_4 0xfa0600ff
3824
3825/*NBITER_NF8*/
3826#define R0900_NBITER_NF8 0xfa07
3827#define F0900_NBITER_NF_QP_4_5 0xfa0700ff
3828
3829/*NBITER_NF9*/
3830#define R0900_NBITER_NF9 0xfa08
3831#define F0900_NBITER_NF_QP_5_6 0xfa0800ff
3832
3833/*NBITER_NF10*/
3834#define R0900_NBITER_NF10 0xfa09
3835#define F0900_NBITER_NF_QP_8_9 0xfa0900ff
3836
3837/*NBITER_NF11*/
3838#define R0900_NBITER_NF11 0xfa0a
3839#define F0900_NBITER_NF_QP_9_10 0xfa0a00ff
3840
3841/*NBITER_NF12*/
3842#define R0900_NBITER_NF12 0xfa0b
3843#define F0900_NBITER_NF_8P_3_5 0xfa0b00ff
3844
3845/*NBITER_NF13*/
3846#define R0900_NBITER_NF13 0xfa0c
3847#define F0900_NBITER_NF_8P_2_3 0xfa0c00ff
3848
3849/*NBITER_NF14*/
3850#define R0900_NBITER_NF14 0xfa0d
3851#define F0900_NBITER_NF_8P_3_4 0xfa0d00ff
3852
3853/*NBITER_NF15*/
3854#define R0900_NBITER_NF15 0xfa0e
3855#define F0900_NBITER_NF_8P_5_6 0xfa0e00ff
3856
3857/*NBITER_NF16*/
3858#define R0900_NBITER_NF16 0xfa0f
3859#define F0900_NBITER_NF_8P_8_9 0xfa0f00ff
3860
3861/*NBITER_NF17*/
3862#define R0900_NBITER_NF17 0xfa10
3863#define F0900_NBITER_NF_8P_9_10 0xfa1000ff
3864
3865/*NBITERNOERR*/
3866#define R0900_NBITERNOERR 0xfa3f
3867#define F0900_NBITER_STOP_CRIT 0xfa3f000f
3868
3869/*GAINLLR_NF4*/
3870#define R0900_GAINLLR_NF4 0xfa43
3871#define F0900_GAINLLR_NF_QP_1_2 0xfa43007f
3872
3873/*GAINLLR_NF5*/
3874#define R0900_GAINLLR_NF5 0xfa44
3875#define F0900_GAINLLR_NF_QP_3_5 0xfa44007f
3876
3877/*GAINLLR_NF6*/
3878#define R0900_GAINLLR_NF6 0xfa45
3879#define F0900_GAINLLR_NF_QP_2_3 0xfa45007f
3880
3881/*GAINLLR_NF7*/
3882#define R0900_GAINLLR_NF7 0xfa46
3883#define F0900_GAINLLR_NF_QP_3_4 0xfa46007f
3884
3885/*GAINLLR_NF8*/
3886#define R0900_GAINLLR_NF8 0xfa47
3887#define F0900_GAINLLR_NF_QP_4_5 0xfa47007f
3888
3889/*GAINLLR_NF9*/
3890#define R0900_GAINLLR_NF9 0xfa48
3891#define F0900_GAINLLR_NF_QP_5_6 0xfa48007f
3892
3893/*GAINLLR_NF10*/
3894#define R0900_GAINLLR_NF10 0xfa49
3895#define F0900_GAINLLR_NF_QP_8_9 0xfa49007f
3896
3897/*GAINLLR_NF11*/
3898#define R0900_GAINLLR_NF11 0xfa4a
3899#define F0900_GAINLLR_NF_QP_9_10 0xfa4a007f
3900
3901/*GAINLLR_NF12*/
3902#define R0900_GAINLLR_NF12 0xfa4b
3903#define F0900_GAINLLR_NF_8P_3_5 0xfa4b007f
3904
3905/*GAINLLR_NF13*/
3906#define R0900_GAINLLR_NF13 0xfa4c
3907#define F0900_GAINLLR_NF_8P_2_3 0xfa4c007f
3908
3909/*GAINLLR_NF14*/
3910#define R0900_GAINLLR_NF14 0xfa4d
3911#define F0900_GAINLLR_NF_8P_3_4 0xfa4d007f
3912
3913/*GAINLLR_NF15*/
3914#define R0900_GAINLLR_NF15 0xfa4e
3915#define F0900_GAINLLR_NF_8P_5_6 0xfa4e007f
3916
3917/*GAINLLR_NF16*/
3918#define R0900_GAINLLR_NF16 0xfa4f
3919#define F0900_GAINLLR_NF_8P_8_9 0xfa4f007f
3920
3921/*GAINLLR_NF17*/
3922#define R0900_GAINLLR_NF17 0xfa50
3923#define F0900_GAINLLR_NF_8P_9_10 0xfa50007f
3924
3925/*CFGEXT*/
3926#define R0900_CFGEXT 0xfa80
3927#define F0900_STAGMODE 0xfa800080
3928#define F0900_BYPBCH 0xfa800040
3929#define F0900_BYPLDPC 0xfa800020
3930#define F0900_LDPCMODE 0xfa800010
3931#define F0900_INVLLRSIGN 0xfa800008
3932#define F0900_SHORTMULT 0xfa800004
3933#define F0900_EXTERNTX 0xfa800001
3934
3935/*GENCFG*/
3936#define R0900_GENCFG 0xfa86
3937#define F0900_BROADCAST 0xfa860010
3938#define F0900_PRIORITY 0xfa860002
3939#define F0900_DDEMOD 0xfa860001
3940
3941/*LDPCERR1*/
3942#define R0900_LDPCERR1 0xfa96
3943#define F0900_LDPC_ERRORS_COUNTER1 0xfa9600ff
3944
3945/*LDPCERR0*/
3946#define R0900_LDPCERR0 0xfa97
3947#define F0900_LDPC_ERRORS_COUNTER0 0xfa9700ff
3948
3949/*BCHERR*/
3950#define R0900_BCHERR 0xfa98
3951#define F0900_ERRORFLAG 0xfa980010
3952#define F0900_BCH_ERRORS_COUNTER 0xfa98000f
3953
3954/*TSTRES0*/
3955#define R0900_TSTRES0 0xff11
3956#define F0900_FRESFEC 0xff110080
3957
3958/*P2_TCTL4*/
3959#define R0900_P2_TCTL4 0xff28
3960#define F0900_P2_PN4_SELECT 0xff280020
3961
3962/*P1_TCTL4*/
3963#define R0900_P1_TCTL4 0xff48
3964#define TCTL4 shiftx(R0900_P1_TCTL4, demod, 0x20)
3965#define F0900_P1_PN4_SELECT 0xff480020
3966
3967/*P2_TSTDISRX*/
3968#define R0900_P2_TSTDISRX 0xff65
3969#define F0900_P2_PIN_SELECT1 0xff650008
3970
3971/*P1_TSTDISRX*/
3972#define R0900_P1_TSTDISRX 0xff67
3973#define TSTDISRX shiftx(R0900_P1_TSTDISRX, demod, 2)
3974#define F0900_P1_PIN_SELECT1 0xff670008
3975#define PIN_SELECT1 shiftx(F0900_P1_PIN_SELECT1, demod, 0x20000)
3976
3977#define STV0900_NBREGS 723
3978#define STV0900_NBFIELDS 1420
3979
3980#endif
3981
diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c
new file mode 100644
index 00000000000..ba0709b2d43
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_sw.c
@@ -0,0 +1,2034 @@
1/*
2 * stv0900_sw.c
3 *
4 * Driver for ST STV0900 satellite demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2009 NetUP Inc.
8 * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include "stv0900.h"
27#include "stv0900_reg.h"
28#include "stv0900_priv.h"
29
30s32 shiftx(s32 x, int demod, s32 shift)
31{
32 if (demod == 1)
33 return x - shift;
34
35 return x;
36}
37
38int stv0900_check_signal_presence(struct stv0900_internal *intp,
39 enum fe_stv0900_demod_num demod)
40{
41 s32 carr_offset,
42 agc2_integr,
43 max_carrier;
44
45 int no_signal = FALSE;
46
47 carr_offset = (stv0900_read_reg(intp, CFR2) << 8)
48 | stv0900_read_reg(intp, CFR1);
49 carr_offset = ge2comp(carr_offset, 16);
50 agc2_integr = (stv0900_read_reg(intp, AGC2I1) << 8)
51 | stv0900_read_reg(intp, AGC2I0);
52 max_carrier = intp->srch_range[demod] / 1000;
53
54 max_carrier += (max_carrier / 10);
55 max_carrier = 65536 * (max_carrier / 2);
56 max_carrier /= intp->mclk / 1000;
57 if (max_carrier > 0x4000)
58 max_carrier = 0x4000;
59
60 if ((agc2_integr > 0x2000)
61 || (carr_offset > (2 * max_carrier))
62 || (carr_offset < (-2 * max_carrier)))
63 no_signal = TRUE;
64
65 return no_signal;
66}
67
68static void stv0900_get_sw_loop_params(struct stv0900_internal *intp,
69 s32 *frequency_inc, s32 *sw_timeout,
70 s32 *steps,
71 enum fe_stv0900_demod_num demod)
72{
73 s32 timeout, freq_inc, max_steps, srate, max_carrier;
74
75 enum fe_stv0900_search_standard standard;
76
77 srate = intp->symbol_rate[demod];
78 max_carrier = intp->srch_range[demod] / 1000;
79 max_carrier += max_carrier / 10;
80 standard = intp->srch_standard[demod];
81
82 max_carrier = 65536 * (max_carrier / 2);
83 max_carrier /= intp->mclk / 1000;
84
85 if (max_carrier > 0x4000)
86 max_carrier = 0x4000;
87
88 freq_inc = srate;
89 freq_inc /= intp->mclk >> 10;
90 freq_inc = freq_inc << 6;
91
92 switch (standard) {
93 case STV0900_SEARCH_DVBS1:
94 case STV0900_SEARCH_DSS:
95 freq_inc *= 3;
96 timeout = 20;
97 break;
98 case STV0900_SEARCH_DVBS2:
99 freq_inc *= 4;
100 timeout = 25;
101 break;
102 case STV0900_AUTO_SEARCH:
103 default:
104 freq_inc *= 3;
105 timeout = 25;
106 break;
107 }
108
109 freq_inc /= 100;
110
111 if ((freq_inc > max_carrier) || (freq_inc < 0))
112 freq_inc = max_carrier / 2;
113
114 timeout *= 27500;
115
116 if (srate > 0)
117 timeout /= srate / 1000;
118
119 if ((timeout > 100) || (timeout < 0))
120 timeout = 100;
121
122 max_steps = (max_carrier / freq_inc) + 1;
123
124 if ((max_steps > 100) || (max_steps < 0)) {
125 max_steps = 100;
126 freq_inc = max_carrier / max_steps;
127 }
128
129 *frequency_inc = freq_inc;
130 *sw_timeout = timeout;
131 *steps = max_steps;
132
133}
134
135static int stv0900_search_carr_sw_loop(struct stv0900_internal *intp,
136 s32 FreqIncr, s32 Timeout, int zigzag,
137 s32 MaxStep, enum fe_stv0900_demod_num demod)
138{
139 int no_signal,
140 lock = FALSE;
141 s32 stepCpt,
142 freqOffset,
143 max_carrier;
144
145 max_carrier = intp->srch_range[demod] / 1000;
146 max_carrier += (max_carrier / 10);
147
148 max_carrier = 65536 * (max_carrier / 2);
149 max_carrier /= intp->mclk / 1000;
150
151 if (max_carrier > 0x4000)
152 max_carrier = 0x4000;
153
154 if (zigzag == TRUE)
155 freqOffset = 0;
156 else
157 freqOffset = -max_carrier + FreqIncr;
158
159 stepCpt = 0;
160
161 do {
162 stv0900_write_reg(intp, DMDISTATE, 0x1c);
163 stv0900_write_reg(intp, CFRINIT1, (freqOffset / 256) & 0xff);
164 stv0900_write_reg(intp, CFRINIT0, freqOffset & 0xff);
165 stv0900_write_reg(intp, DMDISTATE, 0x18);
166 stv0900_write_bits(intp, ALGOSWRST, 1);
167
168 if (intp->chip_id == 0x12) {
169 stv0900_write_bits(intp, RST_HWARE, 1);
170 stv0900_write_bits(intp, RST_HWARE, 0);
171 }
172
173 if (zigzag == TRUE) {
174 if (freqOffset >= 0)
175 freqOffset = -freqOffset - 2 * FreqIncr;
176 else
177 freqOffset = -freqOffset;
178 } else
179 freqOffset += + 2 * FreqIncr;
180
181 stepCpt++;
182 lock = stv0900_get_demod_lock(intp, demod, Timeout);
183 no_signal = stv0900_check_signal_presence(intp, demod);
184
185 } while ((lock == FALSE)
186 && (no_signal == FALSE)
187 && ((freqOffset - FreqIncr) < max_carrier)
188 && ((freqOffset + FreqIncr) > -max_carrier)
189 && (stepCpt < MaxStep));
190
191 stv0900_write_bits(intp, ALGOSWRST, 0);
192
193 return lock;
194}
195
196static int stv0900_sw_algo(struct stv0900_internal *intp,
197 enum fe_stv0900_demod_num demod)
198{
199 int lock = FALSE,
200 no_signal,
201 zigzag;
202 s32 s2fw,
203 fqc_inc,
204 sft_stp_tout,
205 trial_cntr,
206 max_steps;
207
208 stv0900_get_sw_loop_params(intp, &fqc_inc, &sft_stp_tout,
209 &max_steps, demod);
210 switch (intp->srch_standard[demod]) {
211 case STV0900_SEARCH_DVBS1:
212 case STV0900_SEARCH_DSS:
213 if (intp->chip_id >= 0x20)
214 stv0900_write_reg(intp, CARFREQ, 0x3b);
215 else
216 stv0900_write_reg(intp, CARFREQ, 0xef);
217
218 stv0900_write_reg(intp, DMDCFGMD, 0x49);
219 zigzag = FALSE;
220 break;
221 case STV0900_SEARCH_DVBS2:
222 if (intp->chip_id >= 0x20)
223 stv0900_write_reg(intp, CORRELABS, 0x79);
224 else
225 stv0900_write_reg(intp, CORRELABS, 0x68);
226
227 stv0900_write_reg(intp, DMDCFGMD, 0x89);
228
229 zigzag = TRUE;
230 break;
231 case STV0900_AUTO_SEARCH:
232 default:
233 if (intp->chip_id >= 0x20) {
234 stv0900_write_reg(intp, CARFREQ, 0x3b);
235 stv0900_write_reg(intp, CORRELABS, 0x79);
236 } else {
237 stv0900_write_reg(intp, CARFREQ, 0xef);
238 stv0900_write_reg(intp, CORRELABS, 0x68);
239 }
240
241 stv0900_write_reg(intp, DMDCFGMD, 0xc9);
242 zigzag = FALSE;
243 break;
244 }
245
246 trial_cntr = 0;
247 do {
248 lock = stv0900_search_carr_sw_loop(intp,
249 fqc_inc,
250 sft_stp_tout,
251 zigzag,
252 max_steps,
253 demod);
254 no_signal = stv0900_check_signal_presence(intp, demod);
255 trial_cntr++;
256 if ((lock == TRUE)
257 || (no_signal == TRUE)
258 || (trial_cntr == 2)) {
259
260 if (intp->chip_id >= 0x20) {
261 stv0900_write_reg(intp, CARFREQ, 0x49);
262 stv0900_write_reg(intp, CORRELABS, 0x9e);
263 } else {
264 stv0900_write_reg(intp, CARFREQ, 0xed);
265 stv0900_write_reg(intp, CORRELABS, 0x88);
266 }
267
268 if ((stv0900_get_bits(intp, HEADER_MODE) ==
269 STV0900_DVBS2_FOUND) &&
270 (lock == TRUE)) {
271 msleep(sft_stp_tout);
272 s2fw = stv0900_get_bits(intp, FLYWHEEL_CPT);
273
274 if (s2fw < 0xd) {
275 msleep(sft_stp_tout);
276 s2fw = stv0900_get_bits(intp,
277 FLYWHEEL_CPT);
278 }
279
280 if (s2fw < 0xd) {
281 lock = FALSE;
282
283 if (trial_cntr < 2) {
284 if (intp->chip_id >= 0x20)
285 stv0900_write_reg(intp,
286 CORRELABS,
287 0x79);
288 else
289 stv0900_write_reg(intp,
290 CORRELABS,
291 0x68);
292
293 stv0900_write_reg(intp,
294 DMDCFGMD,
295 0x89);
296 }
297 }
298 }
299 }
300
301 } while ((lock == FALSE)
302 && (trial_cntr < 2)
303 && (no_signal == FALSE));
304
305 return lock;
306}
307
308static u32 stv0900_get_symbol_rate(struct stv0900_internal *intp,
309 u32 mclk,
310 enum fe_stv0900_demod_num demod)
311{
312 s32 rem1, rem2, intval1, intval2, srate;
313
314 srate = (stv0900_get_bits(intp, SYMB_FREQ3) << 24) +
315 (stv0900_get_bits(intp, SYMB_FREQ2) << 16) +
316 (stv0900_get_bits(intp, SYMB_FREQ1) << 8) +
317 (stv0900_get_bits(intp, SYMB_FREQ0));
318 dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n",
319 srate, stv0900_get_bits(intp, SYMB_FREQ0),
320 stv0900_get_bits(intp, SYMB_FREQ1),
321 stv0900_get_bits(intp, SYMB_FREQ2),
322 stv0900_get_bits(intp, SYMB_FREQ3));
323
324 intval1 = (mclk) >> 16;
325 intval2 = (srate) >> 16;
326
327 rem1 = (mclk) % 0x10000;
328 rem2 = (srate) % 0x10000;
329 srate = (intval1 * intval2) +
330 ((intval1 * rem2) >> 16) +
331 ((intval2 * rem1) >> 16);
332
333 return srate;
334}
335
336static void stv0900_set_symbol_rate(struct stv0900_internal *intp,
337 u32 mclk, u32 srate,
338 enum fe_stv0900_demod_num demod)
339{
340 u32 symb;
341
342 dprintk("%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk,
343 srate, demod);
344
345 if (srate > 60000000) {
346 symb = srate << 4;
347 symb /= (mclk >> 12);
348 } else if (srate > 6000000) {
349 symb = srate << 6;
350 symb /= (mclk >> 10);
351 } else {
352 symb = srate << 9;
353 symb /= (mclk >> 7);
354 }
355
356 stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0x7f);
357 stv0900_write_reg(intp, SFRINIT1 + 1, (symb & 0xff));
358}
359
360static void stv0900_set_max_symbol_rate(struct stv0900_internal *intp,
361 u32 mclk, u32 srate,
362 enum fe_stv0900_demod_num demod)
363{
364 u32 symb;
365
366 srate = 105 * (srate / 100);
367
368 if (srate > 60000000) {
369 symb = srate << 4;
370 symb /= (mclk >> 12);
371 } else if (srate > 6000000) {
372 symb = srate << 6;
373 symb /= (mclk >> 10);
374 } else {
375 symb = srate << 9;
376 symb /= (mclk >> 7);
377 }
378
379 if (symb < 0x7fff) {
380 stv0900_write_reg(intp, SFRUP1, (symb >> 8) & 0x7f);
381 stv0900_write_reg(intp, SFRUP1 + 1, (symb & 0xff));
382 } else {
383 stv0900_write_reg(intp, SFRUP1, 0x7f);
384 stv0900_write_reg(intp, SFRUP1 + 1, 0xff);
385 }
386}
387
388static void stv0900_set_min_symbol_rate(struct stv0900_internal *intp,
389 u32 mclk, u32 srate,
390 enum fe_stv0900_demod_num demod)
391{
392 u32 symb;
393
394 srate = 95 * (srate / 100);
395 if (srate > 60000000) {
396 symb = srate << 4;
397 symb /= (mclk >> 12);
398
399 } else if (srate > 6000000) {
400 symb = srate << 6;
401 symb /= (mclk >> 10);
402
403 } else {
404 symb = srate << 9;
405 symb /= (mclk >> 7);
406 }
407
408 stv0900_write_reg(intp, SFRLOW1, (symb >> 8) & 0xff);
409 stv0900_write_reg(intp, SFRLOW1 + 1, (symb & 0xff));
410}
411
412static s32 stv0900_get_timing_offst(struct stv0900_internal *intp,
413 u32 srate,
414 enum fe_stv0900_demod_num demod)
415{
416 s32 timingoffset;
417
418
419 timingoffset = (stv0900_read_reg(intp, TMGREG2) << 16) +
420 (stv0900_read_reg(intp, TMGREG2 + 1) << 8) +
421 (stv0900_read_reg(intp, TMGREG2 + 2));
422
423 timingoffset = ge2comp(timingoffset, 24);
424
425
426 if (timingoffset == 0)
427 timingoffset = 1;
428
429 timingoffset = ((s32)srate * 10) / ((s32)0x1000000 / timingoffset);
430 timingoffset /= 320;
431
432 return timingoffset;
433}
434
435static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *intp,
436 enum fe_stv0900_demod_num demod)
437{
438 s32 rolloff;
439
440 if (intp->chip_id == 0x10) {
441 stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
442 rolloff = stv0900_read_reg(intp, MATSTR1) & 0x03;
443 stv0900_write_bits(intp, ROLLOFF_CONTROL, rolloff);
444 } else if (intp->chip_id <= 0x20)
445 stv0900_write_bits(intp, MANUALSX_ROLLOFF, 0);
446 else /* cut 3.0 */
447 stv0900_write_bits(intp, MANUALS2_ROLLOFF, 0);
448}
449
450static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro)
451{
452 u32 rolloff;
453
454 switch (ro) {
455 case STV0900_20:
456 rolloff = 20;
457 break;
458 case STV0900_25:
459 rolloff = 25;
460 break;
461 case STV0900_35:
462 default:
463 rolloff = 35;
464 break;
465 }
466
467 return srate + (srate * rolloff) / 100;
468}
469
470static int stv0900_check_timing_lock(struct stv0900_internal *intp,
471 enum fe_stv0900_demod_num demod)
472{
473 int timingLock = FALSE;
474 s32 i,
475 timingcpt = 0;
476 u8 car_freq,
477 tmg_th_high,
478 tmg_th_low;
479
480 car_freq = stv0900_read_reg(intp, CARFREQ);
481 tmg_th_high = stv0900_read_reg(intp, TMGTHRISE);
482 tmg_th_low = stv0900_read_reg(intp, TMGTHFALL);
483 stv0900_write_reg(intp, TMGTHRISE, 0x20);
484 stv0900_write_reg(intp, TMGTHFALL, 0x0);
485 stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
486 stv0900_write_reg(intp, RTC, 0x80);
487 stv0900_write_reg(intp, RTCS2, 0x40);
488 stv0900_write_reg(intp, CARFREQ, 0x0);
489 stv0900_write_reg(intp, CFRINIT1, 0x0);
490 stv0900_write_reg(intp, CFRINIT0, 0x0);
491 stv0900_write_reg(intp, AGC2REF, 0x65);
492 stv0900_write_reg(intp, DMDISTATE, 0x18);
493 msleep(7);
494
495 for (i = 0; i < 10; i++) {
496 if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
497 timingcpt++;
498
499 msleep(1);
500 }
501
502 if (timingcpt >= 3)
503 timingLock = TRUE;
504
505 stv0900_write_reg(intp, AGC2REF, 0x38);
506 stv0900_write_reg(intp, RTC, 0x88);
507 stv0900_write_reg(intp, RTCS2, 0x68);
508 stv0900_write_reg(intp, CARFREQ, car_freq);
509 stv0900_write_reg(intp, TMGTHRISE, tmg_th_high);
510 stv0900_write_reg(intp, TMGTHFALL, tmg_th_low);
511
512 return timingLock;
513}
514
515static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe,
516 s32 demod_timeout)
517{
518 struct stv0900_state *state = fe->demodulator_priv;
519 struct stv0900_internal *intp = state->internal;
520 enum fe_stv0900_demod_num demod = state->demod;
521 int lock = FALSE,
522 d = demod;
523 s32 srate,
524 search_range,
525 locktimeout,
526 currier_step,
527 nb_steps,
528 current_step,
529 direction,
530 tuner_freq,
531 timeout,
532 freq;
533
534 srate = intp->symbol_rate[d];
535 search_range = intp->srch_range[d];
536
537 if (srate >= 10000000)
538 locktimeout = demod_timeout / 3;
539 else
540 locktimeout = demod_timeout / 2;
541
542 lock = stv0900_get_demod_lock(intp, d, locktimeout);
543
544 if (lock != FALSE)
545 return lock;
546
547 if (srate >= 10000000) {
548 if (stv0900_check_timing_lock(intp, d) == TRUE) {
549 stv0900_write_reg(intp, DMDISTATE, 0x1f);
550 stv0900_write_reg(intp, DMDISTATE, 0x15);
551 lock = stv0900_get_demod_lock(intp, d, demod_timeout);
552 } else
553 lock = FALSE;
554
555 return lock;
556 }
557
558 if (intp->chip_id <= 0x20) {
559 if (srate <= 1000000)
560 currier_step = 500;
561 else if (srate <= 4000000)
562 currier_step = 1000;
563 else if (srate <= 7000000)
564 currier_step = 2000;
565 else if (srate <= 10000000)
566 currier_step = 3000;
567 else
568 currier_step = 5000;
569
570 if (srate >= 2000000) {
571 timeout = (demod_timeout / 3);
572 if (timeout > 1000)
573 timeout = 1000;
574 } else
575 timeout = (demod_timeout / 2);
576 } else {
577 /*cut 3.0 */
578 currier_step = srate / 4000;
579 timeout = (demod_timeout * 3) / 4;
580 }
581
582 nb_steps = ((search_range / 1000) / currier_step);
583
584 if ((nb_steps % 2) != 0)
585 nb_steps += 1;
586
587 if (nb_steps <= 0)
588 nb_steps = 2;
589 else if (nb_steps > 12)
590 nb_steps = 12;
591
592 current_step = 1;
593 direction = 1;
594
595 if (intp->chip_id <= 0x20) {
596 tuner_freq = intp->freq[d];
597 intp->bw[d] = stv0900_carrier_width(intp->symbol_rate[d],
598 intp->rolloff) + intp->symbol_rate[d];
599 } else
600 tuner_freq = 0;
601
602 while ((current_step <= nb_steps) && (lock == FALSE)) {
603 if (direction > 0)
604 tuner_freq += (current_step * currier_step);
605 else
606 tuner_freq -= (current_step * currier_step);
607
608 if (intp->chip_id <= 0x20) {
609 if (intp->tuner_type[d] == 3)
610 stv0900_set_tuner_auto(intp, tuner_freq,
611 intp->bw[d], demod);
612 else
613 stv0900_set_tuner(fe, tuner_freq, intp->bw[d]);
614
615 stv0900_write_reg(intp, DMDISTATE, 0x1c);
616 stv0900_write_reg(intp, CFRINIT1, 0);
617 stv0900_write_reg(intp, CFRINIT0, 0);
618 stv0900_write_reg(intp, DMDISTATE, 0x1f);
619 stv0900_write_reg(intp, DMDISTATE, 0x15);
620 } else {
621 stv0900_write_reg(intp, DMDISTATE, 0x1c);
622 freq = (tuner_freq * 65536) / (intp->mclk / 1000);
623 stv0900_write_bits(intp, CFR_INIT1, MSB(freq));
624 stv0900_write_bits(intp, CFR_INIT0, LSB(freq));
625 stv0900_write_reg(intp, DMDISTATE, 0x1f);
626 stv0900_write_reg(intp, DMDISTATE, 0x05);
627 }
628
629 lock = stv0900_get_demod_lock(intp, d, timeout);
630 direction *= -1;
631 current_step++;
632 }
633
634 return lock;
635}
636
637static void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout,
638 s32 srate,
639 enum fe_stv0900_search_algo algo)
640{
641 switch (algo) {
642 case STV0900_BLIND_SEARCH:
643 if (srate <= 1500000) {
644 (*demod_timeout) = 1500;
645 (*fec_timeout) = 400;
646 } else if (srate <= 5000000) {
647 (*demod_timeout) = 1000;
648 (*fec_timeout) = 300;
649 } else {
650 (*demod_timeout) = 700;
651 (*fec_timeout) = 100;
652 }
653
654 break;
655 case STV0900_COLD_START:
656 case STV0900_WARM_START:
657 default:
658 if (srate <= 1000000) {
659 (*demod_timeout) = 3000;
660 (*fec_timeout) = 1700;
661 } else if (srate <= 2000000) {
662 (*demod_timeout) = 2500;
663 (*fec_timeout) = 1100;
664 } else if (srate <= 5000000) {
665 (*demod_timeout) = 1000;
666 (*fec_timeout) = 550;
667 } else if (srate <= 10000000) {
668 (*demod_timeout) = 700;
669 (*fec_timeout) = 250;
670 } else if (srate <= 20000000) {
671 (*demod_timeout) = 400;
672 (*fec_timeout) = 130;
673 } else {
674 (*demod_timeout) = 300;
675 (*fec_timeout) = 100;
676 }
677
678 break;
679
680 }
681
682 if (algo == STV0900_WARM_START)
683 (*demod_timeout) /= 2;
684}
685
686static void stv0900_set_viterbi_tracq(struct stv0900_internal *intp,
687 enum fe_stv0900_demod_num demod)
688{
689
690 s32 vth_reg = VTH12;
691
692 dprintk("%s\n", __func__);
693
694 stv0900_write_reg(intp, vth_reg++, 0xd0);
695 stv0900_write_reg(intp, vth_reg++, 0x7d);
696 stv0900_write_reg(intp, vth_reg++, 0x53);
697 stv0900_write_reg(intp, vth_reg++, 0x2f);
698 stv0900_write_reg(intp, vth_reg++, 0x24);
699 stv0900_write_reg(intp, vth_reg++, 0x1f);
700}
701
702static void stv0900_set_viterbi_standard(struct stv0900_internal *intp,
703 enum fe_stv0900_search_standard standard,
704 enum fe_stv0900_fec fec,
705 enum fe_stv0900_demod_num demod)
706{
707 dprintk("%s: ViterbiStandard = ", __func__);
708
709 switch (standard) {
710 case STV0900_AUTO_SEARCH:
711 dprintk("Auto\n");
712 stv0900_write_reg(intp, FECM, 0x10);
713 stv0900_write_reg(intp, PRVIT, 0x3f);
714 break;
715 case STV0900_SEARCH_DVBS1:
716 dprintk("DVBS1\n");
717 stv0900_write_reg(intp, FECM, 0x00);
718 switch (fec) {
719 case STV0900_FEC_UNKNOWN:
720 default:
721 stv0900_write_reg(intp, PRVIT, 0x2f);
722 break;
723 case STV0900_FEC_1_2:
724 stv0900_write_reg(intp, PRVIT, 0x01);
725 break;
726 case STV0900_FEC_2_3:
727 stv0900_write_reg(intp, PRVIT, 0x02);
728 break;
729 case STV0900_FEC_3_4:
730 stv0900_write_reg(intp, PRVIT, 0x04);
731 break;
732 case STV0900_FEC_5_6:
733 stv0900_write_reg(intp, PRVIT, 0x08);
734 break;
735 case STV0900_FEC_7_8:
736 stv0900_write_reg(intp, PRVIT, 0x20);
737 break;
738 }
739
740 break;
741 case STV0900_SEARCH_DSS:
742 dprintk("DSS\n");
743 stv0900_write_reg(intp, FECM, 0x80);
744 switch (fec) {
745 case STV0900_FEC_UNKNOWN:
746 default:
747 stv0900_write_reg(intp, PRVIT, 0x13);
748 break;
749 case STV0900_FEC_1_2:
750 stv0900_write_reg(intp, PRVIT, 0x01);
751 break;
752 case STV0900_FEC_2_3:
753 stv0900_write_reg(intp, PRVIT, 0x02);
754 break;
755 case STV0900_FEC_6_7:
756 stv0900_write_reg(intp, PRVIT, 0x10);
757 break;
758 }
759 break;
760 default:
761 break;
762 }
763}
764
765static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *intp,
766 enum fe_stv0900_demod_num demod)
767{
768 enum fe_stv0900_fec prate;
769 s32 rate_fld = stv0900_get_bits(intp, VIT_CURPUN);
770
771 switch (rate_fld) {
772 case 13:
773 prate = STV0900_FEC_1_2;
774 break;
775 case 18:
776 prate = STV0900_FEC_2_3;
777 break;
778 case 21:
779 prate = STV0900_FEC_3_4;
780 break;
781 case 24:
782 prate = STV0900_FEC_5_6;
783 break;
784 case 25:
785 prate = STV0900_FEC_6_7;
786 break;
787 case 26:
788 prate = STV0900_FEC_7_8;
789 break;
790 default:
791 prate = STV0900_FEC_UNKNOWN;
792 break;
793 }
794
795 return prate;
796}
797
798static void stv0900_set_dvbs1_track_car_loop(struct stv0900_internal *intp,
799 enum fe_stv0900_demod_num demod,
800 u32 srate)
801{
802 if (intp->chip_id >= 0x30) {
803 if (srate >= 15000000) {
804 stv0900_write_reg(intp, ACLC, 0x2b);
805 stv0900_write_reg(intp, BCLC, 0x1a);
806 } else if ((srate >= 7000000) && (15000000 > srate)) {
807 stv0900_write_reg(intp, ACLC, 0x0c);
808 stv0900_write_reg(intp, BCLC, 0x1b);
809 } else if (srate < 7000000) {
810 stv0900_write_reg(intp, ACLC, 0x2c);
811 stv0900_write_reg(intp, BCLC, 0x1c);
812 }
813
814 } else { /*cut 2.0 and 1.x*/
815 stv0900_write_reg(intp, ACLC, 0x1a);
816 stv0900_write_reg(intp, BCLC, 0x09);
817 }
818
819}
820
821static void stv0900_track_optimization(struct dvb_frontend *fe)
822{
823 struct stv0900_state *state = fe->demodulator_priv;
824 struct stv0900_internal *intp = state->internal;
825 enum fe_stv0900_demod_num demod = state->demod;
826
827 s32 srate,
828 pilots,
829 aclc,
830 freq1,
831 freq0,
832 i = 0,
833 timed,
834 timef,
835 blind_tun_sw = 0,
836 modulation;
837
838 enum fe_stv0900_rolloff rolloff;
839 enum fe_stv0900_modcode foundModcod;
840
841 dprintk("%s\n", __func__);
842
843 srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
844 srate += stv0900_get_timing_offst(intp, srate, demod);
845
846 switch (intp->result[demod].standard) {
847 case STV0900_DVBS1_STANDARD:
848 case STV0900_DSS_STANDARD:
849 dprintk("%s: found DVB-S or DSS\n", __func__);
850 if (intp->srch_standard[demod] == STV0900_AUTO_SEARCH) {
851 stv0900_write_bits(intp, DVBS1_ENABLE, 1);
852 stv0900_write_bits(intp, DVBS2_ENABLE, 0);
853 }
854
855 stv0900_write_bits(intp, ROLLOFF_CONTROL, intp->rolloff);
856 stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
857
858 if (intp->chip_id < 0x30) {
859 stv0900_write_reg(intp, ERRCTRL1, 0x75);
860 break;
861 }
862
863 if (stv0900_get_vit_fec(intp, demod) == STV0900_FEC_1_2) {
864 stv0900_write_reg(intp, GAUSSR0, 0x98);
865 stv0900_write_reg(intp, CCIR0, 0x18);
866 } else {
867 stv0900_write_reg(intp, GAUSSR0, 0x18);
868 stv0900_write_reg(intp, CCIR0, 0x18);
869 }
870
871 stv0900_write_reg(intp, ERRCTRL1, 0x75);
872 break;
873 case STV0900_DVBS2_STANDARD:
874 dprintk("%s: found DVB-S2\n", __func__);
875 stv0900_write_bits(intp, DVBS1_ENABLE, 0);
876 stv0900_write_bits(intp, DVBS2_ENABLE, 1);
877 stv0900_write_reg(intp, ACLC, 0);
878 stv0900_write_reg(intp, BCLC, 0);
879 if (intp->result[demod].frame_len == STV0900_LONG_FRAME) {
880 foundModcod = stv0900_get_bits(intp, DEMOD_MODCOD);
881 pilots = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
882 aclc = stv0900_get_optim_carr_loop(srate,
883 foundModcod,
884 pilots,
885 intp->chip_id);
886 if (foundModcod <= STV0900_QPSK_910)
887 stv0900_write_reg(intp, ACLC2S2Q, aclc);
888 else if (foundModcod <= STV0900_8PSK_910) {
889 stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
890 stv0900_write_reg(intp, ACLC2S28, aclc);
891 }
892
893 if ((intp->demod_mode == STV0900_SINGLE) &&
894 (foundModcod > STV0900_8PSK_910)) {
895 if (foundModcod <= STV0900_16APSK_910) {
896 stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
897 stv0900_write_reg(intp, ACLC2S216A,
898 aclc);
899 } else if (foundModcod <= STV0900_32APSK_910) {
900 stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
901 stv0900_write_reg(intp, ACLC2S232A,
902 aclc);
903 }
904 }
905
906 } else {
907 modulation = intp->result[demod].modulation;
908 aclc = stv0900_get_optim_short_carr_loop(srate,
909 modulation, intp->chip_id);
910 if (modulation == STV0900_QPSK)
911 stv0900_write_reg(intp, ACLC2S2Q, aclc);
912 else if (modulation == STV0900_8PSK) {
913 stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
914 stv0900_write_reg(intp, ACLC2S28, aclc);
915 } else if (modulation == STV0900_16APSK) {
916 stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
917 stv0900_write_reg(intp, ACLC2S216A, aclc);
918 } else if (modulation == STV0900_32APSK) {
919 stv0900_write_reg(intp, ACLC2S2Q, 0x2a);
920 stv0900_write_reg(intp, ACLC2S232A, aclc);
921 }
922
923 }
924
925 if (intp->chip_id <= 0x11) {
926 if (intp->demod_mode != STV0900_SINGLE)
927 stv0900_activate_s2_modcod(intp, demod);
928
929 }
930
931 stv0900_write_reg(intp, ERRCTRL1, 0x67);
932 break;
933 case STV0900_UNKNOWN_STANDARD:
934 default:
935 dprintk("%s: found unknown standard\n", __func__);
936 stv0900_write_bits(intp, DVBS1_ENABLE, 1);
937 stv0900_write_bits(intp, DVBS2_ENABLE, 1);
938 break;
939 }
940
941 freq1 = stv0900_read_reg(intp, CFR2);
942 freq0 = stv0900_read_reg(intp, CFR1);
943 rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
944 if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
945 stv0900_write_reg(intp, SFRSTEP, 0x00);
946 stv0900_write_bits(intp, SCAN_ENABLE, 0);
947 stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
948 stv0900_write_reg(intp, TMGCFG2, 0xc1);
949 stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
950 blind_tun_sw = 1;
951 if (intp->result[demod].standard != STV0900_DVBS2_STANDARD)
952 stv0900_set_dvbs1_track_car_loop(intp, demod, srate);
953
954 }
955
956 if (intp->chip_id >= 0x20) {
957 if ((intp->srch_standard[demod] == STV0900_SEARCH_DVBS1) ||
958 (intp->srch_standard[demod] ==
959 STV0900_SEARCH_DSS) ||
960 (intp->srch_standard[demod] ==
961 STV0900_AUTO_SEARCH)) {
962 stv0900_write_reg(intp, VAVSRVIT, 0x0a);
963 stv0900_write_reg(intp, VITSCALE, 0x0);
964 }
965 }
966
967 if (intp->chip_id < 0x20)
968 stv0900_write_reg(intp, CARHDR, 0x08);
969
970 if (intp->chip_id == 0x10)
971 stv0900_write_reg(intp, CORRELEXP, 0x0a);
972
973 stv0900_write_reg(intp, AGC2REF, 0x38);
974
975 if ((intp->chip_id >= 0x20) ||
976 (blind_tun_sw == 1) ||
977 (intp->symbol_rate[demod] < 10000000)) {
978 stv0900_write_reg(intp, CFRINIT1, freq1);
979 stv0900_write_reg(intp, CFRINIT0, freq0);
980 intp->bw[demod] = stv0900_carrier_width(srate,
981 intp->rolloff) + 10000000;
982
983 if ((intp->chip_id >= 0x20) || (blind_tun_sw == 1)) {
984 if (intp->srch_algo[demod] != STV0900_WARM_START) {
985 if (intp->tuner_type[demod] == 3)
986 stv0900_set_tuner_auto(intp,
987 intp->freq[demod],
988 intp->bw[demod],
989 demod);
990 else
991 stv0900_set_bandwidth(fe,
992 intp->bw[demod]);
993 }
994 }
995
996 if ((intp->srch_algo[demod] == STV0900_BLIND_SEARCH) ||
997 (intp->symbol_rate[demod] < 10000000))
998 msleep(50);
999 else
1000 msleep(5);
1001
1002 stv0900_get_lock_timeout(&timed, &timef, srate,
1003 STV0900_WARM_START);
1004
1005 if (stv0900_get_demod_lock(intp, demod, timed / 2) == FALSE) {
1006 stv0900_write_reg(intp, DMDISTATE, 0x1f);
1007 stv0900_write_reg(intp, CFRINIT1, freq1);
1008 stv0900_write_reg(intp, CFRINIT0, freq0);
1009 stv0900_write_reg(intp, DMDISTATE, 0x18);
1010 i = 0;
1011 while ((stv0900_get_demod_lock(intp,
1012 demod,
1013 timed / 2) == FALSE) &&
1014 (i <= 2)) {
1015 stv0900_write_reg(intp, DMDISTATE, 0x1f);
1016 stv0900_write_reg(intp, CFRINIT1, freq1);
1017 stv0900_write_reg(intp, CFRINIT0, freq0);
1018 stv0900_write_reg(intp, DMDISTATE, 0x18);
1019 i++;
1020 }
1021 }
1022
1023 }
1024
1025 if (intp->chip_id >= 0x20)
1026 stv0900_write_reg(intp, CARFREQ, 0x49);
1027
1028 if ((intp->result[demod].standard == STV0900_DVBS1_STANDARD) ||
1029 (intp->result[demod].standard == STV0900_DSS_STANDARD))
1030 stv0900_set_viterbi_tracq(intp, demod);
1031
1032}
1033
1034static int stv0900_get_fec_lock(struct stv0900_internal *intp,
1035 enum fe_stv0900_demod_num demod, s32 time_out)
1036{
1037 s32 timer = 0, lock = 0;
1038
1039 enum fe_stv0900_search_state dmd_state;
1040
1041 dprintk("%s\n", __func__);
1042
1043 dmd_state = stv0900_get_bits(intp, HEADER_MODE);
1044
1045 while ((timer < time_out) && (lock == 0)) {
1046 switch (dmd_state) {
1047 case STV0900_SEARCH:
1048 case STV0900_PLH_DETECTED:
1049 default:
1050 lock = 0;
1051 break;
1052 case STV0900_DVBS2_FOUND:
1053 lock = stv0900_get_bits(intp, PKTDELIN_LOCK);
1054 break;
1055 case STV0900_DVBS_FOUND:
1056 lock = stv0900_get_bits(intp, LOCKEDVIT);
1057 break;
1058 }
1059
1060 if (lock == 0) {
1061 msleep(10);
1062 timer += 10;
1063 }
1064 }
1065
1066 if (lock)
1067 dprintk("%s: DEMOD FEC LOCK OK\n", __func__);
1068 else
1069 dprintk("%s: DEMOD FEC LOCK FAIL\n", __func__);
1070
1071 return lock;
1072}
1073
1074static int stv0900_wait_for_lock(struct stv0900_internal *intp,
1075 enum fe_stv0900_demod_num demod,
1076 s32 dmd_timeout, s32 fec_timeout)
1077{
1078
1079 s32 timer = 0, lock = 0;
1080
1081 dprintk("%s\n", __func__);
1082
1083 lock = stv0900_get_demod_lock(intp, demod, dmd_timeout);
1084
1085 if (lock)
1086 lock = lock && stv0900_get_fec_lock(intp, demod, fec_timeout);
1087
1088 if (lock) {
1089 lock = 0;
1090
1091 dprintk("%s: Timer = %d, time_out = %d\n",
1092 __func__, timer, fec_timeout);
1093
1094 while ((timer < fec_timeout) && (lock == 0)) {
1095 lock = stv0900_get_bits(intp, TSFIFO_LINEOK);
1096 msleep(1);
1097 timer++;
1098 }
1099 }
1100
1101 if (lock)
1102 dprintk("%s: DEMOD LOCK OK\n", __func__);
1103 else
1104 dprintk("%s: DEMOD LOCK FAIL\n", __func__);
1105
1106 if (lock)
1107 return TRUE;
1108 else
1109 return FALSE;
1110}
1111
1112enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
1113 enum fe_stv0900_demod_num demod)
1114{
1115 struct stv0900_state *state = fe->demodulator_priv;
1116 struct stv0900_internal *intp = state->internal;
1117 enum fe_stv0900_tracking_standard fnd_standard;
1118
1119 int hdr_mode = stv0900_get_bits(intp, HEADER_MODE);
1120
1121 switch (hdr_mode) {
1122 case 2:
1123 fnd_standard = STV0900_DVBS2_STANDARD;
1124 break;
1125 case 3:
1126 if (stv0900_get_bits(intp, DSS_DVB) == 1)
1127 fnd_standard = STV0900_DSS_STANDARD;
1128 else
1129 fnd_standard = STV0900_DVBS1_STANDARD;
1130
1131 break;
1132 default:
1133 fnd_standard = STV0900_UNKNOWN_STANDARD;
1134 }
1135
1136 dprintk("%s: standard %d\n", __func__, fnd_standard);
1137
1138 return fnd_standard;
1139}
1140
1141static s32 stv0900_get_carr_freq(struct stv0900_internal *intp, u32 mclk,
1142 enum fe_stv0900_demod_num demod)
1143{
1144 s32 derot,
1145 rem1,
1146 rem2,
1147 intval1,
1148 intval2;
1149
1150 derot = (stv0900_get_bits(intp, CAR_FREQ2) << 16) +
1151 (stv0900_get_bits(intp, CAR_FREQ1) << 8) +
1152 (stv0900_get_bits(intp, CAR_FREQ0));
1153
1154 derot = ge2comp(derot, 24);
1155 intval1 = mclk >> 12;
1156 intval2 = derot >> 12;
1157 rem1 = mclk % 0x1000;
1158 rem2 = derot % 0x1000;
1159 derot = (intval1 * intval2) +
1160 ((intval1 * rem2) >> 12) +
1161 ((intval2 * rem1) >> 12);
1162
1163 return derot;
1164}
1165
1166static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe)
1167{
1168 struct dvb_frontend_ops *frontend_ops = NULL;
1169 struct dvb_tuner_ops *tuner_ops = NULL;
1170 u32 freq = 0;
1171
1172 if (&fe->ops)
1173 frontend_ops = &fe->ops;
1174
1175 if (&frontend_ops->tuner_ops)
1176 tuner_ops = &frontend_ops->tuner_ops;
1177
1178 if (tuner_ops->get_frequency) {
1179 if ((tuner_ops->get_frequency(fe, &freq)) < 0)
1180 dprintk("%s: Invalid parameter\n", __func__);
1181 else
1182 dprintk("%s: Frequency=%d\n", __func__, freq);
1183
1184 }
1185
1186 return freq;
1187}
1188
1189static enum
1190fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
1191{
1192 struct stv0900_state *state = fe->demodulator_priv;
1193 struct stv0900_internal *intp = state->internal;
1194 enum fe_stv0900_demod_num demod = state->demod;
1195 enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE;
1196 struct stv0900_signal_info *result = &intp->result[demod];
1197 s32 offsetFreq,
1198 srate_offset;
1199 int i = 0,
1200 d = demod;
1201
1202 u8 timing;
1203
1204 msleep(5);
1205 if (intp->srch_algo[d] == STV0900_BLIND_SEARCH) {
1206 timing = stv0900_read_reg(intp, TMGREG2);
1207 i = 0;
1208 stv0900_write_reg(intp, SFRSTEP, 0x5c);
1209
1210 while ((i <= 50) && (timing != 0) && (timing != 0xff)) {
1211 timing = stv0900_read_reg(intp, TMGREG2);
1212 msleep(5);
1213 i += 5;
1214 }
1215 }
1216
1217 result->standard = stv0900_get_standard(fe, d);
1218 if (intp->tuner_type[demod] == 3)
1219 result->frequency = stv0900_get_freq_auto(intp, d);
1220 else
1221 result->frequency = stv0900_get_tuner_freq(fe);
1222
1223 offsetFreq = stv0900_get_carr_freq(intp, intp->mclk, d) / 1000;
1224 result->frequency += offsetFreq;
1225 result->symbol_rate = stv0900_get_symbol_rate(intp, intp->mclk, d);
1226 srate_offset = stv0900_get_timing_offst(intp, result->symbol_rate, d);
1227 result->symbol_rate += srate_offset;
1228 result->fec = stv0900_get_vit_fec(intp, d);
1229 result->modcode = stv0900_get_bits(intp, DEMOD_MODCOD);
1230 result->pilot = stv0900_get_bits(intp, DEMOD_TYPE) & 0x01;
1231 result->frame_len = ((u32)stv0900_get_bits(intp, DEMOD_TYPE)) >> 1;
1232 result->rolloff = stv0900_get_bits(intp, ROLLOFF_STATUS);
1233
1234 dprintk("%s: modcode=0x%x \n", __func__, result->modcode);
1235
1236 switch (result->standard) {
1237 case STV0900_DVBS2_STANDARD:
1238 result->spectrum = stv0900_get_bits(intp, SPECINV_DEMOD);
1239 if (result->modcode <= STV0900_QPSK_910)
1240 result->modulation = STV0900_QPSK;
1241 else if (result->modcode <= STV0900_8PSK_910)
1242 result->modulation = STV0900_8PSK;
1243 else if (result->modcode <= STV0900_16APSK_910)
1244 result->modulation = STV0900_16APSK;
1245 else if (result->modcode <= STV0900_32APSK_910)
1246 result->modulation = STV0900_32APSK;
1247 else
1248 result->modulation = STV0900_UNKNOWN;
1249 break;
1250 case STV0900_DVBS1_STANDARD:
1251 case STV0900_DSS_STANDARD:
1252 result->spectrum = stv0900_get_bits(intp, IQINV);
1253 result->modulation = STV0900_QPSK;
1254 break;
1255 default:
1256 break;
1257 }
1258
1259 if ((intp->srch_algo[d] == STV0900_BLIND_SEARCH) ||
1260 (intp->symbol_rate[d] < 10000000)) {
1261 offsetFreq = result->frequency - intp->freq[d];
1262 if (intp->tuner_type[demod] == 3)
1263 intp->freq[d] = stv0900_get_freq_auto(intp, d);
1264 else
1265 intp->freq[d] = stv0900_get_tuner_freq(fe);
1266
1267 if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
1268 range = STV0900_RANGEOK;
1269 else if (ABS(offsetFreq) <=
1270 (stv0900_carrier_width(result->symbol_rate,
1271 result->rolloff) / 2000))
1272 range = STV0900_RANGEOK;
1273
1274 } else if (ABS(offsetFreq) <= ((intp->srch_range[d] / 2000) + 500))
1275 range = STV0900_RANGEOK;
1276
1277 dprintk("%s: range %d\n", __func__, range);
1278
1279 return range;
1280}
1281
1282static enum
1283fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe)
1284{
1285 struct stv0900_state *state = fe->demodulator_priv;
1286 struct stv0900_internal *intp = state->internal;
1287 enum fe_stv0900_demod_num demod = state->demod;
1288 enum fe_stv0900_signal_type signal_type = STV0900_NODATA;
1289
1290 s32 srate,
1291 demod_timeout,
1292 fec_timeout,
1293 freq1,
1294 freq0;
1295
1296 intp->result[demod].locked = FALSE;
1297
1298 if (stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) {
1299 srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
1300 srate += stv0900_get_timing_offst(intp, srate, demod);
1301 if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH)
1302 stv0900_set_symbol_rate(intp, intp->mclk, srate, demod);
1303
1304 stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
1305 srate, STV0900_WARM_START);
1306 freq1 = stv0900_read_reg(intp, CFR2);
1307 freq0 = stv0900_read_reg(intp, CFR1);
1308 stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
1309 stv0900_write_bits(intp, SPECINV_CONTROL,
1310 STV0900_IQ_FORCE_SWAPPED);
1311 stv0900_write_reg(intp, DMDISTATE, 0x1c);
1312 stv0900_write_reg(intp, CFRINIT1, freq1);
1313 stv0900_write_reg(intp, CFRINIT0, freq0);
1314 stv0900_write_reg(intp, DMDISTATE, 0x18);
1315 if (stv0900_wait_for_lock(intp, demod,
1316 demod_timeout, fec_timeout) == TRUE) {
1317 intp->result[demod].locked = TRUE;
1318 signal_type = stv0900_get_signal_params(fe);
1319 stv0900_track_optimization(fe);
1320 } else {
1321 stv0900_write_bits(intp, SPECINV_CONTROL,
1322 STV0900_IQ_FORCE_NORMAL);
1323 stv0900_write_reg(intp, DMDISTATE, 0x1c);
1324 stv0900_write_reg(intp, CFRINIT1, freq1);
1325 stv0900_write_reg(intp, CFRINIT0, freq0);
1326 stv0900_write_reg(intp, DMDISTATE, 0x18);
1327 if (stv0900_wait_for_lock(intp, demod,
1328 demod_timeout, fec_timeout) == TRUE) {
1329 intp->result[demod].locked = TRUE;
1330 signal_type = stv0900_get_signal_params(fe);
1331 stv0900_track_optimization(fe);
1332 }
1333
1334 }
1335
1336 } else
1337 intp->result[demod].locked = FALSE;
1338
1339 return signal_type;
1340}
1341
1342static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *intp,
1343 enum fe_stv0900_demod_num demod)
1344{
1345 u32 minagc2level = 0xffff,
1346 agc2level,
1347 init_freq, freq_step;
1348
1349 s32 i, j, nb_steps, direction;
1350
1351 dprintk("%s\n", __func__);
1352
1353 stv0900_write_reg(intp, AGC2REF, 0x38);
1354 stv0900_write_bits(intp, SCAN_ENABLE, 0);
1355 stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
1356
1357 stv0900_write_bits(intp, AUTO_GUP, 1);
1358 stv0900_write_bits(intp, AUTO_GLOW, 1);
1359
1360 stv0900_write_reg(intp, DMDT0M, 0x0);
1361
1362 stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
1363 nb_steps = -1 + (intp->srch_range[demod] / 1000000);
1364 nb_steps /= 2;
1365 nb_steps = (2 * nb_steps) + 1;
1366
1367 if (nb_steps < 0)
1368 nb_steps = 1;
1369
1370 direction = 1;
1371
1372 freq_step = (1000000 << 8) / (intp->mclk >> 8);
1373
1374 init_freq = 0;
1375
1376 for (i = 0; i < nb_steps; i++) {
1377 if (direction > 0)
1378 init_freq = init_freq + (freq_step * i);
1379 else
1380 init_freq = init_freq - (freq_step * i);
1381
1382 direction *= -1;
1383 stv0900_write_reg(intp, DMDISTATE, 0x5C);
1384 stv0900_write_reg(intp, CFRINIT1, (init_freq >> 8) & 0xff);
1385 stv0900_write_reg(intp, CFRINIT0, init_freq & 0xff);
1386 stv0900_write_reg(intp, DMDISTATE, 0x58);
1387 msleep(10);
1388 agc2level = 0;
1389
1390 for (j = 0; j < 10; j++)
1391 agc2level += (stv0900_read_reg(intp, AGC2I1) << 8)
1392 | stv0900_read_reg(intp, AGC2I0);
1393
1394 agc2level /= 10;
1395
1396 if (agc2level < minagc2level)
1397 minagc2level = agc2level;
1398
1399 }
1400
1401 return (u16)minagc2level;
1402}
1403
1404static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe)
1405{
1406 struct stv0900_state *state = fe->demodulator_priv;
1407 struct stv0900_internal *intp = state->internal;
1408 enum fe_stv0900_demod_num demod = state->demod;
1409 int timing_lck = FALSE;
1410 s32 i, timingcpt = 0,
1411 direction = 1,
1412 nb_steps,
1413 current_step = 0,
1414 tuner_freq;
1415 u32 agc2_th,
1416 coarse_srate = 0,
1417 agc2_integr = 0,
1418 currier_step = 1200;
1419
1420 if (intp->chip_id >= 0x30)
1421 agc2_th = 0x2e00;
1422 else
1423 agc2_th = 0x1f00;
1424
1425 stv0900_write_bits(intp, DEMOD_MODE, 0x1f);
1426 stv0900_write_reg(intp, TMGCFG, 0x12);
1427 stv0900_write_reg(intp, TMGTHRISE, 0xf0);
1428 stv0900_write_reg(intp, TMGTHFALL, 0xe0);
1429 stv0900_write_bits(intp, SCAN_ENABLE, 1);
1430 stv0900_write_bits(intp, CFR_AUTOSCAN, 1);
1431 stv0900_write_reg(intp, SFRUP1, 0x83);
1432 stv0900_write_reg(intp, SFRUP0, 0xc0);
1433 stv0900_write_reg(intp, SFRLOW1, 0x82);
1434 stv0900_write_reg(intp, SFRLOW0, 0xa0);
1435 stv0900_write_reg(intp, DMDT0M, 0x0);
1436 stv0900_write_reg(intp, AGC2REF, 0x50);
1437
1438 if (intp->chip_id >= 0x30) {
1439 stv0900_write_reg(intp, CARFREQ, 0x99);
1440 stv0900_write_reg(intp, SFRSTEP, 0x98);
1441 } else if (intp->chip_id >= 0x20) {
1442 stv0900_write_reg(intp, CARFREQ, 0x6a);
1443 stv0900_write_reg(intp, SFRSTEP, 0x95);
1444 } else {
1445 stv0900_write_reg(intp, CARFREQ, 0xed);
1446 stv0900_write_reg(intp, SFRSTEP, 0x73);
1447 }
1448
1449 if (intp->symbol_rate[demod] <= 2000000)
1450 currier_step = 1000;
1451 else if (intp->symbol_rate[demod] <= 5000000)
1452 currier_step = 2000;
1453 else if (intp->symbol_rate[demod] <= 12000000)
1454 currier_step = 3000;
1455 else
1456 currier_step = 5000;
1457
1458 nb_steps = -1 + ((intp->srch_range[demod] / 1000) / currier_step);
1459 nb_steps /= 2;
1460 nb_steps = (2 * nb_steps) + 1;
1461
1462 if (nb_steps < 0)
1463 nb_steps = 1;
1464 else if (nb_steps > 10) {
1465 nb_steps = 11;
1466 currier_step = (intp->srch_range[demod] / 1000) / 10;
1467 }
1468
1469 current_step = 0;
1470 direction = 1;
1471
1472 tuner_freq = intp->freq[demod];
1473
1474 while ((timing_lck == FALSE) && (current_step < nb_steps)) {
1475 stv0900_write_reg(intp, DMDISTATE, 0x5f);
1476 stv0900_write_bits(intp, DEMOD_MODE, 0);
1477
1478 msleep(50);
1479
1480 for (i = 0; i < 10; i++) {
1481 if (stv0900_get_bits(intp, TMGLOCK_QUALITY) >= 2)
1482 timingcpt++;
1483
1484 agc2_integr += (stv0900_read_reg(intp, AGC2I1) << 8) |
1485 stv0900_read_reg(intp, AGC2I0);
1486 }
1487
1488 agc2_integr /= 10;
1489 coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
1490 current_step++;
1491 direction *= -1;
1492
1493 dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started."
1494 " tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n",
1495 tuner_freq, agc2_integr, coarse_srate, timingcpt);
1496
1497 if ((timingcpt >= 5) &&
1498 (agc2_integr < agc2_th) &&
1499 (coarse_srate < 55000000) &&
1500 (coarse_srate > 850000))
1501 timing_lck = TRUE;
1502 else if (current_step < nb_steps) {
1503 if (direction > 0)
1504 tuner_freq += (current_step * currier_step);
1505 else
1506 tuner_freq -= (current_step * currier_step);
1507
1508 if (intp->tuner_type[demod] == 3)
1509 stv0900_set_tuner_auto(intp, tuner_freq,
1510 intp->bw[demod], demod);
1511 else
1512 stv0900_set_tuner(fe, tuner_freq,
1513 intp->bw[demod]);
1514 }
1515 }
1516
1517 if (timing_lck == FALSE)
1518 coarse_srate = 0;
1519 else
1520 coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
1521
1522 return coarse_srate;
1523}
1524
1525static u32 stv0900_search_srate_fine(struct dvb_frontend *fe)
1526{
1527 struct stv0900_state *state = fe->demodulator_priv;
1528 struct stv0900_internal *intp = state->internal;
1529 enum fe_stv0900_demod_num demod = state->demod;
1530 u32 coarse_srate,
1531 coarse_freq,
1532 symb,
1533 symbmax,
1534 symbmin,
1535 symbcomp;
1536
1537 coarse_srate = stv0900_get_symbol_rate(intp, intp->mclk, demod);
1538
1539 if (coarse_srate > 3000000) {
1540 symbmax = 13 * (coarse_srate / 10);
1541 symbmax = (symbmax / 1000) * 65536;
1542 symbmax /= (intp->mclk / 1000);
1543
1544 symbmin = 10 * (coarse_srate / 13);
1545 symbmin = (symbmin / 1000)*65536;
1546 symbmin /= (intp->mclk / 1000);
1547
1548 symb = (coarse_srate / 1000) * 65536;
1549 symb /= (intp->mclk / 1000);
1550 } else {
1551 symbmax = 13 * (coarse_srate / 10);
1552 symbmax = (symbmax / 100) * 65536;
1553 symbmax /= (intp->mclk / 100);
1554
1555 symbmin = 10 * (coarse_srate / 14);
1556 symbmin = (symbmin / 100) * 65536;
1557 symbmin /= (intp->mclk / 100);
1558
1559 symb = (coarse_srate / 100) * 65536;
1560 symb /= (intp->mclk / 100);
1561 }
1562
1563 symbcomp = 13 * (coarse_srate / 10);
1564 coarse_freq = (stv0900_read_reg(intp, CFR2) << 8)
1565 | stv0900_read_reg(intp, CFR1);
1566
1567 if (symbcomp < intp->symbol_rate[demod])
1568 coarse_srate = 0;
1569 else {
1570 stv0900_write_reg(intp, DMDISTATE, 0x1f);
1571 stv0900_write_reg(intp, TMGCFG2, 0xc1);
1572 stv0900_write_reg(intp, TMGTHRISE, 0x20);
1573 stv0900_write_reg(intp, TMGTHFALL, 0x00);
1574 stv0900_write_reg(intp, TMGCFG, 0xd2);
1575 stv0900_write_bits(intp, CFR_AUTOSCAN, 0);
1576 stv0900_write_reg(intp, AGC2REF, 0x38);
1577
1578 if (intp->chip_id >= 0x30)
1579 stv0900_write_reg(intp, CARFREQ, 0x79);
1580 else if (intp->chip_id >= 0x20)
1581 stv0900_write_reg(intp, CARFREQ, 0x49);
1582 else
1583 stv0900_write_reg(intp, CARFREQ, 0xed);
1584
1585 stv0900_write_reg(intp, SFRUP1, (symbmax >> 8) & 0x7f);
1586 stv0900_write_reg(intp, SFRUP0, (symbmax & 0xff));
1587
1588 stv0900_write_reg(intp, SFRLOW1, (symbmin >> 8) & 0x7f);
1589 stv0900_write_reg(intp, SFRLOW0, (symbmin & 0xff));
1590
1591 stv0900_write_reg(intp, SFRINIT1, (symb >> 8) & 0xff);
1592 stv0900_write_reg(intp, SFRINIT0, (symb & 0xff));
1593
1594 stv0900_write_reg(intp, DMDT0M, 0x20);
1595 stv0900_write_reg(intp, CFRINIT1, (coarse_freq >> 8) & 0xff);
1596 stv0900_write_reg(intp, CFRINIT0, coarse_freq & 0xff);
1597 stv0900_write_reg(intp, DMDISTATE, 0x15);
1598 }
1599
1600 return coarse_srate;
1601}
1602
1603static int stv0900_blind_search_algo(struct dvb_frontend *fe)
1604{
1605 struct stv0900_state *state = fe->demodulator_priv;
1606 struct stv0900_internal *intp = state->internal;
1607 enum fe_stv0900_demod_num demod = state->demod;
1608 u8 k_ref_tmg,
1609 k_ref_tmg_max,
1610 k_ref_tmg_min;
1611 u32 coarse_srate,
1612 agc2_th;
1613 int lock = FALSE,
1614 coarse_fail = FALSE;
1615 s32 demod_timeout = 500,
1616 fec_timeout = 50,
1617 fail_cpt,
1618 i,
1619 agc2_overflow;
1620 u16 agc2_int;
1621 u8 dstatus2;
1622
1623 dprintk("%s\n", __func__);
1624
1625 if (intp->chip_id < 0x20) {
1626 k_ref_tmg_max = 233;
1627 k_ref_tmg_min = 143;
1628 } else {
1629 k_ref_tmg_max = 110;
1630 k_ref_tmg_min = 10;
1631 }
1632
1633 if (intp->chip_id <= 0x20)
1634 agc2_th = STV0900_BLIND_SEARCH_AGC2_TH;
1635 else
1636 agc2_th = STV0900_BLIND_SEARCH_AGC2_TH_CUT30;
1637
1638 agc2_int = stv0900_blind_check_agc2_min_level(intp, demod);
1639
1640 dprintk("%s agc2_int=%d agc2_th=%d \n", __func__, agc2_int, agc2_th);
1641 if (agc2_int > agc2_th)
1642 return FALSE;
1643
1644 if (intp->chip_id == 0x10)
1645 stv0900_write_reg(intp, CORRELEXP, 0xaa);
1646
1647 if (intp->chip_id < 0x20)
1648 stv0900_write_reg(intp, CARHDR, 0x55);
1649 else
1650 stv0900_write_reg(intp, CARHDR, 0x20);
1651
1652 if (intp->chip_id <= 0x20)
1653 stv0900_write_reg(intp, CARCFG, 0xc4);
1654 else
1655 stv0900_write_reg(intp, CARCFG, 0x6);
1656
1657 stv0900_write_reg(intp, RTCS2, 0x44);
1658
1659 if (intp->chip_id >= 0x20) {
1660 stv0900_write_reg(intp, EQUALCFG, 0x41);
1661 stv0900_write_reg(intp, FFECFG, 0x41);
1662 stv0900_write_reg(intp, VITSCALE, 0x82);
1663 stv0900_write_reg(intp, VAVSRVIT, 0x0);
1664 }
1665
1666 k_ref_tmg = k_ref_tmg_max;
1667
1668 do {
1669 stv0900_write_reg(intp, KREFTMG, k_ref_tmg);
1670 if (stv0900_search_srate_coarse(fe) != 0) {
1671 coarse_srate = stv0900_search_srate_fine(fe);
1672
1673 if (coarse_srate != 0) {
1674 stv0900_get_lock_timeout(&demod_timeout,
1675 &fec_timeout,
1676 coarse_srate,
1677 STV0900_BLIND_SEARCH);
1678 lock = stv0900_get_demod_lock(intp,
1679 demod,
1680 demod_timeout);
1681 } else
1682 lock = FALSE;
1683 } else {
1684 fail_cpt = 0;
1685 agc2_overflow = 0;
1686
1687 for (i = 0; i < 10; i++) {
1688 agc2_int = (stv0900_read_reg(intp, AGC2I1) << 8)
1689 | stv0900_read_reg(intp, AGC2I0);
1690
1691 if (agc2_int >= 0xff00)
1692 agc2_overflow++;
1693
1694 dstatus2 = stv0900_read_reg(intp, DSTATUS2);
1695
1696 if (((dstatus2 & 0x1) == 0x1) &&
1697 ((dstatus2 >> 7) == 1))
1698 fail_cpt++;
1699 }
1700
1701 if ((fail_cpt > 7) || (agc2_overflow > 7))
1702 coarse_fail = TRUE;
1703
1704 lock = FALSE;
1705 }
1706 k_ref_tmg -= 30;
1707 } while ((k_ref_tmg >= k_ref_tmg_min) &&
1708 (lock == FALSE) &&
1709 (coarse_fail == FALSE));
1710
1711 return lock;
1712}
1713
1714static void stv0900_set_viterbi_acq(struct stv0900_internal *intp,
1715 enum fe_stv0900_demod_num demod)
1716{
1717 s32 vth_reg = VTH12;
1718
1719 dprintk("%s\n", __func__);
1720
1721 stv0900_write_reg(intp, vth_reg++, 0x96);
1722 stv0900_write_reg(intp, vth_reg++, 0x64);
1723 stv0900_write_reg(intp, vth_reg++, 0x36);
1724 stv0900_write_reg(intp, vth_reg++, 0x23);
1725 stv0900_write_reg(intp, vth_reg++, 0x1e);
1726 stv0900_write_reg(intp, vth_reg++, 0x19);
1727}
1728
1729static void stv0900_set_search_standard(struct stv0900_internal *intp,
1730 enum fe_stv0900_demod_num demod)
1731{
1732
1733 dprintk("%s\n", __func__);
1734
1735 switch (intp->srch_standard[demod]) {
1736 case STV0900_SEARCH_DVBS1:
1737 dprintk("Search Standard = DVBS1\n");
1738 break;
1739 case STV0900_SEARCH_DSS:
1740 dprintk("Search Standard = DSS\n");
1741 case STV0900_SEARCH_DVBS2:
1742 break;
1743 dprintk("Search Standard = DVBS2\n");
1744 case STV0900_AUTO_SEARCH:
1745 default:
1746 dprintk("Search Standard = AUTO\n");
1747 break;
1748 }
1749
1750 switch (intp->srch_standard[demod]) {
1751 case STV0900_SEARCH_DVBS1:
1752 case STV0900_SEARCH_DSS:
1753 stv0900_write_bits(intp, DVBS1_ENABLE, 1);
1754 stv0900_write_bits(intp, DVBS2_ENABLE, 0);
1755 stv0900_write_bits(intp, STOP_CLKVIT, 0);
1756 stv0900_set_dvbs1_track_car_loop(intp,
1757 demod,
1758 intp->symbol_rate[demod]);
1759 stv0900_write_reg(intp, CAR2CFG, 0x22);
1760
1761 stv0900_set_viterbi_acq(intp, demod);
1762 stv0900_set_viterbi_standard(intp,
1763 intp->srch_standard[demod],
1764 intp->fec[demod], demod);
1765
1766 break;
1767 case STV0900_SEARCH_DVBS2:
1768 stv0900_write_bits(intp, DVBS1_ENABLE, 0);
1769 stv0900_write_bits(intp, DVBS2_ENABLE, 1);
1770 stv0900_write_bits(intp, STOP_CLKVIT, 1);
1771 stv0900_write_reg(intp, ACLC, 0x1a);
1772 stv0900_write_reg(intp, BCLC, 0x09);
1773 if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
1774 stv0900_write_reg(intp, CAR2CFG, 0x26);
1775 else
1776 stv0900_write_reg(intp, CAR2CFG, 0x66);
1777
1778 if (intp->demod_mode != STV0900_SINGLE) {
1779 if (intp->chip_id <= 0x11)
1780 stv0900_stop_all_s2_modcod(intp, demod);
1781 else
1782 stv0900_activate_s2_modcod(intp, demod);
1783
1784 } else
1785 stv0900_activate_s2_modcod_single(intp, demod);
1786
1787 stv0900_set_viterbi_tracq(intp, demod);
1788
1789 break;
1790 case STV0900_AUTO_SEARCH:
1791 default:
1792 stv0900_write_bits(intp, DVBS1_ENABLE, 1);
1793 stv0900_write_bits(intp, DVBS2_ENABLE, 1);
1794 stv0900_write_bits(intp, STOP_CLKVIT, 0);
1795 stv0900_write_reg(intp, ACLC, 0x1a);
1796 stv0900_write_reg(intp, BCLC, 0x09);
1797 stv0900_set_dvbs1_track_car_loop(intp,
1798 demod,
1799 intp->symbol_rate[demod]);
1800 if (intp->chip_id <= 0x20) /*cut 1.x and 2.0*/
1801 stv0900_write_reg(intp, CAR2CFG, 0x26);
1802 else
1803 stv0900_write_reg(intp, CAR2CFG, 0x66);
1804
1805 if (intp->demod_mode != STV0900_SINGLE) {
1806 if (intp->chip_id <= 0x11)
1807 stv0900_stop_all_s2_modcod(intp, demod);
1808 else
1809 stv0900_activate_s2_modcod(intp, demod);
1810
1811 } else
1812 stv0900_activate_s2_modcod_single(intp, demod);
1813
1814 stv0900_set_viterbi_tracq(intp, demod);
1815 stv0900_set_viterbi_standard(intp,
1816 intp->srch_standard[demod],
1817 intp->fec[demod], demod);
1818
1819 break;
1820 }
1821}
1822
1823enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
1824{
1825 struct stv0900_state *state = fe->demodulator_priv;
1826 struct stv0900_internal *intp = state->internal;
1827 enum fe_stv0900_demod_num demod = state->demod;
1828
1829 s32 demod_timeout = 500, fec_timeout = 50;
1830 s32 aq_power, agc1_power, i;
1831
1832 int lock = FALSE, low_sr = FALSE;
1833
1834 enum fe_stv0900_signal_type signal_type = STV0900_NOCARRIER;
1835 enum fe_stv0900_search_algo algo;
1836 int no_signal = FALSE;
1837
1838 dprintk("%s\n", __func__);
1839
1840 algo = intp->srch_algo[demod];
1841 stv0900_write_bits(intp, RST_HWARE, 1);
1842 stv0900_write_reg(intp, DMDISTATE, 0x5c);
1843 if (intp->chip_id >= 0x20) {
1844 if (intp->symbol_rate[demod] > 5000000)
1845 stv0900_write_reg(intp, CORRELABS, 0x9e);
1846 else
1847 stv0900_write_reg(intp, CORRELABS, 0x82);
1848 } else
1849 stv0900_write_reg(intp, CORRELABS, 0x88);
1850
1851 stv0900_get_lock_timeout(&demod_timeout, &fec_timeout,
1852 intp->symbol_rate[demod],
1853 intp->srch_algo[demod]);
1854
1855 if (intp->srch_algo[demod] == STV0900_BLIND_SEARCH) {
1856 intp->bw[demod] = 2 * 36000000;
1857
1858 stv0900_write_reg(intp, TMGCFG2, 0xc0);
1859 stv0900_write_reg(intp, CORRELMANT, 0x70);
1860
1861 stv0900_set_symbol_rate(intp, intp->mclk, 1000000, demod);
1862 } else {
1863 stv0900_write_reg(intp, DMDT0M, 0x20);
1864 stv0900_write_reg(intp, TMGCFG, 0xd2);
1865
1866 if (intp->symbol_rate[demod] < 2000000)
1867 stv0900_write_reg(intp, CORRELMANT, 0x63);
1868 else
1869 stv0900_write_reg(intp, CORRELMANT, 0x70);
1870
1871 stv0900_write_reg(intp, AGC2REF, 0x38);
1872
1873 intp->bw[demod] =
1874 stv0900_carrier_width(intp->symbol_rate[demod],
1875 intp->rolloff);
1876 if (intp->chip_id >= 0x20) {
1877 stv0900_write_reg(intp, KREFTMG, 0x5a);
1878
1879 if (intp->srch_algo[demod] == STV0900_COLD_START) {
1880 intp->bw[demod] += 10000000;
1881 intp->bw[demod] *= 15;
1882 intp->bw[demod] /= 10;
1883 } else if (intp->srch_algo[demod] == STV0900_WARM_START)
1884 intp->bw[demod] += 10000000;
1885
1886 } else {
1887 stv0900_write_reg(intp, KREFTMG, 0xc1);
1888 intp->bw[demod] += 10000000;
1889 intp->bw[demod] *= 15;
1890 intp->bw[demod] /= 10;
1891 }
1892
1893 stv0900_write_reg(intp, TMGCFG2, 0xc1);
1894
1895 stv0900_set_symbol_rate(intp, intp->mclk,
1896 intp->symbol_rate[demod], demod);
1897 stv0900_set_max_symbol_rate(intp, intp->mclk,
1898 intp->symbol_rate[demod], demod);
1899 stv0900_set_min_symbol_rate(intp, intp->mclk,
1900 intp->symbol_rate[demod], demod);
1901 if (intp->symbol_rate[demod] >= 10000000)
1902 low_sr = FALSE;
1903 else
1904 low_sr = TRUE;
1905
1906 }
1907
1908 if (intp->tuner_type[demod] == 3)
1909 stv0900_set_tuner_auto(intp, intp->freq[demod],
1910 intp->bw[demod], demod);
1911 else
1912 stv0900_set_tuner(fe, intp->freq[demod], intp->bw[demod]);
1913
1914 agc1_power = MAKEWORD(stv0900_get_bits(intp, AGCIQ_VALUE1),
1915 stv0900_get_bits(intp, AGCIQ_VALUE0));
1916
1917 aq_power = 0;
1918
1919 if (agc1_power == 0) {
1920 for (i = 0; i < 5; i++)
1921 aq_power += (stv0900_get_bits(intp, POWER_I) +
1922 stv0900_get_bits(intp, POWER_Q)) / 2;
1923
1924 aq_power /= 5;
1925 }
1926
1927 if ((agc1_power == 0) && (aq_power < IQPOWER_THRESHOLD)) {
1928 intp->result[demod].locked = FALSE;
1929 signal_type = STV0900_NOAGC1;
1930 dprintk("%s: NO AGC1, POWERI, POWERQ\n", __func__);
1931 } else {
1932 stv0900_write_bits(intp, SPECINV_CONTROL,
1933 intp->srch_iq_inv[demod]);
1934 if (intp->chip_id <= 0x20) /*cut 2.0*/
1935 stv0900_write_bits(intp, MANUALSX_ROLLOFF, 1);
1936 else /*cut 3.0*/
1937 stv0900_write_bits(intp, MANUALS2_ROLLOFF, 1);
1938
1939 stv0900_set_search_standard(intp, demod);
1940
1941 if (intp->srch_algo[demod] != STV0900_BLIND_SEARCH)
1942 stv0900_start_search(intp, demod);
1943 }
1944
1945 if (signal_type == STV0900_NOAGC1)
1946 return signal_type;
1947
1948 if (intp->chip_id == 0x12) {
1949 stv0900_write_bits(intp, RST_HWARE, 0);
1950 msleep(3);
1951 stv0900_write_bits(intp, RST_HWARE, 1);
1952 stv0900_write_bits(intp, RST_HWARE, 0);
1953 }
1954
1955 if (algo == STV0900_BLIND_SEARCH)
1956 lock = stv0900_blind_search_algo(fe);
1957 else if (algo == STV0900_COLD_START)
1958 lock = stv0900_get_demod_cold_lock(fe, demod_timeout);
1959 else if (algo == STV0900_WARM_START)
1960 lock = stv0900_get_demod_lock(intp, demod, demod_timeout);
1961
1962 if ((lock == FALSE) && (algo == STV0900_COLD_START)) {
1963 if (low_sr == FALSE) {
1964 if (stv0900_check_timing_lock(intp, demod) == TRUE)
1965 lock = stv0900_sw_algo(intp, demod);
1966 }
1967 }
1968
1969 if (lock == TRUE)
1970 signal_type = stv0900_get_signal_params(fe);
1971
1972 if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) {
1973 stv0900_track_optimization(fe);
1974 if (intp->chip_id <= 0x11) {
1975 if ((stv0900_get_standard(fe, 0) ==
1976 STV0900_DVBS1_STANDARD) &&
1977 (stv0900_get_standard(fe, 1) ==
1978 STV0900_DVBS1_STANDARD)) {
1979 msleep(20);
1980 stv0900_write_bits(intp, RST_HWARE, 0);
1981 } else {
1982 stv0900_write_bits(intp, RST_HWARE, 0);
1983 msleep(3);
1984 stv0900_write_bits(intp, RST_HWARE, 1);
1985 stv0900_write_bits(intp, RST_HWARE, 0);
1986 }
1987
1988 } else if (intp->chip_id >= 0x20) {
1989 stv0900_write_bits(intp, RST_HWARE, 0);
1990 msleep(3);
1991 stv0900_write_bits(intp, RST_HWARE, 1);
1992 stv0900_write_bits(intp, RST_HWARE, 0);
1993 }
1994
1995 if (stv0900_wait_for_lock(intp, demod,
1996 fec_timeout, fec_timeout) == TRUE) {
1997 lock = TRUE;
1998 intp->result[demod].locked = TRUE;
1999 if (intp->result[demod].standard ==
2000 STV0900_DVBS2_STANDARD) {
2001 stv0900_set_dvbs2_rolloff(intp, demod);
2002 stv0900_write_bits(intp, RESET_UPKO_COUNT, 1);
2003 stv0900_write_bits(intp, RESET_UPKO_COUNT, 0);
2004 stv0900_write_reg(intp, ERRCTRL1, 0x67);
2005 } else {
2006 stv0900_write_reg(intp, ERRCTRL1, 0x75);
2007 }
2008
2009 stv0900_write_reg(intp, FBERCPT4, 0);
2010 stv0900_write_reg(intp, ERRCTRL2, 0xc1);
2011 } else {
2012 lock = FALSE;
2013 signal_type = STV0900_NODATA;
2014 no_signal = stv0900_check_signal_presence(intp, demod);
2015
2016 intp->result[demod].locked = FALSE;
2017 }
2018 }
2019
2020 if ((signal_type != STV0900_NODATA) || (no_signal != FALSE))
2021 return signal_type;
2022
2023 if (intp->chip_id > 0x11) {
2024 intp->result[demod].locked = FALSE;
2025 return signal_type;
2026 }
2027
2028 if ((stv0900_get_bits(intp, HEADER_MODE) == STV0900_DVBS_FOUND) &&
2029 (intp->srch_iq_inv[demod] <= STV0900_IQ_AUTO_NORMAL_FIRST))
2030 signal_type = stv0900_dvbs1_acq_workaround(fe);
2031
2032 return signal_type;
2033}
2034
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
new file mode 100644
index 00000000000..52d8712411e
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -0,0 +1,4831 @@
1/*
2 STV0900/0903 Multistandard Broadcast Frontend driver
3 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
4
5 Copyright (C) ST Microelectronics
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#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/slab.h>
27#include <linux/mutex.h>
28
29#include <linux/dvb/frontend.h>
30#include "dvb_frontend.h"
31
32#include "stv6110x.h" /* for demodulator internal modes */
33
34#include "stv090x_reg.h"
35#include "stv090x.h"
36#include "stv090x_priv.h"
37
38static unsigned int verbose;
39module_param(verbose, int, 0644);
40
41/* internal params node */
42struct stv090x_dev {
43 /* pointer for internal params, one for each pair of demods */
44 struct stv090x_internal *internal;
45 struct stv090x_dev *next_dev;
46};
47
48/* first internal params */
49static struct stv090x_dev *stv090x_first_dev;
50
51/* find chip by i2c adapter and i2c address */
52static struct stv090x_dev *find_dev(struct i2c_adapter *i2c_adap,
53 u8 i2c_addr)
54{
55 struct stv090x_dev *temp_dev = stv090x_first_dev;
56
57 /*
58 Search of the last stv0900 chip or
59 find it by i2c adapter and i2c address */
60 while ((temp_dev != NULL) &&
61 ((temp_dev->internal->i2c_adap != i2c_adap) ||
62 (temp_dev->internal->i2c_addr != i2c_addr))) {
63
64 temp_dev = temp_dev->next_dev;
65 }
66
67 return temp_dev;
68}
69
70/* deallocating chip */
71static void remove_dev(struct stv090x_internal *internal)
72{
73 struct stv090x_dev *prev_dev = stv090x_first_dev;
74 struct stv090x_dev *del_dev = find_dev(internal->i2c_adap,
75 internal->i2c_addr);
76
77 if (del_dev != NULL) {
78 if (del_dev == stv090x_first_dev) {
79 stv090x_first_dev = del_dev->next_dev;
80 } else {
81 while (prev_dev->next_dev != del_dev)
82 prev_dev = prev_dev->next_dev;
83
84 prev_dev->next_dev = del_dev->next_dev;
85 }
86
87 kfree(del_dev);
88 }
89}
90
91/* allocating new chip */
92static struct stv090x_dev *append_internal(struct stv090x_internal *internal)
93{
94 struct stv090x_dev *new_dev;
95 struct stv090x_dev *temp_dev;
96
97 new_dev = kmalloc(sizeof(struct stv090x_dev), GFP_KERNEL);
98 if (new_dev != NULL) {
99 new_dev->internal = internal;
100 new_dev->next_dev = NULL;
101
102 /* append to list */
103 if (stv090x_first_dev == NULL) {
104 stv090x_first_dev = new_dev;
105 } else {
106 temp_dev = stv090x_first_dev;
107 while (temp_dev->next_dev != NULL)
108 temp_dev = temp_dev->next_dev;
109
110 temp_dev->next_dev = new_dev;
111 }
112 }
113
114 return new_dev;
115}
116
117
118/* DVBS1 and DSS C/N Lookup table */
119static const struct stv090x_tab stv090x_s1cn_tab[] = {
120 { 0, 8917 }, /* 0.0dB */
121 { 5, 8801 }, /* 0.5dB */
122 { 10, 8667 }, /* 1.0dB */
123 { 15, 8522 }, /* 1.5dB */
124 { 20, 8355 }, /* 2.0dB */
125 { 25, 8175 }, /* 2.5dB */
126 { 30, 7979 }, /* 3.0dB */
127 { 35, 7763 }, /* 3.5dB */
128 { 40, 7530 }, /* 4.0dB */
129 { 45, 7282 }, /* 4.5dB */
130 { 50, 7026 }, /* 5.0dB */
131 { 55, 6781 }, /* 5.5dB */
132 { 60, 6514 }, /* 6.0dB */
133 { 65, 6241 }, /* 6.5dB */
134 { 70, 5965 }, /* 7.0dB */
135 { 75, 5690 }, /* 7.5dB */
136 { 80, 5424 }, /* 8.0dB */
137 { 85, 5161 }, /* 8.5dB */
138 { 90, 4902 }, /* 9.0dB */
139 { 95, 4654 }, /* 9.5dB */
140 { 100, 4417 }, /* 10.0dB */
141 { 105, 4186 }, /* 10.5dB */
142 { 110, 3968 }, /* 11.0dB */
143 { 115, 3757 }, /* 11.5dB */
144 { 120, 3558 }, /* 12.0dB */
145 { 125, 3366 }, /* 12.5dB */
146 { 130, 3185 }, /* 13.0dB */
147 { 135, 3012 }, /* 13.5dB */
148 { 140, 2850 }, /* 14.0dB */
149 { 145, 2698 }, /* 14.5dB */
150 { 150, 2550 }, /* 15.0dB */
151 { 160, 2283 }, /* 16.0dB */
152 { 170, 2042 }, /* 17.0dB */
153 { 180, 1827 }, /* 18.0dB */
154 { 190, 1636 }, /* 19.0dB */
155 { 200, 1466 }, /* 20.0dB */
156 { 210, 1315 }, /* 21.0dB */
157 { 220, 1181 }, /* 22.0dB */
158 { 230, 1064 }, /* 23.0dB */
159 { 240, 960 }, /* 24.0dB */
160 { 250, 869 }, /* 25.0dB */
161 { 260, 792 }, /* 26.0dB */
162 { 270, 724 }, /* 27.0dB */
163 { 280, 665 }, /* 28.0dB */
164 { 290, 616 }, /* 29.0dB */
165 { 300, 573 }, /* 30.0dB */
166 { 310, 537 }, /* 31.0dB */
167 { 320, 507 }, /* 32.0dB */
168 { 330, 483 }, /* 33.0dB */
169 { 400, 398 }, /* 40.0dB */
170 { 450, 381 }, /* 45.0dB */
171 { 500, 377 } /* 50.0dB */
172};
173
174/* DVBS2 C/N Lookup table */
175static const struct stv090x_tab stv090x_s2cn_tab[] = {
176 { -30, 13348 }, /* -3.0dB */
177 { -20, 12640 }, /* -2d.0B */
178 { -10, 11883 }, /* -1.0dB */
179 { 0, 11101 }, /* -0.0dB */
180 { 5, 10718 }, /* 0.5dB */
181 { 10, 10339 }, /* 1.0dB */
182 { 15, 9947 }, /* 1.5dB */
183 { 20, 9552 }, /* 2.0dB */
184 { 25, 9183 }, /* 2.5dB */
185 { 30, 8799 }, /* 3.0dB */
186 { 35, 8422 }, /* 3.5dB */
187 { 40, 8062 }, /* 4.0dB */
188 { 45, 7707 }, /* 4.5dB */
189 { 50, 7353 }, /* 5.0dB */
190 { 55, 7025 }, /* 5.5dB */
191 { 60, 6684 }, /* 6.0dB */
192 { 65, 6331 }, /* 6.5dB */
193 { 70, 6036 }, /* 7.0dB */
194 { 75, 5727 }, /* 7.5dB */
195 { 80, 5437 }, /* 8.0dB */
196 { 85, 5164 }, /* 8.5dB */
197 { 90, 4902 }, /* 9.0dB */
198 { 95, 4653 }, /* 9.5dB */
199 { 100, 4408 }, /* 10.0dB */
200 { 105, 4187 }, /* 10.5dB */
201 { 110, 3961 }, /* 11.0dB */
202 { 115, 3751 }, /* 11.5dB */
203 { 120, 3558 }, /* 12.0dB */
204 { 125, 3368 }, /* 12.5dB */
205 { 130, 3191 }, /* 13.0dB */
206 { 135, 3017 }, /* 13.5dB */
207 { 140, 2862 }, /* 14.0dB */
208 { 145, 2710 }, /* 14.5dB */
209 { 150, 2565 }, /* 15.0dB */
210 { 160, 2300 }, /* 16.0dB */
211 { 170, 2058 }, /* 17.0dB */
212 { 180, 1849 }, /* 18.0dB */
213 { 190, 1663 }, /* 19.0dB */
214 { 200, 1495 }, /* 20.0dB */
215 { 210, 1349 }, /* 21.0dB */
216 { 220, 1222 }, /* 22.0dB */
217 { 230, 1110 }, /* 23.0dB */
218 { 240, 1011 }, /* 24.0dB */
219 { 250, 925 }, /* 25.0dB */
220 { 260, 853 }, /* 26.0dB */
221 { 270, 789 }, /* 27.0dB */
222 { 280, 734 }, /* 28.0dB */
223 { 290, 690 }, /* 29.0dB */
224 { 300, 650 }, /* 30.0dB */
225 { 310, 619 }, /* 31.0dB */
226 { 320, 593 }, /* 32.0dB */
227 { 330, 571 }, /* 33.0dB */
228 { 400, 498 }, /* 40.0dB */
229 { 450, 484 }, /* 45.0dB */
230 { 500, 481 } /* 50.0dB */
231};
232
233/* RF level C/N lookup table */
234static const struct stv090x_tab stv090x_rf_tab[] = {
235 { -5, 0xcaa1 }, /* -5dBm */
236 { -10, 0xc229 }, /* -10dBm */
237 { -15, 0xbb08 }, /* -15dBm */
238 { -20, 0xb4bc }, /* -20dBm */
239 { -25, 0xad5a }, /* -25dBm */
240 { -30, 0xa298 }, /* -30dBm */
241 { -35, 0x98a8 }, /* -35dBm */
242 { -40, 0x8389 }, /* -40dBm */
243 { -45, 0x59be }, /* -45dBm */
244 { -50, 0x3a14 }, /* -50dBm */
245 { -55, 0x2d11 }, /* -55dBm */
246 { -60, 0x210d }, /* -60dBm */
247 { -65, 0xa14f }, /* -65dBm */
248 { -70, 0x07aa } /* -70dBm */
249};
250
251
252static struct stv090x_reg stv0900_initval[] = {
253
254 { STV090x_OUTCFG, 0x00 },
255 { STV090x_MODECFG, 0xff },
256 { STV090x_AGCRF1CFG, 0x11 },
257 { STV090x_AGCRF2CFG, 0x13 },
258 { STV090x_TSGENERAL1X, 0x14 },
259 { STV090x_TSTTNR2, 0x21 },
260 { STV090x_TSTTNR4, 0x21 },
261 { STV090x_P2_DISTXCTL, 0x22 },
262 { STV090x_P2_F22TX, 0xc0 },
263 { STV090x_P2_F22RX, 0xc0 },
264 { STV090x_P2_DISRXCTL, 0x00 },
265 { STV090x_P2_DMDCFGMD, 0xF9 },
266 { STV090x_P2_DEMOD, 0x08 },
267 { STV090x_P2_DMDCFG3, 0xc4 },
268 { STV090x_P2_CARFREQ, 0xed },
269 { STV090x_P2_LDT, 0xd0 },
270 { STV090x_P2_LDT2, 0xb8 },
271 { STV090x_P2_TMGCFG, 0xd2 },
272 { STV090x_P2_TMGTHRISE, 0x20 },
273 { STV090x_P1_TMGCFG, 0xd2 },
274
275 { STV090x_P2_TMGTHFALL, 0x00 },
276 { STV090x_P2_FECSPY, 0x88 },
277 { STV090x_P2_FSPYDATA, 0x3a },
278 { STV090x_P2_FBERCPT4, 0x00 },
279 { STV090x_P2_FSPYBER, 0x10 },
280 { STV090x_P2_ERRCTRL1, 0x35 },
281 { STV090x_P2_ERRCTRL2, 0xc1 },
282 { STV090x_P2_CFRICFG, 0xf8 },
283 { STV090x_P2_NOSCFG, 0x1c },
284 { STV090x_P2_DMDTOM, 0x20 },
285 { STV090x_P2_CORRELMANT, 0x70 },
286 { STV090x_P2_CORRELABS, 0x88 },
287 { STV090x_P2_AGC2O, 0x5b },
288 { STV090x_P2_AGC2REF, 0x38 },
289 { STV090x_P2_CARCFG, 0xe4 },
290 { STV090x_P2_ACLC, 0x1A },
291 { STV090x_P2_BCLC, 0x09 },
292 { STV090x_P2_CARHDR, 0x08 },
293 { STV090x_P2_KREFTMG, 0xc1 },
294 { STV090x_P2_SFRUPRATIO, 0xf0 },
295 { STV090x_P2_SFRLOWRATIO, 0x70 },
296 { STV090x_P2_SFRSTEP, 0x58 },
297 { STV090x_P2_TMGCFG2, 0x01 },
298 { STV090x_P2_CAR2CFG, 0x26 },
299 { STV090x_P2_BCLC2S2Q, 0x86 },
300 { STV090x_P2_BCLC2S28, 0x86 },
301 { STV090x_P2_SMAPCOEF7, 0x77 },
302 { STV090x_P2_SMAPCOEF6, 0x85 },
303 { STV090x_P2_SMAPCOEF5, 0x77 },
304 { STV090x_P2_TSCFGL, 0x20 },
305 { STV090x_P2_DMDCFG2, 0x3b },
306 { STV090x_P2_MODCODLST0, 0xff },
307 { STV090x_P2_MODCODLST1, 0xff },
308 { STV090x_P2_MODCODLST2, 0xff },
309 { STV090x_P2_MODCODLST3, 0xff },
310 { STV090x_P2_MODCODLST4, 0xff },
311 { STV090x_P2_MODCODLST5, 0xff },
312 { STV090x_P2_MODCODLST6, 0xff },
313 { STV090x_P2_MODCODLST7, 0xcc },
314 { STV090x_P2_MODCODLST8, 0xcc },
315 { STV090x_P2_MODCODLST9, 0xcc },
316 { STV090x_P2_MODCODLSTA, 0xcc },
317 { STV090x_P2_MODCODLSTB, 0xcc },
318 { STV090x_P2_MODCODLSTC, 0xcc },
319 { STV090x_P2_MODCODLSTD, 0xcc },
320 { STV090x_P2_MODCODLSTE, 0xcc },
321 { STV090x_P2_MODCODLSTF, 0xcf },
322 { STV090x_P1_DISTXCTL, 0x22 },
323 { STV090x_P1_F22TX, 0xc0 },
324 { STV090x_P1_F22RX, 0xc0 },
325 { STV090x_P1_DISRXCTL, 0x00 },
326 { STV090x_P1_DMDCFGMD, 0xf9 },
327 { STV090x_P1_DEMOD, 0x08 },
328 { STV090x_P1_DMDCFG3, 0xc4 },
329 { STV090x_P1_DMDTOM, 0x20 },
330 { STV090x_P1_CARFREQ, 0xed },
331 { STV090x_P1_LDT, 0xd0 },
332 { STV090x_P1_LDT2, 0xb8 },
333 { STV090x_P1_TMGCFG, 0xd2 },
334 { STV090x_P1_TMGTHRISE, 0x20 },
335 { STV090x_P1_TMGTHFALL, 0x00 },
336 { STV090x_P1_SFRUPRATIO, 0xf0 },
337 { STV090x_P1_SFRLOWRATIO, 0x70 },
338 { STV090x_P1_TSCFGL, 0x20 },
339 { STV090x_P1_FECSPY, 0x88 },
340 { STV090x_P1_FSPYDATA, 0x3a },
341 { STV090x_P1_FBERCPT4, 0x00 },
342 { STV090x_P1_FSPYBER, 0x10 },
343 { STV090x_P1_ERRCTRL1, 0x35 },
344 { STV090x_P1_ERRCTRL2, 0xc1 },
345 { STV090x_P1_CFRICFG, 0xf8 },
346 { STV090x_P1_NOSCFG, 0x1c },
347 { STV090x_P1_CORRELMANT, 0x70 },
348 { STV090x_P1_CORRELABS, 0x88 },
349 { STV090x_P1_AGC2O, 0x5b },
350 { STV090x_P1_AGC2REF, 0x38 },
351 { STV090x_P1_CARCFG, 0xe4 },
352 { STV090x_P1_ACLC, 0x1A },
353 { STV090x_P1_BCLC, 0x09 },
354 { STV090x_P1_CARHDR, 0x08 },
355 { STV090x_P1_KREFTMG, 0xc1 },
356 { STV090x_P1_SFRSTEP, 0x58 },
357 { STV090x_P1_TMGCFG2, 0x01 },
358 { STV090x_P1_CAR2CFG, 0x26 },
359 { STV090x_P1_BCLC2S2Q, 0x86 },
360 { STV090x_P1_BCLC2S28, 0x86 },
361 { STV090x_P1_SMAPCOEF7, 0x77 },
362 { STV090x_P1_SMAPCOEF6, 0x85 },
363 { STV090x_P1_SMAPCOEF5, 0x77 },
364 { STV090x_P1_DMDCFG2, 0x3b },
365 { STV090x_P1_MODCODLST0, 0xff },
366 { STV090x_P1_MODCODLST1, 0xff },
367 { STV090x_P1_MODCODLST2, 0xff },
368 { STV090x_P1_MODCODLST3, 0xff },
369 { STV090x_P1_MODCODLST4, 0xff },
370 { STV090x_P1_MODCODLST5, 0xff },
371 { STV090x_P1_MODCODLST6, 0xff },
372 { STV090x_P1_MODCODLST7, 0xcc },
373 { STV090x_P1_MODCODLST8, 0xcc },
374 { STV090x_P1_MODCODLST9, 0xcc },
375 { STV090x_P1_MODCODLSTA, 0xcc },
376 { STV090x_P1_MODCODLSTB, 0xcc },
377 { STV090x_P1_MODCODLSTC, 0xcc },
378 { STV090x_P1_MODCODLSTD, 0xcc },
379 { STV090x_P1_MODCODLSTE, 0xcc },
380 { STV090x_P1_MODCODLSTF, 0xcf },
381 { STV090x_GENCFG, 0x1d },
382 { STV090x_NBITER_NF4, 0x37 },
383 { STV090x_NBITER_NF5, 0x29 },
384 { STV090x_NBITER_NF6, 0x37 },
385 { STV090x_NBITER_NF7, 0x33 },
386 { STV090x_NBITER_NF8, 0x31 },
387 { STV090x_NBITER_NF9, 0x2f },
388 { STV090x_NBITER_NF10, 0x39 },
389 { STV090x_NBITER_NF11, 0x3a },
390 { STV090x_NBITER_NF12, 0x29 },
391 { STV090x_NBITER_NF13, 0x37 },
392 { STV090x_NBITER_NF14, 0x33 },
393 { STV090x_NBITER_NF15, 0x2f },
394 { STV090x_NBITER_NF16, 0x39 },
395 { STV090x_NBITER_NF17, 0x3a },
396 { STV090x_NBITERNOERR, 0x04 },
397 { STV090x_GAINLLR_NF4, 0x0C },
398 { STV090x_GAINLLR_NF5, 0x0F },
399 { STV090x_GAINLLR_NF6, 0x11 },
400 { STV090x_GAINLLR_NF7, 0x14 },
401 { STV090x_GAINLLR_NF8, 0x17 },
402 { STV090x_GAINLLR_NF9, 0x19 },
403 { STV090x_GAINLLR_NF10, 0x20 },
404 { STV090x_GAINLLR_NF11, 0x21 },
405 { STV090x_GAINLLR_NF12, 0x0D },
406 { STV090x_GAINLLR_NF13, 0x0F },
407 { STV090x_GAINLLR_NF14, 0x13 },
408 { STV090x_GAINLLR_NF15, 0x1A },
409 { STV090x_GAINLLR_NF16, 0x1F },
410 { STV090x_GAINLLR_NF17, 0x21 },
411 { STV090x_RCCFGH, 0x20 },
412 { STV090x_P1_FECM, 0x01 }, /* disable DSS modes */
413 { STV090x_P2_FECM, 0x01 }, /* disable DSS modes */
414 { STV090x_P1_PRVIT, 0x2F }, /* disable PR 6/7 */
415 { STV090x_P2_PRVIT, 0x2F }, /* disable PR 6/7 */
416};
417
418static struct stv090x_reg stv0903_initval[] = {
419 { STV090x_OUTCFG, 0x00 },
420 { STV090x_AGCRF1CFG, 0x11 },
421 { STV090x_STOPCLK1, 0x48 },
422 { STV090x_STOPCLK2, 0x14 },
423 { STV090x_TSTTNR1, 0x27 },
424 { STV090x_TSTTNR2, 0x21 },
425 { STV090x_P1_DISTXCTL, 0x22 },
426 { STV090x_P1_F22TX, 0xc0 },
427 { STV090x_P1_F22RX, 0xc0 },
428 { STV090x_P1_DISRXCTL, 0x00 },
429 { STV090x_P1_DMDCFGMD, 0xF9 },
430 { STV090x_P1_DEMOD, 0x08 },
431 { STV090x_P1_DMDCFG3, 0xc4 },
432 { STV090x_P1_CARFREQ, 0xed },
433 { STV090x_P1_TNRCFG2, 0x82 },
434 { STV090x_P1_LDT, 0xd0 },
435 { STV090x_P1_LDT2, 0xb8 },
436 { STV090x_P1_TMGCFG, 0xd2 },
437 { STV090x_P1_TMGTHRISE, 0x20 },
438 { STV090x_P1_TMGTHFALL, 0x00 },
439 { STV090x_P1_SFRUPRATIO, 0xf0 },
440 { STV090x_P1_SFRLOWRATIO, 0x70 },
441 { STV090x_P1_TSCFGL, 0x20 },
442 { STV090x_P1_FECSPY, 0x88 },
443 { STV090x_P1_FSPYDATA, 0x3a },
444 { STV090x_P1_FBERCPT4, 0x00 },
445 { STV090x_P1_FSPYBER, 0x10 },
446 { STV090x_P1_ERRCTRL1, 0x35 },
447 { STV090x_P1_ERRCTRL2, 0xc1 },
448 { STV090x_P1_CFRICFG, 0xf8 },
449 { STV090x_P1_NOSCFG, 0x1c },
450 { STV090x_P1_DMDTOM, 0x20 },
451 { STV090x_P1_CORRELMANT, 0x70 },
452 { STV090x_P1_CORRELABS, 0x88 },
453 { STV090x_P1_AGC2O, 0x5b },
454 { STV090x_P1_AGC2REF, 0x38 },
455 { STV090x_P1_CARCFG, 0xe4 },
456 { STV090x_P1_ACLC, 0x1A },
457 { STV090x_P1_BCLC, 0x09 },
458 { STV090x_P1_CARHDR, 0x08 },
459 { STV090x_P1_KREFTMG, 0xc1 },
460 { STV090x_P1_SFRSTEP, 0x58 },
461 { STV090x_P1_TMGCFG2, 0x01 },
462 { STV090x_P1_CAR2CFG, 0x26 },
463 { STV090x_P1_BCLC2S2Q, 0x86 },
464 { STV090x_P1_BCLC2S28, 0x86 },
465 { STV090x_P1_SMAPCOEF7, 0x77 },
466 { STV090x_P1_SMAPCOEF6, 0x85 },
467 { STV090x_P1_SMAPCOEF5, 0x77 },
468 { STV090x_P1_DMDCFG2, 0x3b },
469 { STV090x_P1_MODCODLST0, 0xff },
470 { STV090x_P1_MODCODLST1, 0xff },
471 { STV090x_P1_MODCODLST2, 0xff },
472 { STV090x_P1_MODCODLST3, 0xff },
473 { STV090x_P1_MODCODLST4, 0xff },
474 { STV090x_P1_MODCODLST5, 0xff },
475 { STV090x_P1_MODCODLST6, 0xff },
476 { STV090x_P1_MODCODLST7, 0xcc },
477 { STV090x_P1_MODCODLST8, 0xcc },
478 { STV090x_P1_MODCODLST9, 0xcc },
479 { STV090x_P1_MODCODLSTA, 0xcc },
480 { STV090x_P1_MODCODLSTB, 0xcc },
481 { STV090x_P1_MODCODLSTC, 0xcc },
482 { STV090x_P1_MODCODLSTD, 0xcc },
483 { STV090x_P1_MODCODLSTE, 0xcc },
484 { STV090x_P1_MODCODLSTF, 0xcf },
485 { STV090x_GENCFG, 0x1c },
486 { STV090x_NBITER_NF4, 0x37 },
487 { STV090x_NBITER_NF5, 0x29 },
488 { STV090x_NBITER_NF6, 0x37 },
489 { STV090x_NBITER_NF7, 0x33 },
490 { STV090x_NBITER_NF8, 0x31 },
491 { STV090x_NBITER_NF9, 0x2f },
492 { STV090x_NBITER_NF10, 0x39 },
493 { STV090x_NBITER_NF11, 0x3a },
494 { STV090x_NBITER_NF12, 0x29 },
495 { STV090x_NBITER_NF13, 0x37 },
496 { STV090x_NBITER_NF14, 0x33 },
497 { STV090x_NBITER_NF15, 0x2f },
498 { STV090x_NBITER_NF16, 0x39 },
499 { STV090x_NBITER_NF17, 0x3a },
500 { STV090x_NBITERNOERR, 0x04 },
501 { STV090x_GAINLLR_NF4, 0x0C },
502 { STV090x_GAINLLR_NF5, 0x0F },
503 { STV090x_GAINLLR_NF6, 0x11 },
504 { STV090x_GAINLLR_NF7, 0x14 },
505 { STV090x_GAINLLR_NF8, 0x17 },
506 { STV090x_GAINLLR_NF9, 0x19 },
507 { STV090x_GAINLLR_NF10, 0x20 },
508 { STV090x_GAINLLR_NF11, 0x21 },
509 { STV090x_GAINLLR_NF12, 0x0D },
510 { STV090x_GAINLLR_NF13, 0x0F },
511 { STV090x_GAINLLR_NF14, 0x13 },
512 { STV090x_GAINLLR_NF15, 0x1A },
513 { STV090x_GAINLLR_NF16, 0x1F },
514 { STV090x_GAINLLR_NF17, 0x21 },
515 { STV090x_RCCFGH, 0x20 },
516 { STV090x_P1_FECM, 0x01 }, /*disable the DSS mode */
517 { STV090x_P1_PRVIT, 0x2f } /*disable puncture rate 6/7*/
518};
519
520static struct stv090x_reg stv0900_cut20_val[] = {
521
522 { STV090x_P2_DMDCFG3, 0xe8 },
523 { STV090x_P2_DMDCFG4, 0x10 },
524 { STV090x_P2_CARFREQ, 0x38 },
525 { STV090x_P2_CARHDR, 0x20 },
526 { STV090x_P2_KREFTMG, 0x5a },
527 { STV090x_P2_SMAPCOEF7, 0x06 },
528 { STV090x_P2_SMAPCOEF6, 0x00 },
529 { STV090x_P2_SMAPCOEF5, 0x04 },
530 { STV090x_P2_NOSCFG, 0x0c },
531 { STV090x_P1_DMDCFG3, 0xe8 },
532 { STV090x_P1_DMDCFG4, 0x10 },
533 { STV090x_P1_CARFREQ, 0x38 },
534 { STV090x_P1_CARHDR, 0x20 },
535 { STV090x_P1_KREFTMG, 0x5a },
536 { STV090x_P1_SMAPCOEF7, 0x06 },
537 { STV090x_P1_SMAPCOEF6, 0x00 },
538 { STV090x_P1_SMAPCOEF5, 0x04 },
539 { STV090x_P1_NOSCFG, 0x0c },
540 { STV090x_GAINLLR_NF4, 0x21 },
541 { STV090x_GAINLLR_NF5, 0x21 },
542 { STV090x_GAINLLR_NF6, 0x20 },
543 { STV090x_GAINLLR_NF7, 0x1F },
544 { STV090x_GAINLLR_NF8, 0x1E },
545 { STV090x_GAINLLR_NF9, 0x1E },
546 { STV090x_GAINLLR_NF10, 0x1D },
547 { STV090x_GAINLLR_NF11, 0x1B },
548 { STV090x_GAINLLR_NF12, 0x20 },
549 { STV090x_GAINLLR_NF13, 0x20 },
550 { STV090x_GAINLLR_NF14, 0x20 },
551 { STV090x_GAINLLR_NF15, 0x20 },
552 { STV090x_GAINLLR_NF16, 0x20 },
553 { STV090x_GAINLLR_NF17, 0x21 },
554};
555
556static struct stv090x_reg stv0903_cut20_val[] = {
557 { STV090x_P1_DMDCFG3, 0xe8 },
558 { STV090x_P1_DMDCFG4, 0x10 },
559 { STV090x_P1_CARFREQ, 0x38 },
560 { STV090x_P1_CARHDR, 0x20 },
561 { STV090x_P1_KREFTMG, 0x5a },
562 { STV090x_P1_SMAPCOEF7, 0x06 },
563 { STV090x_P1_SMAPCOEF6, 0x00 },
564 { STV090x_P1_SMAPCOEF5, 0x04 },
565 { STV090x_P1_NOSCFG, 0x0c },
566 { STV090x_GAINLLR_NF4, 0x21 },
567 { STV090x_GAINLLR_NF5, 0x21 },
568 { STV090x_GAINLLR_NF6, 0x20 },
569 { STV090x_GAINLLR_NF7, 0x1F },
570 { STV090x_GAINLLR_NF8, 0x1E },
571 { STV090x_GAINLLR_NF9, 0x1E },
572 { STV090x_GAINLLR_NF10, 0x1D },
573 { STV090x_GAINLLR_NF11, 0x1B },
574 { STV090x_GAINLLR_NF12, 0x20 },
575 { STV090x_GAINLLR_NF13, 0x20 },
576 { STV090x_GAINLLR_NF14, 0x20 },
577 { STV090x_GAINLLR_NF15, 0x20 },
578 { STV090x_GAINLLR_NF16, 0x20 },
579 { STV090x_GAINLLR_NF17, 0x21 }
580};
581
582/* Cut 2.0 Long Frame Tracking CR loop */
583static struct stv090x_long_frame_crloop stv090x_s2_crl_cut20[] = {
584 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
585 { STV090x_QPSK_12, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x1e },
586 { STV090x_QPSK_35, 0x2f, 0x3f, 0x2e, 0x2f, 0x3d, 0x0f, 0x0e, 0x2e, 0x3d, 0x0e },
587 { STV090x_QPSK_23, 0x2f, 0x3f, 0x2e, 0x2f, 0x0e, 0x0f, 0x0e, 0x1e, 0x3d, 0x3d },
588 { STV090x_QPSK_34, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
589 { STV090x_QPSK_45, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
590 { STV090x_QPSK_56, 0x3f, 0x3f, 0x3e, 0x1f, 0x0e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
591 { STV090x_QPSK_89, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
592 { STV090x_QPSK_910, 0x3f, 0x3f, 0x3e, 0x1f, 0x1e, 0x3e, 0x0e, 0x1e, 0x3d, 0x3d },
593 { STV090x_8PSK_35, 0x3c, 0x3e, 0x1c, 0x2e, 0x0c, 0x1e, 0x2b, 0x2d, 0x1b, 0x1d },
594 { STV090x_8PSK_23, 0x1d, 0x3e, 0x3c, 0x2e, 0x2c, 0x1e, 0x0c, 0x2d, 0x2b, 0x1d },
595 { STV090x_8PSK_34, 0x0e, 0x3e, 0x3d, 0x2e, 0x0d, 0x1e, 0x2c, 0x2d, 0x0c, 0x1d },
596 { STV090x_8PSK_56, 0x2e, 0x3e, 0x1e, 0x2e, 0x2d, 0x1e, 0x3c, 0x2d, 0x2c, 0x1d },
597 { STV090x_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d },
598 { STV090x_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d }
599};
600
601/* Cut 3.0 Long Frame Tracking CR loop */
602static struct stv090x_long_frame_crloop stv090x_s2_crl_cut30[] = {
603 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
604 { STV090x_QPSK_12, 0x3c, 0x2c, 0x0c, 0x2c, 0x1b, 0x2c, 0x1b, 0x1c, 0x0b, 0x3b },
605 { STV090x_QPSK_35, 0x0d, 0x0d, 0x0c, 0x0d, 0x1b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
606 { STV090x_QPSK_23, 0x1d, 0x0d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
607 { STV090x_QPSK_34, 0x1d, 0x1d, 0x0c, 0x1d, 0x2b, 0x3c, 0x1b, 0x1c, 0x0b, 0x3b },
608 { STV090x_QPSK_45, 0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
609 { STV090x_QPSK_56, 0x2d, 0x1d, 0x1c, 0x1d, 0x2b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
610 { STV090x_QPSK_89, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
611 { STV090x_QPSK_910, 0x3d, 0x2d, 0x1c, 0x1d, 0x3b, 0x3c, 0x2b, 0x0c, 0x1b, 0x3b },
612 { STV090x_8PSK_35, 0x39, 0x29, 0x39, 0x19, 0x19, 0x19, 0x19, 0x19, 0x09, 0x19 },
613 { STV090x_8PSK_23, 0x2a, 0x39, 0x1a, 0x0a, 0x39, 0x0a, 0x29, 0x39, 0x29, 0x0a },
614 { STV090x_8PSK_34, 0x2b, 0x3a, 0x1b, 0x1b, 0x3a, 0x1b, 0x1a, 0x0b, 0x1a, 0x3a },
615 { STV090x_8PSK_56, 0x0c, 0x1b, 0x3b, 0x3b, 0x1b, 0x3b, 0x3a, 0x3b, 0x3a, 0x1b },
616 { STV090x_8PSK_89, 0x0d, 0x3c, 0x2c, 0x2c, 0x2b, 0x0c, 0x0b, 0x3b, 0x0b, 0x1b },
617 { STV090x_8PSK_910, 0x0d, 0x0d, 0x2c, 0x3c, 0x3b, 0x1c, 0x0b, 0x3b, 0x0b, 0x1b }
618};
619
620/* Cut 2.0 Long Frame Tracking CR Loop */
621static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut20[] = {
622 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
623 { STV090x_16APSK_23, 0x0c, 0x0c, 0x0c, 0x0c, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c, 0x0c },
624 { STV090x_16APSK_34, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x0c, 0x2d, 0x0c, 0x1d, 0x0c },
625 { STV090x_16APSK_45, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c },
626 { STV090x_16APSK_56, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x0c, 0x3d, 0x0c, 0x2d, 0x0c },
627 { STV090x_16APSK_89, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c },
628 { STV090x_16APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x2e, 0x0c, 0x0e, 0x0c, 0x3d, 0x0c },
629 { STV090x_32APSK_34, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
630 { STV090x_32APSK_45, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
631 { STV090x_32APSK_56, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
632 { STV090x_32APSK_89, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c },
633 { STV090x_32APSK_910, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }
634};
635
636/* Cut 3.0 Long Frame Tracking CR Loop */
637static struct stv090x_long_frame_crloop stv090x_s2_apsk_crl_cut30[] = {
638 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
639 { STV090x_16APSK_23, 0x0a, 0x0a, 0x0a, 0x0a, 0x1a, 0x0a, 0x3a, 0x0a, 0x2a, 0x0a },
640 { STV090x_16APSK_34, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0a, 0x3b, 0x0a, 0x1b, 0x0a },
641 { STV090x_16APSK_45, 0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a },
642 { STV090x_16APSK_56, 0x0a, 0x0a, 0x0a, 0x0a, 0x1b, 0x0a, 0x3b, 0x0a, 0x2b, 0x0a },
643 { STV090x_16APSK_89, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a },
644 { STV090x_16APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x2b, 0x0a, 0x0c, 0x0a, 0x3b, 0x0a },
645 { STV090x_32APSK_34, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
646 { STV090x_32APSK_45, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
647 { STV090x_32APSK_56, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
648 { STV090x_32APSK_89, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a },
649 { STV090x_32APSK_910, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a }
650};
651
652static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut20[] = {
653 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
654 { STV090x_QPSK_14, 0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x2d, 0x1f, 0x3d, 0x3e },
655 { STV090x_QPSK_13, 0x0f, 0x3f, 0x0e, 0x3f, 0x2d, 0x2f, 0x3d, 0x0f, 0x3d, 0x2e },
656 { STV090x_QPSK_25, 0x1f, 0x3f, 0x1e, 0x3f, 0x3d, 0x1f, 0x3d, 0x3e, 0x3d, 0x2e }
657};
658
659static struct stv090x_long_frame_crloop stv090x_s2_lowqpsk_crl_cut30[] = {
660 /* MODCOD 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
661 { STV090x_QPSK_14, 0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x2a, 0x1c, 0x3a, 0x3b },
662 { STV090x_QPSK_13, 0x0c, 0x3c, 0x0b, 0x3c, 0x2a, 0x2c, 0x3a, 0x0c, 0x3a, 0x2b },
663 { STV090x_QPSK_25, 0x1c, 0x3c, 0x1b, 0x3c, 0x3a, 0x1c, 0x3a, 0x3b, 0x3a, 0x2b }
664};
665
666/* Cut 2.0 Short Frame Tracking CR Loop */
667static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut20[] = {
668 /* MODCOD 2M 5M 10M 20M 30M */
669 { STV090x_QPSK, 0x2f, 0x2e, 0x0e, 0x0e, 0x3d },
670 { STV090x_8PSK, 0x3e, 0x0e, 0x2d, 0x0d, 0x3c },
671 { STV090x_16APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d },
672 { STV090x_32APSK, 0x1e, 0x1e, 0x1e, 0x3d, 0x2d }
673};
674
675/* Cut 3.0 Short Frame Tracking CR Loop */
676static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut30[] = {
677 /* MODCOD 2M 5M 10M 20M 30M */
678 { STV090x_QPSK, 0x2C, 0x2B, 0x0B, 0x0B, 0x3A },
679 { STV090x_8PSK, 0x3B, 0x0B, 0x2A, 0x0A, 0x39 },
680 { STV090x_16APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A },
681 { STV090x_32APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A }
682};
683
684static inline s32 comp2(s32 __x, s32 __width)
685{
686 if (__width == 32)
687 return __x;
688 else
689 return (__x >= (1 << (__width - 1))) ? (__x - (1 << __width)) : __x;
690}
691
692static int stv090x_read_reg(struct stv090x_state *state, unsigned int reg)
693{
694 const struct stv090x_config *config = state->config;
695 int ret;
696
697 u8 b0[] = { reg >> 8, reg & 0xff };
698 u8 buf;
699
700 struct i2c_msg msg[] = {
701 { .addr = config->address, .flags = 0, .buf = b0, .len = 2 },
702 { .addr = config->address, .flags = I2C_M_RD, .buf = &buf, .len = 1 }
703 };
704
705 ret = i2c_transfer(state->i2c, msg, 2);
706 if (ret != 2) {
707 if (ret != -ERESTARTSYS)
708 dprintk(FE_ERROR, 1,
709 "Read error, Reg=[0x%02x], Status=%d",
710 reg, ret);
711
712 return ret < 0 ? ret : -EREMOTEIO;
713 }
714 if (unlikely(*state->verbose >= FE_DEBUGREG))
715 dprintk(FE_ERROR, 1, "Reg=[0x%02x], data=%02x",
716 reg, buf);
717
718 return (unsigned int) buf;
719}
720
721static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8 *data, u32 count)
722{
723 const struct stv090x_config *config = state->config;
724 int ret;
725 u8 buf[2 + count];
726 struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0, .buf = buf, .len = 2 + count };
727
728 buf[0] = reg >> 8;
729 buf[1] = reg & 0xff;
730 memcpy(&buf[2], data, count);
731
732 if (unlikely(*state->verbose >= FE_DEBUGREG)) {
733 int i;
734
735 printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg);
736 for (i = 0; i < count; i++)
737 printk(" %02x", data[i]);
738 printk("\n");
739 }
740
741 ret = i2c_transfer(state->i2c, &i2c_msg, 1);
742 if (ret != 1) {
743 if (ret != -ERESTARTSYS)
744 dprintk(FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d",
745 reg, data[0], count, ret);
746 return ret < 0 ? ret : -EREMOTEIO;
747 }
748
749 return 0;
750}
751
752static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data)
753{
754 return stv090x_write_regs(state, reg, &data, 1);
755}
756
757static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
758{
759 u32 reg;
760
761 /*
762 * NOTE! A lock is used as a FSM to control the state in which
763 * access is serialized between two tuners on the same demod.
764 * This has nothing to do with a lock to protect a critical section
765 * which may in some other cases be confused with protecting I/O
766 * access to the demodulator gate.
767 * In case of any error, the lock is unlocked and exit within the
768 * relevant operations themselves.
769 */
770 if (enable) {
771 if (state->config->tuner_i2c_lock)
772 state->config->tuner_i2c_lock(&state->frontend, 1);
773 else
774 mutex_lock(&state->internal->tuner_lock);
775 }
776
777 reg = STV090x_READ_DEMOD(state, I2CRPT);
778 if (enable) {
779 dprintk(FE_DEBUG, 1, "Enable Gate");
780 STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 1);
781 if (STV090x_WRITE_DEMOD(state, I2CRPT, reg) < 0)
782 goto err;
783
784 } else {
785 dprintk(FE_DEBUG, 1, "Disable Gate");
786 STV090x_SETFIELD_Px(reg, I2CT_ON_FIELD, 0);
787 if ((STV090x_WRITE_DEMOD(state, I2CRPT, reg)) < 0)
788 goto err;
789 }
790
791 if (!enable) {
792 if (state->config->tuner_i2c_lock)
793 state->config->tuner_i2c_lock(&state->frontend, 0);
794 else
795 mutex_unlock(&state->internal->tuner_lock);
796 }
797
798 return 0;
799err:
800 dprintk(FE_ERROR, 1, "I/O error");
801 if (state->config->tuner_i2c_lock)
802 state->config->tuner_i2c_lock(&state->frontend, 0);
803 else
804 mutex_unlock(&state->internal->tuner_lock);
805 return -1;
806}
807
808static void stv090x_get_lock_tmg(struct stv090x_state *state)
809{
810 switch (state->algo) {
811 case STV090x_BLIND_SEARCH:
812 dprintk(FE_DEBUG, 1, "Blind Search");
813 if (state->srate <= 1500000) { /*10Msps< SR <=15Msps*/
814 state->DemodTimeout = 1500;
815 state->FecTimeout = 400;
816 } else if (state->srate <= 5000000) { /*10Msps< SR <=15Msps*/
817 state->DemodTimeout = 1000;
818 state->FecTimeout = 300;
819 } else { /*SR >20Msps*/
820 state->DemodTimeout = 700;
821 state->FecTimeout = 100;
822 }
823 break;
824
825 case STV090x_COLD_SEARCH:
826 case STV090x_WARM_SEARCH:
827 default:
828 dprintk(FE_DEBUG, 1, "Normal Search");
829 if (state->srate <= 1000000) { /*SR <=1Msps*/
830 state->DemodTimeout = 4500;
831 state->FecTimeout = 1700;
832 } else if (state->srate <= 2000000) { /*1Msps < SR <= 2Msps */
833 state->DemodTimeout = 2500;
834 state->FecTimeout = 1100;
835 } else if (state->srate <= 5000000) { /*2Msps < SR <= 5Msps */
836 state->DemodTimeout = 1000;
837 state->FecTimeout = 550;
838 } else if (state->srate <= 10000000) { /*5Msps < SR <= 10Msps */
839 state->DemodTimeout = 700;
840 state->FecTimeout = 250;
841 } else if (state->srate <= 20000000) { /*10Msps < SR <= 20Msps */
842 state->DemodTimeout = 400;
843 state->FecTimeout = 130;
844 } else { /*SR >20Msps*/
845 state->DemodTimeout = 300;
846 state->FecTimeout = 100;
847 }
848 break;
849 }
850
851 if (state->algo == STV090x_WARM_SEARCH)
852 state->DemodTimeout /= 2;
853}
854
855static int stv090x_set_srate(struct stv090x_state *state, u32 srate)
856{
857 u32 sym;
858
859 if (srate > 60000000) {
860 sym = (srate << 4); /* SR * 2^16 / master_clk */
861 sym /= (state->internal->mclk >> 12);
862 } else if (srate > 6000000) {
863 sym = (srate << 6);
864 sym /= (state->internal->mclk >> 10);
865 } else {
866 sym = (srate << 9);
867 sym /= (state->internal->mclk >> 7);
868 }
869
870 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0x7f) < 0) /* MSB */
871 goto err;
872 if (STV090x_WRITE_DEMOD(state, SFRINIT0, (sym & 0xff)) < 0) /* LSB */
873 goto err;
874
875 return 0;
876err:
877 dprintk(FE_ERROR, 1, "I/O error");
878 return -1;
879}
880
881static int stv090x_set_max_srate(struct stv090x_state *state, u32 clk, u32 srate)
882{
883 u32 sym;
884
885 srate = 105 * (srate / 100);
886 if (srate > 60000000) {
887 sym = (srate << 4); /* SR * 2^16 / master_clk */
888 sym /= (state->internal->mclk >> 12);
889 } else if (srate > 6000000) {
890 sym = (srate << 6);
891 sym /= (state->internal->mclk >> 10);
892 } else {
893 sym = (srate << 9);
894 sym /= (state->internal->mclk >> 7);
895 }
896
897 if (sym < 0x7fff) {
898 if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0) /* MSB */
899 goto err;
900 if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0) /* LSB */
901 goto err;
902 } else {
903 if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x7f) < 0) /* MSB */
904 goto err;
905 if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xff) < 0) /* LSB */
906 goto err;
907 }
908
909 return 0;
910err:
911 dprintk(FE_ERROR, 1, "I/O error");
912 return -1;
913}
914
915static int stv090x_set_min_srate(struct stv090x_state *state, u32 clk, u32 srate)
916{
917 u32 sym;
918
919 srate = 95 * (srate / 100);
920 if (srate > 60000000) {
921 sym = (srate << 4); /* SR * 2^16 / master_clk */
922 sym /= (state->internal->mclk >> 12);
923 } else if (srate > 6000000) {
924 sym = (srate << 6);
925 sym /= (state->internal->mclk >> 10);
926 } else {
927 sym = (srate << 9);
928 sym /= (state->internal->mclk >> 7);
929 }
930
931 if (STV090x_WRITE_DEMOD(state, SFRLOW1, ((sym >> 8) & 0x7f)) < 0) /* MSB */
932 goto err;
933 if (STV090x_WRITE_DEMOD(state, SFRLOW0, (sym & 0xff)) < 0) /* LSB */
934 goto err;
935 return 0;
936err:
937 dprintk(FE_ERROR, 1, "I/O error");
938 return -1;
939}
940
941static u32 stv090x_car_width(u32 srate, enum stv090x_rolloff rolloff)
942{
943 u32 ro;
944
945 switch (rolloff) {
946 case STV090x_RO_20:
947 ro = 20;
948 break;
949 case STV090x_RO_25:
950 ro = 25;
951 break;
952 case STV090x_RO_35:
953 default:
954 ro = 35;
955 break;
956 }
957
958 return srate + (srate * ro) / 100;
959}
960
961static int stv090x_set_vit_thacq(struct stv090x_state *state)
962{
963 if (STV090x_WRITE_DEMOD(state, VTH12, 0x96) < 0)
964 goto err;
965 if (STV090x_WRITE_DEMOD(state, VTH23, 0x64) < 0)
966 goto err;
967 if (STV090x_WRITE_DEMOD(state, VTH34, 0x36) < 0)
968 goto err;
969 if (STV090x_WRITE_DEMOD(state, VTH56, 0x23) < 0)
970 goto err;
971 if (STV090x_WRITE_DEMOD(state, VTH67, 0x1e) < 0)
972 goto err;
973 if (STV090x_WRITE_DEMOD(state, VTH78, 0x19) < 0)
974 goto err;
975 return 0;
976err:
977 dprintk(FE_ERROR, 1, "I/O error");
978 return -1;
979}
980
981static int stv090x_set_vit_thtracq(struct stv090x_state *state)
982{
983 if (STV090x_WRITE_DEMOD(state, VTH12, 0xd0) < 0)
984 goto err;
985 if (STV090x_WRITE_DEMOD(state, VTH23, 0x7d) < 0)
986 goto err;
987 if (STV090x_WRITE_DEMOD(state, VTH34, 0x53) < 0)
988 goto err;
989 if (STV090x_WRITE_DEMOD(state, VTH56, 0x2f) < 0)
990 goto err;
991 if (STV090x_WRITE_DEMOD(state, VTH67, 0x24) < 0)
992 goto err;
993 if (STV090x_WRITE_DEMOD(state, VTH78, 0x1f) < 0)
994 goto err;
995 return 0;
996err:
997 dprintk(FE_ERROR, 1, "I/O error");
998 return -1;
999}
1000
1001static int stv090x_set_viterbi(struct stv090x_state *state)
1002{
1003 switch (state->search_mode) {
1004 case STV090x_SEARCH_AUTO:
1005 if (STV090x_WRITE_DEMOD(state, FECM, 0x10) < 0) /* DVB-S and DVB-S2 */
1006 goto err;
1007 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x3f) < 0) /* all puncture rate */
1008 goto err;
1009 break;
1010 case STV090x_SEARCH_DVBS1:
1011 if (STV090x_WRITE_DEMOD(state, FECM, 0x00) < 0) /* disable DSS */
1012 goto err;
1013 switch (state->fec) {
1014 case STV090x_PR12:
1015 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0)
1016 goto err;
1017 break;
1018
1019 case STV090x_PR23:
1020 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0)
1021 goto err;
1022 break;
1023
1024 case STV090x_PR34:
1025 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x04) < 0)
1026 goto err;
1027 break;
1028
1029 case STV090x_PR56:
1030 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x08) < 0)
1031 goto err;
1032 break;
1033
1034 case STV090x_PR78:
1035 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x20) < 0)
1036 goto err;
1037 break;
1038
1039 default:
1040 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x2f) < 0) /* all */
1041 goto err;
1042 break;
1043 }
1044 break;
1045 case STV090x_SEARCH_DSS:
1046 if (STV090x_WRITE_DEMOD(state, FECM, 0x80) < 0)
1047 goto err;
1048 switch (state->fec) {
1049 case STV090x_PR12:
1050 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x01) < 0)
1051 goto err;
1052 break;
1053
1054 case STV090x_PR23:
1055 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x02) < 0)
1056 goto err;
1057 break;
1058
1059 case STV090x_PR67:
1060 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x10) < 0)
1061 goto err;
1062 break;
1063
1064 default:
1065 if (STV090x_WRITE_DEMOD(state, PRVIT, 0x13) < 0) /* 1/2, 2/3, 6/7 */
1066 goto err;
1067 break;
1068 }
1069 break;
1070 default:
1071 break;
1072 }
1073 return 0;
1074err:
1075 dprintk(FE_ERROR, 1, "I/O error");
1076 return -1;
1077}
1078
1079static int stv090x_stop_modcod(struct stv090x_state *state)
1080{
1081 if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
1082 goto err;
1083 if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0)
1084 goto err;
1085 if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0)
1086 goto err;
1087 if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0)
1088 goto err;
1089 if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0)
1090 goto err;
1091 if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0)
1092 goto err;
1093 if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0)
1094 goto err;
1095 if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xff) < 0)
1096 goto err;
1097 if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xff) < 0)
1098 goto err;
1099 if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xff) < 0)
1100 goto err;
1101 if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xff) < 0)
1102 goto err;
1103 if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xff) < 0)
1104 goto err;
1105 if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xff) < 0)
1106 goto err;
1107 if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xff) < 0)
1108 goto err;
1109 if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0)
1110 goto err;
1111 if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xff) < 0)
1112 goto err;
1113 return 0;
1114err:
1115 dprintk(FE_ERROR, 1, "I/O error");
1116 return -1;
1117}
1118
1119static int stv090x_activate_modcod(struct stv090x_state *state)
1120{
1121 if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
1122 goto err;
1123 if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xfc) < 0)
1124 goto err;
1125 if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xcc) < 0)
1126 goto err;
1127 if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xcc) < 0)
1128 goto err;
1129 if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xcc) < 0)
1130 goto err;
1131 if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xcc) < 0)
1132 goto err;
1133 if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xcc) < 0)
1134 goto err;
1135 if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0)
1136 goto err;
1137 if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0)
1138 goto err;
1139 if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0)
1140 goto err;
1141 if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0)
1142 goto err;
1143 if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0)
1144 goto err;
1145 if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0)
1146 goto err;
1147 if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0)
1148 goto err;
1149 if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xcc) < 0)
1150 goto err;
1151 if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0)
1152 goto err;
1153
1154 return 0;
1155err:
1156 dprintk(FE_ERROR, 1, "I/O error");
1157 return -1;
1158}
1159
1160static int stv090x_activate_modcod_single(struct stv090x_state *state)
1161{
1162
1163 if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
1164 goto err;
1165 if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xf0) < 0)
1166 goto err;
1167 if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0x00) < 0)
1168 goto err;
1169 if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0x00) < 0)
1170 goto err;
1171 if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0x00) < 0)
1172 goto err;
1173 if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0x00) < 0)
1174 goto err;
1175 if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0x00) < 0)
1176 goto err;
1177 if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0x00) < 0)
1178 goto err;
1179 if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0x00) < 0)
1180 goto err;
1181 if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0x00) < 0)
1182 goto err;
1183 if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0x00) < 0)
1184 goto err;
1185 if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0x00) < 0)
1186 goto err;
1187 if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0x00) < 0)
1188 goto err;
1189 if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0x00) < 0)
1190 goto err;
1191 if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0x00) < 0)
1192 goto err;
1193 if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0x0f) < 0)
1194 goto err;
1195
1196 return 0;
1197
1198err:
1199 dprintk(FE_ERROR, 1, "I/O error");
1200 return -1;
1201}
1202
1203static int stv090x_vitclk_ctl(struct stv090x_state *state, int enable)
1204{
1205 u32 reg;
1206
1207 switch (state->demod) {
1208 case STV090x_DEMODULATOR_0:
1209 mutex_lock(&state->internal->demod_lock);
1210 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
1211 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, enable);
1212 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
1213 goto err;
1214 mutex_unlock(&state->internal->demod_lock);
1215 break;
1216
1217 case STV090x_DEMODULATOR_1:
1218 mutex_lock(&state->internal->demod_lock);
1219 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
1220 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, enable);
1221 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
1222 goto err;
1223 mutex_unlock(&state->internal->demod_lock);
1224 break;
1225
1226 default:
1227 dprintk(FE_ERROR, 1, "Wrong demodulator!");
1228 break;
1229 }
1230 return 0;
1231err:
1232 mutex_unlock(&state->internal->demod_lock);
1233 dprintk(FE_ERROR, 1, "I/O error");
1234 return -1;
1235}
1236
1237static int stv090x_dvbs_track_crl(struct stv090x_state *state)
1238{
1239 if (state->internal->dev_ver >= 0x30) {
1240 /* Set ACLC BCLC optimised value vs SR */
1241 if (state->srate >= 15000000) {
1242 if (STV090x_WRITE_DEMOD(state, ACLC, 0x2b) < 0)
1243 goto err;
1244 if (STV090x_WRITE_DEMOD(state, BCLC, 0x1a) < 0)
1245 goto err;
1246 } else if ((state->srate >= 7000000) && (15000000 > state->srate)) {
1247 if (STV090x_WRITE_DEMOD(state, ACLC, 0x0c) < 0)
1248 goto err;
1249 if (STV090x_WRITE_DEMOD(state, BCLC, 0x1b) < 0)
1250 goto err;
1251 } else if (state->srate < 7000000) {
1252 if (STV090x_WRITE_DEMOD(state, ACLC, 0x2c) < 0)
1253 goto err;
1254 if (STV090x_WRITE_DEMOD(state, BCLC, 0x1c) < 0)
1255 goto err;
1256 }
1257
1258 } else {
1259 /* Cut 2.0 */
1260 if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0)
1261 goto err;
1262 if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)
1263 goto err;
1264 }
1265 return 0;
1266err:
1267 dprintk(FE_ERROR, 1, "I/O error");
1268 return -1;
1269}
1270
1271static int stv090x_delivery_search(struct stv090x_state *state)
1272{
1273 u32 reg;
1274
1275 switch (state->search_mode) {
1276 case STV090x_SEARCH_DVBS1:
1277 case STV090x_SEARCH_DSS:
1278 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1279 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
1280 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
1281 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1282 goto err;
1283
1284 /* Activate Viterbi decoder in legacy search,
1285 * do not use FRESVIT1, might impact VITERBI2
1286 */
1287 if (stv090x_vitclk_ctl(state, 0) < 0)
1288 goto err;
1289
1290 if (stv090x_dvbs_track_crl(state) < 0)
1291 goto err;
1292
1293 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x22) < 0) /* disable DVB-S2 */
1294 goto err;
1295
1296 if (stv090x_set_vit_thacq(state) < 0)
1297 goto err;
1298 if (stv090x_set_viterbi(state) < 0)
1299 goto err;
1300 break;
1301
1302 case STV090x_SEARCH_DVBS2:
1303 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1304 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
1305 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
1306 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1307 goto err;
1308 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
1309 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
1310 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1311 goto err;
1312
1313 if (stv090x_vitclk_ctl(state, 1) < 0)
1314 goto err;
1315
1316 if (STV090x_WRITE_DEMOD(state, ACLC, 0x1a) < 0) /* stop DVB-S CR loop */
1317 goto err;
1318 if (STV090x_WRITE_DEMOD(state, BCLC, 0x09) < 0)
1319 goto err;
1320
1321 if (state->internal->dev_ver <= 0x20) {
1322 /* enable S2 carrier loop */
1323 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
1324 goto err;
1325 } else {
1326 /* > Cut 3: Stop carrier 3 */
1327 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0)
1328 goto err;
1329 }
1330
1331 if (state->demod_mode != STV090x_SINGLE) {
1332 /* Cut 2: enable link during search */
1333 if (stv090x_activate_modcod(state) < 0)
1334 goto err;
1335 } else {
1336 /* Single demodulator
1337 * Authorize SHORT and LONG frames,
1338 * QPSK, 8PSK, 16APSK and 32APSK
1339 */
1340 if (stv090x_activate_modcod_single(state) < 0)
1341 goto err;
1342 }
1343
1344 if (stv090x_set_vit_thtracq(state) < 0)
1345 goto err;
1346 break;
1347
1348 case STV090x_SEARCH_AUTO:
1349 default:
1350 /* enable DVB-S2 and DVB-S2 in Auto MODE */
1351 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1352 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
1353 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
1354 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1355 goto err;
1356 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
1357 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
1358 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1359 goto err;
1360
1361 if (stv090x_vitclk_ctl(state, 0) < 0)
1362 goto err;
1363
1364 if (stv090x_dvbs_track_crl(state) < 0)
1365 goto err;
1366
1367 if (state->internal->dev_ver <= 0x20) {
1368 /* enable S2 carrier loop */
1369 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x26) < 0)
1370 goto err;
1371 } else {
1372 /* > Cut 3: Stop carrier 3 */
1373 if (STV090x_WRITE_DEMOD(state, CAR2CFG, 0x66) < 0)
1374 goto err;
1375 }
1376
1377 if (state->demod_mode != STV090x_SINGLE) {
1378 /* Cut 2: enable link during search */
1379 if (stv090x_activate_modcod(state) < 0)
1380 goto err;
1381 } else {
1382 /* Single demodulator
1383 * Authorize SHORT and LONG frames,
1384 * QPSK, 8PSK, 16APSK and 32APSK
1385 */
1386 if (stv090x_activate_modcod_single(state) < 0)
1387 goto err;
1388 }
1389
1390 if (stv090x_set_vit_thacq(state) < 0)
1391 goto err;
1392
1393 if (stv090x_set_viterbi(state) < 0)
1394 goto err;
1395 break;
1396 }
1397 return 0;
1398err:
1399 dprintk(FE_ERROR, 1, "I/O error");
1400 return -1;
1401}
1402
1403static int stv090x_start_search(struct stv090x_state *state)
1404{
1405 u32 reg, freq_abs;
1406 s16 freq;
1407
1408 /* Reset demodulator */
1409 reg = STV090x_READ_DEMOD(state, DMDISTATE);
1410 STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f);
1411 if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
1412 goto err;
1413
1414 if (state->internal->dev_ver <= 0x20) {
1415 if (state->srate <= 5000000) {
1416 if (STV090x_WRITE_DEMOD(state, CARCFG, 0x44) < 0)
1417 goto err;
1418 if (STV090x_WRITE_DEMOD(state, CFRUP1, 0x0f) < 0)
1419 goto err;
1420 if (STV090x_WRITE_DEMOD(state, CFRUP0, 0xff) < 0)
1421 goto err;
1422 if (STV090x_WRITE_DEMOD(state, CFRLOW1, 0xf0) < 0)
1423 goto err;
1424 if (STV090x_WRITE_DEMOD(state, CFRLOW0, 0x00) < 0)
1425 goto err;
1426
1427 /*enlarge the timing bandwidth for Low SR*/
1428 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0)
1429 goto err;
1430 } else {
1431 /* If the symbol rate is >5 Msps
1432 Set The carrier search up and low to auto mode */
1433 if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)
1434 goto err;
1435 /*reduce the timing bandwidth for high SR*/
1436 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)
1437 goto err;
1438 }
1439 } else {
1440 /* >= Cut 3 */
1441 if (state->srate <= 5000000) {
1442 /* enlarge the timing bandwidth for Low SR */
1443 STV090x_WRITE_DEMOD(state, RTCS2, 0x68);
1444 } else {
1445 /* reduce timing bandwidth for high SR */
1446 STV090x_WRITE_DEMOD(state, RTCS2, 0x44);
1447 }
1448
1449 /* Set CFR min and max to manual mode */
1450 STV090x_WRITE_DEMOD(state, CARCFG, 0x46);
1451
1452 if (state->algo == STV090x_WARM_SEARCH) {
1453 /* WARM Start
1454 * CFR min = -1MHz,
1455 * CFR max = +1MHz
1456 */
1457 freq_abs = 1000 << 16;
1458 freq_abs /= (state->internal->mclk / 1000);
1459 freq = (s16) freq_abs;
1460 } else {
1461 /* COLD Start
1462 * CFR min =- (SearchRange / 2 + 600KHz)
1463 * CFR max = +(SearchRange / 2 + 600KHz)
1464 * (600KHz for the tuner step size)
1465 */
1466 freq_abs = (state->search_range / 2000) + 600;
1467 freq_abs = freq_abs << 16;
1468 freq_abs /= (state->internal->mclk / 1000);
1469 freq = (s16) freq_abs;
1470 }
1471
1472 if (STV090x_WRITE_DEMOD(state, CFRUP1, MSB(freq)) < 0)
1473 goto err;
1474 if (STV090x_WRITE_DEMOD(state, CFRUP0, LSB(freq)) < 0)
1475 goto err;
1476
1477 freq *= -1;
1478
1479 if (STV090x_WRITE_DEMOD(state, CFRLOW1, MSB(freq)) < 0)
1480 goto err;
1481 if (STV090x_WRITE_DEMOD(state, CFRLOW0, LSB(freq)) < 0)
1482 goto err;
1483
1484 }
1485
1486 if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0) < 0)
1487 goto err;
1488 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0) < 0)
1489 goto err;
1490
1491 if (state->internal->dev_ver >= 0x20) {
1492 if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
1493 goto err;
1494 if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
1495 goto err;
1496
1497 if ((state->search_mode == STV090x_SEARCH_DVBS1) ||
1498 (state->search_mode == STV090x_SEARCH_DSS) ||
1499 (state->search_mode == STV090x_SEARCH_AUTO)) {
1500
1501 if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0)
1502 goto err;
1503 if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0)
1504 goto err;
1505 }
1506 }
1507
1508 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00) < 0)
1509 goto err;
1510 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xe0) < 0)
1511 goto err;
1512 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xc0) < 0)
1513 goto err;
1514
1515 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1516 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0);
1517 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
1518 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1519 goto err;
1520 reg = STV090x_READ_DEMOD(state, DMDCFG2);
1521 STV090x_SETFIELD_Px(reg, S1S2_SEQUENTIAL_FIELD, 0x0);
1522 if (STV090x_WRITE_DEMOD(state, DMDCFG2, reg) < 0)
1523 goto err;
1524
1525 if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0)
1526 goto err;
1527
1528 if (state->internal->dev_ver >= 0x20) {
1529 /*Frequency offset detector setting*/
1530 if (state->srate < 2000000) {
1531 if (state->internal->dev_ver <= 0x20) {
1532 /* Cut 2 */
1533 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x39) < 0)
1534 goto err;
1535 } else {
1536 /* Cut 3 */
1537 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x89) < 0)
1538 goto err;
1539 }
1540 if (STV090x_WRITE_DEMOD(state, CARHDR, 0x40) < 0)
1541 goto err;
1542 } else if (state->srate < 10000000) {
1543 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4c) < 0)
1544 goto err;
1545 if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0)
1546 goto err;
1547 } else {
1548 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x4b) < 0)
1549 goto err;
1550 if (STV090x_WRITE_DEMOD(state, CARHDR, 0x20) < 0)
1551 goto err;
1552 }
1553 } else {
1554 if (state->srate < 10000000) {
1555 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xef) < 0)
1556 goto err;
1557 } else {
1558 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0xed) < 0)
1559 goto err;
1560 }
1561 }
1562
1563 switch (state->algo) {
1564 case STV090x_WARM_SEARCH:
1565 /* The symbol rate and the exact
1566 * carrier Frequency are known
1567 */
1568 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
1569 goto err;
1570 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
1571 goto err;
1572 break;
1573
1574 case STV090x_COLD_SEARCH:
1575 /* The symbol rate is known */
1576 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
1577 goto err;
1578 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
1579 goto err;
1580 break;
1581
1582 default:
1583 break;
1584 }
1585 return 0;
1586err:
1587 dprintk(FE_ERROR, 1, "I/O error");
1588 return -1;
1589}
1590
1591static int stv090x_get_agc2_min_level(struct stv090x_state *state)
1592{
1593 u32 agc2_min = 0xffff, agc2 = 0, freq_init, freq_step, reg;
1594 s32 i, j, steps, dir;
1595
1596 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
1597 goto err;
1598 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1599 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0);
1600 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
1601 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1602 goto err;
1603
1604 if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0) /* SR = 65 Msps Max */
1605 goto err;
1606 if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0)
1607 goto err;
1608 if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0) /* SR= 400 ksps Min */
1609 goto err;
1610 if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0)
1611 goto err;
1612 if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0) /* stop acq @ coarse carrier state */
1613 goto err;
1614 if (stv090x_set_srate(state, 1000000) < 0)
1615 goto err;
1616
1617 steps = state->search_range / 1000000;
1618 if (steps <= 0)
1619 steps = 1;
1620
1621 dir = 1;
1622 freq_step = (1000000 * 256) / (state->internal->mclk / 256);
1623 freq_init = 0;
1624
1625 for (i = 0; i < steps; i++) {
1626 if (dir > 0)
1627 freq_init = freq_init + (freq_step * i);
1628 else
1629 freq_init = freq_init - (freq_step * i);
1630
1631 dir *= -1;
1632
1633 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod RESET */
1634 goto err;
1635 if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_init >> 8) & 0xff) < 0)
1636 goto err;
1637 if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_init & 0xff) < 0)
1638 goto err;
1639 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x58) < 0) /* Demod RESET */
1640 goto err;
1641 msleep(10);
1642
1643 agc2 = 0;
1644 for (j = 0; j < 10; j++) {
1645 agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
1646 STV090x_READ_DEMOD(state, AGC2I0);
1647 }
1648 agc2 /= 10;
1649 if (agc2 < agc2_min)
1650 agc2_min = agc2;
1651 }
1652
1653 return agc2_min;
1654err:
1655 dprintk(FE_ERROR, 1, "I/O error");
1656 return -1;
1657}
1658
1659static u32 stv090x_get_srate(struct stv090x_state *state, u32 clk)
1660{
1661 u8 r3, r2, r1, r0;
1662 s32 srate, int_1, int_2, tmp_1, tmp_2;
1663
1664 r3 = STV090x_READ_DEMOD(state, SFR3);
1665 r2 = STV090x_READ_DEMOD(state, SFR2);
1666 r1 = STV090x_READ_DEMOD(state, SFR1);
1667 r0 = STV090x_READ_DEMOD(state, SFR0);
1668
1669 srate = ((r3 << 24) | (r2 << 16) | (r1 << 8) | r0);
1670
1671 int_1 = clk >> 16;
1672 int_2 = srate >> 16;
1673
1674 tmp_1 = clk % 0x10000;
1675 tmp_2 = srate % 0x10000;
1676
1677 srate = (int_1 * int_2) +
1678 ((int_1 * tmp_2) >> 16) +
1679 ((int_2 * tmp_1) >> 16);
1680
1681 return srate;
1682}
1683
1684static u32 stv090x_srate_srch_coarse(struct stv090x_state *state)
1685{
1686 struct dvb_frontend *fe = &state->frontend;
1687
1688 int tmg_lock = 0, i;
1689 s32 tmg_cpt = 0, dir = 1, steps, cur_step = 0, freq;
1690 u32 srate_coarse = 0, agc2 = 0, car_step = 1200, reg;
1691 u32 agc2th;
1692
1693 if (state->internal->dev_ver >= 0x30)
1694 agc2th = 0x2e00;
1695 else
1696 agc2th = 0x1f00;
1697
1698 reg = STV090x_READ_DEMOD(state, DMDISTATE);
1699 STV090x_SETFIELD_Px(reg, I2C_DEMOD_MODE_FIELD, 0x1f); /* Demod RESET */
1700 if (STV090x_WRITE_DEMOD(state, DMDISTATE, reg) < 0)
1701 goto err;
1702 if (STV090x_WRITE_DEMOD(state, TMGCFG, 0x12) < 0)
1703 goto err;
1704 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0)
1705 goto err;
1706 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0xf0) < 0)
1707 goto err;
1708 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0xe0) < 0)
1709 goto err;
1710 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1711 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 1);
1712 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0);
1713 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1714 goto err;
1715
1716 if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x83) < 0)
1717 goto err;
1718 if (STV090x_WRITE_DEMOD(state, SFRUP0, 0xc0) < 0)
1719 goto err;
1720 if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x82) < 0)
1721 goto err;
1722 if (STV090x_WRITE_DEMOD(state, SFRLOW0, 0xa0) < 0)
1723 goto err;
1724 if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x00) < 0)
1725 goto err;
1726 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x50) < 0)
1727 goto err;
1728
1729 if (state->internal->dev_ver >= 0x30) {
1730 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x99) < 0)
1731 goto err;
1732 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x98) < 0)
1733 goto err;
1734
1735 } else if (state->internal->dev_ver >= 0x20) {
1736 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x6a) < 0)
1737 goto err;
1738 if (STV090x_WRITE_DEMOD(state, SFRSTEP, 0x95) < 0)
1739 goto err;
1740 }
1741
1742 if (state->srate <= 2000000)
1743 car_step = 1000;
1744 else if (state->srate <= 5000000)
1745 car_step = 2000;
1746 else if (state->srate <= 12000000)
1747 car_step = 3000;
1748 else
1749 car_step = 5000;
1750
1751 steps = -1 + ((state->search_range / 1000) / car_step);
1752 steps /= 2;
1753 steps = (2 * steps) + 1;
1754 if (steps < 0)
1755 steps = 1;
1756 else if (steps > 10) {
1757 steps = 11;
1758 car_step = (state->search_range / 1000) / 10;
1759 }
1760 cur_step = 0;
1761 dir = 1;
1762 freq = state->frequency;
1763
1764 while ((!tmg_lock) && (cur_step < steps)) {
1765 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5f) < 0) /* Demod RESET */
1766 goto err;
1767 if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
1768 goto err;
1769 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
1770 goto err;
1771 if (STV090x_WRITE_DEMOD(state, SFRINIT1, 0x00) < 0)
1772 goto err;
1773 if (STV090x_WRITE_DEMOD(state, SFRINIT0, 0x00) < 0)
1774 goto err;
1775 /* trigger acquisition */
1776 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x40) < 0)
1777 goto err;
1778 msleep(50);
1779 for (i = 0; i < 10; i++) {
1780 reg = STV090x_READ_DEMOD(state, DSTATUS);
1781 if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)
1782 tmg_cpt++;
1783 agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
1784 STV090x_READ_DEMOD(state, AGC2I0);
1785 }
1786 agc2 /= 10;
1787 srate_coarse = stv090x_get_srate(state, state->internal->mclk);
1788 cur_step++;
1789 dir *= -1;
1790 if ((tmg_cpt >= 5) && (agc2 < agc2th) &&
1791 (srate_coarse < 50000000) && (srate_coarse > 850000))
1792 tmg_lock = 1;
1793 else if (cur_step < steps) {
1794 if (dir > 0)
1795 freq += cur_step * car_step;
1796 else
1797 freq -= cur_step * car_step;
1798
1799 /* Setup tuner */
1800 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
1801 goto err;
1802
1803 if (state->config->tuner_set_frequency) {
1804 if (state->config->tuner_set_frequency(fe, freq) < 0)
1805 goto err_gateoff;
1806 }
1807
1808 if (state->config->tuner_set_bandwidth) {
1809 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
1810 goto err_gateoff;
1811 }
1812
1813 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
1814 goto err;
1815
1816 msleep(50);
1817
1818 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
1819 goto err;
1820
1821 if (state->config->tuner_get_status) {
1822 if (state->config->tuner_get_status(fe, &reg) < 0)
1823 goto err_gateoff;
1824 }
1825
1826 if (reg)
1827 dprintk(FE_DEBUG, 1, "Tuner phase locked");
1828 else
1829 dprintk(FE_DEBUG, 1, "Tuner unlocked");
1830
1831 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
1832 goto err;
1833
1834 }
1835 }
1836 if (!tmg_lock)
1837 srate_coarse = 0;
1838 else
1839 srate_coarse = stv090x_get_srate(state, state->internal->mclk);
1840
1841 return srate_coarse;
1842
1843err_gateoff:
1844 stv090x_i2c_gate_ctrl(state, 0);
1845err:
1846 dprintk(FE_ERROR, 1, "I/O error");
1847 return -1;
1848}
1849
1850static u32 stv090x_srate_srch_fine(struct stv090x_state *state)
1851{
1852 u32 srate_coarse, freq_coarse, sym, reg;
1853
1854 srate_coarse = stv090x_get_srate(state, state->internal->mclk);
1855 freq_coarse = STV090x_READ_DEMOD(state, CFR2) << 8;
1856 freq_coarse |= STV090x_READ_DEMOD(state, CFR1);
1857 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
1858
1859 if (sym < state->srate)
1860 srate_coarse = 0;
1861 else {
1862 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) /* Demod RESET */
1863 goto err;
1864 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0)
1865 goto err;
1866 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)
1867 goto err;
1868 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0)
1869 goto err;
1870 if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0)
1871 goto err;
1872 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
1873 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00);
1874 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
1875 goto err;
1876
1877 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
1878 goto err;
1879
1880 if (state->internal->dev_ver >= 0x30) {
1881 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x79) < 0)
1882 goto err;
1883 } else if (state->internal->dev_ver >= 0x20) {
1884 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
1885 goto err;
1886 }
1887
1888 if (srate_coarse > 3000000) {
1889 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
1890 sym = (sym / 1000) * 65536;
1891 sym /= (state->internal->mclk / 1000);
1892 if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
1893 goto err;
1894 if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
1895 goto err;
1896 sym = 10 * (srate_coarse / 13); /* SFRLOW = SFR - 30% */
1897 sym = (sym / 1000) * 65536;
1898 sym /= (state->internal->mclk / 1000);
1899 if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
1900 goto err;
1901 if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
1902 goto err;
1903 sym = (srate_coarse / 1000) * 65536;
1904 sym /= (state->internal->mclk / 1000);
1905 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
1906 goto err;
1907 if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
1908 goto err;
1909 } else {
1910 sym = 13 * (srate_coarse / 10); /* SFRUP = SFR + 30% */
1911 sym = (sym / 100) * 65536;
1912 sym /= (state->internal->mclk / 100);
1913 if (STV090x_WRITE_DEMOD(state, SFRUP1, (sym >> 8) & 0x7f) < 0)
1914 goto err;
1915 if (STV090x_WRITE_DEMOD(state, SFRUP0, sym & 0xff) < 0)
1916 goto err;
1917 sym = 10 * (srate_coarse / 14); /* SFRLOW = SFR - 30% */
1918 sym = (sym / 100) * 65536;
1919 sym /= (state->internal->mclk / 100);
1920 if (STV090x_WRITE_DEMOD(state, SFRLOW1, (sym >> 8) & 0x7f) < 0)
1921 goto err;
1922 if (STV090x_WRITE_DEMOD(state, SFRLOW0, sym & 0xff) < 0)
1923 goto err;
1924 sym = (srate_coarse / 100) * 65536;
1925 sym /= (state->internal->mclk / 100);
1926 if (STV090x_WRITE_DEMOD(state, SFRINIT1, (sym >> 8) & 0xff) < 0)
1927 goto err;
1928 if (STV090x_WRITE_DEMOD(state, SFRINIT0, sym & 0xff) < 0)
1929 goto err;
1930 }
1931 if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0)
1932 goto err;
1933 if (STV090x_WRITE_DEMOD(state, CFRINIT1, (freq_coarse >> 8) & 0xff) < 0)
1934 goto err;
1935 if (STV090x_WRITE_DEMOD(state, CFRINIT0, freq_coarse & 0xff) < 0)
1936 goto err;
1937 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) /* trigger acquisition */
1938 goto err;
1939 }
1940
1941 return srate_coarse;
1942
1943err:
1944 dprintk(FE_ERROR, 1, "I/O error");
1945 return -1;
1946}
1947
1948static int stv090x_get_dmdlock(struct stv090x_state *state, s32 timeout)
1949{
1950 s32 timer = 0, lock = 0;
1951 u32 reg;
1952 u8 stat;
1953
1954 while ((timer < timeout) && (!lock)) {
1955 reg = STV090x_READ_DEMOD(state, DMDSTATE);
1956 stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
1957
1958 switch (stat) {
1959 case 0: /* searching */
1960 case 1: /* first PLH detected */
1961 default:
1962 dprintk(FE_DEBUG, 1, "Demodulator searching ..");
1963 lock = 0;
1964 break;
1965 case 2: /* DVB-S2 mode */
1966 case 3: /* DVB-S1/legacy mode */
1967 reg = STV090x_READ_DEMOD(state, DSTATUS);
1968 lock = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
1969 break;
1970 }
1971
1972 if (!lock)
1973 msleep(10);
1974 else
1975 dprintk(FE_DEBUG, 1, "Demodulator acquired LOCK");
1976
1977 timer += 10;
1978 }
1979 return lock;
1980}
1981
1982static int stv090x_blind_search(struct stv090x_state *state)
1983{
1984 u32 agc2, reg, srate_coarse;
1985 s32 cpt_fail, agc2_ovflw, i;
1986 u8 k_ref, k_max, k_min;
1987 int coarse_fail = 0;
1988 int lock;
1989
1990 k_max = 110;
1991 k_min = 10;
1992
1993 agc2 = stv090x_get_agc2_min_level(state);
1994
1995 if (agc2 > STV090x_SEARCH_AGC2_TH(state->internal->dev_ver)) {
1996 lock = 0;
1997 } else {
1998
1999 if (state->internal->dev_ver <= 0x20) {
2000 if (STV090x_WRITE_DEMOD(state, CARCFG, 0xc4) < 0)
2001 goto err;
2002 } else {
2003 /* > Cut 3 */
2004 if (STV090x_WRITE_DEMOD(state, CARCFG, 0x06) < 0)
2005 goto err;
2006 }
2007
2008 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x44) < 0)
2009 goto err;
2010
2011 if (state->internal->dev_ver >= 0x20) {
2012 if (STV090x_WRITE_DEMOD(state, EQUALCFG, 0x41) < 0)
2013 goto err;
2014 if (STV090x_WRITE_DEMOD(state, FFECFG, 0x41) < 0)
2015 goto err;
2016 if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x82) < 0)
2017 goto err;
2018 if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x00) < 0) /* set viterbi hysteresis */
2019 goto err;
2020 }
2021
2022 k_ref = k_max;
2023 do {
2024 if (STV090x_WRITE_DEMOD(state, KREFTMG, k_ref) < 0)
2025 goto err;
2026 if (stv090x_srate_srch_coarse(state) != 0) {
2027 srate_coarse = stv090x_srate_srch_fine(state);
2028 if (srate_coarse != 0) {
2029 stv090x_get_lock_tmg(state);
2030 lock = stv090x_get_dmdlock(state,
2031 state->DemodTimeout);
2032 } else {
2033 lock = 0;
2034 }
2035 } else {
2036 cpt_fail = 0;
2037 agc2_ovflw = 0;
2038 for (i = 0; i < 10; i++) {
2039 agc2 += (STV090x_READ_DEMOD(state, AGC2I1) << 8) |
2040 STV090x_READ_DEMOD(state, AGC2I0);
2041 if (agc2 >= 0xff00)
2042 agc2_ovflw++;
2043 reg = STV090x_READ_DEMOD(state, DSTATUS2);
2044 if ((STV090x_GETFIELD_Px(reg, CFR_OVERFLOW_FIELD) == 0x01) &&
2045 (STV090x_GETFIELD_Px(reg, DEMOD_DELOCK_FIELD) == 0x01))
2046
2047 cpt_fail++;
2048 }
2049 if ((cpt_fail > 7) || (agc2_ovflw > 7))
2050 coarse_fail = 1;
2051
2052 lock = 0;
2053 }
2054 k_ref -= 20;
2055 } while ((k_ref >= k_min) && (!lock) && (!coarse_fail));
2056 }
2057
2058 return lock;
2059
2060err:
2061 dprintk(FE_ERROR, 1, "I/O error");
2062 return -1;
2063}
2064
2065static int stv090x_chk_tmg(struct stv090x_state *state)
2066{
2067 u32 reg;
2068 s32 tmg_cpt = 0, i;
2069 u8 freq, tmg_thh, tmg_thl;
2070 int tmg_lock = 0;
2071
2072 freq = STV090x_READ_DEMOD(state, CARFREQ);
2073 tmg_thh = STV090x_READ_DEMOD(state, TMGTHRISE);
2074 tmg_thl = STV090x_READ_DEMOD(state, TMGTHFALL);
2075 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, 0x20) < 0)
2076 goto err;
2077 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, 0x00) < 0)
2078 goto err;
2079
2080 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
2081 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00); /* stop carrier offset search */
2082 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2083 goto err;
2084 if (STV090x_WRITE_DEMOD(state, RTC, 0x80) < 0)
2085 goto err;
2086
2087 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x40) < 0)
2088 goto err;
2089 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x00) < 0)
2090 goto err;
2091
2092 if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) /* set car ofset to 0 */
2093 goto err;
2094 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
2095 goto err;
2096 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x65) < 0)
2097 goto err;
2098
2099 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0) /* trigger acquisition */
2100 goto err;
2101 msleep(10);
2102
2103 for (i = 0; i < 10; i++) {
2104 reg = STV090x_READ_DEMOD(state, DSTATUS);
2105 if (STV090x_GETFIELD_Px(reg, TMGLOCK_QUALITY_FIELD) >= 2)
2106 tmg_cpt++;
2107 msleep(1);
2108 }
2109 if (tmg_cpt >= 3)
2110 tmg_lock = 1;
2111
2112 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
2113 goto err;
2114 if (STV090x_WRITE_DEMOD(state, RTC, 0x88) < 0) /* DVB-S1 timing */
2115 goto err;
2116 if (STV090x_WRITE_DEMOD(state, RTCS2, 0x68) < 0) /* DVB-S2 timing */
2117 goto err;
2118
2119 if (STV090x_WRITE_DEMOD(state, CARFREQ, freq) < 0)
2120 goto err;
2121 if (STV090x_WRITE_DEMOD(state, TMGTHRISE, tmg_thh) < 0)
2122 goto err;
2123 if (STV090x_WRITE_DEMOD(state, TMGTHFALL, tmg_thl) < 0)
2124 goto err;
2125
2126 return tmg_lock;
2127
2128err:
2129 dprintk(FE_ERROR, 1, "I/O error");
2130 return -1;
2131}
2132
2133static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
2134{
2135 struct dvb_frontend *fe = &state->frontend;
2136
2137 u32 reg;
2138 s32 car_step, steps, cur_step, dir, freq, timeout_lock;
2139 int lock = 0;
2140
2141 if (state->srate >= 10000000)
2142 timeout_lock = timeout_dmd / 3;
2143 else
2144 timeout_lock = timeout_dmd / 2;
2145
2146 lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */
2147 if (!lock) {
2148 if (state->srate >= 10000000) {
2149 if (stv090x_chk_tmg(state)) {
2150 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
2151 goto err;
2152 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
2153 goto err;
2154 lock = stv090x_get_dmdlock(state, timeout_dmd);
2155 } else {
2156 lock = 0;
2157 }
2158 } else {
2159 if (state->srate <= 4000000)
2160 car_step = 1000;
2161 else if (state->srate <= 7000000)
2162 car_step = 2000;
2163 else if (state->srate <= 10000000)
2164 car_step = 3000;
2165 else
2166 car_step = 5000;
2167
2168 steps = (state->search_range / 1000) / car_step;
2169 steps /= 2;
2170 steps = 2 * (steps + 1);
2171 if (steps < 0)
2172 steps = 2;
2173 else if (steps > 12)
2174 steps = 12;
2175
2176 cur_step = 1;
2177 dir = 1;
2178
2179 if (!lock) {
2180 freq = state->frequency;
2181 state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate;
2182 while ((cur_step <= steps) && (!lock)) {
2183 if (dir > 0)
2184 freq += cur_step * car_step;
2185 else
2186 freq -= cur_step * car_step;
2187
2188 /* Setup tuner */
2189 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
2190 goto err;
2191
2192 if (state->config->tuner_set_frequency) {
2193 if (state->config->tuner_set_frequency(fe, freq) < 0)
2194 goto err_gateoff;
2195 }
2196
2197 if (state->config->tuner_set_bandwidth) {
2198 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
2199 goto err_gateoff;
2200 }
2201
2202 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
2203 goto err;
2204
2205 msleep(50);
2206
2207 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
2208 goto err;
2209
2210 if (state->config->tuner_get_status) {
2211 if (state->config->tuner_get_status(fe, &reg) < 0)
2212 goto err_gateoff;
2213 }
2214
2215 if (reg)
2216 dprintk(FE_DEBUG, 1, "Tuner phase locked");
2217 else
2218 dprintk(FE_DEBUG, 1, "Tuner unlocked");
2219
2220 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
2221 goto err;
2222
2223 STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
2224 if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
2225 goto err;
2226 if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
2227 goto err;
2228 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
2229 goto err;
2230 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
2231 goto err;
2232 lock = stv090x_get_dmdlock(state, (timeout_dmd / 3));
2233
2234 dir *= -1;
2235 cur_step++;
2236 }
2237 }
2238 }
2239 }
2240
2241 return lock;
2242
2243err_gateoff:
2244 stv090x_i2c_gate_ctrl(state, 0);
2245err:
2246 dprintk(FE_ERROR, 1, "I/O error");
2247 return -1;
2248}
2249
2250static int stv090x_get_loop_params(struct stv090x_state *state, s32 *freq_inc, s32 *timeout_sw, s32 *steps)
2251{
2252 s32 timeout, inc, steps_max, srate, car_max;
2253
2254 srate = state->srate;
2255 car_max = state->search_range / 1000;
2256 car_max += car_max / 10;
2257 car_max = 65536 * (car_max / 2);
2258 car_max /= (state->internal->mclk / 1000);
2259
2260 if (car_max > 0x4000)
2261 car_max = 0x4000 ; /* maxcarrier should be<= +-1/4 Mclk */
2262
2263 inc = srate;
2264 inc /= state->internal->mclk / 1000;
2265 inc *= 256;
2266 inc *= 256;
2267 inc /= 1000;
2268
2269 switch (state->search_mode) {
2270 case STV090x_SEARCH_DVBS1:
2271 case STV090x_SEARCH_DSS:
2272 inc *= 3; /* freq step = 3% of srate */
2273 timeout = 20;
2274 break;
2275
2276 case STV090x_SEARCH_DVBS2:
2277 inc *= 4;
2278 timeout = 25;
2279 break;
2280
2281 case STV090x_SEARCH_AUTO:
2282 default:
2283 inc *= 3;
2284 timeout = 25;
2285 break;
2286 }
2287 inc /= 100;
2288 if ((inc > car_max) || (inc < 0))
2289 inc = car_max / 2; /* increment <= 1/8 Mclk */
2290
2291 timeout *= 27500; /* 27.5 Msps reference */
2292 if (srate > 0)
2293 timeout /= (srate / 1000);
2294
2295 if ((timeout > 100) || (timeout < 0))
2296 timeout = 100;
2297
2298 steps_max = (car_max / inc) + 1; /* min steps = 3 */
2299 if ((steps_max > 100) || (steps_max < 0)) {
2300 steps_max = 100; /* max steps <= 100 */
2301 inc = car_max / steps_max;
2302 }
2303 *freq_inc = inc;
2304 *timeout_sw = timeout;
2305 *steps = steps_max;
2306
2307 return 0;
2308}
2309
2310static int stv090x_chk_signal(struct stv090x_state *state)
2311{
2312 s32 offst_car, agc2, car_max;
2313 int no_signal;
2314
2315 offst_car = STV090x_READ_DEMOD(state, CFR2) << 8;
2316 offst_car |= STV090x_READ_DEMOD(state, CFR1);
2317 offst_car = comp2(offst_car, 16);
2318
2319 agc2 = STV090x_READ_DEMOD(state, AGC2I1) << 8;
2320 agc2 |= STV090x_READ_DEMOD(state, AGC2I0);
2321 car_max = state->search_range / 1000;
2322
2323 car_max += (car_max / 10); /* 10% margin */
2324 car_max = (65536 * car_max / 2);
2325 car_max /= state->internal->mclk / 1000;
2326
2327 if (car_max > 0x4000)
2328 car_max = 0x4000;
2329
2330 if ((agc2 > 0x2000) || (offst_car > 2 * car_max) || (offst_car < -2 * car_max)) {
2331 no_signal = 1;
2332 dprintk(FE_DEBUG, 1, "No Signal");
2333 } else {
2334 no_signal = 0;
2335 dprintk(FE_DEBUG, 1, "Found Signal");
2336 }
2337
2338 return no_signal;
2339}
2340
2341static int stv090x_search_car_loop(struct stv090x_state *state, s32 inc, s32 timeout, int zigzag, s32 steps_max)
2342{
2343 int no_signal, lock = 0;
2344 s32 cpt_step = 0, offst_freq, car_max;
2345 u32 reg;
2346
2347 car_max = state->search_range / 1000;
2348 car_max += (car_max / 10);
2349 car_max = (65536 * car_max / 2);
2350 car_max /= (state->internal->mclk / 1000);
2351 if (car_max > 0x4000)
2352 car_max = 0x4000;
2353
2354 if (zigzag)
2355 offst_freq = 0;
2356 else
2357 offst_freq = -car_max + inc;
2358
2359 do {
2360 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c) < 0)
2361 goto err;
2362 if (STV090x_WRITE_DEMOD(state, CFRINIT1, ((offst_freq / 256) & 0xff)) < 0)
2363 goto err;
2364 if (STV090x_WRITE_DEMOD(state, CFRINIT0, offst_freq & 0xff) < 0)
2365 goto err;
2366 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
2367 goto err;
2368
2369 reg = STV090x_READ_DEMOD(state, PDELCTRL1);
2370 STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x1); /* stop DVB-S2 packet delin */
2371 if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
2372 goto err;
2373
2374 if (zigzag) {
2375 if (offst_freq >= 0)
2376 offst_freq = -offst_freq - 2 * inc;
2377 else
2378 offst_freq = -offst_freq;
2379 } else {
2380 offst_freq += 2 * inc;
2381 }
2382
2383 cpt_step++;
2384
2385 lock = stv090x_get_dmdlock(state, timeout);
2386 no_signal = stv090x_chk_signal(state);
2387
2388 } while ((!lock) &&
2389 (!no_signal) &&
2390 ((offst_freq - inc) < car_max) &&
2391 ((offst_freq + inc) > -car_max) &&
2392 (cpt_step < steps_max));
2393
2394 reg = STV090x_READ_DEMOD(state, PDELCTRL1);
2395 STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0);
2396 if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
2397 goto err;
2398
2399 return lock;
2400err:
2401 dprintk(FE_ERROR, 1, "I/O error");
2402 return -1;
2403}
2404
2405static int stv090x_sw_algo(struct stv090x_state *state)
2406{
2407 int no_signal, zigzag, lock = 0;
2408 u32 reg;
2409
2410 s32 dvbs2_fly_wheel;
2411 s32 inc, timeout_step, trials, steps_max;
2412
2413 /* get params */
2414 stv090x_get_loop_params(state, &inc, &timeout_step, &steps_max);
2415
2416 switch (state->search_mode) {
2417 case STV090x_SEARCH_DVBS1:
2418 case STV090x_SEARCH_DSS:
2419 /* accelerate the frequency detector */
2420 if (state->internal->dev_ver >= 0x20) {
2421 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3B) < 0)
2422 goto err;
2423 }
2424
2425 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x49) < 0)
2426 goto err;
2427 zigzag = 0;
2428 break;
2429
2430 case STV090x_SEARCH_DVBS2:
2431 if (state->internal->dev_ver >= 0x20) {
2432 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
2433 goto err;
2434 }
2435
2436 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0)
2437 goto err;
2438 zigzag = 1;
2439 break;
2440
2441 case STV090x_SEARCH_AUTO:
2442 default:
2443 /* accelerate the frequency detector */
2444 if (state->internal->dev_ver >= 0x20) {
2445 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x3b) < 0)
2446 goto err;
2447 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
2448 goto err;
2449 }
2450
2451 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0xc9) < 0)
2452 goto err;
2453 zigzag = 0;
2454 break;
2455 }
2456
2457 trials = 0;
2458 do {
2459 lock = stv090x_search_car_loop(state, inc, timeout_step, zigzag, steps_max);
2460 no_signal = stv090x_chk_signal(state);
2461 trials++;
2462
2463 /*run the SW search 2 times maximum*/
2464 if (lock || no_signal || (trials == 2)) {
2465 /*Check if the demod is not losing lock in DVBS2*/
2466 if (state->internal->dev_ver >= 0x20) {
2467 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
2468 goto err;
2469 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
2470 goto err;
2471 }
2472
2473 reg = STV090x_READ_DEMOD(state, DMDSTATE);
2474 if ((lock) && (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == STV090x_DVBS2)) {
2475 /*Check if the demod is not losing lock in DVBS2*/
2476 msleep(timeout_step);
2477 reg = STV090x_READ_DEMOD(state, DMDFLYW);
2478 dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD);
2479 if (dvbs2_fly_wheel < 0xd) { /*if correct frames is decrementing */
2480 msleep(timeout_step);
2481 reg = STV090x_READ_DEMOD(state, DMDFLYW);
2482 dvbs2_fly_wheel = STV090x_GETFIELD_Px(reg, FLYWHEEL_CPT_FIELD);
2483 }
2484 if (dvbs2_fly_wheel < 0xd) {
2485 /*FALSE lock, The demod is losing lock */
2486 lock = 0;
2487 if (trials < 2) {
2488 if (state->internal->dev_ver >= 0x20) {
2489 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x79) < 0)
2490 goto err;
2491 }
2492
2493 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, 0x89) < 0)
2494 goto err;
2495 }
2496 }
2497 }
2498 }
2499 } while ((!lock) && (trials < 2) && (!no_signal));
2500
2501 return lock;
2502err:
2503 dprintk(FE_ERROR, 1, "I/O error");
2504 return -1;
2505}
2506
2507static enum stv090x_delsys stv090x_get_std(struct stv090x_state *state)
2508{
2509 u32 reg;
2510 enum stv090x_delsys delsys;
2511
2512 reg = STV090x_READ_DEMOD(state, DMDSTATE);
2513 if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 2)
2514 delsys = STV090x_DVBS2;
2515 else if (STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD) == 3) {
2516 reg = STV090x_READ_DEMOD(state, FECM);
2517 if (STV090x_GETFIELD_Px(reg, DSS_DVB_FIELD) == 1)
2518 delsys = STV090x_DSS;
2519 else
2520 delsys = STV090x_DVBS1;
2521 } else {
2522 delsys = STV090x_ERROR;
2523 }
2524
2525 return delsys;
2526}
2527
2528/* in Hz */
2529static s32 stv090x_get_car_freq(struct stv090x_state *state, u32 mclk)
2530{
2531 s32 derot, int_1, int_2, tmp_1, tmp_2;
2532
2533 derot = STV090x_READ_DEMOD(state, CFR2) << 16;
2534 derot |= STV090x_READ_DEMOD(state, CFR1) << 8;
2535 derot |= STV090x_READ_DEMOD(state, CFR0);
2536
2537 derot = comp2(derot, 24);
2538 int_1 = mclk >> 12;
2539 int_2 = derot >> 12;
2540
2541 /* carrier_frequency = MasterClock * Reg / 2^24 */
2542 tmp_1 = mclk % 0x1000;
2543 tmp_2 = derot % 0x1000;
2544
2545 derot = (int_1 * int_2) +
2546 ((int_1 * tmp_2) >> 12) +
2547 ((int_2 * tmp_1) >> 12);
2548
2549 return derot;
2550}
2551
2552static int stv090x_get_viterbi(struct stv090x_state *state)
2553{
2554 u32 reg, rate;
2555
2556 reg = STV090x_READ_DEMOD(state, VITCURPUN);
2557 rate = STV090x_GETFIELD_Px(reg, VIT_CURPUN_FIELD);
2558
2559 switch (rate) {
2560 case 13:
2561 state->fec = STV090x_PR12;
2562 break;
2563
2564 case 18:
2565 state->fec = STV090x_PR23;
2566 break;
2567
2568 case 21:
2569 state->fec = STV090x_PR34;
2570 break;
2571
2572 case 24:
2573 state->fec = STV090x_PR56;
2574 break;
2575
2576 case 25:
2577 state->fec = STV090x_PR67;
2578 break;
2579
2580 case 26:
2581 state->fec = STV090x_PR78;
2582 break;
2583
2584 default:
2585 state->fec = STV090x_PRERR;
2586 break;
2587 }
2588
2589 return 0;
2590}
2591
2592static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *state)
2593{
2594 struct dvb_frontend *fe = &state->frontend;
2595
2596 u8 tmg;
2597 u32 reg;
2598 s32 i = 0, offst_freq;
2599
2600 msleep(5);
2601
2602 if (state->algo == STV090x_BLIND_SEARCH) {
2603 tmg = STV090x_READ_DEMOD(state, TMGREG2);
2604 STV090x_WRITE_DEMOD(state, SFRSTEP, 0x5c);
2605 while ((i <= 50) && (tmg != 0) && (tmg != 0xff)) {
2606 tmg = STV090x_READ_DEMOD(state, TMGREG2);
2607 msleep(5);
2608 i += 5;
2609 }
2610 }
2611 state->delsys = stv090x_get_std(state);
2612
2613 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
2614 goto err;
2615
2616 if (state->config->tuner_get_frequency) {
2617 if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)
2618 goto err_gateoff;
2619 }
2620
2621 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
2622 goto err;
2623
2624 offst_freq = stv090x_get_car_freq(state, state->internal->mclk) / 1000;
2625 state->frequency += offst_freq;
2626
2627 if (stv090x_get_viterbi(state) < 0)
2628 goto err;
2629
2630 reg = STV090x_READ_DEMOD(state, DMDMODCOD);
2631 state->modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD);
2632 state->pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01;
2633 state->frame_len = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) >> 1;
2634 reg = STV090x_READ_DEMOD(state, TMGOBS);
2635 state->rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD);
2636 reg = STV090x_READ_DEMOD(state, FECM);
2637 state->inversion = STV090x_GETFIELD_Px(reg, IQINV_FIELD);
2638
2639 if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000)) {
2640
2641 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
2642 goto err;
2643
2644 if (state->config->tuner_get_frequency) {
2645 if (state->config->tuner_get_frequency(fe, &state->frequency) < 0)
2646 goto err_gateoff;
2647 }
2648
2649 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
2650 goto err;
2651
2652 if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
2653 return STV090x_RANGEOK;
2654 else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000))
2655 return STV090x_RANGEOK;
2656 else
2657 return STV090x_OUTOFRANGE; /* Out of Range */
2658 } else {
2659 if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
2660 return STV090x_RANGEOK;
2661 else
2662 return STV090x_OUTOFRANGE;
2663 }
2664
2665 return STV090x_OUTOFRANGE;
2666
2667err_gateoff:
2668 stv090x_i2c_gate_ctrl(state, 0);
2669err:
2670 dprintk(FE_ERROR, 1, "I/O error");
2671 return -1;
2672}
2673
2674static u32 stv090x_get_tmgoffst(struct stv090x_state *state, u32 srate)
2675{
2676 s32 offst_tmg;
2677
2678 offst_tmg = STV090x_READ_DEMOD(state, TMGREG2) << 16;
2679 offst_tmg |= STV090x_READ_DEMOD(state, TMGREG1) << 8;
2680 offst_tmg |= STV090x_READ_DEMOD(state, TMGREG0);
2681
2682 offst_tmg = comp2(offst_tmg, 24); /* 2's complement */
2683 if (!offst_tmg)
2684 offst_tmg = 1;
2685
2686 offst_tmg = ((s32) srate * 10) / ((s32) 0x1000000 / offst_tmg);
2687 offst_tmg /= 320;
2688
2689 return offst_tmg;
2690}
2691
2692static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_modcod modcod, s32 pilots)
2693{
2694 u8 aclc = 0x29;
2695 s32 i;
2696 struct stv090x_long_frame_crloop *car_loop, *car_loop_qpsk_low, *car_loop_apsk_low;
2697
2698 if (state->internal->dev_ver == 0x20) {
2699 car_loop = stv090x_s2_crl_cut20;
2700 car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut20;
2701 car_loop_apsk_low = stv090x_s2_apsk_crl_cut20;
2702 } else {
2703 /* >= Cut 3 */
2704 car_loop = stv090x_s2_crl_cut30;
2705 car_loop_qpsk_low = stv090x_s2_lowqpsk_crl_cut30;
2706 car_loop_apsk_low = stv090x_s2_apsk_crl_cut30;
2707 }
2708
2709 if (modcod < STV090x_QPSK_12) {
2710 i = 0;
2711 while ((i < 3) && (modcod != car_loop_qpsk_low[i].modcod))
2712 i++;
2713
2714 if (i >= 3)
2715 i = 2;
2716
2717 } else {
2718 i = 0;
2719 while ((i < 14) && (modcod != car_loop[i].modcod))
2720 i++;
2721
2722 if (i >= 14) {
2723 i = 0;
2724 while ((i < 11) && (modcod != car_loop_apsk_low[i].modcod))
2725 i++;
2726
2727 if (i >= 11)
2728 i = 10;
2729 }
2730 }
2731
2732 if (modcod <= STV090x_QPSK_25) {
2733 if (pilots) {
2734 if (state->srate <= 3000000)
2735 aclc = car_loop_qpsk_low[i].crl_pilots_on_2;
2736 else if (state->srate <= 7000000)
2737 aclc = car_loop_qpsk_low[i].crl_pilots_on_5;
2738 else if (state->srate <= 15000000)
2739 aclc = car_loop_qpsk_low[i].crl_pilots_on_10;
2740 else if (state->srate <= 25000000)
2741 aclc = car_loop_qpsk_low[i].crl_pilots_on_20;
2742 else
2743 aclc = car_loop_qpsk_low[i].crl_pilots_on_30;
2744 } else {
2745 if (state->srate <= 3000000)
2746 aclc = car_loop_qpsk_low[i].crl_pilots_off_2;
2747 else if (state->srate <= 7000000)
2748 aclc = car_loop_qpsk_low[i].crl_pilots_off_5;
2749 else if (state->srate <= 15000000)
2750 aclc = car_loop_qpsk_low[i].crl_pilots_off_10;
2751 else if (state->srate <= 25000000)
2752 aclc = car_loop_qpsk_low[i].crl_pilots_off_20;
2753 else
2754 aclc = car_loop_qpsk_low[i].crl_pilots_off_30;
2755 }
2756
2757 } else if (modcod <= STV090x_8PSK_910) {
2758 if (pilots) {
2759 if (state->srate <= 3000000)
2760 aclc = car_loop[i].crl_pilots_on_2;
2761 else if (state->srate <= 7000000)
2762 aclc = car_loop[i].crl_pilots_on_5;
2763 else if (state->srate <= 15000000)
2764 aclc = car_loop[i].crl_pilots_on_10;
2765 else if (state->srate <= 25000000)
2766 aclc = car_loop[i].crl_pilots_on_20;
2767 else
2768 aclc = car_loop[i].crl_pilots_on_30;
2769 } else {
2770 if (state->srate <= 3000000)
2771 aclc = car_loop[i].crl_pilots_off_2;
2772 else if (state->srate <= 7000000)
2773 aclc = car_loop[i].crl_pilots_off_5;
2774 else if (state->srate <= 15000000)
2775 aclc = car_loop[i].crl_pilots_off_10;
2776 else if (state->srate <= 25000000)
2777 aclc = car_loop[i].crl_pilots_off_20;
2778 else
2779 aclc = car_loop[i].crl_pilots_off_30;
2780 }
2781 } else { /* 16APSK and 32APSK */
2782 if (state->srate <= 3000000)
2783 aclc = car_loop_apsk_low[i].crl_pilots_on_2;
2784 else if (state->srate <= 7000000)
2785 aclc = car_loop_apsk_low[i].crl_pilots_on_5;
2786 else if (state->srate <= 15000000)
2787 aclc = car_loop_apsk_low[i].crl_pilots_on_10;
2788 else if (state->srate <= 25000000)
2789 aclc = car_loop_apsk_low[i].crl_pilots_on_20;
2790 else
2791 aclc = car_loop_apsk_low[i].crl_pilots_on_30;
2792 }
2793
2794 return aclc;
2795}
2796
2797static u8 stv090x_optimize_carloop_short(struct stv090x_state *state)
2798{
2799 struct stv090x_short_frame_crloop *short_crl = NULL;
2800 s32 index = 0;
2801 u8 aclc = 0x0b;
2802
2803 switch (state->modulation) {
2804 case STV090x_QPSK:
2805 default:
2806 index = 0;
2807 break;
2808 case STV090x_8PSK:
2809 index = 1;
2810 break;
2811 case STV090x_16APSK:
2812 index = 2;
2813 break;
2814 case STV090x_32APSK:
2815 index = 3;
2816 break;
2817 }
2818
2819 if (state->internal->dev_ver >= 0x30) {
2820 /* Cut 3.0 and up */
2821 short_crl = stv090x_s2_short_crl_cut30;
2822 } else {
2823 /* Cut 2.0 and up: we don't support cuts older than 2.0 */
2824 short_crl = stv090x_s2_short_crl_cut20;
2825 }
2826
2827 if (state->srate <= 3000000)
2828 aclc = short_crl[index].crl_2;
2829 else if (state->srate <= 7000000)
2830 aclc = short_crl[index].crl_5;
2831 else if (state->srate <= 15000000)
2832 aclc = short_crl[index].crl_10;
2833 else if (state->srate <= 25000000)
2834 aclc = short_crl[index].crl_20;
2835 else
2836 aclc = short_crl[index].crl_30;
2837
2838 return aclc;
2839}
2840
2841static int stv090x_optimize_track(struct stv090x_state *state)
2842{
2843 struct dvb_frontend *fe = &state->frontend;
2844
2845 enum stv090x_rolloff rolloff;
2846 enum stv090x_modcod modcod;
2847
2848 s32 srate, pilots, aclc, f_1, f_0, i = 0, blind_tune = 0;
2849 u32 reg;
2850
2851 srate = stv090x_get_srate(state, state->internal->mclk);
2852 srate += stv090x_get_tmgoffst(state, srate);
2853
2854 switch (state->delsys) {
2855 case STV090x_DVBS1:
2856 case STV090x_DSS:
2857 if (state->search_mode == STV090x_SEARCH_AUTO) {
2858 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
2859 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
2860 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 0);
2861 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2862 goto err;
2863 }
2864 reg = STV090x_READ_DEMOD(state, DEMOD);
2865 STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff);
2866 STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x01);
2867 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
2868 goto err;
2869
2870 if (state->internal->dev_ver >= 0x30) {
2871 if (stv090x_get_viterbi(state) < 0)
2872 goto err;
2873
2874 if (state->fec == STV090x_PR12) {
2875 if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x98) < 0)
2876 goto err;
2877 if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0)
2878 goto err;
2879 } else {
2880 if (STV090x_WRITE_DEMOD(state, GAUSSR0, 0x18) < 0)
2881 goto err;
2882 if (STV090x_WRITE_DEMOD(state, CCIR0, 0x18) < 0)
2883 goto err;
2884 }
2885 }
2886
2887 if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0)
2888 goto err;
2889 break;
2890
2891 case STV090x_DVBS2:
2892 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
2893 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 0);
2894 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
2895 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2896 goto err;
2897 if (state->internal->dev_ver >= 0x30) {
2898 if (STV090x_WRITE_DEMOD(state, ACLC, 0) < 0)
2899 goto err;
2900 if (STV090x_WRITE_DEMOD(state, BCLC, 0) < 0)
2901 goto err;
2902 }
2903 if (state->frame_len == STV090x_LONG_FRAME) {
2904 reg = STV090x_READ_DEMOD(state, DMDMODCOD);
2905 modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD);
2906 pilots = STV090x_GETFIELD_Px(reg, DEMOD_TYPE_FIELD) & 0x01;
2907 aclc = stv090x_optimize_carloop(state, modcod, pilots);
2908 if (modcod <= STV090x_QPSK_910) {
2909 STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc);
2910 } else if (modcod <= STV090x_8PSK_910) {
2911 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
2912 goto err;
2913 if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0)
2914 goto err;
2915 }
2916 if ((state->demod_mode == STV090x_SINGLE) && (modcod > STV090x_8PSK_910)) {
2917 if (modcod <= STV090x_16APSK_910) {
2918 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
2919 goto err;
2920 if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0)
2921 goto err;
2922 } else {
2923 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
2924 goto err;
2925 if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0)
2926 goto err;
2927 }
2928 }
2929 } else {
2930 /*Carrier loop setting for short frame*/
2931 aclc = stv090x_optimize_carloop_short(state);
2932 if (state->modulation == STV090x_QPSK) {
2933 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, aclc) < 0)
2934 goto err;
2935 } else if (state->modulation == STV090x_8PSK) {
2936 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
2937 goto err;
2938 if (STV090x_WRITE_DEMOD(state, ACLC2S28, aclc) < 0)
2939 goto err;
2940 } else if (state->modulation == STV090x_16APSK) {
2941 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
2942 goto err;
2943 if (STV090x_WRITE_DEMOD(state, ACLC2S216A, aclc) < 0)
2944 goto err;
2945 } else if (state->modulation == STV090x_32APSK) {
2946 if (STV090x_WRITE_DEMOD(state, ACLC2S2Q, 0x2a) < 0)
2947 goto err;
2948 if (STV090x_WRITE_DEMOD(state, ACLC2S232A, aclc) < 0)
2949 goto err;
2950 }
2951 }
2952
2953 STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67); /* PER */
2954 break;
2955
2956 case STV090x_ERROR:
2957 default:
2958 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
2959 STV090x_SETFIELD_Px(reg, DVBS1_ENABLE_FIELD, 1);
2960 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
2961 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2962 goto err;
2963 break;
2964 }
2965
2966 f_1 = STV090x_READ_DEMOD(state, CFR2);
2967 f_0 = STV090x_READ_DEMOD(state, CFR1);
2968 reg = STV090x_READ_DEMOD(state, TMGOBS);
2969 rolloff = STV090x_GETFIELD_Px(reg, ROLLOFF_STATUS_FIELD);
2970
2971 if (state->algo == STV090x_BLIND_SEARCH) {
2972 STV090x_WRITE_DEMOD(state, SFRSTEP, 0x00);
2973 reg = STV090x_READ_DEMOD(state, DMDCFGMD);
2974 STV090x_SETFIELD_Px(reg, SCAN_ENABLE_FIELD, 0x00);
2975 STV090x_SETFIELD_Px(reg, CFR_AUTOSCAN_FIELD, 0x00);
2976 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2977 goto err;
2978 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0)
2979 goto err;
2980
2981 if (stv090x_set_srate(state, srate) < 0)
2982 goto err;
2983 blind_tune = 1;
2984
2985 if (stv090x_dvbs_track_crl(state) < 0)
2986 goto err;
2987 }
2988
2989 if (state->internal->dev_ver >= 0x20) {
2990 if ((state->search_mode == STV090x_SEARCH_DVBS1) ||
2991 (state->search_mode == STV090x_SEARCH_DSS) ||
2992 (state->search_mode == STV090x_SEARCH_AUTO)) {
2993
2994 if (STV090x_WRITE_DEMOD(state, VAVSRVIT, 0x0a) < 0)
2995 goto err;
2996 if (STV090x_WRITE_DEMOD(state, VITSCALE, 0x00) < 0)
2997 goto err;
2998 }
2999 }
3000
3001 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
3002 goto err;
3003
3004 /* AUTO tracking MODE */
3005 if (STV090x_WRITE_DEMOD(state, SFRUP1, 0x80) < 0)
3006 goto err;
3007 /* AUTO tracking MODE */
3008 if (STV090x_WRITE_DEMOD(state, SFRLOW1, 0x80) < 0)
3009 goto err;
3010
3011 if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1) ||
3012 (state->srate < 10000000)) {
3013 /* update initial carrier freq with the found freq offset */
3014 if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
3015 goto err;
3016 if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
3017 goto err;
3018 state->tuner_bw = stv090x_car_width(srate, state->rolloff) + 10000000;
3019
3020 if ((state->internal->dev_ver >= 0x20) || (blind_tune == 1)) {
3021
3022 if (state->algo != STV090x_WARM_SEARCH) {
3023
3024 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
3025 goto err;
3026
3027 if (state->config->tuner_set_bandwidth) {
3028 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
3029 goto err_gateoff;
3030 }
3031
3032 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
3033 goto err;
3034
3035 }
3036 }
3037 if ((state->algo == STV090x_BLIND_SEARCH) || (state->srate < 10000000))
3038 msleep(50); /* blind search: wait 50ms for SR stabilization */
3039 else
3040 msleep(5);
3041
3042 stv090x_get_lock_tmg(state);
3043
3044 if (!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) {
3045 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
3046 goto err;
3047 if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
3048 goto err;
3049 if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
3050 goto err;
3051 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
3052 goto err;
3053
3054 i = 0;
3055
3056 while ((!(stv090x_get_dmdlock(state, (state->DemodTimeout / 2)))) && (i <= 2)) {
3057
3058 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
3059 goto err;
3060 if (STV090x_WRITE_DEMOD(state, CFRINIT1, f_1) < 0)
3061 goto err;
3062 if (STV090x_WRITE_DEMOD(state, CFRINIT0, f_0) < 0)
3063 goto err;
3064 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x18) < 0)
3065 goto err;
3066 i++;
3067 }
3068 }
3069
3070 }
3071
3072 if (state->internal->dev_ver >= 0x20) {
3073 if (STV090x_WRITE_DEMOD(state, CARFREQ, 0x49) < 0)
3074 goto err;
3075 }
3076
3077 if ((state->delsys == STV090x_DVBS1) || (state->delsys == STV090x_DSS))
3078 stv090x_set_vit_thtracq(state);
3079
3080 return 0;
3081
3082err_gateoff:
3083 stv090x_i2c_gate_ctrl(state, 0);
3084err:
3085 dprintk(FE_ERROR, 1, "I/O error");
3086 return -1;
3087}
3088
3089static int stv090x_get_feclock(struct stv090x_state *state, s32 timeout)
3090{
3091 s32 timer = 0, lock = 0, stat;
3092 u32 reg;
3093
3094 while ((timer < timeout) && (!lock)) {
3095 reg = STV090x_READ_DEMOD(state, DMDSTATE);
3096 stat = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
3097
3098 switch (stat) {
3099 case 0: /* searching */
3100 case 1: /* first PLH detected */
3101 default:
3102 lock = 0;
3103 break;
3104
3105 case 2: /* DVB-S2 mode */
3106 reg = STV090x_READ_DEMOD(state, PDELSTATUS1);
3107 lock = STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD);
3108 break;
3109
3110 case 3: /* DVB-S1/legacy mode */
3111 reg = STV090x_READ_DEMOD(state, VSTATUSVIT);
3112 lock = STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD);
3113 break;
3114 }
3115 if (!lock) {
3116 msleep(10);
3117 timer += 10;
3118 }
3119 }
3120 return lock;
3121}
3122
3123static int stv090x_get_lock(struct stv090x_state *state, s32 timeout_dmd, s32 timeout_fec)
3124{
3125 u32 reg;
3126 s32 timer = 0;
3127 int lock;
3128
3129 lock = stv090x_get_dmdlock(state, timeout_dmd);
3130 if (lock)
3131 lock = stv090x_get_feclock(state, timeout_fec);
3132
3133 if (lock) {
3134 lock = 0;
3135
3136 while ((timer < timeout_fec) && (!lock)) {
3137 reg = STV090x_READ_DEMOD(state, TSSTATUS);
3138 lock = STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD);
3139 msleep(1);
3140 timer++;
3141 }
3142 }
3143
3144 return lock;
3145}
3146
3147static int stv090x_set_s2rolloff(struct stv090x_state *state)
3148{
3149 u32 reg;
3150
3151 if (state->internal->dev_ver <= 0x20) {
3152 /* rolloff to auto mode if DVBS2 */
3153 reg = STV090x_READ_DEMOD(state, DEMOD);
3154 STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 0x00);
3155 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
3156 goto err;
3157 } else {
3158 /* DVB-S2 rolloff to auto mode if DVBS2 */
3159 reg = STV090x_READ_DEMOD(state, DEMOD);
3160 STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 0x00);
3161 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
3162 goto err;
3163 }
3164 return 0;
3165err:
3166 dprintk(FE_ERROR, 1, "I/O error");
3167 return -1;
3168}
3169
3170
3171static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
3172{
3173 struct dvb_frontend *fe = &state->frontend;
3174 enum stv090x_signal_state signal_state = STV090x_NOCARRIER;
3175 u32 reg;
3176 s32 agc1_power, power_iq = 0, i;
3177 int lock = 0, low_sr = 0, no_signal = 0;
3178
3179 reg = STV090x_READ_DEMOD(state, TSCFGH);
3180 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* Stop path 1 stream merger */
3181 if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
3182 goto err;
3183
3184 if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x5c) < 0) /* Demod stop */
3185 goto err;
3186
3187 if (state->internal->dev_ver >= 0x20) {
3188 if (state->srate > 5000000) {
3189 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x9e) < 0)
3190 goto err;
3191 } else {
3192 if (STV090x_WRITE_DEMOD(state, CORRELABS, 0x82) < 0)
3193 goto err;
3194 }
3195 }
3196
3197 stv090x_get_lock_tmg(state);
3198
3199 if (state->algo == STV090x_BLIND_SEARCH) {
3200 state->tuner_bw = 2 * 36000000; /* wide bw for unknown srate */
3201 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc0) < 0) /* wider srate scan */
3202 goto err;
3203 if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0)
3204 goto err;
3205 if (stv090x_set_srate(state, 1000000) < 0) /* initial srate = 1Msps */
3206 goto err;
3207 } else {
3208 /* known srate */
3209 if (STV090x_WRITE_DEMOD(state, DMDTOM, 0x20) < 0)
3210 goto err;
3211 if (STV090x_WRITE_DEMOD(state, TMGCFG, 0xd2) < 0)
3212 goto err;
3213
3214 if (state->srate < 2000000) {
3215 /* SR < 2MSPS */
3216 if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x63) < 0)
3217 goto err;
3218 } else {
3219 /* SR >= 2Msps */
3220 if (STV090x_WRITE_DEMOD(state, CORRELMANT, 0x70) < 0)
3221 goto err;
3222 }
3223
3224 if (STV090x_WRITE_DEMOD(state, AGC2REF, 0x38) < 0)
3225 goto err;
3226
3227 if (state->internal->dev_ver >= 0x20) {
3228 if (STV090x_WRITE_DEMOD(state, KREFTMG, 0x5a) < 0)
3229 goto err;
3230 if (state->algo == STV090x_COLD_SEARCH)
3231 state->tuner_bw = (15 * (stv090x_car_width(state->srate, state->rolloff) + 10000000)) / 10;
3232 else if (state->algo == STV090x_WARM_SEARCH)
3233 state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + 10000000;
3234 }
3235
3236 /* if cold start or warm (Symbolrate is known)
3237 * use a Narrow symbol rate scan range
3238 */
3239 if (STV090x_WRITE_DEMOD(state, TMGCFG2, 0xc1) < 0) /* narrow srate scan */
3240 goto err;
3241
3242 if (stv090x_set_srate(state, state->srate) < 0)
3243 goto err;
3244
3245 if (stv090x_set_max_srate(state, state->internal->mclk,
3246 state->srate) < 0)
3247 goto err;
3248 if (stv090x_set_min_srate(state, state->internal->mclk,
3249 state->srate) < 0)
3250 goto err;
3251
3252 if (state->srate >= 10000000)
3253 low_sr = 0;
3254 else
3255 low_sr = 1;
3256 }
3257
3258 /* Setup tuner */
3259 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
3260 goto err;
3261
3262 if (state->config->tuner_set_bbgain) {
3263 reg = state->config->tuner_bbgain;
3264 if (reg == 0)
3265 reg = 10; /* default: 10dB */
3266 if (state->config->tuner_set_bbgain(fe, reg) < 0)
3267 goto err_gateoff;
3268 }
3269
3270 if (state->config->tuner_set_frequency) {
3271 if (state->config->tuner_set_frequency(fe, state->frequency) < 0)
3272 goto err_gateoff;
3273 }
3274
3275 if (state->config->tuner_set_bandwidth) {
3276 if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
3277 goto err_gateoff;
3278 }
3279
3280 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
3281 goto err;
3282
3283 msleep(50);
3284
3285 if (state->config->tuner_get_status) {
3286 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
3287 goto err;
3288 if (state->config->tuner_get_status(fe, &reg) < 0)
3289 goto err_gateoff;
3290 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
3291 goto err;
3292
3293 if (reg)
3294 dprintk(FE_DEBUG, 1, "Tuner phase locked");
3295 else {
3296 dprintk(FE_DEBUG, 1, "Tuner unlocked");
3297 return STV090x_NOCARRIER;
3298 }
3299 }
3300
3301 msleep(10);
3302 agc1_power = MAKEWORD16(STV090x_READ_DEMOD(state, AGCIQIN1),
3303 STV090x_READ_DEMOD(state, AGCIQIN0));
3304
3305 if (agc1_power == 0) {
3306 /* If AGC1 integrator value is 0
3307 * then read POWERI, POWERQ
3308 */
3309 for (i = 0; i < 5; i++) {
3310 power_iq += (STV090x_READ_DEMOD(state, POWERI) +
3311 STV090x_READ_DEMOD(state, POWERQ)) >> 1;
3312 }
3313 power_iq /= 5;
3314 }
3315
3316 if ((agc1_power == 0) && (power_iq < STV090x_IQPOWER_THRESHOLD)) {
3317 dprintk(FE_ERROR, 1, "No Signal: POWER_IQ=0x%02x", power_iq);
3318 lock = 0;
3319 signal_state = STV090x_NOAGC1;
3320 } else {
3321 reg = STV090x_READ_DEMOD(state, DEMOD);
3322 STV090x_SETFIELD_Px(reg, SPECINV_CONTROL_FIELD, state->inversion);
3323
3324 if (state->internal->dev_ver <= 0x20) {
3325 /* rolloff to auto mode if DVBS2 */
3326 STV090x_SETFIELD_Px(reg, MANUAL_SXROLLOFF_FIELD, 1);
3327 } else {
3328 /* DVB-S2 rolloff to auto mode if DVBS2 */
3329 STV090x_SETFIELD_Px(reg, MANUAL_S2ROLLOFF_FIELD, 1);
3330 }
3331 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
3332 goto err;
3333
3334 if (stv090x_delivery_search(state) < 0)
3335 goto err;
3336
3337 if (state->algo != STV090x_BLIND_SEARCH) {
3338 if (stv090x_start_search(state) < 0)
3339 goto err;
3340 }
3341 }
3342
3343 if (signal_state == STV090x_NOAGC1)
3344 return signal_state;
3345
3346 if (state->algo == STV090x_BLIND_SEARCH)
3347 lock = stv090x_blind_search(state);
3348
3349 else if (state->algo == STV090x_COLD_SEARCH)
3350 lock = stv090x_get_coldlock(state, state->DemodTimeout);
3351
3352 else if (state->algo == STV090x_WARM_SEARCH)
3353 lock = stv090x_get_dmdlock(state, state->DemodTimeout);
3354
3355 if ((!lock) && (state->algo == STV090x_COLD_SEARCH)) {
3356 if (!low_sr) {
3357 if (stv090x_chk_tmg(state))
3358 lock = stv090x_sw_algo(state);
3359 }
3360 }
3361
3362 if (lock)
3363 signal_state = stv090x_get_sig_params(state);
3364
3365 if ((lock) && (signal_state == STV090x_RANGEOK)) { /* signal within Range */
3366 stv090x_optimize_track(state);
3367
3368 if (state->internal->dev_ver >= 0x20) {
3369 /* >= Cut 2.0 :release TS reset after
3370 * demod lock and optimized Tracking
3371 */
3372 reg = STV090x_READ_DEMOD(state, TSCFGH);
3373 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */
3374 if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
3375 goto err;
3376
3377 msleep(3);
3378
3379 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* merger reset */
3380 if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
3381 goto err;
3382
3383 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0); /* release merger reset */
3384 if (STV090x_WRITE_DEMOD(state, TSCFGH, reg) < 0)
3385 goto err;
3386 }
3387
3388 lock = stv090x_get_lock(state, state->FecTimeout,
3389 state->FecTimeout);
3390 if (lock) {
3391 if (state->delsys == STV090x_DVBS2) {
3392 stv090x_set_s2rolloff(state);
3393
3394 reg = STV090x_READ_DEMOD(state, PDELCTRL2);
3395 STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 1);
3396 if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0)
3397 goto err;
3398 /* Reset DVBS2 packet delinator error counter */
3399 reg = STV090x_READ_DEMOD(state, PDELCTRL2);
3400 STV090x_SETFIELD_Px(reg, RESET_UPKO_COUNT, 0);
3401 if (STV090x_WRITE_DEMOD(state, PDELCTRL2, reg) < 0)
3402 goto err;
3403
3404 if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x67) < 0) /* PER */
3405 goto err;
3406 } else {
3407 if (STV090x_WRITE_DEMOD(state, ERRCTRL1, 0x75) < 0)
3408 goto err;
3409 }
3410 /* Reset the Total packet counter */
3411 if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0x00) < 0)
3412 goto err;
3413 /* Reset the packet Error counter2 */
3414 if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)
3415 goto err;
3416 } else {
3417 signal_state = STV090x_NODATA;
3418 no_signal = stv090x_chk_signal(state);
3419 }
3420 }
3421 return signal_state;
3422
3423err_gateoff:
3424 stv090x_i2c_gate_ctrl(state, 0);
3425err:
3426 dprintk(FE_ERROR, 1, "I/O error");
3427 return -1;
3428}
3429
3430static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
3431{
3432 struct stv090x_state *state = fe->demodulator_priv;
3433 struct dtv_frontend_properties *props = &fe->dtv_property_cache;
3434
3435 if (p->frequency == 0)
3436 return DVBFE_ALGO_SEARCH_INVALID;
3437
3438 state->delsys = props->delivery_system;
3439 state->frequency = p->frequency;
3440 state->srate = p->u.qpsk.symbol_rate;
3441 state->search_mode = STV090x_SEARCH_AUTO;
3442 state->algo = STV090x_COLD_SEARCH;
3443 state->fec = STV090x_PRERR;
3444 if (state->srate > 10000000) {
3445 dprintk(FE_DEBUG, 1, "Search range: 10 MHz");
3446 state->search_range = 10000000;
3447 } else {
3448 dprintk(FE_DEBUG, 1, "Search range: 5 MHz");
3449 state->search_range = 5000000;
3450 }
3451
3452 if (stv090x_algo(state) == STV090x_RANGEOK) {
3453 dprintk(FE_DEBUG, 1, "Search success!");
3454 return DVBFE_ALGO_SEARCH_SUCCESS;
3455 } else {
3456 dprintk(FE_DEBUG, 1, "Search failed!");
3457 return DVBFE_ALGO_SEARCH_FAILED;
3458 }
3459
3460 return DVBFE_ALGO_SEARCH_ERROR;
3461}
3462
3463static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
3464{
3465 struct stv090x_state *state = fe->demodulator_priv;
3466 u32 reg;
3467 u8 search_state;
3468
3469 reg = STV090x_READ_DEMOD(state, DMDSTATE);
3470 search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
3471
3472 switch (search_state) {
3473 case 0: /* searching */
3474 case 1: /* first PLH detected */
3475 default:
3476 dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)");
3477 *status = 0;
3478 break;
3479
3480 case 2: /* DVB-S2 mode */
3481 dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2");
3482 reg = STV090x_READ_DEMOD(state, DSTATUS);
3483 if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) {
3484 reg = STV090x_READ_DEMOD(state, PDELSTATUS1);
3485 if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) {
3486 reg = STV090x_READ_DEMOD(state, TSSTATUS);
3487 if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
3488 *status = FE_HAS_SIGNAL |
3489 FE_HAS_CARRIER |
3490 FE_HAS_VITERBI |
3491 FE_HAS_SYNC |
3492 FE_HAS_LOCK;
3493 }
3494 }
3495 }
3496 break;
3497
3498 case 3: /* DVB-S1/legacy mode */
3499 dprintk(FE_DEBUG, 1, "Delivery system: DVB-S");
3500 reg = STV090x_READ_DEMOD(state, DSTATUS);
3501 if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) {
3502 reg = STV090x_READ_DEMOD(state, VSTATUSVIT);
3503 if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) {
3504 reg = STV090x_READ_DEMOD(state, TSSTATUS);
3505 if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) {
3506 *status = FE_HAS_SIGNAL |
3507 FE_HAS_CARRIER |
3508 FE_HAS_VITERBI |
3509 FE_HAS_SYNC |
3510 FE_HAS_LOCK;
3511 }
3512 }
3513 }
3514 break;
3515 }
3516
3517 return 0;
3518}
3519
3520static int stv090x_read_per(struct dvb_frontend *fe, u32 *per)
3521{
3522 struct stv090x_state *state = fe->demodulator_priv;
3523
3524 s32 count_4, count_3, count_2, count_1, count_0, count;
3525 u32 reg, h, m, l;
3526 enum fe_status status;
3527
3528 stv090x_read_status(fe, &status);
3529 if (!(status & FE_HAS_LOCK)) {
3530 *per = 1 << 23; /* Max PER */
3531 } else {
3532 /* Counter 2 */
3533 reg = STV090x_READ_DEMOD(state, ERRCNT22);
3534 h = STV090x_GETFIELD_Px(reg, ERR_CNT2_FIELD);
3535
3536 reg = STV090x_READ_DEMOD(state, ERRCNT21);
3537 m = STV090x_GETFIELD_Px(reg, ERR_CNT21_FIELD);
3538
3539 reg = STV090x_READ_DEMOD(state, ERRCNT20);
3540 l = STV090x_GETFIELD_Px(reg, ERR_CNT20_FIELD);
3541
3542 *per = ((h << 16) | (m << 8) | l);
3543
3544 count_4 = STV090x_READ_DEMOD(state, FBERCPT4);
3545 count_3 = STV090x_READ_DEMOD(state, FBERCPT3);
3546 count_2 = STV090x_READ_DEMOD(state, FBERCPT2);
3547 count_1 = STV090x_READ_DEMOD(state, FBERCPT1);
3548 count_0 = STV090x_READ_DEMOD(state, FBERCPT0);
3549
3550 if ((!count_4) && (!count_3)) {
3551 count = (count_2 & 0xff) << 16;
3552 count |= (count_1 & 0xff) << 8;
3553 count |= count_0 & 0xff;
3554 } else {
3555 count = 1 << 24;
3556 }
3557 if (count == 0)
3558 *per = 1;
3559 }
3560 if (STV090x_WRITE_DEMOD(state, FBERCPT4, 0) < 0)
3561 goto err;
3562 if (STV090x_WRITE_DEMOD(state, ERRCTRL2, 0xc1) < 0)
3563 goto err;
3564
3565 return 0;
3566err:
3567 dprintk(FE_ERROR, 1, "I/O error");
3568 return -1;
3569}
3570
3571static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val)
3572{
3573 int res = 0;
3574 int min = 0, med;
3575
3576 if ((val >= tab[min].read && val < tab[max].read) ||
3577 (val >= tab[max].read && val < tab[min].read)) {
3578 while ((max - min) > 1) {
3579 med = (max + min) / 2;
3580 if ((val >= tab[min].read && val < tab[med].read) ||
3581 (val >= tab[med].read && val < tab[min].read))
3582 max = med;
3583 else
3584 min = med;
3585 }
3586 res = ((val - tab[min].read) *
3587 (tab[max].real - tab[min].real) /
3588 (tab[max].read - tab[min].read)) +
3589 tab[min].real;
3590 } else {
3591 if (tab[min].read < tab[max].read) {
3592 if (val < tab[min].read)
3593 res = tab[min].real;
3594 else if (val >= tab[max].read)
3595 res = tab[max].real;
3596 } else {
3597 if (val >= tab[min].read)
3598 res = tab[min].real;
3599 else if (val < tab[max].read)
3600 res = tab[max].real;
3601 }
3602 }
3603
3604 return res;
3605}
3606
3607static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
3608{
3609 struct stv090x_state *state = fe->demodulator_priv;
3610 u32 reg;
3611 s32 agc_0, agc_1, agc;
3612 s32 str;
3613
3614 reg = STV090x_READ_DEMOD(state, AGCIQIN1);
3615 agc_1 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
3616 reg = STV090x_READ_DEMOD(state, AGCIQIN0);
3617 agc_0 = STV090x_GETFIELD_Px(reg, AGCIQ_VALUE_FIELD);
3618 agc = MAKEWORD16(agc_1, agc_0);
3619
3620 str = stv090x_table_lookup(stv090x_rf_tab,
3621 ARRAY_SIZE(stv090x_rf_tab) - 1, agc);
3622 if (agc > stv090x_rf_tab[0].read)
3623 str = 0;
3624 else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read)
3625 str = -100;
3626 *strength = (str + 100) * 0xFFFF / 100;
3627
3628 return 0;
3629}
3630
3631static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
3632{
3633 struct stv090x_state *state = fe->demodulator_priv;
3634 u32 reg_0, reg_1, reg, i;
3635 s32 val_0, val_1, val = 0;
3636 u8 lock_f;
3637 s32 div;
3638 u32 last;
3639
3640 switch (state->delsys) {
3641 case STV090x_DVBS2:
3642 reg = STV090x_READ_DEMOD(state, DSTATUS);
3643 lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
3644 if (lock_f) {
3645 msleep(5);
3646 for (i = 0; i < 16; i++) {
3647 reg_1 = STV090x_READ_DEMOD(state, NNOSPLHT1);
3648 val_1 = STV090x_GETFIELD_Px(reg_1, NOSPLHT_NORMED_FIELD);
3649 reg_0 = STV090x_READ_DEMOD(state, NNOSPLHT0);
3650 val_0 = STV090x_GETFIELD_Px(reg_0, NOSPLHT_NORMED_FIELD);
3651 val += MAKEWORD16(val_1, val_0);
3652 msleep(1);
3653 }
3654 val /= 16;
3655 last = ARRAY_SIZE(stv090x_s2cn_tab) - 1;
3656 div = stv090x_s2cn_tab[0].read -
3657 stv090x_s2cn_tab[last].read;
3658 *cnr = 0xFFFF - ((val * 0xFFFF) / div);
3659 }
3660 break;
3661
3662 case STV090x_DVBS1:
3663 case STV090x_DSS:
3664 reg = STV090x_READ_DEMOD(state, DSTATUS);
3665 lock_f = STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD);
3666 if (lock_f) {
3667 msleep(5);
3668 for (i = 0; i < 16; i++) {
3669 reg_1 = STV090x_READ_DEMOD(state, NOSDATAT1);
3670 val_1 = STV090x_GETFIELD_Px(reg_1, NOSDATAT_UNNORMED_FIELD);
3671 reg_0 = STV090x_READ_DEMOD(state, NOSDATAT0);
3672 val_0 = STV090x_GETFIELD_Px(reg_0, NOSDATAT_UNNORMED_FIELD);
3673 val += MAKEWORD16(val_1, val_0);
3674 msleep(1);
3675 }
3676 val /= 16;
3677 last = ARRAY_SIZE(stv090x_s1cn_tab) - 1;
3678 div = stv090x_s1cn_tab[0].read -
3679 stv090x_s1cn_tab[last].read;
3680 *cnr = 0xFFFF - ((val * 0xFFFF) / div);
3681 }
3682 break;
3683 default:
3684 break;
3685 }
3686
3687 return 0;
3688}
3689
3690static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
3691{
3692 struct stv090x_state *state = fe->demodulator_priv;
3693 u32 reg;
3694
3695 reg = STV090x_READ_DEMOD(state, DISTXCTL);
3696 switch (tone) {
3697 case SEC_TONE_ON:
3698 STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0);
3699 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
3700 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3701 goto err;
3702 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
3703 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3704 goto err;
3705 break;
3706
3707 case SEC_TONE_OFF:
3708 STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, 0);
3709 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
3710 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3711 goto err;
3712 break;
3713 default:
3714 return -EINVAL;
3715 }
3716
3717 return 0;
3718err:
3719 dprintk(FE_ERROR, 1, "I/O error");
3720 return -1;
3721}
3722
3723
3724static enum dvbfe_algo stv090x_frontend_algo(struct dvb_frontend *fe)
3725{
3726 return DVBFE_ALGO_CUSTOM;
3727}
3728
3729static int stv090x_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd)
3730{
3731 struct stv090x_state *state = fe->demodulator_priv;
3732 u32 reg, idle = 0, fifo_full = 1;
3733 int i;
3734
3735 reg = STV090x_READ_DEMOD(state, DISTXCTL);
3736
3737 STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD,
3738 (state->config->diseqc_envelope_mode) ? 4 : 2);
3739 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
3740 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3741 goto err;
3742 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
3743 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3744 goto err;
3745
3746 STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1);
3747 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3748 goto err;
3749
3750 for (i = 0; i < cmd->msg_len; i++) {
3751
3752 while (fifo_full) {
3753 reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
3754 fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD);
3755 }
3756
3757 if (STV090x_WRITE_DEMOD(state, DISTXDATA, cmd->msg[i]) < 0)
3758 goto err;
3759 }
3760 reg = STV090x_READ_DEMOD(state, DISTXCTL);
3761 STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0);
3762 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3763 goto err;
3764
3765 i = 0;
3766
3767 while ((!idle) && (i < 10)) {
3768 reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
3769 idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD);
3770 msleep(10);
3771 i++;
3772 }
3773
3774 return 0;
3775err:
3776 dprintk(FE_ERROR, 1, "I/O error");
3777 return -1;
3778}
3779
3780static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
3781{
3782 struct stv090x_state *state = fe->demodulator_priv;
3783 u32 reg, idle = 0, fifo_full = 1;
3784 u8 mode, value;
3785 int i;
3786
3787 reg = STV090x_READ_DEMOD(state, DISTXCTL);
3788
3789 if (burst == SEC_MINI_A) {
3790 mode = (state->config->diseqc_envelope_mode) ? 5 : 3;
3791 value = 0x00;
3792 } else {
3793 mode = (state->config->diseqc_envelope_mode) ? 4 : 2;
3794 value = 0xFF;
3795 }
3796
3797 STV090x_SETFIELD_Px(reg, DISTX_MODE_FIELD, mode);
3798 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 1);
3799 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3800 goto err;
3801 STV090x_SETFIELD_Px(reg, DISEQC_RESET_FIELD, 0);
3802 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3803 goto err;
3804
3805 STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 1);
3806 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3807 goto err;
3808
3809 while (fifo_full) {
3810 reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
3811 fifo_full = STV090x_GETFIELD_Px(reg, FIFO_FULL_FIELD);
3812 }
3813
3814 if (STV090x_WRITE_DEMOD(state, DISTXDATA, value) < 0)
3815 goto err;
3816
3817 reg = STV090x_READ_DEMOD(state, DISTXCTL);
3818 STV090x_SETFIELD_Px(reg, DIS_PRECHARGE_FIELD, 0);
3819 if (STV090x_WRITE_DEMOD(state, DISTXCTL, reg) < 0)
3820 goto err;
3821
3822 i = 0;
3823
3824 while ((!idle) && (i < 10)) {
3825 reg = STV090x_READ_DEMOD(state, DISTXSTATUS);
3826 idle = STV090x_GETFIELD_Px(reg, TX_IDLE_FIELD);
3827 msleep(10);
3828 i++;
3829 }
3830
3831 return 0;
3832err:
3833 dprintk(FE_ERROR, 1, "I/O error");
3834 return -1;
3835}
3836
3837static int stv090x_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply)
3838{
3839 struct stv090x_state *state = fe->demodulator_priv;
3840 u32 reg = 0, i = 0, rx_end = 0;
3841
3842 while ((rx_end != 1) && (i < 10)) {
3843 msleep(10);
3844 i++;
3845 reg = STV090x_READ_DEMOD(state, DISRX_ST0);
3846 rx_end = STV090x_GETFIELD_Px(reg, RX_END_FIELD);
3847 }
3848
3849 if (rx_end) {
3850 reply->msg_len = STV090x_GETFIELD_Px(reg, FIFO_BYTENBR_FIELD);
3851 for (i = 0; i < reply->msg_len; i++)
3852 reply->msg[i] = STV090x_READ_DEMOD(state, DISRXDATA);
3853 }
3854
3855 return 0;
3856}
3857
3858static int stv090x_sleep(struct dvb_frontend *fe)
3859{
3860 struct stv090x_state *state = fe->demodulator_priv;
3861 u32 reg;
3862 u8 full_standby = 0;
3863
3864 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
3865 goto err;
3866
3867 if (state->config->tuner_sleep) {
3868 if (state->config->tuner_sleep(fe) < 0)
3869 goto err_gateoff;
3870 }
3871
3872 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
3873 goto err;
3874
3875 dprintk(FE_DEBUG, 1, "Set %s(%d) to sleep",
3876 state->device == STV0900 ? "STV0900" : "STV0903",
3877 state->demod);
3878
3879 mutex_lock(&state->internal->demod_lock);
3880
3881 switch (state->demod) {
3882 case STV090x_DEMODULATOR_0:
3883 /* power off ADC 1 */
3884 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
3885 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0);
3886 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
3887 goto err;
3888 /* power off DiSEqC 1 */
3889 reg = stv090x_read_reg(state, STV090x_TSTTNR2);
3890 STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0);
3891 if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
3892 goto err;
3893
3894 /* check whether path 2 is already sleeping, that is when
3895 ADC2 is off */
3896 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
3897 if (STV090x_GETFIELD(reg, ADC2_PON_FIELD) == 0)
3898 full_standby = 1;
3899
3900 /* stop clocks */
3901 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
3902 /* packet delineator 1 clock */
3903 STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 1);
3904 /* ADC 1 clock */
3905 STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 1);
3906 /* FEC clock is shared between the two paths, only stop it
3907 when full standby is possible */
3908 if (full_standby)
3909 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
3910 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
3911 goto err;
3912 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
3913 /* sampling 1 clock */
3914 STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1);
3915 /* viterbi 1 clock */
3916 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 1);
3917 /* TS clock is shared between the two paths, only stop it
3918 when full standby is possible */
3919 if (full_standby)
3920 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
3921 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
3922 goto err;
3923 break;
3924
3925 case STV090x_DEMODULATOR_1:
3926 /* power off ADC 2 */
3927 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
3928 STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0);
3929 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
3930 goto err;
3931 /* power off DiSEqC 2 */
3932 reg = stv090x_read_reg(state, STV090x_TSTTNR4);
3933 STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0);
3934 if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
3935 goto err;
3936
3937 /* check whether path 1 is already sleeping, that is when
3938 ADC1 is off */
3939 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
3940 if (STV090x_GETFIELD(reg, ADC1_PON_FIELD) == 0)
3941 full_standby = 1;
3942
3943 /* stop clocks */
3944 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
3945 /* packet delineator 2 clock */
3946 STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 1);
3947 /* ADC 2 clock */
3948 STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 1);
3949 /* FEC clock is shared between the two paths, only stop it
3950 when full standby is possible */
3951 if (full_standby)
3952 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
3953 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
3954 goto err;
3955 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
3956 /* sampling 2 clock */
3957 STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1);
3958 /* viterbi 2 clock */
3959 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 1);
3960 /* TS clock is shared between the two paths, only stop it
3961 when full standby is possible */
3962 if (full_standby)
3963 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
3964 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
3965 goto err;
3966 break;
3967
3968 default:
3969 dprintk(FE_ERROR, 1, "Wrong demodulator!");
3970 break;
3971 }
3972
3973 if (full_standby) {
3974 /* general power off */
3975 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
3976 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
3977 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
3978 goto err;
3979 }
3980
3981 mutex_unlock(&state->internal->demod_lock);
3982 return 0;
3983
3984err_gateoff:
3985 stv090x_i2c_gate_ctrl(state, 0);
3986err:
3987 mutex_unlock(&state->internal->demod_lock);
3988 dprintk(FE_ERROR, 1, "I/O error");
3989 return -1;
3990}
3991
3992static int stv090x_wakeup(struct dvb_frontend *fe)
3993{
3994 struct stv090x_state *state = fe->demodulator_priv;
3995 u32 reg;
3996
3997 dprintk(FE_DEBUG, 1, "Wake %s(%d) from standby",
3998 state->device == STV0900 ? "STV0900" : "STV0903",
3999 state->demod);
4000
4001 mutex_lock(&state->internal->demod_lock);
4002
4003 /* general power on */
4004 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
4005 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00);
4006 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
4007 goto err;
4008
4009 switch (state->demod) {
4010 case STV090x_DEMODULATOR_0:
4011 /* power on ADC 1 */
4012 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
4013 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1);
4014 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
4015 goto err;
4016 /* power on DiSEqC 1 */
4017 reg = stv090x_read_reg(state, STV090x_TSTTNR2);
4018 STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 1);
4019 if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
4020 goto err;
4021
4022 /* activate clocks */
4023 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
4024 /* packet delineator 1 clock */
4025 STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 0);
4026 /* ADC 1 clock */
4027 STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 0);
4028 /* FEC clock */
4029 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0);
4030 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
4031 goto err;
4032 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
4033 /* sampling 1 clock */
4034 STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 0);
4035 /* viterbi 1 clock */
4036 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 0);
4037 /* TS clock */
4038 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0);
4039 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
4040 goto err;
4041 break;
4042
4043 case STV090x_DEMODULATOR_1:
4044 /* power on ADC 2 */
4045 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
4046 STV090x_SETFIELD(reg, ADC2_PON_FIELD, 1);
4047 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
4048 goto err;
4049 /* power on DiSEqC 2 */
4050 reg = stv090x_read_reg(state, STV090x_TSTTNR4);
4051 STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 1);
4052 if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
4053 goto err;
4054
4055 /* activate clocks */
4056 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
4057 /* packet delineator 2 clock */
4058 STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 0);
4059 /* ADC 2 clock */
4060 STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 0);
4061 /* FEC clock */
4062 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0);
4063 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
4064 goto err;
4065 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
4066 /* sampling 2 clock */
4067 STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 0);
4068 /* viterbi 2 clock */
4069 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 0);
4070 /* TS clock */
4071 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0);
4072 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
4073 goto err;
4074 break;
4075
4076 default:
4077 dprintk(FE_ERROR, 1, "Wrong demodulator!");
4078 break;
4079 }
4080
4081 mutex_unlock(&state->internal->demod_lock);
4082 return 0;
4083err:
4084 mutex_unlock(&state->internal->demod_lock);
4085 dprintk(FE_ERROR, 1, "I/O error");
4086 return -1;
4087}
4088
4089static void stv090x_release(struct dvb_frontend *fe)
4090{
4091 struct stv090x_state *state = fe->demodulator_priv;
4092
4093 state->internal->num_used--;
4094 if (state->internal->num_used <= 0) {
4095
4096 dprintk(FE_ERROR, 1, "Actually removing");
4097
4098 remove_dev(state->internal);
4099 kfree(state->internal);
4100 }
4101
4102 kfree(state);
4103}
4104
4105static int stv090x_ldpc_mode(struct stv090x_state *state, enum stv090x_mode ldpc_mode)
4106{
4107 u32 reg = 0;
4108
4109 reg = stv090x_read_reg(state, STV090x_GENCFG);
4110
4111 switch (ldpc_mode) {
4112 case STV090x_DUAL:
4113 default:
4114 if ((state->demod_mode != STV090x_DUAL) || (STV090x_GETFIELD(reg, DDEMOD_FIELD) != 1)) {
4115 /* set LDPC to dual mode */
4116 if (stv090x_write_reg(state, STV090x_GENCFG, 0x1d) < 0)
4117 goto err;
4118
4119 state->demod_mode = STV090x_DUAL;
4120
4121 reg = stv090x_read_reg(state, STV090x_TSTRES0);
4122 STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1);
4123 if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
4124 goto err;
4125 STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0);
4126 if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
4127 goto err;
4128
4129 if (STV090x_WRITE_DEMOD(state, MODCODLST0, 0xff) < 0)
4130 goto err;
4131 if (STV090x_WRITE_DEMOD(state, MODCODLST1, 0xff) < 0)
4132 goto err;
4133 if (STV090x_WRITE_DEMOD(state, MODCODLST2, 0xff) < 0)
4134 goto err;
4135 if (STV090x_WRITE_DEMOD(state, MODCODLST3, 0xff) < 0)
4136 goto err;
4137 if (STV090x_WRITE_DEMOD(state, MODCODLST4, 0xff) < 0)
4138 goto err;
4139 if (STV090x_WRITE_DEMOD(state, MODCODLST5, 0xff) < 0)
4140 goto err;
4141 if (STV090x_WRITE_DEMOD(state, MODCODLST6, 0xff) < 0)
4142 goto err;
4143
4144 if (STV090x_WRITE_DEMOD(state, MODCODLST7, 0xcc) < 0)
4145 goto err;
4146 if (STV090x_WRITE_DEMOD(state, MODCODLST8, 0xcc) < 0)
4147 goto err;
4148 if (STV090x_WRITE_DEMOD(state, MODCODLST9, 0xcc) < 0)
4149 goto err;
4150 if (STV090x_WRITE_DEMOD(state, MODCODLSTA, 0xcc) < 0)
4151 goto err;
4152 if (STV090x_WRITE_DEMOD(state, MODCODLSTB, 0xcc) < 0)
4153 goto err;
4154 if (STV090x_WRITE_DEMOD(state, MODCODLSTC, 0xcc) < 0)
4155 goto err;
4156 if (STV090x_WRITE_DEMOD(state, MODCODLSTD, 0xcc) < 0)
4157 goto err;
4158
4159 if (STV090x_WRITE_DEMOD(state, MODCODLSTE, 0xff) < 0)
4160 goto err;
4161 if (STV090x_WRITE_DEMOD(state, MODCODLSTF, 0xcf) < 0)
4162 goto err;
4163 }
4164 break;
4165
4166 case STV090x_SINGLE:
4167 if (stv090x_stop_modcod(state) < 0)
4168 goto err;
4169 if (stv090x_activate_modcod_single(state) < 0)
4170 goto err;
4171
4172 if (state->demod == STV090x_DEMODULATOR_1) {
4173 if (stv090x_write_reg(state, STV090x_GENCFG, 0x06) < 0) /* path 2 */
4174 goto err;
4175 } else {
4176 if (stv090x_write_reg(state, STV090x_GENCFG, 0x04) < 0) /* path 1 */
4177 goto err;
4178 }
4179
4180 reg = stv090x_read_reg(state, STV090x_TSTRES0);
4181 STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x1);
4182 if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
4183 goto err;
4184 STV090x_SETFIELD(reg, FRESFEC_FIELD, 0x0);
4185 if (stv090x_write_reg(state, STV090x_TSTRES0, reg) < 0)
4186 goto err;
4187
4188 reg = STV090x_READ_DEMOD(state, PDELCTRL1);
4189 STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x01);
4190 if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
4191 goto err;
4192 STV090x_SETFIELD_Px(reg, ALGOSWRST_FIELD, 0x00);
4193 if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
4194 goto err;
4195 break;
4196 }
4197
4198 return 0;
4199err:
4200 dprintk(FE_ERROR, 1, "I/O error");
4201 return -1;
4202}
4203
4204/* return (Hz), clk in Hz*/
4205static u32 stv090x_get_mclk(struct stv090x_state *state)
4206{
4207 const struct stv090x_config *config = state->config;
4208 u32 div, reg;
4209 u8 ratio;
4210
4211 div = stv090x_read_reg(state, STV090x_NCOARSE);
4212 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
4213 ratio = STV090x_GETFIELD(reg, SELX1RATIO_FIELD) ? 4 : 6;
4214
4215 return (div + 1) * config->xtal / ratio; /* kHz */
4216}
4217
4218static int stv090x_set_mclk(struct stv090x_state *state, u32 mclk, u32 clk)
4219{
4220 const struct stv090x_config *config = state->config;
4221 u32 reg, div, clk_sel;
4222
4223 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
4224 clk_sel = ((STV090x_GETFIELD(reg, SELX1RATIO_FIELD) == 1) ? 4 : 6);
4225
4226 div = ((clk_sel * mclk) / config->xtal) - 1;
4227
4228 reg = stv090x_read_reg(state, STV090x_NCOARSE);
4229 STV090x_SETFIELD(reg, M_DIV_FIELD, div);
4230 if (stv090x_write_reg(state, STV090x_NCOARSE, reg) < 0)
4231 goto err;
4232
4233 state->internal->mclk = stv090x_get_mclk(state);
4234
4235 /*Set the DiseqC frequency to 22KHz */
4236 div = state->internal->mclk / 704000;
4237 if (STV090x_WRITE_DEMOD(state, F22TX, div) < 0)
4238 goto err;
4239 if (STV090x_WRITE_DEMOD(state, F22RX, div) < 0)
4240 goto err;
4241
4242 return 0;
4243err:
4244 dprintk(FE_ERROR, 1, "I/O error");
4245 return -1;
4246}
4247
4248static int stv090x_set_tspath(struct stv090x_state *state)
4249{
4250 u32 reg;
4251
4252 if (state->internal->dev_ver >= 0x20) {
4253 switch (state->config->ts1_mode) {
4254 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4255 case STV090x_TSMODE_DVBCI:
4256 switch (state->config->ts2_mode) {
4257 case STV090x_TSMODE_SERIAL_PUNCTURED:
4258 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4259 default:
4260 stv090x_write_reg(state, STV090x_TSGENERAL, 0x00);
4261 break;
4262
4263 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4264 case STV090x_TSMODE_DVBCI:
4265 if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x06) < 0) /* Mux'd stream mode */
4266 goto err;
4267 reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
4268 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
4269 if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
4270 goto err;
4271 reg = stv090x_read_reg(state, STV090x_P2_TSCFGM);
4272 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
4273 if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0)
4274 goto err;
4275 if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0)
4276 goto err;
4277 if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0)
4278 goto err;
4279 break;
4280 }
4281 break;
4282
4283 case STV090x_TSMODE_SERIAL_PUNCTURED:
4284 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4285 default:
4286 switch (state->config->ts2_mode) {
4287 case STV090x_TSMODE_SERIAL_PUNCTURED:
4288 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4289 default:
4290 if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)
4291 goto err;
4292 break;
4293
4294 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4295 case STV090x_TSMODE_DVBCI:
4296 if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0a) < 0)
4297 goto err;
4298 break;
4299 }
4300 break;
4301 }
4302 } else {
4303 switch (state->config->ts1_mode) {
4304 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4305 case STV090x_TSMODE_DVBCI:
4306 switch (state->config->ts2_mode) {
4307 case STV090x_TSMODE_SERIAL_PUNCTURED:
4308 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4309 default:
4310 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10);
4311 break;
4312
4313 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4314 case STV090x_TSMODE_DVBCI:
4315 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x16);
4316 reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
4317 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
4318 if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
4319 goto err;
4320 reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
4321 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 0);
4322 if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
4323 goto err;
4324 if (stv090x_write_reg(state, STV090x_P1_TSSPEED, 0x14) < 0)
4325 goto err;
4326 if (stv090x_write_reg(state, STV090x_P2_TSSPEED, 0x28) < 0)
4327 goto err;
4328 break;
4329 }
4330 break;
4331
4332 case STV090x_TSMODE_SERIAL_PUNCTURED:
4333 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4334 default:
4335 switch (state->config->ts2_mode) {
4336 case STV090x_TSMODE_SERIAL_PUNCTURED:
4337 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4338 default:
4339 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14);
4340 break;
4341
4342 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4343 case STV090x_TSMODE_DVBCI:
4344 stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x12);
4345 break;
4346 }
4347 break;
4348 }
4349 }
4350
4351 switch (state->config->ts1_mode) {
4352 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4353 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
4354 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
4355 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
4356 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
4357 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
4358 goto err;
4359 break;
4360
4361 case STV090x_TSMODE_DVBCI:
4362 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
4363 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
4364 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
4365 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4366 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
4367 goto err;
4368 break;
4369
4370 case STV090x_TSMODE_SERIAL_PUNCTURED:
4371 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
4372 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
4373 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4374 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
4375 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
4376 goto err;
4377 break;
4378
4379 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4380 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
4381 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
4382 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4383 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4384 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
4385 goto err;
4386 break;
4387
4388 default:
4389 break;
4390 }
4391
4392 switch (state->config->ts2_mode) {
4393 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4394 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4395 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
4396 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
4397 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
4398 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
4399 goto err;
4400 break;
4401
4402 case STV090x_TSMODE_DVBCI:
4403 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4404 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
4405 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
4406 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4407 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
4408 goto err;
4409 break;
4410
4411 case STV090x_TSMODE_SERIAL_PUNCTURED:
4412 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4413 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
4414 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4415 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
4416 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
4417 goto err;
4418 break;
4419
4420 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4421 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4422 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
4423 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4424 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4425 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
4426 goto err;
4427 break;
4428
4429 default:
4430 break;
4431 }
4432
4433 if (state->config->ts1_clk > 0) {
4434 u32 speed;
4435
4436 switch (state->config->ts1_mode) {
4437 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4438 case STV090x_TSMODE_DVBCI:
4439 default:
4440 speed = state->internal->mclk /
4441 (state->config->ts1_clk / 4);
4442 if (speed < 0x08)
4443 speed = 0x08;
4444 if (speed > 0xFF)
4445 speed = 0xFF;
4446 break;
4447 case STV090x_TSMODE_SERIAL_PUNCTURED:
4448 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4449 speed = state->internal->mclk /
4450 (state->config->ts1_clk / 32);
4451 if (speed < 0x20)
4452 speed = 0x20;
4453 if (speed > 0xFF)
4454 speed = 0xFF;
4455 break;
4456 }
4457 reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
4458 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
4459 if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
4460 goto err;
4461 if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0)
4462 goto err;
4463 }
4464
4465 if (state->config->ts2_clk > 0) {
4466 u32 speed;
4467
4468 switch (state->config->ts2_mode) {
4469 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4470 case STV090x_TSMODE_DVBCI:
4471 default:
4472 speed = state->internal->mclk /
4473 (state->config->ts2_clk / 4);
4474 if (speed < 0x08)
4475 speed = 0x08;
4476 if (speed > 0xFF)
4477 speed = 0xFF;
4478 break;
4479 case STV090x_TSMODE_SERIAL_PUNCTURED:
4480 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4481 speed = state->internal->mclk /
4482 (state->config->ts2_clk / 32);
4483 if (speed < 0x20)
4484 speed = 0x20;
4485 if (speed > 0xFF)
4486 speed = 0xFF;
4487 break;
4488 }
4489 reg = stv090x_read_reg(state, STV090x_P2_TSCFGM);
4490 STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
4491 if (stv090x_write_reg(state, STV090x_P2_TSCFGM, reg) < 0)
4492 goto err;
4493 if (stv090x_write_reg(state, STV090x_P2_TSSPEED, speed) < 0)
4494 goto err;
4495 }
4496
4497 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4498 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
4499 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
4500 goto err;
4501 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);
4502 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
4503 goto err;
4504
4505 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
4506 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
4507 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
4508 goto err;
4509 STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);
4510 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
4511 goto err;
4512
4513 return 0;
4514err:
4515 dprintk(FE_ERROR, 1, "I/O error");
4516 return -1;
4517}
4518
4519static int stv090x_init(struct dvb_frontend *fe)
4520{
4521 struct stv090x_state *state = fe->demodulator_priv;
4522 const struct stv090x_config *config = state->config;
4523 u32 reg;
4524
4525 if (state->internal->mclk == 0) {
4526 /* call tuner init to configure the tuner's clock output
4527 divider directly before setting up the master clock of
4528 the stv090x. */
4529 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
4530 goto err;
4531
4532 if (config->tuner_init) {
4533 if (config->tuner_init(fe) < 0)
4534 goto err_gateoff;
4535 }
4536
4537 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
4538 goto err;
4539
4540 stv090x_set_mclk(state, 135000000, config->xtal); /* 135 Mhz */
4541 msleep(5);
4542 if (stv090x_write_reg(state, STV090x_SYNTCTRL,
4543 0x20 | config->clk_mode) < 0)
4544 goto err;
4545 stv090x_get_mclk(state);
4546 }
4547
4548 if (stv090x_wakeup(fe) < 0) {
4549 dprintk(FE_ERROR, 1, "Error waking device");
4550 goto err;
4551 }
4552
4553 if (stv090x_ldpc_mode(state, state->demod_mode) < 0)
4554 goto err;
4555
4556 reg = STV090x_READ_DEMOD(state, TNRCFG2);
4557 STV090x_SETFIELD_Px(reg, TUN_IQSWAP_FIELD, state->inversion);
4558 if (STV090x_WRITE_DEMOD(state, TNRCFG2, reg) < 0)
4559 goto err;
4560 reg = STV090x_READ_DEMOD(state, DEMOD);
4561 STV090x_SETFIELD_Px(reg, ROLLOFF_CONTROL_FIELD, state->rolloff);
4562 if (STV090x_WRITE_DEMOD(state, DEMOD, reg) < 0)
4563 goto err;
4564
4565 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
4566 goto err;
4567
4568 if (config->tuner_set_mode) {
4569 if (config->tuner_set_mode(fe, TUNER_WAKE) < 0)
4570 goto err_gateoff;
4571 }
4572
4573 if (config->tuner_init) {
4574 if (config->tuner_init(fe) < 0)
4575 goto err_gateoff;
4576 }
4577
4578 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
4579 goto err;
4580
4581 if (stv090x_set_tspath(state) < 0)
4582 goto err;
4583
4584 return 0;
4585
4586err_gateoff:
4587 stv090x_i2c_gate_ctrl(state, 0);
4588err:
4589 dprintk(FE_ERROR, 1, "I/O error");
4590 return -1;
4591}
4592
4593static int stv090x_setup(struct dvb_frontend *fe)
4594{
4595 struct stv090x_state *state = fe->demodulator_priv;
4596 const struct stv090x_config *config = state->config;
4597 const struct stv090x_reg *stv090x_initval = NULL;
4598 const struct stv090x_reg *stv090x_cut20_val = NULL;
4599 unsigned long t1_size = 0, t2_size = 0;
4600 u32 reg = 0;
4601
4602 int i;
4603
4604 if (state->device == STV0900) {
4605 dprintk(FE_DEBUG, 1, "Initializing STV0900");
4606 stv090x_initval = stv0900_initval;
4607 t1_size = ARRAY_SIZE(stv0900_initval);
4608 stv090x_cut20_val = stv0900_cut20_val;
4609 t2_size = ARRAY_SIZE(stv0900_cut20_val);
4610 } else if (state->device == STV0903) {
4611 dprintk(FE_DEBUG, 1, "Initializing STV0903");
4612 stv090x_initval = stv0903_initval;
4613 t1_size = ARRAY_SIZE(stv0903_initval);
4614 stv090x_cut20_val = stv0903_cut20_val;
4615 t2_size = ARRAY_SIZE(stv0903_cut20_val);
4616 }
4617
4618 /* STV090x init */
4619
4620 /* Stop Demod */
4621 if (stv090x_write_reg(state, STV090x_P1_DMDISTATE, 0x5c) < 0)
4622 goto err;
4623 if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0)
4624 goto err;
4625
4626 msleep(5);
4627
4628 /* Set No Tuner Mode */
4629 if (stv090x_write_reg(state, STV090x_P1_TNRCFG, 0x6c) < 0)
4630 goto err;
4631 if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0)
4632 goto err;
4633
4634 /* I2C repeater OFF */
4635 STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level);
4636 if (stv090x_write_reg(state, STV090x_P1_I2CRPT, reg) < 0)
4637 goto err;
4638 if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0)
4639 goto err;
4640
4641 if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */
4642 goto err;
4643 msleep(5);
4644 if (stv090x_write_reg(state, STV090x_I2CCFG, 0x08) < 0) /* 1/41 oversampling */
4645 goto err;
4646 if (stv090x_write_reg(state, STV090x_SYNTCTRL, 0x20 | config->clk_mode) < 0) /* enable PLL */
4647 goto err;
4648 msleep(5);
4649
4650 /* write initval */
4651 dprintk(FE_DEBUG, 1, "Setting up initial values");
4652 for (i = 0; i < t1_size; i++) {
4653 if (stv090x_write_reg(state, stv090x_initval[i].addr, stv090x_initval[i].data) < 0)
4654 goto err;
4655 }
4656
4657 state->internal->dev_ver = stv090x_read_reg(state, STV090x_MID);
4658 if (state->internal->dev_ver >= 0x20) {
4659 if (stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c) < 0)
4660 goto err;
4661
4662 /* write cut20_val*/
4663 dprintk(FE_DEBUG, 1, "Setting up Cut 2.0 initial values");
4664 for (i = 0; i < t2_size; i++) {
4665 if (stv090x_write_reg(state, stv090x_cut20_val[i].addr, stv090x_cut20_val[i].data) < 0)
4666 goto err;
4667 }
4668
4669 } else if (state->internal->dev_ver < 0x20) {
4670 dprintk(FE_ERROR, 1, "ERROR: Unsupported Cut: 0x%02x!",
4671 state->internal->dev_ver);
4672
4673 goto err;
4674 } else if (state->internal->dev_ver > 0x30) {
4675 /* we shouldn't bail out from here */
4676 dprintk(FE_ERROR, 1, "INFO: Cut: 0x%02x probably incomplete support!",
4677 state->internal->dev_ver);
4678 }
4679
4680 /* ADC1 range */
4681 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
4682 STV090x_SETFIELD(reg, ADC1_INMODE_FIELD,
4683 (config->adc1_range == STV090x_ADC_1Vpp) ? 0 : 1);
4684 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
4685 goto err;
4686
4687 /* ADC2 range */
4688 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
4689 STV090x_SETFIELD(reg, ADC2_INMODE_FIELD,
4690 (config->adc2_range == STV090x_ADC_1Vpp) ? 0 : 1);
4691 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
4692 goto err;
4693
4694 if (stv090x_write_reg(state, STV090x_TSTRES0, 0x80) < 0)
4695 goto err;
4696 if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)
4697 goto err;
4698
4699 return 0;
4700err:
4701 dprintk(FE_ERROR, 1, "I/O error");
4702 return -1;
4703}
4704
4705int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
4706 u8 xor_value)
4707{
4708 struct stv090x_state *state = fe->demodulator_priv;
4709 u8 reg = 0;
4710
4711 STV090x_SETFIELD(reg, GPIOx_OPD_FIELD, dir);
4712 STV090x_SETFIELD(reg, GPIOx_CONFIG_FIELD, value);
4713 STV090x_SETFIELD(reg, GPIOx_XOR_FIELD, xor_value);
4714
4715 return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg);
4716}
4717EXPORT_SYMBOL(stv090x_set_gpio);
4718
4719static struct dvb_frontend_ops stv090x_ops = {
4720
4721 .info = {
4722 .name = "STV090x Multistandard",
4723 .type = FE_QPSK,
4724 .frequency_min = 950000,
4725 .frequency_max = 2150000,
4726 .frequency_stepsize = 0,
4727 .frequency_tolerance = 0,
4728 .symbol_rate_min = 1000000,
4729 .symbol_rate_max = 45000000,
4730 .caps = FE_CAN_INVERSION_AUTO |
4731 FE_CAN_FEC_AUTO |
4732 FE_CAN_QPSK |
4733 FE_CAN_2G_MODULATION
4734 },
4735
4736 .release = stv090x_release,
4737 .init = stv090x_init,
4738
4739 .sleep = stv090x_sleep,
4740 .get_frontend_algo = stv090x_frontend_algo,
4741
4742 .diseqc_send_master_cmd = stv090x_send_diseqc_msg,
4743 .diseqc_send_burst = stv090x_send_diseqc_burst,
4744 .diseqc_recv_slave_reply = stv090x_recv_slave_reply,
4745 .set_tone = stv090x_set_tone,
4746
4747 .search = stv090x_search,
4748 .read_status = stv090x_read_status,
4749 .read_ber = stv090x_read_per,
4750 .read_signal_strength = stv090x_read_signal_strength,
4751 .read_snr = stv090x_read_cnr
4752};
4753
4754
4755struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
4756 struct i2c_adapter *i2c,
4757 enum stv090x_demodulator demod)
4758{
4759 struct stv090x_state *state = NULL;
4760 struct stv090x_dev *temp_int;
4761
4762 state = kzalloc(sizeof (struct stv090x_state), GFP_KERNEL);
4763 if (state == NULL)
4764 goto error;
4765
4766 state->verbose = &verbose;
4767 state->config = config;
4768 state->i2c = i2c;
4769 state->frontend.ops = stv090x_ops;
4770 state->frontend.demodulator_priv = state;
4771 state->demod = demod;
4772 state->demod_mode = config->demod_mode; /* Single or Dual mode */
4773 state->device = config->device;
4774 state->rolloff = STV090x_RO_35; /* default */
4775
4776 temp_int = find_dev(state->i2c,
4777 state->config->address);
4778
4779 if ((temp_int != NULL) && (state->demod_mode == STV090x_DUAL)) {
4780 state->internal = temp_int->internal;
4781 state->internal->num_used++;
4782 dprintk(FE_INFO, 1, "Found Internal Structure!");
4783 } else {
4784 state->internal = kmalloc(sizeof(struct stv090x_internal),
4785 GFP_KERNEL);
4786 if (!state->internal)
4787 goto error;
4788 temp_int = append_internal(state->internal);
4789 if (!temp_int) {
4790 kfree(state->internal);
4791 goto error;
4792 }
4793 state->internal->num_used = 1;
4794 state->internal->mclk = 0;
4795 state->internal->dev_ver = 0;
4796 state->internal->i2c_adap = state->i2c;
4797 state->internal->i2c_addr = state->config->address;
4798 dprintk(FE_INFO, 1, "Create New Internal Structure!");
4799
4800 mutex_init(&state->internal->demod_lock);
4801 mutex_init(&state->internal->tuner_lock);
4802
4803 if (stv090x_setup(&state->frontend) < 0) {
4804 dprintk(FE_ERROR, 1, "Error setting up device");
4805 goto err_remove;
4806 }
4807 }
4808
4809 /* workaround for stuck DiSEqC output */
4810 if (config->diseqc_envelope_mode)
4811 stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A);
4812
4813 dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
4814 state->device == STV0900 ? "STV0900" : "STV0903",
4815 demod,
4816 state->internal->dev_ver);
4817
4818 return &state->frontend;
4819
4820err_remove:
4821 remove_dev(state->internal);
4822 kfree(state->internal);
4823error:
4824 kfree(state);
4825 return NULL;
4826}
4827EXPORT_SYMBOL(stv090x_attach);
4828MODULE_PARM_DESC(verbose, "Set Verbosity level");
4829MODULE_AUTHOR("Manu Abraham");
4830MODULE_DESCRIPTION("STV090x Multi-Std Broadcast frontend");
4831MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h
new file mode 100644
index 00000000000..29cdc2b7131
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv090x.h
@@ -0,0 +1,134 @@
1/*
2 STV0900/0903 Multistandard Broadcast Frontend driver
3 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
4
5 Copyright (C) ST Microelectronics
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#ifndef __STV090x_H
23#define __STV090x_H
24
25enum stv090x_demodulator {
26 STV090x_DEMODULATOR_0 = 1,
27 STV090x_DEMODULATOR_1
28};
29
30enum stv090x_device {
31 STV0903 = 0,
32 STV0900,
33};
34
35enum stv090x_mode {
36 STV090x_DUAL = 0,
37 STV090x_SINGLE
38};
39
40enum stv090x_tsmode {
41 STV090x_TSMODE_SERIAL_PUNCTURED = 1,
42 STV090x_TSMODE_SERIAL_CONTINUOUS,
43 STV090x_TSMODE_PARALLEL_PUNCTURED,
44 STV090x_TSMODE_DVBCI
45};
46
47enum stv090x_clkmode {
48 STV090x_CLK_INT = 0, /* Clk i/p = CLKI */
49 STV090x_CLK_EXT = 2 /* Clk i/p = XTALI */
50};
51
52enum stv090x_i2crpt {
53 STV090x_RPTLEVEL_256 = 0,
54 STV090x_RPTLEVEL_128 = 1,
55 STV090x_RPTLEVEL_64 = 2,
56 STV090x_RPTLEVEL_32 = 3,
57 STV090x_RPTLEVEL_16 = 4,
58 STV090x_RPTLEVEL_8 = 5,
59 STV090x_RPTLEVEL_4 = 6,
60 STV090x_RPTLEVEL_2 = 7,
61};
62
63enum stv090x_adc_range {
64 STV090x_ADC_2Vpp = 0,
65 STV090x_ADC_1Vpp = 1
66};
67
68struct stv090x_config {
69 enum stv090x_device device;
70 enum stv090x_mode demod_mode;
71 enum stv090x_clkmode clk_mode;
72
73 u32 xtal; /* default: 8000000 */
74 u8 address; /* default: 0x68 */
75
76 u8 ts1_mode;
77 u8 ts2_mode;
78 u32 ts1_clk;
79 u32 ts2_clk;
80
81 u8 ts1_tei : 1;
82 u8 ts2_tei : 1;
83
84 enum stv090x_i2crpt repeater_level;
85
86 u8 tuner_bbgain; /* default: 10db */
87 enum stv090x_adc_range adc1_range; /* default: 2Vpp */
88 enum stv090x_adc_range adc2_range; /* default: 2Vpp */
89
90 bool diseqc_envelope_mode;
91
92 int (*tuner_init) (struct dvb_frontend *fe);
93 int (*tuner_sleep) (struct dvb_frontend *fe);
94 int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
95 int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
96 int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
97 int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth);
98 int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth);
99 int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain);
100 int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain);
101 int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk);
102 int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
103 void (*tuner_i2c_lock) (struct dvb_frontend *fe, int lock);
104};
105
106#if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE))
107
108extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
109 struct i2c_adapter *i2c,
110 enum stv090x_demodulator demod);
111
112/* dir = 0 -> output, dir = 1 -> input/open-drain */
113extern int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
114 u8 dir, u8 value, u8 xor_value);
115
116#else
117
118static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
119 struct i2c_adapter *i2c,
120 enum stv090x_demodulator demod)
121{
122 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
123 return NULL;
124}
125
126static inline int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
127 u8 opd, u8 value, u8 xor_value)
128{
129 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
130 return -ENODEV;
131}
132#endif /* CONFIG_DVB_STV090x */
133
134#endif /* __STV090x_H */
diff --git a/drivers/media/dvb/frontends/stv090x_priv.h b/drivers/media/dvb/frontends/stv090x_priv.h
new file mode 100644
index 00000000000..5b780c80d49
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv090x_priv.h
@@ -0,0 +1,279 @@
1/*
2 STV0900/0903 Multistandard Broadcast Frontend driver
3 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
4
5 Copyright (C) ST Microelectronics
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#ifndef __STV090x_PRIV_H
23#define __STV090x_PRIV_H
24
25#include "dvb_frontend.h"
26
27#define FE_ERROR 0
28#define FE_NOTICE 1
29#define FE_INFO 2
30#define FE_DEBUG 3
31#define FE_DEBUGREG 4
32
33#define dprintk(__y, __z, format, arg...) do { \
34 if (__z) { \
35 if ((verbose > FE_ERROR) && (verbose > __y)) \
36 printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
37 else if ((verbose > FE_NOTICE) && (verbose > __y)) \
38 printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
39 else if ((verbose > FE_INFO) && (verbose > __y)) \
40 printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
41 else if ((verbose > FE_DEBUG) && (verbose > __y)) \
42 printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
43 } else { \
44 if (verbose > __y) \
45 printk(format, ##arg); \
46 } \
47} while (0)
48
49#define STV090x_READ_DEMOD(__state, __reg) (( \
50 (__state)->demod == STV090x_DEMODULATOR_1) ? \
51 stv090x_read_reg(__state, STV090x_P2_##__reg) : \
52 stv090x_read_reg(__state, STV090x_P1_##__reg))
53
54#define STV090x_WRITE_DEMOD(__state, __reg, __data) (( \
55 (__state)->demod == STV090x_DEMODULATOR_1) ? \
56 stv090x_write_reg(__state, STV090x_P2_##__reg, __data) :\
57 stv090x_write_reg(__state, STV090x_P1_##__reg, __data))
58
59#define STV090x_ADDR_OFFST(__state, __x) (( \
60 (__state->demod) == STV090x_DEMODULATOR_1) ? \
61 STV090x_P1_##__x : \
62 STV090x_P2_##__x)
63
64
65#define STV090x_SETFIELD(mask, bitf, val) (mask = (mask & (~(((1 << STV090x_WIDTH_##bitf) - 1) <<\
66 STV090x_OFFST_##bitf))) | \
67 (val << STV090x_OFFST_##bitf))
68
69#define STV090x_GETFIELD(val, bitf) ((val >> STV090x_OFFST_##bitf) & ((1 << STV090x_WIDTH_##bitf) - 1))
70
71
72#define STV090x_SETFIELD_Px(mask, bitf, val) (mask = (mask & (~(((1 << STV090x_WIDTH_Px_##bitf) - 1) <<\
73 STV090x_OFFST_Px_##bitf))) | \
74 (val << STV090x_OFFST_Px_##bitf))
75
76#define STV090x_GETFIELD_Px(val, bitf) ((val >> STV090x_OFFST_Px_##bitf) & ((1 << STV090x_WIDTH_Px_##bitf) - 1))
77
78#define MAKEWORD16(__a, __b) (((__a) << 8) | (__b))
79
80#define MSB(__x) ((__x >> 8) & 0xff)
81#define LSB(__x) (__x & 0xff)
82
83
84#define STV090x_IQPOWER_THRESHOLD 30
85#define STV090x_SEARCH_AGC2_TH_CUT20 700
86#define STV090x_SEARCH_AGC2_TH_CUT30 1400
87
88#define STV090x_SEARCH_AGC2_TH(__ver) \
89 ((__ver <= 0x20) ? \
90 STV090x_SEARCH_AGC2_TH_CUT20 : \
91 STV090x_SEARCH_AGC2_TH_CUT30)
92
93enum stv090x_signal_state {
94 STV090x_NOAGC1,
95 STV090x_NOCARRIER,
96 STV090x_NODATA,
97 STV090x_DATAOK,
98 STV090x_RANGEOK,
99 STV090x_OUTOFRANGE
100};
101
102enum stv090x_fec {
103 STV090x_PR12 = 0,
104 STV090x_PR23,
105 STV090x_PR34,
106 STV090x_PR45,
107 STV090x_PR56,
108 STV090x_PR67,
109 STV090x_PR78,
110 STV090x_PR89,
111 STV090x_PR910,
112 STV090x_PRERR
113};
114
115enum stv090x_modulation {
116 STV090x_QPSK,
117 STV090x_8PSK,
118 STV090x_16APSK,
119 STV090x_32APSK,
120 STV090x_UNKNOWN
121};
122
123enum stv090x_frame {
124 STV090x_LONG_FRAME,
125 STV090x_SHORT_FRAME
126};
127
128enum stv090x_pilot {
129 STV090x_PILOTS_OFF,
130 STV090x_PILOTS_ON
131};
132
133enum stv090x_rolloff {
134 STV090x_RO_35,
135 STV090x_RO_25,
136 STV090x_RO_20
137};
138
139enum stv090x_inversion {
140 STV090x_IQ_AUTO,
141 STV090x_IQ_NORMAL,
142 STV090x_IQ_SWAP
143};
144
145enum stv090x_modcod {
146 STV090x_DUMMY_PLF = 0,
147 STV090x_QPSK_14,
148 STV090x_QPSK_13,
149 STV090x_QPSK_25,
150 STV090x_QPSK_12,
151 STV090x_QPSK_35,
152 STV090x_QPSK_23,
153 STV090x_QPSK_34,
154 STV090x_QPSK_45,
155 STV090x_QPSK_56,
156 STV090x_QPSK_89,
157 STV090x_QPSK_910,
158 STV090x_8PSK_35,
159 STV090x_8PSK_23,
160 STV090x_8PSK_34,
161 STV090x_8PSK_56,
162 STV090x_8PSK_89,
163 STV090x_8PSK_910,
164 STV090x_16APSK_23,
165 STV090x_16APSK_34,
166 STV090x_16APSK_45,
167 STV090x_16APSK_56,
168 STV090x_16APSK_89,
169 STV090x_16APSK_910,
170 STV090x_32APSK_34,
171 STV090x_32APSK_45,
172 STV090x_32APSK_56,
173 STV090x_32APSK_89,
174 STV090x_32APSK_910,
175 STV090x_MODCODE_UNKNOWN
176};
177
178enum stv090x_search {
179 STV090x_SEARCH_DSS = 0,
180 STV090x_SEARCH_DVBS1,
181 STV090x_SEARCH_DVBS2,
182 STV090x_SEARCH_AUTO
183};
184
185enum stv090x_algo {
186 STV090x_BLIND_SEARCH,
187 STV090x_COLD_SEARCH,
188 STV090x_WARM_SEARCH
189};
190
191enum stv090x_delsys {
192 STV090x_ERROR = 0,
193 STV090x_DVBS1 = 1,
194 STV090x_DVBS2,
195 STV090x_DSS
196};
197
198struct stv090x_long_frame_crloop {
199 enum stv090x_modcod modcod;
200
201 u8 crl_pilots_on_2;
202 u8 crl_pilots_off_2;
203 u8 crl_pilots_on_5;
204 u8 crl_pilots_off_5;
205 u8 crl_pilots_on_10;
206 u8 crl_pilots_off_10;
207 u8 crl_pilots_on_20;
208 u8 crl_pilots_off_20;
209 u8 crl_pilots_on_30;
210 u8 crl_pilots_off_30;
211};
212
213struct stv090x_short_frame_crloop {
214 enum stv090x_modulation modulation;
215
216 u8 crl_2; /* SR < 3M */
217 u8 crl_5; /* 3 < SR <= 7M */
218 u8 crl_10; /* 7 < SR <= 15M */
219 u8 crl_20; /* 10 < SR <= 25M */
220 u8 crl_30; /* 10 < SR <= 45M */
221};
222
223struct stv090x_reg {
224 u16 addr;
225 u8 data;
226};
227
228struct stv090x_tab {
229 s32 real;
230 s32 read;
231};
232
233struct stv090x_internal {
234 struct i2c_adapter *i2c_adap;
235 u8 i2c_addr;
236
237 struct mutex demod_lock; /* Lock access to shared register */
238 struct mutex tuner_lock; /* Lock access to tuners */
239 s32 mclk; /* Masterclock Divider factor */
240 u32 dev_ver;
241
242 int num_used;
243};
244
245struct stv090x_state {
246 enum stv090x_device device;
247 enum stv090x_demodulator demod;
248 enum stv090x_mode demod_mode;
249 struct stv090x_internal *internal;
250
251 struct i2c_adapter *i2c;
252 const struct stv090x_config *config;
253 struct dvb_frontend frontend;
254
255 u32 *verbose; /* Cached module verbosity */
256
257 enum stv090x_delsys delsys;
258 enum stv090x_fec fec;
259 enum stv090x_modulation modulation;
260 enum stv090x_modcod modcod;
261 enum stv090x_search search_mode;
262 enum stv090x_frame frame_len;
263 enum stv090x_pilot pilots;
264 enum stv090x_rolloff rolloff;
265 enum stv090x_inversion inversion;
266 enum stv090x_algo algo;
267
268 u32 frequency;
269 u32 srate;
270
271 s32 tuner_bw;
272
273 s32 search_range;
274
275 s32 DemodTimeout;
276 s32 FecTimeout;
277};
278
279#endif /* __STV090x_PRIV_H */
diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb/frontends/stv090x_reg.h
new file mode 100644
index 00000000000..93741ee1429
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv090x_reg.h
@@ -0,0 +1,2371 @@
1/*
2 STV0900/0903 Multistandard Broadcast Frontend driver
3 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
4
5 Copyright (C) ST Microelectronics
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#ifndef __STV090x_REG_H
23#define __STV090x_REG_H
24
25#define STV090x_MID 0xf100
26#define STV090x_OFFST_MCHIP_IDENT_FIELD 4
27#define STV090x_WIDTH_MCHIP_IDENT_FIELD 4
28#define STV090x_OFFST_MRELEASE_FIELD 0
29#define STV090x_WIDTH_MRELEASE_FIELD 4
30
31#define STV090x_DACR1 0xf113
32#define STV090x_OFFST_DACR1_MODE_FIELD 5
33#define STV090x_WIDTH_DACR1_MODE_FIELD 3
34#define STV090x_OFFST_DACR1_VALUE_FIELD 0
35#define STV090x_WIDTH_DACR1_VALUE_FIELD 4
36
37#define STV090x_DACR2 0xf114
38#define STV090x_OFFST_DACR2_VALUE_FIELD 0
39#define STV090x_WIDTH_DACR2_VALUE_FIELD 8
40
41#define STV090x_OUTCFG 0xf11c
42#define STV090x_OFFST_OUTSERRS1_HZ_FIELD 6
43#define STV090x_WIDTH_OUTSERRS1_HZ_FIELD 1
44#define STV090x_OFFST_OUTSERRS2_HZ_FIELD 5
45#define STV090x_WIDTH_OUTSERRS2_HZ_FIELD 1
46#define STV090x_OFFST_OUTSERRS3_HZ_FIELD 4
47#define STV090x_WIDTH_OUTSERRS3_HZ_FIELD 1
48#define STV090x_OFFST_OUTPARRS3_HZ_FIELD 3
49#define STV090x_WIDTH_OUTPARRS3_HZ_FIELD 1
50
51#define STV090x_MODECFG 0xf11d
52
53#define STV090x_IRQSTATUS3 0xf120
54#define STV090x_OFFST_SPLL_LOCK_FIELD 5
55#define STV090x_WIDTH_SPLL_LOCK_FIELD 1
56#define STV090x_OFFST_SSTREAM_LCK_3_FIELD 4
57#define STV090x_WIDTH_SSTREAM_LCK_3_FIELD 1
58#define STV090x_OFFST_SSTREAM_LCK_2_FIELD 3
59#define STV090x_WIDTH_SSTREAM_LCK_2_FIELD 1
60#define STV090x_OFFST_SSTREAM_LCK_1_FIELD 2
61#define STV090x_WIDTH_SSTREAM_LCK_1_FIELD 1
62#define STV090x_OFFST_SDVBS1_PRF_2_FIELD 1
63#define STV090x_WIDTH_SDVBS1_PRF_2_FIELD 1
64#define STV090x_OFFST_SDVBS1_PRF_1_FIELD 0
65#define STV090x_WIDTH_SDVBS1_PRF_1_FIELD 1
66
67#define STV090x_IRQSTATUS2 0xf121
68#define STV090x_OFFST_SSPY_ENDSIM_3_FIELD 7
69#define STV090x_WIDTH_SSPY_ENDSIM_3_FIELD 1
70#define STV090x_OFFST_SSPY_ENDSIM_2_FIELD 6
71#define STV090x_WIDTH_SSPY_ENDSIM_2_FIELD 1
72#define STV090x_OFFST_SSPY_ENDSIM_1_FIELD 5
73#define STV090x_WIDTH_SSPY_ENDSIM_1_FIELD 1
74#define STV090x_OFFST_SPKTDEL_ERROR_2_FIELD 4
75#define STV090x_WIDTH_SPKTDEL_ERROR_2_FIELD 1
76#define STV090x_OFFST_SPKTDEL_LOCKB_2_FIELD 3
77#define STV090x_WIDTH_SPKTDEL_LOCKB_2_FIELD 1
78#define STV090x_OFFST_SPKTDEL_LOCK_2_FIELD 2
79#define STV090x_WIDTH_SPKTDEL_LOCK_2_FIELD 1
80#define STV090x_OFFST_SPKTDEL_ERROR_1_FIELD 1
81#define STV090x_WIDTH_SPKTDEL_ERROR_1_FIELD 1
82#define STV090x_OFFST_SPKTDEL_LOCKB_1_FIELD 0
83#define STV090x_WIDTH_SPKTDEL_LOCKB_1_FIELD 1
84
85#define STV090x_IRQSTATUS1 0xf122
86#define STV090x_OFFST_SPKTDEL_LOCK_1_FIELD 7
87#define STV090x_WIDTH_SPKTDEL_LOCK_1_FIELD 1
88#define STV090x_OFFST_SDEMOD_LOCKB_2_FIELD 2
89#define STV090x_WIDTH_SDEMOD_LOCKB_2_FIELD 1
90#define STV090x_OFFST_SDEMOD_LOCK_2_FIELD 1
91#define STV090x_WIDTH_SDEMOD_LOCK_2_FIELD 1
92#define STV090x_OFFST_SDEMOD_IRQ_2_FIELD 0
93#define STV090x_WIDTH_SDEMOD_IRQ_2_FIELD 1
94
95#define STV090x_IRQSTATUS0 0xf123
96#define STV090x_OFFST_SDEMOD_LOCKB_1_FIELD 7
97#define STV090x_WIDTH_SDEMOD_LOCKB_1_FIELD 1
98#define STV090x_OFFST_SDEMOD_LOCK_1_FIELD 6
99#define STV090x_WIDTH_SDEMOD_LOCK_1_FIELD 1
100#define STV090x_OFFST_SDEMOD_IRQ_1_FIELD 5
101#define STV090x_WIDTH_SDEMOD_IRQ_1_FIELD 1
102#define STV090x_OFFST_SBCH_ERRFLAG_FIELD 4
103#define STV090x_WIDTH_SBCH_ERRFLAG_FIELD 1
104#define STV090x_OFFST_SDISEQC2RX_IRQ_FIELD 3
105#define STV090x_WIDTH_SDISEQC2RX_IRQ_FIELD 1
106#define STV090x_OFFST_SDISEQC2TX_IRQ_FIELD 2
107#define STV090x_WIDTH_SDISEQC2TX_IRQ_FIELD 1
108#define STV090x_OFFST_SDISEQC1RX_IRQ_FIELD 1
109#define STV090x_WIDTH_SDISEQC1RX_IRQ_FIELD 1
110#define STV090x_OFFST_SDISEQC1TX_IRQ_FIELD 0
111#define STV090x_WIDTH_SDISEQC1TX_IRQ_FIELD 1
112
113#define STV090x_IRQMASK3 0xf124
114#define STV090x_OFFST_MPLL_LOCK_FIELD 5
115#define STV090x_WIDTH_MPLL_LOCK_FIELD 1
116#define STV090x_OFFST_MSTREAM_LCK_3_FIELD 4
117#define STV090x_WIDTH_MSTREAM_LCK_3_FIELD 1
118#define STV090x_OFFST_MSTREAM_LCK_2_FIELD 3
119#define STV090x_WIDTH_MSTREAM_LCK_2_FIELD 1
120#define STV090x_OFFST_MSTREAM_LCK_1_FIELD 2
121#define STV090x_WIDTH_MSTREAM_LCK_1_FIELD 1
122#define STV090x_OFFST_MDVBS1_PRF_2_FIELD 1
123#define STV090x_WIDTH_MDVBS1_PRF_2_FIELD 1
124#define STV090x_OFFST_MDVBS1_PRF_1_FIELD 0
125#define STV090x_WIDTH_MDVBS1_PRF_1_FIELD 1
126
127#define STV090x_IRQMASK2 0xf125
128#define STV090x_OFFST_MSPY_ENDSIM_3_FIELD 7
129#define STV090x_WIDTH_MSPY_ENDSIM_3_FIELD 1
130#define STV090x_OFFST_MSPY_ENDSIM_2_FIELD 6
131#define STV090x_WIDTH_MSPY_ENDSIM_2_FIELD 1
132#define STV090x_OFFST_MSPY_ENDSIM_1_FIELD 5
133#define STV090x_WIDTH_MSPY_ENDSIM_1_FIELD 1
134#define STV090x_OFFST_MPKTDEL_ERROR_2_FIELD 4
135#define STV090x_WIDTH_MPKTDEL_ERROR_2_FIELD 1
136#define STV090x_OFFST_MPKTDEL_LOCKB_2_FIELD 3
137#define STV090x_WIDTH_MPKTDEL_LOCKB_2_FIELD 1
138#define STV090x_OFFST_MPKTDEL_LOCK_2_FIELD 2
139#define STV090x_WIDTH_MPKTDEL_LOCK_2_FIELD 1
140#define STV090x_OFFST_MPKTDEL_ERROR_1_FIELD 1
141#define STV090x_WIDTH_MPKTDEL_ERROR_1_FIELD 1
142#define STV090x_OFFST_MPKTDEL_LOCKB_1_FIELD 0
143#define STV090x_WIDTH_MPKTDEL_LOCKB_1_FIELD 1
144
145#define STV090x_IRQMASK1 0xf126
146#define STV090x_OFFST_MPKTDEL_LOCK_1_FIELD 7
147#define STV090x_WIDTH_MPKTDEL_LOCK_1_FIELD 1
148#define STV090x_OFFST_MEXTPINB2_FIELD 6
149#define STV090x_WIDTH_MEXTPINB2_FIELD 1
150#define STV090x_OFFST_MEXTPIN2_FIELD 5
151#define STV090x_WIDTH_MEXTPIN2_FIELD 1
152#define STV090x_OFFST_MEXTPINB1_FIELD 4
153#define STV090x_WIDTH_MEXTPINB1_FIELD 1
154#define STV090x_OFFST_MEXTPIN1_FIELD 3
155#define STV090x_WIDTH_MEXTPIN1_FIELD 1
156#define STV090x_OFFST_MDEMOD_LOCKB_2_FIELD 2
157#define STV090x_WIDTH_MDEMOD_LOCKB_2_FIELD 1
158#define STV090x_OFFST_MDEMOD_LOCK_2_FIELD 1
159#define STV090x_WIDTH_MDEMOD_LOCK_2_FIELD 1
160#define STV090x_OFFST_MDEMOD_IRQ_2_FIELD 0
161#define STV090x_WIDTH_MDEMOD_IRQ_2_FIELD 1
162
163#define STV090x_IRQMASK0 0xf127
164#define STV090x_OFFST_MDEMOD_LOCKB_1_FIELD 7
165#define STV090x_WIDTH_MDEMOD_LOCKB_1_FIELD 1
166#define STV090x_OFFST_MDEMOD_LOCK_1_FIELD 6
167#define STV090x_WIDTH_MDEMOD_LOCK_1_FIELD 1
168#define STV090x_OFFST_MDEMOD_IRQ_1_FIELD 5
169#define STV090x_WIDTH_MDEMOD_IRQ_1_FIELD 1
170#define STV090x_OFFST_MBCH_ERRFLAG_FIELD 4
171#define STV090x_WIDTH_MBCH_ERRFLAG_FIELD 1
172#define STV090x_OFFST_MDISEQC2RX_IRQ_FIELD 3
173#define STV090x_WIDTH_MDISEQC2RX_IRQ_FIELD 1
174#define STV090x_OFFST_MDISEQC2TX_IRQ_FIELD 2
175#define STV090x_WIDTH_MDISEQC2TX_IRQ_FIELD 1
176#define STV090x_OFFST_MDISEQC1RX_IRQ_FIELD 1
177#define STV090x_WIDTH_MDISEQC1RX_IRQ_FIELD 1
178#define STV090x_OFFST_MDISEQC1TX_IRQ_FIELD 0
179#define STV090x_WIDTH_MDISEQC1TX_IRQ_FIELD 1
180
181#define STV090x_I2CCFG 0xf129
182#define STV090x_OFFST_12C_FASTMODE_FIELD 3
183#define STV090x_WIDTH_12C_FASTMODE_FIELD 1
184#define STV090x_OFFST_12CADDR_INC_FIELD 0
185#define STV090x_WIDTH_12CADDR_INC_FIELD 2
186
187#define STV090x_Px_I2CRPT(__x) (0xf12a + (__x - 1) * 0x1)
188#define STV090x_P1_I2CRPT STV090x_Px_I2CRPT(1)
189#define STV090x_P2_I2CRPT STV090x_Px_I2CRPT(2)
190#define STV090x_OFFST_Px_I2CT_ON_FIELD 7
191#define STV090x_WIDTH_Px_I2CT_ON_FIELD 1
192#define STV090x_OFFST_Px_ENARPT_LEVEL_FIELD 4
193#define STV090x_WIDTH_Px_ENARPT_LEVEL_FIELD 3
194#define STV090x_OFFST_Px_SCLT_DELAY_FIELD 3
195#define STV090x_WIDTH_Px_SCLT_DELAY_FIELD 1
196#define STV090x_OFFST_Px_STOP_ENABLE_FIELD 2
197#define STV090x_WIDTH_Px_STOP_ENABLE_FIELD 1
198#define STV090x_OFFST_Px_STOP_SDAT2SDA_FIELD 1
199#define STV090x_WIDTH_Px_STOP_SDAT2SDA_FIELD 1
200
201#define STV090x_CLKI2CFG 0xf140
202#define STV090x_OFFST_CLKI2_OPD_FIELD 7
203#define STV090x_WIDTH_CLKI2_OPD_FIELD 1
204#define STV090x_OFFST_CLKI2_CONFIG_FIELD 1
205#define STV090x_WIDTH_CLKI2_CONFIG_FIELD 6
206#define STV090x_OFFST_CLKI2_XOR_FIELD 0
207#define STV090x_WIDTH_CLKI2_XOR_FIELD 1
208
209#define STV090x_GPIOxCFG(__x) (0xf141 + (__x - 1))
210#define STV090x_GPIO1CFG STV090x_GPIOxCFG(1)
211#define STV090x_GPIO2CFG STV090x_GPIOxCFG(2)
212#define STV090x_GPIO3CFG STV090x_GPIOxCFG(3)
213#define STV090x_GPIO4CFG STV090x_GPIOxCFG(4)
214#define STV090x_GPIO5CFG STV090x_GPIOxCFG(5)
215#define STV090x_GPIO6CFG STV090x_GPIOxCFG(6)
216#define STV090x_GPIO7CFG STV090x_GPIOxCFG(7)
217#define STV090x_GPIO8CFG STV090x_GPIOxCFG(8)
218#define STV090x_GPIO9CFG STV090x_GPIOxCFG(9)
219#define STV090x_GPIO10CFG STV090x_GPIOxCFG(10)
220#define STV090x_GPIO11CFG STV090x_GPIOxCFG(11)
221#define STV090x_GPIO12CFG STV090x_GPIOxCFG(12)
222#define STV090x_GPIO13CFG STV090x_GPIOxCFG(13)
223#define STV090x_OFFST_GPIOx_OPD_FIELD 7
224#define STV090x_WIDTH_GPIOx_OPD_FIELD 1
225#define STV090x_OFFST_GPIOx_CONFIG_FIELD 1
226#define STV090x_WIDTH_GPIOx_CONFIG_FIELD 6
227#define STV090x_OFFST_GPIOx_XOR_FIELD 0
228#define STV090x_WIDTH_GPIOx_XOR_FIELD 1
229
230#define STV090x_CSxCFG(__x) (0xf14e + __x * 0x1)
231#define STV090x_CS0CFG STV090x_CSxCFG(0)
232#define STV090x_CS1CFG STV090x_CSxCFG(1)
233#define STV090x_OFFST_CSX_OPD_FIELD 7
234#define STV090x_WIDTH_CSX_OPD_FIELD 1
235#define STV090x_OFFST_CSX_CONFIG_FIELD 1
236#define STV090x_WIDTH_CSX_CONFIG_FIELD 6
237#define STV090x_OFFST_CSX_XOR_FIELD 0
238#define STV090x_WIDTH_CSX_XOR_FIELD 1
239
240
241#define STV090x_STDBYCFG 0xf150
242#define STV090x_OFFST_STDBY_OPD_FIELD 7
243#define STV090x_WIDTH_STDBY_OPD_FIELD 1
244#define STV090x_OFFST_STDBY_CONFIG_FIELD 1
245#define STV090x_WIDTH_STDBY_CONFIG_FIELD 6
246#define STV090x_OFFST_STDBY_XOR_FIELD 0
247#define STV090x_WIDTH_STDBY_XOR_FIELD 1
248
249#define STV090x_DIRCLKCFG 0xf151
250#define STV090x_OFFST_DIRCLK_OPD_FIELD 7
251#define STV090x_WIDTH_DIRCLK_OPD_FIELD 1
252#define STV090x_OFFST_DIRCLK_CONFIG_FIELD 1
253#define STV090x_WIDTH_DIRCLK_CONFIG_FIELD 6
254#define STV090x_OFFST_DIRCLK_XOR_FIELD 0
255#define STV090x_WIDTH_DIRCLK_XOR_FIELD 1
256
257
258#define STV090x_AGCRFxCFG(__x) (0xf152 + (__x - 1) * 0x4)
259#define STV090x_AGCRF1CFG STV090x_AGCRFxCFG(1)
260#define STV090x_AGCRF2CFG STV090x_AGCRFxCFG(2)
261#define STV090x_OFFST_AGCRFx_OPD_FIELD 7
262#define STV090x_WIDTH_AGCRFx_OPD_FIELD 1
263#define STV090x_OFFST_AGCRFx_CONFIG_FIELD 1
264#define STV090x_WIDTH_AGCRFx_CONFIG_FIELD 6
265#define STV090x_OFFST_AGCRFx_XOR_FIELD 0
266#define STV090x_WIDTH_AGCRFx_XOR_FIELD 1
267
268#define STV090x_SDATxCFG(__x) (0xf153 + (__x - 1) * 0x4)
269#define STV090x_SDAT1CFG STV090x_SDATxCFG(1)
270#define STV090x_SDAT2CFG STV090x_SDATxCFG(2)
271#define STV090x_OFFST_SDATx_OPD_FIELD 7
272#define STV090x_WIDTH_SDATx_OPD_FIELD 1
273#define STV090x_OFFST_SDATx_CONFIG_FIELD 1
274#define STV090x_WIDTH_SDATx_CONFIG_FIELD 6
275#define STV090x_OFFST_SDATx_XOR_FIELD 0
276#define STV090x_WIDTH_SDATx_XOR_FIELD 1
277
278#define STV090x_SCLTxCFG(__x) (0xf154 + (__x - 1) * 0x4)
279#define STV090x_SCLT1CFG STV090x_SCLTxCFG(1)
280#define STV090x_SCLT2CFG STV090x_SCLTxCFG(2)
281#define STV090x_OFFST_SCLTx_OPD_FIELD 7
282#define STV090x_WIDTH_SCLTx_OPD_FIELD 1
283#define STV090x_OFFST_SCLTx_CONFIG_FIELD 1
284#define STV090x_WIDTH_SCLTx_CONFIG_FIELD 6
285#define STV090x_OFFST_SCLTx_XOR_FIELD 0
286#define STV090x_WIDTH_SCLTx_XOR_FIELD 1
287
288#define STV090x_DISEQCOxCFG(__x) (0xf155 + (__x - 1) * 0x4)
289#define STV090x_DISEQCO1CFG STV090x_DISEQCOxCFG(1)
290#define STV090x_DISEQCO2CFG STV090x_DISEQCOxCFG(2)
291#define STV090x_OFFST_DISEQCOx_OPD_FIELD 7
292#define STV090x_WIDTH_DISEQCOx_OPD_FIELD 1
293#define STV090x_OFFST_DISEQCOx_CONFIG_FIELD 1
294#define STV090x_WIDTH_DISEQCOx_CONFIG_FIELD 6
295#define STV090x_OFFST_DISEQCOx_XOR_FIELD 0
296#define STV090x_WIDTH_DISEQCOx_XOR_FIELD 1
297
298#define STV090x_CLKOUT27CFG 0xf15a
299#define STV090x_OFFST_CLKOUT27_OPD_FIELD 7
300#define STV090x_WIDTH_CLKOUT27_OPD_FIELD 1
301#define STV090x_OFFST_CLKOUT27_CONFIG_FIELD 1
302#define STV090x_WIDTH_CLKOUT27_CONFIG_FIELD 6
303#define STV090x_OFFST_CLKOUT27_XOR_FIELD 0
304#define STV090x_WIDTH_CLKOUT27_XOR_FIELD 1
305
306#define STV090x_ERRORxCFG(__x) (0xf15b + (__x - 1) * 0x5)
307#define STV090x_ERROR1CFG STV090x_ERRORxCFG(1)
308#define STV090x_ERROR2CFG STV090x_ERRORxCFG(2)
309#define STV090x_ERROR3CFG STV090x_ERRORxCFG(3)
310#define STV090x_OFFST_ERRORx_OPD_FIELD 7
311#define STV090x_WIDTH_ERRORx_OPD_FIELD 1
312#define STV090x_OFFST_ERRORx_CONFIG_FIELD 1
313#define STV090x_WIDTH_ERRORx_CONFIG_FIELD 6
314#define STV090x_OFFST_ERRORx_XOR_FIELD 0
315#define STV090x_WIDTH_ERRORx_XOR_FIELD 1
316
317#define STV090x_DPNxCFG(__x) (0xf15c + (__x - 1) * 0x5)
318#define STV090x_DPN1CFG STV090x_DPNxCFG(1)
319#define STV090x_DPN2CFG STV090x_DPNxCFG(2)
320#define STV090x_DPN3CFG STV090x_DPNxCFG(3)
321#define STV090x_OFFST_DPNx_OPD_FIELD 7
322#define STV090x_WIDTH_DPNx_OPD_FIELD 1
323#define STV090x_OFFST_DPNx_CONFIG_FIELD 1
324#define STV090x_WIDTH_DPNx_CONFIG_FIELD 6
325#define STV090x_OFFST_DPNx_XOR_FIELD 0
326#define STV090x_WIDTH_DPNx_XOR_FIELD 1
327
328#define STV090x_STROUTxCFG(__x) (0xf15d + (__x - 1) * 0x5)
329#define STV090x_STROUT1CFG STV090x_STROUTxCFG(1)
330#define STV090x_STROUT2CFG STV090x_STROUTxCFG(2)
331#define STV090x_STROUT3CFG STV090x_STROUTxCFG(3)
332#define STV090x_OFFST_STROUTx_OPD_FIELD 7
333#define STV090x_WIDTH_STROUTx_OPD_FIELD 1
334#define STV090x_OFFST_STROUTx_CONFIG_FIELD 1
335#define STV090x_WIDTH_STROUTx_CONFIG_FIELD 6
336#define STV090x_OFFST_STROUTx_XOR_FIELD 0
337#define STV090x_WIDTH_STROUTx_XOR_FIELD 1
338
339#define STV090x_CLKOUTxCFG(__x) (0xf15e + (__x - 1) * 0x5)
340#define STV090x_CLKOUT1CFG STV090x_CLKOUTxCFG(1)
341#define STV090x_CLKOUT2CFG STV090x_CLKOUTxCFG(2)
342#define STV090x_CLKOUT3CFG STV090x_CLKOUTxCFG(3)
343#define STV090x_OFFST_CLKOUTx_OPD_FIELD 7
344#define STV090x_WIDTH_CLKOUTx_OPD_FIELD 1
345#define STV090x_OFFST_CLKOUTx_CONFIG_FIELD 1
346#define STV090x_WIDTH_CLKOUTx_CONFIG_FIELD 6
347#define STV090x_OFFST_CLKOUTx_XOR_FIELD 0
348#define STV090x_WIDTH_CLKOUTx_XOR_FIELD 1
349
350#define STV090x_DATAxCFG(__x) (0xf15f + (__x - 71) * 0x5)
351#define STV090x_DATA71CFG STV090x_DATAxCFG(71)
352#define STV090x_DATA72CFG STV090x_DATAxCFG(72)
353#define STV090x_DATA73CFG STV090x_DATAxCFG(73)
354#define STV090x_OFFST_DATAx_OPD_FIELD 7
355#define STV090x_WIDTH_DATAx_OPD_FIELD 1
356#define STV090x_OFFST_DATAx_CONFIG_FIELD 1
357#define STV090x_WIDTH_DATAx_CONFIG_FIELD 6
358#define STV090x_OFFST_DATAx_XOR_FIELD 0
359#define STV090x_WIDTH_DATAx_XOR_FIELD 1
360
361#define STV090x_NCOARSE 0xf1b3
362#define STV090x_OFFST_M_DIV_FIELD 0
363#define STV090x_WIDTH_M_DIV_FIELD 8
364
365#define STV090x_SYNTCTRL 0xf1b6
366#define STV090x_OFFST_STANDBY_FIELD 7
367#define STV090x_WIDTH_STANDBY_FIELD 1
368#define STV090x_OFFST_BYPASSPLLCORE_FIELD 6
369#define STV090x_WIDTH_BYPASSPLLCORE_FIELD 1
370#define STV090x_OFFST_SELX1RATIO_FIELD 5
371#define STV090x_WIDTH_SELX1RATIO_FIELD 1
372#define STV090x_OFFST_STOP_PLL_FIELD 3
373#define STV090x_WIDTH_STOP_PLL_FIELD 1
374#define STV090x_OFFST_BYPASSPLLFSK_FIELD 2
375#define STV090x_WIDTH_BYPASSPLLFSK_FIELD 1
376#define STV090x_OFFST_SELOSCI_FIELD 1
377#define STV090x_WIDTH_SELOSCI_FIELD 1
378#define STV090x_OFFST_BYPASSPLLADC_FIELD 0
379#define STV090x_WIDTH_BYPASSPLLADC_FIELD 1
380
381#define STV090x_FILTCTRL 0xf1b7
382#define STV090x_OFFST_INV_CLK135_FIELD 7
383#define STV090x_WIDTH_INV_CLK135_FIELD 1
384#define STV090x_OFFST_SEL_FSKCKDIV_FIELD 2
385#define STV090x_WIDTH_SEL_FSKCKDIV_FIELD 1
386#define STV090x_OFFST_INV_CLKFSK_FIELD 1
387#define STV090x_WIDTH_INV_CLKFSK_FIELD 1
388#define STV090x_OFFST_BYPASS_APPLI_FIELD 0
389#define STV090x_WIDTH_BYPASS_APPLI_FIELD 1
390
391#define STV090x_PLLSTAT 0xf1b8
392#define STV090x_OFFST_PLLLOCK_FIELD 0
393#define STV090x_WIDTH_PLLLOCK_FIELD 1
394
395#define STV090x_STOPCLK1 0xf1c2
396#define STV090x_OFFST_STOP_CLKPKDT2_FIELD 6
397#define STV090x_WIDTH_STOP_CLKPKDT2_FIELD 1
398#define STV090x_OFFST_STOP_CLKPKDT1_FIELD 5
399#define STV090x_WIDTH_STOP_CLKPKDT1_FIELD 1
400#define STV090x_OFFST_STOP_CLKFEC_FIELD 4
401#define STV090x_WIDTH_STOP_CLKFEC_FIELD 1
402#define STV090x_OFFST_STOP_CLKADCI2_FIELD 3
403#define STV090x_WIDTH_STOP_CLKADCI2_FIELD 1
404#define STV090x_OFFST_INV_CLKADCI2_FIELD 2
405#define STV090x_WIDTH_INV_CLKADCI2_FIELD 1
406#define STV090x_OFFST_STOP_CLKADCI1_FIELD 1
407#define STV090x_WIDTH_STOP_CLKADCI1_FIELD 1
408#define STV090x_OFFST_INV_CLKADCI1_FIELD 0
409#define STV090x_WIDTH_INV_CLKADCI1_FIELD 1
410
411#define STV090x_STOPCLK2 0xf1c3
412#define STV090x_OFFST_STOP_CLKSAMP2_FIELD 4
413#define STV090x_WIDTH_STOP_CLKSAMP2_FIELD 1
414#define STV090x_OFFST_STOP_CLKSAMP1_FIELD 3
415#define STV090x_WIDTH_STOP_CLKSAMP1_FIELD 1
416#define STV090x_OFFST_STOP_CLKVIT2_FIELD 2
417#define STV090x_WIDTH_STOP_CLKVIT2_FIELD 1
418#define STV090x_OFFST_STOP_CLKVIT1_FIELD 1
419#define STV090x_WIDTH_STOP_CLKVIT1_FIELD 1
420#define STV090x_OFFST_STOP_CLKTS_FIELD 0
421#define STV090x_WIDTH_STOP_CLKTS_FIELD 1
422
423#define STV090x_TSTTNR0 0xf1df
424#define STV090x_OFFST_SEL_FSK_FIELD 7
425#define STV090x_WIDTH_SEL_FSK_FIELD 1
426#define STV090x_OFFST_FSK_PON_FIELD 2
427#define STV090x_WIDTH_FSK_PON_FIELD 1
428
429#define STV090x_TSTTNR1 0xf1e0
430#define STV090x_OFFST_ADC1_PON_FIELD 1
431#define STV090x_WIDTH_ADC1_PON_FIELD 1
432#define STV090x_OFFST_ADC1_INMODE_FIELD 0
433#define STV090x_WIDTH_ADC1_INMODE_FIELD 1
434
435#define STV090x_TSTTNR2 0xf1e1
436#define STV090x_OFFST_DISEQC1_PON_FIELD 5
437#define STV090x_WIDTH_DISEQC1_PON_FIELD 1
438
439#define STV090x_TSTTNR3 0xf1e2
440#define STV090x_OFFST_ADC2_PON_FIELD 1
441#define STV090x_WIDTH_ADC2_PON_FIELD 1
442#define STV090x_OFFST_ADC2_INMODE_FIELD 0
443#define STV090x_WIDTH_ADC2_INMODE_FIELD 1
444
445#define STV090x_TSTTNR4 0xf1e3
446#define STV090x_OFFST_DISEQC2_PON_FIELD 5
447#define STV090x_WIDTH_DISEQC2_PON_FIELD 1
448
449#define STV090x_FSKTFC2 0xf170
450#define STV090x_OFFST_FSKT_KMOD_FIELD 2
451#define STV090x_WIDTH_FSKT_KMOD_FIELD 6
452#define STV090x_OFFST_FSKT_CAR_FIELD 0
453#define STV090x_WIDTH_FSKT_CAR_FIELD 2
454
455#define STV090x_FSKTFC1 0xf171
456#define STV090x_OFFST_FSKTC1_CAR_FIELD 0
457#define STV090x_WIDTH_FSKTC1_CAR_FIELD 8
458
459#define STV090x_FSKTFC0 0xf172
460#define STV090x_OFFST_FSKTC0_CAR_FIELD 0
461#define STV090x_WIDTH_FSKTC0_CAR_FIELD 8
462
463#define STV090x_FSKTDELTAF1 0xf173
464#define STV090x_OFFST_FSKTF1_DELTAF_FIELD 0
465#define STV090x_WIDTH_FSKTF1_DELTAF_FIELD 4
466
467#define STV090x_FSKTDELTAF0 0xf174
468#define STV090x_OFFST_FSKTF0_DELTAF_FIELD 0
469#define STV090x_WIDTH_FSKTF0_DELTAF_FIELD 8
470
471#define STV090x_FSKTCTRL 0xf175
472#define STV090x_OFFST_FSKT_EN_SGN_FIELD 6
473#define STV090x_WIDTH_FSKT_EN_SGN_FIELD 1
474#define STV090x_OFFST_FSKT_MOD_SGN_FIELD 5
475#define STV090x_WIDTH_FSKT_MOD_SGN_FIELD 1
476#define STV090x_OFFST_FSKT_MOD_EN_FIELD 2
477#define STV090x_WIDTH_FSKT_MOD_EN_FIELD 3
478#define STV090x_OFFST_FSKT_DACMODE_FIELD 0
479#define STV090x_WIDTH_FSKT_DACMODE_FIELD 2
480
481#define STV090x_FSKRFC2 0xf176
482#define STV090x_OFFST_FSKRC2_DETSGN_FIELD 6
483#define STV090x_WIDTH_FSKRC2_DETSGN_FIELD 1
484#define STV090x_OFFST_FSKRC2_OUTSGN_FIELD 5
485#define STV090x_WIDTH_FSKRC2_OUTSGN_FIELD 1
486#define STV090x_OFFST_FSKRC2_KAGC_FIELD 2
487#define STV090x_WIDTH_FSKRC2_KAGC_FIELD 3
488#define STV090x_OFFST_FSKRC2_CAR_FIELD 0
489#define STV090x_WIDTH_FSKRC2_CAR_FIELD 2
490
491#define STV090x_FSKRFC1 0xf177
492#define STV090x_OFFST_FSKRC1_CAR_FIELD 0
493#define STV090x_WIDTH_FSKRC1_CAR_FIELD 8
494
495#define STV090x_FSKRFC0 0xf178
496#define STV090x_OFFST_FSKRC0_CAR_FIELD 0
497#define STV090x_WIDTH_FSKRC0_CAR_FIELD 8
498
499#define STV090x_FSKRK1 0xf179
500#define STV090x_OFFST_FSKR_K1_EXP_FIELD 5
501#define STV090x_WIDTH_FSKR_K1_EXP_FIELD 3
502#define STV090x_OFFST_FSKR_K1_MANT_FIELD 0
503#define STV090x_WIDTH_FSKR_K1_MANT_FIELD 5
504
505#define STV090x_FSKRK2 0xf17a
506#define STV090x_OFFST_FSKR_K2_EXP_FIELD 5
507#define STV090x_WIDTH_FSKR_K2_EXP_FIELD 3
508#define STV090x_OFFST_FSKR_K2_MANT_FIELD 0
509#define STV090x_WIDTH_FSKR_K2_MANT_FIELD 5
510
511#define STV090x_FSKRAGCR 0xf17b
512#define STV090x_OFFST_FSKR_OUTCTL_FIELD 6
513#define STV090x_WIDTH_FSKR_OUTCTL_FIELD 2
514#define STV090x_OFFST_FSKR_AGC_REF_FIELD 0
515#define STV090x_WIDTH_FSKR_AGC_REF_FIELD 6
516
517#define STV090x_FSKRAGC 0xf17c
518#define STV090x_OFFST_FSKR_AGC_ACCU_FIELD 0
519#define STV090x_WIDTH_FSKR_AGC_ACCU_FIELD 8
520
521#define STV090x_FSKRALPHA 0xf17d
522#define STV090x_OFFST_FSKR_ALPHA_EXP_FIELD 2
523#define STV090x_WIDTH_FSKR_ALPHA_EXP_FIELD 3
524#define STV090x_OFFST_FSKR_ALPHA_M_FIELD 0
525#define STV090x_WIDTH_FSKR_ALPHA_M_FIELD 2
526
527#define STV090x_FSKRPLTH1 0xf17e
528#define STV090x_OFFST_FSKR_BETA_FIELD 4
529#define STV090x_WIDTH_FSKR_BETA_FIELD 4
530#define STV090x_OFFST_FSKR_PLL_TRESH1_FIELD 0
531#define STV090x_WIDTH_FSKR_PLL_TRESH1_FIELD 4
532
533#define STV090x_FSKRPLTH0 0xf17f
534#define STV090x_OFFST_FSKR_PLL_TRESH0_FIELD 0
535#define STV090x_WIDTH_FSKR_PLL_TRESH0_FIELD 8
536
537#define STV090x_FSKRDF1 0xf180
538#define STV090x_OFFST_FSKR_DELTAF1_FIELD 0
539#define STV090x_WIDTH_FSKR_DELTAF1_FIELD 5
540
541#define STV090x_FSKRDF0 0xf181
542#define STV090x_OFFST_FSKR_DELTAF0_FIELD 0
543#define STV090x_WIDTH_FSKR_DELTAF0_FIELD 8
544
545#define STV090x_FSKRSTEPP 0xf182
546#define STV090x_OFFST_FSKR_STEP_PLUS_FIELD 0
547#define STV090x_WIDTH_FSKR_STEP_PLUS_FIELD 8
548
549#define STV090x_FSKRSTEPM 0xf183
550#define STV090x_OFFST_FSKR_STEP_MINUS_FIELD 0
551#define STV090x_WIDTH_FSKR_STEP_MINUS_FIELD 8
552
553#define STV090x_FSKRDET1 0xf184
554#define STV090x_OFFST_FSKR_CARDET1_ACCU_FIELD 0
555#define STV090x_WIDTH_FSKR_CARDET1_ACCU_FIELD 4
556
557#define STV090x_FSKRDET0 0xf185
558#define STV090x_OFFST_FSKR_CARDET0_ACCU_FIELD 0
559#define STV090x_WIDTH_FSKR_CARDET0_ACCU_FIELD 8
560
561#define STV090x_FSKRDTH1 0xf186
562#define STV090x_OFFST_FSKR_CARLOSS_THRESH1_FIELD 4
563#define STV090x_WIDTH_FSKR_CARLOSS_THRESH1_FIELD 4
564#define STV090x_OFFST_FSKR_CARDET_THRESH1_FIELD 0
565#define STV090x_WIDTH_FSKR_CARDET_THRESH1_FIELD 4
566
567#define STV090x_FSKRDTH0 0xf187
568#define STV090x_OFFST_FSKR_CARDET_THRESH0_FIELD 0
569#define STV090x_WIDTH_FSKR_CARDET_THRESH0_FIELD 8
570
571#define STV090x_FSKRLOSS 0xf188
572#define STV090x_OFFST_FSKR_CARLOSS_THRESH_FIELD 0
573#define STV090x_WIDTH_FSKR_CARLOSS_THRESH_FIELD 8
574
575#define STV090x_Px_DISTXCTL(__x) (0xF1A0 - (__x - 1) * 0x10)
576#define STV090x_P1_DISTXCTL STV090x_Px_DISTXCTL(1)
577#define STV090x_P2_DISTXCTL STV090x_Px_DISTXCTL(2)
578#define STV090x_OFFST_Px_TIM_OFF_FIELD 7
579#define STV090x_WIDTH_Px_TIM_OFF_FIELD 1
580#define STV090x_OFFST_Px_DISEQC_RESET_FIELD 6
581#define STV090x_WIDTH_Px_DISEQC_RESET_FIELD 1
582#define STV090x_OFFST_Px_TIM_CMD_FIELD 4
583#define STV090x_WIDTH_Px_TIM_CMD_FIELD 2
584#define STV090x_OFFST_Px_DIS_PRECHARGE_FIELD 3
585#define STV090x_WIDTH_Px_DIS_PRECHARGE_FIELD 1
586#define STV090x_OFFST_Px_DISTX_MODE_FIELD 0
587#define STV090x_WIDTH_Px_DISTX_MODE_FIELD 3
588
589#define STV090x_Px_DISRXCTL(__x) (0xf1a1 - (__x - 1) * 0x10)
590#define STV090x_P1_DISRXCTL STV090x_Px_DISRXCTL(1)
591#define STV090x_P2_DISRXCTL STV090x_Px_DISRXCTL(2)
592#define STV090x_OFFST_Px_RECEIVER_ON_FIELD 7
593#define STV090x_WIDTH_Px_RECEIVER_ON_FIELD 1
594#define STV090x_OFFST_Px_IGNO_SHORT22K_FIELD 6
595#define STV090x_WIDTH_Px_IGNO_SHORT22K_FIELD 1
596#define STV090x_OFFST_Px_ONECHIP_TRX_FIELD 5
597#define STV090x_WIDTH_Px_ONECHIP_TRX_FIELD 1
598#define STV090x_OFFST_Px_EXT_ENVELOP_FIELD 4
599#define STV090x_WIDTH_Px_EXT_ENVELOP_FIELD 1
600#define STV090x_OFFST_Px_PIN_SELECT_FIELD 2
601#define STV090x_WIDTH_Px_PIN_SELECT_FIELD 2
602#define STV090x_OFFST_Px_IRQ_RXEND_FIELD 1
603#define STV090x_WIDTH_Px_IRQ_RXEND_FIELD 1
604#define STV090x_OFFST_Px_IRQ_4NBYTES_FIELD 0
605#define STV090x_WIDTH_Px_IRQ_4NBYTES_FIELD 1
606
607#define STV090x_Px_DISRX_ST0(__x) (0xf1a4 - (__x - 1) * 0x10)
608#define STV090x_P1_DISRX_ST0 STV090x_Px_DISRX_ST0(1)
609#define STV090x_P2_DISRX_ST0 STV090x_Px_DISRX_ST0(2)
610#define STV090x_OFFST_Px_RX_END_FIELD 7
611#define STV090x_WIDTH_Px_RX_END_FIELD 1
612#define STV090x_OFFST_Px_RX_ACTIVE_FIELD 6
613#define STV090x_WIDTH_Px_RX_ACTIVE_FIELD 1
614#define STV090x_OFFST_Px_SHORT_22KHZ_FIELD 5
615#define STV090x_WIDTH_Px_SHORT_22KHZ_FIELD 1
616#define STV090x_OFFST_Px_CONT_TONE_FIELD 4
617#define STV090x_WIDTH_Px_CONT_TONE_FIELD 1
618#define STV090x_OFFST_Px_FIFO_4BREADY_FIELD 3
619#define STV090x_WIDTH_Px_FIFO_4BREADY_FIELD 1
620#define STV090x_OFFST_Px_FIFO_EMPTY_FIELD 2
621#define STV090x_WIDTH_Px_FIFO_EMPTY_FIELD 1
622#define STV090x_OFFST_Px_ABORT_DISRX_FIELD 0
623#define STV090x_WIDTH_Px_ABORT_DISRX_FIELD 1
624
625#define STV090x_Px_DISRX_ST1(__x) (0xf1a5 - (__x - 1) * 0x10)
626#define STV090x_P1_DISRX_ST1 STV090x_Px_DISRX_ST1(1)
627#define STV090x_P2_DISRX_ST1 STV090x_Px_DISRX_ST1(2)
628#define STV090x_OFFST_Px_RX_FAIL_FIELD 7
629#define STV090x_WIDTH_Px_RX_FAIL_FIELD 1
630#define STV090x_OFFST_Px_FIFO_PARITYFAIL_FIELD 6
631#define STV090x_WIDTH_Px_FIFO_PARITYFAIL_FIELD 1
632#define STV090x_OFFST_Px_RX_NONBYTE_FIELD 5
633#define STV090x_WIDTH_Px_RX_NONBYTE_FIELD 1
634#define STV090x_OFFST_Px_FIFO_OVERFLOW_FIELD 4
635#define STV090x_WIDTH_Px_FIFO_OVERFLOW_FIELD 1
636#define STV090x_OFFST_Px_FIFO_BYTENBR_FIELD 0
637#define STV090x_WIDTH_Px_FIFO_BYTENBR_FIELD 4
638
639#define STV090x_Px_DISRXDATA(__x) (0xf1a6 - (__x - 1) * 0x10)
640#define STV090x_P1_DISRXDATA STV090x_Px_DISRXDATA(1)
641#define STV090x_P2_DISRXDATA STV090x_Px_DISRXDATA(2)
642#define STV090x_OFFST_Px_DISRX_DATA_FIELD 0
643#define STV090x_WIDTH_Px_DISRX_DATA_FIELD 8
644
645#define STV090x_Px_DISTXDATA(__x) (0xf1a7 - (__x - 1) * 0x10)
646#define STV090x_P1_DISTXDATA STV090x_Px_DISTXDATA(1)
647#define STV090x_P2_DISTXDATA STV090x_Px_DISTXDATA(2)
648#define STV090x_OFFST_Px_DISEQC_FIFO_FIELD 0
649#define STV090x_WIDTH_Px_DISEQC_FIFO_FIELD 8
650
651#define STV090x_Px_DISTXSTATUS(__x) (0xf1a8 - (__x - 1) * 0x10)
652#define STV090x_P1_DISTXSTATUS STV090x_Px_DISTXSTATUS(1)
653#define STV090x_P2_DISTXSTATUS STV090x_Px_DISTXSTATUS(2)
654#define STV090x_OFFST_Px_TX_FAIL_FIELD 7
655#define STV090x_WIDTH_Px_TX_FAIL_FIELD 1
656#define STV090x_OFFST_Px_FIFO_FULL_FIELD 6
657#define STV090x_WIDTH_Px_FIFO_FULL_FIELD 1
658#define STV090x_OFFST_Px_TX_IDLE_FIELD 5
659#define STV090x_WIDTH_Px_TX_IDLE_FIELD 1
660#define STV090x_OFFST_Px_GAP_BURST_FIELD 4
661#define STV090x_WIDTH_Px_GAP_BURST_FIELD 1
662#define STV090x_OFFST_Px_TXFIFO_BYTES_FIELD 0
663#define STV090x_WIDTH_Px_TXFIFO_BYTES_FIELD 4
664
665#define STV090x_Px_F22TX(__x) (0xf1a9 - (__x - 1) * 0x10)
666#define STV090x_P1_F22TX STV090x_Px_F22TX(1)
667#define STV090x_P2_F22TX STV090x_Px_F22TX(2)
668#define STV090x_OFFST_Px_F22_REG_FIELD 0
669#define STV090x_WIDTH_Px_F22_REG_FIELD 8
670
671#define STV090x_Px_F22RX(__x) (0xf1aa - (__x - 1) * 0x10)
672#define STV090x_P1_F22RX STV090x_Px_F22RX(1)
673#define STV090x_P2_F22RX STV090x_Px_F22RX(2)
674#define STV090x_OFFST_Px_F22RX_REG_FIELD 0
675#define STV090x_WIDTH_Px_F22RX_REG_FIELD 8
676
677#define STV090x_Px_ACRPRESC(__x) (0xf1ac - (__x - 1) * 0x10)
678#define STV090x_P1_ACRPRESC STV090x_Px_ACRPRESC(1)
679#define STV090x_P2_ACRPRESC STV090x_Px_ACRPRESC(2)
680#define STV090x_OFFST_Px_ACR_PRESC_FIELD 0
681#define STV090x_WIDTH_Px_ACR_PRESC_FIELD 3
682
683#define STV090x_Px_ACRDIV(__x) (0xf1ad - (__x - 1) * 0x10)
684#define STV090x_P1_ACRDIV STV090x_Px_ACRDIV(1)
685#define STV090x_P2_ACRDIV STV090x_Px_ACRDIV(2)
686#define STV090x_OFFST_Px_ACR_DIV_FIELD 0
687#define STV090x_WIDTH_Px_ACR_DIV_FIELD 8
688
689#define STV090x_Px_IQCONST(__x) (0xF400 - (__x - 1) * 0x200)
690#define STV090x_P1_IQCONST STV090x_Px_IQCONST(1)
691#define STV090x_P2_IQCONST STV090x_Px_IQCONST(2)
692#define STV090x_OFFST_Px_CONSTEL_SELECT_FIELD 5
693#define STV090x_WIDTH_Px_CONSTEL_SELECT_FIELD 2
694
695#define STV090x_Px_NOSCFG(__x) (0xF401 - (__x - 1) * 0x200)
696#define STV090x_P1_NOSCFG STV090x_Px_NOSCFG(1)
697#define STV090x_P2_NOSCFG STV090x_Px_NOSCFG(2)
698#define STV090x_OFFST_Px_NOSPLH_BETA_FIELD 3
699#define STV090x_WIDTH_Px_NOSPLH_BETA_FIELD 2
700#define STV090x_OFFST_Px_NOSDATA_BETA_FIELD 0
701#define STV090x_WIDTH_Px_NOSDATA_BETA_FIELD 3
702
703#define STV090x_Px_ISYMB(__x) (0xF402 - (__x - 1) * 0x200)
704#define STV090x_P1_ISYMB STV090x_Px_ISYMB(1)
705#define STV090x_P2_ISYMB STV090x_Px_ISYMB(2)
706#define STV090x_OFFST_Px_I_SYMBOL_FIELD 0
707#define STV090x_WIDTH_Px_I_SYMBOL_FIELD 8
708
709#define STV090x_Px_QSYMB(__x) (0xF403 - (__x - 1) * 0x200)
710#define STV090x_P1_QSYMB STV090x_Px_QSYMB(1)
711#define STV090x_P2_QSYMB STV090x_Px_QSYMB(2)
712#define STV090x_OFFST_Px_Q_SYMBOL_FIELD 0
713#define STV090x_WIDTH_Px_Q_SYMBOL_FIELD 8
714
715#define STV090x_Px_AGC1CFG(__x) (0xF404 - (__x - 1) * 0x200)
716#define STV090x_P1_AGC1CFG STV090x_Px_AGC1CFG(1)
717#define STV090x_P2_AGC1CFG STV090x_Px_AGC1CFG(2)
718#define STV090x_OFFST_Px_DC_FROZEN_FIELD 7
719#define STV090x_WIDTH_Px_DC_FROZEN_FIELD 1
720#define STV090x_OFFST_Px_DC_CORRECT_FIELD 6
721#define STV090x_WIDTH_Px_DC_CORRECT_FIELD 1
722#define STV090x_OFFST_Px_AMM_FROZEN_FIELD 5
723#define STV090x_WIDTH_Px_AMM_FROZEN_FIELD 1
724#define STV090x_OFFST_Px_AMM_CORRECT_FIELD 4
725#define STV090x_WIDTH_Px_AMM_CORRECT_FIELD 1
726#define STV090x_OFFST_Px_QUAD_FROZEN_FIELD 3
727#define STV090x_WIDTH_Px_QUAD_FROZEN_FIELD 1
728#define STV090x_OFFST_Px_QUAD_CORRECT_FIELD 2
729#define STV090x_WIDTH_Px_QUAD_CORRECT_FIELD 1
730
731#define STV090x_Px_AGC1CN(__x) (0xF406 - (__x - 1) * 0x200)
732#define STV090x_P1_AGC1CN STV090x_Px_AGC1CN(1)
733#define STV090x_P2_AGC1CN STV090x_Px_AGC1CN(2)
734#define STV090x_WIDTH_Px_AGC1_LOCKED_FIELD 7
735#define STV090x_OFFST_Px_AGC1_LOCKED_FIELD 1
736#define STV090x_OFFST_Px_AGC1_MINPOWER_FIELD 4
737#define STV090x_WIDTH_Px_AGC1_MINPOWER_FIELD 1
738#define STV090x_OFFST_Px_AGCOUT_FAST_FIELD 3
739#define STV090x_WIDTH_Px_AGCOUT_FAST_FIELD 1
740#define STV090x_OFFST_Px_AGCIQ_BETA_FIELD 0
741#define STV090x_WIDTH_Px_AGCIQ_BETA_FIELD 3
742
743#define STV090x_Px_AGC1REF(__x) (0xF407 - (__x - 1) * 0x200)
744#define STV090x_P1_AGC1REF STV090x_Px_AGC1REF(1)
745#define STV090x_P2_AGC1REF STV090x_Px_AGC1REF(2)
746#define STV090x_OFFST_Px_AGCIQ_REF_FIELD 0
747#define STV090x_WIDTH_Px_AGCIQ_REF_FIELD 8
748
749#define STV090x_Px_IDCCOMP(__x) (0xF408 - (__x - 1) * 0x200)
750#define STV090x_P1_IDCCOMP STV090x_Px_IDCCOMP(1)
751#define STV090x_P2_IDCCOMP STV090x_Px_IDCCOMP(2)
752#define STV090x_OFFST_Px_IAVERAGE_ADJ_FIELD 0
753#define STV090x_WIDTH_Px_IAVERAGE_ADJ_FIELD 8
754
755#define STV090x_Px_QDCCOMP(__x) (0xF409 - (__x - 1) * 0x200)
756#define STV090x_P1_QDCCOMP STV090x_Px_QDCCOMP(1)
757#define STV090x_P2_QDCCOMP STV090x_Px_QDCCOMP(2)
758#define STV090x_OFFST_Px_QAVERAGE_ADJ_FIELD 0
759#define STV090x_WIDTH_Px_QAVERAGE_ADJ_FIELD 8
760
761#define STV090x_Px_POWERI(__x) (0xF40A - (__x - 1) * 0x200)
762#define STV090x_P1_POWERI STV090x_Px_POWERI(1)
763#define STV090x_P2_POWERI STV090x_Px_POWERI(2)
764#define STV090x_OFFST_Px_POWER_I_FIELD 0
765#define STV090x_WIDTH_Px_POWER_I_FIELD 8
766
767#define STV090x_Px_POWERQ(__x) (0xF40B - (__x - 1) * 0x200)
768#define STV090x_P1_POWERQ STV090x_Px_POWERQ(1)
769#define STV090x_P2_POWERQ STV090x_Px_POWERQ(2)
770#define STV090x_OFFST_Px_POWER_Q_FIELD 0
771#define STV090x_WIDTH_Px_POWER_Q_FIELD 8
772
773#define STV090x_Px_AGC1AMM(__x) (0xF40C - (__x - 1) * 0x200)
774#define STV090x_P1_AGC1AMM STV090x_Px_AGC1AMM(1)
775#define STV090x_P2_AGC1AMM STV090x_Px_AGC1AMM(2)
776#define STV090x_OFFST_Px_AMM_VALUE_FIELD 0
777#define STV090x_WIDTH_Px_AMM_VALUE_FIELD 8
778
779#define STV090x_Px_AGC1QUAD(__x) (0xF40D - (__x - 1) * 0x200)
780#define STV090x_P1_AGC1QUAD STV090x_Px_AGC1QUAD(1)
781#define STV090x_P2_AGC1QUAD STV090x_Px_AGC1QUAD(2)
782#define STV090x_OFFST_Px_QUAD_VALUE_FIELD 0
783#define STV090x_WIDTH_Px_QUAD_VALUE_FIELD 8
784
785#define STV090x_Px_AGCIQINy(__x, __y) (0xF40F - (__x-1) * 0x200 - __y * 0x1)
786#define STV090x_P1_AGCIQIN0 STV090x_Px_AGCIQINy(1, 0)
787#define STV090x_P1_AGCIQIN1 STV090x_Px_AGCIQINy(1, 1)
788#define STV090x_P2_AGCIQIN0 STV090x_Px_AGCIQINy(2, 0)
789#define STV090x_P2_AGCIQIN1 STV090x_Px_AGCIQINy(2, 1)
790#define STV090x_OFFST_Px_AGCIQ_VALUE_FIELD 0
791#define STV090x_WIDTH_Px_AGCIQ_VALUE_FIELD 8
792
793#define STV090x_Px_DEMOD(__x) (0xF410 - (__x - 1) * 0x200)
794#define STV090x_P1_DEMOD STV090x_Px_DEMOD(1)
795#define STV090x_P2_DEMOD STV090x_Px_DEMOD(2)
796#define STV090x_OFFST_Px_MANUAL_S2ROLLOFF_FIELD 7
797#define STV090x_WIDTH_Px_MANUAL_S2ROLLOFF_FIELD 1
798#define STV090x_OFFST_Px_DEMOD_STOP_FIELD 6
799#define STV090x_WIDTH_Px_DEMOD_STOP_FIELD 1
800#define STV090x_OFFST_Px_SPECINV_CONTROL_FIELD 4
801#define STV090x_WIDTH_Px_SPECINV_CONTROL_FIELD 2
802#define STV090x_OFFST_Px_FORCE_ENASAMP_FIELD 3
803#define STV090x_WIDTH_Px_FORCE_ENASAMP_FIELD 1
804#define STV090x_OFFST_Px_MANUAL_SXROLLOFF_FIELD 2
805#define STV090x_WIDTH_Px_MANUAL_SXROLLOFF_FIELD 1
806#define STV090x_OFFST_Px_ROLLOFF_CONTROL_FIELD 0
807#define STV090x_WIDTH_Px_ROLLOFF_CONTROL_FIELD 2
808
809#define STV090x_Px_DMDMODCOD(__x) (0xF411 - (__x - 1) * 0x200)
810#define STV090x_P1_DMDMODCOD STV090x_Px_DMDMODCOD(1)
811#define STV090x_P2_DMDMODCOD STV090x_Px_DMDMODCOD(2)
812#define STV090x_OFFST_Px_MANUAL_MODCOD_FIELD 7
813#define STV090x_WIDTH_Px_MANUAL_MODCOD_FIELD 1
814#define STV090x_OFFST_Px_DEMOD_MODCOD_FIELD 2
815#define STV090x_WIDTH_Px_DEMOD_MODCOD_FIELD 5
816#define STV090x_OFFST_Px_DEMOD_TYPE_FIELD 0
817#define STV090x_WIDTH_Px_DEMOD_TYPE_FIELD 2
818
819#define STV090x_Px_DSTATUS(__x) (0xF412 - (__x - 1) * 0x200)
820#define STV090x_P1_DSTATUS STV090x_Px_DSTATUS(1)
821#define STV090x_P2_DSTATUS STV090x_Px_DSTATUS(2)
822#define STV090x_OFFST_Px_CAR_LOCK_FIELD 7
823#define STV090x_WIDTH_Px_CAR_LOCK_FIELD 1
824#define STV090x_OFFST_Px_TMGLOCK_QUALITY_FIELD 5
825#define STV090x_WIDTH_Px_TMGLOCK_QUALITY_FIELD 2
826#define STV090x_OFFST_Px_LOCK_DEFINITIF_FIELD 3
827#define STV090x_WIDTH_Px_LOCK_DEFINITIF_FIELD 1
828
829#define STV090x_Px_DSTATUS2(__x) (0xF413 - (__x - 1) * 0x200)
830#define STV090x_P1_DSTATUS2 STV090x_Px_DSTATUS2(1)
831#define STV090x_P2_DSTATUS2 STV090x_Px_DSTATUS2(2)
832#define STV090x_OFFST_Px_DEMOD_DELOCK_FIELD 7
833#define STV090x_WIDTH_Px_DEMOD_DELOCK_FIELD 1
834#define STV090x_OFFST_Px_AGC1_NOSIGNALACK_FIELD 3
835#define STV090x_WIDTH_Px_AGC1_NOSIGNALACK_FIELD 1
836#define STV090x_OFFST_Px_AGC2_OVERFLOW_FIELD 2
837#define STV090x_WIDTH_Px_AGC2_OVERFLOW_FIELD 1
838#define STV090x_OFFST_Px_CFR_OVERFLOW_FIELD 1
839#define STV090x_WIDTH_Px_CFR_OVERFLOW_FIELD 1
840#define STV090x_OFFST_Px_GAMMA_OVERUNDER_FIELD 0
841#define STV090x_WIDTH_Px_GAMMA_OVERUNDER_FIELD 1
842
843#define STV090x_Px_DMDCFGMD(__x) (0xF414 - (__x - 1) * 0x200)
844#define STV090x_P1_DMDCFGMD STV090x_Px_DMDCFGMD(1)
845#define STV090x_P2_DMDCFGMD STV090x_Px_DMDCFGMD(2)
846#define STV090x_OFFST_Px_DVBS2_ENABLE_FIELD 7
847#define STV090x_WIDTH_Px_DVBS2_ENABLE_FIELD 1
848#define STV090x_OFFST_Px_DVBS1_ENABLE_FIELD 6
849#define STV090x_WIDTH_Px_DVBS1_ENABLE_FIELD 1
850#define STV090x_OFFST_Px_SCAN_ENABLE_FIELD 4
851#define STV090x_WIDTH_Px_SCAN_ENABLE_FIELD 1
852#define STV090x_OFFST_Px_CFR_AUTOSCAN_FIELD 3
853#define STV090x_WIDTH_Px_CFR_AUTOSCAN_FIELD 1
854#define STV090x_OFFST_Px_NOFORCE_RELOCK_FIELD 2
855#define STV090x_WIDTH_Px_NOFORCE_RELOCK_FIELD 1
856#define STV090x_OFFST_Px_TUN_RNG_FIELD 0
857#define STV090x_WIDTH_Px_TUN_RNG_FIELD 2
858
859#define STV090x_Px_DMDCFG2(__x) (0xF415 - (__x - 1) * 0x200)
860#define STV090x_P1_DMDCFG2 STV090x_Px_DMDCFG2(1)
861#define STV090x_P2_DMDCFG2 STV090x_Px_DMDCFG2(2)
862#define STV090x_OFFST_Px_S1S2_SEQUENTIAL_FIELD 6
863#define STV090x_WIDTH_Px_S1S2_SEQUENTIAL_FIELD 1
864
865#define STV090x_Px_DMDISTATE(__x) (0xF416 - (__x - 1) * 0x200)
866#define STV090x_P1_DMDISTATE STV090x_Px_DMDISTATE(1)
867#define STV090x_P2_DMDISTATE STV090x_Px_DMDISTATE(2)
868#define STV090x_OFFST_Px_I2C_DEMOD_MODE_FIELD 0
869#define STV090x_WIDTH_Px_I2C_DEMOD_MODE_FIELD 5
870
871#define STV090x_Px_DMDTOM(__x) (0xF417 - (__x - 1) * 0x200) /* check */
872#define STV090x_P1_DMDTOM STV090x_Px_DMDTOM(1)
873#define STV090x_P2_DMDTOM STV090x_Px_DMDTOM(2)
874
875#define STV090x_Px_DMDSTATE(__x) (0xF41B - (__x - 1) * 0x200)
876#define STV090x_P1_DMDSTATE STV090x_Px_DMDSTATE(1)
877#define STV090x_P2_DMDSTATE STV090x_Px_DMDSTATE(2)
878#define STV090x_OFFST_Px_HEADER_MODE_FIELD 5
879#define STV090x_WIDTH_Px_HEADER_MODE_FIELD 2
880
881#define STV090x_Px_DMDFLYW(__x) (0xF41C - (__x - 1) * 0x200)
882#define STV090x_P1_DMDFLYW STV090x_Px_DMDFLYW(1)
883#define STV090x_P2_DMDFLYW STV090x_Px_DMDFLYW(2)
884#define STV090x_OFFST_Px_I2C_IRQVAL_FIELD 4
885#define STV090x_WIDTH_Px_I2C_IRQVAL_FIELD 4
886#define STV090x_OFFST_Px_FLYWHEEL_CPT_FIELD 0
887#define STV090x_WIDTH_Px_FLYWHEEL_CPT_FIELD 4
888
889#define STV090x_Px_DSTATUS3(__x) (0xF41D - (__x - 1) * 0x200)
890#define STV090x_P1_DSTATUS3 STV090x_Px_DSTATUS3(1)
891#define STV090x_P2_DSTATUS3 STV090x_Px_DSTATUS3(2)
892#define STV090x_OFFST_Px_DEMOD_CFGMODE_FIELD 5
893#define STV090x_WIDTH_Px_DEMOD_CFGMODE_FIELD 2
894
895#define STV090x_Px_DMDCFG3(__x) (0xF41E - (__x - 1) * 0x200)
896#define STV090x_P1_DMDCFG3 STV090x_Px_DMDCFG3(1)
897#define STV090x_P2_DMDCFG3 STV090x_Px_DMDCFG3(2)
898#define STV090x_OFFST_Px_NOSTOP_FIFOFULL_FIELD 3
899#define STV090x_WIDTH_Px_NOSTOP_FIFOFULL_FIELD 1
900
901#define STV090x_Px_DMDCFG4(__x) (0xf41f - (__x - 1) * 0x200)
902#define STV090x_P1_DMDCFG4 STV090x_Px_DMDCFG4(1)
903#define STV090x_P2_DMDCFG4 STV090x_Px_DMDCFG4(2)
904
905#define STV090x_Px_CORRELMANT(__x) (0xF420 - (__x - 1) * 0x200)
906#define STV090x_P1_CORRELMANT STV090x_Px_CORRELMANT(1)
907#define STV090x_P2_CORRELMANT STV090x_Px_CORRELMANT(2)
908#define STV090x_OFFST_Px_CORREL_MANT_FIELD 0
909#define STV090x_WIDTH_Px_CORREL_MANT_FIELD 8
910
911#define STV090x_Px_CORRELABS(__x) (0xF421 - (__x - 1) * 0x200)
912#define STV090x_P1_CORRELABS STV090x_Px_CORRELABS(1)
913#define STV090x_P2_CORRELABS STV090x_Px_CORRELABS(2)
914#define STV090x_OFFST_Px_CORREL_ABS_FIELD 0
915#define STV090x_WIDTH_Px_CORREL_ABS_FIELD 8
916
917#define STV090x_Px_CORRELEXP(__x) (0xF422 - (__x - 1) * 0x200)
918#define STV090x_P1_CORRELEXP STV090x_Px_CORRELEXP(1)
919#define STV090x_P2_CORRELEXP STV090x_Px_CORRELEXP(2)
920#define STV090x_OFFST_Px_CORREL_ABSEXP_FIELD 4
921#define STV090x_WIDTH_Px_CORREL_ABSEXP_FIELD 4
922#define STV090x_OFFST_Px_CORREL_EXP_FIELD 0
923#define STV090x_WIDTH_Px_CORREL_EXP_FIELD 4
924
925#define STV090x_Px_PLHMODCOD(__x) (0xF424 - (__x - 1) * 0x200)
926#define STV090x_P1_PLHMODCOD STV090x_Px_PLHMODCOD(1)
927#define STV090x_P2_PLHMODCOD STV090x_Px_PLHMODCOD(2)
928#define STV090x_OFFST_Px_SPECINV_DEMOD_FIELD 7
929#define STV090x_WIDTH_Px_SPECINV_DEMOD_FIELD 1
930#define STV090x_OFFST_Px_PLH_MODCOD_FIELD 2
931#define STV090x_WIDTH_Px_PLH_MODCOD_FIELD 5
932#define STV090x_OFFST_Px_PLH_TYPE_FIELD 0
933#define STV090x_WIDTH_Px_PLH_TYPE_FIELD 2
934
935#define STV090x_Px_AGCK32(__x) (0xf42b - (__x - 1) * 0x200)
936#define STV090x_P1_AGCK32 STV090x_Px_AGCK32(1)
937#define STV090x_P2_AGCK32 STV090x_Px_AGCK32(2)
938
939#define STV090x_Px_AGC2O(__x) (0xF42C - (__x - 1) * 0x200)
940#define STV090x_P1_AGC2O STV090x_Px_AGC2O(1)
941#define STV090x_P2_AGC2O STV090x_Px_AGC2O(2)
942
943#define STV090x_Px_AGC2REF(__x) (0xF42D - (__x - 1) * 0x200)
944#define STV090x_P1_AGC2REF STV090x_Px_AGC2REF(1)
945#define STV090x_P2_AGC2REF STV090x_Px_AGC2REF(2)
946#define STV090x_OFFST_Px_AGC2_REF_FIELD 0
947#define STV090x_WIDTH_Px_AGC2_REF_FIELD 8
948
949#define STV090x_Px_AGC1ADJ(__x) (0xF42E - (__x - 1) * 0x200)
950#define STV090x_P1_AGC1ADJ STV090x_Px_AGC1ADJ(1)
951#define STV090x_P2_AGC1ADJ STV090x_Px_AGC1ADJ(2)
952#define STV090x_OFFST_Px_AGC1_ADJUSTED_FIELD 0
953#define STV090x_WIDTH_Px_AGC1_ADJUSTED_FIELD 7
954
955#define STV090x_Px_AGC2Iy(__x, __y) (0xF437 - (__x - 1) * 0x200 - __y * 0x1)
956#define STV090x_P1_AGC2I0 STV090x_Px_AGC2Iy(1, 0)
957#define STV090x_P1_AGC2I1 STV090x_Px_AGC2Iy(1, 1)
958#define STV090x_P2_AGC2I0 STV090x_Px_AGC2Iy(2, 0)
959#define STV090x_P2_AGC2I1 STV090x_Px_AGC2Iy(2, 1)
960#define STV090x_OFFST_Px_AGC2_INTEGRATOR_FIELD 0
961#define STV090x_WIDTH_Px_AGC2_INTEGRATOR_FIELD 8
962
963#define STV090x_Px_CARCFG(__x) (0xF438 - (__x - 1) * 0x200)
964#define STV090x_P1_CARCFG STV090x_Px_CARCFG(1)
965#define STV090x_P2_CARCFG STV090x_Px_CARCFG(2)
966#define STV090x_OFFST_Px_EN_CAR2CENTER_FIELD 5
967#define STV090x_WIDTH_Px_EN_CAR2CENTER_FIELD 1
968#define STV090x_OFFST_Px_ROTATON_FIELD 2
969#define STV090x_WIDTH_Px_ROTATON_FIELD 1
970#define STV090x_OFFST_Px_PH_DET_ALGO_FIELD 0
971#define STV090x_WIDTH_Px_PH_DET_ALGO_FIELD 2
972
973#define STV090x_Px_ACLC(__x) (0xF439 - (__x - 1) * 0x200)
974#define STV090x_P1_ACLC STV090x_Px_ACLC(1)
975#define STV090x_P2_ACLC STV090x_Px_ACLC(2)
976#define STV090x_OFFST_Px_CAR_ALPHA_MANT_FIELD 4
977#define STV090x_WIDTH_Px_CAR_ALPHA_MANT_FIELD 2
978#define STV090x_OFFST_Px_CAR_ALPHA_EXP_FIELD 0
979#define STV090x_WIDTH_Px_CAR_ALPHA_EXP_FIELD 4
980
981#define STV090x_Px_BCLC(__x) (0xF43A - (__x - 1) * 0x200)
982#define STV090x_P1_BCLC STV090x_Px_BCLC(1)
983#define STV090x_P2_BCLC STV090x_Px_BCLC(2)
984#define STV090x_OFFST_Px_CAR_BETA_MANT_FIELD 4
985#define STV090x_WIDTH_Px_CAR_BETA_MANT_FIELD 2
986#define STV090x_OFFST_Px_CAR_BETA_EXP_FIELD 0
987#define STV090x_WIDTH_Px_CAR_BETA_EXP_FIELD 4
988
989#define STV090x_Px_CARFREQ(__x) (0xF43D - (__x - 1) * 0x200)
990#define STV090x_P1_CARFREQ STV090x_Px_CARFREQ(1)
991#define STV090x_P2_CARFREQ STV090x_Px_CARFREQ(2)
992#define STV090x_OFFST_Px_KC_COARSE_EXP_FIELD 4
993#define STV090x_WIDTH_Px_KC_COARSE_EXP_FIELD 4
994#define STV090x_OFFST_Px_BETA_FREQ_FIELD 0
995#define STV090x_WIDTH_Px_BETA_FREQ_FIELD 4
996
997#define STV090x_Px_CARHDR(__x) (0xF43E - (__x - 1) * 0x200)
998#define STV090x_P1_CARHDR STV090x_Px_CARHDR(1)
999#define STV090x_P2_CARHDR STV090x_Px_CARHDR(2)
1000#define STV090x_OFFST_Px_FREQ_HDR_FIELD 0
1001#define STV090x_WIDTH_Px_FREQ_HDR_FIELD 8
1002
1003#define STV090x_Px_LDT(__x) (0xF43F - (__x - 1) * 0x200)
1004#define STV090x_P1_LDT STV090x_Px_LDT(1)
1005#define STV090x_P2_LDT STV090x_Px_LDT(2)
1006#define STV090x_OFFST_Px_CARLOCK_THRES_FIELD 0
1007#define STV090x_WIDTH_Px_CARLOCK_THRES_FIELD 8
1008
1009#define STV090x_Px_LDT2(__x) (0xF440 - (__x - 1) * 0x200)
1010#define STV090x_P1_LDT2 STV090x_Px_LDT2(1)
1011#define STV090x_P2_LDT2 STV090x_Px_LDT2(2)
1012#define STV090x_OFFST_Px_CARLOCK_THRES2_FIELD 0
1013#define STV090x_WIDTH_Px_CARLOCK_THRES2_FIELD 8
1014
1015#define STV090x_Px_CFRICFG(__x) (0xF441 - (__x - 1) * 0x200)
1016#define STV090x_P1_CFRICFG STV090x_Px_CFRICFG(1)
1017#define STV090x_P2_CFRICFG STV090x_Px_CFRICFG(2)
1018#define STV090x_OFFST_Px_NEG_CFRSTEP_FIELD 0
1019#define STV090x_WIDTH_Px_NEG_CFRSTEP_FIELD 1
1020
1021#define STV090x_Pn_CFRUPy(__x, __y) (0xF443 - (__x - 1) * 0x200 - __y * 0x1)
1022#define STV090x_P1_CFRUP0 STV090x_Pn_CFRUPy(1, 0)
1023#define STV090x_P1_CFRUP1 STV090x_Pn_CFRUPy(1, 1)
1024#define STV090x_P2_CFRUP0 STV090x_Pn_CFRUPy(2, 0)
1025#define STV090x_P2_CFRUP1 STV090x_Pn_CFRUPy(2, 1)
1026#define STV090x_OFFST_Px_CFR_UP_FIELD 0
1027#define STV090x_WIDTH_Px_CFR_UP_FIELD 8
1028
1029#define STV090x_Pn_CFRLOWy(__x, __y) (0xF447 - (__x - 1) * 0x200 - __y * 0x1)
1030#define STV090x_P1_CFRLOW0 STV090x_Pn_CFRLOWy(1, 0)
1031#define STV090x_P1_CFRLOW1 STV090x_Pn_CFRLOWy(1, 1)
1032#define STV090x_P2_CFRLOW0 STV090x_Pn_CFRLOWy(2, 0)
1033#define STV090x_P2_CFRLOW1 STV090x_Pn_CFRLOWy(2, 1)
1034#define STV090x_OFFST_Px_CFR_LOW_FIELD 0
1035#define STV090x_WIDTH_Px_CFR_LOW_FIELD 8
1036
1037#define STV090x_Pn_CFRINITy(__x, __y) (0xF449 - (__x - 1) * 0x200 - __y * 0x1)
1038#define STV090x_P1_CFRINIT0 STV090x_Pn_CFRINITy(1, 0)
1039#define STV090x_P1_CFRINIT1 STV090x_Pn_CFRINITy(1, 1)
1040#define STV090x_P2_CFRINIT0 STV090x_Pn_CFRINITy(2, 0)
1041#define STV090x_P2_CFRINIT1 STV090x_Pn_CFRINITy(2, 1)
1042#define STV090x_OFFST_Px_CFR_INIT_FIELD 0
1043#define STV090x_WIDTH_Px_CFR_INIT_FIELD 8
1044
1045#define STV090x_Px_CFRINC1(__x) (0xF44A - (__x - 1) * 0x200)
1046#define STV090x_P1_CFRINC1 STV090x_Px_CFRINC1(1)
1047#define STV090x_P2_CFRINC1 STV090x_Px_CFRINC1(2)
1048#define STV090x_OFFST_Px_CFR_INC1_FIELD 0
1049#define STV090x_WIDTH_Px_CFR_INC1_FIELD 7 /* check */
1050
1051#define STV090x_Px_CFRINC0(__x) (0xF44B - (__x - 1) * 0x200)
1052#define STV090x_P1_CFRINC0 STV090x_Px_CFRINC0(1)
1053#define STV090x_P2_CFRINC0 STV090x_Px_CFRINC0(2)
1054#define STV090x_OFFST_Px_CFR_INC0_FIELD 4 /* check */
1055#define STV090x_WIDTH_Px_CFR_INC0_FIELD 4
1056
1057#define STV090x_Pn_CFRy(__x, __y) (0xF44E - (__x - 1) * 0x200 - __y * 0x1)
1058#define STV090x_P1_CFR0 STV090x_Pn_CFRy(1, 0)
1059#define STV090x_P1_CFR1 STV090x_Pn_CFRy(1, 1)
1060#define STV090x_P1_CFR2 STV090x_Pn_CFRy(1, 2)
1061#define STV090x_P2_CFR0 STV090x_Pn_CFRy(2, 0)
1062#define STV090x_P2_CFR1 STV090x_Pn_CFRy(2, 1)
1063#define STV090x_P2_CFR2 STV090x_Pn_CFRy(2, 2)
1064#define STV090x_OFFST_Px_CAR_FREQ_FIELD 0
1065#define STV090x_WIDTH_Px_CAR_FREQ_FIELD 8
1066
1067#define STV090x_Px_LDI(__x) (0xF44F - (__x - 1) * 0x200)
1068#define STV090x_P1_LDI STV090x_Px_LDI(1)
1069#define STV090x_P2_LDI STV090x_Px_LDI(2)
1070#define STV090x_OFFST_Px_LOCK_DET_INTEGR_FIELD 0
1071#define STV090x_WIDTH_Px_LOCK_DET_INTEGR_FIELD 8
1072
1073#define STV090x_Px_TMGCFG(__x) (0xF450 - (__x - 1) * 0x200)
1074#define STV090x_P1_TMGCFG STV090x_Px_TMGCFG(1)
1075#define STV090x_P2_TMGCFG STV090x_Px_TMGCFG(2)
1076#define STV090x_OFFST_Px_TMGLOCK_BETA_FIELD 6
1077#define STV090x_WIDTH_Px_TMGLOCK_BETA_FIELD 2
1078#define STV090x_OFFST_Px_DO_TIMING_FIELD 4
1079#define STV090x_WIDTH_Px_DO_TIMING_FIELD 1
1080#define STV090x_OFFST_Px_TMG_MINFREQ_FIELD 0
1081#define STV090x_WIDTH_Px_TMG_MINFREQ_FIELD 2
1082
1083#define STV090x_Px_RTC(__x) (0xF451 - (__x - 1) * 0x200)
1084#define STV090x_P1_RTC STV090x_Px_RTC(1)
1085#define STV090x_P2_RTC STV090x_Px_RTC(2)
1086#define STV090x_OFFST_Px_TMGALPHA_EXP_FIELD 4
1087#define STV090x_WIDTH_Px_TMGALPHA_EXP_FIELD 4
1088#define STV090x_OFFST_Px_TMGBETA_EXP_FIELD 0
1089#define STV090x_WIDTH_Px_TMGBETA_EXP_FIELD 4
1090
1091#define STV090x_Px_RTCS2(__x) (0xF452 - (__x - 1) * 0x200)
1092#define STV090x_P1_RTCS2 STV090x_Px_RTCS2(1)
1093#define STV090x_P2_RTCS2 STV090x_Px_RTCS2(2)
1094#define STV090x_OFFST_Px_TMGALPHAS2_EXP_FIELD 4
1095#define STV090x_WIDTH_Px_TMGALPHAS2_EXP_FIELD 4
1096#define STV090x_OFFST_Px_TMGBETAS2_EXP_FIELD 0
1097#define STV090x_WIDTH_Px_TMGBETAS2_EXP_FIELD 4
1098
1099#define STV090x_Px_TMGTHRISE(__x) (0xF453 - (__x - 1) * 0x200)
1100#define STV090x_P1_TMGTHRISE STV090x_Px_TMGTHRISE(1)
1101#define STV090x_P2_TMGTHRISE STV090x_Px_TMGTHRISE(2)
1102#define STV090x_OFFST_Px_TMGLOCK_THRISE_FIELD 0
1103#define STV090x_WIDTH_Px_TMGLOCK_THRISE_FIELD 8
1104
1105#define STV090x_Px_TMGTHFALL(__x) (0xF454 - (__x - 1) * 0x200)
1106#define STV090x_P1_TMGTHFALL STV090x_Px_TMGTHFALL(1)
1107#define STV090x_P2_TMGTHFALL STV090x_Px_TMGTHFALL(2)
1108#define STV090x_OFFST_Px_TMGLOCK_THFALL_FIELD 0
1109#define STV090x_WIDTH_Px_TMGLOCK_THFALL_FIELD 8
1110
1111#define STV090x_Px_SFRUPRATIO(__x) (0xF455 - (__x - 1) * 0x200)
1112#define STV090x_P1_SFRUPRATIO STV090x_Px_SFRUPRATIO(1)
1113#define STV090x_P2_SFRUPRATIO STV090x_Px_SFRUPRATIO(2)
1114#define STV090x_OFFST_Px_SFR_UPRATIO_FIELD 0
1115#define STV090x_WIDTH_Px_SFR_UPRATIO_FIELD 8
1116
1117#define STV090x_Px_SFRLOWRATIO(__x) (0xF456 - (__x - 1) * 0x200)
1118#define STV090x_P1_SFRLOWRATIO STV090x_Px_SFRLOWRATIO(1)
1119#define STV090x_P2_SFRLOWRATIO STV090x_Px_SFRLOWRATIO(2)
1120#define STV090x_OFFST_Px_SFR_LOWRATIO_FIELD 0
1121#define STV090x_WIDTH_Px_SFR_LOWRATIO_FIELD 8
1122
1123#define STV090x_Px_KREFTMG(__x) (0xF458 - (__x - 1) * 0x200)
1124#define STV090x_P1_KREFTMG STV090x_Px_KREFTMG(1)
1125#define STV090x_P2_KREFTMG STV090x_Px_KREFTMG(2)
1126#define STV090x_OFFST_Px_KREF_TMG_FIELD 0
1127#define STV090x_WIDTH_Px_KREF_TMG_FIELD 8
1128
1129#define STV090x_Px_SFRSTEP(__x) (0xF459 - (__x - 1) * 0x200)
1130#define STV090x_P1_SFRSTEP STV090x_Px_SFRSTEP(1)
1131#define STV090x_P2_SFRSTEP STV090x_Px_SFRSTEP(2)
1132#define STV090x_OFFST_Px_SFR_SCANSTEP_FIELD 4
1133#define STV090x_WIDTH_Px_SFR_SCANSTEP_FIELD 4
1134#define STV090x_OFFST_Px_SFR_CENTERSTEP_FIELD 0
1135#define STV090x_WIDTH_Px_SFR_CENTERSTEP_FIELD 4
1136
1137#define STV090x_Px_TMGCFG2(__x) (0xF45A - (__x - 1) * 0x200)
1138#define STV090x_P1_TMGCFG2 STV090x_Px_TMGCFG2(1)
1139#define STV090x_P2_TMGCFG2 STV090x_Px_TMGCFG2(2)
1140#define STV090x_OFFST_Px_SFRRATIO_FINE_FIELD 0
1141#define STV090x_WIDTH_Px_SFRRATIO_FINE_FIELD 1
1142
1143#define STV090x_Px_SFRINIT1(__x) (0xF45E - (__x - 1) * 0x200)
1144#define STV090x_P1_SFRINIT1 STV090x_Px_SFRINIT1(1)
1145#define STV090x_P2_SFRINIT1 STV090x_Px_SFRINIT1(2)
1146#define STV090x_OFFST_Px_SFR_INIT1_FIELD 0
1147#define STV090x_WIDTH_Px_SFR_INIT1_FIELD 7
1148
1149#define STV090x_Px_SFRINIT0(__x) (0xF45F - (__x - 1) * 0x200)
1150#define STV090x_P1_SFRINIT0 STV090x_Px_SFRINIT0(1)
1151#define STV090x_P2_SFRINIT0 STV090x_Px_SFRINIT0(2)
1152#define STV090x_OFFST_Px_SFR_INIT0_FIELD 0
1153#define STV090x_WIDTH_Px_SFR_INIT0_FIELD 8
1154
1155#define STV090x_Px_SFRUP1(__x) (0xF460 - (__x - 1) * 0x200)
1156#define STV090x_P1_SFRUP1 STV090x_Px_SFRUP1(1)
1157#define STV090x_P2_SFRUP1 STV090x_Px_SFRUP1(2)
1158#define STV090x_OFFST_Px_SYMB_FREQ_UP1_FIELD 0
1159#define STV090x_WIDTH_Px_SYMB_FREQ_UP1_FIELD 7
1160
1161#define STV090x_Px_SFRUP0(__x) (0xF461 - (__x - 1) * 0x200)
1162#define STV090x_P1_SFRUP0 STV090x_Px_SFRUP0(1)
1163#define STV090x_P2_SFRUP0 STV090x_Px_SFRUP0(2)
1164#define STV090x_OFFST_Px_SYMB_FREQ_UP0_FIELD 0
1165#define STV090x_WIDTH_Px_SYMB_FREQ_UP0_FIELD 8
1166
1167#define STV090x_Px_SFRLOW1(__x) (0xF462 - (__x - 1) * 0x200)
1168#define STV090x_P1_SFRLOW1 STV090x_Px_SFRLOW1(1)
1169#define STV090x_P2_SFRLOW1 STV090x_Px_SFRLOW1(2)
1170#define STV090x_OFFST_Px_SYMB_FREQ_LOW1_FIELD 0
1171#define STV090x_WIDTH_Px_SYMB_FREQ_LOW1_FIELD 7
1172
1173#define STV090x_Px_SFRLOW0(__x) (0xF463 - (__x - 1) * 0x200)
1174#define STV090x_P1_SFRLOW0 STV090x_Px_SFRLOW0(1)
1175#define STV090x_P2_SFRLOW0 STV090x_Px_SFRLOW0(2)
1176#define STV090x_OFFST_Px_SYMB_FREQ_LOW0_FIELD 0
1177#define STV090x_WIDTH_Px_SYMB_FREQ_LOW0_FIELD 8
1178
1179#define STV090x_Px_SFRy(__x, __y) (0xF467 - (__x-1) * 0x200 - __y)
1180#define STV090x_P1_SFR0 STV090x_Px_SFRy(1, 0)
1181#define STV090x_P1_SFR1 STV090x_Px_SFRy(1, 1)
1182#define STV090x_P1_SFR2 STV090x_Px_SFRy(1, 2)
1183#define STV090x_P1_SFR3 STV090x_Px_SFRy(1, 3)
1184#define STV090x_P2_SFR0 STV090x_Px_SFRy(2, 0)
1185#define STV090x_P2_SFR1 STV090x_Px_SFRy(2, 1)
1186#define STV090x_P2_SFR2 STV090x_Px_SFRy(2, 2)
1187#define STV090x_P2_SFR3 STV090x_Px_SFRy(2, 3)
1188#define STV090x_OFFST_Px_SYMB_FREQ_FIELD 0
1189#define STV090x_WIDTH_Px_SYMB_FREQ_FIELD 8
1190
1191#define STV090x_Px_TMGREG2(__x) (0xF468 - (__x - 1) * 0x200)
1192#define STV090x_P1_TMGREG2 STV090x_Px_TMGREG2(1)
1193#define STV090x_P2_TMGREG2 STV090x_Px_TMGREG2(2)
1194#define STV090x_OFFST_Px_TMGREG_FIELD 0
1195#define STV090x_WIDTH_Px_TMGREG_FIELD 8
1196
1197#define STV090x_Px_TMGREG1(__x) (0xF469 - (__x - 1) * 0x200)
1198#define STV090x_P1_TMGREG1 STV090x_Px_TMGREG1(1)
1199#define STV090x_P2_TMGREG1 STV090x_Px_TMGREG1(2)
1200#define STV090x_OFFST_Px_TMGREG_FIELD 0
1201#define STV090x_WIDTH_Px_TMGREG_FIELD 8
1202
1203#define STV090x_Px_TMGREG0(__x) (0xF46A - (__x - 1) * 0x200)
1204#define STV090x_P1_TMGREG0 STV090x_Px_TMGREG0(1)
1205#define STV090x_P2_TMGREG0 STV090x_Px_TMGREG0(2)
1206#define STV090x_OFFST_Px_TMGREG_FIELD 0
1207#define STV090x_WIDTH_Px_TMGREG_FIELD 8
1208
1209#define STV090x_Px_TMGLOCKy(__x, __y) (0xF46C - (__x - 1) * 0x200 - __y * 0x1)
1210#define STV090x_P1_TMGLOCK0 STV090x_Px_TMGLOCKy(1, 0)
1211#define STV090x_P1_TMGLOCK1 STV090x_Px_TMGLOCKy(1, 1)
1212#define STV090x_P2_TMGLOCK0 STV090x_Px_TMGLOCKy(2, 0)
1213#define STV090x_P2_TMGLOCK1 STV090x_Px_TMGLOCKy(2, 1)
1214#define STV090x_OFFST_Px_TMGLOCK_LEVEL_FIELD 0
1215#define STV090x_WIDTH_Px_TMGLOCK_LEVEL_FIELD 8
1216
1217#define STV090x_Px_TMGOBS(__x) (0xF46D - (__x - 1) * 0x200)
1218#define STV090x_P1_TMGOBS STV090x_Px_TMGOBS(1)
1219#define STV090x_P2_TMGOBS STV090x_Px_TMGOBS(2)
1220#define STV090x_OFFST_Px_ROLLOFF_STATUS_FIELD 6
1221#define STV090x_WIDTH_Px_ROLLOFF_STATUS_FIELD 2
1222
1223#define STV090x_Px_EQUALCFG(__x) (0xF46F - (__x - 1) * 0x200)
1224#define STV090x_P1_EQUALCFG STV090x_Px_EQUALCFG(1)
1225#define STV090x_P2_EQUALCFG STV090x_Px_EQUALCFG(2)
1226#define STV090x_OFFST_Px_EQUAL_ON_FIELD 6
1227#define STV090x_WIDTH_Px_EQUAL_ON_FIELD 1
1228#define STV090x_OFFST_Px_MU_EQUALDFE_FIELD 0
1229#define STV090x_WIDTH_Px_MU_EQUALDFE_FIELD 3
1230
1231#define STV090x_Px_EQUAIy(__x, __y) (0xf470 - (__x-1) * 0x200 + 2 * (__y-1))
1232#define STV090x_P1_EQUAI1 STV090x_Px_EQUAIy(1, 1)
1233#define STV090x_P1_EQUAI2 STV090x_Px_EQUAIy(1, 2)
1234#define STV090x_P1_EQUAI3 STV090x_Px_EQUAIy(1, 3)
1235#define STV090x_P1_EQUAI4 STV090x_Px_EQUAIy(1, 4)
1236#define STV090x_P1_EQUAI5 STV090x_Px_EQUAIy(1, 5)
1237#define STV090x_P1_EQUAI6 STV090x_Px_EQUAIy(1, 6)
1238#define STV090x_P1_EQUAI7 STV090x_Px_EQUAIy(1, 7)
1239#define STV090x_P1_EQUAI8 STV090x_Px_EQUAIy(1, 8)
1240
1241#define STV090x_P2_EQUAI1 STV090x_Px_EQUAIy(2, 1)
1242#define STV090x_P2_EQUAI2 STV090x_Px_EQUAIy(2, 2)
1243#define STV090x_P2_EQUAI3 STV090x_Px_EQUAIy(2, 3)
1244#define STV090x_P2_EQUAI4 STV090x_Px_EQUAIy(2, 4)
1245#define STV090x_P2_EQUAI5 STV090x_Px_EQUAIy(2, 5)
1246#define STV090x_P2_EQUAI6 STV090x_Px_EQUAIy(2, 6)
1247#define STV090x_P2_EQUAI7 STV090x_Px_EQUAIy(2, 7)
1248#define STV090x_P2_EQUAI8 STV090x_Px_EQUAIy(2, 8)
1249#define STV090x_OFFST_Px_EQUA_ACCIy_FIELD 0
1250#define STV090x_WIDTH_Px_EQUA_ACCIy_FIELD 8
1251
1252#define STV090x_Px_EQUAQy(__x, __y) (0xf471 - (__x-1) * 0x200 + 2 * (__y-1))
1253#define STV090x_P1_EQUAQ1 STV090x_Px_EQUAQy(1, 1)
1254#define STV090x_P1_EQUAQ2 STV090x_Px_EQUAQy(1, 2)
1255#define STV090x_P1_EQUAQ3 STV090x_Px_EQUAQy(1, 3)
1256#define STV090x_P1_EQUAQ4 STV090x_Px_EQUAQy(1, 4)
1257#define STV090x_P1_EQUAQ5 STV090x_Px_EQUAQy(1, 5)
1258#define STV090x_P1_EQUAQ6 STV090x_Px_EQUAQy(1, 6)
1259#define STV090x_P1_EQUAQ7 STV090x_Px_EQUAQy(1, 7)
1260#define STV090x_P1_EQUAQ8 STV090x_Px_EQUAQy(1, 8)
1261
1262#define STV090x_P2_EQUAQ1 STV090x_Px_EQUAQy(2, 1)
1263#define STV090x_P2_EQUAQ2 STV090x_Px_EQUAQy(2, 2)
1264#define STV090x_P2_EQUAQ3 STV090x_Px_EQUAQy(2, 3)
1265#define STV090x_P2_EQUAQ4 STV090x_Px_EQUAQy(2, 4)
1266#define STV090x_P2_EQUAQ5 STV090x_Px_EQUAQy(2, 5)
1267#define STV090x_P2_EQUAQ6 STV090x_Px_EQUAQy(2, 6)
1268#define STV090x_P2_EQUAQ7 STV090x_Px_EQUAQy(2, 7)
1269#define STV090x_P2_EQUAQ8 STV090x_Px_EQUAQy(2, 8)
1270#define STV090x_OFFST_Px_EQUA_ACCQy_FIELD 0
1271#define STV090x_WIDTH_Px_EQUA_ACCQy_FIELD 8
1272
1273#define STV090x_Px_NNOSDATATy(__x, __y) (0xf481 - (__x - 1) * 0x200 - __y * 0x1)
1274#define STV090x_P1_NNOSDATAT0 STV090x_Px_NNOSDATATy(1, 0)
1275#define STV090x_P1_NNOSDATAT1 STV090x_Px_NNOSDATATy(1, 1)
1276#define STV090x_P2_NNOSDATAT0 STV090x_Px_NNOSDATATy(2, 0)
1277#define STV090x_P2_NNOSDATAT1 STV090x_Px_NNOSDATATy(2, 1)
1278#define STV090x_OFFST_Px_NOSDATAT_NORMED_FIELD 0
1279#define STV090x_WIDTH_Px_NOSDATAT_NORMED_FIELD 8
1280
1281#define STV090x_Px_NNOSDATAy(__x, __y) (0xf483 - (__x - 1) * 0x200 - __y * 0x1)
1282#define STV090x_P1_NNOSDATA0 STV090x_Px_NNOSDATAy(1, 0)
1283#define STV090x_P1_NNOSDATA1 STV090x_Px_NNOSDATAy(1, 1)
1284#define STV090x_P2_NNOSDATA0 STV090x_Px_NNOSDATAy(2, 0)
1285#define STV090x_P2_NNOSDATA1 STV090x_Px_NNOSDATAy(2, 1)
1286#define STV090x_OFFST_Px_NOSDATA_NORMED_FIELD 0
1287#define STV090x_WIDTH_Px_NOSDATA_NORMED_FIELD 8
1288
1289#define STV090x_Px_NNOSPLHTy(__x, __y) (0xf485 - (__x - 1) * 0x200 - __y * 0x1)
1290#define STV090x_P1_NNOSPLHT0 STV090x_Px_NNOSPLHTy(1, 0)
1291#define STV090x_P1_NNOSPLHT1 STV090x_Px_NNOSPLHTy(1, 1)
1292#define STV090x_P2_NNOSPLHT0 STV090x_Px_NNOSPLHTy(2, 0)
1293#define STV090x_P2_NNOSPLHT1 STV090x_Px_NNOSPLHTy(2, 1)
1294#define STV090x_OFFST_Px_NOSPLHT_NORMED_FIELD 0
1295#define STV090x_WIDTH_Px_NOSPLHT_NORMED_FIELD 8
1296
1297#define STV090x_Px_NNOSPLHy(__x, __y) (0xf487 - (__x - 1) * 0x200 - __y * 0x1)
1298#define STV090x_P1_NNOSPLH0 STV090x_Px_NNOSPLHy(1, 0)
1299#define STV090x_P1_NNOSPLH1 STV090x_Px_NNOSPLHy(1, 1)
1300#define STV090x_P2_NNOSPLH0 STV090x_Px_NNOSPLHy(2, 0)
1301#define STV090x_P2_NNOSPLH1 STV090x_Px_NNOSPLHy(2, 1)
1302#define STV090x_OFFST_Px_NOSPLH_NORMED_FIELD 0
1303#define STV090x_WIDTH_Px_NOSPLH_NORMED_FIELD 8
1304
1305#define STV090x_Px_NOSDATATy(__x, __y) (0xf489 - (__x - 1) * 0x200 - __y * 0x1)
1306#define STV090x_P1_NOSDATAT0 STV090x_Px_NOSDATATy(1, 0)
1307#define STV090x_P1_NOSDATAT1 STV090x_Px_NOSDATATy(1, 1)
1308#define STV090x_P2_NOSDATAT0 STV090x_Px_NOSDATATy(2, 0)
1309#define STV090x_P2_NOSDATAT1 STV090x_Px_NOSDATATy(2, 1)
1310#define STV090x_OFFST_Px_NOSDATAT_UNNORMED_FIELD 0
1311#define STV090x_WIDTH_Px_NOSDATAT_UNNORMED_FIELD 8
1312
1313#define STV090x_Px_NOSDATAy(__x, __y) (0xf48b - (__x - 1) * 0x200 - __y * 0x1)
1314#define STV090x_P1_NOSDATA0 STV090x_Px_NOSDATAy(1, 0)
1315#define STV090x_P1_NOSDATA1 STV090x_Px_NOSDATAy(1, 1)
1316#define STV090x_P2_NOSDATA0 STV090x_Px_NOSDATAy(2, 0)
1317#define STV090x_P2_NOSDATA1 STV090x_Px_NOSDATAy(2, 1)
1318#define STV090x_OFFST_Px_NOSDATA_UNNORMED_FIELD 0
1319#define STV090x_WIDTH_Px_NOSDATA_UNNORMED_FIELD 8
1320
1321#define STV090x_Px_NOSPLHTy(__x, __y) (0xf48d - (__x - 1) * 0x200 - __y * 0x1)
1322#define STV090x_P1_NOSPLHT0 STV090x_Px_NOSPLHTy(1, 0)
1323#define STV090x_P1_NOSPLHT1 STV090x_Px_NOSPLHTy(1, 1)
1324#define STV090x_P2_NOSPLHT0 STV090x_Px_NOSPLHTy(2, 0)
1325#define STV090x_P2_NOSPLHT1 STV090x_Px_NOSPLHTy(2, 1)
1326#define STV090x_OFFST_Px_NOSPLHT_UNNORMED_FIELD 0
1327#define STV090x_WIDTH_Px_NOSPLHT_UNNORMED_FIELD 8
1328
1329#define STV090x_Px_NOSPLHy(__x, __y) (0xf48f - (__x - 1) * 0x200 - __y * 0x1)
1330#define STV090x_P1_NOSPLH0 STV090x_Px_NOSPLHy(1, 0)
1331#define STV090x_P1_NOSPLH1 STV090x_Px_NOSPLHy(1, 1)
1332#define STV090x_P2_NOSPLH0 STV090x_Px_NOSPLHy(2, 0)
1333#define STV090x_P2_NOSPLH1 STV090x_Px_NOSPLHy(2, 1)
1334#define STV090x_OFFST_Px_NOSPLH_UNNORMED_FIELD 0
1335#define STV090x_WIDTH_Px_NOSPLH_UNNORMED_FIELD 8
1336
1337#define STV090x_Px_CAR2CFG(__x) (0xf490 - (__x - 1) * 0x200)
1338#define STV090x_P1_CAR2CFG STV090x_Px_CAR2CFG(1)
1339#define STV090x_P2_CAR2CFG STV090x_Px_CAR2CFG(2)
1340#define STV090x_OFFST_Px_PN4_SELECT_FIELD 6
1341#define STV090x_WIDTH_Px_PN4_SELECT_FIELD 1
1342#define STV090x_OFFST_Px_CFR2_STOPDVBS1_FIELD 5
1343#define STV090x_WIDTH_Px_CFR2_STOPDVBS1_FIELD 1
1344#define STV090x_OFFST_Px_ROTA2ON_FIELD 2
1345#define STV090x_WIDTH_Px_ROTA2ON_FIELD 1
1346#define STV090x_OFFST_Px_PH_DET_ALGO2_FIELD 0
1347#define STV090x_WIDTH_Px_PH_DET_ALGO2_FIELD 2
1348
1349#define STV090x_Px_ACLC2(__x) (0xf491 - (__x - 1) * 0x200)
1350#define STV090x_P1_ACLC2 STV090x_Px_ACLC2(1)
1351#define STV090x_P2_ACLC2 STV090x_Px_ACLC2(2)
1352#define STV090x_OFFST_Px_CAR2_ALPHA_MANT_FIELD 4
1353#define STV090x_WIDTH_Px_CAR2_ALPHA_MANT_FIELD 2
1354#define STV090x_OFFST_Px_CAR2_ALPHA_EXP_FIELD 0
1355#define STV090x_WIDTH_Px_CAR2_ALPHA_EXP_FIELD 4
1356
1357#define STV090x_Px_BCLC2(__x) (0xf492 - (__x - 1) * 0x200)
1358#define STV090x_P1_BCLC2 STV090x_Px_BCLC2(1)
1359#define STV090x_P2_BCLC2 STV090x_Px_BCLC2(2)
1360#define STV090x_OFFST_Px_CAR2_BETA_MANT_FIELD 4
1361#define STV090x_WIDTH_Px_CAR2_BETA_MANT_FIELD 2
1362#define STV090x_OFFST_Px_CAR2_BETA_EXP_FIELD 0
1363#define STV090x_WIDTH_Px_CAR2_BETA_EXP_FIELD 4
1364
1365#define STV090x_Px_ACLC2S2Q(__x) (0xf497 - (__x - 1) * 0x200)
1366#define STV090x_P1_ACLC2S2Q STV090x_Px_ACLC2S2Q(1)
1367#define STV090x_P2_ACLC2S2Q STV090x_Px_ACLC2S2Q(2)
1368#define STV090x_OFFST_Px_ENAB_SPSKSYMB_FIELD 7
1369#define STV090x_WIDTH_Px_ENAB_SPSKSYMB_FIELD 1
1370#define STV090x_OFFST_Px_CAR2S2_Q_ALPH_M_FIELD 4
1371#define STV090x_WIDTH_Px_CAR2S2_Q_ALPH_M_FIELD 2
1372#define STV090x_OFFST_Px_CAR2S2_Q_ALPH_E_FIELD 0
1373#define STV090x_WIDTH_Px_CAR2S2_Q_ALPH_E_FIELD 4
1374
1375#define STV090x_Px_ACLC2S28(__x) (0xf498 - (__x - 1) * 0x200)
1376#define STV090x_P1_ACLC2S28 STV090x_Px_ACLC2S28(1)
1377#define STV090x_P2_ACLC2S28 STV090x_Px_ACLC2S28(2)
1378#define STV090x_OFFST_Px_CAR2S2_8_ALPH_M_FIELD 4
1379#define STV090x_WIDTH_Px_CAR2S2_8_ALPH_M_FIELD 2
1380#define STV090x_OFFST_Px_CAR2S2_8_ALPH_E_FIELD 0
1381#define STV090x_WIDTH_Px_CAR2S2_8_ALPH_E_FIELD 4
1382
1383#define STV090x_Px_ACLC2S216A(__x) (0xf499 - (__x - 1) * 0x200)
1384#define STV090x_P1_ACLC2S216A STV090x_Px_ACLC2S216A(1)
1385#define STV090x_P2_ACLC2S216A STV090x_Px_ACLC2S216A(2)
1386#define STV090x_OFFST_Px_CAR2S2_16A_ALPH_M_FIELD 4
1387#define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_M_FIELD 2
1388#define STV090x_OFFST_Px_CAR2S2_16A_ALPH_E_FIELD 0
1389#define STV090x_WIDTH_Px_CAR2S2_16A_ALPH_E_FIELD 4
1390
1391#define STV090x_Px_ACLC2S232A(__x) (0xf49A - (__x - 1) * 0x200)
1392#define STV090x_P1_ACLC2S232A STV090x_Px_ACLC2S232A(1)
1393#define STV090x_P2_ACLC2S232A STV090x_Px_ACLC2S232A(2)
1394#define STV090x_OFFST_Px_CAR2S2_32A_ALPH_M_FIELD 4
1395#define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_M_FIELD 2
1396#define STV090x_OFFST_Px_CAR2S2_32A_ALPH_E_FIELD 0
1397#define STV090x_WIDTH_Px_CAR2S2_32A_ALPH_E_FIELD 4
1398
1399#define STV090x_Px_BCLC2S2Q(__x) (0xf49c - (__x - 1) * 0x200)
1400#define STV090x_P1_BCLC2S2Q STV090x_Px_BCLC2S2Q(1)
1401#define STV090x_P2_BCLC2S2Q STV090x_Px_BCLC2S2Q(2)
1402#define STV090x_OFFST_Px_CAR2S2_Q_BETA_M_FIELD 4
1403#define STV090x_WIDTH_Px_CAR2S2_Q_BETA_M_FIELD 2
1404#define STV090x_OFFST_Px_CAR2S2_Q_BETA_E_FIELD 0
1405#define STV090x_WIDTH_Px_CAR2S2_Q_BETA_E_FIELD 4
1406
1407#define STV090x_Px_BCLC2S28(__x) (0xf49d - (__x - 1) * 0x200)
1408#define STV090x_P1_BCLC2S28 STV090x_Px_BCLC2S28(1)
1409#define STV090x_P2_BCLC2S28 STV090x_Px_BCLC2S28(2)
1410#define STV090x_OFFST_Px_CAR2S2_8_BETA_M_FIELD 4
1411#define STV090x_WIDTH_Px_CAR2S2_8_BETA_M_FIELD 2
1412#define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD 0
1413#define STV090x_WIDTH_Px_CAR2S2_8_BETA_E_FIELD 4
1414
1415#define STV090x_Px_BCLC2S216A(__x) (0xf49e - (__x - 1) * 0x200)
1416#define STV090x_P1_BCLC2S216A STV090x_Px_BCLC2S216A(1)
1417#define STV090x_P2_BCLC2S216A STV090x_Px_BCLC2S216A(2)
1418#define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD 4
1419#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_M_FIELD 2
1420#define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD 0
1421#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_E_FIELD 4
1422
1423#define STV090x_Px_BCLC2S232A(__x) (0xf49f - (__x - 1) * 0x200)
1424#define STV090x_P1_BCLC2S232A STV090x_Px_BCLC2S232A(1)
1425#define STV090x_P2_BCLC2S232A STV090x_Px_BCLC2S232A(2)
1426#define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD 4
1427#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_M_FIELD 2
1428#define STV090x_OFFST_Px_CAR2S2_32A_BETA_E_FIELD 0
1429#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_E_FIELD 4
1430
1431#define STV090x_Px_PLROOT2(__x) (0xf4ac - (__x - 1) * 0x200)
1432#define STV090x_P1_PLROOT2 STV090x_Px_PLROOT2(1)
1433#define STV090x_P2_PLROOT2 STV090x_Px_PLROOT2(2)
1434#define STV090x_OFFST_Px_PLSCRAMB_MODE_FIELD 2
1435#define STV090x_WIDTH_Px_PLSCRAMB_MODE_FIELD 2
1436#define STV090x_OFFST_Px_PLSCRAMB_ROOT_FIELD 0
1437#define STV090x_WIDTH_Px_PLSCRAMB_ROOT_FIELD 2
1438
1439#define STV090x_Px_PLROOT1(__x) (0xf4ad - (__x - 1) * 0x200)
1440#define STV090x_P1_PLROOT1 STV090x_Px_PLROOT1(1)
1441#define STV090x_P2_PLROOT1 STV090x_Px_PLROOT1(2)
1442#define STV090x_OFFST_Px_PLSCRAMB_ROOT1_FIELD 0
1443#define STV090x_WIDTH_Px_PLSCRAMB_ROOT1_FIELD 8
1444
1445#define STV090x_Px_PLROOT0(__x) (0xf4ae - (__x - 1) * 0x200)
1446#define STV090x_P1_PLROOT0 STV090x_Px_PLROOT0(1)
1447#define STV090x_P2_PLROOT0 STV090x_Px_PLROOT0(2)
1448#define STV090x_OFFST_Px_PLSCRAMB_ROOT0_FIELD 0
1449#define STV090x_WIDTH_Px_PLSCRAMB_ROOT0_FIELD 8
1450
1451#define STV090x_Px_MODCODLST0(__x) (0xf4b0 - (__x - 1) * 0x200) /* check */
1452#define STV090x_P1_MODCODLST0 STV090x_Px_MODCODLST0(1)
1453#define STV090x_P2_MODCODLST0 STV090x_Px_MODCODLST0(2)
1454
1455#define STV090x_Px_MODCODLST1(__x) (0xf4b1 - (__x - 1) * 0x200)
1456#define STV090x_P1_MODCODLST1 STV090x_Px_MODCODLST1(1)
1457#define STV090x_P2_MODCODLST1 STV090x_Px_MODCODLST1(2)
1458#define STV090x_OFFST_Px_DIS_MODCOD29_FIELD 4
1459#define STV090x_WIDTH_Px_DIS_MODCOD29_FIELD 4
1460#define STV090x_OFFST_Px_DIS_32PSK_9_10_FIELD 0
1461#define STV090x_WIDTH_Px_DIS_32PSK_9_10_FIELD 4
1462
1463#define STV090x_Px_MODCODLST2(__x) (0xf4b2 - (__x - 1) * 0x200)
1464#define STV090x_P1_MODCODLST2 STV090x_Px_MODCODLST2(1)
1465#define STV090x_P2_MODCODLST2 STV090x_Px_MODCODLST2(2)
1466#define STV090x_OFFST_Px_DIS_32PSK_8_9_FIELD 4
1467#define STV090x_WIDTH_Px_DIS_32PSK_8_9_FIELD 4
1468#define STV090x_OFFST_Px_DIS_32PSK_5_6_FIELD 0
1469#define STV090x_WIDTH_Px_DIS_32PSK_5_6_FIELD 4
1470
1471#define STV090x_Px_MODCODLST3(__x) (0xf4b3 - (__x - 1) * 0x200)
1472#define STV090x_P1_MODCODLST3 STV090x_Px_MODCODLST3(1)
1473#define STV090x_P2_MODCODLST3 STV090x_Px_MODCODLST3(2)
1474#define STV090x_OFFST_Px_DIS_32PSK_4_5_FIELD 4
1475#define STV090x_WIDTH_Px_DIS_32PSK_4_5_FIELD 4
1476#define STV090x_OFFST_Px_DIS_32PSK_3_4_FIELD 0
1477#define STV090x_WIDTH_Px_DIS_32PSK_3_4_FIELD 4
1478
1479#define STV090x_Px_MODCODLST4(__x) (0xf4b4 - (__x - 1) * 0x200)
1480#define STV090x_P1_MODCODLST4 STV090x_Px_MODCODLST4(1)
1481#define STV090x_P2_MODCODLST4 STV090x_Px_MODCODLST4(2)
1482#define STV090x_OFFST_Px_DIS_16PSK_9_10_FIELD 4
1483#define STV090x_WIDTH_Px_DIS_16PSK_9_10_FIELD 4
1484#define STV090x_OFFST_Px_DIS_16PSK_8_9_FIELD 0
1485#define STV090x_WIDTH_Px_DIS_16PSK_8_9_FIELD 4
1486
1487#define STV090x_Px_MODCODLST5(__x) (0xf4b5 - (__x - 1) * 0x200)
1488#define STV090x_P1_MODCODLST5 STV090x_Px_MODCODLST5(1)
1489#define STV090x_P2_MODCODLST5 STV090x_Px_MODCODLST5(2)
1490#define STV090x_OFFST_Px_DIS_16PSK_5_6_FIELD 4
1491#define STV090x_WIDTH_Px_DIS_16PSK_5_6_FIELD 4
1492#define STV090x_OFFST_Px_DIS_16PSK_4_5_FIELD 0
1493#define STV090x_WIDTH_Px_DIS_16PSK_4_5_FIELD 4
1494
1495#define STV090x_Px_MODCODLST6(__x) (0xf4b6 - (__x - 1) * 0x200)
1496#define STV090x_P1_MODCODLST6 STV090x_Px_MODCODLST6(1)
1497#define STV090x_P2_MODCODLST6 STV090x_Px_MODCODLST6(2)
1498#define STV090x_OFFST_Px_DIS_16PSK_3_4_FIELD 4
1499#define STV090x_WIDTH_Px_DIS_16PSK_3_4_FIELD 4
1500#define STV090x_OFFST_Px_DIS_16PSK_2_3_FIELD 0
1501#define STV090x_WIDTH_Px_DIS_16PSK_2_3_FIELD 4
1502
1503#define STV090x_Px_MODCODLST7(__x) (0xf4b7 - (__x - 1) * 0x200)
1504#define STV090x_P1_MODCODLST7 STV090x_Px_MODCODLST7(1)
1505#define STV090x_P2_MODCODLST7 STV090x_Px_MODCODLST7(2)
1506#define STV090x_OFFST_Px_DIS_8P_9_10_FIELD 4
1507#define STV090x_WIDTH_Px_DIS_8P_9_10_FIELD 4
1508#define STV090x_OFFST_Px_DIS_8P_8_9_FIELD 0
1509#define STV090x_WIDTH_Px_DIS_8P_8_9_FIELD 4
1510
1511#define STV090x_Px_MODCODLST8(__x) (0xf4b8 - (__x - 1) * 0x200)
1512#define STV090x_P1_MODCODLST8 STV090x_Px_MODCODLST8(1)
1513#define STV090x_P2_MODCODLST8 STV090x_Px_MODCODLST8(2)
1514#define STV090x_OFFST_Px_DIS_8P_5_6_FIELD 4
1515#define STV090x_WIDTH_Px_DIS_8P_5_6_FIELD 4
1516#define STV090x_OFFST_Px_DIS_8P_3_4_FIELD 0
1517#define STV090x_WIDTH_Px_DIS_8P_3_4_FIELD 4
1518
1519#define STV090x_Px_MODCODLST9(__x) (0xf4b9 - (__x - 1) * 0x200)
1520#define STV090x_P1_MODCODLST9 STV090x_Px_MODCODLST9(1)
1521#define STV090x_P2_MODCODLST9 STV090x_Px_MODCODLST9(2)
1522#define STV090x_OFFST_Px_DIS_8P_2_3_FIELD 4
1523#define STV090x_WIDTH_Px_DIS_8P_2_3_FIELD 4
1524#define STV090x_OFFST_Px_DIS_8P_3_5_FIELD 0
1525#define STV090x_WIDTH_Px_DIS_8P_3_5_FIELD 4
1526
1527#define STV090x_Px_MODCODLSTA(__x) (0xf4ba - (__x - 1) * 0x200)
1528#define STV090x_P1_MODCODLSTA STV090x_Px_MODCODLSTA(1)
1529#define STV090x_P2_MODCODLSTA STV090x_Px_MODCODLSTA(2)
1530#define STV090x_OFFST_Px_DIS_QP_9_10_FIELD 4
1531#define STV090x_WIDTH_Px_DIS_QP_9_10_FIELD 4
1532#define STV090x_OFFST_Px_DIS_QP_8_9_FIELD 0
1533#define STV090x_WIDTH_Px_DIS_QP_8_9_FIELD 4
1534
1535#define STV090x_Px_MODCODLSTB(__x) (0xf4bb - (__x - 1) * 0x200)
1536#define STV090x_P1_MODCODLSTB STV090x_Px_MODCODLSTB(1)
1537#define STV090x_P2_MODCODLSTB STV090x_Px_MODCODLSTB(2)
1538#define STV090x_OFFST_Px_DIS_QP_5_6_FIELD 4
1539#define STV090x_WIDTH_Px_DIS_QP_5_6_FIELD 4
1540#define STV090x_OFFST_Px_DIS_QP_4_5_FIELD 0
1541#define STV090x_WIDTH_Px_DIS_QP_4_5_FIELD 4
1542
1543#define STV090x_Px_MODCODLSTC(__x) (0xf4bc - (__x - 1) * 0x200)
1544#define STV090x_P1_MODCODLSTC STV090x_Px_MODCODLSTC(1)
1545#define STV090x_P2_MODCODLSTC STV090x_Px_MODCODLSTC(2)
1546#define STV090x_OFFST_Px_DIS_QP_3_4_FIELD 4
1547#define STV090x_WIDTH_Px_DIS_QP_3_4_FIELD 4
1548#define STV090x_OFFST_Px_DIS_QP_2_3_FIELD 0
1549#define STV090x_WIDTH_Px_DIS_QP_2_3_FIELD 4
1550
1551#define STV090x_Px_MODCODLSTD(__x) (0xf4bd - (__x - 1) * 0x200)
1552#define STV090x_P1_MODCODLSTD STV090x_Px_MODCODLSTD(1)
1553#define STV090x_P2_MODCODLSTD STV090x_Px_MODCODLSTD(2)
1554#define STV090x_OFFST_Px_DIS_QP_3_5_FIELD 4
1555#define STV090x_WIDTH_Px_DIS_QP_3_5_FIELD 4
1556#define STV090x_OFFST_Px_DIS_QP_1_2_FIELD 0
1557#define STV090x_WIDTH_Px_DIS_QP_1_2_FIELD 4
1558
1559#define STV090x_Px_MODCODLSTE(__x) (0xf4be - (__x - 1) * 0x200)
1560#define STV090x_P1_MODCODLSTE STV090x_Px_MODCODLSTE(1)
1561#define STV090x_P2_MODCODLSTE STV090x_Px_MODCODLSTE(2)
1562#define STV090x_OFFST_Px_DIS_QP_2_5_FIELD 4
1563#define STV090x_WIDTH_Px_DIS_QP_2_5_FIELD 4
1564#define STV090x_OFFST_Px_DIS_QP_1_3_FIELD 0
1565#define STV090x_WIDTH_Px_DIS_QP_1_3_FIELD 4
1566
1567#define STV090x_Px_MODCODLSTF(__x) (0xf4bf - (__x - 1) * 0x200)
1568#define STV090x_P1_MODCODLSTF STV090x_Px_MODCODLSTF(1)
1569#define STV090x_P2_MODCODLSTF STV090x_Px_MODCODLSTF(2)
1570#define STV090x_OFFST_Px_DIS_QP_1_4_FIELD 4
1571#define STV090x_WIDTH_Px_DIS_QP_1_4_FIELD 4
1572
1573#define STV090x_Px_GAUSSR0(__x) (0xf4c0 - (__x - 1) * 0x200)
1574#define STV090x_P1_GAUSSR0 STV090x_Px_GAUSSR0(1)
1575#define STV090x_P2_GAUSSR0 STV090x_Px_GAUSSR0(2)
1576#define STV090x_OFFST_Px_EN_CCIMODE_FIELD 7
1577#define STV090x_WIDTH_Px_EN_CCIMODE_FIELD 1
1578#define STV090x_OFFST_Px_R0_GAUSSIEN_FIELD 0
1579#define STV090x_WIDTH_Px_R0_GAUSSIEN_FIELD 7
1580
1581#define STV090x_Px_CCIR0(__x) (0xf4c1 - (__x - 1) * 0x200)
1582#define STV090x_P1_CCIR0 STV090x_Px_CCIR0(1)
1583#define STV090x_P2_CCIR0 STV090x_Px_CCIR0(2)
1584#define STV090x_OFFST_Px_CCIDETECT_PLH_FIELD 7
1585#define STV090x_WIDTH_Px_CCIDETECT_PLH_FIELD 1
1586#define STV090x_OFFST_Px_R0_CCI_FIELD 0
1587#define STV090x_WIDTH_Px_R0_CCI_FIELD 7
1588
1589#define STV090x_Px_CCIQUANT(__x) (0xf4c2 - (__x - 1) * 0x200)
1590#define STV090x_P1_CCIQUANT STV090x_Px_CCIQUANT(1)
1591#define STV090x_P2_CCIQUANT STV090x_Px_CCIQUANT(2)
1592#define STV090x_OFFST_Px_CCI_BETA_FIELD 5
1593#define STV090x_WIDTH_Px_CCI_BETA_FIELD 3
1594#define STV090x_OFFST_Px_CCI_QUANT_FIELD 0
1595#define STV090x_WIDTH_Px_CCI_QUANT_FIELD 5
1596
1597#define STV090x_Px_CCITHRESH(__x) (0xf4c3 - (__x - 1) * 0x200)
1598#define STV090x_P1_CCITHRESH STV090x_Px_CCITHRESH(1)
1599#define STV090x_P2_CCITHRESH STV090x_Px_CCITHRESH(2)
1600#define STV090x_OFFST_Px_CCI_THRESHOLD_FIELD 0
1601#define STV090x_WIDTH_Px_CCI_THRESHOLD_FIELD 8
1602
1603#define STV090x_Px_CCIACC(__x) (0xf4c4 - (__x - 1) * 0x200)
1604#define STV090x_P1_CCIACC STV090x_Px_CCIACC(1)
1605#define STV090x_P2_CCIACC STV090x_Px_CCIACC(2)
1606#define STV090x_OFFST_Px_CCI_VALUE_FIELD 0
1607#define STV090x_WIDTH_Px_CCI_VALUE_FIELD 8
1608
1609#define STV090x_Px_DMDRESCFG(__x) (0xF4C6 - (__x - 1) * 0x200)
1610#define STV090x_P1_DMDRESCFG STV090x_Px_DMDRESCFG(1)
1611#define STV090x_P2_DMDRESCFG STV090x_Px_DMDRESCFG(2)
1612#define STV090x_OFFST_Px_DMDRES_RESET_FIELD 7
1613#define STV090x_WIDTH_Px_DMDRES_RESET_FIELD 1
1614
1615#define STV090x_Px_DMDRESADR(__x) (0xF4C7 - (__x - 1) * 0x200)
1616#define STV090x_P1_DMDRESADR STV090x_Px_DMDRESADR(1)
1617#define STV090x_P2_DMDRESADR STV090x_Px_DMDRESADR(2)
1618#define STV090x_OFFST_Px_DMDRES_RESNBR_FIELD 0
1619#define STV090x_WIDTH_Px_DMDRES_RESNBR_FIELD 4
1620
1621#define STV090x_Px_DMDRESDATAy(__x, __y) (0xF4C8 - (__x - 1) * 0x200 + (7 - __y))
1622#define STV090x_P1_DMDRESDATA0 STV090x_Px_DMDRESDATAy(1, 0)
1623#define STV090x_P1_DMDRESDATA1 STV090x_Px_DMDRESDATAy(1, 1)
1624#define STV090x_P1_DMDRESDATA2 STV090x_Px_DMDRESDATAy(1, 2)
1625#define STV090x_P1_DMDRESDATA3 STV090x_Px_DMDRESDATAy(1, 3)
1626#define STV090x_P1_DMDRESDATA4 STV090x_Px_DMDRESDATAy(1, 4)
1627#define STV090x_P1_DMDRESDATA5 STV090x_Px_DMDRESDATAy(1, 5)
1628#define STV090x_P1_DMDRESDATA6 STV090x_Px_DMDRESDATAy(1, 6)
1629#define STV090x_P1_DMDRESDATA7 STV090x_Px_DMDRESDATAy(1, 7)
1630#define STV090x_P2_DMDRESDATA0 STV090x_Px_DMDRESDATAy(2, 0)
1631#define STV090x_P2_DMDRESDATA1 STV090x_Px_DMDRESDATAy(2, 1)
1632#define STV090x_P2_DMDRESDATA2 STV090x_Px_DMDRESDATAy(2, 2)
1633#define STV090x_P2_DMDRESDATA3 STV090x_Px_DMDRESDATAy(2, 3)
1634#define STV090x_P2_DMDRESDATA4 STV090x_Px_DMDRESDATAy(2, 4)
1635#define STV090x_P2_DMDRESDATA5 STV090x_Px_DMDRESDATAy(2, 5)
1636#define STV090x_P2_DMDRESDATA6 STV090x_Px_DMDRESDATAy(2, 6)
1637#define STV090x_P2_DMDRESDATA7 STV090x_Px_DMDRESDATAy(2, 7)
1638#define STV090x_OFFST_Px_DMDRES_DATA_FIELD 0
1639#define STV090x_WIDTH_Px_DMDRES_DATA_FIELD 8
1640
1641#define STV090x_Px_FFEIy(__x, __y) (0xf4d0 - (__x - 1) * 0x200 + 0x2 * (__y - 1))
1642#define STV090x_P1_FFEI1 STV090x_Px_FFEIy(1, 1)
1643#define STV090x_P1_FFEI2 STV090x_Px_FFEIy(1, 2)
1644#define STV090x_P1_FFEI3 STV090x_Px_FFEIy(1, 3)
1645#define STV090x_P1_FFEI4 STV090x_Px_FFEIy(1, 4)
1646#define STV090x_P2_FFEI1 STV090x_Px_FFEIy(2, 1)
1647#define STV090x_P2_FFEI2 STV090x_Px_FFEIy(2, 2)
1648#define STV090x_P2_FFEI3 STV090x_Px_FFEIy(2, 3)
1649#define STV090x_P2_FFEI4 STV090x_Px_FFEIy(2, 4)
1650#define STV090x_OFFST_Px_FFE_ACCIy_FIELD 0
1651#define STV090x_WIDTH_Px_FFE_ACCIy_FIELD 8
1652
1653#define STV090x_Px_FFEQy(__x, __y) (0xf4d1 - (__x - 1) * 0x200 + 0x2 * (__y - 1))
1654#define STV090x_P1_FFEQ1 STV090x_Px_FFEQy(1, 1)
1655#define STV090x_P1_FFEQ2 STV090x_Px_FFEQy(1, 2)
1656#define STV090x_P1_FFEQ3 STV090x_Px_FFEQy(1, 3)
1657#define STV090x_P1_FFEQ4 STV090x_Px_FFEQy(1, 4)
1658#define STV090x_P2_FFEQ1 STV090x_Px_FFEQy(2, 1)
1659#define STV090x_P2_FFEQ2 STV090x_Px_FFEQy(2, 2)
1660#define STV090x_P2_FFEQ3 STV090x_Px_FFEQy(2, 3)
1661#define STV090x_P2_FFEQ4 STV090x_Px_FFEQy(2, 4)
1662#define STV090x_OFFST_Px_FFE_ACCQy_FIELD 0
1663#define STV090x_WIDTH_Px_FFE_ACCQy_FIELD 8
1664
1665#define STV090x_Px_FFECFG(__x) (0xf4d8 - (__x - 1) * 0x200)
1666#define STV090x_P1_FFECFG STV090x_Px_FFECFG(1)
1667#define STV090x_P2_FFECFG STV090x_Px_FFECFG(2)
1668#define STV090x_OFFST_Px_EQUALFFE_ON_FIELD 6
1669#define STV090x_WIDTH_Px_EQUALFFE_ON_FIELD 1
1670
1671#define STV090x_Px_SMAPCOEF7(__x) (0xf500 - (__x - 1) * 0x200)
1672#define STV090x_P1_SMAPCOEF7 STV090x_Px_SMAPCOEF7(1)
1673#define STV090x_P2_SMAPCOEF7 STV090x_Px_SMAPCOEF7(2)
1674#define STV090x_OFFST_Px_DIS_QSCALE_FIELD 7
1675#define STV090x_WIDTH_Px_DIS_QSCALE_FIELD 1
1676#define STV090x_OFFST_Px_SMAPCOEF_Q_LLR12_FIELD 0
1677#define STV090x_WIDTH_Px_SMAPCOEF_Q_LLR12_FIELD 7
1678
1679#define STV090x_Px_SMAPCOEF6(__x) (0xf501 - (__x - 1) * 0x200)
1680#define STV090x_P1_SMAPCOEF6 STV090x_Px_SMAPCOEF6(1)
1681#define STV090x_P2_SMAPCOEF6 STV090x_Px_SMAPCOEF6(2)
1682#define STV090x_OFFST_Px_ADJ_8PSKLLR1_FIELD 2
1683#define STV090x_WIDTH_Px_ADJ_8PSKLLR1_FIELD 1
1684#define STV090x_OFFST_Px_OLD_8PSKLLR1_FIELD 1
1685#define STV090x_WIDTH_Px_OLD_8PSKLLR1_FIELD 1
1686#define STV090x_OFFST_Px_DIS_AB8PSK_FIELD 0
1687#define STV090x_WIDTH_Px_DIS_AB8PSK_FIELD 1
1688
1689#define STV090x_Px_SMAPCOEF5(__x) (0xf502 - (__x - 1) * 0x200)
1690#define STV090x_P1_SMAPCOEF5 STV090x_Px_SMAPCOEF5(1)
1691#define STV090x_P2_SMAPCOEF5 STV090x_Px_SMAPCOEF5(2)
1692#define STV090x_OFFST_Px_DIS_8SCALE_FIELD 7
1693#define STV090x_WIDTH_Px_DIS_8SCALE_FIELD 1
1694#define STV090x_OFFST_Px_SMAPCOEF_8P_LLR23_FIELD 0
1695#define STV090x_WIDTH_Px_SMAPCOEF_8P_LLR23_FIELD 7
1696
1697#define STV090x_Px_DMDPLHSTAT(__x) (0xF520 - (__x - 1) * 0x200)
1698#define STV090x_P1_DMDPLHSTAT STV090x_Px_DMDPLHSTAT(1)
1699#define STV090x_P2_DMDPLHSTAT STV090x_Px_DMDPLHSTAT(2)
1700#define STV090x_OFFST_Px_PLH_STATISTIC_FIELD 0
1701#define STV090x_WIDTH_Px_PLH_STATISTIC_FIELD 8
1702
1703#define STV090x_Px_LOCKTIMEy(__x, __y) (0xF525 - (__x - 1) * 0x200 - __y * 0x1)
1704#define STV090x_P1_LOCKTIME0 STV090x_Px_LOCKTIMEy(1, 0)
1705#define STV090x_P1_LOCKTIME1 STV090x_Px_LOCKTIMEy(1, 1)
1706#define STV090x_P1_LOCKTIME2 STV090x_Px_LOCKTIMEy(1, 2)
1707#define STV090x_P1_LOCKTIME3 STV090x_Px_LOCKTIMEy(1, 3)
1708#define STV090x_P2_LOCKTIME0 STV090x_Px_LOCKTIMEy(2, 0)
1709#define STV090x_P2_LOCKTIME1 STV090x_Px_LOCKTIMEy(2, 1)
1710#define STV090x_P2_LOCKTIME2 STV090x_Px_LOCKTIMEy(2, 2)
1711#define STV090x_P2_LOCKTIME3 STV090x_Px_LOCKTIMEy(2, 3)
1712#define STV090x_OFFST_Px_DEMOD_LOCKTIME_FIELD 0
1713#define STV090x_WIDTH_Px_DEMOD_LOCKTIME_FIELD 8
1714
1715#define STV090x_Px_TNRCFG(__x) (0xf4e0 - (__x - 1) * 0x200) /* check */
1716#define STV090x_P1_TNRCFG STV090x_Px_TNRCFG(1)
1717#define STV090x_P2_TNRCFG STV090x_Px_TNRCFG(2)
1718
1719#define STV090x_Px_TNRCFG2(__x) (0xf4e1 - (__x - 1) * 0x200)
1720#define STV090x_P1_TNRCFG2 STV090x_Px_TNRCFG2(1)
1721#define STV090x_P2_TNRCFG2 STV090x_Px_TNRCFG2(2)
1722#define STV090x_OFFST_Px_TUN_IQSWAP_FIELD 7
1723#define STV090x_WIDTH_Px_TUN_IQSWAP_FIELD 1
1724
1725#define STV090x_Px_VITSCALE(__x) (0xf532 - (__x - 1) * 0x200)
1726#define STV090x_P1_VITSCALE STV090x_Px_VITSCALE(1)
1727#define STV090x_P2_VITSCALE STV090x_Px_VITSCALE(2)
1728#define STV090x_OFFST_Px_NVTH_NOSRANGE_FIELD 7
1729#define STV090x_WIDTH_Px_NVTH_NOSRANGE_FIELD 1
1730#define STV090x_OFFST_Px_VERROR_MAXMODE_FIELD 6
1731#define STV090x_WIDTH_Px_VERROR_MAXMODE_FIELD 1
1732#define STV090x_OFFST_Px_NSLOWSN_LOCKED_FIELD 3
1733#define STV090x_WIDTH_Px_NSLOWSN_LOCKED_FIELD 1
1734#define STV090x_OFFST_Px_DIS_RSFLOCK_FIELD 1
1735#define STV090x_WIDTH_Px_DIS_RSFLOCK_FIELD 1
1736
1737#define STV090x_Px_FECM(__x) (0xf533 - (__x - 1) * 0x200)
1738#define STV090x_P1_FECM STV090x_Px_FECM(1)
1739#define STV090x_P2_FECM STV090x_Px_FECM(2)
1740#define STV090x_OFFST_Px_DSS_DVB_FIELD 7
1741#define STV090x_WIDTH_Px_DSS_DVB_FIELD 1
1742#define STV090x_OFFST_Px_DSS_SRCH_FIELD 4
1743#define STV090x_WIDTH_Px_DSS_SRCH_FIELD 1
1744#define STV090x_OFFST_Px_SYNCVIT_FIELD 1
1745#define STV090x_WIDTH_Px_SYNCVIT_FIELD 1
1746#define STV090x_OFFST_Px_IQINV_FIELD 0
1747#define STV090x_WIDTH_Px_IQINV_FIELD 1
1748
1749#define STV090x_Px_VTH12(__x) (0xf534 - (__x - 1) * 0x200)
1750#define STV090x_P1_VTH12 STV090x_Px_VTH12(1)
1751#define STV090x_P2_VTH12 STV090x_Px_VTH12(2)
1752#define STV090x_OFFST_Px_VTH12_FIELD 0
1753#define STV090x_WIDTH_Px_VTH12_FIELD 8
1754
1755#define STV090x_Px_VTH23(__x) (0xf535 - (__x - 1) * 0x200)
1756#define STV090x_P1_VTH23 STV090x_Px_VTH23(1)
1757#define STV090x_P2_VTH23 STV090x_Px_VTH23(2)
1758#define STV090x_OFFST_Px_VTH23_FIELD 0
1759#define STV090x_WIDTH_Px_VTH23_FIELD 8
1760
1761#define STV090x_Px_VTH34(__x) (0xf536 - (__x - 1) * 0x200)
1762#define STV090x_P1_VTH34 STV090x_Px_VTH34(1)
1763#define STV090x_P2_VTH34 STV090x_Px_VTH34(2)
1764#define STV090x_OFFST_Px_VTH34_FIELD 0
1765#define STV090x_WIDTH_Px_VTH34_FIELD 8
1766
1767#define STV090x_Px_VTH56(__x) (0xf537 - (__x - 1) * 0x200)
1768#define STV090x_P1_VTH56 STV090x_Px_VTH56(1)
1769#define STV090x_P2_VTH56 STV090x_Px_VTH56(2)
1770#define STV090x_OFFST_Px_VTH56_FIELD 0
1771#define STV090x_WIDTH_Px_VTH56_FIELD 8
1772
1773#define STV090x_Px_VTH67(__x) (0xf538 - (__x - 1) * 0x200)
1774#define STV090x_P1_VTH67 STV090x_Px_VTH67(1)
1775#define STV090x_P2_VTH67 STV090x_Px_VTH67(2)
1776#define STV090x_OFFST_Px_VTH67_FIELD 0
1777#define STV090x_WIDTH_Px_VTH67_FIELD 8
1778
1779#define STV090x_Px_VTH78(__x) (0xf539 - (__x - 1) * 0x200)
1780#define STV090x_P1_VTH78 STV090x_Px_VTH78(1)
1781#define STV090x_P2_VTH78 STV090x_Px_VTH78(2)
1782#define STV090x_OFFST_Px_VTH78_FIELD 0
1783#define STV090x_WIDTH_Px_VTH78_FIELD 8
1784
1785#define STV090x_Px_VITCURPUN(__x) (0xf53a - (__x - 1) * 0x200)
1786#define STV090x_P1_VITCURPUN STV090x_Px_VITCURPUN(1)
1787#define STV090x_P2_VITCURPUN STV090x_Px_VITCURPUN(2)
1788#define STV090x_OFFST_Px_VIT_CURPUN_FIELD 0
1789#define STV090x_WIDTH_Px_VIT_CURPUN_FIELD 5
1790
1791#define STV090x_Px_VERROR(__x) (0xf53b - (__x - 1) * 0x200)
1792#define STV090x_P1_VERROR STV090x_Px_VERROR(1)
1793#define STV090x_P2_VERROR STV090x_Px_VERROR(2)
1794#define STV090x_OFFST_Px_REGERR_VIT_FIELD 0
1795#define STV090x_WIDTH_Px_REGERR_VIT_FIELD 8
1796
1797#define STV090x_Px_PRVIT(__x) (0xf53c - (__x - 1) * 0x200)
1798#define STV090x_P1_PRVIT STV090x_Px_PRVIT(1)
1799#define STV090x_P2_PRVIT STV090x_Px_PRVIT(2)
1800#define STV090x_OFFST_Px_DIS_VTHLOCK_FIELD 6
1801#define STV090x_WIDTH_Px_DIS_VTHLOCK_FIELD 1
1802#define STV090x_OFFST_Px_E7_8VIT_FIELD 5
1803#define STV090x_WIDTH_Px_E7_8VIT_FIELD 1
1804#define STV090x_OFFST_Px_E6_7VIT_FIELD 4
1805#define STV090x_WIDTH_Px_E6_7VIT_FIELD 1
1806#define STV090x_OFFST_Px_E5_6VIT_FIELD 3
1807#define STV090x_WIDTH_Px_E5_6VIT_FIELD 1
1808#define STV090x_OFFST_Px_E3_4VIT_FIELD 2
1809#define STV090x_WIDTH_Px_E3_4VIT_FIELD 1
1810#define STV090x_OFFST_Px_E2_3VIT_FIELD 1
1811#define STV090x_WIDTH_Px_E2_3VIT_FIELD 1
1812#define STV090x_OFFST_Px_E1_2VIT_FIELD 0
1813#define STV090x_WIDTH_Px_E1_2VIT_FIELD 1
1814
1815#define STV090x_Px_VAVSRVIT(__x) (0xf53d - (__x - 1) * 0x200)
1816#define STV090x_P1_VAVSRVIT STV090x_Px_VAVSRVIT(1)
1817#define STV090x_P2_VAVSRVIT STV090x_Px_VAVSRVIT(2)
1818#define STV090x_OFFST_Px_SNVIT_FIELD 4
1819#define STV090x_WIDTH_Px_SNVIT_FIELD 2
1820#define STV090x_OFFST_Px_TOVVIT_FIELD 2
1821#define STV090x_WIDTH_Px_TOVVIT_FIELD 2
1822#define STV090x_OFFST_Px_HYPVIT_FIELD 0
1823#define STV090x_WIDTH_Px_HYPVIT_FIELD 2
1824
1825#define STV090x_Px_VSTATUSVIT(__x) (0xf53e - (__x - 1) * 0x200)
1826#define STV090x_P1_VSTATUSVIT STV090x_Px_VSTATUSVIT(1)
1827#define STV090x_P2_VSTATUSVIT STV090x_Px_VSTATUSVIT(2)
1828#define STV090x_OFFST_Px_PRFVIT_FIELD 4
1829#define STV090x_WIDTH_Px_PRFVIT_FIELD 1
1830#define STV090x_OFFST_Px_LOCKEDVIT_FIELD 3
1831#define STV090x_WIDTH_Px_LOCKEDVIT_FIELD 1
1832
1833#define STV090x_Px_VTHINUSE(__x) (0xf53f - (__x - 1) * 0x200)
1834#define STV090x_P1_VTHINUSE STV090x_Px_VTHINUSE(1)
1835#define STV090x_P2_VTHINUSE STV090x_Px_VTHINUSE(2)
1836#define STV090x_OFFST_Px_VIT_INUSE_FIELD 0
1837#define STV090x_WIDTH_Px_VIT_INUSE_FIELD 8
1838
1839#define STV090x_Px_KDIV12(__x) (0xf540 - (__x - 1) * 0x200)
1840#define STV090x_P1_KDIV12 STV090x_Px_KDIV12(1)
1841#define STV090x_P2_KDIV12 STV090x_Px_KDIV12(2)
1842#define STV090x_OFFST_Px_K_DIVIDER_12_FIELD 0
1843#define STV090x_WIDTH_Px_K_DIVIDER_12_FIELD 7
1844
1845#define STV090x_Px_KDIV23(__x) (0xf541 - (__x - 1) * 0x200)
1846#define STV090x_P1_KDIV23 STV090x_Px_KDIV23(1)
1847#define STV090x_P2_KDIV23 STV090x_Px_KDIV23(2)
1848#define STV090x_OFFST_Px_K_DIVIDER_23_FIELD 0
1849#define STV090x_WIDTH_Px_K_DIVIDER_23_FIELD 7
1850
1851#define STV090x_Px_KDIV34(__x) (0xf542 - (__x - 1) * 0x200)
1852#define STV090x_P1_KDIV34 STV090x_Px_KDIV34(1)
1853#define STV090x_P2_KDIV34 STV090x_Px_KDIV34(2)
1854#define STV090x_OFFST_Px_K_DIVIDER_34_FIELD 0
1855#define STV090x_WIDTH_Px_K_DIVIDER_34_FIELD 7
1856
1857#define STV090x_Px_KDIV56(__x) (0xf543 - (__x - 1) * 0x200)
1858#define STV090x_P1_KDIV56 STV090x_Px_KDIV56(1)
1859#define STV090x_P2_KDIV56 STV090x_Px_KDIV56(2)
1860#define STV090x_OFFST_Px_K_DIVIDER_56_FIELD 0
1861#define STV090x_WIDTH_Px_K_DIVIDER_56_FIELD 7
1862
1863#define STV090x_Px_KDIV67(__x) (0xf544 - (__x - 1) * 0x200)
1864#define STV090x_P1_KDIV67 STV090x_Px_KDIV67(1)
1865#define STV090x_P2_KDIV67 STV090x_Px_KDIV67(2)
1866#define STV090x_OFFST_Px_K_DIVIDER_67_FIELD 0
1867#define STV090x_WIDTH_Px_K_DIVIDER_67_FIELD 7
1868
1869#define STV090x_Px_KDIV78(__x) (0xf545 - (__x - 1) * 0x200)
1870#define STV090x_P1_KDIV78 STV090x_Px_KDIV78(1)
1871#define STV090x_P2_KDIV78 STV090x_Px_KDIV78(2)
1872#define STV090x_OFFST_Px_K_DIVIDER_78_FIELD 0
1873#define STV090x_WIDTH_Px_K_DIVIDER_78_FIELD 7
1874
1875#define STV090x_Px_PDELCTRL1(__x) (0xf550 - (__x - 1) * 0x200)
1876#define STV090x_P1_PDELCTRL1 STV090x_Px_PDELCTRL1(1)
1877#define STV090x_P2_PDELCTRL1 STV090x_Px_PDELCTRL1(2)
1878#define STV090x_OFFST_Px_INV_MISMASK_FIELD 7
1879#define STV090x_WIDTH_Px_INV_MISMASK_FIELD 1
1880#define STV090x_OFFST_Px_FILTER_EN_FIELD 5
1881#define STV090x_WIDTH_Px_FILTER_EN_FIELD 1
1882#define STV090x_OFFST_Px_EN_MIS00_FIELD 1
1883#define STV090x_WIDTH_Px_EN_MIS00_FIELD 1
1884#define STV090x_OFFST_Px_ALGOSWRST_FIELD 0
1885#define STV090x_WIDTH_Px_ALGOSWRST_FIELD 1
1886
1887#define STV090x_Px_PDELCTRL2(__x) (0xf551 - (__x - 1) * 0x200)
1888#define STV090x_P1_PDELCTRL2 STV090x_Px_PDELCTRL2(1)
1889#define STV090x_P2_PDELCTRL2 STV090x_Px_PDELCTRL2(2)
1890#define STV090x_OFFST_Px_FORCE_CONTINUOUS 7
1891#define STV090x_WIDTH_Px_FORCE_CONTINUOUS 1
1892#define STV090x_OFFST_Px_RESET_UPKO_COUNT 6
1893#define STV090x_WIDTH_Px_RESET_UPKO_COUNT 1
1894#define STV090x_OFFST_Px_USER_PKTDELIN_NB 5
1895#define STV090x_WIDTH_Px_USER_PKTDELIN_NB 1
1896#define STV090x_OFFST_Px_FORCE_LOCKED 4
1897#define STV090x_WIDTH_Px_FORCE_LOCKED 1
1898#define STV090x_OFFST_Px_DATA_UNBBSCRAM 3
1899#define STV090x_WIDTH_Px_DATA_UNBBSCRAM 1
1900#define STV090x_OFFST_Px_FORCE_LONGPACKET 2
1901#define STV090x_WIDTH_Px_FORCE_LONGPACKET 1
1902#define STV090x_OFFST_Px_FRAME_MODE_FIELD 1
1903#define STV090x_WIDTH_Px_FRAME_MODE_FIELD 1
1904
1905#define STV090x_Px_HYSTTHRESH(__x) (0xf554 - (__x - 1) * 0x200)
1906#define STV090x_P1_HYSTTHRESH STV090x_Px_HYSTTHRESH(1)
1907#define STV090x_P2_HYSTTHRESH STV090x_Px_HYSTTHRESH(2)
1908#define STV090x_OFFST_Px_UNLCK_THRESH_FIELD 4
1909#define STV090x_WIDTH_Px_UNLCK_THRESH_FIELD 4
1910#define STV090x_OFFST_Px_DELIN_LCK_THRESH_FIELD 0
1911#define STV090x_WIDTH_Px_DELIN_LCK_THRESH_FIELD 4
1912
1913#define STV090x_Px_ISIENTRY(__x) (0xf55e - (__x - 1) * 0x200)
1914#define STV090x_P1_ISIENTRY STV090x_Px_ISIENTRY(1)
1915#define STV090x_P2_ISIENTRY STV090x_Px_ISIENTRY(2)
1916#define STV090x_OFFST_Px_ISI_ENTRY_FIELD 0
1917#define STV090x_WIDTH_Px_ISI_ENTRY_FIELD 8
1918
1919#define STV090x_Px_ISIBITENA(__x) (0xf55f - (__x - 1) * 0x200)
1920#define STV090x_P1_ISIBITENA STV090x_Px_ISIBITENA(1)
1921#define STV090x_P2_ISIBITENA STV090x_Px_ISIBITENA(2)
1922#define STV090x_OFFST_Px_ISI_BIT_EN_FIELD 0
1923#define STV090x_WIDTH_Px_ISI_BIT_EN_FIELD 8
1924
1925#define STV090x_Px_MATSTRy(__x, __y) (0xf561 - (__x - 1) * 0x200 - __y * 0x1)
1926#define STV090x_P1_MATSTR0 STV090x_Px_MATSTRy(1, 0)
1927#define STV090x_P1_MATSTR1 STV090x_Px_MATSTRy(1, 1)
1928#define STV090x_P2_MATSTR0 STV090x_Px_MATSTRy(2, 0)
1929#define STV090x_P2_MATSTR1 STV090x_Px_MATSTRy(2, 1)
1930#define STV090x_OFFST_Px_MATYPE_CURRENT_FIELD 0
1931#define STV090x_WIDTH_Px_MATYPE_CURRENT_FIELD 8
1932
1933#define STV090x_Px_UPLSTRy(__x, __y) (0xf563 - (__x - 1) * 0x200 - __y * 0x1)
1934#define STV090x_P1_UPLSTR0 STV090x_Px_UPLSTRy(1, 0)
1935#define STV090x_P1_UPLSTR1 STV090x_Px_UPLSTRy(1, 1)
1936#define STV090x_P2_UPLSTR0 STV090x_Px_UPLSTRy(2, 0)
1937#define STV090x_P2_UPLSTR1 STV090x_Px_UPLSTRy(2, 1)
1938#define STV090x_OFFST_Px_UPL_CURRENT_FIELD 0
1939#define STV090x_WIDTH_Px_UPL_CURRENT_FIELD 8
1940
1941#define STV090x_Px_DFLSTRy(__x, __y) (0xf565 - (__x - 1) * 0x200 - __y * 0x1)
1942#define STV090x_P1_DFLSTR0 STV090x_Px_DFLSTRy(1, 0)
1943#define STV090x_P1_DFLSTR1 STV090x_Px_DFLSTRy(1, 1)
1944#define STV090x_P2_DFLSTR0 STV090x_Px_DFLSTRy(2, 0)
1945#define STV090x_P2_DFLSTR1 STV090x_Px_DFLSTRy(2, 1)
1946#define STV090x_OFFST_Px_DFL_CURRENT_FIELD 0
1947#define STV090x_WIDTH_Px_DFL_CURRENT_FIELD 8
1948
1949#define STV090x_Px_SYNCSTR(__x) (0xf566 - (__x - 1) * 0x200)
1950#define STV090x_P1_SYNCSTR STV090x_Px_SYNCSTR(1)
1951#define STV090x_P2_SYNCSTR STV090x_Px_SYNCSTR(2)
1952#define STV090x_OFFST_Px_SYNC_CURRENT_FIELD 0
1953#define STV090x_WIDTH_Px_SYNC_CURRENT_FIELD 8
1954
1955#define STV090x_Px_SYNCDSTRy(__x, __y) (0xf568 - (__x - 1) * 0x200 - __y * 0x1)
1956#define STV090x_P1_SYNCDSTR0 STV090x_Px_SYNCDSTRy(1, 0)
1957#define STV090x_P1_SYNCDSTR1 STV090x_Px_SYNCDSTRy(1, 1)
1958#define STV090x_P2_SYNCDSTR0 STV090x_Px_SYNCDSTRy(2, 0)
1959#define STV090x_P2_SYNCDSTR1 STV090x_Px_SYNCDSTRy(2, 1)
1960#define STV090x_OFFST_Px_SYNCD_CURRENT_FIELD 0
1961#define STV090x_WIDTH_Px_SYNCD_CURRENT_FIELD 8
1962
1963#define STV090x_Px_PDELSTATUS1(__x) (0xf569 - (__x - 1) * 0x200)
1964#define STV090x_P1_PDELSTATUS1 STV090x_Px_PDELSTATUS1(1)
1965#define STV090x_P2_PDELSTATUS1 STV090x_Px_PDELSTATUS1(2)
1966#define STV090x_OFFST_Px_PKTDELIN_LOCK_FIELD 1
1967#define STV090x_WIDTH_Px_PKTDELIN_LOCK_FIELD 1
1968#define STV090x_OFFST_Px_FIRST_LOCK_FIELD 0
1969#define STV090x_WIDTH_Px_FIRST_LOCK_FIELD 1
1970
1971#define STV090x_Px_PDELSTATUS2(__x) (0xf56a - (__x - 1) * 0x200)
1972#define STV090x_P1_PDELSTATUS2 STV090x_Px_PDELSTATUS2(1)
1973#define STV090x_P2_PDELSTATUS2 STV090x_Px_PDELSTATUS2(2)
1974#define STV090x_OFFST_Px_FRAME_MODCOD_FIELD 2
1975#define STV090x_WIDTH_Px_FRAME_MODCOD_FIELD 5
1976#define STV090x_OFFST_Px_FRAME_TYPE_FIELD 0
1977#define STV090x_WIDTH_Px_FRAME_TYPE_FIELD 2
1978
1979#define STV090x_Px_BBFCRCKO1(__x) (0xf56b - (__x - 1) * 0x200)
1980#define STV090x_P1_BBFCRCKO1 STV090x_Px_BBFCRCKO1(1)
1981#define STV090x_P2_BBFCRCKO1 STV090x_Px_BBFCRCKO1(2)
1982#define STV090x_OFFST_Px_BBHCRC_KOCNT_FIELD 0
1983#define STV090x_WIDTH_Px_BBHCRC_KOCNT_FIELD 8
1984
1985#define STV090x_Px_BBFCRCKO0(__x) (0xf56c - (__x - 1) * 0x200)
1986#define STV090x_P1_BBFCRCKO0 STV090x_Px_BBFCRCKO0(1)
1987#define STV090x_P2_BBFCRCKO0 STV090x_Px_BBFCRCKO0(2)
1988#define STV090x_OFFST_Px_BBHCRC_KOCNT_FIELD 0
1989#define STV090x_WIDTH_Px_BBHCRC_KOCNT_FIELD 8
1990
1991#define STV090x_Px_UPCRCKO1(__x) (0xf56d - (__x - 1) * 0x200)
1992#define STV090x_P1_UPCRCKO1 STV090x_Px_UPCRCKO1(1)
1993#define STV090x_P2_UPCRCKO1 STV090x_Px_UPCRCKO1(2)
1994#define STV090x_OFFST_Px_PKTCRC_KOCNT_FIELD 0
1995#define STV090x_WIDTH_Px_PKTCRC_KOCNT_FIELD 8
1996
1997#define STV090x_Px_UPCRCKO0(__x) (0xf56e - (__x - 1) * 0x200)
1998#define STV090x_P1_UPCRCKO0 STV090x_Px_UPCRCKO0(1)
1999#define STV090x_P2_UPCRCKO0 STV090x_Px_UPCRCKO0(2)
2000#define STV090x_OFFST_Px_PKTCRC_KOCNT_FIELD 0
2001#define STV090x_WIDTH_Px_PKTCRC_KOCNT_FIELD 8
2002
2003#define STV090x_NBITER_NFx(__x) (0xFA03 + (__x - 4) * 0x1)
2004#define STV090x_NBITER_NF4 STV090x_NBITER_NFx(4)
2005#define STV090x_NBITER_NF5 STV090x_NBITER_NFx(5)
2006#define STV090x_NBITER_NF6 STV090x_NBITER_NFx(6)
2007#define STV090x_NBITER_NF7 STV090x_NBITER_NFx(7)
2008#define STV090x_NBITER_NF8 STV090x_NBITER_NFx(8)
2009#define STV090x_NBITER_NF9 STV090x_NBITER_NFx(9)
2010#define STV090x_NBITER_NF10 STV090x_NBITER_NFx(10)
2011#define STV090x_NBITER_NF11 STV090x_NBITER_NFx(11)
2012#define STV090x_NBITER_NF12 STV090x_NBITER_NFx(12)
2013#define STV090x_NBITER_NF13 STV090x_NBITER_NFx(13)
2014#define STV090x_NBITER_NF14 STV090x_NBITER_NFx(14)
2015#define STV090x_NBITER_NF15 STV090x_NBITER_NFx(15)
2016#define STV090x_NBITER_NF16 STV090x_NBITER_NFx(16)
2017#define STV090x_NBITER_NF17 STV090x_NBITER_NFx(17)
2018
2019#define STV090x_NBITERNOERR 0xFA3F
2020#define STV090x_OFFST_NBITER_STOP_CRIT_FIELD 0
2021#define STV090x_WIDTH_NBITER_STOP_CRIT_FIELD 4
2022
2023#define STV090x_GAINLLR_NFx(__x) (0xFA43 + (__x - 4) * 0x1)
2024#define STV090x_GAINLLR_NF4 STV090x_GAINLLR_NFx(4)
2025#define STV090x_OFFST_GAINLLR_NF_QP_1_2_FIELD 0
2026#define STV090x_WIDTH_GAINLLR_NF_QP_1_2_FIELD 7
2027
2028#define STV090x_GAINLLR_NF5 STV090x_GAINLLR_NFx(5)
2029#define STV090x_OFFST_GAINLLR_NF_QP_3_5_FIELD 0
2030#define STV090x_WIDTH_GAINLLR_NF_QP_3_5_FIELD 7
2031
2032#define STV090x_GAINLLR_NF6 STV090x_GAINLLR_NFx(6)
2033#define STV090x_OFFST_GAINLLR_NF_QP_2_3_FIELD 0
2034#define STV090x_WIDTH_GAINLLR_NF_QP_2_3_FIELD 7
2035
2036#define STV090x_GAINLLR_NF7 STV090x_GAINLLR_NFx(7)
2037#define STV090x_OFFST_GAINLLR_NF_QP_3_4_FIELD 0
2038#define STV090x_WIDTH_GAINLLR_NF_QP_3_4_FIELD 7
2039
2040#define STV090x_GAINLLR_NF8 STV090x_GAINLLR_NFx(8)
2041#define STV090x_OFFST_GAINLLR_NF_QP_4_5_FIELD 0
2042#define STV090x_WIDTH_GAINLLR_NF_QP_4_5_FIELD 7
2043
2044#define STV090x_GAINLLR_NF9 STV090x_GAINLLR_NFx(9)
2045#define STV090x_OFFST_GAINLLR_NF_QP_5_6_FIELD 0
2046#define STV090x_WIDTH_GAINLLR_NF_QP_5_6_FIELD 7
2047
2048#define STV090x_GAINLLR_NF10 STV090x_GAINLLR_NFx(10)
2049#define STV090x_OFFST_GAINLLR_NF_QP_8_9_FIELD 0
2050#define STV090x_WIDTH_GAINLLR_NF_QP_8_9_FIELD 7
2051
2052#define STV090x_GAINLLR_NF11 STV090x_GAINLLR_NFx(11)
2053#define STV090x_OFFST_GAINLLR_NF_QP_9_10_FIELD 0
2054#define STV090x_WIDTH_GAINLLR_NF_QP_9_10_FIELD 7
2055
2056#define STV090x_GAINLLR_NF12 STV090x_GAINLLR_NFx(12)
2057#define STV090x_OFFST_GAINLLR_NF_8P_3_5_FIELD 0
2058#define STV090x_WIDTH_GAINLLR_NF_8P_3_5_FIELD 7
2059
2060#define STV090x_GAINLLR_NF13 STV090x_GAINLLR_NFx(13)
2061#define STV090x_OFFST_GAINLLR_NF_8P_2_3_FIELD 0
2062#define STV090x_WIDTH_GAINLLR_NF_8P_2_3_FIELD 7
2063
2064#define STV090x_GAINLLR_NF14 STV090x_GAINLLR_NFx(14)
2065#define STV090x_OFFST_GAINLLR_NF_8P_3_4_FIELD 0
2066#define STV090x_WIDTH_GAINLLR_NF_8P_3_4_FIELD 7
2067
2068#define STV090x_GAINLLR_NF15 STV090x_GAINLLR_NFx(15)
2069#define STV090x_OFFST_GAINLLR_NF_8P_5_6_FIELD 0
2070#define STV090x_WIDTH_GAINLLR_NF_8P_5_6_FIELD 7
2071
2072#define STV090x_GAINLLR_NF16 STV090x_GAINLLR_NFx(16)
2073#define STV090x_OFFST_GAINLLR_NF_8P_8_9_FIELD 0
2074#define STV090x_WIDTH_GAINLLR_NF_8P_8_9_FIELD 7
2075
2076#define STV090x_GAINLLR_NF17 STV090x_GAINLLR_NFx(17)
2077#define STV090x_OFFST_GAINLLR_NF_8P_9_10_FIELD 0
2078#define STV090x_WIDTH_GAINLLR_NF_8P_9_10_FIELD 7
2079
2080#define STV090x_GENCFG 0xFA86
2081#define STV090x_OFFST_BROADCAST_FIELD 4
2082#define STV090x_WIDTH_BROADCAST_FIELD 1
2083#define STV090x_OFFST_PRIORITY_FIELD 1
2084#define STV090x_WIDTH_PRIORITY_FIELD 1
2085#define STV090x_OFFST_DDEMOD_FIELD 0
2086#define STV090x_WIDTH_DDEMOD_FIELD 1
2087
2088#define STV090x_LDPCERRx(__x) (0xFA97 - (__x * 0x1))
2089#define STV090x_LDPCERR0 STV090x_LDPCERRx(0)
2090#define STV090x_LDPCERR1 STV090x_LDPCERRx(1)
2091#define STV090x_OFFST_Px_LDPC_ERRORS_COUNTER_FIELD 0
2092#define STV090x_WIDTH_Px_LDPC_ERRORS_COUNTER_FIELD 8
2093
2094#define STV090x_BCHERR 0xFA98
2095#define STV090x_OFFST_Px_ERRORFLAG_FIELD 4
2096#define STV090x_WIDTH_Px_ERRORFLAG_FIELD 1
2097#define STV090x_OFFST_Px_BCH_ERRORS_COUNTER_FIELD 0
2098#define STV090x_WIDTH_Px_BCH_ERRORS_COUNTER_FIELD 4
2099
2100#define STV090x_Px_TSSTATEM(__x) (0xF570 - (__x - 1) * 0x200)
2101#define STV090x_P1_TSSTATEM STV090x_Px_TSSTATEM(1)
2102#define STV090x_P2_TSSTATEM STV090x_Px_TSSTATEM(2)
2103#define STV090x_OFFST_Px_TSDIL_ON_FIELD 7
2104#define STV090x_WIDTH_Px_TSDIL_ON_FIELD 1
2105#define STV090x_OFFST_Px_TSRS_ON_FIELD 5
2106#define STV090x_WIDTH_Px_TSRS_ON_FIELD 1
2107
2108#define STV090x_Px_TSCFGH(__x) (0xF572 - (__x - 1) * 0x200)
2109#define STV090x_P1_TSCFGH STV090x_Px_TSCFGH(1)
2110#define STV090x_P2_TSCFGH STV090x_Px_TSCFGH(2)
2111#define STV090x_OFFST_Px_TSFIFO_DVBCI_FIELD 7
2112#define STV090x_WIDTH_Px_TSFIFO_DVBCI_FIELD 1
2113#define STV090x_OFFST_Px_TSFIFO_SERIAL_FIELD 6
2114#define STV090x_WIDTH_Px_TSFIFO_SERIAL_FIELD 1
2115#define STV090x_OFFST_Px_TSFIFO_TEIUPDATE_FIELD 5
2116#define STV090x_WIDTH_Px_TSFIFO_TEIUPDATE_FIELD 1
2117#define STV090x_OFFST_Px_TSFIFO_DUTY50_FIELD 4
2118#define STV090x_WIDTH_Px_TSFIFO_DUTY50_FIELD 1
2119#define STV090x_OFFST_Px_TSFIFO_HSGNLOUT_FIELD 3
2120#define STV090x_WIDTH_Px_TSFIFO_HSGNLOUT_FIELD 1
2121#define STV090x_OFFST_Px_TSFIFO_ERRORMODE_FIELD 1
2122#define STV090x_WIDTH_Px_TSFIFO_ERRORMODE_FIELD 2
2123#define STV090x_OFFST_Px_RST_HWARE_FIELD 0
2124#define STV090x_WIDTH_Px_RST_HWARE_FIELD 1
2125
2126#define STV090x_Px_TSCFGM(__x) (0xF573 - (__x - 1) * 0x200)
2127#define STV090x_P1_TSCFGM STV090x_Px_TSCFGM(1)
2128#define STV090x_P2_TSCFGM STV090x_Px_TSCFGM(2)
2129#define STV090x_OFFST_Px_TSFIFO_MANSPEED_FIELD 6
2130#define STV090x_WIDTH_Px_TSFIFO_MANSPEED_FIELD 2
2131#define STV090x_OFFST_Px_TSFIFO_PERMDATA_FIELD 5
2132#define STV090x_WIDTH_Px_TSFIFO_PERMDATA_FIELD 1
2133#define STV090x_OFFST_Px_TSFIFO_INVDATA_FIELD 0
2134#define STV090x_WIDTH_Px_TSFIFO_INVDATA_FIELD 1
2135
2136#define STV090x_Px_TSCFGL(__x) (0xF574 - (__x - 1) * 0x200)
2137#define STV090x_P1_TSCFGL STV090x_Px_TSCFGL(1)
2138#define STV090x_P2_TSCFGL STV090x_Px_TSCFGL(2)
2139#define STV090x_OFFST_Px_TSFIFO_BCLKDEL1CK_FIELD 6
2140#define STV090x_WIDTH_Px_TSFIFO_BCLKDEL1CK_FIELD 2
2141#define STV090x_OFFST_Px_BCHERROR_MODE_FIELD 4
2142#define STV090x_WIDTH_Px_BCHERROR_MODE_FIELD 2
2143#define STV090x_OFFST_Px_TSFIFO_NSGNL2DATA_FIELD 3
2144#define STV090x_WIDTH_Px_TSFIFO_NSGNL2DATA_FIELD 1
2145#define STV090x_OFFST_Px_TSFIFO_EMBINDVB_FIELD 2
2146#define STV090x_WIDTH_Px_TSFIFO_EMBINDVB_FIELD 1
2147#define STV090x_OFFST_Px_TSFIFO_DPUNACT_FIELD 1
2148#define STV090x_WIDTH_Px_TSFIFO_DPUNACT_FIELD 1
2149
2150#define STV090x_Px_TSINSDELH(__x) (0xF576 - (__x - 1) * 0x200)
2151#define STV090x_P1_TSINSDELH STV090x_Px_TSINSDELH(1)
2152#define STV090x_P2_TSINSDELH STV090x_Px_TSINSDELH(2)
2153#define STV090x_OFFST_Px_TSDEL_SYNCBYTE_FIELD 7
2154#define STV090x_WIDTH_Px_TSDEL_SYNCBYTE_FIELD 1
2155#define STV090x_OFFST_Px_TSDEL_XXHEADER_FIELD 6
2156#define STV090x_WIDTH_Px_TSDEL_XXHEADER_FIELD 1
2157
2158#define STV090x_Px_TSSPEED(__x) (0xF580 - (__x - 1) * 0x200)
2159#define STV090x_P1_TSSPEED STV090x_Px_TSSPEED(1)
2160#define STV090x_P2_TSSPEED STV090x_Px_TSSPEED(2)
2161#define STV090x_OFFST_Px_TSFIFO_OUTSPEED_FIELD 0
2162#define STV090x_WIDTH_Px_TSFIFO_OUTSPEED_FIELD 8
2163
2164#define STV090x_Px_TSSTATUS(__x) (0xF581 - (__x - 1) * 0x200)
2165#define STV090x_P1_TSSTATUS STV090x_Px_TSSTATUS(1)
2166#define STV090x_P2_TSSTATUS STV090x_Px_TSSTATUS(2)
2167#define STV090x_OFFST_Px_TSFIFO_LINEOK_FIELD 7
2168#define STV090x_WIDTH_Px_TSFIFO_LINEOK_FIELD 1
2169#define STV090x_OFFST_Px_TSFIFO_ERROR_FIELD 6
2170#define STV090x_WIDTH_Px_TSFIFO_ERROR_FIELD 1
2171
2172#define STV090x_Px_TSSTATUS2(__x) (0xF582 - (__x - 1) * 0x200)
2173#define STV090x_P1_TSSTATUS2 STV090x_Px_TSSTATUS2(1)
2174#define STV090x_P2_TSSTATUS2 STV090x_Px_TSSTATUS2(2)
2175#define STV090x_OFFST_Px_TSFIFO_DEMODSEL_FIELD 7
2176#define STV090x_WIDTH_Px_TSFIFO_DEMODSEL_FIELD 1
2177#define STV090x_OFFST_Px_TSFIFOSPEED_STORE_FIELD 6
2178#define STV090x_WIDTH_Px_TSFIFOSPEED_STORE_FIELD 1
2179#define STV090x_OFFST_Px_DILXX_RESET_FIELD 5
2180#define STV090x_WIDTH_Px_DILXX_RESET_FIELD 1
2181#define STV090x_OFFST_Px_TSSERIAL_IMPOS_FIELD 4
2182#define STV090x_WIDTH_Px_TSSERIAL_IMPOS_FIELD 1
2183#define STV090x_OFFST_Px_SCRAMBDETECT_FIELD 1
2184#define STV090x_WIDTH_Px_SCRAMBDETECT_FIELD 1
2185
2186#define STV090x_Px_TSBITRATEy(__x, __y) (0xF584 - (__x - 1) * 0x200 - __y * 0x1)
2187#define STV090x_P1_TSBITRATE0 STV090x_Px_TSBITRATEy(1, 0)
2188#define STV090x_P1_TSBITRATE1 STV090x_Px_TSBITRATEy(1, 1)
2189#define STV090x_P2_TSBITRATE0 STV090x_Px_TSBITRATEy(2, 0)
2190#define STV090x_P2_TSBITRATE1 STV090x_Px_TSBITRATEy(2, 1)
2191#define STV090x_OFFST_Px_TSFIFO_BITRATE_FIELD 0
2192#define STV090x_WIDTH_Px_TSFIFO_BITRATE_FIELD 8
2193
2194#define STV090x_Px_ERRCTRL1(__x) (0xF598 - (__x - 1) * 0x200)
2195#define STV090x_P1_ERRCTRL1 STV090x_Px_ERRCTRL1(1)
2196#define STV090x_P2_ERRCTRL1 STV090x_Px_ERRCTRL1(2)
2197#define STV090x_OFFST_Px_ERR_SOURCE_FIELD 4
2198#define STV090x_WIDTH_Px_ERR_SOURCE_FIELD 4
2199#define STV090x_OFFST_Px_NUM_EVENT_FIELD 0
2200#define STV090x_WIDTH_Px_NUM_EVENT_FIELD 3
2201
2202#define STV090x_Px_ERRCNT12(__x) (0xF599 - (__x - 1) * 0x200)
2203#define STV090x_P1_ERRCNT12 STV090x_Px_ERRCNT12(1)
2204#define STV090x_P2_ERRCNT12 STV090x_Px_ERRCNT12(2)
2205#define STV090x_OFFST_Px_ERRCNT1_OLDVALUE_FIELD 7
2206#define STV090x_WIDTH_Px_ERRCNT1_OLDVALUE_FIELD 1
2207#define STV090x_OFFST_Px_ERR_CNT12_FIELD 0
2208#define STV090x_WIDTH_Px_ERR_CNT12_FIELD 7
2209
2210#define STV090x_Px_ERRCNT11(__x) (0xF59A - (__x - 1) * 0x200)
2211#define STV090x_P1_ERRCNT11 STV090x_Px_ERRCNT11(1)
2212#define STV090x_P2_ERRCNT11 STV090x_Px_ERRCNT11(2)
2213#define STV090x_OFFST_Px_ERR_CNT11_FIELD 0
2214#define STV090x_WIDTH_Px_ERR_CNT11_FIELD 8
2215
2216#define STV090x_Px_ERRCNT10(__x) (0xF59B - (__x - 1) * 0x200)
2217#define STV090x_P1_ERRCNT10 STV090x_Px_ERRCNT10(1)
2218#define STV090x_P2_ERRCNT10 STV090x_Px_ERRCNT10(2)
2219#define STV090x_OFFST_Px_ERR_CNT10_FIELD 0
2220#define STV090x_WIDTH_Px_ERR_CNT10_FIELD 8
2221
2222#define STV090x_Px_ERRCTRL2(__x) (0xF59C - (__x - 1) * 0x200)
2223#define STV090x_P1_ERRCTRL2 STV090x_Px_ERRCTRL2(1)
2224#define STV090x_P2_ERRCTRL2 STV090x_Px_ERRCTRL2(2)
2225#define STV090x_OFFST_Px_ERR_SOURCE2_FIELD 4
2226#define STV090x_WIDTH_Px_ERR_SOURCE2_FIELD 4
2227#define STV090x_OFFST_Px_NUM_EVENT2_FIELD 0
2228#define STV090x_WIDTH_Px_NUM_EVENT2_FIELD 3
2229
2230#define STV090x_Px_ERRCNT22(__x) (0xF59D - (__x - 1) * 0x200)
2231#define STV090x_P1_ERRCNT22 STV090x_Px_ERRCNT22(1)
2232#define STV090x_P2_ERRCNT22 STV090x_Px_ERRCNT22(2)
2233#define STV090x_OFFST_Px_ERRCNT2_OLDVALUE_FIELD 7
2234#define STV090x_WIDTH_Px_ERRCNT2_OLDVALUE_FIELD 1
2235#define STV090x_OFFST_Px_ERR_CNT2_FIELD 0
2236#define STV090x_WIDTH_Px_ERR_CNT2_FIELD 7
2237
2238#define STV090x_Px_ERRCNT21(__x) (0xF59E - (__x - 1) * 0x200)
2239#define STV090x_P1_ERRCNT21 STV090x_Px_ERRCNT21(1)
2240#define STV090x_P2_ERRCNT21 STV090x_Px_ERRCNT21(2)
2241#define STV090x_OFFST_Px_ERR_CNT21_FIELD 0
2242#define STV090x_WIDTH_Px_ERR_CNT21_FIELD 8
2243
2244#define STV090x_Px_ERRCNT20(__x) (0xF59F - (__x - 1) * 0x200)
2245#define STV090x_P1_ERRCNT20 STV090x_Px_ERRCNT20(1)
2246#define STV090x_P2_ERRCNT20 STV090x_Px_ERRCNT20(2)
2247#define STV090x_OFFST_Px_ERR_CNT20_FIELD 0
2248#define STV090x_WIDTH_Px_ERR_CNT20_FIELD 8
2249
2250#define STV090x_Px_FECSPY(__x) (0xF5A0 - (__x - 1) * 0x200)
2251#define STV090x_P1_FECSPY STV090x_Px_FECSPY(1)
2252#define STV090x_P2_FECSPY STV090x_Px_FECSPY(2)
2253#define STV090x_OFFST_Px_SPY_ENABLE_FIELD 7
2254#define STV090x_WIDTH_Px_SPY_ENABLE_FIELD 1
2255#define STV090x_OFFST_Px_BERMETER_DATAMAODE_FIELD 2
2256#define STV090x_WIDTH_Px_BERMETER_DATAMAODE_FIELD 2
2257
2258#define STV090x_Px_FSPYCFG(__x) (0xF5A1 - (__x - 1) * 0x200)
2259#define STV090x_P1_FSPYCFG STV090x_Px_FSPYCFG(1)
2260#define STV090x_P2_FSPYCFG STV090x_Px_FSPYCFG(2)
2261#define STV090x_OFFST_Px_RST_ON_ERROR_FIELD 5
2262#define STV090x_WIDTH_Px_RST_ON_ERROR_FIELD 1
2263#define STV090x_OFFST_Px_ONE_SHOT_FIELD 4
2264#define STV090x_WIDTH_Px_ONE_SHOT_FIELD 1
2265#define STV090x_OFFST_Px_I2C_MODE_FIELD 2
2266#define STV090x_WIDTH_Px_I2C_MODE_FIELD 2
2267
2268#define STV090x_Px_FSPYDATA(__x) (0xF5A2 - (__x - 1) * 0x200)
2269#define STV090x_P1_FSPYDATA STV090x_Px_FSPYDATA(1)
2270#define STV090x_P2_FSPYDATA STV090x_Px_FSPYDATA(2)
2271#define STV090x_OFFST_Px_SPY_STUFFING_FIELD 7
2272#define STV090x_WIDTH_Px_SPY_STUFFING_FIELD 1
2273#define STV090x_OFFST_Px_SPY_CNULLPKT_FIELD 5
2274#define STV090x_WIDTH_Px_SPY_CNULLPKT_FIELD 1
2275#define STV090x_OFFST_Px_SPY_OUTDATA_MODE_FIELD 0
2276#define STV090x_WIDTH_Px_SPY_OUTDATA_MODE_FIELD 5
2277
2278#define STV090x_Px_FSPYOUT(__x) (0xF5A3 - (__x - 1) * 0x200)
2279#define STV090x_P1_FSPYOUT STV090x_Px_FSPYOUT(1)
2280#define STV090x_P2_FSPYOUT STV090x_Px_FSPYOUT(2)
2281#define STV090x_OFFST_Px_FSPY_DIRECT_FIELD 7
2282#define STV090x_WIDTH_Px_FSPY_DIRECT_FIELD 1
2283#define STV090x_OFFST_Px_STUFF_MODE_FIELD 0
2284#define STV090x_WIDTH_Px_STUFF_MODE_FIELD 3
2285
2286#define STV090x_Px_FSTATUS(__x) (0xF5A4 - (__x - 1) * 0x200)
2287#define STV090x_P1_FSTATUS STV090x_Px_FSTATUS(1)
2288#define STV090x_P2_FSTATUS STV090x_Px_FSTATUS(2)
2289#define STV090x_OFFST_Px_SPY_ENDSIM_FIELD 7
2290#define STV090x_WIDTH_Px_SPY_ENDSIM_FIELD 1
2291#define STV090x_OFFST_Px_VALID_SIM_FIELD 6
2292#define STV090x_WIDTH_Px_VALID_SIM_FIELD 1
2293#define STV090x_OFFST_Px_FOUND_SIGNAL_FIELD 5
2294#define STV090x_WIDTH_Px_FOUND_SIGNAL_FIELD 1
2295#define STV090x_OFFST_Px_DSS_SYNCBYTE_FIELD 4
2296#define STV090x_WIDTH_Px_DSS_SYNCBYTE_FIELD 1
2297#define STV090x_OFFST_Px_RESULT_STATE_FIELD 0
2298#define STV090x_WIDTH_Px_RESULT_STATE_FIELD 4
2299
2300#define STV090x_Px_FBERCPT4(__x) (0xF5A8 - (__x - 1) * 0x200)
2301#define STV090x_P1_FBERCPT4 STV090x_Px_FBERCPT4(1)
2302#define STV090x_P2_FBERCPT4 STV090x_Px_FBERCPT4(2)
2303#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
2304#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
2305
2306#define STV090x_Px_FBERCPT3(__x) (0xF5A9 - (__x - 1) * 0x200)
2307#define STV090x_P1_FBERCPT3 STV090x_Px_FBERCPT3(1)
2308#define STV090x_P2_FBERCPT3 STV090x_Px_FBERCPT3(2)
2309#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
2310#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
2311
2312#define STV090x_Px_FBERCPT2(__x) (0xF5AA - (__x - 1) * 0x200)
2313#define STV090x_P1_FBERCPT2 STV090x_Px_FBERCPT2(1)
2314#define STV090x_P2_FBERCPT2 STV090x_Px_FBERCPT2(2)
2315#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
2316#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
2317
2318#define STV090x_Px_FBERCPT1(__x) (0xF5AB - (__x - 1) * 0x200)
2319#define STV090x_P1_FBERCPT1 STV090x_Px_FBERCPT1(1)
2320#define STV090x_P2_FBERCPT1 STV090x_Px_FBERCPT1(2)
2321#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
2322#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
2323
2324#define STV090x_Px_FBERCPT0(__x) (0xF5AC - (__x - 1) * 0x200)
2325#define STV090x_P1_FBERCPT0 STV090x_Px_FBERCPT0(1)
2326#define STV090x_P2_FBERCPT0 STV090x_Px_FBERCPT0(2)
2327#define STV090x_OFFST_Px_FBERMETER_CPT_FIELD 0
2328#define STV090x_WIDTH_Px_FBERMETER_CPT_FIELD 8
2329
2330#define STV090x_Px_FBERERRy(__x, __y) (0xF5AF - (__x - 1) * 0x200 - __y * 0x1)
2331#define STV090x_P1_FBERERR0 STV090x_Px_FBERERRy(1, 0)
2332#define STV090x_P1_FBERERR1 STV090x_Px_FBERERRy(1, 1)
2333#define STV090x_P1_FBERERR2 STV090x_Px_FBERERRy(1, 2)
2334#define STV090x_P2_FBERERR0 STV090x_Px_FBERERRy(2, 0)
2335#define STV090x_P2_FBERERR1 STV090x_Px_FBERERRy(2, 1)
2336#define STV090x_P2_FBERERR2 STV090x_Px_FBERERRy(2, 2)
2337#define STV090x_OFFST_Px_FBERMETER_CPT_ERR_FIELD 0
2338#define STV090x_WIDTH_Px_FBERMETER_CPT_ERR_FIELD 8
2339
2340#define STV090x_Px_FSPYBER(__x) (0xF5B2 - (__x - 1) * 0x200)
2341#define STV090x_P1_FSPYBER STV090x_Px_FSPYBER(1)
2342#define STV090x_P2_FSPYBER STV090x_Px_FSPYBER(2)
2343#define STV090x_OFFST_Px_FSPYBER_SYNCBYTE_FIELD 4
2344#define STV090x_WIDTH_Px_FSPYBER_SYNCBYTE_FIELD 1
2345#define STV090x_OFFST_Px_FSPYBER_UNSYNC_FIELD 3
2346#define STV090x_WIDTH_Px_FSPYBER_UNSYNC_FIELD 1
2347#define STV090x_OFFST_Px_FSPYBER_CTIME_FIELD 0
2348#define STV090x_WIDTH_Px_FSPYBER_CTIME_FIELD 3
2349
2350#define STV090x_RCCFGH 0xf600
2351
2352#define STV090x_TSGENERAL 0xF630
2353#define STV090x_OFFST_Px_MUXSTREAM_OUT_FIELD 3
2354#define STV090x_WIDTH_Px_MUXSTREAM_OUT_FIELD 1
2355#define STV090x_OFFST_Px_TSFIFO_PERMPARAL_FIELD 1
2356#define STV090x_WIDTH_Px_TSFIFO_PERMPARAL_FIELD 2
2357
2358#define STV090x_TSGENERAL1X 0xf670
2359#define STV090x_CFGEXT 0xfa80
2360
2361#define STV090x_TSTRES0 0xFF11
2362#define STV090x_OFFST_FRESFEC_FIELD 7
2363#define STV090x_WIDTH_FRESFEC_FIELD 1
2364
2365#define STV090x_Px_TSTDISRX(__x) (0xFF67 - (__x - 1) * 0x2)
2366#define STV090x_P1_TSTDISRX STV090x_Px_TSTDISRX(1)
2367#define STV090x_P2_TSTDISRX STV090x_Px_TSTDISRX(2)
2368#define STV090x_OFFST_Px_TSTDISRX_SELECT_FIELD 3
2369#define STV090x_WIDTH_Px_TSTDISRX_SELECT_FIELD 1
2370
2371#endif /* __STV090x_REG_H */
diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c
new file mode 100644
index 00000000000..2dca7c8e514
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110.c
@@ -0,0 +1,452 @@
1/*
2 * stv6110.c
3 *
4 * Driver for ST STV6110 satellite tuner IC.
5 *
6 * Copyright (C) 2009 NetUP Inc.
7 * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
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 *
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
25#include <linux/slab.h>
26#include <linux/module.h>
27#include <linux/dvb/frontend.h>
28
29#include <linux/types.h>
30
31#include "stv6110.h"
32
33static int debug;
34
35struct stv6110_priv {
36 int i2c_address;
37 struct i2c_adapter *i2c;
38
39 u32 mclk;
40 u8 clk_div;
41 u8 gain;
42 u8 regs[8];
43};
44
45#define dprintk(args...) \
46 do { \
47 if (debug) \
48 printk(KERN_DEBUG args); \
49 } while (0)
50
51static s32 abssub(s32 a, s32 b)
52{
53 if (a > b)
54 return a - b;
55 else
56 return b - a;
57};
58
59static int stv6110_release(struct dvb_frontend *fe)
60{
61 kfree(fe->tuner_priv);
62 fe->tuner_priv = NULL;
63 return 0;
64}
65
66static int stv6110_write_regs(struct dvb_frontend *fe, u8 buf[],
67 int start, int len)
68{
69 struct stv6110_priv *priv = fe->tuner_priv;
70 int rc;
71 u8 cmdbuf[len + 1];
72 struct i2c_msg msg = {
73 .addr = priv->i2c_address,
74 .flags = 0,
75 .buf = cmdbuf,
76 .len = len + 1
77 };
78
79 dprintk("%s\n", __func__);
80
81 if (start + len > 8)
82 return -EINVAL;
83
84 memcpy(&cmdbuf[1], buf, len);
85 cmdbuf[0] = start;
86
87 if (fe->ops.i2c_gate_ctrl)
88 fe->ops.i2c_gate_ctrl(fe, 1);
89
90 rc = i2c_transfer(priv->i2c, &msg, 1);
91 if (rc != 1)
92 dprintk("%s: i2c error\n", __func__);
93
94 if (fe->ops.i2c_gate_ctrl)
95 fe->ops.i2c_gate_ctrl(fe, 0);
96
97 return 0;
98}
99
100static int stv6110_read_regs(struct dvb_frontend *fe, u8 regs[],
101 int start, int len)
102{
103 struct stv6110_priv *priv = fe->tuner_priv;
104 int rc;
105 u8 reg[] = { start };
106 struct i2c_msg msg[] = {
107 {
108 .addr = priv->i2c_address,
109 .flags = 0,
110 .buf = reg,
111 .len = 1,
112 }, {
113 .addr = priv->i2c_address,
114 .flags = I2C_M_RD,
115 .buf = regs,
116 .len = len,
117 },
118 };
119
120 if (fe->ops.i2c_gate_ctrl)
121 fe->ops.i2c_gate_ctrl(fe, 1);
122
123 rc = i2c_transfer(priv->i2c, msg, 2);
124 if (rc != 2)
125 dprintk("%s: i2c error\n", __func__);
126
127 if (fe->ops.i2c_gate_ctrl)
128 fe->ops.i2c_gate_ctrl(fe, 0);
129
130 memcpy(&priv->regs[start], regs, len);
131
132 return 0;
133}
134
135static int stv6110_read_reg(struct dvb_frontend *fe, int start)
136{
137 u8 buf[] = { 0 };
138 stv6110_read_regs(fe, buf, start, 1);
139
140 return buf[0];
141}
142
143static int stv6110_sleep(struct dvb_frontend *fe)
144{
145 u8 reg[] = { 0 };
146 stv6110_write_regs(fe, reg, 0, 1);
147
148 return 0;
149}
150
151static u32 carrier_width(u32 symbol_rate, fe_rolloff_t rolloff)
152{
153 u32 rlf;
154
155 switch (rolloff) {
156 case ROLLOFF_20:
157 rlf = 20;
158 break;
159 case ROLLOFF_25:
160 rlf = 25;
161 break;
162 default:
163 rlf = 35;
164 break;
165 }
166
167 return symbol_rate + ((symbol_rate * rlf) / 100);
168}
169
170static int stv6110_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
171{
172 struct stv6110_priv *priv = fe->tuner_priv;
173 u8 r8, ret = 0x04;
174 int i;
175
176 if ((bandwidth / 2) > 36000000) /*BW/2 max=31+5=36 mhz for r8=31*/
177 r8 = 31;
178 else if ((bandwidth / 2) < 5000000) /* BW/2 min=5Mhz for F=0 */
179 r8 = 0;
180 else /*if 5 < BW/2 < 36*/
181 r8 = (bandwidth / 2) / 1000000 - 5;
182
183 /* ctrl3, RCCLKOFF = 0 Activate the calibration Clock */
184 /* ctrl3, CF = r8 Set the LPF value */
185 priv->regs[RSTV6110_CTRL3] &= ~((1 << 6) | 0x1f);
186 priv->regs[RSTV6110_CTRL3] |= (r8 & 0x1f);
187 stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
188 /* stat1, CALRCSTRT = 1 Start LPF auto calibration*/
189 priv->regs[RSTV6110_STAT1] |= 0x02;
190 stv6110_write_regs(fe, &priv->regs[RSTV6110_STAT1], RSTV6110_STAT1, 1);
191
192 i = 0;
193 /* Wait for CALRCSTRT == 0 */
194 while ((i < 10) && (ret != 0)) {
195 ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x02);
196 mdelay(1); /* wait for LPF auto calibration */
197 i++;
198 }
199
200 /* RCCLKOFF = 1 calibration done, desactivate the calibration Clock */
201 priv->regs[RSTV6110_CTRL3] |= (1 << 6);
202 stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
203 return 0;
204}
205
206static int stv6110_init(struct dvb_frontend *fe)
207{
208 struct stv6110_priv *priv = fe->tuner_priv;
209 u8 buf0[] = { 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };
210
211 memcpy(priv->regs, buf0, 8);
212 /* K = (Reference / 1000000) - 16 */
213 priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
214 priv->regs[RSTV6110_CTRL1] |=
215 ((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
216
217 /* divisor value for the output clock */
218 priv->regs[RSTV6110_CTRL2] &= ~0xc0;
219 priv->regs[RSTV6110_CTRL2] |= (priv->clk_div << 6);
220
221 stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], RSTV6110_CTRL1, 8);
222 msleep(1);
223 stv6110_set_bandwidth(fe, 72000000);
224
225 return 0;
226}
227
228static int stv6110_get_frequency(struct dvb_frontend *fe, u32 *frequency)
229{
230 struct stv6110_priv *priv = fe->tuner_priv;
231 u32 nbsteps, divider, psd2, freq;
232 u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
233
234 stv6110_read_regs(fe, regs, 0, 8);
235 /*N*/
236 divider = (priv->regs[RSTV6110_TUNING2] & 0x0f) << 8;
237 divider += priv->regs[RSTV6110_TUNING1];
238
239 /*R*/
240 nbsteps = (priv->regs[RSTV6110_TUNING2] >> 6) & 3;
241 /*p*/
242 psd2 = (priv->regs[RSTV6110_TUNING2] >> 4) & 1;
243
244 freq = divider * (priv->mclk / 1000);
245 freq /= (1 << (nbsteps + psd2));
246 freq /= 4;
247
248 *frequency = freq;
249
250 return 0;
251}
252
253static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
254{
255 struct stv6110_priv *priv = fe->tuner_priv;
256 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
257 u8 ret = 0x04;
258 u32 divider, ref, p, presc, i, result_freq, vco_freq;
259 s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val;
260 s32 srate;
261
262 dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__,
263 frequency, priv->mclk);
264
265 /* K = (Reference / 1000000) - 16 */
266 priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
267 priv->regs[RSTV6110_CTRL1] |=
268 ((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
269
270 /* BB_GAIN = db/2 */
271 if (fe->ops.set_property && fe->ops.get_property) {
272 srate = c->symbol_rate;
273 dprintk("%s: Get Frontend parameters: srate=%d\n",
274 __func__, srate);
275 } else
276 srate = 15000000;
277
278 priv->regs[RSTV6110_CTRL2] &= ~0x0f;
279 priv->regs[RSTV6110_CTRL2] |= (priv->gain & 0x0f);
280
281 if (frequency <= 1023000) {
282 p = 1;
283 presc = 0;
284 } else if (frequency <= 1300000) {
285 p = 1;
286 presc = 1;
287 } else if (frequency <= 2046000) {
288 p = 0;
289 presc = 0;
290 } else {
291 p = 0;
292 presc = 1;
293 }
294 /* DIV4SEL = p*/
295 priv->regs[RSTV6110_TUNING2] &= ~(1 << 4);
296 priv->regs[RSTV6110_TUNING2] |= (p << 4);
297
298 /* PRESC32ON = presc */
299 priv->regs[RSTV6110_TUNING2] &= ~(1 << 5);
300 priv->regs[RSTV6110_TUNING2] |= (presc << 5);
301
302 p_val = (int)(1 << (p + 1)) * 10;/* P = 2 or P = 4 */
303 for (r_div = 0; r_div <= 3; r_div++) {
304 p_calc = (priv->mclk / 100000);
305 p_calc /= (1 << (r_div + 1));
306 if ((abssub(p_calc, p_val)) < (abssub(p_calc_opt, p_val)))
307 r_div_opt = r_div;
308
309 p_calc_opt = (priv->mclk / 100000);
310 p_calc_opt /= (1 << (r_div_opt + 1));
311 }
312
313 ref = priv->mclk / ((1 << (r_div_opt + 1)) * (1 << (p + 1)));
314 divider = (((frequency * 1000) + (ref >> 1)) / ref);
315
316 /* RDIV = r_div_opt */
317 priv->regs[RSTV6110_TUNING2] &= ~(3 << 6);
318 priv->regs[RSTV6110_TUNING2] |= (((r_div_opt) & 3) << 6);
319
320 /* NDIV_MSB = MSB(divider) */
321 priv->regs[RSTV6110_TUNING2] &= ~0x0f;
322 priv->regs[RSTV6110_TUNING2] |= (((divider) >> 8) & 0x0f);
323
324 /* NDIV_LSB, LSB(divider) */
325 priv->regs[RSTV6110_TUNING1] = (divider & 0xff);
326
327 /* CALVCOSTRT = 1 VCO Auto Calibration */
328 priv->regs[RSTV6110_STAT1] |= 0x04;
329 stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1],
330 RSTV6110_CTRL1, 8);
331
332 i = 0;
333 /* Wait for CALVCOSTRT == 0 */
334 while ((i < 10) && (ret != 0)) {
335 ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x04);
336 msleep(1); /* wait for VCO auto calibration */
337 i++;
338 }
339
340 ret = stv6110_read_reg(fe, RSTV6110_STAT1);
341 stv6110_get_frequency(fe, &result_freq);
342
343 vco_freq = divider * ((priv->mclk / 1000) / ((1 << (r_div_opt + 1))));
344 dprintk("%s, stat1=%x, lo_freq=%d kHz, vco_frec=%d kHz\n", __func__,
345 ret, result_freq, vco_freq);
346
347 return 0;
348}
349
350static int stv6110_set_params(struct dvb_frontend *fe,
351 struct dvb_frontend_parameters *params)
352{
353 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
354 u32 bandwidth = carrier_width(c->symbol_rate, c->rolloff);
355
356 stv6110_set_frequency(fe, c->frequency);
357 stv6110_set_bandwidth(fe, bandwidth);
358
359 return 0;
360}
361
362static int stv6110_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
363{
364 struct stv6110_priv *priv = fe->tuner_priv;
365 u8 r8 = 0;
366 u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
367 stv6110_read_regs(fe, regs, 0, 8);
368
369 /* CF */
370 r8 = priv->regs[RSTV6110_CTRL3] & 0x1f;
371 *bandwidth = (r8 + 5) * 2000000;/* x2 for ZIF tuner BW/2 = F+5 Mhz */
372
373 return 0;
374}
375
376static struct dvb_tuner_ops stv6110_tuner_ops = {
377 .info = {
378 .name = "ST STV6110",
379 .frequency_min = 950000,
380 .frequency_max = 2150000,
381 .frequency_step = 1000,
382 },
383 .init = stv6110_init,
384 .release = stv6110_release,
385 .sleep = stv6110_sleep,
386 .set_params = stv6110_set_params,
387 .get_frequency = stv6110_get_frequency,
388 .set_frequency = stv6110_set_frequency,
389 .get_bandwidth = stv6110_get_bandwidth,
390 .set_bandwidth = stv6110_set_bandwidth,
391
392};
393
394struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
395 const struct stv6110_config *config,
396 struct i2c_adapter *i2c)
397{
398 struct stv6110_priv *priv = NULL;
399 u8 reg0[] = { 0x00, 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };
400
401 struct i2c_msg msg[] = {
402 {
403 .addr = config->i2c_address,
404 .flags = 0,
405 .buf = reg0,
406 .len = 9
407 }
408 };
409 int ret;
410
411 /* divisor value for the output clock */
412 reg0[2] &= ~0xc0;
413 reg0[2] |= (config->clk_div << 6);
414
415 if (fe->ops.i2c_gate_ctrl)
416 fe->ops.i2c_gate_ctrl(fe, 1);
417
418 ret = i2c_transfer(i2c, msg, 1);
419
420 if (fe->ops.i2c_gate_ctrl)
421 fe->ops.i2c_gate_ctrl(fe, 0);
422
423 if (ret != 1)
424 return NULL;
425
426 priv = kzalloc(sizeof(struct stv6110_priv), GFP_KERNEL);
427 if (priv == NULL)
428 return NULL;
429
430 priv->i2c_address = config->i2c_address;
431 priv->i2c = i2c;
432 priv->mclk = config->mclk;
433 priv->clk_div = config->clk_div;
434 priv->gain = config->gain;
435
436 memcpy(&priv->regs, &reg0[1], 8);
437
438 memcpy(&fe->ops.tuner_ops, &stv6110_tuner_ops,
439 sizeof(struct dvb_tuner_ops));
440 fe->tuner_priv = priv;
441 printk(KERN_INFO "STV6110 attached on addr=%x!\n", priv->i2c_address);
442
443 return fe;
444}
445EXPORT_SYMBOL(stv6110_attach);
446
447module_param(debug, int, 0644);
448MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
449
450MODULE_DESCRIPTION("ST STV6110 driver");
451MODULE_AUTHOR("Igor M. Liplianin");
452MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv6110.h b/drivers/media/dvb/frontends/stv6110.h
new file mode 100644
index 00000000000..fe71bba6a26
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110.h
@@ -0,0 +1,63 @@
1/*
2 * stv6110.h
3 *
4 * Driver for ST STV6110 satellite tuner IC.
5 *
6 * Copyright (C) 2009 NetUP Inc.
7 * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
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 *
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
25#ifndef __DVB_STV6110_H__
26#define __DVB_STV6110_H__
27
28#include <linux/i2c.h>
29#include "dvb_frontend.h"
30
31/* registers */
32#define RSTV6110_CTRL1 0
33#define RSTV6110_CTRL2 1
34#define RSTV6110_TUNING1 2
35#define RSTV6110_TUNING2 3
36#define RSTV6110_CTRL3 4
37#define RSTV6110_STAT1 5
38#define RSTV6110_STAT2 6
39#define RSTV6110_STAT3 7
40
41struct stv6110_config {
42 u8 i2c_address;
43 u32 mclk;
44 u8 gain;
45 u8 clk_div; /* divisor value for the output clock */
46};
47
48#if defined(CONFIG_DVB_STV6110) || (defined(CONFIG_DVB_STV6110_MODULE) \
49 && defined(MODULE))
50extern struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
51 const struct stv6110_config *config,
52 struct i2c_adapter *i2c);
53#else
54static inline struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
55 const struct stv6110_config *config,
56 struct i2c_adapter *i2c)
57{
58 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
59 return NULL;
60}
61#endif
62
63#endif
diff --git a/drivers/media/dvb/frontends/stv6110x.c b/drivers/media/dvb/frontends/stv6110x.c
new file mode 100644
index 00000000000..f36cab12bdc
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110x.c
@@ -0,0 +1,405 @@
1/*
2 STV6110(A) Silicon tuner driver
3
4 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
5
6 Copyright (C) ST Microelectronics
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#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/slab.h>
27#include <linux/string.h>
28
29#include "dvb_frontend.h"
30
31#include "stv6110x_reg.h"
32#include "stv6110x.h"
33#include "stv6110x_priv.h"
34
35static unsigned int verbose;
36module_param(verbose, int, 0644);
37MODULE_PARM_DESC(verbose, "Set Verbosity level");
38
39static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data)
40{
41 int ret;
42 const struct stv6110x_config *config = stv6110x->config;
43 u8 b0[] = { reg };
44 u8 b1[] = { 0 };
45 struct i2c_msg msg[] = {
46 { .addr = config->addr, .flags = 0, .buf = b0, .len = 1 },
47 { .addr = config->addr, .flags = I2C_M_RD, .buf = b1, .len = 1 }
48 };
49
50 ret = i2c_transfer(stv6110x->i2c, msg, 2);
51 if (ret != 2) {
52 dprintk(FE_ERROR, 1, "I/O Error");
53 return -EREMOTEIO;
54 }
55 *data = b1[0];
56
57 return 0;
58}
59
60static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 data[], int len)
61{
62 int ret;
63 const struct stv6110x_config *config = stv6110x->config;
64 u8 buf[len + 1];
65 struct i2c_msg msg = {
66 .addr = config->addr,
67 .flags = 0,
68 .buf = buf,
69 .len = len + 1
70 };
71
72 if (start + len > 8)
73 return -EINVAL;
74
75 buf[0] = start;
76 memcpy(&buf[1], data, len);
77
78 ret = i2c_transfer(stv6110x->i2c, &msg, 1);
79 if (ret != 1) {
80 dprintk(FE_ERROR, 1, "I/O Error");
81 return -EREMOTEIO;
82 }
83
84 return 0;
85}
86
87static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
88{
89 return stv6110x_write_regs(stv6110x, reg, &data, 1);
90}
91
92static int stv6110x_init(struct dvb_frontend *fe)
93{
94 struct stv6110x_state *stv6110x = fe->tuner_priv;
95 int ret;
96
97 ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs,
98 ARRAY_SIZE(stv6110x->regs));
99 if (ret < 0) {
100 dprintk(FE_ERROR, 1, "Initialization failed");
101 return -1;
102 }
103
104 return 0;
105}
106
107static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency)
108{
109 struct stv6110x_state *stv6110x = fe->tuner_priv;
110 u32 rDiv, divider;
111 s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000;
112 u8 i;
113
114 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16));
115
116 if (frequency <= 1023000) {
117 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
118 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
119 pVal = 40;
120 } else if (frequency <= 1300000) {
121 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
122 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
123 pVal = 40;
124 } else if (frequency <= 2046000) {
125 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
126 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
127 pVal = 20;
128 } else {
129 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
130 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
131 pVal = 20;
132 }
133
134 for (rDiv = 0; rDiv <= 3; rDiv++) {
135 pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv);
136
137 if ((abs((s32)(pCalc - pVal))) < (abs((s32)(pCalcOpt - pVal))))
138 rDivOpt = rDiv;
139
140 pCalcOpt = (REFCLOCK_kHz / 100) / R_DIV(rDivOpt);
141 }
142
143 divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz;
144 divider = (divider + 5) / 10;
145
146 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt);
147 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider));
148 STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider));
149
150 /* VCO Auto calibration */
151 STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1);
152
153 stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]);
154 stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x->regs[STV6110x_TNG1]);
155 stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x->regs[STV6110x_TNG0]);
156 stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]);
157
158 for (i = 0; i < TRIALS; i++) {
159 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
160 if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x->regs[STV6110x_STAT1]))
161 break;
162 msleep(1);
163 }
164
165 return 0;
166}
167
168static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
169{
170 struct stv6110x_state *stv6110x = fe->tuner_priv;
171
172 stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x->regs[STV6110x_TNG1]);
173 stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x->regs[STV6110x_TNG0]);
174
175 *frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x->regs[STV6110x_TNG1]),
176 STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x->regs[STV6110x_TNG0]))) * REFCLOCK_kHz;
177
178 *frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x->regs[STV6110x_TNG1]) +
179 STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x->regs[STV6110x_TNG1])));
180
181 *frequency >>= 2;
182
183 return 0;
184}
185
186static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
187{
188 struct stv6110x_state *stv6110x = fe->tuner_priv;
189 u32 halfbw;
190 u8 i;
191
192 halfbw = bandwidth >> 1;
193
194 if (halfbw > 36000000)
195 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */
196 else if (halfbw < 5000000)
197 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */
198 else
199 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */
200
201
202 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */
203 STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */
204
205 stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]);
206 stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]);
207
208 for (i = 0; i < TRIALS; i++) {
209 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
210 if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x->regs[STV6110x_STAT1]))
211 break;
212 msleep(1);
213 }
214 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */
215 stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]);
216
217 return 0;
218}
219
220static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
221{
222 struct stv6110x_state *stv6110x = fe->tuner_priv;
223
224 stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x->regs[STV6110x_CTRL3]);
225 *bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x->regs[STV6110x_CTRL3]) + 5) * 2000000;
226
227 return 0;
228}
229
230static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock)
231{
232 struct stv6110x_state *stv6110x = fe->tuner_priv;
233
234 /* setup divider */
235 switch (refclock) {
236 default:
237 case 1:
238 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
239 break;
240 case 2:
241 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
242 break;
243 case 4:
244 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
245 break;
246 case 8:
247 case 0:
248 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
249 break;
250 }
251 stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]);
252
253 return 0;
254}
255
256static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain)
257{
258 struct stv6110x_state *stv6110x = fe->tuner_priv;
259
260 stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x->regs[STV6110x_CTRL2]);
261 *gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x->regs[STV6110x_CTRL2]);
262
263 return 0;
264}
265
266static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain)
267{
268 struct stv6110x_state *stv6110x = fe->tuner_priv;
269
270 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2);
271 stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]);
272
273 return 0;
274}
275
276static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode)
277{
278 struct stv6110x_state *stv6110x = fe->tuner_priv;
279 int ret;
280
281 switch (mode) {
282 case TUNER_SLEEP:
283 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 0);
284 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 0);
285 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 0);
286 break;
287
288 case TUNER_WAKE:
289 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 1);
290 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 1);
291 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 1);
292 break;
293 }
294
295 ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]);
296 if (ret < 0) {
297 dprintk(FE_ERROR, 1, "I/O Error");
298 return -EIO;
299 }
300
301 return 0;
302}
303
304static int stv6110x_sleep(struct dvb_frontend *fe)
305{
306 if (fe->tuner_priv)
307 return stv6110x_set_mode(fe, TUNER_SLEEP);
308
309 return 0;
310}
311
312static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status)
313{
314 struct stv6110x_state *stv6110x = fe->tuner_priv;
315
316 stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
317
318 if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x->regs[STV6110x_STAT1]))
319 *status = TUNER_PHASELOCKED;
320 else
321 *status = 0;
322
323 return 0;
324}
325
326
327static int stv6110x_release(struct dvb_frontend *fe)
328{
329 struct stv6110x_state *stv6110x = fe->tuner_priv;
330
331 fe->tuner_priv = NULL;
332 kfree(stv6110x);
333
334 return 0;
335}
336
337static struct dvb_tuner_ops stv6110x_ops = {
338 .info = {
339 .name = "STV6110(A) Silicon Tuner",
340 .frequency_min = 950000,
341 .frequency_max = 2150000,
342 .frequency_step = 0,
343 },
344 .release = stv6110x_release
345};
346
347static struct stv6110x_devctl stv6110x_ctl = {
348 .tuner_init = stv6110x_init,
349 .tuner_sleep = stv6110x_sleep,
350 .tuner_set_mode = stv6110x_set_mode,
351 .tuner_set_frequency = stv6110x_set_frequency,
352 .tuner_get_frequency = stv6110x_get_frequency,
353 .tuner_set_bandwidth = stv6110x_set_bandwidth,
354 .tuner_get_bandwidth = stv6110x_get_bandwidth,
355 .tuner_set_bbgain = stv6110x_set_bbgain,
356 .tuner_get_bbgain = stv6110x_get_bbgain,
357 .tuner_set_refclk = stv6110x_set_refclock,
358 .tuner_get_status = stv6110x_get_status,
359};
360
361struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
362 const struct stv6110x_config *config,
363 struct i2c_adapter *i2c)
364{
365 struct stv6110x_state *stv6110x;
366 u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e};
367
368 stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL);
369 if (!stv6110x)
370 return NULL;
371
372 stv6110x->i2c = i2c;
373 stv6110x->config = config;
374 stv6110x->devctl = &stv6110x_ctl;
375 memcpy(stv6110x->regs, default_regs, 8);
376
377 /* setup divider */
378 switch (stv6110x->config->clk_div) {
379 default:
380 case 1:
381 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
382 break;
383 case 2:
384 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
385 break;
386 case 4:
387 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
388 break;
389 case 8:
390 case 0:
391 STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
392 break;
393 }
394
395 fe->tuner_priv = stv6110x;
396 fe->ops.tuner_ops = stv6110x_ops;
397
398 printk(KERN_INFO "%s: Attaching STV6110x\n", __func__);
399 return stv6110x->devctl;
400}
401EXPORT_SYMBOL(stv6110x_attach);
402
403MODULE_AUTHOR("Manu Abraham");
404MODULE_DESCRIPTION("STV6110x Silicon tuner");
405MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv6110x.h b/drivers/media/dvb/frontends/stv6110x.h
new file mode 100644
index 00000000000..47516753929
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110x.h
@@ -0,0 +1,73 @@
1/*
2 STV6110(A) Silicon tuner driver
3
4 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
5
6 Copyright (C) ST Microelectronics
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#ifndef __STV6110x_H
24#define __STV6110x_H
25
26struct stv6110x_config {
27 u8 addr;
28 u32 refclk;
29 u8 clk_div; /* divisor value for the output clock */
30};
31
32enum tuner_mode {
33 TUNER_SLEEP = 1,
34 TUNER_WAKE,
35};
36
37enum tuner_status {
38 TUNER_PHASELOCKED = 1,
39};
40
41struct stv6110x_devctl {
42 int (*tuner_init) (struct dvb_frontend *fe);
43 int (*tuner_sleep) (struct dvb_frontend *fe);
44 int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
45 int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
46 int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
47 int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth);
48 int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth);
49 int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain);
50 int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain);
51 int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk);
52 int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
53};
54
55
56#if defined(CONFIG_DVB_STV6110x) || (defined(CONFIG_DVB_STV6110x_MODULE) && defined(MODULE))
57
58extern struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
59 const struct stv6110x_config *config,
60 struct i2c_adapter *i2c);
61
62#else
63static inline struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
64 const struct stv6110x_config *config,
65 struct i2c_adapter *i2c)
66{
67 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
68 return NULL;
69}
70
71#endif /* CONFIG_DVB_STV6110x */
72
73#endif /* __STV6110x_H */
diff --git a/drivers/media/dvb/frontends/stv6110x_priv.h b/drivers/media/dvb/frontends/stv6110x_priv.h
new file mode 100644
index 00000000000..0ec936a660a
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110x_priv.h
@@ -0,0 +1,76 @@
1/*
2 STV6110(A) Silicon tuner driver
3
4 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
5
6 Copyright (C) ST Microelectronics
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#ifndef __STV6110x_PRIV_H
24#define __STV6110x_PRIV_H
25
26#define FE_ERROR 0
27#define FE_NOTICE 1
28#define FE_INFO 2
29#define FE_DEBUG 3
30#define FE_DEBUGREG 4
31
32#define dprintk(__y, __z, format, arg...) do { \
33 if (__z) { \
34 if ((verbose > FE_ERROR) && (verbose > __y)) \
35 printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
36 else if ((verbose > FE_NOTICE) && (verbose > __y)) \
37 printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
38 else if ((verbose > FE_INFO) && (verbose > __y)) \
39 printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
40 else if ((verbose > FE_DEBUG) && (verbose > __y)) \
41 printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
42 } else { \
43 if (verbose > __y) \
44 printk(format, ##arg); \
45 } \
46} while (0)
47
48
49#define STV6110x_SETFIELD(mask, bitf, val) \
50 (mask = (mask & (~(((1 << STV6110x_WIDTH_##bitf) - 1) << \
51 STV6110x_OFFST_##bitf))) | \
52 (val << STV6110x_OFFST_##bitf))
53
54#define STV6110x_GETFIELD(bitf, val) \
55 ((val >> STV6110x_OFFST_##bitf) & \
56 ((1 << STV6110x_WIDTH_##bitf) - 1))
57
58#define MAKEWORD16(a, b) (((a) << 8) | (b))
59
60#define LSB(x) ((x & 0xff))
61#define MSB(y) ((y >> 8) & 0xff)
62
63#define TRIALS 10
64#define R_DIV(__div) (1 << (__div + 1))
65#define REFCLOCK_kHz (stv6110x->config->refclk / 1000)
66#define REFCLOCK_MHz (stv6110x->config->refclk / 1000000)
67
68struct stv6110x_state {
69 struct i2c_adapter *i2c;
70 const struct stv6110x_config *config;
71 u8 regs[8];
72
73 struct stv6110x_devctl *devctl;
74};
75
76#endif /* __STV6110x_PRIV_H */
diff --git a/drivers/media/dvb/frontends/stv6110x_reg.h b/drivers/media/dvb/frontends/stv6110x_reg.h
new file mode 100644
index 00000000000..93e5c70e5fd
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110x_reg.h
@@ -0,0 +1,82 @@
1/*
2 STV6110(A) Silicon tuner driver
3
4 Copyright (C) Manu Abraham <abraham.manu@gmail.com>
5
6 Copyright (C) ST Microelectronics
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#ifndef __STV6110x_REG_H
24#define __STV6110x_REG_H
25
26#define STV6110x_CTRL1 0x00
27#define STV6110x_OFFST_CTRL1_K 3
28#define STV6110x_WIDTH_CTRL1_K 5
29#define STV6110x_OFFST_CTRL1_LPT 2
30#define STV6110x_WIDTH_CTRL1_LPT 1
31#define STV6110x_OFFST_CTRL1_RX 1
32#define STV6110x_WIDTH_CTRL1_RX 1
33#define STV6110x_OFFST_CTRL1_SYN 0
34#define STV6110x_WIDTH_CTRL1_SYN 1
35
36#define STV6110x_CTRL2 0x01
37#define STV6110x_OFFST_CTRL2_CO_DIV 6
38#define STV6110x_WIDTH_CTRL2_CO_DIV 2
39#define STV6110x_OFFST_CTRL2_RSVD 5
40#define STV6110x_WIDTH_CTRL2_RSVD 1
41#define STV6110x_OFFST_CTRL2_REFOUT_SEL 4
42#define STV6110x_WIDTH_CTRL2_REFOUT_SEL 1
43#define STV6110x_OFFST_CTRL2_BBGAIN 0
44#define STV6110x_WIDTH_CTRL2_BBGAIN 4
45
46#define STV6110x_TNG0 0x02
47#define STV6110x_OFFST_TNG0_N_DIV_7_0 0
48#define STV6110x_WIDTH_TNG0_N_DIV_7_0 8
49
50#define STV6110x_TNG1 0x03
51#define STV6110x_OFFST_TNG1_R_DIV 6
52#define STV6110x_WIDTH_TNG1_R_DIV 2
53#define STV6110x_OFFST_TNG1_PRESC32_ON 5
54#define STV6110x_WIDTH_TNG1_PRESC32_ON 1
55#define STV6110x_OFFST_TNG1_DIV4SEL 4
56#define STV6110x_WIDTH_TNG1_DIV4SEL 1
57#define STV6110x_OFFST_TNG1_N_DIV_11_8 0
58#define STV6110x_WIDTH_TNG1_N_DIV_11_8 4
59
60
61#define STV6110x_CTRL3 0x04
62#define STV6110x_OFFST_CTRL3_DCLOOP_OFF 7
63#define STV6110x_WIDTH_CTRL3_DCLOOP_OFF 1
64#define STV6110x_OFFST_CTRL3_RCCLK_OFF 6
65#define STV6110x_WIDTH_CTRL3_RCCLK_OFF 1
66#define STV6110x_OFFST_CTRL3_ICP 5
67#define STV6110x_WIDTH_CTRL3_ICP 1
68#define STV6110x_OFFST_CTRL3_CF 0
69#define STV6110x_WIDTH_CTRL3_CF 5
70
71#define STV6110x_STAT1 0x05
72#define STV6110x_OFFST_STAT1_CALVCO_STRT 2
73#define STV6110x_WIDTH_STAT1_CALVCO_STRT 1
74#define STV6110x_OFFST_STAT1_CALRC_STRT 1
75#define STV6110x_WIDTH_STAT1_CALRC_STRT 1
76#define STV6110x_OFFST_STAT1_LOCK 0
77#define STV6110x_WIDTH_STAT1_LOCK 1
78
79#define STV6110x_STAT2 0x06
80#define STV6110x_STAT3 0x07
81
82#endif /* __STV6110x_REG_H */
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
new file mode 100644
index 00000000000..6ca533ea0f0
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -0,0 +1,489 @@
1/*
2 TDA10021 - Single Chip Cable Channel Receiver driver module
3 used on the Siemens DVB-C cards
4
5 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
6 Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
7 Support for TDA10021
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., 675 Mass Ave, Cambridge, MA 02139, USA.
22*/
23
24#include <linux/delay.h>
25#include <linux/errno.h>
26#include <linux/init.h>
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/string.h>
30#include <linux/slab.h>
31
32#include "dvb_frontend.h"
33#include "tda1002x.h"
34
35
36struct tda10021_state {
37 struct i2c_adapter* i2c;
38 /* configuration settings */
39 const struct tda1002x_config* config;
40 struct dvb_frontend frontend;
41
42 u8 pwm;
43 u8 reg0;
44};
45
46
47#if 0
48#define dprintk(x...) printk(x)
49#else
50#define dprintk(x...)
51#endif
52
53static int verbose;
54
55#define XIN 57840000UL
56
57#define FIN (XIN >> 4)
58
59static int tda10021_inittab_size = 0x40;
60static u8 tda10021_inittab[0x40]=
61{
62 0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a,
63 0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40,
64 0xb8, 0x3f, 0xa1, 0x00, 0xcd, 0x01, 0x00, 0xff,
65 0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00,
66 0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00,
67 0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58,
68 0x00, 0x00, 0x80, 0x00, 0x80, 0xff, 0x00, 0x00,
69 0x04, 0x2d, 0x2f, 0xff, 0x00, 0x00, 0x00, 0x00,
70};
71
72static int _tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
73{
74 u8 buf[] = { reg, data };
75 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
76 int ret;
77
78 ret = i2c_transfer (state->i2c, &msg, 1);
79 if (ret != 1)
80 printk("DVB: TDA10021(%d): %s, writereg error "
81 "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
82 state->frontend.dvb->num, __func__, reg, data, ret);
83
84 msleep(10);
85 return (ret != 1) ? -EREMOTEIO : 0;
86}
87
88static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
89{
90 u8 b0 [] = { reg };
91 u8 b1 [] = { 0 };
92 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
93 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
94 int ret;
95
96 ret = i2c_transfer (state->i2c, msg, 2);
97 // Don't print an error message if the id is read.
98 if (ret != 2 && reg != 0x1a)
99 printk("DVB: TDA10021: %s: readreg error (ret == %i)\n",
100 __func__, ret);
101 return b1[0];
102}
103
104//get access to tuner
105static int lock_tuner(struct tda10021_state* state)
106{
107 u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] | 0x80 };
108 struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
109
110 if(i2c_transfer(state->i2c, &msg, 1) != 1)
111 {
112 printk("tda10021: lock tuner fails\n");
113 return -EREMOTEIO;
114 }
115 return 0;
116}
117
118//release access from tuner
119static int unlock_tuner(struct tda10021_state* state)
120{
121 u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] & 0x7f };
122 struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
123
124 if(i2c_transfer(state->i2c, &msg_post, 1) != 1)
125 {
126 printk("tda10021: unlock tuner fails\n");
127 return -EREMOTEIO;
128 }
129 return 0;
130}
131
132static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0,
133 fe_spectral_inversion_t inversion)
134{
135 reg0 |= state->reg0 & 0x63;
136
137 if ((INVERSION_ON == inversion) ^ (state->config->invert == 0))
138 reg0 &= ~0x20;
139 else
140 reg0 |= 0x20;
141
142 _tda10021_writereg (state, 0x00, reg0 & 0xfe);
143 _tda10021_writereg (state, 0x00, reg0 | 0x01);
144
145 state->reg0 = reg0;
146 return 0;
147}
148
149static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate)
150{
151 s32 BDR;
152 s32 BDRI;
153 s16 SFIL=0;
154 u16 NDEC = 0;
155 u32 tmp, ratio;
156
157 if (symbolrate > XIN/2)
158 symbolrate = XIN/2;
159 if (symbolrate < 500000)
160 symbolrate = 500000;
161
162 if (symbolrate < XIN/16) NDEC = 1;
163 if (symbolrate < XIN/32) NDEC = 2;
164 if (symbolrate < XIN/64) NDEC = 3;
165
166 if (symbolrate < (u32)(XIN/12.3)) SFIL = 1;
167 if (symbolrate < (u32)(XIN/16)) SFIL = 0;
168 if (symbolrate < (u32)(XIN/24.6)) SFIL = 1;
169 if (symbolrate < (u32)(XIN/32)) SFIL = 0;
170 if (symbolrate < (u32)(XIN/49.2)) SFIL = 1;
171 if (symbolrate < (u32)(XIN/64)) SFIL = 0;
172 if (symbolrate < (u32)(XIN/98.4)) SFIL = 1;
173
174 symbolrate <<= NDEC;
175 ratio = (symbolrate << 4) / FIN;
176 tmp = ((symbolrate << 4) % FIN) << 8;
177 ratio = (ratio << 8) + tmp / FIN;
178 tmp = (tmp % FIN) << 8;
179 ratio = (ratio << 8) + DIV_ROUND_CLOSEST(tmp, FIN);
180
181 BDR = ratio;
182 BDRI = (((XIN << 5) / symbolrate) + 1) / 2;
183
184 if (BDRI > 0xFF)
185 BDRI = 0xFF;
186
187 SFIL = (SFIL << 4) | tda10021_inittab[0x0E];
188
189 NDEC = (NDEC << 6) | tda10021_inittab[0x03];
190
191 _tda10021_writereg (state, 0x03, NDEC);
192 _tda10021_writereg (state, 0x0a, BDR&0xff);
193 _tda10021_writereg (state, 0x0b, (BDR>> 8)&0xff);
194 _tda10021_writereg (state, 0x0c, (BDR>>16)&0x3f);
195
196 _tda10021_writereg (state, 0x0d, BDRI);
197 _tda10021_writereg (state, 0x0e, SFIL);
198
199 return 0;
200}
201
202static int tda10021_init (struct dvb_frontend *fe)
203{
204 struct tda10021_state* state = fe->demodulator_priv;
205 int i;
206
207 dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num);
208
209 //_tda10021_writereg (fe, 0, 0);
210
211 for (i=0; i<tda10021_inittab_size; i++)
212 _tda10021_writereg (state, i, tda10021_inittab[i]);
213
214 _tda10021_writereg (state, 0x34, state->pwm);
215
216 //Comment by markus
217 //0x2A[3-0] == PDIV -> P multiplaying factor (P=PDIV+1)(default 0)
218 //0x2A[4] == BYPPLL -> Power down mode (default 1)
219 //0x2A[5] == LCK -> PLL Lock Flag
220 //0x2A[6] == POLAXIN -> Polarity of the input reference clock (default 0)
221
222 //Activate PLL
223 _tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef);
224 return 0;
225}
226
227static int tda10021_set_parameters (struct dvb_frontend *fe,
228 struct dvb_frontend_parameters *p)
229{
230 struct tda10021_state* state = fe->demodulator_priv;
231
232 //table for QAM4-QAM256 ready QAM4 QAM16 QAM32 QAM64 QAM128 QAM256
233 //CONF
234 static const u8 reg0x00 [] = { 0x14, 0x00, 0x04, 0x08, 0x0c, 0x10 };
235 //AGCREF value
236 static const u8 reg0x01 [] = { 0x78, 0x8c, 0x8c, 0x6a, 0x78, 0x5c };
237 //LTHR value
238 static const u8 reg0x05 [] = { 0x78, 0x87, 0x64, 0x46, 0x36, 0x26 };
239 //MSETH
240 static const u8 reg0x08 [] = { 0x8c, 0xa2, 0x74, 0x43, 0x34, 0x23 };
241 //AREF
242 static const u8 reg0x09 [] = { 0x96, 0x91, 0x96, 0x6a, 0x7e, 0x6b };
243
244 int qam = p->u.qam.modulation;
245
246 if (qam < 0 || qam > 5)
247 return -EINVAL;
248
249 if (p->inversion != INVERSION_ON && p->inversion != INVERSION_OFF)
250 return -EINVAL;
251
252 //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate);
253
254 if (fe->ops.tuner_ops.set_params) {
255 fe->ops.tuner_ops.set_params(fe, p);
256 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
257 }
258
259 tda10021_set_symbolrate (state, p->u.qam.symbol_rate);
260 _tda10021_writereg (state, 0x34, state->pwm);
261
262 _tda10021_writereg (state, 0x01, reg0x01[qam]);
263 _tda10021_writereg (state, 0x05, reg0x05[qam]);
264 _tda10021_writereg (state, 0x08, reg0x08[qam]);
265 _tda10021_writereg (state, 0x09, reg0x09[qam]);
266
267 tda10021_setup_reg0 (state, reg0x00[qam], p->inversion);
268
269 return 0;
270}
271
272static int tda10021_read_status(struct dvb_frontend* fe, fe_status_t* status)
273{
274 struct tda10021_state* state = fe->demodulator_priv;
275 int sync;
276
277 *status = 0;
278 //0x11[0] == EQALGO -> Equalizer algorithms state
279 //0x11[1] == CARLOCK -> Carrier locked
280 //0x11[2] == FSYNC -> Frame synchronisation
281 //0x11[3] == FEL -> Front End locked
282 //0x11[6] == NODVB -> DVB Mode Information
283 sync = tda10021_readreg (state, 0x11);
284
285 if (sync & 2)
286 *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER;
287
288 if (sync & 4)
289 *status |= FE_HAS_SYNC|FE_HAS_VITERBI;
290
291 if (sync & 8)
292 *status |= FE_HAS_LOCK;
293
294 return 0;
295}
296
297static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber)
298{
299 struct tda10021_state* state = fe->demodulator_priv;
300
301 u32 _ber = tda10021_readreg(state, 0x14) |
302 (tda10021_readreg(state, 0x15) << 8) |
303 ((tda10021_readreg(state, 0x16) & 0x0f) << 16);
304 _tda10021_writereg(state, 0x10, (tda10021_readreg(state, 0x10) & ~0xc0)
305 | (tda10021_inittab[0x10] & 0xc0));
306 *ber = 10 * _ber;
307
308 return 0;
309}
310
311static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength)
312{
313 struct tda10021_state* state = fe->demodulator_priv;
314
315 u8 config = tda10021_readreg(state, 0x02);
316 u8 gain = tda10021_readreg(state, 0x17);
317 if (config & 0x02)
318 /* the agc value is inverted */
319 gain = ~gain;
320 *strength = (gain << 8) | gain;
321
322 return 0;
323}
324
325static int tda10021_read_snr(struct dvb_frontend* fe, u16* snr)
326{
327 struct tda10021_state* state = fe->demodulator_priv;
328
329 u8 quality = ~tda10021_readreg(state, 0x18);
330 *snr = (quality << 8) | quality;
331
332 return 0;
333}
334
335static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
336{
337 struct tda10021_state* state = fe->demodulator_priv;
338
339 *ucblocks = tda10021_readreg (state, 0x13) & 0x7f;
340 if (*ucblocks == 0x7f)
341 *ucblocks = 0xffffffff;
342
343 /* reset uncorrected block counter */
344 _tda10021_writereg (state, 0x10, tda10021_inittab[0x10] & 0xdf);
345 _tda10021_writereg (state, 0x10, tda10021_inittab[0x10]);
346
347 return 0;
348}
349
350static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
351{
352 struct tda10021_state* state = fe->demodulator_priv;
353 int sync;
354 s8 afc = 0;
355
356 sync = tda10021_readreg(state, 0x11);
357 afc = tda10021_readreg(state, 0x19);
358 if (verbose) {
359 /* AFC only valid when carrier has been recovered */
360 printk(sync & 2 ? "DVB: TDA10021(%d): AFC (%d) %dHz\n" :
361 "DVB: TDA10021(%d): [AFC (%d) %dHz]\n",
362 state->frontend.dvb->num, afc,
363 -((s32)p->u.qam.symbol_rate * afc) >> 10);
364 }
365
366 p->inversion = ((state->reg0 & 0x20) == 0x20) ^ (state->config->invert != 0) ? INVERSION_ON : INVERSION_OFF;
367 p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
368
369 p->u.qam.fec_inner = FEC_NONE;
370 p->frequency = ((p->frequency + 31250) / 62500) * 62500;
371
372 if (sync & 2)
373 p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10;
374
375 return 0;
376}
377
378static int tda10021_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
379{
380 struct tda10021_state* state = fe->demodulator_priv;
381
382 if (enable) {
383 lock_tuner(state);
384 } else {
385 unlock_tuner(state);
386 }
387 return 0;
388}
389
390static int tda10021_sleep(struct dvb_frontend* fe)
391{
392 struct tda10021_state* state = fe->demodulator_priv;
393
394 _tda10021_writereg (state, 0x1b, 0x02); /* pdown ADC */
395 _tda10021_writereg (state, 0x00, 0x80); /* standby */
396
397 return 0;
398}
399
400static void tda10021_release(struct dvb_frontend* fe)
401{
402 struct tda10021_state* state = fe->demodulator_priv;
403 kfree(state);
404}
405
406static struct dvb_frontend_ops tda10021_ops;
407
408struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
409 struct i2c_adapter* i2c,
410 u8 pwm)
411{
412 struct tda10021_state* state = NULL;
413 u8 id;
414
415 /* allocate memory for the internal state */
416 state = kzalloc(sizeof(struct tda10021_state), GFP_KERNEL);
417 if (state == NULL) goto error;
418
419 /* setup the state */
420 state->config = config;
421 state->i2c = i2c;
422 state->pwm = pwm;
423 state->reg0 = tda10021_inittab[0];
424
425 /* check if the demod is there */
426 id = tda10021_readreg(state, 0x1a);
427 if ((id & 0xf0) != 0x70) goto error;
428
429 /* Don't claim TDA10023 */
430 if (id == 0x7d)
431 goto error;
432
433 printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n",
434 state->config->demod_address, id);
435
436 /* create dvb_frontend */
437 memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops));
438 state->frontend.demodulator_priv = state;
439 return &state->frontend;
440
441error:
442 kfree(state);
443 return NULL;
444}
445
446static struct dvb_frontend_ops tda10021_ops = {
447
448 .info = {
449 .name = "Philips TDA10021 DVB-C",
450 .type = FE_QAM,
451 .frequency_stepsize = 62500,
452 .frequency_min = 47000000,
453 .frequency_max = 862000000,
454 .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */
455 .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */
456 #if 0
457 .frequency_tolerance = ???,
458 .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */
459 #endif
460 .caps = 0x400 | //FE_CAN_QAM_4
461 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
462 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
463 FE_CAN_FEC_AUTO
464 },
465
466 .release = tda10021_release,
467
468 .init = tda10021_init,
469 .sleep = tda10021_sleep,
470 .i2c_gate_ctrl = tda10021_i2c_gate_ctrl,
471
472 .set_frontend = tda10021_set_parameters,
473 .get_frontend = tda10021_get_frontend,
474
475 .read_status = tda10021_read_status,
476 .read_ber = tda10021_read_ber,
477 .read_signal_strength = tda10021_read_signal_strength,
478 .read_snr = tda10021_read_snr,
479 .read_ucblocks = tda10021_read_ucblocks,
480};
481
482module_param(verbose, int, 0644);
483MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting");
484
485MODULE_DESCRIPTION("Philips TDA10021 DVB-C demodulator driver");
486MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Markus Schulz");
487MODULE_LICENSE("GPL");
488
489EXPORT_SYMBOL(tda10021_attach);
diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c
new file mode 100644
index 00000000000..a3c34eecdee
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10023.c
@@ -0,0 +1,573 @@
1/*
2 TDA10023 - DVB-C decoder
3 (as used in Philips CU1216-3 NIM and the Reelbox DVB-C tuner card)
4
5 Copyright (C) 2005 Georg Acher, BayCom GmbH (acher at baycom dot de)
6 Copyright (c) 2006 Hartmut Birr (e9hack at gmail dot com)
7
8 Remotely based on tda10021.c
9 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
10 Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
11 Support for TDA10021
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
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 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26*/
27
28#include <linux/delay.h>
29#include <linux/errno.h>
30#include <linux/init.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/string.h>
34#include <linux/slab.h>
35
36#include <asm/div64.h>
37
38#include "dvb_frontend.h"
39#include "tda1002x.h"
40
41#define REG0_INIT_VAL 0x23
42
43struct tda10023_state {
44 struct i2c_adapter* i2c;
45 /* configuration settings */
46 const struct tda10023_config *config;
47 struct dvb_frontend frontend;
48
49 u8 pwm;
50 u8 reg0;
51
52 /* clock settings */
53 u32 xtal;
54 u8 pll_m;
55 u8 pll_p;
56 u8 pll_n;
57 u32 sysclk;
58};
59
60#define dprintk(x...)
61
62static int verbose;
63
64static u8 tda10023_readreg (struct tda10023_state* state, u8 reg)
65{
66 u8 b0 [] = { reg };
67 u8 b1 [] = { 0 };
68 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
69 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
70 int ret;
71
72 ret = i2c_transfer (state->i2c, msg, 2);
73 if (ret != 2) {
74 int num = state->frontend.dvb ? state->frontend.dvb->num : -1;
75 printk(KERN_ERR "DVB: TDA10023(%d): %s: readreg error "
76 "(reg == 0x%02x, ret == %i)\n",
77 num, __func__, reg, ret);
78 }
79 return b1[0];
80}
81
82static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data)
83{
84 u8 buf[] = { reg, data };
85 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
86 int ret;
87
88 ret = i2c_transfer (state->i2c, &msg, 1);
89 if (ret != 1) {
90 int num = state->frontend.dvb ? state->frontend.dvb->num : -1;
91 printk(KERN_ERR "DVB: TDA10023(%d): %s, writereg error "
92 "(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
93 num, __func__, reg, data, ret);
94 }
95 return (ret != 1) ? -EREMOTEIO : 0;
96}
97
98
99static int tda10023_writebit (struct tda10023_state* state, u8 reg, u8 mask,u8 data)
100{
101 if (mask==0xff)
102 return tda10023_writereg(state, reg, data);
103 else {
104 u8 val;
105 val=tda10023_readreg(state,reg);
106 val&=~mask;
107 val|=(data&mask);
108 return tda10023_writereg(state, reg, val);
109 }
110}
111
112static void tda10023_writetab(struct tda10023_state* state, u8* tab)
113{
114 u8 r,m,v;
115 while (1) {
116 r=*tab++;
117 m=*tab++;
118 v=*tab++;
119 if (r==0xff) {
120 if (m==0xff)
121 break;
122 else
123 msleep(m);
124 }
125 else
126 tda10023_writebit(state,r,m,v);
127 }
128}
129
130//get access to tuner
131static int lock_tuner(struct tda10023_state* state)
132{
133 u8 buf[2] = { 0x0f, 0xc0 };
134 struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
135
136 if(i2c_transfer(state->i2c, &msg, 1) != 1)
137 {
138 printk("tda10023: lock tuner fails\n");
139 return -EREMOTEIO;
140 }
141 return 0;
142}
143
144//release access from tuner
145static int unlock_tuner(struct tda10023_state* state)
146{
147 u8 buf[2] = { 0x0f, 0x40 };
148 struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2};
149
150 if(i2c_transfer(state->i2c, &msg_post, 1) != 1)
151 {
152 printk("tda10023: unlock tuner fails\n");
153 return -EREMOTEIO;
154 }
155 return 0;
156}
157
158static int tda10023_setup_reg0 (struct tda10023_state* state, u8 reg0)
159{
160 reg0 |= state->reg0 & 0x63;
161
162 tda10023_writereg (state, 0x00, reg0 & 0xfe);
163 tda10023_writereg (state, 0x00, reg0 | 0x01);
164
165 state->reg0 = reg0;
166 return 0;
167}
168
169static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
170{
171 s32 BDR;
172 s32 BDRI;
173 s16 SFIL=0;
174 u16 NDEC = 0;
175
176 /* avoid floating point operations multiplying syscloc and divider
177 by 10 */
178 u32 sysclk_x_10 = state->sysclk * 10;
179
180 if (sr < (u32)(sysclk_x_10/984)) {
181 NDEC=3;
182 SFIL=1;
183 } else if (sr < (u32)(sysclk_x_10/640)) {
184 NDEC=3;
185 SFIL=0;
186 } else if (sr < (u32)(sysclk_x_10/492)) {
187 NDEC=2;
188 SFIL=1;
189 } else if (sr < (u32)(sysclk_x_10/320)) {
190 NDEC=2;
191 SFIL=0;
192 } else if (sr < (u32)(sysclk_x_10/246)) {
193 NDEC=1;
194 SFIL=1;
195 } else if (sr < (u32)(sysclk_x_10/160)) {
196 NDEC=1;
197 SFIL=0;
198 } else if (sr < (u32)(sysclk_x_10/123)) {
199 NDEC=0;
200 SFIL=1;
201 }
202
203 BDRI = (state->sysclk)*16;
204 BDRI>>=NDEC;
205 BDRI +=sr/2;
206 BDRI /=sr;
207
208 if (BDRI>255)
209 BDRI=255;
210
211 {
212 u64 BDRX;
213
214 BDRX=1<<(24+NDEC);
215 BDRX*=sr;
216 do_div(BDRX, state->sysclk); /* BDRX/=SYSCLK; */
217
218 BDR=(s32)BDRX;
219 }
220 dprintk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",
221 sr, BDR, BDRI, NDEC);
222 tda10023_writebit (state, 0x03, 0xc0, NDEC<<6);
223 tda10023_writereg (state, 0x0a, BDR&255);
224 tda10023_writereg (state, 0x0b, (BDR>>8)&255);
225 tda10023_writereg (state, 0x0c, (BDR>>16)&31);
226 tda10023_writereg (state, 0x0d, BDRI);
227 tda10023_writereg (state, 0x3d, (SFIL<<7));
228 return 0;
229}
230
231static int tda10023_init (struct dvb_frontend *fe)
232{
233 struct tda10023_state* state = fe->demodulator_priv;
234 u8 tda10023_inittab[] = {
235/* reg mask val */
236/* 000 */ 0x2a, 0xff, 0x02, /* PLL3, Bypass, Power Down */
237/* 003 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
238/* 006 */ 0x2a, 0xff, 0x03, /* PLL3, Bypass, Power Down */
239/* 009 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
240 /* PLL1 */
241/* 012 */ 0x28, 0xff, (state->pll_m-1),
242 /* PLL2 */
243/* 015 */ 0x29, 0xff, ((state->pll_p-1)<<6)|(state->pll_n-1),
244 /* GPR FSAMPLING=1 */
245/* 018 */ 0x00, 0xff, REG0_INIT_VAL,
246/* 021 */ 0x2a, 0xff, 0x08, /* PLL3 PSACLK=1 */
247/* 024 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
248/* 027 */ 0x1f, 0xff, 0x00, /* RESET */
249/* 030 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
250/* 033 */ 0xe6, 0x0c, 0x04, /* RSCFG_IND */
251/* 036 */ 0x10, 0xc0, 0x80, /* DECDVBCFG1 PBER=1 */
252
253/* 039 */ 0x0e, 0xff, 0x82, /* GAIN1 */
254/* 042 */ 0x03, 0x08, 0x08, /* CLKCONF DYN=1 */
255/* 045 */ 0x2e, 0xbf, 0x30, /* AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1
256 PPWMTUN=0 PPWMIF=0 */
257/* 048 */ 0x01, 0xff, 0x30, /* AGCREF */
258/* 051 */ 0x1e, 0x84, 0x84, /* CONTROL SACLK_ON=1 */
259/* 054 */ 0x1b, 0xff, 0xc8, /* ADC TWOS=1 */
260/* 057 */ 0x3b, 0xff, 0xff, /* IFMAX */
261/* 060 */ 0x3c, 0xff, 0x00, /* IFMIN */
262/* 063 */ 0x34, 0xff, 0x00, /* PWMREF */
263/* 066 */ 0x35, 0xff, 0xff, /* TUNMAX */
264/* 069 */ 0x36, 0xff, 0x00, /* TUNMIN */
265/* 072 */ 0x06, 0xff, 0x7f, /* EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 */
266/* 075 */ 0x1c, 0x30, 0x30, /* EQCONF2 STEPALGO=SGNALGO=1 */
267/* 078 */ 0x37, 0xff, 0xf6, /* DELTAF_LSB */
268/* 081 */ 0x38, 0xff, 0xff, /* DELTAF_MSB */
269/* 084 */ 0x02, 0xff, 0x93, /* AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3 */
270/* 087 */ 0x2d, 0xff, 0xf6, /* SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2 */
271/* 090 */ 0x04, 0x10, 0x00, /* SWRAMP=1 */
272/* 093 */ 0x12, 0xff, TDA10023_OUTPUT_MODE_PARALLEL_B, /*
273 INTP1 POCLKP=1 FEL=1 MFS=0 */
274/* 096 */ 0x2b, 0x01, 0xa1, /* INTS1 */
275/* 099 */ 0x20, 0xff, 0x04, /* INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=? */
276/* 102 */ 0x2c, 0xff, 0x0d, /* INTP/S TRIP=0 TRIS=0 */
277/* 105 */ 0xc4, 0xff, 0x00,
278/* 108 */ 0xc3, 0x30, 0x00,
279/* 111 */ 0xb5, 0xff, 0x19, /* ERAGC_THD */
280/* 114 */ 0x00, 0x03, 0x01, /* GPR, CLBS soft reset */
281/* 117 */ 0x00, 0x03, 0x03, /* GPR, CLBS soft reset */
282/* 120 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
283/* 123 */ 0xff, 0xff, 0xff
284};
285 dprintk("DVB: TDA10023(%d): init chip\n", fe->dvb->num);
286
287 /* override default values if set in config */
288 if (state->config->deltaf) {
289 tda10023_inittab[80] = (state->config->deltaf & 0xff);
290 tda10023_inittab[83] = (state->config->deltaf >> 8);
291 }
292
293 if (state->config->output_mode)
294 tda10023_inittab[95] = state->config->output_mode;
295
296 tda10023_writetab(state, tda10023_inittab);
297
298 return 0;
299}
300
301static int tda10023_set_parameters (struct dvb_frontend *fe,
302 struct dvb_frontend_parameters *p)
303{
304 struct tda10023_state* state = fe->demodulator_priv;
305
306 static int qamvals[6][6] = {
307 // QAM LOCKTHR MSETH AREF AGCREFNYQ ERAGCNYQ_THD
308 { (5<<2), 0x78, 0x8c, 0x96, 0x78, 0x4c }, // 4 QAM
309 { (0<<2), 0x87, 0xa2, 0x91, 0x8c, 0x57 }, // 16 QAM
310 { (1<<2), 0x64, 0x74, 0x96, 0x8c, 0x57 }, // 32 QAM
311 { (2<<2), 0x46, 0x43, 0x6a, 0x6a, 0x44 }, // 64 QAM
312 { (3<<2), 0x36, 0x34, 0x7e, 0x78, 0x4c }, // 128 QAM
313 { (4<<2), 0x26, 0x23, 0x6c, 0x5c, 0x3c }, // 256 QAM
314 };
315
316 int qam = p->u.qam.modulation;
317
318 if (qam < 0 || qam > 5)
319 return -EINVAL;
320
321 if (fe->ops.tuner_ops.set_params) {
322 fe->ops.tuner_ops.set_params(fe, p);
323 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
324 }
325
326 tda10023_set_symbolrate (state, p->u.qam.symbol_rate);
327 tda10023_writereg (state, 0x05, qamvals[qam][1]);
328 tda10023_writereg (state, 0x08, qamvals[qam][2]);
329 tda10023_writereg (state, 0x09, qamvals[qam][3]);
330 tda10023_writereg (state, 0xb4, qamvals[qam][4]);
331 tda10023_writereg (state, 0xb6, qamvals[qam][5]);
332
333// tda10023_writereg (state, 0x04, (p->inversion?0x12:0x32));
334// tda10023_writebit (state, 0x04, 0x60, (p->inversion?0:0x20));
335 tda10023_writebit (state, 0x04, 0x40, 0x40);
336 tda10023_setup_reg0 (state, qamvals[qam][0]);
337
338 return 0;
339}
340
341static int tda10023_read_status(struct dvb_frontend* fe, fe_status_t* status)
342{
343 struct tda10023_state* state = fe->demodulator_priv;
344 int sync;
345
346 *status = 0;
347
348 //0x11[1] == CARLOCK -> Carrier locked
349 //0x11[2] == FSYNC -> Frame synchronisation
350 //0x11[3] == FEL -> Front End locked
351 //0x11[6] == NODVB -> DVB Mode Information
352 sync = tda10023_readreg (state, 0x11);
353
354 if (sync & 2)
355 *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER;
356
357 if (sync & 4)
358 *status |= FE_HAS_SYNC|FE_HAS_VITERBI;
359
360 if (sync & 8)
361 *status |= FE_HAS_LOCK;
362
363 return 0;
364}
365
366static int tda10023_read_ber(struct dvb_frontend* fe, u32* ber)
367{
368 struct tda10023_state* state = fe->demodulator_priv;
369 u8 a,b,c;
370 a=tda10023_readreg(state, 0x14);
371 b=tda10023_readreg(state, 0x15);
372 c=tda10023_readreg(state, 0x16)&0xf;
373 tda10023_writebit (state, 0x10, 0xc0, 0x00);
374
375 *ber = a | (b<<8)| (c<<16);
376 return 0;
377}
378
379static int tda10023_read_signal_strength(struct dvb_frontend* fe, u16* strength)
380{
381 struct tda10023_state* state = fe->demodulator_priv;
382 u8 ifgain=tda10023_readreg(state, 0x2f);
383
384 u16 gain = ((255-tda10023_readreg(state, 0x17))) + (255-ifgain)/16;
385 // Max raw value is about 0xb0 -> Normalize to >0xf0 after 0x90
386 if (gain>0x90)
387 gain=gain+2*(gain-0x90);
388 if (gain>255)
389 gain=255;
390
391 *strength = (gain<<8)|gain;
392 return 0;
393}
394
395static int tda10023_read_snr(struct dvb_frontend* fe, u16* snr)
396{
397 struct tda10023_state* state = fe->demodulator_priv;
398
399 u8 quality = ~tda10023_readreg(state, 0x18);
400 *snr = (quality << 8) | quality;
401 return 0;
402}
403
404static int tda10023_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
405{
406 struct tda10023_state* state = fe->demodulator_priv;
407 u8 a,b,c,d;
408 a= tda10023_readreg (state, 0x74);
409 b= tda10023_readreg (state, 0x75);
410 c= tda10023_readreg (state, 0x76);
411 d= tda10023_readreg (state, 0x77);
412 *ucblocks = a | (b<<8)|(c<<16)|(d<<24);
413
414 tda10023_writebit (state, 0x10, 0x20,0x00);
415 tda10023_writebit (state, 0x10, 0x20,0x20);
416 tda10023_writebit (state, 0x13, 0x01, 0x00);
417
418 return 0;
419}
420
421static int tda10023_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
422{
423 struct tda10023_state* state = fe->demodulator_priv;
424 int sync,inv;
425 s8 afc = 0;
426
427 sync = tda10023_readreg(state, 0x11);
428 afc = tda10023_readreg(state, 0x19);
429 inv = tda10023_readreg(state, 0x04);
430
431 if (verbose) {
432 /* AFC only valid when carrier has been recovered */
433 printk(sync & 2 ? "DVB: TDA10023(%d): AFC (%d) %dHz\n" :
434 "DVB: TDA10023(%d): [AFC (%d) %dHz]\n",
435 state->frontend.dvb->num, afc,
436 -((s32)p->u.qam.symbol_rate * afc) >> 10);
437 }
438
439 p->inversion = (inv&0x20?0:1);
440 p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
441
442 p->u.qam.fec_inner = FEC_NONE;
443 p->frequency = ((p->frequency + 31250) / 62500) * 62500;
444
445 if (sync & 2)
446 p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10;
447
448 return 0;
449}
450
451static int tda10023_sleep(struct dvb_frontend* fe)
452{
453 struct tda10023_state* state = fe->demodulator_priv;
454
455 tda10023_writereg (state, 0x1b, 0x02); /* pdown ADC */
456 tda10023_writereg (state, 0x00, 0x80); /* standby */
457
458 return 0;
459}
460
461static int tda10023_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
462{
463 struct tda10023_state* state = fe->demodulator_priv;
464
465 if (enable) {
466 lock_tuner(state);
467 } else {
468 unlock_tuner(state);
469 }
470 return 0;
471}
472
473static void tda10023_release(struct dvb_frontend* fe)
474{
475 struct tda10023_state* state = fe->demodulator_priv;
476 kfree(state);
477}
478
479static struct dvb_frontend_ops tda10023_ops;
480
481struct dvb_frontend *tda10023_attach(const struct tda10023_config *config,
482 struct i2c_adapter *i2c,
483 u8 pwm)
484{
485 struct tda10023_state* state = NULL;
486
487 /* allocate memory for the internal state */
488 state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL);
489 if (state == NULL) goto error;
490
491 /* setup the state */
492 state->config = config;
493 state->i2c = i2c;
494
495 /* wakeup if in standby */
496 tda10023_writereg (state, 0x00, 0x33);
497 /* check if the demod is there */
498 if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
499
500 /* create dvb_frontend */
501 memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
502 state->pwm = pwm;
503 state->reg0 = REG0_INIT_VAL;
504 if (state->config->xtal) {
505 state->xtal = state->config->xtal;
506 state->pll_m = state->config->pll_m;
507 state->pll_p = state->config->pll_p;
508 state->pll_n = state->config->pll_n;
509 } else {
510 /* set default values if not defined in config */
511 state->xtal = 28920000;
512 state->pll_m = 8;
513 state->pll_p = 4;
514 state->pll_n = 1;
515 }
516
517 /* calc sysclk */
518 state->sysclk = (state->xtal * state->pll_m / \
519 (state->pll_n * state->pll_p));
520
521 state->frontend.ops.info.symbol_rate_min = (state->sysclk/2)/64;
522 state->frontend.ops.info.symbol_rate_max = (state->sysclk/2)/4;
523
524 dprintk("DVB: TDA10023 %s: xtal:%d pll_m:%d pll_p:%d pll_n:%d\n",
525 __func__, state->xtal, state->pll_m, state->pll_p,
526 state->pll_n);
527
528 state->frontend.demodulator_priv = state;
529 return &state->frontend;
530
531error:
532 kfree(state);
533 return NULL;
534}
535
536static struct dvb_frontend_ops tda10023_ops = {
537
538 .info = {
539 .name = "Philips TDA10023 DVB-C",
540 .type = FE_QAM,
541 .frequency_stepsize = 62500,
542 .frequency_min = 47000000,
543 .frequency_max = 862000000,
544 .symbol_rate_min = 0, /* set in tda10023_attach */
545 .symbol_rate_max = 0, /* set in tda10023_attach */
546 .caps = 0x400 | //FE_CAN_QAM_4
547 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
548 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
549 FE_CAN_FEC_AUTO
550 },
551
552 .release = tda10023_release,
553
554 .init = tda10023_init,
555 .sleep = tda10023_sleep,
556 .i2c_gate_ctrl = tda10023_i2c_gate_ctrl,
557
558 .set_frontend = tda10023_set_parameters,
559 .get_frontend = tda10023_get_frontend,
560
561 .read_status = tda10023_read_status,
562 .read_ber = tda10023_read_ber,
563 .read_signal_strength = tda10023_read_signal_strength,
564 .read_snr = tda10023_read_snr,
565 .read_ucblocks = tda10023_read_ucblocks,
566};
567
568
569MODULE_DESCRIPTION("Philips TDA10023 DVB-C demodulator driver");
570MODULE_AUTHOR("Georg Acher, Hartmut Birr");
571MODULE_LICENSE("GPL");
572
573EXPORT_SYMBOL(tda10023_attach);
diff --git a/drivers/media/dvb/frontends/tda1002x.h b/drivers/media/dvb/frontends/tda1002x.h
new file mode 100644
index 00000000000..04d19418bf2
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda1002x.h
@@ -0,0 +1,87 @@
1/*
2 TDA10021/TDA10023 - Single Chip Cable Channel Receiver driver module
3 used on the the Siemens DVB-C cards
4
5 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
6 Copyright (C) 2004 Markus Schulz <msc@antzsystem.de>
7 Support for TDA10021
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., 675 Mass Ave, Cambridge, MA 02139, USA.
22*/
23
24#ifndef TDA1002x_H
25#define TDA1002x_H
26
27#include <linux/dvb/frontend.h>
28
29struct tda1002x_config {
30 /* the demodulator's i2c address */
31 u8 demod_address;
32 u8 invert;
33};
34
35enum tda10023_output_mode {
36 TDA10023_OUTPUT_MODE_PARALLEL_A = 0xe0,
37 TDA10023_OUTPUT_MODE_PARALLEL_B = 0xa1,
38 TDA10023_OUTPUT_MODE_PARALLEL_C = 0xa0,
39 TDA10023_OUTPUT_MODE_SERIAL, /* TODO: not implemented */
40};
41
42struct tda10023_config {
43 /* the demodulator's i2c address */
44 u8 demod_address;
45 u8 invert;
46
47 /* clock settings */
48 u32 xtal; /* defaults: 28920000 */
49 u8 pll_m; /* defaults: 8 */
50 u8 pll_p; /* defaults: 4 */
51 u8 pll_n; /* defaults: 1 */
52
53 /* MPEG2 TS output mode */
54 u8 output_mode;
55
56 /* input freq offset + baseband conversion type */
57 u16 deltaf;
58};
59
60#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE))
61extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
62 struct i2c_adapter* i2c, u8 pwm);
63#else
64static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
65 struct i2c_adapter* i2c, u8 pwm)
66{
67 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
68 return NULL;
69}
70#endif // CONFIG_DVB_TDA10021
71
72#if defined(CONFIG_DVB_TDA10023) || \
73 (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE))
74extern struct dvb_frontend *tda10023_attach(
75 const struct tda10023_config *config,
76 struct i2c_adapter *i2c, u8 pwm);
77#else
78static inline struct dvb_frontend *tda10023_attach(
79 const struct tda10023_config *config,
80 struct i2c_adapter *i2c, u8 pwm)
81{
82 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
83 return NULL;
84}
85#endif // CONFIG_DVB_TDA10023
86
87#endif // TDA1002x_H
diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c
new file mode 100644
index 00000000000..93f6a75c238
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10048.c
@@ -0,0 +1,1193 @@
1/*
2 NXP TDA10048HN DVB OFDM demodulator driver
3
4 Copyright (C) 2009 Steven Toth <stoth@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
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/slab.h>
27#include <linux/delay.h>
28#include <linux/math64.h>
29#include <asm/div64.h>
30#include "dvb_frontend.h"
31#include "dvb_math.h"
32#include "tda10048.h"
33
34#define TDA10048_DEFAULT_FIRMWARE "dvb-fe-tda10048-1.0.fw"
35#define TDA10048_DEFAULT_FIRMWARE_SIZE 24878
36
37/* Register name definitions */
38#define TDA10048_IDENTITY 0x00
39#define TDA10048_VERSION 0x01
40#define TDA10048_DSP_CODE_CPT 0x0C
41#define TDA10048_DSP_CODE_IN 0x0E
42#define TDA10048_IN_CONF1 0x10
43#define TDA10048_IN_CONF2 0x11
44#define TDA10048_IN_CONF3 0x12
45#define TDA10048_OUT_CONF1 0x14
46#define TDA10048_OUT_CONF2 0x15
47#define TDA10048_OUT_CONF3 0x16
48#define TDA10048_AUTO 0x18
49#define TDA10048_SYNC_STATUS 0x1A
50#define TDA10048_CONF_C4_1 0x1E
51#define TDA10048_CONF_C4_2 0x1F
52#define TDA10048_CODE_IN_RAM 0x20
53#define TDA10048_CHANNEL_INFO1_R 0x22
54#define TDA10048_CHANNEL_INFO2_R 0x23
55#define TDA10048_CHANNEL_INFO1 0x24
56#define TDA10048_CHANNEL_INFO2 0x25
57#define TDA10048_TIME_ERROR_R 0x26
58#define TDA10048_TIME_ERROR 0x27
59#define TDA10048_FREQ_ERROR_LSB_R 0x28
60#define TDA10048_FREQ_ERROR_MSB_R 0x29
61#define TDA10048_FREQ_ERROR_LSB 0x2A
62#define TDA10048_FREQ_ERROR_MSB 0x2B
63#define TDA10048_IT_SEL 0x30
64#define TDA10048_IT_STAT 0x32
65#define TDA10048_DSP_AD_LSB 0x3C
66#define TDA10048_DSP_AD_MSB 0x3D
67#define TDA10048_DSP_REG_LSB 0x3E
68#define TDA10048_DSP_REG_MSB 0x3F
69#define TDA10048_CONF_TRISTATE1 0x44
70#define TDA10048_CONF_TRISTATE2 0x45
71#define TDA10048_CONF_POLARITY 0x46
72#define TDA10048_GPIO_SP_DS0 0x48
73#define TDA10048_GPIO_SP_DS1 0x49
74#define TDA10048_GPIO_SP_DS2 0x4A
75#define TDA10048_GPIO_SP_DS3 0x4B
76#define TDA10048_GPIO_OUT_SEL 0x4C
77#define TDA10048_GPIO_SELECT 0x4D
78#define TDA10048_IC_MODE 0x4E
79#define TDA10048_CONF_XO 0x50
80#define TDA10048_CONF_PLL1 0x51
81#define TDA10048_CONF_PLL2 0x52
82#define TDA10048_CONF_PLL3 0x53
83#define TDA10048_CONF_ADC 0x54
84#define TDA10048_CONF_ADC_2 0x55
85#define TDA10048_CONF_C1_1 0x60
86#define TDA10048_CONF_C1_3 0x62
87#define TDA10048_AGC_CONF 0x70
88#define TDA10048_AGC_THRESHOLD_LSB 0x72
89#define TDA10048_AGC_THRESHOLD_MSB 0x73
90#define TDA10048_AGC_RENORM 0x74
91#define TDA10048_AGC_GAINS 0x76
92#define TDA10048_AGC_TUN_MIN 0x78
93#define TDA10048_AGC_TUN_MAX 0x79
94#define TDA10048_AGC_IF_MIN 0x7A
95#define TDA10048_AGC_IF_MAX 0x7B
96#define TDA10048_AGC_TUN_LEVEL 0x7E
97#define TDA10048_AGC_IF_LEVEL 0x7F
98#define TDA10048_DIG_AGC_LEVEL 0x81
99#define TDA10048_FREQ_PHY2_LSB 0x86
100#define TDA10048_FREQ_PHY2_MSB 0x87
101#define TDA10048_TIME_INVWREF_LSB 0x88
102#define TDA10048_TIME_INVWREF_MSB 0x89
103#define TDA10048_TIME_WREF_LSB 0x8A
104#define TDA10048_TIME_WREF_MID1 0x8B
105#define TDA10048_TIME_WREF_MID2 0x8C
106#define TDA10048_TIME_WREF_MSB 0x8D
107#define TDA10048_NP_OUT 0xA2
108#define TDA10048_CELL_ID_LSB 0xA4
109#define TDA10048_CELL_ID_MSB 0xA5
110#define TDA10048_EXTTPS_ODD 0xAA
111#define TDA10048_EXTTPS_EVEN 0xAB
112#define TDA10048_TPS_LENGTH 0xAC
113#define TDA10048_FREE_REG_1 0xB2
114#define TDA10048_FREE_REG_2 0xB3
115#define TDA10048_CONF_C3_1 0xC0
116#define TDA10048_CVBER_CTRL 0xC2
117#define TDA10048_CBER_NMAX_LSB 0xC4
118#define TDA10048_CBER_NMAX_MSB 0xC5
119#define TDA10048_CBER_LSB 0xC6
120#define TDA10048_CBER_MSB 0xC7
121#define TDA10048_VBER_LSB 0xC8
122#define TDA10048_VBER_MID 0xC9
123#define TDA10048_VBER_MSB 0xCA
124#define TDA10048_CVBER_LUT 0xCC
125#define TDA10048_UNCOR_CTRL 0xCD
126#define TDA10048_UNCOR_CPT_LSB 0xCE
127#define TDA10048_UNCOR_CPT_MSB 0xCF
128#define TDA10048_SOFT_IT_C3 0xD6
129#define TDA10048_CONF_TS2 0xE0
130#define TDA10048_CONF_TS1 0xE1
131
132static unsigned int debug;
133
134#define dprintk(level, fmt, arg...)\
135 do { if (debug >= level)\
136 printk(KERN_DEBUG "tda10048: " fmt, ## arg);\
137 } while (0)
138
139struct tda10048_state {
140
141 struct i2c_adapter *i2c;
142
143 /* We'll cache and update the attach config settings */
144 struct tda10048_config config;
145 struct dvb_frontend frontend;
146
147 int fwloaded;
148
149 u32 freq_if_hz;
150 u32 xtal_hz;
151 u32 pll_mfactor;
152 u32 pll_nfactor;
153 u32 pll_pfactor;
154 u32 sample_freq;
155
156 enum fe_bandwidth bandwidth;
157};
158
159static struct init_tab {
160 u8 reg;
161 u16 data;
162} init_tab[] = {
163 { TDA10048_CONF_PLL1, 0x08 },
164 { TDA10048_CONF_ADC_2, 0x00 },
165 { TDA10048_CONF_C4_1, 0x00 },
166 { TDA10048_CONF_PLL1, 0x0f },
167 { TDA10048_CONF_PLL2, 0x0a },
168 { TDA10048_CONF_PLL3, 0x43 },
169 { TDA10048_FREQ_PHY2_LSB, 0x02 },
170 { TDA10048_FREQ_PHY2_MSB, 0x0a },
171 { TDA10048_TIME_WREF_LSB, 0xbd },
172 { TDA10048_TIME_WREF_MID1, 0xe4 },
173 { TDA10048_TIME_WREF_MID2, 0xa8 },
174 { TDA10048_TIME_WREF_MSB, 0x02 },
175 { TDA10048_TIME_INVWREF_LSB, 0x04 },
176 { TDA10048_TIME_INVWREF_MSB, 0x06 },
177 { TDA10048_CONF_C4_1, 0x00 },
178 { TDA10048_CONF_C1_1, 0xa8 },
179 { TDA10048_AGC_CONF, 0x16 },
180 { TDA10048_CONF_C1_3, 0x0b },
181 { TDA10048_AGC_TUN_MIN, 0x00 },
182 { TDA10048_AGC_TUN_MAX, 0xff },
183 { TDA10048_AGC_IF_MIN, 0x00 },
184 { TDA10048_AGC_IF_MAX, 0xff },
185 { TDA10048_AGC_THRESHOLD_MSB, 0x00 },
186 { TDA10048_AGC_THRESHOLD_LSB, 0x70 },
187 { TDA10048_CVBER_CTRL, 0x38 },
188 { TDA10048_AGC_GAINS, 0x12 },
189 { TDA10048_CONF_XO, 0x00 },
190 { TDA10048_CONF_TS1, 0x07 },
191 { TDA10048_IC_MODE, 0x00 },
192 { TDA10048_CONF_TS2, 0xc0 },
193 { TDA10048_CONF_TRISTATE1, 0x21 },
194 { TDA10048_CONF_TRISTATE2, 0x00 },
195 { TDA10048_CONF_POLARITY, 0x00 },
196 { TDA10048_CONF_C4_2, 0x04 },
197 { TDA10048_CONF_ADC, 0x60 },
198 { TDA10048_CONF_ADC_2, 0x10 },
199 { TDA10048_CONF_ADC, 0x60 },
200 { TDA10048_CONF_ADC_2, 0x00 },
201 { TDA10048_CONF_C1_1, 0xa8 },
202 { TDA10048_UNCOR_CTRL, 0x00 },
203 { TDA10048_CONF_C4_2, 0x04 },
204};
205
206static struct pll_tab {
207 u32 clk_freq_khz;
208 u32 if_freq_khz;
209 u8 m, n, p;
210} pll_tab[] = {
211 { TDA10048_CLK_4000, TDA10048_IF_36130, 10, 0, 0 },
212 { TDA10048_CLK_16000, TDA10048_IF_3300, 10, 3, 0 },
213 { TDA10048_CLK_16000, TDA10048_IF_3500, 10, 3, 0 },
214 { TDA10048_CLK_16000, TDA10048_IF_3800, 10, 3, 0 },
215 { TDA10048_CLK_16000, TDA10048_IF_4000, 10, 3, 0 },
216 { TDA10048_CLK_16000, TDA10048_IF_4300, 10, 3, 0 },
217 { TDA10048_CLK_16000, TDA10048_IF_36130, 10, 3, 0 },
218};
219
220static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data)
221{
222 struct tda10048_config *config = &state->config;
223 int ret;
224 u8 buf[] = { reg, data };
225 struct i2c_msg msg = {
226 .addr = config->demod_address,
227 .flags = 0, .buf = buf, .len = 2 };
228
229 dprintk(2, "%s(reg = 0x%02x, data = 0x%02x)\n", __func__, reg, data);
230
231 ret = i2c_transfer(state->i2c, &msg, 1);
232
233 if (ret != 1)
234 printk("%s: writereg error (ret == %i)\n", __func__, ret);
235
236 return (ret != 1) ? -1 : 0;
237}
238
239static u8 tda10048_readreg(struct tda10048_state *state, u8 reg)
240{
241 struct tda10048_config *config = &state->config;
242 int ret;
243 u8 b0[] = { reg };
244 u8 b1[] = { 0 };
245 struct i2c_msg msg[] = {
246 { .addr = config->demod_address,
247 .flags = 0, .buf = b0, .len = 1 },
248 { .addr = config->demod_address,
249 .flags = I2C_M_RD, .buf = b1, .len = 1 } };
250
251 dprintk(2, "%s(reg = 0x%02x)\n", __func__, reg);
252
253 ret = i2c_transfer(state->i2c, msg, 2);
254
255 if (ret != 2)
256 printk(KERN_ERR "%s: readreg error (ret == %i)\n",
257 __func__, ret);
258
259 return b1[0];
260}
261
262static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg,
263 const u8 *data, u16 len)
264{
265 struct tda10048_config *config = &state->config;
266 int ret = -EREMOTEIO;
267 struct i2c_msg msg;
268 u8 *buf;
269
270 dprintk(2, "%s(%d, ?, len = %d)\n", __func__, reg, len);
271
272 buf = kmalloc(len + 1, GFP_KERNEL);
273 if (buf == NULL) {
274 ret = -ENOMEM;
275 goto error;
276 }
277
278 *buf = reg;
279 memcpy(buf + 1, data, len);
280
281 msg.addr = config->demod_address;
282 msg.flags = 0;
283 msg.buf = buf;
284 msg.len = len + 1;
285
286 dprintk(2, "%s(): write len = %d\n",
287 __func__, msg.len);
288
289 ret = i2c_transfer(state->i2c, &msg, 1);
290 if (ret != 1) {
291 printk(KERN_ERR "%s(): writereg error err %i\n",
292 __func__, ret);
293 ret = -EREMOTEIO;
294 }
295
296error:
297 kfree(buf);
298
299 return ret;
300}
301
302static int tda10048_set_phy2(struct dvb_frontend *fe, u32 sample_freq_hz,
303 u32 if_hz)
304{
305 struct tda10048_state *state = fe->demodulator_priv;
306 u64 t;
307
308 dprintk(1, "%s()\n", __func__);
309
310 if (sample_freq_hz == 0)
311 return -EINVAL;
312
313 if (if_hz < (sample_freq_hz / 2)) {
314 /* PHY2 = (if2/fs) * 2^15 */
315 t = if_hz;
316 t *= 10;
317 t *= 32768;
318 do_div(t, sample_freq_hz);
319 t += 5;
320 do_div(t, 10);
321 } else {
322 /* PHY2 = ((IF1-fs)/fs) * 2^15 */
323 t = sample_freq_hz - if_hz;
324 t *= 10;
325 t *= 32768;
326 do_div(t, sample_freq_hz);
327 t += 5;
328 do_div(t, 10);
329 t = ~t + 1;
330 }
331
332 tda10048_writereg(state, TDA10048_FREQ_PHY2_LSB, (u8)t);
333 tda10048_writereg(state, TDA10048_FREQ_PHY2_MSB, (u8)(t >> 8));
334
335 return 0;
336}
337
338static int tda10048_set_wref(struct dvb_frontend *fe, u32 sample_freq_hz,
339 u32 bw)
340{
341 struct tda10048_state *state = fe->demodulator_priv;
342 u64 t, z;
343 u32 b = 8000000;
344
345 dprintk(1, "%s()\n", __func__);
346
347 if (sample_freq_hz == 0)
348 return -EINVAL;
349
350 if (bw == BANDWIDTH_6_MHZ)
351 b = 6000000;
352 else
353 if (bw == BANDWIDTH_7_MHZ)
354 b = 7000000;
355
356 /* WREF = (B / (7 * fs)) * 2^31 */
357 t = b * 10;
358 /* avoid warning: this decimal constant is unsigned only in ISO C90 */
359 /* t *= 2147483648 on 32bit platforms */
360 t *= (2048 * 1024);
361 t *= 1024;
362 z = 7 * sample_freq_hz;
363 do_div(t, z);
364 t += 5;
365 do_div(t, 10);
366
367 tda10048_writereg(state, TDA10048_TIME_WREF_LSB, (u8)t);
368 tda10048_writereg(state, TDA10048_TIME_WREF_MID1, (u8)(t >> 8));
369 tda10048_writereg(state, TDA10048_TIME_WREF_MID2, (u8)(t >> 16));
370 tda10048_writereg(state, TDA10048_TIME_WREF_MSB, (u8)(t >> 24));
371
372 return 0;
373}
374
375static int tda10048_set_invwref(struct dvb_frontend *fe, u32 sample_freq_hz,
376 u32 bw)
377{
378 struct tda10048_state *state = fe->demodulator_priv;
379 u64 t;
380 u32 b = 8000000;
381
382 dprintk(1, "%s()\n", __func__);
383
384 if (sample_freq_hz == 0)
385 return -EINVAL;
386
387 if (bw == BANDWIDTH_6_MHZ)
388 b = 6000000;
389 else
390 if (bw == BANDWIDTH_7_MHZ)
391 b = 7000000;
392
393 /* INVWREF = ((7 * fs) / B) * 2^5 */
394 t = sample_freq_hz;
395 t *= 7;
396 t *= 32;
397 t *= 10;
398 do_div(t, b);
399 t += 5;
400 do_div(t, 10);
401
402 tda10048_writereg(state, TDA10048_TIME_INVWREF_LSB, (u8)t);
403 tda10048_writereg(state, TDA10048_TIME_INVWREF_MSB, (u8)(t >> 8));
404
405 return 0;
406}
407
408static int tda10048_set_bandwidth(struct dvb_frontend *fe,
409 enum fe_bandwidth bw)
410{
411 struct tda10048_state *state = fe->demodulator_priv;
412 dprintk(1, "%s(bw=%d)\n", __func__, bw);
413
414 /* Bandwidth setting may need to be adjusted */
415 switch (bw) {
416 case BANDWIDTH_6_MHZ:
417 case BANDWIDTH_7_MHZ:
418 case BANDWIDTH_8_MHZ:
419 tda10048_set_wref(fe, state->sample_freq, bw);
420 tda10048_set_invwref(fe, state->sample_freq, bw);
421 break;
422 default:
423 printk(KERN_ERR "%s() invalid bandwidth\n", __func__);
424 return -EINVAL;
425 }
426
427 state->bandwidth = bw;
428
429 return 0;
430}
431
432static int tda10048_set_if(struct dvb_frontend *fe, enum fe_bandwidth bw)
433{
434 struct tda10048_state *state = fe->demodulator_priv;
435 struct tda10048_config *config = &state->config;
436 int i;
437 u32 if_freq_khz;
438
439 dprintk(1, "%s(bw = %d)\n", __func__, bw);
440
441 /* based on target bandwidth and clk we calculate pll factors */
442 switch (bw) {
443 case BANDWIDTH_6_MHZ:
444 if_freq_khz = config->dtv6_if_freq_khz;
445 break;
446 case BANDWIDTH_7_MHZ:
447 if_freq_khz = config->dtv7_if_freq_khz;
448 break;
449 case BANDWIDTH_8_MHZ:
450 if_freq_khz = config->dtv8_if_freq_khz;
451 break;
452 default:
453 printk(KERN_ERR "%s() no default\n", __func__);
454 return -EINVAL;
455 }
456
457 for (i = 0; i < ARRAY_SIZE(pll_tab); i++) {
458 if ((pll_tab[i].clk_freq_khz == config->clk_freq_khz) &&
459 (pll_tab[i].if_freq_khz == if_freq_khz)) {
460
461 state->freq_if_hz = pll_tab[i].if_freq_khz * 1000;
462 state->xtal_hz = pll_tab[i].clk_freq_khz * 1000;
463 state->pll_mfactor = pll_tab[i].m;
464 state->pll_nfactor = pll_tab[i].n;
465 state->pll_pfactor = pll_tab[i].p;
466 break;
467 }
468 }
469 if (i == ARRAY_SIZE(pll_tab)) {
470 printk(KERN_ERR "%s() Incorrect attach settings\n",
471 __func__);
472 return -EINVAL;
473 }
474
475 dprintk(1, "- freq_if_hz = %d\n", state->freq_if_hz);
476 dprintk(1, "- xtal_hz = %d\n", state->xtal_hz);
477 dprintk(1, "- pll_mfactor = %d\n", state->pll_mfactor);
478 dprintk(1, "- pll_nfactor = %d\n", state->pll_nfactor);
479 dprintk(1, "- pll_pfactor = %d\n", state->pll_pfactor);
480
481 /* Calculate the sample frequency */
482 state->sample_freq = state->xtal_hz * (state->pll_mfactor + 45);
483 state->sample_freq /= (state->pll_nfactor + 1);
484 state->sample_freq /= (state->pll_pfactor + 4);
485 dprintk(1, "- sample_freq = %d\n", state->sample_freq);
486
487 /* Update the I/F */
488 tda10048_set_phy2(fe, state->sample_freq, state->freq_if_hz);
489
490 return 0;
491}
492
493static int tda10048_firmware_upload(struct dvb_frontend *fe)
494{
495 struct tda10048_state *state = fe->demodulator_priv;
496 struct tda10048_config *config = &state->config;
497 const struct firmware *fw;
498 int ret;
499 int pos = 0;
500 int cnt;
501 u8 wlen = config->fwbulkwritelen;
502
503 if ((wlen != TDA10048_BULKWRITE_200) && (wlen != TDA10048_BULKWRITE_50))
504 wlen = TDA10048_BULKWRITE_200;
505
506 /* request the firmware, this will block and timeout */
507 printk(KERN_INFO "%s: waiting for firmware upload (%s)...\n",
508 __func__,
509 TDA10048_DEFAULT_FIRMWARE);
510
511 ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE,
512 state->i2c->dev.parent);
513 if (ret) {
514 printk(KERN_ERR "%s: Upload failed. (file not found?)\n",
515 __func__);
516 return -EIO;
517 } else {
518 printk(KERN_INFO "%s: firmware read %Zu bytes.\n",
519 __func__,
520 fw->size);
521 ret = 0;
522 }
523
524 if (fw->size != TDA10048_DEFAULT_FIRMWARE_SIZE) {
525 printk(KERN_ERR "%s: firmware incorrect size\n", __func__);
526 ret = -EIO;
527 } else {
528 printk(KERN_INFO "%s: firmware uploading\n", __func__);
529
530 /* Soft reset */
531 tda10048_writereg(state, TDA10048_CONF_TRISTATE1,
532 tda10048_readreg(state, TDA10048_CONF_TRISTATE1)
533 & 0xfe);
534 tda10048_writereg(state, TDA10048_CONF_TRISTATE1,
535 tda10048_readreg(state, TDA10048_CONF_TRISTATE1)
536 | 0x01);
537
538 /* Put the demod into host download mode */
539 tda10048_writereg(state, TDA10048_CONF_C4_1,
540 tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xf9);
541
542 /* Boot the DSP */
543 tda10048_writereg(state, TDA10048_CONF_C4_1,
544 tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x08);
545
546 /* Prepare for download */
547 tda10048_writereg(state, TDA10048_DSP_CODE_CPT, 0);
548
549 /* Download the firmware payload */
550 while (pos < fw->size) {
551
552 if ((fw->size - pos) > wlen)
553 cnt = wlen;
554 else
555 cnt = fw->size - pos;
556
557 tda10048_writeregbulk(state, TDA10048_DSP_CODE_IN,
558 &fw->data[pos], cnt);
559
560 pos += cnt;
561 }
562
563 ret = -EIO;
564 /* Wait up to 250ms for the DSP to boot */
565 for (cnt = 0; cnt < 250 ; cnt += 10) {
566
567 msleep(10);
568
569 if (tda10048_readreg(state, TDA10048_SYNC_STATUS)
570 & 0x40) {
571 ret = 0;
572 break;
573 }
574 }
575 }
576
577 release_firmware(fw);
578
579 if (ret == 0) {
580 printk(KERN_INFO "%s: firmware uploaded\n", __func__);
581 state->fwloaded = 1;
582 } else
583 printk(KERN_ERR "%s: firmware upload failed\n", __func__);
584
585 return ret;
586}
587
588static int tda10048_set_inversion(struct dvb_frontend *fe, int inversion)
589{
590 struct tda10048_state *state = fe->demodulator_priv;
591
592 dprintk(1, "%s(%d)\n", __func__, inversion);
593
594 if (inversion == TDA10048_INVERSION_ON)
595 tda10048_writereg(state, TDA10048_CONF_C1_1,
596 tda10048_readreg(state, TDA10048_CONF_C1_1) | 0x20);
597 else
598 tda10048_writereg(state, TDA10048_CONF_C1_1,
599 tda10048_readreg(state, TDA10048_CONF_C1_1) & 0xdf);
600
601 return 0;
602}
603
604/* Retrieve the demod settings */
605static int tda10048_get_tps(struct tda10048_state *state,
606 struct dvb_ofdm_parameters *p)
607{
608 u8 val;
609
610 /* Make sure the TPS regs are valid */
611 if (!(tda10048_readreg(state, TDA10048_AUTO) & 0x01))
612 return -EAGAIN;
613
614 val = tda10048_readreg(state, TDA10048_OUT_CONF2);
615 switch ((val & 0x60) >> 5) {
616 case 0:
617 p->constellation = QPSK;
618 break;
619 case 1:
620 p->constellation = QAM_16;
621 break;
622 case 2:
623 p->constellation = QAM_64;
624 break;
625 }
626 switch ((val & 0x18) >> 3) {
627 case 0:
628 p->hierarchy_information = HIERARCHY_NONE;
629 break;
630 case 1:
631 p->hierarchy_information = HIERARCHY_1;
632 break;
633 case 2:
634 p->hierarchy_information = HIERARCHY_2;
635 break;
636 case 3:
637 p->hierarchy_information = HIERARCHY_4;
638 break;
639 }
640 switch (val & 0x07) {
641 case 0:
642 p->code_rate_HP = FEC_1_2;
643 break;
644 case 1:
645 p->code_rate_HP = FEC_2_3;
646 break;
647 case 2:
648 p->code_rate_HP = FEC_3_4;
649 break;
650 case 3:
651 p->code_rate_HP = FEC_5_6;
652 break;
653 case 4:
654 p->code_rate_HP = FEC_7_8;
655 break;
656 }
657
658 val = tda10048_readreg(state, TDA10048_OUT_CONF3);
659 switch (val & 0x07) {
660 case 0:
661 p->code_rate_LP = FEC_1_2;
662 break;
663 case 1:
664 p->code_rate_LP = FEC_2_3;
665 break;
666 case 2:
667 p->code_rate_LP = FEC_3_4;
668 break;
669 case 3:
670 p->code_rate_LP = FEC_5_6;
671 break;
672 case 4:
673 p->code_rate_LP = FEC_7_8;
674 break;
675 }
676
677 val = tda10048_readreg(state, TDA10048_OUT_CONF1);
678 switch ((val & 0x0c) >> 2) {
679 case 0:
680 p->guard_interval = GUARD_INTERVAL_1_32;
681 break;
682 case 1:
683 p->guard_interval = GUARD_INTERVAL_1_16;
684 break;
685 case 2:
686 p->guard_interval = GUARD_INTERVAL_1_8;
687 break;
688 case 3:
689 p->guard_interval = GUARD_INTERVAL_1_4;
690 break;
691 }
692 switch (val & 0x03) {
693 case 0:
694 p->transmission_mode = TRANSMISSION_MODE_2K;
695 break;
696 case 1:
697 p->transmission_mode = TRANSMISSION_MODE_8K;
698 break;
699 }
700
701 return 0;
702}
703
704static int tda10048_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
705{
706 struct tda10048_state *state = fe->demodulator_priv;
707 struct tda10048_config *config = &state->config;
708 dprintk(1, "%s(%d)\n", __func__, enable);
709
710 if (config->disable_gate_access)
711 return 0;
712
713 if (enable)
714 return tda10048_writereg(state, TDA10048_CONF_C4_1,
715 tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02);
716 else
717 return tda10048_writereg(state, TDA10048_CONF_C4_1,
718 tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xfd);
719}
720
721static int tda10048_output_mode(struct dvb_frontend *fe, int serial)
722{
723 struct tda10048_state *state = fe->demodulator_priv;
724 dprintk(1, "%s(%d)\n", __func__, serial);
725
726 /* Ensure pins are out of tri-state */
727 tda10048_writereg(state, TDA10048_CONF_TRISTATE1, 0x21);
728 tda10048_writereg(state, TDA10048_CONF_TRISTATE2, 0x00);
729
730 if (serial) {
731 tda10048_writereg(state, TDA10048_IC_MODE, 0x80 | 0x20);
732 tda10048_writereg(state, TDA10048_CONF_TS2, 0xc0);
733 } else {
734 tda10048_writereg(state, TDA10048_IC_MODE, 0x00);
735 tda10048_writereg(state, TDA10048_CONF_TS2, 0x01);
736 }
737
738 return 0;
739}
740
741/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
742/* TODO: Support manual tuning with specific params */
743static int tda10048_set_frontend(struct dvb_frontend *fe,
744 struct dvb_frontend_parameters *p)
745{
746 struct tda10048_state *state = fe->demodulator_priv;
747
748 dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency);
749
750 /* Update the I/F pll's if the bandwidth changes */
751 if (p->u.ofdm.bandwidth != state->bandwidth) {
752 tda10048_set_if(fe, p->u.ofdm.bandwidth);
753 tda10048_set_bandwidth(fe, p->u.ofdm.bandwidth);
754 }
755
756 if (fe->ops.tuner_ops.set_params) {
757
758 if (fe->ops.i2c_gate_ctrl)
759 fe->ops.i2c_gate_ctrl(fe, 1);
760
761 fe->ops.tuner_ops.set_params(fe, p);
762
763 if (fe->ops.i2c_gate_ctrl)
764 fe->ops.i2c_gate_ctrl(fe, 0);
765 }
766
767 /* Enable demod TPS auto detection and begin acquisition */
768 tda10048_writereg(state, TDA10048_AUTO, 0x57);
769 /* trigger cber and vber acquisition */
770 tda10048_writereg(state, TDA10048_CVBER_CTRL, 0x3B);
771
772 return 0;
773}
774
775/* Establish sane defaults and load firmware. */
776static int tda10048_init(struct dvb_frontend *fe)
777{
778 struct tda10048_state *state = fe->demodulator_priv;
779 struct tda10048_config *config = &state->config;
780 int ret = 0, i;
781
782 dprintk(1, "%s()\n", __func__);
783
784 /* Apply register defaults */
785 for (i = 0; i < ARRAY_SIZE(init_tab); i++)
786 tda10048_writereg(state, init_tab[i].reg, init_tab[i].data);
787
788 if (state->fwloaded == 0)
789 ret = tda10048_firmware_upload(fe);
790
791 /* Set either serial or parallel */
792 tda10048_output_mode(fe, config->output_mode);
793
794 /* Set inversion */
795 tda10048_set_inversion(fe, config->inversion);
796
797 /* Establish default RF values */
798 tda10048_set_if(fe, BANDWIDTH_8_MHZ);
799 tda10048_set_bandwidth(fe, BANDWIDTH_8_MHZ);
800
801 /* Ensure we leave the gate closed */
802 tda10048_i2c_gate_ctrl(fe, 0);
803
804 return ret;
805}
806
807static int tda10048_read_status(struct dvb_frontend *fe, fe_status_t *status)
808{
809 struct tda10048_state *state = fe->demodulator_priv;
810 u8 reg;
811
812 *status = 0;
813
814 reg = tda10048_readreg(state, TDA10048_SYNC_STATUS);
815
816 dprintk(1, "%s() status =0x%02x\n", __func__, reg);
817
818 if (reg & 0x02)
819 *status |= FE_HAS_CARRIER;
820
821 if (reg & 0x04)
822 *status |= FE_HAS_SIGNAL;
823
824 if (reg & 0x08) {
825 *status |= FE_HAS_LOCK;
826 *status |= FE_HAS_VITERBI;
827 *status |= FE_HAS_SYNC;
828 }
829
830 return 0;
831}
832
833static int tda10048_read_ber(struct dvb_frontend *fe, u32 *ber)
834{
835 struct tda10048_state *state = fe->demodulator_priv;
836 static u32 cber_current;
837 u32 cber_nmax;
838 u64 cber_tmp;
839
840 dprintk(1, "%s()\n", __func__);
841
842 /* update cber on interrupt */
843 if (tda10048_readreg(state, TDA10048_SOFT_IT_C3) & 0x01) {
844 cber_tmp = tda10048_readreg(state, TDA10048_CBER_MSB) << 8 |
845 tda10048_readreg(state, TDA10048_CBER_LSB);
846 cber_nmax = tda10048_readreg(state, TDA10048_CBER_NMAX_MSB) << 8 |
847 tda10048_readreg(state, TDA10048_CBER_NMAX_LSB);
848 cber_tmp *= 100000000;
849 cber_tmp *= 2;
850 cber_tmp = div_u64(cber_tmp, (cber_nmax * 32) + 1);
851 cber_current = (u32)cber_tmp;
852 /* retrigger cber acquisition */
853 tda10048_writereg(state, TDA10048_CVBER_CTRL, 0x39);
854 }
855 /* actual cber is (*ber)/1e8 */
856 *ber = cber_current;
857
858 return 0;
859}
860
861static int tda10048_read_signal_strength(struct dvb_frontend *fe,
862 u16 *signal_strength)
863{
864 struct tda10048_state *state = fe->demodulator_priv;
865 u8 v;
866
867 dprintk(1, "%s()\n", __func__);
868
869 *signal_strength = 65535;
870
871 v = tda10048_readreg(state, TDA10048_NP_OUT);
872 if (v > 0)
873 *signal_strength -= (v << 8) | v;
874
875 return 0;
876}
877
878/* SNR lookup table */
879static struct snr_tab {
880 u8 val;
881 u8 data;
882} snr_tab[] = {
883 { 0, 0 },
884 { 1, 246 },
885 { 2, 215 },
886 { 3, 198 },
887 { 4, 185 },
888 { 5, 176 },
889 { 6, 168 },
890 { 7, 161 },
891 { 8, 155 },
892 { 9, 150 },
893 { 10, 146 },
894 { 11, 141 },
895 { 12, 138 },
896 { 13, 134 },
897 { 14, 131 },
898 { 15, 128 },
899 { 16, 125 },
900 { 17, 122 },
901 { 18, 120 },
902 { 19, 118 },
903 { 20, 115 },
904 { 21, 113 },
905 { 22, 111 },
906 { 23, 109 },
907 { 24, 107 },
908 { 25, 106 },
909 { 26, 104 },
910 { 27, 102 },
911 { 28, 101 },
912 { 29, 99 },
913 { 30, 98 },
914 { 31, 96 },
915 { 32, 95 },
916 { 33, 94 },
917 { 34, 92 },
918 { 35, 91 },
919 { 36, 90 },
920 { 37, 89 },
921 { 38, 88 },
922 { 39, 86 },
923 { 40, 85 },
924 { 41, 84 },
925 { 42, 83 },
926 { 43, 82 },
927 { 44, 81 },
928 { 45, 80 },
929 { 46, 79 },
930 { 47, 78 },
931 { 48, 77 },
932 { 49, 76 },
933 { 50, 76 },
934 { 51, 75 },
935 { 52, 74 },
936 { 53, 73 },
937 { 54, 72 },
938 { 56, 71 },
939 { 57, 70 },
940 { 58, 69 },
941 { 60, 68 },
942 { 61, 67 },
943 { 63, 66 },
944 { 64, 65 },
945 { 66, 64 },
946 { 67, 63 },
947 { 68, 62 },
948 { 69, 62 },
949 { 70, 61 },
950 { 72, 60 },
951 { 74, 59 },
952 { 75, 58 },
953 { 77, 57 },
954 { 79, 56 },
955 { 81, 55 },
956 { 83, 54 },
957 { 85, 53 },
958 { 87, 52 },
959 { 89, 51 },
960 { 91, 50 },
961 { 93, 49 },
962 { 95, 48 },
963 { 97, 47 },
964 { 100, 46 },
965 { 102, 45 },
966 { 104, 44 },
967 { 107, 43 },
968 { 109, 42 },
969 { 112, 41 },
970 { 114, 40 },
971 { 117, 39 },
972 { 120, 38 },
973 { 123, 37 },
974 { 125, 36 },
975 { 128, 35 },
976 { 131, 34 },
977 { 134, 33 },
978 { 138, 32 },
979 { 141, 31 },
980 { 144, 30 },
981 { 147, 29 },
982 { 151, 28 },
983 { 154, 27 },
984 { 158, 26 },
985 { 162, 25 },
986 { 165, 24 },
987 { 169, 23 },
988 { 173, 22 },
989 { 177, 21 },
990 { 181, 20 },
991 { 186, 19 },
992 { 190, 18 },
993 { 194, 17 },
994 { 199, 16 },
995 { 204, 15 },
996 { 208, 14 },
997 { 213, 13 },
998 { 218, 12 },
999 { 223, 11 },
1000 { 229, 10 },
1001 { 234, 9 },
1002 { 239, 8 },
1003 { 245, 7 },
1004 { 251, 6 },
1005 { 255, 5 },
1006};
1007
1008static int tda10048_read_snr(struct dvb_frontend *fe, u16 *snr)
1009{
1010 struct tda10048_state *state = fe->demodulator_priv;
1011 u8 v;
1012 int i, ret = -EINVAL;
1013
1014 dprintk(1, "%s()\n", __func__);
1015
1016 v = tda10048_readreg(state, TDA10048_NP_OUT);
1017 for (i = 0; i < ARRAY_SIZE(snr_tab); i++) {
1018 if (v <= snr_tab[i].val) {
1019 *snr = snr_tab[i].data;
1020 ret = 0;
1021 break;
1022 }
1023 }
1024
1025 return ret;
1026}
1027
1028static int tda10048_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
1029{
1030 struct tda10048_state *state = fe->demodulator_priv;
1031
1032 dprintk(1, "%s()\n", __func__);
1033
1034 *ucblocks = tda10048_readreg(state, TDA10048_UNCOR_CPT_MSB) << 8 |
1035 tda10048_readreg(state, TDA10048_UNCOR_CPT_LSB);
1036 /* clear the uncorrected TS packets counter when saturated */
1037 if (*ucblocks == 0xFFFF)
1038 tda10048_writereg(state, TDA10048_UNCOR_CTRL, 0x80);
1039
1040 return 0;
1041}
1042
1043static int tda10048_get_frontend(struct dvb_frontend *fe,
1044 struct dvb_frontend_parameters *p)
1045{
1046 struct tda10048_state *state = fe->demodulator_priv;
1047
1048 dprintk(1, "%s()\n", __func__);
1049
1050 p->inversion = tda10048_readreg(state, TDA10048_CONF_C1_1)
1051 & 0x20 ? INVERSION_ON : INVERSION_OFF;
1052
1053 return tda10048_get_tps(state, &p->u.ofdm);
1054}
1055
1056static int tda10048_get_tune_settings(struct dvb_frontend *fe,
1057 struct dvb_frontend_tune_settings *tune)
1058{
1059 tune->min_delay_ms = 1000;
1060 return 0;
1061}
1062
1063static void tda10048_release(struct dvb_frontend *fe)
1064{
1065 struct tda10048_state *state = fe->demodulator_priv;
1066 dprintk(1, "%s()\n", __func__);
1067 kfree(state);
1068}
1069
1070static void tda10048_establish_defaults(struct dvb_frontend *fe)
1071{
1072 struct tda10048_state *state = fe->demodulator_priv;
1073 struct tda10048_config *config = &state->config;
1074
1075 /* Validate/default the config */
1076 if (config->dtv6_if_freq_khz == 0) {
1077 config->dtv6_if_freq_khz = TDA10048_IF_4300;
1078 printk(KERN_WARNING "%s() tda10048_config.dtv6_if_freq_khz "
1079 "is not set (defaulting to %d)\n",
1080 __func__,
1081 config->dtv6_if_freq_khz);
1082 }
1083
1084 if (config->dtv7_if_freq_khz == 0) {
1085 config->dtv7_if_freq_khz = TDA10048_IF_4300;
1086 printk(KERN_WARNING "%s() tda10048_config.dtv7_if_freq_khz "
1087 "is not set (defaulting to %d)\n",
1088 __func__,
1089 config->dtv7_if_freq_khz);
1090 }
1091
1092 if (config->dtv8_if_freq_khz == 0) {
1093 config->dtv8_if_freq_khz = TDA10048_IF_4300;
1094 printk(KERN_WARNING "%s() tda10048_config.dtv8_if_freq_khz "
1095 "is not set (defaulting to %d)\n",
1096 __func__,
1097 config->dtv8_if_freq_khz);
1098 }
1099
1100 if (config->clk_freq_khz == 0) {
1101 config->clk_freq_khz = TDA10048_CLK_16000;
1102 printk(KERN_WARNING "%s() tda10048_config.clk_freq_khz "
1103 "is not set (defaulting to %d)\n",
1104 __func__,
1105 config->clk_freq_khz);
1106 }
1107}
1108
1109static struct dvb_frontend_ops tda10048_ops;
1110
1111struct dvb_frontend *tda10048_attach(const struct tda10048_config *config,
1112 struct i2c_adapter *i2c)
1113{
1114 struct tda10048_state *state = NULL;
1115
1116 dprintk(1, "%s()\n", __func__);
1117
1118 /* allocate memory for the internal state */
1119 state = kzalloc(sizeof(struct tda10048_state), GFP_KERNEL);
1120 if (state == NULL)
1121 goto error;
1122
1123 /* setup the state and clone the config */
1124 memcpy(&state->config, config, sizeof(*config));
1125 state->i2c = i2c;
1126 state->fwloaded = 0;
1127 state->bandwidth = BANDWIDTH_8_MHZ;
1128
1129 /* check if the demod is present */
1130 if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048)
1131 goto error;
1132
1133 /* create dvb_frontend */
1134 memcpy(&state->frontend.ops, &tda10048_ops,
1135 sizeof(struct dvb_frontend_ops));
1136 state->frontend.demodulator_priv = state;
1137
1138 /* Establish any defaults the the user didn't pass */
1139 tda10048_establish_defaults(&state->frontend);
1140
1141 /* Set the xtal and freq defaults */
1142 if (tda10048_set_if(&state->frontend, BANDWIDTH_8_MHZ) != 0)
1143 goto error;
1144
1145 /* Default bandwidth */
1146 if (tda10048_set_bandwidth(&state->frontend, BANDWIDTH_8_MHZ) != 0)
1147 goto error;
1148
1149 /* Leave the gate closed */
1150 tda10048_i2c_gate_ctrl(&state->frontend, 0);
1151
1152 return &state->frontend;
1153
1154error:
1155 kfree(state);
1156 return NULL;
1157}
1158EXPORT_SYMBOL(tda10048_attach);
1159
1160static struct dvb_frontend_ops tda10048_ops = {
1161
1162 .info = {
1163 .name = "NXP TDA10048HN DVB-T",
1164 .type = FE_OFDM,
1165 .frequency_min = 177000000,
1166 .frequency_max = 858000000,
1167 .frequency_stepsize = 166666,
1168 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1169 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1170 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1171 FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
1172 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
1173 },
1174
1175 .release = tda10048_release,
1176 .init = tda10048_init,
1177 .i2c_gate_ctrl = tda10048_i2c_gate_ctrl,
1178 .set_frontend = tda10048_set_frontend,
1179 .get_frontend = tda10048_get_frontend,
1180 .get_tune_settings = tda10048_get_tune_settings,
1181 .read_status = tda10048_read_status,
1182 .read_ber = tda10048_read_ber,
1183 .read_signal_strength = tda10048_read_signal_strength,
1184 .read_snr = tda10048_read_snr,
1185 .read_ucblocks = tda10048_read_ucblocks,
1186};
1187
1188module_param(debug, int, 0644);
1189MODULE_PARM_DESC(debug, "Enable verbose debug messages");
1190
1191MODULE_DESCRIPTION("NXP TDA10048HN DVB-T Demodulator driver");
1192MODULE_AUTHOR("Steven Toth");
1193MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda10048.h b/drivers/media/dvb/frontends/tda10048.h
new file mode 100644
index 00000000000..8828ceaf74b
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10048.h
@@ -0,0 +1,82 @@
1/*
2 NXP TDA10048HN DVB OFDM demodulator driver
3
4 Copyright (C) 2009 Steven Toth <stoth@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
22#ifndef TDA10048_H
23#define TDA10048_H
24
25#include <linux/dvb/frontend.h>
26#include <linux/firmware.h>
27
28struct tda10048_config {
29
30 /* the demodulator's i2c address */
31 u8 demod_address;
32
33 /* serial/parallel output */
34#define TDA10048_PARALLEL_OUTPUT 0
35#define TDA10048_SERIAL_OUTPUT 1
36 u8 output_mode;
37
38#define TDA10048_BULKWRITE_200 200
39#define TDA10048_BULKWRITE_50 50
40 u8 fwbulkwritelen;
41
42 /* Spectral Inversion */
43#define TDA10048_INVERSION_OFF 0
44#define TDA10048_INVERSION_ON 1
45 u8 inversion;
46
47#define TDA10048_IF_3300 3300
48#define TDA10048_IF_3500 3500
49#define TDA10048_IF_3800 3800
50#define TDA10048_IF_4000 4000
51#define TDA10048_IF_4300 4300
52#define TDA10048_IF_4500 4500
53#define TDA10048_IF_4750 4750
54#define TDA10048_IF_36130 36130
55 u16 dtv6_if_freq_khz;
56 u16 dtv7_if_freq_khz;
57 u16 dtv8_if_freq_khz;
58
59#define TDA10048_CLK_4000 4000
60#define TDA10048_CLK_16000 16000
61 u16 clk_freq_khz;
62
63 /* Disable I2C gate access */
64 u8 disable_gate_access;
65};
66
67#if defined(CONFIG_DVB_TDA10048) || \
68 (defined(CONFIG_DVB_TDA10048_MODULE) && defined(MODULE))
69extern struct dvb_frontend *tda10048_attach(
70 const struct tda10048_config *config,
71 struct i2c_adapter *i2c);
72#else
73static inline struct dvb_frontend *tda10048_attach(
74 const struct tda10048_config *config,
75 struct i2c_adapter *i2c)
76{
77 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
78 return NULL;
79}
80#endif /* CONFIG_DVB_TDA10048 */
81
82#endif /* TDA10048_H */
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
new file mode 100644
index 00000000000..ea485d92355
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -0,0 +1,1380 @@
1 /*
2 Driver for Philips tda1004xh OFDM Demodulator
3
4 (c) 2003, 2004 Andrew de Quincey & Robert Schlabbach
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22/*
23 * This driver needs external firmware. Please use the commands
24 * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
25 * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
26 * download/extract them, and then copy them to /usr/lib/hotplug/firmware
27 * or /lib/firmware (depending on configuration of firmware hotplug).
28 */
29#define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw"
30#define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw"
31
32#include <linux/init.h>
33#include <linux/module.h>
34#include <linux/device.h>
35#include <linux/jiffies.h>
36#include <linux/string.h>
37#include <linux/slab.h>
38
39#include "dvb_frontend.h"
40#include "tda1004x.h"
41
42static int debug;
43#define dprintk(args...) \
44 do { \
45 if (debug) printk(KERN_DEBUG "tda1004x: " args); \
46 } while (0)
47
48#define TDA1004X_CHIPID 0x00
49#define TDA1004X_AUTO 0x01
50#define TDA1004X_IN_CONF1 0x02
51#define TDA1004X_IN_CONF2 0x03
52#define TDA1004X_OUT_CONF1 0x04
53#define TDA1004X_OUT_CONF2 0x05
54#define TDA1004X_STATUS_CD 0x06
55#define TDA1004X_CONFC4 0x07
56#define TDA1004X_DSSPARE2 0x0C
57#define TDA10045H_CODE_IN 0x0D
58#define TDA10045H_FWPAGE 0x0E
59#define TDA1004X_SCAN_CPT 0x10
60#define TDA1004X_DSP_CMD 0x11
61#define TDA1004X_DSP_ARG 0x12
62#define TDA1004X_DSP_DATA1 0x13
63#define TDA1004X_DSP_DATA2 0x14
64#define TDA1004X_CONFADC1 0x15
65#define TDA1004X_CONFC1 0x16
66#define TDA10045H_S_AGC 0x1a
67#define TDA10046H_AGC_TUN_LEVEL 0x1a
68#define TDA1004X_SNR 0x1c
69#define TDA1004X_CONF_TS1 0x1e
70#define TDA1004X_CONF_TS2 0x1f
71#define TDA1004X_CBER_RESET 0x20
72#define TDA1004X_CBER_MSB 0x21
73#define TDA1004X_CBER_LSB 0x22
74#define TDA1004X_CVBER_LUT 0x23
75#define TDA1004X_VBER_MSB 0x24
76#define TDA1004X_VBER_MID 0x25
77#define TDA1004X_VBER_LSB 0x26
78#define TDA1004X_UNCOR 0x27
79
80#define TDA10045H_CONFPLL_P 0x2D
81#define TDA10045H_CONFPLL_M_MSB 0x2E
82#define TDA10045H_CONFPLL_M_LSB 0x2F
83#define TDA10045H_CONFPLL_N 0x30
84
85#define TDA10046H_CONFPLL1 0x2D
86#define TDA10046H_CONFPLL2 0x2F
87#define TDA10046H_CONFPLL3 0x30
88#define TDA10046H_TIME_WREF1 0x31
89#define TDA10046H_TIME_WREF2 0x32
90#define TDA10046H_TIME_WREF3 0x33
91#define TDA10046H_TIME_WREF4 0x34
92#define TDA10046H_TIME_WREF5 0x35
93
94#define TDA10045H_UNSURW_MSB 0x31
95#define TDA10045H_UNSURW_LSB 0x32
96#define TDA10045H_WREF_MSB 0x33
97#define TDA10045H_WREF_MID 0x34
98#define TDA10045H_WREF_LSB 0x35
99#define TDA10045H_MUXOUT 0x36
100#define TDA1004X_CONFADC2 0x37
101
102#define TDA10045H_IOFFSET 0x38
103
104#define TDA10046H_CONF_TRISTATE1 0x3B
105#define TDA10046H_CONF_TRISTATE2 0x3C
106#define TDA10046H_CONF_POLARITY 0x3D
107#define TDA10046H_FREQ_OFFSET 0x3E
108#define TDA10046H_GPIO_OUT_SEL 0x41
109#define TDA10046H_GPIO_SELECT 0x42
110#define TDA10046H_AGC_CONF 0x43
111#define TDA10046H_AGC_THR 0x44
112#define TDA10046H_AGC_RENORM 0x45
113#define TDA10046H_AGC_GAINS 0x46
114#define TDA10046H_AGC_TUN_MIN 0x47
115#define TDA10046H_AGC_TUN_MAX 0x48
116#define TDA10046H_AGC_IF_MIN 0x49
117#define TDA10046H_AGC_IF_MAX 0x4A
118
119#define TDA10046H_FREQ_PHY2_MSB 0x4D
120#define TDA10046H_FREQ_PHY2_LSB 0x4E
121
122#define TDA10046H_CVBER_CTRL 0x4F
123#define TDA10046H_AGC_IF_LEVEL 0x52
124#define TDA10046H_CODE_CPT 0x57
125#define TDA10046H_CODE_IN 0x58
126
127
128static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data)
129{
130 int ret;
131 u8 buf[] = { reg, data };
132 struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
133
134 dprintk("%s: reg=0x%x, data=0x%x\n", __func__, reg, data);
135
136 msg.addr = state->config->demod_address;
137 ret = i2c_transfer(state->i2c, &msg, 1);
138
139 if (ret != 1)
140 dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
141 __func__, reg, data, ret);
142
143 dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__,
144 reg, data, ret);
145 return (ret != 1) ? -1 : 0;
146}
147
148static int tda1004x_read_byte(struct tda1004x_state *state, int reg)
149{
150 int ret;
151 u8 b0[] = { reg };
152 u8 b1[] = { 0 };
153 struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 },
154 { .flags = I2C_M_RD, .buf = b1, .len = 1 }};
155
156 dprintk("%s: reg=0x%x\n", __func__, reg);
157
158 msg[0].addr = state->config->demod_address;
159 msg[1].addr = state->config->demod_address;
160 ret = i2c_transfer(state->i2c, msg, 2);
161
162 if (ret != 2) {
163 dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg,
164 ret);
165 return -EINVAL;
166 }
167
168 dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__,
169 reg, b1[0], ret);
170 return b1[0];
171}
172
173static int tda1004x_write_mask(struct tda1004x_state *state, int reg, int mask, int data)
174{
175 int val;
176 dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __func__, reg,
177 mask, data);
178
179 // read a byte and check
180 val = tda1004x_read_byte(state, reg);
181 if (val < 0)
182 return val;
183
184 // mask if off
185 val = val & ~mask;
186 val |= data & 0xff;
187
188 // write it out again
189 return tda1004x_write_byteI(state, reg, val);
190}
191
192static int tda1004x_write_buf(struct tda1004x_state *state, int reg, unsigned char *buf, int len)
193{
194 int i;
195 int result;
196
197 dprintk("%s: reg=0x%x, len=0x%x\n", __func__, reg, len);
198
199 result = 0;
200 for (i = 0; i < len; i++) {
201 result = tda1004x_write_byteI(state, reg + i, buf[i]);
202 if (result != 0)
203 break;
204 }
205
206 return result;
207}
208
209static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state)
210{
211 int result;
212 dprintk("%s\n", __func__);
213
214 result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2);
215 msleep(20);
216 return result;
217}
218
219static int tda1004x_disable_tuner_i2c(struct tda1004x_state *state)
220{
221 dprintk("%s\n", __func__);
222
223 return tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 0);
224}
225
226static int tda10045h_set_bandwidth(struct tda1004x_state *state,
227 fe_bandwidth_t bandwidth)
228{
229 static u8 bandwidth_6mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x60, 0x1e, 0xa7, 0x45, 0x4f };
230 static u8 bandwidth_7mhz[] = { 0x02, 0x00, 0x37, 0x00, 0x4a, 0x2f, 0x6d, 0x76, 0xdb };
231 static u8 bandwidth_8mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x48, 0x17, 0x89, 0xc7, 0x14 };
232
233 switch (bandwidth) {
234 case BANDWIDTH_6_MHZ:
235 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_6mhz, sizeof(bandwidth_6mhz));
236 break;
237
238 case BANDWIDTH_7_MHZ:
239 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_7mhz, sizeof(bandwidth_7mhz));
240 break;
241
242 case BANDWIDTH_8_MHZ:
243 tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_8mhz, sizeof(bandwidth_8mhz));
244 break;
245
246 default:
247 return -EINVAL;
248 }
249
250 tda1004x_write_byteI(state, TDA10045H_IOFFSET, 0);
251
252 return 0;
253}
254
255static int tda10046h_set_bandwidth(struct tda1004x_state *state,
256 fe_bandwidth_t bandwidth)
257{
258 static u8 bandwidth_6mhz_53M[] = { 0x7b, 0x2e, 0x11, 0xf0, 0xd2 };
259 static u8 bandwidth_7mhz_53M[] = { 0x6a, 0x02, 0x6a, 0x43, 0x9f };
260 static u8 bandwidth_8mhz_53M[] = { 0x5c, 0x32, 0xc2, 0x96, 0x6d };
261
262 static u8 bandwidth_6mhz_48M[] = { 0x70, 0x02, 0x49, 0x24, 0x92 };
263 static u8 bandwidth_7mhz_48M[] = { 0x60, 0x02, 0xaa, 0xaa, 0xab };
264 static u8 bandwidth_8mhz_48M[] = { 0x54, 0x03, 0x0c, 0x30, 0xc3 };
265 int tda10046_clk53m;
266
267 if ((state->config->if_freq == TDA10046_FREQ_045) ||
268 (state->config->if_freq == TDA10046_FREQ_052))
269 tda10046_clk53m = 0;
270 else
271 tda10046_clk53m = 1;
272 switch (bandwidth) {
273 case BANDWIDTH_6_MHZ:
274 if (tda10046_clk53m)
275 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_53M,
276 sizeof(bandwidth_6mhz_53M));
277 else
278 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_48M,
279 sizeof(bandwidth_6mhz_48M));
280 if (state->config->if_freq == TDA10046_FREQ_045) {
281 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a);
282 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xab);
283 }
284 break;
285
286 case BANDWIDTH_7_MHZ:
287 if (tda10046_clk53m)
288 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_53M,
289 sizeof(bandwidth_7mhz_53M));
290 else
291 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_48M,
292 sizeof(bandwidth_7mhz_48M));
293 if (state->config->if_freq == TDA10046_FREQ_045) {
294 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
295 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00);
296 }
297 break;
298
299 case BANDWIDTH_8_MHZ:
300 if (tda10046_clk53m)
301 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_53M,
302 sizeof(bandwidth_8mhz_53M));
303 else
304 tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_48M,
305 sizeof(bandwidth_8mhz_48M));
306 if (state->config->if_freq == TDA10046_FREQ_045) {
307 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d);
308 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x55);
309 }
310 break;
311
312 default:
313 return -EINVAL;
314 }
315
316 return 0;
317}
318
319static int tda1004x_do_upload(struct tda1004x_state *state,
320 const unsigned char *mem, unsigned int len,
321 u8 dspCodeCounterReg, u8 dspCodeInReg)
322{
323 u8 buf[65];
324 struct i2c_msg fw_msg = { .flags = 0, .buf = buf, .len = 0 };
325 int tx_size;
326 int pos = 0;
327
328 /* clear code counter */
329 tda1004x_write_byteI(state, dspCodeCounterReg, 0);
330 fw_msg.addr = state->config->demod_address;
331
332 buf[0] = dspCodeInReg;
333 while (pos != len) {
334 // work out how much to send this time
335 tx_size = len - pos;
336 if (tx_size > 0x10)
337 tx_size = 0x10;
338
339 // send the chunk
340 memcpy(buf + 1, mem + pos, tx_size);
341 fw_msg.len = tx_size + 1;
342 if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) {
343 printk(KERN_ERR "tda1004x: Error during firmware upload\n");
344 return -EIO;
345 }
346 pos += tx_size;
347
348 dprintk("%s: fw_pos=0x%x\n", __func__, pos);
349 }
350 // give the DSP a chance to settle 03/10/05 Hac
351 msleep(100);
352
353 return 0;
354}
355
356static int tda1004x_check_upload_ok(struct tda1004x_state *state)
357{
358 u8 data1, data2;
359 unsigned long timeout;
360
361 if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
362 timeout = jiffies + 2 * HZ;
363 while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
364 if (time_after(jiffies, timeout)) {
365 printk(KERN_ERR "tda1004x: timeout waiting for DSP ready\n");
366 break;
367 }
368 msleep(1);
369 }
370 } else
371 msleep(100);
372
373 // check upload was OK
374 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP
375 tda1004x_write_byteI(state, TDA1004X_DSP_CMD, 0x67);
376
377 data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1);
378 data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2);
379 if (data1 != 0x67 || data2 < 0x20 || data2 > 0x2e) {
380 printk(KERN_INFO "tda1004x: found firmware revision %x -- invalid\n", data2);
381 return -EIO;
382 }
383 printk(KERN_INFO "tda1004x: found firmware revision %x -- ok\n", data2);
384 return 0;
385}
386
387static int tda10045_fwupload(struct dvb_frontend* fe)
388{
389 struct tda1004x_state* state = fe->demodulator_priv;
390 int ret;
391 const struct firmware *fw;
392
393 /* don't re-upload unless necessary */
394 if (tda1004x_check_upload_ok(state) == 0)
395 return 0;
396
397 /* request the firmware, this will block until someone uploads it */
398 printk(KERN_INFO "tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
399 ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
400 if (ret) {
401 printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
402 return ret;
403 }
404
405 /* reset chip */
406 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0);
407 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
408 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
409 msleep(10);
410
411 /* set parameters */
412 tda10045h_set_bandwidth(state, BANDWIDTH_8_MHZ);
413
414 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN);
415 release_firmware(fw);
416 if (ret)
417 return ret;
418 printk(KERN_INFO "tda1004x: firmware upload complete\n");
419
420 /* wait for DSP to initialise */
421 /* DSPREADY doesn't seem to work on the TDA10045H */
422 msleep(100);
423
424 return tda1004x_check_upload_ok(state);
425}
426
427static void tda10046_init_plls(struct dvb_frontend* fe)
428{
429 struct tda1004x_state* state = fe->demodulator_priv;
430 int tda10046_clk53m;
431
432 if ((state->config->if_freq == TDA10046_FREQ_045) ||
433 (state->config->if_freq == TDA10046_FREQ_052))
434 tda10046_clk53m = 0;
435 else
436 tda10046_clk53m = 1;
437
438 tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
439 if(tda10046_clk53m) {
440 printk(KERN_INFO "tda1004x: setting up plls for 53MHz sampling clock\n");
441 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x08); // PLL M = 8
442 } else {
443 printk(KERN_INFO "tda1004x: setting up plls for 48MHz sampling clock\n");
444 tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3
445 }
446 if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
447 dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __func__);
448 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
449 } else {
450 dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __func__);
451 tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3
452 }
453 if(tda10046_clk53m)
454 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x67);
455 else
456 tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x72);
457 /* Note clock frequency is handled implicitly */
458 switch (state->config->if_freq) {
459 case TDA10046_FREQ_045:
460 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c);
461 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00);
462 break;
463 case TDA10046_FREQ_052:
464 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d);
465 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xc7);
466 break;
467 case TDA10046_FREQ_3617:
468 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7);
469 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x59);
470 break;
471 case TDA10046_FREQ_3613:
472 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7);
473 tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x3f);
474 break;
475 }
476 tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz
477 /* let the PLLs settle */
478 msleep(120);
479}
480
481static int tda10046_fwupload(struct dvb_frontend* fe)
482{
483 struct tda1004x_state* state = fe->demodulator_priv;
484 int ret, confc4;
485 const struct firmware *fw;
486
487 /* reset + wake up chip */
488 if (state->config->xtal_freq == TDA10046_XTAL_4M) {
489 confc4 = 0;
490 } else {
491 dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__);
492 confc4 = 0x80;
493 }
494 tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
495
496 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
497 /* set GPIO 1 and 3 */
498 if (state->config->gpio_config != TDA10046_GPTRI) {
499 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0x33);
500 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, state->config->gpio_config &0x0f);
501 }
502 /* let the clocks recover from sleep */
503 msleep(10);
504
505 /* The PLLs need to be reprogrammed after sleep */
506 tda10046_init_plls(fe);
507 tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0);
508
509 /* don't re-upload unless necessary */
510 if (tda1004x_check_upload_ok(state) == 0)
511 return 0;
512
513 /*
514 For i2c normal work, we need to slow down the bus speed.
515 However, the slow down breaks the eeprom firmware load.
516 So, use normal speed for eeprom booting and then restore the
517 i2c speed after that. Tested with MSI TV @nyware A/D board,
518 that comes with firmware version 29 inside their eeprom.
519
520 It should also be noticed that no other I2C transfer should
521 be in course while booting from eeprom, otherwise, tda10046
522 goes into an instable state. So, proper locking are needed
523 at the i2c bus master.
524 */
525 printk(KERN_INFO "tda1004x: trying to boot from eeprom\n");
526 tda1004x_write_byteI(state, TDA1004X_CONFC4, 4);
527 msleep(300);
528 tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
529
530 /* Checks if eeprom firmware went without troubles */
531 if (tda1004x_check_upload_ok(state) == 0)
532 return 0;
533
534 /* eeprom firmware didn't work. Load one manually. */
535
536 if (state->config->request_firmware != NULL) {
537 /* request the firmware, this will block until someone uploads it */
538 printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
539 ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE);
540 if (ret) {
541 /* remain compatible to old bug: try to load with tda10045 image name */
542 ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
543 if (ret) {
544 printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
545 return ret;
546 } else {
547 printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n",
548 TDA10046_DEFAULT_FIRMWARE);
549 }
550 }
551 } else {
552 printk(KERN_ERR "tda1004x: no request function defined, can't upload from file\n");
553 return -EIO;
554 }
555 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST
556 ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN);
557 release_firmware(fw);
558 return tda1004x_check_upload_ok(state);
559}
560
561static int tda1004x_encode_fec(int fec)
562{
563 // convert known FEC values
564 switch (fec) {
565 case FEC_1_2:
566 return 0;
567 case FEC_2_3:
568 return 1;
569 case FEC_3_4:
570 return 2;
571 case FEC_5_6:
572 return 3;
573 case FEC_7_8:
574 return 4;
575 }
576
577 // unsupported
578 return -EINVAL;
579}
580
581static int tda1004x_decode_fec(int tdafec)
582{
583 // convert known FEC values
584 switch (tdafec) {
585 case 0:
586 return FEC_1_2;
587 case 1:
588 return FEC_2_3;
589 case 2:
590 return FEC_3_4;
591 case 3:
592 return FEC_5_6;
593 case 4:
594 return FEC_7_8;
595 }
596
597 // unsupported
598 return -1;
599}
600
601static int tda1004x_write(struct dvb_frontend* fe, const u8 buf[], int len)
602{
603 struct tda1004x_state* state = fe->demodulator_priv;
604
605 if (len != 2)
606 return -EINVAL;
607
608 return tda1004x_write_byteI(state, buf[0], buf[1]);
609}
610
611static int tda10045_init(struct dvb_frontend* fe)
612{
613 struct tda1004x_state* state = fe->demodulator_priv;
614
615 dprintk("%s\n", __func__);
616
617 if (tda10045_fwupload(fe)) {
618 printk("tda1004x: firmware upload failed\n");
619 return -EIO;
620 }
621
622 tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC
623
624 // tda setup
625 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
626 tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream
627 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0); // set polarity of VAGC signal
628 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0x80); // enable pulse killer
629 tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10); // enable auto offset
630 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0x0); // no frequency offset
631 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 0); // setup MPEG2 TS interface
632 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0); // setup MPEG2 TS interface
633 tda1004x_write_mask(state, TDA1004X_VBER_MSB, 0xe0, 0xa0); // 10^6 VBER measurement bits
634 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x10, 0); // VAGC polarity
635 tda1004x_write_byteI(state, TDA1004X_CONFADC1, 0x2e);
636
637 tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk);
638
639 return 0;
640}
641
642static int tda10046_init(struct dvb_frontend* fe)
643{
644 struct tda1004x_state* state = fe->demodulator_priv;
645 dprintk("%s\n", __func__);
646
647 if (tda10046_fwupload(fe)) {
648 printk("tda1004x: firmware upload failed\n");
649 return -EIO;
650 }
651
652 // tda setup
653 tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
654 tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream
655 tda1004x_write_byteI(state, TDA1004X_CONFC1, 0x88); // enable pulse killer
656
657 switch (state->config->agc_config) {
658 case TDA10046_AGC_DEFAULT:
659 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup
660 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
661 break;
662 case TDA10046_AGC_IFO_AUTO_NEG:
663 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
664 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
665 break;
666 case TDA10046_AGC_IFO_AUTO_POS:
667 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
668 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x00); // set AGC polarities
669 break;
670 case TDA10046_AGC_TDA827X:
671 tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup
672 tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold
673 tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
674 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
675 break;
676 }
677 if (state->config->ts_mode == 0) {
678 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x40);
679 tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7);
680 } else {
681 tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x80);
682 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x10,
683 state->config->invert_oclk << 4);
684 }
685 tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
686 tda1004x_write_mask (state, TDA10046H_CONF_TRISTATE1, 0x3e, 0x38); // Turn IF AGC output on
687 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // }
688 tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
689 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // }
690 tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // }
691 tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 0x12); // IF gain 2, TUN gain 1
692 tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits
693 tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config
694 tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config
695 // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes
696
697 return 0;
698}
699
700static int tda1004x_set_fe(struct dvb_frontend* fe,
701 struct dvb_frontend_parameters *fe_params)
702{
703 struct tda1004x_state* state = fe->demodulator_priv;
704 int tmp;
705 int inversion;
706
707 dprintk("%s\n", __func__);
708
709 if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
710 // setup auto offset
711 tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10);
712 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x80, 0);
713 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0);
714
715 // disable agc_conf[2]
716 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 0);
717 }
718
719 // set frequency
720 if (fe->ops.tuner_ops.set_params) {
721 fe->ops.tuner_ops.set_params(fe, fe_params);
722 if (fe->ops.i2c_gate_ctrl)
723 fe->ops.i2c_gate_ctrl(fe, 0);
724 }
725
726 // Hardcoded to use auto as much as possible on the TDA10045 as it
727 // is very unreliable if AUTO mode is _not_ used.
728 if (state->demod_type == TDA1004X_DEMOD_TDA10045) {
729 fe_params->u.ofdm.code_rate_HP = FEC_AUTO;
730 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
731 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
732 }
733
734 // Set standard params.. or put them to auto
735 if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) ||
736 (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) ||
737 (fe_params->u.ofdm.constellation == QAM_AUTO) ||
738 (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) {
739 tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto
740 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits
741 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits
742 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x3f, 0); // turn off FEC bits
743 } else {
744 tda1004x_write_mask(state, TDA1004X_AUTO, 1, 0); // disable auto
745
746 // set HP FEC
747 tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP);
748 if (tmp < 0)
749 return tmp;
750 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp);
751
752 // set LP FEC
753 tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP);
754 if (tmp < 0)
755 return tmp;
756 tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3);
757
758 // set constellation
759 switch (fe_params->u.ofdm.constellation) {
760 case QPSK:
761 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 0);
762 break;
763
764 case QAM_16:
765 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 1);
766 break;
767
768 case QAM_64:
769 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 2);
770 break;
771
772 default:
773 return -EINVAL;
774 }
775
776 // set hierarchy
777 switch (fe_params->u.ofdm.hierarchy_information) {
778 case HIERARCHY_NONE:
779 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0 << 5);
780 break;
781
782 case HIERARCHY_1:
783 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 1 << 5);
784 break;
785
786 case HIERARCHY_2:
787 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 2 << 5);
788 break;
789
790 case HIERARCHY_4:
791 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 3 << 5);
792 break;
793
794 default:
795 return -EINVAL;
796 }
797 }
798
799 // set bandwidth
800 switch (state->demod_type) {
801 case TDA1004X_DEMOD_TDA10045:
802 tda10045h_set_bandwidth(state, fe_params->u.ofdm.bandwidth);
803 break;
804
805 case TDA1004X_DEMOD_TDA10046:
806 tda10046h_set_bandwidth(state, fe_params->u.ofdm.bandwidth);
807 break;
808 }
809
810 // set inversion
811 inversion = fe_params->inversion;
812 if (state->config->invert)
813 inversion = inversion ? INVERSION_OFF : INVERSION_ON;
814 switch (inversion) {
815 case INVERSION_OFF:
816 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0);
817 break;
818
819 case INVERSION_ON:
820 tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0x20);
821 break;
822
823 default:
824 return -EINVAL;
825 }
826
827 // set guard interval
828 switch (fe_params->u.ofdm.guard_interval) {
829 case GUARD_INTERVAL_1_32:
830 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
831 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
832 break;
833
834 case GUARD_INTERVAL_1_16:
835 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
836 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 1 << 2);
837 break;
838
839 case GUARD_INTERVAL_1_8:
840 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
841 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 2 << 2);
842 break;
843
844 case GUARD_INTERVAL_1_4:
845 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0);
846 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 3 << 2);
847 break;
848
849 case GUARD_INTERVAL_AUTO:
850 tda1004x_write_mask(state, TDA1004X_AUTO, 2, 2);
851 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2);
852 break;
853
854 default:
855 return -EINVAL;
856 }
857
858 // set transmission mode
859 switch (fe_params->u.ofdm.transmission_mode) {
860 case TRANSMISSION_MODE_2K:
861 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);
862 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0 << 4);
863 break;
864
865 case TRANSMISSION_MODE_8K:
866 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0);
867 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 1 << 4);
868 break;
869
870 case TRANSMISSION_MODE_AUTO:
871 tda1004x_write_mask(state, TDA1004X_AUTO, 4, 4);
872 tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0);
873 break;
874
875 default:
876 return -EINVAL;
877 }
878
879 // start the lock
880 switch (state->demod_type) {
881 case TDA1004X_DEMOD_TDA10045:
882 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8);
883 tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0);
884 break;
885
886 case TDA1004X_DEMOD_TDA10046:
887 tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40);
888 msleep(1);
889 tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 1);
890 break;
891 }
892
893 msleep(10);
894
895 return 0;
896}
897
898static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params)
899{
900 struct tda1004x_state* state = fe->demodulator_priv;
901
902 dprintk("%s\n", __func__);
903
904 // inversion status
905 fe_params->inversion = INVERSION_OFF;
906 if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20)
907 fe_params->inversion = INVERSION_ON;
908 if (state->config->invert)
909 fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON;
910
911 // bandwidth
912 switch (state->demod_type) {
913 case TDA1004X_DEMOD_TDA10045:
914 switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) {
915 case 0x14:
916 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
917 break;
918 case 0xdb:
919 fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
920 break;
921 case 0x4f:
922 fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
923 break;
924 }
925 break;
926 case TDA1004X_DEMOD_TDA10046:
927 switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) {
928 case 0x5c:
929 case 0x54:
930 fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
931 break;
932 case 0x6a:
933 case 0x60:
934 fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
935 break;
936 case 0x7b:
937 case 0x70:
938 fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
939 break;
940 }
941 break;
942 }
943
944 // FEC
945 fe_params->u.ofdm.code_rate_HP =
946 tda1004x_decode_fec(tda1004x_read_byte(state, TDA1004X_OUT_CONF2) & 7);
947 fe_params->u.ofdm.code_rate_LP =
948 tda1004x_decode_fec((tda1004x_read_byte(state, TDA1004X_OUT_CONF2) >> 3) & 7);
949
950 // constellation
951 switch (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 3) {
952 case 0:
953 fe_params->u.ofdm.constellation = QPSK;
954 break;
955 case 1:
956 fe_params->u.ofdm.constellation = QAM_16;
957 break;
958 case 2:
959 fe_params->u.ofdm.constellation = QAM_64;
960 break;
961 }
962
963 // transmission mode
964 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
965 if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10)
966 fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
967
968 // guard interval
969 switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) {
970 case 0:
971 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
972 break;
973 case 1:
974 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
975 break;
976 case 2:
977 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
978 break;
979 case 3:
980 fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
981 break;
982 }
983
984 // hierarchy
985 switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x60) >> 5) {
986 case 0:
987 fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE;
988 break;
989 case 1:
990 fe_params->u.ofdm.hierarchy_information = HIERARCHY_1;
991 break;
992 case 2:
993 fe_params->u.ofdm.hierarchy_information = HIERARCHY_2;
994 break;
995 case 3:
996 fe_params->u.ofdm.hierarchy_information = HIERARCHY_4;
997 break;
998 }
999
1000 return 0;
1001}
1002
1003static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status)
1004{
1005 struct tda1004x_state* state = fe->demodulator_priv;
1006 int status;
1007 int cber;
1008 int vber;
1009
1010 dprintk("%s\n", __func__);
1011
1012 // read status
1013 status = tda1004x_read_byte(state, TDA1004X_STATUS_CD);
1014 if (status == -1)
1015 return -EIO;
1016
1017 // decode
1018 *fe_status = 0;
1019 if (status & 4)
1020 *fe_status |= FE_HAS_SIGNAL;
1021 if (status & 2)
1022 *fe_status |= FE_HAS_CARRIER;
1023 if (status & 8)
1024 *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
1025
1026 // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi
1027 // is getting anything valid
1028 if (!(*fe_status & FE_HAS_VITERBI)) {
1029 // read the CBER
1030 cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
1031 if (cber == -1)
1032 return -EIO;
1033 status = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
1034 if (status == -1)
1035 return -EIO;
1036 cber |= (status << 8);
1037 // The address 0x20 should be read to cope with a TDA10046 bug
1038 tda1004x_read_byte(state, TDA1004X_CBER_RESET);
1039
1040 if (cber != 65535)
1041 *fe_status |= FE_HAS_VITERBI;
1042 }
1043
1044 // if we DO have some valid VITERBI output, but don't already have SYNC
1045 // bytes (i.e. not LOCKED), see if the RS decoder is getting anything valid.
1046 if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) {
1047 // read the VBER
1048 vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB);
1049 if (vber == -1)
1050 return -EIO;
1051 status = tda1004x_read_byte(state, TDA1004X_VBER_MID);
1052 if (status == -1)
1053 return -EIO;
1054 vber |= (status << 8);
1055 status = tda1004x_read_byte(state, TDA1004X_VBER_MSB);
1056 if (status == -1)
1057 return -EIO;
1058 vber |= (status & 0x0f) << 16;
1059 // The CVBER_LUT should be read to cope with TDA10046 hardware bug
1060 tda1004x_read_byte(state, TDA1004X_CVBER_LUT);
1061
1062 // if RS has passed some valid TS packets, then we must be
1063 // getting some SYNC bytes
1064 if (vber < 16632)
1065 *fe_status |= FE_HAS_SYNC;
1066 }
1067
1068 // success
1069 dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
1070 return 0;
1071}
1072
1073static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
1074{
1075 struct tda1004x_state* state = fe->demodulator_priv;
1076 int tmp;
1077 int reg = 0;
1078
1079 dprintk("%s\n", __func__);
1080
1081 // determine the register to use
1082 switch (state->demod_type) {
1083 case TDA1004X_DEMOD_TDA10045:
1084 reg = TDA10045H_S_AGC;
1085 break;
1086
1087 case TDA1004X_DEMOD_TDA10046:
1088 reg = TDA10046H_AGC_IF_LEVEL;
1089 break;
1090 }
1091
1092 // read it
1093 tmp = tda1004x_read_byte(state, reg);
1094 if (tmp < 0)
1095 return -EIO;
1096
1097 *signal = (tmp << 8) | tmp;
1098 dprintk("%s: signal=0x%x\n", __func__, *signal);
1099 return 0;
1100}
1101
1102static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr)
1103{
1104 struct tda1004x_state* state = fe->demodulator_priv;
1105 int tmp;
1106
1107 dprintk("%s\n", __func__);
1108
1109 // read it
1110 tmp = tda1004x_read_byte(state, TDA1004X_SNR);
1111 if (tmp < 0)
1112 return -EIO;
1113 tmp = 255 - tmp;
1114
1115 *snr = ((tmp << 8) | tmp);
1116 dprintk("%s: snr=0x%x\n", __func__, *snr);
1117 return 0;
1118}
1119
1120static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
1121{
1122 struct tda1004x_state* state = fe->demodulator_priv;
1123 int tmp;
1124 int tmp2;
1125 int counter;
1126
1127 dprintk("%s\n", __func__);
1128
1129 // read the UCBLOCKS and reset
1130 counter = 0;
1131 tmp = tda1004x_read_byte(state, TDA1004X_UNCOR);
1132 if (tmp < 0)
1133 return -EIO;
1134 tmp &= 0x7f;
1135 while (counter++ < 5) {
1136 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1137 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1138 tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0);
1139
1140 tmp2 = tda1004x_read_byte(state, TDA1004X_UNCOR);
1141 if (tmp2 < 0)
1142 return -EIO;
1143 tmp2 &= 0x7f;
1144 if ((tmp2 < tmp) || (tmp2 == 0))
1145 break;
1146 }
1147
1148 if (tmp != 0x7f)
1149 *ucblocks = tmp;
1150 else
1151 *ucblocks = 0xffffffff;
1152
1153 dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks);
1154 return 0;
1155}
1156
1157static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
1158{
1159 struct tda1004x_state* state = fe->demodulator_priv;
1160 int tmp;
1161
1162 dprintk("%s\n", __func__);
1163
1164 // read it in
1165 tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
1166 if (tmp < 0)
1167 return -EIO;
1168 *ber = tmp << 1;
1169 tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB);
1170 if (tmp < 0)
1171 return -EIO;
1172 *ber |= (tmp << 9);
1173 // The address 0x20 should be read to cope with a TDA10046 bug
1174 tda1004x_read_byte(state, TDA1004X_CBER_RESET);
1175
1176 dprintk("%s: ber=0x%x\n", __func__, *ber);
1177 return 0;
1178}
1179
1180static int tda1004x_sleep(struct dvb_frontend* fe)
1181{
1182 struct tda1004x_state* state = fe->demodulator_priv;
1183 int gpio_conf;
1184
1185 switch (state->demod_type) {
1186 case TDA1004X_DEMOD_TDA10045:
1187 tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10);
1188 break;
1189
1190 case TDA1004X_DEMOD_TDA10046:
1191 /* set outputs to tristate */
1192 tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff);
1193 /* invert GPIO 1 and 3 if desired*/
1194 gpio_conf = state->config->gpio_config;
1195 if (gpio_conf >= TDA10046_GP00_I)
1196 tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f,
1197 (gpio_conf & 0x0f) ^ 0x0a);
1198
1199 tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0xc0);
1200 tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1);
1201 break;
1202 }
1203
1204 return 0;
1205}
1206
1207static int tda1004x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
1208{
1209 struct tda1004x_state* state = fe->demodulator_priv;
1210
1211 if (enable) {
1212 return tda1004x_enable_tuner_i2c(state);
1213 } else {
1214 return tda1004x_disable_tuner_i2c(state);
1215 }
1216}
1217
1218static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
1219{
1220 fesettings->min_delay_ms = 800;
1221 /* Drift compensation makes no sense for DVB-T */
1222 fesettings->step_size = 0;
1223 fesettings->max_drift = 0;
1224 return 0;
1225}
1226
1227static void tda1004x_release(struct dvb_frontend* fe)
1228{
1229 struct tda1004x_state *state = fe->demodulator_priv;
1230 kfree(state);
1231}
1232
1233static struct dvb_frontend_ops tda10045_ops = {
1234 .info = {
1235 .name = "Philips TDA10045H DVB-T",
1236 .type = FE_OFDM,
1237 .frequency_min = 51000000,
1238 .frequency_max = 858000000,
1239 .frequency_stepsize = 166667,
1240 .caps =
1241 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1242 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1243 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1244 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
1245 },
1246
1247 .release = tda1004x_release,
1248
1249 .init = tda10045_init,
1250 .sleep = tda1004x_sleep,
1251 .write = tda1004x_write,
1252 .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl,
1253
1254 .set_frontend = tda1004x_set_fe,
1255 .get_frontend = tda1004x_get_fe,
1256 .get_tune_settings = tda1004x_get_tune_settings,
1257
1258 .read_status = tda1004x_read_status,
1259 .read_ber = tda1004x_read_ber,
1260 .read_signal_strength = tda1004x_read_signal_strength,
1261 .read_snr = tda1004x_read_snr,
1262 .read_ucblocks = tda1004x_read_ucblocks,
1263};
1264
1265struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
1266 struct i2c_adapter* i2c)
1267{
1268 struct tda1004x_state *state;
1269 int id;
1270
1271 /* allocate memory for the internal state */
1272 state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
1273 if (!state) {
1274 printk(KERN_ERR "Can't alocate memory for tda10045 state\n");
1275 return NULL;
1276 }
1277
1278 /* setup the state */
1279 state->config = config;
1280 state->i2c = i2c;
1281 state->demod_type = TDA1004X_DEMOD_TDA10045;
1282
1283 /* check if the demod is there */
1284 id = tda1004x_read_byte(state, TDA1004X_CHIPID);
1285 if (id < 0) {
1286 printk(KERN_ERR "tda10045: chip is not answering. Giving up.\n");
1287 kfree(state);
1288 return NULL;
1289 }
1290
1291 if (id != 0x25) {
1292 printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id);
1293 kfree(state);
1294 return NULL;
1295 }
1296
1297 /* create dvb_frontend */
1298 memcpy(&state->frontend.ops, &tda10045_ops, sizeof(struct dvb_frontend_ops));
1299 state->frontend.demodulator_priv = state;
1300 return &state->frontend;
1301}
1302
1303static struct dvb_frontend_ops tda10046_ops = {
1304 .info = {
1305 .name = "Philips TDA10046H DVB-T",
1306 .type = FE_OFDM,
1307 .frequency_min = 51000000,
1308 .frequency_max = 858000000,
1309 .frequency_stepsize = 166667,
1310 .caps =
1311 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1312 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1313 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1314 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO
1315 },
1316
1317 .release = tda1004x_release,
1318
1319 .init = tda10046_init,
1320 .sleep = tda1004x_sleep,
1321 .write = tda1004x_write,
1322 .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl,
1323
1324 .set_frontend = tda1004x_set_fe,
1325 .get_frontend = tda1004x_get_fe,
1326 .get_tune_settings = tda1004x_get_tune_settings,
1327
1328 .read_status = tda1004x_read_status,
1329 .read_ber = tda1004x_read_ber,
1330 .read_signal_strength = tda1004x_read_signal_strength,
1331 .read_snr = tda1004x_read_snr,
1332 .read_ucblocks = tda1004x_read_ucblocks,
1333};
1334
1335struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
1336 struct i2c_adapter* i2c)
1337{
1338 struct tda1004x_state *state;
1339 int id;
1340
1341 /* allocate memory for the internal state */
1342 state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
1343 if (!state) {
1344 printk(KERN_ERR "Can't alocate memory for tda10046 state\n");
1345 return NULL;
1346 }
1347
1348 /* setup the state */
1349 state->config = config;
1350 state->i2c = i2c;
1351 state->demod_type = TDA1004X_DEMOD_TDA10046;
1352
1353 /* check if the demod is there */
1354 id = tda1004x_read_byte(state, TDA1004X_CHIPID);
1355 if (id < 0) {
1356 printk(KERN_ERR "tda10046: chip is not answering. Giving up.\n");
1357 kfree(state);
1358 return NULL;
1359 }
1360 if (id != 0x46) {
1361 printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id);
1362 kfree(state);
1363 return NULL;
1364 }
1365
1366 /* create dvb_frontend */
1367 memcpy(&state->frontend.ops, &tda10046_ops, sizeof(struct dvb_frontend_ops));
1368 state->frontend.demodulator_priv = state;
1369 return &state->frontend;
1370}
1371
1372module_param(debug, int, 0644);
1373MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1374
1375MODULE_DESCRIPTION("Philips TDA10045H & TDA10046H DVB-T Demodulator");
1376MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach");
1377MODULE_LICENSE("GPL");
1378
1379EXPORT_SYMBOL(tda10045_attach);
1380EXPORT_SYMBOL(tda10046_attach);
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
new file mode 100644
index 00000000000..4e27ffb0f14
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -0,0 +1,149 @@
1 /*
2 Driver for Philips tda1004xh OFDM Frontend
3
4 (c) 2004 Andrew de Quincey
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23#ifndef TDA1004X_H
24#define TDA1004X_H
25
26#include <linux/dvb/frontend.h>
27#include <linux/firmware.h>
28
29enum tda10046_xtal {
30 TDA10046_XTAL_4M,
31 TDA10046_XTAL_16M,
32};
33
34enum tda10046_agc {
35 TDA10046_AGC_DEFAULT, /* original configuration */
36 TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */
37 TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */
38 TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */
39};
40
41/* Many (hybrid) boards use GPIO 1 and 3
42 GPIO1 analog - dvb switch
43 GPIO3 firmware eeprom address switch
44*/
45enum tda10046_gpio {
46 TDA10046_GPTRI = 0x00, /* All GPIOs tristate */
47 TDA10046_GP00 = 0x40, /* GPIO3=0, GPIO1=0 */
48 TDA10046_GP01 = 0x42, /* GPIO3=0, GPIO1=1 */
49 TDA10046_GP10 = 0x48, /* GPIO3=1, GPIO1=0 */
50 TDA10046_GP11 = 0x4a, /* GPIO3=1, GPIO1=1 */
51 TDA10046_GP00_I = 0x80, /* GPIO3=0, GPIO1=0, invert in sleep mode*/
52 TDA10046_GP01_I = 0x82, /* GPIO3=0, GPIO1=1, invert in sleep mode */
53 TDA10046_GP10_I = 0x88, /* GPIO3=1, GPIO1=0, invert in sleep mode */
54 TDA10046_GP11_I = 0x8a, /* GPIO3=1, GPIO1=1, invert in sleep mode */
55};
56
57enum tda10046_if {
58 TDA10046_FREQ_3617, /* original config, 36,166 MHZ */
59 TDA10046_FREQ_3613, /* 36,13 MHZ */
60 TDA10046_FREQ_045, /* low IF, 4.0, 4.5, or 5.0 MHZ */
61 TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */
62};
63
64enum tda10046_tsout {
65 TDA10046_TS_PARALLEL = 0x00, /* parallel transport stream, default */
66 TDA10046_TS_SERIAL = 0x01, /* serial transport stream */
67};
68
69struct tda1004x_config
70{
71 /* the demodulator's i2c address */
72 u8 demod_address;
73
74 /* does the "inversion" need inverted? */
75 u8 invert;
76
77 /* Does the OCLK signal need inverted? */
78 u8 invert_oclk;
79
80 /* parallel or serial transport stream */
81 enum tda10046_tsout ts_mode;
82
83 /* Xtal frequency, 4 or 16MHz*/
84 enum tda10046_xtal xtal_freq;
85
86 /* IF frequency */
87 enum tda10046_if if_freq;
88
89 /* AGC configuration */
90 enum tda10046_agc agc_config;
91
92 /* setting of GPIO1 and 3 */
93 enum tda10046_gpio gpio_config;
94
95 /* slave address and configuration of the tuner */
96 u8 tuner_address;
97 u8 antenna_switch;
98
99 /* if the board uses another I2c Bridge (tda8290), its address */
100 u8 i2c_gate;
101
102 /* request firmware for device */
103 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
104};
105
106enum tda1004x_demod {
107 TDA1004X_DEMOD_TDA10045,
108 TDA1004X_DEMOD_TDA10046,
109};
110
111struct tda1004x_state {
112 struct i2c_adapter* i2c;
113 const struct tda1004x_config* config;
114 struct dvb_frontend frontend;
115
116 /* private demod data */
117 enum tda1004x_demod demod_type;
118};
119
120#if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE))
121extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
122 struct i2c_adapter* i2c);
123
124extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
125 struct i2c_adapter* i2c);
126#else
127static inline struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
128 struct i2c_adapter* i2c)
129{
130 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
131 return NULL;
132}
133static inline struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
134 struct i2c_adapter* i2c)
135{
136 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
137 return NULL;
138}
139#endif // CONFIG_DVB_TDA1004X
140
141static inline int tda1004x_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
142 int r = 0;
143 u8 buf[] = {reg, val};
144 if (fe->ops.write)
145 r = fe->ops.write(fe, buf, 2);
146 return r;
147}
148
149#endif // TDA1004X_H
diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c
new file mode 100644
index 00000000000..f2c8faac6f3
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10086.c
@@ -0,0 +1,775 @@
1 /*
2 Driver for Philips tda10086 DVBS Demodulator
3
4 (c) 2006 Andrew de Quincey
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/device.h>
26#include <linux/jiffies.h>
27#include <linux/string.h>
28#include <linux/slab.h>
29
30#include "dvb_frontend.h"
31#include "tda10086.h"
32
33#define SACLK 96000000
34
35struct tda10086_state {
36 struct i2c_adapter* i2c;
37 const struct tda10086_config* config;
38 struct dvb_frontend frontend;
39
40 /* private demod data */
41 u32 frequency;
42 u32 symbol_rate;
43 bool has_lock;
44};
45
46static int debug;
47#define dprintk(args...) \
48 do { \
49 if (debug) printk(KERN_DEBUG "tda10086: " args); \
50 } while (0)
51
52static int tda10086_write_byte(struct tda10086_state *state, int reg, int data)
53{
54 int ret;
55 u8 b0[] = { reg, data };
56 struct i2c_msg msg = { .flags = 0, .buf = b0, .len = 2 };
57
58 msg.addr = state->config->demod_address;
59 ret = i2c_transfer(state->i2c, &msg, 1);
60
61 if (ret != 1)
62 dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
63 __func__, reg, data, ret);
64
65 return (ret != 1) ? ret : 0;
66}
67
68static int tda10086_read_byte(struct tda10086_state *state, int reg)
69{
70 int ret;
71 u8 b0[] = { reg };
72 u8 b1[] = { 0 };
73 struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 },
74 { .flags = I2C_M_RD, .buf = b1, .len = 1 }};
75
76 msg[0].addr = state->config->demod_address;
77 msg[1].addr = state->config->demod_address;
78 ret = i2c_transfer(state->i2c, msg, 2);
79
80 if (ret != 2) {
81 dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg,
82 ret);
83 return ret;
84 }
85
86 return b1[0];
87}
88
89static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask, int data)
90{
91 int val;
92
93 /* read a byte and check */
94 val = tda10086_read_byte(state, reg);
95 if (val < 0)
96 return val;
97
98 /* mask if off */
99 val = val & ~mask;
100 val |= data & 0xff;
101
102 /* write it out again */
103 return tda10086_write_byte(state, reg, val);
104}
105
106static int tda10086_init(struct dvb_frontend* fe)
107{
108 struct tda10086_state* state = fe->demodulator_priv;
109 u8 t22k_off = 0x80;
110
111 dprintk ("%s\n", __func__);
112
113 if (state->config->diseqc_tone)
114 t22k_off = 0;
115 /* reset */
116 tda10086_write_byte(state, 0x00, 0x00);
117 msleep(10);
118
119 /* misc setup */
120 tda10086_write_byte(state, 0x01, 0x94);
121 tda10086_write_byte(state, 0x02, 0x35); /* NOTE: TT drivers appear to disable CSWP */
122 tda10086_write_byte(state, 0x03, 0xe4);
123 tda10086_write_byte(state, 0x04, 0x43);
124 tda10086_write_byte(state, 0x0c, 0x0c);
125 tda10086_write_byte(state, 0x1b, 0xb0); /* noise threshold */
126 tda10086_write_byte(state, 0x20, 0x89); /* misc */
127 tda10086_write_byte(state, 0x30, 0x04); /* acquisition period length */
128 tda10086_write_byte(state, 0x32, 0x00); /* irq off */
129 tda10086_write_byte(state, 0x31, 0x56); /* setup AFC */
130
131 /* setup PLL (this assumes SACLK = 96MHz) */
132 tda10086_write_byte(state, 0x55, 0x2c); /* misc PLL setup */
133 if (state->config->xtal_freq == TDA10086_XTAL_16M) {
134 tda10086_write_byte(state, 0x3a, 0x0b); /* M=12 */
135 tda10086_write_byte(state, 0x3b, 0x01); /* P=2 */
136 } else {
137 tda10086_write_byte(state, 0x3a, 0x17); /* M=24 */
138 tda10086_write_byte(state, 0x3b, 0x00); /* P=1 */
139 }
140 tda10086_write_mask(state, 0x55, 0x20, 0x00); /* powerup PLL */
141
142 /* setup TS interface */
143 tda10086_write_byte(state, 0x11, 0x81);
144 tda10086_write_byte(state, 0x12, 0x81);
145 tda10086_write_byte(state, 0x19, 0x40); /* parallel mode A + MSBFIRST */
146 tda10086_write_byte(state, 0x56, 0x80); /* powerdown WPLL - unused in the mode we use */
147 tda10086_write_byte(state, 0x57, 0x08); /* bypass WPLL - unused in the mode we use */
148 tda10086_write_byte(state, 0x10, 0x2a);
149
150 /* setup ADC */
151 tda10086_write_byte(state, 0x58, 0x61); /* ADC setup */
152 tda10086_write_mask(state, 0x58, 0x01, 0x00); /* powerup ADC */
153
154 /* setup AGC */
155 tda10086_write_byte(state, 0x05, 0x0B);
156 tda10086_write_byte(state, 0x37, 0x63);
157 tda10086_write_byte(state, 0x3f, 0x0a); /* NOTE: flydvb varies it */
158 tda10086_write_byte(state, 0x40, 0x64);
159 tda10086_write_byte(state, 0x41, 0x4f);
160 tda10086_write_byte(state, 0x42, 0x43);
161
162 /* setup viterbi */
163 tda10086_write_byte(state, 0x1a, 0x11); /* VBER 10^6, DVB, QPSK */
164
165 /* setup carrier recovery */
166 tda10086_write_byte(state, 0x3d, 0x80);
167
168 /* setup SEC */
169 tda10086_write_byte(state, 0x36, t22k_off); /* all SEC off, 22k tone */
170 tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000)));
171 tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8);
172
173 return 0;
174}
175
176static void tda10086_diseqc_wait(struct tda10086_state *state)
177{
178 unsigned long timeout = jiffies + msecs_to_jiffies(200);
179 while (!(tda10086_read_byte(state, 0x50) & 0x01)) {
180 if(time_after(jiffies, timeout)) {
181 printk("%s: diseqc queue not ready, command may be lost.\n", __func__);
182 break;
183 }
184 msleep(10);
185 }
186}
187
188static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
189{
190 struct tda10086_state* state = fe->demodulator_priv;
191 u8 t22k_off = 0x80;
192
193 dprintk ("%s\n", __func__);
194
195 if (state->config->diseqc_tone)
196 t22k_off = 0;
197
198 switch (tone) {
199 case SEC_TONE_OFF:
200 tda10086_write_byte(state, 0x36, t22k_off);
201 break;
202
203 case SEC_TONE_ON:
204 tda10086_write_byte(state, 0x36, 0x01 + t22k_off);
205 break;
206 }
207
208 return 0;
209}
210
211static int tda10086_send_master_cmd (struct dvb_frontend* fe,
212 struct dvb_diseqc_master_cmd* cmd)
213{
214 struct tda10086_state* state = fe->demodulator_priv;
215 int i;
216 u8 oldval;
217 u8 t22k_off = 0x80;
218
219 dprintk ("%s\n", __func__);
220
221 if (state->config->diseqc_tone)
222 t22k_off = 0;
223
224 if (cmd->msg_len > 6)
225 return -EINVAL;
226 oldval = tda10086_read_byte(state, 0x36);
227
228 for(i=0; i< cmd->msg_len; i++) {
229 tda10086_write_byte(state, 0x48+i, cmd->msg[i]);
230 }
231 tda10086_write_byte(state, 0x36, (0x08 + t22k_off)
232 | ((cmd->msg_len - 1) << 4));
233
234 tda10086_diseqc_wait(state);
235
236 tda10086_write_byte(state, 0x36, oldval);
237
238 return 0;
239}
240
241static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
242{
243 struct tda10086_state* state = fe->demodulator_priv;
244 u8 oldval = tda10086_read_byte(state, 0x36);
245 u8 t22k_off = 0x80;
246
247 dprintk ("%s\n", __func__);
248
249 if (state->config->diseqc_tone)
250 t22k_off = 0;
251
252 switch(minicmd) {
253 case SEC_MINI_A:
254 tda10086_write_byte(state, 0x36, 0x04 + t22k_off);
255 break;
256
257 case SEC_MINI_B:
258 tda10086_write_byte(state, 0x36, 0x06 + t22k_off);
259 break;
260 }
261
262 tda10086_diseqc_wait(state);
263
264 tda10086_write_byte(state, 0x36, oldval);
265
266 return 0;
267}
268
269static int tda10086_set_inversion(struct tda10086_state *state,
270 struct dvb_frontend_parameters *fe_params)
271{
272 u8 invval = 0x80;
273
274 dprintk ("%s %i %i\n", __func__, fe_params->inversion, state->config->invert);
275
276 switch(fe_params->inversion) {
277 case INVERSION_OFF:
278 if (state->config->invert)
279 invval = 0x40;
280 break;
281 case INVERSION_ON:
282 if (!state->config->invert)
283 invval = 0x40;
284 break;
285 case INVERSION_AUTO:
286 invval = 0x00;
287 break;
288 }
289 tda10086_write_mask(state, 0x0c, 0xc0, invval);
290
291 return 0;
292}
293
294static int tda10086_set_symbol_rate(struct tda10086_state *state,
295 struct dvb_frontend_parameters *fe_params)
296{
297 u8 dfn = 0;
298 u8 afs = 0;
299 u8 byp = 0;
300 u8 reg37 = 0x43;
301 u8 reg42 = 0x43;
302 u64 big;
303 u32 tmp;
304 u32 bdr;
305 u32 bdri;
306 u32 symbol_rate = fe_params->u.qpsk.symbol_rate;
307
308 dprintk ("%s %i\n", __func__, symbol_rate);
309
310 /* setup the decimation and anti-aliasing filters.. */
311 if (symbol_rate < (u32) (SACLK * 0.0137)) {
312 dfn=4;
313 afs=1;
314 } else if (symbol_rate < (u32) (SACLK * 0.0208)) {
315 dfn=4;
316 afs=0;
317 } else if (symbol_rate < (u32) (SACLK * 0.0270)) {
318 dfn=3;
319 afs=1;
320 } else if (symbol_rate < (u32) (SACLK * 0.0416)) {
321 dfn=3;
322 afs=0;
323 } else if (symbol_rate < (u32) (SACLK * 0.0550)) {
324 dfn=2;
325 afs=1;
326 } else if (symbol_rate < (u32) (SACLK * 0.0833)) {
327 dfn=2;
328 afs=0;
329 } else if (symbol_rate < (u32) (SACLK * 0.1100)) {
330 dfn=1;
331 afs=1;
332 } else if (symbol_rate < (u32) (SACLK * 0.1666)) {
333 dfn=1;
334 afs=0;
335 } else if (symbol_rate < (u32) (SACLK * 0.2200)) {
336 dfn=0;
337 afs=1;
338 } else if (symbol_rate < (u32) (SACLK * 0.3333)) {
339 dfn=0;
340 afs=0;
341 } else {
342 reg37 = 0x63;
343 reg42 = 0x4f;
344 byp=1;
345 }
346
347 /* calculate BDR */
348 big = (1ULL<<21) * ((u64) symbol_rate/1000ULL) * (1ULL<<dfn);
349 big += ((SACLK/1000ULL)-1ULL);
350 do_div(big, (SACLK/1000ULL));
351 bdr = big & 0xfffff;
352
353 /* calculate BDRI */
354 tmp = (1<<dfn)*(symbol_rate/1000);
355 bdri = ((32 * (SACLK/1000)) + (tmp-1)) / tmp;
356
357 tda10086_write_byte(state, 0x21, (afs << 7) | dfn);
358 tda10086_write_mask(state, 0x20, 0x08, byp << 3);
359 tda10086_write_byte(state, 0x06, bdr);
360 tda10086_write_byte(state, 0x07, bdr >> 8);
361 tda10086_write_byte(state, 0x08, bdr >> 16);
362 tda10086_write_byte(state, 0x09, bdri);
363 tda10086_write_byte(state, 0x37, reg37);
364 tda10086_write_byte(state, 0x42, reg42);
365
366 return 0;
367}
368
369static int tda10086_set_fec(struct tda10086_state *state,
370 struct dvb_frontend_parameters *fe_params)
371{
372 u8 fecval;
373
374 dprintk ("%s %i\n", __func__, fe_params->u.qpsk.fec_inner);
375
376 switch(fe_params->u.qpsk.fec_inner) {
377 case FEC_1_2:
378 fecval = 0x00;
379 break;
380 case FEC_2_3:
381 fecval = 0x01;
382 break;
383 case FEC_3_4:
384 fecval = 0x02;
385 break;
386 case FEC_4_5:
387 fecval = 0x03;
388 break;
389 case FEC_5_6:
390 fecval = 0x04;
391 break;
392 case FEC_6_7:
393 fecval = 0x05;
394 break;
395 case FEC_7_8:
396 fecval = 0x06;
397 break;
398 case FEC_8_9:
399 fecval = 0x07;
400 break;
401 case FEC_AUTO:
402 fecval = 0x08;
403 break;
404 default:
405 return -1;
406 }
407 tda10086_write_byte(state, 0x0d, fecval);
408
409 return 0;
410}
411
412static int tda10086_set_frontend(struct dvb_frontend* fe,
413 struct dvb_frontend_parameters *fe_params)
414{
415 struct tda10086_state *state = fe->demodulator_priv;
416 int ret;
417 u32 freq = 0;
418 int freqoff;
419
420 dprintk ("%s\n", __func__);
421
422 /* modify parameters for tuning */
423 tda10086_write_byte(state, 0x02, 0x35);
424 state->has_lock = false;
425
426 /* set params */
427 if (fe->ops.tuner_ops.set_params) {
428 fe->ops.tuner_ops.set_params(fe, fe_params);
429 if (fe->ops.i2c_gate_ctrl)
430 fe->ops.i2c_gate_ctrl(fe, 0);
431
432 if (fe->ops.tuner_ops.get_frequency)
433 fe->ops.tuner_ops.get_frequency(fe, &freq);
434 if (fe->ops.i2c_gate_ctrl)
435 fe->ops.i2c_gate_ctrl(fe, 0);
436 }
437
438 /* calcluate the frequency offset (in *Hz* not kHz) */
439 freqoff = fe_params->frequency - freq;
440 freqoff = ((1<<16) * freqoff) / (SACLK/1000);
441 tda10086_write_byte(state, 0x3d, 0x80 | ((freqoff >> 8) & 0x7f));
442 tda10086_write_byte(state, 0x3e, freqoff);
443
444 if ((ret = tda10086_set_inversion(state, fe_params)) < 0)
445 return ret;
446 if ((ret = tda10086_set_symbol_rate(state, fe_params)) < 0)
447 return ret;
448 if ((ret = tda10086_set_fec(state, fe_params)) < 0)
449 return ret;
450
451 /* soft reset + disable TS output until lock */
452 tda10086_write_mask(state, 0x10, 0x40, 0x40);
453 tda10086_write_mask(state, 0x00, 0x01, 0x00);
454
455 state->symbol_rate = fe_params->u.qpsk.symbol_rate;
456 state->frequency = fe_params->frequency;
457 return 0;
458}
459
460static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params)
461{
462 struct tda10086_state* state = fe->demodulator_priv;
463 u8 val;
464 int tmp;
465 u64 tmp64;
466
467 dprintk ("%s\n", __func__);
468
469 /* check for invalid symbol rate */
470 if (fe_params->u.qpsk.symbol_rate < 500000)
471 return -EINVAL;
472
473 /* calculate the updated frequency (note: we convert from Hz->kHz) */
474 tmp64 = tda10086_read_byte(state, 0x52);
475 tmp64 |= (tda10086_read_byte(state, 0x51) << 8);
476 if (tmp64 & 0x8000)
477 tmp64 |= 0xffffffffffff0000ULL;
478 tmp64 = (tmp64 * (SACLK/1000ULL));
479 do_div(tmp64, (1ULL<<15) * (1ULL<<1));
480 fe_params->frequency = (int) state->frequency + (int) tmp64;
481
482 /* the inversion */
483 val = tda10086_read_byte(state, 0x0c);
484 if (val & 0x80) {
485 switch(val & 0x40) {
486 case 0x00:
487 fe_params->inversion = INVERSION_OFF;
488 if (state->config->invert)
489 fe_params->inversion = INVERSION_ON;
490 break;
491 default:
492 fe_params->inversion = INVERSION_ON;
493 if (state->config->invert)
494 fe_params->inversion = INVERSION_OFF;
495 break;
496 }
497 } else {
498 tda10086_read_byte(state, 0x0f);
499 switch(val & 0x02) {
500 case 0x00:
501 fe_params->inversion = INVERSION_OFF;
502 if (state->config->invert)
503 fe_params->inversion = INVERSION_ON;
504 break;
505 default:
506 fe_params->inversion = INVERSION_ON;
507 if (state->config->invert)
508 fe_params->inversion = INVERSION_OFF;
509 break;
510 }
511 }
512
513 /* calculate the updated symbol rate */
514 tmp = tda10086_read_byte(state, 0x1d);
515 if (tmp & 0x80)
516 tmp |= 0xffffff00;
517 tmp = (tmp * 480 * (1<<1)) / 128;
518 tmp = ((state->symbol_rate/1000) * tmp) / (1000000/1000);
519 fe_params->u.qpsk.symbol_rate = state->symbol_rate + tmp;
520
521 /* the FEC */
522 val = (tda10086_read_byte(state, 0x0d) & 0x70) >> 4;
523 switch(val) {
524 case 0x00:
525 fe_params->u.qpsk.fec_inner = FEC_1_2;
526 break;
527 case 0x01:
528 fe_params->u.qpsk.fec_inner = FEC_2_3;
529 break;
530 case 0x02:
531 fe_params->u.qpsk.fec_inner = FEC_3_4;
532 break;
533 case 0x03:
534 fe_params->u.qpsk.fec_inner = FEC_4_5;
535 break;
536 case 0x04:
537 fe_params->u.qpsk.fec_inner = FEC_5_6;
538 break;
539 case 0x05:
540 fe_params->u.qpsk.fec_inner = FEC_6_7;
541 break;
542 case 0x06:
543 fe_params->u.qpsk.fec_inner = FEC_7_8;
544 break;
545 case 0x07:
546 fe_params->u.qpsk.fec_inner = FEC_8_9;
547 break;
548 }
549
550 return 0;
551}
552
553static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status)
554{
555 struct tda10086_state* state = fe->demodulator_priv;
556 u8 val;
557
558 dprintk ("%s\n", __func__);
559
560 val = tda10086_read_byte(state, 0x0e);
561 *fe_status = 0;
562 if (val & 0x01)
563 *fe_status |= FE_HAS_SIGNAL;
564 if (val & 0x02)
565 *fe_status |= FE_HAS_CARRIER;
566 if (val & 0x04)
567 *fe_status |= FE_HAS_VITERBI;
568 if (val & 0x08)
569 *fe_status |= FE_HAS_SYNC;
570 if (val & 0x10) {
571 *fe_status |= FE_HAS_LOCK;
572 if (!state->has_lock) {
573 state->has_lock = true;
574 /* modify parameters for stable reception */
575 tda10086_write_byte(state, 0x02, 0x00);
576 }
577 }
578
579 return 0;
580}
581
582static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
583{
584 struct tda10086_state* state = fe->demodulator_priv;
585 u8 _str;
586
587 dprintk ("%s\n", __func__);
588
589 _str = 0xff - tda10086_read_byte(state, 0x43);
590 *signal = (_str << 8) | _str;
591
592 return 0;
593}
594
595static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr)
596{
597 struct tda10086_state* state = fe->demodulator_priv;
598 u8 _snr;
599
600 dprintk ("%s\n", __func__);
601
602 _snr = 0xff - tda10086_read_byte(state, 0x1c);
603 *snr = (_snr << 8) | _snr;
604
605 return 0;
606}
607
608static int tda10086_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
609{
610 struct tda10086_state* state = fe->demodulator_priv;
611
612 dprintk ("%s\n", __func__);
613
614 /* read it */
615 *ucblocks = tda10086_read_byte(state, 0x18) & 0x7f;
616
617 /* reset counter */
618 tda10086_write_byte(state, 0x18, 0x00);
619 tda10086_write_byte(state, 0x18, 0x80);
620
621 return 0;
622}
623
624static int tda10086_read_ber(struct dvb_frontend* fe, u32* ber)
625{
626 struct tda10086_state* state = fe->demodulator_priv;
627
628 dprintk ("%s\n", __func__);
629
630 /* read it */
631 *ber = 0;
632 *ber |= tda10086_read_byte(state, 0x15);
633 *ber |= tda10086_read_byte(state, 0x16) << 8;
634 *ber |= (tda10086_read_byte(state, 0x17) & 0xf) << 16;
635
636 return 0;
637}
638
639static int tda10086_sleep(struct dvb_frontend* fe)
640{
641 struct tda10086_state* state = fe->demodulator_priv;
642
643 dprintk ("%s\n", __func__);
644
645 tda10086_write_mask(state, 0x00, 0x08, 0x08);
646
647 return 0;
648}
649
650static int tda10086_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
651{
652 struct tda10086_state* state = fe->demodulator_priv;
653
654 dprintk ("%s\n", __func__);
655
656 if (enable) {
657 tda10086_write_mask(state, 0x00, 0x10, 0x10);
658 } else {
659 tda10086_write_mask(state, 0x00, 0x10, 0x00);
660 }
661
662 return 0;
663}
664
665static int tda10086_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
666{
667 if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) {
668 fesettings->min_delay_ms = 50;
669 fesettings->step_size = 2000;
670 fesettings->max_drift = 8000;
671 } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) {
672 fesettings->min_delay_ms = 100;
673 fesettings->step_size = 1500;
674 fesettings->max_drift = 9000;
675 } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) {
676 fesettings->min_delay_ms = 100;
677 fesettings->step_size = 1000;
678 fesettings->max_drift = 8000;
679 } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) {
680 fesettings->min_delay_ms = 100;
681 fesettings->step_size = 500;
682 fesettings->max_drift = 7000;
683 } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) {
684 fesettings->min_delay_ms = 200;
685 fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
686 fesettings->max_drift = 14 * fesettings->step_size;
687 } else {
688 fesettings->min_delay_ms = 200;
689 fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
690 fesettings->max_drift = 18 * fesettings->step_size;
691 }
692
693 return 0;
694}
695
696static void tda10086_release(struct dvb_frontend* fe)
697{
698 struct tda10086_state *state = fe->demodulator_priv;
699 tda10086_sleep(fe);
700 kfree(state);
701}
702
703static struct dvb_frontend_ops tda10086_ops = {
704
705 .info = {
706 .name = "Philips TDA10086 DVB-S",
707 .type = FE_QPSK,
708 .frequency_min = 950000,
709 .frequency_max = 2150000,
710 .frequency_stepsize = 125, /* kHz for QPSK frontends */
711 .symbol_rate_min = 1000000,
712 .symbol_rate_max = 45000000,
713 .caps = FE_CAN_INVERSION_AUTO |
714 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
715 FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
716 FE_CAN_QPSK
717 },
718
719 .release = tda10086_release,
720
721 .init = tda10086_init,
722 .sleep = tda10086_sleep,
723 .i2c_gate_ctrl = tda10086_i2c_gate_ctrl,
724
725 .set_frontend = tda10086_set_frontend,
726 .get_frontend = tda10086_get_frontend,
727 .get_tune_settings = tda10086_get_tune_settings,
728
729 .read_status = tda10086_read_status,
730 .read_ber = tda10086_read_ber,
731 .read_signal_strength = tda10086_read_signal_strength,
732 .read_snr = tda10086_read_snr,
733 .read_ucblocks = tda10086_read_ucblocks,
734
735 .diseqc_send_master_cmd = tda10086_send_master_cmd,
736 .diseqc_send_burst = tda10086_send_burst,
737 .set_tone = tda10086_set_tone,
738};
739
740struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
741 struct i2c_adapter* i2c)
742{
743 struct tda10086_state *state;
744
745 dprintk ("%s\n", __func__);
746
747 /* allocate memory for the internal state */
748 state = kzalloc(sizeof(struct tda10086_state), GFP_KERNEL);
749 if (!state)
750 return NULL;
751
752 /* setup the state */
753 state->config = config;
754 state->i2c = i2c;
755
756 /* check if the demod is there */
757 if (tda10086_read_byte(state, 0x1e) != 0xe1) {
758 kfree(state);
759 return NULL;
760 }
761
762 /* create dvb_frontend */
763 memcpy(&state->frontend.ops, &tda10086_ops, sizeof(struct dvb_frontend_ops));
764 state->frontend.demodulator_priv = state;
765 return &state->frontend;
766}
767
768module_param(debug, int, 0644);
769MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
770
771MODULE_DESCRIPTION("Philips TDA10086 DVB-S Demodulator");
772MODULE_AUTHOR("Andrew de Quincey");
773MODULE_LICENSE("GPL");
774
775EXPORT_SYMBOL(tda10086_attach);
diff --git a/drivers/media/dvb/frontends/tda10086.h b/drivers/media/dvb/frontends/tda10086.h
new file mode 100644
index 00000000000..61148c558d8
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10086.h
@@ -0,0 +1,61 @@
1 /*
2 Driver for Philips tda10086 DVBS Frontend
3
4 (c) 2006 Andrew de Quincey
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23#ifndef TDA10086_H
24#define TDA10086_H
25
26#include <linux/dvb/frontend.h>
27#include <linux/firmware.h>
28
29enum tda10086_xtal {
30 TDA10086_XTAL_16M,
31 TDA10086_XTAL_4M
32};
33
34struct tda10086_config
35{
36 /* the demodulator's i2c address */
37 u8 demod_address;
38
39 /* does the "inversion" need inverted? */
40 u8 invert;
41
42 /* do we need the diseqc signal with carrier? */
43 u8 diseqc_tone;
44
45 /* frequency of the reference xtal */
46 enum tda10086_xtal xtal_freq;
47};
48
49#if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE))
50extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
51 struct i2c_adapter* i2c);
52#else
53static inline struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
54 struct i2c_adapter* i2c)
55{
56 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
57 return NULL;
58}
59#endif /* CONFIG_DVB_TDA10086 */
60
61#endif /* TDA10086_H */
diff --git a/drivers/media/dvb/frontends/tda18271c2dd.c b/drivers/media/dvb/frontends/tda18271c2dd.c
new file mode 100644
index 00000000000..0384e8da4f5
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda18271c2dd.c
@@ -0,0 +1,1251 @@
1/*
2 * tda18271c2dd: Driver for the TDA18271C2 tuner
3 *
4 * Copyright (C) 2010 Digital Devices GmbH
5 *
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
9 * version 2 only, as published by the Free Software Foundation.
10 *
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 *
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., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA
22 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
23 */
24
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/init.h>
29#include <linux/delay.h>
30#include <linux/firmware.h>
31#include <linux/i2c.h>
32#include <linux/version.h>
33#include <asm/div64.h>
34
35#include "dvb_frontend.h"
36
37struct SStandardParam {
38 s32 m_IFFrequency;
39 u32 m_BandWidth;
40 u8 m_EP3_4_0;
41 u8 m_EB22;
42};
43
44struct SMap {
45 u32 m_Frequency;
46 u8 m_Param;
47};
48
49struct SMapI {
50 u32 m_Frequency;
51 s32 m_Param;
52};
53
54struct SMap2 {
55 u32 m_Frequency;
56 u8 m_Param1;
57 u8 m_Param2;
58};
59
60struct SRFBandMap {
61 u32 m_RF_max;
62 u32 m_RF1_Default;
63 u32 m_RF2_Default;
64 u32 m_RF3_Default;
65};
66
67enum ERegister {
68 ID = 0,
69 TM,
70 PL,
71 EP1, EP2, EP3, EP4, EP5,
72 CPD, CD1, CD2, CD3,
73 MPD, MD1, MD2, MD3,
74 EB1, EB2, EB3, EB4, EB5, EB6, EB7, EB8, EB9, EB10,
75 EB11, EB12, EB13, EB14, EB15, EB16, EB17, EB18, EB19, EB20,
76 EB21, EB22, EB23,
77 NUM_REGS
78};
79
80struct tda_state {
81 struct i2c_adapter *i2c;
82 u8 adr;
83
84 u32 m_Frequency;
85 u32 IF;
86
87 u8 m_IFLevelAnalog;
88 u8 m_IFLevelDigital;
89 u8 m_IFLevelDVBC;
90 u8 m_IFLevelDVBT;
91
92 u8 m_EP4;
93 u8 m_EP3_Standby;
94
95 bool m_bMaster;
96
97 s32 m_SettlingTime;
98
99 u8 m_Regs[NUM_REGS];
100
101 /* Tracking filter settings for band 0..6 */
102 u32 m_RF1[7];
103 s32 m_RF_A1[7];
104 s32 m_RF_B1[7];
105 u32 m_RF2[7];
106 s32 m_RF_A2[7];
107 s32 m_RF_B2[7];
108 u32 m_RF3[7];
109
110 u8 m_TMValue_RFCal; /* Calibration temperatur */
111
112 bool m_bFMInput; /* true to use Pin 8 for FM Radio */
113
114};
115
116static int PowerScan(struct tda_state *state,
117 u8 RFBand, u32 RF_in,
118 u32 *pRF_Out, bool *pbcal);
119
120static int i2c_readn(struct i2c_adapter *adapter, u8 adr, u8 *data, int len)
121{
122 struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD,
123 .buf = data, .len = len} };
124 return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
125}
126
127static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
128{
129 struct i2c_msg msg = {.addr = adr, .flags = 0,
130 .buf = data, .len = len};
131
132 if (i2c_transfer(adap, &msg, 1) != 1) {
133 printk(KERN_ERR "tda18271c2dd: i2c write error at addr %i\n", adr);
134 return -1;
135 }
136 return 0;
137}
138
139static int WriteRegs(struct tda_state *state,
140 u8 SubAddr, u8 *Regs, u16 nRegs)
141{
142 u8 data[nRegs+1];
143
144 data[0] = SubAddr;
145 memcpy(data + 1, Regs, nRegs);
146 return i2c_write(state->i2c, state->adr, data, nRegs+1);
147}
148
149static int WriteReg(struct tda_state *state, u8 SubAddr, u8 Reg)
150{
151 u8 msg[2] = {SubAddr, Reg};
152
153 return i2c_write(state->i2c, state->adr, msg, 2);
154}
155
156static int Read(struct tda_state *state, u8 * Regs)
157{
158 return i2c_readn(state->i2c, state->adr, Regs, 16);
159}
160
161static int ReadExtented(struct tda_state *state, u8 * Regs)
162{
163 return i2c_readn(state->i2c, state->adr, Regs, NUM_REGS);
164}
165
166static int UpdateRegs(struct tda_state *state, u8 RegFrom, u8 RegTo)
167{
168 return WriteRegs(state, RegFrom,
169 &state->m_Regs[RegFrom], RegTo-RegFrom+1);
170}
171static int UpdateReg(struct tda_state *state, u8 Reg)
172{
173 return WriteReg(state, Reg, state->m_Regs[Reg]);
174}
175
176#include "tda18271c2dd_maps.h"
177
178static void reset(struct tda_state *state)
179{
180 u32 ulIFLevelAnalog = 0;
181 u32 ulIFLevelDigital = 2;
182 u32 ulIFLevelDVBC = 7;
183 u32 ulIFLevelDVBT = 6;
184 u32 ulXTOut = 0;
185 u32 ulStandbyMode = 0x06; /* Send in stdb, but leave osc on */
186 u32 ulSlave = 0;
187 u32 ulFMInput = 0;
188 u32 ulSettlingTime = 100;
189
190 state->m_Frequency = 0;
191 state->m_SettlingTime = 100;
192 state->m_IFLevelAnalog = (ulIFLevelAnalog & 0x07) << 2;
193 state->m_IFLevelDigital = (ulIFLevelDigital & 0x07) << 2;
194 state->m_IFLevelDVBC = (ulIFLevelDVBC & 0x07) << 2;
195 state->m_IFLevelDVBT = (ulIFLevelDVBT & 0x07) << 2;
196
197 state->m_EP4 = 0x20;
198 if (ulXTOut != 0)
199 state->m_EP4 |= 0x40;
200
201 state->m_EP3_Standby = ((ulStandbyMode & 0x07) << 5) | 0x0F;
202 state->m_bMaster = (ulSlave == 0);
203
204 state->m_SettlingTime = ulSettlingTime;
205
206 state->m_bFMInput = (ulFMInput == 2);
207}
208
209static bool SearchMap1(struct SMap Map[],
210 u32 Frequency, u8 *pParam)
211{
212 int i = 0;
213
214 while ((Map[i].m_Frequency != 0) && (Frequency > Map[i].m_Frequency))
215 i += 1;
216 if (Map[i].m_Frequency == 0)
217 return false;
218 *pParam = Map[i].m_Param;
219 return true;
220}
221
222static bool SearchMap2(struct SMapI Map[],
223 u32 Frequency, s32 *pParam)
224{
225 int i = 0;
226
227 while ((Map[i].m_Frequency != 0) &&
228 (Frequency > Map[i].m_Frequency))
229 i += 1;
230 if (Map[i].m_Frequency == 0)
231 return false;
232 *pParam = Map[i].m_Param;
233 return true;
234}
235
236static bool SearchMap3(struct SMap2 Map[], u32 Frequency,
237 u8 *pParam1, u8 *pParam2)
238{
239 int i = 0;
240
241 while ((Map[i].m_Frequency != 0) &&
242 (Frequency > Map[i].m_Frequency))
243 i += 1;
244 if (Map[i].m_Frequency == 0)
245 return false;
246 *pParam1 = Map[i].m_Param1;
247 *pParam2 = Map[i].m_Param2;
248 return true;
249}
250
251static bool SearchMap4(struct SRFBandMap Map[],
252 u32 Frequency, u8 *pRFBand)
253{
254 int i = 0;
255
256 while (i < 7 && (Frequency > Map[i].m_RF_max))
257 i += 1;
258 if (i == 7)
259 return false;
260 *pRFBand = i;
261 return true;
262}
263
264static int ThermometerRead(struct tda_state *state, u8 *pTM_Value)
265{
266 int status = 0;
267
268 do {
269 u8 Regs[16];
270 state->m_Regs[TM] |= 0x10;
271 status = UpdateReg(state, TM);
272 if (status < 0)
273 break;
274 status = Read(state, Regs);
275 if (status < 0)
276 break;
277 if (((Regs[TM] & 0x0F) == 0 && (Regs[TM] & 0x20) == 0x20) ||
278 ((Regs[TM] & 0x0F) == 8 && (Regs[TM] & 0x20) == 0x00)) {
279 state->m_Regs[TM] ^= 0x20;
280 status = UpdateReg(state, TM);
281 if (status < 0)
282 break;
283 msleep(10);
284 status = Read(state, Regs);
285 if (status < 0)
286 break;
287 }
288 *pTM_Value = (Regs[TM] & 0x20)
289 ? m_Thermometer_Map_2[Regs[TM] & 0x0F]
290 : m_Thermometer_Map_1[Regs[TM] & 0x0F] ;
291 state->m_Regs[TM] &= ~0x10; /* Thermometer off */
292 status = UpdateReg(state, TM);
293 if (status < 0)
294 break;
295 state->m_Regs[EP4] &= ~0x03; /* CAL_mode = 0 ????????? */
296 status = UpdateReg(state, EP4);
297 if (status < 0)
298 break;
299 } while (0);
300
301 return status;
302}
303
304static int StandBy(struct tda_state *state)
305{
306 int status = 0;
307 do {
308 state->m_Regs[EB12] &= ~0x20; /* PD_AGC1_Det = 0 */
309 status = UpdateReg(state, EB12);
310 if (status < 0)
311 break;
312 state->m_Regs[EB18] &= ~0x83; /* AGC1_loop_off = 0, AGC1_Gain = 6 dB */
313 status = UpdateReg(state, EB18);
314 if (status < 0)
315 break;
316 state->m_Regs[EB21] |= 0x03; /* AGC2_Gain = -6 dB */
317 state->m_Regs[EP3] = state->m_EP3_Standby;
318 status = UpdateReg(state, EP3);
319 if (status < 0)
320 break;
321 state->m_Regs[EB23] &= ~0x06; /* ForceLP_Fc2_En = 0, LP_Fc[2] = 0 */
322 status = UpdateRegs(state, EB21, EB23);
323 if (status < 0)
324 break;
325 } while (0);
326 return status;
327}
328
329static int CalcMainPLL(struct tda_state *state, u32 freq)
330{
331
332 u8 PostDiv;
333 u8 Div;
334 u64 OscFreq;
335 u32 MainDiv;
336
337 if (!SearchMap3(m_Main_PLL_Map, freq, &PostDiv, &Div))
338 return -EINVAL;
339
340 OscFreq = (u64) freq * (u64) Div;
341 OscFreq *= (u64) 16384;
342 do_div(OscFreq, (u64)16000000);
343 MainDiv = OscFreq;
344
345 state->m_Regs[MPD] = PostDiv & 0x77;
346 state->m_Regs[MD1] = ((MainDiv >> 16) & 0x7F);
347 state->m_Regs[MD2] = ((MainDiv >> 8) & 0xFF);
348 state->m_Regs[MD3] = (MainDiv & 0xFF);
349
350 return UpdateRegs(state, MPD, MD3);
351}
352
353static int CalcCalPLL(struct tda_state *state, u32 freq)
354{
355 u8 PostDiv;
356 u8 Div;
357 u64 OscFreq;
358 u32 CalDiv;
359
360 if (!SearchMap3(m_Cal_PLL_Map, freq, &PostDiv, &Div))
361 return -EINVAL;
362
363 OscFreq = (u64)freq * (u64)Div;
364 /* CalDiv = u32( OscFreq * 16384 / 16000000 ); */
365 OscFreq *= (u64)16384;
366 do_div(OscFreq, (u64)16000000);
367 CalDiv = OscFreq;
368
369 state->m_Regs[CPD] = PostDiv;
370 state->m_Regs[CD1] = ((CalDiv >> 16) & 0xFF);
371 state->m_Regs[CD2] = ((CalDiv >> 8) & 0xFF);
372 state->m_Regs[CD3] = (CalDiv & 0xFF);
373
374 return UpdateRegs(state, CPD, CD3);
375}
376
377static int CalibrateRF(struct tda_state *state,
378 u8 RFBand, u32 freq, s32 *pCprog)
379{
380 int status = 0;
381 u8 Regs[NUM_REGS];
382 do {
383 u8 BP_Filter = 0;
384 u8 GainTaper = 0;
385 u8 RFC_K = 0;
386 u8 RFC_M = 0;
387
388 state->m_Regs[EP4] &= ~0x03; /* CAL_mode = 0 */
389 status = UpdateReg(state, EP4);
390 if (status < 0)
391 break;
392 state->m_Regs[EB18] |= 0x03; /* AGC1_Gain = 3 */
393 status = UpdateReg(state, EB18);
394 if (status < 0)
395 break;
396
397 /* Switching off LT (as datasheet says) causes calibration on C1 to fail */
398 /* (Readout of Cprog is allways 255) */
399 if (state->m_Regs[ID] != 0x83) /* C1: ID == 83, C2: ID == 84 */
400 state->m_Regs[EP3] |= 0x40; /* SM_LT = 1 */
401
402 if (!(SearchMap1(m_BP_Filter_Map, freq, &BP_Filter) &&
403 SearchMap1(m_GainTaper_Map, freq, &GainTaper) &&
404 SearchMap3(m_KM_Map, freq, &RFC_K, &RFC_M)))
405 return -EINVAL;
406
407 state->m_Regs[EP1] = (state->m_Regs[EP1] & ~0x07) | BP_Filter;
408 state->m_Regs[EP2] = (RFBand << 5) | GainTaper;
409
410 state->m_Regs[EB13] = (state->m_Regs[EB13] & ~0x7C) | (RFC_K << 4) | (RFC_M << 2);
411
412 status = UpdateRegs(state, EP1, EP3);
413 if (status < 0)
414 break;
415 status = UpdateReg(state, EB13);
416 if (status < 0)
417 break;
418
419 state->m_Regs[EB4] |= 0x20; /* LO_ForceSrce = 1 */
420 status = UpdateReg(state, EB4);
421 if (status < 0)
422 break;
423
424 state->m_Regs[EB7] |= 0x20; /* CAL_ForceSrce = 1 */
425 status = UpdateReg(state, EB7);
426 if (status < 0)
427 break;
428
429 state->m_Regs[EB14] = 0; /* RFC_Cprog = 0 */
430 status = UpdateReg(state, EB14);
431 if (status < 0)
432 break;
433
434 state->m_Regs[EB20] &= ~0x20; /* ForceLock = 0; */
435 status = UpdateReg(state, EB20);
436 if (status < 0)
437 break;
438
439 state->m_Regs[EP4] |= 0x03; /* CAL_Mode = 3 */
440 status = UpdateRegs(state, EP4, EP5);
441 if (status < 0)
442 break;
443
444 status = CalcCalPLL(state, freq);
445 if (status < 0)
446 break;
447 status = CalcMainPLL(state, freq + 1000000);
448 if (status < 0)
449 break;
450
451 msleep(5);
452 status = UpdateReg(state, EP2);
453 if (status < 0)
454 break;
455 status = UpdateReg(state, EP1);
456 if (status < 0)
457 break;
458 status = UpdateReg(state, EP2);
459 if (status < 0)
460 break;
461 status = UpdateReg(state, EP1);
462 if (status < 0)
463 break;
464
465 state->m_Regs[EB4] &= ~0x20; /* LO_ForceSrce = 0 */
466 status = UpdateReg(state, EB4);
467 if (status < 0)
468 break;
469
470 state->m_Regs[EB7] &= ~0x20; /* CAL_ForceSrce = 0 */
471 status = UpdateReg(state, EB7);
472 if (status < 0)
473 break;
474 msleep(10);
475
476 state->m_Regs[EB20] |= 0x20; /* ForceLock = 1; */
477 status = UpdateReg(state, EB20);
478 if (status < 0)
479 break;
480 msleep(60);
481
482 state->m_Regs[EP4] &= ~0x03; /* CAL_Mode = 0 */
483 state->m_Regs[EP3] &= ~0x40; /* SM_LT = 0 */
484 state->m_Regs[EB18] &= ~0x03; /* AGC1_Gain = 0 */
485 status = UpdateReg(state, EB18);
486 if (status < 0)
487 break;
488 status = UpdateRegs(state, EP3, EP4);
489 if (status < 0)
490 break;
491 status = UpdateReg(state, EP1);
492 if (status < 0)
493 break;
494
495 status = ReadExtented(state, Regs);
496 if (status < 0)
497 break;
498
499 *pCprog = Regs[EB14];
500
501 } while (0);
502 return status;
503}
504
505static int RFTrackingFiltersInit(struct tda_state *state,
506 u8 RFBand)
507{
508 int status = 0;
509
510 u32 RF1 = m_RF_Band_Map[RFBand].m_RF1_Default;
511 u32 RF2 = m_RF_Band_Map[RFBand].m_RF2_Default;
512 u32 RF3 = m_RF_Band_Map[RFBand].m_RF3_Default;
513 bool bcal = false;
514
515 s32 Cprog_cal1 = 0;
516 s32 Cprog_table1 = 0;
517 s32 Cprog_cal2 = 0;
518 s32 Cprog_table2 = 0;
519 s32 Cprog_cal3 = 0;
520 s32 Cprog_table3 = 0;
521
522 state->m_RF_A1[RFBand] = 0;
523 state->m_RF_B1[RFBand] = 0;
524 state->m_RF_A2[RFBand] = 0;
525 state->m_RF_B2[RFBand] = 0;
526
527 do {
528 status = PowerScan(state, RFBand, RF1, &RF1, &bcal);
529 if (status < 0)
530 break;
531 if (bcal) {
532 status = CalibrateRF(state, RFBand, RF1, &Cprog_cal1);
533 if (status < 0)
534 break;
535 }
536 SearchMap2(m_RF_Cal_Map, RF1, &Cprog_table1);
537 if (!bcal)
538 Cprog_cal1 = Cprog_table1;
539 state->m_RF_B1[RFBand] = Cprog_cal1 - Cprog_table1;
540 /* state->m_RF_A1[RF_Band] = ???? */
541
542 if (RF2 == 0)
543 break;
544
545 status = PowerScan(state, RFBand, RF2, &RF2, &bcal);
546 if (status < 0)
547 break;
548 if (bcal) {
549 status = CalibrateRF(state, RFBand, RF2, &Cprog_cal2);
550 if (status < 0)
551 break;
552 }
553 SearchMap2(m_RF_Cal_Map, RF2, &Cprog_table2);
554 if (!bcal)
555 Cprog_cal2 = Cprog_table2;
556
557 state->m_RF_A1[RFBand] =
558 (Cprog_cal2 - Cprog_table2 - Cprog_cal1 + Cprog_table1) /
559 ((s32)(RF2) - (s32)(RF1));
560
561 if (RF3 == 0)
562 break;
563
564 status = PowerScan(state, RFBand, RF3, &RF3, &bcal);
565 if (status < 0)
566 break;
567 if (bcal) {
568 status = CalibrateRF(state, RFBand, RF3, &Cprog_cal3);
569 if (status < 0)
570 break;
571 }
572 SearchMap2(m_RF_Cal_Map, RF3, &Cprog_table3);
573 if (!bcal)
574 Cprog_cal3 = Cprog_table3;
575 state->m_RF_A2[RFBand] = (Cprog_cal3 - Cprog_table3 - Cprog_cal2 + Cprog_table2) / ((s32)(RF3) - (s32)(RF2));
576 state->m_RF_B2[RFBand] = Cprog_cal2 - Cprog_table2;
577
578 } while (0);
579
580 state->m_RF1[RFBand] = RF1;
581 state->m_RF2[RFBand] = RF2;
582 state->m_RF3[RFBand] = RF3;
583
584#if 0
585 printk(KERN_ERR "tda18271c2dd: %s %d RF1 = %d A1 = %d B1 = %d RF2 = %d A2 = %d B2 = %d RF3 = %d\n", __func__,
586 RFBand, RF1, state->m_RF_A1[RFBand], state->m_RF_B1[RFBand], RF2,
587 state->m_RF_A2[RFBand], state->m_RF_B2[RFBand], RF3);
588#endif
589
590 return status;
591}
592
593static int PowerScan(struct tda_state *state,
594 u8 RFBand, u32 RF_in, u32 *pRF_Out, bool *pbcal)
595{
596 int status = 0;
597 do {
598 u8 Gain_Taper = 0;
599 s32 RFC_Cprog = 0;
600 u8 CID_Target = 0;
601 u8 CountLimit = 0;
602 u32 freq_MainPLL;
603 u8 Regs[NUM_REGS];
604 u8 CID_Gain;
605 s32 Count = 0;
606 int sign = 1;
607 bool wait = false;
608
609 if (!(SearchMap2(m_RF_Cal_Map, RF_in, &RFC_Cprog) &&
610 SearchMap1(m_GainTaper_Map, RF_in, &Gain_Taper) &&
611 SearchMap3(m_CID_Target_Map, RF_in, &CID_Target, &CountLimit))) {
612
613 printk(KERN_ERR "tda18271c2dd: %s Search map failed\n", __func__);
614 return -EINVAL;
615 }
616
617 state->m_Regs[EP2] = (RFBand << 5) | Gain_Taper;
618 state->m_Regs[EB14] = (RFC_Cprog);
619 status = UpdateReg(state, EP2);
620 if (status < 0)
621 break;
622 status = UpdateReg(state, EB14);
623 if (status < 0)
624 break;
625
626 freq_MainPLL = RF_in + 1000000;
627 status = CalcMainPLL(state, freq_MainPLL);
628 if (status < 0)
629 break;
630 msleep(5);
631 state->m_Regs[EP4] = (state->m_Regs[EP4] & ~0x03) | 1; /* CAL_mode = 1 */
632 status = UpdateReg(state, EP4);
633 if (status < 0)
634 break;
635 status = UpdateReg(state, EP2); /* Launch power measurement */
636 if (status < 0)
637 break;
638 status = ReadExtented(state, Regs);
639 if (status < 0)
640 break;
641 CID_Gain = Regs[EB10] & 0x3F;
642 state->m_Regs[ID] = Regs[ID]; /* Chip version, (needed for C1 workarround in CalibrateRF) */
643
644 *pRF_Out = RF_in;
645
646 while (CID_Gain < CID_Target) {
647 freq_MainPLL = RF_in + sign * Count + 1000000;
648 status = CalcMainPLL(state, freq_MainPLL);
649 if (status < 0)
650 break;
651 msleep(wait ? 5 : 1);
652 wait = false;
653 status = UpdateReg(state, EP2); /* Launch power measurement */
654 if (status < 0)
655 break;
656 status = ReadExtented(state, Regs);
657 if (status < 0)
658 break;
659 CID_Gain = Regs[EB10] & 0x3F;
660 Count += 200000;
661
662 if (Count < CountLimit * 100000)
663 continue;
664 if (sign < 0)
665 break;
666
667 sign = -sign;
668 Count = 200000;
669 wait = true;
670 }
671 status = status;
672 if (status < 0)
673 break;
674 if (CID_Gain >= CID_Target) {
675 *pbcal = true;
676 *pRF_Out = freq_MainPLL - 1000000;
677 } else
678 *pbcal = false;
679 } while (0);
680
681 return status;
682}
683
684static int PowerScanInit(struct tda_state *state)
685{
686 int status = 0;
687 do {
688 state->m_Regs[EP3] = (state->m_Regs[EP3] & ~0x1F) | 0x12;
689 state->m_Regs[EP4] = (state->m_Regs[EP4] & ~0x1F); /* If level = 0, Cal mode = 0 */
690 status = UpdateRegs(state, EP3, EP4);
691 if (status < 0)
692 break;
693 state->m_Regs[EB18] = (state->m_Regs[EB18] & ~0x03); /* AGC 1 Gain = 0 */
694 status = UpdateReg(state, EB18);
695 if (status < 0)
696 break;
697 state->m_Regs[EB21] = (state->m_Regs[EB21] & ~0x03); /* AGC 2 Gain = 0 (Datasheet = 3) */
698 state->m_Regs[EB23] = (state->m_Regs[EB23] | 0x06); /* ForceLP_Fc2_En = 1, LPFc[2] = 1 */
699 status = UpdateRegs(state, EB21, EB23);
700 if (status < 0)
701 break;
702 } while (0);
703 return status;
704}
705
706static int CalcRFFilterCurve(struct tda_state *state)
707{
708 int status = 0;
709 do {
710 msleep(200); /* Temperature stabilisation */
711 status = PowerScanInit(state);
712 if (status < 0)
713 break;
714 status = RFTrackingFiltersInit(state, 0);
715 if (status < 0)
716 break;
717 status = RFTrackingFiltersInit(state, 1);
718 if (status < 0)
719 break;
720 status = RFTrackingFiltersInit(state, 2);
721 if (status < 0)
722 break;
723 status = RFTrackingFiltersInit(state, 3);
724 if (status < 0)
725 break;
726 status = RFTrackingFiltersInit(state, 4);
727 if (status < 0)
728 break;
729 status = RFTrackingFiltersInit(state, 5);
730 if (status < 0)
731 break;
732 status = RFTrackingFiltersInit(state, 6);
733 if (status < 0)
734 break;
735 status = ThermometerRead(state, &state->m_TMValue_RFCal); /* also switches off Cal mode !!! */
736 if (status < 0)
737 break;
738 } while (0);
739
740 return status;
741}
742
743static int FixedContentsI2CUpdate(struct tda_state *state)
744{
745 static u8 InitRegs[] = {
746 0x08, 0x80, 0xC6,
747 0xDF, 0x16, 0x60, 0x80,
748 0x80, 0x00, 0x00, 0x00,
749 0x00, 0x00, 0x00, 0x00,
750 0xFC, 0x01, 0x84, 0x41,
751 0x01, 0x84, 0x40, 0x07,
752 0x00, 0x00, 0x96, 0x3F,
753 0xC1, 0x00, 0x8F, 0x00,
754 0x00, 0x8C, 0x00, 0x20,
755 0xB3, 0x48, 0xB0,
756 };
757 int status = 0;
758 memcpy(&state->m_Regs[TM], InitRegs, EB23 - TM + 1);
759 do {
760 status = UpdateRegs(state, TM, EB23);
761 if (status < 0)
762 break;
763
764 /* AGC1 gain setup */
765 state->m_Regs[EB17] = 0x00;
766 status = UpdateReg(state, EB17);
767 if (status < 0)
768 break;
769 state->m_Regs[EB17] = 0x03;
770 status = UpdateReg(state, EB17);
771 if (status < 0)
772 break;
773 state->m_Regs[EB17] = 0x43;
774 status = UpdateReg(state, EB17);
775 if (status < 0)
776 break;
777 state->m_Regs[EB17] = 0x4C;
778 status = UpdateReg(state, EB17);
779 if (status < 0)
780 break;
781
782 /* IRC Cal Low band */
783 state->m_Regs[EP3] = 0x1F;
784 state->m_Regs[EP4] = 0x66;
785 state->m_Regs[EP5] = 0x81;
786 state->m_Regs[CPD] = 0xCC;
787 state->m_Regs[CD1] = 0x6C;
788 state->m_Regs[CD2] = 0x00;
789 state->m_Regs[CD3] = 0x00;
790 state->m_Regs[MPD] = 0xC5;
791 state->m_Regs[MD1] = 0x77;
792 state->m_Regs[MD2] = 0x08;
793 state->m_Regs[MD3] = 0x00;
794 status = UpdateRegs(state, EP2, MD3); /* diff between sw and datasheet (ep3-md3) */
795 if (status < 0)
796 break;
797
798#if 0
799 state->m_Regs[EB4] = 0x61; /* missing in sw */
800 status = UpdateReg(state, EB4);
801 if (status < 0)
802 break;
803 msleep(1);
804 state->m_Regs[EB4] = 0x41;
805 status = UpdateReg(state, EB4);
806 if (status < 0)
807 break;
808#endif
809
810 msleep(5);
811 status = UpdateReg(state, EP1);
812 if (status < 0)
813 break;
814 msleep(5);
815
816 state->m_Regs[EP5] = 0x85;
817 state->m_Regs[CPD] = 0xCB;
818 state->m_Regs[CD1] = 0x66;
819 state->m_Regs[CD2] = 0x70;
820 status = UpdateRegs(state, EP3, CD3);
821 if (status < 0)
822 break;
823 msleep(5);
824 status = UpdateReg(state, EP2);
825 if (status < 0)
826 break;
827 msleep(30);
828
829 /* IRC Cal mid band */
830 state->m_Regs[EP5] = 0x82;
831 state->m_Regs[CPD] = 0xA8;
832 state->m_Regs[CD2] = 0x00;
833 state->m_Regs[MPD] = 0xA1; /* Datasheet = 0xA9 */
834 state->m_Regs[MD1] = 0x73;
835 state->m_Regs[MD2] = 0x1A;
836 status = UpdateRegs(state, EP3, MD3);
837 if (status < 0)
838 break;
839
840 msleep(5);
841 status = UpdateReg(state, EP1);
842 if (status < 0)
843 break;
844 msleep(5);
845
846 state->m_Regs[EP5] = 0x86;
847 state->m_Regs[CPD] = 0xA8;
848 state->m_Regs[CD1] = 0x66;
849 state->m_Regs[CD2] = 0xA0;
850 status = UpdateRegs(state, EP3, CD3);
851 if (status < 0)
852 break;
853 msleep(5);
854 status = UpdateReg(state, EP2);
855 if (status < 0)
856 break;
857 msleep(30);
858
859 /* IRC Cal high band */
860 state->m_Regs[EP5] = 0x83;
861 state->m_Regs[CPD] = 0x98;
862 state->m_Regs[CD1] = 0x65;
863 state->m_Regs[CD2] = 0x00;
864 state->m_Regs[MPD] = 0x91; /* Datasheet = 0x91 */
865 state->m_Regs[MD1] = 0x71;
866 state->m_Regs[MD2] = 0xCD;
867 status = UpdateRegs(state, EP3, MD3);
868 if (status < 0)
869 break;
870 msleep(5);
871 status = UpdateReg(state, EP1);
872 if (status < 0)
873 break;
874 msleep(5);
875 state->m_Regs[EP5] = 0x87;
876 state->m_Regs[CD1] = 0x65;
877 state->m_Regs[CD2] = 0x50;
878 status = UpdateRegs(state, EP3, CD3);
879 if (status < 0)
880 break;
881 msleep(5);
882 status = UpdateReg(state, EP2);
883 if (status < 0)
884 break;
885 msleep(30);
886
887 /* Back to normal */
888 state->m_Regs[EP4] = 0x64;
889 status = UpdateReg(state, EP4);
890 if (status < 0)
891 break;
892 status = UpdateReg(state, EP1);
893 if (status < 0)
894 break;
895
896 } while (0);
897 return status;
898}
899
900static int InitCal(struct tda_state *state)
901{
902 int status = 0;
903
904 do {
905 status = FixedContentsI2CUpdate(state);
906 if (status < 0)
907 break;
908 status = CalcRFFilterCurve(state);
909 if (status < 0)
910 break;
911 status = StandBy(state);
912 if (status < 0)
913 break;
914 /* m_bInitDone = true; */
915 } while (0);
916 return status;
917};
918
919static int RFTrackingFiltersCorrection(struct tda_state *state,
920 u32 Frequency)
921{
922 int status = 0;
923 s32 Cprog_table;
924 u8 RFBand;
925 u8 dCoverdT;
926
927 if (!SearchMap2(m_RF_Cal_Map, Frequency, &Cprog_table) ||
928 !SearchMap4(m_RF_Band_Map, Frequency, &RFBand) ||
929 !SearchMap1(m_RF_Cal_DC_Over_DT_Map, Frequency, &dCoverdT))
930
931 return -EINVAL;
932
933 do {
934 u8 TMValue_Current;
935 u32 RF1 = state->m_RF1[RFBand];
936 u32 RF2 = state->m_RF1[RFBand];
937 u32 RF3 = state->m_RF1[RFBand];
938 s32 RF_A1 = state->m_RF_A1[RFBand];
939 s32 RF_B1 = state->m_RF_B1[RFBand];
940 s32 RF_A2 = state->m_RF_A2[RFBand];
941 s32 RF_B2 = state->m_RF_B2[RFBand];
942 s32 Capprox = 0;
943 int TComp;
944
945 state->m_Regs[EP3] &= ~0xE0; /* Power up */
946 status = UpdateReg(state, EP3);
947 if (status < 0)
948 break;
949
950 status = ThermometerRead(state, &TMValue_Current);
951 if (status < 0)
952 break;
953
954 if (RF3 == 0 || Frequency < RF2)
955 Capprox = RF_A1 * ((s32)(Frequency) - (s32)(RF1)) + RF_B1 + Cprog_table;
956 else
957 Capprox = RF_A2 * ((s32)(Frequency) - (s32)(RF2)) + RF_B2 + Cprog_table;
958
959 TComp = (int)(dCoverdT) * ((int)(TMValue_Current) - (int)(state->m_TMValue_RFCal))/1000;
960
961 Capprox += TComp;
962
963 if (Capprox < 0)
964 Capprox = 0;
965 else if (Capprox > 255)
966 Capprox = 255;
967
968
969 /* TODO Temperature compensation. There is defenitely a scale factor */
970 /* missing in the datasheet, so leave it out for now. */
971 state->m_Regs[EB14] = Capprox;
972
973 status = UpdateReg(state, EB14);
974 if (status < 0)
975 break;
976
977 } while (0);
978 return status;
979}
980
981static int ChannelConfiguration(struct tda_state *state,
982 u32 Frequency, int Standard)
983{
984
985 s32 IntermediateFrequency = m_StandardTable[Standard].m_IFFrequency;
986 int status = 0;
987
988 u8 BP_Filter = 0;
989 u8 RF_Band = 0;
990 u8 GainTaper = 0;
991 u8 IR_Meas = 0;
992
993 state->IF = IntermediateFrequency;
994 /* printk("tda18271c2dd: %s Freq = %d Standard = %d IF = %d\n", __func__, Frequency, Standard, IntermediateFrequency); */
995 /* get values from tables */
996
997 if (!(SearchMap1(m_BP_Filter_Map, Frequency, &BP_Filter) &&
998 SearchMap1(m_GainTaper_Map, Frequency, &GainTaper) &&
999 SearchMap1(m_IR_Meas_Map, Frequency, &IR_Meas) &&
1000 SearchMap4(m_RF_Band_Map, Frequency, &RF_Band))) {
1001
1002 printk(KERN_ERR "tda18271c2dd: %s SearchMap failed\n", __func__);
1003 return -EINVAL;
1004 }
1005
1006 do {
1007 state->m_Regs[EP3] = (state->m_Regs[EP3] & ~0x1F) | m_StandardTable[Standard].m_EP3_4_0;
1008 state->m_Regs[EP3] &= ~0x04; /* switch RFAGC to high speed mode */
1009
1010 /* m_EP4 default for XToutOn, CAL_Mode (0) */
1011 state->m_Regs[EP4] = state->m_EP4 | ((Standard > HF_AnalogMax) ? state->m_IFLevelDigital : state->m_IFLevelAnalog);
1012 /* state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital; */
1013 if (Standard <= HF_AnalogMax)
1014 state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelAnalog;
1015 else if (Standard <= HF_ATSC)
1016 state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDVBT;
1017 else if (Standard <= HF_DVBC)
1018 state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDVBC;
1019 else
1020 state->m_Regs[EP4] = state->m_EP4 | state->m_IFLevelDigital;
1021
1022 if ((Standard == HF_FM_Radio) && state->m_bFMInput)
1023 state->m_Regs[EP4] |= 80;
1024
1025 state->m_Regs[MPD] &= ~0x80;
1026 if (Standard > HF_AnalogMax)
1027 state->m_Regs[MPD] |= 0x80; /* Add IF_notch for digital */
1028
1029 state->m_Regs[EB22] = m_StandardTable[Standard].m_EB22;
1030
1031 /* Note: This is missing from flowchart in TDA18271 specification ( 1.5 MHz cutoff for FM ) */
1032 if (Standard == HF_FM_Radio)
1033 state->m_Regs[EB23] |= 0x06; /* ForceLP_Fc2_En = 1, LPFc[2] = 1 */
1034 else
1035 state->m_Regs[EB23] &= ~0x06; /* ForceLP_Fc2_En = 0, LPFc[2] = 0 */
1036
1037 status = UpdateRegs(state, EB22, EB23);
1038 if (status < 0)
1039 break;
1040
1041 state->m_Regs[EP1] = (state->m_Regs[EP1] & ~0x07) | 0x40 | BP_Filter; /* Dis_Power_level = 1, Filter */
1042 state->m_Regs[EP5] = (state->m_Regs[EP5] & ~0x07) | IR_Meas;
1043 state->m_Regs[EP2] = (RF_Band << 5) | GainTaper;
1044
1045 state->m_Regs[EB1] = (state->m_Regs[EB1] & ~0x07) |
1046 (state->m_bMaster ? 0x04 : 0x00); /* CALVCO_FortLOn = MS */
1047 /* AGC1_always_master = 0 */
1048 /* AGC_firstn = 0 */
1049 status = UpdateReg(state, EB1);
1050 if (status < 0)
1051 break;
1052
1053 if (state->m_bMaster) {
1054 status = CalcMainPLL(state, Frequency + IntermediateFrequency);
1055 if (status < 0)
1056 break;
1057 status = UpdateRegs(state, TM, EP5);
1058 if (status < 0)
1059 break;
1060 state->m_Regs[EB4] |= 0x20; /* LO_forceSrce = 1 */
1061 status = UpdateReg(state, EB4);
1062 if (status < 0)
1063 break;
1064 msleep(1);
1065 state->m_Regs[EB4] &= ~0x20; /* LO_forceSrce = 0 */
1066 status = UpdateReg(state, EB4);
1067 if (status < 0)
1068 break;
1069 } else {
1070 u8 PostDiv = 0;
1071 u8 Div;
1072 status = CalcCalPLL(state, Frequency + IntermediateFrequency);
1073 if (status < 0)
1074 break;
1075
1076 SearchMap3(m_Cal_PLL_Map, Frequency + IntermediateFrequency, &PostDiv, &Div);
1077 state->m_Regs[MPD] = (state->m_Regs[MPD] & ~0x7F) | (PostDiv & 0x77);
1078 status = UpdateReg(state, MPD);
1079 if (status < 0)
1080 break;
1081 status = UpdateRegs(state, TM, EP5);
1082 if (status < 0)
1083 break;
1084
1085 state->m_Regs[EB7] |= 0x20; /* CAL_forceSrce = 1 */
1086 status = UpdateReg(state, EB7);
1087 if (status < 0)
1088 break;
1089 msleep(1);
1090 state->m_Regs[EB7] &= ~0x20; /* CAL_forceSrce = 0 */
1091 status = UpdateReg(state, EB7);
1092 if (status < 0)
1093 break;
1094 }
1095 msleep(20);
1096 if (Standard != HF_FM_Radio)
1097 state->m_Regs[EP3] |= 0x04; /* RFAGC to normal mode */
1098 status = UpdateReg(state, EP3);
1099 if (status < 0)
1100 break;
1101
1102 } while (0);
1103 return status;
1104}
1105
1106static int sleep(struct dvb_frontend *fe)
1107{
1108 struct tda_state *state = fe->tuner_priv;
1109
1110 StandBy(state);
1111 return 0;
1112}
1113
1114static int init(struct dvb_frontend *fe)
1115{
1116 return 0;
1117}
1118
1119static int release(struct dvb_frontend *fe)
1120{
1121 kfree(fe->tuner_priv);
1122 fe->tuner_priv = NULL;
1123 return 0;
1124}
1125
1126/*
1127 * As defined on EN 300 429 Annex A and on ITU-T J.83 annex A, the DVB-C
1128 * roll-off factor is 0.15.
1129 * According with the specs, the amount of the needed bandwith is given by:
1130 * Bw = Symbol_rate * (1 + 0.15)
1131 * As such, the maximum symbol rate supported by 6 MHz is
1132 * max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
1133 *NOTE: For ITU-T J.83 Annex C, the roll-off factor is 0.13. So:
1134 * max_symbol_rate = 6 MHz / 1.13 = 5309735 Baud
1135 * That means that an adjustment is needed for Japan,
1136 * but, as currently DRX-K is hardcoded to Annex A, let's stick
1137 * with 0.15 roll-off factor.
1138 */
1139#define MAX_SYMBOL_RATE_6MHz 5217391
1140
1141static int set_params(struct dvb_frontend *fe,
1142 struct dvb_frontend_parameters *params)
1143{
1144 struct tda_state *state = fe->tuner_priv;
1145 int status = 0;
1146 int Standard;
1147
1148 state->m_Frequency = params->frequency;
1149
1150 if (fe->ops.info.type == FE_OFDM)
1151 switch (params->u.ofdm.bandwidth) {
1152 case BANDWIDTH_6_MHZ:
1153 Standard = HF_DVBT_6MHZ;
1154 break;
1155 case BANDWIDTH_7_MHZ:
1156 Standard = HF_DVBT_7MHZ;
1157 break;
1158 default:
1159 case BANDWIDTH_8_MHZ:
1160 Standard = HF_DVBT_8MHZ;
1161 break;
1162 }
1163 else if (fe->ops.info.type == FE_QAM) {
1164 if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz)
1165 Standard = HF_DVBC_6MHZ;
1166 else
1167 Standard = HF_DVBC_8MHZ;
1168 } else
1169 return -EINVAL;
1170 do {
1171 status = RFTrackingFiltersCorrection(state, params->frequency);
1172 if (status < 0)
1173 break;
1174 status = ChannelConfiguration(state, params->frequency, Standard);
1175 if (status < 0)
1176 break;
1177
1178 msleep(state->m_SettlingTime); /* Allow AGC's to settle down */
1179 } while (0);
1180 return status;
1181}
1182
1183#if 0
1184static int GetSignalStrength(s32 *pSignalStrength, u32 RFAgc, u32 IFAgc)
1185{
1186 if (IFAgc < 500) {
1187 /* Scale this from 0 to 50000 */
1188 *pSignalStrength = IFAgc * 100;
1189 } else {
1190 /* Scale range 500-1500 to 50000-80000 */
1191 *pSignalStrength = 50000 + (IFAgc - 500) * 30;
1192 }
1193
1194 return 0;
1195}
1196#endif
1197
1198static int get_frequency(struct dvb_frontend *fe, u32 *frequency)
1199{
1200 struct tda_state *state = fe->tuner_priv;
1201
1202 *frequency = state->IF;
1203 return 0;
1204}
1205
1206static int get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
1207{
1208 /* struct tda_state *state = fe->tuner_priv; */
1209 /* *bandwidth = priv->bandwidth; */
1210 return 0;
1211}
1212
1213
1214static struct dvb_tuner_ops tuner_ops = {
1215 .info = {
1216 .name = "NXP TDA18271C2D",
1217 .frequency_min = 47125000,
1218 .frequency_max = 865000000,
1219 .frequency_step = 62500
1220 },
1221 .init = init,
1222 .sleep = sleep,
1223 .set_params = set_params,
1224 .release = release,
1225 .get_frequency = get_frequency,
1226 .get_bandwidth = get_bandwidth,
1227};
1228
1229struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
1230 struct i2c_adapter *i2c, u8 adr)
1231{
1232 struct tda_state *state;
1233
1234 state = kzalloc(sizeof(struct tda_state), GFP_KERNEL);
1235 if (!state)
1236 return NULL;
1237
1238 fe->tuner_priv = state;
1239 state->adr = adr;
1240 state->i2c = i2c;
1241 memcpy(&fe->ops.tuner_ops, &tuner_ops, sizeof(struct dvb_tuner_ops));
1242 reset(state);
1243 InitCal(state);
1244
1245 return fe;
1246}
1247EXPORT_SYMBOL_GPL(tda18271c2dd_attach);
1248
1249MODULE_DESCRIPTION("TDA18271C2 driver");
1250MODULE_AUTHOR("DD");
1251MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda18271c2dd.h b/drivers/media/dvb/frontends/tda18271c2dd.h
new file mode 100644
index 00000000000..1389c74e12c
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda18271c2dd.h
@@ -0,0 +1,16 @@
1#ifndef _TDA18271C2DD_H_
2#define _TDA18271C2DD_H_
3#if defined(CONFIG_DVB_TDA18271C2DD) || (defined(CONFIG_DVB_TDA18271C2DD_MODULE) \
4 && defined(MODULE))
5struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
6 struct i2c_adapter *i2c, u8 adr);
7#else
8static inline struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
9 struct i2c_adapter *i2c, u8 adr)
10{
11 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
12 return NULL;
13}
14#endif
15
16#endif
diff --git a/drivers/media/dvb/frontends/tda18271c2dd_maps.h b/drivers/media/dvb/frontends/tda18271c2dd_maps.h
new file mode 100644
index 00000000000..b87661b9df1
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda18271c2dd_maps.h
@@ -0,0 +1,814 @@
1enum HF_S {
2 HF_None = 0, HF_B, HF_DK, HF_G, HF_I, HF_L, HF_L1, HF_MN, HF_FM_Radio,
3 HF_AnalogMax, HF_DVBT_6MHZ, HF_DVBT_7MHZ, HF_DVBT_8MHZ,
4 HF_DVBT, HF_ATSC, HF_DVBC_6MHZ, HF_DVBC_7MHZ,
5 HF_DVBC_8MHZ, HF_DVBC
6};
7
8struct SStandardParam m_StandardTable[] = {
9 { 0, 0, 0x00, 0x00 }, /* HF_None */
10 { 6000000, 7000000, 0x1D, 0x2C }, /* HF_B, */
11 { 6900000, 8000000, 0x1E, 0x2C }, /* HF_DK, */
12 { 7100000, 8000000, 0x1E, 0x2C }, /* HF_G, */
13 { 7250000, 8000000, 0x1E, 0x2C }, /* HF_I, */
14 { 6900000, 8000000, 0x1E, 0x2C }, /* HF_L, */
15 { 1250000, 8000000, 0x1E, 0x2C }, /* HF_L1, */
16 { 5400000, 6000000, 0x1C, 0x2C }, /* HF_MN, */
17 { 1250000, 500000, 0x18, 0x2C }, /* HF_FM_Radio, */
18 { 0, 0, 0x00, 0x00 }, /* HF_AnalogMax (Unused) */
19 { 3300000, 6000000, 0x1C, 0x58 }, /* HF_DVBT_6MHZ */
20 { 3500000, 7000000, 0x1C, 0x37 }, /* HF_DVBT_7MHZ */
21 { 4000000, 8000000, 0x1D, 0x37 }, /* HF_DVBT_8MHZ */
22 { 0, 0, 0x00, 0x00 }, /* HF_DVBT (Unused) */
23 { 5000000, 6000000, 0x1C, 0x37 }, /* HF_ATSC (center = 3.25 MHz) */
24 { 4000000, 6000000, 0x1D, 0x58 }, /* HF_DVBC_6MHZ (Chicago) */
25 { 4500000, 7000000, 0x1E, 0x37 }, /* HF_DVBC_7MHZ (not documented by NXP) */
26 { 5000000, 8000000, 0x1F, 0x37 }, /* HF_DVBC_8MHZ */
27 { 0, 0, 0x00, 0x00 }, /* HF_DVBC (Unused) */
28};
29
30struct SMap m_BP_Filter_Map[] = {
31 { 62000000, 0x00 },
32 { 84000000, 0x01 },
33 { 100000000, 0x02 },
34 { 140000000, 0x03 },
35 { 170000000, 0x04 },
36 { 180000000, 0x05 },
37 { 865000000, 0x06 },
38 { 0, 0x00 }, /* Table End */
39};
40
41static struct SMapI m_RF_Cal_Map[] = {
42 { 41000000, 0x0F },
43 { 43000000, 0x1C },
44 { 45000000, 0x2F },
45 { 46000000, 0x39 },
46 { 47000000, 0x40 },
47 { 47900000, 0x50 },
48 { 49100000, 0x16 },
49 { 50000000, 0x18 },
50 { 51000000, 0x20 },
51 { 53000000, 0x28 },
52 { 55000000, 0x2B },
53 { 56000000, 0x32 },
54 { 57000000, 0x35 },
55 { 58000000, 0x3E },
56 { 59000000, 0x43 },
57 { 60000000, 0x4E },
58 { 61100000, 0x55 },
59 { 63000000, 0x0F },
60 { 64000000, 0x11 },
61 { 65000000, 0x12 },
62 { 66000000, 0x15 },
63 { 67000000, 0x16 },
64 { 68000000, 0x17 },
65 { 70000000, 0x19 },
66 { 71000000, 0x1C },
67 { 72000000, 0x1D },
68 { 73000000, 0x1F },
69 { 74000000, 0x20 },
70 { 75000000, 0x21 },
71 { 76000000, 0x24 },
72 { 77000000, 0x25 },
73 { 78000000, 0x27 },
74 { 80000000, 0x28 },
75 { 81000000, 0x29 },
76 { 82000000, 0x2D },
77 { 83000000, 0x2E },
78 { 84000000, 0x2F },
79 { 85000000, 0x31 },
80 { 86000000, 0x33 },
81 { 87000000, 0x34 },
82 { 88000000, 0x35 },
83 { 89000000, 0x37 },
84 { 90000000, 0x38 },
85 { 91000000, 0x39 },
86 { 93000000, 0x3C },
87 { 94000000, 0x3E },
88 { 95000000, 0x3F },
89 { 96000000, 0x40 },
90 { 97000000, 0x42 },
91 { 99000000, 0x45 },
92 { 100000000, 0x46 },
93 { 102000000, 0x48 },
94 { 103000000, 0x4A },
95 { 105000000, 0x4D },
96 { 106000000, 0x4E },
97 { 107000000, 0x50 },
98 { 108000000, 0x51 },
99 { 110000000, 0x54 },
100 { 111000000, 0x56 },
101 { 112000000, 0x57 },
102 { 113000000, 0x58 },
103 { 114000000, 0x59 },
104 { 115000000, 0x5C },
105 { 116000000, 0x5D },
106 { 117000000, 0x5F },
107 { 119000000, 0x60 },
108 { 120000000, 0x64 },
109 { 121000000, 0x65 },
110 { 122000000, 0x66 },
111 { 123000000, 0x68 },
112 { 124000000, 0x69 },
113 { 125000000, 0x6C },
114 { 126000000, 0x6D },
115 { 127000000, 0x6E },
116 { 128000000, 0x70 },
117 { 129000000, 0x71 },
118 { 130000000, 0x75 },
119 { 131000000, 0x77 },
120 { 132000000, 0x78 },
121 { 133000000, 0x7B },
122 { 134000000, 0x7E },
123 { 135000000, 0x81 },
124 { 136000000, 0x82 },
125 { 137000000, 0x87 },
126 { 138000000, 0x88 },
127 { 139000000, 0x8D },
128 { 140000000, 0x8E },
129 { 141000000, 0x91 },
130 { 142000000, 0x95 },
131 { 143000000, 0x9A },
132 { 144000000, 0x9D },
133 { 145000000, 0xA1 },
134 { 146000000, 0xA2 },
135 { 147000000, 0xA4 },
136 { 148000000, 0xA9 },
137 { 149000000, 0xAE },
138 { 150000000, 0xB0 },
139 { 151000000, 0xB1 },
140 { 152000000, 0xB7 },
141 { 152600000, 0xBD },
142 { 154000000, 0x20 },
143 { 155000000, 0x22 },
144 { 156000000, 0x24 },
145 { 157000000, 0x25 },
146 { 158000000, 0x27 },
147 { 159000000, 0x29 },
148 { 160000000, 0x2C },
149 { 161000000, 0x2D },
150 { 163000000, 0x2E },
151 { 164000000, 0x2F },
152 { 164700000, 0x30 },
153 { 166000000, 0x11 },
154 { 167000000, 0x12 },
155 { 168000000, 0x13 },
156 { 169000000, 0x14 },
157 { 170000000, 0x15 },
158 { 172000000, 0x16 },
159 { 173000000, 0x17 },
160 { 174000000, 0x18 },
161 { 175000000, 0x1A },
162 { 176000000, 0x1B },
163 { 178000000, 0x1D },
164 { 179000000, 0x1E },
165 { 180000000, 0x1F },
166 { 181000000, 0x20 },
167 { 182000000, 0x21 },
168 { 183000000, 0x22 },
169 { 184000000, 0x24 },
170 { 185000000, 0x25 },
171 { 186000000, 0x26 },
172 { 187000000, 0x27 },
173 { 188000000, 0x29 },
174 { 189000000, 0x2A },
175 { 190000000, 0x2C },
176 { 191000000, 0x2D },
177 { 192000000, 0x2E },
178 { 193000000, 0x2F },
179 { 194000000, 0x30 },
180 { 195000000, 0x33 },
181 { 196000000, 0x35 },
182 { 198000000, 0x36 },
183 { 200000000, 0x38 },
184 { 201000000, 0x3C },
185 { 202000000, 0x3D },
186 { 203500000, 0x3E },
187 { 206000000, 0x0E },
188 { 208000000, 0x0F },
189 { 212000000, 0x10 },
190 { 216000000, 0x11 },
191 { 217000000, 0x12 },
192 { 218000000, 0x13 },
193 { 220000000, 0x14 },
194 { 222000000, 0x15 },
195 { 225000000, 0x16 },
196 { 228000000, 0x17 },
197 { 231000000, 0x18 },
198 { 234000000, 0x19 },
199 { 235000000, 0x1A },
200 { 236000000, 0x1B },
201 { 237000000, 0x1C },
202 { 240000000, 0x1D },
203 { 242000000, 0x1E },
204 { 244000000, 0x1F },
205 { 247000000, 0x20 },
206 { 249000000, 0x21 },
207 { 252000000, 0x22 },
208 { 253000000, 0x23 },
209 { 254000000, 0x24 },
210 { 256000000, 0x25 },
211 { 259000000, 0x26 },
212 { 262000000, 0x27 },
213 { 264000000, 0x28 },
214 { 267000000, 0x29 },
215 { 269000000, 0x2A },
216 { 271000000, 0x2B },
217 { 273000000, 0x2C },
218 { 275000000, 0x2D },
219 { 277000000, 0x2E },
220 { 279000000, 0x2F },
221 { 282000000, 0x30 },
222 { 284000000, 0x31 },
223 { 286000000, 0x32 },
224 { 287000000, 0x33 },
225 { 290000000, 0x34 },
226 { 293000000, 0x35 },
227 { 295000000, 0x36 },
228 { 297000000, 0x37 },
229 { 300000000, 0x38 },
230 { 303000000, 0x39 },
231 { 305000000, 0x3A },
232 { 306000000, 0x3B },
233 { 307000000, 0x3C },
234 { 310000000, 0x3D },
235 { 312000000, 0x3E },
236 { 315000000, 0x3F },
237 { 318000000, 0x40 },
238 { 320000000, 0x41 },
239 { 323000000, 0x42 },
240 { 324000000, 0x43 },
241 { 325000000, 0x44 },
242 { 327000000, 0x45 },
243 { 331000000, 0x46 },
244 { 334000000, 0x47 },
245 { 337000000, 0x48 },
246 { 339000000, 0x49 },
247 { 340000000, 0x4A },
248 { 341000000, 0x4B },
249 { 343000000, 0x4C },
250 { 345000000, 0x4D },
251 { 349000000, 0x4E },
252 { 352000000, 0x4F },
253 { 353000000, 0x50 },
254 { 355000000, 0x51 },
255 { 357000000, 0x52 },
256 { 359000000, 0x53 },
257 { 361000000, 0x54 },
258 { 362000000, 0x55 },
259 { 364000000, 0x56 },
260 { 368000000, 0x57 },
261 { 370000000, 0x58 },
262 { 372000000, 0x59 },
263 { 375000000, 0x5A },
264 { 376000000, 0x5B },
265 { 377000000, 0x5C },
266 { 379000000, 0x5D },
267 { 382000000, 0x5E },
268 { 384000000, 0x5F },
269 { 385000000, 0x60 },
270 { 386000000, 0x61 },
271 { 388000000, 0x62 },
272 { 390000000, 0x63 },
273 { 393000000, 0x64 },
274 { 394000000, 0x65 },
275 { 396000000, 0x66 },
276 { 397000000, 0x67 },
277 { 398000000, 0x68 },
278 { 400000000, 0x69 },
279 { 402000000, 0x6A },
280 { 403000000, 0x6B },
281 { 407000000, 0x6C },
282 { 408000000, 0x6D },
283 { 409000000, 0x6E },
284 { 410000000, 0x6F },
285 { 411000000, 0x70 },
286 { 412000000, 0x71 },
287 { 413000000, 0x72 },
288 { 414000000, 0x73 },
289 { 417000000, 0x74 },
290 { 418000000, 0x75 },
291 { 420000000, 0x76 },
292 { 422000000, 0x77 },
293 { 423000000, 0x78 },
294 { 424000000, 0x79 },
295 { 427000000, 0x7A },
296 { 428000000, 0x7B },
297 { 429000000, 0x7D },
298 { 432000000, 0x7F },
299 { 434000000, 0x80 },
300 { 435000000, 0x81 },
301 { 436000000, 0x83 },
302 { 437000000, 0x84 },
303 { 438000000, 0x85 },
304 { 439000000, 0x86 },
305 { 440000000, 0x87 },
306 { 441000000, 0x88 },
307 { 442000000, 0x89 },
308 { 445000000, 0x8A },
309 { 446000000, 0x8B },
310 { 447000000, 0x8C },
311 { 448000000, 0x8E },
312 { 449000000, 0x8F },
313 { 450000000, 0x90 },
314 { 452000000, 0x91 },
315 { 453000000, 0x93 },
316 { 454000000, 0x94 },
317 { 456000000, 0x96 },
318 { 457800000, 0x98 },
319 { 461000000, 0x11 },
320 { 468000000, 0x12 },
321 { 472000000, 0x13 },
322 { 473000000, 0x14 },
323 { 474000000, 0x15 },
324 { 481000000, 0x16 },
325 { 486000000, 0x17 },
326 { 491000000, 0x18 },
327 { 498000000, 0x19 },
328 { 499000000, 0x1A },
329 { 501000000, 0x1B },
330 { 506000000, 0x1C },
331 { 511000000, 0x1D },
332 { 516000000, 0x1E },
333 { 520000000, 0x1F },
334 { 521000000, 0x20 },
335 { 525000000, 0x21 },
336 { 529000000, 0x22 },
337 { 533000000, 0x23 },
338 { 539000000, 0x24 },
339 { 541000000, 0x25 },
340 { 547000000, 0x26 },
341 { 549000000, 0x27 },
342 { 551000000, 0x28 },
343 { 556000000, 0x29 },
344 { 561000000, 0x2A },
345 { 563000000, 0x2B },
346 { 565000000, 0x2C },
347 { 569000000, 0x2D },
348 { 571000000, 0x2E },
349 { 577000000, 0x2F },
350 { 580000000, 0x30 },
351 { 582000000, 0x31 },
352 { 584000000, 0x32 },
353 { 588000000, 0x33 },
354 { 591000000, 0x34 },
355 { 596000000, 0x35 },
356 { 598000000, 0x36 },
357 { 603000000, 0x37 },
358 { 604000000, 0x38 },
359 { 606000000, 0x39 },
360 { 612000000, 0x3A },
361 { 615000000, 0x3B },
362 { 617000000, 0x3C },
363 { 621000000, 0x3D },
364 { 622000000, 0x3E },
365 { 625000000, 0x3F },
366 { 632000000, 0x40 },
367 { 633000000, 0x41 },
368 { 634000000, 0x42 },
369 { 642000000, 0x43 },
370 { 643000000, 0x44 },
371 { 647000000, 0x45 },
372 { 650000000, 0x46 },
373 { 652000000, 0x47 },
374 { 657000000, 0x48 },
375 { 661000000, 0x49 },
376 { 662000000, 0x4A },
377 { 665000000, 0x4B },
378 { 667000000, 0x4C },
379 { 670000000, 0x4D },
380 { 673000000, 0x4E },
381 { 676000000, 0x4F },
382 { 677000000, 0x50 },
383 { 681000000, 0x51 },
384 { 683000000, 0x52 },
385 { 686000000, 0x53 },
386 { 688000000, 0x54 },
387 { 689000000, 0x55 },
388 { 691000000, 0x56 },
389 { 695000000, 0x57 },
390 { 698000000, 0x58 },
391 { 703000000, 0x59 },
392 { 704000000, 0x5A },
393 { 705000000, 0x5B },
394 { 707000000, 0x5C },
395 { 710000000, 0x5D },
396 { 712000000, 0x5E },
397 { 717000000, 0x5F },
398 { 718000000, 0x60 },
399 { 721000000, 0x61 },
400 { 722000000, 0x62 },
401 { 723000000, 0x63 },
402 { 725000000, 0x64 },
403 { 727000000, 0x65 },
404 { 730000000, 0x66 },
405 { 732000000, 0x67 },
406 { 735000000, 0x68 },
407 { 740000000, 0x69 },
408 { 741000000, 0x6A },
409 { 742000000, 0x6B },
410 { 743000000, 0x6C },
411 { 745000000, 0x6D },
412 { 747000000, 0x6E },
413 { 748000000, 0x6F },
414 { 750000000, 0x70 },
415 { 752000000, 0x71 },
416 { 754000000, 0x72 },
417 { 757000000, 0x73 },
418 { 758000000, 0x74 },
419 { 760000000, 0x75 },
420 { 763000000, 0x76 },
421 { 764000000, 0x77 },
422 { 766000000, 0x78 },
423 { 767000000, 0x79 },
424 { 768000000, 0x7A },
425 { 773000000, 0x7B },
426 { 774000000, 0x7C },
427 { 776000000, 0x7D },
428 { 777000000, 0x7E },
429 { 778000000, 0x7F },
430 { 779000000, 0x80 },
431 { 781000000, 0x81 },
432 { 783000000, 0x82 },
433 { 784000000, 0x83 },
434 { 785000000, 0x84 },
435 { 786000000, 0x85 },
436 { 793000000, 0x86 },
437 { 794000000, 0x87 },
438 { 795000000, 0x88 },
439 { 797000000, 0x89 },
440 { 799000000, 0x8A },
441 { 801000000, 0x8B },
442 { 802000000, 0x8C },
443 { 803000000, 0x8D },
444 { 804000000, 0x8E },
445 { 810000000, 0x90 },
446 { 811000000, 0x91 },
447 { 812000000, 0x92 },
448 { 814000000, 0x93 },
449 { 816000000, 0x94 },
450 { 817000000, 0x96 },
451 { 818000000, 0x97 },
452 { 820000000, 0x98 },
453 { 821000000, 0x99 },
454 { 822000000, 0x9A },
455 { 828000000, 0x9B },
456 { 829000000, 0x9D },
457 { 830000000, 0x9F },
458 { 831000000, 0xA0 },
459 { 833000000, 0xA1 },
460 { 835000000, 0xA2 },
461 { 836000000, 0xA3 },
462 { 837000000, 0xA4 },
463 { 838000000, 0xA6 },
464 { 840000000, 0xA8 },
465 { 842000000, 0xA9 },
466 { 845000000, 0xAA },
467 { 846000000, 0xAB },
468 { 847000000, 0xAD },
469 { 848000000, 0xAE },
470 { 852000000, 0xAF },
471 { 853000000, 0xB0 },
472 { 858000000, 0xB1 },
473 { 860000000, 0xB2 },
474 { 861000000, 0xB3 },
475 { 862000000, 0xB4 },
476 { 863000000, 0xB6 },
477 { 864000000, 0xB8 },
478 { 865000000, 0xB9 },
479 { 0, 0x00 }, /* Table End */
480};
481
482
483static struct SMap2 m_KM_Map[] = {
484 { 47900000, 3, 2 },
485 { 61100000, 3, 1 },
486 { 350000000, 3, 0 },
487 { 720000000, 2, 1 },
488 { 865000000, 3, 3 },
489 { 0, 0x00 }, /* Table End */
490};
491
492static struct SMap2 m_Main_PLL_Map[] = {
493 { 33125000, 0x57, 0xF0 },
494 { 35500000, 0x56, 0xE0 },
495 { 38188000, 0x55, 0xD0 },
496 { 41375000, 0x54, 0xC0 },
497 { 45125000, 0x53, 0xB0 },
498 { 49688000, 0x52, 0xA0 },
499 { 55188000, 0x51, 0x90 },
500 { 62125000, 0x50, 0x80 },
501 { 66250000, 0x47, 0x78 },
502 { 71000000, 0x46, 0x70 },
503 { 76375000, 0x45, 0x68 },
504 { 82750000, 0x44, 0x60 },
505 { 90250000, 0x43, 0x58 },
506 { 99375000, 0x42, 0x50 },
507 { 110375000, 0x41, 0x48 },
508 { 124250000, 0x40, 0x40 },
509 { 132500000, 0x37, 0x3C },
510 { 142000000, 0x36, 0x38 },
511 { 152750000, 0x35, 0x34 },
512 { 165500000, 0x34, 0x30 },
513 { 180500000, 0x33, 0x2C },
514 { 198750000, 0x32, 0x28 },
515 { 220750000, 0x31, 0x24 },
516 { 248500000, 0x30, 0x20 },
517 { 265000000, 0x27, 0x1E },
518 { 284000000, 0x26, 0x1C },
519 { 305500000, 0x25, 0x1A },
520 { 331000000, 0x24, 0x18 },
521 { 361000000, 0x23, 0x16 },
522 { 397500000, 0x22, 0x14 },
523 { 441500000, 0x21, 0x12 },
524 { 497000000, 0x20, 0x10 },
525 { 530000000, 0x17, 0x0F },
526 { 568000000, 0x16, 0x0E },
527 { 611000000, 0x15, 0x0D },
528 { 662000000, 0x14, 0x0C },
529 { 722000000, 0x13, 0x0B },
530 { 795000000, 0x12, 0x0A },
531 { 883000000, 0x11, 0x09 },
532 { 994000000, 0x10, 0x08 },
533 { 0, 0x00, 0x00 }, /* Table End */
534};
535
536static struct SMap2 m_Cal_PLL_Map[] = {
537 { 33813000, 0xDD, 0xD0 },
538 { 36625000, 0xDC, 0xC0 },
539 { 39938000, 0xDB, 0xB0 },
540 { 43938000, 0xDA, 0xA0 },
541 { 48813000, 0xD9, 0x90 },
542 { 54938000, 0xD8, 0x80 },
543 { 62813000, 0xD3, 0x70 },
544 { 67625000, 0xCD, 0x68 },
545 { 73250000, 0xCC, 0x60 },
546 { 79875000, 0xCB, 0x58 },
547 { 87875000, 0xCA, 0x50 },
548 { 97625000, 0xC9, 0x48 },
549 { 109875000, 0xC8, 0x40 },
550 { 125625000, 0xC3, 0x38 },
551 { 135250000, 0xBD, 0x34 },
552 { 146500000, 0xBC, 0x30 },
553 { 159750000, 0xBB, 0x2C },
554 { 175750000, 0xBA, 0x28 },
555 { 195250000, 0xB9, 0x24 },
556 { 219750000, 0xB8, 0x20 },
557 { 251250000, 0xB3, 0x1C },
558 { 270500000, 0xAD, 0x1A },
559 { 293000000, 0xAC, 0x18 },
560 { 319500000, 0xAB, 0x16 },
561 { 351500000, 0xAA, 0x14 },
562 { 390500000, 0xA9, 0x12 },
563 { 439500000, 0xA8, 0x10 },
564 { 502500000, 0xA3, 0x0E },
565 { 541000000, 0x9D, 0x0D },
566 { 586000000, 0x9C, 0x0C },
567 { 639000000, 0x9B, 0x0B },
568 { 703000000, 0x9A, 0x0A },
569 { 781000000, 0x99, 0x09 },
570 { 879000000, 0x98, 0x08 },
571 { 0, 0x00, 0x00 }, /* Table End */
572};
573
574static struct SMap m_GainTaper_Map[] = {
575 { 45400000, 0x1F },
576 { 45800000, 0x1E },
577 { 46200000, 0x1D },
578 { 46700000, 0x1C },
579 { 47100000, 0x1B },
580 { 47500000, 0x1A },
581 { 47900000, 0x19 },
582 { 49600000, 0x17 },
583 { 51200000, 0x16 },
584 { 52900000, 0x15 },
585 { 54500000, 0x14 },
586 { 56200000, 0x13 },
587 { 57800000, 0x12 },
588 { 59500000, 0x11 },
589 { 61100000, 0x10 },
590 { 67600000, 0x0D },
591 { 74200000, 0x0C },
592 { 80700000, 0x0B },
593 { 87200000, 0x0A },
594 { 93800000, 0x09 },
595 { 100300000, 0x08 },
596 { 106900000, 0x07 },
597 { 113400000, 0x06 },
598 { 119900000, 0x05 },
599 { 126500000, 0x04 },
600 { 133000000, 0x03 },
601 { 139500000, 0x02 },
602 { 146100000, 0x01 },
603 { 152600000, 0x00 },
604 { 154300000, 0x1F },
605 { 156100000, 0x1E },
606 { 157800000, 0x1D },
607 { 159500000, 0x1C },
608 { 161200000, 0x1B },
609 { 163000000, 0x1A },
610 { 164700000, 0x19 },
611 { 170200000, 0x17 },
612 { 175800000, 0x16 },
613 { 181300000, 0x15 },
614 { 186900000, 0x14 },
615 { 192400000, 0x13 },
616 { 198000000, 0x12 },
617 { 203500000, 0x11 },
618 { 216200000, 0x14 },
619 { 228900000, 0x13 },
620 { 241600000, 0x12 },
621 { 254400000, 0x11 },
622 { 267100000, 0x10 },
623 { 279800000, 0x0F },
624 { 292500000, 0x0E },
625 { 305200000, 0x0D },
626 { 317900000, 0x0C },
627 { 330700000, 0x0B },
628 { 343400000, 0x0A },
629 { 356100000, 0x09 },
630 { 368800000, 0x08 },
631 { 381500000, 0x07 },
632 { 394200000, 0x06 },
633 { 406900000, 0x05 },
634 { 419700000, 0x04 },
635 { 432400000, 0x03 },
636 { 445100000, 0x02 },
637 { 457800000, 0x01 },
638 { 476300000, 0x19 },
639 { 494800000, 0x18 },
640 { 513300000, 0x17 },
641 { 531800000, 0x16 },
642 { 550300000, 0x15 },
643 { 568900000, 0x14 },
644 { 587400000, 0x13 },
645 { 605900000, 0x12 },
646 { 624400000, 0x11 },
647 { 642900000, 0x10 },
648 { 661400000, 0x0F },
649 { 679900000, 0x0E },
650 { 698400000, 0x0D },
651 { 716900000, 0x0C },
652 { 735400000, 0x0B },
653 { 753900000, 0x0A },
654 { 772500000, 0x09 },
655 { 791000000, 0x08 },
656 { 809500000, 0x07 },
657 { 828000000, 0x06 },
658 { 846500000, 0x05 },
659 { 865000000, 0x04 },
660 { 0, 0x00 }, /* Table End */
661};
662
663static struct SMap m_RF_Cal_DC_Over_DT_Map[] = {
664 { 47900000, 0x00 },
665 { 55000000, 0x00 },
666 { 61100000, 0x0A },
667 { 64000000, 0x0A },
668 { 82000000, 0x14 },
669 { 84000000, 0x19 },
670 { 119000000, 0x1C },
671 { 124000000, 0x20 },
672 { 129000000, 0x2A },
673 { 134000000, 0x32 },
674 { 139000000, 0x39 },
675 { 144000000, 0x3E },
676 { 149000000, 0x3F },
677 { 152600000, 0x40 },
678 { 154000000, 0x40 },
679 { 164700000, 0x41 },
680 { 203500000, 0x32 },
681 { 353000000, 0x19 },
682 { 356000000, 0x1A },
683 { 359000000, 0x1B },
684 { 363000000, 0x1C },
685 { 366000000, 0x1D },
686 { 369000000, 0x1E },
687 { 373000000, 0x1F },
688 { 376000000, 0x20 },
689 { 379000000, 0x21 },
690 { 383000000, 0x22 },
691 { 386000000, 0x23 },
692 { 389000000, 0x24 },
693 { 393000000, 0x25 },
694 { 396000000, 0x26 },
695 { 399000000, 0x27 },
696 { 402000000, 0x28 },
697 { 404000000, 0x29 },
698 { 407000000, 0x2A },
699 { 409000000, 0x2B },
700 { 412000000, 0x2C },
701 { 414000000, 0x2D },
702 { 417000000, 0x2E },
703 { 419000000, 0x2F },
704 { 422000000, 0x30 },
705 { 424000000, 0x31 },
706 { 427000000, 0x32 },
707 { 429000000, 0x33 },
708 { 432000000, 0x34 },
709 { 434000000, 0x35 },
710 { 437000000, 0x36 },
711 { 439000000, 0x37 },
712 { 442000000, 0x38 },
713 { 444000000, 0x39 },
714 { 447000000, 0x3A },
715 { 449000000, 0x3B },
716 { 457800000, 0x3C },
717 { 465000000, 0x0F },
718 { 477000000, 0x12 },
719 { 483000000, 0x14 },
720 { 502000000, 0x19 },
721 { 508000000, 0x1B },
722 { 519000000, 0x1C },
723 { 522000000, 0x1D },
724 { 524000000, 0x1E },
725 { 534000000, 0x1F },
726 { 549000000, 0x20 },
727 { 554000000, 0x22 },
728 { 584000000, 0x24 },
729 { 589000000, 0x26 },
730 { 658000000, 0x27 },
731 { 664000000, 0x2C },
732 { 669000000, 0x2D },
733 { 699000000, 0x2E },
734 { 704000000, 0x30 },
735 { 709000000, 0x31 },
736 { 714000000, 0x32 },
737 { 724000000, 0x33 },
738 { 729000000, 0x36 },
739 { 739000000, 0x38 },
740 { 744000000, 0x39 },
741 { 749000000, 0x3B },
742 { 754000000, 0x3C },
743 { 759000000, 0x3D },
744 { 764000000, 0x3E },
745 { 769000000, 0x3F },
746 { 774000000, 0x40 },
747 { 779000000, 0x41 },
748 { 784000000, 0x43 },
749 { 789000000, 0x46 },
750 { 794000000, 0x48 },
751 { 799000000, 0x4B },
752 { 804000000, 0x4F },
753 { 809000000, 0x54 },
754 { 814000000, 0x59 },
755 { 819000000, 0x5D },
756 { 824000000, 0x61 },
757 { 829000000, 0x68 },
758 { 834000000, 0x6E },
759 { 839000000, 0x75 },
760 { 844000000, 0x7E },
761 { 849000000, 0x82 },
762 { 854000000, 0x84 },
763 { 859000000, 0x8F },
764 { 865000000, 0x9A },
765 { 0, 0x00 }, /* Table End */
766};
767
768
769static struct SMap m_IR_Meas_Map[] = {
770 { 200000000, 0x05 },
771 { 400000000, 0x06 },
772 { 865000000, 0x07 },
773 { 0, 0x00 }, /* Table End */
774};
775
776static struct SMap2 m_CID_Target_Map[] = {
777 { 46000000, 0x04, 18 },
778 { 52200000, 0x0A, 15 },
779 { 70100000, 0x01, 40 },
780 { 136800000, 0x18, 40 },
781 { 156700000, 0x18, 40 },
782 { 186250000, 0x0A, 40 },
783 { 230000000, 0x0A, 40 },
784 { 345000000, 0x18, 40 },
785 { 426000000, 0x0E, 40 },
786 { 489500000, 0x1E, 40 },
787 { 697500000, 0x32, 40 },
788 { 842000000, 0x3A, 40 },
789 { 0, 0x00, 0 }, /* Table End */
790};
791
792static struct SRFBandMap m_RF_Band_Map[7] = {
793 { 47900000, 46000000, 0, 0},
794 { 61100000, 52200000, 0, 0},
795 { 152600000, 70100000, 136800000, 0},
796 { 164700000, 156700000, 0, 0},
797 { 203500000, 186250000, 0, 0},
798 { 457800000, 230000000, 345000000, 426000000},
799 { 865000000, 489500000, 697500000, 842000000},
800};
801
802u8 m_Thermometer_Map_1[16] = {
803 60, 62, 66, 64,
804 74, 72, 68, 70,
805 90, 88, 84, 86,
806 76, 78, 82, 80,
807};
808
809u8 m_Thermometer_Map_2[16] = {
810 92, 94, 98, 96,
811 106, 104, 100, 102,
812 122, 120, 116, 118,
813 108, 110, 114, 112,
814};
diff --git a/drivers/media/dvb/frontends/tda665x.c b/drivers/media/dvb/frontends/tda665x.c
new file mode 100644
index 00000000000..2c1c759a4f4
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda665x.c
@@ -0,0 +1,258 @@
1/*
2 TDA665x tuner driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 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 <linux/init.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/slab.h>
24
25#include "dvb_frontend.h"
26#include "tda665x.h"
27
28struct tda665x_state {
29 struct dvb_frontend *fe;
30 struct i2c_adapter *i2c;
31 const struct tda665x_config *config;
32
33 u32 frequency;
34 u32 bandwidth;
35};
36
37static int tda665x_read(struct tda665x_state *state, u8 *buf)
38{
39 const struct tda665x_config *config = state->config;
40 int err = 0;
41 struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD, .buf = buf, .len = 2 };
42
43 err = i2c_transfer(state->i2c, &msg, 1);
44 if (err != 1)
45 goto exit;
46
47 return err;
48exit:
49 printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err);
50 return err;
51}
52
53static int tda665x_write(struct tda665x_state *state, u8 *buf, u8 length)
54{
55 const struct tda665x_config *config = state->config;
56 int err = 0;
57 struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = length };
58
59 err = i2c_transfer(state->i2c, &msg, 1);
60 if (err != 1)
61 goto exit;
62
63 return err;
64exit:
65 printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err);
66 return err;
67}
68
69static int tda665x_get_state(struct dvb_frontend *fe,
70 enum tuner_param param,
71 struct tuner_state *tstate)
72{
73 struct tda665x_state *state = fe->tuner_priv;
74 int err = 0;
75
76 switch (param) {
77 case DVBFE_TUNER_FREQUENCY:
78 tstate->frequency = state->frequency;
79 break;
80 case DVBFE_TUNER_BANDWIDTH:
81 break;
82 default:
83 printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
84 err = -EINVAL;
85 break;
86 }
87
88 return err;
89}
90
91static int tda665x_get_status(struct dvb_frontend *fe, u32 *status)
92{
93 struct tda665x_state *state = fe->tuner_priv;
94 u8 result = 0;
95 int err = 0;
96
97 *status = 0;
98
99 err = tda665x_read(state, &result);
100 if (err < 0)
101 goto exit;
102
103 if ((result >> 6) & 0x01) {
104 printk(KERN_DEBUG "%s: Tuner Phase Locked\n", __func__);
105 *status = 1;
106 }
107
108 return err;
109exit:
110 printk(KERN_ERR "%s: I/O Error\n", __func__);
111 return err;
112}
113
114static int tda665x_set_state(struct dvb_frontend *fe,
115 enum tuner_param param,
116 struct tuner_state *tstate)
117{
118 struct tda665x_state *state = fe->tuner_priv;
119 const struct tda665x_config *config = state->config;
120 u32 frequency, status = 0;
121 u8 buf[4];
122 int err = 0;
123
124 if (param & DVBFE_TUNER_FREQUENCY) {
125
126 frequency = tstate->frequency;
127 if ((frequency < config->frequency_max) || (frequency > config->frequency_min)) {
128 printk(KERN_ERR "%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
129 return -EINVAL;
130 }
131
132 frequency += config->frequency_offst;
133 frequency *= config->ref_multiplier;
134 frequency += config->ref_divider >> 1;
135 frequency /= config->ref_divider;
136
137 buf[0] = (u8) ((frequency & 0x7f00) >> 8);
138 buf[1] = (u8) (frequency & 0x00ff) >> 0;
139 buf[2] = 0x80 | 0x40 | 0x02;
140 buf[3] = 0x00;
141
142 /* restore frequency */
143 frequency = tstate->frequency;
144
145 if (frequency < 153000000) {
146 /* VHF-L */
147 buf[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */
148 if (frequency < 68000000)
149 buf[3] |= 0x40; /* 83uA */
150 if (frequency < 1040000000)
151 buf[3] |= 0x60; /* 122uA */
152 if (frequency < 1250000000)
153 buf[3] |= 0x80; /* 163uA */
154 else
155 buf[3] |= 0xa0; /* 254uA */
156 } else if (frequency < 438000000) {
157 /* VHF-H */
158 buf[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */
159 if (frequency < 230000000)
160 buf[3] |= 0x40;
161 if (frequency < 300000000)
162 buf[3] |= 0x60;
163 else
164 buf[3] |= 0x80;
165 } else {
166 /* UHF */
167 buf[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */
168 if (frequency < 470000000)
169 buf[3] |= 0x60;
170 if (frequency < 526000000)
171 buf[3] |= 0x80;
172 else
173 buf[3] |= 0xa0;
174 }
175
176 /* Set params */
177 err = tda665x_write(state, buf, 5);
178 if (err < 0)
179 goto exit;
180
181 /* sleep for some time */
182 printk(KERN_DEBUG "%s: Waiting to Phase LOCK\n", __func__);
183 msleep(20);
184 /* check status */
185 err = tda665x_get_status(fe, &status);
186 if (err < 0)
187 goto exit;
188
189 if (status == 1) {
190 printk(KERN_DEBUG "%s: Tuner Phase locked: status=%d\n", __func__, status);
191 state->frequency = frequency; /* cache successful state */
192 } else {
193 printk(KERN_ERR "%s: No Phase lock: status=%d\n", __func__, status);
194 }
195 } else {
196 printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
197 return -EINVAL;
198 }
199
200 return 0;
201exit:
202 printk(KERN_ERR "%s: I/O Error\n", __func__);
203 return err;
204}
205
206static int tda665x_release(struct dvb_frontend *fe)
207{
208 struct tda665x_state *state = fe->tuner_priv;
209
210 fe->tuner_priv = NULL;
211 kfree(state);
212 return 0;
213}
214
215static struct dvb_tuner_ops tda665x_ops = {
216
217 .set_state = tda665x_set_state,
218 .get_state = tda665x_get_state,
219 .get_status = tda665x_get_status,
220 .release = tda665x_release
221};
222
223struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
224 const struct tda665x_config *config,
225 struct i2c_adapter *i2c)
226{
227 struct tda665x_state *state = NULL;
228 struct dvb_tuner_info *info;
229
230 state = kzalloc(sizeof(struct tda665x_state), GFP_KERNEL);
231 if (state == NULL)
232 goto exit;
233
234 state->config = config;
235 state->i2c = i2c;
236 state->fe = fe;
237 fe->tuner_priv = state;
238 fe->ops.tuner_ops = tda665x_ops;
239 info = &fe->ops.tuner_ops.info;
240
241 memcpy(info->name, config->name, sizeof(config->name));
242 info->frequency_min = config->frequency_min;
243 info->frequency_max = config->frequency_max;
244 info->frequency_step = config->frequency_offst;
245
246 printk(KERN_DEBUG "%s: Attaching TDA665x (%s) tuner\n", __func__, info->name);
247
248 return fe;
249
250exit:
251 kfree(state);
252 return NULL;
253}
254EXPORT_SYMBOL(tda665x_attach);
255
256MODULE_DESCRIPTION("TDA665x driver");
257MODULE_AUTHOR("Manu Abraham");
258MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda665x.h b/drivers/media/dvb/frontends/tda665x.h
new file mode 100644
index 00000000000..ec7927aa75a
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda665x.h
@@ -0,0 +1,52 @@
1/*
2 TDA665x tuner driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 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 __TDA665x_H
21#define __TDA665x_H
22
23struct tda665x_config {
24 char name[128];
25
26 u8 addr;
27 u32 frequency_min;
28 u32 frequency_max;
29 u32 frequency_offst;
30 u32 ref_multiplier;
31 u32 ref_divider;
32};
33
34#if defined(CONFIG_DVB_TDA665x) || (defined(CONFIG_DVB_TDA665x_MODULE) && defined(MODULE))
35
36extern struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
37 const struct tda665x_config *config,
38 struct i2c_adapter *i2c);
39
40#else
41
42static inline struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
43 const struct tda665x_config *config,
44 struct i2c_adapter *i2c)
45{
46 printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
47 return NULL;
48}
49
50#endif /* CONFIG_DVB_TDA665x */
51
52#endif /* __TDA665x_H */
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c
new file mode 100644
index 00000000000..9369f7442f2
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8083.c
@@ -0,0 +1,486 @@
1/*
2 Driver for Philips TDA8083 based QPSK Demodulator
3
4 Copyright (C) 2001 Convergence Integrated Media GmbH
5
6 written by Ralph Metzler <ralph@convergence.de>
7
8 adoption to the new DVB frontend API and diagnostic ioctl's
9 by Holger Waechtler <holger@convergence.de>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/
26
27#include <linux/init.h>
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/string.h>
31#include <linux/slab.h>
32#include <linux/jiffies.h>
33#include "dvb_frontend.h"
34#include "tda8083.h"
35
36
37struct tda8083_state {
38 struct i2c_adapter* i2c;
39 /* configuration settings */
40 const struct tda8083_config* config;
41 struct dvb_frontend frontend;
42};
43
44static int debug;
45#define dprintk(args...) \
46 do { \
47 if (debug) printk(KERN_DEBUG "tda8083: " args); \
48 } while (0)
49
50
51static u8 tda8083_init_tab [] = {
52 0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea,
53 0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10,
54 0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8,
55 0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00,
56 0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00
58};
59
60
61static int tda8083_writereg (struct tda8083_state* state, u8 reg, u8 data)
62{
63 int ret;
64 u8 buf [] = { reg, data };
65 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
66
67 ret = i2c_transfer(state->i2c, &msg, 1);
68
69 if (ret != 1)
70 dprintk ("%s: writereg error (reg %02x, ret == %i)\n",
71 __func__, reg, ret);
72
73 return (ret != 1) ? -1 : 0;
74}
75
76static int tda8083_readregs (struct tda8083_state* state, u8 reg1, u8 *b, u8 len)
77{
78 int ret;
79 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = &reg1, .len = 1 },
80 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
81
82 ret = i2c_transfer(state->i2c, msg, 2);
83
84 if (ret != 2)
85 dprintk ("%s: readreg error (reg %02x, ret == %i)\n",
86 __func__, reg1, ret);
87
88 return ret == 2 ? 0 : -1;
89}
90
91static inline u8 tda8083_readreg (struct tda8083_state* state, u8 reg)
92{
93 u8 val;
94
95 tda8083_readregs (state, reg, &val, 1);
96
97 return val;
98}
99
100static int tda8083_set_inversion (struct tda8083_state* state, fe_spectral_inversion_t inversion)
101{
102 /* XXX FIXME: implement other modes than FEC_AUTO */
103 if (inversion == INVERSION_AUTO)
104 return 0;
105
106 return -EINVAL;
107}
108
109static int tda8083_set_fec (struct tda8083_state* state, fe_code_rate_t fec)
110{
111 if (fec == FEC_AUTO)
112 return tda8083_writereg (state, 0x07, 0xff);
113
114 if (fec >= FEC_1_2 && fec <= FEC_8_9)
115 return tda8083_writereg (state, 0x07, 1 << (FEC_8_9 - fec));
116
117 return -EINVAL;
118}
119
120static fe_code_rate_t tda8083_get_fec (struct tda8083_state* state)
121{
122 u8 index;
123 static fe_code_rate_t fec_tab [] = { FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
124 FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8 };
125
126 index = tda8083_readreg(state, 0x0e) & 0x07;
127
128 return fec_tab [index];
129}
130
131static int tda8083_set_symbolrate (struct tda8083_state* state, u32 srate)
132{
133 u32 ratio;
134 u32 tmp;
135 u8 filter;
136
137 if (srate > 32000000)
138 srate = 32000000;
139 if (srate < 500000)
140 srate = 500000;
141
142 filter = 0;
143 if (srate < 24000000)
144 filter = 2;
145 if (srate < 16000000)
146 filter = 3;
147
148 tmp = 31250 << 16;
149 ratio = tmp / srate;
150
151 tmp = (tmp % srate) << 8;
152 ratio = (ratio << 8) + tmp / srate;
153
154 tmp = (tmp % srate) << 8;
155 ratio = (ratio << 8) + tmp / srate;
156
157 dprintk("tda8083: ratio == %08x\n", (unsigned int) ratio);
158
159 tda8083_writereg (state, 0x05, filter);
160 tda8083_writereg (state, 0x02, (ratio >> 16) & 0xff);
161 tda8083_writereg (state, 0x03, (ratio >> 8) & 0xff);
162 tda8083_writereg (state, 0x04, (ratio ) & 0xff);
163
164 tda8083_writereg (state, 0x00, 0x3c);
165 tda8083_writereg (state, 0x00, 0x04);
166
167 return 1;
168}
169
170static void tda8083_wait_diseqc_fifo (struct tda8083_state* state, int timeout)
171{
172 unsigned long start = jiffies;
173
174 while (jiffies - start < timeout &&
175 !(tda8083_readreg(state, 0x02) & 0x80))
176 {
177 msleep(50);
178 };
179}
180
181static int tda8083_set_tone (struct tda8083_state* state, fe_sec_tone_mode_t tone)
182{
183 tda8083_writereg (state, 0x26, 0xf1);
184
185 switch (tone) {
186 case SEC_TONE_OFF:
187 return tda8083_writereg (state, 0x29, 0x00);
188 case SEC_TONE_ON:
189 return tda8083_writereg (state, 0x29, 0x80);
190 default:
191 return -EINVAL;
192 };
193}
194
195static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t voltage)
196{
197 switch (voltage) {
198 case SEC_VOLTAGE_13:
199 return tda8083_writereg (state, 0x20, 0x00);
200 case SEC_VOLTAGE_18:
201 return tda8083_writereg (state, 0x20, 0x11);
202 default:
203 return -EINVAL;
204 };
205}
206
207static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_cmd_t burst)
208{
209 switch (burst) {
210 case SEC_MINI_A:
211 tda8083_writereg (state, 0x29, (5 << 2)); /* send burst A */
212 break;
213 case SEC_MINI_B:
214 tda8083_writereg (state, 0x29, (7 << 2)); /* send B */
215 break;
216 default:
217 return -EINVAL;
218 };
219
220 tda8083_wait_diseqc_fifo (state, 100);
221
222 return 0;
223}
224
225static int tda8083_send_diseqc_msg (struct dvb_frontend* fe,
226 struct dvb_diseqc_master_cmd *m)
227{
228 struct tda8083_state* state = fe->demodulator_priv;
229 int i;
230
231 tda8083_writereg (state, 0x29, (m->msg_len - 3) | (1 << 2)); /* enable */
232
233 for (i=0; i<m->msg_len; i++)
234 tda8083_writereg (state, 0x23 + i, m->msg[i]);
235
236 tda8083_writereg (state, 0x29, (m->msg_len - 3) | (3 << 2)); /* send!! */
237
238 tda8083_wait_diseqc_fifo (state, 100);
239
240 return 0;
241}
242
243static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status)
244{
245 struct tda8083_state* state = fe->demodulator_priv;
246
247 u8 signal = ~tda8083_readreg (state, 0x01);
248 u8 sync = tda8083_readreg (state, 0x02);
249
250 *status = 0;
251
252 if (signal > 10)
253 *status |= FE_HAS_SIGNAL;
254
255 if (sync & 0x01)
256 *status |= FE_HAS_CARRIER;
257
258 if (sync & 0x02)
259 *status |= FE_HAS_VITERBI;
260
261 if (sync & 0x10)
262 *status |= FE_HAS_SYNC;
263
264 if (sync & 0x20) /* frontend can not lock */
265 *status |= FE_TIMEDOUT;
266
267 if ((sync & 0x1f) == 0x1f)
268 *status |= FE_HAS_LOCK;
269
270 return 0;
271}
272
273static int tda8083_read_ber(struct dvb_frontend* fe, u32* ber)
274{
275 struct tda8083_state* state = fe->demodulator_priv;
276 int ret;
277 u8 buf[3];
278
279 if ((ret = tda8083_readregs(state, 0x0b, buf, sizeof(buf))))
280 return ret;
281
282 *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2];
283
284 return 0;
285}
286
287static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength)
288{
289 struct tda8083_state* state = fe->demodulator_priv;
290
291 u8 signal = ~tda8083_readreg (state, 0x01);
292 *strength = (signal << 8) | signal;
293
294 return 0;
295}
296
297static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr)
298{
299 struct tda8083_state* state = fe->demodulator_priv;
300
301 u8 _snr = tda8083_readreg (state, 0x08);
302 *snr = (_snr << 8) | _snr;
303
304 return 0;
305}
306
307static int tda8083_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
308{
309 struct tda8083_state* state = fe->demodulator_priv;
310
311 *ucblocks = tda8083_readreg(state, 0x0f);
312 if (*ucblocks == 0xff)
313 *ucblocks = 0xffffffff;
314
315 return 0;
316}
317
318static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
319{
320 struct tda8083_state* state = fe->demodulator_priv;
321
322 if (fe->ops.tuner_ops.set_params) {
323 fe->ops.tuner_ops.set_params(fe, p);
324 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
325 }
326
327 tda8083_set_inversion (state, p->inversion);
328 tda8083_set_fec (state, p->u.qpsk.fec_inner);
329 tda8083_set_symbolrate (state, p->u.qpsk.symbol_rate);
330
331 tda8083_writereg (state, 0x00, 0x3c);
332 tda8083_writereg (state, 0x00, 0x04);
333
334 return 0;
335}
336
337static int tda8083_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
338{
339 struct tda8083_state* state = fe->demodulator_priv;
340
341 /* FIXME: get symbolrate & frequency offset...*/
342 /*p->frequency = ???;*/
343 p->inversion = (tda8083_readreg (state, 0x0e) & 0x80) ?
344 INVERSION_ON : INVERSION_OFF;
345 p->u.qpsk.fec_inner = tda8083_get_fec (state);
346 /*p->u.qpsk.symbol_rate = tda8083_get_symbolrate (state);*/
347
348 return 0;
349}
350
351static int tda8083_sleep(struct dvb_frontend* fe)
352{
353 struct tda8083_state* state = fe->demodulator_priv;
354
355 tda8083_writereg (state, 0x00, 0x02);
356 return 0;
357}
358
359static int tda8083_init(struct dvb_frontend* fe)
360{
361 struct tda8083_state* state = fe->demodulator_priv;
362 int i;
363
364 for (i=0; i<44; i++)
365 tda8083_writereg (state, i, tda8083_init_tab[i]);
366
367 tda8083_writereg (state, 0x00, 0x3c);
368 tda8083_writereg (state, 0x00, 0x04);
369
370 return 0;
371}
372
373static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
374{
375 struct tda8083_state* state = fe->demodulator_priv;
376
377 tda8083_send_diseqc_burst (state, burst);
378 tda8083_writereg (state, 0x00, 0x3c);
379 tda8083_writereg (state, 0x00, 0x04);
380
381 return 0;
382}
383
384static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
385{
386 struct tda8083_state* state = fe->demodulator_priv;
387
388 tda8083_set_tone (state, tone);
389 tda8083_writereg (state, 0x00, 0x3c);
390 tda8083_writereg (state, 0x00, 0x04);
391
392 return 0;
393}
394
395static int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
396{
397 struct tda8083_state* state = fe->demodulator_priv;
398
399 tda8083_set_voltage (state, voltage);
400 tda8083_writereg (state, 0x00, 0x3c);
401 tda8083_writereg (state, 0x00, 0x04);
402
403 return 0;
404}
405
406static void tda8083_release(struct dvb_frontend* fe)
407{
408 struct tda8083_state* state = fe->demodulator_priv;
409 kfree(state);
410}
411
412static struct dvb_frontend_ops tda8083_ops;
413
414struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
415 struct i2c_adapter* i2c)
416{
417 struct tda8083_state* state = NULL;
418
419 /* allocate memory for the internal state */
420 state = kzalloc(sizeof(struct tda8083_state), GFP_KERNEL);
421 if (state == NULL) goto error;
422
423 /* setup the state */
424 state->config = config;
425 state->i2c = i2c;
426
427 /* check if the demod is there */
428 if ((tda8083_readreg(state, 0x00)) != 0x05) goto error;
429
430 /* create dvb_frontend */
431 memcpy(&state->frontend.ops, &tda8083_ops, sizeof(struct dvb_frontend_ops));
432 state->frontend.demodulator_priv = state;
433 return &state->frontend;
434
435error:
436 kfree(state);
437 return NULL;
438}
439
440static struct dvb_frontend_ops tda8083_ops = {
441
442 .info = {
443 .name = "Philips TDA8083 DVB-S",
444 .type = FE_QPSK,
445 .frequency_min = 920000, /* TDA8060 */
446 .frequency_max = 2200000, /* TDA8060 */
447 .frequency_stepsize = 125, /* kHz for QPSK frontends */
448 /* .frequency_tolerance = ???,*/
449 .symbol_rate_min = 12000000,
450 .symbol_rate_max = 30000000,
451 /* .symbol_rate_tolerance = ???,*/
452 .caps = FE_CAN_INVERSION_AUTO |
453 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
454 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
455 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
456 FE_CAN_QPSK | FE_CAN_MUTE_TS
457 },
458
459 .release = tda8083_release,
460
461 .init = tda8083_init,
462 .sleep = tda8083_sleep,
463
464 .set_frontend = tda8083_set_frontend,
465 .get_frontend = tda8083_get_frontend,
466
467 .read_status = tda8083_read_status,
468 .read_signal_strength = tda8083_read_signal_strength,
469 .read_snr = tda8083_read_snr,
470 .read_ber = tda8083_read_ber,
471 .read_ucblocks = tda8083_read_ucblocks,
472
473 .diseqc_send_master_cmd = tda8083_send_diseqc_msg,
474 .diseqc_send_burst = tda8083_diseqc_send_burst,
475 .set_tone = tda8083_diseqc_set_tone,
476 .set_voltage = tda8083_diseqc_set_voltage,
477};
478
479module_param(debug, int, 0644);
480MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
481
482MODULE_DESCRIPTION("Philips TDA8083 DVB-S Demodulator");
483MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
484MODULE_LICENSE("GPL");
485
486EXPORT_SYMBOL(tda8083_attach);
diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h
new file mode 100644
index 00000000000..5a03c14a10e
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8083.h
@@ -0,0 +1,50 @@
1/*
2 Driver for Grundig 29504-491, a Philips TDA8083 based QPSK Frontend
3
4 Copyright (C) 2001 Convergence Integrated Media GmbH
5
6 written by Ralph Metzler <ralph@convergence.de>
7
8 adoption to the new DVB frontend API and diagnostic ioctl's
9 by Holger Waechtler <holger@convergence.de>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/
26
27#ifndef TDA8083_H
28#define TDA8083_H
29
30#include <linux/dvb/frontend.h>
31
32struct tda8083_config
33{
34 /* the demodulator's i2c address */
35 u8 demod_address;
36};
37
38#if defined(CONFIG_DVB_TDA8083) || (defined(CONFIG_DVB_TDA8083_MODULE) && defined(MODULE))
39extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
40 struct i2c_adapter* i2c);
41#else
42static inline struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
43 struct i2c_adapter* i2c)
44{
45 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
46 return NULL;
47}
48#endif // CONFIG_DVB_TDA8083
49
50#endif // TDA8083_H
diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb/frontends/tda8261.c
new file mode 100644
index 00000000000..53c7d8f1df2
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8261.c
@@ -0,0 +1,230 @@
1/*
2 TDA8261 8PSK/QPSK tuner driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 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
21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/slab.h>
25
26#include "dvb_frontend.h"
27#include "tda8261.h"
28
29struct tda8261_state {
30 struct dvb_frontend *fe;
31 struct i2c_adapter *i2c;
32 const struct tda8261_config *config;
33
34 /* state cache */
35 u32 frequency;
36 u32 bandwidth;
37};
38
39static int tda8261_read(struct tda8261_state *state, u8 *buf)
40{
41 const struct tda8261_config *config = state->config;
42 int err = 0;
43 struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD,.buf = buf, .len = 1 };
44
45 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
46 printk("%s: read error, err=%d\n", __func__, err);
47
48 return err;
49}
50
51static int tda8261_write(struct tda8261_state *state, u8 *buf)
52{
53 const struct tda8261_config *config = state->config;
54 int err = 0;
55 struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = 4 };
56
57 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1)
58 printk("%s: write error, err=%d\n", __func__, err);
59
60 return err;
61}
62
63static int tda8261_get_status(struct dvb_frontend *fe, u32 *status)
64{
65 struct tda8261_state *state = fe->tuner_priv;
66 u8 result = 0;
67 int err = 0;
68
69 *status = 0;
70
71 if ((err = tda8261_read(state, &result)) < 0) {
72 printk("%s: I/O Error\n", __func__);
73 return err;
74 }
75 if ((result >> 6) & 0x01) {
76 printk("%s: Tuner Phase Locked\n", __func__);
77 *status = 1;
78 }
79
80 return err;
81}
82
83static const u32 div_tab[] = { 2000, 1000, 500, 250, 125 }; /* kHz */
84static const u8 ref_div[] = { 0x00, 0x01, 0x02, 0x05, 0x07 };
85
86static int tda8261_get_state(struct dvb_frontend *fe,
87 enum tuner_param param,
88 struct tuner_state *tstate)
89{
90 struct tda8261_state *state = fe->tuner_priv;
91 int err = 0;
92
93 switch (param) {
94 case DVBFE_TUNER_FREQUENCY:
95 tstate->frequency = state->frequency;
96 break;
97 case DVBFE_TUNER_BANDWIDTH:
98 tstate->bandwidth = 40000000; /* FIXME! need to calculate Bandwidth */
99 break;
100 default:
101 printk("%s: Unknown parameter (param=%d)\n", __func__, param);
102 err = -EINVAL;
103 break;
104 }
105
106 return err;
107}
108
109static int tda8261_set_state(struct dvb_frontend *fe,
110 enum tuner_param param,
111 struct tuner_state *tstate)
112{
113 struct tda8261_state *state = fe->tuner_priv;
114 const struct tda8261_config *config = state->config;
115 u32 frequency, N, status = 0;
116 u8 buf[4];
117 int err = 0;
118
119 if (param & DVBFE_TUNER_FREQUENCY) {
120 /**
121 * N = Max VCO Frequency / Channel Spacing
122 * Max VCO Frequency = VCO frequency + (channel spacing - 1)
123 * (to account for half channel spacing on either side)
124 */
125 frequency = tstate->frequency;
126 if ((frequency < 950000) || (frequency > 2150000)) {
127 printk("%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
128 return -EINVAL;
129 }
130 N = (frequency + (div_tab[config->step_size] - 1)) / div_tab[config->step_size];
131 printk("%s: Step size=%d, Divider=%d, PG=0x%02x (%d)\n",
132 __func__, config->step_size, div_tab[config->step_size], N, N);
133
134 buf[0] = (N >> 8) & 0xff;
135 buf[1] = N & 0xff;
136 buf[2] = (0x01 << 7) | ((ref_div[config->step_size] & 0x07) << 1);
137
138 if (frequency < 1450000)
139 buf[3] = 0x00;
140 else if (frequency < 2000000)
141 buf[3] = 0x40;
142 else if (frequency < 2150000)
143 buf[3] = 0x80;
144
145 /* Set params */
146 if ((err = tda8261_write(state, buf)) < 0) {
147 printk("%s: I/O Error\n", __func__);
148 return err;
149 }
150 /* sleep for some time */
151 printk("%s: Waiting to Phase LOCK\n", __func__);
152 msleep(20);
153 /* check status */
154 if ((err = tda8261_get_status(fe, &status)) < 0) {
155 printk("%s: I/O Error\n", __func__);
156 return err;
157 }
158 if (status == 1) {
159 printk("%s: Tuner Phase locked: status=%d\n", __func__, status);
160 state->frequency = frequency; /* cache successful state */
161 } else {
162 printk("%s: No Phase lock: status=%d\n", __func__, status);
163 }
164 } else {
165 printk("%s: Unknown parameter (param=%d)\n", __func__, param);
166 return -EINVAL;
167 }
168
169 return 0;
170}
171
172static int tda8261_release(struct dvb_frontend *fe)
173{
174 struct tda8261_state *state = fe->tuner_priv;
175
176 fe->tuner_priv = NULL;
177 kfree(state);
178 return 0;
179}
180
181static struct dvb_tuner_ops tda8261_ops = {
182
183 .info = {
184 .name = "TDA8261",
185// .tuner_name = NULL,
186 .frequency_min = 950000,
187 .frequency_max = 2150000,
188 .frequency_step = 0
189 },
190
191 .set_state = tda8261_set_state,
192 .get_state = tda8261_get_state,
193 .get_status = tda8261_get_status,
194 .release = tda8261_release
195};
196
197struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
198 const struct tda8261_config *config,
199 struct i2c_adapter *i2c)
200{
201 struct tda8261_state *state = NULL;
202
203 if ((state = kzalloc(sizeof (struct tda8261_state), GFP_KERNEL)) == NULL)
204 goto exit;
205
206 state->config = config;
207 state->i2c = i2c;
208 state->fe = fe;
209 fe->tuner_priv = state;
210 fe->ops.tuner_ops = tda8261_ops;
211
212 fe->ops.tuner_ops.info.frequency_step = div_tab[config->step_size];
213// fe->ops.tuner_ops.tuner_name = &config->buf;
214
215// printk("%s: Attaching %s TDA8261 8PSK/QPSK tuner\n",
216// __func__, fe->ops.tuner_ops.tuner_name);
217 printk("%s: Attaching TDA8261 8PSK/QPSK tuner\n", __func__);
218
219 return fe;
220
221exit:
222 kfree(state);
223 return NULL;
224}
225
226EXPORT_SYMBOL(tda8261_attach);
227
228MODULE_AUTHOR("Manu Abraham");
229MODULE_DESCRIPTION("TDA8261 8PSK/QPSK Tuner");
230MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda8261.h b/drivers/media/dvb/frontends/tda8261.h
new file mode 100644
index 00000000000..006e45351b9
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8261.h
@@ -0,0 +1,55 @@
1/*
2 TDA8261 8PSK/QPSK tuner driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 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 __TDA8261_H
21#define __TDA8261_H
22
23enum tda8261_step {
24 TDA8261_STEP_2000 = 0, /* 2000 kHz */
25 TDA8261_STEP_1000, /* 1000 kHz */
26 TDA8261_STEP_500, /* 500 kHz */
27 TDA8261_STEP_250, /* 250 kHz */
28 TDA8261_STEP_125 /* 125 kHz */
29};
30
31struct tda8261_config {
32// u8 buf[16];
33 u8 addr;
34 enum tda8261_step step_size;
35};
36
37#if defined(CONFIG_DVB_TDA8261) || (defined(CONFIG_DVB_TDA8261_MODULE) && defined(MODULE))
38
39extern struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
40 const struct tda8261_config *config,
41 struct i2c_adapter *i2c);
42
43#else
44
45static inline struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe,
46 const struct tda8261_config *config,
47 struct i2c_adapter *i2c)
48{
49 printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
50 return NULL;
51}
52
53#endif //CONFIG_DVB_TDA8261
54
55#endif// __TDA8261_H
diff --git a/drivers/media/dvb/frontends/tda8261_cfg.h b/drivers/media/dvb/frontends/tda8261_cfg.h
new file mode 100644
index 00000000000..1af1ee49b54
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda8261_cfg.h
@@ -0,0 +1,84 @@
1/*
2 TDA8261 8PSK/QPSK tuner driver
3 Copyright (C) Manu Abraham (abraham.manu@gmail.com)
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 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
20static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency)
21{
22 struct dvb_frontend_ops *frontend_ops = NULL;
23 struct dvb_tuner_ops *tuner_ops = NULL;
24 struct tuner_state t_state;
25 int err = 0;
26
27 if (&fe->ops)
28 frontend_ops = &fe->ops;
29 if (&frontend_ops->tuner_ops)
30 tuner_ops = &frontend_ops->tuner_ops;
31 if (tuner_ops->get_state) {
32 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
33 printk("%s: Invalid parameter\n", __func__);
34 return err;
35 }
36 *frequency = t_state.frequency;
37 printk("%s: Frequency=%d\n", __func__, t_state.frequency);
38 }
39 return 0;
40}
41
42static int tda8261_set_frequency(struct dvb_frontend *fe, u32 frequency)
43{
44 struct dvb_frontend_ops *frontend_ops = NULL;
45 struct dvb_tuner_ops *tuner_ops = NULL;
46 struct tuner_state t_state;
47 int err = 0;
48
49 t_state.frequency = frequency;
50 if (&fe->ops)
51 frontend_ops = &fe->ops;
52 if (&frontend_ops->tuner_ops)
53 tuner_ops = &frontend_ops->tuner_ops;
54 if (tuner_ops->set_state) {
55 if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) {
56 printk("%s: Invalid parameter\n", __func__);
57 return err;
58 }
59 }
60 printk("%s: Frequency=%d\n", __func__, t_state.frequency);
61 return 0;
62}
63
64static int tda8261_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
65{
66 struct dvb_frontend_ops *frontend_ops = &fe->ops;
67 struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops;
68 struct tuner_state t_state;
69 int err = 0;
70
71 if (&fe->ops)
72 frontend_ops = &fe->ops;
73 if (&frontend_ops->tuner_ops)
74 tuner_ops = &frontend_ops->tuner_ops;
75 if (tuner_ops->get_state) {
76 if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) {
77 printk("%s: Invalid parameter\n", __func__);
78 return err;
79 }
80 *bandwidth = t_state.bandwidth;
81 }
82 printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
83 return 0;
84}
diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c
new file mode 100644
index 00000000000..06c94800b94
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda826x.c
@@ -0,0 +1,187 @@
1 /*
2 Driver for Philips tda8262/tda8263 DVBS Silicon tuners
3
4 (c) 2006 Andrew de Quincey
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23#include <linux/slab.h>
24#include <linux/module.h>
25#include <linux/dvb/frontend.h>
26#include <asm/types.h>
27
28#include "tda826x.h"
29
30static int debug;
31#define dprintk(args...) \
32 do { \
33 if (debug) printk(KERN_DEBUG "tda826x: " args); \
34 } while (0)
35
36struct tda826x_priv {
37 /* i2c details */
38 int i2c_address;
39 struct i2c_adapter *i2c;
40 u8 has_loopthrough:1;
41 u32 frequency;
42};
43
44static int tda826x_release(struct dvb_frontend *fe)
45{
46 kfree(fe->tuner_priv);
47 fe->tuner_priv = NULL;
48 return 0;
49}
50
51static int tda826x_sleep(struct dvb_frontend *fe)
52{
53 struct tda826x_priv *priv = fe->tuner_priv;
54 int ret;
55 u8 buf [] = { 0x00, 0x8d };
56 struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 2 };
57
58 dprintk("%s:\n", __func__);
59
60 if (!priv->has_loopthrough)
61 buf[1] = 0xad;
62
63 if (fe->ops.i2c_gate_ctrl)
64 fe->ops.i2c_gate_ctrl(fe, 1);
65 if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
66 dprintk("%s: i2c error\n", __func__);
67 }
68 if (fe->ops.i2c_gate_ctrl)
69 fe->ops.i2c_gate_ctrl(fe, 0);
70
71 return (ret == 1) ? 0 : ret;
72}
73
74static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
75{
76 struct tda826x_priv *priv = fe->tuner_priv;
77 int ret;
78 u32 div;
79 u32 ksyms;
80 u32 bandwidth;
81 u8 buf [11];
82 struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 11 };
83
84 dprintk("%s:\n", __func__);
85
86 div = (params->frequency + (1000-1)) / 1000;
87
88 /* BW = ((1 + RO) * SR/2 + 5) * 1.3 [SR in MSPS, BW in MHz] */
89 /* with R0 = 0.35 and some transformations: */
90 ksyms = params->u.qpsk.symbol_rate / 1000;
91 bandwidth = (878 * ksyms + 6500000) / 1000000 + 1;
92 if (bandwidth < 5)
93 bandwidth = 5;
94 else if (bandwidth > 36)
95 bandwidth = 36;
96
97 buf[0] = 0x00; // subaddress
98 buf[1] = 0x09; // powerdown RSSI + the magic value 1
99 if (!priv->has_loopthrough)
100 buf[1] |= 0x20; // power down loopthrough if not needed
101 buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO
102 buf[3] = div >> 7;
103 buf[4] = div << 1;
104 buf[5] = ((bandwidth - 5) << 3) | 7; /* baseband cut-off */
105 buf[6] = 0xfe; // baseband gain 9 db + no RF attenuation
106 buf[7] = 0x83; // charge pumps at high, tests off
107 buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports.
108 buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL
109 buf[10] = 0xd4; // recommended value 13 for BBIAS + unknown bit set on
110
111 if (fe->ops.i2c_gate_ctrl)
112 fe->ops.i2c_gate_ctrl(fe, 1);
113 if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
114 dprintk("%s: i2c error\n", __func__);
115 }
116 if (fe->ops.i2c_gate_ctrl)
117 fe->ops.i2c_gate_ctrl(fe, 0);
118
119 priv->frequency = div * 1000;
120
121 return (ret == 1) ? 0 : ret;
122}
123
124static int tda826x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
125{
126 struct tda826x_priv *priv = fe->tuner_priv;
127 *frequency = priv->frequency;
128 return 0;
129}
130
131static struct dvb_tuner_ops tda826x_tuner_ops = {
132 .info = {
133 .name = "Philips TDA826X",
134 .frequency_min = 950000,
135 .frequency_max = 2175000
136 },
137 .release = tda826x_release,
138 .sleep = tda826x_sleep,
139 .set_params = tda826x_set_params,
140 .get_frequency = tda826x_get_frequency,
141};
142
143struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough)
144{
145 struct tda826x_priv *priv = NULL;
146 u8 b1 [] = { 0, 0 };
147 struct i2c_msg msg[2] = {
148 { .addr = addr, .flags = 0, .buf = NULL, .len = 0 },
149 { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 }
150 };
151 int ret;
152
153 dprintk("%s:\n", __func__);
154
155 if (fe->ops.i2c_gate_ctrl)
156 fe->ops.i2c_gate_ctrl(fe, 1);
157 ret = i2c_transfer (i2c, msg, 2);
158 if (fe->ops.i2c_gate_ctrl)
159 fe->ops.i2c_gate_ctrl(fe, 0);
160
161 if (ret != 2)
162 return NULL;
163 if (!(b1[1] & 0x80))
164 return NULL;
165
166 priv = kzalloc(sizeof(struct tda826x_priv), GFP_KERNEL);
167 if (priv == NULL)
168 return NULL;
169
170 priv->i2c_address = addr;
171 priv->i2c = i2c;
172 priv->has_loopthrough = has_loopthrough;
173
174 memcpy(&fe->ops.tuner_ops, &tda826x_tuner_ops, sizeof(struct dvb_tuner_ops));
175
176 fe->tuner_priv = priv;
177
178 return fe;
179}
180EXPORT_SYMBOL(tda826x_attach);
181
182module_param(debug, int, 0644);
183MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
184
185MODULE_DESCRIPTION("DVB TDA826x driver");
186MODULE_AUTHOR("Andrew de Quincey");
187MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda826x.h b/drivers/media/dvb/frontends/tda826x.h
new file mode 100644
index 00000000000..89e97926ab2
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda826x.h
@@ -0,0 +1,53 @@
1 /*
2 Driver for Philips tda8262/tda8263 DVBS Silicon tuners
3
4 (c) 2006 Andrew de Quincey
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23#ifndef __DVB_TDA826X_H__
24#define __DVB_TDA826X_H__
25
26#include <linux/i2c.h>
27#include "dvb_frontend.h"
28
29/**
30 * Attach a tda826x tuner to the supplied frontend structure.
31 *
32 * @param fe Frontend to attach to.
33 * @param addr i2c address of the tuner.
34 * @param i2c i2c adapter to use.
35 * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector.
36 * @return FE pointer on success, NULL on failure.
37 */
38#if defined(CONFIG_DVB_TDA826X) || (defined(CONFIG_DVB_TDA826X_MODULE) && defined(MODULE))
39extern struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, int addr,
40 struct i2c_adapter *i2c,
41 int has_loopthrough);
42#else
43static inline struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe,
44 int addr,
45 struct i2c_adapter *i2c,
46 int has_loopthrough)
47{
48 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
49 return NULL;
50}
51#endif // CONFIG_DVB_TDA826X
52
53#endif // __DVB_TDA826X_H__
diff --git a/drivers/media/dvb/frontends/tdhd1.h b/drivers/media/dvb/frontends/tdhd1.h
new file mode 100644
index 00000000000..51f17067865
--- /dev/null
+++ b/drivers/media/dvb/frontends/tdhd1.h
@@ -0,0 +1,73 @@
1/*
2 * tdhd1.h - ALPS TDHD1-204A tuner support
3 *
4 * Copyright (C) 2008 Oliver Endriss <o.endriss@gmx.de>
5 *
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
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (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 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
21 *
22 *
23 * The project's page is at http://www.linuxtv.org
24 */
25
26#ifndef TDHD1_H
27#define TDHD1_H
28
29#include "tda1004x.h"
30
31static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name);
32
33static struct tda1004x_config alps_tdhd1_204a_config = {
34 .demod_address = 0x8,
35 .invert = 1,
36 .invert_oclk = 0,
37 .xtal_freq = TDA10046_XTAL_4M,
38 .agc_config = TDA10046_AGC_DEFAULT,
39 .if_freq = TDA10046_FREQ_3617,
40 .request_firmware = alps_tdhd1_204_request_firmware
41};
42
43static int alps_tdhd1_204a_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
44{
45 struct i2c_adapter *i2c = fe->tuner_priv;
46 u8 data[4];
47 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
48 u32 div;
49
50 div = (params->frequency + 36166666) / 166666;
51
52 data[0] = (div >> 8) & 0x7f;
53 data[1] = div & 0xff;
54 data[2] = 0x85;
55
56 if (params->frequency >= 174000000 && params->frequency <= 230000000)
57 data[3] = 0x02;
58 else if (params->frequency >= 470000000 && params->frequency <= 823000000)
59 data[3] = 0x0C;
60 else if (params->frequency > 823000000 && params->frequency <= 862000000)
61 data[3] = 0x8C;
62 else
63 return -EINVAL;
64
65 if (fe->ops.i2c_gate_ctrl)
66 fe->ops.i2c_gate_ctrl(fe, 1);
67 if (i2c_transfer(i2c, &msg, 1) != 1)
68 return -EIO;
69
70 return 0;
71}
72
73#endif /* TDHD1_H */
diff --git a/drivers/media/dvb/frontends/tua6100.c b/drivers/media/dvb/frontends/tua6100.c
new file mode 100644
index 00000000000..bcb95c2ef29
--- /dev/null
+++ b/drivers/media/dvb/frontends/tua6100.c
@@ -0,0 +1,205 @@
1/**
2 * Driver for Infineon tua6100 pll.
3 *
4 * (c) 2006 Andrew de Quincey
5 *
6 * Based on code found in budget-av.c, which has the following:
7 * Compiled from various sources by Michael Hunold <michael@mihu.de>
8 *
9 * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
10 * Andrew de Quincey <adq_dvb@lidskialf.net>
11 *
12 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
13 *
14 * Copyright (C) 1999-2002 Ralph Metzler
15 * & Marcus Metzler for convergence integrated media GmbH
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include <linux/slab.h>
32#include <linux/module.h>
33#include <linux/dvb/frontend.h>
34#include <asm/types.h>
35
36#include "tua6100.h"
37
38struct tua6100_priv {
39 /* i2c details */
40 int i2c_address;
41 struct i2c_adapter *i2c;
42 u32 frequency;
43};
44
45static int tua6100_release(struct dvb_frontend *fe)
46{
47 kfree(fe->tuner_priv);
48 fe->tuner_priv = NULL;
49 return 0;
50}
51
52static int tua6100_sleep(struct dvb_frontend *fe)
53{
54 struct tua6100_priv *priv = fe->tuner_priv;
55 int ret;
56 u8 reg0[] = { 0x00, 0x00 };
57 struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = reg0, .len = 2 };
58
59 if (fe->ops.i2c_gate_ctrl)
60 fe->ops.i2c_gate_ctrl(fe, 1);
61 if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
62 printk("%s: i2c error\n", __func__);
63 }
64 if (fe->ops.i2c_gate_ctrl)
65 fe->ops.i2c_gate_ctrl(fe, 0);
66
67 return (ret == 1) ? 0 : ret;
68}
69
70static int tua6100_set_params(struct dvb_frontend *fe,
71 struct dvb_frontend_parameters *params)
72{
73 struct tua6100_priv *priv = fe->tuner_priv;
74 u32 div;
75 u32 prediv;
76 u8 reg0[] = { 0x00, 0x00 };
77 u8 reg1[] = { 0x01, 0x00, 0x00, 0x00 };
78 u8 reg2[] = { 0x02, 0x00, 0x00 };
79 struct i2c_msg msg0 = { .addr = priv->i2c_address, .flags = 0, .buf = reg0, .len = 2 };
80 struct i2c_msg msg1 = { .addr = priv->i2c_address, .flags = 0, .buf = reg1, .len = 4 };
81 struct i2c_msg msg2 = { .addr = priv->i2c_address, .flags = 0, .buf = reg2, .len = 3 };
82
83#define _R 4
84#define _P 32
85#define _ri 4000000
86
87 // setup register 0
88 if (params->frequency < 2000000) {
89 reg0[1] = 0x03;
90 } else {
91 reg0[1] = 0x07;
92 }
93
94 // setup register 1
95 if (params->frequency < 1630000) {
96 reg1[1] = 0x2c;
97 } else {
98 reg1[1] = 0x0c;
99 }
100 if (_P == 64)
101 reg1[1] |= 0x40;
102 if (params->frequency >= 1525000)
103 reg1[1] |= 0x80;
104
105 // register 2
106 reg2[1] = (_R >> 8) & 0x03;
107 reg2[2] = _R;
108 if (params->frequency < 1455000) {
109 reg2[1] |= 0x1c;
110 } else if (params->frequency < 1630000) {
111 reg2[1] |= 0x0c;
112 } else {
113 reg2[1] |= 0x1c;
114 }
115
116 // The N divisor ratio (note: params->frequency is in kHz, but we need it in Hz)
117 prediv = (params->frequency * _R) / (_ri / 1000);
118 div = prediv / _P;
119 reg1[1] |= (div >> 9) & 0x03;
120 reg1[2] = div >> 1;
121 reg1[3] = (div << 7);
122 priv->frequency = ((div * _P) * (_ri / 1000)) / _R;
123
124 // Finally, calculate and store the value for A
125 reg1[3] |= (prediv - (div*_P)) & 0x7f;
126
127#undef _R
128#undef _P
129#undef _ri
130
131 if (fe->ops.i2c_gate_ctrl)
132 fe->ops.i2c_gate_ctrl(fe, 1);
133 if (i2c_transfer(priv->i2c, &msg0, 1) != 1)
134 return -EIO;
135
136 if (fe->ops.i2c_gate_ctrl)
137 fe->ops.i2c_gate_ctrl(fe, 1);
138 if (i2c_transfer(priv->i2c, &msg2, 1) != 1)
139 return -EIO;
140
141 if (fe->ops.i2c_gate_ctrl)
142 fe->ops.i2c_gate_ctrl(fe, 1);
143 if (i2c_transfer(priv->i2c, &msg1, 1) != 1)
144 return -EIO;
145
146 if (fe->ops.i2c_gate_ctrl)
147 fe->ops.i2c_gate_ctrl(fe, 0);
148
149 return 0;
150}
151
152static int tua6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
153{
154 struct tua6100_priv *priv = fe->tuner_priv;
155 *frequency = priv->frequency;
156 return 0;
157}
158
159static struct dvb_tuner_ops tua6100_tuner_ops = {
160 .info = {
161 .name = "Infineon TUA6100",
162 .frequency_min = 950000,
163 .frequency_max = 2150000,
164 .frequency_step = 1000,
165 },
166 .release = tua6100_release,
167 .sleep = tua6100_sleep,
168 .set_params = tua6100_set_params,
169 .get_frequency = tua6100_get_frequency,
170};
171
172struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c)
173{
174 struct tua6100_priv *priv = NULL;
175 u8 b1 [] = { 0x80 };
176 u8 b2 [] = { 0x00 };
177 struct i2c_msg msg [] = { { .addr = addr, .flags = 0, .buf = b1, .len = 1 },
178 { .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 } };
179 int ret;
180
181 if (fe->ops.i2c_gate_ctrl)
182 fe->ops.i2c_gate_ctrl(fe, 1);
183 ret = i2c_transfer (i2c, msg, 2);
184 if (fe->ops.i2c_gate_ctrl)
185 fe->ops.i2c_gate_ctrl(fe, 0);
186
187 if (ret != 2)
188 return NULL;
189
190 priv = kzalloc(sizeof(struct tua6100_priv), GFP_KERNEL);
191 if (priv == NULL)
192 return NULL;
193
194 priv->i2c_address = addr;
195 priv->i2c = i2c;
196
197 memcpy(&fe->ops.tuner_ops, &tua6100_tuner_ops, sizeof(struct dvb_tuner_ops));
198 fe->tuner_priv = priv;
199 return fe;
200}
201EXPORT_SYMBOL(tua6100_attach);
202
203MODULE_DESCRIPTION("DVB tua6100 driver");
204MODULE_AUTHOR("Andrew de Quincey");
205MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tua6100.h b/drivers/media/dvb/frontends/tua6100.h
new file mode 100644
index 00000000000..f83dbd5e42a
--- /dev/null
+++ b/drivers/media/dvb/frontends/tua6100.h
@@ -0,0 +1,47 @@
1/**
2 * Driver for Infineon tua6100 PLL.
3 *
4 * (c) 2006 Andrew de Quincey
5 *
6 * Based on code found in budget-av.c, which has the following:
7 * Compiled from various sources by Michael Hunold <michael@mihu.de>
8 *
9 * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
10 * Andrew de Quincey <adq_dvb@lidskialf.net>
11 *
12 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
13 *
14 * Copyright (C) 1999-2002 Ralph Metzler
15 * & Marcus Metzler for convergence integrated media GmbH
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#ifndef __DVB_TUA6100_H__
32#define __DVB_TUA6100_H__
33
34#include <linux/i2c.h>
35#include "dvb_frontend.h"
36
37#if defined(CONFIG_DVB_TUA6100) || (defined(CONFIG_DVB_TUA6100_MODULE) && defined(MODULE))
38extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c);
39#else
40static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c)
41{
42 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
43 return NULL;
44}
45#endif // CONFIG_DVB_TUA6100
46
47#endif
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c
new file mode 100644
index 00000000000..550a07a8a99
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1820.c
@@ -0,0 +1,446 @@
1/*
2 VES1820 - Single Chip Cable Channel Receiver driver module
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
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 <linux/delay.h>
22#include <linux/errno.h>
23#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28#include <asm/div64.h>
29
30#include "dvb_frontend.h"
31#include "ves1820.h"
32
33
34
35struct ves1820_state {
36 struct i2c_adapter* i2c;
37 /* configuration settings */
38 const struct ves1820_config* config;
39 struct dvb_frontend frontend;
40
41 /* private demodulator data */
42 u8 reg0;
43 u8 pwm;
44};
45
46
47static int verbose;
48
49static u8 ves1820_inittab[] = {
50 0x69, 0x6A, 0x93, 0x1A, 0x12, 0x46, 0x26, 0x1A,
51 0x43, 0x6A, 0xAA, 0xAA, 0x1E, 0x85, 0x43, 0x20,
52 0xE0, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
54 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x00, 0x40
57};
58
59static int ves1820_writereg(struct ves1820_state *state, u8 reg, u8 data)
60{
61 u8 buf[] = { 0x00, reg, data };
62 struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 3 };
63 int ret;
64
65 ret = i2c_transfer(state->i2c, &msg, 1);
66
67 if (ret != 1)
68 printk("ves1820: %s(): writereg error (reg == 0x%02x, "
69 "val == 0x%02x, ret == %i)\n", __func__, reg, data, ret);
70
71 return (ret != 1) ? -EREMOTEIO : 0;
72}
73
74static u8 ves1820_readreg(struct ves1820_state *state, u8 reg)
75{
76 u8 b0[] = { 0x00, reg };
77 u8 b1[] = { 0 };
78 struct i2c_msg msg[] = {
79 {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 2},
80 {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
81 };
82 int ret;
83
84 ret = i2c_transfer(state->i2c, msg, 2);
85
86 if (ret != 2)
87 printk("ves1820: %s(): readreg error (reg == 0x%02x, "
88 "ret == %i)\n", __func__, reg, ret);
89
90 return b1[0];
91}
92
93static int ves1820_setup_reg0(struct ves1820_state *state, u8 reg0, fe_spectral_inversion_t inversion)
94{
95 reg0 |= state->reg0 & 0x62;
96
97 if (INVERSION_ON == inversion) {
98 if (!state->config->invert) reg0 |= 0x20;
99 else reg0 &= ~0x20;
100 } else if (INVERSION_OFF == inversion) {
101 if (!state->config->invert) reg0 &= ~0x20;
102 else reg0 |= 0x20;
103 }
104
105 ves1820_writereg(state, 0x00, reg0 & 0xfe);
106 ves1820_writereg(state, 0x00, reg0 | 0x01);
107
108 state->reg0 = reg0;
109
110 return 0;
111}
112
113static int ves1820_set_symbolrate(struct ves1820_state *state, u32 symbolrate)
114{
115 s32 BDR;
116 s32 BDRI;
117 s16 SFIL = 0;
118 u16 NDEC = 0;
119 u32 ratio;
120 u32 fin;
121 u32 tmp;
122 u64 fptmp;
123 u64 fpxin;
124
125 if (symbolrate > state->config->xin / 2)
126 symbolrate = state->config->xin / 2;
127
128 if (symbolrate < 500000)
129 symbolrate = 500000;
130
131 if (symbolrate < state->config->xin / 16)
132 NDEC = 1;
133 if (symbolrate < state->config->xin / 32)
134 NDEC = 2;
135 if (symbolrate < state->config->xin / 64)
136 NDEC = 3;
137
138 /* yeuch! */
139 fpxin = state->config->xin * 10;
140 fptmp = fpxin; do_div(fptmp, 123);
141 if (symbolrate < fptmp)
142 SFIL = 1;
143 fptmp = fpxin; do_div(fptmp, 160);
144 if (symbolrate < fptmp)
145 SFIL = 0;
146 fptmp = fpxin; do_div(fptmp, 246);
147 if (symbolrate < fptmp)
148 SFIL = 1;
149 fptmp = fpxin; do_div(fptmp, 320);
150 if (symbolrate < fptmp)
151 SFIL = 0;
152 fptmp = fpxin; do_div(fptmp, 492);
153 if (symbolrate < fptmp)
154 SFIL = 1;
155 fptmp = fpxin; do_div(fptmp, 640);
156 if (symbolrate < fptmp)
157 SFIL = 0;
158 fptmp = fpxin; do_div(fptmp, 984);
159 if (symbolrate < fptmp)
160 SFIL = 1;
161
162 fin = state->config->xin >> 4;
163 symbolrate <<= NDEC;
164 ratio = (symbolrate << 4) / fin;
165 tmp = ((symbolrate << 4) % fin) << 8;
166 ratio = (ratio << 8) + tmp / fin;
167 tmp = (tmp % fin) << 8;
168 ratio = (ratio << 8) + DIV_ROUND_CLOSEST(tmp, fin);
169
170 BDR = ratio;
171 BDRI = (((state->config->xin << 5) / symbolrate) + 1) / 2;
172
173 if (BDRI > 0xFF)
174 BDRI = 0xFF;
175
176 SFIL = (SFIL << 4) | ves1820_inittab[0x0E];
177
178 NDEC = (NDEC << 6) | ves1820_inittab[0x03];
179
180 ves1820_writereg(state, 0x03, NDEC);
181 ves1820_writereg(state, 0x0a, BDR & 0xff);
182 ves1820_writereg(state, 0x0b, (BDR >> 8) & 0xff);
183 ves1820_writereg(state, 0x0c, (BDR >> 16) & 0x3f);
184
185 ves1820_writereg(state, 0x0d, BDRI);
186 ves1820_writereg(state, 0x0e, SFIL);
187
188 return 0;
189}
190
191static int ves1820_init(struct dvb_frontend* fe)
192{
193 struct ves1820_state* state = fe->demodulator_priv;
194 int i;
195
196 ves1820_writereg(state, 0, 0);
197
198 for (i = 0; i < sizeof(ves1820_inittab); i++)
199 ves1820_writereg(state, i, ves1820_inittab[i]);
200 if (state->config->selagc)
201 ves1820_writereg(state, 2, ves1820_inittab[2] | 0x08);
202
203 ves1820_writereg(state, 0x34, state->pwm);
204
205 return 0;
206}
207
208static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
209{
210 struct ves1820_state* state = fe->demodulator_priv;
211 static const u8 reg0x00[] = { 0x00, 0x04, 0x08, 0x0c, 0x10 };
212 static const u8 reg0x01[] = { 140, 140, 106, 100, 92 };
213 static const u8 reg0x05[] = { 135, 100, 70, 54, 38 };
214 static const u8 reg0x08[] = { 162, 116, 67, 52, 35 };
215 static const u8 reg0x09[] = { 145, 150, 106, 126, 107 };
216 int real_qam = p->u.qam.modulation - QAM_16;
217
218 if (real_qam < 0 || real_qam > 4)
219 return -EINVAL;
220
221 if (fe->ops.tuner_ops.set_params) {
222 fe->ops.tuner_ops.set_params(fe, p);
223 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
224 }
225
226 ves1820_set_symbolrate(state, p->u.qam.symbol_rate);
227 ves1820_writereg(state, 0x34, state->pwm);
228
229 ves1820_writereg(state, 0x01, reg0x01[real_qam]);
230 ves1820_writereg(state, 0x05, reg0x05[real_qam]);
231 ves1820_writereg(state, 0x08, reg0x08[real_qam]);
232 ves1820_writereg(state, 0x09, reg0x09[real_qam]);
233
234 ves1820_setup_reg0(state, reg0x00[real_qam], p->inversion);
235 ves1820_writereg(state, 2, ves1820_inittab[2] | (state->config->selagc ? 0x08 : 0));
236 return 0;
237}
238
239static int ves1820_read_status(struct dvb_frontend* fe, fe_status_t* status)
240{
241 struct ves1820_state* state = fe->demodulator_priv;
242 int sync;
243
244 *status = 0;
245 sync = ves1820_readreg(state, 0x11);
246
247 if (sync & 1)
248 *status |= FE_HAS_SIGNAL;
249
250 if (sync & 2)
251 *status |= FE_HAS_CARRIER;
252
253 if (sync & 2) /* XXX FIXME! */
254 *status |= FE_HAS_VITERBI;
255
256 if (sync & 4)
257 *status |= FE_HAS_SYNC;
258
259 if (sync & 8)
260 *status |= FE_HAS_LOCK;
261
262 return 0;
263}
264
265static int ves1820_read_ber(struct dvb_frontend* fe, u32* ber)
266{
267 struct ves1820_state* state = fe->demodulator_priv;
268
269 u32 _ber = ves1820_readreg(state, 0x14) |
270 (ves1820_readreg(state, 0x15) << 8) |
271 ((ves1820_readreg(state, 0x16) & 0x0f) << 16);
272 *ber = 10 * _ber;
273
274 return 0;
275}
276
277static int ves1820_read_signal_strength(struct dvb_frontend* fe, u16* strength)
278{
279 struct ves1820_state* state = fe->demodulator_priv;
280
281 u8 gain = ves1820_readreg(state, 0x17);
282 *strength = (gain << 8) | gain;
283
284 return 0;
285}
286
287static int ves1820_read_snr(struct dvb_frontend* fe, u16* snr)
288{
289 struct ves1820_state* state = fe->demodulator_priv;
290
291 u8 quality = ~ves1820_readreg(state, 0x18);
292 *snr = (quality << 8) | quality;
293
294 return 0;
295}
296
297static int ves1820_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
298{
299 struct ves1820_state* state = fe->demodulator_priv;
300
301 *ucblocks = ves1820_readreg(state, 0x13) & 0x7f;
302 if (*ucblocks == 0x7f)
303 *ucblocks = 0xffffffff;
304
305 /* reset uncorrected block counter */
306 ves1820_writereg(state, 0x10, ves1820_inittab[0x10] & 0xdf);
307 ves1820_writereg(state, 0x10, ves1820_inittab[0x10]);
308
309 return 0;
310}
311
312static int ves1820_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
313{
314 struct ves1820_state* state = fe->demodulator_priv;
315 int sync;
316 s8 afc = 0;
317
318 sync = ves1820_readreg(state, 0x11);
319 afc = ves1820_readreg(state, 0x19);
320 if (verbose) {
321 /* AFC only valid when carrier has been recovered */
322 printk(sync & 2 ? "ves1820: AFC (%d) %dHz\n" :
323 "ves1820: [AFC (%d) %dHz]\n", afc, -((s32) p->u.qam.symbol_rate * afc) >> 10);
324 }
325
326 if (!state->config->invert) {
327 p->inversion = (state->reg0 & 0x20) ? INVERSION_ON : INVERSION_OFF;
328 } else {
329 p->inversion = (!(state->reg0 & 0x20)) ? INVERSION_ON : INVERSION_OFF;
330 }
331
332 p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
333
334 p->u.qam.fec_inner = FEC_NONE;
335
336 p->frequency = ((p->frequency + 31250) / 62500) * 62500;
337 if (sync & 2)
338 p->frequency -= ((s32) p->u.qam.symbol_rate * afc) >> 10;
339
340 return 0;
341}
342
343static int ves1820_sleep(struct dvb_frontend* fe)
344{
345 struct ves1820_state* state = fe->demodulator_priv;
346
347 ves1820_writereg(state, 0x1b, 0x02); /* pdown ADC */
348 ves1820_writereg(state, 0x00, 0x80); /* standby */
349
350 return 0;
351}
352
353static int ves1820_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
354{
355
356 fesettings->min_delay_ms = 200;
357 fesettings->step_size = 0;
358 fesettings->max_drift = 0;
359 return 0;
360}
361
362static void ves1820_release(struct dvb_frontend* fe)
363{
364 struct ves1820_state* state = fe->demodulator_priv;
365 kfree(state);
366}
367
368static struct dvb_frontend_ops ves1820_ops;
369
370struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
371 struct i2c_adapter* i2c,
372 u8 pwm)
373{
374 struct ves1820_state* state = NULL;
375
376 /* allocate memory for the internal state */
377 state = kzalloc(sizeof(struct ves1820_state), GFP_KERNEL);
378 if (state == NULL)
379 goto error;
380
381 /* setup the state */
382 state->reg0 = ves1820_inittab[0];
383 state->config = config;
384 state->i2c = i2c;
385 state->pwm = pwm;
386
387 /* check if the demod is there */
388 if ((ves1820_readreg(state, 0x1a) & 0xf0) != 0x70)
389 goto error;
390
391 if (verbose)
392 printk("ves1820: pwm=0x%02x\n", state->pwm);
393
394 /* create dvb_frontend */
395 memcpy(&state->frontend.ops, &ves1820_ops, sizeof(struct dvb_frontend_ops));
396 state->frontend.ops.info.symbol_rate_min = (state->config->xin / 2) / 64; /* SACLK/64 == (XIN/2)/64 */
397 state->frontend.ops.info.symbol_rate_max = (state->config->xin / 2) / 4; /* SACLK/4 */
398 state->frontend.demodulator_priv = state;
399
400 return &state->frontend;
401
402error:
403 kfree(state);
404 return NULL;
405}
406
407static struct dvb_frontend_ops ves1820_ops = {
408
409 .info = {
410 .name = "VLSI VES1820 DVB-C",
411 .type = FE_QAM,
412 .frequency_stepsize = 62500,
413 .frequency_min = 47000000,
414 .frequency_max = 862000000,
415 .caps = FE_CAN_QAM_16 |
416 FE_CAN_QAM_32 |
417 FE_CAN_QAM_64 |
418 FE_CAN_QAM_128 |
419 FE_CAN_QAM_256 |
420 FE_CAN_FEC_AUTO
421 },
422
423 .release = ves1820_release,
424
425 .init = ves1820_init,
426 .sleep = ves1820_sleep,
427
428 .set_frontend = ves1820_set_parameters,
429 .get_frontend = ves1820_get_frontend,
430 .get_tune_settings = ves1820_get_tune_settings,
431
432 .read_status = ves1820_read_status,
433 .read_ber = ves1820_read_ber,
434 .read_signal_strength = ves1820_read_signal_strength,
435 .read_snr = ves1820_read_snr,
436 .read_ucblocks = ves1820_read_ucblocks,
437};
438
439module_param(verbose, int, 0644);
440MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting");
441
442MODULE_DESCRIPTION("VLSI VES1820 DVB-C Demodulator driver");
443MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
444MODULE_LICENSE("GPL");
445
446EXPORT_SYMBOL(ves1820_attach);
diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h
new file mode 100644
index 00000000000..e902ed634ec
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1820.h
@@ -0,0 +1,56 @@
1/*
2 VES1820 - Single Chip Cable Channel Receiver driver module
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
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 VES1820_H
22#define VES1820_H
23
24#include <linux/dvb/frontend.h>
25
26#define VES1820_SELAGC_PWM 0
27#define VES1820_SELAGC_SIGNAMPERR 1
28
29struct ves1820_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* value of XIN to use */
35 u32 xin;
36
37 /* does inversion need inverted? */
38 u8 invert:1;
39
40 /* SELAGC control */
41 u8 selagc:1;
42};
43
44#if defined(CONFIG_DVB_VES1820) || (defined(CONFIG_DVB_VES1820_MODULE) && defined(MODULE))
45extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
46 struct i2c_adapter* i2c, u8 pwm);
47#else
48static inline struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
49 struct i2c_adapter* i2c, u8 pwm)
50{
51 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
52 return NULL;
53}
54#endif // CONFIG_DVB_VES1820
55
56#endif // VES1820_H
diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c
new file mode 100644
index 00000000000..8d7854c2fb0
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1x93.c
@@ -0,0 +1,550 @@
1/*
2 Driver for VES1893 and VES1993 QPSK Demodulators
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
5 Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de>
6 Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
7 Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org>
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
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*/
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/string.h>
30#include <linux/slab.h>
31#include <linux/delay.h>
32
33#include "dvb_frontend.h"
34#include "ves1x93.h"
35
36
37struct ves1x93_state {
38 struct i2c_adapter* i2c;
39 /* configuration settings */
40 const struct ves1x93_config* config;
41 struct dvb_frontend frontend;
42
43 /* previous uncorrected block counter */
44 fe_spectral_inversion_t inversion;
45 u8 *init_1x93_tab;
46 u8 *init_1x93_wtab;
47 u8 tab_size;
48 u8 demod_type;
49};
50
51static int debug;
52#define dprintk if (debug) printk
53
54#define DEMOD_VES1893 0
55#define DEMOD_VES1993 1
56
57static u8 init_1893_tab [] = {
58 0x01, 0xa4, 0x35, 0x80, 0x2a, 0x0b, 0x55, 0xc4,
59 0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00,
60 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x80, 0x00, 0x21, 0xb0, 0x14, 0x00, 0xdc, 0x00,
62 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x55, 0x00, 0x00, 0x7f, 0x00
65};
66
67static u8 init_1993_tab [] = {
68 0x00, 0x9c, 0x35, 0x80, 0x6a, 0x09, 0x72, 0x8c,
69 0x09, 0x6b, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00,
70 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x80, 0x40, 0x21, 0xb0, 0x00, 0x00, 0x00, 0x10,
72 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
75 0x00, 0x00, 0x0e, 0x80, 0x00
76};
77
78static u8 init_1893_wtab[] =
79{
80 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
81 0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1,
82 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
83 1,1,1,0,1,1
84};
85
86static u8 init_1993_wtab[] =
87{
88 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0,
89 0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,1,
90 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0,
91 1,1,1,0,1,1,1,1, 1,1,1,1,1
92};
93
94static int ves1x93_writereg (struct ves1x93_state* state, u8 reg, u8 data)
95{
96 u8 buf [] = { 0x00, reg, data };
97 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 };
98 int err;
99
100 if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
101 dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
102 return -EREMOTEIO;
103 }
104
105 return 0;
106}
107
108static u8 ves1x93_readreg (struct ves1x93_state* state, u8 reg)
109{
110 int ret;
111 u8 b0 [] = { 0x00, reg };
112 u8 b1 [] = { 0 };
113 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 },
114 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
115
116 ret = i2c_transfer (state->i2c, msg, 2);
117
118 if (ret != 2) return ret;
119
120 return b1[0];
121}
122
123static int ves1x93_clr_bit (struct ves1x93_state* state)
124{
125 msleep(10);
126 ves1x93_writereg (state, 0, state->init_1x93_tab[0] & 0xfe);
127 ves1x93_writereg (state, 0, state->init_1x93_tab[0]);
128 msleep(50);
129 return 0;
130}
131
132static int ves1x93_set_inversion (struct ves1x93_state* state, fe_spectral_inversion_t inversion)
133{
134 u8 val;
135
136 /*
137 * inversion on/off are interchanged because i and q seem to
138 * be swapped on the hardware
139 */
140
141 switch (inversion) {
142 case INVERSION_OFF:
143 val = 0xc0;
144 break;
145 case INVERSION_ON:
146 val = 0x80;
147 break;
148 case INVERSION_AUTO:
149 val = 0x00;
150 break;
151 default:
152 return -EINVAL;
153 }
154
155 return ves1x93_writereg (state, 0x0c, (state->init_1x93_tab[0x0c] & 0x3f) | val);
156}
157
158static int ves1x93_set_fec (struct ves1x93_state* state, fe_code_rate_t fec)
159{
160 if (fec == FEC_AUTO)
161 return ves1x93_writereg (state, 0x0d, 0x08);
162 else if (fec < FEC_1_2 || fec > FEC_8_9)
163 return -EINVAL;
164 else
165 return ves1x93_writereg (state, 0x0d, fec - FEC_1_2);
166}
167
168static fe_code_rate_t ves1x93_get_fec (struct ves1x93_state* state)
169{
170 return FEC_1_2 + ((ves1x93_readreg (state, 0x0d) >> 4) & 0x7);
171}
172
173static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate)
174{
175 u32 BDR;
176 u32 ratio;
177 u8 ADCONF, FCONF, FNR, AGCR;
178 u32 BDRI;
179 u32 tmp;
180 u32 FIN;
181
182 dprintk("%s: srate == %d\n", __func__, (unsigned int) srate);
183
184 if (srate > state->config->xin/2)
185 srate = state->config->xin/2;
186
187 if (srate < 500000)
188 srate = 500000;
189
190#define MUL (1UL<<26)
191
192 FIN = (state->config->xin + 6000) >> 4;
193
194 tmp = srate << 6;
195 ratio = tmp / FIN;
196
197 tmp = (tmp % FIN) << 8;
198 ratio = (ratio << 8) + tmp / FIN;
199
200 tmp = (tmp % FIN) << 8;
201 ratio = (ratio << 8) + tmp / FIN;
202
203 FNR = 0xff;
204
205 if (ratio < MUL/3) FNR = 0;
206 if (ratio < (MUL*11)/50) FNR = 1;
207 if (ratio < MUL/6) FNR = 2;
208 if (ratio < MUL/9) FNR = 3;
209 if (ratio < MUL/12) FNR = 4;
210 if (ratio < (MUL*11)/200) FNR = 5;
211 if (ratio < MUL/24) FNR = 6;
212 if (ratio < (MUL*27)/1000) FNR = 7;
213 if (ratio < MUL/48) FNR = 8;
214 if (ratio < (MUL*137)/10000) FNR = 9;
215
216 if (FNR == 0xff) {
217 ADCONF = 0x89;
218 FCONF = 0x80;
219 FNR = 0;
220 } else {
221 ADCONF = 0x81;
222 FCONF = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5);
223 /*FCONF = 0x80 | ((FNR & 0x01) << 5) | (((FNR > 1) & 0x03) << 3) | ((FNR >> 1) & 0x07);*/
224 }
225
226 BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1;
227 BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1;
228
229 dprintk("FNR= %d\n", FNR);
230 dprintk("ratio= %08x\n", (unsigned int) ratio);
231 dprintk("BDR= %08x\n", (unsigned int) BDR);
232 dprintk("BDRI= %02x\n", (unsigned int) BDRI);
233
234 if (BDRI > 0xff)
235 BDRI = 0xff;
236
237 ves1x93_writereg (state, 0x06, 0xff & BDR);
238 ves1x93_writereg (state, 0x07, 0xff & (BDR >> 8));
239 ves1x93_writereg (state, 0x08, 0x0f & (BDR >> 16));
240
241 ves1x93_writereg (state, 0x09, BDRI);
242 ves1x93_writereg (state, 0x20, ADCONF);
243 ves1x93_writereg (state, 0x21, FCONF);
244
245 AGCR = state->init_1x93_tab[0x05];
246 if (state->config->invert_pwm)
247 AGCR |= 0x20;
248
249 if (srate < 6000000)
250 AGCR |= 0x80;
251 else
252 AGCR &= ~0x80;
253
254 ves1x93_writereg (state, 0x05, AGCR);
255
256 /* ves1993 hates this, will lose lock */
257 if (state->demod_type != DEMOD_VES1993)
258 ves1x93_clr_bit (state);
259
260 return 0;
261}
262
263static int ves1x93_init (struct dvb_frontend* fe)
264{
265 struct ves1x93_state* state = fe->demodulator_priv;
266 int i;
267 int val;
268
269 dprintk("%s: init chip\n", __func__);
270
271 for (i = 0; i < state->tab_size; i++) {
272 if (state->init_1x93_wtab[i]) {
273 val = state->init_1x93_tab[i];
274
275 if (state->config->invert_pwm && (i == 0x05)) val |= 0x20; /* invert PWM */
276 ves1x93_writereg (state, i, val);
277 }
278 }
279
280 return 0;
281}
282
283static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
284{
285 struct ves1x93_state* state = fe->demodulator_priv;
286
287 switch (voltage) {
288 case SEC_VOLTAGE_13:
289 return ves1x93_writereg (state, 0x1f, 0x20);
290 case SEC_VOLTAGE_18:
291 return ves1x93_writereg (state, 0x1f, 0x30);
292 case SEC_VOLTAGE_OFF:
293 return ves1x93_writereg (state, 0x1f, 0x00);
294 default:
295 return -EINVAL;
296 }
297}
298
299static int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status)
300{
301 struct ves1x93_state* state = fe->demodulator_priv;
302
303 u8 sync = ves1x93_readreg (state, 0x0e);
304
305 /*
306 * The ves1893 sometimes returns sync values that make no sense,
307 * because, e.g., the SIGNAL bit is 0, while some of the higher
308 * bits are 1 (and how can there be a CARRIER w/o a SIGNAL?).
309 * Tests showed that the VITERBI and SYNC bits are returned
310 * reliably, while the SIGNAL and CARRIER bits ar sometimes wrong.
311 * If such a case occurs, we read the value again, until we get a
312 * valid value.
313 */
314 int maxtry = 10; /* just for safety - let's not get stuck here */
315 while ((sync & 0x03) != 0x03 && (sync & 0x0c) && maxtry--) {
316 msleep(10);
317 sync = ves1x93_readreg (state, 0x0e);
318 }
319
320 *status = 0;
321
322 if (sync & 1)
323 *status |= FE_HAS_SIGNAL;
324
325 if (sync & 2)
326 *status |= FE_HAS_CARRIER;
327
328 if (sync & 4)
329 *status |= FE_HAS_VITERBI;
330
331 if (sync & 8)
332 *status |= FE_HAS_SYNC;
333
334 if ((sync & 0x1f) == 0x1f)
335 *status |= FE_HAS_LOCK;
336
337 return 0;
338}
339
340static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber)
341{
342 struct ves1x93_state* state = fe->demodulator_priv;
343
344 *ber = ves1x93_readreg (state, 0x15);
345 *ber |= (ves1x93_readreg (state, 0x16) << 8);
346 *ber |= ((ves1x93_readreg (state, 0x17) & 0x0F) << 16);
347 *ber *= 10;
348
349 return 0;
350}
351
352static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength)
353{
354 struct ves1x93_state* state = fe->demodulator_priv;
355
356 u8 signal = ~ves1x93_readreg (state, 0x0b);
357 *strength = (signal << 8) | signal;
358
359 return 0;
360}
361
362static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr)
363{
364 struct ves1x93_state* state = fe->demodulator_priv;
365
366 u8 _snr = ~ves1x93_readreg (state, 0x1c);
367 *snr = (_snr << 8) | _snr;
368
369 return 0;
370}
371
372static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
373{
374 struct ves1x93_state* state = fe->demodulator_priv;
375
376 *ucblocks = ves1x93_readreg (state, 0x18) & 0x7f;
377
378 if (*ucblocks == 0x7f)
379 *ucblocks = 0xffffffff; /* counter overflow... */
380
381 ves1x93_writereg (state, 0x18, 0x00); /* reset the counter */
382 ves1x93_writereg (state, 0x18, 0x80); /* dto. */
383
384 return 0;
385}
386
387static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
388{
389 struct ves1x93_state* state = fe->demodulator_priv;
390
391 if (fe->ops.tuner_ops.set_params) {
392 fe->ops.tuner_ops.set_params(fe, p);
393 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
394 }
395 ves1x93_set_inversion (state, p->inversion);
396 ves1x93_set_fec (state, p->u.qpsk.fec_inner);
397 ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate);
398 state->inversion = p->inversion;
399
400 return 0;
401}
402
403static int ves1x93_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
404{
405 struct ves1x93_state* state = fe->demodulator_priv;
406 int afc;
407
408 afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2;
409 afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16;
410
411 p->frequency -= afc;
412
413 /*
414 * inversion indicator is only valid
415 * if auto inversion was used
416 */
417 if (state->inversion == INVERSION_AUTO)
418 p->inversion = (ves1x93_readreg (state, 0x0f) & 2) ?
419 INVERSION_OFF : INVERSION_ON;
420 p->u.qpsk.fec_inner = ves1x93_get_fec (state);
421 /* XXX FIXME: timing offset !! */
422
423 return 0;
424}
425
426static int ves1x93_sleep(struct dvb_frontend* fe)
427{
428 struct ves1x93_state* state = fe->demodulator_priv;
429
430 return ves1x93_writereg (state, 0x00, 0x08);
431}
432
433static void ves1x93_release(struct dvb_frontend* fe)
434{
435 struct ves1x93_state* state = fe->demodulator_priv;
436 kfree(state);
437}
438
439static int ves1x93_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
440{
441 struct ves1x93_state* state = fe->demodulator_priv;
442
443 if (enable) {
444 return ves1x93_writereg(state, 0x00, 0x11);
445 } else {
446 return ves1x93_writereg(state, 0x00, 0x01);
447 }
448}
449
450static struct dvb_frontend_ops ves1x93_ops;
451
452struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
453 struct i2c_adapter* i2c)
454{
455 struct ves1x93_state* state = NULL;
456 u8 identity;
457
458 /* allocate memory for the internal state */
459 state = kzalloc(sizeof(struct ves1x93_state), GFP_KERNEL);
460 if (state == NULL) goto error;
461
462 /* setup the state */
463 state->config = config;
464 state->i2c = i2c;
465 state->inversion = INVERSION_OFF;
466
467 /* check if the demod is there + identify it */
468 identity = ves1x93_readreg(state, 0x1e);
469 switch (identity) {
470 case 0xdc: /* VES1893A rev1 */
471 printk("ves1x93: Detected ves1893a rev1\n");
472 state->demod_type = DEMOD_VES1893;
473 state->init_1x93_tab = init_1893_tab;
474 state->init_1x93_wtab = init_1893_wtab;
475 state->tab_size = sizeof(init_1893_tab);
476 break;
477
478 case 0xdd: /* VES1893A rev2 */
479 printk("ves1x93: Detected ves1893a rev2\n");
480 state->demod_type = DEMOD_VES1893;
481 state->init_1x93_tab = init_1893_tab;
482 state->init_1x93_wtab = init_1893_wtab;
483 state->tab_size = sizeof(init_1893_tab);
484 break;
485
486 case 0xde: /* VES1993 */
487 printk("ves1x93: Detected ves1993\n");
488 state->demod_type = DEMOD_VES1993;
489 state->init_1x93_tab = init_1993_tab;
490 state->init_1x93_wtab = init_1993_wtab;
491 state->tab_size = sizeof(init_1993_tab);
492 break;
493
494 default:
495 goto error;
496 }
497
498 /* create dvb_frontend */
499 memcpy(&state->frontend.ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops));
500 state->frontend.demodulator_priv = state;
501 return &state->frontend;
502
503error:
504 kfree(state);
505 return NULL;
506}
507
508static struct dvb_frontend_ops ves1x93_ops = {
509
510 .info = {
511 .name = "VLSI VES1x93 DVB-S",
512 .type = FE_QPSK,
513 .frequency_min = 950000,
514 .frequency_max = 2150000,
515 .frequency_stepsize = 125, /* kHz for QPSK frontends */
516 .frequency_tolerance = 29500,
517 .symbol_rate_min = 1000000,
518 .symbol_rate_max = 45000000,
519 /* .symbol_rate_tolerance = ???,*/
520 .caps = FE_CAN_INVERSION_AUTO |
521 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
522 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
523 FE_CAN_QPSK
524 },
525
526 .release = ves1x93_release,
527
528 .init = ves1x93_init,
529 .sleep = ves1x93_sleep,
530 .i2c_gate_ctrl = ves1x93_i2c_gate_ctrl,
531
532 .set_frontend = ves1x93_set_frontend,
533 .get_frontend = ves1x93_get_frontend,
534
535 .read_status = ves1x93_read_status,
536 .read_ber = ves1x93_read_ber,
537 .read_signal_strength = ves1x93_read_signal_strength,
538 .read_snr = ves1x93_read_snr,
539 .read_ucblocks = ves1x93_read_ucblocks,
540
541 .set_voltage = ves1x93_set_voltage,
542};
543
544module_param(debug, int, 0644);
545
546MODULE_DESCRIPTION("VLSI VES1x93 DVB-S Demodulator driver");
547MODULE_AUTHOR("Ralph Metzler");
548MODULE_LICENSE("GPL");
549
550EXPORT_SYMBOL(ves1x93_attach);
diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h
new file mode 100644
index 00000000000..8a5a49e808f
--- /dev/null
+++ b/drivers/media/dvb/frontends/ves1x93.h
@@ -0,0 +1,55 @@
1/*
2 Driver for VES1893 and VES1993 QPSK Demodulators
3
4 Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de>
5 Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de>
6 Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de>
7 Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org>
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
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*/
25
26#ifndef VES1X93_H
27#define VES1X93_H
28
29#include <linux/dvb/frontend.h>
30
31struct ves1x93_config
32{
33 /* the demodulator's i2c address */
34 u8 demod_address;
35
36 /* value of XIN to use */
37 u32 xin;
38
39 /* should PWM be inverted? */
40 u8 invert_pwm:1;
41};
42
43#if defined(CONFIG_DVB_VES1X93) || (defined(CONFIG_DVB_VES1X93_MODULE) && defined(MODULE))
44extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
45 struct i2c_adapter* i2c);
46#else
47static inline struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
48 struct i2c_adapter* i2c)
49{
50 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
51 return NULL;
52}
53#endif // CONFIG_DVB_VES1X93
54
55#endif // VES1X93_H
diff --git a/drivers/media/dvb/frontends/z0194a.h b/drivers/media/dvb/frontends/z0194a.h
new file mode 100644
index 00000000000..96d86d6eb47
--- /dev/null
+++ b/drivers/media/dvb/frontends/z0194a.h
@@ -0,0 +1,85 @@
1/* z0194a.h Sharp z0194a tuner support
2*
3* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
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#ifndef Z0194A
13#define Z0194A
14
15static int sharp_z0194a_set_symbol_rate(struct dvb_frontend *fe,
16 u32 srate, u32 ratio)
17{
18 u8 aclk = 0;
19 u8 bclk = 0;
20
21 if (srate < 1500000) {
22 aclk = 0xb7; bclk = 0x47; }
23 else if (srate < 3000000) {
24 aclk = 0xb7; bclk = 0x4b; }
25 else if (srate < 7000000) {
26 aclk = 0xb7; bclk = 0x4f; }
27 else if (srate < 14000000) {
28 aclk = 0xb7; bclk = 0x53; }
29 else if (srate < 30000000) {
30 aclk = 0xb6; bclk = 0x53; }
31 else if (srate < 45000000) {
32 aclk = 0xb4; bclk = 0x51; }
33
34 stv0299_writereg(fe, 0x13, aclk);
35 stv0299_writereg(fe, 0x14, bclk);
36 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
37 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
38 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
39
40 return 0;
41}
42
43static u8 sharp_z0194a_inittab[] = {
44 0x01, 0x15,
45 0x02, 0x30,
46 0x03, 0x00,
47 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
48 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
49 0x06, 0x40, /* DAC not used, set to high impendance mode */
50 0x07, 0x00, /* DAC LSB */
51 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
52 0x09, 0x00, /* FIFO */
53 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
54 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
55 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
56 0x10, 0x3f, /* AGC2 0x3d */
57 0x11, 0x84,
58 0x12, 0xb9,
59 0x15, 0xc9, /* lock detector threshold */
60 0x16, 0x00,
61 0x17, 0x00,
62 0x18, 0x00,
63 0x19, 0x00,
64 0x1a, 0x00,
65 0x1f, 0x50,
66 0x20, 0x00,
67 0x21, 0x00,
68 0x22, 0x00,
69 0x23, 0x00,
70 0x28, 0x00, /* out imp: normal out type: parallel FEC mode:0 */
71 0x29, 0x1e, /* 1/2 threshold */
72 0x2a, 0x14, /* 2/3 threshold */
73 0x2b, 0x0f, /* 3/4 threshold */
74 0x2c, 0x09, /* 5/6 threshold */
75 0x2d, 0x05, /* 7/8 threshold */
76 0x2e, 0x01,
77 0x31, 0x1f, /* test all FECs */
78 0x32, 0x19, /* viterbi and synchro search */
79 0x33, 0xfc, /* rs control */
80 0x34, 0x93, /* error control */
81 0x0f, 0x52,
82 0xff, 0xff
83};
84
85#endif
diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c
new file mode 100644
index 00000000000..81aa984c551
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10036.c
@@ -0,0 +1,520 @@
1/**
2 * Driver for Zarlink zl10036 DVB-S silicon tuner
3 *
4 * Copyright (C) 2006 Tino Reichardt
5 * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.de>
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 Version 2, as
9 * published by the Free Software Foundation.
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 * The data sheet for this tuner can be found at:
22 * http://www.mcmilk.de/projects/dvb-card/datasheets/ZL10036.pdf
23 *
24 * This one is working: (at my Avermedia DVB-S Pro)
25 * - zl10036 (40pin, FTA)
26 *
27 * A driver for zl10038 should be very similar.
28 */
29
30#include <linux/module.h>
31#include <linux/dvb/frontend.h>
32#include <linux/slab.h>
33#include <linux/types.h>
34
35#include "zl10036.h"
36
37static int zl10036_debug;
38#define dprintk(level, args...) \
39 do { if (zl10036_debug & level) printk(KERN_DEBUG "zl10036: " args); \
40 } while (0)
41
42#define deb_info(args...) dprintk(0x01, args)
43#define deb_i2c(args...) dprintk(0x02, args)
44
45struct zl10036_state {
46 struct i2c_adapter *i2c;
47 const struct zl10036_config *config;
48 u32 frequency;
49 u8 br, bf;
50};
51
52
53/* This driver assumes the tuner is driven by a 10.111MHz Cristal */
54#define _XTAL 10111
55
56/* Some of the possible dividers:
57 * 64, (write 0x05 to reg), freq step size 158kHz
58 * 10, (write 0x0a to reg), freq step size 1.011kHz (used here)
59 * 5, (write 0x09 to reg), freq step size 2.022kHz
60 */
61
62#define _RDIV 10
63#define _RDIV_REG 0x0a
64#define _FR (_XTAL/_RDIV)
65
66#define STATUS_POR 0x80 /* Power on Reset */
67#define STATUS_FL 0x40 /* Frequency & Phase Lock */
68
69/* read/write for zl10036 and zl10038 */
70
71static int zl10036_read_status_reg(struct zl10036_state *state)
72{
73 u8 status;
74 struct i2c_msg msg[1] = {
75 { .addr = state->config->tuner_address, .flags = I2C_M_RD,
76 .buf = &status, .len = sizeof(status) },
77 };
78
79 if (i2c_transfer(state->i2c, msg, 1) != 1) {
80 printk(KERN_ERR "%s: i2c read failed at addr=%02x\n",
81 __func__, state->config->tuner_address);
82 return -EIO;
83 }
84
85 deb_i2c("R(status): %02x [FL=%d]\n", status,
86 (status & STATUS_FL) ? 1 : 0);
87 if (status & STATUS_POR)
88 deb_info("%s: Power-On-Reset bit enabled - "
89 "need to initialize the tuner\n", __func__);
90
91 return status;
92}
93
94static int zl10036_write(struct zl10036_state *state, u8 buf[], u8 count)
95{
96 struct i2c_msg msg[1] = {
97 { .addr = state->config->tuner_address, .flags = 0,
98 .buf = buf, .len = count },
99 };
100 u8 reg = 0;
101 int ret;
102
103 if (zl10036_debug & 0x02) {
104 /* every 8bit-value satisifes this!
105 * so only check for debug log */
106 if ((buf[0] & 0x80) == 0x00)
107 reg = 2;
108 else if ((buf[0] & 0xc0) == 0x80)
109 reg = 4;
110 else if ((buf[0] & 0xf0) == 0xc0)
111 reg = 6;
112 else if ((buf[0] & 0xf0) == 0xd0)
113 reg = 8;
114 else if ((buf[0] & 0xf0) == 0xe0)
115 reg = 10;
116 else if ((buf[0] & 0xf0) == 0xf0)
117 reg = 12;
118
119 deb_i2c("W(%d):", reg);
120 {
121 int i;
122 for (i = 0; i < count; i++)
123 printk(KERN_CONT " %02x", buf[i]);
124 printk(KERN_CONT "\n");
125 }
126 }
127
128 ret = i2c_transfer(state->i2c, msg, 1);
129 if (ret != 1) {
130 printk(KERN_ERR "%s: i2c error, ret=%d\n", __func__, ret);
131 return -EIO;
132 }
133
134 return 0;
135}
136
137static int zl10036_release(struct dvb_frontend *fe)
138{
139 struct zl10036_state *state = fe->tuner_priv;
140
141 fe->tuner_priv = NULL;
142 kfree(state);
143
144 return 0;
145}
146
147static int zl10036_sleep(struct dvb_frontend *fe)
148{
149 struct zl10036_state *state = fe->tuner_priv;
150 u8 buf[] = { 0xf0, 0x80 }; /* regs 12/13 */
151 int ret;
152
153 deb_info("%s\n", __func__);
154
155 if (fe->ops.i2c_gate_ctrl)
156 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
157
158 ret = zl10036_write(state, buf, sizeof(buf));
159
160 if (fe->ops.i2c_gate_ctrl)
161 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
162
163 return ret;
164}
165
166/**
167 * register map of the ZL10036/ZL10038
168 *
169 * reg[default] content
170 * 2[0x00]: 0 | N14 | N13 | N12 | N11 | N10 | N9 | N8
171 * 3[0x00]: N7 | N6 | N5 | N4 | N3 | N2 | N1 | N0
172 * 4[0x80]: 1 | 0 | RFG | BA1 | BA0 | BG1 | BG0 | LEN
173 * 5[0x00]: P0 | C1 | C0 | R4 | R3 | R2 | R1 | R0
174 * 6[0xc0]: 1 | 1 | 0 | 0 | RSD | 0 | 0 | 0
175 * 7[0x20]: P1 | BF6 | BF5 | BF4 | BF3 | BF2 | BF1 | 0
176 * 8[0xdb]: 1 | 1 | 0 | 1 | 0 | CC | 1 | 1
177 * 9[0x30]: VSD | V2 | V1 | V0 | S3 | S2 | S1 | S0
178 * 10[0xe1]: 1 | 1 | 1 | 0 | 0 | LS2 | LS1 | LS0
179 * 11[0xf5]: WS | WH2 | WH1 | WH0 | WL2 | WL1 | WL0 | WRE
180 * 12[0xf0]: 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0
181 * 13[0x28]: PD | BR4 | BR3 | BR2 | BR1 | BR0 | CLR | TL
182 */
183
184static int zl10036_set_frequency(struct zl10036_state *state, u32 frequency)
185{
186 u8 buf[2];
187 u32 div, foffset;
188
189 div = (frequency + _FR/2) / _FR;
190 state->frequency = div * _FR;
191
192 foffset = frequency - state->frequency;
193
194 buf[0] = (div >> 8) & 0x7f;
195 buf[1] = (div >> 0) & 0xff;
196
197 deb_info("%s: ftodo=%u fpriv=%u ferr=%d div=%u\n", __func__,
198 frequency, state->frequency, foffset, div);
199
200 return zl10036_write(state, buf, sizeof(buf));
201}
202
203static int zl10036_set_bandwidth(struct zl10036_state *state, u32 fbw)
204{
205 /* fbw is measured in kHz */
206 u8 br, bf;
207 int ret;
208 u8 buf_bf[] = {
209 0xc0, 0x00, /* 6/7: rsd=0 bf=0 */
210 };
211 u8 buf_br[] = {
212 0xf0, 0x00, /* 12/13: br=0xa clr=0 tl=0*/
213 };
214 u8 zl10036_rsd_off[] = { 0xc8 }; /* set RSD=1 */
215
216 /* ensure correct values */
217 if (fbw > 35000)
218 fbw = 35000;
219 if (fbw < 8000)
220 fbw = 8000;
221
222#define _BR_MAXIMUM (_XTAL/575) /* _XTAL / 575kHz = 17 */
223
224 /* <= 28,82 MHz */
225 if (fbw <= 28820) {
226 br = _BR_MAXIMUM;
227 } else {
228 /**
229 * f(bw)=34,6MHz f(xtal)=10.111MHz
230 * br = (10111/34600) * 63 * 1/K = 14;
231 */
232 br = ((_XTAL * 21 * 1000) / (fbw * 419));
233 }
234
235 /* ensure correct values */
236 if (br < 4)
237 br = 4;
238 if (br > _BR_MAXIMUM)
239 br = _BR_MAXIMUM;
240
241 /*
242 * k = 1.257
243 * bf = fbw/_XTAL * br * k - 1 */
244
245 bf = (fbw * br * 1257) / (_XTAL * 1000) - 1;
246
247 /* ensure correct values */
248 if (bf > 62)
249 bf = 62;
250
251 buf_bf[1] = (bf << 1) & 0x7e;
252 buf_br[1] = (br << 2) & 0x7c;
253 deb_info("%s: BW=%d br=%u bf=%u\n", __func__, fbw, br, bf);
254
255 if (br != state->br) {
256 ret = zl10036_write(state, buf_br, sizeof(buf_br));
257 if (ret < 0)
258 return ret;
259 }
260
261 if (bf != state->bf) {
262 ret = zl10036_write(state, buf_bf, sizeof(buf_bf));
263 if (ret < 0)
264 return ret;
265
266 /* time = br/(32* fxtal) */
267 /* minimal sleep time to be calculated
268 * maximum br is 63 -> max time = 2 /10 MHz = 2e-7 */
269 msleep(1);
270
271 ret = zl10036_write(state, zl10036_rsd_off,
272 sizeof(zl10036_rsd_off));
273 if (ret < 0)
274 return ret;
275 }
276
277 state->br = br;
278 state->bf = bf;
279
280 return 0;
281}
282
283static int zl10036_set_gain_params(struct zl10036_state *state,
284 int c)
285{
286 u8 buf[2];
287 u8 rfg, ba, bg;
288
289 /* default values */
290 rfg = 0; /* enable when using an lna */
291 ba = 1;
292 bg = 1;
293
294 /* reg 4 */
295 buf[0] = 0x80 | ((rfg << 5) & 0x20)
296 | ((ba << 3) & 0x18) | ((bg << 1) & 0x06);
297
298 if (!state->config->rf_loop_enable)
299 buf[0] |= 0x01;
300
301 /* P0=0 */
302 buf[1] = _RDIV_REG | ((c << 5) & 0x60);
303
304 deb_info("%s: c=%u rfg=%u ba=%u bg=%u\n", __func__, c, rfg, ba, bg);
305 return zl10036_write(state, buf, sizeof(buf));
306}
307
308static int zl10036_set_params(struct dvb_frontend *fe,
309 struct dvb_frontend_parameters *params)
310{
311 struct zl10036_state *state = fe->tuner_priv;
312 int ret = 0;
313 u32 frequency = params->frequency;
314 u32 fbw;
315 int i;
316 u8 c;
317
318 /* ensure correct values
319 * maybe redundant as core already checks this */
320 if ((frequency < fe->ops.info.frequency_min)
321 || (frequency > fe->ops.info.frequency_max))
322 return -EINVAL;
323
324 /**
325 * alpha = 1.35 for dvb-s
326 * fBW = (alpha*symbolrate)/(2*0.8)
327 * 1.35 / (2*0.8) = 27 / 32
328 */
329 fbw = (27 * params->u.qpsk.symbol_rate) / 32;
330
331 /* scale to kHz */
332 fbw /= 1000;
333
334 /* Add safe margin of 3MHz */
335 fbw += 3000;
336
337 /* setting the charge pump - guessed values */
338 if (frequency < 950000)
339 return -EINVAL;
340 else if (frequency < 1250000)
341 c = 0;
342 else if (frequency < 1750000)
343 c = 1;
344 else if (frequency < 2175000)
345 c = 2;
346 else
347 return -EINVAL;
348
349 if (fe->ops.i2c_gate_ctrl)
350 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
351
352 ret = zl10036_set_gain_params(state, c);
353 if (ret < 0)
354 goto error;
355
356 ret = zl10036_set_frequency(state, params->frequency);
357 if (ret < 0)
358 goto error;
359
360 ret = zl10036_set_bandwidth(state, fbw);
361 if (ret < 0)
362 goto error;
363
364 /* wait for tuner lock - no idea if this is really needed */
365 for (i = 0; i < 20; i++) {
366 ret = zl10036_read_status_reg(state);
367 if (ret < 0)
368 goto error;
369
370 /* check Frequency & Phase Lock Bit */
371 if (ret & STATUS_FL)
372 break;
373
374 msleep(10);
375 }
376
377error:
378 if (fe->ops.i2c_gate_ctrl)
379 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
380
381 return ret;
382}
383
384static int zl10036_get_frequency(struct dvb_frontend *fe, u32 *frequency)
385{
386 struct zl10036_state *state = fe->tuner_priv;
387
388 *frequency = state->frequency;
389
390 return 0;
391}
392
393static int zl10036_init_regs(struct zl10036_state *state)
394{
395 int ret;
396 int i;
397
398 /* could also be one block from reg 2 to 13 and additional 10/11 */
399 u8 zl10036_init_tab[][2] = {
400 { 0x04, 0x00 }, /* 2/3: div=0x400 - arbitrary value */
401 { 0x8b, _RDIV_REG }, /* 4/5: rfg=0 ba=1 bg=1 len=? */
402 /* p0=0 c=0 r=_RDIV_REG */
403 { 0xc0, 0x20 }, /* 6/7: rsd=0 bf=0x10 */
404 { 0xd3, 0x40 }, /* 8/9: from datasheet */
405 { 0xe3, 0x5b }, /* 10/11: lock window level */
406 { 0xf0, 0x28 }, /* 12/13: br=0xa clr=0 tl=0*/
407 { 0xe3, 0xf9 }, /* 10/11: unlock window level */
408 };
409
410 /* invalid values to trigger writing */
411 state->br = 0xff;
412 state->bf = 0xff;
413
414 if (!state->config->rf_loop_enable)
415 zl10036_init_tab[1][0] |= 0x01;
416
417 deb_info("%s\n", __func__);
418
419 for (i = 0; i < ARRAY_SIZE(zl10036_init_tab); i++) {
420 ret = zl10036_write(state, zl10036_init_tab[i], 2);
421 if (ret < 0)
422 return ret;
423 }
424
425 return 0;
426}
427
428static int zl10036_init(struct dvb_frontend *fe)
429{
430 struct zl10036_state *state = fe->tuner_priv;
431 int ret = 0;
432
433 if (fe->ops.i2c_gate_ctrl)
434 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
435
436 ret = zl10036_read_status_reg(state);
437 if (ret < 0)
438 return ret;
439
440 /* Only init if Power-on-Reset bit is set? */
441 ret = zl10036_init_regs(state);
442
443 if (fe->ops.i2c_gate_ctrl)
444 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
445
446 return ret;
447}
448
449static struct dvb_tuner_ops zl10036_tuner_ops = {
450 .info = {
451 .name = "Zarlink ZL10036",
452 .frequency_min = 950000,
453 .frequency_max = 2175000
454 },
455 .init = zl10036_init,
456 .release = zl10036_release,
457 .sleep = zl10036_sleep,
458 .set_params = zl10036_set_params,
459 .get_frequency = zl10036_get_frequency,
460};
461
462struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
463 const struct zl10036_config *config,
464 struct i2c_adapter *i2c)
465{
466 struct zl10036_state *state;
467 int ret;
468
469 if (!config) {
470 printk(KERN_ERR "%s: no config specified", __func__);
471 return NULL;
472 }
473
474 state = kzalloc(sizeof(struct zl10036_state), GFP_KERNEL);
475 if (!state)
476 return NULL;
477
478 state->config = config;
479 state->i2c = i2c;
480
481 if (fe->ops.i2c_gate_ctrl)
482 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
483
484 ret = zl10036_read_status_reg(state);
485 if (ret < 0) {
486 printk(KERN_ERR "%s: No zl10036 found\n", __func__);
487 goto error;
488 }
489
490 ret = zl10036_init_regs(state);
491 if (ret < 0) {
492 printk(KERN_ERR "%s: tuner initialization failed\n",
493 __func__);
494 goto error;
495 }
496
497 if (fe->ops.i2c_gate_ctrl)
498 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
499
500 fe->tuner_priv = state;
501
502 memcpy(&fe->ops.tuner_ops, &zl10036_tuner_ops,
503 sizeof(struct dvb_tuner_ops));
504 printk(KERN_INFO "%s: tuner initialization (%s addr=0x%02x) ok\n",
505 __func__, fe->ops.tuner_ops.info.name, config->tuner_address);
506
507 return fe;
508
509error:
510 kfree(state);
511 return NULL;
512}
513EXPORT_SYMBOL(zl10036_attach);
514
515module_param_named(debug, zl10036_debug, int, 0644);
516MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
517MODULE_DESCRIPTION("DVB ZL10036 driver");
518MODULE_AUTHOR("Tino Reichardt");
519MODULE_AUTHOR("Matthias Schwarzott");
520MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/zl10036.h b/drivers/media/dvb/frontends/zl10036.h
new file mode 100644
index 00000000000..d84b8f8215e
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10036.h
@@ -0,0 +1,53 @@
1/**
2 * Driver for Zarlink ZL10036 DVB-S silicon tuner
3 *
4 * Copyright (C) 2006 Tino Reichardt
5 * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.de>
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 Version 2, as
9 * published by the Free Software Foundation.
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_ZL10036_H
22#define DVB_ZL10036_H
23
24#include <linux/i2c.h>
25#include "dvb_frontend.h"
26
27/**
28 * Attach a zl10036 tuner to the supplied frontend structure.
29 *
30 * @param fe Frontend to attach to.
31 * @param config zl10036_config structure
32 * @return FE pointer on success, NULL on failure.
33 */
34
35struct zl10036_config {
36 u8 tuner_address;
37 int rf_loop_enable;
38};
39
40#if defined(CONFIG_DVB_ZL10036) || \
41 (defined(CONFIG_DVB_ZL10036_MODULE) && defined(MODULE))
42extern struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
43 const struct zl10036_config *config, struct i2c_adapter *i2c);
44#else
45static inline struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
46 const struct zl10036_config *config, struct i2c_adapter *i2c)
47{
48 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
49 return NULL;
50}
51#endif
52
53#endif /* DVB_ZL10036_H */
diff --git a/drivers/media/dvb/frontends/zl10039.c b/drivers/media/dvb/frontends/zl10039.c
new file mode 100644
index 00000000000..c085e58a94b
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10039.c
@@ -0,0 +1,307 @@
1/*
2 * Driver for Zarlink ZL10039 DVB-S tuner
3 *
4 * Copyright 2007 Jan D. Louw <jd.louw@mweb.co.za>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/string.h>
25#include <linux/slab.h>
26#include <linux/dvb/frontend.h>
27
28#include "dvb_frontend.h"
29#include "zl10039.h"
30
31static int debug;
32
33#define dprintk(args...) \
34 do { \
35 if (debug) \
36 printk(KERN_DEBUG args); \
37 } while (0)
38
39enum zl10039_model_id {
40 ID_ZL10039 = 1
41};
42
43struct zl10039_state {
44 struct i2c_adapter *i2c;
45 u8 i2c_addr;
46 u8 id;
47};
48
49enum zl10039_reg_addr {
50 PLL0 = 0,
51 PLL1,
52 PLL2,
53 PLL3,
54 RFFE,
55 BASE0,
56 BASE1,
57 BASE2,
58 LO0,
59 LO1,
60 LO2,
61 LO3,
62 LO4,
63 LO5,
64 LO6,
65 GENERAL
66};
67
68static int zl10039_read(const struct zl10039_state *state,
69 const enum zl10039_reg_addr reg, u8 *buf,
70 const size_t count)
71{
72 u8 regbuf[] = { reg };
73 struct i2c_msg msg[] = {
74 {/* Write register address */
75 .addr = state->i2c_addr,
76 .flags = 0,
77 .buf = regbuf,
78 .len = 1,
79 }, {/* Read count bytes */
80 .addr = state->i2c_addr,
81 .flags = I2C_M_RD,
82 .buf = buf,
83 .len = count,
84 },
85 };
86
87 dprintk("%s\n", __func__);
88
89 if (i2c_transfer(state->i2c, msg, 2) != 2) {
90 dprintk("%s: i2c read error\n", __func__);
91 return -EREMOTEIO;
92 }
93
94 return 0; /* Success */
95}
96
97static int zl10039_write(struct zl10039_state *state,
98 const enum zl10039_reg_addr reg, const u8 *src,
99 const size_t count)
100{
101 u8 buf[count + 1];
102 struct i2c_msg msg = {
103 .addr = state->i2c_addr,
104 .flags = 0,
105 .buf = buf,
106 .len = count + 1,
107 };
108
109 dprintk("%s\n", __func__);
110 /* Write register address and data in one go */
111 buf[0] = reg;
112 memcpy(&buf[1], src, count);
113 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
114 dprintk("%s: i2c write error\n", __func__);
115 return -EREMOTEIO;
116 }
117
118 return 0; /* Success */
119}
120
121static inline int zl10039_readreg(struct zl10039_state *state,
122 const enum zl10039_reg_addr reg, u8 *val)
123{
124 return zl10039_read(state, reg, val, 1);
125}
126
127static inline int zl10039_writereg(struct zl10039_state *state,
128 const enum zl10039_reg_addr reg,
129 const u8 val)
130{
131 return zl10039_write(state, reg, &val, 1);
132}
133
134static int zl10039_init(struct dvb_frontend *fe)
135{
136 struct zl10039_state *state = fe->tuner_priv;
137 int ret;
138
139 dprintk("%s\n", __func__);
140 if (fe->ops.i2c_gate_ctrl)
141 fe->ops.i2c_gate_ctrl(fe, 1);
142 /* Reset logic */
143 ret = zl10039_writereg(state, GENERAL, 0x40);
144 if (ret < 0) {
145 dprintk("Note: i2c write error normal when resetting the "
146 "tuner\n");
147 }
148 /* Wake up */
149 ret = zl10039_writereg(state, GENERAL, 0x01);
150 if (ret < 0) {
151 dprintk("Tuner power up failed\n");
152 return ret;
153 }
154 if (fe->ops.i2c_gate_ctrl)
155 fe->ops.i2c_gate_ctrl(fe, 0);
156
157 return 0;
158}
159
160static int zl10039_sleep(struct dvb_frontend *fe)
161{
162 struct zl10039_state *state = fe->tuner_priv;
163 int ret;
164
165 dprintk("%s\n", __func__);
166 if (fe->ops.i2c_gate_ctrl)
167 fe->ops.i2c_gate_ctrl(fe, 1);
168 ret = zl10039_writereg(state, GENERAL, 0x80);
169 if (ret < 0) {
170 dprintk("Tuner sleep failed\n");
171 return ret;
172 }
173 if (fe->ops.i2c_gate_ctrl)
174 fe->ops.i2c_gate_ctrl(fe, 0);
175
176 return 0;
177}
178
179static int zl10039_set_params(struct dvb_frontend *fe,
180 struct dvb_frontend_parameters *params)
181{
182 struct zl10039_state *state = fe->tuner_priv;
183 u8 buf[6];
184 u8 bf;
185 u32 fbw;
186 u32 div;
187 int ret;
188
189 dprintk("%s\n", __func__);
190 dprintk("Set frequency = %d, symbol rate = %d\n",
191 params->frequency, params->u.qpsk.symbol_rate);
192
193 /* Assumed 10.111 MHz crystal oscillator */
194 /* Cancelled num/den 80 to prevent overflow */
195 div = (params->frequency * 1000) / 126387;
196 fbw = (params->u.qpsk.symbol_rate * 27) / 32000;
197 /* Cancelled num/den 10 to prevent overflow */
198 bf = ((fbw * 5088) / 1011100) - 1;
199
200 /*PLL divider*/
201 buf[0] = (div >> 8) & 0x7f;
202 buf[1] = (div >> 0) & 0xff;
203 /*Reference divider*/
204 /* Select reference ratio of 80 */
205 buf[2] = 0x1D;
206 /*PLL test modes*/
207 buf[3] = 0x40;
208 /*RF Control register*/
209 buf[4] = 0x6E; /* Bypass enable */
210 /*Baseband filter cutoff */
211 buf[5] = bf;
212
213 /* Open i2c gate */
214 if (fe->ops.i2c_gate_ctrl)
215 fe->ops.i2c_gate_ctrl(fe, 1);
216 /* BR = 10, Enable filter adjustment */
217 ret = zl10039_writereg(state, BASE1, 0x0A);
218 if (ret < 0)
219 goto error;
220 /* Write new config values */
221 ret = zl10039_write(state, PLL0, buf, sizeof(buf));
222 if (ret < 0)
223 goto error;
224 /* BR = 10, Disable filter adjustment */
225 ret = zl10039_writereg(state, BASE1, 0x6A);
226 if (ret < 0)
227 goto error;
228
229 /* Close i2c gate */
230 if (fe->ops.i2c_gate_ctrl)
231 fe->ops.i2c_gate_ctrl(fe, 0);
232 return 0;
233error:
234 dprintk("Error setting tuner\n");
235 return ret;
236}
237
238static int zl10039_release(struct dvb_frontend *fe)
239{
240 struct zl10039_state *state = fe->tuner_priv;
241
242 dprintk("%s\n", __func__);
243 kfree(state);
244 fe->tuner_priv = NULL;
245 return 0;
246}
247
248static struct dvb_tuner_ops zl10039_ops = {
249 .release = zl10039_release,
250 .init = zl10039_init,
251 .sleep = zl10039_sleep,
252 .set_params = zl10039_set_params,
253};
254
255struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
256 u8 i2c_addr, struct i2c_adapter *i2c)
257{
258 struct zl10039_state *state = NULL;
259
260 dprintk("%s\n", __func__);
261 state = kmalloc(sizeof(struct zl10039_state), GFP_KERNEL);
262 if (state == NULL)
263 goto error;
264
265 state->i2c = i2c;
266 state->i2c_addr = i2c_addr;
267
268 /* Open i2c gate */
269 if (fe->ops.i2c_gate_ctrl)
270 fe->ops.i2c_gate_ctrl(fe, 1);
271 /* check if this is a valid tuner */
272 if (zl10039_readreg(state, GENERAL, &state->id) < 0) {
273 /* Close i2c gate */
274 if (fe->ops.i2c_gate_ctrl)
275 fe->ops.i2c_gate_ctrl(fe, 0);
276 goto error;
277 }
278 /* Close i2c gate */
279 if (fe->ops.i2c_gate_ctrl)
280 fe->ops.i2c_gate_ctrl(fe, 0);
281
282 state->id = state->id & 0x0f;
283 switch (state->id) {
284 case ID_ZL10039:
285 strcpy(fe->ops.tuner_ops.info.name,
286 "Zarlink ZL10039 DVB-S tuner");
287 break;
288 default:
289 dprintk("Chip ID=%x does not match a known type\n", state->id);
290 goto error;
291 }
292
293 memcpy(&fe->ops.tuner_ops, &zl10039_ops, sizeof(struct dvb_tuner_ops));
294 fe->tuner_priv = state;
295 dprintk("Tuner attached @ i2c address 0x%02x\n", i2c_addr);
296 return fe;
297error:
298 kfree(state);
299 return NULL;
300}
301EXPORT_SYMBOL(zl10039_attach);
302
303module_param(debug, int, 0644);
304MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
305MODULE_DESCRIPTION("Zarlink ZL10039 DVB-S tuner driver");
306MODULE_AUTHOR("Jan D. Louw <jd.louw@mweb.co.za>");
307MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/zl10039.h b/drivers/media/dvb/frontends/zl10039.h
new file mode 100644
index 00000000000..5eee7ea162a
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10039.h
@@ -0,0 +1,40 @@
1/*
2 Driver for Zarlink ZL10039 DVB-S tuner
3
4 Copyright (C) 2007 Jan D. Louw <jd.louw@mweb.co.za>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22#ifndef ZL10039_H
23#define ZL10039_H
24
25#if defined(CONFIG_DVB_ZL10039) || (defined(CONFIG_DVB_ZL10039_MODULE) \
26 && defined(MODULE))
27struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
28 u8 i2c_addr,
29 struct i2c_adapter *i2c);
30#else
31static inline struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
32 u8 i2c_addr,
33 struct i2c_adapter *i2c)
34{
35 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
36 return NULL;
37}
38#endif /* CONFIG_DVB_ZL10039 */
39
40#endif /* ZL10039_H */
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
new file mode 100644
index 00000000000..adbbf6d3d04
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -0,0 +1,699 @@
1/*
2 * Driver for Zarlink DVB-T ZL10353 demodulator
3 *
4 * Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28#include <asm/div64.h>
29
30#include "dvb_frontend.h"
31#include "zl10353_priv.h"
32#include "zl10353.h"
33
34struct zl10353_state {
35 struct i2c_adapter *i2c;
36 struct dvb_frontend frontend;
37
38 struct zl10353_config config;
39
40 enum fe_bandwidth bandwidth;
41 u32 ucblocks;
42 u32 frequency;
43};
44
45static int debug;
46#define dprintk(args...) \
47 do { \
48 if (debug) printk(KERN_DEBUG "zl10353: " args); \
49 } while (0)
50
51static int debug_regs;
52
53static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
54{
55 struct zl10353_state *state = fe->demodulator_priv;
56 u8 buf[2] = { reg, val };
57 struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0,
58 .buf = buf, .len = 2 };
59 int err = i2c_transfer(state->i2c, &msg, 1);
60 if (err != 1) {
61 printk("zl10353: write to reg %x failed (err = %d)!\n", reg, err);
62 return err;
63 }
64 return 0;
65}
66
67static int zl10353_write(struct dvb_frontend *fe, const u8 ibuf[], int ilen)
68{
69 int err, i;
70 for (i = 0; i < ilen - 1; i++)
71 if ((err = zl10353_single_write(fe, ibuf[0] + i, ibuf[i + 1])))
72 return err;
73
74 return 0;
75}
76
77static int zl10353_read_register(struct zl10353_state *state, u8 reg)
78{
79 int ret;
80 u8 b0[1] = { reg };
81 u8 b1[1] = { 0 };
82 struct i2c_msg msg[2] = { { .addr = state->config.demod_address,
83 .flags = 0,
84 .buf = b0, .len = 1 },
85 { .addr = state->config.demod_address,
86 .flags = I2C_M_RD,
87 .buf = b1, .len = 1 } };
88
89 ret = i2c_transfer(state->i2c, msg, 2);
90
91 if (ret != 2) {
92 printk("%s: readreg error (reg=%d, ret==%i)\n",
93 __func__, reg, ret);
94 return ret;
95 }
96
97 return b1[0];
98}
99
100static void zl10353_dump_regs(struct dvb_frontend *fe)
101{
102 struct zl10353_state *state = fe->demodulator_priv;
103 int ret;
104 u8 reg;
105
106 /* Dump all registers. */
107 for (reg = 0; ; reg++) {
108 if (reg % 16 == 0) {
109 if (reg)
110 printk(KERN_CONT "\n");
111 printk(KERN_DEBUG "%02x:", reg);
112 }
113 ret = zl10353_read_register(state, reg);
114 if (ret >= 0)
115 printk(KERN_CONT " %02x", (u8)ret);
116 else
117 printk(KERN_CONT " --");
118 if (reg == 0xff)
119 break;
120 }
121 printk(KERN_CONT "\n");
122}
123
124static void zl10353_calc_nominal_rate(struct dvb_frontend *fe,
125 enum fe_bandwidth bandwidth,
126 u16 *nominal_rate)
127{
128 struct zl10353_state *state = fe->demodulator_priv;
129 u32 adc_clock = 450560; /* 45.056 MHz */
130 u64 value;
131 u8 bw;
132
133 if (state->config.adc_clock)
134 adc_clock = state->config.adc_clock;
135
136 switch (bandwidth) {
137 case BANDWIDTH_6_MHZ:
138 bw = 6;
139 break;
140 case BANDWIDTH_7_MHZ:
141 bw = 7;
142 break;
143 case BANDWIDTH_8_MHZ:
144 default:
145 bw = 8;
146 break;
147 }
148
149 value = (u64)10 * (1 << 23) / 7 * 125;
150 value = (bw * value) + adc_clock / 2;
151 do_div(value, adc_clock);
152 *nominal_rate = value;
153
154 dprintk("%s: bw %d, adc_clock %d => 0x%x\n",
155 __func__, bw, adc_clock, *nominal_rate);
156}
157
158static void zl10353_calc_input_freq(struct dvb_frontend *fe,
159 u16 *input_freq)
160{
161 struct zl10353_state *state = fe->demodulator_priv;
162 u32 adc_clock = 450560; /* 45.056 MHz */
163 int if2 = 361667; /* 36.1667 MHz */
164 int ife;
165 u64 value;
166
167 if (state->config.adc_clock)
168 adc_clock = state->config.adc_clock;
169 if (state->config.if2)
170 if2 = state->config.if2;
171
172 if (adc_clock >= if2 * 2)
173 ife = if2;
174 else {
175 ife = adc_clock - (if2 % adc_clock);
176 if (ife > adc_clock / 2)
177 ife = adc_clock - ife;
178 }
179 value = (u64)65536 * ife + adc_clock / 2;
180 do_div(value, adc_clock);
181 *input_freq = -value;
182
183 dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n",
184 __func__, if2, ife, adc_clock, -(int)value, *input_freq);
185}
186
187static int zl10353_sleep(struct dvb_frontend *fe)
188{
189 static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 };
190
191 zl10353_write(fe, zl10353_softdown, sizeof(zl10353_softdown));
192 return 0;
193}
194
195static int zl10353_set_parameters(struct dvb_frontend *fe,
196 struct dvb_frontend_parameters *param)
197{
198 struct zl10353_state *state = fe->demodulator_priv;
199 u16 nominal_rate, input_freq;
200 u8 pllbuf[6] = { 0x67 }, acq_ctl = 0;
201 u16 tps = 0;
202 struct dvb_ofdm_parameters *op = &param->u.ofdm;
203
204 state->frequency = param->frequency;
205
206 zl10353_single_write(fe, RESET, 0x80);
207 udelay(200);
208 zl10353_single_write(fe, 0xEA, 0x01);
209 udelay(200);
210 zl10353_single_write(fe, 0xEA, 0x00);
211
212 zl10353_single_write(fe, AGC_TARGET, 0x28);
213
214 if (op->transmission_mode != TRANSMISSION_MODE_AUTO)
215 acq_ctl |= (1 << 0);
216 if (op->guard_interval != GUARD_INTERVAL_AUTO)
217 acq_ctl |= (1 << 1);
218 zl10353_single_write(fe, ACQ_CTL, acq_ctl);
219
220 switch (op->bandwidth) {
221 case BANDWIDTH_6_MHZ:
222 /* These are extrapolated from the 7 and 8MHz values */
223 zl10353_single_write(fe, MCLK_RATIO, 0x97);
224 zl10353_single_write(fe, 0x64, 0x34);
225 zl10353_single_write(fe, 0xcc, 0xdd);
226 break;
227 case BANDWIDTH_7_MHZ:
228 zl10353_single_write(fe, MCLK_RATIO, 0x86);
229 zl10353_single_write(fe, 0x64, 0x35);
230 zl10353_single_write(fe, 0xcc, 0x73);
231 break;
232 case BANDWIDTH_8_MHZ:
233 default:
234 zl10353_single_write(fe, MCLK_RATIO, 0x75);
235 zl10353_single_write(fe, 0x64, 0x36);
236 zl10353_single_write(fe, 0xcc, 0x73);
237 }
238
239 zl10353_calc_nominal_rate(fe, op->bandwidth, &nominal_rate);
240 zl10353_single_write(fe, TRL_NOMINAL_RATE_1, msb(nominal_rate));
241 zl10353_single_write(fe, TRL_NOMINAL_RATE_0, lsb(nominal_rate));
242 state->bandwidth = op->bandwidth;
243
244 zl10353_calc_input_freq(fe, &input_freq);
245 zl10353_single_write(fe, INPUT_FREQ_1, msb(input_freq));
246 zl10353_single_write(fe, INPUT_FREQ_0, lsb(input_freq));
247
248 /* Hint at TPS settings */
249 switch (op->code_rate_HP) {
250 case FEC_2_3:
251 tps |= (1 << 7);
252 break;
253 case FEC_3_4:
254 tps |= (2 << 7);
255 break;
256 case FEC_5_6:
257 tps |= (3 << 7);
258 break;
259 case FEC_7_8:
260 tps |= (4 << 7);
261 break;
262 case FEC_1_2:
263 case FEC_AUTO:
264 break;
265 default:
266 return -EINVAL;
267 }
268
269 switch (op->code_rate_LP) {
270 case FEC_2_3:
271 tps |= (1 << 4);
272 break;
273 case FEC_3_4:
274 tps |= (2 << 4);
275 break;
276 case FEC_5_6:
277 tps |= (3 << 4);
278 break;
279 case FEC_7_8:
280 tps |= (4 << 4);
281 break;
282 case FEC_1_2:
283 case FEC_AUTO:
284 break;
285 case FEC_NONE:
286 if (op->hierarchy_information == HIERARCHY_AUTO ||
287 op->hierarchy_information == HIERARCHY_NONE)
288 break;
289 default:
290 return -EINVAL;
291 }
292
293 switch (op->constellation) {
294 case QPSK:
295 break;
296 case QAM_AUTO:
297 case QAM_16:
298 tps |= (1 << 13);
299 break;
300 case QAM_64:
301 tps |= (2 << 13);
302 break;
303 default:
304 return -EINVAL;
305 }
306
307 switch (op->transmission_mode) {
308 case TRANSMISSION_MODE_2K:
309 case TRANSMISSION_MODE_AUTO:
310 break;
311 case TRANSMISSION_MODE_8K:
312 tps |= (1 << 0);
313 break;
314 default:
315 return -EINVAL;
316 }
317
318 switch (op->guard_interval) {
319 case GUARD_INTERVAL_1_32:
320 case GUARD_INTERVAL_AUTO:
321 break;
322 case GUARD_INTERVAL_1_16:
323 tps |= (1 << 2);
324 break;
325 case GUARD_INTERVAL_1_8:
326 tps |= (2 << 2);
327 break;
328 case GUARD_INTERVAL_1_4:
329 tps |= (3 << 2);
330 break;
331 default:
332 return -EINVAL;
333 }
334
335 switch (op->hierarchy_information) {
336 case HIERARCHY_AUTO:
337 case HIERARCHY_NONE:
338 break;
339 case HIERARCHY_1:
340 tps |= (1 << 10);
341 break;
342 case HIERARCHY_2:
343 tps |= (2 << 10);
344 break;
345 case HIERARCHY_4:
346 tps |= (3 << 10);
347 break;
348 default:
349 return -EINVAL;
350 }
351
352 zl10353_single_write(fe, TPS_GIVEN_1, msb(tps));
353 zl10353_single_write(fe, TPS_GIVEN_0, lsb(tps));
354
355 if (fe->ops.i2c_gate_ctrl)
356 fe->ops.i2c_gate_ctrl(fe, 0);
357
358 /*
359 * If there is no tuner attached to the secondary I2C bus, we call
360 * set_params to program a potential tuner attached somewhere else.
361 * Otherwise, we update the PLL registers via calc_regs.
362 */
363 if (state->config.no_tuner) {
364 if (fe->ops.tuner_ops.set_params) {
365 fe->ops.tuner_ops.set_params(fe, param);
366 if (fe->ops.i2c_gate_ctrl)
367 fe->ops.i2c_gate_ctrl(fe, 0);
368 }
369 } else if (fe->ops.tuner_ops.calc_regs) {
370 fe->ops.tuner_ops.calc_regs(fe, param, pllbuf + 1, 5);
371 pllbuf[1] <<= 1;
372 zl10353_write(fe, pllbuf, sizeof(pllbuf));
373 }
374
375 zl10353_single_write(fe, 0x5F, 0x13);
376
377 /* If no attached tuner or invalid PLL registers, just start the FSM. */
378 if (state->config.no_tuner || fe->ops.tuner_ops.calc_regs == NULL)
379 zl10353_single_write(fe, FSM_GO, 0x01);
380 else
381 zl10353_single_write(fe, TUNER_GO, 0x01);
382
383 return 0;
384}
385
386static int zl10353_get_parameters(struct dvb_frontend *fe,
387 struct dvb_frontend_parameters *param)
388{
389 struct zl10353_state *state = fe->demodulator_priv;
390 struct dvb_ofdm_parameters *op = &param->u.ofdm;
391 int s6, s9;
392 u16 tps;
393 static const u8 tps_fec_to_api[8] = {
394 FEC_1_2,
395 FEC_2_3,
396 FEC_3_4,
397 FEC_5_6,
398 FEC_7_8,
399 FEC_AUTO,
400 FEC_AUTO,
401 FEC_AUTO
402 };
403
404 s6 = zl10353_read_register(state, STATUS_6);
405 s9 = zl10353_read_register(state, STATUS_9);
406 if (s6 < 0 || s9 < 0)
407 return -EREMOTEIO;
408 if ((s6 & (1 << 5)) == 0 || (s9 & (1 << 4)) == 0)
409 return -EINVAL; /* no FE or TPS lock */
410
411 tps = zl10353_read_register(state, TPS_RECEIVED_1) << 8 |
412 zl10353_read_register(state, TPS_RECEIVED_0);
413
414 op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7];
415 op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7];
416
417 switch ((tps >> 13) & 3) {
418 case 0:
419 op->constellation = QPSK;
420 break;
421 case 1:
422 op->constellation = QAM_16;
423 break;
424 case 2:
425 op->constellation = QAM_64;
426 break;
427 default:
428 op->constellation = QAM_AUTO;
429 break;
430 }
431
432 op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K :
433 TRANSMISSION_MODE_2K;
434
435 switch ((tps >> 2) & 3) {
436 case 0:
437 op->guard_interval = GUARD_INTERVAL_1_32;
438 break;
439 case 1:
440 op->guard_interval = GUARD_INTERVAL_1_16;
441 break;
442 case 2:
443 op->guard_interval = GUARD_INTERVAL_1_8;
444 break;
445 case 3:
446 op->guard_interval = GUARD_INTERVAL_1_4;
447 break;
448 default:
449 op->guard_interval = GUARD_INTERVAL_AUTO;
450 break;
451 }
452
453 switch ((tps >> 10) & 7) {
454 case 0:
455 op->hierarchy_information = HIERARCHY_NONE;
456 break;
457 case 1:
458 op->hierarchy_information = HIERARCHY_1;
459 break;
460 case 2:
461 op->hierarchy_information = HIERARCHY_2;
462 break;
463 case 3:
464 op->hierarchy_information = HIERARCHY_4;
465 break;
466 default:
467 op->hierarchy_information = HIERARCHY_AUTO;
468 break;
469 }
470
471 param->frequency = state->frequency;
472 op->bandwidth = state->bandwidth;
473 param->inversion = INVERSION_AUTO;
474
475 return 0;
476}
477
478static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status)
479{
480 struct zl10353_state *state = fe->demodulator_priv;
481 int s6, s7, s8;
482
483 if ((s6 = zl10353_read_register(state, STATUS_6)) < 0)
484 return -EREMOTEIO;
485 if ((s7 = zl10353_read_register(state, STATUS_7)) < 0)
486 return -EREMOTEIO;
487 if ((s8 = zl10353_read_register(state, STATUS_8)) < 0)
488 return -EREMOTEIO;
489
490 *status = 0;
491 if (s6 & (1 << 2))
492 *status |= FE_HAS_CARRIER;
493 if (s6 & (1 << 1))
494 *status |= FE_HAS_VITERBI;
495 if (s6 & (1 << 5))
496 *status |= FE_HAS_LOCK;
497 if (s7 & (1 << 4))
498 *status |= FE_HAS_SYNC;
499 if (s8 & (1 << 6))
500 *status |= FE_HAS_SIGNAL;
501
502 if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) !=
503 (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))
504 *status &= ~FE_HAS_LOCK;
505
506 return 0;
507}
508
509static int zl10353_read_ber(struct dvb_frontend *fe, u32 *ber)
510{
511 struct zl10353_state *state = fe->demodulator_priv;
512
513 *ber = zl10353_read_register(state, RS_ERR_CNT_2) << 16 |
514 zl10353_read_register(state, RS_ERR_CNT_1) << 8 |
515 zl10353_read_register(state, RS_ERR_CNT_0);
516
517 return 0;
518}
519
520static int zl10353_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
521{
522 struct zl10353_state *state = fe->demodulator_priv;
523
524 u16 signal = zl10353_read_register(state, AGC_GAIN_1) << 10 |
525 zl10353_read_register(state, AGC_GAIN_0) << 2 | 3;
526
527 *strength = ~signal;
528
529 return 0;
530}
531
532static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr)
533{
534 struct zl10353_state *state = fe->demodulator_priv;
535 u8 _snr;
536
537 if (debug_regs)
538 zl10353_dump_regs(fe);
539
540 _snr = zl10353_read_register(state, SNR);
541 *snr = (_snr << 8) | _snr;
542
543 return 0;
544}
545
546static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
547{
548 struct zl10353_state *state = fe->demodulator_priv;
549 u32 ubl = 0;
550
551 ubl = zl10353_read_register(state, RS_UBC_1) << 8 |
552 zl10353_read_register(state, RS_UBC_0);
553
554 state->ucblocks += ubl;
555 *ucblocks = state->ucblocks;
556
557 return 0;
558}
559
560static int zl10353_get_tune_settings(struct dvb_frontend *fe,
561 struct dvb_frontend_tune_settings
562 *fe_tune_settings)
563{
564 fe_tune_settings->min_delay_ms = 1000;
565 fe_tune_settings->step_size = 0;
566 fe_tune_settings->max_drift = 0;
567
568 return 0;
569}
570
571static int zl10353_init(struct dvb_frontend *fe)
572{
573 struct zl10353_state *state = fe->demodulator_priv;
574 u8 zl10353_reset_attach[6] = { 0x50, 0x03, 0x64, 0x46, 0x15, 0x0F };
575 int rc = 0;
576
577 if (debug_regs)
578 zl10353_dump_regs(fe);
579 if (state->config.parallel_ts)
580 zl10353_reset_attach[2] &= ~0x20;
581 if (state->config.clock_ctl_1)
582 zl10353_reset_attach[3] = state->config.clock_ctl_1;
583 if (state->config.pll_0)
584 zl10353_reset_attach[4] = state->config.pll_0;
585
586 /* Do a "hard" reset if not already done */
587 if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] ||
588 zl10353_read_register(state, 0x51) != zl10353_reset_attach[2]) {
589 rc = zl10353_write(fe, zl10353_reset_attach,
590 sizeof(zl10353_reset_attach));
591 if (debug_regs)
592 zl10353_dump_regs(fe);
593 }
594
595 return 0;
596}
597
598static int zl10353_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
599{
600 struct zl10353_state *state = fe->demodulator_priv;
601 u8 val = 0x0a;
602
603 if (state->config.disable_i2c_gate_ctrl) {
604 /* No tuner attached to the internal I2C bus */
605 /* If set enable I2C bridge, the main I2C bus stopped hardly */
606 return 0;
607 }
608
609 if (enable)
610 val |= 0x10;
611
612 return zl10353_single_write(fe, 0x62, val);
613}
614
615static void zl10353_release(struct dvb_frontend *fe)
616{
617 struct zl10353_state *state = fe->demodulator_priv;
618 kfree(state);
619}
620
621static struct dvb_frontend_ops zl10353_ops;
622
623struct dvb_frontend *zl10353_attach(const struct zl10353_config *config,
624 struct i2c_adapter *i2c)
625{
626 struct zl10353_state *state = NULL;
627 int id;
628
629 /* allocate memory for the internal state */
630 state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL);
631 if (state == NULL)
632 goto error;
633
634 /* setup the state */
635 state->i2c = i2c;
636 memcpy(&state->config, config, sizeof(struct zl10353_config));
637
638 /* check if the demod is there */
639 id = zl10353_read_register(state, CHIP_ID);
640 if ((id != ID_ZL10353) && (id != ID_CE6230) && (id != ID_CE6231))
641 goto error;
642
643 /* create dvb_frontend */
644 memcpy(&state->frontend.ops, &zl10353_ops, sizeof(struct dvb_frontend_ops));
645 state->frontend.demodulator_priv = state;
646
647 return &state->frontend;
648error:
649 kfree(state);
650 return NULL;
651}
652
653static struct dvb_frontend_ops zl10353_ops = {
654
655 .info = {
656 .name = "Zarlink ZL10353 DVB-T",
657 .type = FE_OFDM,
658 .frequency_min = 174000000,
659 .frequency_max = 862000000,
660 .frequency_stepsize = 166667,
661 .frequency_tolerance = 0,
662 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
663 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
664 FE_CAN_FEC_AUTO |
665 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
666 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
667 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
668 FE_CAN_MUTE_TS
669 },
670
671 .release = zl10353_release,
672
673 .init = zl10353_init,
674 .sleep = zl10353_sleep,
675 .i2c_gate_ctrl = zl10353_i2c_gate_ctrl,
676 .write = zl10353_write,
677
678 .set_frontend = zl10353_set_parameters,
679 .get_frontend = zl10353_get_parameters,
680 .get_tune_settings = zl10353_get_tune_settings,
681
682 .read_status = zl10353_read_status,
683 .read_ber = zl10353_read_ber,
684 .read_signal_strength = zl10353_read_signal_strength,
685 .read_snr = zl10353_read_snr,
686 .read_ucblocks = zl10353_read_ucblocks,
687};
688
689module_param(debug, int, 0644);
690MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
691
692module_param(debug_regs, int, 0644);
693MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off).");
694
695MODULE_DESCRIPTION("Zarlink ZL10353 DVB-T demodulator driver");
696MODULE_AUTHOR("Chris Pascoe");
697MODULE_LICENSE("GPL");
698
699EXPORT_SYMBOL(zl10353_attach);
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h
new file mode 100644
index 00000000000..6e3ca9eed04
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10353.h
@@ -0,0 +1,62 @@
1/*
2 * Driver for Zarlink DVB-T ZL10353 demodulator
3 *
4 * Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#ifndef ZL10353_H
23#define ZL10353_H
24
25#include <linux/dvb/frontend.h>
26
27struct zl10353_config
28{
29 /* demodulator's I2C address */
30 u8 demod_address;
31
32 /* frequencies in units of 0.1kHz */
33 int adc_clock; /* default: 450560 (45.056 MHz) */
34 int if2; /* default: 361667 (36.1667 MHz) */
35
36 /* set if no pll is connected to the secondary i2c bus */
37 int no_tuner;
38
39 /* set if parallel ts output is required */
40 int parallel_ts;
41
42 /* set if i2c_gate_ctrl disable is required */
43 u8 disable_i2c_gate_ctrl:1;
44
45 /* clock control registers (0x51-0x54) */
46 u8 clock_ctl_1; /* default: 0x46 */
47 u8 pll_0; /* default: 0x15 */
48};
49
50#if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE))
51extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
52 struct i2c_adapter *i2c);
53#else
54static inline struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
55 struct i2c_adapter *i2c)
56{
57 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
58 return NULL;
59}
60#endif /* CONFIG_DVB_ZL10353 */
61
62#endif /* ZL10353_H */
diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h
new file mode 100644
index 00000000000..e0dd1d3e09d
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10353_priv.h
@@ -0,0 +1,79 @@
1/*
2 * Driver for Zarlink DVB-T ZL10353 demodulator
3 *
4 * Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef _ZL10353_PRIV_
23#define _ZL10353_PRIV_
24
25#define ID_ZL10353 0x14 /* Zarlink ZL10353 */
26#define ID_CE6230 0x18 /* Intel CE6230 */
27#define ID_CE6231 0x19 /* Intel CE6231 */
28
29#define msb(x) (((x) >> 8) & 0xff)
30#define lsb(x) ((x) & 0xff)
31
32enum zl10353_reg_addr {
33 INTERRUPT_0 = 0x00,
34 INTERRUPT_1 = 0x01,
35 INTERRUPT_2 = 0x02,
36 INTERRUPT_3 = 0x03,
37 INTERRUPT_4 = 0x04,
38 INTERRUPT_5 = 0x05,
39 STATUS_6 = 0x06,
40 STATUS_7 = 0x07,
41 STATUS_8 = 0x08,
42 STATUS_9 = 0x09,
43 AGC_GAIN_1 = 0x0A,
44 AGC_GAIN_0 = 0x0B,
45 SNR = 0x10,
46 RS_ERR_CNT_2 = 0x11,
47 RS_ERR_CNT_1 = 0x12,
48 RS_ERR_CNT_0 = 0x13,
49 RS_UBC_1 = 0x14,
50 RS_UBC_0 = 0x15,
51 TPS_RECEIVED_1 = 0x1D,
52 TPS_RECEIVED_0 = 0x1E,
53 TPS_CURRENT_1 = 0x1F,
54 TPS_CURRENT_0 = 0x20,
55 CLOCK_CTL_0 = 0x51,
56 CLOCK_CTL_1 = 0x52,
57 PLL_0 = 0x53,
58 PLL_1 = 0x54,
59 RESET = 0x55,
60 AGC_TARGET = 0x56,
61 MCLK_RATIO = 0x5C,
62 ACQ_CTL = 0x5E,
63 TRL_NOMINAL_RATE_1 = 0x65,
64 TRL_NOMINAL_RATE_0 = 0x66,
65 INPUT_FREQ_1 = 0x6C,
66 INPUT_FREQ_0 = 0x6D,
67 TPS_GIVEN_1 = 0x6E,
68 TPS_GIVEN_0 = 0x6F,
69 TUNER_GO = 0x70,
70 FSM_GO = 0x71,
71 CHIP_ID = 0x7F,
72 CHAN_STEP_1 = 0xE4,
73 CHAN_STEP_0 = 0xE5,
74 OFDM_LOCK_TIME = 0xE7,
75 FEC_LOCK_TIME = 0xE8,
76 ACQ_DELAY = 0xE9,
77};
78
79#endif /* _ZL10353_PRIV_ */