rockchip: i2c: enable i2c controller for rk3066 and rk3188
authorAlexander Kochetkov <al.kochet@gmail.com>
Mon, 26 Feb 2018 17:42:54 +0000 (20:42 +0300)
committerPhilipp Tomsich <philipp.tomsich@theobroma-systems.com>
Fri, 20 Jul 2018 23:55:25 +0000 (01:55 +0200)
rk3066 and rk3188 has two I2C controller implementations.
Current I2C driver wan't work with legacy implementation.
Switching between controllers is performed using a bit inside
GFR_SOC_CON1 register. The bit setting is performed by pinctrl
driver. The patch ask pinctrl to do settings.

Signed-off-by: Alexander Kochetkov <al.kochet@gmail.com>
Acked-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Reviewed-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
[fix warnings by including the rk3228 variant in the compatible-list]:
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
drivers/i2c/rk_i2c.c

index 001af668a8a37d533522cea050ce4a0d81bd8682..f9a5796b96b7bb19bac93daad5019ae602166bd1 100644 (file)
@@ -31,6 +31,18 @@ struct rk_i2c {
        unsigned int speed;
 };
 
+enum {
+       RK_I2C_LEGACY,
+       RK_I2C_NEW,
+};
+
+/**
+ * @controller_type: i2c controller type
+ */
+struct rk_i2c_soc_data {
+       int controller_type;
+};
+
 static inline void rk_i2c_get_div(int div, int *divh, int *divl)
 {
        *divl = div / 2;
@@ -378,9 +390,38 @@ static int rockchip_i2c_ofdata_to_platdata(struct udevice *bus)
 static int rockchip_i2c_probe(struct udevice *bus)
 {
        struct rk_i2c *priv = dev_get_priv(bus);
+       struct rk_i2c_soc_data *soc_data;
+       struct udevice *pinctrl;
+       int bus_nr;
+       int ret;
 
        priv->regs = dev_read_addr_ptr(bus);
 
+       soc_data = (struct rk_i2c_soc_data*)dev_get_driver_data(bus);
+
+       if (soc_data->controller_type == RK_I2C_LEGACY) {
+               ret = dev_read_alias_seq(bus, &bus_nr);
+               if (ret < 0) {
+                       debug("%s: Could not get alias for %s: %d\n",
+                        __func__, bus->name, ret);
+                       return ret;
+               }
+
+               ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
+               if (ret) {
+                       debug("%s: Cannot find pinctrl device\n", __func__);
+                       return ret;
+               }
+
+               /* pinctrl will switch I2C to new type */
+               ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_I2C0 + bus_nr);
+               if (ret) {
+                       debug("%s: Failed to switch I2C to new type %s: %d\n",
+                               __func__, bus->name, ret);
+                       return ret;
+               }
+       }
+
        return 0;
 }
 
@@ -389,12 +430,55 @@ static const struct dm_i2c_ops rockchip_i2c_ops = {
        .set_bus_speed  = rockchip_i2c_set_bus_speed,
 };
 
+static const struct rk_i2c_soc_data rk3066_soc_data = {
+       .controller_type = RK_I2C_LEGACY,
+};
+
+static const struct rk_i2c_soc_data rk3188_soc_data = {
+       .controller_type = RK_I2C_LEGACY,
+};
+
+static const struct rk_i2c_soc_data rk3228_soc_data = {
+       .controller_type = RK_I2C_NEW,
+};
+
+static const struct rk_i2c_soc_data rk3288_soc_data = {
+       .controller_type = RK_I2C_NEW,
+};
+
+static const struct rk_i2c_soc_data rk3328_soc_data = {
+       .controller_type = RK_I2C_NEW,
+};
+
+static const struct rk_i2c_soc_data rk3399_soc_data = {
+       .controller_type = RK_I2C_NEW,
+};
+
 static const struct udevice_id rockchip_i2c_ids[] = {
-       { .compatible = "rockchip,rk3066-i2c" },
-       { .compatible = "rockchip,rk3188-i2c" },
-       { .compatible = "rockchip,rk3288-i2c" },
-       { .compatible = "rockchip,rk3328-i2c" },
-       { .compatible = "rockchip,rk3399-i2c" },
+       {
+               .compatible = "rockchip,rk3066-i2c",
+               .data = (ulong)&rk3066_soc_data,
+       },
+       {
+               .compatible = "rockchip,rk3188-i2c",
+               .data = (ulong)&rk3188_soc_data,
+       },
+       {
+               .compatible = "rockchip,rk3228-i2c",
+               .data = (ulong)&rk3228_soc_data,
+       },
+       {
+               .compatible = "rockchip,rk3288-i2c",
+               .data = (ulong)&rk3288_soc_data,
+       },
+       {
+               .compatible = "rockchip,rk3328-i2c",
+               .data = (ulong)&rk3328_soc_data,
+       },
+       {
+               .compatible = "rockchip,rk3399-i2c",
+               .data = (ulong)&rk3399_soc_data,
+       },
        { }
 };