diff options
author | Michael Arndt <michael@scriptkiller.de> | 2013-02-17 14:31:27 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-02-18 15:47:12 -0500 |
commit | 9c95bb6f25ff802081125f24bf0c756252fa27b2 (patch) | |
tree | 4372971eb0b6dbf806343da4982b09fbeafe6a80 /drivers/w1 | |
parent | def1820d25fa93cf5fca10bf45f22cdb11be41f2 (diff) |
w1: ds2482: Added 1-Wire pull-up support to the driver
Signed-off-by: Michael Arndt <michael@scriptkiller.de>
Acked-by: Evgeniy Polyakov <zbr@ioremap.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/w1')
-rw-r--r-- | drivers/w1/masters/ds2482.c | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c index 6429b9e9fb82..e033491fe308 100644 --- a/drivers/w1/masters/ds2482.c +++ b/drivers/w1/masters/ds2482.c | |||
@@ -51,10 +51,10 @@ | |||
51 | * The top 4 bits always read 0. | 51 | * The top 4 bits always read 0. |
52 | * To write, the top nibble must be the 1's compl. of the low nibble. | 52 | * To write, the top nibble must be the 1's compl. of the low nibble. |
53 | */ | 53 | */ |
54 | #define DS2482_REG_CFG_1WS 0x08 | 54 | #define DS2482_REG_CFG_1WS 0x08 /* 1-wire speed */ |
55 | #define DS2482_REG_CFG_SPU 0x04 | 55 | #define DS2482_REG_CFG_SPU 0x04 /* strong pull-up */ |
56 | #define DS2482_REG_CFG_PPM 0x02 | 56 | #define DS2482_REG_CFG_PPM 0x02 /* presence pulse masking */ |
57 | #define DS2482_REG_CFG_APU 0x01 | 57 | #define DS2482_REG_CFG_APU 0x01 /* active pull-up */ |
58 | 58 | ||
59 | 59 | ||
60 | /** | 60 | /** |
@@ -132,6 +132,17 @@ struct ds2482_data { | |||
132 | 132 | ||
133 | 133 | ||
134 | /** | 134 | /** |
135 | * Helper to calculate values for configuration register | ||
136 | * @param conf the raw config value | ||
137 | * @return the value w/ complements that can be written to register | ||
138 | */ | ||
139 | static inline u8 ds2482_calculate_config(u8 conf) | ||
140 | { | ||
141 | return conf | ((~conf & 0x0f) << 4); | ||
142 | } | ||
143 | |||
144 | |||
145 | /** | ||
135 | * Sets the read pointer. | 146 | * Sets the read pointer. |
136 | * @param pdev The ds2482 client pointer | 147 | * @param pdev The ds2482 client pointer |
137 | * @param read_ptr see DS2482_PTR_CODE_xxx above | 148 | * @param read_ptr see DS2482_PTR_CODE_xxx above |
@@ -399,7 +410,7 @@ static u8 ds2482_w1_reset_bus(void *data) | |||
399 | /* If the chip did reset since detect, re-config it */ | 410 | /* If the chip did reset since detect, re-config it */ |
400 | if (err & DS2482_REG_STS_RST) | 411 | if (err & DS2482_REG_STS_RST) |
401 | ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG, | 412 | ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG, |
402 | 0xF0); | 413 | ds2482_calculate_config(0x00)); |
403 | } | 414 | } |
404 | 415 | ||
405 | mutex_unlock(&pdev->access_lock); | 416 | mutex_unlock(&pdev->access_lock); |
@@ -407,6 +418,32 @@ static u8 ds2482_w1_reset_bus(void *data) | |||
407 | return retval; | 418 | return retval; |
408 | } | 419 | } |
409 | 420 | ||
421 | static u8 ds2482_w1_set_pullup(void *data, int delay) | ||
422 | { | ||
423 | struct ds2482_w1_chan *pchan = data; | ||
424 | struct ds2482_data *pdev = pchan->pdev; | ||
425 | u8 retval = 1; | ||
426 | |||
427 | /* if delay is non-zero activate the pullup, | ||
428 | * the strong pullup will be automatically deactivated | ||
429 | * by the master, so do not explicitly deactive it | ||
430 | */ | ||
431 | if (delay) { | ||
432 | /* both waits are crucial, otherwise devices might not be | ||
433 | * powered long enough, causing e.g. a w1_therm sensor to | ||
434 | * provide wrong conversion results | ||
435 | */ | ||
436 | ds2482_wait_1wire_idle(pdev); | ||
437 | /* note: it seems like both SPU and APU have to be set! */ | ||
438 | retval = ds2482_send_cmd_data(pdev, DS2482_CMD_WRITE_CONFIG, | ||
439 | ds2482_calculate_config(DS2482_REG_CFG_SPU | | ||
440 | DS2482_REG_CFG_APU)); | ||
441 | ds2482_wait_1wire_idle(pdev); | ||
442 | } | ||
443 | |||
444 | return retval; | ||
445 | } | ||
446 | |||
410 | 447 | ||
411 | static int ds2482_probe(struct i2c_client *client, | 448 | static int ds2482_probe(struct i2c_client *client, |
412 | const struct i2c_device_id *id) | 449 | const struct i2c_device_id *id) |
@@ -452,7 +489,8 @@ static int ds2482_probe(struct i2c_client *client, | |||
452 | data->w1_count = 8; | 489 | data->w1_count = 8; |
453 | 490 | ||
454 | /* Set all config items to 0 (off) */ | 491 | /* Set all config items to 0 (off) */ |
455 | ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG, 0xF0); | 492 | ds2482_send_cmd_data(data, DS2482_CMD_WRITE_CONFIG, |
493 | ds2482_calculate_config(0x00)); | ||
456 | 494 | ||
457 | mutex_init(&data->access_lock); | 495 | mutex_init(&data->access_lock); |
458 | 496 | ||
@@ -468,6 +506,7 @@ static int ds2482_probe(struct i2c_client *client, | |||
468 | data->w1_ch[idx].w1_bm.touch_bit = ds2482_w1_touch_bit; | 506 | data->w1_ch[idx].w1_bm.touch_bit = ds2482_w1_touch_bit; |
469 | data->w1_ch[idx].w1_bm.triplet = ds2482_w1_triplet; | 507 | data->w1_ch[idx].w1_bm.triplet = ds2482_w1_triplet; |
470 | data->w1_ch[idx].w1_bm.reset_bus = ds2482_w1_reset_bus; | 508 | data->w1_ch[idx].w1_bm.reset_bus = ds2482_w1_reset_bus; |
509 | data->w1_ch[idx].w1_bm.set_pullup = ds2482_w1_set_pullup; | ||
471 | 510 | ||
472 | err = w1_add_master_device(&data->w1_ch[idx].w1_bm); | 511 | err = w1_add_master_device(&data->w1_ch[idx].w1_bm); |
473 | if (err) { | 512 | if (err) { |