Hello Simon,
        Sorry, do you have time to check v2 patch?

Ryan Chen

> -----Original Message-----
> From: Ryan Chen <ryan_c...@aspeedtech.com>
> Sent: Wednesday, January 11, 2023 2:53 PM
> To: Heiko Schocher <h...@denx.de>; Ryan Chen <ryan_c...@aspeedtech.com>;
> BMC-SW <bmc...@aspeedtech.com>; u-boot@lists.denx.de
> Subject: [PATCH v2 1/1] i2c:aspeed:support ast2600 i2c new register mode
> driver
> 
> Add i2c new register mode driver to support AST2600 i2c new register mode.
> AST2600 i2c controller have legacy and new register mode. The new register
> mode have global register support 4 base clock for scl clock selection, and 
> new
> clock divider mode.
> 
> Signed-off-by: ryan_chen <ryan_c...@aspeedtech.com>
> ---
>  MAINTAINERS               |   6 +
>  drivers/i2c/Kconfig       |  10 +
>  drivers/i2c/Makefile      |   1 +
>  drivers/i2c/ast2600_i2c.c | 375
> ++++++++++++++++++++++++++++++++++++++
>  drivers/i2c/ast2600_i2c.h | 120 ++++++++++++
>  5 files changed, 512 insertions(+)
>  create mode 100644 drivers/i2c/ast2600_i2c.c  create mode 100644
> drivers/i2c/ast2600_i2c.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 3fc4cd0f12..1cf54f0b4e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -769,6 +769,12 @@ S:       Maintained
>  F:   drivers/pci/pcie_phytium.c
>  F:   arch/arm/dts/phytium-durian.dts
> 
> +ASPEED AST2600 I2C DRIVER
> +M:   Ryan Chen <ryan_c...@aspeedtech.com>
> +R:   Aspeed BMC SW team <bmc...@aspeedtech.com>
> +S:   Maintained
> +F:   drivers/i2c/ast2600_i2c.c
> +
>  ASPEED FMC SPI DRIVER
>  M:   Chin-Ting Kuo <chin-ting_...@aspeedtech.com>
>  M:   Cédric Le Goater <c...@kaod.org>
> diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index
> 08b6c7bdcc..77e2a1c4c0 100644
> --- a/drivers/i2c/Kconfig
> +++ b/drivers/i2c/Kconfig
> @@ -221,6 +221,16 @@ config SYS_I2C_DW
>         controller is used in various SoCs, e.g. the ST SPEAr, Altera
>         SoCFPGA, Synopsys ARC700 and some Intel x86 SoCs.
> 
> +config SYS_I2C_AST2600
> +    bool "AST2600 I2C Controller"
> +    depends on DM_I2C && ARCH_ASPEED
> +    help
> +      Say yes here to select AST2600 I2C Host Controller. The driver
> +      support AST2600 I2C new mode register. This I2C controller supports:
> +      _Standard-mode (up to 100 kHz)
> +      _Fast-mode (up to 400 kHz)
> +      _Fast-mode Plus (up to 1 MHz)
> +
>  config SYS_I2C_ASPEED
>       bool "Aspeed I2C Controller"
>       depends on DM_I2C && ARCH_ASPEED
> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index
> 920aafb91c..89db2d8e37 100644
> --- a/drivers/i2c/Makefile
> +++ b/drivers/i2c/Makefile
> @@ -12,6 +12,7 @@ obj-$(CONFIG_$(SPL_)I2C_CROS_EC_LDO) +=
> cros_ec_ldo.o
> 
>  obj-$(CONFIG_$(SPL_)SYS_I2C_LEGACY) += i2c_core.o
>  obj-$(CONFIG_SYS_I2C_ASPEED) += ast_i2c.o
> +obj-$(CONFIG_SYS_I2C_AST2600) += ast2600_i2c.o
>  obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o
>  obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o
>  obj-$(CONFIG_SYS_I2C_CA) += i2c-cortina.o diff --git
> a/drivers/i2c/ast2600_i2c.c b/drivers/i2c/ast2600_i2c.c new file mode 100644
> index 0000000000..0fad30b5a2
> --- /dev/null
> +++ b/drivers/i2c/ast2600_i2c.c
> @@ -0,0 +1,375 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright ASPEED Technology Inc.
> + */
> +#include <common.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <fdtdec.h>
> +#include <i2c.h>
> +#include <log.h>
> +#include <regmap.h>
> +#include <reset.h>
> +#include <asm/io.h>
> +#include <linux/iopoll.h>
> +#include "ast2600_i2c.h"
> +
> +/* Device private data */
> +struct ast2600_i2c_priv {
> +     struct clk clk;
> +     struct ast2600_i2c_regs *regs;
> +     void __iomem *global;
> +};
> +
> +static int ast2600_i2c_read_data(struct ast2600_i2c_priv *priv, u8 chip_addr,
> +                              u8 *buffer, size_t len, bool send_stop) {
> +     int rx_cnt, ret = 0;
> +     u32 cmd, isr;
> +
> +     for (rx_cnt = 0; rx_cnt < len; rx_cnt++, buffer++) {
> +             cmd = I2CM_PKT_EN | I2CM_PKT_ADDR(chip_addr) |
> +                   I2CM_RX_CMD;
> +             if (!rx_cnt)
> +                     cmd |= I2CM_START_CMD;
> +
> +             if ((len - 1) == rx_cnt)
> +                     cmd |= I2CM_RX_CMD_LAST;
> +
> +             if (send_stop && ((len - 1) == rx_cnt))
> +                     cmd |= I2CM_STOP_CMD;
> +
> +             writel(cmd, &priv->regs->cmd_sts);
> +
> +             ret = readl_poll_timeout(&priv->regs->isr, isr,
> +                                      isr & I2CM_PKT_DONE,
> +                                      I2C_TIMEOUT_US);
> +             if (ret)
> +                     return -ETIMEDOUT;
> +
> +             *buffer =
> +                     I2CC_GET_RX_BUFF(readl(&priv->regs->trx_buff));
> +
> +             writel(I2CM_PKT_DONE, &priv->regs->isr);
> +
> +             if (isr & I2CM_TX_NAK)
> +                     return -EREMOTEIO;
> +     }
> +
> +     return 0;
> +}
> +
> +static int ast2600_i2c_write_data(struct ast2600_i2c_priv *priv, u8 
> chip_addr,
> +                               u8 *buffer, size_t len, bool send_stop) {
> +     int tx_cnt, ret = 0;
> +     u32 cmd, isr;
> +
> +     if (!len) {
> +             cmd = I2CM_PKT_EN | I2CM_PKT_ADDR(chip_addr) |
> +                   I2CM_START_CMD;
> +             writel(cmd, &priv->regs->cmd_sts);
> +             ret = readl_poll_timeout(&priv->regs->isr, isr,
> +                                      isr & I2CM_PKT_DONE,
> +                                      I2C_TIMEOUT_US);
> +             if (ret)
> +                     return -ETIMEDOUT;
> +
> +             writel(I2CM_PKT_DONE, &priv->regs->isr);
> +
> +             if (isr & I2CM_TX_NAK)
> +                     return -EREMOTEIO;
> +     }
> +
> +     for (tx_cnt = 0; tx_cnt < len; tx_cnt++, buffer++) {
> +             cmd = I2CM_PKT_EN | I2CM_PKT_ADDR(chip_addr);
> +             cmd |= I2CM_TX_CMD;
> +
> +             if (!tx_cnt)
> +                     cmd |= I2CM_START_CMD;
> +
> +             if (send_stop && ((len - 1) == tx_cnt))
> +                     cmd |= I2CM_STOP_CMD;
> +
> +             writel(*buffer, &priv->regs->trx_buff);
> +             writel(cmd, &priv->regs->cmd_sts);
> +             ret = readl_poll_timeout(&priv->regs->isr, isr,
> +                                      isr & I2CM_PKT_DONE,
> +                                      I2C_TIMEOUT_US);
> +             if (ret)
> +                     return -ETIMEDOUT;
> +
> +             writel(I2CM_PKT_DONE, &priv->regs->isr);
> +
> +             if (isr & I2CM_TX_NAK)
> +                     return -EREMOTEIO;
> +     }
> +
> +     return 0;
> +}
> +
> +static int ast2600_i2c_deblock(struct udevice *dev) {
> +     struct ast2600_i2c_priv *priv = dev_get_priv(dev);
> +     u32 csr = readl(&priv->regs->cmd_sts);
> +     u32 isr;
> +     int ret;
> +
> +     /* reinit */
> +     writel(0, &priv->regs->fun_ctrl);
> +     /* Enable Master Mode. Assuming single-master */
> +     writel(I2CC_BUS_AUTO_RELEASE | I2CC_MASTER_EN |
> +                    I2CC_MULTI_MASTER_DIS,
> +            &priv->regs->fun_ctrl);
> +
> +     csr = readl(&priv->regs->cmd_sts);
> +
> +     if (!(csr & I2CC_SDA_LINE_STS) &&
> +         (csr & I2CC_SCL_LINE_STS)) {
> +             debug("Bus stuck (%x), attempting recovery\n", csr);
> +             writel(I2CM_RECOVER_CMD_EN, &priv->regs->cmd_sts);
> +             ret = readl_poll_timeout(&priv->regs->isr, isr,
> +                                      isr & (I2CM_BUS_RECOVER_FAIL |
> +                                             I2CM_BUS_RECOVER),
> +                                      I2C_TIMEOUT_US);
> +             writel(~0, &priv->regs->isr);
> +             if (ret)
> +                     return -EREMOTEIO;
> +     }
> +
> +     return 0;
> +}
> +
> +static int ast2600_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
> +int nmsgs) {
> +     struct ast2600_i2c_priv *priv = dev_get_priv(dev);
> +     int ret;
> +
> +     if (readl(&priv->regs->trx_buff) & I2CC_BUS_BUSY_STS)
> +             return -EREMOTEIO;
> +
> +     for (; nmsgs > 0; nmsgs--, msg++) {
> +             if (msg->flags & I2C_M_RD) {
> +                     debug("i2c_read: chip=0x%x, len=0x%x, flags=0x%x\n",
> +                           msg->addr, msg->len, msg->flags);
> +                     ret = ast2600_i2c_read_data(priv, msg->addr, msg->buf,
> +                                                 msg->len, (nmsgs == 1));
> +             } else {
> +                     debug("i2c_write: chip=0x%x, len=0x%x, flags=0x%x\n",
> +                           msg->addr, msg->len, msg->flags);
> +                     ret = ast2600_i2c_write_data(priv, msg->addr, msg->buf,
> +                                                  msg->len, (nmsgs == 1));
> +             }
> +             if (ret) {
> +                     debug("%s: error (%d)\n", __func__, ret);
> +                     return -EREMOTEIO;
> +             }
> +     }
> +
> +     return 0;
> +}
> +
> +static int ast2600_i2c_set_speed(struct udevice *dev, unsigned int
> +speed) {
> +     struct ast2600_i2c_priv *priv = dev_get_priv(dev);
> +     unsigned long base_clk1, base_clk2, base_clk3, base_clk4;
> +     int multiply = 10;
> +     int baseclk_idx;
> +     u32 clk_div_reg;
> +     u32 apb_clk;
> +     u32 scl_low;
> +     u32 scl_high;
> +     int divisor;
> +     int inc = 0;
> +     u32 data;
> +
> +     debug("Setting speed for I2C%d to <%u>\n", dev->seq_, speed);
> +     if (!speed) {
> +             debug("No valid speed specified\n");
> +             return -EINVAL;
> +     }
> +
> +     apb_clk = clk_get_rate(&priv->clk);
> +
> +     clk_div_reg = readl(priv->global + I2CG_CLK_DIV_CTRL);
> +
> +     base_clk1 = (apb_clk * multiply) / (((GET_CLK1_DIV(clk_div_reg) + 2) *
> multiply) / 2);
> +     base_clk2 = (apb_clk * multiply) / (((GET_CLK2_DIV(clk_div_reg) + 2) *
> multiply) / 2);
> +     base_clk3 = (apb_clk * multiply) / (((GET_CLK3_DIV(clk_div_reg) + 2) *
> multiply) / 2);
> +     base_clk4 = (apb_clk * multiply) / (((GET_CLK4_DIV(clk_div_reg) + 2) *
> +multiply) / 2);
> +
> +     if ((apb_clk / speed) <= 32) {
> +             baseclk_idx = 0;
> +             divisor = DIV_ROUND_UP(apb_clk, speed);
> +     } else if ((base_clk1 / speed) <= 32) {
> +             baseclk_idx = 1;
> +             divisor = DIV_ROUND_UP(base_clk1, speed);
> +     } else if ((base_clk2 / speed) <= 32) {
> +             baseclk_idx = 2;
> +             divisor = DIV_ROUND_UP(base_clk2, speed);
> +     } else if ((base_clk3 / speed) <= 32) {
> +             baseclk_idx = 3;
> +             divisor = DIV_ROUND_UP(base_clk3, speed);
> +     } else {
> +             baseclk_idx = 4;
> +             divisor = DIV_ROUND_UP(base_clk4, speed);
> +             inc = 0;
> +             while ((divisor + inc) > 32) {
> +                     inc |= divisor & 0x1;
> +                     divisor >>= 1;
> +                     baseclk_idx++;
> +             }
> +             divisor += inc;
> +     }
> +     divisor = min_t(int, divisor, 32);
> +     baseclk_idx &= 0xf;
> +     scl_low = ((divisor * 9) / 16) - 1;
> +     scl_low = min_t(u32, scl_low, 0xf);
> +     scl_high = (divisor - scl_low - 2) & 0xf;
> +     /* Divisor : Base Clock : tCKHighMin : tCK High : tCK Low  */
> +     data = ((scl_high - 1) << 20) | (scl_high << 16) | (scl_low << 12) |
> +            baseclk_idx;
> +     /* Set AC Timing */
> +     writel(data, &priv->regs->ac_timing);
> +
> +     return 0;
> +}
> +
> +static int ast2600_i2c_probe(struct udevice *dev) {
> +     struct ast2600_i2c_priv *priv = dev_get_priv(dev);
> +     struct udevice *global_dev;
> +     int ret;
> +
> +     /* find global base address */
> +     ret = uclass_get_device_by_driver(UCLASS_MISC,
> +                                       DM_DRIVER_GET(aspeed_i2c_global),
> +                                       &global_dev);
> +     if (ret) {
> +             debug("i2c global not defined\n");
> +             return ret;
> +     }
> +
> +     priv->global = dev_read_addr_ptr(global_dev);
> +     if (IS_ERR(priv->global)) {
> +             debug("%s(): can't get global\n", __func__);
> +             return PTR_ERR(priv->global);
> +     }
> +
> +     /* Reset device */
> +     writel(0, &priv->regs->fun_ctrl);
> +     /* Enable Master Mode. Assuming single-master */
> +     writel(I2CC_BUS_AUTO_RELEASE | I2CC_MASTER_EN |
> +                    I2CC_MULTI_MASTER_DIS,
> +            &priv->regs->fun_ctrl);
> +
> +     writel(0, &priv->regs->ier);
> +     /* Clear Interrupt */
> +     writel(~0, &priv->regs->isr);
> +
> +     return 0;
> +}
> +
> +static int ast2600_i2c_of_to_plat(struct udevice *dev) {
> +     struct ast2600_i2c_priv *priv = dev_get_priv(dev);
> +     int ret;
> +
> +     priv->regs = dev_read_addr_ptr(dev);
> +     if (!priv->regs)
> +             return -EINVAL;
> +
> +     ret = clk_get_by_index(dev, 0, &priv->clk);
> +     if (ret < 0) {
> +             debug("%s: Can't get clock for %s: %d\n", __func__, dev->name,
> +                   ret);
> +             return ret;
> +     }
> +
> +     return 0;
> +}
> +
> +static const struct dm_i2c_ops ast2600_i2c_ops = {
> +     .xfer = ast2600_i2c_xfer,
> +     .deblock = ast2600_i2c_deblock,
> +     .set_bus_speed = ast2600_i2c_set_speed, };
> +
> +static const struct udevice_id ast2600_i2c_ids[] = {
> +     { .compatible = "aspeed,ast2600-i2c" },
> +     {},
> +};
> +
> +U_BOOT_DRIVER(ast2600_i2c) = {
> +     .name = "ast2600_i2c",
> +     .id = UCLASS_I2C,
> +     .of_match = ast2600_i2c_ids,
> +     .probe = ast2600_i2c_probe,
> +     .of_to_plat = ast2600_i2c_of_to_plat,
> +     .priv_auto = sizeof(struct ast2600_i2c_priv),
> +     .ops = &ast2600_i2c_ops,
> +};
> +
> +struct ast2600_i2c_global_priv {
> +     void __iomem *regs;
> +     struct reset_ctl reset;
> +};
> +
> +/*
> + * APB clk : 100Mhz
> + * div  : scl       : baseclk [APB/((div/2) + 1)] : tBuf [1/bclk * 16]
> + * I2CG10[31:24] base clk4 for i2c auto recovery timeout counter (0xC6)
> + * I2CG10[23:16] base clk3 for Standard-mode (100Khz) min tBuf 4.7us
> + * 0x3c : 100.8Khz  : 3.225Mhz                    : 4.96us
> + * 0x3d : 99.2Khz   : 3.174Mhz                    : 5.04us
> + * 0x3e : 97.65Khz  : 3.125Mhz                    : 5.12us
> + * 0x40 : 97.75Khz  : 3.03Mhz                     : 5.28us
> + * 0x41 : 99.5Khz   : 2.98Mhz                     : 5.36us (default)
> + * I2CG10[15:8] base clk2 for Fast-mode (400Khz) min tBuf 1.3us
> + * 0x12 : 400Khz    : 10Mhz                       : 1.6us
> + * I2CG10[7:0] base clk1 for Fast-mode Plus (1Mhz) min tBuf 0.5us
> + * 0x08 : 1Mhz      : 20Mhz                       : 0.8us
> + */
> +
> +static int aspeed_i2c_global_probe(struct udevice *dev) {
> +     struct ast2600_i2c_global_priv *i2c_global = dev_get_priv(dev);
> +     void __iomem *regs;
> +     int ret = 0;
> +
> +     i2c_global->regs = dev_read_addr_ptr(dev);
> +     if (!i2c_global->regs)
> +             return -EINVAL;
> +
> +     debug("%s(dev=%p)\n", __func__, dev);
> +
> +     regs = i2c_global->regs;
> +
> +     ret = reset_get_by_index(dev, 0, &i2c_global->reset);
> +     if (ret) {
> +             printf("%s(): Failed to get reset signal\n", __func__);
> +             return ret;
> +     }
> +
> +     reset_deassert(&i2c_global->reset);
> +
> +     writel(GLOBAL_INIT, regs + I2CG_CTRL);
> +     writel(I2CCG_DIV_CTRL, regs + I2CG_CLK_DIV_CTRL);
> +
> +     return 0;
> +}
> +
> +static const struct udevice_id aspeed_i2c_global_ids[] = {
> +     {       .compatible = "aspeed,ast2600-i2c-global",      },
> +     { }
> +};
> +
> +U_BOOT_DRIVER(aspeed_i2c_global) = {
> +     .name           = "aspeed_i2c_global",
> +     .id                     = UCLASS_MISC,
> +     .of_match       = aspeed_i2c_global_ids,
> +     .probe          = aspeed_i2c_global_probe,
> +     .priv_auto  = sizeof(struct ast2600_i2c_global_priv), };
> +
> diff --git a/drivers/i2c/ast2600_i2c.h b/drivers/i2c/ast2600_i2c.h new file
> mode 100644 index 0000000000..69699ba84c
> --- /dev/null
> +++ b/drivers/i2c/ast2600_i2c.h
> @@ -0,0 +1,120 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright ASPEED Technology Inc.
> + */
> +#ifndef __AST2600_I2C_H_
> +#define __AST2600_I2C_H_
> +
> +struct ast2600_i2c_regs {
> +     u32 fun_ctrl;
> +     u32 ac_timing;
> +     u32 trx_buff;
> +     u32 icr;
> +     u32 ier;
> +     u32 isr;
> +     u32 cmd_sts;
> +};
> +
> +/* 0x00 : I2CC Master/Slave Function Control Register  */
> +#define I2CC_SLAVE_ADDR_RX_EN        BIT(20)
> +#define I2CC_MASTER_RETRY_MASK       GENMASK(19, 18)
> +#define I2CC_MASTER_RETRY(x) (((x) & GENMASK(1, 0)) << 18)
> +#define I2CC_BUS_AUTO_RELEASE        BIT(17)
> +#define I2CC_M_SDA_LOCK_EN           BIT(16)
> +#define I2CC_MULTI_MASTER_DIS        BIT(15)
> +#define I2CC_M_SCL_DRIVE_EN          BIT(14)
> +#define I2CC_MSB_STS                 BIT(9)
> +#define I2CC_SDA_DRIVE_1T_EN BIT(8)
> +#define I2CC_M_SDA_DRIVE_1T_EN       BIT(7)
> +#define I2CC_M_HIGH_SPEED_EN BIT(6)
> +/* reserved 5 : 2 */
> +#define I2CC_SLAVE_EN                        BIT(1)
> +#define I2CC_MASTER_EN                       BIT(0)
> +
> +/* 0x04 : I2CD Clock and AC Timing Control Register #1 */
> +/* Base register value. These bits are always set by the driver. */
> +#define I2CD_CACTC_BASE              0xfff00300
> +#define I2CD_TCKHIGH_SHIFT   16
> +#define I2CD_TCKLOW_SHIFT    12
> +#define I2CD_THDDAT_SHIFT    10
> +#define I2CD_TO_DIV_SHIFT    8
> +#define I2CD_BASE_DIV_SHIFT  0
> +
> +/* 0x08 : I2CC Master/Slave Transmit/Receive Byte Buffer Register */
> +#define I2CC_TX_DIR_MASK             GENMASK(31, 29)
> +#define I2CC_SDA_OE                          BIT(28)
> +#define I2CC_SDA_O                           BIT(27)
> +#define I2CC_SCL_OE                          BIT(26)
> +#define I2CC_SCL_O                           BIT(25)
> +
> +#define I2CC_SCL_LINE_STS            BIT(18)
> +#define I2CC_SDA_LINE_STS            BIT(17)
> +#define I2CC_BUS_BUSY_STS            BIT(16)
> +#define I2CC_GET_RX_BUFF(x)          (((x) >> 8) & GENMASK(7, 0))
> +
> +/* 0x10 : I2CM Master Interrupt Control Register */
> +/* 0x14 : I2CM Master Interrupt Status Register  */
> +#define I2CM_PKT_TIMEOUT             BIT(18)
> +#define I2CM_PKT_ERROR                       BIT(17)
> +#define I2CM_PKT_DONE                        BIT(16)
> +
> +#define I2CM_BUS_RECOVER_FAIL        BIT(15)
> +#define I2CM_SDA_DL_TO                       BIT(14)
> +#define I2CM_BUS_RECOVER             BIT(13)
> +#define I2CM_SMBUS_ALT                       BIT(12)
> +
> +#define I2CM_SCL_LOW_TO                      BIT(6)
> +#define I2CM_ABNORMAL                        BIT(5)
> +#define I2CM_NORMAL_STOP             BIT(4)
> +#define I2CM_ARBIT_LOSS                      BIT(3)
> +#define I2CM_RX_DONE                 BIT(2)
> +#define I2CM_TX_NAK                          BIT(1)
> +#define I2CM_TX_ACK                          BIT(0)
> +
> +/* 0x18 : I2CM Master Command/Status Register   */
> +#define I2CM_PKT_ADDR(x)             (((x) & GENMASK(6, 0)) << 24)
> +#define I2CM_PKT_EN                          BIT(16)
> +#define I2CM_SDA_OE_OUT_DIR          BIT(15)
> +#define I2CM_SDA_O_OUT_DIR           BIT(14)
> +#define I2CM_SCL_OE_OUT_DIR          BIT(13)
> +#define I2CM_SCL_O_OUT_DIR           BIT(12)
> +#define I2CM_RECOVER_CMD_EN          BIT(11)
> +
> +#define I2CM_RX_DMA_EN                       BIT(9)
> +#define I2CM_TX_DMA_EN                       BIT(8)
> +/* Command Bit */
> +#define I2CM_RX_BUFF_EN                      BIT(7)
> +#define I2CM_TX_BUFF_EN                      BIT(6)
> +#define I2CM_STOP_CMD                        BIT(5)
> +#define I2CM_RX_CMD_LAST             BIT(4)
> +#define I2CM_RX_CMD                          BIT(3)
> +
> +#define I2CM_TX_CMD                          BIT(1)
> +#define I2CM_START_CMD                       BIT(0)
> +
> +#define I2C_TIMEOUT_US 100000
> +
> +/* I2C Global Register */
> +#define I2CG_ISR                     0x00
> +#define I2CG_SLAVE_ISR               0x04
> +#define I2CG_OWNER               0x08
> +#define I2CG_CTRL                0x0C
> +#define I2CG_CLK_DIV_CTRL    0x10
> +
> +#define I2CG_SLAVE_PKT_NAK       BIT(4)
> +#define I2CG_M_S_SEPARATE_INTR       BIT(3)
> +#define I2CG_CTRL_NEW_REG        BIT(2)
> +#define I2CG_CTRL_NEW_CLK_DIV        BIT(1)
> +
> +#define GLOBAL_INIT                                  \
> +                     (I2CG_SLAVE_PKT_NAK |   \
> +                     I2CG_CTRL_NEW_REG |             \
> +                     I2CG_CTRL_NEW_CLK_DIV)
> +#define I2CCG_DIV_CTRL 0xc6411208
> +
> +#define GET_CLK1_DIV(x) ((x) & 0xff)
> +#define GET_CLK2_DIV(x) (((x) >> 8) & 0xff) #define GET_CLK3_DIV(x)
> +(((x) >> 16) & 0xff) #define GET_CLK4_DIV(x) (((x) >> 24) & 0xff)
> +
> +#endif                               /* __AST2600_I2C_H_ */
> --
> 2.34.1

Reply via email to