Commit b9fa0a3a authored by Vadim Pasternak's avatar Vadim Pasternak Committed by Guenter Roeck

hwmon: (pmbus/core) Add support for vid mode detection per page bases

Add support for VID protocol detection per page bases, instead of
detecting it based on "PMBU_VOUT" readout from page 0 for all the pages
supported by particular device.
The reason that some devices allows to configure different VID modes
per page within the same device.
Patch modifies the field "vrm_version" within the structure
"pmbus_driver_info" to be per page array.
Signed-off-by: default avatarVadim Pasternak <vadimp@mellanox.com>
Link: https://lore.kernel.org/r/20200113150841.17670-2-vadimp@mellanox.comSigned-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
parent d9c8ae69
...@@ -16,7 +16,7 @@ static struct pmbus_driver_info max20751_info = { ...@@ -16,7 +16,7 @@ static struct pmbus_driver_info max20751_info = {
.pages = 1, .pages = 1,
.format[PSC_VOLTAGE_IN] = linear, .format[PSC_VOLTAGE_IN] = linear,
.format[PSC_VOLTAGE_OUT] = vid, .format[PSC_VOLTAGE_OUT] = vid,
.vrm_version = vr12, .vrm_version[0] = vr12,
.format[PSC_TEMPERATURE] = linear, .format[PSC_TEMPERATURE] = linear,
.format[PSC_CURRENT_OUT] = linear, .format[PSC_CURRENT_OUT] = linear,
.format[PSC_POWER] = linear, .format[PSC_POWER] = linear,
......
...@@ -115,7 +115,7 @@ static int pmbus_identify(struct i2c_client *client, ...@@ -115,7 +115,7 @@ static int pmbus_identify(struct i2c_client *client,
} }
if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) { if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) {
int vout_mode; int vout_mode, i;
vout_mode = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); vout_mode = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE);
if (vout_mode >= 0 && vout_mode != 0xff) { if (vout_mode >= 0 && vout_mode != 0xff) {
...@@ -124,7 +124,8 @@ static int pmbus_identify(struct i2c_client *client, ...@@ -124,7 +124,8 @@ static int pmbus_identify(struct i2c_client *client,
break; break;
case 1: case 1:
info->format[PSC_VOLTAGE_OUT] = vid; info->format[PSC_VOLTAGE_OUT] = vid;
info->vrm_version = vr11; for (i = 0; i < info->pages; i++)
info->vrm_version[i] = vr11;
break; break;
case 2: case 2:
info->format[PSC_VOLTAGE_OUT] = direct; info->format[PSC_VOLTAGE_OUT] = direct;
......
...@@ -393,7 +393,7 @@ enum vrm_version { vr11 = 0, vr12, vr13 }; ...@@ -393,7 +393,7 @@ enum vrm_version { vr11 = 0, vr12, vr13 };
struct pmbus_driver_info { struct pmbus_driver_info {
int pages; /* Total number of pages */ int pages; /* Total number of pages */
enum pmbus_data_format format[PSC_NUM_CLASSES]; enum pmbus_data_format format[PSC_NUM_CLASSES];
enum vrm_version vrm_version; enum vrm_version vrm_version[PMBUS_PAGES]; /* vrm version per page */
/* /*
* Support one set of coefficients for each sensor type * Support one set of coefficients for each sensor type
* Used for chips providing data in direct mode. * Used for chips providing data in direct mode.
......
...@@ -696,7 +696,7 @@ static long pmbus_reg2data_vid(struct pmbus_data *data, ...@@ -696,7 +696,7 @@ static long pmbus_reg2data_vid(struct pmbus_data *data,
long val = sensor->data; long val = sensor->data;
long rv = 0; long rv = 0;
switch (data->info->vrm_version) { switch (data->info->vrm_version[sensor->page]) {
case vr11: case vr11:
if (val >= 0x02 && val <= 0xb2) if (val >= 0x02 && val <= 0xb2)
rv = DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100); rv = DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100);
......
...@@ -19,26 +19,30 @@ ...@@ -19,26 +19,30 @@
static int pxe1610_identify(struct i2c_client *client, static int pxe1610_identify(struct i2c_client *client,
struct pmbus_driver_info *info) struct pmbus_driver_info *info)
{ {
if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) { int i;
u8 vout_mode;
int ret; for (i = 0; i < PXE1610_NUM_PAGES; i++) {
if (pmbus_check_byte_register(client, i, PMBUS_VOUT_MODE)) {
/* Read the register with VOUT scaling value.*/ u8 vout_mode;
ret = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); int ret;
if (ret < 0)
return ret; /* Read the register with VOUT scaling value.*/
ret = pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE);
vout_mode = ret & GENMASK(4, 0); if (ret < 0)
return ret;
switch (vout_mode) {
case 1: vout_mode = ret & GENMASK(4, 0);
info->vrm_version = vr12;
break; switch (vout_mode) {
case 2: case 1:
info->vrm_version = vr13; info->vrm_version[i] = vr12;
break; break;
default: case 2:
return -ENODEV; info->vrm_version[i] = vr13;
break;
default:
return -ENODEV;
}
} }
} }
......
...@@ -24,27 +24,29 @@ static int tps53679_identify(struct i2c_client *client, ...@@ -24,27 +24,29 @@ static int tps53679_identify(struct i2c_client *client,
struct pmbus_driver_info *info) struct pmbus_driver_info *info)
{ {
u8 vout_params; u8 vout_params;
int ret; int i, ret;
/* Read the register with VOUT scaling value.*/ for (i = 0; i < TPS53679_PAGE_NUM; i++) {
ret = pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); /* Read the register with VOUT scaling value.*/
if (ret < 0) ret = pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE);
return ret; if (ret < 0)
return ret;
vout_params = ret & GENMASK(4, 0);
vout_params = ret & GENMASK(4, 0);
switch (vout_params) {
case TPS53679_PROT_VR13_10MV: switch (vout_params) {
case TPS53679_PROT_VR12_5_10MV: case TPS53679_PROT_VR13_10MV:
info->vrm_version = vr13; case TPS53679_PROT_VR12_5_10MV:
break; info->vrm_version[i] = vr13;
case TPS53679_PROT_VR13_5MV: break;
case TPS53679_PROT_VR12_5MV: case TPS53679_PROT_VR13_5MV:
case TPS53679_PROT_IMVP8_5MV: case TPS53679_PROT_VR12_5MV:
info->vrm_version = vr12; case TPS53679_PROT_IMVP8_5MV:
break; info->vrm_version[i] = vr12;
default: break;
return -EINVAL; default:
return -EINVAL;
}
} }
return 0; return 0;
......
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