1 /* $OpenBSD: simpleamp.c,v 1.1 2020/06/10 23:59:07 patrick Exp $ */ 2 /* 3 * Copyright (c) 2020 Patrick Wildt <patrick@blueri.se> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/systm.h> 20 #include <sys/device.h> 21 #include <sys/malloc.h> 22 23 #include <machine/fdt.h> 24 25 #include <dev/ofw/openfirm.h> 26 #include <dev/ofw/ofw_gpio.h> 27 #include <dev/ofw/ofw_misc.h> 28 #include <dev/ofw/ofw_regulator.h> 29 30 #include <sys/audioio.h> 31 #include <dev/audio_if.h> 32 #include <dev/midi_if.h> 33 34 int simpleamp_match(struct device *, void *, void *); 35 void simpleamp_attach(struct device *, struct device *, void *); 36 37 int simpleamp_open(void *, int); 38 void simpleamp_close(void *); 39 40 struct simpleamp_softc { 41 struct device sc_dev; 42 struct dai_device sc_dai; 43 44 uint32_t *sc_gpio; 45 size_t sc_gpiolen; 46 uint32_t sc_vcc; 47 }; 48 49 struct audio_hw_if simpleamp_hw_if = { 50 .open = simpleamp_open, 51 .close = simpleamp_close, 52 }; 53 54 struct cfattach simpleamp_ca = { 55 sizeof(struct simpleamp_softc), simpleamp_match, simpleamp_attach 56 }; 57 58 struct cfdriver simpleamp_cd = { 59 NULL, "simpleamp", DV_DULL 60 }; 61 62 int 63 simpleamp_match(struct device *parent, void *match, void *aux) 64 { 65 struct fdt_attach_args *faa = aux; 66 67 return OF_is_compatible(faa->fa_node, "simple-audio-amplifier"); 68 } 69 70 void 71 simpleamp_attach(struct device *parent, struct device *self, void *aux) 72 { 73 struct simpleamp_softc *sc = (struct simpleamp_softc *)self; 74 struct fdt_attach_args *faa = aux; 75 76 sc->sc_gpiolen = OF_getproplen(faa->fa_node, "enable-gpios"); 77 if (sc->sc_gpiolen > 0) { 78 sc->sc_gpio = malloc(sc->sc_gpiolen, M_DEVBUF, M_WAITOK); 79 OF_getpropintarray(faa->fa_node, "enable-gpios", 80 sc->sc_gpio, sc->sc_gpiolen); 81 gpio_controller_config_pin(sc->sc_gpio, GPIO_CONFIG_OUTPUT); 82 } 83 sc->sc_vcc = OF_getpropint(faa->fa_node, "VCC-supply", 0); 84 85 printf("\n"); 86 87 sc->sc_dai.dd_node = faa->fa_node; 88 sc->sc_dai.dd_cookie = sc; 89 sc->sc_dai.dd_hw_if = &simpleamp_hw_if; 90 dai_register(&sc->sc_dai); 91 } 92 93 int 94 simpleamp_open(void *cookie, int flags) 95 { 96 struct simpleamp_softc *sc = cookie; 97 98 if (sc->sc_gpio) 99 gpio_controller_set_pin(sc->sc_gpio, 1); 100 if (sc->sc_vcc) 101 regulator_enable(sc->sc_vcc); 102 103 return 0; 104 } 105 106 void 107 simpleamp_close(void *cookie) 108 { 109 struct simpleamp_softc *sc = cookie; 110 111 if (sc->sc_gpio) 112 gpio_controller_set_pin(sc->sc_gpio, 0); 113 if (sc->sc_vcc) 114 regulator_disable(sc->sc_vcc); 115 } 116