Ejemplo n.º 1
0
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");
}
Ejemplo n.º 2
0
static void
cuda_attach(device_t parent, device_t dev, void *aux)
{
	struct confargs *ca = aux;
	struct cuda_softc *sc = device_private(dev);
	struct i2cbus_attach_args iba;
	static struct cuda_attach_args caa;
	int irq = ca->ca_intr[0];
	int node, i, child;
	char name[32];

	sc->sc_dev = dev;
	node = of_getnode_byname(OF_parent(ca->ca_node), "extint-gpio1");
	if (node)
		OF_getprop(node, "interrupts", &irq, 4);

	printf(" irq %d: ", irq);

	sc->sc_node = ca->ca_node;
	sc->sc_memt = ca->ca_tag;

	sc->sc_sent = 0;
	sc->sc_received = 0;
	sc->sc_waiting = 0;
	sc->sc_polling = 0;
	sc->sc_state = CUDA_NOTREADY;
	sc->sc_error = 0;
	sc->sc_i2c_read_len = 0;

	if (bus_space_map(sc->sc_memt, ca->ca_reg[0] + ca->ca_baseaddr,
	    ca->ca_reg[1], 0, &sc->sc_memh) != 0) {

		printf("%s: unable to map registers\n", dev->dv_xname);
		return;
	}
	sc->sc_ih = intr_establish(irq, IST_EDGE, IPL_TTY, cuda_intr, sc);
	printf("\n");

	for (i = 0; i < 16; i++) {
		sc->sc_handlers[i].handler = NULL;
		sc->sc_handlers[i].cookie = NULL;
	}

	cuda_init(sc);

	/* now attach children */
	config_interrupts(dev, cuda_final);
	cuda_set_handler(sc, CUDA_ERROR, cuda_error_handler, sc);
	cuda_set_handler(sc, CUDA_PSEUDO, cuda_todr_handler, sc);

	child = OF_child(ca->ca_node);
	while (child != 0) {

		if (OF_getprop(child, "name", name, 32) == 0)
			continue;
		if (strncmp(name, "adb", 4) == 0) {

			cuda_set_handler(sc, CUDA_ADB, cuda_adb_handler, sc);
			sc->sc_adbops.cookie = sc;
			sc->sc_adbops.send = cuda_adb_send;
			sc->sc_adbops.poll = cuda_adb_poll;
			sc->sc_adbops.autopoll = cuda_autopoll;
			sc->sc_adbops.set_handler = cuda_adb_set_handler;
			config_found_ia(dev, "adb_bus", &sc->sc_adbops,
			    nadb_print);
		} else if (strncmp(name, "rtc", 4) == 0) {

			sc->sc_todr.todr_gettime = cuda_todr_get;
			sc->sc_todr.todr_settime = cuda_todr_set;
			sc->sc_todr.cookie = sc;
			todr_attach(&sc->sc_todr);
		} 
		child = OF_peer(child);
	}

	caa.cookie = sc;
	caa.set_handler = cuda_set_handler;
	caa.send = cuda_send;
	caa.poll = cuda_poll;
#if notyet
	config_found(dev, &caa, cuda_print);
#endif
	mutex_init(&sc->sc_buslock, MUTEX_DEFAULT, IPL_NONE);
	iba.iba_tag = &sc->sc_i2c;
	sc->sc_i2c.ic_cookie = sc;
	sc->sc_i2c.ic_acquire_bus = cuda_i2c_acquire_bus;
	sc->sc_i2c.ic_release_bus = cuda_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 = cuda_i2c_exec;
	config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print);

	if (cuda0 == NULL)
		cuda0 = &caa;
}