acpi_sony.c revision 273736
1/*-
2 * Copyright (c) 2004 Takanori Watanabe
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: stable/10/sys/dev/acpi_support/acpi_sony.c 273736 2014-10-27 14:38:00Z hselasky $");
29
30#include "opt_acpi.h"
31#include <sys/param.h>
32#include <sys/kernel.h>
33#include <sys/bus.h>
34
35#include <contrib/dev/acpica/include/acpi.h>
36
37#include "acpi_if.h"
38#include <sys/module.h>
39#include <dev/acpica/acpivar.h>
40#include <sys/sysctl.h>
41
42#define _COMPONENT	ACPI_OEM
43ACPI_MODULE_NAME("Sony")
44
45#define ACPI_SONY_GET_PID "GPID"
46
47/*
48 * SNY5001
49 *   This is the ACPI handle for the "Sony Notebook Control" driver under
50 *   Windows.
51 *   It provides several methods within the ACPI namespace, including:
52 *  [GS]BRT [GS]PBR [GS]CTR [GS]PCR [GS]CMI [CDPW GCDP]? GWDP PWAK PWRN
53 *
54 * SNY6001
55 *   This is the ACPI handle for the "Sony Programmable I/O" driver under
56 *   Windows.
57 *   It is not yet supported by this driver, but provides control over the
58 *   power to the bluetooth, built-in camera and HSDPA modem devices in some
59 *   laptops, and also allows some control of the fan speed.
60 */
61
62struct acpi_sony_softc {
63	int pid;
64};
65static struct acpi_sony_name_list
66{
67	char *nodename;
68	char *getmethod;
69	char *setmethod;
70	char *comment;
71} acpi_sony_oids[] = {
72	{ "brightness", "GBRT", "SBRT", "Display Brightness"},
73	{ "brightness_default", "GPBR", "SPBR", "Default Display Brightness"},
74	{ "contrast", "GCTR", "SCTR", "Display Contrast"},
75	{ "bass_gain", "GMGB", "SMGB", "Multimedia Bass Gain"},
76	{ "pcr", "GPCR", "SPCR", "???"},
77#if 0
78	{ "cmi", "GCMI", "SCMI", "???"},
79#endif
80	{ "wdp", "GWDP", NULL, "???"},
81	{ "cdp", "GCDP", "CDPW", "CD Power"},  /*shares [\GL03]&0x8 flag*/
82	{ "azp", "GAZP", "AZPW", "Audio Power"},
83	{ "lnp", "GLNP", "LNPW", "LAN Power"},
84	{ NULL, NULL, NULL }
85};
86
87static int	acpi_sony_probe(device_t dev);
88static int	acpi_sony_attach(device_t dev);
89static int 	acpi_sony_detach(device_t dev);
90static int	sysctl_acpi_sony_gen_handler(SYSCTL_HANDLER_ARGS);
91
92static device_method_t acpi_sony_methods[] = {
93	/* Device interface */
94	DEVMETHOD(device_probe, acpi_sony_probe),
95	DEVMETHOD(device_attach, acpi_sony_attach),
96	DEVMETHOD(device_detach, acpi_sony_detach),
97
98	DEVMETHOD_END
99};
100
101static driver_t	acpi_sony_driver = {
102	"acpi_sony",
103	acpi_sony_methods,
104	sizeof(struct acpi_sony_softc),
105};
106
107static devclass_t acpi_sony_devclass;
108
109DRIVER_MODULE(acpi_sony, acpi, acpi_sony_driver, acpi_sony_devclass,
110	      0, 0);
111MODULE_DEPEND(acpi_sony, acpi, 1, 1, 1);
112static char    *sny_id[] = {"SNY5001", NULL};
113
114static int
115acpi_sony_probe(device_t dev)
116{
117	int ret = ENXIO;
118
119	if (ACPI_ID_PROBE(device_get_parent(dev), dev, sny_id)) {
120		device_set_desc(dev, "Sony notebook controller");
121		ret = 0;
122	}
123	return (ret);
124}
125
126static int
127acpi_sony_attach(device_t dev)
128{
129	struct acpi_sony_softc *sc;
130	int i;
131
132	sc = device_get_softc(dev);
133	acpi_GetInteger(acpi_get_handle(dev), ACPI_SONY_GET_PID, &sc->pid);
134	device_printf(dev, "PID %x\n", sc->pid);
135	for (i = 0 ; acpi_sony_oids[i].nodename != NULL; i++) {
136		if (acpi_sony_oids[i].setmethod != NULL) {
137			SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
138			    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
139			    i, acpi_sony_oids[i].nodename ,
140			    CTLTYPE_INT | CTLFLAG_RW,
141			    dev, i, sysctl_acpi_sony_gen_handler, "I",
142			    acpi_sony_oids[i].comment);
143		} else {
144			SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
145			    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
146			    i, acpi_sony_oids[i].nodename ,
147			    CTLTYPE_INT | CTLFLAG_RD,
148			    dev, i, sysctl_acpi_sony_gen_handler, "I",
149			    acpi_sony_oids[i].comment);
150		}
151	}
152	return (0);
153}
154
155static int
156acpi_sony_detach(device_t dev)
157{
158	return (0);
159}
160
161#if 0
162static int
163acpi_sony_suspend(device_t dev)
164{
165	struct acpi_sony_softc *sc = device_get_softc(dev);
166	return (0);
167}
168
169static int
170acpi_sony_resume(device_t dev)
171{
172	return (0);
173}
174#endif
175
176static int
177sysctl_acpi_sony_gen_handler(SYSCTL_HANDLER_ARGS)
178{
179	device_t	dev = arg1;
180	int 	function = oidp->oid_arg2;
181	int		error = 0, val;
182
183	acpi_GetInteger(acpi_get_handle(dev),
184	    acpi_sony_oids[function].getmethod, &val);
185	error = sysctl_handle_int(oidp, &val, 0, req);
186	if (error || !req->newptr || !acpi_sony_oids[function].setmethod)
187		return (error);
188	acpi_SetInteger(acpi_get_handle(dev),
189	    acpi_sony_oids[function].setmethod, val);
190	return (0);
191}
192