static int __devinit gpiomux_probe(struct platform_device *pdev) { struct gpiomux *mux; struct gpio_i2cmux_platform_data *pdata; struct i2c_adapter *parent; int (*deselect) (struct i2c_adapter *, void *, u32); unsigned initial_state; int i, ret; pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "Missing platform data\n"); return -ENODEV; } parent = i2c_get_adapter(pdata->parent); if (!parent) { dev_err(&pdev->dev, "Parent adapter (%d) not found\n", pdata->parent); return -ENODEV; } mux = kzalloc(sizeof(*mux), GFP_KERNEL); if (!mux) { ret = -ENOMEM; goto alloc_failed; } mux->parent = parent; mux->data = *pdata; mux->adap = kzalloc(sizeof(struct i2c_adapter *) * pdata->n_values, GFP_KERNEL); if (!mux->adap) { ret = -ENOMEM; goto alloc_failed2; } if (pdata->idle != GPIO_I2CMUX_NO_IDLE) { initial_state = pdata->idle; deselect = gpiomux_deselect; } else { initial_state = pdata->values[0]; deselect = NULL; } for (i = 0; i < pdata->n_gpios; i++) { ret = gpio_request(pdata->gpios[i], "gpio-i2cmux"); if (ret) goto err_request_gpio; gpio_direction_output(pdata->gpios[i], initial_state & (1 << i)); } for (i = 0; i < pdata->n_values; i++) { u32 nr = pdata->base_nr ? (pdata->base_nr + i) : 0; mux->adap[i] = i2c_add_mux_adapter(parent, mux, nr, i, gpiomux_select, deselect); if (!mux->adap[i]) { ret = -ENODEV; dev_err(&pdev->dev, "Failed to add adapter %d\n", i); goto add_adapter_failed; } } dev_info(&pdev->dev, "%d port mux on %s adapter\n", pdata->n_values, parent->name); platform_set_drvdata(pdev, mux); return 0; add_adapter_failed: for (; i > 0; i--) i2c_del_mux_adapter(mux->adap[i - 1]); i = pdata->n_gpios; err_request_gpio: for (; i > 0; i--) gpio_free(pdata->gpios[i - 1]); kfree(mux->adap); alloc_failed2: kfree(mux); alloc_failed: i2c_put_adapter(parent); return ret; }
static int i2c_arbitrator_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct device_node *parent_np; struct i2c_arbitrator_data *arb; enum of_gpio_flags gpio_flags; unsigned long out_init; int ret; /* We only support probing from device tree; no platform_data */ if (!np) { dev_err(dev, "Cannot find device tree node\n"); return -ENODEV; } if (dev->platform_data) { dev_err(dev, "Platform data is not supported\n"); return -EINVAL; } arb = devm_kzalloc(dev, sizeof(*arb), GFP_KERNEL); if (!arb) { dev_err(dev, "Cannot allocate i2c_arbitrator_data\n"); return -ENOMEM; } platform_set_drvdata(pdev, arb); /* Request GPIOs */ ret = of_get_named_gpio_flags(np, "our-claim-gpio", 0, &gpio_flags); if (!gpio_is_valid(ret)) { if (ret != -EPROBE_DEFER) dev_err(dev, "Error getting our-claim-gpio\n"); return ret; } arb->our_gpio = ret; arb->our_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW); out_init = (gpio_flags & OF_GPIO_ACTIVE_LOW) ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; ret = devm_gpio_request_one(dev, arb->our_gpio, out_init, "our-claim-gpio"); if (ret) { if (ret != -EPROBE_DEFER) dev_err(dev, "Error requesting our-claim-gpio\n"); return ret; } ret = of_get_named_gpio_flags(np, "their-claim-gpios", 0, &gpio_flags); if (!gpio_is_valid(ret)) { if (ret != -EPROBE_DEFER) dev_err(dev, "Error getting their-claim-gpio\n"); return ret; } arb->their_gpio = ret; arb->their_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW); ret = devm_gpio_request_one(dev, arb->their_gpio, GPIOF_IN, "their-claim-gpio"); if (ret) { if (ret != -EPROBE_DEFER) dev_err(dev, "Error requesting their-claim-gpio\n"); return ret; } /* At the moment we only support a single two master (us + 1 other) */ if (gpio_is_valid(of_get_named_gpio(np, "their-claim-gpios", 1))) { dev_err(dev, "Only one other master is supported\n"); return -EINVAL; } /* Arbitration parameters */ if (of_property_read_u32(np, "slew-delay-us", &arb->slew_delay_us)) arb->slew_delay_us = 10; if (of_property_read_u32(np, "wait-retry-us", &arb->wait_retry_us)) arb->wait_retry_us = 3000; if (of_property_read_u32(np, "wait-free-us", &arb->wait_free_us)) arb->wait_free_us = 50000; /* Find our parent */ parent_np = of_parse_phandle(np, "i2c-parent", 0); if (!parent_np) { dev_err(dev, "Cannot parse i2c-parent\n"); return -EINVAL; } arb->parent = of_find_i2c_adapter_by_node(parent_np); if (!arb->parent) { dev_err(dev, "Cannot find parent bus\n"); return -EINVAL; } /* Actually add the mux adapter */ arb->child = i2c_add_mux_adapter(arb->parent, dev, arb, 0, 0, 0, i2c_arbitrator_select, i2c_arbitrator_deselect); if (!arb->child) { dev_err(dev, "Failed to add adapter\n"); ret = -ENODEV; i2c_put_adapter(arb->parent); } return ret; }