diff options
author | Olivier Grenie <olivier.grenie@dibcom.fr> | 2011-01-03 13:33:37 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 19:31:41 -0400 |
commit | 4c70e074f8c496dc06798188d71be13162115d32 (patch) | |
tree | f3d5e6b57f6bb32782c39962e07cdd585be74b11 /drivers/media/dvb/frontends | |
parent | 7757ddda6f4febbc52342d82440dd4f7a7d4f14f (diff) |
[media] DiB8000: add diversity support
This patch adds a set a functions which allow the handling of multiple
demodulator in a diversity reception chain.
Signed-off-by: Olivier Grenie <olivier.grenie@dibcom.fr>
Signed-off-by: Patrick Boettcher <patrick.boettcher@dibcom.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r-- | drivers/media/dvb/frontends/dib8000.c | 814 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dib8000.h | 19 |
2 files changed, 532 insertions, 301 deletions
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index df17b91b3250..625e4210d2dd 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #define LAYER_C 3 | 22 | #define LAYER_C 3 |
23 | 23 | ||
24 | #define FE_CALLBACK_TIME_NEVER 0xffffffff | 24 | #define FE_CALLBACK_TIME_NEVER 0xffffffff |
25 | #define MAX_NUMBER_OF_FRONTENDS 6 | ||
25 | 26 | ||
26 | static int debug; | 27 | static int debug; |
27 | module_param(debug, int, 0644); | 28 | module_param(debug, int, 0644); |
@@ -37,7 +38,6 @@ struct i2c_device { | |||
37 | }; | 38 | }; |
38 | 39 | ||
39 | struct dib8000_state { | 40 | struct dib8000_state { |
40 | struct dvb_frontend fe; | ||
41 | struct dib8000_config cfg; | 41 | struct dib8000_config cfg; |
42 | 42 | ||
43 | struct i2c_device i2c; | 43 | struct i2c_device i2c; |
@@ -68,6 +68,8 @@ struct dib8000_state { | |||
68 | u8 isdbt_cfg_loaded; | 68 | u8 isdbt_cfg_loaded; |
69 | enum frontend_tune_state tune_state; | 69 | enum frontend_tune_state tune_state; |
70 | u32 status; | 70 | u32 status; |
71 | |||
72 | struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS]; | ||
71 | }; | 73 | }; |
72 | 74 | ||
73 | enum dib8000_power_mode { | 75 | enum dib8000_power_mode { |
@@ -122,111 +124,111 @@ static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val) | |||
122 | return dib8000_i2c_write16(&state->i2c, reg, val); | 124 | return dib8000_i2c_write16(&state->i2c, reg, val); |
123 | } | 125 | } |
124 | 126 | ||
125 | static const int16_t coeff_2k_sb_1seg_dqpsk[8] = { | 127 | static const s16 coeff_2k_sb_1seg_dqpsk[8] = { |
126 | (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c, | 128 | (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c, |
127 | (920 << 5) | 0x09 | 129 | (920 << 5) | 0x09 |
128 | }; | 130 | }; |
129 | 131 | ||
130 | static const int16_t coeff_2k_sb_1seg[8] = { | 132 | static const s16 coeff_2k_sb_1seg[8] = { |
131 | (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f | 133 | (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f |
132 | }; | 134 | }; |
133 | 135 | ||
134 | static const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = { | 136 | static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = { |
135 | (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11, | 137 | (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11, |
136 | (-931 << 5) | 0x0f | 138 | (-931 << 5) | 0x0f |
137 | }; | 139 | }; |
138 | 140 | ||
139 | static const int16_t coeff_2k_sb_3seg_0dqpsk[8] = { | 141 | static const s16 coeff_2k_sb_3seg_0dqpsk[8] = { |
140 | (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e, | 142 | (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e, |
141 | (982 << 5) | 0x0c | 143 | (982 << 5) | 0x0c |
142 | }; | 144 | }; |
143 | 145 | ||
144 | static const int16_t coeff_2k_sb_3seg_1dqpsk[8] = { | 146 | static const s16 coeff_2k_sb_3seg_1dqpsk[8] = { |
145 | (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12, | 147 | (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12, |
146 | (-720 << 5) | 0x0d | 148 | (-720 << 5) | 0x0d |
147 | }; | 149 | }; |
148 | 150 | ||
149 | static const int16_t coeff_2k_sb_3seg[8] = { | 151 | static const s16 coeff_2k_sb_3seg[8] = { |
150 | (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e, | 152 | (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e, |
151 | (-610 << 5) | 0x0a | 153 | (-610 << 5) | 0x0a |
152 | }; | 154 | }; |
153 | 155 | ||
154 | static const int16_t coeff_4k_sb_1seg_dqpsk[8] = { | 156 | static const s16 coeff_4k_sb_1seg_dqpsk[8] = { |
155 | (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f, | 157 | (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f, |
156 | (-922 << 5) | 0x0d | 158 | (-922 << 5) | 0x0d |
157 | }; | 159 | }; |
158 | 160 | ||
159 | static const int16_t coeff_4k_sb_1seg[8] = { | 161 | static const s16 coeff_4k_sb_1seg[8] = { |
160 | (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d, | 162 | (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d, |
161 | (-655 << 5) | 0x0a | 163 | (-655 << 5) | 0x0a |
162 | }; | 164 | }; |
163 | 165 | ||
164 | static const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = { | 166 | static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = { |
165 | (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14, | 167 | (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14, |
166 | (-958 << 5) | 0x13 | 168 | (-958 << 5) | 0x13 |
167 | }; | 169 | }; |
168 | 170 | ||
169 | static const int16_t coeff_4k_sb_3seg_0dqpsk[8] = { | 171 | static const s16 coeff_4k_sb_3seg_0dqpsk[8] = { |
170 | (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12, | 172 | (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12, |
171 | (-568 << 5) | 0x0f | 173 | (-568 << 5) | 0x0f |
172 | }; | 174 | }; |
173 | 175 | ||
174 | static const int16_t coeff_4k_sb_3seg_1dqpsk[8] = { | 176 | static const s16 coeff_4k_sb_3seg_1dqpsk[8] = { |
175 | (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14, | 177 | (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14, |
176 | (-848 << 5) | 0x13 | 178 | (-848 << 5) | 0x13 |
177 | }; | 179 | }; |
178 | 180 | ||
179 | static const int16_t coeff_4k_sb_3seg[8] = { | 181 | static const s16 coeff_4k_sb_3seg[8] = { |
180 | (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12, | 182 | (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12, |
181 | (-869 << 5) | 0x13 | 183 | (-869 << 5) | 0x13 |
182 | }; | 184 | }; |
183 | 185 | ||
184 | static const int16_t coeff_8k_sb_1seg_dqpsk[8] = { | 186 | static const s16 coeff_8k_sb_1seg_dqpsk[8] = { |
185 | (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13, | 187 | (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13, |
186 | (-598 << 5) | 0x10 | 188 | (-598 << 5) | 0x10 |
187 | }; | 189 | }; |
188 | 190 | ||
189 | static const int16_t coeff_8k_sb_1seg[8] = { | 191 | static const s16 coeff_8k_sb_1seg[8] = { |
190 | (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f, | 192 | (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f, |
191 | (585 << 5) | 0x0f | 193 | (585 << 5) | 0x0f |
192 | }; | 194 | }; |
193 | 195 | ||
194 | static const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = { | 196 | static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = { |
195 | (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18, | 197 | (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18, |
196 | (0 << 5) | 0x14 | 198 | (0 << 5) | 0x14 |
197 | }; | 199 | }; |
198 | 200 | ||
199 | static const int16_t coeff_8k_sb_3seg_0dqpsk[8] = { | 201 | static const s16 coeff_8k_sb_3seg_0dqpsk[8] = { |
200 | (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15, | 202 | (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15, |
201 | (-877 << 5) | 0x15 | 203 | (-877 << 5) | 0x15 |
202 | }; | 204 | }; |
203 | 205 | ||
204 | static const int16_t coeff_8k_sb_3seg_1dqpsk[8] = { | 206 | static const s16 coeff_8k_sb_3seg_1dqpsk[8] = { |
205 | (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18, | 207 | (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18, |
206 | (-921 << 5) | 0x14 | 208 | (-921 << 5) | 0x14 |
207 | }; | 209 | }; |
208 | 210 | ||
209 | static const int16_t coeff_8k_sb_3seg[8] = { | 211 | static const s16 coeff_8k_sb_3seg[8] = { |
210 | (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15, | 212 | (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15, |
211 | (690 << 5) | 0x14 | 213 | (690 << 5) | 0x14 |
212 | }; | 214 | }; |
213 | 215 | ||
214 | static const int16_t ana_fe_coeff_3seg[24] = { | 216 | static const s16 ana_fe_coeff_3seg[24] = { |
215 | 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017 | 217 | 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017 |
216 | }; | 218 | }; |
217 | 219 | ||
218 | static const int16_t ana_fe_coeff_1seg[24] = { | 220 | static const s16 ana_fe_coeff_1seg[24] = { |
219 | 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003 | 221 | 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003 |
220 | }; | 222 | }; |
221 | 223 | ||
222 | static const int16_t ana_fe_coeff_13seg[24] = { | 224 | static const s16 ana_fe_coeff_13seg[24] = { |
223 | 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1 | 225 | 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1 |
224 | }; | 226 | }; |
225 | 227 | ||
226 | static u16 fft_to_mode(struct dib8000_state *state) | 228 | static u16 fft_to_mode(struct dib8000_state *state) |
227 | { | 229 | { |
228 | u16 mode; | 230 | u16 mode; |
229 | switch (state->fe.dtv_property_cache.transmission_mode) { | 231 | switch (state->fe[0]->dtv_property_cache.transmission_mode) { |
230 | case TRANSMISSION_MODE_2K: | 232 | case TRANSMISSION_MODE_2K: |
231 | mode = 1; | 233 | mode = 1; |
232 | break; | 234 | break; |
@@ -249,16 +251,17 @@ static void dib8000_set_acquisition_mode(struct dib8000_state *state) | |||
249 | dprintk("acquisition mode activated"); | 251 | dprintk("acquisition mode activated"); |
250 | dib8000_write_word(state, 298, nud); | 252 | dib8000_write_word(state, 298, nud); |
251 | } | 253 | } |
252 | 254 | static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode) | |
253 | static int dib8000_set_output_mode(struct dib8000_state *state, int mode) | ||
254 | { | 255 | { |
256 | struct dib8000_state *state = fe->demodulator_priv; | ||
257 | |||
255 | u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */ | 258 | u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */ |
256 | 259 | ||
257 | outreg = 0; | 260 | outreg = 0; |
258 | fifo_threshold = 1792; | 261 | fifo_threshold = 1792; |
259 | smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1); | 262 | smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1); |
260 | 263 | ||
261 | dprintk("-I- Setting output mode for demod %p to %d", &state->fe, mode); | 264 | dprintk("-I- Setting output mode for demod %p to %d", &state->fe[0], mode); |
262 | 265 | ||
263 | switch (mode) { | 266 | switch (mode) { |
264 | case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock | 267 | case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock |
@@ -292,7 +295,7 @@ static int dib8000_set_output_mode(struct dib8000_state *state, int mode) | |||
292 | break; | 295 | break; |
293 | 296 | ||
294 | default: | 297 | default: |
295 | dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe); | 298 | dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe[0]); |
296 | return -EINVAL; | 299 | return -EINVAL; |
297 | } | 300 | } |
298 | 301 | ||
@@ -342,7 +345,7 @@ static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_pow | |||
342 | { | 345 | { |
343 | /* by default everything is going to be powered off */ | 346 | /* by default everything is going to be powered off */ |
344 | u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff, | 347 | u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff, |
345 | reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00; | 348 | reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00; |
346 | 349 | ||
347 | /* now, depending on the requested mode, we power on */ | 350 | /* now, depending on the requested mode, we power on */ |
348 | switch (mode) { | 351 | switch (mode) { |
@@ -411,8 +414,9 @@ static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_s | |||
411 | return ret; | 414 | return ret; |
412 | } | 415 | } |
413 | 416 | ||
414 | static int dib8000_set_bandwidth(struct dib8000_state *state, u32 bw) | 417 | static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw) |
415 | { | 418 | { |
419 | struct dib8000_state *state = fe->demodulator_priv; | ||
416 | u32 timf; | 420 | u32 timf; |
417 | 421 | ||
418 | if (bw == 0) | 422 | if (bw == 0) |
@@ -478,7 +482,7 @@ static void dib8000_reset_pll(struct dib8000_state *state) | |||
478 | 482 | ||
479 | // clk_cfg1 | 483 | // clk_cfg1 |
480 | clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | | 484 | clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | |
481 | (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | (pll->pll_range << 1) | (pll->pll_reset << 0); | 485 | (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | (pll->pll_range << 1) | (pll->pll_reset << 0); |
482 | 486 | ||
483 | dib8000_write_word(state, 902, clk_cfg1); | 487 | dib8000_write_word(state, 902, clk_cfg1); |
484 | clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); | 488 | clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); |
@@ -491,7 +495,7 @@ static void dib8000_reset_pll(struct dib8000_state *state) | |||
491 | dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); | 495 | dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); |
492 | else if (state->cfg.refclksel != 0) | 496 | else if (state->cfg.refclksel != 0) |
493 | dib8000_write_word(state, 904, | 497 | dib8000_write_word(state, 904, |
494 | (0 << 15) | (1 << 12) | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | (pll-> | 498 | (0 << 15) | (1 << 12) | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | (pll-> |
495 | ADClkSrc << 7) | (0 << 1)); | 499 | ADClkSrc << 7) | (0 << 1)); |
496 | else | 500 | else |
497 | dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); | 501 | dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); |
@@ -560,7 +564,7 @@ static const u16 dib8000_defaults[] = { | |||
560 | 0xd4c0, | 564 | 0xd4c0, |
561 | 565 | ||
562 | /*1, 32, | 566 | /*1, 32, |
563 | 0x6680 // P_corm_thres Lock algorithms configuration */ | 567 | 0x6680 // P_corm_thres Lock algorithms configuration */ |
564 | 568 | ||
565 | 11, 80, /* set ADC level to -16 */ | 569 | 11, 80, /* set ADC level to -16 */ |
566 | (1 << 13) - 825 - 117, | 570 | (1 << 13) - 825 - 117, |
@@ -627,10 +631,10 @@ static const u16 dib8000_defaults[] = { | |||
627 | 631 | ||
628 | 1, 338, | 632 | 1, 338, |
629 | (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1 | 633 | (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1 |
630 | (1 << 10) | // P_ctrl_pre_freq_mode_sat=1 | 634 | (1 << 10) | // P_ctrl_pre_freq_mode_sat=1 |
631 | (0 << 9) | // P_ctrl_pre_freq_inh=0 | 635 | (0 << 9) | // P_ctrl_pre_freq_inh=0 |
632 | (3 << 5) | // P_ctrl_pre_freq_step=3 | 636 | (3 << 5) | // P_ctrl_pre_freq_step=3 |
633 | (1 << 0), // P_pre_freq_win_len=1 | 637 | (1 << 0), // P_pre_freq_win_len=1 |
634 | 638 | ||
635 | 1, 903, | 639 | 1, 903, |
636 | (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW) | 640 | (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW) |
@@ -717,7 +721,7 @@ static int dib8000_reset(struct dvb_frontend *fe) | |||
717 | if (dib8000_reset_gpio(state) != 0) | 721 | if (dib8000_reset_gpio(state) != 0) |
718 | dprintk("GPIO reset was not successful."); | 722 | dprintk("GPIO reset was not successful."); |
719 | 723 | ||
720 | if (dib8000_set_output_mode(state, OUTMODE_HIGH_Z) != 0) | 724 | if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0) |
721 | dprintk("OUTPUT_MODE could not be resetted."); | 725 | dprintk("OUTPUT_MODE could not be resetted."); |
722 | 726 | ||
723 | state->current_agc = NULL; | 727 | state->current_agc = NULL; |
@@ -752,7 +756,7 @@ static int dib8000_reset(struct dvb_frontend *fe) | |||
752 | /* unforce divstr regardless whether i2c enumeration was done or not */ | 756 | /* unforce divstr regardless whether i2c enumeration was done or not */ |
753 | dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1)); | 757 | dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1)); |
754 | 758 | ||
755 | dib8000_set_bandwidth(state, 6000); | 759 | dib8000_set_bandwidth(fe, 6000); |
756 | 760 | ||
757 | dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON); | 761 | dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON); |
758 | dib8000_sad_calib(state); | 762 | dib8000_sad_calib(state); |
@@ -778,7 +782,7 @@ static int dib8000_update_lna(struct dib8000_state *state) | |||
778 | // read dyn_gain here (because it is demod-dependent and not tuner) | 782 | // read dyn_gain here (because it is demod-dependent and not tuner) |
779 | dyn_gain = dib8000_read_word(state, 390); | 783 | dyn_gain = dib8000_read_word(state, 390); |
780 | 784 | ||
781 | if (state->cfg.update_lna(&state->fe, dyn_gain)) { // LNA has changed | 785 | if (state->cfg.update_lna(state->fe[0], dyn_gain)) { // LNA has changed |
782 | dib8000_restart_agc(state); | 786 | dib8000_restart_agc(state); |
783 | return 1; | 787 | return 1; |
784 | } | 788 | } |
@@ -865,7 +869,7 @@ static int dib8000_agc_soft_split(struct dib8000_state *state) | |||
865 | split_offset = state->current_agc->split.max; | 869 | split_offset = state->current_agc->split.max; |
866 | else | 870 | else |
867 | split_offset = state->current_agc->split.max * | 871 | split_offset = state->current_agc->split.max * |
868 | (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres); | 872 | (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres); |
869 | 873 | ||
870 | dprintk("AGC split_offset: %d", split_offset); | 874 | dprintk("AGC split_offset: %d", split_offset); |
871 | 875 | ||
@@ -900,7 +904,7 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) | |||
900 | case CT_AGC_STEP_0: | 904 | case CT_AGC_STEP_0: |
901 | //AGC initialization | 905 | //AGC initialization |
902 | if (state->cfg.agc_control) | 906 | if (state->cfg.agc_control) |
903 | state->cfg.agc_control(&state->fe, 1); | 907 | state->cfg.agc_control(fe, 1); |
904 | 908 | ||
905 | dib8000_restart_agc(state); | 909 | dib8000_restart_agc(state); |
906 | 910 | ||
@@ -924,7 +928,7 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) | |||
924 | dib8000_agc_soft_split(state); | 928 | dib8000_agc_soft_split(state); |
925 | 929 | ||
926 | if (state->cfg.agc_control) | 930 | if (state->cfg.agc_control) |
927 | state->cfg.agc_control(&state->fe, 0); | 931 | state->cfg.agc_control(fe, 0); |
928 | 932 | ||
929 | *tune_state = CT_AGC_STOP; | 933 | *tune_state = CT_AGC_STOP; |
930 | break; | 934 | break; |
@@ -936,29 +940,29 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) | |||
936 | 940 | ||
937 | } | 941 | } |
938 | 942 | ||
939 | static const int32_t lut_1000ln_mant[] = | 943 | static const s32 lut_1000ln_mant[] = |
940 | { | 944 | { |
941 | 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 | 945 | 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 |
942 | }; | 946 | }; |
943 | 947 | ||
944 | int32_t dib8000_get_adc_power(struct dvb_frontend *fe, uint8_t mode) | 948 | s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) |
945 | { | 949 | { |
946 | struct dib8000_state *state = fe->demodulator_priv; | 950 | struct dib8000_state *state = fe->demodulator_priv; |
947 | uint32_t ix = 0, tmp_val = 0, exp = 0, mant = 0; | 951 | u32 ix = 0, tmp_val = 0, exp = 0, mant = 0; |
948 | int32_t val; | 952 | s32 val; |
949 | 953 | ||
950 | val = dib8000_read32(state, 384); | 954 | val = dib8000_read32(state, 384); |
951 | /* mode = 1 : ln_agcpower calc using mant-exp conversion and mantis look up table */ | 955 | /* mode = 1 : ln_agcpower calc using mant-exp conversion and mantis look up table */ |
952 | if (mode) { | 956 | if (mode) { |
953 | tmp_val = val; | 957 | tmp_val = val; |
954 | while (tmp_val >>= 1) | 958 | while (tmp_val >>= 1) |
955 | exp++; | 959 | exp++; |
956 | mant = (val * 1000 / (1<<exp)); | 960 | mant = (val * 1000 / (1<<exp)); |
957 | ix = (uint8_t)((mant-1000)/100); /* index of the LUT */ | 961 | ix = (u8)((mant-1000)/100); /* index of the LUT */ |
958 | val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908); /* 1000 * ln(adcpower_real) ; 693 = 1000ln(2) ; 6908 = 1000*ln(1000) ; 20 comes from adc_real = adc_pow_int / 2**20 */ | 962 | val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908); /* 1000 * ln(adcpower_real) ; 693 = 1000ln(2) ; 6908 = 1000*ln(1000) ; 20 comes from adc_real = adc_pow_int / 2**20 */ |
959 | val = (val*256)/1000; | 963 | val = (val*256)/1000; |
960 | } | 964 | } |
961 | return val; | 965 | return val; |
962 | } | 966 | } |
963 | EXPORT_SYMBOL(dib8000_get_adc_power); | 967 | EXPORT_SYMBOL(dib8000_get_adc_power); |
964 | 968 | ||
@@ -1002,22 +1006,22 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1002 | dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60); | 1006 | dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60); |
1003 | 1007 | ||
1004 | i = dib8000_read_word(state, 26) & 1; // P_dds_invspec | 1008 | i = dib8000_read_word(state, 26) & 1; // P_dds_invspec |
1005 | dib8000_write_word(state, 26, state->fe.dtv_property_cache.inversion ^ i); | 1009 | dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion ^ i); |
1006 | 1010 | ||
1007 | if (state->fe.dtv_property_cache.isdbt_sb_mode) { | 1011 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) { |
1008 | //compute new dds_freq for the seg and adjust prbs | 1012 | //compute new dds_freq for the seg and adjust prbs |
1009 | int seg_offset = | 1013 | int seg_offset = |
1010 | state->fe.dtv_property_cache.isdbt_sb_segment_idx - (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) - | 1014 | state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx - (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) - |
1011 | (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2); | 1015 | (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2); |
1012 | int clk = state->cfg.pll->internal; | 1016 | int clk = state->cfg.pll->internal; |
1013 | u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26) | 1017 | u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26) |
1014 | int dds_offset = seg_offset * segtodds; | 1018 | int dds_offset = seg_offset * segtodds; |
1015 | int new_dds, sub_channel; | 1019 | int new_dds, sub_channel; |
1016 | if ((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) // if even | 1020 | if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) // if even |
1017 | dds_offset -= (int)(segtodds / 2); | 1021 | dds_offset -= (int)(segtodds / 2); |
1018 | 1022 | ||
1019 | if (state->cfg.pll->ifreq == 0) { | 1023 | if (state->cfg.pll->ifreq == 0) { |
1020 | if ((state->fe.dtv_property_cache.inversion ^ i) == 0) { | 1024 | if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) { |
1021 | dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1); | 1025 | dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1); |
1022 | new_dds = dds_offset; | 1026 | new_dds = dds_offset; |
1023 | } else | 1027 | } else |
@@ -1027,35 +1031,34 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1027 | // - the segment of center frequency with an odd total number of segments | 1031 | // - the segment of center frequency with an odd total number of segments |
1028 | // - the segment to the left of center frequency with an even total number of segments | 1032 | // - the segment to the left of center frequency with an even total number of segments |
1029 | // - the segment to the right of center frequency with an even total number of segments | 1033 | // - the segment to the right of center frequency with an even total number of segments |
1030 | if ((state->fe.dtv_property_cache.delivery_system == SYS_ISDBT) && (state->fe.dtv_property_cache.isdbt_sb_mode == 1) | 1034 | if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT) && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) |
1031 | && | 1035 | && (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) |
1032 | (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) | 1036 | && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == |
1033 | && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == | 1037 | ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) |
1034 | ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) | 1038 | || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) |
1035 | || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) | 1039 | && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2))) |
1036 | && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2))) | 1040 | || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) |
1037 | || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) | 1041 | && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == |
1038 | && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == | 1042 | ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) |
1039 | ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) | 1043 | )) { |
1040 | )) { | ||
1041 | new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26) | 1044 | new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26) |
1042 | } | 1045 | } |
1043 | } else { | 1046 | } else { |
1044 | if ((state->fe.dtv_property_cache.inversion ^ i) == 0) | 1047 | if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) |
1045 | new_dds = state->cfg.pll->ifreq - dds_offset; | 1048 | new_dds = state->cfg.pll->ifreq - dds_offset; |
1046 | else | 1049 | else |
1047 | new_dds = state->cfg.pll->ifreq + dds_offset; | 1050 | new_dds = state->cfg.pll->ifreq + dds_offset; |
1048 | } | 1051 | } |
1049 | dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff)); | 1052 | dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff)); |
1050 | dib8000_write_word(state, 28, (u16) (new_dds & 0xffff)); | 1053 | dib8000_write_word(state, 28, (u16) (new_dds & 0xffff)); |
1051 | if (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) // if odd | 1054 | if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) // if odd |
1052 | sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3; | 1055 | sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3; |
1053 | else // if even | 1056 | else // if even |
1054 | sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3; | 1057 | sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3; |
1055 | sub_channel -= 6; | 1058 | sub_channel -= 6; |
1056 | 1059 | ||
1057 | if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K | 1060 | if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K |
1058 | || state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) { | 1061 | || state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) { |
1059 | dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1 | 1062 | dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1 |
1060 | dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1 | 1063 | dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1 |
1061 | } else { | 1064 | } else { |
@@ -1063,7 +1066,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1063 | dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0 | 1066 | dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0 |
1064 | } | 1067 | } |
1065 | 1068 | ||
1066 | switch (state->fe.dtv_property_cache.transmission_mode) { | 1069 | switch (state->fe[0]->dtv_property_cache.transmission_mode) { |
1067 | case TRANSMISSION_MODE_2K: | 1070 | case TRANSMISSION_MODE_2K: |
1068 | switch (sub_channel) { | 1071 | switch (sub_channel) { |
1069 | case -6: | 1072 | case -6: |
@@ -1209,7 +1212,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1209 | } | 1212 | } |
1210 | break; | 1213 | break; |
1211 | } | 1214 | } |
1212 | } else { // if not state->fe.dtv_property_cache.isdbt_sb_mode | 1215 | } else { // if not state->fe[0]->dtv_property_cache.isdbt_sb_mode |
1213 | dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff)); | 1216 | dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff)); |
1214 | dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff)); | 1217 | dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff)); |
1215 | dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003)); | 1218 | dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003)); |
@@ -1218,7 +1221,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1218 | dib8000_write_word(state, 10, (seq << 4)); | 1221 | dib8000_write_word(state, 10, (seq << 4)); |
1219 | // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000); | 1222 | // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000); |
1220 | 1223 | ||
1221 | switch (state->fe.dtv_property_cache.guard_interval) { | 1224 | switch (state->fe[0]->dtv_property_cache.guard_interval) { |
1222 | case GUARD_INTERVAL_1_32: | 1225 | case GUARD_INTERVAL_1_32: |
1223 | guard = 0; | 1226 | guard = 0; |
1224 | break; | 1227 | break; |
@@ -1238,7 +1241,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1238 | 1241 | ||
1239 | max_constellation = DQPSK; | 1242 | max_constellation = DQPSK; |
1240 | for (i = 0; i < 3; i++) { | 1243 | for (i = 0; i < 3; i++) { |
1241 | switch (state->fe.dtv_property_cache.layer[i].modulation) { | 1244 | switch (state->fe[0]->dtv_property_cache.layer[i].modulation) { |
1242 | case DQPSK: | 1245 | case DQPSK: |
1243 | constellation = 0; | 1246 | constellation = 0; |
1244 | break; | 1247 | break; |
@@ -1254,7 +1257,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1254 | break; | 1257 | break; |
1255 | } | 1258 | } |
1256 | 1259 | ||
1257 | switch (state->fe.dtv_property_cache.layer[i].fec) { | 1260 | switch (state->fe[0]->dtv_property_cache.layer[i].fec) { |
1258 | case FEC_1_2: | 1261 | case FEC_1_2: |
1259 | crate = 1; | 1262 | crate = 1; |
1260 | break; | 1263 | break; |
@@ -1273,26 +1276,26 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1273 | break; | 1276 | break; |
1274 | } | 1277 | } |
1275 | 1278 | ||
1276 | if ((state->fe.dtv_property_cache.layer[i].interleaving > 0) && | 1279 | if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) && |
1277 | ((state->fe.dtv_property_cache.layer[i].interleaving <= 3) || | 1280 | ((state->fe[0]->dtv_property_cache.layer[i].interleaving <= 3) || |
1278 | (state->fe.dtv_property_cache.layer[i].interleaving == 4 && state->fe.dtv_property_cache.isdbt_sb_mode == 1)) | 1281 | (state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)) |
1279 | ) | 1282 | ) |
1280 | timeI = state->fe.dtv_property_cache.layer[i].interleaving; | 1283 | timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving; |
1281 | else | 1284 | else |
1282 | timeI = 0; | 1285 | timeI = 0; |
1283 | dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe.dtv_property_cache.layer[i].segment_count & 0xf) << 6) | | 1286 | dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) | |
1284 | (crate << 3) | timeI); | 1287 | (crate << 3) | timeI); |
1285 | if (state->fe.dtv_property_cache.layer[i].segment_count > 0) { | 1288 | if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) { |
1286 | switch (max_constellation) { | 1289 | switch (max_constellation) { |
1287 | case DQPSK: | 1290 | case DQPSK: |
1288 | case QPSK: | 1291 | case QPSK: |
1289 | if (state->fe.dtv_property_cache.layer[i].modulation == QAM_16 || | 1292 | if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 || |
1290 | state->fe.dtv_property_cache.layer[i].modulation == QAM_64) | 1293 | state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64) |
1291 | max_constellation = state->fe.dtv_property_cache.layer[i].modulation; | 1294 | max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation; |
1292 | break; | 1295 | break; |
1293 | case QAM_16: | 1296 | case QAM_16: |
1294 | if (state->fe.dtv_property_cache.layer[i].modulation == QAM_64) | 1297 | if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64) |
1295 | max_constellation = state->fe.dtv_property_cache.layer[i].modulation; | 1298 | max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation; |
1296 | break; | 1299 | break; |
1297 | } | 1300 | } |
1298 | } | 1301 | } |
@@ -1303,34 +1306,34 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1303 | //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/ | 1306 | //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/ |
1304 | 1307 | ||
1305 | dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) | | 1308 | dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) | |
1306 | ((state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe.dtv_property_cache. | 1309 | ((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache. |
1307 | isdbt_sb_mode & 1) << 4)); | 1310 | isdbt_sb_mode & 1) << 4)); |
1308 | 1311 | ||
1309 | dprintk("mode = %d ; guard = %d", mode, state->fe.dtv_property_cache.guard_interval); | 1312 | dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval); |
1310 | 1313 | ||
1311 | /* signal optimization parameter */ | 1314 | /* signal optimization parameter */ |
1312 | 1315 | ||
1313 | if (state->fe.dtv_property_cache.isdbt_partial_reception) { | 1316 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) { |
1314 | seg_diff_mask = (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0]; | 1317 | seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0]; |
1315 | for (i = 1; i < 3; i++) | 1318 | for (i = 1; i < 3; i++) |
1316 | nbseg_diff += | 1319 | nbseg_diff += |
1317 | (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count; | 1320 | (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count; |
1318 | for (i = 0; i < nbseg_diff; i++) | 1321 | for (i = 0; i < nbseg_diff; i++) |
1319 | seg_diff_mask |= 1 << permu_seg[i + 1]; | 1322 | seg_diff_mask |= 1 << permu_seg[i + 1]; |
1320 | } else { | 1323 | } else { |
1321 | for (i = 0; i < 3; i++) | 1324 | for (i = 0; i < 3; i++) |
1322 | nbseg_diff += | 1325 | nbseg_diff += |
1323 | (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count; | 1326 | (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count; |
1324 | for (i = 0; i < nbseg_diff; i++) | 1327 | for (i = 0; i < nbseg_diff; i++) |
1325 | seg_diff_mask |= 1 << permu_seg[i]; | 1328 | seg_diff_mask |= 1 << permu_seg[i]; |
1326 | } | 1329 | } |
1327 | dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask); | 1330 | dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask); |
1328 | 1331 | ||
1329 | state->differential_constellation = (seg_diff_mask != 0); | 1332 | state->differential_constellation = (seg_diff_mask != 0); |
1330 | dib8000_set_diversity_in(&state->fe, state->diversity_onoff); | 1333 | dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); |
1331 | 1334 | ||
1332 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb | 1335 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb |
1333 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments | 1336 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) // 3-segments |
1334 | seg_mask13 = 0x00E0; | 1337 | seg_mask13 = 0x00E0; |
1335 | else // 1-segment | 1338 | else // 1-segment |
1336 | seg_mask13 = 0x0040; | 1339 | seg_mask13 = 0x0040; |
@@ -1340,7 +1343,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1340 | // WRITE: Mode & Diff mask | 1343 | // WRITE: Mode & Diff mask |
1341 | dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask); | 1344 | dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask); |
1342 | 1345 | ||
1343 | if ((seg_diff_mask) || (state->fe.dtv_property_cache.isdbt_sb_mode)) | 1346 | if ((seg_diff_mask) || (state->fe[0]->dtv_property_cache.isdbt_sb_mode)) |
1344 | dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200); | 1347 | dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200); |
1345 | else | 1348 | else |
1346 | dib8000_write_word(state, 268, (2 << 9) | 39); //init value | 1349 | dib8000_write_word(state, 268, (2 << 9) | 39); //init value |
@@ -1351,26 +1354,26 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1351 | 1354 | ||
1352 | dib8000_write_word(state, 353, seg_mask13); // ADDR 353 | 1355 | dib8000_write_word(state, 353, seg_mask13); // ADDR 353 |
1353 | 1356 | ||
1354 | /* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */ | 1357 | /* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */ |
1355 | // dib8000_write_word(state, 351, (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5 ); | 1358 | // dib8000_write_word(state, 351, (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5 ); |
1356 | 1359 | ||
1357 | // ---- SMALL ---- | 1360 | // ---- SMALL ---- |
1358 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { | 1361 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { |
1359 | switch (state->fe.dtv_property_cache.transmission_mode) { | 1362 | switch (state->fe[0]->dtv_property_cache.transmission_mode) { |
1360 | case TRANSMISSION_MODE_2K: | 1363 | case TRANSMISSION_MODE_2K: |
1361 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg | 1364 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg |
1362 | if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK | 1365 | if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK |
1363 | ncoeff = coeff_2k_sb_1seg_dqpsk; | 1366 | ncoeff = coeff_2k_sb_1seg_dqpsk; |
1364 | else // QPSK or QAM | 1367 | else // QPSK or QAM |
1365 | ncoeff = coeff_2k_sb_1seg; | 1368 | ncoeff = coeff_2k_sb_1seg; |
1366 | } else { // 3-segments | 1369 | } else { // 3-segments |
1367 | if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment | 1370 | if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment |
1368 | if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments | 1371 | if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments |
1369 | ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk; | 1372 | ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk; |
1370 | else // QPSK or QAM on external segments | 1373 | else // QPSK or QAM on external segments |
1371 | ncoeff = coeff_2k_sb_3seg_0dqpsk; | 1374 | ncoeff = coeff_2k_sb_3seg_0dqpsk; |
1372 | } else { // QPSK or QAM on central segment | 1375 | } else { // QPSK or QAM on central segment |
1373 | if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments | 1376 | if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments |
1374 | ncoeff = coeff_2k_sb_3seg_1dqpsk; | 1377 | ncoeff = coeff_2k_sb_3seg_1dqpsk; |
1375 | else // QPSK or QAM on external segments | 1378 | else // QPSK or QAM on external segments |
1376 | ncoeff = coeff_2k_sb_3seg; | 1379 | ncoeff = coeff_2k_sb_3seg; |
@@ -1379,20 +1382,20 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1379 | break; | 1382 | break; |
1380 | 1383 | ||
1381 | case TRANSMISSION_MODE_4K: | 1384 | case TRANSMISSION_MODE_4K: |
1382 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg | 1385 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg |
1383 | if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK | 1386 | if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK |
1384 | ncoeff = coeff_4k_sb_1seg_dqpsk; | 1387 | ncoeff = coeff_4k_sb_1seg_dqpsk; |
1385 | else // QPSK or QAM | 1388 | else // QPSK or QAM |
1386 | ncoeff = coeff_4k_sb_1seg; | 1389 | ncoeff = coeff_4k_sb_1seg; |
1387 | } else { // 3-segments | 1390 | } else { // 3-segments |
1388 | if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment | 1391 | if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment |
1389 | if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments | 1392 | if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments |
1390 | ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk; | 1393 | ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk; |
1391 | } else { // QPSK or QAM on external segments | 1394 | } else { // QPSK or QAM on external segments |
1392 | ncoeff = coeff_4k_sb_3seg_0dqpsk; | 1395 | ncoeff = coeff_4k_sb_3seg_0dqpsk; |
1393 | } | 1396 | } |
1394 | } else { // QPSK or QAM on central segment | 1397 | } else { // QPSK or QAM on central segment |
1395 | if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments | 1398 | if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments |
1396 | ncoeff = coeff_4k_sb_3seg_1dqpsk; | 1399 | ncoeff = coeff_4k_sb_3seg_1dqpsk; |
1397 | } else // QPSK or QAM on external segments | 1400 | } else // QPSK or QAM on external segments |
1398 | ncoeff = coeff_4k_sb_3seg; | 1401 | ncoeff = coeff_4k_sb_3seg; |
@@ -1403,20 +1406,20 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1403 | case TRANSMISSION_MODE_AUTO: | 1406 | case TRANSMISSION_MODE_AUTO: |
1404 | case TRANSMISSION_MODE_8K: | 1407 | case TRANSMISSION_MODE_8K: |
1405 | default: | 1408 | default: |
1406 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg | 1409 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg |
1407 | if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK | 1410 | if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK |
1408 | ncoeff = coeff_8k_sb_1seg_dqpsk; | 1411 | ncoeff = coeff_8k_sb_1seg_dqpsk; |
1409 | else // QPSK or QAM | 1412 | else // QPSK or QAM |
1410 | ncoeff = coeff_8k_sb_1seg; | 1413 | ncoeff = coeff_8k_sb_1seg; |
1411 | } else { // 3-segments | 1414 | } else { // 3-segments |
1412 | if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment | 1415 | if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment |
1413 | if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments | 1416 | if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments |
1414 | ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk; | 1417 | ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk; |
1415 | } else { // QPSK or QAM on external segments | 1418 | } else { // QPSK or QAM on external segments |
1416 | ncoeff = coeff_8k_sb_3seg_0dqpsk; | 1419 | ncoeff = coeff_8k_sb_3seg_0dqpsk; |
1417 | } | 1420 | } |
1418 | } else { // QPSK or QAM on central segment | 1421 | } else { // QPSK or QAM on central segment |
1419 | if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments | 1422 | if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments |
1420 | ncoeff = coeff_8k_sb_3seg_1dqpsk; | 1423 | ncoeff = coeff_8k_sb_3seg_1dqpsk; |
1421 | } else // QPSK or QAM on external segments | 1424 | } else // QPSK or QAM on external segments |
1422 | ncoeff = coeff_8k_sb_3seg; | 1425 | ncoeff = coeff_8k_sb_3seg; |
@@ -1430,22 +1433,22 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1430 | 1433 | ||
1431 | // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5 | 1434 | // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5 |
1432 | dib8000_write_word(state, 351, | 1435 | dib8000_write_word(state, 351, |
1433 | (state->fe.dtv_property_cache.isdbt_sb_mode << 9) | (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5); | 1436 | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5); |
1434 | 1437 | ||
1435 | // ---- COFF ---- | 1438 | // ---- COFF ---- |
1436 | // Carloff, the most robust | 1439 | // Carloff, the most robust |
1437 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // Sound Broadcasting mode - use both TMCC and AC pilots | 1440 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { // Sound Broadcasting mode - use both TMCC and AC pilots |
1438 | 1441 | ||
1439 | // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64 | 1442 | // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64 |
1440 | // 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 | 1443 | // 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 |
1441 | dib8000_write_word(state, 187, | 1444 | dib8000_write_word(state, 187, |
1442 | (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 2) | 1445 | (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2) |
1443 | | 0x3); | 1446 | | 0x3); |
1444 | 1447 | ||
1445 | /* // P_small_coef_ext_enable = 1 */ | 1448 | /* // P_small_coef_ext_enable = 1 */ |
1446 | /* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */ | 1449 | /* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */ |
1447 | 1450 | ||
1448 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg | 1451 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg |
1449 | 1452 | ||
1450 | // 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) | 1453 | // 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) |
1451 | if (mode == 3) | 1454 | if (mode == 3) |
@@ -1469,10 +1472,10 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1469 | dib8000_write_word(state, 186, 80); | 1472 | dib8000_write_word(state, 186, 80); |
1470 | } else { // Sound Broadcasting mode 3 seg | 1473 | } else { // Sound Broadcasting mode 3 seg |
1471 | // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15 | 1474 | // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15 |
1472 | /* if (mode == 3) */ | 1475 | /* if (mode == 3) */ |
1473 | /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */ | 1476 | /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */ |
1474 | /* else */ | 1477 | /* else */ |
1475 | /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */ | 1478 | /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */ |
1476 | dib8000_write_word(state, 180, 0x1fcf | (1 << 14)); | 1479 | dib8000_write_word(state, 180, 0x1fcf | (1 << 14)); |
1477 | 1480 | ||
1478 | // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1, | 1481 | // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1, |
@@ -1509,7 +1512,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1509 | dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); | 1512 | dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); |
1510 | } | 1513 | } |
1511 | // ---- FFT ---- | 1514 | // ---- FFT ---- |
1512 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 && state->fe.dtv_property_cache.isdbt_partial_reception == 0) // 1-seg | 1515 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) // 1-seg |
1513 | dib8000_write_word(state, 178, 64); // P_fft_powrange=64 | 1516 | dib8000_write_word(state, 178, 64); // P_fft_powrange=64 |
1514 | else | 1517 | else |
1515 | dib8000_write_word(state, 178, 32); // P_fft_powrange=32 | 1518 | dib8000_write_word(state, 178, 32); // P_fft_powrange=32 |
@@ -1518,12 +1521,12 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1518 | * 6bits; p_coff_thres_lock 6bits (for coff lock if needed) | 1521 | * 6bits; p_coff_thres_lock 6bits (for coff lock if needed) |
1519 | */ | 1522 | */ |
1520 | /* if ( ( nbseg_diff>0)&&(nbseg_diff<13)) | 1523 | /* if ( ( nbseg_diff>0)&&(nbseg_diff<13)) |
1521 | dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */ | 1524 | dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */ |
1522 | 1525 | ||
1523 | dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */ | 1526 | dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */ |
1524 | dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */ | 1527 | dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */ |
1525 | dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */ | 1528 | dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */ |
1526 | if ((!state->fe.dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0)) | 1529 | if ((!state->fe[0]->dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0)) |
1527 | dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */ | 1530 | dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */ |
1528 | else | 1531 | else |
1529 | dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */ | 1532 | dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */ |
@@ -1538,8 +1541,8 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1538 | dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */ | 1541 | dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */ |
1539 | 1542 | ||
1540 | /* offset loop parameters */ | 1543 | /* offset loop parameters */ |
1541 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { | 1544 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { |
1542 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg | 1545 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg |
1543 | /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */ | 1546 | /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */ |
1544 | dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40); | 1547 | dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40); |
1545 | 1548 | ||
@@ -1551,8 +1554,8 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1551 | /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */ | 1554 | /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */ |
1552 | dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80); | 1555 | dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80); |
1553 | 1556 | ||
1554 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { | 1557 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { |
1555 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg | 1558 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg |
1556 | /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */ | 1559 | /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */ |
1557 | dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode)); | 1560 | dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode)); |
1558 | 1561 | ||
@@ -1564,7 +1567,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1564 | dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode)); | 1567 | dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode)); |
1565 | 1568 | ||
1566 | /* P_dvsy_sync_wait - reuse mode */ | 1569 | /* P_dvsy_sync_wait - reuse mode */ |
1567 | switch (state->fe.dtv_property_cache.transmission_mode) { | 1570 | switch (state->fe[0]->dtv_property_cache.transmission_mode) { |
1568 | case TRANSMISSION_MODE_8K: | 1571 | case TRANSMISSION_MODE_8K: |
1569 | mode = 256; | 1572 | mode = 256; |
1570 | break; | 1573 | break; |
@@ -1624,15 +1627,15 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1624 | } | 1627 | } |
1625 | 1628 | ||
1626 | // ---- ANA_FE ---- | 1629 | // ---- ANA_FE ---- |
1627 | if (state->fe.dtv_property_cache.isdbt_sb_mode) { | 1630 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) { |
1628 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments | 1631 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) // 3-segments |
1629 | ana_fe = ana_fe_coeff_3seg; | 1632 | ana_fe = ana_fe_coeff_3seg; |
1630 | else // 1-segment | 1633 | else // 1-segment |
1631 | ana_fe = ana_fe_coeff_1seg; | 1634 | ana_fe = ana_fe_coeff_1seg; |
1632 | } else | 1635 | } else |
1633 | ana_fe = ana_fe_coeff_13seg; | 1636 | ana_fe = ana_fe_coeff_13seg; |
1634 | 1637 | ||
1635 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0) | 1638 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0) |
1636 | for (mode = 0; mode < 24; mode++) | 1639 | for (mode = 0; mode < 24; mode++) |
1637 | dib8000_write_word(state, 117 + mode, ana_fe[mode]); | 1640 | dib8000_write_word(state, 117 + mode, ana_fe[mode]); |
1638 | 1641 | ||
@@ -1648,11 +1651,11 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1648 | // "P_cspu_left_edge" not used => do not care | 1651 | // "P_cspu_left_edge" not used => do not care |
1649 | // "P_cspu_right_edge" not used => do not care | 1652 | // "P_cspu_right_edge" not used => do not care |
1650 | 1653 | ||
1651 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb | 1654 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb |
1652 | dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1 | 1655 | dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1 |
1653 | dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0 | 1656 | dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0 |
1654 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 0 // 1-segment | 1657 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0 // 1-segment |
1655 | && state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) { | 1658 | && state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) { |
1656 | //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0 | 1659 | //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0 |
1657 | dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15 | 1660 | dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15 |
1658 | } | 1661 | } |
@@ -1664,7 +1667,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1664 | // ---- TMCC ---- | 1667 | // ---- TMCC ---- |
1665 | for (i = 0; i < 3; i++) | 1668 | for (i = 0; i < 3; i++) |
1666 | tmcc_pow += | 1669 | tmcc_pow += |
1667 | (((state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe.dtv_property_cache.layer[i].segment_count); | 1670 | (((state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe[0]->dtv_property_cache.layer[i].segment_count); |
1668 | // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9); | 1671 | // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9); |
1669 | // Threshold is set at 1/4 of max power. | 1672 | // Threshold is set at 1/4 of max power. |
1670 | tmcc_pow *= (1 << (9 - 2)); | 1673 | tmcc_pow *= (1 << (9 - 2)); |
@@ -1678,7 +1681,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1678 | if (state->isdbt_cfg_loaded == 0) | 1681 | if (state->isdbt_cfg_loaded == 0) |
1679 | dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */ | 1682 | dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */ |
1680 | 1683 | ||
1681 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) | 1684 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) |
1682 | state->isdbt_cfg_loaded = 0; | 1685 | state->isdbt_cfg_loaded = 0; |
1683 | else | 1686 | else |
1684 | state->isdbt_cfg_loaded = 1; | 1687 | state->isdbt_cfg_loaded = 1; |
@@ -1693,38 +1696,38 @@ static int dib8000_autosearch_start(struct dvb_frontend *fe) | |||
1693 | 1696 | ||
1694 | int slist = 0; | 1697 | int slist = 0; |
1695 | 1698 | ||
1696 | state->fe.dtv_property_cache.inversion = 0; | 1699 | state->fe[0]->dtv_property_cache.inversion = 0; |
1697 | if (!state->fe.dtv_property_cache.isdbt_sb_mode) | 1700 | if (!state->fe[0]->dtv_property_cache.isdbt_sb_mode) |
1698 | state->fe.dtv_property_cache.layer[0].segment_count = 13; | 1701 | state->fe[0]->dtv_property_cache.layer[0].segment_count = 13; |
1699 | state->fe.dtv_property_cache.layer[0].modulation = QAM_64; | 1702 | state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64; |
1700 | state->fe.dtv_property_cache.layer[0].fec = FEC_2_3; | 1703 | state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3; |
1701 | state->fe.dtv_property_cache.layer[0].interleaving = 0; | 1704 | state->fe[0]->dtv_property_cache.layer[0].interleaving = 0; |
1702 | 1705 | ||
1703 | //choose the right list, in sb, always do everything | 1706 | //choose the right list, in sb, always do everything |
1704 | if (state->fe.dtv_property_cache.isdbt_sb_mode) { | 1707 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) { |
1705 | state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K; | 1708 | state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K; |
1706 | state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8; | 1709 | state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8; |
1707 | slist = 7; | 1710 | slist = 7; |
1708 | dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); | 1711 | dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); |
1709 | } else { | 1712 | } else { |
1710 | if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) { | 1713 | if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) { |
1711 | if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) { | 1714 | if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) { |
1712 | slist = 7; | 1715 | slist = 7; |
1713 | dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2 | 1716 | dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2 |
1714 | } else | 1717 | } else |
1715 | slist = 3; | 1718 | slist = 3; |
1716 | } else { | 1719 | } else { |
1717 | if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) { | 1720 | if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) { |
1718 | slist = 2; | 1721 | slist = 2; |
1719 | dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 | 1722 | dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 |
1720 | } else | 1723 | } else |
1721 | slist = 0; | 1724 | slist = 0; |
1722 | } | 1725 | } |
1723 | 1726 | ||
1724 | if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) | 1727 | if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) |
1725 | state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K; | 1728 | state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K; |
1726 | if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) | 1729 | if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) |
1727 | state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8; | 1730 | state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8; |
1728 | 1731 | ||
1729 | dprintk("using list for autosearch : %d", slist); | 1732 | dprintk("using list for autosearch : %d", slist); |
1730 | dib8000_set_channel(state, (unsigned char)slist, 1); | 1733 | dib8000_set_channel(state, (unsigned char)slist, 1); |
@@ -1786,7 +1789,7 @@ static int dib8000_tune(struct dvb_frontend *fe) | |||
1786 | if (state == NULL) | 1789 | if (state == NULL) |
1787 | return -EINVAL; | 1790 | return -EINVAL; |
1788 | 1791 | ||
1789 | dib8000_set_bandwidth(state, state->fe.dtv_property_cache.bandwidth_hz / 1000); | 1792 | dib8000_set_bandwidth(fe, state->fe[0]->dtv_property_cache.bandwidth_hz / 1000); |
1790 | dib8000_set_channel(state, 0, 0); | 1793 | dib8000_set_channel(state, 0, 0); |
1791 | 1794 | ||
1792 | // restart demod | 1795 | // restart demod |
@@ -1799,17 +1802,16 @@ static int dib8000_tune(struct dvb_frontend *fe) | |||
1799 | 1802 | ||
1800 | // never achieved a lock before - wait for timfreq to update | 1803 | // never achieved a lock before - wait for timfreq to update |
1801 | if (state->timf == 0) { | 1804 | if (state->timf == 0) { |
1802 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { | 1805 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { |
1803 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg | 1806 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg |
1804 | msleep(300); | 1807 | msleep(300); |
1805 | else // Sound Broadcasting mode 3 seg | 1808 | else // Sound Broadcasting mode 3 seg |
1806 | msleep(500); | 1809 | msleep(500); |
1807 | } else // 13 seg | 1810 | } else // 13 seg |
1808 | msleep(200); | 1811 | msleep(200); |
1809 | } | 1812 | } |
1810 | //dump_reg(state); | 1813 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { |
1811 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { | 1814 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg |
1812 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg | ||
1813 | 1815 | ||
1814 | /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */ | 1816 | /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */ |
1815 | dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40); | 1817 | dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40); |
@@ -1854,26 +1856,38 @@ static int dib8000_tune(struct dvb_frontend *fe) | |||
1854 | static int dib8000_wakeup(struct dvb_frontend *fe) | 1856 | static int dib8000_wakeup(struct dvb_frontend *fe) |
1855 | { | 1857 | { |
1856 | struct dib8000_state *state = fe->demodulator_priv; | 1858 | struct dib8000_state *state = fe->demodulator_priv; |
1859 | u8 index_frontend; | ||
1860 | int ret; | ||
1857 | 1861 | ||
1858 | dib8000_set_power_mode(state, DIB8000M_POWER_ALL); | 1862 | dib8000_set_power_mode(state, DIB8000M_POWER_ALL); |
1859 | dib8000_set_adc_state(state, DIBX000_ADC_ON); | 1863 | dib8000_set_adc_state(state, DIBX000_ADC_ON); |
1860 | if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) | 1864 | if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) |
1861 | dprintk("could not start Slow ADC"); | 1865 | dprintk("could not start Slow ADC"); |
1862 | 1866 | ||
1867 | for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
1868 | ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]); | ||
1869 | if (ret<0) | ||
1870 | return ret; | ||
1871 | } | ||
1872 | |||
1863 | return 0; | 1873 | return 0; |
1864 | } | 1874 | } |
1865 | 1875 | ||
1866 | static int dib8000_sleep(struct dvb_frontend *fe) | 1876 | static int dib8000_sleep(struct dvb_frontend *fe) |
1867 | { | 1877 | { |
1868 | struct dib8000_state *st = fe->demodulator_priv; | 1878 | struct dib8000_state *state = fe->demodulator_priv; |
1869 | if (1) { | 1879 | u8 index_frontend; |
1870 | dib8000_set_output_mode(st, OUTMODE_HIGH_Z); | 1880 | int ret; |
1871 | dib8000_set_power_mode(st, DIB8000M_POWER_INTERFACE_ONLY); | ||
1872 | return dib8000_set_adc_state(st, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(st, DIBX000_ADC_OFF); | ||
1873 | } else { | ||
1874 | 1881 | ||
1875 | return 0; | 1882 | for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { |
1883 | ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]); | ||
1884 | if (ret < 0) | ||
1885 | return ret; | ||
1876 | } | 1886 | } |
1887 | |||
1888 | dib8000_set_output_mode(fe, OUTMODE_HIGH_Z); | ||
1889 | dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY); | ||
1890 | return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF); | ||
1877 | } | 1891 | } |
1878 | 1892 | ||
1879 | enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe) | 1893 | enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe) |
@@ -1891,16 +1905,40 @@ int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tun | |||
1891 | } | 1905 | } |
1892 | EXPORT_SYMBOL(dib8000_set_tune_state); | 1906 | EXPORT_SYMBOL(dib8000_set_tune_state); |
1893 | 1907 | ||
1894 | |||
1895 | |||
1896 | |||
1897 | static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) | 1908 | static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) |
1898 | { | 1909 | { |
1899 | struct dib8000_state *state = fe->demodulator_priv; | 1910 | struct dib8000_state *state = fe->demodulator_priv; |
1900 | u16 i, val = 0; | 1911 | u16 i, val = 0; |
1912 | fe_status_t stat; | ||
1913 | u8 index_frontend, sub_index_frontend; | ||
1901 | 1914 | ||
1902 | fe->dtv_property_cache.bandwidth_hz = 6000000; | 1915 | fe->dtv_property_cache.bandwidth_hz = 6000000; |
1903 | 1916 | ||
1917 | for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
1918 | state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat); | ||
1919 | if (stat&FE_HAS_SYNC) { | ||
1920 | dprintk("TMCC lock on the slave%i", index_frontend); | ||
1921 | /* synchronize the cache with the other frontends */ | ||
1922 | state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep); | ||
1923 | for (sub_index_frontend=0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) { | ||
1924 | if (sub_index_frontend != index_frontend) { | ||
1925 | state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode; | ||
1926 | state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion; | ||
1927 | state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode; | ||
1928 | state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval; | ||
1929 | state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception; | ||
1930 | for (i = 0; i < 3; i++) { | ||
1931 | state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count; | ||
1932 | state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving; | ||
1933 | state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec; | ||
1934 | state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation; | ||
1935 | } | ||
1936 | } | ||
1937 | } | ||
1938 | return 0; | ||
1939 | } | ||
1940 | } | ||
1941 | |||
1904 | fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1; | 1942 | fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1; |
1905 | 1943 | ||
1906 | val = dib8000_read_word(state, 570); | 1944 | val = dib8000_read_word(state, 570); |
@@ -1992,112 +2030,201 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par | |||
1992 | break; | 2030 | break; |
1993 | } | 2031 | } |
1994 | } | 2032 | } |
2033 | |||
2034 | /* synchronize the cache with the other frontends */ | ||
2035 | for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
2036 | state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode; | ||
2037 | state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion; | ||
2038 | state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode; | ||
2039 | state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval; | ||
2040 | state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception; | ||
2041 | for (i = 0; i < 3; i++) { | ||
2042 | state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count; | ||
2043 | state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving; | ||
2044 | state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec; | ||
2045 | state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation; | ||
2046 | } | ||
2047 | } | ||
1995 | return 0; | 2048 | return 0; |
1996 | } | 2049 | } |
1997 | 2050 | ||
1998 | static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) | 2051 | static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) |
1999 | { | 2052 | { |
2000 | struct dib8000_state *state = fe->demodulator_priv; | 2053 | struct dib8000_state *state = fe->demodulator_priv; |
2054 | u8 nbr_pending, exit_condition, index_frontend; | ||
2055 | s8 index_frontend_success = -1; | ||
2001 | int time, ret; | 2056 | int time, ret; |
2057 | int time_slave = FE_CALLBACK_TIME_NEVER; | ||
2058 | |||
2059 | if (state->fe[0]->dtv_property_cache.frequency == 0) { | ||
2060 | dprintk("dib8000: must at least specify frequency "); | ||
2061 | return 0; | ||
2062 | } | ||
2063 | |||
2064 | if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) { | ||
2065 | dprintk("dib8000: no bandwidth specified, set to default "); | ||
2066 | state->fe[0]->dtv_property_cache.bandwidth_hz = 6000000; | ||
2067 | } | ||
2002 | 2068 | ||
2003 | fe->dtv_property_cache.delivery_system = SYS_ISDBT; | 2069 | for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { |
2070 | /* synchronization of the cache */ | ||
2071 | state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT; | ||
2072 | memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties)); | ||
2004 | 2073 | ||
2005 | dib8000_set_output_mode(state, OUTMODE_HIGH_Z); | 2074 | dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z); |
2075 | if (state->fe[index_frontend]->ops.tuner_ops.set_params) | ||
2076 | state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend], fep); | ||
2006 | 2077 | ||
2007 | if (fe->ops.tuner_ops.set_params) | 2078 | dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START); |
2008 | fe->ops.tuner_ops.set_params(fe, fep); | 2079 | } |
2009 | 2080 | ||
2010 | /* start up the AGC */ | 2081 | /* start up the AGC */ |
2011 | state->tune_state = CT_AGC_START; | ||
2012 | do { | 2082 | do { |
2013 | time = dib8000_agc_startup(fe); | 2083 | time = dib8000_agc_startup(state->fe[0]); |
2084 | for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
2085 | time_slave = dib8000_agc_startup(state->fe[index_frontend]); | ||
2086 | if (time == FE_CALLBACK_TIME_NEVER) | ||
2087 | time = time_slave; | ||
2088 | else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time)) | ||
2089 | time = time_slave; | ||
2090 | } | ||
2014 | if (time != FE_CALLBACK_TIME_NEVER) | 2091 | if (time != FE_CALLBACK_TIME_NEVER) |
2015 | msleep(time / 10); | 2092 | msleep(time / 10); |
2016 | else | 2093 | else |
2017 | break; | 2094 | break; |
2018 | } while (state->tune_state != CT_AGC_STOP); | 2095 | exit_condition = 1; |
2019 | 2096 | for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | |
2020 | if (state->fe.dtv_property_cache.frequency == 0) { | 2097 | if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) { |
2021 | dprintk("dib8000: must at least specify frequency "); | 2098 | exit_condition = 0; |
2022 | return 0; | 2099 | break; |
2100 | } | ||
2101 | } | ||
2102 | } while (exit_condition == 0); | ||
2103 | |||
2104 | for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) | ||
2105 | dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START); | ||
2106 | |||
2107 | if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) || | ||
2108 | (state->fe[0]->dtv_property_cache.inversion == INVERSION_AUTO) || | ||
2109 | (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) || | ||
2110 | (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) || | ||
2111 | (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) && | ||
2112 | (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0xff) && | ||
2113 | (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0) && | ||
2114 | ((state->fe[0]->dtv_property_cache.layer[0].modulation == QAM_AUTO) || | ||
2115 | (state->fe[0]->dtv_property_cache.layer[0].fec == FEC_AUTO))) || | ||
2116 | (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) && | ||
2117 | (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0xff) && | ||
2118 | (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0) && | ||
2119 | ((state->fe[0]->dtv_property_cache.layer[1].modulation == QAM_AUTO) || | ||
2120 | (state->fe[0]->dtv_property_cache.layer[1].fec == FEC_AUTO))) || | ||
2121 | (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) && | ||
2122 | (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0xff) && | ||
2123 | (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0) && | ||
2124 | ((state->fe[0]->dtv_property_cache.layer[2].modulation == QAM_AUTO) || | ||
2125 | (state->fe[0]->dtv_property_cache.layer[2].fec == FEC_AUTO))) || | ||
2126 | (((state->fe[0]->dtv_property_cache.layer[0].segment_count == 0) || | ||
2127 | ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) && | ||
2128 | ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) || | ||
2129 | ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) && | ||
2130 | ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) { | ||
2131 | int i = 80000; | ||
2132 | u8 found = 0; | ||
2133 | u8 tune_failed = 0; | ||
2134 | |||
2135 | for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
2136 | dib8000_set_bandwidth(state->fe[index_frontend], fe->dtv_property_cache.bandwidth_hz / 1000); | ||
2137 | dib8000_autosearch_start(state->fe[index_frontend]); | ||
2138 | } | ||
2139 | |||
2140 | do { | ||
2141 | msleep(10); | ||
2142 | nbr_pending = 0; | ||
2143 | exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */ | ||
2144 | for (index_frontend=0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
2145 | if (((tune_failed >> index_frontend) & 0x1) == 0) { | ||
2146 | found = dib8000_autosearch_irq(state->fe[index_frontend]); | ||
2147 | switch (found) { | ||
2148 | case 0: /* tune pending */ | ||
2149 | nbr_pending++; | ||
2150 | break; | ||
2151 | case 2: | ||
2152 | dprintk("autosearch succeed on the frontend%i", index_frontend); | ||
2153 | exit_condition = 2; | ||
2154 | index_frontend_success = index_frontend; | ||
2155 | break; | ||
2156 | default: | ||
2157 | dprintk("unhandled autosearch result"); | ||
2158 | case 1: | ||
2159 | tune_failed |= (1 << index_frontend); | ||
2160 | dprintk("autosearch failed for the frontend%i", index_frontend); | ||
2161 | break; | ||
2162 | } | ||
2163 | } | ||
2164 | } | ||
2165 | |||
2166 | /* if all tune are done and no success, exit: tune failed */ | ||
2167 | if ((nbr_pending == 0) && (exit_condition == 0)) | ||
2168 | exit_condition = 1; | ||
2169 | } while ((exit_condition == 0) && i--); | ||
2170 | |||
2171 | if (exit_condition == 1) { /* tune failed */ | ||
2172 | dprintk("tune failed"); | ||
2173 | return 0; | ||
2174 | } | ||
2175 | |||
2176 | dprintk("tune success on frontend%i", index_frontend_success); | ||
2177 | |||
2178 | dib8000_get_frontend(fe, fep); | ||
2179 | } | ||
2180 | |||
2181 | for (index_frontend=0, ret=0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
2182 | ret = dib8000_tune(state->fe[index_frontend]); | ||
2023 | } | 2183 | } |
2024 | 2184 | ||
2025 | if (state->fe.dtv_property_cache.bandwidth_hz == 0) { | 2185 | /* set output mode and diversity input */ |
2026 | dprintk("dib8000: no bandwidth specified, set to default "); | 2186 | dib8000_set_output_mode(state->fe[0], state->cfg.output_mode); |
2027 | state->fe.dtv_property_cache.bandwidth_hz = 6000000; | 2187 | for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { |
2188 | dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY); | ||
2189 | dib8000_set_diversity_in(state->fe[index_frontend-1], 1); | ||
2028 | } | 2190 | } |
2029 | 2191 | ||
2030 | state->tune_state = CT_DEMOD_START; | 2192 | /* turn off the diversity of the last chip */ |
2031 | 2193 | dib8000_set_diversity_in(state->fe[index_frontend-1], 0); | |
2032 | if ((state->fe.dtv_property_cache.delivery_system != SYS_ISDBT) || | ||
2033 | (state->fe.dtv_property_cache.inversion == INVERSION_AUTO) || | ||
2034 | (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) || | ||
2035 | (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) || | ||
2036 | (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) && | ||
2037 | (state->fe.dtv_property_cache.layer[0].segment_count != 0xff) && | ||
2038 | (state->fe.dtv_property_cache.layer[0].segment_count != 0) && | ||
2039 | ((state->fe.dtv_property_cache.layer[0].modulation == QAM_AUTO) || | ||
2040 | (state->fe.dtv_property_cache.layer[0].fec == FEC_AUTO))) || | ||
2041 | (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) && | ||
2042 | (state->fe.dtv_property_cache.layer[1].segment_count != 0xff) && | ||
2043 | (state->fe.dtv_property_cache.layer[1].segment_count != 0) && | ||
2044 | ((state->fe.dtv_property_cache.layer[1].modulation == QAM_AUTO) || | ||
2045 | (state->fe.dtv_property_cache.layer[1].fec == FEC_AUTO))) || | ||
2046 | (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) && | ||
2047 | (state->fe.dtv_property_cache.layer[2].segment_count != 0xff) && | ||
2048 | (state->fe.dtv_property_cache.layer[2].segment_count != 0) && | ||
2049 | ((state->fe.dtv_property_cache.layer[2].modulation == QAM_AUTO) || | ||
2050 | (state->fe.dtv_property_cache.layer[2].fec == FEC_AUTO))) || | ||
2051 | (((state->fe.dtv_property_cache.layer[0].segment_count == 0) || | ||
2052 | ((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) && | ||
2053 | ((state->fe.dtv_property_cache.layer[1].segment_count == 0) || | ||
2054 | ((state->fe.dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) && | ||
2055 | ((state->fe.dtv_property_cache.layer[2].segment_count == 0) || ((state->fe.dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) { | ||
2056 | int i = 800, found; | ||
2057 | |||
2058 | dib8000_set_bandwidth(state, fe->dtv_property_cache.bandwidth_hz / 1000); | ||
2059 | dib8000_autosearch_start(fe); | ||
2060 | do { | ||
2061 | msleep(10); | ||
2062 | found = dib8000_autosearch_irq(fe); | ||
2063 | } while (found == 0 && i--); | ||
2064 | |||
2065 | dprintk("Frequency %d Hz, autosearch returns: %d", fep->frequency, found); | ||
2066 | |||
2067 | if (found == 0 || found == 1) | ||
2068 | return 0; // no channel found | ||
2069 | |||
2070 | dib8000_get_frontend(fe, fep); | ||
2071 | } | ||
2072 | 2194 | ||
2073 | ret = dib8000_tune(fe); | 2195 | return ret; |
2196 | } | ||
2074 | 2197 | ||
2075 | /* make this a config parameter */ | 2198 | static u16 dib8000_read_lock(struct dvb_frontend *fe) { |
2076 | dib8000_set_output_mode(state, state->cfg.output_mode); | 2199 | struct dib8000_state *state = fe->demodulator_priv; |
2077 | 2200 | ||
2078 | return ret; | 2201 | return dib8000_read_word(state, 568); |
2079 | } | 2202 | } |
2080 | 2203 | ||
2081 | static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) | 2204 | static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) |
2082 | { | 2205 | { |
2083 | struct dib8000_state *state = fe->demodulator_priv; | 2206 | struct dib8000_state *state = fe->demodulator_priv; |
2084 | u16 lock = dib8000_read_word(state, 568); | 2207 | u16 lock_slave = 0, lock = dib8000_read_word(state, 568); |
2208 | u8 index_frontend; | ||
2209 | |||
2210 | for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) | ||
2211 | lock_slave |= dib8000_read_lock(state->fe[index_frontend]); | ||
2085 | 2212 | ||
2086 | *stat = 0; | 2213 | *stat = 0; |
2087 | 2214 | ||
2088 | if ((lock >> 13) & 1) | 2215 | if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1)) |
2089 | *stat |= FE_HAS_SIGNAL; | 2216 | *stat |= FE_HAS_SIGNAL; |
2090 | 2217 | ||
2091 | if ((lock >> 8) & 1) /* Equal */ | 2218 | if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */ |
2092 | *stat |= FE_HAS_CARRIER; | 2219 | *stat |= FE_HAS_CARRIER; |
2093 | 2220 | ||
2094 | if (((lock >> 1) & 0xf) == 0xf) /* TMCC_SYNC */ | 2221 | if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */ |
2095 | *stat |= FE_HAS_SYNC; | 2222 | *stat |= FE_HAS_SYNC; |
2096 | 2223 | ||
2097 | if (((lock >> 12) & 1) && ((lock >> 5) & 7)) /* FEC MPEG */ | 2224 | if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */ |
2098 | *stat |= FE_HAS_LOCK; | 2225 | *stat |= FE_HAS_LOCK; |
2099 | 2226 | ||
2100 | if ((lock >> 12) & 1) { | 2227 | if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) { |
2101 | lock = dib8000_read_word(state, 554); /* Viterbi Layer A */ | 2228 | lock = dib8000_read_word(state, 554); /* Viterbi Layer A */ |
2102 | if (lock & 0x01) | 2229 | if (lock & 0x01) |
2103 | *stat |= FE_HAS_VITERBI; | 2230 | *stat |= FE_HAS_VITERBI; |
@@ -2131,44 +2258,120 @@ static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) | |||
2131 | static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) | 2258 | static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) |
2132 | { | 2259 | { |
2133 | struct dib8000_state *state = fe->demodulator_priv; | 2260 | struct dib8000_state *state = fe->demodulator_priv; |
2134 | u16 val = dib8000_read_word(state, 390); | 2261 | u8 index_frontend; |
2135 | *strength = 65535 - val; | 2262 | u16 val; |
2263 | |||
2264 | *strength = 0; | ||
2265 | for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
2266 | state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val); | ||
2267 | if (val > 65535 - *strength) | ||
2268 | *strength = 65535; | ||
2269 | else | ||
2270 | *strength += val; | ||
2271 | } | ||
2272 | |||
2273 | val = 65535 - dib8000_read_word(state, 390); | ||
2274 | if (val > 65535 - *strength) | ||
2275 | *strength = 65535; | ||
2276 | else | ||
2277 | *strength += val; | ||
2136 | return 0; | 2278 | return 0; |
2137 | } | 2279 | } |
2138 | 2280 | ||
2139 | static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr) | 2281 | static u32 dib8000_get_snr(struct dvb_frontend *fe) |
2140 | { | 2282 | { |
2141 | struct dib8000_state *state = fe->demodulator_priv; | 2283 | struct dib8000_state *state = fe->demodulator_priv; |
2284 | u32 n, s, exp; | ||
2142 | u16 val; | 2285 | u16 val; |
2143 | s32 signal_mant, signal_exp, noise_mant, noise_exp; | ||
2144 | u32 result = 0; | ||
2145 | 2286 | ||
2146 | val = dib8000_read_word(state, 542); | 2287 | val = dib8000_read_word(state, 542); |
2147 | noise_mant = (val >> 6) & 0xff; | 2288 | n = (val >> 6) & 0xff; |
2148 | noise_exp = (val & 0x3f); | 2289 | exp = (val & 0x3f); |
2290 | if ((exp & 0x20) != 0) | ||
2291 | exp -= 0x40; | ||
2292 | n <<= exp+16; | ||
2149 | 2293 | ||
2150 | val = dib8000_read_word(state, 543); | 2294 | val = dib8000_read_word(state, 543); |
2151 | signal_mant = (val >> 6) & 0xff; | 2295 | s = (val >> 6) & 0xff; |
2152 | signal_exp = (val & 0x3f); | 2296 | exp = (val & 0x3f); |
2297 | if ((exp & 0x20) != 0) | ||
2298 | exp -= 0x40; | ||
2299 | s <<= exp+16; | ||
2300 | |||
2301 | if (n > 0) { | ||
2302 | u32 t = (s/n) << 16; | ||
2303 | return t + ((s << 16) - n*t) / n; | ||
2304 | } | ||
2305 | return 0xffffffff; | ||
2306 | } | ||
2307 | |||
2308 | static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr) | ||
2309 | { | ||
2310 | struct dib8000_state *state = fe->demodulator_priv; | ||
2311 | u8 index_frontend; | ||
2312 | u32 snr_master; | ||
2153 | 2313 | ||
2154 | if ((noise_exp & 0x20) != 0) | 2314 | snr_master = dib8000_get_snr(fe); |
2155 | noise_exp -= 0x40; | 2315 | for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) |
2156 | if ((signal_exp & 0x20) != 0) | 2316 | snr_master += dib8000_get_snr(state->fe[index_frontend]); |
2157 | signal_exp -= 0x40; | ||
2158 | 2317 | ||
2159 | if (signal_mant != 0) | 2318 | if (snr_master != 0) { |
2160 | result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant); | 2319 | snr_master = 10*intlog10(snr_master>>16); |
2161 | else | 2320 | *snr = snr_master / ((1 << 24) / 10); |
2162 | result = intlog10(2) * 10 * signal_exp - 100; | 2321 | } |
2163 | if (noise_mant != 0) | ||
2164 | result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant); | ||
2165 | else | 2322 | else |
2166 | result -= intlog10(2) * 10 * noise_exp - 100; | 2323 | *snr = 0; |
2167 | 2324 | ||
2168 | *snr = result / ((1 << 24) / 10); | ||
2169 | return 0; | 2325 | return 0; |
2170 | } | 2326 | } |
2171 | 2327 | ||
2328 | int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave) | ||
2329 | { | ||
2330 | struct dib8000_state *state = fe->demodulator_priv; | ||
2331 | u8 index_frontend = 1; | ||
2332 | |||
2333 | while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL)) | ||
2334 | index_frontend++; | ||
2335 | if (index_frontend < MAX_NUMBER_OF_FRONTENDS) { | ||
2336 | dprintk("set slave fe %p to index %i", fe_slave, index_frontend); | ||
2337 | state->fe[index_frontend] = fe_slave; | ||
2338 | return 0; | ||
2339 | } | ||
2340 | |||
2341 | dprintk("too many slave frontend"); | ||
2342 | return -ENOMEM; | ||
2343 | } | ||
2344 | EXPORT_SYMBOL(dib8000_set_slave_frontend); | ||
2345 | |||
2346 | int dib8000_remove_slave_frontend(struct dvb_frontend *fe) | ||
2347 | { | ||
2348 | struct dib8000_state *state = fe->demodulator_priv; | ||
2349 | u8 index_frontend = 1; | ||
2350 | |||
2351 | while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL)) | ||
2352 | index_frontend++; | ||
2353 | if (index_frontend != 1) { | ||
2354 | dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1); | ||
2355 | state->fe[index_frontend] = NULL; | ||
2356 | return 0; | ||
2357 | } | ||
2358 | |||
2359 | dprintk("no frontend to be removed"); | ||
2360 | return -ENODEV; | ||
2361 | } | ||
2362 | EXPORT_SYMBOL(dib8000_remove_slave_frontend); | ||
2363 | |||
2364 | struct dvb_frontend * dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) | ||
2365 | { | ||
2366 | struct dib8000_state *state = fe->demodulator_priv; | ||
2367 | |||
2368 | if (slave_index >= MAX_NUMBER_OF_FRONTENDS) | ||
2369 | return NULL; | ||
2370 | return state->fe[slave_index]; | ||
2371 | } | ||
2372 | EXPORT_SYMBOL(dib8000_get_slave_frontend); | ||
2373 | |||
2374 | |||
2172 | int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) | 2375 | int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) |
2173 | { | 2376 | { |
2174 | int k = 0; | 2377 | int k = 0; |
@@ -2227,7 +2430,13 @@ static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_fron | |||
2227 | static void dib8000_release(struct dvb_frontend *fe) | 2430 | static void dib8000_release(struct dvb_frontend *fe) |
2228 | { | 2431 | { |
2229 | struct dib8000_state *st = fe->demodulator_priv; | 2432 | struct dib8000_state *st = fe->demodulator_priv; |
2433 | u8 index_frontend; | ||
2434 | |||
2435 | for (index_frontend=1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++) | ||
2436 | dvb_frontend_detach(st->fe[index_frontend]); | ||
2437 | |||
2230 | dibx000_exit_i2c_master(&st->i2c_master); | 2438 | dibx000_exit_i2c_master(&st->i2c_master); |
2439 | kfree(st->fe[0]); | ||
2231 | kfree(st); | 2440 | kfree(st); |
2232 | } | 2441 | } |
2233 | 2442 | ||
@@ -2242,19 +2451,19 @@ EXPORT_SYMBOL(dib8000_get_i2c_master); | |||
2242 | int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) | 2451 | int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) |
2243 | { | 2452 | { |
2244 | struct dib8000_state *st = fe->demodulator_priv; | 2453 | struct dib8000_state *st = fe->demodulator_priv; |
2245 | u16 val = dib8000_read_word(st, 299) & 0xffef; | 2454 | u16 val = dib8000_read_word(st, 299) & 0xffef; |
2246 | val |= (onoff & 0x1) << 4; | 2455 | val |= (onoff & 0x1) << 4; |
2247 | 2456 | ||
2248 | dprintk("pid filter enabled %d", onoff); | 2457 | dprintk("pid filter enabled %d", onoff); |
2249 | return dib8000_write_word(st, 299, val); | 2458 | return dib8000_write_word(st, 299, val); |
2250 | } | 2459 | } |
2251 | EXPORT_SYMBOL(dib8000_pid_filter_ctrl); | 2460 | EXPORT_SYMBOL(dib8000_pid_filter_ctrl); |
2252 | 2461 | ||
2253 | int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) | 2462 | int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) |
2254 | { | 2463 | { |
2255 | struct dib8000_state *st = fe->demodulator_priv; | 2464 | struct dib8000_state *st = fe->demodulator_priv; |
2256 | dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); | 2465 | dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); |
2257 | return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0); | 2466 | return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0); |
2258 | } | 2467 | } |
2259 | EXPORT_SYMBOL(dib8000_pid_filter); | 2468 | EXPORT_SYMBOL(dib8000_pid_filter); |
2260 | 2469 | ||
@@ -2298,6 +2507,9 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s | |||
2298 | state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL); | 2507 | state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL); |
2299 | if (state == NULL) | 2508 | if (state == NULL) |
2300 | return NULL; | 2509 | return NULL; |
2510 | fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL); | ||
2511 | if (fe == NULL) | ||
2512 | return NULL; | ||
2301 | 2513 | ||
2302 | memcpy(&state->cfg, cfg, sizeof(struct dib8000_config)); | 2514 | memcpy(&state->cfg, cfg, sizeof(struct dib8000_config)); |
2303 | state->i2c.adap = i2c_adap; | 2515 | state->i2c.adap = i2c_adap; |
@@ -2311,9 +2523,9 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s | |||
2311 | if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK)) | 2523 | if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK)) |
2312 | state->cfg.output_mode = OUTMODE_MPEG2_FIFO; | 2524 | state->cfg.output_mode = OUTMODE_MPEG2_FIFO; |
2313 | 2525 | ||
2314 | fe = &state->fe; | 2526 | state->fe[0] = fe; |
2315 | fe->demodulator_priv = state; | 2527 | fe->demodulator_priv = state; |
2316 | memcpy(&state->fe.ops, &dib8000_ops, sizeof(struct dvb_frontend_ops)); | 2528 | memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops)); |
2317 | 2529 | ||
2318 | state->timf_default = cfg->pll->timf; | 2530 | state->timf_default = cfg->pll->timf; |
2319 | 2531 | ||
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h index e0a9ded11df4..558b7e83c722 100644 --- a/drivers/media/dvb/frontends/dib8000.h +++ b/drivers/media/dvb/frontends/dib8000.h | |||
@@ -50,6 +50,9 @@ extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_st | |||
50 | extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe); | 50 | extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe); |
51 | extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe); | 51 | extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe); |
52 | extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode); | 52 | extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode); |
53 | extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave); | ||
54 | extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe); | ||
55 | extern struct dvb_frontend * dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index); | ||
53 | #else | 56 | #else |
54 | static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg) | 57 | static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg) |
55 | { | 58 | { |
@@ -111,6 +114,22 @@ static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) | |||
111 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 114 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
112 | return 0; | 115 | return 0; |
113 | } | 116 | } |
117 | static 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 | |||
123 | int 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 | |||
129 | static inline struct dvb_frontend * dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) { | ||
130 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
131 | return NULL; | ||
132 | } | ||
114 | #endif | 133 | #endif |
115 | 134 | ||
116 | #endif | 135 | #endif |