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