w1-gpio.c 5.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * w1-gpio - GPIO w1 bus master driver
 *
 * Copyright (C) 2007 Ville Syrjala <syrjala@sci.fi>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2
 * as published by the Free Software Foundation.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
14
#include <linux/slab.h>
15
#include <linux/w1-gpio.h>
16
#include <linux/gpio.h>
D
Daniel Mack 已提交
17 18
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
P
Pantelis Antoniou 已提交
19 20
#include <linux/pinctrl/consumer.h>
#include <linux/err.h>
21
#include <linux/of.h>
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

#include "../w1.h"
#include "../w1_int.h"

static void w1_gpio_write_bit_dir(void *data, u8 bit)
{
	struct w1_gpio_platform_data *pdata = data;

	if (bit)
		gpio_direction_input(pdata->pin);
	else
		gpio_direction_output(pdata->pin, 0);
}

static void w1_gpio_write_bit_val(void *data, u8 bit)
{
	struct w1_gpio_platform_data *pdata = data;

	gpio_set_value(pdata->pin, bit);
}

static u8 w1_gpio_read_bit(void *data)
{
	struct w1_gpio_platform_data *pdata = data;

47
	return gpio_get_value(pdata->pin) ? 1 : 0;
48 49
}

D
Daniel Mack 已提交
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
static struct of_device_id w1_gpio_dt_ids[] = {
	{ .compatible = "w1-gpio" },
	{}
};
MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids);

static int w1_gpio_probe_dt(struct platform_device *pdev)
{
	struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
	struct device_node *np = pdev->dev.of_node;

	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;

	if (of_get_property(np, "linux,open-drain", NULL))
		pdata->is_open_drain = 1;

	pdata->pin = of_get_gpio(np, 0);
	pdata->ext_pullup_enable_pin = of_get_gpio(np, 1);
	pdev->dev.platform_data = pdata;

	return 0;
}

H
Hauke Mehrtens 已提交
75
static int w1_gpio_probe(struct platform_device *pdev)
76 77
{
	struct w1_bus_master *master;
D
Daniel Mack 已提交
78
	struct w1_gpio_platform_data *pdata;
P
Pantelis Antoniou 已提交
79
	struct pinctrl *pinctrl;
80 81
	int err;

P
Pantelis Antoniou 已提交
82 83 84 85
	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
	if (IS_ERR(pinctrl))
		dev_warn(&pdev->dev, "unable to select pin group\n");

86 87 88 89 90 91 92
	if (of_have_populated_dt()) {
		err = w1_gpio_probe_dt(pdev);
		if (err < 0) {
			dev_err(&pdev->dev, "Failed to parse DT\n");
			return err;
		}
	}
D
Daniel Mack 已提交
93 94 95

	pdata = pdev->dev.platform_data;

96 97
	if (!pdata) {
		dev_err(&pdev->dev, "No configuration data\n");
98
		return -ENXIO;
99
	}
100 101

	master = kzalloc(sizeof(struct w1_bus_master), GFP_KERNEL);
102 103
	if (!master) {
		dev_err(&pdev->dev, "Out of memory\n");
104
		return -ENOMEM;
105
	}
106 107

	err = gpio_request(pdata->pin, "w1");
108 109
	if (err) {
		dev_err(&pdev->dev, "gpio_request (pin) failed\n");
110
		goto free_master;
111
	}
112

113 114 115
	if (gpio_is_valid(pdata->ext_pullup_enable_pin)) {
		err = gpio_request_one(pdata->ext_pullup_enable_pin,
				       GPIOF_INIT_LOW, "w1 pullup");
116 117 118
		if (err < 0) {
			dev_err(&pdev->dev, "gpio_request_one "
					"(ext_pullup_enable_pin) failed\n");
119
			goto free_gpio;
120
		}
121 122
	}

123 124 125 126 127 128 129 130 131 132 133 134
	master->data = pdata;
	master->read_bit = w1_gpio_read_bit;

	if (pdata->is_open_drain) {
		gpio_direction_output(pdata->pin, 1);
		master->write_bit = w1_gpio_write_bit_val;
	} else {
		gpio_direction_input(pdata->pin);
		master->write_bit = w1_gpio_write_bit_dir;
	}

	err = w1_add_master_device(master);
135 136
	if (err) {
		dev_err(&pdev->dev, "w1_add_master device failed\n");
137
		goto free_gpio_ext_pu;
138
	}
139

140 141 142
	if (pdata->enable_external_pullup)
		pdata->enable_external_pullup(1);

143 144 145
	if (gpio_is_valid(pdata->ext_pullup_enable_pin))
		gpio_set_value(pdata->ext_pullup_enable_pin, 1);

146 147 148 149
	platform_set_drvdata(pdev, master);

	return 0;

150 151 152
 free_gpio_ext_pu:
	if (gpio_is_valid(pdata->ext_pullup_enable_pin))
		gpio_free(pdata->ext_pullup_enable_pin);
153 154 155 156 157 158 159 160 161 162 163 164 165
 free_gpio:
	gpio_free(pdata->pin);
 free_master:
	kfree(master);

	return err;
}

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;

166 167 168
	if (pdata->enable_external_pullup)
		pdata->enable_external_pullup(0);

169 170 171
	if (gpio_is_valid(pdata->ext_pullup_enable_pin))
		gpio_set_value(pdata->ext_pullup_enable_pin, 0);

172 173 174 175 176 177 178
	w1_remove_master_device(master);
	gpio_free(pdata->pin);
	kfree(master);

	return 0;
}

179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
#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

206 207 208 209
static struct platform_driver w1_gpio_driver = {
	.driver = {
		.name	= "w1-gpio",
		.owner	= THIS_MODULE,
D
Daniel Mack 已提交
210
		.of_match_table = of_match_ptr(w1_gpio_dt_ids),
211
	},
212
	.probe = w1_gpio_probe,
213
	.remove	= __exit_p(w1_gpio_remove),
214 215
	.suspend = w1_gpio_suspend,
	.resume = w1_gpio_resume,
216 217
};

218
module_platform_driver(w1_gpio_driver);
219 220 221 222

MODULE_DESCRIPTION("GPIO w1 bus master driver");
MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>");
MODULE_LICENSE("GPL");