Esempio n. 1
0
static void
thinkpad_get_hotkeys(void *opaque)
{
	thinkpad_softc_t *sc = (thinkpad_softc_t *)opaque;
	device_t self = sc->sc_dev;
	ACPI_STATUS rv;
	ACPI_INTEGER val;
	int type, event;
	
	for (;;) {
		rv = acpi_eval_integer(sc->sc_node->ad_handle, "MHKP", &val);
		if (ACPI_FAILURE(rv)) {
			aprint_error_dev(self, "couldn't evaluate MHKP: %s\n",
			    AcpiFormatException(rv));
			return;
		}

		if (val == 0)
			return;

		type = (val & 0xf000) >> 12;
		event = val & 0x0fff;

		if (type != 1)
			/* Only type 1 events are supported for now */
			continue;

		switch (event) {
		case THINKPAD_NOTIFY_BrightnessUp:
			thinkpad_brightness_up(self);
			break;
		case THINKPAD_NOTIFY_BrightnessDown:
			thinkpad_brightness_down(self);
			break;
		case THINKPAD_NOTIFY_WirelessSwitch:
			thinkpad_wireless_toggle(sc);
			break;
		case THINKPAD_NOTIFY_SleepButton:
			if (sc->sc_smpsw_valid == false)
				break;
			sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_SLEEP],
			    PSWITCH_EVENT_PRESSED);
			break;
		case THINKPAD_NOTIFY_HibernateButton:
#if notyet
			if (sc->sc_smpsw_valid == false)
				break;
			sysmon_pswitch_event(&sc->sc_smpsw[TP_PSW_HIBERNATE],
			    PSWITCH_EVENT_PRESSED);
#endif
			break;
		case THINKPAD_NOTIFY_DisplayCycle:
			if (sc->sc_smpsw_valid == false)
				break;
			sysmon_pswitch_event(
			    &sc->sc_smpsw[TP_PSW_DISPLAY_CYCLE],
			    PSWITCH_EVENT_PRESSED);
			break;
		case THINKPAD_NOTIFY_LockScreen:
			if (sc->sc_smpsw_valid == false)
				break;
			sysmon_pswitch_event(
			    &sc->sc_smpsw[TP_PSW_LOCK_SCREEN],
			    PSWITCH_EVENT_PRESSED);
			break;
		case THINKPAD_NOTIFY_BatteryInfo:
			if (sc->sc_smpsw_valid == false)
				break;
			sysmon_pswitch_event(
			    &sc->sc_smpsw[TP_PSW_BATTERY_INFO],
			    PSWITCH_EVENT_PRESSED);
			break;
		case THINKPAD_NOTIFY_EjectButton:
			if (sc->sc_smpsw_valid == false)
				break;
			sysmon_pswitch_event(
			    &sc->sc_smpsw[TP_PSW_EJECT_BUTTON],
			    PSWITCH_EVENT_PRESSED);
			break;
		case THINKPAD_NOTIFY_Zoom:
			if (sc->sc_smpsw_valid == false)
				break;
			sysmon_pswitch_event(
			    &sc->sc_smpsw[TP_PSW_ZOOM_BUTTON],
			    PSWITCH_EVENT_PRESSED);
			break;
		case THINKPAD_NOTIFY_ThinkVantage:
			if (sc->sc_smpsw_valid == false)
				break;
			sysmon_pswitch_event(
			    &sc->sc_smpsw[TP_PSW_VENDOR_BUTTON],
			    PSWITCH_EVENT_PRESSED);
			break;
		case THINKPAD_NOTIFY_FnF1:
		case THINKPAD_NOTIFY_FnF6:
		case THINKPAD_NOTIFY_PointerSwitch:
		case THINKPAD_NOTIFY_FnF10:
		case THINKPAD_NOTIFY_FnF11:
		case THINKPAD_NOTIFY_ThinkLight:
			/* XXXJDM we should deliver hotkeys as keycodes */
			break;
		default:
			aprint_debug_dev(self, "notify event 0x%03x\n", event);
			break;
		}
	}
}
int
thinkpad_hotkey(struct aml_node *node, int notify_type, void *arg)
{
	struct acpithinkpad_softc *sc = arg;
	int handled = 0;
	int64_t	event;

	if (notify_type == 0x00) {
		/* Poll sensors */
		thinkpad_sensor_refresh(sc);
		return (0);
	}

	if (notify_type != 0x80)
		return (1);

	for (;;) {
		if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "MHKP",
		    0, NULL, &event))
			break;
		if (event == 0)
			break;

		switch (event) {
		case THINKPAD_BUTTON_BRIGHTNESS_UP:
			thinkpad_brightness_up(sc);
			handled = 1;
			break;
		case THINKPAD_BUTTON_BRIGHTNESS_DOWN:
			thinkpad_brightness_down(sc);
			handled = 1;
			break;
		case THINKPAD_BUTTON_WIRELESS:
			thinkpad_toggle_bluetooth(sc);
			handled = 1;
			break;
		case THINKPAD_BUTTON_SUSPEND:
#ifndef SMALL_KERNEL
			if (acpi_record_event(sc->sc_acpi, APM_USER_SUSPEND_REQ))
				acpi_addtask(sc->sc_acpi, acpi_sleep_task, 
				    sc->sc_acpi, ACPI_STATE_S3);
#endif
			handled = 1;
			break;
		case THINKPAD_BUTTON_VOLUME_MUTE:
			thinkpad_volume_mute(sc);
			handled = 1;
			break;
		case THINKPAD_BUTTON_VOLUME_DOWN:
			thinkpad_volume_down(sc);
			handled = 1;
			break;
		case THINKPAD_BUTTON_VOLUME_UP:
			thinkpad_volume_up(sc);
			handled = 1;
			break;
		case THINKPAD_BUTTON_MICROPHONE_MUTE:
#if NAUDIO > 0 && NWSKBD > 0
			wskbd_set_mixervolume(0, 0);
#endif
			handled = 1;
			break;
		case THINKPAD_BUTTON_HIBERNATE:
#ifndef SMALL_KERNEL
			acpi_addtask(sc->sc_acpi, acpi_sleep_task, 
			    sc->sc_acpi, ACPI_STATE_S4);
#endif
			handled = 1;
			break;
		case THINKPAD_ADAPTIVE_NEXT:
		case THINKPAD_ADAPTIVE_QUICK:
			thinkpad_adaptive_change(sc);
			handled = 1;
			break;
		case THINKPAD_ADAPTIVE_BACK:
		case THINKPAD_ADAPTIVE_GESTURES:
		case THINKPAD_ADAPTIVE_REFRESH:
		case THINKPAD_ADAPTIVE_SETTINGS:
		case THINKPAD_ADAPTIVE_SNIP:
		case THINKPAD_ADAPTIVE_TAB:
		case THINKPAD_ADAPTIVE_VOICE:
		case THINKPAD_BACKLIGHT_CHANGED:
		case THINKPAD_BRIGHTNESS_CHANGED:
		case THINKPAD_BUTTON_BATTERY_INFO:
		case THINKPAD_BUTTON_EJECT:
		case THINKPAD_BUTTON_EXTERNAL_SCREEN:
		case THINKPAD_BUTTON_FN_F11:
		case THINKPAD_BUTTON_FN_F1:
		case THINKPAD_BUTTON_FN_F6:
		case THINKPAD_BUTTON_FN_SPACE:
		case THINKPAD_BUTTON_LOCK_SCREEN:
		case THINKPAD_BUTTON_POINTER_SWITCH:
		case THINKPAD_BUTTON_THINKLIGHT:
		case THINKPAD_BUTTON_THINKVANTAGE:
		case THINKPAD_LID_CLOSED:
		case THINKPAD_LID_OPEN:
		case THINKPAD_PORT_REPL_DOCKED:
		case THINKPAD_PORT_REPL_UNDOCKED:
		case THINKPAD_POWER_CHANGED:
		case THINKPAD_SWITCH_WIRELESS:
		case THINKPAD_TABLET_PEN_INSERTED:
		case THINKPAD_TABLET_PEN_REMOVED:
		case THINKPAD_TABLET_SCREEN_NORMAL:
		case THINKPAD_TABLET_SCREEN_ROTATED:
		case THINKPAD_THERMAL_TABLE_CHANGED:
			handled = 1;
			break;
		default:
			printf("%s: unknown event 0x%03llx\n",
			    DEVNAME(sc), event);
		}
	}

	return (handled);
}