summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <m.chehab@samsung.com>2014-05-16 10:55:55 -0300
committerChanho Park <chanho61.park@samsung.com>2014-08-08 15:23:20 +0900
commit70af01e95bc21a6dbe0fbe8a3efa13a2f37d837a (patch)
tree43e5203c4f96ea9439b8976ebf6ce78ec2fa0399
parentb12c60bba2823caeac4e05557aefb6ed716a53c4 (diff)
downloadlinux-3.10-70af01e95bc21a6dbe0fbe8a3efa13a2f37d837a.tar.gz
linux-3.10-70af01e95bc21a6dbe0fbe8a3efa13a2f37d837a.tar.bz2
linux-3.10-70af01e95bc21a6dbe0fbe8a3efa13a2f37d837a.zip
upstream: [media] m88ts2022: convert to Kernel I2C driver model
Convert driver from proprietary DVB driver model to standard I2C driver model. Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> Conflicts: drivers/media/tuners/m88ts2022.c Conflicts: drivers/media/tuners/m88ts2022.c
-rw-r--r--drivers/media/tuners/m88ts2022.c121
-rw-r--r--drivers/media/tuners/m88ts2022.h24
-rw-r--r--drivers/media/tuners/m88ts2022_priv.h4
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c25
4 files changed, 90 insertions, 84 deletions
diff --git a/drivers/media/tuners/m88ts2022.c b/drivers/media/tuners/m88ts2022.c
index 8e7a35d1cf9..40c42dec721 100644
--- a/drivers/media/tuners/m88ts2022.c
+++ b/drivers/media/tuners/m88ts2022.c
@@ -28,7 +28,7 @@ static int m88ts2022_wr_regs(struct m88ts2022_priv *priv,
u8 buf[MAX_WR_XFER_LEN];
struct i2c_msg msg[1] = {
{
- .addr = priv->cfg->i2c_addr,
+ .addr = priv->client->addr,
.flags = 0,
.len = 1 + len,
.buf = buf,
@@ -41,11 +41,11 @@ static int m88ts2022_wr_regs(struct m88ts2022_priv *priv,
buf[0] = reg;
memcpy(&buf[1], val, len);
- ret = i2c_transfer(priv->i2c, msg, 1);
+ ret = i2c_transfer(priv->client->adapter, msg, 1);
if (ret == 1) {
ret = 0;
} else {
- dev_warn(&priv->i2c->dev,
+ dev_warn(&priv->client->dev,
"%s: i2c wr failed=%d reg=%02x len=%d\n",
KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
@@ -64,12 +64,12 @@ static int m88ts2022_rd_regs(struct m88ts2022_priv *priv, u8 reg,
u8 buf[MAX_RD_XFER_LEN];
struct i2c_msg msg[2] = {
{
- .addr = priv->cfg->i2c_addr,
+ .addr = priv->client->addr,
.flags = 0,
.len = 1,
.buf = &reg,
}, {
- .addr = priv->cfg->i2c_addr,
+ .addr = priv->client->addr,
.flags = I2C_M_RD,
.len = len,
.buf = buf,
@@ -79,12 +79,12 @@ static int m88ts2022_rd_regs(struct m88ts2022_priv *priv, u8 reg,
if (WARN_ON(len > MAX_RD_LEN))
return -EINVAL;
- ret = i2c_transfer(priv->i2c, msg, 2);
+ ret = i2c_transfer(priv->client->adapter, msg, 2);
if (ret == 2) {
memcpy(val, buf, len);
ret = 0;
} else {
- dev_warn(&priv->i2c->dev,
+ dev_warn(&priv->client->dev,
"%s: i2c rd failed=%d reg=%02x len=%d\n",
KBUILD_MODNAME, ret, reg, len);
ret = -EREMOTEIO;
@@ -140,7 +140,7 @@ static int m88ts2022_cmd(struct dvb_frontend *fe,
};
for (i = 0; i < 2; i++) {
- dev_dbg(&priv->i2c->dev,
+ dev_dbg(&priv->client->dev,
"%s: i=%d op=%02x reg=%02x mask=%02x val=%02x\n",
__func__, i, op, reg, mask, val);
@@ -176,14 +176,14 @@ static int m88ts2022_set_params(struct dvb_frontend *fe)
unsigned int f_ref_khz, f_vco_khz, div_ref, div_out, pll_n, gdiv28;
u8 buf[3], u8tmp, cap_code, lpf_gm, lpf_mxdiv, div_max, div_min;
u16 u16tmp;
- dev_dbg(&priv->i2c->dev,
+ dev_dbg(&priv->client->dev,
"%s: frequency=%d symbol_rate=%d rolloff=%d\n",
__func__, c->frequency, c->symbol_rate, c->rolloff);
/*
* Integer-N PLL synthesizer
* kHz is used for all calculations to keep calculations within 32-bit
*/
- f_ref_khz = DIV_ROUND_CLOSEST(priv->cfg->clock, 1000);
+ f_ref_khz = DIV_ROUND_CLOSEST(priv->cfg.clock, 1000);
div_ref = DIV_ROUND_CLOSEST(f_ref_khz, 2000);
if (c->symbol_rate < 5000000)
@@ -226,7 +226,7 @@ static int m88ts2022_set_params(struct dvb_frontend *fe)
if (ret)
goto err;
- dev_dbg(&priv->i2c->dev,
+ dev_dbg(&priv->client->dev,
"%s: frequency=%u offset=%d f_vco_khz=%u pll_n=%u div_ref=%u div_out=%u\n",
__func__, priv->frequency_khz,
priv->frequency_khz - c->frequency, f_vco_khz, pll_n,
@@ -370,7 +370,7 @@ static int m88ts2022_set_params(struct dvb_frontend *fe)
goto err;
err:
if (ret)
- dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -393,7 +393,7 @@ static int m88ts2022_init(struct dvb_frontend *fe)
{0x24, 0x02},
{0x12, 0xa0},
};
- dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+ dev_dbg(&priv->client->dev, "%s:\n", __func__);
ret = m88ts2022_wr_reg(priv, 0x00, 0x01);
if (ret)
@@ -403,13 +403,13 @@ static int m88ts2022_init(struct dvb_frontend *fe)
if (ret)
goto err;
- switch (priv->cfg->clock_out) {
+ switch (priv->cfg.clock_out) {
case M88TS2022_CLOCK_OUT_DISABLED:
u8tmp = 0x60;
break;
case M88TS2022_CLOCK_OUT_ENABLED:
u8tmp = 0x70;
- ret = m88ts2022_wr_reg(priv, 0x05, priv->cfg->clock_out_div);
+ ret = m88ts2022_wr_reg(priv, 0x05, priv->cfg.clock_out_div);
if (ret)
goto err;
break;
@@ -424,7 +424,7 @@ static int m88ts2022_init(struct dvb_frontend *fe)
if (ret)
goto err;
- if (priv->cfg->loop_through)
+ if (priv->cfg.loop_through)
u8tmp = 0xec;
else
u8tmp = 0x6c;
@@ -440,7 +440,7 @@ static int m88ts2022_init(struct dvb_frontend *fe)
}
err:
if (ret)
- dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
@@ -448,21 +448,21 @@ static int m88ts2022_sleep(struct dvb_frontend *fe)
{
struct m88ts2022_priv *priv = fe->tuner_priv;
int ret;
- dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+ dev_dbg(&priv->client->dev, "%s:\n", __func__);
ret = m88ts2022_wr_reg(priv, 0x00, 0x00);
if (ret)
goto err;
err:
if (ret)
- dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
static int m88ts2022_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct m88ts2022_priv *priv = fe->tuner_priv;
- dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+ dev_dbg(&priv->client->dev, "%s:\n", __func__);
*frequency = priv->frequency_khz;
return 0;
@@ -471,7 +471,7 @@ static int m88ts2022_get_frequency(struct dvb_frontend *fe, u32 *frequency)
static int m88ts2022_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
{
struct m88ts2022_priv *priv = fe->tuner_priv;
- dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
+ dev_dbg(&priv->client->dev, "%s:\n", __func__);
*frequency = 0; /* Zero-IF */
return 0;
@@ -515,19 +515,10 @@ static int m88ts2022_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
*strength = (u16tmp - 59000) * 0xffff / (61500 - 59000);
err:
if (ret)
- dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
+ dev_dbg(&priv->client->dev, "%s: failed=%d\n", __func__, ret);
return ret;
}
-static int m88ts2022_release(struct dvb_frontend *fe)
-{
- struct m88ts2022_priv *priv = fe->tuner_priv;
- dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
-
- kfree(fe->tuner_priv);
- return 0;
-}
-
static const struct dvb_tuner_ops m88ts2022_tuner_ops = {
.info = {
.name = "Montage M88TS2022",
@@ -535,8 +526,6 @@ static const struct dvb_tuner_ops m88ts2022_tuner_ops = {
.frequency_max = 2150000,
},
- .release = m88ts2022_release,
-
.init = m88ts2022_init,
.sleep = m88ts2022_sleep,
.set_params = m88ts2022_set_params,
@@ -546,9 +535,11 @@ static const struct dvb_tuner_ops m88ts2022_tuner_ops = {
.get_rf_strength = m88ts2022_get_rf_strength,
};
-struct dvb_frontend *m88ts2022_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c, const struct m88ts2022_config *cfg)
+static int m88ts2022_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
+ struct m88ts2022_config *cfg = client->dev.platform_data;
+ struct dvb_frontend *fe = cfg->fe;
struct m88ts2022_priv *priv;
int ret;
u8 chip_id, u8tmp;
@@ -556,13 +547,12 @@ struct dvb_frontend *m88ts2022_attach(struct dvb_frontend *fe,
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
ret = -ENOMEM;
- dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
+ dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
goto err;
}
- priv->cfg = cfg;
- priv->i2c = i2c;
- priv->fe = fe;
+ memcpy(&priv->cfg, cfg, sizeof(struct m88ts2022_config));
+ priv->client = client;
/* check if the tuner is there */
ret = m88ts2022_rd_reg(priv, 0x00, &u8tmp);
@@ -587,7 +577,7 @@ struct dvb_frontend *m88ts2022_attach(struct dvb_frontend *fe,
if (ret)
goto err;
- dev_dbg(&priv->i2c->dev, "%s: chip_id=%02x\n", __func__, chip_id);
+ dev_dbg(&priv->client->dev, "%s: chip_id=%02x\n", __func__, chip_id);
switch (chip_id) {
case 0xc3:
@@ -597,13 +587,13 @@ struct dvb_frontend *m88ts2022_attach(struct dvb_frontend *fe,
goto err;
}
- switch (priv->cfg->clock_out) {
+ switch (priv->cfg.clock_out) {
case M88TS2022_CLOCK_OUT_DISABLED:
u8tmp = 0x60;
break;
case M88TS2022_CLOCK_OUT_ENABLED:
u8tmp = 0x70;
- ret = m88ts2022_wr_reg(priv, 0x05, priv->cfg->clock_out_div);
+ ret = m88ts2022_wr_reg(priv, 0x05, priv->cfg.clock_out_div);
if (ret)
goto err;
break;
@@ -618,7 +608,7 @@ struct dvb_frontend *m88ts2022_attach(struct dvb_frontend *fe,
if (ret)
goto err;
- if (priv->cfg->loop_through)
+ if (priv->cfg.loop_through)
u8tmp = 0xec;
else
u8tmp = 0x6c;
@@ -632,23 +622,52 @@ struct dvb_frontend *m88ts2022_attach(struct dvb_frontend *fe,
if (ret)
goto err;
- dev_info(&priv->i2c->dev,
+ dev_info(&priv->client->dev,
"%s: Montage M88TS2022 successfully identified\n",
KBUILD_MODNAME);
fe->tuner_priv = priv;
memcpy(&fe->ops.tuner_ops, &m88ts2022_tuner_ops,
sizeof(struct dvb_tuner_ops));
+
+ i2c_set_clientdata(client, priv);
+ return 0;
err:
- if (ret) {
- dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
- kfree(priv);
- return NULL;
- }
+ dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret);
+ kfree(priv);
+ return ret;
+}
+
+static int m88ts2022_remove(struct i2c_client *client)
+{
+ struct m88ts2022_priv *priv = i2c_get_clientdata(client);
+ struct dvb_frontend *fe = priv->cfg.fe;
+ dev_dbg(&client->dev, "%s:\n", __func__);
- return fe;
+ memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
+ fe->tuner_priv = NULL;
+ kfree(priv);
+
+ return 0;
}
-EXPORT_SYMBOL(m88ts2022_attach);
+
+static const struct i2c_device_id m88ts2022_id[] = {
+ {"m88ts2022", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, m88ts2022_id);
+
+static struct i2c_driver m88ts2022_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "m88ts2022",
+ },
+ .probe = m88ts2022_probe,
+ .remove = m88ts2022_remove,
+ .id_table = m88ts2022_id,
+};
+
+module_i2c_driver(m88ts2022_driver);
MODULE_DESCRIPTION("Montage M88TS2022 silicon tuner driver");
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
diff --git a/drivers/media/tuners/m88ts2022.h b/drivers/media/tuners/m88ts2022.h
index 4f82d181596..659fa1b1633 100644
--- a/drivers/media/tuners/m88ts2022.h
+++ b/drivers/media/tuners/m88ts2022.h
@@ -21,12 +21,6 @@
struct m88ts2022_config {
/*
- * I2C address
- * 0x60, ...
- */
- u8 i2c_addr;
-
- /*
* clock
* 16000000 - 32000000
*/
@@ -50,19 +44,11 @@ struct m88ts2022_config {
* 1 - 31
*/
u8 clock_out_div:5;
-};
-#if defined(CONFIG_MEDIA_TUNER_M88TS2022) || \
- (defined(CONFIG_MEDIA_TUNER_M88TS2022_MODULE) && defined(MODULE))
-extern struct dvb_frontend *m88ts2022_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c, const struct m88ts2022_config *cfg);
-#else
-static inline struct dvb_frontend *m88ts2022_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c, const struct m88ts2022_config *cfg)
-{
- pr_warn("%s: driver disabled by Kconfig\n", __func__);
- return NULL;
-}
-#endif
+ /*
+ * pointer to DVB frontend
+ */
+ struct dvb_frontend *fe;
+};
#endif
diff --git a/drivers/media/tuners/m88ts2022_priv.h b/drivers/media/tuners/m88ts2022_priv.h
index f885daef195..0363dd866a2 100644
--- a/drivers/media/tuners/m88ts2022_priv.h
+++ b/drivers/media/tuners/m88ts2022_priv.h
@@ -20,8 +20,8 @@
#include "m88ts2022.h"
struct m88ts2022_priv {
- const struct m88ts2022_config *cfg;
- struct i2c_adapter *i2c;
+ struct m88ts2022_config cfg;
+ struct i2c_client *client;
struct dvb_frontend *fe;
u32 frequency_khz;
};
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 97013372c70..be1749076f2 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -91,6 +91,7 @@ struct em28xx_dvb {
struct semaphore pll_mutex;
bool dont_attach_fe1;
int lna_gpio;
+ struct i2c_client *i2c_client_tuner;
};
@@ -826,11 +827,6 @@ static const struct m88ds3103_config pctv_461e_m88ds3103_config = {
.agc = 0x99,
};
-static const struct m88ts2022_config em28xx_m88ts2022_config = {
- .i2c_addr = 0x60,
- .clock = 27000000,
-};
-
/* ------------------------------------------------------------------ */
static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev)
@@ -1383,6 +1379,11 @@ static int em28xx_dvb_init(struct em28xx *dev)
{
/* demod I2C adapter */
struct i2c_adapter *i2c_adapter;
+ struct i2c_board_info info;
+ struct m88ts2022_config m88ts2022_config = {
+ .clock = 27000000,
+ };
+ memset(&info, 0, sizeof(struct i2c_board_info));
/* attach demod */
dvb->fe[0] = dvb_attach(m88ds3103_attach,
@@ -1395,13 +1396,12 @@ static int em28xx_dvb_init(struct em28xx *dev)
}
/* attach tuner */
- if (!dvb_attach(m88ts2022_attach, dvb->fe[0],
- i2c_adapter,
- &em28xx_m88ts2022_config)) {
- dvb_frontend_detach(dvb->fe[0]);
- result = -ENODEV;
- goto out_free;
- }
+ m88ts2022_config.fe = dvb->fe[0];
+ strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE);
+ info.addr = 0x60;
+ info.platform_data = &m88ts2022_config;
+ request_module("m88ts2022");
+ dvb->i2c_client_tuner = i2c_new_device(i2c_adapter, &info);
/* delegate signal strength measurement to tuner */
dvb->fe[0]->ops.read_signal_strength =
@@ -1488,6 +1488,7 @@ static int em28xx_dvb_fini(struct em28xx *dev)
prevent_sleep(&dvb->fe[1]->ops);
}
+ i2c_release_client(dvb->i2c_client_tuner);
em28xx_unregister_dvb(dvb);
kfree(dvb);
dev->dvb = NULL;