static int ads131e08_probe()

in adc/ti-ads131e08.c [803:929]


static int ads131e08_probe(struct spi_device *spi)
{
	const struct ads131e08_info *info;
	struct ads131e08_state *st;
	struct iio_dev *indio_dev;
	unsigned long adc_clk_hz;
	unsigned long adc_clk_ns;
	int ret;

	info = device_get_match_data(&spi->dev);
	if (!info) {
		dev_err(&spi->dev, "failed to get match data\n");
		return -ENODEV;
	}

	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
	if (!indio_dev) {
		dev_err(&spi->dev, "failed to allocate IIO device\n");
		return -ENOMEM;
	}

	st = iio_priv(indio_dev);
	st->info = info;
	st->spi = spi;

	ret = ads131e08_alloc_channels(indio_dev);
	if (ret)
		return ret;

	indio_dev->name = st->info->name;
	indio_dev->info = &ads131e08_iio_info;
	indio_dev->modes = INDIO_DIRECT_MODE;

	init_completion(&st->completion);

	if (spi->irq) {
		ret = devm_request_irq(&spi->dev, spi->irq,
			ads131e08_interrupt,
			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
			spi->dev.driver->name, indio_dev);
		if (ret)
			return dev_err_probe(&spi->dev, ret,
					     "request irq failed\n");
	} else {
		dev_err(&spi->dev, "data ready IRQ missing\n");
		return -ENODEV;
	}

	st->trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d",
		indio_dev->name, iio_device_id(indio_dev));
	if (!st->trig) {
		dev_err(&spi->dev, "failed to allocate IIO trigger\n");
		return -ENOMEM;
	}

	st->trig->ops = &ads131e08_trigger_ops;
	st->trig->dev.parent = &spi->dev;
	iio_trigger_set_drvdata(st->trig, indio_dev);
	ret = devm_iio_trigger_register(&spi->dev, st->trig);
	if (ret) {
		dev_err(&spi->dev, "failed to register IIO trigger\n");
		return -ENOMEM;
	}

	indio_dev->trig = iio_trigger_get(st->trig);

	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev,
		NULL, &ads131e08_trigger_handler, NULL);
	if (ret) {
		dev_err(&spi->dev, "failed to setup IIO buffer\n");
		return ret;
	}

	st->vref_reg = devm_regulator_get_optional(&spi->dev, "vref");
	if (!IS_ERR(st->vref_reg)) {
		ret = regulator_enable(st->vref_reg);
		if (ret) {
			dev_err(&spi->dev,
				"failed to enable external vref supply\n");
			return ret;
		}

		ret = devm_add_action_or_reset(&spi->dev, ads131e08_regulator_disable, st);
		if (ret)
			return ret;
	} else {
		if (PTR_ERR(st->vref_reg) != -ENODEV)
			return PTR_ERR(st->vref_reg);

		st->vref_reg = NULL;
	}

	st->adc_clk = devm_clk_get(&spi->dev, "adc-clk");
	if (IS_ERR(st->adc_clk))
		return dev_err_probe(&spi->dev, PTR_ERR(st->adc_clk),
				     "failed to get the ADC clock\n");

	ret = clk_prepare_enable(st->adc_clk);
	if (ret) {
		dev_err(&spi->dev, "failed to prepare/enable the ADC clock\n");
		return ret;
	}

	ret = devm_add_action_or_reset(&spi->dev, ads131e08_clk_disable, st);
	if (ret)
		return ret;

	adc_clk_hz = clk_get_rate(st->adc_clk);
	if (!adc_clk_hz) {
		dev_err(&spi->dev, "failed to get the ADC clock rate\n");
		return  -EINVAL;
	}

	adc_clk_ns = NSEC_PER_SEC / adc_clk_hz;
	st->sdecode_delay_us = DIV_ROUND_UP(
		ADS131E08_WAIT_SDECODE_CYCLES * adc_clk_ns, NSEC_PER_USEC);
	st->reset_delay_us = DIV_ROUND_UP(
		ADS131E08_WAIT_RESET_CYCLES * adc_clk_ns, NSEC_PER_USEC);

	ret = ads131e08_initial_config(indio_dev);
	if (ret) {
		dev_err(&spi->dev, "initial configuration failed\n");
		return ret;
	}

	return devm_iio_device_register(&spi->dev, indio_dev);
}