Index: v4l-dvb/linux/drivers/media/dvb/dvb-core/dvb_frontend.c =================================================================== --- v4l-dvb.orig/linux/drivers/media/dvb/dvb-core/dvb_frontend.c 2007-08-20 19:02:07.000000000 -0700 +++ v4l-dvb/linux/drivers/media/dvb/dvb-core/dvb_frontend.c 2007-08-20 19:04:18.000000000 -0700 @@ -102,6 +102,7 @@ /* thread/frontend values */ struct dvb_device *dvbdev; struct dvb_frontend_parameters parameters; + struct dvb_frontend_parameters_new parameters_new; struct dvb_fe_events events; struct semaphore sem; struct list_head list_head; @@ -117,6 +118,8 @@ int tone; int voltage; + int current_standard_set; + fe_type_t current_standard; /* swzigzag values */ unsigned int state; unsigned int bending; @@ -268,13 +271,23 @@ int autoinversion; int ready = 0; struct dvb_frontend_private *fepriv = fe->frontend_priv; - int original_inversion = fepriv->parameters.inversion; - u32 original_frequency = fepriv->parameters.frequency; + int original_inversion; + u32 original_frequency; + + if (fepriv->current_standard_set) { + original_inversion = fepriv->parameters_new.inversion; + original_frequency = fepriv->parameters_new.frequency; + } else { + original_inversion = fepriv->parameters.inversion; + original_frequency = fepriv->parameters.frequency; + } /* are we using autoinversion? */ autoinversion = ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) && - (fepriv->parameters.inversion == INVERSION_AUTO)); - + ((fepriv->current_standard_set && + fepriv->parameters_new.inversion == INVERSION_AUTO) || + (! fepriv->current_standard_set && + fepriv->parameters.inversion == INVERSION_AUTO))); /* setup parameters correctly */ while(!ready) { /* calculate the lnb_drift */ @@ -339,14 +352,24 @@ fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step); /* set the frontend itself */ - fepriv->parameters.frequency += fepriv->lnb_drift; - if (autoinversion) - fepriv->parameters.inversion = fepriv->inversion; - if (fe->ops.set_frontend) - fe->ops.set_frontend(fe, &fepriv->parameters); - - fepriv->parameters.frequency = original_frequency; - fepriv->parameters.inversion = original_inversion; + if (fepriv->current_standard_set) { + fepriv->parameters_new.frequency += fepriv->lnb_drift; + if (autoinversion) + fepriv->parameters_new.inversion = fepriv->inversion; + if (fe->ops.set_frontend2) + fe->ops.set_frontend2(fe, &fepriv->parameters_new); + fepriv->parameters_new.frequency = original_frequency; + fepriv->parameters_new.inversion = original_inversion; + } else { + fepriv->parameters.frequency += fepriv->lnb_drift; + if (autoinversion) + fepriv->parameters.inversion = fepriv->inversion; + if (fe->ops.set_frontend) + fe->ops.set_frontend(fe, &fepriv->parameters); + + fepriv->parameters.frequency = original_frequency; + fepriv->parameters.inversion = original_inversion; + } fepriv->auto_sub_step++; return 0; @@ -367,8 +390,13 @@ /* in SCAN mode, we just set the frontend when asked and leave it alone */ 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); + if (fepriv->current_standard_set) { + if (fe->ops.set_frontend2) + fe->ops.set_frontend2(fe, &fepriv->parameters_new); + } else { + if (fe->ops.set_frontend) + fe->ops.set_frontend(fe, &fepriv->parameters); + } fepriv->state = FESTATE_TUNED; } fepriv->delay = 3*HZ; @@ -982,18 +1010,21 @@ /* default values */ switch(fe->ops.info.type) { case FE_QPSK: + case FE_DVB_S: fepriv->min_delay = HZ/20; fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000; fepriv->max_drift = fepriv->parameters.u.qpsk.symbol_rate / 2000; break; case FE_QAM: + case FE_DVB_C: fepriv->min_delay = HZ/20; fepriv->step_size = 0; /* no zigzag */ fepriv->max_drift = 0; break; case FE_OFDM: + case FE_DVB_T: fepriv->min_delay = HZ/20; fepriv->step_size = fe->ops.info.frequency_stepsize * 2; fepriv->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1; @@ -1003,6 +1034,108 @@ fepriv->step_size = 0; fepriv->max_drift = 0; break; + case FE_DVB_S2: + printk("dvb-core: ERROR FE_DVB_S2 is handled via FE_SET_FRONTEND2.\n"); + break; + case FE_DSS: + printk("dvb-core: ERROR FE_DSS is handled via FE_SET_FRONTEND2.\n"); + break; + } + } + if (dvb_override_tune_delay > 0) + fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000; + + fepriv->state = FESTATE_RETUNE; + dvb_frontend_wakeup(fe); + dvb_frontend_add_event(fe, 0); + fepriv->status = 0; + err = 0; + break; + } + case FE_SET_FRONTEND2: { + struct dvb_frontend_tune_settings fetunesettings; + struct dvb_frontend_parameters_new *castedparg; + + if (!fepriv->current_standard_set) { + err = -EINVAL; + break; + } + + castedparg = (struct dvb_frontend_parameters_new *)parg; + memcpy (&fepriv->parameters_new, parg, + sizeof (struct dvb_frontend_parameters_new)); + + memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings)); + + /* be sure struct union pointer is set - even if it is NULL */ + fetunesettings.parameters_new.u = castedparg->u; + + /* force auto frequency inversion if requested */ + if (dvb_force_auto_inversion) { + fepriv->parameters_new.inversion = INVERSION_AUTO; + fetunesettings.parameters_new.inversion = INVERSION_AUTO; + } + if (fe->ops.info.type == FE_DVB_T || fe->ops.info.type == FE_OFDM) { + /* without hierachical coding code_rate_LP is irrelevant, + * so we tolerate the otherwise invalid FEC_NONE setting */ + if (fepriv->parameters_new.u.ofdm.hierarchy_information == HIERARCHY_NONE && + fepriv->parameters_new.u.ofdm.code_rate_LP == FEC_NONE) + fepriv->parameters_new.u.ofdm.code_rate_LP = FEC_AUTO; + } + + /* get frontend-specific tuning settings */ + if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, &fetunesettings) == 0)) { + fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000; + fepriv->max_drift = fetunesettings.max_drift; + fepriv->step_size = fetunesettings.step_size; + } else { + /* default values */ + switch(fe->ops.info.type) { + case FE_DVB_S: + case FE_QPSK: + if (fepriv->current_standard != FE_DVB_S) { + err = -EINVAL; + break; + } + fepriv->min_delay = HZ/20; + fepriv->step_size = fepriv->parameters_new.u.qpsk.symbol_rate / 16000; + fepriv->max_drift = fepriv->parameters_new.u.qpsk.symbol_rate / 2000; + break; + case FE_DVB_C: + case FE_QAM: + if (fepriv->current_standard != FE_DVB_C) { + err = -EINVAL; + break; + } + fepriv->min_delay = HZ/20; + fepriv->step_size = 0; /* no zigzag */ + fepriv->max_drift = 0; + break; + case FE_DVB_T: + case FE_OFDM: + if (fepriv->current_standard != FE_DVB_T) { + err = -EINVAL; + break; + } + fepriv->min_delay = HZ/20; + fepriv->step_size = fe->ops.info.frequency_stepsize * 2; + fepriv->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1; + break; + case FE_ATSC: + printk("dvb-core: FE_ATSC not handled yet.\n"); + break; + case FE_DVB_S2: + case FE_DSS: + if (fepriv->current_standard != FE_DVB_S2 && + fepriv->current_standard != FE_DSS) { + err = -EINVAL; + break; + } + fepriv->min_delay = HZ/20; + fepriv->step_size = fepriv->parameters_new.u.qpsk2.symbol_rate / 16000; + fepriv->max_drift = fepriv->parameters_new.u.qpsk2.symbol_rate / 2000; + break; + } } if (dvb_override_tune_delay > 0) @@ -1013,6 +1146,7 @@ dvb_frontend_add_event(fe, 0); fepriv->status = 0; err = 0; + /* if previously used delete old tuning params */ break; } @@ -1026,6 +1160,48 @@ err = fe->ops.get_frontend(fe, (struct dvb_frontend_parameters*) parg); } break; + case FE_GET_FRONTEND2: + if (!fepriv->current_standard) { + err = -EINVAL; + break; + } + if (fe->ops.get_frontend2) { + memcpy (parg, &fepriv->parameters_new, sizeof (struct dvb_frontend_parameters_new)); + err = fe->ops.get_frontend2(fe, (struct dvb_frontend_parameters_new*) parg); + } + break; + + case FE_SET_STANDARD: + /* + * current_standard_set and current_standard are reset + * this prevents user from ignoring return value and + * if current_standard would be kept as fallback, users may + * supply corrupted tuning data. + * if the new standard isn't supported no FE_SET_FRONTEND2 + * is possible. it will return EINVAL + */ + fepriv->current_standard_set = 0; + fepriv->current_standard = 0; + { + fe_type_t fetype = (fe_type_t) parg; + if (fetype != FE_DVB_S && fetype != FE_DVB_C && fetype != FE_DVB_T && fetype != FE_DVB_S2 && fetype != FE_ATSC && fetype != FE_DSS) { + err = -EINVAL; + } else if (fe->ops.set_standard) { + err = fe->ops.set_standard(fe, fetype); + if (!err) { + fepriv->current_standard_set = 1; + fepriv->current_standard = fetype; + } + } + } + break; + + case FE_GET_EXTENDED_INFO: { + struct dvb_fe_caps_extended* info = parg; + memcpy(info, &fe->ops.extended_info, sizeof(struct dvb_fe_caps_extended)); + err = 0; + break; + } case FE_SET_FRONTEND_TUNE_MODE: fepriv->tune_mode_flags = (unsigned long) parg; @@ -1078,7 +1254,10 @@ fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; fepriv->tone = -1; fepriv->voltage = -1; - + fepriv->current_standard_set = 0; + fepriv->current_standard = 0; + if (fe->ops.set_standard) + fe->ops.set_standard(fe, 0); ret = dvb_frontend_start (fe); if (ret) dvb_generic_release (inode, file); Index: v4l-dvb/linux/drivers/media/dvb/dvb-core/dvb_frontend.h =================================================================== --- v4l-dvb.orig/linux/drivers/media/dvb/dvb-core/dvb_frontend.h 2007-08-20 19:01:24.000000000 -0700 +++ v4l-dvb/linux/drivers/media/dvb/dvb-core/dvb_frontend.h 2007-08-20 19:04:18.000000000 -0700 @@ -48,6 +48,7 @@ int step_size; int max_drift; struct dvb_frontend_parameters parameters; + struct dvb_frontend_parameters_new parameters_new; }; struct dvb_frontend; @@ -93,6 +94,7 @@ struct dvb_frontend_ops { struct dvb_frontend_info info; + struct dvb_fe_caps_extended extended_info; void (*release)(struct dvb_frontend* fe); void (*release_sec)(struct dvb_frontend* fe); @@ -132,6 +134,10 @@ 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 (*set_standard)(struct dvb_frontend* fe, fe_type_t type); + int (*get_extended_info)(struct dvb_frontend* fe, struct dvb_fe_caps_extended* extendedinfo); + int (*set_frontend2)(struct dvb_frontend* fe, struct dvb_frontend_parameters_new* params); + int (*get_frontend2)(struct dvb_frontend* fe, struct dvb_frontend_parameters_new* params); int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire); struct dvb_tuner_ops tuner_ops; Index: v4l-dvb/linux/drivers/media/dvb/dvb-usb/gp8psk-fe.c =================================================================== --- v4l-dvb.orig/linux/drivers/media/dvb/dvb-usb/gp8psk-fe.c 2007-08-20 19:02:07.000000000 -0700 +++ v4l-dvb/linux/drivers/media/dvb/dvb-usb/gp8psk-fe.c 2007-08-20 19:04:18.000000000 -0700 @@ -25,6 +25,20 @@ unsigned long status_check_interval; }; +static int gp8psk_tuned_to_DCII(struct dvb_frontend* fe) +{ + struct gp8psk_fe_state *st = fe->demodulator_priv; + u8 status; + gp8psk_usb_in_op(st->d, GET_8PSK_CONFIG, 0,0,&status,1); + return (status & bmDCtuned); +} + +static int gp8psk_set_tuner_mode(struct dvb_frontend* fe, int mode) +{ + struct gp8psk_fe_state *state = fe->demodulator_priv; + return gp8psk_usb_out_op(state->d, SET_8PSK_CONFIG, mode,0,NULL,0); +} + static int gp8psk_fe_update_status(struct gp8psk_fe_state *st) { u8 buf[6]; @@ -54,6 +68,17 @@ return 0; } +static int gp8psk_set_standard(struct dvb_frontend* fe, u32 type) +{ + if (type == FE_DVB_S2 || type == FE_DVB_S) { + fe->ops.info.type = type; + return 0; + } else { + fe->ops.info.type = FE_QPSK; + return 1; + } +} + /* not supported by this Frontend */ static int gp8psk_fe_read_ber(struct dvb_frontend* fe, u32 *ber) { @@ -99,12 +124,13 @@ return 0; } -static int gp8psk_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) +static int gp8psk_fe_set_frontend2(struct dvb_frontend* fe, + struct dvb_frontend_parameters_new *fep) { struct gp8psk_fe_state *state = fe->demodulator_priv; u8 cmd[10]; u32 freq = fep->frequency * 1000; + int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct); cmd[4] = freq & 0xff; cmd[5] = (freq >> 8) & 0xff; @@ -112,13 +138,98 @@ cmd[7] = (freq >> 24) & 0xff; switch(fe->ops.info.type) { + case FE_DVB_S: case FE_QPSK: + if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) + if (gp8psk_tuned_to_DCII(fe)) + gp8psk_bcm4500_reload(state->d); cmd[0] = fep->u.qpsk.symbol_rate & 0xff; cmd[1] = (fep->u.qpsk.symbol_rate >> 8) & 0xff; cmd[2] = (fep->u.qpsk.symbol_rate >> 16) & 0xff; cmd[3] = (fep->u.qpsk.symbol_rate >> 24) & 0xff; cmd[8] = ADV_MOD_DVB_QPSK; - cmd[9] = 0x03; /*ADV_MOD_FEC_XXX*/ + cmd[9] = 5; + break; + case FE_DVB_S2: + cmd[0] = fep->u.qpsk2.symbol_rate & 0xff; + cmd[1] = (fep->u.qpsk2.symbol_rate >> 8) & 0xff; + cmd[2] = (fep->u.qpsk2.symbol_rate >> 16) & 0xff; + cmd[3] = (fep->u.qpsk2.symbol_rate >> 24) & 0xff; + switch (fep->u.qpsk2.modulation) { + case MOD_QPSK: + cmd[8] = ADV_MOD_DVB_QPSK; + if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) + if (gp8psk_tuned_to_DCII(fe)) + gp8psk_bcm4500_reload(state->d); + switch (fep->u.qpsk.fec_inner) { + case FEC_1_2: cmd[9] = 0; break; + case FEC_2_3: cmd[9] = 1; break; + case FEC_3_4: cmd[9] = 2; break; + case FEC_5_6: cmd[9] = 3; break; + case FEC_7_8: cmd[9] = 4; break; + case FEC_AUTO: cmd[9] = 5; break; + default: cmd[9] = 5; break; + } + break; + case MOD_QPSK_TURBO: + cmd[8] = ADV_MOD_TURBO_QPSK; + switch (fep->u.qpsk2.fec_inner) { + case FEC_1_4: cmd[9] = 0; break; + case FEC_1_2: cmd[9] = 1; break; + case FEC_2_3: cmd[9] = 0; + cmd[8] = ADV_MOD_TURBO_16QAM; break; + case FEC_3_4: cmd[9] = 2; break; + default: cmd[9] = 0; break; + } + break; + case MOD_8PSK_TURBO: + case MOD_8PSK: /* MOD_8PSK is for compatibility with DN */ + cmd[8] = ADV_MOD_TURBO_8PSK; + switch (fep->u.qpsk2.fec_inner) { + case FEC_2_3: cmd[9] = 0; break; + case FEC_3_4: cmd[9] = 1; break; + case FEC_3_5: cmd[9] = 2; break; + case FEC_5_6: cmd[9] = 3; break; + case FEC_8_9: cmd[9] = 4; break; + default: cmd[9] = 0; break; + } + break; + case MOD_16QAM_TURBO: + case MOD_QAM_16: /* MOD_QAM_16 is for compatibility with DN */ + cmd[8] = ADV_MOD_TURBO_16QAM; + cmd[9] = 0; + break; + case MOD_DCII_C_QPSK: + cmd[8] = ADV_MOD_DCII_C_QPSK; + goto fill_fec; + case MOD_DCII_I_QPSK: + cmd[8] = ADV_MOD_DCII_I_QPSK; + goto fill_fec; + case MOD_DCII_Q_QPSK: + cmd[8] = ADV_MOD_DCII_Q_QPSK; + goto fill_fec; + case MOD_DCII_C_OQPSK: + cmd[8] = ADV_MOD_DCII_C_OQPSK; +fill_fec: + switch (fep->u.qpsk2.fec_inner) { + case FEC_5_11: cmd[9] = 0; break; + case FEC_1_2: cmd[9] = 1; break; + case FEC_3_5: cmd[9] = 2; break; + case FEC_2_3: cmd[9] = 3; break; + case FEC_3_4: cmd[9] = 4; break; + case FEC_4_5: cmd[9] = 5; break; + case FEC_5_6: cmd[9] = 6; break; + case FEC_7_8: cmd[9] = 7; break; + case FEC_AUTO: cmd[9] = 8; break; + default: cmd[9] = 8; break; + } + break; + default: /* DSS QPSK is not supported right now */ + info("WRONG modulation selected"); + cmd[8] = ADV_MOD_DVB_QPSK; + cmd[9] = 5; /* FEC_AUTO */ + break; + } break; default: // other modes are unsuported right now @@ -131,6 +242,8 @@ break; } + if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) + gp8psk_set_tuner_mode(fe,0); gp8psk_usb_out_op(state->d,TUNE_8PSK,0,0,cmd,10); state->lock = 0; @@ -140,6 +253,13 @@ return 0; } +static int gp8psk_fe_set_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) +{ + return gp8psk_fe_set_frontend2(fe, + (struct dvb_frontend_parameters_new *) fep); +} + static int gp8psk_fe_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) { @@ -261,10 +381,19 @@ .symbol_rate_max = 45000000, .symbol_rate_tolerance = 500, /* ppm */ .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + // FE_CAN_QAM_16 is for compatibility + // (Myth incorrectly detects Turbo-QPSK as plain QAM-16) + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_HAS_EXTENDED_INFO }, + .extended_info = { + .fecs = FEC_1_2 | FEC_2_3 | FEC_3_4 | FEC_5_6 | + FEC_7_8 | FEC_AUTO, + .modulations = MOD_QPSK | MOD_BPSK | MOD_8PSK | MOD_DSS_QPSK, + .standards = FE_DVB_S | FE_DVB_S2 + }, + .set_standard = gp8psk_set_standard, .release = gp8psk_fe_release, @@ -273,6 +402,10 @@ .set_frontend = gp8psk_fe_set_frontend, .get_frontend = gp8psk_fe_get_frontend, + + .set_frontend2 = gp8psk_fe_set_frontend2, + .get_frontend2 = NULL, + .get_tune_settings = gp8psk_fe_get_tune_settings, .read_status = gp8psk_fe_read_status, Index: v4l-dvb/linux/include/linux/dvb/frontend.h =================================================================== --- v4l-dvb.orig/linux/include/linux/dvb/frontend.h 2007-08-20 19:01:24.000000000 -0700 +++ v4l-dvb/linux/include/linux/dvb/frontend.h 2007-08-20 19:04:18.000000000 -0700 @@ -28,15 +28,25 @@ #include - +/** + * Usage of fe_type_t enumerations: + * Don't use FE_QPSK, FE_QAM, FE_OFDM any longer in new applications. + * If the FE_HAS_EXTENDED_INFO is set within the fe_caps, + * applications should ignore the fe_type_t returned by the FE_GET_INFO ioctl. + * + */ typedef enum fe_type { - FE_QPSK, - FE_QAM, - FE_OFDM, - FE_ATSC + FE_QPSK = 0, + FE_QAM = 1, + FE_OFDM = 2, + FE_ATSC = 3, + FE_DVB_S = (1 << 2), + FE_DVB_C = (1 << 3), + FE_DVB_T = (1 << 4), + FE_DVB_S2 = (1 << 5), + FE_DSS = (1 << 6), } fe_type_t; - typedef enum fe_caps { FE_IS_STUPID = 0, FE_CAN_INVERSION_AUTO = 0x1, @@ -62,12 +72,12 @@ FE_CAN_HIERARCHY_AUTO = 0x100000, FE_CAN_8VSB = 0x200000, FE_CAN_16VSB = 0x400000, + FE_HAS_EXTENDED_INFO = 0x10000000, FE_NEEDS_BENDING = 0x20000000, // not supported anymore, don't use (frontend requires frequency bending) FE_CAN_RECOVER = 0x40000000, // frontend can recover from a cable unplug automatically FE_CAN_MUTE_TS = 0x80000000 // frontend can stop spurious TS data output } fe_caps_t; - struct dvb_frontend_info { char name[128]; fe_type_t type; @@ -82,7 +92,6 @@ fe_caps_t caps; }; - /** * Check out the DiSEqC bus spec available on http://www.eutelsat.org/ for * the meaning of this struct... @@ -126,9 +135,9 @@ FE_HAS_SYNC = 0x08, /* found sync bytes */ FE_HAS_LOCK = 0x10, /* everything's working... */ FE_TIMEDOUT = 0x20, /* no lock within the last ~2 seconds */ - FE_REINIT = 0x40 /* frontend was reinitialized, */ -} fe_status_t; /* application is recommended to reset */ - /* DiSEqC, tone and parameters */ + FE_REINIT = 0x40 /* legacy cruft, do not use */ +} fe_status_t; + typedef enum fe_spectral_inversion { INVERSION_OFF, @@ -147,22 +156,56 @@ FEC_6_7, FEC_7_8, FEC_8_9, - FEC_AUTO + FEC_AUTO, + FEC_3_5, + FEC_9_10, + FEC_1_4, + FEC_5_11 } fe_code_rate_t; typedef enum fe_modulation { - QPSK, - QAM_16, - QAM_32, - QAM_64, - QAM_128, - QAM_256, - QAM_AUTO, - VSB_8, - VSB_16 + MOD_QPSK = 0, + QPSK = 0, + MOD_QAM_16 = 1, + QAM_16 = 1, + MOD_QAM_32 = 2, + QAM_32 = 2, + MOD_QAM_64 = 3, + QAM_64 = 3, + MOD_QAM_128 = 4, + QAM_128 = 4, + MOD_QAM_256 = 5, + QAM_256 = 5, + MOD_QAM_AUTO = 6, + QAM_AUTO = 6, + MOD_8VSB = 7, + VSB_8 = 7, + MOD_16VSB = 8, + VSB_16 = 8, + MOD_2VSB = 9, + MOD_4VSB = 10, + MOD_BPSK = 11, + MOD_16APSK = 12, + MOD_32APSK = 13, + MOD_8PSK = 14, + MOD_16PSK = 15, + MOD_QPSK_TURBO = 16, + MOD_8PSK_TURBO = 17, + MOD_16QAM_TURBO = 18, + MOD_DCII_C_QPSK = 19, + MOD_DCII_I_QPSK = 20, + MOD_DCII_Q_QPSK = 21, + MOD_DCII_C_OQPSK = 22, + MOD_DSS_QPSK = 23, } fe_modulation_t; +typedef enum fe_rolloff_factor { + ROLLOFF_ALPHA_0_35, + ROLLOFF_ALPHA_0_25, + ROLLOFF_ALPHA_0_20 +} fe_rolloff_factor_t; + typedef enum fe_transmit_mode { TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K, @@ -194,23 +237,34 @@ HIERARCHY_AUTO } fe_hierarchy_t; +/** + * this struct will be filled by the FE_GET_EXTENDED_INFO ioctl. + * it is a extension to the normal frontend capabilities and provided + * if the dvb_fe_info.caps is having the FE_HAS_EXTENDED_INFO bit set. + */ +struct dvb_fe_caps_extended { + __u32 fecs; /* supported fecs */ + __u32 modulations; /* supported modulations */ + __u32 standards; /* supported frontend_types */ +}; + -struct dvb_qpsk_parameters { - __u32 symbol_rate; /* symbol rate in Symbols per second */ +struct dvb_dvbs_parameters { + __u32 symbol_rate; /* symbol rate in symbols per second */ fe_code_rate_t fec_inner; /* forward error correction (see above) */ }; -struct dvb_qam_parameters { - __u32 symbol_rate; /* symbol rate in Symbols per second */ +struct dvb_dvbc_parameters { + __u32 symbol_rate; /* symbol rate in symbols per second */ fe_code_rate_t fec_inner; /* forward error correction (see above) */ fe_modulation_t modulation; /* modulation type (see above) */ }; -struct dvb_vsb_parameters { +struct dvb_atsc_parameters { fe_modulation_t modulation; /* modulation type (see above) */ }; -struct dvb_ofdm_parameters { +struct dvb_dvbt_parameters { fe_bandwidth_t bandwidth; fe_code_rate_t code_rate_HP; /* high priority stream code rate */ fe_code_rate_t code_rate_LP; /* low priority stream code rate */ @@ -220,25 +274,75 @@ fe_hierarchy_t hierarchy_information; }; +struct dvb_dvbs2_parameters { + __u32 symbol_rate; /* symbol rate in symbols per second */ + fe_code_rate_t fec_inner; /* forward error correction (see above) */ + fe_modulation_t modulation; /* modulation type (see above) */ + fe_rolloff_factor_t rolloff_factor; /* rolloff factor needed for dvb-s2 */ +}; + +/* The following structure is used to allocate enough space in the union + for future expansion. +*/ +struct dvb_private_parameters { + __u32 priv[64]; +}; + +#define dvb_qpsk_parameters dvb_dvbs_parameters +#define dvb_qam_parameters dvb_dvbc_parameters +#define dvb_ofdm_parameters dvb_dvbt_parameters +#define dvb_vsb_parameters dvb_atsc_parameters +/* just kept for backwards binary compatibility + * deprecated for usage in actual applications + */ struct dvb_frontend_parameters { __u32 frequency; /* (absolute) frequency in Hz for QAM/OFDM/ATSC */ /* intermediate frequency in kHz for QPSK */ fe_spectral_inversion_t inversion; union { - struct dvb_qpsk_parameters qpsk; - struct dvb_qam_parameters qam; - struct dvb_ofdm_parameters ofdm; - struct dvb_vsb_parameters vsb; + struct dvb_dvbs_parameters qpsk; + struct dvb_dvbc_parameters qam; + struct dvb_dvbt_parameters ofdm; + struct dvb_atsc_parameters vsb; } u; +};// __attribute((__deprecated__)); + +typedef union { + struct dvb_dvbs_parameters qpsk; + struct dvb_dvbc_parameters qam; + struct dvb_dvbt_parameters ofdm; + struct dvb_atsc_parameters vsb; + struct dvb_dvbs2_parameters qpsk2; + struct dvb_private_parameters priv; +} frontend_parameters_union; + +struct dvb_frontend_parameters_new { + __u32 frequency; /* (absolute) frequency in Hz for QAM/OFDM/ATSC */ + /* intermediate frequency in kHz for QPSK */ + fe_spectral_inversion_t inversion; + frontend_parameters_union u; }; +/** + * Important: + * FE_GET_EVENT and struct dvb_frontend_event + * are deprecated due to: + * FE_GET_EVENT is a mis-designed ioctl + * informations within dvb_frontend_event will + * always return stale information. + * Applications should: + * - open the frontend device with O_NONBLOCK + * - poll() for events + * - FE_GET_EVENT all pending events to clear the POLLPRI status, + * and throw them away + * - FE_READ_STATUS etc. to get current information + */ struct dvb_frontend_event { fe_status_t status; struct dvb_frontend_parameters parameters; -}; - +}; // __attribute((__deprecated__)); /** * When set, this flag will disable any zigzagging or other "normal" tuning @@ -267,9 +371,36 @@ #define FE_READ_SNR _IOR('o', 72, __u16) #define FE_READ_UNCORRECTED_BLOCKS _IOR('o', 73, __u32) +#define FE_SET_FRONTEND2 _IOW('o', 84, struct dvb_frontend_parameters_new) +#define FE_GET_FRONTEND2 _IOR('o', 85, struct dvb_frontend_parameters_new) + +/** + * next two IOCTLs are deprecated for further use in applications + */ #define FE_SET_FRONTEND _IOW('o', 76, struct dvb_frontend_parameters) #define FE_GET_FRONTEND _IOR('o', 77, struct dvb_frontend_parameters) + + #define FE_SET_FRONTEND_TUNE_MODE _IO('o', 81) /* unsigned int */ + +/** + * use to set the FE_STANDARD - if a tuner supports more than one type. + * e.g. DVB-C/T or DVB-S/S2 combi frontends. after FE_SET_STANDARD was set, + * the drivers has to make sure still to reflect the standards available, + * but capabilities should be adjusted to the selected standard + */ +#define FE_SET_STANDARD _IO('o', 82) /* fe_type_t */ + +/** + * used to query the extended frontend capabilities (see above for details) + */ +#define FE_GET_EXTENDED_INFO _IOR('o', 83, struct dvb_fe_caps_extended) + +/** + * FE_GET_EVENT is deprecated for applications. + * you should use FE_READ_STATUS and if needed the FE_GET_FRONTEND_NEW + * IOCTLs. + */ #define FE_GET_EVENT _IOR('o', 78, struct dvb_frontend_event) #define FE_DISHNETWORK_SEND_LEGACY_CMD _IO('o', 80) /* unsigned int */ Index: v4l-dvb/linux/include/linux/dvb/video.h =================================================================== --- v4l-dvb.orig/linux/include/linux/dvb/video.h 2007-08-20 19:01:24.000000000 -0700 +++ v4l-dvb/linux/include/linux/dvb/video.h 2007-08-20 19:04:18.000000000 -0700 @@ -24,7 +24,7 @@ #ifndef _DVBVIDEO_H_ #define _DVBVIDEO_H_ -#include +//#include #ifdef __KERNEL__ #include