Beispiel #1
0
static void
fujitsu_hk_attach(device_t parent, device_t self, void *aux)
{
    struct fujitsu_hk_softc *sc = device_private(self);
    struct acpi_attach_args *aa = aux;
    struct acpi_devnode *ad = aa->aa_node;
    int i;

    aprint_naive(": Fujitsu Hotkeys\n");
    aprint_normal(": Fujitsu Hotkeys\n");

    sc->sc_dev = self;
    sc->sc_node = ad;
    sc->sc_log = NULL;
    sc->sc_caps = fujitsu_hk_capabilities(ad);

    mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);

    for (i = 0; i < FUJITSU_HK_PSW_COUNT; i++) {
        (void)snprintf(sc->sc_smpsw_name[i],
                       sizeof(sc->sc_smpsw_name[i]), "%s-%d",
                       device_xname(self), i);
        sc->sc_smpsw[i].smpsw_name = sc->sc_smpsw_name[i];
        sc->sc_smpsw[i].smpsw_type = PSWITCH_TYPE_HOTKEY;
        (void)sysmon_pswitch_register(&sc->sc_smpsw[i]);
    }

    fujitsu_hk_sysctl_setup(sc);

    (void)pmf_device_register(self, fujitsu_hk_suspend, fujitsu_hk_resume);
    (void)acpi_register_notify(sc->sc_node, fujitsu_hk_notify_handler);
}
/*
 * acpitz_attach: autoconf(9) attach routine
 */
static void
acpitz_attach(device_t parent, device_t self, void *aux)
{
    struct acpitz_softc *sc = device_private(self);
    struct acpi_attach_args *aa = aux;
    ACPI_INTEGER val;
    ACPI_STATUS rv;

    sc->sc_first = true;
    sc->sc_have_fan = false;
    sc->sc_node = aa->aa_node;
    sc->sc_zone.tzp = ATZ_TZP_RATE;

    aprint_naive("\n");
    acpitz_print_processor_list(self);
    aprint_normal("\n");

    /*
     * The _TZP (ACPI 4.0, p. 430) defines the recommended
     * polling interval (in tenths of seconds). A value zero
     * means that polling "should not be necessary".
     */
    rv = acpi_eval_integer(sc->sc_node->ad_handle, "_TZP", &val);

    if (ACPI_SUCCESS(rv) && val != 0)
        sc->sc_zone.tzp = val;

    aprint_debug_dev(self, "polling interval %d.%d seconds\n",
                     sc->sc_zone.tzp / 10, sc->sc_zone.tzp % 10);

    sc->sc_zone_expire = ATZ_ZONE_EXPIRE / sc->sc_zone.tzp;

    /*
     * XXX: The fan controls seen here are available on
     *	some HP laptops. Arguably these should not
     *	appear in a generic device driver like this.
     */
    if (acpitz_get_fanspeed(self, &sc->sc_zone.fanmin,
                            &sc->sc_zone.fanmax, &sc->sc_zone.fancurrent) == 0)
        sc->sc_have_fan = true;

    acpitz_get_zone(self, 1);
    acpitz_get_status(self);

    (void)pmf_device_register(self, NULL, NULL);
    (void)acpi_power_register(sc->sc_node->ad_handle);
    (void)acpi_register_notify(sc->sc_node, acpitz_notify_handler);

    callout_init(&sc->sc_callout, CALLOUT_MPSAFE);
    callout_setfunc(&sc->sc_callout, acpitz_tick, self);

    acpitz_init_envsys(self);

    callout_schedule(&sc->sc_callout, sc->sc_zone.tzp * hz / 10);
}
static void
asus_attach(device_t parent, device_t self, void *opaque)
{
	struct asus_softc *sc = device_private(self);
	struct acpi_attach_args *aa = opaque;

	sc->sc_dev = self;
	sc->sc_node = aa->aa_node;

	aprint_naive("\n");
	aprint_normal("\n");

	asus_init(self);
	asus_sysctl_setup(sc);

	sc->sc_smpsw_valid = true;
	sc->sc_smpsw[ASUS_PSW_DISPLAY_CYCLE].smpsw_name =
	    PSWITCH_HK_DISPLAY_CYCLE;
	sc->sc_smpsw[ASUS_PSW_DISPLAY_CYCLE].smpsw_type =
	    PSWITCH_TYPE_HOTKEY;
	if (sysmon_pswitch_register(&sc->sc_smpsw[ASUS_PSW_DISPLAY_CYCLE])) {
		aprint_error_dev(self, "couldn't register with sysmon\n");
		sc->sc_smpsw_valid = false;
	}

	if (asus_get_fan_speed(sc, NULL) == false)
		goto out;

	sc->sc_sme = sysmon_envsys_create();

	strcpy(sc->sc_sensor[ASUS_SENSOR_FAN].desc, "fan");
	sc->sc_sensor[ASUS_SENSOR_FAN].units = ENVSYS_SFANRPM;
	sc->sc_sensor[ASUS_SENSOR_FAN].state = ENVSYS_SINVALID;
	sysmon_envsys_sensor_attach(sc->sc_sme,
	    &sc->sc_sensor[ASUS_SENSOR_FAN]);

	sc->sc_sme->sme_name = device_xname(self);
	sc->sc_sme->sme_cookie = sc;
	sc->sc_sme->sme_refresh = asus_sensors_refresh;
	sc->sc_sme->sme_flags = SME_POLL_ONLY;

	if (sysmon_envsys_register(sc->sc_sme)) {
		aprint_error_dev(self, "couldn't register with envsys\n");
		sysmon_envsys_destroy(sc->sc_sme);
		sc->sc_sme = NULL;
	}

out:
	(void)pmf_device_register(self, asus_suspend, asus_resume);
	(void)acpi_register_notify(sc->sc_node, asus_notify_handler);
}
static void
acpi_dalb_attach(device_t parent, device_t self, void *aux)
{
	struct acpi_dalb_softc *sc = device_private(self);
	struct acpi_attach_args *aa = aux;

	aprint_naive("\n");
	aprint_normal(": Direct Application Launch Button\n");

	sc->sc_dev = self;
	sc->sc_node = aa->aa_node;

	config_interrupts(self, acpi_dalb_init);

	(void)pmf_device_register(self, NULL, acpi_dalb_resume);
	(void)acpi_register_notify(sc->sc_node, acpi_dalb_notify_handler);

	sc->sc_smpsw_valid = false;
	acpi_dalb_sysmon_init(sc);
}
Beispiel #5
0
/*
 * valz_acpi_attach:
 *
 *	Autoconfiguration `attach' routine.
 */
static void
valz_acpi_attach(device_t parent, device_t self, void *aux)
{
	struct valz_acpi_softc *sc = device_private(self);
	struct acpi_attach_args *aa = aux;
	ACPI_STATUS rv;

	aprint_naive(": Toshiba VALZ\n");
	aprint_normal(": Toshiba VALZ\n");

	sc->sc_node = aa->aa_node;
	sc->sc_dev = self;

	/* enable valz notify */
	rv = AcpiEvaluateObject(sc->sc_node->ad_handle, METHOD_HCI_ENABLE,
				NULL, NULL);
	if (ACPI_FAILURE(rv)) {
		aprint_error("Cannot enable VALZ.\n");
	} else {
		(void)acpi_register_notify(sc->sc_node,
		    valz_acpi_notify_handler);
	}
}
static void
acpicpu_attach(device_t parent, device_t self, void *aux)
{
	struct acpicpu_softc *sc = device_private(self);
	struct cpu_info *ci;
	ACPI_HANDLE hdl;
	cpuid_t id;
	int rv;

	ci = acpicpu_md_attach(parent, self, aux);

	if (ci == NULL)
		return;

	sc->sc_ci = ci;
	sc->sc_dev = self;
	sc->sc_cold = true;

	hdl = acpi_match_cpu_info(ci);

	if (hdl == NULL) {
		aprint_normal(": failed to match processor\n");
		return;
	}

	sc->sc_node = acpi_match_node(hdl);

	if (acpicpu_once_attach() != 0) {
		aprint_normal(": failed to initialize\n");
		return;
	}

	KASSERT(acpi_softc != NULL);
	KASSERT(acpicpu_sc != NULL);
	KASSERT(sc->sc_node != NULL);

	id = sc->sc_ci->ci_acpiid;

	if (acpicpu_sc[id] != NULL) {
		aprint_normal(": already attached\n");
		return;
	}

	aprint_naive("\n");
	aprint_normal(": ACPI CPU\n");

	rv = acpicpu_object(sc->sc_node->ad_handle, &sc->sc_object);

	if (ACPI_FAILURE(rv))
		aprint_verbose_dev(self, "failed to obtain CPU object\n");

	acpicpu_count++;
	acpicpu_sc[id] = sc;

	sc->sc_cap = acpicpu_cap(sc);
	sc->sc_ncpus = acpi_md_ncpus();
	sc->sc_flags = acpicpu_md_flags();

	KASSERT(acpicpu_count <= sc->sc_ncpus);
	KASSERT(sc->sc_node->ad_device == NULL);

	sc->sc_node->ad_device = self;
	mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);

	acpicpu_cstate_attach(self);
	acpicpu_pstate_attach(self);
	acpicpu_tstate_attach(self);

	acpicpu_debug_print(self);
	acpicpu_evcnt_attach(self);

	(void)config_interrupts(self, acpicpu_start);
	(void)acpi_register_notify(sc->sc_node, acpicpu_notify);
	(void)pmf_device_register(self, acpicpu_suspend, acpicpu_resume);
}
Beispiel #7
0
static void
thinkpad_attach(device_t parent, device_t self, void *opaque)
{
	thinkpad_softc_t *sc = device_private(self);
	struct acpi_attach_args *aa = (struct acpi_attach_args *)opaque;
	struct sysmon_pswitch *psw;
	device_t curdev;
	deviter_t di;
	ACPI_STATUS rv;
	ACPI_INTEGER val;
	int i;

	sc->sc_dev = self;
	sc->sc_powhdl = NULL;
	sc->sc_cmoshdl = NULL;
	sc->sc_node = aa->aa_node;
	sc->sc_display_state = THINKPAD_DISPLAY_LCD;

	aprint_naive("\n");
	aprint_normal("\n");

	sc->sc_ecdev = NULL;
	for (curdev = deviter_first(&di, DEVITER_F_ROOT_FIRST);
	     curdev != NULL; curdev = deviter_next(&di))
		if (device_is_a(curdev, "acpiecdt") ||
		    device_is_a(curdev, "acpiec")) {
			sc->sc_ecdev = curdev;
			break;
		}
	deviter_release(&di);

	if (sc->sc_ecdev)
		aprint_debug_dev(self, "using EC at %s\n",
		    device_xname(sc->sc_ecdev));

	/* Get the supported event mask */
	rv = acpi_eval_integer(sc->sc_node->ad_handle, "MHKA", &val);
	if (ACPI_FAILURE(rv)) {
		aprint_error_dev(self, "couldn't evaluate MHKA: %s\n",
		    AcpiFormatException(rv));
		goto fail;
	}

	/* Enable all supported events */
	rv = thinkpad_mask_init(sc, val);
	if (ACPI_FAILURE(rv)) {
		aprint_error_dev(self, "couldn't set event mask: %s\n",
		    AcpiFormatException(rv));
		goto fail;
	}

	(void)acpi_register_notify(sc->sc_node, thinkpad_notify_handler);

	/*
	 * Obtain a handle for CMOS commands. This is used by T61.
	 */
	(void)AcpiGetHandle(NULL, "\\UCMS", &sc->sc_cmoshdl);

	/*
	 * Obtain a handle to the power resource available on many models.
	 * Since pmf(9) is not yet integrated with the ACPI power resource
	 * code, this must be turned on manually upon resume. Otherwise the
	 * system may, for instance, resume from S3 with usb(4) powered down.
	 */
	(void)AcpiGetHandle(NULL, "\\_SB.PCI0.LPC.EC.PUBS", &sc->sc_powhdl);

	/* Register power switches with sysmon */
	psw = sc->sc_smpsw;
	sc->sc_smpsw_valid = true;

	psw[TP_PSW_SLEEP].smpsw_name = device_xname(self);
	psw[TP_PSW_SLEEP].smpsw_type = PSWITCH_TYPE_SLEEP;
#if notyet
	psw[TP_PSW_HIBERNATE].smpsw_name = device_xname(self);
	mpsw[TP_PSW_HIBERNATE].smpsw_type = PSWITCH_TYPE_HIBERNATE;
#endif
	for (i = TP_PSW_DISPLAY_CYCLE; i < TP_PSW_LAST; i++)
		sc->sc_smpsw[i].smpsw_type = PSWITCH_TYPE_HOTKEY;
	psw[TP_PSW_DISPLAY_CYCLE].smpsw_name = PSWITCH_HK_DISPLAY_CYCLE;
	psw[TP_PSW_LOCK_SCREEN].smpsw_name = PSWITCH_HK_LOCK_SCREEN;
	psw[TP_PSW_BATTERY_INFO].smpsw_name = PSWITCH_HK_BATTERY_INFO;
	psw[TP_PSW_EJECT_BUTTON].smpsw_name = PSWITCH_HK_EJECT_BUTTON;
	psw[TP_PSW_ZOOM_BUTTON].smpsw_name = PSWITCH_HK_ZOOM_BUTTON;
	psw[TP_PSW_VENDOR_BUTTON].smpsw_name = PSWITCH_HK_VENDOR_BUTTON;
#ifndef THINKPAD_NORMAL_HOTKEYS
	psw[TP_PSW_FNF1_BUTTON].smpsw_name     = PSWITCH_HK_FNF1_BUTTON;
	psw[TP_PSW_WIRELESS_BUTTON].smpsw_name = PSWITCH_HK_WIRELESS_BUTTON;
	psw[TP_PSW_WWAN_BUTTON].smpsw_name     = PSWITCH_HK_WWAN_BUTTON;
	psw[TP_PSW_POINTER_BUTTON].smpsw_name  = PSWITCH_HK_POINTER_BUTTON;
	psw[TP_PSW_FNF10_BUTTON].smpsw_name    = PSWITCH_HK_FNF10_BUTTON;
	psw[TP_PSW_FNF11_BUTTON].smpsw_name    = PSWITCH_HK_FNF11_BUTTON;
	psw[TP_PSW_BRIGHTNESS_UP].smpsw_name   = PSWITCH_HK_BRIGHTNESS_UP;
	psw[TP_PSW_BRIGHTNESS_DOWN].smpsw_name = PSWITCH_HK_BRIGHTNESS_DOWN;
	psw[TP_PSW_THINKLIGHT].smpsw_name      = PSWITCH_HK_THINKLIGHT;
	psw[TP_PSW_VOLUME_UP].smpsw_name       = PSWITCH_HK_VOLUME_UP;
	psw[TP_PSW_VOLUME_DOWN].smpsw_name     = PSWITCH_HK_VOLUME_DOWN;
	psw[TP_PSW_VOLUME_MUTE].smpsw_name     = PSWITCH_HK_VOLUME_MUTE;
#endif /* THINKPAD_NORMAL_HOTKEYS */

	for (i = 0; i < TP_PSW_LAST; i++) {
		/* not supported yet */
		if (i == TP_PSW_HIBERNATE)
			continue;
		if (sysmon_pswitch_register(&sc->sc_smpsw[i]) != 0) {
			aprint_error_dev(self,
			    "couldn't register with sysmon\n");
			sc->sc_smpsw_valid = false;
			break;
		}
	}

	/* Register temperature and fan sensors with envsys */
	thinkpad_sensors_init(sc);

fail:
	if (!pmf_device_register(self, NULL, thinkpad_resume))
		aprint_error_dev(self, "couldn't establish power handler\n");
	if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_UP,
	    thinkpad_brightness_up, true))
		aprint_error_dev(self, "couldn't register event handler\n");
	if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_DOWN,
	    thinkpad_brightness_down, true))
		aprint_error_dev(self, "couldn't register event handler\n");
}