aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/adt7475.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/adt7475.c')
-rw-r--r--drivers/hwmon/adt7475.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
index 688b0a1af5a8..eac24c1361bc 100644
--- a/drivers/hwmon/adt7475.c
+++ b/drivers/hwmon/adt7475.c
@@ -80,6 +80,8 @@
80 80
81#define REG_TEMP_OFFSET_BASE 0x70 81#define REG_TEMP_OFFSET_BASE 0x70
82 82
83#define REG_CONFIG2 0x73
84
83#define REG_EXTEND1 0x76 85#define REG_EXTEND1 0x76
84#define REG_EXTEND2 0x77 86#define REG_EXTEND2 0x77
85 87
@@ -92,11 +94,15 @@
92#define REG_VTT_MIN 0x84 /* ADT7490 only */ 94#define REG_VTT_MIN 0x84 /* ADT7490 only */
93#define REG_VTT_MAX 0x86 /* ADT7490 only */ 95#define REG_VTT_MAX 0x86 /* ADT7490 only */
94 96
97#define CONFIG2_ATTN 0x20
98
95#define CONFIG3_SMBALERT 0x01 99#define CONFIG3_SMBALERT 0x01
96#define CONFIG3_THERM 0x02 100#define CONFIG3_THERM 0x02
97 101
98#define CONFIG4_PINFUNC 0x03 102#define CONFIG4_PINFUNC 0x03
99#define CONFIG4_MAXDUTY 0x08 103#define CONFIG4_MAXDUTY 0x08
104#define CONFIG4_ATTN_IN10 0x30
105#define CONFIG4_ATTN_IN43 0xC0
100 106
101#define CONFIG5_TWOSCOMP 0x01 107#define CONFIG5_TWOSCOMP 0x01
102#define CONFIG5_TEMPOFFSET 0x02 108#define CONFIG5_TEMPOFFSET 0x02
@@ -157,6 +163,7 @@ struct adt7475_data {
157 u8 config4; 163 u8 config4;
158 u8 config5; 164 u8 config5;
159 u8 has_voltage; 165 u8 has_voltage;
166 u8 bypass_attn; /* Bypass voltage attenuator */
160 u8 has_pwm2:1; 167 u8 has_pwm2:1;
161 u8 has_fan4:1; 168 u8 has_fan4:1;
162 u32 alarms; 169 u32 alarms;
@@ -233,19 +240,24 @@ static const int adt7473_in_scaling[ADT7475_VOLTAGE_COUNT + 1][2] = {
233 { 45, 45 }, /* Vtt */ 240 { 45, 45 }, /* Vtt */
234}; 241};
235 242
236static inline int reg2volt(int channel, u16 reg) 243static inline int reg2volt(int channel, u16 reg, u8 bypass_attn)
237{ 244{
238 const int *r = adt7473_in_scaling[channel]; 245 const int *r = adt7473_in_scaling[channel];
239 246
247 if (bypass_attn & (1 << channel))
248 return DIV_ROUND_CLOSEST(reg * 2250, 1024);
240 return DIV_ROUND_CLOSEST(reg * (r[0] + r[1]) * 2250, r[1] * 1024); 249 return DIV_ROUND_CLOSEST(reg * (r[0] + r[1]) * 2250, r[1] * 1024);
241} 250}
242 251
243static inline u16 volt2reg(int channel, long volt) 252static inline u16 volt2reg(int channel, long volt, u8 bypass_attn)
244{ 253{
245 const int *r = adt7473_in_scaling[channel]; 254 const int *r = adt7473_in_scaling[channel];
246 long reg; 255 long reg;
247 256
248 reg = (volt * r[1] * 1024) / ((r[0] + r[1]) * 2250); 257 if (bypass_attn & (1 << channel))
258 reg = (volt * 1024) / 2250;
259 else
260 reg = (volt * r[1] * 1024) / ((r[0] + r[1]) * 2250);
249 return SENSORS_LIMIT(reg, 0, 1023) & (0xff << 2); 261 return SENSORS_LIMIT(reg, 0, 1023) & (0xff << 2);
250} 262}
251 263
@@ -305,7 +317,8 @@ static ssize_t show_voltage(struct device *dev, struct device_attribute *attr,
305 (data->alarms >> sattr->index) & 1); 317 (data->alarms >> sattr->index) & 1);
306 default: 318 default:
307 val = data->voltage[sattr->nr][sattr->index]; 319 val = data->voltage[sattr->nr][sattr->index];
308 return sprintf(buf, "%d\n", reg2volt(sattr->index, val)); 320 return sprintf(buf, "%d\n",
321 reg2volt(sattr->index, val, data->bypass_attn));
309 } 322 }
310} 323}
311 324
@@ -324,7 +337,8 @@ static ssize_t set_voltage(struct device *dev, struct device_attribute *attr,
324 337
325 mutex_lock(&data->lock); 338 mutex_lock(&data->lock);
326 339
327 data->voltage[sattr->nr][sattr->index] = volt2reg(sattr->index, val); 340 data->voltage[sattr->nr][sattr->index] =
341 volt2reg(sattr->index, val, data->bypass_attn);
328 342
329 if (sattr->index < ADT7475_VOLTAGE_COUNT) { 343 if (sattr->index < ADT7475_VOLTAGE_COUNT) {
330 if (sattr->nr == MIN) 344 if (sattr->nr == MIN)
@@ -1159,7 +1173,7 @@ static int adt7475_probe(struct i2c_client *client,
1159 1173
1160 struct adt7475_data *data; 1174 struct adt7475_data *data;
1161 int i, ret = 0, revision; 1175 int i, ret = 0, revision;
1162 u8 config3; 1176 u8 config2, config3;
1163 1177
1164 data = kzalloc(sizeof(*data), GFP_KERNEL); 1178 data = kzalloc(sizeof(*data), GFP_KERNEL);
1165 if (data == NULL) 1179 if (data == NULL)
@@ -1205,6 +1219,16 @@ static int adt7475_probe(struct i2c_client *client,
1205 data->has_voltage |= (1 << 0); /* in0 */ 1219 data->has_voltage |= (1 << 0); /* in0 */
1206 } 1220 }
1207 1221
1222 /* Voltage attenuators can be bypassed, globally or individually */
1223 config2 = adt7475_read(REG_CONFIG2);
1224 if (config2 & CONFIG2_ATTN) {
1225 data->bypass_attn = (0x3 << 3) | 0x3;
1226 } else {
1227 data->bypass_attn = ((data->config4 & CONFIG4_ATTN_IN10) >> 4) |
1228 ((data->config4 & CONFIG4_ATTN_IN43) >> 3);
1229 }
1230 data->bypass_attn &= data->has_voltage;
1231
1208 /* Call adt7475_read_pwm for all pwm's as this will reprogram any 1232 /* Call adt7475_read_pwm for all pwm's as this will reprogram any
1209 pwm's which are disabled to manual mode with 0% duty cycle */ 1233 pwm's which are disabled to manual mode with 0% duty cycle */
1210 for (i = 0; i < ADT7475_PWM_COUNT; i++) 1234 for (i = 0; i < ADT7475_PWM_COUNT; i++)
@@ -1251,6 +1275,12 @@ static int adt7475_probe(struct i2c_client *client,
1251 (data->has_voltage & (1 << 0)) ? " in0" : "", 1275 (data->has_voltage & (1 << 0)) ? " in0" : "",
1252 data->has_fan4 ? " fan4" : "", 1276 data->has_fan4 ? " fan4" : "",
1253 data->has_pwm2 ? " pwm2" : ""); 1277 data->has_pwm2 ? " pwm2" : "");
1278 if (data->bypass_attn)
1279 dev_info(&client->dev, "Bypassing attenuators on:%s%s%s%s\n",
1280 (data->bypass_attn & (1 << 0)) ? " in0" : "",
1281 (data->bypass_attn & (1 << 1)) ? " in1" : "",
1282 (data->bypass_attn & (1 << 3)) ? " in3" : "",
1283 (data->bypass_attn & (1 << 4)) ? " in4" : "");
1254 1284
1255 return 0; 1285 return 0;
1256 1286