static void slugbutt_deferred(device_t self) { struct slugbutt_softc *sc = device_private(self); struct ixp425_softc *ixsc = ixp425_softc; uint32_t reg; sc->sc_dev = self; /* Configure the GPIO pins as inputs */ reg = GPIO_CONF_READ_4(ixsc, IXP425_GPIO_GPOER); reg |= SLUGBUTT_PWR_BIT | SLUGBUTT_RST_BIT; GPIO_CONF_WRITE_4(ixsc, IXP425_GPIO_GPOER, reg); /* Configure the input type: Falling edge */ reg = GPIO_CONF_READ_4(ixsc, GPIO_TYPE_REG(GPIO_BUTTON_PWR)); reg &= ~GPIO_TYPE(GPIO_BUTTON_PWR, GPIO_TYPE_MASK); reg |= GPIO_TYPE(GPIO_BUTTON_PWR, GPIO_TYPE_EDG_FALLING); GPIO_CONF_WRITE_4(ixsc, GPIO_TYPE_REG(GPIO_BUTTON_PWR), reg); reg = GPIO_CONF_READ_4(ixsc, GPIO_TYPE_REG(GPIO_BUTTON_RST)); reg &= ~GPIO_TYPE(GPIO_BUTTON_RST, GPIO_TYPE_MASK); reg |= GPIO_TYPE(GPIO_BUTTON_RST, GPIO_TYPE_EDG_FALLING); GPIO_CONF_WRITE_4(ixsc, GPIO_TYPE_REG(GPIO_BUTTON_RST), reg); /* Clear any existing interrupt */ GPIO_CONF_WRITE_4(ixsc, IXP425_GPIO_GPISR, SLUGBUTT_PWR_BIT | SLUGBUTT_RST_BIT); sysmon_task_queue_init(); sc->sc_smpwr.smpsw_name = device_xname(sc->sc_dev); sc->sc_smpwr.smpsw_type = PSWITCH_TYPE_POWER; if (sysmon_pswitch_register(&sc->sc_smpwr) != 0) { printf("%s: unable to register power button with sysmon\n", device_xname(sc->sc_dev)); return; } sc->sc_smrst.smpsw_name = device_xname(sc->sc_dev); sc->sc_smrst.smpsw_type = PSWITCH_TYPE_RESET; if (sysmon_pswitch_register(&sc->sc_smrst) != 0) { printf("%s: unable to register reset button with sysmon\n", device_xname(sc->sc_dev)); return; } /* Hook the interrupts */ ixp425_intr_establish(BUTTON_PWR_INT, IPL_TTY, power_intr, sc); ixp425_intr_establish(BUTTON_RST_INT, IPL_TTY, reset_intr, sc); }
static void asus_attach(device_t parent, device_t self, void *opaque) { asus_softc_t *sc = device_private(self); struct acpi_attach_args *aa = opaque; ACPI_STATUS rv; sc->sc_node = aa->aa_node; sc->sc_dev = self; aprint_naive("\n"); aprint_normal("\n"); asus_init(self); 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; } rv = AcpiInstallNotifyHandler(sc->sc_node->ad_handle, ACPI_ALL_NOTIFY, asus_notify_handler, sc); if (ACPI_FAILURE(rv)) aprint_error_dev(self, "couldn't install notify handler: %s\n", AcpiFormatException(rv)); if (!pmf_device_register(self, asus_suspend, asus_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); }
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); }
static void btn_obio_attach(device_t parent, device_t self, void *aux) { struct obio_attach_args *oba = aux; struct btn_obio_softc *sc = device_private(self); int error; sc->sc_dev = self; sc->sc_iot = oba->oba_st; error = bus_space_map(sc->sc_iot, oba->oba_addr, 1, 0, &sc->sc_ioh); if (error) { aprint_error(": failed to map registers: %d\n", error); return; } sysmon_power_settype("landisk"); sysmon_task_queue_init(); /* power switch */ sc->sc_smpsw[0].smpsw_name = device_xname(self); sc->sc_smpsw[0].smpsw_type = PSWITCH_TYPE_POWER; if (sysmon_pswitch_register(&sc->sc_smpsw[0]) != 0) { aprint_error(": unable to register power button with sysmon\n"); return; } sc->sc_mask |= BTNSTAT_POWER; hdlg_enable_pldintr(INTEN_PWRSW); /* reset button */ sc->sc_smpsw[1].smpsw_name = device_xname(self); sc->sc_smpsw[1].smpsw_type = PSWITCH_TYPE_RESET; if (sysmon_pswitch_register(&sc->sc_smpsw[1]) != 0) { aprint_error(": unable to register reset button with sysmon\n"); return; } sc->sc_mask |= BTNSTAT_RESET; sc->sc_ih = i80321_intr_establish(oba->oba_irq, IPL_TTY, btn_intr, sc); if (sc->sc_ih == NULL) { aprint_error(": couldn't establish intr handler"); return; } hdlg_enable_pldintr(INTEN_BUTTON); aprint_normal("\n"); }
static void acpi_dalb_sysmon_init(struct acpi_dalb_softc *sc) { sc->sc_smpsw_valid = true; sc->sc_smpsw.smpsw_name = device_xname(sc->sc_dev); sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_HOTKEY; if (sysmon_pswitch_register(&sc->sc_smpsw)) { aprint_error_dev(sc->sc_dev, "couldn't register sleep with sysmon\n"); sc->sc_smpsw_valid = false; } }
static void n900audjck_attach(device_t parent, device_t self, void *aux) { struct n900audjck_softc *sc = device_private(self); struct gpio_attach_args *ga = aux; int caps; sc->sc_dev = self; sc->sc_gpio = ga->ga_gpio; /* map pins */ sc->sc_map.pm_map = sc->sc_map_pins; if (gpio_pin_map(sc->sc_gpio, ga->ga_offset, ga->ga_mask, &sc->sc_map)) { aprint_error(": couldn't map the pins\n"); return; } /* configure the input pin */ caps = gpio_pin_caps(sc->sc_gpio, &sc->sc_map, N900AUDJCK_PIN_INPUT); if (!(caps & GPIO_PIN_INPUT)) { aprint_error(": pin is unable to read input\n"); gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); return; } gpio_pin_ctl(sc->sc_gpio, &sc->sc_map, N900AUDJCK_PIN_INPUT, GPIO_PIN_INPUT); sc->sc_intr = intr_establish(N900AUDJCK_GPIO_BASE + ga->ga_offset, IPL_VM, IST_EDGE_BOTH, n900audjck_intr, sc); if (sc->sc_intr == NULL) { aprint_error(": couldn't establish interrupt\n"); gpio_pin_unmap(sc->sc_gpio, &sc->sc_map); return; } aprint_normal(": N900 audio jack\n"); aprint_naive(": N900 audio jack\n"); if (!pmf_device_register(sc->sc_dev, NULL, NULL)) { aprint_error_dev(sc->sc_dev, "couldn't establish power handler\n"); } sysmon_task_queue_init(); sc->sc_smpsw.smpsw_name = device_xname(self); sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_HOTKEY; sc->sc_state = PSWITCH_EVENT_RELEASED; sysmon_pswitch_register(&sc->sc_smpsw); /* report an event immediately if an audio jack is inserted */ n900audjck_refresh(sc); }
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 tps65217pmic_attach(device_t parent, device_t self, void *aux) { struct tps65217pmic_softc *sc = device_private(self); struct i2c_attach_args *ia = aux; sc->sc_dev = self; sc->sc_addr = ia->ia_addr; sc->sc_tag = ia->ia_tag; tps65217pmic_version(sc); aprint_normal(": TPS65217"); switch (sc->sc_version) { case TPS65217PMIC_CHIPID_VER_A: aprint_normal("A"); break; case TPS65217PMIC_CHIPID_VER_B: aprint_normal("B"); break; case TPS65217PMIC_CHIPID_VER_C: aprint_normal("C"); break; case TPS65217PMIC_CHIPID_VER_D: aprint_normal("D"); break; default: /* unknown version */ break; } aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n", sc->sc_revision); mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); sc->sc_smpsw.smpsw_name = device_xname(self); sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER; sysmon_pswitch_register(&sc->sc_smpsw); tps65217pmic_reg_refresh(sc); tps65217pmic_print_ppath(sc); tps65217pmic_print_ldos(sc); tps65217pmic_power_monitor_init(sc); tps65217pmic_envsys_register(sc); }
static void btn_obio_attach(device_t parent, device_t self, void *aux) { struct btn_obio_softc *sc; int i; aprint_naive("\n"); aprint_normal(": USL-5P buttons\n"); sc = device_private(self); sc->sc_dev = self; btn_softc = sc; callout_init(&sc->sc_guard_ch, 0); callout_setfunc(&sc->sc_guard_ch, btn_guard_timeout, sc); sc->sc_ih = extintr_establish(LANDISK_INTR_BTN, IPL_TTY, btn_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "unable to establish interrupt"); panic("extintr_establish"); } sc->sc_smpsw.smpsw_name = device_xname(self); sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_RESET; if (sysmon_pswitch_register(&sc->sc_smpsw) != 0) { aprint_error_dev(self, "unable to register with sysmon\n"); return; } sc->sc_mask |= BTN_RESET_BIT; for (i = 0; i < NBUTTON; i++) { int idx = btnlist[i].idx; sc->sc_bev[idx].bev_name = btnlist[i].name; if (btn_event_register(&sc->sc_bev[idx]) != 0) { aprint_error_dev(self, "unable to register '%s' button\n", btnlist[i].name); } else { sc->sc_mask |= btnlist[i].mask; } } }
static void powsw_attach(device_t parent, device_t self, void *aux) { struct powsw_softc *sc = device_private(self); powsw_desc_t *desc; const char *xname; int unit; int sw; unit = device_unit(self); xname = device_xname(self); desc = &powsw_desc[unit]; memset(sc, 0, sizeof(*sc)); sc->sc_dev = self; sc->sc_mask = desc->mask; sc->sc_prev = -1; powsw_reset_counter(sc); sysmon_task_queue_init(); sc->sc_smpsw.smpsw_name = xname; sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_POWER; if (sysmon_pswitch_register(&sc->sc_smpsw) != 0) panic("can't register with sysmon"); callout_init(&sc->sc_callout, 0); callout_setfunc(&sc->sc_callout, powsw_softintr, sc); if (shutdownhook_establish(powsw_shutdown_check, sc) == NULL) panic("%s: can't establish shutdown hook", xname); if (intio_intr_establish(desc->vector, xname, powsw_intr, sc) < 0) panic("%s: can't establish interrupt", xname); /* Set AER and enable interrupt */ sw = (mfp_get_gpip() & sc->sc_mask); powsw_set_aer(sc, sw ? 0 : 1); mfp_bit_set_ierb(sc->sc_mask); aprint_normal(": %s\n", desc->name); }
static void battery_attach(struct device *parent, struct device *self, void *aux) { struct battery_attach_args *baa = aux; struct battery_softc *sc = (struct battery_softc *)self; uint32_t reg; sc->sc_pmu_ops = baa->baa_pmu_ops; printf(": legacy battery "); reg = in32rb(0xf3000034); DPRINTF("reg: %08x\n", reg); if (reg & 0x20000000) { sc->sc_type = BTYPE_HOOPER; sc->sc_vmax_charged = 330; sc->sc_vmax_charging = 365; printf("[hooper]\n"); } else { sc->sc_type = BTYPE_COMET; sc->sc_vmax_charged = 189; sc->sc_vmax_charging = 213; printf("[comet]\n"); } battery_update(sc, 1); /* trigger a status update */ sc->sc_oflags = ~sc->sc_flags; battery_setup_envsys(sc); sc->sc_pmu_ops->register_callback(sc->sc_pmu_ops->cookie, battery_poll, sc); memset(&sc->sc_sm_acpower, 0, sizeof(struct sysmon_pswitch)); sc->sc_sm_acpower.smpsw_name = "AC Power"; sc->sc_sm_acpower.smpsw_type = PSWITCH_TYPE_ACADAPTER; if (sysmon_pswitch_register(&sc->sc_sm_acpower) != 0) printf("%s: unable to register AC power status with sysmon\n", sc->sc_dev.dv_xname); }
void spic_attach(struct spic_softc *sc) { struct wsmousedev_attach_args a; int i, rv; #ifdef SPIC_DEBUG if (spicdebug) printf("spic_attach %x\n", (uint)sc->sc_ioh); #endif callout_init(&sc->sc_poll, 0); spic_call1(sc, 0x82); spic_call2(sc, 0x81, 0xff); spic_call1(sc, 0x92); /* or 0x82 */ a.accessops = &spic_accessops; a.accesscookie = sc; sc->sc_wsmousedev = config_found(sc->sc_dev, &a, wsmousedevprint); sc->sc_smpsw[SPIC_PSWITCH_LID].smpsw_name = "spiclid0"; sc->sc_smpsw[SPIC_PSWITCH_LID].smpsw_type = PSWITCH_TYPE_LID; sc->sc_smpsw[SPIC_PSWITCH_SUSPEND].smpsw_name = "spicsuspend0"; sc->sc_smpsw[SPIC_PSWITCH_SUSPEND].smpsw_type = PSWITCH_TYPE_SLEEP; sc->sc_smpsw[SPIC_PSWITCH_HIBERNATE].smpsw_name = "spichibernate0"; sc->sc_smpsw[SPIC_PSWITCH_HIBERNATE].smpsw_type = PSWITCH_TYPE_SLEEP; for (i = 0; i < SPIC_NPSWITCH; i++) { rv = sysmon_pswitch_register(&sc->sc_smpsw[i]); if (rv != 0) aprint_error_dev(sc->sc_dev, "unable to register %s with sysmon\n", sc->sc_smpsw[i].smpsw_name); } callout_reset(&sc->sc_poll, POLLRATE, spictimeout, sc); return; }
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; ACPI_STATUS rv; ACPI_INTEGER val; int i; sc->sc_node = aa->aa_node; sc->sc_dev = self; sc->sc_display_state = THINKPAD_DISPLAY_LCD; aprint_naive("\n"); aprint_normal("\n"); /* T61 uses \UCMS method for issuing CMOS commands */ rv = AcpiGetHandle(NULL, "\\UCMS", &sc->sc_cmoshdl); if (ACPI_FAILURE(rv)) sc->sc_cmoshdl_valid = false; else { aprint_verbose_dev(self, "using CMOS at \\UCMS\n"); sc->sc_cmoshdl_valid = true; } sc->sc_ecdev = NULL; TAILQ_FOREACH(curdev, &alldevs, dv_list) if (device_is_a(curdev, "acpiecdt") || device_is_a(curdev, "acpiec")) { sc->sc_ecdev = curdev; break; } if (sc->sc_ecdev) aprint_verbose_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; } /* Install notify handler for events */ rv = AcpiInstallNotifyHandler(sc->sc_node->ad_handle, ACPI_DEVICE_NOTIFY, thinkpad_notify_handler, sc); if (ACPI_FAILURE(rv)) aprint_error_dev(self, "couldn't install notify handler: %s\n", AcpiFormatException(rv)); /* 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; 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"); }
static void sony_acpi_attach(device_t parent, device_t self, void *aux) { struct sony_acpi_softc *sc = device_private(self); struct acpi_attach_args *aa = aux; ACPI_STATUS rv; int i; aprint_naive(": Sony Miscellaneous Controller\n"); aprint_normal(": Sony Miscellaneous Controller\n"); sc->sc_node = aa->aa_node; sc->sc_dev = self; rv = AcpiWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 100, sony_acpi_find_pic, sc, NULL); if (ACPI_FAILURE(rv)) aprint_error_dev(self, "couldn't walk namespace: %s\n", AcpiFormatException(rv)); /* * If we don't find an SNY6001 device, assume that we need the * Fn key initialization sequence. */ if (sc->sc_has_pic == false) sc->sc_quirks |= SONY_ACPI_QUIRK_FNINIT; sony_acpi_quirk_setup(sc); /* Configure suspend button and hotkeys */ sc->sc_smpsw[SONY_PSW_SLEEP].smpsw_name = device_xname(self); sc->sc_smpsw[SONY_PSW_SLEEP].smpsw_type = PSWITCH_TYPE_SLEEP; sc->sc_smpsw[SONY_PSW_DISPLAY_CYCLE].smpsw_name = PSWITCH_HK_DISPLAY_CYCLE; sc->sc_smpsw[SONY_PSW_DISPLAY_CYCLE].smpsw_type = PSWITCH_TYPE_HOTKEY; sc->sc_smpsw[SONY_PSW_ZOOM].smpsw_name = PSWITCH_HK_ZOOM_BUTTON; sc->sc_smpsw[SONY_PSW_ZOOM].smpsw_type = PSWITCH_TYPE_HOTKEY; sc->sc_smpsw_valid = 1; for (i = 0; i < SONY_PSW_LAST; i++) if (sysmon_pswitch_register(&sc->sc_smpsw[i]) != 0) { aprint_error_dev(self, "couldn't register %s with sysmon\n", sc->sc_smpsw[i].smpsw_name); sc->sc_smpsw_valid = 0; } /* Install notify handler */ rv = AcpiInstallNotifyHandler(sc->sc_node->ad_handle, ACPI_DEVICE_NOTIFY, sony_acpi_notify_handler, self); if (ACPI_FAILURE(rv)) aprint_error_dev(self, "couldn't install notify handler (%d)\n", rv); /* Install sysctl handler */ rv = AcpiWalkNamespace(ACPI_TYPE_METHOD, sc->sc_node->ad_handle, 1, sony_walk_cb, sc, NULL); #ifdef DIAGNOSTIC if (ACPI_FAILURE(rv)) aprint_error_dev(self, "Cannot walk ACPI namespace (%d)\n", rv); #endif if (!pmf_device_register(self, sony_acpi_suspend, sony_acpi_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_UP, sony_acpi_brightness_up, true)) aprint_error_dev(self, "couldn't register BRIGHTNESS UP handler\n"); if (!pmf_event_register(self, PMFE_DISPLAY_BRIGHTNESS_DOWN, sony_acpi_brightness_down, true)) aprint_error_dev(self, "couldn't register BRIGHTNESS DOWN handler\n"); }
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"); }
static void vmt_attach(device_t parent, device_t self, void *aux) { int rv; struct vmt_softc *sc = device_private(self); aprint_naive("\n"); aprint_normal(": %s\n", vmt_type()); sc->sc_dev = self; sc->sc_log = NULL; callout_init(&sc->sc_tick, 0); callout_init(&sc->sc_tclo_tick, 0); callout_init(&sc->sc_clock_sync_tick, 0); sc->sc_clock_sync_period_seconds = VMT_CLOCK_SYNC_PERIOD_SECONDS; rv = vmt_sysctl_setup_root(self); if (rv != 0) { aprint_error_dev(self, "failed to initialize sysctl " "(err %d)\n", rv); goto free; } sc->sc_rpc_buf = kmem_alloc(VMT_RPC_BUFLEN, KM_SLEEP); if (sc->sc_rpc_buf == NULL) { aprint_error_dev(self, "unable to allocate buffer for RPC\n"); goto free; } if (vm_rpc_open(&sc->sc_tclo_rpc, VM_RPC_OPEN_TCLO) != 0) { aprint_error_dev(self, "failed to open backdoor RPC channel (TCLO protocol)\n"); goto free; } sc->sc_tclo_rpc_open = true; /* don't know if this is important at all yet */ if (vm_rpc_send_rpci_tx(sc, "tools.capability.hgfs_server toolbox 1") != 0) { aprint_error_dev(self, "failed to set HGFS server capability\n"); goto free; } pmf_device_register1(self, NULL, NULL, vmt_shutdown); sysmon_task_queue_init(); sc->sc_ev_power.ev_smpsw.smpsw_type = PSWITCH_TYPE_POWER; sc->sc_ev_power.ev_smpsw.smpsw_name = device_xname(self); sc->sc_ev_power.ev_code = PSWITCH_EVENT_PRESSED; sysmon_pswitch_register(&sc->sc_ev_power.ev_smpsw); sc->sc_ev_reset.ev_smpsw.smpsw_type = PSWITCH_TYPE_RESET; sc->sc_ev_reset.ev_smpsw.smpsw_name = device_xname(self); sc->sc_ev_reset.ev_code = PSWITCH_EVENT_PRESSED; sysmon_pswitch_register(&sc->sc_ev_reset.ev_smpsw); sc->sc_ev_sleep.ev_smpsw.smpsw_type = PSWITCH_TYPE_SLEEP; sc->sc_ev_sleep.ev_smpsw.smpsw_name = device_xname(self); sc->sc_ev_sleep.ev_code = PSWITCH_EVENT_RELEASED; sysmon_pswitch_register(&sc->sc_ev_sleep.ev_smpsw); sc->sc_smpsw_valid = true; callout_setfunc(&sc->sc_tick, vmt_tick, sc); callout_schedule(&sc->sc_tick, hz); callout_setfunc(&sc->sc_tclo_tick, vmt_tclo_tick, sc); callout_schedule(&sc->sc_tclo_tick, hz); sc->sc_tclo_ping = 1; callout_setfunc(&sc->sc_clock_sync_tick, vmt_clock_sync_tick, sc); callout_schedule(&sc->sc_clock_sync_tick, mstohz(sc->sc_clock_sync_period_seconds * 1000)); vmt_sync_guest_clock(sc); return; free: if (sc->sc_rpc_buf) kmem_free(sc->sc_rpc_buf, VMT_RPC_BUFLEN); pmf_device_register(self, NULL, NULL); if (sc->sc_log) sysctl_teardown(&sc->sc_log); }
static void wzero3kbd_attach(device_t parent, device_t self, void *aux) { struct wzero3kbd_softc *sc = device_private(self); struct pxaip_attach_args *pxa = (struct pxaip_attach_args *)aux; struct hpckbd_attach_args haa; const struct wzero3kbd_model *model; sc->sc_dev = self; model = wzero3kbd_lookup(); if (model == NULL) { aprint_error(": unknown model\n"); return; } aprint_normal(": keyboard\n"); aprint_naive("\n"); sc->sc_key_pin = model->key_pin; sc->sc_power_pin = model->power_pin; sc->sc_reset_pin = model->reset_pin; sc->sc_ncolumn = model->ncolumn; sc->sc_nrow = model->nrow; sc->sc_iot = pxa->pxa_iot; if (bus_space_map(sc->sc_iot, PXA2X0_CS2_START, REGMAPSIZE, 0, &sc->sc_ioh)) { aprint_error_dev(self, "couldn't map registers.\n"); return; } sc->sc_okeystat = malloc(sc->sc_nrow * sc->sc_ncolumn, M_DEVBUF, M_NOWAIT | M_ZERO); sc->sc_keystat = malloc(sc->sc_nrow * sc->sc_ncolumn, M_DEVBUF, M_NOWAIT | M_ZERO); if (sc->sc_okeystat == NULL || sc->sc_keystat == NULL) { aprint_error_dev(self, "couldn't alloc memory.\n"); if (sc->sc_okeystat) free(sc->sc_okeystat, M_DEVBUF); if (sc->sc_keystat) free(sc->sc_keystat, M_DEVBUF); return; } sc->sc_if.hii_ctx = sc; sc->sc_if.hii_establish = wzero3kbd_input_establish; sc->sc_if.hii_poll = wzero3kbd_poll; /* Attach console if not using serial. */ if (!(bootinfo->bi_cnuse & BI_CNUSE_SERIAL)) hpckbd_cnattach(&sc->sc_if); /* Install interrupt handler. */ if (sc->sc_key_pin >= 0) { pxa2x0_gpio_set_function(sc->sc_key_pin, GPIO_IN); sc->sc_key_ih = pxa2x0_gpio_intr_establish(sc->sc_key_pin, IST_EDGE_BOTH, IPL_TTY, wzero3kbd_intr, sc); if (sc->sc_key_ih == NULL) { aprint_error_dev(sc->sc_dev, "couldn't establish key interrupt\n"); } } else { sc->sc_interval = KEY_INTERVAL / (1000 / hz); if (sc->sc_interval < 1) sc->sc_interval = 1; callout_init(&sc->sc_keyscan_ch, 0); callout_reset(&sc->sc_keyscan_ch, sc->sc_interval, wzero3kbd_tick, sc); } /* power key */ if (sc->sc_power_pin >= 0) { pxa2x0_gpio_set_function(sc->sc_power_pin, GPIO_IN); sc->sc_power_ih = pxa2x0_gpio_intr_establish( sc->sc_power_pin, IST_EDGE_BOTH, IPL_TTY, wzero3kbd_power_intr, sc); if (sc->sc_power_ih == NULL) { aprint_error_dev(sc->sc_dev, "couldn't establish power key interrupt\n"); } } /* reset button */ if (sc->sc_reset_pin >= 0) { pxa2x0_gpio_set_function(sc->sc_reset_pin, GPIO_IN); sc->sc_reset_ih = pxa2x0_gpio_intr_establish( sc->sc_reset_pin, IST_EDGE_BOTH, IPL_TTY, wzero3kbd_reset_intr, sc); if (sc->sc_reset_ih == NULL) { aprint_error_dev(sc->sc_dev, "couldn't establish reset key interrupt\n"); } sc->sc_smpsw.smpsw_name = device_xname(self); sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_RESET; if (sysmon_pswitch_register(&sc->sc_smpsw) != 0) { aprint_error_dev(sc->sc_dev, "unable to register reset event handler\n"); } } /* Attach hpckbd. */ haa.haa_ic = &sc->sc_if; config_found(self, &haa, hpckbd_print); #if defined(KEYTEST) || defined(KEYTEST2) || defined(KEYTEST3) || defined(KEYTEST4) || defined(KEYTEST5) sc->sc_test_ih = NULL; sc->sc_test_pin = -1; sc->sc_nouse_pin = -1; sc->sc_nouse_pin2 = -1; sc->sc_nouse_pin3 = -1; sc->sc_bit = 0x01; if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS003SH) || platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS004SH)) { sc->sc_nouse_pin = GPIO_WS003SH_SD_DETECT; /* SD_DETECT */ sc->sc_nouse_pin2 = 86; /* Vsync? */ sc->sc_nouse_pin3 = 89; /* RESET? */ } if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS007SH)) { sc->sc_nouse_pin = GPIO_WS007SH_SD_DETECT; /* SD_DETECT */ sc->sc_nouse_pin2 = 77; /* Vsync? */ } if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS011SH)) { sc->sc_nouse_pin = GPIO_WS011SH_SD_DETECT; /* SD_DETECT */ sc->sc_nouse_pin2 = 77; /* Vsync? */ } if (platid_match(&platid, &platid_mask_MACH_SHARP_WZERO3_WS020SH)) { sc->sc_nouse_pin = GPIO_WS020SH_SD_DETECT; /* SD_DETECT */ sc->sc_nouse_pin2 = 77; /* Vsync? */ } #ifdef KEYTEST for (sc->sc_test_pin = 2; sc->sc_test_pin < PXA270_GPIO_NPINS; sc->sc_test_pin++) { if (sc->sc_test_pin != sc->sc_nouse_pin && sc->sc_test_pin != sc->sc_nouse_pin2 && sc->sc_test_pin != sc->sc_nouse_pin3 && sc->sc_test_pin != sc->sc_key_pin && sc->sc_test_pin != sc->sc_power_pin && sc->sc_test_pin != sc->sc_reset_pin && GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(sc->sc_test_pin))) break; } if (sc->sc_test_pin < PXA270_GPIO_NPINS) { printf("GPIO_IN: GPIO pin #%d\n", sc->sc_test_pin); sc->sc_test_ih = pxa2x0_gpio_intr_establish(sc->sc_test_pin, IST_EDGE_BOTH, IPL_TTY, wzero3kbd_intr2, sc); } else { sc->sc_test_pin = -1; } #endif #ifdef KEYTEST3 { int i; printf("pin: "); for (i = 0; i < PXA270_GPIO_NPINS; i++) { if (i == sc->sc_nouse_pin || i == sc->sc_nouse_pin2 || i == sc->sc_nouse_pin3 || i == sc->sc_key_pin || i == sc->sc_power_pin || i == sc->sc_reset_pin) continue; printf("%d, ", i); if (GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(i))) { pxa2x0_gpio_intr_establish(i, IST_EDGE_BOTH, IPL_TTY, wzero3kbd_intr3, (void *)(long)i); } } } #endif #ifdef KEYTEST4 for (sc->sc_test_pin = 2; sc->sc_test_pin < PXA270_GPIO_NPINS; sc->sc_test_pin++) { if (sc->sc_test_pin != sc->sc_nouse_pin && sc->sc_test_pin != sc->sc_nouse_pin2 && sc->sc_test_pin != sc->sc_nouse_pin3 && sc->sc_test_pin != sc->sc_key_pin && sc->sc_test_pin != sc->sc_power_pin && sc->sc_test_pin != sc->sc_reset_pin && GPIO_IS_GPIO_OUT(pxa2x0_gpio_get_function(sc->sc_test_pin))) break; } if (sc->sc_test_pin < PXA270_GPIO_NPINS) { printf("GPIO_OUT: GPIO pin #%d\n", sc->sc_test_pin); } else { sc->sc_test_pin = -1; } #endif #ifdef KEYTEST5 sc->sc_test_pin = 0x00; sc->sc_bit = 0x01; #endif #endif }
static void tctrl_sensor_setup(struct tctrl_softc *sc) { int i, error; sc->sc_sme = sysmon_envsys_create(); /* case temperature */ (void)strlcpy(sc->sc_sensor[0].desc, "Case temperature", sizeof(sc->sc_sensor[0].desc)); sc->sc_sensor[0].units = ENVSYS_STEMP; sc->sc_sensor[0].state = ENVSYS_SINVALID; /* battery voltage */ (void)strlcpy(sc->sc_sensor[1].desc, "Internal battery voltage", sizeof(sc->sc_sensor[1].desc)); sc->sc_sensor[1].units = ENVSYS_SVOLTS_DC; sc->sc_sensor[1].state = ENVSYS_SINVALID; /* DC voltage */ (void)strlcpy(sc->sc_sensor[2].desc, "DC-In voltage", sizeof(sc->sc_sensor[2].desc)); sc->sc_sensor[2].units = ENVSYS_SVOLTS_DC; sc->sc_sensor[2].state = ENVSYS_SINVALID; for (i = 0; i < ENVSYS_NUMSENSORS; i++) { if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor[i])) { sysmon_envsys_destroy(sc->sc_sme); return; } } sc->sc_sme->sme_name = device_xname(sc->sc_dev); sc->sc_sme->sme_cookie = sc; sc->sc_sme->sme_refresh = tctrl_refresh; if ((error = sysmon_envsys_register(sc->sc_sme)) != 0) { printf("%s: couldn't register sensors (%d)\n", device_xname(sc->sc_dev), error); sysmon_envsys_destroy(sc->sc_sme); return; } /* now register the power button */ sysmon_task_queue_init(); sc->sc_powerpressed = 0; memset(&sc->sc_sm_pbutton, 0, sizeof(struct sysmon_pswitch)); sc->sc_sm_pbutton.smpsw_name = device_xname(sc->sc_dev); sc->sc_sm_pbutton.smpsw_type = PSWITCH_TYPE_POWER; if (sysmon_pswitch_register(&sc->sc_sm_pbutton) != 0) printf("%s: unable to register power button with sysmon\n", device_xname(sc->sc_dev)); memset(&sc->sc_sm_lid, 0, sizeof(struct sysmon_pswitch)); sc->sc_sm_lid.smpsw_name = device_xname(sc->sc_dev); sc->sc_sm_lid.smpsw_type = PSWITCH_TYPE_LID; if (sysmon_pswitch_register(&sc->sc_sm_lid) != 0) printf("%s: unable to register lid switch with sysmon\n", device_xname(sc->sc_dev)); memset(&sc->sc_sm_ac, 0, sizeof(struct sysmon_pswitch)); sc->sc_sm_ac.smpsw_name = device_xname(sc->sc_dev); sc->sc_sm_ac.smpsw_type = PSWITCH_TYPE_ACADAPTER; if (sysmon_pswitch_register(&sc->sc_sm_ac) != 0) printf("%s: unable to register AC adaptor with sysmon\n", device_xname(sc->sc_dev)); }
static void pmu_attach(device_t parent, device_t self, void *aux) { struct confargs *ca = aux; struct pmu_softc *sc = device_private(self); #if notyet struct i2cbus_attach_args iba; #endif uint32_t regs[16]; int irq = ca->ca_intr[0]; int node, extint_node, root_node; int nbat = 1, i, pmnode; int type = IST_EDGE; uint8_t cmd[2] = {2, 0}; uint8_t resp[16]; char name[256]; extint_node = of_getnode_byname(OF_parent(ca->ca_node), "extint-gpio1"); if (extint_node) { OF_getprop(extint_node, "interrupts", &irq, 4); type = IST_LEVEL; } aprint_normal(" irq %d: ", irq); sc->sc_dev = self; sc->sc_node = ca->ca_node; sc->sc_memt = ca->ca_tag; root_node = OF_finddevice("/"); sc->sc_error = 0; sc->sc_autopoll = 0; sc->sc_pending_eject = 0; sc->sc_brightness = sc->sc_brightness_wanted = 0x80; sc->sc_volume = sc->sc_volume_wanted = 0x80; sc->sc_flags = 0; sc->sc_callback = NULL; sc->sc_lid_closed = 0; if (bus_space_map(sc->sc_memt, ca->ca_reg[0] + ca->ca_baseaddr, ca->ca_reg[1], 0, &sc->sc_memh) != 0) { aprint_error_dev(self, "unable to map registers\n"); return; } sc->sc_ih = intr_establish(irq, type, IPL_TTY, pmu_intr, sc); pmu_init(sc); sc->sc_pmu_ops.cookie = sc; sc->sc_pmu_ops.do_command = pmu_send; sc->sc_pmu_ops.register_callback = pmu_register_callback; if (pmu0 == NULL) pmu0 = sc; pmu_send(sc, PMU_SYSTEM_READY, 1, cmd, 16, resp); /* check what kind of PMU we're talking to */ if (pmu_send(sc, PMU_GET_VERSION, 0, cmd, 16, resp) > 1) aprint_normal(" rev. %d", resp[1]); aprint_normal("\n"); node = OF_child(sc->sc_node); while (node != 0) { if (OF_getprop(node, "name", name, 256) == 0) goto next; if (strncmp(name, "pmu-i2c", 8) == 0) { aprint_normal_dev(self, "initializing IIC bus\n"); goto next; } if (strncmp(name, "adb", 4) == 0) { aprint_normal_dev(self, "initializing ADB\n"); sc->sc_adbops.cookie = sc; sc->sc_adbops.send = pmu_adb_send; sc->sc_adbops.poll = pmu_adb_poll; sc->sc_adbops.autopoll = pmu_autopoll; sc->sc_adbops.set_handler = pmu_adb_set_handler; #if NNADB > 0 config_found_ia(self, "adb_bus", &sc->sc_adbops, nadb_print); #endif goto next; } if (strncmp(name, "rtc", 4) == 0) { aprint_normal_dev(self, "initializing RTC\n"); sc->sc_todr.todr_gettime = pmu_todr_get; sc->sc_todr.todr_settime = pmu_todr_set; sc->sc_todr.cookie = sc; todr_attach(&sc->sc_todr); goto next; } if (strncmp(name, "battery", 8) == 0) goto next; aprint_normal_dev(self, "%s not configured\n", name); next: node = OF_peer(node); } if (OF_finddevice("/bandit/ohare") != -1) { aprint_normal_dev(self, "enabling ohare backlight control\n"); sc->sc_flags |= PMU_HAS_BACKLIGHT_CONTROL; cmd[0] = 0; cmd[1] = 0; memset(resp, 0, 6); if (pmu_send(sc, PMU_READ_BRIGHTNESS, 1, cmd, 16, resp) > 1) { sc->sc_brightness_wanted = resp[1]; pmu_update_brightness(sc); } } /* attach batteries */ if (of_compatible(root_node, has_legacy_battery) != -1) { pmu_attach_legacy_battery(sc); } else if (of_compatible(root_node, has_two_smart_batteries) != -1) { pmu_attach_smart_battery(sc, 0); pmu_attach_smart_battery(sc, 1); } else { /* check how many batteries we have */ pmnode = of_getnode_byname(ca->ca_node, "power-mgt"); if (pmnode == -1) goto bat_done; if (OF_getprop(pmnode, "prim-info", regs, sizeof(regs)) < 24) goto bat_done; nbat = regs[6] >> 16; for (i = 0; i < nbat; i++) pmu_attach_smart_battery(sc, i); } bat_done: #if notyet memset(&iba, 0, sizeof(iba)); iba.iba_tag = &sc->sc_i2c; sc->sc_i2c.ic_cookie = sc; sc->sc_i2c.ic_acquire_bus = pmu_i2c_acquire_bus; sc->sc_i2c.ic_release_bus = pmu_i2c_release_bus; sc->sc_i2c.ic_send_start = NULL; sc->sc_i2c.ic_send_stop = NULL; sc->sc_i2c.ic_initiate_xfer = NULL; sc->sc_i2c.ic_read_byte = NULL; sc->sc_i2c.ic_write_byte = NULL; sc->sc_i2c.ic_exec = pmu_i2c_exec; config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print); #endif if (kthread_create(PRI_NONE, 0, NULL, pmu_thread, sc, &sc->sc_thread, "%s", "pmu") != 0) { aprint_error_dev(self, "unable to create event kthread\n"); } sc->sc_lidswitch.smpsw_name = "Lid switch"; sc->sc_lidswitch.smpsw_type = PSWITCH_TYPE_LID; if (sysmon_pswitch_register(&sc->sc_lidswitch) != 0) aprint_error_dev(self, "unable to register lid switch with sysmon\n"); }
static void adbkbd_attach(device_t parent, device_t self, void *aux) { struct adbkbd_softc *sc = device_private(self); struct adb_attach_args *aaa = aux; short cmd; struct wskbddev_attach_args a; #if NWSMOUSE > 0 struct wsmousedev_attach_args am; #endif uint8_t buffer[2]; sc->sc_dev = self; sc->sc_ops = aaa->ops; sc->sc_adbdev = aaa->dev; sc->sc_adbdev->cookie = sc; sc->sc_adbdev->handler = adbkbd_handler; sc->sc_us = ADBTALK(sc->sc_adbdev->current_addr, 0); sc->sc_leds = 0; /* initially off */ sc->sc_have_led_control = 0; /* * If this is != 0 then pushing the power button will not immadiately * send a shutdown event to sysmon but instead require another key * press within 5 seconds with a gap of at least two seconds. The * reason to do this is the fact that some PowerBook keyboards, * like the 2400, 3400 and original G3 have their power buttons * right next to the backspace key and it's extremely easy to hit * it by accident. * On most other keyboards the power button is sufficiently far out * of the way so we don't need this. */ sc->sc_power_button_delay = 0; sc->sc_msg_len = 0; sc->sc_poll = 0; sc->sc_capslock = 0; sc->sc_trans[1] = 103; /* F11 */ sc->sc_trans[2] = 111; /* F12 */ /* * Most ADB keyboards send 0x7f 0x7f when the power button is pressed. * Some older PowerBooks, like the 3400c, will send a single scancode * 0x7e instead. Unfortunately Fn-Command on some more recent *Books * sends the same scancode, so by default sc_power is set to a value * that can't occur as a scancode and only set to 0x7e on hardware that * needs it */ sc->sc_power = 0xffff; sc->sc_timestamp = 0; sc->sc_emul_usb = FALSE; aprint_normal(" addr %d: ", sc->sc_adbdev->current_addr); switch (sc->sc_adbdev->handler_id) { case ADB_STDKBD: aprint_normal("standard keyboard\n"); break; case ADB_ISOKBD: aprint_normal("standard keyboard (ISO layout)\n"); break; case ADB_EXTKBD: cmd = ADBTALK(sc->sc_adbdev->current_addr, 1); sc->sc_msg_len = 0; sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 0, NULL); adbkbd_wait(sc, 10); /* Ignore Logitech MouseMan/Trackman pseudo keyboard */ /* XXX needs testing */ if (sc->sc_buffer[2] == 0x9a && sc->sc_buffer[3] == 0x20) { aprint_normal("Mouseman (non-EMP) pseudo keyboard\n"); return; } else if (sc->sc_buffer[2] == 0x9a && sc->sc_buffer[3] == 0x21) { aprint_normal("Trackman (non-EMP) pseudo keyboard\n"); return; } else { aprint_normal("extended keyboard\n"); adbkbd_initleds(sc); } break; case ADB_EXTISOKBD: aprint_normal("extended keyboard (ISO layout)\n"); adbkbd_initleds(sc); break; case ADB_KBDII: aprint_normal("keyboard II\n"); break; case ADB_ISOKBDII: aprint_normal("keyboard II (ISO layout)\n"); break; case ADB_PBKBD: aprint_normal("PowerBook keyboard\n"); sc->sc_power = 0x7e; sc->sc_power_button_delay = 1; break; case ADB_PBISOKBD: aprint_normal("PowerBook keyboard (ISO layout)\n"); sc->sc_power = 0x7e; sc->sc_power_button_delay = 1; break; case ADB_ADJKPD: aprint_normal("adjustable keypad\n"); break; case ADB_ADJKBD: aprint_normal("adjustable keyboard\n"); break; case ADB_ADJISOKBD: aprint_normal("adjustable keyboard (ISO layout)\n"); break; case ADB_ADJJAPKBD: aprint_normal("adjustable keyboard (Japanese layout)\n"); break; case ADB_PBEXTISOKBD: aprint_normal("PowerBook extended keyboard (ISO layout)\n"); sc->sc_power_button_delay = 1; sc->sc_power = 0x7e; break; case ADB_PBEXTJAPKBD: aprint_normal("PowerBook extended keyboard (Japanese layout)\n"); sc->sc_power_button_delay = 1; sc->sc_power = 0x7e; break; case ADB_JPKBDII: aprint_normal("keyboard II (Japanese layout)\n"); break; case ADB_PBEXTKBD: aprint_normal("PowerBook extended keyboard\n"); sc->sc_power_button_delay = 1; sc->sc_power = 0x7e; break; case ADB_DESIGNKBD: aprint_normal("extended keyboard\n"); adbkbd_initleds(sc); break; case ADB_PBJPKBD: aprint_normal("PowerBook keyboard (Japanese layout)\n"); sc->sc_power_button_delay = 1; sc->sc_power = 0x7e; break; case ADB_PBG3KBD: aprint_normal("PowerBook G3 keyboard\n"); break; case ADB_PBG3JPKBD: aprint_normal("PowerBook G3 keyboard (Japanese layout)\n"); break; case ADB_IBOOKKBD: aprint_normal("iBook keyboard\n"); break; default: aprint_normal("mapped device (%d)\n", sc->sc_adbdev->handler_id); break; } /* * try to switch to extended protocol * as in, tell the keyboard to distinguish between left and right * Shift, Control and Alt keys */ cmd = ADBLISTEN(sc->sc_adbdev->current_addr, 3); buffer[0] = sc->sc_adbdev->current_addr; buffer[1] = 3; sc->sc_msg_len = 0; sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 2, buffer); adbkbd_wait(sc, 10); cmd = ADBTALK(sc->sc_adbdev->current_addr, 3); sc->sc_msg_len = 0; sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 0, NULL); adbkbd_wait(sc, 10); if ((sc->sc_msg_len == 4) && (sc->sc_buffer[3] == 3)) { aprint_verbose_dev(sc->sc_dev, "extended protocol enabled\n"); } if (adbkbd_is_console && (adbkbd_console_attached == 0)) { wskbd_cnattach(&adbkbd_consops, sc, &adbkbd_keymapdata); adbkbd_console_attached = 1; a.console = 1; } else { a.console = 0; } a.keymap = &adbkbd_keymapdata; a.accessops = &adbkbd_accessops; a.accesscookie = sc; sc->sc_wskbddev = config_found_ia(self, "wskbddev", &a, wskbddevprint); #ifdef ADBKBD_EMUL_USB sc->sc_emul_usb = TRUE; wskbd_set_evtrans(sc->sc_wskbddev, adb_to_usb, 128); #endif /* ADBKBD_EMUL_USB */ #if NWSMOUSE > 0 /* attach the mouse device */ am.accessops = &adbkms_accessops; am.accesscookie = sc; sc->sc_wsmousedev = config_found_ia(self, "wsmousedev", &am, wsmousedevprint); #endif adbkbd_setup_sysctl(sc); /* finally register the power button */ sysmon_task_queue_init(); memset(&sc->sc_sm_pbutton, 0, sizeof(struct sysmon_pswitch)); sc->sc_sm_pbutton.smpsw_name = device_xname(sc->sc_dev); sc->sc_sm_pbutton.smpsw_type = PSWITCH_TYPE_POWER; if (sysmon_pswitch_register(&sc->sc_sm_pbutton) != 0) aprint_error_dev(sc->sc_dev, "unable to register power button with sysmon\n"); }