Module Name: src Committed By: thorpej Date: Wed May 19 03:33:33 UTC 2021
Modified Files: src/sys/dev/spi [thorpej-i2c-spi-conf]: mcp48x1.c Log Message: Use spi_compatible_match(). To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.1.54.1 src/sys/dev/spi/mcp48x1.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/mcp48x1.c diff -u src/sys/dev/spi/mcp48x1.c:1.1 src/sys/dev/spi/mcp48x1.c:1.1.54.1 --- src/sys/dev/spi/mcp48x1.c:1.1 Tue Feb 25 20:09:37 2014 +++ src/sys/dev/spi/mcp48x1.c Wed May 19 03:33:33 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: mcp48x1.c,v 1.1 2014/02/25 20:09:37 rkujawa Exp $ */ +/* $NetBSD: mcp48x1.c,v 1.1.54.1 2021/05/19 03:33:33 thorpej Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mcp48x1.c,v 1.1 2014/02/25 20:09:37 rkujawa Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mcp48x1.c,v 1.1.54.1 2021/05/19 03:33:33 thorpej Exp $"); /* * Driver for Microchip MCP4801/MCP4811/MCP4821 DAC. @@ -57,7 +57,7 @@ __KERNEL_RCSID(0, "$NetBSD: mcp48x1.c,v #define MCP48X1DAC_DATA __BITS(11,0) /* data */ struct mcp48x1dac_model { - const char *name; + u_int name; uint8_t resolution; uint8_t shift; /* data left shift during write */ }; @@ -66,7 +66,7 @@ struct mcp48x1dac_softc { device_t sc_dev; struct spi_handle *sc_sh; - struct mcp48x1dac_model *sc_dm; /* struct describing DAC model */ + const struct mcp48x1dac_model *sc_dm; uint16_t sc_dac_data; bool sc_dac_gain; @@ -93,55 +93,97 @@ static int sysctl_mcp48x1dac_gain(SYSCTL CFATTACH_DECL_NEW(mcp48x1dac, sizeof(struct mcp48x1dac_softc), mcp48x1dac_match, mcp48x1dac_attach, NULL, NULL); -static struct mcp48x1dac_model mcp48x1_models[] = { - { - .name = "MCP4801", - .resolution = 8, - .shift = 4 - }, - { - .name = "MCP4811", - .resolution = 10, - .shift = 2 - }, - { - .name = "MCP4821", - .resolution = 12, - .shift = 0 - } +static const struct mcp48x1dac_model mcp4801 = { + .name = 4801, + .resolution = 8, + .shift = 4 +}; + +static const struct mcp48x1dac_model mcp4811 = { + .name = 4811, + .resolution = 10, + .shift = 2 +}; + +static const struct mcp48x1dac_model mcp4821 = { + .name = 4821, + .resolution = 12, + .shift = 0 +}; + +static const struct device_compatible_entry compat_data[] = { + { .compat = "microchip,mcp4801", .data = &mcp4801 }, + { .compat = "microchip,mcp4811", .data = &mcp4811 }, + { .compat = "microchip,mcp4821", .data = &mcp4821 }, + DEVICE_COMPAT_EOL }; +static const struct mcp48x1dac_model * +mcp48x1dac_lookup(const struct spi_attach_args *sa, const cfdata_t cf) +{ + const struct device_compatible_entry *dce; + + if (sa->sa_clist != NULL) { + dce = device_compatible_lookup_strlist(sa->sa_clist, + sa->sa_clist_size, compat_data); + if (dce == NULL) { + return NULL; + } + return dce->data; + } else { + const struct mcp48x1dac_model *model; + + for (dce = compat_data; dce->compat != NULL; dce++) { + model = dce->data; + if (model->name == cf->cf_flags) { + return model; + } + } + return NULL; + } +} static int mcp48x1dac_match(device_t parent, cfdata_t cf, void *aux) { struct spi_attach_args *sa = aux; + int rv; - /* MCP48x1 is a write-only device, so no way to detect it! */ - - if (spi_configure(sa->sa_handle, SPI_MODE_0, 20000000)) - return 0; + rv = spi_compatible_match(sa, cf, compat_data); + if (rv != 0) { + /* + * If we're doing indorect config, the user must + * have specified the correct model. + */ + if (sa->sa_clist == NULL && mcp48x1dac_lookup(sa, cf) == NULL) { + return 0; + } + + /* configure for 20MHz */ + if (spi_configure(sa->sa_handle, SPI_MODE_0, 20000000)) + return 0; + } - return 1; + return rv; } static void mcp48x1dac_attach(device_t parent, device_t self, void *aux) { - struct mcp48x1dac_softc *sc; - struct spi_attach_args *sa; - int cf_flags; - - aprint_naive(": Digital to Analog converter\n"); - aprint_normal(": MCP48x1 DAC\n"); + struct mcp48x1dac_softc *sc = device_private(self); + struct spi_attach_args *sa = aux; + const struct mcp48x1dac_model *model; - sa = aux; - sc = device_private(self); sc->sc_dev = self; sc->sc_sh = sa->sa_handle; - cf_flags = device_cfdata(sc->sc_dev)->cf_flags; - sc->sc_dm = &mcp48x1_models[cf_flags]; /* flag value defines model */ + model = mcp48x1dac_lookup(sa, device_cfdata(self)); + KASSERT(model != NULL); + + sc->sc_dm = model; + + aprint_naive(": Digital to Analog converter\n"); + aprint_normal(": MCP%u DAC\n", model->name); if(!mcp48x1dac_envsys_attach(sc)) { aprint_error_dev(sc->sc_dev, "failed to attach envsys\n");