blob: 26136ce59b5507a1b28b32849ef6475d4d6349d5 [file] [log] [blame]
Karl Kurbjun7b97fe22007-09-20 04:46:41 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
Karl Kurbjunbebbac82007-09-22 15:43:38 +00008 * $Id$
Karl Kurbjun7b97fe22007-09-20 04:46:41 +00009 *
10 * Copyright (C) 2007 by Karl Kurbjun
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Karl Kurbjun7b97fe22007-09-20 04:46:41 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
Jonathan Gordone1089642007-09-30 11:15:14 +000022/* this file also handles the touch screen driver interface */
23
Karl Kurbjun7b97fe22007-09-20 04:46:41 +000024#include "config.h"
25#include "cpu.h"
26#include "system.h"
27#include "button.h"
28#include "kernel.h"
29#include "backlight.h"
30#include "adc.h"
31#include "system.h"
32#include "backlight-target.h"
Jonathan Gordon300f64c2007-09-20 09:08:40 +000033#include "uart-target.h"
Jonathan Gordone1089642007-09-30 11:15:14 +000034#include "tsc2100.h"
Karl Kurbjunb7a4e102007-10-13 14:53:34 +000035#include "string.h"
Karl Kurbjun7b97fe22007-09-20 04:46:41 +000036
Jonathan Gordon376429d2007-09-20 08:42:06 +000037#define BUTTON_TIMEOUT 50
Jonathan Gordonc5d22bc2007-09-21 02:05:02 +000038
39#define BUTTON_START_BYTE 0xF0
40#define BUTTON_START_BYTE2 0xF4 /* not sure why, but sometimes you get F0 or F4, */
41 /* but always the same one for the session? */
Jonathan Gordone1089642007-09-30 11:15:14 +000042static short last_x, last_y, last_z1, last_z2; /* for the touch screen */
Jonathan Gordon12d1ff92007-10-22 07:01:59 +000043static bool touch_available = false;
Jonathan Gordon274c2b82007-10-01 07:52:39 +000044
Jonathan Gordon5b5a6262008-04-15 10:35:11 +000045static enum touchpad_mode current_mode = TOUCHPAD_POINT;
46static int touchpad_buttons[3][3] = {
47 {BUTTON_TOPLEFT, BUTTON_TOPMIDDLE, BUTTON_TOPRIGHT},
48 {BUTTON_MIDLEFT, BUTTON_CENTER, BUTTON_MIDRIGHT},
49 {BUTTON_BOTTOMLEFT, BUTTON_BOTTOMMIDDLE, BUTTON_BOTTOMRIGHT},
50};
51
52void touchpad_set_mode(enum touchpad_mode mode)
53{
54 current_mode = mode;
55}
56enum touchpad_mode touchpad_get_mode(void)
57{
58 return current_mode;
59}
60
Jonathan Gordon274c2b82007-10-01 07:52:39 +000061static struct touch_calibration_point topleft, bottomright;
Karl Kurbjund3d0b262007-11-15 06:44:35 +000062
Jonathan Gordond8667df2007-10-18 12:15:56 +000063/* Jd's tests.. These will hopefully work for everyone so we dont have to
Karl Kurbjun59a28622007-11-11 03:31:24 +000064 * create a calibration screen.
65 * Portait:
66 * (0,0) = 200, 3900
67 * (480,640) = 3880, 270
68 * Landscape:
69 * (0,0) = 200, 270
70 * (640,480) = 3880, 3900
Jonathan Gordond8667df2007-10-18 12:15:56 +000071*/
Karl Kurbjun59a28622007-11-11 03:31:24 +000072
Jonathan Gordon274c2b82007-10-01 07:52:39 +000073static int touch_to_pixels(short val_x, short val_y)
74{
75 short x,y;
Karl Kurbjun59a28622007-11-11 03:31:24 +000076
Jonathan Gordonc741ecc2008-04-29 01:09:39 +000077#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
Karl Kurbjun59a28622007-11-11 03:31:24 +000078 x=val_x;
79 y=val_y;
80#else
81 x=val_y;
82 y=val_x;
83#endif
84
Karl Kurbjun59a28622007-11-11 03:31:24 +000085 x = (x-topleft.val_x)*(bottomright.px_x - topleft.px_x) / (bottomright.val_x - topleft.val_x) + topleft.px_x;
86 y = (y-topleft.val_y)*(bottomright.px_y - topleft.px_y) / (bottomright.val_y - topleft.val_y) + topleft.px_y;
87
Jonathan Gordon274c2b82007-10-01 07:52:39 +000088 if (x < 0)
89 x = 0;
Karl Kurbjund3d0b262007-11-15 06:44:35 +000090 else if (x>=LCD_WIDTH)
91 x=LCD_WIDTH-1;
92
Jonathan Gordon274c2b82007-10-01 07:52:39 +000093 if (y < 0)
94 y = 0;
Karl Kurbjund3d0b262007-11-15 06:44:35 +000095 else if (y>=LCD_HEIGHT)
96 y=LCD_HEIGHT-1;
97
98
Jonathan Gordon274c2b82007-10-01 07:52:39 +000099 return (x<<16)|y;
100}
Karl Kurbjunfa1a38e2007-10-18 05:14:10 +0000101
Karl Kurbjun7b97fe22007-09-20 04:46:41 +0000102void button_init_device(void)
103{
Jonathan Gordon12d1ff92007-10-22 07:01:59 +0000104 touch_available = false;
Jonathan Gordon376429d2007-09-20 08:42:06 +0000105 /* GIO is the power button, set as input */
Jonathan Gordona5e788f2007-09-30 08:18:46 +0000106 IO_GIO_DIR0 |= 0x01;
Karl Kurbjun59a28622007-11-11 03:31:24 +0000107
Jonathan Gordonc741ecc2008-04-29 01:09:39 +0000108#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
Karl Kurbjun59a28622007-11-11 03:31:24 +0000109 topleft.val_x = 200;
110 topleft.val_y = 3900;
Jonathan Gordone1089642007-09-30 11:15:14 +0000111
Karl Kurbjun59a28622007-11-11 03:31:24 +0000112 bottomright.val_x = 3880;
113 bottomright.val_y = 270;
Jonathan Gordon28dfb542007-11-11 04:48:33 +0000114#else
Karl Kurbjun59a28622007-11-11 03:31:24 +0000115 topleft.val_x = 270;
116 topleft.val_y = 200;
117
118 bottomright.val_x = 3900;
119 bottomright.val_y = 3880;
120#endif
121
Karl Kurbjund3d0b262007-11-15 06:44:35 +0000122 topleft.px_x = 0;
Karl Kurbjun59a28622007-11-11 03:31:24 +0000123 topleft.px_y = 0;
Karl Kurbjund3d0b262007-11-15 06:44:35 +0000124
125 bottomright.px_x = LCD_WIDTH;
Karl Kurbjun59a28622007-11-11 03:31:24 +0000126 bottomright.px_y = LCD_HEIGHT;
127
Jonathan Gordone1089642007-09-30 11:15:14 +0000128 /* Enable the touchscreen interrupt */
129 IO_INTC_EINT2 |= (1<<3); /* IRQ_GIO14 */
130#if 0
131 tsc2100_writereg(TSADC_PAGE, TSADC_ADDRESS,
132 TSADC_PSTCM|
133 (0x2<<TSADC_ADSCM_SHIFT)| /* scan x,y,z1,z2 */
134 (0x1<<TSADC_RESOL_SHIFT) /* 8 bit resolution */
135 );
136 /* doesnt work for some reason...
137 setting to 8bit would probably be better than the 12bit currently */
138#endif
Karl Kurbjun7b97fe22007-09-20 04:46:41 +0000139}
140
141inline bool button_hold(void)
142{
143 return false;
144}
Jonathan Gordond8667df2007-10-18 12:15:56 +0000145
Karl Kurbjunfa1a38e2007-10-18 05:14:10 +0000146static void remote_heartbeat(void)
147{
148 char data[5] = {0x11, 0x30, 0x11^0x30, 0x11+0x30, '\0'};
Karl Kurbjund3d0b262007-11-15 06:44:35 +0000149 uart1_puts(data, 5);
Karl Kurbjunfa1a38e2007-10-18 05:14:10 +0000150}
151
Jonathan Gordon12d1ff92007-10-22 07:01:59 +0000152#define TOUCH_MARGIN 8
Karl Kurbjund3d0b262007-11-15 06:44:35 +0000153char r_buffer[5];
154int r_button = BUTTON_NONE;
Jonathan Gordon12d1ff92007-10-22 07:01:59 +0000155int button_read_device(int *data)
Karl Kurbjun7b97fe22007-09-20 04:46:41 +0000156{
Karl Kurbjund3d0b262007-11-15 06:44:35 +0000157 int retval, calbuf;
Karl Kurbjund3c0a7f2007-11-10 22:12:54 +0000158 static int oldbutton = BUTTON_NONE;
Karl Kurbjund3d0b262007-11-15 06:44:35 +0000159
160 r_button=BUTTON_NONE;
Jonathan Gordon12d1ff92007-10-22 07:01:59 +0000161 *data = 0;
Karl Kurbjund3c0a7f2007-11-10 22:12:54 +0000162
Jonathan Gordon12d1ff92007-10-22 07:01:59 +0000163 if (touch_available)
164 {
165 short x,y;
166 static long last_touch = 0;
167 bool send_touch = false;
168 tsc2100_read_values(&x, &y, &last_z1, &last_z2);
169 if (TIME_BEFORE(last_touch + HZ/5, current_tick))
170 {
171 if ((x > last_x + TOUCH_MARGIN) ||
172 (x < last_x - TOUCH_MARGIN) ||
173 (y > last_y + TOUCH_MARGIN) ||
174 (y < last_y - TOUCH_MARGIN))
175 {
176 send_touch = true;
177 }
178 }
179 else
180 send_touch = true;
181 if (send_touch)
182 {
183 last_x = x;
184 last_y = y;
185 *data = touch_to_pixels(x, y);
Jonathan Gordon5b5a6262008-04-15 10:35:11 +0000186 switch (current_mode)
187 {
188 case TOUCHPAD_POINT:
189 r_button |= BUTTON_TOUCHPAD;
190 break;
191 case TOUCHPAD_BUTTON:
192 {
193 int px_x = ((*data&0xffff0000)>>16), px_y = ((*data&0x0000ffff));
194 r_button |= touchpad_buttons[px_y/(LCD_HEIGHT/3)][px_x/(LCD_WIDTH/3)];
195 oldbutton = r_button;
196 break;
197 }
198 }
Jonathan Gordon12d1ff92007-10-22 07:01:59 +0000199 }
200 last_touch = current_tick;
201 touch_available = false;
202 }
Karl Kurbjunfa1a38e2007-10-18 05:14:10 +0000203 remote_heartbeat();
Karl Kurbjund3c0a7f2007-11-10 22:12:54 +0000204
205 if ((IO_GIO_BITSET0&0x01) == 0)
Karl Kurbjund3d0b262007-11-15 06:44:35 +0000206 {
207 r_button |= BUTTON_POWER;
208 oldbutton=r_button;
209 }
Karl Kurbjund3c0a7f2007-11-10 22:12:54 +0000210
Karl Kurbjund3d0b262007-11-15 06:44:35 +0000211 retval=uart1_gets_queue(r_buffer, 5);
Karl Kurbjund3c0a7f2007-11-10 22:12:54 +0000212 do
Jonathan Gordon376429d2007-09-20 08:42:06 +0000213 {
Karl Kurbjund3d0b262007-11-15 06:44:35 +0000214 for(calbuf=0;calbuf<4;calbuf++)
215 {
216 if((r_buffer[calbuf]&0xF0)==0xF0 && (r_buffer[calbuf+1]&0xF0)!=0xF0)
217 break;
218 }
219 calbuf++;
220 if(calbuf==5)
221 calbuf=0;
Karl Kurbjund3c0a7f2007-11-10 22:12:54 +0000222 if(retval>=0)
Jonathan Gordon376429d2007-09-20 08:42:06 +0000223 {
Karl Kurbjund3d0b262007-11-15 06:44:35 +0000224 r_button |= r_buffer[calbuf];
225 oldbutton=r_button;
Karl Kurbjunfa1a38e2007-10-18 05:14:10 +0000226 }
Karl Kurbjund3c0a7f2007-11-10 22:12:54 +0000227 else
Karl Kurbjunfa1a38e2007-10-18 05:14:10 +0000228 {
Karl Kurbjund3d0b262007-11-15 06:44:35 +0000229 r_button=oldbutton;
Jonathan Gordon376429d2007-09-20 08:42:06 +0000230 }
Karl Kurbjund3d0b262007-11-15 06:44:35 +0000231 } while((retval=uart1_gets_queue(r_buffer, 5))>=5);
Karl Kurbjund3c0a7f2007-11-10 22:12:54 +0000232
Karl Kurbjund3d0b262007-11-15 06:44:35 +0000233 return r_button;
Karl Kurbjun7b97fe22007-09-20 04:46:41 +0000234}
Jonathan Gordon12d1ff92007-10-22 07:01:59 +0000235
236/* Touchpad data available interupt */
Jonathan Gordon4c06ad62007-10-22 15:28:40 +0000237void read_battery_inputs(void);
Jonathan Gordone1089642007-09-30 11:15:14 +0000238void GIO14(void)
239{
Jonathan Gordon4c06ad62007-10-22 15:28:40 +0000240 short tsadc = tsc2100_readreg(TSADC_PAGE, TSADC_ADDRESS);
241 short adscm = (tsadc&TSADC_ADSCM_MASK)>>TSADC_ADSCM_SHIFT;
242 switch (adscm)
243 {
244 case 1:
245 case 2:
246 touch_available = true;
247 break;
248 case 0xb:
249 read_battery_inputs();
250 break;
251 }
Jonathan Gordon5b5a6262008-04-15 10:35:11 +0000252 //touch_available = true;
Jonathan Gordon12d1ff92007-10-22 07:01:59 +0000253 IO_INTC_IRQ2 = (1<<3); /* IRQ_GIO14 == 35 */
Jonathan Gordone1089642007-09-30 11:15:14 +0000254}