summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/dvb-core
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-09-17 11:17:44 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-17 11:17:44 -0300
commitee117cb21fc99d6d1ef141b62ac07c2c99ed6558 (patch)
treeb3109826151f5b2cacd01a2a78fc51079381fec7 /linux/drivers/media/dvb/dvb-core
parent3c34c6c8fa0c2f378cdad415e8f15c0938c28cb8 (diff)
parent26642526dd562aa77049bb56d5bf9ad64158c767 (diff)
downloadmediapointer-dvb-s2-ee117cb21fc99d6d1ef141b62ac07c2c99ed6558.tar.gz
mediapointer-dvb-s2-ee117cb21fc99d6d1ef141b62ac07c2c99ed6558.tar.bz2
merge: http://kernellabs.com/hg/~mkrufky/saa7164
From: Mauro Carvalho Chehab <mchehab@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'linux/drivers/media/dvb/dvb-core')
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.c349
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.h26
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvbdev.c14
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvbdev.h5
4 files changed, 267 insertions, 127 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
index 41166d407..2409586d3 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -77,6 +77,7 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open(
#define FESTATE_ZIGZAG_FAST 32
#define FESTATE_ZIGZAG_SLOW 64
#define FESTATE_DISEQC 128
+#define FESTATE_ERROR 256
#define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC)
#define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST)
#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW)
@@ -274,6 +275,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
{
int autoinversion;
int ready = 0;
+ int fe_set_err = 0;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
int original_inversion = fepriv->parameters.inversion;
u32 original_frequency = fepriv->parameters.frequency;
@@ -350,7 +352,11 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
if (autoinversion)
fepriv->parameters.inversion = fepriv->inversion;
if (fe->ops.set_frontend)
- fe->ops.set_frontend(fe, &fepriv->parameters);
+ fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters);
+ if (fe_set_err < 0) {
+ fepriv->state = FESTATE_ERROR;
+ return fe_set_err;
+ }
fepriv->parameters.frequency = original_frequency;
fepriv->parameters.inversion = original_inversion;
@@ -362,6 +368,7 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra
static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
{
fe_status_t s = 0;
+ int retval = 0;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
/* if we've got no parameters, just keep idling */
@@ -375,8 +382,12 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) {
if (fepriv->state & FESTATE_RETUNE) {
if (fe->ops.set_frontend)
- fe->ops.set_frontend(fe, &fepriv->parameters);
- fepriv->state = FESTATE_TUNED;
+ retval = fe->ops.set_frontend(fe,
+ &fepriv->parameters);
+ if (retval < 0)
+ fepriv->state = FESTATE_ERROR;
+ else
+ fepriv->state = FESTATE_TUNED;
}
fepriv->delay = 3*HZ;
fepriv->quality = 0;
@@ -454,7 +465,11 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
fepriv->delay = fepriv->min_delay;
/* peform a tune */
- if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) {
+ retval = dvb_frontend_swzigzag_autotune(fe,
+ fepriv->check_wrapped);
+ if (retval < 0) {
+ return;
+ } else if (retval) {
/* OK, if we've run out of trials at the fast speed.
* Drop back to slow for the _next_ attempt */
fepriv->state = FESTATE_SEARCHING_SLOW;
@@ -834,9 +849,61 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
}
}
+ /* check for supported modulation */
+ if (fe->ops.info.type == FE_QAM &&
+ (parms->u.qam.modulation > QAM_AUTO ||
+ !((1 << (parms->u.qam.modulation + 10)) & fe->ops.info.caps))) {
+ printk(KERN_WARNING "DVB: adapter %i frontend %i modulation %u not supported\n",
+ fe->dvb->num, fe->id, parms->u.qam.modulation);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
+{
+ int i;
+
+ memset(&(fe->dtv_property_cache), 0,
+ sizeof(struct dtv_frontend_properties));
+
+ fe->dtv_property_cache.state = DTV_CLEAR;
+ fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
+ fe->dtv_property_cache.inversion = INVERSION_AUTO;
+ fe->dtv_property_cache.fec_inner = FEC_AUTO;
+ fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
+ fe->dtv_property_cache.bandwidth_hz = BANDWIDTH_AUTO;
+ fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
+ fe->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
+ fe->dtv_property_cache.symbol_rate = QAM_AUTO;
+ fe->dtv_property_cache.code_rate_HP = FEC_AUTO;
+ fe->dtv_property_cache.code_rate_LP = FEC_AUTO;
+
+ fe->dtv_property_cache.isdbt_partial_reception = -1;
+ fe->dtv_property_cache.isdbt_sb_mode = -1;
+ fe->dtv_property_cache.isdbt_sb_subchannel = -1;
+ fe->dtv_property_cache.isdbt_sb_segment_idx = -1;
+ fe->dtv_property_cache.isdbt_sb_segment_count = -1;
+ fe->dtv_property_cache.isdbt_layer_enabled = 0x7;
+ for (i = 0; i < 3; i++) {
+ fe->dtv_property_cache.layer[i].fec = FEC_AUTO;
+ fe->dtv_property_cache.layer[i].modulation = QAM_AUTO;
+ fe->dtv_property_cache.layer[i].interleaving = -1;
+ fe->dtv_property_cache.layer[i].segment_count = -1;
+ }
+
return 0;
}
+#define _DTV_CMD(n, s, b) \
+[n] = { \
+ .name = #n, \
+ .cmd = n, \
+ .set = s,\
+ .buffer = b \
+}
+
static struct dtv_cmds_h dtv_cmds[] = {
[DTV_TUNE] = {
.name = "DTV_TUNE",
@@ -916,18 +983,6 @@ static struct dtv_cmds_h dtv_cmds[] = {
.cmd = DTV_HIERARCHY,
.set = 1,
},
-#if 0
- [DTV_ISDB_SEGMENT_IDX] = {
- .name = "DTV_ISDB_SEGMENT_IDX",
- .cmd = DTV_ISDB_SEGMENT_IDX,
- .set = 1,
- },
- [DTV_ISDB_SEGMENT_WIDTH] = {
- .name = "DTV_ISDB_SEGMENT_WIDTH",
- .cmd = DTV_ISDB_SEGMENT_WIDTH,
- .set = 1,
- },
-#endif
[DTV_CODE_RATE_HP] = {
.name = "DTV_CODE_RATE_HP",
.cmd = DTV_CODE_RATE_HP,
@@ -948,6 +1003,45 @@ static struct dtv_cmds_h dtv_cmds[] = {
.cmd = DTV_TRANSMISSION_MODE,
.set = 1,
},
+
+ _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0),
+ _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0),
+ _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 1, 0),
+ _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 1, 0),
+ _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0),
+
+ _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 0, 0),
+ _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 0, 0),
+ _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 0, 0),
+ _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 0, 0),
+ _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 0, 0),
+ _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 0, 0),
+
/* Get */
[DTV_DISEQC_SLAVE_REPLY] = {
.name = "DTV_DISEQC_SLAVE_REPLY",
@@ -955,53 +1049,7 @@ static struct dtv_cmds_h dtv_cmds[] = {
.set = 0,
.buffer = 1,
},
-#if 0
- [DTV_ISDB_LAYERA_FEC] = {
- .name = "DTV_ISDB_LAYERA_FEC",
- .cmd = DTV_ISDB_LAYERA_FEC,
- .set = 0,
- },
- [DTV_ISDB_LAYERA_MODULATION] = {
- .name = "DTV_ISDB_LAYERA_MODULATION",
- .cmd = DTV_ISDB_LAYERA_MODULATION,
- .set = 0,
- },
- [DTV_ISDB_LAYERA_SEGMENT_WIDTH] = {
- .name = "DTV_ISDB_LAYERA_SEGMENT_WIDTH",
- .cmd = DTV_ISDB_LAYERA_SEGMENT_WIDTH,
- .set = 0,
- },
- [DTV_ISDB_LAYERB_FEC] = {
- .name = "DTV_ISDB_LAYERB_FEC",
- .cmd = DTV_ISDB_LAYERB_FEC,
- .set = 0,
- },
- [DTV_ISDB_LAYERB_MODULATION] = {
- .name = "DTV_ISDB_LAYERB_MODULATION",
- .cmd = DTV_ISDB_LAYERB_MODULATION,
- .set = 0,
- },
- [DTV_ISDB_LAYERB_SEGMENT_WIDTH] = {
- .name = "DTV_ISDB_LAYERB_SEGMENT_WIDTH",
- .cmd = DTV_ISDB_LAYERB_SEGMENT_WIDTH,
- .set = 0,
- },
- [DTV_ISDB_LAYERC_FEC] = {
- .name = "DTV_ISDB_LAYERC_FEC",
- .cmd = DTV_ISDB_LAYERC_FEC,
- .set = 0,
- },
- [DTV_ISDB_LAYERC_MODULATION] = {
- .name = "DTV_ISDB_LAYERC_MODULATION",
- .cmd = DTV_ISDB_LAYERC_MODULATION,
- .set = 0,
- },
- [DTV_ISDB_LAYERC_SEGMENT_WIDTH] = {
- .name = "DTV_ISDB_LAYERC_SEGMENT_WIDTH",
- .cmd = DTV_ISDB_LAYERC_SEGMENT_WIDTH,
- .set = 0,
- },
-#endif
+
[DTV_API_VERSION] = {
.name = "DTV_API_VERSION",
.cmd = DTV_API_VERSION,
@@ -1211,14 +1259,21 @@ static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
if(c->delivery_system == SYS_ISDBT) {
/* Fake out a generic DVB-T request so we pass validation in the ioctl */
p->frequency = c->frequency;
- p->inversion = INVERSION_AUTO;
+ p->inversion = c->inversion;
p->u.ofdm.constellation = QAM_AUTO;
p->u.ofdm.code_rate_HP = FEC_AUTO;
p->u.ofdm.code_rate_LP = FEC_AUTO;
- p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
p->u.ofdm.hierarchy_information = HIERARCHY_AUTO;
+ if (c->bandwidth_hz == 8000000)
+ p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
+ else if (c->bandwidth_hz == 7000000)
+ p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
+ else if (c->bandwidth_hz == 6000000)
+ p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
+ else
+ p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
}
}
@@ -1296,42 +1351,6 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
case DTV_DELIVERY_SYSTEM:
tvp->u.data = fe->dtv_property_cache.delivery_system;
break;
-#if 0
- /* ISDB-T Support here */
- case DTV_ISDB_SEGMENT_IDX:
- tvp->u.data = fe->dtv_property_cache.isdb_segment_idx;
- break;
- case DTV_ISDB_SEGMENT_WIDTH:
- tvp->u.data = fe->dtv_property_cache.isdb_segment_width;
- break;
- case DTV_ISDB_LAYERA_FEC:
- tvp->u.data = fe->dtv_property_cache.isdb_layera_fec;
- break;
- case DTV_ISDB_LAYERA_MODULATION:
- tvp->u.data = fe->dtv_property_cache.isdb_layera_modulation;
- break;
- case DTV_ISDB_LAYERA_SEGMENT_WIDTH:
- tvp->u.data = fe->dtv_property_cache.isdb_layera_segment_width;
- break;
- case DTV_ISDB_LAYERB_FEC:
- tvp->u.data = fe->dtv_property_cache.isdb_layerb_fec;
- break;
- case DTV_ISDB_LAYERB_MODULATION:
- tvp->u.data = fe->dtv_property_cache.isdb_layerb_modulation;
- break;
- case DTV_ISDB_LAYERB_SEGMENT_WIDTH:
- tvp->u.data = fe->dtv_property_cache.isdb_layerb_segment_width;
- break;
- case DTV_ISDB_LAYERC_FEC:
- tvp->u.data = fe->dtv_property_cache.isdb_layerc_fec;
- break;
- case DTV_ISDB_LAYERC_MODULATION:
- tvp->u.data = fe->dtv_property_cache.isdb_layerc_modulation;
- break;
- case DTV_ISDB_LAYERC_SEGMENT_WIDTH:
- tvp->u.data = fe->dtv_property_cache.isdb_layerc_segment_width;
- break;
-#endif
case DTV_VOLTAGE:
tvp->u.data = fe->dtv_property_cache.voltage;
break;
@@ -1356,6 +1375,62 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
case DTV_HIERARCHY:
tvp->u.data = fe->dtv_property_cache.hierarchy;
break;
+
+ /* ISDB-T Support here */
+ case DTV_ISDBT_PARTIAL_RECEPTION:
+ tvp->u.data = fe->dtv_property_cache.isdbt_partial_reception;
+ break;
+ case DTV_ISDBT_SOUND_BROADCASTING:
+ tvp->u.data = fe->dtv_property_cache.isdbt_sb_mode;
+ break;
+ case DTV_ISDBT_SB_SUBCHANNEL_ID:
+ tvp->u.data = fe->dtv_property_cache.isdbt_sb_subchannel;
+ break;
+ case DTV_ISDBT_SB_SEGMENT_IDX:
+ tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_idx;
+ break;
+ case DTV_ISDBT_SB_SEGMENT_COUNT:
+ tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_count;
+ break;
+ case DTV_ISDBT_LAYER_ENABLED:
+ tvp->u.data = fe->dtv_property_cache.isdbt_layer_enabled;
+ break;
+ case DTV_ISDBT_LAYERA_FEC:
+ tvp->u.data = fe->dtv_property_cache.layer[0].fec;
+ break;
+ case DTV_ISDBT_LAYERA_MODULATION:
+ tvp->u.data = fe->dtv_property_cache.layer[0].modulation;
+ break;
+ case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
+ tvp->u.data = fe->dtv_property_cache.layer[0].segment_count;
+ break;
+ case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
+ tvp->u.data = fe->dtv_property_cache.layer[0].interleaving;
+ break;
+ case DTV_ISDBT_LAYERB_FEC:
+ tvp->u.data = fe->dtv_property_cache.layer[1].fec;
+ break;
+ case DTV_ISDBT_LAYERB_MODULATION:
+ tvp->u.data = fe->dtv_property_cache.layer[1].modulation;
+ break;
+ case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
+ tvp->u.data = fe->dtv_property_cache.layer[1].segment_count;
+ break;
+ case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
+ tvp->u.data = fe->dtv_property_cache.layer[1].interleaving;
+ break;
+ case DTV_ISDBT_LAYERC_FEC:
+ tvp->u.data = fe->dtv_property_cache.layer[2].fec;
+ break;
+ case DTV_ISDBT_LAYERC_MODULATION:
+ tvp->u.data = fe->dtv_property_cache.layer[2].modulation;
+ break;
+ case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
+ tvp->u.data = fe->dtv_property_cache.layer[2].segment_count;
+ break;
+ case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
+ tvp->u.data = fe->dtv_property_cache.layer[2].interleaving;
+ break;
default:
r = -1;
}
@@ -1384,10 +1459,8 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
/* Reset a cache of data specific to the frontend here. This does
* not effect hardware.
*/
+ dvb_frontend_clear_cache(fe);
dprintk("%s() Flushing property cache\n", __func__);
- memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties));
- fe->dtv_property_cache.state = tvp->cmd;
- fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
break;
case DTV_TUNE:
/* interpret the cache of data, build either a traditional frontend
@@ -1428,15 +1501,6 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
case DTV_DELIVERY_SYSTEM:
fe->dtv_property_cache.delivery_system = tvp->u.data;
break;
-#if 0
- /* ISDB-T Support here */
- case DTV_ISDB_SEGMENT_IDX:
- fe->dtv_property_cache.isdb_segment_idx = tvp->u.data;
- break;
- case DTV_ISDB_SEGMENT_WIDTH:
- fe->dtv_property_cache.isdb_segment_width = tvp->u.data;
- break;
-#endif
case DTV_VOLTAGE:
fe->dtv_property_cache.voltage = tvp->u.data;
r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_VOLTAGE,
@@ -1462,6 +1526,62 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
case DTV_HIERARCHY:
fe->dtv_property_cache.hierarchy = tvp->u.data;
break;
+
+ /* ISDB-T Support here */
+ case DTV_ISDBT_PARTIAL_RECEPTION:
+ fe->dtv_property_cache.isdbt_partial_reception = tvp->u.data;
+ break;
+ case DTV_ISDBT_SOUND_BROADCASTING:
+ fe->dtv_property_cache.isdbt_sb_mode = tvp->u.data;
+ break;
+ case DTV_ISDBT_SB_SUBCHANNEL_ID:
+ fe->dtv_property_cache.isdbt_sb_subchannel = tvp->u.data;
+ break;
+ case DTV_ISDBT_SB_SEGMENT_IDX:
+ fe->dtv_property_cache.isdbt_sb_segment_idx = tvp->u.data;
+ break;
+ case DTV_ISDBT_SB_SEGMENT_COUNT:
+ fe->dtv_property_cache.isdbt_sb_segment_count = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYER_ENABLED:
+ fe->dtv_property_cache.isdbt_layer_enabled = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERA_FEC:
+ fe->dtv_property_cache.layer[0].fec = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERA_MODULATION:
+ fe->dtv_property_cache.layer[0].modulation = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
+ fe->dtv_property_cache.layer[0].segment_count = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
+ fe->dtv_property_cache.layer[0].interleaving = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERB_FEC:
+ fe->dtv_property_cache.layer[1].fec = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERB_MODULATION:
+ fe->dtv_property_cache.layer[1].modulation = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
+ fe->dtv_property_cache.layer[1].segment_count = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
+ fe->dtv_property_cache.layer[1].interleaving = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERC_FEC:
+ fe->dtv_property_cache.layer[2].fec = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERC_MODULATION:
+ fe->dtv_property_cache.layer[2].modulation = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
+ fe->dtv_property_cache.layer[2].segment_count = tvp->u.data;
+ break;
+ case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
+ fe->dtv_property_cache.layer[2].interleaving = tvp->u.data;
+ break;
default:
r = -1;
}
@@ -1614,7 +1734,8 @@ static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file,
/* if retune was requested but hasn't occured yet, prevent
* that user get signal state from previous tuning */
- if(fepriv->state == FESTATE_RETUNE) {
+ if (fepriv->state == FESTATE_RETUNE ||
+ fepriv->state == FESTATE_ERROR) {
err=0;
*status = 0;
break;
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
index cff26dd66..9e46f1772 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -341,20 +341,20 @@ struct dtv_frontend_properties {
fe_rolloff_t rolloff;
fe_delivery_system_t delivery_system;
-#if 0
+
/* ISDB-T specifics */
- u32 isdb_segment_idx;
- u32 isdb_segment_width;
- fe_code_rate_t isdb_layera_fec;
- fe_modulation_t isdb_layera_modulation;
- u32 isdb_layera_segment_width;
- fe_code_rate_t isdb_layerb_fec;
- fe_modulation_t isdb_layerb_modulation;
- u32 isdb_layerb_segment_width;
- fe_code_rate_t isdb_layerc_fec;
- fe_modulation_t isdb_layerc_modulation;
- u32 isdb_layerc_segment_width;
-#endif
+ u8 isdbt_partial_reception;
+ u8 isdbt_sb_mode;
+ u8 isdbt_sb_subchannel;
+ u32 isdbt_sb_segment_idx;
+ u32 isdbt_sb_segment_count;
+ u8 isdbt_layer_enabled;
+ struct {
+ u8 segment_count;
+ fe_code_rate_t fec;
+ fe_modulation_t modulation;
+ u8 interleaving;
+ } layer[3];
};
struct dvb_frontend {
diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c
index f6084e19d..2028be23d 100644
--- a/linux/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c
@@ -472,6 +472,17 @@ static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
}
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
+static char *dvb_nodename(struct device *dev)
+{
+ struct dvb_device *dvbdev = dev_get_drvdata(dev);
+
+ return kasprintf(GFP_KERNEL, "dvb/adapter%d/%s%d",
+ dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id);
+}
+
+
+#endif
static int __init init_dvbdev(void)
{
int retval;
@@ -501,6 +512,9 @@ static int __init init_dvbdev(void)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
dvb_class->dev_uevent = dvb_uevent;
#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31)
+ dvb_class->nodename = dvb_nodename;
+#endif
return 0;
error:
diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.h b/linux/drivers/media/dvb/dvb-core/dvbdev.h
index 487919bea..895e2efca 100644
--- a/linux/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/linux/drivers/media/dvb/dvb-core/dvbdev.h
@@ -30,7 +30,12 @@
#define DVB_MAJOR 212
+#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
+#define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
+#else
+#warning invalid CONFIG_DVB_MAX_ADAPTERS value
#define DVB_MAX_ADAPTERS 8
+#endif
#define DVB_UNSET (-1)