static int xadc_probe()

in adc/xilinx-xadc-core.c [1316:1480]


static int xadc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	const struct of_device_id *id;
	const struct xadc_ops *ops;
	struct iio_dev *indio_dev;
	unsigned int bipolar_mask;
	unsigned int conf0;
	struct xadc *xadc;
	int ret;
	int irq;
	int i;

	if (!dev->of_node)
		return -ENODEV;

	id = of_match_node(xadc_of_match_table, dev->of_node);
	if (!id)
		return -EINVAL;

	ops = id->data;

	irq = platform_get_irq_optional(pdev, 0);
	if (irq < 0 &&
	    (irq != -ENXIO || !(ops->flags & XADC_FLAGS_IRQ_OPTIONAL)))
		return irq;

	indio_dev = devm_iio_device_alloc(dev, sizeof(*xadc));
	if (!indio_dev)
		return -ENOMEM;

	xadc = iio_priv(indio_dev);
	xadc->ops = id->data;
	init_completion(&xadc->completion);
	mutex_init(&xadc->mutex);
	spin_lock_init(&xadc->lock);
	INIT_DELAYED_WORK(&xadc->zynq_unmask_work, xadc_zynq_unmask_worker);

	xadc->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(xadc->base))
		return PTR_ERR(xadc->base);

	indio_dev->name = xadc_type_names[xadc->ops->type];
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->info = &xadc_info;

	ret = xadc_parse_dt(indio_dev, dev->of_node, &conf0, irq);
	if (ret)
		return ret;

	if (xadc->ops->flags & XADC_FLAGS_BUFFERED) {
		ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
						      &iio_pollfunc_store_time,
						      &xadc_trigger_handler,
						      &xadc_buffer_ops);
		if (ret)
			return ret;

		if (irq > 0) {
			xadc->convst_trigger = xadc_alloc_trigger(indio_dev, "convst");
			if (IS_ERR(xadc->convst_trigger))
				return PTR_ERR(xadc->convst_trigger);

			xadc->samplerate_trigger = xadc_alloc_trigger(indio_dev,
				"samplerate");
			if (IS_ERR(xadc->samplerate_trigger))
				return PTR_ERR(xadc->samplerate_trigger);
		}
	}

	xadc->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(xadc->clk))
		return PTR_ERR(xadc->clk);

	ret = clk_prepare_enable(xadc->clk);
	if (ret)
		return ret;

	ret = devm_add_action_or_reset(dev,
				       xadc_clk_disable_unprepare, xadc->clk);
	if (ret)
		return ret;

	/*
	 * Make sure not to exceed the maximum samplerate since otherwise the
	 * resulting interrupt storm will soft-lock the system.
	 */
	if (xadc->ops->flags & XADC_FLAGS_BUFFERED) {
		ret = xadc_read_samplerate(xadc);
		if (ret < 0)
			return ret;

		if (ret > XADC_MAX_SAMPLERATE) {
			ret = xadc_write_samplerate(xadc, XADC_MAX_SAMPLERATE);
			if (ret < 0)
				return ret;
		}
	}

	if (irq > 0) {
		ret = devm_request_irq(dev, irq, xadc->ops->interrupt_handler,
				       0, dev_name(dev), indio_dev);
		if (ret)
			return ret;

		ret = devm_add_action_or_reset(dev, xadc_cancel_delayed_work,
					       &xadc->zynq_unmask_work);
		if (ret)
			return ret;
	}

	ret = xadc->ops->setup(pdev, indio_dev, irq);
	if (ret)
		return ret;

	for (i = 0; i < 16; i++)
		xadc_read_adc_reg(xadc, XADC_REG_THRESHOLD(i),
			&xadc->threshold[i]);

	ret = xadc_write_adc_reg(xadc, XADC_REG_CONF0, conf0);
	if (ret)
		return ret;

	bipolar_mask = 0;
	for (i = 0; i < indio_dev->num_channels; i++) {
		if (indio_dev->channels[i].scan_type.sign == 's')
			bipolar_mask |= BIT(indio_dev->channels[i].scan_index);
	}

	ret = xadc_write_adc_reg(xadc, XADC_REG_INPUT_MODE(0), bipolar_mask);
	if (ret)
		return ret;

	ret = xadc_write_adc_reg(xadc, XADC_REG_INPUT_MODE(1),
		bipolar_mask >> 16);
	if (ret)
		return ret;

	/* Disable all alarms */
	ret = xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF1_ALARM_MASK,
				  XADC_CONF1_ALARM_MASK);
	if (ret)
		return ret;

	/* Set thresholds to min/max */
	for (i = 0; i < 16; i++) {
		/*
		 * Set max voltage threshold and both temperature thresholds to
		 * 0xffff, min voltage threshold to 0.
		 */
		if (i % 8 < 4 || i == 7)
			xadc->threshold[i] = 0xffff;
		else
			xadc->threshold[i] = 0;
		ret = xadc_write_adc_reg(xadc, XADC_REG_THRESHOLD(i),
			xadc->threshold[i]);
		if (ret)
			return ret;
	}

	/* Go to non-buffered mode */
	xadc_postdisable(indio_dev);

	return devm_iio_device_register(dev, indio_dev);
}