Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 250527
b: refs/heads/master
c: b73077e
h: refs/heads/master
i:
  250525: 81ccda4
  250523: fc01b45
  250519: 369d34b
  250511: 3f52c26
  250495: 768805a
v: v3
  • Loading branch information
Dmitry Torokhov committed May 24, 2011
1 parent 54cc491 commit f213aaa
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9d2e173644bb5c42ff1b280fbdda3f195a7cf1f7
refs/heads/master: b73077eb03f510a84b102fb97640e595a958403c
13 changes: 10 additions & 3 deletions trunk/drivers/input/touchscreen/ads7846.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,17 +282,24 @@ struct ser_req {
u8 command;
u8 ref_off;
u16 scratch;
__be16 sample;
struct spi_message msg;
struct spi_transfer xfer[6];
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
*/
__be16 sample ____cacheline_aligned;
};

struct ads7845_ser_req {
u8 command[3];
u8 pwrdown[3];
u8 sample[3];
struct spi_message msg;
struct spi_transfer xfer[2];
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
*/
u8 sample[3] ____cacheline_aligned;
};

static int ads7846_read12_ser(struct device *dev, unsigned command)
Expand Down
75 changes: 64 additions & 11 deletions trunk/drivers/input/touchscreen/wm831x-ts.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,23 @@ struct wm831x_ts {
unsigned int pd_irq;
bool pressure;
bool pen_down;
struct work_struct pd_data_work;
};

static void wm831x_pd_data_work(struct work_struct *work)
{
struct wm831x_ts *wm831x_ts =
container_of(work, struct wm831x_ts, pd_data_work);

if (wm831x_ts->pen_down) {
enable_irq(wm831x_ts->data_irq);
dev_dbg(wm831x_ts->wm831x->dev, "IRQ PD->DATA done\n");
} else {
enable_irq(wm831x_ts->pd_irq);
dev_dbg(wm831x_ts->wm831x->dev, "IRQ DATA->PD done\n");
}
}

static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data)
{
struct wm831x_ts *wm831x_ts = irq_data;
Expand Down Expand Up @@ -110,6 +125,9 @@ static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data)
}

if (!wm831x_ts->pen_down) {
/* Switch from data to pen down */
dev_dbg(wm831x->dev, "IRQ DATA->PD\n");

disable_irq_nosync(wm831x_ts->data_irq);

/* Don't need data any more */
Expand All @@ -128,6 +146,10 @@ static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data)
ABS_PRESSURE, 0);

input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 0);

schedule_work(&wm831x_ts->pd_data_work);
} else {
input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 1);
}

input_sync(wm831x_ts->input_dev);
Expand All @@ -141,6 +163,11 @@ static irqreturn_t wm831x_ts_pen_down_irq(int irq, void *irq_data)
struct wm831x *wm831x = wm831x_ts->wm831x;
int ena = 0;

if (wm831x_ts->pen_down)
return IRQ_HANDLED;

disable_irq_nosync(wm831x_ts->pd_irq);

/* Start collecting data */
if (wm831x_ts->pressure)
ena |= WM831X_TCH_Z_ENA;
Expand All @@ -149,14 +176,14 @@ static irqreturn_t wm831x_ts_pen_down_irq(int irq, void *irq_data)
WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA,
WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | ena);

input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 1);
input_sync(wm831x_ts->input_dev);

wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1,
WM831X_TCHPD_EINT, WM831X_TCHPD_EINT);

wm831x_ts->pen_down = true;
enable_irq(wm831x_ts->data_irq);

/* Switch from pen down to data */
dev_dbg(wm831x->dev, "IRQ PD->DATA\n");
schedule_work(&wm831x_ts->pd_data_work);

return IRQ_HANDLED;
}
Expand All @@ -182,13 +209,28 @@ static void wm831x_ts_input_close(struct input_dev *idev)
struct wm831x_ts *wm831x_ts = input_get_drvdata(idev);
struct wm831x *wm831x = wm831x_ts->wm831x;

/* Shut the controller down, disabling all other functionality too */
wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
WM831X_TCH_ENA | WM831X_TCH_CVT_ENA |
WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA |
WM831X_TCH_Z_ENA, 0);
WM831X_TCH_ENA | WM831X_TCH_X_ENA |
WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, 0);

if (wm831x_ts->pen_down)
/* Make sure any pending IRQs are done, the above will prevent
* new ones firing.
*/
synchronize_irq(wm831x_ts->data_irq);
synchronize_irq(wm831x_ts->pd_irq);

/* Make sure the IRQ completion work is quiesced */
flush_work_sync(&wm831x_ts->pd_data_work);

/* If we ended up with the pen down then make sure we revert back
* to pen detection state for the next time we start up.
*/
if (wm831x_ts->pen_down) {
disable_irq(wm831x_ts->data_irq);
enable_irq(wm831x_ts->pd_irq);
wm831x_ts->pen_down = false;
}
}

static __devinit int wm831x_ts_probe(struct platform_device *pdev)
Expand All @@ -198,7 +240,7 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev)
struct wm831x_pdata *core_pdata = dev_get_platdata(pdev->dev.parent);
struct wm831x_touch_pdata *pdata = NULL;
struct input_dev *input_dev;
int error;
int error, irqf;

if (core_pdata)
pdata = core_pdata->touch;
Expand All @@ -212,6 +254,7 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev)

wm831x_ts->wm831x = wm831x;
wm831x_ts->input_dev = input_dev;
INIT_WORK(&wm831x_ts->pd_data_work, wm831x_pd_data_work);

/*
* If we have a direct IRQ use it, otherwise use the interrupt
Expand Down Expand Up @@ -270,9 +313,14 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev)
wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1,
WM831X_TCH_RATE_MASK, 6);

if (pdata && pdata->data_irqf)
irqf = pdata->data_irqf;
else
irqf = IRQF_TRIGGER_HIGH;

error = request_threaded_irq(wm831x_ts->data_irq,
NULL, wm831x_ts_data_irq,
IRQF_ONESHOT,
irqf | IRQF_ONESHOT,
"Touchscreen data", wm831x_ts);
if (error) {
dev_err(&pdev->dev, "Failed to request data IRQ %d: %d\n",
Expand All @@ -281,9 +329,14 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev)
}
disable_irq(wm831x_ts->data_irq);

if (pdata && pdata->pd_irqf)
irqf = pdata->pd_irqf;
else
irqf = IRQF_TRIGGER_HIGH;

error = request_threaded_irq(wm831x_ts->pd_irq,
NULL, wm831x_ts_pen_down_irq,
IRQF_ONESHOT,
irqf | IRQF_ONESHOT,
"Touchscreen pen down", wm831x_ts);
if (error) {
dev_err(&pdev->dev, "Failed to request pen down IRQ %d: %d\n",
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/mfd/wm831x/pdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ struct wm831x_touch_pdata {
int rpu; /** Pen down sensitivity resistor divider */
int pressure; /** Report pressure (boolean) */
unsigned int data_irq; /** Touch data ready IRQ */
int data_irqf; /** IRQ flags for data ready IRQ */
unsigned int pd_irq; /** Touch pendown detect IRQ */
int pd_irqf; /** IRQ flags for pen down IRQ */
};

enum wm831x_watchdog_action {
Expand Down

0 comments on commit f213aaa

Please sign in to comment.