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