1 // SPDX-License-Identifier: GPL-2.0+
3 * Hardware monitoring driver for BEL PFE family power supplies.
5 * Copyright (c) 2019 Facebook Inc.
10 #include <linux/init.h>
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/pmbus.h>
17 enum chips
{pfe1100
, pfe3000
};
20 * Disable status check because some devices report communication error
21 * (invalid command) for VOUT_MODE command (0x20) although the correct
22 * VOUT_MODE (0x16) is returned: it leads to incorrect exponent in linear
24 * This affects both pfe3000 and pfe1100.
26 static struct pmbus_platform_data pfe_plat_data
= {
27 .flags
= PMBUS_SKIP_STATUS_CHECK
,
30 static struct pmbus_driver_info pfe_driver_info
[] = {
33 .format
[PSC_VOLTAGE_IN
] = linear
,
34 .format
[PSC_VOLTAGE_OUT
] = linear
,
35 .format
[PSC_CURRENT_IN
] = linear
,
36 .format
[PSC_CURRENT_OUT
] = linear
,
37 .format
[PSC_POWER
] = linear
,
38 .format
[PSC_TEMPERATURE
] = linear
,
39 .format
[PSC_FAN
] = linear
,
41 .func
[0] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
|
42 PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
|
44 PMBUS_HAVE_VIN
| PMBUS_HAVE_IIN
|
45 PMBUS_HAVE_PIN
| PMBUS_HAVE_STATUS_INPUT
|
46 PMBUS_HAVE_TEMP
| PMBUS_HAVE_TEMP2
|
47 PMBUS_HAVE_STATUS_TEMP
|
53 .format
[PSC_VOLTAGE_IN
] = linear
,
54 .format
[PSC_VOLTAGE_OUT
] = linear
,
55 .format
[PSC_CURRENT_IN
] = linear
,
56 .format
[PSC_CURRENT_OUT
] = linear
,
57 .format
[PSC_POWER
] = linear
,
58 .format
[PSC_TEMPERATURE
] = linear
,
59 .format
[PSC_FAN
] = linear
,
62 .func
[0] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
|
63 PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
|
64 PMBUS_HAVE_POUT
| PMBUS_HAVE_FAN12
|
65 PMBUS_HAVE_VIN
| PMBUS_HAVE_IIN
|
66 PMBUS_HAVE_PIN
| PMBUS_HAVE_STATUS_INPUT
|
67 PMBUS_HAVE_TEMP
| PMBUS_HAVE_TEMP2
|
68 PMBUS_HAVE_TEMP3
| PMBUS_HAVE_STATUS_TEMP
|
72 .func
[1] = PMBUS_HAVE_VOUT
| PMBUS_HAVE_STATUS_VOUT
|
73 PMBUS_HAVE_IOUT
| PMBUS_HAVE_STATUS_IOUT
|
74 PMBUS_HAVE_PIN
| PMBUS_HAVE_STATUS_INPUT
|
81 * Page 5: Vsb Cathode.
84 .func
[2] = PMBUS_HAVE_VOUT
,
85 .func
[4] = PMBUS_HAVE_VOUT
,
86 .func
[5] = PMBUS_HAVE_VOUT
,
87 .func
[6] = PMBUS_HAVE_VOUT
,
91 static const struct i2c_device_id pfe_device_id
[];
93 static int pfe_pmbus_probe(struct i2c_client
*client
)
97 model
= (int)i2c_match_id(pfe_device_id
, client
)->driver_data
;
98 client
->dev
.platform_data
= &pfe_plat_data
;
101 * PFE3000-12-069RA devices may not stay in page 0 during device
102 * probe which leads to probe failure (read status word failed).
103 * So let's set the device to page 0 at the beginning.
105 if (model
== pfe3000
)
106 i2c_smbus_write_byte_data(client
, PMBUS_PAGE
, 0);
108 return pmbus_do_probe(client
, &pfe_driver_info
[model
]);
111 static const struct i2c_device_id pfe_device_id
[] = {
112 {"pfe1100", pfe1100
},
113 {"pfe3000", pfe3000
},
117 MODULE_DEVICE_TABLE(i2c
, pfe_device_id
);
119 static struct i2c_driver pfe_pmbus_driver
= {
123 .probe
= pfe_pmbus_probe
,
124 .id_table
= pfe_device_id
,
127 module_i2c_driver(pfe_pmbus_driver
);
129 MODULE_AUTHOR("Tao Ren <rentao.bupt@gmail.com>");
130 MODULE_DESCRIPTION("PMBus driver for BEL PFE Family Power Supplies");
131 MODULE_LICENSE("GPL");
132 MODULE_IMPORT_NS("PMBUS");