]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/iio/dac/mcp4725.c
Merge tag 'perf-core-for-mingo-5.2-20190517' of git://git.kernel.org/pub/scm/linux...
[mirror_ubuntu-hirsute-kernel.git] / drivers / iio / dac / mcp4725.c
CommitLineData
cf35ad61 1/*
35f73967 2 * mcp4725.c - Support for Microchip MCP4725/6
cf35ad61
PM
3 *
4 * Copyright (C) 2012 Peter Meerwald <pmeerw@pmeerw.net>
5 *
6 * Based on max517 by Roland Stigge <stigge@antcom.de>
7 *
8 * This file is subject to the terms and conditions of version 2 of
9 * the GNU General Public License. See the file COPYING in the main
10 * directory of this archive for more details.
11 *
12 * driver for the Microchip I2C 12-bit digital-to-analog converter (DAC)
13 * (7-bit I2C slave address 0x60, the three LSBs can be configured in
14 * hardware)
cf35ad61
PM
15 */
16
17#include <linux/module.h>
cf35ad61
PM
18#include <linux/i2c.h>
19#include <linux/err.h>
f17b77d6 20#include <linux/delay.h>
b440f1d9 21#include <linux/regulator/consumer.h>
8414af1e 22#include <linux/of_device.h>
88e39a88 23#include <linux/of.h>
cf35ad61
PM
24
25#include <linux/iio/iio.h>
26#include <linux/iio/sysfs.h>
27
28#include <linux/iio/dac/mcp4725.h>
29
30#define MCP4725_DRV_NAME "mcp4725"
31
29157c6d
TN
32#define MCP472X_REF_VDD 0x00
33#define MCP472X_REF_VREF_UNBUFFERED 0x02
34#define MCP472X_REF_VREF_BUFFERED 0x03
35
cf35ad61
PM
36struct mcp4725_data {
37 struct i2c_client *client;
29157c6d
TN
38 int id;
39 unsigned ref_mode;
40 bool vref_buffered;
cf35ad61 41 u16 dac_value;
155f1b41
PM
42 bool powerdown;
43 unsigned powerdown_mode;
b440f1d9 44 struct regulator *vdd_reg;
29157c6d 45 struct regulator *vref_reg;
cf35ad61
PM
46};
47
1a5bc41a 48static int __maybe_unused mcp4725_suspend(struct device *dev)
cf35ad61 49{
a97dd069
PM
50 struct mcp4725_data *data = iio_priv(i2c_get_clientdata(
51 to_i2c_client(dev)));
cf35ad61
PM
52 u8 outbuf[2];
53
155f1b41 54 outbuf[0] = (data->powerdown_mode + 1) << 4;
cf35ad61 55 outbuf[1] = 0;
155f1b41 56 data->powerdown = true;
cf35ad61 57
a97dd069 58 return i2c_master_send(data->client, outbuf, 2);
cf35ad61
PM
59}
60
1a5bc41a 61static int __maybe_unused mcp4725_resume(struct device *dev)
cf35ad61 62{
a97dd069
PM
63 struct mcp4725_data *data = iio_priv(i2c_get_clientdata(
64 to_i2c_client(dev)));
cf35ad61
PM
65 u8 outbuf[2];
66
67 /* restore previous DAC value */
68 outbuf[0] = (data->dac_value >> 8) & 0xf;
69 outbuf[1] = data->dac_value & 0xff;
155f1b41 70 data->powerdown = false;
cf35ad61 71
a97dd069 72 return i2c_master_send(data->client, outbuf, 2);
cf35ad61 73}
cf35ad61 74static SIMPLE_DEV_PM_OPS(mcp4725_pm_ops, mcp4725_suspend, mcp4725_resume);
cf35ad61 75
4fd313da 76static ssize_t mcp4725_store_eeprom(struct device *dev,
f17b77d6
PM
77 struct device_attribute *attr, const char *buf, size_t len)
78{
79 struct iio_dev *indio_dev = dev_to_iio_dev(dev);
80 struct mcp4725_data *data = iio_priv(indio_dev);
81 int tries = 20;
82 u8 inoutbuf[3];
83 bool state;
84 int ret;
85
86 ret = strtobool(buf, &state);
87 if (ret < 0)
88 return ret;
89
90 if (!state)
91 return 0;
92
93 inoutbuf[0] = 0x60; /* write EEPROM */
29157c6d 94 inoutbuf[0] |= data->ref_mode << 3;
06003531 95 inoutbuf[0] |= data->powerdown ? ((data->powerdown_mode + 1) << 1) : 0;
f17b77d6
PM
96 inoutbuf[1] = data->dac_value >> 4;
97 inoutbuf[2] = (data->dac_value & 0xf) << 4;
98
99 ret = i2c_master_send(data->client, inoutbuf, 3);
100 if (ret < 0)
101 return ret;
102 else if (ret != 3)
103 return -EIO;
104
105 /* wait for write complete, takes up to 50ms */
106 while (tries--) {
107 msleep(20);
108 ret = i2c_master_recv(data->client, inoutbuf, 3);
109 if (ret < 0)
110 return ret;
111 else if (ret != 3)
112 return -EIO;
113
114 if (inoutbuf[0] & 0x80)
115 break;
116 }
117
118 if (tries < 0) {
119 dev_err(&data->client->dev,
120 "mcp4725_store_eeprom() failed, incomplete\n");
121 return -EIO;
122 }
123
124 return len;
125}
126
127static IIO_DEVICE_ATTR(store_eeprom, S_IWUSR, NULL, mcp4725_store_eeprom, 0);
128
129static struct attribute *mcp4725_attributes[] = {
130 &iio_dev_attr_store_eeprom.dev_attr.attr,
131 NULL,
132};
133
134static const struct attribute_group mcp4725_attribute_group = {
135 .attrs = mcp4725_attributes,
136};
137
155f1b41
PM
138static const char * const mcp4725_powerdown_modes[] = {
139 "1kohm_to_gnd",
140 "100kohm_to_gnd",
141 "500kohm_to_gnd"
142};
143
35f73967
AM
144static const char * const mcp4726_powerdown_modes[] = {
145 "1kohm_to_gnd",
146 "125kohm_to_gnd",
147 "640kohm_to_gnd"
148};
149
155f1b41
PM
150static int mcp4725_get_powerdown_mode(struct iio_dev *indio_dev,
151 const struct iio_chan_spec *chan)
152{
153 struct mcp4725_data *data = iio_priv(indio_dev);
154
155 return data->powerdown_mode;
156}
157
158static int mcp4725_set_powerdown_mode(struct iio_dev *indio_dev,
159 const struct iio_chan_spec *chan, unsigned mode)
160{
161 struct mcp4725_data *data = iio_priv(indio_dev);
162
163 data->powerdown_mode = mode;
164
165 return 0;
166}
167
168static ssize_t mcp4725_read_powerdown(struct iio_dev *indio_dev,
169 uintptr_t private, const struct iio_chan_spec *chan, char *buf)
170{
171 struct mcp4725_data *data = iio_priv(indio_dev);
172
173 return sprintf(buf, "%d\n", data->powerdown);
174}
175
176static ssize_t mcp4725_write_powerdown(struct iio_dev *indio_dev,
177 uintptr_t private, const struct iio_chan_spec *chan,
178 const char *buf, size_t len)
179{
180 struct mcp4725_data *data = iio_priv(indio_dev);
181 bool state;
182 int ret;
183
184 ret = strtobool(buf, &state);
185 if (ret)
186 return ret;
187
188 if (state)
189 ret = mcp4725_suspend(&data->client->dev);
190 else
191 ret = mcp4725_resume(&data->client->dev);
192 if (ret < 0)
193 return ret;
194
195 return len;
196}
197
8414af1e 198enum chip_id {
35f73967
AM
199 MCP4725,
200 MCP4726,
201};
202
203static const struct iio_enum mcp472x_powerdown_mode_enum[] = {
204 [MCP4725] = {
205 .items = mcp4725_powerdown_modes,
206 .num_items = ARRAY_SIZE(mcp4725_powerdown_modes),
207 .get = mcp4725_get_powerdown_mode,
208 .set = mcp4725_set_powerdown_mode,
209 },
210 [MCP4726] = {
211 .items = mcp4726_powerdown_modes,
212 .num_items = ARRAY_SIZE(mcp4726_powerdown_modes),
213 .get = mcp4725_get_powerdown_mode,
214 .set = mcp4725_set_powerdown_mode,
215 },
155f1b41
PM
216};
217
218static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = {
219 {
220 .name = "powerdown",
221 .read = mcp4725_read_powerdown,
222 .write = mcp4725_write_powerdown,
3704432f 223 .shared = IIO_SEPARATE,
155f1b41 224 },
35f73967
AM
225 IIO_ENUM("powerdown_mode", IIO_SEPARATE,
226 &mcp472x_powerdown_mode_enum[MCP4725]),
227 IIO_ENUM_AVAILABLE("powerdown_mode",
228 &mcp472x_powerdown_mode_enum[MCP4725]),
229 { },
230};
231
232static const struct iio_chan_spec_ext_info mcp4726_ext_info[] = {
233 {
234 .name = "powerdown",
235 .read = mcp4725_read_powerdown,
236 .write = mcp4725_write_powerdown,
237 .shared = IIO_SEPARATE,
238 },
239 IIO_ENUM("powerdown_mode", IIO_SEPARATE,
240 &mcp472x_powerdown_mode_enum[MCP4726]),
241 IIO_ENUM_AVAILABLE("powerdown_mode",
242 &mcp472x_powerdown_mode_enum[MCP4726]),
155f1b41
PM
243 { },
244};
245
35f73967
AM
246static const struct iio_chan_spec mcp472x_channel[] = {
247 [MCP4725] = {
248 .type = IIO_VOLTAGE,
249 .indexed = 1,
250 .output = 1,
251 .channel = 0,
252 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
253 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
254 .ext_info = mcp4725_ext_info,
255 },
256 [MCP4726] = {
257 .type = IIO_VOLTAGE,
258 .indexed = 1,
259 .output = 1,
260 .channel = 0,
261 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
262 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
263 .ext_info = mcp4726_ext_info,
264 },
cf35ad61
PM
265};
266
267static int mcp4725_set_value(struct iio_dev *indio_dev, int val)
268{
269 struct mcp4725_data *data = iio_priv(indio_dev);
270 u8 outbuf[2];
271 int ret;
272
273 if (val >= (1 << 12) || val < 0)
274 return -EINVAL;
275
276 outbuf[0] = (val >> 8) & 0xf;
277 outbuf[1] = val & 0xff;
278
279 ret = i2c_master_send(data->client, outbuf, 2);
280 if (ret < 0)
281 return ret;
282 else if (ret != 2)
283 return -EIO;
284 else
285 return 0;
286}
287
29157c6d
TN
288static int mcp4726_set_cfg(struct iio_dev *indio_dev)
289{
290 struct mcp4725_data *data = iio_priv(indio_dev);
291 u8 outbuf[3];
292 int ret;
293
294 outbuf[0] = 0x40;
295 outbuf[0] |= data->ref_mode << 3;
296 if (data->powerdown)
297 outbuf[0] |= data->powerdown << 1;
298 outbuf[1] = data->dac_value >> 4;
299 outbuf[2] = (data->dac_value & 0xf) << 4;
300
301 ret = i2c_master_send(data->client, outbuf, 3);
302 if (ret < 0)
303 return ret;
304 else if (ret != 3)
305 return -EIO;
306 else
307 return 0;
308}
309
cf35ad61
PM
310static int mcp4725_read_raw(struct iio_dev *indio_dev,
311 struct iio_chan_spec const *chan,
312 int *val, int *val2, long mask)
313{
314 struct mcp4725_data *data = iio_priv(indio_dev);
b440f1d9 315 int ret;
cf35ad61
PM
316
317 switch (mask) {
318 case IIO_CHAN_INFO_RAW:
319 *val = data->dac_value;
320 return IIO_VAL_INT;
321 case IIO_CHAN_INFO_SCALE:
29157c6d
TN
322 if (data->ref_mode == MCP472X_REF_VDD)
323 ret = regulator_get_voltage(data->vdd_reg);
324 else
325 ret = regulator_get_voltage(data->vref_reg);
326
b440f1d9
TN
327 if (ret < 0)
328 return ret;
329
330 *val = ret / 1000;
b117f96f
LPC
331 *val2 = 12;
332 return IIO_VAL_FRACTIONAL_LOG2;
cf35ad61
PM
333 }
334 return -EINVAL;
335}
336
337static int mcp4725_write_raw(struct iio_dev *indio_dev,
338 struct iio_chan_spec const *chan,
339 int val, int val2, long mask)
340{
341 struct mcp4725_data *data = iio_priv(indio_dev);
342 int ret;
343
344 switch (mask) {
345 case IIO_CHAN_INFO_RAW:
346 ret = mcp4725_set_value(indio_dev, val);
347 data->dac_value = val;
348 break;
349 default:
350 ret = -EINVAL;
351 break;
352 }
353
354 return ret;
355}
356
357static const struct iio_info mcp4725_info = {
358 .read_raw = mcp4725_read_raw,
359 .write_raw = mcp4725_write_raw,
f17b77d6 360 .attrs = &mcp4725_attribute_group,
cf35ad61
PM
361};
362
88e39a88
TN
363#ifdef CONFIG_OF
364static int mcp4725_probe_dt(struct device *dev,
365 struct mcp4725_platform_data *pdata)
366{
367 struct device_node *np = dev->of_node;
368
369 if (!np)
370 return -ENODEV;
371
372 /* check if is the vref-supply defined */
373 pdata->use_vref = of_property_read_bool(np, "vref-supply");
374 pdata->vref_buffered =
375 of_property_read_bool(np, "microchip,vref-buffered");
376
377 return 0;
378}
379#else
380static int mcp4725_probe_dt(struct device *dev,
381 struct mcp4725_platform_data *platform_data)
382{
383 return -ENODEV;
384}
385#endif
386
fc52692c
GKH
387static int mcp4725_probe(struct i2c_client *client,
388 const struct i2c_device_id *id)
cf35ad61
PM
389{
390 struct mcp4725_data *data;
391 struct iio_dev *indio_dev;
88e39a88 392 struct mcp4725_platform_data *pdata, pdata_dt;
29157c6d 393 u8 inbuf[4];
155f1b41 394 u8 pd;
29157c6d 395 u8 ref;
cf35ad61
PM
396 int err;
397
b6ff86f3
PM
398 indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
399 if (indio_dev == NULL)
400 return -ENOMEM;
cf35ad61
PM
401 data = iio_priv(indio_dev);
402 i2c_set_clientdata(client, indio_dev);
403 data->client = client;
8414af1e
JMC
404 if (client->dev.of_node)
405 data->id = (enum chip_id)of_device_get_match_data(&client->dev);
406 else
407 data->id = id->driver_data;
88e39a88
TN
408 pdata = dev_get_platdata(&client->dev);
409
410 if (!pdata) {
411 err = mcp4725_probe_dt(&client->dev, &pdata_dt);
412 if (err) {
413 dev_err(&client->dev,
414 "invalid platform or devicetree data");
415 return err;
416 }
417 pdata = &pdata_dt;
418 }
29157c6d
TN
419
420 if (data->id == MCP4725 && pdata->use_vref) {
421 dev_err(&client->dev,
422 "external reference is unavailable on MCP4725");
423 return -EINVAL;
424 }
425
426 if (!pdata->use_vref && pdata->vref_buffered) {
427 dev_err(&client->dev,
428 "buffering is unavailable on the internal reference");
429 return -EINVAL;
430 }
431
432 if (!pdata->use_vref)
433 data->ref_mode = MCP472X_REF_VDD;
434 else
435 data->ref_mode = pdata->vref_buffered ?
436 MCP472X_REF_VREF_BUFFERED :
437 MCP472X_REF_VREF_UNBUFFERED;
cf35ad61 438
b440f1d9
TN
439 data->vdd_reg = devm_regulator_get(&client->dev, "vdd");
440 if (IS_ERR(data->vdd_reg))
441 return PTR_ERR(data->vdd_reg);
442
443 err = regulator_enable(data->vdd_reg);
444 if (err)
445 return err;
446
29157c6d
TN
447 if (pdata->use_vref) {
448 data->vref_reg = devm_regulator_get(&client->dev, "vref");
449 if (IS_ERR(data->vref_reg)) {
30df2d18 450 err = PTR_ERR(data->vref_reg);
29157c6d
TN
451 goto err_disable_vdd_reg;
452 }
453
454 err = regulator_enable(data->vref_reg);
455 if (err)
456 goto err_disable_vdd_reg;
457 }
458
cf35ad61 459 indio_dev->dev.parent = &client->dev;
97a249e9 460 indio_dev->name = id->name;
cf35ad61 461 indio_dev->info = &mcp4725_info;
35f73967 462 indio_dev->channels = &mcp472x_channel[id->driver_data];
cf35ad61
PM
463 indio_dev->num_channels = 1;
464 indio_dev->modes = INDIO_DIRECT_MODE;
465
29157c6d
TN
466 /* read current DAC value and settings */
467 err = i2c_master_recv(client, inbuf, data->id == MCP4725 ? 3 : 4);
468
cf35ad61
PM
469 if (err < 0) {
470 dev_err(&client->dev, "failed to read DAC value");
29157c6d 471 goto err_disable_vref_reg;
cf35ad61 472 }
155f1b41 473 pd = (inbuf[0] >> 1) & 0x3;
f272f19c 474 data->powerdown = pd > 0;
6a31c225 475 data->powerdown_mode = pd ? pd - 1 : 2; /* largest resistor to gnd */
cf35ad61 476 data->dac_value = (inbuf[1] << 4) | (inbuf[2] >> 4);
29157c6d
TN
477 if (data->id == MCP4726)
478 ref = (inbuf[3] >> 3) & 0x3;
479
480 if (data->id == MCP4726 && ref != data->ref_mode) {
481 dev_info(&client->dev,
482 "voltage reference mode differs (conf: %u, eeprom: %u), setting %u",
483 data->ref_mode, ref, data->ref_mode);
484 err = mcp4726_set_cfg(indio_dev);
485 if (err < 0)
486 goto err_disable_vref_reg;
487 }
488
b440f1d9
TN
489 err = iio_device_register(indio_dev);
490 if (err)
29157c6d 491 goto err_disable_vref_reg;
b440f1d9
TN
492
493 return 0;
494
29157c6d
TN
495err_disable_vref_reg:
496 if (data->vref_reg)
497 regulator_disable(data->vref_reg);
b440f1d9
TN
498
499err_disable_vdd_reg:
500 regulator_disable(data->vdd_reg);
501
502 return err;
cf35ad61
PM
503}
504
fc52692c 505static int mcp4725_remove(struct i2c_client *client)
cf35ad61 506{
b440f1d9
TN
507 struct iio_dev *indio_dev = i2c_get_clientdata(client);
508 struct mcp4725_data *data = iio_priv(indio_dev);
509
510 iio_device_unregister(indio_dev);
511
29157c6d
TN
512 if (data->vref_reg)
513 regulator_disable(data->vref_reg);
b440f1d9
TN
514 regulator_disable(data->vdd_reg);
515
cf35ad61
PM
516 return 0;
517}
518
519static const struct i2c_device_id mcp4725_id[] = {
35f73967
AM
520 { "mcp4725", MCP4725 },
521 { "mcp4726", MCP4726 },
cf35ad61
PM
522 { }
523};
524MODULE_DEVICE_TABLE(i2c, mcp4725_id);
525
8414af1e
JMC
526#ifdef CONFIG_OF
527static const struct of_device_id mcp4725_of_match[] = {
528 {
529 .compatible = "microchip,mcp4725",
530 .data = (void *)MCP4725
531 },
532 {
533 .compatible = "microchip,mcp4726",
534 .data = (void *)MCP4726
535 },
536 { }
537};
538MODULE_DEVICE_TABLE(of, mcp4725_of_match);
539#endif
540
cf35ad61
PM
541static struct i2c_driver mcp4725_driver = {
542 .driver = {
543 .name = MCP4725_DRV_NAME,
8414af1e 544 .of_match_table = of_match_ptr(mcp4725_of_match),
1a5bc41a 545 .pm = &mcp4725_pm_ops,
cf35ad61
PM
546 },
547 .probe = mcp4725_probe,
fc52692c 548 .remove = mcp4725_remove,
cf35ad61
PM
549 .id_table = mcp4725_id,
550};
551module_i2c_driver(mcp4725_driver);
552
553MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
35f73967 554MODULE_DESCRIPTION("MCP4725/6 12-bit DAC");
cf35ad61 555MODULE_LICENSE("GPL");