14dc038f3Smaxims@google.com /*
24dc038f3Smaxims@google.com * Copyright (C) 2012-2020 ASPEED Technology Inc.
34dc038f3Smaxims@google.com * Copyright 2016 IBM Corporation
44dc038f3Smaxims@google.com * Copyright 2017 Google, Inc.
54dc038f3Smaxims@google.com *
64dc038f3Smaxims@google.com * SPDX-License-Identifier: GPL-2.0+
74dc038f3Smaxims@google.com */
84dc038f3Smaxims@google.com
94dc038f3Smaxims@google.com #include <common.h>
104dc038f3Smaxims@google.com #include <clk.h>
114dc038f3Smaxims@google.com #include <dm.h>
124dc038f3Smaxims@google.com #include <errno.h>
134dc038f3Smaxims@google.com #include <fdtdec.h>
144dc038f3Smaxims@google.com #include <i2c.h>
154dc038f3Smaxims@google.com #include <asm/io.h>
164dc038f3Smaxims@google.com #include <asm/arch/scu_ast2500.h>
174dc038f3Smaxims@google.com
184dc038f3Smaxims@google.com #include "ast_i2c.h"
194dc038f3Smaxims@google.com
204dc038f3Smaxims@google.com #define I2C_TIMEOUT_US 100000
214dc038f3Smaxims@google.com #define I2C_SLEEP_STEP_US 20
224dc038f3Smaxims@google.com
234dc038f3Smaxims@google.com #define HIGHSPEED_TTIMEOUT 3
244dc038f3Smaxims@google.com
254dc038f3Smaxims@google.com DECLARE_GLOBAL_DATA_PTR;
264dc038f3Smaxims@google.com
274dc038f3Smaxims@google.com /*
284dc038f3Smaxims@google.com * Device private data
294dc038f3Smaxims@google.com */
304dc038f3Smaxims@google.com struct ast_i2c_priv {
314dc038f3Smaxims@google.com /* This device's clock */
324dc038f3Smaxims@google.com struct clk clk;
334dc038f3Smaxims@google.com /* Device registers */
344dc038f3Smaxims@google.com struct ast_i2c_regs *regs;
354dc038f3Smaxims@google.com /* I2C speed in Hz */
364dc038f3Smaxims@google.com int speed;
374dc038f3Smaxims@google.com };
384dc038f3Smaxims@google.com
394dc038f3Smaxims@google.com /*
404dc038f3Smaxims@google.com * Given desired divider ratio, return the value that needs to be set
414dc038f3Smaxims@google.com * in Clock and AC Timing Control register
424dc038f3Smaxims@google.com */
get_clk_reg_val(ulong divider_ratio)434dc038f3Smaxims@google.com static u32 get_clk_reg_val(ulong divider_ratio)
444dc038f3Smaxims@google.com {
454dc038f3Smaxims@google.com ulong inc = 0, div;
464dc038f3Smaxims@google.com ulong scl_low, scl_high, data;
474dc038f3Smaxims@google.com
484dc038f3Smaxims@google.com for (div = 0; divider_ratio >= 16; div++) {
494dc038f3Smaxims@google.com inc |= (divider_ratio & 1);
504dc038f3Smaxims@google.com divider_ratio >>= 1;
514dc038f3Smaxims@google.com }
524dc038f3Smaxims@google.com divider_ratio += inc;
534dc038f3Smaxims@google.com scl_low = (divider_ratio >> 1) - 1;
544dc038f3Smaxims@google.com scl_high = divider_ratio - scl_low - 2;
554dc038f3Smaxims@google.com data = I2CD_CACTC_BASE
564dc038f3Smaxims@google.com | (scl_high << I2CD_TCKHIGH_SHIFT)
574dc038f3Smaxims@google.com | (scl_low << I2CD_TCKLOW_SHIFT)
584dc038f3Smaxims@google.com | (div << I2CD_BASE_DIV_SHIFT);
594dc038f3Smaxims@google.com
604dc038f3Smaxims@google.com return data;
614dc038f3Smaxims@google.com }
624dc038f3Smaxims@google.com
ast_i2c_clear_interrupts(struct udevice * dev)634dc038f3Smaxims@google.com static void ast_i2c_clear_interrupts(struct udevice *dev)
644dc038f3Smaxims@google.com {
654dc038f3Smaxims@google.com struct ast_i2c_priv *priv = dev_get_priv(dev);
664dc038f3Smaxims@google.com
674dc038f3Smaxims@google.com writel(~0, &priv->regs->isr);
684dc038f3Smaxims@google.com }
694dc038f3Smaxims@google.com
ast_i2c_init_bus(struct udevice * dev)704dc038f3Smaxims@google.com static void ast_i2c_init_bus(struct udevice *dev)
714dc038f3Smaxims@google.com {
724dc038f3Smaxims@google.com struct ast_i2c_priv *priv = dev_get_priv(dev);
734dc038f3Smaxims@google.com
744dc038f3Smaxims@google.com /* Reset device */
754dc038f3Smaxims@google.com writel(0, &priv->regs->fcr);
764dc038f3Smaxims@google.com /* Enable Master Mode. Assuming single-master */
774dc038f3Smaxims@google.com writel(I2CD_MASTER_EN
784dc038f3Smaxims@google.com | I2CD_M_SDA_LOCK_EN
794dc038f3Smaxims@google.com | I2CD_MULTI_MASTER_DIS | I2CD_M_SCL_DRIVE_EN,
804dc038f3Smaxims@google.com &priv->regs->fcr);
814dc038f3Smaxims@google.com /* Enable Interrupts */
824dc038f3Smaxims@google.com writel(I2CD_INTR_TX_ACK
834dc038f3Smaxims@google.com | I2CD_INTR_TX_NAK
844dc038f3Smaxims@google.com | I2CD_INTR_RX_DONE
854dc038f3Smaxims@google.com | I2CD_INTR_BUS_RECOVER_DONE
864dc038f3Smaxims@google.com | I2CD_INTR_NORMAL_STOP
874dc038f3Smaxims@google.com | I2CD_INTR_ABNORMAL, &priv->regs->icr);
884dc038f3Smaxims@google.com }
894dc038f3Smaxims@google.com
ast_i2c_ofdata_to_platdata(struct udevice * dev)904dc038f3Smaxims@google.com static int ast_i2c_ofdata_to_platdata(struct udevice *dev)
914dc038f3Smaxims@google.com {
924dc038f3Smaxims@google.com struct ast_i2c_priv *priv = dev_get_priv(dev);
934dc038f3Smaxims@google.com int ret;
944dc038f3Smaxims@google.com
95*a821c4afSSimon Glass priv->regs = devfdt_get_addr_ptr(dev);
964dc038f3Smaxims@google.com if (IS_ERR(priv->regs))
974dc038f3Smaxims@google.com return PTR_ERR(priv->regs);
984dc038f3Smaxims@google.com
994dc038f3Smaxims@google.com ret = clk_get_by_index(dev, 0, &priv->clk);
1004dc038f3Smaxims@google.com if (ret < 0) {
1014dc038f3Smaxims@google.com debug("%s: Can't get clock for %s: %d\n", __func__, dev->name,
1024dc038f3Smaxims@google.com ret);
1034dc038f3Smaxims@google.com return ret;
1044dc038f3Smaxims@google.com }
1054dc038f3Smaxims@google.com
1064dc038f3Smaxims@google.com return 0;
1074dc038f3Smaxims@google.com }
1084dc038f3Smaxims@google.com
ast_i2c_probe(struct udevice * dev)1094dc038f3Smaxims@google.com static int ast_i2c_probe(struct udevice *dev)
1104dc038f3Smaxims@google.com {
1114dc038f3Smaxims@google.com struct ast2500_scu *scu;
1124dc038f3Smaxims@google.com
1134dc038f3Smaxims@google.com debug("Enabling I2C%u\n", dev->seq);
1144dc038f3Smaxims@google.com
1154dc038f3Smaxims@google.com /*
1164dc038f3Smaxims@google.com * Get all I2C devices out of Reset.
1174dc038f3Smaxims@google.com * Only needs to be done once, but doing it for every
1184dc038f3Smaxims@google.com * device does not hurt.
1194dc038f3Smaxims@google.com */
1204dc038f3Smaxims@google.com scu = ast_get_scu();
1214dc038f3Smaxims@google.com ast_scu_unlock(scu);
1224dc038f3Smaxims@google.com clrbits_le32(&scu->sysreset_ctrl1, SCU_SYSRESET_I2C);
1234dc038f3Smaxims@google.com ast_scu_lock(scu);
1244dc038f3Smaxims@google.com
1254dc038f3Smaxims@google.com ast_i2c_init_bus(dev);
1264dc038f3Smaxims@google.com
1274dc038f3Smaxims@google.com return 0;
1284dc038f3Smaxims@google.com }
1294dc038f3Smaxims@google.com
ast_i2c_wait_isr(struct udevice * dev,u32 flag)1304dc038f3Smaxims@google.com static int ast_i2c_wait_isr(struct udevice *dev, u32 flag)
1314dc038f3Smaxims@google.com {
1324dc038f3Smaxims@google.com struct ast_i2c_priv *priv = dev_get_priv(dev);
1334dc038f3Smaxims@google.com int timeout = I2C_TIMEOUT_US;
1344dc038f3Smaxims@google.com
1354dc038f3Smaxims@google.com while (!(readl(&priv->regs->isr) & flag) && timeout > 0) {
1364dc038f3Smaxims@google.com udelay(I2C_SLEEP_STEP_US);
1374dc038f3Smaxims@google.com timeout -= I2C_SLEEP_STEP_US;
1384dc038f3Smaxims@google.com }
1394dc038f3Smaxims@google.com
1404dc038f3Smaxims@google.com ast_i2c_clear_interrupts(dev);
1414dc038f3Smaxims@google.com if (timeout <= 0)
1424dc038f3Smaxims@google.com return -ETIMEDOUT;
1434dc038f3Smaxims@google.com
1444dc038f3Smaxims@google.com return 0;
1454dc038f3Smaxims@google.com }
1464dc038f3Smaxims@google.com
ast_i2c_send_stop(struct udevice * dev)1474dc038f3Smaxims@google.com static int ast_i2c_send_stop(struct udevice *dev)
1484dc038f3Smaxims@google.com {
1494dc038f3Smaxims@google.com struct ast_i2c_priv *priv = dev_get_priv(dev);
1504dc038f3Smaxims@google.com
1514dc038f3Smaxims@google.com writel(I2CD_M_STOP_CMD, &priv->regs->csr);
1524dc038f3Smaxims@google.com
1534dc038f3Smaxims@google.com return ast_i2c_wait_isr(dev, I2CD_INTR_NORMAL_STOP);
1544dc038f3Smaxims@google.com }
1554dc038f3Smaxims@google.com
ast_i2c_wait_tx(struct udevice * dev)1564dc038f3Smaxims@google.com static int ast_i2c_wait_tx(struct udevice *dev)
1574dc038f3Smaxims@google.com {
1584dc038f3Smaxims@google.com struct ast_i2c_priv *priv = dev_get_priv(dev);
1594dc038f3Smaxims@google.com int timeout = I2C_TIMEOUT_US;
1604dc038f3Smaxims@google.com u32 flag = I2CD_INTR_TX_ACK | I2CD_INTR_TX_NAK;
1614dc038f3Smaxims@google.com u32 status = readl(&priv->regs->isr) & flag;
1624dc038f3Smaxims@google.com int ret = 0;
1634dc038f3Smaxims@google.com
1644dc038f3Smaxims@google.com while (!status && timeout > 0) {
1654dc038f3Smaxims@google.com status = readl(&priv->regs->isr) & flag;
1664dc038f3Smaxims@google.com udelay(I2C_SLEEP_STEP_US);
1674dc038f3Smaxims@google.com timeout -= I2C_SLEEP_STEP_US;
1684dc038f3Smaxims@google.com }
1694dc038f3Smaxims@google.com
1704dc038f3Smaxims@google.com if (status == I2CD_INTR_TX_NAK)
1714dc038f3Smaxims@google.com ret = -EREMOTEIO;
1724dc038f3Smaxims@google.com
1734dc038f3Smaxims@google.com if (timeout <= 0)
1744dc038f3Smaxims@google.com ret = -ETIMEDOUT;
1754dc038f3Smaxims@google.com
1764dc038f3Smaxims@google.com ast_i2c_clear_interrupts(dev);
1774dc038f3Smaxims@google.com
1784dc038f3Smaxims@google.com return ret;
1794dc038f3Smaxims@google.com }
1804dc038f3Smaxims@google.com
ast_i2c_start_txn(struct udevice * dev,uint devaddr)1814dc038f3Smaxims@google.com static int ast_i2c_start_txn(struct udevice *dev, uint devaddr)
1824dc038f3Smaxims@google.com {
1834dc038f3Smaxims@google.com struct ast_i2c_priv *priv = dev_get_priv(dev);
1844dc038f3Smaxims@google.com
1854dc038f3Smaxims@google.com /* Start and Send Device Address */
1864dc038f3Smaxims@google.com writel(devaddr, &priv->regs->trbbr);
1874dc038f3Smaxims@google.com writel(I2CD_M_START_CMD | I2CD_M_TX_CMD, &priv->regs->csr);
1884dc038f3Smaxims@google.com
1894dc038f3Smaxims@google.com return ast_i2c_wait_tx(dev);
1904dc038f3Smaxims@google.com }
1914dc038f3Smaxims@google.com
ast_i2c_read_data(struct udevice * dev,u8 chip_addr,u8 * buffer,size_t len,bool send_stop)1924dc038f3Smaxims@google.com static int ast_i2c_read_data(struct udevice *dev, u8 chip_addr, u8 *buffer,
1934dc038f3Smaxims@google.com size_t len, bool send_stop)
1944dc038f3Smaxims@google.com {
1954dc038f3Smaxims@google.com struct ast_i2c_priv *priv = dev_get_priv(dev);
1964dc038f3Smaxims@google.com u32 i2c_cmd = I2CD_M_RX_CMD;
1974dc038f3Smaxims@google.com int ret;
1984dc038f3Smaxims@google.com
1994dc038f3Smaxims@google.com ret = ast_i2c_start_txn(dev, (chip_addr << 1) | I2C_M_RD);
2004dc038f3Smaxims@google.com if (ret < 0)
2014dc038f3Smaxims@google.com return ret;
2024dc038f3Smaxims@google.com
2034dc038f3Smaxims@google.com for (; len > 0; len--, buffer++) {
2044dc038f3Smaxims@google.com if (len == 1)
2054dc038f3Smaxims@google.com i2c_cmd |= I2CD_M_S_RX_CMD_LAST;
2064dc038f3Smaxims@google.com writel(i2c_cmd, &priv->regs->csr);
2074dc038f3Smaxims@google.com ret = ast_i2c_wait_isr(dev, I2CD_INTR_RX_DONE);
2084dc038f3Smaxims@google.com if (ret < 0)
2094dc038f3Smaxims@google.com return ret;
2104dc038f3Smaxims@google.com *buffer = (readl(&priv->regs->trbbr) & I2CD_RX_DATA_MASK)
2114dc038f3Smaxims@google.com >> I2CD_RX_DATA_SHIFT;
2124dc038f3Smaxims@google.com }
2134dc038f3Smaxims@google.com ast_i2c_clear_interrupts(dev);
2144dc038f3Smaxims@google.com
2154dc038f3Smaxims@google.com if (send_stop)
2164dc038f3Smaxims@google.com return ast_i2c_send_stop(dev);
2174dc038f3Smaxims@google.com
2184dc038f3Smaxims@google.com return 0;
2194dc038f3Smaxims@google.com }
2204dc038f3Smaxims@google.com
ast_i2c_write_data(struct udevice * dev,u8 chip_addr,u8 * buffer,size_t len,bool send_stop)2214dc038f3Smaxims@google.com static int ast_i2c_write_data(struct udevice *dev, u8 chip_addr, u8
2224dc038f3Smaxims@google.com *buffer, size_t len, bool send_stop)
2234dc038f3Smaxims@google.com {
2244dc038f3Smaxims@google.com struct ast_i2c_priv *priv = dev_get_priv(dev);
2254dc038f3Smaxims@google.com int ret;
2264dc038f3Smaxims@google.com
2274dc038f3Smaxims@google.com ret = ast_i2c_start_txn(dev, (chip_addr << 1));
2284dc038f3Smaxims@google.com if (ret < 0)
2294dc038f3Smaxims@google.com return ret;
2304dc038f3Smaxims@google.com
2314dc038f3Smaxims@google.com for (; len > 0; len--, buffer++) {
2324dc038f3Smaxims@google.com writel(*buffer, &priv->regs->trbbr);
2334dc038f3Smaxims@google.com writel(I2CD_M_TX_CMD, &priv->regs->csr);
2344dc038f3Smaxims@google.com ret = ast_i2c_wait_tx(dev);
2354dc038f3Smaxims@google.com if (ret < 0)
2364dc038f3Smaxims@google.com return ret;
2374dc038f3Smaxims@google.com }
2384dc038f3Smaxims@google.com
2394dc038f3Smaxims@google.com if (send_stop)
2404dc038f3Smaxims@google.com return ast_i2c_send_stop(dev);
2414dc038f3Smaxims@google.com
2424dc038f3Smaxims@google.com return 0;
2434dc038f3Smaxims@google.com }
2444dc038f3Smaxims@google.com
ast_i2c_deblock(struct udevice * dev)2454dc038f3Smaxims@google.com static int ast_i2c_deblock(struct udevice *dev)
2464dc038f3Smaxims@google.com {
2474dc038f3Smaxims@google.com struct ast_i2c_priv *priv = dev_get_priv(dev);
2484dc038f3Smaxims@google.com struct ast_i2c_regs *regs = priv->regs;
2494dc038f3Smaxims@google.com u32 csr = readl(®s->csr);
2504dc038f3Smaxims@google.com bool sda_high = csr & I2CD_SDA_LINE_STS;
2514dc038f3Smaxims@google.com bool scl_high = csr & I2CD_SCL_LINE_STS;
2524dc038f3Smaxims@google.com int ret = 0;
2534dc038f3Smaxims@google.com
2544dc038f3Smaxims@google.com if (sda_high && scl_high) {
2554dc038f3Smaxims@google.com /* Bus is idle, no deblocking needed. */
2564dc038f3Smaxims@google.com return 0;
2574dc038f3Smaxims@google.com } else if (sda_high) {
2584dc038f3Smaxims@google.com /* Send stop command */
2594dc038f3Smaxims@google.com debug("Unterminated TXN in (%x), sending stop\n", csr);
2604dc038f3Smaxims@google.com ret = ast_i2c_send_stop(dev);
2614dc038f3Smaxims@google.com } else if (scl_high) {
2624dc038f3Smaxims@google.com /* Possibly stuck slave */
2634dc038f3Smaxims@google.com debug("Bus stuck (%x), attempting recovery\n", csr);
2644dc038f3Smaxims@google.com writel(I2CD_BUS_RECOVER_CMD, ®s->csr);
2654dc038f3Smaxims@google.com ret = ast_i2c_wait_isr(dev, I2CD_INTR_BUS_RECOVER_DONE);
2664dc038f3Smaxims@google.com } else {
2674dc038f3Smaxims@google.com /* Just try to reinit the device. */
2684dc038f3Smaxims@google.com ast_i2c_init_bus(dev);
2694dc038f3Smaxims@google.com }
2704dc038f3Smaxims@google.com
2714dc038f3Smaxims@google.com return ret;
2724dc038f3Smaxims@google.com }
2734dc038f3Smaxims@google.com
ast_i2c_xfer(struct udevice * dev,struct i2c_msg * msg,int nmsgs)2744dc038f3Smaxims@google.com static int ast_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
2754dc038f3Smaxims@google.com {
2764dc038f3Smaxims@google.com int ret;
2774dc038f3Smaxims@google.com
2784dc038f3Smaxims@google.com ret = ast_i2c_deblock(dev);
2794dc038f3Smaxims@google.com if (ret < 0)
2804dc038f3Smaxims@google.com return ret;
2814dc038f3Smaxims@google.com
2824dc038f3Smaxims@google.com debug("i2c_xfer: %d messages\n", nmsgs);
2834dc038f3Smaxims@google.com for (; nmsgs > 0; nmsgs--, msg++) {
2844dc038f3Smaxims@google.com if (msg->flags & I2C_M_RD) {
2854dc038f3Smaxims@google.com debug("i2c_read: chip=0x%x, len=0x%x, flags=0x%x\n",
2864dc038f3Smaxims@google.com msg->addr, msg->len, msg->flags);
2874dc038f3Smaxims@google.com ret = ast_i2c_read_data(dev, msg->addr, msg->buf,
2884dc038f3Smaxims@google.com msg->len, (nmsgs == 1));
2894dc038f3Smaxims@google.com } else {
2904dc038f3Smaxims@google.com debug("i2c_write: chip=0x%x, len=0x%x, flags=0x%x\n",
2914dc038f3Smaxims@google.com msg->addr, msg->len, msg->flags);
2924dc038f3Smaxims@google.com ret = ast_i2c_write_data(dev, msg->addr, msg->buf,
2934dc038f3Smaxims@google.com msg->len, (nmsgs == 1));
2944dc038f3Smaxims@google.com }
2954dc038f3Smaxims@google.com if (ret) {
2964dc038f3Smaxims@google.com debug("%s: error (%d)\n", __func__, ret);
2974dc038f3Smaxims@google.com return -EREMOTEIO;
2984dc038f3Smaxims@google.com }
2994dc038f3Smaxims@google.com }
3004dc038f3Smaxims@google.com
3014dc038f3Smaxims@google.com return 0;
3024dc038f3Smaxims@google.com }
3034dc038f3Smaxims@google.com
ast_i2c_set_speed(struct udevice * dev,unsigned int speed)3044dc038f3Smaxims@google.com static int ast_i2c_set_speed(struct udevice *dev, unsigned int speed)
3054dc038f3Smaxims@google.com {
3064dc038f3Smaxims@google.com struct ast_i2c_priv *priv = dev_get_priv(dev);
3074dc038f3Smaxims@google.com struct ast_i2c_regs *regs = priv->regs;
3084dc038f3Smaxims@google.com ulong i2c_rate, divider;
3094dc038f3Smaxims@google.com
3104dc038f3Smaxims@google.com debug("Setting speed for I2C%d to <%u>\n", dev->seq, speed);
3114dc038f3Smaxims@google.com if (!speed) {
3124dc038f3Smaxims@google.com debug("No valid speed specified\n");
3134dc038f3Smaxims@google.com return -EINVAL;
3144dc038f3Smaxims@google.com }
3154dc038f3Smaxims@google.com
3164dc038f3Smaxims@google.com i2c_rate = clk_get_rate(&priv->clk);
3174dc038f3Smaxims@google.com divider = i2c_rate / speed;
3184dc038f3Smaxims@google.com
3194dc038f3Smaxims@google.com priv->speed = speed;
3204dc038f3Smaxims@google.com if (speed > I2C_HIGHSPEED_RATE) {
3214dc038f3Smaxims@google.com debug("Enable High Speed\n");
3224dc038f3Smaxims@google.com setbits_le32(®s->fcr, I2CD_M_HIGH_SPEED_EN
3234dc038f3Smaxims@google.com | I2CD_M_SDA_DRIVE_1T_EN
3244dc038f3Smaxims@google.com | I2CD_SDA_DRIVE_1T_EN);
3254dc038f3Smaxims@google.com writel(HIGHSPEED_TTIMEOUT, ®s->cactcr2);
3264dc038f3Smaxims@google.com } else {
3274dc038f3Smaxims@google.com debug("Enabling Normal Speed\n");
3284dc038f3Smaxims@google.com writel(I2CD_NO_TIMEOUT_CTRL, ®s->cactcr2);
3294dc038f3Smaxims@google.com }
3304dc038f3Smaxims@google.com
3314dc038f3Smaxims@google.com writel(get_clk_reg_val(divider), ®s->cactcr1);
3324dc038f3Smaxims@google.com ast_i2c_clear_interrupts(dev);
3334dc038f3Smaxims@google.com
3344dc038f3Smaxims@google.com return 0;
3354dc038f3Smaxims@google.com }
3364dc038f3Smaxims@google.com
3374dc038f3Smaxims@google.com static const struct dm_i2c_ops ast_i2c_ops = {
3384dc038f3Smaxims@google.com .xfer = ast_i2c_xfer,
3394dc038f3Smaxims@google.com .set_bus_speed = ast_i2c_set_speed,
3404dc038f3Smaxims@google.com .deblock = ast_i2c_deblock,
3414dc038f3Smaxims@google.com };
3424dc038f3Smaxims@google.com
3434dc038f3Smaxims@google.com static const struct udevice_id ast_i2c_ids[] = {
3444dc038f3Smaxims@google.com { .compatible = "aspeed,ast2400-i2c-bus" },
3454dc038f3Smaxims@google.com { .compatible = "aspeed,ast2500-i2c-bus" },
3464dc038f3Smaxims@google.com { },
3474dc038f3Smaxims@google.com };
3484dc038f3Smaxims@google.com
3494dc038f3Smaxims@google.com U_BOOT_DRIVER(ast_i2c) = {
3504dc038f3Smaxims@google.com .name = "ast_i2c",
3514dc038f3Smaxims@google.com .id = UCLASS_I2C,
3524dc038f3Smaxims@google.com .of_match = ast_i2c_ids,
3534dc038f3Smaxims@google.com .probe = ast_i2c_probe,
3544dc038f3Smaxims@google.com .ofdata_to_platdata = ast_i2c_ofdata_to_platdata,
3554dc038f3Smaxims@google.com .priv_auto_alloc_size = sizeof(struct ast_i2c_priv),
3564dc038f3Smaxims@google.com .ops = &ast_i2c_ops,
3574dc038f3Smaxims@google.com };
358