Loading drivers/hwmon/lm90.c +265 −276 Original line number Diff line number Diff line Loading @@ -163,21 +163,6 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, #define LM90_HAVE_EMERGENCY_ALARM (1 << 5)/* emergency alarm */ #define LM90_HAVE_TEMP3 (1 << 6) /* 3rd temperature sensor */ /* * Functions declaration */ static int lm90_detect(struct i2c_client *client, struct i2c_board_info *info); static int lm90_probe(struct i2c_client *client, const struct i2c_device_id *id); static void lm90_init_client(struct i2c_client *client); static void lm90_alert(struct i2c_client *client, unsigned int flag); static int lm90_remove(struct i2c_client *client); static struct lm90_data *lm90_update_device(struct device *dev); static inline void lm90_select_remote_channel(struct i2c_client *client, struct lm90_data *data, int channel); /* * Driver data (common to all clients) */ Loading @@ -204,19 +189,6 @@ static const struct i2c_device_id lm90_id[] = { }; MODULE_DEVICE_TABLE(i2c, lm90_id); static struct i2c_driver lm90_driver = { .class = I2C_CLASS_HWMON, .driver = { .name = "lm90", }, .probe = lm90_probe, .remove = lm90_remove, .alert = lm90_alert, .id_table = lm90_id, .detect = lm90_detect, .address_list = normal_i2c, }; /* * Client data (each client gets its own) */ Loading Loading @@ -255,6 +227,209 @@ struct lm90_data { u16 alarms; /* bitvector (upper 8 bits for max6695/96) */ }; /* * Support functions */ /* * The ADM1032 supports PEC but not on write byte transactions, so we need * to explicitly ask for a transaction without PEC. */ static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value) { return i2c_smbus_xfer(client->adapter, client->addr, client->flags & ~I2C_CLIENT_PEC, I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); } /* * It is assumed that client->update_lock is held (unless we are in * detection or initialization steps). This matters when PEC is enabled, * because we don't want the address pointer to change between the write * byte and the read byte transactions. */ static int lm90_read_reg(struct i2c_client *client, u8 reg, u8 *value) { int err; if (client->flags & I2C_CLIENT_PEC) { err = adm1032_write_byte(client, reg); if (err >= 0) err = i2c_smbus_read_byte(client); } else err = i2c_smbus_read_byte_data(client, reg); if (err < 0) { dev_warn(&client->dev, "Register %#02x read failed (%d)\n", reg, err); return err; } *value = err; return 0; } static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value) { int err; u8 oldh, newh, l; /* * There is a trick here. We have to read two registers to have the * sensor temperature, but we have to beware a conversion could occur * inbetween the readings. The datasheet says we should either use * the one-shot conversion register, which we don't want to do * (disables hardware monitoring) or monitor the busy bit, which is * impossible (we can't read the values and monitor that bit at the * exact same time). So the solution used here is to read the high * byte once, then the low byte, then the high byte again. If the new * high byte matches the old one, then we have a valid reading. Else * we have to read the low byte again, and now we believe we have a * correct reading. */ if ((err = lm90_read_reg(client, regh, &oldh)) || (err = lm90_read_reg(client, regl, &l)) || (err = lm90_read_reg(client, regh, &newh))) return err; if (oldh != newh) { err = lm90_read_reg(client, regl, &l); if (err) return err; } *value = (newh << 8) | l; return 0; } /* * client->update_lock must be held when calling this function (unless we are * in detection or initialization steps), and while a remote channel other * than channel 0 is selected. Also, calling code must make sure to re-select * external channel 0 before releasing the lock. This is necessary because * various registers have different meanings as a result of selecting a * non-default remote channel. */ static inline void lm90_select_remote_channel(struct i2c_client *client, struct lm90_data *data, int channel) { u8 config; if (data->kind == max6696) { lm90_read_reg(client, LM90_REG_R_CONFIG1, &config); config &= ~0x08; if (channel) config |= 0x08; i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); } } static struct lm90_data *lm90_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct lm90_data *data = i2c_get_clientdata(client); mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ / 2 + HZ / 10) || !data->valid) { u8 h, l; u8 alarms; dev_dbg(&client->dev, "Updating lm90 data.\n"); lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[0]); lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[1]); lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[2]); lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[3]); lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); if (data->flags & LM90_HAVE_LOCAL_EXT) { lm90_read16(client, LM90_REG_R_LOCAL_TEMP, MAX6657_REG_R_LOCAL_TEMPL, &data->temp11[4]); } else { if (lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &h) == 0) data->temp11[4] = h << 8; } lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, LM90_REG_R_REMOTE_TEMPL, &data->temp11[0]); if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h) == 0) { data->temp11[1] = h << 8; if ((data->flags & LM90_HAVE_REM_LIMIT_EXT) && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, &l) == 0) data->temp11[1] |= l; } if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h) == 0) { data->temp11[2] = h << 8; if ((data->flags & LM90_HAVE_REM_LIMIT_EXT) && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0) data->temp11[2] |= l; } if (data->flags & LM90_HAVE_OFFSET) { if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH, &h) == 0 && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL, &l) == 0) data->temp11[3] = (h << 8) | l; } if (data->flags & LM90_HAVE_EMERGENCY) { lm90_read_reg(client, MAX6659_REG_R_LOCAL_EMERG, &data->temp8[4]); lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG, &data->temp8[5]); } lm90_read_reg(client, LM90_REG_R_STATUS, &alarms); data->alarms = alarms; /* save as 16 bit value */ if (data->kind == max6696) { lm90_select_remote_channel(client, data, 1); lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[6]); lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG, &data->temp8[7]); lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, LM90_REG_R_REMOTE_TEMPL, &data->temp11[5]); if (!lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h)) data->temp11[6] = h << 8; if (!lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h)) data->temp11[7] = h << 8; lm90_select_remote_channel(client, data, 0); if (!lm90_read_reg(client, MAX6696_REG_R_STATUS2, &alarms)) data->alarms |= alarms << 8; } /* Re-enable ALERT# output if it was originally enabled and * relevant alarms are all clear */ if ((data->config_orig & 0x80) == 0 && (data->alarms & data->alert_alarms) == 0) { u8 config; lm90_read_reg(client, LM90_REG_R_CONFIG1, &config); if (config & 0x80) { dev_dbg(&client->dev, "Re-enabling ALERT#\n"); i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config & ~0x80); } } data->last_updated = jiffies; data->valid = 1; } mutex_unlock(&data->update_lock); return data; } /* * Conversions * For local temperatures and limits, critical limits and the hysteresis Loading Loading @@ -770,79 +945,17 @@ static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec); * Real code */ /* * The ADM1032 supports PEC but not on write byte transactions, so we need * to explicitly ask for a transaction without PEC. */ static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value) { return i2c_smbus_xfer(client->adapter, client->addr, client->flags & ~I2C_CLIENT_PEC, I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); } /* * It is assumed that client->update_lock is held (unless we are in * detection or initialization steps). This matters when PEC is enabled, * because we don't want the address pointer to change between the write * byte and the read byte transactions. */ static int lm90_read_reg(struct i2c_client *client, u8 reg, u8 *value) /* Return 0 if detection is successful, -ENODEV otherwise */ static int lm90_detect(struct i2c_client *new_client, struct i2c_board_info *info) { int err; struct i2c_adapter *adapter = new_client->adapter; int address = new_client->addr; const char *name = NULL; int man_id, chip_id, reg_config1, reg_convrate; if (client->flags & I2C_CLIENT_PEC) { err = adm1032_write_byte(client, reg); if (err >= 0) err = i2c_smbus_read_byte(client); } else err = i2c_smbus_read_byte_data(client, reg); if (err < 0) { dev_warn(&client->dev, "Register %#02x read failed (%d)\n", reg, err); return err; } *value = err; return 0; } /* * client->update_lock must be held when calling this function (unless we are * in detection or initialization steps), and while a remote channel other * than channel 0 is selected. Also, calling code must make sure to re-select * external channel 0 before releasing the lock. This is necessary because * various registers have different meanings as a result of selecting a * non-default remote channel. */ static inline void lm90_select_remote_channel(struct i2c_client *client, struct lm90_data *data, int channel) { u8 config; if (data->kind == max6696) { lm90_read_reg(client, LM90_REG_R_CONFIG1, &config); config &= ~0x08; if (channel) config |= 0x08; i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); } } /* Return 0 if detection is successful, -ENODEV otherwise */ static int lm90_detect(struct i2c_client *new_client, struct i2c_board_info *info) { struct i2c_adapter *adapter = new_client->adapter; int address = new_client->addr; const char *name = NULL; int man_id, chip_id, reg_config1, reg_convrate; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; /* detection and identification */ if ((man_id = i2c_smbus_read_byte_data(new_client, Loading Loading @@ -1023,6 +1136,47 @@ static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data) sysfs_remove_group(&client->dev.kobj, &lm90_group); } static void lm90_init_client(struct i2c_client *client) { u8 config; struct lm90_data *data = i2c_get_clientdata(client); /* * Start the conversions. */ i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, 5); /* 2 Hz */ if (lm90_read_reg(client, LM90_REG_R_CONFIG1, &config) < 0) { dev_warn(&client->dev, "Initialization failed!\n"); return; } data->config_orig = config; /* Check Temperature Range Select */ if (data->kind == adt7461) { if (config & 0x04) data->flags |= LM90_FLAG_ADT7461_EXT; } /* * Put MAX6680/MAX8881 into extended resolution (bit 0x10, * 0.125 degree resolution) and range (0x08, extend range * to -64 degree) mode for the remote temperature sensor. */ if (data->kind == max6680) config |= 0x18; /* * Select external channel 0 for max6695/96 */ if (data->kind == max6696) config &= ~0x08; config &= 0xBF; /* run */ if (config != data->config_orig) /* Only write if changed */ i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); } static int lm90_probe(struct i2c_client *new_client, const struct i2c_device_id *id) { Loading Loading @@ -1134,47 +1288,6 @@ static int lm90_probe(struct i2c_client *new_client, return err; } static void lm90_init_client(struct i2c_client *client) { u8 config; struct lm90_data *data = i2c_get_clientdata(client); /* * Start the conversions. */ i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, 5); /* 2 Hz */ if (lm90_read_reg(client, LM90_REG_R_CONFIG1, &config) < 0) { dev_warn(&client->dev, "Initialization failed!\n"); return; } data->config_orig = config; /* Check Temperature Range Select */ if (data->kind == adt7461) { if (config & 0x04) data->flags |= LM90_FLAG_ADT7461_EXT; } /* * Put MAX6680/MAX8881 into extended resolution (bit 0x10, * 0.125 degree resolution) and range (0x08, extend range * to -64 degree) mode for the remote temperature sensor. */ if (data->kind == max6680) config |= 0x18; /* * Select external channel 0 for max6695/96 */ if (data->kind == max6696) config &= ~0x08; config &= 0xBF; /* run */ if (config != data->config_orig) /* Only write if changed */ i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); } static int lm90_remove(struct i2c_client *client) { struct lm90_data *data = i2c_get_clientdata(client); Loading Loading @@ -1230,142 +1343,18 @@ static void lm90_alert(struct i2c_client *client, unsigned int flag) } } static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value) { int err; u8 oldh, newh, l; /* * There is a trick here. We have to read two registers to have the * sensor temperature, but we have to beware a conversion could occur * inbetween the readings. The datasheet says we should either use * the one-shot conversion register, which we don't want to do * (disables hardware monitoring) or monitor the busy bit, which is * impossible (we can't read the values and monitor that bit at the * exact same time). So the solution used here is to read the high * byte once, then the low byte, then the high byte again. If the new * high byte matches the old one, then we have a valid reading. Else * we have to read the low byte again, and now we believe we have a * correct reading. */ if ((err = lm90_read_reg(client, regh, &oldh)) || (err = lm90_read_reg(client, regl, &l)) || (err = lm90_read_reg(client, regh, &newh))) return err; if (oldh != newh) { err = lm90_read_reg(client, regl, &l); if (err) return err; } *value = (newh << 8) | l; return 0; } static struct lm90_data *lm90_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct lm90_data *data = i2c_get_clientdata(client); mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ / 2 + HZ / 10) || !data->valid) { u8 h, l; u8 alarms; dev_dbg(&client->dev, "Updating lm90 data.\n"); lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[0]); lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[1]); lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[2]); lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[3]); lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); if (data->flags & LM90_HAVE_LOCAL_EXT) { lm90_read16(client, LM90_REG_R_LOCAL_TEMP, MAX6657_REG_R_LOCAL_TEMPL, &data->temp11[4]); } else { if (lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &h) == 0) data->temp11[4] = h << 8; } lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, LM90_REG_R_REMOTE_TEMPL, &data->temp11[0]); if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h) == 0) { data->temp11[1] = h << 8; if ((data->flags & LM90_HAVE_REM_LIMIT_EXT) && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, &l) == 0) data->temp11[1] |= l; } if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h) == 0) { data->temp11[2] = h << 8; if ((data->flags & LM90_HAVE_REM_LIMIT_EXT) && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0) data->temp11[2] |= l; } if (data->flags & LM90_HAVE_OFFSET) { if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH, &h) == 0 && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL, &l) == 0) data->temp11[3] = (h << 8) | l; } if (data->flags & LM90_HAVE_EMERGENCY) { lm90_read_reg(client, MAX6659_REG_R_LOCAL_EMERG, &data->temp8[4]); lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG, &data->temp8[5]); } lm90_read_reg(client, LM90_REG_R_STATUS, &alarms); data->alarms = alarms; /* save as 16 bit value */ if (data->kind == max6696) { lm90_select_remote_channel(client, data, 1); lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[6]); lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG, &data->temp8[7]); lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, LM90_REG_R_REMOTE_TEMPL, &data->temp11[5]); if (!lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h)) data->temp11[6] = h << 8; if (!lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h)) data->temp11[7] = h << 8; lm90_select_remote_channel(client, data, 0); if (!lm90_read_reg(client, MAX6696_REG_R_STATUS2, &alarms)) data->alarms |= alarms << 8; } /* Re-enable ALERT# output if it was originally enabled and * relevant alarms are all clear */ if ((data->config_orig & 0x80) == 0 && (data->alarms & data->alert_alarms) == 0) { u8 config; lm90_read_reg(client, LM90_REG_R_CONFIG1, &config); if (config & 0x80) { dev_dbg(&client->dev, "Re-enabling ALERT#\n"); i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config & ~0x80); } } data->last_updated = jiffies; data->valid = 1; } mutex_unlock(&data->update_lock); return data; } static struct i2c_driver lm90_driver = { .class = I2C_CLASS_HWMON, .driver = { .name = "lm90", }, .probe = lm90_probe, .remove = lm90_remove, .alert = lm90_alert, .id_table = lm90_id, .detect = lm90_detect, .address_list = normal_i2c, }; static int __init sensors_lm90_init(void) { Loading Loading
drivers/hwmon/lm90.c +265 −276 Original line number Diff line number Diff line Loading @@ -163,21 +163,6 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, #define LM90_HAVE_EMERGENCY_ALARM (1 << 5)/* emergency alarm */ #define LM90_HAVE_TEMP3 (1 << 6) /* 3rd temperature sensor */ /* * Functions declaration */ static int lm90_detect(struct i2c_client *client, struct i2c_board_info *info); static int lm90_probe(struct i2c_client *client, const struct i2c_device_id *id); static void lm90_init_client(struct i2c_client *client); static void lm90_alert(struct i2c_client *client, unsigned int flag); static int lm90_remove(struct i2c_client *client); static struct lm90_data *lm90_update_device(struct device *dev); static inline void lm90_select_remote_channel(struct i2c_client *client, struct lm90_data *data, int channel); /* * Driver data (common to all clients) */ Loading @@ -204,19 +189,6 @@ static const struct i2c_device_id lm90_id[] = { }; MODULE_DEVICE_TABLE(i2c, lm90_id); static struct i2c_driver lm90_driver = { .class = I2C_CLASS_HWMON, .driver = { .name = "lm90", }, .probe = lm90_probe, .remove = lm90_remove, .alert = lm90_alert, .id_table = lm90_id, .detect = lm90_detect, .address_list = normal_i2c, }; /* * Client data (each client gets its own) */ Loading Loading @@ -255,6 +227,209 @@ struct lm90_data { u16 alarms; /* bitvector (upper 8 bits for max6695/96) */ }; /* * Support functions */ /* * The ADM1032 supports PEC but not on write byte transactions, so we need * to explicitly ask for a transaction without PEC. */ static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value) { return i2c_smbus_xfer(client->adapter, client->addr, client->flags & ~I2C_CLIENT_PEC, I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); } /* * It is assumed that client->update_lock is held (unless we are in * detection or initialization steps). This matters when PEC is enabled, * because we don't want the address pointer to change between the write * byte and the read byte transactions. */ static int lm90_read_reg(struct i2c_client *client, u8 reg, u8 *value) { int err; if (client->flags & I2C_CLIENT_PEC) { err = adm1032_write_byte(client, reg); if (err >= 0) err = i2c_smbus_read_byte(client); } else err = i2c_smbus_read_byte_data(client, reg); if (err < 0) { dev_warn(&client->dev, "Register %#02x read failed (%d)\n", reg, err); return err; } *value = err; return 0; } static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value) { int err; u8 oldh, newh, l; /* * There is a trick here. We have to read two registers to have the * sensor temperature, but we have to beware a conversion could occur * inbetween the readings. The datasheet says we should either use * the one-shot conversion register, which we don't want to do * (disables hardware monitoring) or monitor the busy bit, which is * impossible (we can't read the values and monitor that bit at the * exact same time). So the solution used here is to read the high * byte once, then the low byte, then the high byte again. If the new * high byte matches the old one, then we have a valid reading. Else * we have to read the low byte again, and now we believe we have a * correct reading. */ if ((err = lm90_read_reg(client, regh, &oldh)) || (err = lm90_read_reg(client, regl, &l)) || (err = lm90_read_reg(client, regh, &newh))) return err; if (oldh != newh) { err = lm90_read_reg(client, regl, &l); if (err) return err; } *value = (newh << 8) | l; return 0; } /* * client->update_lock must be held when calling this function (unless we are * in detection or initialization steps), and while a remote channel other * than channel 0 is selected. Also, calling code must make sure to re-select * external channel 0 before releasing the lock. This is necessary because * various registers have different meanings as a result of selecting a * non-default remote channel. */ static inline void lm90_select_remote_channel(struct i2c_client *client, struct lm90_data *data, int channel) { u8 config; if (data->kind == max6696) { lm90_read_reg(client, LM90_REG_R_CONFIG1, &config); config &= ~0x08; if (channel) config |= 0x08; i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); } } static struct lm90_data *lm90_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct lm90_data *data = i2c_get_clientdata(client); mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ / 2 + HZ / 10) || !data->valid) { u8 h, l; u8 alarms; dev_dbg(&client->dev, "Updating lm90 data.\n"); lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[0]); lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[1]); lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[2]); lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[3]); lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); if (data->flags & LM90_HAVE_LOCAL_EXT) { lm90_read16(client, LM90_REG_R_LOCAL_TEMP, MAX6657_REG_R_LOCAL_TEMPL, &data->temp11[4]); } else { if (lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &h) == 0) data->temp11[4] = h << 8; } lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, LM90_REG_R_REMOTE_TEMPL, &data->temp11[0]); if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h) == 0) { data->temp11[1] = h << 8; if ((data->flags & LM90_HAVE_REM_LIMIT_EXT) && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, &l) == 0) data->temp11[1] |= l; } if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h) == 0) { data->temp11[2] = h << 8; if ((data->flags & LM90_HAVE_REM_LIMIT_EXT) && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0) data->temp11[2] |= l; } if (data->flags & LM90_HAVE_OFFSET) { if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH, &h) == 0 && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL, &l) == 0) data->temp11[3] = (h << 8) | l; } if (data->flags & LM90_HAVE_EMERGENCY) { lm90_read_reg(client, MAX6659_REG_R_LOCAL_EMERG, &data->temp8[4]); lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG, &data->temp8[5]); } lm90_read_reg(client, LM90_REG_R_STATUS, &alarms); data->alarms = alarms; /* save as 16 bit value */ if (data->kind == max6696) { lm90_select_remote_channel(client, data, 1); lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[6]); lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG, &data->temp8[7]); lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, LM90_REG_R_REMOTE_TEMPL, &data->temp11[5]); if (!lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h)) data->temp11[6] = h << 8; if (!lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h)) data->temp11[7] = h << 8; lm90_select_remote_channel(client, data, 0); if (!lm90_read_reg(client, MAX6696_REG_R_STATUS2, &alarms)) data->alarms |= alarms << 8; } /* Re-enable ALERT# output if it was originally enabled and * relevant alarms are all clear */ if ((data->config_orig & 0x80) == 0 && (data->alarms & data->alert_alarms) == 0) { u8 config; lm90_read_reg(client, LM90_REG_R_CONFIG1, &config); if (config & 0x80) { dev_dbg(&client->dev, "Re-enabling ALERT#\n"); i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config & ~0x80); } } data->last_updated = jiffies; data->valid = 1; } mutex_unlock(&data->update_lock); return data; } /* * Conversions * For local temperatures and limits, critical limits and the hysteresis Loading Loading @@ -770,79 +945,17 @@ static DEVICE_ATTR(pec, S_IWUSR | S_IRUGO, show_pec, set_pec); * Real code */ /* * The ADM1032 supports PEC but not on write byte transactions, so we need * to explicitly ask for a transaction without PEC. */ static inline s32 adm1032_write_byte(struct i2c_client *client, u8 value) { return i2c_smbus_xfer(client->adapter, client->addr, client->flags & ~I2C_CLIENT_PEC, I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); } /* * It is assumed that client->update_lock is held (unless we are in * detection or initialization steps). This matters when PEC is enabled, * because we don't want the address pointer to change between the write * byte and the read byte transactions. */ static int lm90_read_reg(struct i2c_client *client, u8 reg, u8 *value) /* Return 0 if detection is successful, -ENODEV otherwise */ static int lm90_detect(struct i2c_client *new_client, struct i2c_board_info *info) { int err; struct i2c_adapter *adapter = new_client->adapter; int address = new_client->addr; const char *name = NULL; int man_id, chip_id, reg_config1, reg_convrate; if (client->flags & I2C_CLIENT_PEC) { err = adm1032_write_byte(client, reg); if (err >= 0) err = i2c_smbus_read_byte(client); } else err = i2c_smbus_read_byte_data(client, reg); if (err < 0) { dev_warn(&client->dev, "Register %#02x read failed (%d)\n", reg, err); return err; } *value = err; return 0; } /* * client->update_lock must be held when calling this function (unless we are * in detection or initialization steps), and while a remote channel other * than channel 0 is selected. Also, calling code must make sure to re-select * external channel 0 before releasing the lock. This is necessary because * various registers have different meanings as a result of selecting a * non-default remote channel. */ static inline void lm90_select_remote_channel(struct i2c_client *client, struct lm90_data *data, int channel) { u8 config; if (data->kind == max6696) { lm90_read_reg(client, LM90_REG_R_CONFIG1, &config); config &= ~0x08; if (channel) config |= 0x08; i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); } } /* Return 0 if detection is successful, -ENODEV otherwise */ static int lm90_detect(struct i2c_client *new_client, struct i2c_board_info *info) { struct i2c_adapter *adapter = new_client->adapter; int address = new_client->addr; const char *name = NULL; int man_id, chip_id, reg_config1, reg_convrate; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; /* detection and identification */ if ((man_id = i2c_smbus_read_byte_data(new_client, Loading Loading @@ -1023,6 +1136,47 @@ static void lm90_remove_files(struct i2c_client *client, struct lm90_data *data) sysfs_remove_group(&client->dev.kobj, &lm90_group); } static void lm90_init_client(struct i2c_client *client) { u8 config; struct lm90_data *data = i2c_get_clientdata(client); /* * Start the conversions. */ i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, 5); /* 2 Hz */ if (lm90_read_reg(client, LM90_REG_R_CONFIG1, &config) < 0) { dev_warn(&client->dev, "Initialization failed!\n"); return; } data->config_orig = config; /* Check Temperature Range Select */ if (data->kind == adt7461) { if (config & 0x04) data->flags |= LM90_FLAG_ADT7461_EXT; } /* * Put MAX6680/MAX8881 into extended resolution (bit 0x10, * 0.125 degree resolution) and range (0x08, extend range * to -64 degree) mode for the remote temperature sensor. */ if (data->kind == max6680) config |= 0x18; /* * Select external channel 0 for max6695/96 */ if (data->kind == max6696) config &= ~0x08; config &= 0xBF; /* run */ if (config != data->config_orig) /* Only write if changed */ i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); } static int lm90_probe(struct i2c_client *new_client, const struct i2c_device_id *id) { Loading Loading @@ -1134,47 +1288,6 @@ static int lm90_probe(struct i2c_client *new_client, return err; } static void lm90_init_client(struct i2c_client *client) { u8 config; struct lm90_data *data = i2c_get_clientdata(client); /* * Start the conversions. */ i2c_smbus_write_byte_data(client, LM90_REG_W_CONVRATE, 5); /* 2 Hz */ if (lm90_read_reg(client, LM90_REG_R_CONFIG1, &config) < 0) { dev_warn(&client->dev, "Initialization failed!\n"); return; } data->config_orig = config; /* Check Temperature Range Select */ if (data->kind == adt7461) { if (config & 0x04) data->flags |= LM90_FLAG_ADT7461_EXT; } /* * Put MAX6680/MAX8881 into extended resolution (bit 0x10, * 0.125 degree resolution) and range (0x08, extend range * to -64 degree) mode for the remote temperature sensor. */ if (data->kind == max6680) config |= 0x18; /* * Select external channel 0 for max6695/96 */ if (data->kind == max6696) config &= ~0x08; config &= 0xBF; /* run */ if (config != data->config_orig) /* Only write if changed */ i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config); } static int lm90_remove(struct i2c_client *client) { struct lm90_data *data = i2c_get_clientdata(client); Loading Loading @@ -1230,142 +1343,18 @@ static void lm90_alert(struct i2c_client *client, unsigned int flag) } } static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value) { int err; u8 oldh, newh, l; /* * There is a trick here. We have to read two registers to have the * sensor temperature, but we have to beware a conversion could occur * inbetween the readings. The datasheet says we should either use * the one-shot conversion register, which we don't want to do * (disables hardware monitoring) or monitor the busy bit, which is * impossible (we can't read the values and monitor that bit at the * exact same time). So the solution used here is to read the high * byte once, then the low byte, then the high byte again. If the new * high byte matches the old one, then we have a valid reading. Else * we have to read the low byte again, and now we believe we have a * correct reading. */ if ((err = lm90_read_reg(client, regh, &oldh)) || (err = lm90_read_reg(client, regl, &l)) || (err = lm90_read_reg(client, regh, &newh))) return err; if (oldh != newh) { err = lm90_read_reg(client, regl, &l); if (err) return err; } *value = (newh << 8) | l; return 0; } static struct lm90_data *lm90_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct lm90_data *data = i2c_get_clientdata(client); mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ / 2 + HZ / 10) || !data->valid) { u8 h, l; u8 alarms; dev_dbg(&client->dev, "Updating lm90 data.\n"); lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[0]); lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[1]); lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[2]); lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[3]); lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); if (data->flags & LM90_HAVE_LOCAL_EXT) { lm90_read16(client, LM90_REG_R_LOCAL_TEMP, MAX6657_REG_R_LOCAL_TEMPL, &data->temp11[4]); } else { if (lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &h) == 0) data->temp11[4] = h << 8; } lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, LM90_REG_R_REMOTE_TEMPL, &data->temp11[0]); if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h) == 0) { data->temp11[1] = h << 8; if ((data->flags & LM90_HAVE_REM_LIMIT_EXT) && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, &l) == 0) data->temp11[1] |= l; } if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h) == 0) { data->temp11[2] = h << 8; if ((data->flags & LM90_HAVE_REM_LIMIT_EXT) && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0) data->temp11[2] |= l; } if (data->flags & LM90_HAVE_OFFSET) { if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH, &h) == 0 && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL, &l) == 0) data->temp11[3] = (h << 8) | l; } if (data->flags & LM90_HAVE_EMERGENCY) { lm90_read_reg(client, MAX6659_REG_R_LOCAL_EMERG, &data->temp8[4]); lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG, &data->temp8[5]); } lm90_read_reg(client, LM90_REG_R_STATUS, &alarms); data->alarms = alarms; /* save as 16 bit value */ if (data->kind == max6696) { lm90_select_remote_channel(client, data, 1); lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[6]); lm90_read_reg(client, MAX6659_REG_R_REMOTE_EMERG, &data->temp8[7]); lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, LM90_REG_R_REMOTE_TEMPL, &data->temp11[5]); if (!lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h)) data->temp11[6] = h << 8; if (!lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h)) data->temp11[7] = h << 8; lm90_select_remote_channel(client, data, 0); if (!lm90_read_reg(client, MAX6696_REG_R_STATUS2, &alarms)) data->alarms |= alarms << 8; } /* Re-enable ALERT# output if it was originally enabled and * relevant alarms are all clear */ if ((data->config_orig & 0x80) == 0 && (data->alarms & data->alert_alarms) == 0) { u8 config; lm90_read_reg(client, LM90_REG_R_CONFIG1, &config); if (config & 0x80) { dev_dbg(&client->dev, "Re-enabling ALERT#\n"); i2c_smbus_write_byte_data(client, LM90_REG_W_CONFIG1, config & ~0x80); } } data->last_updated = jiffies; data->valid = 1; } mutex_unlock(&data->update_lock); return data; } static struct i2c_driver lm90_driver = { .class = I2C_CLASS_HWMON, .driver = { .name = "lm90", }, .probe = lm90_probe, .remove = lm90_remove, .alert = lm90_alert, .id_table = lm90_id, .detect = lm90_detect, .address_list = normal_i2c, }; static int __init sensors_lm90_init(void) { Loading