summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorphilip <philip@FreeBSD.org>2005-03-20 23:36:36 +0000
committerphilip <philip@FreeBSD.org>2005-03-20 23:36:36 +0000
commitdf09d3a7819676e84feebf7b0dfd2d7736450bd6 (patch)
tree5e7df4e4beba465715e60acf6726c79529674593 /sys
parent4da02be559060350260670cdba83826a86971ad7 (diff)
downloadFreeBSD-src-df09d3a7819676e84feebf7b0dfd2d7736450bd6.zip
FreeBSD-src-df09d3a7819676e84feebf7b0dfd2d7736450bd6.tar.gz
Simplify sysctl handling by consolidating various get/set functions into
generic functions, use a table for hooking up sysctls nodes rather than doing it manually. While here, clean up some style bugs. Glanced at by: njl
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/acpi_support/acpi_asus.c373
1 files changed, 213 insertions, 160 deletions
diff --git a/sys/dev/acpi_support/acpi_asus.c b/sys/dev/acpi_support/acpi_asus.c
index 372a9c3..88e2384 100644
--- a/sys/dev/acpi_support/acpi_asus.c
+++ b/sys/dev/acpi_support/acpi_asus.c
@@ -51,6 +51,11 @@ __FBSDID("$FreeBSD$");
#include <dev/acpica/acpivar.h>
#include <dev/led/led.h>
+/* Methods */
+#define ACPI_ASUS_METHOD_BRN 1
+#define ACPI_ASUS_METHOD_DISP 2
+#define ACPI_ASUS_METHOD_LCD 3
+
#define _COMPONENT ACPI_OEM
ACPI_MODULE_NAME("ASUS")
@@ -218,6 +223,30 @@ static struct acpi_asus_model acpi_samsung_models[] = {
{ .name = NULL }
};
+static struct {
+ char *name;
+ char *description;
+ int method;
+} acpi_asus_sysctls[] = {
+ {
+ .name = "lcd_backlight",
+ .method = ACPI_ASUS_METHOD_LCD,
+ .description = "state of the lcd backlight"
+ },
+ {
+ .name = "lcd_brightness",
+ .method = ACPI_ASUS_METHOD_BRN,
+ .description = "brightness of the lcd panel"
+ },
+ {
+ .name = "video_output",
+ .method = ACPI_ASUS_METHOD_DISP,
+ .description = "display output state"
+ },
+
+ { .name = NULL }
+};
+
ACPI_SERIAL_DECL(asus, "ACPI ASUS extras");
/* Function prototypes */
@@ -227,9 +256,10 @@ static int acpi_asus_detach(device_t dev);
static void acpi_asus_led(struct acpi_asus_led *led, int state);
-static int acpi_asus_sysctl_brn(SYSCTL_HANDLER_ARGS);
-static int acpi_asus_sysctl_lcd(SYSCTL_HANDLER_ARGS);
-static int acpi_asus_sysctl_disp(SYSCTL_HANDLER_ARGS);
+static int acpi_asus_sysctl(SYSCTL_HANDLER_ARGS);
+static int acpi_asus_sysctl_init(struct acpi_asus_softc *sc, int method);
+static int acpi_asus_sysctl_get(struct acpi_asus_softc *sc, int method);
+static int acpi_asus_sysctl_set(struct acpi_asus_softc *sc, int method, int val);
static void acpi_asus_notify(ACPI_HANDLE h, UINT32 notify, void *context);
@@ -356,6 +386,19 @@ acpi_asus_attach(device_t dev)
SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree),
OID_AUTO, "asus", CTLFLAG_RD, 0, "");
+ /* Hook up nodes */
+ for (int i = 0; acpi_asus_sysctls[i].name != NULL; i++) {
+ if (!acpi_asus_sysctl_init(sc, acpi_asus_sysctls[i].method))
+ continue;
+
+ SYSCTL_ADD_PROC(&sc->sysctl_ctx,
+ SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+ acpi_asus_sysctls[i].name,
+ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY,
+ sc, i, acpi_asus_sysctl, "I",
+ acpi_asus_sysctls[i].description);
+ }
+
/* Attach leds */
if (sc->model->mled_set) {
sc->s_mled.dev = dev;
@@ -378,71 +421,6 @@ acpi_asus_attach(device_t dev)
led_create((led_t *)acpi_asus_led, &sc->s_wled, "wled");
}
- /* Attach brightness for GPLV/SPLV models */
- if (sc->model->brn_get && ACPI_SUCCESS(acpi_GetInteger(sc->handle,
- sc->model->brn_get, &sc->s_brn)))
- SYSCTL_ADD_PROC(&sc->sysctl_ctx,
- SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
- "lcd_brightness", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
- acpi_asus_sysctl_brn, "I", "brightness of the lcd panel");
-
- /* Attach brightness for other models */
- if (sc->model->brn_up &&
- ACPI_SUCCESS(AcpiEvaluateObject(sc->handle, sc->model->brn_up,
- NULL, NULL)) &&
- ACPI_SUCCESS(AcpiEvaluateObject(sc->handle, sc->model->brn_dn,
- NULL, NULL)))
- SYSCTL_ADD_PROC(&sc->sysctl_ctx,
- SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
- "lcd_brightness", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
- acpi_asus_sysctl_brn, "I", "brightness of the lcd panel");
-
- /* Attach display switching */
- if (sc->model->disp_get && ACPI_SUCCESS(acpi_GetInteger(sc->handle,
- sc->model->disp_get, &sc->s_disp)))
- SYSCTL_ADD_PROC(&sc->sysctl_ctx,
- SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
- "video_output", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
- acpi_asus_sysctl_disp, "I", "display output state");
-
- /* Attach LCD state, easy for most models... */
- if (sc->model->lcd_get && strncmp(sc->model->name, "L3H", 3) != 0 &&
- ACPI_SUCCESS(acpi_GetInteger(sc->handle, sc->model->lcd_get,
- &sc->s_lcd))) {
- SYSCTL_ADD_PROC(&sc->sysctl_ctx,
- SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
- "lcd_backlight", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
- acpi_asus_sysctl_lcd, "I", "state of the lcd backlight");
- } else if (sc->model->lcd_get) {
- ACPI_BUFFER Buf;
- ACPI_OBJECT Arg[2], Obj;
- ACPI_OBJECT_LIST Args;
-
- /* ...a nightmare for the L3H */
- Arg[0].Type = ACPI_TYPE_INTEGER;
- Arg[0].Integer.Value = 0x02;
- Arg[1].Type = ACPI_TYPE_INTEGER;
- Arg[1].Integer.Value = 0x03;
-
- Args.Count = 2;
- Args.Pointer = Arg;
-
- Buf.Length = sizeof(Obj);
- Buf.Pointer = &Obj;
-
- if (ACPI_SUCCESS(AcpiEvaluateObject(sc->handle,
- sc->model->lcd_get, &Args, &Buf)) &&
- Obj.Type == ACPI_TYPE_INTEGER) {
- sc->s_lcd = Obj.Integer.Value >> 8;
-
- SYSCTL_ADD_PROC(&sc->sysctl_ctx,
- SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
- "lcd_backlight", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
- acpi_asus_sysctl_lcd, "I",
- "state of the lcd backlight");
- }
- }
-
/* Activate hotkeys */
AcpiEvaluateObject(sc->handle, "BSTS", NULL, NULL);
@@ -493,138 +471,213 @@ acpi_asus_led(struct acpi_asus_led *led, int state)
sc = device_get_softc(led->dev);
switch (led->type) {
- case ACPI_ASUS_LED_MLED:
- method = sc->model->mled_set;
-
- /* Note: inverted */
- state = !state;
- break;
- case ACPI_ASUS_LED_TLED:
- method = sc->model->tled_set;
- break;
- case ACPI_ASUS_LED_WLED:
- method = sc->model->wled_set;
- break;
- default:
- printf("acpi_asus_led: invalid LED type %d\n",
- (int)led->type);
- return;
+ case ACPI_ASUS_LED_MLED:
+ method = sc->model->mled_set;
+
+ /* Note: inverted */
+ state = !state;
+ break;
+ case ACPI_ASUS_LED_TLED:
+ method = sc->model->tled_set;
+ break;
+ case ACPI_ASUS_LED_WLED:
+ method = sc->model->wled_set;
+ break;
+ default:
+ printf("acpi_asus_led: invalid LED type %d\n",
+ (int)led->type);
+ return;
}
acpi_SetInteger(sc->handle, method, state);
}
static int
-acpi_asus_sysctl_brn(SYSCTL_HANDLER_ARGS)
+acpi_asus_sysctl(SYSCTL_HANDLER_ARGS)
{
struct acpi_asus_softc *sc;
- int brn, err;
-
+ int arg;
+ int error = 0;
+ int function;
+ int method;
+
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
sc = (struct acpi_asus_softc *)oidp->oid_arg1;
+ function = oidp->oid_arg2;
+ method = acpi_asus_sysctls[function].method;
+
ACPI_SERIAL_BEGIN(asus);
+ arg = acpi_asus_sysctl_get(sc, method);
+ error = sysctl_handle_int(oidp, &arg, 0, req);
/* Sanity check */
- brn = sc->s_brn;
- err = sysctl_handle_int(oidp, &brn, 0, req);
-
- if (err != 0 || req->newptr == NULL)
+ if (error != 0 || req->newptr == NULL)
goto out;
- if (brn < 0 || brn > 15) {
- err = EINVAL;
- goto out;
- }
-
- /* Keep track and update */
- sc->s_brn = brn;
-
- if (sc->model->brn_set)
- acpi_SetInteger(sc->handle, sc->model->brn_set, brn);
- else {
- brn -= sc->s_brn;
-
- while (brn != 0) {
- AcpiEvaluateObject(sc->handle, (brn > 0) ?
- sc->model->brn_up : sc->model->brn_dn,
- NULL, NULL);
- (brn > 0) ? brn-- : brn++;
- }
- }
+ /* Update */
+ error = acpi_asus_sysctl_set(sc, method, arg);
out:
ACPI_SERIAL_END(asus);
- return (err);
+ return (error);
}
static int
-acpi_asus_sysctl_lcd(SYSCTL_HANDLER_ARGS)
+acpi_asus_sysctl_get(struct acpi_asus_softc *sc, int method)
{
- struct acpi_asus_softc *sc;
- int lcd, err;
+ int val = 0;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
-
- sc = (struct acpi_asus_softc *)oidp->oid_arg1;
- ACPI_SERIAL_BEGIN(asus);
-
- /* Sanity check */
- lcd = sc->s_lcd;
- err = sysctl_handle_int(oidp, &lcd, 0, req);
-
- if (err != 0 || req->newptr == NULL)
- goto out;
-
- if (lcd < 0 || lcd > 1) {
- err = EINVAL;
- goto out;
+ ACPI_SERIAL_ASSERT(asus);
+
+ switch (method) {
+ case ACPI_ASUS_METHOD_BRN:
+ val = sc->s_brn;
+ break;
+ case ACPI_ASUS_METHOD_DISP:
+ val = sc->s_disp;
+ break;
+ case ACPI_ASUS_METHOD_LCD:
+ val = sc->s_lcd;
+ break;
}
- /* Keep track and update */
- sc->s_lcd = lcd;
-
- /* Most models just need a lcd_set evaluated, the L3H is trickier */
- if (strncmp(sc->model->name, "L3H", 3) != 0)
- AcpiEvaluateObject(sc->handle, sc->model->lcd_set, NULL, NULL);
- else
- acpi_SetInteger(sc->handle, sc->model->lcd_set, 0x7);
-
-out:
- ACPI_SERIAL_END(asus);
- return (err);
+ return (val);
}
static int
-acpi_asus_sysctl_disp(SYSCTL_HANDLER_ARGS)
+acpi_asus_sysctl_set(struct acpi_asus_softc *sc, int method, int arg)
{
- struct acpi_asus_softc *sc;
- int disp, err;
+ ACPI_STATUS status;
ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);
+ ACPI_SERIAL_ASSERT(asus);
+
+ switch (method) {
+ case ACPI_ASUS_METHOD_BRN:
+ if (arg < 0 || arg > 15)
+ return (EINVAL);
+
+ if (sc->model->brn_set)
+ status = acpi_SetInteger(sc->handle,
+ sc->model->brn_set, arg);
+ else {
+ while (arg != 0) {
+ status = AcpiEvaluateObject(sc->handle,
+ (arg > 0) ? sc->model->brn_up :
+ sc->model->brn_dn, NULL, NULL);
+ (arg > 0) ? arg-- : arg++;
+ }
+ }
- sc = (struct acpi_asus_softc *)oidp->oid_arg1;
+ if (ACPI_SUCCESS(status))
+ sc->s_brn = arg;
- /* Sanity check */
- ACPI_SERIAL_BEGIN(asus);
- disp = sc->s_disp;
- err = sysctl_handle_int(oidp, &disp, 0, req);
+ break;
+ case ACPI_ASUS_METHOD_DISP:
+ if (arg < 0 || arg > 7)
+ return (EINVAL);
- if (err != 0 || req->newptr == NULL)
- goto out;
+ status = acpi_SetInteger(sc->handle,
+ sc->model->disp_set, arg);
- if (disp < 0 || disp > 7) {
- err = EINVAL;
- goto out;
+ if (ACPI_SUCCESS(status))
+ sc->s_disp = arg;
+
+ break;
+ case ACPI_ASUS_METHOD_LCD:
+ if (arg < 0 || arg > 1)
+ return (EINVAL);
+
+ if (strncmp(sc->model->name, "L3H", 3) != 0)
+ status = AcpiEvaluateObject(sc->handle,
+ sc->model->lcd_set, NULL, NULL);
+ else
+ status = acpi_SetInteger(sc->handle,
+ sc->model->lcd_set, 0x7);
+
+ if (ACPI_SUCCESS(status))
+ sc->s_lcd = arg;
+
+ break;
}
- /* Keep track and update */
- sc->s_disp = disp;
- acpi_SetInteger(sc->handle, sc->model->disp_set, disp);
+ return (0);
+}
-out:
- ACPI_SERIAL_END(asus);
- return (err);
+static int
+acpi_asus_sysctl_init(struct acpi_asus_softc *sc, int method)
+{
+ ACPI_STATUS status;
+
+ switch (method) {
+ case ACPI_ASUS_METHOD_BRN:
+ if (sc->model->brn_get) {
+ /* GPLV/SPLV models */
+ status = acpi_GetInteger(sc->handle,
+ sc->model->brn_get, &sc->s_brn);
+ if (ACPI_SUCCESS(status))
+ return (TRUE);
+ } else if (sc->model->brn_up) {
+ /* Relative models */
+ status = AcpiEvaluateObject(sc->handle,
+ sc->model->brn_up, NULL, NULL);
+ if (ACPI_FAILURE(status))
+ return (FALSE);
+
+ status = AcpiEvaluateObject(sc->handle,
+ sc->model->brn_dn, NULL, NULL);
+ if (ACPI_FAILURE(status))
+ return (FALSE);
+
+ return (TRUE);
+ }
+ return (FALSE);
+ case ACPI_ASUS_METHOD_DISP:
+ if (sc->model->disp_get) {
+ status = acpi_GetInteger(sc->handle,
+ sc->model->disp_get, &sc->s_disp);
+ if (ACPI_SUCCESS(status))
+ return (TRUE);
+ }
+ return (FALSE);
+ case ACPI_ASUS_METHOD_LCD:
+ if (sc->model->lcd_get &&
+ strncmp(sc->model->name, "L3H", 3) != 0) {
+ status = acpi_GetInteger(sc->handle,
+ sc->model->lcd_get, &sc->s_lcd);
+ if (ACPI_SUCCESS(status))
+ return (TRUE);
+ }
+ else if (sc->model->lcd_get) {
+ ACPI_BUFFER Buf;
+ ACPI_OBJECT Arg[2], Obj;
+ ACPI_OBJECT_LIST Args;
+
+ /* L3H is a bit special */
+ Arg[0].Type = ACPI_TYPE_INTEGER;
+ Arg[0].Integer.Value = 0x02;
+ Arg[1].Type = ACPI_TYPE_INTEGER;
+ Arg[1].Integer.Value = 0x03;
+
+ Args.Count = 2;
+ Args.Pointer = Arg;
+
+ Buf.Length = sizeof(Obj);
+ Buf.Pointer = &Obj;
+
+ status = AcpiEvaluateObject(sc->handle,
+ sc->model->lcd_get, &Args, &Buf);
+ if (ACPI_SUCCESS(status) &&
+ Obj.Type == ACPI_TYPE_INTEGER) {
+ sc->s_lcd = Obj.Integer.Value >> 8;
+ return (TRUE);
+ }
+ }
+ return (FALSE);
+ }
+ return (FALSE);
}
static void
OpenPOWER on IntegriCloud