diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-09 17:26:28 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2013-03-21 06:47:31 -0400 |
commit | d42f1cb25334bbcddf213a00bb67083414027933 (patch) | |
tree | 698df33b58aa2d1a5486afb4c9f3d7050e51124e | |
parent | ff702eb8d9c8ca293e7f0343dd38b718d58815b0 (diff) |
[media] siano: Convert it to report DVBv5 stats
While this frontend provides a nice set of statistics, the
way it is currently reported to userspace is poor. Worse than
that, instead of using quality indicators that range from 0 to 65535,
as expected by userspace, most indicators range from 0 to 100.
Improve it by using DVBv5 statistics API. The legacy indicators
are still reported using the very same old way, but they're now
using a proper range (0 to 65535 for quality indicadors; 0.1 dB
for SNR).
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/common/siano/smsdvb.c | 826 |
1 files changed, 468 insertions, 358 deletions
diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c index 04544f591df5..a5f52721154c 100644 --- a/drivers/media/common/siano/smsdvb.c +++ b/drivers/media/common/siano/smsdvb.c | |||
@@ -49,7 +49,10 @@ struct smsdvb_client_t { | |||
49 | struct completion tune_done; | 49 | struct completion tune_done; |
50 | struct completion stats_done; | 50 | struct completion stats_done; |
51 | 51 | ||
52 | struct SMSHOSTLIB_STATISTICS_DVB_EX_S sms_stat_dvb; | 52 | int last_per; |
53 | |||
54 | int legacy_ber, legacy_per; | ||
55 | |||
53 | int event_fe_state; | 56 | int event_fe_state; |
54 | int event_unc_state; | 57 | int event_unc_state; |
55 | }; | 58 | }; |
@@ -61,6 +64,82 @@ static int sms_dbg; | |||
61 | module_param_named(debug, sms_dbg, int, 0644); | 64 | module_param_named(debug, sms_dbg, int, 0644); |
62 | MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); | 65 | MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); |
63 | 66 | ||
67 | /* | ||
68 | * This struct is a mix of RECEPTION_STATISTICS_EX_S and SRVM_SIGNAL_STATUS_S. | ||
69 | * It was obtained by comparing the way it was filled by the original code | ||
70 | */ | ||
71 | struct RECEPTION_STATISTICS_PER_SLICES_S { | ||
72 | u32 result; | ||
73 | u32 snr; | ||
74 | s32 inBandPower; | ||
75 | u32 tsPackets; | ||
76 | u32 etsPackets; | ||
77 | u32 constellation; | ||
78 | u32 hpCode; | ||
79 | u32 tpsSrvIndLP; | ||
80 | u32 tpsSrvIndHP; | ||
81 | u32 cellId; | ||
82 | u32 reason; | ||
83 | u32 requestId; | ||
84 | u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */ | ||
85 | |||
86 | u32 BER; /* Post Viterbi BER [1E-5] */ | ||
87 | s32 RSSI; /* dBm */ | ||
88 | s32 CarrierOffset; /* Carrier Offset in bin/1024 */ | ||
89 | |||
90 | u32 IsRfLocked; /* 0 - not locked, 1 - locked */ | ||
91 | u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ | ||
92 | |||
93 | u32 BERBitCount; /* Total number of SYNC bits. */ | ||
94 | u32 BERErrorCount; /* Number of erronous SYNC bits. */ | ||
95 | |||
96 | s32 MRC_SNR; /* dB */ | ||
97 | s32 MRC_InBandPwr; /* In band power in dBM */ | ||
98 | s32 MRC_RSSI; /* dBm */ | ||
99 | }; | ||
100 | |||
101 | u32 sms_to_bw_table[] = { | ||
102 | [BW_8_MHZ] = 8000000, | ||
103 | [BW_7_MHZ] = 7000000, | ||
104 | [BW_6_MHZ] = 6000000, | ||
105 | [BW_5_MHZ] = 5000000, | ||
106 | [BW_2_MHZ] = 2000000, | ||
107 | [BW_1_5_MHZ] = 1500000, | ||
108 | [BW_ISDBT_1SEG] = 6000000, | ||
109 | [BW_ISDBT_3SEG] = 6000000, | ||
110 | [BW_ISDBT_13SEG] = 6000000, | ||
111 | }; | ||
112 | |||
113 | u32 sms_to_guard_interval_table[] = { | ||
114 | [0] = GUARD_INTERVAL_1_32, | ||
115 | [1] = GUARD_INTERVAL_1_16, | ||
116 | [2] = GUARD_INTERVAL_1_8, | ||
117 | [3] = GUARD_INTERVAL_1_4, | ||
118 | }; | ||
119 | |||
120 | u32 sms_to_code_rate_table[] = { | ||
121 | [0] = FEC_1_2, | ||
122 | [1] = FEC_2_3, | ||
123 | [2] = FEC_3_4, | ||
124 | [3] = FEC_5_6, | ||
125 | [4] = FEC_7_8, | ||
126 | }; | ||
127 | |||
128 | |||
129 | u32 sms_to_hierarchy_table[] = { | ||
130 | [0] = HIERARCHY_NONE, | ||
131 | [1] = HIERARCHY_1, | ||
132 | [2] = HIERARCHY_2, | ||
133 | [3] = HIERARCHY_4, | ||
134 | }; | ||
135 | |||
136 | u32 sms_to_modulation_table[] = { | ||
137 | [0] = QPSK, | ||
138 | [1] = QAM_16, | ||
139 | [2] = QAM_64, | ||
140 | [3] = DQPSK, | ||
141 | }; | ||
142 | |||
64 | static void smsdvb_print_dvb_stats(struct SMSHOSTLIB_STATISTICS_ST *p) | 143 | static void smsdvb_print_dvb_stats(struct SMSHOSTLIB_STATISTICS_ST *p) |
65 | { | 144 | { |
66 | if (!(sms_dbg & 2)) | 145 | if (!(sms_dbg & 2)) |
@@ -244,93 +323,350 @@ static void sms_board_dvb3_event(struct smsdvb_client_t *client, | |||
244 | } | 323 | } |
245 | } | 324 | } |
246 | 325 | ||
247 | static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_EX_S *pReceptionData, | 326 | static void smsdvb_stats_not_ready(struct dvb_frontend *fe) |
327 | { | ||
328 | struct smsdvb_client_t *client = | ||
329 | container_of(fe, struct smsdvb_client_t, frontend); | ||
330 | struct smscore_device_t *coredev = client->coredev; | ||
331 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
332 | int i, n_layers; | ||
333 | |||
334 | switch (smscore_get_device_mode(coredev)) { | ||
335 | case DEVICE_MODE_ISDBT: | ||
336 | case DEVICE_MODE_ISDBT_BDA: | ||
337 | n_layers = 4; | ||
338 | default: | ||
339 | n_layers = 1; | ||
340 | } | ||
341 | |||
342 | /* Fill the length of each status counter */ | ||
343 | |||
344 | /* Only global stats */ | ||
345 | c->strength.len = 1; | ||
346 | c->cnr.len = 1; | ||
347 | |||
348 | /* Per-layer stats */ | ||
349 | c->post_bit_error.len = n_layers; | ||
350 | c->post_bit_count.len = n_layers; | ||
351 | c->block_error.len = n_layers; | ||
352 | c->block_count.len = n_layers; | ||
353 | |||
354 | /* Signal is always available */ | ||
355 | c->strength.stat[0].scale = FE_SCALE_RELATIVE; | ||
356 | c->strength.stat[0].uvalue = 0; | ||
357 | |||
358 | /* Put all of them at FE_SCALE_NOT_AVAILABLE */ | ||
359 | for (i = 0; i < n_layers; i++) { | ||
360 | c->cnr.stat[i].scale = FE_SCALE_NOT_AVAILABLE; | ||
361 | c->post_bit_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; | ||
362 | c->post_bit_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; | ||
363 | c->block_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE; | ||
364 | c->block_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE; | ||
365 | } | ||
366 | } | ||
367 | |||
368 | static inline int sms_to_mode(u32 mode) | ||
369 | { | ||
370 | switch (mode) { | ||
371 | case 2: | ||
372 | return TRANSMISSION_MODE_2K; | ||
373 | case 4: | ||
374 | return TRANSMISSION_MODE_4K; | ||
375 | case 8: | ||
376 | return TRANSMISSION_MODE_8K; | ||
377 | } | ||
378 | return TRANSMISSION_MODE_AUTO; | ||
379 | } | ||
380 | |||
381 | static inline int sms_to_status(u32 is_demod_locked, u32 is_rf_locked) | ||
382 | { | ||
383 | if (is_demod_locked) | ||
384 | return FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | | ||
385 | FE_HAS_SYNC | FE_HAS_LOCK; | ||
386 | |||
387 | if (is_rf_locked) | ||
388 | return FE_HAS_SIGNAL | FE_HAS_CARRIER; | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | |||
394 | #define convert_from_table(value, table, defval) ({ \ | ||
395 | u32 __ret; \ | ||
396 | if (value < ARRAY_SIZE(table)) \ | ||
397 | __ret = table[value]; \ | ||
398 | else \ | ||
399 | __ret = defval; \ | ||
400 | __ret; \ | ||
401 | }) | ||
402 | |||
403 | #define sms_to_bw(value) \ | ||
404 | convert_from_table(value, sms_to_bw_table, 0); | ||
405 | |||
406 | #define sms_to_guard_interval(value) \ | ||
407 | convert_from_table(value, sms_to_guard_interval_table, \ | ||
408 | GUARD_INTERVAL_AUTO); | ||
409 | |||
410 | #define sms_to_code_rate(value) \ | ||
411 | convert_from_table(value, sms_to_code_rate_table, \ | ||
412 | FEC_NONE); | ||
413 | |||
414 | #define sms_to_hierarchy(value) \ | ||
415 | convert_from_table(value, sms_to_hierarchy_table, \ | ||
416 | FEC_NONE); | ||
417 | |||
418 | #define sms_to_modulation(value) \ | ||
419 | convert_from_table(value, sms_to_modulation_table, \ | ||
420 | FEC_NONE); | ||
421 | |||
422 | static void smsdvb_update_tx_params(struct smsdvb_client_t *client, | ||
423 | struct TRANSMISSION_STATISTICS_S *p) | ||
424 | { | ||
425 | struct dvb_frontend *fe = &client->frontend; | ||
426 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
427 | |||
428 | c->frequency = p->Frequency; | ||
429 | client->fe_status = sms_to_status(p->IsDemodLocked, 0); | ||
430 | c->bandwidth_hz = sms_to_bw(p->Bandwidth); | ||
431 | c->transmission_mode = sms_to_mode(p->TransmissionMode); | ||
432 | c->guard_interval = sms_to_guard_interval(p->GuardInterval); | ||
433 | c->code_rate_HP = sms_to_code_rate(p->CodeRate); | ||
434 | c->code_rate_LP = sms_to_code_rate(p->LPCodeRate); | ||
435 | c->hierarchy = sms_to_hierarchy(p->Hierarchy); | ||
436 | c->modulation = sms_to_modulation(p->Constellation); | ||
437 | } | ||
438 | |||
439 | static void smsdvb_update_per_slices(struct smsdvb_client_t *client, | ||
440 | struct RECEPTION_STATISTICS_PER_SLICES_S *p) | ||
441 | { | ||
442 | struct dvb_frontend *fe = &client->frontend; | ||
443 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
444 | |||
445 | client->fe_status = sms_to_status(p->IsDemodLocked, p->IsRfLocked); | ||
446 | c->modulation = sms_to_modulation(p->constellation); | ||
447 | |||
448 | /* TS PER */ | ||
449 | client->last_per = c->block_error.stat[0].uvalue; | ||
450 | c->block_error.stat[0].scale = FE_SCALE_COUNTER; | ||
451 | c->block_count.stat[0].scale = FE_SCALE_COUNTER; | ||
452 | c->block_error.stat[0].uvalue += p->etsPackets; | ||
453 | c->block_count.stat[0].uvalue += p->etsPackets + p->tsPackets; | ||
454 | |||
455 | /* BER */ | ||
456 | c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; | ||
457 | c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; | ||
458 | c->post_bit_error.stat[0].uvalue += p->BERErrorCount; | ||
459 | c->post_bit_count.stat[0].uvalue += p->BERBitCount; | ||
460 | |||
461 | /* Legacy PER/BER */ | ||
462 | client->legacy_per = (p->etsPackets * 65535) / | ||
463 | (p->tsPackets + p->etsPackets); | ||
464 | |||
465 | /* Signal Strength, in DBm */ | ||
466 | c->strength.stat[0].uvalue = p->RSSI * 1000; | ||
467 | |||
468 | /* Carrier to Noise ratio, in DB */ | ||
469 | c->cnr.stat[0].scale = FE_SCALE_DECIBEL; | ||
470 | c->cnr.stat[0].svalue = p->snr * 1000; | ||
471 | } | ||
472 | |||
473 | static void smsdvb_update_dvb_stats(struct smsdvb_client_t *client, | ||
248 | struct SMSHOSTLIB_STATISTICS_ST *p) | 474 | struct SMSHOSTLIB_STATISTICS_ST *p) |
249 | { | 475 | { |
476 | struct dvb_frontend *fe = &client->frontend; | ||
477 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
478 | |||
250 | smsdvb_print_dvb_stats(p); | 479 | smsdvb_print_dvb_stats(p); |
251 | 480 | ||
481 | client->fe_status = sms_to_status(p->IsDemodLocked, p->IsRfLocked); | ||
482 | |||
483 | /* Update DVB modulation parameters */ | ||
484 | c->frequency = p->Frequency; | ||
485 | client->fe_status = sms_to_status(p->IsDemodLocked, 0); | ||
486 | c->bandwidth_hz = sms_to_bw(p->Bandwidth); | ||
487 | c->transmission_mode = sms_to_mode(p->TransmissionMode); | ||
488 | c->guard_interval = sms_to_guard_interval(p->GuardInterval); | ||
489 | c->code_rate_HP = sms_to_code_rate(p->CodeRate); | ||
490 | c->code_rate_LP = sms_to_code_rate(p->LPCodeRate); | ||
491 | c->hierarchy = sms_to_hierarchy(p->Hierarchy); | ||
492 | c->modulation = sms_to_modulation(p->Constellation); | ||
493 | |||
252 | /* update reception data */ | 494 | /* update reception data */ |
253 | pReceptionData->IsRfLocked = p->IsRfLocked; | 495 | c->lna = p->IsExternalLNAOn ? 1 : 0; |
254 | pReceptionData->IsDemodLocked = p->IsDemodLocked; | 496 | |
255 | pReceptionData->IsExternalLNAOn = p->IsExternalLNAOn; | 497 | /* Carrier to Noise ratio, in DB */ |
256 | pReceptionData->ModemState = p->ModemState; | 498 | c->cnr.stat[0].scale = FE_SCALE_DECIBEL; |
257 | pReceptionData->SNR = p->SNR; | 499 | c->cnr.stat[0].svalue = p->SNR * 1000; |
258 | pReceptionData->BER = p->BER; | 500 | |
259 | pReceptionData->BERErrorCount = p->BERErrorCount; | 501 | /* Signal Strength, in DBm */ |
260 | pReceptionData->BERBitCount = p->BERBitCount; | 502 | c->strength.stat[0].uvalue = p->RSSI * 1000; |
261 | pReceptionData->RSSI = p->RSSI; | 503 | |
262 | CORRECT_STAT_RSSI(*pReceptionData); | 504 | /* TS PER */ |
263 | pReceptionData->InBandPwr = p->InBandPwr; | 505 | client->last_per = c->block_error.stat[0].uvalue; |
264 | pReceptionData->CarrierOffset = p->CarrierOffset; | 506 | c->block_error.stat[0].scale = FE_SCALE_COUNTER; |
265 | pReceptionData->ErrorTSPackets = p->ErrorTSPackets; | 507 | c->block_count.stat[0].scale = FE_SCALE_COUNTER; |
266 | pReceptionData->TotalTSPackets = p->TotalTSPackets; | 508 | c->block_error.stat[0].uvalue += p->ErrorTSPackets; |
509 | c->block_count.stat[0].uvalue += p->TotalTSPackets; | ||
510 | |||
511 | /* BER */ | ||
512 | c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; | ||
513 | c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; | ||
514 | c->post_bit_error.stat[0].uvalue += p->BERErrorCount; | ||
515 | c->post_bit_count.stat[0].uvalue += p->BERBitCount; | ||
516 | |||
517 | /* Legacy PER/BER */ | ||
518 | client->legacy_ber = p->BER; | ||
267 | }; | 519 | }; |
268 | 520 | ||
269 | static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_EX_S *pReceptionData, | 521 | static void smsdvb_update_isdbt_stats(struct smsdvb_client_t *client, |
270 | struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) | 522 | struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p) |
271 | { | 523 | { |
524 | struct dvb_frontend *fe = &client->frontend; | ||
525 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
526 | struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST *lr; | ||
527 | int i, n_layers; | ||
528 | |||
272 | smsdvb_print_isdb_stats(p); | 529 | smsdvb_print_isdb_stats(p); |
273 | 530 | ||
531 | /* Update ISDB-T transmission parameters */ | ||
532 | c->frequency = p->Frequency; | ||
533 | client->fe_status = sms_to_status(p->IsDemodLocked, 0); | ||
534 | c->bandwidth_hz = sms_to_bw(p->Bandwidth); | ||
535 | c->transmission_mode = sms_to_mode(p->TransmissionMode); | ||
536 | c->guard_interval = sms_to_guard_interval(p->GuardInterval); | ||
537 | c->isdbt_partial_reception = p->PartialReception ? 1 : 0; | ||
538 | n_layers = p->NumOfLayers; | ||
539 | if (n_layers < 1) | ||
540 | n_layers = 1; | ||
541 | if (n_layers > 3) | ||
542 | n_layers = 3; | ||
543 | c->isdbt_layer_enabled = 0; | ||
544 | |||
274 | /* update reception data */ | 545 | /* update reception data */ |
275 | pReceptionData->IsRfLocked = p->IsRfLocked; | 546 | c->lna = p->IsExternalLNAOn ? 1 : 0; |
276 | pReceptionData->IsDemodLocked = p->IsDemodLocked; | ||
277 | pReceptionData->IsExternalLNAOn = p->IsExternalLNAOn; | ||
278 | pReceptionData->ModemState = p->ModemState; | ||
279 | pReceptionData->SNR = p->SNR; | ||
280 | pReceptionData->BER = p->LayerInfo[0].BER; | ||
281 | pReceptionData->BERErrorCount = p->LayerInfo[0].BERErrorCount; | ||
282 | pReceptionData->BERBitCount = p->LayerInfo[0].BERBitCount; | ||
283 | pReceptionData->RSSI = p->RSSI; | ||
284 | CORRECT_STAT_RSSI(*pReceptionData); | ||
285 | pReceptionData->InBandPwr = p->InBandPwr; | ||
286 | |||
287 | pReceptionData->CarrierOffset = p->CarrierOffset; | ||
288 | pReceptionData->ErrorTSPackets = p->LayerInfo[0].ErrorTSPackets; | ||
289 | pReceptionData->TotalTSPackets = p->LayerInfo[0].TotalTSPackets; | ||
290 | pReceptionData->MFER = 0; | ||
291 | 547 | ||
292 | /* TS PER */ | 548 | /* Carrier to Noise ratio, in DB */ |
293 | if ((p->LayerInfo[0].TotalTSPackets + | 549 | c->cnr.stat[0].scale = FE_SCALE_DECIBEL; |
294 | p->LayerInfo[0].ErrorTSPackets) > 0) { | 550 | c->cnr.stat[0].svalue = p->SNR * 1000; |
295 | pReceptionData->TS_PER = (p->LayerInfo[0].ErrorTSPackets | 551 | |
296 | * 100) / (p->LayerInfo[0].TotalTSPackets | 552 | /* Signal Strength, in DBm */ |
297 | + p->LayerInfo[0].ErrorTSPackets); | 553 | c->strength.stat[0].uvalue = p->RSSI * 1000; |
298 | } else { | 554 | |
299 | pReceptionData->TS_PER = 0; | 555 | client->last_per = c->block_error.stat[0].uvalue; |
556 | |||
557 | /* Clears global counters, as the code below will sum it again */ | ||
558 | c->block_error.stat[0].uvalue = 0; | ||
559 | c->block_count.stat[0].uvalue = 0; | ||
560 | c->post_bit_error.stat[0].uvalue = 0; | ||
561 | c->post_bit_count.stat[0].uvalue = 0; | ||
562 | |||
563 | for (i = 0; i < n_layers; i++) { | ||
564 | lr = &p->LayerInfo[i]; | ||
565 | |||
566 | /* Update per-layer transmission parameters */ | ||
567 | if (lr->NumberOfSegments > 0 && lr->NumberOfSegments < 13) { | ||
568 | c->isdbt_layer_enabled |= 1 << i; | ||
569 | c->layer[i].segment_count = lr->NumberOfSegments; | ||
570 | } else { | ||
571 | continue; | ||
572 | } | ||
573 | c->layer[i].modulation = sms_to_modulation(lr->Constellation); | ||
574 | |||
575 | /* TS PER */ | ||
576 | c->block_error.stat[i].scale = FE_SCALE_COUNTER; | ||
577 | c->block_count.stat[i].scale = FE_SCALE_COUNTER; | ||
578 | c->block_error.stat[i].uvalue += lr->ErrorTSPackets; | ||
579 | c->block_count.stat[i].uvalue += lr->TotalTSPackets; | ||
580 | |||
581 | /* Update global PER counter */ | ||
582 | c->block_error.stat[0].uvalue += lr->ErrorTSPackets; | ||
583 | c->block_count.stat[0].uvalue += lr->TotalTSPackets; | ||
584 | |||
585 | /* BER */ | ||
586 | c->post_bit_error.stat[i].scale = FE_SCALE_COUNTER; | ||
587 | c->post_bit_count.stat[i].scale = FE_SCALE_COUNTER; | ||
588 | c->post_bit_error.stat[i].uvalue += lr->BERErrorCount; | ||
589 | c->post_bit_count.stat[i].uvalue += lr->BERBitCount; | ||
590 | |||
591 | /* Update global BER counter */ | ||
592 | c->post_bit_error.stat[0].uvalue += lr->BERErrorCount; | ||
593 | c->post_bit_count.stat[0].uvalue += lr->BERBitCount; | ||
300 | } | 594 | } |
301 | } | 595 | } |
302 | 596 | ||
303 | static void smsdvb_update_isdbt_stats_ex(struct RECEPTION_STATISTICS_EX_S *pReceptionData, | 597 | static void smsdvb_update_isdbt_stats_ex(struct smsdvb_client_t *client, |
304 | struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p) | 598 | struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST *p) |
305 | { | 599 | { |
600 | struct dvb_frontend *fe = &client->frontend; | ||
601 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
602 | struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST *lr; | ||
603 | int i, n_layers; | ||
604 | |||
306 | smsdvb_print_isdb_stats_ex(p); | 605 | smsdvb_print_isdb_stats_ex(p); |
307 | 606 | ||
607 | /* Update ISDB-T transmission parameters */ | ||
608 | c->frequency = p->Frequency; | ||
609 | client->fe_status = sms_to_status(p->IsDemodLocked, 0); | ||
610 | c->bandwidth_hz = sms_to_bw(p->Bandwidth); | ||
611 | c->transmission_mode = sms_to_mode(p->TransmissionMode); | ||
612 | c->guard_interval = sms_to_guard_interval(p->GuardInterval); | ||
613 | c->isdbt_partial_reception = p->PartialReception ? 1 : 0; | ||
614 | n_layers = p->NumOfLayers; | ||
615 | if (n_layers < 1) | ||
616 | n_layers = 1; | ||
617 | if (n_layers > 3) | ||
618 | n_layers = 3; | ||
619 | c->isdbt_layer_enabled = 0; | ||
620 | |||
308 | /* update reception data */ | 621 | /* update reception data */ |
309 | pReceptionData->IsRfLocked = p->IsRfLocked; | 622 | c->lna = p->IsExternalLNAOn ? 1 : 0; |
310 | pReceptionData->IsDemodLocked = p->IsDemodLocked; | ||
311 | pReceptionData->IsExternalLNAOn = p->IsExternalLNAOn; | ||
312 | pReceptionData->ModemState = p->ModemState; | ||
313 | pReceptionData->SNR = p->SNR; | ||
314 | pReceptionData->BER = p->LayerInfo[0].BER; | ||
315 | pReceptionData->BERErrorCount = p->LayerInfo[0].BERErrorCount; | ||
316 | pReceptionData->BERBitCount = p->LayerInfo[0].BERBitCount; | ||
317 | pReceptionData->RSSI = p->RSSI; | ||
318 | CORRECT_STAT_RSSI(*pReceptionData); | ||
319 | pReceptionData->InBandPwr = p->InBandPwr; | ||
320 | |||
321 | pReceptionData->CarrierOffset = p->CarrierOffset; | ||
322 | pReceptionData->ErrorTSPackets = p->LayerInfo[0].ErrorTSPackets; | ||
323 | pReceptionData->TotalTSPackets = p->LayerInfo[0].TotalTSPackets; | ||
324 | pReceptionData->MFER = 0; | ||
325 | 623 | ||
326 | /* TS PER */ | 624 | /* Carrier to Noise ratio, in DB */ |
327 | if ((p->LayerInfo[0].TotalTSPackets + | 625 | c->cnr.stat[0].scale = FE_SCALE_DECIBEL; |
328 | p->LayerInfo[0].ErrorTSPackets) > 0) { | 626 | c->cnr.stat[0].svalue = p->SNR * 1000; |
329 | pReceptionData->TS_PER = (p->LayerInfo[0].ErrorTSPackets | 627 | |
330 | * 100) / (p->LayerInfo[0].TotalTSPackets | 628 | /* Signal Strength, in DBm */ |
331 | + p->LayerInfo[0].ErrorTSPackets); | 629 | c->strength.stat[0].uvalue = p->RSSI * 1000; |
332 | } else { | 630 | |
333 | pReceptionData->TS_PER = 0; | 631 | client->last_per = c->block_error.stat[0].uvalue; |
632 | |||
633 | /* Clears global counters, as the code below will sum it again */ | ||
634 | c->block_error.stat[0].uvalue = 0; | ||
635 | c->block_count.stat[0].uvalue = 0; | ||
636 | c->post_bit_error.stat[0].uvalue = 0; | ||
637 | c->post_bit_count.stat[0].uvalue = 0; | ||
638 | |||
639 | for (i = 0; i < n_layers; i++) { | ||
640 | lr = &p->LayerInfo[i]; | ||
641 | |||
642 | /* Update per-layer transmission parameters */ | ||
643 | if (lr->NumberOfSegments > 0 && lr->NumberOfSegments < 13) { | ||
644 | c->isdbt_layer_enabled |= 1 << i; | ||
645 | c->layer[i].segment_count = lr->NumberOfSegments; | ||
646 | } else { | ||
647 | continue; | ||
648 | } | ||
649 | c->layer[i].modulation = sms_to_modulation(lr->Constellation); | ||
650 | |||
651 | /* TS PER */ | ||
652 | c->block_error.stat[i].scale = FE_SCALE_COUNTER; | ||
653 | c->block_count.stat[i].scale = FE_SCALE_COUNTER; | ||
654 | c->block_error.stat[i].uvalue += lr->ErrorTSPackets; | ||
655 | c->block_count.stat[i].uvalue += lr->TotalTSPackets; | ||
656 | |||
657 | /* Update global PER counter */ | ||
658 | c->block_error.stat[0].uvalue += lr->ErrorTSPackets; | ||
659 | c->block_count.stat[0].uvalue += lr->TotalTSPackets; | ||
660 | |||
661 | /* BER */ | ||
662 | c->post_bit_error.stat[i].scale = FE_SCALE_COUNTER; | ||
663 | c->post_bit_count.stat[i].scale = FE_SCALE_COUNTER; | ||
664 | c->post_bit_error.stat[i].uvalue += lr->BERErrorCount; | ||
665 | c->post_bit_count.stat[i].uvalue += lr->BERBitCount; | ||
666 | |||
667 | /* Update global BER counter */ | ||
668 | c->post_bit_error.stat[0].uvalue += lr->BERErrorCount; | ||
669 | c->post_bit_count.stat[0].uvalue += lr->BERBitCount; | ||
334 | } | 670 | } |
335 | } | 671 | } |
336 | 672 | ||
@@ -339,13 +675,14 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) | |||
339 | struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; | 675 | struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; |
340 | struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p) | 676 | struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p) |
341 | + cb->offset); | 677 | + cb->offset); |
342 | u32 *pMsgData = (u32 *) phdr + 1; | 678 | void *p = phdr + 1; |
343 | /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/ | 679 | struct dvb_frontend *fe = &client->frontend; |
680 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
344 | bool is_status_update = false; | 681 | bool is_status_update = false; |
345 | 682 | ||
346 | switch (phdr->msgType) { | 683 | switch (phdr->msgType) { |
347 | case MSG_SMS_DVBT_BDA_DATA: | 684 | case MSG_SMS_DVBT_BDA_DATA: |
348 | dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1), | 685 | dvb_dmx_swfilter(&client->demux, p, |
349 | cb->size - sizeof(struct SmsMsgHdr_ST)); | 686 | cb->size - sizeof(struct SmsMsgHdr_ST)); |
350 | break; | 687 | break; |
351 | 688 | ||
@@ -355,166 +692,64 @@ static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) | |||
355 | break; | 692 | break; |
356 | 693 | ||
357 | case MSG_SMS_SIGNAL_DETECTED_IND: | 694 | case MSG_SMS_SIGNAL_DETECTED_IND: |
358 | client->sms_stat_dvb.TransmissionData.IsDemodLocked = true; | 695 | client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | |
696 | FE_HAS_VITERBI | FE_HAS_SYNC | | ||
697 | FE_HAS_LOCK; | ||
698 | |||
359 | is_status_update = true; | 699 | is_status_update = true; |
360 | break; | 700 | break; |
361 | 701 | ||
362 | case MSG_SMS_NO_SIGNAL_IND: | 702 | case MSG_SMS_NO_SIGNAL_IND: |
363 | client->sms_stat_dvb.TransmissionData.IsDemodLocked = false; | 703 | client->fe_status = 0; |
704 | |||
364 | is_status_update = true; | 705 | is_status_update = true; |
365 | break; | 706 | break; |
366 | 707 | ||
367 | case MSG_SMS_TRANSMISSION_IND: { | 708 | case MSG_SMS_TRANSMISSION_IND: |
368 | 709 | smsdvb_update_tx_params(client, p); | |
369 | pMsgData++; | ||
370 | memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData, | ||
371 | sizeof(struct TRANSMISSION_STATISTICS_S)); | ||
372 | 710 | ||
373 | #if 1 | ||
374 | /* | ||
375 | * FIXME: newer driver doesn't have those fixes | ||
376 | * Are those firmware-specific stuff? | ||
377 | */ | ||
378 | |||
379 | /* Mo need to correct guard interval | ||
380 | * (as opposed to old statistics message). | ||
381 | */ | ||
382 | CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData); | ||
383 | CORRECT_STAT_TRANSMISSON_MODE( | ||
384 | client->sms_stat_dvb.TransmissionData); | ||
385 | #endif | ||
386 | is_status_update = true; | 711 | is_status_update = true; |
387 | break; | 712 | break; |
388 | } | ||
389 | case MSG_SMS_HO_PER_SLICES_IND: { | ||
390 | struct RECEPTION_STATISTICS_EX_S *pReceptionData = | ||
391 | &client->sms_stat_dvb.ReceptionData; | ||
392 | struct SRVM_SIGNAL_STATUS_S SignalStatusData; | ||
393 | |||
394 | pMsgData++; | ||
395 | SignalStatusData.result = pMsgData[0]; | ||
396 | SignalStatusData.snr = pMsgData[1]; | ||
397 | SignalStatusData.inBandPower = (s32) pMsgData[2]; | ||
398 | SignalStatusData.tsPackets = pMsgData[3]; | ||
399 | SignalStatusData.etsPackets = pMsgData[4]; | ||
400 | SignalStatusData.constellation = pMsgData[5]; | ||
401 | SignalStatusData.hpCode = pMsgData[6]; | ||
402 | SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03; | ||
403 | SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03; | ||
404 | SignalStatusData.cellId = pMsgData[9] & 0xFFFF; | ||
405 | SignalStatusData.reason = pMsgData[10]; | ||
406 | SignalStatusData.requestId = pMsgData[11]; | ||
407 | pReceptionData->IsRfLocked = pMsgData[16]; | ||
408 | pReceptionData->IsDemodLocked = pMsgData[17]; | ||
409 | pReceptionData->ModemState = pMsgData[12]; | ||
410 | pReceptionData->SNR = pMsgData[1]; | ||
411 | pReceptionData->BER = pMsgData[13]; | ||
412 | pReceptionData->RSSI = pMsgData[14]; | ||
413 | CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData); | ||
414 | |||
415 | pReceptionData->InBandPwr = (s32) pMsgData[2]; | ||
416 | pReceptionData->CarrierOffset = (s32) pMsgData[15]; | ||
417 | pReceptionData->TotalTSPackets = pMsgData[3]; | ||
418 | pReceptionData->ErrorTSPackets = pMsgData[4]; | ||
419 | 713 | ||
420 | /* TS PER */ | 714 | case MSG_SMS_HO_PER_SLICES_IND: |
421 | if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets) | 715 | smsdvb_update_per_slices(client, p); |
422 | > 0) { | ||
423 | pReceptionData->TS_PER = (SignalStatusData.etsPackets | ||
424 | * 100) / (SignalStatusData.tsPackets | ||
425 | + SignalStatusData.etsPackets); | ||
426 | } else { | ||
427 | pReceptionData->TS_PER = 0; | ||
428 | } | ||
429 | |||
430 | pReceptionData->BERBitCount = pMsgData[18]; | ||
431 | pReceptionData->BERErrorCount = pMsgData[19]; | ||
432 | |||
433 | pReceptionData->MRC_SNR = pMsgData[20]; | ||
434 | pReceptionData->MRC_InBandPwr = pMsgData[21]; | ||
435 | pReceptionData->MRC_RSSI = pMsgData[22]; | ||
436 | 716 | ||
437 | is_status_update = true; | 717 | is_status_update = true; |
438 | break; | 718 | break; |
439 | } | ||
440 | case MSG_SMS_GET_STATISTICS_RES: { | ||
441 | union { | ||
442 | struct SMSHOSTLIB_STATISTICS_ISDBT_ST isdbt; | ||
443 | struct SmsMsgStatisticsInfo_ST dvb; | ||
444 | } *p = (void *) (phdr + 1); | ||
445 | struct RECEPTION_STATISTICS_EX_S *pReceptionData = | ||
446 | &client->sms_stat_dvb.ReceptionData; | ||
447 | |||
448 | is_status_update = true; | ||
449 | 719 | ||
720 | case MSG_SMS_GET_STATISTICS_RES: | ||
450 | switch (smscore_get_device_mode(client->coredev)) { | 721 | switch (smscore_get_device_mode(client->coredev)) { |
451 | case DEVICE_MODE_ISDBT: | 722 | case DEVICE_MODE_ISDBT: |
452 | case DEVICE_MODE_ISDBT_BDA: | 723 | case DEVICE_MODE_ISDBT_BDA: |
453 | smsdvb_update_isdbt_stats(pReceptionData, &p->isdbt); | 724 | smsdvb_update_isdbt_stats(client, p); |
454 | break; | 725 | break; |
455 | default: | 726 | default: |
456 | smsdvb_update_dvb_stats(pReceptionData, &p->dvb.Stat); | 727 | smsdvb_update_dvb_stats(client, p); |
457 | } | ||
458 | if (!pReceptionData->IsDemodLocked) { | ||
459 | pReceptionData->SNR = 0; | ||
460 | pReceptionData->BER = 0; | ||
461 | pReceptionData->BERErrorCount = 0; | ||
462 | pReceptionData->InBandPwr = 0; | ||
463 | pReceptionData->ErrorTSPackets = 0; | ||
464 | } | 728 | } |
465 | 729 | ||
730 | is_status_update = true; | ||
466 | break; | 731 | break; |
467 | } | ||
468 | case MSG_SMS_GET_STATISTICS_EX_RES: { | ||
469 | union { | ||
470 | struct SMSHOSTLIB_STATISTICS_ISDBT_EX_ST isdbt; | ||
471 | struct SMSHOSTLIB_STATISTICS_ST dvb; | ||
472 | } *p = (void *) (phdr + 1); | ||
473 | struct RECEPTION_STATISTICS_EX_S *pReceptionData = | ||
474 | &client->sms_stat_dvb.ReceptionData; | ||
475 | 732 | ||
733 | /* Only for ISDB-T */ | ||
734 | case MSG_SMS_GET_STATISTICS_EX_RES: | ||
735 | smsdvb_update_isdbt_stats_ex(client, p); | ||
476 | is_status_update = true; | 736 | is_status_update = true; |
477 | |||
478 | switch (smscore_get_device_mode(client->coredev)) { | ||
479 | case DEVICE_MODE_ISDBT: | ||
480 | case DEVICE_MODE_ISDBT_BDA: | ||
481 | smsdvb_update_isdbt_stats_ex(pReceptionData, &p->isdbt); | ||
482 | break; | ||
483 | default: | ||
484 | smsdvb_update_dvb_stats(pReceptionData, &p->dvb); | ||
485 | } | ||
486 | if (!pReceptionData->IsDemodLocked) { | ||
487 | pReceptionData->SNR = 0; | ||
488 | pReceptionData->BER = 0; | ||
489 | pReceptionData->BERErrorCount = 0; | ||
490 | pReceptionData->InBandPwr = 0; | ||
491 | pReceptionData->ErrorTSPackets = 0; | ||
492 | } | ||
493 | |||
494 | break; | 737 | break; |
495 | } | ||
496 | default: | 738 | default: |
497 | sms_info("message not handled"); | 739 | sms_info("message not handled"); |
498 | } | 740 | } |
499 | smscore_putbuffer(client->coredev, cb); | 741 | smscore_putbuffer(client->coredev, cb); |
500 | 742 | ||
501 | if (is_status_update) { | 743 | if (is_status_update) { |
502 | if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) { | 744 | if (client->fe_status == FE_HAS_LOCK) { |
503 | client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | ||
504 | | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | ||
505 | sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK); | 745 | sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK); |
506 | if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets | 746 | if (client->last_per == c->block_error.stat[0].uvalue) |
507 | == 0) | ||
508 | sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); | 747 | sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); |
509 | else | 748 | else |
510 | sms_board_dvb3_event(client, | 749 | sms_board_dvb3_event(client, DVB3_EVENT_UNC_ERR); |
511 | DVB3_EVENT_UNC_ERR); | ||
512 | |||
513 | } else { | 750 | } else { |
514 | if (client->sms_stat_dvb.ReceptionData.IsRfLocked) | 751 | smsdvb_stats_not_ready(fe); |
515 | client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER; | 752 | |
516 | else | ||
517 | client->fe_status = 0; | ||
518 | sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); | 753 | sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); |
519 | } | 754 | } |
520 | complete(&client->stats_done); | 755 | complete(&client->stats_done); |
@@ -612,13 +847,20 @@ static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) | |||
612 | Msg.msgFlags = 0; | 847 | Msg.msgFlags = 0; |
613 | Msg.msgLength = sizeof(Msg); | 848 | Msg.msgLength = sizeof(Msg); |
614 | 849 | ||
615 | /* | 850 | switch (smscore_get_device_mode(client->coredev)) { |
616 | * Check for firmware version, to avoid breaking for old cards | 851 | case DEVICE_MODE_ISDBT: |
617 | */ | 852 | case DEVICE_MODE_ISDBT_BDA: |
618 | if (client->coredev->fw_version >= 0x800) | 853 | /* |
619 | Msg.msgType = MSG_SMS_GET_STATISTICS_EX_REQ; | 854 | * Check for firmware version, to avoid breaking for old cards |
620 | else | 855 | */ |
856 | if (client->coredev->fw_version >= 0x800) | ||
857 | Msg.msgType = MSG_SMS_GET_STATISTICS_EX_REQ; | ||
858 | else | ||
859 | Msg.msgType = MSG_SMS_GET_STATISTICS_REQ; | ||
860 | break; | ||
861 | default: | ||
621 | Msg.msgType = MSG_SMS_GET_STATISTICS_REQ; | 862 | Msg.msgType = MSG_SMS_GET_STATISTICS_REQ; |
863 | } | ||
622 | 864 | ||
623 | rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), | 865 | rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), |
624 | &client->stats_done); | 866 | &client->stats_done); |
@@ -628,12 +870,12 @@ static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) | |||
628 | 870 | ||
629 | static inline int led_feedback(struct smsdvb_client_t *client) | 871 | static inline int led_feedback(struct smsdvb_client_t *client) |
630 | { | 872 | { |
631 | if (client->fe_status & FE_HAS_LOCK) | 873 | if (!(client->fe_status & FE_HAS_LOCK)) |
632 | return sms_board_led_feedback(client->coredev, | ||
633 | (client->sms_stat_dvb.ReceptionData.BER | ||
634 | == 0) ? SMS_LED_HI : SMS_LED_LO); | ||
635 | else | ||
636 | return sms_board_led_feedback(client->coredev, SMS_LED_OFF); | 874 | return sms_board_led_feedback(client->coredev, SMS_LED_OFF); |
875 | |||
876 | return sms_board_led_feedback(client->coredev, | ||
877 | (client->legacy_ber == 0) ? | ||
878 | SMS_LED_HI : SMS_LED_LO); | ||
637 | } | 879 | } |
638 | 880 | ||
639 | static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) | 881 | static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) |
@@ -655,11 +897,12 @@ static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) | |||
655 | { | 897 | { |
656 | int rc; | 898 | int rc; |
657 | struct smsdvb_client_t *client; | 899 | struct smsdvb_client_t *client; |
900 | |||
658 | client = container_of(fe, struct smsdvb_client_t, frontend); | 901 | client = container_of(fe, struct smsdvb_client_t, frontend); |
659 | 902 | ||
660 | rc = smsdvb_send_statistics_request(client); | 903 | rc = smsdvb_send_statistics_request(client); |
661 | 904 | ||
662 | *ber = client->sms_stat_dvb.ReceptionData.BER; | 905 | *ber = client->legacy_ber; |
663 | 906 | ||
664 | led_feedback(client); | 907 | led_feedback(client); |
665 | 908 | ||
@@ -668,21 +911,21 @@ static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) | |||
668 | 911 | ||
669 | static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | 912 | static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) |
670 | { | 913 | { |
914 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
671 | int rc; | 915 | int rc; |
672 | 916 | s32 power = (s32) c->strength.stat[0].uvalue; | |
673 | struct smsdvb_client_t *client; | 917 | struct smsdvb_client_t *client; |
918 | |||
674 | client = container_of(fe, struct smsdvb_client_t, frontend); | 919 | client = container_of(fe, struct smsdvb_client_t, frontend); |
675 | 920 | ||
676 | rc = smsdvb_send_statistics_request(client); | 921 | rc = smsdvb_send_statistics_request(client); |
677 | 922 | ||
678 | if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95) | 923 | if (power < -95) |
679 | *strength = 0; | 924 | *strength = 0; |
680 | else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29) | 925 | else if (power > -29) |
681 | *strength = 100; | 926 | *strength = 65535; |
682 | else | 927 | else |
683 | *strength = | 928 | *strength = (power + 95) * 65535 / 66; |
684 | (client->sms_stat_dvb.ReceptionData.InBandPwr | ||
685 | + 95) * 3 / 2; | ||
686 | 929 | ||
687 | led_feedback(client); | 930 | led_feedback(client); |
688 | 931 | ||
@@ -691,13 +934,16 @@ static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | |||
691 | 934 | ||
692 | static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) | 935 | static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) |
693 | { | 936 | { |
937 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
694 | int rc; | 938 | int rc; |
695 | struct smsdvb_client_t *client; | 939 | struct smsdvb_client_t *client; |
940 | |||
696 | client = container_of(fe, struct smsdvb_client_t, frontend); | 941 | client = container_of(fe, struct smsdvb_client_t, frontend); |
697 | 942 | ||
698 | rc = smsdvb_send_statistics_request(client); | 943 | rc = smsdvb_send_statistics_request(client); |
699 | 944 | ||
700 | *snr = client->sms_stat_dvb.ReceptionData.SNR; | 945 | /* Preferred scale for SNR with legacy API: 0.1 dB */ |
946 | *snr = c->cnr.stat[0].svalue / 100; | ||
701 | 947 | ||
702 | led_feedback(client); | 948 | led_feedback(client); |
703 | 949 | ||
@@ -707,12 +953,14 @@ static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) | |||
707 | static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | 953 | static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
708 | { | 954 | { |
709 | int rc; | 955 | int rc; |
956 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
710 | struct smsdvb_client_t *client; | 957 | struct smsdvb_client_t *client; |
958 | |||
711 | client = container_of(fe, struct smsdvb_client_t, frontend); | 959 | client = container_of(fe, struct smsdvb_client_t, frontend); |
712 | 960 | ||
713 | rc = smsdvb_send_statistics_request(client); | 961 | rc = smsdvb_send_statistics_request(client); |
714 | 962 | ||
715 | *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets; | 963 | *ucblocks = c->block_error.stat[0].uvalue; |
716 | 964 | ||
717 | led_feedback(client); | 965 | led_feedback(client); |
718 | 966 | ||
@@ -743,7 +991,7 @@ static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe) | |||
743 | 991 | ||
744 | int ret; | 992 | int ret; |
745 | 993 | ||
746 | client->fe_status = FE_HAS_SIGNAL; | 994 | client->fe_status = 0; |
747 | client->event_fe_state = -1; | 995 | client->event_fe_state = -1; |
748 | client->event_unc_state = -1; | 996 | client->event_unc_state = -1; |
749 | fe->dtv_property_cache.delivery_system = SYS_DVBT; | 997 | fe->dtv_property_cache.delivery_system = SYS_DVBT; |
@@ -871,6 +1119,8 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe) | |||
871 | container_of(fe, struct smsdvb_client_t, frontend); | 1119 | container_of(fe, struct smsdvb_client_t, frontend); |
872 | struct smscore_device_t *coredev = client->coredev; | 1120 | struct smscore_device_t *coredev = client->coredev; |
873 | 1121 | ||
1122 | smsdvb_stats_not_ready(fe); | ||
1123 | |||
874 | switch (smscore_get_device_mode(coredev)) { | 1124 | switch (smscore_get_device_mode(coredev)) { |
875 | case DEVICE_MODE_DVBT: | 1125 | case DEVICE_MODE_DVBT: |
876 | case DEVICE_MODE_DVBT_BDA: | 1126 | case DEVICE_MODE_DVBT_BDA: |
@@ -883,150 +1133,10 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe) | |||
883 | } | 1133 | } |
884 | } | 1134 | } |
885 | 1135 | ||
886 | static int smsdvb_get_frontend_dvb(struct dvb_frontend *fe) | 1136 | /* Nothing to do here, as stats are automatically updated */ |
887 | { | ||
888 | struct dtv_frontend_properties *fep = &fe->dtv_property_cache; | ||
889 | struct smsdvb_client_t *client = | ||
890 | container_of(fe, struct smsdvb_client_t, frontend); | ||
891 | struct TRANSMISSION_STATISTICS_S *td = | ||
892 | &client->sms_stat_dvb.TransmissionData; | ||
893 | |||
894 | fep->frequency = td->Frequency; | ||
895 | |||
896 | switch (td->Bandwidth) { | ||
897 | case 6: | ||
898 | fep->bandwidth_hz = 6000000; | ||
899 | break; | ||
900 | case 7: | ||
901 | fep->bandwidth_hz = 7000000; | ||
902 | break; | ||
903 | case 8: | ||
904 | fep->bandwidth_hz = 8000000; | ||
905 | break; | ||
906 | } | ||
907 | |||
908 | switch (td->TransmissionMode) { | ||
909 | case 2: | ||
910 | fep->transmission_mode = TRANSMISSION_MODE_2K; | ||
911 | break; | ||
912 | case 8: | ||
913 | fep->transmission_mode = TRANSMISSION_MODE_8K; | ||
914 | } | ||
915 | |||
916 | switch (td->GuardInterval) { | ||
917 | case 0: | ||
918 | fep->guard_interval = GUARD_INTERVAL_1_32; | ||
919 | break; | ||
920 | case 1: | ||
921 | fep->guard_interval = GUARD_INTERVAL_1_16; | ||
922 | break; | ||
923 | case 2: | ||
924 | fep->guard_interval = GUARD_INTERVAL_1_8; | ||
925 | break; | ||
926 | case 3: | ||
927 | fep->guard_interval = GUARD_INTERVAL_1_4; | ||
928 | break; | ||
929 | } | ||
930 | |||
931 | switch (td->CodeRate) { | ||
932 | case 0: | ||
933 | fep->code_rate_HP = FEC_1_2; | ||
934 | break; | ||
935 | case 1: | ||
936 | fep->code_rate_HP = FEC_2_3; | ||
937 | break; | ||
938 | case 2: | ||
939 | fep->code_rate_HP = FEC_3_4; | ||
940 | break; | ||
941 | case 3: | ||
942 | fep->code_rate_HP = FEC_5_6; | ||
943 | break; | ||
944 | case 4: | ||
945 | fep->code_rate_HP = FEC_7_8; | ||
946 | break; | ||
947 | } | ||
948 | |||
949 | switch (td->LPCodeRate) { | ||
950 | case 0: | ||
951 | fep->code_rate_LP = FEC_1_2; | ||
952 | break; | ||
953 | case 1: | ||
954 | fep->code_rate_LP = FEC_2_3; | ||
955 | break; | ||
956 | case 2: | ||
957 | fep->code_rate_LP = FEC_3_4; | ||
958 | break; | ||
959 | case 3: | ||
960 | fep->code_rate_LP = FEC_5_6; | ||
961 | break; | ||
962 | case 4: | ||
963 | fep->code_rate_LP = FEC_7_8; | ||
964 | break; | ||
965 | } | ||
966 | |||
967 | switch (td->Constellation) { | ||
968 | case 0: | ||
969 | fep->modulation = QPSK; | ||
970 | break; | ||
971 | case 1: | ||
972 | fep->modulation = QAM_16; | ||
973 | break; | ||
974 | case 2: | ||
975 | fep->modulation = QAM_64; | ||
976 | break; | ||
977 | } | ||
978 | |||
979 | switch (td->Hierarchy) { | ||
980 | case 0: | ||
981 | fep->hierarchy = HIERARCHY_NONE; | ||
982 | break; | ||
983 | case 1: | ||
984 | fep->hierarchy = HIERARCHY_1; | ||
985 | break; | ||
986 | case 2: | ||
987 | fep->hierarchy = HIERARCHY_2; | ||
988 | break; | ||
989 | case 3: | ||
990 | fep->hierarchy = HIERARCHY_4; | ||
991 | break; | ||
992 | } | ||
993 | |||
994 | fep->inversion = INVERSION_AUTO; | ||
995 | |||
996 | return 0; | ||
997 | } | ||
998 | |||
999 | static int smsdvb_get_frontend_isdb(struct dvb_frontend *fe) | ||
1000 | { | ||
1001 | struct dtv_frontend_properties *fep = &fe->dtv_property_cache; | ||
1002 | struct smsdvb_client_t *client = | ||
1003 | container_of(fe, struct smsdvb_client_t, frontend); | ||
1004 | struct TRANSMISSION_STATISTICS_S *td = | ||
1005 | &client->sms_stat_dvb.TransmissionData; | ||
1006 | |||
1007 | fep->frequency = td->Frequency; | ||
1008 | fep->bandwidth_hz = 6000000; | ||
1009 | /* todo: retrive the other parameters */ | ||
1010 | |||
1011 | return 0; | ||
1012 | } | ||
1013 | |||
1014 | static int smsdvb_get_frontend(struct dvb_frontend *fe) | 1137 | static int smsdvb_get_frontend(struct dvb_frontend *fe) |
1015 | { | 1138 | { |
1016 | struct smsdvb_client_t *client = | 1139 | return 0; |
1017 | container_of(fe, struct smsdvb_client_t, frontend); | ||
1018 | struct smscore_device_t *coredev = client->coredev; | ||
1019 | |||
1020 | switch (smscore_get_device_mode(coredev)) { | ||
1021 | case DEVICE_MODE_DVBT: | ||
1022 | case DEVICE_MODE_DVBT_BDA: | ||
1023 | return smsdvb_get_frontend_dvb(fe); | ||
1024 | case DEVICE_MODE_ISDBT: | ||
1025 | case DEVICE_MODE_ISDBT_BDA: | ||
1026 | return smsdvb_get_frontend_isdb(fe); | ||
1027 | default: | ||
1028 | return -EINVAL; | ||
1029 | } | ||
1030 | } | 1140 | } |
1031 | 1141 | ||
1032 | static int smsdvb_init(struct dvb_frontend *fe) | 1142 | static int smsdvb_init(struct dvb_frontend *fe) |