1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Hardware monitoring driver for IR35221
5 * Copyright (C) IBM Corporation 2017.
10 #include <linux/init.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
15 #define IR35221_MFR_VIN_PEAK 0xc5
16 #define IR35221_MFR_VOUT_PEAK 0xc6
17 #define IR35221_MFR_IOUT_PEAK 0xc7
18 #define IR35221_MFR_TEMP_PEAK 0xc8
19 #define IR35221_MFR_VIN_VALLEY 0xc9
20 #define IR35221_MFR_VOUT_VALLEY 0xca
21 #define IR35221_MFR_IOUT_VALLEY 0xcb
22 #define IR35221_MFR_TEMP_VALLEY 0xcc
24 static int ir35221_read_word_data(struct i2c_client
*client
, int page
, int reg
)
29 case PMBUS_VIRT_READ_VIN_MAX
:
30 ret
= pmbus_read_word_data(client
, page
, IR35221_MFR_VIN_PEAK
);
32 case PMBUS_VIRT_READ_VOUT_MAX
:
33 ret
= pmbus_read_word_data(client
, page
, IR35221_MFR_VOUT_PEAK
);
35 case PMBUS_VIRT_READ_IOUT_MAX
:
36 ret
= pmbus_read_word_data(client
, page
, IR35221_MFR_IOUT_PEAK
);
38 case PMBUS_VIRT_READ_TEMP_MAX
:
39 ret
= pmbus_read_word_data(client
, page
, IR35221_MFR_TEMP_PEAK
);
41 case PMBUS_VIRT_READ_VIN_MIN
:
42 ret
= pmbus_read_word_data(client
, page
,
43 IR35221_MFR_VIN_VALLEY
);
45 case PMBUS_VIRT_READ_VOUT_MIN
:
46 ret
= pmbus_read_word_data(client
, page
,
47 IR35221_MFR_VOUT_VALLEY
);
49 case PMBUS_VIRT_READ_IOUT_MIN
:
50 ret
= pmbus_read_word_data(client
, page
,
51 IR35221_MFR_IOUT_VALLEY
);
53 case PMBUS_VIRT_READ_TEMP_MIN
:
54 ret
= pmbus_read_word_data(client
, page
,
55 IR35221_MFR_TEMP_VALLEY
);
65 static int ir35221_probe(struct i2c_client
*client
,
66 const struct i2c_device_id
*id
)
68 struct pmbus_driver_info
*info
;
69 u8 buf
[I2C_SMBUS_BLOCK_MAX
];
72 if (!i2c_check_functionality(client
->adapter
,
73 I2C_FUNC_SMBUS_READ_BYTE_DATA
74 | I2C_FUNC_SMBUS_READ_WORD_DATA
75 | I2C_FUNC_SMBUS_READ_BLOCK_DATA
))
78 ret
= i2c_smbus_read_block_data(client
, PMBUS_MFR_ID
, buf
);
80 dev_err(&client
->dev
, "Failed to read PMBUS_MFR_ID\n");
83 if (ret
!= 2 || strncmp(buf
, "RI", strlen("RI"))) {
84 dev_err(&client
->dev
, "MFR_ID unrecognised\n");
88 ret
= i2c_smbus_read_block_data(client
, PMBUS_MFR_MODEL
, buf
);
90 dev_err(&client
->dev
, "Failed to read PMBUS_MFR_MODEL\n");
93 if (ret
!= 2 || !(buf
[0] == 0x6c && buf
[1] == 0x00)) {
94 dev_err(&client
->dev
, "MFR_MODEL unrecognised\n");
98 info
= devm_kzalloc(&client
->dev
, sizeof(struct pmbus_driver_info
),
103 info
->read_word_data
= ir35221_read_word_data
;
106 info
->format
[PSC_VOLTAGE_IN
] = linear
;
107 info
->format
[PSC_VOLTAGE_OUT
] = linear
;
108 info
->format
[PSC_CURRENT_IN
] = linear
;
109 info
->format
[PSC_CURRENT_OUT
] = linear
;
110 info
->format
[PSC_POWER
] = linear
;
111 info
->format
[PSC_TEMPERATURE
] = linear
;
113 info
->func
[0] = PMBUS_HAVE_VIN
114 | PMBUS_HAVE_VOUT
| PMBUS_HAVE_IIN
115 | PMBUS_HAVE_IOUT
| PMBUS_HAVE_PIN
116 | PMBUS_HAVE_POUT
| PMBUS_HAVE_TEMP
117 | PMBUS_HAVE_STATUS_VOUT
| PMBUS_HAVE_STATUS_IOUT
118 | PMBUS_HAVE_STATUS_INPUT
| PMBUS_HAVE_STATUS_TEMP
;
119 info
->func
[1] = info
->func
[0];
121 return pmbus_do_probe(client
, id
, info
);
124 static const struct i2c_device_id ir35221_id
[] = {
129 MODULE_DEVICE_TABLE(i2c
, ir35221_id
);
131 static struct i2c_driver ir35221_driver
= {
135 .probe
= ir35221_probe
,
136 .remove
= pmbus_do_remove
,
137 .id_table
= ir35221_id
,
140 module_i2c_driver(ir35221_driver
);
142 MODULE_AUTHOR("Samuel Mendoza-Jonas <sam@mendozajonas.com");
143 MODULE_DESCRIPTION("PMBus driver for IR35221");
144 MODULE_LICENSE("GPL");