0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/spi/spi.h>
0010 #include <linux/types.h>
0011 #include <linux/err.h>
0012
0013 #include <linux/iio/iio.h>
0014 #include "ad7606.h"
0015
0016 #define MAX_SPI_FREQ_HZ 23500000
0017
0018 #define AD7616_CONFIGURATION_REGISTER 0x02
0019 #define AD7616_OS_MASK GENMASK(4, 2)
0020 #define AD7616_BURST_MODE BIT(6)
0021 #define AD7616_SEQEN_MODE BIT(5)
0022 #define AD7616_RANGE_CH_A_ADDR_OFF 0x04
0023 #define AD7616_RANGE_CH_B_ADDR_OFF 0x06
0024
0025
0026
0027
0028
0029
0030 #define AD7616_RANGE_CH_ADDR(ch) ((ch) >> 2)
0031
0032 #define AD7616_RANGE_CH_MSK(ch) (0b11 << (((ch) & 0b11) * 2))
0033 #define AD7616_RANGE_CH_MODE(ch, mode) ((mode) << ((((ch) & 0b11)) * 2))
0034
0035 #define AD7606_CONFIGURATION_REGISTER 0x02
0036 #define AD7606_SINGLE_DOUT 0x00
0037
0038
0039
0040
0041
0042 #define AD7606_RANGE_CH_MSK(ch) (GENMASK(3, 0) << (4 * ((ch) & 0x1)))
0043 #define AD7606_RANGE_CH_MODE(ch, mode) \
0044 ((GENMASK(3, 0) & mode) << (4 * ((ch) & 0x1)))
0045 #define AD7606_RANGE_CH_ADDR(ch) (0x03 + ((ch) >> 1))
0046 #define AD7606_OS_MODE 0x08
0047
0048 static const struct iio_chan_spec ad7616_sw_channels[] = {
0049 IIO_CHAN_SOFT_TIMESTAMP(16),
0050 AD7616_CHANNEL(0),
0051 AD7616_CHANNEL(1),
0052 AD7616_CHANNEL(2),
0053 AD7616_CHANNEL(3),
0054 AD7616_CHANNEL(4),
0055 AD7616_CHANNEL(5),
0056 AD7616_CHANNEL(6),
0057 AD7616_CHANNEL(7),
0058 AD7616_CHANNEL(8),
0059 AD7616_CHANNEL(9),
0060 AD7616_CHANNEL(10),
0061 AD7616_CHANNEL(11),
0062 AD7616_CHANNEL(12),
0063 AD7616_CHANNEL(13),
0064 AD7616_CHANNEL(14),
0065 AD7616_CHANNEL(15),
0066 };
0067
0068 static const struct iio_chan_spec ad7606b_sw_channels[] = {
0069 IIO_CHAN_SOFT_TIMESTAMP(8),
0070 AD7616_CHANNEL(0),
0071 AD7616_CHANNEL(1),
0072 AD7616_CHANNEL(2),
0073 AD7616_CHANNEL(3),
0074 AD7616_CHANNEL(4),
0075 AD7616_CHANNEL(5),
0076 AD7616_CHANNEL(6),
0077 AD7616_CHANNEL(7),
0078 };
0079
0080 static const unsigned int ad7606B_oversampling_avail[9] = {
0081 1, 2, 4, 8, 16, 32, 64, 128, 256
0082 };
0083
0084 static u16 ad7616_spi_rd_wr_cmd(int addr, char isWriteOp)
0085 {
0086
0087
0088
0089
0090 return ((addr & 0x7F) << 1) | ((isWriteOp & 0x1) << 7);
0091 }
0092
0093 static u16 ad7606B_spi_rd_wr_cmd(int addr, char is_write_op)
0094 {
0095
0096
0097
0098
0099
0100 return (addr & 0x3F) | (((~is_write_op) & 0x1) << 6);
0101 }
0102
0103 static int ad7606_spi_read_block(struct device *dev,
0104 int count, void *buf)
0105 {
0106 struct spi_device *spi = to_spi_device(dev);
0107 int i, ret;
0108 unsigned short *data = buf;
0109 __be16 *bdata = buf;
0110
0111 ret = spi_read(spi, buf, count * 2);
0112 if (ret < 0) {
0113 dev_err(&spi->dev, "SPI read error\n");
0114 return ret;
0115 }
0116
0117 for (i = 0; i < count; i++)
0118 data[i] = be16_to_cpu(bdata[i]);
0119
0120 return 0;
0121 }
0122
0123 static int ad7606_spi_reg_read(struct ad7606_state *st, unsigned int addr)
0124 {
0125 struct spi_device *spi = to_spi_device(st->dev);
0126 struct spi_transfer t[] = {
0127 {
0128 .tx_buf = &st->d16[0],
0129 .len = 2,
0130 .cs_change = 0,
0131 }, {
0132 .rx_buf = &st->d16[1],
0133 .len = 2,
0134 },
0135 };
0136 int ret;
0137
0138 st->d16[0] = cpu_to_be16(st->bops->rd_wr_cmd(addr, 0) << 8);
0139
0140 ret = spi_sync_transfer(spi, t, ARRAY_SIZE(t));
0141 if (ret < 0)
0142 return ret;
0143
0144 return be16_to_cpu(st->d16[1]);
0145 }
0146
0147 static int ad7606_spi_reg_write(struct ad7606_state *st,
0148 unsigned int addr,
0149 unsigned int val)
0150 {
0151 struct spi_device *spi = to_spi_device(st->dev);
0152
0153 st->d16[0] = cpu_to_be16((st->bops->rd_wr_cmd(addr, 1) << 8) |
0154 (val & 0x1FF));
0155
0156 return spi_write(spi, &st->d16[0], sizeof(st->d16[0]));
0157 }
0158
0159 static int ad7606_spi_write_mask(struct ad7606_state *st,
0160 unsigned int addr,
0161 unsigned long mask,
0162 unsigned int val)
0163 {
0164 int readval;
0165
0166 readval = st->bops->reg_read(st, addr);
0167 if (readval < 0)
0168 return readval;
0169
0170 readval &= ~mask;
0171 readval |= val;
0172
0173 return st->bops->reg_write(st, addr, readval);
0174 }
0175
0176 static int ad7616_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
0177 {
0178 struct ad7606_state *st = iio_priv(indio_dev);
0179 unsigned int ch_addr, mode, ch_index;
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189 ch_index = ch >> 1;
0190
0191 ch_addr = AD7616_RANGE_CH_ADDR(ch_index);
0192
0193 if ((ch & 0x1) == 0)
0194 ch_addr += AD7616_RANGE_CH_A_ADDR_OFF;
0195 else
0196 ch_addr += AD7616_RANGE_CH_B_ADDR_OFF;
0197
0198
0199 mode = AD7616_RANGE_CH_MODE(ch_index, ((val + 1) & 0b11));
0200 return st->bops->write_mask(st, ch_addr, AD7616_RANGE_CH_MSK(ch_index),
0201 mode);
0202 }
0203
0204 static int ad7616_write_os_sw(struct iio_dev *indio_dev, int val)
0205 {
0206 struct ad7606_state *st = iio_priv(indio_dev);
0207
0208 return st->bops->write_mask(st, AD7616_CONFIGURATION_REGISTER,
0209 AD7616_OS_MASK, val << 2);
0210 }
0211
0212 static int ad7606_write_scale_sw(struct iio_dev *indio_dev, int ch, int val)
0213 {
0214 struct ad7606_state *st = iio_priv(indio_dev);
0215
0216 return ad7606_spi_write_mask(st,
0217 AD7606_RANGE_CH_ADDR(ch),
0218 AD7606_RANGE_CH_MSK(ch),
0219 AD7606_RANGE_CH_MODE(ch, val));
0220 }
0221
0222 static int ad7606_write_os_sw(struct iio_dev *indio_dev, int val)
0223 {
0224 struct ad7606_state *st = iio_priv(indio_dev);
0225
0226 return ad7606_spi_reg_write(st, AD7606_OS_MODE, val);
0227 }
0228
0229 static int ad7616_sw_mode_config(struct iio_dev *indio_dev)
0230 {
0231 struct ad7606_state *st = iio_priv(indio_dev);
0232
0233
0234
0235
0236
0237 indio_dev->channels = ad7616_sw_channels;
0238
0239 st->write_scale = ad7616_write_scale_sw;
0240 st->write_os = &ad7616_write_os_sw;
0241
0242
0243 return st->bops->write_mask(st,
0244 AD7616_CONFIGURATION_REGISTER,
0245 AD7616_BURST_MODE | AD7616_SEQEN_MODE,
0246 AD7616_BURST_MODE | AD7616_SEQEN_MODE);
0247 }
0248
0249 static int ad7606B_sw_mode_config(struct iio_dev *indio_dev)
0250 {
0251 struct ad7606_state *st = iio_priv(indio_dev);
0252 unsigned long os[3] = {1};
0253
0254
0255
0256
0257
0258
0259
0260 if (st->gpio_os) {
0261 gpiod_set_array_value(ARRAY_SIZE(os),
0262 st->gpio_os->desc, st->gpio_os->info, os);
0263 }
0264
0265 st->oversampling_avail = ad7606B_oversampling_avail;
0266 st->num_os_ratios = ARRAY_SIZE(ad7606B_oversampling_avail);
0267
0268 st->write_scale = ad7606_write_scale_sw;
0269 st->write_os = &ad7606_write_os_sw;
0270
0271
0272 st->bops->reg_write(st,
0273 AD7606_CONFIGURATION_REGISTER,
0274 AD7606_SINGLE_DOUT);
0275
0276
0277
0278
0279
0280 indio_dev->channels = ad7606b_sw_channels;
0281
0282 return 0;
0283 }
0284
0285 static const struct ad7606_bus_ops ad7606_spi_bops = {
0286 .read_block = ad7606_spi_read_block,
0287 };
0288
0289 static const struct ad7606_bus_ops ad7616_spi_bops = {
0290 .read_block = ad7606_spi_read_block,
0291 .reg_read = ad7606_spi_reg_read,
0292 .reg_write = ad7606_spi_reg_write,
0293 .write_mask = ad7606_spi_write_mask,
0294 .rd_wr_cmd = ad7616_spi_rd_wr_cmd,
0295 .sw_mode_config = ad7616_sw_mode_config,
0296 };
0297
0298 static const struct ad7606_bus_ops ad7606B_spi_bops = {
0299 .read_block = ad7606_spi_read_block,
0300 .reg_read = ad7606_spi_reg_read,
0301 .reg_write = ad7606_spi_reg_write,
0302 .write_mask = ad7606_spi_write_mask,
0303 .rd_wr_cmd = ad7606B_spi_rd_wr_cmd,
0304 .sw_mode_config = ad7606B_sw_mode_config,
0305 };
0306
0307 static int ad7606_spi_probe(struct spi_device *spi)
0308 {
0309 const struct spi_device_id *id = spi_get_device_id(spi);
0310 const struct ad7606_bus_ops *bops;
0311
0312 switch (id->driver_data) {
0313 case ID_AD7616:
0314 bops = &ad7616_spi_bops;
0315 break;
0316 case ID_AD7606B:
0317 bops = &ad7606B_spi_bops;
0318 break;
0319 default:
0320 bops = &ad7606_spi_bops;
0321 break;
0322 }
0323
0324 return ad7606_probe(&spi->dev, spi->irq, NULL,
0325 id->name, id->driver_data,
0326 bops);
0327 }
0328
0329 static const struct spi_device_id ad7606_id_table[] = {
0330 { "ad7605-4", ID_AD7605_4 },
0331 { "ad7606-4", ID_AD7606_4 },
0332 { "ad7606-6", ID_AD7606_6 },
0333 { "ad7606-8", ID_AD7606_8 },
0334 { "ad7606b", ID_AD7606B },
0335 { "ad7616", ID_AD7616 },
0336 {}
0337 };
0338 MODULE_DEVICE_TABLE(spi, ad7606_id_table);
0339
0340 static const struct of_device_id ad7606_of_match[] = {
0341 { .compatible = "adi,ad7605-4" },
0342 { .compatible = "adi,ad7606-4" },
0343 { .compatible = "adi,ad7606-6" },
0344 { .compatible = "adi,ad7606-8" },
0345 { .compatible = "adi,ad7606b" },
0346 { .compatible = "adi,ad7616" },
0347 { },
0348 };
0349 MODULE_DEVICE_TABLE(of, ad7606_of_match);
0350
0351 static struct spi_driver ad7606_driver = {
0352 .driver = {
0353 .name = "ad7606",
0354 .of_match_table = ad7606_of_match,
0355 .pm = AD7606_PM_OPS,
0356 },
0357 .probe = ad7606_spi_probe,
0358 .id_table = ad7606_id_table,
0359 };
0360 module_spi_driver(ad7606_driver);
0361
0362 MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
0363 MODULE_DESCRIPTION("Analog Devices AD7606 ADC");
0364 MODULE_LICENSE("GPL v2");
0365 MODULE_IMPORT_NS(IIO_AD7606);