]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
i2c: imx: add support for S32G2/S32G3 SoCs
authorCiprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
Mon, 4 Nov 2024 10:00:44 +0000 (12:00 +0200)
committerAndi Shyti <andi.shyti@kernel.org>
Sun, 17 Nov 2024 10:58:56 +0000 (11:58 +0100)
Some S32G2/S32G3 SoC I2C particularities exist
such as different <clock divider, register value> pairs.
Those are addressed by adding specific S32G2 and S32G3
compatible strings.

Co-developed-by: Ionut Vicovan <Ionut.Vicovan@nxp.com>
Signed-off-by: Ionut Vicovan <Ionut.Vicovan@nxp.com>
Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@oss.nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-imx.c

index e95aaab760c23e6671f5811ddc5e3e4424db9b62..0e1ce4fe1325b5e5ba7418997233b3d6a7d1f244 100644 (file)
@@ -733,13 +733,14 @@ config I2C_IMG
 
 config I2C_IMX
        tristate "IMX I2C interface"
-       depends on ARCH_MXC || ARCH_LAYERSCAPE || COLDFIRE || COMPILE_TEST
+       depends on ARCH_MXC || ARCH_LAYERSCAPE || ARCH_S32 || COLDFIRE \
+               || COMPILE_TEST
        select I2C_SLAVE
        help
          Say Y here if you want to use the IIC bus controller on
-         the Freescale i.MX/MXC, Layerscape or ColdFire processors.
+         the Freescale i.MX/MXC/S32G, Layerscape or ColdFire processors.
 
-         This driver can also be built as a module.  If so, the module
+         This driver can also be built as a module. If so, the module
          will be called i2c-imx.
 
 config I2C_IMX_LPI2C
index 862300ed1bde3bbda45c147230ff4d0b3133ccf2..f751d231ded87cf549bf14892421fc40c128bdf8 100644 (file)
@@ -17,7 +17,7 @@
  *     Copyright (C) 2008 Darius Augulis <darius.augulis at teltonika.lt>
  *
  *     Copyright 2013 Freescale Semiconductor, Inc.
- *     Copyright 2020 NXP
+ *     Copyright 2020, 2024 NXP
  *
  */
 
@@ -84,6 +84,7 @@
 
 #define IMX_I2C_REGSHIFT       2
 #define VF610_I2C_REGSHIFT     0
+#define S32G_I2C_REGSHIFT      0
 
 /* Bits of IMX I2C registers */
 #define I2SR_RXAK      0x01
@@ -165,9 +166,34 @@ static struct imx_i2c_clk_pair vf610_i2c_clk_div[] = {
        { 3840, 0x3F }, { 4096, 0x7B }, { 5120, 0x7D }, { 6144, 0x7E },
 };
 
+/* S32G2/S32G3 clock divider, register value pairs */
+static struct imx_i2c_clk_pair s32g2_i2c_clk_div[] = {
+       { 34,    0x00 }, { 36,    0x01 }, { 38,    0x02 }, { 40,    0x03 },
+       { 42,    0x04 }, { 44,    0x05 }, { 46,    0x06 }, { 48,    0x09 },
+       { 52,    0x0A }, { 54,    0x07 }, { 56,    0x0B }, { 60,    0x0C },
+       { 64,    0x0D }, { 68,    0x40 }, { 72,    0x0E }, { 76,    0x42 },
+       { 80,    0x12 }, { 84,    0x0F }, { 88,    0x13 }, { 96,    0x14 },
+       { 104,   0x15 }, { 108,   0x47 }, { 112,   0x19 }, { 120,   0x16 },
+       { 128,   0x1A }, { 136,   0x80 }, { 144,   0x17 }, { 152,   0x82 },
+       { 160,   0x1C }, { 168,   0x84 }, { 176,   0x1D }, { 192,   0x21 },
+       { 208,   0x1E }, { 216,   0x87 }, { 224,   0x22 }, { 240,   0x56 },
+       { 256,   0x1F }, { 288,   0x24 }, { 320,   0x25 }, { 336,   0x8F },
+       { 352,   0x93 }, { 356,   0x5D }, { 358,   0x98 }, { 384,   0x26 },
+       { 416,   0x56 }, { 448,   0x2A }, { 480,   0x27 }, { 512,   0x2B },
+       { 576,   0x2C }, { 640,   0x2D }, { 704,   0x9D }, { 768,   0x2E },
+       { 832,   0x9D }, { 896,   0x32 }, { 960,   0x2F }, { 1024,  0x33 },
+       { 1152,  0x34 }, { 1280,  0x35 }, { 1536,  0x36 }, { 1792,  0x3A },
+       { 1920,  0x37 }, { 2048,  0x3B }, { 2304,  0x74 }, { 2560,  0x3D },
+       { 3072,  0x3E }, { 3584,  0x7A }, { 3840,  0x3F }, { 4096,  0x7B },
+       { 4608,  0x7C }, { 5120,  0x7D }, { 6144,  0x7E }, { 7168,  0xBA },
+       { 7680,  0x7F }, { 8192,  0xBB }, { 9216,  0xBC }, { 10240, 0xBD },
+       { 12288, 0xBE }, { 15360, 0xBF },
+};
+
 enum imx_i2c_type {
        IMX1_I2C,
        IMX21_I2C,
+       S32G_I2C,
        VF610_I2C,
 };
 
@@ -277,7 +303,15 @@ static struct imx_i2c_hwdata vf610_i2c_hwdata = {
        .ndivs                  = ARRAY_SIZE(vf610_i2c_clk_div),
        .i2sr_clr_opcode        = I2SR_CLR_OPCODE_W1C,
        .i2cr_ien_opcode        = I2CR_IEN_OPCODE_0,
+};
 
+static const struct imx_i2c_hwdata s32g2_i2c_hwdata = {
+       .devtype                = S32G_I2C,
+       .regshift               = S32G_I2C_REGSHIFT,
+       .clk_div                = s32g2_i2c_clk_div,
+       .ndivs                  = ARRAY_SIZE(s32g2_i2c_clk_div),
+       .i2sr_clr_opcode        = I2SR_CLR_OPCODE_W1C,
+       .i2cr_ien_opcode        = I2CR_IEN_OPCODE_0,
 };
 
 static const struct platform_device_id imx_i2c_devtype[] = {
@@ -307,6 +341,7 @@ static const struct of_device_id i2c_imx_dt_ids[] = {
        { .compatible = "fsl,imx8mp-i2c", .data = &imx6_i2c_hwdata, },
        { .compatible = "fsl,imx8mq-i2c", .data = &imx6_i2c_hwdata, },
        { .compatible = "fsl,vf610-i2c", .data = &vf610_i2c_hwdata, },
+       { .compatible = "nxp,s32g2-i2c", .data = &s32g2_i2c_hwdata, },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, i2c_imx_dt_ids);