Esempio n. 1
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 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);
}
Esempio n. 3
0
static int
acpi_sony_attach(device_t dev)
{
	struct acpi_sony_softc *sc;
	int i;

	sc = device_get_softc(dev);
	acpi_GetInteger(acpi_get_handle(dev), ACPI_SONY_GET_PID, &sc->pid);
	device_printf(dev, "PID %x\n", sc->pid);
	for (i = 0 ; acpi_sony_oids[i].nodename != NULL; i++) {
		if (acpi_sony_oids[i].setmethod != NULL) {
			SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
			    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
			    i, acpi_sony_oids[i].nodename ,
			    CTLTYPE_INT | CTLFLAG_RW,
			    dev, i, sysctl_acpi_sony_gen_handler, "I",
			    acpi_sony_oids[i].comment);
		} else {
			SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
			    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
			    i, acpi_sony_oids[i].nodename ,
			    CTLTYPE_INT | CTLFLAG_RD,
			    dev, i, sysctl_acpi_sony_gen_handler, "I",
			    acpi_sony_oids[i].comment);
		}
	}
	return (0);
}
Esempio n. 4
0
static int
acpi_smbat_attach(device_t dev)
{
	struct acpi_smbat_softc *sc;
	uint32_t base;

	sc = device_get_softc(dev);
	if (ACPI_FAILURE(acpi_GetInteger(acpi_get_handle(dev), "_EC", &base))) {
		device_printf(dev, "cannot get EC base address\n");
		return (ENXIO);
	}
	sc->sb_base_addr = (base >> 8) & 0xff;

	/* XXX Only works with one EC, but nearly all systems only have one. */
	sc->ec_dev = devclass_get_device(devclass_find("acpi_ec"), 0);
	if (sc->ec_dev == NULL) {
		device_printf(dev, "cannot find EC device\n");
		return (ENXIO);
	}

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

	if (acpi_battery_register(dev) != 0) {
		device_printf(dev, "cannot register battery\n");
		return (ENXIO);
	}
	return (0);
}
Esempio n. 5
0
static ACPI_STATUS
acpi_pci_save_handle(ACPI_HANDLE handle, UINT32 level, void *context,
    void **status)
{
	struct acpi_pci_devinfo *dinfo;
	device_t *devlist;
	int devcount, i, func, slot;
	UINT32 address;

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

	if (ACPI_FAILURE(acpi_GetInteger(handle, "_ADR", &address)))
		return_ACPI_STATUS (AE_OK);
	slot = ACPI_ADR_PCI_SLOT(address);
	func = ACPI_ADR_PCI_FUNC(address);
	if (device_get_children((device_t)context, &devlist, &devcount) != 0)
		return_ACPI_STATUS (AE_OK);
	for (i = 0; i < devcount; i++) {
		dinfo = device_get_ivars(devlist[i]);
		if (dinfo->ap_dinfo.cfg.func == func &&
		    dinfo->ap_dinfo.cfg.slot == slot) {
			dinfo->ap_handle = handle;
			acpi_pci_update_device(handle, devlist[i]);
			break;
		}
	}
	free(devlist, M_TEMP);
	return_ACPI_STATUS (AE_OK);
}
Esempio n. 6
0
/*
 * Look for an ECDT and if we find one, set up default GPE and
 * space handlers to catch attempts to access EC space before
 * we have a real driver instance in place.
 *
 * TODO: Some old Gateway laptops need us to fake up an ECDT or
 * otherwise attach early so that _REG methods can run.
 */
void
acpi_ec_ecdt_probe(device_t parent)
{
    ACPI_TABLE_ECDT *ecdt;
    ACPI_STATUS	     status;
    device_t	     child;
    ACPI_HANDLE	     h;
    struct acpi_ec_params *params;

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

    /* Find and validate the ECDT. */
    status = AcpiGetTable(ACPI_SIG_ECDT, 1, (ACPI_TABLE_HEADER **)&ecdt);
    if (ACPI_FAILURE(status) ||
	ecdt->Control.BitWidth != 8 ||
	ecdt->Data.BitWidth != 8) {
	return;
    }

    /* Create the child device with the given unit number. */
    child = BUS_ADD_CHILD(parent, parent, 0, "acpi_ec", ecdt->Uid);
    if (child == NULL) {
	kprintf("%s: can't add child\n", __func__);
	return;
    }

    /* Find and save the ACPI handle for this device. */
    status = AcpiGetHandle(NULL, ecdt->Id, &h);
    if (ACPI_FAILURE(status)) {
	device_delete_child(parent, child);
	kprintf("%s: can't get handle\n", __func__);
	return;
    }
    acpi_set_handle(child, h);

    /* Set the data and CSR register addresses. */
    bus_set_resource(child, SYS_RES_IOPORT, 0, ecdt->Data.Address,
	/*count*/1, -1);
    bus_set_resource(child, SYS_RES_IOPORT, 1, ecdt->Control.Address,
	/*count*/1, -1);

    /*
     * Store values for the probe/attach routines to use.  Store the
     * ECDT GPE bit and set the global lock flag according to _GLK.
     * Note that it is not perfectly correct to be evaluating a method
     * before initializing devices, but in practice this function
     * should be safe to call at this point.
     */
    params = kmalloc(sizeof(struct acpi_ec_params), M_TEMP, M_WAITOK | M_ZERO);
    params->gpe_handle = NULL;
    params->gpe_bit = ecdt->Gpe;
    params->uid = ecdt->Uid;
    acpi_GetInteger(h, "_GLK", &params->glk);
    acpi_set_private(child, params);

    /* Finish the attach process. */
    if (device_probe_and_attach(child) != 0)
	device_delete_child(parent, child);
}
Esempio n. 7
0
/*
 * Query the get methods to determine what functionality is available
 * from the hardware function hotkeys.
 */
static uint8_t
acpi_fujitsu_check_hardware(struct acpi_fujitsu_softc *sc)
{
	int val;

	ACPI_SERIAL_ASSERT(fujitsu);
	/* save the hotkey bitmask */
	if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
	sc->gsif.name, &(sc->gsif.value)))) {
		sc->gsif.exists = 0;
		device_printf(sc->dev, "Couldn't query bitmask value\n");
	} else {
		sc->gsif.exists = 1;
	}

	/* System Volume Level */
	if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
	    sc->gvol.name, &val))) {
		sc->gvol.exists = 0;
	} else {
		sc->gvol.exists = 1;
	}

	if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
	    sc->gbll.name, &val))) {
		sc->gbll.exists = 0;
	} else {
		sc->gbll.exists = 1;
	}

	if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
	    sc->ghks.name, &val))) {
		sc->ghks.exists = 0;
	} else {
		sc->ghks.exists = 1;
	}

	if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
	    sc->gmou.name, &val))) {
		sc->gmou.exists = 0;
	} else {
		sc->gmou.exists = 1;
	}

	if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
	    sc->rbll.name, &val))) {
		sc->rbll.exists = 0;
	} else {
		sc->rbll.exists = 1;
	}

	if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
	    sc->rvol.name, &val))) {
		sc->rvol.exists = 0;
	} else {
		sc->rvol.exists = 1;
	}

	return (TRUE);
}
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);
}
Esempio n. 9
0
static int
acpi_fujitsu_method_get(struct acpi_fujitsu_softc *sc, int method)
{
	struct int_nameval	nv;
	ACPI_STATUS		status;

	ACPI_SERIAL_ASSERT(fujitsu);

	switch (method) {
		case METHOD_GBLL:
			nv = sc->gbll;
			break;
		case METHOD_GBLS:
			nv = sc->gbls;
			break;
		case METHOD_GMOU:
			nv = sc->gmou;
			break;
		case METHOD_GVOL:
		case METHOD_MUTE:
			nv = sc->gvol;
			break;
		case METHOD_GHKS:
			nv = sc->ghks;
			break;
		case METHOD_GSIF:
			nv = sc->gsif;
			break;
		case METHOD_RBLL:
			nv = sc->rbll;
			break;
		case METHOD_RVOL:
			nv = sc->rvol;
			break;
		default:
			return (FALSE);
	}

	if(!nv.exists)
		return (EINVAL);

	status = acpi_GetInteger(sc->handle, nv.name, &nv.value);
	if (ACPI_FAILURE(status)) {
		device_printf(sc->dev, "Couldn't query method (%s)\n", nv.name);
		return (FALSE);
	}

	if (method == METHOD_MUTE) {
		sc->bIsMuted = (uint8_t)((nv.value & VOLUME_MUTE_BIT) != 0);
		return (sc->bIsMuted);
	}

	nv.value &= GENERAL_SETTING_BITS;
	return (nv.value);
}
Esempio n. 10
0
/*
 * Read/debug-print a parameter, default it to -1.
 */
static void
acpi_tz_getparam(struct acpi_tz_softc *sc, char *node, int *data)
{

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

    if (ACPI_FAILURE(acpi_GetInteger(sc->tz_handle, node, data))) {
	*data = -1;
    } else {
	ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "%s.%s = %d\n",
			 acpi_name(sc->tz_handle), node, *data));
    }

    return_VOID;
}
Esempio n. 11
0
static int 
sysctl_acpi_sony_gen_handler(SYSCTL_HANDLER_ARGS)
{
	device_t	dev = arg1;
	int 	function = oidp->oid_arg2;
	int		error = 0, val;

	acpi_GetInteger(acpi_get_handle(dev),
	    acpi_sony_oids[function].getmethod, &val);
	error = sysctl_handle_int(oidp, &val, 0, req);
	if (error || !req->newptr || !acpi_sony_oids[function].setmethod)
		return (error);
	acpi_SetInteger(acpi_get_handle(dev),
	    acpi_sony_oids[function].setmethod, val);
	return (0);
}
Esempio n. 12
0
/*
 * Find the highest currently-supported performance state.
 * This can be called at runtime (e.g., due to a docking event) at
 * the request of a Notify on the processor object.
 */
static void
acpi_px_available(struct acpi_perf_softc *sc)
{
	ACPI_STATUS status;
	struct cf_setting set;

	status = acpi_GetInteger(sc->handle, "_PPC", &sc->px_max_avail);

	/* If the old state is too high, set current state to the new max. */
	if (ACPI_SUCCESS(status)) {
		if (sc->px_curr_state != CPUFREQ_VAL_UNKNOWN &&
		    sc->px_curr_state > sc->px_max_avail) {
			acpi_px_to_set(sc->dev,
			    &sc->px_states[sc->px_max_avail], &set);
			acpi_px_set(sc->dev, &set);
		}
	} else
		sc->px_max_avail = 0;
}
Esempio n. 13
0
static int
acpi_pci_child_location_str_method(device_t cbdev, device_t child, char *buf,
    size_t buflen)
{
    struct acpi_pci_devinfo *dinfo = device_get_ivars(child);
    int pxm;
    char buf2[32];

    pci_child_location_str_method(cbdev, child, buf, buflen);

    if (dinfo->ap_handle) {
        strlcat(buf, " handle=", buflen);
        strlcat(buf, acpi_name(dinfo->ap_handle), buflen);

        if (ACPI_SUCCESS(acpi_GetInteger(dinfo->ap_handle, "_PXM", &pxm))) {
                snprintf(buf2, 32, " _PXM=%d", pxm);
                strlcat(buf, buf2, buflen);
        }
    }
    return (0);
}
Esempio n. 14
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;
}
Esempio n. 15
0
static int
ipmi_acpi_attach(device_t dev)
{
	ACPI_HANDLE devh;
	const char *mode;
	struct ipmi_get_info info;
	struct ipmi_softc *sc = device_get_softc(dev);
	int count, error, flags, i, type;
	int interface_type = 0, interface_version = 0;

	error = 0;
	devh = acpi_get_handle(dev);
	if (ACPI_FAILURE(acpi_GetInteger(devh, "_IFT", &interface_type)))
		return (ENXIO);

	if (ACPI_FAILURE(acpi_GetInteger(devh, "_SRV", &interface_version)))
		return (ENXIO);

	switch (interface_type) {
	case KCS_MODE:
		count = 2;
		mode = "KCS";
		break;
	case SMIC_MODE:
		count = 3;
		mode = "SMIC";
		break;
	case BT_MODE:
		device_printf(dev, "BT interface not supported\n");
		return (ENXIO);
	case SSIF_MODE:
		if (ACPI_FAILURE(acpi_GetInteger(devh, "_ADR", &flags)))
			return (ENXIO);
		info.address = flags;
		device_printf(dev, "SSIF interface not supported on ACPI\n");
		return (0);
	default:
		return (ENXIO);
	}

	if (bus_get_resource(dev, SYS_RES_IOPORT, 0, NULL, NULL) == 0)
		type = SYS_RES_IOPORT;
	else if (bus_get_resource(dev, SYS_RES_MEMORY, 0, NULL, NULL) == 0)
		type = SYS_RES_MEMORY;
	else {
		device_printf(dev, "unknown resource type\n");
		return (ENXIO);
	}

	sc->ipmi_io_rid = 0;
	sc->ipmi_io_res[0] = bus_alloc_resource_any(dev, type,
	    &sc->ipmi_io_rid, RF_ACTIVE);
	sc->ipmi_io_type = type;
	sc->ipmi_io_spacing = 1;
	if (sc->ipmi_io_res[0] == NULL) {
		device_printf(dev, "couldn't configure I/O resource\n");
		return (ENXIO);
	}

	/* If we have multiple resources, allocate up to MAX_RES. */
	for (i = 1; i < MAX_RES; i++) {
		sc->ipmi_io_rid = i;
		sc->ipmi_io_res[i] = bus_alloc_resource_any(dev, type,
		    &sc->ipmi_io_rid, RF_ACTIVE);
		if (sc->ipmi_io_res[i] == NULL)
			break;
	}
	sc->ipmi_io_rid = 0;

	/* If we have multiple resources, make sure we have enough of them. */
	if (sc->ipmi_io_res[1] != NULL && sc->ipmi_io_res[count - 1] == NULL) {
		device_printf(dev, "too few I/O resources\n");
		error = ENXIO;
		goto bad;
	}

	device_printf(dev, "%s mode found at %s 0x%jx on %s\n",
	    mode, type == SYS_RES_IOPORT ? "io" : "mem",
	    (uintmax_t)rman_get_start(sc->ipmi_io_res[0]),
	    device_get_name(device_get_parent(dev)));

	sc->ipmi_dev = dev;

	/*
	 * Setup an interrupt if we have an interrupt resource.  We
	 * don't support GPE interrupts via _GPE yet.
	 */
	sc->ipmi_irq_rid = 0;
	sc->ipmi_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
	    &sc->ipmi_irq_rid, RF_SHAREABLE | RF_ACTIVE);

	/* Warn if _GPE exists. */
	if (ACPI_SUCCESS(AcpiEvaluateObject(devh, "_GPE", NULL, NULL)))
		device_printf(dev, "_GPE support not implemented\n");

	/*
	 * We assume an alignment of 1 byte as currently the IPMI spec
	 * doesn't provide any way to determine the alignment via ACPI.
	 */
	switch (interface_type) {
	case KCS_MODE:
		error = ipmi_kcs_attach(sc);
		if (error)
			goto bad;
		break;
	case SMIC_MODE:
		error = ipmi_smic_attach(sc);
		if (error)
			goto bad;
		break;
	}
	error = ipmi_attach(dev);
	if (error)
		goto bad;

	return (0);
bad:
	ipmi_release_resources(dev);
	return (error);
}
Esempio n. 16
0
static int
acpi_ec_probe(device_t dev)
{
    ACPI_BUFFER buf;
    ACPI_HANDLE h;
    ACPI_OBJECT *obj;
    ACPI_STATUS status;
    device_t	peer;
    char	desc[64];
    int		ecdt;
    int		ret;
    struct acpi_ec_params *params;
    static char *ec_ids[] = { "PNP0C09", NULL };

    /* Check that this is a device and that EC is not disabled. */
    if (acpi_get_type(dev) != ACPI_TYPE_DEVICE || acpi_disabled("ec"))
	return (ENXIO);

    /*
     * If probed via ECDT, set description and continue.  Otherwise,
     * we can access the namespace and make sure this is not a
     * duplicate probe.
     */
    ret = ENXIO;
    ecdt = 0;
    buf.Pointer = NULL;
    buf.Length = ACPI_ALLOCATE_BUFFER;
    params = acpi_get_private(dev);
    if (params != NULL) {
	ecdt = 1;
	ret = 0;
    } else if (ACPI_ID_PROBE(device_get_parent(dev), dev, ec_ids)) {
	params = kmalloc(sizeof(struct acpi_ec_params), M_TEMP,
			M_WAITOK | M_ZERO);
	h = acpi_get_handle(dev);

	/*
	 * Read the unit ID to check for duplicate attach and the
	 * global lock value to see if we should acquire it when
	 * accessing the EC.
	 */
	status = acpi_GetInteger(h, "_UID", &params->uid);
	if (ACPI_FAILURE(status))
	    params->uid = 0;
	status = acpi_GetInteger(h, "_GLK", &params->glk);
	if (ACPI_FAILURE(status))
	    params->glk = 0;

	/*
	 * Evaluate the _GPE method to find the GPE bit used by the EC to
	 * signal status (SCI).  If it's a package, it contains a reference
	 * and GPE bit, similar to _PRW.
	 */
	status = AcpiEvaluateObject(h, "_GPE", NULL, &buf);
	if (ACPI_FAILURE(status)) {
	    device_printf(dev, "can't evaluate _GPE - %s\n",
			  AcpiFormatException(status));
	    goto out;
	}
	obj = (ACPI_OBJECT *)buf.Pointer;
	if (obj == NULL)
	    goto out;

	switch (obj->Type) {
	case ACPI_TYPE_INTEGER:
	    params->gpe_handle = NULL;
	    params->gpe_bit = obj->Integer.Value;
	    break;
	case ACPI_TYPE_PACKAGE:
	    if (!ACPI_PKG_VALID(obj, 2))
		goto out;
	    params->gpe_handle =
		acpi_GetReference(NULL, &obj->Package.Elements[0]);
	    if (params->gpe_handle == NULL ||
		acpi_PkgInt32(obj, 1, &params->gpe_bit) != 0)
		goto out;
	    break;
	default:
	    device_printf(dev, "_GPE has invalid type %d\n", obj->Type);
	    goto out;
	}

	/* Store the values we got from the namespace for attach. */
	acpi_set_private(dev, params);

	/*
	 * Check for a duplicate probe.  This can happen when a probe
	 * via ECDT succeeded already.  If this is a duplicate, disable
	 * this device.
	 */
	peer = devclass_get_device(acpi_ec_devclass, params->uid);
	if (peer == NULL || !device_is_alive(peer))
	    ret = 0;
	else
	    device_disable(dev);
    }

out:
    if (ret == 0) {
	ksnprintf(desc, sizeof(desc), "Embedded Controller: GPE %#x%s%s",
		 params->gpe_bit, (params->glk) ? ", GLK" : "",
		 ecdt ? ", ECDT" : "");
	device_set_desc_copy(dev, desc);
    }

    if (ret > 0 && params)
	kfree(params, M_TEMP);
    if (buf.Pointer)
	AcpiOsFree(buf.Pointer);
    return (ret);
}
Esempio n. 17
0
/*
 * Query each of the ACPI control methods that contain information we're
 * interested in. We check the return values from the control methods and
 * adjust any state variables if they should be adjusted.
 */
static uint8_t
acpi_fujitsu_update(struct acpi_fujitsu_softc *sc)
{
	int changed;
	struct acpi_softc *acpi_sc;

	acpi_sc = acpi_device_get_parent_softc(sc->dev);

	ACPI_SERIAL_ASSERT(fujitsu);
	if(sc->gsif.exists)
		changed = sc->gsif.value & acpi_fujitsu_method_get(sc,METHOD_GHKS);
	else
		changed = 0;

	/* System Volume Level */
	if(sc->gvol.exists) {
		if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
		sc->gvol.name, &(sc->gvol.value)))) {
			device_printf(sc->dev, "Couldn't query volume level\n");
			return (FALSE);
		}
	
		if (changed & VOLUME_CHANGED) {
			sc->bIsMuted =
			(uint8_t)((sc->gvol.value & VOLUME_MUTE_BIT) != 0);
	
			/* Clear the modification bit */
			sc->gvol.value &= VOLUME_SETTING_BITS;
	
			if (sc->bIsMuted) {
				acpi_UserNotify("FUJITSU", sc->handle, FN_MUTE);
				ACPI_VPRINT(sc->dev, acpi_sc, "Volume is now mute\n");
			} else
				ACPI_VPRINT(sc->dev, acpi_sc, "Volume is now %d\n",
				sc->gvol.value);
	
			acpi_UserNotify("FUJITSU", sc->handle, FN_VOLUME);
		}
	}

	/* Internal mouse pointer (eraserhead) */
	if(sc->gmou.exists) {
		if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
		sc->gmou.name, &(sc->gmou.value)))) {
			device_printf(sc->dev, "Couldn't query pointer state\n");
			return (FALSE);
		}
	
		if (changed & MOUSE_CHANGED) {
			sc->bIntPtrEnabled = (uint8_t)(sc->gmou.value & 0x1);
	
			/* Clear the modification bit */
			sc->gmou.value &= MOUSE_SETTING_BITS;
			
			/* Set the value in case it is not hardware controlled */
                        acpi_fujitsu_method_set(sc, METHOD_GMOU, sc->gmou.value);

			acpi_UserNotify("FUJITSU", sc->handle, FN_POINTER_ENABLE);
	
			ACPI_VPRINT(sc->dev, acpi_sc, "Internal pointer is now %s\n",
			(sc->bIntPtrEnabled) ? "enabled" : "disabled");
		}
	}

	/* Screen Brightness Level P8XXX */
	if(sc->gbls.exists) {
		if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
                sc->gbls.name, &(sc->gbls.value)))) {
                        device_printf(sc->dev, "Couldn't query P8XXX brightness level\n");
                        return (FALSE);
                }
		if (changed & BRIGHT_CHANGED) {
			/* No state to record here. */

			/* Clear the modification bit */
			sc->gbls.value &= BRIGHTNESS_SETTING_BITS;

			/* Set the value in case it is not hardware controlled */
			acpi_fujitsu_method_set(sc, METHOD_GBLS, sc->gbls.value);

			acpi_UserNotify("FUJITSU", sc->handle, FN_LCD_BRIGHTNESS);

			ACPI_VPRINT(sc->dev, acpi_sc, "P8XXX Brightness level is now %d\n",
			sc->gbls.value);
                }
	}

	/* Screen Brightness Level */
	if(sc->gbll.exists) {
		if (ACPI_FAILURE(acpi_GetInteger(sc->handle,
		sc->gbll.name, &(sc->gbll.value)))) {
			device_printf(sc->dev, "Couldn't query brightness level\n");
			return (FALSE);
		}
	
		if (changed & BRIGHT_CHANGED) {
			/* No state to record here. */
	
			/* Clear the modification bit */
			sc->gbll.value &= BRIGHTNESS_SETTING_BITS;
	
			acpi_UserNotify("FUJITSU", sc->handle, FN_LCD_BRIGHTNESS);
	
			ACPI_VPRINT(sc->dev, acpi_sc, "Brightness level is now %d\n",
			sc->gbll.value);
		}
	}

	sc->lastValChanged = changed;
	return (TRUE);
}
Esempio n. 18
0
static int
bytgpio_attach(device_t dev)
{
	struct bytgpio_softc	*sc;
	ACPI_STATUS status;
	int uid;
	int pin;
	uint32_t reg, val;

	sc = device_get_softc(dev);
	sc->sc_dev = dev;
	sc->sc_handle = acpi_get_handle(dev);
	status = acpi_GetInteger(sc->sc_handle, "_UID", &uid);
	if (ACPI_FAILURE(status)) {
		device_printf(dev, "failed to read _UID\n");
		return (ENXIO);
	}

	BYTGPIO_LOCK_INIT(sc);

	switch (uid) {
	case SCORE_UID:
		sc->sc_npins = SCORE_PINS;
		sc->sc_bank_prefix = SCORE_BANK_PREFIX;
		sc->sc_pinpad_map = bytgpio_score_pins;
		break;
	case NCORE_UID:
		sc->sc_npins = NCORE_PINS;
		sc->sc_bank_prefix = NCORE_BANK_PREFIX;
		sc->sc_pinpad_map = bytgpio_ncore_pins;
		break;
	case SUS_UID:
		sc->sc_npins = SUS_PINS;
		sc->sc_bank_prefix = SUS_BANK_PREFIX;
		sc->sc_pinpad_map = bytgpio_sus_pins;
		break;
	default:
		device_printf(dev, "invalid _UID value: %d\n", uid);
		goto error;
	}

	sc->sc_pad_funcs = malloc(sizeof(int)*sc->sc_npins, M_DEVBUF,
	    M_WAITOK | M_ZERO);

	sc->sc_mem_rid = 0;
	sc->sc_mem_res = bus_alloc_resource_any(sc->sc_dev,
	    SYS_RES_MEMORY, &sc->sc_mem_rid, RF_ACTIVE);
	if (sc->sc_mem_res == NULL) {
		device_printf(dev, "can't allocate resource\n");
		goto error;
	}

	for (pin = 0; pin < sc->sc_npins; pin++) {
	    reg = BYGPIO_PIN_REGISTER(sc, pin, BYTGPIO_PCONF0);
	    val = bytgpio_read_4(sc, reg);
	    sc->sc_pad_funcs[pin] = val & BYTGPIO_PCONF0_FUNC_MASK;
	}

	sc->sc_busdev = gpiobus_attach_bus(dev);
	if (sc->sc_busdev == NULL) {
		BYTGPIO_LOCK_DESTROY(sc);
		bus_release_resource(dev, SYS_RES_MEMORY,
		    sc->sc_mem_rid, sc->sc_mem_res);
		return (ENXIO);
	}

	return (0);

error:
	BYTGPIO_LOCK_DESTROY(sc);

	return (ENXIO);
}
Esempio n. 19
0
static int
acpi_pcib_acpi_attach(device_t dev)
{
    struct acpi_hpcib_softc	*sc;
    ACPI_STATUS			status;
    static int bus0_seen = 0;
    u_int addr, slot, func, busok;
    uint8_t busno;

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

    sc = device_get_softc(dev);
    sc->ap_dev = dev;
    sc->ap_handle = acpi_get_handle(dev);

    /*
     * Get our segment number by evaluating _SEG
     * It's OK for this to not exist.
     */
    status = acpi_GetInteger(sc->ap_handle, "_SEG", &sc->ap_segment);
    if (ACPI_FAILURE(status)) {
	if (status != AE_NOT_FOUND) {
	    device_printf(dev, "could not evaluate _SEG - %s\n",
		AcpiFormatException(status));
	    return_VALUE (ENXIO);
	}
	/* If it's not found, assume 0. */
	sc->ap_segment = 0;
    }

    /*
     * Get our base bus number by evaluating _BBN.
     * If this doesn't work, we assume we're bus number 0.
     *
     * XXX note that it may also not exist in the case where we are
     *     meant to use a private configuration space mechanism for this bus,
     *     so we should dig out our resources and check to see if we have
     *     anything like that.  How do we do this?
     * XXX If we have the requisite information, and if we don't think the
     *     default PCI configuration space handlers can deal with this bus,
     *     we should attach our own handler.
     * XXX invoke _REG on this for the PCI config space address space?
     * XXX It seems many BIOS's with multiple Host-PCI bridges do not set
     *     _BBN correctly.  They set _BBN to zero for all bridges.  Thus,
     *     if _BBN is zero and PCI bus 0 already exists, we try to read our
     *     bus number from the configuration registers at address _ADR.
     *     We only do this for domain/segment 0 in the hopes that this is
     *     only needed for old single-domain machines.
     */
    status = acpi_GetInteger(sc->ap_handle, "_BBN", &sc->ap_bus);
    if (ACPI_FAILURE(status)) {
	if (status != AE_NOT_FOUND) {
	    device_printf(dev, "could not evaluate _BBN - %s\n",
		AcpiFormatException(status));
	    return_VALUE (ENXIO);
	} else {
	    /* If it's not found, assume 0. */
	    sc->ap_bus = 0;
	}
    }

    /*
     * If this is segment 0, the bus is zero, and PCI bus 0 already
     * exists, read the bus number via PCI config space.
     */
    busok = 1;
    if (sc->ap_segment == 0 && sc->ap_bus == 0 && bus0_seen) {
	busok = 0;
	status = acpi_GetInteger(sc->ap_handle, "_ADR", &addr);
	if (ACPI_FAILURE(status)) {
	    if (status != AE_NOT_FOUND) {
		device_printf(dev, "could not evaluate _ADR - %s\n",
		    AcpiFormatException(status));
		return_VALUE (ENXIO);
	    } else
		device_printf(dev, "couldn't find _ADR\n");
	} else {
	    /* XXX: We assume bus 0. */
	    slot = ACPI_ADR_PCI_SLOT(addr);
	    func = ACPI_ADR_PCI_FUNC(addr);
	    if (bootverbose)
		device_printf(dev, "reading config registers from 0:%d:%d\n",
		    slot, func);
	    if (host_pcib_get_busno(pci_cfgregread, 0, slot, func, &busno) == 0)
		device_printf(dev, "couldn't read bus number from cfg space\n");
	    else {
		sc->ap_bus = busno;
		busok = 1;
	    }
	}
    }

    /*
     * If nothing else worked, hope that ACPI at least lays out the
     * host-PCI bridges in order and that as a result our unit number
     * is actually our bus number.  There are several reasons this
     * might not be true.
     */
    if (busok == 0) {
	sc->ap_bus = device_get_unit(dev);
	device_printf(dev, "trying bus number %d\n", sc->ap_bus);
    }

    /* If this is bus 0 on segment 0, note that it has been seen already. */
    if (sc->ap_segment == 0 && sc->ap_bus == 0)
	    bus0_seen = 1;

    return (acpi_pcib_attach(dev, &sc->ap_prt, sc->ap_bus));
}