diff options
Diffstat (limited to 'drivers/w1/masters/ds2482.c')
| -rw-r--r-- | drivers/w1/masters/ds2482.c | 93 |
1 files changed, 48 insertions, 45 deletions
diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c index df52cb355f7..e033491fe30 100644 --- a/drivers/w1/masters/ds2482.c +++ b/drivers/w1/masters/ds2482.c @@ -24,19 +24,6 @@ #include "../w1_int.h" /** - * Address is selected using 2 pins, resulting in 4 possible addresses. - * 0x18, 0x19, 0x1a, 0x1b - * However, the chip cannot be detected without doing an i2c write, - * so use the force module parameter. - */ -static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -/** - * Insmod parameters - */ -I2C_CLIENT_INSMOD_1(ds2482); - -/** * The DS2482 registers - there are 3 registers that are addressed by a read * pointer. The read pointer is set by the last command executed. * @@ -64,10 +51,10 @@ I2C_CLIENT_INSMOD_1(ds2482); * The top 4 bits always read 0. * To write, the top nibble must be the 1's compl. of the low nibble. */ -#define DS2482_REG_CFG_1WS 0x08 -#define DS2482_REG_CFG_SPU 0x04 -#define DS2482_REG_CFG_PPM 0x02 -#define DS2482_REG_CFG_APU 0x01 +#define DS2482_REG_CFG_1WS 0x08 /* 1-wire speed */ +#define DS2482_REG_CFG_SPU 0x04 /* strong pull-up */ +#define DS2482_REG_CFG_PPM 0x02 /* presence pulse masking */ +#define DS2482_REG_CFG_APU 0x01 /* active pull-up */ /** @@ -96,8 +83,6 @@ static const u8 ds2482_chan_rd[8] = static int ds2482_probe(struct i2c_client *client, const struct i2c_device_id *id); -static int ds2482_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info); static int ds2482_remove(struct i2c_client *client); @@ -117,8 +102,6 @@ static struct i2c_driver ds2482_driver = { .probe = ds2482_probe, .remove = ds2482_remove, .id_table = ds2482_id, - .detect = ds2482_detect, - .address_data = &addr_data, }; /* @@ -149,6 +132,17 @@ struct ds2482_data { /** + * Helper to calculate values for configuration register + * @param conf the raw config value + * @return the value w/ complements that can be written to register + */ +static inline u8 ds2482_calculate_config(u8 conf) +{ + return conf | ((~conf & 0x0f) << 4); +} + + +/** * Sets the read pointer. * @param pdev The ds2482 client pointer * @param read_ptr see DS2482_PTR_CODE_xxx above @@ -231,7 +225,7 @@ static int ds2482_wait_1wire_idle(struct ds2482_data *pdev) (++retries < DS2482_WAIT_IDLE_TIMEOUT)); } - if (retries > DS2482_WAIT_IDLE_TIMEOUT) + if (retries >= DS2482_WAIT_IDLE_TIMEOUT) printk(KERN_ERR "%s: timeout on channel %d\n", __func__, pdev->channel); @@ -416,7 +410,7 @@ static u8 ds2482_w1_reset_bus(void *data) /* If the chip did reset since detect, re-config it */ if (err & DS2482_REG_STS_RST) ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG, - 0xF0); + ds2482_calculate_config(0x00)); } mutex_unlock(&pdev->access_lock); @@ -424,20 +418,33 @@ static u8 ds2482_w1_reset_bus(void *data) return retval; } - -static int ds2482_detect(struct i2c_client *client, int kind, - struct i2c_board_info *info) +static u8 ds2482_w1_set_pullup(void *data, int delay) { - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_WRITE_BYTE_DATA | - I2C_FUNC_SMBUS_BYTE)) - return -ENODEV; + struct ds2482_w1_chan *pchan = data; + struct ds2482_data *pdev = pchan->pdev; + u8 retval = 1; - strlcpy(info->type, "ds2482", I2C_NAME_SIZE); + /* if delay is non-zero activate the pullup, + * the strong pullup will be automatically deactivated + * by the master, so do not explicitly deactive it + */ + if (delay) { + /* both waits are crucial, otherwise devices might not be + * powered long enough, causing e.g. a w1_therm sensor to + * provide wrong conversion results + */ + ds2482_wait_1wire_idle(pdev); + /* note: it seems like both SPU and APU have to be set! */ + retval = ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG, + ds2482_calculate_config(DS2482_REG_CFG_SPU | + DS2482_REG_CFG_APU)); + ds2482_wait_1wire_idle(pdev); + } - return 0; + return retval; } + static int ds2482_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -446,6 +453,11 @@ static int ds2482_probe(struct i2c_client *client, int temp1; int idx; + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA | + I2C_FUNC_SMBUS_BYTE)) + return -ENODEV; + if (!(data = kzalloc(sizeof(struct ds2482_data), GFP_KERNEL))) { err = -ENOMEM; goto exit; @@ -477,7 +489,8 @@ static int ds2482_probe(struct i2c_client *client, data->w1_count = 8; /* Set all config items to 0 (off) */ - ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG, 0xF0); + ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG, + ds2482_calculate_config(0x00)); mutex_init(&data->access_lock); @@ -493,6 +506,7 @@ static int ds2482_probe(struct i2c_client *client, data->w1_ch[idx].w1_bm.touch_bit = ds2482_w1_touch_bit; data->w1_ch[idx].w1_bm.triplet = ds2482_w1_triplet; data->w1_ch[idx].w1_bm.reset_bus = ds2482_w1_reset_bus; + data->w1_ch[idx].w1_bm.set_pullup = ds2482_w1_set_pullup; err = w1_add_master_device(&data->w1_ch[idx].w1_bm); if (err) { @@ -530,19 +544,8 @@ static int ds2482_remove(struct i2c_client *client) return 0; } -static int __init sensors_ds2482_init(void) -{ - return i2c_add_driver(&ds2482_driver); -} - -static void __exit sensors_ds2482_exit(void) -{ - i2c_del_driver(&ds2482_driver); -} +module_i2c_driver(ds2482_driver); MODULE_AUTHOR("Ben Gardner <bgardner@wabtec.com>"); MODULE_DESCRIPTION("DS2482 driver"); MODULE_LICENSE("GPL"); - -module_init(sensors_ds2482_init); -module_exit(sensors_ds2482_exit); |
