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); }
int thinkpad_adaptive_change(struct acpithinkpad_softc *sc) { struct aml_value arg; int64_t mode; if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "GTRW", 0, NULL, &mode)) { printf("%s: couldn't get adaptive keyboard mode\n", DEVNAME(sc)); return (1); } bzero(&arg, sizeof(arg)); arg.type = AML_OBJTYPE_INTEGER; if (mode == THINKPAD_ADAPTIVE_MODE_FUNCTION) arg.v_integer = THINKPAD_ADAPTIVE_MODE_HOME; else arg.v_integer = THINKPAD_ADAPTIVE_MODE_FUNCTION; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "STRW", 1, &arg, NULL)) { printf("%s: couldn't set adaptive keyboard mode\n", DEVNAME(sc)); return (1); } return (0); }
int thinkpad_activate(struct device *self, int act) { struct acpithinkpad_softc *sc = (struct acpithinkpad_softc *)self; int64_t res; switch(act) { case DVACT_WAKEUP: if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "GTRW", 0, NULL, &res) == 0) thinkpad_adaptive_change(sc); break; } return (0); }
int acpidock_status(struct acpidock_softc *sc) { int64_t sta; int rv; if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL, &sta) != 0) { sta = 0; rv = 0; } else rv = 1; sc->sc_sta = sta; sc->sc_docked = sc->sc_sta & STA_PRESENT; return (rv); }
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; int64_t sta; sc->sc_acpi = (struct acpi_softc *)parent; sc->sc_devnode = aa->aaa_node; if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL, &sta)) { dnprintf(10, "%s: no _STA\n", DEVNAME(sc)); return; } if ((sta & 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); } /* create sensors */ acpibat_monitor(sc); /* populate sensors */ acpibat_refresh(sc); aml_register_notify(sc->sc_devnode, aa->aaa_dev, acpibat_notify, sc, ACPIDEV_POLL); }
int sdhc_acpi_match(struct device *parent, void *match, void *aux) { struct acpi_attach_args *aaa = aux; struct cfdata *cf = match; int64_t sta; if (!acpi_matchhids(aaa, sdhc_hids, cf->cf_driver->cd_name)) return 0; if (aml_evalinteger((struct acpi_softc *)parent, aaa->aaa_node, "_STA", 0, NULL, &sta)) sta = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000; if ((sta & STA_PRESENT) == 0) return 0; return 1; }
int thinkpad_match(struct device *parent, void *match, void *aux) { struct acpi_attach_args *aa = aux; struct cfdata *cf = match; int64_t res; if (!acpi_matchhids(aa, acpithinkpad_hids, cf->cf_driver->cd_name)) return (0); if (aml_evalinteger((struct acpi_softc *)parent, aa->aaa_node, "MHKV", 0, NULL, &res)) return (0); if (!(res == THINKPAD_HKEY_VERSION1 || res == THINKPAD_HKEY_VERSION2)) return (0); return (1); }
int thinkpad_enable_events(struct acpithinkpad_softc *sc) { struct aml_value arg, args[2]; int64_t mask; int i; /* Get the supported event mask */ if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "MHKA", 0, NULL, &mask)) { printf("%s: no MHKA\n", DEVNAME(sc)); return (1); } /* Update hotkey mask */ bzero(args, sizeof(args)); args[0].type = args[1].type = AML_OBJTYPE_INTEGER; for (i = 0; i < 32; i++) { args[0].v_integer = i + 1; args[1].v_integer = (((1 << i) & mask) != 0); if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "MHKM", 2, args, NULL)) { printf("%s: couldn't toggle MHKM\n", DEVNAME(sc)); return (1); } } /* Enable hotkeys */ bzero(&arg, sizeof(arg)); arg.type = AML_OBJTYPE_INTEGER; arg.v_integer = 1; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "MHKC", 1, &arg, NULL)) { printf("%s: couldn't enable hotkeys\n", DEVNAME(sc)); return (1); } return (0); }
void thinkpad_sensor_refresh(void *arg) { struct acpithinkpad_softc *sc = arg; u_int8_t lo, hi, i; int64_t tmp; char sname[5]; /* Refresh sensor readings */ for (i=0; i<THINKPAD_NTEMPSENSORS; i++) { snprintf(sname, sizeof(sname), "TMP%d", i); aml_evalinteger(sc->sc_acpi, sc->sc_ec->sc_devnode, sname, 0, 0, &tmp); sc->sc_sens[i].value = (tmp * 1000000) + 273150000; if (tmp > 127 || tmp < -127) sc->sc_sens[i].flags = SENSOR_FINVALID; } /* Read fan RPM */ acpiec_read(sc->sc_ec, THINKPAD_ECOFFSET_FANLO, 1, &lo); acpiec_read(sc->sc_ec, THINKPAD_ECOFFSET_FANHI, 1, &hi); sc->sc_sens[i].value = ((hi << 8L) + lo); }
int thinkpad_toggle_wan(struct acpithinkpad_softc *sc) { struct aml_value arg; int64_t wan; if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "GWAN", 0, NULL, &wan)) return (1); if (!(wan & THINKPAD_WAN_PRESENT)) return (1); bzero(&arg, sizeof(arg)); arg.type = AML_OBJTYPE_INTEGER; arg.v_integer = wan ^ THINKPAD_WAN_ENABLED; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "SWAN", 1, &arg, NULL)) { printf("%s: couldn't toggle wan\n", DEVNAME(sc)); return (1); } return (0); }
int thinkpad_toggle_bluetooth(struct acpithinkpad_softc *sc) { struct aml_value arg; int64_t bluetooth; if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "GBDC", 0, NULL, &bluetooth)) return (1); if (!(bluetooth & THINKPAD_BLUETOOTH_PRESENT)) return (1); bzero(&arg, sizeof(arg)); arg.type = AML_OBJTYPE_INTEGER; arg.v_integer = bluetooth ^ THINKPAD_BLUETOOTH_ENABLED; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "SBDC", 1, &arg, NULL)) { printf("%s: couldn't toggle bluetooth\n", DEVNAME(sc)); return (1); } return (0); }
int acpiec_getcrs(struct acpiec_softc *sc, struct acpi_attach_args *aa) { struct aml_value res; bus_size_t ec_sc, ec_data; int dtype, ctype; char *buf; int size, ret; int64_t gpe; struct acpi_ecdt *ecdt = aa->aaa_table; extern struct aml_node aml_root; /* Check if this is ECDT initialization */ if (ecdt) { /* Get GPE, Data and Control segments */ sc->sc_gpe = ecdt->gpe_bit; ctype = ecdt->ec_control.address_space_id; ec_sc = ecdt->ec_control.address; dtype = ecdt->ec_data.address_space_id; ec_data = ecdt->ec_data.address; /* Get devnode from header */ sc->sc_devnode = aml_searchname(&aml_root, ecdt->ec_id); goto ecdtdone; } if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "_GPE", 0, NULL, &gpe)) { dnprintf(10, "%s: no _GPE\n", DEVNAME(sc)); return (1); } sc->sc_gpe = gpe; if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_CRS", 0, NULL, &res)) { dnprintf(10, "%s: no _CRS\n", DEVNAME(sc)); return (1); } /* Parse CRS to get control and data registers */ if (res.type != AML_OBJTYPE_BUFFER) { dnprintf(10, "%s: unknown _CRS type %d\n", DEVNAME(sc), res.type); aml_freevalue(&res); return (1); } size = res.length; buf = res.v_buffer; ret = acpiec_getregister(buf, size, &dtype, &ec_data); if (ret <= 0) { dnprintf(10, "%s: failed to read DATA from _CRS\n", DEVNAME(sc)); aml_freevalue(&res); return (1); } buf += ret; size -= ret; ret = acpiec_getregister(buf, size, &ctype, &ec_sc); if (ret <= 0) { dnprintf(10, "%s: failed to read S/C from _CRS\n", DEVNAME(sc)); aml_freevalue(&res); return (1); } buf += ret; size -= ret; if (size != 2 || *buf != RES_TYPE_ENDTAG) { dnprintf(10, "%s: no _CRS end tag\n", DEVNAME(sc)); aml_freevalue(&res); return (1); } aml_freevalue(&res); /* XXX: todo - validate _CRS checksum? */ ecdtdone: dnprintf(10, "%s: Data: 0x%lx, S/C: 0x%lx\n", DEVNAME(sc), ec_data, ec_sc); if (ctype == GAS_SYSTEM_IOSPACE) sc->sc_cmd_bt = aa->aaa_iot; else sc->sc_cmd_bt = aa->aaa_memt; if (bus_space_map(sc->sc_cmd_bt, ec_sc, 1, 0, &sc->sc_cmd_bh)) { dnprintf(10, "%s: failed to map S/C reg.\n", DEVNAME(sc)); return (1); } if (dtype == GAS_SYSTEM_IOSPACE) sc->sc_data_bt = aa->aaa_iot; else sc->sc_data_bt = aa->aaa_memt; if (bus_space_map(sc->sc_data_bt, ec_data, 1, 0, &sc->sc_data_bh)) { dnprintf(10, "%s: failed to map DATA reg.\n", DEVNAME(sc)); bus_space_unmap(sc->sc_cmd_bt, sc->sc_cmd_bh, 1); return (1); } return (0); }
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); }