diff --git a/TODO b/TODO index faae3892..eafa5a3a 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,7 @@ Many, many things. Most notably: * Check whether the FAN count divisors in the lm78 module are correct - (probably not!) + (probably not!); correct gl518sm changed-fan_div_but_did_not_update_fans * Wouldn't it be better to display all natural voltages for the LM78 chip, and do *all* conversions through a user program? * kmalloc with GFP_KERNEL can cause a context switch! Check whether this is diff --git a/kernel/chips/gl518sm.c b/kernel/chips/gl518sm.c index 36080aec..34fbc42e 100644 --- a/kernel/chips/gl518sm.c +++ b/kernel/chips/gl518sm.c @@ -132,6 +132,7 @@ static int gl518_command(struct i2c_client *client, unsigned int cmd, void *arg); static void gl518_inc_use (struct i2c_client *client); static void gl518_dec_use (struct i2c_client *client); +static u16 swap_bytes(u16 val); static int gl518_read_value(struct i2c_client *client, u8 reg); static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value); static void gl518_update_client(struct i2c_client *client); @@ -362,19 +363,30 @@ void gl518_dec_use (struct i2c_client *client) #endif } -/* Registers 0x07 to 0x0c are word-sized, others are byte-sized */ +u16 swap_bytes(u16 val) +{ + return (val >> 8) | (val << 8); +} + +/* Registers 0x07 to 0x0c are word-sized, others are byte-sized + GL518 uses a high-byte first convention, which is exactly opposite to + the usual practice. */ int gl518_read_value(struct i2c_client *client, u8 reg) { if ((reg >= 0x07) && (reg <= 0x0c)) - return smbus_read_word_data(client->adapter,client->addr,reg); + return swap_bytes(smbus_read_word_data(client->adapter,client->addr,reg)); else return smbus_read_byte_data(client->adapter,client->addr,reg); } +/* Registers 0x07 to 0x0c are word-sized, others are byte-sized + GL518 uses a high-byte first convention, which is exactly opposite to + the usual practice. */ int gl518_write_value(struct i2c_client *client, u8 reg, u16 value) { if ((reg >= 0x07) && (reg <= 0x0c)) - return smbus_write_word_data(client->adapter,client->addr,reg,value); + return smbus_write_word_data(client->adapter,client->addr,reg, + swap_bytes(value)); else return smbus_write_byte_data(client->adapter,client->addr,reg,value); } diff --git a/kernel/chips/lm75.c b/kernel/chips/lm75.c index 71d68495..6e7f6adf 100644 --- a/kernel/chips/lm75.c +++ b/kernel/chips/lm75.c @@ -242,8 +242,8 @@ u16 swap_bytes(u16 val) } /* All registers are word-sized, except for the configuration register. - For some reason, we must swap the low and high byte, but only on - reading words?!? */ + LM75 uses a high-byte first convention, which is exactly opposite to + the usual practice. */ int lm75_read_value(struct i2c_client *client, u8 reg) { if (reg == LM75_REG_CONF) @@ -252,13 +252,16 @@ int lm75_read_value(struct i2c_client *client, u8 reg) return swap_bytes(smbus_read_word_data(client->adapter,client->addr,reg)); } -/* No swapping needed here! */ +/* All registers are word-sized, except for the configuration register. + LM75 uses a high-byte first convention, which is exactly opposite to + the usual practice. */ int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) { if (reg == LM75_REG_CONF) return smbus_write_byte_data(client->adapter,client->addr,reg,value); else - return smbus_write_word_data(client->adapter,client->addr,reg,value); + return smbus_write_word_data(client->adapter,client->addr,reg, + swap_bytes(value)); } void lm75_update_client(struct i2c_client *client) diff --git a/src/gl518sm.c b/src/gl518sm.c index 36080aec..34fbc42e 100644 --- a/src/gl518sm.c +++ b/src/gl518sm.c @@ -132,6 +132,7 @@ static int gl518_command(struct i2c_client *client, unsigned int cmd, void *arg); static void gl518_inc_use (struct i2c_client *client); static void gl518_dec_use (struct i2c_client *client); +static u16 swap_bytes(u16 val); static int gl518_read_value(struct i2c_client *client, u8 reg); static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value); static void gl518_update_client(struct i2c_client *client); @@ -362,19 +363,30 @@ void gl518_dec_use (struct i2c_client *client) #endif } -/* Registers 0x07 to 0x0c are word-sized, others are byte-sized */ +u16 swap_bytes(u16 val) +{ + return (val >> 8) | (val << 8); +} + +/* Registers 0x07 to 0x0c are word-sized, others are byte-sized + GL518 uses a high-byte first convention, which is exactly opposite to + the usual practice. */ int gl518_read_value(struct i2c_client *client, u8 reg) { if ((reg >= 0x07) && (reg <= 0x0c)) - return smbus_read_word_data(client->adapter,client->addr,reg); + return swap_bytes(smbus_read_word_data(client->adapter,client->addr,reg)); else return smbus_read_byte_data(client->adapter,client->addr,reg); } +/* Registers 0x07 to 0x0c are word-sized, others are byte-sized + GL518 uses a high-byte first convention, which is exactly opposite to + the usual practice. */ int gl518_write_value(struct i2c_client *client, u8 reg, u16 value) { if ((reg >= 0x07) && (reg <= 0x0c)) - return smbus_write_word_data(client->adapter,client->addr,reg,value); + return smbus_write_word_data(client->adapter,client->addr,reg, + swap_bytes(value)); else return smbus_write_byte_data(client->adapter,client->addr,reg,value); } diff --git a/src/lm75.c b/src/lm75.c index 71d68495..6e7f6adf 100644 --- a/src/lm75.c +++ b/src/lm75.c @@ -242,8 +242,8 @@ u16 swap_bytes(u16 val) } /* All registers are word-sized, except for the configuration register. - For some reason, we must swap the low and high byte, but only on - reading words?!? */ + LM75 uses a high-byte first convention, which is exactly opposite to + the usual practice. */ int lm75_read_value(struct i2c_client *client, u8 reg) { if (reg == LM75_REG_CONF) @@ -252,13 +252,16 @@ int lm75_read_value(struct i2c_client *client, u8 reg) return swap_bytes(smbus_read_word_data(client->adapter,client->addr,reg)); } -/* No swapping needed here! */ +/* All registers are word-sized, except for the configuration register. + LM75 uses a high-byte first convention, which is exactly opposite to + the usual practice. */ int lm75_write_value(struct i2c_client *client, u8 reg, u16 value) { if (reg == LM75_REG_CONF) return smbus_write_byte_data(client->adapter,client->addr,reg,value); else - return smbus_write_word_data(client->adapter,client->addr,reg,value); + return smbus_write_word_data(client->adapter,client->addr,reg, + swap_bytes(value)); } void lm75_update_client(struct i2c_client *client)