791 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Driver for MAX20710, MAX20730, MAX20734, and MAX20743 Integrated,4 * Step-Down Switching Regulators5 *6 * Copyright 2019 Google LLC.7 * Copyright 2020 Maxim Integrated8 */9 10#include <linux/bits.h>11#include <linux/debugfs.h>12#include <linux/err.h>13#include <linux/i2c.h>14#include <linux/init.h>15#include <linux/kernel.h>16#include <linux/module.h>17#include <linux/mutex.h>18#include <linux/of.h>19#include <linux/pmbus.h>20#include <linux/util_macros.h>21#include "pmbus.h"22 23enum chips {24 max20710,25 max20730,26 max20734,27 max2074328};29 30enum {31 MAX20730_DEBUGFS_VOUT_MIN = 0,32 MAX20730_DEBUGFS_FREQUENCY,33 MAX20730_DEBUGFS_PG_DELAY,34 MAX20730_DEBUGFS_INTERNAL_GAIN,35 MAX20730_DEBUGFS_BOOT_VOLTAGE,36 MAX20730_DEBUGFS_OUT_V_RAMP_RATE,37 MAX20730_DEBUGFS_OC_PROTECT_MODE,38 MAX20730_DEBUGFS_SS_TIMING,39 MAX20730_DEBUGFS_IMAX,40 MAX20730_DEBUGFS_OPERATION,41 MAX20730_DEBUGFS_ON_OFF_CONFIG,42 MAX20730_DEBUGFS_SMBALERT_MASK,43 MAX20730_DEBUGFS_VOUT_MODE,44 MAX20730_DEBUGFS_VOUT_COMMAND,45 MAX20730_DEBUGFS_VOUT_MAX,46 MAX20730_DEBUGFS_NUM_ENTRIES47};48 49struct max20730_data {50 enum chips id;51 struct pmbus_driver_info info;52 struct mutex lock; /* Used to protect against parallel writes */53 u16 mfr_devset1;54 u16 mfr_devset2;55 u16 mfr_voutmin;56 u32 vout_voltage_divider[2];57};58 59#define to_max20730_data(x) container_of(x, struct max20730_data, info)60 61#define VOLT_FROM_REG(val) DIV_ROUND_CLOSEST((val), 1 << 9)62 63#define PMBUS_SMB_ALERT_MASK 0x1B64 65#define MAX20730_MFR_VOUT_MIN 0xd166#define MAX20730_MFR_DEVSET1 0xd267#define MAX20730_MFR_DEVSET2 0xd368 69#define MAX20730_MFR_VOUT_MIN_MASK GENMASK(9, 0)70#define MAX20730_MFR_VOUT_MIN_BIT_POS 071 72#define MAX20730_MFR_DEVSET1_RGAIN_MASK (BIT(13) | BIT(14))73#define MAX20730_MFR_DEVSET1_OTP_MASK (BIT(11) | BIT(12))74#define MAX20730_MFR_DEVSET1_VBOOT_MASK (BIT(8) | BIT(9))75#define MAX20730_MFR_DEVSET1_OCP_MASK (BIT(5) | BIT(6))76#define MAX20730_MFR_DEVSET1_FSW_MASK GENMASK(4, 2)77#define MAX20730_MFR_DEVSET1_TSTAT_MASK (BIT(0) | BIT(1))78 79#define MAX20730_MFR_DEVSET1_RGAIN_BIT_POS 1380#define MAX20730_MFR_DEVSET1_OTP_BIT_POS 1181#define MAX20730_MFR_DEVSET1_VBOOT_BIT_POS 882#define MAX20730_MFR_DEVSET1_OCP_BIT_POS 583#define MAX20730_MFR_DEVSET1_FSW_BIT_POS 284#define MAX20730_MFR_DEVSET1_TSTAT_BIT_POS 085 86#define MAX20730_MFR_DEVSET2_IMAX_MASK GENMASK(10, 8)87#define MAX20730_MFR_DEVSET2_VRATE (BIT(6) | BIT(7))88#define MAX20730_MFR_DEVSET2_OCPM_MASK BIT(5)89#define MAX20730_MFR_DEVSET2_SS_MASK (BIT(0) | BIT(1))90 91#define MAX20730_MFR_DEVSET2_IMAX_BIT_POS 892#define MAX20730_MFR_DEVSET2_VRATE_BIT_POS 693#define MAX20730_MFR_DEVSET2_OCPM_BIT_POS 594#define MAX20730_MFR_DEVSET2_SS_BIT_POS 095 96#define DEBUG_FS_DATA_MAX 1697 98struct max20730_debugfs_data {99 struct i2c_client *client;100 int debugfs_entries[MAX20730_DEBUGFS_NUM_ENTRIES];101};102 103#define to_psu(x, y) container_of((x), \104 struct max20730_debugfs_data, debugfs_entries[(y)])105 106#ifdef CONFIG_DEBUG_FS107static ssize_t max20730_debugfs_read(struct file *file, char __user *buf,108 size_t count, loff_t *ppos)109{110 int ret, len;111 int *idxp = file->private_data;112 int idx = *idxp;113 struct max20730_debugfs_data *psu = to_psu(idxp, idx);114 const struct pmbus_driver_info *info;115 const struct max20730_data *data;116 char tbuf[DEBUG_FS_DATA_MAX] = { 0 };117 char *result = tbuf;118 u16 val;119 120 info = pmbus_get_driver_info(psu->client);121 data = to_max20730_data(info);122 123 switch (idx) {124 case MAX20730_DEBUGFS_VOUT_MIN:125 ret = VOLT_FROM_REG(data->mfr_voutmin * 10000);126 len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d.%d\n",127 ret / 10000, ret % 10000);128 break;129 case MAX20730_DEBUGFS_FREQUENCY:130 val = (data->mfr_devset1 & MAX20730_MFR_DEVSET1_FSW_MASK)131 >> MAX20730_MFR_DEVSET1_FSW_BIT_POS;132 133 if (val == 0)134 ret = 400;135 else if (val == 1)136 ret = 500;137 else if (val == 2 || val == 3)138 ret = 600;139 else if (val == 4)140 ret = 700;141 else if (val == 5)142 ret = 800;143 else144 ret = 900;145 len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret);146 break;147 case MAX20730_DEBUGFS_PG_DELAY:148 val = (data->mfr_devset1 & MAX20730_MFR_DEVSET1_TSTAT_MASK)149 >> MAX20730_MFR_DEVSET1_TSTAT_BIT_POS;150 151 if (val == 0)152 result = "2000\n";153 else if (val == 1)154 result = "125\n";155 else if (val == 2)156 result = "62.5\n";157 else158 result = "32\n";159 break;160 case MAX20730_DEBUGFS_INTERNAL_GAIN:161 val = (data->mfr_devset1 & MAX20730_MFR_DEVSET1_RGAIN_MASK)162 >> MAX20730_MFR_DEVSET1_RGAIN_BIT_POS;163 164 if (data->id == max20734) {165 /* AN6209 */166 if (val == 0)167 result = "0.8\n";168 else if (val == 1)169 result = "3.2\n";170 else if (val == 2)171 result = "1.6\n";172 else173 result = "6.4\n";174 } else if (data->id == max20730 || data->id == max20710) {175 /* AN6042 or AN6140 */176 if (val == 0)177 result = "0.9\n";178 else if (val == 1)179 result = "3.6\n";180 else if (val == 2)181 result = "1.8\n";182 else183 result = "7.2\n";184 } else if (data->id == max20743) {185 /* AN6042 */186 if (val == 0)187 result = "0.45\n";188 else if (val == 1)189 result = "1.8\n";190 else if (val == 2)191 result = "0.9\n";192 else193 result = "3.6\n";194 } else {195 result = "Not supported\n";196 }197 break;198 case MAX20730_DEBUGFS_BOOT_VOLTAGE:199 val = (data->mfr_devset1 & MAX20730_MFR_DEVSET1_VBOOT_MASK)200 >> MAX20730_MFR_DEVSET1_VBOOT_BIT_POS;201 202 if (val == 0)203 result = "0.6484\n";204 else if (val == 1)205 result = "0.8984\n";206 else if (val == 2)207 result = "1.0\n";208 else209 result = "Invalid\n";210 break;211 case MAX20730_DEBUGFS_OUT_V_RAMP_RATE:212 val = (data->mfr_devset2 & MAX20730_MFR_DEVSET2_VRATE)213 >> MAX20730_MFR_DEVSET2_VRATE_BIT_POS;214 215 if (val == 0)216 result = "4\n";217 else if (val == 1)218 result = "2\n";219 else if (val == 2)220 result = "1\n";221 else222 result = "Invalid\n";223 break;224 case MAX20730_DEBUGFS_OC_PROTECT_MODE:225 ret = (data->mfr_devset2 & MAX20730_MFR_DEVSET2_OCPM_MASK)226 >> MAX20730_MFR_DEVSET2_OCPM_BIT_POS;227 len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret);228 break;229 case MAX20730_DEBUGFS_SS_TIMING:230 val = (data->mfr_devset2 & MAX20730_MFR_DEVSET2_SS_MASK)231 >> MAX20730_MFR_DEVSET2_SS_BIT_POS;232 233 if (val == 0)234 result = "0.75\n";235 else if (val == 1)236 result = "1.5\n";237 else if (val == 2)238 result = "3\n";239 else240 result = "6\n";241 break;242 case MAX20730_DEBUGFS_IMAX:243 ret = (data->mfr_devset2 & MAX20730_MFR_DEVSET2_IMAX_MASK)244 >> MAX20730_MFR_DEVSET2_IMAX_BIT_POS;245 len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret);246 break;247 case MAX20730_DEBUGFS_OPERATION:248 ret = i2c_smbus_read_byte_data(psu->client, PMBUS_OPERATION);249 if (ret < 0)250 return ret;251 len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret);252 break;253 case MAX20730_DEBUGFS_ON_OFF_CONFIG:254 ret = i2c_smbus_read_byte_data(psu->client, PMBUS_ON_OFF_CONFIG);255 if (ret < 0)256 return ret;257 len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret);258 break;259 case MAX20730_DEBUGFS_SMBALERT_MASK:260 ret = i2c_smbus_read_word_data(psu->client,261 PMBUS_SMB_ALERT_MASK);262 if (ret < 0)263 return ret;264 len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret);265 break;266 case MAX20730_DEBUGFS_VOUT_MODE:267 ret = i2c_smbus_read_byte_data(psu->client, PMBUS_VOUT_MODE);268 if (ret < 0)269 return ret;270 len = scnprintf(tbuf, DEBUG_FS_DATA_MAX, "%d\n", ret);271 break;272 case MAX20730_DEBUGFS_VOUT_COMMAND:273 ret = i2c_smbus_read_word_data(psu->client, PMBUS_VOUT_COMMAND);274 if (ret < 0)275 return ret;276 277 ret = VOLT_FROM_REG(ret * 10000);278 len = scnprintf(tbuf, DEBUG_FS_DATA_MAX,279 "%d.%d\n", ret / 10000, ret % 10000);280 break;281 case MAX20730_DEBUGFS_VOUT_MAX:282 ret = i2c_smbus_read_word_data(psu->client, PMBUS_VOUT_MAX);283 if (ret < 0)284 return ret;285 286 ret = VOLT_FROM_REG(ret * 10000);287 len = scnprintf(tbuf, DEBUG_FS_DATA_MAX,288 "%d.%d\n", ret / 10000, ret % 10000);289 break;290 default:291 result = "Invalid\n";292 }293 294 len = strlen(result);295 return simple_read_from_buffer(buf, count, ppos, result, len);296}297 298static const struct file_operations max20730_fops = {299 .llseek = noop_llseek,300 .read = max20730_debugfs_read,301 .write = NULL,302 .open = simple_open,303};304 305static int max20730_init_debugfs(struct i2c_client *client,306 struct max20730_data *data)307{308 int ret, i;309 struct dentry *debugfs;310 struct dentry *max20730_dir;311 struct max20730_debugfs_data *psu;312 313 ret = i2c_smbus_read_word_data(client, MAX20730_MFR_DEVSET2);314 if (ret < 0)315 return ret;316 data->mfr_devset2 = ret;317 318 ret = i2c_smbus_read_word_data(client, MAX20730_MFR_VOUT_MIN);319 if (ret < 0)320 return ret;321 data->mfr_voutmin = ret;322 323 psu = devm_kzalloc(&client->dev, sizeof(*psu), GFP_KERNEL);324 if (!psu)325 return -ENOMEM;326 psu->client = client;327 328 debugfs = pmbus_get_debugfs_dir(client);329 if (!debugfs)330 return -ENOENT;331 332 max20730_dir = debugfs_create_dir(client->name, debugfs);333 334 for (i = 0; i < MAX20730_DEBUGFS_NUM_ENTRIES; ++i)335 psu->debugfs_entries[i] = i;336 337 debugfs_create_file("vout_min", 0444, max20730_dir,338 &psu->debugfs_entries[MAX20730_DEBUGFS_VOUT_MIN],339 &max20730_fops);340 debugfs_create_file("frequency", 0444, max20730_dir,341 &psu->debugfs_entries[MAX20730_DEBUGFS_FREQUENCY],342 &max20730_fops);343 debugfs_create_file("power_good_delay", 0444, max20730_dir,344 &psu->debugfs_entries[MAX20730_DEBUGFS_PG_DELAY],345 &max20730_fops);346 debugfs_create_file("internal_gain", 0444, max20730_dir,347 &psu->debugfs_entries[MAX20730_DEBUGFS_INTERNAL_GAIN],348 &max20730_fops);349 debugfs_create_file("boot_voltage", 0444, max20730_dir,350 &psu->debugfs_entries[MAX20730_DEBUGFS_BOOT_VOLTAGE],351 &max20730_fops);352 debugfs_create_file("out_voltage_ramp_rate", 0444, max20730_dir,353 &psu->debugfs_entries[MAX20730_DEBUGFS_OUT_V_RAMP_RATE],354 &max20730_fops);355 debugfs_create_file("oc_protection_mode", 0444, max20730_dir,356 &psu->debugfs_entries[MAX20730_DEBUGFS_OC_PROTECT_MODE],357 &max20730_fops);358 debugfs_create_file("soft_start_timing", 0444, max20730_dir,359 &psu->debugfs_entries[MAX20730_DEBUGFS_SS_TIMING],360 &max20730_fops);361 debugfs_create_file("imax", 0444, max20730_dir,362 &psu->debugfs_entries[MAX20730_DEBUGFS_IMAX],363 &max20730_fops);364 debugfs_create_file("operation", 0444, max20730_dir,365 &psu->debugfs_entries[MAX20730_DEBUGFS_OPERATION],366 &max20730_fops);367 debugfs_create_file("on_off_config", 0444, max20730_dir,368 &psu->debugfs_entries[MAX20730_DEBUGFS_ON_OFF_CONFIG],369 &max20730_fops);370 debugfs_create_file("smbalert_mask", 0444, max20730_dir,371 &psu->debugfs_entries[MAX20730_DEBUGFS_SMBALERT_MASK],372 &max20730_fops);373 debugfs_create_file("vout_mode", 0444, max20730_dir,374 &psu->debugfs_entries[MAX20730_DEBUGFS_VOUT_MODE],375 &max20730_fops);376 debugfs_create_file("vout_command", 0444, max20730_dir,377 &psu->debugfs_entries[MAX20730_DEBUGFS_VOUT_COMMAND],378 &max20730_fops);379 debugfs_create_file("vout_max", 0444, max20730_dir,380 &psu->debugfs_entries[MAX20730_DEBUGFS_VOUT_MAX],381 &max20730_fops);382 383 return 0;384}385#else386static int max20730_init_debugfs(struct i2c_client *client,387 struct max20730_data *data)388{389 return 0;390}391#endif /* CONFIG_DEBUG_FS */392 393static const struct i2c_device_id max20730_id[];394 395/*396 * Convert discreet value to direct data format. Strictly speaking, all passed397 * values are constants, so we could do that calculation manually. On the398 * downside, that would make the driver more difficult to maintain, so lets399 * use this approach.400 */401static u16 val_to_direct(int v, enum pmbus_sensor_classes class,402 const struct pmbus_driver_info *info)403{404 int R = info->R[class] - 3; /* take milli-units into account */405 int b = info->b[class] * 1000;406 long d;407 408 d = v * info->m[class] + b;409 /*410 * R < 0 is true for all callers, so we don't need to bother411 * about the R > 0 case.412 */413 while (R < 0) {414 d = DIV_ROUND_CLOSEST(d, 10);415 R++;416 }417 return (u16)d;418}419 420static long direct_to_val(u16 w, enum pmbus_sensor_classes class,421 const struct pmbus_driver_info *info)422{423 int R = info->R[class] - 3;424 int b = info->b[class] * 1000;425 int m = info->m[class];426 long d = (s16)w;427 428 if (m == 0)429 return 0;430 431 while (R < 0) {432 d *= 10;433 R++;434 }435 d = (d - b) / m;436 return d;437}438 439static u32 max_current[][5] = {440 [max20710] = { 6200, 8000, 9700, 11600 },441 [max20730] = { 13000, 16600, 20100, 23600 },442 [max20734] = { 21000, 27000, 32000, 38000 },443 [max20743] = { 18900, 24100, 29200, 34100 },444};445 446static int max20730_read_word_data(struct i2c_client *client, int page,447 int phase, int reg)448{449 const struct pmbus_driver_info *info = pmbus_get_driver_info(client);450 const struct max20730_data *data = to_max20730_data(info);451 int ret = 0;452 u32 max_c;453 454 switch (reg) {455 case PMBUS_OT_FAULT_LIMIT:456 switch ((data->mfr_devset1 >> 11) & 0x3) {457 case 0x0:458 ret = val_to_direct(150000, PSC_TEMPERATURE, info);459 break;460 case 0x1:461 ret = val_to_direct(130000, PSC_TEMPERATURE, info);462 break;463 default:464 ret = -ENODATA;465 break;466 }467 break;468 case PMBUS_IOUT_OC_FAULT_LIMIT:469 max_c = max_current[data->id][(data->mfr_devset1 >> 5) & 0x3];470 ret = val_to_direct(max_c, PSC_CURRENT_OUT, info);471 break;472 case PMBUS_READ_VOUT:473 ret = pmbus_read_word_data(client, page, phase, reg);474 if (ret > 0 && data->vout_voltage_divider[0] && data->vout_voltage_divider[1]) {475 u64 temp = DIV_ROUND_CLOSEST_ULL((u64)ret * data->vout_voltage_divider[1],476 data->vout_voltage_divider[0]);477 ret = clamp_val(temp, 0, 0xffff);478 }479 break;480 default:481 ret = -ENODATA;482 break;483 }484 return ret;485}486 487static int max20730_write_word_data(struct i2c_client *client, int page,488 int reg, u16 word)489{490 struct pmbus_driver_info *info;491 struct max20730_data *data;492 u16 devset1;493 int ret = 0;494 int idx;495 496 info = (struct pmbus_driver_info *)pmbus_get_driver_info(client);497 data = to_max20730_data(info);498 499 mutex_lock(&data->lock);500 devset1 = data->mfr_devset1;501 502 switch (reg) {503 case PMBUS_OT_FAULT_LIMIT:504 devset1 &= ~(BIT(11) | BIT(12));505 if (direct_to_val(word, PSC_TEMPERATURE, info) < 140000)506 devset1 |= BIT(11);507 break;508 case PMBUS_IOUT_OC_FAULT_LIMIT:509 devset1 &= ~(BIT(5) | BIT(6));510 511 idx = find_closest(direct_to_val(word, PSC_CURRENT_OUT, info),512 max_current[data->id], 4);513 devset1 |= (idx << 5);514 break;515 default:516 ret = -ENODATA;517 break;518 }519 520 if (!ret && devset1 != data->mfr_devset1) {521 ret = i2c_smbus_write_word_data(client, MAX20730_MFR_DEVSET1,522 devset1);523 if (!ret) {524 data->mfr_devset1 = devset1;525 pmbus_clear_cache(client);526 }527 }528 mutex_unlock(&data->lock);529 return ret;530}531 532static const struct pmbus_driver_info max20730_info[] = {533 [max20710] = {534 .pages = 1,535 .read_word_data = max20730_read_word_data,536 .write_word_data = max20730_write_word_data,537 538 /* Source : Maxim AN6140 and AN6042 */539 .format[PSC_TEMPERATURE] = direct,540 .m[PSC_TEMPERATURE] = 21,541 .b[PSC_TEMPERATURE] = 5887,542 .R[PSC_TEMPERATURE] = -1,543 544 .format[PSC_VOLTAGE_IN] = direct,545 .m[PSC_VOLTAGE_IN] = 3609,546 .b[PSC_VOLTAGE_IN] = 0,547 .R[PSC_VOLTAGE_IN] = -2,548 549 .format[PSC_CURRENT_OUT] = direct,550 .m[PSC_CURRENT_OUT] = 153,551 .b[PSC_CURRENT_OUT] = 4976,552 .R[PSC_CURRENT_OUT] = -1,553 554 .format[PSC_VOLTAGE_OUT] = linear,555 556 .func[0] = PMBUS_HAVE_VIN |557 PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |558 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |559 PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |560 PMBUS_HAVE_STATUS_INPUT,561 },562 [max20730] = {563 .pages = 1,564 .read_word_data = max20730_read_word_data,565 .write_word_data = max20730_write_word_data,566 567 /* Source : Maxim AN6042 */568 .format[PSC_TEMPERATURE] = direct,569 .m[PSC_TEMPERATURE] = 21,570 .b[PSC_TEMPERATURE] = 5887,571 .R[PSC_TEMPERATURE] = -1,572 573 .format[PSC_VOLTAGE_IN] = direct,574 .m[PSC_VOLTAGE_IN] = 3609,575 .b[PSC_VOLTAGE_IN] = 0,576 .R[PSC_VOLTAGE_IN] = -2,577 578 /*579 * Values in the datasheet are adjusted for temperature and580 * for the relationship between Vin and Vout.581 * Unfortunately, the data sheet suggests that Vout measurement582 * may be scaled with a resistor array. This is indeed the case583 * at least on the evaulation boards. As a result, any in-driver584 * adjustments would either be wrong or require elaborate means585 * to configure the scaling. Instead of doing that, just report586 * raw values and let userspace handle adjustments.587 */588 .format[PSC_CURRENT_OUT] = direct,589 .m[PSC_CURRENT_OUT] = 153,590 .b[PSC_CURRENT_OUT] = 4976,591 .R[PSC_CURRENT_OUT] = -1,592 593 .format[PSC_VOLTAGE_OUT] = linear,594 595 .func[0] = PMBUS_HAVE_VIN |596 PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |597 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |598 PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |599 PMBUS_HAVE_STATUS_INPUT,600 },601 [max20734] = {602 .pages = 1,603 .read_word_data = max20730_read_word_data,604 .write_word_data = max20730_write_word_data,605 606 /* Source : Maxim AN6209 */607 .format[PSC_TEMPERATURE] = direct,608 .m[PSC_TEMPERATURE] = 21,609 .b[PSC_TEMPERATURE] = 5887,610 .R[PSC_TEMPERATURE] = -1,611 612 .format[PSC_VOLTAGE_IN] = direct,613 .m[PSC_VOLTAGE_IN] = 3592,614 .b[PSC_VOLTAGE_IN] = 0,615 .R[PSC_VOLTAGE_IN] = -2,616 617 .format[PSC_CURRENT_OUT] = direct,618 .m[PSC_CURRENT_OUT] = 111,619 .b[PSC_CURRENT_OUT] = 3461,620 .R[PSC_CURRENT_OUT] = -1,621 622 .format[PSC_VOLTAGE_OUT] = linear,623 624 .func[0] = PMBUS_HAVE_VIN |625 PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |626 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |627 PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |628 PMBUS_HAVE_STATUS_INPUT,629 },630 [max20743] = {631 .pages = 1,632 .read_word_data = max20730_read_word_data,633 .write_word_data = max20730_write_word_data,634 635 /* Source : Maxim AN6042 */636 .format[PSC_TEMPERATURE] = direct,637 .m[PSC_TEMPERATURE] = 21,638 .b[PSC_TEMPERATURE] = 5887,639 .R[PSC_TEMPERATURE] = -1,640 641 .format[PSC_VOLTAGE_IN] = direct,642 .m[PSC_VOLTAGE_IN] = 3597,643 .b[PSC_VOLTAGE_IN] = 0,644 .R[PSC_VOLTAGE_IN] = -2,645 646 .format[PSC_CURRENT_OUT] = direct,647 .m[PSC_CURRENT_OUT] = 95,648 .b[PSC_CURRENT_OUT] = 5014,649 .R[PSC_CURRENT_OUT] = -1,650 651 .format[PSC_VOLTAGE_OUT] = linear,652 653 .func[0] = PMBUS_HAVE_VIN |654 PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |655 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |656 PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |657 PMBUS_HAVE_STATUS_INPUT,658 },659};660 661static int max20730_probe(struct i2c_client *client)662{663 struct device *dev = &client->dev;664 u8 buf[I2C_SMBUS_BLOCK_MAX + 1];665 struct max20730_data *data;666 enum chips chip_id;667 int ret;668 669 if (!i2c_check_functionality(client->adapter,670 I2C_FUNC_SMBUS_READ_BYTE_DATA |671 I2C_FUNC_SMBUS_READ_WORD_DATA |672 I2C_FUNC_SMBUS_BLOCK_DATA))673 return -ENODEV;674 675 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf);676 if (ret < 0) {677 dev_err(&client->dev, "Failed to read Manufacturer ID\n");678 return ret;679 }680 if (ret != 5 || strncmp(buf, "MAXIM", 5)) {681 buf[ret] = '\0';682 dev_err(dev, "Unsupported Manufacturer ID '%s'\n", buf);683 return -ENODEV;684 }685 686 /*687 * The chips support reading PMBUS_MFR_MODEL. On both MAX20730688 * and MAX20734, reading it returns M20743. Presumably that is689 * the reason why the command is not documented. Unfortunately,690 * that means that there is no reliable means to detect the chip.691 * However, we can at least detect the chip series. Compare692 * the returned value against 'M20743' and bail out if there is693 * a mismatch. If that doesn't work for all chips, we may have694 * to remove this check.695 */696 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);697 if (ret < 0) {698 dev_err(dev, "Failed to read Manufacturer Model\n");699 return ret;700 }701 if (ret != 6 || strncmp(buf, "M20743", 6)) {702 buf[ret] = '\0';703 dev_err(dev, "Unsupported Manufacturer Model '%s'\n", buf);704 return -ENODEV;705 }706 707 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_REVISION, buf);708 if (ret < 0) {709 dev_err(dev, "Failed to read Manufacturer Revision\n");710 return ret;711 }712 if (ret != 1 || buf[0] != 'F') {713 buf[ret] = '\0';714 dev_err(dev, "Unsupported Manufacturer Revision '%s'\n", buf);715 return -ENODEV;716 }717 718 if (client->dev.of_node)719 chip_id = (uintptr_t)of_device_get_match_data(dev);720 else721 chip_id = i2c_match_id(max20730_id, client)->driver_data;722 723 data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);724 if (!data)725 return -ENOMEM;726 data->id = chip_id;727 mutex_init(&data->lock);728 memcpy(&data->info, &max20730_info[chip_id], sizeof(data->info));729 if (of_property_read_u32_array(client->dev.of_node, "vout-voltage-divider",730 data->vout_voltage_divider,731 ARRAY_SIZE(data->vout_voltage_divider)) != 0)732 memset(data->vout_voltage_divider, 0, sizeof(data->vout_voltage_divider));733 if (data->vout_voltage_divider[1] < data->vout_voltage_divider[0]) {734 dev_err(dev,735 "The total resistance of voltage divider is less than output resistance\n");736 return -EINVAL;737 }738 739 ret = i2c_smbus_read_word_data(client, MAX20730_MFR_DEVSET1);740 if (ret < 0)741 return ret;742 data->mfr_devset1 = ret;743 744 ret = pmbus_do_probe(client, &data->info);745 if (ret < 0)746 return ret;747 748 ret = max20730_init_debugfs(client, data);749 if (ret)750 dev_warn(dev, "Failed to register debugfs: %d\n",751 ret);752 753 return 0;754}755 756static const struct i2c_device_id max20730_id[] = {757 { "max20710", max20710 },758 { "max20730", max20730 },759 { "max20734", max20734 },760 { "max20743", max20743 },761 { },762};763 764MODULE_DEVICE_TABLE(i2c, max20730_id);765 766static const struct of_device_id max20730_of_match[] = {767 { .compatible = "maxim,max20710", .data = (void *)max20710 },768 { .compatible = "maxim,max20730", .data = (void *)max20730 },769 { .compatible = "maxim,max20734", .data = (void *)max20734 },770 { .compatible = "maxim,max20743", .data = (void *)max20743 },771 { },772};773 774MODULE_DEVICE_TABLE(of, max20730_of_match);775 776static struct i2c_driver max20730_driver = {777 .driver = {778 .name = "max20730",779 .of_match_table = max20730_of_match,780 },781 .probe = max20730_probe,782 .id_table = max20730_id,783};784 785module_i2c_driver(max20730_driver);786 787MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");788MODULE_DESCRIPTION("PMBus driver for Maxim MAX20710 / MAX20730 / MAX20734 / MAX20743");789MODULE_LICENSE("GPL");790MODULE_IMPORT_NS(PMBUS);791