Skip to content

Commit

Permalink
w1-gpio: add external pull-up enable callback
Browse files Browse the repository at this point in the history
On embedded devices, sleep mode conditions can be tricky to handle,
Especially when processors tend to pull-down the w1 bus during sleep.  Bus
slaves (such as the ds2760) may interpret this as a reason for power-down
conditions and entirely switch off the device.

This patch adds a callback function pointer to let users switch on and off
the external pull-up resistor.  This lets the outside world know whether
the processor is currently actively driving the bus or not.

When this callback is not provided, the code behaviour won't change.

Signed-off-by: Daniel Mack <daniel@caiaq.de>
Acked-by: Ville Syrjala <syrjala@sci.fi>
Acked-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Daniel Mack authored and Linus Torvalds committed Jun 18, 2009
1 parent 9916219 commit c8a06c1
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
35 changes: 35 additions & 0 deletions drivers/w1/masters/w1-gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ static int __init w1_gpio_probe(struct platform_device *pdev)
if (err)
goto free_gpio;

if (pdata->enable_external_pullup)
pdata->enable_external_pullup(1);

platform_set_drvdata(pdev, master);

return 0;
Expand All @@ -91,19 +94,51 @@ static int __exit w1_gpio_remove(struct platform_device *pdev)
struct w1_bus_master *master = platform_get_drvdata(pdev);
struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;

if (pdata->enable_external_pullup)
pdata->enable_external_pullup(0);

w1_remove_master_device(master);
gpio_free(pdata->pin);
kfree(master);

return 0;
}

#ifdef CONFIG_PM

static int w1_gpio_suspend(struct platform_device *pdev, pm_message_t state)
{
struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;

if (pdata->enable_external_pullup)
pdata->enable_external_pullup(0);

return 0;
}

static int w1_gpio_resume(struct platform_device *pdev)
{
struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;

if (pdata->enable_external_pullup)
pdata->enable_external_pullup(1);

return 0;
}

#else
#define w1_gpio_suspend NULL
#define w1_gpio_resume NULL
#endif

static struct platform_driver w1_gpio_driver = {
.driver = {
.name = "w1-gpio",
.owner = THIS_MODULE,
},
.remove = __exit_p(w1_gpio_remove),
.suspend = w1_gpio_suspend,
.resume = w1_gpio_resume,
};

static int __init w1_gpio_init(void)
Expand Down
1 change: 1 addition & 0 deletions include/linux/w1-gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
struct w1_gpio_platform_data {
unsigned int pin;
unsigned int is_open_drain:1;
void (*enable_external_pullup)(int enable);
};

#endif /* _LINUX_W1_GPIO_H */

0 comments on commit c8a06c1

Please sign in to comment.