diff options
-rw-r--r-- | drivers/hwmon/f75375s.c | 42 | ||||
-rw-r--r-- | include/linux/f75375s.h | 21 |
2 files changed, 56 insertions, 7 deletions
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 19b3427b5e9e..472b052770d3 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/i2c.h> | 34 | #include <linux/i2c.h> |
35 | #include <linux/err.h> | 35 | #include <linux/err.h> |
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/f75375s.h> | ||
37 | 38 | ||
38 | /* Addresses to scan */ | 39 | /* Addresses to scan */ |
39 | static unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; | 40 | static unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; |
@@ -286,19 +287,14 @@ static ssize_t show_pwm_enable(struct device *dev, struct device_attribute | |||
286 | return sprintf(buf, "%d\n", data->pwm_enable[nr]); | 287 | return sprintf(buf, "%d\n", data->pwm_enable[nr]); |
287 | } | 288 | } |
288 | 289 | ||
289 | static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, | 290 | static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) |
290 | const char *buf, size_t count) | ||
291 | { | 291 | { |
292 | int nr = to_sensor_dev_attr(attr)->index; | ||
293 | struct i2c_client *client = to_i2c_client(dev); | ||
294 | struct f75375_data *data = i2c_get_clientdata(client); | 292 | struct f75375_data *data = i2c_get_clientdata(client); |
295 | int val = simple_strtoul(buf, NULL, 10); | ||
296 | u8 fanmode; | 293 | u8 fanmode; |
297 | 294 | ||
298 | if (val < 0 || val > 4) | 295 | if (val < 0 || val > 4) |
299 | return -EINVAL; | 296 | return -EINVAL; |
300 | 297 | ||
301 | mutex_lock(&data->update_lock); | ||
302 | fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); | 298 | fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); |
303 | fanmode = ~(3 << FAN_CTRL_MODE(nr)); | 299 | fanmode = ~(3 << FAN_CTRL_MODE(nr)); |
304 | 300 | ||
@@ -320,8 +316,22 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, | |||
320 | } | 316 | } |
321 | f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); | 317 | f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); |
322 | data->pwm_enable[nr] = val; | 318 | data->pwm_enable[nr] = val; |
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, | ||
323 | const char *buf, size_t count) | ||
324 | { | ||
325 | int nr = to_sensor_dev_attr(attr)->index; | ||
326 | struct i2c_client *client = to_i2c_client(dev); | ||
327 | struct f75375_data *data = i2c_get_clientdata(client); | ||
328 | int val = simple_strtoul(buf, NULL, 10); | ||
329 | int err = 0; | ||
330 | |||
331 | mutex_lock(&data->update_lock); | ||
332 | err = set_pwm_enable_direct(client, nr, val); | ||
323 | mutex_unlock(&data->update_lock); | 333 | mutex_unlock(&data->update_lock); |
324 | return count; | 334 | return err ? err : count; |
325 | } | 335 | } |
326 | 336 | ||
327 | static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr, | 337 | static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr, |
@@ -604,9 +614,24 @@ static int f75375_detach_client(struct i2c_client *client) | |||
604 | return 0; | 614 | return 0; |
605 | } | 615 | } |
606 | 616 | ||
617 | static void f75375_init(struct i2c_client *client, struct f75375_data *data, | ||
618 | struct f75375s_platform_data *f75375s_pdata) | ||
619 | { | ||
620 | int nr; | ||
621 | set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]); | ||
622 | set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]); | ||
623 | for (nr = 0; nr < 2; nr++) { | ||
624 | data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255); | ||
625 | f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), | ||
626 | data->pwm[nr]); | ||
627 | } | ||
628 | |||
629 | } | ||
630 | |||
607 | static int f75375_probe(struct i2c_client *client) | 631 | static int f75375_probe(struct i2c_client *client) |
608 | { | 632 | { |
609 | struct f75375_data *data = i2c_get_clientdata(client); | 633 | struct f75375_data *data = i2c_get_clientdata(client); |
634 | struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data; | ||
610 | int err; | 635 | int err; |
611 | 636 | ||
612 | if (!i2c_check_functionality(client->adapter, | 637 | if (!i2c_check_functionality(client->adapter, |
@@ -637,6 +662,9 @@ static int f75375_probe(struct i2c_client *client) | |||
637 | goto exit_remove; | 662 | goto exit_remove; |
638 | } | 663 | } |
639 | 664 | ||
665 | if (f75375s_pdata != NULL) | ||
666 | f75375_init(client, data, f75375s_pdata); | ||
667 | |||
640 | return 0; | 668 | return 0; |
641 | 669 | ||
642 | exit_remove: | 670 | exit_remove: |
diff --git a/include/linux/f75375s.h b/include/linux/f75375s.h new file mode 100644 index 000000000000..e99e22500668 --- /dev/null +++ b/include/linux/f75375s.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * f75375s.h - platform data structure for f75375s sensor | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2007, Riku Voipio <riku.voipio@iki.fi> | ||
9 | */ | ||
10 | |||
11 | #ifndef __LINUX_F75375S_H | ||
12 | #define __LINUX_F75375S_H | ||
13 | |||
14 | /* We want to set fans spinning on systems where there is no | ||
15 | * BIOS to do that for us */ | ||
16 | struct f75375s_platform_data { | ||
17 | u8 pwm[2]; | ||
18 | u8 pwm_enable[2]; | ||
19 | }; | ||
20 | |||
21 | #endif /* __LINUX_F75375S_H */ | ||