--- accelerometer.c.orig 2005-07-03 11:37:07.000000000 -0700 +++ accelerometer.c 2005-07-03 12:16:50.000000000 -0700 @@ -53,17 +53,17 @@ static inline int latch_wait(unsigned char value, unsigned short port) { - printk(KERN_DEBUG DRV_NAME ": latch_wait(0x%x, 0x%x)\n", value, port); - int status = 0; int i; - for (i = 0; i < 10; i++) { + printk(KERN_DEBUG DRV_NAME ": latch_wait(0x%x, 0x%x)\n", value, port); + + for (i = 0; i < 100; i++) { if (latch_check(value, port)) { status = 1; break; } - udelay(5); + udelay(10); } return status; @@ -78,9 +78,9 @@ static inline int refresh(int synchronous) { - printk(KERN_DEBUG DRV_NAME ": refresh(%d)\n", synchronous); - int status = 0; + + printk(KERN_DEBUG DRV_NAME ": refresh(%d)\n", synchronous); if (refresh_check()) { status = 1; @@ -103,29 +103,54 @@ inb(0x1604); } -static int read(void) -{ - printk(KERN_DEBUG DRV_NAME ": read()\n"); +struct accelerometer_data { + unsigned char state; + unsigned short x_accel; + unsigned short y_accel; + unsigned char temperature_a; + unsigned short x_variation; + unsigned short y_variation; + unsigned char temperature_b; + unsigned char unknown; + unsigned char mk_use; +} __attribute__ ((packed)); +static int read(int print) +{ + int i; int status = 0; + struct accelerometer_data d; + + printk(KERN_DEBUG DRV_NAME ": read()\n"); if (refresh(ACCELEROMETER_SYNC)) { + for (i=0; i< sizeof(struct accelerometer_data); i++) { + ((unsigned char *)(&d))[i] = inb(0x1611 + i); + } + /* FIXME: read data from 0x1611 through 0x161E */ read_done(); refresh(ACCELEROMETER_ASYNC); status = 1; } + if (print) { + //for (i=0; i< sizeof(struct accelerometer_data); i++) + // printk("data[%2d]: %02x\n", i, ((unsigned char *)(&d))[i]); + printk("x_accel: %d\n", d.x_accel); + printk("y_accel: %d\n", d.y_accel); + } return status; } static int initialize(void) { + int ret = -EIO; outb(0x13, 0x1610); outb(0x01, 0x161f); if (! latch_wait(0x0, 0x161f)) - return -EIO; + return ret; if (! latch_wait(0x3, 0x1611)) return -EIO; @@ -140,6 +165,7 @@ return -EIO; if (! latch_wait(0x0, 0x1613)) return -EIO; + printk("%s() 5\n", __func__); outb(0x14, 0x1610); outb(0x01, 0x1611); @@ -159,9 +185,57 @@ if (! latch_wait(0x0, 0x1611)) return -EIO; - /* FIXME: finish init sequence */ +/* + * I issue an outb at port 0x1610 of value 0x13, + * followed by an outb at port 0x161f of value 0x01. + * I then waits for latch 0x161f for value 0x0, + * and then wait for latch 0x1611 for value 0x3. + * + * Three more outbs at ports 0x1610, 0x1611, and 0x161f of values 0x17, 0x81, and 0x01, respectively follow. + * + * Four more waits for latches 0x161f, 0x1611, 0x1612, and 0x1613 for values 0x0, 0x0, 0x60, and 0x0 respectively. + * Then three more outbs at ports 0x1610, 0x1611, and 0x161f of values 0x14, 0x01, and 0x01. + * + * Then I wait for latch 0x161f for value 0x0. + * Then five outbs at ports 0x1610, 0x1611, 0x1612, 0x1613, and 0x161f of values 0x10, 0xc8, 0x00, 0x02, and 0x01 + * + * I then wait for latch 0x161f for value 0x0 again. + * + * I then issues a synchronous refresh of the accelerometer data, and wait for latch 0x1611 to become 0x0. + */ + + /*---------------------------------------------- + * The next part is a little bit tricky because it can take a long time for the accelerometer to complete. + * I loop forever until latch 0x1611 becomes 0x02. + * Inside this loop, I check the timeout value against the "time waited so far" variable. + * If the function has taken too long, + * return failure. + * else, I call the function which reads the accelerometer data + * and I throw away the (probably garbage) data + * (this read somehow seems to kick the accelerometer into being initialized). + * I set_current_state to TASK_INTERRUPTIBLE, and schedule_timeout for HZ. + * I then increment our "seconds waited so far" variable and continue the loop. + * If the loop ever exits successfully, the function returns success. + * A good value to pass for the initialize timeout value is 10 seconds. + * + */ + /* I loop forever until latch 0x1611 becomes 0x02. */ { + unsigned long msecs_to_sleep = 10000; + unsigned long msecs_per_sleep = 100; + unsigned long msecs_slept = 0; + while (msecs_slept <= msecs_to_sleep) { + if (latch_check(0x2, 0x1611)) { + printk("good latch check\n"); + ret = 0; + break; + } + + read(0); + msleep_interruptible(msecs_per_sleep); + msecs_slept += msecs_per_sleep; + }} - return 0; + return ret; } static int __init accelerometer_init(void) @@ -180,6 +254,17 @@ } ret = initialize(); + printk("initialize() ret: %d\n", ret); + if (ret) + return ret; + read(1); + { + int i; + for (i=0; i<10;i++) { + msleep_interruptible(1000); + read(1); + } + } if (ret != 0) { printk(KERN_ERR DRV_NAME ": initialization failed\n");