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 26 static 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 46 static 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 56 static 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 63 static 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) 71 static struct of_device_id w1_gpio_dt_ids[] = { 72 { .compatible = "w1-gpio" }, 73 {} 74 }; 75 MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids); 76 #endif 77 78 static 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 return gpio; 94 pdata->pin = gpio; 95 96 pdata->ext_pullup_enable_pin = of_get_gpio(np, 1); 97 pdev->dev.platform_data = pdata; 98 99 return 0; 100 } 101 102 static int w1_gpio_probe(struct platform_device *pdev) 103 { 104 struct w1_bus_master *master; 105 struct w1_gpio_platform_data *pdata; 106 int err; 107 108 if (of_have_populated_dt()) { 109 err = w1_gpio_probe_dt(pdev); 110 if (err < 0) { 111 dev_err(&pdev->dev, "Failed to parse DT\n"); 112 return err; 113 } 114 } 115 116 pdata = dev_get_platdata(&pdev->dev); 117 118 if (!pdata) { 119 dev_err(&pdev->dev, "No configuration data\n"); 120 return -ENXIO; 121 } 122 123 master = devm_kzalloc(&pdev->dev, sizeof(struct w1_bus_master), 124 GFP_KERNEL); 125 if (!master) { 126 dev_err(&pdev->dev, "Out of memory\n"); 127 return -ENOMEM; 128 } 129 130 err = devm_gpio_request(&pdev->dev, pdata->pin, "w1"); 131 if (err) { 132 dev_err(&pdev->dev, "gpio_request (pin) failed\n"); 133 return err; 134 } 135 136 if (gpio_is_valid(pdata->ext_pullup_enable_pin)) { 137 err = devm_gpio_request_one(&pdev->dev, 138 pdata->ext_pullup_enable_pin, GPIOF_INIT_LOW, 139 "w1 pullup"); 140 if (err < 0) { 141 dev_err(&pdev->dev, "gpio_request_one " 142 "(ext_pullup_enable_pin) failed\n"); 143 return err; 144 } 145 } 146 147 master->data = pdata; 148 master->read_bit = w1_gpio_read_bit; 149 150 if (pdata->is_open_drain) { 151 gpio_direction_output(pdata->pin, 1); 152 master->write_bit = w1_gpio_write_bit_val; 153 } else { 154 gpio_direction_input(pdata->pin); 155 master->write_bit = w1_gpio_write_bit_dir; 156 master->set_pullup = w1_gpio_set_pullup; 157 } 158 159 err = w1_add_master_device(master); 160 if (err) { 161 dev_err(&pdev->dev, "w1_add_master device failed\n"); 162 return err; 163 } 164 165 if (pdata->enable_external_pullup) 166 pdata->enable_external_pullup(1); 167 168 if (gpio_is_valid(pdata->ext_pullup_enable_pin)) 169 gpio_set_value(pdata->ext_pullup_enable_pin, 1); 170 171 platform_set_drvdata(pdev, master); 172 173 return 0; 174 } 175 176 static int w1_gpio_remove(struct platform_device *pdev) 177 { 178 struct w1_bus_master *master = platform_get_drvdata(pdev); 179 struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); 180 181 if (pdata->enable_external_pullup) 182 pdata->enable_external_pullup(0); 183 184 if (gpio_is_valid(pdata->ext_pullup_enable_pin)) 185 gpio_set_value(pdata->ext_pullup_enable_pin, 0); 186 187 w1_remove_master_device(master); 188 189 return 0; 190 } 191 192 #ifdef CONFIG_PM 193 194 static int w1_gpio_suspend(struct platform_device *pdev, pm_message_t state) 195 { 196 struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); 197 198 if (pdata->enable_external_pullup) 199 pdata->enable_external_pullup(0); 200 201 return 0; 202 } 203 204 static int w1_gpio_resume(struct platform_device *pdev) 205 { 206 struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev); 207 208 if (pdata->enable_external_pullup) 209 pdata->enable_external_pullup(1); 210 211 return 0; 212 } 213 214 #else 215 #define w1_gpio_suspend NULL 216 #define w1_gpio_resume NULL 217 #endif 218 219 static struct platform_driver w1_gpio_driver = { 220 .driver = { 221 .name = "w1-gpio", 222 .owner = THIS_MODULE, 223 .of_match_table = of_match_ptr(w1_gpio_dt_ids), 224 }, 225 .probe = w1_gpio_probe, 226 .remove = w1_gpio_remove, 227 .suspend = w1_gpio_suspend, 228 .resume = w1_gpio_resume, 229 }; 230 231 module_platform_driver(w1_gpio_driver); 232 233 MODULE_DESCRIPTION("GPIO w1 bus master driver"); 234 MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>"); 235 MODULE_LICENSE("GPL"); 236