mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00:00
[media] fc0012: rework attach() to check chip id and I/O errors
Signed-off-by: Antti Palosaari <crope@iki.fi> Acked-by: Hans-Frieder Vogt <hfvogt@gmx.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
3a98477200
commit
44ff69cd95
1 changed files with 49 additions and 10 deletions
|
@ -443,32 +443,71 @@ static const struct dvb_tuner_ops fc0012_tuner_ops = {
|
|||
struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, const struct fc0012_config *cfg)
|
||||
{
|
||||
struct fc0012_priv *priv = NULL;
|
||||
struct fc0012_priv *priv;
|
||||
int ret;
|
||||
u8 chip_id;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
|
||||
priv = kzalloc(sizeof(struct fc0012_priv), GFP_KERNEL);
|
||||
if (priv == NULL)
|
||||
return NULL;
|
||||
if (!priv) {
|
||||
ret = -ENOMEM;
|
||||
dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
|
||||
goto err;
|
||||
}
|
||||
|
||||
priv->i2c = i2c;
|
||||
priv->cfg = cfg;
|
||||
priv->i2c = i2c;
|
||||
|
||||
info("Fitipower FC0012 successfully attached.");
|
||||
/* check if the tuner is there */
|
||||
ret = fc0012_readreg(priv, 0x00, &chip_id);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
fe->tuner_priv = priv;
|
||||
dev_dbg(&i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id);
|
||||
|
||||
if (priv->cfg->loop_through)
|
||||
fc0012_writereg(priv, 0x09, 0x6f);
|
||||
switch (chip_id) {
|
||||
case 0xa1:
|
||||
break;
|
||||
default:
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
dev_info(&i2c->dev, "%s: Fitipower FC0012 successfully identified\n",
|
||||
KBUILD_MODNAME);
|
||||
|
||||
if (priv->cfg->loop_through) {
|
||||
ret = fc0012_writereg(priv, 0x09, 0x6f);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Clock out en or div?
|
||||
* For dual tuner configuration clearing bit [0] is required.
|
||||
*/
|
||||
if (priv->cfg->clock_out)
|
||||
fc0012_writereg(priv, 0x0b, 0x82);
|
||||
if (priv->cfg->clock_out) {
|
||||
ret = fc0012_writereg(priv, 0x0b, 0x82);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
fe->tuner_priv = priv;
|
||||
memcpy(&fe->ops.tuner_ops, &fc0012_tuner_ops,
|
||||
sizeof(struct dvb_tuner_ops));
|
||||
|
||||
err:
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
|
||||
if (ret) {
|
||||
dev_dbg(&i2c->dev, "%s: failed: %d\n", __func__, ret);
|
||||
kfree(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fe;
|
||||
}
|
||||
EXPORT_SYMBOL(fc0012_attach);
|
||||
|
|
Loading…
Reference in a new issue