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#include <linux/delay.h> 22 23#include "../w1.h" 24#include "../w1_int.h" 25 26static u8 w1_gpio_set_pullup(void *data, int delay) 27{ 28 struct w1_gpio_platform_data *pdata = data; 29 30 if (delay) { 31 pdata->pullup_duration = delay; 32 } else { 33 if (pdata->pullup_duration) { 34 gpio_direction_output(pdata->pin, 1); 35 36 msleep(pdata->pullup_duration); 37 38 gpio_direction_input(pdata->pin); 39 } 40 pdata->pullup_duration = 0; 41 } 42 43 return 0; 44} 45 46static void w1_gpio_write_bit_dir(void *data, u8 bit) 47{ 48 struct w1_gpio_platform_data *pdata = data; 49 50 if (bit) 51 gpio_direction_input(pdata->pin); 52 else 53 gpio_direction_output(pdata->pin, 0); 54} 55 56static void w1_gpio_write_bit_val(void *data, u8 bit) 57{ 58 struct w1_gpio_platform_data *pdata = data; 59 60 gpio_set_value(pdata->pin, bit); 61} 62 63static u8 w1_gpio_read_bit(void *data) 64{ 65 struct w1_gpio_platform_data *pdata = data; 66 67 return gpio_get_value(pdata->pin) ? 1 : 0; 68} 69 70#if defined(CONFIG_OF) 71static const struct of_device_id w1_gpio_dt_ids[] = { 72 { .compatible = "w1-gpio" }, 73 {} 74}; 75MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids); 76#endif 77 78static int w1_gpio_probe_dt(struct platform_device *pdev) 79{ 80 struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); 81 struct device_node *np = pdev->dev.of_node; 82 int gpio; 83 84 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); 85 if (!pdata) 86 return -ENOMEM; 87 88 if (of_get_property(np, "linux,open-drain", NULL)) 89 pdata->is_open_drain = 1; 90 91 gpio = of_get_gpio(np, 0); 92 if (gpio < 0) { 93 if (gpio != -EPROBE_DEFER) 94 dev_err(&pdev->dev, 95 "Failed to parse gpio property for data pin (%d)\n", 96 gpio); 97 98 return gpio; 99 } 100 pdata->pin = gpio; 101 102 gpio = of_get_gpio(np, 1); 103 if (gpio == -EPROBE_DEFER) 104 return gpio; 105 /* ignore other errors as the pullup gpio is optional */ 106 pdata->ext_pullup_enable_pin = gpio; 107 108 pdev->dev.platform_data = pdata; 109 110 return 0; 111} 112 113static int w1_gpio_probe(struct platform_device *pdev) 114{ 115 struct w1_bus_master *master; 116 struct w1_gpio_platform_data *pdata; 117 int err; 118 119 if (of_have_populated_dt()) { 120 err = w1_gpio_probe_dt(pdev); 121 if (err < 0) 122 return err; 123 } 124 125 pdata = dev_get_platdata(&pdev->dev); 126 127 if (!pdata) { 128 dev_err(&pdev->dev, "No configuration data\n"); 129 return -ENXIO; 130 } 131 132 master = devm_kzalloc(&pdev->dev, sizeof(struct w1_bus_master), 133 GFP_KERNEL); 134 if (!master) { 135 dev_err(&pdev->dev, "Out of memory\n"); 136 return -ENOMEM; 137 } 138 139 err = devm_gpio_request(&pdev->dev, pdata->pin, "w1"); 140 if (err) { 141 dev_err(&pdev->dev, "gpio_request (pin) failed\n"); 142 return err; 143 } 144 145 if (gpio_is_valid(pdata->ext_pullup_enable_pin)) { 146 err = devm_gpio_request_one(&pdev->dev, 147 pdata->ext_pullup_enable_pin, GPIOF_INIT_LOW, 148 "w1 pullup"); 149 if (err < 0) { 150 dev_err(&pdev->dev, "gpio_request_one " 151 "(ext_pullup_enable_pin) failed\n"); 152 return err; 153 } 154 } 155 156 master->data = pdata; 157 master->read_bit = w1_gpio_read_bit; 158 159 if (pdata->is_open_drain) { 160 gpio_direction_output(pdata->pin, 1); 161 master->write_bit = w1_gpio_write_bit_val; 162 } else { 163 gpio_direction_input(pdata->pin); 164 master->write_bit = w1_gpio_write_bit_dir; 165 master->set_pullup = w1_gpio_set_pullup; 166 } 167 168 err = w1_add_master_device(master); 169 if (err) { 170 dev_err(&pdev->dev, "w1_add_master device failed\n"); 171 return err; 172 } 173 174 if (pdata->enable_external_pullup) 175 pdata->enable_external_pullup(1); 176 177 if (gpio_is_valid(pdata->ext_pullup_enable_pin)) 178 gpio_set_value(pdata->ext_pullup_enable_pin, 1); 179 180 platform_set_drvdata(pdev, master); 181 182 return 0; 183} 184 185static int w1_gpio_remove(struct platform_device *pdev) 186{ 187 struct w1_bus_master *master = platform_get_drvdata(pdev); 188 struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); 189 190 if (pdata->enable_external_pullup) 191 pdata->enable_external_pullup(0); 192 193 if (gpio_is_valid(pdata->ext_pullup_enable_pin)) 194 gpio_set_value(pdata->ext_pullup_enable_pin, 0); 195 196 w1_remove_master_device(master); 197 198 return 0; 199} 200 201#ifdef CONFIG_PM 202 203static int w1_gpio_suspend(struct platform_device *pdev, pm_message_t state) 204{ 205 struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); 206 207 if (pdata->enable_external_pullup) 208 pdata->enable_external_pullup(0); 209 210 return 0; 211} 212 213static int w1_gpio_resume(struct platform_device *pdev) 214{ 215 struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); 216 217 if (pdata->enable_external_pullup) 218 pdata->enable_external_pullup(1); 219 220 return 0; 221} 222 223#else 224#define w1_gpio_suspend NULL 225#define w1_gpio_resume NULL 226#endif 227 228static struct platform_driver w1_gpio_driver = { 229 .driver = { 230 .name = "w1-gpio", 231 .of_match_table = of_match_ptr(w1_gpio_dt_ids), 232 }, 233 .probe = w1_gpio_probe, 234 .remove = w1_gpio_remove, 235 .suspend = w1_gpio_suspend, 236 .resume = w1_gpio_resume, 237}; 238 239module_platform_driver(w1_gpio_driver); 240 241MODULE_DESCRIPTION("GPIO w1 bus master driver"); 242MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>"); 243MODULE_LICENSE("GPL"); 244