1038a9c3dSMaxim Sloyko // SPDX-License-Identifier: GPL-2.0+ 2038a9c3dSMaxim Sloyko /* 3f621d61fSGrant Peltier * Hardware monitoring driver for Renesas Digital Multiphase Voltage Regulators 4038a9c3dSMaxim Sloyko * 5038a9c3dSMaxim Sloyko * Copyright (c) 2017 Google Inc 6f621d61fSGrant Peltier * Copyright (c) 2020 Renesas Electronics America 7038a9c3dSMaxim Sloyko * 8038a9c3dSMaxim Sloyko */ 9038a9c3dSMaxim Sloyko 10038a9c3dSMaxim Sloyko #include <linux/err.h> 11038a9c3dSMaxim Sloyko #include <linux/hwmon-sysfs.h> 12038a9c3dSMaxim Sloyko #include <linux/i2c.h> 13038a9c3dSMaxim Sloyko #include <linux/init.h> 14038a9c3dSMaxim Sloyko #include <linux/kernel.h> 15038a9c3dSMaxim Sloyko #include <linux/module.h> 16038a9c3dSMaxim Sloyko #include <linux/string.h> 17038a9c3dSMaxim Sloyko #include <linux/sysfs.h> 18f621d61fSGrant Peltier 19038a9c3dSMaxim Sloyko #include "pmbus.h" 20038a9c3dSMaxim Sloyko 21038a9c3dSMaxim Sloyko #define ISL68137_VOUT_AVS 0x30 22f621d61fSGrant Peltier #define RAA_DMPVR2_READ_VMON 0xc8 23f621d61fSGrant Peltier 2437d59d10SGuenter Roeck enum chips { 25f621d61fSGrant Peltier isl68137, 2637d59d10SGuenter Roeck isl68220, 2737d59d10SGuenter Roeck isl68221, 2837d59d10SGuenter Roeck isl68222, 2937d59d10SGuenter Roeck isl68223, 3037d59d10SGuenter Roeck isl68224, 3137d59d10SGuenter Roeck isl68225, 3237d59d10SGuenter Roeck isl68226, 3337d59d10SGuenter Roeck isl68227, 3437d59d10SGuenter Roeck isl68229, 3537d59d10SGuenter Roeck isl68233, 3637d59d10SGuenter Roeck isl68239, 3737d59d10SGuenter Roeck isl69222, 3837d59d10SGuenter Roeck isl69223, 3937d59d10SGuenter Roeck isl69224, 4037d59d10SGuenter Roeck isl69225, 4137d59d10SGuenter Roeck isl69227, 4237d59d10SGuenter Roeck isl69228, 4337d59d10SGuenter Roeck isl69234, 4437d59d10SGuenter Roeck isl69236, 4537d59d10SGuenter Roeck isl69239, 4637d59d10SGuenter Roeck isl69242, 4737d59d10SGuenter Roeck isl69243, 4837d59d10SGuenter Roeck isl69247, 4937d59d10SGuenter Roeck isl69248, 5037d59d10SGuenter Roeck isl69254, 5137d59d10SGuenter Roeck isl69255, 5237d59d10SGuenter Roeck isl69256, 5337d59d10SGuenter Roeck isl69259, 5437d59d10SGuenter Roeck isl69260, 5537d59d10SGuenter Roeck isl69268, 5637d59d10SGuenter Roeck isl69269, 5737d59d10SGuenter Roeck isl69298, 5837d59d10SGuenter Roeck raa228000, 5937d59d10SGuenter Roeck raa228004, 6037d59d10SGuenter Roeck raa228006, 6137d59d10SGuenter Roeck raa228228, 6237d59d10SGuenter Roeck raa229001, 6337d59d10SGuenter Roeck raa229004, 6437d59d10SGuenter Roeck }; 6537d59d10SGuenter Roeck 6637d59d10SGuenter Roeck enum variants { 6737d59d10SGuenter Roeck raa_dmpvr1_2rail, 68f621d61fSGrant Peltier raa_dmpvr2_1rail, 69f621d61fSGrant Peltier raa_dmpvr2_2rail, 70*51fb91edSGrant Peltier raa_dmpvr2_2rail_nontc, 71f621d61fSGrant Peltier raa_dmpvr2_3rail, 72f621d61fSGrant Peltier raa_dmpvr2_hv, 73f621d61fSGrant Peltier }; 74038a9c3dSMaxim Sloyko 75038a9c3dSMaxim Sloyko static ssize_t isl68137_avs_enable_show_page(struct i2c_client *client, 76038a9c3dSMaxim Sloyko int page, 77038a9c3dSMaxim Sloyko char *buf) 78038a9c3dSMaxim Sloyko { 79038a9c3dSMaxim Sloyko int val = pmbus_read_byte_data(client, page, PMBUS_OPERATION); 80038a9c3dSMaxim Sloyko 81038a9c3dSMaxim Sloyko return sprintf(buf, "%d\n", 82038a9c3dSMaxim Sloyko (val & ISL68137_VOUT_AVS) == ISL68137_VOUT_AVS ? 1 : 0); 83038a9c3dSMaxim Sloyko } 84038a9c3dSMaxim Sloyko 85038a9c3dSMaxim Sloyko static ssize_t isl68137_avs_enable_store_page(struct i2c_client *client, 86038a9c3dSMaxim Sloyko int page, 87038a9c3dSMaxim Sloyko const char *buf, size_t count) 88038a9c3dSMaxim Sloyko { 89038a9c3dSMaxim Sloyko int rc, op_val; 90038a9c3dSMaxim Sloyko bool result; 91038a9c3dSMaxim Sloyko 92038a9c3dSMaxim Sloyko rc = kstrtobool(buf, &result); 93038a9c3dSMaxim Sloyko if (rc) 94038a9c3dSMaxim Sloyko return rc; 95038a9c3dSMaxim Sloyko 96038a9c3dSMaxim Sloyko op_val = result ? ISL68137_VOUT_AVS : 0; 97038a9c3dSMaxim Sloyko 98038a9c3dSMaxim Sloyko /* 99038a9c3dSMaxim Sloyko * Writes to VOUT setpoint over AVSBus will persist after the VRM is 100038a9c3dSMaxim Sloyko * switched to PMBus control. Switching back to AVSBus control 101038a9c3dSMaxim Sloyko * restores this persisted setpoint rather than re-initializing to 102038a9c3dSMaxim Sloyko * PMBus VOUT_COMMAND. Writing VOUT_COMMAND first over PMBus before 103038a9c3dSMaxim Sloyko * enabling AVS control is the workaround. 104038a9c3dSMaxim Sloyko */ 105038a9c3dSMaxim Sloyko if (op_val == ISL68137_VOUT_AVS) { 10643f33b6eSGuenter Roeck rc = pmbus_read_word_data(client, page, 0xff, 10743f33b6eSGuenter Roeck PMBUS_VOUT_COMMAND); 108038a9c3dSMaxim Sloyko if (rc < 0) 109038a9c3dSMaxim Sloyko return rc; 110038a9c3dSMaxim Sloyko 111038a9c3dSMaxim Sloyko rc = pmbus_write_word_data(client, page, PMBUS_VOUT_COMMAND, 112038a9c3dSMaxim Sloyko rc); 113038a9c3dSMaxim Sloyko if (rc < 0) 114038a9c3dSMaxim Sloyko return rc; 115038a9c3dSMaxim Sloyko } 116038a9c3dSMaxim Sloyko 117038a9c3dSMaxim Sloyko rc = pmbus_update_byte_data(client, page, PMBUS_OPERATION, 118038a9c3dSMaxim Sloyko ISL68137_VOUT_AVS, op_val); 119038a9c3dSMaxim Sloyko 120038a9c3dSMaxim Sloyko return (rc < 0) ? rc : count; 121038a9c3dSMaxim Sloyko } 122038a9c3dSMaxim Sloyko 123038a9c3dSMaxim Sloyko static ssize_t isl68137_avs_enable_show(struct device *dev, 124038a9c3dSMaxim Sloyko struct device_attribute *devattr, 125038a9c3dSMaxim Sloyko char *buf) 126038a9c3dSMaxim Sloyko { 127038a9c3dSMaxim Sloyko struct i2c_client *client = to_i2c_client(dev->parent); 128038a9c3dSMaxim Sloyko struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 129038a9c3dSMaxim Sloyko 130038a9c3dSMaxim Sloyko return isl68137_avs_enable_show_page(client, attr->index, buf); 131038a9c3dSMaxim Sloyko } 132038a9c3dSMaxim Sloyko 133038a9c3dSMaxim Sloyko static ssize_t isl68137_avs_enable_store(struct device *dev, 134038a9c3dSMaxim Sloyko struct device_attribute *devattr, 135038a9c3dSMaxim Sloyko const char *buf, size_t count) 136038a9c3dSMaxim Sloyko { 137038a9c3dSMaxim Sloyko struct i2c_client *client = to_i2c_client(dev->parent); 138038a9c3dSMaxim Sloyko struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 139038a9c3dSMaxim Sloyko 140038a9c3dSMaxim Sloyko return isl68137_avs_enable_store_page(client, attr->index, buf, count); 141038a9c3dSMaxim Sloyko } 142038a9c3dSMaxim Sloyko 143038a9c3dSMaxim Sloyko static SENSOR_DEVICE_ATTR_RW(avs0_enable, isl68137_avs_enable, 0); 144038a9c3dSMaxim Sloyko static SENSOR_DEVICE_ATTR_RW(avs1_enable, isl68137_avs_enable, 1); 145038a9c3dSMaxim Sloyko 146038a9c3dSMaxim Sloyko static struct attribute *enable_attrs[] = { 147038a9c3dSMaxim Sloyko &sensor_dev_attr_avs0_enable.dev_attr.attr, 148038a9c3dSMaxim Sloyko &sensor_dev_attr_avs1_enable.dev_attr.attr, 149038a9c3dSMaxim Sloyko NULL, 150038a9c3dSMaxim Sloyko }; 151038a9c3dSMaxim Sloyko 152038a9c3dSMaxim Sloyko static const struct attribute_group enable_group = { 153038a9c3dSMaxim Sloyko .attrs = enable_attrs, 154038a9c3dSMaxim Sloyko }; 155038a9c3dSMaxim Sloyko 156f621d61fSGrant Peltier static const struct attribute_group *isl68137_attribute_groups[] = { 157038a9c3dSMaxim Sloyko &enable_group, 158038a9c3dSMaxim Sloyko NULL, 159038a9c3dSMaxim Sloyko }; 160038a9c3dSMaxim Sloyko 161f621d61fSGrant Peltier static int raa_dmpvr2_read_word_data(struct i2c_client *client, int page, 162f621d61fSGrant Peltier int phase, int reg) 163f621d61fSGrant Peltier { 164f621d61fSGrant Peltier int ret; 165f621d61fSGrant Peltier 166f621d61fSGrant Peltier switch (reg) { 167f621d61fSGrant Peltier case PMBUS_VIRT_READ_VMON: 168f621d61fSGrant Peltier ret = pmbus_read_word_data(client, page, phase, 169f621d61fSGrant Peltier RAA_DMPVR2_READ_VMON); 170f621d61fSGrant Peltier break; 171f621d61fSGrant Peltier default: 172f621d61fSGrant Peltier ret = -ENODATA; 173f621d61fSGrant Peltier break; 174f621d61fSGrant Peltier } 175f621d61fSGrant Peltier 176f621d61fSGrant Peltier return ret; 177f621d61fSGrant Peltier } 178f621d61fSGrant Peltier 179f621d61fSGrant Peltier static struct pmbus_driver_info raa_dmpvr_info = { 180f621d61fSGrant Peltier .pages = 3, 181038a9c3dSMaxim Sloyko .format[PSC_VOLTAGE_IN] = direct, 182038a9c3dSMaxim Sloyko .format[PSC_VOLTAGE_OUT] = direct, 183038a9c3dSMaxim Sloyko .format[PSC_CURRENT_IN] = direct, 184038a9c3dSMaxim Sloyko .format[PSC_CURRENT_OUT] = direct, 185038a9c3dSMaxim Sloyko .format[PSC_POWER] = direct, 186038a9c3dSMaxim Sloyko .format[PSC_TEMPERATURE] = direct, 187038a9c3dSMaxim Sloyko .m[PSC_VOLTAGE_IN] = 1, 188038a9c3dSMaxim Sloyko .b[PSC_VOLTAGE_IN] = 0, 189f621d61fSGrant Peltier .R[PSC_VOLTAGE_IN] = 2, 190038a9c3dSMaxim Sloyko .m[PSC_VOLTAGE_OUT] = 1, 191038a9c3dSMaxim Sloyko .b[PSC_VOLTAGE_OUT] = 0, 192038a9c3dSMaxim Sloyko .R[PSC_VOLTAGE_OUT] = 3, 193038a9c3dSMaxim Sloyko .m[PSC_CURRENT_IN] = 1, 194038a9c3dSMaxim Sloyko .b[PSC_CURRENT_IN] = 0, 195038a9c3dSMaxim Sloyko .R[PSC_CURRENT_IN] = 2, 196038a9c3dSMaxim Sloyko .m[PSC_CURRENT_OUT] = 1, 197038a9c3dSMaxim Sloyko .b[PSC_CURRENT_OUT] = 0, 198038a9c3dSMaxim Sloyko .R[PSC_CURRENT_OUT] = 1, 199038a9c3dSMaxim Sloyko .m[PSC_POWER] = 1, 200038a9c3dSMaxim Sloyko .b[PSC_POWER] = 0, 201038a9c3dSMaxim Sloyko .R[PSC_POWER] = 0, 202038a9c3dSMaxim Sloyko .m[PSC_TEMPERATURE] = 1, 203038a9c3dSMaxim Sloyko .b[PSC_TEMPERATURE] = 0, 204038a9c3dSMaxim Sloyko .R[PSC_TEMPERATURE] = 0, 205038a9c3dSMaxim Sloyko .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN 206038a9c3dSMaxim Sloyko | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 207038a9c3dSMaxim Sloyko | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP 208038a9c3dSMaxim Sloyko | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 209f621d61fSGrant Peltier | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT 210f621d61fSGrant Peltier | PMBUS_HAVE_VMON, 211f621d61fSGrant Peltier .func[1] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT 212f621d61fSGrant Peltier | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP 213f621d61fSGrant Peltier | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT 214f621d61fSGrant Peltier | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, 215f621d61fSGrant Peltier .func[2] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT 216f621d61fSGrant Peltier | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP 217f621d61fSGrant Peltier | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT 218f621d61fSGrant Peltier | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, 219038a9c3dSMaxim Sloyko }; 220038a9c3dSMaxim Sloyko 221038a9c3dSMaxim Sloyko static int isl68137_probe(struct i2c_client *client, 222038a9c3dSMaxim Sloyko const struct i2c_device_id *id) 223038a9c3dSMaxim Sloyko { 224f621d61fSGrant Peltier struct pmbus_driver_info *info; 225f621d61fSGrant Peltier 226f621d61fSGrant Peltier info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL); 227f621d61fSGrant Peltier if (!info) 228f621d61fSGrant Peltier return -ENOMEM; 229f621d61fSGrant Peltier memcpy(info, &raa_dmpvr_info, sizeof(*info)); 230f621d61fSGrant Peltier 231f621d61fSGrant Peltier switch (id->driver_data) { 23237d59d10SGuenter Roeck case raa_dmpvr1_2rail: 233f621d61fSGrant Peltier info->pages = 2; 234f621d61fSGrant Peltier info->R[PSC_VOLTAGE_IN] = 3; 235f621d61fSGrant Peltier info->func[0] &= ~PMBUS_HAVE_VMON; 236f621d61fSGrant Peltier info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 237f621d61fSGrant Peltier | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT 238f621d61fSGrant Peltier | PMBUS_HAVE_POUT; 239f621d61fSGrant Peltier info->groups = isl68137_attribute_groups; 240f621d61fSGrant Peltier break; 241f621d61fSGrant Peltier case raa_dmpvr2_1rail: 242f621d61fSGrant Peltier info->pages = 1; 243f621d61fSGrant Peltier info->read_word_data = raa_dmpvr2_read_word_data; 244f621d61fSGrant Peltier break; 245*51fb91edSGrant Peltier case raa_dmpvr2_2rail_nontc: 246*51fb91edSGrant Peltier info->func[0] &= ~PMBUS_HAVE_TEMP; 247*51fb91edSGrant Peltier info->func[1] &= ~PMBUS_HAVE_TEMP; 248*51fb91edSGrant Peltier fallthrough; 249f621d61fSGrant Peltier case raa_dmpvr2_2rail: 250f621d61fSGrant Peltier info->pages = 2; 251f621d61fSGrant Peltier info->read_word_data = raa_dmpvr2_read_word_data; 252f621d61fSGrant Peltier break; 253f621d61fSGrant Peltier case raa_dmpvr2_3rail: 254f621d61fSGrant Peltier info->read_word_data = raa_dmpvr2_read_word_data; 255f621d61fSGrant Peltier break; 256f621d61fSGrant Peltier case raa_dmpvr2_hv: 257f621d61fSGrant Peltier info->pages = 1; 258f621d61fSGrant Peltier info->R[PSC_VOLTAGE_IN] = 1; 259f621d61fSGrant Peltier info->m[PSC_VOLTAGE_OUT] = 2; 260f621d61fSGrant Peltier info->R[PSC_VOLTAGE_OUT] = 2; 261f621d61fSGrant Peltier info->m[PSC_CURRENT_IN] = 2; 262f621d61fSGrant Peltier info->m[PSC_POWER] = 2; 263f621d61fSGrant Peltier info->R[PSC_POWER] = -1; 264f621d61fSGrant Peltier info->read_word_data = raa_dmpvr2_read_word_data; 265f621d61fSGrant Peltier break; 266f621d61fSGrant Peltier default: 267f621d61fSGrant Peltier return -ENODEV; 268038a9c3dSMaxim Sloyko } 269038a9c3dSMaxim Sloyko 270f621d61fSGrant Peltier return pmbus_do_probe(client, id, info); 271f621d61fSGrant Peltier } 272f621d61fSGrant Peltier 273f621d61fSGrant Peltier static const struct i2c_device_id raa_dmpvr_id[] = { 27437d59d10SGuenter Roeck {"isl68137", raa_dmpvr1_2rail}, 27537d59d10SGuenter Roeck {"isl68220", raa_dmpvr2_2rail}, 27637d59d10SGuenter Roeck {"isl68221", raa_dmpvr2_3rail}, 27737d59d10SGuenter Roeck {"isl68222", raa_dmpvr2_2rail}, 27837d59d10SGuenter Roeck {"isl68223", raa_dmpvr2_2rail}, 27937d59d10SGuenter Roeck {"isl68224", raa_dmpvr2_3rail}, 28037d59d10SGuenter Roeck {"isl68225", raa_dmpvr2_2rail}, 28137d59d10SGuenter Roeck {"isl68226", raa_dmpvr2_3rail}, 28237d59d10SGuenter Roeck {"isl68227", raa_dmpvr2_1rail}, 28337d59d10SGuenter Roeck {"isl68229", raa_dmpvr2_3rail}, 28437d59d10SGuenter Roeck {"isl68233", raa_dmpvr2_2rail}, 28537d59d10SGuenter Roeck {"isl68239", raa_dmpvr2_3rail}, 28637d59d10SGuenter Roeck 28737d59d10SGuenter Roeck {"isl69222", raa_dmpvr2_2rail}, 28837d59d10SGuenter Roeck {"isl69223", raa_dmpvr2_3rail}, 28937d59d10SGuenter Roeck {"isl69224", raa_dmpvr2_2rail}, 29037d59d10SGuenter Roeck {"isl69225", raa_dmpvr2_2rail}, 29137d59d10SGuenter Roeck {"isl69227", raa_dmpvr2_3rail}, 29237d59d10SGuenter Roeck {"isl69228", raa_dmpvr2_3rail}, 29337d59d10SGuenter Roeck {"isl69234", raa_dmpvr2_2rail}, 29437d59d10SGuenter Roeck {"isl69236", raa_dmpvr2_2rail}, 29537d59d10SGuenter Roeck {"isl69239", raa_dmpvr2_3rail}, 29637d59d10SGuenter Roeck {"isl69242", raa_dmpvr2_2rail}, 29737d59d10SGuenter Roeck {"isl69243", raa_dmpvr2_1rail}, 29837d59d10SGuenter Roeck {"isl69247", raa_dmpvr2_2rail}, 29937d59d10SGuenter Roeck {"isl69248", raa_dmpvr2_2rail}, 30037d59d10SGuenter Roeck {"isl69254", raa_dmpvr2_2rail}, 30137d59d10SGuenter Roeck {"isl69255", raa_dmpvr2_2rail}, 30237d59d10SGuenter Roeck {"isl69256", raa_dmpvr2_2rail}, 30337d59d10SGuenter Roeck {"isl69259", raa_dmpvr2_2rail}, 30437d59d10SGuenter Roeck {"isl69260", raa_dmpvr2_2rail}, 30537d59d10SGuenter Roeck {"isl69268", raa_dmpvr2_2rail}, 30637d59d10SGuenter Roeck {"isl69269", raa_dmpvr2_3rail}, 30737d59d10SGuenter Roeck {"isl69298", raa_dmpvr2_2rail}, 30837d59d10SGuenter Roeck 30937d59d10SGuenter Roeck {"raa228000", raa_dmpvr2_hv}, 31037d59d10SGuenter Roeck {"raa228004", raa_dmpvr2_hv}, 31137d59d10SGuenter Roeck {"raa228006", raa_dmpvr2_hv}, 312*51fb91edSGrant Peltier {"raa228228", raa_dmpvr2_2rail_nontc}, 31337d59d10SGuenter Roeck {"raa229001", raa_dmpvr2_2rail}, 31437d59d10SGuenter Roeck {"raa229004", raa_dmpvr2_2rail}, 315038a9c3dSMaxim Sloyko {} 316038a9c3dSMaxim Sloyko }; 317038a9c3dSMaxim Sloyko 318f621d61fSGrant Peltier MODULE_DEVICE_TABLE(i2c, raa_dmpvr_id); 319038a9c3dSMaxim Sloyko 320038a9c3dSMaxim Sloyko /* This is the driver that will be inserted */ 321038a9c3dSMaxim Sloyko static struct i2c_driver isl68137_driver = { 322038a9c3dSMaxim Sloyko .driver = { 323038a9c3dSMaxim Sloyko .name = "isl68137", 324038a9c3dSMaxim Sloyko }, 325038a9c3dSMaxim Sloyko .probe = isl68137_probe, 326038a9c3dSMaxim Sloyko .remove = pmbus_do_remove, 327f621d61fSGrant Peltier .id_table = raa_dmpvr_id, 328038a9c3dSMaxim Sloyko }; 329038a9c3dSMaxim Sloyko 330038a9c3dSMaxim Sloyko module_i2c_driver(isl68137_driver); 331038a9c3dSMaxim Sloyko 332038a9c3dSMaxim Sloyko MODULE_AUTHOR("Maxim Sloyko <maxims@google.com>"); 333f621d61fSGrant Peltier MODULE_DESCRIPTION("PMBus driver for Renesas digital multiphase voltage regulators"); 334038a9c3dSMaxim Sloyko MODULE_LICENSE("GPL"); 335