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/platform_data/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_kcalloc(&pdev->dev, 92 mux->data.n_values, sizeof(*mux->data.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_kcalloc(&pdev->dev, 115 mux->data.n_gpios, sizeof(*mux->data.gpios), 116 GFP_KERNEL); 117 if (!gpios) { 118 dev_err(&pdev->dev, "Cannot allocate gpios array"); 119 return -ENOMEM; 120 } 121 122 for (i = 0; i < mux->data.n_gpios; i++) { 123 ret = of_get_named_gpio(np, "mux-gpios", i); 124 if (ret < 0) 125 return ret; 126 gpios[i] = ret; 127 } 128 129 mux->data.gpios = gpios; 130 131 return 0; 132 } 133 #else 134 static int i2c_mux_gpio_probe_dt(struct gpiomux *mux, 135 struct platform_device *pdev) 136 { 137 return 0; 138 } 139 #endif 140 141 static int i2c_mux_gpio_probe(struct platform_device *pdev) 142 { 143 struct i2c_mux_core *muxc; 144 struct gpiomux *mux; 145 struct i2c_adapter *parent; 146 struct i2c_adapter *root; 147 unsigned initial_state, gpio_base; 148 int i, ret; 149 150 mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL); 151 if (!mux) 152 return -ENOMEM; 153 154 if (!dev_get_platdata(&pdev->dev)) { 155 ret = i2c_mux_gpio_probe_dt(mux, pdev); 156 if (ret < 0) 157 return ret; 158 } else { 159 memcpy(&mux->data, dev_get_platdata(&pdev->dev), 160 sizeof(mux->data)); 161 } 162 163 /* 164 * If a GPIO chip name is provided, the GPIO pin numbers provided are 165 * relative to its base GPIO number. Otherwise they are absolute. 166 */ 167 if (mux->data.gpio_chip) { 168 struct gpio_chip *gpio; 169 170 gpio = gpiochip_find(mux->data.gpio_chip, 171 match_gpio_chip_by_label); 172 if (!gpio) 173 return -EPROBE_DEFER; 174 175 gpio_base = gpio->base; 176 } else { 177 gpio_base = 0; 178 } 179 180 parent = i2c_get_adapter(mux->data.parent); 181 if (!parent) 182 return -EPROBE_DEFER; 183 184 muxc = i2c_mux_alloc(parent, &pdev->dev, mux->data.n_values, 185 mux->data.n_gpios * sizeof(*mux->gpios) + 186 mux->data.n_gpios * sizeof(*mux->values), 0, 187 i2c_mux_gpio_select, NULL); 188 if (!muxc) { 189 ret = -ENOMEM; 190 goto alloc_failed; 191 } 192 mux->gpios = muxc->priv; 193 mux->values = (int *)(mux->gpios + mux->data.n_gpios); 194 muxc->priv = mux; 195 196 platform_set_drvdata(pdev, muxc); 197 198 root = i2c_root_adapter(&parent->dev); 199 200 muxc->mux_locked = true; 201 mux->gpio_base = gpio_base; 202 203 if (mux->data.idle != I2C_MUX_GPIO_NO_IDLE) { 204 initial_state = mux->data.idle; 205 muxc->deselect = i2c_mux_gpio_deselect; 206 } else { 207 initial_state = mux->data.values[0]; 208 } 209 210 for (i = 0; i < mux->data.n_gpios; i++) { 211 struct device *gpio_dev; 212 struct gpio_desc *gpio_desc; 213 214 ret = gpio_request(gpio_base + mux->data.gpios[i], "i2c-mux-gpio"); 215 if (ret) { 216 dev_err(&pdev->dev, "Failed to request GPIO %d\n", 217 mux->data.gpios[i]); 218 goto err_request_gpio; 219 } 220 221 ret = gpio_direction_output(gpio_base + mux->data.gpios[i], 222 initial_state & (1 << i)); 223 if (ret) { 224 dev_err(&pdev->dev, 225 "Failed to set direction of GPIO %d to output\n", 226 mux->data.gpios[i]); 227 i++; /* gpio_request above succeeded, so must free */ 228 goto err_request_gpio; 229 } 230 231 gpio_desc = gpio_to_desc(gpio_base + mux->data.gpios[i]); 232 mux->gpios[i] = gpio_desc; 233 234 if (!muxc->mux_locked) 235 continue; 236 237 gpio_dev = &gpio_desc->gdev->dev; 238 muxc->mux_locked = i2c_root_adapter(gpio_dev) == root; 239 } 240 241 if (muxc->mux_locked) 242 dev_info(&pdev->dev, "mux-locked i2c mux\n"); 243 244 for (i = 0; i < mux->data.n_values; i++) { 245 u32 nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0; 246 unsigned int class = mux->data.classes ? mux->data.classes[i] : 0; 247 248 ret = i2c_mux_add_adapter(muxc, nr, mux->data.values[i], class); 249 if (ret) 250 goto add_adapter_failed; 251 } 252 253 dev_info(&pdev->dev, "%d port mux on %s adapter\n", 254 mux->data.n_values, parent->name); 255 256 return 0; 257 258 add_adapter_failed: 259 i2c_mux_del_adapters(muxc); 260 i = mux->data.n_gpios; 261 err_request_gpio: 262 for (; i > 0; i--) 263 gpio_free(gpio_base + mux->data.gpios[i - 1]); 264 alloc_failed: 265 i2c_put_adapter(parent); 266 267 return ret; 268 } 269 270 static int i2c_mux_gpio_remove(struct platform_device *pdev) 271 { 272 struct i2c_mux_core *muxc = platform_get_drvdata(pdev); 273 struct gpiomux *mux = i2c_mux_priv(muxc); 274 int i; 275 276 i2c_mux_del_adapters(muxc); 277 278 for (i = 0; i < mux->data.n_gpios; i++) 279 gpio_free(mux->gpio_base + mux->data.gpios[i]); 280 281 i2c_put_adapter(muxc->parent); 282 283 return 0; 284 } 285 286 static const struct of_device_id i2c_mux_gpio_of_match[] = { 287 { .compatible = "i2c-mux-gpio", }, 288 {}, 289 }; 290 MODULE_DEVICE_TABLE(of, i2c_mux_gpio_of_match); 291 292 static struct platform_driver i2c_mux_gpio_driver = { 293 .probe = i2c_mux_gpio_probe, 294 .remove = i2c_mux_gpio_remove, 295 .driver = { 296 .name = "i2c-mux-gpio", 297 .of_match_table = i2c_mux_gpio_of_match, 298 }, 299 }; 300 301 module_platform_driver(i2c_mux_gpio_driver); 302 303 MODULE_DESCRIPTION("GPIO-based I2C multiplexer driver"); 304 MODULE_AUTHOR("Peter Korsgaard <peter.korsgaard@barco.com>"); 305 MODULE_LICENSE("GPL"); 306 MODULE_ALIAS("platform:i2c-mux-gpio"); 307