xref: /openbmc/linux/drivers/iio/dac/ds4424.c (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   * Maxim Integrated
4   * 7-bit, Multi-Channel Sink/Source Current DAC Driver
5   * Copyright (C) 2017 Maxim Integrated
6   */
7  
8  #include <linux/kernel.h>
9  #include <linux/module.h>
10  #include <linux/i2c.h>
11  #include <linux/regulator/consumer.h>
12  #include <linux/err.h>
13  #include <linux/delay.h>
14  #include <linux/iio/iio.h>
15  #include <linux/iio/driver.h>
16  #include <linux/iio/machine.h>
17  #include <linux/iio/consumer.h>
18  
19  #define DS4422_MAX_DAC_CHANNELS		2
20  #define DS4424_MAX_DAC_CHANNELS		4
21  
22  #define DS4424_DAC_ADDR(chan)   ((chan) + 0xf8)
23  #define DS4424_SOURCE_I		1
24  #define DS4424_SINK_I		0
25  
26  #define DS4424_CHANNEL(chan) { \
27  	.type = IIO_CURRENT, \
28  	.indexed = 1, \
29  	.output = 1, \
30  	.channel = chan, \
31  	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
32  }
33  
34  /*
35   * DS4424 DAC control register 8 bits
36   * [7]		0: to sink; 1: to source
37   * [6:0]	steps to sink/source
38   * bit[7] looks like a sign bit, but the value of the register is
39   * not a two's complement code considering the bit[6:0] is a absolute
40   * distance from the zero point.
41   */
42  union ds4424_raw_data {
43  	struct {
44  		u8 dx:7;
45  		u8 source_bit:1;
46  	};
47  	u8 bits;
48  };
49  
50  enum ds4424_device_ids {
51  	ID_DS4422,
52  	ID_DS4424,
53  };
54  
55  struct ds4424_data {
56  	struct i2c_client *client;
57  	struct mutex lock;
58  	uint8_t save[DS4424_MAX_DAC_CHANNELS];
59  	struct regulator *vcc_reg;
60  	uint8_t raw[DS4424_MAX_DAC_CHANNELS];
61  };
62  
63  static const struct iio_chan_spec ds4424_channels[] = {
64  	DS4424_CHANNEL(0),
65  	DS4424_CHANNEL(1),
66  	DS4424_CHANNEL(2),
67  	DS4424_CHANNEL(3),
68  };
69  
ds4424_get_value(struct iio_dev * indio_dev,int * val,int channel)70  static int ds4424_get_value(struct iio_dev *indio_dev,
71  			     int *val, int channel)
72  {
73  	struct ds4424_data *data = iio_priv(indio_dev);
74  	int ret;
75  
76  	mutex_lock(&data->lock);
77  	ret = i2c_smbus_read_byte_data(data->client, DS4424_DAC_ADDR(channel));
78  	if (ret < 0)
79  		goto fail;
80  
81  	*val = ret;
82  
83  fail:
84  	mutex_unlock(&data->lock);
85  	return ret;
86  }
87  
ds4424_set_value(struct iio_dev * indio_dev,int val,struct iio_chan_spec const * chan)88  static int ds4424_set_value(struct iio_dev *indio_dev,
89  			     int val, struct iio_chan_spec const *chan)
90  {
91  	struct ds4424_data *data = iio_priv(indio_dev);
92  	int ret;
93  
94  	mutex_lock(&data->lock);
95  	ret = i2c_smbus_write_byte_data(data->client,
96  			DS4424_DAC_ADDR(chan->channel), val);
97  	if (ret < 0)
98  		goto fail;
99  
100  	data->raw[chan->channel] = val;
101  
102  fail:
103  	mutex_unlock(&data->lock);
104  	return ret;
105  }
106  
ds4424_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)107  static int ds4424_read_raw(struct iio_dev *indio_dev,
108  			   struct iio_chan_spec const *chan,
109  			   int *val, int *val2, long mask)
110  {
111  	union ds4424_raw_data raw;
112  	int ret;
113  
114  	switch (mask) {
115  	case IIO_CHAN_INFO_RAW:
116  		ret = ds4424_get_value(indio_dev, val, chan->channel);
117  		if (ret < 0) {
118  			pr_err("%s : ds4424_get_value returned %d\n",
119  							__func__, ret);
120  			return ret;
121  		}
122  		raw.bits = *val;
123  		*val = raw.dx;
124  		if (raw.source_bit == DS4424_SINK_I)
125  			*val = -*val;
126  		return IIO_VAL_INT;
127  
128  	default:
129  		return -EINVAL;
130  	}
131  }
132  
ds4424_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)133  static int ds4424_write_raw(struct iio_dev *indio_dev,
134  			     struct iio_chan_spec const *chan,
135  			     int val, int val2, long mask)
136  {
137  	union ds4424_raw_data raw;
138  
139  	if (val2 != 0)
140  		return -EINVAL;
141  
142  	switch (mask) {
143  	case IIO_CHAN_INFO_RAW:
144  		if (val < S8_MIN || val > S8_MAX)
145  			return -EINVAL;
146  
147  		if (val > 0) {
148  			raw.source_bit = DS4424_SOURCE_I;
149  			raw.dx = val;
150  		} else {
151  			raw.source_bit = DS4424_SINK_I;
152  			raw.dx = -val;
153  		}
154  
155  		return ds4424_set_value(indio_dev, raw.bits, chan);
156  
157  	default:
158  		return -EINVAL;
159  	}
160  }
161  
ds4424_verify_chip(struct iio_dev * indio_dev)162  static int ds4424_verify_chip(struct iio_dev *indio_dev)
163  {
164  	int ret, val;
165  
166  	ret = ds4424_get_value(indio_dev, &val, 0);
167  	if (ret < 0)
168  		dev_err(&indio_dev->dev,
169  				"%s failed. ret: %d\n", __func__, ret);
170  
171  	return ret;
172  }
173  
ds4424_suspend(struct device * dev)174  static int ds4424_suspend(struct device *dev)
175  {
176  	struct i2c_client *client = to_i2c_client(dev);
177  	struct iio_dev *indio_dev = i2c_get_clientdata(client);
178  	struct ds4424_data *data = iio_priv(indio_dev);
179  	int ret = 0;
180  	int i;
181  
182  	for (i = 0; i < indio_dev->num_channels; i++) {
183  		data->save[i] = data->raw[i];
184  		ret = ds4424_set_value(indio_dev, 0,
185  				&indio_dev->channels[i]);
186  		if (ret < 0)
187  			return ret;
188  	}
189  	return ret;
190  }
191  
ds4424_resume(struct device * dev)192  static int ds4424_resume(struct device *dev)
193  {
194  	struct i2c_client *client = to_i2c_client(dev);
195  	struct iio_dev *indio_dev = i2c_get_clientdata(client);
196  	struct ds4424_data *data = iio_priv(indio_dev);
197  	int ret = 0;
198  	int i;
199  
200  	for (i = 0; i < indio_dev->num_channels; i++) {
201  		ret = ds4424_set_value(indio_dev, data->save[i],
202  				&indio_dev->channels[i]);
203  		if (ret < 0)
204  			return ret;
205  	}
206  	return ret;
207  }
208  
209  static DEFINE_SIMPLE_DEV_PM_OPS(ds4424_pm_ops, ds4424_suspend, ds4424_resume);
210  
211  static const struct iio_info ds4424_info = {
212  	.read_raw = ds4424_read_raw,
213  	.write_raw = ds4424_write_raw,
214  };
215  
ds4424_probe(struct i2c_client * client)216  static int ds4424_probe(struct i2c_client *client)
217  {
218  	const struct i2c_device_id *id = i2c_client_get_device_id(client);
219  	struct ds4424_data *data;
220  	struct iio_dev *indio_dev;
221  	int ret;
222  
223  	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
224  	if (!indio_dev) {
225  		dev_err(&client->dev, "iio dev alloc failed.\n");
226  		return -ENOMEM;
227  	}
228  
229  	data = iio_priv(indio_dev);
230  	i2c_set_clientdata(client, indio_dev);
231  	data->client = client;
232  	indio_dev->name = id->name;
233  
234  	data->vcc_reg = devm_regulator_get(&client->dev, "vcc");
235  	if (IS_ERR(data->vcc_reg))
236  		return dev_err_probe(&client->dev, PTR_ERR(data->vcc_reg),
237  				     "Failed to get vcc-supply regulator.\n");
238  
239  	mutex_init(&data->lock);
240  	ret = regulator_enable(data->vcc_reg);
241  	if (ret < 0) {
242  		dev_err(&client->dev,
243  				"Unable to enable the regulator.\n");
244  		return ret;
245  	}
246  
247  	usleep_range(1000, 1200);
248  	ret = ds4424_verify_chip(indio_dev);
249  	if (ret < 0)
250  		goto fail;
251  
252  	switch (id->driver_data) {
253  	case ID_DS4422:
254  		indio_dev->num_channels = DS4422_MAX_DAC_CHANNELS;
255  		break;
256  	case ID_DS4424:
257  		indio_dev->num_channels = DS4424_MAX_DAC_CHANNELS;
258  		break;
259  	default:
260  		dev_err(&client->dev,
261  				"ds4424: Invalid chip id.\n");
262  		ret = -ENXIO;
263  		goto fail;
264  	}
265  
266  	indio_dev->channels = ds4424_channels;
267  	indio_dev->modes = INDIO_DIRECT_MODE;
268  	indio_dev->info = &ds4424_info;
269  
270  	ret = iio_device_register(indio_dev);
271  	if (ret < 0) {
272  		dev_err(&client->dev,
273  				"iio_device_register failed. ret: %d\n", ret);
274  		goto fail;
275  	}
276  
277  	return ret;
278  
279  fail:
280  	regulator_disable(data->vcc_reg);
281  	return ret;
282  }
283  
ds4424_remove(struct i2c_client * client)284  static void ds4424_remove(struct i2c_client *client)
285  {
286  	struct iio_dev *indio_dev = i2c_get_clientdata(client);
287  	struct ds4424_data *data = iio_priv(indio_dev);
288  
289  	iio_device_unregister(indio_dev);
290  	regulator_disable(data->vcc_reg);
291  }
292  
293  static const struct i2c_device_id ds4424_id[] = {
294  	{ "ds4422", ID_DS4422 },
295  	{ "ds4424", ID_DS4424 },
296  	{ }
297  };
298  
299  MODULE_DEVICE_TABLE(i2c, ds4424_id);
300  
301  static const struct of_device_id ds4424_of_match[] = {
302  	{ .compatible = "maxim,ds4422" },
303  	{ .compatible = "maxim,ds4424" },
304  	{ },
305  };
306  
307  MODULE_DEVICE_TABLE(of, ds4424_of_match);
308  
309  static struct i2c_driver ds4424_driver = {
310  	.driver = {
311  		.name	= "ds4424",
312  		.of_match_table = ds4424_of_match,
313  		.pm     = pm_sleep_ptr(&ds4424_pm_ops),
314  	},
315  	.probe		= ds4424_probe,
316  	.remove		= ds4424_remove,
317  	.id_table	= ds4424_id,
318  };
319  module_i2c_driver(ds4424_driver);
320  
321  MODULE_DESCRIPTION("Maxim DS4424 DAC Driver");
322  MODULE_AUTHOR("Ismail H. Kose <ismail.kose@maximintegrated.com>");
323  MODULE_AUTHOR("Vishal Sood <vishal.sood@maximintegrated.com>");
324  MODULE_AUTHOR("David Jung <david.jung@maximintegrated.com>");
325  MODULE_LICENSE("GPL v2");
326