/*-1* SPDX-License-Identifier: BSD-3-Clause2*3* Copyright (c) 2011, Justin Hibbits.4* Copyright (c) 2002, Miodrag Vallat.5* Copyright (C) 1999 Tsubai Masanari. All rights reserved.6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions9* are met:10* 1. Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15* 3. The name of the author may not be used to endorse or promote products16* derived from this software without specific prior written permission.17*18* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR19* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES20* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.21* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,22* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT23* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,24* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY25* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT26* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE27* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.28*29* OpenBSD: abtn.c,v 1.12 2009/01/10 18:00:59 robert Exp30* NetBSD: abtn.c,v 1.1 1999/07/12 17:48:26 tsubai Exp31*/3233#include <sys/param.h>34#include <sys/systm.h>35#include <sys/module.h>36#include <sys/kernel.h>37#include <sys/bus.h>3839#include <machine/bus.h>4041#include <dev/ofw/openfirm.h>42#include <machine/ofw_machdep.h>4344#include <dev/adb/adb.h>4546#define ABTN_HANDLER_ID 314748struct abtn_softc {49device_t sc_dev;5051int handler_id;52};5354static int abtn_probe(device_t dev);55static int abtn_attach(device_t dev);56static u_int abtn_receive_packet(device_t dev, u_char status,57u_char command, u_char reg, int len, u_char *data);5859static device_method_t abtn_methods[] = {60/* Device interface */61DEVMETHOD(device_probe, abtn_probe),62DEVMETHOD(device_attach, abtn_attach),63DEVMETHOD(device_shutdown, bus_generic_shutdown),64DEVMETHOD(device_suspend, bus_generic_suspend),65DEVMETHOD(device_resume, bus_generic_resume),6667/* ADB interface */68DEVMETHOD(adb_receive_packet, abtn_receive_packet),69{ 0, 0 }70};7172static driver_t abtn_driver = {73"abtn",74abtn_methods,75sizeof(struct abtn_softc),76};7778DRIVER_MODULE(abtn, adb, abtn_driver, 0, 0);7980static int81abtn_probe(device_t dev)82{83uint8_t type;8485type = adb_get_device_type(dev);8687if (type != ADB_DEVICE_MISC)88return (ENXIO);8990device_set_desc(dev, "ADB Brightness/Volume/Eject Buttons");91return (0);92}9394static int95abtn_attach(device_t dev)96{97struct abtn_softc *sc;9899sc = device_get_softc(dev);100sc->sc_dev = dev;101102sc->handler_id = adb_get_device_handler(dev);103104return 0;105}106107static u_int108abtn_receive_packet(device_t dev, u_char status,109u_char command, u_char reg, int len, u_char *data)110{111u_int cmd;112113cmd = data[0];114115switch (cmd) {116case 0x0a: /* decrease brightness */117devctl_notify("PMU", "keys", "brightness",118"notify=down");119break;120121case 0x09: /* increase brightness */122devctl_notify("PMU", "keys", "brightness", "notify=up");123break;124125case 0x08: /* mute */126case 0x01: /* mute, AV hardware */127devctl_notify("PMU", "keys", "mute", NULL);128break;129case 0x07: /* decrease volume */130case 0x02: /* decrease volume, AV hardware */131devctl_notify("PMU", "keys", "volume", "notify=down");132break;133case 0x06: /* increase volume */134case 0x03: /* increase volume, AV hardware */135devctl_notify("PMU", "keys", "volume", "notify=up");136break;137case 0x0c: /* mirror display key */138/* Need callback to do something with this */139break;140case 0x0b: /* eject tray */141devctl_notify("PMU", "keys", "eject", NULL);142break;143case 0x7f: /* numlock */144/* Need callback to do something with this */145break;146147default:148#ifdef DEBUG149if ((cmd & ~0x7f) == 0)150device_printf(dev, "unknown ADB button 0x%x\n", cmd);151#endif152break;153}154return 0;155}156157158