summaryrefslogtreecommitdiff
path: root/drivers/media/dvb/dvb-core
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2011-12-22 14:47:48 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-12-31 09:10:49 -0200
commita689e3657d7e82c2271008553c709fc79fb2e038 (patch)
tree88c1edf1deacd41733ce5b31566c6fd187a52e11 /drivers/media/dvb/dvb-core
parentbc9cd2736b34619b58961d506210fe0e6dfaa27d (diff)
[media] dvb-core: add support for a DVBv5 get_frontend() callback
Creates a DVBv5 get_frontend call, renaming the DVBv3 one to get_frontend_legacy(), while not all frontends are converted. After the conversion for all drivers, get_frontend_legacy() will be removed. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/dvb-core')
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c102
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h5
2 files changed, 82 insertions, 25 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 930868fc113..7246c914a70 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -139,6 +139,14 @@ struct dvb_frontend_private {
};
static void dvb_frontend_wakeup(struct dvb_frontend *fe);
+static int dtv_get_frontend(struct dvb_frontend *fe,
+ struct dtv_frontend_properties *c,
+ struct dvb_frontend_parameters *p_out);
+
+static bool has_get_frontend(struct dvb_frontend *fe)
+{
+ return fe->ops.get_frontend || fe->ops.get_frontend_legacy;
+}
static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
{
@@ -149,8 +157,8 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status)
dprintk ("%s\n", __func__);
- if ((status & FE_HAS_LOCK) && fe->ops.get_frontend)
- fe->ops.get_frontend(fe, &fepriv->parameters_out);
+ if ((status & FE_HAS_LOCK) && has_get_frontend(fe))
+ dtv_get_frontend(fe, NULL, &fepriv->parameters_out);
mutex_lock(&events->mtx);
@@ -1097,11 +1105,10 @@ static void dtv_property_cache_sync(struct dvb_frontend *fe,
/* Ensure the cached values are set correctly in the frontend
* legacy tuning structures, for the advanced tuning API.
*/
-static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
+static void dtv_property_legacy_params_sync(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
{
const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- struct dvb_frontend_private *fepriv = fe->frontend_priv;
- struct dvb_frontend_parameters *p = &fepriv->parameters_in;
p->frequency = c->frequency;
p->inversion = c->inversion;
@@ -1223,6 +1230,7 @@ static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
static void dtv_property_cache_submit(struct dvb_frontend *fe)
{
const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ struct dvb_frontend_private *fepriv = fe->frontend_priv;
/* For legacy delivery systems we don't need the delivery_system to
* be specified, but we populate the older structures from the cache
@@ -1231,7 +1239,7 @@ static void dtv_property_cache_submit(struct dvb_frontend *fe)
if(is_legacy_delivery_system(c->delivery_system)) {
dprintk("%s() legacy, modulation = %d\n", __func__, c->modulation);
- dtv_property_legacy_params_sync(fe);
+ dtv_property_legacy_params_sync(fe, &fepriv->parameters_in);
} else {
dprintk("%s() adv, modulation = %d\n", __func__, c->modulation);
@@ -1246,6 +1254,58 @@ static void dtv_property_cache_submit(struct dvb_frontend *fe)
}
}
+/**
+ * dtv_get_frontend - calls a callback for retrieving DTV parameters
+ * @fe: struct dvb_frontend pointer
+ * @c: struct dtv_frontend_properties pointer (DVBv5 cache)
+ * @p_out struct dvb_frontend_parameters pointer (DVBv3 FE struct)
+ *
+ * This routine calls either the DVBv3 or DVBv5 get_frontend call.
+ * If c is not null, it will update the DVBv5 cache struct pointed by it.
+ * If p_out is not null, it will update the DVBv3 params pointed by it.
+ */
+static int dtv_get_frontend(struct dvb_frontend *fe,
+ struct dtv_frontend_properties *c,
+ struct dvb_frontend_parameters *p_out)
+{
+ const struct dtv_frontend_properties *cache = &fe->dtv_property_cache;
+ struct dtv_frontend_properties tmp_cache;
+ struct dvb_frontend_parameters tmp_out;
+ bool fill_cache = (c != NULL);
+ bool fill_params = (p_out != NULL);
+ int r;
+
+ if (!p_out)
+ p_out = &tmp_out;
+
+ if (!c)
+ c = &tmp_cache;
+ else
+ memcpy(c, cache, sizeof(*c));
+
+ /* Then try the DVBv5 one */
+ if (fe->ops.get_frontend) {
+ r = fe->ops.get_frontend(fe, c);
+ if (unlikely(r < 0))
+ return r;
+ if (fill_params)
+ dtv_property_legacy_params_sync(fe, p_out);
+ return 0;
+ }
+
+ /* As no DVBv5 call exists, use the DVBv3 one */
+ if (fe->ops.get_frontend_legacy) {
+ r = fe->ops.get_frontend_legacy(fe, p_out);
+ if (unlikely(r < 0))
+ return r;
+ if (fill_cache)
+ dtv_property_cache_sync(fe, c, p_out);
+ return 0;
+ }
+
+ return -EOPNOTSUPP;
+}
+
static int dvb_frontend_ioctl_legacy(struct file *file,
unsigned int cmd, void *parg);
static int dvb_frontend_ioctl_properties(struct file *file,
@@ -1296,24 +1356,12 @@ static void dtv_set_default_delivery_caps(const struct dvb_frontend *fe, struct
}
static int dtv_property_process_get(struct dvb_frontend *fe,
+ const struct dtv_frontend_properties *c,
struct dtv_property *tvp,
struct file *file)
{
- const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- struct dvb_frontend_private *fepriv = fe->frontend_priv;
- struct dtv_frontend_properties cdetected;
int r;
- /*
- * If the driver implements a get_frontend function, then convert
- * detected parameters to S2API properties.
- */
- if (fe->ops.get_frontend) {
- cdetected = *c;
- dtv_property_cache_sync(fe, &cdetected, &fepriv->parameters_out);
- c = &cdetected;
- }
-
switch(tvp->cmd) {
case DTV_ENUM_DELSYS:
dtv_set_default_delivery_caps(fe, tvp);
@@ -1685,6 +1733,7 @@ static int dvb_frontend_ioctl_properties(struct file *file,
} else
if(cmd == FE_GET_PROPERTY) {
+ struct dtv_frontend_properties cache_out;
tvps = (struct dtv_properties __user *)parg;
@@ -1707,8 +1756,13 @@ static int dvb_frontend_ioctl_properties(struct file *file,
goto out;
}
+ /*
+ * Fills the cache out struct with the cache contents, plus
+ * the data retrieved from get_frontend/get_frontend_legacy.
+ */
+ dtv_get_frontend(fe, &cache_out, NULL);
for (i = 0; i < tvps->num; i++) {
- err = dtv_property_process_get(fe, tvp + i, file);
+ err = dtv_property_process_get(fe, &cache_out, tvp + i, file);
if (err < 0)
goto out;
(tvp + i)->result = err;
@@ -2008,10 +2062,10 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
break;
case FE_GET_FRONTEND:
- if (fe->ops.get_frontend) {
- err = fe->ops.get_frontend(fe, &fepriv->parameters_out);
- memcpy(parg, &fepriv->parameters_out, sizeof(struct dvb_frontend_parameters));
- }
+ err = dtv_get_frontend(fe, NULL, &fepriv->parameters_out);
+ if (err >= 0)
+ memcpy(parg, &fepriv->parameters_out,
+ sizeof(struct dvb_frontend_parameters));
break;
case FE_SET_FRONTEND_TUNE_MODE:
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 1810bab1fb8..7a7debef53d 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -256,6 +256,8 @@ struct analog_demod_ops {
int (*set_config)(struct dvb_frontend *fe, void *priv_cfg);
};
+struct dtv_frontend_properties;
+
struct dvb_frontend_ops {
struct dvb_frontend_info info;
@@ -284,7 +286,8 @@ struct dvb_frontend_ops {
int (*set_frontend)(struct dvb_frontend *fe);
int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings);
- int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
+ int (*get_frontend_legacy)(struct dvb_frontend *fe, struct dvb_frontend_parameters *params);
+ int (*get_frontend)(struct dvb_frontend *fe, struct dtv_frontend_properties *props);
int (*read_status)(struct dvb_frontend* fe, fe_status_t* status);
int (*read_ber)(struct dvb_frontend* fe, u32* ber);