1*89ed722cSmpi /* $OpenBSD: abtn.c,v 1.18 2022/03/13 12:33:01 mpi Exp $ */
2d9a5f17fSdrahn /* $NetBSD: abtn.c,v 1.1 1999/07/12 17:48:26 tsubai Exp $ */
3d9a5f17fSdrahn
4d9a5f17fSdrahn /*-
56544bd67Smiod * Copyright (c) 2002, Miodrag Vallat.
6d9a5f17fSdrahn * Copyright (C) 1999 Tsubai Masanari. All rights reserved.
7d9a5f17fSdrahn *
8d9a5f17fSdrahn * Redistribution and use in source and binary forms, with or without
9d9a5f17fSdrahn * modification, are permitted provided that the following conditions
10d9a5f17fSdrahn * are met:
11d9a5f17fSdrahn * 1. Redistributions of source code must retain the above copyright
12d9a5f17fSdrahn * notice, this list of conditions and the following disclaimer.
13d9a5f17fSdrahn * 2. Redistributions in binary form must reproduce the above copyright
14d9a5f17fSdrahn * notice, this list of conditions and the following disclaimer in the
15d9a5f17fSdrahn * documentation and/or other materials provided with the distribution.
16d9a5f17fSdrahn * 3. The name of the author may not be used to endorse or promote products
17d9a5f17fSdrahn * derived from this software without specific prior written permission.
18d9a5f17fSdrahn *
19d9a5f17fSdrahn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20d9a5f17fSdrahn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21d9a5f17fSdrahn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22d9a5f17fSdrahn * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23d9a5f17fSdrahn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24d9a5f17fSdrahn * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25d9a5f17fSdrahn * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26d9a5f17fSdrahn * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27d9a5f17fSdrahn * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28d9a5f17fSdrahn * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29d9a5f17fSdrahn */
30d9a5f17fSdrahn
31d9a5f17fSdrahn #include <sys/param.h>
32d9a5f17fSdrahn #include <sys/device.h>
33d9a5f17fSdrahn #include <sys/systm.h>
349bae9981Sblambert #include <sys/task.h>
35d9a5f17fSdrahn
366544bd67Smiod #include <machine/bus.h>
37d9a5f17fSdrahn
386544bd67Smiod #include <dev/ofw/openfirm.h>
396544bd67Smiod #include <macppc/macppc/ofw_machdep.h>
406544bd67Smiod
41305d9e87Smiod #include <dev/adb/adb.h>
426544bd67Smiod
433a81050dSrobert #include "audio.h"
443a81050dSrobert #include "cd.h"
453a81050dSrobert #include "wskbd.h"
463a81050dSrobert
47d9a5f17fSdrahn #define ABTN_HANDLER_ID 31
48d9a5f17fSdrahn
49d9a5f17fSdrahn struct abtn_softc {
50d9a5f17fSdrahn struct device sc_dev;
51d9a5f17fSdrahn
52d9a5f17fSdrahn int origaddr; /* ADB device type */
53d9a5f17fSdrahn int adbaddr; /* current ADB address */
54d9a5f17fSdrahn int handler_id;
55d9a5f17fSdrahn };
56d9a5f17fSdrahn
576544bd67Smiod int abtn_match(struct device *, void *, void *);
586544bd67Smiod void abtn_attach(struct device *, struct device *, void *);
596544bd67Smiod void abtn_adbcomplete(caddr_t, caddr_t, int);
60d9a5f17fSdrahn
613a81050dSrobert #if NWSKBD > 0
623a81050dSrobert extern int cd_eject(void);
633a81050dSrobert #if NAUDIO > 0
64012023bfSmpi extern int wskbd_set_mixervolume(long, long);
653a81050dSrobert #endif
663a81050dSrobert #endif
673a81050dSrobert
68*89ed722cSmpi const struct cfattach abtn_ca = {
69d9a5f17fSdrahn sizeof(struct abtn_softc), abtn_match, abtn_attach
70d9a5f17fSdrahn };
71d9a5f17fSdrahn struct cfdriver abtn_cd = {
72d9a5f17fSdrahn NULL, "abtn", DV_DULL
73d9a5f17fSdrahn };
74d9a5f17fSdrahn
759bae9981Sblambert struct task eject_task =
76d99f18c8Sdlg TASK_INITIALIZER((void (*)(void *))cd_eject, NULL);
779bae9981Sblambert
78d9a5f17fSdrahn int
abtn_match(struct device * parent,void * cf,void * aux)79093da1aaSdrahn abtn_match(struct device *parent, void *cf, void *aux)
80d9a5f17fSdrahn {
81d9a5f17fSdrahn struct adb_attach_args *aa = aux;
82d9a5f17fSdrahn
834425d974Smiod if (strcmp(aa->name, adb_device_name) != 0)
844425d974Smiod return (0);
854425d974Smiod
86d9a5f17fSdrahn if (aa->origaddr == ADBADDR_MISC &&
87d9a5f17fSdrahn aa->handler_id == ABTN_HANDLER_ID)
88d9a5f17fSdrahn return 1;
89d9a5f17fSdrahn
90d9a5f17fSdrahn return 0;
91d9a5f17fSdrahn }
92d9a5f17fSdrahn
93d9a5f17fSdrahn void
abtn_attach(struct device * parent,struct device * self,void * aux)94093da1aaSdrahn abtn_attach(struct device *parent, struct device *self, void *aux)
95d9a5f17fSdrahn {
96d9a5f17fSdrahn struct abtn_softc *sc = (struct abtn_softc *)self;
97d9a5f17fSdrahn struct adb_attach_args *aa = aux;
98d9a5f17fSdrahn ADBSetInfoBlock adbinfo;
99d9a5f17fSdrahn
100fef6d604Smiod printf(": brightness/volume/eject buttons\n");
101d9a5f17fSdrahn
102d9a5f17fSdrahn sc->origaddr = aa->origaddr;
103d9a5f17fSdrahn sc->adbaddr = aa->adbaddr;
104d9a5f17fSdrahn sc->handler_id = aa->handler_id;
105d9a5f17fSdrahn
106d9a5f17fSdrahn adbinfo.siServiceRtPtr = (Ptr)abtn_adbcomplete;
107d9a5f17fSdrahn adbinfo.siDataAreaAddr = (caddr_t)sc;
108d9a5f17fSdrahn
109305d9e87Smiod set_adb_info(&adbinfo, sc->adbaddr);
110d9a5f17fSdrahn }
111d9a5f17fSdrahn
112d9a5f17fSdrahn void
abtn_adbcomplete(caddr_t buffer,caddr_t data,int adb_command)113093da1aaSdrahn abtn_adbcomplete(caddr_t buffer, caddr_t data, int adb_command)
114d9a5f17fSdrahn {
1156544bd67Smiod u_int cmd, brightness;
116d9a5f17fSdrahn
117d9a5f17fSdrahn cmd = buffer[1];
118d9a5f17fSdrahn
119d9a5f17fSdrahn switch (cmd) {
1206544bd67Smiod case 0x0a: /* decrease brightness */
1216544bd67Smiod brightness = cons_brightness;
1226544bd67Smiod if (brightness == MAX_BRIGHTNESS)
1236544bd67Smiod brightness++; /* get round values */
1246544bd67Smiod brightness -= STEP_BRIGHTNESS;
1256544bd67Smiod of_setbrightness(brightness);
126d9a5f17fSdrahn break;
127d9a5f17fSdrahn
1286544bd67Smiod case 0x09: /* increase brightness */
1296544bd67Smiod brightness = cons_brightness + STEP_BRIGHTNESS;
1306544bd67Smiod of_setbrightness(brightness);
131d9a5f17fSdrahn break;
1326544bd67Smiod
1333a81050dSrobert #if NAUDIO > 0 && NWSKBD > 0
1346544bd67Smiod case 0x08: /* mute */
1356544bd67Smiod case 0x01: /* mute, AV hardware */
136012023bfSmpi wskbd_set_mixervolume(0, 1);
1373a81050dSrobert break;
1386544bd67Smiod case 0x07: /* decrease volume */
1396544bd67Smiod case 0x02: /* decrease volume, AV hardware */
140012023bfSmpi wskbd_set_mixervolume(-1, 1);
1413a81050dSrobert break;
1426544bd67Smiod case 0x06: /* increase volume */
1436544bd67Smiod case 0x03: /* increase volume, AV hardware */
144012023bfSmpi wskbd_set_mixervolume(1, 1);
145088642d9Sdrahn break;
1463a81050dSrobert #endif
147088642d9Sdrahn case 0x0c: /* mirror display key */
148088642d9Sdrahn /* Need callback to do something with this */
1496544bd67Smiod break;
1503a81050dSrobert #if NWSKBD > 0 && NCD > 0
1516544bd67Smiod case 0x0b: /* eject tray */
1529bae9981Sblambert task_add(systq, &eject_task);
1536544bd67Smiod break;
1543a81050dSrobert #endif
1556544bd67Smiod case 0x7f: /* numlock */
156088642d9Sdrahn /* Need callback to do something with this */
1576544bd67Smiod break;
1586544bd67Smiod
1596544bd67Smiod default:
1603a81050dSrobert #ifdef DEBUG
161af780111Smiod if ((cmd & ~0x7f) == 0)
162088642d9Sdrahn printf("unknown ADB button 0x%x\n", cmd);
1636544bd67Smiod #endif
1643a81050dSrobert break;
165d9a5f17fSdrahn }
166d9a5f17fSdrahn }
167