[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, ¶->has_led);
+ prop_led_status = InitAtom(local->dev, SYNAPTICS_PROP_LED_STATUS, 8, 1, ¶->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