d4341020619190ca847eb4eb52ff17885c009259
[oweals/openwrt.git] /
1 From dc2d8a486db8a21cd998b0bdb117d30b8034aceb Mon Sep 17 00:00:00 2001
2 From: popcornmix <popcornmix@gmail.com>
3 Date: Wed, 8 May 2013 11:46:50 +0100
4 Subject: [PATCH 058/454] enabling the realtime clock 1-wire chip DS1307 and
5  1-wire on GPIO4 (as a module)
6
7 1-wire: Add support for configuring pin for w1-gpio kernel module
8 See: https://github.com/raspberrypi/linux/pull/457
9
10 Add bitbanging pullups, use them for w1-gpio
11
12 Allows parasite power to work, uses module option pullup=1
13
14 bcm2708: Ensure 1-wire pullup is disabled by default, and expose as module parameter
15
16 Signed-off-by: Alex J Lennon <ajlennon@dynamicdevices.co.uk>
17
18 w1-gpio: Add gpiopin module parameter and correctly free up gpio pull-up pin, if set
19
20 Signed-off-by: Alex J Lennon <ajlennon@dynamicdevices.co.uk>
21
22 w1-gpio: Sort out the pullup/parasitic power tangle
23 ---
24  drivers/w1/masters/w1-gpio.c | 69 ++++++++++++++++++++++++++++++++----
25  drivers/w1/w1_int.c          | 14 ++++++++
26  drivers/w1/w1_io.c           | 18 ++++++++--
27  include/linux/w1-gpio.h      |  1 +
28  include/linux/w1.h           |  6 ++++
29  5 files changed, 99 insertions(+), 9 deletions(-)
30
31 --- a/drivers/w1/masters/w1-gpio.c
32 +++ b/drivers/w1/masters/w1-gpio.c
33 @@ -22,6 +22,19 @@
34  
35  #include <linux/w1.h>
36  
37 +static int w1_gpio_pullup = 0;
38 +static int w1_gpio_pullup_orig = 0;
39 +module_param_named(pullup, w1_gpio_pullup, int, 0);
40 +MODULE_PARM_DESC(pullup, "Enable parasitic power (power on data) mode");
41 +static int w1_gpio_pullup_pin = -1;
42 +static int w1_gpio_pullup_pin_orig = -1;
43 +module_param_named(extpullup, w1_gpio_pullup_pin, int, 0);
44 +MODULE_PARM_DESC(extpullup, "GPIO external pullup pin number");
45 +static int w1_gpio_pin = -1;
46 +static int w1_gpio_pin_orig = -1;
47 +module_param_named(gpiopin, w1_gpio_pin, int, 0);
48 +MODULE_PARM_DESC(gpiopin, "GPIO pin number");
49 +
50  static u8 w1_gpio_set_pullup(void *data, int delay)
51  {
52         struct w1_gpio_platform_data *pdata = data;
53 @@ -66,6 +79,16 @@ static u8 w1_gpio_read_bit(void *data)
54         return gpio_get_value(pdata->pin) ? 1 : 0;
55  }
56  
57 +static void w1_gpio_bitbang_pullup(void *data, u8 on)
58 +{
59 +       struct w1_gpio_platform_data *pdata = data;
60 +
61 +       if (on)
62 +               gpio_direction_output(pdata->pin, 1);
63 +       else
64 +               gpio_direction_input(pdata->pin);
65 +}
66 +
67  #if defined(CONFIG_OF)
68  static const struct of_device_id w1_gpio_dt_ids[] = {
69         { .compatible = "w1-gpio" },
70 @@ -79,6 +102,7 @@ static int w1_gpio_probe_dt(struct platf
71         struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
72         struct device_node *np = pdev->dev.of_node;
73         int gpio;
74 +       u32 value;
75  
76         pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
77         if (!pdata)
78 @@ -87,6 +111,9 @@ static int w1_gpio_probe_dt(struct platf
79         if (of_get_property(np, "linux,open-drain", NULL))
80                 pdata->is_open_drain = 1;
81  
82 +       if (of_property_read_u32(np, "rpi,parasitic-power", &value) == 0)
83 +           pdata->parasitic_power = (value != 0);
84 +
85         gpio = of_get_gpio(np, 0);
86         if (gpio < 0) {
87                 if (gpio != -EPROBE_DEFER)
88 @@ -102,7 +129,7 @@ static int w1_gpio_probe_dt(struct platf
89         if (gpio == -EPROBE_DEFER)
90                 return gpio;
91         /* ignore other errors as the pullup gpio is optional */
92 -       pdata->ext_pullup_enable_pin = gpio;
93 +       pdata->ext_pullup_enable_pin = (gpio >= 0) ? gpio : -1;
94  
95         pdev->dev.platform_data = pdata;
96  
97 @@ -134,6 +161,22 @@ static int w1_gpio_probe(struct platform
98                 return -ENOMEM;
99         }
100  
101 +       w1_gpio_pin_orig = pdata->pin;
102 +       w1_gpio_pullup_pin_orig = pdata->ext_pullup_enable_pin;
103 +       w1_gpio_pullup_orig = pdata->parasitic_power;
104 +
105 +       if(gpio_is_valid(w1_gpio_pin)) {
106 +               pdata->pin = w1_gpio_pin;
107 +               pdata->ext_pullup_enable_pin = -1;
108 +               pdata->parasitic_power = -1;
109 +       }
110 +       pdata->parasitic_power |= w1_gpio_pullup;
111 +       if(gpio_is_valid(w1_gpio_pullup_pin)) {
112 +               pdata->ext_pullup_enable_pin = w1_gpio_pullup_pin;
113 +       }
114 +
115 +       dev_info(&pdev->dev, "gpio pin %d, external pullup pin %d, parasitic power %d\n", pdata->pin, pdata->ext_pullup_enable_pin, pdata->parasitic_power);
116 +
117         err = devm_gpio_request(&pdev->dev, pdata->pin, "w1");
118         if (err) {
119                 dev_err(&pdev->dev, "gpio_request (pin) failed\n");
120 @@ -163,6 +206,14 @@ static int w1_gpio_probe(struct platform
121                 master->set_pullup = w1_gpio_set_pullup;
122         }
123  
124 +       if (pdata->parasitic_power) {
125 +               if (pdata->is_open_drain)
126 +                       printk(KERN_ERR "w1-gpio 'pullup'(parasitic power) "
127 +                              "option doesn't work with open drain GPIO\n");
128 +               else
129 +                       master->bitbang_pullup = w1_gpio_bitbang_pullup;
130 +       }
131 +
132         err = w1_add_master_device(master);
133         if (err) {
134                 dev_err(&pdev->dev, "w1_add_master device failed\n");
135 @@ -193,6 +244,10 @@ static int w1_gpio_remove(struct platfor
136  
137         w1_remove_master_device(master);
138  
139 +       pdata->pin = w1_gpio_pin_orig;
140 +       pdata->ext_pullup_enable_pin = w1_gpio_pullup_pin_orig;
141 +       pdata->parasitic_power = w1_gpio_pullup_orig;
142 +
143         return 0;
144  }
145  
146 --- a/drivers/w1/w1_int.c
147 +++ b/drivers/w1/w1_int.c
148 @@ -114,6 +114,20 @@ int w1_add_master_device(struct w1_bus_m
149                 return(-EINVAL);
150         }
151  
152 +       /* bitbanging hardware uses bitbang_pullup, other hardware uses set_pullup
153 +        * and takes care of timing itself */
154 +       if (!master->write_byte && !master->touch_bit && master->set_pullup) {
155 +               printk(KERN_ERR "w1_add_master_device: set_pullup requires "
156 +                       "write_byte or touch_bit, disabling\n");
157 +               master->set_pullup = NULL;
158 +       }
159 +
160 +       if (master->set_pullup && master->bitbang_pullup) {
161 +               printk(KERN_ERR "w1_add_master_device: set_pullup should not "
162 +                      "be set when bitbang_pullup is used, disabling\n");
163 +               master->set_pullup = NULL;
164 +       }
165 +
166         /* Lock until the device is added (or not) to w1_masters. */
167         mutex_lock(&w1_mlock);
168         /* Search for the first available id (starting at 1). */
169 --- a/drivers/w1/w1_io.c
170 +++ b/drivers/w1/w1_io.c
171 @@ -126,10 +126,22 @@ static void w1_pre_write(struct w1_maste
172  static void w1_post_write(struct w1_master *dev)
173  {
174         if (dev->pullup_duration) {
175 -               if (dev->enable_pullup && dev->bus_master->set_pullup)
176 -                       dev->bus_master->set_pullup(dev->bus_master->data, 0);
177 -               else
178 +               if (dev->enable_pullup) {
179 +                       if (dev->bus_master->set_pullup) {
180 +                               dev->bus_master->set_pullup(dev->
181 +                                                           bus_master->data,
182 +                                                           0);
183 +                       } else if (dev->bus_master->bitbang_pullup) {
184 +                               dev->bus_master->
185 +                                   bitbang_pullup(dev->bus_master->data, 1);
186                         msleep(dev->pullup_duration);
187 +                               dev->bus_master->
188 +                                   bitbang_pullup(dev->bus_master->data, 0);
189 +                       }
190 +               } else {
191 +                       msleep(dev->pullup_duration);
192 +               }
193 +
194                 dev->pullup_duration = 0;
195         }
196  }
197 --- a/include/linux/w1-gpio.h
198 +++ b/include/linux/w1-gpio.h
199 @@ -18,6 +18,7 @@
200  struct w1_gpio_platform_data {
201         unsigned int pin;
202         unsigned int is_open_drain:1;
203 +       unsigned int parasitic_power:1;
204         void (*enable_external_pullup)(int enable);
205         unsigned int ext_pullup_enable_pin;
206         unsigned int pullup_duration;
207 --- a/include/linux/w1.h
208 +++ b/include/linux/w1.h
209 @@ -157,6 +157,12 @@ struct w1_bus_master {
210  
211         u8              (*set_pullup)(void *, int);
212  
213 +       /**
214 +        * Turns the pullup on/off in bitbanging mode, takes an on/off argument.
215 +        * @return -1=Error, 0=completed
216 +        */
217 +       void (*bitbang_pullup) (void *, u8);
218 +
219         void            (*search)(void *, struct w1_master *,
220                 u8, w1_slave_found_callback);
221  };