X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fhwmon%2Flm85.c;h=ee5eca1c1921d9d1f7ba1d67bd638ed9d6ba2cb2;hb=b2798bf0ec2cb5a17bfc1430c5ba6d971c436a03;hp=a02480be65f24db5e2c4fdca873d3b5682f92b10;hpb=62ee3e10d3ea11f50bcec8dffb46555fa16d417b;p=linux-2.6 diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index a02480be65..ee5eca1c19 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c @@ -35,7 +35,7 @@ #include /* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; +static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; /* Insmod parameters */ I2C_CLIENT_INSMOD_6(lm85b, lm85c, adm1027, adt7463, emc6d100, emc6d102); @@ -192,23 +192,20 @@ static int RANGE_TO_REG( int range ) { int i; - if ( range < lm85_range_map[0] ) { - return 0 ; - } else if ( range > lm85_range_map[15] ) { + if (range >= lm85_range_map[15]) return 15 ; - } else { /* find closest match */ - for ( i = 14 ; i >= 0 ; --i ) { - if ( range > lm85_range_map[i] ) { /* range bracketed */ - if ((lm85_range_map[i+1] - range) < - (range - lm85_range_map[i])) { - i++; - break; - } - break; - } + + /* Find the closest match */ + for (i = 14; i >= 0; --i) { + if (range >= lm85_range_map[i]) { + if ((lm85_range_map[i + 1] - range) < + (range - lm85_range_map[i])) + return i + 1; + return i; } } - return( i & 0x0f ); + + return 0; } #define RANGE_FROM_REG(val) (lm85_range_map[(val)&0x0f]) @@ -367,7 +364,6 @@ static struct i2c_driver lm85_driver = { .driver = { .name = "lm85", }, - .id = I2C_DRIVERID_LM85, .attach_adapter = lm85_attach_adapter, .detach_client = lm85_detach_client, }; @@ -444,12 +440,8 @@ static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, c static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct i2c_client *client = to_i2c_client(dev); - struct lm85_data *data = i2c_get_clientdata(client); - u32 val; - - val = simple_strtoul(buf, NULL, 10); - data->vrm = val; + struct lm85_data *data = dev_get_drvdata(dev); + data->vrm = simple_strtoul(buf, NULL, 10); return count; } @@ -519,17 +511,64 @@ static ssize_t show_pwm_enable(struct device *dev, struct device_attribute { int nr = to_sensor_dev_attr(attr)->index; struct lm85_data *data = lm85_update_device(dev); - int pwm_zone; + int pwm_zone, enable; pwm_zone = ZONE_FROM_REG(data->autofan[nr].config); - return sprintf(buf,"%d\n", (pwm_zone != 0 && pwm_zone != -1) ); + switch (pwm_zone) { + case -1: /* PWM is always at 100% */ + enable = 0; + break; + case 0: /* PWM is always at 0% */ + case -2: /* PWM responds to manual control */ + enable = 1; + break; + default: /* PWM in automatic mode */ + enable = 2; + } + return sprintf(buf, "%d\n", enable); +} + +static ssize_t set_pwm_enable(struct device *dev, struct device_attribute + *attr, const char *buf, size_t count) +{ + int nr = to_sensor_dev_attr(attr)->index; + struct i2c_client *client = to_i2c_client(dev); + struct lm85_data *data = i2c_get_clientdata(client); + long val = simple_strtol(buf, NULL, 10); + u8 config; + + switch (val) { + case 0: + config = 3; + break; + case 1: + config = 7; + break; + case 2: + /* Here we have to choose arbitrarily one of the 5 possible + configurations; I go for the safest */ + config = 6; + break; + default: + return -EINVAL; + } + + mutex_lock(&data->update_lock); + data->autofan[nr].config = lm85_read_value(client, + LM85_REG_AFAN_CONFIG(nr)); + data->autofan[nr].config = (data->autofan[nr].config & ~0xe0) + | (config << 5); + lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr), + data->autofan[nr].config); + mutex_unlock(&data->update_lock); + return count; } #define show_pwm_reg(offset) \ static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ show_pwm, set_pwm, offset - 1); \ -static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO, \ - show_pwm_enable, NULL, offset - 1) +static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ + show_pwm_enable, set_pwm_enable, offset - 1) show_pwm_reg(1); show_pwm_reg(2);