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