#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/i2c-sensor.h>
#include "lm75.h"
/* Addresses to scan */
-static unsigned short normal_i2c[] = { I2C_CLIENT_END };
-static unsigned short normal_i2c_range[] = { 0x48, 0x4f, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
+ 0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END };
-static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END };
/* Insmod parameters */
SENSORS_INSMOD_1(ds1621);
/* Many DS1621 constants specified below */
/* Config register used for detection */
/* 7 6 5 4 3 2 1 0 */
-/* |Done|THF |TLF |NVB | 1 | 0 |POL |1SHOT| */
-#define DS1621_REG_CONFIG_MASK 0x0C
-#define DS1621_REG_CONFIG_VAL 0x08
+/* |Done|THF |TLF |NVB | X | X |POL |1SHOT| */
+#define DS1621_REG_CONFIG_NVB 0x10
#define DS1621_REG_CONFIG_POLARITY 0x02
#define DS1621_REG_CONFIG_1SHOT 0x01
#define DS1621_REG_CONFIG_DONE 0x80
#define DS1621_REG_TEMP_MAX 0xA2 /* word, RW */
#define DS1621_REG_CONF 0xAC /* byte, RW */
#define DS1621_COM_START 0xEE /* no data */
+#define DS1621_COM_STOP 0x22 /* no data */
/* The DS1621 configuration register */
#define DS1621_ALARM_TEMP_HIGH 0x40
.detach_client = ds1621_detach_client,
};
-static int ds1621_id = 0;
-
/* All registers are word-sized, except for the configuration register.
DS1621 uses a high-byte first convention, which is exactly opposite to
the usual practice. */
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct ds1621_data *data = ds1621_update_client(dev); \
- data->value = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10)); \
+ u16 val = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10)); \
+ \
+ down(&data->update_lock); \
+ data->value = val; \
ds1621_write_value(client, reg, data->value); \
+ up(&data->update_lock); \
return count; \
}
/* Now, we do the remaining detection. It is lousy. */
if (kind < 0) {
+ /* The NVB bit should be low if no EEPROM write has been
+ requested during the latest 10ms, which is highly
+ improbable in our case. */
conf = ds1621_read_value(new_client, DS1621_REG_CONF);
- if ((conf & DS1621_REG_CONFIG_MASK) != DS1621_REG_CONFIG_VAL)
+ if (conf & DS1621_REG_CONFIG_NVB)
goto exit_free;
+ /* The 7 lowest bits of a temperature should always be 0. */
temp = ds1621_read_value(new_client, DS1621_REG_TEMP);
if (temp & 0x007f)
goto exit_free;
/* Fill in remaining client fields and put it into the global list */
strlcpy(new_client->name, "ds1621", I2C_NAME_SIZE);
-
- new_client->id = ds1621_id++;
data->valid = 0;
init_MUTEX(&data->update_lock);
down(&data->update_lock);
- if ((jiffies - data->last_updated > HZ + HZ / 2) ||
- (jiffies < data->last_updated) || !data->valid) {
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
dev_dbg(&client->dev, "Starting ds1621 update\n");