diff options
Diffstat (limited to 'drivers/media/dvb/frontends/dib8000.c')
-rw-r--r-- | drivers/media/dvb/frontends/dib8000.c | 821 |
1 files changed, 519 insertions, 302 deletions
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index df17b91b3250..c1c3e26906e2 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,18 @@ 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", |
265 | &state->fe[0], mode); | ||
262 | 266 | ||
263 | switch (mode) { | 267 | switch (mode) { |
264 | case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock | 268 | case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock |
@@ -292,7 +296,8 @@ static int dib8000_set_output_mode(struct dib8000_state *state, int mode) | |||
292 | break; | 296 | break; |
293 | 297 | ||
294 | default: | 298 | default: |
295 | dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe); | 299 | dprintk("Unhandled output_mode passed to be set for demod %p", |
300 | &state->fe[0]); | ||
296 | return -EINVAL; | 301 | return -EINVAL; |
297 | } | 302 | } |
298 | 303 | ||
@@ -342,7 +347,8 @@ static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_pow | |||
342 | { | 347 | { |
343 | /* by default everything is going to be powered off */ | 348 | /* by default everything is going to be powered off */ |
344 | u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff, | 349 | 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; | 350 | reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, |
351 | reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00; | ||
346 | 352 | ||
347 | /* now, depending on the requested mode, we power on */ | 353 | /* now, depending on the requested mode, we power on */ |
348 | switch (mode) { | 354 | switch (mode) { |
@@ -411,8 +417,9 @@ static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_s | |||
411 | return ret; | 417 | return ret; |
412 | } | 418 | } |
413 | 419 | ||
414 | static int dib8000_set_bandwidth(struct dib8000_state *state, u32 bw) | 420 | static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw) |
415 | { | 421 | { |
422 | struct dib8000_state *state = fe->demodulator_priv; | ||
416 | u32 timf; | 423 | u32 timf; |
417 | 424 | ||
418 | if (bw == 0) | 425 | if (bw == 0) |
@@ -478,7 +485,8 @@ static void dib8000_reset_pll(struct dib8000_state *state) | |||
478 | 485 | ||
479 | // clk_cfg1 | 486 | // clk_cfg1 |
480 | clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | | 487 | 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); | 488 | (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | |
489 | (pll->pll_range << 1) | (pll->pll_reset << 0); | ||
482 | 490 | ||
483 | dib8000_write_word(state, 902, clk_cfg1); | 491 | dib8000_write_word(state, 902, clk_cfg1); |
484 | clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); | 492 | clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); |
@@ -488,11 +496,12 @@ static void dib8000_reset_pll(struct dib8000_state *state) | |||
488 | 496 | ||
489 | /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ | 497 | /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ |
490 | if (state->cfg.pll->ADClkSrc == 0) | 498 | if (state->cfg.pll->ADClkSrc == 0) |
491 | dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); | 499 | dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | |
500 | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); | ||
492 | else if (state->cfg.refclksel != 0) | 501 | else if (state->cfg.refclksel != 0) |
493 | dib8000_write_word(state, 904, | 502 | dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | |
494 | (0 << 15) | (1 << 12) | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | (pll-> | 503 | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | |
495 | ADClkSrc << 7) | (0 << 1)); | 504 | (pll->ADClkSrc << 7) | (0 << 1)); |
496 | else | 505 | else |
497 | dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); | 506 | dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); |
498 | 507 | ||
@@ -560,7 +569,7 @@ static const u16 dib8000_defaults[] = { | |||
560 | 0xd4c0, | 569 | 0xd4c0, |
561 | 570 | ||
562 | /*1, 32, | 571 | /*1, 32, |
563 | 0x6680 // P_corm_thres Lock algorithms configuration */ | 572 | 0x6680 // P_corm_thres Lock algorithms configuration */ |
564 | 573 | ||
565 | 11, 80, /* set ADC level to -16 */ | 574 | 11, 80, /* set ADC level to -16 */ |
566 | (1 << 13) - 825 - 117, | 575 | (1 << 13) - 825 - 117, |
@@ -623,14 +632,14 @@ static const u16 dib8000_defaults[] = { | |||
623 | 1, 285, | 632 | 1, 285, |
624 | 0x0020, //p_fec_ | 633 | 0x0020, //p_fec_ |
625 | 1, 299, | 634 | 1, 299, |
626 | 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard | 635 | 0x0062, /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */ |
627 | 636 | ||
628 | 1, 338, | 637 | 1, 338, |
629 | (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1 | 638 | (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1 |
630 | (1 << 10) | // P_ctrl_pre_freq_mode_sat=1 | 639 | (1 << 10) | |
631 | (0 << 9) | // P_ctrl_pre_freq_inh=0 | 640 | (0 << 9) | /* P_ctrl_pre_freq_inh=0 */ |
632 | (3 << 5) | // P_ctrl_pre_freq_step=3 | 641 | (3 << 5) | /* P_ctrl_pre_freq_step=3 */ |
633 | (1 << 0), // P_pre_freq_win_len=1 | 642 | (1 << 0), /* P_pre_freq_win_len=1 */ |
634 | 643 | ||
635 | 1, 903, | 644 | 1, 903, |
636 | (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW) | 645 | (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW) |
@@ -717,7 +726,7 @@ static int dib8000_reset(struct dvb_frontend *fe) | |||
717 | if (dib8000_reset_gpio(state) != 0) | 726 | if (dib8000_reset_gpio(state) != 0) |
718 | dprintk("GPIO reset was not successful."); | 727 | dprintk("GPIO reset was not successful."); |
719 | 728 | ||
720 | if (dib8000_set_output_mode(state, OUTMODE_HIGH_Z) != 0) | 729 | if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0) |
721 | dprintk("OUTPUT_MODE could not be resetted."); | 730 | dprintk("OUTPUT_MODE could not be resetted."); |
722 | 731 | ||
723 | state->current_agc = NULL; | 732 | state->current_agc = NULL; |
@@ -752,7 +761,7 @@ static int dib8000_reset(struct dvb_frontend *fe) | |||
752 | /* unforce divstr regardless whether i2c enumeration was done or not */ | 761 | /* unforce divstr regardless whether i2c enumeration was done or not */ |
753 | dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1)); | 762 | dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1)); |
754 | 763 | ||
755 | dib8000_set_bandwidth(state, 6000); | 764 | dib8000_set_bandwidth(fe, 6000); |
756 | 765 | ||
757 | dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON); | 766 | dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON); |
758 | dib8000_sad_calib(state); | 767 | dib8000_sad_calib(state); |
@@ -778,7 +787,7 @@ static int dib8000_update_lna(struct dib8000_state *state) | |||
778 | // read dyn_gain here (because it is demod-dependent and not tuner) | 787 | // read dyn_gain here (because it is demod-dependent and not tuner) |
779 | dyn_gain = dib8000_read_word(state, 390); | 788 | dyn_gain = dib8000_read_word(state, 390); |
780 | 789 | ||
781 | if (state->cfg.update_lna(&state->fe, dyn_gain)) { // LNA has changed | 790 | if (state->cfg.update_lna(state->fe[0], dyn_gain)) { |
782 | dib8000_restart_agc(state); | 791 | dib8000_restart_agc(state); |
783 | return 1; | 792 | return 1; |
784 | } | 793 | } |
@@ -865,7 +874,8 @@ static int dib8000_agc_soft_split(struct dib8000_state *state) | |||
865 | split_offset = state->current_agc->split.max; | 874 | split_offset = state->current_agc->split.max; |
866 | else | 875 | else |
867 | split_offset = state->current_agc->split.max * | 876 | 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); | 877 | (agc - state->current_agc->split.min_thres) / |
878 | (state->current_agc->split.max_thres - state->current_agc->split.min_thres); | ||
869 | 879 | ||
870 | dprintk("AGC split_offset: %d", split_offset); | 880 | dprintk("AGC split_offset: %d", split_offset); |
871 | 881 | ||
@@ -900,7 +910,7 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) | |||
900 | case CT_AGC_STEP_0: | 910 | case CT_AGC_STEP_0: |
901 | //AGC initialization | 911 | //AGC initialization |
902 | if (state->cfg.agc_control) | 912 | if (state->cfg.agc_control) |
903 | state->cfg.agc_control(&state->fe, 1); | 913 | state->cfg.agc_control(fe, 1); |
904 | 914 | ||
905 | dib8000_restart_agc(state); | 915 | dib8000_restart_agc(state); |
906 | 916 | ||
@@ -924,7 +934,7 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) | |||
924 | dib8000_agc_soft_split(state); | 934 | dib8000_agc_soft_split(state); |
925 | 935 | ||
926 | if (state->cfg.agc_control) | 936 | if (state->cfg.agc_control) |
927 | state->cfg.agc_control(&state->fe, 0); | 937 | state->cfg.agc_control(fe, 0); |
928 | 938 | ||
929 | *tune_state = CT_AGC_STOP; | 939 | *tune_state = CT_AGC_STOP; |
930 | break; | 940 | break; |
@@ -936,29 +946,28 @@ static int dib8000_agc_startup(struct dvb_frontend *fe) | |||
936 | 946 | ||
937 | } | 947 | } |
938 | 948 | ||
939 | static const int32_t lut_1000ln_mant[] = | 949 | static const s32 lut_1000ln_mant[] = |
940 | { | 950 | { |
941 | 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 | 951 | 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 |
942 | }; | 952 | }; |
943 | 953 | ||
944 | int32_t dib8000_get_adc_power(struct dvb_frontend *fe, uint8_t mode) | 954 | s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode) |
945 | { | 955 | { |
946 | struct dib8000_state *state = fe->demodulator_priv; | 956 | struct dib8000_state *state = fe->demodulator_priv; |
947 | uint32_t ix = 0, tmp_val = 0, exp = 0, mant = 0; | 957 | u32 ix = 0, tmp_val = 0, exp = 0, mant = 0; |
948 | int32_t val; | 958 | s32 val; |
949 | 959 | ||
950 | val = dib8000_read32(state, 384); | 960 | val = dib8000_read32(state, 384); |
951 | /* mode = 1 : ln_agcpower calc using mant-exp conversion and mantis look up table */ | 961 | if (mode) { |
952 | if (mode) { | 962 | tmp_val = val; |
953 | tmp_val = val; | 963 | while (tmp_val >>= 1) |
954 | while (tmp_val >>= 1) | 964 | exp++; |
955 | exp++; | 965 | mant = (val * 1000 / (1<<exp)); |
956 | mant = (val * 1000 / (1<<exp)); | 966 | ix = (u8)((mant-1000)/100); /* index of the LUT */ |
957 | ix = (uint8_t)((mant-1000)/100); /* index of the LUT */ | 967 | val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908); |
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 */ | 968 | val = (val*256)/1000; |
959 | val = (val*256)/1000; | 969 | } |
960 | } | 970 | return val; |
961 | return val; | ||
962 | } | 971 | } |
963 | EXPORT_SYMBOL(dib8000_get_adc_power); | 972 | EXPORT_SYMBOL(dib8000_get_adc_power); |
964 | 973 | ||
@@ -1002,22 +1011,23 @@ 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); | 1011 | dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60); |
1003 | 1012 | ||
1004 | i = dib8000_read_word(state, 26) & 1; // P_dds_invspec | 1013 | i = dib8000_read_word(state, 26) & 1; // P_dds_invspec |
1005 | dib8000_write_word(state, 26, state->fe.dtv_property_cache.inversion ^ i); | 1014 | dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i); |
1006 | 1015 | ||
1007 | if (state->fe.dtv_property_cache.isdbt_sb_mode) { | 1016 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) { |
1008 | //compute new dds_freq for the seg and adjust prbs | 1017 | //compute new dds_freq for the seg and adjust prbs |
1009 | int seg_offset = | 1018 | int seg_offset = |
1010 | state->fe.dtv_property_cache.isdbt_sb_segment_idx - (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) - | 1019 | state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx - |
1011 | (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2); | 1020 | (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) - |
1021 | (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2); | ||
1012 | int clk = state->cfg.pll->internal; | 1022 | int clk = state->cfg.pll->internal; |
1013 | u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26) | 1023 | u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26) |
1014 | int dds_offset = seg_offset * segtodds; | 1024 | int dds_offset = seg_offset * segtodds; |
1015 | int new_dds, sub_channel; | 1025 | int new_dds, sub_channel; |
1016 | if ((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) // if even | 1026 | if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) |
1017 | dds_offset -= (int)(segtodds / 2); | 1027 | dds_offset -= (int)(segtodds / 2); |
1018 | 1028 | ||
1019 | if (state->cfg.pll->ifreq == 0) { | 1029 | if (state->cfg.pll->ifreq == 0) { |
1020 | if ((state->fe.dtv_property_cache.inversion ^ i) == 0) { | 1030 | if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) { |
1021 | dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1); | 1031 | dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1); |
1022 | new_dds = dds_offset; | 1032 | new_dds = dds_offset; |
1023 | } else | 1033 | } else |
@@ -1027,35 +1037,35 @@ 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 | 1037 | // - 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 | 1038 | // - 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 | 1039 | // - 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) | 1040 | if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT) |
1031 | && | 1041 | && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) |
1032 | (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) | 1042 | && (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) |
1033 | && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == | 1043 | && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == |
1034 | ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) | 1044 | ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) |
1035 | || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) | 1045 | || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) |
1036 | && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2))) | 1046 | && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2))) |
1037 | || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) | 1047 | || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0) |
1038 | && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == | 1048 | && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == |
1039 | ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) | 1049 | ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) |
1040 | )) { | 1050 | )) { |
1041 | new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26) | 1051 | new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26) |
1042 | } | 1052 | } |
1043 | } else { | 1053 | } else { |
1044 | if ((state->fe.dtv_property_cache.inversion ^ i) == 0) | 1054 | if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) |
1045 | new_dds = state->cfg.pll->ifreq - dds_offset; | 1055 | new_dds = state->cfg.pll->ifreq - dds_offset; |
1046 | else | 1056 | else |
1047 | new_dds = state->cfg.pll->ifreq + dds_offset; | 1057 | new_dds = state->cfg.pll->ifreq + dds_offset; |
1048 | } | 1058 | } |
1049 | dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff)); | 1059 | dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff)); |
1050 | dib8000_write_word(state, 28, (u16) (new_dds & 0xffff)); | 1060 | dib8000_write_word(state, 28, (u16) (new_dds & 0xffff)); |
1051 | if (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) // if odd | 1061 | if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) |
1052 | sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3; | 1062 | sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3; |
1053 | else // if even | 1063 | else |
1054 | sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3; | 1064 | sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3; |
1055 | sub_channel -= 6; | 1065 | sub_channel -= 6; |
1056 | 1066 | ||
1057 | if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K | 1067 | if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K |
1058 | || state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) { | 1068 | || 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 | 1069 | 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 | 1070 | dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1 |
1061 | } else { | 1071 | } else { |
@@ -1063,7 +1073,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 | 1073 | dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0 |
1064 | } | 1074 | } |
1065 | 1075 | ||
1066 | switch (state->fe.dtv_property_cache.transmission_mode) { | 1076 | switch (state->fe[0]->dtv_property_cache.transmission_mode) { |
1067 | case TRANSMISSION_MODE_2K: | 1077 | case TRANSMISSION_MODE_2K: |
1068 | switch (sub_channel) { | 1078 | switch (sub_channel) { |
1069 | case -6: | 1079 | case -6: |
@@ -1209,7 +1219,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1209 | } | 1219 | } |
1210 | break; | 1220 | break; |
1211 | } | 1221 | } |
1212 | } else { // if not state->fe.dtv_property_cache.isdbt_sb_mode | 1222 | } else { |
1213 | dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff)); | 1223 | dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff)); |
1214 | dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff)); | 1224 | dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff)); |
1215 | dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003)); | 1225 | dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003)); |
@@ -1218,7 +1228,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1218 | dib8000_write_word(state, 10, (seq << 4)); | 1228 | dib8000_write_word(state, 10, (seq << 4)); |
1219 | // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000); | 1229 | // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000); |
1220 | 1230 | ||
1221 | switch (state->fe.dtv_property_cache.guard_interval) { | 1231 | switch (state->fe[0]->dtv_property_cache.guard_interval) { |
1222 | case GUARD_INTERVAL_1_32: | 1232 | case GUARD_INTERVAL_1_32: |
1223 | guard = 0; | 1233 | guard = 0; |
1224 | break; | 1234 | break; |
@@ -1238,7 +1248,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1238 | 1248 | ||
1239 | max_constellation = DQPSK; | 1249 | max_constellation = DQPSK; |
1240 | for (i = 0; i < 3; i++) { | 1250 | for (i = 0; i < 3; i++) { |
1241 | switch (state->fe.dtv_property_cache.layer[i].modulation) { | 1251 | switch (state->fe[0]->dtv_property_cache.layer[i].modulation) { |
1242 | case DQPSK: | 1252 | case DQPSK: |
1243 | constellation = 0; | 1253 | constellation = 0; |
1244 | break; | 1254 | break; |
@@ -1254,7 +1264,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1254 | break; | 1264 | break; |
1255 | } | 1265 | } |
1256 | 1266 | ||
1257 | switch (state->fe.dtv_property_cache.layer[i].fec) { | 1267 | switch (state->fe[0]->dtv_property_cache.layer[i].fec) { |
1258 | case FEC_1_2: | 1268 | case FEC_1_2: |
1259 | crate = 1; | 1269 | crate = 1; |
1260 | break; | 1270 | break; |
@@ -1273,26 +1283,26 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1273 | break; | 1283 | break; |
1274 | } | 1284 | } |
1275 | 1285 | ||
1276 | if ((state->fe.dtv_property_cache.layer[i].interleaving > 0) && | 1286 | if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) && |
1277 | ((state->fe.dtv_property_cache.layer[i].interleaving <= 3) || | 1287 | ((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)) | 1288 | (state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)) |
1279 | ) | 1289 | ) |
1280 | timeI = state->fe.dtv_property_cache.layer[i].interleaving; | 1290 | timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving; |
1281 | else | 1291 | else |
1282 | timeI = 0; | 1292 | timeI = 0; |
1283 | dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe.dtv_property_cache.layer[i].segment_count & 0xf) << 6) | | 1293 | dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) | |
1284 | (crate << 3) | timeI); | 1294 | (crate << 3) | timeI); |
1285 | if (state->fe.dtv_property_cache.layer[i].segment_count > 0) { | 1295 | if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) { |
1286 | switch (max_constellation) { | 1296 | switch (max_constellation) { |
1287 | case DQPSK: | 1297 | case DQPSK: |
1288 | case QPSK: | 1298 | case QPSK: |
1289 | if (state->fe.dtv_property_cache.layer[i].modulation == QAM_16 || | 1299 | if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 || |
1290 | state->fe.dtv_property_cache.layer[i].modulation == QAM_64) | 1300 | state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64) |
1291 | max_constellation = state->fe.dtv_property_cache.layer[i].modulation; | 1301 | max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation; |
1292 | break; | 1302 | break; |
1293 | case QAM_16: | 1303 | case QAM_16: |
1294 | if (state->fe.dtv_property_cache.layer[i].modulation == QAM_64) | 1304 | if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64) |
1295 | max_constellation = state->fe.dtv_property_cache.layer[i].modulation; | 1305 | max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation; |
1296 | break; | 1306 | break; |
1297 | } | 1307 | } |
1298 | } | 1308 | } |
@@ -1303,34 +1313,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*/ | 1313 | //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/ |
1304 | 1314 | ||
1305 | dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) | | 1315 | 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. | 1316 | ((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache. |
1307 | isdbt_sb_mode & 1) << 4)); | 1317 | isdbt_sb_mode & 1) << 4)); |
1308 | 1318 | ||
1309 | dprintk("mode = %d ; guard = %d", mode, state->fe.dtv_property_cache.guard_interval); | 1319 | dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval); |
1310 | 1320 | ||
1311 | /* signal optimization parameter */ | 1321 | /* signal optimization parameter */ |
1312 | 1322 | ||
1313 | if (state->fe.dtv_property_cache.isdbt_partial_reception) { | 1323 | 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]; | 1324 | seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0]; |
1315 | for (i = 1; i < 3; i++) | 1325 | for (i = 1; i < 3; i++) |
1316 | nbseg_diff += | 1326 | nbseg_diff += |
1317 | (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count; | 1327 | (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++) | 1328 | for (i = 0; i < nbseg_diff; i++) |
1319 | seg_diff_mask |= 1 << permu_seg[i + 1]; | 1329 | seg_diff_mask |= 1 << permu_seg[i + 1]; |
1320 | } else { | 1330 | } else { |
1321 | for (i = 0; i < 3; i++) | 1331 | for (i = 0; i < 3; i++) |
1322 | nbseg_diff += | 1332 | nbseg_diff += |
1323 | (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count; | 1333 | (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++) | 1334 | for (i = 0; i < nbseg_diff; i++) |
1325 | seg_diff_mask |= 1 << permu_seg[i]; | 1335 | seg_diff_mask |= 1 << permu_seg[i]; |
1326 | } | 1336 | } |
1327 | dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask); | 1337 | dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask); |
1328 | 1338 | ||
1329 | state->differential_constellation = (seg_diff_mask != 0); | 1339 | state->differential_constellation = (seg_diff_mask != 0); |
1330 | dib8000_set_diversity_in(&state->fe, state->diversity_onoff); | 1340 | dib8000_set_diversity_in(state->fe[0], state->diversity_onoff); |
1331 | 1341 | ||
1332 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb | 1342 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { |
1333 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments | 1343 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) |
1334 | seg_mask13 = 0x00E0; | 1344 | seg_mask13 = 0x00E0; |
1335 | else // 1-segment | 1345 | else // 1-segment |
1336 | seg_mask13 = 0x0040; | 1346 | seg_mask13 = 0x0040; |
@@ -1340,7 +1350,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1340 | // WRITE: Mode & Diff mask | 1350 | // WRITE: Mode & Diff mask |
1341 | dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask); | 1351 | dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask); |
1342 | 1352 | ||
1343 | if ((seg_diff_mask) || (state->fe.dtv_property_cache.isdbt_sb_mode)) | 1353 | 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); | 1354 | dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200); |
1345 | else | 1355 | else |
1346 | dib8000_write_word(state, 268, (2 << 9) | 39); //init value | 1356 | dib8000_write_word(state, 268, (2 << 9) | 39); //init value |
@@ -1351,26 +1361,25 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1351 | 1361 | ||
1352 | dib8000_write_word(state, 353, seg_mask13); // ADDR 353 | 1362 | dib8000_write_word(state, 353, seg_mask13); // ADDR 353 |
1353 | 1363 | ||
1354 | /* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */ | 1364 | /* // 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 ); | ||
1356 | 1365 | ||
1357 | // ---- SMALL ---- | 1366 | // ---- SMALL ---- |
1358 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { | 1367 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { |
1359 | switch (state->fe.dtv_property_cache.transmission_mode) { | 1368 | switch (state->fe[0]->dtv_property_cache.transmission_mode) { |
1360 | case TRANSMISSION_MODE_2K: | 1369 | case TRANSMISSION_MODE_2K: |
1361 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg | 1370 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { |
1362 | if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK | 1371 | if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) |
1363 | ncoeff = coeff_2k_sb_1seg_dqpsk; | 1372 | ncoeff = coeff_2k_sb_1seg_dqpsk; |
1364 | else // QPSK or QAM | 1373 | else // QPSK or QAM |
1365 | ncoeff = coeff_2k_sb_1seg; | 1374 | ncoeff = coeff_2k_sb_1seg; |
1366 | } else { // 3-segments | 1375 | } else { // 3-segments |
1367 | if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment | 1376 | if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { |
1368 | if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments | 1377 | if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) |
1369 | ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk; | 1378 | ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk; |
1370 | else // QPSK or QAM on external segments | 1379 | else // QPSK or QAM on external segments |
1371 | ncoeff = coeff_2k_sb_3seg_0dqpsk; | 1380 | ncoeff = coeff_2k_sb_3seg_0dqpsk; |
1372 | } else { // QPSK or QAM on central segment | 1381 | } else { // QPSK or QAM on central segment |
1373 | if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments | 1382 | if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) |
1374 | ncoeff = coeff_2k_sb_3seg_1dqpsk; | 1383 | ncoeff = coeff_2k_sb_3seg_1dqpsk; |
1375 | else // QPSK or QAM on external segments | 1384 | else // QPSK or QAM on external segments |
1376 | ncoeff = coeff_2k_sb_3seg; | 1385 | ncoeff = coeff_2k_sb_3seg; |
@@ -1379,20 +1388,20 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1379 | break; | 1388 | break; |
1380 | 1389 | ||
1381 | case TRANSMISSION_MODE_4K: | 1390 | case TRANSMISSION_MODE_4K: |
1382 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg | 1391 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { |
1383 | if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK | 1392 | if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) |
1384 | ncoeff = coeff_4k_sb_1seg_dqpsk; | 1393 | ncoeff = coeff_4k_sb_1seg_dqpsk; |
1385 | else // QPSK or QAM | 1394 | else // QPSK or QAM |
1386 | ncoeff = coeff_4k_sb_1seg; | 1395 | ncoeff = coeff_4k_sb_1seg; |
1387 | } else { // 3-segments | 1396 | } else { // 3-segments |
1388 | if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment | 1397 | if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { |
1389 | 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) { |
1390 | ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk; | 1399 | ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk; |
1391 | } else { // QPSK or QAM on external segments | 1400 | } else { // QPSK or QAM on external segments |
1392 | ncoeff = coeff_4k_sb_3seg_0dqpsk; | 1401 | ncoeff = coeff_4k_sb_3seg_0dqpsk; |
1393 | } | 1402 | } |
1394 | } else { // QPSK or QAM on central segment | 1403 | } else { // QPSK or QAM on central segment |
1395 | if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments | 1404 | if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { |
1396 | ncoeff = coeff_4k_sb_3seg_1dqpsk; | 1405 | ncoeff = coeff_4k_sb_3seg_1dqpsk; |
1397 | } else // QPSK or QAM on external segments | 1406 | } else // QPSK or QAM on external segments |
1398 | ncoeff = coeff_4k_sb_3seg; | 1407 | ncoeff = coeff_4k_sb_3seg; |
@@ -1403,20 +1412,20 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1403 | case TRANSMISSION_MODE_AUTO: | 1412 | case TRANSMISSION_MODE_AUTO: |
1404 | case TRANSMISSION_MODE_8K: | 1413 | case TRANSMISSION_MODE_8K: |
1405 | default: | 1414 | default: |
1406 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg | 1415 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { |
1407 | if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK | 1416 | if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) |
1408 | ncoeff = coeff_8k_sb_1seg_dqpsk; | 1417 | ncoeff = coeff_8k_sb_1seg_dqpsk; |
1409 | else // QPSK or QAM | 1418 | else // QPSK or QAM |
1410 | ncoeff = coeff_8k_sb_1seg; | 1419 | ncoeff = coeff_8k_sb_1seg; |
1411 | } else { // 3-segments | 1420 | } else { // 3-segments |
1412 | if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment | 1421 | if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) { |
1413 | 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) { |
1414 | ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk; | 1423 | ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk; |
1415 | } else { // QPSK or QAM on external segments | 1424 | } else { // QPSK or QAM on external segments |
1416 | ncoeff = coeff_8k_sb_3seg_0dqpsk; | 1425 | ncoeff = coeff_8k_sb_3seg_0dqpsk; |
1417 | } | 1426 | } |
1418 | } else { // QPSK or QAM on central segment | 1427 | } else { // QPSK or QAM on central segment |
1419 | if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments | 1428 | if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) { |
1420 | ncoeff = coeff_8k_sb_3seg_1dqpsk; | 1429 | ncoeff = coeff_8k_sb_3seg_1dqpsk; |
1421 | } else // QPSK or QAM on external segments | 1430 | } else // QPSK or QAM on external segments |
1422 | ncoeff = coeff_8k_sb_3seg; | 1431 | ncoeff = coeff_8k_sb_3seg; |
@@ -1430,22 +1439,22 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1430 | 1439 | ||
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 | 1440 | // 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, | 1441 | 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); | 1442 | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5); |
1434 | 1443 | ||
1435 | // ---- COFF ---- | 1444 | // ---- COFF ---- |
1436 | // Carloff, the most robust | 1445 | // Carloff, the most robust |
1437 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // Sound Broadcasting mode - use both TMCC and AC pilots | 1446 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { |
1438 | 1447 | ||
1439 | // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64 | 1448 | // 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 | 1449 | // 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, | 1450 | dib8000_write_word(state, 187, |
1442 | (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 2) | 1451 | (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2) |
1443 | | 0x3); | 1452 | | 0x3); |
1444 | 1453 | ||
1445 | /* // P_small_coef_ext_enable = 1 */ | 1454 | /* // P_small_coef_ext_enable = 1 */ |
1446 | /* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */ | 1455 | /* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */ |
1447 | 1456 | ||
1448 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg | 1457 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { |
1449 | 1458 | ||
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) | 1459 | // 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) | 1460 | if (mode == 3) |
@@ -1469,10 +1478,10 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1469 | dib8000_write_word(state, 186, 80); | 1478 | dib8000_write_word(state, 186, 80); |
1470 | } else { // Sound Broadcasting mode 3 seg | 1479 | } 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 | 1480 | // 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) */ | 1481 | /* if (mode == 3) */ |
1473 | /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */ | 1482 | /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */ |
1474 | /* else */ | 1483 | /* else */ |
1475 | /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */ | 1484 | /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */ |
1476 | dib8000_write_word(state, 180, 0x1fcf | (1 << 14)); | 1485 | dib8000_write_word(state, 180, 0x1fcf | (1 << 14)); |
1477 | 1486 | ||
1478 | // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1, | 1487 | // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1, |
@@ -1509,7 +1518,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)); | 1518 | dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); |
1510 | } | 1519 | } |
1511 | // ---- FFT ---- | 1520 | // ---- FFT ---- |
1512 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 && state->fe.dtv_property_cache.isdbt_partial_reception == 0) // 1-seg | 1521 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) |
1513 | dib8000_write_word(state, 178, 64); // P_fft_powrange=64 | 1522 | dib8000_write_word(state, 178, 64); // P_fft_powrange=64 |
1514 | else | 1523 | else |
1515 | dib8000_write_word(state, 178, 32); // P_fft_powrange=32 | 1524 | dib8000_write_word(state, 178, 32); // P_fft_powrange=32 |
@@ -1518,12 +1527,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) | 1527 | * 6bits; p_coff_thres_lock 6bits (for coff lock if needed) |
1519 | */ | 1528 | */ |
1520 | /* if ( ( nbseg_diff>0)&&(nbseg_diff<13)) | 1529 | /* if ( ( nbseg_diff>0)&&(nbseg_diff<13)) |
1521 | dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */ | 1530 | dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */ |
1522 | 1531 | ||
1523 | dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */ | 1532 | 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 */ | 1533 | 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 */ | 1534 | 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)) | 1535 | 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 */ | 1536 | dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */ |
1528 | else | 1537 | else |
1529 | dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */ | 1538 | dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */ |
@@ -1538,8 +1547,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 */ | 1547 | dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */ |
1539 | 1548 | ||
1540 | /* offset loop parameters */ | 1549 | /* offset loop parameters */ |
1541 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { | 1550 | 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 | 1551 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) |
1543 | /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */ | 1552 | /* 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); | 1553 | dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40); |
1545 | 1554 | ||
@@ -1551,8 +1560,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 */ | 1560 | /* 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); | 1561 | dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80); |
1553 | 1562 | ||
1554 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { | 1563 | 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 | 1564 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) |
1556 | /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */ | 1565 | /* 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)); | 1566 | dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode)); |
1558 | 1567 | ||
@@ -1564,7 +1573,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)); | 1573 | dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode)); |
1565 | 1574 | ||
1566 | /* P_dvsy_sync_wait - reuse mode */ | 1575 | /* P_dvsy_sync_wait - reuse mode */ |
1567 | switch (state->fe.dtv_property_cache.transmission_mode) { | 1576 | switch (state->fe[0]->dtv_property_cache.transmission_mode) { |
1568 | case TRANSMISSION_MODE_8K: | 1577 | case TRANSMISSION_MODE_8K: |
1569 | mode = 256; | 1578 | mode = 256; |
1570 | break; | 1579 | break; |
@@ -1624,15 +1633,15 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1624 | } | 1633 | } |
1625 | 1634 | ||
1626 | // ---- ANA_FE ---- | 1635 | // ---- ANA_FE ---- |
1627 | if (state->fe.dtv_property_cache.isdbt_sb_mode) { | 1636 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) { |
1628 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments | 1637 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1) |
1629 | ana_fe = ana_fe_coeff_3seg; | 1638 | ana_fe = ana_fe_coeff_3seg; |
1630 | else // 1-segment | 1639 | else // 1-segment |
1631 | ana_fe = ana_fe_coeff_1seg; | 1640 | ana_fe = ana_fe_coeff_1seg; |
1632 | } else | 1641 | } else |
1633 | ana_fe = ana_fe_coeff_13seg; | 1642 | ana_fe = ana_fe_coeff_13seg; |
1634 | 1643 | ||
1635 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0) | 1644 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0) |
1636 | for (mode = 0; mode < 24; mode++) | 1645 | for (mode = 0; mode < 24; mode++) |
1637 | dib8000_write_word(state, 117 + mode, ana_fe[mode]); | 1646 | dib8000_write_word(state, 117 + mode, ana_fe[mode]); |
1638 | 1647 | ||
@@ -1648,11 +1657,11 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1648 | // "P_cspu_left_edge" not used => do not care | 1657 | // "P_cspu_left_edge" not used => do not care |
1649 | // "P_cspu_right_edge" not used => do not care | 1658 | // "P_cspu_right_edge" not used => do not care |
1650 | 1659 | ||
1651 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb | 1660 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { |
1652 | dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1 | 1661 | 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 | 1662 | 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 | 1663 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0 |
1655 | && state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) { | 1664 | && 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 | 1665 | //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 | 1666 | dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15 |
1658 | } | 1667 | } |
@@ -1664,7 +1673,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1664 | // ---- TMCC ---- | 1673 | // ---- TMCC ---- |
1665 | for (i = 0; i < 3; i++) | 1674 | for (i = 0; i < 3; i++) |
1666 | tmcc_pow += | 1675 | tmcc_pow += |
1667 | (((state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe.dtv_property_cache.layer[i].segment_count); | 1676 | (((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); | 1677 | // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9); |
1669 | // Threshold is set at 1/4 of max power. | 1678 | // Threshold is set at 1/4 of max power. |
1670 | tmcc_pow *= (1 << (9 - 2)); | 1679 | tmcc_pow *= (1 << (9 - 2)); |
@@ -1678,7 +1687,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear | |||
1678 | if (state->isdbt_cfg_loaded == 0) | 1687 | if (state->isdbt_cfg_loaded == 0) |
1679 | dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */ | 1688 | dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */ |
1680 | 1689 | ||
1681 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) | 1690 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) |
1682 | state->isdbt_cfg_loaded = 0; | 1691 | state->isdbt_cfg_loaded = 0; |
1683 | else | 1692 | else |
1684 | state->isdbt_cfg_loaded = 1; | 1693 | state->isdbt_cfg_loaded = 1; |
@@ -1693,38 +1702,38 @@ static int dib8000_autosearch_start(struct dvb_frontend *fe) | |||
1693 | 1702 | ||
1694 | int slist = 0; | 1703 | int slist = 0; |
1695 | 1704 | ||
1696 | state->fe.dtv_property_cache.inversion = 0; | 1705 | state->fe[0]->dtv_property_cache.inversion = 0; |
1697 | if (!state->fe.dtv_property_cache.isdbt_sb_mode) | 1706 | if (!state->fe[0]->dtv_property_cache.isdbt_sb_mode) |
1698 | state->fe.dtv_property_cache.layer[0].segment_count = 13; | 1707 | state->fe[0]->dtv_property_cache.layer[0].segment_count = 13; |
1699 | state->fe.dtv_property_cache.layer[0].modulation = QAM_64; | 1708 | state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64; |
1700 | state->fe.dtv_property_cache.layer[0].fec = FEC_2_3; | 1709 | state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3; |
1701 | state->fe.dtv_property_cache.layer[0].interleaving = 0; | 1710 | state->fe[0]->dtv_property_cache.layer[0].interleaving = 0; |
1702 | 1711 | ||
1703 | //choose the right list, in sb, always do everything | 1712 | //choose the right list, in sb, always do everything |
1704 | if (state->fe.dtv_property_cache.isdbt_sb_mode) { | 1713 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) { |
1705 | state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K; | 1714 | state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K; |
1706 | state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8; | 1715 | state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8; |
1707 | slist = 7; | 1716 | slist = 7; |
1708 | dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); | 1717 | dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); |
1709 | } else { | 1718 | } else { |
1710 | if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) { | 1719 | if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) { |
1711 | if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) { | 1720 | if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) { |
1712 | slist = 7; | 1721 | 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 | 1722 | 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 | 1723 | } else |
1715 | slist = 3; | 1724 | slist = 3; |
1716 | } else { | 1725 | } else { |
1717 | if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) { | 1726 | if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) { |
1718 | slist = 2; | 1727 | slist = 2; |
1719 | dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 | 1728 | dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 |
1720 | } else | 1729 | } else |
1721 | slist = 0; | 1730 | slist = 0; |
1722 | } | 1731 | } |
1723 | 1732 | ||
1724 | if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) | 1733 | if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) |
1725 | state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K; | 1734 | state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K; |
1726 | if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) | 1735 | if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) |
1727 | state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8; | 1736 | state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8; |
1728 | 1737 | ||
1729 | dprintk("using list for autosearch : %d", slist); | 1738 | dprintk("using list for autosearch : %d", slist); |
1730 | dib8000_set_channel(state, (unsigned char)slist, 1); | 1739 | dib8000_set_channel(state, (unsigned char)slist, 1); |
@@ -1786,7 +1795,7 @@ static int dib8000_tune(struct dvb_frontend *fe) | |||
1786 | if (state == NULL) | 1795 | if (state == NULL) |
1787 | return -EINVAL; | 1796 | return -EINVAL; |
1788 | 1797 | ||
1789 | dib8000_set_bandwidth(state, state->fe.dtv_property_cache.bandwidth_hz / 1000); | 1798 | dib8000_set_bandwidth(fe, state->fe[0]->dtv_property_cache.bandwidth_hz / 1000); |
1790 | dib8000_set_channel(state, 0, 0); | 1799 | dib8000_set_channel(state, 0, 0); |
1791 | 1800 | ||
1792 | // restart demod | 1801 | // restart demod |
@@ -1799,17 +1808,16 @@ static int dib8000_tune(struct dvb_frontend *fe) | |||
1799 | 1808 | ||
1800 | // never achieved a lock before - wait for timfreq to update | 1809 | // never achieved a lock before - wait for timfreq to update |
1801 | if (state->timf == 0) { | 1810 | if (state->timf == 0) { |
1802 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { | 1811 | 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 | 1812 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) |
1804 | msleep(300); | 1813 | msleep(300); |
1805 | else // Sound Broadcasting mode 3 seg | 1814 | else // Sound Broadcasting mode 3 seg |
1806 | msleep(500); | 1815 | msleep(500); |
1807 | } else // 13 seg | 1816 | } else // 13 seg |
1808 | msleep(200); | 1817 | msleep(200); |
1809 | } | 1818 | } |
1810 | //dump_reg(state); | 1819 | if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) { |
1811 | if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { | 1820 | if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) { |
1812 | if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg | ||
1813 | 1821 | ||
1814 | /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */ | 1822 | /* 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); | 1823 | dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40); |
@@ -1854,26 +1862,38 @@ static int dib8000_tune(struct dvb_frontend *fe) | |||
1854 | static int dib8000_wakeup(struct dvb_frontend *fe) | 1862 | static int dib8000_wakeup(struct dvb_frontend *fe) |
1855 | { | 1863 | { |
1856 | struct dib8000_state *state = fe->demodulator_priv; | 1864 | struct dib8000_state *state = fe->demodulator_priv; |
1865 | u8 index_frontend; | ||
1866 | int ret; | ||
1857 | 1867 | ||
1858 | dib8000_set_power_mode(state, DIB8000M_POWER_ALL); | 1868 | dib8000_set_power_mode(state, DIB8000M_POWER_ALL); |
1859 | dib8000_set_adc_state(state, DIBX000_ADC_ON); | 1869 | dib8000_set_adc_state(state, DIBX000_ADC_ON); |
1860 | if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) | 1870 | if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) |
1861 | dprintk("could not start Slow ADC"); | 1871 | dprintk("could not start Slow ADC"); |
1862 | 1872 | ||
1873 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
1874 | ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]); | ||
1875 | if (ret < 0) | ||
1876 | return ret; | ||
1877 | } | ||
1878 | |||
1863 | return 0; | 1879 | return 0; |
1864 | } | 1880 | } |
1865 | 1881 | ||
1866 | static int dib8000_sleep(struct dvb_frontend *fe) | 1882 | static int dib8000_sleep(struct dvb_frontend *fe) |
1867 | { | 1883 | { |
1868 | struct dib8000_state *st = fe->demodulator_priv; | 1884 | struct dib8000_state *state = fe->demodulator_priv; |
1869 | if (1) { | 1885 | u8 index_frontend; |
1870 | dib8000_set_output_mode(st, OUTMODE_HIGH_Z); | 1886 | 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 | 1887 | ||
1875 | return 0; | 1888 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { |
1889 | ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]); | ||
1890 | if (ret < 0) | ||
1891 | return ret; | ||
1876 | } | 1892 | } |
1893 | |||
1894 | dib8000_set_output_mode(fe, OUTMODE_HIGH_Z); | ||
1895 | dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY); | ||
1896 | return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF); | ||
1877 | } | 1897 | } |
1878 | 1898 | ||
1879 | enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe) | 1899 | enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe) |
@@ -1891,16 +1911,40 @@ int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tun | |||
1891 | } | 1911 | } |
1892 | EXPORT_SYMBOL(dib8000_set_tune_state); | 1912 | EXPORT_SYMBOL(dib8000_set_tune_state); |
1893 | 1913 | ||
1894 | |||
1895 | |||
1896 | |||
1897 | static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) | 1914 | static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) |
1898 | { | 1915 | { |
1899 | struct dib8000_state *state = fe->demodulator_priv; | 1916 | struct dib8000_state *state = fe->demodulator_priv; |
1900 | u16 i, val = 0; | 1917 | u16 i, val = 0; |
1918 | fe_status_t stat; | ||
1919 | u8 index_frontend, sub_index_frontend; | ||
1901 | 1920 | ||
1902 | fe->dtv_property_cache.bandwidth_hz = 6000000; | 1921 | fe->dtv_property_cache.bandwidth_hz = 6000000; |
1903 | 1922 | ||
1923 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
1924 | state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat); | ||
1925 | if (stat&FE_HAS_SYNC) { | ||
1926 | dprintk("TMCC lock on the slave%i", index_frontend); | ||
1927 | /* synchronize the cache with the other frontends */ | ||
1928 | state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep); | ||
1929 | for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) { | ||
1930 | if (sub_index_frontend != index_frontend) { | ||
1931 | state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode; | ||
1932 | state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion; | ||
1933 | state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode; | ||
1934 | state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval; | ||
1935 | state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception; | ||
1936 | for (i = 0; i < 3; i++) { | ||
1937 | state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count; | ||
1938 | state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving; | ||
1939 | state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec; | ||
1940 | state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation; | ||
1941 | } | ||
1942 | } | ||
1943 | } | ||
1944 | return 0; | ||
1945 | } | ||
1946 | } | ||
1947 | |||
1904 | fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1; | 1948 | fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1; |
1905 | 1949 | ||
1906 | val = dib8000_read_word(state, 570); | 1950 | val = dib8000_read_word(state, 570); |
@@ -1992,112 +2036,200 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par | |||
1992 | break; | 2036 | break; |
1993 | } | 2037 | } |
1994 | } | 2038 | } |
2039 | |||
2040 | /* synchronize the cache with the other frontends */ | ||
2041 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
2042 | state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode; | ||
2043 | state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion; | ||
2044 | state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode; | ||
2045 | state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval; | ||
2046 | state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception; | ||
2047 | for (i = 0; i < 3; i++) { | ||
2048 | state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count; | ||
2049 | state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving; | ||
2050 | state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec; | ||
2051 | state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation; | ||
2052 | } | ||
2053 | } | ||
1995 | return 0; | 2054 | return 0; |
1996 | } | 2055 | } |
1997 | 2056 | ||
1998 | static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) | 2057 | static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) |
1999 | { | 2058 | { |
2000 | struct dib8000_state *state = fe->demodulator_priv; | 2059 | struct dib8000_state *state = fe->demodulator_priv; |
2060 | u8 nbr_pending, exit_condition, index_frontend; | ||
2061 | s8 index_frontend_success = -1; | ||
2001 | int time, ret; | 2062 | int time, ret; |
2063 | int time_slave = FE_CALLBACK_TIME_NEVER; | ||
2002 | 2064 | ||
2003 | fe->dtv_property_cache.delivery_system = SYS_ISDBT; | 2065 | if (state->fe[0]->dtv_property_cache.frequency == 0) { |
2066 | dprintk("dib8000: must at least specify frequency "); | ||
2067 | return 0; | ||
2068 | } | ||
2004 | 2069 | ||
2005 | dib8000_set_output_mode(state, OUTMODE_HIGH_Z); | 2070 | if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) { |
2071 | dprintk("dib8000: no bandwidth specified, set to default "); | ||
2072 | state->fe[0]->dtv_property_cache.bandwidth_hz = 6000000; | ||
2073 | } | ||
2074 | |||
2075 | for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
2076 | /* synchronization of the cache */ | ||
2077 | state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT; | ||
2078 | memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties)); | ||
2079 | |||
2080 | dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z); | ||
2081 | if (state->fe[index_frontend]->ops.tuner_ops.set_params) | ||
2082 | state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend], fep); | ||
2006 | 2083 | ||
2007 | if (fe->ops.tuner_ops.set_params) | 2084 | dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START); |
2008 | fe->ops.tuner_ops.set_params(fe, fep); | 2085 | } |
2009 | 2086 | ||
2010 | /* start up the AGC */ | 2087 | /* start up the AGC */ |
2011 | state->tune_state = CT_AGC_START; | ||
2012 | do { | 2088 | do { |
2013 | time = dib8000_agc_startup(fe); | 2089 | time = dib8000_agc_startup(state->fe[0]); |
2090 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
2091 | time_slave = dib8000_agc_startup(state->fe[index_frontend]); | ||
2092 | if (time == FE_CALLBACK_TIME_NEVER) | ||
2093 | time = time_slave; | ||
2094 | else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time)) | ||
2095 | time = time_slave; | ||
2096 | } | ||
2014 | if (time != FE_CALLBACK_TIME_NEVER) | 2097 | if (time != FE_CALLBACK_TIME_NEVER) |
2015 | msleep(time / 10); | 2098 | msleep(time / 10); |
2016 | else | 2099 | else |
2017 | break; | 2100 | break; |
2018 | } while (state->tune_state != CT_AGC_STOP); | 2101 | exit_condition = 1; |
2019 | 2102 | 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) { | 2103 | if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) { |
2021 | dprintk("dib8000: must at least specify frequency "); | 2104 | exit_condition = 0; |
2022 | return 0; | 2105 | break; |
2023 | } | 2106 | } |
2024 | 2107 | } | |
2025 | if (state->fe.dtv_property_cache.bandwidth_hz == 0) { | 2108 | } while (exit_condition == 0); |
2026 | dprintk("dib8000: no bandwidth specified, set to default "); | 2109 | |
2027 | state->fe.dtv_property_cache.bandwidth_hz = 6000000; | 2110 | for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) |
2028 | } | 2111 | dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START); |
2112 | |||
2113 | if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) || | ||
2114 | (state->fe[0]->dtv_property_cache.inversion == INVERSION_AUTO) || | ||
2115 | (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) || | ||
2116 | (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) || | ||
2117 | (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) && | ||
2118 | (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0xff) && | ||
2119 | (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0) && | ||
2120 | ((state->fe[0]->dtv_property_cache.layer[0].modulation == QAM_AUTO) || | ||
2121 | (state->fe[0]->dtv_property_cache.layer[0].fec == FEC_AUTO))) || | ||
2122 | (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) && | ||
2123 | (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0xff) && | ||
2124 | (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0) && | ||
2125 | ((state->fe[0]->dtv_property_cache.layer[1].modulation == QAM_AUTO) || | ||
2126 | (state->fe[0]->dtv_property_cache.layer[1].fec == FEC_AUTO))) || | ||
2127 | (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) && | ||
2128 | (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0xff) && | ||
2129 | (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0) && | ||
2130 | ((state->fe[0]->dtv_property_cache.layer[2].modulation == QAM_AUTO) || | ||
2131 | (state->fe[0]->dtv_property_cache.layer[2].fec == FEC_AUTO))) || | ||
2132 | (((state->fe[0]->dtv_property_cache.layer[0].segment_count == 0) || | ||
2133 | ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) && | ||
2134 | ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) || | ||
2135 | ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) && | ||
2136 | ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) { | ||
2137 | int i = 80000; | ||
2138 | u8 found = 0; | ||
2139 | u8 tune_failed = 0; | ||
2140 | |||
2141 | for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
2142 | dib8000_set_bandwidth(state->fe[index_frontend], fe->dtv_property_cache.bandwidth_hz / 1000); | ||
2143 | dib8000_autosearch_start(state->fe[index_frontend]); | ||
2144 | } | ||
2029 | 2145 | ||
2030 | state->tune_state = CT_DEMOD_START; | ||
2031 | |||
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 { | 2146 | do { |
2061 | msleep(10); | 2147 | msleep(20); |
2062 | found = dib8000_autosearch_irq(fe); | 2148 | nbr_pending = 0; |
2063 | } while (found == 0 && i--); | 2149 | exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */ |
2150 | for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
2151 | if (((tune_failed >> index_frontend) & 0x1) == 0) { | ||
2152 | found = dib8000_autosearch_irq(state->fe[index_frontend]); | ||
2153 | switch (found) { | ||
2154 | case 0: /* tune pending */ | ||
2155 | nbr_pending++; | ||
2156 | break; | ||
2157 | case 2: | ||
2158 | dprintk("autosearch succeed on the frontend%i", index_frontend); | ||
2159 | exit_condition = 2; | ||
2160 | index_frontend_success = index_frontend; | ||
2161 | break; | ||
2162 | default: | ||
2163 | dprintk("unhandled autosearch result"); | ||
2164 | case 1: | ||
2165 | dprintk("autosearch failed for the frontend%i", index_frontend); | ||
2166 | break; | ||
2167 | } | ||
2168 | } | ||
2169 | } | ||
2064 | 2170 | ||
2065 | dprintk("Frequency %d Hz, autosearch returns: %d", fep->frequency, found); | 2171 | /* if all tune are done and no success, exit: tune failed */ |
2172 | if ((nbr_pending == 0) && (exit_condition == 0)) | ||
2173 | exit_condition = 1; | ||
2174 | } while ((exit_condition == 0) && i--); | ||
2066 | 2175 | ||
2067 | if (found == 0 || found == 1) | 2176 | if (exit_condition == 1) { /* tune failed */ |
2068 | return 0; // no channel found | 2177 | dprintk("tune failed"); |
2178 | return 0; | ||
2179 | } | ||
2180 | |||
2181 | dprintk("tune success on frontend%i", index_frontend_success); | ||
2069 | 2182 | ||
2070 | dib8000_get_frontend(fe, fep); | 2183 | dib8000_get_frontend(fe, fep); |
2071 | } | 2184 | } |
2072 | 2185 | ||
2073 | ret = dib8000_tune(fe); | 2186 | for (index_frontend = 0, ret = 0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) |
2187 | ret = dib8000_tune(state->fe[index_frontend]); | ||
2188 | |||
2189 | /* set output mode and diversity input */ | ||
2190 | dib8000_set_output_mode(state->fe[0], state->cfg.output_mode); | ||
2191 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
2192 | dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY); | ||
2193 | dib8000_set_diversity_in(state->fe[index_frontend-1], 1); | ||
2194 | } | ||
2074 | 2195 | ||
2075 | /* make this a config parameter */ | 2196 | /* turn off the diversity of the last chip */ |
2076 | dib8000_set_output_mode(state, state->cfg.output_mode); | 2197 | dib8000_set_diversity_in(state->fe[index_frontend-1], 0); |
2077 | 2198 | ||
2078 | return ret; | 2199 | return ret; |
2079 | } | 2200 | } |
2080 | 2201 | ||
2202 | static u16 dib8000_read_lock(struct dvb_frontend *fe) | ||
2203 | { | ||
2204 | struct dib8000_state *state = fe->demodulator_priv; | ||
2205 | |||
2206 | return dib8000_read_word(state, 568); | ||
2207 | } | ||
2208 | |||
2081 | static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) | 2209 | static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) |
2082 | { | 2210 | { |
2083 | struct dib8000_state *state = fe->demodulator_priv; | 2211 | struct dib8000_state *state = fe->demodulator_priv; |
2084 | u16 lock = dib8000_read_word(state, 568); | 2212 | u16 lock_slave = 0, lock = dib8000_read_word(state, 568); |
2213 | u8 index_frontend; | ||
2214 | |||
2215 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) | ||
2216 | lock_slave |= dib8000_read_lock(state->fe[index_frontend]); | ||
2085 | 2217 | ||
2086 | *stat = 0; | 2218 | *stat = 0; |
2087 | 2219 | ||
2088 | if ((lock >> 13) & 1) | 2220 | if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1)) |
2089 | *stat |= FE_HAS_SIGNAL; | 2221 | *stat |= FE_HAS_SIGNAL; |
2090 | 2222 | ||
2091 | if ((lock >> 8) & 1) /* Equal */ | 2223 | if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */ |
2092 | *stat |= FE_HAS_CARRIER; | 2224 | *stat |= FE_HAS_CARRIER; |
2093 | 2225 | ||
2094 | if (((lock >> 1) & 0xf) == 0xf) /* TMCC_SYNC */ | 2226 | if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */ |
2095 | *stat |= FE_HAS_SYNC; | 2227 | *stat |= FE_HAS_SYNC; |
2096 | 2228 | ||
2097 | if (((lock >> 12) & 1) && ((lock >> 5) & 7)) /* FEC MPEG */ | 2229 | if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */ |
2098 | *stat |= FE_HAS_LOCK; | 2230 | *stat |= FE_HAS_LOCK; |
2099 | 2231 | ||
2100 | if ((lock >> 12) & 1) { | 2232 | if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) { |
2101 | lock = dib8000_read_word(state, 554); /* Viterbi Layer A */ | 2233 | lock = dib8000_read_word(state, 554); /* Viterbi Layer A */ |
2102 | if (lock & 0x01) | 2234 | if (lock & 0x01) |
2103 | *stat |= FE_HAS_VITERBI; | 2235 | *stat |= FE_HAS_VITERBI; |
@@ -2131,44 +2263,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) | 2263 | static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) |
2132 | { | 2264 | { |
2133 | struct dib8000_state *state = fe->demodulator_priv; | 2265 | struct dib8000_state *state = fe->demodulator_priv; |
2134 | u16 val = dib8000_read_word(state, 390); | 2266 | u8 index_frontend; |
2135 | *strength = 65535 - val; | 2267 | u16 val; |
2268 | |||
2269 | *strength = 0; | ||
2270 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) { | ||
2271 | state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val); | ||
2272 | if (val > 65535 - *strength) | ||
2273 | *strength = 65535; | ||
2274 | else | ||
2275 | *strength += val; | ||
2276 | } | ||
2277 | |||
2278 | val = 65535 - dib8000_read_word(state, 390); | ||
2279 | if (val > 65535 - *strength) | ||
2280 | *strength = 65535; | ||
2281 | else | ||
2282 | *strength += val; | ||
2136 | return 0; | 2283 | return 0; |
2137 | } | 2284 | } |
2138 | 2285 | ||
2139 | static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr) | 2286 | static u32 dib8000_get_snr(struct dvb_frontend *fe) |
2140 | { | 2287 | { |
2141 | struct dib8000_state *state = fe->demodulator_priv; | 2288 | struct dib8000_state *state = fe->demodulator_priv; |
2289 | u32 n, s, exp; | ||
2142 | u16 val; | 2290 | u16 val; |
2143 | s32 signal_mant, signal_exp, noise_mant, noise_exp; | ||
2144 | u32 result = 0; | ||
2145 | 2291 | ||
2146 | val = dib8000_read_word(state, 542); | 2292 | val = dib8000_read_word(state, 542); |
2147 | noise_mant = (val >> 6) & 0xff; | 2293 | n = (val >> 6) & 0xff; |
2148 | noise_exp = (val & 0x3f); | 2294 | exp = (val & 0x3f); |
2295 | if ((exp & 0x20) != 0) | ||
2296 | exp -= 0x40; | ||
2297 | n <<= exp+16; | ||
2149 | 2298 | ||
2150 | val = dib8000_read_word(state, 543); | 2299 | val = dib8000_read_word(state, 543); |
2151 | signal_mant = (val >> 6) & 0xff; | 2300 | s = (val >> 6) & 0xff; |
2152 | signal_exp = (val & 0x3f); | 2301 | exp = (val & 0x3f); |
2302 | if ((exp & 0x20) != 0) | ||
2303 | exp -= 0x40; | ||
2304 | s <<= exp+16; | ||
2305 | |||
2306 | if (n > 0) { | ||
2307 | u32 t = (s/n) << 16; | ||
2308 | return t + ((s << 16) - n*t) / n; | ||
2309 | } | ||
2310 | return 0xffffffff; | ||
2311 | } | ||
2153 | 2312 | ||
2154 | if ((noise_exp & 0x20) != 0) | 2313 | static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr) |
2155 | noise_exp -= 0x40; | 2314 | { |
2156 | if ((signal_exp & 0x20) != 0) | 2315 | struct dib8000_state *state = fe->demodulator_priv; |
2157 | signal_exp -= 0x40; | 2316 | u8 index_frontend; |
2317 | u32 snr_master; | ||
2158 | 2318 | ||
2159 | if (signal_mant != 0) | 2319 | snr_master = dib8000_get_snr(fe); |
2160 | result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant); | 2320 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) |
2161 | else | 2321 | snr_master += dib8000_get_snr(state->fe[index_frontend]); |
2162 | result = intlog10(2) * 10 * signal_exp - 100; | 2322 | |
2163 | if (noise_mant != 0) | 2323 | if (snr_master != 0) { |
2164 | result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant); | 2324 | snr_master = 10*intlog10(snr_master>>16); |
2325 | *snr = snr_master / ((1 << 24) / 10); | ||
2326 | } | ||
2165 | else | 2327 | else |
2166 | result -= intlog10(2) * 10 * noise_exp - 100; | 2328 | *snr = 0; |
2167 | 2329 | ||
2168 | *snr = result / ((1 << 24) / 10); | ||
2169 | return 0; | 2330 | return 0; |
2170 | } | 2331 | } |
2171 | 2332 | ||
2333 | int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave) | ||
2334 | { | ||
2335 | struct dib8000_state *state = fe->demodulator_priv; | ||
2336 | u8 index_frontend = 1; | ||
2337 | |||
2338 | while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL)) | ||
2339 | index_frontend++; | ||
2340 | if (index_frontend < MAX_NUMBER_OF_FRONTENDS) { | ||
2341 | dprintk("set slave fe %p to index %i", fe_slave, index_frontend); | ||
2342 | state->fe[index_frontend] = fe_slave; | ||
2343 | return 0; | ||
2344 | } | ||
2345 | |||
2346 | dprintk("too many slave frontend"); | ||
2347 | return -ENOMEM; | ||
2348 | } | ||
2349 | EXPORT_SYMBOL(dib8000_set_slave_frontend); | ||
2350 | |||
2351 | int dib8000_remove_slave_frontend(struct dvb_frontend *fe) | ||
2352 | { | ||
2353 | struct dib8000_state *state = fe->demodulator_priv; | ||
2354 | u8 index_frontend = 1; | ||
2355 | |||
2356 | while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL)) | ||
2357 | index_frontend++; | ||
2358 | if (index_frontend != 1) { | ||
2359 | dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1); | ||
2360 | state->fe[index_frontend] = NULL; | ||
2361 | return 0; | ||
2362 | } | ||
2363 | |||
2364 | dprintk("no frontend to be removed"); | ||
2365 | return -ENODEV; | ||
2366 | } | ||
2367 | EXPORT_SYMBOL(dib8000_remove_slave_frontend); | ||
2368 | |||
2369 | struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index) | ||
2370 | { | ||
2371 | struct dib8000_state *state = fe->demodulator_priv; | ||
2372 | |||
2373 | if (slave_index >= MAX_NUMBER_OF_FRONTENDS) | ||
2374 | return NULL; | ||
2375 | return state->fe[slave_index]; | ||
2376 | } | ||
2377 | EXPORT_SYMBOL(dib8000_get_slave_frontend); | ||
2378 | |||
2379 | |||
2172 | int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) | 2380 | int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) |
2173 | { | 2381 | { |
2174 | int k = 0; | 2382 | int k = 0; |
@@ -2227,7 +2435,13 @@ static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_fron | |||
2227 | static void dib8000_release(struct dvb_frontend *fe) | 2435 | static void dib8000_release(struct dvb_frontend *fe) |
2228 | { | 2436 | { |
2229 | struct dib8000_state *st = fe->demodulator_priv; | 2437 | struct dib8000_state *st = fe->demodulator_priv; |
2438 | u8 index_frontend; | ||
2439 | |||
2440 | for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++) | ||
2441 | dvb_frontend_detach(st->fe[index_frontend]); | ||
2442 | |||
2230 | dibx000_exit_i2c_master(&st->i2c_master); | 2443 | dibx000_exit_i2c_master(&st->i2c_master); |
2444 | kfree(st->fe[0]); | ||
2231 | kfree(st); | 2445 | kfree(st); |
2232 | } | 2446 | } |
2233 | 2447 | ||
@@ -2242,19 +2456,19 @@ EXPORT_SYMBOL(dib8000_get_i2c_master); | |||
2242 | int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) | 2456 | int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) |
2243 | { | 2457 | { |
2244 | struct dib8000_state *st = fe->demodulator_priv; | 2458 | struct dib8000_state *st = fe->demodulator_priv; |
2245 | u16 val = dib8000_read_word(st, 299) & 0xffef; | 2459 | u16 val = dib8000_read_word(st, 299) & 0xffef; |
2246 | val |= (onoff & 0x1) << 4; | 2460 | val |= (onoff & 0x1) << 4; |
2247 | 2461 | ||
2248 | dprintk("pid filter enabled %d", onoff); | 2462 | dprintk("pid filter enabled %d", onoff); |
2249 | return dib8000_write_word(st, 299, val); | 2463 | return dib8000_write_word(st, 299, val); |
2250 | } | 2464 | } |
2251 | EXPORT_SYMBOL(dib8000_pid_filter_ctrl); | 2465 | EXPORT_SYMBOL(dib8000_pid_filter_ctrl); |
2252 | 2466 | ||
2253 | int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) | 2467 | int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) |
2254 | { | 2468 | { |
2255 | struct dib8000_state *st = fe->demodulator_priv; | 2469 | struct dib8000_state *st = fe->demodulator_priv; |
2256 | dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); | 2470 | dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); |
2257 | return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0); | 2471 | return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0); |
2258 | } | 2472 | } |
2259 | EXPORT_SYMBOL(dib8000_pid_filter); | 2473 | EXPORT_SYMBOL(dib8000_pid_filter); |
2260 | 2474 | ||
@@ -2298,6 +2512,9 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s | |||
2298 | state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL); | 2512 | state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL); |
2299 | if (state == NULL) | 2513 | if (state == NULL) |
2300 | return NULL; | 2514 | return NULL; |
2515 | fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL); | ||
2516 | if (fe == NULL) | ||
2517 | goto error; | ||
2301 | 2518 | ||
2302 | memcpy(&state->cfg, cfg, sizeof(struct dib8000_config)); | 2519 | memcpy(&state->cfg, cfg, sizeof(struct dib8000_config)); |
2303 | state->i2c.adap = i2c_adap; | 2520 | state->i2c.adap = i2c_adap; |
@@ -2311,9 +2528,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)) | 2528 | 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; | 2529 | state->cfg.output_mode = OUTMODE_MPEG2_FIFO; |
2313 | 2530 | ||
2314 | fe = &state->fe; | 2531 | state->fe[0] = fe; |
2315 | fe->demodulator_priv = state; | 2532 | fe->demodulator_priv = state; |
2316 | memcpy(&state->fe.ops, &dib8000_ops, sizeof(struct dvb_frontend_ops)); | 2533 | memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops)); |
2317 | 2534 | ||
2318 | state->timf_default = cfg->pll->timf; | 2535 | state->timf_default = cfg->pll->timf; |
2319 | 2536 | ||