summaryrefslogtreecommitdiff
path: root/drivers/media/dvb-core/dvb_frontend.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-07-05 18:59:36 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2018-08-02 18:10:48 -0400
commitf1b1eabff0eb3fc46b06668de8174c0f23b271fd (patch)
treeeb4e9ec56be3792965fda7b00760911bd0086efc /drivers/media/dvb-core/dvb_frontend.c
parenta3f90c75b833caeff123499e13e0e31cbecf7d5b (diff)
media: dvb: represent min/max/step/tolerance freqs in Hz
Right now, satellite frontend drivers specify frequencies in kHz, while terrestrial/cable ones specify in Hz. That's confusing for developers. However, the main problem is that universal frontends capable of handling both satellite and non-satelite delivery systems are appearing. We end by needing to hack the drivers in order to support such hybrid frontends. So, convert everything to specify frontend frequencies in Hz. Tested-by: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/dvb-core/dvb_frontend.c')
-rw-r--r--drivers/media/dvb-core/dvb_frontend.c84
1 files changed, 59 insertions, 25 deletions
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 75e95b56f8b3..fe0fae482ba4 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -894,11 +894,28 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
}
static void dvb_frontend_get_frequency_limits(struct dvb_frontend *fe,
- u32 *freq_min, u32 *freq_max)
+ u32 *freq_min, u32 *freq_max,
+ u32 *tolerance)
{
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- __u32 tuner_min = fe->ops.tuner_ops.info.frequency_min_hz;
- __u32 tuner_max = fe->ops.tuner_ops.info.frequency_max_hz;
+ u32 tuner_min = fe->ops.tuner_ops.info.frequency_min_hz;
+ u32 tuner_max = fe->ops.tuner_ops.info.frequency_max_hz;
+ u32 frontend_min = fe->ops.info.frequency_min_hz;
+ u32 frontend_max = fe->ops.info.frequency_max_hz;
+
+ *freq_min = max(frontend_min, tuner_min);
+
+ if (frontend_max == 0)
+ *freq_max = tuner_max;
+ else if (tuner_max == 0)
+ *freq_max = frontend_max;
+ else
+ *freq_max = min(frontend_max, tuner_max);
+
+ if (*freq_min == 0 || *freq_max == 0)
+ dev_warn(fe->dvb->device,
+ "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n",
+ fe->dvb->num, fe->id);
/* If the standard is for satellite, convert frequencies to kHz */
switch (c->delivery_system) {
@@ -906,26 +923,35 @@ static void dvb_frontend_get_frequency_limits(struct dvb_frontend *fe,
case SYS_DVBS2:
case SYS_TURBO:
case SYS_ISDBS:
- tuner_max /= kHz;
- tuner_min /= kHz;
+ *freq_min /= kHz;
+ *freq_max /= kHz;
+ if (tolerance)
+ *tolerance = fe->ops.info.frequency_tolerance_hz / kHz;
+
break;
default:
+ if (tolerance)
+ *tolerance = fe->ops.info.frequency_tolerance_hz;
break;
}
+}
- *freq_min = max(fe->ops.info.frequency_min, tuner_min);
-
- if (fe->ops.info.frequency_max == 0)
- *freq_max = tuner_max;
- else if (tuner_max == 0)
- *freq_max = fe->ops.info.frequency_max;
- else
- *freq_max = min(fe->ops.info.frequency_max, tuner_max);
+static u32 dvb_frontend_get_stepsize(struct dvb_frontend *fe)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ u32 step = fe->ops.info.frequency_stepsize_hz;
+ switch (c->delivery_system) {
+ case SYS_DVBS:
+ case SYS_DVBS2:
+ case SYS_TURBO:
+ case SYS_ISDBS:
+ step /= kHz;
+ break;
+ default:
+ break;
+ }
- if (*freq_min == 0 || *freq_max == 0)
- dev_warn(fe->dvb->device,
- "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n",
- fe->dvb->num, fe->id);
+ return step;
}
static int dvb_frontend_check_parameters(struct dvb_frontend *fe)
@@ -935,7 +961,7 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe)
u32 freq_max;
/* range check: frequency */
- dvb_frontend_get_frequency_limits(fe, &freq_min, &freq_max);
+ dvb_frontend_get_frequency_limits(fe, &freq_min, &freq_max, NULL);
if ((freq_min && c->frequency < freq_min) ||
(freq_max && c->frequency > freq_max)) {
dev_warn(fe->dvb->device, "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n",
@@ -2261,8 +2287,8 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
case SYS_ISDBT:
case SYS_DTMB:
fepriv->min_delay = HZ / 20;
- fepriv->step_size = fe->ops.info.frequency_stepsize * 2;
- fepriv->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
+ fepriv->step_size = dvb_frontend_get_stepsize(fe) * 2;
+ fepriv->max_drift = (dvb_frontend_get_stepsize(fe) * 2) + 1;
break;
default:
/*
@@ -2391,9 +2417,17 @@ static int dvb_frontend_handle_ioctl(struct file *file,
case FE_GET_INFO: {
struct dvb_frontend_info *info = parg;
-
- memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info));
- dvb_frontend_get_frequency_limits(fe, &info->frequency_min, &info->frequency_max);
+ memset(info, 0, sizeof(*info));
+
+ strcpy(info->name, fe->ops.info.name);
+ info->symbol_rate_min = fe->ops.info.symbol_rate_min;
+ info->symbol_rate_max = fe->ops.info.symbol_rate_max;
+ info->symbol_rate_tolerance = fe->ops.info.symbol_rate_tolerance;
+ info->caps = fe->ops.info.caps;
+ info->frequency_stepsize = dvb_frontend_get_stepsize(fe);
+ dvb_frontend_get_frequency_limits(fe, &info->frequency_min,
+ &info->frequency_max,
+ &info->frequency_tolerance);
/*
* Associate the 4 delivery systems supported by DVBv3
@@ -2423,10 +2457,10 @@ static int dvb_frontend_handle_ioctl(struct file *file,
dev_err(fe->dvb->device,
"%s: doesn't know how to handle a DVBv3 call to delivery system %i\n",
__func__, c->delivery_system);
- fe->ops.info.type = FE_OFDM;
+ info->type = FE_OFDM;
}
dev_dbg(fe->dvb->device, "%s: current delivery system on cache: %d, V3 type: %d\n",
- __func__, c->delivery_system, fe->ops.info.type);
+ __func__, c->delivery_system, info->type);
/* Set CAN_INVERSION_AUTO bit on in other than oneshot mode */
if (!(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT))