Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 468792eb authored by Dmitry Torokhov's avatar Dmitry Torokhov
Browse files

Input: migor-ts - convert to a threaded IRQ



Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent e23ed600
Loading
Loading
Loading
Loading
+24 −41
Original line number Original line Diff line number Diff line
@@ -36,7 +36,6 @@
struct migor_ts_priv {
struct migor_ts_priv {
	struct i2c_client *client;
	struct i2c_client *client;
	struct input_dev *input;
	struct input_dev *input;
	struct delayed_work work;
	int irq;
	int irq;
};
};


@@ -44,15 +43,24 @@ static const u_int8_t migor_ts_ena_seq[17] = { 0x33, 0x22, 0x11,
					       0x01, 0x06, 0x07, };
					       0x01, 0x06, 0x07, };
static const u_int8_t migor_ts_dis_seq[17] = { };
static const u_int8_t migor_ts_dis_seq[17] = { };


static void migor_ts_poscheck(struct work_struct *work)
static irqreturn_t migor_ts_isr(int irq, void *dev_id)
{
{
	struct migor_ts_priv *priv = container_of(work,
	struct migor_ts_priv *priv = dev_id;
						  struct migor_ts_priv,
						  work.work);
	unsigned short xpos, ypos;
	unsigned short xpos, ypos;
	unsigned char event;
	unsigned char event;
	u_int8_t buf[16];
	u_int8_t buf[16];


	/*
	 * The touch screen controller chip is hooked up to the CPU
	 * using I2C and a single interrupt line. The interrupt line
	 * is pulled low whenever someone taps the screen. To deassert
	 * the interrupt line we need to acknowledge the interrupt by
	 * communicating with the controller over the slow i2c bus.
	 *
	 * Since I2C bus controller may sleep we are using threaded
	 * IRQ here.
	 */

	memset(buf, 0, sizeof(buf));
	memset(buf, 0, sizeof(buf));


	/* Set Index 0 */
	/* Set Index 0 */
@@ -72,41 +80,25 @@ static void migor_ts_poscheck(struct work_struct *work)
	xpos = ((buf[11] & 0x03) << 8 | buf[10]);
	xpos = ((buf[11] & 0x03) << 8 | buf[10]);
	event = buf[12];
	event = buf[12];


	if (event == EVENT_PENDOWN || event == EVENT_REPEAT) {
	switch (event) {
	case EVENT_PENDOWN:
	case EVENT_REPEAT:
		input_report_key(priv->input, BTN_TOUCH, 1);
		input_report_key(priv->input, BTN_TOUCH, 1);
		input_report_abs(priv->input, ABS_X, ypos); /*X-Y swap*/
		input_report_abs(priv->input, ABS_X, ypos); /*X-Y swap*/
		input_report_abs(priv->input, ABS_Y, xpos);
		input_report_abs(priv->input, ABS_Y, xpos);
		input_sync(priv->input);
		input_sync(priv->input);
	} else if (event == EVENT_PENUP) {
		break;

	case EVENT_PENUP:
		input_report_key(priv->input, BTN_TOUCH, 0);
		input_report_key(priv->input, BTN_TOUCH, 0);
		input_sync(priv->input);
		input_sync(priv->input);
	}
		break;
 out:
	enable_irq(priv->irq);
	}
	}


static irqreturn_t migor_ts_isr(int irq, void *dev_id)
 out:
{
	struct migor_ts_priv *priv = dev_id;

	/* the touch screen controller chip is hooked up to the cpu
	 * using i2c and a single interrupt line. the interrupt line
	 * is pulled low whenever someone taps the screen. to deassert
	 * the interrupt line we need to acknowledge the interrupt by
	 * communicating with the controller over the slow i2c bus.
	 *
	 * we can't acknowledge from interrupt context since the i2c
	 * bus controller may sleep, so we just disable the interrupt
	 * here and handle the acknowledge using delayed work.
	 */

	disable_irq_nosync(irq);
	schedule_delayed_work(&priv->work, HZ / 20);

	return IRQ_HANDLED;
	return IRQ_HANDLED;
}
}



static int migor_ts_open(struct input_dev *dev)
static int migor_ts_open(struct input_dev *dev)
{
{
	struct migor_ts_priv *priv = input_get_drvdata(dev);
	struct migor_ts_priv *priv = input_get_drvdata(dev);
@@ -131,15 +123,6 @@ static void migor_ts_close(struct input_dev *dev)


	disable_irq(priv->irq);
	disable_irq(priv->irq);


	/* cancel pending work and wait for migor_ts_poscheck() to finish */
	if (cancel_delayed_work_sync(&priv->work)) {
		/*
		 * if migor_ts_poscheck was canceled we need to enable IRQ
		 * here to balance disable done in migor_ts_isr.
		 */
		enable_irq(priv->irq);
	}

	/* disable controller */
	/* disable controller */
	i2c_master_send(client, migor_ts_dis_seq, sizeof(migor_ts_dis_seq));
	i2c_master_send(client, migor_ts_dis_seq, sizeof(migor_ts_dis_seq));


@@ -186,14 +169,14 @@ static int migor_ts_probe(struct i2c_client *client,


	priv->client = client;
	priv->client = client;
	priv->input = input;
	priv->input = input;
	INIT_DELAYED_WORK(&priv->work, migor_ts_poscheck);
	priv->irq = client->irq;
	priv->irq = client->irq;


	error = input_register_device(input);
	error = input_register_device(input);
	if (error)
	if (error)
		goto err1;
		goto err1;


	error = request_irq(priv->irq, migor_ts_isr, IRQF_TRIGGER_LOW,
	error = request_threaded_irq(priv->irq, NULL, migor_ts_isr,
                                     IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                                     client->name, priv);
                                     client->name, priv);
	if (error) {
	if (error) {
		dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
		dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");