1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Hardware monitoring driver for Renesas Digital Multiphase Voltage Regulators 4 * 5 * Copyright (c) 2017 Google Inc 6 * Copyright (c) 2020 Renesas Electronics America 7 * 8 */ 9 10 #include <linux/err.h> 11 #include <linux/hwmon-sysfs.h> 12 #include <linux/i2c.h> 13 #include <linux/init.h> 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/string.h> 17 #include <linux/sysfs.h> 18 19 #include "pmbus.h" 20 21 #define ISL68137_VOUT_AVS 0x30 22 #define RAA_DMPVR2_READ_VMON 0xc8 23 24 enum chips { 25 isl68137, 26 isl68220, 27 isl68221, 28 isl68222, 29 isl68223, 30 isl68224, 31 isl68225, 32 isl68226, 33 isl68227, 34 isl68229, 35 isl68233, 36 isl68239, 37 isl69222, 38 isl69223, 39 isl69224, 40 isl69225, 41 isl69227, 42 isl69228, 43 isl69234, 44 isl69236, 45 isl69239, 46 isl69242, 47 isl69243, 48 isl69247, 49 isl69248, 50 isl69254, 51 isl69255, 52 isl69256, 53 isl69259, 54 isl69260, 55 isl69268, 56 isl69269, 57 isl69298, 58 raa228000, 59 raa228004, 60 raa228006, 61 raa228228, 62 raa229001, 63 raa229004, 64 }; 65 66 enum variants { 67 raa_dmpvr1_2rail, 68 raa_dmpvr2_1rail, 69 raa_dmpvr2_2rail, 70 raa_dmpvr2_2rail_nontc, 71 raa_dmpvr2_3rail, 72 raa_dmpvr2_hv, 73 }; 74 75 static ssize_t isl68137_avs_enable_show_page(struct i2c_client *client, 76 int page, 77 char *buf) 78 { 79 int val = pmbus_read_byte_data(client, page, PMBUS_OPERATION); 80 81 return sprintf(buf, "%d\n", 82 (val & ISL68137_VOUT_AVS) == ISL68137_VOUT_AVS ? 1 : 0); 83 } 84 85 static ssize_t isl68137_avs_enable_store_page(struct i2c_client *client, 86 int page, 87 const char *buf, size_t count) 88 { 89 int rc, op_val; 90 bool result; 91 92 rc = kstrtobool(buf, &result); 93 if (rc) 94 return rc; 95 96 op_val = result ? ISL68137_VOUT_AVS : 0; 97 98 /* 99 * Writes to VOUT setpoint over AVSBus will persist after the VRM is 100 * switched to PMBus control. Switching back to AVSBus control 101 * restores this persisted setpoint rather than re-initializing to 102 * PMBus VOUT_COMMAND. Writing VOUT_COMMAND first over PMBus before 103 * enabling AVS control is the workaround. 104 */ 105 if (op_val == ISL68137_VOUT_AVS) { 106 rc = pmbus_read_word_data(client, page, 0xff, 107 PMBUS_VOUT_COMMAND); 108 if (rc < 0) 109 return rc; 110 111 rc = pmbus_write_word_data(client, page, PMBUS_VOUT_COMMAND, 112 rc); 113 if (rc < 0) 114 return rc; 115 } 116 117 rc = pmbus_update_byte_data(client, page, PMBUS_OPERATION, 118 ISL68137_VOUT_AVS, op_val); 119 120 return (rc < 0) ? rc : count; 121 } 122 123 static ssize_t isl68137_avs_enable_show(struct device *dev, 124 struct device_attribute *devattr, 125 char *buf) 126 { 127 struct i2c_client *client = to_i2c_client(dev->parent); 128 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 129 130 return isl68137_avs_enable_show_page(client, attr->index, buf); 131 } 132 133 static ssize_t isl68137_avs_enable_store(struct device *dev, 134 struct device_attribute *devattr, 135 const char *buf, size_t count) 136 { 137 struct i2c_client *client = to_i2c_client(dev->parent); 138 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 139 140 return isl68137_avs_enable_store_page(client, attr->index, buf, count); 141 } 142 143 static SENSOR_DEVICE_ATTR_RW(avs0_enable, isl68137_avs_enable, 0); 144 static SENSOR_DEVICE_ATTR_RW(avs1_enable, isl68137_avs_enable, 1); 145 146 static struct attribute *enable_attrs[] = { 147 &sensor_dev_attr_avs0_enable.dev_attr.attr, 148 &sensor_dev_attr_avs1_enable.dev_attr.attr, 149 NULL, 150 }; 151 152 static const struct attribute_group enable_group = { 153 .attrs = enable_attrs, 154 }; 155 156 static const struct attribute_group *isl68137_attribute_groups[] = { 157 &enable_group, 158 NULL, 159 }; 160 161 static int raa_dmpvr2_read_word_data(struct i2c_client *client, int page, 162 int phase, int reg) 163 { 164 int ret; 165 166 switch (reg) { 167 case PMBUS_VIRT_READ_VMON: 168 ret = pmbus_read_word_data(client, page, phase, 169 RAA_DMPVR2_READ_VMON); 170 break; 171 default: 172 ret = -ENODATA; 173 break; 174 } 175 176 return ret; 177 } 178 179 static struct pmbus_driver_info raa_dmpvr_info = { 180 .pages = 3, 181 .format[PSC_VOLTAGE_IN] = direct, 182 .format[PSC_VOLTAGE_OUT] = direct, 183 .format[PSC_CURRENT_IN] = direct, 184 .format[PSC_CURRENT_OUT] = direct, 185 .format[PSC_POWER] = direct, 186 .format[PSC_TEMPERATURE] = direct, 187 .m[PSC_VOLTAGE_IN] = 1, 188 .b[PSC_VOLTAGE_IN] = 0, 189 .R[PSC_VOLTAGE_IN] = 2, 190 .m[PSC_VOLTAGE_OUT] = 1, 191 .b[PSC_VOLTAGE_OUT] = 0, 192 .R[PSC_VOLTAGE_OUT] = 3, 193 .m[PSC_CURRENT_IN] = 1, 194 .b[PSC_CURRENT_IN] = 0, 195 .R[PSC_CURRENT_IN] = 2, 196 .m[PSC_CURRENT_OUT] = 1, 197 .b[PSC_CURRENT_OUT] = 0, 198 .R[PSC_CURRENT_OUT] = 1, 199 .m[PSC_POWER] = 1, 200 .b[PSC_POWER] = 0, 201 .R[PSC_POWER] = 0, 202 .m[PSC_TEMPERATURE] = 1, 203 .b[PSC_TEMPERATURE] = 0, 204 .R[PSC_TEMPERATURE] = 0, 205 .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN 206 | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 207 | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP 208 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 209 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT 210 | PMBUS_HAVE_VMON, 211 .func[1] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT 212 | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP 213 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT 214 | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, 215 .func[2] = PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | PMBUS_HAVE_STATUS_INPUT 216 | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_TEMP 217 | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_IOUT 218 | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, 219 }; 220 221 static int isl68137_probe(struct i2c_client *client, 222 const struct i2c_device_id *id) 223 { 224 struct pmbus_driver_info *info; 225 226 info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL); 227 if (!info) 228 return -ENOMEM; 229 memcpy(info, &raa_dmpvr_info, sizeof(*info)); 230 231 switch (id->driver_data) { 232 case raa_dmpvr1_2rail: 233 info->pages = 2; 234 info->R[PSC_VOLTAGE_IN] = 3; 235 info->func[0] &= ~PMBUS_HAVE_VMON; 236 info->func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 237 | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT 238 | PMBUS_HAVE_POUT; 239 info->groups = isl68137_attribute_groups; 240 break; 241 case raa_dmpvr2_1rail: 242 info->pages = 1; 243 info->read_word_data = raa_dmpvr2_read_word_data; 244 break; 245 case raa_dmpvr2_2rail_nontc: 246 info->func[0] &= ~PMBUS_HAVE_TEMP; 247 info->func[1] &= ~PMBUS_HAVE_TEMP; 248 fallthrough; 249 case raa_dmpvr2_2rail: 250 info->pages = 2; 251 info->read_word_data = raa_dmpvr2_read_word_data; 252 break; 253 case raa_dmpvr2_3rail: 254 info->read_word_data = raa_dmpvr2_read_word_data; 255 break; 256 case raa_dmpvr2_hv: 257 info->pages = 1; 258 info->R[PSC_VOLTAGE_IN] = 1; 259 info->m[PSC_VOLTAGE_OUT] = 2; 260 info->R[PSC_VOLTAGE_OUT] = 2; 261 info->m[PSC_CURRENT_IN] = 2; 262 info->m[PSC_POWER] = 2; 263 info->R[PSC_POWER] = -1; 264 info->read_word_data = raa_dmpvr2_read_word_data; 265 break; 266 default: 267 return -ENODEV; 268 } 269 270 return pmbus_do_probe(client, id, info); 271 } 272 273 static const struct i2c_device_id raa_dmpvr_id[] = { 274 {"isl68137", raa_dmpvr1_2rail}, 275 {"isl68220", raa_dmpvr2_2rail}, 276 {"isl68221", raa_dmpvr2_3rail}, 277 {"isl68222", raa_dmpvr2_2rail}, 278 {"isl68223", raa_dmpvr2_2rail}, 279 {"isl68224", raa_dmpvr2_3rail}, 280 {"isl68225", raa_dmpvr2_2rail}, 281 {"isl68226", raa_dmpvr2_3rail}, 282 {"isl68227", raa_dmpvr2_1rail}, 283 {"isl68229", raa_dmpvr2_3rail}, 284 {"isl68233", raa_dmpvr2_2rail}, 285 {"isl68239", raa_dmpvr2_3rail}, 286 287 {"isl69222", raa_dmpvr2_2rail}, 288 {"isl69223", raa_dmpvr2_3rail}, 289 {"isl69224", raa_dmpvr2_2rail}, 290 {"isl69225", raa_dmpvr2_2rail}, 291 {"isl69227", raa_dmpvr2_3rail}, 292 {"isl69228", raa_dmpvr2_3rail}, 293 {"isl69234", raa_dmpvr2_2rail}, 294 {"isl69236", raa_dmpvr2_2rail}, 295 {"isl69239", raa_dmpvr2_3rail}, 296 {"isl69242", raa_dmpvr2_2rail}, 297 {"isl69243", raa_dmpvr2_1rail}, 298 {"isl69247", raa_dmpvr2_2rail}, 299 {"isl69248", raa_dmpvr2_2rail}, 300 {"isl69254", raa_dmpvr2_2rail}, 301 {"isl69255", raa_dmpvr2_2rail}, 302 {"isl69256", raa_dmpvr2_2rail}, 303 {"isl69259", raa_dmpvr2_2rail}, 304 {"isl69260", raa_dmpvr2_2rail}, 305 {"isl69268", raa_dmpvr2_2rail}, 306 {"isl69269", raa_dmpvr2_3rail}, 307 {"isl69298", raa_dmpvr2_2rail}, 308 309 {"raa228000", raa_dmpvr2_hv}, 310 {"raa228004", raa_dmpvr2_hv}, 311 {"raa228006", raa_dmpvr2_hv}, 312 {"raa228228", raa_dmpvr2_2rail_nontc}, 313 {"raa229001", raa_dmpvr2_2rail}, 314 {"raa229004", raa_dmpvr2_2rail}, 315 {} 316 }; 317 318 MODULE_DEVICE_TABLE(i2c, raa_dmpvr_id); 319 320 /* This is the driver that will be inserted */ 321 static struct i2c_driver isl68137_driver = { 322 .driver = { 323 .name = "isl68137", 324 }, 325 .probe = isl68137_probe, 326 .remove = pmbus_do_remove, 327 .id_table = raa_dmpvr_id, 328 }; 329 330 module_i2c_driver(isl68137_driver); 331 332 MODULE_AUTHOR("Maxim Sloyko <maxims@google.com>"); 333 MODULE_DESCRIPTION("PMBus driver for Renesas digital multiphase voltage regulators"); 334 MODULE_LICENSE("GPL"); 335