2 * ts_osk.c - touchscreen support for OMAP OSK board
4 * Copyright 2002 MontaVista Software Inc.
5 * Author: MontaVista Software, Inc.
6 * stevel@mvista.com or source@mvista.com
8 * The touchscreen hardware on the OSK uses OMAP5912 uWire interface,
9 * GPIO4 (/PENIRQ) and GPIO6 (BUSY) to connect to an ADS7846
10 * touch screen controller. GPIO6 doesn't seem to be necessary here.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <linux/input.h>
28 #include <linux/device.h>
29 #include <asm/arch/mux.h>
30 #include <asm/arch/gpio.h>
31 #include <asm/mach-types.h>
33 #include "../drivers/ssi/omap-uwire.h"
38 // /PENIRQ on GPIO4 on OSK
39 #define PEN_IRQ OMAP_GPIO_IRQ(4)
41 // ADS7846 is on OSK uWire CS 0
42 #define ADS7846_UWIRE_CS 0
43 #define UWIRE_LEAVE_CS 1
45 #define X_PLATE_OHMS 419
46 #define Y_PLATE_OHMS 486
48 static int osk_ts_penup(void);
49 static int osk_ts_probe(struct omap_ts_t *ts);
50 static void osk_ts_read(u16 * data);
51 static void osk_ts_enable(void);
52 static void osk_ts_disable(void);
54 static void osk_ts_remove(void);
57 struct ts_device osk_ts = {
58 .probe = osk_ts_probe,
60 .enable = osk_ts_enable,
61 .disable = osk_ts_disable,
62 .remove = __exit_p(osk_ts_remove),
63 .penup = osk_ts_penup,
66 static u16 ads7846_do(u8 cmd)
70 // send the command to the ADS7846, leave CS active after this
71 omap_uwire_data_transfer(ADS7846_UWIRE_CS, cmd, 8, 0, NULL, UWIRE_LEAVE_CS);
73 // now read returned data
74 omap_uwire_data_transfer(ADS7846_UWIRE_CS, 0, 0, 16, &val, !UWIRE_LEAVE_CS);
79 static int osk_ts_penup(void)
81 return (omap_get_gpio_datain(4));
84 static int __init osk_ts_probe(struct omap_ts_t *ts)
86 #ifdef CONFIG_OMAP_OSK_MISTRAL
87 if (!machine_is_omap_osk())
90 /* Configure GPIO4 (pin M17 ZDY) as /PENIRQ interrupt input */
91 omap_cfg_reg(P20_1610_GPIO4);
93 omap_set_gpio_direction(4, 1);
94 set_irq_type(OMAP_GPIO_IRQ(4), IRQT_FALLING);
98 /* Configure uWire interface. ADS7846 is on CS0 */
99 omap_uwire_configure_mode(ADS7846_UWIRE_CS, UWIRE_READ_RISING_EDGE |
100 UWIRE_WRITE_RISING_EDGE |
101 UWIRE_CS_ACTIVE_LOW |
104 /* FIXME verify there's really a Mistral board:
105 * see if the AD7846 chip responds.
108 /* NOTE: no VREF; must ignore the temp, VBAT, and AUX sensors */
115 static void osk_ts_read(u16 *data)
119 data[0] = ads7846_do(MEASURE_12BIT_X);
120 data[1] = ads7846_do(MEASURE_12BIT_Y);
121 data[2] = ads7846_do(MEASURE_12BIT_Z1);
122 data[3] = ads7846_do(MEASURE_12BIT_Z2);
124 // Calculate touch pressure resistance
126 Rt = (X_PLATE_OHMS * (u32)data[0] *
127 ((u32)data[3] - (u32)data[2])) / (u32)data[2];
129 Rt = (Rt + 2048) >> 12; // round up to nearest ohm
133 * Raw OSK touchscreen data values are between ~4000 and
134 * ~60000. This seems to be to large for calibration
135 * systems (e.g. tslib). Make the values smaller.
137 data[0] = data[0] >> 4;
138 data[1] = data[1] >> 4;
143 static void osk_ts_enable(void)
148 static void osk_ts_disable(void)
154 static void __exit osk_ts_remove(void)