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/init.h> 16 #include <linux/module.h> 17 #include <linux/slab.h> 18 #include <linux/gpio.h> 19 #include <linux/of_gpio.h> 20 21 struct gpiomux { 22 struct i2c_adapter *parent; 23 struct i2c_adapter **adap; /* child busses */ 24 struct i2c_mux_gpio_platform_data data; 25 unsigned gpio_base; 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 gpio_set_value(mux->gpio_base + mux->data.gpios[i], 34 val & (1 << i)); 35 } 36 37 static int i2c_mux_gpio_select(struct i2c_adapter *adap, void *data, u32 chan) 38 { 39 struct gpiomux *mux = data; 40 41 i2c_mux_gpio_set(mux, mux->data.values[chan]); 42 43 return 0; 44 } 45 46 static int i2c_mux_gpio_deselect(struct i2c_adapter *adap, void *data, u32 chan) 47 { 48 struct gpiomux *mux = data; 49 50 i2c_mux_gpio_set(mux, mux->data.idle); 51 52 return 0; 53 } 54 55 static int match_gpio_chip_by_label(struct gpio_chip *chip, 56 void *data) 57 { 58 return !strcmp(chip->label, data); 59 } 60 61 #ifdef CONFIG_OF 62 static int i2c_mux_gpio_probe_dt(struct gpiomux *mux, 63 struct platform_device *pdev) 64 { 65 struct device_node *np = pdev->dev.of_node; 66 struct device_node *adapter_np, *child; 67 struct i2c_adapter *adapter; 68 unsigned *values, *gpios; 69 int i = 0, ret; 70 71 if (!np) 72 return -ENODEV; 73 74 adapter_np = of_parse_phandle(np, "i2c-parent", 0); 75 if (!adapter_np) { 76 dev_err(&pdev->dev, "Cannot parse i2c-parent\n"); 77 return -ENODEV; 78 } 79 adapter = of_find_i2c_adapter_by_node(adapter_np); 80 if (!adapter) { 81 dev_err(&pdev->dev, "Cannot find parent bus\n"); 82 return -EPROBE_DEFER; 83 } 84 mux->data.parent = i2c_adapter_id(adapter); 85 put_device(&adapter->dev); 86 87 mux->data.n_values = of_get_child_count(np); 88 89 values = devm_kzalloc(&pdev->dev, 90 sizeof(*mux->data.values) * mux->data.n_values, 91 GFP_KERNEL); 92 if (!values) { 93 dev_err(&pdev->dev, "Cannot allocate values array"); 94 return -ENOMEM; 95 } 96 97 for_each_child_of_node(np, child) { 98 of_property_read_u32(child, "reg", values + i); 99 i++; 100 } 101 mux->data.values = values; 102 103 if (of_property_read_u32(np, "idle-state", &mux->data.idle)) 104 mux->data.idle = I2C_MUX_GPIO_NO_IDLE; 105 106 mux->data.n_gpios = of_gpio_named_count(np, "mux-gpios"); 107 if (mux->data.n_gpios < 0) { 108 dev_err(&pdev->dev, "Missing mux-gpios property in the DT.\n"); 109 return -EINVAL; 110 } 111 112 gpios = devm_kzalloc(&pdev->dev, 113 sizeof(*mux->data.gpios) * mux->data.n_gpios, GFP_KERNEL); 114 if (!gpios) { 115 dev_err(&pdev->dev, "Cannot allocate gpios array"); 116 return -ENOMEM; 117 } 118 119 for (i = 0; i < mux->data.n_gpios; i++) { 120 ret = of_get_named_gpio(np, "mux-gpios", i); 121 if (ret < 0) 122 return ret; 123 gpios[i] = ret; 124 } 125 126 mux->data.gpios = gpios; 127 128 return 0; 129 } 130 #else 131 static int i2c_mux_gpio_probe_dt(struct gpiomux *mux, 132 struct platform_device *pdev) 133 { 134 return 0; 135 } 136 #endif 137 138 static int i2c_mux_gpio_probe(struct platform_device *pdev) 139 { 140 struct gpiomux *mux; 141 struct i2c_adapter *parent; 142 int (*deselect) (struct i2c_adapter *, void *, u32); 143 unsigned initial_state, gpio_base; 144 int i, ret; 145 146 mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL); 147 if (!mux) { 148 dev_err(&pdev->dev, "Cannot allocate gpiomux structure"); 149 return -ENOMEM; 150 } 151 152 platform_set_drvdata(pdev, mux); 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 dev_err(&pdev->dev, "Parent adapter (%d) not found\n", 183 mux->data.parent); 184 return -EPROBE_DEFER; 185 } 186 187 mux->parent = parent; 188 mux->gpio_base = gpio_base; 189 190 mux->adap = devm_kzalloc(&pdev->dev, 191 sizeof(*mux->adap) * mux->data.n_values, 192 GFP_KERNEL); 193 if (!mux->adap) { 194 dev_err(&pdev->dev, "Cannot allocate i2c_adapter structure"); 195 ret = -ENOMEM; 196 goto alloc_failed; 197 } 198 199 if (mux->data.idle != I2C_MUX_GPIO_NO_IDLE) { 200 initial_state = mux->data.idle; 201 deselect = i2c_mux_gpio_deselect; 202 } else { 203 initial_state = mux->data.values[0]; 204 deselect = NULL; 205 } 206 207 for (i = 0; i < mux->data.n_gpios; i++) { 208 ret = gpio_request(gpio_base + mux->data.gpios[i], "i2c-mux-gpio"); 209 if (ret) { 210 dev_err(&pdev->dev, "Failed to request GPIO %d\n", 211 mux->data.gpios[i]); 212 goto err_request_gpio; 213 } 214 215 ret = gpio_direction_output(gpio_base + mux->data.gpios[i], 216 initial_state & (1 << i)); 217 if (ret) { 218 dev_err(&pdev->dev, 219 "Failed to set direction of GPIO %d to output\n", 220 mux->data.gpios[i]); 221 i++; /* gpio_request above succeeded, so must free */ 222 goto err_request_gpio; 223 } 224 } 225 226 for (i = 0; i < mux->data.n_values; i++) { 227 u32 nr = mux->data.base_nr ? (mux->data.base_nr + i) : 0; 228 unsigned int class = mux->data.classes ? mux->data.classes[i] : 0; 229 230 mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr, 231 i, class, 232 i2c_mux_gpio_select, deselect); 233 if (!mux->adap[i]) { 234 ret = -ENODEV; 235 dev_err(&pdev->dev, "Failed to add adapter %d\n", i); 236 goto add_adapter_failed; 237 } 238 } 239 240 dev_info(&pdev->dev, "%d port mux on %s adapter\n", 241 mux->data.n_values, parent->name); 242 243 return 0; 244 245 add_adapter_failed: 246 for (; i > 0; i--) 247 i2c_del_mux_adapter(mux->adap[i - 1]); 248 i = mux->data.n_gpios; 249 err_request_gpio: 250 for (; i > 0; i--) 251 gpio_free(gpio_base + mux->data.gpios[i - 1]); 252 alloc_failed: 253 i2c_put_adapter(parent); 254 255 return ret; 256 } 257 258 static int i2c_mux_gpio_remove(struct platform_device *pdev) 259 { 260 struct gpiomux *mux = platform_get_drvdata(pdev); 261 int i; 262 263 for (i = 0; i < mux->data.n_values; i++) 264 i2c_del_mux_adapter(mux->adap[i]); 265 266 for (i = 0; i < mux->data.n_gpios; i++) 267 gpio_free(mux->gpio_base + mux->data.gpios[i]); 268 269 i2c_put_adapter(mux->parent); 270 271 return 0; 272 } 273 274 static const struct of_device_id i2c_mux_gpio_of_match[] = { 275 { .compatible = "i2c-mux-gpio", }, 276 {}, 277 }; 278 MODULE_DEVICE_TABLE(of, i2c_mux_gpio_of_match); 279 280 static struct platform_driver i2c_mux_gpio_driver = { 281 .probe = i2c_mux_gpio_probe, 282 .remove = i2c_mux_gpio_remove, 283 .driver = { 284 .owner = THIS_MODULE, 285 .name = "i2c-mux-gpio", 286 .of_match_table = of_match_ptr(i2c_mux_gpio_of_match), 287 }, 288 }; 289 290 module_platform_driver(i2c_mux_gpio_driver); 291 292 MODULE_DESCRIPTION("GPIO-based I2C multiplexer driver"); 293 MODULE_AUTHOR("Peter Korsgaard <peter.korsgaard@barco.com>"); 294 MODULE_LICENSE("GPL"); 295 MODULE_ALIAS("platform:i2c-mux-gpio"); 296