1 From 28ca85a46bbdae4152b48a669872ac205d053856 Mon Sep 17 00:00:00 2001
2 From: popcornmix <popcornmix@gmail.com>
3 Date: Wed, 1 May 2013 21:14:28 +0100
4 Subject: [PATCH 055/174] Add bitbanging pullups, use them for w1-gpio
6 Allows parasite power to work, uses module option pullup=1
8 drivers/w1/masters/w1-gpio.c | 20 ++++++++++++++++++++
9 drivers/w1/w1.h | 6 ++++++
10 drivers/w1/w1_int.c | 16 +++++++++-------
11 drivers/w1/w1_io.c | 18 +++++++++++++++---
12 4 files changed, 50 insertions(+), 10 deletions(-)
14 --- a/drivers/w1/masters/w1-gpio.c
15 +++ b/drivers/w1/masters/w1-gpio.c
18 #include "../w1_int.h"
20 +static int w1_gpio_pullup = 0;
21 +module_param_named(pullup, w1_gpio_pullup, int, 0);
23 static void w1_gpio_write_bit_dir(void *data, u8 bit)
25 struct w1_gpio_platform_data *pdata = data;
26 @@ -47,6 +50,16 @@ static u8 w1_gpio_read_bit(void *data)
27 return gpio_get_value(pdata->pin) ? 1 : 0;
30 +static void w1_gpio_bitbang_pullup(void *data, u8 on)
32 + struct w1_gpio_platform_data *pdata = data;
35 + gpio_direction_output(pdata->pin, 1);
37 + gpio_direction_input(pdata->pin);
40 #if defined(CONFIG_OF)
41 static struct of_device_id w1_gpio_dt_ids[] = {
42 { .compatible = "w1-gpio" },
43 @@ -133,6 +146,13 @@ static int w1_gpio_probe(struct platform
44 master->write_bit = w1_gpio_write_bit_dir;
48 + if (pdata->is_open_drain)
49 + printk(KERN_ERR "w1-gpio 'pullup' option "
50 + "doesn't work with open drain GPIO\n");
52 + master->bitbang_pullup = w1_gpio_bitbang_pullup;
54 err = w1_add_master_device(master);
56 dev_err(&pdev->dev, "w1_add_master device failed\n");
59 @@ -148,6 +148,12 @@ struct w1_bus_master
61 u8 (*set_pullup)(void *, int);
64 + * Turns the pullup on/off in bitbanging mode, takes an on/off argument.
65 + * @return -1=Error, 0=completed
67 + void (*bitbang_pullup) (void *, u8);
69 /** Really nice hardware can handles the different types of ROM search
70 * w1_master* is passed to the slave found callback.
72 --- a/drivers/w1/w1_int.c
73 +++ b/drivers/w1/w1_int.c
74 @@ -117,19 +117,21 @@ int w1_add_master_device(struct w1_bus_m
75 printk(KERN_ERR "w1_add_master_device: invalid function set\n");
78 - /* While it would be electrically possible to make a device that
79 - * generated a strong pullup in bit bang mode, only hardware that
80 - * controls 1-wire time frames are even expected to support a strong
81 - * pullup. w1_io.c would need to support calling set_pullup before
82 - * the last write_bit operation of a w1_write_8 which it currently
86 + /* bitbanging hardware uses bitbang_pullup, other hardware uses set_pullup
87 + * and takes care of timing itself */
88 if (!master->write_byte && !master->touch_bit && master->set_pullup) {
89 printk(KERN_ERR "w1_add_master_device: set_pullup requires "
90 "write_byte or touch_bit, disabling\n");
91 master->set_pullup = NULL;
94 + if (master->set_pullup && master->bitbang_pullup) {
95 + printk(KERN_ERR "w1_add_master_device: set_pullup should not "
96 + "be set when bitbang_pullup is used, disabling\n");
97 + master->set_pullup = NULL;
100 /* Lock until the device is added (or not) to w1_masters. */
101 mutex_lock(&w1_mlock);
102 /* Search for the first available id (starting at 1). */
103 --- a/drivers/w1/w1_io.c
104 +++ b/drivers/w1/w1_io.c
105 @@ -127,10 +127,22 @@ static void w1_pre_write(struct w1_maste
106 static void w1_post_write(struct w1_master *dev)
108 if (dev->pullup_duration) {
109 - if (dev->enable_pullup && dev->bus_master->set_pullup)
110 - dev->bus_master->set_pullup(dev->bus_master->data, 0);
112 + if (dev->enable_pullup) {
113 + if (dev->bus_master->set_pullup) {
114 + dev->bus_master->set_pullup(dev->
117 + } else if (dev->bus_master->bitbang_pullup) {
119 + bitbang_pullup(dev->bus_master->data, 1);
120 msleep(dev->pullup_duration);
122 + bitbang_pullup(dev->bus_master->data, 0);
125 + msleep(dev->pullup_duration);
128 dev->pullup_duration = 0;