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

Commit 17532989 authored by Pavel Machek's avatar Pavel Machek Committed by Russell King
Browse files

[ARM] Sharp sl-5500 touchscreen support



This adds support for sharp zaurus sl-5500 touchscreen.  It introduces
some not-too-nice ifs, but I guess copying whole ucb1x00-ts.c would be
bad idea...

Signed-off-by: default avatarPavel Machek <pavel@suse.cz>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 5ecdb02c
Loading
Loading
Loading
Loading
+53 −21
Original line number Diff line number Diff line
@@ -32,9 +32,12 @@
#include <linux/suspend.h>
#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/delay.h>

#include <asm/dma.h>
#include <asm/semaphore.h>
#include <asm/arch/collie.h>
#include <asm/mach-types.h>

#include "ucb1x00.h"

@@ -85,6 +88,16 @@ static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
 */
static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
{
	if (machine_is_collie()) {
		ucb1x00_io_write(ts->ucb, COLLIE_TC35143_GPIO_TBL_CHK, 0);
		ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
				  UCB_TS_CR_TSPX_POW | UCB_TS_CR_TSMX_POW |
				  UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);

		udelay(55);

		return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_AD2, ts->adcsync);
	} else {
		ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
				  UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
				  UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
@@ -92,6 +105,7 @@ static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)

		return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
	}
}

/*
 * Switch to X position mode and measure Y plate.  We switch the plate
@@ -101,12 +115,16 @@ static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
 */
static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
{
	if (machine_is_collie())
		ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
	else {
		ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
				  UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
				  UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
		ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
				  UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
				  UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
	}
	ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
			UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
			UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
@@ -124,12 +142,17 @@ static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
 */
static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
{
	if (machine_is_collie())
		ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
	else {
		ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
				  UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
				  UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
		ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
				  UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
				  UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
	}

	ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
			UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
			UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
@@ -163,6 +186,15 @@ static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
	return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
}

static inline int ucb1x00_ts_pen_down(struct ucb1x00_ts *ts)
{
	unsigned int val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
	if (machine_is_collie())
		return (!(val & (UCB_TS_CR_TSPX_LOW)));
	else
		return (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW));
}

/*
 * This is a RT kernel thread that handles the ADC accesses
 * (mainly so we can use semaphores in the UCB1200 core code
@@ -186,7 +218,7 @@ static int ucb1x00_thread(void *_ts)

	add_wait_queue(&ts->irq_wait, &wait);
	while (!kthread_should_stop()) {
		unsigned int x, y, p, val;
		unsigned int x, y, p;
		signed long timeout;

		ts->restart = 0;
@@ -206,12 +238,12 @@ static int ucb1x00_thread(void *_ts)
		msleep(10);

		ucb1x00_enable(ts->ucb);
		val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);

		if (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)) {

		if (ucb1x00_ts_pen_down(ts)) {
			set_task_state(tsk, TASK_INTERRUPTIBLE);

			ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
			ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING);
			ucb1x00_disable(ts->ucb);

			/*