X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fi2c%2Fchips%2Flm80.c;h=c13d515c54ec52fececc62f8a14034f8d2eae0de;hb=f1227cd3e0e73c48b93368800aa89f4341103a00;hp=a72f431971bb6351872dfeef29e539fdde26658d;hpb=340e2b1a4c74f653454348914c408420d5d3c28a;p=linux-2.6.git diff --git a/drivers/i2c/chips/lm80.c b/drivers/i2c/chips/lm80.c index a72f43197..c13d515c5 100644 --- a/drivers/i2c/chips/lm80.c +++ b/drivers/i2c/chips/lm80.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -100,7 +99,10 @@ static inline long TEMP_FROM_REG(u16 temp) #define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val)<0?\ ((val)-500)/1000:((val)+500)/1000,0,255) +#define ALARMS_FROM_REG(val) (val) + #define DIV_FROM_REG(val) (1 << (val)) +#define DIV_TO_REG(val) ((val)==8?3:(val)==4?2:(val)==1?0:1) /* * Client data (each client gets its own) @@ -138,6 +140,12 @@ static struct lm80_data *lm80_update_device(struct device *dev); static int lm80_read_value(struct i2c_client *client, u8 reg); static int lm80_write_value(struct i2c_client *client, u8 reg, u8 value); +/* + * Internal variables + */ + +static int lm80_id; + /* * Driver data (common to all clients) */ @@ -190,11 +198,8 @@ static ssize_t set_in_##suffix(struct device *dev, const char *buf, \ struct i2c_client *client = to_i2c_client(dev); \ struct lm80_data *data = i2c_get_clientdata(client); \ long val = simple_strtol(buf, NULL, 10); \ - \ - down(&data->update_lock);\ data->value = IN_TO_REG(val); \ lm80_write_value(client, reg, data->value); \ - up(&data->update_lock);\ return count; \ } set_in(min0, in_min[0], LM80_REG_IN_MIN(0)); @@ -240,11 +245,8 @@ static ssize_t set_fan_##suffix(struct device *dev, const char *buf, \ struct i2c_client *client = to_i2c_client(dev); \ struct lm80_data *data = i2c_get_clientdata(client); \ long val = simple_strtoul(buf, NULL, 10); \ - \ - down(&data->update_lock);\ data->value = FAN_TO_REG(val, DIV_FROM_REG(data->div)); \ lm80_write_value(client, reg, data->value); \ - up(&data->update_lock);\ return count; \ } set_fan(min1, fan_min[0], LM80_REG_FAN_MIN(1), fan_div[0]); @@ -259,25 +261,15 @@ static ssize_t set_fan_div(struct device *dev, const char *buf, { struct i2c_client *client = to_i2c_client(dev); struct lm80_data *data = i2c_get_clientdata(client); - unsigned long min, val = simple_strtoul(buf, NULL, 10); + unsigned long min, val; u8 reg; /* Save fan_min */ - down(&data->update_lock); min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); - switch (val) { - case 1: data->fan_div[nr] = 0; break; - case 2: data->fan_div[nr] = 1; break; - case 4: data->fan_div[nr] = 2; break; - case 8: data->fan_div[nr] = 3; break; - default: - dev_err(&client->dev, "fan_div value %ld not " - "supported. Choose one of 1, 2, 4 or 8!\n", val); - up(&data->update_lock); - return -EINVAL; - } + val = simple_strtoul(buf, NULL, 10); + data->fan_div[nr] = DIV_TO_REG(val); reg = (lm80_read_value(client, LM80_REG_FANDIV) & ~(3 << (2 * (nr + 1)))) | (data->fan_div[nr] << (2 * (nr + 1))); @@ -286,7 +278,6 @@ static ssize_t set_fan_div(struct device *dev, const char *buf, /* Restore fan_min */ data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); lm80_write_value(client, LM80_REG_FAN_MIN(nr + 1), data->fan_min[nr]); - up(&data->update_lock); return count; } @@ -324,11 +315,8 @@ static ssize_t set_temp_##suffix(struct device *dev, const char *buf, \ struct i2c_client *client = to_i2c_client(dev); \ struct lm80_data *data = i2c_get_clientdata(client); \ long val = simple_strtoul(buf, NULL, 10); \ - \ - down(&data->update_lock); \ data->value = TEMP_LIMIT_TO_REG(val); \ lm80_write_value(client, reg, data->value); \ - up(&data->update_lock); \ return count; \ } set_temp(hot_max, temp_hot_max, LM80_REG_TEMP_HOT_MAX); @@ -339,7 +327,7 @@ set_temp(os_hyst, temp_os_hyst, LM80_REG_TEMP_OS_HYST); static ssize_t show_alarms(struct device *dev, char *buf) { struct lm80_data *data = lm80_update_device(dev); - return sprintf(buf, "%u\n", data->alarms); + return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->alarms)); } static DEVICE_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min0, set_in_min0); @@ -437,6 +425,8 @@ int lm80_detect(struct i2c_adapter *adapter, int address, int kind) /* Fill in the remaining client fields and put it into the global list */ strlcpy(new_client->name, name, I2C_NAME_SIZE); + + new_client->id = lm80_id++; data->valid = 0; init_MUTEX(&data->update_lock); @@ -540,7 +530,9 @@ static struct lm80_data *lm80_update_device(struct device *dev) down(&data->update_lock); - if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) { + if ((jiffies - data->last_updated > 2 * HZ) || + (jiffies < data->last_updated) || !data->valid) { + dev_dbg(&client->dev, "Starting lm80 update\n"); for (i = 0; i <= 6; i++) { data->in[i] =