Commit | Line | Data |
---|---|---|
41b44e04 PH |
1 | /* |
2 | * Abilis Systems Single DVB-T Receiver | |
3 | * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com> | |
87ad567e | 4 | * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com> |
41b44e04 PH |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; either version 2, or (at your option) | |
9 | * any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program; if not, write to the Free Software | |
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
19 | */ | |
20 | #include <linux/version.h> | |
21 | ||
22 | #include "as102_drv.h" | |
23 | #include "as10x_types.h" | |
24 | #include "as10x_cmd.h" | |
25 | ||
26 | extern int elna_enable; | |
27 | ||
41b44e04 PH |
28 | static void as10x_fe_copy_tps_parameters(struct dvb_frontend_parameters *dst, |
29 | struct as10x_tps *src); | |
30 | ||
31 | static void as102_fe_copy_tune_parameters(struct as10x_tune_args *dst, | |
32 | struct dvb_frontend_parameters *src); | |
33 | ||
41b44e04 | 34 | static int as102_fe_set_frontend(struct dvb_frontend *fe, |
87ad567e DH |
35 | struct dvb_frontend_parameters *params) |
36 | { | |
41b44e04 PH |
37 | int ret = 0; |
38 | struct as102_dev_t *dev; | |
39 | struct as10x_tune_args tune_args = { 0 }; | |
40 | ||
41 | ENTER(); | |
42 | ||
87ad567e DH |
43 | dev = (struct as102_dev_t *) fe->tuner_priv; |
44 | if (dev == NULL) | |
41b44e04 PH |
45 | return -ENODEV; |
46 | ||
47 | if (mutex_lock_interruptible(&dev->bus_adap.lock)) | |
48 | return -EBUSY; | |
49 | ||
50 | as102_fe_copy_tune_parameters(&tune_args, params); | |
51 | ||
52 | /* send abilis command: SET_TUNE */ | |
53 | ret = as10x_cmd_set_tune(&dev->bus_adap, &tune_args); | |
87ad567e | 54 | if (ret != 0) |
41b44e04 | 55 | dprintk(debug, "as10x_cmd_set_tune failed. (err = %d)\n", ret); |
41b44e04 PH |
56 | |
57 | mutex_unlock(&dev->bus_adap.lock); | |
58 | ||
59 | LEAVE(); | |
60 | return (ret < 0) ? -EINVAL : 0; | |
61 | } | |
62 | ||
87ad567e | 63 | static int as102_fe_get_frontend(struct dvb_frontend *fe, |
41b44e04 PH |
64 | struct dvb_frontend_parameters *p) { |
65 | int ret = 0; | |
66 | struct as102_dev_t *dev; | |
67 | struct as10x_tps tps = { 0 }; | |
68 | ||
69 | ENTER(); | |
70 | ||
87ad567e DH |
71 | dev = (struct as102_dev_t *) fe->tuner_priv; |
72 | if (dev == NULL) | |
41b44e04 PH |
73 | return -EINVAL; |
74 | ||
75 | if (mutex_lock_interruptible(&dev->bus_adap.lock)) | |
76 | return -EBUSY; | |
77 | ||
78 | /* send abilis command: GET_TPS */ | |
79 | ret = as10x_cmd_get_tps(&dev->bus_adap, &tps); | |
80 | ||
81 | if (ret == 0) | |
82 | as10x_fe_copy_tps_parameters(p, &tps); | |
83 | ||
84 | mutex_unlock(&dev->bus_adap.lock); | |
85 | ||
86 | LEAVE(); | |
87 | return (ret < 0) ? -EINVAL : 0; | |
88 | } | |
89 | ||
90 | static int as102_fe_get_tune_settings(struct dvb_frontend *fe, | |
91 | struct dvb_frontend_tune_settings *settings) { | |
92 | ENTER(); | |
93 | ||
94 | #if 0 | |
95 | dprintk(debug, "step_size = %d\n", settings->step_size); | |
96 | dprintk(debug, "max_drift = %d\n", settings->max_drift); | |
87ad567e DH |
97 | dprintk(debug, "min_delay_ms = %d -> %d\n", settings->min_delay_ms, |
98 | 1000); | |
41b44e04 PH |
99 | #endif |
100 | ||
101 | settings->min_delay_ms = 1000; | |
102 | ||
103 | LEAVE(); | |
104 | return 0; | |
105 | } | |
106 | ||
107 | ||
87ad567e DH |
108 | static int as102_fe_read_status(struct dvb_frontend *fe, fe_status_t *status) |
109 | { | |
41b44e04 PH |
110 | int ret = 0; |
111 | struct as102_dev_t *dev; | |
112 | struct as10x_tune_status tstate = { 0 }; | |
113 | ||
114 | ENTER(); | |
115 | ||
87ad567e DH |
116 | dev = (struct as102_dev_t *) fe->tuner_priv; |
117 | if (dev == NULL) | |
41b44e04 PH |
118 | return -ENODEV; |
119 | ||
120 | if (mutex_lock_interruptible(&dev->bus_adap.lock)) | |
121 | return -EBUSY; | |
122 | ||
123 | /* send abilis command: GET_TUNE_STATUS */ | |
124 | ret = as10x_cmd_get_tune_status(&dev->bus_adap, &tstate); | |
125 | if (ret < 0) { | |
87ad567e DH |
126 | dprintk(debug, "as10x_cmd_get_tune_status failed (err = %d)\n", |
127 | ret); | |
41b44e04 PH |
128 | goto out; |
129 | } | |
130 | ||
131 | dev->signal_strength = tstate.signal_strength; | |
132 | dev->ber = tstate.BER; | |
133 | ||
87ad567e DH |
134 | switch (tstate.tune_state) { |
135 | case TUNE_STATUS_SIGNAL_DVB_OK: | |
136 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER; | |
137 | break; | |
138 | case TUNE_STATUS_STREAM_DETECTED: | |
139 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC; | |
140 | break; | |
141 | case TUNE_STATUS_STREAM_TUNED: | |
142 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | | |
143 | FE_HAS_LOCK; | |
144 | break; | |
145 | default: | |
146 | *status = TUNE_STATUS_NOT_TUNED; | |
41b44e04 PH |
147 | } |
148 | ||
87ad567e | 149 | dprintk(debug, "tuner status: 0x%02x, strength %d, per: %d, ber: %d\n", |
41b44e04 PH |
150 | tstate.tune_state, tstate.signal_strength, |
151 | tstate.PER, tstate.BER); | |
152 | ||
153 | if (*status & FE_HAS_LOCK) { | |
154 | if (as10x_cmd_get_demod_stats(&dev->bus_adap, | |
87ad567e | 155 | (struct as10x_demod_stats *) &dev->demod_stats) < 0) { |
41b44e04 | 156 | memset(&dev->demod_stats, 0, sizeof(dev->demod_stats)); |
87ad567e DH |
157 | dprintk(debug, "as10x_cmd_get_demod_stats failed " |
158 | "(probably not tuned)\n"); | |
41b44e04 | 159 | } else { |
87ad567e DH |
160 | dprintk(debug, |
161 | "demod status: fc: 0x%08x, bad fc: 0x%08x, " | |
162 | "bytes corrected: 0x%08x , MER: 0x%04x\n", | |
163 | dev->demod_stats.frame_count, | |
164 | dev->demod_stats.bad_frame_count, | |
165 | dev->demod_stats.bytes_fixed_by_rs, | |
166 | dev->demod_stats.mer); | |
41b44e04 PH |
167 | } |
168 | } else { | |
169 | memset(&dev->demod_stats, 0, sizeof(dev->demod_stats)); | |
170 | } | |
171 | ||
172 | out: | |
173 | mutex_unlock(&dev->bus_adap.lock); | |
174 | LEAVE(); | |
175 | return ret; | |
176 | } | |
177 | ||
178 | /* | |
179 | * Note: | |
180 | * - in AS102 SNR=MER | |
181 | * - the SNR will be returned in linear terms, i.e. not in dB | |
182 | * - the accuracy equals ±2dB for a SNR range from 4dB to 30dB | |
183 | * - the accuracy is >2dB for SNR values outside this range | |
184 | */ | |
87ad567e DH |
185 | static int as102_fe_read_snr(struct dvb_frontend *fe, u16 *snr) |
186 | { | |
41b44e04 PH |
187 | struct as102_dev_t *dev; |
188 | ||
189 | ENTER(); | |
190 | ||
87ad567e DH |
191 | dev = (struct as102_dev_t *) fe->tuner_priv; |
192 | if (dev == NULL) | |
41b44e04 PH |
193 | return -ENODEV; |
194 | ||
195 | *snr = dev->demod_stats.mer; | |
196 | ||
197 | LEAVE(); | |
198 | return 0; | |
199 | } | |
200 | ||
87ad567e DH |
201 | static int as102_fe_read_ber(struct dvb_frontend *fe, u32 *ber) |
202 | { | |
41b44e04 PH |
203 | struct as102_dev_t *dev; |
204 | ||
205 | ENTER(); | |
206 | ||
87ad567e DH |
207 | dev = (struct as102_dev_t *) fe->tuner_priv; |
208 | if (dev == NULL) | |
41b44e04 PH |
209 | return -ENODEV; |
210 | ||
211 | *ber = dev->ber; | |
212 | ||
213 | LEAVE(); | |
214 | return 0; | |
215 | } | |
216 | ||
87ad567e DH |
217 | static int as102_fe_read_signal_strength(struct dvb_frontend *fe, |
218 | u16 *strength) | |
219 | { | |
41b44e04 PH |
220 | struct as102_dev_t *dev; |
221 | ||
222 | ENTER(); | |
223 | ||
87ad567e DH |
224 | dev = (struct as102_dev_t *) fe->tuner_priv; |
225 | if (dev == NULL) | |
41b44e04 PH |
226 | return -ENODEV; |
227 | ||
228 | *strength = (((0xffff * 400) * dev->signal_strength + 41000) * 2); | |
229 | ||
230 | LEAVE(); | |
231 | return 0; | |
232 | } | |
233 | ||
87ad567e DH |
234 | static int as102_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
235 | { | |
41b44e04 PH |
236 | struct as102_dev_t *dev; |
237 | ||
238 | ENTER(); | |
239 | ||
87ad567e DH |
240 | dev = (struct as102_dev_t *) fe->tuner_priv; |
241 | if (dev == NULL) | |
41b44e04 PH |
242 | return -ENODEV; |
243 | ||
244 | if (dev->demod_stats.has_started) | |
245 | *ucblocks = dev->demod_stats.bad_frame_count; | |
246 | else | |
247 | *ucblocks = 0; | |
248 | ||
249 | LEAVE(); | |
250 | return 0; | |
251 | } | |
252 | ||
87ad567e DH |
253 | static int as102_fe_ts_bus_ctrl(struct dvb_frontend *fe, int acquire) |
254 | { | |
41b44e04 PH |
255 | struct as102_dev_t *dev; |
256 | int ret; | |
257 | ||
258 | ENTER(); | |
259 | ||
87ad567e DH |
260 | dev = (struct as102_dev_t *) fe->tuner_priv; |
261 | if (dev == NULL) | |
41b44e04 PH |
262 | return -ENODEV; |
263 | ||
264 | if (mutex_lock_interruptible(&dev->bus_adap.lock)) | |
265 | return -EBUSY; | |
266 | ||
267 | if (acquire) { | |
268 | if (elna_enable) | |
269 | as10x_cmd_set_context(&dev->bus_adap, 1010, 0xC0); | |
270 | ||
271 | ret = as10x_cmd_turn_on(&dev->bus_adap); | |
272 | } else { | |
273 | ret = as10x_cmd_turn_off(&dev->bus_adap); | |
274 | } | |
275 | ||
276 | mutex_unlock(&dev->bus_adap.lock); | |
277 | ||
278 | LEAVE(); | |
279 | return ret; | |
280 | } | |
41b44e04 PH |
281 | |
282 | static struct dvb_frontend_ops as102_fe_ops = { | |
283 | .info = { | |
4f7b7c01 | 284 | .name = "Unknown AS102 device", |
41b44e04 PH |
285 | .type = FE_OFDM, |
286 | .frequency_min = 174000000, | |
287 | .frequency_max = 862000000, | |
288 | .frequency_stepsize = 166667, | |
289 | .caps = FE_CAN_INVERSION_AUTO | |
290 | | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | |
291 | | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | |
292 | | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QPSK | |
293 | | FE_CAN_QAM_AUTO | |
294 | | FE_CAN_TRANSMISSION_MODE_AUTO | |
295 | | FE_CAN_GUARD_INTERVAL_AUTO | |
296 | | FE_CAN_HIERARCHY_AUTO | |
297 | | FE_CAN_RECOVER | |
298 | | FE_CAN_MUTE_TS | |
299 | }, | |
300 | ||
301 | .set_frontend = as102_fe_set_frontend, | |
302 | .get_frontend = as102_fe_get_frontend, | |
303 | .get_tune_settings = as102_fe_get_tune_settings, | |
304 | ||
41b44e04 PH |
305 | .read_status = as102_fe_read_status, |
306 | .read_snr = as102_fe_read_snr, | |
307 | .read_ber = as102_fe_read_ber, | |
308 | .read_signal_strength = as102_fe_read_signal_strength, | |
309 | .read_ucblocks = as102_fe_read_ucblocks, | |
41b44e04 | 310 | .ts_bus_ctrl = as102_fe_ts_bus_ctrl, |
41b44e04 PH |
311 | }; |
312 | ||
87ad567e DH |
313 | int as102_dvb_unregister_fe(struct dvb_frontend *fe) |
314 | { | |
41b44e04 PH |
315 | /* unregister frontend */ |
316 | dvb_unregister_frontend(fe); | |
317 | ||
41b44e04 PH |
318 | /* detach frontend */ |
319 | dvb_frontend_detach(fe); | |
92e9d1b7 | 320 | |
41b44e04 PH |
321 | return 0; |
322 | } | |
323 | ||
87ad567e DH |
324 | int as102_dvb_register_fe(struct as102_dev_t *as102_dev, |
325 | struct dvb_frontend *dvb_fe) | |
326 | { | |
41b44e04 PH |
327 | int errno; |
328 | struct dvb_adapter *dvb_adap; | |
329 | ||
87ad567e | 330 | if (as102_dev == NULL) |
41b44e04 PH |
331 | return -EINVAL; |
332 | ||
333 | /* extract dvb_adapter */ | |
334 | dvb_adap = &as102_dev->dvb_adap; | |
335 | ||
336 | /* init frontend callback ops */ | |
337 | memcpy(&dvb_fe->ops, &as102_fe_ops, sizeof(struct dvb_frontend_ops)); | |
4f7b7c01 DH |
338 | strncpy(dvb_fe->ops.info.name, as102_dev->name, |
339 | sizeof(dvb_fe->ops.info.name)); | |
41b44e04 PH |
340 | |
341 | /* register dbvb frontend */ | |
342 | errno = dvb_register_frontend(dvb_adap, dvb_fe); | |
87ad567e | 343 | if (errno == 0) |
41b44e04 PH |
344 | dvb_fe->tuner_priv = as102_dev; |
345 | ||
346 | return errno; | |
347 | } | |
348 | ||
349 | static void as10x_fe_copy_tps_parameters(struct dvb_frontend_parameters *dst, | |
87ad567e DH |
350 | struct as10x_tps *as10x_tps) |
351 | { | |
41b44e04 PH |
352 | |
353 | struct dvb_ofdm_parameters *fe_tps = &dst->u.ofdm; | |
354 | ||
355 | /* extract consteallation */ | |
87ad567e DH |
356 | switch (as10x_tps->constellation) { |
357 | case CONST_QPSK: | |
358 | fe_tps->constellation = QPSK; | |
359 | break; | |
360 | case CONST_QAM16: | |
361 | fe_tps->constellation = QAM_16; | |
362 | break; | |
363 | case CONST_QAM64: | |
364 | fe_tps->constellation = QAM_64; | |
365 | break; | |
41b44e04 PH |
366 | } |
367 | ||
368 | /* extract hierarchy */ | |
87ad567e DH |
369 | switch (as10x_tps->hierarchy) { |
370 | case HIER_NONE: | |
371 | fe_tps->hierarchy_information = HIERARCHY_NONE; | |
372 | break; | |
373 | case HIER_ALPHA_1: | |
374 | fe_tps->hierarchy_information = HIERARCHY_1; | |
375 | break; | |
376 | case HIER_ALPHA_2: | |
377 | fe_tps->hierarchy_information = HIERARCHY_2; | |
378 | break; | |
379 | case HIER_ALPHA_4: | |
380 | fe_tps->hierarchy_information = HIERARCHY_4; | |
381 | break; | |
41b44e04 PH |
382 | } |
383 | ||
384 | /* extract code rate HP */ | |
87ad567e DH |
385 | switch (as10x_tps->code_rate_HP) { |
386 | case CODE_RATE_1_2: | |
387 | fe_tps->code_rate_HP = FEC_1_2; | |
388 | break; | |
389 | case CODE_RATE_2_3: | |
390 | fe_tps->code_rate_HP = FEC_2_3; | |
391 | break; | |
392 | case CODE_RATE_3_4: | |
393 | fe_tps->code_rate_HP = FEC_3_4; | |
394 | break; | |
395 | case CODE_RATE_5_6: | |
396 | fe_tps->code_rate_HP = FEC_5_6; | |
397 | break; | |
398 | case CODE_RATE_7_8: | |
399 | fe_tps->code_rate_HP = FEC_7_8; | |
400 | break; | |
41b44e04 PH |
401 | } |
402 | ||
403 | /* extract code rate LP */ | |
87ad567e DH |
404 | switch (as10x_tps->code_rate_LP) { |
405 | case CODE_RATE_1_2: | |
406 | fe_tps->code_rate_LP = FEC_1_2; | |
407 | break; | |
408 | case CODE_RATE_2_3: | |
409 | fe_tps->code_rate_LP = FEC_2_3; | |
410 | break; | |
411 | case CODE_RATE_3_4: | |
412 | fe_tps->code_rate_LP = FEC_3_4; | |
413 | break; | |
414 | case CODE_RATE_5_6: | |
415 | fe_tps->code_rate_LP = FEC_5_6; | |
416 | break; | |
417 | case CODE_RATE_7_8: | |
418 | fe_tps->code_rate_LP = FEC_7_8; | |
419 | break; | |
41b44e04 PH |
420 | } |
421 | ||
422 | /* extract guard interval */ | |
87ad567e DH |
423 | switch (as10x_tps->guard_interval) { |
424 | case GUARD_INT_1_32: | |
425 | fe_tps->guard_interval = GUARD_INTERVAL_1_32; | |
426 | break; | |
427 | case GUARD_INT_1_16: | |
428 | fe_tps->guard_interval = GUARD_INTERVAL_1_16; | |
429 | break; | |
430 | case GUARD_INT_1_8: | |
431 | fe_tps->guard_interval = GUARD_INTERVAL_1_8; | |
432 | break; | |
433 | case GUARD_INT_1_4: | |
434 | fe_tps->guard_interval = GUARD_INTERVAL_1_4; | |
435 | break; | |
41b44e04 PH |
436 | } |
437 | ||
438 | /* extract transmission mode */ | |
87ad567e DH |
439 | switch (as10x_tps->transmission_mode) { |
440 | case TRANS_MODE_2K: | |
441 | fe_tps->transmission_mode = TRANSMISSION_MODE_2K; | |
442 | break; | |
443 | case TRANS_MODE_8K: | |
444 | fe_tps->transmission_mode = TRANSMISSION_MODE_8K; | |
445 | break; | |
41b44e04 PH |
446 | } |
447 | } | |
448 | ||
87ad567e DH |
449 | static uint8_t as102_fe_get_code_rate(fe_code_rate_t arg) |
450 | { | |
41b44e04 PH |
451 | uint8_t c; |
452 | ||
87ad567e DH |
453 | switch (arg) { |
454 | case FEC_1_2: | |
455 | c = CODE_RATE_1_2; | |
456 | break; | |
457 | case FEC_2_3: | |
458 | c = CODE_RATE_2_3; | |
459 | break; | |
460 | case FEC_3_4: | |
461 | c = CODE_RATE_3_4; | |
462 | break; | |
463 | case FEC_5_6: | |
464 | c = CODE_RATE_5_6; | |
465 | break; | |
466 | case FEC_7_8: | |
467 | c = CODE_RATE_7_8; | |
468 | break; | |
469 | default: | |
470 | c = CODE_RATE_UNKNOWN; | |
471 | break; | |
41b44e04 PH |
472 | } |
473 | ||
474 | return c; | |
475 | } | |
476 | ||
477 | static void as102_fe_copy_tune_parameters(struct as10x_tune_args *tune_args, | |
87ad567e DH |
478 | struct dvb_frontend_parameters *params) |
479 | { | |
41b44e04 PH |
480 | |
481 | /* set frequency */ | |
482 | tune_args->freq = params->frequency / 1000; | |
483 | ||
484 | /* fix interleaving_mode */ | |
485 | tune_args->interleaving_mode = INTLV_NATIVE; | |
486 | ||
87ad567e DH |
487 | switch (params->u.ofdm.bandwidth) { |
488 | case BANDWIDTH_8_MHZ: | |
489 | tune_args->bandwidth = BW_8_MHZ; | |
490 | break; | |
491 | case BANDWIDTH_7_MHZ: | |
492 | tune_args->bandwidth = BW_7_MHZ; | |
493 | break; | |
494 | case BANDWIDTH_6_MHZ: | |
495 | tune_args->bandwidth = BW_6_MHZ; | |
496 | break; | |
497 | default: | |
498 | tune_args->bandwidth = BW_8_MHZ; | |
41b44e04 PH |
499 | } |
500 | ||
87ad567e DH |
501 | switch (params->u.ofdm.guard_interval) { |
502 | case GUARD_INTERVAL_1_32: | |
503 | tune_args->guard_interval = GUARD_INT_1_32; | |
504 | break; | |
505 | case GUARD_INTERVAL_1_16: | |
506 | tune_args->guard_interval = GUARD_INT_1_16; | |
507 | break; | |
508 | case GUARD_INTERVAL_1_8: | |
509 | tune_args->guard_interval = GUARD_INT_1_8; | |
510 | break; | |
511 | case GUARD_INTERVAL_1_4: | |
512 | tune_args->guard_interval = GUARD_INT_1_4; | |
513 | break; | |
514 | case GUARD_INTERVAL_AUTO: | |
515 | default: | |
516 | tune_args->guard_interval = GUARD_UNKNOWN; | |
517 | break; | |
41b44e04 PH |
518 | } |
519 | ||
87ad567e DH |
520 | switch (params->u.ofdm.constellation) { |
521 | case QPSK: | |
522 | tune_args->constellation = CONST_QPSK; | |
523 | break; | |
524 | case QAM_16: | |
525 | tune_args->constellation = CONST_QAM16; | |
526 | break; | |
527 | case QAM_64: | |
528 | tune_args->constellation = CONST_QAM64; | |
529 | break; | |
530 | default: | |
531 | tune_args->constellation = CONST_UNKNOWN; | |
532 | break; | |
41b44e04 PH |
533 | } |
534 | ||
87ad567e DH |
535 | switch (params->u.ofdm.transmission_mode) { |
536 | case TRANSMISSION_MODE_2K: | |
537 | tune_args->transmission_mode = TRANS_MODE_2K; | |
538 | break; | |
539 | case TRANSMISSION_MODE_8K: | |
540 | tune_args->transmission_mode = TRANS_MODE_8K; | |
541 | break; | |
542 | default: | |
543 | tune_args->transmission_mode = TRANS_MODE_UNKNOWN; | |
41b44e04 PH |
544 | } |
545 | ||
87ad567e DH |
546 | switch (params->u.ofdm.hierarchy_information) { |
547 | case HIERARCHY_NONE: | |
548 | tune_args->hierarchy = HIER_NONE; | |
549 | break; | |
550 | case HIERARCHY_1: | |
551 | tune_args->hierarchy = HIER_ALPHA_1; | |
552 | break; | |
553 | case HIERARCHY_2: | |
554 | tune_args->hierarchy = HIER_ALPHA_2; | |
555 | break; | |
556 | case HIERARCHY_4: | |
557 | tune_args->hierarchy = HIER_ALPHA_4; | |
558 | break; | |
559 | case HIERARCHY_AUTO: | |
560 | tune_args->hierarchy = HIER_UNKNOWN; | |
561 | break; | |
41b44e04 PH |
562 | } |
563 | ||
564 | dprintk(debug, "tuner parameters: freq: %d bw: 0x%02x gi: 0x%02x\n", | |
565 | params->frequency, | |
566 | tune_args->bandwidth, | |
567 | tune_args->guard_interval); | |
568 | ||
569 | /* | |
570 | * Detect a hierarchy selection | |
571 | * if HP/LP are both set to FEC_NONE, HP will be selected. | |
572 | */ | |
573 | if ((tune_args->hierarchy != HIER_NONE) && | |
574 | ((params->u.ofdm.code_rate_LP == FEC_NONE) || | |
575 | (params->u.ofdm.code_rate_HP == FEC_NONE))) { | |
576 | ||
577 | if (params->u.ofdm.code_rate_LP == FEC_NONE) { | |
578 | tune_args->hier_select = HIER_HIGH_PRIORITY; | |
579 | tune_args->code_rate = | |
87ad567e | 580 | as102_fe_get_code_rate(params->u.ofdm.code_rate_HP); |
41b44e04 PH |
581 | } |
582 | ||
583 | if (params->u.ofdm.code_rate_HP == FEC_NONE) { | |
584 | tune_args->hier_select = HIER_LOW_PRIORITY; | |
585 | tune_args->code_rate = | |
87ad567e | 586 | as102_fe_get_code_rate(params->u.ofdm.code_rate_LP); |
41b44e04 PH |
587 | } |
588 | ||
589 | dprintk(debug, "\thierarchy: 0x%02x " | |
590 | "selected: %s code_rate_%s: 0x%02x\n", | |
591 | tune_args->hierarchy, | |
87ad567e DH |
592 | tune_args->hier_select == HIER_HIGH_PRIORITY ? |
593 | "HP" : "LP", | |
594 | tune_args->hier_select == HIER_HIGH_PRIORITY ? | |
595 | "HP" : "LP", | |
41b44e04 PH |
596 | tune_args->code_rate); |
597 | } else { | |
87ad567e DH |
598 | tune_args->code_rate = |
599 | as102_fe_get_code_rate(params->u.ofdm.code_rate_HP); | |
41b44e04 PH |
600 | } |
601 | } | |
41b44e04 PH |
602 | |
603 | /* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ |