diff -r 421de709288e linux/drivers/media/dvb/dvb-core/dvb_frontend.c --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c Wed Mar 18 23:42:34 2009 +0400 +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c Wed Mar 25 01:22:31 2009 +0400 -1607,6 +1607,13 @@ break; } + case FE_STATISTICS_CAPS: { + struct fecap_statistics *stats_cap = parg; + memcpy(stats_cap, &fe->ops.statistics_caps, sizeof (struct fecap_statistics)); + err = 0; + break; + } + case FE_READ_STATUS: { fe_status_t* status = parg; -1622,6 +1629,17 @@ err = fe->ops.read_status(fe, status); break; } + + case FE_SIGNAL_LEVEL: + if (fe->ops.read_level) + err = fe->ops.read_level(fe, (__u32 *) parg); + break; + + case FE_SIGNAL_STATS: + if (fe->ops.read_stats) + err = fe->ops.read_stats(fe, (struct fesignal_stat *) parg); + break; + case FE_READ_BER: if (fe->ops.read_ber) err = fe->ops.read_ber(fe, (__u32*) parg); diff -r 421de709288e linux/drivers/media/dvb/dvb-core/dvb_frontend.h --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h Wed Mar 18 23:42:34 2009 +0400 +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h Wed Mar 25 01:22:31 2009 +0400 -252,6 +252,7 @@ struct dvb_frontend_ops { struct dvb_frontend_info info; + struct fecap_statistics statistics_caps; void (*release)(struct dvb_frontend* fe); void (*release_sec)(struct dvb_frontend* fe); -298,6 +299,9 @@ */ enum dvbfe_search (*search)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); int (*track)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); + + int (*read_level)(struct dvb_frontend *fe, u32 *signal); /* Raw AGC level */ + int (*read_stats)(struct dvb_frontend *fe, struct fesignal_stat *stat); struct dvb_tuner_ops tuner_ops; struct analog_demod_ops analog_ops; diff -r 421de709288e linux/drivers/media/dvb/frontends/stb0899_drv.c --- a/linux/drivers/media/dvb/frontends/stb0899_drv.c Wed Mar 18 23:42:34 2009 +0400 +++ b/linux/drivers/media/dvb/frontends/stb0899_drv.c Wed Mar 25 01:22:31 2009 +0400 -1226,6 +1226,29 @@ return 0; } +static int stb0899_read_level(struct dvb_frontend *fe, u32 *signal) +{ + /* TODO! */ + return 0; +} + +static int stb0899_read_stats(struct dvb_frontend *fe, struct fesignal_stat *stats) +{ + u16 snr, strength; + u32 ber; + + stb0899_read_snr(fe, &snr); + stb0899_read_signal_strength(fe, &strength); + stb0899_read_ber(fe, &ber); + + stats->quality = snr; + stats->strength = strength; + stats->error = ber; + stats->unc = 0; + + return 0; +} + static int stb0899_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) { struct stb0899_state *state = fe->demodulator_priv; -1917,6 +1940,27 @@ FE_CAN_QPSK }, + .statistics_caps = { + .quality = { + .params = FE_QUALITY_CNR, + .scale = FE_SCALE_dB, + .exponent = -4, + }, + + .strength = { + .params = FE_SCALE_dB, + .exponent = -4, + }, + + .error = { + .params = FE_ERROR_BER, + .exponent = 7, + }, + + .unc = FE_UNC_UNKNOWN, + + }, + .release = stb0899_release, .init = stb0899_init, .sleep = stb0899_sleep, -1934,6 +1978,9 @@ .read_snr = stb0899_read_snr, .read_signal_strength = stb0899_read_signal_strength, .read_ber = stb0899_read_ber, + + .read_level = stb0899_read_level, + .read_stats = stb0899_read_stats, .set_voltage = stb0899_set_voltage, .set_tone = stb0899_set_tone, diff -r 421de709288e linux/include/linux/dvb/frontend.h --- a/linux/include/linux/dvb/frontend.h Wed Mar 18 23:42:34 2009 +0400 +++ b/linux/include/linux/dvb/frontend.h Wed Mar 25 01:22:31 2009 +0400 -413,4 +413,120 @@ #define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */ + +/* Frontend General Statistics + * General parameters + * FE_*_UNKNOWN: + * Parameter is unknown to the frontend and doesn't really + * make any sense for an application. + * + * FE_*_RELATIVE: + * Parameter is relative on the basis of a ceil - floor basis + * Format is based on empirical test to determine + * the floor and ceiling values. This format is exactly the + * same format as the existing statistics implementation. + */ +enum fecap_quality_params { + FE_QUALITY_UNKNOWN = 0, + FE_QUALITY_SNR = (1 << 0), + FE_QUALITY_CNR = (1 << 1), + FE_QUALITY_EsNo = (1 << 2), + FE_QUALITY_EbNo = (1 << 3), + FE_QUALITY_RELATIVE = (1 << 31), +}; + +enum fecap_scale_params { + FE_SCALE_UNKNOWN = 0, + FE_SCALE_dB = (1 << 0), + FE_SCALE_RELATIVE = (1 << 31), +}; + +enum fecap_error_params { + FE_ERROR_UNKNOWN = 0, + FE_ERROR_BER = (1 << 0), + FE_ERROR_PER = (1 << 1), + FE_ERROR_RELATIVE = (1 << 31), +}; + +enum fecap_unc_params { + FE_UNC_UNKNOWN = 0, + FE_UNC_RELATIVE = (1 << 31), +}; + +/* General parameters + * width: + * Specifies the width of the field + * + * exponent: + * Specifies the multiplier for the respective field + * MSB:1bit indicates the signdness of the parameter + */ +struct fecap_quality { + enum fecap_quality_params params; + enum fecap_scale_params scale; + + __u32 width; + __s32 exponent; +}; + +struct fecap_strength { + enum fecap_scale_params params; + __u32 width; + __s32 exponent; +}; + +struct fecap_error { + enum fecap_error_params params; + __u32 width; + __s32 exponent; +}; + +struct fecap_statistics { + struct fecap_quality quality; + struct fecap_strength strength; + struct fecap_error error; + enum fecap_unc_params unc; +}; + +/* FE_STATISTICS_CAPS + * Userspace query for frontend signal statistics capabilities + */ +#define FE_STATISTICS_CAPS _IOR('o', 84, struct fecap_statistics) + + +/* FE_SIGNAL_LEVEL + * This system call provides a direct monitor of the signal, without + * passing through the relevant processing chains. In many cases, it + * is simply considered as direct AGC1 scaled values. This parameter + * can generally be used to position an antenna to while looking at + * a peak of this value. This parameter can be read back, even when + * a frontend LOCK has not been achieved. Some microntroller based + * demodulators do not provide a direct access to the AGC on the + * demodulator, hence this parameter will be Unsupported for such + * devices. + */ +#define FE_SIGNAL_LEVEL _IOR('o', 85, __u32) + + +struct fesignal_stat { + __u32 quality; + __u32 strength; + __u32 error; + __u32 unc; +}; + +/* FE_SIGNAL_STATS + * This system call provides a snapshot of all the receiver system + * at any given point of time. System signal statistics are always + * computed with respect to time and is best obtained the nearest + * to each of the individual parameters in a time domain. + * Signal statistics are assumed, "at any given instance of time". + * It is not possible to get a snapshot at the exact single instance + * and hence we look at the nearest instance, in the time domain. + * The statistics are described by the FE_STATISTICS_CAPS ioctl, + * ie. based on the device capabilities. + */ +#define FE_SIGNAL_STATS _IOR('o', 86, struct fesignal_stat) + + #endif /*_DVBFRONTEND_H_*/