linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC ebeam PATCH 0/3] new USB eBeam input driver
@ 2012-07-28  0:02 Yann Cantin
  2012-07-28  0:02 ` [RFC ebeam PATCH 1/3] hid: hid-ids.h: Add vendor and device ID for eBeam classic device Yann Cantin
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Yann Cantin @ 2012-07-28  0:02 UTC (permalink / raw)
  To: linux-input, linux-usb; +Cc: gregkh, dmitry.torokhov, linux-kernel

Hi,

This patchset is a test-drive for a new USB input driver for eBeam
devices.
Currently, only the Luidia eBeam classic projection model is supported
(usb id known).

Patch 1 and 2 are here to let the ebeam driver be choose to handle
the device instead of the generic-usb hid one (totally useless).

Patch 3 is the actual driver.
Some things to consider :
- I'm not familiar with kernel coding (i've based my work on
  usbtouchscreen.c) so the code certainly contain flaws.
- There's 2 64/64-bits divisions needed, don't know how to handle that the
  right way to be efficient and portable.
- There's 14 custom sysfs files. Yes.

Beside this, the driver run fine with 3.3.6 and 3.5.0 kernels on x86_64.

Thanks for your help.

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

* [RFC ebeam PATCH 1/3] hid: hid-ids.h: Add vendor and device ID for eBeam classic device.
  2012-07-28  0:02 [RFC ebeam PATCH 0/3] new USB eBeam input driver Yann Cantin
@ 2012-07-28  0:02 ` Yann Cantin
  2012-07-28  0:02 ` [RFC ebeam PATCH 2/3] hid: hid-core.c: Blackist " Yann Cantin
  2012-07-28  0:02 ` [RFC ebeam PATCH 3/3] input: misc: New USB eBeam input driver Yann Cantin
  2 siblings, 0 replies; 8+ messages in thread
From: Yann Cantin @ 2012-07-28  0:02 UTC (permalink / raw)
  To: linux-input, linux-usb; +Cc: gregkh, dmitry.torokhov, linux-kernel, Yann Cantin


Signed-off-by: Yann Cantin <yann.cantin@laposte.net>
---
 drivers/hid/hid-ids.h |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 41c34f2..8cd4b8e 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -271,6 +271,9 @@
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_7349	0x7349
 #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001	0xa001
 
+#define USB_VENDOR_ID_EFI		0x2650
+#define USB_DEVICE_ID_EFI_CLASSIC	0x1311
+
 #define USB_VENDOR_ID_ELECOM		0x056e
 #define USB_DEVICE_ID_ELECOM_BM084	0x0061
 
-- 
1.7.10


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

* [RFC ebeam PATCH 2/3] hid: hid-core.c: Blackist eBeam classic device.
  2012-07-28  0:02 [RFC ebeam PATCH 0/3] new USB eBeam input driver Yann Cantin
  2012-07-28  0:02 ` [RFC ebeam PATCH 1/3] hid: hid-ids.h: Add vendor and device ID for eBeam classic device Yann Cantin
@ 2012-07-28  0:02 ` Yann Cantin
  2012-07-28  0:02 ` [RFC ebeam PATCH 3/3] input: misc: New USB eBeam input driver Yann Cantin
  2 siblings, 0 replies; 8+ messages in thread
From: Yann Cantin @ 2012-07-28  0:02 UTC (permalink / raw)
  To: linux-input, linux-usb; +Cc: gregkh, dmitry.torokhov, linux-kernel, Yann Cantin


Signed-off-by: Yann Cantin <yann.cantin@laposte.net>
---
 drivers/hid/hid-core.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 500844f..1c03586 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1908,6 +1908,9 @@ static const struct hid_device_id hid_ignore_list[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, 0x0004) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, 0x000a) },
+#if defined(CONFIG_INPUT_EBEAM_USB_CLASSIC)
+	{ HID_USB_DEVICE(USB_VENDOR_ID_EFI, USB_DEVICE_ID_EFI_CLASSIC) },
+#endif
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) },
-- 
1.7.10


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

* [RFC ebeam PATCH 3/3] input: misc: New USB eBeam input driver.
  2012-07-28  0:02 [RFC ebeam PATCH 0/3] new USB eBeam input driver Yann Cantin
  2012-07-28  0:02 ` [RFC ebeam PATCH 1/3] hid: hid-ids.h: Add vendor and device ID for eBeam classic device Yann Cantin
  2012-07-28  0:02 ` [RFC ebeam PATCH 2/3] hid: hid-core.c: Blackist " Yann Cantin
@ 2012-07-28  0:02 ` Yann Cantin
  2012-07-28  1:42   ` Dmitry Torokhov
  2 siblings, 1 reply; 8+ messages in thread
From: Yann Cantin @ 2012-07-28  0:02 UTC (permalink / raw)
  To: linux-input, linux-usb; +Cc: gregkh, dmitry.torokhov, linux-kernel, Yann Cantin


Signed-off-by: Yann Cantin <yann.cantin@laposte.net>
---
 drivers/input/misc/Kconfig  |   21 +
 drivers/input/misc/Makefile |    1 +
 drivers/input/misc/ebeam.c  |  895 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 917 insertions(+)
 create mode 100644 drivers/input/misc/ebeam.c

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 7faf4a7..0e798cb 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -73,6 +73,27 @@ config INPUT_BMA150
 	  To compile this driver as a module, choose M here: the
 	  module will be called bma150.
 
+config INPUT_EBEAM_USB
+	tristate "USB eBeam driver"
+	depends on USB_ARCH_HAS_HCD
+	select USB
+	help
+	  Say Y here if you have a USB eBeam pointing device and want to
+	  use it without any proprietary user space tools.
+
+	  Have a look at <http://sourceforge.net/projects/ebeam/> for
+	  a usage description and the required user-space tools.
+
+	  Currently, only the Classic Projection model is supported.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ebeam.
+
+config INPUT_EBEAM_USB_CLASSIC
+	bool "eBeam Classic Projection support"
+	depends on INPUT_EBEAM_USB
+	default y
+
 config INPUT_PCSPKR
 	tristate "PC Speaker support"
 	depends on PCSPKR_PLATFORM
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index f55cdf4..4b5e4a9 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_INPUT_CMA3000_I2C)		+= cma3000_d0x_i2c.o
 obj-$(CONFIG_INPUT_COBALT_BTNS)		+= cobalt_btns.o
 obj-$(CONFIG_INPUT_DA9052_ONKEY)	+= da9052_onkey.o
 obj-$(CONFIG_INPUT_DM355EVM)		+= dm355evm_keys.o
+obj-$(CONFIG_INPUT_EBEAM_USB)		+= ebeam.o
 obj-$(CONFIG_INPUT_GP2A)		+= gp2ap002a00f.o
 obj-$(CONFIG_INPUT_GPIO_TILT_POLLED)	+= gpio_tilt_polled.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
diff --git a/drivers/input/misc/ebeam.c b/drivers/input/misc/ebeam.c
new file mode 100644
index 0000000..a18615a
--- /dev/null
+++ b/drivers/input/misc/ebeam.c
@@ -0,0 +1,895 @@
+/******************************************************************************
+ *
+ * eBeam driver
+ *
+ * Copyright (C) 2012 Yann Cantin (yann.cantin@laposte.net)
+ *
+ *	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.
+ *
+ *  based on
+ *
+ *	usbtouchscreen.c by Daniel Ritz <daniel.ritz@gmx.ch>
+ *	aiptek.c (sysfs/settings) by Chris Atenasio <chris@crud.net>
+ *				     Bryan W. Headley <bwheadley@earthlink.net>
+ *
+ *****************************************************************************/
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/usb.h>
+#include <linux/usb/input.h>
+#include <linux/hid.h>
+
+#define DRIVER_VERSION		"v0.5"
+#define DRIVER_AUTHOR		"Yann Cantin <yann.cantin@laposte.net>"
+#define DRIVER_DESC		"USB eBeam Driver"
+
+#define USB_VENDOR_ID_EFI	   0x2650   /* Electronics For Imaging, Inc   */
+#define USB_DEVICE_ID_EFI_CLASSIC  0x1311   /* Classic projection "La banane" */
+
+#define EBEAM_BTN_TIP		0x1      /* tip    */
+#define EBEAM_BTN_LIT		0x2      /* little */
+#define EBEAM_BTN_BIG		0x4      /* big    */
+
+/* until KConfig */
+#define CONFIG_INPUT_EBEAM_USB_CLASSIC
+
+/* device specifc data/functions */
+struct ebeam_device;
+struct ebeam_device_info {
+	int min_X;
+	int max_X;
+	int min_Y;
+	int max_Y;
+
+	/*
+	 * TODO : Check if it's really necessary, waiting for other device info.
+	 * Always service the USB devices irq not just when the input device is
+	 * open. This is useful when devices have a watchdog which prevents us
+	 * from periodically polling the device. Leave this unset unless your
+	 * ebeam device requires it, as it does consume more of the USB
+	 * bandwidth.
+	 */
+	bool irq_always;
+
+	int rept_size;
+
+	/* optional, generic exist */
+	void (*process_pkt)  (struct ebeam_device *ebeam,
+			      unsigned char *pkt,
+			      int len);
+
+	/* mandatory, model-specific */
+	int  (*read_data)    (struct ebeam_device *ebeam,
+			      unsigned char *pkt);
+	void (*setup_input)  (struct ebeam_device *ebeam,
+			      struct input_dev *input_dev);
+	void (*report_input) (struct ebeam_device *ebeam);
+
+	/* optional, model-specific */
+	int  (*alloc)	(struct ebeam_device *ebeam);
+	int  (*init)	(struct ebeam_device *ebeam);
+	void (*exit)	(struct ebeam_device *ebeam);
+};
+
+/* ebeam settings */
+struct ebeam_settings {
+	int min_x;
+	int max_x;
+	int min_y;
+	int max_y;
+
+	/* H matrix */
+	s64 h1;
+	s64 h2;
+	s64 h3;
+	s64 h4;
+	s64 h5;
+	s64 h6;
+	s64 h7;
+	s64 h8;
+	s64 h9;
+};
+
+/* ebeam device */
+struct ebeam_device {
+	unsigned char		 *data;
+	dma_addr_t		 data_dma;
+	unsigned char		 *buffer;
+	int			 buf_len;
+	struct urb		 *irq;
+	struct usb_interface	 *interface;
+	struct input_dev	 *input;
+	struct ebeam_device_info *type;
+	char			 name[128];
+	char			 phys[64];
+	void			 *priv;
+
+	struct ebeam_settings	 cursetting;	/* device's current settings */
+	struct ebeam_settings	 newsetting;	/* ... and new ones	  */
+
+	bool			 calibrated;	/* false : send raw
+						 * true  : send computed     */
+	u16			 X, Y;		/* raw coordinates	   */
+	int			 x, y;		/* computed coordinates      */
+	int			 btn_map;	/* internal buttons map      */
+};
+
+
+/* device types */
+enum {
+	DEVTYPE_IGNORE = -1,
+	DEVTYPE_CLASSIC,
+};
+
+static const struct usb_device_id ebeam_devices[] = {
+#ifdef CONFIG_INPUT_EBEAM_USB_CLASSIC
+	{USB_DEVICE(USB_VENDOR_ID_EFI, USB_DEVICE_ID_EFI_CLASSIC),
+			.driver_info = DEVTYPE_CLASSIC},
+#endif
+	{}
+};
+
+/*******************************************************************************
+ * sysfs part
+ */
+
+/*
+ * screen min/max and H matrix coefs
+ * _get return *current* value
+ * _set set new value
+ */
+#define DEVICE_MINMAX_ATTR(MM)						       \
+static ssize_t ebeam_##MM##_get(struct device *dev,			       \
+				struct device_attribute *attr,		       \
+				char *buf)				       \
+{									       \
+	struct ebeam_device *ebeam = dev_get_drvdata(dev);		       \
+									       \
+	return snprintf(buf, PAGE_SIZE, "%d\n", ebeam->cursetting.MM);	       \
+}									       \
+static ssize_t ebeam_##MM##_set(struct device *dev,			       \
+				struct device_attribute *attr,		       \
+				const char *buf,			       \
+				size_t count)				       \
+{									       \
+	struct ebeam_device *ebeam = dev_get_drvdata(dev);		       \
+	int err, MM;							       \
+									       \
+	err = kstrtoint(buf, 10, &MM);					       \
+	if (err)							       \
+		return err;						       \
+									       \
+	ebeam->newsetting.MM = MM;					       \
+	return count;							       \
+}									       \
+static DEVICE_ATTR(MM, S_IRUGO | S_IWUGO,				       \
+		   ebeam_##MM##_get,					       \
+		   ebeam_##MM##_set)
+
+DEVICE_MINMAX_ATTR(min_x);
+DEVICE_MINMAX_ATTR(max_x);
+DEVICE_MINMAX_ATTR(min_y);
+DEVICE_MINMAX_ATTR(max_y);
+
+#define DEVICE_H_ATTR(SET_ID)						       \
+static ssize_t ebeam_h##SET_ID##_get(struct device *dev,		       \
+				     struct device_attribute *attr,	       \
+				     char *buf)				       \
+{									       \
+	struct ebeam_device *ebeam = dev_get_drvdata(dev);		       \
+									       \
+	return snprintf(buf, PAGE_SIZE, "%lld\n", ebeam->cursetting.h##SET_ID);\
+}									       \
+static ssize_t ebeam_h##SET_ID##_set(struct device *dev,		       \
+				     struct device_attribute *attr,	       \
+				     const char *buf,			       \
+				     size_t count)			       \
+{									       \
+	struct ebeam_device *ebeam = dev_get_drvdata(dev);		       \
+	int err;							       \
+	u64 h;								       \
+									       \
+	err = kstrtoll(buf, 10, &h);					       \
+	if (err)							       \
+		return err;						       \
+									       \
+	ebeam->newsetting.h##SET_ID = h;				       \
+	return count;							       \
+}									       \
+static DEVICE_ATTR(h##SET_ID, S_IRUGO | S_IWUGO,			       \
+		   ebeam_h##SET_ID##_get,				       \
+		   ebeam_h##SET_ID##_set)
+
+DEVICE_H_ATTR(1);
+DEVICE_H_ATTR(2);
+DEVICE_H_ATTR(3);
+DEVICE_H_ATTR(4);
+DEVICE_H_ATTR(5);
+DEVICE_H_ATTR(6);
+DEVICE_H_ATTR(7);
+DEVICE_H_ATTR(8);
+DEVICE_H_ATTR(9);
+
+/*
+ * sysfs calibrated
+ * Once H matrix coefs are set, writing 1 to this file triggers
+ * coordinates mapping.
+ * Anything else reset the device to un-calibrated mode,
+ * storing cursetting in newsetting.
+*/
+static ssize_t ebeam_calibrated_get(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	struct ebeam_device *ebeam = dev_get_drvdata(dev);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", ebeam->calibrated);
+}
+
+static ssize_t ebeam_calibrated_set(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf,
+				    size_t count)
+{
+	struct ebeam_device *ebeam = dev_get_drvdata(dev);
+	int err, c;
+
+	err = kstrtoint(buf, 10, &c);
+	if (err)
+		return err;
+
+	if (c == 1) {
+		memcpy(&ebeam->cursetting, &ebeam->newsetting,
+		       sizeof(struct ebeam_settings));
+		ebeam->calibrated = true;
+		ebeam->type->setup_input(ebeam, ebeam->input);
+	} else {
+		memcpy(&ebeam->newsetting, &ebeam->cursetting,
+		       sizeof(struct ebeam_settings));
+		ebeam->calibrated = false;
+		ebeam->type->setup_input(ebeam, ebeam->input);
+	}
+
+	return count;
+}
+
+static DEVICE_ATTR(calibrated, S_IRUGO | S_IWUGO,
+		   ebeam_calibrated_get, ebeam_calibrated_set);
+
+static struct attribute *ebeam_attrs[] = {
+	&dev_attr_min_x.attr,
+	&dev_attr_min_y.attr,
+	&dev_attr_max_x.attr,
+	&dev_attr_max_y.attr,
+	&dev_attr_h1.attr,
+	&dev_attr_h2.attr,
+	&dev_attr_h3.attr,
+	&dev_attr_h4.attr,
+	&dev_attr_h5.attr,
+	&dev_attr_h6.attr,
+	&dev_attr_h7.attr,
+	&dev_attr_h8.attr,
+	&dev_attr_h9.attr,
+	&dev_attr_calibrated.attr,
+	NULL
+};
+
+static const struct attribute_group ebeam_attr_group = {
+	.attrs = ebeam_attrs,
+};
+
+/*******************************************************************************
+ * classic projection Part
+ */
+
+#ifdef CONFIG_INPUT_EBEAM_USB_CLASSIC
+/* IRQ */
+static int classic_read_data(struct ebeam_device *ebeam, unsigned char *pkt)
+{
+
+/*
+ * Packet description : 8 bytes
+ *
+ *  nop packet : FF FF FF FF FF FF FF FF
+ *
+ *  pkt[0] : Sensors
+ *	bit 1 : ultrasound signal (guessed)
+ *	bit 2 : IR signal (tested with a remote...) ;
+ *	readings OK : 0x03 (anything else is a show-stopper)
+ *
+ *  pkt[1] : X low
+ *  pkt[2] : X high
+ *
+ *  pkt[3] : Y low
+ *  pkt[4] : Y high
+ *
+ *  pkt[5] : fiability ?
+ *	often 0xC0
+ *	> 0x80 : OK
+ *
+ *  pkt[6] :
+ *	buttons state (low 4 bits)
+ *		0x1 = no buttons
+ *		bit 0 : tip (WARNING inversed : 0=pressed)
+ *		bit 1 : ? (always 0 during tests)
+ *		bit 2 : little (1=pressed)
+ *		bit 3 : big (1=pressed)
+ *
+ *	pointer ID : (hight 4 bits)
+ *		Tested  : 0x6=wand ;
+ *		Guessed : 0x1=red ; 0x2=blue ; 0x3=green ; 0x4=black ;
+ *			  0x5=eraser
+ *		bit 4 : pointer ID
+ *		bit 5 : pointer ID
+ *		bit 6 : pointer ID
+ *		bit 7 : pointer ID
+ *
+ *
+ *  pkt[7] : fiability ?
+ *	often 0xFF
+ *
+ */
+
+	/* Filtering bad/nop packet */
+	if (pkt[0] != 0x03)
+		return 0;
+
+	ebeam->X = (pkt[2] << 8) | pkt[1];
+	ebeam->Y = (pkt[4] << 8) | pkt[3];
+
+	ebeam->btn_map = (!(pkt[6] & 0x1))	|
+			 ((pkt[6] & 0x4) >> 1)	|
+			 ((pkt[6] & 0x8) >> 1);
+
+	return 1;
+}
+
+/* IRQ */
+static void classic_report_input(struct ebeam_device *ebeam)
+{
+	input_report_key(ebeam->input, BTN_LEFT,
+			 (ebeam->btn_map & EBEAM_BTN_TIP));
+	input_report_key(ebeam->input, BTN_MIDDLE,
+			 (ebeam->btn_map & EBEAM_BTN_LIT));
+	input_report_key(ebeam->input, BTN_RIGHT,
+			 (ebeam->btn_map & EBEAM_BTN_BIG));
+
+	input_report_abs(ebeam->input, ABS_X, ebeam->x);
+	input_report_abs(ebeam->input, ABS_Y, ebeam->y);
+
+	input_sync(ebeam->input);
+}
+
+static void classic_setup_input(struct ebeam_device *ebeam,
+				struct input_dev *input_dev)
+{
+	unsigned long flags;
+
+	/* Take event lock while modifying parameters */
+	spin_lock_irqsave(&input_dev->event_lock, flags);
+
+	/* Properties */
+	set_bit(INPUT_PROP_DIRECT,  input_dev->propbit);
+
+	/* Events generated */
+	set_bit(EV_KEY, input_dev->evbit);
+	set_bit(EV_ABS, input_dev->evbit);
+
+	/* Keys */
+	set_bit(BTN_LEFT,   input_dev->keybit);
+	set_bit(BTN_MIDDLE, input_dev->keybit);
+	set_bit(BTN_RIGHT,  input_dev->keybit);
+
+	/* Axis */
+	if (!ebeam->calibrated) {
+		ebeam->cursetting.min_x = ebeam->type->min_X;
+		ebeam->cursetting.max_x = ebeam->type->max_X;
+		ebeam->cursetting.min_y = ebeam->type->min_Y;
+		ebeam->cursetting.max_y = ebeam->type->max_Y;
+	}
+
+	input_set_abs_params(input_dev, ABS_X,
+			     ebeam->cursetting.min_x, ebeam->cursetting.max_x,
+			     0, 0);
+	input_set_abs_params(input_dev, ABS_Y,
+			     ebeam->cursetting.min_y, ebeam->cursetting.max_y,
+			     0, 0);
+
+	spin_unlock_irqrestore(&input_dev->event_lock, flags);
+}
+
+#endif
+
+/*****************************************************************************
+ * device descriptors
+ */
+static struct ebeam_device_info ebeam_dev_info[] = {
+#ifdef CONFIG_INPUT_EBEAM_USB_CLASSIC
+	[DEVTYPE_CLASSIC] = {
+		.min_X		= 0,
+		.max_X		= 65535,
+		.min_Y		= 0,
+		.max_Y		= 65535,
+		.rept_size	= 8,
+		.read_data	= classic_read_data,
+		.setup_input	= classic_setup_input,
+		.report_input	= classic_report_input,
+	},
+#endif
+};
+
+/*******************************************************************************
+ * Generic Part
+ * Nothing model-specific below this point
+ */
+
+static void ebeam_init_settings(struct ebeam_device *ebeam)
+{
+	ebeam->calibrated = false;
+
+	/* Init (x,y) min/max to raw ones */
+	ebeam->cursetting.min_x = ebeam->newsetting.min_x = ebeam->type->min_X;
+	ebeam->cursetting.max_x = ebeam->newsetting.max_x = ebeam->type->max_X;
+	ebeam->cursetting.min_y = ebeam->newsetting.min_y = ebeam->type->min_Y;
+	ebeam->cursetting.max_y = ebeam->newsetting.max_y = ebeam->type->max_Y;
+
+	/* Safe values for the H matrix (Identity) */
+	ebeam->cursetting.h1 = ebeam->newsetting.h1 = 1;
+	ebeam->cursetting.h2 = ebeam->newsetting.h2 = 0;
+	ebeam->cursetting.h3 = ebeam->newsetting.h3 = 0;
+
+	ebeam->cursetting.h4 = ebeam->newsetting.h4 = 0;
+	ebeam->cursetting.h5 = ebeam->newsetting.h5 = 1;
+	ebeam->cursetting.h6 = ebeam->newsetting.h6 = 0;
+
+	ebeam->cursetting.h7 = ebeam->newsetting.h7 = 0;
+	ebeam->cursetting.h8 = ebeam->newsetting.h8 = 0;
+	ebeam->cursetting.h9 = ebeam->newsetting.h9 = 1;
+}
+
+/*
+ * IRQ
+ * compute screen coordinates from raw
+ * Overflow and negative values are user space's problem
+ */
+static bool ebeam_calculate_xy(struct ebeam_device *ebeam)
+{
+	/* TODO : check if u64 division is available on all plateform */
+
+	s64 scale;
+
+	if (!ebeam->calibrated) {
+		ebeam->x = ebeam->X;
+		ebeam->y = ebeam->Y;
+	} else {
+		scale = ebeam->cursetting.h7 * ebeam->X +
+			ebeam->cursetting.h8 * ebeam->Y +
+			ebeam->cursetting.h9;
+
+		/* Who want a division by zero in kernel ? */
+		if (scale == 0) {
+			dev_err(&(ebeam->interface)->dev,
+				"%s - Division by zero, wrong calibration.\n",
+				__func__);
+			dev_err(&(ebeam->interface)->dev,
+				"%s - Resetting to un-calibrated mode.\n",
+				__func__);
+			ebeam->calibrated = false;
+			return 0;
+		}
+
+		/*
+		 * We *must* round the result, but not with (int) (v1/v2 + 0.5)
+		 *
+		 * (int) (v1/v2 + 0.5) <=> (int) ( (2*v1 + v2)/(2*v2) )
+		 */
+		ebeam->x = (int) ((((ebeam->cursetting.h1 * ebeam->X +
+				     ebeam->cursetting.h2 * ebeam->Y +
+				     ebeam->cursetting.h3) << 1) + scale) /
+				     (scale << 1));
+		ebeam->y = (int) ((((ebeam->cursetting.h4 * ebeam->X +
+				     ebeam->cursetting.h5 * ebeam->Y +
+				     ebeam->cursetting.h6) << 1) + scale) /
+				     (scale << 1));
+	}
+
+	return 1;
+}
+
+/* IRQ */
+/* generic function, may be overloaded */
+static void ebeam_process_pkt(struct ebeam_device *ebeam,
+			      unsigned char *pkt, int len)
+{
+	struct ebeam_device_info *type = ebeam->type;
+
+	if (!type->read_data(ebeam, pkt))
+		return;
+
+	if (!ebeam_calculate_xy(ebeam))
+		return;
+
+	type->report_input(ebeam);
+}
+
+/* IRQ
+ * handler */
+static void ebeam_irq(struct urb *urb)
+{
+	struct ebeam_device *ebeam = urb->context;
+	struct device *dev = &ebeam->interface->dev;
+	int retval;
+
+	switch (urb->status) {
+	case 0:
+		/* success */
+		break;
+	case -ETIME:
+		/* this urb is timing out */
+		dev_dbg(dev,
+			"%s - urb timed out - was the device unplugged?\n",
+			__func__);
+		return;
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+	case -EPIPE:
+		/* this urb is terminated, clean up */
+		dev_dbg(dev, "%s - urb shutting down with status: %d\n",
+			__func__, urb->status);
+		return;
+	default:
+		dev_dbg(dev, "%s - nonzero urb status received: %d\n",
+			__func__, urb->status);
+		goto exit;
+	}
+
+	ebeam->type->process_pkt(ebeam, ebeam->data, urb->actual_length);
+
+exit:
+	usb_mark_last_busy(interface_to_usbdev(ebeam->interface));
+	retval = usb_submit_urb(urb, GFP_ATOMIC);
+	if (retval)
+		dev_err(dev, "%s - usb_submit_urb failed with result: %d\n",
+			__func__, retval);
+}
+
+static int ebeam_open(struct input_dev *input)
+{
+	struct ebeam_device *ebeam = input_get_drvdata(input);
+	int r;
+
+	ebeam->irq->dev = interface_to_usbdev(ebeam->interface);
+
+	r = usb_autopm_get_interface(ebeam->interface) ? -EIO : 0;
+	if (r < 0)
+		goto out;
+
+	if (!ebeam->type->irq_always) {
+		if (usb_submit_urb(ebeam->irq, GFP_KERNEL)) {
+			r = -EIO;
+			goto out_put;
+		}
+	}
+
+	ebeam->interface->needs_remote_wakeup = 1;
+out_put:
+	usb_autopm_put_interface(ebeam->interface);
+out:
+	return r;
+}
+
+static void ebeam_close(struct input_dev *input)
+{
+	struct ebeam_device *ebeam = input_get_drvdata(input);
+	int r;
+
+	if (!ebeam->type->irq_always)
+		usb_kill_urb(ebeam->irq);
+
+	r = usb_autopm_get_interface(ebeam->interface);
+	ebeam->interface->needs_remote_wakeup = 0;
+
+	if (!r)
+		usb_autopm_put_interface(ebeam->interface);
+}
+
+static int ebeam_suspend(struct usb_interface *intf, pm_message_t message)
+{
+	struct ebeam_device *ebeam = usb_get_intfdata(intf);
+
+	usb_kill_urb(ebeam->irq);
+
+	return 0;
+}
+
+static int ebeam_resume(struct usb_interface *intf)
+{
+	struct ebeam_device *ebeam = usb_get_intfdata(intf);
+	struct input_dev *input = ebeam->input;
+	int result = 0;
+
+	mutex_lock(&input->mutex);
+	if (input->users || ebeam->type->irq_always)
+		result = usb_submit_urb(ebeam->irq, GFP_NOIO);
+	mutex_unlock(&input->mutex);
+
+	return result;
+}
+
+static int ebeam_reset_resume(struct usb_interface *intf)
+{
+	struct ebeam_device *ebeam = usb_get_intfdata(intf);
+	struct input_dev *input = ebeam->input;
+	int err = 0;
+
+	/* reinit the device */
+	if (ebeam->type->init) {
+		err = ebeam->type->init(ebeam);
+		if (err) {
+			dev_dbg(&intf->dev,
+				"%s - type->init() failed, err: %d\n",
+				__func__, err);
+			return err;
+		}
+	}
+
+	/* restart IO if needed */
+	mutex_lock(&input->mutex);
+	if (input->users)
+		err = usb_submit_urb(ebeam->irq, GFP_NOIO);
+	mutex_unlock(&input->mutex);
+
+	return err;
+}
+
+static void ebeam_free_buffers(struct usb_device *udev,
+			       struct ebeam_device *ebeam)
+{
+	usb_free_coherent(udev, ebeam->type->rept_size,
+			  ebeam->data, ebeam->data_dma);
+	kfree(ebeam->buffer);
+}
+
+static struct usb_endpoint_descriptor *
+ebeam_get_input_endpoint(struct usb_host_interface *interface)
+{
+	int i;
+
+	for (i = 0; i < interface->desc.bNumEndpoints; i++)
+		if (usb_endpoint_dir_in(&interface->endpoint[i].desc))
+			return &interface->endpoint[i].desc;
+
+	return NULL;
+}
+
+static int ebeam_probe(struct usb_interface *intf,
+		       const struct usb_device_id *id)
+{
+	struct ebeam_device *ebeam;
+	struct input_dev *input_dev;
+	struct usb_endpoint_descriptor *endpoint;
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct ebeam_device_info *type;
+	int err = -ENOMEM;
+
+	/* some devices are ignored */
+	if (id->driver_info == DEVTYPE_IGNORE)
+		return -ENODEV;
+
+	endpoint = ebeam_get_input_endpoint(intf->cur_altsetting);
+	if (!endpoint)
+		return -ENXIO;
+
+	ebeam = kzalloc(sizeof(struct ebeam_device), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!ebeam || !input_dev)
+		goto out_free;
+
+	type = &ebeam_dev_info[id->driver_info];
+	ebeam->type = type;
+	ebeam_init_settings(ebeam);
+
+	if (!type->process_pkt)
+		type->process_pkt = ebeam_process_pkt;
+
+	ebeam->data = usb_alloc_coherent(udev, type->rept_size,
+					 GFP_KERNEL, &ebeam->data_dma);
+	if (!ebeam->data)
+		goto out_free;
+
+	ebeam->irq = usb_alloc_urb(0, GFP_KERNEL);
+	if (!ebeam->irq) {
+		dev_dbg(&intf->dev,
+			"%s - usb_alloc_urb failed: ebeam->irq\n", __func__);
+		goto out_free_buffers;
+	}
+
+	ebeam->interface = intf;
+	ebeam->input = input_dev;
+
+	/* setup name */
+	snprintf(ebeam->name, sizeof(ebeam->name),
+		 "USB eBeam %04x:%04x",
+		 le16_to_cpu(udev->descriptor.idVendor),
+		 le16_to_cpu(udev->descriptor.idProduct));
+
+	if (udev->manufacturer || udev->product) {
+		strlcat(ebeam->name,
+			" (",
+			sizeof(ebeam->name));
+
+		if (udev->manufacturer)
+			strlcat(ebeam->name,
+				udev->manufacturer,
+				sizeof(ebeam->name));
+
+		if (udev->product) {
+			if (udev->manufacturer)
+				strlcat(ebeam->name,
+					" ",
+					sizeof(ebeam->name));
+			strlcat(ebeam->name,
+				udev->product,
+				sizeof(ebeam->name));
+		}
+
+		strlcat(ebeam->name, ")", sizeof(ebeam->name));
+	}
+
+	/* usb tree */
+	usb_make_path(udev, ebeam->phys, sizeof(ebeam->phys));
+	strlcat(ebeam->phys, "/input0", sizeof(ebeam->phys));
+
+	/* input setup */
+	input_dev->name = ebeam->name;
+	input_dev->phys = ebeam->phys;
+	usb_to_input_id(udev, &input_dev->id);
+	input_dev->dev.parent = &intf->dev;
+
+	input_set_drvdata(input_dev, ebeam);
+
+	input_dev->open = ebeam_open;
+	input_dev->close = ebeam_close;
+
+	/* usb urb setup */
+	if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT)
+		usb_fill_int_urb(ebeam->irq, udev,
+			usb_rcvintpipe(udev, endpoint->bEndpointAddress),
+			ebeam->data, type->rept_size,
+			ebeam_irq, ebeam, endpoint->bInterval);
+	else
+		usb_fill_bulk_urb(ebeam->irq, udev,
+			usb_rcvbulkpipe(udev, endpoint->bEndpointAddress),
+			ebeam->data, type->rept_size,
+			ebeam_irq, ebeam);
+
+	ebeam->irq->dev = udev;
+	ebeam->irq->transfer_dma = ebeam->data_dma;
+	ebeam->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+	/* device specific allocations */
+	if (type->alloc) {
+		err = type->alloc(ebeam);
+		if (err) {
+			dev_dbg(&intf->dev,
+				"%s - type->alloc() failed, err: %d\n",
+				__func__, err);
+			goto out_free_urb;
+		}
+	}
+
+	/* device specific initialisation */
+	if (type->init) {
+		err = type->init(ebeam);
+		if (err) {
+			dev_dbg(&intf->dev,
+				"%s - type->init() failed, err: %d\n",
+				__func__, err);
+			goto out_do_exit;
+		}
+	}
+
+	/* input final setup */
+	err = input_register_device(ebeam->input);
+	if (err) {
+		dev_dbg(&intf->dev,
+			"%s - input_register_device failed, err: %d\n",
+			__func__, err);
+		goto out_do_exit;
+	}
+
+	type->setup_input(ebeam, input_dev);
+
+	/* usb final setup */
+	usb_set_intfdata(intf, ebeam);
+
+	if (ebeam->type->irq_always) {
+		/* this can't fail */
+		usb_autopm_get_interface(intf);
+		err = usb_submit_urb(ebeam->irq, GFP_KERNEL);
+		if (err) {
+			usb_autopm_put_interface(intf);
+			dev_err(&intf->dev,
+				"%s - usb_submit_urb failed with result: %d\n",
+				__func__, err);
+			goto out_unregister_input;
+		}
+	}
+
+	/* sysfs setup */
+	err = sysfs_create_group(&intf->dev.kobj, &ebeam_attr_group);
+	if (err) {
+		dev_dbg(&intf->dev,
+			"%s - cannot create sysfs group, err: %d\n",
+			__func__, err);
+		goto out_unregister_input;
+	}
+
+	return 0;
+
+out_unregister_input:
+	input_unregister_device(input_dev);
+	input_dev = NULL;
+out_do_exit:
+	if (type->exit)
+		type->exit(ebeam);
+out_free_urb:
+	usb_free_urb(ebeam->irq);
+out_free_buffers:
+	ebeam_free_buffers(udev, ebeam);
+out_free:
+	input_free_device(input_dev);
+	kfree(ebeam);
+	return err;
+}
+
+static void ebeam_disconnect(struct usb_interface *intf)
+{
+	struct ebeam_device *ebeam = usb_get_intfdata(intf);
+
+	if (!ebeam)
+		return;
+
+	dev_dbg(&intf->dev,
+		"%s - ebeam is initialized, cleaning up\n", __func__);
+
+	usb_set_intfdata(intf, NULL);
+	/* this will stop IO via close */
+	input_unregister_device(ebeam->input);
+	sysfs_remove_group(&intf->dev.kobj, &ebeam_attr_group);
+	usb_free_urb(ebeam->irq);
+	if (ebeam->type->exit)
+		ebeam->type->exit(ebeam);
+	ebeam_free_buffers(interface_to_usbdev(intf), ebeam);
+	kfree(ebeam);
+}
+
+MODULE_DEVICE_TABLE(usb, ebeam_devices);
+
+static struct usb_driver ebeam_driver = {
+	.name			= "ebeam",
+	.probe			= ebeam_probe,
+	.disconnect		= ebeam_disconnect,
+	.suspend		= ebeam_suspend,
+	.resume			= ebeam_resume,
+	.reset_resume		= ebeam_reset_resume,
+	.id_table		= ebeam_devices,
+	.supports_autosuspend	= 1,
+};
+
+module_usb_driver(ebeam_driver);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
-- 
1.7.10


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

* Re: [RFC ebeam PATCH 3/3] input: misc: New USB eBeam input driver.
  2012-07-28  0:02 ` [RFC ebeam PATCH 3/3] input: misc: New USB eBeam input driver Yann Cantin
@ 2012-07-28  1:42   ` Dmitry Torokhov
  2012-07-28  9:02     ` Yann Cantin
  0 siblings, 1 reply; 8+ messages in thread
From: Dmitry Torokhov @ 2012-07-28  1:42 UTC (permalink / raw)
  To: Yann Cantin; +Cc: linux-input, linux-usb, gregkh, linux-kernel

Hi Yann,

On Sat, Jul 28, 2012 at 02:02:34AM +0200, Yann Cantin wrote:
> 
> Signed-off-by: Yann Cantin <yann.cantin@laposte.net>
> ---
>  drivers/input/misc/Kconfig  |   21 +
>  drivers/input/misc/Makefile |    1 +
>  drivers/input/misc/ebeam.c  |  895 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 917 insertions(+)
>  create mode 100644 drivers/input/misc/ebeam.c
> 
> diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
> index 7faf4a7..0e798cb 100644
> --- a/drivers/input/misc/Kconfig
> +++ b/drivers/input/misc/Kconfig
> @@ -73,6 +73,27 @@ config INPUT_BMA150
>  	  To compile this driver as a module, choose M here: the
>  	  module will be called bma150.
>  
> +config INPUT_EBEAM_USB
> +	tristate "USB eBeam driver"
> +	depends on USB_ARCH_HAS_HCD
> +	select USB
> +	help
> +	  Say Y here if you have a USB eBeam pointing device and want to
> +	  use it without any proprietary user space tools.
> +
> +	  Have a look at <http://sourceforge.net/projects/ebeam/> for
> +	  a usage description and the required user-space tools.
> +
> +	  Currently, only the Classic Projection model is supported.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called ebeam.
> +
> +config INPUT_EBEAM_USB_CLASSIC
> +	bool "eBeam Classic Projection support"
> +	depends on INPUT_EBEAM_USB
> +	default y

Will there be support for other eBean devices (are there any)? If there
will how soon? How different are they? If not the we probably do not
need this INPUT_EBEAM_USB_CLASSIC selector.

> +
>  config INPUT_PCSPKR
>  	tristate "PC Speaker support"
>  	depends on PCSPKR_PLATFORM
> diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
> index f55cdf4..4b5e4a9 100644
> --- a/drivers/input/misc/Makefile
> +++ b/drivers/input/misc/Makefile
> @@ -23,6 +23,7 @@ obj-$(CONFIG_INPUT_CMA3000_I2C)		+= cma3000_d0x_i2c.o
>  obj-$(CONFIG_INPUT_COBALT_BTNS)		+= cobalt_btns.o
>  obj-$(CONFIG_INPUT_DA9052_ONKEY)	+= da9052_onkey.o
>  obj-$(CONFIG_INPUT_DM355EVM)		+= dm355evm_keys.o
> +obj-$(CONFIG_INPUT_EBEAM_USB)		+= ebeam.o
>  obj-$(CONFIG_INPUT_GP2A)		+= gp2ap002a00f.o
>  obj-$(CONFIG_INPUT_GPIO_TILT_POLLED)	+= gpio_tilt_polled.o
>  obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
> diff --git a/drivers/input/misc/ebeam.c b/drivers/input/misc/ebeam.c
> new file mode 100644
> index 0000000..a18615a
> --- /dev/null
> +++ b/drivers/input/misc/ebeam.c
> @@ -0,0 +1,895 @@
> +/******************************************************************************
> + *
> + * eBeam driver
> + *
> + * Copyright (C) 2012 Yann Cantin (yann.cantin@laposte.net)
> + *
> + *	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.
> + *
> + *  based on
> + *
> + *	usbtouchscreen.c by Daniel Ritz <daniel.ritz@gmx.ch>
> + *	aiptek.c (sysfs/settings) by Chris Atenasio <chris@crud.net>
> + *				     Bryan W. Headley <bwheadley@earthlink.net>
> + *
> + *****************************************************************************/
> +
> +#define DEBUG

I do not think leaving DEBUG on is good idea for production code.

> +
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +#include <linux/input.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/usb.h>
> +#include <linux/usb/input.h>
> +#include <linux/hid.h>
> +
> +#define DRIVER_VERSION		"v0.5"
> +#define DRIVER_AUTHOR		"Yann Cantin <yann.cantin@laposte.net>"
> +#define DRIVER_DESC		"USB eBeam Driver"
> +
> +#define USB_VENDOR_ID_EFI	   0x2650   /* Electronics For Imaging, Inc   */
> +#define USB_DEVICE_ID_EFI_CLASSIC  0x1311   /* Classic projection "La banane" */
> +
> +#define EBEAM_BTN_TIP		0x1      /* tip    */
> +#define EBEAM_BTN_LIT		0x2      /* little */
> +#define EBEAM_BTN_BIG		0x4      /* big    */
> +
> +/* until KConfig */
> +#define CONFIG_INPUT_EBEAM_USB_CLASSIC

Huh?

> +
> +/* device specifc data/functions */
> +struct ebeam_device;
> +struct ebeam_device_info {
> +	int min_X;
> +	int max_X;
> +	int min_Y;
> +	int max_Y;
> +
> +	/*
> +	 * TODO : Check if it's really necessary, waiting for other device info.
> +	 * Always service the USB devices irq not just when the input device is
> +	 * open. This is useful when devices have a watchdog which prevents us
> +	 * from periodically polling the device. Leave this unset unless your
> +	 * ebeam device requires it, as it does consume more of the USB
> +	 * bandwidth.
> +	 */
> +	bool irq_always;

Does you device need this?

> +
> +	int rept_size;
> +
> +	/* optional, generic exist */
> +	void (*process_pkt)  (struct ebeam_device *ebeam,
> +			      unsigned char *pkt,
> +			      int len);
> +
> +	/* mandatory, model-specific */
> +	int  (*read_data)    (struct ebeam_device *ebeam,
> +			      unsigned char *pkt);
> +	void (*setup_input)  (struct ebeam_device *ebeam,
> +			      struct input_dev *input_dev);
> +	void (*report_input) (struct ebeam_device *ebeam);
> +
> +	/* optional, model-specific */
> +	int  (*alloc)	(struct ebeam_device *ebeam);
> +	int  (*init)	(struct ebeam_device *ebeam);
> +	void (*exit)	(struct ebeam_device *ebeam);

Again, do you expect to see multitude of sufficiently different
devices or are they going to follow roughly the same protocol?

Thanks.

-- 
Dmitry

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

* Re: [RFC ebeam PATCH 3/3] input: misc: New USB eBeam input driver.
  2012-07-28  1:42   ` Dmitry Torokhov
@ 2012-07-28  9:02     ` Yann Cantin
  2012-07-30  5:56       ` Dmitry Torokhov
  0 siblings, 1 reply; 8+ messages in thread
From: Yann Cantin @ 2012-07-28  9:02 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input, linux-usb, gregkh, linux-kernel

Hi Dmitry,

>> +config INPUT_EBEAM_USB_CLASSIC
>> +	bool "eBeam Classic Projection support"
>> +	depends on INPUT_EBEAM_USB
>> +	default y
> 
> Will there be support for other eBean devices (are there any)? If there
> will how soon? How different are they? If not the we probably do not
> need this INPUT_EBEAM_USB_CLASSIC selector.

I know at least one re-branded same hardware by 3M, i will be able to borrow
one in a month or so. According to the wikipedia article, there's probably more.

There's also newer models and embeded ones in some video projector setup, also
re-branded, based on the same technology and that might use the same type of
protocol, but i can't be sure until someone can inspect them.
These pieces of hardware are quite expensive, and mostly used in educational
or corporate, they are not easy to grab.

The code structure (device selector + functions indirection) also seems overkill
to me for now, but permit to anticipate device's variations. If it appears that they
all works in the same way, it'll be easy (and more comfortable to me) to step down,
the opposite seems more difficult.

>> +#define DEBUG
> I do not think leaving DEBUG on is good idea for production code.
Cinder, cleaned.
 
>> +/* until KConfig */
>> +#define CONFIG_INPUT_EBEAM_USB_CLASSIC
> 
> Huh?

I test the module against my running kernel, building out of tree,
and don't know how to define that in the makefile.
This will be cleaned in final step.

>> +	bool irq_always;
> 
> Does you device need this?

Part of "overkill" foresight.
 
>> +	/* optional, model-specific */
>> +	int  (*alloc)	(struct ebeam_device *ebeam);
>> +	int  (*init)	(struct ebeam_device *ebeam);
>> +	void (*exit)	(struct ebeam_device *ebeam);
> 
> Again, do you expect to see multitude of sufficiently different
> devices or are they going to follow roughly the same protocol?
ditto.

-- 
Yann Cantin
A4FEB47F
--

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

* Re: [RFC ebeam PATCH 3/3] input: misc: New USB eBeam input driver.
  2012-07-28  9:02     ` Yann Cantin
@ 2012-07-30  5:56       ` Dmitry Torokhov
  2012-07-30 14:25         ` Yann Cantin
  0 siblings, 1 reply; 8+ messages in thread
From: Dmitry Torokhov @ 2012-07-30  5:56 UTC (permalink / raw)
  To: Yann Cantin; +Cc: linux-input, linux-usb, gregkh, linux-kernel

On Sat, Jul 28, 2012 at 11:02:13AM +0200, Yann Cantin wrote:
> Hi Dmitry,
> 
> >> +config INPUT_EBEAM_USB_CLASSIC
> >> +	bool "eBeam Classic Projection support"
> >> +	depends on INPUT_EBEAM_USB
> >> +	default y
> > 
> > Will there be support for other eBean devices (are there any)? If there
> > will how soon? How different are they? If not the we probably do not
> > need this INPUT_EBEAM_USB_CLASSIC selector.
> 
> I know at least one re-branded same hardware by 3M, i will be able to borrow
> one in a month or so. According to the wikipedia article, there's probably more.
> 
> There's also newer models and embeded ones in some video projector setup, also
> re-branded, based on the same technology and that might use the same type of
> protocol, but i can't be sure until someone can inspect them.
> These pieces of hardware are quite expensive, and mostly used in educational
> or corporate, they are not easy to grab.
> 
> The code structure (device selector + functions indirection) also seems overkill
> to me for now, but permit to anticipate device's variations. If it appears that they
> all works in the same way, it'll be easy (and more comfortable to me) to step down,
> the opposite seems more difficult.

Actually I am hesitant to add infrastructure if it is unclear if we need
it at all.

Thanks.

-- 
Dmitry

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

* Re: [RFC ebeam PATCH 3/3] input: misc: New USB eBeam input driver.
  2012-07-30  5:56       ` Dmitry Torokhov
@ 2012-07-30 14:25         ` Yann Cantin
  0 siblings, 0 replies; 8+ messages in thread
From: Yann Cantin @ 2012-07-30 14:25 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-input, linux-usb, gregkh, linux-kernel

Hi,

>> The code structure (device selector + functions indirection) also seems overkill
>> to me for now, but permit to anticipate device's variations. If it appears that they
>> all works in the same way, it'll be easy (and more comfortable to me) to step down,
>> the opposite seems more difficult.
> 
> Actually I am hesitant to add infrastructure if it is unclear if we need
> it at all.

Understand.

I've thrown some hook to see if i can get my hands on other devices.

In the meantime, i'll bet on uniform support and strip down the driver. Wish me luck.

Thanks.
-- 
Yann Cantin
A4FEB47F
--

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

end of thread, other threads:[~2012-07-30 14:24 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-28  0:02 [RFC ebeam PATCH 0/3] new USB eBeam input driver Yann Cantin
2012-07-28  0:02 ` [RFC ebeam PATCH 1/3] hid: hid-ids.h: Add vendor and device ID for eBeam classic device Yann Cantin
2012-07-28  0:02 ` [RFC ebeam PATCH 2/3] hid: hid-core.c: Blackist " Yann Cantin
2012-07-28  0:02 ` [RFC ebeam PATCH 3/3] input: misc: New USB eBeam input driver Yann Cantin
2012-07-28  1:42   ` Dmitry Torokhov
2012-07-28  9:02     ` Yann Cantin
2012-07-30  5:56       ` Dmitry Torokhov
2012-07-30 14:25         ` Yann Cantin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).