Пример #1
0
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;
}
Пример #2
0
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;
}