summaryrefslogtreecommitdiff
path: root/drivers/media/i2c/max9286.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2022-01-01 21:28:04 +0300
committerMauro Carvalho Chehab <mchehab@kernel.org>2023-01-22 11:11:11 +0300
commite332061bbe3ed2b38ebd8f148add894028311279 (patch)
treee438939a642c34b64586245fe0b34051462aa7c7 /drivers/media/i2c/max9286.c
parentcdcb186e364452cbe309db5a94ff5a510be234e2 (diff)
downloadlinux-e332061bbe3ed2b38ebd8f148add894028311279.tar.xz
media: i2c: max9286: Configure remote I2C speed from device tree
Read the maxim,i2c-clock-frequency DT property that specifies the speed of the remote I2C bus, and configure the MAX9286 accordingly. The remote serializers must all have a matching configuration. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'drivers/media/i2c/max9286.c')
-rw-r--r--drivers/media/i2c/max9286.c56
1 files changed, 47 insertions, 9 deletions
diff --git a/drivers/media/i2c/max9286.c b/drivers/media/i2c/max9286.c
index 91d4c9662389..6643b3690770 100644
--- a/drivers/media/i2c/max9286.c
+++ b/drivers/media/i2c/max9286.c
@@ -144,6 +144,11 @@ struct max9286_format_info {
u8 datatype;
};
+struct max9286_i2c_speed {
+ u32 rate;
+ u8 mstbt;
+};
+
struct max9286_source {
struct v4l2_subdev *sd;
struct fwnode_handle *fwnode;
@@ -177,6 +182,7 @@ struct max9286_priv {
/* The initial reverse control channel amplitude. */
u32 init_rev_chan_mv;
u32 rev_chan_mv;
+ u8 i2c_mstbt;
bool use_gpio_poc;
u32 gpio_poc[2];
@@ -254,6 +260,17 @@ static const struct max9286_format_info max9286_formats[] = {
},
};
+static const struct max9286_i2c_speed max9286_i2c_speeds[] = {
+ { .rate = 8470, .mstbt = MAX9286_I2CMSTBT_8KBPS },
+ { .rate = 28300, .mstbt = MAX9286_I2CMSTBT_28KBPS },
+ { .rate = 84700, .mstbt = MAX9286_I2CMSTBT_84KBPS },
+ { .rate = 105000, .mstbt = MAX9286_I2CMSTBT_105KBPS },
+ { .rate = 173000, .mstbt = MAX9286_I2CMSTBT_173KBPS },
+ { .rate = 339000, .mstbt = MAX9286_I2CMSTBT_339KBPS },
+ { .rate = 533000, .mstbt = MAX9286_I2CMSTBT_533KBPS },
+ { .rate = 837000, .mstbt = MAX9286_I2CMSTBT_837KBPS },
+};
+
/* -----------------------------------------------------------------------------
* I2C IO
*/
@@ -374,7 +391,7 @@ error:
static void max9286_configure_i2c(struct max9286_priv *priv, bool localack)
{
u8 config = MAX9286_I2CSLVSH_469NS_234NS | MAX9286_I2CSLVTO_1024US |
- MAX9286_I2CMSTBT_105KBPS;
+ priv->i2c_mstbt;
if (localack)
config |= MAX9286_I2CLOCACK;
@@ -1387,6 +1404,8 @@ static int max9286_parse_dt(struct max9286_priv *priv)
struct device_node *node = NULL;
unsigned int i2c_mux_mask = 0;
u32 reverse_channel_microvolt;
+ u32 i2c_clk_freq = 105000;
+ unsigned int i;
/* Balance the of_node_put() performed by of_find_node_by_name(). */
of_node_get(dev->of_node);
@@ -1477,6 +1496,23 @@ static int max9286_parse_dt(struct max9286_priv *priv)
}
of_node_put(node);
+ of_property_read_u32(dev->of_node, "maxim,i2c-remote-bus-hz",
+ &i2c_clk_freq);
+ for (i = 0; i < ARRAY_SIZE(max9286_i2c_speeds); ++i) {
+ const struct max9286_i2c_speed *speed = &max9286_i2c_speeds[i];
+
+ if (speed->rate == i2c_clk_freq) {
+ priv->i2c_mstbt = speed->mstbt;
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(max9286_i2c_speeds)) {
+ dev_err(dev, "Invalid %s value %u\n", "maxim,i2c-remote-bus-hz",
+ i2c_clk_freq);
+ return -EINVAL;
+ }
+
/*
* Parse the initial value of the reverse channel amplitude from
* the firmware interface and convert it to millivolts.
@@ -1550,10 +1586,16 @@ static int max9286_probe(struct i2c_client *client)
/* GPIO values default to high */
priv->gpio_state = BIT(0) | BIT(1);
+ ret = max9286_parse_dt(priv);
+ if (ret)
+ goto err_cleanup_dt;
+
priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable",
GPIOD_OUT_HIGH);
- if (IS_ERR(priv->gpiod_pwdn))
- return PTR_ERR(priv->gpiod_pwdn);
+ if (IS_ERR(priv->gpiod_pwdn)) {
+ ret = PTR_ERR(priv->gpiod_pwdn);
+ goto err_cleanup_dt;
+ }
gpiod_set_consumer_name(priv->gpiod_pwdn, "max9286-pwdn");
gpiod_set_value_cansleep(priv->gpiod_pwdn, 1);
@@ -1580,10 +1622,6 @@ static int max9286_probe(struct i2c_client *client)
if (ret)
goto err_powerdown;
- ret = max9286_parse_dt(priv);
- if (ret)
- goto err_cleanup_dt;
-
if (!priv->use_gpio_poc) {
ret = max9286_get_poc_supplies(priv);
if (ret)
@@ -1596,10 +1634,10 @@ static int max9286_probe(struct i2c_client *client)
return 0;
-err_cleanup_dt:
- max9286_cleanup_dt(priv);
err_powerdown:
gpiod_set_value_cansleep(priv->gpiod_pwdn, 0);
+err_cleanup_dt:
+ max9286_cleanup_dt(priv);
return ret;
}