aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/gl518sm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/gl518sm.c')
-rw-r--r--drivers/hwmon/gl518sm.c110
1 files changed, 60 insertions, 50 deletions
diff --git a/drivers/hwmon/gl518sm.c b/drivers/hwmon/gl518sm.c
index 8287a3af6d79..ed901f96a04f 100644
--- a/drivers/hwmon/gl518sm.c
+++ b/drivers/hwmon/gl518sm.c
@@ -38,6 +38,7 @@
38#include <linux/jiffies.h> 38#include <linux/jiffies.h>
39#include <linux/i2c.h> 39#include <linux/i2c.h>
40#include <linux/hwmon.h> 40#include <linux/hwmon.h>
41#include <linux/hwmon-sysfs.h>
41#include <linux/err.h> 42#include <linux/err.h>
42#include <linux/mutex.h> 43#include <linux/mutex.h>
43#include <linux/sysfs.h> 44#include <linux/sysfs.h>
@@ -166,24 +167,10 @@ static ssize_t show_##suffix(struct device *dev, struct device_attribute *attr,
166 return sprintf(buf, "%d\n", type##_FROM_REG(data->value)); \ 167 return sprintf(buf, "%d\n", type##_FROM_REG(data->value)); \
167} 168}
168 169
169#define show_fan(suffix, value, index) \
170static ssize_t show_##suffix(struct device *dev, struct device_attribute *attr, char *buf) \
171{ \
172 struct gl518_data *data = gl518_update_device(dev); \
173 return sprintf(buf, "%d\n", FAN_FROM_REG(data->value[index], \
174 DIV_FROM_REG(data->fan_div[index]))); \
175}
176
177show(TEMP, temp_input1, temp_in); 170show(TEMP, temp_input1, temp_in);
178show(TEMP, temp_max1, temp_max); 171show(TEMP, temp_max1, temp_max);
179show(TEMP, temp_hyst1, temp_hyst); 172show(TEMP, temp_hyst1, temp_hyst);
180show(BOOL, fan_auto1, fan_auto1); 173show(BOOL, fan_auto1, fan_auto1);
181show_fan(fan_input1, fan_in, 0);
182show_fan(fan_input2, fan_in, 1);
183show_fan(fan_min1, fan_min, 0);
184show_fan(fan_min2, fan_min, 1);
185show(DIV, fan_div1, fan_div[0]);
186show(DIV, fan_div2, fan_div[1]);
187show(VDD, in_input0, voltage_in[0]); 174show(VDD, in_input0, voltage_in[0]);
188show(IN, in_input1, voltage_in[1]); 175show(IN, in_input1, voltage_in[1]);
189show(IN, in_input2, voltage_in[2]); 176show(IN, in_input2, voltage_in[2]);
@@ -200,6 +187,32 @@ show(RAW, alarms, alarms);
200show(BOOL, beep_enable, beep_enable); 187show(BOOL, beep_enable, beep_enable);
201show(BEEP_MASK, beep_mask, beep_mask); 188show(BEEP_MASK, beep_mask, beep_mask);
202 189
190static ssize_t show_fan_input(struct device *dev,
191 struct device_attribute *attr, char *buf)
192{
193 int nr = to_sensor_dev_attr(attr)->index;
194 struct gl518_data *data = gl518_update_device(dev);
195 return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_in[nr],
196 DIV_FROM_REG(data->fan_div[nr])));
197}
198
199static ssize_t show_fan_min(struct device *dev,
200 struct device_attribute *attr, char *buf)
201{
202 int nr = to_sensor_dev_attr(attr)->index;
203 struct gl518_data *data = gl518_update_device(dev);
204 return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr],
205 DIV_FROM_REG(data->fan_div[nr])));
206}
207
208static ssize_t show_fan_div(struct device *dev,
209 struct device_attribute *attr, char *buf)
210{
211 int nr = to_sensor_dev_attr(attr)->index;
212 struct gl518_data *data = gl518_update_device(dev);
213 return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
214}
215
203#define set(type, suffix, value, reg) \ 216#define set(type, suffix, value, reg) \
204static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \ 217static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, const char *buf, \
205 size_t count) \ 218 size_t count) \
@@ -241,8 +254,6 @@ static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, c
241set(TEMP, temp_max1, temp_max, GL518_REG_TEMP_MAX); 254set(TEMP, temp_max1, temp_max, GL518_REG_TEMP_MAX);
242set(TEMP, temp_hyst1, temp_hyst, GL518_REG_TEMP_HYST); 255set(TEMP, temp_hyst1, temp_hyst, GL518_REG_TEMP_HYST);
243set_bits(BOOL, fan_auto1, fan_auto1, GL518_REG_MISC, 0x08, 3); 256set_bits(BOOL, fan_auto1, fan_auto1, GL518_REG_MISC, 0x08, 3);
244set_bits(DIV, fan_div1, fan_div[0], GL518_REG_MISC, 0xc0, 6);
245set_bits(DIV, fan_div2, fan_div[1], GL518_REG_MISC, 0x30, 4);
246set_low(VDD, in_min0, voltage_min[0], GL518_REG_VDD_LIMIT); 257set_low(VDD, in_min0, voltage_min[0], GL518_REG_VDD_LIMIT);
247set_low(IN, in_min1, voltage_min[1], GL518_REG_VIN1_LIMIT); 258set_low(IN, in_min1, voltage_min[1], GL518_REG_VIN1_LIMIT);
248set_low(IN, in_min2, voltage_min[2], GL518_REG_VIN2_LIMIT); 259set_low(IN, in_min2, voltage_min[2], GL518_REG_VIN2_LIMIT);
@@ -254,25 +265,27 @@ set_high(IN, in_max3, voltage_max[3], GL518_REG_VIN3_LIMIT);
254set_bits(BOOL, beep_enable, beep_enable, GL518_REG_CONF, 0x04, 2); 265set_bits(BOOL, beep_enable, beep_enable, GL518_REG_CONF, 0x04, 2);
255set(BEEP_MASK, beep_mask, beep_mask, GL518_REG_ALARM); 266set(BEEP_MASK, beep_mask, beep_mask, GL518_REG_ALARM);
256 267
257static ssize_t set_fan_min1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 268static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
269 const char *buf, size_t count)
258{ 270{
259 struct i2c_client *client = to_i2c_client(dev); 271 struct i2c_client *client = to_i2c_client(dev);
260 struct gl518_data *data = i2c_get_clientdata(client); 272 struct gl518_data *data = i2c_get_clientdata(client);
273 int nr = to_sensor_dev_attr(attr)->index;
261 int regvalue; 274 int regvalue;
262 unsigned long val = simple_strtoul(buf, NULL, 10); 275 unsigned long val = simple_strtoul(buf, NULL, 10);
263 276
264 mutex_lock(&data->update_lock); 277 mutex_lock(&data->update_lock);
265 regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT); 278 regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT);
266 data->fan_min[0] = FAN_TO_REG(val, 279 data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
267 DIV_FROM_REG(data->fan_div[0])); 280 regvalue = (regvalue & (0xff << (8 * nr)))
268 regvalue = (regvalue & 0x00ff) | (data->fan_min[0] << 8); 281 | (data->fan_min[nr] << (8 * (1 - nr)));
269 gl518_write_value(client, GL518_REG_FAN_LIMIT, regvalue); 282 gl518_write_value(client, GL518_REG_FAN_LIMIT, regvalue);
270 283
271 data->beep_mask = gl518_read_value(client, GL518_REG_ALARM); 284 data->beep_mask = gl518_read_value(client, GL518_REG_ALARM);
272 if (data->fan_min[0] == 0) 285 if (data->fan_min[nr] == 0)
273 data->alarm_mask &= ~0x20; 286 data->alarm_mask &= ~(0x20 << nr);
274 else 287 else
275 data->alarm_mask |= 0x20; 288 data->alarm_mask |= (0x20 << nr);
276 data->beep_mask &= data->alarm_mask; 289 data->beep_mask &= data->alarm_mask;
277 gl518_write_value(client, GL518_REG_ALARM, data->beep_mask); 290 gl518_write_value(client, GL518_REG_ALARM, data->beep_mask);
278 291
@@ -280,28 +293,21 @@ static ssize_t set_fan_min1(struct device *dev, struct device_attribute *attr, c
280 return count; 293 return count;
281} 294}
282 295
283static ssize_t set_fan_min2(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 296static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
297 const char *buf, size_t count)
284{ 298{
285 struct i2c_client *client = to_i2c_client(dev); 299 struct i2c_client *client = to_i2c_client(dev);
286 struct gl518_data *data = i2c_get_clientdata(client); 300 struct gl518_data *data = i2c_get_clientdata(client);
301 int nr = to_sensor_dev_attr(attr)->index;
287 int regvalue; 302 int regvalue;
288 unsigned long val = simple_strtoul(buf, NULL, 10); 303 unsigned long val = simple_strtoul(buf, NULL, 10);
289 304
290 mutex_lock(&data->update_lock); 305 mutex_lock(&data->update_lock);
291 regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT); 306 regvalue = gl518_read_value(client, GL518_REG_MISC);
292 data->fan_min[1] = FAN_TO_REG(val, 307 data->fan_div[nr] = DIV_TO_REG(val);
293 DIV_FROM_REG(data->fan_div[1])); 308 regvalue = (regvalue & ~(0xc0 >> (2 * nr)))
294 regvalue = (regvalue & 0xff00) | data->fan_min[1]; 309 | (data->fan_div[nr] << (6 - 2 * nr));
295 gl518_write_value(client, GL518_REG_FAN_LIMIT, regvalue); 310 gl518_write_value(client, GL518_REG_MISC, regvalue);
296
297 data->beep_mask = gl518_read_value(client, GL518_REG_ALARM);
298 if (data->fan_min[1] == 0)
299 data->alarm_mask &= ~0x40;
300 else
301 data->alarm_mask |= 0x40;
302 data->beep_mask &= data->alarm_mask;
303 gl518_write_value(client, GL518_REG_ALARM, data->beep_mask);
304
305 mutex_unlock(&data->update_lock); 311 mutex_unlock(&data->update_lock);
306 return count; 312 return count;
307} 313}
@@ -311,12 +317,16 @@ static DEVICE_ATTR(temp1_max, S_IWUSR|S_IRUGO, show_temp_max1, set_temp_max1);
311static DEVICE_ATTR(temp1_max_hyst, S_IWUSR|S_IRUGO, 317static DEVICE_ATTR(temp1_max_hyst, S_IWUSR|S_IRUGO,
312 show_temp_hyst1, set_temp_hyst1); 318 show_temp_hyst1, set_temp_hyst1);
313static DEVICE_ATTR(fan1_auto, S_IWUSR|S_IRUGO, show_fan_auto1, set_fan_auto1); 319static DEVICE_ATTR(fan1_auto, S_IWUSR|S_IRUGO, show_fan_auto1, set_fan_auto1);
314static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input1, NULL); 320static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0);
315static DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input2, NULL); 321static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1);
316static DEVICE_ATTR(fan1_min, S_IWUSR|S_IRUGO, show_fan_min1, set_fan_min1); 322static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR|S_IRUGO,
317static DEVICE_ATTR(fan2_min, S_IWUSR|S_IRUGO, show_fan_min2, set_fan_min2); 323 show_fan_min, set_fan_min, 0);
318static DEVICE_ATTR(fan1_div, S_IWUSR|S_IRUGO, show_fan_div1, set_fan_div1); 324static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR|S_IRUGO,
319static DEVICE_ATTR(fan2_div, S_IWUSR|S_IRUGO, show_fan_div2, set_fan_div2); 325 show_fan_min, set_fan_min, 1);
326static SENSOR_DEVICE_ATTR(fan1_div, S_IWUSR|S_IRUGO,
327 show_fan_div, set_fan_div, 0);
328static SENSOR_DEVICE_ATTR(fan2_div, S_IWUSR|S_IRUGO,
329 show_fan_div, set_fan_div, 1);
320static DEVICE_ATTR(in0_input, S_IRUGO, show_in_input0, NULL); 330static DEVICE_ATTR(in0_input, S_IRUGO, show_in_input0, NULL);
321static DEVICE_ATTR(in1_input, S_IRUGO, show_in_input1, NULL); 331static DEVICE_ATTR(in1_input, S_IRUGO, show_in_input1, NULL);
322static DEVICE_ATTR(in2_input, S_IRUGO, show_in_input2, NULL); 332static DEVICE_ATTR(in2_input, S_IRUGO, show_in_input2, NULL);
@@ -347,12 +357,12 @@ static struct attribute *gl518_attributes[] = {
347 &dev_attr_in3_max.attr, 357 &dev_attr_in3_max.attr,
348 358
349 &dev_attr_fan1_auto.attr, 359 &dev_attr_fan1_auto.attr,
350 &dev_attr_fan1_input.attr, 360 &sensor_dev_attr_fan1_input.dev_attr.attr,
351 &dev_attr_fan2_input.attr, 361 &sensor_dev_attr_fan2_input.dev_attr.attr,
352 &dev_attr_fan1_min.attr, 362 &sensor_dev_attr_fan1_min.dev_attr.attr,
353 &dev_attr_fan2_min.attr, 363 &sensor_dev_attr_fan2_min.dev_attr.attr,
354 &dev_attr_fan1_div.attr, 364 &sensor_dev_attr_fan1_div.dev_attr.attr,
355 &dev_attr_fan2_div.attr, 365 &sensor_dev_attr_fan2_div.dev_attr.attr,
356 366
357 &dev_attr_temp1_input.attr, 367 &dev_attr_temp1_input.attr,
358 &dev_attr_temp1_max.attr, 368 &dev_attr_temp1_max.attr,