Hi All,
Revised patch again.
Changelog:
#1) typedef's are bad (typedef's for structs are considered evil at
kernel, makes object's opaque)
#2) consistency issues (tried to make it as consistent as possible)
#3) unified callback's (have a simple get_params, now, advantage future
systems might define more things, but still the same callback can be
used in that case too)
#4) multi tuner support (same demod can have multiple delivery systems,
each tune might be on a different delivery system)
#5) split out each parameter, such there is more space in future (fec
and modulation separated out)
#6) added in all delivery systems now, hoping that it might make things
clear.
Thanks for all the previous feedback, awaiting comments again.
Thanks,
Manu
diff -Naurp multi-proto-orig/linux/drivers/media/dvb/dvb-core/dvb_frontend.c multi-proto2/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-proto2/linux/drivers/media/dvb/dvb-core/dvb_frontend.c 2006-04-25 03:46:55.000000000 +0400
@@ -94,6 +94,8 @@ struct dvb_frontend_private {
/* thread/frontend values */
struct dvb_device *dvbdev;
struct dvb_frontend_parameters parameters;
+ struct dvb_frontend_params params;
+ struct dvb_frontend_cap caps;
struct dvb_fe_events events;
struct semaphore sem;
struct list_head list_head;
@@ -124,6 +126,62 @@ struct dvb_frontend_private {
unsigned int check_wrapped;
};
+struct modcod_table dvbs2_modcod_lookup[] = {
+ { MOD_QPSK_1_4, FE_MOD_QPSK, FE_FECRATE_1_4 },
+ { MOD_QPSK_1_3, FE_MOD_QPSK, FE_FECRATE_1_3 },
+ { MOD_QPSK_2_5, FE_MOD_QPSK, FE_FECRATE_2_5 },
+ { MOD_QPSK_1_2, FE_MOD_QPSK, FE_FECRATE_1_2 },
+ { MOD_QPSK_3_5, FE_MOD_QPSK, FE_FECRATE_3_5 },
+ { MOD_QPSK_2_3, FE_MOD_QPSK, FE_FECRATE_2_3 },
+ { MOD_QPSK_3_4, FE_MOD_QPSK, FE_FECRATE_3_4 },
+ { MOD_QPSK_4_5, FE_MOD_QPSK, FE_FECRATE_4_5 },
+ { MOD_QPSK_5_6, FE_MOD_QPSK, FE_FECRATE_5_6 },
+ { MOD_QPSK_8_9, FE_MOD_QPSK, FE_FECRATE_8_9 },
+ { MOD_QPSK_9_10, FE_MOD_QPSK, FE_FECRATE_9_10 },
+ { MOD_8PSK_3_5, FE_MOD_8PSK, FE_FECRATE_3_5 },
+ { MOD_8PSK_2_3, FE_MOD_8PSK, FE_FECRATE_2_3 },
+ { MOD_8PSK_3_4, FE_MOD_8PSK, FE_FECRATE_3_4 },
+ { MOD_8PSK_5_6, FE_MOD_8PSK, FE_FECRATE_5_6 },
+ { MOD_8PSK_8_9, FE_MOD_8PSK, FE_FECRATE_8_9 },
+ { MOD_8PSK_9_10, FE_MOD_8PSK, FE_FECRATE_9_10 },
+ { MOD_16APSK_2_3, FE_MOD_16APSK, FE_FECRATE_2_3 },
+ { MOD_16APSK_3_4, FE_MOD_16APSK, FE_FECRATE_3_4 },
+ { MOD_16APSK_4_5, FE_MOD_16APSK, FE_FECRATE_4_5 },
+ { MOD_16APSK_5_6, FE_MOD_16APSK, FE_FECRATE_5_6 },
+ { MOD_16APSK_8_9, FE_MOD_16APSK, FE_FECRATE_8_9 },
+ { MOD_16APSK_9_10, FE_MOD_16APSK, FE_FECRATE_9_10 },
+ { MOD_32APSK_3_4, FE_MOD_32APSK, FE_FECRATE_3_4 },
+ { MOD_32APSK_4_5, FE_MOD_32APSK, FE_FECRATE_4_5 },
+ { MOD_32APSK_5_6, FE_MOD_32APSK, FE_FECRATE_5_6 },
+ { MOD_32APSK_8_9, FE_MOD_32APSK, FE_FECRATE_8_9 },
+ { MOD_32APSK_9_10, FE_MOD_32APSK, FE_FECRATE_9_10 },
+ { MOD_DUMMY_PLFRAME, FE_MOD_NONE, FE_FECRATE_NONE },
+};
+
+int decode_dvbs2_modcod(struct dvb_frontend *fe, enum fe_modcod modcod)
+{
+ int i;
+
+ struct modcod_table *table;
+ struct dvb_frontend_private *fepriv = fe->frontend_priv;
+ struct dvb_frontend_params *params = &fepriv->params;
+
+ if (params->delivery & FE_DELSYS_DVBS2) {
+ for (i = 0, table = dvbs2_modcod_lookup;
+ i < ARRAY_SIZE(dvbs2_modcod_lookup);
+ i++, table++) {
+
+ if (table->modcod == modcod) {
+ params->delsys.dvbs2.modulation = table->modulation;
+ params->delsys.dvbs2.fecrate = table->fecrate;
+ }
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(decode_dvbs2_modcod);
+
static void dvb_frontend_wakeup(struct dvb_frontend *fe);
static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
@@ -508,7 +566,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 +622,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;
}
@@ -722,6 +780,7 @@ static int dvb_frontend_ioctl(struct ino
struct dvb_device *dvbdev = file->private_data;
struct dvb_frontend *fe = dvbdev->priv;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
+
int err = -EOPNOTSUPP;
dprintk ("%s\n", __FUNCTION__);
@@ -977,6 +1036,18 @@ 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:
+ if (fe->ops->set_params)
+ err = fe->ops->set_params(fe, (struct dvb_frontend_params*) parg);
+ break;
+
+ case FE_GET_PARAMS:
+ if (fe->ops->get_caps) {
+ memcpy(parg, &fepriv->caps, sizeof (struct dvb_frontend_cap));
+ err = fe->ops->get_caps(fe, (struct dvb_frontend_cap*) parg);
+ }
+ break;
};
up (&fepriv->sem);
diff -Naurp multi-proto-orig/linux/drivers/media/dvb/dvb-core/dvb_frontend.h multi-proto2/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-proto2/linux/drivers/media/dvb/dvb-core/dvb_frontend.h 2006-04-25 03:30:38.000000000 +0400
@@ -61,6 +61,12 @@ struct dvb_tuner_info {
u32 bandwidth_step;
};
+struct modcod_table {
+ u32 modcod;
+ u32 modulation;
+ u32 fecrate;
+};
+
struct dvb_tuner_ops {
struct dvb_tuner_info info;
@@ -98,7 +104,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);
@@ -125,6 +131,9 @@ 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);
+ int (*get_caps)(struct dvb_frontend* fe, struct dvb_frontend_cap* caps);
+ int (*set_params)(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-proto2/linux/include/linux/dvb/frontend.h
--- multi-proto-orig/linux/include/linux/dvb/frontend.h 2006-04-20 20:56:40.000000000 +0400
+++ multi-proto2/linux/include/linux/dvb/frontend.h 2006-04-25 03:47:10.000000000 +0400
@@ -274,4 +274,273 @@ struct dvb_frontend_event {
#define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */
+/**
+ * Supported delivery systems
+ * some frontends are capable of supporting
+ * multiple delivery systems
+ */
+enum fe_delsys {
+ FE_DELSYS_QUERY = 0x00000000,
+ FE_DELSYS_DVBS = 0x00000001,
+ FE_DELSYS_DVBS2 = 0x00000002,
+ FE_DELSYS_DSS = 0x00000004,
+ FE_DELSYS_DVBC = 0x00000008,
+ FE_DELSYS_DVBT = 0x00000010,
+ FE_DELSYS_DVBH = 0x00000020,
+ FE_DELSYS_ATSC = 0x00000040,
+ FE_DELSYS_AUTO = 0x10000000
+};
+
+enum fe_matype {
+ FE_MATYPE_QUERY = 0x00000000,
+ FE_TRANSPORT = 0x00000001,
+ FE_GENERIC_PACKET = 0x00000002,
+ FE_GENERIC_CONTINUOUS = 0x00000004,
+ FE_RESERVED = 0x00000008,
+ FE_MATYPE_AUTO = 0x10000000
+};
+
+enum fe_stream {
+ FE_STREAM_HP = 0x00000001,
+ FE_STREAM_LP = 0x00000002
+};
+
+/**
+ * Supported Modulation types
+ * Some frontends are capable of supporting
+ * mutiple modulation types
+ */
+enum fe_modulations {
+ FE_MOD_QUERY = 0x00000000,
+ FE_MOD_NONE = 0x00000001,
+ FE_MOD_BPSK = 0x00000002,
+ FE_MOD_QPSK = 0x00000004,
+ FE_MOD_8PSK = 0x00000008,
+ FE_MOD_16APSK = 0x00000010,
+ FE_MOD_32APSK = 0x00000020,
+ FE_MOD_QAM16 = 0x00000040,
+ FE_MOD_QAM32 = 0x00000080,
+ FE_MOD_QAM64 = 0x00000100,
+ FE_MOD_QAM128 = 0x00000200,
+ FE_MOD_QAM256 = 0x00000400,
+ FE_MOD_OFDM = 0x00000800,
+ FE_MOD_COFDM = 0x00001000,
+ FE_MOD_VSB8 = 0x00002000,
+ FE_MOD_VSB16 = 0x00004000,
+ FE_MOD_AUTO = 0x10000000
+};
+
+enum fe_fecrates {
+ FE_FECRATE_QUERY = 0x00000000,
+ FE_FECRATE_NONE = 0x00000001,
+ FE_FECRATE_1_4 = 0x00000002,
+ FE_FECRATE_1_3 = 0x00000004,
+ FE_FECRATE_2_5 = 0x00000008,
+ FE_FECRATE_1_2 = 0x00000010,
+ FE_FECRATE_3_5 = 0x00000020,
+ FE_FECRATE_2_3 = 0x00000040,
+ FE_FECRATE_3_4 = 0x00000080,
+ FE_FECRATE_4_5 = 0x00000100,
+ FE_FECRATE_5_6 = 0x00000200,
+ FE_FECRATE_6_7 = 0x00000400,
+ FE_FECRATE_7_8 = 0x00000800,
+ FE_FECRATE_8_9 = 0x00001000,
+ FE_FECRATE_9_10 = 0x00002000,
+ FE_FECRATE_AUTO = 0x10000000
+};
+
+enum fe_modcod {
+ MOD_DUMMY_PLFRAME = 0x00000000,
+ MOD_QPSK_1_4,
+ MOD_QPSK_1_3,
+ MOD_QPSK_2_5,
+ MOD_QPSK_1_2,
+ MOD_QPSK_3_5,
+ MOD_QPSK_2_3,
+ MOD_QPSK_3_4,
+ MOD_QPSK_4_5,
+ MOD_QPSK_5_6,
+ MOD_QPSK_8_9,
+ MOD_QPSK_9_10,
+ MOD_8PSK_3_5,
+ MOD_8PSK_2_3,
+ MOD_8PSK_3_4,
+ MOD_8PSK_5_6,
+ MOD_8PSK_8_9,
+ MOD_8PSK_9_10,
+ MOD_16APSK_2_3,
+ MOD_16APSK_3_4,
+ MOD_16APSK_4_5,
+ MOD_16APSK_5_6,
+ MOD_16APSK_8_9,
+ MOD_16APSK_9_10,
+ MOD_32APSK_3_4,
+ MOD_32APSK_4_5,
+ MOD_32APSK_5_6,
+ MOD_32APSK_8_9,
+ MOD_32APSK_9_10,
+ MOD_RESERVED_1,
+ MOD_BPSK_1_3,
+ MOD_BPSK_1_4,
+ MOD_RESERVED_2
+};
+
+enum fe_bandwidths {
+ FE_BANDWIDTH_QUERY = 0x00000000,
+ FE_BANDWIDTH_8_MHZ = 0x00000001,
+ FE_BANDWIDTH_7_MHZ = 0x00000002,
+ FE_BANDWIDTH_6_MHZ = 0x00000004,
+ FE_BANDWIDTH_AUTO = 0x10000000
+};
+
+enum fe_inversion {
+ FE_INVERSION_QUERY = 0x00000000,
+ FE_INVERSION_OFF = 0x00000001,
+ FE_INVERSION_ON = 0x00000002,
+ FE_INVERSION_AUTO = 0x10000000
+};
+
+enum fe_transmit_modes {
+ FE_TRANSMISSION_MODE_QUERY = 0x00000000,
+ FE_TRANSMISSION_MODE_2K = 0x00000001,
+ FE_TRANSMISSION_MODE_4K = 0x00000002,
+ FE_TRANSMISSION_MODE_8K = 0x00000004,
+ FE_TRANSMISSION_MODE_AUTO = 0x10000000
+};
+
+enum fe_guard_intervals {
+ FE_GUARD_INTERVAL_QUERY = 0x00000000,
+ FE_GUARD_INTERVAL_1_32 = 0x00000001,
+ FE_GUARD_INTERVAL_1_16 = 0x00000002,
+ FE_GUARD_INTERVAL_1_8 = 0x00000004,
+ FE_GUARD_INTERVAL_1_4 = 0x00000008,
+ FE_GUARD_INTERVAL_AUTO = 0x10000000
+};
+
+enum fe_hierarchy_info {
+ FE_HIERARCHY_QUERY = 0x00000000,
+ FE_HIERARCHY_NONE = 0x00000001,
+ FE_HIERARCHY_1 = 0x00000002,
+ FE_HIERARCHY_2 = 0x00000004,
+ FE_HIERARCHY_4 = 0x00000008,
+ FE_HIERARCHY_AUTO = 0x10000000
+};
+
+enum fe_mpefec{
+ FE_MPEFEC_ON = 0x00000001,
+ FE_MPEFEC_OFF = 0x00000002,
+};
+
+enum fe_timeslicing {
+ FE_TIMESLICING_ON = 0x00000001,
+ FE_TIMESLICING_OFF = 0x00000002
+};
+
+/**
+ * DVB-S parameters
+ */
+struct dvbs_params {
+ __u32 symbol_rate;
+ enum fe_modulations modulation;
+ enum fe_fecrates fecrate;
+};
+
+/**
+ * DVB-S2 parameters
+ */
+struct dvbs2_params {
+ __u32 symbol_rate;
+ enum fe_modulations modulation;
+ enum fe_fecrates fecrate;
+ enum fe_stream streamtype;
+};
+
+/**
+ * DSS parameters
+ */
+struct dss_params {
+ __u32 symbol_rate;
+ enum fe_modulations modulation;
+ enum fe_fecrates fecrate;
+};
+
+/**
+ * DVB-C parameters
+ */
+struct dvbc_params {
+ __u32 symbol_rate;
+ enum fe_modulations modulation;
+ enum fe_fecrates fecrate;
+};
+
+/**
+ * DVB-T parameters
+ */
+struct dvbt_params {
+ enum fe_modulations constellation;
+ enum fe_bandwidths bandwidth;
+ enum fe_fecrates code_rate_HP;
+ enum fe_fecrates code_rate_LP;
+ enum fe_transmit_modes transmission_mode;
+ enum fe_guard_intervals guard_interval;
+ enum fe_hierarchy_info hierarchy;
+};
+
+/**
+ * DVB-H parameters
+ */
+struct dvbh_params {
+ enum fe_modulations constellation;
+ enum fe_bandwidths bandwidth;
+ enum fe_fecrates code_rate_HP;
+ enum fe_fecrates code_rate_LP;
+ enum fe_transmit_modes transmission_mode;
+ enum fe_guard_intervals guard_interval;
+ enum fe_hierarchy_info hierarchy;
+ enum fe_mpefec mpefec;
+ enum fe_timeslicing timeslicing;
+};
+
+/**
+ * ATSC parameters
+ */
+struct atsc_params {
+ enum fe_modulations modulation;
+ enum fe_fecrates fecrate;
+};
+
+struct dvb_frontend_cap {
+ enum fe_delsys delivery;
+ enum fe_inversion inversion;
+
+ union {
+ struct dvbs_params dvbs;
+ struct dvbs2_params dvbs2;
+ struct dss_params dss;
+ struct dvbc_params dvbc;
+ struct dvbt_params dvbt;
+ struct dvbh_params dvbh;
+ struct atsc_params atsc;
+ } delsys;
+};
+
+struct dvb_frontend_params {
+ __u32 frequency;
+ enum fe_delsys delivery;
+ enum fe_inversion inversion;
+
+ union {
+ struct dvbs_params dvbs;
+ struct dvbs2_params dvbs2;
+ struct dss_params dss;
+ struct dvbc_params dvbc;
+ struct dvbt_params dvbt;
+ struct dvbh_params dvbh;
+ struct atsc_params atsc;
+ } delsys;
+};
+
+#define FE_SET_PARAMS _IOW('o', 81, struct dvb_frontend_params)
+#define FE_GET_PARAMS _IOWR('o', 82, struct dvb_frontend_cap)
+
#endif /*_DVBFRONTEND_H_*/
_______________________________________________
linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb