hwmon: (pmbus) add support for 2nd Gen Renesas digital multiphase

Extend the isl68137 driver to provide support for 2nd generation Renesas
digital multiphase voltage regulators.

Signed-off-by: Grant Peltier <grantpeltier93@gmail.com>
Link: https://lore.kernel.org/r/62c000adf0108aeb65d3f275f28eb26b690384aa.1584720563.git.grantpeltier93@gmail.com
[groeck: Adjusted for new PMBus API function parameters]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
Grant Peltier 2020-03-20 11:16:21 -05:00 committed by Guenter Roeck
parent b1fbe673b8
commit f621d61fd5
2 changed files with 99 additions and 18 deletions

View File

@ -92,10 +92,10 @@ config SENSORS_IRPS5401
be called irps5401.
config SENSORS_ISL68137
tristate "Intersil ISL68137"
tristate "Renesas Digital Multiphase Voltage Regulators"
help
If you say yes here you get hardware monitoring support for Intersil
ISL68137.
If you say yes here you get hardware monitoring support for Renesas
digital multiphase voltage regulators.
This driver can also be built as a module. If so, the module will
be called isl68137.

View File

@ -1,8 +1,9 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Hardware monitoring driver for Intersil ISL68137
* Hardware monitoring driver for Renesas Digital Multiphase Voltage Regulators
*
* Copyright (c) 2017 Google Inc
* Copyright (c) 2020 Renesas Electronics America
*
*/
@ -14,9 +15,19 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include "pmbus.h"
#define ISL68137_VOUT_AVS 0x30
#define RAA_DMPVR2_READ_VMON 0xc8
enum versions {
isl68137,
raa_dmpvr2_1rail,
raa_dmpvr2_2rail,
raa_dmpvr2_3rail,
raa_dmpvr2_hv,
};
static ssize_t isl68137_avs_enable_show_page(struct i2c_client *client,
int page,
@ -99,13 +110,31 @@ static const struct attribute_group enable_group = {
.attrs = enable_attrs,
};
static const struct attribute_group *attribute_groups[] = {
static const struct attribute_group *isl68137_attribute_groups[] = {
&enable_group,
NULL,
};
static struct pmbus_driver_info isl68137_info = {
.pages = 2,
static int raa_dmpvr2_read_word_data(struct i2c_client *client, int page,
int phase, int reg)
{
int ret;
switch (reg) {
case PMBUS_VIRT_READ_VMON:
ret = pmbus_read_word_data(client, page, phase,
RAA_DMPVR2_READ_VMON);
break;
default:
ret = -ENODATA;
break;
}
return ret;
}
static struct pmbus_driver_info raa_dmpvr_info = {
.pages = 3,
.format[PSC_VOLTAGE_IN] = direct,
.format[PSC_VOLTAGE_OUT] = direct,
.format[PSC_CURRENT_IN] = direct,
@ -114,7 +143,7 @@ static struct pmbus_driver_info isl68137_info = {
.format[PSC_TEMPERATURE] = direct,
.m[PSC_VOLTAGE_IN] = 1,
.b[PSC_VOLTAGE_IN] = 0,
.R[PSC_VOLTAGE_IN] = 3,
.R[PSC_VOLTAGE_IN] = 2,
.m[PSC_VOLTAGE_OUT] = 1,
.b[PSC_VOLTAGE_OUT] = 0,
.R[PSC_VOLTAGE_OUT] = 3,
@ -134,24 +163,76 @@ static struct pmbus_driver_info isl68137_info = {
| PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2
| PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP
| PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
| PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
| PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
.groups = attribute_groups,
| PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT
| PMBUS_HAVE_VMON,
.func[1] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT
| PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP
| PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
.func[2] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT
| PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP
| PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT,
};
static int isl68137_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
return pmbus_do_probe(client, id, &isl68137_info);
struct pmbus_driver_info *info;
info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
memcpy(info, &raa_dmpvr_info, sizeof(*info));
switch (id->driver_data) {
case isl68137:
info->pages = 2;
info->R[PSC_VOLTAGE_IN] = 3;
info->func[0] &= ~PMBUS_HAVE_VMON;
info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT
| PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT
| PMBUS_HAVE_POUT;
info->groups = isl68137_attribute_groups;
break;
case raa_dmpvr2_1rail:
info->pages = 1;
info->read_word_data = raa_dmpvr2_read_word_data;
break;
case raa_dmpvr2_2rail:
info->pages = 2;
info->read_word_data = raa_dmpvr2_read_word_data;
break;
case raa_dmpvr2_3rail:
info->read_word_data = raa_dmpvr2_read_word_data;
break;
case raa_dmpvr2_hv:
info->pages = 1;
info->R[PSC_VOLTAGE_IN] = 1;
info->m[PSC_VOLTAGE_OUT] = 2;
info->R[PSC_VOLTAGE_OUT] = 2;
info->m[PSC_CURRENT_IN] = 2;
info->m[PSC_POWER] = 2;
info->R[PSC_POWER] = -1;
info->read_word_data = raa_dmpvr2_read_word_data;
break;
default:
return -ENODEV;
}
return pmbus_do_probe(client, id, info);
}
static const struct i2c_device_id isl68137_id[] = {
{"isl68137", 0},
static const struct i2c_device_id raa_dmpvr_id[] = {
{"isl68137", isl68137},
{"raa_dmpvr2_1rail", raa_dmpvr2_1rail},
{"raa_dmpvr2_2rail", raa_dmpvr2_2rail},
{"raa_dmpvr2_3rail", raa_dmpvr2_3rail},
{"raa_dmpvr2_hv", raa_dmpvr2_hv},
{}
};
MODULE_DEVICE_TABLE(i2c, isl68137_id);
MODULE_DEVICE_TABLE(i2c, raa_dmpvr_id);
/* This is the driver that will be inserted */
static struct i2c_driver isl68137_driver = {
@ -160,11 +241,11 @@ static struct i2c_driver isl68137_driver = {
},
.probe = isl68137_probe,
.remove = pmbus_do_remove,
.id_table = isl68137_id,
.id_table = raa_dmpvr_id,
};
module_i2c_driver(isl68137_driver);
MODULE_AUTHOR("Maxim Sloyko <maxims@google.com>");
MODULE_DESCRIPTION("PMBus driver for Intersil ISL68137");
MODULE_DESCRIPTION("PMBus driver for Renesas digital multiphase voltage regulators");
MODULE_LICENSE("GPL");