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);
}