1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * DAC7612 Dual, 12-Bit Serial input Digital-to-Analog Converter 4 * 5 * Copyright 2019 Qtechnology A/S 6 * 2019 Ricardo Ribalda <ribalda@kernel.org> 7 * 8 * Licensed under the GPL-2. 9 */ 10 #include <linux/kernel.h> 11 #include <linux/module.h> 12 #include <linux/spi/spi.h> 13 #include <linux/gpio/consumer.h> 14 #include <linux/iio/iio.h> 15 16 #define DAC7612_RESOLUTION 12 17 #define DAC7612_ADDRESS 4 18 #define DAC7612_START 5 19 20 struct dac7612 { 21 struct spi_device *spi; 22 struct gpio_desc *loaddacs; 23 uint16_t cache[2]; 24 25 /* 26 * DMA (thus cache coherency maintenance) requires the 27 * transfer buffers to live in their own cache lines. 28 */ 29 uint8_t data[2] ____cacheline_aligned; 30 }; 31 32 static int dac7612_cmd_single(struct dac7612 *priv, int channel, u16 val) 33 { 34 int ret; 35 36 priv->data[0] = BIT(DAC7612_START) | (channel << DAC7612_ADDRESS); 37 priv->data[0] |= val >> 8; 38 priv->data[1] = val & 0xff; 39 40 priv->cache[channel] = val; 41 42 ret = spi_write(priv->spi, priv->data, sizeof(priv->data)); 43 if (ret) 44 return ret; 45 46 gpiod_set_value(priv->loaddacs, 1); 47 gpiod_set_value(priv->loaddacs, 0); 48 49 return 0; 50 } 51 52 #define dac7612_CHANNEL(chan, name) { \ 53 .type = IIO_VOLTAGE, \ 54 .channel = (chan), \ 55 .indexed = 1, \ 56 .output = 1, \ 57 .datasheet_name = name, \ 58 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 59 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 60 } 61 62 static const struct iio_chan_spec dac7612_channels[] = { 63 dac7612_CHANNEL(0, "OUTA"), 64 dac7612_CHANNEL(1, "OUTB"), 65 }; 66 67 static int dac7612_read_raw(struct iio_dev *iio_dev, 68 const struct iio_chan_spec *chan, 69 int *val, int *val2, long mask) 70 { 71 struct dac7612 *priv; 72 73 switch (mask) { 74 case IIO_CHAN_INFO_RAW: 75 priv = iio_priv(iio_dev); 76 *val = priv->cache[chan->channel]; 77 return IIO_VAL_INT; 78 79 case IIO_CHAN_INFO_SCALE: 80 *val = 1; 81 return IIO_VAL_INT; 82 83 default: 84 return -EINVAL; 85 } 86 } 87 88 static int dac7612_write_raw(struct iio_dev *iio_dev, 89 const struct iio_chan_spec *chan, 90 int val, int val2, long mask) 91 { 92 struct dac7612 *priv = iio_priv(iio_dev); 93 int ret; 94 95 if (mask != IIO_CHAN_INFO_RAW) 96 return -EINVAL; 97 98 if ((val >= BIT(DAC7612_RESOLUTION)) || val < 0 || val2) 99 return -EINVAL; 100 101 if (val == priv->cache[chan->channel]) 102 return 0; 103 104 mutex_lock(&iio_dev->mlock); 105 ret = dac7612_cmd_single(priv, chan->channel, val); 106 mutex_unlock(&iio_dev->mlock); 107 108 return ret; 109 } 110 111 static const struct iio_info dac7612_info = { 112 .read_raw = dac7612_read_raw, 113 .write_raw = dac7612_write_raw, 114 }; 115 116 static int dac7612_probe(struct spi_device *spi) 117 { 118 struct iio_dev *iio_dev; 119 struct dac7612 *priv; 120 int i; 121 int ret; 122 123 iio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*priv)); 124 if (!iio_dev) 125 return -ENOMEM; 126 127 priv = iio_priv(iio_dev); 128 /* 129 * LOADDACS pin can be controlled by the driver or externally. 130 * When controlled by the driver, the DAC value is updated after 131 * every write. 132 * When the driver does not control the PIN, the user or an external 133 * event can change the value of all DACs by pulsing down the LOADDACs 134 * pin. 135 */ 136 priv->loaddacs = devm_gpiod_get_optional(&spi->dev, "ti,loaddacs", 137 GPIOD_OUT_LOW); 138 if (IS_ERR(priv->loaddacs)) 139 return PTR_ERR(priv->loaddacs); 140 priv->spi = spi; 141 spi_set_drvdata(spi, iio_dev); 142 iio_dev->info = &dac7612_info; 143 iio_dev->modes = INDIO_DIRECT_MODE; 144 iio_dev->channels = dac7612_channels; 145 iio_dev->num_channels = ARRAY_SIZE(priv->cache); 146 iio_dev->name = spi_get_device_id(spi)->name; 147 148 for (i = 0; i < ARRAY_SIZE(priv->cache); i++) { 149 ret = dac7612_cmd_single(priv, i, 0); 150 if (ret) 151 return ret; 152 } 153 154 return devm_iio_device_register(&spi->dev, iio_dev); 155 } 156 157 static const struct spi_device_id dac7612_id[] = { 158 {"ti-dac7612"}, 159 {} 160 }; 161 MODULE_DEVICE_TABLE(spi, dac7612_id); 162 163 static const struct of_device_id dac7612_of_match[] = { 164 { .compatible = "ti,dac7612" }, 165 { .compatible = "ti,dac7612u" }, 166 { .compatible = "ti,dac7612ub" }, 167 { }, 168 }; 169 MODULE_DEVICE_TABLE(of, dac7612_of_match); 170 171 static struct spi_driver dac7612_driver = { 172 .driver = { 173 .name = "ti-dac7612", 174 .of_match_table = dac7612_of_match, 175 }, 176 .probe = dac7612_probe, 177 .id_table = dac7612_id, 178 }; 179 module_spi_driver(dac7612_driver); 180 181 MODULE_AUTHOR("Ricardo Ribalda <ribalda@kernel.org>"); 182 MODULE_DESCRIPTION("Texas Instruments DAC7612 DAC driver"); 183 MODULE_LICENSE("GPL v2"); 184