10357e488SStefan Popa // SPDX-License-Identifier: GPL-2.0+ 20357e488SStefan Popa /* 31dbae4c6SStefan Popa * AD5672R, AD5676, AD5676R, AD5681R, AD5682R, AD5683, AD5683R, 41dbae4c6SStefan Popa * AD5684, AD5684R, AD5685R, AD5686, AD5686R 50357e488SStefan Popa * Digital to analog converters driver 60357e488SStefan Popa * 70357e488SStefan Popa * Copyright 2018 Analog Devices Inc. 80357e488SStefan Popa */ 90357e488SStefan Popa 100357e488SStefan Popa #include "ad5686.h" 110357e488SStefan Popa 120357e488SStefan Popa #include <linux/module.h> 130357e488SStefan Popa #include <linux/spi/spi.h> 140357e488SStefan Popa 150357e488SStefan Popa static int ad5686_spi_write(struct ad5686_state *st, 160357e488SStefan Popa u8 cmd, u8 addr, u16 val) 170357e488SStefan Popa { 180357e488SStefan Popa struct spi_device *spi = to_spi_device(st->dev); 191dbae4c6SStefan Popa u8 tx_len, *buf; 200357e488SStefan Popa 211dbae4c6SStefan Popa switch (st->chip_info->regmap_type) { 221dbae4c6SStefan Popa case AD5683_REGMAP: 231dbae4c6SStefan Popa st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | 241dbae4c6SStefan Popa AD5683_DATA(val)); 251dbae4c6SStefan Popa buf = &st->data[0].d8[1]; 261dbae4c6SStefan Popa tx_len = 3; 271dbae4c6SStefan Popa break; 281dbae4c6SStefan Popa case AD5686_REGMAP: 290357e488SStefan Popa st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | 300357e488SStefan Popa AD5686_ADDR(addr) | 310357e488SStefan Popa val); 321dbae4c6SStefan Popa buf = &st->data[0].d8[1]; 331dbae4c6SStefan Popa tx_len = 3; 341dbae4c6SStefan Popa break; 351dbae4c6SStefan Popa default: 361dbae4c6SStefan Popa return -EINVAL; 371dbae4c6SStefan Popa } 380357e488SStefan Popa 391dbae4c6SStefan Popa return spi_write(spi, buf, tx_len); 400357e488SStefan Popa } 410357e488SStefan Popa 420357e488SStefan Popa static int ad5686_spi_read(struct ad5686_state *st, u8 addr) 430357e488SStefan Popa { 440357e488SStefan Popa struct spi_transfer t[] = { 450357e488SStefan Popa { 460357e488SStefan Popa .tx_buf = &st->data[0].d8[1], 470357e488SStefan Popa .len = 3, 480357e488SStefan Popa .cs_change = 1, 490357e488SStefan Popa }, { 500357e488SStefan Popa .tx_buf = &st->data[1].d8[1], 510357e488SStefan Popa .rx_buf = &st->data[2].d8[1], 520357e488SStefan Popa .len = 3, 530357e488SStefan Popa }, 540357e488SStefan Popa }; 550357e488SStefan Popa struct spi_device *spi = to_spi_device(st->dev); 561dbae4c6SStefan Popa u8 cmd = 0; 570357e488SStefan Popa int ret; 580357e488SStefan Popa 591dbae4c6SStefan Popa if (st->chip_info->regmap_type == AD5686_REGMAP) 601dbae4c6SStefan Popa cmd = AD5686_CMD_READBACK_ENABLE; 611dbae4c6SStefan Popa else if (st->chip_info->regmap_type == AD5683_REGMAP) 621dbae4c6SStefan Popa cmd = AD5686_CMD_READBACK_ENABLE_V2; 631dbae4c6SStefan Popa 641dbae4c6SStefan Popa st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | 650357e488SStefan Popa AD5686_ADDR(addr)); 660357e488SStefan Popa st->data[1].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP)); 670357e488SStefan Popa 680357e488SStefan Popa ret = spi_sync_transfer(spi, t, ARRAY_SIZE(t)); 690357e488SStefan Popa if (ret < 0) 700357e488SStefan Popa return ret; 710357e488SStefan Popa 720357e488SStefan Popa return be32_to_cpu(st->data[2].d32); 730357e488SStefan Popa } 740357e488SStefan Popa 750357e488SStefan Popa static int ad5686_spi_probe(struct spi_device *spi) 760357e488SStefan Popa { 770357e488SStefan Popa const struct spi_device_id *id = spi_get_device_id(spi); 780357e488SStefan Popa 790357e488SStefan Popa return ad5686_probe(&spi->dev, id->driver_data, id->name, 800357e488SStefan Popa ad5686_spi_write, ad5686_spi_read); 810357e488SStefan Popa } 820357e488SStefan Popa 830357e488SStefan Popa static int ad5686_spi_remove(struct spi_device *spi) 840357e488SStefan Popa { 850357e488SStefan Popa return ad5686_remove(&spi->dev); 860357e488SStefan Popa } 870357e488SStefan Popa 880357e488SStefan Popa static const struct spi_device_id ad5686_spi_id[] = { 890357e488SStefan Popa {"ad5672r", ID_AD5672R}, 900357e488SStefan Popa {"ad5676", ID_AD5676}, 910357e488SStefan Popa {"ad5676r", ID_AD5676R}, 921dbae4c6SStefan Popa {"ad5681r", ID_AD5681R}, 931dbae4c6SStefan Popa {"ad5682r", ID_AD5682R}, 941dbae4c6SStefan Popa {"ad5683", ID_AD5683}, 951dbae4c6SStefan Popa {"ad5683r", ID_AD5683R}, 960357e488SStefan Popa {"ad5684", ID_AD5684}, 970357e488SStefan Popa {"ad5684r", ID_AD5684R}, 980357e488SStefan Popa {"ad5685", ID_AD5685R}, /* Does not exist */ 990357e488SStefan Popa {"ad5685r", ID_AD5685R}, 1000357e488SStefan Popa {"ad5686", ID_AD5686}, 1010357e488SStefan Popa {"ad5686r", ID_AD5686R}, 1020357e488SStefan Popa {} 1030357e488SStefan Popa }; 1040357e488SStefan Popa MODULE_DEVICE_TABLE(spi, ad5686_spi_id); 1050357e488SStefan Popa 1060357e488SStefan Popa static struct spi_driver ad5686_spi_driver = { 1070357e488SStefan Popa .driver = { 1080357e488SStefan Popa .name = "ad5686", 1090357e488SStefan Popa }, 1100357e488SStefan Popa .probe = ad5686_spi_probe, 1110357e488SStefan Popa .remove = ad5686_spi_remove, 1120357e488SStefan Popa .id_table = ad5686_spi_id, 1130357e488SStefan Popa }; 1140357e488SStefan Popa 1150357e488SStefan Popa module_spi_driver(ad5686_spi_driver); 1160357e488SStefan Popa 1170357e488SStefan Popa MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>"); 1180357e488SStefan Popa MODULE_DESCRIPTION("Analog Devices AD5686 and similar multi-channel DACs"); 1190357e488SStefan Popa MODULE_LICENSE("GPL v2"); 120