[PATCH] Multi protocol support (stage #1)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux