/* * hdaps_readb_one - reads a byte from a single I/O port, placing the value in * the given pointer. Returns zero on success or a negative error on failure. * Can sleep. */ static int hdaps_readb_one(unsigned int port, u8 *val) { int ret; down(&hdaps_sem); /* do a sync refresh -- we need to be sure that we read fresh data */ ret = __device_refresh_sync(); if (ret) goto out; *val = inb(port); __device_complete(); out: up(&hdaps_sem); return ret; }
static int hdaps_readb_one(unsigned int port, u8 *val) { int ret; mutex_lock(&hdaps_mtx); ret = __device_refresh_sync(); if (ret) goto out; *val = inb(port); __device_complete(); out: mutex_unlock(&hdaps_mtx); return ret; }
/* __hdaps_read_pair - internal lockless helper for hdaps_read_pair(). */ static int __hdaps_read_pair(unsigned int port1, unsigned int port2, int *x, int *y) { /* do a sync refresh -- we need to be sure that we read fresh data */ if (__device_refresh_sync()) return -EIO; *y = inw(port2); *x = inw(port1); km_activity = inb(HDAPS_PORT_KMACT); __device_complete(); /* if hdaps_invert is set, negate the two values */ if (hdaps_invert) { *x = -*x; *y = -*y; } return 0; }
static int __hdaps_read_pair(unsigned int port1, unsigned int port2, int *x, int *y) { if (__device_refresh_sync()) return -EIO; *y = inw(port2); *x = inw(port1); km_activity = inb(HDAPS_PORT_KMACT); __device_complete(); if (hdaps_invert & HDAPS_X_AXIS) *x = -*x; if (hdaps_invert & HDAPS_Y_AXIS) *y = -*y; return 0; }
/* * hdaps_device_init - initialize the accelerometer. Returns zero on success * and negative error code on failure. Can sleep. */ static int hdaps_device_init(void) { int total, ret = -ENXIO; down(&hdaps_sem); outb(0x13, 0x1610); outb(0x01, 0x161f); if (__wait_latch(0x161f, 0x00)) goto out; /* * Most ThinkPads return 0x01. * * Others--namely the R50p, T41p, and T42p--return 0x03. These laptops * have "inverted" axises. * * The 0x02 value occurs when the chip has been previously initialized. */ if (__check_latch(0x1611, 0x03) && __check_latch(0x1611, 0x02) && __check_latch(0x1611, 0x01)) goto out; printk(KERN_DEBUG "hdaps: initial latch check good (0x%02x).\n", __get_latch(0x1611)); outb(0x17, 0x1610); outb(0x81, 0x1611); outb(0x01, 0x161f); if (__wait_latch(0x161f, 0x00)) goto out; if (__wait_latch(0x1611, 0x00)) goto out; if (__wait_latch(0x1612, 0x60)) goto out; if (__wait_latch(0x1613, 0x00)) goto out; outb(0x14, 0x1610); outb(0x01, 0x1611); outb(0x01, 0x161f); if (__wait_latch(0x161f, 0x00)) goto out; outb(0x10, 0x1610); outb(0xc8, 0x1611); outb(0x00, 0x1612); outb(0x02, 0x1613); outb(0x01, 0x161f); if (__wait_latch(0x161f, 0x00)) goto out; if (__device_refresh_sync()) goto out; if (__wait_latch(0x1611, 0x00)) goto out; /* we have done our dance, now let's wait for the applause */ for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { int x, y; /* a read of the device helps push it into action */ __hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y); if (!__wait_latch(0x1611, 0x02)) { ret = 0; break; } msleep(INIT_WAIT_MSECS); } out: up(&hdaps_sem); return ret; }
static int hdaps_device_init(void) { int total, ret = -ENXIO; mutex_lock(&hdaps_mtx); outb(0x13, 0x1610); outb(0x01, 0x161f); if (__wait_latch(0x161f, 0x00)) goto out; if (__check_latch(0x1611, 0x03) && __check_latch(0x1611, 0x02) && __check_latch(0x1611, 0x01)) goto out; printk(KERN_DEBUG "hdaps: initial latch check good (0x%02x).\n", __get_latch(0x1611)); outb(0x17, 0x1610); outb(0x81, 0x1611); outb(0x01, 0x161f); if (__wait_latch(0x161f, 0x00)) goto out; if (__wait_latch(0x1611, 0x00)) goto out; if (__wait_latch(0x1612, 0x60)) goto out; if (__wait_latch(0x1613, 0x00)) goto out; outb(0x14, 0x1610); outb(0x01, 0x1611); outb(0x01, 0x161f); if (__wait_latch(0x161f, 0x00)) goto out; outb(0x10, 0x1610); outb(0xc8, 0x1611); outb(0x00, 0x1612); outb(0x02, 0x1613); outb(0x01, 0x161f); if (__wait_latch(0x161f, 0x00)) goto out; if (__device_refresh_sync()) goto out; if (__wait_latch(0x1611, 0x00)) goto out; for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) { int x, y; __hdaps_read_pair(HDAPS_PORT_XPOS, HDAPS_PORT_YPOS, &x, &y); if (!__wait_latch(0x1611, 0x02)) { ret = 0; break; } msleep(INIT_WAIT_MSECS); } out: mutex_unlock(&hdaps_mtx); return ret; }