1
/* Id: citron.c,v 1.8 2001/03/28 08:24:38 pk Exp $
2
* Copyright (c) 1998 Metro Link Incorporated
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, cpy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
11
* The above copyright notice and this permission notice shall be included in
12
* all copies or substantial portions of the Software.
14
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17
* THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
* Except as contained in this notice, the name of the Metro Link shall not be
23
* used in advertising or otherwise to promote the sale, use or other dealings
24
* in this Software without prior written authorization from Metro Link.
28
/* $XFree86: xc/programs/Xserver/hw/xfree86/input/citron/citron.c,v 1.7 2001/07/02 17:29:20 dawes Exp $ */
31
* Based, in part, on code with the following copyright notice:
33
* Copyright 1999-2001 by Thomas Thanner, Citron GmbH, Germany. <support@citron.de>
34
* Copyright 1999-2001 by Peter Kunzmann, Citron GmbH, Germany. <kunzmann@citron.de>
36
* Permission to use, copy, modify, distribute, and sell this software and its
37
* documentation for any purpose is hereby granted without fee, provided that
38
* the above copyright notice appear in all copies and that both that copyright
39
* notice and this permission notice appear in supporting documentation, and that
40
* the name of Thomas Thanner and Citron GmbH not be used in advertising or
41
* publicity pertaining to distribution of the software without specific, written
42
* prior permission. Thomas Thanner and Citron GmbH makes no representations about
43
* the suitability of this software for any purpose. It is provided "as is"
44
* without express or implied warranty.
46
* THOMAS THANNER AND CITRON GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
47
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
48
* IN NO EVENT SHALL THOMAS THANNER OR CITRON GMBH BE LIABLE FOR ANY SPECIAL,
49
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RSULTING FROM
50
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
51
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
52
* PERFORMANCE OF THIS SOFTWARE.
56
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
57
* Citron specific extensions:
59
* 1) Configuration file entries:
60
* a) "SleepTime" Touch idle time in seconds before sleep mode
61
* (reduced scanning) is entered.
62
* 0 = immediately; 65535=never;
64
* b) "ActivePWM" PWM duty cycle during regular operation.
66
* c) "SleepPWM" PWM duty cycle during sleep mode.
68
* d) "ClickMode" Button click emulation mode;
73
* 5 = Z-Press Exit Mode
76
* 2) Additional modes in SetMode() function:
77
* (These modes are only activated if the CIT_MODE_EXT macro is defined
78
* at compile time. Until now the mode values are not defined, yet)
79
* a) ClickMode_Enter set the button click emulation mode to 1
80
* b) ClickMode_Dual set the button click emulation mode to 2
81
* c) ClickMode_DualExit set the button click emulation mode to 3
82
* d) ClickMode_ZPress set the button click emulation mode to 4
83
* e) ClickMode_ZPressExit set the button click emulation mode to 5
85
*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
87
---------------------------------------------------------------------------
90
Ver Date Description of changes Name
91
---------------------------------------------------------------------------
92
2.03 17.09.00 Reconnect when getting breaks changed, changes
93
when powering off the system and reconnecting
94
parser for commands from "xcit" added
95
"cit_ParseCommand" to set the variables not
96
only on the touch side but also in the priv rec pk
97
2.04 19.10.00 reconnect enhanced pk
98
2.05 27.02.01 QueryHardware enhanced, connection faster pk
99
2.06 15.03.01 cit_SetBlockDuration added, cit_Flush modified pk
100
2.07 16.03.01 The problem that the touch didn't connect to the
101
X-server was a hardware problem
102
with the winbond chip (interrupt was dead after
103
receiving spurious characters when the touch screen
104
is switched on). The SIO has to be reinitialized to
105
get rid of that problem. pk
106
2.08 20.03.01 if cit_GetPacket has an overrun
107
cit_ReinitSerial has to be called, Vmin set to "1"
108
cit_SuperVisionTimer, cit_SetEnterCount added
109
debuglevel, entercount(z) from external now poss.
110
enter_touched not reset by coord_exit pk
111
2.09 25.03.01 enter_touched also reset by press_exit, a new
112
command (SetPWMFreq) for backlight dimming added pk
113
============================================================================
120
#define INITT 0 /* Initialisation of touch in first loop */
123
#define CITOUCH_VERSION 0x209
124
char version[]="Touch Driver V2.09 (c) 1999-2001 Citron GmbH";
126
#define CITOUCH_VERSION_MAJOR ((CITOUCH_VERSION >> 8) & 0xf)
127
#define CITOUCH_VERSION_MINOR ((CITOUCH_VERSION >> 4) & 0xf)
128
#define CITOUCH_VERSION_PATCH ((CITOUCH_VERSION >> 0) & 0xf)
131
/*****************************************************************************
133
****************************************************************************/
137
#define NEED_XF86_TYPES
138
#include "xf86_ansic.h"
139
#include "xf86_OSproc.h"
140
#include "xf86Xinput.h"
142
#include "exevents.h" /* Needed for InitValuator/Proximity stuff*/
145
/* #define CIT_TIM */ /* Enable timer */
146
#define CIT_BEEP /* enable beep feature */
148
/*****************************************************************************
150
****************************************************************************/
153
/*****************************************************************************
154
* Variables without includable headers
155
****************************************************************************/
157
/*****************************************************************************
159
****************************************************************************/
160
#define CIT_DEF_MIN_X 0
161
#define CIT_DEF_MAX_X 0xFFFF
162
#define CIT_DEF_MIN_Y 0
163
#define CIT_DEF_MAX_Y 0xFFFF
165
#define CIT_BUFFER_SIZE 1024
169
/******************************************************************************
171
*****************************************************************************/
179
static int debug_level = 0;
182
debug is always on, because we can set the debug-level
183
in XF86Config (Option DebugLevel)
188
#define DBG(lvl, f) {if ((lvl) <= debug_level) f;}
193
/* Debugging levels for various routines */
194
#define PP 5 /* cit_ProcessPacket */
195
#define RI 6 /* cit_ReadInput */
196
#define GP 6 /* cit_GetPacket */
197
#define DDS 5 /* DDS package */
198
#define DC 5 /* cit_DriverComm */
204
err = xf86WaitForInput(-1, ((t) * 1000)); \
206
ErrorF("Citron select error\n"); \
211
timeout.tv_sec = 0; \
212
timeout.tv_usec = (t) * 1000; \
213
SYSCALL(err = select(0, NULL, NULL, NULL, &timeout)); \
215
ErrorF("Citron select error : %s\n", strerror(errno)); \
223
/*****************************************************************************
225
****************************************************************************/
228
static InputInfoPtr CitronPreInit(InputDriverPtr drv, IDevPtr dev, int flags);
231
InputDriverRec CITRON = {
236
/*CitronUnInit*/ NULL,
245
***************************************************************************
247
* Dynamic loading functions
249
***************************************************************************
253
static XF86ModuleVersionInfo VersionRec =
255
"citron", /* name of module */
256
MODULEVENDORSTRING, /* vendor specific string */
259
XF86_VERSION_CURRENT, /* Current XFree version */
260
CITOUCH_VERSION_MAJOR, /* Module-specific major version */
261
CITOUCH_VERSION_MINOR, /* Module-specific minor version */
262
CITOUCH_VERSION_PATCH, /* Module-specific patch level */
266
{0, 0, 0, 0} /* signature of the version info structure */
270
/* ************************************************************************
273
* called when the module subsection is found in XF86Config
275
* ************************************************************************/
278
SetupProc( pointer module,
283
/* xf86LoaderReqSymLists(reqSymbols, NULL); */
284
xf86AddInputDriver(&CITRON, module, 0);
285
DBG(5, ErrorF ("%sSetupProc called\n", CI_INFO));
290
/*****************************************************************************
292
****************************************************************************/
294
TearDownProc (pointer p)
296
DBG(5, ErrorF ("%sTearDownProc Called\n", CI_INFO));
300
XF86ModuleData citronModuleData = { &VersionRec, SetupProc, TearDownProc};
302
#endif /* XFree86LOADER */
309
* Be sure to set vmin appropriately for your device's protocol. You want to
310
* read a full packet before returning
312
static const char *default_options[] =
320
In non-canonical input processing mode, input is not assembled into
321
lines and input processing (erase, kill, delete, etc.) does not occur.
322
Two parameters control the behavior of this mode: c_cc[VTIME] sets the
323
character timer, and c_cc[VMIN] sets the minimum number of characters
324
to receive before satisfying the read.
326
If MIN > 0 and TIME = 0, MIN sets the number of characters to receive
327
before the read is satisfied. As TIME is zero, the timer is not used.
329
If MIN = 0 and TIME > 0, TIME serves as a timeout value. The read will
330
be satisfied if a single character is read, or TIME is exceeded (t =
331
TIME *0.1 s). If TIME is exceeded, no character will be returned.
334
If MIN > 0 and TIME > 0, TIME serves as an inter-character timer. The
335
read will be satisfied if MIN characters are received, or the time
336
between two characters exceeds TIME. The timer is restarted every time
337
a character is received and only becomes active after the first
338
character has been received.
340
If MIN = 0 and TIME = 0, read will be satisfied immediately. The
341
number of characters currently available, or the number of characters
342
requested will be returned. According to Antonino (see contributions),
343
you could issue a fcntl(fd, F_SETFL, FNDELAY); before reading to get
346
By modifying newtio.c_cc[VTIME] and newtio.c_cc[VMIN] all modes
347
described above can be tested.
348
(Copied from serial-programming-howto)
352
/* Vmin was set to 3 (Three characters have to arrive until Read_Input is called).
353
I set it to 1 because of the winbond SIO (maybe the interrupt disappears after 1 character
354
and X waits for another two.
357
"Vmin", "1", /* blocking read until 1 chars received */
359
"FlowControl", "None",
364
/*****************************************************************************
365
* Function Definitions
366
****************************************************************************/
370
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
371
/* [xf86CitronFeedback] */
372
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
373
/* Online driver parameter change */
374
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
377
cit_SendtoTouch(DeviceIntPtr dev)
379
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
380
cit_PrivatePtr priv = (cit_PrivatePtr)(local->private);
382
unsigned char buf[MAX_BYTES_TO_TRANSFER*2+2];
384
DBG(DDS, ErrorF("%scit_SendtoTouch(numbytes=0x%02X, data[0]=%02x, data[1]=%02x, data[2]=%02x, data[3]=%02x, ...)\n", CI_INFO, priv->dds.numbytes,
385
priv->dds.data[0], priv->dds.data[1], priv->dds.data[2], priv->dds.data[3]));
388
buf[j++] = CTS_STX; /* transmit start of packet */
390
for(i=0; i<priv->dds.numbytes; i++)
392
if (priv->dds.data[i] >= CTS_CTRLMIN && priv->dds.data[i] <= CTS_CTRLMAX)
393
{ /* data has to be encoded */
395
buf[j++] = priv->dds.data[i] | CTS_ENCODE;
397
else buf[j++] = priv->dds.data[i];
399
buf[j++] = CTS_ETX; /* end of packet */
401
XisbWrite(priv->buffer, buf, j);
406
if(i%16 == 0) DBG(DDS, ErrorF("\n"));
407
DBG(DDS, ErrorF("%02x ",buf[i]));
411
DBG(DDS, ErrorF("\n"));
416
cit_ParseCommand(DeviceIntPtr dev)
418
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
419
cit_PrivatePtr priv = (cit_PrivatePtr)(local->private);
422
DBG(DDS, ErrorF("%scit_ParseCommand(numbytes=0x%02X, data= ", CI_INFO, priv->dds.numbytes));
424
for(i=0; i<priv->dds.numbytes; i++)
425
DBG(DDS, ErrorF("%02x ", priv->dds.data[i]));
427
DBG(DDS,ErrorF("\n"));
429
switch(priv->dds.data[0]&0xff)
432
priv->pwm_active = priv->dds.data[1];
433
priv->pwm_sleep = priv->dds.data[2];
434
DBG(DDS, ErrorF("%scit_ParseCommand(PWM Active:%d PWM Sleep:%d \n", CI_INFO, priv->pwm_active, priv->pwm_sleep));
438
priv->pwm_freq = (int)priv->dds.data[1] | (int)(priv->dds.data[2] << 8);
439
DBG(DDS, ErrorF("%scit_ParseCommand: PWM Freq:%d\n", CI_INFO, priv->pwm_freq));
443
if(priv->dds.data[1] == 0)
445
priv->sleep_time_act = priv->dds.data[2] | (priv->dds.data[3] << 8);
447
DBG(DDS, ErrorF("%scit_ParseCommand: Sleep Time act:%d \n", CI_INFO, priv->sleep_time_act));
451
if(priv->dds.data[1] == 0)
453
priv->doze_time_act = priv->dds.data[2] | (priv->dds.data[3] << 8);
455
DBG(DDS, ErrorF("%scit_ParseCommand: Doze Time act:%d \n", CI_INFO, priv->doze_time_act));
458
case C_SETAREAPRESSURE:
459
priv->button_threshold = priv->dds.data[1];
460
DBG(DDS, ErrorF("%scit_ParseCommand: Button Threshold:%d \n", CI_INFO, priv->button_threshold));
464
DBG(DDS, ErrorF("%scit_ParseCommand: Command %d not found\n", CI_INFO, priv->dds.data[0]));
473
cit_DriverComm(DeviceIntPtr dev)
475
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
476
cit_PrivatePtr priv = (cit_PrivatePtr)(local->private);
480
DBG(DC, ErrorF("%scit_DriverComm(numbytes=0x%02X, data[1]=%02x, ...)\n", CI_INFO, priv->dds.numbytes, priv->dds.data[1]));
483
switch(priv->dds.data[i++]) /* command word */
486
priv->click_mode = priv->dds.data[i++];
487
ErrorF("%sClick Mode: %d\n", CI_INFO, priv->click_mode);
488
cit_SetEnterCount(priv); /* set enter_count according to click_mode */
492
priv->beep = priv->dds.data[i++];
493
ErrorF("%sBeep: %s\n", CI_INFO, (priv->beep > 0) ? "activated":"not activated");
497
priv->press_vol = priv->dds.data[i++];
498
ErrorF("%sBeep Pressure Volume: %d\n", CI_INFO, priv->press_vol);
499
tmp = priv->dds.data[i++];
500
tmp += priv->dds.data[i++] << 8;
501
priv->press_pitch = tmp;
502
ErrorF("%sBeep Pressure Pitch: %d\n", CI_INFO, priv->press_pitch);
503
priv->press_dur = priv->dds.data[i++];
504
ErrorF("%sBeep Pressure Duration: %d\n", CI_INFO, priv->press_dur);
505
priv->rel_vol = priv->dds.data[i++];
506
ErrorF("%sBeep Release Volume: %d\n", CI_INFO, priv->rel_vol);
507
tmp = priv->dds.data[i++];
508
tmp += priv->dds.data[i++] << 8;
509
priv->rel_pitch = tmp;
510
ErrorF("%sBeep Release Pitch: %d\n", CI_INFO, priv->rel_pitch);
511
priv->rel_dur = priv->dds.data[i++];
512
ErrorF("%sBeep Release Duration: %d\n", CI_INFO, priv->rel_dur);
516
debug_level = priv->dds.data[i++];
517
ErrorF("%sDebug level set to %d \n", CI_INFO, debug_level);
521
priv->enter_count_no_Z = priv->dds.data[i++];
522
cit_SetEnterCount(priv); /* set enter_count according click_mode */
523
ErrorF("%sEnterCount set to %d \n", CI_INFO, priv->enter_count_no_Z);
527
priv->enter_count_Z = priv->dds.data[i++];
528
cit_SetEnterCount(priv); /* set enter_count according click_mode */
529
ErrorF("%sZEnterCount set to %d \n", CI_INFO, priv->enter_count_Z);
533
ErrorF("%sNot known command: %d - Get a recent driver\n", CI_WARNING, priv->dds.data[1]);
540
xf86CitronPrint (int nr, LedCtrl *ctrl)
542
DBG(8, ErrorF("%s------------------------------------------\n", CI_INFO));
543
DBG(8, ErrorF("%sxf86CitronFeedback%d(dev, ctrl)\n", CI_INFO, nr));
544
DBG(8, ErrorF("%s ctrl->led_values.......:%d [0x%08lX]\n", CI_INFO, ctrl->led_values, ctrl->led_values));
545
DBG(8, ErrorF("%s ctrl->led_mask.........:%d [0x%08lX]\n", CI_INFO, ctrl->led_mask, ctrl->led_mask));
546
DBG(8, ErrorF("%s ctrl->id...............:%d\n", CI_INFO, ctrl->id));
551
xf86CitronFeedback0 (DeviceIntPtr dev, LedCtrl *ctrl)
553
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
554
cit_PrivatePtr priv = (cit_PrivatePtr)(local->private);
557
DBG(DDS, ErrorF("%sEntering xf86CitronFeedback0()...\n",CI_INFO));
559
cmd = (COMMAND *)&ctrl->led_values;
561
DBG(DDS, ErrorF("%scmd->packet = %d\n", CI_INFO, cmd->packet));
564
if(cmd->packet == 0) /* test if first packet has come (with number of bytes in first byte) */
566
if(cmd->par[0] == 0) /* test if something is to do at all */
568
priv->dds.curbyte = 2;
569
priv->dds.numbytes = cmd->par[0];
570
priv->dds.data[0] = cmd->par[1];
571
priv->dds.data[1] = cmd->par[2];
572
priv->dds.packet = 1;
576
if(priv->dds.packet == cmd->packet)
578
priv->dds.data[priv->dds.packet*3-1] = cmd->par[0];
579
priv->dds.data[priv->dds.packet*3] = cmd->par[1];
580
priv->dds.data[priv->dds.packet*3+1] = cmd->par[2];
582
priv->dds.curbyte += 3;
585
DBG(DDS, ErrorF("%sPacket error: should be %d is %d\n", CI_WARNING, priv->dds.packet, cmd->packet));
588
DBG(DDS, ErrorF("%snumbytes = %d curbyte=%d\n", CI_INFO, priv->dds.numbytes, priv->dds.curbyte));
589
if(priv->dds.curbyte >= priv->dds.numbytes)
591
if(priv->dds.data[0] == DRIVCOMM)
592
cit_DriverComm(dev); /* process command in the driver */
595
cit_ParseCommand(dev); /* First parse command and set parameters in priv rec */
596
cit_SendtoTouch(dev); /* send message to the touch and execute command there */
600
DBG(DDS, ErrorF("%s 1 led_values = %08x\n", CI_INFO, ctrl->led_values));
601
ctrl->led_values = 0x12345678;
602
DBG(DDS, ErrorF("%s 2 led_values = %08x\n", CI_INFO, ctrl->led_values));
608
xf86CitronFeedback1 (DeviceIntPtr dev, LedCtrl *ctrl)
611
xf86CitronPrint (1, ctrl);
612
ctrl->led_values = 0x8765432;
613
ctrl->led_mask = test++;
617
xf86CitronFeedback2 (DeviceIntPtr dev, LedCtrl *ctrl)
619
xf86CitronPrint (2, ctrl);
620
ctrl->led_values = (unsigned long)GetTimeInMillis();
621
ctrl->led_mask = (unsigned long)GetTimeInMillis()&0xff;
627
/* Hexdump a number of Words */
628
/* len is number of words to dump */
629
static void hexdump (void *ioaddr, int len)
632
unsigned long *ptr = (unsigned long *)ioaddr;
634
ErrorF(" ADDR 0-3 4-7 8-B C-F\n");
635
ErrorF("---------+-----+----+----+----+----+----+----+----\n");
639
ErrorF ("%08X: ", (unsigned long)ptr);
641
for (i=0;i < ( (len>4)?4:len);i++)
642
ErrorF (" %08x", *ptr++);
647
ErrorF("---------+-----+----+----+----+----+----+----+----\n");
652
/*****************************************************************************
654
****************************************************************************/
657
cit_StartTimer(cit_PrivatePtr priv, int nr)
659
priv->timer_ptr[nr] = TimerSet(priv->timer_ptr[nr], 0, priv->timer_val1[nr],
660
priv->timer_callback[nr], (pointer)priv);
661
DBG(5, ErrorF ("%scit_StartTimer[%d] called PTR=%08x\n", CI_INFO, nr, priv->timer_ptr));
665
/*****************************************************************************
667
****************************************************************************/
669
cit_CloseTimer(cit_PrivatePtr priv, int nr)
672
DBG(5, ErrorF ("%scit_CloseTimer[%d] called PTR=%08x\n", CI_INFO, nr, priv->timer_ptr));
673
if(priv->timer_ptr[nr])
675
TimerFree(priv->timer_ptr[nr]);
676
priv->timer_ptr[nr] = NULL;
679
DBG(5, ErrorF ("%scit_CloseTimer[%d]: Nothing to close\n", CI_WARNING, nr));
684
/*****************************************************************************
685
* [cit_SuperVisionTimer] If called reset Serial device
686
****************************************************************************/
688
cit_SuperVisionTimer(OsTimerPtr timer, CARD32 now, pointer arg)
690
cit_PrivatePtr priv = (cit_PrivatePtr) arg;
693
DBG(5, ErrorF ("%scit_SuperVisionTimer called %d\n", CI_INFO, GetTimeInMillis()));
695
sigstate = xf86BlockSIGIO ();
697
cit_ReinitSerial(priv);
699
xf86UnblockSIGIO (sigstate);
701
return (0); /* stop timer */
707
/*****************************************************************************
708
* [cit_DualTouchTimer]
709
****************************************************************************/
711
cit_DualTouchTimer(OsTimerPtr timer, CARD32 now, pointer arg)
713
cit_PrivatePtr priv = (cit_PrivatePtr) arg;
716
DBG(5, ErrorF ("%scit_DualTouchTimer called %d\n", CI_INFO, GetTimeInMillis()));
718
priv->packet[0] = R_EXIT; /* build a exit message */
719
priv->packet[1] = LOBYTE(priv->raw_x);
720
priv->packet[2] = HIBYTE(priv->raw_x);
721
priv->packet[3] = LOBYTE(priv->raw_y);
722
priv->packet[4] = HIBYTE(priv->raw_y);
724
priv->fake_exit = TRUE;
725
sigstate = xf86BlockSIGIO ();
728
priv->local->read_input(priv->local); /* faking up an exit message */
729
xf86UnblockSIGIO (sigstate);
731
DBG(3, ErrorF ("%scit_DualTouchTimer: Faking Exit Message Sent\n", CI_INFO));
733
return (0); /* stop timer */
738
/*****************************************************************************
740
****************************************************************************/
742
CitronPreInit (InputDriverPtr drv, IDevPtr dev, int flags)
744
LocalDevicePtr local = xf86AllocateInput(drv, 0);
745
cit_PrivatePtr priv = (cit_PrivatePtr) xcalloc (1, sizeof (cit_PrivateRec));
751
ErrorF ("%sCitronPreInit called - xcalloc=%d\n", CI_INFO, sizeof(cit_PrivateRec));
752
/* DBG(2, ErrorF("\txf86Verbose=%d\n", xf86Verbose));*/
753
if ((!local) || (!priv))
755
ErrorF("%s\t- unable to allocate structures!\n", CI_ERROR);
759
priv->local = local; /* save local device pointer */
762
/* this results in an xf86strdup that must be freed later */
763
local->name = xf86SetStrOption(local->options, "DeviceName", "CiTouch");
764
ErrorF("%sDevice name: %s\n", CI_INFO, local->name);
766
local->type_name = XI_TOUCHSCREEN;
769
* Standard setup for the local device record
771
local->device_control = DeviceControl;
772
local->read_input = ReadInput;
773
local->control_proc = ControlProc;
774
local->close_proc = CloseProc;
775
local->switch_mode = SwitchMode;
776
local->conversion_proc = ConvertProc;
778
local->private = priv;
779
local->private_flags = 0;
780
local->history_size = xf86SetIntOption(local->options, "HistorySize", 0);
781
local->flags = XI86_POINTER_CAPABLE | XI86_SEND_DRAG_EVENTS;
782
local->conf_idev = dev;
784
xf86CollectInputOptions(local, default_options, NULL);
786
/* xf86OptionListReport(local->options); */
790
debug_level = xf86SetIntOption(local->options, "DebugLevel", 0);
794
ErrorF("%sDebug level set to %d\n", CI_CONFIG, debug_level);
796
ErrorF("%sDebug not available\n", CI_INFO);
804
DBG(5, ErrorF ("%sOpenSerial will be called\n", CI_INFO));
806
local->fd = xf86OpenSerial (local->options);
809
ErrorF ("%s\t- unable to open device %s\n", CI_ERROR, xf86FindOptionValue (local->options, "Device"));
813
DBG(6, ErrorF("%s\t+ %s opened successfully.\n", CI_INFO, xf86FindOptionValue (local->options, "Device")));
817
* Process the options for the IRT
819
priv->screen_num = xf86SetIntOption(local->options, "ScreenNumber", 0);
820
ErrorF("%sAssociated screen: %d\n", CI_CONFIG, priv->screen_num);
821
priv->min_x = xf86SetIntOption(local->options, "MinX", CIT_DEF_MIN_X);
822
ErrorF("%sMinimum x position: %d\n", CI_CONFIG, priv->min_x);
823
priv->max_x = xf86SetIntOption(local->options, "MaxX", CIT_DEF_MAX_X);
824
ErrorF("%sMaximum x position: %d\n", CI_CONFIG, priv->max_x);
825
priv->min_y = xf86SetIntOption(local->options, "MinY", CIT_DEF_MIN_Y);
826
ErrorF("%sMinimum y position: %d\n", CI_CONFIG, priv->min_y);
827
priv->max_y = xf86SetIntOption(local->options, "MaxY", CIT_DEF_MAX_Y);
828
ErrorF("%sMaximum y position: %d\n", CI_CONFIG, priv->max_y);
829
priv->button_number = xf86SetIntOption(local->options, "ButtonNumber", 1);
830
ErrorF("%sButton Number: %d\n", CI_CONFIG, priv->button_number);
831
priv->button_threshold = xf86SetIntOption(local->options, "ButtonThreshold", 10);
832
ErrorF("%sButton Threshold: %d\n", CI_CONFIG, priv->button_threshold);
833
priv->sleep_mode = xf86SetIntOption(local->options, "SleepMode", 0);
834
ErrorF("%sSleep Mode: %d\n", CI_CONFIG, priv->sleep_mode);
835
priv->sleep_time_act = xf86SetIntOption(local->options, "SleepTime", 65535);
836
ErrorF("%sSleep Time: %d\n", CI_CONFIG, priv->sleep_time_act);
837
priv->sleep_time_scan = xf86SetIntOption(local->options, "SleepScan", 65535);
838
ErrorF("%sSleep Scan: %d\n", CI_CONFIG, priv->sleep_time_scan);
839
priv->pwm_active = xf86SetIntOption(local->options, "PWMActive", 255);
840
ErrorF("%sPWM Active: %d\n", CI_CONFIG, priv->pwm_active);
841
priv->pwm_sleep = xf86SetIntOption(local->options, "PWMSleep", 255);
842
ErrorF("%sPWM Sleep: %d\n", CI_CONFIG, priv->pwm_sleep);
843
priv->click_mode = xf86SetIntOption(local->options, "ClickMode", NO_CLICK_MODE);
844
ErrorF("%sClick Mode: %d\n", CI_CONFIG, priv->click_mode);
845
priv->origin = xf86SetIntOption(local->options, "Origin", 0);
846
ErrorF("%sOrigin: %d\n", CI_CONFIG, priv->origin);
847
priv->doze_mode = xf86SetIntOption(local->options, "DozeMode", 0);
848
ErrorF("%sDoze Mode: %d\n", CI_CONFIG, priv->doze_mode);
849
priv->doze_time_act = xf86SetIntOption(local->options, "DozeTime", 10);
850
ErrorF("%sDoze Time: %d\n", CI_CONFIG, priv->doze_time_act);
851
priv->doze_time_scan = xf86SetIntOption(local->options, "DozeScan", 25);
852
ErrorF("%sDoze Scan: %d\n", CI_CONFIG, priv->doze_time_scan);
853
priv->delta_x = xf86SetIntOption(local->options, "DeltaX", 0) & 0xff;
854
ErrorF("%sDelta X: %d\n", CI_CONFIG, priv->delta_x);
855
priv->delta_y = xf86SetIntOption(local->options, "DeltaY", 0) & 0xff;
856
ErrorF("%sDelta Y: %d\n", CI_CONFIG, priv->delta_y);
857
priv->beep = xf86SetIntOption(local->options, "Beep", 0);
858
ErrorF("%sBeep: %s\n", CI_CONFIG, (priv->beep > 0) ? "activated":"not activated");
859
priv->press_vol = xf86SetIntOption(local->options, "PressVol", 100);
860
ErrorF("%sBeep Pressure Volume: %d\n", CI_CONFIG, priv->press_vol);
861
priv->press_pitch = xf86SetIntOption(local->options, "PressPitch", 880);
862
ErrorF("%sBeep Pressure Pitch: %d\n", CI_CONFIG, priv->press_pitch);
863
priv->press_dur = xf86SetIntOption(local->options, "PressDur", 15) & 0xff;
864
ErrorF("%sBeep Pressure Duration: %d\n", CI_CONFIG, priv->press_dur);
865
priv->rel_vol = xf86SetIntOption(local->options, "ReleaseVol", 100);
866
ErrorF("%sBeep Release Volume: %d\n", CI_CONFIG, priv->rel_vol);
867
priv->rel_pitch = xf86SetIntOption(local->options, "ReleasePitch", 1200);
868
ErrorF("%sBeep Release Pitch: %d\n", CI_CONFIG, priv->rel_pitch);
869
priv->rel_dur = xf86SetIntOption(local->options, "ReleaseDur", 10) & 0xff;
870
ErrorF("%sBeep Release Duration: %d\n", CI_CONFIG, priv->rel_dur);
871
priv->beam_timeout = xf86SetIntOption(local->options, "BeamTimeout", 30) & 0xffff;
872
ErrorF("%sBeam Timeout: %d\n", CI_CONFIG, priv->beam_timeout);
873
priv->touch_time = xf86SetIntOption(local->options, "TouchTime", 0) & 0xff;
874
ErrorF("%sTouch Time: %d\n", CI_CONFIG, priv->touch_time);
875
priv->max_dual_count = xf86SetIntOption(local->options, "DualCount", MAX_DUAL_TOUCH_COUNT);
876
ErrorF("%sDual Count: %d\n", CI_CONFIG, priv->max_dual_count);
877
priv->enter_count_no_Z = xf86SetIntOption(priv->local->options, "EnterCount", 3);
878
ErrorF("%sEnterCount: %d\n", CI_CONFIG, priv->enter_count_no_Z);
879
priv->enter_count_Z = xf86SetIntOption(priv->local->options, "ZEnterCount", 2);
880
ErrorF("%sZEnterCount: %d\n", CI_CONFIG, priv->enter_count_Z);
881
priv->pwm_freq = xf86SetIntOption(priv->local->options, "PWMFreq", -1);
882
ErrorF("%sPWMFreq: %d\n", CI_CONFIG, priv->pwm_freq);
884
cit_SetEnterCount(priv); /* set enter_count according click_mode */
886
/* trace the min and max values */
887
priv->raw_min_x = CIT_DEF_MAX_X;
889
priv->raw_min_y = CIT_DEF_MAX_Y;
893
/* preset timer values */
894
priv->timer_ptr[FAKE_TIMER] = NULL;
895
priv->timer_val1[FAKE_TIMER] = 0;
896
priv->timer_val2[FAKE_TIMER] = 0;
897
priv->timer_callback[FAKE_TIMER] = NULL;
899
priv->timer_ptr[SV_TIMER] = NULL;
900
priv->timer_val1[SV_TIMER] = 0;
901
priv->timer_val2[SV_TIMER] = 0;
902
priv->timer_callback[SV_TIMER] = NULL;
904
priv->fake_exit = FALSE;
905
priv->enter_touched = 0; /* preset */
907
DBG(6, ErrorF("%s\t+ options read\n", CI_INFO));
908
s = xf86FindOptionValue (local->options, "ReportingMode");
909
if ((s) && (xf86NameCmp (s, "raw") == 0))
910
priv->reporting_mode = TS_Raw;
912
priv->reporting_mode = TS_Scaled;
916
* Create an X Input Serial Buffer, because IRT is connected to a serial port
918
priv->buffer = XisbNew (local->fd, CIT_BUFFER_SIZE);
920
priv->proximity = FALSE;
921
priv->button_down = FALSE;
922
priv->dual_touch_count = 0;
925
priv->lex_mode = cit_idle;
928
priv->query_state = 0; /* first query */
932
DBG (8, XisbTrace (priv->buffer, 1));
936
* Verify that the IRT is attached and functional
938
if (QueryHardware (local, &errmaj, &errmin) != Success)
940
ErrorF ("%s\t- Unable to query/initialize Citron hardware.\n", CI_INFO);
945
xf86ProcessCommonOptions(local, local->options);
946
local->flags |= XI86_CONFIGURED;
948
if (xf86FindOption (local->options, "DemandLoaded"))
950
DBG (5, ErrorF ("%s\tCitron module was demand loaded\n", CI_INFO));
951
xf86AddLocalDevice (local, TRUE);
954
xf86AddLocalDevice (local, FALSE);
959
RemoveEnabledDevice (local->fd);
963
XisbFree(priv->buffer);
966
xf86CloseSerial(local->fd);
973
/* return the LocalDevice */
974
DBG(5, ErrorF ("%sCitronPreInit success\n", CI_INFO));
979
* If something went wrong, cleanup and return NULL
983
if ((local) && (local->fd))
985
xf86CloseSerial (local->fd);
989
if ((local) && (local->name))
994
if ((priv) && (priv->buffer))
995
XisbFree (priv->buffer);
999
ErrorF ("%sCitronPreInit returning NULL\n", CI_ERROR);
1005
/*****************************************************************************
1007
****************************************************************************/
1009
DeviceControl (DeviceIntPtr dev, int mode)
1013
DBG(5, ErrorF ("%sDeviceControl called; mode = %d\n", CI_INFO, mode));
1017
DBG(6, ErrorF ("%s\tINIT\n", CI_INFO));
1022
DBG(6, ErrorF ("%s\tON\n", CI_INFO));
1023
RetVal = DeviceOn (dev);
1026
DBG(6, ErrorF ("%s\tOFF\n", CI_INFO));
1027
RetVal = DeviceOff (dev);
1030
DBG(6, ErrorF ("%s\tCLOSE\n", CI_INFO));
1031
RetVal = DeviceClose (dev);
1034
ErrorF ("%sDeviceControl Mode (%d) not found\n", CI_ERROR, mode);
1037
DBG(2, ErrorF ("%sDeviceControl: RetVal = %d\n", CI_INFO, RetVal));
1041
/*****************************************************************************
1043
****************************************************************************/
1045
DeviceOn (DeviceIntPtr dev)
1047
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
1048
cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
1051
DBG(5, ErrorF ("%sDeviceOn called\n", CI_INFO));
1053
local->fd = xf86OpenSerial(local->options);
1054
if (local->fd == -1)
1056
DBG(5, ErrorF("%s%s: cannot open input device\n", CI_ERROR, local->name));
1059
priv->buffer = XisbNew (local->fd, CIT_BUFFER_SIZE);
1063
xf86FlushInput(local->fd);
1065
cit_SendCommand(priv->buffer, C_SOFTRESET, 0); /* Make a Reset in case of a connected touch */
1067
if (QueryHardware (local, &errmaj, &errmin) != Success)
1069
ErrorF ("%s\t- DeviceOn: Unable to query/initialize hardware.\n", CI_ERROR);
1073
AddEnabledDevice(local->fd);
1074
dev->public.on = TRUE;
1075
DBG(5, ErrorF ("%sDeviceOn Success\n", CI_INFO));
1079
* If something went wrong, cleanup
1083
if ((local) && (local->fd))
1085
xf86CloseSerial (local->fd);
1089
if ((local) && (local->name))
1090
xfree (local->name);
1096
if ((priv) && (priv->buffer))
1097
XisbFree (priv->buffer);
1103
ErrorF ("%sDeviceOn failed\n", CI_ERROR);
1107
/*****************************************************************************
1109
****************************************************************************/
1111
DeviceOff (DeviceIntPtr dev)
1113
DBG(5, ErrorF ("%sDeviceOff called\n", CI_INFO));
1114
return DeviceClose(dev);
1117
/*****************************************************************************
1119
****************************************************************************/
1121
DeviceClose (DeviceIntPtr dev)
1123
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
1124
cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
1127
DBG(5, ErrorF ("%sDeviceClose called\n",CI_INFO));
1131
cit_SendCommand(priv->buffer, C_SOFTRESET, 0);
1133
cit_CloseTimer(priv, FAKE_TIMER); /* Close timer if started */
1135
cit_CloseTimer(priv, SV_TIMER); /* Do not know if it is running, close anyway */
1137
XisbTrace(priv->buffer, 1); /* trace on */
1138
cit_SetBlockDuration (priv, 500000);
1139
c = XisbRead (priv->buffer);
1142
DBG(6, ErrorF ("%sTouch Reset executed\n",CI_INFO));
1146
DBG(6, ErrorF ("%sTouch Reset not executed\n",CI_ERROR));
1150
/* Now free all allocated memory */
1153
RemoveEnabledDevice (local->fd);
1156
XisbFree(priv->buffer);
1157
priv->buffer = NULL;
1159
xf86CloseSerial(local->fd);
1163
dev->public.on = FALSE;
1164
ErrorF("%sx-range = [%d..%d]\n", CI_INFO, priv->raw_min_x, priv->raw_max_x);
1165
ErrorF("%sy-range = [%d..%d]\n", CI_INFO, priv->raw_min_y, priv->raw_max_y);
1171
/*****************************************************************************
1173
****************************************************************************/
1175
DeviceInit (DeviceIntPtr dev)
1177
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
1178
cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
1180
unsigned char map[] =
1183
DBG (5, ErrorF("%sDeviceInit called\n", CI_INFO));
1185
* these have to be here instead of in the SetupProc, because when the
1186
* SetupProc is run and server startup, screenInfo is not setup yet
1188
priv->screen_width = screenInfo.screens[priv->screen_num]->width;
1189
priv->screen_height = screenInfo.screens[priv->screen_num]->height;
1191
DBG (5, ErrorF("%sScreen Number: %d Screen Width: %d Screen Height: %d\n", CI_INFO,
1192
priv->screen_num, priv->screen_width, priv->screen_height));
1195
* Device reports button press for up to 1 button.
1197
if (InitButtonClassDeviceStruct (dev, 1, map) == FALSE)
1199
ErrorF ("%sUnable to allocate Citron touchscreen ButtonClassDeviceStruct\n", CI_ERROR);
1204
* Device reports motions on 2 axes in absolute coordinates.
1205
* Axes min and max values are reported in raw coordinates.
1206
* Resolution is computed roughly by the difference between
1207
* max and min values scaled from the approximate size of the
1208
* screen to fit one meter.
1209
* Device may reports touch pressure on the 3rd axis.
1211
if (InitValuatorClassDeviceStruct (dev, 2, xf86GetMotionEvents,
1212
local->history_size, Absolute) == FALSE)
1214
ErrorF ("%sUnable to allocate Citron touchscreen ValuatorClassDeviceStruct\n", CI_ERROR);
1219
InitValuatorAxisStruct (dev, 0, priv->min_x, priv->max_x,
1221
CIT_DEF_MIN_X /* min_res */ ,
1222
CIT_DEF_MAX_X /* max_res */ );
1223
InitValuatorAxisStruct (dev, 1, priv->min_y, priv->max_y,
1225
CIT_DEF_MIN_Y /* min_res */ ,
1226
CIT_DEF_MAX_Y /* max_res */ );
1229
if (InitProximityClassDeviceStruct (dev) == FALSE)
1231
ErrorF ("%sUnable to allocate Citron touchscreen ProximityClassDeviceStruct\n", CI_ERROR);
1237
* Use the LedFeedbackClass to set some driver parameters
1240
/* ID=0 --> Return driver version (RO) */
1242
if (InitLedFeedbackClassDeviceStruct(dev, xf86CitronFeedback0) == FALSE)
1244
ErrorF("Unable to allocate CITRON touchscreen LedFeedbackClassDeviceStruct, id=0\n");
1247
/* ID=1 --> ENTER_COUNT */
1248
if (InitLedFeedbackClassDeviceStruct(dev, xf86CitronFeedback1) == FALSE)
1250
ErrorF("Unable to allocate CITRON touchscreen LedFeedbackClassDeviceStruct, id=1\n");
1255
if (InitLedFeedbackClassDeviceStruct(dev, xf86CitronFeedback2) == FALSE)
1257
ErrorF("Unable to allocate CITRON touchscreen LedFeedbackClassDeviceStruct, id=2\n");
1263
* Allocate the motion events buffer.
1265
xf86MotionHistoryAllocate (local);
1269
/*****************************************************************************
1271
****************************************************************************/
1273
ReadInput (LocalDevicePtr local)
1276
cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
1278
DBG(RI, ErrorF("%sReadInput called\n", CI_INFO));
1281
* set blocking to -1 on the first call because we know there is data to
1282
* read. Xisb automatically clears it after one successful read so that
1283
* succeeding reads are preceeded by a select with a 0 timeout to prevent
1284
* read from blocking indefinately.
1286
if(!priv->fake_exit)
1288
cit_SetBlockDuration (priv, -1);
1294
(cit_GetPacket (priv) == Success))
1296
cit_ProcessPacket(priv);
1300
if (priv->reporting_mode == TS_Scaled)
1302
x = xf86ScaleAxis (priv->raw_x, 0, priv->screen_width, priv->min_x,
1304
y = xf86ScaleAxis (priv->raw_y, 0, priv->screen_height, priv->min_y,
1306
DBG(RI, ErrorF("%s\tscaled coordinates: (%d, %d)\n", CI_INFO, x, y));
1314
xf86XInputSetScreen (local, priv->screen_num, x, y);
1316
if ((priv->proximity == FALSE) && (priv->state & CIT_TOUCHED))
1318
priv->proximity = TRUE;
1319
xf86PostProximityEvent (local->dev, 1, 0, 2, x, y);
1320
DBG(RI, ErrorF("%s\tproximity(TRUE, x=%d, y=%d)\n", CI_INFO, x, y));
1326
* We *must* generate a motion before a button change if pointer
1327
* location has changed as DIX assumes this. This is why we always
1328
* emit a motion, regardless of the kind of packet processed.
1329
* First test if coordinates have changed a predefined amount of pixels
1332
if ( ((x >= (priv->last_x + priv->delta_x)) ||
1333
(x <= (priv->last_x - priv->delta_x)) ||
1334
(y >= (priv->last_y + priv->delta_y)) ||
1335
(y <= (priv->last_y - priv->delta_y))) ||
1336
( ((x < priv->delta_x) ||
1337
(x > (priv->screen_width - priv->delta_x))) ||
1338
((y < priv->delta_x) ||
1339
(y > (priv->screen_height - priv->delta_y)))) )
1341
xf86PostMotionEvent (local->dev, TRUE, 0, 2, x, y);
1342
DBG(RI, ErrorF("%s\tPostMotionEvent(x=%d, y=%d, last_x=%d, last_y=%d)\n", CI_INFO,
1343
x, y, priv->last_x, priv->last_y));
1345
priv->last_x = x; /* save cooked data */
1350
* Emit a button press or release.
1353
if ((priv->button_down == FALSE) && (priv->state & CIT_BUTTON))
1355
if(priv->enter_touched < priv->enter_count)
1356
priv->enter_touched++;
1358
if(priv->enter_touched == priv->enter_count)
1360
priv->enter_touched++; /* increment count one more time to prevent further enter events */
1361
xf86PostButtonEvent (local->dev, TRUE,
1362
priv->button_number, 1, 0, 2, x, y);
1365
DBG(RI, ErrorF("%s\tPostButtonEvent(DOWN, x=%d, y=%d)\n", CI_INFO, x, y));
1367
priv->button_down = TRUE;
1371
if ((priv->button_down == TRUE) && !(priv->state & CIT_BUTTON))
1373
xf86PostButtonEvent (local->dev, TRUE,
1374
priv->button_number, 0, 0, 2, x, y);
1376
DBG(RI, ErrorF("%s\tPostButtonEvent(UP, x=%d, y=%d)\n", CI_INFO, x, y));
1377
priv->button_down = FALSE;
1380
* the untouch should always come after the button release
1382
if ((priv->proximity == TRUE) && !(priv->state & CIT_TOUCHED))
1384
priv->proximity = FALSE;
1385
xf86PostProximityEvent (local->dev, 0, 0, 2, x, y);
1386
DBG(RI, ErrorF("%s\tproximity(FALSE, x=%d, y=%d)\n", CI_INFO, x, y));
1390
DBG (RI, ErrorF ("%sTouchScreen: x(%d), y(%d), %s\n",
1392
(priv->state == CIT_TOUCHED) ? "Touched" : "Released"));
1397
priv->fake_exit = FALSE; /* do not sent any further faked exit messages */
1402
DBG(RI, ErrorF("%sExit ReadInput\n", CI_INFO));
1405
/*****************************************************************************
1407
****************************************************************************/
1409
ControlProc (LocalDevicePtr local, xDeviceCtl * control)
1411
xDeviceTSCalibrationCtl *c = (xDeviceTSCalibrationCtl *) control;
1412
cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
1414
DBG(5, ErrorF("%sControlProc called\n", CI_INFO));
1416
priv->min_x = c->min_x;
1417
priv->max_x = c->max_x;
1418
priv->min_y = c->min_y;
1419
priv->max_y = c->max_y;
1425
/*****************************************************************************
1427
****************************************************************************/
1429
CloseProc (LocalDevicePtr local)
1431
DBG(5, ErrorF("%sCloseProc called\n", CI_INFO));
1434
/*****************************************************************************
1436
****************************************************************************/
1438
SwitchMode (ClientPtr client, DeviceIntPtr dev, int mode)
1440
LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
1441
cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
1442
DBG(5, ErrorF("%sSwitchMode called; mode = %d\n", CI_INFO, mode));
1443
if ((mode == TS_Raw) || (mode == TS_Scaled))
1445
priv->reporting_mode = mode;
1446
DBG(6, ErrorF("%s\treporting mode = %s\n", CI_INFO, mode==TS_Raw?"raw":"scaled"));
1449
else if ((mode == SendCoreEvents) || (mode == DontSendCoreEvents))
1451
xf86XInputSetSendCoreEvents (local, (mode == SendCoreEvents));
1452
DBG(6, ErrorF("%s\tmode = %sSend Core Events\n", CI_INFO, mode==DontSendCoreEvents?"Don\'t ":""));
1456
else if (mode == ClickMode_Enter)
1458
priv->click_mode = CM_ENTER;
1459
DBG(6, ErrorF("%s\tset click mode to ENTER\n", CI_INFO));
1462
else if (mode == ClickMode_Dual)
1464
priv->click_mode = CM_DUAL;
1465
DBG(6, ErrorF("%s\tset click mode to DUAL TOUCH\n", CI_INFO));
1468
else if (mode == ClickMode_ZPress)
1470
priv->click_mode = CM_ZPRESS;
1471
DBG(6, ErrorF("%s\tset click mode to Z-Press\n", CI_INFO));
1477
ErrorF("%sUnknown mode for Citron Touchscreen Switchmode Function: 0x%02x!\n", CI_ERROR, mode);
1482
/*****************************************************************************
1484
****************************************************************************/
1486
ConvertProc (LocalDevicePtr local,
1498
cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
1500
DBG(5, ErrorF("%sConvertProc called(first=%d, num=%d, v0=%d, v1=%d, v2=%d, v3=%d\n",
1501
CI_INFO, first, num, v0, v1, v2, v3));
1502
if (priv->reporting_mode == TS_Raw)
1504
*x = xf86ScaleAxis (v0, 0, priv->screen_width, priv->min_x,
1506
*y = xf86ScaleAxis (v1, 0, priv->screen_height, priv->min_y,
1514
DBG(6, ErrorF("%s\t+ x=%d, y=%d\n",CI_INFO, *x, *y));
1518
/*****************************************************************************
1520
****************************************************************************/
1522
QueryHardware (LocalDevicePtr local, int *errmaj, int *errmin)
1524
cit_PrivatePtr priv = (cit_PrivatePtr) (local->private);
1527
int err; /* for WAIT */
1530
/* Reset the IRT from any mode and wait for end of warmstart */
1531
DBG(5, ErrorF("%sQueryHardware called\n", CI_INFO));
1535
/* Will not work with XFree86 4.0.1 */
1536
/* xf86SerialSendBreak (local->fd, 2); */
1542
* IRT signals end of startup by sending BREAKS with 100 ms length.
1543
* wait a maximum of 2 seconds for at least 2 consecutive breaks
1544
* to be sure the IRT is really initialized
1546
cit_Flush(priv); /* clear the buffer and wait for break */
1547
DBG(6, ErrorF("%s\t* waiting for BREAKS...\n", CI_INFO));
1549
cit_SetBlockDuration (priv, 1);
1551
for (i=0, cnt=0; (i<20) && (cnt<3); i++)
1553
cit_Flush(priv); /* clear the buffer and wait for break */
1554
WAIT(150); /* wait a little bit longer than 100 ms */
1555
DBG(7, ErrorF("%s\t (loop %d)\n", CI_INFO, i));
1556
if (XisbRead(priv->buffer) == 0)
1559
DBG(6, ErrorF("%s\t+ BREAK %d detected\n", CI_INFO, cnt));
1567
cit_SendCommand(priv->buffer, C_SOFTRESET, 0);
1568
DBG(6, ErrorF("%s\t+ SOFTRESET sent\n", CI_INFO));
1571
/* maybe we are in Debug Mode and have to sent a soft reset */
1574
XisbWrite(priv->buffer, (unsigned char *)"r2", 2);
1576
XisbWrite(priv->buffer, &x, 1);
1577
DBG(6, ErrorF("%s\t+ DEBUG-MODE SOFTRESET sent\n", CI_INFO));
1583
ErrorF("%sCannot reset Citron Infrared Touch!\n", CI_ERROR);
1585
/* Workaround - bugfix
1586
Normally when the touch is connected and the driver thinks it didn't sent
1587
breaks we have the problem, that spurious characters, which are sent at
1588
the startup of the touch screen make the winbond SIO chip not to sent
1589
any further interrupts. To overcome this problem we reinitialize the
1590
winbond chip with a close and open of the serial line.
1591
Thanks a lot winbond team. Without it I wouldn't have
1592
written these wonderful lines of source code ;-).
1594
cit_ReinitSerial(priv);
1597
/* Now initialize IRT to CTS Protocol */
1598
DBG(6, ErrorF("%s\t* initializing to CTS mode\n", CI_INFO));
1602
XisbWrite(priv->buffer, &x, 1);
1606
XisbWrite(priv->buffer, &x, 1);
1608
/* wait max. 0.5 seconds for acknowledge */
1609
DBG(6, ErrorF("%s\t* waiting for acknowledge\n", CI_INFO));
1610
cit_SetBlockDuration (priv, 500000);
1612
while ((i=XisbRead(priv->buffer)) != -1)
1614
DBG(7, ErrorF("%s\t* 0x%02X received - waiting for CTS_XON\n",CI_INFO, i));
1615
if ((unsigned char)i == CTS_XON)
1617
if(cnt++ > 50) return (Success); /* emergency stop */
1619
if ((unsigned char)i != CTS_XON)
1621
ErrorF("%sNo acknowledge from Citron Infrared Touch!\n", CI_ERROR);
1622
cit_ReinitSerial(priv);
1626
/* now we have the touch connected, do the initialization stuff */
1627
DBG(6, ErrorF("%s\t+ Touch connected!\n",CI_INFO));
1630
DBG(6, ErrorF("%s\t+ requesting pressure sensors report\n",CI_INFO));
1631
if (cit_GetPressureSensors(priv)!=Success)
1633
ErrorF("%sNo pressure sensors report received from Citron Touchscreen!\n",CI_ERROR);
1636
DBG(5, ErrorF("%s ClickMode is %d\n",CI_INFO, priv->click_mode));
1637
if(priv->click_mode == NO_CLICK_MODE) /* if no click mode set in XF86Config set it automatically */
1639
priv->click_mode = (priv->pressure_sensors > 0) ? CM_ZPRESS : CM_ENTER;
1640
DBG(5, ErrorF("%sClickMode set to %d\n",CI_INFO, priv->click_mode));
1641
cit_SetEnterCount(priv);
1644
cit_SendCommand(priv->buffer, C_SETAREAFLAGS, 1, AOF_ADDEXIT
1649
cit_SendCommand(priv->buffer, C_SETAREAMODE, 1, AOM_CONT);
1651
cit_SendCommand(priv->buffer, C_SETCONTTIME, 1, 20);
1653
cit_SendCommand(priv->buffer, C_SETDUALTOUCHING, 1, DT_ERROR);
1655
cit_SendCommand(priv->buffer, C_SETAREAPRESSURE, 1, LOBYTE(priv->button_threshold));
1657
cit_SendCommand(priv->buffer, C_SETRESOLUTION, 4,
1658
LOBYTE(CIT_DEF_MAX_X),
1659
HIBYTE(CIT_DEF_MAX_X),
1660
LOBYTE(CIT_DEF_MAX_Y),
1661
HIBYTE(CIT_DEF_MAX_Y));
1663
cit_SendCommand(priv->buffer, C_SETPWM, 2,
1664
LOBYTE(priv->pwm_active),
1665
LOBYTE(priv->pwm_sleep));
1667
cit_SendCommand(priv->buffer, C_SETBEAMTIMEOUT, 2,
1668
LOBYTE(priv->beam_timeout),
1669
HIBYTE(priv->beam_timeout));
1671
cit_SendCommand(priv->buffer, C_SETORIGIN, 1, LOBYTE(priv->origin));
1672
cit_SendCommand(priv->buffer, C_SETTOUCHTIME, 1, LOBYTE(priv->touch_time));
1674
cit_SendCommand(priv->buffer, C_SETSLEEPMODE, 5,
1675
LOBYTE(priv->sleep_mode),
1676
LOBYTE(priv->sleep_time_act),
1677
HIBYTE(priv->sleep_time_act),
1678
LOBYTE(priv->sleep_time_scan),
1679
HIBYTE(priv->sleep_time_scan));
1681
cit_SendCommand(priv->buffer, C_SETDOZEMODE, 5,
1682
LOBYTE(priv->doze_mode),
1683
LOBYTE(priv->doze_time_act),
1684
HIBYTE(priv->doze_time_act),
1685
LOBYTE(priv->doze_time_scan),
1686
HIBYTE(priv->doze_time_scan));
1688
cit_SendCommand(priv->buffer, C_SETTRANSMISSION, 1, TM_TRANSMIT);
1689
cit_SendCommand(priv->buffer, C_SETSCANNING, 1, 1);
1691
cit_SendPWMFreq(priv); /* Set PWM Frequency */
1693
if(priv->query_state == 0) /* do error reporting only 1 time */
1695
priv->query_state++;
1697
DBG(6, ErrorF("%s\t+ requesting initial errors report\n",CI_INFO));
1698
if (cit_GetInitialErrors(priv)!=Success)
1700
ErrorF("%sNo initial error report received from Citron Touchscreen!\n",CI_ERROR);
1701
*errmaj = LDR_NOHARDWARE;
1704
DBG(6, ErrorF("\t+ requesting defective beams report\n"));
1705
if (cit_GetDefectiveBeams(priv)!=Success)
1707
ErrorF("%sNo defective beams report received from Citron Touchscreen!\n",CI_ERROR);
1708
*errmaj = LDR_NOHARDWARE;
1711
DBG(6, ErrorF("\t+ requesting touch revisions\n"));
1712
if (cit_GetDesignator(priv)!=Success)
1714
ErrorF("%sNo designator received from Citron Touchscreen!\n",CI_ERROR);
1715
*errmaj = LDR_NOHARDWARE;
1718
if (cit_GetRevision(priv, GR_SYSMGR)!=Success)
1720
ErrorF("%sNo system manager module revision received from Citron Touchscreen!\n",CI_ERROR);
1721
*errmaj = LDR_NOHARDWARE;
1724
if (cit_GetRevision(priv, GR_HARDWARE)!=Success)
1726
ErrorF("%sNo hardware module revision received from Citron Touchscreen!\n",CI_ERROR);
1727
*errmaj = LDR_NOHARDWARE;
1730
if (cit_GetRevision(priv, GR_PROCESS)!=Success)
1732
ErrorF("%sNo process module revision received from Citron Touchscreen!\n",CI_ERROR);
1733
*errmaj = LDR_NOHARDWARE;
1736
if (cit_GetRevision(priv, GR_PROTOCOL)!=Success)
1738
ErrorF("%sNo protocol module revision received from Citron Touchscreen!\n",CI_ERROR);
1739
*errmaj = LDR_NOHARDWARE;
1742
if (cit_GetRevision(priv, GR_HWPARAM)!=Success)
1744
ErrorF("%sNo hardware parameter module revision received from Citron Touchscreen!\n",CI_ERROR);
1745
*errmaj = LDR_NOHARDWARE;
1750
DBG(6, ErrorF("%s\t+ Touch initialized - %d\n",CI_INFO, priv->query_state));
1756
/*****************************************************************************
1758
****************************************************************************/
1760
cit_GetPacket (cit_PrivatePtr priv)
1765
DBG(GP, ErrorF("%scit_GetPacket called\n", CI_INFO));
1766
DBG(GP, ErrorF("%s\t* initial lex_mode =%d (%s)\n", CI_INFO, priv->lex_mode,
1767
priv->lex_mode==cit_idle ?"idle":
1768
priv->lex_mode==cit_getID ?"getID":
1769
priv->lex_mode==cit_collect ?"collect":
1770
priv->lex_mode==cit_escape ?"escape":
1772
while ((c = XisbRead (priv->buffer)) >= 0)
1775
DBG(GP, ErrorF("%s c=%d\n",CI_INFO, c));
1780
DBG(GP, ErrorF("%s\t+ STX detected\n", CI_INFO));
1781
/* start of report received */
1782
if (priv->lex_mode != cit_idle)
1783
DBG(7, ErrorF("%s\t- no ETX received before this STX!\n", CI_WARNING));
1784
priv->lex_mode = cit_getID;
1785
DBG(GP, ErrorF("%s\t+ new lex_mode == getID\n", CI_INFO));
1786
/* Start supervision timer at the beginning of a command */
1787
priv->timer_val1[SV_TIMER] = 2000; /* Timer delay [ms] 2s */
1788
priv->timer_callback[SV_TIMER] = (OsTimerCallback)cit_SuperVisionTimer; /* timer callback routine */
1789
cit_StartTimer(priv, SV_TIMER);
1792
else if (c == CTS_ETX)
1794
DBG(GP, ErrorF("%s\t+ ETX detected\n", CI_INFO));
1795
/* end of command received */
1796
/* always IDLE after report completion */
1797
DBG(GP, ErrorF("%s\t+ new lex_mode == idle\n", CI_INFO));
1798
if (priv->lex_mode == cit_collect)
1800
DBG(GP, ErrorF("%s\t+ Good report received\n", CI_INFO));
1801
priv->lex_mode = cit_idle;
1802
cit_CloseTimer(priv, SV_TIMER); /* stop supervision */
1805
DBG(GP, ErrorF("%s\t- unexpected ETX received!\n", CI_WARNING));
1806
priv->lex_mode = cit_idle;
1808
else if (c == CTS_ESC)
1810
DBG(GP, ErrorF("%s\t+ escape detected\n", CI_INFO));
1811
/* next character is encoded */
1812
if (priv->lex_mode != cit_collect)
1814
DBG(GP, ErrorF("%s\t- unexpected control character received\n", CI_WARNING));
1818
priv->lex_mode = cit_escape;
1819
DBG(GP, ErrorF("%s\t+ new lex_mode == escape\n", CI_INFO));
1822
else if ((c < CTS_CTRLMIN) || (c > CTS_CTRLMAX))
1824
/* regular report data received */
1825
if (priv->lex_mode == cit_getID)
1826
{ /* receive report ID */
1828
priv->packet[priv->packeti++] = (unsigned char)c;
1829
priv->lex_mode = cit_collect;
1830
DBG(GP, ErrorF("%s\t+ identifier captured, new lex_mode == collect\n", CI_INFO));
1832
else if ((priv->lex_mode == cit_collect) || (priv->lex_mode == cit_escape))
1833
{ /* receive command data */
1834
if (priv->lex_mode == cit_escape)
1835
{ /* decode encoded data byte */
1836
c &= CTS_DECODE; /* decode data */
1837
priv->lex_mode = cit_collect;
1838
DBG(GP, ErrorF("%s\t+ decoded character = 0x%02X\n", CI_INFO, c));
1839
DBG(GP, ErrorF("%s\t+ new lex_mode = collect\n", CI_INFO));
1841
if (priv->packeti < CTS_PACKET_SIZE)
1842
{ /* add data bytes to buffer */
1843
priv->packet[priv->packeti++] = (unsigned char)c;
1847
DBG(GP, ErrorF("%s\t- command buffer overrun, loop[%d]\n", CI_ERROR, loop));
1848
/* let's reinitialize the touch - maybe it sends breaks */
1849
/* The touch assembles breaks until the buffer has an overrun */
1850
/* 100ms x 256 -> 26 seconds */
1852
priv->lex_mode = cit_idle;
1853
cit_ReinitSerial(priv);
1859
/* this happens e.g. when the touch sends breaks, so we try to reconnect */
1860
DBG(GP, ErrorF("%s\t- unexpected non control received! [%d, 0x%02x, loop[%d]]\n", CI_WARNING, c, c, loop));
1861
DBG(GP, ErrorF("%s\t- Device not connected - trying to reconnect ...\n", CI_WARNING));
1862
if (QueryHardware (priv->local, &errmaj, &errmin) != Success)
1863
ErrorF ("%s\t- Unable to query/initialize Citron Touch hardware.\n", CI_ERROR);
1865
ErrorF ("%s\t- Citron Touch reconnected\n", CI_INFO);
1870
else if (c != CTS_XON && c != CTS_XOFF)
1872
DBG(GP, ErrorF("%s\t- unhandled control character received! loop[%d]\n", CI_WARNING, loop));
1875
DBG(GP, ErrorF("%scit_GetPacket exit !Success - loop[%d]\n", CI_INFO, loop));
1881
/*****************************************************************************
1882
* [cit_ReinitSerial] Reinitialize serial port
1883
****************************************************************************/
1885
cit_ReinitSerial(cit_PrivatePtr priv)
1889
xf86CloseSerial(priv->local->fd);
1890
priv->local->fd = 0;
1891
priv->local->fd = xf86OpenSerial (priv->local->options);
1892
DBG(6, ErrorF("%s\t* cit_ReinitSerial: Serial connection reinitialized\n", CI_INFO));
1895
DBG(6, ErrorF("%s\t* cit_ReinitSerial: Serial connection not opened\n", CI_ERROR));
1898
/*****************************************************************************
1900
****************************************************************************/
1902
cit_Flush (cit_PrivatePtr priv)
1904
int old_block_duration;
1906
DBG(7, ErrorF("%scit_Flush called\n", CI_INFO));
1907
old_block_duration = priv->buffer->block_duration;
1908
XisbBlockDuration(priv->buffer, 1000); /* wait for at least 10ms for the next character */
1909
while (XisbRead(priv->buffer) >= 0);
1910
cit_SetBlockDuration(priv, old_block_duration); /* Restore the last set block duration (cit_SetBlockDuration) */
1913
/*****************************************************************************
1914
* [cit_SetBlockDuration]
1915
****************************************************************************/
1917
cit_SetBlockDuration (cit_PrivatePtr priv, int block_duration)
1919
DBG(7, ErrorF("%scit_SetBlockDuration called [%d]\n", CI_INFO, block_duration));
1920
XisbBlockDuration(priv->buffer, block_duration);
1924
/*****************************************************************************
1926
****************************************************************************/
1928
cit_Beep(cit_PrivatePtr priv, int press)
1934
/* ring release bell */
1937
/* [0]: volume, [1]: pitch, [2]: duration */
1938
/* formula is: ((1193190 / freq) & 0xffff) | */
1939
/* (((unsigned long)duration * loudness / 50) << 16)) */
1940
/* .. whatever the inventor wants to intend by it, I don't know (PK) */
1942
xf86SoundKbdBell(priv->rel_vol, priv->rel_pitch, priv->rel_dur);
1945
/* ring press bell */
1946
xf86SoundKbdBell(priv->press_vol,priv->press_pitch, priv->press_dur);
1948
DBG(7, ErrorF("%scit_Beep called - %s\n", CI_INFO, (press == 0) ? "release" : "press"));
1953
/*****************************************************************************
1955
****************************************************************************/
1957
cit_SendCommand (XISBuffer *b, unsigned char cmd, int cnt, ...)
1960
unsigned char data, x;
1964
DBG(7, ErrorF("%scit_SendCommand(cmd=0x%02X, cnt=%d, ...)\n", CI_INFO, cmd, cnt));
1966
XisbWrite(b, &x, 1); /* transmit start of packet */
1967
XisbWrite(b, &cmd, 1); /* transmit command code */
1970
{ /* encode and transmit optional parameters */
1971
data = va_arg(ap, int);
1972
if (data >= CTS_CTRLMIN && data <= CTS_CTRLMAX)
1973
{ /* data has to be encoded */
1975
XisbWrite(b, &x, 1); /* mark coded data */
1977
XisbWrite(b, &data, 1); /* transmit data */
1980
XisbWrite(b, &x, 1); /* transmit end of packet */
1985
/*****************************************************************************
1986
* [cit_GetInitialErrors]
1987
****************************************************************************/
1988
static Bool cit_GetInitialErrors(cit_PrivatePtr priv)
1990
unsigned long errors;
1995
cit_SendCommand(priv->buffer, C_GETERRORS, 1, GE_INITIAL);
1997
touch responds within 1 millisecond,
1998
but it takes some time, until the command is sent!
2002
cit_SetBlockDuration(priv, 500000);
2003
res = cit_GetPacket(priv);
2004
if ((res == Success) || (priv->lex_mode == cit_idle));
2009
DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE));
2012
/* examine packet */
2013
if (priv->packeti != 6)
2015
DBG(5, ErrorF("%sWrong packet length (expected 6, received %d bytes)\n", CI_NOTICE, priv->packeti));
2018
if (priv->packet[0] != (C_GETERRORS & CMD_REP_CONV))
2020
DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
2021
(C_GETERRORS & CMD_REP_CONV), priv->packet[0]));
2024
if (priv->packet[1] != GE_INITIAL)
2026
DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
2027
GE_INITIAL, priv->packet[1]));
2030
/* this is our packet! check contents */
2031
errors = 0x00000001UL * (unsigned long)priv->packet[2]
2032
+ 0x00000100UL * (unsigned long)priv->packet[3]
2033
+ 0x00010000UL * (unsigned long)priv->packet[4]
2034
+ 0x10000000UL * (unsigned long)priv->packet[5];
2035
DBG(6, ErrorF("%sinitial errors = 0x%08lX\n", CI_NOTICE, errors));
2036
if (errors == 0x00000000UL)
2038
ErrorF("%sNo initialization errors detected.\n", CI_INFO);
2040
if (errors & IE_SMCHKSUM)
2042
ErrorF("%sSystem Manager Module checksum error!\n", CI_ERROR);
2044
if (errors & IE_SMINIT)
2046
ErrorF("%sSystem Manager Module initialization error!\n", CI_ERROR);
2048
if (errors & IE_HWCHKSUM)
2050
ErrorF("%sHardware Module checksum error!\n", CI_ERROR);
2052
if (errors & IE_HWINIT)
2054
ErrorF("%sHardware Module initialization error!\n", CI_ERROR);
2056
if (errors & IE_HW_BEAMS)
2058
ErrorF("%s broken beams during initialization detected!\n", CI_ERROR);
2060
if (errors & IE_HW_PSU)
2062
ErrorF("%s force sensors not operating!\n", CI_ERROR);
2064
if (errors & IE_HW_CPU)
2066
ErrorF("%s CPU integrity test failed!\n", CI_ERROR);
2068
if (errors & IE_HW_IRAM)
2070
ErrorF("%s internal RAM error!\n", CI_ERROR);
2072
if (errors & IE_HW_XRAM)
2074
ErrorF("%s external SRAM error!\n", CI_ERROR);
2076
if (errors & IE_PCCHKSUM)
2078
ErrorF("%sProcess Module checksum error!\n", CI_ERROR);
2080
if (errors & IE_PCINIT)
2082
ErrorF("%sProcess Module initialization error!\n", CI_ERROR);
2084
if (errors & IE_PTCHKSUM)
2086
ErrorF("%sProtocol Module checksum error!\n", CI_ERROR);
2088
if (errors & IE_PTINIT)
2090
ErrorF("%sProtocol Module initialization error!\n", CI_ERROR);
2092
if (errors & IE_BICHK)
2094
ErrorF("%sBurnIn Module checksum error!\n", CI_ERROR);
2096
if (errors & IE_BIINIT)
2098
ErrorF("%sBurnIn Module initialization error!\n", CI_ERROR);
2100
if (errors & IE_FPGACHK)
2102
ErrorF("%sFPGA configuration checksum error!\n", CI_ERROR);
2104
if (errors & IE_HWPCHK)
2106
ErrorF("%sHardware Parameter checksum error!\n", CI_ERROR);
2112
/*****************************************************************************
2113
* [cit_GetDefectiveBeams]
2114
****************************************************************************/
2115
static Bool cit_GetDefectiveBeams(cit_PrivatePtr priv)
2122
cit_SendCommand(priv->buffer, C_GETERRORS, 1, GE_DEFECTBEAMS);
2124
touch responds within 1 millisecond,
2125
but it takes some time, until the command is sent!
2129
cit_SetBlockDuration(priv, 500000);
2130
res = cit_GetPacket(priv);
2131
if ((res == Success) || (priv->lex_mode == cit_idle));
2136
DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE));
2139
/* examine packet */
2140
if (priv->packeti < 6)
2142
DBG(5, ErrorF("%sWrong packet length (expected >= 6, received %d bytes)\n", CI_NOTICE, priv->packeti));
2145
if (priv->packet[0] != (C_GETERRORS & CMD_REP_CONV))
2147
DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
2148
(C_GETERRORS & CMD_REP_CONV), priv->packet[0]));
2151
if (priv->packet[1] != GE_DEFECTBEAMS)
2153
DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
2154
GE_DEFECTBEAMS, priv->packet[1]));
2157
/* this is our packet! check contents */
2158
nx = 0x0001U * (unsigned)priv->packet[2]
2159
+ 0x0100U * (unsigned)priv->packet[3];
2161
ny = 0x0001U * (unsigned)priv->packet[4]
2162
+ 0x0100U * (unsigned)priv->packet[5];
2163
/* list defective X-beams */
2166
ErrorF("%s%u defective X-Beams detected:\n", CI_ERROR, nx);
2167
for (i=0; i<nx; i++)
2169
ErrorF("%s\tX%02u\n", CI_ERROR, (unsigned)priv->packet[6+i]);
2174
ErrorF("%sNo defective X-beams detected.\n", CI_INFO);
2177
/* list defective Y-beams */
2180
ErrorF("%s%u defective Y-Beams detected:\n", CI_ERROR, ny);
2181
for (i=0; i<ny; i++)
2183
ErrorF("%s\tY%02u\n", CI_ERROR, (unsigned)priv->packet[6+nx+i]);
2188
ErrorF("%sNo defective Y-beams detected.\n", CI_INFO);
2194
/*****************************************************************************
2195
* [cit_GetDesignator]
2196
****************************************************************************/
2197
static Bool cit_GetDesignator(cit_PrivatePtr priv)
2203
cit_SendCommand(priv->buffer, C_GETREVISIONS, 1, GR_DESIGNATOR);
2205
touch responds within 1 millisecond,
2206
but it takes some time, until the command is sent and received!
2210
cit_SetBlockDuration(priv, 500000);
2211
res = cit_GetPacket(priv);
2212
if ((res == Success) || (priv->lex_mode == cit_idle));
2217
DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE));
2220
/* examine packet */
2221
if (priv->packeti < 2+CTS_DESIGNATOR_LEN+CTS_ASSY_LEN)
2223
DBG(5, ErrorF("%sWrong packet length (expected >= %d, received %d bytes)\n", CI_NOTICE,
2224
2+CTS_DESIGNATOR_LEN+CTS_ASSY_LEN,
2228
if (priv->packet[0] != (C_GETREVISIONS & CMD_REP_CONV))
2230
DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
2231
(C_GETREVISIONS & CMD_REP_CONV), priv->packet[0]));
2234
if (priv->packet[1] != GR_DESIGNATOR)
2236
DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
2237
GR_DESIGNATOR, priv->packet[1]));
2240
/* this is our packet! check contents */
2241
ErrorF("%sDesignator \"", CI_INFO);
2244
while (n++ < CTS_DESIGNATOR_LEN && priv->packet[i]!=0)
2246
ErrorF("%c", priv->packet[i++]);
2248
ErrorF("\"\n%sAssembly \"", CI_INFO);
2249
i = 2 + CTS_DESIGNATOR_LEN;
2251
while (n++ < CTS_ASSY_LEN && priv->packet[i]!=0)
2253
ErrorF("%c", priv->packet[i++]);
2260
/*****************************************************************************
2262
****************************************************************************/
2263
static Bool cit_GetRevision(cit_PrivatePtr priv, int selection)
2269
cit_SendCommand(priv->buffer, C_GETREVISIONS, 1, (unsigned char)selection);
2271
touch responds within 1 millisecond,
2272
but it takes some time, until the command is sent and received!
2274
cit_SetBlockDuration(priv, 500000);
2275
while (((res = cit_GetPacket(priv)) != Success) && (priv->lex_mode != cit_idle));
2278
DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE));
2281
/* examine packet */
2282
if (priv->packeti < 2)
2284
DBG(5, ErrorF("%sWrong packet length (expected >= %d, received %d bytes)\n", CI_NOTICE,
2288
if (priv->packet[0] != (C_GETREVISIONS & CMD_REP_CONV))
2290
DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
2291
(C_GETREVISIONS & CMD_REP_CONV), priv->packet[0]));
2294
if (priv->packet[1] != selection)
2296
DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
2297
selection, priv->packet[1]));
2300
/* this is our packet! check contents */
2301
DBG(5, ErrorF("%s%s module revision ", CI_INFO,
2302
selection == GR_SYSMGR ? "SysMgr " :
2303
selection == GR_HARDWARE ? "Hardware" :
2304
selection == GR_PROCESS ? "Process " :
2305
selection == GR_PROTOCOL ? "Protocol" :
2306
selection == GR_HWPARAM ? "HWParam " :
2310
DBG(5, ErrorF("\""));
2311
while (n < priv->packeti && priv->packet[i]!=0)
2313
DBG(5, ErrorF("%c", priv->packet[i]));
2316
DBG(5, ErrorF("\"\n"));
2321
/*****************************************************************************
2322
* [cit_ProcessPacket]
2323
****************************************************************************/
2324
static void cit_ProcessPacket(cit_PrivatePtr priv)
2328
DBG(PP, ErrorF("%scit_ProcessPacket called\n", CI_INFO));
2329
DBG(PP, ErrorF("%s\t+ enter state = 0x%04X, dual touch count=%d\n", CI_INFO, priv->state, priv->dual_touch_count));
2330
/* examine message identifier */
2332
priv->dual_flg = TRUE; /* Dual Touch Error occurred */
2334
priv->timer_val1[FAKE_TIMER] = 1000; /* Timer delay [ms]*/
2335
priv->timer_callback[FAKE_TIMER] = (OsTimerCallback)cit_DualTouchTimer; /* timer callback routine */
2336
cit_StartTimer(priv, FAKE_TIMER);
2339
switch (priv->packet[0])
2341
case R_COORD: /* new touch coordinates received */
2342
if (priv->packeti < 5)
2344
DBG(PP, ErrorF("%s\t- coordinate message packet too short (%d bytes)\n", CI_ERROR, priv->packeti));
2349
if (priv->dual_touch_count > 0)
2350
priv->dual_touch_count--;
2352
priv->raw_x = 0x0001U * priv->packet[1]
2353
+ 0x0100U * priv->packet[2];
2354
priv->raw_y = 0x0001U * priv->packet[3]
2355
+ 0x0100U * priv->packet[4];
2357
priv->raw_min_x = min(priv->raw_min_x, priv->raw_x);
2358
priv->raw_max_x = max(priv->raw_max_x, priv->raw_x);
2359
priv->raw_min_y = min(priv->raw_min_y, priv->raw_y);
2360
priv->raw_max_y = max(priv->raw_max_y, priv->raw_y);
2362
priv->state |= CIT_TOUCHED;
2364
DBG(PP, ErrorF("%s\t+ COORD message raw (%d,%d)\n", CI_INFO, priv->raw_x, priv->raw_y));
2367
case R_EXIT: /* touch area no longer interrupted */
2368
if (priv->packeti < 5)
2370
DBG(PP, ErrorF("%s\t- exit message packet too short (%d bytes)\n", CI_ERROR, priv->packeti));
2374
priv->state &= ~(CIT_TOUCHED | CIT_PRESSED);
2375
priv->dual_touch_count = 0;
2376
priv->enter_touched = 0; /* reset coordinate report counter */
2377
priv->raw_x = 0x0001U * priv->packet[1]
2378
+ 0x0100U * priv->packet[2];
2379
priv->raw_y = 0x0001U * priv->packet[3]
2380
+ 0x0100U * priv->packet[4];
2382
cit_CloseTimer(priv, FAKE_TIMER); /* close timer if exit message was received */
2384
DBG(PP, ErrorF("%s\t+ EXIT message (%d,%d)\n", CI_INFO, priv->raw_x, priv->raw_y));
2387
case R_DUALTOUCHERROR:
2388
if (priv->dual_touch_count < priv->max_dual_count)
2389
priv->dual_touch_count++;
2390
DBG(PP, ErrorF("%s\t+ DUAL TOUCH ERROR message received\n", CI_INFO));
2393
case R_PRESSURE: /* pressure message received */
2394
if (priv->packeti < 2)
2396
DBG(PP, ErrorF("%s\t- pressure message packet too short (%d bytes)\n", CI_ERROR, priv->packeti));
2399
priv->state |= CIT_TOUCHED;
2400
if (priv->packet[1] == PRESS_EXCEED)
2401
priv->state |= CIT_PRESSED;
2402
else if(priv->packet[1] == PRESS_BELOW)
2404
priv->enter_touched = 0; /* reset coordinate report counter */
2405
priv->state &= ~CIT_PRESSED;
2408
DBG(PP, ErrorF("%sPressure Message Error\n", CI_ERROR));
2410
DBG(PP, ErrorF("%s\t+ pressure %s message\n", CI_INFO, priv->packet[1] ? "enter":"exit"));
2414
DBG(PP, ErrorF("%s\t* unhandled message:", CI_ERROR));
2415
for (i=0; i<priv->packeti; i++)
2417
DBG(PP, ErrorF(" 0x%02X", priv->packet[i]));
2419
DBG(PP, ErrorF("\n"));
2421
/* generate button state */
2422
switch (priv->click_mode)
2425
DBG(PP, ErrorF("%s\t+ ZPress, button ", CI_INFO));
2426
if (priv->state & CIT_PRESSED)
2428
priv->state |= CIT_BUTTON;
2429
DBG(PP, ErrorF("down"));
2433
priv->state &= ~CIT_BUTTON;
2434
DBG(PP, ErrorF("up"));
2440
DBG(PP, ErrorF("%s\t+ ZPressExit, button ", CI_INFO));
2441
if (priv->state & CIT_PRESSED)
2443
priv->state |= CIT_BUTTON;
2444
DBG(PP, ErrorF("down"));
2446
else if (!(priv->state & CIT_TOUCHED))
2448
priv->state &= ~CIT_BUTTON;
2449
DBG(PP, ErrorF("up"));
2454
DBG(PP, ErrorF("%s\t+ Dual Touch, button ", CI_INFO));
2455
if ((priv->dual_touch_count == priv->max_dual_count) && (priv->state & CIT_TOUCHED))
2457
priv->state |= CIT_BUTTON;
2458
DBG(PP, ErrorF("down"));
2460
else if (priv->dual_touch_count == 0)
2462
priv->state &= ~CIT_BUTTON;
2463
DBG(PP, ErrorF("up"));
2468
DBG(PP, ErrorF("%s\t+ Dual Exit, button ", CI_INFO));
2469
if ((priv->dual_touch_count == priv->max_dual_count) && (priv->state & CIT_TOUCHED))
2471
priv->dual_flg = TRUE;
2472
priv->state |= CIT_BUTTON;
2473
DBG(PP, ErrorF("down"));
2475
else if (!(priv->state & CIT_TOUCHED))
2477
priv->state &= ~CIT_BUTTON;
2478
DBG(PP, ErrorF("up"));
2482
default: /* default to enter mode */
2483
DBG(PP, ErrorF("%s\t+ Enter Mode, button ", CI_INFO));
2484
if (priv->state & CIT_TOUCHED)
2486
priv->state |= CIT_BUTTON;
2487
DBG(PP, ErrorF("down"));
2491
priv->state &= ~CIT_BUTTON;
2492
DBG(PP, ErrorF("up"));
2496
DBG(PP, ErrorF("\n"));
2497
DBG(PP, ErrorF("%s\t+ Click Mode=%d\n", CI_INFO, priv->click_mode));
2498
DBG(PP+1, ErrorF("%s\t+ exit state = 0x%04X, dual touch count=%d\n", CI_INFO, priv->state, priv->dual_touch_count));
2499
DBG(PP+1, ErrorF("%s\t raw_x=%d, raw_y=%d\n", CI_INFO, priv->raw_x, priv->raw_y));
2504
/*****************************************************************************
2505
* [cit_GetPressureSensors]
2506
****************************************************************************/
2507
static Bool cit_GetPressureSensors(cit_PrivatePtr priv)
2513
cit_SendCommand(priv->buffer, C_GETHARDWARE, 1, GH_SENSORCOUNT);
2515
touch responds within 1 millisecond,
2516
but it takes some time, until the command is sent and received!
2520
cit_SetBlockDuration(priv, 500000);
2521
res = cit_GetPacket(priv);
2522
if ((res == Success) || (priv->lex_mode == cit_idle));
2527
DBG(5, ErrorF("%sNo packet received!\n", CI_NOTICE));
2530
/* examine packet */
2531
if (priv->packeti < 2+CTS_SENSORCOUNT_LEN)
2533
DBG(5, ErrorF("%sWrong packet length (expected >= %d, received %d bytes)\n", CI_NOTICE,
2534
2+CTS_SENSORCOUNT_LEN,
2538
if (priv->packet[0] != (C_GETHARDWARE & CMD_REP_CONV))
2540
DBG(5, ErrorF("%sWrong packet identifier (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
2541
(C_GETHARDWARE & CMD_REP_CONV), priv->packet[0]));
2544
if (priv->packet[1] != GH_SENSORCOUNT)
2546
DBG(5, ErrorF("%sWrong packet selector (expected 0x%02X, received 0x%02X)\n", CI_NOTICE,
2547
GH_SENSORCOUNT, priv->packet[1]));
2550
/* this is our packet! check contents */
2551
ErrorF("%sPressureSensors: \"%d\"\n", CI_INFO, priv->packet[2]);
2552
priv->pressure_sensors = priv->packet[2];
2557
/*****************************************************************************
2558
* [cit_ZPress] tell if click mode is ZPress (True if ZPress)
2559
****************************************************************************/
2560
static int cit_ZPress(cit_PrivatePtr priv)
2562
if((priv->click_mode == CM_ZPRESS) || (priv->click_mode == CM_ZPRESSEXIT))
2569
/*****************************************************************************
2570
* [cit_SetEnterCount] set enter_count according click_mode
2571
****************************************************************************/
2572
static void cit_SetEnterCount(cit_PrivatePtr priv)
2574
if(cit_ZPress(priv)) /* Test if 3D Mode is active and set Options according */
2575
priv->enter_count = priv->enter_count_Z;
2576
else priv->enter_count = priv->enter_count_no_Z;
2577
ErrorF("%scit_SetEnterCount: Count=%d\n", CI_CONFIG, priv->enter_count);
2581
/*****************************************************************************
2582
* [cit_SendPWMFreq] send pwm frequency of PWM signal to the touch
2583
****************************************************************************/
2584
static void cit_SendPWMFreq(cit_PrivatePtr priv)
2586
if(priv->pwm_freq >= 0) /* -1 is switched off (no SetPWMFreq set in XF86Config */
2588
cit_SendCommand(priv->buffer, C_SETPWMFREQ, 2,
2589
LOBYTE(priv->pwm_freq),
2590
HIBYTE(priv->pwm_freq));
2591
DBG(3,ErrorF("%scit_SendPWMFreq: Freq=%d\n", CI_CONFIG, priv->pwm_freq));
2594
DBG(3,ErrorF("%scit_SendPWMFreq: Frequency not set\n", CI_CONFIG));