aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorVadim Pasternak <vadimp@nvidia.com>2021-08-23 17:45:04 +0300
committerWolfram Sang <wsa@kernel.org>2021-10-11 12:32:00 +0200
commit712d6617d0a29dc4d4da361247720cdf156ae7bb (patch)
treec75f68ff50852d279c66b09c4f1afbbf7d07b3ad /drivers/i2c
parenti2c: pasemi: Set enable bit for Apple variant (diff)
downloadlinux-dev-712d6617d0a29dc4d4da361247720cdf156ae7bb.tar.xz
linux-dev-712d6617d0a29dc4d4da361247720cdf156ae7bb.zip
i2c: mlxcpld: Allow flexible polling time setting for I2C transactions
Allow polling time setting according to I2C frequency supported across the system. For base frequency 400 KHz and 1 MHz set polling time is set four times less than for system with base frequency 100KHz. Signed-off-by: Vadim Pasternak <vadimp@nvidia.com> Signed-off-by: Wolfram Sang <wsa@kernel.org>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-mlxcpld.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c
index 615f0a98640e..56aa424fd71d 100644
--- a/drivers/i2c/busses/i2c-mlxcpld.c
+++ b/drivers/i2c/busses/i2c-mlxcpld.c
@@ -73,6 +73,7 @@ struct mlxcpld_i2c_priv {
struct mlxcpld_i2c_curr_xfer xfer;
struct device *dev;
bool smbus_block;
+ int polling_time;
};
static void mlxcpld_i2c_lpc_write_buf(u8 *data, u8 len, u32 addr)
@@ -267,8 +268,8 @@ static int mlxcpld_i2c_wait_for_free(struct mlxcpld_i2c_priv *priv)
do {
if (!mlxcpld_i2c_check_busy(priv))
break;
- usleep_range(MLXCPLD_I2C_POLL_TIME / 2, MLXCPLD_I2C_POLL_TIME);
- timeout += MLXCPLD_I2C_POLL_TIME;
+ usleep_range(priv->polling_time / 2, priv->polling_time);
+ timeout += priv->polling_time;
} while (timeout <= MLXCPLD_I2C_XFER_TO);
if (timeout > MLXCPLD_I2C_XFER_TO)
@@ -288,10 +289,10 @@ static int mlxcpld_i2c_wait_for_tc(struct mlxcpld_i2c_priv *priv)
u8 datalen, val;
do {
- usleep_range(MLXCPLD_I2C_POLL_TIME / 2, MLXCPLD_I2C_POLL_TIME);
+ usleep_range(priv->polling_time / 2, priv->polling_time);
if (!mlxcpld_i2c_check_status(priv, &status))
break;
- timeout += MLXCPLD_I2C_POLL_TIME;
+ timeout += priv->polling_time;
} while (status == 0 && timeout < MLXCPLD_I2C_XFER_TO);
switch (status) {
@@ -498,9 +499,11 @@ mlxcpld_i2c_set_frequency(struct mlxcpld_i2c_priv *priv,
switch ((regval & data->mask) >> data->bit) {
case MLXCPLD_I2C_FREQ_1000KHZ:
freq = MLXCPLD_I2C_FREQ_1000KHZ_SET;
+ priv->polling_time /= 4;
break;
case MLXCPLD_I2C_FREQ_400KHZ:
freq = MLXCPLD_I2C_FREQ_400KHZ_SET;
+ priv->polling_time /= 4;
break;
default:
return 0;
@@ -527,6 +530,7 @@ static int mlxcpld_i2c_probe(struct platform_device *pdev)
priv->dev = &pdev->dev;
priv->base_addr = MLXPLAT_CPLD_LPC_I2C_BASE_ADDR;
+ priv->polling_time = MLXCPLD_I2C_POLL_TIME;
/* Set I2C bus frequency if platform data provides this info. */
pdata = dev_get_platdata(&pdev->dev);