1 /* 2 * GPIO-based I2C Arbitration Using a Challenge & Response Mechanism 3 * 4 * Copyright (C) 2012 Google, Inc 5 * 6 * This software is licensed under the terms of the GNU General Public 7 * License version 2, as published by the Free Software Foundation, and 8 * may be copied, distributed, and modified under those terms. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 */ 16 17 #include <linux/delay.h> 18 #include <linux/gpio.h> 19 #include <linux/kernel.h> 20 #include <linux/i2c.h> 21 #include <linux/i2c-mux.h> 22 #include <linux/init.h> 23 #include <linux/module.h> 24 #include <linux/of_gpio.h> 25 #include <linux/platform_device.h> 26 #include <linux/slab.h> 27 28 29 /** 30 * struct i2c_arbitrator_data - Driver data for I2C arbitrator 31 * 32 * @parent: Parent adapter 33 * @child: Child bus 34 * @our_gpio: GPIO we'll use to claim. 35 * @our_gpio_release: 0 if active high; 1 if active low; AKA if the GPIO == 36 * this then consider it released. 37 * @their_gpio: GPIO that the other side will use to claim. 38 * @their_gpio_release: 0 if active high; 1 if active low; AKA if the GPIO == 39 * this then consider it released. 40 * @slew_delay_us: microseconds to wait for a GPIO to go high. 41 * @wait_retry_us: we'll attempt another claim after this many microseconds. 42 * @wait_free_us: we'll give up after this many microseconds. 43 */ 44 45 struct i2c_arbitrator_data { 46 struct i2c_adapter *parent; 47 struct i2c_adapter *child; 48 int our_gpio; 49 int our_gpio_release; 50 int their_gpio; 51 int their_gpio_release; 52 unsigned int slew_delay_us; 53 unsigned int wait_retry_us; 54 unsigned int wait_free_us; 55 }; 56 57 58 /** 59 * i2c_arbitrator_select - claim the I2C bus 60 * 61 * Use the GPIO-based signalling protocol; return -EBUSY if we fail. 62 */ 63 static int i2c_arbitrator_select(struct i2c_adapter *adap, void *data, u32 chan) 64 { 65 const struct i2c_arbitrator_data *arb = data; 66 unsigned long stop_retry, stop_time; 67 68 /* Start a round of trying to claim the bus */ 69 stop_time = jiffies + usecs_to_jiffies(arb->wait_free_us) + 1; 70 do { 71 /* Indicate that we want to claim the bus */ 72 gpio_set_value(arb->our_gpio, !arb->our_gpio_release); 73 udelay(arb->slew_delay_us); 74 75 /* Wait for the other master to release it */ 76 stop_retry = jiffies + usecs_to_jiffies(arb->wait_retry_us) + 1; 77 while (time_before(jiffies, stop_retry)) { 78 int gpio_val = !!gpio_get_value(arb->their_gpio); 79 80 if (gpio_val == arb->their_gpio_release) { 81 /* We got it, so return */ 82 return 0; 83 } 84 85 usleep_range(50, 200); 86 } 87 88 /* It didn't release, so give up, wait, and try again */ 89 gpio_set_value(arb->our_gpio, arb->our_gpio_release); 90 91 usleep_range(arb->wait_retry_us, arb->wait_retry_us * 2); 92 } while (time_before(jiffies, stop_time)); 93 94 /* Give up, release our claim */ 95 gpio_set_value(arb->our_gpio, arb->our_gpio_release); 96 udelay(arb->slew_delay_us); 97 dev_err(&adap->dev, "Could not claim bus, timeout\n"); 98 return -EBUSY; 99 } 100 101 /** 102 * i2c_arbitrator_deselect - release the I2C bus 103 * 104 * Release the I2C bus using the GPIO-based signalling protocol. 105 */ 106 static int i2c_arbitrator_deselect(struct i2c_adapter *adap, void *data, 107 u32 chan) 108 { 109 const struct i2c_arbitrator_data *arb = data; 110 111 /* Release the bus and wait for the other master to notice */ 112 gpio_set_value(arb->our_gpio, arb->our_gpio_release); 113 udelay(arb->slew_delay_us); 114 115 return 0; 116 } 117 118 static int i2c_arbitrator_probe(struct platform_device *pdev) 119 { 120 struct device *dev = &pdev->dev; 121 struct device_node *np = dev->of_node; 122 struct device_node *parent_np; 123 struct i2c_arbitrator_data *arb; 124 enum of_gpio_flags gpio_flags; 125 unsigned long out_init; 126 int ret; 127 128 /* We only support probing from device tree; no platform_data */ 129 if (!np) { 130 dev_err(dev, "Cannot find device tree node\n"); 131 return -ENODEV; 132 } 133 if (dev_get_platdata(dev)) { 134 dev_err(dev, "Platform data is not supported\n"); 135 return -EINVAL; 136 } 137 138 arb = devm_kzalloc(dev, sizeof(*arb), GFP_KERNEL); 139 if (!arb) { 140 dev_err(dev, "Cannot allocate i2c_arbitrator_data\n"); 141 return -ENOMEM; 142 } 143 platform_set_drvdata(pdev, arb); 144 145 /* Request GPIOs */ 146 ret = of_get_named_gpio_flags(np, "our-claim-gpio", 0, &gpio_flags); 147 if (!gpio_is_valid(ret)) { 148 if (ret != -EPROBE_DEFER) 149 dev_err(dev, "Error getting our-claim-gpio\n"); 150 return ret; 151 } 152 arb->our_gpio = ret; 153 arb->our_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW); 154 out_init = (gpio_flags & OF_GPIO_ACTIVE_LOW) ? 155 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; 156 ret = devm_gpio_request_one(dev, arb->our_gpio, out_init, 157 "our-claim-gpio"); 158 if (ret) { 159 if (ret != -EPROBE_DEFER) 160 dev_err(dev, "Error requesting our-claim-gpio\n"); 161 return ret; 162 } 163 164 ret = of_get_named_gpio_flags(np, "their-claim-gpios", 0, &gpio_flags); 165 if (!gpio_is_valid(ret)) { 166 if (ret != -EPROBE_DEFER) 167 dev_err(dev, "Error getting their-claim-gpio\n"); 168 return ret; 169 } 170 arb->their_gpio = ret; 171 arb->their_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW); 172 ret = devm_gpio_request_one(dev, arb->their_gpio, GPIOF_IN, 173 "their-claim-gpio"); 174 if (ret) { 175 if (ret != -EPROBE_DEFER) 176 dev_err(dev, "Error requesting their-claim-gpio\n"); 177 return ret; 178 } 179 180 /* At the moment we only support a single two master (us + 1 other) */ 181 if (gpio_is_valid(of_get_named_gpio(np, "their-claim-gpios", 1))) { 182 dev_err(dev, "Only one other master is supported\n"); 183 return -EINVAL; 184 } 185 186 /* Arbitration parameters */ 187 if (of_property_read_u32(np, "slew-delay-us", &arb->slew_delay_us)) 188 arb->slew_delay_us = 10; 189 if (of_property_read_u32(np, "wait-retry-us", &arb->wait_retry_us)) 190 arb->wait_retry_us = 3000; 191 if (of_property_read_u32(np, "wait-free-us", &arb->wait_free_us)) 192 arb->wait_free_us = 50000; 193 194 /* Find our parent */ 195 parent_np = of_parse_phandle(np, "i2c-parent", 0); 196 if (!parent_np) { 197 dev_err(dev, "Cannot parse i2c-parent\n"); 198 return -EINVAL; 199 } 200 arb->parent = of_find_i2c_adapter_by_node(parent_np); 201 if (!arb->parent) { 202 dev_err(dev, "Cannot find parent bus\n"); 203 return -EPROBE_DEFER; 204 } 205 206 /* Actually add the mux adapter */ 207 arb->child = i2c_add_mux_adapter(arb->parent, dev, arb, 0, 0, 0, 208 i2c_arbitrator_select, 209 i2c_arbitrator_deselect); 210 if (!arb->child) { 211 dev_err(dev, "Failed to add adapter\n"); 212 ret = -ENODEV; 213 i2c_put_adapter(arb->parent); 214 } 215 216 return ret; 217 } 218 219 static int i2c_arbitrator_remove(struct platform_device *pdev) 220 { 221 struct i2c_arbitrator_data *arb = platform_get_drvdata(pdev); 222 223 i2c_del_mux_adapter(arb->child); 224 i2c_put_adapter(arb->parent); 225 226 return 0; 227 } 228 229 static const struct of_device_id i2c_arbitrator_of_match[] = { 230 { .compatible = "i2c-arb-gpio-challenge", }, 231 {}, 232 }; 233 MODULE_DEVICE_TABLE(of, i2c_arbitrator_of_match); 234 235 static struct platform_driver i2c_arbitrator_driver = { 236 .probe = i2c_arbitrator_probe, 237 .remove = i2c_arbitrator_remove, 238 .driver = { 239 .owner = THIS_MODULE, 240 .name = "i2c-arb-gpio-challenge", 241 .of_match_table = i2c_arbitrator_of_match, 242 }, 243 }; 244 245 module_platform_driver(i2c_arbitrator_driver); 246 247 MODULE_DESCRIPTION("GPIO-based I2C Arbitration"); 248 MODULE_AUTHOR("Doug Anderson <dianders@chromium.org>"); 249 MODULE_LICENSE("GPL v2"); 250 MODULE_ALIAS("platform:i2c-arb-gpio-challenge"); 251