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