Thread (3 messages) 3 messages, 2 authors, 2013-12-31

Re: [PATCH v4] input: Add LED support to Synaptics device

From: Pali Rohár <hidden>
Date: 2013-12-31 10:16:37
Also in: lkml

On Saturday 20 April 2013 20:51:13 Pali Rohár wrote:
On Thursday 22 April 2010 08:16:42 Takashi Iwai wrote:
quoted
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)
quoted
+{
+	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);
quoted
+}
+
+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)
quoted
!= 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
*/
quoted
 	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!

-- 
Pali Rohár
pali.rohar@gmail.com

Attachments

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help