diff options
author | Pierrick Hascoet <pierrick.hascoet@abilis.com> | 2011-10-31 11:24:39 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-11-03 05:42:49 -0400 |
commit | 41b44e0418112e694f9b7beb8088efbb8c9c0053 (patch) | |
tree | c12811c8a738b48f75d8b9a9eeb7e7d1cad68a54 /drivers/staging/media/as102/as102_fe.c | |
parent | 539b469518b45c0b5915bec3e258e21e03667084 (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.c | 647 |
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 | |||
25 | extern int elna_enable; | ||
26 | |||
27 | #if defined(CONFIG_DVB_CORE) || defined(CONFIG_DVB_CORE_MODULE) | ||
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 | |||
34 | static 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)) | ||
67 | static 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 | |||
92 | static 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 | |||
120 | static 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 | |||
146 | static 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 | |||
163 | static 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 | |||
226 | out: | ||
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 | */ | ||
239 | static 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 | |||
253 | static 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 | |||
267 | static 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 | |||
281 | static 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)) | ||
299 | static 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 | |||
327 | static 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 | |||
365 | int 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 | |||
377 | int 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 | |||
398 | static 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 | |||
497 | static 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 | |||
524 | static 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: */ | ||