Loading drivers/input/touchscreen/migor_ts.c +24 −41 Original line number Original line Diff line number Diff line Loading @@ -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; }; }; Loading @@ -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 */ Loading @@ -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); Loading @@ -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)); Loading Loading @@ -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"); Loading Loading
drivers/input/touchscreen/migor_ts.c +24 −41 Original line number Original line Diff line number Diff line Loading @@ -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; }; }; Loading @@ -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 */ Loading @@ -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); Loading @@ -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)); Loading Loading @@ -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"); Loading