1*93ab13d8SZiming Zhu // SPDX-License-Identifier: GPL-2.0 2*93ab13d8SZiming Zhu /* 3*93ab13d8SZiming Zhu * Author: Ziming Zhu <ziming.zhu@silergycorp.com> 4*93ab13d8SZiming Zhu */ 5*93ab13d8SZiming Zhu 6*93ab13d8SZiming Zhu #include <linux/bitfield.h> 7*93ab13d8SZiming Zhu #include <linux/err.h> 8*93ab13d8SZiming Zhu #include <linux/i2c.h> 9*93ab13d8SZiming Zhu #include <linux/init.h> 10*93ab13d8SZiming Zhu #include <linux/kernel.h> 11*93ab13d8SZiming Zhu #include <linux/module.h> 12*93ab13d8SZiming Zhu #include <linux/math64.h> 13*93ab13d8SZiming Zhu 14*93ab13d8SZiming Zhu #include "pmbus.h" 15*93ab13d8SZiming Zhu 16*93ab13d8SZiming Zhu #define SQ24860_IIN_CAL_GAIN 0x38 17*93ab13d8SZiming Zhu #define SQ24860_READ_VAUX 0xd0 18*93ab13d8SZiming Zhu #define SQ24860_READ_VIN_MIN 0xd1 19*93ab13d8SZiming Zhu #define SQ24860_READ_VIN_PEAK 0xd2 20*93ab13d8SZiming Zhu #define SQ24860_READ_IIN_PEAK 0xd4 21*93ab13d8SZiming Zhu #define SQ24860_READ_PIN_PEAK 0xd5 22*93ab13d8SZiming Zhu #define SQ24860_READ_TEMP_AVG 0xd6 23*93ab13d8SZiming Zhu #define SQ24860_READ_TEMP_PEAK 0xd7 24*93ab13d8SZiming Zhu #define SQ24860_READ_VOUT_MIN 0xda 25*93ab13d8SZiming Zhu #define SQ24860_READ_VIN_AVG 0xdc 26*93ab13d8SZiming Zhu #define SQ24860_READ_VOUT_AVG 0xdd 27*93ab13d8SZiming Zhu #define SQ24860_READ_IIN_AVG 0xde 28*93ab13d8SZiming Zhu #define SQ24860_READ_PIN_AVG 0xdf 29*93ab13d8SZiming Zhu #define SQ24860_VIREF 0xe0 30*93ab13d8SZiming Zhu #define SQ24860_PK_MIN_AVG 0xea 31*93ab13d8SZiming Zhu #define PK_MIN_AVG_RST_PEAK BIT(7) 32*93ab13d8SZiming Zhu #define PK_MIN_AVG_RST_AVG BIT(6) 33*93ab13d8SZiming Zhu #define PK_MIN_AVG_RST_MIN BIT(5) 34*93ab13d8SZiming Zhu #define PK_MIN_AVG_AVG_CNT GENMASK(2, 0) 35*93ab13d8SZiming Zhu #define SQ24860_MFR_WRITE_PROTECT 0xf8 36*93ab13d8SZiming Zhu #define SQ24860_UNLOCKED BIT(7) 37*93ab13d8SZiming Zhu 38*93ab13d8SZiming Zhu #define SQ24860_8B_SHIFT 2 39*93ab13d8SZiming Zhu #define SQ24860_IIN_OCF_NUM 1000000 40*93ab13d8SZiming Zhu #define SQ24860_IIN_OCF_DIV 129278 41*93ab13d8SZiming Zhu #define SQ24860_IIN_OCF_OFF 165 42*93ab13d8SZiming Zhu 43*93ab13d8SZiming Zhu #define PK_MIN_AVG_RST_MASK (PK_MIN_AVG_RST_PEAK | \ 44*93ab13d8SZiming Zhu PK_MIN_AVG_RST_AVG | \ 45*93ab13d8SZiming Zhu PK_MIN_AVG_RST_MIN) 46*93ab13d8SZiming Zhu #define SQ24860_MAX_SAMPLES BIT(FIELD_MAX(PK_MIN_AVG_AVG_CNT)) 47*93ab13d8SZiming Zhu /* 48*93ab13d8SZiming Zhu * Arbitrary default Rimon value: 1.6kOhm 49*93ab13d8SZiming Zhu */ 50*93ab13d8SZiming Zhu #define SQ24860_DEFAULT_RIMON 1600000000 51*93ab13d8SZiming Zhu #define SQ24860_GIMON 18180 52*93ab13d8SZiming Zhu 53*93ab13d8SZiming Zhu #define SQ24860_VAUX_DIV 20 54*93ab13d8SZiming Zhu 55*93ab13d8SZiming Zhu static int sq24860_write_iin_cal_gain(struct i2c_client *client, u32 rimon) 56*93ab13d8SZiming Zhu { 57*93ab13d8SZiming Zhu u64 temp = 6400ULL * 1000000000ULL * 1000ULL; 58*93ab13d8SZiming Zhu u64 denom; 59*93ab13d8SZiming Zhu u64 word; 60*93ab13d8SZiming Zhu 61*93ab13d8SZiming Zhu if (!rimon) 62*93ab13d8SZiming Zhu return -EINVAL; 63*93ab13d8SZiming Zhu 64*93ab13d8SZiming Zhu denom = (u64)rimon * SQ24860_GIMON; 65*93ab13d8SZiming Zhu word = div64_u64(temp, denom); 66*93ab13d8SZiming Zhu if (!word || word > U16_MAX) 67*93ab13d8SZiming Zhu return -EINVAL; 68*93ab13d8SZiming Zhu 69*93ab13d8SZiming Zhu return i2c_smbus_write_word_data(client, SQ24860_IIN_CAL_GAIN, 70*93ab13d8SZiming Zhu (u16)word); 71*93ab13d8SZiming Zhu } 72*93ab13d8SZiming Zhu 73*93ab13d8SZiming Zhu static int sq24860_mfr_write_protect_set(struct i2c_client *client, 74*93ab13d8SZiming Zhu u8 protect) 75*93ab13d8SZiming Zhu { 76*93ab13d8SZiming Zhu u8 val; 77*93ab13d8SZiming Zhu 78*93ab13d8SZiming Zhu switch (protect) { 79*93ab13d8SZiming Zhu case 0: 80*93ab13d8SZiming Zhu val = 0xa2; 81*93ab13d8SZiming Zhu break; 82*93ab13d8SZiming Zhu case PB_WP_ALL: 83*93ab13d8SZiming Zhu val = 0x0; 84*93ab13d8SZiming Zhu break; 85*93ab13d8SZiming Zhu default: 86*93ab13d8SZiming Zhu return -EINVAL; 87*93ab13d8SZiming Zhu } 88*93ab13d8SZiming Zhu 89*93ab13d8SZiming Zhu return pmbus_write_byte_data(client, -1, SQ24860_MFR_WRITE_PROTECT, 90*93ab13d8SZiming Zhu val); 91*93ab13d8SZiming Zhu } 92*93ab13d8SZiming Zhu 93*93ab13d8SZiming Zhu static int sq24860_mfr_write_protect_get(struct i2c_client *client) 94*93ab13d8SZiming Zhu { 95*93ab13d8SZiming Zhu int ret = pmbus_read_byte_data(client, -1, SQ24860_MFR_WRITE_PROTECT); 96*93ab13d8SZiming Zhu 97*93ab13d8SZiming Zhu if (ret < 0) 98*93ab13d8SZiming Zhu return ret; 99*93ab13d8SZiming Zhu 100*93ab13d8SZiming Zhu return (ret & SQ24860_UNLOCKED) ? 0 : PB_WP_ALL; 101*93ab13d8SZiming Zhu } 102*93ab13d8SZiming Zhu 103*93ab13d8SZiming Zhu static int sq24860_read_word_data(struct i2c_client *client, 104*93ab13d8SZiming Zhu int page, int phase, int reg) 105*93ab13d8SZiming Zhu { 106*93ab13d8SZiming Zhu int ret; 107*93ab13d8SZiming Zhu 108*93ab13d8SZiming Zhu switch (reg) { 109*93ab13d8SZiming Zhu case PMBUS_VIRT_READ_VIN_MAX: 110*93ab13d8SZiming Zhu ret = pmbus_read_word_data(client, page, phase, 111*93ab13d8SZiming Zhu SQ24860_READ_VIN_PEAK); 112*93ab13d8SZiming Zhu break; 113*93ab13d8SZiming Zhu 114*93ab13d8SZiming Zhu case PMBUS_VIRT_READ_VIN_MIN: 115*93ab13d8SZiming Zhu ret = pmbus_read_word_data(client, page, phase, 116*93ab13d8SZiming Zhu SQ24860_READ_VIN_MIN); 117*93ab13d8SZiming Zhu break; 118*93ab13d8SZiming Zhu 119*93ab13d8SZiming Zhu case PMBUS_VIRT_READ_VIN_AVG: 120*93ab13d8SZiming Zhu ret = pmbus_read_word_data(client, page, phase, 121*93ab13d8SZiming Zhu SQ24860_READ_VIN_AVG); 122*93ab13d8SZiming Zhu break; 123*93ab13d8SZiming Zhu 124*93ab13d8SZiming Zhu case PMBUS_VIRT_READ_VOUT_MIN: 125*93ab13d8SZiming Zhu ret = pmbus_read_word_data(client, page, phase, 126*93ab13d8SZiming Zhu SQ24860_READ_VOUT_MIN); 127*93ab13d8SZiming Zhu break; 128*93ab13d8SZiming Zhu 129*93ab13d8SZiming Zhu case PMBUS_VIRT_READ_VOUT_AVG: 130*93ab13d8SZiming Zhu ret = pmbus_read_word_data(client, page, phase, 131*93ab13d8SZiming Zhu SQ24860_READ_VOUT_AVG); 132*93ab13d8SZiming Zhu break; 133*93ab13d8SZiming Zhu 134*93ab13d8SZiming Zhu case PMBUS_VIRT_READ_IIN_AVG: 135*93ab13d8SZiming Zhu ret = pmbus_read_word_data(client, page, phase, 136*93ab13d8SZiming Zhu SQ24860_READ_IIN_AVG); 137*93ab13d8SZiming Zhu break; 138*93ab13d8SZiming Zhu 139*93ab13d8SZiming Zhu case PMBUS_VIRT_READ_IIN_MAX: 140*93ab13d8SZiming Zhu ret = pmbus_read_word_data(client, page, phase, 141*93ab13d8SZiming Zhu SQ24860_READ_IIN_PEAK); 142*93ab13d8SZiming Zhu break; 143*93ab13d8SZiming Zhu 144*93ab13d8SZiming Zhu case PMBUS_VIRT_READ_TEMP_AVG: 145*93ab13d8SZiming Zhu ret = pmbus_read_word_data(client, page, phase, 146*93ab13d8SZiming Zhu SQ24860_READ_TEMP_AVG); 147*93ab13d8SZiming Zhu break; 148*93ab13d8SZiming Zhu 149*93ab13d8SZiming Zhu case PMBUS_VIRT_READ_TEMP_MAX: 150*93ab13d8SZiming Zhu ret = pmbus_read_word_data(client, page, phase, 151*93ab13d8SZiming Zhu SQ24860_READ_TEMP_PEAK); 152*93ab13d8SZiming Zhu break; 153*93ab13d8SZiming Zhu 154*93ab13d8SZiming Zhu case PMBUS_VIRT_READ_PIN_AVG: 155*93ab13d8SZiming Zhu ret = pmbus_read_word_data(client, page, phase, 156*93ab13d8SZiming Zhu SQ24860_READ_PIN_AVG); 157*93ab13d8SZiming Zhu break; 158*93ab13d8SZiming Zhu 159*93ab13d8SZiming Zhu case PMBUS_VIRT_READ_PIN_MAX: 160*93ab13d8SZiming Zhu ret = pmbus_read_word_data(client, page, phase, 161*93ab13d8SZiming Zhu SQ24860_READ_PIN_PEAK); 162*93ab13d8SZiming Zhu break; 163*93ab13d8SZiming Zhu 164*93ab13d8SZiming Zhu case PMBUS_VIRT_READ_VMON: 165*93ab13d8SZiming Zhu ret = pmbus_read_word_data(client, page, phase, 166*93ab13d8SZiming Zhu SQ24860_READ_VAUX); 167*93ab13d8SZiming Zhu if (ret < 0) 168*93ab13d8SZiming Zhu break; 169*93ab13d8SZiming Zhu ret = DIV_ROUND_CLOSEST(ret, SQ24860_VAUX_DIV); 170*93ab13d8SZiming Zhu break; 171*93ab13d8SZiming Zhu 172*93ab13d8SZiming Zhu case PMBUS_VIN_UV_WARN_LIMIT: 173*93ab13d8SZiming Zhu case PMBUS_VIN_UV_FAULT_LIMIT: 174*93ab13d8SZiming Zhu case PMBUS_VIN_OV_WARN_LIMIT: 175*93ab13d8SZiming Zhu case PMBUS_VIN_OV_FAULT_LIMIT: 176*93ab13d8SZiming Zhu case PMBUS_VOUT_UV_WARN_LIMIT: 177*93ab13d8SZiming Zhu case PMBUS_IIN_OC_WARN_LIMIT: 178*93ab13d8SZiming Zhu case PMBUS_OT_WARN_LIMIT: 179*93ab13d8SZiming Zhu case PMBUS_OT_FAULT_LIMIT: 180*93ab13d8SZiming Zhu case PMBUS_PIN_OP_WARN_LIMIT: 181*93ab13d8SZiming Zhu /* 182*93ab13d8SZiming Zhu * These registers provide an 8 bits value instead of a 183*93ab13d8SZiming Zhu * 10bits one. Just shifting twice the register value is 184*93ab13d8SZiming Zhu * enough to make the sensor type conversion work, even 185*93ab13d8SZiming Zhu * if the datasheet provides different m, b and R for 186*93ab13d8SZiming Zhu * those. 187*93ab13d8SZiming Zhu */ 188*93ab13d8SZiming Zhu ret = pmbus_read_word_data(client, page, phase, reg); 189*93ab13d8SZiming Zhu if (ret < 0) 190*93ab13d8SZiming Zhu break; 191*93ab13d8SZiming Zhu ret <<= SQ24860_8B_SHIFT; 192*93ab13d8SZiming Zhu break; 193*93ab13d8SZiming Zhu 194*93ab13d8SZiming Zhu case PMBUS_IIN_OC_FAULT_LIMIT: 195*93ab13d8SZiming Zhu /* 196*93ab13d8SZiming Zhu * VIREF directly sets the over-current limit at which the eFuse 197*93ab13d8SZiming Zhu * will turn the FET off and trigger a fault. Expose it through 198*93ab13d8SZiming Zhu * this generic property instead of a manufacturer specific one. 199*93ab13d8SZiming Zhu */ 200*93ab13d8SZiming Zhu ret = pmbus_read_byte_data(client, page, SQ24860_VIREF); 201*93ab13d8SZiming Zhu if (ret < 0) 202*93ab13d8SZiming Zhu break; 203*93ab13d8SZiming Zhu ret = DIV_ROUND_CLOSEST(ret * SQ24860_IIN_OCF_NUM, 204*93ab13d8SZiming Zhu SQ24860_IIN_OCF_DIV); 205*93ab13d8SZiming Zhu ret += SQ24860_IIN_OCF_OFF; 206*93ab13d8SZiming Zhu break; 207*93ab13d8SZiming Zhu 208*93ab13d8SZiming Zhu case PMBUS_VIRT_SAMPLES: 209*93ab13d8SZiming Zhu ret = pmbus_read_byte_data(client, page, SQ24860_PK_MIN_AVG); 210*93ab13d8SZiming Zhu if (ret < 0) 211*93ab13d8SZiming Zhu break; 212*93ab13d8SZiming Zhu ret = BIT(FIELD_GET(PK_MIN_AVG_AVG_CNT, ret)); 213*93ab13d8SZiming Zhu break; 214*93ab13d8SZiming Zhu 215*93ab13d8SZiming Zhu case PMBUS_VIRT_RESET_TEMP_HISTORY: 216*93ab13d8SZiming Zhu case PMBUS_VIRT_RESET_VIN_HISTORY: 217*93ab13d8SZiming Zhu case PMBUS_VIRT_RESET_IIN_HISTORY: 218*93ab13d8SZiming Zhu case PMBUS_VIRT_RESET_PIN_HISTORY: 219*93ab13d8SZiming Zhu case PMBUS_VIRT_RESET_VOUT_HISTORY: 220*93ab13d8SZiming Zhu ret = 0; 221*93ab13d8SZiming Zhu break; 222*93ab13d8SZiming Zhu 223*93ab13d8SZiming Zhu default: 224*93ab13d8SZiming Zhu ret = -ENODATA; 225*93ab13d8SZiming Zhu break; 226*93ab13d8SZiming Zhu } 227*93ab13d8SZiming Zhu 228*93ab13d8SZiming Zhu return ret; 229*93ab13d8SZiming Zhu } 230*93ab13d8SZiming Zhu 231*93ab13d8SZiming Zhu static int sq24860_write_word_data(struct i2c_client *client, 232*93ab13d8SZiming Zhu int page, int reg, u16 value) 233*93ab13d8SZiming Zhu { 234*93ab13d8SZiming Zhu int ret; 235*93ab13d8SZiming Zhu 236*93ab13d8SZiming Zhu switch (reg) { 237*93ab13d8SZiming Zhu case PMBUS_VIN_UV_WARN_LIMIT: 238*93ab13d8SZiming Zhu case PMBUS_VIN_UV_FAULT_LIMIT: 239*93ab13d8SZiming Zhu case PMBUS_VIN_OV_WARN_LIMIT: 240*93ab13d8SZiming Zhu case PMBUS_VIN_OV_FAULT_LIMIT: 241*93ab13d8SZiming Zhu case PMBUS_VOUT_UV_WARN_LIMIT: 242*93ab13d8SZiming Zhu case PMBUS_IIN_OC_WARN_LIMIT: 243*93ab13d8SZiming Zhu case PMBUS_OT_WARN_LIMIT: 244*93ab13d8SZiming Zhu case PMBUS_OT_FAULT_LIMIT: 245*93ab13d8SZiming Zhu case PMBUS_PIN_OP_WARN_LIMIT: 246*93ab13d8SZiming Zhu value = max_t(s16, (s16)value, 0); 247*93ab13d8SZiming Zhu value >>= SQ24860_8B_SHIFT; 248*93ab13d8SZiming Zhu value = clamp_val(value, 0, 0xff); 249*93ab13d8SZiming Zhu ret = pmbus_write_word_data(client, page, reg, value); 250*93ab13d8SZiming Zhu break; 251*93ab13d8SZiming Zhu 252*93ab13d8SZiming Zhu case PMBUS_IIN_OC_FAULT_LIMIT: 253*93ab13d8SZiming Zhu value = max_t(s16, (s16)value, SQ24860_IIN_OCF_OFF); 254*93ab13d8SZiming Zhu value -= SQ24860_IIN_OCF_OFF; 255*93ab13d8SZiming Zhu value = DIV_ROUND_CLOSEST(((unsigned int)value) * SQ24860_IIN_OCF_DIV, 256*93ab13d8SZiming Zhu SQ24860_IIN_OCF_NUM); 257*93ab13d8SZiming Zhu value = clamp_val(value, 0, 0x3f); 258*93ab13d8SZiming Zhu ret = pmbus_write_byte_data(client, page, SQ24860_VIREF, value); 259*93ab13d8SZiming Zhu break; 260*93ab13d8SZiming Zhu 261*93ab13d8SZiming Zhu case PMBUS_VIRT_SAMPLES: 262*93ab13d8SZiming Zhu value = clamp_val(value, 1, SQ24860_MAX_SAMPLES); 263*93ab13d8SZiming Zhu value = ilog2(value); 264*93ab13d8SZiming Zhu ret = pmbus_update_byte_data(client, page, SQ24860_PK_MIN_AVG, 265*93ab13d8SZiming Zhu PK_MIN_AVG_AVG_CNT, 266*93ab13d8SZiming Zhu FIELD_PREP(PK_MIN_AVG_AVG_CNT, value)); 267*93ab13d8SZiming Zhu break; 268*93ab13d8SZiming Zhu 269*93ab13d8SZiming Zhu case PMBUS_VIRT_RESET_TEMP_HISTORY: 270*93ab13d8SZiming Zhu case PMBUS_VIRT_RESET_VIN_HISTORY: 271*93ab13d8SZiming Zhu case PMBUS_VIRT_RESET_IIN_HISTORY: 272*93ab13d8SZiming Zhu case PMBUS_VIRT_RESET_PIN_HISTORY: 273*93ab13d8SZiming Zhu case PMBUS_VIRT_RESET_VOUT_HISTORY: 274*93ab13d8SZiming Zhu /* 275*93ab13d8SZiming Zhu * SQ24860 has history resets based on MIN/AVG/PEAK instead of per 276*93ab13d8SZiming Zhu * sensor type. Exposing this quirk in hwmon is not desirable so 277*93ab13d8SZiming Zhu * reset MIN, AVG and PEAK together. Even is there effectively only 278*93ab13d8SZiming Zhu * one reset, which resets everything, expose the 5 entries so 279*93ab13d8SZiming Zhu * userspace is not required map a sensor type to another to trigger 280*93ab13d8SZiming Zhu * a reset 281*93ab13d8SZiming Zhu */ 282*93ab13d8SZiming Zhu ret = pmbus_update_byte_data(client, 0, SQ24860_PK_MIN_AVG, 283*93ab13d8SZiming Zhu PK_MIN_AVG_RST_MASK, 284*93ab13d8SZiming Zhu PK_MIN_AVG_RST_MASK); 285*93ab13d8SZiming Zhu break; 286*93ab13d8SZiming Zhu 287*93ab13d8SZiming Zhu default: 288*93ab13d8SZiming Zhu ret = -ENODATA; 289*93ab13d8SZiming Zhu break; 290*93ab13d8SZiming Zhu } 291*93ab13d8SZiming Zhu 292*93ab13d8SZiming Zhu return ret; 293*93ab13d8SZiming Zhu } 294*93ab13d8SZiming Zhu 295*93ab13d8SZiming Zhu static int sq24860_read_byte_data(struct i2c_client *client, 296*93ab13d8SZiming Zhu int page, int reg) 297*93ab13d8SZiming Zhu { 298*93ab13d8SZiming Zhu int ret; 299*93ab13d8SZiming Zhu 300*93ab13d8SZiming Zhu switch (reg) { 301*93ab13d8SZiming Zhu case PMBUS_WRITE_PROTECT: 302*93ab13d8SZiming Zhu ret = sq24860_mfr_write_protect_get(client); 303*93ab13d8SZiming Zhu break; 304*93ab13d8SZiming Zhu 305*93ab13d8SZiming Zhu default: 306*93ab13d8SZiming Zhu ret = -ENODATA; 307*93ab13d8SZiming Zhu break; 308*93ab13d8SZiming Zhu } 309*93ab13d8SZiming Zhu 310*93ab13d8SZiming Zhu return ret; 311*93ab13d8SZiming Zhu } 312*93ab13d8SZiming Zhu 313*93ab13d8SZiming Zhu static int sq24860_write_byte_data(struct i2c_client *client, 314*93ab13d8SZiming Zhu int page, int reg, u8 byte) 315*93ab13d8SZiming Zhu { 316*93ab13d8SZiming Zhu int ret; 317*93ab13d8SZiming Zhu 318*93ab13d8SZiming Zhu switch (reg) { 319*93ab13d8SZiming Zhu case PMBUS_WRITE_PROTECT: 320*93ab13d8SZiming Zhu ret = sq24860_mfr_write_protect_set(client, byte); 321*93ab13d8SZiming Zhu break; 322*93ab13d8SZiming Zhu 323*93ab13d8SZiming Zhu default: 324*93ab13d8SZiming Zhu ret = -ENODATA; 325*93ab13d8SZiming Zhu break; 326*93ab13d8SZiming Zhu } 327*93ab13d8SZiming Zhu 328*93ab13d8SZiming Zhu return ret; 329*93ab13d8SZiming Zhu } 330*93ab13d8SZiming Zhu 331*93ab13d8SZiming Zhu #if IS_ENABLED(CONFIG_SENSORS_SQ24860_REGULATOR) 332*93ab13d8SZiming Zhu static const struct regulator_desc sq24860_reg_desc[] = { 333*93ab13d8SZiming Zhu PMBUS_REGULATOR_ONE_NODE("vout"), 334*93ab13d8SZiming Zhu }; 335*93ab13d8SZiming Zhu #endif 336*93ab13d8SZiming Zhu 337*93ab13d8SZiming Zhu static const struct pmbus_driver_info sq24860_base_info = { 338*93ab13d8SZiming Zhu .pages = 1, 339*93ab13d8SZiming Zhu .format[PSC_VOLTAGE_IN] = direct, 340*93ab13d8SZiming Zhu .m[PSC_VOLTAGE_IN] = 64, 341*93ab13d8SZiming Zhu .b[PSC_VOLTAGE_IN] = 0, 342*93ab13d8SZiming Zhu .R[PSC_VOLTAGE_IN] = 0, 343*93ab13d8SZiming Zhu .format[PSC_VOLTAGE_OUT] = direct, 344*93ab13d8SZiming Zhu .m[PSC_VOLTAGE_OUT] = 64, 345*93ab13d8SZiming Zhu .b[PSC_VOLTAGE_OUT] = 0, 346*93ab13d8SZiming Zhu .R[PSC_VOLTAGE_OUT] = 0, 347*93ab13d8SZiming Zhu .format[PSC_TEMPERATURE] = direct, 348*93ab13d8SZiming Zhu .m[PSC_TEMPERATURE] = 1, 349*93ab13d8SZiming Zhu .b[PSC_TEMPERATURE] = 0, 350*93ab13d8SZiming Zhu .R[PSC_TEMPERATURE] = 0, 351*93ab13d8SZiming Zhu /* 352*93ab13d8SZiming Zhu * Current and power measurements depend on the calibration gain 353*93ab13d8SZiming Zhu * programmed from the board-specific IMON resistor value. 354*93ab13d8SZiming Zhu */ 355*93ab13d8SZiming Zhu .format[PSC_CURRENT_IN] = direct, 356*93ab13d8SZiming Zhu .m[PSC_CURRENT_IN] = 16, 357*93ab13d8SZiming Zhu .b[PSC_CURRENT_IN] = 0, 358*93ab13d8SZiming Zhu .R[PSC_CURRENT_IN] = 0, 359*93ab13d8SZiming Zhu .format[PSC_POWER] = direct, 360*93ab13d8SZiming Zhu .m[PSC_POWER] = 2, 361*93ab13d8SZiming Zhu .b[PSC_POWER] = 0, 362*93ab13d8SZiming Zhu .R[PSC_POWER] = 0, 363*93ab13d8SZiming Zhu .func[0] = PMBUS_HAVE_VIN | 364*93ab13d8SZiming Zhu PMBUS_HAVE_VOUT | 365*93ab13d8SZiming Zhu PMBUS_HAVE_VMON | 366*93ab13d8SZiming Zhu PMBUS_HAVE_IIN | 367*93ab13d8SZiming Zhu PMBUS_HAVE_PIN | 368*93ab13d8SZiming Zhu PMBUS_HAVE_TEMP | 369*93ab13d8SZiming Zhu PMBUS_HAVE_STATUS_VOUT | 370*93ab13d8SZiming Zhu PMBUS_HAVE_STATUS_IOUT | 371*93ab13d8SZiming Zhu PMBUS_HAVE_STATUS_INPUT | 372*93ab13d8SZiming Zhu PMBUS_HAVE_STATUS_TEMP | 373*93ab13d8SZiming Zhu PMBUS_HAVE_SAMPLES, 374*93ab13d8SZiming Zhu .read_word_data = sq24860_read_word_data, 375*93ab13d8SZiming Zhu .write_word_data = sq24860_write_word_data, 376*93ab13d8SZiming Zhu .read_byte_data = sq24860_read_byte_data, 377*93ab13d8SZiming Zhu .write_byte_data = sq24860_write_byte_data, 378*93ab13d8SZiming Zhu 379*93ab13d8SZiming Zhu #if IS_ENABLED(CONFIG_SENSORS_SQ24860_REGULATOR) 380*93ab13d8SZiming Zhu .reg_desc = sq24860_reg_desc, 381*93ab13d8SZiming Zhu .num_regulators = ARRAY_SIZE(sq24860_reg_desc), 382*93ab13d8SZiming Zhu #endif 383*93ab13d8SZiming Zhu }; 384*93ab13d8SZiming Zhu 385*93ab13d8SZiming Zhu static const struct i2c_device_id sq24860_i2c_id[] = { 386*93ab13d8SZiming Zhu { "sq24860" }, 387*93ab13d8SZiming Zhu {} 388*93ab13d8SZiming Zhu }; 389*93ab13d8SZiming Zhu MODULE_DEVICE_TABLE(i2c, sq24860_i2c_id); 390*93ab13d8SZiming Zhu 391*93ab13d8SZiming Zhu static const struct of_device_id sq24860_of_match[] = { 392*93ab13d8SZiming Zhu { .compatible = "silergy,sq24860" }, 393*93ab13d8SZiming Zhu {} 394*93ab13d8SZiming Zhu }; 395*93ab13d8SZiming Zhu MODULE_DEVICE_TABLE(of, sq24860_of_match); 396*93ab13d8SZiming Zhu 397*93ab13d8SZiming Zhu static int sq24860_probe(struct i2c_client *client) 398*93ab13d8SZiming Zhu { 399*93ab13d8SZiming Zhu struct device *dev = &client->dev; 400*93ab13d8SZiming Zhu struct pmbus_driver_info *info; 401*93ab13d8SZiming Zhu u32 rimon; 402*93ab13d8SZiming Zhu int ret; 403*93ab13d8SZiming Zhu 404*93ab13d8SZiming Zhu if (device_property_read_u32(dev, "silergy,rimon-micro-ohms", &rimon)) 405*93ab13d8SZiming Zhu rimon = SQ24860_DEFAULT_RIMON; 406*93ab13d8SZiming Zhu ret = sq24860_write_iin_cal_gain(client, rimon); 407*93ab13d8SZiming Zhu if (ret < 0) 408*93ab13d8SZiming Zhu return dev_err_probe(&client->dev, ret, 409*93ab13d8SZiming Zhu "Failed to set gain\n"); 410*93ab13d8SZiming Zhu info = devm_kmemdup(dev, &sq24860_base_info, sizeof(*info), GFP_KERNEL); 411*93ab13d8SZiming Zhu if (!info) 412*93ab13d8SZiming Zhu return -ENOMEM; 413*93ab13d8SZiming Zhu 414*93ab13d8SZiming Zhu return pmbus_do_probe(client, info); 415*93ab13d8SZiming Zhu } 416*93ab13d8SZiming Zhu 417*93ab13d8SZiming Zhu static struct i2c_driver sq24860_driver = { 418*93ab13d8SZiming Zhu .driver = { 419*93ab13d8SZiming Zhu .name = "sq24860", 420*93ab13d8SZiming Zhu .of_match_table = sq24860_of_match, 421*93ab13d8SZiming Zhu }, 422*93ab13d8SZiming Zhu .probe = sq24860_probe, 423*93ab13d8SZiming Zhu .id_table = sq24860_i2c_id, 424*93ab13d8SZiming Zhu }; 425*93ab13d8SZiming Zhu module_i2c_driver(sq24860_driver); 426*93ab13d8SZiming Zhu 427*93ab13d8SZiming Zhu MODULE_AUTHOR("Ziming Zhu <ziming.zhu@silergycorp.com>"); 428*93ab13d8SZiming Zhu MODULE_DESCRIPTION("PMBUS driver for SQ24860 eFuse"); 429*93ab13d8SZiming Zhu MODULE_LICENSE("GPL"); 430*93ab13d8SZiming Zhu MODULE_IMPORT_NS("PMBUS"); 431