[PATCH 03/18] Add the embedded LED support

Takashi Iwai tiwai at suse.de
Fri Oct 8 10:22:27 PDT 2010


This patch adds the control of the embedded LED on the top-left corner
of new Synaptics devices.  For LED control, it requires the patch to
Linux synaptics input driver,
	https://patchwork.kernel.org/patch/92434/

When a sysfs file /sys/class/leds/psmouse::synaptics exists, the driver
assumes it supports the embeded LED control.

The LED can be controlled via new properties, "Synaptics LED" and
"Synaptics LED Status".

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 include/synaptics-properties.h |    6 ++++++
 man/synaptics.man              |    9 +++++++++
 src/eventcomm.c                |   32 +++++++++++++++++++++++++++++++-
 src/properties.c               |   15 +++++++++++++++
 src/synapticsstr.h             |    2 ++
 src/synproto.h                 |    1 +
 tools/synclient.c              |    1 +
 7 files changed, 65 insertions(+), 1 deletions(-)

diff --git a/include/synaptics-properties.h b/include/synaptics-properties.h
index 9c6a2ee..dd7e259 100644
--- a/include/synaptics-properties.h
+++ b/include/synaptics-properties.h
@@ -155,4 +155,10 @@
 /* 32 bit, 4 values, left, right, top, bottom */
 #define SYNAPTICS_PROP_AREA "Synaptics Area"
 
+/* 8 bit (BOOL, read-only), has_led */
+#define SYNAPTICS_PROP_LED "Synaptics LED"
+
+/* 8 bit (BOOL), led_status (on/off) */
+#define SYNAPTICS_PROP_LED_STATUS "Synaptics LED Status"
+
 #endif /* _SYNAPTICS_PROPERTIES_H_ */
diff --git a/man/synaptics.man b/man/synaptics.man
index 1561e19..8a9767d 100644
--- a/man/synaptics.man
+++ b/man/synaptics.man
@@ -909,6 +909,15 @@ right button, two-finger detection, three-finger detection, pressure detection,
 .BI "Synaptics Pad Resolution"
 32 bit unsigned, 2 values (read-only), vertical, horizontal in units/millimeter.
 
+.TP 7
+.BI "Synaptics LED"
+8 bit (BOOL, read-only), indicating whether the device has an embedded
+LED support or not.
+
+.TP 7
+.BI "Synaptics LED Status"
+8 bit (BOOL), the light status of the embedded LED.
+
 .SH "NOTES"
 There is an example hal policy file in
 .I ${sourcecode}/fdi/11-x11-synaptics.fdi
diff --git a/src/eventcomm.c b/src/eventcomm.c
index fc5055b..1fc41ef 100644
--- a/src/eventcomm.c
+++ b/src/eventcomm.c
@@ -51,6 +51,8 @@
 #define LONG(x)  ((x) / LONG_BITS)
 #define TEST_BIT(bit, array) (array[LONG(bit)] & (1 << OFF(bit)))
 
+#define SYNAPTICS_LED_SYS_FILE	"/sys/class/leds/psmouse::synaptics/brightness"
+
 /*****************************************************************************
  *	Function Definitions
  ****************************************************************************/
@@ -166,6 +168,32 @@ event_query_info(InputInfoPtr pInfo)
     }
 }
 
+static void
+event_query_led(LocalDevicePtr local)
+{
+    SynapticsPrivate *priv = (SynapticsPrivate *)local->private;
+
+    priv->synpara.has_led = !access(SYNAPTICS_LED_SYS_FILE, W_OK);
+}
+
+static void EventUpdateLED(LocalDevicePtr local)
+{
+    SynapticsPrivate *priv = (SynapticsPrivate *)local->private;
+
+    if (priv->synpara.has_led) {
+        char *val = priv->synpara.led_status ? "255" : "0";
+        int fd = open(SYNAPTICS_LED_SYS_FILE, O_WRONLY);
+        int err;
+
+        if (fd < 0)
+            return;
+        err = write(fd, val, strlen(val));
+        close(fd);
+        if (err < 0)
+	    xf86Msg(X_WARNING, "%s can't write LED value %s\n", local->name, val);
+    }
+}
+
 /* Query device for axis ranges */
 static void
 event_query_axis_ranges(InputInfoPtr pInfo)
@@ -434,6 +462,7 @@ EventReadDevDimensions(InputInfoPtr pInfo)
     if (event_query_is_touchpad(pInfo->fd, (need_grab) ? *need_grab : TRUE))
 	event_query_axis_ranges(pInfo);
     event_query_info(pInfo);
+    event_query_led(local);
 }
 
 static Bool
@@ -493,5 +522,6 @@ struct SynapticsProtocolOperations event_proto_operations = {
     EventQueryHardware,
     EventReadHwState,
     EventAutoDevProbe,
-    EventReadDevDimensions
+    EventReadDevDimensions,
+    EventUpdateLED,
 };
diff --git a/src/properties.c b/src/properties.c
index 5400928..57db0ec 100644
--- a/src/properties.c
+++ b/src/properties.c
@@ -82,6 +82,8 @@ Atom prop_gestures              = 0;
 Atom prop_capabilities          = 0;
 Atom prop_resolution            = 0;
 Atom prop_area                  = 0;
+Atom prop_led                   = 0;
+Atom prop_led_status            = 0;
 
 static Atom
 InitAtom(DeviceIntPtr dev, char *name, int format, int nvalues, int *values)
@@ -278,6 +280,9 @@ InitDeviceProperties(InputInfoPtr pInfo)
     values[2] = para->area_top_edge;
     values[3] = para->area_bottom_edge;
     prop_area = InitAtom(pInfo->dev, SYNAPTICS_PROP_AREA, 32, 4, values);
+
+    prop_led = InitAtom(local->dev, SYNAPTICS_PROP_LED, 8, 1, &para->has_led);
+    prop_led_status = InitAtom(local->dev, SYNAPTICS_PROP_LED_STATUS, 8, 1, &para->led_status);
 }
 
 int
@@ -649,6 +654,16 @@ SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
         para->area_right_edge  = area[1];
         para->area_top_edge    = area[2];
         para->area_bottom_edge = area[3];
+    } else if (property == prop_led_status)
+    {
+        if (prop->size != 1 || prop->format != 8 || prop->type != XA_INTEGER)
+            return BadMatch;
+
+        if (para->has_led) {
+            para->led_status = *(BOOL*)prop->data;
+            if (priv->proto_ops && priv->proto_ops->UpdateLED)
+                priv->proto_ops->UpdateLED(local);
+        }
     }
 
     return Success;
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index 2e7b9ca..88ca9de 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -160,6 +160,8 @@ typedef struct _SynapticsParameters
     unsigned int resolution_horiz;          /* horizontal resolution of touchpad in units/mm */
     unsigned int resolution_vert;           /* vertical resolution of touchpad in units/mm */
     int area_left_edge, area_right_edge, area_top_edge, area_bottom_edge; /* area coordinates absolute */
+    Bool has_led;                           /* has an embedded LED */
+    Bool led_status;                        /* Current status of LED (1=on) */
 } SynapticsParameters;
 
 
diff --git a/src/synproto.h b/src/synproto.h
index 96ddf3e..eee56e2 100644
--- a/src/synproto.h
+++ b/src/synproto.h
@@ -91,6 +91,7 @@ struct SynapticsProtocolOperations {
 			struct CommData *comm, struct SynapticsHwState *hwRet);
     Bool (*AutoDevProbe)(InputInfoPtr pInfo);
     void (*ReadDevDimensions)(InputInfoPtr pInfo);
+    void (*UpdateLED)(LocalDevicePtr local);
 };
 
 extern struct SynapticsProtocolOperations psaux_proto_operations;
diff --git a/tools/synclient.c b/tools/synclient.c
index e7be499..539eefb 100644
--- a/tools/synclient.c
+++ b/tools/synclient.c
@@ -143,6 +143,7 @@ static struct Parameter params[] = {
     {"AreaRightEdge",         PT_INT,    0, 10000, SYNAPTICS_PROP_AREA,	32,	1},
     {"AreaTopEdge",           PT_INT,    0, 10000, SYNAPTICS_PROP_AREA,	32,	2},
     {"AreaBottomEdge",        PT_INT,    0, 10000, SYNAPTICS_PROP_AREA,	32,	3},
+    {"LEDStatus",             PT_BOOL,   0, 1,     SYNAPTICS_PROP_LED_STATUS,	8,	0},
     { NULL, 0, 0, 0, 0 }
 };
 
-- 
1.7.3.1



More information about the xorg-devel mailing list