This is a rework of the patch posted by Anssi Hannula some time ago (http://www.spinics.net/lists/linux-dvb/msg26174.html).
It allows an unpatched application such as gnutv to access cards that
only have new api drivers. The example I have tested is the TT-3200 S2
driver in Manu's multiproto tree. The patch requires that the new
driver has the default modulation type for old api access to be set in
the .type field of the its frontend info structure. For example for the
stb0889 frontend this is. --- stb0899_drv.c.orig 2008-09-04 17:57:23.000000000 +0000 +++ stb0899_drv.c 2008-09-04 17:58:54.000000000 +0000 @@ -2036,6 +2036,7 @@ .info = { .name = "STB0899 Multistandard", + .type = FE_QPSK, /* default for old API */ }, .release = stb0899_release, The main patch to be applied is wholly to dvb_frontend.c and is given at the end of this message. I would appreciate if people who are more familiar with this environment than I am could verify that the approach is correct. Sorry about the inline patches but I am cutting and pasting from a terminal into a Linux box which is the wrong side of a firewall. Roger --- dvb_frontend.c.orig 2008-09-01 12:24:49.000000000 +0000 +++ dvb_frontend.c 2008-09-05 10:43:22.000000000 +0000 @@ -1646,20 +1646,61 @@ } memcpy(&fepriv->parameters, parg, sizeof (struct dvb_frontend_parameters)); - memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings)); - memcpy(&fetunesettings.parameters, parg, sizeof (struct dvb_frontend_parameters)); - - /* force auto frequency inversion if requested */ - if (dvb_force_auto_inversion) { - fepriv->parameters.inversion = INVERSION_AUTO; - fetunesettings.parameters.inversion = INVERSION_AUTO; - } - if (fe->ops.info.type == FE_OFDM) { + if (fe->legacy) { + memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings)); + memcpy(&fetunesettings.parameters, parg, sizeof (struct dvb_frontend_parameters)); + + /* force auto frequency inversion if requested */ + if (dvb_force_auto_inversion) { + fepriv->parameters.inversion = INVERSION_AUTO; + fetunesettings.parameters.inversion = INVERSION_AUTO; + } /* without hierarchical coding code_rate_LP is irrelevant, * so we tolerate the otherwise invalid FEC_NONE setting */ - if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE && - fepriv->parameters.u.ofdm.code_rate_LP == FEC_NONE) - fepriv->parameters.u.ofdm.code_rate_LP = FEC_AUTO; + if (fe->ops.info.type == FE_OFDM) { + if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE && + fepriv->parameters.u.ofdm.code_rate_LP == FEC_NONE) + fepriv->parameters.u.ofdm.code_rate_LP = FEC_AUTO; + } + } else { + enum dvbfe_delsys delsys; + if (olddrv_to_newapi(fe, &fepriv->fe_params, &fepriv->parameters, fe->ops.info.type) == -EINVAL) + printk("%s: ERROR !!! Converting Old parameters --> New parameters\n", __func__); + memset(&fetunesettings, 0, sizeof (struct dvb_frontend_tune_settings)); + memcpy(&fetunesettings.fe_params, &fepriv->fe_params, sizeof (struct dvbfe_params)); + + /* Request the search algorithm to search */ + fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; + + /* force auto frequency inversion if requested */ + if (dvb_force_auto_inversion) { + fepriv->fe_params.inversion = DVBFE_INVERSION_AUTO; + fetunesettings.fe_params.inversion = DVBFE_INVERSION_AUTO; + } + + /* set the delivery system to the default one */ + switch(fe->ops.info.type) { + case FE_OFDM: + /* without hierachical coding code_rate_LP is irrelevant, + * so we tolerate the otherwise invalid FEC_NONE setting */ + if (fepriv->fe_params.delsys.dvbt.hierarchy == DVBFE_HIERARCHY_OFF && + fepriv->fe_params.delsys.dvbt.code_rate_LP == DVBFE_FEC_NONE) + fepriv->fe_params.delsys.dvbt.code_rate_LP = DVBFE_FEC_AUTO; + delsys = DVBFE_DELSYS_DVBT; + break; + case FE_QAM: + delsys = DVBFE_DELSYS_DVBC; + break; + case FE_ATSC: + delsys = DVBFE_DELSYS_ATSC; + break; + case FE_QPSK: + default: + delsys = DVBFE_DELSYS_DVBS; + break; + } + if (fe->ops.set_delsys) + fe->ops.set_delsys(fe, delsys); } /* get frontend-specific tuning settings */ @@ -1717,9 +1758,19 @@ } case FE_GET_FRONTEND: - if (fe->ops.get_frontend) { - memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters)); - err = fe->ops.get_frontend(fe, (struct dvb_frontend_parameters*) parg); + if (fe->legacy) { + if (fe->ops.get_frontend) { + memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters)); + err = fe->ops.get_frontend(fe, (struct dvb_frontend_parameters*) parg); + } + } else { + if (fe->ops.get_params) { + struct dvbfe_params temporary_params; + memcpy(&temporary_params, &fepriv->fe_params, sizeof (struct dvbfe_params)); + err = fe->ops.get_params(fe, &temporary_params); + if (newapi_to_olddrv(&temporary_params, (struct dvb_frontend_parameters*) parg, fepriv->delsys) == -EINVAL) + printk("%s: ERROR !!! Converting New parameters --> Old parameters\n", __func__); + } } break; |
_______________________________________________ linux-dvb mailing list linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb