Beispiel #1
0
int
acpibat_notify(struct aml_node *node, int notify_type, void *arg)
{
	struct acpibat_softc	*sc = arg;
	int64_t			sta;

	dnprintf(10, "acpibat_notify: %.2x %s\n", notify_type,
	    sc->sc_devnode->name);

	/* Check if installed state of battery has changed */
	if (aml_evalinteger(sc->sc_acpi, node, "_STA", 0, NULL, &sta) == 0) {
		if (sta & STA_BATTERY)
			sc->sc_bat_present = 1;
		else
			sc->sc_bat_present = 0;
	}

	switch (notify_type) {
	case 0x00:	/* Poll sensors */
	case 0x80:	/* _BST changed */
		acpibat_getbst(sc);
		break;
	case 0x81:	/* _BIF changed */
		acpibat_getbif(sc);
		break;
	default:
		break;
	}

	acpibat_refresh(sc);

	return (0);
}
Beispiel #2
0
void
acpibat_attach(struct device *parent, struct device *self, void *aux)
{
    struct acpibat_softc	*sc = (struct acpibat_softc *)self;
    struct acpi_attach_args	*aa = aux;
    struct aml_value	res;

    sc->sc_acpi = (struct acpi_softc *)parent;
    sc->sc_devnode = aa->aaa_node;

    if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL, &res)) {
        dnprintf(10, "%s: no _STA\n", DEVNAME(sc));
        return;
    }

    if ((res.v_integer & STA_BATTERY) != 0) {
        sc->sc_bat_present = 1;
        acpibat_getbif(sc);
        acpibat_getbst(sc);

        printf(": %s", sc->sc_devnode->name);
        if (sc->sc_bif.bif_model[0])
            printf(" model \"%s\"", sc->sc_bif.bif_model);
        if (sc->sc_bif.bif_serial[0])
            printf(" serial %s", sc->sc_bif.bif_serial);
        if (sc->sc_bif.bif_type[0])
            printf(" type %s", sc->sc_bif.bif_type);
        if (sc->sc_bif.bif_oem[0])
            printf(" oem \"%s\"", sc->sc_bif.bif_oem);
        printf("\n");
    } else {
        sc->sc_bat_present = 0;
        printf(": %s not present\n", sc->sc_devnode->name);
    }

    aml_freevalue(&res);

    /* create sensors */
    acpibat_monitor(sc);

    /* populate sensors */
    acpibat_refresh(sc);

    aml_register_notify(sc->sc_devnode, aa->aaa_dev,
                        acpibat_notify, sc, ACPIDEV_POLL);
}
Beispiel #3
0
void
acpibat_refresh(void *arg)
{
    struct acpibat_softc	*sc = arg;
    int			i;

    dnprintf(30, "%s: %s: refresh\n", DEVNAME(sc),
             sc->sc_devnode->name);

    if (!sc->sc_bat_present) {
        for (i = 0; i < 8; i++) {
            sc->sc_sens[i].value = 0;
            sc->sc_sens[i].status = SENSOR_S_UNSPEC;
            sc->sc_sens[i].flags = SENSOR_FINVALID;
        }
        /* override state */
        strlcpy(sc->sc_sens[4].desc, "battery removed",
                sizeof(sc->sc_sens[4].desc));
        return;
    }

    /*
     * XXX don't really need _BIF but keep it here in case we
     * miss an insertion/removal event
     */
    acpibat_getbif(sc);
    acpibat_getbst(sc);

    /* _BIF values are static, sensor 0..3 */
    if (sc->sc_bif.bif_last_capacity == BIF_UNKNOWN) {
        sc->sc_sens[0].value = 0;
        sc->sc_sens[0].status = SENSOR_S_UNKNOWN;
        sc->sc_sens[0].flags = SENSOR_FUNKNOWN;
    } else {
        sc->sc_sens[0].value = sc->sc_bif.bif_last_capacity * 1000;
        sc->sc_sens[0].status = SENSOR_S_UNSPEC;
        sc->sc_sens[0].flags = 0;
    }
    sc->sc_sens[1].value = sc->sc_bif.bif_warning * 1000;
    sc->sc_sens[1].flags = 0;
    sc->sc_sens[2].value = sc->sc_bif.bif_low * 1000;
    sc->sc_sens[2].flags = 0;
    if (sc->sc_bif.bif_voltage == BIF_UNKNOWN) {
        sc->sc_sens[3].value = 0;
        sc->sc_sens[3].status = SENSOR_S_UNKNOWN;
        sc->sc_sens[3].flags = SENSOR_FUNKNOWN;
    } else {
        sc->sc_sens[3].value = sc->sc_bif.bif_voltage * 1000;
        sc->sc_sens[3].status = SENSOR_S_UNSPEC;
        sc->sc_sens[3].flags = 0;
    }

    /* _BST values are dynamic, sensor 4..7 */
    sc->sc_sens[4].status = SENSOR_S_OK;
    sc->sc_sens[4].flags = 0;
    if (sc->sc_bif.bif_last_capacity == BIF_UNKNOWN ||
            sc->sc_bst.bst_capacity == BST_UNKNOWN) {
        sc->sc_sens[4].status = SENSOR_S_UNKNOWN;
        sc->sc_sens[4].flags = SENSOR_FUNKNOWN;
        strlcpy(sc->sc_sens[4].desc, "battery unknown",
                sizeof(sc->sc_sens[4].desc));
    } else if (sc->sc_bst.bst_capacity >= sc->sc_bif.bif_last_capacity)
        strlcpy(sc->sc_sens[4].desc, "battery full",
                sizeof(sc->sc_sens[4].desc));
    else if (sc->sc_bst.bst_state & BST_DISCHARGE)
        strlcpy(sc->sc_sens[4].desc, "battery discharging",
                sizeof(sc->sc_sens[4].desc));
    else if (sc->sc_bst.bst_state & BST_CHARGE)
        strlcpy(sc->sc_sens[4].desc, "battery charging",
                sizeof(sc->sc_sens[4].desc));
    else if (sc->sc_bst.bst_state & BST_CRITICAL) {
        strlcpy(sc->sc_sens[4].desc, "battery critical",
                sizeof(sc->sc_sens[4].desc));
        sc->sc_sens[4].status = SENSOR_S_CRIT;
    } else
        strlcpy(sc->sc_sens[4].desc, "battery idle",
                sizeof(sc->sc_sens[4].desc));
    sc->sc_sens[4].value = sc->sc_bst.bst_state;

    if (sc->sc_bst.bst_rate == BST_UNKNOWN) {
        sc->sc_sens[5].value = 0;
        sc->sc_sens[5].status = SENSOR_S_UNKNOWN;
        sc->sc_sens[5].flags = SENSOR_FUNKNOWN;
    } else {
        sc->sc_sens[5].value = sc->sc_bst.bst_rate;
        sc->sc_sens[5].status = SENSOR_S_UNSPEC;
        sc->sc_sens[5].flags = 0;
    }

    if (sc->sc_bst.bst_capacity == BST_UNKNOWN) {
        sc->sc_sens[6].value = 0;
        sc->sc_sens[6].status = SENSOR_S_UNKNOWN;
        sc->sc_sens[6].flags = SENSOR_FUNKNOWN;
    } else {
        sc->sc_sens[6].value = sc->sc_bst.bst_capacity * 1000;
        sc->sc_sens[6].flags = 0;

        if (sc->sc_bst.bst_capacity < sc->sc_bif.bif_low)
            /* XXX we should shutdown the system */
            sc->sc_sens[6].status = SENSOR_S_CRIT;
        else if (sc->sc_bst.bst_capacity < sc->sc_bif.bif_warning)
            sc->sc_sens[6].status = SENSOR_S_WARN;
        else
            sc->sc_sens[6].status = SENSOR_S_OK;
    }

    if (sc->sc_bst.bst_voltage == BST_UNKNOWN) {
        sc->sc_sens[7].value = 0;
        sc->sc_sens[7].status = SENSOR_S_UNKNOWN;
        sc->sc_sens[7].flags = SENSOR_FUNKNOWN;
    } else {
        sc->sc_sens[7].value = sc->sc_bst.bst_voltage * 1000;
        sc->sc_sens[7].status = SENSOR_S_UNSPEC;
        sc->sc_sens[7].flags = 0;
    }
}