diff options
Diffstat (limited to 'drivers/hwmon/pmbus/max34440.c')
-rw-r--r-- | drivers/hwmon/pmbus/max34440.c | 112 |
1 files changed, 109 insertions, 3 deletions
diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c index 95ee9e195cb6..2ada7b021fbe 100644 --- a/drivers/hwmon/pmbus/max34440.c +++ b/drivers/hwmon/pmbus/max34440.c | |||
@@ -25,21 +25,35 @@ | |||
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | #include "pmbus.h" | 26 | #include "pmbus.h" |
27 | 27 | ||
28 | enum chips { max34440, max34441 }; | 28 | enum chips { max34440, max34441, max34446 }; |
29 | 29 | ||
30 | #define MAX34440_MFR_VOUT_PEAK 0xd4 | 30 | #define MAX34440_MFR_VOUT_PEAK 0xd4 |
31 | #define MAX34440_MFR_IOUT_PEAK 0xd5 | 31 | #define MAX34440_MFR_IOUT_PEAK 0xd5 |
32 | #define MAX34440_MFR_TEMPERATURE_PEAK 0xd6 | 32 | #define MAX34440_MFR_TEMPERATURE_PEAK 0xd6 |
33 | #define MAX34440_MFR_VOUT_MIN 0xd7 | 33 | #define MAX34440_MFR_VOUT_MIN 0xd7 |
34 | 34 | ||
35 | #define MAX34446_MFR_POUT_PEAK 0xe0 | ||
36 | #define MAX34446_MFR_POUT_AVG 0xe1 | ||
37 | #define MAX34446_MFR_IOUT_AVG 0xe2 | ||
38 | #define MAX34446_MFR_TEMPERATURE_AVG 0xe3 | ||
39 | |||
35 | #define MAX34440_STATUS_OC_WARN (1 << 0) | 40 | #define MAX34440_STATUS_OC_WARN (1 << 0) |
36 | #define MAX34440_STATUS_OC_FAULT (1 << 1) | 41 | #define MAX34440_STATUS_OC_FAULT (1 << 1) |
37 | #define MAX34440_STATUS_OT_FAULT (1 << 5) | 42 | #define MAX34440_STATUS_OT_FAULT (1 << 5) |
38 | #define MAX34440_STATUS_OT_WARN (1 << 6) | 43 | #define MAX34440_STATUS_OT_WARN (1 << 6) |
39 | 44 | ||
45 | struct max34440_data { | ||
46 | int id; | ||
47 | struct pmbus_driver_info info; | ||
48 | }; | ||
49 | |||
50 | #define to_max34440_data(x) container_of(x, struct max34440_data, info) | ||
51 | |||
40 | static int max34440_read_word_data(struct i2c_client *client, int page, int reg) | 52 | static int max34440_read_word_data(struct i2c_client *client, int page, int reg) |
41 | { | 53 | { |
42 | int ret; | 54 | int ret; |
55 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
56 | const struct max34440_data *data = to_max34440_data(info); | ||
43 | 57 | ||
44 | switch (reg) { | 58 | switch (reg) { |
45 | case PMBUS_VIRT_READ_VOUT_MIN: | 59 | case PMBUS_VIRT_READ_VOUT_MIN: |
@@ -50,14 +64,43 @@ static int max34440_read_word_data(struct i2c_client *client, int page, int reg) | |||
50 | ret = pmbus_read_word_data(client, page, | 64 | ret = pmbus_read_word_data(client, page, |
51 | MAX34440_MFR_VOUT_PEAK); | 65 | MAX34440_MFR_VOUT_PEAK); |
52 | break; | 66 | break; |
67 | case PMBUS_VIRT_READ_IOUT_AVG: | ||
68 | if (data->id != max34446) | ||
69 | return -ENXIO; | ||
70 | ret = pmbus_read_word_data(client, page, | ||
71 | MAX34446_MFR_IOUT_AVG); | ||
72 | break; | ||
53 | case PMBUS_VIRT_READ_IOUT_MAX: | 73 | case PMBUS_VIRT_READ_IOUT_MAX: |
54 | ret = pmbus_read_word_data(client, page, | 74 | ret = pmbus_read_word_data(client, page, |
55 | MAX34440_MFR_IOUT_PEAK); | 75 | MAX34440_MFR_IOUT_PEAK); |
56 | break; | 76 | break; |
77 | case PMBUS_VIRT_READ_POUT_AVG: | ||
78 | if (data->id != max34446) | ||
79 | return -ENXIO; | ||
80 | ret = pmbus_read_word_data(client, page, | ||
81 | MAX34446_MFR_POUT_AVG); | ||
82 | break; | ||
83 | case PMBUS_VIRT_READ_POUT_MAX: | ||
84 | if (data->id != max34446) | ||
85 | return -ENXIO; | ||
86 | ret = pmbus_read_word_data(client, page, | ||
87 | MAX34446_MFR_POUT_PEAK); | ||
88 | break; | ||
89 | case PMBUS_VIRT_READ_TEMP_AVG: | ||
90 | if (data->id != max34446) | ||
91 | return -ENXIO; | ||
92 | ret = pmbus_read_word_data(client, page, | ||
93 | MAX34446_MFR_TEMPERATURE_AVG); | ||
94 | break; | ||
57 | case PMBUS_VIRT_READ_TEMP_MAX: | 95 | case PMBUS_VIRT_READ_TEMP_MAX: |
58 | ret = pmbus_read_word_data(client, page, | 96 | ret = pmbus_read_word_data(client, page, |
59 | MAX34440_MFR_TEMPERATURE_PEAK); | 97 | MAX34440_MFR_TEMPERATURE_PEAK); |
60 | break; | 98 | break; |
99 | case PMBUS_VIRT_RESET_POUT_HISTORY: | ||
100 | if (data->id != max34446) | ||
101 | return -ENXIO; | ||
102 | ret = 0; | ||
103 | break; | ||
61 | case PMBUS_VIRT_RESET_VOUT_HISTORY: | 104 | case PMBUS_VIRT_RESET_VOUT_HISTORY: |
62 | case PMBUS_VIRT_RESET_IOUT_HISTORY: | 105 | case PMBUS_VIRT_RESET_IOUT_HISTORY: |
63 | case PMBUS_VIRT_RESET_TEMP_HISTORY: | 106 | case PMBUS_VIRT_RESET_TEMP_HISTORY: |
@@ -73,9 +116,19 @@ static int max34440_read_word_data(struct i2c_client *client, int page, int reg) | |||
73 | static int max34440_write_word_data(struct i2c_client *client, int page, | 116 | static int max34440_write_word_data(struct i2c_client *client, int page, |
74 | int reg, u16 word) | 117 | int reg, u16 word) |
75 | { | 118 | { |
119 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
120 | const struct max34440_data *data = to_max34440_data(info); | ||
76 | int ret; | 121 | int ret; |
77 | 122 | ||
78 | switch (reg) { | 123 | switch (reg) { |
124 | case PMBUS_VIRT_RESET_POUT_HISTORY: | ||
125 | ret = pmbus_write_word_data(client, page, | ||
126 | MAX34446_MFR_POUT_PEAK, 0); | ||
127 | if (ret) | ||
128 | break; | ||
129 | ret = pmbus_write_word_data(client, page, | ||
130 | MAX34446_MFR_POUT_AVG, 0); | ||
131 | break; | ||
79 | case PMBUS_VIRT_RESET_VOUT_HISTORY: | 132 | case PMBUS_VIRT_RESET_VOUT_HISTORY: |
80 | ret = pmbus_write_word_data(client, page, | 133 | ret = pmbus_write_word_data(client, page, |
81 | MAX34440_MFR_VOUT_MIN, 0x7fff); | 134 | MAX34440_MFR_VOUT_MIN, 0x7fff); |
@@ -87,11 +140,18 @@ static int max34440_write_word_data(struct i2c_client *client, int page, | |||
87 | case PMBUS_VIRT_RESET_IOUT_HISTORY: | 140 | case PMBUS_VIRT_RESET_IOUT_HISTORY: |
88 | ret = pmbus_write_word_data(client, page, | 141 | ret = pmbus_write_word_data(client, page, |
89 | MAX34440_MFR_IOUT_PEAK, 0); | 142 | MAX34440_MFR_IOUT_PEAK, 0); |
143 | if (!ret && data->id == max34446) | ||
144 | ret = pmbus_write_word_data(client, page, | ||
145 | MAX34446_MFR_IOUT_AVG, 0); | ||
146 | |||
90 | break; | 147 | break; |
91 | case PMBUS_VIRT_RESET_TEMP_HISTORY: | 148 | case PMBUS_VIRT_RESET_TEMP_HISTORY: |
92 | ret = pmbus_write_word_data(client, page, | 149 | ret = pmbus_write_word_data(client, page, |
93 | MAX34440_MFR_TEMPERATURE_PEAK, | 150 | MAX34440_MFR_TEMPERATURE_PEAK, |
94 | 0x8000); | 151 | 0x8000); |
152 | if (!ret && data->id == max34446) | ||
153 | ret = pmbus_write_word_data(client, page, | ||
154 | MAX34446_MFR_TEMPERATURE_AVG, 0); | ||
95 | break; | 155 | break; |
96 | default: | 156 | default: |
97 | ret = -ENODATA; | 157 | ret = -ENODATA; |
@@ -225,20 +285,66 @@ static struct pmbus_driver_info max34440_info[] = { | |||
225 | .read_word_data = max34440_read_word_data, | 285 | .read_word_data = max34440_read_word_data, |
226 | .write_word_data = max34440_write_word_data, | 286 | .write_word_data = max34440_write_word_data, |
227 | }, | 287 | }, |
288 | [max34446] = { | ||
289 | .pages = 7, | ||
290 | .format[PSC_VOLTAGE_IN] = direct, | ||
291 | .format[PSC_VOLTAGE_OUT] = direct, | ||
292 | .format[PSC_TEMPERATURE] = direct, | ||
293 | .format[PSC_CURRENT_OUT] = direct, | ||
294 | .format[PSC_POWER] = direct, | ||
295 | .m[PSC_VOLTAGE_IN] = 1, | ||
296 | .b[PSC_VOLTAGE_IN] = 0, | ||
297 | .R[PSC_VOLTAGE_IN] = 3, | ||
298 | .m[PSC_VOLTAGE_OUT] = 1, | ||
299 | .b[PSC_VOLTAGE_OUT] = 0, | ||
300 | .R[PSC_VOLTAGE_OUT] = 3, | ||
301 | .m[PSC_CURRENT_OUT] = 1, | ||
302 | .b[PSC_CURRENT_OUT] = 0, | ||
303 | .R[PSC_CURRENT_OUT] = 3, | ||
304 | .m[PSC_POWER] = 1, | ||
305 | .b[PSC_POWER] = 0, | ||
306 | .R[PSC_POWER] = 3, | ||
307 | .m[PSC_TEMPERATURE] = 1, | ||
308 | .b[PSC_TEMPERATURE] = 0, | ||
309 | .R[PSC_TEMPERATURE] = 2, | ||
310 | .func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ||
311 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, | ||
312 | .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ||
313 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, | ||
314 | .func[2] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ||
315 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT, | ||
316 | .func[3] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT | ||
317 | | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT, | ||
318 | .func[4] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, | ||
319 | .func[5] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, | ||
320 | .func[6] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP, | ||
321 | .read_byte_data = max34440_read_byte_data, | ||
322 | .read_word_data = max34440_read_word_data, | ||
323 | .write_word_data = max34440_write_word_data, | ||
324 | }, | ||
228 | }; | 325 | }; |
229 | 326 | ||
230 | static int max34440_probe(struct i2c_client *client, | 327 | static int max34440_probe(struct i2c_client *client, |
231 | const struct i2c_device_id *id) | 328 | const struct i2c_device_id *id) |
232 | { | 329 | { |
233 | return pmbus_do_probe(client, id, &max34440_info[id->driver_data]); | 330 | struct max34440_data *data; |
331 | |||
332 | data = devm_kzalloc(&client->dev, sizeof(struct max34440_data), | ||
333 | GFP_KERNEL); | ||
334 | if (!data) | ||
335 | return -ENOMEM; | ||
336 | data->id = id->driver_data; | ||
337 | data->info = max34440_info[id->driver_data]; | ||
338 | |||
339 | return pmbus_do_probe(client, id, &data->info); | ||
234 | } | 340 | } |
235 | 341 | ||
236 | static const struct i2c_device_id max34440_id[] = { | 342 | static const struct i2c_device_id max34440_id[] = { |
237 | {"max34440", max34440}, | 343 | {"max34440", max34440}, |
238 | {"max34441", max34441}, | 344 | {"max34441", max34441}, |
345 | {"max34446", max34446}, | ||
239 | {} | 346 | {} |
240 | }; | 347 | }; |
241 | |||
242 | MODULE_DEVICE_TABLE(i2c, max34440_id); | 348 | MODULE_DEVICE_TABLE(i2c, max34440_id); |
243 | 349 | ||
244 | /* This is the driver that will be inserted */ | 350 | /* This is the driver that will be inserted */ |