File Index
Files and directories
Sign in
FILE

rohm-bd79703.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/dac/rohm-bd79703.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * BD79703 ROHM Digital to Analog converter
  4 *
  5 * Copyright (c) 2024, ROHM Semiconductor.
  6 */
  7
  8#include <linux/bits.h>
  9#include <linux/device.h>
 10#include <linux/module.h>
 11#include <linux/regmap.h>
 12#include <linux/regulator/consumer.h>
 13#include <linux/spi/spi.h>
 14#include <linux/iio/iio.h>
 15
 16#define BD79703_MAX_REGISTER 0xf
 17#define BD79703_DAC_BITS 8
 18#define BD79703_REG_OUT_ALL GENMASK(2, 0)
 19
 20/*
 21 * The BD79703 uses 12-bit SPI commands. First four bits (high bits) define
 22 * channel(s) which are operated on, and also the mode. The mode can be to set
 23 * a DAC word only, or set DAC word and output. The data-sheet is not very
 24 * specific on how a previously set DAC word can be 'taken in to use'. Thus
 25 * this driver only uses the 'set DAC and output it' -mode.
 26 *
 27 * The BD79703 latches last 12-bits when the chip-select is toggled. Thus we
 28 * can use 16-bit transfers which should be widely supported. To simplify this
 29 * further, we treat the last 8 bits as a value, and first 8 bits as an
 30 * address. This allows us to separate channels/mode by address and treat the
 31 * 8-bit register value as DAC word. The highest 4 bits of address will be
 32 * discarded when the transfer is latched.
 33 */
 34static const struct regmap_config bd79703_regmap_config = {
 35	.reg_bits = 8,
 36	.val_bits = 8,
 37	.max_register = BD79703_MAX_REGISTER,
 38	.cache_type = REGCACHE_MAPLE,
 39};
 40
 41/* Dynamic driver private data */
 42struct bd79703_data {
 43	struct regmap *regmap;
 44	int vfs;
 45};
 46
 47/* Static, IC type specific data for different variants */
 48struct bd7970x_chip_data {
 49	const char *name;
 50	const struct iio_chan_spec *channels;
 51	int num_channels;
 52	bool has_vfs;
 53};
 54
 55static int bd79703_read_raw(struct iio_dev *idev,
 56			    struct iio_chan_spec const *chan, int *val,
 57			    int *val2, long mask)
 58{
 59	struct bd79703_data *data = iio_priv(idev);
 60
 61	if (mask != IIO_CHAN_INFO_SCALE)
 62		return -EINVAL;
 63
 64	*val = data->vfs / 1000;
 65	*val2 = BD79703_DAC_BITS;
 66
 67	return IIO_VAL_FRACTIONAL_LOG2;
 68}
 69
 70static int bd79703_write_raw(struct iio_dev *idev,
 71			     struct iio_chan_spec const *chan, int val,
 72			     int val2, long mask)
 73{
 74	struct bd79703_data *data = iio_priv(idev);
 75
 76	if (val < 0 || val >= 1 << BD79703_DAC_BITS)
 77		return -EINVAL;
 78
 79	return regmap_write(data->regmap, chan->address, val);
 80};
 81
 82static const struct iio_info bd79703_info = {
 83	.read_raw = bd79703_read_raw,
 84	.write_raw = bd79703_write_raw,
 85};
 86
 87#define BD79703_CHAN_ADDR(_chan, _addr) {			\
 88	.type = IIO_VOLTAGE,					\
 89	.indexed = 1,						\
 90	.output = 1,						\
 91	.channel = (_chan),					\
 92	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
 93	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
 94	.address = (_addr),					\
 95}
 96
 97#define BD79703_CHAN(_chan) BD79703_CHAN_ADDR((_chan), (_chan) + 1)
 98
 99static const struct iio_chan_spec bd79700_channels[] = {
100	BD79703_CHAN(0),
101	BD79703_CHAN(1),
102};
103
104static const struct iio_chan_spec bd79701_channels[] = {
105	BD79703_CHAN(0),
106	BD79703_CHAN(1),
107	BD79703_CHAN(2),
108};
109
110/*
111 * The BD79702 has 4 channels. They aren't mapped to BD79703 channels 0, 1, 2
112 * and 3, but to the channels 0, 1, 4, 5. So the addressing used with SPI
113 * accesses is 1, 2, 5 and 6 for them. Thus, they're not constant offset to
114 * the channel number as with other IC variants.
115 */
116static const struct iio_chan_spec bd79702_channels[] = {
117	BD79703_CHAN_ADDR(0, 1),
118	BD79703_CHAN_ADDR(1, 2),
119	BD79703_CHAN_ADDR(2, 5),
120	BD79703_CHAN_ADDR(3, 6),
121};
122
123static const struct iio_chan_spec bd79703_channels[] = {
124	BD79703_CHAN(0),
125	BD79703_CHAN(1),
126	BD79703_CHAN(2),
127	BD79703_CHAN(3),
128	BD79703_CHAN(4),
129	BD79703_CHAN(5),
130};
131
132static const struct bd7970x_chip_data bd79700_chip_data = {
133	.name = "bd79700",
134	.channels = bd79700_channels,
135	.num_channels = ARRAY_SIZE(bd79700_channels),
136	.has_vfs = false,
137};
138
139static const struct bd7970x_chip_data bd79701_chip_data = {
140	.name = "bd79701",
141	.channels = bd79701_channels,
142	.num_channels = ARRAY_SIZE(bd79701_channels),
143	.has_vfs = false,
144};
145
146static const struct bd7970x_chip_data bd79702_chip_data = {
147	.name = "bd79702",
148	.channels = bd79702_channels,
149	.num_channels = ARRAY_SIZE(bd79702_channels),
150	.has_vfs = true,
151};
152
153static const struct bd7970x_chip_data bd79703_chip_data = {
154	.name = "bd79703",
155	.channels = bd79703_channels,
156	.num_channels = ARRAY_SIZE(bd79703_channels),
157	.has_vfs = true,
158};
159
160static int bd79703_probe(struct spi_device *spi)
161{
162	const struct bd7970x_chip_data *cd;
163	struct device *dev = &spi->dev;
164	struct bd79703_data *data;
165	struct iio_dev *idev;
166	int ret;
167
168	cd = spi_get_device_match_data(spi);
169	if (!cd)
170		return -ENODEV;
171
172	idev = devm_iio_device_alloc(dev, sizeof(*data));
173	if (!idev)
174		return -ENOMEM;
175
176	data = iio_priv(idev);
177
178	data->regmap = devm_regmap_init_spi(spi, &bd79703_regmap_config);
179	if (IS_ERR(data->regmap))
180		return dev_err_probe(dev, PTR_ERR(data->regmap),
181				     "Failed to initialize Regmap\n");
182
183	/*
184	 * BD79703 has a separate VFS pin, whereas the BD79700 and BD79701 use
185	 * VCC for their full-scale output voltage.
186	 */
187	if (cd->has_vfs) {
188		ret = devm_regulator_get_enable(dev, "vcc");
189		if (ret)
190			return dev_err_probe(dev, ret, "Failed to enable VCC\n");
191
192		ret = devm_regulator_get_enable_read_voltage(dev, "vfs");
193		if (ret < 0)
194			return dev_err_probe(dev, ret, "Failed to get Vfs\n");
195	} else {
196		ret = devm_regulator_get_enable_read_voltage(dev, "vcc");
197		if (ret < 0)
198			return dev_err_probe(dev, ret, "Failed to get VCC\n");
199	}
200	data->vfs = ret;
201
202	idev->channels = cd->channels;
203	idev->num_channels = cd->num_channels;
204	idev->modes = INDIO_DIRECT_MODE;
205	idev->info = &bd79703_info;
206	idev->name = cd->name;
207
208	/* Initialize all to output zero */
209	ret = regmap_write(data->regmap, BD79703_REG_OUT_ALL, 0);
210	if (ret)
211		return ret;
212
213	return devm_iio_device_register(dev, idev);
214}
215
216static const struct spi_device_id bd79703_id[] = {
217	{ "bd79700", (kernel_ulong_t)&bd79700_chip_data },
218	{ "bd79701", (kernel_ulong_t)&bd79701_chip_data },
219	{ "bd79702", (kernel_ulong_t)&bd79702_chip_data },
220	{ "bd79703", (kernel_ulong_t)&bd79703_chip_data },
221	{ }
222};
223MODULE_DEVICE_TABLE(spi, bd79703_id);
224
225static const struct of_device_id bd79703_of_match[] = {
226	{ .compatible = "rohm,bd79700", .data = &bd79700_chip_data },
227	{ .compatible = "rohm,bd79701", .data = &bd79701_chip_data },
228	{ .compatible = "rohm,bd79702", .data = &bd79702_chip_data },
229	{ .compatible = "rohm,bd79703", .data = &bd79703_chip_data },
230	{ }
231};
232MODULE_DEVICE_TABLE(of, bd79703_of_match);
233
234static struct spi_driver bd79703_driver = {
235	.driver = {
236		.name = "bd79703",
237		.of_match_table = bd79703_of_match,
238	},
239	.probe = bd79703_probe,
240	.id_table = bd79703_id,
241};
242module_spi_driver(bd79703_driver);
243
244MODULE_AUTHOR("Matti Vaittinen <mazziesaccount@gmail.com>");
245MODULE_DESCRIPTION("ROHM BD79703 DAC driver");
246MODULE_LICENSE("GPL");
~/ Read-only file preview.