Message ID | s5hy6ggxb91.wl%tiwai@suse.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thursday 22 April 2010 08:16:42 Takashi Iwai wrote: > diff --git a/drivers/input/mouse/Kconfig > b/drivers/input/mouse/Kconfig index c714ca2..91d3517 100644 > --- a/drivers/input/mouse/Kconfig > +++ b/drivers/input/mouse/Kconfig > @@ -19,6 +19,7 @@ config MOUSE_PS2 > select SERIO_LIBPS2 > select SERIO_I8042 if X86 > select SERIO_GSCPS2 if GSC > + select LEDS_CLASS if MOUSE_PS2_SYNAPICS_LED > help > Say Y here if you have a PS/2 mouse connected to your > system. This includes the standard 2 or 3-button PS/2 mouse, > as well as PS/2 @@ -67,6 +68,14 @@ config MOUSE_PS2_SYNAPTICS > > If unsure, say Y. > > +config MOUSE_PS2_SYNAPTICS_LED > + bool "Support embedded LED on Synaptics devices" > + depends on MOUSE_PS2_SYNAPTICS > + select NEW_LEDS > + help > + Say Y here if you have a Synaptics device with an embedded > LED. + This will enable LED class driver to control the LED > device. + > config MOUSE_PS2_LIFEBOOK > bool "Fujitsu Lifebook PS/2 mouse protocol extension" if > EMBEDDED default y > diff --git a/drivers/input/mouse/synaptics.c > b/drivers/input/mouse/synaptics.c index c7b5285..8dc1fb5 > 100644 > --- a/drivers/input/mouse/synaptics.c > +++ b/drivers/input/mouse/synaptics.c > @@ -28,6 +28,7 @@ > #include <linux/input.h> > #include <linux/serio.h> > #include <linux/libps2.h> > +#include <linux/leds.h> > #include <linux/slab.h> > #include "psmouse.h" > #include "synaptics.h" > @@ -335,6 +336,110 @@ static void synaptics_pt_create(struct > psmouse *psmouse) serio_register_port(serio); > } > > +#ifdef CONFIG_MOUSE_PS2_SYNAPTICS_LED > +/* > + * LED handling: > + * Some Synaptics devices have an embeded LED at the top-left > corner. + */ > + > +struct synaptics_led { > + struct psmouse *psmouse; > + struct work_struct work; > + struct led_classdev cdev; > +}; > + > +static void synaptics_set_led(struct psmouse *psmouse, int > on) +{ > + int i; > + unsigned char cmd = on ? 0x88 : 0x10; > + > + ps2_begin_command(&psmouse->ps2dev); > + if (__ps2_command(&psmouse->ps2dev, NULL, > PSMOUSE_CMD_SETSCALE11)) + goto out; > + for (i = 6; i >= 0; i -= 2) { > + unsigned char d = (cmd >> i) & 3; > + if (__ps2_command(&psmouse->ps2dev, &d, > PSMOUSE_CMD_SETRES)) + goto out; > + } > + cmd = 0x0a; > + __ps2_command(&psmouse->ps2dev, &cmd, PSMOUSE_CMD_SETRATE); > + out: > + ps2_end_command(&psmouse->ps2dev); > +} > + > +static void synaptics_led_work(struct work_struct *work) > +{ > + struct synaptics_led *led; > + > + led = container_of(work, struct synaptics_led, work); > + synaptics_set_led(led->psmouse, led->cdev.brightness); > +} > + > +static void synaptics_led_cdev_brightness_set(struct > led_classdev *cdev, + enum led_brightness value) > +{ > + struct synaptics_led *led; > + > + led = container_of(cdev, struct synaptics_led, cdev); > + schedule_work(&led->work); > +} > + > +static void synaptics_sync_led(struct psmouse *psmouse) > +{ > + struct synaptics_data *priv = psmouse->private; > + > + if (priv->led) > + synaptics_set_led(psmouse, priv->led->cdev.brightness); > +} > + > +static int synaptics_init_led(struct psmouse *psmouse) > +{ > + struct synaptics_data *priv = psmouse->private; > + struct synaptics_led *led; > + int err; > + > + /* FIXME: LED is supposedly detectable in cap0c[1] 0x20, but > it seems + * not working on real machines. > + * So we check the product id to be sure. > + */ > + if (!priv->ext_cap_0c || SYN_CAP_PRODUCT_ID(priv->ext_cap) > != 0xe4) + return 0; > + > + printk(KERN_INFO "synaptics: support LED control\n"); > + led = kzalloc(sizeof(struct synaptics_led), GFP_KERNEL); > + if (!led) > + return -ENOMEM; > + led->psmouse = psmouse; > + INIT_WORK(&led->work, synaptics_led_work); > + led->cdev.name = "psmouse::synaptics"; > + led->cdev.brightness_set = > synaptics_led_cdev_brightness_set; + led->cdev.flags = > LED_CORE_SUSPENDRESUME; > + err = led_classdev_register(NULL, &led->cdev); > + if (err < 0) { > + kfree(led); > + return err; > + } > + priv->led = led; > + return 0; > +} > + > +static void synaptics_free_led(struct psmouse *psmouse) > +{ > + struct synaptics_data *priv = psmouse->private; > + > + if (!priv->led) > + return; > + cancel_work_sync(&priv->led->work); > + synaptics_set_led(psmouse, 0); > + led_classdev_unregister(&priv->led->cdev); > + kfree(priv->led); > +} > +#else > +#define synaptics_init_led(ps) 0 > +#define synaptics_free_led(ps) do {} while (0) > +#define synaptics_sync_led(ps) do {} while (0) > +#endif > + > /************************************************************ > ***************** * Functions to interpret the absolute mode > packets > > ************************************************************* > ***************/ @@ -622,6 +727,7 @@ static void > set_input_params(struct input_dev *dev, struct synaptics_data > *priv) > > static void synaptics_disconnect(struct psmouse *psmouse) > { > + synaptics_free_led(psmouse); > synaptics_reset(psmouse); > kfree(psmouse->private); > psmouse->private = NULL; > @@ -653,6 +759,8 @@ static int synaptics_reconnect(struct > psmouse *psmouse) return -1; > } > > + synaptics_sync_led(psmouse); > + > return 0; > } > > @@ -727,6 +835,9 @@ int synaptics_init(struct psmouse > *psmouse) SYN_ID_MAJOR(priv->identity), > SYN_ID_MINOR(priv->identity), priv->model_id, > priv->capabilities, priv->ext_cap, priv->ext_cap_0c); > > + if (synaptics_init_led(psmouse) < 0) > + goto init_fail; > + > set_input_params(psmouse->dev, priv); > > /* > diff --git a/drivers/input/mouse/synaptics.h > b/drivers/input/mouse/synaptics.h index ae37c5d..d5bb8f4 > 100644 > --- a/drivers/input/mouse/synaptics.h > +++ b/drivers/input/mouse/synaptics.h > @@ -94,6 +94,8 @@ struct synaptics_hw_state { > signed char scroll; > }; > > +struct synaptics_led; > + > struct synaptics_data { > /* Data read from the touchpad */ > unsigned long int model_id; /* Model-ID */ > @@ -107,6 +109,7 @@ struct synaptics_data { > unsigned char pkt_type; /* packet type - old, new, etc */ > unsigned char mode; /* current mode byte */ > int scroll; > + struct synaptics_led *led; > }; > > void synaptics_module_init(void); Hello, what happened with this patch? There is no discussion about v4: https://patchwork.kernel.org/patch/94026/ https://lkml.org/lkml/2010/4/22/35 Are there any problems with this patch?
On Saturday 20 April 2013 20:51:13 Pali Rohár wrote: > On Thursday 22 April 2010 08:16:42 Takashi Iwai wrote: > > diff --git a/drivers/input/mouse/Kconfig > > b/drivers/input/mouse/Kconfig index c714ca2..91d3517 100644 > > --- a/drivers/input/mouse/Kconfig > > +++ b/drivers/input/mouse/Kconfig > > @@ -19,6 +19,7 @@ config MOUSE_PS2 > > > > select SERIO_LIBPS2 > > select SERIO_I8042 if X86 > > select SERIO_GSCPS2 if GSC > > > > + select LEDS_CLASS if MOUSE_PS2_SYNAPICS_LED > > > > help > > > > Say Y here if you have a PS/2 mouse connected to your > > > > system. This includes the standard 2 or 3-button PS/2 mouse, > > as well as PS/2 @@ -67,6 +68,14 @@ config > > MOUSE_PS2_SYNAPTICS > > > > If unsure, say Y. > > > > +config MOUSE_PS2_SYNAPTICS_LED > > + bool "Support embedded LED on Synaptics devices" > > + depends on MOUSE_PS2_SYNAPTICS > > + select NEW_LEDS > > + help > > + Say Y here if you have a Synaptics device with an > > embedded LED. + This will enable LED class driver to > > control the LED device. + > > > > config MOUSE_PS2_LIFEBOOK > > > > bool "Fujitsu Lifebook PS/2 mouse protocol extension" if > > > > EMBEDDED default y > > diff --git a/drivers/input/mouse/synaptics.c > > b/drivers/input/mouse/synaptics.c index c7b5285..8dc1fb5 > > 100644 > > --- a/drivers/input/mouse/synaptics.c > > +++ b/drivers/input/mouse/synaptics.c > > @@ -28,6 +28,7 @@ > > > > #include <linux/input.h> > > #include <linux/serio.h> > > #include <linux/libps2.h> > > > > +#include <linux/leds.h> > > > > #include <linux/slab.h> > > #include "psmouse.h" > > #include "synaptics.h" > > > > @@ -335,6 +336,110 @@ static void synaptics_pt_create(struct > > psmouse *psmouse) serio_register_port(serio); > > > > } > > > > +#ifdef CONFIG_MOUSE_PS2_SYNAPTICS_LED > > +/* > > + * LED handling: > > + * Some Synaptics devices have an embeded LED at the > > top-left corner. + */ > > + > > +struct synaptics_led { > > + struct psmouse *psmouse; > > + struct work_struct work; > > + struct led_classdev cdev; > > +}; > > + > > +static void synaptics_set_led(struct psmouse *psmouse, int > > on) +{ > > + int i; > > + unsigned char cmd = on ? 0x88 : 0x10; > > + > > + ps2_begin_command(&psmouse->ps2dev); > > + if (__ps2_command(&psmouse->ps2dev, NULL, > > PSMOUSE_CMD_SETSCALE11)) + goto out; > > + for (i = 6; i >= 0; i -= 2) { > > + unsigned char d = (cmd >> i) & 3; > > + if (__ps2_command(&psmouse->ps2dev, &d, > > PSMOUSE_CMD_SETRES)) + goto out; > > + } > > + cmd = 0x0a; > > + __ps2_command(&psmouse->ps2dev, &cmd, > > PSMOUSE_CMD_SETRATE); + out: > > + ps2_end_command(&psmouse->ps2dev); > > +} > > + > > +static void synaptics_led_work(struct work_struct *work) > > +{ > > + struct synaptics_led *led; > > + > > + led = container_of(work, struct synaptics_led, work); > > + synaptics_set_led(led->psmouse, led->cdev.brightness); > > +} > > + > > +static void synaptics_led_cdev_brightness_set(struct > > led_classdev *cdev, + enum led_brightness > > value) > > > +{ > > + struct synaptics_led *led; > > + > > + led = container_of(cdev, struct synaptics_led, cdev); > > + schedule_work(&led->work); > > +} > > + > > +static void synaptics_sync_led(struct psmouse *psmouse) > > +{ > > + struct synaptics_data *priv = psmouse->private; > > + > > + if (priv->led) > > + synaptics_set_led(psmouse, priv->led- >cdev.brightness); > > +} > > + > > +static int synaptics_init_led(struct psmouse *psmouse) > > +{ > > + struct synaptics_data *priv = psmouse->private; > > + struct synaptics_led *led; > > + int err; > > + > > + /* FIXME: LED is supposedly detectable in cap0c[1] 0x20, > > but it seems + * not working on real machines. > > + * So we check the product id to be sure. > > + */ > > + if (!priv->ext_cap_0c || SYN_CAP_PRODUCT_ID(priv- >ext_cap) > > != 0xe4) + return 0; > > + > > + printk(KERN_INFO "synaptics: support LED control\n"); > > + led = kzalloc(sizeof(struct synaptics_led), GFP_KERNEL); > > + if (!led) > > + return -ENOMEM; > > + led->psmouse = psmouse; > > + INIT_WORK(&led->work, synaptics_led_work); > > + led->cdev.name = "psmouse::synaptics"; > > + led->cdev.brightness_set = > > synaptics_led_cdev_brightness_set; + led->cdev.flags = > > LED_CORE_SUSPENDRESUME; > > + err = led_classdev_register(NULL, &led->cdev); > > + if (err < 0) { > > + kfree(led); > > + return err; > > + } > > + priv->led = led; > > + return 0; > > +} > > + > > +static void synaptics_free_led(struct psmouse *psmouse) > > +{ > > + struct synaptics_data *priv = psmouse->private; > > + > > + if (!priv->led) > > + return; > > + cancel_work_sync(&priv->led->work); > > + synaptics_set_led(psmouse, 0); > > + led_classdev_unregister(&priv->led->cdev); > > + kfree(priv->led); > > +} > > +#else > > +#define synaptics_init_led(ps) 0 > > +#define synaptics_free_led(ps) do {} while (0) > > +#define synaptics_sync_led(ps) do {} while (0) > > +#endif > > + > > > > /********************************************************** > > ** > > > > ***************** * Functions to interpret the absolute mode > > packets > > > > ************************************************************ > > * ***************/ @@ -622,6 +727,7 @@ static void > > set_input_params(struct input_dev *dev, struct > > synaptics_data *priv) > > > > static void synaptics_disconnect(struct psmouse *psmouse) > > { > > > > + synaptics_free_led(psmouse); > > > > synaptics_reset(psmouse); > > kfree(psmouse->private); > > psmouse->private = NULL; > > > > @@ -653,6 +759,8 @@ static int synaptics_reconnect(struct > > psmouse *psmouse) return -1; > > > > } > > > > + synaptics_sync_led(psmouse); > > + > > > > return 0; > > > > } > > > > @@ -727,6 +835,9 @@ int synaptics_init(struct psmouse > > *psmouse) SYN_ID_MAJOR(priv->identity), > > SYN_ID_MINOR(priv->identity), priv->model_id, > > priv->capabilities, priv->ext_cap, priv->ext_cap_0c); > > > > + if (synaptics_init_led(psmouse) < 0) > > + goto init_fail; > > + > > > > set_input_params(psmouse->dev, priv); > > > > /* > > > > diff --git a/drivers/input/mouse/synaptics.h > > b/drivers/input/mouse/synaptics.h index ae37c5d..d5bb8f4 > > 100644 > > --- a/drivers/input/mouse/synaptics.h > > +++ b/drivers/input/mouse/synaptics.h > > @@ -94,6 +94,8 @@ struct synaptics_hw_state { > > > > signed char scroll; > > > > }; > > > > +struct synaptics_led; > > + > > > > struct synaptics_data { > > > > /* Data read from the touchpad */ > > unsigned long int model_id; /* Model-ID */ > > > > @@ -107,6 +109,7 @@ struct synaptics_data { > > > > unsigned char pkt_type; /* packet type - old, new, etc > > */ > > > unsigned char mode; /* current mode byte */ > > int scroll; > > > > + struct synaptics_led *led; > > > > }; > > > > void synaptics_module_init(void); > > Hello, > > what happened with this patch? There is no discussion about > v4: https://patchwork.kernel.org/patch/94026/ > https://lkml.org/lkml/2010/4/22/35 > > Are there any problems with this patch? BUMP!
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index c714ca2..91d3517 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -19,6 +19,7 @@ config MOUSE_PS2 select SERIO_LIBPS2 select SERIO_I8042 if X86 select SERIO_GSCPS2 if GSC + select LEDS_CLASS if MOUSE_PS2_SYNAPICS_LED help Say Y here if you have a PS/2 mouse connected to your system. This includes the standard 2 or 3-button PS/2 mouse, as well as PS/2 @@ -67,6 +68,14 @@ config MOUSE_PS2_SYNAPTICS If unsure, say Y. +config MOUSE_PS2_SYNAPTICS_LED + bool "Support embedded LED on Synaptics devices" + depends on MOUSE_PS2_SYNAPTICS + select NEW_LEDS + help + Say Y here if you have a Synaptics device with an embedded LED. + This will enable LED class driver to control the LED device. + config MOUSE_PS2_LIFEBOOK bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED default y diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index c7b5285..8dc1fb5 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -28,6 +28,7 @@ #include <linux/input.h> #include <linux/serio.h> #include <linux/libps2.h> +#include <linux/leds.h> #include <linux/slab.h> #include "psmouse.h" #include "synaptics.h" @@ -335,6 +336,110 @@ static void synaptics_pt_create(struct psmouse *psmouse) serio_register_port(serio); } +#ifdef CONFIG_MOUSE_PS2_SYNAPTICS_LED +/* + * LED handling: + * Some Synaptics devices have an embeded LED at the top-left corner. + */ + +struct synaptics_led { + struct psmouse *psmouse; + struct work_struct work; + struct led_classdev cdev; +}; + +static void synaptics_set_led(struct psmouse *psmouse, int on) +{ + int i; + unsigned char cmd = on ? 0x88 : 0x10; + + ps2_begin_command(&psmouse->ps2dev); + if (__ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSCALE11)) + goto out; + for (i = 6; i >= 0; i -= 2) { + unsigned char d = (cmd >> i) & 3; + if (__ps2_command(&psmouse->ps2dev, &d, PSMOUSE_CMD_SETRES)) + goto out; + } + cmd = 0x0a; + __ps2_command(&psmouse->ps2dev, &cmd, PSMOUSE_CMD_SETRATE); + out: + ps2_end_command(&psmouse->ps2dev); +} + +static void synaptics_led_work(struct work_struct *work) +{ + struct synaptics_led *led; + + led = container_of(work, struct synaptics_led, work); + synaptics_set_led(led->psmouse, led->cdev.brightness); +} + +static void synaptics_led_cdev_brightness_set(struct led_classdev *cdev, + enum led_brightness value) +{ + struct synaptics_led *led; + + led = container_of(cdev, struct synaptics_led, cdev); + schedule_work(&led->work); +} + +static void synaptics_sync_led(struct psmouse *psmouse) +{ + struct synaptics_data *priv = psmouse->private; + + if (priv->led) + synaptics_set_led(psmouse, priv->led->cdev.brightness); +} + +static int synaptics_init_led(struct psmouse *psmouse) +{ + struct synaptics_data *priv = psmouse->private; + struct synaptics_led *led; + int err; + + /* FIXME: LED is supposedly detectable in cap0c[1] 0x20, but it seems + * not working on real machines. + * So we check the product id to be sure. + */ + if (!priv->ext_cap_0c || SYN_CAP_PRODUCT_ID(priv->ext_cap) != 0xe4) + return 0; + + printk(KERN_INFO "synaptics: support LED control\n"); + led = kzalloc(sizeof(struct synaptics_led), GFP_KERNEL); + if (!led) + return -ENOMEM; + led->psmouse = psmouse; + INIT_WORK(&led->work, synaptics_led_work); + led->cdev.name = "psmouse::synaptics"; + led->cdev.brightness_set = synaptics_led_cdev_brightness_set; + led->cdev.flags = LED_CORE_SUSPENDRESUME; + err = led_classdev_register(NULL, &led->cdev); + if (err < 0) { + kfree(led); + return err; + } + priv->led = led; + return 0; +} + +static void synaptics_free_led(struct psmouse *psmouse) +{ + struct synaptics_data *priv = psmouse->private; + + if (!priv->led) + return; + cancel_work_sync(&priv->led->work); + synaptics_set_led(psmouse, 0); + led_classdev_unregister(&priv->led->cdev); + kfree(priv->led); +} +#else +#define synaptics_init_led(ps) 0 +#define synaptics_free_led(ps) do {} while (0) +#define synaptics_sync_led(ps) do {} while (0) +#endif + /***************************************************************************** * Functions to interpret the absolute mode packets ****************************************************************************/ @@ -622,6 +727,7 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) static void synaptics_disconnect(struct psmouse *psmouse) { + synaptics_free_led(psmouse); synaptics_reset(psmouse); kfree(psmouse->private); psmouse->private = NULL; @@ -653,6 +759,8 @@ static int synaptics_reconnect(struct psmouse *psmouse) return -1; } + synaptics_sync_led(psmouse); + return 0; } @@ -727,6 +835,9 @@ int synaptics_init(struct psmouse *psmouse) SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), priv->model_id, priv->capabilities, priv->ext_cap, priv->ext_cap_0c); + if (synaptics_init_led(psmouse) < 0) + goto init_fail; + set_input_params(psmouse->dev, priv); /* diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index ae37c5d..d5bb8f4 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h @@ -94,6 +94,8 @@ struct synaptics_hw_state { signed char scroll; }; +struct synaptics_led; + struct synaptics_data { /* Data read from the touchpad */ unsigned long int model_id; /* Model-ID */ @@ -107,6 +109,7 @@ struct synaptics_data { unsigned char pkt_type; /* packet type - old, new, etc */ unsigned char mode; /* current mode byte */ int scroll; + struct synaptics_led *led; }; void synaptics_module_init(void);