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 | |
| 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>
| -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) { |
