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
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
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");
}
Example #4
0
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);
}
Example #5
0
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);
}
Example #6
0
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));
}
Example #7
0
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");
}