summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
Diffstat (limited to 'linux')
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_frontend.h1
-rw-r--r--linux/drivers/media/video/tda8290.c23
-rw-r--r--linux/drivers/media/video/tea5761.c64
-rw-r--r--linux/drivers/media/video/tea5767.c63
-rw-r--r--linux/drivers/media/video/tuner-core.c32
-rw-r--r--linux/drivers/media/video/tuner-simple.c64
6 files changed, 154 insertions, 93 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
index 757cbfb1c..663d61f7d 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/linux/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -92,6 +92,7 @@ struct dvb_tuner_ops {
#define TUNER_STATUS_LOCKED 1
#define TUNER_STATUS_STEREO 2
int (*get_status)(struct dvb_frontend *fe, u32 *status);
+ int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength);
/** These are provided seperately from set_params in order to facilitate silicon
* tuners which require sophisticated tuning loops, controlling each parameter seperately. */
diff --git a/linux/drivers/media/video/tda8290.c b/linux/drivers/media/video/tda8290.c
index fc55c6122..e00b3516b 100644
--- a/linux/drivers/media/video/tda8290.c
+++ b/linux/drivers/media/video/tda8290.c
@@ -557,27 +557,35 @@ static int tda8290_set_params(struct dvb_frontend *fe,
static int tda8290_has_signal(struct dvb_frontend *fe)
{
struct tda8290_priv *priv = fe->tuner_priv;
+ int ret;
unsigned char i2c_get_afc[1] = { 0x1B };
unsigned char afc = 0;
+ /* for now, report based on afc status */
tuner_i2c_xfer_send(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc));
tuner_i2c_xfer_recv(&priv->i2c_props, &afc, 1);
- return (afc & 0x80)? 65535:0;
+
+ ret = (afc & 0x80) ? 65535 : 0;
+
+ tuner_dbg("AFC status: %d\n", ret);
+
+ return ret;
}
static int tda8290_get_status(struct dvb_frontend *fe, u32 *status)
{
- struct tda8290_priv *priv = fe->tuner_priv;
-
- int signal = tda8290_has_signal(fe);
*status = 0;
- /* for now, report based on afc status */
- if (signal)
+ if (tda8290_has_signal(fe))
*status = TUNER_STATUS_LOCKED;
- tuner_dbg("tda8290: AFC status: %d\n", signal);
+ return 0;
+}
+
+static int tda8290_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ *strength = tda8290_has_signal(fe);
return 0;
}
@@ -660,6 +668,7 @@ static struct dvb_tuner_ops tda8290_tuner_ops = {
.release = tda8290_release,
.get_frequency = tda8290_get_frequency,
.get_status = tda8290_get_status,
+ .get_rf_strength = tda8290_get_rf_strength,
};
struct dvb_frontend *tda8290_attach(struct dvb_frontend *fe,
diff --git a/linux/drivers/media/video/tea5761.c b/linux/drivers/media/video/tea5761.c
index 3b661d8dc..d5f83818d 100644
--- a/linux/drivers/media/video/tea5761.c
+++ b/linux/drivers/media/video/tea5761.c
@@ -178,49 +178,66 @@ static int set_radio_freq(struct dvb_frontend *fe,
return 0;
}
-static int tea5761_signal(struct dvb_frontend *fe)
+static int tea5761_read_status(struct dvb_frontend *fe, char *buffer)
{
- unsigned char buffer[16];
- int rc;
struct tea5761_priv *priv = fe->tuner_priv;
+ int rc;
- memset(buffer, 0, sizeof(buffer));
- if (16 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 16)))
- tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+ memset(buffer, 0, 16);
+ if (16 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 16))) {
+ tuner_warn("i2c i/o error: rc == %d (should be 16)\n", rc);
+ return -EREMOTEIO;
+ }
- return ((buffer[9] & TEA5761_TUNCHECK_LEV_MASK) << (13 - 4));
+ return 0;
}
-static int tea5761_stereo(struct dvb_frontend *fe)
+static inline int tea5761_signal(struct dvb_frontend *fe, const char *buffer)
{
- unsigned char buffer[16];
- int rc;
struct tea5761_priv *priv = fe->tuner_priv;
- memset(buffer, 0, sizeof(buffer));
- if (16 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 16)))
- tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+ int signal = ((buffer[9] & TEA5761_TUNCHECK_LEV_MASK) << (13 - 4));
+
+ tuner_dbg("Signal strength: %d\n", signal);
- rc = buffer[9] & TEA5761_TUNCHECK_STEREO;
+ return signal;
+}
- tuner_dbg("TEA5761 radio ST GET = %02x\n", rc);
+static inline int tea5761_stereo(struct dvb_frontend *fe, const char *buffer)
+{
+ struct tea5761_priv *priv = fe->tuner_priv;
- return (rc ? V4L2_TUNER_SUB_STEREO : 0);
+ int stereo = buffer[9] & TEA5761_TUNCHECK_STEREO;
+
+ tuner_dbg("Radio ST GET = %02x\n", stereo);
+
+ return (stereo ? V4L2_TUNER_SUB_STEREO : 0);
}
static int tea5761_get_status(struct dvb_frontend *fe, u32 *status)
{
- struct tea5761_priv *priv = fe->tuner_priv;
- int signal = tea5761_signal(fe);
+ unsigned char buffer[16];
*status = 0;
- if (signal)
- *status = TUNER_STATUS_LOCKED;
- if (tea5761_stereo(fe))
- *status |= TUNER_STATUS_STEREO;
+ if (0 == tea5761_read_status(fe, buffer)) {
+ if (tea5761_signal(fe, buffer))
+ *status = TUNER_STATUS_LOCKED;
+ if (tea5761_stereo(fe, buffer))
+ *status |= TUNER_STATUS_STEREO;
+ }
+
+ return 0;
+}
+
+static int tea5761_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ unsigned char buffer[16];
+
+ *strength = 0;
- tuner_dbg("tea5761: Signal strength: %d\n", signal);
+ if (0 == tea5761_read_status(fe, buffer))
+ *strength = tea5761_signal(fe, buffer);
return 0;
}
@@ -272,6 +289,7 @@ static struct dvb_tuner_ops tea5761_tuner_ops = {
.release = tea5761_release,
.get_frequency = tea5761_get_frequency,
.get_status = tea5761_get_status,
+ .get_rf_strength = tea5761_get_rf_strength,
};
struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
diff --git a/linux/drivers/media/video/tea5767.c b/linux/drivers/media/video/tea5767.c
index 1fc1844b8..3726f1e11 100644
--- a/linux/drivers/media/video/tea5767.c
+++ b/linux/drivers/media/video/tea5767.c
@@ -268,48 +268,66 @@ static int set_radio_freq(struct dvb_frontend *fe,
return 0;
}
-static int tea5767_signal(struct dvb_frontend *fe)
+static int tea5767_read_status(struct dvb_frontend *fe, char *buffer)
{
- unsigned char buffer[5];
- int rc;
struct tea5767_priv *priv = fe->tuner_priv;
+ int rc;
- memset(buffer, 0, sizeof(buffer));
- if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5)))
+ memset(buffer, 0, 5);
+ if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5))) {
tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+ return -EREMOTEIO;
+ }
- return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8);
+ return 0;
}
-static int tea5767_stereo(struct dvb_frontend *fe)
+static inline int tea5767_signal(struct dvb_frontend *fe, const char *buffer)
{
- unsigned char buffer[5];
- int rc;
struct tea5767_priv *priv = fe->tuner_priv;
- memset(buffer, 0, sizeof(buffer));
- if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5)))
- tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+ int signal = ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8);
+
+ tuner_dbg("Signal strength: %d\n", signal);
+
+ return signal;
+}
- rc = buffer[2] & TEA5767_STEREO_MASK;
+static inline int tea5767_stereo(struct dvb_frontend *fe, const char *buffer)
+{
+ struct tea5767_priv *priv = fe->tuner_priv;
- tuner_dbg("radio ST GET = %02x\n", rc);
+ int stereo = buffer[2] & TEA5767_STEREO_MASK;
- return ((buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO : 0);
+ tuner_dbg("Radio ST GET = %02x\n", stereo);
+
+ return (stereo ? V4L2_TUNER_SUB_STEREO : 0);
}
static int tea5767_get_status(struct dvb_frontend *fe, u32 *status)
{
- struct tea5767_priv *priv = fe->tuner_priv;
- int signal = tea5767_signal(fe);
+ unsigned char buffer[5];
+
*status = 0;
- if (signal)
- *status = TUNER_STATUS_LOCKED;
- if (tea5767_stereo(fe))
- *status |= TUNER_STATUS_STEREO;
+ if (0 == tea5767_read_status(fe, buffer)) {
+ if (tea5767_signal(fe, buffer))
+ *status = TUNER_STATUS_LOCKED;
+ if (tea5767_stereo(fe, buffer))
+ *status |= TUNER_STATUS_STEREO;
+ }
+
+ return 0;
+}
+
+static int tea5767_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ unsigned char buffer[5];
+
+ *strength = 0;
- tuner_dbg("tea5767: Signal strength: %d\n", signal);
+ if (0 == tea5767_read_status(fe, buffer))
+ *strength = tea5767_signal(fe, buffer);
return 0;
}
@@ -433,6 +451,7 @@ static struct dvb_tuner_ops tea5767_tuner_ops = {
.release = tea5767_release,
.get_frequency = tea5767_get_frequency,
.get_status = tea5767_get_status,
+ .get_rf_strength = tea5767_get_rf_strength,
};
struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c
index 142367f4e..4a3ccd81b 100644
--- a/linux/drivers/media/video/tuner-core.c
+++ b/linux/drivers/media/video/tuner-core.c
@@ -135,6 +135,17 @@ static void fe_standby(struct tuner *t)
fe_tuner_ops->sleep(&t->fe);
}
+static int fe_has_signal(struct tuner *t)
+{
+ struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
+ u16 strength;
+
+ if (fe_tuner_ops->get_rf_strength)
+ fe_tuner_ops->get_rf_strength(&t->fe, &strength);
+
+ return strength;
+}
+
/* Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz */
static void set_tv_freq(struct i2c_client *c, unsigned int freq)
{
@@ -358,6 +369,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
t->ops.set_radio_freq = fe_set_freq;
t->ops.standby = fe_standby;
t->ops.release = fe_release;
+ t->ops.has_signal = fe_has_signal;
}
tuner_info("type set to %s\n", t->i2c.name);
@@ -873,12 +885,10 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
u32 tuner_status;
fe_tuner_ops->get_status(&t->fe, &tuner_status);
- if (tuner_status & TUNER_STATUS_STEREO)
- vt->flags |= VIDEO_TUNER_STEREO_ON;
- else
- vt->flags &= ~VIDEO_TUNER_STEREO_ON;
- vt->signal = tuner_status & TUNER_STATUS_LOCKED
- ? 65535 : 0;
+ if (tuner_status & TUNER_STATUS_STEREO)
+ vt->flags |= VIDEO_TUNER_STEREO_ON;
+ else
+ vt->flags &= ~VIDEO_TUNER_STEREO_ON;
} else {
if (t->ops.is_stereo) {
if (t->ops.is_stereo(t))
@@ -888,9 +898,10 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
vt->flags &=
~VIDEO_TUNER_STEREO_ON;
}
- if (t->ops.has_signal)
- vt->signal = t->ops.has_signal(t);
}
+ if (t->ops.has_signal)
+ vt->signal = t->ops.has_signal(t);
+
vt->flags |= VIDEO_TUNER_LOW; /* Allow freqs at 62.5 Hz */
vt->rangelow = radio_range[0] * 16000;
@@ -1014,15 +1025,14 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
fe_tuner_ops->get_status(&t->fe, &tuner_status);
tuner->rxsubchans = (tuner_status & TUNER_STATUS_STEREO) ?
V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
- tuner->signal = tuner_status & TUNER_STATUS_LOCKED ? 65535 : 0;
} else {
if (t->ops.is_stereo) {
tuner->rxsubchans = t->ops.is_stereo(t) ?
V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
}
- if (t->ops.has_signal)
- tuner->signal = t->ops.has_signal(t);
}
+ if (t->ops.has_signal)
+ tuner->signal = t->ops.has_signal(t);
tuner->capability |=
V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
tuner->audmode = t->audmode;
diff --git a/linux/drivers/media/video/tuner-simple.c b/linux/drivers/media/video/tuner-simple.c
index 8ece12ca9..e3247174e 100644
--- a/linux/drivers/media/video/tuner-simple.c
+++ b/linux/drivers/media/video/tuner-simple.c
@@ -110,7 +110,7 @@ struct tuner_simple_priv {
/* ---------------------------------------------------------------------- */
-static int tuner_getstatus(struct dvb_frontend *fe)
+static int tuner_read_status(struct dvb_frontend *fe)
{
struct tuner_simple_priv *priv = fe->tuner_priv;
unsigned char byte;
@@ -121,63 +121,66 @@ static int tuner_getstatus(struct dvb_frontend *fe)
return byte;
}
-static int tuner_signal(struct dvb_frontend *fe)
+static inline int tuner_signal(const int status)
{
- return (tuner_getstatus(fe) & TUNER_SIGNAL) << 13;
+ return (status & TUNER_SIGNAL) << 13;
}
-static int tuner_stereo(struct dvb_frontend *fe)
+static inline int tuner_stereo(const int type, const int status)
{
- struct tuner_simple_priv *priv = fe->tuner_priv;
-
- int stereo, status;
-
- status = tuner_getstatus(fe);
-
- switch (priv->type) {
+ switch (type) {
case TUNER_PHILIPS_FM1216ME_MK3:
case TUNER_PHILIPS_FM1236_MK3:
case TUNER_PHILIPS_FM1256_IH3:
case TUNER_LG_NTSC_TAPE:
- stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
- break;
+ return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
default:
- stereo = status & TUNER_STEREO;
+ return status & TUNER_STEREO;
}
-
- return stereo;
}
-#if 0 /* unused */
-static int tuner_islocked (struct i2c_client *c)
+static inline int tuner_islocked(const int status)
{
- return (tuner_getstatus (c) & TUNER_FL);
+ return (status & TUNER_FL);
}
-static int tuner_afcstatus (struct i2c_client *c)
+static inline int tuner_afcstatus(const int status)
{
- return (tuner_getstatus (c) & TUNER_AFC) - 2;
+ return (status & TUNER_AFC) - 2;
}
-static int tuner_mode (struct i2c_client *c)
+#if 0 /* unused */
+static inline int tuner_mode(const int status)
{
- return (tuner_getstatus (c) & TUNER_MODE) >> 3;
+ return (status & TUNER_MODE) >> 3;
}
#endif
static int simple_get_status(struct dvb_frontend *fe, u32 *status)
{
struct tuner_simple_priv *priv = fe->tuner_priv;
- int signal = tuner_signal(fe);
+ int tuner_status = tuner_read_status(fe);
*status = 0;
- if (signal)
+ if (tuner_islocked(tuner_status))
*status = TUNER_STATUS_LOCKED;
- if (tuner_stereo(fe))
+ if (tuner_stereo(priv->type, tuner_status))
*status |= TUNER_STATUS_STEREO;
- tuner_dbg("tuner-simple: Signal strength: %d\n", signal);
+ tuner_dbg("AFC Status: %d\n", tuner_afcstatus(tuner_status));
+
+ return 0;
+}
+
+static int simple_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ struct tuner_simple_priv *priv = fe->tuner_priv;
+ int signal = tuner_signal(tuner_read_status(fe));
+
+ *strength = signal;
+
+ tuner_dbg("Signal strength: %d\n", signal);
return 0;
}
@@ -623,9 +626,10 @@ static struct dvb_tuner_ops simple_tuner_ops = {
},
#endif
.set_analog_params = simple_set_params,
- .release = simple_release,
- .get_frequency = simple_get_frequency,
- .get_status = simple_get_status,
+ .release = simple_release,
+ .get_frequency = simple_get_frequency,
+ .get_status = simple_get_status,
+ .get_rf_strength = simple_get_rf_strength,
};
struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,