1 /* 2 * I2C multiplexer using GPIO API 3 * 4 * Peter Korsgaard <peter.korsgaard@barco.com> 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 as 8 * published by the Free Software Foundation. 9 */ 10 11 #include <linux/i2c.h> 12 #include <linux/i2c-mux.h> 13 #include <linux/i2c-mux-gpio.h> 14 #include <linux/platform_device.h> 15 #include <linux/module.h> 16 #include <linux/slab.h> 17 #include <linux/gpio.h> 18 #include "../../gpio/gpiolib.h" 19 #include <linux/of_gpio.h> 20 21 struct gpiomux { 22 struct i2c_mux_gpio_platform_data data; 23 unsigned gpio_base; 24 struct gpio_desc **gpios; 25 int *values; 26 }; 27 28 static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val) 29 { 30 int i; 31 32 for (i = 0; i < mux->data.n_gpios; i++) 33 mux->values[i] = (val >> i) & 1; 34 35 gpiod_set_array_value_cansleep(mux->data.n_gpios, 36 mux->gpios, mux->values); 37 } 38 39 static int i2c_mux_gpio_select(struct i2c_mux_core *muxc, u32 chan) 40 { 41 struct gpiomux *mux = i2c_mux_priv(muxc); 42 43 i2c_mux_gpio_set(mux, chan); 44 45 return 0; 46 } 47 48 static int i2c_mux_gpio_deselect(struct i2c_mux_core *muxc, u32 chan) 49 { 50 struct gpiomux *mux = i2c_mux_priv(muxc); 51 52 i2c_mux_gpio_set(mux, mux->data.idle); 53 54 return 0; 55 } 56 57 static int match_gpio_chip_by_label(struct gpio_chip *chip, 58 void *data) 59 { 60 return !strcmp(chip->label, data); 61 } 62 63 #ifdef CONFIG_OF 64 static int i2c_mux_gpio_probe_dt(struct gpiomux *mux, 65 struct platform_device *pdev) 66 { 67 struct device_node *np = pdev->dev.of_node; 68 struct device_node *adapter_np, *child; 69 struct i2c_adapter *adapter; 70 unsigned *values, *gpios; 71 int i = 0, ret; 72 73 if (!np) 74 return -ENODEV; 75 76 adapter_np = of_parse_phandle(np, "i2c-parent", 0); 77 if (!adapter_np) { 78 dev_err(&pdev->dev, "Cannot parse i2c-parent\n"); 79 return -ENODEV; 80 } 81 adapter = of_find_i2c_adapter_by_node(adapter_np); 82 of_node_put(adapter_np); 83 if (!adapter) 84 return -EPROBE_DEFER; 85 86 mux->data.parent = i2c_adapter_id(adapter); 87 put_device(&adapter->dev); 88 89 mux->data.n_values = of_get_child_count(np); 90 91 values = devm_kzalloc(&pdev->dev, 92 sizeof(*mux->data.values) * mux->data.n_values, 93 GFP_KERNEL); 94 if (!values) { 95 dev_err(&pdev->dev, "Cannot allocate values array"); 96 return -ENOMEM; 97 } 98 99 for_each_child_of_node(np, child) { 100 of_property_read_u32(child, "reg", values + i); 101 i++; 102 } 103 mux->data.values = values; 104 105 if (of_property_read_u32(np, "idle-state", &mux->data.idle)) 106 mux->data.idle = I2C_MUX_GPIO_NO_IDLE; 107 108 mux->data.n_gpios = of_gpio_named_count(np, "mux-gpios"); 109 if (mux->data.n_gpios < 0) { 110 dev_err(&pdev->dev, "Missing mux-gpios property in the DT.\n"); 111 return -EINVAL; 112 } 113 114 gpios = devm_kzalloc(&pdev->dev, 115 sizeof(*mux->data.gpios) * mux->data.n_gpios, GFP_KERNEL); 116 if (!gpios) { 117 dev_err(&pdev->dev, "Cannot allocate gpios array"); 118 return -ENOMEM; 119 } 120 121 for (i = 0; i < mux->data.n_gpios; i++) { 122 ret = of_get_named_gpio(np, "mux-gpios", i); 123 if (ret < 0) 124 return ret; 125 gpios[i] = ret; 126 } 127 128 mux->data.gpios = gpios; 129 130 return 0; 131 } 132 #else 133 static int i2c_mux_gpio_probe_dt(struct gpiomux *mux, 134 struct platform_device *pdev) 135 { 136 return 0; 137 } 138 #endif 139 140 static int i2c_mux_gpio_probe(struct platform_device *pdev) 141 { 142 struct i2c_mux_core *muxc; 143 struct gpiomux *mux; 144 struct i2c_adapter *parent; 145 struct i2c_adapter *root; 146 unsigned initial_state, gpio_base; 147 int i, ret; 148 149 mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL); 150 if (!mux) 151 return -ENOMEM; 152 153 if (!dev_get_platdata(&pdev->dev)) { 154 ret = i2c_mux_gpio_probe_dt(mux, pdev); 155 if (ret < 0) 156 return ret; 157 } else { 158 memcpy(&mux->data, dev_get_platdata(&pdev->dev), 159 sizeof(mux->data)); 160 } 161 162 /* 163 * If a GPIO chip name is provided, the GPIO pin numbers provided are 164 * relative to its base GPIO number. Otherwise they are absolute. 165 */ 166 if (mux->data.gpio_chip) { 167 struct gpio_chip *gpio; 168 169 gpio = gpiochip_find(mux->data.gpio_chip, 170 match_gpio_chip_by_label); 171 if (!gpio) 172 return -EPROBE_DEFER; 173 174 gpio_base = gpio->base; 175 } else { 176 gpio_base = 0; 177 } 178 179 parent = i2c_get_adapter(mux->data.parent); 180 if (!parent) 181 return -EPROBE_DEFER; 182 183 muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values, 184 mux->data.n_gpios * sizeof(*mux->gpios) + 185 mux->data.n_gpios * sizeof(*mux->values), 0, 186 i2c_mux_gpio_select, NULL); 187 if (!muxc) { 188 ret = -ENOMEM; 189 goto alloc_failed; 190 } 191 mux->gpios = muxc->priv; 192 mux->values = (int *)(mux->gpios + mux->data.n_gpios); 193 muxc->priv = mux; 194 195 platform_set_drvdata(pdev, muxc); 196 197 root = i2c_root_adapter(&parent->dev); 198 199 muxc->mux_locked = true; 200 mux->gpio_base = gpio_base; 201 202 if (mux->data.idle != I2C_MUX_GPIO_NO_IDLE) { 203 initial_state = mux->data.idle; 204 muxc->deselect = i2c_mux_gpio_deselect; 205 } else { 206 initial_state = mux->data.values[0]; 207 } 208 209 for (i = 0; i < mux->data.n_gpios; i++) { 210 struct device *gpio_dev; 211 struct gpio_desc *gpio_desc; 212 213 ret = gpio_request(gpio_base + mux->data.gpios[i], "i2c-mux-gpio"); 214 if (ret) { 215 dev_err(&pdev->dev, "Failed to request GPIO %d\n", 216 mux->data.gpios[i]); 217 goto err_request_gpio; 218 } 219 220 ret = gpio_direction_output(gpio_base + mux->data.gpios[i], 221 initial_state & (1 << i)); 222 if (ret) { 223 dev_err(&pdev->dev, 224 "Failed to set direction of GPIO %d to output\n", 225 mux->data.gpios[i]); 226 i++; /* gpio_request above succeeded, so must free */ 227 goto err_request_gpio; 228 } 229 230 gpio_desc = gpio_to_desc(gpio_base + mux->data.gpios[i]); 231 mux->gpios[i] = gpio_desc; 232 233 if (!muxc->mux_locked) 234 continue; 235 236 gpio_dev = &gpio_desc->gdev->dev; 237 muxc->mux_locked = i2c_root_adapter(gpio_dev) == root; 238 } 239 240 if (muxc->mux_locked) 241 dev_info(&pdev->dev, "mux-locked i2c mux\n"); 242 243 for (i = 0; i < mux->data.n_values; i++) { 244 u32 nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0; 245 unsigned int class = mux->data.classes ? mux->data.classes[i] : 0; 246 247 ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i], class); 248 if (ret) { 249 dev_err(&pdev->dev, "Failed to add adapter %d\n", i); 250 goto add_adapter_failed; 251 } 252 } 253 254 dev_info(&pdev->dev, "%d port mux on %s adapter\n", 255 mux->data.n_values, parent->name); 256 257 return 0; 258 259 add_adapter_failed: 260 i2c_mux_del_adapters(muxc); 261 i = mux->data.n_gpios; 262 err_request_gpio: 263 for (; i > 0; i--) 264 gpio_free(gpio_base + mux->data.gpios[i - 1]); 265 alloc_failed: 266 i2c_put_adapter(parent); 267 268 return ret; 269 } 270 271 static int i2c_mux_gpio_remove(struct platform_device *pdev) 272 { 273 struct i2c_mux_core *muxc = platform_get_drvdata(pdev); 274 struct gpiomux *mux = i2c_mux_priv(muxc); 275 int i; 276 277 i2c_mux_del_adapters(muxc); 278 279 for (i = 0; i < mux->data.n_gpios; i++) 280 gpio_free(mux->gpio_base + mux->data.gpios[i]); 281 282 i2c_put_adapter(muxc->parent); 283 284 return 0; 285 } 286 287 static const struct of_device_id i2c_mux_gpio_of_match[] = { 288 { .compatible = "i2c-mux-gpio", }, 289 {}, 290 }; 291 MODULE_DEVICE_TABLE(of, i2c_mux_gpio_of_match); 292 293 static struct platform_driver i2c_mux_gpio_driver = { 294 .probe = i2c_mux_gpio_probe, 295 .remove = i2c_mux_gpio_remove, 296 .driver = { 297 .name = "i2c-mux-gpio", 298 .of_match_table = i2c_mux_gpio_of_match, 299 }, 300 }; 301 302 module_platform_driver(i2c_mux_gpio_driver); 303 304 MODULE_DESCRIPTION("GPIO-based I2C multiplexer driver"); 305 MODULE_AUTHOR("Peter Korsgaard <peter.korsgaard@barco.com>"); 306 MODULE_LICENSE("GPL"); 307 MODULE_ALIAS("platform:i2c-mux-gpio"); 308