All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Logitech USB mice/trackball extensions
@ 2003-03-26  2:29 Eric Wong
  2003-03-26  3:35 ` Eric Wong
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: Eric Wong @ 2003-03-26  2:29 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-usb-devel, linux-kernel

This patch adds support for controlling 400/800 cpi resolution and
SMS/Smart Scroll/Cruise control for certain Logitech mice.  Disabling
SMS lets you use the extra buttons on MX500/700 as regular buttons if
an application supports evdev since ExpPS/2 doesn't support all the
buttons.

For XFree86, there are some patches (not mine) to support evdev here: 
http://people.debian.org/~warp/evdev/

diff -ruN a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig
--- a/drivers/usb/input/Kconfig	2003-03-17 13:44:22.000000000 -0800
+++ b/drivers/usb/input/Kconfig	2003-03-24 20:06:26.000000000 -0800
@@ -90,6 +90,36 @@
 
 	  If unsure, say Y.
 
+config USB_HIDLOGITECH
+ 	bool "Logitech HID extensions"
+ 	default n
+ 	depends on USB_HID
+ 	help
+ 	  Say Y here will enable control of Logitech specific extensions
+ 
+	  module parameter: 'hid_logitech_sms' type: boolean
+	  
+	  Toggle simulated scrolling with the Smart Scroll / Cruise Control
+ 	  buttons (7 and 8) on the following Logitech devices: 
+ 	  - MX500 Optical Mouse
+ 	  - Receiver for Cordless Elite Duo
+ 	  - Receiver for MX700 Optical Mouse
+ 	  - Receiver for Cordless Optical TrackMan
+
+  	  default: 1 (Smart Scroll / Cruise Control enabled)
+ 
+	  module parameter: 'hid_logitech_res' type: boolean
+	  Toggle 400 / 800 cpi (characters per inch) resolution on Logitech
+ 	  devices that support it:
+ 	  - Wheel Mouse Optical
+ 	  - MouseMan Traveler
+ 	  - MouseMan Dual Optical
+ 	  - MX300 Optical Mouse
+ 	  - MX500 Optical Mouse
+ 	  - iFeel Mouse (silver)
+	  
+ 	  default: 0 (400 cpi)
+
 menu "USB HID Boot Protocol drivers"
 	depends on USB!=n && USB_HID!=y
 
diff -ruN a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile
--- a/drivers/usb/input/Makefile	2003-03-17 13:44:11.000000000 -0800
+++ b/drivers/usb/input/Makefile	2003-03-24 20:06:26.000000000 -0800
@@ -25,6 +25,9 @@
 ifeq ($(CONFIG_HID_FF),y)
 	hid-objs	+= hid-ff.o
 endif
+ifeq ($(CONFIG_USB_HIDLOGITECH),y)
+	hid-objs	+= hid-logitech.o
+endif
 
 obj-$(CONFIG_USB_AIPTEK)	+= aiptek.o
 obj-$(CONFIG_USB_HID)		+= hid.o
diff -ruN a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c	2003-03-24 19:22:13.000000000 -0800
+++ b/drivers/usb/input/hid-core.c	2003-03-25 18:05:48.000000000 -0800
@@ -1610,6 +1610,7 @@
 	hid_dump_device(hid);
 
 	hid_ff_init(hid);
+	hid_logitech_extras(hid);
 
 	if (!hidinput_connect(hid))
 		hid->claimed |= HID_CLAIMED_INPUT;
@@ -1687,3 +1688,19 @@
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE(DRIVER_LICENSE);
+
+/* Module parameters */
+MODULE_PARM(hid_poll_interval, "i");
+MODULE_PARM_DESC(hid_poll_interval, "polling interval, millseconds (default=10)");
+
+#ifndef MODULE
+static int __init hid_poll_interval_setup(char *str)
+{
+	get_option(&str,&hid_poll_interval);
+	return 1;
+}
+
+__setup("hid_poll_interval=", hid_poll_interval_setup);
+
+#endif
+
diff -ruN a/drivers/usb/input/hid-logitech.c b/drivers/usb/input/hid-logitech.c
--- a/drivers/usb/input/hid-logitech.c	1969-12-31 16:00:00.000000000 -0800
+++ b/drivers/usb/input/hid-logitech.c	2003-03-25 18:11:16.000000000 -0800
@@ -0,0 +1,156 @@
+/*
+ *  Copyright (c) 2003 Eric Wong <eric@yhbt.net>
+ *
+ *  Logitech extensions for HID devices
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/input.h>
+#include <linux/usb.h>
+#include "hid.h"
+
+/* 
+ * Logitech USB extra features 
+ */
+
+#define HID_QUIRK_LOGI_HIRES	0x01
+#define HID_QUIRK_LOGI_SMS	0x02
+
+#if 0
+#define HID_QUIRK_LOGI_CSR	0x04 /* not implemented */
+#endif
+
+/*
+ * RES - Resolution switching between 400 cpi and 800 cpi
+ *                type  req  value  index  length   
+ * Set 400 cpi    40    02   0E 00  03 00  00 00  
+ * Set 800 cpi    40    02   0E 00  04 00  00 00  
+ * Get resolution C0    01   0E 00  00 00  01 00 
+ * 	returns: 03 for 400 cpi or 04 for 800 cpi
+ *
+ * SMS - Smart Scroll / Cruise Control
+ *                type  req  value  index  length   
+ * Enable SMS     40    02   17 00  01 00  00 00  
+ * Disable SMS    40    02   17 00  00 00  00 00  
+ * Get SMS mode   C0    01   17 00  00 00  01 00 
+ * 	returns: 00 for disabled, 01 for enabled
+ */
+
+#define USB_VENDOR_ID_LOGITECH		0x046d
+
+/* mice */
+#define USB_DEVICE_ID_LOGITECH_WMOPT	0xc00e	/* Wheel Mouse Optical */
+#define USB_DEVICE_ID_LOGITECH_MMTRAV	0xc00f	/* MouseMan Traveler */
+#define USB_DEVICE_ID_LOGITECH_MMDUAL	0xc012	/* MouseMan Dual Optical */
+#define USB_DEVICE_ID_LOGITECH_MX300	0xc024	/* MX300 Optical Mouse */
+#define USB_DEVICE_ID_LOGITECH_MX500	0xc025	/* MX500 Optical Mouse */
+#define USB_DEVICE_ID_LOGITECH_IFEEL	0xc031	/* iFeel Mouse (silver) */
+
+/* receivers for cordless devices */
+#define USB_DEVICE_ID_LOGITECH_CEDUO	0xc505	/* Cordless Elite Duo */
+#define USB_DEVICE_ID_LOGITECH_MX700	0xc506	/* MX700 Optical Mouse */
+#define USB_DEVICE_ID_LOGITECH_COTRACK	0xc508	/* Cordless Optical TrackMan */
+
+/*
+ * keep this separate from the main hid-core.c blacklist to avoid bloating the
+ * code for people who don't use these Logitech products.  This isn't a
+ * blacklist, it's a whitelist :)
+ */
+
+struct hid_logitech_quirklist {
+	__u16 idVendor;
+	__u16 idProduct;
+	unsigned features;
+} hid_logitech_quirklist[] = { 
+	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WMOPT,
+		HID_QUIRK_LOGI_HIRES },
+	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MMTRAV,
+		HID_QUIRK_LOGI_HIRES },
+	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MMDUAL,
+		HID_QUIRK_LOGI_HIRES },
+	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MX300,
+		HID_QUIRK_LOGI_HIRES },
+	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_IFEEL,
+		HID_QUIRK_LOGI_HIRES },
+	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MX500,
+		HID_QUIRK_LOGI_HIRES | HID_QUIRK_LOGI_SMS },
+	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CEDUO,
+		HID_QUIRK_LOGI_SMS },
+	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MX700,
+		HID_QUIRK_LOGI_SMS },
+	{ USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_COTRACK,
+		HID_QUIRK_LOGI_SMS },
+	{ 0, 0 }
+};
+	
+/* 
+ * Logitech SMS and RES
+ * these are the logitech defaults for dpi and smart scrolling 
+ * I don't like them, but they're the defaults. Also why I made this patch
+ */
+
+#define HID_LOGITECH_RES	0
+#define HID_LOGITECH_SMS	1
+
+static int hid_logitech_res = HID_LOGITECH_RES;
+static int hid_logitech_sms = HID_LOGITECH_SMS;
+
+void hid_logitech_extras (struct hid_device *hid) 
+{
+	unsigned features = 0;
+	int n;
+	for (n = 0; hid_logitech_quirklist[n].idVendor; ++n)
+		if ((hid_logitech_quirklist[n].idVendor == hid->dev->descriptor.idVendor) &&
+			(hid_logitech_quirklist[n].idProduct == hid->dev->descriptor.idProduct))
+				features = hid_logitech_quirklist[n].features;
+
+	if ( (features & HID_QUIRK_LOGI_SMS) && !hid_logitech_sms ) 
+		/* disable sms */
+	        usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0),
+				0x02, 0x40, 0x0017, 0x0000, NULL, 0, HZ);
+	else if ( (features & HID_QUIRK_LOGI_SMS) && hid_logitech_sms ) 
+		/* enable sms */
+	        usb_control_msg(hid->dev, usb_sndctrlpipe(hid->dev, 0),
+				0x02, 0x40, 0x0017, 0x0001, NULL, 0, HZ);
+
+	if ( (features & HID_QUIRK_LOGI_HIRES) && hid_logitech_res ) 
+		/* 800 cpi resolution */
+	        usb_control_msg(hid->dev,usb_sndctrlpipe(hid->dev, 0),
+				0x02, 0x40, 0x000e, 0x0004, NULL, 0, HZ);
+	else if ( (features & HID_QUIRK_LOGI_HIRES) && !hid_logitech_res ) 
+		/* 400 cpi resolution */
+	        usb_control_msg(hid->dev,usb_sndctrlpipe(hid->dev, 0),
+				0x02, 0x40, 0x000e, 0x0003, NULL, 0, HZ);
+}
+
+MODULE_PARM(hid_logitech_res, "i");
+MODULE_PARM_DESC(hid_logitech_res, "resolution, 1 = 800cpi | 0 = 400cpi (default)");
+MODULE_PARM(hid_logitech_sms, "i");
+MODULE_PARM_DESC(hid_logitech_sms, "auto-repeat, 1 = enabled (default) | 0 = disabled");
+
+#ifndef MODULE
+static int __init hid_logitech_res_setup(char *str)
+{
+	get_option(&str,&hid_logitech_res);
+	return 1;
+}
+
+static int __init hid_logitech_sms_setup(char *str)
+{
+	get_option(&str,&hid_logitech_sms);
+	return 1;
+}
+__setup("hid_logitech_res=", hid_logitech_res_setup);
+__setup("hid_logitech_sms=", hid_logitech_sms_setup);
+#endif
+
diff -ruN a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
--- a/drivers/usb/input/hid.h	2003-03-17 13:43:37.000000000 -0800
+++ b/drivers/usb/input/hid.h	2003-03-24 20:06:26.000000000 -0800
@@ -432,6 +432,12 @@
 static inline void hidinput_disconnect(struct hid_device *hid) { }
 #endif
 
+#ifdef CONFIG_USB_HIDLOGITECH
+extern void hid_logitech_extras (struct hid_device *);
+#else
+static inline void hid_logitech_extras (struct hid_device *hid) { }
+#endif 
+
 int hid_open(struct hid_device *);
 void hid_close(struct hid_device *);
 int hid_find_field(struct hid_device *, unsigned int, unsigned int, struct hid_field **);



-- 
Eric Wong

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2003-03-27  8:12 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-03-26  2:29 [PATCH] Logitech USB mice/trackball extensions Eric Wong
2003-03-26  3:35 ` Eric Wong
     [not found] ` <20030326030330.GC12549@BL4ST>
2003-03-26  3:48   ` Greg KH
2003-03-26  4:09     ` Eric Wong
2003-03-26  5:54       ` [linux-usb-devel] " Brad Hards
2003-03-26  6:25         ` Greg KH
2003-03-26  6:27         ` Brad Hards
2003-03-26 18:41           ` Josh McKinney
2003-03-27  7:03           ` Eric Wong
2003-03-27  8:23             ` Josh McKinney
2003-03-26  4:10 ` Robert Love

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.