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