2 * Copyright (c) 2019 Ian Lepore.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * Driver for Texas Instruments ADS101x and ADS111x family i2c ADC chips.
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include "opt_platform.h"
34 #include <sys/param.h>
35 #include <sys/systm.h>
37 #include <sys/endian.h>
38 #include <sys/kernel.h>
40 #include <sys/module.h>
42 #include <sys/sysctl.h>
45 #include <dev/ofw/ofw_bus.h>
46 #include <dev/ofw/ofw_bus_subr.h>
49 #include <dev/iicbus/iiconf.h>
50 #include <dev/iicbus/iicbus.h>
52 #include "iicbus_if.h"
55 * Chip registers, bit definitions, shifting and masking values.
57 #define ADS111x_CONV 0 /* Reg 0: Latest sample (ro) */
59 #define ADS111x_CONF 1 /* Reg 1: Config (rw) */
60 #define ADS111x_CONF_OS_SHIFT 15 /* Operational state */
61 #define ADS111x_CONF_MUX_SHIFT 12 /* Input mux setting */
62 #define ADS111x_CONF_GAIN_SHIFT 9 /* Programmable gain amp */
63 #define ADS111x_CONF_MODE_SHIFT 8 /* Operational mode */
64 #define ADS111x_CONF_RATE_SHIFT 5 /* Sample rate */
66 #define ADS111x_LOTHRESH 2 /* Compare lo threshold (rw) */
68 #define ADS111x_HITHRESH 3 /* Compare hi threshold (rw) */
71 * On config write, the operational-state bit starts a measurement, on read it
72 * indicates when the measurement process is complete/idle.
74 #define ADS111x_CONF_MEASURE (1u << ADS111x_CONF_OS_SHIFT)
75 #define ADS111x_CONF_IDLE (1u << ADS111x_CONF_OS_SHIFT)
78 * The default values for config items that are not per-channel. Mostly, this
79 * turns off the comparator on chips that have that feature, because this driver
80 * doesn't support it directly. However, the user is allowed to enable the
81 * comparator and we'll leave it alone if they do. That allows them connect the
82 * alert pin to something and use the feature without any help from this driver.
84 #define ADS111x_CONF_DEFAULT (1 << ADS111x_CONF_MODE_SHIFT)
85 #define ADS111x_CONF_USERMASK 0x001f
88 * Per-channel defaults. The chip only has one control register, and we load
89 * per-channel values into it every time we make a measurement on that channel.
90 * These are the default values for the control register from the datasheet, for
91 * values we maintain on a per-channel basis.
93 #define DEFAULT_GAINIDX 2
94 #define DEFAULT_RATEIDX 4
97 * Full-scale ranges for each available amplifier setting, in microvolts. The
98 * ADS1x13 chips are fixed-range, the other chips contain a programmable gain
99 * amplifier, and the full scale range is based on the amplifier setting.
101 static const u_int fixedranges[8] = {
102 2048000, 2048000, 2048000, 2048000, 2048000, 2048000, 2048000, 2048000,
104 static const u_int gainranges[8] = {
105 6144000, 4096000, 2048000, 1024000, 512000, 256000, 256000, 256000,
108 /* The highest value for the ADS101x chip is 0x7ff0, for ADS111x it's 0x7fff. */
109 #define ADS101x_RANGEDIV ((1 << 15) - 15)
110 #define ADS111x_RANGEDIV ((1 << 15) - 1)
112 /* Samples per second; varies based on chip type. */
113 static const u_int rates101x[8] = {128, 250, 490, 920, 1600, 2400, 3300, 3300};
114 static const u_int rates111x[8] = { 8, 16, 32, 64, 128, 250, 475, 860};
116 struct ads111x_channel {
117 u_int gainidx; /* Amplifier (full-scale range) config index */
118 u_int rateidx; /* Samples per second config index */
119 bool configured; /* Channel has been configured */
122 #define ADS111x_MAX_CHANNELS 8
124 struct ads111x_chipinfo {
126 const u_int *rangetab;
127 const u_int *ratetab;
132 static struct ads111x_chipinfo ads111x_chip_infos[] = {
133 { "ADS1013", fixedranges, rates101x, 1, ADS101x_RANGEDIV },
134 { "ADS1014", gainranges, rates101x, 1, ADS101x_RANGEDIV },
135 { "ADS1015", gainranges, rates101x, 8, ADS101x_RANGEDIV },
136 { "ADS1113", fixedranges, rates111x, 1, ADS111x_RANGEDIV },
137 { "ADS1114", gainranges, rates111x, 1, ADS111x_RANGEDIV },
138 { "ADS1115", gainranges, rates111x, 8, ADS111x_RANGEDIV },
142 static struct ofw_compat_data compat_data[] = {
143 {"ti,ads1013", (uintptr_t)&ads111x_chip_infos[0]},
144 {"ti,ads1014", (uintptr_t)&ads111x_chip_infos[1]},
145 {"ti,ads1015", (uintptr_t)&ads111x_chip_infos[2]},
146 {"ti,ads1113", (uintptr_t)&ads111x_chip_infos[3]},
147 {"ti,ads1114", (uintptr_t)&ads111x_chip_infos[4]},
148 {"ti,ads1115", (uintptr_t)&ads111x_chip_infos[5]},
149 {NULL, (uintptr_t)NULL},
151 IICBUS_FDT_PNP_INFO(compat_data);
154 struct ads111x_softc {
159 const struct ads111x_chipinfo
161 struct ads111x_channel
162 channels[ADS111x_MAX_CHANNELS];
166 ads111x_write_2(struct ads111x_softc *sc, int reg, int val)
172 return (iic2errno(iicdev_writeto(sc->dev, reg, data, 2, IIC_WAIT)));
176 ads111x_read_2(struct ads111x_softc *sc, int reg, int *val)
181 err = iic2errno(iicdev_readfrom(sc->dev, reg, data, 2, IIC_WAIT));
183 *val = (int16_t)be16dec(data);
189 ads111x_sample_voltage(struct ads111x_softc *sc, int channum, int *voltage)
191 struct ads111x_channel *chan;
192 int err, cfgword, convword, rate, waitns;
195 chan = &sc->channels[channum];
197 /* Ask the chip to do a one-shot measurement of the given channel. */
198 cfgword = sc->cfgword |
199 (1 << ADS111x_CONF_OS_SHIFT) |
200 (channum << ADS111x_CONF_MUX_SHIFT) |
201 (chan->gainidx << ADS111x_CONF_GAIN_SHIFT) |
202 (chan->rateidx << ADS111x_CONF_RATE_SHIFT);
203 if ((err = ads111x_write_2(sc, ADS111x_CONF, cfgword)) != 0)
207 * Calculate how long it will take to make the measurement at the
208 * current sampling rate (round up), and sleep at least that long.
210 rate = sc->chipinfo->ratetab[chan->rateidx];
211 waitns = (1000000000 + rate - 1) / rate;
212 err = pause_sbt("ads111x", nstosbt(waitns), 0, C_PREL(2));
213 if (err != 0 && err != EWOULDBLOCK)
218 * Sanity-check that the measurement is complete. Not enabled by
219 * default because checking wastes 200-800us just in moving the status
220 * command and result across the i2c bus, which could double the time it
221 * takes to get one measurement. Unlike most i2c slaves, this device
222 * does not auto-increment the register number on reads, so we can't
223 * read both status and measurement in one operation.
225 if ((err = ads111x_read_2(sc, ADS111x_CONF, &cfgword)) != 0)
227 if (!(cfgword & ADS111x_CONF_IDLE))
231 /* Retrieve the sample and convert it to microvolts. */
232 if ((err = ads111x_read_2(sc, ADS111x_CONV, &convword)) != 0)
234 fsrange = sc->chipinfo->rangetab[chan->gainidx];
235 *voltage = (int)((convword * fsrange ) / sc->chipinfo->rangediv);
241 ads111x_sysctl_gainidx(SYSCTL_HANDLER_ARGS)
243 struct ads111x_softc *sc;
244 int chan, err, gainidx;
249 gainidx = sc->channels[chan].gainidx;
250 err = sysctl_handle_int(oidp, &gainidx, 0, req);
251 if (err != 0 || req->newptr == NULL)
253 if (gainidx < 0 || gainidx > 7)
256 sc->channels[chan].gainidx = gainidx;
257 sx_xunlock(&sc->lock);
263 ads111x_sysctl_rateidx(SYSCTL_HANDLER_ARGS)
265 struct ads111x_softc *sc;
266 int chan, err, rateidx;
271 rateidx = sc->channels[chan].rateidx;
272 err = sysctl_handle_int(oidp, &rateidx, 0, req);
273 if (err != 0 || req->newptr == NULL)
275 if (rateidx < 0 || rateidx > 7)
278 sc->channels[chan].rateidx = rateidx;
279 sx_xunlock(&sc->lock);
285 ads111x_sysctl_voltage(SYSCTL_HANDLER_ARGS)
287 struct ads111x_softc *sc;
288 int chan, err, voltage;
293 if (req->oldptr != NULL) {
295 err = ads111x_sample_voltage(sc, chan, &voltage);
296 sx_xunlock(&sc->lock);
298 device_printf(sc->dev,
299 "conversion read failed, error %d\n", err);
303 err = sysctl_handle_int(oidp, &voltage, 0, req);
308 ads111x_sysctl_config(SYSCTL_HANDLER_ARGS)
310 struct ads111x_softc *sc;
314 config = sc->cfgword & ADS111x_CONF_USERMASK;
315 err = sysctl_handle_int(oidp, &config, 0, req);
316 if (err != 0 || req->newptr == NULL)
319 sc->cfgword = config & ADS111x_CONF_USERMASK;
320 err = ads111x_write_2(sc, ADS111x_CONF, sc->cfgword);
321 sx_xunlock(&sc->lock);
326 ads111x_sysctl_lothresh(SYSCTL_HANDLER_ARGS)
328 struct ads111x_softc *sc;
332 if ((err = ads111x_read_2(sc, ADS111x_LOTHRESH, &thresh)) != 0)
334 err = sysctl_handle_int(oidp, &thresh, 0, req);
335 if (err != 0 || req->newptr == NULL)
338 err = ads111x_write_2(sc, ADS111x_CONF, thresh);
339 sx_xunlock(&sc->lock);
345 ads111x_sysctl_hithresh(SYSCTL_HANDLER_ARGS)
347 struct ads111x_softc *sc;
351 if ((err = ads111x_read_2(sc, ADS111x_HITHRESH, &thresh)) != 0)
353 err = sysctl_handle_int(oidp, &thresh, 0, req);
354 if (err != 0 || req->newptr == NULL)
357 err = ads111x_write_2(sc, ADS111x_CONF, thresh);
358 sx_xunlock(&sc->lock);
364 ads111x_setup_channel(struct ads111x_softc *sc, int chan, int gainidx, int rateidx)
366 struct ads111x_channel *c;
367 struct sysctl_ctx_list *ctx;
368 struct sysctl_oid *chantree, *devtree;
371 c = &sc->channels[chan];
372 c->gainidx = gainidx;
373 c->rateidx = rateidx;
376 * If setting up the channel for the first time, create channel's
377 * sysctl entries. We might have already configured the channel if
378 * config data for it exists in both FDT and hints.
384 ctx = device_get_sysctl_ctx(sc->dev);
385 devtree = device_get_sysctl_tree(sc->dev);
386 snprintf(chanstr, sizeof(chanstr), "%d", chan);
387 chantree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(devtree), OID_AUTO,
388 chanstr, CTLFLAG_RD, NULL, "channel data");
389 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(chantree), OID_AUTO,
390 "gain_index", CTLTYPE_INT | CTLFLAG_RWTUN, sc, chan,
391 ads111x_sysctl_gainidx, "I", "programmable gain amp setting, 0-7");
392 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(chantree), OID_AUTO,
393 "rate_index", CTLTYPE_INT | CTLFLAG_RWTUN, sc, chan,
394 ads111x_sysctl_rateidx, "I", "sample rate setting, 0-7");
395 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(chantree), OID_AUTO,
396 "voltage", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_SKIP, sc, chan,
397 ads111x_sysctl_voltage, "I", "sampled voltage in microvolts");
399 c->configured = true;
403 ads111x_add_channels(struct ads111x_softc *sc)
406 uint32_t chan, gainidx, num_added, rateidx, unit;
410 phandle_t child, node;
412 /* Configure any channels that have FDT data. */
414 node = ofw_bus_get_node(sc->dev);
415 for (child = OF_child(node); child != 0; child = OF_peer(child)) {
416 if (OF_getencprop(child, "reg", &chan, sizeof(chan)) == -1)
418 if (chan >= ADS111x_MAX_CHANNELS)
420 gainidx = DEFAULT_GAINIDX;
421 rateidx = DEFAULT_RATEIDX;
422 OF_getencprop(child, "ti,gain", &gainidx, sizeof(gainidx));
423 OF_getencprop(child, "ti,datarate", &rateidx, sizeof(rateidx));
424 ads111x_setup_channel(sc, chan, gainidx, rateidx);
431 /* Configure any channels that have hint data. */
432 name = device_get_name(sc->dev);
433 unit = device_get_unit(sc->dev);
434 for (chan = 0; chan < sc->chipinfo->numchan; ++chan) {
436 gainidx = DEFAULT_GAINIDX;
437 rateidx = DEFAULT_RATEIDX;
438 if (resource_int_value(name, unit, "gain_index", &gainidx) == 0)
440 if (resource_int_value(name, unit, "rate_index", &gainidx) == 0)
443 ads111x_setup_channel(sc, chan, gainidx, rateidx);
448 /* If any channels were configured via FDT or hints, we're done. */
453 * No channel config; add all possible channels using default values,
454 * and let the user configure the ones they want on the fly via sysctl.
456 for (chan = 0; chan < sc->chipinfo->numchan; ++chan) {
457 gainidx = DEFAULT_GAINIDX;
458 rateidx = DEFAULT_RATEIDX;
459 ads111x_setup_channel(sc, chan, gainidx, rateidx);
463 static const struct ads111x_chipinfo *
464 ads111x_find_chipinfo(device_t dev)
466 const struct ads111x_chipinfo *info;
467 const char *chiptype;
471 if (ofw_bus_status_okay(dev)) {
472 info = (struct ads111x_chipinfo*)
473 ofw_bus_search_compatible(dev, compat_data)->ocd_data;
479 /* For hinted devices, we must be told the chip type. */
481 resource_string_value(device_get_name(dev), device_get_unit(dev),
483 if (chiptype != NULL) {
484 for (i = 0; i < nitems(ads111x_chip_infos); ++i) {
485 info = &ads111x_chip_infos[i];
486 if (strcasecmp(chiptype, info->name) == 0)
494 ads111x_probe(device_t dev)
496 const struct ads111x_chipinfo *info;
498 info = ads111x_find_chipinfo(dev);
500 device_set_desc(dev, info->name);
501 return (BUS_PROBE_DEFAULT);
508 ads111x_attach(device_t dev)
510 struct ads111x_softc *sc;
511 struct sysctl_ctx_list *ctx;
512 struct sysctl_oid *tree;
515 sc = device_get_softc(dev);
517 sc->addr = iicbus_get_addr(dev);
518 sc->cfgword = ADS111x_CONF_DEFAULT;
520 sc->chipinfo = ads111x_find_chipinfo(sc->dev);
521 if (sc->chipinfo == NULL) {
523 "cannot get chipinfo (but it worked during probe)");
527 /* Set the default chip config. */
528 if ((err = ads111x_write_2(sc, ADS111x_CONF, sc->cfgword)) != 0) {
529 device_printf(dev, "cannot write chip config register\n");
533 /* Add the sysctl handler to set the chip configuration register. */
534 ctx = device_get_sysctl_ctx(dev);
535 tree = device_get_sysctl_tree(dev);
536 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
537 "config", CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0,
538 ads111x_sysctl_config, "I", "configuration register word");
539 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
540 "lo_thresh", CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0,
541 ads111x_sysctl_lothresh, "I", "comparator low threshold");
542 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
543 "hi_thresh", CTLTYPE_INT | CTLFLAG_RWTUN, sc, 0,
544 ads111x_sysctl_hithresh, "I", "comparator high threshold");
546 /* Set up channels based on metadata or default config. */
547 ads111x_add_channels(sc);
549 sx_init(&sc->lock, "ads111x");
555 ads111x_detach(device_t dev)
557 struct ads111x_softc *sc;
559 sc = device_get_softc(dev);
561 sx_destroy(&sc->lock);
565 static device_method_t ads111x_methods[] = {
566 DEVMETHOD(device_probe, ads111x_probe),
567 DEVMETHOD(device_attach, ads111x_attach),
568 DEVMETHOD(device_detach, ads111x_detach),
573 static driver_t ads111x_driver = {
576 sizeof(struct ads111x_softc),
578 static devclass_t ads111x_devclass;
580 DRIVER_MODULE(ads111x, iicbus, ads111x_driver, ads111x_devclass, NULL, NULL);
581 MODULE_VERSION(ads111x, 1);
582 MODULE_DEPEND(ads111x, iicbus, 1, 1, 1);