[v2] media: helene: add I2C device probe function
Commit Message
This patch adds I2C probe function to use dvb_module_probe()
with this driver.
Signed-off-by: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>
---
Changes since v1:
- Add documents for dvb_frontend member of helene_config
---
drivers/media/dvb-frontends/helene.c | 88 ++++++++++++++++++++++++++--
drivers/media/dvb-frontends/helene.h | 3 +
2 files changed, 87 insertions(+), 4 deletions(-)
Comments
Hi Katsuhiro,
Thanks for patch.
What is the purpose to rework helene_set_params(_t|_s) ?
other part of this patch looks ok for me, but not tested due to lack
of spare time ;(
2018-05-16 4:37 GMT-04:00 Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>:
> This patch adds I2C probe function to use dvb_module_probe()
> with this driver.
>
> Signed-off-by: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>
>
> ---
>
> Changes since v1:
> - Add documents for dvb_frontend member of helene_config
> ---
> drivers/media/dvb-frontends/helene.c | 88 ++++++++++++++++++++++++++--
> 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 a0d0b53c91d7..04033f0c278b 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 = 1000000,
> @@ -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 = 500000,
> + .frequency_max = 1200000000,
> + .frequency_step = 1000,
> + },
> + .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
> */
> @@ -1032,7 +1059,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,
> @@ -1042,6 +1069,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)
> --
> 2.17.0
>
Hello Abylay,
> -----Original Message-----
> From: Abylay Ospan <aospan@netup.ru>
> Sent: Wednesday, May 16, 2018 7:54 PM
> To: Suzuki, Katsuhiro/?? ?? <suzuki.katsuhiro@socionext.com>
> Cc: Mauro Carvalho Chehab <mchehab@kernel.org>; linux-media
> <linux-media@vger.kernel.org>; Masami Hiramatsu <masami.hiramatsu@linaro.org>;
> Jassi Brar <jaswinder.singh@linaro.org>; linux-arm-kernel@lists.infradead.org;
> linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v2] media: helene: add I2C device probe function
>
> Hi Katsuhiro,
>
> Thanks for patch.
>
> What is the purpose to rework helene_set_params(_t|_s) ?
> other part of this patch looks ok for me, but not tested due to lack of spare time ;(
>
I'm using Socionext SC1501A (or MN88443x) ISDB-S/ISDB-T demodulator with this
tuner. This demodulator has 1 port, and can use ISDB-S or ISDB-T exclusively.
So I think I cannot use ISDB-S features of this tuner if I use helene_attach(),
and I cannot use ISDB-T if I use helene_attach_s() too.
Regards,
--
Katsuhiro Suzuki
>
> 2018-05-16 4:37 GMT-04:00 Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com
> <mailto:suzuki.katsuhiro@socionext.com> >:
>
>
> This patch adds I2C probe function to use dvb_module_probe()
> with this driver.
>
> Signed-off-by: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com
> <mailto:suzuki.katsuhiro@socionext.com> >
>
> ---
>
> Changes since v1:
> - Add documents for dvb_frontend member of helene_config
> ---
> drivers/media/dvb-frontends/helene.c | 88 ++++++++++++++++++++++++++--
> 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 a0d0b53c91d7..04033f0c278b 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 = 1000000,
> @@ -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 = 500000,
> + .frequency_max = 1200000000,
> + .frequency_step = 1000,
> + },
> + .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
> */
> @@ -1032,7 +1059,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,
> @@ -1042,6 +1069,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 <mailto: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)
> --
> 2.17.0
>
>
>
>
>
>
> --
>
> Abylay Ospan,
> NetUP Inc.
> http://www.netup.tv <http://www.netup.tv/>
@@ -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 = 1000000,
@@ -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 = 500000,
+ .frequency_max = 1200000000,
+ .frequency_step = 1000,
+ },
+ .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
*/
@@ -1032,7 +1059,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,
@@ -1042,6 +1069,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");
@@ -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)