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