diff --git a/arch/arm/mach-at91/board-panelcard.c b/arch/arm/mach-at91/board-panelcard.c index 348a2e5..7db8972 100644 --- a/arch/arm/mach-at91/board-panelcard.c +++ b/arch/arm/mach-at91/board-panelcard.c @@ -249,6 +249,39 @@ static struct platform_device panelcard_flash = { .num_resources = 1, }; +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) +static int ads7843_pendown_state(void) +{ + return !at91_get_gpio_value(AT91_PIN_PA25); /* Touchscreen PENIRQ */ +} + +static struct ads7846_platform_data ads_info = { + .model = 7843, + .x_min = 190, + .x_max = 3880, + .y_min = 190, + .y_max = 3880, + .x_inverted = 1, + .y_inverted = 1, + .vref_delay_usecs = 100, + .x_plate_ohms = 1000, + .y_plate_ohms = 1000, + .pressure_max = 0, + .debounce_max = 1, + .debounce_rep = 5, + .debounce_tol = 8, + .get_pendown_state = ads7843_pendown_state, +}; + +static void __init ek_add_device_ts(void) +{ + at91_set_gpio_input(AT91_PIN_PA25, 1); /* External IRQ0, with pullup */ + at91_set_gpio_input(AT91_PIN_PA26, 1); /* Touchscreen BUSY signal */ +} +#else +static void __init ek_add_device_ts(void) {} +#endif + #if defined(CONFIG_RTC_DRV_AT91SAM926X) || defined(CONFIG_RTC_DRV_AT91SAM926X_MODULE) static struct at91_rtt_data rtt_data={0}; @@ -380,23 +413,19 @@ static void __init panelcard_add_w1(void) static void __init panelcard_add_w1(void) {} #endif +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) static struct spi_board_info panelcard_spi_devices[] = { - { /* User accessible spi - cs1 (1Mhz) */ - .modalias = "spidev", + { /* User accessible spi - cs1 */ + .modalias = "ads7846", .chip_select = 1, - .max_speed_hz = 1000 * 1000, - }, - { /* User accessible spi - cs2 (1MHz) */ - .modalias = "spidev", - .chip_select = 2, - .max_speed_hz = 1 * 1000 * 1000, - }, - { /* User accessible spi - cs3 (10MHz) */ - .modalias = "spidev", - .chip_select = 3, - .max_speed_hz = 10 * 1000 * 1000, + .max_speed_hz = 125000 * 4, + .bus_num = 1, + .irq = AT91_PIN_PA25, + .controller_data = AT91_PIN_PA24, + .platform_data = &ads_info, }, }; +#endif static void __init panelcard_board_init(void) { @@ -408,8 +437,12 @@ static void __init panelcard_board_init(void) at91_add_device_udc(&panelcard_udc_data); /* I2C */ at91_add_device_i2c(NULL, 0); + /* Touchscreen */ + ek_add_device_ts(); /* SPI */ - at91_add_device_spi(panelcard_spi_devices, 3); +#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) + at91_add_device_spi(panelcard_spi_devices, 1); +#endif /* DM9000 ethernet */ panelcard_add_device_dm9000(); /* MMC */ diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 1c9069c..44ef445 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -91,6 +91,9 @@ struct ads7846 { u16 x_plate_ohms; u16 pressure_max; + int x_inverted; + int y_inverted; + u8 read_x, read_y, read_z1, read_z2, pwrdown; u16 dummy; /* for the pwrdown read */ struct ts_event tc; @@ -564,6 +567,18 @@ static void ads7846_rx(void *ads) if (Rt) { struct input_dev *input = ts->input; + if(ts->x_inverted) + input_report_abs(input, ABS_X, 4095-x); + else + input_report_abs(input, ABS_X, x); + + if(ts->y_inverted) + input_report_abs(input, ABS_Y, 4095-y); + else + input_report_abs(input, ABS_Y, y); + + input_report_abs(input, ABS_PRESSURE, Rt); + input_sync(input); if (!ts->pendown) { input_report_key(input, BTN_TOUCH, 1); ts->pendown = 1; @@ -571,10 +586,6 @@ static void ads7846_rx(void *ads) dev_dbg(&ts->spi->dev, "DOWN\n"); #endif } - input_report_abs(input, ABS_X, x); - input_report_abs(input, ABS_Y, y); - input_report_abs(input, ABS_PRESSURE, Rt); - input_sync(input); #ifdef VERBOSE dev_dbg(&ts->spi->dev, "%4d/%4d/%4d\n", x, y, Rt); @@ -876,6 +887,9 @@ static int __devinit ads7846_probe(struct spi_device *spi) ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; ts->pressure_max = pdata->pressure_max ? : ~0; + ts->x_inverted = pdata->x_inverted; + ts->y_inverted = pdata->y_inverted; + if (pdata->filter != NULL) { if (pdata->filter_init != NULL) { err = pdata->filter_init(pdata, &ts->filter_data); diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index 3387e44..2080f13 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -23,6 +23,8 @@ struct ads7846_platform_data { u16 y_min, y_max; u16 pressure_min, pressure_max; + int x_inverted, y_inverted; + u16 debounce_max; /* max number of additional readings * per sample */ u16 debounce_tol; /* tolerance used for filtering */