Hi,
After some rework landed up with a patch like this.
Currently
- the ATSC and DSS have not been included in the new implementation, to
make it look a bit simpler initially, if it is found okay we can add
them both in the same way.
- we use the FE_SET/GET_PARAMS instead of FE_SET/GET_FRONTEND in order
to maintain backward compatibility
- we now implement driver specific algorithms using the tune() callback
(we need the math functions)
- we set the delivery system on each tune call, such that each tune can
be on a different delivery system, rather having an additional IOCTL to
do FE_SET_PROTOCOL/DELIVERY etc. (we save on an additional IOCTL). A
requisite for demods with multiple delivery systems
Currently it has a dependency on the tuner_refactor_patch in
http://www.linuxtv.org/hg/~quincy/v4l-dvb-tuner-refactor
I have removed the demux related patches and the rest of the stuff (in
this stage) to make it a bit easier to comprehend.
diff -Naurp multi-proto-orig/linux/drivers/media/dvb/dvb-core/dvb_frontend.c multi-proto/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
--- multi-proto-orig/linux/drivers/media/dvb/dvb-core/dvb_frontend.c 2006-04-20 20:56:39.000000000 +0400
+++ multi-proto/linux/drivers/media/dvb/dvb-core/dvb_frontend.c 2006-04-22 03:34:44.000000000 +0400
@@ -94,6 +94,7 @@ struct dvb_frontend_private {
/* thread/frontend values */
struct dvb_device *dvbdev;
struct dvb_frontend_parameters parameters;
+ struct dvb_frontend_params params;
struct dvb_fe_events events;
struct semaphore sem;
struct list_head list_head;
@@ -508,7 +509,7 @@ static int dvb_frontend_thread(void *dat
unsigned long timeout;
char name [15];
fe_status_t s;
- struct dvb_frontend_parameters *params;
+ struct dvb_frontend_params *params;
dprintk("%s\n", __FUNCTION__);
@@ -564,7 +565,7 @@ static int dvb_frontend_thread(void *dat
/* have we been asked to retune? */
params = NULL;
if (fepriv->state & FESTATE_RETUNE) {
- params = &fepriv->parameters;
+ params = &fepriv->params;
fepriv->state = FESTATE_TUNED;
}
@@ -977,6 +978,39 @@ static int dvb_frontend_ioctl(struct ino
case FE_SET_FRONTEND_TUNE_MODE:
fepriv->tune_mode_flags = (unsigned long) parg;
break;
+
+ case FE_SET_PARAMS:
+ memcpy(&fepriv->params, parg,sizeof (struct dvb_frontend_params));
+ fepriv->state = FESTATE_RETUNE;
+ dvb_frontend_wakeup(fe);
+ dvb_frontend_add_event(fe, 0);
+ break;
+ /**
+ * Case #1
+ * If we make a call FE_GET_PARAMS with modcod=0x00
+ * and do a FE_GET_PARAMS, it will simply return
+ * all the available modulation and coding types used.
+ *
+ * Case #2
+ * calling FE_GET_PARAMS with the corresponding
+ * MODCOD type will return the parameters
+ * available for the corresponding MODCOD
+ */
+ case FE_GET_PARAMS:
+ if ((fepriv->params.caps.modulation.sat == 0) ||
+ (fepriv->params.caps.modulation.cab == 0) ||
+ (fepriv->params.caps.modulation.ter == 0)) {
+
+ if (fe->ops->get_modcod)
+ memcpy(parg, &fepriv->params, sizeof (struct dvb_frontend_params));
+ err = fe->ops->get_modcod(fe, (struct dvb_frontend_params*) parg);
+ } else {
+ if (fe->ops->get_params) {
+ memcpy(parg, &fepriv->params, sizeof (struct dvb_frontend_params));
+ err = fe->ops->get_params(fe, (struct dvb_frontend_params*) parg);
+ }
+ }
+ break;
};
up (&fepriv->sem);
diff -Naurp multi-proto-orig/linux/drivers/media/dvb/dvb-core/dvb_frontend.h multi-proto/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
--- multi-proto-orig/linux/drivers/media/dvb/dvb-core/dvb_frontend.h 2006-04-20 20:56:39.000000000 +0400
+++ multi-proto/linux/drivers/media/dvb/dvb-core/dvb_frontend.h 2006-04-22 03:28:18.000000000 +0400
@@ -98,7 +98,7 @@ struct dvb_frontend_ops {
/* if this is set, it overrides the default swzigzag */
int (*tune)(struct dvb_frontend* fe,
- struct dvb_frontend_parameters* params,
+ struct dvb_frontend_params* params,
unsigned int mode_flags,
int *delay,
fe_status_t *status);
@@ -124,6 +124,8 @@ struct dvb_frontend_ops {
int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg);
int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
+ int (*get_params)(struct dvb_frontend* fe, struct dvb_frontend_params* params);
+ int (*get_modcod)(struct dvb_frontend* fe, struct dvb_frontend_params* params);
struct dvb_tuner_ops tuner_ops;
};
diff -Naurp multi-proto-orig/linux/include/linux/dvb/frontend.h multi-proto/linux/include/linux/dvb/frontend.h
--- multi-proto-orig/linux/include/linux/dvb/frontend.h 2006-04-20 20:56:40.000000000 +0400
+++ multi-proto/linux/include/linux/dvb/frontend.h 2006-04-22 03:29:53.000000000 +0400
@@ -166,7 +166,8 @@ typedef enum fe_modulation {
typedef enum fe_transmit_mode {
TRANSMISSION_MODE_2K,
TRANSMISSION_MODE_8K,
- TRANSMISSION_MODE_AUTO
+ TRANSMISSION_MODE_AUTO,
+ TRANSMISSION_MODE_4K
} fe_transmit_mode_t;
typedef enum fe_bandwidth {
@@ -274,4 +275,171 @@ struct dvb_frontend_event {
#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */
+
+/**
+ * When delivery system is set to 0x00,
+ * we can query back, supported modcods
+ */
+typedef enum {
+ FE_DELSYS_DVB_S = 0x00000001,
+ FE_DELSYS_DVB_S2 = 0x00000002,
+ FE_DELSYS_DVB_C = 0x00000004,
+ FE_DELSYS_DVB_T = 0x00000008,
+ FE_DELSYS_DVB_H = 0x00000010,
+ FE_DELSYS_ATSC = 0x00000020,
+ FE_DELSYS_DSS = 0x00000040
+} fe_delsys_t;
+
+typedef enum {
+ FE_TRANSPORT = 0x00000001,
+ FE_GENERIC_PACKET,
+ FE_GENERIC_CONTINUOUS,
+ FE_RESERVED,
+} fe_matype_t;
+
+/**
+ * Satellite frontend capabilities
+ */
+typedef enum {
+ MOD_DUMMY_PLFRAME = 0x00000000,
+ MOD_QPSK_1_4 = 0x00000001,
+ MOD_QPSK_1_3 = 0x00000002,
+ MOD_QPSK_2_5 = 0x00000004,
+ MOD_QPSK_1_2 = 0x00000008,
+ MOD_QPSK_3_5 = 0x00000010,
+ MOD_QPSK_2_3 = 0x00000020,
+ MOD_QPSK_3_4 = 0x00000040,
+ MOD_QPSK_4_5 = 0x00000080,
+ MOD_QPSK_5_6 = 0x00000100,
+ MOD_QPSK_8_9 = 0x00000200,
+ MOD_QPSK_9_10 = 0x00000400,
+ MOD_8PSK_3_5 = 0x00000800,
+ MOD_8PSK_2_3 = 0x00001000,
+ MOD_8PSK_3_4 = 0x00002000,
+ MOD_8PSK_5_6 = 0x00004000,
+ MOD_8PSK_8_9 = 0x00008000,
+ MOD_8PSK_9_10 = 0x00010000,
+ MOD_16APSK_2_3 = 0x00020000,
+ MOD_16APSK_3_4 = 0x00040000,
+ MOD_16APSK_4_5 = 0x00080000,
+ MOD_16APSK_5_6 = 0x00100000,
+ MOD_16APSK_8_9 = 0x00200000,
+ MOD_16APSK_9_10 = 0x00400000,
+ MOD_32APSK_3_4 = 0x00800000,
+ MOD_32APSK_4_5 = 0x01000000,
+ MOD_32APSK_5_6 = 0x02000000,
+ MOD_32APSK_8_9 = 0x04000000,
+ MOD_32APSK_9_10 = 0x08000000,
+ MOD_RESERVED_1 = 0x10000000,
+ MOD_BPSK_1_3 = 0x20000000,
+ MOD_BPSK_1_4 = 0x40000000,
+ MOD_RESERVED_2 = 0x80000000
+} sat_modcod_t;
+
+/**
+ * Satellite frontend parameters
+ */
+struct sat_params {
+ __u32 symbol_rate;
+
+ fe_delsys_t delivery;
+ sat_modcod_t modcod;
+ fe_matype_t matype;
+};
+
+/**
+ * Cable frontend capabilities
+ */
+typedef enum {
+ MOD_QAM_16 = 0x00000001,
+ MOD_QAM_32 = 0x00000002,
+ MOD_QAM_64 = 0x00000004,
+ MOD_QAM_128 = 0x00000008,
+ MOD_QAM_256 = 0x00000010
+} cab_modcod_t;
+
+/**
+ * Cable frontend parameters
+ */
+struct cab_params {
+ __u32 symbol_rate;
+
+ fe_delsys_t delivery;
+ fe_code_rate_t fec_inner;
+};
+
+typedef enum fe_mpefec {
+ MPE_FEC_OFF = 0x00000000,
+ MPE_FEC_ON,
+} fe_mpefec_t;
+
+typedef enum fe_timeslicing {
+ TIMESLICING_OFF = 0x00000000,
+ TIMESLICING_ON,
+} fe_timeslicing_t;
+
+typedef enum fe_interleaver {
+ FE_INTERLEAVER_NATIVE = 0x00000000,
+ FE_INTERLEAVER_INDEPTH,
+} fe_interleaver_t;
+
+/**
+ * Terrestrial frontend capabilities
+ */
+typedef enum ter_modcod {
+ MOD_COFDM = 0x00000001
+} ter_modcod_t;
+
+/**
+ * Terrestrial frontend parameters
+ */
+struct ter_params {
+ fe_bandwidth_t bandwidth;
+ fe_code_rate_t code_rate_HP;
+ fe_code_rate_t code_rate_LP;
+ fe_modulation_t constellation;
+ fe_transmit_mode_t transmission_mode;
+ fe_guard_interval_t guard_interval;
+ fe_hierarchy_t hierarchy_info;
+ fe_interleaver_t interleaver;
+ fe_mpefec_t mpefec_indicator;
+ fe_timeslicing_t timeslicing_indicator;
+};
+
+
+struct fe_cap {
+ fe_delsys_t delivery;
+ union {
+ sat_modcod_t sat;
+ cab_modcod_t cab;
+ ter_modcod_t ter;
+ } modulation;
+};
+
+struct dvb_frontend_params {
+ __u32 frequency;
+ fe_spectral_inversion_t inversion;
+ struct fe_cap caps;
+
+ union {
+ struct sat_params sat;
+ struct cab_params cab;
+ struct ter_params ter;
+ } delsys;
+};
+
+#define FE_SET_PARAMS _IOW('o', 81, struct dvb_frontend_params)
+/**
+ * Case #1
+ * If we make a call FE_GET_PARAMS with modcod=0x00
+ * and do a FE_GET_PARAMS, it will simply return
+ * all the available modulation and coding types used.
+ *
+ * Case #2
+ * calling FE_GET_PARAMS with the corresponding
+ * MODCOD type will return the parameters
+ * available for the corresponding MODCOD
+ */
+#define FE_GET_PARAMS _IOWR('o', 82, struct dvb_frontend_params)
+
#endif /*_DVBFRONTEND_H_*/
_______________________________________________
linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb