MFC: r197438, r203810, r203813, r203935, r203936
Sync acpi_video(4) with HEAD. r197438: Uninline an instance of STAILQ_FOREACH_SAFE(). r203810: Implement LCD brightness control notify handler. r203813: Make sanity check slightly more useful and tweak an error message. r203935: Add support for `cycle' and `zero' events for LCD brightness control. r203936: Rename some macros to clarify their intentions and fix style nits.
This commit is contained in:
parent
50819829d3
commit
0cd9e69dae
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/stable/8/; revision=204963
@ -83,6 +83,7 @@ static struct acpi_video_output *acpi_video_vo_init(UINT32);
|
|||||||
static void acpi_video_vo_bind(struct acpi_video_output *, ACPI_HANDLE);
|
static void acpi_video_vo_bind(struct acpi_video_output *, ACPI_HANDLE);
|
||||||
static void acpi_video_vo_destroy(struct acpi_video_output *);
|
static void acpi_video_vo_destroy(struct acpi_video_output *);
|
||||||
static int acpi_video_vo_check_level(struct acpi_video_output *, int);
|
static int acpi_video_vo_check_level(struct acpi_video_output *, int);
|
||||||
|
static void acpi_video_vo_notify_handler(ACPI_HANDLE, UINT32, void *);
|
||||||
static int acpi_video_vo_active_sysctl(SYSCTL_HANDLER_ARGS);
|
static int acpi_video_vo_active_sysctl(SYSCTL_HANDLER_ARGS);
|
||||||
static int acpi_video_vo_bright_sysctl(SYSCTL_HANDLER_ARGS);
|
static int acpi_video_vo_bright_sysctl(SYSCTL_HANDLER_ARGS);
|
||||||
static int acpi_video_vo_presets_sysctl(SYSCTL_HANDLER_ARGS);
|
static int acpi_video_vo_presets_sysctl(SYSCTL_HANDLER_ARGS);
|
||||||
@ -93,56 +94,61 @@ static void vid_set_switch_policy(ACPI_HANDLE, UINT32);
|
|||||||
static int vid_enum_outputs(ACPI_HANDLE,
|
static int vid_enum_outputs(ACPI_HANDLE,
|
||||||
void(*)(ACPI_HANDLE, UINT32, void *), void *);
|
void(*)(ACPI_HANDLE, UINT32, void *), void *);
|
||||||
static int vo_get_brightness_levels(ACPI_HANDLE, int **);
|
static int vo_get_brightness_levels(ACPI_HANDLE, int **);
|
||||||
|
static int vo_get_brightness(ACPI_HANDLE);
|
||||||
static void vo_set_brightness(ACPI_HANDLE, int);
|
static void vo_set_brightness(ACPI_HANDLE, int);
|
||||||
static UINT32 vo_get_device_status(ACPI_HANDLE);
|
static UINT32 vo_get_device_status(ACPI_HANDLE);
|
||||||
static UINT32 vo_get_graphics_state(ACPI_HANDLE);
|
static UINT32 vo_get_graphics_state(ACPI_HANDLE);
|
||||||
static void vo_set_device_state(ACPI_HANDLE, UINT32);
|
static void vo_set_device_state(ACPI_HANDLE, UINT32);
|
||||||
|
|
||||||
/* events */
|
/* events */
|
||||||
#define VID_NOTIFY_SWITCHED 0x80
|
#define VID_NOTIFY_SWITCHED 0x80
|
||||||
#define VID_NOTIFY_REPROBE 0x81
|
#define VID_NOTIFY_REPROBE 0x81
|
||||||
|
#define VID_NOTIFY_CYCLE_BRN 0x85
|
||||||
|
#define VID_NOTIFY_INC_BRN 0x86
|
||||||
|
#define VID_NOTIFY_DEC_BRN 0x87
|
||||||
|
#define VID_NOTIFY_ZERO_BRN 0x88
|
||||||
|
|
||||||
/* _DOS (Enable/Disable Output Switching) argument bits */
|
/* _DOS (Enable/Disable Output Switching) argument bits */
|
||||||
#define DOS_SWITCH_MASK 3
|
#define DOS_SWITCH_MASK 3
|
||||||
#define DOS_SWITCH_BY_OSPM 0
|
#define DOS_SWITCH_BY_OSPM 0
|
||||||
#define DOS_SWITCH_BY_BIOS 1
|
#define DOS_SWITCH_BY_BIOS 1
|
||||||
#define DOS_SWITCH_LOCKED 2
|
#define DOS_SWITCH_LOCKED 2
|
||||||
#define DOS_BRIGHTNESS_BY_BIOS (1 << 2)
|
#define DOS_BRIGHTNESS_BY_OSPM (1 << 2)
|
||||||
|
|
||||||
/* _DOD and subdev's _ADR */
|
/* _DOD and subdev's _ADR */
|
||||||
#define DOD_DEVID_MASK 0x0f00
|
#define DOD_DEVID_MASK 0x0f00
|
||||||
#define DOD_DEVID_MASK_FULL 0xffff
|
#define DOD_DEVID_MASK_FULL 0xffff
|
||||||
#define DOD_DEVID_MASK_DISPIDX 0x000f
|
#define DOD_DEVID_MASK_DISPIDX 0x000f
|
||||||
#define DOD_DEVID_MASK_DISPPORT 0x00f0
|
#define DOD_DEVID_MASK_DISPPORT 0x00f0
|
||||||
#define DOD_DEVID_MONITOR 0x0100
|
#define DOD_DEVID_MONITOR 0x0100
|
||||||
#define DOD_DEVID_LCD 0x0110
|
#define DOD_DEVID_LCD 0x0110
|
||||||
#define DOD_DEVID_TV 0x0200
|
#define DOD_DEVID_TV 0x0200
|
||||||
#define DOD_DEVID_EXT 0x0300
|
#define DOD_DEVID_EXT 0x0300
|
||||||
#define DOD_DEVID_INTDFP 0x0400
|
#define DOD_DEVID_INTDFP 0x0400
|
||||||
#define DOD_BIOS (1 << 16)
|
#define DOD_BIOS (1 << 16)
|
||||||
#define DOD_NONVGA (1 << 17)
|
#define DOD_NONVGA (1 << 17)
|
||||||
#define DOD_HEAD_ID_SHIFT 18
|
#define DOD_HEAD_ID_SHIFT 18
|
||||||
#define DOD_HEAD_ID_BITS 3
|
#define DOD_HEAD_ID_BITS 3
|
||||||
#define DOD_HEAD_ID_MASK \
|
#define DOD_HEAD_ID_MASK \
|
||||||
(((1 << DOD_HEAD_ID_BITS) - 1) << DOD_HEAD_ID_SHIFT)
|
(((1 << DOD_HEAD_ID_BITS) - 1) << DOD_HEAD_ID_SHIFT)
|
||||||
#define DOD_DEVID_SCHEME_STD (1 << 31)
|
#define DOD_DEVID_SCHEME_STD (1 << 31)
|
||||||
|
|
||||||
/* _BCL related constants */
|
/* _BCL related constants */
|
||||||
#define BCL_FULLPOWER 0
|
#define BCL_FULLPOWER 0
|
||||||
#define BCL_ECONOMY 1
|
#define BCL_ECONOMY 1
|
||||||
|
|
||||||
/* _DCS (Device Currrent Status) value bits and masks. */
|
/* _DCS (Device Currrent Status) value bits and masks. */
|
||||||
#define DCS_EXISTS (1 << 0)
|
#define DCS_EXISTS (1 << 0)
|
||||||
#define DCS_ACTIVE (1 << 1)
|
#define DCS_ACTIVE (1 << 1)
|
||||||
#define DCS_READY (1 << 2)
|
#define DCS_READY (1 << 2)
|
||||||
#define DCS_FUNCTIONAL (1 << 3)
|
#define DCS_FUNCTIONAL (1 << 3)
|
||||||
#define DCS_ATTACHED (1 << 4)
|
#define DCS_ATTACHED (1 << 4)
|
||||||
|
|
||||||
/* _DSS (Device Set Status) argument bits and masks. */
|
/* _DSS (Device Set Status) argument bits and masks. */
|
||||||
#define DSS_INACTIVE 0
|
#define DSS_INACTIVE 0
|
||||||
#define DSS_ACTIVE (1 << 0)
|
#define DSS_ACTIVE (1 << 0)
|
||||||
#define DSS_SETNEXT (1 << 30)
|
#define DSS_SETNEXT (1 << 30)
|
||||||
#define DSS_COMMIT (1 << 31)
|
#define DSS_COMMIT (1 << 31)
|
||||||
|
|
||||||
static device_method_t acpi_video_methods[] = {
|
static device_method_t acpi_video_methods[] = {
|
||||||
DEVMETHOD(device_identify, acpi_video_identify),
|
DEVMETHOD(device_identify, acpi_video_identify),
|
||||||
@ -269,7 +275,7 @@ acpi_video_attach(device_t dev)
|
|||||||
* brightness levels.
|
* brightness levels.
|
||||||
*/
|
*/
|
||||||
vid_set_switch_policy(sc->handle, DOS_SWITCH_BY_OSPM |
|
vid_set_switch_policy(sc->handle, DOS_SWITCH_BY_OSPM |
|
||||||
DOS_BRIGHTNESS_BY_BIOS);
|
DOS_BRIGHTNESS_BY_OSPM);
|
||||||
|
|
||||||
acpi_video_power_profile(sc);
|
acpi_video_power_profile(sc);
|
||||||
|
|
||||||
@ -290,8 +296,7 @@ acpi_video_detach(device_t dev)
|
|||||||
acpi_video_notify_handler);
|
acpi_video_notify_handler);
|
||||||
|
|
||||||
ACPI_SERIAL_BEGIN(video);
|
ACPI_SERIAL_BEGIN(video);
|
||||||
for (vo = STAILQ_FIRST(&sc->vid_outputs); vo != NULL; vo = vn) {
|
STAILQ_FOREACH_SAFE(vo, &sc->vid_outputs, vo_next, vn) {
|
||||||
vn = STAILQ_NEXT(vo, vo_next);
|
|
||||||
acpi_video_vo_destroy(vo);
|
acpi_video_vo_destroy(vo);
|
||||||
}
|
}
|
||||||
ACPI_SERIAL_END(video);
|
ACPI_SERIAL_END(video);
|
||||||
@ -578,6 +583,9 @@ acpi_video_vo_bind(struct acpi_video_output *vo, ACPI_HANDLE handle)
|
|||||||
/* XXX - see above. */
|
/* XXX - see above. */
|
||||||
vo->vo_economy = vo->vo_levels[BCL_ECONOMY];
|
vo->vo_economy = vo->vo_levels[BCL_ECONOMY];
|
||||||
}
|
}
|
||||||
|
if (vo->vo_levels != NULL)
|
||||||
|
AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY,
|
||||||
|
acpi_video_vo_notify_handler, vo);
|
||||||
ACPI_SERIAL_END(video_output);
|
ACPI_SERIAL_END(video_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -591,8 +599,11 @@ acpi_video_vo_destroy(struct acpi_video_output *vo)
|
|||||||
vo->vo_sysctl_tree = NULL;
|
vo->vo_sysctl_tree = NULL;
|
||||||
sysctl_ctx_free(&vo->vo_sysctl_ctx);
|
sysctl_ctx_free(&vo->vo_sysctl_ctx);
|
||||||
}
|
}
|
||||||
if (vo->vo_levels != NULL)
|
if (vo->vo_levels != NULL) {
|
||||||
|
AcpiRemoveNotifyHandler(vo->handle, ACPI_DEVICE_NOTIFY,
|
||||||
|
acpi_video_vo_notify_handler);
|
||||||
AcpiOsFree(vo->vo_levels);
|
AcpiOsFree(vo->vo_levels);
|
||||||
|
}
|
||||||
|
|
||||||
switch (vo->adr & DOD_DEVID_MASK) {
|
switch (vo->adr & DOD_DEVID_MASK) {
|
||||||
case DOD_DEVID_MONITOR:
|
case DOD_DEVID_MONITOR:
|
||||||
@ -628,6 +639,79 @@ acpi_video_vo_check_level(struct acpi_video_output *vo, int level)
|
|||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
acpi_video_vo_notify_handler(ACPI_HANDLE handle, UINT32 notify, void *context)
|
||||||
|
{
|
||||||
|
struct acpi_video_output *vo;
|
||||||
|
int i, j, level, new_level;
|
||||||
|
|
||||||
|
vo = context;
|
||||||
|
ACPI_SERIAL_BEGIN(video_output);
|
||||||
|
if (vo->handle != handle)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
switch (notify) {
|
||||||
|
case VID_NOTIFY_CYCLE_BRN:
|
||||||
|
if (vo->vo_numlevels <= 3)
|
||||||
|
goto out;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case VID_NOTIFY_INC_BRN:
|
||||||
|
case VID_NOTIFY_DEC_BRN:
|
||||||
|
case VID_NOTIFY_ZERO_BRN:
|
||||||
|
if (vo->vo_levels == NULL)
|
||||||
|
goto out;
|
||||||
|
level = vo_get_brightness(handle);
|
||||||
|
if (level < 0)
|
||||||
|
goto out;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("unknown notify event 0x%x from %s\n",
|
||||||
|
notify, acpi_name(handle));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_level = level;
|
||||||
|
switch (notify) {
|
||||||
|
case VID_NOTIFY_CYCLE_BRN:
|
||||||
|
for (i = 2; i < vo->vo_numlevels; i++)
|
||||||
|
if (vo->vo_levels[i] == level) {
|
||||||
|
new_level = vo->vo_numlevels > i + 1 ?
|
||||||
|
vo->vo_levels[i + 1] : vo->vo_levels[2];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VID_NOTIFY_INC_BRN:
|
||||||
|
case VID_NOTIFY_DEC_BRN:
|
||||||
|
for (i = 0; i < vo->vo_numlevels; i++) {
|
||||||
|
j = vo->vo_levels[i];
|
||||||
|
if (notify == VID_NOTIFY_INC_BRN) {
|
||||||
|
if (j > level &&
|
||||||
|
(j < new_level || level == new_level))
|
||||||
|
new_level = j;
|
||||||
|
} else {
|
||||||
|
if (j < level &&
|
||||||
|
(j > new_level || level == new_level))
|
||||||
|
new_level = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VID_NOTIFY_ZERO_BRN:
|
||||||
|
for (i = 0; i < vo->vo_numlevels; i++)
|
||||||
|
if (vo->vo_levels[i] == 0) {
|
||||||
|
new_level = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (new_level != level) {
|
||||||
|
vo_set_brightness(handle, new_level);
|
||||||
|
vo->vo_brightness = new_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
ACPI_SERIAL_END(video_output);
|
||||||
|
}
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
acpi_video_vo_active_sysctl(SYSCTL_HANDLER_ARGS)
|
acpi_video_vo_active_sysctl(SYSCTL_HANDLER_ARGS)
|
||||||
@ -901,6 +985,25 @@ vo_get_brightness_levels(ACPI_HANDLE handle, int **levelp)
|
|||||||
return (num);
|
return (num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vo_get_brightness(ACPI_HANDLE handle)
|
||||||
|
{
|
||||||
|
UINT32 level;
|
||||||
|
ACPI_STATUS status;
|
||||||
|
|
||||||
|
ACPI_SERIAL_ASSERT(video_output);
|
||||||
|
status = acpi_GetInteger(handle, "_BQC", &level);
|
||||||
|
if (ACPI_FAILURE(status)) {
|
||||||
|
printf("can't evaluate %s._BQC - %s\n", acpi_name(handle),
|
||||||
|
AcpiFormatException(status));
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (level > 100)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
return (level);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vo_set_brightness(ACPI_HANDLE handle, int level)
|
vo_set_brightness(ACPI_HANDLE handle, int level)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user