diff options
author | Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com> | 2018-07-17 21:06:42 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-08-02 18:53:42 -0400 |
commit | 817dc4b579d897d3f645c11dc255f21642aa99df (patch) | |
tree | 742b8ac411f3037bf67864cdda2ff214a39b8278 /drivers | |
parent | 299c7007e93645067e1d2743f4e50156de78c4ff (diff) | |
download | linux-817dc4b579d897d3f645c11dc255f21642aa99df.tar.gz linux-817dc4b579d897d3f645c11dc255f21642aa99df.tar.bz2 linux-817dc4b579d897d3f645c11dc255f21642aa99df.zip |
media: helene: add I2C device probe function
This patch adds I2C probe function to use dvb_module_probe() with
this driver. And also support multiple delivery systems at the
same device.
Signed-off-by: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/dvb-frontends/helene.c | 88 | ||||
-rw-r--r-- | drivers/media/dvb-frontends/helene.h | 3 |
2 files changed, 87 insertions, 4 deletions
diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c index dc70fb684681..d7790cb98a0c 100644 --- a/drivers/media/dvb-frontends/helene.c +++ b/drivers/media/dvb-frontends/helene.c @@ -666,7 +666,7 @@ static int helene_set_params_s(struct dvb_frontend *fe) return 0; } -static int helene_set_params(struct dvb_frontend *fe) +static int helene_set_params_t(struct dvb_frontend *fe) { u8 data[MAX_WRITE_REGSIZE]; u32 frequency; @@ -835,6 +835,19 @@ static int helene_set_params(struct dvb_frontend *fe) return 0; } +static int helene_set_params(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + + if (p->delivery_system == SYS_DVBT || + p->delivery_system == SYS_DVBT2 || + p->delivery_system == SYS_ISDBT || + p->delivery_system == SYS_DVBC_ANNEX_A) + return helene_set_params_t(fe); + + return helene_set_params_s(fe); +} + static int helene_get_frequency(struct dvb_frontend *fe, u32 *frequency) { struct helene_priv *priv = fe->tuner_priv; @@ -843,7 +856,7 @@ static int helene_get_frequency(struct dvb_frontend *fe, u32 *frequency) return 0; } -static const struct dvb_tuner_ops helene_tuner_ops = { +static const struct dvb_tuner_ops helene_tuner_ops_t = { .info = { .name = "Sony HELENE Ter tuner", .frequency_min_hz = 1 * MHz, @@ -853,7 +866,7 @@ static const struct dvb_tuner_ops helene_tuner_ops = { .init = helene_init, .release = helene_release, .sleep = helene_sleep, - .set_params = helene_set_params, + .set_params = helene_set_params_t, .get_frequency = helene_get_frequency, }; @@ -871,6 +884,20 @@ static const struct dvb_tuner_ops helene_tuner_ops_s = { .get_frequency = helene_get_frequency, }; +static const struct dvb_tuner_ops helene_tuner_ops = { + .info = { + .name = "Sony HELENE Sat/Ter tuner", + .frequency_min_hz = 1 * MHz, + .frequency_max_hz = 2500 * MHz, + .frequency_step_hz = 25 * kHz, + }, + .init = helene_init, + .release = helene_release, + .sleep = helene_sleep, + .set_params = helene_set_params, + .get_frequency = helene_get_frequency, +}; + /* power-on tuner * call once after reset */ @@ -1035,7 +1062,7 @@ struct dvb_frontend *helene_attach(struct dvb_frontend *fe, if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - memcpy(&fe->ops.tuner_ops, &helene_tuner_ops, + memcpy(&fe->ops.tuner_ops, &helene_tuner_ops_t, sizeof(struct dvb_tuner_ops)); fe->tuner_priv = priv; dev_info(&priv->i2c->dev, @@ -1045,6 +1072,59 @@ struct dvb_frontend *helene_attach(struct dvb_frontend *fe, } EXPORT_SYMBOL(helene_attach); +static int helene_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct helene_config *config = client->dev.platform_data; + struct dvb_frontend *fe = config->fe; + struct device *dev = &client->dev; + struct helene_priv *priv; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->i2c_address = client->addr; + priv->i2c = client->adapter; + priv->set_tuner_data = config->set_tuner_priv; + priv->set_tuner = config->set_tuner_callback; + priv->xtal = config->xtal; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + if (helene_x_pon(priv) != 0) + return -EINVAL; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + memcpy(&fe->ops.tuner_ops, &helene_tuner_ops, + sizeof(struct dvb_tuner_ops)); + fe->tuner_priv = priv; + i2c_set_clientdata(client, priv); + + dev_info(dev, "Sony HELENE attached on addr=%x at I2C adapter %p\n", + priv->i2c_address, priv->i2c); + + return 0; +} + +static const struct i2c_device_id helene_id[] = { + { "helene", }, + {} +}; +MODULE_DEVICE_TABLE(i2c, helene_id); + +static struct i2c_driver helene_driver = { + .driver = { + .name = "helene", + }, + .probe = helene_probe, + .id_table = helene_id, +}; +module_i2c_driver(helene_driver); + MODULE_DESCRIPTION("Sony HELENE Sat/Ter tuner driver"); MODULE_AUTHOR("Abylay Ospan <aospan@netup.ru>"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb-frontends/helene.h b/drivers/media/dvb-frontends/helene.h index c9fc81c7e4e7..8562d01bc93e 100644 --- a/drivers/media/dvb-frontends/helene.h +++ b/drivers/media/dvb-frontends/helene.h @@ -39,6 +39,7 @@ enum helene_xtal { * @set_tuner_callback: Callback function that notifies the parent driver * which tuner is active now * @xtal: Cristal frequency as described by &enum helene_xtal + * @fe: Frontend for which connects this tuner */ struct helene_config { u8 i2c_address; @@ -46,6 +47,8 @@ struct helene_config { void *set_tuner_priv; int (*set_tuner_callback)(void *, int); enum helene_xtal xtal; + + struct dvb_frontend *fe; }; #if IS_REACHABLE(CONFIG_DVB_HELENE) |