Date: Mon, 14 Sep 2009 11:46:43 +0000 (UTC) From: Rui Paulo <rpaulo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r197190 - head/sys/dev/asmc Message-ID: <200909141146.n8EBkhIb050942@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rpaulo Date: Mon Sep 14 11:46:43 2009 New Revision: 197190 URL: http://svn.freebsd.org/changeset/base/197190 Log: Make the sudden motion sensor work on older models and add a bit of debugging. Submitted by: Christoph Langguth <christoph at rosenkeller.org> MFC after: 1 week Modified: head/sys/dev/asmc/asmc.c head/sys/dev/asmc/asmcvar.h Modified: head/sys/dev/asmc/asmc.c ============================================================================== --- head/sys/dev/asmc/asmc.c Mon Sep 14 11:20:45 2009 (r197189) +++ head/sys/dev/asmc/asmc.c Mon Sep 14 11:46:43 2009 (r197190) @@ -86,6 +86,10 @@ static void asmc_sms_handler(void *arg) #endif static void asmc_sms_printintr(device_t dev, uint8_t); static void asmc_sms_task(void *arg, int pending); +#ifdef DEBUG +void asmc_dumpall(device_t); +static int asmc_key_dump(device_t, int); +#endif /* * Model functions. @@ -532,6 +536,17 @@ asmc_detach(device_t dev) return (0); } +#ifdef DEBUG +void asmc_dumpall(device_t dev) +{ + int i; + + /* XXX magic number */ + for (i=0; i < 0x100; i++) + asmc_key_dump(dev, i); +} +#endif + static int asmc_init(device_t dev) { @@ -584,13 +599,17 @@ asmc_init(device_t dev) asmc_key_write(dev, ASMC_KEY_SMS_FLAG, buf, 1); DELAY(100); + sc->sc_sms_intr_works = 0; + /* - * Wait up to 5 seconds for SMS initialization. + * Retry SMS initialization 1000 times + * (takes approx. 2 seconds in worst case) */ - for (i = 0; i < 10000; i++) { + for (i = 0; i < 1000; i++) { if (asmc_key_read(dev, ASMC_KEY_SMS, buf, 2) == 0 && - (buf[0] != 0x00 || buf[1] != 0x00)) { + (buf[0] == ASMC_SMS_INIT1 && buf[1] == ASMC_SMS_INIT2)) { error = 0; + sc->sc_sms_intr_works = 1; goto out; } buf[0] = ASMC_SMS_INIT1; @@ -620,6 +639,10 @@ nosms: device_printf(dev, "number of keys: %d\n", buf[3]); } +#ifdef DEBUG + asmc_dumpall(dev); +#endif + return (error); } @@ -729,6 +752,99 @@ out: return (error); } +#ifdef DEBUG +static int +asmc_key_dump(device_t dev, int number) +{ + struct asmc_softc *sc = device_get_softc(dev); + char key[5] = { 0 }; + char type[7] = { 0 }; + uint8_t index[4]; + uint8_t v[32]; + uint8_t maxlen; + int i, error = 1, try = 0; + + mtx_lock_spin(&sc->sc_mtx); + + index[0] = (number >> 24) & 0xff; + index[1] = (number >> 16) & 0xff; + index[2] = (number >> 8) & 0xff; + index[3] = (number) & 0xff; + +begin: + if (asmc_command(dev, 0x12)) + goto out; + + for (i = 0; i < 4; i++) { + ASMC_DATAPORT_WRITE(sc, index[i]); + if (asmc_wait(dev, 0x04)) + goto out; + } + + ASMC_DATAPORT_WRITE(sc, 4); + + for (i = 0; i < 4; i++) { + if (asmc_wait(dev, 0x05)) + goto out; + key[i] = ASMC_DATAPORT_READ(sc); + } + + /* get type */ + if (asmc_command(dev, 0x13)) + goto out; + + for (i = 0; i < 4; i++) { + ASMC_DATAPORT_WRITE(sc, key[i]); + if (asmc_wait(dev, 0x04)) + goto out; + } + + ASMC_DATAPORT_WRITE(sc, 6); + + for (i = 0; i < 6; i++) { + if (asmc_wait(dev, 0x05)) + goto out; + type[i] = ASMC_DATAPORT_READ(sc); + } + + error = 0; +out: + if (error) { + if (++try < 10) goto begin; + device_printf(dev,"%s for key %s failed %d times, giving up\n", + __func__, key, try); + mtx_unlock_spin(&sc->sc_mtx); + } + else { + char buf[1024]; + char buf2[8]; + mtx_unlock_spin(&sc->sc_mtx); + maxlen = type[0]; + type[0] = ' '; + type[5] = 0; + if (maxlen > sizeof(v)) { + device_printf(dev, "WARNING: cropping maxlen " + "from %d to %lud\n", maxlen, sizeof(v)); + maxlen = sizeof(v); + } + for (i = 0; i < sizeof(v); i++) { + v[i] = 0; + } + asmc_key_read(dev, key, v, maxlen); + snprintf(buf, sizeof(buf), "key %d is: %s, type %s " + "(len %d), data", number, key, type, maxlen); + for (i = 0; i < maxlen; i++) { + snprintf(buf2, sizeof(buf), " %02x", v[i]); + strlcat(buf, buf2, sizeof(buf)); + } + strlcat(buf, " \n", sizeof(buf)); + device_printf(dev, buf); + } + + return (error); +} +#endif + static int asmc_key_write(device_t dev, const char *key, uint8_t *buf, uint8_t len) { @@ -945,6 +1061,8 @@ asmc_sms_intrfast(void *arg) uint8_t type; device_t dev = (device_t) arg; struct asmc_softc *sc = device_get_softc(dev); + if (!sc->sc_sms_intr_works) + return (FILTER_HANDLED); mtx_lock_spin(&sc->sc_mtx); type = ASMC_INTPORT_READ(sc); Modified: head/sys/dev/asmc/asmcvar.h ============================================================================== --- head/sys/dev/asmc/asmcvar.h Mon Sep 14 11:20:45 2009 (r197189) +++ head/sys/dev/asmc/asmcvar.h Mon Sep 14 11:46:43 2009 (r197190) @@ -49,6 +49,7 @@ struct asmc_softc { int sc_sms_intrtype; struct taskqueue *sc_sms_tq; struct task sc_sms_task; + uint8_t sc_sms_intr_works; }; /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200909141146.n8EBkhIb050942>