Re: [PATCH V3] input: add EETI eGalax I2C capacitive multi touch driver.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Zhang,

On Thu, Nov 10, 2011 at 06:01:42PM +0800, Zhang Jiejing wrote:
> This patch adds the EETI eGalax serial multi touch controller driver.
> 
> EETI eGalax serial touch screen controller is a I2C based multiple
> capacitive touch screen controller, it can support 5 touch events maximum.
> 
> Signed-off-by: Zhang Jiejing <jiejing.zhang@xxxxxxxxxxxxx>
> 
> ---
> V1 changes:
> * use mt protocol B for report pointer.
> * get the pressure value from pointer.
> * use macro to define X,Y max value.
> 
> V2 changes:
> * change MODE_SINGLE to a meanful name MODE_MOUSE
> * add some comment on each mode to avoid misunderstand
> 
> V3 changes:
> * some typo fix
> * remove MODE_MOUSE, since it can't support both mode 100% well.
>   also use this chip as MODE_MOUSE is very rare case.

Looks much nicer now.

...

>  obj-$(CONFIG_TOUCHSCREEN_GUNZE)		+= gunze.o
>  obj-$(CONFIG_TOUCHSCREEN_EETI)		+= eeti_ts.o
>  obj-$(CONFIG_TOUCHSCREEN_ELO)		+= elo.o
> +obj-$(CONFIG_TOUCHSCREEN_EGALAX)	+= egalax_ts.o

'g' is before 'l'...

> +
> +/* EETI eGalax serial touch screen controller is a I2C based multiple
> + * touch screen controller, it can supports 5 pointer multiple touch. */

s/it can supports 5 pointer/it supports 5 point/

> +
> +/* TODO:
> +  - auto idle mode support
> +*/
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/i2c.h>
> +#include <linux/interrupt.h>
> +#include <linux/input.h>
> +#include <linux/irq.h>
> +#include <linux/gpio.h>
> +#include <linux/delay.h>
> +#include <linux/slab.h>
> +#include <linux/bitops.h>
> +#include <linux/input/mt.h>
> +
> +/* Mouse Mode: some panel may configure the controller to mouse mode,
> + * which can only report one point at a given time.
> + * This driver will ignore events in this mode.
> + */
> +#define REPORT_MODE_MOUSE		0x1
> +/* Vendor Mode: this mode is used to transfer some vendor specify

s/specify/specific/

> + * messages, it was ignore in this driver.

s/, it was ignore in this driver//

> + * This driver will ignore events in this mode.
> + */
> +#define REPORT_MODE_VENDOR		0x3
> +/* Multiple Touch Mode */
> +#define REPORT_MODE_MTTOUCH		0x4
> +
> +#define MAX_SUPPORT_POINTS		5
> +
> +#define EVENT_VALID_OFFSET	7
> +#define EVENT_VALID_MASK	(0x1 << EVENT_VALID_OFFSET)
> +#define EVENT_ID_OFFSET		2
> +#define EVENT_ID_MASK		(0xf << EVENT_ID_OFFSET)
> +#define EVENT_IN_RANGE		(0x1 << 1)
> +#define EVENT_DOWN_UP		(0X1 << 0)
> +
> +#define MAX_I2C_DATA_LEN	10
> +
> +#define EGALAX_MAX_X	32760
> +#define EGALAX_MAX_Y	32760
> +
> +struct egalax_ts {
> +	struct i2c_client		*client;
> +	struct input_dev		*input_dev;
> +};
> +
> +static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id)
> +{
> +	struct egalax_ts *data = dev_id;
> +	struct input_dev *input_dev = data->input_dev;
> +	struct i2c_client *client = data->client;
> +	u8 buf[MAX_I2C_DATA_LEN];
> +	int id, ret, x, y, z;
> +	bool down, valid;
> +	u8 state;
> +
> +retry:
> +	ret = i2c_master_recv(client, buf, MAX_I2C_DATA_LEN);
> +	if (ret == -EAGAIN)
> +		goto retry;
> +

Can't allow spinnig indefinitely...

	do {
		error = i2c_master_recv(client, buf, MAX_I2C_DATA_LEN);
	} while (error == -EAGAIN && tries++ < EGALAX_MAX_TRIES);

> +
> +	input_dev->name = "EETI eGalax Touch Screen";
> +	input_dev->phys = "I2C",

I'd just drop this phys, it does not provide any additional information
compared to BUS_I2C below.

> +	input_dev->id.bustype = BUS_I2C;
> +	input_dev->dev.parent = &client->dev;
> +
> +	__set_bit(EV_ABS, input_dev->evbit);
> +	__set_bit(EV_KEY, input_dev->evbit);
> +	__set_bit(BTN_TOUCH, input_dev->keybit);
> +	__set_bit(EV_SYN, input_dev->evbit);

	Not need, always set by input core.

> +	__set_bit(ABS_X, input_dev->absbit);
> +	__set_bit(ABS_Y, input_dev->absbit);

	Calls below will take care of these 2.

> +
> +	input_set_abs_params(input_dev, ABS_X, 0, EGALAX_MAX_X, 0, 0);
> +	input_set_abs_params(input_dev, ABS_Y, 0, EGALAX_MAX_Y, 0, 0);
> +	input_set_abs_params(input_dev,
> +			     ABS_MT_POSITION_X, 0, EGALAX_MAX_X, 0, 0);
> +	input_set_abs_params(input_dev,
> +			     ABS_MT_POSITION_X, 0, EGALAX_MAX_Y, 0, 0);
> +	input_mt_init_slots(input_dev, MAX_SUPPORT_POINTS);
> +
> +	input_set_drvdata(input_dev, data);
> +
> +	ret = request_threaded_irq(client->irq, NULL, egalax_ts_interrupt,
> +				   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
> +				   "egalax_ts", data);
> +	if (ret < 0) {
> +		dev_err(&client->dev, "Failed to register interrupt\n");
> +		goto err_free_dev;
> +	}
> +
> +	ret = input_register_device(data->input_dev);
> +	if (ret < 0)
> +		goto err_free_irq;
> +	i2c_set_clientdata(client, data);
> +	return 0;
> +
> +err_free_irq:
> +	free_irq(client->irq, data);
> +err_free_dev:
> +	input_free_device(input_dev);
> +err_free_data:
> +	kfree(data);
> +
> +	return ret;
> +}
> +
> +static __devexit int egalax_ts_remove(struct i2c_client *client)
> +{
> +	struct egalax_ts *data = i2c_get_clientdata(client);
> +
> +	free_irq(client->irq, data);
> +	input_unregister_device(data->input_dev);
> +	input_free_device(data->input_dev);

No calls to input_free_device after input_unregister_device.

Thanks.

-- 
Dmitry
--
To unsubscribe from this list: send the line "unsubscribe linux-input" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media Devel]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Linux Wireless Networking]     [Linux Omap]

  Powered by Linux