Lines Matching +full:i2c +full:- +full:fast +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Synopsys DesignWare I2C adapter driver.
5 * Based on the TI DAVINCI I2C adapter driver.
18 #include <linux/i2c.h>
29 #include "i2c-designware-core.h"
33 "slave address not acknowledged (7bit mode)",
35 "first address byte not acknowledged (10bit mode)",
37 "second address byte not acknowledged (10bit mode)",
49 "trying to read when restart is disabled (10bit mode)",
59 "incorrect slave-transmitter mode configuration",
66 *val = readl(dev->base + reg); in dw_reg_read()
75 writel(val, dev->base + reg); in dw_reg_write()
84 *val = swab32(readl(dev->base + reg)); in dw_reg_read_swab()
93 writel(swab32(val), dev->base + reg); in dw_reg_write_swab()
102 *val = readw(dev->base + reg) | in dw_reg_read_word()
103 (readw(dev->base + reg + 2) << 16); in dw_reg_read_word()
112 writew(val, dev->base + reg); in dw_reg_write_word()
113 writew(val >> 16, dev->base + reg + 2); in dw_reg_write_word()
119 * i2c_dw_init_regmap() - Initialize registers map
122 * Autodetects needed register access mode and creates the regmap with
144 if (dev->map) in i2c_dw_init_regmap()
151 reg = readl(dev->base + DW_IC_COMP_TYPE); in i2c_dw_init_regmap()
154 if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU) in i2c_dw_init_regmap()
164 dev_err(dev->dev, in i2c_dw_init_regmap()
166 return -ENODEV; in i2c_dw_init_regmap()
172 * basically we have MMIO-based regmap so non of the read/write methods in i2c_dw_init_regmap()
175 dev->map = devm_regmap_init(dev->dev, NULL, dev, &map_cfg); in i2c_dw_init_regmap()
176 if (IS_ERR(dev->map)) { in i2c_dw_init_regmap()
177 dev_err(dev->dev, "Failed to init the registers map\n"); in i2c_dw_init_regmap()
178 return PTR_ERR(dev->map); in i2c_dw_init_regmap()
193 struct i2c_timings *t = &dev->timings; in i2c_dw_validate_speed()
197 * Only standard mode at 100kHz, fast mode at 400kHz, in i2c_dw_validate_speed()
198 * fast mode plus at 1MHz and high speed mode at 3.4MHz are supported. in i2c_dw_validate_speed()
201 if (t->bus_freq_hz == supported_speeds[i]) in i2c_dw_validate_speed()
205 dev_err(dev->dev, in i2c_dw_validate_speed()
207 t->bus_freq_hz); in i2c_dw_validate_speed()
209 return -EINVAL; in i2c_dw_validate_speed()
247 if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 3) { in i2c_dw_acpi_params()
248 const union acpi_object *objs = obj->package.elements; in i2c_dw_acpi_params()
261 struct i2c_timings *t = &dev->timings; in i2c_dw_acpi_configure()
268 i2c_dw_acpi_params(device, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, &ss_ht); in i2c_dw_acpi_configure()
269 i2c_dw_acpi_params(device, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, &fs_ht); in i2c_dw_acpi_configure()
270 i2c_dw_acpi_params(device, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt, &fp_ht); in i2c_dw_acpi_configure()
271 i2c_dw_acpi_params(device, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, &hs_ht); in i2c_dw_acpi_configure()
273 switch (t->bus_freq_hz) { in i2c_dw_acpi_configure()
275 dev->sda_hold_time = ss_ht; in i2c_dw_acpi_configure()
278 dev->sda_hold_time = fp_ht; in i2c_dw_acpi_configure()
281 dev->sda_hold_time = hs_ht; in i2c_dw_acpi_configure()
285 dev->sda_hold_time = fs_ht; in i2c_dw_acpi_configure()
319 u32 acpi_speed = i2c_dw_acpi_round_bus_speed(dev->dev); in i2c_dw_adjust_bus_speed()
320 struct i2c_timings *t = &dev->timings; in i2c_dw_adjust_bus_speed()
323 * Find bus speed from the "clock-frequency" device property, ACPI in i2c_dw_adjust_bus_speed()
324 * or by using fast mode if neither is set. in i2c_dw_adjust_bus_speed()
326 if (acpi_speed && t->bus_freq_hz) in i2c_dw_adjust_bus_speed()
327 t->bus_freq_hz = min(t->bus_freq_hz, acpi_speed); in i2c_dw_adjust_bus_speed()
328 else if (acpi_speed || t->bus_freq_hz) in i2c_dw_adjust_bus_speed()
329 t->bus_freq_hz = max(t->bus_freq_hz, acpi_speed); in i2c_dw_adjust_bus_speed()
331 t->bus_freq_hz = I2C_MAX_FAST_MODE_FREQ; in i2c_dw_adjust_bus_speed()
338 * DesignWare I2C core doesn't seem to have solid strategy to meet in i2c_dw_scl_hcnt()
349 * configuration. The resulting I2C bus speed will be in i2c_dw_scl_hcnt()
354 return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * tSYMBOL, MICRO) - in i2c_dw_scl_hcnt()
371 return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * (tSYMBOL + tf), MICRO) - in i2c_dw_scl_hcnt()
382 * DW I2C core starts counting the SCL CNTs for the LOW period in i2c_dw_scl_lcnt()
388 return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * (tLOW + tf), MICRO) - in i2c_dw_scl_lcnt()
402 ret = regmap_read(dev->map, DW_IC_COMP_VERSION, &reg); in i2c_dw_set_sda_hold()
407 if (!dev->sda_hold_time) { in i2c_dw_set_sda_hold()
409 ret = regmap_read(dev->map, DW_IC_SDA_HOLD, in i2c_dw_set_sda_hold()
410 &dev->sda_hold_time); in i2c_dw_set_sda_hold()
416 * Workaround for avoiding TX arbitration lost in case I2C in i2c_dw_set_sda_hold()
418 * SCL by enabling non-zero SDA RX hold. Specification says it in i2c_dw_set_sda_hold()
422 if (!(dev->sda_hold_time & DW_IC_SDA_HOLD_RX_MASK)) in i2c_dw_set_sda_hold()
423 dev->sda_hold_time |= 1 << DW_IC_SDA_HOLD_RX_SHIFT; in i2c_dw_set_sda_hold()
425 dev_dbg(dev->dev, "SDA Hold Time TX:RX = %d:%d\n", in i2c_dw_set_sda_hold()
426 dev->sda_hold_time & ~(u32)DW_IC_SDA_HOLD_RX_MASK, in i2c_dw_set_sda_hold()
427 dev->sda_hold_time >> DW_IC_SDA_HOLD_RX_SHIFT); in i2c_dw_set_sda_hold()
428 } else if (dev->set_sda_hold_time) { in i2c_dw_set_sda_hold()
429 dev->set_sda_hold_time(dev); in i2c_dw_set_sda_hold()
430 } else if (dev->sda_hold_time) { in i2c_dw_set_sda_hold()
431 dev_warn(dev->dev, in i2c_dw_set_sda_hold()
433 dev->sda_hold_time = 0; in i2c_dw_set_sda_hold()
451 regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &raw_intr_stats); in __i2c_dw_disable()
452 regmap_read(dev->map, DW_IC_ENABLE, &enable); in __i2c_dw_disable()
456 regmap_write(dev->map, DW_IC_ENABLE, enable | DW_IC_ENABLE_ABORT); in __i2c_dw_disable()
457 ret = regmap_read_poll_timeout(dev->map, DW_IC_ENABLE, enable, in __i2c_dw_disable()
461 dev_err(dev->dev, "timeout while trying to abort current transfer\n"); in __i2c_dw_disable()
470 regmap_read(dev->map, DW_IC_ENABLE_STATUS, &status); in __i2c_dw_disable()
475 * Wait 10 times the signaling period of the highest I2C in __i2c_dw_disable()
477 * 25us) as described in the DesignWare I2C databook. in __i2c_dw_disable()
480 } while (timeout--); in __i2c_dw_disable()
482 dev_warn(dev->dev, "timeout in disabling adapter\n"); in __i2c_dw_disable()
491 if (WARN_ON_ONCE(!dev->get_clk_rate_khz)) in i2c_dw_clk_rate()
493 return dev->get_clk_rate_khz(dev); in i2c_dw_clk_rate()
502 ret = clk_prepare_enable(dev->pclk); in i2c_dw_prepare_clk()
506 ret = clk_prepare_enable(dev->clk); in i2c_dw_prepare_clk()
508 clk_disable_unprepare(dev->pclk); in i2c_dw_prepare_clk()
513 clk_disable_unprepare(dev->clk); in i2c_dw_prepare_clk()
514 clk_disable_unprepare(dev->pclk); in i2c_dw_prepare_clk()
524 if (!dev->acquire_lock) in i2c_dw_acquire_lock()
527 ret = dev->acquire_lock(); in i2c_dw_acquire_lock()
531 dev_err(dev->dev, "couldn't acquire bus ownership\n"); in i2c_dw_acquire_lock()
538 if (dev->release_lock) in i2c_dw_release_lock()
539 dev->release_lock(); in i2c_dw_release_lock()
550 ret = regmap_read_poll_timeout(dev->map, DW_IC_STATUS, status, in i2c_dw_wait_bus_not_busy()
554 dev_warn(dev->dev, "timeout waiting for bus ready\n"); in i2c_dw_wait_bus_not_busy()
556 i2c_recover_bus(&dev->adapter); in i2c_dw_wait_bus_not_busy()
558 regmap_read(dev->map, DW_IC_STATUS, &status); in i2c_dw_wait_bus_not_busy()
568 unsigned long abort_source = dev->abort_source; in i2c_dw_handle_tx_abort()
573 dev_dbg(dev->dev, in i2c_dw_handle_tx_abort()
575 return -EREMOTEIO; in i2c_dw_handle_tx_abort()
579 dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]); in i2c_dw_handle_tx_abort()
582 return -EAGAIN; in i2c_dw_handle_tx_abort()
584 return -EINVAL; /* wrong msgs[] data */ in i2c_dw_handle_tx_abort()
586 return -EIO; in i2c_dw_handle_tx_abort()
596 if ((dev->flags & MODEL_MASK) == MODEL_WANGXUN_SP) { in i2c_dw_set_fifo_size()
597 dev->tx_fifo_depth = TXGBE_TX_FIFO_DEPTH; in i2c_dw_set_fifo_size()
598 dev->rx_fifo_depth = TXGBE_RX_FIFO_DEPTH; in i2c_dw_set_fifo_size()
611 ret = regmap_read(dev->map, DW_IC_COMP_PARAM_1, &param); in i2c_dw_set_fifo_size()
618 if (!dev->tx_fifo_depth) { in i2c_dw_set_fifo_size()
619 dev->tx_fifo_depth = tx_fifo_depth; in i2c_dw_set_fifo_size()
620 dev->rx_fifo_depth = rx_fifo_depth; in i2c_dw_set_fifo_size()
622 dev->tx_fifo_depth = min_t(u32, dev->tx_fifo_depth, in i2c_dw_set_fifo_size()
624 dev->rx_fifo_depth = min_t(u32, dev->rx_fifo_depth, in i2c_dw_set_fifo_size()
635 return dev->functionality; in i2c_dw_func()
651 regmap_write(dev->map, DW_IC_INTR_MASK, 0); in i2c_dw_disable()
652 regmap_read(dev->map, DW_IC_CLR_INTR, &dummy); in i2c_dw_disable()
657 MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter core");