xref: /openbmc/linux/drivers/iio/dac/ad5686-spi.c (revision 0357e488)
10357e488SStefan Popa // SPDX-License-Identifier: GPL-2.0+
20357e488SStefan Popa /*
30357e488SStefan Popa  * AD5672R, AD5676, AD5676R, AD5684, AD5684R, AD5684R, AD5685R, AD5686, AD5686R
40357e488SStefan Popa  * Digital to analog converters driver
50357e488SStefan Popa  *
60357e488SStefan Popa  * Copyright 2018 Analog Devices Inc.
70357e488SStefan Popa  */
80357e488SStefan Popa 
90357e488SStefan Popa #include "ad5686.h"
100357e488SStefan Popa 
110357e488SStefan Popa #include <linux/module.h>
120357e488SStefan Popa #include <linux/spi/spi.h>
130357e488SStefan Popa 
140357e488SStefan Popa static int ad5686_spi_write(struct ad5686_state *st,
150357e488SStefan Popa 			    u8 cmd, u8 addr, u16 val)
160357e488SStefan Popa {
170357e488SStefan Popa 	struct spi_device *spi = to_spi_device(st->dev);
180357e488SStefan Popa 
190357e488SStefan Popa 	st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
200357e488SStefan Popa 				      AD5686_ADDR(addr) |
210357e488SStefan Popa 				      val);
220357e488SStefan Popa 
230357e488SStefan Popa 	return spi_write(spi, &st->data[0].d8[1], 3);
240357e488SStefan Popa }
250357e488SStefan Popa 
260357e488SStefan Popa static int ad5686_spi_read(struct ad5686_state *st, u8 addr)
270357e488SStefan Popa {
280357e488SStefan Popa 	struct spi_transfer t[] = {
290357e488SStefan Popa 		{
300357e488SStefan Popa 			.tx_buf = &st->data[0].d8[1],
310357e488SStefan Popa 			.len = 3,
320357e488SStefan Popa 			.cs_change = 1,
330357e488SStefan Popa 		}, {
340357e488SStefan Popa 			.tx_buf = &st->data[1].d8[1],
350357e488SStefan Popa 			.rx_buf = &st->data[2].d8[1],
360357e488SStefan Popa 			.len = 3,
370357e488SStefan Popa 		},
380357e488SStefan Popa 	};
390357e488SStefan Popa 	struct spi_device *spi = to_spi_device(st->dev);
400357e488SStefan Popa 	int ret;
410357e488SStefan Popa 
420357e488SStefan Popa 	st->data[0].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_READBACK_ENABLE) |
430357e488SStefan Popa 				      AD5686_ADDR(addr));
440357e488SStefan Popa 	st->data[1].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP));
450357e488SStefan Popa 
460357e488SStefan Popa 	ret = spi_sync_transfer(spi, t, ARRAY_SIZE(t));
470357e488SStefan Popa 	if (ret < 0)
480357e488SStefan Popa 		return ret;
490357e488SStefan Popa 
500357e488SStefan Popa 	return be32_to_cpu(st->data[2].d32);
510357e488SStefan Popa }
520357e488SStefan Popa 
530357e488SStefan Popa static int ad5686_spi_probe(struct spi_device *spi)
540357e488SStefan Popa {
550357e488SStefan Popa 	const struct spi_device_id *id = spi_get_device_id(spi);
560357e488SStefan Popa 
570357e488SStefan Popa 	return ad5686_probe(&spi->dev, id->driver_data, id->name,
580357e488SStefan Popa 			    ad5686_spi_write, ad5686_spi_read);
590357e488SStefan Popa }
600357e488SStefan Popa 
610357e488SStefan Popa static int ad5686_spi_remove(struct spi_device *spi)
620357e488SStefan Popa {
630357e488SStefan Popa 	return ad5686_remove(&spi->dev);
640357e488SStefan Popa }
650357e488SStefan Popa 
660357e488SStefan Popa static const struct spi_device_id ad5686_spi_id[] = {
670357e488SStefan Popa 	{"ad5672r", ID_AD5672R},
680357e488SStefan Popa 	{"ad5676", ID_AD5676},
690357e488SStefan Popa 	{"ad5676r", ID_AD5676R},
700357e488SStefan Popa 	{"ad5684", ID_AD5684},
710357e488SStefan Popa 	{"ad5684r", ID_AD5684R},
720357e488SStefan Popa 	{"ad5685", ID_AD5685R}, /* Does not exist */
730357e488SStefan Popa 	{"ad5685r", ID_AD5685R},
740357e488SStefan Popa 	{"ad5686", ID_AD5686},
750357e488SStefan Popa 	{"ad5686r", ID_AD5686R},
760357e488SStefan Popa 	{}
770357e488SStefan Popa };
780357e488SStefan Popa MODULE_DEVICE_TABLE(spi, ad5686_spi_id);
790357e488SStefan Popa 
800357e488SStefan Popa static struct spi_driver ad5686_spi_driver = {
810357e488SStefan Popa 	.driver = {
820357e488SStefan Popa 		.name = "ad5686",
830357e488SStefan Popa 	},
840357e488SStefan Popa 	.probe = ad5686_spi_probe,
850357e488SStefan Popa 	.remove = ad5686_spi_remove,
860357e488SStefan Popa 	.id_table = ad5686_spi_id,
870357e488SStefan Popa };
880357e488SStefan Popa 
890357e488SStefan Popa module_spi_driver(ad5686_spi_driver);
900357e488SStefan Popa 
910357e488SStefan Popa MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
920357e488SStefan Popa MODULE_DESCRIPTION("Analog Devices AD5686 and similar multi-channel DACs");
930357e488SStefan Popa MODULE_LICENSE("GPL v2");
94