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/macppc/dev Children of the "cuda" i2...
details: https://anonhg.NetBSD.org/src/rev/3e42cb34a41e
branches: thorpej-i2c-spi-conf
changeset: 378754:3e42cb34a41e
user: thorpej <thorpej%NetBSD.org@localhost>
date: Sat May 08 11:40:02 2021 +0000
description:
Children of the "cuda" i2c controller don't appear in the OF device tree,
so we need to supply our own "i2c-enumerate-devices" method.
diffstat:
sys/arch/macppc/dev/cuda.c | 122 +++++++++++++++++++++++++++++++++-------
sys/arch/macppc/dev/videopll.c | 12 +++-
2 files changed, 108 insertions(+), 26 deletions(-)
diffs (223 lines):
diff -r 8ad82d1b1fe6 -r 3e42cb34a41e sys/arch/macppc/dev/cuda.c
--- a/sys/arch/macppc/dev/cuda.c Sat May 08 11:34:38 2021 +0000
+++ b/sys/arch/macppc/dev/cuda.c Sat May 08 11:40:02 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cuda.c,v 1.28 2021/04/24 23:36:41 thorpej Exp $ */
+/* $NetBSD: cuda.c,v 1.28.2.1 2021/05/08 11:40:02 thorpej Exp $ */
/*-
* Copyright (c) 2006 Michael Lorenz
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cuda.c,v 1.28 2021/04/24 23:36:41 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cuda.c,v 1.28.2.1 2021/05/08 11:40:02 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -72,6 +72,8 @@ typedef struct _cuda_handler {
void *cookie;
} CudaHandler;
+#define CUDA_MAX_I2C_DEVICES 2
+
struct cuda_softc {
device_t sc_dev;
void *sc_ih;
@@ -81,6 +83,20 @@ struct cuda_softc {
struct i2c_controller sc_i2c;
bus_space_tag_t sc_memt;
bus_space_handle_t sc_memh;
+
+ /*
+ * We provide our own i2c device enumeration method, so we
+ * need to provide our own devhandle_impl.
+ */
+ struct devhandle_impl sc_devhandle_impl;
+
+ struct {
+ const char *name;
+ const char *compatible;
+ i2c_addr_t addr;
+ } sc_i2c_devices[CUDA_MAX_I2C_DEVICES];
+ int sc_ni2c_devices;
+
int sc_node;
int sc_state;
int sc_waiting;
@@ -147,6 +163,65 @@ static int cuda_adb_set_handler(void *,
static int cuda_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t,
void *, size_t, int);
+static void
+cuda_add_i2c_device(struct cuda_softc *sc, const char *name,
+ const char *compatible, i2c_addr_t addr)
+{
+ KASSERT(sc->sc_ni2c_devices < CUDA_MAX_I2C_DEVICES);
+ sc->sc_i2c_devices[sc->sc_ni2c_devices].name = name;
+ sc->sc_i2c_devices[sc->sc_ni2c_devices].compatible = compatible;
+ sc->sc_i2c_devices[sc->sc_ni2c_devices].addr = addr;
+ sc->sc_ni2c_devices++;
+}
+
+static int
+cuda_i2c_enumerate_devices(device_t dev, devhandle_t call_handle, void *v)
+{
+ struct i2c_enumerate_devices_args *args = v;
+ prop_dictionary_t props;
+ int i;
+ bool cbrv;
+
+ /* dev is the "iicbus" instance. Cuda softc is in args. */
+ struct cuda_softc *sc = args->ia->ia_tag->ic_cookie;
+
+ for (i = 0; i < sc->sc_ni2c_devices; i++) {
+ props = prop_dictionary_create();
+
+ args->ia->ia_addr = sc->sc_i2c_devices[i].addr;
+ args->ia->ia_name = sc->sc_i2c_devices[i].name;
+ args->ia->ia_clist = sc->sc_i2c_devices[i].compatible;
+ args->ia->ia_clist_size = strlen(args->ia->ia_clist) + 1;
+ args->ia->ia_prop = props;
+ /* Child gets no handle. */
+ 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; /* callback decides if we continue */
+ }
+ }
+
+ return 0;
+}
+
+static device_call_t
+cuda_devhandle_lookup_device_call(devhandle_t handle, const char *name,
+ devhandle_t *call_handlep)
+{
+ if (strcmp(name, "i2c-enumerate-devices") == 0) {
+ return cuda_i2c_enumerate_devices;
+ }
+
+ /* Defer everything else to the "super". */
+ return NULL;
+}
+
static int
cuda_match(device_t parent, struct cfdata *cf, void *aux)
{
@@ -172,9 +247,6 @@ cuda_attach(device_t parent, device_t se
struct cuda_softc *sc = device_private(self);
struct i2cbus_attach_args iba;
static struct cuda_attach_args caa;
- prop_dictionary_t dict = device_properties(self);
- prop_dictionary_t dev;
- prop_array_t cfg;
int irq = ca->ca_intr[0];
int node, i, child;
char name[32];
@@ -252,37 +324,41 @@ cuda_attach(device_t parent, device_t se
#if notyet
config_found(self, &caa, cuda_print, CFARG_EOL);
#endif
- cfg = prop_array_create();
- prop_dictionary_set(dict, "i2c-child-devices", cfg);
- prop_object_release(cfg);
-
/* we don't have OF nodes for i2c devices so we have to make our own */
-
node = OF_finddevice("/valkyrie");
if (node != -1) {
- dev = prop_dictionary_create();
- prop_dictionary_set_string(dev, "name", "videopll");
- prop_dictionary_set_uint32(dev, "addr", 0x50);
- prop_array_add(cfg, dev);
- prop_object_release(dev);
+ /* XXX a real "compatible" string would be nice... */
+ cuda_add_i2c_device(sc, "videopll",
+ "aapl,valkyrie-videopll", 0x50);
}
node = OF_finddevice("/perch");
if (node != -1) {
- dev = prop_dictionary_create();
- prop_dictionary_set_string(dev, "name", "sgsmix");
- prop_dictionary_set_uint32(dev, "addr", 0x8a);
- prop_array_add(cfg, dev);
- prop_object_release(dev);
+ cuda_add_i2c_device(sc, "sgsmix", "st,tda7433", 0x8a);
}
+ /*
+ * Normally the i2c bus instance would automatically inherit
+ * our devhandle, but we provide our own i2c device enumeration
+ * method, so we need to supply the bus instance with our own
+ * device handle implementation, using the one we got from
+ * OpenFirmware as the "super".
+ */
+ devhandle_t devhandle = devhandle_from_of(sc->sc_node);
+ devhandle_impl_inherit(&sc->sc_devhandle_impl, devhandle.impl);
+ sc->sc_devhandle_impl.lookup_device_call =
+ cuda_devhandle_lookup_device_call;
+ devhandle.impl = &sc->sc_devhandle_impl;
+
+ iic_tag_init(&sc->sc_i2c);
+ sc->sc_i2c.ic_cookie = sc;
+ sc->sc_i2c.ic_exec = cuda_i2c_exec;
+
memset(&iba, 0, sizeof(iba));
iba.iba_tag = &sc->sc_i2c;
- iic_tag_init(&sc->sc_i2c);
- sc->sc_i2c.ic_cookie = sc;
- sc->sc_i2c.ic_exec = cuda_i2c_exec;
config_found(self, &iba, iicbus_print,
CFARG_IATTR, "i2cbus",
+ CFARG_DEVHANDLE, devhandle,
CFARG_EOL);
if (cuda0 == NULL)
diff -r 8ad82d1b1fe6 -r 3e42cb34a41e sys/arch/macppc/dev/videopll.c
--- a/sys/arch/macppc/dev/videopll.c Sat May 08 11:34:38 2021 +0000
+++ b/sys/arch/macppc/dev/videopll.c Sat May 08 11:40:02 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: videopll.c,v 1.3 2018/06/16 21:22:13 thorpej Exp $ */
+/* $NetBSD: videopll.c,v 1.3.18.1 2021/05/08 11:40:02 thorpej Exp $ */
/*
* Copyright (c) 2012 Michael Lorenz
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: videopll.c,v 1.3 2018/06/16 21:22:13 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: videopll.c,v 1.3.18.1 2021/05/08 11:40:02 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -66,13 +66,19 @@ CFATTACH_DECL_NEW(videopll, sizeof(struc
static void *glob = NULL;
+static const struct device_compatible_entry compat_data[] = {
+ /* XXX a real "compatible" string would be nice... */
+ { .compat = "aapl,valkyrie-videopll" },
+ DEVICE_COMPAT_EOL
+};
+
static int
videopll_match(device_t parent, cfdata_t cfdata, void *aux)
{
struct i2c_attach_args *ia = aux;
int match_result;
- if (iic_use_direct_match(ia, cfdata, NULL, &match_result))
+ if (iic_use_direct_match(ia, cfdata, compat_data, &match_result))
return match_result;
/* This driver is direct-config only. */
Home |
Main Index |
Thread Index |
Old Index