| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Fujitu mb86a20s ISDB-T/ISDB-Tsb Module driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2010-2013 Mauro Carvalho Chehab |
|---|
| 5 | 6 | * Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com> |
|---|
| 6 | | - * |
|---|
| 7 | | - * This program is free software; you can redistribute it and/or |
|---|
| 8 | | - * modify it under the terms of the GNU General Public License as |
|---|
| 9 | | - * published by the Free Software Foundation version 2. |
|---|
| 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 GNU |
|---|
| 14 | | - * General Public License for more details. |
|---|
| 15 | 7 | */ |
|---|
| 16 | 8 | |
|---|
| 17 | 9 | #include <linux/kernel.h> |
|---|
| .. | .. |
|---|
| 525 | 517 | * Estimates the bit rate using the per-segment bit rate given by |
|---|
| 526 | 518 | * ABNT/NBR 15601 spec (table 4). |
|---|
| 527 | 519 | */ |
|---|
| 528 | | -static u32 isdbt_rate[3][5][4] = { |
|---|
| 520 | +static const u32 isdbt_rate[3][5][4] = { |
|---|
| 529 | 521 | { /* DQPSK/QPSK */ |
|---|
| 530 | 522 | { 280850, 312060, 330420, 340430 }, /* 1/2 */ |
|---|
| 531 | 523 | { 374470, 416080, 440560, 453910 }, /* 2/3 */ |
|---|
| .. | .. |
|---|
| 547 | 539 | } |
|---|
| 548 | 540 | }; |
|---|
| 549 | 541 | |
|---|
| 550 | | -static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer, |
|---|
| 551 | | - u32 modulation, u32 forward_error_correction, |
|---|
| 552 | | - u32 guard_interval, |
|---|
| 553 | | - u32 segment) |
|---|
| 542 | +static u32 isdbt_layer_min_bitrate(struct dtv_frontend_properties *c, |
|---|
| 543 | + u32 layer) |
|---|
| 554 | 544 | { |
|---|
| 555 | | - struct mb86a20s_state *state = fe->demodulator_priv; |
|---|
| 556 | | - u32 rate; |
|---|
| 557 | 545 | int mod, fec, guard; |
|---|
| 558 | 546 | |
|---|
| 559 | 547 | /* |
|---|
| .. | .. |
|---|
| 561 | 549 | * to consider the lowest bit rate, to avoid taking too long time |
|---|
| 562 | 550 | * to get BER. |
|---|
| 563 | 551 | */ |
|---|
| 564 | | - switch (modulation) { |
|---|
| 552 | + switch (c->layer[layer].modulation) { |
|---|
| 565 | 553 | case DQPSK: |
|---|
| 566 | 554 | case QPSK: |
|---|
| 567 | 555 | default: |
|---|
| .. | .. |
|---|
| 575 | 563 | break; |
|---|
| 576 | 564 | } |
|---|
| 577 | 565 | |
|---|
| 578 | | - switch (forward_error_correction) { |
|---|
| 566 | + switch (c->layer[layer].fec) { |
|---|
| 579 | 567 | default: |
|---|
| 580 | 568 | case FEC_1_2: |
|---|
| 581 | 569 | case FEC_AUTO: |
|---|
| .. | .. |
|---|
| 595 | 583 | break; |
|---|
| 596 | 584 | } |
|---|
| 597 | 585 | |
|---|
| 598 | | - switch (guard_interval) { |
|---|
| 586 | + switch (c->guard_interval) { |
|---|
| 599 | 587 | default: |
|---|
| 600 | 588 | case GUARD_INTERVAL_1_4: |
|---|
| 601 | 589 | guard = 0; |
|---|
| .. | .. |
|---|
| 611 | 599 | break; |
|---|
| 612 | 600 | } |
|---|
| 613 | 601 | |
|---|
| 614 | | - /* Samples BER at BER_SAMPLING_RATE seconds */ |
|---|
| 615 | | - rate = isdbt_rate[mod][fec][guard] * segment * BER_SAMPLING_RATE; |
|---|
| 616 | | - |
|---|
| 617 | | - /* Avoids sampling too quickly or to overflow the register */ |
|---|
| 618 | | - if (rate < 256) |
|---|
| 619 | | - rate = 256; |
|---|
| 620 | | - else if (rate > (1 << 24) - 1) |
|---|
| 621 | | - rate = (1 << 24) - 1; |
|---|
| 622 | | - |
|---|
| 623 | | - dev_dbg(&state->i2c->dev, |
|---|
| 624 | | - "%s: layer %c bitrate: %d kbps; counter = %d (0x%06x)\n", |
|---|
| 625 | | - __func__, 'A' + layer, |
|---|
| 626 | | - segment * isdbt_rate[mod][fec][guard]/1000, |
|---|
| 627 | | - rate, rate); |
|---|
| 628 | | - |
|---|
| 629 | | - state->estimated_rate[layer] = rate; |
|---|
| 602 | + return isdbt_rate[mod][fec][guard] * c->layer[layer].segment_count; |
|---|
| 630 | 603 | } |
|---|
| 631 | 604 | |
|---|
| 632 | 605 | static int mb86a20s_get_frontend(struct dvb_frontend *fe) |
|---|
| 633 | 606 | { |
|---|
| 634 | 607 | struct mb86a20s_state *state = fe->demodulator_priv; |
|---|
| 635 | 608 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
|---|
| 636 | | - int layer, rc; |
|---|
| 609 | + int layer, rc, rate, counter; |
|---|
| 637 | 610 | |
|---|
| 638 | 611 | dev_dbg(&state->i2c->dev, "%s called.\n", __func__); |
|---|
| 639 | 612 | |
|---|
| .. | .. |
|---|
| 684 | 657 | dev_dbg(&state->i2c->dev, "%s: interleaving %d.\n", |
|---|
| 685 | 658 | __func__, rc); |
|---|
| 686 | 659 | c->layer[layer].interleaving = rc; |
|---|
| 687 | | - mb86a20s_layer_bitrate(fe, layer, c->layer[layer].modulation, |
|---|
| 688 | | - c->layer[layer].fec, |
|---|
| 689 | | - c->guard_interval, |
|---|
| 690 | | - c->layer[layer].segment_count); |
|---|
| 660 | + |
|---|
| 661 | + rate = isdbt_layer_min_bitrate(c, layer); |
|---|
| 662 | + counter = rate * BER_SAMPLING_RATE; |
|---|
| 663 | + |
|---|
| 664 | + /* Avoids sampling too quickly or to overflow the register */ |
|---|
| 665 | + if (counter < 256) |
|---|
| 666 | + counter = 256; |
|---|
| 667 | + else if (counter > (1 << 24) - 1) |
|---|
| 668 | + counter = (1 << 24) - 1; |
|---|
| 669 | + |
|---|
| 670 | + dev_dbg(&state->i2c->dev, |
|---|
| 671 | + "%s: layer %c bitrate: %d kbps; counter = %d (0x%06x)\n", |
|---|
| 672 | + __func__, 'A' + layer, rate / 1000, counter, counter); |
|---|
| 673 | + |
|---|
| 674 | + state->estimated_rate[layer] = counter; |
|---|
| 691 | 675 | } |
|---|
| 692 | 676 | |
|---|
| 693 | 677 | rc = mb86a20s_writereg(state, 0x6d, 0x84); |
|---|
| .. | .. |
|---|
| 2097 | 2081 | dev_info(&i2c->dev, "Detected a Fujitsu mb86a20s frontend\n"); |
|---|
| 2098 | 2082 | return &state->frontend; |
|---|
| 2099 | 2083 | } |
|---|
| 2100 | | -EXPORT_SYMBOL(mb86a20s_attach); |
|---|
| 2084 | +EXPORT_SYMBOL_GPL(mb86a20s_attach); |
|---|
| 2101 | 2085 | |
|---|
| 2102 | 2086 | static const struct dvb_frontend_ops mb86a20s_ops = { |
|---|
| 2103 | 2087 | .delsys = { SYS_ISDBT }, |
|---|