From 8c851e2796af253e4025f9c4d975a7f56ab85c97 Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Wed, 22 Jul 2015 19:26:32 +0200
Subject: [PATCH] kernel/acpi_toshiba: WIP

---
 sys/dev/acpica/acpi_toshiba/acpi_toshiba.c | 67 ++++++++++++++++++++----------
 1 file changed, 44 insertions(+), 23 deletions(-)

diff --git a/sys/dev/acpica/acpi_toshiba/acpi_toshiba.c b/sys/dev/acpica/acpi_toshiba/acpi_toshiba.c
index c58c707..67fe025 100644
--- a/sys/dev/acpica/acpi_toshiba/acpi_toshiba.c
+++ b/sys/dev/acpica/acpi_toshiba/acpi_toshiba.c
@@ -51,6 +51,7 @@ ACPI_MODULE_NAME("Toshiba")
  */
 
 #define METHOD_HCI		"GHCI"
+#define METHOD_HCI2		"SPFC"
 #define METHOD_HCI_ENABLE	"ENAB"
 #define METHOD_VIDEO		"DSSX"
 
@@ -125,12 +126,13 @@ struct acpi_toshiba_softc {
 	device_t	dev;
 	ACPI_HANDLE	handle;
 	ACPI_HANDLE	video_handle;
+	char		*method_hci;
 	struct		sysctl_ctx_list sysctl_ctx;
 	struct		sysctl_oid *sysctl_tree;
 };
 
 /* Prototype for HCI functions for getting/setting a value. */
-typedef int	hci_fn_t(ACPI_HANDLE, int, UINT32 *);
+typedef int	hci_fn_t(struct acpi_toshiba_softc *, int, UINT32 *);
 
 static int	acpi_toshiba_probe(device_t dev);
 static int	acpi_toshiba_attach(device_t dev);
@@ -141,7 +143,8 @@ static hci_fn_t	hci_video_output;
 static hci_fn_t	hci_lcd_brightness;
 static hci_fn_t	hci_lcd_backlight;
 static hci_fn_t	hci_cpu_speed;
-static int	hci_call(ACPI_HANDLE h, int op, int function, UINT32 *arg);
+static int	hci_call(struct acpi_toshiba_softc *sc, int op, int function,
+		    UINT32 *arg);
 static void	hci_key_action(struct acpi_toshiba_softc *sc, ACPI_HANDLE h,
 		    UINT32 key);
 static void	acpi_toshiba_notify(ACPI_HANDLE h, UINT32 notify,
@@ -217,7 +220,8 @@ TUNABLE_INT("hw.acpi.toshiba.enable_fn_keys", &enable_fn_keys);
 static int
 acpi_toshiba_probe(device_t dev)
 {
-	static char *tosh_ids[] = { "TOS6200", "TOS6207", "TOS6208", NULL };
+	static char *tosh_ids[] = { "TOS1900", "TOS6200", "TOS6207", "TOS6208",
+				    NULL };
 
 	if (acpi_disabled("toshiba") ||
 	    ACPI_ID_PROBE(device_get_parent(dev), dev, tosh_ids) == NULL ||
@@ -234,6 +238,7 @@ acpi_toshiba_attach(device_t dev)
 	struct		acpi_toshiba_softc *sc;
 	struct		acpi_softc *acpi_sc;
 	ACPI_STATUS	status;
+	ACPI_HANDLE	h;
 	int		i;
 
 	sc = device_get_softc(dev);
@@ -241,6 +246,19 @@ acpi_toshiba_attach(device_t dev)
 	sc->handle = acpi_get_handle(dev);
 	ACPI_SERIAL_INIT(toshiba);
 
+	status = AcpiGetHandle(sc->handle, METHOD_HCI, &h);
+	if (ACPI_FAILURE(status)) {
+		status = AcpiGetHandle(sc->handle, METHOD_HCI2, &h);
+		if (ACPI_FAILURE(status)) {
+			device_printf(dev, "no HCI method found\n");
+			return (ENXIO);
+		} else {
+			sc->method_hci = METHOD_HCI2;
+		}
+	} else {
+		sc->method_hci = METHOD_HCI;
+	}
+
 	acpi_sc = acpi_device_get_parent_softc(dev);
 	sysctl_ctx_init(&sc->sysctl_ctx);
 	sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
@@ -299,7 +317,7 @@ acpi_toshiba_sysctl(SYSCTL_HANDLER_ARGS)
 
 	/* Get the current value from the appropriate function. */
 	ACPI_SERIAL_BEGIN(toshiba);
-	error = handler(sc->handle, HCI_GET, &arg);
+	error = handler(sc, HCI_GET, &arg);
 	if (error != 0)
 		goto out;
 
@@ -317,7 +335,7 @@ out:
 }
 
 static int
-hci_force_fan(ACPI_HANDLE h, int op, UINT32 *state)
+hci_force_fan(struct acpi_toshiba_softc *sc, int op, UINT32 *state)
 {
 	int		ret;
 
@@ -327,14 +345,14 @@ hci_force_fan(ACPI_HANDLE h, int op, UINT32 *state)
 			return (EINVAL);
 		*state <<= HCI_FAN_SHIFT;
 	}
-	ret = hci_call(h, op, HCI_REG_FAN, state);
+	ret = hci_call(sc, op, HCI_REG_FAN, state);
 	if (ret == 0 && op == HCI_GET)
 		*state >>= HCI_FAN_SHIFT;
 	return (ret);
 }
 
 static int
-hci_video_output(ACPI_HANDLE h, int op, UINT32 *video_output)
+hci_video_output(struct acpi_toshiba_softc *sc, int op, UINT32 *video_output)
 {
 	int		ret;
 	ACPI_STATUS	status;
@@ -343,16 +361,16 @@ hci_video_output(ACPI_HANDLE h, int op, UINT32 *video_output)
 	if (op == HCI_SET) {
 		if (*video_output < 1 || *video_output > 7)
 			return (EINVAL);
-		if (h == NULL)
+		if (sc->handle == NULL)
 			return (ENXIO);
 		*video_output |= HCI_VIDEO_OUTPUT_FLAG;
-		status = acpi_SetInteger(h, METHOD_VIDEO, *video_output);
+		status = acpi_SetInteger(sc->handle, METHOD_VIDEO, *video_output);
 		if (ACPI_SUCCESS(status))
 			ret = 0;
 		else
 			ret = ENXIO;
 	} else {
-		ret = hci_call(h, op, HCI_REG_VIDEO_OUTPUT, video_output);
+		ret = hci_call(sc, op, HCI_REG_VIDEO_OUTPUT, video_output);
 		if (ret == 0)
 			*video_output &= 0xff;
 	}
@@ -361,7 +379,7 @@ hci_video_output(ACPI_HANDLE h, int op, UINT32 *video_output)
 }
 
 static int
-hci_lcd_brightness(ACPI_HANDLE h, int op, UINT32 *brightness)
+hci_lcd_brightness(struct acpi_toshiba_softc *sc, int op, UINT32 *brightness)
 {
 	int		ret;
 
@@ -371,14 +389,14 @@ hci_lcd_brightness(ACPI_HANDLE h, int op, UINT32 *brightness)
 			return (EINVAL);
 		*brightness <<= HCI_LCD_BRIGHTNESS_SHIFT;
 	}
-	ret = hci_call(h, op, HCI_REG_LCD_BRIGHTNESS, brightness);
+	ret = hci_call(sc, op, HCI_REG_LCD_BRIGHTNESS, brightness);
 	if (ret == 0 && op == HCI_GET)
 		*brightness >>= HCI_LCD_BRIGHTNESS_SHIFT;
 	return (ret);
 }
 
 static int
-hci_lcd_backlight(ACPI_HANDLE h, int op, UINT32 *backlight)
+hci_lcd_backlight(struct acpi_toshiba_softc *sc, int op, UINT32 *backlight)
 {
 
 	ACPI_SERIAL_ASSERT(toshiba);
@@ -386,11 +404,11 @@ hci_lcd_backlight(ACPI_HANDLE h, int op, UINT32 *backlight)
 		if (*backlight < 0 || *backlight > 1)
 			return (EINVAL);
 	}
-	return (hci_call(h, op, HCI_REG_LCD_BACKLIGHT, backlight));
+	return (hci_call(sc, op, HCI_REG_LCD_BACKLIGHT, backlight));
 }
 
 static int
-hci_cpu_speed(ACPI_HANDLE h, int op, UINT32 *speed)
+hci_cpu_speed(struct acpi_toshiba_softc *sc, int op, UINT32 *speed)
 {
 	int		ret;
 
@@ -400,23 +418,24 @@ hci_cpu_speed(ACPI_HANDLE h, int op, UINT32 *speed)
 			return (EINVAL);
 		*speed <<= HCI_CPU_SPEED_SHIFT;
 	}
-	ret = hci_call(h, op, HCI_REG_CPU_SPEED, speed);
+	ret = hci_call(sc, op, HCI_REG_CPU_SPEED, speed);
 	if (ret == 0 && op == HCI_GET)
 		*speed >>= HCI_CPU_SPEED_SHIFT;
 	return (ret);
 }
 
 static int
-hci_call(ACPI_HANDLE h, int op, int function, UINT32 *arg)
+hci_call(struct acpi_toshiba_softc *sc, int op, int function, UINT32 *arg)
 {
 	ACPI_OBJECT_LIST args;
 	ACPI_BUFFER	results;
 	ACPI_OBJECT	obj[HCI_WORDS];
 	ACPI_OBJECT	*res;
-	int		status, i, ret;
+	ACPI_STATUS	status;
+	int		error, i, ret;
 
 	ACPI_SERIAL_ASSERT(toshiba);
-	status = ENXIO;
+	error = ENXIO;
 
 	for (i = 0; i < HCI_WORDS; i++) {
 		obj[i].Type = ACPI_TYPE_INTEGER;
@@ -431,7 +450,9 @@ hci_call(ACPI_HANDLE h, int op, int function, UINT32 *arg)
 	args.Pointer = obj;
 	results.Pointer = NULL;
 	results.Length = ACPI_ALLOCATE_BUFFER;
-	if (ACPI_FAILURE(AcpiEvaluateObject(h, METHOD_HCI, &args, &results)))
+	status = AcpiEvaluateObject(sc->handle, sc->method_hci, &args,
+	    &results);
+	if (ACPI_FAILURE(status))
 		goto end;
 	res = (ACPI_OBJECT *)results.Pointer;
 	if (!ACPI_PKG_VALID(res, HCI_WORDS)) {
@@ -443,7 +464,7 @@ hci_call(ACPI_HANDLE h, int op, int function, UINT32 *arg)
 	if (ret == HCI_SUCCESS) {
 		if (op == HCI_GET)
 			acpi_PkgInt32(res, HCI_REG_CX, arg);
-		status = 0;
+		error = 0;
 	} else if (function == HCI_REG_SYSTEM_EVENT && op == HCI_GET &&
 	    ret == HCI_NOT_SUPPORTED) {
 		/*
@@ -454,14 +475,14 @@ hci_call(ACPI_HANDLE h, int op, int function, UINT32 *arg)
 		 * a task via AcpiOsQueueForExecution() might be better.
 		 */
 		 i = 1;
-		 hci_call(h, HCI_SET, HCI_REG_SYSTEM_EVENT, &i);
+		 hci_call(sc, HCI_SET, HCI_REG_SYSTEM_EVENT, &i);
 	}
 
 end:
 	if (results.Pointer != NULL)
 		AcpiOsFree(results.Pointer);
 
-	return (status);
+	return (error);
 }
 
 /*
-- 
2.3.7

