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