diff options
Diffstat (limited to 'drivers/hwmon/w83792d.c')
-rw-r--r-- | drivers/hwmon/w83792d.c | 83 |
1 files changed, 22 insertions, 61 deletions
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index 1ba072630361..b176bf0c4c7b 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c @@ -269,7 +269,6 @@ DIV_TO_REG(long val) struct w83792d_data { struct i2c_client client; struct class_device *class_dev; - struct semaphore lock; enum chips type; struct semaphore update_lock; @@ -282,7 +281,7 @@ struct w83792d_data { u8 in[9]; /* Register value */ u8 in_max[9]; /* Register value */ u8 in_min[9]; /* Register value */ - u8 low_bits[2]; /* Additional resolution to voltage in0-6 */ + u16 low_bits; /* Additional resolution to voltage in6-0 */ u8 fan[7]; /* Register value */ u8 fan_min[7]; /* Register value */ u8 temp1[3]; /* current, over, thyst */ @@ -317,45 +316,17 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev); static void w83792d_init_client(struct i2c_client *client); static struct i2c_driver w83792d_driver = { - .owner = THIS_MODULE, - .name = "w83792d", - .flags = I2C_DF_NOTIFY, + .driver = { + .name = "w83792d", + }, .attach_adapter = w83792d_attach_adapter, .detach_client = w83792d_detach_client, }; -static long in_count_from_reg(int nr, struct w83792d_data *data) +static inline long in_count_from_reg(int nr, struct w83792d_data *data) { - u16 vol_count = data->in[nr]; - u16 low_bits = 0; - vol_count = (vol_count << 2); - switch (nr) - { - case 0: /* vin0 */ - low_bits = (data->low_bits[0]) & 0x03; - break; - case 1: /* vin1 */ - low_bits = ((data->low_bits[0]) & 0x0c) >> 2; - break; - case 2: /* vin2 */ - low_bits = ((data->low_bits[0]) & 0x30) >> 4; - break; - case 3: /* vin3 */ - low_bits = ((data->low_bits[0]) & 0xc0) >> 6; - break; - case 4: /* vin4 */ - low_bits = (data->low_bits[1]) & 0x03; - break; - case 5: /* vin5 */ - low_bits = ((data->low_bits[1]) & 0x0c) >> 2; - break; - case 6: /* vin6 */ - low_bits = ((data->low_bits[1]) & 0x30) >> 4; - default: - break; - } - vol_count = vol_count | low_bits; - return vol_count; + /* in7 and in8 do not have low bits, but the formula still works */ + return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03)); } /* following are the sysfs callback functions */ @@ -1192,7 +1163,6 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) new_client = &data->client; i2c_set_clientdata(new_client, data); new_client->addr = address; - init_MUTEX(&data->lock); new_client->adapter = adapter; new_client->driver = &w83792d_driver; new_client->flags = 0; @@ -1243,7 +1213,7 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) goto ERROR1; } val1 = w83792d_read_value(new_client, W83792D_REG_WCHIPID); - if (val1 == 0x7a && address >= 0x2c) { + if (val1 == 0x7a) { kind = w83792d; } else { if (kind == 0) @@ -1416,26 +1386,17 @@ w83792d_detach_client(struct i2c_client *client) return 0; } -/* The SMBus locks itself, usually, but nothing may access the Winbond between - bank switches. ISA access must always be locked explicitly! - We ignore the W83792D BUSY flag at this moment - it could lead to deadlocks, - would slow down the W83792D access and should not be necessary. - There are some ugly typecasts here, but the good news is - they should - nowhere else be necessary! */ -static int -w83792d_read_value(struct i2c_client *client, u8 reg) +/* The SMBus locks itself. The Winbond W83792D chip has a bank register, + but the driver only accesses registers in bank 0, so we don't have + to switch banks and lock access between switches. */ +static int w83792d_read_value(struct i2c_client *client, u8 reg) { - int res=0; - res = i2c_smbus_read_byte_data(client, reg); - - return res; + return i2c_smbus_read_byte_data(client, reg); } -static int -w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) +static int w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) { - i2c_smbus_write_byte_data(client, reg, value); - return 0; + return i2c_smbus_write_byte_data(client, reg, value); } static void @@ -1492,10 +1453,10 @@ static struct w83792d_data *w83792d_update_device(struct device *dev) data->in_min[i] = w83792d_read_value(client, W83792D_REG_IN_MIN[i]); } - data->low_bits[0] = w83792d_read_value(client, - W83792D_REG_LOW_BITS1); - data->low_bits[1] = w83792d_read_value(client, - W83792D_REG_LOW_BITS2); + data->low_bits = w83792d_read_value(client, + W83792D_REG_LOW_BITS1) + + (w83792d_read_value(client, + W83792D_REG_LOW_BITS2) << 8); for (i = 0; i < 7; i++) { /* Update the Fan measured value and limits */ data->fan[i] = w83792d_read_value(client, @@ -1506,7 +1467,7 @@ static struct w83792d_data *w83792d_update_device(struct device *dev) pwm_array_tmp[i] = w83792d_read_value(client, W83792D_REG_PWM[i]); data->pwm[i] = pwm_array_tmp[i] & 0x0f; - data->pwm_mode[i] = (pwm_array_tmp[i] >> 7) & 0x01; + data->pwm_mode[i] = pwm_array_tmp[i] >> 7; } reg_tmp = w83792d_read_value(client, W83792D_REG_FAN_CFG); @@ -1607,8 +1568,8 @@ static void w83792d_print_debug(struct w83792d_data *data, struct device *dev) dev_dbg(dev, "vin[%d] max is: 0x%x\n", i, data->in_max[i]); dev_dbg(dev, "vin[%d] min is: 0x%x\n", i, data->in_min[i]); } - dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits[0]); - dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits[1]); + dev_dbg(dev, "Low Bit1 is: 0x%x\n", data->low_bits & 0xff); + dev_dbg(dev, "Low Bit2 is: 0x%x\n", data->low_bits >> 8); dev_dbg(dev, "7 set of Fan Counts and Duty Cycles: =====>\n"); for (i=0; i<7; i++) { dev_dbg(dev, "fan[%d] is: 0x%x\n", i, data->fan[i]); |