Merge tag 'for-v2020.04' of https://gitlab.denx.de/u-boot/custodians/u-boot-i2c
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:
commit
e7ab1cb3f0
73
doc/device-tree-bindings/i2c/i2c-designware.txt
Normal file
73
doc/device-tree-bindings/i2c/i2c-designware.txt
Normal 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>;
|
||||
};
|
||||
};
|
@ -314,7 +314,7 @@ static int ast_i2c_set_speed(struct udevice *dev, unsigned int speed)
|
||||
divider = i2c_rate / speed;
|
||||
|
||||
priv->speed = speed;
|
||||
if (speed > I2C_HIGHSPEED_RATE) {
|
||||
if (speed > I2C_SPEED_FAST_RATE) {
|
||||
debug("Enable High Speed\n");
|
||||
setbits_le32(®s->fcr, I2CD_M_HIGH_SPEED_EN
|
||||
| I2CD_M_SDA_DRIVE_1T_EN
|
||||
|
@ -126,6 +126,4 @@ struct ast_i2c_regs {
|
||||
#define I2CD_RX_DATA_SHIFT 8
|
||||
#define I2CD_RX_DATA_MASK (0xff << I2CD_RX_DATA_SHIFT)
|
||||
|
||||
#define I2C_HIGHSPEED_RATE 400000
|
||||
|
||||
#endif /* __AST_I2C_H_ */
|
||||
|
@ -4,8 +4,8 @@
|
||||
* Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
|
||||
*/
|
||||
|
||||
#include <clk.h>
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <i2c.h>
|
||||
#include <pci.h>
|
||||
@ -46,30 +46,220 @@ static int dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
|
||||
}
|
||||
#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(®s->hs_spklen);
|
||||
else
|
||||
spk_cnt = readl(®s->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
|
||||
*
|
||||
* Set the i2c speed.
|
||||
*/
|
||||
static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base,
|
||||
struct dw_scl_sda_cfg *scl_sda_cfg,
|
||||
unsigned int speed,
|
||||
unsigned int bus_mhz)
|
||||
static int _dw_i2c_set_bus_speed(struct dw_i2c *priv, struct i2c_regs *i2c_base,
|
||||
unsigned int speed, unsigned int bus_clk)
|
||||
{
|
||||
struct dw_i2c_speed_config config;
|
||||
unsigned int cntl;
|
||||
unsigned int hcnt, lcnt;
|
||||
unsigned int ena;
|
||||
int i2c_spd;
|
||||
int ret;
|
||||
|
||||
/* Allow max speed if there is no config, or the config allows it */
|
||||
if (speed >= I2C_MAX_SPEED &&
|
||||
(!scl_sda_cfg || scl_sda_cfg->has_max_speed))
|
||||
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;
|
||||
ret = calc_bus_speed(priv, speed, bus_clk, &config);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Get enable setting for restore later */
|
||||
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));
|
||||
|
||||
switch (i2c_spd) {
|
||||
case IC_SPEED_MODE_MAX:
|
||||
switch (config.speed_mode) {
|
||||
case IC_SPEED_MODE_HIGH:
|
||||
cntl |= IC_CON_SPD_SS;
|
||||
if (scl_sda_cfg) {
|
||||
hcnt = scl_sda_cfg->fs_hcnt;
|
||||
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);
|
||||
writel(config.scl_hcnt, &i2c_base->ic_hs_scl_hcnt);
|
||||
writel(config.scl_lcnt, &i2c_base->ic_hs_scl_lcnt);
|
||||
break;
|
||||
|
||||
case IC_SPEED_MODE_STANDARD:
|
||||
cntl |= IC_CON_SPD_SS;
|
||||
if (scl_sda_cfg) {
|
||||
hcnt = scl_sda_cfg->ss_hcnt;
|
||||
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);
|
||||
writel(config.scl_hcnt, &i2c_base->ic_ss_scl_hcnt);
|
||||
writel(config.scl_lcnt, &i2c_base->ic_ss_scl_lcnt);
|
||||
break;
|
||||
|
||||
case IC_SPEED_MODE_FAST_PLUS:
|
||||
case IC_SPEED_MODE_FAST:
|
||||
default:
|
||||
cntl |= IC_CON_SPD_FS;
|
||||
if (scl_sda_cfg) {
|
||||
hcnt = scl_sda_cfg->fs_hcnt;
|
||||
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);
|
||||
writel(config.scl_hcnt, &i2c_base->ic_fs_scl_hcnt);
|
||||
writel(config.scl_lcnt, &i2c_base->ic_fs_scl_lcnt);
|
||||
break;
|
||||
}
|
||||
|
||||
writel(cntl, &i2c_base->ic_con);
|
||||
|
||||
/* Configure SDA Hold Time if required */
|
||||
if (scl_sda_cfg)
|
||||
writel(scl_sda_cfg->sda_hold, &i2c_base->ic_sda_hold);
|
||||
if (config.sda_hold)
|
||||
writel(config.sda_hold, &i2c_base->ic_sda_hold);
|
||||
|
||||
/* Restore back i2c now speed set */
|
||||
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_STOP_DET, &i2c_base->ic_intr_mask);
|
||||
#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);
|
||||
#endif
|
||||
|
||||
@ -415,7 +583,7 @@ static unsigned int dw_i2c_set_bus_speed(struct i2c_adapter *adap,
|
||||
unsigned int 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)
|
||||
@ -511,14 +679,10 @@ static int designware_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
|
||||
rate = clk_get_rate(&i2c->clk);
|
||||
if (IS_ERR_VALUE(rate))
|
||||
return -EINVAL;
|
||||
|
||||
/* Convert to MHz */
|
||||
rate /= 1000000;
|
||||
#else
|
||||
rate = IC_CLK;
|
||||
#endif
|
||||
return __dw_i2c_set_bus_speed(i2c->regs, i2c->scl_sda_cfg, speed,
|
||||
rate);
|
||||
return _dw_i2c_set_bus_speed(i2c, i2c->regs, speed, rate);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static 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)
|
||||
int designware_i2c_ofdata_to_platdata(struct udevice *bus)
|
||||
{
|
||||
struct dw_i2c *priv = dev_get_priv(bus);
|
||||
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);
|
||||
if (ret)
|
||||
dev_warn(bus, "Can't get reset: %d\n", ret);
|
||||
@ -570,6 +731,13 @@ int designware_i2c_probe(struct udevice *bus)
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
#ifndef __DW_I2C_H_
|
||||
#define __DW_I2C_H_
|
||||
|
||||
#include <clk.h>
|
||||
#include <i2c.h>
|
||||
#include <reset.h>
|
||||
|
||||
struct i2c_regs {
|
||||
@ -43,20 +45,32 @@ struct i2c_regs {
|
||||
u32 ic_rxflr; /* 0x78 */
|
||||
u32 ic_sda_hold; /* 0x7c */
|
||||
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 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 166
|
||||
#endif
|
||||
#define NANO_TO_MICRO 1000
|
||||
#define IC_CLK 166666666
|
||||
#define NANO_TO_KILO 1000000
|
||||
|
||||
/* High and low times in different speed modes (in ns) */
|
||||
#define MIN_SS_SCL_HIGHTIME 4000
|
||||
#define MIN_SS_SCL_LOWTIME 4700
|
||||
#define MIN_FS_SCL_HIGHTIME 600
|
||||
#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_LOWTIME 160
|
||||
|
||||
@ -124,19 +138,10 @@ struct i2c_regs {
|
||||
#define IC_STATUS_TFNF 0x0002
|
||||
#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
|
||||
*
|
||||
* @has_max_speed: Support maximum speed (1Mbps)
|
||||
* @has_high_speed: Support high speed (3.4Mbps)
|
||||
* @ss_hcnt: Standard speed high time in ns
|
||||
* @fs_hcnt: Fast speed high time in ns
|
||||
* @ss_lcnt: Standard speed low time in ns
|
||||
@ -144,7 +149,7 @@ struct i2c_regs {
|
||||
* @sda_hold: SDA hold time
|
||||
*/
|
||||
struct dw_scl_sda_cfg {
|
||||
bool has_max_speed;
|
||||
bool has_high_speed;
|
||||
u32 ss_hcnt;
|
||||
u32 fs_hcnt;
|
||||
u32 ss_lcnt;
|
||||
@ -152,10 +157,45 @@ struct dw_scl_sda_cfg {
|
||||
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 i2c_regs *regs;
|
||||
struct dw_scl_sda_cfg *scl_sda_cfg;
|
||||
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)
|
||||
struct clk clk;
|
||||
#endif
|
||||
@ -165,5 +205,6 @@ extern const struct dm_i2c_ops designware_i2c_ops;
|
||||
|
||||
int designware_i2c_probe(struct udevice *bus);
|
||||
int designware_i2c_remove(struct udevice *dev);
|
||||
int designware_i2c_ofdata_to_platdata(struct udevice *bus);
|
||||
|
||||
#endif /* __DW_I2C_H_ */
|
||||
|
@ -62,8 +62,10 @@ static int designware_i2c_pci_ofdata_to_platdata(struct udevice *dev)
|
||||
if (IS_ENABLED(CONFIG_INTEL_BAYTRAIL))
|
||||
/* Use BayTrail specific timing values */
|
||||
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)
|
||||
|
@ -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->clock_frequency = fdtdec_get_int(blob, node,
|
||||
"clock-frequency", 100000);
|
||||
i2c_bus->clock_frequency =
|
||||
dev_read_u32_default(dev, "clock-frequency",
|
||||
I2C_SPEED_STANDARD_RATE);
|
||||
i2c_bus->node = node;
|
||||
i2c_bus->bus_num = dev->seq;
|
||||
|
||||
|
@ -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->slaveadd = dev_read_u32_default(bus, "u-boot,i2c-slave-addr",
|
||||
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))
|
||||
dev->i2c_clk = clk_get_rate(&clock);
|
||||
|
@ -213,7 +213,7 @@ static int cdns_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
|
||||
unsigned long speed_p = speed;
|
||||
int ret = 0;
|
||||
|
||||
if (speed > 400000) {
|
||||
if (speed > I2C_SPEED_FAST_RATE) {
|
||||
debug("%s, failed to set clock speed to %u\n", __func__,
|
||||
speed);
|
||||
return -EINVAL;
|
||||
|
@ -641,7 +641,8 @@ static int i2c_post_probe(struct udevice *dev)
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
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);
|
||||
#else
|
||||
@ -699,11 +700,10 @@ int i2c_uclass_init(struct uclass *class)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Get the last allocated alias. */
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL)
|
||||
priv->max_id = dev_read_alias_highest_id("i2c");
|
||||
#else
|
||||
priv->max_id = -1;
|
||||
#endif
|
||||
if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA))
|
||||
priv->max_id = dev_read_alias_highest_id("i2c");
|
||||
else
|
||||
priv->max_id = -1;
|
||||
|
||||
debug("%s: highest alias id is %d\n", __func__, priv->max_id);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
/* max supported frequency is 400 kHz */
|
||||
if (speed > 400000)
|
||||
if (speed > I2C_SPEED_FAST_RATE)
|
||||
return -EINVAL;
|
||||
|
||||
ret = uniphier_fi2c_check_bus_busy(priv);
|
||||
|
@ -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);
|
||||
|
||||
/* max supported frequency is 400 kHz */
|
||||
if (speed > 400000)
|
||||
if (speed > I2C_SPEED_FAST_RATE)
|
||||
return -EINVAL;
|
||||
|
||||
/* bus reset: make sure the bus is idle when change the frequency */
|
||||
|
@ -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);
|
||||
|
||||
/* 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);
|
||||
if (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);
|
||||
if (result) {
|
||||
bus_i2c_stop(bus);
|
||||
bus_i2c_init(bus, 100000);
|
||||
bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = bus_i2c_stop(bus);
|
||||
if (result)
|
||||
bus_i2c_init(bus, 100000);
|
||||
bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -489,7 +489,7 @@ static int imx_lpi2c_probe(struct udevice *bus)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = bus_i2c_init(bus, 100000);
|
||||
ret = bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
@ -98,12 +98,6 @@ enum bcm_kona_cmd_t {
|
||||
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 */
|
||||
struct bus_speed_cfg {
|
||||
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[] = {
|
||||
[BCM_SPD_100K] = {0x01, 0x01, 0x03, 0x06, 0x00, 0x02},
|
||||
[BCM_SPD_400K] = {0x05, 0x01, 0x03, 0x05, 0x01, 0x02},
|
||||
[BCM_SPD_1MHZ] = {0x01, 0x01, 0x03, 0x01, 0x01, 0x03},
|
||||
[IC_SPEED_MODE_STANDARD] = {0x01, 0x01, 0x03, 0x06, 0x00, 0x02},
|
||||
[IC_SPEED_MODE_FAST] = {0x05, 0x01, 0x03, 0x05, 0x01, 0x02},
|
||||
[IC_SPEED_MODE_FAST_PLUS] = {0x01, 0x01, 0x03, 0x01, 0x01, 0x03},
|
||||
};
|
||||
|
||||
struct bcm_kona_i2c_dev {
|
||||
@ -127,8 +121,8 @@ struct bcm_kona_i2c_dev {
|
||||
};
|
||||
|
||||
/* Keep these two defines in sync */
|
||||
#define DEF_SPD 100000
|
||||
#define DEF_SPD_ENUM BCM_SPD_100K
|
||||
#define DEF_SPD I2C_SPEED_STANDARD_RATE
|
||||
#define DEF_SPD_ENUM IC_SPEED_MODE_STANDARD
|
||||
|
||||
#define DEF_DEVICE(num) \
|
||||
{(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)
|
||||
{
|
||||
switch (speed) {
|
||||
case 100000:
|
||||
dev->std_cfg = &std_cfg_table[BCM_SPD_100K];
|
||||
case I2C_SPEED_STANDARD_RATE:
|
||||
dev->std_cfg = &std_cfg_table[IC_SPEED_MODE_STANDARD];
|
||||
break;
|
||||
case 400000:
|
||||
dev->std_cfg = &std_cfg_table[BCM_SPD_400K];
|
||||
case I2C_SPEED_FAST_RATE:
|
||||
dev->std_cfg = &std_cfg_table[IC_SPEED_MODE_FAST];
|
||||
break;
|
||||
case 1000000:
|
||||
dev->std_cfg = &std_cfg_table[BCM_SPD_1MHZ];
|
||||
case I2C_SPEED_FAST_PLUS_RATE:
|
||||
dev->std_cfg = &std_cfg_table[IC_SPEED_MODE_FAST_PLUS];
|
||||
break;
|
||||
default:
|
||||
printf("%d hz bus speed not supported\n", speed);
|
||||
|
@ -434,7 +434,7 @@ void i2c_init(int speed, int slaveaddr)
|
||||
base_glob = (struct mv_i2c *)CONFIG_MV_I2C_REG;
|
||||
#endif
|
||||
|
||||
if (speed > 100000)
|
||||
if (speed > I2C_SPEED_STANDARD_RATE)
|
||||
val = ICR_FM;
|
||||
else
|
||||
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);
|
||||
u32 val;
|
||||
|
||||
if (speed > 100000)
|
||||
if (speed > I2C_SPEED_STANDARD_RATE)
|
||||
val = ICR_FM;
|
||||
else
|
||||
val = ICR_SM;
|
||||
|
@ -805,8 +805,9 @@ static int mvtwsi_i2c_ofdata_to_platdata(struct udevice *bus)
|
||||
"cell-index", -1);
|
||||
dev->slaveadd = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
|
||||
"u-boot,i2c-slave-addr", 0x0);
|
||||
dev->speed = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus),
|
||||
"clock-frequency", 100000);
|
||||
dev->speed = dev_read_u32_default(bus, "clock-frequency",
|
||||
I2C_SPEED_STANDARD_RATE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -306,7 +306,7 @@ static int __omap24_i2c_setspeed(void __iomem *i2c_base, int ip_rev, uint speed,
|
||||
int hsscll = 0, hssclh = 0;
|
||||
u32 scll = 0, sclh = 0;
|
||||
|
||||
if (speed >= OMAP_I2C_HIGH_SPEED) {
|
||||
if (speed >= I2C_SPEED_HIGH_RATE) {
|
||||
/* High speed */
|
||||
psc = I2C_IP_CLK / I2C_INTERNAL_SAMPLING_CLK;
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
return 0;
|
||||
|
@ -81,10 +81,6 @@
|
||||
#define I2C_SCLH_HSSCLH 8
|
||||
#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_13 13000000
|
||||
#define SYSTEM_CLOCK_192 19200000
|
||||
|
@ -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_ICMAR);
|
||||
|
||||
ret = rcar_i2c_set_speed(dev, 100000);
|
||||
ret = rcar_i2c_set_speed(dev, I2C_SPEED_STANDARD_RATE);
|
||||
if (ret)
|
||||
clk_disable(&priv->clk);
|
||||
|
||||
|
@ -248,7 +248,7 @@ static int rcar_iic_probe(struct udevice *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 = {
|
||||
|
@ -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->clock_frequency = fdtdec_get_int(blob, node,
|
||||
"clock-frequency", 100000);
|
||||
i2c_bus->clock_frequency =
|
||||
dev_read_u32_default(dev, "clock-frequency",
|
||||
I2C_SPEED_STANDARD_RATE);
|
||||
i2c_bus->node = node;
|
||||
i2c_bus->bus_num = dev->seq;
|
||||
|
||||
|
@ -72,7 +72,8 @@ static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
|
||||
* 400KHz for reads.
|
||||
*/
|
||||
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__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -115,17 +115,6 @@ struct stm32_i2c_regs {
|
||||
|
||||
#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
|
||||
* @rate: I2C bus speed (Hz)
|
||||
@ -164,7 +153,7 @@ struct stm32_i2c_spec {
|
||||
* @analog_filter: Analog filter delay (On/Off)
|
||||
*/
|
||||
struct stm32_i2c_setup {
|
||||
enum stm32_i2c_speed speed;
|
||||
enum i2c_speed_mode speed;
|
||||
u32 speed_freq;
|
||||
u32 clock_src;
|
||||
u32 rise_time;
|
||||
@ -198,8 +187,8 @@ struct stm32_i2c_priv {
|
||||
};
|
||||
|
||||
static const struct stm32_i2c_spec i2c_specs[] = {
|
||||
[STM32_I2C_SPEED_STANDARD] = {
|
||||
.rate = STANDARD_RATE,
|
||||
[IC_SPEED_MODE_STANDARD] = {
|
||||
.rate = I2C_SPEED_STANDARD_RATE,
|
||||
.rate_min = 8000,
|
||||
.rate_max = 120000,
|
||||
.fall_max = 300,
|
||||
@ -210,8 +199,8 @@ static const struct stm32_i2c_spec i2c_specs[] = {
|
||||
.l_min = 4700,
|
||||
.h_min = 4000,
|
||||
},
|
||||
[STM32_I2C_SPEED_FAST] = {
|
||||
.rate = FAST_RATE,
|
||||
[IC_SPEED_MODE_FAST] = {
|
||||
.rate = I2C_SPEED_FAST_RATE,
|
||||
.rate_min = 320000,
|
||||
.rate_max = 480000,
|
||||
.fall_max = 300,
|
||||
@ -222,8 +211,8 @@ static const struct stm32_i2c_spec i2c_specs[] = {
|
||||
.l_min = 1300,
|
||||
.h_min = 600,
|
||||
},
|
||||
[STM32_I2C_SPEED_FAST_PLUS] = {
|
||||
.rate = FAST_PLUS_RATE,
|
||||
[IC_SPEED_MODE_FAST_PLUS] = {
|
||||
.rate = I2C_SPEED_FAST_PLUS_RATE,
|
||||
.rate_min = 800000,
|
||||
.rate_max = 1200000,
|
||||
.fall_max = 100,
|
||||
@ -648,9 +637,9 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv,
|
||||
struct list_head solutions;
|
||||
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__,
|
||||
setup->speed, STM32_I2C_SPEED_END - 1);
|
||||
setup->speed, ARRAY_SIZE(i2c_specs) - 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -719,7 +708,7 @@ static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv,
|
||||
if (ret) {
|
||||
debug("%s: failed to compute I2C timings.\n",
|
||||
__func__);
|
||||
if (i2c_priv->speed > STM32_I2C_SPEED_STANDARD) {
|
||||
if (i2c_priv->speed > IC_SPEED_MODE_STANDARD) {
|
||||
i2c_priv->speed--;
|
||||
setup->speed = i2c_priv->speed;
|
||||
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);
|
||||
|
||||
switch (speed) {
|
||||
case STANDARD_RATE:
|
||||
i2c_priv->speed = STM32_I2C_SPEED_STANDARD;
|
||||
case I2C_SPEED_STANDARD_RATE:
|
||||
i2c_priv->speed = IC_SPEED_MODE_STANDARD;
|
||||
break;
|
||||
case FAST_RATE:
|
||||
i2c_priv->speed = STM32_I2C_SPEED_FAST;
|
||||
case I2C_SPEED_FAST_RATE:
|
||||
i2c_priv->speed = IC_SPEED_MODE_FAST;
|
||||
break;
|
||||
case FAST_PLUS_RATE:
|
||||
i2c_priv->speed = STM32_I2C_SPEED_FAST_PLUS;
|
||||
case I2C_SPEED_FAST_PLUS_RATE:
|
||||
i2c_priv->speed = IC_SPEED_MODE_FAST_PLUS;
|
||||
break;
|
||||
default:
|
||||
debug("%s: Speed %d not supported\n", __func__, speed);
|
||||
|
@ -89,9 +89,6 @@ typedef struct global_data {
|
||||
#endif
|
||||
#if defined(CONFIG_SYS_I2C)
|
||||
int cur_i2c_bus; /* current used i2c bus */
|
||||
#endif
|
||||
#ifdef CONFIG_SYS_I2C_MXC
|
||||
void *srdata[10];
|
||||
#endif
|
||||
unsigned int timebase_h;
|
||||
unsigned int timebase_l;
|
||||
|
@ -30,6 +30,32 @@ enum dm_i2c_chip_flags {
|
||||
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 dm_i2c_chip - information about an i2c chip
|
||||
|
Loading…
Reference in New Issue
Block a user