Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * AD5672R, AD5674R, AD5676, AD5676R, AD5679R,
0004  * AD5681R, AD5682R, AD5683, AD5683R, AD5684,
0005  * AD5684R, AD5685R, AD5686, AD5686R
0006  * Digital to analog converters driver
0007  *
0008  * Copyright 2018 Analog Devices Inc.
0009  */
0010 
0011 #include "ad5686.h"
0012 
0013 #include <linux/module.h>
0014 #include <linux/spi/spi.h>
0015 
0016 static int ad5686_spi_write(struct ad5686_state *st,
0017                 u8 cmd, u8 addr, u16 val)
0018 {
0019     struct spi_device *spi = to_spi_device(st->dev);
0020     u8 tx_len, *buf;
0021 
0022     switch (st->chip_info->regmap_type) {
0023     case AD5310_REGMAP:
0024         st->data[0].d16 = cpu_to_be16(AD5310_CMD(cmd) |
0025                           val);
0026         buf = &st->data[0].d8[0];
0027         tx_len = 2;
0028         break;
0029     case AD5683_REGMAP:
0030         st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
0031                           AD5683_DATA(val));
0032         buf = &st->data[0].d8[1];
0033         tx_len = 3;
0034         break;
0035     case AD5686_REGMAP:
0036         st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
0037                           AD5686_ADDR(addr) |
0038                           val);
0039         buf = &st->data[0].d8[1];
0040         tx_len = 3;
0041         break;
0042     default:
0043         return -EINVAL;
0044     }
0045 
0046     return spi_write(spi, buf, tx_len);
0047 }
0048 
0049 static int ad5686_spi_read(struct ad5686_state *st, u8 addr)
0050 {
0051     struct spi_transfer t[] = {
0052         {
0053             .tx_buf = &st->data[0].d8[1],
0054             .len = 3,
0055             .cs_change = 1,
0056         }, {
0057             .tx_buf = &st->data[1].d8[1],
0058             .rx_buf = &st->data[2].d8[1],
0059             .len = 3,
0060         },
0061     };
0062     struct spi_device *spi = to_spi_device(st->dev);
0063     u8 cmd = 0;
0064     int ret;
0065 
0066     switch (st->chip_info->regmap_type) {
0067     case AD5310_REGMAP:
0068         return -ENOTSUPP;
0069     case AD5683_REGMAP:
0070         cmd = AD5686_CMD_READBACK_ENABLE_V2;
0071         break;
0072     case AD5686_REGMAP:
0073         cmd = AD5686_CMD_READBACK_ENABLE;
0074         break;
0075     default:
0076         return -EINVAL;
0077     }
0078 
0079     st->data[0].d32 = cpu_to_be32(AD5686_CMD(cmd) |
0080                       AD5686_ADDR(addr));
0081     st->data[1].d32 = cpu_to_be32(AD5686_CMD(AD5686_CMD_NOOP));
0082 
0083     ret = spi_sync_transfer(spi, t, ARRAY_SIZE(t));
0084     if (ret < 0)
0085         return ret;
0086 
0087     return be32_to_cpu(st->data[2].d32);
0088 }
0089 
0090 static int ad5686_spi_probe(struct spi_device *spi)
0091 {
0092     const struct spi_device_id *id = spi_get_device_id(spi);
0093 
0094     return ad5686_probe(&spi->dev, id->driver_data, id->name,
0095                 ad5686_spi_write, ad5686_spi_read);
0096 }
0097 
0098 static void ad5686_spi_remove(struct spi_device *spi)
0099 {
0100     ad5686_remove(&spi->dev);
0101 }
0102 
0103 static const struct spi_device_id ad5686_spi_id[] = {
0104     {"ad5310r", ID_AD5310R},
0105     {"ad5672r", ID_AD5672R},
0106     {"ad5674r", ID_AD5674R},
0107     {"ad5676", ID_AD5676},
0108     {"ad5676r", ID_AD5676R},
0109     {"ad5679r", ID_AD5679R},
0110     {"ad5681r", ID_AD5681R},
0111     {"ad5682r", ID_AD5682R},
0112     {"ad5683", ID_AD5683},
0113     {"ad5683r", ID_AD5683R},
0114     {"ad5684", ID_AD5684},
0115     {"ad5684r", ID_AD5684R},
0116     {"ad5685", ID_AD5685R}, /* Does not exist */
0117     {"ad5685r", ID_AD5685R},
0118     {"ad5686", ID_AD5686},
0119     {"ad5686r", ID_AD5686R},
0120     {}
0121 };
0122 MODULE_DEVICE_TABLE(spi, ad5686_spi_id);
0123 
0124 static struct spi_driver ad5686_spi_driver = {
0125     .driver = {
0126         .name = "ad5686",
0127     },
0128     .probe = ad5686_spi_probe,
0129     .remove = ad5686_spi_remove,
0130     .id_table = ad5686_spi_id,
0131 };
0132 
0133 module_spi_driver(ad5686_spi_driver);
0134 
0135 MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
0136 MODULE_DESCRIPTION("Analog Devices AD5686 and similar multi-channel DACs");
0137 MODULE_LICENSE("GPL v2");
0138 MODULE_IMPORT_NS(IIO_AD5686);