diff options
Diffstat (limited to 'drivers/hwmon/pmbus/ltc2978.c')
-rw-r--r-- | drivers/hwmon/pmbus/ltc2978.c | 111 |
1 files changed, 101 insertions, 10 deletions
diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c index 60fe8f9839d3..f1c69c9de849 100644 --- a/drivers/hwmon/pmbus/ltc2978.c +++ b/drivers/hwmon/pmbus/ltc2978.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2011 Ericsson AB. | 4 | * Copyright (c) 2011 Ericsson AB. |
5 | * Copyright (c) 2013, 2014, 2015 Guenter Roeck | 5 | * Copyright (c) 2013, 2014, 2015 Guenter Roeck |
6 | * Copyright (c) 2015 Linear Technology | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * 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 | * it under the terms of the GNU General Public License as published by |
@@ -15,6 +16,8 @@ | |||
15 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
16 | */ | 17 | */ |
17 | 18 | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/jiffies.h> | ||
18 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | 22 | #include <linux/module.h> |
20 | #include <linux/init.h> | 23 | #include <linux/init.h> |
@@ -32,6 +35,7 @@ enum chips { ltc2974, ltc2975, ltc2977, ltc2978, ltc2980, ltc3880, ltc3882, | |||
32 | #define LTC2978_MFR_VIN_PEAK 0xde | 35 | #define LTC2978_MFR_VIN_PEAK 0xde |
33 | #define LTC2978_MFR_TEMPERATURE_PEAK 0xdf | 36 | #define LTC2978_MFR_TEMPERATURE_PEAK 0xdf |
34 | #define LTC2978_MFR_SPECIAL_ID 0xe7 /* Undocumented on LTC3882 */ | 37 | #define LTC2978_MFR_SPECIAL_ID 0xe7 /* Undocumented on LTC3882 */ |
38 | #define LTC2978_MFR_COMMON 0xef | ||
35 | 39 | ||
36 | /* LTC2974, LTC2975, LCT2977, LTC2980, LTC2978, and LTM2987 */ | 40 | /* LTC2974, LTC2975, LCT2977, LTC2980, LTC2978, and LTM2987 */ |
37 | #define LTC2978_MFR_VOUT_MIN 0xfb | 41 | #define LTC2978_MFR_VOUT_MIN 0xfb |
@@ -82,6 +86,11 @@ enum chips { ltc2974, ltc2975, ltc2977, ltc2978, ltc2980, ltc3880, ltc3882, | |||
82 | #define LTC3880_NUM_PAGES 2 | 86 | #define LTC3880_NUM_PAGES 2 |
83 | #define LTC3883_NUM_PAGES 1 | 87 | #define LTC3883_NUM_PAGES 1 |
84 | 88 | ||
89 | #define LTC_POLL_TIMEOUT 100 /* in milli-seconds */ | ||
90 | |||
91 | #define LTC_NOT_BUSY BIT(5) | ||
92 | #define LTC_NOT_PENDING BIT(4) | ||
93 | |||
85 | /* | 94 | /* |
86 | * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which | 95 | * LTC2978 clears peak data whenever the CLEAR_FAULTS command is executed, which |
87 | * happens pretty much each time chip data is updated. Raw peak data therefore | 96 | * happens pretty much each time chip data is updated. Raw peak data therefore |
@@ -105,8 +114,81 @@ struct ltc2978_data { | |||
105 | #define to_ltc2978_data(x) container_of(x, struct ltc2978_data, info) | 114 | #define to_ltc2978_data(x) container_of(x, struct ltc2978_data, info) |
106 | 115 | ||
107 | #define FEAT_CLEAR_PEAKS BIT(0) | 116 | #define FEAT_CLEAR_PEAKS BIT(0) |
117 | #define FEAT_NEEDS_POLLING BIT(1) | ||
108 | 118 | ||
109 | #define has_clear_peaks(d) ((d)->features & FEAT_CLEAR_PEAKS) | 119 | #define has_clear_peaks(d) ((d)->features & FEAT_CLEAR_PEAKS) |
120 | #define needs_polling(d) ((d)->features & FEAT_NEEDS_POLLING) | ||
121 | |||
122 | static int ltc_wait_ready(struct i2c_client *client) | ||
123 | { | ||
124 | unsigned long timeout = jiffies + msecs_to_jiffies(LTC_POLL_TIMEOUT); | ||
125 | const struct pmbus_driver_info *info = pmbus_get_driver_info(client); | ||
126 | struct ltc2978_data *data = to_ltc2978_data(info); | ||
127 | int status; | ||
128 | u8 mask; | ||
129 | |||
130 | if (!needs_polling(data)) | ||
131 | return 0; | ||
132 | |||
133 | /* | ||
134 | * LTC3883 does not support LTC_NOT_PENDING, even though | ||
135 | * the datasheet claims that it does. | ||
136 | */ | ||
137 | mask = LTC_NOT_BUSY; | ||
138 | if (data->id != ltc3883) | ||
139 | mask |= LTC_NOT_PENDING; | ||
140 | |||
141 | do { | ||
142 | status = pmbus_read_byte_data(client, 0, LTC2978_MFR_COMMON); | ||
143 | if (status == -EBADMSG || status == -ENXIO) { | ||
144 | /* PEC error or NACK: chip may be busy, try again */ | ||
145 | usleep_range(50, 100); | ||
146 | continue; | ||
147 | } | ||
148 | if (status < 0) | ||
149 | return status; | ||
150 | |||
151 | if ((status & mask) == mask) | ||
152 | return 0; | ||
153 | |||
154 | usleep_range(50, 100); | ||
155 | } while (time_before(jiffies, timeout)); | ||
156 | |||
157 | return -ETIMEDOUT; | ||
158 | } | ||
159 | |||
160 | static int ltc_read_word_data(struct i2c_client *client, int page, int reg) | ||
161 | { | ||
162 | int ret; | ||
163 | |||
164 | ret = ltc_wait_ready(client); | ||
165 | if (ret < 0) | ||
166 | return ret; | ||
167 | |||
168 | return pmbus_read_word_data(client, page, reg); | ||
169 | } | ||
170 | |||
171 | static int ltc_read_byte_data(struct i2c_client *client, int page, int reg) | ||
172 | { | ||
173 | int ret; | ||
174 | |||
175 | ret = ltc_wait_ready(client); | ||
176 | if (ret < 0) | ||
177 | return ret; | ||
178 | |||
179 | return pmbus_read_byte_data(client, page, reg); | ||
180 | } | ||
181 | |||
182 | static int ltc_write_byte(struct i2c_client *client, int page, u8 byte) | ||
183 | { | ||
184 | int ret; | ||
185 | |||
186 | ret = ltc_wait_ready(client); | ||
187 | if (ret < 0) | ||
188 | return ret; | ||
189 | |||
190 | return pmbus_write_byte(client, page, byte); | ||
191 | } | ||
110 | 192 | ||
111 | static inline int lin11_to_val(int data) | 193 | static inline int lin11_to_val(int data) |
112 | { | 194 | { |
@@ -126,7 +208,7 @@ static int ltc_get_max(struct ltc2978_data *data, struct i2c_client *client, | |||
126 | { | 208 | { |
127 | int ret; | 209 | int ret; |
128 | 210 | ||
129 | ret = pmbus_read_word_data(client, page, reg); | 211 | ret = ltc_read_word_data(client, page, reg); |
130 | if (ret >= 0) { | 212 | if (ret >= 0) { |
131 | if (lin11_to_val(ret) > lin11_to_val(*pmax)) | 213 | if (lin11_to_val(ret) > lin11_to_val(*pmax)) |
132 | *pmax = ret; | 214 | *pmax = ret; |
@@ -140,7 +222,7 @@ static int ltc_get_min(struct ltc2978_data *data, struct i2c_client *client, | |||
140 | { | 222 | { |
141 | int ret; | 223 | int ret; |
142 | 224 | ||
143 | ret = pmbus_read_word_data(client, page, reg); | 225 | ret = ltc_read_word_data(client, page, reg); |
144 | if (ret >= 0) { | 226 | if (ret >= 0) { |
145 | if (lin11_to_val(ret) < lin11_to_val(*pmin)) | 227 | if (lin11_to_val(ret) < lin11_to_val(*pmin)) |
146 | *pmin = ret; | 228 | *pmin = ret; |
@@ -162,7 +244,7 @@ static int ltc2978_read_word_data_common(struct i2c_client *client, int page, | |||
162 | &data->vin_max); | 244 | &data->vin_max); |
163 | break; | 245 | break; |
164 | case PMBUS_VIRT_READ_VOUT_MAX: | 246 | case PMBUS_VIRT_READ_VOUT_MAX: |
165 | ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_PEAK); | 247 | ret = ltc_read_word_data(client, page, LTC2978_MFR_VOUT_PEAK); |
166 | if (ret >= 0) { | 248 | if (ret >= 0) { |
167 | /* | 249 | /* |
168 | * VOUT is 16 bit unsigned with fixed exponent, | 250 | * VOUT is 16 bit unsigned with fixed exponent, |
@@ -184,6 +266,9 @@ static int ltc2978_read_word_data_common(struct i2c_client *client, int page, | |||
184 | ret = 0; | 266 | ret = 0; |
185 | break; | 267 | break; |
186 | default: | 268 | default: |
269 | ret = ltc_wait_ready(client); | ||
270 | if (ret < 0) | ||
271 | return ret; | ||
187 | ret = -ENODATA; | 272 | ret = -ENODATA; |
188 | break; | 273 | break; |
189 | } | 274 | } |
@@ -202,7 +287,7 @@ static int ltc2978_read_word_data(struct i2c_client *client, int page, int reg) | |||
202 | &data->vin_min); | 287 | &data->vin_min); |
203 | break; | 288 | break; |
204 | case PMBUS_VIRT_READ_VOUT_MIN: | 289 | case PMBUS_VIRT_READ_VOUT_MIN: |
205 | ret = pmbus_read_word_data(client, page, LTC2978_MFR_VOUT_MIN); | 290 | ret = ltc_read_word_data(client, page, LTC2978_MFR_VOUT_MIN); |
206 | if (ret >= 0) { | 291 | if (ret >= 0) { |
207 | /* | 292 | /* |
208 | * VOUT_MIN is known to not be supported on some lots | 293 | * VOUT_MIN is known to not be supported on some lots |
@@ -353,9 +438,9 @@ static int ltc2978_clear_peaks(struct ltc2978_data *data, | |||
353 | int ret; | 438 | int ret; |
354 | 439 | ||
355 | if (has_clear_peaks(data)) | 440 | if (has_clear_peaks(data)) |
356 | ret = pmbus_write_byte(client, 0, LTC3880_MFR_CLEAR_PEAKS); | 441 | ret = ltc_write_byte(client, 0, LTC3880_MFR_CLEAR_PEAKS); |
357 | else | 442 | else |
358 | ret = pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); | 443 | ret = ltc_write_byte(client, page, PMBUS_CLEAR_FAULTS); |
359 | 444 | ||
360 | return ret; | 445 | return ret; |
361 | } | 446 | } |
@@ -403,6 +488,9 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page, | |||
403 | ret = ltc2978_clear_peaks(data, client, page); | 488 | ret = ltc2978_clear_peaks(data, client, page); |
404 | break; | 489 | break; |
405 | default: | 490 | default: |
491 | ret = ltc_wait_ready(client); | ||
492 | if (ret < 0) | ||
493 | return ret; | ||
406 | ret = -ENODATA; | 494 | ret = -ENODATA; |
407 | break; | 495 | break; |
408 | } | 496 | } |
@@ -530,6 +618,9 @@ static int ltc2978_probe(struct i2c_client *client, | |||
530 | 618 | ||
531 | info = &data->info; | 619 | info = &data->info; |
532 | info->write_word_data = ltc2978_write_word_data; | 620 | info->write_word_data = ltc2978_write_word_data; |
621 | info->write_byte = ltc_write_byte; | ||
622 | info->read_word_data = ltc_read_word_data; | ||
623 | info->read_byte_data = ltc_read_byte_data; | ||
533 | 624 | ||
534 | data->vin_min = 0x7bff; | 625 | data->vin_min = 0x7bff; |
535 | data->vin_max = 0x7c00; | 626 | data->vin_max = 0x7c00; |
@@ -588,7 +679,7 @@ static int ltc2978_probe(struct i2c_client *client, | |||
588 | case ltc3880: | 679 | case ltc3880: |
589 | case ltc3887: | 680 | case ltc3887: |
590 | case ltm4676: | 681 | case ltm4676: |
591 | data->features |= FEAT_CLEAR_PEAKS; | 682 | data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING; |
592 | info->read_word_data = ltc3880_read_word_data; | 683 | info->read_word_data = ltc3880_read_word_data; |
593 | info->pages = LTC3880_NUM_PAGES; | 684 | info->pages = LTC3880_NUM_PAGES; |
594 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | 685 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN |
@@ -603,7 +694,7 @@ static int ltc2978_probe(struct i2c_client *client, | |||
603 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; | 694 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; |
604 | break; | 695 | break; |
605 | case ltc3882: | 696 | case ltc3882: |
606 | data->features |= FEAT_CLEAR_PEAKS; | 697 | data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING; |
607 | info->read_word_data = ltc3880_read_word_data; | 698 | info->read_word_data = ltc3880_read_word_data; |
608 | info->pages = LTC3880_NUM_PAGES; | 699 | info->pages = LTC3880_NUM_PAGES; |
609 | info->func[0] = PMBUS_HAVE_VIN | 700 | info->func[0] = PMBUS_HAVE_VIN |
@@ -618,7 +709,7 @@ static int ltc2978_probe(struct i2c_client *client, | |||
618 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; | 709 | | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; |
619 | break; | 710 | break; |
620 | case ltc3883: | 711 | case ltc3883: |
621 | data->features |= FEAT_CLEAR_PEAKS; | 712 | data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING; |
622 | info->read_word_data = ltc3883_read_word_data; | 713 | info->read_word_data = ltc3883_read_word_data; |
623 | info->pages = LTC3883_NUM_PAGES; | 714 | info->pages = LTC3883_NUM_PAGES; |
624 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | 715 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN |
@@ -629,7 +720,7 @@ static int ltc2978_probe(struct i2c_client *client, | |||
629 | | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; | 720 | | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP; |
630 | break; | 721 | break; |
631 | case ltc3886: | 722 | case ltc3886: |
632 | data->features |= FEAT_CLEAR_PEAKS; | 723 | data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING; |
633 | info->read_word_data = ltc3883_read_word_data; | 724 | info->read_word_data = ltc3883_read_word_data; |
634 | info->pages = LTC3880_NUM_PAGES; | 725 | info->pages = LTC3880_NUM_PAGES; |
635 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN | 726 | info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_IIN |