summaryrefslogtreecommitdiff
path: root/drivers/i2c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/designware_i2c.c20
-rw-r--r--drivers/i2c/meson_i2c.c30
2 files changed, 39 insertions, 11 deletions
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index 63e40823f1..9ccc2411a6 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -34,7 +34,7 @@ static struct dw_scl_sda_cfg byt_config = {
struct dw_i2c {
struct i2c_regs *regs;
struct dw_scl_sda_cfg *scl_sda_cfg;
- struct reset_ctl reset_ctl;
+ struct reset_ctl_bulk resets;
};
#ifdef CONFIG_SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED
@@ -562,16 +562,22 @@ static int designware_i2c_probe(struct udevice *bus)
priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus);
}
- ret = reset_get_by_name(bus, "i2c", &priv->reset_ctl);
+ ret = reset_get_bulk(bus, &priv->resets);
if (ret)
- pr_info("reset_get_by_name() failed: %d\n", ret);
-
- if (&priv->reset_ctl)
- reset_deassert(&priv->reset_ctl);
+ dev_warn(bus, "Can't get reset: %d\n", ret);
+ else
+ reset_deassert_bulk(&priv->resets);
return __dw_i2c_init(priv->regs, 0, 0);
}
+static int designware_i2c_remove(struct udevice *dev)
+{
+ struct dw_i2c *priv = dev_get_priv(dev);
+
+ return reset_release_bulk(&priv->resets);
+}
+
static int designware_i2c_bind(struct udevice *dev)
{
static int num_cards;
@@ -613,6 +619,8 @@ U_BOOT_DRIVER(i2c_designware) = {
.bind = designware_i2c_bind,
.probe = designware_i2c_probe,
.priv_auto_alloc_size = sizeof(struct dw_i2c),
+ .remove = designware_i2c_remove,
+ .flags = DM_FLAG_OS_PREPARE,
.ops = &designware_i2c_ops,
};
diff --git a/drivers/i2c/meson_i2c.c b/drivers/i2c/meson_i2c.c
index 7d06d95cf3..ee59bac123 100644
--- a/drivers/i2c/meson_i2c.c
+++ b/drivers/i2c/meson_i2c.c
@@ -41,7 +41,12 @@ struct i2c_regs {
u32 tok_rdata1;
};
+struct meson_i2c_data {
+ unsigned char div_factor;
+};
+
struct meson_i2c {
+ const struct meson_i2c_data *data;
struct clk clk;
struct i2c_regs *regs;
struct i2c_msg *msg; /* Current I2C message */
@@ -229,7 +234,7 @@ static int meson_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
if (IS_ERR_VALUE(clk_rate))
return -EINVAL;
- div = DIV_ROUND_UP(clk_rate, speed * 4);
+ div = DIV_ROUND_UP(clk_rate, speed * i2c->data->div_factor);
/* clock divider has 12 bits */
if (div >= (1 << 12)) {
@@ -253,6 +258,8 @@ static int meson_i2c_probe(struct udevice *bus)
struct meson_i2c *i2c = dev_get_priv(bus);
int ret;
+ i2c->data = (const struct meson_i2c_data *)dev_get_driver_data(bus);
+
ret = clk_get_by_index(bus, 0, &i2c->clk);
if (ret < 0)
return ret;
@@ -272,11 +279,24 @@ static const struct dm_i2c_ops meson_i2c_ops = {
.set_bus_speed = meson_i2c_set_bus_speed,
};
+static const struct meson_i2c_data i2c_meson6_data = {
+ .div_factor = 4,
+};
+
+static const struct meson_i2c_data i2c_gxbb_data = {
+ .div_factor = 4,
+};
+
+static const struct meson_i2c_data i2c_axg_data = {
+ .div_factor = 3,
+};
+
static const struct udevice_id meson_i2c_ids[] = {
- { .compatible = "amlogic,meson6-i2c" },
- { .compatible = "amlogic,meson-gx-i2c" },
- { .compatible = "amlogic,meson-gxbb-i2c" },
- { }
+ {.compatible = "amlogic,meson6-i2c", .data = (ulong)&i2c_meson6_data},
+ {.compatible = "amlogic,meson-gx-i2c", .data = (ulong)&i2c_gxbb_data},
+ {.compatible = "amlogic,meson-gxbb-i2c", .data = (ulong)&i2c_gxbb_data},
+ {.compatible = "amlogic,meson-axg-i2c", .data = (ulong)&i2c_axg_data},
+ {}
};
U_BOOT_DRIVER(i2c_meson) = {