diff options
author | Guenter Roeck <linux@roeck-us.net> | 2023-06-14 19:36:04 +0300 |
---|---|---|
committer | Guenter Roeck <linux@roeck-us.net> | 2023-06-22 20:39:41 +0300 |
commit | 98ac8af4e7b2f260236cf468762450630e73eb67 (patch) | |
tree | 61a9dfe9165aceaffd53f51d6b426669d7fa5718 /drivers/hwmon | |
parent | 37f665ffa886ce49d1baaca1c3501ce93713b77e (diff) | |
download | linux-98ac8af4e7b2f260236cf468762450630e73eb67.tar.xz |
hwmon: (pmbus/adm1275) Prepare for protected write to PMON_CONFIG
According to ADI, changing PMON_CONFIG while ADC is running can have
unexpected results. ADI recommends halting the ADC with PMON_CONTROL
before setting PMON_CONFIG and then resume after.
To prepare for this change, rename adm1275_read_pmon_config()
and adm1275_write_pmon_config() to adm1275_read_samples() and
adm1275_write_samples() to more accurately reflect the functionality
of the code. Introduce new function adm1275_write_pmon_config()
and use it for all code writing into the PMON_CONFIG register.
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Link: https://lore.kernel.org/r/20230614163605.3688964-2-linux@roeck-us.net
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/pmbus/adm1275.c | 56 |
1 files changed, 31 insertions, 25 deletions
diff --git a/drivers/hwmon/pmbus/adm1275.c b/drivers/hwmon/pmbus/adm1275.c index 49d59b745afe..84a1b3aa99ba 100644 --- a/drivers/hwmon/pmbus/adm1275.c +++ b/drivers/hwmon/pmbus/adm1275.c @@ -173,8 +173,8 @@ static const struct coefficients adm1293_coefficients[] = { [18] = { 7658, 0, -3 }, /* power, 21V, irange200 */ }; -static int adm1275_read_pmon_config(const struct adm1275_data *data, - struct i2c_client *client, bool is_power) +static int adm1275_read_samples(const struct adm1275_data *data, + struct i2c_client *client, bool is_power) { int shift, ret; u16 mask; @@ -200,8 +200,23 @@ static int adm1275_read_pmon_config(const struct adm1275_data *data, } static int adm1275_write_pmon_config(const struct adm1275_data *data, - struct i2c_client *client, - bool is_power, u16 word) + struct i2c_client *client, u16 word) +{ + int ret; + + if (data->have_power_sampling) + ret = i2c_smbus_write_word_data(client, ADM1275_PMON_CONFIG, + word); + else + ret = i2c_smbus_write_byte_data(client, ADM1275_PMON_CONFIG, + word); + + return ret; +} + +static int adm1275_write_samples(const struct adm1275_data *data, + struct i2c_client *client, + bool is_power, u16 word) { int shift, ret; u16 mask; @@ -219,14 +234,8 @@ static int adm1275_write_pmon_config(const struct adm1275_data *data, return ret; word = (ret & ~mask) | ((word << shift) & mask); - if (data->have_power_sampling) - ret = i2c_smbus_write_word_data(client, ADM1275_PMON_CONFIG, - word); - else - ret = i2c_smbus_write_byte_data(client, ADM1275_PMON_CONFIG, - word); - return ret; + return adm1275_write_pmon_config(data, client, word); } static int adm1275_read_word_data(struct i2c_client *client, int page, @@ -321,14 +330,14 @@ static int adm1275_read_word_data(struct i2c_client *client, int page, case PMBUS_VIRT_POWER_SAMPLES: if (!data->have_power_sampling) return -ENXIO; - ret = adm1275_read_pmon_config(data, client, true); + ret = adm1275_read_samples(data, client, true); if (ret < 0) break; ret = BIT(ret); break; case PMBUS_VIRT_IN_SAMPLES: case PMBUS_VIRT_CURR_SAMPLES: - ret = adm1275_read_pmon_config(data, client, false); + ret = adm1275_read_samples(data, client, false); if (ret < 0) break; ret = BIT(ret); @@ -381,14 +390,12 @@ static int adm1275_write_word_data(struct i2c_client *client, int page, int reg, if (!data->have_power_sampling) return -ENXIO; word = clamp_val(word, 1, ADM1275_SAMPLES_AVG_MAX); - ret = adm1275_write_pmon_config(data, client, true, - ilog2(word)); + ret = adm1275_write_samples(data, client, true, ilog2(word)); break; case PMBUS_VIRT_IN_SAMPLES: case PMBUS_VIRT_CURR_SAMPLES: word = clamp_val(word, 1, ADM1275_SAMPLES_AVG_MAX); - ret = adm1275_write_pmon_config(data, client, false, - ilog2(word)); + ret = adm1275_write_samples(data, client, false, ilog2(word)); break; default: ret = -ENODATA; @@ -466,13 +473,14 @@ static const struct i2c_device_id adm1275_id[] = { MODULE_DEVICE_TABLE(i2c, adm1275_id); /* Enable VOUT & TEMP1 if not enabled (disabled by default) */ -static int adm1275_enable_vout_temp(struct i2c_client *client, int config) +static int adm1275_enable_vout_temp(struct adm1275_data *data, + struct i2c_client *client, int config) { int ret; if ((config & ADM1278_PMON_DEFCONFIG) != ADM1278_PMON_DEFCONFIG) { config |= ADM1278_PMON_DEFCONFIG; - ret = i2c_smbus_write_word_data(client, ADM1275_PMON_CONFIG, config); + ret = adm1275_write_pmon_config(data, client, config); if (ret < 0) { dev_err(&client->dev, "Failed to enable VOUT/TEMP1 monitoring\n"); return ret; @@ -634,7 +642,7 @@ static int adm1275_probe(struct i2c_client *client) PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; - ret = adm1275_enable_vout_temp(client, config); + ret = adm1275_enable_vout_temp(data, client, config); if (ret) return ret; @@ -694,7 +702,7 @@ static int adm1275_probe(struct i2c_client *client) PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; - ret = adm1275_enable_vout_temp(client, config); + ret = adm1275_enable_vout_temp(data, client, config); if (ret) return ret; @@ -766,8 +774,7 @@ static int adm1275_probe(struct i2c_client *client) "Invalid number of power samples"); return -EINVAL; } - ret = adm1275_write_pmon_config(data, client, true, - ilog2(avg)); + ret = adm1275_write_samples(data, client, true, ilog2(avg)); if (ret < 0) { dev_err(&client->dev, "Setting power sample averaging failed with error %d", @@ -784,8 +791,7 @@ static int adm1275_probe(struct i2c_client *client) "Invalid number of voltage/current samples"); return -EINVAL; } - ret = adm1275_write_pmon_config(data, client, false, - ilog2(avg)); + ret = adm1275_write_samples(data, client, false, ilog2(avg)); if (ret < 0) { dev_err(&client->dev, "Setting voltage and current sample averaging failed with error %d", |