1 /* $NetBSD: simple_amplifier.c,v 1.1 2020/01/02 00:57:09 jmcneill Exp $ */ 2 3 /*- 4 * Copyright (c) 2020 Jared McNeill <jmcneill@invisible.ca> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: simple_amplifier.c,v 1.1 2020/01/02 00:57:09 jmcneill Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/bus.h> 34 #include <sys/device.h> 35 #include <sys/systm.h> 36 #include <sys/sysctl.h> 37 #include <sys/kmem.h> 38 39 #include <dev/audio/audio_dai.h> 40 41 #include <dev/fdt/fdtvar.h> 42 43 struct simple_amplifier_softc { 44 device_t sc_dev; 45 struct audio_dai_device sc_dai; 46 struct fdtbus_gpio_pin *sc_pin; 47 struct fdtbus_regulator *sc_vcc; 48 }; 49 50 static int simple_amplifier_match(device_t, cfdata_t, void *); 51 static void simple_amplifier_attach(device_t, device_t, void *); 52 53 static const char *compatible[] = { 54 "simple-audio-amplifier", 55 NULL 56 }; 57 58 CFATTACH_DECL_NEW(simpleamp, sizeof(struct simple_amplifier_softc), 59 simple_amplifier_match, simple_amplifier_attach, NULL, NULL); 60 61 static int 62 simple_amplifier_open(void *priv, int flags) 63 { 64 struct simple_amplifier_softc * const sc = priv; 65 int error; 66 67 if (sc->sc_pin != NULL) 68 fdtbus_gpio_write(sc->sc_pin, 1); 69 70 if (sc->sc_vcc != NULL) { 71 error = fdtbus_regulator_enable(sc->sc_vcc); 72 if (error != 0) 73 aprint_error_dev(sc->sc_dev, "couldn't enable power supply\n"); 74 } 75 76 return 0; 77 } 78 79 static void 80 simple_amplifier_close(void *priv) 81 { 82 struct simple_amplifier_softc * const sc = priv; 83 84 if (sc->sc_pin != NULL) 85 fdtbus_gpio_write(sc->sc_pin, 0); 86 87 if (sc->sc_vcc != NULL) 88 (void)fdtbus_regulator_disable(sc->sc_vcc); 89 } 90 91 static const struct audio_hw_if simple_amplifier_hw_if = { 92 .open = simple_amplifier_open, 93 .close = simple_amplifier_close, 94 }; 95 96 static audio_dai_tag_t 97 simple_amplifier_dai_get_tag(device_t dev, const void *data, size_t len) 98 { 99 struct simple_amplifier_softc * const sc = device_private(dev); 100 101 if (len != 4) 102 return NULL; 103 104 return &sc->sc_dai; 105 } 106 107 static struct fdtbus_dai_controller_func simple_amplifier_dai_funcs = { 108 .get_tag = simple_amplifier_dai_get_tag 109 }; 110 111 static int 112 simple_amplifier_match(device_t parent, cfdata_t cf, void *aux) 113 { 114 struct fdt_attach_args * const faa = aux; 115 116 return of_match_compatible(faa->faa_phandle, compatible); 117 } 118 119 static void 120 simple_amplifier_attach(device_t parent, device_t self, void *aux) 121 { 122 struct simple_amplifier_softc * const sc = device_private(self); 123 struct fdt_attach_args * const faa = aux; 124 const int phandle = faa->faa_phandle; 125 126 sc->sc_dev = self; 127 sc->sc_pin = fdtbus_gpio_acquire(phandle, "enable-gpios", GPIO_PIN_OUTPUT); 128 sc->sc_vcc = fdtbus_regulator_acquire(phandle, "VCC-supply"); 129 130 aprint_naive("\n"); 131 aprint_normal(": Simple Amplifier\n"); 132 133 sc->sc_dai.dai_hw_if = &simple_amplifier_hw_if; 134 sc->sc_dai.dai_dev = self; 135 sc->sc_dai.dai_priv = sc; 136 fdtbus_register_dai_controller(self, phandle, &simple_amplifier_dai_funcs); 137 } 138