1*674f03e5Sderaadt /* $OpenBSD: acpisurface.c,v 1.3 2024/08/15 17:30:40 deraadt Exp $ */ 2144c780aSmlarkin /* 3144c780aSmlarkin * Copyright (c) 2018 Mike Larkin <mlarkin@openbsd.org> 4144c780aSmlarkin * 5144c780aSmlarkin * Permission to use, copy, modify, and distribute this software for any 6144c780aSmlarkin * purpose with or without fee is hereby granted, provided that the above 7144c780aSmlarkin * copyright notice and this permission notice appear in all copies. 8144c780aSmlarkin * 9144c780aSmlarkin * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10144c780aSmlarkin * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11144c780aSmlarkin * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12144c780aSmlarkin * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13144c780aSmlarkin * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14144c780aSmlarkin * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15144c780aSmlarkin * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16144c780aSmlarkin */ 17144c780aSmlarkin 18144c780aSmlarkin #include <sys/param.h> 19144c780aSmlarkin #include <sys/systm.h> 20144c780aSmlarkin 21144c780aSmlarkin #include <dev/acpi/acpireg.h> 22144c780aSmlarkin #include <dev/acpi/acpivar.h> 23144c780aSmlarkin #include <dev/acpi/acpidev.h> 24144c780aSmlarkin #include <dev/acpi/amltypes.h> 25144c780aSmlarkin #include <dev/acpi/dsdt.h> 26144c780aSmlarkin 27144c780aSmlarkin #include "audio.h" 28144c780aSmlarkin #include "wskbd.h" 29144c780aSmlarkin 30144c780aSmlarkin /* #define ACPISURFACE_DEBUG */ 31144c780aSmlarkin 32144c780aSmlarkin #ifdef ACPISURFACE_DEBUG 33144c780aSmlarkin #define DPRINTF(x...) do { printf(x); } while(0) 34144c780aSmlarkin #else 35144c780aSmlarkin #define DPRINTF(x...) 36144c780aSmlarkin #endif /* ACPISURFACE_DEBUG */ 37144c780aSmlarkin 38144c780aSmlarkin #define SURFACE_ACCESSORY_REMOVED 0xC8 39144c780aSmlarkin #define SURFACE_WINDOWS_KEY_PRESSED 0xC4 40144c780aSmlarkin #define SURFACE_WINDOWS_KEY_RELEASED 0xC5 41144c780aSmlarkin #define SURFACE_VOLUME_UP_PRESSED 0xC0 42144c780aSmlarkin #define SURFACE_VOLUME_UP_RELEASED 0xC1 43144c780aSmlarkin #define SURFACE_VOLUME_DOWN_PRESSED 0xC2 44144c780aSmlarkin #define SURFACE_VOLUME_DOWN_RELEASED 0xC3 45144c780aSmlarkin #define SURFACE_POWER_BUTTON_PRESSED 0xC6 46144c780aSmlarkin #define SURFACE_POWER_BUTTON_RELEASED 0xC7 47144c780aSmlarkin 48144c780aSmlarkin struct acpisurface_softc { 49144c780aSmlarkin struct device sc_dev; 50144c780aSmlarkin 51144c780aSmlarkin struct acpiec_softc *sc_ec; 52144c780aSmlarkin struct acpi_softc *sc_acpi; 53144c780aSmlarkin struct aml_node *sc_devnode; 54144c780aSmlarkin }; 55144c780aSmlarkin 56144c780aSmlarkin int surface_match(struct device *, void *, void *); 57144c780aSmlarkin void surface_attach(struct device *, struct device *, void *); 58144c780aSmlarkin int surface_hotkey(struct aml_node *, int, void *); 59144c780aSmlarkin 60144c780aSmlarkin #if NAUDIO > 0 && NWSKBD > 0 61144c780aSmlarkin extern int wskbd_set_mixervolume(long, long); 62144c780aSmlarkin #endif 63144c780aSmlarkin 64471aeecfSnaddy const struct cfattach acpisurface_ca = { 65144c780aSmlarkin sizeof(struct acpisurface_softc), surface_match, surface_attach, 66144c780aSmlarkin NULL, NULL 67144c780aSmlarkin }; 68144c780aSmlarkin 69144c780aSmlarkin struct cfdriver acpisurface_cd = { 70144c780aSmlarkin NULL, "acpisurface", DV_DULL 71144c780aSmlarkin }; 72144c780aSmlarkin 73144c780aSmlarkin const char *acpisurface_hids[] = { 74144c780aSmlarkin "MSHW0040", 75144c780aSmlarkin NULL 76144c780aSmlarkin }; 77144c780aSmlarkin 78144c780aSmlarkin int 79144c780aSmlarkin surface_match(struct device *parent, void *match, void *aux) 80144c780aSmlarkin { 81144c780aSmlarkin struct acpi_attach_args *aa = aux; 82144c780aSmlarkin struct cfdata *cf = match; 83144c780aSmlarkin 84144c780aSmlarkin if (!acpi_matchhids(aa, acpisurface_hids, cf->cf_driver->cd_name)) 85144c780aSmlarkin return (0); 86144c780aSmlarkin 87144c780aSmlarkin return (1); 88144c780aSmlarkin } 89144c780aSmlarkin 90144c780aSmlarkin void 91144c780aSmlarkin surface_attach(struct device *parent, struct device *self, void *aux) 92144c780aSmlarkin { 93144c780aSmlarkin struct acpisurface_softc *sc = (struct acpisurface_softc *)self; 94144c780aSmlarkin struct acpi_attach_args *aa = aux; 95144c780aSmlarkin 96144c780aSmlarkin sc->sc_acpi = (struct acpi_softc *)parent; 97144c780aSmlarkin sc->sc_devnode = aa->aaa_node; 98144c780aSmlarkin 99144c780aSmlarkin printf("\n"); 100144c780aSmlarkin 101144c780aSmlarkin /* Run surface_hotkey on button presses */ 102144c780aSmlarkin aml_register_notify(sc->sc_devnode, aa->aaa_dev, 103144c780aSmlarkin surface_hotkey, sc, ACPIDEV_NOPOLL); 104144c780aSmlarkin } 105144c780aSmlarkin 106144c780aSmlarkin int 107144c780aSmlarkin surface_hotkey(struct aml_node *node, int notify_type, void *arg) 108144c780aSmlarkin { 109144c780aSmlarkin struct acpisurface_softc *sc = arg; 110144c780aSmlarkin 111144c780aSmlarkin switch (notify_type) { 112144c780aSmlarkin case SURFACE_ACCESSORY_REMOVED: 113144c780aSmlarkin DPRINTF("%s: accessory removed\n", __func__); 114144c780aSmlarkin break; 115144c780aSmlarkin case SURFACE_VOLUME_UP_PRESSED: 116144c780aSmlarkin DPRINTF("%s: volume up pressed\n", __func__); 117144c780aSmlarkin #if NAUDIO > 0 && NWSKBD > 0 118144c780aSmlarkin wskbd_set_mixervolume(1, 10); 119144c780aSmlarkin #endif 120144c780aSmlarkin break; 121144c780aSmlarkin case SURFACE_VOLUME_UP_RELEASED: 122144c780aSmlarkin DPRINTF("%s: volume up released\n", __func__); 123144c780aSmlarkin break; 124144c780aSmlarkin case SURFACE_VOLUME_DOWN_PRESSED: 125144c780aSmlarkin DPRINTF("%s: volume down pressed\n", __func__); 126144c780aSmlarkin #if NAUDIO > 0 && NWSKBD > 0 127144c780aSmlarkin wskbd_set_mixervolume(-1, 10); 128144c780aSmlarkin #endif 129144c780aSmlarkin break; 130144c780aSmlarkin case SURFACE_VOLUME_DOWN_RELEASED: 131144c780aSmlarkin DPRINTF("%s: volume down released\n", __func__); 132144c780aSmlarkin break; 133144c780aSmlarkin case SURFACE_POWER_BUTTON_PRESSED: 134144c780aSmlarkin DPRINTF("%s: power button pressed\n", __func__); 135144c780aSmlarkin break; 136144c780aSmlarkin case SURFACE_POWER_BUTTON_RELEASED: 137144c780aSmlarkin DPRINTF("%s: power button released\n", __func__); 138144c780aSmlarkin acpi_addtask(sc->sc_acpi, acpi_powerdown_task, 139144c780aSmlarkin sc->sc_acpi, 0); 140144c780aSmlarkin break; 141144c780aSmlarkin case SURFACE_WINDOWS_KEY_PRESSED: 142144c780aSmlarkin DPRINTF("%s: windows key pressed\n", __func__); 143144c780aSmlarkin break; 144144c780aSmlarkin case SURFACE_WINDOWS_KEY_RELEASED: 145144c780aSmlarkin DPRINTF("%s: windows key released\n", __func__); 146144c780aSmlarkin break; 147144c780aSmlarkin default: 148144c780aSmlarkin DPRINTF("%s: unknown notification 0x%x\n", __func__, 149144c780aSmlarkin notify_type); 150144c780aSmlarkin } 151144c780aSmlarkin 152144c780aSmlarkin return (0); 153144c780aSmlarkin } 154