Add in-driver event handler.
MFC after: 3 days
This commit is contained in:
parent
e1f4f1f860
commit
ae2f080bc4
@ -50,6 +50,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/module.h>
|
||||
#include <dev/acpica/acpivar.h>
|
||||
#include <dev/led/led.h>
|
||||
#include <sys/power.h>
|
||||
#include <sys/sbuf.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <isa/rtc.h>
|
||||
|
||||
@ -70,6 +72,7 @@ ACPI_MODULE_NAME("IBM")
|
||||
#define ACPI_IBM_METHOD_FANLEVEL 11
|
||||
#define ACPI_IBM_METHOD_FANSTATUS 12
|
||||
#define ACPI_IBM_METHOD_THERMAL 13
|
||||
#define ACPI_IBM_METHOD_HANDLEREVENTS 14
|
||||
|
||||
/* Hotkeys/Buttons */
|
||||
#define IBM_RTC_HOTKEY1 0x64
|
||||
@ -126,6 +129,21 @@ ACPI_MODULE_NAME("IBM")
|
||||
#define IBM_NAME_EVENTS_GET "MHKP"
|
||||
#define IBM_NAME_EVENTS_AVAILMASK "MHKA"
|
||||
|
||||
/* Event Code */
|
||||
#define IBM_EVENT_LCD_BACKLIGHT 0x03
|
||||
#define IBM_EVENT_SUSPEND_TO_RAM 0x04
|
||||
#define IBM_EVENT_BLUETOOTH 0x05
|
||||
#define IBM_EVENT_SCREEN_EXPAND 0x07
|
||||
#define IBM_EVENT_SUSPEND_TO_DISK 0x0c
|
||||
#define IBM_EVENT_BRIGHTNESS_UP 0x10
|
||||
#define IBM_EVENT_BRIGHTNESS_DOWN 0x11
|
||||
#define IBM_EVENT_THINKLIGHT 0x12
|
||||
#define IBM_EVENT_ZOOM 0x14
|
||||
#define IBM_EVENT_VOLUME_UP 0x15
|
||||
#define IBM_EVENT_VOLUME_DOWN 0x16
|
||||
#define IBM_EVENT_MUTE 0x17
|
||||
#define IBM_EVENT_ACCESS_IBM_BUTTON 0x18
|
||||
|
||||
#define ABS(x) (((x) < 0)? -(x) : (x))
|
||||
|
||||
struct acpi_ibm_softc {
|
||||
@ -164,6 +182,8 @@ struct acpi_ibm_softc {
|
||||
int events_mask_supported;
|
||||
int events_enable;
|
||||
|
||||
unsigned int handler_events;
|
||||
|
||||
struct sysctl_ctx_list *sysctl_ctx;
|
||||
struct sysctl_oid *sysctl_tree;
|
||||
};
|
||||
@ -267,8 +287,15 @@ static int acpi_ibm_sysctl_set(struct acpi_ibm_softc *sc, int method, int val);
|
||||
|
||||
static int acpi_ibm_eventmask_set(struct acpi_ibm_softc *sc, int val);
|
||||
static int acpi_ibm_thermal_sysctl(SYSCTL_HANDLER_ARGS);
|
||||
static int acpi_ibm_handlerevents_sysctl(SYSCTL_HANDLER_ARGS);
|
||||
static void acpi_ibm_notify(ACPI_HANDLE h, UINT32 notify, void *context);
|
||||
|
||||
static int acpi_ibm_brightness_set(struct acpi_ibm_softc *sc, int arg);
|
||||
static int acpi_ibm_bluetooth_set(struct acpi_ibm_softc *sc, int arg);
|
||||
static int acpi_ibm_thinklight_set(struct acpi_ibm_softc *sc, int arg);
|
||||
static int acpi_ibm_volume_set(struct acpi_ibm_softc *sc, int arg);
|
||||
static int acpi_ibm_mute_set(struct acpi_ibm_softc *sc, int arg);
|
||||
|
||||
static device_method_t acpi_ibm_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, acpi_ibm_probe),
|
||||
@ -404,6 +431,15 @@ acpi_ibm_attach(device_t dev)
|
||||
"Thermal zones");
|
||||
}
|
||||
|
||||
/* Hook up handlerevents node */
|
||||
if (acpi_ibm_sysctl_init(sc, ACPI_IBM_METHOD_HANDLEREVENTS)) {
|
||||
SYSCTL_ADD_PROC(sc->sysctl_ctx,
|
||||
SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
|
||||
"handlerevents", CTLTYPE_STRING | CTLFLAG_RW,
|
||||
sc, 0, acpi_ibm_handlerevents_sysctl, "I",
|
||||
"devd(8) events handled by acpi_ibm");
|
||||
}
|
||||
|
||||
/* Handle notifies */
|
||||
AcpiInstallNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY,
|
||||
acpi_ibm_notify, dev);
|
||||
@ -656,10 +692,8 @@ acpi_ibm_sysctl_get(struct acpi_ibm_softc *sc, int method)
|
||||
static int
|
||||
acpi_ibm_sysctl_set(struct acpi_ibm_softc *sc, int method, int arg)
|
||||
{
|
||||
int val, step;
|
||||
int val;
|
||||
UINT64 val_ec;
|
||||
ACPI_OBJECT Arg;
|
||||
ACPI_OBJECT_LIST Args;
|
||||
ACPI_STATUS status;
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
@ -683,101 +717,23 @@ acpi_ibm_sysctl_set(struct acpi_ibm_softc *sc, int method, int arg)
|
||||
break;
|
||||
|
||||
case ACPI_IBM_METHOD_BRIGHTNESS:
|
||||
if (arg < 0 || arg > 7)
|
||||
return (EINVAL);
|
||||
|
||||
if (sc->cmos_handle) {
|
||||
/* Read the current brightness */
|
||||
status = ACPI_EC_READ(sc->ec_dev, IBM_EC_BRIGHTNESS, &val_ec, 1);
|
||||
if (ACPI_FAILURE(status))
|
||||
return (status);
|
||||
val = val_ec & IBM_EC_MASK_BRI;
|
||||
|
||||
Args.Count = 1;
|
||||
Args.Pointer = &Arg;
|
||||
Arg.Type = ACPI_TYPE_INTEGER;
|
||||
Arg.Integer.Value = (arg > val) ? IBM_CMOS_BRIGHTNESS_UP : IBM_CMOS_BRIGHTNESS_DOWN;
|
||||
|
||||
step = (arg > val) ? 1 : -1;
|
||||
for (int i = val; i != arg; i += step) {
|
||||
status = AcpiEvaluateObject(sc->cmos_handle, NULL, &Args, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ACPI_EC_WRITE(sc->ec_dev, IBM_EC_BRIGHTNESS, arg, 1);
|
||||
return acpi_ibm_brightness_set(sc, arg);
|
||||
break;
|
||||
|
||||
case ACPI_IBM_METHOD_VOLUME:
|
||||
if (arg < 0 || arg > 14)
|
||||
return (EINVAL);
|
||||
|
||||
status = ACPI_EC_READ(sc->ec_dev, IBM_EC_VOLUME, &val_ec, 1);
|
||||
if (ACPI_FAILURE(status))
|
||||
return (status);
|
||||
|
||||
if (sc->cmos_handle) {
|
||||
val = val_ec & IBM_EC_MASK_VOL;
|
||||
|
||||
Args.Count = 1;
|
||||
Args.Pointer = &Arg;
|
||||
Arg.Type = ACPI_TYPE_INTEGER;
|
||||
Arg.Integer.Value = (arg > val) ? IBM_CMOS_VOLUME_UP : IBM_CMOS_VOLUME_DOWN;
|
||||
|
||||
step = (arg > val) ? 1 : -1;
|
||||
for (int i = val; i != arg; i += step) {
|
||||
status = AcpiEvaluateObject(sc->cmos_handle, NULL, &Args, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ACPI_EC_WRITE(sc->ec_dev, IBM_EC_VOLUME, arg + (val_ec & (~IBM_EC_MASK_VOL)), 1);
|
||||
return acpi_ibm_volume_set(sc, arg);
|
||||
break;
|
||||
|
||||
case ACPI_IBM_METHOD_MUTE:
|
||||
if (arg < 0 || arg > 1)
|
||||
return (EINVAL);
|
||||
|
||||
status = ACPI_EC_READ(sc->ec_dev, IBM_EC_VOLUME, &val_ec, 1);
|
||||
if (ACPI_FAILURE(status))
|
||||
return (status);
|
||||
|
||||
if (sc->cmos_handle) {
|
||||
Args.Count = 1;
|
||||
Args.Pointer = &Arg;
|
||||
Arg.Type = ACPI_TYPE_INTEGER;
|
||||
Arg.Integer.Value = IBM_CMOS_VOLUME_MUTE;
|
||||
|
||||
status = AcpiEvaluateObject(sc->cmos_handle, NULL, &Args, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
break;
|
||||
}
|
||||
return ACPI_EC_WRITE(sc->ec_dev, IBM_EC_VOLUME, (arg==1) ? val_ec | IBM_EC_MASK_MUTE : val_ec & (~IBM_EC_MASK_MUTE), 1);
|
||||
return acpi_ibm_mute_set(sc, arg);
|
||||
break;
|
||||
|
||||
case ACPI_IBM_METHOD_THINKLIGHT:
|
||||
if (arg < 0 || arg > 1)
|
||||
return (EINVAL);
|
||||
|
||||
if (sc->light_set_supported) {
|
||||
Args.Count = 1;
|
||||
Args.Pointer = &Arg;
|
||||
Arg.Type = ACPI_TYPE_INTEGER;
|
||||
Arg.Integer.Value = arg ? sc->light_cmd_on : sc->light_cmd_off;
|
||||
|
||||
status = AcpiEvaluateObject(sc->light_handle, NULL, &Args, NULL);
|
||||
if (ACPI_SUCCESS(status))
|
||||
sc->light_val = arg;
|
||||
return (status);
|
||||
}
|
||||
return acpi_ibm_thinklight_set(sc, arg);
|
||||
break;
|
||||
|
||||
case ACPI_IBM_METHOD_BLUETOOTH:
|
||||
if (arg < 0 || arg > 1)
|
||||
return (EINVAL);
|
||||
|
||||
val = (arg == 1) ? sc->wlan_bt_flags | IBM_NAME_MASK_BT : sc->wlan_bt_flags & (~IBM_NAME_MASK_BT);
|
||||
return acpi_SetInteger(sc->handle, IBM_NAME_WLAN_BT_SET, val);
|
||||
return acpi_ibm_bluetooth_set(sc, arg);
|
||||
break;
|
||||
|
||||
case ACPI_IBM_METHOD_FANLEVEL:
|
||||
@ -898,6 +854,9 @@ acpi_ibm_sysctl_init(struct acpi_ibm_softc *sc, int method)
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
|
||||
case ACPI_IBM_METHOD_HANDLEREVENTS:
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
@ -937,6 +896,328 @@ acpi_ibm_thermal_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_ibm_handlerevents_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
struct acpi_ibm_softc *sc;
|
||||
int error = 0;
|
||||
struct sbuf sb;
|
||||
char *cp, *ep;
|
||||
int l, val;
|
||||
unsigned int handler_events;
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
|
||||
sc = (struct acpi_ibm_softc *)oidp->oid_arg1;
|
||||
|
||||
if (sbuf_new(&sb, NULL, 128, SBUF_AUTOEXTEND) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
ACPI_SERIAL_BEGIN(ibm);
|
||||
|
||||
/* Get old values if this is a get request. */
|
||||
if (req->newptr == NULL) {
|
||||
for (int i = 0; i < 8 * sizeof(sc->handler_events); i++)
|
||||
if (sc->handler_events & (1 << i))
|
||||
sbuf_printf(&sb, "0x%02x ", i + 1);
|
||||
if (sbuf_len(&sb) == 0)
|
||||
sbuf_printf(&sb, "NONE");
|
||||
}
|
||||
|
||||
sbuf_trim(&sb);
|
||||
sbuf_finish(&sb);
|
||||
|
||||
/* Copy out the old values to the user. */
|
||||
error = SYSCTL_OUT(req, sbuf_data(&sb), sbuf_len(&sb));
|
||||
sbuf_delete(&sb);
|
||||
|
||||
if (error != 0 || req->newptr == NULL)
|
||||
goto out;
|
||||
|
||||
/* If the user is setting a string, parse it. */
|
||||
handler_events = 0;
|
||||
cp = (char *)req->newptr;
|
||||
while (*cp) {
|
||||
if (isspace(*cp)) {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
ep = cp;
|
||||
|
||||
while (*ep && !isspace(*ep))
|
||||
ep++;
|
||||
|
||||
l = ep - cp;
|
||||
if (l == 0)
|
||||
break;
|
||||
|
||||
if (strncmp(cp, "NONE", 4) == 0) {
|
||||
cp = ep;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (l >= 3 && cp[0] == '0' && (cp[1] == 'X' || cp[1] == 'x'))
|
||||
val = strtoul(cp, &ep, 16);
|
||||
else
|
||||
val = strtoul(cp, &ep, 10);
|
||||
|
||||
if (val == 0 || ep == cp || val >= 8 * sizeof(handler_events)) {
|
||||
cp[l] = '\0';
|
||||
device_printf(sc->dev, "invalid event code: %s\n", cp);
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
handler_events |= 1 << (val - 1);
|
||||
|
||||
cp = ep;
|
||||
}
|
||||
|
||||
sc->handler_events = handler_events;
|
||||
out:
|
||||
ACPI_SERIAL_END(ibm);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_ibm_brightness_set(struct acpi_ibm_softc *sc, int arg)
|
||||
{
|
||||
int val, step;
|
||||
UINT64 val_ec;
|
||||
ACPI_OBJECT Arg;
|
||||
ACPI_OBJECT_LIST Args;
|
||||
ACPI_STATUS status;
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
ACPI_SERIAL_ASSERT(ibm);
|
||||
|
||||
if (arg < 0 || arg > 7)
|
||||
return (EINVAL);
|
||||
|
||||
/* Read the current brightness */
|
||||
status = ACPI_EC_READ(sc->ec_dev, IBM_EC_BRIGHTNESS, &val_ec, 1);
|
||||
if (ACPI_FAILURE(status))
|
||||
return (status);
|
||||
|
||||
if (sc->cmos_handle) {
|
||||
val = val_ec & IBM_EC_MASK_BRI;
|
||||
|
||||
Args.Count = 1;
|
||||
Args.Pointer = &Arg;
|
||||
Arg.Type = ACPI_TYPE_INTEGER;
|
||||
Arg.Integer.Value = (arg > val) ? IBM_CMOS_BRIGHTNESS_UP :
|
||||
IBM_CMOS_BRIGHTNESS_DOWN;
|
||||
|
||||
step = (arg > val) ? 1 : -1;
|
||||
for (int i = val; i != arg; i += step) {
|
||||
status = AcpiEvaluateObject(sc->cmos_handle, NULL,
|
||||
&Args, NULL);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
/* Record the last value */
|
||||
if (i != val) {
|
||||
ACPI_EC_WRITE(sc->ec_dev,
|
||||
IBM_EC_BRIGHTNESS, i - step, 1);
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ACPI_EC_WRITE(sc->ec_dev, IBM_EC_BRIGHTNESS, arg, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_ibm_bluetooth_set(struct acpi_ibm_softc *sc, int arg)
|
||||
{
|
||||
int val;
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
ACPI_SERIAL_ASSERT(ibm);
|
||||
|
||||
if (arg < 0 || arg > 1)
|
||||
return (EINVAL);
|
||||
|
||||
val = (arg == 1) ? sc->wlan_bt_flags | IBM_NAME_MASK_BT :
|
||||
sc->wlan_bt_flags & (~IBM_NAME_MASK_BT);
|
||||
return acpi_SetInteger(sc->handle, IBM_NAME_WLAN_BT_SET, val);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_ibm_thinklight_set(struct acpi_ibm_softc *sc, int arg)
|
||||
{
|
||||
ACPI_OBJECT Arg;
|
||||
ACPI_OBJECT_LIST Args;
|
||||
ACPI_STATUS status;
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
ACPI_SERIAL_ASSERT(ibm);
|
||||
|
||||
if (arg < 0 || arg > 1)
|
||||
return (EINVAL);
|
||||
|
||||
if (sc->light_set_supported) {
|
||||
Args.Count = 1;
|
||||
Args.Pointer = &Arg;
|
||||
Arg.Type = ACPI_TYPE_INTEGER;
|
||||
Arg.Integer.Value = arg ? sc->light_cmd_on : sc->light_cmd_off;
|
||||
|
||||
status = AcpiEvaluateObject(sc->light_handle, NULL,
|
||||
&Args, NULL);
|
||||
if (ACPI_SUCCESS(status))
|
||||
sc->light_val = arg;
|
||||
return (status);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_ibm_volume_set(struct acpi_ibm_softc *sc, int arg)
|
||||
{
|
||||
int val, step;
|
||||
UINT64 val_ec;
|
||||
ACPI_OBJECT Arg;
|
||||
ACPI_OBJECT_LIST Args;
|
||||
ACPI_STATUS status;
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
ACPI_SERIAL_ASSERT(ibm);
|
||||
|
||||
if (arg < 0 || arg > 14)
|
||||
return (EINVAL);
|
||||
|
||||
/* Read the current volume */
|
||||
status = ACPI_EC_READ(sc->ec_dev, IBM_EC_VOLUME, &val_ec, 1);
|
||||
if (ACPI_FAILURE(status))
|
||||
return (status);
|
||||
|
||||
if (sc->cmos_handle) {
|
||||
val = val_ec & IBM_EC_MASK_VOL;
|
||||
|
||||
Args.Count = 1;
|
||||
Args.Pointer = &Arg;
|
||||
Arg.Type = ACPI_TYPE_INTEGER;
|
||||
Arg.Integer.Value = (arg > val) ? IBM_CMOS_VOLUME_UP :
|
||||
IBM_CMOS_VOLUME_DOWN;
|
||||
|
||||
step = (arg > val) ? 1 : -1;
|
||||
for (int i = val; i != arg; i += step) {
|
||||
status = AcpiEvaluateObject(sc->cmos_handle, NULL,
|
||||
&Args, NULL);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
/* Record the last value */
|
||||
if (i != val) {
|
||||
val_ec = i - step +
|
||||
(val_ec & (~IBM_EC_MASK_VOL));
|
||||
ACPI_EC_WRITE(sc->ec_dev, IBM_EC_VOLUME,
|
||||
val_ec, 1);
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val_ec = arg + (val_ec & (~IBM_EC_MASK_VOL));
|
||||
return ACPI_EC_WRITE(sc->ec_dev, IBM_EC_VOLUME, val_ec, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_ibm_mute_set(struct acpi_ibm_softc *sc, int arg)
|
||||
{
|
||||
UINT64 val_ec;
|
||||
ACPI_OBJECT Arg;
|
||||
ACPI_OBJECT_LIST Args;
|
||||
ACPI_STATUS status;
|
||||
|
||||
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
|
||||
ACPI_SERIAL_ASSERT(ibm);
|
||||
|
||||
if (arg < 0 || arg > 1)
|
||||
return (EINVAL);
|
||||
|
||||
status = ACPI_EC_READ(sc->ec_dev, IBM_EC_VOLUME, &val_ec, 1);
|
||||
if (ACPI_FAILURE(status))
|
||||
return (status);
|
||||
|
||||
if (sc->cmos_handle) {
|
||||
Args.Count = 1;
|
||||
Args.Pointer = &Arg;
|
||||
Arg.Type = ACPI_TYPE_INTEGER;
|
||||
Arg.Integer.Value = IBM_CMOS_VOLUME_MUTE;
|
||||
|
||||
status = AcpiEvaluateObject(sc->cmos_handle, NULL, &Args, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
return (status);
|
||||
}
|
||||
|
||||
val_ec = (arg == 1) ? val_ec | IBM_EC_MASK_MUTE :
|
||||
val_ec & (~IBM_EC_MASK_MUTE);
|
||||
return ACPI_EC_WRITE(sc->ec_dev, IBM_EC_VOLUME, val_ec, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
acpi_ibm_eventhandler(struct acpi_ibm_softc *sc, int arg)
|
||||
{
|
||||
int val;
|
||||
UINT64 val_ec;
|
||||
ACPI_STATUS status;
|
||||
|
||||
ACPI_SERIAL_BEGIN(ibm);
|
||||
switch (arg) {
|
||||
case IBM_EVENT_SUSPEND_TO_RAM:
|
||||
power_pm_suspend(POWER_SLEEP_STATE_SUSPEND);
|
||||
break;
|
||||
|
||||
case IBM_EVENT_BLUETOOTH:
|
||||
acpi_ibm_bluetooth_set(sc, (sc->wlan_bt_flags == 0));
|
||||
break;
|
||||
|
||||
case IBM_EVENT_BRIGHTNESS_UP:
|
||||
case IBM_EVENT_BRIGHTNESS_DOWN:
|
||||
/* Read the current brightness */
|
||||
status = ACPI_EC_READ(sc->ec_dev, IBM_EC_BRIGHTNESS,
|
||||
&val_ec, 1);
|
||||
if (ACPI_FAILURE(status))
|
||||
return;
|
||||
|
||||
val = val_ec & IBM_EC_MASK_BRI;
|
||||
val = (arg == IBM_EVENT_BRIGHTNESS_UP) ? val + 1 : val - 1;
|
||||
acpi_ibm_brightness_set(sc, val);
|
||||
break;
|
||||
|
||||
case IBM_EVENT_THINKLIGHT:
|
||||
acpi_ibm_thinklight_set(sc, (sc->light_val == 0));
|
||||
break;
|
||||
|
||||
case IBM_EVENT_VOLUME_UP:
|
||||
case IBM_EVENT_VOLUME_DOWN:
|
||||
/* Read the current volume */
|
||||
status = ACPI_EC_READ(sc->ec_dev, IBM_EC_VOLUME, &val_ec, 1);
|
||||
if (ACPI_FAILURE(status))
|
||||
return;
|
||||
|
||||
val = val_ec & IBM_EC_MASK_VOL;
|
||||
val = (arg == IBM_EVENT_VOLUME_UP) ? val + 1 : val - 1;
|
||||
acpi_ibm_volume_set(sc, val);
|
||||
break;
|
||||
|
||||
case IBM_EVENT_MUTE:
|
||||
/* Read the current value */
|
||||
status = ACPI_EC_READ(sc->ec_dev, IBM_EC_VOLUME, &val_ec, 1);
|
||||
if (ACPI_FAILURE(status))
|
||||
return;
|
||||
|
||||
val = ((val_ec & IBM_EC_MASK_MUTE) == IBM_EC_MASK_MUTE);
|
||||
acpi_ibm_mute_set(sc, (val == 0));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ACPI_SERIAL_END(ibm);
|
||||
}
|
||||
|
||||
static void
|
||||
acpi_ibm_notify(ACPI_HANDLE h, UINT32 notify, void *context)
|
||||
{
|
||||
@ -965,6 +1246,10 @@ acpi_ibm_notify(ACPI_HANDLE h, UINT32 notify, void *context)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Execute event handler */
|
||||
if (sc->handler_events & (1 << (arg - 1)))
|
||||
acpi_ibm_eventhandler(sc, (arg & 0xff));
|
||||
|
||||
/* Notify devd(8) */
|
||||
acpi_UserNotify("IBM", h, (arg & 0xff));
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user