Commit ad8dc96e3b2c3e28854e0de4ab49351ed547b30c
Committed by
Linus Torvalds
1 parent
4cdf854f7d
Exists in
master
and in
39 other branches
w1-gpio: add GPIO w1 bus master driver
Add a GPIO 1-wire bus master driver. The driver used the GPIO API to control the wire and the GPIO pin can be specified using platform data similar to i2c-gpio. The driver was tested with AT91SAM9260 + DS2401. Signed-off-by: Ville Syrjala <syrjala@sci.fi> Cc: Evgeniy Polyakov <johnpol@2ka.mipt.ru> Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 6 changed files with 193 additions and 0 deletions Side-by-side Diff
Documentation/w1/masters/00-INDEX
Documentation/w1/masters/w1-gpio
1 | +Kernel driver w1-gpio | |
2 | +===================== | |
3 | + | |
4 | +Author: Ville Syrjala <syrjala@sci.fi> | |
5 | + | |
6 | + | |
7 | +Description | |
8 | +----------- | |
9 | + | |
10 | +GPIO 1-wire bus master driver. The driver uses the GPIO API to control the | |
11 | +wire and the GPIO pin can be specified using platform data. | |
12 | + | |
13 | + | |
14 | +Example (mach-at91) | |
15 | +------------------- | |
16 | + | |
17 | +#include <linux/w1-gpio.h> | |
18 | + | |
19 | +static struct w1_gpio_platform_data foo_w1_gpio_pdata = { | |
20 | + .pin = AT91_PIN_PB20, | |
21 | + .is_open_drain = 1, | |
22 | +}; | |
23 | + | |
24 | +static struct platform_device foo_w1_device = { | |
25 | + .name = "w1-gpio", | |
26 | + .id = -1, | |
27 | + .dev.platform_data = &foo_w1_gpio_pdata, | |
28 | +}; | |
29 | + | |
30 | +... | |
31 | + at91_set_GPIO_periph(foo_w1_gpio_pdata.pin, 1); | |
32 | + at91_set_multi_drive(foo_w1_gpio_pdata.pin, 1); | |
33 | + platform_device_register(&foo_w1_device); |
drivers/w1/masters/Kconfig
... | ... | @@ -42,5 +42,15 @@ |
42 | 42 | in HP iPAQ devices like h5xxx, h2200, and ASIC3-based like |
43 | 43 | hx4700. |
44 | 44 | |
45 | +config W1_MASTER_GPIO | |
46 | + tristate "GPIO 1-wire busmaster" | |
47 | + depends on GENERIC_GPIO | |
48 | + help | |
49 | + Say Y here if you want to communicate with your 1-wire devices using | |
50 | + GPIO pins. This driver uses the GPIO API to control the wire. | |
51 | + | |
52 | + This support is also available as a module. If so, the module | |
53 | + will be called w1-gpio.ko. | |
54 | + | |
45 | 55 | endmenu |
drivers/w1/masters/Makefile
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/w1-gpio.h> | |
15 | + | |
16 | +#include "../w1.h" | |
17 | +#include "../w1_int.h" | |
18 | + | |
19 | +#include <asm/gpio.h> | |
20 | + | |
21 | +static void w1_gpio_write_bit_dir(void *data, u8 bit) | |
22 | +{ | |
23 | + struct w1_gpio_platform_data *pdata = data; | |
24 | + | |
25 | + if (bit) | |
26 | + gpio_direction_input(pdata->pin); | |
27 | + else | |
28 | + gpio_direction_output(pdata->pin, 0); | |
29 | +} | |
30 | + | |
31 | +static void w1_gpio_write_bit_val(void *data, u8 bit) | |
32 | +{ | |
33 | + struct w1_gpio_platform_data *pdata = data; | |
34 | + | |
35 | + gpio_set_value(pdata->pin, bit); | |
36 | +} | |
37 | + | |
38 | +static u8 w1_gpio_read_bit(void *data) | |
39 | +{ | |
40 | + struct w1_gpio_platform_data *pdata = data; | |
41 | + | |
42 | + return gpio_get_value(pdata->pin); | |
43 | +} | |
44 | + | |
45 | +static int __init w1_gpio_probe(struct platform_device *pdev) | |
46 | +{ | |
47 | + struct w1_bus_master *master; | |
48 | + struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; | |
49 | + int err; | |
50 | + | |
51 | + if (!pdata) | |
52 | + return -ENXIO; | |
53 | + | |
54 | + master = kzalloc(sizeof(struct w1_bus_master), GFP_KERNEL); | |
55 | + if (!master) | |
56 | + return -ENOMEM; | |
57 | + | |
58 | + err = gpio_request(pdata->pin, "w1"); | |
59 | + if (err) | |
60 | + goto free_master; | |
61 | + | |
62 | + master->data = pdata; | |
63 | + master->read_bit = w1_gpio_read_bit; | |
64 | + | |
65 | + if (pdata->is_open_drain) { | |
66 | + gpio_direction_output(pdata->pin, 1); | |
67 | + master->write_bit = w1_gpio_write_bit_val; | |
68 | + } else { | |
69 | + gpio_direction_input(pdata->pin); | |
70 | + master->write_bit = w1_gpio_write_bit_dir; | |
71 | + } | |
72 | + | |
73 | + err = w1_add_master_device(master); | |
74 | + if (err) | |
75 | + goto free_gpio; | |
76 | + | |
77 | + platform_set_drvdata(pdev, master); | |
78 | + | |
79 | + return 0; | |
80 | + | |
81 | + free_gpio: | |
82 | + gpio_free(pdata->pin); | |
83 | + free_master: | |
84 | + kfree(master); | |
85 | + | |
86 | + return err; | |
87 | +} | |
88 | + | |
89 | +static int __exit w1_gpio_remove(struct platform_device *pdev) | |
90 | +{ | |
91 | + struct w1_bus_master *master = platform_get_drvdata(pdev); | |
92 | + struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; | |
93 | + | |
94 | + w1_remove_master_device(master); | |
95 | + gpio_free(pdata->pin); | |
96 | + kfree(master); | |
97 | + | |
98 | + return 0; | |
99 | +} | |
100 | + | |
101 | +static struct platform_driver w1_gpio_driver = { | |
102 | + .driver = { | |
103 | + .name = "w1-gpio", | |
104 | + .owner = THIS_MODULE, | |
105 | + }, | |
106 | + .remove = __exit_p(w1_gpio_remove), | |
107 | +}; | |
108 | + | |
109 | +static int __init w1_gpio_init(void) | |
110 | +{ | |
111 | + return platform_driver_probe(&w1_gpio_driver, w1_gpio_probe); | |
112 | +} | |
113 | + | |
114 | +static void __exit w1_gpio_exit(void) | |
115 | +{ | |
116 | + platform_driver_unregister(&w1_gpio_driver); | |
117 | +} | |
118 | + | |
119 | +module_init(w1_gpio_init); | |
120 | +module_exit(w1_gpio_exit); | |
121 | + | |
122 | +MODULE_DESCRIPTION("GPIO w1 bus master driver"); | |
123 | +MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>"); | |
124 | +MODULE_LICENSE("GPL"); |
include/linux/w1-gpio.h
1 | +/* | |
2 | + * w1-gpio interface to platform code | |
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 | +#ifndef _LINUX_W1_GPIO_H | |
11 | +#define _LINUX_W1_GPIO_H | |
12 | + | |
13 | +/** | |
14 | + * struct w1_gpio_platform_data - Platform-dependent data for w1-gpio | |
15 | + * @pin: GPIO pin to use | |
16 | + * @is_open_drain: GPIO pin is configured as open drain | |
17 | + */ | |
18 | +struct w1_gpio_platform_data { | |
19 | + unsigned int pin; | |
20 | + unsigned int is_open_drain:1; | |
21 | +}; | |
22 | + | |
23 | +#endif /* _LINUX_W1_GPIO_H */ |