Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/thorpej-i2c-spi-conf]: src/sys/arch/sandpoint/sandpoint Use a private de...
details: https://anonhg.NetBSD.org/src/rev/c69f3e3b64d7
branches: thorpej-i2c-spi-conf
changeset: 378751:c69f3e3b64d7
user: thorpej <thorpej%NetBSD.org@localhost>
date: Sun Apr 25 23:19:16 2021 +0000
description:
Use a private devhandle to implement i2c device enumeration on the
Sandpoint-based NAS devices.
diffstat:
sys/arch/sandpoint/sandpoint/autoconf.c | 222 +++++++++++++++++++++++--------
1 files changed, 162 insertions(+), 60 deletions(-)
diffs (263 lines):
diff -r a7bf45a958d6 -r c69f3e3b64d7 sys/arch/sandpoint/sandpoint/autoconf.c
--- a/sys/arch/sandpoint/sandpoint/autoconf.c Sun Apr 25 22:20:08 2021 +0000
+++ b/sys/arch/sandpoint/sandpoint/autoconf.c Sun Apr 25 23:19:16 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.c,v 1.29 2020/07/09 05:12:09 nisimura Exp $ */
+/* $NetBSD: autoconf.c,v 1.29.6.1 2021/04/25 23:19:16 thorpej Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.29 2020/07/09 05:12:09 nisimura Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.29.6.1 2021/04/25 23:19:16 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -44,6 +44,7 @@
#include <dev/cons.h>
#include <dev/pci/pcivar.h>
+#include <dev/i2c/i2cvar.h>
#include <net/if.h>
#include <net/if_ether.h>
@@ -57,31 +58,167 @@ static struct btinfo_net *bi_net;
static struct btinfo_prodfamily *bi_pfam;
static struct btinfo_model *bi_model;
-struct i2c_dev {
- const char *name;
- unsigned addr;
- /* only attach when one of these bits in the model flags is set */
+struct sandpoint_i2cdev {
+ const char * name;
+ const char * compat;
uint32_t model_mask;
+ i2c_addr_t addr;
+};
+
+static const struct sandpoint_i2cdev dlink_i2cdevs[] = {
+[0] = {
+ .name = "strtc",
+ .compat = "st,m41t80",
+ .addr = 0x68,
+ },
+[1] = {
+ .name = NULL
+ }
+};
+
+static const struct sandpoint_i2cdev iomega_i2cdevs[] = {
+[0] = {
+ .name = "dsrtc",
+ .compat = "dallas,ds1307",
+ .addr = 0x68,
+ },
+[1] = {
+ .name = NULL
+ }
};
-#define MAXI2CDEVS 4
-struct model_i2c {
- const char *family;
- struct i2c_dev i2c_devs[MAXI2CDEVS];
+static const struct sandpoint_i2cdev kurobox_i2cdevs[] = {
+[0] = {
+ .name = "rs5c372rtc",
+ .compat = "ricoh,rs5c372a",
+ .addr = 0x32,
+ },
+[1] = {
+ .name = NULL
+ }
+};
+
+static const struct sandpoint_i2cdev nhnas_i2cdevs[] = {
+[0] = {
+ .name = "pcf8563rtc",
+ .compat = "nxp,pcf8563",
+ .addr = 0x51,
+ },
+[1] = {
+ .name = NULL
+ }
+};
+
+static const struct sandpoint_i2cdev qnap_i2cdevs[] = {
+[0] = {
+ .name = "s390rtc",
+ .compat = "sii,s35390a",
+ .addr = 0x30,
+ },
+[1] = {
+ .name = NULL
+ }
+};
+
+static const struct sandpoint_i2cdev synology_i2cdevs[] = {
+[0] = {
+ .name = "rs5c372rtc",
+ .compat = "ricoh,rs5c372a",
+ .addr = 0x32,
+ },
+[1] = {
+ .name = "lmtemp",
+ .compat = "national,lm75",
+ .addr = 0x48,
+ .model_mask = BI_MODEL_THERMAL,
+ },
+[2] = {
+ .name = NULL
+ }
};
-static struct model_i2c model_i2c_list[] = {
- { "dlink", { { "strtc", 0x68, 0 } } },
- { "iomega", { { "dsrtc", 0x68, 0 } } },
- { "kurobox", { { "rs5c372rtc", 0x32, 0 } } },
- { "kurot4", { { "rs5c372rtc", 0x32, 0 } } },
- { "nhnas", { { "pcf8563rtc", 0x51, 0 } } },
- { "qnap", { { "s390rtc", 0x30, 0 } } },
- { "synology", { { "rs5c372rtc", 0x32, 0 },
- { "lmtemp", 0x48, BI_MODEL_THERMAL } } },
+static const struct device_compatible_entry sandpoint_i2c_compat[] = {
+ { .compat = "dlink", .data = &dlink_i2cdevs },
+ { .compat = "iomega", .data = &iomega_i2cdevs },
+ { .compat = "kurobox", .data = &kurobox_i2cdevs },
+ /* kurot4 has same i2c devices as kurobox */
+ { .compat = "kurot4", .data = &kurobox_i2cdevs },
+ { .compat = "nhnas", .data = &nhnas_i2cdevs },
+ { .compat = "qnap", .data = &qnap_i2cdevs },
+ { .compat = "synology", .data = &synology_i2cdevs },
+ DEVICE_COMPAT_EOL
};
-static void add_i2c_child_devices(device_t, const char *);
+/*
+ * We provide a device handle implementation for i2c device enumeration.
+ */
+static int
+sandpoint_i2c_enumerate_devices(device_t dev, devhandle_t call_handle, void *v)
+{
+ struct i2c_enumerate_devices_args *args = v;
+ const struct device_compatible_entry *dce;
+ const struct sandpoint_i2cdev *i2cdev;
+ prop_dictionary_t props;
+ bool cbrv;
+
+ KASSERT(bi_pfam != NULL);
+
+ const char *fam_name = bi_pfam->name;
+ dce = device_compatible_lookup(&fam_name, 1, sandpoint_i2c_compat);
+ if (dce == NULL) {
+ /* no i2c devices for this model. */
+ return 0;
+ }
+ i2cdev = dce->data;
+ KASSERT(i2cdev != NULL);
+
+ for (; i2cdev->name != NULL; i2cdev++) {
+ if (i2cdev->model_mask != 0) {
+ KASSERT(bi_model != NULL);
+ if ((i2cdev->model_mask & bi_model->flags) == 0) {
+ /* skip this device. */
+ continue;
+ }
+ }
+
+ props = prop_dictionary_create();
+
+ args->ia->ia_addr = i2cdev->addr;
+ args->ia->ia_name = i2cdev->name;
+ args->ia->ia_clist = i2cdev->compat;
+ args->ia->ia_clist_size = strlen(i2cdev->compat) + 1;
+ args->ia->ia_prop = props;
+ /* no devhandle for child devices. */
+ devhandle_invalidate(&args->ia->ia_devhandle);
+ args->ia->ia_cookie = 0; /* XXX */
+ args->ia->ia_cookietype = I2C_COOKIE_NONE; /* XXX */
+
+ cbrv = args->callback(dev, args);
+
+ prop_object_release(props);
+
+ if (!cbrv) {
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static device_call_t
+sandpoint_i2c_devhandle_lookup_device_call(devhandle_t handle, const char *name,
+ devhandle_t *call_handlep)
+{
+ if (strcmp(name, "i2c-enumerate-devices") == 0) {
+ return sandpoint_i2c_enumerate_devices;
+ }
+ return NULL;
+}
+
+static const struct devhandle_impl sandpoint_i2c_devhandle_impl = {
+ .type = DEVHANDLE_TYPE_PRIVATE,
+ .lookup_device_call = sandpoint_i2c_devhandle_lookup_device_call,
+};
/*
* Determine i/o configuration for a machine.
@@ -170,45 +307,10 @@ device_register(device_t dev, void *aux)
booted_partition = bi_rdev->cookie & 0xff;
}
else if (device_is_a(dev, "ociic") && bi_pfam != NULL) {
- add_i2c_child_devices(dev, bi_pfam->name);
+ /* For i2c device enumeration. */
+ devhandle_t devhandle = {
+ .impl = &sandpoint_i2c_devhandle_impl,
+ };
+ device_set_handle(dev, devhandle);
}
}
-
-static void
-add_i2c_child_devices(device_t self, const char *family)
-{
- struct i2c_dev *model_i2c_devs;
- prop_dictionary_t pd;
- prop_array_t pa;
- int i;
-
- for (i = 0;
- i < (int)(sizeof(model_i2c_list) / sizeof(model_i2c_list[0]));
- i++) {
- if (strcmp(family, model_i2c_list[i].family) == 0) {
- model_i2c_devs = model_i2c_list[i].i2c_devs;
- goto found;
- }
- }
- return;
-
- found:
- /* make an i2c-child-devices property list with for direct config. */
- pa = prop_array_create();
-
- for (i = 0; i < MAXI2CDEVS && model_i2c_devs[i].name != NULL; i++) {
- if (model_i2c_devs[i].model_mask != 0 &&
- !(bi_model->flags & model_i2c_devs[i].model_mask))
- continue;
- pd = prop_dictionary_create();
- prop_dictionary_set_string_nocopy(pd, "name",
- model_i2c_devs[i].name);
- prop_dictionary_set_uint32(pd, "addr",
- model_i2c_devs[i].addr);
- prop_array_add(pa, pd);
- prop_object_release(pd);
- }
-
- prop_dictionary_set(device_properties(self), "i2c-child-devices", pa);
- prop_object_release(pa);
-}
Home |
Main Index |
Thread Index |
Old Index