]> Pileus Git - ~andy/linux/blob - drivers/w1/masters/w1-gpio.c
w1-gpio: Detect of_gpio_error for first gpio
[~andy/linux] / drivers / w1 / masters / w1-gpio.c
1 /*
2  * w1-gpio - GPIO w1 bus master driver
3  *
4  * Copyright (C) 2007 Ville Syrjala <syrjala@sci.fi>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2
8  * as published by the Free Software Foundation.
9  */
10
11 #include <linux/init.h>
12 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/slab.h>
15 #include <linux/w1-gpio.h>
16 #include <linux/gpio.h>
17 #include <linux/of_platform.h>
18 #include <linux/of_gpio.h>
19 #include <linux/err.h>
20 #include <linux/of.h>
21
22 #include "../w1.h"
23 #include "../w1_int.h"
24
25 static void w1_gpio_write_bit_dir(void *data, u8 bit)
26 {
27         struct w1_gpio_platform_data *pdata = data;
28
29         if (bit)
30                 gpio_direction_input(pdata->pin);
31         else
32                 gpio_direction_output(pdata->pin, 0);
33 }
34
35 static void w1_gpio_write_bit_val(void *data, u8 bit)
36 {
37         struct w1_gpio_platform_data *pdata = data;
38
39         gpio_set_value(pdata->pin, bit);
40 }
41
42 static u8 w1_gpio_read_bit(void *data)
43 {
44         struct w1_gpio_platform_data *pdata = data;
45
46         return gpio_get_value(pdata->pin) ? 1 : 0;
47 }
48
49 #if defined(CONFIG_OF)
50 static struct of_device_id w1_gpio_dt_ids[] = {
51         { .compatible = "w1-gpio" },
52         {}
53 };
54 MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids);
55 #endif
56
57 static int w1_gpio_probe_dt(struct platform_device *pdev)
58 {
59         struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
60         struct device_node *np = pdev->dev.of_node;
61         int gpio;
62
63         pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
64         if (!pdata)
65                 return -ENOMEM;
66
67         if (of_get_property(np, "linux,open-drain", NULL))
68                 pdata->is_open_drain = 1;
69
70         gpio = of_get_gpio(np, 0);
71         if (gpio < 0)
72                 return gpio;
73         pdata->pin = gpio;
74
75         pdata->ext_pullup_enable_pin = of_get_gpio(np, 1);
76         pdev->dev.platform_data = pdata;
77
78         return 0;
79 }
80
81 static int w1_gpio_probe(struct platform_device *pdev)
82 {
83         struct w1_bus_master *master;
84         struct w1_gpio_platform_data *pdata;
85         int err;
86
87         if (of_have_populated_dt()) {
88                 err = w1_gpio_probe_dt(pdev);
89                 if (err < 0) {
90                         dev_err(&pdev->dev, "Failed to parse DT\n");
91                         return err;
92                 }
93         }
94
95         pdata = pdev->dev.platform_data;
96
97         if (!pdata) {
98                 dev_err(&pdev->dev, "No configuration data\n");
99                 return -ENXIO;
100         }
101
102         master = kzalloc(sizeof(struct w1_bus_master), GFP_KERNEL);
103         if (!master) {
104                 dev_err(&pdev->dev, "Out of memory\n");
105                 return -ENOMEM;
106         }
107
108         err = gpio_request(pdata->pin, "w1");
109         if (err) {
110                 dev_err(&pdev->dev, "gpio_request (pin) failed\n");
111                 goto free_master;
112         }
113
114         if (gpio_is_valid(pdata->ext_pullup_enable_pin)) {
115                 err = gpio_request_one(pdata->ext_pullup_enable_pin,
116                                        GPIOF_INIT_LOW, "w1 pullup");
117                 if (err < 0) {
118                         dev_err(&pdev->dev, "gpio_request_one "
119                                         "(ext_pullup_enable_pin) failed\n");
120                         goto free_gpio;
121                 }
122         }
123
124         master->data = pdata;
125         master->read_bit = w1_gpio_read_bit;
126
127         if (pdata->is_open_drain) {
128                 gpio_direction_output(pdata->pin, 1);
129                 master->write_bit = w1_gpio_write_bit_val;
130         } else {
131                 gpio_direction_input(pdata->pin);
132                 master->write_bit = w1_gpio_write_bit_dir;
133         }
134
135         err = w1_add_master_device(master);
136         if (err) {
137                 dev_err(&pdev->dev, "w1_add_master device failed\n");
138                 goto free_gpio_ext_pu;
139         }
140
141         if (pdata->enable_external_pullup)
142                 pdata->enable_external_pullup(1);
143
144         if (gpio_is_valid(pdata->ext_pullup_enable_pin))
145                 gpio_set_value(pdata->ext_pullup_enable_pin, 1);
146
147         platform_set_drvdata(pdev, master);
148
149         return 0;
150
151  free_gpio_ext_pu:
152         if (gpio_is_valid(pdata->ext_pullup_enable_pin))
153                 gpio_free(pdata->ext_pullup_enable_pin);
154  free_gpio:
155         gpio_free(pdata->pin);
156  free_master:
157         kfree(master);
158
159         return err;
160 }
161
162 static int w1_gpio_remove(struct platform_device *pdev)
163 {
164         struct w1_bus_master *master = platform_get_drvdata(pdev);
165         struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
166
167         if (pdata->enable_external_pullup)
168                 pdata->enable_external_pullup(0);
169
170         if (gpio_is_valid(pdata->ext_pullup_enable_pin))
171                 gpio_set_value(pdata->ext_pullup_enable_pin, 0);
172
173         w1_remove_master_device(master);
174         gpio_free(pdata->pin);
175         kfree(master);
176
177         return 0;
178 }
179
180 #ifdef CONFIG_PM
181
182 static int w1_gpio_suspend(struct platform_device *pdev, pm_message_t state)
183 {
184         struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
185
186         if (pdata->enable_external_pullup)
187                 pdata->enable_external_pullup(0);
188
189         return 0;
190 }
191
192 static int w1_gpio_resume(struct platform_device *pdev)
193 {
194         struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
195
196         if (pdata->enable_external_pullup)
197                 pdata->enable_external_pullup(1);
198
199         return 0;
200 }
201
202 #else
203 #define w1_gpio_suspend NULL
204 #define w1_gpio_resume  NULL
205 #endif
206
207 static struct platform_driver w1_gpio_driver = {
208         .driver = {
209                 .name   = "w1-gpio",
210                 .owner  = THIS_MODULE,
211                 .of_match_table = of_match_ptr(w1_gpio_dt_ids),
212         },
213         .probe = w1_gpio_probe,
214         .remove = w1_gpio_remove,
215         .suspend = w1_gpio_suspend,
216         .resume = w1_gpio_resume,
217 };
218
219 module_platform_driver(w1_gpio_driver);
220
221 MODULE_DESCRIPTION("GPIO w1 bus master driver");
222 MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>");
223 MODULE_LICENSE("GPL");