Module Name: src Committed By: thorpej Date: Sat May 8 11:40:02 UTC 2021
Modified Files: src/sys/arch/macppc/dev [thorpej-i2c-spi-conf]: cuda.c videopll.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.28 -r1.28.2.1 src/sys/arch/macppc/dev/cuda.c cvs rdiff -u -r1.3 -r1.3.18.1 src/sys/arch/macppc/dev/videopll.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/arch/macppc/dev/cuda.c diff -u src/sys/arch/macppc/dev/cuda.c:1.28 src/sys/arch/macppc/dev/cuda.c:1.28.2.1 --- src/sys/arch/macppc/dev/cuda.c:1.28 Sat Apr 24 23:36:41 2021 +++ src/sys/arch/macppc/dev/cuda.c Sat May 8 11:40:02 2021 @@ -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); } - memset(&iba, 0, sizeof(iba)); - iba.iba_tag = &sc->sc_i2c; + /* + * 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; config_found(self, &iba, iicbus_print, CFARG_IATTR, "i2cbus", + CFARG_DEVHANDLE, devhandle, CFARG_EOL); if (cuda0 == NULL) Index: src/sys/arch/macppc/dev/videopll.c diff -u src/sys/arch/macppc/dev/videopll.c:1.3 src/sys/arch/macppc/dev/videopll.c:1.3.18.1 --- src/sys/arch/macppc/dev/videopll.c:1.3 Sat Jun 16 21:22:13 2018 +++ src/sys/arch/macppc/dev/videopll.c Sat May 8 11:40:02 2021 @@ -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. */