Line data Source code
1 : /* $OpenBSD: acpiasus.c,v 1.19 2018/07/01 19:40:49 mlarkin Exp $ */
2 : /* $NetBSD: asus_acpi.c,v 1.2.2.2 2008/04/03 12:42:37 mjf Exp $ */
3 : /*
4 : * Copyright (c) 2007, 2008 Jared D. 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 : * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 : * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 : * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 : * POSSIBILITY OF SUCH DAMAGE.
27 : */
28 :
29 : /*
30 : * ASUS ACPI hotkeys driver.
31 : */
32 :
33 : #include <sys/param.h>
34 : #include <sys/device.h>
35 : #include <sys/systm.h>
36 :
37 : #include <dev/acpi/acpireg.h>
38 : #include <dev/acpi/acpivar.h>
39 : #include <dev/acpi/acpidev.h>
40 : #include <dev/acpi/amltypes.h>
41 : #include <dev/acpi/dsdt.h>
42 :
43 : #include "audio.h"
44 : #include "wskbd.h"
45 :
46 : struct acpiasus_softc {
47 : struct device sc_dev;
48 :
49 : struct acpi_softc *sc_acpi;
50 : struct aml_node *sc_devnode;
51 : };
52 :
53 : #define ASUS_NOTIFY_WIRELESSON 0x10
54 : #define ASUS_NOTIFY_WIRELESSOFF 0x11
55 : #define ASUS_NOTIFY_TASKSWITCH 0x12
56 : #define ASUS_NOTIFY_VOLUMEMUTE 0x13
57 : #define ASUS_NOTIFY_VOLUMEDOWN 0x14
58 : #define ASUS_NOTIFY_VOLUMEUP 0x15
59 : #define ASUS_NOTIFY_LCDSWITCHOFF0 0x16
60 : #define ASUS_NOTIFY_LCDSWITCHOFF1 0x1a
61 : #define ASUS_NOTIFY_LCDCHANGERES 0x1b
62 : #define ASUS_NOTIFY_USERDEF0 0x1c
63 : #define ASUS_NOTIFY_USERDEF1 0x1d
64 : #define ASUS_NOTIFY_BRIGHTNESSLOW 0x20
65 : #define ASUS_NOTIFY_BRIGHTNESSHIGH 0x2f
66 : #define ASUS_NOTIFY_DISPLAYCYCLEDOWN 0x30
67 : #define ASUS_NOTIFY_DISPLAYCYCLEUP 0x32
68 :
69 : #define ASUS_NOTIFY_POWERCONNECT 0x50
70 : #define ASUS_NOTIFY_POWERDISCONNECT 0x51
71 :
72 : #define ASUS_SDSP_LCD 0x01
73 : #define ASUS_SDSP_CRT 0x02
74 : #define ASUS_SDSP_TV 0x04
75 : #define ASUS_SDSP_DVI 0x08
76 : #define ASUS_SDSP_ALL \
77 : (ASUS_SDSP_LCD | ASUS_SDSP_CRT | ASUS_SDSP_TV | ASUS_SDSP_DVI)
78 :
79 : int acpiasus_match(struct device *, void *, void *);
80 : void acpiasus_attach(struct device *, struct device *, void *);
81 : void acpiasus_init(struct device *);
82 : int acpiasus_notify(struct aml_node *, int, void *);
83 : int acpiasus_activate(struct device *, int);
84 :
85 : #if NAUDIO > 0 && NWSKBD > 0
86 : extern int wskbd_set_mixervolume(long, long);
87 : #endif
88 :
89 : struct cfattach acpiasus_ca = {
90 : sizeof(struct acpiasus_softc), acpiasus_match, acpiasus_attach,
91 : NULL, acpiasus_activate
92 : };
93 :
94 : struct cfdriver acpiasus_cd = {
95 : NULL, "acpiasus", DV_DULL
96 : };
97 :
98 : const char *acpiasus_hids[] = {
99 : "ASUS010",
100 : NULL
101 : };
102 :
103 : int
104 0 : acpiasus_match(struct device *parent, void *match, void *aux)
105 : {
106 0 : struct acpi_attach_args *aa = aux;
107 0 : struct cfdata *cf = match;
108 :
109 0 : return (acpi_matchhids(aa, acpiasus_hids, cf->cf_driver->cd_name));
110 : }
111 :
112 : void
113 0 : acpiasus_attach(struct device *parent, struct device *self, void *aux)
114 : {
115 0 : struct acpiasus_softc *sc = (struct acpiasus_softc *)self;
116 0 : struct acpi_attach_args *aa = aux;
117 :
118 0 : sc->sc_acpi = (struct acpi_softc *)parent;
119 0 : sc->sc_devnode = aa->aaa_node;
120 :
121 0 : printf("\n");
122 :
123 0 : acpiasus_init(self);
124 :
125 0 : aml_register_notify(sc->sc_devnode, aa->aaa_dev,
126 0 : acpiasus_notify, sc, ACPIDEV_NOPOLL);
127 0 : }
128 :
129 : void
130 0 : acpiasus_init(struct device *self)
131 : {
132 0 : struct acpiasus_softc *sc = (struct acpiasus_softc *)self;
133 0 : struct aml_value cmd;
134 0 : struct aml_value ret;
135 :
136 0 : bzero(&cmd, sizeof(cmd));
137 0 : cmd.type = AML_OBJTYPE_INTEGER;
138 0 : cmd.v_integer = 0x40; /* Disable ASL display switching. */
139 :
140 0 : if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "INIT", 1, &cmd, &ret))
141 0 : printf("%s: no INIT\n", DEVNAME(sc));
142 : else
143 0 : aml_freevalue(&ret);
144 0 : }
145 :
146 : int
147 0 : acpiasus_notify(struct aml_node *node, int notify, void *arg)
148 : {
149 0 : struct acpiasus_softc *sc = arg;
150 :
151 0 : if (notify >= ASUS_NOTIFY_BRIGHTNESSLOW &&
152 0 : notify <= ASUS_NOTIFY_BRIGHTNESSHIGH) {
153 : #ifdef ACPIASUS_DEBUG
154 : printf("%s: brightness %d percent\n", DEVNAME(sc),
155 : (notify & 0xf) * 100 / 0xf);
156 : #endif
157 0 : return 0;
158 : }
159 :
160 0 : switch (notify) {
161 : case ASUS_NOTIFY_WIRELESSON: /* Handled by AML. */
162 : case ASUS_NOTIFY_WIRELESSOFF: /* Handled by AML. */
163 : break;
164 : case ASUS_NOTIFY_TASKSWITCH:
165 : break;
166 : case ASUS_NOTIFY_DISPLAYCYCLEDOWN:
167 : case ASUS_NOTIFY_DISPLAYCYCLEUP:
168 : break;
169 : #if NAUDIO > 0 && NWSKBD > 0
170 : case ASUS_NOTIFY_VOLUMEMUTE:
171 0 : wskbd_set_mixervolume(0, 1);
172 0 : break;
173 : case ASUS_NOTIFY_VOLUMEDOWN:
174 0 : wskbd_set_mixervolume(-1, 1);
175 0 : break;
176 : case ASUS_NOTIFY_VOLUMEUP:
177 0 : wskbd_set_mixervolume(1, 1);
178 0 : break;
179 : #else
180 : case ASUS_NOTIFY_VOLUMEMUTE:
181 : case ASUS_NOTIFY_VOLUMEDOWN:
182 : case ASUS_NOTIFY_VOLUMEUP:
183 : break;
184 : #endif
185 : case ASUS_NOTIFY_POWERCONNECT:
186 : case ASUS_NOTIFY_POWERDISCONNECT:
187 : break;
188 :
189 : case ASUS_NOTIFY_LCDSWITCHOFF0:
190 : case ASUS_NOTIFY_LCDSWITCHOFF1:
191 : break;
192 :
193 : case ASUS_NOTIFY_LCDCHANGERES:
194 : break;
195 :
196 : case ASUS_NOTIFY_USERDEF0:
197 : case ASUS_NOTIFY_USERDEF1:
198 : break;
199 :
200 : default:
201 0 : printf("%s: unknown event 0x%02x\n", DEVNAME(sc), notify);
202 0 : break;
203 : }
204 :
205 0 : return 0;
206 0 : }
207 :
208 : int
209 0 : acpiasus_activate(struct device *self, int act)
210 : {
211 0 : struct acpiasus_softc *sc = (struct acpiasus_softc *)self;
212 0 : struct aml_value cmd;
213 0 : struct aml_value ret;
214 :
215 0 : switch (act) {
216 : case DVACT_WAKEUP:
217 0 : acpiasus_init(self);
218 :
219 0 : bzero(&cmd, sizeof(cmd));
220 0 : cmd.type = AML_OBJTYPE_INTEGER;
221 0 : cmd.v_integer = ASUS_SDSP_LCD;
222 :
223 0 : if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "SDSP", 1,
224 : &cmd, &ret))
225 0 : printf("%s: no SDSP\n", DEVNAME(sc));
226 : else
227 0 : aml_freevalue(&ret);
228 : break;
229 : }
230 0 : return (0);
231 0 : }
|