xref: /freebsd-13.1/sys/dev/iicbus/ads111x.c (revision 19d2d50e)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2019 Ian Lepore.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 /*
28  * Driver for Texas Instruments ADS101x and ADS111x family i2c ADC chips.
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 #include "opt_platform.h"
35 
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/bus.h>
39 #include <sys/endian.h>
40 #include <sys/kernel.h>
41 #include <sys/lock.h>
42 #include <sys/module.h>
43 #include <sys/sx.h>
44 #include <sys/sysctl.h>
45 
46 #ifdef FDT
47 #include <dev/ofw/ofw_bus.h>
48 #include <dev/ofw/ofw_bus_subr.h>
49 #endif
50 
51 #include <dev/iicbus/iiconf.h>
52 #include <dev/iicbus/iicbus.h>
53 
54 #include "iicbus_if.h"
55 
56 /*
57  * Chip registers, bit definitions, shifting and masking values.
58  */
59 #define	ADS111x_CONV			0	/* Reg 0: Latest sample (ro) */
60 
61 #define	ADS111x_CONF			1	/* Reg 1: Config (rw) */
62 #define	  ADS111x_CONF_OS_SHIFT		15	/* Operational state */
63 #define	  ADS111x_CONF_MUX_SHIFT	12	/* Input mux setting */
64 #define	  ADS111x_CONF_GAIN_SHIFT	 9	/* Programmable gain amp */
65 #define	  ADS111x_CONF_MODE_SHIFT	 8	/* Operational mode */
66 #define	  ADS111x_CONF_RATE_SHIFT	 5	/* Sample rate */
67 #define	  ADS111x_CONF_COMP_DISABLE	 3	/* Comparator disable */
68 
69 #define	ADS111x_LOTHRESH		2	/* Compare lo threshold (rw) */
70 
71 #define	ADS111x_HITHRESH		3	/* Compare hi threshold (rw) */
72 
73 /*
74  * On config write, the operational-state bit starts a measurement, on read it
75  * indicates when the measurement process is complete/idle.
76  */
77 #define	  ADS111x_CONF_MEASURE		(1u << ADS111x_CONF_OS_SHIFT)
78 #define	  ADS111x_CONF_IDLE		(1u << ADS111x_CONF_OS_SHIFT)
79 
80 /*
81  * The default values for config items that are not per-channel.  Mostly, this
82  * turns off the comparator on chips that have that feature, because this driver
83  * doesn't support it directly.  However, the user is allowed to enable the
84  * comparator and we'll leave it alone if they do.  That allows them connect the
85  * alert pin to something and use the feature without any help from this driver.
86  */
87 #define	ADS111x_CONF_DEFAULT    \
88     ((1 << ADS111x_CONF_MODE_SHIFT) | ADS111x_CONF_COMP_DISABLE)
89 #define	ADS111x_CONF_USERMASK   0x001f
90 
91 /*
92  * Per-channel defaults.  The chip only has one control register, and we load
93  * per-channel values into it every time we make a measurement on that channel.
94  * These are the default values for the control register from the datasheet, for
95  * values we maintain on a per-channel basis.
96  */
97 #define	DEFAULT_GAINIDX		2
98 #define	DEFAULT_RATEIDX		4
99 
100 /*
101  * Full-scale ranges for each available amplifier setting, in microvolts.  The
102  * ADS1x13 chips are fixed-range, the other chips contain a programmable gain
103  * amplifier, and the full scale range is based on the amplifier setting.
104  */
105 static const u_int fixedranges[8] = {
106 	2048000, 2048000, 2048000, 2048000, 2048000, 2048000, 2048000, 2048000,
107 };
108 static const u_int gainranges[8] = {
109 	6144000, 4096000, 2048000, 1024000,  512000,  256000,  256000,  256000,
110 };
111 
112 /* The highest value for the ADS101x chip is 0x7ff0, for ADS111x it's 0x7fff. */
113 #define	ADS101x_RANGEDIV	((1 << 15) - 15)
114 #define	ADS111x_RANGEDIV	((1 << 15) - 1)
115 
116 /* Samples per second; varies based on chip type. */
117 static const u_int rates101x[8] = {128, 250, 490, 920, 1600, 2400, 3300, 3300};
118 static const u_int rates111x[8] = {  8,  16,  32,  64,  128,  250,  475,  860};
119 
120 struct ads111x_channel {
121 	u_int gainidx;		/* Amplifier (full-scale range) config index */
122 	u_int rateidx;		/* Samples per second config index */
123 	bool  configured;	/* Channel has been configured */
124 };
125 
126 #define	ADS111x_MAX_CHANNELS	8
127 
128 struct ads111x_chipinfo {
129 	const char	*name;
130 	const u_int	*rangetab;
131 	const u_int	*ratetab;
132 	u_int		numchan;
133 	int		rangediv;
134 };
135 
136 static struct ads111x_chipinfo ads111x_chip_infos[] = {
137 	{ "ADS1013", fixedranges, rates101x, 1, ADS101x_RANGEDIV },
138 	{ "ADS1014", gainranges,  rates101x, 1, ADS101x_RANGEDIV },
139 	{ "ADS1015", gainranges,  rates101x, 8, ADS101x_RANGEDIV },
140 	{ "ADS1113", fixedranges, rates111x, 1, ADS111x_RANGEDIV },
141 	{ "ADS1114", gainranges,  rates111x, 1, ADS111x_RANGEDIV },
142 	{ "ADS1115", gainranges,  rates111x, 8, ADS111x_RANGEDIV },
143 };
144 
145 #ifdef FDT
146 static struct ofw_compat_data compat_data[] = {
147 	{"ti,ads1013",   (uintptr_t)&ads111x_chip_infos[0]},
148 	{"ti,ads1014",   (uintptr_t)&ads111x_chip_infos[1]},
149 	{"ti,ads1015",   (uintptr_t)&ads111x_chip_infos[2]},
150 	{"ti,ads1113",   (uintptr_t)&ads111x_chip_infos[3]},
151 	{"ti,ads1114",   (uintptr_t)&ads111x_chip_infos[4]},
152 	{"ti,ads1115",   (uintptr_t)&ads111x_chip_infos[5]},
153 	{NULL,           (uintptr_t)NULL},
154 };
155 IICBUS_FDT_PNP_INFO(compat_data);
156 #endif
157 
158 struct ads111x_softc {
159 	device_t	dev;
160 	struct sx	lock;
161 	int		addr;
162 	int		cfgword;
163 	const struct ads111x_chipinfo
164 			*chipinfo;
165 	struct ads111x_channel
166 			channels[ADS111x_MAX_CHANNELS];
167 };
168 
169 static int
ads111x_write_2(struct ads111x_softc * sc,int reg,int val)170 ads111x_write_2(struct ads111x_softc *sc, int reg, int val)
171 {
172 	uint8_t data[3];
173 	struct iic_msg msgs[1];
174 	uint8_t slaveaddr;
175 
176 	slaveaddr = iicbus_get_addr(sc->dev);
177 
178 	data[0] = reg;
179 	be16enc(&data[1], val);
180 
181 	msgs[0].slave = slaveaddr;
182 	msgs[0].flags = IIC_M_WR;
183 	msgs[0].len   = sizeof(data);
184 	msgs[0].buf   = data;
185 
186 	return (iicbus_transfer_excl(sc->dev, msgs, nitems(msgs), IIC_WAIT));
187 }
188 
189 static int
ads111x_read_2(struct ads111x_softc * sc,int reg,int * val)190 ads111x_read_2(struct ads111x_softc *sc, int reg, int *val)
191 {
192 	int err;
193 	uint8_t data[2];
194 
195 	err = iic2errno(iicdev_readfrom(sc->dev, reg, data, 2, IIC_WAIT));
196 	if (err == 0)
197 		*val = (int16_t)be16dec(data);
198 
199 	return (err);
200 }
201 
202 static int
ads111x_sample_voltage(struct ads111x_softc * sc,int channum,int * voltage)203 ads111x_sample_voltage(struct ads111x_softc *sc, int channum, int *voltage)
204 {
205 	struct ads111x_channel *chan;
206 	int err, cfgword, convword, rate, retries, waitns;
207 	int64_t fsrange;
208 
209 	chan = &sc->channels[channum];
210 
211 	/* Ask the chip to do a one-shot measurement of the given channel. */
212 	cfgword = sc->cfgword |
213 	    (1 << ADS111x_CONF_OS_SHIFT) |
214 	    (channum << ADS111x_CONF_MUX_SHIFT) |
215 	    (chan->gainidx << ADS111x_CONF_GAIN_SHIFT) |
216 	    (chan->rateidx << ADS111x_CONF_RATE_SHIFT);
217 	if ((err = ads111x_write_2(sc, ADS111x_CONF, cfgword)) != 0)
218 		return (err);
219 
220 	/*
221 	 * Calculate how long it will take to make the measurement at the
222 	 * current sampling rate (round up).  The measurement averaging time
223 	 * ranges from 300us to 125ms, so we yield the cpu while waiting.
224 	 */
225 	rate = sc->chipinfo->ratetab[chan->rateidx];
226 	waitns = (1000000000 + rate - 1) / rate;
227 	err = pause_sbt("ads111x", nstosbt(waitns), 0, C_PREL(2));
228 	if (err != 0 && err != EWOULDBLOCK)
229 		return (err);
230 
231 	/*
232 	 * In theory the measurement should be available now; we waited long
233 	 * enough.  However, the chip times its averaging intervals using an
234 	 * internal 1 MHz oscillator which likely isn't running at the same rate
235 	 * as the system clock, so we have to double-check that the measurement
236 	 * is complete before reading the result.  If it's not ready yet, yield
237 	 * the cpu again for 5% of the time we originally calculated.
238 	 *
239 	 * Unlike most i2c slaves, this device does not auto-increment the
240 	 * register number on reads, so we can't read both status and
241 	 * measurement in one operation.
242 	 */
243 	for (retries = 5; ; --retries) {
244 		if (retries == 0)
245 			return (EWOULDBLOCK);
246 		if ((err = ads111x_read_2(sc, ADS111x_CONF, &cfgword)) != 0)
247 			return (err);
248 		if (cfgword & ADS111x_CONF_IDLE)
249 			break;
250 		pause_sbt("ads111x", nstosbt(waitns / 20), 0, C_PREL(2));
251 	}
252 
253 	/* Retrieve the sample and convert it to microvolts. */
254 	if ((err = ads111x_read_2(sc, ADS111x_CONV, &convword)) != 0)
255 		return (err);
256 	fsrange = sc->chipinfo->rangetab[chan->gainidx];
257 	*voltage = (int)((convword * fsrange ) / sc->chipinfo->rangediv);
258 
259 	return (err);
260 }
261 
262 static int
ads111x_sysctl_gainidx(SYSCTL_HANDLER_ARGS)263 ads111x_sysctl_gainidx(SYSCTL_HANDLER_ARGS)
264 {
265 	struct ads111x_softc *sc;
266 	int chan, err, gainidx;
267 
268 	sc = arg1;
269 	chan = arg2;
270 
271 	gainidx = sc->channels[chan].gainidx;
272 	err = sysctl_handle_int(oidp, &gainidx, 0, req);
273 	if (err != 0 || req->newptr == NULL)
274 		return (err);
275 	if (gainidx < 0 || gainidx > 7)
276 		return (EINVAL);
277 	sx_xlock(&sc->lock);
278 	sc->channels[chan].gainidx = gainidx;
279 	sx_xunlock(&sc->lock);
280 
281 	return (err);
282 }
283 
284 static int
ads111x_sysctl_rateidx(SYSCTL_HANDLER_ARGS)285 ads111x_sysctl_rateidx(SYSCTL_HANDLER_ARGS)
286 {
287 	struct ads111x_softc *sc;
288 	int chan, err, rateidx;
289 
290 	sc = arg1;
291 	chan = arg2;
292 
293 	rateidx = sc->channels[chan].rateidx;
294 	err = sysctl_handle_int(oidp, &rateidx, 0, req);
295 	if (err != 0 || req->newptr == NULL)
296 		return (err);
297 	if (rateidx < 0 || rateidx > 7)
298 		return (EINVAL);
299 	sx_xlock(&sc->lock);
300 	sc->channels[chan].rateidx = rateidx;
301 	sx_xunlock(&sc->lock);
302 
303 	return (err);
304 }
305 
306 static int
ads111x_sysctl_voltage(SYSCTL_HANDLER_ARGS)307 ads111x_sysctl_voltage(SYSCTL_HANDLER_ARGS)
308 {
309 	struct ads111x_softc *sc;
310 	int chan, err, voltage;
311 
312 	sc = arg1;
313 	chan = arg2;
314 
315 	if (req->oldptr != NULL) {
316 		sx_xlock(&sc->lock);
317 		err = ads111x_sample_voltage(sc, chan, &voltage);
318 		sx_xunlock(&sc->lock);
319 		if (err != 0) {
320 			device_printf(sc->dev,
321 			    "conversion read failed, error %d\n", err);
322 			return (err);
323 		}
324 	}
325 	err = sysctl_handle_int(oidp, &voltage, 0, req);
326 	return (err);
327 }
328 
329 static int
ads111x_sysctl_config(SYSCTL_HANDLER_ARGS)330 ads111x_sysctl_config(SYSCTL_HANDLER_ARGS)
331 {
332 	struct ads111x_softc *sc;
333 	int config, err;
334 
335 	sc = arg1;
336 	config = sc->cfgword & ADS111x_CONF_USERMASK;
337 	err = sysctl_handle_int(oidp, &config, 0, req);
338 	if (err != 0 || req->newptr == NULL)
339 		return (err);
340 	sx_xlock(&sc->lock);
341 	sc->cfgword = config & ADS111x_CONF_USERMASK;
342 	err = ads111x_write_2(sc, ADS111x_CONF, sc->cfgword);
343 	sx_xunlock(&sc->lock);
344 
345 	return (err);
346 }
347 static int
ads111x_sysctl_lothresh(SYSCTL_HANDLER_ARGS)348 ads111x_sysctl_lothresh(SYSCTL_HANDLER_ARGS)
349 {
350 	struct ads111x_softc *sc;
351 	int thresh, err;
352 
353 	sc = arg1;
354 	if ((err = ads111x_read_2(sc, ADS111x_LOTHRESH, &thresh)) != 0)
355 		return (err);
356 	err = sysctl_handle_int(oidp, &thresh, 0, req);
357 	if (err != 0 || req->newptr == NULL)
358 		return (err);
359 	sx_xlock(&sc->lock);
360 	err = ads111x_write_2(sc, ADS111x_CONF, thresh);
361 	sx_xunlock(&sc->lock);
362 
363 	return (err);
364 }
365 
366 static int
ads111x_sysctl_hithresh(SYSCTL_HANDLER_ARGS)367 ads111x_sysctl_hithresh(SYSCTL_HANDLER_ARGS)
368 {
369 	struct ads111x_softc *sc;
370 	int thresh, err;
371 
372 	sc = arg1;
373 	if ((err = ads111x_read_2(sc, ADS111x_HITHRESH, &thresh)) != 0)
374 		return (err);
375 	err = sysctl_handle_int(oidp, &thresh, 0, req);
376 	if (err != 0 || req->newptr == NULL)
377 		return (err);
378 	sx_xlock(&sc->lock);
379 	err = ads111x_write_2(sc, ADS111x_CONF, thresh);
380 	sx_xunlock(&sc->lock);
381 
382 	return (err);
383 }
384 
385 static void
ads111x_setup_channel(struct ads111x_softc * sc,int chan,int gainidx,int rateidx)386 ads111x_setup_channel(struct ads111x_softc *sc, int chan, int gainidx, int rateidx)
387 {
388 	struct ads111x_channel *c;
389 	struct sysctl_ctx_list *ctx;
390 	struct sysctl_oid *chantree, *devtree;
391 	char chanstr[4];
392 
393 	c = &sc->channels[chan];
394 	c->gainidx = gainidx;
395 	c->rateidx = rateidx;
396 
397 	/*
398 	 *  If setting up the channel for the first time, create channel's
399 	 *  sysctl entries.  We might have already configured the channel if
400 	 *  config data for it exists in both FDT and hints.
401 	 */
402 
403 	if (c->configured)
404 		return;
405 
406 	ctx = device_get_sysctl_ctx(sc->dev);
407 	devtree = device_get_sysctl_tree(sc->dev);
408 	snprintf(chanstr, sizeof(chanstr), "%d", chan);
409 	chantree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(devtree), OID_AUTO,
410 	    chanstr, CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "channel data");
411 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(chantree), OID_AUTO,
412 	    "gain_index", CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT,
413 	    sc, chan, ads111x_sysctl_gainidx, "I",
414 	    "programmable gain amp setting, 0-7");
415 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(chantree), OID_AUTO,
416 	    "rate_index", CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT,
417 	    sc, chan, ads111x_sysctl_rateidx, "I", "sample rate setting, 0-7");
418 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(chantree), OID_AUTO,
419 	    "voltage",
420 	    CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_SKIP | CTLFLAG_NEEDGIANT, sc,
421 	    chan, ads111x_sysctl_voltage, "I", "sampled voltage in microvolts");
422 
423 	c->configured = true;
424 }
425 
426 static void
ads111x_add_channels(struct ads111x_softc * sc)427 ads111x_add_channels(struct ads111x_softc *sc)
428 {
429 	const char *name;
430 	uint32_t chan, gainidx, num_added, rateidx, unit;
431 	bool found;
432 
433 #ifdef FDT
434 	phandle_t child, node;
435 
436 	/* Configure any channels that have FDT data. */
437 	num_added = 0;
438 	node = ofw_bus_get_node(sc->dev);
439 	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
440 		if (OF_getencprop(child, "reg", &chan, sizeof(chan)) == -1)
441 			continue;
442 		if (chan >= ADS111x_MAX_CHANNELS)
443 			continue;
444 		gainidx = DEFAULT_GAINIDX;
445 		rateidx = DEFAULT_RATEIDX;
446 		OF_getencprop(child, "ti,gain", &gainidx, sizeof(gainidx));
447 		OF_getencprop(child, "ti,datarate", &rateidx, sizeof(rateidx));
448 		ads111x_setup_channel(sc, chan, gainidx, rateidx);
449 		++num_added;
450 	}
451 #else
452 	num_added = 0;
453 #endif
454 
455 	/* Configure any channels that have hint data. */
456 	name = device_get_name(sc->dev);
457 	unit = device_get_unit(sc->dev);
458 	for (chan = 0; chan < sc->chipinfo->numchan; ++chan) {
459 		char resname[16];
460 		found = false;
461 		gainidx = DEFAULT_GAINIDX;
462 		rateidx = DEFAULT_RATEIDX;
463 		snprintf(resname, sizeof(resname), "%d.gain_index", chan);
464 		if (resource_int_value(name, unit, resname, &gainidx) == 0)
465 			found = true;
466 		snprintf(resname, sizeof(resname), "%d.rate_index", chan);
467 		if (resource_int_value(name, unit, resname, &rateidx) == 0)
468 			found = true;
469 		if (found) {
470 			ads111x_setup_channel(sc, chan, gainidx, rateidx);
471 			++num_added;
472 		}
473 	}
474 
475 	/* If any channels were configured via FDT or hints, we're done. */
476 	if (num_added > 0)
477 		return;
478 
479 	/*
480 	 * No channel config; add all possible channels using default values,
481 	 * and let the user configure the ones they want on the fly via sysctl.
482 	 */
483 	for (chan = 0; chan < sc->chipinfo->numchan; ++chan) {
484 		gainidx = DEFAULT_GAINIDX;
485 		rateidx = DEFAULT_RATEIDX;
486 		ads111x_setup_channel(sc, chan, gainidx, rateidx);
487 	}
488 }
489 
490 static const struct ads111x_chipinfo *
ads111x_find_chipinfo(device_t dev)491 ads111x_find_chipinfo(device_t dev)
492 {
493 	const struct ads111x_chipinfo *info;
494 	const char *chiptype;
495 	int i;
496 
497 #ifdef FDT
498 	if (ofw_bus_status_okay(dev)) {
499 		info = (struct ads111x_chipinfo*)
500 		    ofw_bus_search_compatible(dev, compat_data)->ocd_data;
501 		if (info != NULL)
502 			return (info);
503 	}
504 #endif
505 
506 	/* For hinted devices, we must be told the chip type. */
507 	chiptype = NULL;
508 	resource_string_value(device_get_name(dev), device_get_unit(dev),
509 	    "type", &chiptype);
510 	if (chiptype != NULL) {
511 		for (i = 0; i < nitems(ads111x_chip_infos); ++i) {
512 			info = &ads111x_chip_infos[i];
513 			if (strcasecmp(chiptype, info->name) == 0)
514 				return (info);
515 		}
516 	}
517 	return (NULL);
518 }
519 
520 static int
ads111x_probe(device_t dev)521 ads111x_probe(device_t dev)
522 {
523 	const struct ads111x_chipinfo *info;
524 
525 	info = ads111x_find_chipinfo(dev);
526 	if (info != NULL) {
527 		device_set_desc(dev, info->name);
528 #ifdef FDT
529 		return (BUS_PROBE_DEFAULT);
530 #else
531 		return (BUS_PROBE_NOWILDCARD);
532 #endif
533 	}
534 
535 	return (ENXIO);
536 }
537 
538 static int
ads111x_attach(device_t dev)539 ads111x_attach(device_t dev)
540 {
541 	struct ads111x_softc *sc;
542 	struct sysctl_ctx_list *ctx;
543 	struct sysctl_oid *tree;
544 	int err;
545 
546 	sc = device_get_softc(dev);
547 	sc->dev = dev;
548 	sc->addr = iicbus_get_addr(dev);
549 	sc->cfgword = ADS111x_CONF_DEFAULT;
550 
551 	sc->chipinfo = ads111x_find_chipinfo(sc->dev);
552 	if (sc->chipinfo == NULL) {
553 		device_printf(dev,
554 		    "cannot get chipinfo (but it worked during probe)");
555 		return (ENXIO);
556 	}
557 
558 	/* Set the default chip config. */
559 	if ((err = ads111x_write_2(sc, ADS111x_CONF, sc->cfgword)) != 0) {
560 		device_printf(dev, "cannot write chip config register\n");
561 		return (err);
562 	}
563 
564 	/* Add the sysctl handler to set the chip configuration register.  */
565 	ctx = device_get_sysctl_ctx(dev);
566 	tree = device_get_sysctl_tree(dev);
567 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
568 	    "config", CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, sc, 0,
569 	    ads111x_sysctl_config, "I", "configuration register word");
570 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
571 	    "lo_thresh", CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, sc, 0,
572 	    ads111x_sysctl_lothresh, "I", "comparator low threshold");
573 	SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
574 	    "hi_thresh", CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, sc, 0,
575 	    ads111x_sysctl_hithresh, "I", "comparator high threshold");
576 
577 	/* Set up channels based on metadata or default config. */
578 	ads111x_add_channels(sc);
579 
580 	sx_init(&sc->lock, "ads111x");
581 
582 	return (0);
583 }
584 
585 static int
ads111x_detach(device_t dev)586 ads111x_detach(device_t dev)
587 {
588 	struct ads111x_softc *sc;
589 
590 	sc = device_get_softc(dev);
591 
592 	sx_destroy(&sc->lock);
593 	return (0);
594 }
595 
596 static device_method_t ads111x_methods[] = {
597 	DEVMETHOD(device_probe,		ads111x_probe),
598 	DEVMETHOD(device_attach,	ads111x_attach),
599 	DEVMETHOD(device_detach,	ads111x_detach),
600 
601 	DEVMETHOD_END,
602 };
603 
604 static driver_t ads111x_driver = {
605 	"ads111x",
606 	ads111x_methods,
607 	sizeof(struct ads111x_softc),
608 };
609 static devclass_t ads111x_devclass;
610 
611 DRIVER_MODULE(ads111x, iicbus, ads111x_driver, ads111x_devclass, NULL, NULL);
612 MODULE_VERSION(ads111x, 1);
613 MODULE_DEPEND(ads111x, iicbus, 1, 1, 1);
614