Ejemplo n.º 1
0
int
aps_init(bus_space_tag_t iot, bus_space_handle_t ioh)
{
	unsigned char iobuf[16];


	/* command 0x17/0x81: check EC */
	iobuf[APS_CMD] = 0x17;
	iobuf[APS_ARG1] = 0x81;

	if (aps_do_io(iot, ioh, iobuf, APS_WRITE_1, APS_READ_3))
		return (1);

	if (iobuf[APS_RET] != 0 ||iobuf[APS_ARG3] != 0)
		return (1);

	/* Test values from the Linux driver */
	if ((iobuf[APS_ARG1] != 0 || iobuf[APS_ARG2] != 0x60) &&
	    (iobuf[APS_ARG1] != 1 || iobuf[APS_ARG2] != 0))
		return (1);

	/* command 0x14: set power */
	iobuf[APS_CMD] = 0x14;
	iobuf[APS_ARG1] = 0x01;

	if (aps_do_io(iot, ioh, iobuf, APS_WRITE_1, APS_READ_0))
		return (1);

	if (iobuf[APS_RET] != 0)
		return (1);

	/* command 0x10: set config (sample rate and order) */
	iobuf[APS_CMD] = 0x10;
	iobuf[APS_ARG1] = 0xc8;
	iobuf[APS_ARG2] = 0x00;
	iobuf[APS_ARG3] = 0x02;

	if (aps_do_io(iot, ioh, iobuf, APS_WRITE_3, APS_READ_0))
		return (1);

	if (iobuf[APS_RET] != 0)
		return (1);

	/* command 0x11: refresh data */
	iobuf[APS_CMD] = 0x11;
	if (aps_do_io(iot, ioh, iobuf, APS_WRITE_0, APS_READ_1))
		return (1);
	if (iobuf[APS_ARG1] != 0)
		return (1);

	return (0);
}
Ejemplo n.º 2
0
void
aps_power(int why, void *arg)
{
	struct aps_softc *sc = (struct aps_softc *)arg;
	bus_space_tag_t iot = sc->aps_iot;
	bus_space_handle_t ioh = sc->aps_ioh;
	unsigned char iobuf[16];

	if (why != PWR_RESUME) {
		timeout_del(&aps_timeout);
		return;
	}
	/*
	 * Redo the init sequence on resume, because APS is 
	 * as forgetful as it is deaf.
	 */

	/* get APS mode */
	iobuf[APS_CMD] = 0x13;
	if (aps_do_io(iot, ioh, iobuf, APS_WRITE_0, APS_READ_1)
	    || aps_init(iot, ioh))
		printf("aps: failed to wake up\n");
	else
		timeout_add(&aps_timeout, (5 * hz) / 10);
}
Ejemplo n.º 3
0
int
aps_match(struct device *parent, void *match, void *aux)
{
	bus_space_tag_t iot;
	bus_space_handle_t ioh;
	struct isa_attach_args *ia = aux;
	int iobase;
	u_int8_t cr;

	char iobuf[16];

	iot = ia->ia_iot;
	iobase = ia->ipa_io[0].base;

	if (bus_space_map(iot, iobase, APS_ADDR_SIZE, 0, &ioh)) {
		DPRINTF(("aps: can't map i/o space\n"));
		return (0);
	}


	/* See if this machine has APS */

	/* get APS mode */
	iobuf[APS_CMD] = 0x13;
	if (aps_do_io(iot, ioh, iobuf, APS_WRITE_0, APS_READ_1)) {
		bus_space_unmap(iot, ioh, APS_ADDR_SIZE);
		return (0);
	}

	/*
	 * Observed values from Linux driver:
	 * 0x01: T42
	 * 0x02: chip already initialised
	 * 0x03: T41
	 * 0x05: T61
	 */

	cr = iobuf[APS_ARG1];

	bus_space_unmap(iot, ioh, APS_ADDR_SIZE);
	DPRINTF(("aps: state register 0x%x\n", cr));

	if (iobuf[APS_RET] != 0 || cr < 1 || cr > 5) {
		DPRINTF(("aps0: unsupported state %d\n", cr));
		return (0);
	}

	ia->ipa_nio = 1;
	ia->ipa_io[0].length = APS_ADDR_SIZE;
	ia->ipa_nmem = 0;
	ia->ipa_nirq = 0;
	ia->ipa_ndrq = 0;

	return (1);
}
Ejemplo n.º 4
0
static int
aps_probe(struct device *dev)
{
	struct resource *iores;
	int iorid = 0;
	u_int8_t cr;
	unsigned char iobuf[16];

#if defined(APSDEBUG) || defined(KLD_MODULE)
	device_printf(dev, "%s: port 0x%x\n", __func__, isa_get_port(dev));
#endif

	if (device_get_unit(dev) != 0)
		return ENXIO;

	iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &iorid, RF_ACTIVE);
	if (iores == NULL) {
		DPRINTF(("aps: can't map i/o space\n"));
		return ENXIO;
	}


	/* See if this machine has APS */

	/* get APS mode */
	iobuf[APS_CMD] = 0x13;
	if (aps_do_io(iores, iobuf, APS_WRITE_0, APS_READ_1)) {
		bus_release_resource(dev, SYS_RES_IOPORT, iorid, iores);
		return ENXIO;
	}

	/*
	 * Observed values from Linux driver:
	 * 0x01: T42
	 * 0x02: chip already initialised
	 * 0x03: T41
	 * 0x05: T61
	 */

	cr = iobuf[APS_ARG1];

	bus_release_resource(dev, SYS_RES_IOPORT, iorid, iores);
	DPRINTF(("aps: state register 0x%x\n", cr));

	if (iobuf[APS_RET] != 0 || cr < 1 || cr > 5) {
		DPRINTF(("aps: unsupported state %d\n", cr));
		return ENXIO;
	}
	device_set_desc(dev, "ThinkPad Active Protection System");
	return 0;
}
Ejemplo n.º 5
0
static int
aps_read_data(struct aps_softc *sc)
{
	unsigned char iobuf[16];

	/* command 0x11: refresh data */
	iobuf[APS_CMD] = 0x11;
	if (aps_do_io(sc->sc_iores, iobuf, APS_WRITE_0, APS_READ_ALL))
		return (1);

	sc->aps_data.state = iobuf[APS_STATE];
	sc->aps_data.x_accel = iobuf[APS_XACCEL] + 256 * iobuf[APS_XACCEL + 1];
	sc->aps_data.y_accel = iobuf[APS_YACCEL] + 256 * iobuf[APS_YACCEL + 1];
	sc->aps_data.temp1 = iobuf[APS_TEMP];
	sc->aps_data.x_var = iobuf[APS_XVAR] + 256 * iobuf[APS_XVAR + 1];
	sc->aps_data.y_var = iobuf[APS_YVAR] + 256 * iobuf[APS_YVAR + 1];
	sc->aps_data.temp2 = iobuf[APS_TEMP2];
	sc->aps_data.input = iobuf[APS_INPUT];

	return (0);
}
Ejemplo n.º 6
0
static int
aps_resume(struct device *dev)
{
	struct aps_softc *sc = device_get_softc(dev);
	unsigned char iobuf[16];

	/*
	 * Redo the init sequence on resume, because APS is
	 * as forgetful as it is deaf.
	 */

	/* get APS mode */
	iobuf[APS_CMD] = 0x13;
	if (aps_do_io(sc->sc_iores, iobuf, APS_WRITE_0, APS_READ_1)
	    || aps_init(sc->sc_iores)) {
		device_printf(sc->sc_dev, "failed to wake up\n");
		return EIO;
	}

	sensor_task_register(sc, aps_refresh, 1);
	return 0;
}