@@ -1004,8 +1004,8 @@
*/
/* Legacy */
if (fe->legacy) {
- if ((fepriv->state & FESTATE_LOSTLOCK) &&
- (fe->ops.info.caps & FE_CAN_RECOVER) &&
+ if ((fepriv->state & FESTATE_LOSTLOCK) &&
+ (fe->ops.info.caps & FE_CAN_RECOVER) &&
(fepriv->max_drift == 0)) {
dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK);
@@ -1487,6 +1487,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;
@@ -1502,6 +1509,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);
@@ -1645,7 +1663,7 @@
break;
}
- memcpy(&fepriv->parameters, parg, sizeof (struct dvb_frontend_parameters));
+ memcpy(&fepriv->parameters, parg, sizeof (struct dvb_frontend_parameters));
memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings));
memcpy(&fetunesettings.parameters, parg, sizeof (struct dvb_frontend_parameters));
@@ -72,7 +72,7 @@
unsigned int audmode;
u64 std;
};
-
+
enum dvbfe_modcod {
DVBFE_MODCOD_DUMMY_PLFRAME = 0,
DVBFE_MODCOD_QPSK_1_4,
@@ -250,6 +250,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);
@@ -304,6 +305,9 @@
enum dvbfe_search (*search)(struct dvb_frontend *fe, struct dvbfe_params *fe_params);
int (*track)(struct dvb_frontend *fe, struct dvbfe_params *fe_params, int *delay);
+ 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;
};
@@ -1225,6 +1225,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;
@@ -2039,6 +2062,26 @@
.type = FE_QPSK, /* with old API */
},
+ .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,
@@ -2059,6 +2102,9 @@
.read_signal_strength = stb0899_read_signal_strength,
.read_status = stb0899_read_status,
.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,
@@ -645,4 +645,118 @@
};
#define DVBFE_GET_EVENT _IOR('o', 86, struct dvbfe_event)
+/* 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_*/