diff options
| author | Vivien Didelot <vivien.didelot@savoirfairelinux.com> | 2011-04-12 15:34:37 -0400 |
|---|---|---|
| committer | Guenter Roeck <guenter.roeck@ericsson.com> | 2011-05-19 11:19:34 -0400 |
| commit | 181148ae68799f5b17f09b418b276f56e9179e99 (patch) | |
| tree | a0252fec3f94fb65459ef1fbb9956de046f06744 | |
| parent | 99a0378de9f887fd4d501f1baa50aaf16d01a8e8 (diff) | |
hwmon: (sht15) clean-up the probe function
* Move the creation of sysfs attributes after the end of the
initialization, and remove them in the error path.
* Release regulator in the error path.
* Add a soft reset command (need to wait 11ms before next command).
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Acked-by: Jonathan Cameron <jic23@cam.ac.uk>
Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
| -rw-r--r-- | drivers/hwmon/sht15.c | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index 080af75c517b..3182b3f578e2 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c | |||
| @@ -33,11 +33,13 @@ | |||
| 33 | /* Commands */ | 33 | /* Commands */ |
| 34 | #define SHT15_MEASURE_TEMP 0x03 | 34 | #define SHT15_MEASURE_TEMP 0x03 |
| 35 | #define SHT15_MEASURE_RH 0x05 | 35 | #define SHT15_MEASURE_RH 0x05 |
| 36 | #define SHT15_SOFT_RESET 0x1E | ||
| 36 | 37 | ||
| 37 | /* Min timings */ | 38 | /* Min timings */ |
| 38 | #define SHT15_TSCKL 100 /* (nsecs) clock low */ | 39 | #define SHT15_TSCKL 100 /* (nsecs) clock low */ |
| 39 | #define SHT15_TSCKH 100 /* (nsecs) clock high */ | 40 | #define SHT15_TSCKH 100 /* (nsecs) clock high */ |
| 40 | #define SHT15_TSU 150 /* (nsecs) data setup time */ | 41 | #define SHT15_TSU 150 /* (nsecs) data setup time */ |
| 42 | #define SHT15_TSRST 11 /* (msecs) soft reset time */ | ||
| 41 | 43 | ||
| 42 | /* Actions the driver may be doing */ | 44 | /* Actions the driver may be doing */ |
| 43 | enum sht15_state { | 45 | enum sht15_state { |
| @@ -229,6 +231,24 @@ static int sht15_send_cmd(struct sht15_data *data, u8 cmd) | |||
| 229 | } | 231 | } |
| 230 | 232 | ||
| 231 | /** | 233 | /** |
| 234 | * sht15_soft_reset() - send a soft reset command | ||
| 235 | * @data: sht15 specific data. | ||
| 236 | * | ||
| 237 | * As described in section 3.2 of the datasheet. | ||
| 238 | */ | ||
| 239 | static int sht15_soft_reset(struct sht15_data *data) | ||
| 240 | { | ||
| 241 | int ret; | ||
| 242 | |||
| 243 | ret = sht15_send_cmd(data, SHT15_SOFT_RESET); | ||
| 244 | if (ret) | ||
| 245 | return ret; | ||
| 246 | msleep(SHT15_TSRST); | ||
| 247 | |||
| 248 | return 0; | ||
| 249 | } | ||
| 250 | |||
| 251 | /** | ||
| 232 | * sht15_measurement() - get a new value from device | 252 | * sht15_measurement() - get a new value from device |
| 233 | * @data: device instance specific data | 253 | * @data: device instance specific data |
| 234 | * @command: command sent to request value | 254 | * @command: command sent to request value |
| @@ -588,13 +608,20 @@ static int __devinit sht15_probe(struct platform_device *pdev) | |||
| 588 | */ | 608 | */ |
| 589 | data->nb.notifier_call = &sht15_invalidate_voltage; | 609 | data->nb.notifier_call = &sht15_invalidate_voltage; |
| 590 | ret = regulator_register_notifier(data->reg, &data->nb); | 610 | ret = regulator_register_notifier(data->reg, &data->nb); |
| 611 | if (ret) { | ||
| 612 | dev_err(&pdev->dev, | ||
| 613 | "regulator notifier request failed\n"); | ||
| 614 | regulator_disable(data->reg); | ||
| 615 | regulator_put(data->reg); | ||
| 616 | goto err_free_data; | ||
| 617 | } | ||
| 591 | } | 618 | } |
| 592 | 619 | ||
| 593 | /* Try requesting the GPIOs */ | 620 | /* Try requesting the GPIOs */ |
| 594 | ret = gpio_request(data->pdata->gpio_sck, "SHT15 sck"); | 621 | ret = gpio_request(data->pdata->gpio_sck, "SHT15 sck"); |
| 595 | if (ret) { | 622 | if (ret) { |
| 596 | dev_err(&pdev->dev, "gpio request failed\n"); | 623 | dev_err(&pdev->dev, "gpio request failed\n"); |
| 597 | goto err_free_data; | 624 | goto err_release_reg; |
| 598 | } | 625 | } |
| 599 | gpio_direction_output(data->pdata->gpio_sck, 0); | 626 | gpio_direction_output(data->pdata->gpio_sck, 0); |
| 600 | 627 | ||
| @@ -603,11 +630,6 @@ static int __devinit sht15_probe(struct platform_device *pdev) | |||
| 603 | dev_err(&pdev->dev, "gpio request failed\n"); | 630 | dev_err(&pdev->dev, "gpio request failed\n"); |
| 604 | goto err_release_gpio_sck; | 631 | goto err_release_gpio_sck; |
| 605 | } | 632 | } |
| 606 | ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group); | ||
| 607 | if (ret) { | ||
| 608 | dev_err(&pdev->dev, "sysfs create failed"); | ||
| 609 | goto err_release_gpio_data; | ||
| 610 | } | ||
| 611 | 633 | ||
| 612 | ret = request_irq(gpio_to_irq(data->pdata->gpio_data), | 634 | ret = request_irq(gpio_to_irq(data->pdata->gpio_data), |
| 613 | sht15_interrupt_fired, | 635 | sht15_interrupt_fired, |
| @@ -620,22 +642,38 @@ static int __devinit sht15_probe(struct platform_device *pdev) | |||
| 620 | } | 642 | } |
| 621 | disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); | 643 | disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data)); |
| 622 | sht15_connection_reset(data); | 644 | sht15_connection_reset(data); |
| 623 | sht15_send_cmd(data, 0x1E); | 645 | ret = sht15_soft_reset(data); |
| 646 | if (ret) | ||
| 647 | goto err_release_irq; | ||
| 648 | |||
| 649 | ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group); | ||
| 650 | if (ret) { | ||
| 651 | dev_err(&pdev->dev, "sysfs create failed\n"); | ||
| 652 | goto err_release_irq; | ||
| 653 | } | ||
| 624 | 654 | ||
| 625 | data->hwmon_dev = hwmon_device_register(data->dev); | 655 | data->hwmon_dev = hwmon_device_register(data->dev); |
| 626 | if (IS_ERR(data->hwmon_dev)) { | 656 | if (IS_ERR(data->hwmon_dev)) { |
| 627 | ret = PTR_ERR(data->hwmon_dev); | 657 | ret = PTR_ERR(data->hwmon_dev); |
| 628 | goto err_release_irq; | 658 | goto err_release_sysfs_group; |
| 629 | } | 659 | } |
| 630 | 660 | ||
| 631 | return 0; | 661 | return 0; |
| 632 | 662 | ||
| 663 | err_release_sysfs_group: | ||
| 664 | sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group); | ||
| 633 | err_release_irq: | 665 | err_release_irq: |
| 634 | free_irq(gpio_to_irq(data->pdata->gpio_data), data); | 666 | free_irq(gpio_to_irq(data->pdata->gpio_data), data); |
| 635 | err_release_gpio_data: | 667 | err_release_gpio_data: |
| 636 | gpio_free(data->pdata->gpio_data); | 668 | gpio_free(data->pdata->gpio_data); |
| 637 | err_release_gpio_sck: | 669 | err_release_gpio_sck: |
| 638 | gpio_free(data->pdata->gpio_sck); | 670 | gpio_free(data->pdata->gpio_sck); |
| 671 | err_release_reg: | ||
| 672 | if (!IS_ERR(data->reg)) { | ||
| 673 | regulator_unregister_notifier(data->reg, &data->nb); | ||
| 674 | regulator_disable(data->reg); | ||
| 675 | regulator_put(data->reg); | ||
| 676 | } | ||
| 639 | err_free_data: | 677 | err_free_data: |
| 640 | kfree(data); | 678 | kfree(data); |
| 641 | error_ret: | 679 | error_ret: |
