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