1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Driver for MAX20730, MAX20734, and MAX20743 Integrated, Step-Down 4 * Switching Regulators 5 * 6 * Copyright 2019 Google LLC. 7 */ 8 9 #include <linux/bits.h> 10 #include <linux/err.h> 11 #include <linux/i2c.h> 12 #include <linux/init.h> 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/mutex.h> 16 #include <linux/of_device.h> 17 #include <linux/pmbus.h> 18 #include <linux/util_macros.h> 19 #include "pmbus.h" 20 21 enum chips { 22 max20730, 23 max20734, 24 max20743 25 }; 26 27 struct max20730_data { 28 enum chips id; 29 struct pmbus_driver_info info; 30 struct mutex lock; /* Used to protect against parallel writes */ 31 u16 mfr_devset1; 32 }; 33 34 #define to_max20730_data(x) container_of(x, struct max20730_data, info) 35 36 #define MAX20730_MFR_DEVSET1 0xd2 37 38 /* 39 * Convert discreet value to direct data format. Strictly speaking, all passed 40 * values are constants, so we could do that calculation manually. On the 41 * downside, that would make the driver more difficult to maintain, so lets 42 * use this approach. 43 */ 44 static u16 val_to_direct(int v, enum pmbus_sensor_classes class, 45 const struct pmbus_driver_info *info) 46 { 47 int R = info->R[class] - 3; /* take milli-units into account */ 48 int b = info->b[class] * 1000; 49 long d; 50 51 d = v * info->m[class] + b; 52 /* 53 * R < 0 is true for all callers, so we don't need to bother 54 * about the R > 0 case. 55 */ 56 while (R < 0) { 57 d = DIV_ROUND_CLOSEST(d, 10); 58 R++; 59 } 60 return (u16)d; 61 } 62 63 static long direct_to_val(u16 w, enum pmbus_sensor_classes class, 64 const struct pmbus_driver_info *info) 65 { 66 int R = info->R[class] - 3; 67 int b = info->b[class] * 1000; 68 int m = info->m[class]; 69 long d = (s16)w; 70 71 if (m == 0) 72 return 0; 73 74 while (R < 0) { 75 d *= 10; 76 R++; 77 } 78 d = (d - b) / m; 79 return d; 80 } 81 82 static u32 max_current[][5] = { 83 [max20730] = { 13000, 16600, 20100, 23600 }, 84 [max20734] = { 21000, 27000, 32000, 38000 }, 85 [max20743] = { 18900, 24100, 29200, 34100 }, 86 }; 87 88 static int max20730_read_word_data(struct i2c_client *client, int page, 89 int phase, int reg) 90 { 91 const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 92 const struct max20730_data *data = to_max20730_data(info); 93 int ret = 0; 94 u32 max_c; 95 96 switch (reg) { 97 case PMBUS_OT_FAULT_LIMIT: 98 switch ((data->mfr_devset1 >> 11) & 0x3) { 99 case 0x0: 100 ret = val_to_direct(150000, PSC_TEMPERATURE, info); 101 break; 102 case 0x1: 103 ret = val_to_direct(130000, PSC_TEMPERATURE, info); 104 break; 105 default: 106 ret = -ENODATA; 107 break; 108 } 109 break; 110 case PMBUS_IOUT_OC_FAULT_LIMIT: 111 max_c = max_current[data->id][(data->mfr_devset1 >> 5) & 0x3]; 112 ret = val_to_direct(max_c, PSC_CURRENT_OUT, info); 113 break; 114 default: 115 ret = -ENODATA; 116 break; 117 } 118 return ret; 119 } 120 121 static int max20730_write_word_data(struct i2c_client *client, int page, 122 int reg, u16 word) 123 { 124 struct pmbus_driver_info *info; 125 struct max20730_data *data; 126 u16 devset1; 127 int ret = 0; 128 int idx; 129 130 info = (struct pmbus_driver_info *)pmbus_get_driver_info(client); 131 data = to_max20730_data(info); 132 133 mutex_lock(&data->lock); 134 devset1 = data->mfr_devset1; 135 136 switch (reg) { 137 case PMBUS_OT_FAULT_LIMIT: 138 devset1 &= ~(BIT(11) | BIT(12)); 139 if (direct_to_val(word, PSC_TEMPERATURE, info) < 140000) 140 devset1 |= BIT(11); 141 break; 142 case PMBUS_IOUT_OC_FAULT_LIMIT: 143 devset1 &= ~(BIT(5) | BIT(6)); 144 145 idx = find_closest(direct_to_val(word, PSC_CURRENT_OUT, info), 146 max_current[data->id], 4); 147 devset1 |= (idx << 5); 148 break; 149 default: 150 ret = -ENODATA; 151 break; 152 } 153 154 if (!ret && devset1 != data->mfr_devset1) { 155 ret = i2c_smbus_write_word_data(client, MAX20730_MFR_DEVSET1, 156 devset1); 157 if (!ret) { 158 data->mfr_devset1 = devset1; 159 pmbus_clear_cache(client); 160 } 161 } 162 mutex_unlock(&data->lock); 163 return ret; 164 } 165 166 static const struct pmbus_driver_info max20730_info[] = { 167 [max20730] = { 168 .pages = 1, 169 .read_word_data = max20730_read_word_data, 170 .write_word_data = max20730_write_word_data, 171 172 /* Source : Maxim AN6042 */ 173 .format[PSC_TEMPERATURE] = direct, 174 .m[PSC_TEMPERATURE] = 21, 175 .b[PSC_TEMPERATURE] = 5887, 176 .R[PSC_TEMPERATURE] = -1, 177 178 .format[PSC_VOLTAGE_IN] = direct, 179 .m[PSC_VOLTAGE_IN] = 3609, 180 .b[PSC_VOLTAGE_IN] = 0, 181 .R[PSC_VOLTAGE_IN] = -2, 182 183 /* 184 * Values in the datasheet are adjusted for temperature and 185 * for the relationship between Vin and Vout. 186 * Unfortunately, the data sheet suggests that Vout measurement 187 * may be scaled with a resistor array. This is indeed the case 188 * at least on the evaulation boards. As a result, any in-driver 189 * adjustments would either be wrong or require elaborate means 190 * to configure the scaling. Instead of doing that, just report 191 * raw values and let userspace handle adjustments. 192 */ 193 .format[PSC_CURRENT_OUT] = direct, 194 .m[PSC_CURRENT_OUT] = 153, 195 .b[PSC_CURRENT_OUT] = 4976, 196 .R[PSC_CURRENT_OUT] = -1, 197 198 .format[PSC_VOLTAGE_OUT] = linear, 199 200 .func[0] = PMBUS_HAVE_VIN | 201 PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 202 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 203 PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 204 }, 205 [max20734] = { 206 .pages = 1, 207 .read_word_data = max20730_read_word_data, 208 .write_word_data = max20730_write_word_data, 209 210 /* Source : Maxim AN6209 */ 211 .format[PSC_TEMPERATURE] = direct, 212 .m[PSC_TEMPERATURE] = 21, 213 .b[PSC_TEMPERATURE] = 5887, 214 .R[PSC_TEMPERATURE] = -1, 215 216 .format[PSC_VOLTAGE_IN] = direct, 217 .m[PSC_VOLTAGE_IN] = 3592, 218 .b[PSC_VOLTAGE_IN] = 0, 219 .R[PSC_VOLTAGE_IN] = -2, 220 221 .format[PSC_CURRENT_OUT] = direct, 222 .m[PSC_CURRENT_OUT] = 111, 223 .b[PSC_CURRENT_OUT] = 3461, 224 .R[PSC_CURRENT_OUT] = -1, 225 226 .format[PSC_VOLTAGE_OUT] = linear, 227 228 .func[0] = PMBUS_HAVE_VIN | 229 PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 230 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 231 PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 232 }, 233 [max20743] = { 234 .pages = 1, 235 .read_word_data = max20730_read_word_data, 236 .write_word_data = max20730_write_word_data, 237 238 /* Source : Maxim AN6042 */ 239 .format[PSC_TEMPERATURE] = direct, 240 .m[PSC_TEMPERATURE] = 21, 241 .b[PSC_TEMPERATURE] = 5887, 242 .R[PSC_TEMPERATURE] = -1, 243 244 .format[PSC_VOLTAGE_IN] = direct, 245 .m[PSC_VOLTAGE_IN] = 3597, 246 .b[PSC_VOLTAGE_IN] = 0, 247 .R[PSC_VOLTAGE_IN] = -2, 248 249 .format[PSC_CURRENT_OUT] = direct, 250 .m[PSC_CURRENT_OUT] = 95, 251 .b[PSC_CURRENT_OUT] = 5014, 252 .R[PSC_CURRENT_OUT] = -1, 253 254 .format[PSC_VOLTAGE_OUT] = linear, 255 256 .func[0] = PMBUS_HAVE_VIN | 257 PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 258 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 259 PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, 260 }, 261 }; 262 263 static int max20730_probe(struct i2c_client *client, 264 const struct i2c_device_id *id) 265 { 266 struct device *dev = &client->dev; 267 u8 buf[I2C_SMBUS_BLOCK_MAX + 1]; 268 struct max20730_data *data; 269 enum chips chip_id; 270 int ret; 271 272 if (!i2c_check_functionality(client->adapter, 273 I2C_FUNC_SMBUS_READ_BYTE_DATA | 274 I2C_FUNC_SMBUS_READ_WORD_DATA | 275 I2C_FUNC_SMBUS_BLOCK_DATA)) 276 return -ENODEV; 277 278 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf); 279 if (ret < 0) { 280 dev_err(&client->dev, "Failed to read Manufacturer ID\n"); 281 return ret; 282 } 283 if (ret != 5 || strncmp(buf, "MAXIM", 5)) { 284 buf[ret] = '\0'; 285 dev_err(dev, "Unsupported Manufacturer ID '%s'\n", buf); 286 return -ENODEV; 287 } 288 289 /* 290 * The chips support reading PMBUS_MFR_MODEL. On both MAX20730 291 * and MAX20734, reading it returns M20743. Presumably that is 292 * the reason why the command is not documented. Unfortunately, 293 * that means that there is no reliable means to detect the chip. 294 * However, we can at least detect the chip series. Compare 295 * the returned value against 'M20743' and bail out if there is 296 * a mismatch. If that doesn't work for all chips, we may have 297 * to remove this check. 298 */ 299 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf); 300 if (ret < 0) { 301 dev_err(dev, "Failed to read Manufacturer Model\n"); 302 return ret; 303 } 304 if (ret != 6 || strncmp(buf, "M20743", 6)) { 305 buf[ret] = '\0'; 306 dev_err(dev, "Unsupported Manufacturer Model '%s'\n", buf); 307 return -ENODEV; 308 } 309 310 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_REVISION, buf); 311 if (ret < 0) { 312 dev_err(dev, "Failed to read Manufacturer Revision\n"); 313 return ret; 314 } 315 if (ret != 1 || buf[0] != 'F') { 316 buf[ret] = '\0'; 317 dev_err(dev, "Unsupported Manufacturer Revision '%s'\n", buf); 318 return -ENODEV; 319 } 320 321 if (client->dev.of_node) 322 chip_id = (enum chips)of_device_get_match_data(dev); 323 else 324 chip_id = id->driver_data; 325 326 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 327 if (!data) 328 return -ENOMEM; 329 data->id = chip_id; 330 mutex_init(&data->lock); 331 memcpy(&data->info, &max20730_info[chip_id], sizeof(data->info)); 332 333 ret = i2c_smbus_read_word_data(client, MAX20730_MFR_DEVSET1); 334 if (ret < 0) 335 return ret; 336 data->mfr_devset1 = ret; 337 338 return pmbus_do_probe(client, id, &data->info); 339 } 340 341 static const struct i2c_device_id max20730_id[] = { 342 { "max20730", max20730 }, 343 { "max20734", max20734 }, 344 { "max20743", max20743 }, 345 { }, 346 }; 347 348 MODULE_DEVICE_TABLE(i2c, max20730_id); 349 350 static const struct of_device_id max20730_of_match[] = { 351 { .compatible = "maxim,max20730", .data = (void *)max20730 }, 352 { .compatible = "maxim,max20734", .data = (void *)max20734 }, 353 { .compatible = "maxim,max20743", .data = (void *)max20743 }, 354 { }, 355 }; 356 357 MODULE_DEVICE_TABLE(of, max20730_of_match); 358 359 static struct i2c_driver max20730_driver = { 360 .driver = { 361 .name = "max20730", 362 .of_match_table = max20730_of_match, 363 }, 364 .probe = max20730_probe, 365 .remove = pmbus_do_remove, 366 .id_table = max20730_id, 367 }; 368 369 module_i2c_driver(max20730_driver); 370 371 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); 372 MODULE_DESCRIPTION("PMBus driver for Maxim MAX20730 / MAX20734 / MAX20743"); 373 MODULE_LICENSE("GPL"); 374