Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Hans-Frieder Vogt and committed by
Mauro Carvalho Chehab
47eafa54 3234bd2f

+63 -2
+63 -2
drivers/media/dvb/frontends/af9033.c
··· 29 29 u32 bandwidth_hz; 30 30 bool ts_mode_parallel; 31 31 bool ts_mode_serial; 32 + 33 + u32 ber; 34 + u32 ucb; 35 + unsigned long last_stat_check; 32 36 }; 33 37 34 38 /* write multiple registers */ ··· 776 772 return ret; 777 773 } 778 774 775 + static int af9033_update_ch_stat(struct af9033_state *state) 776 + { 777 + int ret = 0; 778 + u32 err_cnt, bit_cnt; 779 + u16 abort_cnt; 780 + u8 buf[7]; 781 + 782 + /* only update data every half second */ 783 + if (time_after(jiffies, state->last_stat_check + msecs_to_jiffies(500))) { 784 + ret = af9033_rd_regs(state, 0x800032, buf, sizeof(buf)); 785 + if (ret < 0) 786 + goto err; 787 + /* in 8 byte packets? */ 788 + abort_cnt = (buf[1] << 8) + buf[0]; 789 + /* in bits */ 790 + err_cnt = (buf[4] << 16) + (buf[3] << 8) + buf[2]; 791 + /* in 8 byte packets? always(?) 0x2710 = 10000 */ 792 + bit_cnt = (buf[6] << 8) + buf[5]; 793 + 794 + if (bit_cnt < abort_cnt) { 795 + abort_cnt = 1000; 796 + state->ber = 0xffffffff; 797 + } else { 798 + /* 8 byte packets, that have not been rejected already */ 799 + bit_cnt -= (u32)abort_cnt; 800 + if (bit_cnt == 0) { 801 + state->ber = 0xffffffff; 802 + } else { 803 + err_cnt -= (u32)abort_cnt * 8 * 8; 804 + bit_cnt *= 8 * 8; 805 + state->ber = err_cnt * (0xffffffff / bit_cnt); 806 + } 807 + } 808 + state->ucb += abort_cnt; 809 + state->last_stat_check = jiffies; 810 + } 811 + 812 + return 0; 813 + err: 814 + pr_debug("%s: failed=%d\n", __func__, ret); 815 + return ret; 816 + } 817 + 779 818 static int af9033_read_ber(struct dvb_frontend *fe, u32 *ber) 780 819 { 781 - *ber = 0; 820 + struct af9033_state *state = fe->demodulator_priv; 821 + int ret; 822 + 823 + ret = af9033_update_ch_stat(state); 824 + if (ret < 0) 825 + return ret; 826 + 827 + *ber = state->ber; 782 828 783 829 return 0; 784 830 } 785 831 786 832 static int af9033_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 787 833 { 788 - *ucblocks = 0; 834 + struct af9033_state *state = fe->demodulator_priv; 835 + int ret; 836 + 837 + ret = af9033_update_ch_stat(state); 838 + if (ret < 0) 839 + return ret; 840 + 841 + *ucblocks = state->ucb; 789 842 790 843 return 0; 791 844 }