/* * Lock to protect the state of the device from potential concurrent * write accesses from userspace. The write operation requires an * SPI write, then toggling of a GPIO, so the lock aims to protect * the sanity of the entire sequence of operation.
*/ struct mutex lock;
/* * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines.
*/
uint8_t data[2] __aligned(IIO_DMA_MINALIGN);
};
staticint dac7612_cmd_single(struct dac7612 *priv, int channel, u16 val)
{ int ret;
priv->data[0] = BIT(DAC7612_START) | (channel << DAC7612_ADDRESS);
priv->data[0] |= val >> 8;
priv->data[1] = val & 0xff;
priv->cache[channel] = val;
ret = spi_write(priv->spi, priv->data, sizeof(priv->data)); if (ret) return ret;
staticint dac7612_probe(struct spi_device *spi)
{ struct iio_dev *iio_dev; struct dac7612 *priv; int i; int ret;
iio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*priv)); if (!iio_dev) return -ENOMEM;
priv = iio_priv(iio_dev); /* * LOADDACS pin can be controlled by the driver or externally. * When controlled by the driver, the DAC value is updated after * every write. * When the driver does not control the PIN, the user or an external * event can change the value of all DACs by pulsing down the LOADDACs * pin.
*/
priv->loaddacs = devm_gpiod_get_optional(&spi->dev, "ti,loaddacs",
GPIOD_OUT_LOW); if (IS_ERR(priv->loaddacs)) return PTR_ERR(priv->loaddacs);
priv->spi = spi;
spi_set_drvdata(spi, iio_dev);
iio_dev->info = &dac7612_info;
iio_dev->modes = INDIO_DIRECT_MODE;
iio_dev->channels = dac7612_channels;
iio_dev->num_channels = ARRAY_SIZE(priv->cache);
iio_dev->name = spi_get_device_id(spi)->name;
mutex_init(&priv->lock);
for (i = 0; i < ARRAY_SIZE(priv->cache); i++) {
ret = dac7612_cmd_single(priv, i, 0); if (ret) return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.