Add support for video output switching. It appears no systems use HCI to
change the video output but use a separate device with a DSSX method and a HID of "TOS6201" instead. We use a pseudo-driver to get the handle for this object and pass it to the acpi_toshiba driver. This is untested but seems to match the Linux Toshiba driver.
This commit is contained in:
parent
c7141791f3
commit
0287be96bf
@ -64,6 +64,12 @@ CRT
|
||||
.It Li 4
|
||||
TV-Out
|
||||
.El
|
||||
.Pp
|
||||
Only some systems (i.e., the Libretto L5) support video switching via
|
||||
this hardware-specific driver.
|
||||
Use the
|
||||
.Xr acpi_video 4
|
||||
driver for generic video output support.
|
||||
.It Va hw.acpi.toshiba.lcd_brightness
|
||||
Makes the LCD backlight brighter or dimmer (higher values are brighter).
|
||||
.It Va hw.acpi.toshiba.lcd_backlight
|
||||
@ -91,6 +97,7 @@ prompt or in
|
||||
.Xr loader.conf 5 .
|
||||
.Sh SEE ALSO
|
||||
.Xr acpi 4 ,
|
||||
.Xr acpi_video 4 ,
|
||||
.Xr loader.conf 5 ,
|
||||
.Xr sysctl.conf 5 ,
|
||||
.Xr sysctl 8
|
||||
|
@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define METHOD_HCI "GHCI"
|
||||
#define METHOD_HCI_ENABLE "ENAB"
|
||||
#define METHOD_VIDEO "DSSX"
|
||||
|
||||
/* Operations */
|
||||
#define HCI_SET 0xFF00
|
||||
@ -120,6 +121,7 @@ __FBSDID("$FreeBSD$");
|
||||
struct acpi_toshiba_softc {
|
||||
device_t dev;
|
||||
ACPI_HANDLE handle;
|
||||
ACPI_HANDLE video_handle;
|
||||
struct sysctl_ctx_list sysctl_ctx;
|
||||
struct sysctl_oid *sysctl_tree;
|
||||
};
|
||||
@ -137,9 +139,12 @@ 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 void hci_key_action(ACPI_HANDLE h, UINT32 key);
|
||||
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,
|
||||
void *context);
|
||||
void *context);
|
||||
static int acpi_toshiba_video_probe(device_t dev);
|
||||
static int acpi_toshiba_video_attach(device_t dev);
|
||||
|
||||
/* Table of sysctl names and HCI functions to call. */
|
||||
static struct {
|
||||
@ -171,9 +176,27 @@ static driver_t acpi_toshiba_driver = {
|
||||
|
||||
static devclass_t acpi_toshiba_devclass;
|
||||
DRIVER_MODULE(acpi_toshiba, acpi, acpi_toshiba_driver, acpi_toshiba_devclass,
|
||||
0, 0);
|
||||
0, 0);
|
||||
MODULE_DEPEND(acpi_toshiba, acpi, 1, 1, 1);
|
||||
|
||||
static device_method_t acpi_toshiba_video_methods[] = {
|
||||
DEVMETHOD(device_probe, acpi_toshiba_video_probe),
|
||||
DEVMETHOD(device_attach, acpi_toshiba_video_attach),
|
||||
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static driver_t acpi_toshiba_video_driver = {
|
||||
"acpi_toshiba_video",
|
||||
acpi_toshiba_video_methods,
|
||||
0,
|
||||
};
|
||||
|
||||
static devclass_t acpi_toshiba_video_devclass;
|
||||
DRIVER_MODULE(acpi_toshiba_video, acpi, acpi_toshiba_video_driver,
|
||||
acpi_toshiba_video_devclass, 0, 0);
|
||||
MODULE_DEPEND(acpi_toshiba_video, acpi, 1, 1, 1);
|
||||
|
||||
static int enable_fn_keys = 1;
|
||||
TUNABLE_INT("hw.acpi.toshiba.enable_fn_keys", &enable_fn_keys);
|
||||
|
||||
@ -306,15 +329,25 @@ static int
|
||||
hci_video_output(ACPI_HANDLE h, int op, UINT32 *video_output)
|
||||
{
|
||||
int ret;
|
||||
ACPI_STATUS status;
|
||||
|
||||
if (op == HCI_SET) {
|
||||
if (*video_output < 1 || *video_output > 7)
|
||||
return (EINVAL);
|
||||
if (h == NULL)
|
||||
return (ENXIO);
|
||||
*video_output |= HCI_VIDEO_OUTPUT_FLAG;
|
||||
status = acpi_SetInteger(h, "DSSX", *video_output);
|
||||
if (ACPI_SUCCESS(status))
|
||||
ret = 0;
|
||||
else
|
||||
ret = ENXIO;
|
||||
} else {
|
||||
ret = hci_call(h, op, HCI_REG_VIDEO_OUTPUT, video_output);
|
||||
if (ret == 0)
|
||||
*video_output &= 0xff;
|
||||
}
|
||||
ret = hci_call(h, op, HCI_REG_VIDEO_OUTPUT, video_output);
|
||||
if (ret == 0 && op == HCI_GET)
|
||||
*video_output &= 0xff;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -419,7 +452,7 @@ end:
|
||||
* functionality by reading the keystrokes we send to devd(8).
|
||||
*/
|
||||
static void
|
||||
hci_key_action(ACPI_HANDLE h, UINT32 key)
|
||||
hci_key_action(struct acpi_toshiba_softc *sc, ACPI_HANDLE h, UINT32 key)
|
||||
{
|
||||
UINT32 arg;
|
||||
|
||||
@ -444,7 +477,7 @@ hci_key_action(ACPI_HANDLE h, UINT32 key)
|
||||
/* Cycle through video outputs. */
|
||||
hci_video_output(h, HCI_GET, &arg);
|
||||
arg = (arg + 1) % 7;
|
||||
hci_video_output(h, HCI_SET, &arg);
|
||||
hci_video_output(sc->video_handle, HCI_SET, &arg);
|
||||
break;
|
||||
case FN_F8_RELEASE:
|
||||
/* Toggle LCD backlight. */
|
||||
@ -471,10 +504,45 @@ acpi_toshiba_notify(ACPI_HANDLE h, UINT32 notify, void *context)
|
||||
|
||||
if (notify == 0x80) {
|
||||
while (hci_call(h, HCI_GET, HCI_REG_SYSTEM_EVENT, &key) == 0) {
|
||||
hci_key_action(h, key);
|
||||
hci_key_action(sc, h, key);
|
||||
acpi_UserNotify("TOSHIBA", h, (uint8_t)key);
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
device_printf(sc->dev, "unknown notify: 0x%x\n", notify);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Toshiba video pseudo-device to provide the DSSX method.
|
||||
*
|
||||
* HID Model
|
||||
* -------------------------------------
|
||||
* TOS6201 Libretto L Series
|
||||
*/
|
||||
static int
|
||||
acpi_toshiba_video_probe(device_t dev)
|
||||
{
|
||||
int ret = ENXIO;
|
||||
|
||||
if (!acpi_disabled("toshiba") &&
|
||||
acpi_get_type(dev) == ACPI_TYPE_DEVICE &&
|
||||
device_get_unit(dev) == 0 &&
|
||||
acpi_MatchHid(dev, "TOS6201")) {
|
||||
device_quiet(dev);
|
||||
device_set_desc(dev, "Toshiba Video");
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_toshiba_video_attach(device_t dev)
|
||||
{
|
||||
struct acpi_toshiba_softc *sc;
|
||||
|
||||
sc = devclass_get_softc(acpi_toshiba_devclass, 0);
|
||||
if (sc == NULL)
|
||||
return (ENXIO);
|
||||
sc->video_handle = acpi_get_handle(dev);
|
||||
return (0);
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define METHOD_HCI "GHCI"
|
||||
#define METHOD_HCI_ENABLE "ENAB"
|
||||
#define METHOD_VIDEO "DSSX"
|
||||
|
||||
/* Operations */
|
||||
#define HCI_SET 0xFF00
|
||||
@ -120,6 +121,7 @@ __FBSDID("$FreeBSD$");
|
||||
struct acpi_toshiba_softc {
|
||||
device_t dev;
|
||||
ACPI_HANDLE handle;
|
||||
ACPI_HANDLE video_handle;
|
||||
struct sysctl_ctx_list sysctl_ctx;
|
||||
struct sysctl_oid *sysctl_tree;
|
||||
};
|
||||
@ -137,9 +139,12 @@ 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 void hci_key_action(ACPI_HANDLE h, UINT32 key);
|
||||
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,
|
||||
void *context);
|
||||
void *context);
|
||||
static int acpi_toshiba_video_probe(device_t dev);
|
||||
static int acpi_toshiba_video_attach(device_t dev);
|
||||
|
||||
/* Table of sysctl names and HCI functions to call. */
|
||||
static struct {
|
||||
@ -171,9 +176,27 @@ static driver_t acpi_toshiba_driver = {
|
||||
|
||||
static devclass_t acpi_toshiba_devclass;
|
||||
DRIVER_MODULE(acpi_toshiba, acpi, acpi_toshiba_driver, acpi_toshiba_devclass,
|
||||
0, 0);
|
||||
0, 0);
|
||||
MODULE_DEPEND(acpi_toshiba, acpi, 1, 1, 1);
|
||||
|
||||
static device_method_t acpi_toshiba_video_methods[] = {
|
||||
DEVMETHOD(device_probe, acpi_toshiba_video_probe),
|
||||
DEVMETHOD(device_attach, acpi_toshiba_video_attach),
|
||||
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static driver_t acpi_toshiba_video_driver = {
|
||||
"acpi_toshiba_video",
|
||||
acpi_toshiba_video_methods,
|
||||
0,
|
||||
};
|
||||
|
||||
static devclass_t acpi_toshiba_video_devclass;
|
||||
DRIVER_MODULE(acpi_toshiba_video, acpi, acpi_toshiba_video_driver,
|
||||
acpi_toshiba_video_devclass, 0, 0);
|
||||
MODULE_DEPEND(acpi_toshiba_video, acpi, 1, 1, 1);
|
||||
|
||||
static int enable_fn_keys = 1;
|
||||
TUNABLE_INT("hw.acpi.toshiba.enable_fn_keys", &enable_fn_keys);
|
||||
|
||||
@ -306,15 +329,25 @@ static int
|
||||
hci_video_output(ACPI_HANDLE h, int op, UINT32 *video_output)
|
||||
{
|
||||
int ret;
|
||||
ACPI_STATUS status;
|
||||
|
||||
if (op == HCI_SET) {
|
||||
if (*video_output < 1 || *video_output > 7)
|
||||
return (EINVAL);
|
||||
if (h == NULL)
|
||||
return (ENXIO);
|
||||
*video_output |= HCI_VIDEO_OUTPUT_FLAG;
|
||||
status = acpi_SetInteger(h, "DSSX", *video_output);
|
||||
if (ACPI_SUCCESS(status))
|
||||
ret = 0;
|
||||
else
|
||||
ret = ENXIO;
|
||||
} else {
|
||||
ret = hci_call(h, op, HCI_REG_VIDEO_OUTPUT, video_output);
|
||||
if (ret == 0)
|
||||
*video_output &= 0xff;
|
||||
}
|
||||
ret = hci_call(h, op, HCI_REG_VIDEO_OUTPUT, video_output);
|
||||
if (ret == 0 && op == HCI_GET)
|
||||
*video_output &= 0xff;
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -419,7 +452,7 @@ end:
|
||||
* functionality by reading the keystrokes we send to devd(8).
|
||||
*/
|
||||
static void
|
||||
hci_key_action(ACPI_HANDLE h, UINT32 key)
|
||||
hci_key_action(struct acpi_toshiba_softc *sc, ACPI_HANDLE h, UINT32 key)
|
||||
{
|
||||
UINT32 arg;
|
||||
|
||||
@ -444,7 +477,7 @@ hci_key_action(ACPI_HANDLE h, UINT32 key)
|
||||
/* Cycle through video outputs. */
|
||||
hci_video_output(h, HCI_GET, &arg);
|
||||
arg = (arg + 1) % 7;
|
||||
hci_video_output(h, HCI_SET, &arg);
|
||||
hci_video_output(sc->video_handle, HCI_SET, &arg);
|
||||
break;
|
||||
case FN_F8_RELEASE:
|
||||
/* Toggle LCD backlight. */
|
||||
@ -471,10 +504,45 @@ acpi_toshiba_notify(ACPI_HANDLE h, UINT32 notify, void *context)
|
||||
|
||||
if (notify == 0x80) {
|
||||
while (hci_call(h, HCI_GET, HCI_REG_SYSTEM_EVENT, &key) == 0) {
|
||||
hci_key_action(h, key);
|
||||
hci_key_action(sc, h, key);
|
||||
acpi_UserNotify("TOSHIBA", h, (uint8_t)key);
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
device_printf(sc->dev, "unknown notify: 0x%x\n", notify);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Toshiba video pseudo-device to provide the DSSX method.
|
||||
*
|
||||
* HID Model
|
||||
* -------------------------------------
|
||||
* TOS6201 Libretto L Series
|
||||
*/
|
||||
static int
|
||||
acpi_toshiba_video_probe(device_t dev)
|
||||
{
|
||||
int ret = ENXIO;
|
||||
|
||||
if (!acpi_disabled("toshiba") &&
|
||||
acpi_get_type(dev) == ACPI_TYPE_DEVICE &&
|
||||
device_get_unit(dev) == 0 &&
|
||||
acpi_MatchHid(dev, "TOS6201")) {
|
||||
device_quiet(dev);
|
||||
device_set_desc(dev, "Toshiba Video");
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
acpi_toshiba_video_attach(device_t dev)
|
||||
{
|
||||
struct acpi_toshiba_softc *sc;
|
||||
|
||||
sc = devclass_get_softc(acpi_toshiba_devclass, 0);
|
||||
if (sc == NULL)
|
||||
return (ENXIO);
|
||||
sc->video_handle = acpi_get_handle(dev);
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user