1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Hardware monitoring driver for Texas Instruments TPS53679 4 * 5 * Copyright (c) 2017 Mellanox Technologies. All rights reserved. 6 * Copyright (c) 2017 Vadim Pasternak <vadimp@mellanox.com> 7 */ 8 9 #include <linux/bits.h> 10 #include <linux/err.h> 11 #include <linux/i2c.h> 12 #include <linux/init.h> 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/of_device.h> 16 #include "pmbus.h" 17 18 enum chips { 19 tps53647, tps53667, tps53679, tps53681, tps53688 20 }; 21 22 #define TPS53647_PAGE_NUM 1 23 24 #define TPS53679_PROT_VR12_5MV 0x01 /* VR12.0 mode, 5-mV DAC */ 25 #define TPS53679_PROT_VR12_5_10MV 0x02 /* VR12.5 mode, 10-mV DAC */ 26 #define TPS53679_PROT_VR13_10MV 0x04 /* VR13.0 mode, 10-mV DAC */ 27 #define TPS53679_PROT_IMVP8_5MV 0x05 /* IMVP8 mode, 5-mV DAC */ 28 #define TPS53679_PROT_VR13_5MV 0x07 /* VR13.0 mode, 5-mV DAC */ 29 #define TPS53679_PAGE_NUM 2 30 31 #define TPS53681_DEVICE_ID 0x81 32 33 #define TPS53681_PMBUS_REVISION 0x33 34 35 #define TPS53681_MFR_SPECIFIC_20 0xe4 /* Number of phases, per page */ 36 37 static int tps53679_identify_mode(struct i2c_client *client, 38 struct pmbus_driver_info *info) 39 { 40 u8 vout_params; 41 int i, ret; 42 43 for (i = 0; i < info->pages; i++) { 44 /* Read the register with VOUT scaling value.*/ 45 ret = pmbus_read_byte_data(client, i, PMBUS_VOUT_MODE); 46 if (ret < 0) 47 return ret; 48 49 vout_params = ret & GENMASK(4, 0); 50 51 switch (vout_params) { 52 case TPS53679_PROT_VR13_10MV: 53 case TPS53679_PROT_VR12_5_10MV: 54 info->vrm_version[i] = vr13; 55 break; 56 case TPS53679_PROT_VR13_5MV: 57 case TPS53679_PROT_VR12_5MV: 58 case TPS53679_PROT_IMVP8_5MV: 59 info->vrm_version[i] = vr12; 60 break; 61 default: 62 return -EINVAL; 63 } 64 } 65 66 return 0; 67 } 68 69 static int tps53679_identify_phases(struct i2c_client *client, 70 struct pmbus_driver_info *info) 71 { 72 int ret; 73 74 /* On TPS53681, only channel A provides per-phase output current */ 75 ret = pmbus_read_byte_data(client, 0, TPS53681_MFR_SPECIFIC_20); 76 if (ret < 0) 77 return ret; 78 info->phases[0] = (ret & 0x07) + 1; 79 80 return 0; 81 } 82 83 static int tps53679_identify_chip(struct i2c_client *client, 84 u8 revision, u16 id) 85 { 86 u8 buf[I2C_SMBUS_BLOCK_MAX]; 87 int ret; 88 89 ret = pmbus_read_byte_data(client, 0, PMBUS_REVISION); 90 if (ret < 0) 91 return ret; 92 if (ret != revision) { 93 dev_err(&client->dev, "Unexpected PMBus revision 0x%x\n", ret); 94 return -ENODEV; 95 } 96 97 ret = i2c_smbus_read_block_data(client, PMBUS_IC_DEVICE_ID, buf); 98 if (ret < 0) 99 return ret; 100 if (ret != 1 || buf[0] != id) { 101 dev_err(&client->dev, "Unexpected device ID 0x%x\n", buf[0]); 102 return -ENODEV; 103 } 104 return 0; 105 } 106 107 /* 108 * Common identification function for chips with multi-phase support. 109 * Since those chips have special configuration registers, we want to have 110 * some level of reassurance that we are really talking with the chip 111 * being probed. Check PMBus revision and chip ID. 112 */ 113 static int tps53679_identify_multiphase(struct i2c_client *client, 114 struct pmbus_driver_info *info, 115 int pmbus_rev, int device_id) 116 { 117 int ret; 118 119 ret = tps53679_identify_chip(client, pmbus_rev, device_id); 120 if (ret < 0) 121 return ret; 122 123 ret = tps53679_identify_mode(client, info); 124 if (ret < 0) 125 return ret; 126 127 return tps53679_identify_phases(client, info); 128 } 129 130 static int tps53679_identify(struct i2c_client *client, 131 struct pmbus_driver_info *info) 132 { 133 return tps53679_identify_mode(client, info); 134 } 135 136 static int tps53681_identify(struct i2c_client *client, 137 struct pmbus_driver_info *info) 138 { 139 return tps53679_identify_multiphase(client, info, 140 TPS53681_PMBUS_REVISION, 141 TPS53681_DEVICE_ID); 142 } 143 144 static int tps53681_read_word_data(struct i2c_client *client, int page, 145 int phase, int reg) 146 { 147 /* 148 * For reading the total output current (READ_IOUT) for all phases, 149 * the chip datasheet is a bit vague. It says "PHASE must be set to 150 * FFh to access all phases simultaneously. PHASE may also be set to 151 * 80h readack (!) the total phase current". 152 * Experiments show that the command does _not_ report the total 153 * current for all phases if the phase is set to 0xff. Instead, it 154 * appears to report the current of one of the phases. Override phase 155 * parameter with 0x80 when reading the total output current on page 0. 156 */ 157 if (reg == PMBUS_READ_IOUT && page == 0 && phase == 0xff) 158 return pmbus_read_word_data(client, page, 0x80, reg); 159 return -ENODATA; 160 } 161 162 static struct pmbus_driver_info tps53679_info = { 163 .format[PSC_VOLTAGE_IN] = linear, 164 .format[PSC_VOLTAGE_OUT] = vid, 165 .format[PSC_TEMPERATURE] = linear, 166 .format[PSC_CURRENT_OUT] = linear, 167 .format[PSC_POWER] = linear, 168 .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | PMBUS_HAVE_PIN | 169 PMBUS_HAVE_STATUS_INPUT | 170 PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 171 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 172 PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | 173 PMBUS_HAVE_POUT, 174 .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | 175 PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | 176 PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP | 177 PMBUS_HAVE_POUT, 178 .pfunc[0] = PMBUS_HAVE_IOUT, 179 .pfunc[1] = PMBUS_HAVE_IOUT, 180 .pfunc[2] = PMBUS_HAVE_IOUT, 181 .pfunc[3] = PMBUS_HAVE_IOUT, 182 .pfunc[4] = PMBUS_HAVE_IOUT, 183 .pfunc[5] = PMBUS_HAVE_IOUT, 184 }; 185 186 static int tps53679_probe(struct i2c_client *client, 187 const struct i2c_device_id *id) 188 { 189 struct device *dev = &client->dev; 190 struct pmbus_driver_info *info; 191 enum chips chip_id; 192 193 if (dev->of_node) 194 chip_id = (enum chips)of_device_get_match_data(dev); 195 else 196 chip_id = id->driver_data; 197 198 info = devm_kmemdup(dev, &tps53679_info, sizeof(*info), GFP_KERNEL); 199 if (!info) 200 return -ENOMEM; 201 202 switch (chip_id) { 203 case tps53647: 204 case tps53667: 205 info->pages = TPS53647_PAGE_NUM; 206 info->identify = tps53679_identify; 207 break; 208 case tps53679: 209 case tps53688: 210 info->pages = TPS53679_PAGE_NUM; 211 info->identify = tps53679_identify; 212 break; 213 case tps53681: 214 info->pages = TPS53679_PAGE_NUM; 215 info->phases[0] = 6; 216 info->identify = tps53681_identify; 217 info->read_word_data = tps53681_read_word_data; 218 break; 219 default: 220 return -ENODEV; 221 } 222 223 return pmbus_do_probe(client, id, info); 224 } 225 226 static const struct i2c_device_id tps53679_id[] = { 227 {"tps53647", tps53647}, 228 {"tps53667", tps53667}, 229 {"tps53679", tps53679}, 230 {"tps53681", tps53681}, 231 {"tps53688", tps53688}, 232 {} 233 }; 234 235 MODULE_DEVICE_TABLE(i2c, tps53679_id); 236 237 static const struct of_device_id __maybe_unused tps53679_of_match[] = { 238 {.compatible = "ti,tps53647", .data = (void *)tps53647}, 239 {.compatible = "ti,tps53667", .data = (void *)tps53667}, 240 {.compatible = "ti,tps53679", .data = (void *)tps53679}, 241 {.compatible = "ti,tps53681", .data = (void *)tps53681}, 242 {.compatible = "ti,tps53688", .data = (void *)tps53688}, 243 {} 244 }; 245 MODULE_DEVICE_TABLE(of, tps53679_of_match); 246 247 static struct i2c_driver tps53679_driver = { 248 .driver = { 249 .name = "tps53679", 250 .of_match_table = of_match_ptr(tps53679_of_match), 251 }, 252 .probe = tps53679_probe, 253 .remove = pmbus_do_remove, 254 .id_table = tps53679_id, 255 }; 256 257 module_i2c_driver(tps53679_driver); 258 259 MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>"); 260 MODULE_DESCRIPTION("PMBus driver for Texas Instruments TPS53679"); 261 MODULE_LICENSE("GPL"); 262