PERFORCE change 120510 for review

Rui Paulo rpaulo at FreeBSD.org
Mon May 28 19:53:20 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=120510

Change 120510 by rpaulo at rpaulo_epsilon on 2007/05/28 19:52:46

	Setup the Sudden Motion sensor so that it sends an IRQ when
	the laptop recieves a shock.
	For example, if the laptop is moved in air agressivly, the
	following will show up on dmesg:
	asmc0: WARNING: possible shock!
	asmc0: WARNING: possible shock!
	asmc0: WARNING: high acceleration detected!
	
	Fix comments.

Affected files ...

.. //depot/projects/soc2007/rpaulo-macbook/dev/asmc/asmc.c#4 edit
.. //depot/projects/soc2007/rpaulo-macbook/dev/asmc/asmcvar.h#3 edit

Differences ...

==== //depot/projects/soc2007/rpaulo-macbook/dev/asmc/asmc.c#4 (text+ko) ====

@@ -23,7 +23,7 @@
  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $P4: //depot/projects/soc2007/rpaulo-macbook/dev/asmc/asmc.c#3 $
+ * $P4: //depot/projects/soc2007/rpaulo-macbook/dev/asmc/asmc.c#4 $
  *
  */
 
@@ -76,6 +76,7 @@
 static int	asmc_temp_getvalue(device_t, const char *);
 static int	asmc_sms_read(device_t, const char *, int16_t *);
 static void	asms_sms_calibrate(device_t);
+static int	asmc_sms_intr(void *);
 
 /*
  * Model functions.
@@ -226,6 +227,7 @@
 asmc_attach(device_t dev)
 {
 	int i, j;
+	int error;
 	char name[2];
 	struct asmc_softc *sc = device_get_softc(dev);
 	struct asmc_model *model;
@@ -354,6 +356,26 @@
 			dev, 0, model->smc_sms_z, "I",
 			"Sudden Motion Sensor Z value");
 
+	/*
+	 * Allocate an IRQ for the SMS.
+	 */
+	sc->sc_rid = 0;
+	sc->sc_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_rid,
+					ASMC_IRQ, ASMC_IRQ, 1, RF_ACTIVE);
+	if (sc->sc_res == NULL) {
+		device_printf(dev, "unable to allocate IRQ resource\n");
+		goto out;
+	}
+
+	error = bus_setup_intr(dev, sc->sc_res, 
+			       INTR_TYPE_MISC|INTR_MPSAFE|INTR_EXCL,
+			       asmc_sms_intr, NULL, dev, &sc->sc_cookie);
+	if (error) {
+		device_printf(dev, "unable to setup SMS IRQ\n");
+		bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid,
+				     sc->sc_res);
+	}
+
 out:
 	return 0;
 }
@@ -365,6 +387,11 @@
 
 	sysctl_ctx_free(&sc->sc_sysctl_ctx);
 
+	if (sc->sc_cookie)
+		bus_teardown_intr(dev, sc->sc_res, sc->sc_cookie);
+	if (sc->sc_res)
+		bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid, sc->sc_res);
+
 	return 0;
 }
 
@@ -376,9 +403,45 @@
 	uint8_t buf[4];
 
 	/*
+	 * We are ready to recieve interrupts from the SMS.
+	 */
+	buf[0] = 0x01;
+	asmc_key_write(dev, ASMC_KEY_INTOK, buf, 1);
+	DELAY(50);
+
+	/* 
+	 * Initiate the polling intervals.
+	 */
+	buf[0] = 20; /* msecs */
+	asmc_key_write(dev, ASMC_KEY_SMS_LOW_INT, buf, 1);
+	DELAY(150);
+
+	buf[0] = 20; /* msecs */
+	asmc_key_write(dev, ASMC_KEY_SMS_HIGH_INT, buf, 1);
+	DELAY(150);
+
+	buf[0] = 0x00;
+	buf[1] = 0x60;
+	asmc_key_write(dev, ASMC_KEY_SMS_LOW, buf, 2);
+	DELAY(150);
+
+	buf[0] = 0x01;
+	buf[1] = 0xc0;
+	asmc_key_write(dev, ASMC_KEY_SMS_HIGH, buf, 2);
+	DELAY(150);
+
+	/*
+	 * I'm not sure what this key does, but it seems to be
+	 * required.
+	 */
+	buf[0] = 0x01;
+	asmc_key_write(dev, ASMC_KEY_SMS_FLAG, buf, 1);
+	DELAY(50);
+
+	/*
 	 * Wait up to 5 seconds for SMS initialization.
 	 */
-	for (i = 0; i < 100; i++) {
+	for (i = 0; i < 10000; i++) {
 		if (asmc_key_read(dev, ASMC_KEY_SMS, buf, 2) == 0 && 
 		    (buf[0] != 0x00 || buf[1] != 0x00)) {
 			error = 0;
@@ -397,7 +460,7 @@
 	sc->sc_nfan = asmc_fan_count(dev);
 	if (sc->sc_nfan > ASMC_MAXFANS) {
 		device_printf(dev, "more than %d fans were detected. Please "
-			           "report this.", ASMC_MAXFANS);
+			           "report this.\n", ASMC_MAXFANS);
 		sc->sc_nfan = ASMC_MAXFANS;
 	}
 
@@ -424,7 +487,7 @@
 
 	val = val & ASMC_STATUS_MASK;
 
-	for (i = 0; i < 10000; i++) {
+	for (i = 0; i < 100; i++) {
 		if ((inb(ASMC_CMDPORT) & ASMC_STATUS_MASK) == val)
 			return 0;
 		DELAY(10);
@@ -668,6 +731,31 @@
 }
 
 static int
+asmc_sms_intr(void *arg)
+{
+	uint8_t type;
+	device_t dev = (device_t) arg;
+
+	type = inb(ASMC_INTPORT);
+
+	switch (type) {
+	case ASMC_SMS_INTFF:
+		device_printf(dev, "WARNING: possible free fall!\n");
+		break;
+	case ASMC_SMS_INTHA:
+		device_printf(dev, "WARNING: high acceleration detected!\n");
+		break;
+	case ASMC_SMS_INTSH:
+		device_printf(dev, "WARNING: possible shock!\n");
+		break;
+	default:
+		device_printf(dev, "%s unknown interrupt\n", __func__);
+	}
+
+	return 0;
+}
+
+static int
 asmc_mb_sysctl_sms_x(SYSCTL_HANDLER_ARGS)
 {
 	device_t dev = (device_t) arg1;

==== //depot/projects/soc2007/rpaulo-macbook/dev/asmc/asmcvar.h#3 (text+ko) ====

@@ -23,7 +23,7 @@
  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- * $P4: //depot/projects/soc2007/rpaulo-macbook/dev/asmc/asmcvar.h#2 $
+ * $P4: //depot/projects/soc2007/rpaulo-macbook/dev/asmc/asmcvar.h#3 $
  *
  */
 
@@ -45,6 +45,10 @@
 	struct sysctl_oid      *sc_sms_tree;
 
 	struct asmc_model	*sc_model;
+
+	int			sc_rid;
+	struct resource		*sc_res;
+	void			*sc_cookie;
 };
 
 struct asmc_model {
@@ -66,6 +70,13 @@
 	const char	*smc_tempdescs[8];
 };
 
+/*
+ * The Sudden Motion Sensor is able to generate an interrupt when
+ * there are certain critical conditions (free fall, high acceleration and
+ * shocks).
+ * The following IRQ is used.
+ */
+#define ASMC_IRQ		6
 
 /*
  * Data port.
@@ -80,6 +91,12 @@
 #define ASMC_CMDREAD		0x10
 #define ASMC_CMDWRITE		0x11
 
+/*
+ * Interrupt port.
+ */
+#define ASMC_INTPORT		0x31f
+
+
 /* Number of keys */
 #define ASMC_NKEYS		"#KEY"	/* RO; 4 bytes */ 
 
@@ -98,11 +115,19 @@
  * Sudden Motion Sensor (SMS).
  */
 #define ASMC_SMS_INIT1		0xe0
-#define ASMC_SMS_INIT2		0x00
+#define ASMC_SMS_INIT2		0xf8
 #define ASMC_KEY_SMS		"MOCN"	/* RW; 2 bytes */
 #define ASMC_KEY_SMS_X		"MO_X"	/* RO; 2 bytes */
 #define ASMC_KEY_SMS_Y		"MO_Y"	/* RO; 2 bytes */
 #define ASMC_KEY_SMS_Z		"MO_Z"	/* RO; 2 bytes */
+#define ASMC_KEY_SMS_LOW	"MOLT"	/* RW; 2 bytes */
+#define ASMC_KEY_SMS_HIGH	"MOHT"	/* RW; 2 bytes */
+#define ASMC_KEY_SMS_LOW_INT	"MOLD"	/* RW; 1 byte */
+#define ASMC_KEY_SMS_HIGH_INT	"MOHD"	/* RW; 1 byte */
+#define ASMC_KEY_SMS_FLAG	"MSDW"	/* RW; 1 byte */
+#define ASMC_SMS_INTFF		0x60	/* Free fall Interrupt */
+#define ASMC_SMS_INTHA		0x6f	/* High Acceleration Interrupt */
+#define ASMC_SMS_INTSH		0x80	/* Shock Interrupt */
 
 /*
  * Keyboard backlight.
@@ -116,10 +141,16 @@
 #define ASMC_KEY_CLAMSHELL	"MSLD"	/* RO; 1 byte */
 
 /*
+ * Interrupt keys.
+ */
+#define ASMC_KEY_INTOK		"NTOK"	/* WO; 1 byte */
+
+
+
+/*
  * Temperatures.
  *
  * First for MacBook/MacBook Pro, then for Intel Mac Mini.
- * XXX: the descriptions/names are probably wrong (rpaulo)
  * 
  */
 


More information about the p4-projects mailing list