Manu Abraham wrote:
Johannes Stezenbach wrote:
IMHO:
MODCOD as it is defined in the spec is a field which
is part of the physical layer signalling. It is a lowlevel
encoding used to saved a bit in the PLHEADER, and
not what you should use in the tuning API.
Ok.
And we might provide MATYPE for informational purposes,
but decoding it is left to the application. You could
put the code to decode it into dvb-apps/lib/ somewhere.
Not yet reached there. Will do some utils as soon as it is finished.
Yeah, here I mixed up MATYPE (from BBHEADER) with MODCODE
(from PLSCODE). So assuming that the demo hw will give
you the MODCOD from PLSCODE in a register and you want
to query it via FE_GET_PARAMS, we should keep
decode_dvbs2_modcod() in dvb_frontend.
FE_GET_PARAMS will then return fec and modulation
instead of modcod.
Ok, ignore my just previous post.
We will need the SIS/MIS flag as well.
SIS/MIS (1 bit): describes whether there is a single input stream or
multiple input streams. If SIS/
MIS = multiple input stream, then the second byte is the input stream
identifier (ISI)
So we will need the Input Stream Identifier as well.
I was trying to understand why people did not understand what i was
trying to convey across (ie, wondering why people saying that they don't
understand how it works)
While thinking about this, Marcel gave a hint that really struck my mind.
In this patch (in this stage only), i am _not_ addressing the entire
devices/drivers that are present in the whole tree. In my previous
patch, i missed out the track and search callbacks.
The current patch incorporates the updates to tuning algorithms as well.
Andrew did say that a split would cause confusion to people, well i
thought the split would make it easier for people to read through. (I
hope he doesn't go to Tromso, to borrow that club .. ;-) )
Will go to the existing drivers, if this situation is found acceptable.
It doesn't make sense to make a giga patch and modify it again and again.
Track and Search Callbacks are used on devices that do have their own
tuning algorithms.
One requests Search to search for a frequency and Track tracks it down
for frontend lock loss etc and other events. These events can be private
to the driver itself in most cases as they are device specific itself.
(for example ST makes use of the derotator heavily for this. Other
vendors use different methods)
Search does it's own internal zigzag etc, based on feedback from the
device itself, rather than a blind swzigzag.
The advantage is that, this yields in a faster LOCK.
Again, thanks to all the people who helped to make it still better.
Maybe i missed out certain things too, but could not make it out as
there were so many patches and updates. Tried the best to check whether
i missed out anything.
Mauro, requested me that he be CC'd on the API patch as he finds no time
to go through the ML's . :-(
Changes,
- Split out info from Caps, as many were not happy with a huge caps struct.
In this case a FE_GET_DELSYS has to be called (to identify the delivery
system), before any operation on params, ie FE_GET_PARAMS/FE_SET_PARAMS
The delivery system info from FE_GET_DELSYS is used to identify what
delivery system is used in FE_GET/SET/PARAMS
- All new Frontend params now are prefixed dvbfe_
- Added the search/track callbacks for devices that do support tuning
algorithms
- Use a common callback for all Silicon Tuner callbacks (Thanks to
Andrew for the concept)
- Add SIS/MIS flag for DVB-S2 (Thanks to Johannes for taking the
discussion ahead)
- Add Input Stream identifier for DVB-S2 (Thanks to Johannes for taking
the discussion ahead)
Thanks,
Manu
------------------------------------------------------------------------
diff -Naurp multiproto5c.orig/linux/drivers/media/dvb/dvb-core/dvb_frontend.c multiproto5c/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
--- multiproto5c.orig/linux/drivers/media/dvb/dvb-core/dvb_frontend.c 2006-04-29 03:22:23.000000000 +0400
+++ multiproto5c/linux/drivers/media/dvb/dvb-core/dvb_frontend.c 2006-05-14 04:10:16.000000000 +0400
@@ -93,7 +93,11 @@ struct dvb_frontend_private {
/* thread/frontend values */
struct dvb_device *dvbdev;
+ /* Legacy datatype, superseded by dvbfe_params */
struct dvb_frontend_parameters parameters;
+ /* dvbfe_params supersedes, dvb_frontend_parameters */
+ struct dvbfe_params fe_params;
+ struct dvbfe_info fe_info;
struct dvb_fe_events events;
struct semaphore sem;
struct list_head list_head;
@@ -126,6 +130,58 @@ struct dvb_frontend_private {
static void dvb_frontend_wakeup(struct dvb_frontend *fe);
+struct modcod_table {
+ u32 dvbfe_modcod;
+ u32 dvbfe_modulation;
+ u32 dvbfe_fec;
+};
+
+static struct modcod_table dvbs2_modcod_lookup[] = {
+ { DVBFE_MODCOD_DUMMY_PLFRAME, DVBFE_MOD_UNKNOWN, DVBFE_FEC_UNKNOWN },
+ { DVBFE_MODCOD_QPSK_1_4, DVBFE_MOD_QPSK, DVBFE_FEC_1_4 },
+ { DVBFE_MODCOD_QPSK_1_3, DVBFE_MOD_QPSK, DVBFE_FEC_1_3 },
+ { DVBFE_MODCOD_QPSK_2_5, DVBFE_MOD_QPSK, DVBFE_FEC_2_5 },
+ { DVBFE_MODCOD_QPSK_1_2, DVBFE_MOD_QPSK, DVBFE_FEC_1_2 },
+ { DVBFE_MODCOD_QPSK_3_5, DVBFE_MOD_QPSK, DVBFE_FEC_3_5 },
+ { DVBFE_MODCOD_QPSK_2_3, DVBFE_MOD_QPSK, DVBFE_FEC_2_3 },
+ { DVBFE_MODCOD_QPSK_3_4, DVBFE_MOD_QPSK, DVBFE_FEC_3_4 },
+ { DVBFE_MODCOD_QPSK_4_5, DVBFE_MOD_QPSK, DVBFE_FEC_4_5 },
+ { DVBFE_MODCOD_QPSK_5_6, DVBFE_MOD_QPSK, DVBFE_FEC_5_6 },
+ { DVBFE_MODCOD_QPSK_8_9, DVBFE_MOD_QPSK, DVBFE_FEC_8_9 },
+ { DVBFE_MODCOD_QPSK_9_10, DVBFE_MOD_QPSK, DVBFE_FEC_9_10 },
+ { DVBFE_MODCOD_8PSK_3_5, DVBFE_MOD_8PSK, DVBFE_FEC_3_5 },
+ { DVBFE_MODCOD_8PSK_2_3, DVBFE_MOD_8PSK, DVBFE_FEC_2_3 },
+ { DVBFE_MODCOD_8PSK_3_4, DVBFE_MOD_8PSK, DVBFE_FEC_3_4 },
+ { DVBFE_MODCOD_8PSK_5_6, DVBFE_MOD_8PSK, DVBFE_FEC_5_6 },
+ { DVBFE_MODCOD_8PSK_8_9, DVBFE_MOD_8PSK, DVBFE_FEC_8_9 },
+ { DVBFE_MODCOD_8PSK_9_10, DVBFE_MOD_8PSK, DVBFE_FEC_9_10 },
+ { DVBFE_MODCOD_16APSK_2_3, DVBFE_MOD_16APSK, DVBFE_FEC_2_3 },
+ { DVBFE_MODCOD_16APSK_3_4, DVBFE_MOD_16APSK, DVBFE_FEC_3_4 },
+ { DVBFE_MODCOD_16APSK_4_5, DVBFE_MOD_16APSK, DVBFE_FEC_4_5 },
+ { DVBFE_MODCOD_16APSK_5_6, DVBFE_MOD_16APSK, DVBFE_FEC_5_6 },
+ { DVBFE_MODCOD_16APSK_8_9, DVBFE_MOD_16APSK, DVBFE_FEC_8_9 },
+ { DVBFE_MODCOD_16APSK_9_10, DVBFE_MOD_16APSK, DVBFE_FEC_9_10 },
+ { DVBFE_MODCOD_32APSK_3_4, DVBFE_MOD_32APSK, DVBFE_FEC_3_4 },
+ { DVBFE_MODCOD_32APSK_4_5, DVBFE_MOD_32APSK, DVBFE_FEC_4_5 },
+ { DVBFE_MODCOD_32APSK_5_6, DVBFE_MOD_32APSK, DVBFE_FEC_5_6 },
+ { DVBFE_MODCOD_32APSK_8_9, DVBFE_MOD_32APSK, DVBFE_FEC_8_9 },
+ { DVBFE_MODCOD_32APSK_9_10, DVBFE_MOD_32APSK, DVBFE_FEC_9_10 },
+ { DVBFE_MODCOD_RESERVED_1, DVBFE_MOD_UNKNOWN, DVBFE_FEC_UNKNOWN },
+ { DVBFE_MODCOD_BPSK_1_3, DVBFE_MOD_BPSK, DVBFE_FEC_1_3 },
+ { DVBFE_MODCOD_BPSK_1_4, DVBFE_MOD_BPSK, DVBFE_FEC_1_4 },
+ { DVBFE_MODCOD_RESERVED_2, DVBFE_MOD_UNKNOWN, DVBFE_FEC_UNKNOWN }
+};
+
+void decode_dvbs2_modcod(u32 dvbfe_modcod,
+ enum dvbfe_modulation *modulation,
+ enum dvbfe_fec *fec)
+{
+ BUG_ON(dvbfe_modcod >= ARRAY_SIZE(dvbs2_modcod_lookup));
+ *modulation = dvbs2_modcod_lookup[dvbfe_modcod].dvbfe_modulation;
+ *fec = dvbs2_modcod_lookup[dvbfe_modcod].dvbfe_fec;
+}
+EXPORT_SYMBOL(decode_dvbs2_modcod);
+
static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
{
struct dvb_frontend_private *fepriv = fe->frontend_priv;
@@ -508,7 +564,10 @@ static int dvb_frontend_thread(void *dat
unsigned long timeout;
char name [15];
fe_status_t s;
+ /* Legacy datatype */
struct dvb_frontend_parameters *params;
+ /* Superseded datatype */
+ struct dvbfe_params *fe_params = &fepriv->fe_params;
dprintk("%s\n", __FUNCTION__);
@@ -558,6 +617,20 @@ static int dvb_frontend_thread(void *dat
}
fepriv->reinitialise = 0;
}
+ /* These callbacks do exist for devices that do have their
+ * own tuning algorithms!
+ *
+ * If we don't have search, we don't have track either. But,
+ * being paranoid, we check whether both of them exists.
+ *
+ * In this case the demod/tuner does zigzag internally based
+ * on information from the device itself rather than using a
+ * simple and blind swzigzag.
+ */
+ if (fe->ops->search)
+ fe->ops->search(fe, fe_params);
+ if (fe->ops->track)
+ fe->ops->track(fe, fe_params);
/* do an iteration of the tuning loop */
if (fe->ops->tune) {
diff -Naurp multiproto5c.orig/linux/drivers/media/dvb/dvb-core/dvb_frontend.h multiproto5c/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
--- multiproto5c.orig/linux/drivers/media/dvb/dvb-core/dvb_frontend.h 2006-04-29 03:22:23.000000000 +0400
+++ multiproto5c/linux/drivers/media/dvb/dvb-core/dvb_frontend.h 2006-05-14 03:26:01.000000000 +0400
@@ -61,6 +61,61 @@ struct dvb_tuner_info {
u32 bandwidth_step;
};
+enum dvbfe_modcod {
+ DVBFE_MODCOD_DUMMY_PLFRAME = 0,
+ DVBFE_MODCOD_QPSK_1_4,
+ DVBFE_MODCOD_QPSK_1_3,
+ DVBFE_MODCOD_QPSK_2_5,
+ DVBFE_MODCOD_QPSK_1_2,
+ DVBFE_MODCOD_QPSK_3_5,
+ DVBFE_MODCOD_QPSK_2_3,
+ DVBFE_MODCOD_QPSK_3_4,
+ DVBFE_MODCOD_QPSK_4_5,
+ DVBFE_MODCOD_QPSK_5_6,
+ DVBFE_MODCOD_QPSK_8_9,
+ DVBFE_MODCOD_QPSK_9_10,
+ DVBFE_MODCOD_8PSK_3_5,
+ DVBFE_MODCOD_8PSK_2_3,
+ DVBFE_MODCOD_8PSK_3_4,
+ DVBFE_MODCOD_8PSK_5_6,
+ DVBFE_MODCOD_8PSK_8_9,
+ DVBFE_MODCOD_8PSK_9_10,
+ DVBFE_MODCOD_16APSK_2_3,
+ DVBFE_MODCOD_16APSK_3_4,
+ DVBFE_MODCOD_16APSK_4_5,
+ DVBFE_MODCOD_16APSK_5_6,
+ DVBFE_MODCOD_16APSK_8_9,
+ DVBFE_MODCOD_16APSK_9_10,
+ DVBFE_MODCOD_32APSK_3_4,
+ DVBFE_MODCOD_32APSK_4_5,
+ DVBFE_MODCOD_32APSK_5_6,
+ DVBFE_MODCOD_32APSK_8_9,
+ DVBFE_MODCOD_32APSK_9_10,
+ DVBFE_MODCOD_RESERVED_1,
+ DVBFE_MODCOD_BPSK_1_3,
+ DVBFE_MODCOD_BPSK_1_4,
+ DVBFE_MODCOD_RESERVED_2
+};
+
+enum tuner_param {
+ DVBFE_TUNER_FREQUENCY = (1 << 0),
+ DVBFE_TUNER_TUNERSTEP = (1 << 1),
+ DVBFE_TUNER_IFFREQ = (1 << 2),
+ DVBFE_TUNER_BANDWIDTH = (1 << 3),
+ DVBFE_TUNER_REFERENCE_CLK = (1 << 4),
+ DVBFE_TUNER_IQSENSE = (1 << 5),
+ DVBFE_TUNER_DUMMY = (1 << 31)
+};
+
+struct tuner_state {
+ u32 frequency;
+ u32 tunerstep;
+ u32 ifreq;
+ u32 bandwidth;
+ u32 iqsense;
+ s32 reference_clk;
+};
+
struct dvb_tuner_ops {
struct dvb_tuner_info info;
@@ -83,8 +138,8 @@ struct dvb_tuner_ops {
/** These are provided seperately from set_params in order to facilitate silicon
* tuners which require sophisticated tuning loops, controlling each parameter seperately. */
- int (*set_frequency)(struct dvb_frontend *fe, u32 frequency);
- int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
+ int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
+ int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
};
struct dvb_frontend_ops {
@@ -125,6 +180,19 @@ struct dvb_frontend_ops {
int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
+ /* These callbacks are based on the supeseded IOCTL's */
+ int (*set_params)(struct dvb_frontend *fe, struct dvbfe_params *fe_params);
+ int (*get_params)(struct dvb_frontend *fe, struct dvbfe_params *fe_params);
+ int (*get_info)(struct dvb_frontend *fe, struct dvbfe_info *fe_info);
+ int (*get_events)(struct dvb_frontend *fe, struct dvbfe_events *fe_events);
+ int (*get_delsys)(struct dvb_frontend *fe, enum dvbfe_delsys);
+
+ /* These callbacks are for devices that implement their own
+ * tuning algorithms, rather than a simple swzigzag
+ */
+ int (*search)(struct dvb_frontend *fe, struct dvbfe_params *fe_params);
+ int (*track)(struct dvb_frontend *fe, struct dvbfe_params *fe_params);
+
struct dvb_tuner_ops tuner_ops;
};
@@ -158,4 +226,8 @@ extern void dvb_frontend_reinitialise(st
extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
+extern void decode_dvbs2_modcod(u32 modcod,
+ enum dvbfe_modulation *modulation,
+ enum dvbfe_fec *fec);
+
#endif
diff -Naurp multiproto5c.orig/linux/include/linux/dvb/frontend.h multiproto5c/linux/include/linux/dvb/frontend.h
--- multiproto5c.orig/linux/include/linux/dvb/frontend.h 2006-04-29 03:22:23.000000000 +0400
+++ multiproto5c/linux/include/linux/dvb/frontend.h 2006-05-14 03:14:37.000000000 +0400
@@ -274,4 +274,379 @@ struct dvb_frontend_event {
#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */
+/*
+ * References:
+ * DVB-S : EN 300 421
+ * DVB-S2: EN 300 307, TR 102 376, EN 301 210
+ * DVB-C : EN 300 429
+ * DVB-T : EN 300 744
+ * DVB-H : EN 300 304
+ * ATSC : A/53A
+ */
+
+/*
+ * Delivery Systems
+ * needs to set/queried for multistandard frontends
+ */
+enum dvbfe_delsys {
+ DVBFE_DELSYS_DVBS = (1 << 0),
+ DVBFE_DELSYS_DSS = (1 << 1),
+ DVBFE_DELSYS_DVBS2 = (1 << 2),
+ DVBFE_DELSYS_DVBC = (1 << 3),
+ DVBFE_DELSYS_DVBT = (1 << 4),
+ DVBFE_DELSYS_DVBH = (1 << 5),
+ DVBFE_DELSYS_ATSC = (1 << 6),
+ DVBFE_DELSYS_DUMMY = (1 << 31)
+};
+#define DVBFE_GET_DELSYS _IOR('o', 82, enum dvbfe_delsys)
+
+/*
+ * Modulation types
+ */
+enum dvbfe_modulation {
+ DVBFE_MOD_IGNORE = (0 << 0),
+ DVBFE_MOD_UNKNOWN = (1 << 0),
+ DVBFE_MOD_BPSK = (1 << 1),
+ DVBFE_MOD_QPSK = (1 << 2),
+ DVBFE_MOD_OQPSK = (1 << 3),
+ DVBFE_MOD_8PSK = (1 << 4),
+ DVBFE_MOD_16APSK = (1 << 5),
+ DVBFE_MOD_32APSK = (1 << 6),
+ DVBFE_MOD_QAM16 = (1 << 7),
+ DVBFE_MOD_QAM32 = (1 << 8),
+ DVBFE_MOD_QAM64 = (1 << 9),
+ DVBFE_MOD_QAM128 = (1 << 10),
+ DVBFE_MOD_QAM256 = (1 << 11),
+ DVBFE_MOD_QAM512 = (1 << 12),
+ DVBFE_MOD_QAM1024 = (1 << 13),
+ DVBFE_MOD_QAMAUTO = (1 << 14),
+ DVBFE_MOD_OFDM = (1 << 15),
+ DVBFE_MOD_COFDM = (1 << 16),
+ DVBFE_MOD_VSB8 = (1 << 17),
+ DVBFE_MOD_VSB16 = (1 << 18),
+ DVBFE_MOD_AUTO = (1 << 30),
+ DVBFE_MOD_DUMMY = (1 << 31)
+};
+
+/*
+ * FEC (Forward Error Correction) / Puncture Rate
+ * Reed Solomon Error Correction, an implementation
+ * can be found at http://rscode.sourceforge.net
+ */
+enum dvbfe_fec {
+ DVBFE_FEC_IGNORE = (0 << 0),
+ DVBFE_FEC_UNKNOWN = (1 << 0),
+ DVBFE_FEC_1_4 = (1 << 1),
+ DVBFE_FEC_1_3 = (1 << 2),
+ DVBFE_FEC_2_5 = (1 << 3),
+ DVBFE_FEC_1_2 = (1 << 4),
+ DVBFE_FEC_3_5 = (1 << 5),
+ DVBFE_FEC_2_3 = (1 << 6),
+ DVBFE_FEC_3_4 = (1 << 7),
+ DVBFE_FEC_4_5 = (1 << 8),
+ DVBFE_FEC_5_6 = (1 << 9),
+ DVBFE_FEC_6_7 = (1 << 10),
+ DVBFE_FEC_7_8 = (1 << 11),
+ DVBFE_FEC_8_9 = (1 << 12),
+ DVBFE_FEC_9_10 = (1 << 13),
+ DVBFE_FEC_AUTO = (1 << 30),
+ DVBFE_FEC_DUMMY = (1 << 31)
+};
+
+/*
+ * Frontend Inversion (I/Q Swap)
+ */
+enum dvbfe_iqswap {
+ DVBFE_IQSWAP_IGNORE = (0 << 0),
+ DVBFE_IQSWAP_OFF = (1 << 1),
+ DVBFE_IQSWAP_ON = (1 << 2),
+ DVBFE_IQSWAP_AUTO = (1 << 30),
+ DVBFE_IQSWAP_DUMMY = (1 << 31)
+};
+
+/*
+ * DVB-S parameters
+ */
+struct dvbs_params {
+ __u32 symbol_rate;
+
+ enum dvbfe_modulation modulation;
+ enum dvbfe_fec fec;
+};
+
+/*
+ * DSS parameters
+ */
+struct dss_params {
+ __u32 symbol_rate;
+
+ enum dvbfe_modulation modulation;
+ enum dvbfe_fec fec;
+};
+
+/*
+ * Optional Backwards Compatible Mode
+ * NOTE: Applies to DVB-S2 only
+ */
+enum dvbfe_obc_mode {
+ DVBFE_OBC_IGNORE = (0 << 0),
+ DVBFE_OBC_OFF = (1 << 0),
+ DVBFE_OBC_ON = (1 << 1),
+ DVBFE_OBC_DUMMY = (1 << 31)
+};
+
+/*
+ * Input Stream Flag
+ * NOTE: Applies to DVB-S2 only
+ */
+enum dvbfe_sismis_flag {
+ DVBFE_SISMIS_IGNORE = (0 << 0),
+ DVBFE_SISMIS_SINGLE = (1 << 0),
+ DVBFE_SISMIS_MULTIPLE = (1 << 1),
+ DVBFE_SISMIS_DUMMY = (1 << 31)
+};
+
+/*
+ * Rolloff Rate (Nyquist Filter Rolloff)
+ * NOTE: DVB-S has a fixed Rolloff rate of 0.5
+ * DVB-S2 has rates of 0.20, 0.25, 0.35
+ * Values are x100
+ */
+enum dvbfe_rolloff {
+ DVBFE_ROLLOFF_35 = (0 << 0),
+ DVBFE_ROLLOFF_25 = (1 << 0),
+ DVBFE_ROLLOFF_20 = (1 << 1),
+ DVBFE_ROLLOFF_5 = (1 << 2),
+ DVBFE_ROLLOFF_DUMMY = (1 << 31)
+};
+
+/*
+ * DVB-S2 parameters
+ */
+struct dvbs2_params {
+ __u32 symbol_rate;
+
+ enum dvbfe_modulation modulation;
+ enum dvbfe_fec fec;
+ enum dvbfe_obc_mode obc_mode;
+