[PATCH 03/18] Add the embedded LED support
Peter Hutterer
peter.hutterer at who-t.net
Tue Oct 12 20:29:21 PDT 2010
On Fri, Oct 08, 2010 at 07:22:27PM +0200, Takashi Iwai wrote:
> 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"
> +
this should be added to the "Synaptics Capabilities" property, there's no
need for a separate property. I guess sooner or later we'll see non-clickpad
devices come out with leds too, making this a generic capability like
two-finger tapping and similar.
> +/* 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);
the prop_led_status atom should only be initialized if the touchpad actually
has a led, please make this conditional on the has_led bit.
Cheers,
Peter
> }
>
> 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