i2c changes for 2020.04
- updates the Designware I2C driver
  - get timings from device tree
  - handle units in nanoseconds
  - make sure that the requested bus speed is not exceeded
  - few smaller clean-ups
- adds enums for i2c speed and update drivers which use them
- global_data: remove unused mxc_i2c specific field
This commit is contained in:
Tom Rini 2020-01-29 09:34:13 -05:00
commit e7ab1cb3f0
25 changed files with 454 additions and 164 deletions

View file

@ -0,0 +1,73 @@
* Synopsys DesignWare I2C
Required properties :
- compatible : should be "snps,designware-i2c"
or "mscc,ocelot-i2c" with "snps,designware-i2c" for fallback
- reg : Offset and length of the register set for the device
- interrupts : <IRQ> where IRQ is the interrupt number.
- clocks : phandles for the clocks, see the description of clock-names below.
The phandle for the "ic_clk" clock is required. The phandle for the "pclk"
clock is optional. If a single clock is specified but no clock-name, it is
the "ic_clk" clock. If both clocks are listed, the "ic_clk" must be first.
Recommended properties :
- clock-frequency : desired I2C bus clock frequency in Hz.
Optional properties :
- clock-names : Contains the names of the clocks:
"ic_clk", for the core clock used to generate the external I2C clock.
"pclk", the interface clock, required for register access.
- reg : for "mscc,ocelot-i2c", a second register set to configure the SDA hold
time, named ICPU_CFG:TWI_DELAY in the datasheet.
- i2c-sda-hold-time-ns : should contain the SDA hold time in nanoseconds.
This option is only supported in hardware blocks version 1.11a or newer and
on Microsemi SoCs ("mscc,ocelot-i2c" compatible).
- i2c-scl-falling-time-ns : should contain the SCL falling time in nanoseconds.
This value which is by default 300ns is used to compute the tLOW period.
- i2c-sda-falling-time-ns : should contain the SDA falling time in nanoseconds.
This value which is by default 300ns is used to compute the tHIGH period.
Examples :
i2c@f0000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,designware-i2c";
reg = <0xf0000 0x1000>;
interrupts = <11>;
clock-frequency = <400000>;
};
i2c@1120000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,designware-i2c";
reg = <0x1120000 0x1000>;
interrupt-parent = <&ictl>;
interrupts = <12 1>;
clock-frequency = <400000>;
i2c-sda-hold-time-ns = <300>;
i2c-sda-falling-time-ns = <300>;
i2c-scl-falling-time-ns = <300>;
};x
i2c@1120000 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0x2000 0x100>;
clock-frequency = <400000>;
clocks = <&i2cclk>;
interrupts = <0>;
eeprom@64 {
compatible = "linux,slave-24c02";
reg = <0x40000064>;
};
};

View file

@ -314,7 +314,7 @@ static int ast_i2c_set_speed(struct udevice *dev, unsigned int speed)
divider = i2c_rate / speed; divider = i2c_rate / speed;
priv->speed = speed; priv->speed = speed;
if (speed > I2C_HIGHSPEED_RATE) { if (speed > I2C_SPEED_FAST_RATE) {
debug("Enable High Speed\n"); debug("Enable High Speed\n");
setbits_le32(&regs->fcr, I2CD_M_HIGH_SPEED_EN setbits_le32(&regs->fcr, I2CD_M_HIGH_SPEED_EN
| I2CD_M_SDA_DRIVE_1T_EN | I2CD_M_SDA_DRIVE_1T_EN

View file

@ -126,6 +126,4 @@ struct ast_i2c_regs {
#define I2CD_RX_DATA_SHIFT 8 #define I2CD_RX_DATA_SHIFT 8
#define I2CD_RX_DATA_MASK (0xff << I2CD_RX_DATA_SHIFT) #define I2CD_RX_DATA_MASK (0xff << I2CD_RX_DATA_SHIFT)
#define I2C_HIGHSPEED_RATE 400000
#endif /* __AST_I2C_H_ */ #endif /* __AST_I2C_H_ */

View file

@ -4,8 +4,8 @@
* Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
*/ */
#include <clk.h>
#include <common.h> #include <common.h>
#include <clk.h>
#include <dm.h> #include <dm.h>
#include <i2c.h> #include <i2c.h>
#include <pci.h> #include <pci.h>
@ -46,30 +46,220 @@ static int dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
} }
#endif #endif
/* High and low times in different speed modes (in ns) */
enum {
/* SDA Hold Time */
DEFAULT_SDA_HOLD_TIME = 300,
};
/**
* calc_counts() - Convert a period to a number of IC clk cycles
*
* @ic_clk: Input clock in Hz
* @period_ns: Period to represent, in ns
* @return calculated count
*/
static uint calc_counts(uint ic_clk, uint period_ns)
{
return DIV_ROUND_UP(ic_clk / 1000 * period_ns, NANO_TO_KILO);
}
/**
* struct i2c_mode_info - Information about an I2C speed mode
*
* Each speed mode has its own characteristics. This struct holds these to aid
* calculations in dw_i2c_calc_timing().
*
* @speed: Speed in Hz
* @min_scl_lowtime_ns: Minimum value for SCL low period in ns
* @min_scl_hightime_ns: Minimum value for SCL high period in ns
* @def_rise_time_ns: Default rise time in ns
* @def_fall_time_ns: Default fall time in ns
*/
struct i2c_mode_info {
int speed;
int min_scl_hightime_ns;
int min_scl_lowtime_ns;
int def_rise_time_ns;
int def_fall_time_ns;
};
static const struct i2c_mode_info info_for_mode[] = {
[IC_SPEED_MODE_STANDARD] = {
I2C_SPEED_STANDARD_RATE,
MIN_SS_SCL_HIGHTIME,
MIN_SS_SCL_LOWTIME,
1000,
300,
},
[IC_SPEED_MODE_FAST] = {
I2C_SPEED_FAST_RATE,
MIN_FS_SCL_HIGHTIME,
MIN_FS_SCL_LOWTIME,
300,
300,
},
[IC_SPEED_MODE_FAST_PLUS] = {
I2C_SPEED_FAST_PLUS_RATE,
MIN_FP_SCL_HIGHTIME,
MIN_FP_SCL_LOWTIME,
260,
500,
},
[IC_SPEED_MODE_HIGH] = {
I2C_SPEED_HIGH_RATE,
MIN_HS_SCL_HIGHTIME,
MIN_HS_SCL_LOWTIME,
120,
120,
},
};
/**
* dw_i2c_calc_timing() - Calculate the timings to use for a bus
*
* @priv: Bus private information (NULL if not using driver model)
* @mode: Speed mode to use
* @ic_clk: IC clock speed in Hz
* @spk_cnt: Spike-suppression count
* @config: Returns value to use
* @return 0 if OK, -EINVAL if the calculation failed due to invalid data
*/
static int dw_i2c_calc_timing(struct dw_i2c *priv, enum i2c_speed_mode mode,
int ic_clk, int spk_cnt,
struct dw_i2c_speed_config *config)
{
int fall_cnt, rise_cnt, min_tlow_cnt, min_thigh_cnt;
int hcnt, lcnt, period_cnt, diff, tot;
int sda_hold_time_ns, scl_rise_time_ns, scl_fall_time_ns;
const struct i2c_mode_info *info;
/*
* Find the period, rise, fall, min tlow, and min thigh in terms of
* counts of the IC clock
*/
info = &info_for_mode[mode];
period_cnt = ic_clk / info->speed;
scl_rise_time_ns = priv && priv->scl_rise_time_ns ?
priv->scl_rise_time_ns : info->def_rise_time_ns;
scl_fall_time_ns = priv && priv->scl_fall_time_ns ?
priv->scl_fall_time_ns : info->def_fall_time_ns;
rise_cnt = calc_counts(ic_clk, scl_rise_time_ns);
fall_cnt = calc_counts(ic_clk, scl_fall_time_ns);
min_tlow_cnt = calc_counts(ic_clk, info->min_scl_lowtime_ns);
min_thigh_cnt = calc_counts(ic_clk, info->min_scl_hightime_ns);
debug("dw_i2c: period %d rise %d fall %d tlow %d thigh %d spk %d\n",
period_cnt, rise_cnt, fall_cnt, min_tlow_cnt, min_thigh_cnt,
spk_cnt);
/*
* Back-solve for hcnt and lcnt according to the following equations:
* SCL_High_time = [(HCNT + IC_*_SPKLEN + 7) * ic_clk] + SCL_Fall_time
* SCL_Low_time = [(LCNT + 1) * ic_clk] - SCL_Fall_time + SCL_Rise_time
*/
hcnt = min_thigh_cnt - fall_cnt - 7 - spk_cnt;
lcnt = min_tlow_cnt - rise_cnt + fall_cnt - 1;
if (hcnt < 0 || lcnt < 0) {
debug("dw_i2c: bad counts. hcnt = %d lcnt = %d\n", hcnt, lcnt);
return -EINVAL;
}
/*
* Now add things back up to ensure the period is hit. If it is off,
* split the difference and bias to lcnt for remainder
*/
tot = hcnt + lcnt + 7 + spk_cnt + rise_cnt + 1;
if (tot < period_cnt) {
diff = (period_cnt - tot) / 2;
hcnt += diff;
lcnt += diff;
tot = hcnt + lcnt + 7 + spk_cnt + rise_cnt + 1;
lcnt += period_cnt - tot;
}
config->scl_lcnt = lcnt;
config->scl_hcnt = hcnt;
/* Use internal default unless other value is specified */
sda_hold_time_ns = priv && priv->sda_hold_time_ns ?
priv->sda_hold_time_ns : DEFAULT_SDA_HOLD_TIME;
config->sda_hold = calc_counts(ic_clk, sda_hold_time_ns);
debug("dw_i2c: hcnt = %d lcnt = %d sda hold = %d\n", hcnt, lcnt,
config->sda_hold);
return 0;
}
static int calc_bus_speed(struct dw_i2c *priv, int speed, ulong bus_clk,
struct dw_i2c_speed_config *config)
{
const struct dw_scl_sda_cfg *scl_sda_cfg = NULL;
struct i2c_regs *regs = priv->regs;
enum i2c_speed_mode i2c_spd;
int spk_cnt;
int ret;
if (priv)
scl_sda_cfg = priv->scl_sda_cfg;
/* Allow high speed if there is no config, or the config allows it */
if (speed >= I2C_SPEED_HIGH_RATE &&
(!scl_sda_cfg || scl_sda_cfg->has_high_speed))
i2c_spd = IC_SPEED_MODE_HIGH;
else if (speed >= I2C_SPEED_FAST_RATE)
i2c_spd = IC_SPEED_MODE_FAST_PLUS;
else if (speed >= I2C_SPEED_FAST_PLUS_RATE)
i2c_spd = IC_SPEED_MODE_FAST;
else
i2c_spd = IC_SPEED_MODE_STANDARD;
/* Get the proper spike-suppression count based on target speed */
if (!priv || !priv->has_spk_cnt)
spk_cnt = 0;
else if (i2c_spd >= IC_SPEED_MODE_HIGH)
spk_cnt = readl(&regs->hs_spklen);
else
spk_cnt = readl(&regs->fs_spklen);
if (scl_sda_cfg) {
config->sda_hold = scl_sda_cfg->sda_hold;
if (i2c_spd == IC_SPEED_MODE_STANDARD) {
config->scl_hcnt = scl_sda_cfg->ss_hcnt;
config->scl_lcnt = scl_sda_cfg->ss_lcnt;
} else {
config->scl_hcnt = scl_sda_cfg->fs_hcnt;
config->scl_lcnt = scl_sda_cfg->fs_lcnt;
}
} else {
ret = dw_i2c_calc_timing(priv, i2c_spd, bus_clk, spk_cnt,
config);
if (ret)
return log_msg_ret("gen_confg", ret);
}
config->speed_mode = i2c_spd;
return 0;
}
/* /*
* i2c_set_bus_speed - Set the i2c speed * _dw_i2c_set_bus_speed - Set the i2c speed
* @speed: required i2c speed * @speed: required i2c speed
* *
* Set the i2c speed. * Set the i2c speed.
*/ */
static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base, static int _dw_i2c_set_bus_speed(struct dw_i2c *priv, struct i2c_regs *i2c_base,
struct dw_scl_sda_cfg *scl_sda_cfg, unsigned int speed, unsigned int bus_clk)
unsigned int speed,
unsigned int bus_mhz)
{ {
struct dw_i2c_speed_config config;
unsigned int cntl; unsigned int cntl;
unsigned int hcnt, lcnt;
unsigned int ena; unsigned int ena;
int i2c_spd; int ret;
/* Allow max speed if there is no config, or the config allows it */ ret = calc_bus_speed(priv, speed, bus_clk, &config);
if (speed >= I2C_MAX_SPEED && if (ret)
(!scl_sda_cfg || scl_sda_cfg->has_max_speed)) return ret;
i2c_spd = IC_SPEED_MODE_MAX;
else if (speed >= I2C_FAST_SPEED)
i2c_spd = IC_SPEED_MODE_FAST;
else
i2c_spd = IC_SPEED_MODE_STANDARD;
/* Get enable setting for restore later */ /* Get enable setting for restore later */
ena = readl(&i2c_base->ic_enable) & IC_ENABLE_0B; ena = readl(&i2c_base->ic_enable) & IC_ENABLE_0B;
@ -79,53 +269,31 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base,
cntl = (readl(&i2c_base->ic_con) & (~IC_CON_SPD_MSK)); cntl = (readl(&i2c_base->ic_con) & (~IC_CON_SPD_MSK));
switch (i2c_spd) { switch (config.speed_mode) {
case IC_SPEED_MODE_MAX: case IC_SPEED_MODE_HIGH:
cntl |= IC_CON_SPD_SS; cntl |= IC_CON_SPD_SS;
if (scl_sda_cfg) { writel(config.scl_hcnt, &i2c_base->ic_hs_scl_hcnt);
hcnt = scl_sda_cfg->fs_hcnt; writel(config.scl_lcnt, &i2c_base->ic_hs_scl_lcnt);
lcnt = scl_sda_cfg->fs_lcnt;
} else {
hcnt = (bus_mhz * MIN_HS_SCL_HIGHTIME) / NANO_TO_MICRO;
lcnt = (bus_mhz * MIN_HS_SCL_LOWTIME) / NANO_TO_MICRO;
}
writel(hcnt, &i2c_base->ic_hs_scl_hcnt);
writel(lcnt, &i2c_base->ic_hs_scl_lcnt);
break; break;
case IC_SPEED_MODE_STANDARD: case IC_SPEED_MODE_STANDARD:
cntl |= IC_CON_SPD_SS; cntl |= IC_CON_SPD_SS;
if (scl_sda_cfg) { writel(config.scl_hcnt, &i2c_base->ic_ss_scl_hcnt);
hcnt = scl_sda_cfg->ss_hcnt; writel(config.scl_lcnt, &i2c_base->ic_ss_scl_lcnt);
lcnt = scl_sda_cfg->ss_lcnt;
} else {
hcnt = (bus_mhz * MIN_SS_SCL_HIGHTIME) / NANO_TO_MICRO;
lcnt = (bus_mhz * MIN_SS_SCL_LOWTIME) / NANO_TO_MICRO;
}
writel(hcnt, &i2c_base->ic_ss_scl_hcnt);
writel(lcnt, &i2c_base->ic_ss_scl_lcnt);
break; break;
case IC_SPEED_MODE_FAST_PLUS:
case IC_SPEED_MODE_FAST: case IC_SPEED_MODE_FAST:
default: default:
cntl |= IC_CON_SPD_FS; cntl |= IC_CON_SPD_FS;
if (scl_sda_cfg) { writel(config.scl_hcnt, &i2c_base->ic_fs_scl_hcnt);
hcnt = scl_sda_cfg->fs_hcnt; writel(config.scl_lcnt, &i2c_base->ic_fs_scl_lcnt);
lcnt = scl_sda_cfg->fs_lcnt;
} else {
hcnt = (bus_mhz * MIN_FS_SCL_HIGHTIME) / NANO_TO_MICRO;
lcnt = (bus_mhz * MIN_FS_SCL_LOWTIME) / NANO_TO_MICRO;
}
writel(hcnt, &i2c_base->ic_fs_scl_hcnt);
writel(lcnt, &i2c_base->ic_fs_scl_lcnt);
break; break;
} }
writel(cntl, &i2c_base->ic_con); writel(cntl, &i2c_base->ic_con);
/* Configure SDA Hold Time if required */ /* Configure SDA Hold Time if required */
if (scl_sda_cfg) if (config.sda_hold)
writel(scl_sda_cfg->sda_hold, &i2c_base->ic_sda_hold); writel(config.sda_hold, &i2c_base->ic_sda_hold);
/* Restore back i2c now speed set */ /* Restore back i2c now speed set */
if (ena == IC_ENABLE_0B) if (ena == IC_ENABLE_0B)
@ -370,7 +538,7 @@ static int __dw_i2c_init(struct i2c_regs *i2c_base, int speed, int slaveaddr)
writel(IC_TX_TL, &i2c_base->ic_tx_tl); writel(IC_TX_TL, &i2c_base->ic_tx_tl);
writel(IC_STOP_DET, &i2c_base->ic_intr_mask); writel(IC_STOP_DET, &i2c_base->ic_intr_mask);
#ifndef CONFIG_DM_I2C #ifndef CONFIG_DM_I2C
__dw_i2c_set_bus_speed(i2c_base, NULL, speed, IC_CLK); _dw_i2c_set_bus_speed(NULL, i2c_base, speed, IC_CLK);
writel(slaveaddr, &i2c_base->ic_sar); writel(slaveaddr, &i2c_base->ic_sar);
#endif #endif
@ -415,7 +583,7 @@ static unsigned int dw_i2c_set_bus_speed(struct i2c_adapter *adap,
unsigned int speed) unsigned int speed)
{ {
adap->speed = speed; adap->speed = speed;
return __dw_i2c_set_bus_speed(i2c_get_base(adap), NULL, speed, IC_CLK); return _dw_i2c_set_bus_speed(NULL, i2c_get_base(adap), speed, IC_CLK);
} }
static void dw_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr) static void dw_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
@ -511,14 +679,10 @@ static int designware_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
rate = clk_get_rate(&i2c->clk); rate = clk_get_rate(&i2c->clk);
if (IS_ERR_VALUE(rate)) if (IS_ERR_VALUE(rate))
return -EINVAL; return -EINVAL;
/* Convert to MHz */
rate /= 1000000;
#else #else
rate = IC_CLK; rate = IC_CLK;
#endif #endif
return __dw_i2c_set_bus_speed(i2c->regs, i2c->scl_sda_cfg, speed, return _dw_i2c_set_bus_speed(i2c, i2c->regs, speed, rate);
rate);
} }
static int designware_i2c_probe_chip(struct udevice *bus, uint chip_addr, static int designware_i2c_probe_chip(struct udevice *bus, uint chip_addr,
@ -537,20 +701,17 @@ static int designware_i2c_probe_chip(struct udevice *bus, uint chip_addr,
return ret; return ret;
} }
static int designware_i2c_ofdata_to_platdata(struct udevice *bus) int designware_i2c_ofdata_to_platdata(struct udevice *bus)
{
struct dw_i2c *priv = dev_get_priv(bus);
priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus);
return 0;
}
int designware_i2c_probe(struct udevice *bus)
{ {
struct dw_i2c *priv = dev_get_priv(bus); struct dw_i2c *priv = dev_get_priv(bus);
int ret; int ret;
if (!priv->regs)
priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus);
dev_read_u32(bus, "i2c-scl-rising-time-ns", &priv->scl_rise_time_ns);
dev_read_u32(bus, "i2c-scl-falling-time-ns", &priv->scl_fall_time_ns);
dev_read_u32(bus, "i2c-sda-hold-time-ns", &priv->sda_hold_time_ns);
ret = reset_get_bulk(bus, &priv->resets); ret = reset_get_bulk(bus, &priv->resets);
if (ret) if (ret)
dev_warn(bus, "Can't get reset: %d\n", ret); dev_warn(bus, "Can't get reset: %d\n", ret);
@ -570,6 +731,13 @@ int designware_i2c_probe(struct udevice *bus)
} }
#endif #endif
return 0;
}
int designware_i2c_probe(struct udevice *bus)
{
struct dw_i2c *priv = dev_get_priv(bus);
return __dw_i2c_init(priv->regs, 0, 0); return __dw_i2c_init(priv->regs, 0, 0);
} }

View file

@ -7,6 +7,8 @@
#ifndef __DW_I2C_H_ #ifndef __DW_I2C_H_
#define __DW_I2C_H_ #define __DW_I2C_H_
#include <clk.h>
#include <i2c.h>
#include <reset.h> #include <reset.h>
struct i2c_regs { struct i2c_regs {
@ -43,20 +45,32 @@ struct i2c_regs {
u32 ic_rxflr; /* 0x78 */ u32 ic_rxflr; /* 0x78 */
u32 ic_sda_hold; /* 0x7c */ u32 ic_sda_hold; /* 0x7c */
u32 ic_tx_abrt_source; /* 0x80 */ u32 ic_tx_abrt_source; /* 0x80 */
u8 res1[0x18]; /* 0x84 */ u32 slv_data_nak_only;
u32 dma_cr;
u32 dma_tdlr;
u32 dma_rdlr;
u32 sda_setup;
u32 ack_general_call;
u32 ic_enable_status; /* 0x9c */ u32 ic_enable_status; /* 0x9c */
u32 fs_spklen;
u32 hs_spklen;
u32 clr_restart_det;
u8 reserved[0xf4 - 0xac];
u32 comp_param1; /* 0xf4 */
u32 comp_version;
u32 comp_type;
}; };
#if !defined(IC_CLK) #define IC_CLK 166666666
#define IC_CLK 166 #define NANO_TO_KILO 1000000
#endif
#define NANO_TO_MICRO 1000
/* High and low times in different speed modes (in ns) */ /* High and low times in different speed modes (in ns) */
#define MIN_SS_SCL_HIGHTIME 4000 #define MIN_SS_SCL_HIGHTIME 4000
#define MIN_SS_SCL_LOWTIME 4700 #define MIN_SS_SCL_LOWTIME 4700
#define MIN_FS_SCL_HIGHTIME 600 #define MIN_FS_SCL_HIGHTIME 600
#define MIN_FS_SCL_LOWTIME 1300 #define MIN_FS_SCL_LOWTIME 1300
#define MIN_FP_SCL_HIGHTIME 260
#define MIN_FP_SCL_LOWTIME 500
#define MIN_HS_SCL_HIGHTIME 60 #define MIN_HS_SCL_HIGHTIME 60
#define MIN_HS_SCL_LOWTIME 160 #define MIN_HS_SCL_LOWTIME 160
@ -124,19 +138,10 @@ struct i2c_regs {
#define IC_STATUS_TFNF 0x0002 #define IC_STATUS_TFNF 0x0002
#define IC_STATUS_ACT 0x0001 #define IC_STATUS_ACT 0x0001
/* Speed Selection */
#define IC_SPEED_MODE_STANDARD 1
#define IC_SPEED_MODE_FAST 2
#define IC_SPEED_MODE_MAX 3
#define I2C_MAX_SPEED 3400000
#define I2C_FAST_SPEED 400000
#define I2C_STANDARD_SPEED 100000
/** /**
* struct dw_scl_sda_cfg - I2C timing configuration * struct dw_scl_sda_cfg - I2C timing configuration
* *
* @has_max_speed: Support maximum speed (1Mbps) * @has_high_speed: Support high speed (3.4Mbps)
* @ss_hcnt: Standard speed high time in ns * @ss_hcnt: Standard speed high time in ns
* @fs_hcnt: Fast speed high time in ns * @fs_hcnt: Fast speed high time in ns
* @ss_lcnt: Standard speed low time in ns * @ss_lcnt: Standard speed low time in ns
@ -144,7 +149,7 @@ struct i2c_regs {
* @sda_hold: SDA hold time * @sda_hold: SDA hold time
*/ */
struct dw_scl_sda_cfg { struct dw_scl_sda_cfg {
bool has_max_speed; bool has_high_speed;
u32 ss_hcnt; u32 ss_hcnt;
u32 fs_hcnt; u32 fs_hcnt;
u32 ss_lcnt; u32 ss_lcnt;
@ -152,10 +157,45 @@ struct dw_scl_sda_cfg {
u32 sda_hold; u32 sda_hold;
}; };
/**
* struct dw_i2c_speed_config - timings to use for a particular speed
*
* This holds calculated values to be written to the I2C controller. Each value
* is represented as a number of IC clock cycles.
*
* @scl_lcnt: Low count value for SCL
* @scl_hcnt: High count value for SCL
* @sda_hold: Data hold count
* @speed_mode: Speed mode being used
*/
struct dw_i2c_speed_config {
/* SCL high and low period count */
u16 scl_lcnt;
u16 scl_hcnt;
u32 sda_hold;
enum i2c_speed_mode speed_mode;
};
/**
* struct dw_i2c - private information for the bus
*
* @regs: Registers pointer
* @scl_sda_cfg: Deprecated information for x86 (should move to device tree)
* @resets: Resets for the I2C controller
* @scl_rise_time_ns: Configured SCL rise time in nanoseconds
* @scl_fall_time_ns: Configured SCL fall time in nanoseconds
* @sda_hold_time_ns: Configured SDA hold time in nanoseconds
* @has_spk_cnt: true if the spike-count register is present
* @clk: Clock input to the I2C controller
*/
struct dw_i2c { struct dw_i2c {
struct i2c_regs *regs; struct i2c_regs *regs;
struct dw_scl_sda_cfg *scl_sda_cfg; struct dw_scl_sda_cfg *scl_sda_cfg;
struct reset_ctl_bulk resets; struct reset_ctl_bulk resets;
u32 scl_rise_time_ns;
u32 scl_fall_time_ns;
u32 sda_hold_time_ns;
bool has_spk_cnt;
#if CONFIG_IS_ENABLED(CLK) #if CONFIG_IS_ENABLED(CLK)
struct clk clk; struct clk clk;
#endif #endif
@ -165,5 +205,6 @@ extern const struct dm_i2c_ops designware_i2c_ops;
int designware_i2c_probe(struct udevice *bus); int designware_i2c_probe(struct udevice *bus);
int designware_i2c_remove(struct udevice *dev); int designware_i2c_remove(struct udevice *dev);
int designware_i2c_ofdata_to_platdata(struct udevice *bus);
#endif /* __DW_I2C_H_ */ #endif /* __DW_I2C_H_ */

View file

@ -62,8 +62,10 @@ static int designware_i2c_pci_ofdata_to_platdata(struct udevice *dev)
if (IS_ENABLED(CONFIG_INTEL_BAYTRAIL)) if (IS_ENABLED(CONFIG_INTEL_BAYTRAIL))
/* Use BayTrail specific timing values */ /* Use BayTrail specific timing values */
priv->scl_sda_cfg = &byt_config; priv->scl_sda_cfg = &byt_config;
if (dev_get_driver_data(dev) == INTEL_APL)
priv->has_spk_cnt = true;
return 0; return designware_i2c_ofdata_to_platdata(dev);
} }
static int designware_i2c_pci_probe(struct udevice *dev) static int designware_i2c_pci_probe(struct udevice *dev)

View file

@ -527,8 +527,9 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
i2c_bus->id = pinmux_decode_periph_id(blob, node); i2c_bus->id = pinmux_decode_periph_id(blob, node);
i2c_bus->clock_frequency = fdtdec_get_int(blob, node, i2c_bus->clock_frequency =
"clock-frequency", 100000); dev_read_u32_default(dev, "clock-frequency",
I2C_SPEED_STANDARD_RATE);
i2c_bus->node = node; i2c_bus->node = node;
i2c_bus->bus_num = dev->seq; i2c_bus->bus_num = dev->seq;

View file

@ -584,7 +584,8 @@ static int fsl_i2c_ofdata_to_platdata(struct udevice *bus)
dev->index = dev_read_u32_default(bus, "cell-index", -1); dev->index = dev_read_u32_default(bus, "cell-index", -1);
dev->slaveadd = dev_read_u32_default(bus, "u-boot,i2c-slave-addr", dev->slaveadd = dev_read_u32_default(bus, "u-boot,i2c-slave-addr",
0x7f); 0x7f);
dev->speed = dev_read_u32_default(bus, "clock-frequency", 400000); dev->speed = dev_read_u32_default(bus, "clock-frequency",
I2C_SPEED_FAST_RATE);
if (!clk_get_by_index(bus, 0, &clock)) if (!clk_get_by_index(bus, 0, &clock))
dev->i2c_clk = clk_get_rate(&clock); dev->i2c_clk = clk_get_rate(&clock);

View file

@ -213,7 +213,7 @@ static int cdns_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
unsigned long speed_p = speed; unsigned long speed_p = speed;
int ret = 0; int ret = 0;
if (speed > 400000) { if (speed > I2C_SPEED_FAST_RATE) {
debug("%s, failed to set clock speed to %u\n", __func__, debug("%s, failed to set clock speed to %u\n", __func__,
speed); speed);
return -EINVAL; return -EINVAL;

View file

@ -641,7 +641,8 @@ static int i2c_post_probe(struct udevice *dev)
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
struct dm_i2c_bus *i2c = dev_get_uclass_priv(dev); struct dm_i2c_bus *i2c = dev_get_uclass_priv(dev);
i2c->speed_hz = dev_read_u32_default(dev, "clock-frequency", 100000); i2c->speed_hz = dev_read_u32_default(dev, "clock-frequency",
I2C_SPEED_STANDARD_RATE);
return dm_i2c_set_bus_speed(dev, i2c->speed_hz); return dm_i2c_set_bus_speed(dev, i2c->speed_hz);
#else #else
@ -699,11 +700,10 @@ int i2c_uclass_init(struct uclass *class)
return -ENOMEM; return -ENOMEM;
/* Get the last allocated alias. */ /* Get the last allocated alias. */
#if CONFIG_IS_ENABLED(OF_CONTROL) if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA))
priv->max_id = dev_read_alias_highest_id("i2c"); priv->max_id = dev_read_alias_highest_id("i2c");
#else else
priv->max_id = -1; priv->max_id = -1;
#endif
debug("%s: highest alias id is %d\n", __func__, priv->max_id); debug("%s: highest alias id is %d\n", __func__, priv->max_id);

View file

@ -281,7 +281,7 @@ static int uniphier_fi2c_set_bus_speed(struct udevice *bus, unsigned int speed)
struct uniphier_fi2c_regs __iomem *regs = priv->regs; struct uniphier_fi2c_regs __iomem *regs = priv->regs;
/* max supported frequency is 400 kHz */ /* max supported frequency is 400 kHz */
if (speed > 400000) if (speed > I2C_SPEED_FAST_RATE)
return -EINVAL; return -EINVAL;
ret = uniphier_fi2c_check_bus_busy(priv); ret = uniphier_fi2c_check_bus_busy(priv);

View file

@ -177,7 +177,7 @@ static int uniphier_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
struct uniphier_i2c_priv *priv = dev_get_priv(bus); struct uniphier_i2c_priv *priv = dev_get_priv(bus);
/* max supported frequency is 400 kHz */ /* max supported frequency is 400 kHz */
if (speed > 400000) if (speed > I2C_SPEED_FAST_RATE)
return -EINVAL; return -EINVAL;
/* bus reset: make sure the bus is idle when change the frequency */ /* bus reset: make sure the bus is idle when change the frequency */

View file

@ -169,7 +169,7 @@ static int bus_i2c_start(struct udevice *bus, u8 addr, u8 dir)
debug("i2c: start check busy bus: 0x%x\n", result); debug("i2c: start check busy bus: 0x%x\n", result);
/* Try to init the lpi2c then check the bus busy again */ /* Try to init the lpi2c then check the bus busy again */
bus_i2c_init(bus, 100000); bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
result = imx_lpci2c_check_busy_bus(regs); result = imx_lpci2c_check_busy_bus(regs);
if (result) { if (result) {
printf("i2c: Error check busy bus: 0x%x\n", result); printf("i2c: Error check busy bus: 0x%x\n", result);
@ -388,13 +388,13 @@ static int imx_lpi2c_probe_chip(struct udevice *bus, u32 chip,
result = bus_i2c_start(bus, chip, 0); result = bus_i2c_start(bus, chip, 0);
if (result) { if (result) {
bus_i2c_stop(bus); bus_i2c_stop(bus);
bus_i2c_init(bus, 100000); bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
return result; return result;
} }
result = bus_i2c_stop(bus); result = bus_i2c_stop(bus);
if (result) if (result)
bus_i2c_init(bus, 100000); bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
return result; return result;
} }
@ -489,7 +489,7 @@ static int imx_lpi2c_probe(struct udevice *bus)
return ret; return ret;
} }
ret = bus_i2c_init(bus, 100000); ret = bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
if (ret < 0) if (ret < 0)
return ret; return ret;

View file

@ -98,12 +98,6 @@ enum bcm_kona_cmd_t {
BCM_CMD_STOP, BCM_CMD_STOP,
}; };
enum bus_speed_index {
BCM_SPD_100K = 0,
BCM_SPD_400K,
BCM_SPD_1MHZ,
};
/* Internal divider settings for standard mode, fast mode and fast mode plus */ /* Internal divider settings for standard mode, fast mode and fast mode plus */
struct bus_speed_cfg { struct bus_speed_cfg {
uint8_t time_m; /* Number of cycles for setup time */ uint8_t time_m; /* Number of cycles for setup time */
@ -115,9 +109,9 @@ struct bus_speed_cfg {
}; };
static const struct bus_speed_cfg std_cfg_table[] = { static const struct bus_speed_cfg std_cfg_table[] = {
[BCM_SPD_100K] = {0x01, 0x01, 0x03, 0x06, 0x00, 0x02}, [IC_SPEED_MODE_STANDARD] = {0x01, 0x01, 0x03, 0x06, 0x00, 0x02},
[BCM_SPD_400K] = {0x05, 0x01, 0x03, 0x05, 0x01, 0x02}, [IC_SPEED_MODE_FAST] = {0x05, 0x01, 0x03, 0x05, 0x01, 0x02},
[BCM_SPD_1MHZ] = {0x01, 0x01, 0x03, 0x01, 0x01, 0x03}, [IC_SPEED_MODE_FAST_PLUS] = {0x01, 0x01, 0x03, 0x01, 0x01, 0x03},
}; };
struct bcm_kona_i2c_dev { struct bcm_kona_i2c_dev {
@ -127,8 +121,8 @@ struct bcm_kona_i2c_dev {
}; };
/* Keep these two defines in sync */ /* Keep these two defines in sync */
#define DEF_SPD 100000 #define DEF_SPD I2C_SPEED_STANDARD_RATE
#define DEF_SPD_ENUM BCM_SPD_100K #define DEF_SPD_ENUM IC_SPEED_MODE_STANDARD
#define DEF_DEVICE(num) \ #define DEF_DEVICE(num) \
{(void *)CONFIG_SYS_I2C_BASE##num, DEF_SPD, &std_cfg_table[DEF_SPD_ENUM]} {(void *)CONFIG_SYS_I2C_BASE##num, DEF_SPD, &std_cfg_table[DEF_SPD_ENUM]}
@ -560,14 +554,14 @@ static uint bcm_kona_i2c_assign_bus_speed(struct bcm_kona_i2c_dev *dev,
uint speed) uint speed)
{ {
switch (speed) { switch (speed) {
case 100000: case I2C_SPEED_STANDARD_RATE:
dev->std_cfg = &std_cfg_table[BCM_SPD_100K]; dev->std_cfg = &std_cfg_table[IC_SPEED_MODE_STANDARD];
break; break;
case 400000: case I2C_SPEED_FAST_RATE:
dev->std_cfg = &std_cfg_table[BCM_SPD_400K]; dev->std_cfg = &std_cfg_table[IC_SPEED_MODE_FAST];
break; break;
case 1000000: case I2C_SPEED_FAST_PLUS_RATE:
dev->std_cfg = &std_cfg_table[BCM_SPD_1MHZ]; dev->std_cfg = &std_cfg_table[IC_SPEED_MODE_FAST_PLUS];
break; break;
default: default:
printf("%d hz bus speed not supported\n", speed); printf("%d hz bus speed not supported\n", speed);

View file

@ -434,7 +434,7 @@ void i2c_init(int speed, int slaveaddr)
base_glob = (struct mv_i2c *)CONFIG_MV_I2C_REG; base_glob = (struct mv_i2c *)CONFIG_MV_I2C_REG;
#endif #endif
if (speed > 100000) if (speed > I2C_SPEED_STANDARD_RATE)
val = ICR_FM; val = ICR_FM;
else else
val = ICR_SM; val = ICR_SM;
@ -565,7 +565,7 @@ static int mv_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
struct mv_i2c_priv *priv = dev_get_priv(bus); struct mv_i2c_priv *priv = dev_get_priv(bus);
u32 val; u32 val;
if (speed > 100000) if (speed > I2C_SPEED_STANDARD_RATE)
val = ICR_FM; val = ICR_FM;
else else
val = ICR_SM; val = ICR_SM;

View file

@ -805,8 +805,9 @@ static int mvtwsi_i2c_ofdata_to_platdata(struct udevice *bus)
"cell-index", -1); "cell-index", -1);
dev->slaveadd = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus), dev->slaveadd = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
"u-boot,i2c-slave-addr", 0x0); "u-boot,i2c-slave-addr", 0x0);
dev->speed = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus), dev->speed = dev_read_u32_default(bus, "clock-frequency",
"clock-frequency", 100000); I2C_SPEED_STANDARD_RATE);
return 0; return 0;
} }

View file

@ -306,7 +306,7 @@ static int __omap24_i2c_setspeed(void __iomem *i2c_base, int ip_rev, uint speed,
int hsscll = 0, hssclh = 0; int hsscll = 0, hssclh = 0;
u32 scll = 0, sclh = 0; u32 scll = 0, sclh = 0;
if (speed >= OMAP_I2C_HIGH_SPEED) { if (speed >= I2C_SPEED_HIGH_RATE) {
/* High speed */ /* High speed */
psc = I2C_IP_CLK / I2C_INTERNAL_SAMPLING_CLK; psc = I2C_IP_CLK / I2C_INTERNAL_SAMPLING_CLK;
psc -= 1; psc -= 1;
@ -1066,7 +1066,8 @@ static int omap_i2c_ofdata_to_platdata(struct udevice *bus)
struct omap_i2c_platdata *plat = dev_get_platdata(bus); struct omap_i2c_platdata *plat = dev_get_platdata(bus);
plat->base = devfdt_get_addr(bus); plat->base = devfdt_get_addr(bus);
plat->speed = dev_read_u32_default(bus, "clock-frequency", 100000); plat->speed = dev_read_u32_default(bus, "clock-frequency",
I2C_SPEED_STANDARD_RATE);
plat->ip_rev = dev_get_driver_data(bus); plat->ip_rev = dev_get_driver_data(bus);
return 0; return 0;

View file

@ -81,10 +81,6 @@
#define I2C_SCLH_HSSCLH 8 #define I2C_SCLH_HSSCLH 8
#define I2C_SCLH_HSSCLH_M 0xFF #define I2C_SCLH_HSSCLH_M 0xFF
#define OMAP_I2C_STANDARD 100000
#define OMAP_I2C_FAST_MODE 400000
#define OMAP_I2C_HIGH_SPEED 3400000
#define SYSTEM_CLOCK_12 12000000 #define SYSTEM_CLOCK_12 12000000
#define SYSTEM_CLOCK_13 13000000 #define SYSTEM_CLOCK_13 13000000
#define SYSTEM_CLOCK_192 19200000 #define SYSTEM_CLOCK_192 19200000

View file

@ -344,7 +344,7 @@ static int rcar_i2c_probe(struct udevice *dev)
writel(0, priv->base + RCAR_I2C_ICMSR); writel(0, priv->base + RCAR_I2C_ICMSR);
writel(0, priv->base + RCAR_I2C_ICMAR); writel(0, priv->base + RCAR_I2C_ICMAR);
ret = rcar_i2c_set_speed(dev, 100000); ret = rcar_i2c_set_speed(dev, I2C_SPEED_STANDARD_RATE);
if (ret) if (ret)
clk_disable(&priv->clk); clk_disable(&priv->clk);

View file

@ -248,7 +248,7 @@ static int rcar_iic_probe(struct udevice *dev)
rcar_iic_finish(dev); rcar_iic_finish(dev);
return rcar_iic_set_speed(dev, 100000); return rcar_iic_set_speed(dev, I2C_SPEED_STANDARD_RATE);
} }
static const struct dm_i2c_ops rcar_iic_ops = { static const struct dm_i2c_ops rcar_iic_ops = {

View file

@ -313,8 +313,9 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
i2c_bus->id = pinmux_decode_periph_id(blob, node); i2c_bus->id = pinmux_decode_periph_id(blob, node);
i2c_bus->clock_frequency = fdtdec_get_int(blob, node, i2c_bus->clock_frequency =
"clock-frequency", 100000); dev_read_u32_default(dev, "clock-frequency",
I2C_SPEED_STANDARD_RATE);
i2c_bus->node = node; i2c_bus->node = node;
i2c_bus->bus_num = dev->seq; i2c_bus->bus_num = dev->seq;

View file

@ -72,7 +72,8 @@ static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
* 400KHz for reads. * 400KHz for reads.
*/ */
is_read = nmsgs > 1; is_read = nmsgs > 1;
if (i2c->speed_hz > (is_read ? 400000 : 100000)) { if (i2c->speed_hz > (is_read ? I2C_SPEED_FAST_RATE :
I2C_SPEED_STANDARD_RATE)) {
debug("%s: Max speed exceeded\n", __func__); debug("%s: Max speed exceeded\n", __func__);
return -EINVAL; return -EINVAL;
} }

View file

@ -115,17 +115,6 @@ struct stm32_i2c_regs {
#define STM32_NSEC_PER_SEC 1000000000L #define STM32_NSEC_PER_SEC 1000000000L
#define STANDARD_RATE 100000
#define FAST_RATE 400000
#define FAST_PLUS_RATE 1000000
enum stm32_i2c_speed {
STM32_I2C_SPEED_STANDARD, /* 100 kHz */
STM32_I2C_SPEED_FAST, /* 400 kHz */
STM32_I2C_SPEED_FAST_PLUS, /* 1 MHz */
STM32_I2C_SPEED_END,
};
/** /**
* struct stm32_i2c_spec - private i2c specification timing * struct stm32_i2c_spec - private i2c specification timing
* @rate: I2C bus speed (Hz) * @rate: I2C bus speed (Hz)
@ -164,7 +153,7 @@ struct stm32_i2c_spec {
* @analog_filter: Analog filter delay (On/Off) * @analog_filter: Analog filter delay (On/Off)
*/ */
struct stm32_i2c_setup { struct stm32_i2c_setup {
enum stm32_i2c_speed speed; enum i2c_speed_mode speed;
u32 speed_freq; u32 speed_freq;
u32 clock_src; u32 clock_src;
u32 rise_time; u32 rise_time;
@ -198,8 +187,8 @@ struct stm32_i2c_priv {
}; };
static const struct stm32_i2c_spec i2c_specs[] = { static const struct stm32_i2c_spec i2c_specs[] = {
[STM32_I2C_SPEED_STANDARD] = { [IC_SPEED_MODE_STANDARD] = {
.rate = STANDARD_RATE, .rate = I2C_SPEED_STANDARD_RATE,
.rate_min = 8000, .rate_min = 8000,
.rate_max = 120000, .rate_max = 120000,
.fall_max = 300, .fall_max = 300,
@ -210,8 +199,8 @@ static const struct stm32_i2c_spec i2c_specs[] = {
.l_min = 4700, .l_min = 4700,
.h_min = 4000, .h_min = 4000,
}, },
[STM32_I2C_SPEED_FAST] = { [IC_SPEED_MODE_FAST] = {
.rate = FAST_RATE, .rate = I2C_SPEED_FAST_RATE,
.rate_min = 320000, .rate_min = 320000,
.rate_max = 480000, .rate_max = 480000,
.fall_max = 300, .fall_max = 300,
@ -222,8 +211,8 @@ static const struct stm32_i2c_spec i2c_specs[] = {
.l_min = 1300, .l_min = 1300,
.h_min = 600, .h_min = 600,
}, },
[STM32_I2C_SPEED_FAST_PLUS] = { [IC_SPEED_MODE_FAST_PLUS] = {
.rate = FAST_PLUS_RATE, .rate = I2C_SPEED_FAST_PLUS_RATE,
.rate_min = 800000, .rate_min = 800000,
.rate_max = 1200000, .rate_max = 1200000,
.fall_max = 100, .fall_max = 100,
@ -648,9 +637,9 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv,
struct list_head solutions; struct list_head solutions;
int ret; int ret;
if (setup->speed >= STM32_I2C_SPEED_END) { if (setup->speed >= ARRAY_SIZE(i2c_specs)) {
pr_err("%s: speed out of bound {%d/%d}\n", __func__, pr_err("%s: speed out of bound {%d/%d}\n", __func__,
setup->speed, STM32_I2C_SPEED_END - 1); setup->speed, ARRAY_SIZE(i2c_specs) - 1);
return -EINVAL; return -EINVAL;
} }
@ -719,7 +708,7 @@ static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv,
if (ret) { if (ret) {
debug("%s: failed to compute I2C timings.\n", debug("%s: failed to compute I2C timings.\n",
__func__); __func__);
if (i2c_priv->speed > STM32_I2C_SPEED_STANDARD) { if (i2c_priv->speed > IC_SPEED_MODE_STANDARD) {
i2c_priv->speed--; i2c_priv->speed--;
setup->speed = i2c_priv->speed; setup->speed = i2c_priv->speed;
setup->speed_freq = setup->speed_freq =
@ -784,14 +773,14 @@ static int stm32_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
struct stm32_i2c_priv *i2c_priv = dev_get_priv(bus); struct stm32_i2c_priv *i2c_priv = dev_get_priv(bus);
switch (speed) { switch (speed) {
case STANDARD_RATE: case I2C_SPEED_STANDARD_RATE:
i2c_priv->speed = STM32_I2C_SPEED_STANDARD; i2c_priv->speed = IC_SPEED_MODE_STANDARD;
break; break;
case FAST_RATE: case I2C_SPEED_FAST_RATE:
i2c_priv->speed = STM32_I2C_SPEED_FAST; i2c_priv->speed = IC_SPEED_MODE_FAST;
break; break;
case FAST_PLUS_RATE: case I2C_SPEED_FAST_PLUS_RATE:
i2c_priv->speed = STM32_I2C_SPEED_FAST_PLUS; i2c_priv->speed = IC_SPEED_MODE_FAST_PLUS;
break; break;
default: default:
debug("%s: Speed %d not supported\n", __func__, speed); debug("%s: Speed %d not supported\n", __func__, speed);

View file

@ -89,9 +89,6 @@ typedef struct global_data {
#endif #endif
#if defined(CONFIG_SYS_I2C) #if defined(CONFIG_SYS_I2C)
int cur_i2c_bus; /* current used i2c bus */ int cur_i2c_bus; /* current used i2c bus */
#endif
#ifdef CONFIG_SYS_I2C_MXC
void *srdata[10];
#endif #endif
unsigned int timebase_h; unsigned int timebase_h;
unsigned int timebase_l; unsigned int timebase_l;

View file

@ -30,6 +30,32 @@ enum dm_i2c_chip_flags {
DM_I2C_CHIP_WR_ADDRESS = 1 << 2, /* Send address for each write byte */ DM_I2C_CHIP_WR_ADDRESS = 1 << 2, /* Send address for each write byte */
}; };
/** enum i2c_speed_mode - standard I2C speed modes */
enum i2c_speed_mode {
IC_SPEED_MODE_STANDARD,
IC_SPEED_MODE_FAST,
IC_SPEED_MODE_FAST_PLUS,
IC_SPEED_MODE_HIGH,
IC_SPEED_MODE_FAST_ULTRA,
IC_SPEED_MODE_COUNT,
};
/** enum i2c_speed_rate - standard I2C speeds in Hz */
enum i2c_speed_rate {
I2C_SPEED_STANDARD_RATE = 100000,
I2C_SPEED_FAST_RATE = 400000,
I2C_SPEED_FAST_PLUS_RATE = 1000000,
I2C_SPEED_HIGH_RATE = 3400000,
I2C_SPEED_FAST_ULTRA_RATE = 5000000,
};
/** enum i2c_address_mode - available address modes */
enum i2c_address_mode {
I2C_MODE_7_BIT,
I2C_MODE_10_BIT
};
struct udevice; struct udevice;
/** /**
* struct dm_i2c_chip - information about an i2c chip * struct dm_i2c_chip - information about an i2c chip