1cbd5dd38SStefan Popa // SPDX-License-Identifier: GPL-2.0 20357e488SStefan Popa /* 3192778fbSMircea Caprioru * AD5672R, AD5674R, AD5676, AD5676R, AD5679R, 4192778fbSMircea Caprioru * AD5681R, AD5682R, AD5683, AD5683R, AD5684, 5192778fbSMircea Caprioru * AD5684R, AD5685R, AD5686, AD5686R 60357e488SStefan Popa * Digital to analog converters driver 70357e488SStefan Popa * 80357e488SStefan Popa * Copyright 2018 Analog Devices Inc. 90357e488SStefan Popa */ 100357e488SStefan Popa 110357e488SStefan Popa #include "ad5686.h" 120357e488SStefan Popa 130357e488SStefan Popa #include <linux/module.h> 140357e488SStefan Popa #include <linux/spi/spi.h> 150357e488SStefan Popa 160357e488SStefan Popa static int ad5686_spi_write(struct ad5686_state *st, 170357e488SStefan Popa u8 cmd, u8 addr, u16 val) 180357e488SStefan Popa { 190357e488SStefan Popa struct spi_device *spi = to_spi_device(st->dev); 201dbae4c6SStefan Popa u8 tx_len, *buf; 210357e488SStefan Popa 221dbae4c6SStefan Popa switch (st->chip_info->regmap_type) { 2312d323cfSStefan Popa case AD5310_REGMAP: 2412d323cfSStefan Popa st->data[0].d16 = cpu_to_be16(AD5310_CMD(cmd) | 2512d323cfSStefan Popa val); 2612d323cfSStefan Popa buf = &st->data[0].d8[0]; 2712d323cfSStefan Popa tx_len = 2; 2812d323cfSStefan Popa break; 291dbae4c6SStefan Popa case AD5683_REGMAP: 301dbae4c6SStefan Popa st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | 311dbae4c6SStefan Popa AD5683_DATA(val)); 321dbae4c6SStefan Popa buf = &st->data[0].d8[1]; 331dbae4c6SStefan Popa tx_len = 3; 341dbae4c6SStefan Popa break; 351dbae4c6SStefan Popa case AD5686_REGMAP: 360357e488SStefan Popa st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | 370357e488SStefan Popa AD5686_ADDR(addr) | 380357e488SStefan Popa val); 391dbae4c6SStefan Popa buf = &st->data[0].d8[1]; 401dbae4c6SStefan Popa tx_len = 3; 411dbae4c6SStefan Popa break; 421dbae4c6SStefan Popa default: 431dbae4c6SStefan Popa return -EINVAL; 441dbae4c6SStefan Popa } 450357e488SStefan Popa 461dbae4c6SStefan Popa return spi_write(spi, buf, tx_len); 470357e488SStefan Popa } 480357e488SStefan Popa 490357e488SStefan Popa static int ad5686_spi_read(struct ad5686_state *st, u8 addr) 500357e488SStefan Popa { 510357e488SStefan Popa struct spi_transfer t[] = { 520357e488SStefan Popa { 530357e488SStefan Popa .tx_buf = &st->data[0].d8[1], 540357e488SStefan Popa .len = 3, 550357e488SStefan Popa .cs_change = 1, 560357e488SStefan Popa }, { 570357e488SStefan Popa .tx_buf = &st->data[1].d8[1], 580357e488SStefan Popa .rx_buf = &st->data[2].d8[1], 590357e488SStefan Popa .len = 3, 600357e488SStefan Popa }, 610357e488SStefan Popa }; 620357e488SStefan Popa struct spi_device *spi = to_spi_device(st->dev); 631dbae4c6SStefan Popa u8 cmd = 0; 640357e488SStefan Popa int ret; 650357e488SStefan Popa 6612d323cfSStefan Popa switch (st->chip_info->regmap_type) { 6712d323cfSStefan Popa case AD5310_REGMAP: 6812d323cfSStefan Popa return -ENOTSUPP; 6912d323cfSStefan Popa case AD5683_REGMAP: 701dbae4c6SStefan Popa cmd = AD5686_CMD_READBACK_ENABLE_V2; 7112d323cfSStefan Popa break; 7212d323cfSStefan Popa case AD5686_REGMAP: 7312d323cfSStefan Popa cmd = AD5686_CMD_READBACK_ENABLE; 7412d323cfSStefan Popa break; 7512d323cfSStefan Popa default: 7612d323cfSStefan Popa return -EINVAL; 7712d323cfSStefan Popa } 781dbae4c6SStefan Popa 791dbae4c6SStefan Popa st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) | 800357e488SStefan Popa AD5686_ADDR(addr)); 810357e488SStefan Popa st->data[1].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP)); 820357e488SStefan Popa 830357e488SStefan Popa ret = spi_sync_transfer(spi, t, ARRAY_SIZE(t)); 840357e488SStefan Popa if (ret < 0) 850357e488SStefan Popa return ret; 860357e488SStefan Popa 870357e488SStefan Popa return be32_to_cpu(st->data[2].d32); 880357e488SStefan Popa } 890357e488SStefan Popa 900357e488SStefan Popa static int ad5686_spi_probe(struct spi_device *spi) 910357e488SStefan Popa { 920357e488SStefan Popa const struct spi_device_id *id = spi_get_device_id(spi); 930357e488SStefan Popa 940357e488SStefan Popa return ad5686_probe(&spi->dev, id->driver_data, id->name, 950357e488SStefan Popa ad5686_spi_write, ad5686_spi_read); 960357e488SStefan Popa } 970357e488SStefan Popa 980357e488SStefan Popa static int ad5686_spi_remove(struct spi_device *spi) 990357e488SStefan Popa { 1000357e488SStefan Popa return ad5686_remove(&spi->dev); 1010357e488SStefan Popa } 1020357e488SStefan Popa 1030357e488SStefan Popa static const struct spi_device_id ad5686_spi_id[] = { 10412d323cfSStefan Popa {"ad5310r", ID_AD5310R}, 1050357e488SStefan Popa {"ad5672r", ID_AD5672R}, 106192778fbSMircea Caprioru {"ad5674r", ID_AD5674R}, 1070357e488SStefan Popa {"ad5676", ID_AD5676}, 1080357e488SStefan Popa {"ad5676r", ID_AD5676R}, 109192778fbSMircea Caprioru {"ad5679r", ID_AD5679R}, 1101dbae4c6SStefan Popa {"ad5681r", ID_AD5681R}, 1111dbae4c6SStefan Popa {"ad5682r", ID_AD5682R}, 1121dbae4c6SStefan Popa {"ad5683", ID_AD5683}, 1131dbae4c6SStefan Popa {"ad5683r", ID_AD5683R}, 1140357e488SStefan Popa {"ad5684", ID_AD5684}, 1150357e488SStefan Popa {"ad5684r", ID_AD5684R}, 1160357e488SStefan Popa {"ad5685", ID_AD5685R}, /* Does not exist */ 1170357e488SStefan Popa {"ad5685r", ID_AD5685R}, 1180357e488SStefan Popa {"ad5686", ID_AD5686}, 1190357e488SStefan Popa {"ad5686r", ID_AD5686R}, 1200357e488SStefan Popa {} 1210357e488SStefan Popa }; 1220357e488SStefan Popa MODULE_DEVICE_TABLE(spi, ad5686_spi_id); 1230357e488SStefan Popa 1240357e488SStefan Popa static struct spi_driver ad5686_spi_driver = { 1250357e488SStefan Popa .driver = { 1260357e488SStefan Popa .name = "ad5686", 1270357e488SStefan Popa }, 1280357e488SStefan Popa .probe = ad5686_spi_probe, 1290357e488SStefan Popa .remove = ad5686_spi_remove, 1300357e488SStefan Popa .id_table = ad5686_spi_id, 1310357e488SStefan Popa }; 1320357e488SStefan Popa 1330357e488SStefan Popa module_spi_driver(ad5686_spi_driver); 1340357e488SStefan Popa 1350357e488SStefan Popa MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>"); 1360357e488SStefan Popa MODULE_DESCRIPTION("Analog Devices AD5686 and similar multi-channel DACs"); 1370357e488SStefan Popa MODULE_LICENSE("GPL v2"); 138