11.2Sskrll/* $NetBSD: usbnode.c,v 1.3 2026/01/17 05:45:17 skrll Exp $ */ 21.1Sskrll 31.1Sskrll/*- 41.1Sskrll * Copyright (c) 2025 The NetBSD Foundation, Inc. 51.1Sskrll * All rights reserved. 61.1Sskrll * 71.1Sskrll * This code is derived from software contributed to The NetBSD Foundation 81.1Sskrll * by Nick Hudson 91.1Sskrll * 101.1Sskrll * Redistribution and use in source and binary forms, with or without 111.1Sskrll * modification, are permitted provided that the following conditions 121.1Sskrll * are met: 131.1Sskrll * 1. Redistributions of source code must retain the above copyright 141.1Sskrll * notice, this list of conditions and the following disclaimer. 151.1Sskrll * 2. Redistributions in binary form must reproduce the above copyright 161.1Sskrll * notice, this list of conditions and the following disclaimer in the 171.1Sskrll * documentation and/or other materials provided with the distribution. 181.1Sskrll * 191.1Sskrll * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 201.1Sskrll * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 211.1Sskrll * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 221.1Sskrll * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 231.1Sskrll * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 241.1Sskrll * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 251.1Sskrll * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 261.1Sskrll * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 271.1Sskrll * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 281.1Sskrll * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 291.1Sskrll * POSSIBILITY OF SUCH DAMAGE. 301.1Sskrll */ 311.1Sskrll 321.1Sskrll#include <sys/cdefs.h> 331.2Sskrll__KERNEL_RCSID(0, "$NetBSD: usbnode.c,v 1.3 2026/01/17 05:45:17 skrll Exp $"); 341.1Sskrll 351.1Sskrll#include <sys/param.h> 361.1Sskrll#include <sys/device.h> 371.1Sskrll 381.1Sskrll#include <dev/fdt/fdtvar.h> 391.1Sskrll 401.1Sskrllstruct usbnode_softc { 411.1Sskrll device_t sc_dev; 421.1Sskrll int sc_phandle; 431.1Sskrll 441.1Sskrll struct fdtbus_gpio_pin * sc_pin_reset; 451.1Sskrll u_int sc_resetdelay; 461.1Sskrll}; 471.1Sskrll 481.1Sskrllstruct usbnode_data { 491.1Sskrll const char * und_desc; 501.1Sskrll u_int und_resetdelay; 511.1Sskrll}; 521.1Sskrll 531.1Sskrll/* Genesys Logic GL852G usb hub */ 541.1Sskrllstatic struct usbnode_data genesys_gl852g_data = { 551.1Sskrll .und_desc = "Genesys Logic GL852G usb hub", 561.1Sskrll .und_resetdelay = 50, 571.1Sskrll}; 581.1Sskrll 591.1Sskrllstatic const struct device_compatible_entry compat_data[] = { 601.1Sskrll { .compat = "usb5e3,610", .data = &genesys_gl852g_data }, 611.1Sskrll DEVICE_COMPAT_EOL 621.1Sskrll}; 631.1Sskrll 641.1Sskrllstatic void 651.1Sskrllusbnode_enable(struct usbnode_softc *sc,bool enable) 661.1Sskrll{ 671.1Sskrll 681.1Sskrll if (enable) { 691.1Sskrll fdtbus_gpio_write(sc->sc_pin_reset, 1); 701.1Sskrll delay(sc->sc_resetdelay); 711.1Sskrll } 721.1Sskrll 731.1Sskrll fdtbus_gpio_write(sc->sc_pin_reset, enable ? 0 : 1); 741.1Sskrll} 751.1Sskrll 761.1Sskrllstatic int 771.1Sskrllusbnode_match(device_t parent, cfdata_t cf, void *aux) 781.1Sskrll{ 791.1Sskrll struct fdt_attach_args * const faa = aux; 801.1Sskrll 811.1Sskrll return of_compatible_match(faa->faa_phandle, compat_data); 821.1Sskrll} 831.1Sskrll 841.1Sskrllstatic int 851.1Sskrllusbnode_detach(device_t self, int flags) 861.1Sskrll{ 871.1Sskrll struct usbnode_softc * const sc = device_private(self); 881.1Sskrll 891.1Sskrll usbnode_enable(sc, false); 901.1Sskrll 911.1Sskrll return 0; 921.1Sskrll} 931.1Sskrll 941.1Sskrllstatic void 951.1Sskrllusbnode_attach(device_t parent, device_t self, void *aux) 961.1Sskrll{ 971.1Sskrll struct usbnode_softc * const sc = device_private(self); 981.1Sskrll struct fdt_attach_args * const faa = aux; 991.1Sskrll const int phandle = faa->faa_phandle; 1001.1Sskrll 1011.1Sskrll sc->sc_dev = self; 1021.1Sskrll 1031.1Sskrll const struct device_compatible_entry * const dce = 1041.1Sskrll of_compatible_lookup(phandle, compat_data); 1051.1Sskrll 1061.1Sskrll const struct usbnode_data *und = dce->data; 1071.1Sskrll 1081.1Sskrll /* reset gpio is ... */ 1091.1Sskrll sc->sc_pin_reset = 1101.1Sskrll fdtbus_gpio_acquire(phandle, "reset-gpio", GPIO_PIN_OUTPUT); 1111.1Sskrll if (sc->sc_pin_reset == NULL) { 1121.1Sskrll aprint_error(": couldn't acquire reset gpio\n"); 1131.1Sskrll } 1141.1Sskrll 1151.1Sskrll usbnode_enable(sc, true); 1161.1Sskrll 1171.1Sskrll aprint_naive("\n"); 1181.1Sskrll aprint_normal(": USB node '%s'\n", und->und_desc); 1191.1Sskrll} 1201.1Sskrll 1211.1SskrllCFATTACH_DECL_NEW(usbnode, sizeof(struct usbnode_softc), 1221.1Sskrll usbnode_match, usbnode_attach, usbnode_detach, NULL); 123