diff options
author | Hans-Frieder Vogt <hfvogt@gmx.net> | 2012-04-07 09:34:34 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-05-14 12:19:31 -0400 |
commit | 47eafa5427c2da51f676e4c0b48bc851df8779f8 (patch) | |
tree | a8475fb21a9c6eb1a4051bd2a6477768833a566f /drivers/media/dvb | |
parent | 3234bd2f193936da6180a7dc6699a75191bc44d1 (diff) |
[media] af9033: implement ber and ucb functions
af9033: implement read_ber and read_ucblocks functions. Version 2 of patch that
reflects my findings on the behaviour of abort_cnt, err_cnt and bit_cnt:
- bit_cnt is always 0x2710 (10000)
- abort_cnt is between 0 and 0x2710
- err_cnt is between 0 and 640000 (= 0x2710 * 8 * 8)
in the current implementation BER is calculated as the number of bit errors per
processed bits, ignoring those bits that are already discarded and counted in
abort_cnt, i.e. UCBLOCKS.
Signed-off-by: Hans-Frieder Vogt <hfvogt@gmx.net>
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r-- | drivers/media/dvb/frontends/af9033.c | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/drivers/media/dvb/frontends/af9033.c b/drivers/media/dvb/frontends/af9033.c index 2cb1f8d6955e..a38998286260 100644 --- a/drivers/media/dvb/frontends/af9033.c +++ b/drivers/media/dvb/frontends/af9033.c | |||
@@ -29,6 +29,10 @@ struct af9033_state { | |||
29 | u32 bandwidth_hz; | 29 | u32 bandwidth_hz; |
30 | bool ts_mode_parallel; | 30 | bool ts_mode_parallel; |
31 | bool ts_mode_serial; | 31 | bool ts_mode_serial; |
32 | |||
33 | u32 ber; | ||
34 | u32 ucb; | ||
35 | unsigned long last_stat_check; | ||
32 | }; | 36 | }; |
33 | 37 | ||
34 | /* write multiple registers */ | 38 | /* write multiple registers */ |
@@ -772,16 +776,73 @@ err: | |||
772 | return ret; | 776 | return ret; |
773 | } | 777 | } |
774 | 778 | ||
779 | static int af9033_update_ch_stat(struct af9033_state *state) | ||
780 | { | ||
781 | int ret = 0; | ||
782 | u32 err_cnt, bit_cnt; | ||
783 | u16 abort_cnt; | ||
784 | u8 buf[7]; | ||
785 | |||
786 | /* only update data every half second */ | ||
787 | if (time_after(jiffies, state->last_stat_check + msecs_to_jiffies(500))) { | ||
788 | ret = af9033_rd_regs(state, 0x800032, buf, sizeof(buf)); | ||
789 | if (ret < 0) | ||
790 | goto err; | ||
791 | /* in 8 byte packets? */ | ||
792 | abort_cnt = (buf[1] << 8) + buf[0]; | ||
793 | /* in bits */ | ||
794 | err_cnt = (buf[4] << 16) + (buf[3] << 8) + buf[2]; | ||
795 | /* in 8 byte packets? always(?) 0x2710 = 10000 */ | ||
796 | bit_cnt = (buf[6] << 8) + buf[5]; | ||
797 | |||
798 | if (bit_cnt < abort_cnt) { | ||
799 | abort_cnt = 1000; | ||
800 | state->ber = 0xffffffff; | ||
801 | } else { | ||
802 | /* 8 byte packets, that have not been rejected already */ | ||
803 | bit_cnt -= (u32)abort_cnt; | ||
804 | if (bit_cnt == 0) { | ||
805 | state->ber = 0xffffffff; | ||
806 | } else { | ||
807 | err_cnt -= (u32)abort_cnt * 8 * 8; | ||
808 | bit_cnt *= 8 * 8; | ||
809 | state->ber = err_cnt * (0xffffffff / bit_cnt); | ||
810 | } | ||
811 | } | ||
812 | state->ucb += abort_cnt; | ||
813 | state->last_stat_check = jiffies; | ||
814 | } | ||
815 | |||
816 | return 0; | ||
817 | err: | ||
818 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
819 | return ret; | ||
820 | } | ||
821 | |||
775 | static int af9033_read_ber(struct dvb_frontend *fe, u32 *ber) | 822 | static int af9033_read_ber(struct dvb_frontend *fe, u32 *ber) |
776 | { | 823 | { |
777 | *ber = 0; | 824 | struct af9033_state *state = fe->demodulator_priv; |
825 | int ret; | ||
826 | |||
827 | ret = af9033_update_ch_stat(state); | ||
828 | if (ret < 0) | ||
829 | return ret; | ||
830 | |||
831 | *ber = state->ber; | ||
778 | 832 | ||
779 | return 0; | 833 | return 0; |
780 | } | 834 | } |
781 | 835 | ||
782 | static int af9033_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | 836 | static int af9033_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
783 | { | 837 | { |
784 | *ucblocks = 0; | 838 | struct af9033_state *state = fe->demodulator_priv; |
839 | int ret; | ||
840 | |||
841 | ret = af9033_update_ch_stat(state); | ||
842 | if (ret < 0) | ||
843 | return ret; | ||
844 | |||
845 | *ucblocks = state->ucb; | ||
785 | 846 | ||
786 | return 0; | 847 | return 0; |
787 | } | 848 | } |