#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/videodev.h>
-#include "tuner-driver.h"
#include "tuner-i2c.h"
#include "tda8290.h"
#include "tda827x.h"
static void tda829x_release(struct dvb_frontend *fe)
{
- if (fe->ops.tuner_ops.release)
- fe->ops.tuner_ops.release(fe);
+ struct tda8290_priv *priv = fe->analog_demod_priv;
+
+ /* only try to release the tuner if we've
+ * attached it from within this module */
+ if (priv->ver & (TDA18271 | TDA8275 | TDA8275A))
+ if (fe->ops.tuner_ops.release)
+ fe->ops.tuner_ops.release(fe);
kfree(fe->analog_demod_priv);
fe->analog_demod_priv = NULL;
}
+static struct tda18271_config tda829x_tda18271_config = {
+ .gate = TDA18271_GATE_ANALOG,
+};
+
static int tda829x_find_tuner(struct dvb_frontend *fe)
{
struct tda8290_priv *priv = fe->analog_demod_priv;
- struct analog_tuner_ops *ops = fe->ops.analog_demod_ops;
+ struct analog_demod_ops *analog_ops = &fe->ops.analog_ops;
int i, ret, tuners_found;
u32 tuner_addrs;
u8 data;
struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 };
- if (NULL == ops)
+ if (NULL == analog_ops->i2c_gate_ctrl)
return -EINVAL;
- ops->i2c_gate_ctrl(fe, 1);
+ analog_ops->i2c_gate_ctrl(fe, 1);
/* probe for tuner chip */
tuners_found = 0;
give a response now
*/
- ops->i2c_gate_ctrl(fe, 0);
+ analog_ops->i2c_gate_ctrl(fe, 0);
if (tuners_found > 1)
for (i = 0; i < tuners_found; i++) {
priv->tda827x_addr = tuner_addrs;
msg.addr = tuner_addrs;
- ops->i2c_gate_ctrl(fe, 1);
+ analog_ops->i2c_gate_ctrl(fe, 1);
ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
if (ret != 1) {
return -EREMOTEIO;
}
- if (data == 0x83) {
+ if ((data == 0x83) || (data == 0x84)) {
priv->ver |= TDA18271;
tda18271_attach(fe, priv->tda827x_addr,
- priv->i2c_props.adap);
+ priv->i2c_props.adap,
+ &tda829x_tda18271_config);
} else {
if ((data & 0x3c) == 0)
priv->ver |= TDA8275;
if (fe->ops.tuner_ops.sleep)
fe->ops.tuner_ops.sleep(fe);
- ops->i2c_gate_ctrl(fe, 0);
+ analog_ops->i2c_gate_ctrl(fe, 0);
return 0;
}
return -ENODEV;
}
-static struct analog_tuner_ops tda8290_tuner_ops = {
- .info = {
- .name = "TDA8290",
- },
+static struct analog_demod_ops tda8290_ops = {
.set_params = tda8290_set_params,
.has_signal = tda8290_has_signal,
.standby = tda8290_standby,
.i2c_gate_ctrl = tda8290_i2c_bridge,
};
-static struct analog_tuner_ops tda8295_tuner_ops = {
- .info = {
- .name = "TDA8295",
- },
+static struct analog_demod_ops tda8295_ops = {
.set_params = tda8295_set_params,
.has_signal = tda8295_has_signal,
.standby = tda8295_standby,
if (tda8290_probe(&priv->i2c_props) == 0) {
priv->ver = TDA8290;
- fe->ops.analog_demod_ops = &tda8290_tuner_ops;
+ memcpy(&fe->ops.analog_ops, &tda8290_ops,
+ sizeof(struct analog_demod_ops));
}
if (tda8295_probe(&priv->i2c_props) == 0) {
priv->ver = TDA8295;
- fe->ops.analog_demod_ops = &tda8295_tuner_ops;
+ memcpy(&fe->ops.analog_ops, &tda8295_ops,
+ sizeof(struct analog_demod_ops));
}
- if (tda829x_find_tuner(fe) < 0)
+ if ((!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) &&
+ (tda829x_find_tuner(fe) < 0))
goto fail;
switch (priv->ver) {
+ case TDA8290:
+ name = "tda8290";
+ break;
+ case TDA8295:
+ name = "tda8295";
+ break;
case TDA8290 | TDA8275:
name = "tda8290+75";
break;
}
tuner_info("type set to %s\n", name);
+ fe->ops.analog_ops.info.name = name;
+
if (priv->ver & TDA8290) {
tda8290_init_tuner(fe);
tda8290_init_if(fe);
fail:
tda829x_release(fe);
- fe->ops.analog_demod_ops = NULL;
return NULL;
}
EXPORT_SYMBOL_GPL(tda829x_attach);