1*e656735fSWensheng Wang // SPDX-License-Identifier: GPL-2.0-or-later 2*e656735fSWensheng Wang /* 3*e656735fSWensheng Wang * Hardware monitoring driver for MPS Multi-phase Digital VR Controllers(MP2985) 4*e656735fSWensheng Wang * 5*e656735fSWensheng Wang * Copyright (C) 2026 MPS 6*e656735fSWensheng Wang */ 7*e656735fSWensheng Wang 8*e656735fSWensheng Wang #include <linux/bitfield.h> 9*e656735fSWensheng Wang #include <linux/i2c.h> 10*e656735fSWensheng Wang #include <linux/module.h> 11*e656735fSWensheng Wang #include <linux/of_device.h> 12*e656735fSWensheng Wang #include "pmbus.h" 13*e656735fSWensheng Wang 14*e656735fSWensheng Wang /* 15*e656735fSWensheng Wang * Vender specific register READ_PIN_EST(0x93), READ_IIN_EST(0x8E), 16*e656735fSWensheng Wang * MFR_VR_MULTI_CONFIG_R1(0x0D) and MFR_VR_MULTI_CONFIG_R2(0x1D). 17*e656735fSWensheng Wang * The READ_PIN_EST is used to read pin telemetry, the READ_IIN_EST 18*e656735fSWensheng Wang * is used to read iin telemetry and the MFR_VR_MULTI_CONFIG_R1, 19*e656735fSWensheng Wang * MFR_VR_MULTI_CONFIG_R2 are used to obtain vid scale. 20*e656735fSWensheng Wang */ 21*e656735fSWensheng Wang #define READ_PIN_EST 0x93 22*e656735fSWensheng Wang #define READ_IIN_EST 0x8E 23*e656735fSWensheng Wang #define MFR_VR_MULTI_CONFIG_R1 0x0D 24*e656735fSWensheng Wang #define MFR_VR_MULTI_CONFIG_R2 0x1D 25*e656735fSWensheng Wang 26*e656735fSWensheng Wang #define MP2985_VOUT_DIV 64 27*e656735fSWensheng Wang #define MP2985_VOUT_OVUV_UINT 125 28*e656735fSWensheng Wang #define MP2985_VOUT_OVUV_DIV 64 29*e656735fSWensheng Wang 30*e656735fSWensheng Wang #define MP2985_PAGE_NUM 2 31*e656735fSWensheng Wang 32*e656735fSWensheng Wang #define MP2985_RAIL1_FUNC (PMBUS_HAVE_VIN | PMBUS_HAVE_PIN | \ 33*e656735fSWensheng Wang PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | \ 34*e656735fSWensheng Wang PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | \ 35*e656735fSWensheng Wang PMBUS_HAVE_STATUS_VOUT | \ 36*e656735fSWensheng Wang PMBUS_HAVE_STATUS_IOUT | \ 37*e656735fSWensheng Wang PMBUS_HAVE_STATUS_TEMP | \ 38*e656735fSWensheng Wang PMBUS_HAVE_STATUS_INPUT) 39*e656735fSWensheng Wang 40*e656735fSWensheng Wang #define MP2985_RAIL2_FUNC (PMBUS_HAVE_PIN | PMBUS_HAVE_VOUT | \ 41*e656735fSWensheng Wang PMBUS_HAVE_IOUT | PMBUS_HAVE_POUT | \ 42*e656735fSWensheng Wang PMBUS_HAVE_TEMP | PMBUS_HAVE_IIN | \ 43*e656735fSWensheng Wang PMBUS_HAVE_STATUS_VOUT | \ 44*e656735fSWensheng Wang PMBUS_HAVE_STATUS_IOUT | \ 45*e656735fSWensheng Wang PMBUS_HAVE_STATUS_TEMP | \ 46*e656735fSWensheng Wang PMBUS_HAVE_STATUS_INPUT) 47*e656735fSWensheng Wang 48*e656735fSWensheng Wang struct mp2985_data { 49*e656735fSWensheng Wang struct pmbus_driver_info info; 50*e656735fSWensheng Wang int vout_scale[MP2985_PAGE_NUM]; 51*e656735fSWensheng Wang int vid_offset[MP2985_PAGE_NUM]; 52*e656735fSWensheng Wang }; 53*e656735fSWensheng Wang 54*e656735fSWensheng Wang #define to_mp2985_data(x) container_of(x, struct mp2985_data, info) 55*e656735fSWensheng Wang 56*e656735fSWensheng Wang static u16 mp2985_linear_exp_transfer(u16 word, u16 expect_exponent) 57*e656735fSWensheng Wang { 58*e656735fSWensheng Wang s16 exponent, mantissa, target_exponent; 59*e656735fSWensheng Wang 60*e656735fSWensheng Wang exponent = ((s16)word) >> 11; 61*e656735fSWensheng Wang mantissa = ((s16)((word & 0x7ff) << 5)) >> 5; 62*e656735fSWensheng Wang target_exponent = (s16)((expect_exponent & 0x1f) << 11) >> 11; 63*e656735fSWensheng Wang 64*e656735fSWensheng Wang /* 65*e656735fSWensheng Wang * The MP2985 does not support negtive limit value, if a negtive 66*e656735fSWensheng Wang * limit value is written, the limit value will become to 0. And 67*e656735fSWensheng Wang * the maximum positive limit value is limitted to 0x3FF. 68*e656735fSWensheng Wang */ 69*e656735fSWensheng Wang if (mantissa < 0) { 70*e656735fSWensheng Wang mantissa = 0; 71*e656735fSWensheng Wang } else { 72*e656735fSWensheng Wang if (exponent > target_exponent) { 73*e656735fSWensheng Wang mantissa = (1023 >> (exponent - target_exponent)) >= mantissa ? 74*e656735fSWensheng Wang mantissa << (exponent - target_exponent) : 75*e656735fSWensheng Wang 0x3FF; 76*e656735fSWensheng Wang } else { 77*e656735fSWensheng Wang mantissa = clamp_val(mantissa >> (target_exponent - exponent), 78*e656735fSWensheng Wang 0, 0x3FF); 79*e656735fSWensheng Wang } 80*e656735fSWensheng Wang } 81*e656735fSWensheng Wang 82*e656735fSWensheng Wang return mantissa | ((expect_exponent << 11) & 0xf800); 83*e656735fSWensheng Wang } 84*e656735fSWensheng Wang 85*e656735fSWensheng Wang static int mp2985_read_byte_data(struct i2c_client *client, int page, int reg) 86*e656735fSWensheng Wang { 87*e656735fSWensheng Wang int ret; 88*e656735fSWensheng Wang 89*e656735fSWensheng Wang switch (reg) { 90*e656735fSWensheng Wang case PMBUS_VOUT_MODE: 91*e656735fSWensheng Wang /* 92*e656735fSWensheng Wang * The MP2985 does not follow standard PMBus protocol completely, 93*e656735fSWensheng Wang * and the calculation of vout in this driver is based on direct 94*e656735fSWensheng Wang * format. As a result, the format of vout is enforced to direct. 95*e656735fSWensheng Wang */ 96*e656735fSWensheng Wang ret = PB_VOUT_MODE_DIRECT; 97*e656735fSWensheng Wang break; 98*e656735fSWensheng Wang default: 99*e656735fSWensheng Wang ret = -ENODATA; 100*e656735fSWensheng Wang break; 101*e656735fSWensheng Wang } 102*e656735fSWensheng Wang 103*e656735fSWensheng Wang return ret; 104*e656735fSWensheng Wang } 105*e656735fSWensheng Wang 106*e656735fSWensheng Wang static int mp2985_read_word_data(struct i2c_client *client, int page, int phase, 107*e656735fSWensheng Wang int reg) 108*e656735fSWensheng Wang { 109*e656735fSWensheng Wang const struct pmbus_driver_info *info = pmbus_get_driver_info(client); 110*e656735fSWensheng Wang struct mp2985_data *data = to_mp2985_data(info); 111*e656735fSWensheng Wang int ret; 112*e656735fSWensheng Wang 113*e656735fSWensheng Wang switch (reg) { 114*e656735fSWensheng Wang case PMBUS_READ_VOUT: 115*e656735fSWensheng Wang ret = pmbus_read_word_data(client, page, phase, reg); 116*e656735fSWensheng Wang if (ret < 0) 117*e656735fSWensheng Wang return ret; 118*e656735fSWensheng Wang 119*e656735fSWensheng Wang /* 120*e656735fSWensheng Wang * The MP2985 supports three vout mode, direct, linear11 and vid mode. 121*e656735fSWensheng Wang * In vid mode, the MP2985 vout telemetry has 49 vid step offset, but 122*e656735fSWensheng Wang * PMBUS_VOUT_OV_FAULT_LIMIT and PMBUS_VOUT_UV_FAULT_LIMIT do not take 123*e656735fSWensheng Wang * this into consideration, their resolution are 1.953125mV/LSB, as a 124*e656735fSWensheng Wang * result, format[PSC_VOLTAGE_OUT] can not be set to vid mode directly. 125*e656735fSWensheng Wang * Adding extra vid_offset variable for vout telemetry. 126*e656735fSWensheng Wang */ 127*e656735fSWensheng Wang ret = clamp_val(DIV_ROUND_CLOSEST(((ret & GENMASK(11, 0)) + 128*e656735fSWensheng Wang data->vid_offset[page]) * 129*e656735fSWensheng Wang data->vout_scale[page], MP2985_VOUT_DIV), 130*e656735fSWensheng Wang 0, 0x7FFF); 131*e656735fSWensheng Wang break; 132*e656735fSWensheng Wang case PMBUS_READ_IIN: 133*e656735fSWensheng Wang /* 134*e656735fSWensheng Wang * The MP2985 has standard PMBUS_READ_IIN register(0x89), but this is 135*e656735fSWensheng Wang * not used to read the input current of per rail. The input current 136*e656735fSWensheng Wang * is read through the vender redefined register READ_IIN_EST(0x8E). 137*e656735fSWensheng Wang */ 138*e656735fSWensheng Wang ret = pmbus_read_word_data(client, page, phase, READ_IIN_EST); 139*e656735fSWensheng Wang break; 140*e656735fSWensheng Wang case PMBUS_READ_PIN: 141*e656735fSWensheng Wang /* 142*e656735fSWensheng Wang * The MP2985 has standard PMBUS_READ_PIN register(0x97), but this 143*e656735fSWensheng Wang * is not used to read the input power of per rail. The input power 144*e656735fSWensheng Wang * of per rail is read through the vender redefined register 145*e656735fSWensheng Wang * READ_PIN_EST(0x93). 146*e656735fSWensheng Wang */ 147*e656735fSWensheng Wang ret = pmbus_read_word_data(client, page, phase, READ_PIN_EST); 148*e656735fSWensheng Wang break; 149*e656735fSWensheng Wang case PMBUS_VOUT_OV_FAULT_LIMIT: 150*e656735fSWensheng Wang case PMBUS_VOUT_UV_FAULT_LIMIT: 151*e656735fSWensheng Wang ret = pmbus_read_word_data(client, page, phase, reg); 152*e656735fSWensheng Wang if (ret < 0) 153*e656735fSWensheng Wang return ret; 154*e656735fSWensheng Wang 155*e656735fSWensheng Wang ret = DIV_ROUND_CLOSEST((ret & GENMASK(11, 0)) * MP2985_VOUT_OVUV_UINT, 156*e656735fSWensheng Wang MP2985_VOUT_OVUV_DIV); 157*e656735fSWensheng Wang break; 158*e656735fSWensheng Wang case PMBUS_STATUS_WORD: 159*e656735fSWensheng Wang case PMBUS_READ_VIN: 160*e656735fSWensheng Wang case PMBUS_READ_IOUT: 161*e656735fSWensheng Wang case PMBUS_READ_POUT: 162*e656735fSWensheng Wang case PMBUS_READ_TEMPERATURE_1: 163*e656735fSWensheng Wang case PMBUS_VIN_OV_FAULT_LIMIT: 164*e656735fSWensheng Wang case PMBUS_VIN_OV_WARN_LIMIT: 165*e656735fSWensheng Wang case PMBUS_VIN_UV_WARN_LIMIT: 166*e656735fSWensheng Wang case PMBUS_VIN_UV_FAULT_LIMIT: 167*e656735fSWensheng Wang case PMBUS_IOUT_OC_FAULT_LIMIT: 168*e656735fSWensheng Wang case PMBUS_IOUT_OC_WARN_LIMIT: 169*e656735fSWensheng Wang case PMBUS_OT_FAULT_LIMIT: 170*e656735fSWensheng Wang case PMBUS_OT_WARN_LIMIT: 171*e656735fSWensheng Wang /* 172*e656735fSWensheng Wang * These register is not explicitly handled by the driver, 173*e656735fSWensheng Wang * as a result, return -ENODATA directly. 174*e656735fSWensheng Wang */ 175*e656735fSWensheng Wang ret = -ENODATA; 176*e656735fSWensheng Wang break; 177*e656735fSWensheng Wang default: 178*e656735fSWensheng Wang /* 179*e656735fSWensheng Wang * The MP2985 do not support other telemetry and limit value 180*e656735fSWensheng Wang * reading, so, return -EINVAL directly. 181*e656735fSWensheng Wang */ 182*e656735fSWensheng Wang ret = -EINVAL; 183*e656735fSWensheng Wang break; 184*e656735fSWensheng Wang } 185*e656735fSWensheng Wang 186*e656735fSWensheng Wang return ret; 187*e656735fSWensheng Wang } 188*e656735fSWensheng Wang 189*e656735fSWensheng Wang static int mp2985_write_word_data(struct i2c_client *client, int page, int reg, 190*e656735fSWensheng Wang u16 word) 191*e656735fSWensheng Wang { 192*e656735fSWensheng Wang int ret; 193*e656735fSWensheng Wang 194*e656735fSWensheng Wang switch (reg) { 195*e656735fSWensheng Wang case PMBUS_VIN_OV_FAULT_LIMIT: 196*e656735fSWensheng Wang case PMBUS_VIN_OV_WARN_LIMIT: 197*e656735fSWensheng Wang case PMBUS_VIN_UV_WARN_LIMIT: 198*e656735fSWensheng Wang case PMBUS_VIN_UV_FAULT_LIMIT: 199*e656735fSWensheng Wang /* 200*e656735fSWensheng Wang * The PMBUS_VIN_OV_FAULT_LIMIT, PMBUS_VIN_OV_WARN_LIMIT, 201*e656735fSWensheng Wang * PMBUS_VIN_UV_WARN_LIMIT and PMBUS_VIN_UV_FAULT_LIMIT 202*e656735fSWensheng Wang * of MP2985 is linear11 format, and the exponent is a 203*e656735fSWensheng Wang * constant value(5'b11101), so the exponent of word 204*e656735fSWensheng Wang * parameter should be converted to 5'b11101(0x1D). 205*e656735fSWensheng Wang */ 206*e656735fSWensheng Wang ret = pmbus_write_word_data(client, page, reg, 207*e656735fSWensheng Wang mp2985_linear_exp_transfer(word, 0x1D)); 208*e656735fSWensheng Wang break; 209*e656735fSWensheng Wang case PMBUS_VOUT_OV_FAULT_LIMIT: 210*e656735fSWensheng Wang case PMBUS_VOUT_UV_FAULT_LIMIT: 211*e656735fSWensheng Wang /* 212*e656735fSWensheng Wang * The bit0-bit11 is the limit value, and bit12-bit15 213*e656735fSWensheng Wang * should not be changed. 214*e656735fSWensheng Wang */ 215*e656735fSWensheng Wang ret = pmbus_read_word_data(client, page, 0xff, reg); 216*e656735fSWensheng Wang if (ret < 0) 217*e656735fSWensheng Wang return ret; 218*e656735fSWensheng Wang 219*e656735fSWensheng Wang ret = pmbus_write_word_data(client, page, reg, 220*e656735fSWensheng Wang (ret & ~GENMASK(11, 0)) | 221*e656735fSWensheng Wang clamp_val(DIV_ROUND_CLOSEST(word * MP2985_VOUT_OVUV_DIV, 222*e656735fSWensheng Wang MP2985_VOUT_OVUV_UINT), 0, 0xFFF)); 223*e656735fSWensheng Wang break; 224*e656735fSWensheng Wang case PMBUS_OT_FAULT_LIMIT: 225*e656735fSWensheng Wang case PMBUS_OT_WARN_LIMIT: 226*e656735fSWensheng Wang /* 227*e656735fSWensheng Wang * The PMBUS_OT_FAULT_LIMIT and PMBUS_OT_WARN_LIMIT of 228*e656735fSWensheng Wang * MP2985 is linear11 format, and the exponent is a 229*e656735fSWensheng Wang * constant value(5'b00000), so the exponent of word 230*e656735fSWensheng Wang * parameter should be converted to 5'b00000. 231*e656735fSWensheng Wang */ 232*e656735fSWensheng Wang ret = pmbus_write_word_data(client, page, reg, 233*e656735fSWensheng Wang mp2985_linear_exp_transfer(word, 0x00)); 234*e656735fSWensheng Wang break; 235*e656735fSWensheng Wang case PMBUS_IOUT_OC_FAULT_LIMIT: 236*e656735fSWensheng Wang case PMBUS_IOUT_OC_WARN_LIMIT: 237*e656735fSWensheng Wang /* 238*e656735fSWensheng Wang * The PMBUS_IOUT_OC_FAULT_LIMIT and PMBUS_IOUT_OC_WARN_LIMIT 239*e656735fSWensheng Wang * of MP2985 is linear11 format, and the exponent can not be 240*e656735fSWensheng Wang * changed. 241*e656735fSWensheng Wang */ 242*e656735fSWensheng Wang ret = pmbus_read_word_data(client, page, 0xff, reg); 243*e656735fSWensheng Wang if (ret < 0) 244*e656735fSWensheng Wang return ret; 245*e656735fSWensheng Wang 246*e656735fSWensheng Wang ret = pmbus_write_word_data(client, page, reg, 247*e656735fSWensheng Wang mp2985_linear_exp_transfer(word, 248*e656735fSWensheng Wang FIELD_GET(GENMASK(15, 11), 249*e656735fSWensheng Wang ret))); 250*e656735fSWensheng Wang break; 251*e656735fSWensheng Wang default: 252*e656735fSWensheng Wang /* 253*e656735fSWensheng Wang * The MP2985 do not support other limit value configuration, 254*e656735fSWensheng Wang * so, return -EINVAL directly. 255*e656735fSWensheng Wang */ 256*e656735fSWensheng Wang ret = -EINVAL; 257*e656735fSWensheng Wang break; 258*e656735fSWensheng Wang } 259*e656735fSWensheng Wang 260*e656735fSWensheng Wang return ret; 261*e656735fSWensheng Wang } 262*e656735fSWensheng Wang 263*e656735fSWensheng Wang static int 264*e656735fSWensheng Wang mp2985_identify_vout_scale(struct i2c_client *client, struct pmbus_driver_info *info, 265*e656735fSWensheng Wang int page) 266*e656735fSWensheng Wang { 267*e656735fSWensheng Wang struct mp2985_data *data = to_mp2985_data(info); 268*e656735fSWensheng Wang int ret; 269*e656735fSWensheng Wang 270*e656735fSWensheng Wang ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); 271*e656735fSWensheng Wang if (ret < 0) 272*e656735fSWensheng Wang return ret; 273*e656735fSWensheng Wang 274*e656735fSWensheng Wang ret = i2c_smbus_read_byte_data(client, PMBUS_VOUT_MODE); 275*e656735fSWensheng Wang if (ret < 0) 276*e656735fSWensheng Wang return ret; 277*e656735fSWensheng Wang 278*e656735fSWensheng Wang /* 279*e656735fSWensheng Wang * The MP2985 supports three vout mode. If PMBUS_VOUT_MODE 280*e656735fSWensheng Wang * bit5 is 1, it is vid mode. If PMBUS PMBUS_VOUT_MODE bit4 281*e656735fSWensheng Wang * is 1, it is linear11 mode, the vout scale is 1.953125mv/LSB. 282*e656735fSWensheng Wang * If PMBUS PMBUS_VOUT_MODE bit6 is 1, it is direct mode, the 283*e656735fSWensheng Wang * vout scale is 1mv/LSB. In vid mode, the MP2985 vout telemetry 284*e656735fSWensheng Wang * has 49 vid step offset. 285*e656735fSWensheng Wang */ 286*e656735fSWensheng Wang if (FIELD_GET(BIT(5), ret)) { 287*e656735fSWensheng Wang ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 2); 288*e656735fSWensheng Wang if (ret < 0) 289*e656735fSWensheng Wang return ret; 290*e656735fSWensheng Wang 291*e656735fSWensheng Wang ret = i2c_smbus_read_word_data(client, page == 0 ? 292*e656735fSWensheng Wang MFR_VR_MULTI_CONFIG_R1 : 293*e656735fSWensheng Wang MFR_VR_MULTI_CONFIG_R2); 294*e656735fSWensheng Wang if (ret < 0) 295*e656735fSWensheng Wang return ret; 296*e656735fSWensheng Wang 297*e656735fSWensheng Wang if (page == 0) { 298*e656735fSWensheng Wang if (FIELD_GET(BIT(4), ret)) 299*e656735fSWensheng Wang data->vout_scale[page] = 320; 300*e656735fSWensheng Wang else 301*e656735fSWensheng Wang data->vout_scale[page] = 640; 302*e656735fSWensheng Wang } else { 303*e656735fSWensheng Wang if (FIELD_GET(BIT(3), ret)) 304*e656735fSWensheng Wang data->vout_scale[page] = 320; 305*e656735fSWensheng Wang else 306*e656735fSWensheng Wang data->vout_scale[page] = 640; 307*e656735fSWensheng Wang } 308*e656735fSWensheng Wang 309*e656735fSWensheng Wang data->vid_offset[page] = 49; 310*e656735fSWensheng Wang 311*e656735fSWensheng Wang /* 312*e656735fSWensheng Wang * For vid mode, the MP2985 should be changed to page 2 313*e656735fSWensheng Wang * to obtain vout scale value, this may confuse the PMBus 314*e656735fSWensheng Wang * core. To avoid this, switch back to the previous page 315*e656735fSWensheng Wang * again. 316*e656735fSWensheng Wang */ 317*e656735fSWensheng Wang ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); 318*e656735fSWensheng Wang if (ret < 0) 319*e656735fSWensheng Wang return ret; 320*e656735fSWensheng Wang } else if (FIELD_GET(BIT(4), ret)) { 321*e656735fSWensheng Wang data->vout_scale[page] = 125; 322*e656735fSWensheng Wang data->vid_offset[page] = 0; 323*e656735fSWensheng Wang } else { 324*e656735fSWensheng Wang data->vout_scale[page] = 64; 325*e656735fSWensheng Wang data->vid_offset[page] = 0; 326*e656735fSWensheng Wang } 327*e656735fSWensheng Wang 328*e656735fSWensheng Wang return 0; 329*e656735fSWensheng Wang } 330*e656735fSWensheng Wang 331*e656735fSWensheng Wang static int mp2985_identify(struct i2c_client *client, struct pmbus_driver_info *info) 332*e656735fSWensheng Wang { 333*e656735fSWensheng Wang int ret; 334*e656735fSWensheng Wang 335*e656735fSWensheng Wang ret = mp2985_identify_vout_scale(client, info, 0); 336*e656735fSWensheng Wang if (ret < 0) 337*e656735fSWensheng Wang return ret; 338*e656735fSWensheng Wang 339*e656735fSWensheng Wang return mp2985_identify_vout_scale(client, info, 1); 340*e656735fSWensheng Wang } 341*e656735fSWensheng Wang 342*e656735fSWensheng Wang static struct pmbus_driver_info mp2985_info = { 343*e656735fSWensheng Wang .pages = MP2985_PAGE_NUM, 344*e656735fSWensheng Wang .format[PSC_VOLTAGE_IN] = linear, 345*e656735fSWensheng Wang .format[PSC_CURRENT_IN] = linear, 346*e656735fSWensheng Wang .format[PSC_CURRENT_OUT] = linear, 347*e656735fSWensheng Wang .format[PSC_POWER] = linear, 348*e656735fSWensheng Wang .format[PSC_TEMPERATURE] = linear, 349*e656735fSWensheng Wang .format[PSC_VOLTAGE_OUT] = direct, 350*e656735fSWensheng Wang 351*e656735fSWensheng Wang .m[PSC_VOLTAGE_OUT] = 1, 352*e656735fSWensheng Wang .R[PSC_VOLTAGE_OUT] = 3, 353*e656735fSWensheng Wang .b[PSC_VOLTAGE_OUT] = 0, 354*e656735fSWensheng Wang 355*e656735fSWensheng Wang .func[0] = MP2985_RAIL1_FUNC, 356*e656735fSWensheng Wang .func[1] = MP2985_RAIL2_FUNC, 357*e656735fSWensheng Wang .read_word_data = mp2985_read_word_data, 358*e656735fSWensheng Wang .read_byte_data = mp2985_read_byte_data, 359*e656735fSWensheng Wang .write_word_data = mp2985_write_word_data, 360*e656735fSWensheng Wang .identify = mp2985_identify, 361*e656735fSWensheng Wang }; 362*e656735fSWensheng Wang 363*e656735fSWensheng Wang static int mp2985_probe(struct i2c_client *client) 364*e656735fSWensheng Wang { 365*e656735fSWensheng Wang struct mp2985_data *data; 366*e656735fSWensheng Wang 367*e656735fSWensheng Wang data = devm_kzalloc(&client->dev, sizeof(struct mp2985_data), GFP_KERNEL); 368*e656735fSWensheng Wang if (!data) 369*e656735fSWensheng Wang return -ENOMEM; 370*e656735fSWensheng Wang 371*e656735fSWensheng Wang memcpy(&data->info, &mp2985_info, sizeof(mp2985_info)); 372*e656735fSWensheng Wang 373*e656735fSWensheng Wang return pmbus_do_probe(client, &data->info); 374*e656735fSWensheng Wang } 375*e656735fSWensheng Wang 376*e656735fSWensheng Wang static const struct i2c_device_id mp2985_id[] = { 377*e656735fSWensheng Wang {"mp2985", 0}, 378*e656735fSWensheng Wang {} 379*e656735fSWensheng Wang }; 380*e656735fSWensheng Wang MODULE_DEVICE_TABLE(i2c, mp2985_id); 381*e656735fSWensheng Wang 382*e656735fSWensheng Wang static const struct of_device_id __maybe_unused mp2985_of_match[] = { 383*e656735fSWensheng Wang {.compatible = "mps,mp2985"}, 384*e656735fSWensheng Wang {} 385*e656735fSWensheng Wang }; 386*e656735fSWensheng Wang MODULE_DEVICE_TABLE(of, mp2985_of_match); 387*e656735fSWensheng Wang 388*e656735fSWensheng Wang static struct i2c_driver mp2985_driver = { 389*e656735fSWensheng Wang .driver = { 390*e656735fSWensheng Wang .name = "mp2985", 391*e656735fSWensheng Wang .of_match_table = mp2985_of_match, 392*e656735fSWensheng Wang }, 393*e656735fSWensheng Wang .probe = mp2985_probe, 394*e656735fSWensheng Wang .id_table = mp2985_id, 395*e656735fSWensheng Wang }; 396*e656735fSWensheng Wang 397*e656735fSWensheng Wang module_i2c_driver(mp2985_driver); 398*e656735fSWensheng Wang 399*e656735fSWensheng Wang MODULE_AUTHOR("Wensheng Wang <wenswang@yeah.net>"); 400*e656735fSWensheng Wang MODULE_DESCRIPTION("PMBus driver for MPS MP2985 device"); 401*e656735fSWensheng Wang MODULE_LICENSE("GPL"); 402*e656735fSWensheng Wang MODULE_IMPORT_NS("PMBUS"); 403