[media] rtl2832: convert driver to I2C binding
Convert that driver to I2C driver model. Legacy DVB binding is left also for later removal... Tested-by: Benjamin Larsson <benjamin@southpole.se> Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
c97da15411
commit
c2c8386f82
3 changed files with 119 additions and 0 deletions
|
@ -1183,6 +1183,114 @@ static struct dvb_frontend_ops rtl2832_ops = {
|
|||
.i2c_gate_ctrl = rtl2832_i2c_gate_ctrl,
|
||||
};
|
||||
|
||||
static int rtl2832_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct rtl2832_platform_data *pdata = client->dev.platform_data;
|
||||
const struct rtl2832_config *config = pdata->config;
|
||||
struct i2c_adapter *i2c = client->adapter;
|
||||
struct rtl2832_priv *priv;
|
||||
int ret;
|
||||
u8 tmp;
|
||||
|
||||
dev_dbg(&client->dev, "\n");
|
||||
|
||||
/* Caller really need to provide pointer for frontend we create. */
|
||||
if (pdata->dvb_frontend == NULL) {
|
||||
dev_err(&client->dev, "frontend pointer not defined\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* allocate memory for the internal state */
|
||||
priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
|
||||
if (priv == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* setup the priv */
|
||||
priv->client = client;
|
||||
priv->i2c = i2c;
|
||||
priv->tuner = config->tuner;
|
||||
priv->sleeping = true;
|
||||
memcpy(&priv->cfg, config, sizeof(struct rtl2832_config));
|
||||
INIT_DELAYED_WORK(&priv->i2c_gate_work, rtl2832_i2c_gate_work);
|
||||
|
||||
/* create muxed i2c adapter for demod itself */
|
||||
priv->i2c_adapter = i2c_add_mux_adapter(i2c, &i2c->dev, priv, 0, 0, 0,
|
||||
rtl2832_select, NULL);
|
||||
if (priv->i2c_adapter == NULL) {
|
||||
ret = -ENODEV;
|
||||
goto err_kfree;
|
||||
}
|
||||
|
||||
/* check if the demod is there */
|
||||
ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
|
||||
if (ret)
|
||||
goto err_i2c_del_mux_adapter;
|
||||
|
||||
/* create muxed i2c adapter for demod tuner bus */
|
||||
priv->i2c_adapter_tuner = i2c_add_mux_adapter(i2c, &i2c->dev, priv,
|
||||
0, 1, 0, rtl2832_select, rtl2832_deselect);
|
||||
if (priv->i2c_adapter_tuner == NULL) {
|
||||
ret = -ENODEV;
|
||||
goto err_i2c_del_mux_adapter;
|
||||
}
|
||||
|
||||
/* create dvb_frontend */
|
||||
memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
|
||||
priv->fe.ops.release = NULL;
|
||||
priv->fe.demodulator_priv = priv;
|
||||
i2c_set_clientdata(client, priv);
|
||||
*pdata->dvb_frontend = &priv->fe;
|
||||
|
||||
dev_info(&client->dev, "Realtek RTL2832 successfully attached\n");
|
||||
return 0;
|
||||
err_i2c_del_mux_adapter:
|
||||
i2c_del_mux_adapter(priv->i2c_adapter);
|
||||
err_kfree:
|
||||
kfree(priv);
|
||||
err:
|
||||
dev_dbg(&client->dev, "failed=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtl2832_remove(struct i2c_client *client)
|
||||
{
|
||||
struct rtl2832_priv *priv = i2c_get_clientdata(client);
|
||||
|
||||
dev_dbg(&client->dev, "\n");
|
||||
|
||||
cancel_delayed_work_sync(&priv->i2c_gate_work);
|
||||
|
||||
i2c_del_mux_adapter(priv->i2c_adapter_tuner);
|
||||
|
||||
i2c_del_mux_adapter(priv->i2c_adapter);
|
||||
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id rtl2832_id_table[] = {
|
||||
{"rtl2832", 0},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, rtl2832_id_table);
|
||||
|
||||
static struct i2c_driver rtl2832_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "rtl2832",
|
||||
},
|
||||
.probe = rtl2832_probe,
|
||||
.remove = rtl2832_remove,
|
||||
.id_table = rtl2832_id_table,
|
||||
};
|
||||
|
||||
module_i2c_driver(rtl2832_driver);
|
||||
|
||||
MODULE_AUTHOR("Thomas Mair <mair.thomas86@gmail.com>");
|
||||
MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -50,6 +50,16 @@ struct rtl2832_config {
|
|||
u8 tuner;
|
||||
};
|
||||
|
||||
struct rtl2832_platform_data {
|
||||
const struct rtl2832_config *config;
|
||||
|
||||
/*
|
||||
* frontend
|
||||
* returned by driver
|
||||
*/
|
||||
struct dvb_frontend **dvb_frontend;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_DVB_RTL2832)
|
||||
struct dvb_frontend *rtl2832_attach(
|
||||
const struct rtl2832_config *cfg,
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/i2c-mux.h>
|
||||
|
||||
struct rtl2832_priv {
|
||||
struct i2c_client *client;
|
||||
struct i2c_adapter *i2c;
|
||||
struct i2c_adapter *i2c_adapter;
|
||||
struct i2c_adapter *i2c_adapter_tuner;
|
||||
|
|
Loading…
Reference in a new issue