2 * Hardware monitoring driver for Analog Devices ADM1275 Hot-Swap Controller
3 * and Digital Power Monitor
5 * Copyright (c) 2011 Ericsson AB.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/err.h>
22 #include <linux/slab.h>
23 #include <linux/i2c.h>
26 enum chips
{ adm1075
, adm1275
, adm1276
};
28 #define ADM1275_PEAK_IOUT 0xd0
29 #define ADM1275_PEAK_VIN 0xd1
30 #define ADM1275_PEAK_VOUT 0xd2
31 #define ADM1275_PMON_CONFIG 0xd4
33 #define ADM1275_VIN_VOUT_SELECT (1 << 6)
34 #define ADM1275_VRANGE (1 << 5)
35 #define ADM1075_IRANGE_50 (1 << 4)
36 #define ADM1075_IRANGE_25 (1 << 3)
37 #define ADM1075_IRANGE_MASK ((1 << 3) | (1 << 4))
39 #define ADM1275_IOUT_WARN2_LIMIT 0xd7
40 #define ADM1275_DEVICE_CONFIG 0xd8
42 #define ADM1275_IOUT_WARN2_SELECT (1 << 4)
44 #define ADM1276_PEAK_PIN 0xda
46 #define ADM1275_MFR_STATUS_IOUT_WARN2 (1 << 0)
48 #define ADM1075_READ_VAUX 0xdd
49 #define ADM1075_VAUX_OV_WARN_LIMIT 0xde
50 #define ADM1075_VAUX_UV_WARN_LIMIT 0xdf
51 #define ADM1075_VAUX_STATUS 0xf6
53 #define ADM1075_VAUX_OV_WARN (1<<7)
54 #define ADM1075_VAUX_UV_WARN (1<<6)
59 struct pmbus_driver_info info
;
62 #define to_adm1275_data(x) container_of(x, struct adm1275_data, info)
64 static int adm1275_read_word_data(struct i2c_client
*client
, int page
, int reg
)
66 const struct pmbus_driver_info
*info
= pmbus_get_driver_info(client
);
67 const struct adm1275_data
*data
= to_adm1275_data(info
);
74 case PMBUS_IOUT_UC_FAULT_LIMIT
:
75 if (data
->have_oc_fault
) {
79 ret
= pmbus_read_word_data(client
, 0, ADM1275_IOUT_WARN2_LIMIT
);
81 case PMBUS_IOUT_OC_FAULT_LIMIT
:
82 if (!data
->have_oc_fault
) {
86 ret
= pmbus_read_word_data(client
, 0, ADM1275_IOUT_WARN2_LIMIT
);
88 case PMBUS_VOUT_OV_WARN_LIMIT
:
89 if (data
->id
!= adm1075
) {
93 ret
= pmbus_read_word_data(client
, 0,
94 ADM1075_VAUX_OV_WARN_LIMIT
);
96 case PMBUS_VOUT_UV_WARN_LIMIT
:
97 if (data
->id
!= adm1075
) {
101 ret
= pmbus_read_word_data(client
, 0,
102 ADM1075_VAUX_UV_WARN_LIMIT
);
104 case PMBUS_READ_VOUT
:
105 if (data
->id
!= adm1075
) {
109 ret
= pmbus_read_word_data(client
, 0, ADM1075_READ_VAUX
);
111 case PMBUS_VIRT_READ_IOUT_MAX
:
112 ret
= pmbus_read_word_data(client
, 0, ADM1275_PEAK_IOUT
);
114 case PMBUS_VIRT_READ_VOUT_MAX
:
115 ret
= pmbus_read_word_data(client
, 0, ADM1275_PEAK_VOUT
);
117 case PMBUS_VIRT_READ_VIN_MAX
:
118 ret
= pmbus_read_word_data(client
, 0, ADM1275_PEAK_VIN
);
120 case PMBUS_VIRT_READ_PIN_MAX
:
121 if (data
->id
== adm1275
) {
125 ret
= pmbus_read_word_data(client
, 0, ADM1276_PEAK_PIN
);
127 case PMBUS_VIRT_RESET_IOUT_HISTORY
:
128 case PMBUS_VIRT_RESET_VOUT_HISTORY
:
129 case PMBUS_VIRT_RESET_VIN_HISTORY
:
131 case PMBUS_VIRT_RESET_PIN_HISTORY
:
132 if (data
->id
== adm1275
)
142 static int adm1275_write_word_data(struct i2c_client
*client
, int page
, int reg
,
151 case PMBUS_IOUT_UC_FAULT_LIMIT
:
152 case PMBUS_IOUT_OC_FAULT_LIMIT
:
153 ret
= pmbus_write_word_data(client
, 0, ADM1275_IOUT_WARN2_LIMIT
,
156 case PMBUS_VIRT_RESET_IOUT_HISTORY
:
157 ret
= pmbus_write_word_data(client
, 0, ADM1275_PEAK_IOUT
, 0);
159 case PMBUS_VIRT_RESET_VOUT_HISTORY
:
160 ret
= pmbus_write_word_data(client
, 0, ADM1275_PEAK_VOUT
, 0);
162 case PMBUS_VIRT_RESET_VIN_HISTORY
:
163 ret
= pmbus_write_word_data(client
, 0, ADM1275_PEAK_VIN
, 0);
165 case PMBUS_VIRT_RESET_PIN_HISTORY
:
166 ret
= pmbus_write_word_data(client
, 0, ADM1276_PEAK_PIN
, 0);
175 static int adm1275_read_byte_data(struct i2c_client
*client
, int page
, int reg
)
177 const struct pmbus_driver_info
*info
= pmbus_get_driver_info(client
);
178 const struct adm1275_data
*data
= to_adm1275_data(info
);
185 case PMBUS_STATUS_IOUT
:
186 ret
= pmbus_read_byte_data(client
, page
, PMBUS_STATUS_IOUT
);
189 mfr_status
= pmbus_read_byte_data(client
, page
,
190 PMBUS_STATUS_MFR_SPECIFIC
);
191 if (mfr_status
< 0) {
195 if (mfr_status
& ADM1275_MFR_STATUS_IOUT_WARN2
) {
196 ret
|= data
->have_oc_fault
?
197 PB_IOUT_OC_FAULT
: PB_IOUT_UC_FAULT
;
200 case PMBUS_STATUS_VOUT
:
201 if (data
->id
!= adm1075
) {
206 mfr_status
= pmbus_read_byte_data(client
, 0,
207 ADM1075_VAUX_STATUS
);
208 if (mfr_status
& ADM1075_VAUX_OV_WARN
)
209 ret
|= PB_VOLTAGE_OV_WARNING
;
210 if (mfr_status
& ADM1075_VAUX_UV_WARN
)
211 ret
|= PB_VOLTAGE_UV_WARNING
;
220 static const struct i2c_device_id adm1275_id
[] = {
221 { "adm1075", adm1075
},
222 { "adm1275", adm1275
},
223 { "adm1276", adm1276
},
226 MODULE_DEVICE_TABLE(i2c
, adm1275_id
);
228 static int adm1275_probe(struct i2c_client
*client
,
229 const struct i2c_device_id
*id
)
231 u8 block_buffer
[I2C_SMBUS_BLOCK_MAX
+ 1];
232 int config
, device_config
;
234 struct pmbus_driver_info
*info
;
235 struct adm1275_data
*data
;
236 const struct i2c_device_id
*mid
;
238 if (!i2c_check_functionality(client
->adapter
,
239 I2C_FUNC_SMBUS_READ_BYTE_DATA
240 | I2C_FUNC_SMBUS_BLOCK_DATA
))
243 ret
= i2c_smbus_read_block_data(client
, PMBUS_MFR_ID
, block_buffer
);
245 dev_err(&client
->dev
, "Failed to read Manufacturer ID\n");
248 if (ret
!= 3 || strncmp(block_buffer
, "ADI", 3)) {
249 dev_err(&client
->dev
, "Unsupported Manufacturer ID\n");
253 ret
= i2c_smbus_read_block_data(client
, PMBUS_MFR_MODEL
, block_buffer
);
255 dev_err(&client
->dev
, "Failed to read Manufacturer Model\n");
258 for (mid
= adm1275_id
; mid
->name
[0]; mid
++) {
259 if (!strncasecmp(mid
->name
, block_buffer
, strlen(mid
->name
)))
263 dev_err(&client
->dev
, "Unsupported device\n");
267 if (id
->driver_data
!= mid
->driver_data
)
268 dev_notice(&client
->dev
,
269 "Device mismatch: Configured %s, detected %s\n",
270 id
->name
, mid
->name
);
272 config
= i2c_smbus_read_byte_data(client
, ADM1275_PMON_CONFIG
);
276 device_config
= i2c_smbus_read_byte_data(client
, ADM1275_DEVICE_CONFIG
);
277 if (device_config
< 0)
278 return device_config
;
280 data
= devm_kzalloc(&client
->dev
, sizeof(struct adm1275_data
),
285 data
->id
= mid
->driver_data
;
290 info
->format
[PSC_VOLTAGE_IN
] = direct
;
291 info
->format
[PSC_VOLTAGE_OUT
] = direct
;
292 info
->format
[PSC_CURRENT_OUT
] = direct
;
293 info
->m
[PSC_CURRENT_OUT
] = 807;
294 info
->b
[PSC_CURRENT_OUT
] = 20475;
295 info
->R
[PSC_CURRENT_OUT
] = -1;
296 info
->func
[0] = PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
;
298 info
->read_word_data
= adm1275_read_word_data
;
299 info
->read_byte_data
= adm1275_read_byte_data
;
300 info
->write_word_data
= adm1275_write_word_data
;
302 if (data
->id
== adm1075
) {
303 info
->m
[PSC_VOLTAGE_IN
] = 27169;
304 info
->b
[PSC_VOLTAGE_IN
] = 0;
305 info
->R
[PSC_VOLTAGE_IN
] = -1;
306 info
->m
[PSC_VOLTAGE_OUT
] = 27169;
307 info
->b
[PSC_VOLTAGE_OUT
] = 0;
308 info
->R
[PSC_VOLTAGE_OUT
] = -1;
309 } else if (config
& ADM1275_VRANGE
) {
310 info
->m
[PSC_VOLTAGE_IN
] = 19199;
311 info
->b
[PSC_VOLTAGE_IN
] = 0;
312 info
->R
[PSC_VOLTAGE_IN
] = -2;
313 info
->m
[PSC_VOLTAGE_OUT
] = 19199;
314 info
->b
[PSC_VOLTAGE_OUT
] = 0;
315 info
->R
[PSC_VOLTAGE_OUT
] = -2;
317 info
->m
[PSC_VOLTAGE_IN
] = 6720;
318 info
->b
[PSC_VOLTAGE_IN
] = 0;
319 info
->R
[PSC_VOLTAGE_IN
] = -1;
320 info
->m
[PSC_VOLTAGE_OUT
] = 6720;
321 info
->b
[PSC_VOLTAGE_OUT
] = 0;
322 info
->R
[PSC_VOLTAGE_OUT
] = -1;
325 if (device_config
& ADM1275_IOUT_WARN2_SELECT
)
326 data
->have_oc_fault
= true;
330 info
->format
[PSC_POWER
] = direct
;
331 info
->b
[PSC_POWER
] = 0;
332 info
->R
[PSC_POWER
] = -1;
333 switch (config
& ADM1075_IRANGE_MASK
) {
334 case ADM1075_IRANGE_25
:
335 info
->m
[PSC_POWER
] = 8549;
336 info
->m
[PSC_CURRENT_OUT
] = 806;
338 case ADM1075_IRANGE_50
:
339 info
->m
[PSC_POWER
] = 4279;
340 info
->m
[PSC_CURRENT_OUT
] = 404;
343 dev_err(&client
->dev
, "Invalid input current range");
344 info
->m
[PSC_POWER
] = 0;
345 info
->m
[PSC_CURRENT_OUT
] = 0;
348 info
->func
[0] |= PMBUS_HAVE_VIN
| PMBUS_HAVE_PIN
349 | PMBUS_HAVE_STATUS_INPUT
;
350 if (config
& ADM1275_VIN_VOUT_SELECT
)
352 PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
;
355 if (config
& ADM1275_VIN_VOUT_SELECT
)
357 PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
;
360 PMBUS_HAVE_VIN
| PMBUS_HAVE_STATUS_INPUT
;
363 info
->format
[PSC_POWER
] = direct
;
364 info
->func
[0] |= PMBUS_HAVE_VIN
| PMBUS_HAVE_PIN
365 | PMBUS_HAVE_STATUS_INPUT
;
366 if (config
& ADM1275_VIN_VOUT_SELECT
)
368 PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
;
369 if (config
& ADM1275_VRANGE
) {
370 info
->m
[PSC_POWER
] = 6043;
371 info
->b
[PSC_POWER
] = 0;
372 info
->R
[PSC_POWER
] = -2;
374 info
->m
[PSC_POWER
] = 2115;
375 info
->b
[PSC_POWER
] = 0;
376 info
->R
[PSC_POWER
] = -1;
381 return pmbus_do_probe(client
, id
, info
);
384 static struct i2c_driver adm1275_driver
= {
388 .probe
= adm1275_probe
,
389 .remove
= pmbus_do_remove
,
390 .id_table
= adm1275_id
,
393 module_i2c_driver(adm1275_driver
);
395 MODULE_AUTHOR("Guenter Roeck");
396 MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275 and compatibles");
397 MODULE_LICENSE("GPL");