34#include "opt_platform.h"
39#include <sys/endian.h>
40#include <sys/kernel.h>
42#include <sys/module.h>
44#include <sys/sysctl.h>
47#include <dev/ofw/ofw_bus.h>
48#include <dev/ofw/ofw_bus_subr.h>
62#define ADS111x_CONF_OS_SHIFT 15
63#define ADS111x_CONF_MUX_SHIFT 12
64#define ADS111x_CONF_GAIN_SHIFT 9
65#define ADS111x_CONF_MODE_SHIFT 8
66#define ADS111x_CONF_RATE_SHIFT 5
67#define ADS111x_CONF_COMP_DISABLE 3
69#define ADS111x_LOTHRESH 2
71#define ADS111x_HITHRESH 3
77#define ADS111x_CONF_MEASURE (1u << ADS111x_CONF_OS_SHIFT)
78#define ADS111x_CONF_IDLE (1u << ADS111x_CONF_OS_SHIFT)
87#define ADS111x_CONF_DEFAULT \
88 ((1 << ADS111x_CONF_MODE_SHIFT) | ADS111x_CONF_COMP_DISABLE)
89#define ADS111x_CONF_USERMASK 0x001f
97#define DEFAULT_GAINIDX 2
98#define DEFAULT_RATEIDX 4
106 2048000, 2048000, 2048000, 2048000, 2048000, 2048000, 2048000, 2048000,
109 6144000, 4096000, 2048000, 1024000, 512000, 256000, 256000, 256000,
113#define ADS101x_RANGEDIV ((1 << 15) - 15)
114#define ADS111x_RANGEDIV ((1 << 15) - 1)
117static const u_int
rates101x[8] = {128, 250, 490, 920, 1600, 2400, 3300, 3300};
118static const u_int
rates111x[8] = { 8, 16, 32, 64, 128, 250, 475, 860};
126#define ADS111x_MAX_CHANNELS 8
153 {NULL, (uintptr_t)NULL},
176 slaveaddr = iicbus_get_addr(sc->
dev);
206 int err, cfgword, convword, rate, retries, waitns;
226 waitns = (1000000000 + rate - 1) / rate;
227 err = pause_sbt(
"ads111x", nstosbt(waitns), 0, C_PREL(2));
228 if (err != 0 && err != EWOULDBLOCK)
243 for (retries = 5; ; --retries) {
245 return (EWOULDBLOCK);
250 pause_sbt(
"ads111x", nstosbt(waitns / 20), 0, C_PREL(2));
266 int chan, err, gainidx;
272 err = sysctl_handle_int(oidp, &gainidx, 0, req);
273 if (err != 0 || req->newptr == NULL)
275 if (gainidx < 0 || gainidx > 7)
279 sx_xunlock(&sc->
lock);
288 int chan, err, rateidx;
294 err = sysctl_handle_int(oidp, &rateidx, 0, req);
295 if (err != 0 || req->newptr == NULL)
297 if (rateidx < 0 || rateidx > 7)
301 sx_xunlock(&sc->
lock);
310 int chan, err, voltage;
315 if (req->oldptr != NULL) {
318 sx_xunlock(&sc->
lock);
320 device_printf(sc->
dev,
321 "conversion read failed, error %d\n", err);
325 err = sysctl_handle_int(oidp, &voltage, 0, req);
337 err = sysctl_handle_int(oidp, &config, 0, req);
338 if (err != 0 || req->newptr == NULL)
343 sx_xunlock(&sc->
lock);
356 err = sysctl_handle_int(oidp, &thresh, 0, req);
357 if (err != 0 || req->newptr == NULL)
361 sx_xunlock(&sc->
lock);
375 err = sysctl_handle_int(oidp, &thresh, 0, req);
376 if (err != 0 || req->newptr == NULL)
380 sx_xunlock(&sc->
lock);
389 struct sysctl_ctx_list *ctx;
390 struct sysctl_oid *chantree, *devtree;
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,
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,
418 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(chantree), OID_AUTO,
420 CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_SKIP | CTLFLAG_NEEDGIANT, sc,
430 uint32_t chan, gainidx, num_added, rateidx, unit;
434 phandle_t child, node;
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)
446 OF_getencprop(child,
"ti,gain", &gainidx,
sizeof(gainidx));
447 OF_getencprop(child,
"ti,datarate", &rateidx,
sizeof(rateidx));
456 name = device_get_name(sc->
dev);
457 unit = device_get_unit(sc->
dev);
463 snprintf(resname,
sizeof(resname),
"%d.gain_index", chan);
464 if (resource_int_value(name, unit, resname, &gainidx) == 0)
466 snprintf(resname,
sizeof(resname),
"%d.rate_index", chan);
467 if (resource_int_value(name, unit, resname, &rateidx) == 0)
494 const char *chiptype;
498 if (ofw_bus_status_okay(
dev)) {
508 resource_string_value(device_get_name(
dev), device_get_unit(
dev),
510 if (chiptype != NULL) {
513 if (strcasecmp(chiptype, info->
name) == 0)
527 device_set_desc(
dev, info->
name);
529 return (BUS_PROBE_DEFAULT);
531 return (BUS_PROBE_NOWILDCARD);
542 struct sysctl_ctx_list *ctx;
543 struct sysctl_oid *tree;
546 sc = device_get_softc(
dev);
548 sc->
addr = iicbus_get_addr(
dev);
554 "cannot get chipinfo (but it worked during probe)");
560 device_printf(
dev,
"cannot write chip config register\n");
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,
570 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
571 "lo_thresh", CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, sc, 0,
573 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
574 "hi_thresh", CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, sc, 0,
580 sx_init(&sc->
lock,
"ads111x");
590 sc = device_get_softc(
dev);
592 sx_destroy(&sc->
lock);
static const u_int fixedranges[8]
static int ads111x_sysctl_config(SYSCTL_HANDLER_ARGS)
MODULE_DEPEND(ads111x, iicbus, 1, 1, 1)
static int ads111x_attach(device_t dev)
static device_method_t ads111x_methods[]
static const u_int rates111x[8]
static int ads111x_sysctl_gainidx(SYSCTL_HANDLER_ARGS)
static struct ads111x_chipinfo ads111x_chip_infos[]
#define ADS111x_CONF_USERMASK
#define ADS111x_CONF_RATE_SHIFT
static int ads111x_read_2(struct ads111x_softc *sc, int reg, int *val)
static int ads111x_detach(device_t dev)
#define ADS111x_CONF_DEFAULT
static driver_t ads111x_driver
static int ads111x_sysctl_voltage(SYSCTL_HANDLER_ARGS)
static const u_int rates101x[8]
DRIVER_MODULE(ads111x, iicbus, ads111x_driver, ads111x_devclass, NULL, NULL)
static const u_int gainranges[8]
#define ADS111x_CONF_GAIN_SHIFT
#define ADS111x_CONF_MUX_SHIFT
static int ads111x_sysctl_hithresh(SYSCTL_HANDLER_ARGS)
static void ads111x_setup_channel(struct ads111x_softc *sc, int chan, int gainidx, int rateidx)
static void ads111x_add_channels(struct ads111x_softc *sc)
static int ads111x_sample_voltage(struct ads111x_softc *sc, int channum, int *voltage)
static int ads111x_probe(device_t dev)
#define ADS111x_CONF_IDLE
static int ads111x_write_2(struct ads111x_softc *sc, int reg, int val)
static int ads111x_sysctl_lothresh(SYSCTL_HANDLER_ARGS)
static devclass_t ads111x_devclass
MODULE_VERSION(ads111x, 1)
#define ADS111x_CONF_OS_SHIFT
static const struct ads111x_chipinfo * ads111x_find_chipinfo(device_t dev)
static int ads111x_sysctl_rateidx(SYSCTL_HANDLER_ARGS)
#define ADS111x_MAX_CHANNELS
static ds13_compat_data compat_data[]
#define IICBUS_FDT_PNP_INFO(t)
int iic2errno(int iic_status)
int iicdev_readfrom(device_t slavedev, uint8_t regaddr, void *buffer, uint16_t buflen, int waithow)
int iicbus_transfer_excl(device_t dev, struct iic_msg *msgs, uint32_t nmsgs, int how)
struct ads111x_channel channels[ADS111x_MAX_CHANNELS]
const struct ads111x_chipinfo * chipinfo