mirror of
https://github.com/lm-sensors/lm-sensors.git
synced 2026-11-13 17:00:15 +00:00
Fixed a byte swapping bug in both the LM75 and the GL518SM drivers.
Strangly enough, both these devices use a high byte, low byte order for word-sized reads and writes. The SMBus documentation specifies the reverse (low, high) order, though. If all devices use the high,low order, we should change this in smbus.c. git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@64 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
1 parent
3b1432c71e
commit
89e2183261
5 files changed
+45
-15
No files matched your search
@@ -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
|
||||
|
||||
+15
-3
@@ -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);
|
||||
}
|
||||
|
||||
+7
-4
@@ -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)
|
||||
|
||||
+15
-3
@@ -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);
|
||||
}
|
||||
|
||||
+7
-4
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user