2 * Hardware monitoring driver for IR35221
4 * Copyright (C) IBM Corporation 2017.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
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>
19 #define IR35221_MFR_VIN_PEAK 0xc5
20 #define IR35221_MFR_VOUT_PEAK 0xc6
21 #define IR35221_MFR_IOUT_PEAK 0xc7
22 #define IR35221_MFR_TEMP_PEAK 0xc8
23 #define IR35221_MFR_VIN_VALLEY 0xc9
24 #define IR35221_MFR_VOUT_VALLEY 0xca
25 #define IR35221_MFR_IOUT_VALLEY 0xcb
26 #define IR35221_MFR_TEMP_VALLEY 0xcc
28 static long ir35221_reg2data(int data, enum pmbus_sensor_classes class)
34 /* We only modify LINEAR11 formats */
35 exponent = ((s16)data) >> 11;
36 mantissa = ((s16)((data & 0x7ff) << 5)) >> 5;
38 val = mantissa * 1000L;
40 /* scale result to micro-units for power sensors */
41 if (class == PSC_POWER)
52 #define MAX_MANTISSA (1023 * 1000)
53 #define MIN_MANTISSA (511 * 1000)
55 static u16 ir35221_data2reg(long val, enum pmbus_sensor_classes class)
57 s16 exponent = 0, mantissa;
58 bool negative = false;
68 /* Power is in uW. Convert to mW before converting. */
69 if (class == PSC_POWER)
70 val = DIV_ROUND_CLOSEST(val, 1000L);
72 /* Reduce large mantissa until it fits into 10 bit */
73 while (val >= MAX_MANTISSA && exponent < 15) {
77 /* Increase small mantissa to improve precision */
78 while (val < MIN_MANTISSA && exponent > -15) {
83 /* Convert mantissa from milli-units to units */
84 mantissa = DIV_ROUND_CLOSEST(val, 1000);
86 /* Ensure that resulting number is within range */
94 /* Convert to 5 bit exponent, 11 bit mantissa */
95 return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800);
98 static u16 ir35221_scale_result(s16 data, int shift,
99 enum pmbus_sensor_classes class)
103 val = ir35221_reg2data(data, class);
110 return ir35221_data2reg(val, class);
113 static int ir35221_read_word_data(struct i2c_client *client, int page, int reg)
118 case PMBUS_IOUT_OC_FAULT_LIMIT:
119 case PMBUS_IOUT_OC_WARN_LIMIT:
120 ret = pmbus_read_word_data(client, page, reg);
123 ret = ir35221_scale_result(ret, 1, PSC_CURRENT_OUT);
125 case PMBUS_VIN_OV_FAULT_LIMIT:
126 case PMBUS_VIN_OV_WARN_LIMIT:
127 case PMBUS_VIN_UV_WARN_LIMIT:
128 ret = pmbus_read_word_data(client, page, reg);
129 ret = ir35221_scale_result(ret, -4, PSC_VOLTAGE_IN);
131 case PMBUS_IIN_OC_WARN_LIMIT:
132 ret = pmbus_read_word_data(client, page, reg);
135 ret = ir35221_scale_result(ret, -1, PSC_CURRENT_IN);
138 ret = pmbus_read_word_data(client, page, PMBUS_READ_VIN);
141 ret = ir35221_scale_result(ret, -5, PSC_VOLTAGE_IN);
144 ret = pmbus_read_word_data(client, page, PMBUS_READ_IIN);
148 ret = ir35221_scale_result(ret, -4, PSC_CURRENT_IN);
150 ret = ir35221_scale_result(ret, -5, PSC_CURRENT_IN);
152 case PMBUS_READ_POUT:
153 ret = pmbus_read_word_data(client, page, PMBUS_READ_POUT);
156 ret = ir35221_scale_result(ret, -1, PSC_POWER);
159 ret = pmbus_read_word_data(client, page, PMBUS_READ_PIN);
162 ret = ir35221_scale_result(ret, -1, PSC_POWER);
164 case PMBUS_READ_IOUT:
165 ret = pmbus_read_word_data(client, page, PMBUS_READ_IOUT);
169 ret = ir35221_scale_result(ret, -1, PSC_CURRENT_OUT);
171 ret = ir35221_scale_result(ret, -2, PSC_CURRENT_OUT);
173 case PMBUS_VIRT_READ_VIN_MAX:
174 ret = pmbus_read_word_data(client, page, IR35221_MFR_VIN_PEAK);
177 ret = ir35221_scale_result(ret, -5, PSC_VOLTAGE_IN);
179 case PMBUS_VIRT_READ_VOUT_MAX:
180 ret = pmbus_read_word_data(client, page, IR35221_MFR_VOUT_PEAK);
182 case PMBUS_VIRT_READ_IOUT_MAX:
183 ret = pmbus_read_word_data(client, page, IR35221_MFR_IOUT_PEAK);
187 ret = ir35221_scale_result(ret, -1, PSC_CURRENT_IN);
189 ret = ir35221_scale_result(ret, -2, PSC_CURRENT_IN);
191 case PMBUS_VIRT_READ_TEMP_MAX:
192 ret = pmbus_read_word_data(client, page, IR35221_MFR_TEMP_PEAK);
194 case PMBUS_VIRT_READ_VIN_MIN:
195 ret = pmbus_read_word_data(client, page,
196 IR35221_MFR_VIN_VALLEY);
199 ret = ir35221_scale_result(ret, -5, PSC_VOLTAGE_IN);
201 case PMBUS_VIRT_READ_VOUT_MIN:
202 ret = pmbus_read_word_data(client, page,
203 IR35221_MFR_VOUT_VALLEY);
205 case PMBUS_VIRT_READ_IOUT_MIN:
206 ret = pmbus_read_word_data(client, page,
207 IR35221_MFR_IOUT_VALLEY);
211 ret = ir35221_scale_result(ret, -1, PSC_CURRENT_IN);
213 ret = ir35221_scale_result(ret, -2, PSC_CURRENT_IN);
215 case PMBUS_VIRT_READ_TEMP_MIN:
216 ret = pmbus_read_word_data(client, page,
217 IR35221_MFR_TEMP_VALLEY);
227 static int ir35221_write_word_data(struct i2c_client *client, int page, int reg,
234 case PMBUS_IOUT_OC_FAULT_LIMIT:
235 case PMBUS_IOUT_OC_WARN_LIMIT:
236 val = ir35221_scale_result(word, -1, PSC_CURRENT_OUT);
237 ret = pmbus_write_word_data(client, page, reg, val);
239 case PMBUS_VIN_OV_FAULT_LIMIT:
240 case PMBUS_VIN_OV_WARN_LIMIT:
241 case PMBUS_VIN_UV_WARN_LIMIT:
242 val = ir35221_scale_result(word, 4, PSC_VOLTAGE_IN);
243 ret = pmbus_write_word_data(client, page, reg, val);
245 case PMBUS_IIN_OC_WARN_LIMIT:
246 val = ir35221_scale_result(word, 1, PSC_CURRENT_IN);
247 ret = pmbus_write_word_data(client, page, reg, val);
257 static int ir35221_probe(struct i2c_client *client,
258 const struct i2c_device_id *id)
260 struct pmbus_driver_info *info;
261 u8 buf[I2C_SMBUS_BLOCK_MAX];
264 if (!i2c_check_functionality(client->adapter,
265 I2C_FUNC_SMBUS_READ_BYTE_DATA
266 | I2C_FUNC_SMBUS_READ_WORD_DATA
267 | I2C_FUNC_SMBUS_READ_BLOCK_DATA))
270 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf);
272 dev_err(&client->dev, "Failed to read PMBUS_MFR_ID\n");
275 if (ret != 2 || strncmp(buf, "RI", strlen("RI"))) {
276 dev_err(&client->dev, "MFR_ID unrecognised\n");
280 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf);
282 dev_err(&client->dev, "Failed to read PMBUS_MFR_MODEL\n");
285 if (ret != 2 || !(buf[0] == 0x6c && buf[1] == 0x00)) {
286 dev_err(&client->dev, "MFR_MODEL unrecognised\n");
290 info = devm_kzalloc(&client->dev, sizeof(struct pmbus_driver_info),
295 info->write_word_data = ir35221_write_word_data;
296 info->read_word_data = ir35221_read_word_data;
299 info->format[PSC_VOLTAGE_IN] = linear;
300 info->format[PSC_VOLTAGE_OUT] = linear;
301 info->format[PSC_CURRENT_IN] = linear;
302 info->format[PSC_CURRENT_OUT] = linear;
303 info->format[PSC_POWER] = linear;
304 info->format[PSC_TEMPERATURE] = linear;
306 info->func[0] = PMBUS_HAVE_VIN
307 | PMBUS_HAVE_VOUT | PMBUS_HAVE_IIN
308 | PMBUS_HAVE_IOUT | PMBUS_HAVE_PIN
309 | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP
310 | PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT
311 | PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP;
312 info->func[1] = info->func[0];
314 return pmbus_do_probe(client, id, info);
317 static const struct i2c_device_id ir35221_id[] = {
322 MODULE_DEVICE_TABLE(i2c, ir35221_id);
324 static struct i2c_driver ir35221_driver = {
328 .probe = ir35221_probe,
329 .remove = pmbus_do_remove,
330 .id_table = ir35221_id,
333 module_i2c_driver(ir35221_driver);
335 MODULE_AUTHOR("Samuel Mendoza-Jonas <sam@mendozajonas.com");
336 MODULE_DESCRIPTION("PMBus driver for IR35221");
337 MODULE_LICENSE("GPL");