0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/spi/spi.h>
0013 #include <linux/gpio/consumer.h>
0014 #include <linux/iio/iio.h>
0015
0016 #define DAC7612_RESOLUTION 12
0017 #define DAC7612_ADDRESS 4
0018 #define DAC7612_START 5
0019
0020 struct dac7612 {
0021 struct spi_device *spi;
0022 struct gpio_desc *loaddacs;
0023 uint16_t cache[2];
0024
0025
0026
0027
0028
0029
0030
0031 struct mutex lock;
0032
0033
0034
0035
0036
0037 uint8_t data[2] __aligned(IIO_DMA_MINALIGN);
0038 };
0039
0040 static int dac7612_cmd_single(struct dac7612 *priv, int channel, u16 val)
0041 {
0042 int ret;
0043
0044 priv->data[0] = BIT(DAC7612_START) | (channel << DAC7612_ADDRESS);
0045 priv->data[0] |= val >> 8;
0046 priv->data[1] = val & 0xff;
0047
0048 priv->cache[channel] = val;
0049
0050 ret = spi_write(priv->spi, priv->data, sizeof(priv->data));
0051 if (ret)
0052 return ret;
0053
0054 gpiod_set_value(priv->loaddacs, 1);
0055 gpiod_set_value(priv->loaddacs, 0);
0056
0057 return 0;
0058 }
0059
0060 #define dac7612_CHANNEL(chan, name) { \
0061 .type = IIO_VOLTAGE, \
0062 .channel = (chan), \
0063 .indexed = 1, \
0064 .output = 1, \
0065 .datasheet_name = name, \
0066 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
0067 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
0068 }
0069
0070 static const struct iio_chan_spec dac7612_channels[] = {
0071 dac7612_CHANNEL(0, "OUTA"),
0072 dac7612_CHANNEL(1, "OUTB"),
0073 };
0074
0075 static int dac7612_read_raw(struct iio_dev *iio_dev,
0076 const struct iio_chan_spec *chan,
0077 int *val, int *val2, long mask)
0078 {
0079 struct dac7612 *priv;
0080
0081 switch (mask) {
0082 case IIO_CHAN_INFO_RAW:
0083 priv = iio_priv(iio_dev);
0084 *val = priv->cache[chan->channel];
0085 return IIO_VAL_INT;
0086
0087 case IIO_CHAN_INFO_SCALE:
0088 *val = 1;
0089 return IIO_VAL_INT;
0090
0091 default:
0092 return -EINVAL;
0093 }
0094 }
0095
0096 static int dac7612_write_raw(struct iio_dev *iio_dev,
0097 const struct iio_chan_spec *chan,
0098 int val, int val2, long mask)
0099 {
0100 struct dac7612 *priv = iio_priv(iio_dev);
0101 int ret;
0102
0103 if (mask != IIO_CHAN_INFO_RAW)
0104 return -EINVAL;
0105
0106 if ((val >= BIT(DAC7612_RESOLUTION)) || val < 0 || val2)
0107 return -EINVAL;
0108
0109 if (val == priv->cache[chan->channel])
0110 return 0;
0111
0112 mutex_lock(&priv->lock);
0113 ret = dac7612_cmd_single(priv, chan->channel, val);
0114 mutex_unlock(&priv->lock);
0115
0116 return ret;
0117 }
0118
0119 static const struct iio_info dac7612_info = {
0120 .read_raw = dac7612_read_raw,
0121 .write_raw = dac7612_write_raw,
0122 };
0123
0124 static int dac7612_probe(struct spi_device *spi)
0125 {
0126 struct iio_dev *iio_dev;
0127 struct dac7612 *priv;
0128 int i;
0129 int ret;
0130
0131 iio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*priv));
0132 if (!iio_dev)
0133 return -ENOMEM;
0134
0135 priv = iio_priv(iio_dev);
0136
0137
0138
0139
0140
0141
0142
0143
0144 priv->loaddacs = devm_gpiod_get_optional(&spi->dev, "ti,loaddacs",
0145 GPIOD_OUT_LOW);
0146 if (IS_ERR(priv->loaddacs))
0147 return PTR_ERR(priv->loaddacs);
0148 priv->spi = spi;
0149 spi_set_drvdata(spi, iio_dev);
0150 iio_dev->info = &dac7612_info;
0151 iio_dev->modes = INDIO_DIRECT_MODE;
0152 iio_dev->channels = dac7612_channels;
0153 iio_dev->num_channels = ARRAY_SIZE(priv->cache);
0154 iio_dev->name = spi_get_device_id(spi)->name;
0155
0156 mutex_init(&priv->lock);
0157
0158 for (i = 0; i < ARRAY_SIZE(priv->cache); i++) {
0159 ret = dac7612_cmd_single(priv, i, 0);
0160 if (ret)
0161 return ret;
0162 }
0163
0164 return devm_iio_device_register(&spi->dev, iio_dev);
0165 }
0166
0167 static const struct spi_device_id dac7612_id[] = {
0168 {"ti-dac7612"},
0169 {}
0170 };
0171 MODULE_DEVICE_TABLE(spi, dac7612_id);
0172
0173 static const struct of_device_id dac7612_of_match[] = {
0174 { .compatible = "ti,dac7612" },
0175 { .compatible = "ti,dac7612u" },
0176 { .compatible = "ti,dac7612ub" },
0177 { },
0178 };
0179 MODULE_DEVICE_TABLE(of, dac7612_of_match);
0180
0181 static struct spi_driver dac7612_driver = {
0182 .driver = {
0183 .name = "ti-dac7612",
0184 .of_match_table = dac7612_of_match,
0185 },
0186 .probe = dac7612_probe,
0187 .id_table = dac7612_id,
0188 };
0189 module_spi_driver(dac7612_driver);
0190
0191 MODULE_AUTHOR("Ricardo Ribalda <ribalda@kernel.org>");
0192 MODULE_DESCRIPTION("Texas Instruments DAC7612 DAC driver");
0193 MODULE_LICENSE("GPL v2");