Module Name: src Committed By: thorpej Date: Wed May 19 13:40:57 UTC 2021
Modified Files: src/sys/dev/spi [thorpej-i2c-spi-conf]: mcp3k.c Log Message: If we were directly configured using the platform device tree, consult the device tree for our reference voltage and make the vref sysctl read-only in that case. Implement this for the Device Tree bindings for this device (the "vref-supply" property points to the regulator providing the reference voltage). To generate a diff of this commit: cvs rdiff -u -r1.2.36.2 -r1.2.36.3 src/sys/dev/spi/mcp3k.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/spi/mcp3k.c diff -u src/sys/dev/spi/mcp3k.c:1.2.36.2 src/sys/dev/spi/mcp3k.c:1.2.36.3 --- src/sys/dev/spi/mcp3k.c:1.2.36.2 Wed May 19 03:46:26 2021 +++ src/sys/dev/spi/mcp3k.c Wed May 19 13:40:56 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: mcp3k.c,v 1.2.36.2 2021/05/19 03:46:26 thorpej Exp $ */ +/* $NetBSD: mcp3k.c,v 1.2.36.3 2021/05/19 13:40:56 thorpej Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -45,6 +45,8 @@ * MPC3302/3304: http://ww1.microchip.com/downloads/en/DeviceDoc/21697F.pdf */ +#include "opt_fdt.h" + #include <sys/param.h> #include <sys/systm.h> #include <sys/device.h> @@ -55,6 +57,10 @@ #include <dev/sysmon/sysmonvar.h> #include <dev/spi/spivar.h> +#ifdef FDT +#include <dev/fdt/fdtvar.h> +#endif /* FDT */ + #define M3K_MAX_SENSORS 16 /* 8 single-ended & 8 diff. */ /* mcp3x0x model description */ @@ -77,6 +83,9 @@ struct mcp3kadc_softc { const struct mcp3kadc_model *sc_model; uint32_t sc_adc_max; int32_t sc_vref_mv; +#ifdef FDT + struct fdtbus_regulator *sc_vref_supply; +#endif struct sysmon_envsys *sc_sme; envsys_data_t sc_sensors[M3K_MAX_SENSORS]; @@ -247,14 +256,58 @@ mcp3kadc_match(device_t parent, cfdata_t return rv; } +#ifdef FDT +static bool +mcp3kadc_vref_fdt(struct mcp3kadc_softc *sc) +{ + devhandle_t devhandle = device_handle(sc->sc_dev); + int phandle = devhandle_to_of(devhandle); + int error; + u_int uvolts; + + sc->sc_vref_supply = fdtbus_regulator_acquire(phandle, "vref-supply"); + if (sc->sc_vref_supply == NULL) { + aprint_error_dev(sc->sc_dev, + "unable to acquire \"vref-supply\"\n"); + return false; + } + + error = fdtbus_regulator_enable(sc->sc_vref_supply); + if (error) { + aprint_error_dev(sc->sc_dev, + "failed to enable \"vref-supply\" (error = %d)\n", + error); + return false; + } + + error = fdtbus_regulator_get_voltage(sc->sc_vref_supply, &uvolts); + if (error) { + aprint_error_dev(sc->sc_dev, + "unable to get \"vref-supply\" voltage (error = %d)\n", + error); + (void) fdtbus_regulator_disable(sc->sc_vref_supply); + return false; + } + + /* + * Device tree property is uV, convert to mV that we use + * internally. + */ + sc->sc_vref_mv = uvolts / 1000; + return true; +} +#endif /* FDT */ + static void mcp3kadc_attach(device_t parent, device_t self, void *aux) { const struct sysctlnode *rnode, *node; struct spi_attach_args *sa = aux; struct mcp3kadc_softc *sc = device_private(self); + devhandle_t devhandle = device_handle(self); const struct mcp3kadc_model *model; int ch, i, error; + bool vref_read_only; sc->sc_dev = self; sc->sc_sh = sa->sa_handle; @@ -277,13 +330,27 @@ mcp3kadc_attach(device_t parent, device_ return; } - /* - * XXX Get vref-supply from device tree and make the sysctl - * XXX read-only in that case. - */ - /* set a default Vref in mV according to the chip's ADC resolution */ - sc->sc_vref_mv = 1 << ((model->flags & M3K_SIGNED) ? - model->bits - 1 : model->bits); + vref_read_only = false; + switch (devhandle_type(devhandle)) { +#ifdef FDT + case DEVHANDLE_TYPE_OF: + vref_read_only = mcp3kadc_vref_fdt(sc); + if (! vref_read_only) { + /* Error already displayed. */ + return; + } + break; +#endif /* FDT */ + default: + /* + * set a default Vref in mV according to the chip's ADC + * resolution + */ + sc->sc_vref_mv = 1 << ((model->flags & M3K_SIGNED) ? + model->bits - 1 : model->bits); + break; + } + /* remember maximum value for this ADC - also used for masking */ sc->sc_adc_max = (1 << model->bits) - 1; @@ -338,9 +405,11 @@ mcp3kadc_attach(device_t parent, device_ NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); + const int ctlflag = vref_read_only ? CTLFLAG_READONLY + : CTLFLAG_READWRITE; if (rnode != NULL) sysctl_createv(NULL, 0, NULL, &node, - CTLFLAG_READWRITE | CTLFLAG_OWNDESC, + ctlflag | CTLFLAG_OWNDESC, CTLTYPE_INT, "vref", SYSCTL_DESCR("ADC reference voltage"), sysctl_mcp3kadc_vref, 0, (void *)sc, 0,