Title: [7668] trunk: [#5146] Develop Linux driver for ADXL345/346 Three-Axis Digital
Revision
7668
Author
hennerich
Date
2009-10-16 08:31:57 -0400 (Fri, 16 Oct 2009)

Log Message

[#5146] Develop Linux driver for ADXL345/346 Three-Axis Digital
Accelerometers
Linux-Input feedback by Dmitry Torokhov:
Balance interrupts disables/enables
Prefer s8/u8 types
Avoid input syncs by reporting all TAP-Axis in row

Modified Paths

Diff

Modified: trunk/drivers/input/misc/adxl34x.c (7667 => 7668)


--- trunk/drivers/input/misc/adxl34x.c	2009-10-16 09:03:54 UTC (rev 7667)
+++ trunk/drivers/input/misc/adxl34x.c	2009-10-16 12:31:57 UTC (rev 7668)
@@ -177,6 +177,10 @@
 
 #undef ADXL_DEBUG
 
+#define ADXL_X_AXIS			0
+#define ADXL_Y_AXIS			1
+#define ADXL_Z_AXIS			2
+
 #define AC_READ(ac, reg)	((ac)->read((ac)->dev, reg))
 #define AC_WRITE(ac, reg, val)	((ac)->write((ac)->dev, reg, val))
 
@@ -228,9 +232,7 @@
 	.ev_code_y = ABS_Y,	/* EV_REL */
 	.ev_code_z = ABS_Z,	/* EV_REL */
 
-	.ev_code_tap_x = BTN_TOUCH,	/* EV_KEY */
-	.ev_code_tap_y = BTN_TOUCH,	/* EV_KEY */
-	.ev_code_tap_z = BTN_TOUCH,	/* EV_KEY */
+	.ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY {x,y,z} */
 	.power_mode = ADXL_AUTO_SLEEP | ADXL_LINK,
 	.fifo_mode = FIFO_STREAM,
 	.watermark = 0,
@@ -272,22 +274,31 @@
 
 static void adxl34x_report_key_single(struct input_dev *input, int key)
 {
-	input_report_key(input, key, 1);
+	input_report_key(input, key, true);
 	input_sync(input);
-	input_report_key(input, key, 0);
+	input_report_key(input, key, false);
 }
 
-static void adxl34x_report_key_double(struct input_dev *input, int key)
+static void adxl34x_send_key_events(struct adxl34x *ac,
+		struct adxl34x_platform_data *pdata, int status, int press)
 {
-	input_report_key(input, key, 1);
-	input_sync(input);
-	input_report_key(input, key, 0);
-	input_sync(input);
-	input_report_key(input, key, 1);
-	input_sync(input);
-	input_report_key(input, key, 0);
+	int i;
+
+	for (i = ADXL_X_AXIS; i <= ADXL_Z_AXIS; i++) {
+		if (status & (1 << (ADXL_Z_AXIS - i)))
+			input_report_key(ac->input,
+					 pdata->ev_code_tap[i], press);
+	}
 }
 
+static void adxl34x_do_tap(struct adxl34x *ac,
+		struct adxl34x_platform_data *pdata, int status)
+{
+	adxl34x_send_key_events(ac, pdata, status, true);
+	input_sync(ac->input);
+	adxl34x_send_key_events(ac, pdata, status, false);
+}
+
 static void adxl34x_work(struct work_struct *work)
 {
 	struct adxl34x *ac = container_of(work, struct adxl34x, work);
@@ -312,28 +323,11 @@
 	if (int_stat & OVERRUN)
 		dev_dbg(ac->dev, "OVERRUN\n");
 
-	if (int_stat & SINGLE_TAP) {
-		if (tap_stat & TAP_X_SRC)
-			adxl34x_report_key_single(ac->input,
-						  pdata->ev_code_tap_x);
-		if (tap_stat & TAP_Y_SRC)
-			adxl34x_report_key_single(ac->input,
-						  pdata->ev_code_tap_y);
-		if (tap_stat & TAP_Z_SRC)
-			adxl34x_report_key_single(ac->input,
-						  pdata->ev_code_tap_z);
-	}
+	if (int_stat & (SINGLE_TAP | DOUBLE_TAP)) {
+		adxl34x_do_tap(ac, pdata, tap_stat);
 
-	if (int_stat & DOUBLE_TAP) {
-		if (tap_stat & TAP_X_SRC)
-			adxl34x_report_key_double(ac->input,
-						  pdata->ev_code_tap_x);
-		if (tap_stat & TAP_Y_SRC)
-			adxl34x_report_key_double(ac->input,
-						  pdata->ev_code_tap_y);
-		if (tap_stat & TAP_Z_SRC)
-			adxl34x_report_key_double(ac->input,
-						  pdata->ev_code_tap_z);
+		if (int_stat & DOUBLE_TAP)
+			adxl34x_do_tap(ac, pdata, tap_stat);
 	}
 
 	if (pdata->ev_code_act_inactivity) {
@@ -392,7 +386,9 @@
 	mutex_lock(&ac->mutex);
 	if (!ac->disabled && ac->opened) {
 		ac->disabled = 1;
-		cancel_work_sync(&ac->work);
+		/* Balance interrupts disables/enables */
+		if (cancel_work_sync(&ac->work))
+			enable_irq(ac->irq);
 		/*
 		 * A '0' places the ADXL34x into standby mode
 		 * with minimum power consumption.
@@ -748,9 +744,9 @@
 	}
 
 	__set_bit(EV_KEY, input_dev->evbit);
-	__set_bit(pdata->ev_code_tap_x, input_dev->keybit);
-	__set_bit(pdata->ev_code_tap_y, input_dev->keybit);
-	__set_bit(pdata->ev_code_tap_z, input_dev->keybit);
+	__set_bit(pdata->ev_code_tap[ADXL_X_AXIS], input_dev->keybit);
+	__set_bit(pdata->ev_code_tap[ADXL_Y_AXIS], input_dev->keybit);
+	__set_bit(pdata->ev_code_tap[ADXL_Z_AXIS], input_dev->keybit);
 
 	if (pdata->ev_code_ff) {
 		ac->int_mask = FREE_FALL;

Modified: trunk/include/linux/input/adxl34x.h (7667 => 7668)


--- trunk/include/linux/input/adxl34x.h	2009-10-16 09:03:54 UTC (rev 7667)
+++ trunk/include/linux/input/adxl34x.h	2009-10-16 12:31:57 UTC (rev 7668)
@@ -21,9 +21,9 @@
 	 * form with a scale factor of 15.6 mg/LSB (i.e. 0x7F = +2 g)
 	 */
 
-	char x_axis_offset;
-	char y_axis_offset;
-	char z_axis_offset;
+	s8 x_axis_offset;
+	s8 y_axis_offset;
+	s8 z_axis_offset;
 
 	/*
 	 * TAP_X/Y/Z Enable: Setting TAP_X, Y, or Z Enable enables X,
@@ -39,7 +39,7 @@
 #define ADXL_TAP_Y_EN	(1 << 1)
 #define ADXL_TAP_Z_EN	(1 << 0)
 
-	unsigned char tap_axis_control;
+	u8 tap_axis_control;
 
 	/*
 	 * tap_threshold:
@@ -49,7 +49,7 @@
 	 * behavior if Tap/Double Tap is enabled.
 	 */
 
-	unsigned char tap_threshold;
+	u8 tap_threshold;
 
 	/*
 	 * tap_duration:
@@ -59,7 +59,7 @@
 	 * value will prevent Tap/Double Tap functions from working.
 	 */
 
-	unsigned char tap_duration;
+	u8 tap_duration;
 
 	/*
 	 * tap_latency:
@@ -70,7 +70,7 @@
 	 * function.
 	 */
 
-	unsigned char tap_latency;
+	u8 tap_latency;
 
 	/*
 	 * tap_window:
@@ -80,7 +80,7 @@
 	 * disable the Double Tap function.
 	 */
 
-	unsigned char tap_window;
+	u8 tap_window;
 
 	/*
 	 * act_axis_control:
@@ -116,7 +116,7 @@
 #define ADXL_INACT_Y_EN		(1 << 1)
 #define ADXL_INACT_Z_EN		(1 << 0)
 
-	unsigned char act_axis_control;
+	u8 act_axis_control;
 
 	/*
 	 * activity_threshold:
@@ -126,7 +126,7 @@
 	 * Activity interrupt is enabled.
 	 */
 
-	unsigned char activity_threshold;
+	u8 activity_threshold;
 
 	/*
 	 * inactivity_threshold:
@@ -136,7 +136,7 @@
 	 * behavior if Inactivity interrupt is enabled.
 	 */
 
-	unsigned char inactivity_threshold;
+	u8 inactivity_threshold;
 
 	/*
 	 * inactivity_time:
@@ -153,7 +153,7 @@
 	 * interrupt when the output data is below inactivity_threshold.
 	 */
 
-	unsigned char inactivity_time;
+	u8 inactivity_time;
 
 	/*
 	 * free_fall_threshold:
@@ -167,7 +167,7 @@
 	 * recommended.
 	 */
 
-	unsigned char free_fall_threshold;
+	u8 free_fall_threshold;
 
 	/*
 	 * free_fall_time:
@@ -179,7 +179,7 @@
 	 * Values between 100 to 350 ms (0x14 to 0x46) are recommended.
 	 */
 
-	unsigned char free_fall_time;
+	u8 free_fall_time;
 
 	/*
 	 * data_rate:
@@ -191,7 +191,7 @@
 	 * communication speed will result in samples being discarded.
 	 */
 
-	unsigned char data_rate;
+	u8 data_rate;
 
 	/*
 	 * data_range:
@@ -208,7 +208,7 @@
 #define ADXL_RANGE_PM_8g	2
 #define ADXL_RANGE_PM_16g	3
 
-	unsigned char data_range;
+	u8 data_range;
 
 	/*
 	 * low_power_mode:
@@ -216,7 +216,7 @@
 	 * power operation with somewhat higher noise.
 	 */
 
-	unsigned char low_power_mode;
+	u8 low_power_mode;
 
 	/*
 	 * power_mode:
@@ -238,7 +238,7 @@
 #define ADXL_LINK	(1 << 5)
 #define ADXL_AUTO_SLEEP	(1 << 4)
 
-	unsigned char power_mode;
+	u8 power_mode;
 
 	/*
 	 * fifo_mode:
@@ -254,7 +254,7 @@
 #define ADXL_FIFO_FIFO		1
 #define ADXL_FIFO_STREAM	2
 
-	unsigned char fifo_mode;
+	u8 fifo_mode;
 
 	/*
 	 * watermark:
@@ -264,22 +264,20 @@
 	 * A '0' disables the watermark feature.
 	 */
 
-	unsigned char watermark;
+	u8 watermark;
 
-	unsigned int ev_type;	/* EV_ABS or EV_REL */
+	u32 ev_type;	/* EV_ABS or EV_REL */
 
-	unsigned int ev_code_x;	/* ABS_X,Y,Z or REL_X,Y,Z */
-	unsigned int ev_code_y;	/* ABS_X,Y,Z or REL_X,Y,Z */
-	unsigned int ev_code_z;	/* ABS_X,Y,Z or REL_X,Y,Z */
+	u32 ev_code_x;	/* ABS_X,Y,Z or REL_X,Y,Z */
+	u32 ev_code_y;	/* ABS_X,Y,Z or REL_X,Y,Z */
+	u32 ev_code_z;	/* ABS_X,Y,Z or REL_X,Y,Z */
 
 	/*
 	 * A valid BTN or KEY Code; use tap_axis_control to disable
 	 * event reporting
 	 */
 
-	unsigned int ev_code_tap_x;	/* EV_KEY */
-	unsigned int ev_code_tap_y;	/* EV_KEY */
-	unsigned int ev_code_tap_z;	/* EV_KEY */
+	u32 ev_code_tap[3];	/* EV_KEY {X-Axis, Y-Axis, Z-Axis} */
 
 	/*
 	 * A valid BTN or KEY Code for Free-Fall or Activity enables
@@ -287,9 +285,9 @@
 	 * Activity reporting.
 	 */
 
-	unsigned int ev_code_ff;	/* EV_KEY */
-	unsigned int ev_code_act_inactivity;	/* EV_KEY */
+	u32 ev_code_ff;	/* EV_KEY */
+	u32 ev_code_act_inactivity;	/* EV_KEY */
 
-	unsigned char use_int2;
+	u8 use_int2;
 };
 #endif
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to