From f42bba1bc814311cdd5852cec964d6ac5e59ec3b Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Mon, 3 Aug 2009 19:39:15 +0200 Subject: DVB-API: add support for ISDB-T and ISDB-Tsb (version 5.1) From: Patrick Boettcher This patch increments the DVB-API to version 5.1 in order to reflect the addition of ISDB-T and ISDB-Tsb on Linux' DVB-API. Changes in detail: - added a small document to describe how to use the API to tune to an ISDB-T or ISDB-Tsb channel - added necessary fields to dtv_frontend_cache - added a smarter clear-cache function which resets all fields of the dtv_frontend_cache - added a TRANSMISSION_MODE_4K to fe_transmit_mode_t Priority: normal Signed-off-by: Olivier Grenie Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 306 +++++++++++++++--------- linux/drivers/media/dvb/dvb-core/dvb_frontend.h | 26 +- 2 files changed, 210 insertions(+), 122 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 41166d407..52b0baa52 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -837,6 +837,49 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe, 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 +959,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 +979,43 @@ 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_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_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 +1023,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 +1233,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 +1325,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 +1349,59 @@ 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_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 +1430,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 +1472,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 +1497,59 @@ 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_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; } 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 { -- cgit v1.2.3 From beae3fdb4940243ca65c75fea541535237e8e280 Mon Sep 17 00:00:00 2001 From: Patrick Boettcher Date: Fri, 14 Aug 2009 10:24:19 +0200 Subject: ISDB-T: add mapping of LAYER_ENABLED to frontend-cache From: Patrick Boettcher It was forgotten to map the LAYER_ENABLED ioctl to the frontend-cache and back. Priority: normal Signed-off-by: Patrick Boettcher --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 52b0baa52..6f3491599 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -985,6 +985,7 @@ static struct dtv_cmds_h dtv_cmds[] = { _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), @@ -1003,6 +1004,7 @@ static struct dtv_cmds_h dtv_cmds[] = { _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), @@ -1366,6 +1368,9 @@ static int dtv_property_process_get(struct dvb_frontend *fe, 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; @@ -1514,6 +1519,9 @@ static int dtv_property_process_set(struct dvb_frontend *fe, 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; -- cgit v1.2.3 From 3218818d07892e9fd082cf1b3165164eae279bb5 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Wed, 2 Sep 2009 00:15:39 +0200 Subject: DVB: make DVB_MAX_ADAPTERS configurable From: Janne Grunau Support for more than 8 DVB devices is requested regularly so make it a kconfig variable instead of a header define. Values in the range 4-32 are tested. Priority: normal Signed-off-by: Janne Grunau Signed-off-by: Michael Krufky --- linux/drivers/media/dvb/dvb-core/dvbdev.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'linux/drivers/media/dvb/dvb-core') 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) -- cgit v1.2.3 From 39c7c8c56d56cc3a3fd5128d0598944303a929df Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Wed, 2 Sep 2009 00:23:09 +0200 Subject: dvb-core: check fe->ops.set_frontend return value From: Janne Grunau Various frontend driver have parameter checks in their set_frontend functions and return an error if the parameters are not supported, tda10021 and cx24116 to name two. The tuning ioctls FE_SET_FRONTEND/FE_SET_PROPERTY only change values in the property cache and return before set_frontend is called. If a set_frontend call in software zigzag algorithm fails and the card was previously locked it will report a lock and the new parameters but is still tuned to the old transport. This is not detectable from userspace. This change checks the return values of fe->ops.set_frontend and changes the state to the added FESTATE_ERROR for software zigzag. No lock will be reported to userspace if the State is FESTATE_ERROR. Priority: normal Signed-off-by: Janne Grunau --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 26 ++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index 41166d407..fbfccbd91 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 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; @@ -1614,7 +1629,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; -- cgit v1.2.3 From 47515034f52a7a8848e3636668e31e1af4a79fbe Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Wed, 2 Sep 2009 00:24:08 +0200 Subject: dvb-core: check supported QAM modulations From: Janne Grunau Check the modulation in dvb_frontend_check_parameters against frontend's capabilties for FE_QAM devices. Priority: normal Signed-off-by: Janne Grunau --- linux/drivers/media/dvb/dvb-core/dvb_frontend.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'linux/drivers/media/dvb/dvb-core') diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c index fbfccbd91..56a11d32a 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -849,6 +849,15 @@ 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; } -- cgit v1.2.3 From 74c8a615523ef5d42b617ab521fa1c6a01da0cd9 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 12 Sep 2009 14:18:18 -0300 Subject: backport commit 8a8bdcc7533b104d789d9bb3ed90da9352515e21 From: Mauro Carvalho Chehab kernel-sync: Author: Kay Sievers Date: Thu Apr 30 15:23:42 2009 +0200 Driver Core: dvb: add nodename for dvb drivers This adds support to the dvb core to report the proper device name to userspace for their devices. Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dvb-core/dvbdev.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'linux/drivers/media/dvb/dvb-core') 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; @@ -500,6 +511,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; -- cgit v1.2.3