Beispiel #1
0
static ACPI_STATUS
EcRead(struct acpi_ec_softc *sc, UINT8 Address, UINT8 *Data)
{
    ACPI_STATUS	Status;

    if (!EcIsLocked(sc))
	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
	    "EcRead called without EC lock!\n");

    /*EcBurstEnable(EmbeddedController);*/

    EC_SET_CSR(sc, EC_COMMAND_READ);
    if (ACPI_FAILURE(Status = EcWaitEventIntr(sc, EC_EVENT_INPUT_BUFFER_EMPTY))) {
	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
	    "EcRead: Failed waiting for EC to process read command.\n");
	return(Status);
    }

    EC_SET_DATA(sc, Address);
    if (ACPI_FAILURE(Status = EcWaitEventIntr(sc, EC_EVENT_OUTPUT_BUFFER_FULL))) {
	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
	    "EcRead: Failed waiting for EC to send data.\n");
	return(Status);
    }

    (*Data) = EC_GET_DATA(sc);

    /*EcBurstDisable(EmbeddedController);*/

    return(AE_OK);
}    
Beispiel #2
0
int
acpi_PkgGas(device_t dev, ACPI_OBJECT *res, int idx, int *rid,
	    struct resource **dst)
{
    ACPI_GENERIC_ADDRESS gas;
    ACPI_OBJECT		*obj;

    obj = &res->Package.Elements[idx];
    if (obj == NULL || obj->Type != ACPI_TYPE_BUFFER ||
	obj->Buffer.Length < sizeof(ACPI_GENERIC_ADDRESS) + 3) {

	ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "PkgGas error at %d\n", idx);
	return (-1);
    }

    memcpy(&gas, obj->Buffer.Pointer + 3, sizeof(gas));
    *dst = acpi_bus_alloc_gas(dev, rid, &gas);
    if (*dst == NULL) {
	ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "PkgGas error at %d\n", idx);
	return (-1);
    }

    return (0);
}
Beispiel #3
0
static void
acpi_cmbat_get_bst(void *arg)
{
    struct acpi_cmbat_softc *sc;
    ACPI_STATUS	as;
    ACPI_OBJECT	*res;
    ACPI_HANDLE	h;
    ACPI_BUFFER	bst_buffer;
    device_t dev;

    ACPI_SERIAL_ASSERT(cmbat);

    dev = arg;
    sc = device_get_softc(dev);
    h = acpi_get_handle(dev);
    bst_buffer.Pointer = NULL;
    bst_buffer.Length = ACPI_ALLOCATE_BUFFER;

    if (!acpi_cmbat_info_expired(&sc->bst_lastupdated))
	goto end;

    as = AcpiEvaluateObject(h, "_BST", NULL, &bst_buffer);
    if (ACPI_FAILURE(as)) {
	ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "error fetching current battery status -- %s\n",
		    AcpiFormatException(as));
	goto end;
    }

    res = (ACPI_OBJECT *)bst_buffer.Pointer;
    if (!ACPI_PKG_VALID(res, 4)) {
	ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "battery status corrupted\n");
	goto end;
    }

    if (acpi_PkgInt32(res, 0, &sc->bst.state) != 0)
	goto end;
    if (acpi_PkgInt32(res, 1, &sc->bst.rate) != 0)
	goto end;
    if (acpi_PkgInt32(res, 2, &sc->bst.cap) != 0)
	goto end;
    if (acpi_PkgInt32(res, 3, &sc->bst.volt) != 0)
	goto end;
    acpi_cmbat_info_updated(&sc->bst_lastupdated);

    /* XXX If all batteries are critical, perhaps we should suspend. */
    if (sc->bst.state & ACPI_BATT_STAT_CRITICAL) {
    	if ((sc->flags & ACPI_BATT_STAT_CRITICAL) == 0) {
	    sc->flags |= ACPI_BATT_STAT_CRITICAL;
	    device_printf(dev, "critically low charge!\n");
	}
    } else
	sc->flags &= ~ACPI_BATT_STAT_CRITICAL;

end:
    if (bst_buffer.Pointer != NULL)
	AcpiOsFree(bst_buffer.Pointer);
}
Beispiel #4
0
static void
acpi_cmbat_get_bif(void *context)
{
	device_t	dev;
	struct acpi_cmbat_softc *sc;
	ACPI_STATUS	as;
	ACPI_OBJECT	*res, *tmp;
	ACPI_HANDLE	h;
	ACPI_BUFFER	bif_buffer;

	dev = context;
	sc = device_get_softc(dev);
	h = acpi_get_handle(dev);
	bif_buffer.Pointer = NULL;

	if (!acpi_cmbat_info_expired(&sc->bif_lastupdated)) {
		return;
	}

	if (sc->bif_updating) {
		return;
	}
	sc->bif_updating = 1;

	bif_buffer.Length = ACPI_ALLOCATE_BUFFER;
	if (ACPI_FAILURE(as = AcpiEvaluateObject(h, "_BIF", NULL, &bif_buffer))) {
		ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "error fetching current battery info -- %s\n",
		    AcpiFormatException(as));
		goto end;
	}

	res = (ACPI_OBJECT *)bif_buffer.Pointer;

	if ((res == NULL) || (res->Type != ACPI_TYPE_PACKAGE) || (res->Package.Count != 13)) {
		ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "battery info corrupted\n");
		goto end;
	}

	PKG_GETINT(res, tmp,  0, sc->bif.unit, end);
	PKG_GETINT(res, tmp,  1, sc->bif.dcap, end);
	PKG_GETINT(res, tmp,  2, sc->bif.lfcap, end);
	PKG_GETINT(res, tmp,  3, sc->bif.btech, end);
	PKG_GETINT(res, tmp,  4, sc->bif.dvol, end);
	PKG_GETINT(res, tmp,  5, sc->bif.wcap, end);
	PKG_GETINT(res, tmp,  6, sc->bif.lcap, end);
	PKG_GETINT(res, tmp,  7, sc->bif.gra1, end);
	PKG_GETINT(res, tmp,  8, sc->bif.gra2, end);
	PKG_GETSTR(res, tmp,  9, sc->bif.model, ACPI_CMBAT_MAXSTRLEN, end);
	PKG_GETSTR(res, tmp, 10, sc->bif.serial, ACPI_CMBAT_MAXSTRLEN, end);
	PKG_GETSTR(res, tmp, 11, sc->bif.type, ACPI_CMBAT_MAXSTRLEN, end);
	PKG_GETSTR(res, tmp, 12, sc->bif.oeminfo, ACPI_CMBAT_MAXSTRLEN, end);
	acpi_cmbat_info_updated(&sc->bif_lastupdated);
end:
	if (bif_buffer.Pointer != NULL)
		AcpiOsFree(bif_buffer.Pointer);
	sc->bif_updating = 0;
}
Beispiel #5
0
static ACPI_STATUS
EcTransaction(struct acpi_ec_softc *sc, EC_REQUEST *EcRequest)
{
    ACPI_STATUS	Status;

    /*
     * Lock the EC
     */
    if (ACPI_FAILURE(Status = EcLock(sc)))
	return(Status);

    /*
     * Perform the transaction.
     */
    switch (EcRequest->Command) {
    case EC_COMMAND_READ:
	Status = EcRead(sc, EcRequest->Address, &(EcRequest->Data));
	break;

    case EC_COMMAND_WRITE:
	Status = EcWrite(sc, EcRequest->Address, &(EcRequest->Data));
	break;

    default:
	Status = AE_SUPPORT;
	break;
    }

    /*
     * Unlock the EC
     */
    EcUnlock(sc);
    
    /*
     * Clear & Re-Enable the EC GPE:
     * -----------------------------
     * 'Consume' any EC GPE events that we generated while performing
     * the transaction (e.g. IBF/OBF).	Clearing the GPE here shouldn't
     * have an adverse affect on outstanding EC-SCI's, as the source
     * (EC-SCI) will still be high and thus should trigger the GPE
     * immediately after we re-enabling it.
     */
    if (sc->ec_pendquery){
	if (ACPI_FAILURE(AcpiOsQueueForExecution(OSD_PRIORITY_HIGH,
						 EcGpeQueryHandler, sc)))
	    printf("Pend Query Queuing Failed\n");
	sc->ec_pendquery = 0;
    }

    if (ACPI_FAILURE(AcpiClearEvent(sc->ec_gpebit, ACPI_EVENT_GPE)))
	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
	    "EcRequest: Unable to clear the EC GPE.\n");
    if (ACPI_FAILURE(AcpiEnableEvent(sc->ec_gpebit, ACPI_EVENT_GPE, 0)))
	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
	    "EcRequest: Unable to re-enable the EC GPE.\n");

    return(Status);
}
Beispiel #6
0
static void
acpi_cmbat_init_battery(void *arg)
{
    struct acpi_cmbat_softc *sc;
    int		retry, valid;
    device_t	dev;

    dev = (device_t)arg;
    sc = device_get_softc(dev);
    ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		"battery initialization start\n");

    /*
     * Try repeatedly to get valid data from the battery.  Since the
     * embedded controller isn't always ready just after boot, we may have
     * to wait a while.
     */
    for (retry = 0; retry < ACPI_CMBAT_RETRY_MAX; retry++, AcpiOsSleep(10000)) {
	/* batteries on DOCK can be ejected w/ DOCK during retrying */
	if (!device_is_attached(dev))
	    return;

	if (!acpi_BatteryIsPresent(dev))
	    continue;

	/*
	 * Only query the battery if this is the first try or the specific
	 * type of info is still invalid.
	 */
	ACPI_SERIAL_BEGIN(cmbat);
	if (retry == 0 || !acpi_battery_bst_valid(&sc->bst)) {
	    timespecclear(&sc->bst_lastupdated);
	    acpi_cmbat_get_bst(dev);
	}
	if (retry == 0 || !acpi_battery_bif_valid(&sc->bif))
	    acpi_cmbat_get_bif(dev);

	valid = acpi_battery_bst_valid(&sc->bst) &&
	    acpi_battery_bif_valid(&sc->bif);
	ACPI_SERIAL_END(cmbat);

	if (valid)
	    break;
    }

    if (retry == ACPI_CMBAT_RETRY_MAX) {
	ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "battery initialization failed, giving up\n");
    } else {
	ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "battery initialization done, tried %d times\n", retry + 1);
    }
}
Beispiel #7
0
static void
acpi_cmbat_init_battery(void *arg)
{
	int		retry;
	device_t	dev = (device_t)arg;
	struct acpi_cmbat_softc *sc = device_get_softc(dev);
#define ACPI_CMBAT_RETRY_MAX	6

	if (sc->initializing) {
		return;
	}

	sc->initializing = 1;

	ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "battery initialization start\n");

	for (retry = 0; retry < ACPI_CMBAT_RETRY_MAX; retry++, AcpiOsSleep(10, 0)) {
		sc->present = acpi_BatteryIsPresent(dev);
		if (!sc->present) {
			continue;
		}

		timespecclear(&sc->bst_lastupdated);
		timespecclear(&sc->bif_lastupdated);

		acpi_cmbat_get_bst(dev);

		if (!acpi_cmbat_is_bst_valid(&sc->bst)) {
			continue;
		}

		acpi_cmbat_get_bif(dev);

		if (!acpi_cmbat_is_bif_valid(&sc->bif)) {
			continue;
		}

		break;
	}

	if (retry == ACPI_CMBAT_RETRY_MAX)
		ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
			    "battery initialization failed, giving up\n");
	else
		ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
			    "battery initialization done, tried %d times\n",
			    retry+1);

	sc->initializing = 0;
}
Beispiel #8
0
static void
acpi_cmbat_get_bst(void *context)
{
	device_t	dev;
	struct acpi_cmbat_softc *sc;
	ACPI_STATUS	as;
	ACPI_OBJECT	*res, *tmp;
	ACPI_HANDLE	h;
	ACPI_BUFFER	bst_buffer;

	dev = context;
	sc = device_get_softc(dev);
	h = acpi_get_handle(dev);
	bst_buffer.Pointer = NULL;

	if (!acpi_cmbat_info_expired(&sc->bst_lastupdated)) {
		return;
	}

	if (sc->bst_updating) {
		return;
	}
	sc->bst_updating = 1;

	bst_buffer.Length = ACPI_ALLOCATE_BUFFER;
	if (ACPI_FAILURE(as = AcpiEvaluateObject(h, "_BST", NULL, &bst_buffer))) {
		ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "error fetching current battery status -- %s\n",
		    AcpiFormatException(as));
		goto end;
	}

	res = (ACPI_OBJECT *)bst_buffer.Pointer;

	if ((res == NULL) || (res->Type != ACPI_TYPE_PACKAGE) || (res->Package.Count != 4)) {
		ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "battery status corrupted\n");
		goto end;
	}

	PKG_GETINT(res, tmp, 0, sc->bst.state, end);
	PKG_GETINT(res, tmp, 1, sc->bst.rate, end);
	PKG_GETINT(res, tmp, 2, sc->bst.cap, end);
	PKG_GETINT(res, tmp, 3, sc->bst.volt, end);
	acpi_cmbat_info_updated(&sc->bst_lastupdated);
end:
	if (bst_buffer.Pointer != NULL)
		AcpiOsFree(bst_buffer.Pointer);
	sc->bst_updating = 0;
}
Beispiel #9
0
static void
acpi_button_notify_wakeup(void *arg)
{
    struct acpi_button_softc	*sc;
    struct acpi_softc		*acpi_sc;

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

    sc = (struct acpi_button_softc *)arg;
    acpi_sc = acpi_device_get_parent_softc(sc->button_dev);
    if (acpi_sc == NULL)
	return_VOID;

    acpi_UserNotify("Button", sc->button_handle, sc->button_type);

    switch (sc->button_type) {
    case ACPI_POWER_BUTTON:
	ACPI_VPRINT(sc->button_dev, acpi_sc, "wakeup by power button\n");
	acpi_event_power_button_wake(acpi_sc);
	break;
    case ACPI_SLEEP_BUTTON:
	ACPI_VPRINT(sc->button_dev, acpi_sc, "wakeup by sleep button\n");
	acpi_event_sleep_button_wake(acpi_sc);
	break;
    default:
	break;		/* unknown button type */
    }
}
static void
acpi_acad_get_status(void *context)
{
    struct acpi_acad_softc *sc;
    device_t	dev;
    ACPI_HANDLE	h;
    int		newstatus;

    dev = context;
    sc = device_get_softc(dev);
    h = acpi_get_handle(dev);
    newstatus = -1;
    acpi_GetInteger(h, "_PSR", &newstatus);

    /* If status is valid and has changed, notify the system. */
    ACPI_SERIAL_BEGIN(acad);
    if (newstatus != -1 && sc->status != newstatus) {
	sc->status = newstatus;
	power_profile_set_state(newstatus ? POWER_PROFILE_PERFORMANCE :
	    POWER_PROFILE_ECONOMY);
	ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
	    "%s Line\n", newstatus ? "On" : "Off");
	acpi_UserNotify("ACAD", h, newstatus);
    }
    ACPI_SERIAL_END(acad);
}
Beispiel #11
0
static void
acpi_lid_notify_status_changed(void *arg)
{
    struct acpi_lid_softc	*sc;
    struct acpi_softc		*acpi_sc;

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

    sc = (struct acpi_lid_softc *)arg;

    /*
     * Evaluate _LID and check the return value, update lid status.
     *	Zero:		The lid is closed
     *	Non-zero:	The lid is open
     */
    if (ACPI_FAILURE(acpi_EvaluateInteger(sc->lid_handle, "_LID", &sc->lid_status)))
	return_VOID;

    acpi_sc = acpi_device_get_parent_softc(sc->lid_dev);
    if (acpi_sc == NULL) {
        return_VOID;
    }

    ACPI_VPRINT(sc->lid_dev, acpi_sc,
	"Lid %s\n", sc->lid_status ? "opened" : "closed");

    if (sc->lid_status == 0) {
	EVENTHANDLER_INVOKE(acpi_sleep_event, acpi_sc->acpi_lid_switch_sx);
    } else {
	EVENTHANDLER_INVOKE(acpi_wakeup_event, acpi_sc->acpi_lid_switch_sx);
    }

    return_VOID;
}
Beispiel #12
0
/*
 * System power profile may have changed; fetch and notify the
 * thermal zone accordingly.
 *
 * Since this can be called from an arbitrary eventhandler, it needs
 * to get the ACPI lock itself.
 */
static void
acpi_tz_power_profile(void *arg)
{
    ACPI_STATUS			status;
    struct acpi_tz_softc	*sc = (struct acpi_tz_softc *)arg;
    int				state;

    state = power_profile_get_state();
    if (state != POWER_PROFILE_PERFORMANCE && state != POWER_PROFILE_ECONOMY)
	return;

    /* check that we haven't decided there's no _SCP method */
    if ((sc->tz_flags & TZ_FLAG_NO_SCP) == 0) {

	/* Call _SCP to set the new profile */
	status = acpi_SetInteger(sc->tz_handle, "_SCP",
	    (state == POWER_PROFILE_PERFORMANCE) ? 0 : 1);
	if (ACPI_FAILURE(status)) {
	    if (status != AE_NOT_FOUND)
		ACPI_VPRINT(sc->tz_dev,
			    acpi_device_get_parent_softc(sc->tz_dev),
			    "can't evaluate %s._SCP - %s\n",
			    acpi_name(sc->tz_handle),
			    AcpiFormatException(status));
	    sc->tz_flags |= TZ_FLAG_NO_SCP;
	} else {
	    /* We have to re-evaluate the entire zone now */
	    acpi_tz_signal(sc, TZ_FLAG_GETSETTINGS);
	}
    }
}
Beispiel #13
0
/*
 * Given an object, verify that it's a reference to a device of some sort,
 * and try to switch it on.
 *
 * XXX replication of off/on function code is bad.
 */
static void
acpi_tz_switch_cooler_on(ACPI_OBJECT *obj, void *arg)
{
    struct acpi_tz_softc	*sc = (struct acpi_tz_softc *)arg;
    ACPI_HANDLE			cooler;
    ACPI_STATUS			status;

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

    cooler = acpi_GetReference(NULL, obj);
    if (cooler == NULL) {
	ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "can't get handle\n"));
	return_VOID;
    }

    ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s on\n",
		     acpi_name(cooler)));
    status = acpi_pwr_switch_consumer(cooler, ACPI_STATE_D0);
    if (ACPI_FAILURE(status)) {
	ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
		    "failed to activate %s - %s\n", acpi_name(cooler),
		    AcpiFormatException(status));
    }

    return_VOID;
}
Beispiel #14
0
static void
acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
{
    struct acpi_tz_softc	*sc = (struct acpi_tz_softc *)context;

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

    switch (notify) {
    case TZ_NOTIFY_TEMPERATURE:
	/* Temperature change occurred */
	acpi_tz_signal(sc, 0);
	break;
    case TZ_NOTIFY_DEVICES:
    case TZ_NOTIFY_LEVELS:
	/* Zone devices/setpoints changed */
	acpi_tz_signal(sc, TZ_FLAG_GETSETTINGS);
	break;
    default:
	ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
		    "unknown Notify event 0x%x\n", notify);
	break;
    }

    acpi_UserNotify("Thermal", h, notify);

    return_VOID;
}
Beispiel #15
0
static void
acpi_button_notify_pressed_for_sleep(void *arg)
{
    struct acpi_button_softc	*sc;
    struct acpi_softc		*acpi_sc;

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

    sc = (struct acpi_button_softc *)arg;
    acpi_sc = acpi_device_get_parent_softc(sc->button_dev);
    if (acpi_sc == NULL) {
	return_VOID;
    }

    switch (sc->button_type) {
    case ACPI_POWER_BUTTON:
	ACPI_VPRINT(sc->button_dev, acpi_sc, "power button pressed\n");
	acpi_eventhandler_power_button_for_sleep((void *)acpi_sc);
	break;
    case ACPI_SLEEP_BUTTON:
	ACPI_VPRINT(sc->button_dev, acpi_sc, "sleep button pressed\n");
	acpi_eventhandler_sleep_button_for_sleep((void *)acpi_sc);
	break;
    default:
	break;		/* unknown button type */
    }
    return_VOID;
}
Beispiel #16
0
/*
 * Get the current temperature.
 */
static int
acpi_tz_get_temperature(struct acpi_tz_softc *sc)
{
    int		temp;
    ACPI_STATUS	status;

    ACPI_FUNCTION_NAME ("acpi_tz_get_temperature");

    /* Evaluate the thermal zone's _TMP method. */
    status = acpi_GetInteger(sc->tz_handle, acpi_tz_tmp_name, &temp);
    if (ACPI_FAILURE(status)) {
	ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
	    "error fetching current temperature -- %s\n",
	     AcpiFormatException(status));
	return (FALSE);
    }

    /* Check it for validity. */
    acpi_tz_sanity(sc, &temp, acpi_tz_tmp_name);
    if (temp == -1)
	return (FALSE);

    ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "got %d.%dC\n", TZ_KELVTOC(temp)));
    sc->tz_temperature = temp;
    return (TRUE);
}
static ACPI_STATUS
acpi_dock_eject_child(ACPI_HANDLE handle, UINT32 level, void *context,
    void **status)
{
	device_t	dock_dev, dev;
	ACPI_HANDLE	dock_handle;

	dock_dev = *(device_t *)context;
	dock_handle = acpi_get_handle(dock_dev);

	if (!acpi_dock_is_ejd_device(dock_handle, handle))
		goto out;

	ACPI_VPRINT(dock_dev, acpi_device_get_parent_softc(dock_dev),
	    "ejecting device for %s\n", acpi_name(handle));

	dev = acpi_get_device(handle);
	if (dev != NULL && device_is_attached(dev)) {
		mtx_lock(&Giant);
		device_detach(dev);
		mtx_unlock(&Giant);
	}

	acpi_SetInteger(handle, "_EJ0", 0);
out:
	return (AE_OK);
}
Beispiel #18
0
static int
acpi_panasonic_attach(device_t dev)
{
	struct acpi_panasonic_softc *sc;
	struct acpi_softc *acpi_sc;
	ACPI_STATUS status;
	int i;

	sc = device_get_softc(dev);
	sc->dev = dev;
	sc->handle = acpi_get_handle(dev);

	acpi_sc = acpi_device_get_parent_softc(dev);

	/* Build sysctl tree */
	sysctl_ctx_init(&sc->sysctl_ctx);
	sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
	    SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), OID_AUTO,
	    "panasonic", CTLFLAG_RD, 0, "");
	for (i = 0; sysctl_table[i].name != NULL; i++) {
		SYSCTL_ADD_PROC(&sc->sysctl_ctx,
		    SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
		    sysctl_table[i].name,
		    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY,
		    sc, i, acpi_panasonic_sysctl, "I", "");
	}

#if 0
	/* Activate hotkeys */
	status = AcpiEvaluateObject(sc->handle, "", NULL, NULL);
	if (ACPI_FAILURE(status)) {
		device_printf(dev, "enable FN keys failed\n");
		sysctl_ctx_free(&sc->sysctl_ctx);
		return (ENXIO);
	}
#endif

	/* Handle notifies */
	status = AcpiInstallNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY,
	    acpi_panasonic_notify, sc);
	if (ACPI_FAILURE(status)) {
		device_printf(dev, "couldn't install notify handler - %s\n",
		    AcpiFormatException(status));
		sysctl_ctx_free(&sc->sysctl_ctx);
		return (ENXIO);
	}

	/* Install power profile event handler */
	sc->power_evh = EVENTHANDLER_REGISTER(power_profile_change,
	    acpi_panasonic_power_profile, sc->handle, 0);

	return (0);
}
Beispiel #19
0
int
acpi_PkgStr(device_t dev, ACPI_OBJECT *res, int idx, void *dst, size_t size)
{
    ACPI_OBJECT		*obj;
    void		*ptr;
    size_t		 length;

    obj = &res->Package.Elements[idx];
    if (obj == NULL) {
	ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "PkgStr NULL object at %d\n", idx);
	return (-1);
    }
    bzero(dst, sizeof(dst));

    switch (obj->Type) {
    case ACPI_TYPE_STRING:
	ptr = obj->String.Pointer;
	length = obj->String.Length;
	break;
    case ACPI_TYPE_BUFFER:
	ptr = obj->Buffer.Pointer;
	length = obj->Buffer.Length;
	break;
    default:
	ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "PkgStr: invalid object type %d at %d\n", obj->Type, idx);
	return (-1);
    }

    /* Make sure string will fit, including terminating NUL */
    if (++length > size) {
	ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "PkgStr string too long (%zu bytes) at %d\n", length, idx);
	return (-1);
    }

    strlcpy(dst, ptr, length);
    return (0);
}
static void
acpi_acad_init_acline(void *arg)
{
    struct acpi_acad_softc *sc;
    device_t	dev;
    int		retry;

    dev = (device_t)arg;
    sc = device_get_softc(dev);
    ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		"acline initialization start\n");

    for (retry = 0; retry < ACPI_ACAD_RETRY_MAX; retry++) {
	acpi_acad_get_status(dev);
	if (sc->status != -1)
	    break;
	AcpiOsSleep(10000);
    }

    ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		"acline initialization done, tried %d times\n", retry + 1);
}
Beispiel #21
0
static void
acpi_panasonic_hkey_action(struct acpi_panasonic_softc *sc, ACPI_HANDLE h,
    UINT32 key)
{
	struct acpi_softc *acpi_sc;
	int arg, max, min;

	acpi_sc = acpi_device_get_parent_softc(sc->dev);

	ACPI_SERIAL_ASSERT(panasonic);
	switch (key) {
	case 1:
		/* Decrease LCD brightness. */
		hkey_lcd_brightness_max(h, HKEY_GET, &max);
		hkey_lcd_brightness_min(h, HKEY_GET, &min);
		hkey_lcd_brightness(h, HKEY_GET, &arg);
		arg -= max / HKEY_LCD_BRIGHTNESS_DIV;
		if (arg < min)
			arg = min;
		else if (arg > max)
			arg = max;
		hkey_lcd_brightness(h, HKEY_SET, &arg);
		break;
	case 2:
		/* Increase LCD brightness. */
		hkey_lcd_brightness_max(h, HKEY_GET, &max);
		hkey_lcd_brightness_min(h, HKEY_GET, &min);
		hkey_lcd_brightness(h, HKEY_GET, &arg);
		arg += max / HKEY_LCD_BRIGHTNESS_DIV;
		if (arg < min)
			arg = min;
		else if (arg > max)
			arg = max;
		hkey_lcd_brightness(h, HKEY_SET, &arg);
		break;
	case 4:
		/* Toggle sound mute. */
		hkey_sound_mute(h, HKEY_GET, &arg);
		if (arg)
			arg = 0;
		else
			arg = 1;
		hkey_sound_mute(h, HKEY_SET, &arg);
		break;
	case 7:
		/* Suspend. */
		acpi_event_sleep_button_sleep(acpi_sc);
		break;
	}
}
Beispiel #22
0
int
acpi_PkgInt(device_t dev, ACPI_OBJECT *res, int idx, ACPI_INTEGER *dst)
{
    ACPI_OBJECT		*obj;

    obj = &res->Package.Elements[idx];
    if (obj == NULL || obj->Type != ACPI_TYPE_INTEGER) {
	ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "PkgInt error, pkg[%d] at %d %p\n",
		    res->Package.Count, idx, obj);
	return (-1);
    }

    *dst = obj->Integer.Value;
    return (0);
}
Beispiel #23
0
static int
acpi_tz_cpufreq_restore(struct acpi_tz_softc *sc)
{
    device_t dev;
    int error;

    if (!sc->tz_cooling_updated)
	return (0);
    if ((dev = devclass_get_device(devclass_find("cpufreq"), 0)) == NULL)
	return (ENXIO);
    ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
	"temperature %d.%dC: resuming previous clock speed (%d MHz)\n",
	TZ_KELVTOC(sc->tz_temperature), sc->tz_cooling_saved_freq);
    error = CPUFREQ_SET(dev, NULL, CPUFREQ_PRIO_KERN);
    if (error == 0)
	sc->tz_cooling_updated = FALSE;
    return (error);
}
Beispiel #24
0
static ACPI_STATUS
EcWaitEvent(struct acpi_ec_softc *sc, EC_EVENT Event)
{
    EC_STATUS	EcStatus;
    UINT32	i = 0;

    if (!EcIsLocked(sc))
	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
	    "EcWaitEvent called without EC lock!\n");

    /*
     * Stall 1us:
     * ----------
     * Stall for 1 microsecond before reading the status register
     * for the first time.  This allows the EC to set the IBF/OBF
     * bit to its proper state.
     *
     * XXX it is not clear why we read the CSR twice.
     */
    AcpiOsStall(1);
    EcStatus = EC_GET_CSR(sc);

    /*
     * Wait For Event:
     * ---------------
     * Poll the EC status register to detect completion of the last
     * command.  Wait up to 10ms (in 10us chunks) for this to occur.
     */
    for (i = 0; i < 1000; i++) {
	EcStatus = EC_GET_CSR(sc);

        if ((Event == EC_EVENT_OUTPUT_BUFFER_FULL) &&
            (EcStatus & EC_FLAG_OUTPUT_BUFFER))
	    return(AE_OK);

	if ((Event == EC_EVENT_INPUT_BUFFER_EMPTY) && 
            !(EcStatus & EC_FLAG_INPUT_BUFFER))
	    return(AE_OK);
	
	AcpiOsStall(10);
    }

    return(AE_ERROR);
}    
static void
acpi_dock_get_info(device_t dev)
{
	struct acpi_dock_softc *sc;
	ACPI_HANDLE	h;

	sc = device_get_softc(dev);
	h = acpi_get_handle(dev);

	if (ACPI_FAILURE(acpi_GetInteger(h, "_STA", &sc->_sta)))
		sc->_sta = ACPI_DOCK_STATUS_UNKNOWN;
	if (ACPI_FAILURE(acpi_GetInteger(h, "_BDN", &sc->_bdn)))
		sc->_bdn = ACPI_DOCK_STATUS_UNKNOWN;
	if (ACPI_FAILURE(acpi_GetInteger(h, "_UID", &sc->_uid)))
		sc->_uid = ACPI_DOCK_STATUS_UNKNOWN;
	ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev),
		    "_STA: %04x, _BDN: %04x, _UID: %04x\n", sc->_sta,
		    sc->_bdn, sc->_uid);
}
Beispiel #26
0
static ACPI_STATUS
EcQuery(struct acpi_ec_softc *sc, UINT8 *Data)
{
    ACPI_STATUS	Status;

    if (ACPI_FAILURE(Status = EcLock(sc)))
	return(Status);

    EC_SET_CSR(sc, EC_COMMAND_QUERY);
    if (ACPI_SUCCESS(Status = EcWaitEvent(sc, EC_EVENT_OUTPUT_BUFFER_FULL)))
	*Data = EC_GET_DATA(sc);

    EcUnlock(sc);

    if (ACPI_FAILURE(Status))
	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
	    "timeout waiting for EC to respond to EC_COMMAND_QUERY\n");
    return(Status);
}    
static ACPI_STATUS
acpi_dock_insert_child(ACPI_HANDLE handle, UINT32 level, void *context,
    void **status)
{
	device_t	dock_dev, dev;
	ACPI_HANDLE	dock_handle;

	dock_dev = (device_t)context;
	dock_handle = acpi_get_handle(dock_dev);

	if (!acpi_dock_is_ejd_device(dock_handle, handle))
		goto out;

	ACPI_VPRINT(dock_dev, acpi_device_get_parent_softc(dock_dev),
		    "inserting device for %s\n", acpi_name(handle));

#if 0
	/*
	 * If the system boot up w/o Docking, the devices under the dock
	 * still un-initialized, also control methods such as _INI, _STA
	 * are not executed.
	 * Normal devices are initialized at booting by calling
	 * AcpiInitializeObjects(), however the devices under the dock
	 * need to be initialized here on the scheme of ACPICA.
	 */
	ACPI_INIT_WALK_INFO	Info;

	AcpiNsWalkNamespace(ACPI_TYPE_ANY, handle,
	    100, TRUE, AcpiNsInitOneDevice, &Info, NULL);
#endif

	dev = acpi_get_device(handle);
	if (dev == NULL) {
		device_printf(dock_dev, "error: %s has no associated device\n",
		    acpi_name(handle));
		goto out;
	}

	AcpiOsExecute(OSL_NOTIFY_HANDLER, acpi_dock_attach_later, dev);

out:
	return (AE_OK);
}
Beispiel #28
0
/*
 * Wait for an event interrupt for a specific condition.
 */
static ACPI_STATUS
EcWaitEventIntr(struct acpi_ec_softc *sc, EC_EVENT Event)
{
    EC_STATUS	EcStatus;
    int		i;

    ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, (UINT32)Event);

    /* XXX this should test whether interrupts are available some other way */
    if (cold || acpi_ec_event_driven)
	return_ACPI_STATUS(EcWaitEvent(sc, Event));

    if (!EcIsLocked(sc))
	ACPI_VPRINT(sc->ec_dev, acpi_device_get_parent_softc(sc->ec_dev),
	    "EcWaitEventIntr called without EC lock!\n");

    EcStatus = EC_GET_CSR(sc);

    /* XXX waiting too long? */
    for(i = 0; i < 10; i++){
	/*
	 * Check EC status against the desired event.
	 */
    	if ((Event == EC_EVENT_OUTPUT_BUFFER_FULL) &&
	    (EcStatus & EC_FLAG_OUTPUT_BUFFER))
	    return_ACPI_STATUS(AE_OK);
      
	if ((Event == EC_EVENT_INPUT_BUFFER_EMPTY) && 
	    !(EcStatus & EC_FLAG_INPUT_BUFFER))
	    return_ACPI_STATUS(AE_OK);
	
	sc->ec_csrvalue = 0;
	if (ACPI_MSLEEP(&sc->ec_csrvalue, &acpi_mutex, PZERO, "EcWait", 1) != EWOULDBLOCK){
	    EcStatus = sc->ec_csrvalue;
	}else{
	    EcStatus = EC_GET_CSR(sc);
	}
    }
    return_ACPI_STATUS(AE_ERROR);
}
Beispiel #29
0
static void
acpi_lid_notify_status_changed(void *arg)
{
    struct acpi_lid_softc	*sc;
    struct acpi_softc		*acpi_sc;
    ACPI_STATUS			status;

    ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__);

    sc = (struct acpi_lid_softc *)arg;
    ACPI_SERIAL_BEGIN(lid);

    /*
     * Evaluate _LID and check the return value, update lid status.
     *	Zero:		The lid is closed
     *	Non-zero:	The lid is open
     */
    status = acpi_GetInteger(sc->lid_handle, "_LID", &sc->lid_status);
    if (ACPI_FAILURE(status))
        goto out;

    acpi_sc = acpi_device_get_parent_softc(sc->lid_dev);
    if (acpi_sc == NULL)
        goto out;

    ACPI_VPRINT(sc->lid_dev, acpi_sc, "Lid %s\n",
                sc->lid_status ? "opened" : "closed");

    acpi_UserNotify("Lid", sc->lid_handle, sc->lid_status);

    if (sc->lid_status == 0)
        EVENTHANDLER_INVOKE(acpi_sleep_event, acpi_sc->acpi_lid_switch_sx);
    else
        EVENTHANDLER_INVOKE(acpi_wakeup_event, acpi_sc->acpi_lid_switch_sx);

out:
    ACPI_SERIAL_END(lid);
    return_VOID;
}
Beispiel #30
0
static int
acpi_acad_attach(device_t dev)
{
    struct acpi_acad_softc *sc;
    struct acpi_softc	   *acpi_sc;
    ACPI_HANDLE	handle;
    int		error;

    sc = device_get_softc(dev);
    handle = acpi_get_handle(dev);

    error = acpi_register_ioctl(ACPIIO_ACAD_GET_STATUS, acpi_acad_ioctl, dev);
    if (error != 0)
	return (error);

    ACPI_SERIAL_INIT(acad);

    if (device_get_unit(dev) == 0) {
	acpi_sc = acpi_device_get_parent_softc(dev);
	SYSCTL_ADD_PROC(&acpi_sc->acpi_sysctl_ctx,
			SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree),
			OID_AUTO, "acline", CTLTYPE_INT | CTLFLAG_RD,
			&sc->status, 0, acpi_acad_sysctl, "I", "");
    }

    /* Get initial status after whole system is up. */
    sc->status = -1;

    /*
     * Install both system and device notify handlers since the Casio
     * FIVA needs them.
     */
    AcpiInstallNotifyHandler(handle, ACPI_ALL_NOTIFY,
			     acpi_acad_notify_handler, dev);
    AcpiOsExecute(OSL_NOTIFY_HANDLER, acpi_acad_init_acline, dev);

    return (0);
}