Commit 464df6fa authored by Andrew Jeffery's avatar Andrew Jeffery Committed by Guenter Roeck

hwmon: (pmbus) Add virtual page config bit

Some circumstances call for virtual pages, to expose multiple values
packed into an extended PMBus register in a manner non-compliant with
the PMBus standard. An example of this is the Maxim MAX31785 controller,
which extends the READ_FAN_SPEED_1 PMBus register from two to four bytes
to support tach readings for both rotors of a dual rotor fan. This extended
register contains two word-sized values, one reporting the rate of the
fastest rotor, the other the rate of the slowest. The concept of virtual
pages aids this situation by mapping the page number onto the value to be
selected from the vectored result.

We should not try to set virtual pages on the device as such a page
explicitly doesn't exist; add a flag so we can avoid doing so.
Signed-off-by: default avatarAndrew Jeffery <andrew@aj.id.au>
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent 56ad86b4
...@@ -372,6 +372,8 @@ enum pmbus_sensor_classes { ...@@ -372,6 +372,8 @@ enum pmbus_sensor_classes {
#define PMBUS_HAVE_PWM12 BIT(20) #define PMBUS_HAVE_PWM12 BIT(20)
#define PMBUS_HAVE_PWM34 BIT(21) #define PMBUS_HAVE_PWM34 BIT(21)
#define PMBUS_PAGE_VIRTUAL BIT(31)
enum pmbus_data_format { linear = 0, direct, vid }; enum pmbus_data_format { linear = 0, direct, vid };
enum vrm_version { vr11 = 0, vr12, vr13 }; enum vrm_version { vr11 = 0, vr12, vr13 };
......
...@@ -162,18 +162,27 @@ EXPORT_SYMBOL_GPL(pmbus_clear_cache); ...@@ -162,18 +162,27 @@ EXPORT_SYMBOL_GPL(pmbus_clear_cache);
int pmbus_set_page(struct i2c_client *client, int page) int pmbus_set_page(struct i2c_client *client, int page)
{ {
struct pmbus_data *data = i2c_get_clientdata(client); struct pmbus_data *data = i2c_get_clientdata(client);
int rv = 0; int rv;
int newpage;
if (page < 0 || page == data->currpage)
return 0;
if (page >= 0 && page != data->currpage) { if (!(data->info->func[page] & PMBUS_PAGE_VIRTUAL)) {
rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page);
newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE); if (rv < 0)
if (newpage != page)
rv = -EIO;
else
data->currpage = page;
}
return rv; return rv;
rv = i2c_smbus_read_byte_data(client, PMBUS_PAGE);
if (rv < 0)
return rv;
if (rv != page)
return -EIO;
}
data->currpage = page;
return 0;
} }
EXPORT_SYMBOL_GPL(pmbus_set_page); EXPORT_SYMBOL_GPL(pmbus_set_page);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment