1*3b9d585eSjsg /* $OpenBSD: acpitoshiba.c,v 1.17 2024/04/13 23:44:11 jsg Exp $ */
2a1b92009Spirofti /*-
3a1b92009Spirofti * Copyright (c) 2003 Hiroyuki Aizu <aizu@navi.org>
4a1b92009Spirofti * All rights reserved.
5a1b92009Spirofti *
6a1b92009Spirofti * Redistribution and use in source and binary forms, with or without
7a1b92009Spirofti * modification, are permitted provided that the following conditions
8a1b92009Spirofti * are met:
9a1b92009Spirofti * 1. Redistributions of source code must retain the above copyright
10a1b92009Spirofti * notice, this list of conditions and the following disclaimer.
11a1b92009Spirofti * 2. Redistributions in binary form must reproduce the above copyright
12a1b92009Spirofti * notice, this list of conditions and the following disclaimer in the
13a1b92009Spirofti * documentation and/or other materials provided with the distribution.
14a1b92009Spirofti *
15a1b92009Spirofti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16a1b92009Spirofti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17a1b92009Spirofti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18a1b92009Spirofti * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19a1b92009Spirofti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20a1b92009Spirofti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21a1b92009Spirofti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22a1b92009Spirofti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23a1b92009Spirofti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24a1b92009Spirofti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25a1b92009Spirofti * SUCH DAMAGE.
26a1b92009Spirofti *
27a1b92009Spirofti */
28a1b92009Spirofti #include <sys/param.h>
29a1b92009Spirofti #include <sys/systm.h>
30a1b92009Spirofti
31a1b92009Spirofti #include <dev/acpi/acpivar.h>
32a1b92009Spirofti #include <dev/acpi/acpidev.h>
33a1b92009Spirofti #include <dev/acpi/amltypes.h>
34a1b92009Spirofti #include <dev/acpi/dsdt.h>
35a1b92009Spirofti
36a1b92009Spirofti #include <machine/apmvar.h>
37a1b92009Spirofti #include <dev/wscons/wsconsio.h>
38d95a16b0Skettenis #include <dev/wscons/wsdisplayvar.h>
39a1b92009Spirofti
40a1b92009Spirofti /*
41a1b92009Spirofti * Toshiba HCI interface definitions
42a1b92009Spirofti *
43a1b92009Spirofti * HCI is Toshiba's "Hardware Control Interface" which is supposed to
44a1b92009Spirofti * be uniform across all their models. Ideally we would just call
45a1b92009Spirofti * dedicated ACPI methods instead of using this primitive interface.
46a1b92009Spirofti * However, the ACPI methods seem to be incomplete in some areas (for
47a1b92009Spirofti * example they allow setting, but not reading, the LCD brightness
48a1b92009Spirofti * value), so this is still useful.
49a1b92009Spirofti */
50a1b92009Spirofti #define METHOD_HCI "GHCI"
51a1b92009Spirofti #define METHOD_HCI_ENABLE "ENAB"
52a1b92009Spirofti
53a1b92009Spirofti /* Operations */
54a1b92009Spirofti #define HCI_SET 0xFF00
55a1b92009Spirofti #define HCI_GET 0xFE00
56a1b92009Spirofti
57a1b92009Spirofti /* Functions */
58a1b92009Spirofti #define HCI_REG_SYSTEM_EVENT 0x0016
59a1b92009Spirofti #define HCI_REG_VIDEO_OUTPUT 0x001C
60a1b92009Spirofti #define HCI_REG_LCD_BRIGHTNESS 0x002A
61a1b92009Spirofti
62a1b92009Spirofti /* Field definitions */
63a1b92009Spirofti #define HCI_LCD_BRIGHTNESS_BITS 3
64a1b92009Spirofti #define HCI_LCD_BRIGHTNESS_SHIFT (16 - HCI_LCD_BRIGHTNESS_BITS)
65a1b92009Spirofti #define HCI_LCD_BRIGHTNESS_MAX ((1 << HCI_LCD_BRIGHTNESS_BITS) - 1)
66a1b92009Spirofti #define HCI_LCD_BRIGHTNESS_MIN 0
67a1b92009Spirofti #define HCI_VIDEO_OUTPUT_FLAG 0x0100
68a1b92009Spirofti #define HCI_VIDEO_OUTPUT_CYCLE_MIN 0
69a1b92009Spirofti #define HCI_VIDEO_OUTPUT_CYCLE_MAX 7
70a1b92009Spirofti
71a1b92009Spirofti /* HCI register definitions */
72a1b92009Spirofti #define HCI_WORDS 6 /* Number of register */
73a1b92009Spirofti #define HCI_REG_AX 0 /* Operation, then return value */
74a1b92009Spirofti #define HCI_REG_BX 1 /* Function */
75a1b92009Spirofti #define HCI_REG_CX 2 /* Argument (in or out) */
76a1b92009Spirofti
77a1b92009Spirofti /* Return codes */
78a1b92009Spirofti #define HCI_FAILURE -1
79a1b92009Spirofti #define HCI_SUCCESS 0
80a1b92009Spirofti
81a1b92009Spirofti /* Toshiba fn_keys events */
82aed231a4Sgiovanni #define FN_KEY_SUSPEND 0x01BD
83aed231a4Sgiovanni #define FN_KEY_HIBERNATE 0x01BE
84a1b92009Spirofti #define FN_KEY_VIDEO_OUTPUT 0x01BF
85a1b92009Spirofti #define FN_KEY_BRIGHTNESS_DOWN 0x01C0
86a1b92009Spirofti #define FN_KEY_BRIGHTNESS_UP 0x01C1
87a1b92009Spirofti
88a1b92009Spirofti struct acpitoshiba_softc {
89a1b92009Spirofti struct device sc_dev;
90a1b92009Spirofti struct acpi_softc *sc_acpi;
91a1b92009Spirofti struct aml_node *sc_devnode;
924aff7db4Skettenis
934aff7db4Skettenis uint32_t sc_brightness;
94a1b92009Spirofti };
95a1b92009Spirofti
96a1b92009Spirofti int toshiba_enable_events(struct acpitoshiba_softc *);
97a1b92009Spirofti int toshiba_read_events(struct acpitoshiba_softc *);
98a1b92009Spirofti int toshiba_match(struct device *, void *, void *);
99a1b92009Spirofti void toshiba_attach(struct device *, struct device *, void *);
100a1b92009Spirofti int toshiba_hotkey(struct aml_node *, int, void *);
101d2eaebe9Skettenis int toshiba_get_brightness(struct acpitoshiba_softc *, uint32_t *);
102d2eaebe9Skettenis int toshiba_set_brightness(struct acpitoshiba_softc *, uint32_t *);
103d2eaebe9Skettenis int toshiba_get_video_output(struct acpitoshiba_softc *, uint32_t *);
104d2eaebe9Skettenis int toshiba_set_video_output(struct acpitoshiba_softc *, uint32_t *);
1054aff7db4Skettenis void toshiba_update_brightness(void *, int);
106a1b92009Spirofti int toshiba_fn_key_brightness_up(struct acpitoshiba_softc *);
107a1b92009Spirofti int toshiba_fn_key_brightness_down(struct acpitoshiba_softc *);
108a1b92009Spirofti int toshiba_fn_key_video_output(struct acpitoshiba_softc *);
109a1b92009Spirofti
110a1b92009Spirofti /* wconsole hook functions */
111a1b92009Spirofti int acpitoshiba_get_param(struct wsdisplay_param *);
112a1b92009Spirofti int acpitoshiba_set_param(struct wsdisplay_param *);
113a1b92009Spirofti int get_param_brightness(struct wsdisplay_param *);
114a1b92009Spirofti int set_param_brightness(struct wsdisplay_param *);
115a1b92009Spirofti
116471aeecfSnaddy const struct cfattach acpitoshiba_ca = {
117a1b92009Spirofti sizeof(struct acpitoshiba_softc), toshiba_match, toshiba_attach
118a1b92009Spirofti };
119a1b92009Spirofti
120a1b92009Spirofti struct cfdriver acpitoshiba_cd = {
121a1b92009Spirofti NULL, "acpitoshiba", DV_DULL
122a1b92009Spirofti };
123a1b92009Spirofti
124882e55bfSgiovanni const char *acpitoshiba_hids[] = {
1256bf9874fSjcs "TOS6200", /* Libretto */
1266bf9874fSjcs "TOS6207", /* Dynabook */
1276bf9874fSjcs "TOS6208", /* SPA40 */
128128e94b2Smlarkin NULL
129882e55bfSgiovanni };
130882e55bfSgiovanni
131a1b92009Spirofti int
get_param_brightness(struct wsdisplay_param * dp)132a1b92009Spirofti get_param_brightness(struct wsdisplay_param *dp)
133a1b92009Spirofti {
1344aff7db4Skettenis struct acpitoshiba_softc *sc = acpitoshiba_cd.cd_devs[0];
135a1b92009Spirofti
136a1b92009Spirofti if (sc != NULL) {
137a1b92009Spirofti /* default settings */
138a1b92009Spirofti dp->min = HCI_LCD_BRIGHTNESS_MIN;
139a1b92009Spirofti dp->max = HCI_LCD_BRIGHTNESS_MAX;
1404aff7db4Skettenis dp->curval = sc->sc_brightness;
141a1b92009Spirofti return (0);
142a1b92009Spirofti }
143a1b92009Spirofti
144a1b92009Spirofti return (1);
145a1b92009Spirofti }
146a1b92009Spirofti
147a1b92009Spirofti int
acpitoshiba_get_param(struct wsdisplay_param * dp)148a1b92009Spirofti acpitoshiba_get_param(struct wsdisplay_param *dp)
149a1b92009Spirofti {
150a1b92009Spirofti int ret;
151a1b92009Spirofti
152a1b92009Spirofti switch (dp->param) {
153a1b92009Spirofti case WSDISPLAYIO_PARAM_BRIGHTNESS:
154a1b92009Spirofti ret = get_param_brightness(dp);
155a1b92009Spirofti return (ret);
156a1b92009Spirofti default:
157a1b92009Spirofti return (1);
158a1b92009Spirofti }
159a1b92009Spirofti }
160a1b92009Spirofti
161a1b92009Spirofti int
set_param_brightness(struct wsdisplay_param * dp)162a1b92009Spirofti set_param_brightness(struct wsdisplay_param *dp)
163a1b92009Spirofti {
1644aff7db4Skettenis struct acpitoshiba_softc *sc = acpitoshiba_cd.cd_devs[0];
165a1b92009Spirofti
166a1b92009Spirofti if (sc != NULL) {
1674aff7db4Skettenis if (dp->curval < HCI_LCD_BRIGHTNESS_MIN)
1684aff7db4Skettenis dp->curval = HCI_LCD_BRIGHTNESS_MIN;
1694aff7db4Skettenis if (dp->curval > HCI_LCD_BRIGHTNESS_MAX)
1704aff7db4Skettenis dp->curval = HCI_LCD_BRIGHTNESS_MAX;
1714aff7db4Skettenis sc->sc_brightness = dp->curval;
1724aff7db4Skettenis acpi_addtask(sc->sc_acpi, toshiba_update_brightness, sc, 0);
1734aff7db4Skettenis acpi_wakeup(sc->sc_acpi);
174a1b92009Spirofti return (0);
175a1b92009Spirofti }
176a1b92009Spirofti
177a1b92009Spirofti return (1);
178a1b92009Spirofti }
179a1b92009Spirofti
180a1b92009Spirofti int
acpitoshiba_set_param(struct wsdisplay_param * dp)181a1b92009Spirofti acpitoshiba_set_param(struct wsdisplay_param *dp)
182a1b92009Spirofti {
183a1b92009Spirofti int ret;
184a1b92009Spirofti
185a1b92009Spirofti switch (dp->param) {
186a1b92009Spirofti case WSDISPLAYIO_PARAM_BRIGHTNESS:
187a1b92009Spirofti ret = set_param_brightness(dp);
188a1b92009Spirofti return (ret);
189a1b92009Spirofti default:
190a1b92009Spirofti return (1);
191a1b92009Spirofti }
192a1b92009Spirofti }
193a1b92009Spirofti
1944aff7db4Skettenis void
toshiba_update_brightness(void * arg0,int arg1)1954aff7db4Skettenis toshiba_update_brightness(void *arg0, int arg1)
196a1b92009Spirofti {
1974aff7db4Skettenis struct acpitoshiba_softc *sc = arg0;
198a1b92009Spirofti
1994aff7db4Skettenis toshiba_set_brightness(sc, &sc->sc_brightness);
200a1b92009Spirofti }
201a1b92009Spirofti
202a1b92009Spirofti int
toshiba_match(struct device * parent,void * match,void * aux)203a1b92009Spirofti toshiba_match(struct device *parent, void *match, void *aux)
204a1b92009Spirofti {
205a1b92009Spirofti struct acpi_attach_args *aa = aux;
206a1b92009Spirofti struct cfdata *cf = match;
207a1b92009Spirofti
208882e55bfSgiovanni if (acpi_matchhids(aa, acpitoshiba_hids, cf->cf_driver->cd_name))
209882e55bfSgiovanni return (1);
210882e55bfSgiovanni
211a1b92009Spirofti if (aa->aaa_name == NULL ||
212a1b92009Spirofti strcmp(aa->aaa_name, cf->cf_driver->cd_name) != 0 ||
213a1b92009Spirofti aa->aaa_table != NULL)
214a1b92009Spirofti return (0);
215a1b92009Spirofti
216a1b92009Spirofti return (1);
217a1b92009Spirofti }
218a1b92009Spirofti
219a1b92009Spirofti int
toshiba_enable_events(struct acpitoshiba_softc * sc)220a1b92009Spirofti toshiba_enable_events(struct acpitoshiba_softc *sc)
221a1b92009Spirofti {
222a1b92009Spirofti if (aml_evalname(sc->sc_acpi, sc->sc_devnode, METHOD_HCI_ENABLE,
223a1b92009Spirofti 0, NULL, NULL)) {
224a1b92009Spirofti printf("%s: couldn't toggle METHOD_HCI_ENABLE\n", DEVNAME(sc));
225a1b92009Spirofti return (HCI_FAILURE);
226a1b92009Spirofti }
227a1b92009Spirofti
228a1b92009Spirofti return (HCI_SUCCESS);
229a1b92009Spirofti }
230a1b92009Spirofti
231a1b92009Spirofti int
toshiba_read_events(struct acpitoshiba_softc * sc)232a1b92009Spirofti toshiba_read_events(struct acpitoshiba_softc *sc)
233a1b92009Spirofti {
234a1b92009Spirofti struct aml_value args[HCI_WORDS];
235a1b92009Spirofti struct aml_value res;
236a1b92009Spirofti int i, val;
237a1b92009Spirofti
238a1b92009Spirofti bzero(args, sizeof(args));
239a1b92009Spirofti bzero(&res, sizeof(res));
240a1b92009Spirofti
241a1b92009Spirofti for (i = 0; i < HCI_WORDS; ++i)
242a1b92009Spirofti args[i].type = AML_OBJTYPE_INTEGER;
243a1b92009Spirofti
244a1b92009Spirofti args[HCI_REG_AX].v_integer = HCI_GET;
245a1b92009Spirofti args[HCI_REG_BX].v_integer = HCI_REG_SYSTEM_EVENT;
246a1b92009Spirofti
247a1b92009Spirofti if (aml_evalname(sc->sc_acpi, sc->sc_devnode, METHOD_HCI,
248a1b92009Spirofti i, args, &res)) {
249a1b92009Spirofti printf("%s: couldn't toggle METHOD_HCI\n", DEVNAME(sc));
250a1b92009Spirofti return (HCI_FAILURE);
251a1b92009Spirofti }
252a1b92009Spirofti
253a1b92009Spirofti /*
254a1b92009Spirofti * We receive a package type so we need to get the event
255a1b92009Spirofti * value from the HCI_REG_CX.
256a1b92009Spirofti */
257a1b92009Spirofti val = aml_val2int(res.v_package[HCI_REG_CX]);
258a1b92009Spirofti aml_freevalue(&res);
259a1b92009Spirofti
260a1b92009Spirofti return (val);
261a1b92009Spirofti }
262a1b92009Spirofti
263a1b92009Spirofti void
toshiba_attach(struct device * parent,struct device * self,void * aux)264a1b92009Spirofti toshiba_attach(struct device *parent, struct device *self, void *aux)
265a1b92009Spirofti {
266a1b92009Spirofti struct acpitoshiba_softc *sc = (struct acpitoshiba_softc *)self;
267a1b92009Spirofti struct acpi_attach_args *aa = aux;
268a1b92009Spirofti int ret;
269a1b92009Spirofti
270a1b92009Spirofti sc->sc_acpi = (struct acpi_softc *)parent;
271a1b92009Spirofti sc->sc_devnode = aa->aaa_node;
272a1b92009Spirofti
273a1b92009Spirofti printf("\n");
274a1b92009Spirofti
275a1b92009Spirofti /* enable events and hotkeys */
276a1b92009Spirofti ret = toshiba_enable_events(sc);
277a1b92009Spirofti if (ret != HCI_FAILURE) {
278a1b92009Spirofti /* Run toshiba_hotkey on button presses */
279a1b92009Spirofti aml_register_notify(sc->sc_devnode, aa->aaa_dev,
280a1b92009Spirofti toshiba_hotkey, sc, ACPIDEV_NOPOLL);
2814aff7db4Skettenis }
282a1b92009Spirofti
2834aff7db4Skettenis ret = toshiba_get_brightness(sc, &sc->sc_brightness);
2844aff7db4Skettenis if (ret != HCI_FAILURE) {
285a1b92009Spirofti /* wsconsctl purpose */
286a1b92009Spirofti ws_get_param = acpitoshiba_get_param;
287a1b92009Spirofti ws_set_param = acpitoshiba_set_param;
288a1b92009Spirofti }
289a1b92009Spirofti }
290a1b92009Spirofti
291a1b92009Spirofti int
toshiba_fn_key_brightness_up(struct acpitoshiba_softc * sc)292a1b92009Spirofti toshiba_fn_key_brightness_up(struct acpitoshiba_softc *sc)
293a1b92009Spirofti {
294d2eaebe9Skettenis uint32_t brightness_level;
295a1b92009Spirofti int ret;
296a1b92009Spirofti
297a1b92009Spirofti ret = toshiba_get_brightness(sc, &brightness_level);
298a1b92009Spirofti if (ret != HCI_FAILURE) {
299a1b92009Spirofti
300a1b92009Spirofti if (brightness_level++ == HCI_LCD_BRIGHTNESS_MAX)
301a1b92009Spirofti brightness_level = HCI_LCD_BRIGHTNESS_MAX;
302a1b92009Spirofti else
303a1b92009Spirofti ret = toshiba_set_brightness(sc, &brightness_level);
304a1b92009Spirofti }
305a1b92009Spirofti
306a1b92009Spirofti return (ret);
307a1b92009Spirofti }
308a1b92009Spirofti
309a1b92009Spirofti int
toshiba_fn_key_brightness_down(struct acpitoshiba_softc * sc)310a1b92009Spirofti toshiba_fn_key_brightness_down(struct acpitoshiba_softc *sc)
311a1b92009Spirofti {
312d2eaebe9Skettenis uint32_t brightness_level;
313a1b92009Spirofti int ret;
314a1b92009Spirofti
315a1b92009Spirofti ret = toshiba_get_brightness(sc, &brightness_level);
316a1b92009Spirofti if (ret != HCI_FAILURE) {
317a1b92009Spirofti if (brightness_level-- == HCI_LCD_BRIGHTNESS_MIN)
318a1b92009Spirofti brightness_level = HCI_LCD_BRIGHTNESS_MIN;
319a1b92009Spirofti else
320a1b92009Spirofti ret = toshiba_set_brightness(sc, &brightness_level);
321a1b92009Spirofti }
322a1b92009Spirofti
323a1b92009Spirofti return (ret);
324a1b92009Spirofti }
325a1b92009Spirofti
326a1b92009Spirofti int
toshiba_fn_key_video_output(struct acpitoshiba_softc * sc)327a1b92009Spirofti toshiba_fn_key_video_output(struct acpitoshiba_softc *sc)
328a1b92009Spirofti {
329d2eaebe9Skettenis uint32_t video_output;
330a1b92009Spirofti int ret;
331a1b92009Spirofti
332a1b92009Spirofti ret = toshiba_get_video_output(sc, &video_output);
333a1b92009Spirofti if (ret != HCI_FAILURE) {
334a1b92009Spirofti video_output = (video_output + 1) % HCI_VIDEO_OUTPUT_CYCLE_MAX;
335a1b92009Spirofti
336a1b92009Spirofti ret = toshiba_set_video_output(sc, &video_output);
337a1b92009Spirofti }
338a1b92009Spirofti
339a1b92009Spirofti return (ret);
340a1b92009Spirofti }
341a1b92009Spirofti
342a1b92009Spirofti int
toshiba_hotkey(struct aml_node * node,int notify,void * arg)343a1b92009Spirofti toshiba_hotkey(struct aml_node *node, int notify, void *arg)
344a1b92009Spirofti {
345a1b92009Spirofti struct acpitoshiba_softc *sc = arg;
3468a66542aSbluhm int event, ret = HCI_FAILURE;
347a1b92009Spirofti
348a1b92009Spirofti event = toshiba_read_events(sc);
349a1b92009Spirofti if (!event)
350a1b92009Spirofti return (0);
351a1b92009Spirofti
352a1b92009Spirofti switch (event) {
353a1b92009Spirofti case FN_KEY_BRIGHTNESS_UP:
354a1b92009Spirofti /* Increase brightness */
355a1b92009Spirofti ret = toshiba_fn_key_brightness_up(sc);
356a1b92009Spirofti break;
357a1b92009Spirofti case FN_KEY_BRIGHTNESS_DOWN:
358a1b92009Spirofti /* Decrease brightness */
359a1b92009Spirofti ret = toshiba_fn_key_brightness_down(sc);
360a1b92009Spirofti break;
361aed231a4Sgiovanni case FN_KEY_SUSPEND:
362aed231a4Sgiovanni #ifndef SMALL_KERNEL
363aed231a4Sgiovanni if (acpi_record_event(sc->sc_acpi, APM_USER_SUSPEND_REQ)) {
364aed231a4Sgiovanni acpi_addtask(sc->sc_acpi, acpi_sleep_task,
365ad814436Sderaadt sc->sc_acpi, SLEEP_SUSPEND);
366aed231a4Sgiovanni ret = HCI_SUCCESS;
367aed231a4Sgiovanni }
368aed231a4Sgiovanni #endif
369aed231a4Sgiovanni break;
370aed231a4Sgiovanni case FN_KEY_HIBERNATE:
371aed231a4Sgiovanni #if defined(HIBERNATE) && !defined(SMALL_KERNEL)
372aed231a4Sgiovanni if (acpi_record_event(sc->sc_acpi, APM_USER_HIBERNATE_REQ)) {
373aed231a4Sgiovanni acpi_addtask(sc->sc_acpi, acpi_sleep_task,
374ad814436Sderaadt sc->sc_acpi, SLEEP_HIBERNATE);
375aed231a4Sgiovanni ret = HCI_SUCCESS;
376aed231a4Sgiovanni }
377aed231a4Sgiovanni #endif
378aed231a4Sgiovanni break;
379a1b92009Spirofti case FN_KEY_VIDEO_OUTPUT:
380a1b92009Spirofti /* Cycle through video outputs. */
381a1b92009Spirofti ret = toshiba_fn_key_video_output(sc);
382a1b92009Spirofti break;
383a1b92009Spirofti default:
384a1b92009Spirofti break;
385a1b92009Spirofti }
386a1b92009Spirofti
387a1b92009Spirofti if (ret != HCI_SUCCESS)
388a1b92009Spirofti return (1);
389a1b92009Spirofti
390a1b92009Spirofti return (0);
391a1b92009Spirofti }
392a1b92009Spirofti
393a1b92009Spirofti int
toshiba_set_brightness(struct acpitoshiba_softc * sc,uint32_t * brightness)394d2eaebe9Skettenis toshiba_set_brightness(struct acpitoshiba_softc *sc, uint32_t *brightness)
395a1b92009Spirofti {
396a1b92009Spirofti struct aml_value args[HCI_WORDS];
397a1b92009Spirofti int i;
398a1b92009Spirofti
399a1b92009Spirofti bzero(args, sizeof(args));
400a1b92009Spirofti
401a1b92009Spirofti for (i = 0; i < HCI_WORDS; ++i)
402a1b92009Spirofti args[i].type = AML_OBJTYPE_INTEGER;
403a1b92009Spirofti
404a1b92009Spirofti if ((*brightness < HCI_LCD_BRIGHTNESS_MIN) ||
405a1b92009Spirofti (*brightness > HCI_LCD_BRIGHTNESS_MAX))
406a1b92009Spirofti return (HCI_FAILURE);
407a1b92009Spirofti
408a1b92009Spirofti *brightness <<= HCI_LCD_BRIGHTNESS_SHIFT;
409a1b92009Spirofti
410a1b92009Spirofti args[HCI_REG_AX].v_integer = HCI_SET;
411a1b92009Spirofti args[HCI_REG_BX].v_integer = HCI_REG_LCD_BRIGHTNESS;
412a1b92009Spirofti args[HCI_REG_CX].v_integer = *brightness;
413a1b92009Spirofti
414a1b92009Spirofti if (aml_evalname(sc->sc_acpi, sc->sc_devnode, METHOD_HCI,
415a1b92009Spirofti i, args, NULL)) {
416a1b92009Spirofti printf("%s: set brightness failed\n", DEVNAME(sc));
417a1b92009Spirofti return (HCI_FAILURE);
418a1b92009Spirofti }
419a1b92009Spirofti
4204aff7db4Skettenis sc->sc_brightness = *brightness;
421a1b92009Spirofti return (HCI_SUCCESS);
422a1b92009Spirofti }
423a1b92009Spirofti
424a1b92009Spirofti int
toshiba_get_brightness(struct acpitoshiba_softc * sc,uint32_t * brightness)425d2eaebe9Skettenis toshiba_get_brightness(struct acpitoshiba_softc *sc, uint32_t *brightness)
426a1b92009Spirofti {
427a1b92009Spirofti struct aml_value args[HCI_WORDS];
428a1b92009Spirofti struct aml_value res;
429a1b92009Spirofti int i;
430a1b92009Spirofti
431a1b92009Spirofti bzero(args, sizeof(args));
432a1b92009Spirofti bzero(&res, sizeof(res));
433a1b92009Spirofti
434a1b92009Spirofti for (i = 0; i < HCI_WORDS; ++i)
435a1b92009Spirofti args[i].type = AML_OBJTYPE_INTEGER;
436a1b92009Spirofti
437a1b92009Spirofti args[HCI_REG_AX].v_integer = HCI_GET;
438a1b92009Spirofti args[HCI_REG_BX].v_integer = HCI_REG_LCD_BRIGHTNESS;
439a1b92009Spirofti
440a1b92009Spirofti if (aml_evalname(sc->sc_acpi, sc->sc_devnode, METHOD_HCI,
441a1b92009Spirofti i, args, &res)) {
442a1b92009Spirofti printf("%s: get brightness failed\n", DEVNAME(sc));
443a1b92009Spirofti return (HCI_FAILURE);
444a1b92009Spirofti }
445a1b92009Spirofti
446a1b92009Spirofti /*
447a1b92009Spirofti * We receive a package type so we need to get the event
448a1b92009Spirofti * value from the HCI_REG_CX.
449a1b92009Spirofti */
450a1b92009Spirofti *brightness = aml_val2int(res.v_package[HCI_REG_CX]);
451a1b92009Spirofti
452a1b92009Spirofti *brightness >>= HCI_LCD_BRIGHTNESS_SHIFT;
453a1b92009Spirofti
454a1b92009Spirofti aml_freevalue(&res);
455a1b92009Spirofti
456a1b92009Spirofti return (HCI_SUCCESS);
457a1b92009Spirofti }
458a1b92009Spirofti
459a1b92009Spirofti int
toshiba_get_video_output(struct acpitoshiba_softc * sc,uint32_t * video_output)460d2eaebe9Skettenis toshiba_get_video_output(struct acpitoshiba_softc *sc, uint32_t *video_output)
461a1b92009Spirofti {
462a1b92009Spirofti struct aml_value res, args[HCI_WORDS];
463a1b92009Spirofti int i;
464a1b92009Spirofti
465a1b92009Spirofti bzero(args, sizeof(args));
466a1b92009Spirofti bzero(&res, sizeof(res));
467a1b92009Spirofti
468a1b92009Spirofti for (i = 0; i < HCI_WORDS; ++i)
469a1b92009Spirofti args[i].type = AML_OBJTYPE_INTEGER;
470a1b92009Spirofti
471a1b92009Spirofti args[HCI_REG_AX].v_integer = HCI_GET;
472a1b92009Spirofti args[HCI_REG_BX].v_integer = HCI_REG_VIDEO_OUTPUT;
473a1b92009Spirofti
474a1b92009Spirofti if (aml_evalname(sc->sc_acpi, sc->sc_devnode, METHOD_HCI,
475a1b92009Spirofti i, args, &res)) {
476a1b92009Spirofti printf("%s: get video output failed\n", DEVNAME(sc));
477a1b92009Spirofti return (HCI_FAILURE);
478a1b92009Spirofti }
479a1b92009Spirofti
480a1b92009Spirofti /*
481a1b92009Spirofti * We receive a package type so we need to get the event
482a1b92009Spirofti * value from the HCI_REG_CX.
483a1b92009Spirofti */
484a1b92009Spirofti *video_output = aml_val2int(res.v_package[HCI_REG_CX]);
485a1b92009Spirofti
486a1b92009Spirofti *video_output &= 0xff;
487a1b92009Spirofti
488a1b92009Spirofti aml_freevalue(&res);
489a1b92009Spirofti
490a1b92009Spirofti return (HCI_SUCCESS);
491a1b92009Spirofti }
492a1b92009Spirofti
493a1b92009Spirofti int
toshiba_set_video_output(struct acpitoshiba_softc * sc,uint32_t * video_output)494d2eaebe9Skettenis toshiba_set_video_output(struct acpitoshiba_softc *sc, uint32_t *video_output)
495a1b92009Spirofti {
496a1b92009Spirofti struct aml_value args[HCI_WORDS];
497a1b92009Spirofti int i;
498a1b92009Spirofti
499a1b92009Spirofti bzero(args, sizeof(args));
500a1b92009Spirofti
501a1b92009Spirofti if ((*video_output < HCI_VIDEO_OUTPUT_CYCLE_MIN) ||
502a1b92009Spirofti (*video_output > HCI_VIDEO_OUTPUT_CYCLE_MAX))
503a1b92009Spirofti return (HCI_FAILURE);
504a1b92009Spirofti
505a1b92009Spirofti *video_output |= HCI_VIDEO_OUTPUT_FLAG;
506a1b92009Spirofti
507a1b92009Spirofti for (i = 0; i < HCI_WORDS; ++i)
508a1b92009Spirofti args[i].type = AML_OBJTYPE_INTEGER;
509a1b92009Spirofti
510a1b92009Spirofti args[HCI_REG_AX].v_integer = HCI_SET;
511a1b92009Spirofti args[HCI_REG_BX].v_integer = HCI_REG_VIDEO_OUTPUT;
512a1b92009Spirofti args[HCI_REG_CX].v_integer = *video_output;
513a1b92009Spirofti
514a1b92009Spirofti if (aml_evalname(sc->sc_acpi, sc->sc_devnode, METHOD_HCI,
515a1b92009Spirofti i, args, NULL)) {
516a1b92009Spirofti printf("%s: set video output failed\n", DEVNAME(sc));
517a1b92009Spirofti return (HCI_FAILURE);
518a1b92009Spirofti }
519a1b92009Spirofti
520a1b92009Spirofti return (HCI_SUCCESS);
521a1b92009Spirofti }
522