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) { 2212d323cfSStefan Popa case AD5310_REGMAP: 2312d323cfSStefan Popa st->data[0].d16 = cpu_to_be16(AD5310_CMD(cmd) | 2412d323cfSStefan Popa val); 2512d323cfSStefan Popa buf = &st->data[0].d8[0]; 2612d323cfSStefan Popa tx_len = 2; 2712d323cfSStefan Popa break; 281dbae4c6SStefan Popa case AD5683_REGMAP: 291dbae4c6SStefan Popa st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | 301dbae4c6SStefan Popa AD5683_DATA(val)); 311dbae4c6SStefan Popa buf = &st->data[0].d8[1]; 321dbae4c6SStefan Popa tx_len = 3; 331dbae4c6SStefan Popa break; 341dbae4c6SStefan Popa case AD5686_REGMAP: 350357e488SStefan Popa st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | 360357e488SStefan Popa AD5686_ADDR(addr) | 370357e488SStefan Popa val); 381dbae4c6SStefan Popa buf = &st->data[0].d8[1]; 391dbae4c6SStefan Popa tx_len = 3; 401dbae4c6SStefan Popa break; 411dbae4c6SStefan Popa default: 421dbae4c6SStefan Popa return -EINVAL; 431dbae4c6SStefan Popa } 440357e488SStefan Popa 451dbae4c6SStefan Popa return spi_write(spi, buf, tx_len); 460357e488SStefan Popa } 470357e488SStefan Popa 480357e488SStefan Popa static int ad5686_spi_read(struct ad5686_state *st, u8 addr) 490357e488SStefan Popa { 500357e488SStefan Popa struct spi_transfer t[] = { 510357e488SStefan Popa { 520357e488SStefan Popa .tx_buf = &st->data[0].d8[1], 530357e488SStefan Popa .len = 3, 540357e488SStefan Popa .cs_change = 1, 550357e488SStefan Popa }, { 560357e488SStefan Popa .tx_buf = &st->data[1].d8[1], 570357e488SStefan Popa .rx_buf = &st->data[2].d8[1], 580357e488SStefan Popa .len = 3, 590357e488SStefan Popa }, 600357e488SStefan Popa }; 610357e488SStefan Popa struct spi_device *spi = to_spi_device(st->dev); 621dbae4c6SStefan Popa u8 cmd = 0; 630357e488SStefan Popa int ret; 640357e488SStefan Popa 6512d323cfSStefan Popa switch (st->chip_info->regmap_type) { 6612d323cfSStefan Popa case AD5310_REGMAP: 6712d323cfSStefan Popa return -ENOTSUPP; 6812d323cfSStefan Popa case AD5683_REGMAP: 691dbae4c6SStefan Popa cmd = AD5686_CMD_READBACK_ENABLE_V2; 7012d323cfSStefan Popa break; 7112d323cfSStefan Popa case AD5686_REGMAP: 7212d323cfSStefan Popa cmd = AD5686_CMD_READBACK_ENABLE; 7312d323cfSStefan Popa break; 7412d323cfSStefan Popa default: 7512d323cfSStefan Popa return -EINVAL; 7612d323cfSStefan Popa } 771dbae4c6SStefan Popa 781dbae4c6SStefan Popa st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | 790357e488SStefan Popa AD5686_ADDR(addr)); 800357e488SStefan Popa st->data[1].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP)); 810357e488SStefan Popa 820357e488SStefan Popa ret = spi_sync_transfer(spi, t, ARRAY_SIZE(t)); 830357e488SStefan Popa if (ret < 0) 840357e488SStefan Popa return ret; 850357e488SStefan Popa 860357e488SStefan Popa return be32_to_cpu(st->data[2].d32); 870357e488SStefan Popa } 880357e488SStefan Popa 890357e488SStefan Popa static int ad5686_spi_probe(struct spi_device *spi) 900357e488SStefan Popa { 910357e488SStefan Popa const struct spi_device_id *id = spi_get_device_id(spi); 920357e488SStefan Popa 930357e488SStefan Popa return ad5686_probe(&spi->dev, id->driver_data, id->name, 940357e488SStefan Popa ad5686_spi_write, ad5686_spi_read); 950357e488SStefan Popa } 960357e488SStefan Popa 970357e488SStefan Popa static int ad5686_spi_remove(struct spi_device *spi) 980357e488SStefan Popa { 990357e488SStefan Popa return ad5686_remove(&spi->dev); 1000357e488SStefan Popa } 1010357e488SStefan Popa 1020357e488SStefan Popa static const struct spi_device_id ad5686_spi_id[] = { 10312d323cfSStefan Popa {"ad5310r", ID_AD5310R}, 1040357e488SStefan Popa {"ad5672r", ID_AD5672R}, 1050357e488SStefan Popa {"ad5676", ID_AD5676}, 1060357e488SStefan Popa {"ad5676r", ID_AD5676R}, 1071dbae4c6SStefan Popa {"ad5681r", ID_AD5681R}, 1081dbae4c6SStefan Popa {"ad5682r", ID_AD5682R}, 1091dbae4c6SStefan Popa {"ad5683", ID_AD5683}, 1101dbae4c6SStefan Popa {"ad5683r", ID_AD5683R}, 1110357e488SStefan Popa {"ad5684", ID_AD5684}, 1120357e488SStefan Popa {"ad5684r", ID_AD5684R}, 1130357e488SStefan Popa {"ad5685", ID_AD5685R}, /* Does not exist */ 1140357e488SStefan Popa {"ad5685r", ID_AD5685R}, 1150357e488SStefan Popa {"ad5686", ID_AD5686}, 1160357e488SStefan Popa {"ad5686r", ID_AD5686R}, 1170357e488SStefan Popa {} 1180357e488SStefan Popa }; 1190357e488SStefan Popa MODULE_DEVICE_TABLE(spi, ad5686_spi_id); 1200357e488SStefan Popa 1210357e488SStefan Popa static struct spi_driver ad5686_spi_driver = { 1220357e488SStefan Popa .driver = { 1230357e488SStefan Popa .name = "ad5686", 1240357e488SStefan Popa }, 1250357e488SStefan Popa .probe = ad5686_spi_probe, 1260357e488SStefan Popa .remove = ad5686_spi_remove, 1270357e488SStefan Popa .id_table = ad5686_spi_id, 1280357e488SStefan Popa }; 1290357e488SStefan Popa 1300357e488SStefan Popa module_spi_driver(ad5686_spi_driver); 1310357e488SStefan Popa 1320357e488SStefan Popa MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>"); 1330357e488SStefan Popa MODULE_DESCRIPTION("Analog Devices AD5686 and similar multi-channel DACs"); 1340357e488SStefan Popa MODULE_LICENSE("GPL v2"); 135